常上新聞組的朋友一定在那裡學到不少東西吧﹖您又有否想過自己架一個 NEWS 伺服器呢﹖﹖其實在有些企業內部﹐也會透過 NEWS 伺服器進行公告、技術討論、工作彙報等事情。好消息是﹕要架設一個 NEWS 伺服器並不難﹐下面的步驟就是教您如何在本地網路中架一個 NEWS 伺服器。
如果您當初在安裝的時候選擇 everything 的話﹐相信您的機器上面已經有一個叫“inn”的 NEWS 伺服器了。請打﹕ setup --> System services --> [ * ] innd ﹐就可以讓 innd 在每次啟動的時候載入了。不過﹐如果還沒啟動的話﹐也可以使用 /etc/rc.d/init.d/innd start 來將之啟動啦。
如果您的 innd 已經成功啟動﹐在預設的情況下﹐您已經有‘control’、‘control.cancel’、‘junk’、‘test’者四個新聞群組了。只要您用 NEWS 客戶程式(如 outlook 等)﹐連上您的 NEWS 伺服器﹐就可以看到上面的群組了。
小心哦﹕上述的四個群組不能刪除哦﹐否則您的 innd 可能跑不起來。如果您不想用戶連接到它們﹐那麼參考後面的說明修改/etc/news/nnrp.access這個設定檔。例如﹕
提供的意見﹗)
如果您要增加新的群組﹐只要輸入﹕
ctlinnd newgroup test.netman
|
就可以增加一個叫‘test.netman’的新聞組了。您再用您的客戶程式重新連接就可以看得到。
如果您輸入﹕
ctlinnd rmgroup test.netman
|
就會剛才建立的群組移除掉。
這樣看來﹐要建立起一個 NEWS 伺服器似乎一點也不難。不過﹐有幾個檔案我們還是要修改一下的﹕
- /etc/news/inn.conf
-
organization: netman's news site
|
這是用來設定組織名稱的﹐您看一看原來的句子可能會有會心的微笑。
server: redhat52.siyongc.domain
|
指定 NEWS 伺服器的名稱。
pathhost: redhat52.siyongc.domain
|
指定群組的 path 。
moderatormailer: webmaster@siyongc.domain
|
指定管制群組的管理者信箱。
指定網域名稱。
fromhost: redhat52.siyongc.domain
|
指定文章的‘From’地址。
其它的設定﹐使用預設則可。
- /etc/news/expire.ctl
-
只記錄兩星期的文章標題。
在預設情況下﹐所有文章都會保留‘1 至 10’天﹔而允許標題‘永不過期(never)’。不過﹐您也可以指定某些群組的保留期限﹐如﹕
netman.*:M:1:35:90
test.*:A:never:never:never
|
這樣﹐以‘netman.’開頭的群組都會最多保留 90 天。而以‘test.’開頭的群組則永遠保留。
- /etc/news/nnrp.access
-
*.siyongc.domain:Read Post:::*
192.168.0.*:Read Post:::*
|
這樣﹐所有從‘siyongc.domain’或‘192.168.0’這個網域連上來的使用者都可以‘讀’和‘刊登’文章。
在修改上面的檔案時﹐請注意在句子後面不能有空白鍵﹐如果您不知道有否﹐執行
就可以得知。使用這個命令﹐我們還可以得知要設定 NEWS 伺服器要修改的檔案有哪些﹐以及它們有沒有設定錯誤。
和其他news伺服器連接
NEWS 系統有一個功能是﹕新聞群組可以從一個伺服器傳給另外一個伺服器﹐一直傳遞開去﹐從而達到一信傳千里的效果。要做到這個目的﹐您得在各伺服器之間建立餵信(newsfeed)功能。這需要雙方伺服器的極度配合方可達成。
有些朋友喜歡用上游、下游來稱呼參與餵信過程的雙方﹐不過您也可以稱之為餵方(feeder)和受方(receiver)。因為 news 並非如 DNS 那樣的樹狀層級架構。比如 server A 和 server B 互有信件對傳﹐那麼它們之間既是上游﹐也是下游﹐端看信件的傳遞方向而定。
前面我們已經知道架設好 innd 之後﹐可以用 ctlinnd newgroup 來增加群組。但技術上來說﹐它只是增加一個 active 群組﹐您可以在 /var/lib/news/active 檔案裡面找到。不過﹐請您不要胡亂修改它﹐否則您可能失掉整個群組。但如果您要為該群組做些說明﹐可以修改 /var/lib/news/newsgroups 這個檔﹐將 active 裡面的群組名稱寫進去﹐然後在它後面增加一些說明。例如﹕我先用下面命令建立三個群組﹕
ctlinnd newgroup netman.test
ctlinnd newgroup siyongc
ctlinnd newgroup private
|
然後修改 /var/lib/news/newsgroup :
netman.test A test group for netman
siyongc A public group for siyongc
private A private group
|
上面是手工的方法﹐如果您的上游 news server 有許多已經建立起來的群組﹐您想您的 server 也能接收(或回送)它們的文章﹐您必須要先將群組建立起來﹐這恐怕是一件非常累人的事情。不過﹐下面教您一個方法﹐一次過將上游的群組名單全部抓回來。
在我們這例子中﹐假設上游 server 叫做 news1.siyongc.domain ﹐而下游 server 叫 news2.home.siyongc.domain 。這個 news1 已經跑起來好一段日子了﹐且也接受外部的餵信﹐這個我們暫時不管它。而 news2 則是剛建立好﹐且測試過可以勝任本地新聞的工作。那麼我們在 news2 的主機上依順序輸入﹕
service innd stop
chown news:news /var/lib/news/*
su - news
telnet news1.siyongc.domain nntp > /tmp/active.new
list active
quit
telnet news1.siyongc.domain nntp > /tmp/newsgroups.new
list newsgroups
quit
|
您在 telnet 過程中熒幕是沒有顯示回應結果的﹐如果您想確定一下看到什麼﹐那就只輸入 " > " 之前的句子看看吧。然後您要修改新下載回來的 active.new 和 newsgroups.new 兩個檔﹐把開頭的 5 或 6 行(至那個以 215 開頭的句子)和最後 2 行文字刪除掉﹐這樣您就擁有和上游一模一樣的群組名單了。但這還不夠完整﹐您還要執行下面命令﹐重設 active 和 newsgroups 檔案﹕
(繼續保持 news 身份﹐否則 su -news)
cd /var/lib/news
cp active active.bak
cp newsgroups newsgroups.bak
awk '{ $2 = "0000000000" ; $3 = "0000000001" ; print }' /tmp/active.new >> active
cat active | sort -o active
cat /tmp/newsgroups.new >> newsgroups
cat newsgroups | sort -o newsgroups
|
您可能需要手工的修改上面檔案﹐將您原來的群組和新群組重複的部份刪除掉。最後執行 inncheck -v 看看是否有地方需要修改﹐有則根據提示改之﹐直到再沒錯誤才繼續。否則﹐您的 NEWS 可能跑不起來哦﹐盡管執行 service innd start 後您會看到 OK﹐您用 service innd status 就可以確定了。切記切記﹗
好了﹐當群組名單建立起來之後﹐我們就可以正式修改 innd 的檔案﹐以接受餵方的信件了。除非真有必要﹐我建議您保留 news 的身份來設定所有的 innd 檔案。不過好消息是﹕受方只需設定一個檔案就可以了﹐您只需修改 /etc/news/incoming.conf 檔﹐給餵方起一個名稱(可隨意)﹐然後將它的地址寫好就行﹕
peer news1 {
hostname: news1.siyongc.domain
}
|
設定完之後﹐可以用 root 身份重新 stop 和 start 那個 innd 服務以確定設定生效。但這動作可能不是必須的﹐如果不影響正常運作﹐做一下也無妨就是了。
雖然您把受方的大門打開了﹐如果餵方沒有相應的設定﹐那麼您還是收不到任何信件的。接下來﹐就是餵方的設定啦。這裡﹐我假設您已搖身一變成為餵方 server 的管理員了。 :)
在一切正常的情形下﹐餵方只需修改兩個檔案﹕ /etc/news/nntpsend.ctl 和 /etc/news/newsfeeds 。讓我們逐個來吧。一如設定受方的 incoming.conf 那樣﹐您必須為受方定義一個名稱(可隨意)﹐然後將地址寫到 nntpsend.ctl 檔案裡面﹕
news2:news2.home.siyongc.domain::
|
就這麼簡單﹐一行而已﹐如果您還要其它設定﹐可以 man nntpsend.ctl 。不過﹐請記著第一個 ":" 號前的名字﹐在下面的 newsfeeds 檔案裡面要使用和它一樣的名稱﹕
news2\
:netman.*,siyong,!private,!junk,!control/!foo\
:Tf,Wnm:
|
好了﹐這個檔案有必要解釋一下了。
- 首先定義一個受方名稱﹐它和 nntpsend.ctl 裡面定義的要一致。
- 然後在第一個 ":" 和第二個 ":" 之間﹐指定有哪些群組要餵送﹐各群組名稱用 "﹐" 來分隔。如果群組前面用 "﹗" 就表示該群組絕對不進行餵送。
- 再來在第二個 ":" 和第三個 ":" 之間﹐指定了用哪些方式進行餵送。這裡設定是用 batch file 的方式﹐經由 innxmit 程式用 nntp 協定進行餵送。具體餵送方式的設定可以 man newsfeeds ﹐或參考
http://bbs.ee.ntu.edu.tw/boards/NetNews/7/4/index.html 。
- 如果還要其它設定﹐請自己參考資料﹐或 man newsfeeds 。
當一切設定妥當之後﹐在 news1 的相關群組發表一些文章﹐看看 /var/spool/news/outgoing 目錄下面是否有 news2 這個 batch file 檔案。如果沒有﹐就試試重新啟動 innd ﹕
su -
service innd stop
service innd start (不建議用 restart)
service innd status (確定啟動正常)
exit (回到 news 身份)
|
如果 news2 檔案存在﹐可以 cat 一下看看是否有文章標號和 message-ID 出現。如果沒有可能要等一下﹐如果一直都沒有﹐那就可能是設定上某部份出現問題了(這個我就不是很確定了)。當萬事俱備之後﹐我們就可以進行餵送了﹕
然後看看 /var/log/news/nntpsend.log 有沒有錯誤信息。如果遇到什麼 "Ignoreing line ......" 的話﹐那可能是 batch file 的格式不對。如果用 innxmit 的話﹐請 man innxmit 看看格式規定是否和檔案一致。如果用其它的﹐請自行找資料。這就這要求您小心設定 newsfeeds 檔案了。
假如 log 信息沒錯誤﹐那麼我相信受方那邊已經成功收到更新文章了。如果沒有的話﹐那重新檢查所有步驟吧﹐或到各 BBS 找答案吧。不過﹐當 batchfile 建立起來之後﹐您可以可以手工的用 innxmit 來試試看﹕
innxmit -a -d news2.home.siyongc.domain news2
|
小心哦﹐這樣可能會把 batch file 移除掉哦﹐不過您可以重新啟動 innd 建立回來啦。
如果一切順利﹐那就開香賓慶祝一下吧﹗然後﹐您或許會希望 news2 回應的文章﹐也可以送回到 news1 去吧﹖現在相信難不到您啦﹐參考上面的設定﹐稍微改改餵方和受方名稱﹐然後換一台機器設而已啦。
剛才我們是用 nntpsend 這個程式手工進行餵送的﹐如果您沒時間親自執行這個動作﹐最簡單莫過於用 crontable 來做啦。只要用 root 身份執行 crontable -u news -e﹐然後加入﹕
0,10,20,30,40,50 * * * * /usr/bin/nntpsend
|
醬子就大功告成啦 ~~~ 哇~﹗好開心哦~~~﹗﹗ ^_^
設定 suck
好了﹐前面說的餵信方式﹐要經過雙方伺服器的配合才能完成﹐那麼有沒有法子不需要上游餵進來﹐而主動去抓文章的辦法呢﹖當然有啦﹗用 suck 就可以做到﹐下面就和大家談談如何用 suck 抓信吧﹐而且還能 post 回去哦~~~
這裡我要特別感謝 lman 兄<lman@ccns.ncku.edu.tw>的大力幫助﹐才讓我的測試順利完成。有興趣討論 suck 相關技術的朋友也可以找他研究一下的。
當然﹐首先要做的事情是取得 suck 這隻程式﹐我這裡使用的是 suck-4.2.3-1.i386.rpm ﹐從 http://rpmfind.net/linux/RPM/ 那裡抓的。直接用 rpm 安裝就好了﹐根本不用設定一大堆有的沒的﹐如 prefix 之類的東東。
不過﹐在真正動手設定 suck 之前﹐我們首先要修改 innd ﹐以符合這個特殊的環境。首先﹐您不能像前面教的被動餵信模式那樣保留長長的一列 /var/lib/news/active 記錄。因為 suck 會依據 /var/lib/suck/sucknewsrc 這個檔案來決定到上游抓信。這本來沒什麼問題﹐您可以手工的修改它(請參考 man suck)﹐但在我目前使用的這個 rpm 套件版本﹐sucknewsrc 卻會在執行 get.news.inn (後面就會談到) 之後把群組名稱同步為 active 記錄裡面的名稱(假如您使用預設的 -A 選項)。如果您的 active 是滿滿的一大串﹐那麼下次執行 get.news.inn 的時候﹐恐怕會嘗試抓所有的群組信件回來﹐這樣子﹐就算您不計較時間和頻寬﹐您也得每天至少準備 500MB 的空間(取決於名單長度)來裝那些信件。(tips:您也可以修改 /var/lib/suck/active-ignore 檔案來指定哪些群組不用去抓。)
這不同正常的被動模式那樣﹕可以通過 newsfeeds 和 incoming.conf 來限制群組名單哦﹐所以一定要小心設計 active﹐把不必要的群組拿掉。您可以手工刪除﹐也可以動一下腦筋去修改啦﹐比方我只想留 tw.bbs.comp 和本地的群組﹐我會這樣做﹕
cd /var/lib/news
cat active | grep "tw.bbs.comp" | awk '{ $2 = "0000000000" ; \
$3 = "0000000001" ; print }' > active.tmp # 同時完成歸零的動作
cat active.bak > active # 這是上次抓上游 active 時﹐原來的本機群組備份)
cat active.tmp >> active
|
不過﹐如果您不想 suck 全部把 active 的東都更新至 sucknewsrc 去﹐您可以在 /var/lib/suck 目錄下建立一個 active-ignore 檔﹐把一些本機的群組﹐或那些不想到上游抓的群組名單﹐一行一個的寫進裡面去。
另外﹐您還得修改 /etc/news/newsfeeds ﹐為上游定義一個名稱﹐以及把您要回餵的群組寫進去。您可以參考前面所教的範例﹐不過﹐我現在的例子要用 news1 這個名稱哦﹗而且每次修改好 innd﹐別忘了讓 innd 重新讀入更新檔案或重新啟動。
等安裝好 suck 之後﹐就進入 /var/lib/suck 這個目錄工作了。您全部要做的只是編輯一個檔案﹐修改 get.news.inn ﹐主要是下面這幾句就夠了﹕
把您要抓的上游主機寫好﹕
REMOTE_HOST=news1.siyongc.domain
|
接著也給上游起一個名字﹐是用來把信件餵回上去的。要注意﹕這個名稱跟 newsfeeds 裡面所定義的要一至哦﹗
如果您執行這個 script 沒問題的話﹐應該不用做什麼修改了。但如果您碰到“GROUP command not recognized, try the -M option”這樣的錯誤信息﹐那您還要修改另外兩行﹐在句子中插入一個 " -M " 選項﹕
......
# download messages
${SUCK} ${REMOTE_HOST} -M -c -A -bp -hl ${LOCAL_HOST} -dt ${TMPDIR} -dm ${MSGDI
R} -dd ${BASEDIR} -HF ${HISTORY}
......
# outgoing messages to post
${RPOST} ${REMOTE_HOST} -M -d -b ${OUTGOINGNEW} -p ${SPOOLDIR} -f \$
\$o=${OUTFILE} ${SCRIPT} \$\$i ${OUTFILE}
......
|
這裡﹐我將修改過的的 get.news.inn 這個 script 內容列出來﹐希望對您有所參考。因為﹐在測試過程中曾對它修改了好多次﹐最後才變成目前這個樣子 (它是用來抓 hinet 上面的 news 用的)﹕
#!/bin/sh
#BEFORE USING - check to ensure all the paths defined below are correct!!
#NOTE: this script probably needs to be run by root. Most systems will
# not let a normal user run ctlinnd
REMOTE_HOST=news.hinet.net
INN_DIR=/etc/news
INN_CONF=${INN_DIR}/inn.conf
LOCAL_HOST=localhost
LOCAL_TEST=$(cat ${INN_CONF} | grep fromhost | awk '{print $2}')
if [ "$LOCAL_TEST" != "" ]; then
echo "Set LOCAL_INN to '$LOCAL_TEST'"
LOCAL_INN=${LOCAL_TEST}
fi
SPOOLDIR=/var/spool/news/articles # base directory for articles to be rposted
NEWSDIR=/usr # base directory for news binaries
BASEDIR=/var/lib/suck # base directory for scripts and data files
FILTER=${BASEDIR}/newsfil.pl
CTLINND=${NEWSDIR}/bin/ctlinnd # location of binary
SHLOCK=${NEWSDIR}/bin/shlock # location of binary
TMPDIR=${BASEDIR} # location for suck.* files
MSGDIR=${BASEDIR}/Msgs # where to put MultiFile messages when getting them
SITE=hinet # name of site from newsfeeds file
OUTGOING=/var/spool/news/outgoing/${SITE} # location of the list of articles to upload
OUTGOINGNEW=${OUTGOING}.new # file to contain the list temporarily
OUTGOINGFAIL=${OUTGOINGNEW}.fail # file with failed xfers
SCRIPT=${BASEDIR}/put.news # my filter for rpost
OUTFILE=/tmp/tmp$$ # used by rpost as article after it is filtered
LOCKFILE=${BASEDIR}/getnews.lock # lock file to prevent multiple instances of script
NEWSGROUP=news # which group owns the file in out.going,
# typically either news or uucp.
TESTHOST=testhost
RPOST=rpost
SUCK=suck
HISTORY=/var/lib/news/history # location of history file
# if we are already running, abort
trap 'rm -f ${LOCKFILE} ; echo "Aborting" ; exit 1' 1 2 3 15
${SHLOCK} -p $$ -f ${LOCKFILE}
if [ $? -ne 0 ]; then
echo "Already running, can't run two at one time"
exit
fi
# is the local host up and running so we can post messages we download?
${TESTHOST} ${LOCAL_HOST} -s
LOCAL_RESULT=$?
# is the remote host up and running so we can download messages?
${TESTHOST} ${REMOTE_HOST} -s
REMOTE_RESULT=$?
if [ ${REMOTE_RESULT} -eq 0 -a ${LOCAL_RESULT} -eq 0 ]; then
# download messages
if [ -x ${FILTER} ]; then
${SUCK} ${REMOTE_HOST} -c -A -bp -hl ${LOCAL_HOST} -dt ${TMPDIR}\
-dm ${MSGDIR} -dd ${BASEDIR} -HF ${HISTORY} -y ${FILTER}
else
${SUCK} ${REMOTE_HOST} -c -A -bp -hl ${LOCAL_HOST} -dt ${TMPDIR}\
-dm ${MSGDIR} -dd ${BASEDIR} -HF ${HISTORY}
fi
SUCK_STATUS=$?
if [ ${SUCK_STATUS} -eq 0 ]; then
echo "Downloaded Articles"
elif [ ${SUCK_STATUS} -eq 1 ]; then
echo "No articles to download"
elif [ ${SUCK_STATUS} -eq 2 ]; then
echo "Unexpected answer from remote server to an issued command"
elif [ ${SUCK_STATUS} -eq 4 ]; then
echo "Can't do NNTP authorization"
elif [ ${SUCK_STATUS} -eq -1 ]; then
echo "General failure"
fi
# now upload messages
# filtering outgoing articles
if [ -s ${OUTGOING} ]; then
echo "LOCAL_INN is ${LOCAL_INN}"
echo "OUTGOING is ${OUTGOING}"
echo "Filtering ${OUTGOING} ..."
cat ${OUTGOING} | grep ${LOCAL_INN} > ${OUTGOING}
fi
if [ -s ${OUTGOINGNEW} ]; then
echo "OUTGOINGNEW is ${OUTGOINGNEW}"
echo "Filtering ${OUTGOINGNEW} ..."
cat ${OUTGOINGNEW} | grep ${LOCAL_INN} > ${OUTGOINGNEW}
fi
if [ -s ${OUTGOING} -o -s ${OUTGOINGNEW} ]; then
${TESTHOST} ${REMOTE_HOST} -s
if [ $? -ne 0 ]; then
echo "Remote posting host not responding"
else
# this is needed by INND so that the outgoing file will be
# properly flushed and we have a new blank file to work with
# when we are done
# First mv the current one to a new file name
# Since innd already has the file open, it doesn't care
# about the rename.
# The flush will ensure that all messages to be posted have
# been written out, close off the old one (already renamed)
# and create a new one.
# if the outgoingnew already exists, it means we aborted last time
# so don't try to do it again
if [ ! -s ${OUTGOINGNEW} ]; then
mv ${OUTGOING} ${OUTGOINGNEW}
${CTLINND} flush ${SITE}
fi
# outgoing messages to post
echo "Posting outgoing articles..."
${RPOST} ${REMOTE_HOST} -d -b ${OUTGOINGNEW}\
-p ${SPOOLDIR} -f \$\$o=${OUTFILE} ${SCRIPT} \$\$i ${OUTFILE}
ERRLEV=$?
if [ ${ERRLEV} -eq 0 ]; then
echo "Remotely posted articles"
rm ${OUTFILE}
elif [ ${ERRLEV} -eq 1 ]; then
echo "Error posting a message"
elif [ ${ERRLEV} -eq 2 ]; then
echo "Unable to do NNTP authorization with remote server"
elif [ ${ERRLEV} -eq 3 ]; then
echo "Unexpected answer from remote server to a command while doing NNTP authorization"
elif [ ${ERRLEV} -eq -1 ]; then
echo "Fatal error"
fi
if [ -f ${OUTGOINGFAIL} ]; then
mv ${OUTGOINGFAIL} ${OUTGOINGNEW} # so we can re do it
chown news.${NEWSGROUP} ${OUTGOINGNEW}
chmod 664 ${OUTGOINGNEW}
fi
fi
fi
echo "Suck has finished the job, enjoy it!"
fi
rm -f ${LOCKFILE}
### added for restarting innd
### to make sure innd is running well.
echo "Trying to restart innd..."
sleep 5
/etc/rc.d/init.d/innd stop
sleep 10
/etc/rc.d/init.d/innd start
innstatus=`/etc/rc.d/init.d/innd status`
chkinn=`echo ${innstatus} | grep 'pid'`
if [ -z "$chkinn" ]; then
echo "WARNING: something wrong with innd! Please fix it."
else
echo "$innstatus"
fi
exit 0
|
不過﹐就算您的設定完全沒問題﹐根據我這裡的經驗﹐您還不能抓上游的文章啦。您必須還要幫 sucknewsrc 做一個歸零的動作﹕
cat sucknewsrc | awk '{ $2 = "1" ; print }' > sucknewsrc
|
然後再重新執行 get.news.inn 。
假如您有時間﹐應該 man suck 看看如何設定這個 sucknewsrc 的﹐這樣您就可以對群組有更大的控制空間了。
關於過濾
雖然您能夠成功抓上游的文章了﹐但通常來說﹐您是沒選擇的。也就是上面有什麼您就抓什麼﹐不管好的、壞的、想要的、不想要的﹐都通通會抓下來。這不僅讓您在閱讀標題時非常“不爽”﹐而且還會浪費許多磁碟空間。
這時候﹐您或許想用一些方法把那些不想要的文章過濾掉吧。剛好﹐最近在一位高手 AcE 兄的大力協助之下﹐寫了一個 script ﹐專門用來砍 news 文章用的。下面就和大家分享一下 ﹕
#!/usr/bin/perl -P
#
#~~~~~~~~~~~
#
# Purpose: Filtering BAD news articles.
# Author: netman <netman@study-area.net>
# Origin: AcE <ace@coventive.com>
#
# Version: 1.0.1
# Date: 2000/10/31
#
# License: GNU/GPL <http://www.gnu.org/copyleft/gpl.html>
#
#~~~~~~~~~~~
if ( $ARGV[0] =~ /^$/) {
printf "ERROR: missing argument.\n";
printf " Syntax: $0 DIR_PATH\n\n";
exit 1;
}
else {
opendir (FDIR, $ARGV[0]) or die "ERROR: Can't open $ARGV[0].\n\n";
close FDIR;
}
printf "Feltering BAD articles under $ARGV[0] ...\n";
# List for Content filtering
$CList="/var/lib/suck/clist";
# List for 'Subject' filtering
$SList="/var/lib/suck/slist";
# List for 'From' filtering
$FList="/var/lib/suck/flist";
# List for 'Host' filtering
$HList="/var/lib/suck/hlist";
########## Starting Content feltering:
open(cList,"${CList}") or die "Can't open ${CList}.\n";
$index=0;
while()
{
chop;
$keys[$index]=$_;
#printf "$keys[$index]\n";
$index++;
}
close(cList);
for($i=0;$i<$index;$i++){
$keyword=$keys[$i];
printf "searching $keyword in Content.\n";
system("grep -i -r '$keyword' $ARGV[0] > wait4kill-c");
open(killList,"./wait4kill-c");
while(){
if($_ =~ /^([^:]+):.*$/){
if($tt ne $1){
printf "Deleting $1 ...\n";
system("rm -f $1");
$tt=$1;
}
}
}
close(killList);
}
system("rm -f ./wait4kill-c");
########## Starting 'Newsgroups' feltering:
printf "Filtering Newsgroups...\n";
system("grep -r '^Newsgroups.*tw.*tw.*.tw' $ARGV[0] > wait4kill-n");
open(killList,"./wait4kill-n");
while(){
if($_ =~ /^(.+):Newsgroups.*$/){
printf "Deleting $1 ...\n";
system("rm -f $1");
}
}
close(killList);
system("rm -f ./wait4kill-n");
########## Starting 'Subject' feltering:
open(sList,"${SList}") or die "Can't open ${SList}.\n";
$index=0;
while()
{
chop;
$keys[$index]=$_;
#printf "$keys[$index]\n";
$index++;
}
close(sList);
for($i=0;$i<$index;$i++){
$keyword=$keys[$i];
printf "Searching $keyword in \n";
system("grep -r 'Subject:.*$keyword.*' $ARGV[0] > wait4kill-s");
open(killList,"./wait4kill-s");
while(){
if($_ =~ /^(.+):Subject:.*$/){
printf "Deleting $1 ...\n";
system("rm -f $1");
}
}
close(killList);
}
system("rm -f ./wait4kill-s");
########## Starting 'From' feltering:
open(fList,"${FList}") or die "Can't open ${FList}.\n";
$index=0;
while()
{
chop;
$keys[$index]=$_;
#printf "$keys[$index]\n";
$index++;
}
close(fList);
for($i=0;$i<$index;$i++){
$keyword=$keys[$i];
printf "Searching $keyword in \n";
system("grep -r 'From:.*$keyword.*' $ARGV[0] > wait4kill-f");
open(killList,"./wait4kill-f");
while(){
if($_ =~ /^(.+):From:.*$/){
printf "Deleting $1 ...\n";
system("rm -f $1");
}
}
close(killList);
}
system("rm -f ./wait4kill-f");
########## Starting 'NNTP-Posting-Host' feltering:
open(hList,"${HList}") or die "Can't open ${HList}.\n";
$index=0;
while()
{
chop;
$keys[$index]=$_;
#printf "$keys[$index]\n";
$index++;
}
close(hList);
for($i=0;$i<$index;$i++){
$keyword=$keys[$i];
printf "searching $keyword in \n";
system("grep -r 'NNTP-Posting-Host:.*$keyword.*' $ARGV[0] > wait4kill-h");
open(killList,"./wait4kill-h");
while(){
if($_ =~ /^(.+):NNTP-Posting-Host:.*$/){
printf "Deleting $1 ...\n";
system("rm -f $1");
}
}
close(killList);
}
system("rm -f ./wait4kill-h");
|
然後您針對 script 所需在 /var/lib/suck 目錄下建立清單﹐將您要過濾的字串相應填上﹐逐行寫就是了。下面是各檔的內容﹕
- clist
- 這是針對文章內容而設的。那麼凡是文章包含有此清單上面的字串都會被砍掉。這是威力最大的﹐也最容易誤砍無辜者﹐所以不要列太多名稱。我通常建議您把那些廣告者所宣傳的網站、電話、地址、單位名稱、等具“唯一性”的字眼寫在此檔。
- slist
- 這是針對標題而設的。如果您想對所有標題中的字串進行過濾﹐就將可以寫在這裡。例如什麼﹕空片、情趣用品、無碼、等等。
- flist
- 這是針對發信人名稱而設的。如果有人常用什麼宣傳王、佈告王、廣告王、片片俱樂部等名稱來發信的話﹐加在這裡就對了。
- hlist
- 這是針對發信主機而設的。如果您用 outlook 的話﹐可以用鼠標右點廣告文章的標題﹐然後看“內容”﹔或是用 netscape 的新聞閱讀器看文章的“source”﹐就可以找到一個“NNTP-Posting-Host”的句子﹐冒號後面就是該發信主機了。除非對方用非固定的連線或用程式修改發信文章﹐那麼您可以把所有從這台主機所發的文件砍掉。
如果您有 cross-post 的習慣﹐也就是一次過向不同的新聞群組發佈文章的話。不好意思﹐假如您要發佈的新聞群組中超過三個是用“tw”開頭的﹐就通不過這個 script了。不過﹐您可以修改其中關於 “Filtering Newsgroups”部份的 Regular Expression﹐以符合您的需求。
上面那個 newsfil.pl 只要寫好﹐連同那些過濾清單檔一起放在 /var/lib/suck 目錄下面﹐那麼當執行 get.news.inn 的時候﹐就會被執行起來。不過﹐它除了可以用來砍每次 suck 下載時的信件。而且也用來清理特定目錄裡面的新聞郵件﹐包括子目錄哦。只要執行 ./newsfil.pl /the/path/of/dir 就可以了﹐但要小心哦﹕如果不是新聞檔的存放目錄﹐那麼﹐只要檔案裡面有相關字串的話﹐都一律會被砍掉哦~~~ 小心小心﹗
好了﹐網中人把上面提到的相關檔案﹐都包在一個壓縮檔了。您只要 點這裡 將它下載回去﹐就可以慢慢針對自己的實際情形修改了。
測試
假如不牽涉餵信的問題﹐設定一個 NEWS 伺服器是非常簡單的﹐應該不至於有問題出現。不過﹐會得運用 inncheck -v 來檢查﹐會幫我們找到許多設定問題。不過有些東西﹐inncheck 也無能為力﹐例如﹐在 active 檔案裡面﹐留意是否要包含原來的那些群組﹐例如 control、control.cancel、juck 等幾個﹐別以為從上游抓下來的就可以代替哦。反而﹐newsgroups 那個檔案倒不是很重要﹐只要將群組描述清楚就可以了。
當您完成一些設定之後﹐其實沒有必要一定重新啟動 innd 的。您可以執行 ctlinnd -h 看看有哪些動作可以做﹐比如﹐重新讀取 active 檔﹕
ctlinnd reload active "update active only"
|
註﹕別少了最後那個 “reason”哦﹐就算您不想打字﹐也應該要有一對 " " 符號。
不過﹐如果您真的需要重新啟動 innd ﹐我建議不要用 restart﹐而是先 stop 再 start﹐這還不夠﹐還要再輸入 service innd status 看看新的 innd 是否跑起來了。我發現就算顯示 start [ OK ] 之後也未必一定 OK 哦~~~
在做餵信的時候﹐最關鍵是 newsfeeds 那個檔案﹐一定要留意格式是否寫對了﹐以及傳送模式(如Tf)和寫入信息(如Wnm)是否設對﹐這裡的設定要符合 nntpsend.ctl 的要求。我強烈建議您 man newsfeeds 看看啦。當然﹐還別忘了受方也要設定好 incoming.conf 哦。
如果您要用 suck 來抓信和送信﹐要注意的地方是 get.news.inn 檔案裡面的 SITE= 要和 newsfeed 裡面設定的名稱一致。因為送信時是主要參考 /var/spool/news/outgoing 目錄下的名稱﹐它必須由 innd 產生﹐而供 suck 來讀取。要是在 post 過程中遇到問題﹐或許會在該目錄下產生一個 xxxx.new (xxxx 是 site 名稱)﹐這樣會造成往後的文章都不能 post。這時候﹐只要將那些 *.new 砍掉就是了。
就算如此﹐最後有一點您還是最好留意一下的﹐就是看看跑完 get.inn.news 之後﹐您的 innd 是否能夠順利啟動。根據我這邊的經驗是﹐通常第一次跑 get.inn.news 之後﹐/var/lib/news/active 檔有可能給弄得亂七八糟﹐尤其是那些數字可能會超過或少過 10 位數﹔也有時候會把一些空白意外移除掉了。這些都會導至 innd 跑不起來﹐而且可惡的是執行 inncheck 並不能檢查出來。如果真的如此﹐我建議您“逐行”檢查 active 檔的準確性。
還有﹐在我目前使用的版本和設定來實作﹐我發現在下游 post 的第一篇文章是無法用 suck 上載到上游群組中去的。不知道為什麼﹐不過只要從第一篇往後的回應文章(RE﹕)都可以就是了。怪怪的﹐如果您能幫我解決這問題的話﹐一定要告訴我哦~~~﹗(不過﹐後來在別的機器上試過又沒有﹐很怪啦~~)
最後﹐如果您想對 NEWS 做更深入的了解﹐可以參閱 <<曾桑談如何架設 News Server (修正版)>> 這篇文章。(我是從 台大電機 Maxwell BBS 精華區 看來的﹐雖然著作日期舊了一點﹐但絕對值得一讀﹗)