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

📄 sun2mime.c

📁 linux下的E_MAIL客户端源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: sun2mime.c,v 1.3 2000/06/07 16:10:01 evgeny Exp $ * * Copyright (c) 1994 HAL Computer Systems International, Ltd. *  *          HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. *                  1315 Dell Avenue *                  Campbell, CA  95008 * * Author: Greg Hilton * Contributors: Tom Lang, Frank Bieser, and others * * 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. * * http://www.gnu.org/copyleft/gpl.html * * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */#include <config.h>/* * Name: sun2mime * * Function: Convert a mail message containing Sun mail attachments to a *	MIME message. Input is file name, offset of start of message,  *	number of lines in the message, and output file name. * *	Return code 0 = successful translation, 1 = something was wrong. * * Tom Lang * 8/94 */#include <errno.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#define XSUNATT "Content-Type: X-sun-attachment"#define XSUNDT "X-Sun-Data-Type: "#define XSUNDD "X-Sun-Data-Description: "#define XSUNDN "X-Sun-Data-Name: "#define XSUNEN "X-Sun-Encoding-Info: "#define XSUNCL "X-Sun-Content-Lines: "#define XSUNCLEN "X-Sun-Content-Length: "#define XSUNBDY "----------"#define XLINES "X-Lines: "#define CONTENTLENGTH "Content-Length: "#define CONTENTLINES "Content-Lines: "/*#define MIMEBDY "--bODY.pART.bOUNDARY"*/static char	*mimebdy;#ifndef SEEK_SET#define SEEK_SET 0#endif/* Data type codes */#define T_UNK	0#define T_TEXT	1#define T_PS	2#define T_XBM	3#define T_XPM	4#define T_AUDIO	5#define T_GIF	6#define T_FRAME	7void convert();void convertPart();void convertText( int );void convertEncoded( int );void uu2base64();void setContentType( int, char *, int );void uuDecode( char * );int  To64( FILE *, FILE *, int ); void copyPart( FILE * );void copyLines( FILE * );void findBegin( char * );/* * global variables  */extern int debug1, debug2;static struct {	int contentLength;	int contentLines;	int bannerLoc;	int inconsistent;	/* flag: inconsistent content-length or lines */	FILE *origFile;	FILE *inFile;	FILE *outFile;	char line[2048];} g;/**************************************************************************/intsun2mime( char *in, int msgOffset, int bytes, char *out, char *bound ){	int inCount, outCount;	char tmp[256];	struct stat stats;	mimebdy = bound;	g.inconsistent = 0;	if(debug1 || debug2) {		fprintf(stderr, "sun2mime called, offset = %i, length = %i\n", msgOffset, bytes);	}	/*	 * open the file to be converted	 */	if ((g.origFile = fopen( in, "r")) == NULL) {		fprintf(stderr, "sun2mime: Message file: %s ", in);		perror("Can't open for reading");		return(1);	}	/*	 * If file size was not passed in, figure it out now.	 */	if (bytes <= 0) {		if (stat(in, &stats) == -1) {			fprintf(stderr, "sun2mime: Message file: %s ", in);			perror("Can't stat to find size");			return(1);		}		bytes = stats.st_size;	}	/*	 * Find the start of the message	 * (not necessarily the beginning of the file if this is a 	 * Unix-style folder)	 */	fseek( g.origFile, msgOffset, SEEK_SET);	if(debug2) {		fgets(g.line, sizeof(g.line), g.origFile);		fprintf(stderr, "First line:\n%s\n",g.line);		fseek(g.origFile, msgOffset+bytes, SEEK_SET);		if((fgets(g.line, sizeof(g.line), g.origFile)) != NULL) {			fprintf(stderr, "First line of next msg:\n%s\n",g.line);		} else {			fprintf(stderr, "No data past end\n");		}		fseek( g.origFile, msgOffset, SEEK_SET);	}	/*	 * open a temporary file to contain a copy of the input message.	 * note: this may be redundant, if the input message is the only	 * message in the file...	 */	tmpnam( tmp );	if((g.inFile = fopen( tmp, "w" )) == NULL) {		perror("sun2mime: can't create temp file ");		fclose(g.origFile);		return(1);	}	/*	 * extract the message from the original input file	 */	while(bytes > 0) {		inCount = (bytes>sizeof(g.line)) ? sizeof(g.line) : bytes;		inCount = fread(g.line, 1, inCount, g.origFile);		bytes -= inCount;		if(bytes < 0) {			fprintf(stderr, "sun2mime: WARNING: input file length not consistent\n");		}		outCount = fwrite(g.line, 1, inCount, g.inFile);		if(outCount != inCount) {			fprintf(stderr, "sun2mime: WARNING: problem extracting msg\n");		}	}	fclose(g.origFile);	fclose(g.inFile);	if ((g.inFile = fopen( tmp, "r")) == NULL) {		fprintf(stderr, "sun2mime: Message file: %s ", in);		perror("Can't open for reading");		return(1);	}	/*	 * open a temporary file to contain the converted message	 * note: the name for this file was passed in from the caller	 */	if((g.outFile = fopen( out, "w" )) == NULL) {		perror("sun2mime: can't create temp file ");		fclose(g.inFile);		return(1);	}		/*	 * read through the mail message headers. copy headers to output	 * until Sun-Attachment found or end of headers.	 */	if(debug2) {		fprintf(stderr, "Looking for a Sun attachment\n");	}	while((fgets(g.line, sizeof(g.line), g.inFile)) != NULL) {		/*		 * look for blank line, indicating end of mail headers		 */		if( strlen(g.line) == 1 ) {			fputc('\n', g.outFile);			break;		}		/*		 * look for "Content-Type: X-Sun-Attachment" mail header		 * if found, call conversion routine, which will process		 * the rest of the message.		 */		if( strncasecmp( g.line, XSUNATT, sizeof(XSUNATT)-1 ) == 0 ) {			convert();			break;		}		/*		 * copy header line to output, unless it's Content-Length,		 * Content-Lines, or X-Lines - this would be confusing...		 */		if((strncasecmp( g.line, CONTENTLENGTH, sizeof(CONTENTLENGTH)-1 ) != 0) && 		   (strncasecmp( g.line, CONTENTLINES, sizeof(CONTENTLINES)-1 ) != 0) &&		   (strncasecmp( g.line, XLINES, sizeof(XLINES)-1 ) != 0)) {			fputs(g.line, g.outFile);		}	}	/*	 * If previous loop terminated because end of headers reached	 * without finding that the message has Sun attachments, this	 * loop will copy the remainder of the message. Else, there	 * won't be anything left to copy.	 *	 * note: this function shouldn't be called unless there are	 * Sun attachments, so there shouldn't be anything left...	 */	while((fgets(g.line, sizeof(g.line), g.inFile)) != NULL) {		fputs(g.line, g.outFile);	}	/*	 * close files	 */	fclose(g.inFile);	unlink(tmp);	/* delete temporary file */	fclose(g.outFile);	return(0);}/* * subroutine: convert Sun attachment format to MIME format. */voidconvert() {	/*	 * output standard headers	 */	if(debug1 || debug2) {		fprintf(stderr, "Found a message with one or more Sun attachments\n");	}	fputs("Mime-Version: 1.0\n", g.outFile);	fputs("Content-Type: multipart/mixed;\n\tboundary=\"", g.outFile);	fputs(mimebdy, g.outFile);	fputs("\"\n", g.outFile);	/*	 * copy rest of the mail message headers	 */	while((fgets(g.line, sizeof(g.line), g.inFile)) != NULL) {		fputs(g.line, g.outFile);		/*		 * look for blank line, indicating end of mail headers		 */		if( strlen(g.line) == 1 ) {			break;		}	}	/*	 * output informative message	 */	fputs("--", g.outFile);	fputs(mimebdy, g.outFile);	fputc('\n', g.outFile);	fputs("Content-Type: text/plain\n", g.outFile);	fputs("Content-Description: conversion information\n", g.outFile);	fputc('\n', g.outFile);	fputs("******************************************************************************\n", g.outFile);	fputs("*** This message was converted from Sun mailtool format to MIME by Ishmail ***\n", g.outFile);	g.bannerLoc = ftell(g.outFile);	fputs("******************************************************************************\n", g.outFile);	fputc('\n', g.outFile);	/*	 * look for body parts, convert each one	 */	while((fgets(g.line, sizeof(g.line), g.inFile)) != NULL) {		/*		 * look for body part boundary		 */		if( strncasecmp( g.line, XSUNBDY, sizeof(XSUNBDY)-1 ) == 0 ) {			fputs("--", g.outFile);			fputs(mimebdy, g.outFile);			fputc('\n', g.outFile);			if(debug1 || debug2) {				fprintf(stderr, "Found a body part to convert\n");			}			convertPart();		}		/*		 * we don't expect to find extraneous lines between body		 * parts, if the content length is correct, but if there		 * are any - just copy them		 */		else			fputs(g.line, g.outFile);	}	/*	 * output final body part boundary and trailing blank line	 */	fputs("--", g.outFile);	fputs(mimebdy, g.outFile);	fputs("--\n\n", g.outFile);	/*	 * if inconsistent or missing content-length/lines info,	 * update the banner with a warning	 */	if (g.inconsistent) {		fseek(g.outFile, g.bannerLoc, SEEK_SET);		fputs("*** NOTE: Inconsistent content-length info makes the conversion suspect... ***\n",g.outFile);	}}#define DESC_SIZE 256#define NAME_SIZE 256#define ENCODE_SIZE 128/* * subroutine: Determine body part type and process it. */voidconvertPart(){	int type;	char *p;	int isUU = 0;	char desc[DESC_SIZE] = "";	char name[NAME_SIZE] = "";	char encoding[ENCODE_SIZE] = "";	/*	 * look through body part headers for:	 *	data type	 *	transfer encoding method	 *	body part description	 *	... others silently ignored	 */		if(debug2) {			fprintf(stderr, "Looking for body part headers...\n");		}	while((fgets(g.line, sizeof(g.line), g.inFile)) != NULL) {		/*		 * end of headers ?		 */		if( strlen(g.line) == 1 ) {			if(debug2) {				fprintf(stderr, "End of body part headers.\n");			}			break;		}			/*		 * data type ?		 */		if( strncasecmp( g.line, XSUNDT, sizeof(XSUNDT)-1 ) == 0 ) {			p = g.line + sizeof(XSUNDT)-1;			if( strncasecmp( p, "text", sizeof("text")-1 ) == 0 ) {				type = T_TEXT;			} else			if( strncasecmp( p, "postscript-file", sizeof("postscript-file")-1 ) == 0 ) {				type = T_PS;#if 0			} else			if( strncasecmp( p, "c-file", sizeof("c-file")-1 ) == 0 ) {				type  = T_TEXT;#endif			} else			if( strncasecmp( p, "xbm-file", sizeof("xbm-file")-1 ) == 0 ) {				type = T_XBM;			} else			if( strncasecmp( p, "xpm-file", sizeof("xpm-file")-1 ) == 0 ) {				type = T_XPM;			} else			if( strncasecmp( p, "audio-file", sizeof("audio-file")-1 ) == 0 ) {				type = T_AUDIO;			} else			if( strncasecmp( p, "gif-file", sizeof("gif-file")-1 ) == 0 ) {				type = T_GIF;			} else			if( strncasecmp( p, "framemaker-document", sizeof("framemaker-document")-1 ) == 0 ) {				type = T_FRAME;			}			else {				type = T_UNK;			}			if(debug2) {				fprintf(stderr, "Data type header found, type = %i\n", type);			}			continue;		}		/*		 * data description ?		 */		if( strncasecmp( g.line, XSUNDD, sizeof(XSUNDD)-1) == 0 ) {			p = g.line + sizeof(XSUNDD)-1;			/*			 * truncate description, if necessary			 */			strncat( desc, p, DESC_SIZE );			p = strrchr( desc, '\n' );			if(p != NULL) *p = '\0';			if(debug2) {				fprintf(stderr, "Description: %s\n",desc);			}			continue;		}		/*		 * data name ?		 */		if( strncasecmp( g.line, XSUNDN, sizeof(XSUNDN)-1) == 0 ) {			p = g.line + sizeof(XSUNDN)-1;			strncat( name, p, NAME_SIZE );			p = strrchr( name, '\n' );			if(p != NULL) *p = '\0';			if(debug2) {				fprintf(stderr, "Data name: %s\n",name);			}			continue;		}		/*		 * transfer encoding ?		 */		if( strncasecmp( g.line, XSUNEN, sizeof(XSUNEN)-1) == 0 ) {			p = g.line + sizeof(XSUNEN)-1;			isUU = parseEncode( p, encoding );			if(debug2) {				fprintf(stderr, "Transfer encoding: %s uuencode = %i\n",p, isUU);			}		}		/*		 * content length ?		 */		if( strncasecmp( g.line, XSUNCLEN, sizeof(XSUNCLEN)-1) == 0 ) {			p = g.line + sizeof(XSUNCLEN)-1;			g.contentLength = atoi(p);			if(debug2) {				fprintf(stderr, "Content length: %i\n", g.contentLength);			}		}		/*		 * content lines ?		 */		if( strncasecmp( g.line, XSUNCL, sizeof(XSUNCL)-1) == 0 ) {			p = g.line + sizeof(XSUNCL)-1;			g.contentLines = atoi(p);			if(debug2) {				fprintf(stderr, "Content lines: %i\n", g.contentLines);			}		}		/*		 * we don't expect to find extraneous headers,		 * but if there are any - just copy them		 */		else			fputs(g.line, g.outFile);	} /* End - look through headers for this body part */	 	/*	 * Before processing the remainder of the body part,	 * see if it needs to be uudecoded (then base64 encoded)	 */	if( isUU ) {		findBegin( &name[0] );	} 	/*	 * output content type header, based on input type code and	 * input transfer encoding. 	 */	setContentType( type, name, isUU );	/*	 * output description and encoding headers, followed by blank line	 */	fprintf( g.outFile, "Content-Description: %s\n", desc );	if( strlen(encoding) > (int)0 )	   fprintf( g.outFile, "Content-Transfer-Encoding: %s\n", encoding );	fputc('\n', g.outFile);	/*	 * if uuencoded body part, decode and re-encode as base64	 */	if ( isUU ) {		uu2base64();	}	/*	 * If not uuencoded, just pass the data through. It must just be	 * some form of ASCII text.	 */	else {		copyPart( g.outFile );	}	/*	 * body part processed, end it with a blank 	 * line and return.	 */	fputc('\n', g.outFile);}/* * subroutine: parse the transfer encoding line, look for uuencode *	return 1 is uuencoded, 0 otherwise *	also, the string pointed to by "encoding" is appended to. * * input:		updated string:			return val: * uuencode		base64				1 * <any>, uuencode	base64				1 * <other>		<input string>			0 * * The middle case is only seen with audio files, where <any> is  * "adpcm-compress". The third case should never be seen, but if it is the * data will be passed through unchanged. */intparseEncode( char *line, char *encoding ){	char *p;	/*	 * uuencode ?	 */	if( strncasecmp( line, "uuencode", sizeof("uuencode")-1 ) == 0 ) {		/*		 * indicate what data will be after conversion		 */		strcpy( encoding, "base64");		return(1);	}	/*	 * two attributes, comma separated ?	 */	p = strchr( line, (int)',' );	if( p == NULL ) {		strncpy( encoding, line, ENCODE_SIZE );		p = strrchr( encoding, '\n' );		if (p != NULL) *p = '\0';		return(0);	}	/*	 * <any>, uuencode ?	 */	p++;			/* skip over the comma */	if( *p == ' ' ) p++;	/* skip over blank, if any */	if( strncasecmp( p, "uuencode", sizeof("uuencode")-1 ) == 0 ) {		/*		 * indicate what data will be after conversion		 */		strcpy( encoding, "base64");		return(1);	}	strncpy( encoding, line, ENCODE_SIZE );	p = strrchr( encoding, '\n' );

⌨️ 快捷键说明

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