메뉴 건너뛰기


Developer > Application


email 파일인 *.eml 파일을 필터링하는 C 소스입니다.


/*#include <windows.h>*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define FALSE  0
#define TRUE   1

static char BASE64CODE[] =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char x2c(char *x);
char *MimeLookUpContentType(char *fname);
char *GetFileBody(char *fname, int *length);
char *QPEncoding(const char *body, int length, int bNewLine, int bText);
char *QPDecoding(const char *body, int length);
char *Base64Encoding(const char *body, int length, int bNewLine);
char *Base64Decoding(const char *body, int length);
char *Base64ReadFile(char *file);
char *SubjectDecoding(const char *body, int length);

int eml2txt(char *srcfn, char* destfn, char *title)
{
	/*Content-Transfer-Encoding: 
      8bit   ==>   1
      base64 ==>   2
      qp     ==>   3
	  7bit   ==>   4*/
	FILE *fp, *fp2;
	char *tmp;
	char buf[1000];
	char bound[100]="";
	int count=0, i=0, j=0, EncodeFlag=0;
	int EncodeType=0;
	int bAttach=FALSE;


	fp=fopen(srcfn, "rt");
    fp2=fopen(destfn, "wt");

		while(1)
		{
			memset(buf, 0x00, 1000);
		    if(fgets(buf, 1000, fp)==NULL) break;
			if(strncmp(buf, "------=", 7)==0) {
				strcpy(bound, buf);
				EncodeType=0;
			}
			if(strncmp(buf, "Content-Type:" , 13)==0)
			{
				if(strncmp(buf+14, "text/", 5)!=0) /*TEXT형태가 아니면*/
				{
					for(;;)
					{
						if(fgets(buf, 1000, fp)==NULL) return 0;
						if(strncmp(buf, "------=", 7)==0) break;
					}
					continue;
				}
			}

			if(strncmp(buf, "Content-Transfer-Encoding:" , 26)==0) 
			{
				EncodeFlag=0;
				if(strncmp(buf+27, "8bit", 4)==0 || strncmp(buf+27, "7bit", 4)==0)
					EncodeType=1;
				else if(strncmp(buf+27, "base64", 6)==0)
					EncodeType=2;
				else if(strncmp(buf+27, "quoted-printable", 16)==0)
					EncodeType=3;
				else EncodeType=2;
			}

			if(EncodeType!=0 && strcmp(buf, "\n")==0){
				fprintf(fp2, "%s\n", buf);
				EncodeFlag=1;
			}

			if(strncmp(buf, "Subject:", 8)==0){
				strcpy(title, SubjectDecoding(buf+9, strlen(buf+9)));
				/*fprintf(fp2, "<subject> %s</subject>\n", title);*/
			}

			else  if(EncodeFlag!=0) /*내용이면*/
			{
				if     ( EncodeType==1) fprintf(fp2, "%s", buf);
				else if( EncodeType==2) {tmp=Base64Decoding(buf, sizeof(buf)); fprintf(fp2, "%s", tmp); free(tmp);}
				else if( EncodeType==3) {tmp=QPDecoding(buf, sizeof(buf)); fprintf(fp2, "%s", tmp); free(tmp);}
				/*else printf("%s", buf);*/
			}
		}
		fclose(fp);
		fclose(fp2);

	return 0;
}

char *MimeLookUpContentType(char *fname)
{
	char *Result=(char *)malloc(50);
	char ext[5];
	char ext1[4];
	memset(Result, 0x00, 50);
	strcpy(ext, fname+(strlen(fname)-4));
	strcpy(ext1, fname+(strlen(fname)-3));

	if(strcmp(ext, ".htm") == 0 || strcmp(ext1, ".html") == 0 )
		strcpy(Result, "text/html");
	else if(strcmp(ext, ".txt") == 0)
		strcpy(Result, "text/plain");
	else if(strcmp(ext, ".gif") == 0)
		strcpy(Result, "image/gif");
	else if(strcmp(ext, ".jpg") == 0 || strcmp(ext, ".jpeg") == 0 )
		strcpy(Result, "image/jpeg");
	else if(strcmp(ext, ".wav") == 0)
		strcpy(Result, "audio/x-wav");
	else if(strcmp(ext, ".au") == 0)
		strcpy(Result, "audio/basic");
	else if(strcmp(ext, ".zip") == 0)
		strcpy(Result, "application/x-zip-compressed");
	else 
		strcpy(Result, "application/octet-stream");
	return (char *)Result;
}

/*Quoted Printable코드로 인코딩한다.*/
char *QPEncoding(const char *body, int length, int bNewLine, int bText)
{
    int len;
    int enlen = 0;
    char *p, *q, hexbuf[3];
    int qp;

	char *text = (char *)malloc(length * 3 + 20);
	memset(text, 0x00, length*3+20);
	q = text;
    p = (char *)body;
    len = length;
    while(len > 0)
    {
		qp = *p++ & 0xff;
        if(((33 <= qp) && (qp <= 126) && (qp != 61)) ||
			(qp == 9) || (qp == 32))
        {
			*q++ = qp;
            enlen++;
        }
        else if (qp == '\r' && bText)
			;
        else if (qp == '\n' && bText) {
			*q++ = '\r';
			*q++ = '\n';
            if (len > 0 && *p == '.')
				*q++ = '.';
			enlen = 0;
        }
        else
        {
			*q++ = '=';
            sprintf(hexbuf, "%02x", qp);
            *q++ = toupper(hexbuf[0]);
            *q++ = toupper(hexbuf[1]);
            enlen += 3;
        }
        len--;
        if(bNewLine && ((enlen >= 73) || (len <= 0)))
        {
			*q++ = '=';
			*q++ = '\r';
			*q++ = '\n';
            if (len > 0 && *p == '.')
				*q++ = '.';
            enlen = 0;
        }
    }
	*q = 0;
	return text;
}

/*Quoted Printable코드를 디코딩한다.*/
char *QPDecoding(const char *body, int length)
{
	register int i, j;
	char *text=(char *)malloc(length+1);
	memset(text, 0x00, length+1);
	strcpy(text, body);

	for(i=0, j=0; text[j]; ++i, ++j)
	{
		if((text[i]=text[j])=='=')
		{
			text[i]=x2c(&text[j+1]);
			j+=2;
		}
		else if(text[i]=='+')
			text[i]=' ';
	}
	text[i]='\0';
/*	memset(text+i-1, 0x00, length+1-i);*/

	return (char *)text;
}

/* 16진수에 해당되는 ASCII문자를 반환*/

char x2c(char *what)
{
	register char digit;

	if(what[0]==10) return(0);
	digit=(what[0]>='A'?((what[0]&0xdf)-'A')+10:(what[0]-'0'));
	digit*=16;
	digit+=(what[1]>='A'?((what[1]&0xdf)-'A')+10:(what[1]-'0'));
	return(digit);
}

/*NewLine다음에 .이 오면 종료 명령이므로 ..으로 바꾼다.*/
char *NoEncoding(const char *body, int length)
{
	char *ptr = (char *)body, *q;
	char *text = (char *)malloc(length * 2);
	char prev = '\n';

	q = text;

    while (*ptr) 
	{
		if((*ptr == '.') && (prev == '\n'))
			*q++ = '.';
		prev = *ptr;
		*q++ = *ptr++;
    }
	*q = 0;
    return text;
}

char *Base64Encoding(const char *body, int length, int bNewLine)
{
    int len;
    int enlen = 0;
    long base1, base2, base3, base64, numeq;
    char *p, *q;
	char *text;

    p = (char *)body;
    len = length;
	text = (char *)malloc(len * 78 / 57 + 20);
	q = text;
    while(len > 0)
    {
		base2 = base3 = 0;
		if(len > 2)
        {
			base1 = (long)*p++; len--;
            base2 = (long)*p++; len--;
            base3 = (long)*p++; len--;
            numeq = 0;
        }
        else if(len == 2)
        {
			len = 0;
            base1 = *p++;
            base2 = *p;
            numeq = 1;
        }
        else
        {
			len = 0;
            base1 = *p;
            numeq = 2;
		}

        base64 = base3 & 0x000000ff;
        base64 |= (base2 << 8) & 0x0000ff00;
        base64 |= (base1 << 16) & 0x00ff0000;
        *q++ = BASE64CODE[((base64 >> 18) & ~(~0 << 6))];
        *q++ = BASE64CODE[((base64 >> 12) & ~(~0 << 6))];
        if(numeq >= 2)
			*q++ = '=';
        else
			*q++ = BASE64CODE[((base64 >> 6) & ~(~0 << 6))];
		if(numeq >= 1)
			*q++ = '=';
        else
			*q++ = BASE64CODE[(base64 & ~(~0 << 6))];
		enlen++;
        if(bNewLine && ((enlen >= 19) || (len <= 0)))
        {
			*q++ = '\r';
			*q++ = '\n';
            enlen = 0;
        }
    }
	*q = 0;
    return text;
}


char *Base64Decoding(const char *body, int length)
{
	int pos1=0, pos2=0, pos3=0, pos4=0;
	int len=length;
	char *p, *q;
	long base1, base2, base3, base4, base64;

	char *text = (char *)malloc((len/4)*3+1);
	p = (char *)body;
	q=text;

	memset(text, 0x00, (len/4)*3+1);

	while(len > 0)
	{
		base1 = base2 = base3 = base4 = 0;
		base1 = (long)*p++; len--;
        base2 = (long)*p++; len--;
        base3 = (long)*p++; len--;
		base4 = (long)*p++; len--;

		for(pos1=0; pos1<=63 ; pos1++)
			if(BASE64CODE[pos1]==base1)	break;
		for(pos2=0; pos2<=63 ; pos2++)
			if(BASE64CODE[pos2]==base2)	break;
		for(pos3=0; pos3<=63 ; pos3++)
			if(BASE64CODE[pos3]==base3)	break;
		for(pos4=0; pos4<=63 ; pos4++)
			if(BASE64CODE[pos4]==base4)	break;


		base64  = pos4     & 0x00003f;          /*000000000000000000111111*/
		base64 |= pos3<< 6 & 0x000fc0;          /*000000000000111111000000*/
		base64 |= pos2<<12 & 0x03f000;          /*000000111111000000000000*/
		base64 |= pos1<<18 & 0xfc0000;          /*111111000000000000000000*/

		*q++= base64>>16 & 0x0000ff;
		*q++= base64>>8  & 0x0000ff;
		*q++= base64     & 0x0000ff;
	}

	*q='\0';
	return (char *)text;
}


char *Base64ReadFile(char *file)
{
	FILE *fp;
	int len;
    int enlen = 0;
    long base1, base2, base3, base64, numeq;
    char *q;
	int bNewLine=FALSE;
	char *text;

	fp=fopen(file, "rb");
	fseek(fp, 0L, SEEK_END);
    len=ftell(fp);
	fseek(fp, 0L, SEEK_SET);



	text = (char *)malloc(len * 78 / 57 + 20);
	q = text;
    while(len > 0)
    {
		base2 = base3 = 0;
		if(len > 2)
        {
			base1 = (long)fgetc(fp); len--;
            base2 = (long)fgetc(fp); len--;
            base3 = (long)fgetc(fp); len--;
            numeq = 0;
        }
        else if(len == 2)
        {
			len = 0;
            base1 = fgetc(fp);
            base2 = fgetc(fp);
            numeq = 1;
        }
        else
        {
			len = 0;
            base1 = fgetc(fp);
            numeq = 2;
		}

        base64 = base3 & 0x000000ff;
        base64 |= (base2 << 8) & 0x0000ff00;
        base64 |= (base1 << 16) & 0x00ff0000;
        *q++ = BASE64CODE[((base64 >> 18) & ~(~0 << 6))];
        *q++ = BASE64CODE[((base64 >> 12) & ~(~0 << 6))];
        if(numeq >= 2)
			*q++ = '=';
        else
			*q++ = BASE64CODE[((base64 >> 6) & ~(~0 << 6))];
		if(numeq >= 1)
			*q++ = '=';
        else
			*q++ = BASE64CODE[(base64 & ~(~0 << 6))];
		enlen++;
        if(bNewLine && ((enlen >= 19) || (len <= 0)))
        {
			*q++ = '\r';
			*q++ = '\n';
            enlen = 0;
        }
    }
	*q = 0;
	fclose(fp);
    return text;
}

char *SubjectDecoding(const char *body, int length)
{
	char charset[20];
	int  i, j;

	char *text=(char *)malloc(length*2);

	if(strncmp(body, "=?", 2)) return (char *)body;

	for(i=2, j=0; i<length ; i++)
	{
		if(body[i]=='?') break;
		charset[j++]=body[i];
	}
	strcpy(text, body+i);
	for(j=strlen(text); j>0 ; j--) {
		if(text[j]=='?') 
		{
			text[j]='\0';
			break;
		}
	}
	if(body[++i]=='B')
		return (char *)Base64Decoding(text+3, strlen(text+3));
	else 
		return (char *)QPDecoding(text+3, strlen(text+3));
}

번호 제목 글쓴이 날짜 조회 수
38 Windows에서 GetLastError()의 에러 메시지 내용 출력하기 푸우 2013.11.27 15516
37 윈도우즈, 유닉스, C라이브러리 비교 - Securing Windows Objects 푸우 2013.11.27 23596
36 윈도우즈, 유닉스, C라이브러리 비교 - Asynchronous I/O 푸우 2013.11.27 23385
35 윈도우즈, 유닉스, C라이브러리 비교 - Interprocess Communication 푸우 2013.11.27 25487
34 윈도우즈, 유닉스, C라이브러리 비교 - Thread Synchronization 푸우 2013.11.27 25052
33 윈도우즈, 유닉스, C라이브러리 비교 - Threads and Scheduling 푸우 2013.11.27 23835
32 윈도우즈, 유닉스, C라이브러리 비교 - Process Management 푸우 2013.11.27 25241
31 윈도우즈, 유닉스, C라이브러리 비교 - Memory Management, Memory-Mapped Files, and DLLs 푸우 2013.11.27 26756
30 윈도우즈, 유닉스, C라이브러리 비교 - Exception Handling 푸우 2013.11.27 23959
29 윈도우즈, 유닉스, C라이브러리 비교 - File and Directory Management 푸우 2013.11.27 32744
28 BASE64 인코딩 디코딩 file 푸우 2013.11.27 22277
27 mms client file 푸우 2013.11.26 15440
26 The SNIPPETS Portable C++ Source Code Archive file 푸우 2013.11.26 21995
25 The SNIPPETS Portable C Source Code Archive file 푸우 2013.11.26 16519
» Email 포맷인 eml파일의 필터링을 위한 라이브러리 file 푸우 2013.11.26 16189
23 Linux, Unix에서 라이브러리 만들기 file 푸우 2013.11.26 15784
22 Zlib를 이용한 프로그래밍 푸우 2013.11.26 16105
21 Bit Field를 이용한 구조체 크기 줄이기 푸우 2013.11.26 15178
20 C++ 에서 C 함수의 사용하기 푸우 2013.11.26 15669
19 MD5 라이브러리 file 푸우 2013.11.26 14041