procmail 을 이용한 필터작성 문의드립니다.

bushi의 이미지

메일을 수신했을 때, 메일 헤더의 Date: 항목을 분석해서 이틀 이전과 이틀 이후의 모든 메일들을 outdate 편지함으로 보내려고 합니다.

VALID_DATE1=`date --date "2 days ago" "+%a_%d_%b_%Y"`
VALID_DATE2=`date --date "1 days ago" "+%a_%d_%b_%Y"`
VALID_DATE3=`date "+%a_%d_%b_%Y"`
VALID_DATE4=`date --date "1 days" "+%a_%d_%b_%Y"`
VALID_DATE5=`date --date "2 days" "+%a_%d_%b_%Y"`
 
:0
* ^Date: \/.*
{
        MAIL_DATE = `echo "$MATCH" | cut -d " " -f-4 | tr -d ',' | sed "s/ /_/g"`
 
        :0c:
        * 1^0 ?/usr/bin/test \"$MAIL_DATE\" != \"$VALID_DATE1\" -a \"$MAIL_DATE\" != \"$VALID_DATE2\" -a \"$MAIL_DATE\" != \"$VALID_DATE3\" -a \"$MAIL_DATE\" != \"$VALID_DATE4\" -a \"$MAIL_DATE\" != \"$VALID_DATE5\"
        { }
 
        RESULT= $=
 
        :0
        * RESULT ?? 1
        | $HOME/mbox2maildir - .outdate
} 

일단 그럭저럭 동작은 합니다만, 문제가 있습니다.
너무 난잡합니다. 시간규칙을 정할 수 있는 보조설비를 procmail 에서 아무리 찾아도 안보입니다.
포기하고, procmail regexp 를 찾아봤는데, 뒤져도 문서가 없군요. '쫌 다르거든' 이라는 힌트만 봤습니다.

두번째 문제는,

MAIL_DATE = `echo "$MATCH" | cut -d " " -f-4 | tr -d ',' | sed "s/ /_/g"`

부분입니다. 난잡한 것은 둘째치고... 메일 헤더에 있는
Date:요일, 일 월 년


요일_일_월_년

으로 바꾸기 위해 사용했는데... 메일들 중에는 간혹
Date:일 월 년

처럼 요일이 빠진 헤더가 달린 놈들도 있습니다.(LWN 에서 보내주는 메일이 이러합니다.)

좀 깔끔하게 안될까요 ?

정태영의 이미지

procmail 만으로 하려고 하지 마시고, 간단한 스크립트를 작성해서 그걸 이용하세요.

아래와 같은 식으로 하시면 파이프로 실행된 스크립트의 리턴 값을 이용해서 필터링 할 수 있습니다. (이미 비슷한 걸 사용하시는 듯 하네요.)
* ? /usr/bin/getmailbody | grep -isF -f /etc/spamword/spam_word

전 메일 본문등을 먼저 디코딩 하지 않으면서 스팸이 어떤 인코딩을 사용하던지 상관 없이 단어로 필터링할 수 있도록 하기 위해 본문을 utf-8 로 바꿔주며, &#유니코드; 식으로 된 html entity 들을 utf-8 로 변환해주는 코드를 php 로 작성해서 위와 같은 식으로 이용했었습니다.

참고로 php 의 strtotime 를 이용해심 좋을 것 같습니다..
http://kr.php.net/manual/en/function.strtotime.php

--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

bushi의 이미지

그동한 메일을 받아보며 헤더를 검토해봤습니다.
이건 뭐 따로 RFC 가 없는 것인지 아주 정말 죄다 제각각이더군요.

Date: 요일, 월 일 시간 년
이 포맷이 가장 보편적이긴 한데, '요일'과 '월' 사이에 쉼표가 없는 놈도 있습니다.

'요일' 항목이 없는 놈도 있습니다.

'일' 을 표시할 때 10보다 작은 수일 경우 앞에 '0' 을 붙이는 놈이 있고 그렇지 않은 놈도 있습니다.

예를 들어 "1970년 1월 1월 0시 0분 0초, 월요일" 이라면 다음과 같은 형식의 헤더들이 발견됩니다.

Mon, Jan 1 00:00:00 1970
Mon, Jan 01 00:00:00 1970
Mon Jan 1 00:00:00 1970
Mon Jan 01 00:00:00 1970
Jan 1 00:00:00 1970
Jan 01 00:00:00 1970

정규화를 할 수 있는 방법이나 원하는 항목들만 골라낼 수 있는 필터가...
어떻게든 regex 로 돌려보려고 삽질을 해봤는데...
'요일' 항목이 있는 놈 중에서 '쉼표'가 없는 놈을 만나는 순간 좌절했습니다.

발상의 전환을 해서, 앞이 아니라 뒤에서 부터 끊어쳐야겠습니다.

OTL

정태영의 이미지

정규표현식에서 ? 는 '있거나 없거나' 를 의미합니다. ? 를 활용하세요.

--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..