iT邦幫忙

0

shell scirpt 如何過濾sendmail 附加檔案並轉發出來?

我的環境是fedora core 5
公司希望將客戶寄送過來的email 檔案內容*.csv 在sendmail 部分就可以將附加檔案過濾出來並發email 通知相關人員,請問各位前輩是否有做過,指點一下,謝謝!

8
逮丸逮丸
iT邦大師 1 級 ‧ 2010-02-02 11:20:35
最佳解答

假設更詳細一點的問題說明是:
要把客戶寄往本公司某個帳號中,
其中檔案裡有 CSV 附件的信件,
才同時轉寄給其他帳號。

所以不需要在 sendmail 處理的階段來管內容是什麼。
除非問題是:
「把外寄郵件中,附件有 csv 的檔案,轉寄給特定帳號」
才需要很麻煩地去利用 sendmail 的 milter 來處理。

然而本問題,只要利用 procmail
就最容易根據本機來信內容做處理,
甚至也不需動到 shell script,
結合網路上的兩個 procmail 的範例,
就可達到您的目的。

一、
根據 Filtering Dangerous Microsoft Windows Attachments 裡的 Sample 檔:
http://www.ece.northwestern.edu/CFS/procmailrc.virusFilters
來修改成偵測信件裡是否有 CSV 的附件。

二、
用 procmail 同時轉發多人的語法可參考:
http://partmaps.org/era/procmail/mini-faq.html#forward-many

結合以上兩個範例,改成您所需的,
可能的內容類似像這樣:

<pre class="c" name="code">
:0
* $ content-[^:]+:${WS}*.+(\<)*(file)?name${WS}*=${WS}*\/.+\.csv\"?$
! first@company.com second@company.com third@company.com

:0
* ^Content-Type: .*;$[ 	]*(file)?name=\"?.*\.csv\"?$
! first@company.com second@company.com third@company.com

:0
* ^Content-Type: .*; [ 	]*(file)?name=\"?.*\.csv\"?$
! first@company.com second@company.com third@company.com

※ procmail 的語法是會把大小寫不分來 match。

其實,procmail 辨識附件的語法,可以有不同的方式,
用 google 找 procmail attachment 就可找到不同的寫法,
可測試看哪些寫法比較能涵蓋大部份可能的情況。

procmail 在 fedora 預設都有裝,
如何設定使用也很容易找到,就不多言。

看更多先前的回應...收起先前的回應...
fillano iT邦超人 1 級 ‧ 2010-02-02 11:36:31 檢舉

這個方法看起來比較好。

checo iT邦新手 4 級 ‧ 2010-02-02 13:32:39 檢舉

謝謝您,我會試看看的!

checo iT邦新手 4 級 ‧ 2010-02-03 11:16:31 檢舉

您好:
可是我要將附件檔存在linux本機資料夾中,請問語法如何修改?謝謝!

自動存附件的方式較複雜。可用現成的 procmail 的 http://ftp.twaren.net/Unix/NonGNU/procmail-lib/procmail-lib-2009.1202.tar.gz,其中裡面的 pm-jamime-save.rc 有自動存附件的模組,說明可參閱:http://ring.nict.go.jp/archives/net/mail/procmail/jari-REMOVEME/pm-code-body.html#152
但限制是,必須是信件中只有一個附件,才會自動存,若超過一個附件就沒作用。

上述的 pm-jamime-save.rc 其實不是那麼理想,因為現實環境的 mail 的附件會有很多可能的情形,最好利用 perl 之類程式,運用該程式現成的套件,寫成 script 來處理 MIME 的附件,才會有較完善的處理。
這部份我應會再貼個文來分享怎麼做出來。

有現成的程式可以直接解信件中的附件檔,Fedora 可安裝 mpack,rpm 檔可在 http://dag.wieers.com/rpm/packages/mpack/ 抓下安裝。
若把 Outlook Express 的信件抓到 Linux 的 CLI 上的話,假設是 a.eml,
只要執行 munpack a.eml 就會在該目錄將附件解出了。
若要用到 procmail 的話,就變成像:

<pre class="c" name="code">
#! first@company.com second@company.com third@company.com
| munpack -q -C /SOME/Directory

若怕會同檔名覆改的情況,
那就用 script 來每次執行產生個別目錄,存在該新目錄下。

6
fillano
iT邦超人 1 級 ‧ 2010-02-01 17:20:29

可以看一下郵件的原始碼,應該就可以看出規則。

有附件的郵件應該都是multipart格式的,所以可以先到mail header找Content-Type header,裡面可以找到他的boundary字串,然後可以用這個字串來切割mail body。切割出來的每個part也還會有Content-TypeContent-Transfer-Encoding 等header,從Content-Type可以找到檔案類型及檔名的資訊,從Content-Transfer-Encoding可以知道內容編碼的方法,大部分的附件檔案是base64比較多。

知道這些特徵,應該就可以做出parser。(不過shell我沒那麼熟,coding我就沒辦法協助了)

checo iT邦新手 4 級 ‧ 2010-02-01 17:30:36 檢舉

請問大大有沒有具體一點的作法!謝謝!

fillano iT邦超人 1 級 ‧ 2010-02-02 10:24:22 檢舉

具體喔...請參考sendmail filter的文件:
https://www.sendmail.org/doc/sendmail-current/libmilter/docs/
裡面有api的說明跟sample code。sendmail filter api看起來已經把mail格式parse好了,你主要實作的是針對郵件各個部份處理的callback函數。他需要用C來開發。

設定的話,用sendmail filter關鍵字應該可以找到不少其他家filter的設定方法可以參考。

2
shen129
iT邦新手 1 級 ‧ 2010-02-02 11:44:34

這裡有python的作法,供您參考

http://code.activestate.com/recipes/302086/

checo iT邦新手 4 級 ‧ 2010-02-02 13:34:20 檢舉

checo提到:
Python 我不會用不過還是非常感謝您!

我要發表回答

立即登入回答