메뉴 건너뛰기


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 14793
37 윈도우즈, 유닉스, C라이브러리 비교 - Securing Windows Objects 푸우 2013.11.27 22377
36 윈도우즈, 유닉스, C라이브러리 비교 - Asynchronous I/O 푸우 2013.11.27 22264
35 윈도우즈, 유닉스, C라이브러리 비교 - Interprocess Communication 푸우 2013.11.27 24256
34 윈도우즈, 유닉스, C라이브러리 비교 - Thread Synchronization 푸우 2013.11.27 23921
33 윈도우즈, 유닉스, C라이브러리 비교 - Threads and Scheduling 푸우 2013.11.27 22694
32 윈도우즈, 유닉스, C라이브러리 비교 - Process Management 푸우 2013.11.27 24035
31 윈도우즈, 유닉스, C라이브러리 비교 - Memory Management, Memory-Mapped Files, and DLLs 푸우 2013.11.27 25285
30 윈도우즈, 유닉스, C라이브러리 비교 - Exception Handling 푸우 2013.11.27 22777
29 윈도우즈, 유닉스, C라이브러리 비교 - File and Directory Management 푸우 2013.11.27 31496
28 BASE64 인코딩 디코딩 file 푸우 2013.11.27 21316
27 mms client file 푸우 2013.11.26 14836
26 The SNIPPETS Portable C++ Source Code Archive file 푸우 2013.11.26 21489
25 The SNIPPETS Portable C Source Code Archive file 푸우 2013.11.26 15632
» Email 포맷인 eml파일의 필터링을 위한 라이브러리 file 푸우 2013.11.26 15482
23 Linux, Unix에서 라이브러리 만들기 file 푸우 2013.11.26 15072
22 Zlib를 이용한 프로그래밍 푸우 2013.11.26 15616
21 Bit Field를 이용한 구조체 크기 줄이기 푸우 2013.11.26 14534
20 C++ 에서 C 함수의 사용하기 푸우 2013.11.26 15092
19 MD5 라이브러리 file 푸우 2013.11.26 13614