1.簡介
本文的目的在于定義UUCP項目中主機之間傳遞郵件消息的標準格式,沒有討論消息在
一臺機器上的存儲格式,也不涉及一臺機器從另一臺機器上獲取數(shù)據(jù)的底層傳輸機制。我們
假定遠程執(zhí)行rmail(或者等價的)命令是UUCP網絡的基本操作。
一條基本法則是:假如我們試圖發(fā)明一種新的標準,通常無法與現(xiàn)有的系統(tǒng)兼容。世界
上已經有太多的(互相矛盾的)標準,引起了混淆,比如a!b@c.d按照舊的UUCP標準被解
釋為a!(b@c.d),而在Internet世界里則被解釋為(a!b)@c.d。(兩個標準都不支持括號,否則
就可以兼容了。外殼(shell)和UUCP傳輸機制同樣存在嚴重的問題)。
ARPA社區(qū)已經定義了明確的、具有完善文檔的、可擴展的標準族,我們也選擇這些標
準應用于UUCP區(qū)。(UUCP區(qū)是使用UUCP連接并注冊到UUCP項目的社區(qū)的子集,代表
一個治理實體。)因為實際的傳輸機制取決于兩臺主機的安排,可能包括UUCP、SMTP、
NMDF或者其它工具,我們選用RFC920(域)和RFC822(郵件格式)作為UUCP區(qū)的標
準。所有系統(tǒng)間的郵件傳輸都應遵循這兩個標準。另外,假如ARPA社區(qū)在以后改變了他
們的標準,我們也將修改我們的標準以保證與之兼容,以便提供一個合理的軟件升級時間。
本文詳述了RFC822和RFC920在UUCP世界中的解釋,說明了如何對信封編碼以及在
混合實現(xiàn)環(huán)境中如何實現(xiàn)UUCP尋路。
2.基礎
消息可以分為兩部分:信封和消息本身。信封包含郵件傳輸服務所需要的信息,消息包
含對收發(fā)方有用的信息。消息分為首部和主體。有時候中間主機會改變消息(如增加Received
行),但除非是網關需要改變傳輸格式,中間主機一般不得修改消息本身。在UUCP世界中,
信封包括“目的地址”(通常表現(xiàn)為rmail命令的參數(shù))和“源地址”(通常由消息的第一行
或者最初幾行表示,以“From”或者“>From”開始,又稱為“From行”)。RFC32的報頭
行(包括“From:”和“To:”)作為消息的一部分是消息體本身的文本。
UUCP在運輸層及以下各層使用短主機名,如“ucbvax”。我們把這種短名稱為“6字符
名”,因為任何UUCP的實現(xiàn)都至少把前6個字符視為有效的。(有一些把前7個或者前14
個字符視為有效,但我們必須使用最低的通用標準。)UUCP名可以長于6個字符,但其前
6個必須各不相同。RFC920域的名稱,如“ucbvaxBerkeley.EDU”稱為“域名”。這兩個名
是不同的。大小寫對于6字符名被認為是不同的,但對于域名則認為是相同的。6字符名后
加上“.UUCP”,如“ubcvax.UUCP”在過去作為對使用6字符名的主機的域格式的引用。
隨著對組織化的域名如“ucbvax.Berkelry.EDU”的支持,這一類名稱正在逐步淘汰。
2.1混合地址(HybridAddresses)
在UUCP世界中主要使用兩種郵件地址語法:舊式UUCP軟件使用的“a!b!c!user”(完
全路徑)格式指明了傳送郵件到目的地址的路線;遵循RFC822的“user@domain”(域)語
法格式。大部分情況下都可以根據(jù)給定的地址判定地址的類型。但是對于@左側包含“a!”
的混合地址,如a!b@c就出現(xiàn)了混淆:即可以解釋為(a!b)@c.d,也可以解釋為a!(b@c.d)。這
兩種解釋都有意義,前者用于RFC822,后者是UUCP軟件事實上的標準。
由于混合地址帶來的混亂,我們建議所有的運輸層軟件在任何時候都應該避免使用混合
地址。純粹的完全地址語法可以用來澄清這種混淆,上例中的第一種解釋可以寫為“c.d!a!b”,
第二種解釋寫為“a!c.d!b”。我們建議所有的實現(xiàn)都是用這種“完全域”語法,除非他們確
實知道下一臺機器上運行什么。
按照RFC822和AT&T消息傳輸體系,我們建議所有答應混合地址的主機采用(a!b)@c.d
這種解釋。
2.2傳輸
因為許多UUCP域不支持SMTP,我們把用于“遠程執(zhí)行”的方法定義在傳輸機制的
基礎上。要“遠程執(zhí)行”的命令與其標準輸出信息應一起讀作:rmailuser@domain...。參數(shù)
user@domain必須符合RFC920和RFC822。答應包含多個地址參數(shù),這樣把同一個消息發(fā)
往多個接收方時可以節(jié)省傳輸時間。
另一種方式是“rmaildomain!user”,其中“domain”至少包含一個逗點而且不含“!”。
這種表示可以被準確地解釋為user@domain,可以通過舊式的UUCP主機傳輸消息而無需擔
心地址被改變。“user”字符串可以包含除“@”之外的任意字符,禁止該字符是因為無法
確定中間主機如何處理它。(同樣建議避免使用“%”,有些主機把“%”視為“@”的同義
字。)不過,假如傳輸路徑包含不理解域的主機,下面的格式是可能的:
rmaila!b!c!domain!user
域至少要包含一個逗點,因而可以與6字符的UUCP站點名區(qū)分開。(單層的域沒有逗
點,應在尾部增加額外的逗點,比如Mark.Horton@att就成了“att.!Mark.Horton”。把!格式
改為@格式的解釋器應該刪除尾部逗點——假如有的話。)我們不希望發(fā)生此類情況,除非
本地網絡使用類似user@host的地址。
簡單的應用可以只使用domain!user語法(而不是user@domian),因為這種方式對3類
網關(參見節(jié)3.5)也是安全的。
2.3批處理SMTP
符合標準的實現(xiàn)可能會選擇支持一種稱為“批處理SMTP”的協(xié)議。SMTP(簡單郵件
傳輸協(xié)議)是ARPA社區(qū)的標準郵件傳輸協(xié)議(RFC821),BITNET和Mailnet也使用該協(xié)
議。因為SMTP被設計為交互式的,把一系列命令組成以批發(fā)到遠程機器上成批執(zhí)行是可
能的。BSMTP的一個優(yōu)點是UNIX外殼不參與消息的解釋,因而電子信息中可以包含空格
和括號這樣的非凡字符(這些字符在X.400地址中將會非常普遍)。
為了使UNIX支持BSMTP,符合標準的主機應當把用戶的郵件命令“b-smtp”解釋為
批處理SMTP(我們使用“b-smtp”而不是“bsmtp”是因為后者與一個登錄名沖突)。因為
許多郵件系統(tǒng)把包含單個逗點一行當作“文件尾”的標志處理,而SMTP把逗點用作必需
的文件尾標志,為了區(qū)分出報頭,我們在BSMTP的每一行增加一個非凡的“#”。在郵件發(fā)
送系統(tǒng)中實現(xiàn)這一點的簡單方法是包括如下別名:
b-smtp:"egrep'^#'sed's/^#//'/usr/lib/sendmail-bs"
這樣就可以把命令輸送給SMTP解釋器。更好的方案還要同時檢查錯誤并把錯誤信息反饋
給發(fā)送方。
下面的例子說明了一個從seismo.CSS.GOV發(fā)往cbosgd.ATT.COM的BSMTP消息。這
個例子是通過UUCP連接傳遞給命令“rmailb-smtp”的文件。注重RFC-822消息位于DATA
行和逗點行(最后一行)之間。信封信息在MAILFROM和RCPTTO行中傳遞。發(fā)送系統(tǒng)
的名稱在HELO行中。實際的信封信息(帶有“#”的行以上的部分)被忽略了,不一定要
出現(xiàn)。
Fromfoo!barSunJan1223:59:001986remotefromseismoDate:
Tue,18Feb8613:07:36EST
From:mark@ucbvax.Berkeley.EDU
Message-Id:<8602181807.AA10228@mark@ucbvax.Berkeley.EDU>To:
b-smtp@cbosgd.ATT.COM
#HELOseismo.CSS.GOV
#MAILFROM:<mark@ucbvax.Berkeley.EDU>
#RCPTTO:<mark@cbosgd.ATT.COM>
#DATA
#Date:Tue,18Feb8613:07:36EST
#From:mark@ucbvax.Berkeley.EDU
#Message-Id:<8602181807.AA10228@mark@ucbvax.Berkeley.EDU>#To:
mark@cbosgd.ATT.COM
#
#Thisisasamplemessage.
#.
#QUIT
2.4信封(Envelope)
命令的標準輸入應該以單獨的一行:Fromdomain!userdateremotefromsystem開始,后
面緊跟著RFC822格式的報頭和消息主體。可能在該行前還有其他的FROM行——這些行
是可以增加的,消息途經的每個系統(tǒng)增加一行。“系統(tǒng)字段”也可能堆疊成單獨一行,在
“user”字符串中包含許多“!”。“From”前面可能還會有“>”字符。一般說來,這些“信
封”信息應該與舊式的UUCP郵件一樣遵從相同的約定。主要的區(qū)別是當系統(tǒng)名緊湊書寫
時,假如舊式的寫法是a!b!c!mysys!me,新的寫法改為a!b!c!mysys!domain!me,其中“domain”
至少包含一個逗點符號,“mysys”通常是稱為“domain”的系統(tǒng)的6字符UUCP名。假如
“domain!”是多余的,就可以在信封中——源路徑或者目的地址——省略掉。
假如需要把信息包裝成只有一個FROM行,接收系統(tǒng)可能會丟棄多余的“From_”行。
它把“path!domain!user”和“信封”信息——包括消息發(fā)送方的地址,可能還生成新的一
行如Received或Sent-By,其中保存著轉發(fā)日期和轉發(fā)系統(tǒng)——一起發(fā)送出去。(不建議使
用Received,因為這樣的行可能在真正增加該行的系統(tǒng)之前被其他的系統(tǒng)添加,而其他的系
統(tǒng)可能事實上也包括一個Received行。Sent-By行與Received行類似,但日期不需要改為
RFC822格式,而且不主張由名稱被提及的系統(tǒng)提前增加該行。)
假如接收系統(tǒng)繼續(xù)把消息轉發(fā)給另一個系統(tǒng),它就會在前面增加一個FROM行,給處于
發(fā)送方相同的user@domain地址并加上自身的系統(tǒng)名。假如接收系統(tǒng)把消息保存到本地的信
箱內,建議僅在消息前生成一個FROM行并保存日期(使用相同的格式,因為有些郵件閱
讀程序對這種格式是敏感的),而不是用“remotefromsystem”語法格式。
注重:假如中間系統(tǒng)在user@domain語法格式地址——無論是信封還是消息體中——前
面增加文本如“system!”,都是不符合本標準和RFC822規(guī)范的。
2.5郵件路由
為了正確地發(fā)送郵件,有時候需要了解目的系統(tǒng)或者中間系統(tǒng)運行了什么軟件或者遵從
什么樣的約定。我們曾經試圖盡量減少必要的信息量,但是對子域的支持可能需要在不同條
件下使用不同的方法。為了預告其他系統(tǒng)的行為方式,我們把主機分為三類。這三類包括:
一類僅使用舊式的UUCP“!”路徑。我們設想主機理解本地用戶名:“rmailuser”和完
全路徑“rmailhost1!host2!user”,但我們不對主機做更多的假定。假如沒有關于某
臺主機的任何信息,我們可以毫無問題地把它作為第一類處理,因為我們沒有對
其如何處理混合地址作任何假設。
二類舊式的UUCP“!”路徑和4.2BSD格式的域解析。我們假設除了具有一類主機的功
能外,還能夠理解“rmailuser@domain”,其中“domain”位于UUCP區(qū)之外但主
機可以識別。二類主機不必理解“domain!user”,也不需要路由器。符合RFC920
標準的非UUCP域中的主機被認為是二類主機,即使也可能識別“host!user”。
三類具有一類和二類主機的全部功能。另外,三類主機還能夠為相距較遠的主機發(fā)送
UUCP郵件,并且能夠理解如前所述的語法“ramildomain!user”。所有連接到UUCP
的網關必須是第三類。
本文檔描述了三類主機必須具有的功能。一類和二類主機已經存在,并將繼續(xù)存在相當
長的一段時間,但被視為“過時的系統(tǒng)”并最終將升級到3類主機的狀態(tài)。
3.算法
通過UUCP連接傳遞消息給地址user@domain的算法可以概述如下:
a.假如地址的實際格式是@domain1:user@domain2,就把“domain1”而不是
“domain2”保留下來作為“doamin”,完整的格式讀為“domain1!domain2!user”。
b.確定本地可以識別的“domain”中的最明確的部分,記作“d:”,該部分應該是
“domain”的后綴。這項工作可以通過掃描一個表來完成,表項按照從非凡到一
般的順序排列,比較表項與“domain”檢查該表項是否與“domain”的尾部匹配。
例如,對于地址mark@osgd.cb.att.com,假如本地主機能夠識別“uucp”和“att.com”,
那么d就應該是“att.com”。表的最后一項是空字符串,與完全無法識別的域匹配。
c.查看基本表項(foundtableentry),尋找網關名(g:)和通往g的UUCP“!”格
式的路徑“r:”。G不一定要與本地主機直接相連,但應視作連接域d的網關。(對
于給定的d,在不同的主機上g和r可能具有不同的值,不過g通常是一樣的)
d.根據(jù)r的開始部分查找“下一跳”的主機n,n總是直接與本地主機相連。
e.假如可能則確定g和n的類型。
f.建立n能夠解釋的適當?shù)哪繕俗址畇(見下面)。
g. 把消息及目標信息s傳遞給n。
假如環(huán)境中包括其它類型的不使用UUCP“!”解析的網絡,表中可能還會有附加的
信息,如使用的連接類型。路徑信息在其他的環(huán)境中可能被替換為那個網絡的非凡信
息。
上述第二步(b)中提到的表中的第一項一般是非常精確的,能夠直接構造知名的路徑
而無需通過域樹尋路。域樹僅保留用于下列情況:沒有更詳盡多的信息;信息量很少;默認
路徑是最佳的選擇。假如存在更好的路徑就可以把該信息寫入表中。假如主機有大量的信息
傳送給第二個主機,一般希望在兩臺主機之間建立直接的UUCP連接并為它們建立相應的
表項以便直接傳遞郵件,即使兩臺主機位于不同的域中。路徑表的構造應該為最大的通信量
保持最短最便宜的路徑。
這里對目標字符串n(上述第六步f)的構造提供幾點提示。假如發(fā)送站點確定下一跳是
三類主機,那么“enveloperecipient”信息(rmail的s參數(shù))既可以使用域“!”格式
(host.com!user),也可以采用域“@”格式(user@host.com)。假如下一跳步不是三類主機,
或者發(fā)送站點不能確定,那么應盡可能使用“!”格式,因為無法預知下一跳會如何處理混
合地址。
假如已知網關是第三類,可以使用域“!”格式,但是假如發(fā)送站點不能確定其類型,或
者查找中目標字符串完全匹配(而不是與某個父域匹配),則應使用6字符“!”格式“r!user”,
如“dumbhost!host!user”。假如網關看來實際上是一個子域的網關,即與一個父域匹配(如
地址user@host.gateway.com,表中沒有找到host.gateway.com但發(fā)現(xiàn)了gateway.com),可以
把它假定為第三類。這樣在一定程度上可以安全使用如
dumbhost!domain!host.domain.com!user之類的路徑。假如存在到目標主機的直接連接,可以
使用user@domain或者domain!user兩種語法格式。
符合本標準的主機是三類主機,所有的子域網關必須是三類主機。
4.例子
假設主機A.D.COM向主機C.D.COM發(fā)送郵件。設兩臺主機的6字符名分別為aname
和dname,途徑中間主機bname。
主機A的用戶輸入:mailuser@c.d.com
用戶界面生成一個文件并使用命令(如sendmailuser@c.d.com<file)把它傳遞給傳輸機
制,文件內容如下:
Date:9Jan19858:39EST
From:myname@A.D.COM(MyName)
Subject:samplemessage
To:user@c.d.com
Thisisasamplemessage
傳輸機制查找到c.d.com的路徑,但在數(shù)據(jù)庫中沒有找到;于是尋找d.com,發(fā)現(xiàn)其路
徑是bname!dname!%s,而且發(fā)現(xiàn)c.cd.com是三類主機。然后加入c.d.com!user,就得到了路
徑bname!dname!c.d.com!user。(假如發(fā)現(xiàn)c.d.com的路徑是bname!cname!%s,結果路徑
bname!cname!user中的域將被忽略,因為無法確認目標主機屬于哪一類。)
傳輸機制預備一個FROM行并把它傳遞給uux:uux-bname!rmaildname!c.d.com!user<
file2,file2的內容包括:
FromA.D.COM!userWedJan912:43:351985remotefromanameDate:
9Jan19858:39EST
From:myname@A.D.COM(MyName)
Subject:samplemessage
To:user@c.d.com
Thisisasamplemessage
(注重消息尾部的空行——至少需要一個空行。)這將導致B主機執(zhí)行命令:rmail
dname!c.d.com!user。B預備了它自己的FROM行并繼續(xù)轉發(fā)郵件:uux-dname!rmail
c.d.com!user<file3,file3的內容包括:
FromnuucpWedJan912:43:351985remotefrombname>From
A.D.COM!userWedJan911:21:481985remotefromanameDate:9
Jan19858:39EST
From:myname@A.D.COM(MyName)
Subject:samplemessage
To:user@c.d.com
Thisisasamplemessage
C主機執(zhí)行命令:rmailc.d.com!user并壓縮FROM行,然后把消息保存到本地——可能
使用相同的格式:
Frombname!aname!A.D.COM!userWedJan912:43:351985Date:9
Jan19858:39EST
From:myname@A.D.COM(MyName)
Subject:samplemessage
To:user@c.d.com
Thisisasamplemessage
5.結論
符合本標準的主機可以接受如下所有的格式:
rmaillocaluser(user中不含“!”、“%”、“@”)
rmailhosta!hostb!user(user中不含“!”、“%”、“@”)
rmailuser@domain(域中只有逗點“.”)
rmaildomain!user(域中至少包含一個逗點“.”)
rmaildomain.!user(域中沒有圓點的情形)
消息的信封部分(FROM行)應遵循現(xiàn)有的約定使用“!”路徑。消息的首部(Word:
行,如Date:、From:、To:和Subject:)必須符合RFC822規(guī)范。所有首部地址必須采用@格
式。原始站點應確保地址符合RFC822,不能要求轉發(fā)站點或者網關把地址轉換為合法的
RFC822地址。(同樣轉發(fā)站點或者網關也不得把合法的RFC822地址user@domain轉化成不
符合RFC822的地址gateway!user@domain,即使要轉發(fā)給一類UUCP主機。)
6.參考
[1]Postel,J.,"SimpleMailTransferUSC/InformationSciencesInstitute,August,1982.
[2]Crocker,D.,"StandardfortheFormatofARPAInternetText
Messages",RFC-822,DepartmentofElectricalEngineering,
UniversityofDelaware,August,1982.
[3]Postel,J.,andJ.K.Reynolds,"DomainRequirements",RFC-920,
USC/InformationSciencesInstitute,October,1984
新聞熱點
疑難解答