磁碟、slice 及分割區命名範例名稱意義ad0s1a第一個 IDE 硬碟 (ad0) 上第一個 slice
(s1)的第一個分割區(a)
。da1s2e第二個 SCSI 硬碟 (da1) 上第二個 slice
(s2) 的第五個分割區 (e)
。磁碟的概念模型此圖顯示 FreeBSD 中接到系統的第一個 IDE 磁碟機內部配置圖。
假設這個磁碟的容量是 4 GB,並且包含了兩個 2 GB 的
slice (&ms-dos; 的分割區)。 第一個 slice 是 DOS 的
C: 磁碟機,第二個則安裝了 FreeBSD。
本範例的 FreeBSD 有三個分割區以及一個 swap 分割區。這三個分割區每個都是一個檔案系統。
a 分割是根 (root) 檔案系統;分割
e 是 /var;而
f 分割是 /usr
目錄結構。.-----------------. --.
| | |
| DOS / Windows | |
: : > First slice, ad0s1
: : |
| | |
:=================: ==: --.
| | | Partition a, mounted as / |
| | > referred to as ad0s2a |
| | | |
:-----------------: ==: |
| | | Partition b, used as swap |
| | > referred to as ad0s2b |
| | | |
:-----------------: ==: | Partition c, no
| | | Partition e, used as /var > file system, all
| | > referred to as ad0s2e | of FreeBSD slice,
| | | | ad0s2c
:-----------------: ==: |
| | | |
: : | Partition f, used as /usr |
: : > referred to as ad0s2f |
: : | |
| | | |
| | --' |
`-----------------' --'掛載與卸載檔案系統檔案系統就像一顆樹。/
就像是樹根,而 /dev,/usr
以及其他在根目錄下的目錄就像是樹枝,而這些樹枝上面又還有分支,像是
/usr/local 等。根檔案系統因為某些原因,我們會將一些目錄分別放在不同的檔案系統上。
如 /var 包含了可能會滿出來的
log/,spool/
等目錄以及各式各樣的暫存檔。
把根檔案系統塞到滿出來顯然不是個好主意,所以我們往往會比較傾向把
/var 從 / 中拉出來。另一個常見到把某些目錄放在不同檔案系統上的理由是:
這些檔案在不同的實體或虛擬磁碟機上。
像是網路檔案系統
(Network File System) 或是光碟機。fstab 檔檔案系統 file systems由fstab掛載 mounted with fstab在 /etc/fstab
裡面有設定的檔案系統會在開機
的過程中自動地被掛載
(除非該檔案系統有被加上 參數)。/etc/fstab 檔案內容的格式如下:device/mount-pointfstypeoptionsdumpfreqpassnodevice裝置名稱 (該裝置必須真的存在)。 詳情請參閱
.mount-point檔案系統要掛載到的目錄 (該目錄必須真的存在)。fstype檔案系統類型,這是要傳給 &man.mount.8; 的參數。
FreeBSD 預設的檔案系統是 ufs。options可讀可寫的檔案系統用
,而唯讀的檔案系統則是用
,後面視需要還可以加其他選項。
常見的選項如
是用在不要於開機過程中自動的掛載的檔案系統。
其他選項可參閱 &man.mount.8; 說明。dumpfreq&man.dump.8; 由此項目決定那些檔案系統需要傾印。
如果這格空白則以零為預設值。passno這個項目決定檔案系統檢查的順序。
對於要跳過檢查的檔案系統,它們的 passno
值要設為零。 根檔案系統的 passno 值應設為一
(因為需要比所有其他的還要先檢查),而其他的檔案系統的
passno 值應該要設得比一大。
若有多個檔案系統具有相同的 passno 值,則
&man.fsck.8; 會試著平行地(如果可能的話)檢查這些檔案系統。更多關於 /etc/fstab
檔案格式及選項的資訊請參閱 &man.fstab.5; 說明文件。mount 指令檔案系統 file systems掛載 mounting&man.mount.8; 指令是拿來掛載檔案系統用的。基本的操作指令格式如下:&prompt.root; mount devicemountpoint在 &man.mount.8;
裡面有提到一大堆的選項,不過最常用的就是這些:掛載選項把 /etc/fstab
裡面所有還沒有被掛載、沒有被標記成 noauto
而且沒有用 排除的檔案系統掛載起來。執行所有的動作,但是不真的去呼叫掛載的 system call。
這個選項和 搭配拿來推測 &man.mount.8;
將要做什麼動作時很好用。強迫掛載不乾淨的檔案系統 (危險),或是用來強制取消寫入權限
(把檔案系統的掛載狀態從可存取變成唯讀)。用唯讀的方式掛載檔案系統。 這個選項和在
選項中指定 (在 &os; 5.2之前的版本是用
) 參數是一樣的。fstype用指定的檔案系統型態 (fstype)
來掛載指定的檔案系統,或是在有
選項時只掛載指定型態的檔案系統。預設的檔案系統是 ufs。更新檔案系統的掛載選項。顯示較詳細資訊。以可存取的模式掛載檔案系統。 選項後面會接著以逗號分隔的參數,例如:noexec不允許在這個檔案系統上執行二進位程式碼,
這也是一個蠻有用的安全選項。nosuid不解析檔案系統上的 setuid 或 setgid 旗標,
這也是一個蠻有用的安全選項。umount 指令檔案系統 file systems卸載 unmounting&man.umount.8; 指令的參數可以是掛載點
(mountpoint),裝置名稱,以及 或是
等選項。加上 可以強制卸載,加上
則是會顯示詳細資訊。 要注意的是一般來說用
並不是個好主意,強制卸載檔案系統有可能會造成電腦當機,
或者損壞檔案系統內的資料。 和
是用來卸載所有已掛載的檔案系統,另外還可以用
來指定要卸載的是哪些種類的檔案系統。 要注意的是
並不會試圖卸載根檔案系統。程序FreeBSD 是一個多工的作業系統,也就是說在同一時間內可以跑超過一個程式。
每一個正在花時間跑的程式就叫做 程序 (process)。
您下的每個指令都至少會開啟一個新的程序,
而有些系統程序是一直在跑以維持系統正常運作的。每一個程序都有一個不重覆的數字叫做 process ID
,或稱為 PID
,而且就像檔案一樣,每一個程序也有擁有者及群組。
擁有者及群組的資訊是用來決定什麼檔案或裝置是這個程序可以開啟的
(前面有提到過檔案權限)。 大部份的程序都有父程序。
父程序是開啟這個程序的程序,例如:您對 shell 輸入指令,shell
本身就是一個程序,而您執行的指令也是程序。
每一個您用這種方式跑的程序的父程序都是 shell。
有一個特別的程序叫做 &man.init.8; 是個例外。init
永遠是第一個程序,所以他的 PID 一直都會是 1。 在 FreeBSD 開機的時候
init 會自動地被 kernel 開啟。要看系統執行中的程序,有兩個相當有用的指令可用:
&man.ps.1; 以及 &man.top.1;。ps
指令是用來列出正在執行之程序,而且可以秀它們的
PID、用了多少記憶體、執行的指令名稱及其後之參數是什麼等等。
top 指令則是顯示所有正在執行的程序,
並且數秒鐘更新一次。因此您可以互動式的觀看您的電腦正在做什麼。在預設的情況下,ps
指令只會顯示您所擁有的的程序。 例如:&prompt.user; ps
PID TT STAT TIME COMMAND
298 p0 Ss 0:01.10 tcsh
7078 p0 S 2:40.88 xemacs mdoc.xsl (xemacs-21.1.14)
37393 p0 I 0:03.11 xemacs freebsd.dsl (xemacs-21.1.14)
48630 p0 S 2:50.89 /usr/local/lib/netscape-linux/navigator-linux-4.77.bi
48730 p0 IW 0:00.00 (dns helper) (navigator-linux-)
72210 p0 R+ 0:00.00 ps
390 p1 Is 0:01.14 tcsh
7059 p2 Is+ 1:36.18 /usr/local/bin/mutt -y
6688 p3 IWs 0:00.00 tcsh
10735 p4 IWs 0:00.00 tcsh
20256 p5 IWs 0:00.00 tcsh
262 v0 IWs 0:00.00 -tcsh (tcsh)
270 v0 IW+ 0:00.00 /bin/sh /usr/X11R6/bin/startx -- -bpp 16
280 v0 IW+ 0:00.00 xinit /home/nik/.xinitrc -- -bpp 16
284 v0 IW 0:00.00 /bin/sh /home/nik/.xinitrc
285 v0 S 0:38.45 /usr/X11R6/bin/sawfish在這個範例裡可以看到 &man.ps.1; 的輸出分成好幾個欄位。
PID 就是前面有提到的 process ID。 PID 的分配是從
1 開始一直到 99999,如果用完的話又會繞回來重頭開始分配
(若該 PID 已經在用了,則 PID 不會重新分配)。
TT 欄位是指這個程式在哪個 tty
上執行,在這裡可以先忽略不管。STAT
是程式的狀態,也可以先不要管。TIME 是這個程式在
CPU 上執行的時間—這通常不是程式總共花的時間,
因為當您開始執行程式後,大部份的程式在 CPU 上執行前會先花上不少時間等待
。 最後,COMMAND 是執行這個程式的命令列。&man.ps.1;
有幾個不同的選項組合可以用來變更顯示出來的資訊,其中一個最有用的組合是
auxww。
可以顯示所有正在跑的程序的指令,不只是您自已的。
則是顯示程序的擁有者名稱以及記憶體使用情況。
可以把 daemon 程序顯示出來,
而 可讓 &man.ps.1; 顯示出每個程序完整的內容,
而不致因過長而被螢幕截掉了。&man.top.1; 也有類似的輸出。 一般的情況看像是這樣:&prompt.user; top
last pid: 72257; load averages: 0.13, 0.09, 0.03 up 0+13:38:33 22:39:10
47 processes: 1 running, 46 sleeping
CPU states: 12.6% user, 0.0% nice, 7.8% system, 0.0% interrupt, 79.7% idle
Mem: 36M Active, 5256K Inact, 13M Wired, 6312K Cache, 15M Buf, 408K Free
Swap: 256M Total, 38M Used, 217M Free, 15% Inuse
PID USERNAME PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND
72257 nik 28 0 1960K 1044K RUN 0:00 14.86% 1.42% top
7078 nik 2 0 15280K 10960K select 2:54 0.88% 0.88% xemacs-21.1.14
281 nik 2 0 18636K 7112K select 5:36 0.73% 0.73% XF86_SVGA
296 nik 2 0 3240K 1644K select 0:12 0.05% 0.05% xterm
48630 nik 2 0 29816K 9148K select 3:18 0.00% 0.00% navigator-linu
175 root 2 0 924K 252K select 1:41 0.00% 0.00% syslogd
7059 nik 2 0 7260K 4644K poll 1:38 0.00% 0.00% mutt
...輸出的資訊分成兩個部份。開頭 (前五行) 秀出最近一個程序的
PID、系統平均負載 (系統有多忙錄的測試)、系統的開機時間
(從上次重開算起) 以及現在的時間等。
在開頭裡面的其他數字分別是在講有多少程序正在執行
(在本例中為47)、有多少記憶體及 swap space
被占用了,還有就是系統分別花了多少時間在不同的 CPU 狀態上。接下來的部份是由好幾個欄位所構成,和 &man.ps.1; 輸出的資訊類似。
就如同前例,您可以看到 PID、使用者名稱、CPU
花費的時間以及正在執行的指令。 &man.top.1;
在預設的情況下還會告訴您程序用掉了多少的記憶體空間。
在這邊會分成兩欄,一個是總用量 (total size),另一個是實際用量
(resident size)—總用量是指這個應用程式需要的記憶體空間,
而實際用量則是指實際上該程式的記憶體使用量。
在這個例子裡面您可以看到 &netscape;
要了幾乎到 30 MB 的 RAM,但是只有用到 9 MB。&man.top.1; 每隔 2 秒鐘會自動更新顯示內容,可用
選項來改變間隔的時間。Daemon、信號及終止程序當在執行文書編輯器時,您可以很容易地使用它,叫它讀取檔案或是什麼的。
可以這樣做是因為編輯器有提供這些功能,
還有就是編輯器依附在一個終端機 (Terminal) 之上。
有些程式並不是設計成一直在接收使用者的輸入的,
所以它們在一開始執行的時候就從終端機斷開了。 例如說,
網頁伺服器整天都在回應網頁方面的要求,它通常不需要您輸入任何東西。
另外,像是把信從一個站傳送到另一個站的程式,也是這種類型的應用程式。
我們把這種程式稱作 daemon。
Daemon (惡魔、守護神)
是希臘神話中的角色:祂們不屬於善良陣營或邪惡陣營,是守護的小精靈。
大致上來說祂們就是在替人類做一些有用的事情,
跟今天的網頁伺服器或是郵件伺服器很像。 這也就是為何 BSD
的吉祥物,長期以來都是一隻穿著帆布鞋拿著三叉耙的快樂小惡魔的原因。通常來說 deamon 程式的名字後面都會加一個字母 d。
BIND 是 Berkeley Internet Name Domain
的縮寫 (但實際上執行的程式名稱是 named)、Apache
網頁伺服器的程式名稱是 httpd、印表機服務程式是
lpd,依此類推。
這是習慣用法,並沒有硬性規定,例如 Sendmail
主要的寄信 daemon 是叫做 sendmail 而不是
maild,跟您想像的不一樣。有些時候會需要跟某個 daemon 程序溝通,
這些溝通是透過所謂的信號(signal)來傳遞給該 daemon
程序(或是其他執行中的程序)。
藉由送出信號,您可以和一個 daemon (或是任何一個正在跑的程序) 溝通。
信號有很多種—有些有特定的意義,有些則是會由應用程式來解讀。
應用程式的說明文件會告訴您該程式是如何解讀信號的。
您只能送信號給您擁有的程序,送 &man.kill.1; 或 &man.kill.2;
的信號給別人的程序是不被允許的。 不過 root
不受此限制,他可以送信號給任何人的程序。FreeBSD 本身在某些情況也會送信號給應用程式。
假設有個應用程式寫得很爛,然後企圖要存取它不該碰的記憶體的時候,FreeBSD
會送一個 Segmentation Violation 信號
(SIGSEGV) 給這個程序。
又如果有一個應用程式用了 &man.alarm.3; 的 system call
要求系統在過一段時間之後叫他一下,時間到了的時候鬧鐘的信號
(SIGALRM) 就會被送出了,其他的依此類推。SIGTERM and SIGKILL
這兩個信號可以拿來終止程序。 用 SIGTERM
結束程序是比較有禮貌的方式,該程序會捕捉 (catch)
這個信號而了解到您想要把他關掉。 接著下來它會把它自已開的記錄檔通通關掉,
然後在關掉程序之前結束掉手邊的工作。 在某些情況下程序有可能會裝作沒看見
SIGTERM,假如它正在做一些不能中斷的工作的話。SIGKILL 就沒有辦法被程序忽略了。
這是一個我管你正在幹嘛,現在就給我停下來的信號。
如果您送了 SIGKILL 信號給某個程序,FreeBSD
將會把它停掉不完全正確—還是有少數東西不能被中斷。
例如有個程序正在從網路上的別的電腦讀一個檔案,
而那部電腦因為某些理由連不到 (機器被關掉,或是網路爛掉了),
那這個程序我們就說他是一個不能中斷的程序。
通常在經過兩分鐘左右之後這個程序會逾時。
當發生逾時的時候這個程序就會被結束掉了。。這些是其他您有可能會要用到的信號:
SIGHUP,SIGUSR1,以及
SIGUSR2。
這些是通用的信號,當送出時不同的應用程式會有不同的反應。假設您更動了您的網頁伺服器的設定檔—
您想要叫網頁伺服器去重新讀取設定值。 您可以關閉後再重新啟動
httpd,但是這麼做會造成網頁伺服器暫停服務一段時間,
這樣子可能不太好。
大部份的 daemon 都寫成會去回應 SIGHUP。
當收到這個信號之後,它們會去重新讀取自已的設定檔。
因此您可以用送 SIGHUP 信號來取代關掉重開。
又因為沒有標準在規範如何回應這些信號,不同的 daemon
可能會有不同的行為,所以有疑問的話請先確認並翻閱 deamon
的說明文件。信號是由 &man.kill.1; 指令送出的,如範例所示:送信號給程序這個範例將會示範如何送一個信號給 &man.inetd.8;。
inetd 的設定檔是
/etc/inetd.conf,而 inetd
會在收到 SIGHUP 的時候重新讀取這個設定檔。找出您想要送信號的那個程序的 ID。 您會用到 &man.ps.1; 以及
&man.grep.1; 這兩個指令。 &man.grep.1; 是用來在輸出中搜尋,
找出您指定的字串。 這個指令是由一般使用者執行,而 &man.inetd.8;
是由 root 執行,所以在使用 &man.ps.1; 時需要加上
選項。&prompt.user; ps -ax | grep inetd
198 ?? IWs 0:00.00 inetd -wW因此可知 &man.inetd.8; 的 PID 為 198。 在某些情況下
grep inetd 這個指令本身也會出現在輸出裡。
這是因為 &man.ps.1; 乃是找所有執行中的程序的方式造成的。用 &man.kill.1; 來送信號。 又因為 &man.inetd.8; 是由
root 執行的,您必須用 &man.su.1; 切換成
root先。&prompt.user; suPassword:
&prompt.root; /bin/kill -s HUP 198一般情況對大多數 &unix; 指令來講,當 &man.kill.1;
執行成功時並不會輸出任何訊息。
假設您送一個信號給某個不是您所擁有的程序,
那麼您就會吃到這個錯誤訊息: kill:
PID: Operation not permitted。
而如果您打錯 PID 的話,那就會把信號送給錯誤的程序。 這樣可能會很糟,
不過如果您夠幸運的話,可能剛好就只是把信號送給一個非使用中的
PID,那您就只會看到 kill:
PID: No such process 而已。
為什麼用 /bin/kill?很多 shell 有提供內建的 kill 指令。
也就是說這種 shell 會直接送信號,而不是執行
/bin/kill。
這樣是蠻方便的沒錯啦,但是不同的 shell
會有不同的語法來指定信號的名稱等。
與其嘗試去把它們通通學會,不如就單純的直接用 /bin/kill
... 吧。要送其他的信號的話也是非常類似,就視需要把指令中的
TERM 或 KILL
替換掉即可。隨便抓一個系統中的程序然後把他砍掉並不是個好主意。
特別是 &man.init.8;, process ID 1,一個非常特別的程序。
執行 /bin/kill -s KILL 1
的結果就是系統立刻關機。 因此在您按下 Return
要執行 &man.kill.1;之前,
請一定要記得再次確認您下的參數。Shellsshells
- command line
-
- In FreeBSD, a lot of everyday work is done in a command line
- interface called a shell. A shell's main job is to take commands
- from the input channel and execute them. A lot of shells also have
- built in functions to help everyday tasks such as file management,
- file globbing, command line editing, command macros, and environment
- variables. FreeBSD comes with a set of shells, such as
- sh, the Bourne Shell, and tcsh,
- the improved C-shell. Many other shells are available
- from the FreeBSD Ports Collection, such as
- zsh and bash.
-
- Which shell do you use? It is really a matter of taste. If you
- are a C programmer you might feel more comfortable with a C-like shell
- such as tcsh. If you have come from Linux or are new
- to a &unix; command line interface you might try bash.
- The point is that each
- shell has unique properties that may or may not work with your
- preferred working environment, and that you have a choice of what
- shell to use.
-
- One common feature in a shell is filename completion. Given
- the typing of the first few letters of a command or filename, you
- can usually have the shell automatically complete the rest of the
- command or filename by hitting the Tab key on the keyboard. Here is
- an example. Suppose you have two files called
- foobar and foo.bar. You
- want to delete foo.bar. So what you would type
- on the keyboard is: rm fo[Tab].[Tab].
-
- The shell would print out rm
- foo[BEEP].bar.
-
- The [BEEP] is the console bell, which is the shell telling me it
- was unable to totally complete the filename because there is more
- than one match. Both foobar and
- foo.bar start with fo, but
- it was able to complete to foo. If you type in
- ., then hit Tab again, the shell would be able to
- fill in the rest of the filename for you.
+ 命令列 command line
+
+ 在 FreeBSD 中,很多日常的工作是在一個叫做 shell
+ 的文字介面中完成的。
+ Shell 的主要工作就是從輸入中收到命令並執行它們。
+ 許多 shell 也有內建一些有助於日常工作的指令,
+ 像是檔案管理、檔案比對、命令列編輯、指令巨集以及環境變數等。
+ FreeBSD 有內附了幾個 shell,像是 sh,
+ Bourne Shell,以及 tcsh,改良版的 C-shell。
+ 還有許多其他的 shell 可以從 FreeBSD Ports Collection
+ 中取得,像是 zsh 以及 bash
+ 等。
+
+ 您用哪個 shell 呢? 其實每個人的喜好都不一樣。
+ 如果您是一個 C 程式設計師,那對於使用像是 tcsh
+ 這種 C-like 的 shell 可能會感到相當愉快。 如果你是從 Linux
+ 跳過來的,或者您是一個 &unix; 新手,那您也許會想要用
+ bash 來當作文字介面。
+ 每一個 shell 都有自已獨特之處,至於這些特點能不能配合您的工作環境?
+ 那就是您選擇 shell 的重點了。
+
+ 檔名自動補齊就是常見的 shell 功能。
+ 首先輸入指令或檔案的前幾個字母,這時通常您只需要按下 Tab
+ 鍵,接下來 shell 就會自動把指令或是檔案名稱剩餘的部份補齊。
+ 假設您有兩個檔案分別叫作 foobar 及
+ foo.bar。 現在要刪掉
+ foo.bar,那麼可以輸入:
+ rm fo[Tab].[Tab]
+
+
+ Shell 會印出這個: rm foo[嗶].bar。
+
+ [嗶] 是 console 的響鈴,這嗶的一聲是 shell
+ 在告訴我說它沒有辦法完全自動補齊檔名,因為有不只一個檔名符合條件。
+ foobar 和 foo.bar 都是
+ fo 開頭的檔名,不過它至少可以補齊到 foo。
+ 如果您接著輸入 . 然後再按 Tab
+ 一次,那 shell 就能夠替您把剩下的檔名填滿了。
+
environment variables
- Another feature of the shell is the use of environment variables.
- Environment variables are a variable/key pair stored in the shell's
- environment space. This space can be read by any program invoked by
- the shell, and thus contains a lot of program configuration. Here
- is a list of common environment variables and what they mean:
+ Shell 的另一項特點是使用了環境變數。
+ 環境變數是以變數與鍵值(variable/key)的對應關係儲存於 shell
+ 的環境空間中,任何由 shell 所產生的程序都可以讀取此空間,
+ 因此這個空間儲存了許多程序的設定組態。在此附上
+ 一份常見環境變數與其含意的列表:environment variables
- Variable
- Description
+ 變數
+ 詳細說明USER
- Current logged in user's name.
+ 目前登入的使用者名稱。PATH
- Colon-separated list of directories to search for
- binaries.
+ 以冒號(:)隔開的目錄列表,用以搜尋執行檔的路徑。DISPLAY
- Network name of the X11 display to connect to, if
- available.
+ 若存在這個環境變數,則代表 X11 連結顯示器的網路名稱。SHELL
- The current shell.
+ 目前使用的 shell。TERM
- The name of the user's type of terminal. Used to determine
- the capabilities of the terminal.
+ 使用者終端機的名稱,能藉由此變數判斷終端機的能力。TERMCAPDatabase entry of the terminal escape codes to perform
various terminal functions.OSTYPE
- Type of operating system. e.g., FreeBSD.
+ 作業系統的種類,如:FreeBSD。MACHTYPE
- The CPU architecture that the system is running
- on.
+ 目前系統所用的 CPU 架構。EDITOR
- The user's preferred text editor.
+ 使用者偏好的文字編輯器。PAGER
- The user's preferred text pager.
+ 使用者偏好的文字分頁器(text pager)。MANPATH
- Colon-separated list of directories to search for
- manual pages.
+ 以冒號(:)隔開的目錄列表,用以搜尋 manual pages 的路徑。Bourne shells
- Setting an environment variable differs somewhat from
- shell to shell. For example, in the C-Style shells such as
- tcsh and csh, you would use
- setenv to set environment variables.
- Under Bourne shells such as sh and
- bash, you would use
- export to set your current environment
- variables. For example, to set or modify the
- EDITOR environment variable, under csh or
- tcsh a
- command like this would set EDITOR to
- /usr/local/bin/emacs:
+ 在不同的 shell 底下設定環境變數的方式也有所不同。
+ 舉例來說,在 C-Style 的 shell 底下,像是
+ tcsh 和 csh,你必須使用
+ setenv 來設定環境變數。
+ 但在 Bourne shells 底下,像是 sh 和
+ bash,你則必須使用
+ export 來設定你所使用的環境變數。
+ 再舉個例子來說,若要設定或是修改
+ EDITOR 這個環境變數,在 csh 或
+ tcsh 下設定 EDITOR 這個環境變數為
+ /usr/local/bin/emacs 的指令是:&prompt.user; setenv EDITOR /usr/local/bin/emacs
- Under Bourne shells:
+ 在 Bourne shells 下則是:&prompt.user; export EDITOR="/usr/local/bin/emacs"
- You can also make most shells expand the environment variable by
- placing a $ character in front of it on the
- command line. For example, echo $TERM would
- print out whatever $TERM is set to, because the shell
- expands $TERM and passes it on to echo.
+ 大多數的 shell 都支援使用者在命令列中將
+ $ 字元放在變數之前,以取得環境變數的值。
+ 舉例來說,echo $TERM 會
+ 顯示出 $TERM 的設定值,這是因為 shell 取得了
+ $TERM 的設定值,並將他傳給 echo 顯示出來。Shells treat a lot of special characters, called meta-characters
as special representations of data. The most common one is the
* character, which represents any number of
characters in a filename. These special meta-characters can be used
to do filename globbing. For example, typing in
echo * is almost the same as typing in
ls because the shell takes all the files that
match * and puts them on the command line for
echo to see.To prevent the shell from interpreting these special characters,
they can be escaped from the shell by putting a backslash
(\) character in front of them. echo
$TERM prints whatever your terminal is set to.
echo \$TERM prints $TERM as
is.
- Changing Your Shell
-
- The easiest way to change your shell is to use the
- chsh command. Running chsh will
- place you into the editor that is in your EDITOR
- environment variable; if it is not set, you will be placed in
- vi. Change the Shell: line
- accordingly.
-
- You can also give chsh the
- option; this will set your shell for you,
- without requiring you to enter an editor.
- For example, if you wanted to
- change your shell to bash, the following should do the
- trick:
-
+ 變更你的 Shell
+
+ 變更 shell 最簡單的方法就是透過 chsh 命令。
+ 執行 chsh 將會呼叫環境變數中 EDITOR 指定的
+ 文字編輯器。如果沒有設定,則預設是 vi。依照需求去修改
+ Shell: 的值。
+
+ 你也可以透過 chsh 的參數 ,這可以
+ 直接設定你的 shell 而不需要透過任何文字編輯器。例如,假設你想將 shell 變更為
+ bash,可以透過下列的方式:
+
&prompt.user; chsh -s /usr/local/bin/bashThe shell that you wish to use must be
present in the /etc/shells file. If you
have installed a shell from the ports
collection, then this should have been done for you
already. If you installed the shell by hand, you must do
this.For example, if you installed bash by hand
and placed it into /usr/local/bin, you would
want to:&prompt.root; echo "/usr/local/bin/bash" >> /etc/shellsThen rerun chsh.文字編輯器text editorseditorsA lot of configuration in FreeBSD is done by editing text files.
Because of this, it would be a good idea to become familiar
with a text editor. FreeBSD comes with a few as part of the base
system, and many more are available in the Ports Collection.eeeditorseeThe easiest and simplest editor to learn is an editor called
ee, which stands for easy editor. To
start ee, one would type at the command
line ee filename where
filename is the name of the file to be edited.
For example, to edit /etc/rc.conf, type in
ee /etc/rc.conf. Once inside of
ee, all of the
commands for manipulating the editor's functions are listed at the
top of the display. The caret ^ character represents
the Ctrl key on the keyboard, so ^e expands to the key combination
Ctrle. To leave
ee, hit the Esc key, then choose leave
editor. The editor will prompt you to save any changes if the file
has been modified.vieditorsviemacseditorsemacsFreeBSD also comes with more powerful text editors such as
vi as part of the base system, while other editors, like
Emacs and vim,
are part of the FreeBSD Ports Collection (editors/emacs and editors/vim). These editors offer much
more functionality and power at the expense of being a little more
complicated to learn. However if you plan on doing a lot of text
editing, learning a more powerful editor such as
vim or Emacs
will save you much more time in the long run.Devices and Device NodesA device is a term used mostly for hardware-related
activities in a system, including disks, printers, graphics
cards, and keyboards. When FreeBSD boots, the majority
of what FreeBSD displays are devices being detected.
You can look through the boot messages again by viewing
/var/run/dmesg.boot.For example, acd0 is the
first IDE CDROM drive, while kbd0
represents the keyboard.Most of these devices in a &unix; operating system must be
accessed through special files called device nodes, which are
located in the /dev directory.Creating Device NodesWhen adding a new device to your system, or compiling
in support for additional devices, new device nodes must
be created.DEVFS (DEVice File System)The device file system, or DEVFS, provides access to
kernel's device namespace in the global file system namespace.
Instead of having to create and modify device nodes,
DEVFS maintains this particular file system for you.See the &man.devfs.5; manual page for more
information.Binary FormatsTo understand why &os; uses the &man.elf.5;
format, you must first know a little about the three currently
dominant executable formats for &unix;:&man.a.out.5;The oldest and classic &unix; object
format. It uses a short and compact header with a magic
number at the beginning that is often used to characterize
the format (see &man.a.out.5; for more details). It
contains three loaded segments: .text, .data, and .bss plus
a symbol table and a string table.COFFThe SVR3 object format. The header now comprises a
section table, so you can have more than just .text, .data,
and .bss sections.&man.elf.5;The successor to COFF, featuring
multiple sections and 32-bit or 64-bit possible values. One
major drawback: ELF was also designed
with the assumption that there would be only one ABI per
system architecture. That assumption is actually quite
incorrect, and not even in the commercial SYSV world (which
has at least three ABIs: SVR4, Solaris, SCO) does it hold
true.FreeBSD tries to work around this problem somewhat by
providing a utility for branding a
known ELF executable with information
about the ABI it is compliant with. See the manual page for
&man.brandelf.1; for more information.FreeBSD comes from the classic camp and used
the &man.a.out.5; format, a technology tried and proven through
many generations of BSD releases, until the beginning of the 3.X
branch. Though it was possible to build and run native
ELF binaries (and kernels) on a FreeBSD
system for some time before that, FreeBSD initially resisted the
push to switch to ELF as the
default format. Why? Well, when the Linux camp made their
painful transition to ELF, it was not so much
to flee the a.out executable format as it
was their inflexible jump-table based shared library mechanism,
which made the construction of shared libraries very difficult
for vendors and developers alike. Since the
ELF tools available offered a solution to the
shared library problem and were generally seen as the way
forward anyway, the migration cost was accepted as
necessary and the transition made. FreeBSD's shared library
mechanism is based more closely on Sun's
&sunos; style shared library mechanism
and, as such, is very easy to use.So, why are there so many different formats?Back in the dim, dark past, there was simple hardware. This
simple hardware supported a simple, small system. a.out was
completely adequate for the job of representing binaries on this
simple system (a PDP-11). As people ported &unix; from this simple
system, they retained the a.out format because it was sufficient
for the early ports of &unix; to architectures like the Motorola
68k, VAXen, etc.Then some bright hardware engineer decided that if he could
force software to do some sleazy tricks, then he would be able
to shave a few gates off the design and allow his CPU core to
run faster. While it was made to work with this new kind of
hardware (known these days as RISC), a.out
was ill-suited for this hardware, so many formats were developed
to get to a better performance from this hardware than the
limited, simple a.out format could
offer. Things like COFF,
ECOFF, and a few obscure others were invented
and their limitations explored before things seemed to settle on
ELF.In addition, program sizes were getting huge and disks (and
physical memory) were still relatively small so the concept of a
shared library was born. The VM system also became more
sophisticated. While each one of these advancements was done
using the a.out format, its usefulness was
stretched more and more with each new feature. In addition,
people wanted to dynamically load things at run time, or to junk
parts of their program after the init code had run to save in
core memory and swap space. Languages became more sophisticated
and people wanted code called before main automatically. Lots of
hacks were done to the a.out format to
allow all of these things to happen, and they basically worked
for a time. In time, a.out was not up to
handling all these problems without an ever increasing overhead
in code and complexity. While ELF solved many
of these problems, it would be painful to switch from the system
that basically worked. So ELF had to wait
until it was more painful to remain with
a.out than it was to migrate to
ELF.However, as time passed, the build tools that FreeBSD
derived their build tools from (the assembler and loader
especially) evolved in two parallel trees. The FreeBSD tree
added shared libraries and fixed some bugs. The GNU folks that
originally wrote these programs rewrote them and added simpler
support for building cross compilers, plugging in different
formats at will, and so on. Since many people wanted to build cross
compilers targeting FreeBSD, they were out of luck since the
older sources that FreeBSD had for as and ld were not up to the
task. The new GNU tools chain (binutils) does support cross
compiling, ELF, shared libraries, C++
extensions, etc. In addition, many vendors are releasing
ELF binaries, and it is a good thing for
FreeBSD to run them.ELF is more expressive than a.out and
allows more extensibility in the base system. The
ELF tools are better maintained, and offer
cross compilation support, which is important to many people.
ELF may be a little slower than a.out, but
trying to measure it can be difficult. There are also numerous
details that are different between the two in how they map
pages, handle init code, etc. None of these are very important,
but they are differences. In time support for
a.out will be moved out of the GENERIC
kernel, and eventually removed from the kernel once the need to
run legacy a.out programs is past.更多資訊Manual Pagesmanual pagesThe most comprehensive documentation on FreeBSD is in the form
of manual pages. Nearly every program on the system comes with a
short reference manual explaining the basic operation and various
arguments. These manuals can be viewed with the man command. Use
of the man command is simple:&prompt.user; man commandcommand is the name of the command you
wish to learn about. For example, to learn more about
ls command type:&prompt.user; man lsThe online manual is divided up into numbered sections:User commands.System calls and error numbers.Functions in the C libraries.Device drivers.File formats.Games and other diversions.Miscellaneous information.System maintenance and operation commands.Kernel developers.In some cases, the same topic may appear in more than one
section of the online manual. For example, there is a
chmod user command and a
chmod() system call. In this case, you can
tell the man command which one you want by specifying the
section:&prompt.user; man 1 chmodThis will display the manual page for the user command
chmod. References to a particular section of
the online manual are traditionally placed in parenthesis in
written documentation, so &man.chmod.1; refers to the
chmod user command and &man.chmod.2; refers to
the system call.This is fine if you know the name of the command and simply
wish to know how to use it, but what if you cannot recall the
command name? You can use man to search for keywords in the
command descriptions by using the
switch:&prompt.user; man -k mailWith this command you will be presented with a list of
commands that have the keyword mail in their
descriptions. This is actually functionally equivalent to using
the apropos command.So, you are looking at all those fancy commands in
/usr/bin but do not have the faintest idea
what most of them actually do? Simply do:&prompt.user; cd /usr/bin
&prompt.user; man -f *or&prompt.user; cd /usr/bin
&prompt.user; whatis *which does the same thing.GNU Info FilesFree Software FoundationFreeBSD includes many applications and utilities produced by
the Free Software Foundation (FSF). In addition to manual pages,
these programs come with more extensive hypertext documents called
info files which can be viewed with the
info command or, if you installed
emacs, the info mode of
emacs.To use the &man.info.1; command, simply type:&prompt.user; infoFor a brief introduction, type h. For a
quick command reference, type ?.
diff --git a/zh_TW.Big5/books/handbook/config/chapter.sgml b/zh_TW.Big5/books/handbook/config/chapter.sgml
index 1a4597903c..4d488ad549 100644
--- a/zh_TW.Big5/books/handbook/config/chapter.sgml
+++ b/zh_TW.Big5/books/handbook/config/chapter.sgml
@@ -1,3051 +1,3171 @@
ChernLeeWritten by MikeSmithBased on a tutorial written by MattDillonAlso based on tuning(7) written by 設定與效能調校(Tuning)概述system configurationsystem optimization在 &os; 使用過程中,相當重要的環節之一就是系統設定部分。
正確的系統設定,可以讓你減輕日後升級的頭痛壓力。
本章著重於介紹 &os; 的相關重要設定上,包括一些可以調整 &os; 效能的參數設定。
讀完這章,您將了解:如何有效運用檔案系統以及 swap 分割區。rc.conf 的設定與 /usr/local/etc/rc.d 的啟動架構。如何設定、測試網路卡。如何設定 virtual hosts。如何設定 /etc 內的各種設定檔。如何以 sysctl 來調整 &os; 的系統效能。如何調整硬碟效能,以及更改 kernel 限制。在開始閱讀這章之前,您需要︰瞭解 &unix; 及 &os; 相關基本概念()。要有設定、編譯 kernel 的基礎概念()。一開始的規劃規劃分割區(Partition)partition layout/etc/var/usrBase Partitions用 &man.bsdlabel.8; 或 &man.sysinstall.8; 來規劃檔案系統時,請記住:
硬碟在傳輸資料方面,(由於結構為碟片因素)外圈會比內圈來得快些。
因此,建議把較小、常會存取的分割區儘量放外圈,而較大的分割區像是
/usr 則應放在較內圈。
建議建立分割區的順序,以像是:root, swap,
/var, /usr 這樣順序來建立會較妥。/var 的大小要視機器的用途而定。
/var 是用來放
信箱、log 紀錄檔以及印表機佇列(spools)。 信箱以及記錄檔的成長幅度可能無法預估,
因為這些成長幅度乃是取決於多少用戶、要放多久等管理原則而定。
通常這些使用者並沒有用到 1 GB 以上,但請切記:至少要保留一定空間給 /var/tmp
以便存放 packages。
而 /usr 分割區主要是用來放系統運作時所需的檔案、工具程式等,例如:
&man.ports.7; collection(建議安裝)跟 source tree(optional)。
在安裝 FreeBSD 時,這兩者都是可選擇裝與不裝的。
不過,這個分割區建議至少要有 2 GB 空間以上才夠用。規劃分割區大小時,記得多保留些成長空間。
否則若某個分割區滿了,但另一個分割區卻還剩很多空間,就會相當困窘。有些人可能會發現 &man.sysinstall.8; 的
Auto-defaults(自動預設值) 所做的分割區大小,
有時候會把 /var 以及 / 分割區設太小了。
我們建議是:請依使用情況以及需求,來手動調整相關分割區大小。Swap 分割區swap sizingswap partition根據經驗法則,通常 swap 分割區應該設為系統記憶體(RAM)大小的兩倍即可。
舉例來說:若機器有 128 MB RAM 的話,那麼
- swap 則應該設為 256 MB。 Systems with
- less memory may perform better with more swap.
- Less than 256 megabytes of swap is not recommended and
- memory expansion should be considered.
- The kernel's VM paging algorithms are tuned to
- perform best when the swap partition is at least two times the
- size of main memory. Configuring too little swap can lead to
- inefficiencies in the VM page scanning code and might create
- issues later if more memory is added.
-
- On larger systems with multiple SCSI disks (or
- multiple IDE disks operating on different controllers), it is
- recommend that a swap is configured on each drive (up
- to four drives). The swap partitions should be
- approximately the same size. The kernel can handle arbitrary
- sizes but internal data structures scale to 4 times the
- largest swap partition. Keeping the swap partitions near the
- same size will allow the kernel to optimally stripe swap space
- across disks.
- Large swap sizes are fine, even if swap is not
- used much. It might be easier to recover
- from a runaway program before being forced to reboot.
+ swap 則應該設為 256 MB。 記憶體較少的機器,可以透過增加更多 swap 空間來提昇效能。
+ 我們建議 swap 空間不要設低於 256 MB,而且該考慮增加記憶體才是良策。
+ 當 swap 最少為記憶體的兩倍大時,kernel 的 VM paging 演算法會把效能調整到最佳狀態。
+ 但若是機器記憶體很大,但 swap 卻劃分太少的話,會導致 VM page 掃瞄的效率過低,
+ 此外日後若增加更多記憶體時,也會導致一些異常狀況發生。
+
+ 在較大型的機器內,通常會有多顆 SCSI 磁碟(或多顆 IDE 磁碟接在不同 IDE 匯流排上),
+ 建議在每顆磁碟上都建立 swap(最多到四顆)。
+ 而這些 swap 應該都大約一樣大小,
+ Kernel 可接受任意大小的 swap,但內部資料結構則是最大塊 swap 的 4 倍。
+ 若有保持 swap 為同樣大小的話,則可讓 kernel 最佳化運用各磁碟之中的 swap 空間。
+ 即使不太常會用到,分配大的 swap 也都還可接受,
+ 因為它可在強制重開機之前讓你更容易從當掉的程式中恢復正常。為何要規劃 Partition?
- Several users think a single large partition will be fine,
- but there are several reasons why this is a bad idea.
- First, each partition has different operational
- characteristics and separating them allows the file system to
- tune accordingly. For example, the root
- and /usr partitions are read-mostly, without
- much writing. While a lot of reading and writing could
- occur in /var and
- /var/tmp.
+ 有些人覺得把硬碟就直接劃分一個大分割區就好了,
+ 但是事實上有些原因會證明為何這是個爛點子,
+ 首先,每個分割區都有不同的運作特性,把它們分開的話可以讓檔案系統來調整。
+ 比如: / 以及 /usr 分割區大多只是讀取而已,
+ 比較少在寫入。 而讀寫都很頻繁的則是 /var 及
+ /var/tmp。By properly partitioning a system, fragmentation
introduced in the smaller write heavy partitions
will not bleed over into the mostly-read partitions.
Keeping the write-loaded partitions closer to
the disk's edge,
will
increase I/O performance in the partitions where it occurs
the most. Now while I/O
performance in the larger partitions may be needed,
shifting them more toward the edge of the disk will not
lead to a significant performance improvement over moving
/var to the edge.
Finally, there are safety concerns. A smaller, neater root
partition which is mostly read-only has a greater
chance of surviving a bad crash.最主要的設定檔rc filesrc.confThe principal location for system configuration information
is within /etc/rc.conf. This file
contains a wide range of configuration information, principally
used at system startup to configure the system. Its name
directly implies this; it is configuration information for the
rc* files.An administrator should make entries in the
rc.conf file to
override the default settings from
/etc/defaults/rc.conf. The defaults file
should not be copied verbatim to /etc - it
contains default values, not examples. All system-specific
changes should be made in the rc.conf
file itself.A number of strategies may be applied in clustered
applications to separate site-wide configuration from
system-specific configuration in order to keep administration
overhead down. The recommended approach is to place site-wide
configuration into another file,
such as /etc/rc.conf.site, and then include
this file into /etc/rc.conf, which will
contain only system-specific information.As rc.conf is read by &man.sh.1; it is
trivial to achieve this. For example:rc.conf: . /etc/rc.conf.site
hostname="node15.example.com"
network_interfaces="fxp0 lo0"
ifconfig_fxp0="inet 10.1.1.1"rc.conf.site: defaultrouter="10.1.1.254"
saver="daemon"
blanktime="100"The rc.conf.site file can then be
distributed to every system using rsync or a
similar program, while the rc.conf file
remains unique.Upgrading the system using &man.sysinstall.8;
or make world will not overwrite the
rc.conf
file, so system configuration information will not be lost.各式應用程式的設定檔
- Typically, installed applications have their own
- configuration files, with their own syntax, etc. It is
- important that these files be kept separate from the base
- system, so that they may be easily located and managed by the
- package management tools.
+ 原則上,安裝的軟體都會有其自有的設定檔,也會有自己的格式及語法。
+ 因此,將其與系統分開獨立是件非常重要的事情。如此一來,套件管理工具將可以
+ 很輕易的找出這些設定檔並管理這些設定檔。/usr/local/etc
- Typically, these files are installed in
- /usr/local/etc. In the case where an
- application has a large number of configuration files, a
- subdirectory will be created to hold them.
+ 原則上,設定檔會被放置在 /usr/local/etc。
+ 若某軟體的設定檔為數眾多,那將會其下建立一個目錄以供放置
- Normally, when a port or package is installed, sample
- configuration files are also installed. These are usually
- identified with a .default suffix. If there
- are no existing
- configuration files for the application, they will be created by
- copying the .default files.
+ 通常,當一個 port 或 package 被安裝的同時,一些基本的設定範例
+ 也會一併被安裝至此。這些範例通常會被用 .default 做為副檔名。
+ 若安裝時沒有自行撰寫的軟體設定檔,那麼將會複製一份 .default 設定
+ 做為預設設定檔
- For example, consider the contents of the directory
- /usr/local/etc/apache:
+ 舉個例子,我們來看看 /usr/local/etc/apache:-rw-r--r-- 1 root wheel 2184 May 20 1998 access.conf
-rw-r--r-- 1 root wheel 2184 May 20 1998 access.conf.default
-rw-r--r-- 1 root wheel 9555 May 20 1998 httpd.conf
-rw-r--r-- 1 root wheel 9555 May 20 1998 httpd.conf.default
-rw-r--r-- 1 root wheel 12205 May 20 1998 magic
-rw-r--r-- 1 root wheel 12205 May 20 1998 magic.default
-rw-r--r-- 1 root wheel 2700 May 20 1998 mime.types
-rw-r--r-- 1 root wheel 2700 May 20 1998 mime.types.default
-rw-r--r-- 1 root wheel 7980 May 20 1998 srm.conf
-rw-r--r-- 1 root wheel 7933 May 20 1998 srm.conf.default
- The file sizes show that only the srm.conf
- file has been changed. A later update of the Apache port would not
- overwrite this changed file.
+ srm.conf 的檔案被修改過了,爾後 Apache 的更新
+ 將不會對這個已修改過的設定檔做任何變動。TomRhodesContributed by 各種 Services 的啟動方式servicesMany users choose to install third party software on &os;
from the Ports Collection. In many of these situations it
may be necessary to configure the software in a manner which
will allow it to be started upon system initialization. Services,
such as mail/postfix or
www/apache13 are just two
of the many software packages which may be started during system
initialization. This section explains the procedures available
for starting third party software.In &os;, most included services, such as &man.cron.8;, are
started through the system start up scripts. These scripts may
differ depending on &os; or vendor version; however, the most
important aspect to consider is that their start up configuration
can be handled through simple startup scripts.Before the advent of rc.d, applications would drop a
simple start up script into the
/usr/local/etc/rc.d
directory which would be read by the system initialization
scripts. These scripts would then be executed during the latter
stages of system start up.While many individuals have spent hours trying to merge the
old configuration style into the new system, the fact remains
that some third party utilities still require a script simply
dropped into the aforementioned directory. The subtle differences
in the scripts depend whether or not rc.d is being used. Prior
to &os; 5.1 the old configuration style is used and in
almost all cases a new style script would do just fine.While every script must meet some minimal requirements, most
of the time these requirements are &os; version
agnostic. Each script must have a .sh
extension appended to the end and every script must be
executable by the system. The latter may be achieved by using
the chmod command and setting the unique permissions
of 755. There should also be, at minimal,
an option to start the application and an
option to stop the application.The simplest start up script would probably look a little
bit like this one:#!/bin/sh
echo -n ' utility'
case "$1" in
start)
/usr/local/bin/utility
;;
stop)
kill -9 `cat /var/run/utility.pid`
;;
*)
echo "Usage: `basename $0` {start|stop}" >&2
exit 64
;;
esac
exit 0This script provides for a stop and
start option for
the application hereto referred simply as
utility.Could be started manually with:&prompt.root; /usr/local/etc/rc.d/utility.sh startWhile not all third party software requires the line in
rc.conf, almost every day a new port will
be modified to accept this configuration. Check the final output
of the installation for more information on a specific
application. Some third party software will provide start up
scripts which permit the application to be used with
rc.d; although, this will be discussed in the next section.Extended Application ConfigurationNow that &os; includes rc.d, configuration
of application startup has become easier, and more
featureful. Using the key words discussed in the
rc.d section,
applications may now be set to start after certain other
services for example DNS; may permit extra
flags to be passed through rc.conf in
place of hard coded flags in the start up script, etc. A
basic script may look similar to the following:#!/bin/sh
#
# PROVIDE: utility
# REQUIRE: DAEMON
# KEYWORD: shutdown
#
# DO NOT CHANGE THESE DEFAULT VALUES HERE
# SET THEM IN THE /etc/rc.conf FILE
#
utility_enable=${utility_enable-"NO"}
utility_flags=${utility_flags-""}
utility_pidfile=${utility_pidfile-"/var/run/utility.pid"}
. /etc/rc.subr
name="utility"
rcvar=`set_rcvar`
command="/usr/local/sbin/utility"
load_rc_config $name
pidfile="${utility_pidfile}"
start_cmd="echo \"Starting ${name}.\"; /usr/bin/nice -5 ${command} ${utility_flags} ${command_args}"
run_rc_command "$1"This script will ensure that the provided
utility will be started after the
daemon service. It also provides a method
for setting and tracking the PID, or process
ID file.This application could then have the following line placed
in /etc/rc.conf:utility_enable="YES"This new method also allows for easier manipulation of the
command line arguments, inclusion of the default functions
provided in /etc/rc.subr, compatibility
with the &man.rcorder.8; utility and provides for easier
configuration via the rc.conf file.以 Services 來啟動各式 ServicesOther services, such as POP3 server
daemons, IMAP, etc. could be started using
the &man.inetd.8;. This involves installing the service
utility from the Ports Collection with a configuration line
appended to the /etc/inetd.conf file,
or uncommenting one of the current configuration lines. Working
with inetd and its configuration is
described in depth in the
inetd section.In some cases, it may be more plausible to use the
&man.cron.8; daemon to start system services. This approach
has a number of advantages because cron runs
these processes as the crontab's file
owner. This allows regular users to start and maintain some
applications.The cron utility provides a unique
feature, @reboot, which may be used in place
of the time specification. This will cause the job to be run
when &man.cron.8; is started, normally during system
initialization.TomRhodesContributed by 設定 croncronconfiguration&os; 最好用的工具之一就是 &man.cron.8;。
cron 會在背景下運作,並不斷檢查
/etc/crontab 檔以及 /var/cron/tabs 目錄,來搜尋是否有新 crontab 檔案。
這些 crontab 檔會存放一些排程工作的設定,來給 cron 執行。cron 程式,可同時採用兩種不同類型的設定檔:系統本身的 crontab
及使用者本身的 crontab。而兩種格式唯一差別在於第六欄的不同;In the
system crontab, the sixth field is the name of a user for the command
to run as. This gives the system crontab the ability to run commands
as any user. In a user crontab, the sixth field is the command to run,
and all commands run as the user who created the crontab; this is an
important security feature.User crontabs allow individual users to schedule tasks without the
need for root privileges. Commands in a user's crontab run with the
permissions of the user who owns the crontab.The root user can have a user crontab just like
any other user. This one is different from
/etc/crontab (the system crontab). Because of the
system crontab, there is usually no need to create a user crontab
for root.Let us take a look at the /etc/crontab file
(the system crontab):# /etc/crontab - root's crontab for &os;
#
# $&os;: src/etc/crontab,v 1.32 2002/11/22 16:13:39 tom Exp $
#
#
SHELL=/bin/sh
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin
HOME=/var/log
#
#
#minute hour mday month wday who command
#
#
*/5 * * * * root /usr/libexec/atrun Like most &os; configuration files, the #
character represents a comment. A comment can be placed in
the file as a reminder of what and why a desired action is performed.
Comments cannot be on the same line as a command or else they will
be interpreted as part of the command; they must be on a new line.
Blank lines are ignored.First, the environment must be defined. The equals
(=) character is used to define any environment
settings, as with this example where it is used for the SHELL,
PATH, and HOME options. If the shell line is
omitted, cron will use the default, which is
sh. If the PATH variable is
omitted, no default will be used and file locations will need to
be absolute. If HOME is omitted, cron
will use the invoking users home directory.This line defines a total of seven fields. Listed here are the
values minute, hour,
mday, month, wday,
who, and command. These
are almost all self explanatory. minute is the time in minutes the
command will be run. hour is similar to the minute option, just in
hours. mday stands for day of the month. month is similar to hour
and minute, as it designates the month. The wday option stands for
day of the week. All these fields must be numeric values, and follow
the twenty-four hour clock. The who field is special,
and only exists in the /etc/crontab file.
This field specifies which user the command should be run as.
When a user installs his or her crontab file, they
will not have this option. Finally, the command option is listed.
This is the last field, so naturally it should designate the command
to be executed.This last line will define the values discussed above. Notice here
we have a */5 listing, followed by several more
* characters. These * characters
mean first-last, and can be interpreted as
every time. So, judging by this line,
it is apparent that the atrun command is to be invoked by
root every five minutes regardless of what
day or month it is. For more information on the atrun command,
see the &man.atrun.8; manual page.Commands can have any number of flags passed to them; however,
commands which extend to multiple lines need to be broken with the backslash
\ continuation character.This is the basic set up for every
crontab file, although there is one thing
different about this one. Field number six, where we specified
the username, only exists in the system
/etc/crontab file. This field should be
omitted for individual user crontab
files.工作排程(Crontab)的排定與管理You must not use the procedure described here to
edit/install the system crontab. Simply use your favorite
editor: the cron utility will notice that the file
has changed and immediately begin using the updated version.
See
this FAQ entry for more information.To install a freshly written user
crontab, first use your favorite editor to create
a file in the proper format, and then use the
crontab utility. The most common usage
is:&prompt.user; crontab crontab-fileIn this example, crontab-file is the filename
of a crontab that was previously created.There is also an option to list installed
crontab files: just pass the
option to crontab and look
over the output.For users who wish to begin their own crontab file from scratch,
without the use of a template, the crontab -e
option is available. This will invoke the selected editor
with an empty file. When the file is saved, it will be
automatically installed by the crontab command.
If you later want to remove your user crontab
completely, use crontab with the
option.
TomRhodesContributed by
- 在 &os; 5.X (含之後) 使用 rc
+ 在 &os; 使用 rc從 2002 年起,&os; 整合了 NetBSD 的 rc.d 機制來作為系統服務啟動機制。
可以到 /etc/rc.d 目錄下去看,很多檔案都是基本服務,可以用 ,
及 作為使用時的選項。
舉個例子,可以用下列指令來重新啟動 &man.sshd.8;:&prompt.root; /etc/rc.d/sshd restart其他服務也是類似作法。當然,
服務通常只要在 &man.rc.conf.5; 內有指定的話,都會在開機時就自動啟動。舉例來說,若要開機時啟動 NAT(Network Address
Translation) daemon 的話,只要在 /etc/rc.conf 內加上下列這行即可:natd_enable="YES"若原本寫的是 那麼只要把 改為
就好了。rc scripts 會在下次重開機時,自動載入相關(有相依)的服務,以下我們會講到這部分。Since the rc.d system is primarily
intended to start/stop services at system startup/shutdown time,
the standard ,
and options will only
perform their action if the appropriate
/etc/rc.conf variables are set. For
instance the above sshd restart command will
only work if sshd_enable is set to
in /etc/rc.conf. To
, or
a service regardless of the settings in
/etc/rc.conf, the commands should be
prefixed with force. For instance to restart
sshd regardless of the current
/etc/rc.conf setting, execute the following
command:&prompt.root; /etc/rc.d/sshd forcerestartIt is easy to check if a service is enabled in
/etc/rc.conf by running the appropriate
rc.d script with the option
. Thus, an administrator can check that
sshd is in fact enabled in
/etc/rc.conf by running:&prompt.root; /etc/rc.d/sshd rcvar
# sshd
$sshd_enable=YESThe second line (# sshd) is the output
from the sshd command, not a root
console.若要檢查服務是否有在運作,可以用 選項來查詢。比如:若要確認
sshd 是否真的有啟動的話,那麼打:&prompt.root; /etc/rc.d/sshd status
sshd is running as pid 433.In some cases it is also possible to a service.
This will attempt to send a signal to an individual service, forcing the
service to reload its configuration files. In most cases this
means sending the service a SIGHUP
signal. Support for this feature is not included for every service.The rc.d system is not only used for network services, it also
contributes to most of the system initialization. For
instance, consider the bgfsck file. When
this script is executed, it will print out the following
message:Starting background file system checks in 60 seconds.Therefore this file is used for background file system
checks, which are done only during system initialization.Many system services depend on other services to function
properly. For example, NIS and other RPC-based services may
fail to start until after the rpcbind
(portmapper) service has started. To resolve this issue,
information about dependencies and other meta-data is included
in the comments at the top of each startup script. The
&man.rcorder.8; program is then used to parse these comments
during system initialization to determine the order in which
system services should be invoked to satisfy the dependencies.
The following words may be included at the top of each startup
file:PROVIDE: Specifies the services this file provides.REQUIRE: Lists services which are required for this
service. This file will run after
the specified services.BEFORE: Lists services which depend on this service.
This file will run before
the specified services.By using this method, an administrator can easily control system
services without the hassle of runlevels like
some other &unix; operating systems.Additional information about the
rc.d system can be found in the &man.rc.8;
and &man.rc.subr.8; manual pages.MarcFonvieilleContributed by 設定網路卡network cardsconfigurationNowadays we can not think about a computer without thinking
about a network connection. Adding and configuring a network
card is a common task for any &os; administrator.選擇正確、可用的驅動程式(Driver)network cardsdriverBefore you begin, you should know the model of the card
you have, the chip it uses, and whether it is a PCI or ISA card.
&os; supports a wide variety of both PCI and ISA cards.
Check the Hardware Compatibility List for your release to see
if your card is supported.Once you are sure your card is supported, you need
to determine the proper driver for the card.
/usr/src/sys/conf/NOTES and
/usr/src/sys/arch/conf/NOTES will give you
the list of network interface drivers with some information
about the supported chipsets/cards. If you have doubts about
which driver is the correct one, read the manual page of the
driver. The manual page will give you more information about
the supported hardware and even the possible problems that
could occur.If you own a common card, most of the time you will not
have to look very hard for a driver. Drivers for common
network cards are present in the GENERIC
kernel, so your card should show up during boot, like so:dc0: <82c169 PNIC 10/100BaseTX> port 0xa000-0xa0ff mem 0xd3800000-0xd38
000ff irq 15 at device 11.0 on pci0
dc0: Ethernet address: 00:a0:cc:da:da:da
miibus0: <MII bus> on dc0
ukphy0: <Generic IEEE 802.3u media interface> on miibus0
ukphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
dc1: <82c169 PNIC 10/100BaseTX> port 0x9800-0x98ff mem 0xd3000000-0xd30
000ff irq 11 at device 12.0 on pci0
dc1: Ethernet address: 00:a0:cc:da:da:db
miibus1: <MII bus> on dc1
ukphy1: <Generic IEEE 802.3u media interface> on miibus1
ukphy1: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, autoIn this example, we see that two cards using the &man.dc.4;
driver are present on the system.If the driver for your NIC is not present in
GENERIC, you will need to load the proper
driver to use your NIC. This may be accomplished in one of
two ways:The easiest way is to simply load a kernel module for
- your network card with &man.kldload.8;. Not all NIC
+ your network card with &man.kldload.8;, or automatically at boot time by adding the appropriate line to the file /boot/loader.conf. Not all NIC
drivers are available as modules; notable examples of
devices for which modules do not exist are ISA cards.Alternatively, you may statically compile the support
for your card into your kernel. Check
/usr/src/sys/conf/NOTES,
/usr/src/sys/arch/conf/NOTES
and the manual page of the driver to know what to add in
your kernel configuration file. For more information
about recompiling your kernel, please see . If your card was detected at
boot by your kernel (GENERIC) you do
not have to build a new kernel.
+
+
+ Using &windows; NDIS Drivers
+
+ NDIS
+ NDISulator
+ &windows; drivers
+ Microsoft Windows
+ Microsoft Windows
+ device drivers
+ KLD (kernel loadable
+ object)
+
+
+ Unfortunately, there are still many vendors that do not
+ provide schematics for their drivers to the open source
+ community because they regard such information as trade
+ secrets. Consequently, the developers of &os; and other
+ operating systems are left two choices: develop the drivers
+ by a long and pain-staking process of reverse engineering or
+ using the existing driver binaries available for the
+ µsoft.windows; platforms. Most developers, including
+ those involved with &os;, have taken the latter
+ approach.
+
+ Thanks to the contributions of Bill Paul (wpaul), as of
+ &os; 5.3-RELEASE there is native support
+ for the Network Driver Interface Specification (NDIS). The
+ &os; NDISulator (otherwise known as Project Evil) takes a
+ &windows; driver binary and basically tricks it into
+ thinking it is running on &windows;. Because the
+ &man.ndis.4; driver is using a &windows; binary, it is only
+ usable on &i386; and amd64 systems.
+
+
+ The &man.ndis.4; driver is designed to support mainly
+ PCI, CardBus and PCMCIA devices, USB devices are not yet
+ supported.
+
+
+ In order to use the NDISulator, you need three
+ things:
+
+
+
+ Kernel sources
+
+
+ &windowsxp; driver binary
+ (.SYS extension)
+
+
+ &windowsxp; driver configuration file
+ (.INF extension)
+
+
+
+ Locate the files for your specific card. Generally,
+ they can be found on the included CDs or at the vendors'
+ websites. In the following examples, we will use
+ W32DRIVER.SYS and
+ W32DRIVER.INF.
+
+
+ You can not use a &windows;/i386 driver with
+ &os;/amd64, you must get a &windows;/amd64 driver to make it
+ work properly.
+
+
+ The next step is to compile the driver binary into a
+ loadable kernel module. To accomplish this, as
+ root, use &man.ndisgen.8;:
+
+ &prompt.root; ndisgen /path/to/W32DRIVER.INF/path/to/W32DRIVER.SYS
+
+ The &man.ndisgen.8; utility is interactive and will
+ prompt for any extra information it requires; it will
+ produce a kernel module in the current directory which can
+ be loaded as follows:
+
+ &prompt.root; kldload ./W32DRIVER.ko
+
+ In addition to the generated kernel module, you must
+ load the ndis.ko and
+ if_ndis.ko modules. This should be
+ automatically done when you load any module that depends on
+ &man.ndis.4;. If you want to load them manually, use the
+ following commands:
+
+ &prompt.root; kldload ndis
+&prompt.root; kldload if_ndis
+
+ The first command loads the NDIS miniport driver
+ wrapper, the second loads the actual network
+ interface.
+
+ Now, check &man.dmesg.8; to see if there were any errors
+ loading. If all went well, you should get output resembling
+ the following:
+
+ ndis0: <Wireless-G PCI Adapter> mem 0xf4100000-0xf4101fff irq 3 at device 8.0 on pci1
+ndis0: NDIS API version: 5.0
+ndis0: Ethernet address: 0a:b1:2c:d3:4e:f5
+ndis0: 11b rates: 1Mbps 2Mbps 5.5Mbps 11Mbps
+ndis0: 11g rates: 6Mbps 9Mbps 12Mbps 18Mbps 36Mbps 48Mbps 54Mbps
+
+ From here you can treat the
+ ndis0 device like any other network
+ interface (e.g., dc0).
+
+ You can configure the system to load the NDIS modules at
+ boot time in the same way as with any other module. First,
+ copy the generated module,
+ W32DRIVER.ko, to the /boot/modules directory. Then,
+ add the following line to
+ /boot/loader.conf:
+
+ W32DRIVER_load="YES"
+ 設定網路卡network cardsconfigurationOnce the right driver is loaded for the network card, the
card needs to be configured. As with many other things, the
network card may have been configured at installation time by
sysinstall.To display the configuration for the network interfaces on
your system, enter the following command:&prompt.user; ifconfig
dc0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 192.168.1.3 netmask 0xffffff00 broadcast 192.168.1.255
ether 00:a0:cc:da:da:da
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
dc1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
inet 10.0.0.1 netmask 0xffffff00 broadcast 10.0.0.255
ether 00:a0:cc:da:da:db
media: Ethernet 10baseT/UTP
status: no carrier
lp0: flags=8810<POINTOPOINT,SIMPLEX,MULTICAST> mtu 1500
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
inet 127.0.0.1 netmask 0xff000000
tun0: flags=8010<POINTOPOINT,MULTICAST> mtu 1500Old versions of &os; may require the
option following &man.ifconfig.8;, for more details about the
correct syntax of &man.ifconfig.8;, please refer to the manual
page. Note also that entries concerning IPv6
(inet6 etc.) were omitted in this
example.In this example, the following devices were
displayed:dc0: The first Ethernet
interfacedc1: The second Ethernet
interfacelp0: The parallel port
interfacelo0: The loopback devicetun0: The tunnel device used by
ppp&os; uses the driver name followed by the order in
which one the card is detected at the kernel boot to name the
network card. For example sis2 would
be the third network card on the system using the &man.sis.4;
driver.In this example, the dc0 device is
up and running. The key indicators are:UP means that the card is configured
and ready.The card has an Internet (inet)
address (in this case
192.168.1.3).It has a valid subnet mask (netmask;
0xffffff00 is the same as
255.255.255.0).It has a valid broadcast address (in this case,
192.168.1.255).The MAC address of the card (ether)
is 00:a0:cc:da:da:daThe physical media selection is on autoselection mode
(media: Ethernet autoselect (100baseTX
<full-duplex>)). We see that
dc1 was configured to run with
10baseT/UTP media. For more
information on available media types for a driver, please
refer to its manual page.The status of the link (status)
is active, i.e. the carrier is detected.
For dc1, we see
status: no carrier. This is normal when
an Ethernet cable is not plugged into the card.If the &man.ifconfig.8; output had shown something similar
to:dc0: flags=8843<BROADCAST,SIMPLEX,MULTICAST> mtu 1500
ether 00:a0:cc:da:da:dait would indicate the card has not been configured.To configure your card, you need root
privileges. The network card configuration can be done from the
command line with &man.ifconfig.8; but you would have to do it
after each reboot of the system. The file
/etc/rc.conf is where to add the network
card's configuration.Open /etc/rc.conf in your favorite
editor. You need to add a line for each network card present on
the system, for example in our case, we added these lines:ifconfig_dc0="inet 192.168.1.3 netmask 255.255.255.0"
ifconfig_dc1="inet 10.0.0.1 netmask 255.255.255.0 media 10baseT/UTP"You have to replace dc0,
dc1, and so on, with
the correct device for your cards, and the addresses with the
proper ones. You should read the card driver and
&man.ifconfig.8; manual pages for more details about the allowed
options and also &man.rc.conf.5; manual page for more
information on the syntax of
/etc/rc.conf.If you configured the network during installation, some
lines about the network card(s) may be already present. Double
check /etc/rc.conf before adding any
lines.You will also have to edit the file
/etc/hosts to add the names and the IP
addresses of various machines of the LAN, if they are not already
there. For more information please refer to &man.hosts.5;
and to /usr/share/examples/etc/hosts.測試與疑難排除Once you have made the necessary changes in
/etc/rc.conf, you should reboot your
system. This will allow the change(s) to the interface(s) to
be applied, and verify that the system restarts without any
configuration errors.Once the system has been rebooted, you should test the
network interfaces.測試乙太網路卡(Ethernet Card)network cardstestingTo verify that an Ethernet card is configured correctly,
you have to try two things. First, ping the interface itself,
and then ping another machine on the LAN.First test the local interface:&prompt.user; ping -c5 192.168.1.3
PING 192.168.1.3 (192.168.1.3): 56 data bytes
64 bytes from 192.168.1.3: icmp_seq=0 ttl=64 time=0.082 ms
64 bytes from 192.168.1.3: icmp_seq=1 ttl=64 time=0.074 ms
64 bytes from 192.168.1.3: icmp_seq=2 ttl=64 time=0.076 ms
64 bytes from 192.168.1.3: icmp_seq=3 ttl=64 time=0.108 ms
64 bytes from 192.168.1.3: icmp_seq=4 ttl=64 time=0.076 ms
--- 192.168.1.3 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.074/0.083/0.108/0.013 msNow we have to ping another machine on the LAN:&prompt.user; ping -c5 192.168.1.2
PING 192.168.1.2 (192.168.1.2): 56 data bytes
64 bytes from 192.168.1.2: icmp_seq=0 ttl=64 time=0.726 ms
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.766 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.700 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.747 ms
64 bytes from 192.168.1.2: icmp_seq=4 ttl=64 time=0.704 ms
--- 192.168.1.2 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.700/0.729/0.766/0.025 msYou could also use the machine name instead of
192.168.1.2 if you have set up the
/etc/hosts file.疑難排除network cardstroubleshootingTroubleshooting hardware and software configurations is always
a pain, and a pain which can be alleviated by checking the simple
things first. Is your network cable plugged in? Have you properly
configured the network services? Did you configure the firewall
correctly? Is the card you are using supported by &os;? Always
check the hardware notes before sending off a bug report. Update
your version of &os; to the latest STABLE version. Check the
mailing list archives, or perhaps search the Internet.If the card works, yet performance is poor, it would be
worthwhile to read over the &man.tuning.7; manual page. You
can also check the network configuration as incorrect network
settings can cause slow connections.Some users experience one or two device
timeout messages, which is normal for some cards. If they
continue, or are bothersome, you may wish to be sure the
device is not conflicting with another device. Double check
the cable connections. Perhaps you may just need to get
another card.At times, users see a few watchdog timeout
errors. The first thing to do here is to check your network
cable. Many cards require a PCI slot which supports Bus
Mastering. On some old motherboards, only one PCI slot allows
it (usually slot 0). Check the network card and the
motherboard documentation to determine if that may be the
problem.No route to host messages occur if the
system is unable to route a packet to the destination host.
This can happen if no default route is specified, or if a
cable is unplugged. Check the output of netstat
-rn and make sure there is a valid route to the host
you are trying to reach. If there is not, read on to .ping: sendto: Permission denied error
messages are often caused by a misconfigured firewall. If
ipfw is enabled in the kernel but no rules
have been defined, then the default policy is to deny all
traffic, even ping requests! Read on to for more information.Sometimes performance of the card is poor, or below average.
In these cases it is best to set the media selection mode
from autoselect to the correct media selection.
While this usually works for most hardware, it may not resolve
this issue for everyone. Again, check all the network settings,
and read over the &man.tuning.7; manual page.虛擬主機(Virtual Hosts)virtual hostsIP aliasesA very common use of &os; is virtual site hosting, where
one server appears to the network as many servers. This is
achieved by assigning multiple network addresses to a single
interface.A given network interface has one real address,
and may have any number of alias addresses.
These aliases are
normally added by placing alias entries in
/etc/rc.conf.An alias entry for the interface fxp0
looks like:ifconfig_fxp0_alias0="inet xxx.xxx.xxx.xxx netmask xxx.xxx.xxx.xxx"Note that alias entries must start with alias0 and proceed
upwards in order, (for example, _alias1, _alias2, and so on).
The configuration process will stop at the first missing number.
The calculation of alias netmasks is important, but
fortunately quite simple. For a given interface, there must be
one address which correctly represents the network's netmask.
Any other addresses which fall within this network must have a
netmask of all 1s (expressed as either
255.255.255.255 or 0xffffffff).
For example, consider the case where the
fxp0 interface is
connected to two networks, the 10.1.1.0
network with a netmask of 255.255.255.0
and the 202.0.75.16 network with
a netmask of 255.255.255.240.
We want the system to appear at 10.1.1.1
through 10.1.1.5 and at
202.0.75.17 through
202.0.75.20. As noted above, only the
first address in a given network range (in this case,
10.0.1.1 and
202.0.75.17) should have a real
netmask; all the rest (10.1.1.2
through 10.1.1.5 and
202.0.75.18 through
202.0.75.20) must be configured with a
netmask of 255.255.255.255.The following /etc/rc.conf entries
configure the adapter correctly for this arrangement:ifconfig_fxp0="inet 10.1.1.1 netmask 255.255.255.0"
ifconfig_fxp0_alias0="inet 10.1.1.2 netmask 255.255.255.255"
ifconfig_fxp0_alias1="inet 10.1.1.3 netmask 255.255.255.255"
ifconfig_fxp0_alias2="inet 10.1.1.4 netmask 255.255.255.255"
ifconfig_fxp0_alias3="inet 10.1.1.5 netmask 255.255.255.255"
ifconfig_fxp0_alias4="inet 202.0.75.17 netmask 255.255.255.240"
ifconfig_fxp0_alias5="inet 202.0.75.18 netmask 255.255.255.255"
ifconfig_fxp0_alias6="inet 202.0.75.19 netmask 255.255.255.255"
ifconfig_fxp0_alias7="inet 202.0.75.20 netmask 255.255.255.255"還有哪些主要設定檔呢?/etc LayoutThere are a number of directories in which configuration
information is kept. These include:/etcGeneric system configuration information; data here is
system-specific./etc/defaultsDefault versions of system configuration files./etc/mailExtra &man.sendmail.8; configuration, other
MTA configuration files.
/etc/pppConfiguration for both user- and kernel-ppp programs.
/etc/namedbDefault location for &man.named.8; data. Normally
named.conf and zone files are stored
here./usr/local/etcConfiguration files for installed applications.
May contain per-application subdirectories./usr/local/etc/rc.dStart/stop scripts for installed applications./var/dbAutomatically generated system-specific database files,
such as the package database, the locate database, and so
onHostnameshostnameDNS/etc/resolv.confresolv.conf/etc/resolv.conf dictates how &os;'s
resolver accesses the Internet Domain Name System (DNS).The most common entries to resolv.conf are:
nameserverThe IP address of a name server the resolver
should query. The servers are queried in the order
listed with a maximum of three.searchSearch list for hostname lookup. This is normally
determined by the domain of the local hostname.domainThe local domain name.A typical resolv.conf:search example.com
nameserver 147.11.1.11
nameserver 147.11.100.30Only one of the search and
domain options should be used.If you are using DHCP, &man.dhclient.8; usually rewrites
resolv.conf with information received from the
DHCP server./etc/hostshosts/etc/hosts is a simple text
database reminiscent of the old Internet. It works in
conjunction with DNS and NIS providing name to IP address
mappings. Local computers connected via a LAN can be placed
in here for simplistic naming purposes instead of setting up
a &man.named.8; server. Additionally,
/etc/hosts can be used to provide a
local record of Internet names, reducing the need to query
externally for commonly accessed names.# $&os;$
#
# Host Database
# This file should contain the addresses and aliases
# for local hosts that share this file.
# In the presence of the domain name service or NIS, this file may
# not be consulted at all; see /etc/nsswitch.conf for the resolution order.
#
#
::1 localhost localhost.my.domain myname.my.domain
127.0.0.1 localhost localhost.my.domain myname.my.domain
#
# Imaginary network.
#10.0.0.2 myname.my.domain myname
#10.0.0.3 myfriend.my.domain myfriend
#
# According to RFC 1918, you can use the following IP networks for
# private nets which will never be connected to the Internet:
#
# 10.0.0.0 - 10.255.255.255
# 172.16.0.0 - 172.31.255.255
# 192.168.0.0 - 192.168.255.255
#
# In case you want to be able to connect to the Internet, you need
# real official assigned numbers. PLEASE PLEASE PLEASE do not try
# to invent your own network numbers but instead get one from your
# network provider (if any) or from the Internet Registry (ftp to
# rs.internic.net, directory `/templates').
#/etc/hosts takes on the simple format
of:[Internet address] [official hostname] [alias1] [alias2] ...For example:10.0.0.1 myRealHostname.example.com myRealHostname foobar1 foobar2Consult &man.hosts.5; for more information.Log File Configurationlog filessyslog.confsyslog.confsyslog.conf is the configuration file
for the &man.syslogd.8; program. It indicates which types
of syslog messages are logged to particular
log files.# $&os;$
#
# Spaces ARE valid field separators in this file. However,
# other *nix-like systems still insist on using tabs as field
# separators. If you are sharing this file between systems, you
# may want to use only tabs as field separators here.
# Consult the syslog.conf(5) manual page.
*.err;kern.debug;auth.notice;mail.crit /dev/console
*.notice;kern.debug;lpr.info;mail.crit;news.err /var/log/messages
security.* /var/log/security
mail.info /var/log/maillog
lpr.info /var/log/lpd-errs
cron.* /var/log/cron
*.err root
*.notice;news.err root
*.alert root
*.emerg *
# uncomment this to log all writes to /dev/console to /var/log/console.log
#console.info /var/log/console.log
# uncomment this to enable logging of all log messages to /var/log/all.log
#*.* /var/log/all.log
# uncomment this to enable logging to a remote log host named loghost
#*.* @loghost
# uncomment these if you're running inn
# news.crit /var/log/news/news.crit
# news.err /var/log/news/news.err
# news.notice /var/log/news/news.notice
!startslip
*.* /var/log/slip.log
!ppp
*.* /var/log/ppp.logConsult the &man.syslog.conf.5; manual page for more
information.newsyslog.confnewsyslog.confnewsyslog.conf is the configuration
file for &man.newsyslog.8;, a program that is normally scheduled
to run by &man.cron.8;. &man.newsyslog.8; determines when log
files require archiving or rearranging.
logfile is moved to
logfile.0, logfile.0
is moved to logfile.1, and so on.
Alternatively, the log files may be archived in &man.gzip.1; format
causing them to be named: logfile.0.gz,
logfile.1.gz, and so on.newsyslog.conf indicates which log
files are to be managed, how many are to be kept, and when
they are to be touched. Log files can be rearranged and/or
archived when they have either reached a certain size, or at a
certain periodic time/date.# configuration file for newsyslog
# $&os;$
#
# filename [owner:group] mode count size when [ZB] [/pid_file] [sig_num]
/var/log/cron 600 3 100 * Z
/var/log/amd.log 644 7 100 * Z
/var/log/kerberos.log 644 7 100 * Z
/var/log/lpd-errs 644 7 100 * Z
/var/log/maillog 644 7 * @T00 Z
/var/log/sendmail.st 644 10 * 168 B
/var/log/messages 644 5 100 * Z
/var/log/all.log 600 7 * @T00 Z
/var/log/slip.log 600 3 100 * Z
/var/log/ppp.log 600 3 100 * Z
/var/log/security 600 10 100 * Z
/var/log/wtmp 644 3 * @01T05 B
/var/log/daily.log 640 7 * @T00 Z
/var/log/weekly.log 640 5 1 $W6D0 Z
/var/log/monthly.log 640 12 * $M1D0 Z
/var/log/console.log 640 5 100 * ZConsult the &man.newsyslog.8; manual page for more
information.sysctl.confsysctl.confsysctlsysctl.conf looks much like
rc.conf. Values are set in a
variable=value
form. The specified values are set after the system goes into
multi-user mode. Not all variables are settable in this mode.A sample sysctl.conf turning off logging
of fatal signal exits and letting Linux programs know they are really
running under &os;:kern.logsigexit=0 # Do not log fatal signal exits (e.g. sig 11)
compat.linux.osname=&os;
compat.linux.osrelease=4.3-STABLETuning with sysctlsysctltuningwith sysctl&man.sysctl.8; is an interface that allows you to make changes
to a running &os; system. This includes many advanced
options of the TCP/IP stack and virtual memory system that can
dramatically improve performance for an experienced system
administrator. Over five hundred system variables can be read
and set using &man.sysctl.8;.At its core, &man.sysctl.8; serves two functions: to read and
to modify system settings.To view all readable variables:&prompt.user; sysctl -aTo read a particular variable, for example,
kern.maxproc:&prompt.user; sysctl kern.maxproc
kern.maxproc: 1044To set a particular variable, use the intuitive
variable=value
syntax:&prompt.root; sysctl kern.maxfiles=5000
kern.maxfiles: 2088 -> 5000Settings of sysctl variables are usually either strings,
numbers, or booleans (a boolean being 1 for yes
or a 0 for no).If you want to set automatically some variables each time
the machine boots, add them to the
/etc/sysctl.conf file. For more information
see the &man.sysctl.conf.5; manual page and the
.TomRhodesContributed by &man.sysctl.8; Read-onlyIn some cases it may be desirable to modify read-only &man.sysctl.8;
values. While this is sometimes unavoidable, it can only be done
on (re)boot.For instance on some laptop models the &man.cardbus.4; device will
not probe memory ranges, and fail with errors which look similar to:cbb0: Could not map register memory
device_probe_and_attach: cbb0 attach returned 12Cases like the one above usually require the modification of some
default &man.sysctl.8; settings which are set read only. To overcome
these situations a user can put &man.sysctl.8; OIDs
in their local /boot/loader.conf. Default
settings are located in the /boot/defaults/loader.conf
file.Fixing the problem mentioned above would require a user to set
in the aforementioned
file. Now &man.cardbus.4; will work properly.Tuning DisksSysctl Variablesvfs.vmiodirenablevfs.vmiodirenableThe vfs.vmiodirenable sysctl variable
may be set to either 0 (off) or 1 (on); it is 1 by default.
This variable controls how directories are cached by the
system. Most directories are small, using just a single
fragment (typically 1 K) in the file system and less
(typically 512 bytes) in the buffer cache.
With this variable turned off (to 0), the buffer
cache will only cache a fixed number of directories even if
you have a huge amount of memory. When turned on (to 1), this sysctl
allows the buffer cache to use the VM Page Cache to cache the
directories, making all the memory available for caching
directories. However,
the minimum in-core memory used to cache a directory is the
physical page size (typically 4 K) rather than 512
bytes. We recommend keeping this option on if you are running
any services which manipulate large numbers of files. Such
services can include web caches, large mail systems, and news
systems. Keeping this option on will generally not reduce
performance even with the wasted memory but you should
experiment to find out.vfs.write_behindvfs.write_behindThe vfs.write_behind sysctl variable
defaults to 1 (on). This tells the file system
to issue media writes as full clusters are collected, which
typically occurs when writing large sequential files. The idea
is to avoid saturating the buffer cache with dirty buffers when
it would not benefit I/O performance. However, this may stall
processes and under certain circumstances you may wish to turn it
off.vfs.hirunningspacevfs.hirunningspaceThe vfs.hirunningspace sysctl variable
determines how much outstanding write I/O may be queued to disk
controllers system-wide at any given instance. The default is
usually sufficient but on machines with lots of disks you may
want to bump it up to four or five megabytes.
Note that setting too high a value (exceeding the buffer cache's
write threshold) can lead to extremely bad clustering
performance. Do not set this value arbitrarily high! Higher
write values may add latency to reads occurring at the same time.
There are various other buffer-cache and VM page cache
related sysctls. We do not recommend modifying these values,
the VM system does an extremely good job of
automatically tuning itself.vm.swap_idle_enabledvm.swap_idle_enabledThe vm.swap_idle_enabled sysctl variable
is useful in large multi-user systems where you have lots of
users entering and leaving the system and lots of idle processes.
Such systems tend to generate a great deal of continuous pressure
on free memory reserves. Turning this feature on and tweaking
the swapout hysteresis (in idle seconds) via
vm.swap_idle_threshold1 and
vm.swap_idle_threshold2 allows you to depress
the priority of memory pages associated with idle processes more
quickly then the normal pageout algorithm. This gives a helping
hand to the pageout daemon. Do not turn this option on unless
you need it, because the tradeoff you are making is essentially
pre-page memory sooner rather than later; thus eating more swap
and disk bandwidth. In a small system this option will have a
determinable effect but in a large system that is already doing
moderate paging this option allows the VM system to stage whole
processes into and out of memory easily.hw.ata.wchw.ata.wc&os; 4.3 flirted with turning off IDE write caching.
This reduced write bandwidth to IDE disks but was considered
necessary due to serious data consistency issues introduced
by hard drive vendors. The problem is that IDE
drives lie about when a write completes. With IDE write
caching turned on, IDE hard drives not only write data
to disk out of order, but will sometimes delay writing some
blocks indefinitely when under heavy disk loads. A crash or
power failure may cause serious file system corruption.
&os;'s default was changed to be safe. Unfortunately, the
result was such a huge performance loss that we changed
write caching back to on by default after the release. You
should check the default on your system by observing the
hw.ata.wc sysctl variable. If IDE write
caching is turned off, you can turn it back on by setting
the kernel variable back to 1. This must be done from the
boot loader at boot time. Attempting to do it after the
kernel boots will have no effect.For more information, please see &man.ata.4;.SCSI_DELAY
(kern.cam.scsi_delay)kern.cam.scsi_delaykernel optionsSCSI_DELAYThe SCSI_DELAY kernel config may be used to
reduce system boot times. The defaults are fairly high and can be
responsible for 15 seconds of delay in the
boot process. Reducing it to 5 seconds usually
works (especially with modern drives). Newer versions of &os;
(5.0 and higher) should use the kern.cam.scsi_delay
boot time tunable. The tunable, and kernel config option accept
values in terms of milliseconds and
notseconds.Soft UpdatesSoft UpdatestunefsThe &man.tunefs.8; program can be used to fine-tune a
file system. This program has many different options, but for
now we are only concerned with toggling Soft Updates on and
off, which is done by:&prompt.root; tunefs -n enable /filesystem
&prompt.root; tunefs -n disable /filesystemA filesystem cannot be modified with &man.tunefs.8; while
it is mounted. A good time to enable Soft Updates is before any
partitions have been mounted, in single-user mode.Soft Updates drastically improves meta-data performance, mainly
file creation and deletion, through the use of a memory cache. We
recommend to use Soft Updates on all of your file systems. There
are two downsides to Soft Updates that you should be aware of: First,
Soft Updates guarantees filesystem consistency in the case of a crash
but could very easily be several seconds (even a minute!) behind
updating the physical disk. If your system crashes you may lose more
work than otherwise. Secondly, Soft Updates delays the freeing of
filesystem blocks. If you have a filesystem (such as the root
filesystem) which is almost full, performing a major update, such as
make installworld, can cause the filesystem to run
out of space and the update to fail.More Details about Soft UpdatesSoft UpdatesdetailsThere are two traditional approaches to writing a file
systems meta-data back to disk. (Meta-data updates are
updates to non-content data like inodes or
directories.)Historically, the default behavior was to write out
meta-data updates synchronously. If a directory had been
changed, the system waited until the change was actually
written to disk. The file data buffers (file contents) were
passed through the buffer cache and backed up
to disk later on asynchronously. The advantage of this
implementation is that it operates safely. If there is
a failure during an update, the meta-data are always in a
consistent state. A file is either created completely
or not at all. If the data blocks of a file did not find
their way out of the buffer cache onto the disk by the time
of the crash, &man.fsck.8; is able to recognize this and
repair the filesystem by setting the file length to
0. Additionally, the implementation is clear and simple.
The disadvantage is that meta-data changes are slow. An
rm -r, for instance, touches all the files
in a directory sequentially, but each directory
change (deletion of a file) will be written synchronously
to the disk. This includes updates to the directory itself,
to the inode table, and possibly to indirect blocks
allocated by the file. Similar considerations apply for
unrolling large hierarchies (tar -x).The second case is asynchronous meta-data updates. This
is the default for Linux/ext2fs and
mount -o async for *BSD ufs. All
meta-data updates are simply being passed through the buffer
cache too, that is, they will be intermixed with the updates
of the file content data. The advantage of this
implementation is there is no need to wait until each
meta-data update has been written to disk, so all operations
which cause huge amounts of meta-data updates work much
faster than in the synchronous case. Also, the
implementation is still clear and simple, so there is a low
risk for bugs creeping into the code. The disadvantage is
that there is no guarantee at all for a consistent state of
the filesystem. If there is a failure during an operation
that updated large amounts of meta-data (like a power
failure, or someone pressing the reset button),
the filesystem
will be left in an unpredictable state. There is no opportunity
to examine the state of the filesystem when the system
comes up again; the data blocks of a file could already have
been written to the disk while the updates of the inode
table or the associated directory were not. It is actually
impossible to implement a fsck which is
able to clean up the resulting chaos (because the necessary
information is not available on the disk). If the
filesystem has been damaged beyond repair, the only choice
is to use &man.newfs.8; on it and restore it from backup.
The usual solution for this problem was to implement
dirty region logging, which is also
referred to as journaling, although that
term is not used consistently and is occasionally applied
to other forms of transaction logging as well. Meta-data
updates are still written synchronously, but only into a
small region of the disk. Later on they will be moved
to their proper location. Because the logging
area is a small, contiguous region on the disk, there
are no long distances for the disk heads to move, even
during heavy operations, so these operations are quicker
than synchronous updates.
Additionally the complexity of the implementation is fairly
limited, so the risk of bugs being present is low. A disadvantage
is that all meta-data are written twice (once into the
logging region and once to the proper location) so for
normal work, a performance pessimization
might result. On the other hand, in case of a crash, all
pending meta-data operations can be quickly either rolled-back
or completed from the logging area after the system comes
up again, resulting in a fast filesystem startup.Kirk McKusick, the developer of Berkeley FFS,
solved this problem with Soft Updates: all pending
meta-data updates are kept in memory and written out to disk
in a sorted sequence (ordered meta-data
updates). This has the effect that, in case of
heavy meta-data operations, later updates to an item
catch the earlier ones if the earlier ones are still in
memory and have not already been written to disk. So all
operations on, say, a directory are generally performed in
memory before the update is written to disk (the data
blocks are sorted according to their position so
that they will not be on the disk ahead of their meta-data).
If the system crashes, this causes an implicit log
rewind: all operations which did not find their way
to the disk appear as if they had never happened. A
consistent filesystem state is maintained that appears to
be the one of 30 to 60 seconds earlier. The
algorithm used guarantees that all resources in use
are marked as such in their appropriate bitmaps: blocks and inodes.
After a crash, the only resource allocation error
that occurs is that resources are
marked as used which are actually free.
&man.fsck.8; recognizes this situation,
and frees the resources that are no longer used. It is safe to
ignore the dirty state of the filesystem after a crash by
forcibly mounting it with mount -f. In
order to free resources that may be unused, &man.fsck.8;
needs to be run at a later time. This is the idea behind
the background fsck: at system startup
time, only a snapshot of the
filesystem is recorded. The fsck can be
run later on. All file systems can then be mounted
dirty, so the system startup proceeds in
multiuser mode. Then, background fscks
will be scheduled for all file systems where this is required, to free
resources that may be unused. (File systems that do not use
Soft Updates still need the usual foreground
fsck though.)The advantage is that meta-data operations are nearly as
fast as asynchronous updates (i.e. faster than with
logging, which has to write the
meta-data twice). The disadvantages are the complexity of
the code (implying a higher risk for bugs in an area that
is highly sensitive regarding loss of user data), and a
higher memory consumption. Additionally there are some
idiosyncrasies one has to get used to.
After a crash, the state of the filesystem appears to be
somewhat older. In situations where
the standard synchronous approach would have caused some
zero-length files to remain after the
fsck, these files do not exist at all
with a Soft Updates filesystem because neither the meta-data
nor the file contents have ever been written to disk.
Disk space is not released until the updates have been
written to disk, which may take place some time after
running rm. This may cause problems
when installing large amounts of data on a filesystem
that does not have enough free space to hold all the files
twice.Tuning Kernel Limitstuningkernel limitsFile/Process Limitskern.maxfileskern.maxfileskern.maxfiles can be raised or
lowered based upon your system requirements. This variable
indicates the maximum number of file descriptors on your
system. When the file descriptor table is full,
file: table is full will show up repeatedly
in the system message buffer, which can be viewed with the
dmesg command.Each open file, socket, or fifo uses one file
descriptor. A large-scale production server may easily
require many thousands of file descriptors, depending on the
kind and number of services running concurrently.
- kern.maxfile's default value is
+ In older FreeBSD releases, kern.maxfile's default
+ value is derived from the option in your
dictated by the option in your
kernel configuration file. kern.maxfiles grows
proportionally to the value of . When
compiling a custom kernel, it is a good idea to set this kernel
configuration option according to the uses of your system. From
this number, the kernel is given most of its pre-defined limits.
Even though a production machine may not actually have 256 users
connected at once, the resources needed may be similar to a
high-scale web server.
+ As of FreeBSD 4.5, kern.maxusers is
+ automatically sized at boot based on the amount of memory available
+ in the system, and may be determined at run-time by inspecting the
+ value of the read-only kern.maxusers sysctl.
+ Some sites will require larger or smaller values of
+ kern.maxusers and may set it as a loader tunable;
+ values of 64, 128, and 256 are not uncommon. We do not recommend
+ going above 256 unless you need a huge number of file descriptors;
+ many of the tunable values set to their defaults by
+ kern.maxusers may be individually overridden at
+ boot-time or run-time in /boot/loader.conf (see
+ the &man.loader.conf.5; man page or the
+ /boot/defaults/loader.conf file for some hints)
+ or as described elsewhere in this document. Systems older than
+ FreeBSD 4.4 must set this value via the kernel &man.config.8;
+ option instead.
+
The system will auto-tune
maxusers for you if you explicitly set it to
0The auto-tuning algorithm sets
maxusers equal to the amount of memory in the
system, with a minimum of 32, and a maximum of 384.. When setting this option, you will want to set
maxusers to at least 4, especially if you are
using the X Window System or compiling software. The reason is that
the most important table set by maxusers is the
maximum number of processes, which is set to 20 + 16 *
maxusers, so if you set maxusers to 1,
then you can only have 36 simultaneous processes, including the 18
or so that the system starts up at boot time and the 15 or so you
will probably create when you start the X Window System. Even a
simple task like reading a manual page will start up nine
processes to filter, decompress, and view it. Setting
maxusers to 64 will allow you to have up to 1044
simultaneous processes, which should be enough for nearly all uses.
If, however, you see the dreaded proc table
full error when trying to start another program, or are
running a server with a large number of simultaneous users (like
ftp.FreeBSD.org), you can always
increase the number and rebuild.maxusers does not
limit the number of users which can log into your machine. It
simply sets various table sizes to reasonable values considering
the maximum number of users you will likely have on your system
and how many processes each of them will be running. One keyword
which does limit the number of simultaneous
remote logins and X terminal windows is pseudo-device pty
16. With &os; 5.X, you do not have to
worry about this number since the &man.pty.4; driver is
auto-cloning; you simply use the line
device pty in your configuration file.kern.ipc.somaxconnkern.ipc.somaxconnThe kern.ipc.somaxconn sysctl variable
limits the size of the listen queue for accepting new TCP
connections. The default value of 128 is
typically too low for robust handling of new connections in a
heavily loaded web server environment. For such environments, it
is recommended to increase this value to 1024 or
higher. The service daemon may itself limit the listen queue size
(e.g. &man.sendmail.8;, or Apache) but
will often have a directive in its configuration file to adjust
the queue size. Large listen queues also do a better job of
avoiding Denial of Service (DoS) attacks.Network LimitsThe NMBCLUSTERS kernel configuration
option dictates the amount of network Mbufs available to the
system. A heavily-trafficked server with a low number of Mbufs
will hinder &os;'s ability. Each cluster represents
approximately 2 K of memory, so a value of 1024 represents 2
megabytes of kernel memory reserved for network buffers. A
simple calculation can be done to figure out how many are
needed. If you have a web server which maxes out at 1000
simultaneous connections, and each connection eats a 16 K receive
and 16 K send buffer, you need approximately 32 MB worth of
network buffers to cover the web server. A good rule of thumb is
to multiply by 2, so 2x32 MB / 2 KB =
64 MB / 2 kB = 32768. We recommend
values between 4096 and 32768 for machines with greater amounts
of memory. Under no circumstances should you specify an
arbitrarily high value for this parameter as it could lead to a
boot time crash. The option to
&man.netstat.1; may be used to observe network cluster
use.kern.ipc.nmbclusters loader tunable should
be used to tune this at boot time. Only older versions of &os;
will require you to use the NMBCLUSTERS kernel
&man.config.8; option.For busy servers that make extensive use of the
&man.sendfile.2; system call, it may be necessary to increase
the number of &man.sendfile.2; buffers via the
NSFBUFS kernel configuration option or by
setting its value in /boot/loader.conf
(see &man.loader.8; for details). A common indicator that
this parameter needs to be adjusted is when processes are seen
in the sfbufa state. The sysctl
variable kern.ipc.nsfbufs is a read-only
glimpse at the kernel configured variable. This parameter
nominally scales with kern.maxusers,
however it may be necessary to tune accordingly.Even though a socket has been marked as non-blocking,
calling &man.sendfile.2; on the non-blocking socket may
result in the &man.sendfile.2; call blocking until enough
struct sf_buf's are made
available.net.inet.ip.portrange.*net.inet.ip.portrange.*The net.inet.ip.portrange.* sysctl
variables control the port number ranges automatically bound to TCP
and UDP sockets. There are three ranges: a low range, a default
range, and a high range. Most network programs use the default
range which is controlled by the
net.inet.ip.portrange.first and
net.inet.ip.portrange.last, which default to
1024 and 5000, respectively. Bound port ranges are used for
outgoing connections, and it is possible to run the system out of
ports under certain circumstances. This most commonly occurs
when you are running a heavily loaded web proxy. The port range
is not an issue when running servers which handle mainly incoming
connections, such as a normal web server, or has a limited number
of outgoing connections, such as a mail relay. For situations
where you may run yourself out of ports, it is recommended to
increase net.inet.ip.portrange.last modestly.
A value of 10000, 20000 or
30000 may be reasonable. You should also
consider firewall effects when changing the port range. Some
firewalls may block large ranges of ports (usually low-numbered
ports) and expect systems to use higher ranges of ports for
outgoing connections — for this reason it is not recommended that
net.inet.ip.portrange.first be lowered.TCP Bandwidth Delay ProductTCP Bandwidth Delay Product Limitingnet.inet.tcp.inflight.enableThe TCP Bandwidth Delay Product Limiting is similar to
TCP/Vegas in NetBSD. It can be
enabled by setting net.inet.tcp.inflight.enable
sysctl variable to 1. The system will attempt
to calculate the bandwidth delay product for each connection and
limit the amount of data queued to the network to just the amount
required to maintain optimum throughput.This feature is useful if you are serving data over modems,
Gigabit Ethernet, or even high speed WAN links (or any other link
with a high bandwidth delay product), especially if you are also
using window scaling or have configured a large send window. If
you enable this option, you should also be sure to set
net.inet.tcp.inflight.debug to
0 (disable debugging), and for production use
setting net.inet.tcp.inflight.min to at least
6144 may be beneficial. However, note that
setting high minimums may effectively disable bandwidth limiting
depending on the link. The limiting feature reduces the amount of
data built up in intermediate route and switch packet queues as
well as reduces the amount of data built up in the local host's
interface queue. With fewer packets queued up, interactive
connections, especially over slow modems, will also be able to
operate with lower Round Trip Times. However,
note that this feature only effects data transmission (uploading
/ server side). It has no effect on data reception (downloading).
Adjusting net.inet.tcp.inflight.stab is
not recommended. This parameter defaults to
20, representing 2 maximal packets added to the bandwidth delay
product window calculation. The additional window is required to
stabilize the algorithm and improve responsiveness to changing
conditions, but it can also result in higher ping times over slow
links (though still much lower than you would get without the
inflight algorithm). In such cases, you may wish to try reducing
this parameter to 15, 10, or 5; and may also have to reduce
net.inet.tcp.inflight.min (for example, to
3500) to get the desired effect. Reducing these parameters
should be done as a last resort only.Virtual Memorykern.maxvnodesA vnode is the internal representation of a file or
directory. So increasing the number of vnodes available to
the operating system cuts down on disk I/O. Normally this
is handled by the operating system and does not need to be
changed. In some cases where disk I/O is a bottleneck and
the system is running out of vnodes, this setting will need
to be increased. The amount of inactive and free RAM will
need to be taken into account.To see the current number of vnodes in use:&prompt.root; sysctl vfs.numvnodes
vfs.numvnodes: 91349To see the maximum vnodes:&prompt.root; sysctl kern.maxvnodes
kern.maxvnodes: 100000If the current vnode usage is near the maximum, increasing
kern.maxvnodes by a value of 1,000 is
probably a good idea. Keep an eye on the number of
vfs.numvnodes. If it climbs up to the
maximum again, kern.maxvnodes will need to
be increased further. A shift in your memory usage as
reported by &man.top.1; should be visible. More memory should
be active.Adding Swap SpaceNo matter how well you plan, sometimes a system does not run
as you expect. If you find you need more swap space, it is
simple enough to add. You have three ways to increase swap
space: adding a new hard drive, enabling swap over NFS, and
creating a swap file on an existing partition.For information on how to encrypt swap space, what options
for this task exist and why it should be done, please refer to
of the Handbook.Swap on a New Hard DriveThe best way to add swap, of course, is to use this as an
excuse to add another hard drive. You can always use another
hard drive, after all. If you can do this, go reread the
discussion of swap space
in
of the Handbook for some suggestions on how to best
arrange your swap.Swapping over NFSSwapping over NFS is only recommended if you do not have a
local hard disk to swap to; NFS swapping will be limited
by the available network bandwidth and puts an additional
burden on the NFS server.SwapfilesYou can create a file of a specified size to use as a swap
file. In our example here we will use a 64MB file called
/usr/swap0. You can use any name you
want, of course.Creating a Swapfile on &os;Be certain that your kernel configuration includes
the memory disk driver (&man.md.4;). It is default in
GENERIC kernel.device md # Memory "disks"Create a swapfile (/usr/swap0):&prompt.root; dd if=/dev/zero of=/usr/swap0 bs=1024k count=64Set proper permissions on (/usr/swap0):&prompt.root; chmod 0600 /usr/swap0Enable the swap file in /etc/rc.conf:swapfile="/usr/swap0" # Set to name of swapfile if aux swapfile desired.Reboot the machine or to enable the swap file immediately,
type:&prompt.root; mdconfig -a -t vnode -f /usr/swap0 -u 0 && swapon /dev/md0HitenPandyaWritten by TomRhodesPower and Resource ManagementIt is very important to utilize hardware resources in an
efficient manner. Before ACPI was introduced,
it was very difficult and inflexible for operating systems to manage
the power usage and thermal properties of a system. The hardware was
controlled by some sort of BIOS embedded
interface, such as Plug and Play BIOS (PNPBIOS), or
Advanced Power Management (APM) and so on.
Power and Resource Management is one of the key components of a modern
operating system. For example, you may want an operating system to
monitor system limits (and possibly alert you) in case your system
temperature increased unexpectedly.In this section of the &os; Handbook, we will provide
comprehensive information about ACPI. References
will be provided for further reading at the end.What Is ACPI?ACPIAPMAdvanced Configuration and Power Interface
(ACPI) is a standard written by
an alliance of vendors to provide a standard interface for
hardware resources and power management (hence the name).
It is a key element in Operating System-directed
configuration and Power Management, i.e.: it provides
more control and flexibility to the operating system
(OS).
Modern systems stretched the limits of the
current Plug and Play interfaces prior to the introduction of
ACPI. ACPI is the direct
successor to APM
(Advanced Power Management).Shortcomings of Advanced Power Management (APM)The Advanced Power Management (APM)
facility controls the power usage of a system based on its
activity. The APM BIOS is supplied by the (system) vendor and
it is specific to the hardware platform. An APM driver in the
OS mediates access to the APM Software Interface,
which allows management of power levels.There are four major problems in APM. Firstly, power
management is done by the (vendor-specific) BIOS, and the OS
does not have any knowledge of it. One example of this, is when
the user sets idle-time values for a hard drive in the APM BIOS,
that when exceeded, it (BIOS) would spin down the hard drive,
without the consent of the OS. Secondly, the APM logic is
embedded in the BIOS, and it operates outside the scope of the
OS. This means users can only fix problems in their APM BIOS by
flashing a new one into the ROM; which is a very dangerous
procedure with the potential to leave the system in an
unrecoverable state if it fails. Thirdly, APM is a vendor-specific
technology, which means that there is a lot of parity
(duplication of efforts) and bugs found in one vendor's BIOS,
may not be solved in others. Last but not the least, the APM
BIOS did not have enough room to implement a sophisticated power
policy, or one that can adapt very well to the purpose of the
machine.Plug and Play BIOS (PNPBIOS) was
unreliable in many situations. PNPBIOS is 16-bit technology,
so the OS has to use 16-bit emulation in order to
interface with PNPBIOS methods.The &os; APM driver is documented in
the &man.apm.4; manual page.Configuring ACPIThe acpi.ko driver is loaded by default
at start up by the &man.loader.8; and should not
be compiled into the kernel. The reasoning behind this is that modules
are easier to work with, say if switching to another acpi.ko
without doing a kernel rebuild. This has the advantage of making testing easier.
Another reason is that starting ACPI after a system has been
brought up is not too useful, and in some cases can be fatal. In doubt, just
disable ACPI all together. This driver should not and can not
be unloaded because the system bus uses it for various hardware interactions.
ACPI can be disabled with the &man.acpiconf.8; utility.
In fact most of the interaction with ACPI can be done via
&man.acpiconf.8;. Basically this means, if anything about ACPI
is in the &man.dmesg.8; output, then most likely it is already running.ACPI and APM cannot coexist and
should be used separately. The last one to load will terminate if the driver
notices the other running.In the simplest form, ACPI can be used to put the
system into a sleep mode with &man.acpiconf.8;, the
flag, and a 1-5 option. Most users will only need
1. Option 5 will do a soft-off
which is the same action as:&prompt.root; halt -pThe other options are available. Check out the &man.acpiconf.8;
manual page for more information.NateLawsonWritten by PeterSchultzWith contributions from TomRhodesUsing and Debugging &os; ACPIACPIproblemsACPI is a fundamentally new way of
discovering devices, managing power usage, and providing
standardized access to various hardware previously managed
by the BIOS. Progress is being made toward
ACPI working on all systems, but bugs in some
motherboards' ACPI Machine
Language (AML) bytecode,
incompleteness in &os;'s kernel subsystems, and bugs in the &intel;
ACPI-CA interpreter continue to appear.This document is intended to help you assist the &os;
ACPI maintainers in identifying the root cause
of problems you observe and debugging and developing a solution.
Thanks for reading this and we hope we can solve your system's
problems.Submitting Debugging InformationBefore submitting a problem, be sure you are running the latest
BIOS version and, if available, embedded
controller firmware version.For those of you that want to submit a problem right away,
please send the following information to
freebsd-acpi@FreeBSD.org:Description of the buggy behavior, including system type
and model and anything that causes the bug to appear. Also,
please note as accurately as possible when the bug began
occurring if it is new for you.The &man.dmesg.8; output after boot
-v, including any error messages
generated by you exercising the bug.The &man.dmesg.8; output from boot
-v with ACPI
disabled, if disabling it helps fix the problem.Output from sysctl hw.acpi. This is also
a good way of figuring out what features your system
offers.URL where your
ACPI Source Language
(ASL)
can be found. Do not send the
ASL directly to the list as it can be
very large. Generate a copy of your ASL
by running this command:&prompt.root; acpidump -t -d > name-system.asl(Substitute your login name for
name and manufacturer/model for
system. Example:
njl-FooCo6000.asl)Most of the developers watch the &a.current;
but please submit problems to &a.acpi.name; to be sure it is
seen. Please be patient, all of us have full-time jobs
elsewhere. If your bug is not immediately apparent, we will
probably ask you to submit a PR via
&man.send-pr.1;. When entering a PR, please
include the same information as requested above. This will help
us track the problem and resolve it. Do not send a
PR without emailing &a.acpi.name; first as we use
PRs as reminders of existing problems, not a
reporting mechanism. It is likely that your problem has been
reported by someone before.BackgroundACPIACPI is present in all modern computers
that conform to the ia32 (x86), ia64 (Itanium), and amd64 (AMD)
architectures. The full standard has many features including
CPU performance management, power planes
control, thermal zones, various battery systems, embedded
controllers, and bus enumeration. Most systems implement less
than the full standard. For instance, a desktop system usually
only implements the bus enumeration parts while a laptop might
have cooling and battery management support as well. Laptops
also have suspend and resume, with their own associated
complexity.An ACPI-compliant system has various
components. The BIOS and chipset vendors
provide various fixed tables (e.g., FADT)
in memory that specify things like the APIC
map (used for SMP), config registers, and
simple configuration values. Additionally, a table of bytecode
(the Differentiated System Description Table
DSDT) is provided that specifies a
tree-like name space of devices and methods.The ACPI driver must parse the fixed
tables, implement an interpreter for the bytecode, and modify
device drivers and the kernel to accept information from the
ACPI subsystem. For &os;, &intel; has
provided an interpreter (ACPI-CA) that is
shared with Linux and NetBSD. The path to the
ACPI-CA source code is
src/sys/contrib/dev/acpica.
The glue code that allows ACPI-CA to work on
&os; is in
src/sys/dev/acpica/Osd. Finally, drivers
that implement various ACPI devices are found
in
src/sys/dev/acpica.Common ProblemsACPIproblemsFor ACPI to work correctly, all the parts
have to work correctly. Here are some common problems, in order
of frequency of appearance, and some possible workarounds or
fixes.Mouse IssuesIn some cases, resuming from a suspend operation will
cause the mouse to fail. A known work around is to add
hint.psm.0.flags="0x3000" to the
/boot/loader.conf file. If this
does not work then please consider sending a bug report
as described above.Suspend/ResumeACPI has three suspend to
RAM (STR) states,
S1-S3, and one suspend
to disk state (STD), called
S4. S5 is
soft off and is the normal state your system
is in when plugged in but not powered up.
S4 can actually be implemented two separate
ways. S4BIOS is a
BIOS-assisted suspend to disk.
S4OS is implemented
entirely by the operating system.Start by checking sysctl hw.acpi
for the suspend-related items. Here
are the results for a Thinkpad:hw.acpi.supported_sleep_state: S3 S4 S5
hw.acpi.s4bios: 0This means that we can use acpiconf -s
to test S3,
S4OS, and
S5. If was one
(1), we would have
S4BIOS
support instead of S4
OS.When testing suspend/resume, start with
S1, if supported. This state is most
likely to work since it does not require much driver support.
No one has implemented S2 but if you have
it, it is similar to S1. The next thing
to try is S3. This is the deepest
STR state and requires a lot of driver
support to properly reinitialize your hardware. If you have
problems resuming, feel free to email the &a.acpi.name; list but
do not expect the problem to be resolved since there are a lot
of drivers/hardware that need more testing and work.To help isolate the problem, remove as many drivers from
your kernel as possible. If it works, you can narrow down
which driver is the problem by loading drivers until it fails
again. Typically binary drivers like
nvidia.ko, X11
display drivers, and USB will have the most
problems while Ethernet interfaces usually work fine. If you
can properly load/unload the drivers, you can automate this by
putting the appropriate commands in
/etc/rc.suspend and
/etc/rc.resume. There is a
commented-out example for unloading and loading a driver. Try
setting to zero (0) if
your display is messed up after resume. Try setting longer or
shorter values for to see
if that helps.Another thing to try is load a recent Linux distribution
with ACPI support and test their
suspend/resume support on the same hardware. If it works
on Linux, it is likely a &os; driver problem and narrowing down
which driver causes the problems will help us fix the problem.
Note that the ACPI maintainers do not
usually maintain other drivers (e.g sound,
ATA, etc.) so any work done on tracking
down a driver problem should probably eventually be posted
to the &a.current.name; list and mailed to the driver
maintainer. If you are feeling adventurous, go ahead and
start putting some debugging &man.printf.3;s in a problematic
driver to track down where in its resume function it
hangs.Finally, try disabling ACPI and
enabling APM instead. If suspend/resume
works with APM, you may be better off
sticking with APM, especially on older
hardware (pre-2000). It took vendors a while to get
ACPI support correct and older hardware is
more likely to have BIOS problems with
ACPI.System Hangs (temporary or permanent)Most system hangs are a result of lost interrupts or an
interrupt storm. Chipsets have a lot of problems based on how
the BIOS configures interrupts before boot,
correctness of the APIC
(MADT) table, and routing of the
System Control Interrupt
(SCI).interrupt stormsInterrupt storms can be distinguished from lost interrupts
by checking the output of vmstat -i
and looking at the line that has
acpi0. If the counter is increasing at more
than a couple per second, you have an interrupt storm. If the
system appears hung, try breaking to DDB
(CTRLALTESC on
console) and type show interrupts.APICdisablingYour best hope when dealing with interrupt problems is to
try disabling APIC support with
hint.apic.0.disabled="1" in
loader.conf.PanicsPanics are relatively rare for ACPI and
are the top priority to be fixed. The first step is to
isolate the steps to reproduce the panic (if possible)
and get a backtrace. Follow the advice for enabling
options DDB and setting up a serial console
(see )
or setting up a &man.dump.8; partition. You can get a
backtrace in DDB with
tr. If you have to handwrite the
backtrace, be sure to at least get the lowest five (5) and top
five (5) lines in the trace.Then, try to isolate the problem by booting with
ACPI disabled. If that works, you can
isolate the ACPI subsystem by using various
values of . See the
&man.acpi.4; manual page for some examples.System Powers Up After Suspend or ShutdownFirst, try setting
hw.acpi.disable_on_poweroff="0"
in &man.loader.conf.5;. This keeps ACPI
from disabling various events during the shutdown process.
Some systems need this value set to 1 (the
default) for the same reason. This usually fixes
the problem of a system powering up spontaneously after a
suspend or poweroff.Other ProblemsIf you have other problems with ACPI
(working with a docking station, devices not detected, etc.),
please email a description to the mailing list as well;
however, some of these issues may be related to unfinished
parts of the ACPI subsystem so they might
take a while to be implemented. Please be patient and
prepared to test patches we may send you.ASL, acpidump, and
IASLACPIASLThe most common problem is the BIOS
vendors providing incorrect (or outright buggy!) bytecode. This
is usually manifested by kernel console messages like
this:ACPI-1287: *** Error: Method execution failed [\\_SB_.PCI0.LPC0.FIGD._STA] \\
(Node 0xc3f6d160), AE_NOT_FOUNDOften, you can resolve these problems by updating your
BIOS to the latest revision. Most console
messages are harmless but if you have other problems like
battery status not working, they are a good place to start
looking for problems in the AML. The
bytecode, known as AML, is compiled from a
source language called ASL. The
AML is found in the table known as the
DSDT. To get a copy of your
ASL, use &man.acpidump.8;. You should use
both the (show contents of the fixed tables)
and (disassemble AML to
ASL) options. See the
Submitting Debugging
Information section for an example syntax.The simplest first check you can do is to recompile your
ASL to check for errors. Warnings can
usually be ignored but errors are bugs that will usually prevent
ACPI from working correctly. To recompile
your ASL, issue the following command:&prompt.root; iasl your.aslFixing Your ASLACPIASLIn the long run, our goal is for almost everyone to have
ACPI work without any user intervention. At
this point, however, we are still developing workarounds for
common mistakes made by the BIOS vendors.
The µsoft; interpreter (acpi.sys and
acpiec.sys) does not strictly check for
adherence to the standard, and thus many BIOS
vendors who only test ACPI under &windows;
never fix their ASL. We hope to continue to
identify and document exactly what non-standard behavior is
allowed by µsoft;'s interpreter and replicate it so &os; can
work without forcing users to fix the ASL.
As a workaround and to help us identify behavior, you can fix
the ASL manually. If this works for you,
please send a &man.diff.1; of the old and new
ASL so we can possibly work around the buggy
behavior in ACPI-CA and thus make your fix
unnecessary.ACPIerror messagesHere is a list of common error messages, their cause, and
how to fix them:_OS dependenciesSome AML assumes the world consists of
various &windows; versions. You can tell &os; to claim it is
any OS to see if this fixes problems you
may have. An easy way to override this is to set
hw.acpi.osname="Windows 2001"
in /boot/loader.conf or other similar
strings you find in the ASL.Missing Return statementsSome methods do not explicitly return a value as the
standard requires. While ACPI-CA
does not handle this, &os; has a workaround that allows it to
return the value implicitly. You can also add explicit
Return statements where required if you know what value should
be returned. To force iasl to compile the
ASL, use the
flag.Overriding the Default AMLAfter you customize your.asl, you
will want to compile it, run:&prompt.root; iasl your.aslYou can add the flag to force creation
of the AML, even if there are errors during
compilation. Remember that some errors (e.g., missing Return
statements) are automatically worked around by the
interpreter.DSDT.aml is the default output
filename for iasl. You can load this
instead of your BIOS's buggy copy (which
is still present in flash memory) by editing
/boot/loader.conf as
follows:acpi_dsdt_load="YES"
acpi_dsdt_name="/boot/DSDT.aml"Be sure to copy your DSDT.aml to the
/boot directory.Getting Debugging Output From
ACPIACPIproblemsACPIdebuggingThe ACPI driver has a very flexible
debugging facility. It allows you to specify a set of subsystems
as well as the level of verbosity. The subsystems you wish to
debug are specified as layers and are broken down
into ACPI-CA components (ACPI_ALL_COMPONENTS)
and ACPI hardware support (ACPI_ALL_DRIVERS).
The verbosity of debugging output is specified as the
level and ranges from ACPI_LV_ERROR (just report
errors) to ACPI_LV_VERBOSE (everything). The
level is a bitmask so multiple options can be set
at once, separated by spaces. In practice, you will want to use
a serial console to log the output if it is so long
it flushes the console message buffer. A full list of the
individual layers and levels is found in the &man.acpi.4; manual
page.Debugging output is not enabled by default. To enable it,
add options ACPI_DEBUG to your kernel configuration file
if ACPI is compiled into the kernel. You can
add ACPI_DEBUG=1 to your
/etc/make.conf to enable it globally. If
it is a module, you can recompile just your
acpi.ko module as follows:&prompt.root; cd /sys/modules/acpi/acpi
&& make clean &&
make ACPI_DEBUG=1Install acpi.ko in
/boot/kernel and add your
desired level and layer to loader.conf.
This example enables debug messages for all
ACPI-CA components and all
ACPI hardware drivers
(CPU, LID, etc.) It will
only output error messages, the least verbose level.debug.acpi.layer="ACPI_ALL_COMPONENTS ACPI_ALL_DRIVERS"
debug.acpi.level="ACPI_LV_ERROR"If the information you want is triggered by a specific event
(say, a suspend and then resume), you can leave out changes to
loader.conf and instead use
sysctl to specify the layer and level after
booting and preparing your system for the specific event. The
sysctls are named the same as the tunables
in loader.conf.ReferencesMore information about ACPI may be found
in the following locations:The &a.acpi;The ACPI Mailing List Archives
The old ACPI Mailing List Archives
The ACPI 2.0 Specification
&os; Manual pages: &man.acpi.4;,
&man.acpi.thermal.4;, &man.acpidump.8;, &man.iasl.8;,
&man.acpidb.8;
DSDT debugging resource.
(Uses Compaq as an example but generally useful.)
diff --git a/zh_TW.Big5/books/handbook/introduction/chapter.sgml b/zh_TW.Big5/books/handbook/introduction/chapter.sgml
index 060e0df5dd..e92bcf7ddf 100644
--- a/zh_TW.Big5/books/handbook/introduction/chapter.sgml
+++ b/zh_TW.Big5/books/handbook/introduction/chapter.sgml
@@ -1,795 +1,795 @@
JimMockRestructured, reorganized, and parts
rewritten by 簡介概述非常感謝您對 FreeBSD 感興趣!以下章節涵蓋 FreeBSD
計劃的各方面:比如它的歷史、目標、開發模式等等。讀完這章,您將了解︰FreeBSD 與其他 OS 之間的關係;FreeBSD 計劃的歷史源流;FreeBSD 計劃的目標;FreeBSD open-source 開發模式的基礎概念;
- 當然囉,還有 FreeBSD 這名字的緣故。
+ 當然囉,還有 FreeBSD 這名字的由來。Welcome to FreeBSD!4.4BSD-LiteFreeBSD 是一個從 4.4BSD-Lite 衍生出而能在以 Intel (x86 and &itanium;),
AMD64, Alpha, Sun &ultrasparc;
為基礎的電腦上執行的作業系統。同時,移植到其他平台的工作也在進行中。
對於本計劃歷史的介紹,請看 FreeBSD 歷史源流,
對於 FreeBSD 的最新版本介紹,請看 current release
。若打算對於 FreeBSD 計劃有所貢獻的話(像是程式碼硬體設備,資金),
請看 如何對 FreeBSD
有貢獻。FreeBSD 能做什麼?FreeBSD 提供給你許多先進功能。這些功能包括:先佔式多工(preemptive multitasking)動態優先權調整的『先佔式多工』能夠確保,即使在系統負擔很重的情況下,
程式執行平順並且應用程式與使用者公平地共享資源。支援多人共用『多人共用(multi-user)』代表著許多人可以同時使用一個 FreeBSD 系統來處理各自的事務。
系統的硬體周邊(如印表機及磁帶機)也可以讓所有的使用者適當地分享。
也可以針對各別使用者或一群使用者的系統資源,予以設限,
以保護系統不致被過度使用。TCP/IP 網路功能好用的『TCP/IP 網路功能』可支援許多業界標準,比如:
SCTP、DHCP、NFS、NIS、PPP、SLIP 的支援,也就是說 FreeBSD
可以容易地跟其他作業系統透過網路共同運作,或是當作企業的伺服器用途
,例如提供遠端檔案共享(NFS)及電子郵件(email)等服務,
或是讓您的企業連上網際網路(Internet)並提供 WWW、FTP、
路由(routing)、及防火牆(firewall、security) 等必備服務。記憶體保護『記憶體保護(Memory protection)』能確保程式(或是使用者)不會互相干擾,
即使任何程式有不正常的運作,都不會影響其他程式的執行。FreeBSD 是『32位元(32-bit)』的作業系統
(在 Alpha、&itanium;、 AMD64 及 &ultrasparc; 上則是『64位元(64-bit)』)
— 打從一開始便是這樣設計的。X Window SystemXFree86業界標準的『X Window 系統』(X11R6)可以在常見的便宜 VGA 顯示卡/螢幕,
提供了圖形化的使用者介面(GUI),並且包括了完整的原始程式碼。binary compatibilityLinuxbinary compatibilitySCObinary compatibilitySVR4binary compatibilityBSD/OSbinary compatibilityNetBSD能『直接執行』許多其他作業系統(比如: Linux、SCO、SVR4、BSDI 和 NetBSD)
的可執行檔。數以萬計的立即可以執行的應用程式,這些都可透過 FreeBSD
的『ports』及『packages』軟體管理機制來取得。
不再需要費心到網路上到處搜尋所需要的軟體。此外,網路上尚有可非常容易移植的數以萬計應用程式。
FreeBSD 的原始程式碼與許多常見的商業版 &unix; 系統都相容,
所以大部分的程式都只需要很少的修改(或根本不用修改)
,就可以編譯執行。virtual memory需要時才置換(demand paged) virtual memory 及
merged VM/buffer cache 的設計,
這點在系統中有用去大量記憶體的程式執行時,仍然有不錯的效率表現。Symmetric Multi-Processing (SMP)支援 CPU 的對稱多工處理(SMP):可以支援多 CPU
的電腦系統。compilersCcompilersC++compilersFORTRAN完全相容的 C、C++ 以及
Fortran 的環境和其他開發工具。
以及其他許多可供進階研發的程式語言也收集在 ports 和 packages。
source code整個系統都有『原始程式碼』,
這讓你對作業環境擁有最完全的掌握度。
既然能擁有完全開放的系統,何苦被特定封閉軟體所約束,任廠商擺佈呢?
廣泛且豐富的『線上文件』。當然囉,還不止如此!4.4BSD-LiteComputer Systems Research Group (CSRG)U.C. BerkeleyFreeBSD 系統乃是基於美國加州大學柏克萊分校的電腦系統研究群
(Computer Systems Research Group 也就是 CSRG) 所發行的
4.4BSD-Lite,以及基於 BSD 系統開發的優良傳統。
除了由 CSRG 所提供的高品質的成果,
為了提供可處理真正具負荷的工作,
FreeBSD 計劃也投入了數千小時以上的細部調整,
以能獲得最好的執行效率以及系統的穩定度。
正當許多商業上的巨人正努力地希望能提供效能及穩定時,
FreeBSD 已經具備這樣的特質 -- 就是現在!
FreeBSD 的運用範圍無限,其實完全限制在你的想像力上。
從軟體的開發到工廠自動化,或是人造衛星上面的天線的方位角度的遠端控制;
這些功能若可以用商用的 Unix 產品來達成,
那麼極有可能使用 FreeBSD 也能辦到!
FreeBSD 也受益於來自於全球各研究中心及大學所開發的數千個高品質的軟體
,這些通常只需要花費很少的費用或根本就是免費的。
當然也有商業軟體,而且出現的數目是與日俱增。由於每個人都可以取得 FreeBSD 的原始程式碼,
這個系統可以被調整而能執行任何原本完全無法想像的功能或計劃,
而對於從各廠商取得的作業系統通常沒有辦法這樣地被修改。
以下提供一些人們使用 FreeBSD 的例子:網路服務: FreeBSD
內建強勁的網路功能使它成為網路服務(如下例)的理想平台:FTP servers檔案伺服器(FTP servers)web servers全球資訊網伺服器(WWW servers)
(標準的或更安全的 SSL 連線)firewallIP masquerading防火牆以及 NAT (IP masquerading)
gateways。electronic mail電子郵件伺服器(Electronic Mail servers)USENET網路新聞伺服器(USENET News)
或是電子佈告欄系統(BBS)還有更多...有了 FreeBSD,您可以容易地先用便宜的 386 PC,
再逐步升級您的機器到四個 CPU 的 Xeon
並使用磁碟陣列(RAID)來滿足您企業運用上的需求。教育:
如果你是資訊或相關工程領域的學生,再也沒有比使用 FreeBSD
能學到更多作業系統、計算機結構、及網路的方法了。
另外如果你想利用電腦來處理一些其他的
工作,還有一些如 CAD、
數學運算以及圖形處理軟體等可以免費地取得使用。研究:有了完整的原始程式碼,FreeBSD
是研究作業系統及電腦科學的極佳環境。
具有免費且自由取得特性的 FreeBSD
也使得一個分置兩地的合作計劃,不必擔心版權及系統開放性的問題,
而能自在的交流。routerDNS Server網路:
你如果需要 router、Name Server (DNS) 或安全的防火牆(Firewall),
FreeBSD 可以輕易的將你沒有用到的 386 或 486 PC
變身成為絕佳的伺服器,甚至具有過濾封包(packet-filter) 的功能。
X Window SystemXFree86X Window SystemAccelerated-XX 視窗工作站: FreeBSD 是 X
終端機的良策,你可以使用免費的 X11 Server。
FreeBSD 不但可以充當遠端 X 程式終端機,
也可以執行本地的 X 程式而減輕大型工作站的負荷。
如果有一台中央伺服器的話,FreeBSD 甚至可以經由網路開機
(不需硬碟,也就是diskless)
,而變成更便宜且易於管理的工作站。GNU Compiler Collection軟體開發:
基本安裝的 FreeBSD 就包含了完整的程式開發工具,如 GNU C/C++
編譯器及除錯器。你可以經由燒錄 CDROM、DVD 或是從 FTP 站上抓回 FreeBSD --
包括立即可執行的系統以及系統的完整程式碼。
詳情請參閱 取得 FreeBSD。誰在用 FreeBSD?userslarge sites running FreeBSD許多 Internet 上的大型網站都是以 FreeBSD 作為它的作業系統,例如:Yahoo!Yahoo!ApacheApacheBlue Mountain ArtsBlue Mountain
ArtsPair NetworksPair
NetworksSony JapanSony
JapanNetcraftNetcraftWeathernewsWeathernewsSupervaluSupervaluTELEHOUSE AmericaTELEHOUSE
AmericaSophos Anti-VirusSophos
Anti-VirusJMA WiredJMA Wired以及許多其他的網站。關於 FreeBSD 計劃接下來講的是 FreeBSD 計劃的背景,包含歷史源流的簡介、計劃的目標,以及開發的模式。JordanHubbardContributed by FreeBSD 歷史源流的簡介386BSD PatchkitHubbard, JordanWilliams, NateGrimes, RodFreeBSD ProjecthistoryFreeBSD 計畫的想法是在 1993 年初所形成的,
那是源自於維護一組 『非官方 386BSD 的 patchkit(修正工具)』計劃的三個協調維護人
Nate Williams,Rod Grimes 和我(Jordan Hubbard)。386BSD我們最初的目標是做出一份 386BSD 綜合修正的 snapshot 版,以便修正當時一堆
patchkit 都不容易解決的問題。有些人可能還記得早期的計劃名稱叫做
386BSD 0.5 或 386BSD Interim 就是這個原因。Jolitz, Bill386BSD 是 Bill Jolitz 的作業系統,在當時就已有約一年的分裂討論。
當該修正工具 (patchkit) 日漸龐雜得令人不舒服,我們無異議地同意要作一些事了,
並決定提供一份臨時性的 淨化版(cleanup) 來幫助 Bill。
然而,由於 Bill Jolitz 忽然決定取消其對該計劃的認可,且沒有明確指出未來的打算,
所以該計劃便突然面臨斷炊危機。Greenman, DavidWalnut Creek CDROM不久我們便決定在即使沒有 Bill 的支持下,讓該計劃仍然繼續下去,
最後我們採用 David Greenman 丟銅板決定的名字,也就是『FreeBSD』。
在詢問了當時的一些使用者意見之後,就開始決定了最初的目標,
當該計劃開始實施一切就要成真時,一切就變得更清楚了。
我跟 Walnut Creek CDROM 討論發行 CDROM
這樣子不便上網的人就可以用比較簡單的方式取得 FreeBSD。
Walnut Creek CDROM 不只贊成以 CDROM 來發行 FreeBSD
的想法,同時提供了一台機器以及快速的網際網路的頻寬。
如果不是 Walnut Creek CDROM 幾乎是空前的信任這個剛開始還是完全默默無聞的計劃,
那麼很可能 FreeBSD 不會如此快速的成長到今日這樣的規模。4.3BSD-LiteNet/2U.C. Berkeley386BSDFree Software Foundation第一張以 CDROM (及網路)發行的 FreeBSD 1.0 是在 1993 年十二月。
該版本是基於由 U.C. Berkeley 以磁帶方式發行的
4.3BSD-Lite (Net/2)以及許多來自於 386BSD
和自由軟體基金會的軟體。對於第一次發行而言還算成功,
我們又接著於 1994 年 5 月發行了相當成功的 FreeBSD 1.1。NovellU.C. BerkeleyNet/2AT&T然而此後不久,另一個意外的風暴在 Novell 和 U.C. Berkeley 關於
Berkeley Net/2 磁帶之法律地位的訴訟確定之後形成。
U.C. Berkeley 接受大部份的 Net/2 的程式碼都是『侵佔來的』且是屬於 Novell 的財產
-- 事實上是當時不久前從 AT&T 取得的。
Berkeley 得到的是 Novell 對於 4.4BSD-Lite 的『祝福』,最後當 4.4BSD-Lite
終於發行之後,便不再是侵佔行為。
而所有現有 Net/2 使用者都被強烈建議更換新版本,這包括了 FreeBSD。
於是,我們被要求於 1994 年 6 月底前停止散佈基於 Net/2
的產品。在此前提之下,本計劃被允許在期限以前作最後一次發行,也就是
FreeBSD 1.1.5.1。FreeBSD 便開始了這宛如『重新發明輪子』的艱鉅工作 -- 從全新的且不完整的
4.4BSD-Lite 重新整合。
這個 Lite 版本是不完整的,因為
Berkeley 的 CSRG 已經刪除了大量在建立一個可以開機執行的系統所需要的程式碼
(基於若干法律上的要求),且該版本在 Intel 平台的移植是非常不完整的。
直到 1994 年 11 月本計劃才完成了這個轉移,
同時在該年 12 月底以 CDROM 以及網路的形式發行了 FreeBSD 2.0。
雖然該份版本在當時有點匆促粗糙,但仍是富有意義的成功。
隨之於 1995 年 6 月又發行了更容易安裝,更好的 FreeBSD 2.0.5。我們在 1996 年 8 月發行了 FreeBSD 2.1.5,在 ISP 和商業團體中非常流行。
隨後, 2.1-STABLE 分支的另一個版本應運而生,它就是在 1997 年 2 月發行 FreeBSD 2.1.7.1
,同時也是 2.1-STABLE 分支的最後版。之後此分支便進入維護狀態,
僅僅提供安全性的加強和其他嚴重錯誤修補的維護(RELENG_2_1_0)。1996 年 11 月 FreeBSD 2.2 從開發主軸分支 (-CURRENT)
出來成為 RELENG_2_2 分支。它的第一個完整版(2.2.1)於 1997 年 4 月發行。
2.2 分支的延續版本在 97 年夏秋之間發行的,其最後版是在 1998 年 11 月發行的 2.2.8 版。
第一個正式的 3.0 版本在 1998 年 10 月發行,亦即宣告 2.2 分支的落幕。1999/01/20 日再度分支,這產生了 4.0-CURRENT 以及 3.X-STABLE 兩個分支。
3.X-STABLE 方面,3.1 發行於 1999/02/15,3.2 發行於1999/05/15,3.3 發行於 1999/09/16,
3.4 發行於 1999/12/20,3.5 發行於 2000/06/24
,接下來幾天後發佈了一些的修補檔(對 Kerberos 安全性方面的修正),就升級至 3.5.1
,這是 3.X 分支最後一個發行版本。在 2000/03/13 又有了一個新的分支, 也就是 4.X-STABLE
。這個分支之後發佈了許多的發行版本︰ 4.0-RELEASE 在 2000 年 3 月發行,
而最後的 4.11-RELEASE 則在 2005 年 1 月發行。4-STABLE 分支的支援會持續到 2007/01/31
,但主要焦點在於安全方面的漏洞、臭蟲及其他嚴重問題的修補。期待已久的 5.0-RELEASE 在 2003/01/19 正式發行。這是將近開發三年的巔峰之作,同時
也開始加強多顆CPU(SMPng)的支援、kernel thread(KSE) 的支援、檔案系統採用 UFS2 以及支援 snapshot
等, 並支援 &ultrasparc; 和
ia64 平台、支援藍牙、32 bit 的 PCMCIA 等。之後於 2003 年 6 月發行了 5.1。
而 -CURRENT 這個發展主軸分支的最後 5.X 版本是在 2004 年 2 月正式發行的 5.2.1-RELEASE,在 5.X
系列進入 -STABLE (RELENG_5分支)之後,-CURRENT 就轉移為 6.X 系列。RELENG_5 分支於 2004 年 8 月正式開跑,之後是 5.3-RELEASE
,它是 5-STABLE 分支的第一個發行版本。&rel2.current;-RELEASE 的最新發表是在 &rel2.current.date; 發行的 &rel2.current;-RELEASE,照往例 RELENG_5 分支還將有後續的發行版。RELENG_6 分支於 2005 年 7 月開跑,而 6.X 分支的第一個 release(6.0-RELEASE) 是在 2005 年 11 月出的。
最新的 &rel.current;-RELEASE 是在 &rel.current.date; 發行。當然囉,RELENG_6 分支還將有後續的發行版。目前,長期的開發計畫繼續在 7.X-CURRENT (trunk) 分支中進行,而 7.X 的 CDROM
(當然,也可以用網路抓) snapshot 版本可以在 FreeBSD snapshot server
取得。JordanHubbardContributed by FreeBSD 計劃的目標FreeBSD ProjectgoalsFreeBSD 計劃的目標在於提供可作任意用途的軟體而不附帶任何限制條文。
我們之中許多人對程式碼 (以及計畫本身) 都有非常大的投入,
因此,當然不介意偶爾有一些資金上的補償,但我們並沒打算堅決地要求得到這類資助。
我們認為我們的首要『使命(mission)』是為任何人提供程式碼,
不管他們打算用這些程式碼做什麼, 因為這樣程式碼將能夠被更廣泛地使用,從而發揮其價值。
我認為這是自由軟體最基本的,同時也是我們所倡導的一個目標。GNU General Public License (GPL)GNU Lesser General Public License (LGPL)BSD Copyright我們程式碼樹中,有若干是以 GNU GPL 或者 LGPL
發佈的那些程式碼帶有少許的附加限制,還好只是強制性的要求開放程式碼而不是別的。
由於使用 GPL 的軟體在商業用途上會增加若干複雜性,因此,如果可以選擇的話,
我們會比較喜歡使用限制相對更寬鬆的 BSD 版權來發佈軟體。SatoshiAsamiContributed by FreeBSD 的開發模式FreeBSD Projectdevelopment modelFreeBSD 的開發是一個非常開放且具彈性的過程,就像從 貢獻者名單
所看到的,是由全世界成千上萬的貢獻者發展起來的。
FreeBSD 的開發基礎架構允許數以百計的開發者透過網際網路協同工作。
我們也經常關注著那些對我們的計畫感興趣的新開發者和新的創意,
那些有興趣更進一步參與計劃的人只需要在 &a.hackers; 連繫我們。
&a.announce; 對那些希望了解我們進度的人也是相當有用的。無論是單獨開發者或者封閉式的團隊合作,多瞭解 FreeBSD 計劃和它的開發過程會是不錯的︰The CVS repositoryCVSrepositoryConcurrent Versions SystemCVSFreeBSD 的中央 source tree 是以
CVS
(Concurrent Versions System) 來維護的,它是個自由軟體,可用來做為版本控制,一裝完 FreeBSD 內就有附了。
最主要的 CVS
repository 是位於美國加州 Santa Clara 的某台機器上,
然後再 mirror 到世界上其他的許多機器上。CVS tree 內有兩個主分支:-CURRENT 以及 -STABLE ,這些都可輕鬆複製到自己機器上。
詳情請參閱 更新你的 source tree 一節。The committers listcommitters所謂的 committers
指的是對 CVS tree 有 write 權限,
並依不同授權部分,而有不同權限可修改 FreeBSD source。
(committer 這詞源自 &man.cvs.1; 中的 commit
指令,該指令是用來把新的修改提交給 CVS repository。)
而提交修改給 committer 們檢查的最好方式,就是用 &man.send-pr.1; 指令。
若提交 PR 的流程、系統上有壅塞現象的話,也可以改用寄信方式,寄信到 &a.committers; 即可。The FreeBSD core teamcore team如果把 FreeBSD 看成是一家公司的話,FreeBSD core team
就相當於『董事會(board of directors)』。
core team 的主要職責在於確保此計劃有良好的架構,以朝著正確的方向發展。
此外,邀請熱血且負責的軟體開發者加入 committers 行列,以在若干成員離去時得以補充新血。
目前的 core team 是在 2006 年 7 月 committers 候選人中選出來的,每兩年會舉辦一次選舉有些 core team 成員還負責某些特定範圍,也就是說他們必須盡量確保一些子系統的穩定、效能。
關於 FreeBSD 開發者們以及各自責任範圍,請參閱 貢獻者名單。core team 大部分成員加入 FreeBSD 開發都是志工性質而已,並未從本計劃中獲得任何薪酬,
所以不該把 commitment 誤解為 guaranteed support
才對。 剛前面所講的『董事會』可能是不恰當的類推,或許我們應該說:
他們是一群自願放棄原本的優渥生活、個人其他領域成就,而選擇投入 FreeBSD 開發的熱血有為者才對!其他的貢獻者contributors最後一點,但這點絕非最不重要的,最大的開發者團隊就是持續為我們提供回饋以及錯誤修正的使用者自己。
與 FreeBSD 非核心開發者互動的主要方式,便是透過訂閱 &a.hackers; 來進行溝通,
這方面可參考,請參閱 以瞭解各式不同的 FreeBSD 郵遞論壇(mailing lists)。FreeBSD 貢獻者名單
相當長且不斷成長中,只要有貢獻就會被列入其中,要不要立即考慮貢獻 FreeBSD 一些回饋呢?然而,提供原始碼並非為這個計劃做貢獻的唯一方式;
還需要大家投入的完整工作列表、說明,請參閱 FreeBSD 官網。簡單的說,我們的開發模式就像是一組沒有拘束的同心圓。
這種集中開發模式是以 給使用者方便 為主,
同時讓他們能很容易地共同維護軟體,而不會把潛在的貢獻者排除在外!
我們的目標是提供含有大量一致性的 應用軟體(ports/packages)
,以便讓使用者輕鬆安裝、使用的作業系統 —— 而這開發模式相當符合此一目標。我們對於那些想要加入 FreeBSD 開發者的期待是:請保持如同前人一樣的投入,以確保繼續成功!最新的 FreeBSD 發行版本NetBSDOpenBSD386BSDFree Software FoundationU.C. BerkeleyComputer Systems Research Group (CSRG)FreeBSD 是免費使用且帶有完整原始程式碼的以 4.4BSD-Lite 為基礎的系統,可以在
Intel &i386;, &i486;, &pentium;,
&pentium; Pro,
&celeron;,
&pentium; II,
&pentium; III,
&pentium; 4 (或者相容型號),
&xeon;, DEC Alpha
和 Sun &ultrasparc; 為基礎的電腦上執行的作業系統。
它主要以加州大學巴爾克利分校 的 CSRG 研究小組的軟體為基礎,並加入了
NetBSD、OpenBSD、386BSD 以及自由軟體基金會的一些東西。自從 1994 年末,我們發佈了 FreeBSD 2.0 之後,系統的執行效率、
功能、穩定性都有了令人注目的提升。
最大的改變就是我們將記憶體與檔案系統的 cache 機制結合在一起。
這不只使得系統的表現變得更好, 並且使得 FreeBSD
系統最少的記憶體需求減少到 5 MB。
其它的改進包括完整的 NIS cilent and server 功能支援,
支援 transaction TCP、PPP 撥接連線、整合的 DHCP 支援、
SCSI 子系統的改進、ISDN 的支援,ATM、FDDI 以及乙太網路 (Ethernet、包括
100 Mbit 和 Gigabit) 的支援,提升了最新的 Adaptec
控制卡驅動程式的改善,以及數以千計的 bug 修正。除了最基本的系統軟體,FreeBSD 還提供了廣受歡迎的套件軟體管理機制:
Ports Collection。
到本書付印時,已有超過 &os.numports; 個 ports,這範疇涵蓋從 http(WWW)
伺服器到遊戲、程式語言、編輯器以及您能想到的幾乎所有的東西。
完整的 Ports Collection 需要約 &ports.size; 的硬碟空間,除了
port 基本架構檔案外,都只儲存與該 port 軟體的原始碼有『須要變更』的部份。
如此一來,我們可以更容易更新這些 ports,
也大量的減少如舊的 1.0 版 Ports Collection 對於硬碟空間的需求。
要安裝一個 port 的話,只需要進入該 port 的目錄,輸入 make install
,這樣子系統就會幫你裝好了。您要編譯的每個程式的完整原始程式,
都可從 FTP 或 CDROM 中獲得,所以您只需準備足夠的硬碟空間來編譯你要的 port 軟體。
幾乎每一個 port 都有已事先編譯好的 package以方便安裝,
如果不想從編譯 port 的人,只要用個簡單指令(pkg_add)就可以安裝。
有關 packages 和 ports 的細節,可以參閱 。FreeBSD 主機的 /usr/share/doc 目錄下找到許多有用的文件,
來幫助您安裝、使用 FreeBSD。也可以使用下面的網址,以瀏覽器來翻閱本機上安裝的手冊︰FreeBSD 使用手冊/usr/share/doc/handbook/index.htmlFreeBSD 常見問答集/usr/share/doc/faq/index.html此外,可在下列網址找到最新版 (也是更新最頻繁的版本):。
diff --git a/zh_TW.Big5/books/handbook/mail/chapter.sgml b/zh_TW.Big5/books/handbook/mail/chapter.sgml
index b51cda2784..2937d5bacd 100644
--- a/zh_TW.Big5/books/handbook/mail/chapter.sgml
+++ b/zh_TW.Big5/books/handbook/mail/chapter.sgml
@@ -1,2324 +1,2324 @@
BillLloydOriginal work by JimMockRewritten by
- Electronic Mail
+ 電子郵件
- Synopsis
+ 概述emailElectronic Mail, better known as email, is one of the
most widely used forms of communication today. This chapter provides
a basic introduction to running a mail server on &os;, as well as an
introduction to sending and receiving email using &os;; however,
it is not a complete reference and in fact many important
considerations are omitted. For more complete coverage of the
subject, the reader is referred to the many excellent books listed
in .After reading this chapter, you will know:What software components are involved in sending and receiving
electronic mail.Where basic sendmail configuration
files are located in FreeBSD.The difference between remote and
local mailboxes.How to block spammers from illegally using your mail server as a
relay.How to install and configure an alternate Mail Transfer Agent on
your system, replacing sendmail.How to troubleshoot common mail server problems.How to use SMTP with UUCP.How to set up the system to send mail only.How to use mail with a dialup connection.How to configure SMTP Authentication for added security.How to install and use a Mail User Agent, such as
mutt to send and receive email.How to download your mail from a remote POP
or IMAP server.How to automatically apply filters and rules to incoming
email.Before reading this chapter, you should:Properly set up your network connection
().Properly set up the DNS information for your mail host
().Know how to install additional third-party software
().Using Electronic MailPOPIMAPDNSThere are five major parts involved in an email exchange. They
are: the user program, the server daemon, DNS, a
remote or local mailbox, and of course, the
mailhost itself.The User ProgramThis includes command line programs such as
mutt,
pine, elm,
and mail, and GUI programs such as
balsa,
xfmail to name a few, and something
more sophisticated like a WWW browser. These
programs simply pass off the email transactions to the local
mailhost, either
by calling one of the server
daemons available, or delivering it over TCP.Mailhost Server Daemonmail server daemonssendmailmail server daemonspostfixmail server daemonsqmailmail server daemonsexim&os; ships with sendmail by
default, but also support numerous other mail server daemons,
just some of which include:exim;postfix;qmail.The server daemon usually has two functions—it is responsible
for receiving incoming mail as well as delivering outgoing mail. It is
not responsible for the collection of mail using protocols
such as POP or IMAP to
read your email, nor does it allow connecting to local
mbox or Maildir mailboxes. You may require
an additional daemon for
that.Older versions of sendmail
have some serious security issues which may result in an
attacker gaining local and/or remote access to your machine.
Make sure that you are running a current version to avoid
these problems. Optionally, install an alternative
MTA from the &os;
Ports Collection.Email and DNSThe Domain Name System (DNS) and its daemon
named play a large role in the delivery of
email. In order to deliver mail from your site to another, the
server daemon will look up the remote site in the DNS to determine the
host that will receive mail for the destination. This process
also occurs when mail is sent from a remote host to your mail
server.MX recordDNS is responsible for mapping
hostnames to IP addresses, as well as for storing information
specific to mail delivery, known as MX records. The MX (Mail
eXchanger) record specifies which host, or hosts, will receive
mail for a particular domain. If you do not have an MX record
for your hostname or domain, the mail will be delivered
directly to your host provided you have an A record pointing
your hostname to your IP address.You may view the MX records for any domain by using the
&man.host.1; command, as seen in the example below:&prompt.user; host -t mx FreeBSD.org
FreeBSD.org mail is handled (pri=10) by mx1.FreeBSD.orgReceiving MailemailreceivingReceiving mail for your domain is done by the mail host. It
will collect all mail sent to your domain and store it
either in mbox (the default method for storing mail) or Maildir format, depending
on your configuration.
Once mail has been stored, it may either be read locally using
applications such as &man.mail.1; or
mutt, or remotely accessed and
collected using protocols such as
POP or IMAP.
This means that should you only
wish to read mail locally, you are not required to install a
POP or IMAP server.Accessing remote mailboxes using POP and IMAPPOPIMAPIn order to access mailboxes remotely, you are required to
have access to a POP or IMAP
server. These protocols allow users to connect to their mailboxes from
remote locations with ease. Though both
POP and IMAP allow users
to remotely access mailboxes, IMAP offers
many advantages, some of which are:IMAP can store messages on a remote
server as well as fetch them.IMAP supports concurrent updates.IMAP can be extremely useful over
low-speed links as it allows users to fetch the structure
of messages without downloading them; it can also
perform tasks such as searching on the server in
order to minimize data transfer between clients and
servers.In order to install a POP or
IMAP server, the following steps should be
performed:Choose an IMAP or
POP server that best suits your needs.
The following POP and
IMAP servers are well known and serve
as some good examples:qpopper;teapop;imap-uw;courier-imap;Install the POP or
IMAP daemon of your choosing from the
ports
collection.Where required, modify /etc/inetd.conf
to load the POP or
IMAP server.It should be noted that both POP and
IMAP transmit information, including
username and password credentials in clear-text. This means
that if you wish to secure the transmission of information
across these protocols, you should consider tunneling
sessions over &man.ssh.1;. Tunneling sessions is
described in .Accessing local mailboxesMailboxes may be accessed locally by directly utilizing
MUAs on the server on which the mailbox
resides. This can be done using applications such as
mutt or &man.mail.1;.
The Mail Hostmail hostThe mail host is the name given to a server that is
responsible for delivering and receiving mail for your host, and
possibly your network.ChristopherShumwayContributed by sendmail Configurationsendmail&man.sendmail.8; is the default Mail Transfer Agent (MTA) in
FreeBSD. sendmail's job is to accept
mail from Mail User Agents (MUA) and deliver it
to the appropriate mailer as defined by its configuration file.
sendmail can also accept network
connections and deliver mail to local mailboxes or deliver it to
another program.sendmail uses the following
configuration files:/etc/mail/access/etc/mail/aliases/etc/mail/local-host-names/etc/mail/mailer.conf/etc/mail/mailertable/etc/mail/sendmail.cf/etc/mail/virtusertableFilenameFunction/etc/mail/accesssendmail access database
file/etc/mail/aliasesMailbox aliases/etc/mail/local-host-namesLists of hosts sendmail
accepts mail for/etc/mail/mailer.confMailer program configuration/etc/mail/mailertableMailer delivery table/etc/mail/sendmail.cfsendmail master
configuration file/etc/mail/virtusertableVirtual users and domain tables/etc/mail/accessThe access database defines what host(s) or IP addresses
have access to the local mail server and what kind of access
they have. Hosts can be listed as ,
, or simply passed
to sendmail's error handling routine with a given mailer error.
Hosts that are listed as , which is the
default, are allowed to send mail to this host as long as the
mail's final destination is the local machine. Hosts that are
listed as are rejected for all mail
connections. Hosts that have the option
for their hostname are allowed to send mail for any destination
through this mail server.Configuring the sendmail
Access Databasecyberspammer.com 550 We do not accept mail from spammers
FREE.STEALTH.MAILER@ 550 We do not accept mail from spammers
another.source.of.spam REJECT
okay.cyberspammer.com OK
128.32 RELAYIn this example we have five entries. Mail senders that
match the left hand side of the table are affected by the action
on the right side of the table. The first two examples give an
error code to sendmail's error
handling routine. The message is printed to the remote host when
a mail matches the left hand side of the table. The next entry
rejects mail from a specific host on the Internet,
another.source.of.spam. The next entry accepts
mail connections from a host
okay.cyberspammer.com, which is more exact than
the cyberspammer.com line above. More specific
matches override less exact matches. The last entry allows
relaying of electronic mail from hosts with an IP address that
begins with 128.32. These hosts would be able
to send mail through this mail server that are destined for other
mail servers.When this file is updated, you need to run
make in /etc/mail/ to
update the database./etc/mail/aliasesThe aliases database contains a list of virtual mailboxes
that are expanded to other user(s), files, programs or other
aliases. Here are a few examples that can be used in
/etc/mail/aliases:Mail Aliasesroot: localuser
ftp-bugs: joe,eric,paul
bit.bucket: /dev/null
procmail: "|/usr/local/bin/procmail"The file format is simple; the mailbox name on the left
side of the colon is expanded to the target(s) on the right.
The
first example simply expands the mailbox root
to the mailbox localuser, which is then
looked up again in the aliases database. If no match is found,
then the message is delivered to the local user
localuser. The next example shows a mail
list. Mail to the mailbox ftp-bugs is
expanded to the three local mailboxes joe,
eric, and paul. Note
that a remote mailbox could be specified as user@example.com. The
next example shows writing mail to a file, in this case
/dev/null. The last example shows sending
mail to a program, in this case the mail message is written to the
standard input of /usr/local/bin/procmail
through a &unix; pipe.When this file is updated, you need to run
make in /etc/mail/ to
update the database./etc/mail/local-host-namesThis is a list of hostnames &man.sendmail.8; is to accept as
the local host name. Place any domains or hosts that
sendmail is to be receiving mail for.
For example, if this mail server was to accept mail for the
domain example.com and the host
mail.example.com, its
local-host-names might look something like
this:example.com
mail.example.comWhen this file is updated, &man.sendmail.8; needs to be
restarted to read the changes./etc/mail/sendmail.cfsendmail's master configuration
file, sendmail.cf controls the overall
behavior of sendmail, including everything
from rewriting e-mail addresses to printing rejection messages to
remote mail servers. Naturally, with such a diverse role, this
configuration file is quite complex and its details are a bit
out of the scope of this section. Fortunately, this file rarely
needs to be changed for standard mail servers.The master sendmail configuration
file can be built from &man.m4.1; macros that define the features
and behavior of sendmail. Please see
/usr/src/contrib/sendmail/cf/README for
some of the details.When changes to this file are made,
sendmail needs to be restarted for
the changes to take effect./etc/mail/virtusertableThe virtusertable maps mail addresses for
virtual domains and
mailboxes to real mailboxes. These mailboxes can be local,
remote, aliases defined in
/etc/mail/aliases or files.Example Virtual Domain Mail Maproot@example.com root
postmaster@example.com postmaster@noc.example.net
@example.com joeIn the above example, we have a mapping for a domain
example.com. This file is processed in a
first match order down the file. The first item maps
root@example.com to the local mailbox root. The next entry maps
postmaster@example.com to the mailbox postmaster on the host
noc.example.net. Finally, if nothing from example.com has
matched so far, it will match the last mapping, which matches
every other mail message addressed to someone at
example.com.
This will be mapped to the local mailbox joe.AndrewBoothmanWritten by GregoryNeil ShapiroInformation taken from e-mails written by Changing Your Mail Transfer Agentemailchange mtaAs already mentioned, FreeBSD comes with
sendmail already installed as your
MTA (Mail Transfer Agent). Therefore by default it is
in charge of your outgoing and incoming mail.However, for a variety of reasons, some system
administrators want to change their system's MTA. These
reasons range from simply wanting to try out another MTA to
needing a specific feature or package which relies on another
mailer. Fortunately, whatever the reason, FreeBSD makes it
easy to make the change.Install a New MTAYou have a wide choice of MTAs available. A good
starting point is the
FreeBSD Ports Collection where
you will be able to find many. Of course you are free to use
any MTA you want from any location, as long as you can make
it run under FreeBSD.Start by installing your new MTA. Once it is installed
it gives you a chance to decide if it really fulfills your
needs, and also gives you the opportunity to configure your
new software before getting it to take over from
sendmail. When doing this, you
should be sure that installing the new software will not attempt
to overwrite system binaries such as
/usr/bin/sendmail. Otherwise, your new
mail software has essentially been put into service before
you have configured it.Please refer to your chosen MTA's documentation for
information on how to configure the software you have
chosen.Disable sendmailThe procedure used to start
sendmail changed significantly
between 4.5-RELEASE, 4.6-RELEASE, and later releases.
Therefore, the procedure used to disable it is subtly
different.If you disable sendmail's
outgoing mail service, it is important that you replace it
with an alternative mail delivery system. If
you choose not to, system functions such as &man.periodic.8;
will be unable to deliver their results by e-mail as they
would normally expect to. Many parts of your system may
expect to have a functional
sendmail-compatible system. If
applications continue to use
sendmail's binaries to try to send
e-mail after you have disabled them, mail could go into an
inactive sendmail queue, and
never be delivered.FreeBSD 4.5-STABLE before 2002/4/4 and Earlier
(Including 4.5-RELEASE and Earlier)Enter:sendmail_enable="NO"into /etc/rc.conf. This will disable
sendmail's incoming mail service,
but if /etc/mail/mailer.conf (see below)
is not changed, sendmail will
still be used to send e-mail.FreeBSD 4.5-STABLE after 2002/4/4
(Including 4.6-RELEASE and Later)In order to completely disable
sendmail, including the outgoing
mail service, you must usesendmail_enable="NONE"in /etc/rc.conf.If you only want to disable
sendmail's incoming mail service,
you should setsendmail_enable="NO"in /etc/rc.conf. However, if
incoming mail is disabled, local delivery will still
function. More information on
sendmail's startup options is
available from the &man.rc.sendmail.8; manual page.FreeBSD 5.0-STABLE and LaterIn order to completely disable
sendmail, including the outgoing
mail service, you must usesendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"in /etc/rc.conf.If you only want to disable
sendmail's incoming mail service,
you should setsendmail_enable="NO"in /etc/rc.conf. More information on
sendmail's startup options is
available from the &man.rc.sendmail.8; manual page.Running Your New MTA on BootYou may have a choice of two methods for running your
new MTA on boot, again depending on what version of FreeBSD
you are running.FreeBSD 4.5-STABLE before 2002/4/11
(Including 4.5-RELEASE and Earlier)Add a script to
/usr/local/etc/rc.d/ that
ends in .sh and is executable by
root. The script should accept start and
stop parameters. At startup time the
system scripts will execute the command/usr/local/etc/rc.d/supermailer.sh startwhich you can also use to manually start the server. At
shutdown time, the system scripts will use the
stop option, running the command/usr/local/etc/rc.d/supermailer.sh stopwhich you can also use to manually stop the server
while the system is running.FreeBSD 4.5-STABLE after 2002/4/11
(Including 4.6-RELEASE and Later)With later versions of FreeBSD, you can use the
above method or you can setmta_start_script="filename"in /etc/rc.conf, where
filename is the name of some
script that you want executed at boot to start your
MTA.Replacing sendmail as
the System's Default MailerThe program sendmail is so ubiquitous
as standard software on &unix; systems that some software
just assumes it is already installed and configured.
For this reason, many alternative MTA's provide their own compatible
implementations of the sendmail
command-line interface; this facilitates using them as
drop-in replacements for sendmail.Therefore, if you are using an alternative mailer,
you will need to make sure that software trying to execute
standard sendmail binaries such as
/usr/bin/sendmail actually executes
your chosen mailer instead. Fortunately, FreeBSD provides
a system called &man.mailwrapper.8; that does this job for
you.When sendmail is operating as installed, you will
find something like the following
in /etc/mail/mailer.conf:sendmail /usr/libexec/sendmail/sendmail
send-mail /usr/libexec/sendmail/sendmail
mailq /usr/libexec/sendmail/sendmail
newaliases /usr/libexec/sendmail/sendmail
hoststat /usr/libexec/sendmail/sendmail
purgestat /usr/libexec/sendmail/sendmailThis means that when any of these common commands
(such as sendmail itself) are run,
the system actually invokes a copy of mailwrapper named sendmail, which
checks mailer.conf and
executes /usr/libexec/sendmail/sendmail
instead. This system makes it easy to change what binaries
are actually executed when these default sendmail functions
are invoked.Therefore if you wanted
/usr/local/supermailer/bin/sendmail-compat
to be run instead of sendmail, you could change
/etc/mail/mailer.conf to read:sendmail /usr/local/supermailer/bin/sendmail-compat
send-mail /usr/local/supermailer/bin/sendmail-compat
mailq /usr/local/supermailer/bin/mailq-compat
newaliases /usr/local/supermailer/bin/newaliases-compat
hoststat /usr/local/supermailer/bin/hoststat-compat
purgestat /usr/local/supermailer/bin/purgestat-compatFinishingOnce you have everything configured the way you want it, you should
either kill the sendmail processes that
you no longer need and start the processes belonging to your new
software, or simply reboot. Rebooting will also
give you the opportunity to ensure that you have correctly
configured your system to start your new MTA automatically on boot.TroubleshootingemailtroubleshootingWhy do I have to use the FQDN for hosts on my site?You will probably find that the host is actually in a
different domain; for example, if you are in
foo.bar.edu and you wish to reach
a host called mumble in the bar.edu domain, you will have to
refer to it by the fully-qualified domain name, mumble.bar.edu, instead of just
mumble.BINDTraditionally, this was allowed by BSD BIND resolvers.
However the current version of BIND
that ships with FreeBSD no longer provides default abbreviations
for non-fully qualified domain names other than the domain you
are in. So an unqualified host mumble must
either be found as mumble.foo.bar.edu, or it will be searched
for in the root domain.This is different from the previous behavior, where the
search continued across mumble.bar.edu, and mumble.edu. Have a look at RFC 1535
for why this was considered bad practice, or even a security
hole.As a good workaround, you can place the line:
search foo.bar.edu bar.edu
instead of the previous:
domain foo.bar.edu
into your /etc/resolv.conf. However, make
sure that the search order does not go beyond the
boundary between local and public administration,
as RFC 1535 calls it.MX recordsendmail says mail
loops back to myselfThis is answered in the
sendmail FAQ as follows:I'm getting these error messages:
553 MX list for domain.net points back to relay.domain.net
554 <user@domain.net>... Local configuration error
How can I solve this problem?
You have asked mail to the domain (e.g., domain.net) to be
forwarded to a specific host (in this case, relay.domain.net)
by using an MX record, but the relay machine does not recognize
itself as domain.net. Add domain.net to /etc/mail/local-host-names
[known as /etc/sendmail.cw prior to version 8.10]
(if you are using FEATURE(use_cw_file)) or add Cw domain.net
to /etc/mail/sendmail.cf.The sendmail FAQ can be found at
and is
recommended reading if you want to do any
tweaking of your mail setup.PPPHow can I run a mail server on a dial-up PPP host?You want to connect a FreeBSD box on a LAN to the
Internet. The FreeBSD box will be a mail gateway for the LAN.
The PPP connection is non-dedicated.UUCPMX recordThere are at least two ways to do this. One way is to use
UUCP.Another way is to get a full-time Internet server to provide secondary MX
services for your domain. For example, if your company's domain is
example.com and your Internet service provider has
set example.net up to provide secondary MX services
to your domain:example.com. MX 10 example.com.
MX 20 example.net.Only one host should be specified as the final recipient
(add Cw example.com in
/etc/mail/sendmail.cf on example.com).When the sending sendmail is trying to
deliver the mail it will try to connect to you (example.com) over the modem
link. It will most likely time out because you are not online.
The program sendmail will automatically deliver it to the
secondary MX site, i.e. your Internet provider (example.net). The secondary MX
site will then periodically try to connect to
your host and deliver the mail to the primary MX host (example.com).You might want to use something like this as a login
script:#!/bin/sh
# Put me in /usr/local/bin/pppmyisp
( sleep 60 ; /usr/sbin/sendmail -q ) &
/usr/sbin/ppp -direct pppmyispIf you are going to create a separate login script for a
user you could use sendmail -qRexample.com
instead in the script above. This will force all mail in your
queue for example.com to be processed immediately.A further refinement of the situation is as follows:Message stolen from the &a.isp;.> we provide the secondary MX for a customer. The customer connects to
> our services several times a day automatically to get the mails to
> his primary MX (We do not call his site when a mail for his domains
> arrived). Our sendmail sends the mailqueue every 30 minutes. At the
> moment he has to stay 30 minutes online to be sure that all mail is
> gone to the primary MX.
>
> Is there a command that would initiate sendmail to send all the mails
> now? The user has not root-privileges on our machine of course.
In the privacy flags section of sendmail.cf, there is a
definition Opgoaway,restrictqrun
Remove restrictqrun to allow non-root users to start the queue processing.
You might also like to rearrange the MXs. We are the 1st MX for our
customers like this, and we have defined:
# If we are the best MX for a host, try directly instead of generating
# local config error.
OwTrue
That way a remote site will deliver straight to you, without trying
the customer connection. You then send to your customer. Only works for
hosts, so you need to get your customer to name their mail
machine customer.com as well as
hostname.customer.com in the DNS. Just put an A record in
the DNS for customer.com.Why do I keep getting Relaying
Denied errors when sending mail from other
hosts?In default FreeBSD installations,
sendmail is configured to only
send mail from the host it is running on. For example, if
a POP server is available, then users
will be able to check mail from school, work, or other
remote locations but they still will not be able to send
outgoing emails from outside locations. Typically, a few
moments after the attempt, an email will be sent from
MAILER-DAEMON with a
5.7 Relaying Denied error
message.There are several ways to get around this. The most
straightforward solution is to put your ISP's address in
a relay-domains file at
/etc/mail/relay-domains. A quick way
to do this would be:&prompt.root; echo "your.isp.example.com" > /etc/mail/relay-domainsAfter creating or editing this file you must restart
sendmail. This works great if
you are a server administrator and do not wish to send mail
locally, or would like to use a point and click
client/system on another machine or even another ISP. It
is also very useful if you only have one or two email
accounts set up. If there is a large number of addresses
to add, you can simply open this file in your favorite
text editor and then add the domains, one per line:your.isp.example.com
other.isp.example.net
users-isp.example.org
www.example.orgNow any mail sent through your system, by any host in
this list (provided the user has an account on your
system), will succeed. This is a very nice way to allow
users to send mail from your system remotely without
allowing people to send SPAM through your system.Advanced TopicsThe following section covers more involved topics such as mail
configuration and setting up mail for your entire domain.Basic ConfigurationemailconfigurationOut of the box, you should be able to send email to external
hosts as long as you have set up
/etc/resolv.conf or are running your own
name server. If you would like to have mail for your host
delivered to the MTA (e.g., sendmail) on your own FreeBSD host, there are two methods:Run your own name server and have your own domain. For
example, FreeBSD.orgGet mail delivered directly to your host. This is done by
delivering mail directly to the current DNS name for your
machine. For example, example.FreeBSD.org.SMTPRegardless of which of the above you choose, in order to have
mail delivered directly to your host, it must have a permanent
static IP address (not a dynamic address, as with most PPP dial-up configurations). If you are behind a
firewall, it must pass SMTP traffic on to you. If you want to
receive mail directly at your host, you need to be sure of either of two
things:MX recordMake sure that the (lowest-numbered) MX record in your DNS points to your
host's IP address.Make sure there is no MX entry in your DNS for your
host.Either of the above will allow you to receive mail directly at
your host.Try this:&prompt.root; hostname
example.FreeBSD.org
&prompt.root; host example.FreeBSD.org
example.FreeBSD.org has address 204.216.27.XXIf that is what you see, mail directly to
yourlogin@example.FreeBSD.org should work without
problems (assuming sendmail is
running correctly on example.FreeBSD.org).If instead you see something like this:&prompt.root; host example.FreeBSD.org
example.FreeBSD.org has address 204.216.27.XX
example.FreeBSD.org mail is handled (pri=10) by hub.FreeBSD.orgAll mail sent to your host (example.FreeBSD.org) will end up being
collected on hub under the same username instead
of being sent directly to your host.The above information is handled by your DNS server. The DNS
record that carries mail routing information is the
Mail eXchange entry. If
no MX record exists, mail will be delivered directly to the host by
way of its IP address.The MX entry for freefall.FreeBSD.org at one time looked like
this:freefall MX 30 mail.crl.net
freefall MX 40 agora.rdrop.com
freefall MX 10 freefall.FreeBSD.org
freefall MX 20 who.cdrom.comAs you can see, freefall had many MX entries.
The lowest MX number is the host that receives mail directly if
available; if it is not accessible for some reason, the others
(sometimes called backup MXes) accept messages
temporarily, and pass it along when a lower-numbered host becomes
available, eventually to the lowest-numbered host.Alternate MX sites should have separate Internet connections
from your own in order to be most useful. Your ISP or another
friendly site should have no problem providing this service for
you.Mail for Your DomainIn order to set up a mailhost (a.k.a. mail
server) you need to have any mail sent to various workstations
directed to it. Basically, you want to claim any
mail for any hostname in your domain (in this case *.FreeBSD.org) and divert it to your mail
server so your users can receive their mail on
the master mail server.DNSTo make life easiest, a user account with the same
username should exist on both machines. Use
&man.adduser.8; to do this.The mailhost you will be using must be the designated mail
exchanger for each workstation on the network. This is done in
your DNS configuration like so:example.FreeBSD.org A 204.216.27.XX ; Workstation
MX 10 hub.FreeBSD.org ; MailhostThis will redirect mail for the workstation to the mailhost no
matter where the A record points. The mail is sent to the MX
host.You cannot do this yourself unless you are running a DNS
server. If you are not, or cannot run your own DNS server, talk
to your ISP or whoever provides your DNS.If you are doing virtual email hosting, the following
information will come in handy. For this example, we
will assume you have a customer with his own domain, in this
case customer1.org, and you want
all the mail for customer1.org
sent to your mailhost, mail.myhost.com. The entry in your DNS
should look like this:customer1.org MX 10 mail.myhost.comYou do not need an A record for customer1.org if you only
want to handle email for that domain.Be aware that pinging customer1.org will not work unless
an A record exists for it.The last thing that you must do is tell
sendmail on your mailhost what domains
and/or hostnames it should be accepting mail for. There are a few
different ways this can be done. Either of the following will
work:Add the hosts to your
/etc/mail/local-host-names file if you are using the
FEATURE(use_cw_file). If you are using
a version of sendmail earlier than 8.10, the file is
/etc/sendmail.cw.Add a Cwyour.host.com line to your
/etc/sendmail.cf or
/etc/mail/sendmail.cf if you are using
sendmail 8.10 or higher.SMTP with UUCPThe sendmail configuration that ships with FreeBSD is
designed for sites that connect directly to the Internet. Sites
that wish to exchange their mail via UUCP must install another
sendmail configuration file.Tweaking /etc/mail/sendmail.cf manually
is an advanced topic. sendmail version 8 generates config files
via &man.m4.1; preprocessing, where the actual configuration
occurs on a higher abstraction level. The &man.m4.1;
configuration files can be found under
/usr/src/usr.sbin/sendmail/cf.If you did not install your system with full sources, the
sendmail configuration set has been broken out into a separate source
distribution tarball. Assuming you have your FreeBSD source code
CDROM mounted, do:&prompt.root; cd /cdrom/src
&prompt.root; cat scontrib.?? | tar xzf - -C /usr/src/contrib/sendmailThis extracts to only a few hundred kilobytes. The file
README in the cf
directory can serve as a basic introduction to &man.m4.1;
configuration.The best way to support UUCP delivery is to use the
mailertable feature. This creates a database
that sendmail can use to make routing decisions.First, you have to create your .mc
file. The directory
/usr/src/usr.sbin/sendmail/cf/cf contains a
few examples. Assuming you have named your file
foo.mc, all you need to do in order to
convert it into a valid sendmail.cf
is:&prompt.root; cd /usr/src/usr.sbin/sendmail/cf/cf
&prompt.root; make foo.cf
&prompt.root; cp foo.cf /etc/mail/sendmail.cfA typical .mc file might look
like:VERSIONID(`Your version number') OSTYPE(bsd4.4)
FEATURE(accept_unresolvable_domains)
FEATURE(nocanonify)
FEATURE(mailertable, `hash -o /etc/mail/mailertable')
define(`UUCP_RELAY', your.uucp.relay)
define(`UUCP_MAX_SIZE', 200000)
define(`confDONT_PROBE_INTERFACES')
MAILER(local)
MAILER(smtp)
MAILER(uucp)
Cw your.alias.host.name
Cw youruucpnodename.UUCPThe lines containing
accept_unresolvable_domains,
nocanonify, and
confDONT_PROBE_INTERFACES features will
prevent any usage of the DNS during mail delivery. The
UUCP_RELAY clause is needed to support UUCP
delivery. Simply put an Internet hostname there that is able to
handle .UUCP pseudo-domain addresses; most likely, you will
enter the mail relay of your ISP there.Once you have this, you need an
/etc/mail/mailertable file. If you have
only one link to the outside that is used for all your mails,
the following file will suffice:#
# makemap hash /etc/mail/mailertable.db < /etc/mail/mailertable
. uucp-dom:your.uucp.relayA more complex example might look like this:#
# makemap hash /etc/mail/mailertable.db < /etc/mail/mailertable
#
horus.interface-business.de uucp-dom:horus
.interface-business.de uucp-dom:if-bus
interface-business.de uucp-dom:if-bus
.heep.sax.de smtp8:%1
horus.UUCP uucp-dom:horus
if-bus.UUCP uucp-dom:if-bus
. uucp-dom:The first three lines handle special cases where
domain-addressed mail should not be sent out to the default
route, but instead to some UUCP neighbor in order to
shortcut the delivery path. The next line handles
mail to the local Ethernet domain that can be delivered using
SMTP. Finally, the UUCP neighbors are mentioned in the .UUCP
pseudo-domain notation, to allow for a
uucp-neighbor
!recipient
override of the default rules. The last line is always a single
dot, matching everything else, with UUCP delivery to a UUCP
neighbor that serves as your universal mail gateway to the
world. All of the node names behind the
uucp-dom: keyword must be valid UUCP
neighbors, as you can verify using the command
uuname.As a reminder that this file needs to be converted into a
DBM database file before use. The command line to accomplish
this is best placed as a comment at the top of the mailertable file.
You always have to execute this command each time you change
your mailertable file.Final hint: if you are uncertain whether some particular
mail routing would work, remember the
option to sendmail. It starts sendmail in address test
mode; simply enter 3,0, followed
by the address you wish to test for the mail routing. The last
line tells you the used internal mail agent, the destination
host this agent will be called with, and the (possibly
translated) address. Leave this mode by typing CtrlD.&prompt.user; sendmail -bt
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
>3,0 foo@example.com
canonify input: foo @ example . com
...
parse returns: $# uucp-dom $@ your.uucp.relay $: foo < @ example . com . >
>^DBillMoranContributed by Setting Up to Send OnlyThere are many instances where you may only want to send
mail through a relay. Some examples are:Your computer is a desktop machine, but you want
to use programs such as &man.send-pr.1;. To do so, you should use
your ISP's mail relay.The computer is a server that does not handle mail
locally, but needs to pass off all mail to a relay for
processing.Just about any MTA is capable of filling
this particular niche. Unfortunately, it can be very difficult
to properly configure a full-featured MTA
just to handle offloading mail. Programs such as
sendmail and
postfix are largely overkill for
this use.Additionally, if you are using a typical Internet access
service, your agreement may forbid you from running a
mail server.The easiest way to fulfill those needs is to install the
mail/ssmtp port. Execute
the following commands as root:&prompt.root; cd /usr/ports/mail/ssmtp
&prompt.root; make install replace cleanOnce installed,
mail/ssmtp can be configured
with a four-line file located at
/usr/local/etc/ssmtp/ssmtp.conf:root=yourrealemail@example.com
mailhub=mail.example.com
rewriteDomain=example.com
hostname=_HOSTNAME_Make sure you use your real email address for
root. Enter your ISP's outgoing mail relay
in place of mail.example.com (some ISPs call
this the outgoing mail server or
SMTP server).Make sure you disable sendmail,
including the outgoing mail service. See
for details.mail/ssmtp has some
other options available. See the example configuration file in
/usr/local/etc/ssmtp or the manual page of
ssmtp for some examples and more
information.Setting up ssmtp in this manner
will allow any software on your computer that needs to send
mail to function properly, while not violating your ISP's usage
policy or allowing your computer to be hijacked for spamming.Using Mail with a Dialup ConnectionIf you have a static IP address, you should not need to
adjust anything from the defaults. Set your host name to your
assigned Internet name and sendmail will do the rest.If you have a dynamically assigned IP number and use a
dialup PPP connection to the Internet, you will probably have a
mailbox on your ISPs mail server. Let's assume your ISP's domain
is example.net, and that your
user name is user, you have called your
machine bsd.home, and your ISP has
told you that you may use relay.example.net as a mail relay.In order to retrieve mail from your mailbox, you must
install a retrieval agent. The
fetchmail utility is a good choice as
it supports many different protocols. This program is available
as a package or from the Ports Collection (mail/fetchmail). Usually, your ISP will
provide POP. If you are using user PPP, you can
automatically fetch your mail when an Internet connection is
established with the following entry in
/etc/ppp/ppp.linkup:MYADDR:
!bg su user -c fetchmailIf you are using sendmail (as
shown below) to deliver mail to non-local accounts, you probably
want to have sendmail process your
mailqueue as soon as your Internet connection is established.
To do this, put this command after the
fetchmail command in
/etc/ppp/ppp.linkup: !bg su user -c "sendmail -q"Assume that you have an account for
user on bsd.home. In the home directory of
user on bsd.home, create a
.fetchmailrc file:poll example.net protocol pop3 fetchall pass MySecretThis file should not be readable by anyone except
user as it contains the password
MySecret.In order to send mail with the correct
from: header, you must tell
sendmail to use
user@example.net rather than
user@bsd.home. You may also wish to tell
sendmail to send all mail via relay.example.net, allowing quicker mail
transmission.The following .mc file should
suffice:VERSIONID(`bsd.home.mc version 1.0')
OSTYPE(bsd4.4)dnl
FEATURE(nouucp)dnl
MAILER(local)dnl
MAILER(smtp)dnl
Cwlocalhost
Cwbsd.home
MASQUERADE_AS(`example.net')dnl
FEATURE(allmasquerade)dnl
FEATURE(masquerade_envelope)dnl
FEATURE(nocanonify)dnl
FEATURE(nodns)dnl
define(`SMART_HOST', `relay.example.net')
Dmbsd.home
define(`confDOMAIN_NAME',`bsd.home')dnl
define(`confDELIVERY_MODE',`deferred')dnlRefer to the previous section for details of how to turn
this .mc file into a
sendmail.cf file. Also, do not forget to
restart sendmail after updating
sendmail.cf.JamesGorhamWritten by SMTP AuthenticationHaving SMTP Authentication in place on
your mail server has a number of benefits.
SMTP Authentication can add another layer
of security to sendmail, and has the benefit of giving mobile
users who switch hosts the ability to use the same mail server
without the need to reconfigure their mail client settings
each time.Install security/cyrus-sasl
from the ports. You can find this port in
security/cyrus-sasl.
security/cyrus-sasl has
a number of compile time options to choose from and, for
the method we will be using here, make sure to select the
option.After installing security/cyrus-sasl,
edit /usr/local/lib/sasl/Sendmail.conf
(or create it if it does not exist) and add the following
line:pwcheck_method: passwdThis method will enable sendmail
to authenticate against your FreeBSD passwd
database. This saves the trouble of creating a new set of usernames
and passwords for each user that needs to use
SMTP authentication, and keeps the login
and mail password the same.Now edit /etc/make.conf and add the
following lines:SENDMAIL_CFLAGS=-I/usr/local/include/sasl1 -DSASL
SENDMAIL_LDFLAGS=-L/usr/local/lib
SENDMAIL_LDADD=-lsaslThese lines will give sendmail
the proper configuration options for linking
to cyrus-sasl at compile time.
Make sure that cyrus-sasl
has been installed before recompiling
sendmail.Recompile sendmail by executing the following commands:&prompt.root; cd /usr/src/usr.sbin/sendmail
&prompt.root; make cleandir
&prompt.root; make obj
&prompt.root; make
&prompt.root; make installThe compile of sendmail should not have any problems
if /usr/src has not been changed extensively
and the shared libraries it needs are available.After sendmail has been compiled
and reinstalled, edit your /etc/mail/freebsd.mc
file (or whichever file you use as your .mc file. Many administrators
choose to use the output from &man.hostname.1; as the .mc file for
uniqueness). Add these lines to it:dnl set SASL options
TRUST_AUTH_MECH(`GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN')dnl
define(`confAUTH_MECHANISMS', `GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN')dnl
define(`confDEF_AUTH_INFO', `/etc/mail/auth-info')dnlThese options configure the different methods available to
sendmail for authenticating users.
If you would like to use a method other than
pwcheck, please see the
included documentation.Finally, run &man.make.1; while in /etc/mail.
That will run your new .mc file and create a .cf file named
freebsd.cf (or whatever name you have used
for your .mc file). Then use the
command make install restart, which will
copy the file to sendmail.cf, and will
properly restart sendmail.
For more information about this process, you should refer
to /etc/mail/Makefile.If all has gone correctly, you should be able to enter your login
information into the mail client and send a test message.
For further investigation, set the of
sendmail to 13 and watch
/var/log/maillog for any errors.You may wish to add the following line to /etc/rc.conf
so this service will be available after every system boot:cyrus_pwcheck_enable="YES"This will ensure the initialization of SMTP_AUTH upon system
boot.For more information, please see the sendmail
page regarding
SMTP authentication.MarcSilverContributed by Mail User AgentsMail User AgentsA Mail User Agent (MUA) is an application
that is used to send and receive email. Furthermore, as email
evolves and becomes more complex,
MUA's are becoming increasingly powerful in the
way they interact with email; this gives users increased
functionality and flexibility. &os; contains support for
numerous mail user agents, all of which can be easily installed
using the FreeBSD Ports Collection.
Users may choose between graphical email clients such as
evolution or
balsa, console based clients such as
mutt, pine
or mail, or the web interfaces used by some
large organizations.mail&man.mail.1; is the default Mail User Agent
(MUA) in &os;. It is a
console based MUA that offers all the basic
functionality required to send and receive text-based email,
though it is limited in interaction abilities with attachments
and can only support local mailboxes.Although mail does not natively support
interaction with POP or
IMAP servers, these mailboxes may be
downloaded to a local mbox file using an
application such as fetchmail, which
will be discussed later in this chapter ().In order to send and receive email, simply invoke the
mail command as per the following
example:&prompt.user; mailThe contents of the user mailbox in
/var/mail are
automatically read by the mail utility.
Should the mailbox be empty, the utility exits with a
message indicating that no mails could be found. Once the
mailbox has been read, the application interface is started, and
a list of messages will be displayed. Messages are automatically
numbered, as can be seen in the following example:Mail version 8.1 6/6/93. Type ? for help.
"/var/mail/marcs": 3 messages 3 new
>N 1 root@localhost Mon Mar 8 14:05 14/510 "test"
N 2 root@localhost Mon Mar 8 14:05 14/509 "user account"
N 3 root@localhost Mon Mar 8 14:05 14/509 "sample"Messages can now be read by using the tmail command, suffixed by the message number
that should be displayed. In this example, we will read the
first email:& t 1
Message 1:
From root@localhost Mon Mar 8 14:05:52 2004
X-Original-To: marcs@localhost
Delivered-To: marcs@localhost
To: marcs@localhost
Subject: test
Date: Mon, 8 Mar 2004 14:05:52 +0200 (SAST)
From: root@localhost (Charlie Root)
This is a test message, please reply if you receive it.As can be seen in the example above, the t
key will cause the message to be displayed with full headers.
To display the list of messages again, the h
key should be used.If the email requires a response, you may use
mail to reply, by using either the
R or rmail
keys. The R key instructs
mail to reply only to the sender of the
email, while r replies not only to the sender,
but also to other recipients of the message. You may also
suffix these commands with the mail number which you would like
make a reply to. Once this has been done, the response should
be entered, and the end of the message should be marked by a
single . on a new line. An example can be seen
below:& R 1
To: root@localhost
Subject: Re: test
Thank you, I did get your email.
.
EOTIn order to send new email, the m
key should be used, followed by the
recipient email address. Multiple recipients may also be
specified by separating each address with the ,
delimiter. The subject of the message may then be entered,
followed by the message contents. The end of the message should
be specified by putting a single . on a new
line.& mail root@localhost
Subject: I mastered mail
Now I can send and receive email using mail ... :)
.
EOTWhile inside the mail utility, the
? command may be used to display help at any
time, the &man.mail.1; manual page should also be consulted for
more help with mail.As previously mentioned, the &man.mail.1; command was not
originally designed to handle attachments, and thus deals with
them very poorly. Newer MUAs such as
mutt handle attachments in a much
more intelligent way. But should you still wish to use the
mail command, the converters/mpack port may be of
considerable use.muttmutt is a small yet very
powerful Mail User Agent, with excellent features,
just some of which include:The ability to thread messages;PGP support for digital signing and encryption of
email;MIME Support;Maildir Support;Highly customizable.All of these features help to make
mutt one of the most advanced mail
user agents available. See for more
information on mutt.The stable version of mutt may be
installed using the mail/mutt port, while the current
development version may be installed via the mail/mutt-devel port. After the port
has been installed, mutt can be
started by issuing the following command:&prompt.user; muttmutt will automatically read the
contents of the user mailbox in /var/mail and display the contents
if applicable. If no mails are found in the user mailbox, then
mutt will wait for commands from the
user. The example below shows mutt
displaying a list of messages:In order to read an email, simply select it using the cursor
keys, and press the Enter key. An example of
mutt displaying email can be seen
below:As with the &man.mail.1; command,
mutt allows users to reply only to
the sender of the message as well as to all recipients. To
reply only to the sender of the email, use the
r keyboard shortcut. To send a group reply,
which will be sent to the original sender as well as all the
message recipients, use the g shortcut.mutt makes use of the
&man.vi.1; command as an editor for creating and replying to
emails. This may be customized by the user by creating or
editing their own .muttrc file in their home directory and setting the
editor variable.In order to compose a new mail message, press
m. After a valid subject has been given,
mutt will start &man.vi.1; and the
mail can be written. Once the contents of the mail are
complete, save and quit from vi and
mutt will resume, displaying a
summary screen of the mail that is to be delivered. In order to
send the mail, press y. An example of the
summary screen can be seen below:mutt also contains extensive
help, which can be accessed from most of the menus by pressing
the ? key. The top line also displays the
keyboard shortcuts where appropriate.pinepine is aimed at a beginner
user, but also includes some advanced features.The pine software has had several remote vulnerabilities
discovered in the past, which allowed remote attackers to
execute arbitrary code as users on the local system, by the
action of sending a specially-prepared email. All such
known problems have been fixed, but the
pine code is written in a very insecure style and the &os;
Security Officer believes there are likely to be other
undiscovered vulnerabilities. You install
pine at your own risk.The current version of pine may
be installed using the mail/pine4 port. Once the port has
installed, pine can be started by
issuing the following command:&prompt.user; pineThe first time that pine is run
it displays a greeting page with a brief introduction, as well
as a request from the pine
development team to send an anonymous email message allowing
them to judge how many users are using their client. To send
this anonymous message, press Enter, or
alternatively press E to exit the greeting
without sending an anonymous message. An example of the
greeting page can be seen below:Users are then presented with the main menu, which can be
easily navigated using the cursor keys. This main menu provides
shortcuts for the composing new mails, browsing of mail directories,
and even the administration of address book entries. Below the
main menu, relevant keyboard shortcuts to perform functions
specific to the task at hand are shown.The default directory opened by pine
is the inbox. To view the message index, press
I, or select the MESSAGE INDEX
option as seen below:The message index shows messages in the current directory,
and can be navigated by using the cursor keys. Highlighted
messages can be read by pressing the
Enter key.In the screenshot below, a sample message is displayed by
pine. Keyboard shortcuts are
displayed as a reference at the bottom of the screen. An
example of one of these shortcuts is the r key,
which tells the MUA to reply to the current
message being displayed.Replying to an email in pine is
done using the pico editor, which is
installed by default with pine.
The pico utility makes it easy to
navigate around the message and is slightly more forgiving on
novice users than &man.vi.1; or &man.mail.1;. Once the reply
is complete, the message can be sent by pressing
CtrlX. The pine application
will ask for confirmation.The pine application can be
customized using the SETUP option from the main
menu. Consult
for more information.MarcSilverContributed by Using fetchmailfetchmailfetchmail is a full-featured
IMAP and POP client which
allows users to automatically download mail from remote
IMAP and POP servers and
save it into local mailboxes; there it can be accessed more easily.
fetchmail can be installed using the
mail/fetchmail port, and
offers various features, some of which include:Support of POP3,
APOP, KPOP,
IMAP, ETRN and
ODMR protocols.Ability to forward mail using SMTP, which
allows filtering, forwarding, and aliasing to function
normally.May be run in daemon mode to check periodically for new
messages.Can retrieve multiple mailboxes and forward them based
on configuration, to different local users.While it is outside the scope of this document to explain
all of fetchmail's features, some
basic features will be explained. The
fetchmail utility requires a
configuration file known as .fetchmailrc,
in order to run correctly. This file includes server information
as well as login credentials. Due to the sensitive nature of the
contents of this file, it is advisable to make it readable only by the owner,
with the following command:&prompt.user; chmod 600 .fetchmailrcThe following .fetchmailrc serves as an
example for downloading a single user mailbox using
POP. It tells
fetchmail to connect to example.com using a username of
joesoap and a password of
XXX. This example assumes that the user
joesoap is also a user on the local
system.poll example.com protocol pop3 username "joesoap" password "XXX"The next example connects to multiple POP
and IMAP servers and redirects to different
local usernames where applicable:poll example.com proto pop3:
user "joesoap", with password "XXX", is "jsoap" here;
user "andrea", with password "XXXX";
poll example2.net proto imap:
user "john", with password "XXXXX", is "myth" here;The fetchmail utility can be run in daemon
mode by running it with the flag, followed
by the interval (in seconds) that
fetchmail should poll servers listed
in the .fetchmailrc file. The following
example would cause fetchmail to poll
every 600 seconds:&prompt.user; fetchmail -d 600More information on fetchmail can
be found at .MarcSilverContributed by Using procmailprocmailThe procmail utility is an
incredibly powerful application used to filter incoming mail.
It allows users to define rules which can be
matched to incoming mails to perform specific functions or to
reroute mail to alternative mailboxes and/or email addresses.
procmail can be installed using the
mail/procmail port. Once
installed, it can be directly integrated into most
MTAs; consult your MTA
documentation for more information. Alternatively,
procmail can be integrated by adding
the following line to a .forward in the home
directory of the user utilizing
procmail features:"|exec /usr/local/bin/procmail || exit 75"The following section will display some basic
procmail rules, as well as brief
descriptions on what they do. These rules, and others must be
inserted into a .procmailrc file, which
must reside in the user's home directory.The majority of these rules can also be found in the
&man.procmailex.5; manual page.Forward all mail from user@example.com to an
external address of goodmail@example2.com::0
* ^From.*user@example.com
! goodmail@example2.comForward all mails shorter than 1000 bytes to an external
address of goodmail@example2.com::0
* < 1000
! goodmail@example2.comSend all mail sent to alternate@example.com
into a mailbox called alternate::0
* ^TOalternate@example.com
alternateSend all mail with a subject of Spam to
/dev/null::0
^Subject:.*Spam
/dev/nullA useful recipe that parses incoming &os;.org mailing lists
and places each list in its own mailbox::0
* ^Sender:.owner-freebsd-\/[^@]+@FreeBSD.ORG
{
LISTNAME=${MATCH}
:0
* LISTNAME??^\/[^@]+
FreeBSD-${MATCH}
}
diff --git a/zh_TW.Big5/books/handbook/printing/chapter.sgml b/zh_TW.Big5/books/handbook/printing/chapter.sgml
index d54a94b620..1653805d08 100644
--- a/zh_TW.Big5/books/handbook/printing/chapter.sgml
+++ b/zh_TW.Big5/books/handbook/printing/chapter.sgml
@@ -1,4949 +1,4871 @@
SeanKellyContributed by JimMockRestructured and updated by
- Printing
+ 列印
- Synopsis
+ 概述LPD spooling system
+ LPD 緩衝系統printing
+ 列印
- FreeBSD can be used to print with a wide variety of printers, from the
- oldest impact printer to the latest laser printers, and everything in
- between, allowing you to produce high-quality printed output from the
- applications you run.
-
- FreeBSD can also be configured to act as a print server on a
- network; in this capacity FreeBSD can receive print jobs from a variety
- of other computers, including other FreeBSD computers, &windows; and &macos;
- hosts. FreeBSD will ensure that one job at a time is printed, and can
- keep statistics on which users and machines are doing the most printing,
- produce banner pages showing who's printout is who's, and
- more.
+ FreeBSD 可以和各式各樣的印表機搭配列印,
+ 從最老的撞針式印表機到最新的雷射印表機都沒問題,
+ 讓您的應用程式可以產生出高品質的文件列印輸出。
+
+ 也可以把 FreeBSD 設定成一台網路列印伺服器;這時候的 FreeBSD
+ 能接收其他電腦送來的列印工作,包括其他 FreeBSD 的電腦、&windows;
+ 的電腦以及 &macos; 的電腦。 FreeBSD
+ 會確保同時只有一件文件正在列印,而且可以統計哪個使用者及機器印得最多,
+ 還有就是印出接下來是誰的文件這類的標題頁等。
- After reading this chapter, you will know:
+ 讀完這章,您將了解:
- How to configure the FreeBSD print spooler.
+ 如何設定 FreeBSD 的列印多工緩衝處理器。
- How to install print filters, to handle special print jobs
- differently, including converting incoming documents to print
- formats that your printers understand.
+ 如何安裝列印過濾器以分別處理特殊的列印工作,
+ 包括把收到的文件轉換成您的印表機看得懂的列印格式等。
- How to enable header, or banner pages on your printout.
+ 了解如何在您列印時順便印出頁首或標題。
- How to print with printers connected to other computers.
+ 如何利用別台電腦上的印表機列印。
- How to print with printers connected directly to the
- network.
+ 如何利用直接接在網路上的印表機列印。
- How to control printer restrictions, including limiting the size
- of print jobs, and preventing certain users from printing.
+ 如何控制印表機的權限,包括限制列印工作的檔案大小,
+ 以及不允許特定使用者列印等。
- How to keep printer statistics, and account for printer
- usage.
+ 如何記下印表機的統計資料,以及各帳號的印表機使用量。
- How to troubleshoot printing problems.
+ 如何解決列印時遇到的問題。
- Before reading this chapter, you should:
+ 在開始閱讀這章之前,您需要︰
- Know how to configure and install a new kernel
- ().
+ 要有設定、編譯 kernel 的基礎概念
+ ()。
- Introduction
+ 介紹
- In order to use printers with FreeBSD, you may set
- them up to work with the Berkeley line printer spooling system,
- also known as the LPD spooling system,
- or just LPD.
- It is the standard printer control system in FreeBSD. This
- chapter introduces LPD and
- will guide you through its configuration.
+ 要在 FreeBSD 上使用印表機,您需要設定好 Berkeley
+ 行列式印表機列印緩衝系統,又稱為 LPD
+ 列印緩衝系統,或者就叫 LPD。
+ 這是 FreeBSD 標準的印表機控制系統,本章會介紹並教您如何設定
+ LPD
- If you are already familiar with
- LPD or another printer spooling
- system, you may wish to skip to section Basic Setup.
+ 如果您已經對 LPD
+ 或是其他列印緩衝系統很熟悉了,
+ 您可以直接跳到基本設定。
+
- LPD controls everything about a
- host's printers. It is responsible for a number of things:
+ LPD 控制著主機上印表機的一切。
+ 這些事情都是它在負責的:It controls access to attached printers and printers
attached to other hosts on the network.print jobsIt enables users to submit files to be printed; these
submissions are known as jobs.It prevents multiple users from accessing a printer at the
same time by maintaining a queue for each
printer.It can print header pages (also known
as banner or burst
pages) so users can easily find jobs they have printed in a
stack of printouts.It takes care of communications parameters for printers
connected on serial ports.It can send jobs over the network to a
LPD spooler on another host.It can run special filters to format jobs to be printed for
various printer languages or printer capabilities.It can account for printer usage.Through a configuration file
(/etc/printcap), and by providing the special
filter programs, you can enable the LPD
system to do all or some
subset of the above for a great variety of printer hardware.Why You Should Use the SpoolerIf you are the sole user of your system, you may be wondering
why you should bother with the spooler when you do not need access
control, header pages, or printer accounting. While it is
possible to enable direct access to a printer, you should use the
spooler anyway since:LPD prints jobs in the background;
you do not have to wait
for data to be copied to the printer.&tex;LPD can conveniently run a job
to be printed through
filters to add date/time headers or convert a special file
format (such as a &tex; DVI file) into a format the printer will
understand. You will not have to do these steps
manually.Many free and commercial programs that provide a print
feature usually expect to talk to the spooler on your system.
By setting up the spooling system, you will more easily
support other software you may later add or already
have.Basic SetupTo use printers with the LPD spooling
system, you will need to
set up both your printer hardware and the
LPD software. This
document describes two levels of setup:See section Simple Printer
Setup to learn how to connect a printer, tell
LPD how to
communicate with it, and print plain text files to the
printer.See section Advanced
Printer Setup to learn how to print a variety of
special file formats, to print header pages, to print across a
network, to control access to printers, and to do printer
accounting.Simple Printer SetupThis section tells how to configure printer hardware and the
LPD software to use the printer.
It teaches the basics:Section Hardware
Setup gives some hints on connecting the printer to a
port on your computer.Section Software
Setup shows how to set up the
LPD spooler configuration
file (/etc/printcap).If you are setting up a printer that uses a network protocol
to accept data to print instead of a computer's local interfaces,
see Printers With
Networked Data Stream Interfaces.Although this section is called Simple Printer
Setup, it is actually fairly complex. Getting the printer
to work with your computer and the LPD
spooler is the hardest
part. The advanced options like header pages and accounting are
fairly easy once you get the printer working.Hardware SetupThis section tells about the various ways you can connect a
printer to your PC. It talks about the kinds of ports and
cables, and also the kernel configuration you may need to enable
FreeBSD to speak to the printer.If you have already connected your printer and have
successfully printed with it under another operating system, you
can probably skip to section Software Setup.Ports and CablesPrinters sold for use on PC's today generally come
with one or more of the following three interfaces:printersserialSerial interfaces, also known
as RS-232 or COM ports, use a serial port
on your computer to send data to the printer. Serial
interfaces are common in the computer industry and cables
are readily available and also easy to construct. Serial
interfaces sometimes need special cables and might require
you to configure somewhat complex communications
options. Most PC serial ports have a maximum
transmission rate of 115200 bps, which makes printing
large graphic print jobs with them impractical.printersparallelParallel interfaces use a
parallel port on your computer to send data to the
printer. Parallel interfaces are common in the PC market
and are faster than RS-232 serial.
Cables are readily available but more difficult to
construct by hand. There are usually no communications
options with parallel interfaces, making their
configuration exceedingly simple.centronicsparallel printersParallel interfaces are sometimes known as
Centronics interfaces, named after the
connector type on the printer.printersUSBUSB interfaces, named for the Universal Serial
Bus, can run at even faster speeds than parallel or
RS-232 serial interfaces. Cables are simple and cheap.
USB is superior to RS-232 Serial and to Parallel for
printing, but it is not as well supported under &unix;
systems. A way to avoid this problem is to purchase a
printer that has both a USB interface and a Parallel
interface, as many printers do.In general, Parallel interfaces usually offer just
one-way communication (computer to printer) while serial
and USB gives you two-way. Newer parallel ports (EPP and
ECP) and printers
can communicate in both directions under FreeBSD when a
IEEE-1284-compliant cable is used.PostScriptTwo-way communication to the printer over a parallel
port is generally done in one of two ways. The first method
uses a custom-built printer driver for FreeBSD that speaks
the proprietary language used by the printer. This is
common with inkjet printers and can be used for reporting
ink levels and other status information. The second
method is used when the printer supports
&postscript;.&postscript; jobs are
actually programs sent to the printer; they need not produce
paper at all and may return results directly to the computer.
&postscript; also uses two-way communication to tell the
computer about problems, such as errors in the &postscript;
program or paper jams. Your users may be appreciative of such
information. Furthermore, the best way to do effective
accounting with a &postscript; printer requires two-way
communication: you ask the printer for its page count (how
many pages it has printed in its lifetime), then send the
user's job, then ask again for its page count. Subtract the
two values and you know how much paper to charge to the
user.Parallel PortsTo hook up a printer using a parallel interface, connect
the Centronics cable between the printer and the computer.
The instructions that came with the printer, the computer, or
both should give you complete guidance.Remember which parallel port you used on the computer.
The first parallel port is ppc0 to
FreeBSD; the second is ppc1, and so
on. The printer device name uses the same scheme:
/dev/lpt0 for the printer on the first
parallel ports etc.Serial PortsTo hook up a printer using a serial interface, connect the
proper serial cable between the printer and the computer. The
instructions that came with the printer, the computer, or both
should give you complete guidance.If you are unsure what the proper serial
cable is, you may wish to try one of the following
alternatives:A modem cable connects each pin
of the connector on one end of the cable straight through
to its corresponding pin of the connector on the other
end. This type of cable is also known as a
DTE-to-DCE cable.null-modem cableA null-modem cable connects some
pins straight through, swaps others (send data to receive
data, for example), and shorts some internally in each
connector hood. This type of cable is also known as a
DTE-to-DTE cable.A serial printer cable, required
for some unusual printers, is like the null-modem cable,
but sends some signals to their counterparts instead of
being internally shorted.baud rateparityflow control protocolYou should also set up the communications parameters for
the printer, usually through front-panel controls or DIP
switches on the printer. Choose the highest
bps (bits per second, sometimes
baud rate) that both your computer
and the printer can support. Choose 7 or 8 data bits; none,
even, or odd parity; and 1 or 2 stop bits. Also choose a flow
control protocol: either none, or XON/XOFF (also known as
in-band or software) flow control.
Remember these settings for the software configuration that
follows.Software SetupThis section describes the software setup necessary to print
with the LPD spooling system in FreeBSD.
Here is an outline of the steps involved:Configure your kernel, if necessary, for the port you
are using for the printer; section Kernel Configuration tells
you what you need to do.Set the communications mode for the parallel port, if
you are using a parallel port; section Setting the
Communication Mode for the Parallel Port gives
details.Test if the operating system can send data to the printer.
Section Checking Printer
Communications gives some suggestions on how to do
this.Set up LPD for the printer by
modifying the file
/etc/printcap. You will find out how
to do this later in this chapter.Kernel ConfigurationThe operating system kernel is compiled to work with a
specific set of devices. The serial or parallel interface for
your printer is a part of that set. Therefore, it might be
necessary to add support for an additional serial or parallel
port if your kernel is not already configured for one.To find out if the kernel you are currently using supports
a serial interface, type:&prompt.root; grep sioN /var/run/dmesg.bootWhere N is the number of the
serial port, starting from zero. If you see output similar to
the following:sio2 at port 0x3e8-0x3ef irq 5 on isa
sio2: type 16550Athen the kernel supports the port.To find out if the kernel supports a parallel interface,
type:&prompt.root; grep ppcN /var/run/dmesg.bootWhere N is the number of the
parallel port, starting from zero. If you see output similar
to the following:ppc0: <Parallel port> at port 0x378-0x37f irq 7 on isa0
ppc0: SMC-like chipset (ECP/EPP/PS2/NIBBLE) in COMPATIBLE mode
ppc0: FIFO with 16/16/8 bytes thresholdthen the kernel supports the port.You might have to reconfigure your kernel in order for the
operating system to recognize and use the parallel or serial
port you are using for the printer.To add support for a serial port, see the section on
kernel configuration. To add support for a parallel port, see
that section and the section that
follows.
-
-
- Adding /dev Entries for the
- Ports
-
- FreeBSD 5.0 includes the devfs
- filesystem which automatically creates device nodes as
- needed. If you are running a version of FreeBSD with
- devfs enabled then you can safely skip
- this section.
-
- Even though the kernel may support communication along a
- serial or parallel port, you will still need a software
- interface through which programs running on the system can
- send and receive data. That is what entries in the
- /dev directory are for.
-
- To add a /dev entry for a
- port:
-
-
-
- Become root with the &man.su.1; command.
- Enter the root password when prompted.
-
-
-
- Change to the /dev
- directory:
-
- &prompt.root; cd /dev
-
-
-
- Type:
-
- &prompt.root; ./MAKEDEV port
-
- Where port is the device
- entry for the port you want to make. Use
- lpt0 for the printer on the first parallel port,
- lpt1 for the printer on the second port, and so on; use
- ttyd0 for the first serial port,
- ttyd1 for the second, and so on.
-
-
-
- Type:
-
- &prompt.root; ls -l port
-
- to make sure the device entry got created.
-
-
-
-
+ Setting the Communication Mode for the Parallel
PortWhen you are using the parallel interface, you can choose
whether FreeBSD should use interrupt-driven or polled
communication with the printer. The generic printer
- device driver (&man.lpt.4;) on FreeBSD 4.X and 5.X
+ device driver (&man.lpt.4;) on FreeBSD
uses the &man.ppbus.4; system, which controls the port
chipset with the &man.ppc.4; driver.The interrupt-driven method is
the default with the GENERIC kernel. With this method,
the operating system uses an IRQ line to determine when
the printer is ready for data.The polled method directs the
operating system to repeatedly ask the printer if it is
ready for more data. When it responds ready, the kernel
sends more data.The interrupt-driven method is usually somewhat faster
but uses up a precious IRQ line. Some newer HP printers
are claimed not to work correctly in interrupt mode,
apparently due to some (not yet exactly understood) timing
problem. These printers need polled mode. You should use
whichever one works. Some printers will work in both
modes, but are painfully slow in interrupt mode.You can set the communications mode in two ways: by
configuring the kernel or by using the &man.lptcontrol.8;
program.To set the communications mode by configuring
the kernel:Edit your kernel configuration file. Look for
an ppc0 entry. If you are setting up
the second parallel port, use ppc1
instead. Use ppc2 for the third port,
and so on.
- If you want interrupt-driven mode, for FreeBSD 4.X add the
- irq specifier:
-
- device ppc0 at isa? irq N
-
- Where N is the IRQ
- number for your computer's parallel port.
-
- For FreeBSD 5.X, edit the following line:
+ If you want interrupt-driven mode, edit the following line:hint.ppc.0.irq="N"in the /boot/device.hints file
and replace N with the right
IRQ number. The kernel configuration file must
also contain the &man.ppc.4; driver:device ppc
- If you want polled mode, do not add the
- irq specifier:
-
- For FreeBSD 4.X, use the following line in
- your kernel configuration file:
-
- device ppc0 at isa?
-
- For FreeBSD 5.X, simply remove in your
+ If you want polled mode, remove in your
/boot/device.hints file, the
following line:hint.ppc.0.irq="N"In some cases, this is not enough to put the
- port in polled mode under FreeBSD 5.X. Most of
+ port in polled mode under FreeBSD. Most of
time it comes from &man.acpi.4; driver, this latter
is able to probe and attach devices, and therefore,
control the access mode to the printer port. You
should check your &man.acpi.4; configuration to
correct this problem.Save the file. Then configure, build, and install the
kernel, then reboot. See kernel configuration for
more details.To set the communications mode with
&man.lptcontrol.8;:Type:&prompt.root; lptcontrol -i -d /dev/lptNto set interrupt-driven mode for
lptN.Type:&prompt.root; lptcontrol -p -d /dev/lptNto set polled-mode for
lptN.You could put these commands in your
/etc/rc.local file to set the mode each
time your system boots. See &man.lptcontrol.8; for more
information.
-
+
-
+ Checking Printer CommunicationsBefore proceeding to configure the spooling system, you
should make sure the operating system can successfully send
data to your printer. It is a lot easier to debug printer
communication and the spooling system separately.To test the printer, we will send some text to it. For
printers that can immediately print characters sent to them,
the program &man.lptest.1; is perfect: it generates all 96
printable ASCII characters in 96 lines.PostScriptFor a &postscript; (or other language-based) printer, we
will need a more sophisticated test. A small &postscript;
program, such as the following, will suffice:%!PS
100 100 moveto 300 300 lineto stroke
310 310 moveto /Helvetica findfont 12 scalefont setfont
(Is this thing working?) show
showpageThe above &postscript; code can be placed into a file and
used as shown in the examples appearing in the following
sections.PCLWhen this document refers to a printer language, it is
assuming a language like &postscript;, and not Hewlett
Packard's PCL. Although PCL has great functionality, you
can intermingle plain text with its escape sequences.
&postscript; cannot directly print plain text, and that is the
kind of printer language for which we must make special
accommodations.
-
+ Checking a Parallel PrinterprintersparallelThis section tells you how to check if FreeBSD can
communicate with a printer connected to a parallel
port.To test a printer on a parallel
port:Become root with &man.su.1;.Send data to the printer.If the printer can print plain text, then use
&man.lptest.1;. Type:&prompt.root; lptest > /dev/lptNWhere N is the number
of the parallel port, starting from zero.If the printer understands &postscript; or other
printer language, then send a small program to the
printer. Type:&prompt.root; cat > /dev/lptNThen, line by line, type the program
carefully as you cannot edit a
line once you have pressed RETURN
or ENTER. When you have finished
entering the program, press
CONTROL+D, or whatever your end
of file key is.Alternatively, you can put the program in a file
and type:&prompt.root; cat file > /dev/lptNWhere file is the
name of the file containing the program you want to
send to the printer.You should see something print. Do not worry if the
text does not look right; we will fix such things
later.
-
+
-
+ Checking a Serial PrinterprintersserialThis section tells you how to check if FreeBSD can
communicate with a printer on a serial port.To test a printer on a serial
port:Become root with &man.su.1;.Edit the file /etc/remote. Add
the following entry:printer:dv=/dev/port:br#bps-rate:pa=paritybits-per-secondserial portparityWhere port is the device
entry for the serial port (ttyd0,
ttyd1, etc.),
bps-rate is the
bits-per-second rate at which the printer communicates,
and parity is the parity
required by the printer (either even,
odd, none, or
zero).Here is a sample entry for a printer connected via
a serial line to the third serial port at 19200 bps with
no parity:printer:dv=/dev/ttyd2:br#19200:pa=noneConnect to the printer with &man.tip.1;.
Type:&prompt.root; tip printerIf this step does not work, edit the file
/etc/remote again and try using
/dev/cuaaN
instead of
/dev/ttydN.Send data to the printer.If the printer can print plain text, then use
&man.lptest.1;. Type:&prompt.user; $lptestIf the printer understands &postscript; or other
printer language, then send a small program to the
printer. Type the program, line by line,
very carefully as backspacing
or other editing keys may be significant to the
printer. You may also need to type a special
end-of-file key for the printer so it knows it
received the whole program. For &postscript;
printers, press CONTROL+D.Alternatively, you can put the program in a file
and type:&prompt.user; >fileWhere file is the
name of the file containing the program. After
&man.tip.1; sends the file, press any required
end-of-file key.You should see something print. Do not worry if the
text does not look right; we will fix that later.
-
-
-
+
+
Enabling the Spooler: the /etc/printcap
FileAt this point, your printer should be hooked up, your kernel
configured to communicate with it (if necessary), and you have
been able to send some simple data to the printer. Now, we are
ready to configure LPD to control access
to your printer.You configure LPD by editing the file
/etc/printcap. The
LPD spooling system
reads this file each time the spooler is used, so updates to the
file take immediate effect.printerscapabilitiesThe format of the &man.printcap.5; file is straightforward.
Use your favorite text editor to make changes to
/etc/printcap. The format is identical to
other capability files like
/usr/share/misc/termcap and
/etc/remote. For complete information
about the format, see the &man.cgetent.3;.The simple spooler configuration consists of the following
steps:Pick a name (and a few convenient aliases) for the
printer, and put them in the
/etc/printcap file; see the
Naming the Printer
section for more information on naming.header pagesTurn off header pages (which are on by default) by
inserting the sh capability; see the
Suppressing Header
Pages section for more information.Make a spooling directory, and specify its location with
the sd capability; see the Making the Spooling
Directory section for more information.Set the /dev entry to use for the
printer, and note it in /etc/printcap
with the lp capability; see the Identifying the Printer
Device for more information. Also, if the printer is
on a serial port, set up the communication parameters with
the ms# capability which is discussed in the Configuring Spooler
Communications Parameters section.Install a plain text input filter; see the Installing the Text
Filter section for details.Test the setup by printing something with the
&man.lpr.1; command. More details are available in the
Trying It Out and
Troubleshooting
sections.Language-based printers, such as &postscript; printers,
cannot directly print plain text. The simple setup outlined
above and described in the following sections assumes that if
you are installing such a printer you will print only files
that the printer can understand.Users often expect that they can print plain text to any of
the printers installed on your system. Programs that interface
to LPD to do their printing usually
make the same assumption.
If you are installing such a printer and want to be able to
print jobs in the printer language and
print plain text jobs, you are strongly urged to add an
additional step to the simple setup outlined above: install an
automatic plain-text-to-&postscript; (or other printer language)
conversion program. The section entitled Accommodating Plain
Text Jobs on &postscript; Printers tells how to do
this.Naming the PrinterThe first (easy) step is to pick a name for your printer.
It really does not matter whether you choose functional or
whimsical names since you can also provide a number of aliases
for the printer.At least one of the printers specified in the
/etc/printcap should have the alias
lp. This is the default printer's name.
If users do not have the PRINTER environment
variable nor specify a printer name on the command line of any
of the LPD commands,
then lp will be the
default printer they get to use.Also, it is common practice to make the last alias for a
printer be a full description of the printer, including make
and model.Once you have picked a name and some common aliases, put
them in the /etc/printcap file. The name
of the printer should start in the leftmost column. Separate
each alias with a vertical bar and put a colon after the last
alias.In the following example, we start with a skeletal
/etc/printcap that defines two printers
(a Diablo 630 line printer and a Panasonic KX-P4455 &postscript;
laser printer):#
# /etc/printcap for host rose
#
rattan|line|diablo|lp|Diablo 630 Line Printer:
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:In this example, the first printer is named
rattan and has as aliases
line, diablo,
lp, and Diablo 630 Line
Printer. Since it has the alias
lp, it is also the default printer. The
second is named bamboo, and has as aliases
ps, PS,
S, panasonic, and
Panasonic KX-P4455 PostScript v51.4.Suppressing Header Pagesprintingheader pagesThe LPD spooling system will
by default print a
header page for each job. The header
page contains the user name who requested the job, the host
from which the job came, and the name of the job, in nice
large letters. Unfortunately, all this extra text gets in the
way of debugging the simple printer setup, so we will suppress
header pages.To suppress header pages, add the sh
capability to the entry for the printer in
/etc/printcap. Here is an example
/etc/printcap with sh
added:#
# /etc/printcap for host rose - no header pages anywhere
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
:sh:
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:sh:Note how we used the correct format: the first line starts
in the leftmost column, and subsequent lines are indented.
Every line in an entry except the last ends in
a backslash character.Making the Spooling Directoryprinter spoolprint jobsThe next step in the simple spooler setup is to make a
spooling directory, a directory where
print jobs reside until they are printed, and where a number
of other spooler support files live.Because of the variable nature of spooling directories, it
is customary to put these directories under
/var/spool. It is not necessary to
backup the contents of spooling directories, either.
Recreating them is as simple as running &man.mkdir.1;.It is also customary to make the directory with a name
that is identical to the name of the printer, as shown
below:&prompt.root; mkdir /var/spool/printer-nameHowever, if you have a lot of printers on your network,
you might want to put the spooling directories under a single
directory that you reserve just for printing with
LPD. We
will do this for our two example printers
rattan and
bamboo:&prompt.root; mkdir /var/spool/lpd
&prompt.root; mkdir /var/spool/lpd/rattan
&prompt.root; mkdir /var/spool/lpd/bambooIf you are concerned about the privacy of jobs that
users print, you might want to protect the spooling
directory so it is not publicly accessible. Spooling
directories should be owned and be readable, writable, and
searchable by user daemon and group daemon, and no one else.
We will do this for our example printers:&prompt.root; chown daemon:daemon /var/spool/lpd/rattan
&prompt.root; chown daemon:daemon /var/spool/lpd/bamboo
&prompt.root; chmod 770 /var/spool/lpd/rattan
&prompt.root; chmod 770 /var/spool/lpd/bambooFinally, you need to tell LPD
about these directories
using the /etc/printcap file. You
specify the pathname of the spooling directory with the
sd capability:#
# /etc/printcap for host rose - added spooling directories
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
:sh:sd=/var/spool/lpd/rattan:
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:sh:sd=/var/spool/lpd/bamboo:Note that the name of the printer starts in the first
column but all other entries describing the printer should be
indented and each line end escaped with a
backslash.If you do not specify a spooling directory with
sd, the spooling system will use
/var/spool/lpd as a default.Identifying the Printer Device
- In the Adding
- /dev Entries for the Ports
+ In the
+ Entries for the Ports
section, we identified which entry in the
/dev directory FreeBSD will use to
communicate with the printer. Now, we tell
LPD that
information. When the spooling system has a job to print, it
will open the specified device on behalf of the filter program
(which is responsible for passing data to the printer).List the /dev entry pathname in the
/etc/printcap file using the
lp capability.In our running example, let us assume that
rattan is on the first parallel port, and
bamboo is on a sixth serial port; here are
the additions to /etc/printcap:#
# /etc/printcap for host rose - identified what devices to use
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
:sh:sd=/var/spool/lpd/rattan:\
:lp=/dev/lpt0:
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:sh:sd=/var/spool/lpd/bamboo:\
:lp=/dev/ttyd5:If you do not specify the lp capability
for a printer in your /etc/printcap file,
LPD uses /dev/lp
as a default.
/dev/lp currently does not exist in
FreeBSD.If the printer you are installing is connected to a
parallel port, skip to the section entitled, Installing the Text
Filter. Otherwise, be sure to follow the instructions
in the next section.Configuring Spooler Communication ParametersprintersserialFor printers on serial ports, LPD
can set up the bps rate,
parity, and other serial communication parameters on behalf of
the filter program that sends data to the printer. This is
advantageous since:It lets you try different communication parameters by
simply editing the /etc/printcap
file; you do not have to recompile the filter
program.It enables the spooling system to use the same filter
program for multiple printers which may have different
serial communication settings.The following /etc/printcap
capabilities control serial communication parameters of the
device listed in the lp capability:br#bps-rateSets the communications speed of the device to
bps-rate, where
bps-rate can be 50, 75, 110,
134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600,
19200, 38400, 57600, or 115200 bits-per-second.ms#stty-modeSets the options for the terminal device after
opening the device. &man.stty.1; explains the
available options.When LPD opens the device
specified by the lp capability, it sets
the characteristics of the device to those specified with
the ms# capability. Of particular
interest will be the parenb,
parodd, cs5,
cs6, cs7,
cs8, cstopb,
crtscts, and ixon
modes, which are explained in the &man.stty.1;
manual page.Let us add to our example printer on the sixth serial
port. We will set the bps rate to 38400. For the mode,
we will set no parity with -parenb,
8-bit characters with cs8,
no modem control with clocal and
hardware flow control with crtscts:bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:sh:sd=/var/spool/lpd/bamboo:\
:lp=/dev/ttyd5:ms#-parenb cs8 clocal crtscts:Installing the Text FilterprintingfiltersWe are now ready to tell LPD
what text filter to use to
send jobs to the printer. A text filter,
also known as an input filter, is a
program that LPD runs when it
has a job to print. When LPD
runs the text filter for a printer, it sets the filter's
standard input to the job to print, and its standard output to
the printer device specified with the lp
capability. The filter is expected to read the job from
standard input, perform any necessary translation for the
printer, and write the results to standard output, which will
get printed. For more information on the text filter, see
the Filters
section.For our simple printer setup, the text filter can be a
small shell script that just executes
/bin/cat to send the job to the printer.
FreeBSD comes with another filter called
lpf that handles backspacing and
underlining for printers that might not deal with such
character streams well. And, of course, you can use any other
filter program you want. The filter lpf is
described in detail in section entitled lpf: a Text
Filter.First, let us make the shell script
/usr/local/libexec/if-simple be a simple
text filter. Put the following text into that file with your
favorite text editor:#!/bin/sh
#
# if-simple - Simple text input filter for lpd
# Installed in /usr/local/libexec/if-simple
#
# Simply copies stdin to stdout. Ignores all filter arguments.
/bin/cat && exit 0
exit 2Make the file executable:&prompt.root; chmod 555 /usr/local/libexec/if-simpleAnd then tell LPD to use it by specifying it with the
if capability in
/etc/printcap. We will add it to the two
printers we have so far in the example
/etc/printcap:#
# /etc/printcap for host rose - added text filter
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
:sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\
:if=/usr/local/libexec/if-simple:
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:sh:sd=/var/spool/lpd/bamboo:\
:lp=/dev/ttyd5:ms#-parenb cs8 clocal crtscts:\
:if=/usr/local/libexec/if-simple:A copy of the if-simple script
can be found in the /usr/share/examples/printing
directory.Turn on LPD&man.lpd.8; is run from /etc/rc,
controlled by the lpd_enable variable. This
variable defaults to NO. If you have not done
so already, add the line:lpd_enable="YES"to /etc/rc.conf, and then either restart
your machine, or just run &man.lpd.8;.&prompt.root; lpdTrying It OutYou have reached the end of the simple
LPD setup.
Unfortunately, congratulations are not quite yet in order,
since we still have to test the setup and correct any
problems. To test the setup, try printing something. To
print with the LPD system, you
use the command &man.lpr.1;,
which submits a job for printing.You can combine &man.lpr.1; with the &man.lptest.1;
program, introduced in section Checking Printer
Communications to generate some test text.To test the simple LPD
setup:Type:&prompt.root; lptest 20 5 | lpr -Pprinter-nameWhere printer-name is a the
name of a printer (or an alias) specified in
/etc/printcap. To test the default
printer, type &man.lpr.1; without any
argument. Again, if you are testing a printer that expects
&postscript;, send a &postscript; program in that language instead
of using &man.lptest.1;. You can do so by putting the program
in a file and typing lpr
file.For a &postscript; printer, you should get the results of
the program. If you are using &man.lptest.1;, then your
results should look like the following:!"#$%&'()*+,-./01234
"#$%&'()*+,-./012345
#$%&'()*+,-./0123456
$%&'()*+,-./01234567
%&'()*+,-./012345678To further test the printer, try downloading larger
programs (for language-based printers) or running
&man.lptest.1; with different arguments. For example,
lptest 80 60 will produce 60 lines of 80
characters each.If the printer did not work, see the Troubleshooting
section.Advanced Printer SetupThis section describes filters for printing specially formatted
files, header pages, printing across networks, and restricting and
accounting for printer usage.FiltersprintingfiltersAlthough LPD handles network protocols,
queuing, access control,
and other aspects of printing, most of the real
work happens in the filters. Filters are
programs that communicate with the printer and handle its device
dependencies and special requirements. In the simple printer setup,
we installed a plain text filter—an extremely simple one that
should work with most printers (section Installing the Text
Filter).However, in order to take advantage of format conversion, printer
accounting, specific printer quirks, and so on, you should understand
how filters work. It will ultimately be the filter's responsibility
to handle these aspects. And the bad news is that most of the time
you have to provide filters yourself. The good
news is that many are generally available; when they are not, they are
usually easy to write.Also, FreeBSD comes with one,
/usr/libexec/lpr/lpf, that works with many
printers that can print plain text. (It handles backspacing and tabs
in the file, and does accounting, but that is about all it does.)
There are also several filters and filter components in the FreeBSD
Ports Collection.Here is what you will find in this section:Section How Filters
Work, tries to give an overview of a filter's role in the
printing process. You should read this section to get an
understanding of what is happening under the hood
when LPD uses filters. This knowledge
could help you anticipate
and debug problems you might encounter as you install more and
more filters on each of your printers.LPD expects every printer to be
able to print plain text by
default. This presents a problem for &postscript; (or other
language-based printers) which cannot directly print plain text.
Section Accommodating
Plain Text Jobs on &postscript; Printers tells you what you
should do to overcome this problem. You should read this
section if you have a &postscript; printer.&postscript; is a popular output format for many programs.
Some people even write &postscript; code directly. Unfortunately,
&postscript; printers are expensive. Section Simulating &postscript; on
Non &postscript; Printers tells how you can further modify
a printer's text filter to accept and print &postscript; data on a
non &postscript; printer. You should read
this section if you do not have a &postscript; printer.Section Conversion
Filters tells about a way you can automate the conversion
of specific file formats, such as graphic or typesetting data,
into formats your printer can understand. After reading this
section, you should be able to set up your printers such that
users can type lpr -t to print troff data, or
lpr -d to print &tex; DVI data, or lpr
-v to print raster image data, and so forth. I
recommend reading this section.Section Output
Filters tells all about a not often used feature of
LPD:
output filters. Unless you are printing header pages (see Header Pages),
you can probably skip that section altogether.Section lpf: a Text
Filter describes lpf, a fairly
complete if simple text filter for line printers (and laser
printers that act like line printers) that comes with FreeBSD. If
you need a quick way to get printer accounting working for plain
text, or if you have a printer which emits smoke when it sees
backspace characters, you should definitely consider
lpf.A copy of the various scripts described below can be
found in the /usr/share/examples/printing
directory.How Filters WorkAs mentioned before, a filter is an executable program started
by LPD to handle the device-dependent part of
communicating with the printer.When LPD wants to print a file in a
job, it starts a filter
program. It sets the filter's standard input to the file to print,
its standard output to the printer, and its standard error to the
error logging file (specified in the lf
capability in /etc/printcap, or
/dev/console by default).troffWhich filter LPD starts and the
filter's arguments depend on
what is listed in the /etc/printcap file and
what arguments the user specified for the job on the
&man.lpr.1; command line. For example, if the user typed
lpr -t, LPD would
start the troff filter, listed
in the tf capability for the destination printer.
If the user wanted to print plain text, it would start the
if filter (this is mostly true: see Output Filters for
details).There are three kinds of filters you can specify in
/etc/printcap:The text filter, confusingly called the
input filter in
LPD documentation, handles
regular text printing. Think of it as the default filter.
LPD
expects every printer to be able to print plain text by default,
and it is the text filter's job to make sure backspaces, tabs,
or other special characters do not confuse the printer. If you
are in an environment where you have to account for printer
usage, the text filter must also account for pages printed,
usually by counting the number of lines printed and comparing
that to the number of lines per page the printer supports. The
text filter is started with the following argument list:
filter-name-c-wwidth-llength-iindent-n login-h hostacct-file
where
appears if the job is submitted with lpr
-lwidthis the value from the pw (page
width) capability specified in
/etc/printcap, default 132lengthis the value from the pl (page
length) capability, default 66indentis the amount of the indentation from lpr
-i, default 0loginis the account name of the user printing the
filehostis the host name from which the job was
submittedacct-fileis the name of the accounting file from the
af capability.printingfiltersA conversion filter converts a specific
file format into one the printer can render onto paper. For
example, ditroff typesetting data cannot be directly printed,
but you can install a conversion filter for ditroff files to
convert the ditroff data into a form the printer can digest and
print. Section Conversion
Filters tells all about them. Conversion filters also
need to do accounting, if you need printer accounting.
Conversion filters are started with the following arguments:
filter-name-xpixel-width-ypixel-height-n login-h hostacct-file
where pixel-width is the value
from the px capability (default 0) and
pixel-height is the value from the
py capability (default 0).The output filter is used only if there
is no text filter, or if header pages are enabled. In my
experience, output filters are rarely used. Section Output Filters describe
them. There are only two arguments to an output filter:
filter-name-wwidth-llength
which are identical to the text filters and
arguments.Filters should also exit with the
following exit status:exit 0If the filter printed the file successfully.exit 1If the filter failed to print the file but wants
LPD to
try to print the file again. LPD
will restart a filter if it exits with this status.exit 2If the filter failed to print the file and does not want
LPD to try again.
LPD will throw out the file.The text filter that comes with the FreeBSD release,
/usr/libexec/lpr/lpf, takes advantage of the
page width and length arguments to determine when to send a form
feed and how to account for printer usage. It uses the login, host,
and accounting file arguments to make the accounting entries.If you are shopping for filters, see if they are LPD-compatible.
If they are, they must support the argument lists described above.
If you plan on writing filters for general use, then have them
support the same argument lists and exit codes.Accommodating Plain Text Jobs on &postscript; Printersprint jobsIf you are the only user of your computer and &postscript; (or
other language-based) printer, and you promise to never send plain
text to your printer and to never use features of various programs
that will want to send plain text to your printer, then you do not
need to worry about this section at all.But, if you would like to send both &postscript; and plain text
jobs to the printer, then you are urged to augment your printer
setup. To do so, we have the text filter detect if the arriving job
is plain text or &postscript;. All &postscript; jobs must start with
%! (for other printer languages, see your printer
documentation). If those are the first two characters in the job,
we have &postscript;, and can pass the rest of the job directly. If
those are not the first two characters in the file, then the filter
will convert the text into &postscript; and print the result.How do we do this?printersserialIf you have got a serial printer, a great way to do it is to
install lprps. lprps is a
&postscript; printer filter which performs two-way communication with
the printer. It updates the printer's status file with verbose
information from the printer, so users and administrators can see
exactly what the state of the printer is (such as toner
low or paper jam). But more
importantly, it includes a program called psif
which detects whether the incoming job is plain text and calls
textps (another program that comes with
lprps) to convert it to &postscript;. It then uses
lprps to send the job to the printer.lprps is part of the FreeBSD Ports Collection
(see The Ports Collection). You can
fetch, build and install it yourself, of course. After installing
lprps, just specify the pathname to the
psif program that is part of
lprps. If you installed lprps
from the Ports Collection, use the following in the serial
&postscript; printer's entry in
/etc/printcap::if=/usr/local/libexec/psif:You should also specify the rw capability;
that tells LPD to open the printer in
read-write mode.If you have a parallel &postscript; printer (and therefore cannot
use two-way communication with the printer, which
lprps needs), you can use the following shell
script as the text filter:#!/bin/sh
#
# psif - Print PostScript or plain text on a PostScript printer
# Script version; NOT the version that comes with lprps
# Installed in /usr/local/libexec/psif
#
IFS="" read -r first_line
first_two_chars=`expr "$first_line" : '\(..\)'`
if [ "$first_two_chars" = "%!" ]; then
#
# PostScript job, print it.
#
echo "$first_line" && cat && printf "\004" && exit 0
exit 2
else
#
# Plain text, convert it, then print it.
#
( echo "$first_line"; cat ) | /usr/local/bin/textps && printf "\004" && exit 0
exit 2
fiIn the above script, textps is a program we
installed separately to convert plain text to &postscript;. You can
use any text-to-&postscript; program you wish. The FreeBSD Ports
Collection (see The Ports Collection)
includes a full featured text-to-&postscript; program called
a2ps that you might want to investigate.Simulating &postscript; on Non &postscript; PrintersPostScriptemulatingGhostscript&postscript; is the de facto standard for
high quality typesetting and printing. &postscript; is, however, an
expensive standard. Thankfully, Aladdin
Enterprises has a free &postscript; work-alike called
Ghostscript that runs with FreeBSD.
Ghostscript can read most &postscript; files and can render their
pages onto a variety of devices, including many brands of
non-PostScript printers. By installing Ghostscript and using a
special text filter for your printer, you can make your
non &postscript; printer act like a real &postscript; printer.Ghostscript is in the FreeBSD Ports Collection, if you
would like to install it from there. You can fetch, build, and
install it quite easily yourself, as well.To simulate &postscript;, we have the text filter detect if it is
printing a &postscript; file. If it is not, then the filter will pass
the file directly to the printer; otherwise, it will use Ghostscript
to first convert the file into a format the printer will
understand.Here is an example: the following script is a text filter
for Hewlett Packard DeskJet 500 printers. For other printers,
substitute the argument to the
gs (Ghostscript) command. (Type gs
-h to get a list of devices the current installation of
Ghostscript supports.)#!/bin/sh
#
# ifhp - Print Ghostscript-simulated PostScript on a DeskJet 500
# Installed in /usr/local/libexec/ifhp
#
# Treat LF as CR+LF (to avoid the "staircase effect" on HP/PCL
# printers):
#
printf "\033&k2G" || exit 2
#
# Read first two characters of the file
#
IFS="" read -r first_line
first_two_chars=`expr "$first_line" : '\(..\)'`
if [ "$first_two_chars" = "%!" ]; then
#
# It is PostScript; use Ghostscript to scan-convert and print it.
#
/usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 \
-sOutputFile=- - && exit 0
else
#
# Plain text or HP/PCL, so just print it directly; print a form feed
# at the end to eject the last page.
#
echo "$first_line" && cat && printf "\033&l0H" &&
exit 0
fi
exit 2Finally, you need to notify LPD of
the filter via the if capability::if=/usr/local/libexec/ifhp:That is it. You can type lpr plain.text and
lpr whatever.ps and both should print
successfully.Conversion FiltersAfter completing the simple setup described in Simple Printer Setup, the first
thing you will probably want to do is install conversion filters for
your favorite file formats (besides plain ASCII text).Why Install Conversion Filters?&tex;printing DVI filesConversion filters make printing various kinds of files easy.
As an example, suppose we do a lot of work with the &tex;
typesetting system, and we have a &postscript; printer. Every time
we generate a DVI file from &tex;, we cannot print it directly until
we convert the DVI file into &postscript;. The command sequence
goes like this:&prompt.user; dvips seaweed-analysis.dvi
&prompt.user; lpr seaweed-analysis.psBy installing a conversion filter for DVI files, we can skip
the hand conversion step each time by having
LPD do it for us.
Now, each time we get a DVI file, we are just one step away from
printing it:&prompt.user; lpr -d seaweed-analysis.dviWe got LPD to do the DVI file
conversion for us by specifying
the option. Section Formatting and Conversion
Options lists the conversion options.For each of the conversion options you want a printer to
support, install a conversion filter and
specify its pathname in /etc/printcap. A
conversion filter is like the text filter for the simple printer
setup (see section Installing
the Text Filter) except that instead of printing plain
text, the filter converts the file into a format the printer can
understand.Which Conversion Filters Should I Install?You should install the conversion filters you expect to use.
If you print a lot of DVI data, then a DVI conversion filter is in
order. If you have got plenty of troff to print out, then you
probably want a troff filter.The following table summarizes the filters that
LPD works
with, their capability entries for the
/etc/printcap file, and how to invoke them
with the lpr command:File type/etc/printcap capabilitylpr optioncifplotcfDVIdfplotgfditroffnfFORTRAN textrftrofftfrastervfplain textifnone, , or
In our example, using lpr -d means the
printer needs a df capability in its entry in
/etc/printcap.FORTRANDespite what others might contend, formats like FORTRAN text
and plot are probably obsolete. At your site, you can give new
meanings to these or any of the formatting options just by
installing custom filters. For example, suppose you would like to
directly print Printerleaf files (files from the Interleaf desktop
publishing program), but will never print plot files. You could
install a Printerleaf conversion filter under the
gf capability and then educate your users that
lpr -g mean print Printerleaf
files.Installing Conversion FiltersSince conversion filters are programs you install outside of
the base FreeBSD installation, they should probably go under
/usr/local. The directory
/usr/local/libexec is a popular location,
since they are specialized programs that only
LPD will run;
regular users should not ever need to run them.To enable a conversion filter, specify its pathname under the
appropriate capability for the destination printer in
/etc/printcap.In our example, we will add the DVI conversion filter to the
entry for the printer named bamboo. Here is
the example /etc/printcap file again, with
the new df capability for the printer
bamboo.#
# /etc/printcap for host rose - added df filter for bamboo
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
:sh:sd=/var/spool/lpd/rattan:\
:lp=/dev/lpt0:\
:if=/usr/local/libexec/if-simple:
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:sh:sd=/var/spool/lpd/bamboo:\
:lp=/dev/ttyd5:ms#-parenb cs8 clocal crtscts:rw:\
:if=/usr/local/libexec/psif:\
:df=/usr/local/libexec/psdf:The DVI filter is a shell script named
/usr/local/libexec/psdf. Here is that
script:#!/bin/sh
#
# psdf - DVI to PostScript printer filter
# Installed in /usr/local/libexec/psdf
#
# Invoked by lpd when user runs lpr -d
#
exec /usr/local/bin/dvips -f | /usr/local/libexec/lprps "$@"This script runs dvips in filter mode (the
argument) on standard input, which is the job
to print. It then starts the &postscript; printer filter
lprps (see section Accommodating Plain
Text Jobs on &postscript; Printers) with the arguments
LPD
passed to this script. lprps will use those
arguments to account for the pages printed.More Conversion Filter ExamplesSince there is no fixed set of steps to install conversion
filters, let me instead provide more examples. Use these as
guidance to making your own filters. Use them directly, if
appropriate.This example script is a raster (well, GIF file, actually)
conversion filter for a Hewlett Packard LaserJet III-Si
printer:#!/bin/sh
#
# hpvf - Convert GIF files into HP/PCL, then print
# Installed in /usr/local/libexec/hpvf
PATH=/usr/X11R6/bin:$PATH; export PATH
giftopnm | ppmtopgm | pgmtopbm | pbmtolj -resolution 300 \
&& exit 0 \
|| exit 2It works by converting the GIF file into a portable anymap,
converting that into a portable graymap, converting that into a
portable bitmap, and converting that into LaserJet/PCL-compatible
data.Here is the /etc/printcap file with an
entry for a printer using the above filter:#
# /etc/printcap for host orchid
#
teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\
:lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\
:if=/usr/local/libexec/hpif:\
:vf=/usr/local/libexec/hpvf:The following script is a conversion filter for troff data
from the groff typesetting system for the &postscript; printer named
bamboo:#!/bin/sh
#
# pstf - Convert groff's troff data into PS, then print.
# Installed in /usr/local/libexec/pstf
#
exec grops | /usr/local/libexec/lprps "$@"The above script makes use of lprps again
to handle the communication with the printer. If the printer were
on a parallel port, we would use this script instead:#!/bin/sh
#
# pstf - Convert groff's troff data into PS, then print.
# Installed in /usr/local/libexec/pstf
#
exec gropsThat is it. Here is the entry we need to add to
/etc/printcap to enable the filter::tf=/usr/local/libexec/pstf:Here is an example that might make old hands at FORTRAN blush.
It is a FORTRAN-text filter for any printer that can directly
print plain text. We will install it for the printer
teak:#!/bin/sh
#
# hprf - FORTRAN text filter for LaserJet 3si:
# Installed in /usr/local/libexec/hprf
#
printf "\033&k2G" && fpr && printf "\033&l0H" &&
exit 0
exit 2And we will add this line to the
/etc/printcap for the printer
teak to enable this filter::rf=/usr/local/libexec/hprf:Here is one final, somewhat complex example. We will add a
DVI filter to the LaserJet printer teak
introduced earlier. First, the easy part: updating
/etc/printcap with the location of the DVI
filter::df=/usr/local/libexec/hpdf:Now, for the hard part: making the filter. For that, we need
a DVI-to-LaserJet/PCL conversion program. The FreeBSD Ports
Collection (see The Ports Collection)
has one: dvi2xx is the name of the package.
Installing this package gives us the program we need,
dvilj2p, which converts DVI into LaserJet IIp,
LaserJet III, and LaserJet 2000 compatible codes.dvilj2p makes the filter
hpdf quite complex since
dvilj2p cannot read from standard input. It
wants to work with a filename. What is worse, the filename has to
end in .dvi so using
/dev/fd/0 for standard input is problematic.
We can get around that problem by linking (symbolically) a
temporary file name (one that ends in .dvi)
to /dev/fd/0, thereby forcing
dvilj2p to read from standard input.The only other fly in the ointment is the fact that we cannot
use /tmp for the temporary link. Symbolic
links are owned by user and group bin. The
filter runs as user daemon. And the
/tmp directory has the sticky bit set. The
filter can create the link, but it will not be able clean up when
done and remove it since the link will belong to a different
user.Instead, the filter will make the symbolic link in the current
working directory, which is the spooling directory (specified by
the sd capability in
/etc/printcap). This is a perfect place for
filters to do their work, especially since there is (sometimes)
more free disk space in the spooling directory than under
/tmp.Here, finally, is the filter:#!/bin/sh
#
# hpdf - Print DVI data on HP/PCL printer
# Installed in /usr/local/libexec/hpdf
PATH=/usr/local/bin:$PATH; export PATH
#
# Define a function to clean up our temporary files. These exist
# in the current directory, which will be the spooling directory
# for the printer.
#
cleanup() {
rm -f hpdf$$.dvi
}
#
# Define a function to handle fatal errors: print the given message
# and exit 2. Exiting with 2 tells LPD to do not try to reprint the
# job.
#
fatal() {
echo "$@" 1>&2
cleanup
exit 2
}
#
# If user removes the job, LPD will send SIGINT, so trap SIGINT
# (and a few other signals) to clean up after ourselves.
#
trap cleanup 1 2 15
#
# Make sure we are not colliding with any existing files.
#
cleanup
#
# Link the DVI input file to standard input (the file to print).
#
ln -s /dev/fd/0 hpdf$$.dvi || fatal "Cannot symlink /dev/fd/0"
#
# Make LF = CR+LF
#
printf "\033&k2G" || fatal "Cannot initialize printer"
#
# Convert and print. Return value from dvilj2p does not seem to be
# reliable, so we ignore it.
#
dvilj2p -M1 -q -e- dfhp$$.dvi
#
# Clean up and exit
#
cleanup
exit 0Automated Conversion: an Alternative to Conversion
FiltersAll these conversion filters accomplish a lot for your
printing environment, but at the cost forcing the user to specify
(on the &man.lpr.1; command line) which one to use.
If your users are not particularly computer literate, having to
specify a filter option will become annoying. What is worse,
though, is that an incorrectly specified filter option may run a
filter on the wrong type of file and cause your printer to spew
out hundreds of sheets of paper.Rather than install conversion filters at all, you might want
to try having the text filter (since it is the default filter)
detect the type of file it has been asked to print and then
automatically run the right conversion filter. Tools such as
file can be of help here. Of course, it will
be hard to determine the differences between
some file types—and, of course, you can
still provide conversion filters just for them.apsfilterprintingfiltersapsfilterThe FreeBSD Ports Collection has a text filter that performs
automatic conversion called apsfilter. It can
detect plain text, &postscript;, and DVI files, run the proper
conversions, and print.Output FiltersThe LPD spooling system supports one
other type of filter that
we have not yet explored: an output filter. An output filter is
intended for printing plain text only, like the text filter, but
with many simplifications. If you are using an output filter but no
text filter, then:LPD starts an output filter once
for the entire job instead
of once for each file in the job.LPD does not make any provision
to identify the start or the
end of files within the job for the output filter.LPD does not pass the user's
login or host to the filter, so
it is not intended to do accounting. In fact, it gets only two
arguments:filter-name-wwidth-llengthWhere width is from the
pw capability and
length is from the
pl capability for the printer in
question.Do not be seduced by an output filter's simplicity. If you
would like each file in a job to start on a different page an output
filter will not work. Use a text filter (also
known as an input filter); see section Installing the Text Filter.
Furthermore, an output filter is actually more
complex in that it has to examine the byte stream being
sent to it for special flag characters and must send signals to
itself on behalf of LPD.However, an output filter is necessary if
you want header pages and need to send escape sequences or other
initialization strings to be able to print the header page. (But it
is also futile if you want to charge header
pages to the requesting user's account, since
LPD does not give any
user or host information to the output filter.)On a single printer, LPD
allows both an output filter and text or other filters. In
such cases, LPD will start the
output filter
to print the header page (see section Header Pages)
only. LPD then expects the
output filter to stop
itself by sending two bytes to the filter: ASCII 031
followed by ASCII 001. When an output filter sees these two bytes
(031, 001), it should stop by sending SIGSTOP
to itself. When
LPD's
done running other filters, it will restart the output filter by
sending SIGCONT to it.If there is an output filter but no text
filter and LPD is working on a plain
text job, LPD uses the output
filter to do the job. As stated before, the output filter will
print each file of the job in sequence with no intervening form
feeds or other paper advancement, and this is probably
not what you want. In almost all cases, you
need a text filter.The program lpf, which we introduced earlier
as a text filter, can also run as an output filter. If you need a
quick-and-dirty output filter but do not want to write the byte
detection and signal sending code, try lpf. You
can also wrap lpf in a shell script to handle any
initialization codes the printer might require.lpf: a Text FilterThe program /usr/libexec/lpr/lpf that comes
with FreeBSD binary distribution is a text filter (input filter)
that can indent output (job submitted with lpr
-i), allow literal characters to pass (job submitted
with lpr -l), adjust the printing position for
backspaces and tabs in the job, and account for pages printed. It
can also act like an output filter.lpf is suitable for many printing
environments. And although it has no capability to send
initialization sequences to a printer, it is easy to write a shell
script to do the needed initialization and then execute
lpf.page accountingaccountingprinterIn order for lpf to do page accounting
correctly, it needs correct values filled in for the
pw and pl capabilities in the
/etc/printcap file. It uses these values to
determine how much text can fit on a page and how many pages were in
a user's job. For more information on printer accounting, see Accounting for Printer
Usage.Header PagesIf you have lots of users, all of them using
various printers, then you probably want to consider header
pages as a necessary evil.banner pagesheader pagesheader pagesHeader pages, also known as banner or
burst pages identify to whom jobs belong after
they are printed. They are usually printed in large, bold letters,
perhaps with decorative borders, so that in a stack of printouts they
stand out from the real documents that comprise users' jobs. They
enable users to locate their jobs quickly. The obvious drawback to a
header page is that it is yet one more sheet that has to be printed
for every job, their ephemeral usefulness lasting not more than a few
minutes, ultimately finding themselves in a recycling bin or rubbish
heap. (Note that header pages go with each job, not each file in a
job, so the paper waste might not be that bad.)The LPD system can provide header
pages automatically for your
printouts if your printer can directly print
plain text. If you have a &postscript; printer, you will need an
external program to generate the header page; see Header Pages on
&postscript; Printers.Enabling Header PagesIn the Simple Printer
Setup section, we turned off header pages by specifying
sh (meaning suppress header) in the
/etc/printcap file. To enable header pages for
a printer, just remove the sh capability.Sounds too easy, right?You are right. You might have to provide
an output filter to send initialization strings to the printer.
Here is an example output filter for Hewlett Packard PCL-compatible
printers:#!/bin/sh
#
# hpof - Output filter for Hewlett Packard PCL-compatible printers
# Installed in /usr/local/libexec/hpof
printf "\033&k2G" || exit 2
exec /usr/libexec/lpr/lpfSpecify the path to the output filter in the
of capability. See the Output Filters section for more
information.Here is an example /etc/printcap file for
the printer teak that we introduced earlier; we
enabled header pages and added the above output filter:#
# /etc/printcap for host orchid
#
teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\
:lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:\
:if=/usr/local/libexec/hpif:\
:vf=/usr/local/libexec/hpvf:\
:of=/usr/local/libexec/hpof:Now, when users print jobs to teak, they get
a header page with each job. If users want to spend time searching
for their printouts, they can suppress header pages by submitting
the job with lpr -h; see the Header Page Options section for
more &man.lpr.1; options.LPD prints a form feed character
after the header page. If
your printer uses a different character or sequence of characters
to eject a page, specify them with the ff
capability in /etc/printcap.Controlling Header PagesBy enabling header pages, LPD will
produce a long
header, a full page of large letters identifying the
user, host, and job. Here is an example (kelly printed the job
named outline from host rose): k ll ll
k l l
k l l
k k eeee l l y y
k k e e l l y y
k k eeeeee l l y y
kk k e l l y y
k k e e l l y yy
k k eeee lll lll yyy y
y
y y
yyyy
ll
t l i
t l
oooo u u ttttt l ii n nnn eeee
o o u u t l i nn n e e
o o u u t l i n n eeeeee
o o u u t l i n n e
o o u uu t t l i n n e e
oooo uuu u tt lll iii n n eeee
r rrr oooo ssss eeee
rr r o o s s e e
r o o ss eeeeee
r o o ss e
r o o s s e e
r oooo ssss eeee
Job: outline
Date: Sun Sep 17 11:04:58 1995LPD appends a form feed after this
text so the job starts on a
new page (unless you have sf (suppress form
feeds) in the destination printer's entry in
/etc/printcap).If you prefer, LPD can make a
short header;
specify sb (short banner) in the
/etc/printcap file. The header page will look
like this:rose:kelly Job: outline Date: Sun Sep 17 11:07:51 1995Also by default, LPD prints the
header page first, then the job.
To reverse that, specify hl (header last) in
/etc/printcap.Accounting for Header PagesUsing LPD's built-in header pages
enforces a particular paradigm
when it comes to printer accounting: header pages must be
free of charge.Why?Because the output filter is the only external program that will
have control when the header page is printed that could do
accounting, and it is not provided with any user or
host information or an accounting file, so it has no
idea whom to charge for printer use. It is also not enough to just
add one page to the text filter or any of the
conversion filters (which do have user and host information) since
users can suppress header pages with lpr -h.
They could still be charged for header pages they did not print.
Basically, lpr -h will be the preferred option of
environmentally-minded users, but you cannot offer any incentive to
use it.It is still not enough to have each of the
filters generate their own header pages (thereby being able to
charge for them). If users wanted the option of suppressing the
header pages with lpr -h, they will still get
them and be charged for them since LPD
does not pass any knowledge
of the option to any of the filters.So, what are your options?You can:Accept LPD's paradigm and make
header pages free.Install an alternative to LPD,
such as
LPRng. Section
Alternatives to the
Standard Spooler tells more about other spooling
software you can substitute for LPD.
Write a smart output filter. Normally,
an output filter is not meant to do anything more than
initialize a printer or do some simple character conversion. It
is suited for header pages and plain text jobs (when there is no
text (input) filter). But, if there is a text filter for the
plain text jobs, then LPD will start
the output filter only for
the header pages. And the output filter can parse the header
page text that LPD generates to
determine what user and host to
charge for the header page. The only other problem with this
method is that the output filter still does not know what
accounting file to use (it is not passed the name of the file
from the af capability), but if you have a
well-known accounting file, you can hard-code that into the
output filter. To facilitate the parsing step, use the
sh (short header) capability in
/etc/printcap. Then again, all that might
be too much trouble, and users will certainly appreciate the
more generous system administrator who makes header pages
free.Header Pages on &postscript; PrintersAs described above, LPD can generate
a plain text header page
suitable for many printers. Of course, &postscript; cannot directly
print plain text, so the header page feature of
LPD is
useless—or mostly so.One obvious way to get header pages is to have every conversion
filter and the text filter generate the header page. The filters
should use the user and host arguments to generate a suitable
header page. The drawback of this method is that users will always
get a header page, even if they submit jobs with lpr
-h.Let us explore this method. The following script takes three
arguments (user login name, host name, and job name) and makes a
simple &postscript; header page:#!/bin/sh
#
# make-ps-header - make a PostScript header page on stdout
# Installed in /usr/local/libexec/make-ps-header
#
#
# These are PostScript units (72 to the inch). Modify for A4 or
# whatever size paper you are using:
#
page_width=612
page_height=792
border=72
#
# Check arguments
#
if [ $# -ne 3 ]; then
echo "Usage: `basename $0` <user> <host> <job>" 1>&2
exit 1
fi
#
# Save these, mostly for readability in the PostScript, below.
#
user=$1
host=$2
job=$3
date=`date`
#
# Send the PostScript code to stdout.
#
exec cat <<EOF
%!PS
%
% Make sure we do not interfere with user's job that will follow
%
save
%
% Make a thick, unpleasant border around the edge of the paper.
%
$border $border moveto
$page_width $border 2 mul sub 0 rlineto
0 $page_height $border 2 mul sub rlineto
currentscreen 3 -1 roll pop 100 3 1 roll setscreen
$border 2 mul $page_width sub 0 rlineto closepath
0.8 setgray 10 setlinewidth stroke 0 setgray
%
% Display user's login name, nice and large and prominent
%
/Helvetica-Bold findfont 64 scalefont setfont
$page_width ($user) stringwidth pop sub 2 div $page_height 200 sub moveto
($user) show
%
% Now show the boring particulars
%
/Helvetica findfont 14 scalefont setfont
/y 200 def
[ (Job:) (Host:) (Date:) ] {
200 y moveto show /y y 18 sub def }
forall
/Helvetica-Bold findfont 14 scalefont setfont
/y 200 def
[ ($job) ($host) ($date) ] {
270 y moveto show /y y 18 sub def
} forall
%
% That is it
%
restore
showpage
EOFNow, each of the conversion filters and the text filter can call
this script to first generate the header page, and then print the
user's job. Here is the DVI conversion filter from earlier in this
document, modified to make a header page:#!/bin/sh
#
# psdf - DVI to PostScript printer filter
# Installed in /usr/local/libexec/psdf
#
# Invoked by lpd when user runs lpr -d
#
orig_args="$@"
fail() {
echo "$@" 1>&2
exit 2
}
while getopts "x:y:n:h:" option; do
case $option in
x|y) ;; # Ignore
n) login=$OPTARG ;;
h) host=$OPTARG ;;
*) echo "LPD started `basename $0` wrong." 1>&2
exit 2
;;
esac
done
[ "$login" ] || fail "No login name"
[ "$host" ] || fail "No host name"
( /usr/local/libexec/make-ps-header $login $host "DVI File"
/usr/local/bin/dvips -f ) | eval /usr/local/libexec/lprps $orig_argsNotice how the filter has to parse the argument list in order to
determine the user and host name. The parsing for the other
conversion filters is identical. The text filter takes a slightly
different set of arguments, though (see section How Filters
Work).As we have mentioned before, the above scheme, though fairly
simple, disables the suppress header page option (the
option) to lpr. If users
wanted to save a tree (or a few pennies, if you charge for header
pages), they would not be able to do so, since every filter's going
to print a header page with every job.To allow users to shut off header pages on a per-job basis, you
will need to use the trick introduced in section Accounting for
Header Pages: write an output filter that parses the
LPD-generated header page and produces a &postscript; version. If the
user submits the job with lpr -h, then
LPD will
not generate a header page, and neither will your output filter.
Otherwise, your output filter will read the text from
LPD and send
the appropriate header page &postscript; code to the printer.If you have a &postscript; printer on a serial line, you can make
use of lprps, which comes with an output filter,
psof, which does the above. Note that
psof does not charge for header pages.Networked Printingprintersnetworknetwork printingFreeBSD supports networked printing: sending jobs to remote
printers. Networked printing generally refers to two different
things:Accessing a printer attached to a remote host. You install a
printer that has a conventional serial or parallel interface on
one host. Then, you set up LPD to
enable access to the printer
from other hosts on the network. Section Printers Installed on
Remote Hosts tells how to do this.Accessing a printer attached directly to a network. The
printer has a network interface in addition (or in place of) a
more conventional serial or parallel interface. Such a printer
might work as follows:It might understand the LPD
protocol and can even queue
jobs from remote hosts. In this case, it acts just like a
regular host running LPD. Follow
the same procedure in
section Printers
Installed on Remote Hosts to set up such a
printer.It might support a data stream network connection. In this
case, you attach the printer to one host on the
network by making that host responsible for spooling jobs and
sending them to the printer. Section Printers with
Networked Data Stream Interfaces gives some
suggestions on installing such printers.Printers Installed on Remote HostsThe LPD spooling system has built-in
support for sending jobs to
other hosts also running LPD (or are
compatible with LPD). This
feature enables you to install a printer on one host and make it
accessible from other hosts. It also works with printers that have
network interfaces that understand the
LPD protocol.To enable this kind of remote printing, first install a printer
on one host, the printer host, using the simple
printer setup described in the Simple
Printer Setup section. Do any advanced setup in Advanced Printer Setup that you
need. Make sure to test the printer and see if it works with the
features of LPD you have enabled.
Also ensure that the
local host has authorization to use the
LPD
service in the remote host (see Restricting Jobs
from Remote Printers).printersnetworknetwork printingIf you are using a printer with a network interface that is
compatible with LPD, then the
printer host in
the discussion below is the printer itself, and the
printer name is the name you configured for the
printer. See the documentation that accompanied your printer and/or
printer-network interface.If you are using a Hewlett Packard Laserjet then the printer
name text will automatically perform the LF to
CRLF conversion for you, so you will not require the
hpif script.Then, on the other hosts you want to have access to the printer,
make an entry in their /etc/printcap files with
the following:Name the entry anything you want. For simplicity, though,
you probably want to use the same name and aliases as on the
printer host.Leave the lp capability blank, explicitly
(:lp=:).Make a spooling directory and specify its location in the
sd capability. LPD
will store jobs here
before they get sent to the printer host.Place the name of the printer host in the
rm capability.Place the printer name on the printer
host in the rp
capability.That is it. You do not need to list conversion filters, page
dimensions, or anything else in the
/etc/printcap file.Here is an example. The host rose has two
printers, bamboo and rattan.
We will enable users on the host orchid to print
to those printers.
Here is the /etc/printcap file for
orchid (back from section Enabling Header
Pages). It already had the entry for the printer
teak; we have added entries for the two printers
on the host rose:#
# /etc/printcap for host orchid - added (remote) printers on rose
#
#
# teak is local; it is connected directly to orchid:
#
teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\
:lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:\
:if=/usr/local/libexec/ifhp:\
:vf=/usr/local/libexec/vfhp:\
:of=/usr/local/libexec/ofhp:
#
# rattan is connected to rose; send jobs for rattan to rose:
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
:lp=:rm=rose:rp=rattan:sd=/var/spool/lpd/rattan:
#
# bamboo is connected to rose as well:
#
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:lp=:rm=rose:rp=bamboo:sd=/var/spool/lpd/bamboo:Then, we just need to make spooling directories on
orchid:&prompt.root; mkdir -p /var/spool/lpd/rattan /var/spool/lpd/bamboo
&prompt.root; chmod 770 /var/spool/lpd/rattan /var/spool/lpd/bamboo
&prompt.root; chown daemon:daemon /var/spool/lpd/rattan /var/spool/lpd/bambooNow, users on orchid can print to
rattan and bamboo. If, for
example, a user on orchid typed
&prompt.user; lpr -P bamboo -d sushi-review.dvi
the LPD system on orchid
would copy the job to the spooling
directory /var/spool/lpd/bamboo and note that it was a
DVI job. As soon as the host rose has room in its
bamboo spooling directory, the two
LPDs would transfer the
file to rose. The file would wait in rose's
queue until it was finally printed. It would be converted from DVI to
&postscript; (since bamboo is a &postscript; printer) on
rose.Printers with Networked Data Stream InterfacesOften, when you buy a network interface card for a printer, you
can get two versions: one which emulates a spooler (the more
expensive version), or one which just lets you send data to it as if
you were using a serial or parallel port (the cheaper version).
This section tells how to use the cheaper version. For the more
expensive one, see the previous section Printers Installed on
Remote Hosts.The format of the /etc/printcap file lets
you specify what serial or parallel interface to use, and (if you
are using a serial interface), what baud rate, whether to use flow
control, delays for tabs, conversion of newlines, and more. But
there is no way to specify a connection to a printer that is
listening on a TCP/IP or other network port.To send data to a networked printer, you need to develop a
communications program that can be called by the text and conversion
filters. Here is one such example: the script
netprint takes all data on standard input and
sends it to a network-attached printer. We specify the hostname of
the printer as the first argument and the port number to which to
connect as the second argument to netprint. Note
that this supports one-way communication only (FreeBSD to printer);
many network printers support two-way communication, and you might
want to take advantage of that (to get printer status, perform
accounting, etc.).#!/usr/bin/perl
#
# netprint - Text filter for printer attached to network
# Installed in /usr/local/libexec/netprint
#
$#ARGV eq 1 || die "Usage: $0 <printer-hostname> <port-number>";
$printer_host = $ARGV[0];
$printer_port = $ARGV[1];
require 'sys/socket.ph';
($ignore, $ignore, $protocol) = getprotobyname('tcp');
($ignore, $ignore, $ignore, $ignore, $address)
= gethostbyname($printer_host);
$sockaddr = pack('S n a4 x8', &AF_INET, $printer_port, $address);
socket(PRINTER, &PF_INET, &SOCK_STREAM, $protocol)
|| die "Can't create TCP/IP stream socket: $!";
connect(PRINTER, $sockaddr) || die "Can't contact $printer_host: $!";
while (<STDIN>) { print PRINTER; }
exit 0;We can then use this script in various filters. Suppose we had
a Diablo 750-N line printer connected to the network. The printer
accepts data to print on port number 5100. The host name of the
printer is scrivener. Here is the text filter for the
printer:#!/bin/sh
#
# diablo-if-net - Text filter for Diablo printer `scrivener' listening
# on port 5100. Installed in /usr/local/libexec/diablo-if-net
#
exec /usr/libexec/lpr/lpf "$@" | /usr/local/libexec/netprint scrivener 5100Restricting Printer Usageprintersrestricting access toThis section gives information on restricting printer usage. The
LPD system lets you control who can access
a printer, both locally or
remotely, whether they can print multiple copies, how large their jobs
can be, and how large the printer queues can get.Restricting Multiple CopiesThe LPD system makes it easy for
users to print multiple copies
of a file. Users can print jobs with lpr -#5
(for example) and get five copies of each file in the job. Whether
this is a good thing is up to you.If you feel multiple copies cause unnecessary wear and tear on
your printers, you can disable the option to
&man.lpr.1; by adding the sc capability to the
/etc/printcap file. When users submit jobs
with the option, they will see:lpr: multiple copies are not allowedNote that if you have set up access to a printer remotely (see
section Printers
Installed on Remote Hosts), you need the
sc capability on the remote
/etc/printcap files as well, or else users will
still be able to submit multiple-copy jobs by using another
host.Here is an example. This is the
/etc/printcap file for the host
rose. The printer rattan is
quite hearty, so we will allow multiple copies, but the laser
printer bamboo is a bit more delicate, so we will
disable multiple copies by adding the sc
capability:#
# /etc/printcap for host rose - restrict multiple copies on bamboo
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
:sh:sd=/var/spool/lpd/rattan:\
:lp=/dev/lpt0:\
:if=/usr/local/libexec/if-simple:
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:sh:sd=/var/spool/lpd/bamboo:sc:\
:lp=/dev/ttyd5:ms#-parenb cs8 clocal crtscts:rw:\
:if=/usr/local/libexec/psif:\
:df=/usr/local/libexec/psdf:Now, we also need to add the sc capability on
the host orchid's
/etc/printcap (and while we are at it, let us
disable multiple copies for the printer
teak):#
# /etc/printcap for host orchid - no multiple copies for local
# printer teak or remote printer bamboo
teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\
:lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:sc:\
:if=/usr/local/libexec/ifhp:\
:vf=/usr/local/libexec/vfhp:\
:of=/usr/local/libexec/ofhp:
rattan|line|diablo|lp|Diablo 630 Line Printer:\
:lp=:rm=rose:rp=rattan:sd=/var/spool/lpd/rattan:
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:lp=:rm=rose:rp=bamboo:sd=/var/spool/lpd/bamboo:sc:By using the sc capability, we prevent the
use of lpr -#, but that still does not prevent
users from running &man.lpr.1;
multiple times, or from submitting the same file multiple times in
one job like this:&prompt.user; lpr forsale.sign forsale.sign forsale.sign forsale.sign forsale.signThere are many ways to prevent this abuse (including ignoring
it) which you are free to explore.Restricting Access to PrintersYou can control who can print to what printers by using the &unix;
group mechanism and the rg capability in
/etc/printcap. Just place the users you want
to have access to a printer in a certain group, and then name that
group in the rg capability.Users outside the group (including root)
will be greeted with
lpr: Not a member of the restricted group
if they try to print to the controlled printer.As with the sc (suppress multiple copies)
capability, you need to specify rg on remote
hosts that also have access to your printers, if you feel it is
appropriate (see section Printers Installed on
Remote Hosts).For example, we will let anyone access the printer
rattan, but only those in group
artists can use bamboo. Here
is the familiar /etc/printcap for host
rose:#
# /etc/printcap for host rose - restricted group for bamboo
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
:sh:sd=/var/spool/lpd/rattan:\
:lp=/dev/lpt0:\
:if=/usr/local/libexec/if-simple:
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:\
:lp=/dev/ttyd5:ms#-parenb cs8 clocal crtscts:rw:\
:if=/usr/local/libexec/psif:\
:df=/usr/local/libexec/psdf:Let us leave the other example
/etc/printcap file (for the host
orchid) alone. Of course, anyone on
orchid can print to bamboo. It
might be the case that we only allow certain logins on
orchid anyway, and want them to have access to the
printer. Or not.There can be only one restricted group per printer.Controlling Sizes of Jobs Submittedprint jobsIf you have many users accessing the printers, you probably need
to put an upper limit on the sizes of the files users can submit to
print. After all, there is only so much free space on the
filesystem that houses the spooling directories, and you also need
to make sure there is room for the jobs of other users.print jobscontrollingLPD enables you to limit the maximum
byte size a file in a job
can be with the mx capability. The units are in
BUFSIZ blocks, which are 1024 bytes. If you put
a zero for this
capability, there will be no limit on file size; however, if no
mx capability is specified, then a default limit
of 1000 blocks will be used.The limit applies to files in a job, and
not the total job size.LPD will not refuse a file that is
larger than the limit you
place on a printer. Instead, it will queue as much of the file up
to the limit, which will then get printed. The rest will be
discarded. Whether this is correct behavior is up for
debate.Let us add limits to our example printers
rattan and bamboo. Since
those artists' &postscript; files tend to be large, we will limit them
to five megabytes. We will put no limit on the plain text line
printer:#
# /etc/printcap for host rose
#
#
# No limit on job size:
#
rattan|line|diablo|lp|Diablo 630 Line Printer:\
:sh:mx#0:sd=/var/spool/lpd/rattan:\
:lp=/dev/lpt0:\
:if=/usr/local/libexec/if-simple:
#
# Limit of five megabytes:
#
bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:mx#5000:\
:lp=/dev/ttyd5:ms#-parenb cs8 clocal crtscts:rw:\
:if=/usr/local/libexec/psif:\
:df=/usr/local/libexec/psdf:Again, the limits apply to the local users only. If you have
set up access to your printers remotely, remote users will not get
those limits. You will need to specify the mx
capability in the remote /etc/printcap files as
well. See section Printers Installed on
Remote Hosts for more information on remote
printing.There is another specialized way to limit job sizes from remote
printers; see section Restricting Jobs
from Remote Printers.Restricting Jobs from Remote PrintersThe LPD spooling system provides
several ways to restrict print
jobs submitted from remote hosts:Host restrictionsYou can control from which remote hosts a local
LPD accepts requests with the files
/etc/hosts.equiv and
/etc/hosts.lpd.
LPD checks to see if an
incoming request is from a host listed in either one of these
files. If not, LPD refuses the
request.The format of these files is simple: one host name per
line. Note that the file
/etc/hosts.equiv is also used by the
&man.ruserok.3; protocol, and affects programs like
&man.rsh.1; and &man.rcp.1;, so be careful.For example, here is the
/etc/hosts.lpd file on the host
rose:orchid
violet
madrigal.fishbaum.deThis means rose will accept requests from
the hosts orchid, violet,
and madrigal.fishbaum.de. If any
other host tries to access rose's
LPD, the job will be refused.Size restrictionsYou can control how much free space there needs to remain
on the filesystem where a spooling directory resides. Make a
file called minfree in the spooling
directory for the local printer. Insert in that file a number
representing how many disk blocks (512 bytes) of free space
there has to be for a remote job to be accepted.This lets you insure that remote users will not fill your
filesystem. You can also use it to give a certain priority to
local users: they will be able to queue jobs long after the
free disk space has fallen below the amount specified in the
minfree file.For example, let us add a minfree
file for the printer bamboo. We examine
/etc/printcap to find the spooling
directory for this printer; here is bamboo's
entry:bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\
:sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:mx#5000:\
:lp=/dev/ttyd5:ms#-parenb cs8 clocal crtscts:rw:mx#5000:\
:if=/usr/local/libexec/psif:\
:df=/usr/local/libexec/psdf:The spooling directory is given in the sd
capability. We will make three megabytes (which is 6144 disk blocks)
the amount of free disk space that must exist on the filesystem for
LPD to accept remote jobs:&prompt.root; echo 6144 > /var/spool/lpd/bamboo/minfree
User restrictionsYou can control which remote users can print to local
printers by specifying the rs capability in
/etc/printcap. When
rs appears in the entry for a
locally-attached printer, LPD will
accept jobs from remote
hosts if the user submitting the job also
has an account of the same login name on the local host.
Otherwise, LPD refuses the job.This capability is particularly useful in an environment
where there are (for example) different departments sharing a
network, and some users transcend departmental boundaries. By
giving them accounts on your systems, they can use your
printers from their own departmental systems. If you would
rather allow them to use only your
printers and not your computer resources, you can give them
token accounts, with no home directory and a
useless shell like /usr/bin/false.Accounting for Printer UsageaccountingprinterSo, you need to charge for printouts. And why not? Paper and ink
cost money. And then there are maintenance costs—printers are
loaded with moving parts and tend to break down. You have examined
your printers, usage patterns, and maintenance fees and have come up
with a per-page (or per-foot, per-meter, or per-whatever) cost. Now,
how do you actually start accounting for printouts?Well, the bad news is the LPD spooling
system does not provide
much help in this department. Accounting is highly dependent on the
kind of printer in use, the formats being printed, and
your requirements in charging for printer
usage.To implement accounting, you have to modify a printer's text
filter (to charge for plain text jobs) and the conversion filters (to
charge for other file formats), to count pages or query the printer
for pages printed. You cannot get away with using the simple output
filter, since it cannot do accounting. See section Filters.Generally, there are two ways to do accounting:Periodic accounting is the more common
way, possibly because it is easier. Whenever someone prints a
job, the filter logs the user, host, and number of pages to an
accounting file. Every month, semester, year, or whatever time
period you prefer, you collect the accounting files for the
various printers, tally up the pages printed by users, and charge
for usage. Then you truncate all the logging files, starting with
a clean slate for the next period.Timely accounting is less common,
probably because it is more difficult. This method has the
filters charge users for printouts as soon as they use the
printers. Like disk quotas, the accounting is immediate. You can
prevent users from printing when their account goes in the red,
and might provide a way for users to check and adjust their
print quotas. But this method requires some database
code to track users and their quotas.The LPD spooling system supports both
methods easily: since you
have to provide the filters (well, most of the time), you also have to
provide the accounting code. But there is a bright side: you have
enormous flexibility in your accounting methods. For example, you
choose whether to use periodic or timely accounting. You choose what
information to log: user names, host names, job types, pages printed,
square footage of paper used, how long the job took to print, and so
forth. And you do so by modifying the filters to save this
information.Quick and Dirty Printer AccountingFreeBSD comes with two programs that can get you set up with
simple periodic accounting right away. They are the text filter
lpf, described in section lpf: a Text Filter, and
&man.pac.8;, a program to gather and total
entries from printer accounting files.As mentioned in the section on filters (Filters),
LPD starts
the text and the conversion filters with the name of the accounting
file to use on the filter command line. The filters can use this
argument to know where to write an accounting file entry. The name
of this file comes from the af capability in
/etc/printcap, and if not specified as an
absolute path, is relative to the spooling directory.LPD starts lpf
with page width and length
arguments (from the pw and pl
capabilities). lpf uses these arguments to
determine how much paper will be used. After sending the file to
the printer, it then writes an accounting entry in the accounting
file. The entries look like this:2.00 rose:andy
3.00 rose:kelly
3.00 orchid:mary
5.00 orchid:mary
2.00 orchid:zhangYou should use a separate accounting file for each printer, as
lpf has no file locking logic built into it, and
two lpfs might corrupt each other's entries if
they were to write to the same file at the same time. An easy way
to insure a separate accounting file for each printer is to use
af=acct in /etc/printcap.
Then, each accounting file will be in the spooling directory for a
printer, in a file named acct.When you are ready to charge users for printouts, run the
&man.pac.8; program. Just change to the spooling directory for
the printer you want to collect on and type pac.
You will get a dollar-centric summary like the following: Login pages/feet runs price
orchid:kelly 5.00 1 $ 0.10
orchid:mary 31.00 3 $ 0.62
orchid:zhang 9.00 1 $ 0.18
rose:andy 2.00 1 $ 0.04
rose:kelly 177.00 104 $ 3.54
rose:mary 87.00 32 $ 1.74
rose:root 26.00 12 $ 0.52
total 337.00 154 $ 6.74These are the arguments &man.pac.8; expects:Which printer to summarize.
This option works only if there is an absolute path in the
af capability in
/etc/printcap.Sort the output by cost instead of alphabetically by user
name.Ignore host name in the accounting files. With this
option, user smith on host
alpha is the same user
smith on host gamma.
Without, they are different users.Compute charges with price
dollars per page or per foot instead of the price from the
pc capability in
/etc/printcap, or two cents (the
default). You can specify price as
a floating point number.Reverse the sort order.Make an accounting summary file and truncate the
accounting file.name…Print accounting information for the given user
names only.In the default summary that &man.pac.8; produces, you see the
number of pages printed by each user from various hosts. If, at
your site, host does not matter (because users can use any host),
run pac -m, to produce the following
summary: Login pages/feet runs price
andy 2.00 1 $ 0.04
kelly 182.00 105 $ 3.64
mary 118.00 35 $ 2.36
root 26.00 12 $ 0.52
zhang 9.00 1 $ 0.18
total 337.00 154 $ 6.74To compute the dollar amount due,
&man.pac.8; uses the pc capability in the
/etc/printcap file (default of 200, or 2 cents
per page). Specify, in hundredths of cents, the price per page or
per foot you want to charge for printouts in this capability. You
can override this value when you run &man.pac.8; with the
option. The units for the
option are in dollars, though, not hundredths of cents. For
example,
&prompt.root; pac -p1.50
makes each page cost one dollar and fifty cents. You can really
rake in the profits by using this option.Finally, running pac -s will save the summary
information in a summary accounting file, which is named the same as
the printer's accounting file, but with _sum
appended to the name. It then truncates the accounting file. When
you run &man.pac.8; again, it rereads the
summary file to get starting totals, then adds information from the
regular accounting file.How Can You Count Pages Printed?In order to perform even remotely accurate accounting, you need
to be able to determine how much paper a job uses. This is the
essential problem of printer accounting.For plain text jobs, the problem is not that hard to solve: you
count how many lines are in a job and compare it to how many lines
per page your printer supports. Do not forget to take into account
backspaces in the file which overprint lines, or long logical lines
that wrap onto one or more additional physical lines.The text filter lpf (introduced in lpf: a Text Filter) takes
into account these things when it does accounting. If you are
writing a text filter which needs to do accounting, you might want
to examine lpf's source code.How do you handle other file formats, though?Well, for DVI-to-LaserJet or DVI-to-&postscript; conversion, you
can have your filter parse the diagnostic output of
dvilj or dvips and look to see
how many pages were converted. You might be able to do similar
things with other file formats and conversion programs.But these methods suffer from the fact that the printer may not
actually print all those pages. For example, it could jam, run out
of toner, or explode—and the user would still get
charged.So, what can you do?There is only one sure way to do
accurate accounting. Get a printer that can
tell you how much paper it uses, and attach it via a serial line or
a network connection. Nearly all &postscript; printers support this
notion. Other makes and models do as well (networked Imagen laser
printers, for example). Modify the filters for these printers to
get the page usage after they print each job and have them log
accounting information based on that value
only. There is no line counting nor
error-prone file examination required.Of course, you can always be generous and make all printouts
free.Using PrintersprintersusageThis section tells you how to use printers you have set up with
FreeBSD. Here is an overview of the user-level commands:&man.lpr.1;Print jobs&man.lpq.1;Check printer queues&man.lprm.1;Remove jobs from a printer's queueThere is also an administrative command, &man.lpc.8;,
described in the section Administering Printers, used to
control printers and their queues.All three of the commands &man.lpr.1;, &man.lprm.1;, and &man.lpq.1;
accept an option to specify on which
printer/queue to operate, as listed in the
/etc/printcap file. This enables you to submit,
remove, and check on jobs for various printers. If you do not use the
option, then these commands use the printer
specified in the PRINTER environment variable. Finally,
if you do not have a PRINTER environment variable, these
commands default to the printer named lp.Hereafter, the terminology default printer
means the printer named in the PRINTER environment
variable, or the printer named lp when there is no
PRINTER environment variable.Printing JobsTo print files, type:&prompt.user; lpr filename...printingThis prints each of the listed files to the default printer. If
you list no files, &man.lpr.1; reads data to
print from standard input. For example, this command prints some
important system files:&prompt.user; lpr /etc/host.conf /etc/hosts.equivTo select a specific printer, type:&prompt.user; lpr -P printer-namefilename...This example prints a long listing of the current directory to the
printer named rattan:&prompt.user; ls -l | lpr -P rattanBecause no files were listed for the
&man.lpr.1; command, lpr read the data to print
from standard input, which was the output of the ls
-l command.The &man.lpr.1; command can also accept a wide variety of options
to control formatting, apply file conversions, generate multiple
copies, and so forth. For more information, see the section Printing Options.Checking Jobsprint jobsWhen you print with &man.lpr.1;, the data you wish to print is put
together in a package called a print job, which is sent
to the LPD spooling system. Each printer
has a queue of jobs, and
your job waits in that queue along with other jobs from yourself and
from other users. The printer prints those jobs in a first-come,
first-served order.To display the queue for the default printer, type &man.lpq.1;.
For a specific printer, use the option. For
example, the command
&prompt.user; lpq -P bamboo
shows the queue for the printer named bamboo. Here
is an example of the output of the lpq
command:bamboo is ready and printing
Rank Owner Job Files Total Size
active kelly 9 /etc/host.conf, /etc/hosts.equiv 88 bytes
2nd kelly 10 (standard input) 1635 bytes
3rd mary 11 ... 78519 bytesThis shows three jobs in the queue for bamboo.
The first job, submitted by user kelly, got assigned job
number 9. Every job for a printer gets a unique job number.
Most of the time you can ignore the job number, but you will need it
if you want to cancel the job; see section Removing Jobs for details.Job number nine consists of two files; multiple files given on the
&man.lpr.1; command line are treated as part of a single job. It
is the currently active job (note the word active
under the Rank column), which means the printer should
be currently printing that job. The second job consists of data
passed as the standard input to the &man.lpr.1; command. The third
job came from user mary; it is a much larger
job. The pathname of the file she is trying to print is too long to
fit, so the &man.lpq.1; command just shows three dots.The very first line of the output from &man.lpq.1; is also useful:
it tells what the printer is currently doing (or at least what
LPD thinks the printer is doing).The &man.lpq.1; command also support a option
to generate a detailed long listing. Here is an example of
lpq -l:waiting for bamboo to become ready (offline ?)
kelly: 1st [job 009rose]
/etc/host.conf 73 bytes
/etc/hosts.equiv 15 bytes
kelly: 2nd [job 010rose]
(standard input) 1635 bytes
mary: 3rd [job 011rose]
/home/orchid/mary/research/venus/alpha-regio/mapping 78519 bytesRemoving JobsIf you change your mind about printing a job, you can remove the
job from the queue with the &man.lprm.1; command. Often, you can
even use &man.lprm.1; to remove an active job, but some or all of the
job might still get printed.To remove a job from the default printer, first use
&man.lpq.1; to find the job number. Then type:&prompt.user; lprm job-numberTo remove the job from a specific printer, add the
option. The following command removes job number
10 from the queue for the printer bamboo:&prompt.user; lprm -P bamboo 10The &man.lprm.1; command has a few shortcuts:lprm -Removes all jobs (for the default printer) belonging to
you.lprm userRemoves all jobs (for the default printer) belonging to
user. The superuser can remove other
users' jobs; you can remove only your own jobs.lprmWith no job number, user name, or
appearing on the command line,
&man.lprm.1; removes the currently active job on the
default printer, if it belongs to you. The superuser can remove
any active job.Just use the option with the above shortcuts
to operate on a specific printer instead of the default. For example,
the following command removes all jobs for the current user in the
queue for the printer named rattan:&prompt.user; lprm -P rattan -If you are working in a networked environment, &man.lprm.1; will
let you remove jobs only from the
host from which the jobs were submitted, even if the same printer is
available from other hosts. The following command sequence
demonstrates this:&prompt.user; lpr -P rattan myfile
&prompt.user; rlogin orchid
&prompt.user; lpq -P rattan
Rank Owner Job Files Total Size
active seeyan 12 ... 49123 bytes
2nd kelly 13 myfile 12 bytes
&prompt.user; lprm -P rattan 13
rose: Permission denied
&prompt.user; logout
&prompt.user; lprm -P rattan 13
dfA013rose dequeued
cfA013rose dequeued
Beyond Plain Text: Printing OptionsThe &man.lpr.1; command supports a number of options that control
formatting text, converting graphic and other file formats, producing
multiple copies, handling of the job, and more. This section
describes the options.Formatting and Conversion OptionsThe following &man.lpr.1; options control formatting of the
files in the job. Use these options if the job does not contain
plain text or if you want plain text formatted through the
&man.pr.1; utility.&tex;For example, the following command prints a DVI file (from the
&tex; typesetting system) named fish-report.dvi
to the printer named bamboo:&prompt.user; lpr -P bamboo -d fish-report.dviThese options apply to every file in the job, so you cannot mix
(say) DVI and ditroff files together in a job. Instead, submit the
files as separate jobs, using a different conversion option for each
job.All of these options except and
require conversion filters installed for the
destination printer. For example, the option
requires the DVI conversion filter. Section Conversion
Filters gives details.Print cifplot files.Print DVI files.Print FORTRAN text files.Print plot data.Indent the output by number
columns; if you omit number, indent
by 8 columns. This option works only with certain conversion
filters.Do not put any space between the and
the number.Print literal text data, including control
characters.Print ditroff (device independent troff) data.-pFormat plain text with &man.pr.1; before printing. See
&man.pr.1; for more information.Use title on the
&man.pr.1; header instead of the file name. This option has
effect only when used with the
option.Print troff data.Print raster data.Here is an example: this command prints a nicely formatted
version of the &man.ls.1; manual page on the default printer:&prompt.user; zcat /usr/share/man/man1/ls.1.gz | troff -t -man | lpr -tThe &man.zcat.1; command uncompresses the source of the
&man.ls.1; manual page and passes it to the &man.troff.1;
command, which formats that source and makes GNU troff
output and passes it to &man.lpr.1;, which submits the job
to the LPD spooler. Because we
used the
option to &man.lpr.1;, the spooler will convert the GNU
troff output into a format the default printer can
understand when it prints the job.Job Handling OptionsThe following options to &man.lpr.1; tell
LPD to handle the job
specially:-# copiesProduce a number of copies of
each file in the job instead of just one copy. An
administrator may disable this option to reduce printer
wear-and-tear and encourage photocopier usage. See section
Restricting
Multiple Copies.This example prints three copies of
parser.c followed by three copies of
parser.h to the default printer:&prompt.user; lpr -#3 parser.c parser.h-mSend mail after completing the print job. With this
option, the LPD system will send
mail to your account when it
finishes handling your job. In its message, it will tell you
if the job completed successfully or if there was an error,
and (often) what the error was.-sDo not copy the files to the spooling directory, but make
symbolic links to them instead.If you are printing a large job, you probably want to use
this option. It saves space in the spooling directory (your
job might overflow the free space on the filesystem where the
spooling directory resides). It saves time as well since
LPD
will not have to copy each and every byte of your job to the
spooling directory.There is a drawback, though: since
LPD will refer to the
original files directly, you cannot modify or remove them
until they have been printed.If you are printing to a remote printer,
LPD will
eventually have to copy files from the local host to the
remote host, so the option will save
space only on the local spooling directory, not the remote.
It is still useful, though.-rRemove the files in the job after copying them to the
spooling directory, or after printing them with the
option. Be careful with this
option!Header Page OptionsThese options to &man.lpr.1; adjust the text that normally
appears on a job's header page. If header pages are suppressed for
the destination printer, these options have no effect. See section
Header Pages
for information about setting up header pages.-C textReplace the hostname on the header page with
text. The hostname is normally the
name of the host from which the job was submitted.-J textReplace the job name on the header page with
text. The job name is normally the
name of the first file of the job, or
stdin if you are printing standard
input.-hDo not print any header page.At some sites, this option may have no effect due to the
way header pages are generated. See Header
Pages for details.Administering PrintersAs an administrator for your printers, you have had to install,
set up, and test them. Using the &man.lpc.8; command, you
can interact with your printers in yet more ways. With &man.lpc.8;,
you canStart and stop the printersEnable and disable their queuesRearrange the order of the jobs in each queue.First, a note about terminology: if a printer is
stopped, it will not print anything in its queue.
Users can still submit jobs, which will wait in the queue until the
printer is started or the queue is
cleared.If a queue is disabled, no user (except
root) can submit jobs for the printer. An
enabled queue allows jobs to be submitted. A
printer can be started for a disabled queue, in
which case it will continue to print jobs in the queue until the queue
is empty.In general, you have to have root privileges
to use the &man.lpc.8; command. Ordinary users can use the &man.lpc.8;
command to get printer status and to restart a hung printer only.Here is a summary of the &man.lpc.8; commands. Most of the
commands take a printer-name argument to
tell on which printer to operate. You can use all
for the printer-name to mean all printers
listed in /etc/printcap.abort
printer-nameCancel the current job and stop the printer. Users can
still submit jobs if the queue is enabled.clean
printer-nameRemove old files from the printer's spooling directory.
Occasionally, the files that make up a job are not properly
removed by LPD, particularly if
there have been errors during
printing or a lot of administrative activity. This command
finds files that do not belong in the spooling directory and
removes them.disable
printer-nameDisable queuing of new jobs. If the printer is running, it
will continue to print any jobs remaining in the queue. The
superuser (root) can always submit jobs,
even to a disabled queue.This command is useful while you are testing a new printer
or filter installation: disable the queue and submit jobs as
root. Other users will not be able to submit
jobs until you complete your testing and re-enable the queue with
the enable command.down printer-namemessageTake a printer down. Equivalent to
disable followed by stop.
The message appears as the printer's
status whenever a user checks the printer's queue with
&man.lpq.1; or status with lpc
status.enable
printer-nameEnable the queue for a printer. Users can submit jobs but
the printer will not print anything until it is started.help
command-namePrint help on the command
command-name. With no
command-name, print a summary of the
commands available.restart
printer-nameStart the printer. Ordinary users can use this command if
some extraordinary circumstance hangs
LPD, but they cannot start
a printer stopped with either the stop or
down commands. The
restart command is equivalent to
abort followed by
start.start
printer-nameStart the printer. The printer will print jobs in its
queue.stop
printer-nameStop the printer. The printer will finish the current job
and will not print anything else in its queue. Even though the
printer is stopped, users can still submit jobs to an enabled
queue.topq printer-namejob-or-usernameRearrange the queue for
printer-name by placing the jobs with
the listed job numbers or the jobs
belonging to username at the top of
the queue. For this command, you cannot use
all as the
printer-name.up
printer-nameBring a printer up; the opposite of the
down command. Equivalent to
start followed by
enable.&man.lpc.8; accepts the above commands on the command line. If
you do not enter any commands, &man.lpc.8; enters an interactive mode,
where you can enter commands until you type exit,
quit, or end-of-file.Alternatives to the Standard SpoolerIf you have been reading straight through this manual, by now you
have learned just about everything there is to know about the
LPD
spooling system that comes with FreeBSD. You can probably appreciate
many of its shortcomings, which naturally leads to the question:
What other spooling systems are out there (and work with
FreeBSD)?LPRngLPRngLPRng, which purportedly means
LPR: the Next
Generation is a complete rewrite of PLP. Patrick Powell
and Justin Mason (the principal maintainer of PLP) collaborated to
make LPRng. The main site for
LPRng is .CUPSCUPSCUPS, the Common UNIX Printing
System, provides a portable printing layer for &unix;-based
operating systems. It has been developed by Easy Software
Products to promote a standard printing solution for all &unix;
vendors and users.CUPS uses the Internet Printing
Protocol (IPP) as the basis for managing
print jobs and queues. The Line Printer Daemon
(LPD), Server Message Block
(SMB), and AppSocket (a.k.a. JetDirect)
protocols are also supported with reduced functionality. CUPS
adds network printer browsing and PostScript Printer Description
(PPD) based printing options to support
real-world printing under &unix;.The main site for CUPS is .TroubleshootingAfter performing the simple test with &man.lptest.1;, you might
have gotten one of the following results instead of the correct
printout:It worked, after awhile; or, it did not eject a full
sheet.The printer printed the above, but it sat for awhile and
did nothing. In fact, you might have needed to press a
PRINT REMAINING or FORM FEED button on the printer to get any
results to appear.If this is the case, the printer was probably waiting to
see if there was any more data for your job before it printed
anything. To fix this problem, you can have the text filter
send a FORM FEED character (or whatever is necessary) to the
printer. This is usually sufficient to have the printer
immediately print any text remaining in its internal buffer.
It is also useful to make sure each print job ends on a full
sheet, so the next job does not start somewhere on the middle
of the last page of the previous job.The following replacement for the shell script
/usr/local/libexec/if-simple prints a
form feed after it sends the job to the printer:#!/bin/sh
#
# if-simple - Simple text input filter for lpd
# Installed in /usr/local/libexec/if-simple
#
# Simply copies stdin to stdout. Ignores all filter arguments.
# Writes a form feed character (\f) after printing job.
/bin/cat && printf "\f" && exit 0
exit 2It produced the staircase effect.You got the following on paper:!"#$%&'()*+,-./01234
"#$%&'()*+,-./012345
#$%&'()*+,-./0123456MS-DOSOS/2ASCIIYou have become another victim of the staircase
effect, caused by conflicting interpretations of
what characters should indicate a new line. &unix; style
operating systems use a single character: ASCII code 10, the
line feed (LF). &ms-dos;, &os2;, and others uses a pair of
characters, ASCII code 10 and ASCII code
13 (the carriage return or CR). Many printers use the &ms-dos;
convention for representing new-lines.When you print with FreeBSD, your text used just the line
feed character. The printer, upon seeing a line feed
character, advanced the paper one line, but maintained the
same horizontal position on the page for the next character
to print. That is what the carriage return is for: to move
the location of the next character to print to the left edge
of the paper.Here is what FreeBSD wants your printer to do:Printer received CRPrinter prints CRPrinter received LFPrinter prints CR + LFHere are some ways to achieve this:Use the printer's configuration switches or control
panel to alter its interpretation of these characters.
Check your printer's manual to find out how to do
this.If you boot your system into other operating systems
besides FreeBSD, you may have to
reconfigure the printer to use a an
interpretation for CR and LF characters that those other
operating systems use. You might prefer one of the other
solutions, below.Have FreeBSD's serial line driver automatically
convert LF to CR+LF. Of course, this works with printers
on serial ports only. To enable this
feature, use the ms# capability and
set the onlcr mode
in the /etc/printcap file
for the printer.Send an escape code to the
printer to have it temporarily treat LF characters
differently. Consult your printer's manual for escape
codes that your printer might support. When you find the
proper escape code, modify the text filter to send the
code first, then send the print job.PCLHere is an example text filter for printers that
understand the Hewlett-Packard PCL escape codes. This
filter makes the printer treat LF characters as a LF and
CR; then it sends the job; then it sends a form feed to
eject the last page of the job. It should work with
nearly all Hewlett Packard printers.#!/bin/sh
#
# hpif - Simple text input filter for lpd for HP-PCL based printers
# Installed in /usr/local/libexec/hpif
#
# Simply copies stdin to stdout. Ignores all filter arguments.
# Tells printer to treat LF as CR+LF. Ejects the page when done.
printf "\033&k2G" && cat && printf "\033&l0H" && exit 0
exit 2Here is an example /etc/printcap
from a host called orchid. It has a single printer
attached to its first parallel port, a Hewlett Packard
LaserJet 3Si named teak. It is using the
above script as its text filter:#
# /etc/printcap for host orchid
#
teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\
:lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\
:if=/usr/local/libexec/hpif:It overprinted each line.The printer never advanced a line. All of the lines of
text were printed on top of each other on one line.This problem is the opposite of the
staircase effect, described above, and is much rarer.
Somewhere, the LF characters that FreeBSD uses to end a line
are being treated as CR characters to return the print
location to the left edge of the paper, but not also down a
line.Use the printer's configuration switches or control panel
to enforce the following interpretation of LF and CR
characters:Printer receivesPrinter printsCRCRLFCR + LFThe printer lost characters.While printing, the printer did not print a few characters
in each line. The problem might have gotten worse as the
printer ran, losing more and more characters.The problem is that the printer cannot keep up with the
speed at which the computer sends data over a serial line
(this problem should not occur with printers on parallel
ports). There are two ways to overcome the problem:If the printer supports XON/XOFF flow control, have
FreeBSD use it by specifying the ixon mode
in the ms# capability.If the printer supports carrier flow control, specify
the crtscts mode in the
ms# capability.
Make sure the cable connecting the printer to the computer
is correctly wired for carrier flow control.It printed garbage.The printer printed what appeared to be random garbage,
but not the desired text.This is usually another symptom of incorrect
communications parameters with a serial printer. Double-check
the bps rate in the br capability, and the
parity setting in the
ms# capability; make sure the printer is
using the same settings as specified in the
/etc/printcap file.Nothing happened.If nothing happened, the problem is probably within
FreeBSD and not the hardware. Add the log file
(lf) capability to the entry for the
printer you are debugging in the
/etc/printcap file. For example, here is
the entry for rattan, with the
lf capability:rattan|line|diablo|lp|Diablo 630 Line Printer:\
:sh:sd=/var/spool/lpd/rattan:\
:lp=/dev/lpt0:\
:if=/usr/local/libexec/if-simple:\
:lf=/var/log/rattan.logThen, try printing again. Check the log file (in our
example, /var/log/rattan.log) to see any
error messages that might appear. Based on the messages you
see, try to correct the problem.If you do not specify a lf capability,
LPD uses
/dev/console as a default.
diff --git a/zh_TW.Big5/books/handbook/users/chapter.sgml b/zh_TW.Big5/books/handbook/users/chapter.sgml
index 216229dc9e..59efb0be88 100644
--- a/zh_TW.Big5/books/handbook/users/chapter.sgml
+++ b/zh_TW.Big5/books/handbook/users/chapter.sgml
@@ -1,1112 +1,960 @@
NeilBlakey-MilnerContributed by 使用者與基本帳號管理概述
- FreeBSD 允許多個使用者同時使用電腦。當然,這並不是很多人同時坐在同一台電腦前
+ FreeBSD 允許多個使用者同時使用電腦。 當然,
+ 這並不是很多人同時坐在同一台電腦前
Well..除非您連接 multiple terminals,這種情況我們會在 講到。,而是其他使用者可以透過網路來使用同一台電腦以完成他們的工作。
要使用系統的話,那麼每個人都得有一個帳號。讀完這章,您將了解:在 FreeBSD 系統上不同帳號之間的區別。如何增加帳號。如何刪除帳號。
- 如何更改帳號的基本資料,像是帳號全名,或是使用的 shell 種類。
+ 如何更改帳號的基本資料,像是帳號全名,或是使用的 shell
+ 種類。
- 如何針對帳號、群組來設限,比如:允許存取記憶體或 CPU 資源多寡等。
+ 如何針對帳號、群組來設限,比如:允許存取記憶體或 CPU
+ 資源多寡等。如何運用群組,來更容易地管理帳號。
- 在閱讀這章之前,您應當了解:
+ 在開始閱讀這章之前,您需要:
- 瞭解 &unix; 及 FreeBSD (瞭解 &unix; 及 FreeBSD ()的基礎概念。介紹
- 系統的所有存取是經由帳號來進行,而所有的程式 process 是由使用者來進行,所以
- 使用者及帳號管理,乃是 FreeBSD 系統上不可或缺的重點。
+ 系統的所有存取是經由帳號來進行,而所有的程式 process
+ 是由使用者來進行,所以使用者及帳號的管理,乃是 FreeBSD
+ 系統上不可或缺的重點。
- Every account on a FreeBSD system has certain information associated
- with it to identify the account.
+ 所有於 FreeBSD 系統中的帳號皆包含下列相關資訊用來辨識身份。
- User name
+ 使用者名稱
- The user name as it would be typed at the
- login: prompt. User names must be unique across
- the computer; you may not have two users with the same
- user name. There are a number of rules for creating valid user
- names, documented in &man.passwd.5;; you would typically use user
- names that consist of eight or fewer all lower case
- characters.
+ 使用者名稱要輸入在 login: 提示出現後。
+ 使用者名稱必須是獨一無二,
+ 不能有重複的使用者名稱。
+ 至於如何建立有效使用者名稱的規則,請參閱 &man.passwd.5; 說明,
+ 通常使用者名稱是以八個以內的小寫字母所組成。
- Password
+ 密碼
- Each account has a password associated with it. The password
- may be blank, in which case no password will be required to access
- the system. This is normally a very bad idea; every account
- should have a password.
+ 每個帳號都可擁有一組密碼。 密碼也可以不設,
+ 如此就不需密碼即可登入系統,但通常這並非妙策,
+ 每個帳號都應設定一組密碼。
- User ID (UID)
+ 使用者代號 (User ID, UID)
- The UID is a number, traditionally from 0 to 65535
- It is possible to use UID/GIDs as large as
- 4294967295, but such IDs can cause serious problems
- with software that makes assumptions about the values
- of IDs.
- , used to uniquely identify
- the user to the system. Internally, FreeBSD uses the UID to
- identify users—any FreeBSD commands that allow you to
- specify a user name will convert it to the UID before working with
- it. This means that you can have several accounts with different
- user names but the same UID. As far as FreeBSD is concerned these
- accounts are one user. It is unlikely you will ever need to do
- this.
+ UID 是系統用來辨識使用者的數字,通常範圍是從 0 到 65535
+ UID/GID 最大可使用至 4294967295,但這樣的 ID
+ 可能會對已假設範圍的軟體造成嚴重問題。
+ 。 FreeBSD 內部是使用 UID 來辨識使用者 —
+ FreeBSD 在執行任何指定使用者的指令之前,都會先把使用者名稱轉換為
+ UID。 也就是說,比如可以有數個不同的使用者名稱,
+ 但是都使用同一個 UID,對 FreeBSD 來說,這些帳號都只代表同一使用者。
+ 不過,實際上需要這樣做的可能性不大。
- Group ID (GID)
+ 群組代號 (Group ID, GID)
- The GID is a number, traditionally from 0 to 65535, used to uniquely identify
- the primary group that the user belongs to. Groups are a
- mechanism for controlling access to resources based on a user's
- GID rather than their UID. This can significantly reduce the size
- of some configuration files. A user may also be in more than one
- group.
+ GID 是系統用來辨識使用者所屬群組的數字,通常範圍是從 0 到 65535
+ 。 用群組來控制資源存取,可有效減少一些設定檔的大小。
+ 此外,使用者還可以同時屬於多個不同的群組。
- Login class
+ 登入分類(Login classes)
- Login classes are an extension to the group mechanism that
- provide additional flexibility when tailoring the system to
- different users.
+
+ 登入分類是群組的延伸機制,
+ 提供了不同的使用者更彈性的。
- Password change time
+ 密碼變更期限
- By default FreeBSD does not force users to change their
- passwords periodically. You can enforce this on a per-user basis,
- forcing some or all of your users to change their passwords after
- a certain amount of time has elapsed.
+ FreeBSD 預設並不要求使用者週期性的更改密碼。您可以強制某些或
+ 全部的使用者在指定的期間過後必須更改密碼。
- Account expiry time
+ 帳號期限
+
- By default FreeBSD does not expire accounts. If you are
- creating accounts that you know have a limited lifespan, for
- example, in a school where you have accounts for the students,
- then you can specify when the account expires. After the expiry
- time has elapsed the account cannot be used to log in to the
- system, although the account's directories and files will
- remain.
+ FreeBSD 的帳號沒有預設的期限,如果您已知道帳號的使用期限,
+ 例如,學校中提供學生使用的帳號,可在建立帳號時指定帳號的期限。
+ 當帳號過期後會無法登入系統,但該帳號的目錄及檔案則會保留。
- User's full name
+ 使用者全名
- The user name uniquely identifies the account to FreeBSD, but
- does not necessarily reflect the user's real name. This
- information can be associated with the account.
+ FreeBSD 的帳號使用使用者名稱用來辨識,但使用者名稱並不一定代表
+ 真實使用者的姓名。為帳號所需的相關資訊。
- Home directory
+ 家目錄
- The home directory is the full path to a directory on the
- system in which the user will start when logging on to the
- system. A common convention is to put all user home directories
- under
- /home/username
- or /usr/home/username.
- The user would store their personal files in their home directory,
- and any directories they may create in there.
+ 家目錄為使用者登入系統時的所在目錄的完整路徑。
+ 通常會將所有使用者的家目錄放置於
+ /home/使用者名稱
+ 或 /usr/home/使用者名稱。
+ 使用者可以將其個人的資料放置於其家目錄之中,並可以在此目錄底下
+ 建立新的目錄
- User shell
+ 使用者 Shell
- The shell provides the default environment users use to
- interact with the system. There are many different kinds of
- shells, and experienced users will have their own preferences,
- which can be reflected in their account settings.
+ Shell 提供預設的環境讓使用者與系統互動。
+ Shell 擁有數種不同的種類, 可供進階使用者依使用習慣選擇。
-
- There are three main types of accounts: the Superuser, system users, and user accounts. The Superuser
- account, usually called root, is used to
- manage the system with no limitations on privileges. System
- users run services. Finally, user accounts are used by real
- people, who log on, read mail, and so forth.
+
+ 帳號主要分為下列三類: 系統管理者帳號, 系統帳號,及 使用者帳號。 系統管理者帳號的帳號
+ 通常為 root,擁有最大的權限來管理系統。
+ 系統帳號用來執行伺服器服務。最後,使用者帳號供真正的使用者使用,
+ 可登入、讀信等等。
- The Superuser Account
+ 系統管理者帳號accountssuperuser (root)The superuser account, usually called
root, comes preconfigured to facilitate
system administration, and should not be used for day-to-day
tasks like sending and receiving mail, general exploration of
the system, or programming.This is because the superuser, unlike normal user accounts,
can operate without limits, and misuse of the superuser account
may result in spectacular disasters. User accounts are unable
to destroy the system by mistake, so it is generally best to use
normal user accounts whenever possible, unless you especially
need the extra privilege.You should always double and triple-check commands you issue
as the superuser, since an extra space or missing character can
mean irreparable data loss.So, the first thing you should do after reading this
chapter is to create an unprivileged user account for yourself
for general usage if you have not already. This applies equally
whether you are running a multi-user or single-user machine.
Later in this chapter, we discuss how to create additional
accounts, and how to change between the normal user and
superuser.
- System Accounts
+ 系統帳號accountssystemSystem users are those used to run services such as DNS,
mail, web servers, and so forth. The reason for this is
security; if all services ran as the superuser, they could
act without restriction.accountsdaemonaccountsoperatorExamples of system users are daemon,
operator, bind (for
the Domain Name Service), news, and
www.accountsnobodynobody is the generic unprivileged
system user. However, it is important to keep in mind that the
more services that use nobody, the more
files and processes that user will become associated with, and
hence the more privileged that user becomes.
- User Accounts
+ 使用者帳號accountsuserUser accounts are the primary means of access for real
people to the system, and these accounts insulate the user and
the environment, preventing the users from damaging the system
or other users, and allowing users to customize their
environment without affecting others.Every person accessing your system should have a unique user
account. This allows you to find out who is doing what, prevent
people from clobbering each others' settings or reading each
others' mail, and so forth.Each user can set up their own environment to accommodate
their use of the system, by using alternate shells, editors, key
bindings, and language.
- Modifying Accounts
+ 更改帳號accountsmodifying
- There are a variety of different commands available in the
- &unix; environment to manipulate user accounts. The most common
- commands are summarized below, followed by more detailed
- examples of their usage.
+ 在 &unix; 的環境之中提供了各式不同的指令管理使用者帳號,
+ 以下為較常使用的指令摘要及更詳細的使用範例。
+
- Command
- Summary
+ 指令
+ 摘要&man.adduser.8;
- The recommended command-line application for adding
- new users.
+ 新增使用者。&man.rmuser.8;
- The recommended command-line application for
- removing users.
+ 移除使用者。&man.chpass.1;
- A flexible tool to change user database information.
+ 更改使用者資料。&man.passwd.1;
- The simple command-line tool to change user
- passwords.
+ 更改使用者密碼。&man.pw.8;
- A powerful and flexible tool to modify all aspects
- of user accounts.
+ 修改使用者的各種資料。adduseraccountsaddingadduser/usr/share/skelskeleton directory
- &man.adduser.8; is a simple program for
- adding new users. It creates entries in the system
- passwd and group
- files. It will also create a home directory for the new user,
- copy in the default configuration files (dotfiles) from
- /usr/share/skel, and can optionally mail
- the new user a welcome message.
-
- In &os; 5.0, &man.adduser.8; was rewritten from a
- Perl script to a shell script that acts as wrapper around
- &man.pw.8;, so its usage is slightly different on &os; 4.X
- and &os; 5.X.
-
- To create the initial configuration file, use
- adduser -s -config_create.
-
- The makes &man.adduser.8;
- default to
- quiet. We use later when we want to
- change defaults.
-
- Next, we configure &man.adduser.8;
- defaults, and create our first user account, since using
- root for normal usage is evil and
- nasty.
+ &man.adduser.8; 是一支新增使用者的簡單程式。
+ 它會建立資料於系統的 passwd 與
+ group
+ 檔案之中。 同時也會建立使用者的家目錄,從
+ /usr/share/skel 複製預設的組態檔(dotfiles),
+ 並可以選擇性的郵件通知新使用者歡迎訊息。
- Configuring adduser and adding a
- user on &os; 4.X
-
- &prompt.root; adduser -v
-Use option ``-silent'' if you don't want to see all warnings and questions.
-Check /etc/shells
-Check /etc/master.passwd
-Check /etc/group
-Enter your default shell: csh date no sh tcsh zsh [sh]: zsh
-Your default shell is: zsh -> /usr/local/bin/zsh
-Enter your default HOME partition: [/home]:
-Copy dotfiles from: /usr/share/skel no [/usr/share/skel]:
-Send message from file: /etc/adduser.message no
-[/etc/adduser.message]: no
-Do not send message
-Use passwords (y/n) [y]: y
-
-Write your changes to /etc/adduser.conf? (y/n) [n]: y
-
-Ok, let's go.
-Don't worry about mistakes. I will give you the chance later to correct any input.
-Enter username [a-z0-9_-]: jru
-Enter full name []: J. Random User
-Enter shell csh date no sh tcsh zsh [zsh]:
-Enter home directory (full path) [/home/jru]:
-Uid [1001]:
-Enter login class: default []:
-Login group jru [jru]:
-Login group is ``jru''. Invite jru into other groups: guest no
-[no]: wheel
-Enter password []:
-Enter password again []:
-
-Name: jru
-Password: ****
-Fullname: J. Random User
-Uid: 1001
-Gid: 1001 (jru)
-Class:
-Groups: jru wheel
-HOME: /home/jru
-Shell: /usr/local/bin/zsh
-OK? (y/n) [y]: y
-Added user ``jru''
-Copy files from /usr/share/skel to /home/jru
-Add another user? (y/n) [y]: n
-Goodbye!
-&prompt.root;
-
-
- In summary, we changed the default shell to
- zsh (an additional shell found in
- the Ports Collection), and turned off the sending of a welcome mail to
- added users. We then saved the configuration,
- created an account for jru, and made
- sure jru is in wheel
- group (so that she may assume the role of
- root with the &man.su.1;
- command.)
-
-
- The password you type in is not echoed, nor are asterisks
- displayed. Make sure that you do not mistype the password.
-
-
-
-
- Just use &man.adduser.8; without arguments
- from now on, and you will not have to go through changing the
- defaults. If the program asks you to change the defaults,
- exit the program, and try the
- option.
-
-
-
- Adding a user on &os; 5.X
+ 在 &os; 內新增使用者&prompt.root; adduser
Username: jru
Full name: J. Random User
Uid (Leave empty for default):
Login group [jru]:
Login group is jru. Invite jru into other groups? []: wheel
Login class [default]:
Shell (sh csh tcsh zsh nologin) [sh]: zsh
Home directory [/home/jru]:
Use password-based authentication? [yes]:
Use an empty password? (yes/no) [no]:
Use a random password? (yes/no) [no]:
Enter password:
Enter password again:
Lock out the account after creation? [no]:
Username : jru
Password : ****
Full Name : J. Random User
Uid : 1001
Class :
Groups : jru wheel
Home : /home/jru
Shell : /usr/local/bin/zsh
Locked : no
OK? (yes/no): yes
adduser: INFO: Successfully added (jru) to the user database.
Add another user? (yes/no): no
Goodbye!
&prompt.root;
+
+
+ 您輸入的密碼並不會回應到螢幕,所以不會以星號顯示
+ 。 請確定您所輸入的密碼無誤。
+ rmuserrmuseraccountsremoving
- You can use &man.rmuser.8; to
- completely remove a user from the system.
- &man.rmuser.8; performs the following
- steps:
+ 您可以使用 &man.rmuser.8; 來將使用者從系統之中完全移除
+ &man.rmuser.8; 會執行以下動作:
- Removes the user's &man.crontab.1; entry (if
- any).
+ 移除該使用者的 &man.crontab.1; 資料 (如果存在)。
- Removes any &man.at.1; jobs belonging to the
- user.
+ 移除所有屬於該使用者的 &man.at.1; 工作。
- Kills all processes owned by the user.
+ 中止所有該使用者擁有的程序。
- Removes the user from the system's local password
- file.
+ 移除系統本機密碼檔中該使用者的資料。
- Removes the user's home directory (if it is owned by
- the user).
+ 移除該使用者的家目錄 (如果為該使用者所有)。
- Removes the incoming mail files belonging to the user
- from /var/mail.
+ 移除 /var/mail 中屬於該使用者的郵件。
- Removes all files owned by the user from temporary
- file storage areas such as /tmp.
+ 移除暫存空間 (如: /tmp) 中所有屬於該使用者的檔案。
- Finally, removes the username from all groups to which
- it belongs in /etc/group.
-
+ 最後,在 /etc/group 檔內移除該使用者帳號。
+
+
- If a group becomes empty and the group name is the
- same as the username, the group is removed; this
- complements the per-user unique groups created by
- &man.adduser.8;.
+ 若該群組已無成員,或者是群組名稱與該使用者名稱相同時,
+ 則群組將會被移除; 此操作會與 &man.adduser.8;
+ 所建立的帳號群組相對應。
-
- &man.rmuser.8; cannot be used to remove
- superuser accounts, since that is almost always an indication
- of massive destruction.
+ &man.rmuser.8; 無法移除系統管理者帳號帳號,
+ 因為這即代表嚴重的破壞行為。
- By default, an interactive mode is used, which attempts to
- make sure you know what you are doing.
+ 為了確認您的操作,預設採互動模式。
- rmuser Interactive Account Removal
+ rmuser 帳號移除&prompt.root; rmuser jru
Matching password entry:
jru:*:1001:1001::0:0:J. Random User:/home/jru:/usr/local/bin/zsh
Is this the entry you wish to remove? y
Remove user's home directory (/home/jru)? y
Updating password file, updating databases, done.
Updating group file: trusted (removing group jru -- personal group is empty) done.
Removing user's incoming mail file /var/mail/jru: done.
Removing files belonging to jru from /tmp: done.
Removing files belonging to jru from /var/tmp: done.
Removing files belonging to jru from /var/tmp/vi.recover: done.
&prompt.root;chpasschpass
- &man.chpass.1; changes user database
- information such as passwords, shells, and personal
- information.
+ &man.chpass.1; 可更改使用者資料如: 密碼、Shell及個人資訊。
- Only system administrators, as the superuser, may change
- other users' information and passwords with
- &man.chpass.1;.
+ 僅系統管理者即系統管理者帳號可利用 &man.chpass.1; 更改其他使用者的資訊及密碼
- When passed no options, aside from an optional username,
- &man.chpass.1; displays an editor
- containing user information. When the user exists from the
- editor, the user database is updated with the new
- information.
+ 除了指定使用者名稱,當不加參數時,&man.chpass.1; 會將使用者資訊顯示於編輯器當中。
+ 並於使用者離開編輯器時更新使用者資訊。
- In &os; 5.X, you will be asked for your password
- after exiting the editor if you are not the superuser.
+ 若您並非系統管理者帳號,在離開編輯器前會詢問您的密碼。
- Interactive chpass by Superuser
+ 系統管理者帳號 chpass#Changing user database information for jru.
Login: jru
Password: *
Uid [#]: 1001
Gid [# or name]: 1001
Change [month day year]:
Expire [month day year]:
Class:
Home directory: /home/jru
Shell: /usr/local/bin/zsh
Full Name: J. Random User
Office Location:
Office Phone:
Home Phone:
Other information:
- The normal user can change only a small subset of this
- information, and only for themselves.
+ 一般使用者僅可更改自己的少部份資訊。
- Interactive chpass by Normal User
+ 一般使用者 chpass#Changing user database information for jru.
Shell: /usr/local/bin/zsh
Full Name: J. Random User
Office Location:
Office Phone:
Home Phone:
Other information:
- &man.chfn.1; and &man.chsh.1; are
- just links to &man.chpass.1;, as
- are &man.ypchpass.1;,
- &man.ypchfn.1;, and
- &man.ypchsh.1;. NIS support is automatic, so
- specifying the yp before the command is
- not necessary. If this is confusing to you, do not worry, NIS will
- be covered in .
+ &man.chfn.1; 與 &man.chsh.1; 即為 &man.chpass.1;,也同
+ &man.ypchpass.1;、&man.ypchfn.1; 與 &man.ypchsh.1;。
+ NIS 支援是自動的,所以無需在指令前加上 yp。
+ 若這會困擾您,請不必擔心, 將函蓋 NIS 的部份的說明。passwdpasswdaccountschanging password
- &man.passwd.1; is the usual way to
- change your own password as a user, or another user's password
- as the superuser.
+ &man.passwd.1; 是更改密碼常用的方式,除了超級管理者可更改其他使用者的密碼外
+ 使用者僅能更改自己的密碼。
- To prevent accidental or unauthorized changes, the original
- password must be entered before a new password can be set.
+ 為了避免意外或未經同意的修改,在更新密碼前需輸入原密碼。
- Changing Your Password
+ 更改您的密碼&prompt.user; passwd
Changing local password for jru.
Old password:
New password:
Retype new password:
passwd: updating the database...
passwd: done
- Changing Another User's Password as the Superuser
+ 以系統管理者帳號去更改其他使用者的密碼&prompt.root; passwd jru
Changing local password for jru.
New password:
Retype new password:
passwd: updating the database...
passwd: done
- As with &man.chpass.1;,
- &man.yppasswd.1; is just a link to
- &man.passwd.1;, so NIS works with either
- command.
+ &man.chpass.1;、
+ &man.yppasswd.1; 即為 &man.passwd.1;,皆支援 NIS。pwpw
- &man.pw.8; is a command line utility to create, remove,
- modify, and display users and groups. It functions as a front
- end to the system user and group files. &man.pw.8;
- has a very powerful set of command line options that make it
- suitable for use in shell scripts, but new users may find it
- more complicated than the other commands presented
- here.
+ &man.pw.8; 用來建立、移除、修改及查詢使用者及群組。
+ 其功能即為系統使用者及群組檔案的前端。&man.pw.8; 擁有大量的指令參數
+ 較適合使用於 shell script 中,對新手來說會此指令較其他指令複雜許多。
+
- 對帳號的資源運用作限制
+ 使用者資源限制limiting usersaccountslimiting
- If you have users, the ability to limit their system use may
- have come to mind. FreeBSD provides
- several ways an administrator can limit the amount of system
- resources an individual may use. These limits are
- divided into two sections: disk quotas, and other resource
- limits.
+
+
+ 若您擁有許多使用者,接下會想到該如何限制使用的資源。
+ FreeBSD 提供管理者許多方法來限制系統的資源給每個人使用。
+ 這些限制分為兩個部份: 磁碟限額,以及其他資源限制。
+ quotaslimiting usersquotasdisk quotas
- Disk quotas limit disk usage to users, and
- they
- provide a way to quickly check that usage without
- calculating it every time. Quotas are discussed in .
+ 磁碟限額可以限制使用者的磁碟用量,
+ 它提供了一種方法可以快速的檢查並計算用量
+ 而不需每次重新計算,
+ 關於磁碟限額將於 會討論。
- The other resource limits include ways to limit the amount of
- CPU, memory, and other resources a user may consume. These are
- defined using login classes and are discussed here.
+ 其他資源限制包含了 CPU、記憶體、以及其他每個使用者可使用
+ 的資源做限制,這些限制可使用 Login class 來定義並於在本章討論。/etc/login.conf
- Login classes are defined in
- /etc/login.conf. The precise semantics are
- beyond the scope of this section, but are described in detail in the
- &man.login.conf.5; manual page. It is sufficient to say that each
- user is assigned to a login class (default by
- default), and that each login class has a set of login capabilities
- associated with it. A login capability is a
- name=value
- pair, where name is a well-known
- identifier and value is an arbitrary
- string processed accordingly depending on the name. Setting up login
- classes and capabilities is rather straight-forward and is also
- described in &man.login.conf.5;.
+ Login class 定義於
+ /etc/login.conf。 明確語意不會在本節說明
+ 但詳細的描述會在 &man.login.conf.5; 文件中。 每使用者預設被
+ 分配到一個 Login class 中 (預設為 default),
+ 而每個 Login class 都有其資源的限制(Login capabilitiy)。
+ Login capabilitiy 以 名稱=值 成對,
+ 名稱 代表資源的種類,而 值
+ 為任意的字串,為對應名稱的參數。 設定 Login class 及 Login capability 相當簡單,並同樣在
+ &man.login.conf.5; 中詳細說明。
- The system does not normally read the configuration in
- /etc/login.conf directly, but reads the database
- file /etc/login.conf.db which provides
- faster lookups.
- To generate /etc/login.conf.db from
- /etc/login.conf, execute the following
- command:
+ 系統不會直接讀取 /etc/login.conf 的組態
+ 而是讀取提供查詢較快的 /etc/login.conf.db 資料庫檔。
+ 要從 /etc/login.conf 產生 /etc/login.conf.db
+ 需要執行以下指令:&prompt.root; cap_mkdb /etc/login.conf
- Resource limits are different from plain vanilla login
- capabilities in two ways. First, for every limit, there is a soft
- (current) and hard limit. A soft limit may be adjusted by the user
- or application, but may be no higher than the hard limit. The latter
- may be lowered by the user, but never raised. Second, most resource
- limits apply per process to a specific user, not the user as a whole.
- Note, however, that these differences are mandated by the specific
- handling of the limits, not by the implementation of the login
- capability framework (i.e., they are not really
- a special case of login capabilities).
-
- And so, without further ado, below are the most commonly used
- resource limits (the rest, along with all the other login
- capabilities, may be found in &man.login.conf.5;).
+ 資源限制於一般的 Login capability 有兩點不同。
+ 第一,每種限制分為軟性限制及硬性限制。
+ 軟性限制可由使用者或應用程式調整,但不能高於硬性限制。
+ 後者限制可被使用者降低,但無法再提高。
+ 第二,多數資源限制是針對每個使用者的個別行程限制,而不是使用者的所有行程。
+ 注意,這些差異是由指定的限制程式托管,並非實作於 Login capability 的架構
+ (例如,這些不是 真正 登入容量的特例)。
+
+ 另外,為了避免麻煩,以下為幾個常用的資源限制
+ (剩下及其他的 Login capability 可在 &man.login.conf.5; 中找到說明)。coredumpsizecoredumpsizelimiting userscoredumpsizeThe limit on the size of a core file generated by a program
is, for obvious reasons, subordinate to other limits on disk
usage (e.g., filesize, or disk quotas).
Nevertheless, it is often used as a less-severe method of
controlling disk space consumption: since users do not generate
core files themselves, and often do not delete them, setting this
may save them from running out of disk space should a large
program (e.g., emacs) crash.cputimecputimelimiting userscputimeThis is the maximum amount of CPU time a user's process may
- consume. Offending processes will be killed by the kernel.
+ consume. Offending processes will be killed by the kernel.This is a limit on CPU time
consumed, not percentage of the CPU as displayed in some
fields by &man.top.1; and &man.ps.1;. A limit on the
latter is, at the time of this writing, not possible, and
would be rather useless: a compiler—probably a
legitimate task—can easily use almost 100% of a CPU
for some time.
-
filesizefilesizelimiting usersfilesizeThis is the maximum size of a file the user may possess.
Unlike disk quotas, this limit is
enforced on individual files, not the set of all files a user
owns.maxprocmaxproclimiting usersmaxprocThis is the maximum number of processes a user may be
running. This includes foreground and background processes
alike. For obvious reasons, this may not be larger than the
system limit specified by the kern.maxproc
&man.sysctl.8;. Also note that setting this
too small may hinder a
user's productivity: it is often useful to be logged in
multiple times or execute pipelines. Some tasks, such as
compiling a large program, also spawn multiple processes (e.g.,
&man.make.1;, &man.cc.1;, and other intermediate
preprocessors).memorylockedmemorylockedlimiting usersmemorylockedThis is the maximum amount a memory a process may have
requested to be locked into main memory (e.g., see
&man.mlock.2;). Some system-critical programs, such as
&man.amd.8;, lock into main memory such that in the event
of being swapped out, they do not contribute to
a system's trashing in time of trouble.memoryusememoryuselimiting usersmemoryuseThis is the maximum amount of memory a process may consume
at any given time. It includes both core memory and swap
usage. This is not a catch-all limit for restricting memory
consumption, but it is a good start.openfilesopenfileslimiting usersopenfilesThis is the maximum amount of files a process may have
open. In FreeBSD, files are also used to represent sockets and
IPC channels; thus, be careful not to set this too low. The
system-wide limit for this is defined by the
kern.maxfiles &man.sysctl.8;.sbsizesbsizelimiting userssbsizeThis is the limit on the amount of network memory, and thus
mbufs, a user may consume. This originated as a response to an
old DoS attack by creating a lot of sockets, but can be
generally used to limit network communications.stacksizestacksizelimiting usersstacksizeThis is the maximum size a process' stack may grow to.
This alone is not sufficient to limit the amount of memory a
program may use; consequently, it should be used in conjunction
with other limits.There are a few other things to remember when setting resource
limits. Following are some general tips, suggestions, and
miscellaneous comments.Processes started at system startup by
/etc/rc are assigned to the
daemon login class.Although the /etc/login.conf that comes
with the system is a good source of reasonable values for most
limits, only you, the administrator, can know what is appropriate
for your system. Setting a limit too high may open your system
up to abuse, while setting it too low may put a strain on
productivity.Users of the X Window System (X11) should probably be granted
more resources than other users. X11 by itself takes a lot of
resources, but it also encourages users to run more programs
simultaneously.Remember that many limits apply to individual processes, not
the user as a whole. For example, setting
openfiles to 50 means
that each process the user runs may open up to 50 files. Thus,
the gross amount of files a user may open is the value of
openfiles multiplied by the value of
maxproc. This also applies to memory
consumption.For further information on resource limits and login classes and
capabilities in general, please consult the relevant manual pages:
&man.cap.mkdb.1;, &man.getrlimit.2;, &man.login.conf.5;.
- Groups
+ 群組groups/etc/groupsaccountsgroupsA group is simply a list of users. Groups are identified by
their group name and GID (Group ID). In FreeBSD (and most other &unix; like
systems), the two factors the kernel uses to decide whether a process
is allowed to do something is its user ID and list of groups it
belongs to. Unlike a user ID, a process has a list of groups
associated with it. You may hear some things refer to the group ID
of a user or process; most of the time, this just means the first
group in the list.The group name to group ID map is in
/etc/group. This is a plain text file with four
colon-delimited fields. The first field is the group name, the
second is the encrypted password, the third the group ID, and the
fourth the comma-delimited list of members. It can safely be edited
by hand (assuming, of course, that you do not make any syntax
errors!). For a more complete description of the syntax, see the
&man.group.5; manual page.If you do not want to edit /etc/group
manually, you can use the &man.pw.8; command to add and edit groups.
For example, to add a group called teamtwo and
then confirm that it exists you can use:Adding a Group Using &man.pw.8;&prompt.root; pw groupadd teamtwo
&prompt.root; pw groupshow teamtwo
teamtwo:*:1100:The number 1100 above is the group ID of the
group teamtwo. Right now,
teamtwo has no members, and is thus rather
useless. Let's change that by inviting jru to
the teamtwo group.Adding Somebody to a Group Using &man.pw.8;&prompt.root; pw groupmod teamtwo -M jru
&prompt.root; pw groupshow teamtwo
teamtwo:*:1100:jruThe argument to the option is a
comma-delimited list of users who are members of the group. From the
preceding sections, we know that the password file also contains a
group for each user. The latter (the user) is automatically added to
the group list by the system; the user will not show up as a member
when using the command to &man.pw.8;,
but will show up when the information is queried via &man.id.1; or
similar tool. In other words, &man.pw.8; only manipulates the
/etc/group file; it will never attempt to read
additionally data from /etc/passwd.Using &man.id.1; to Determine Group Membership&prompt.user; id jru
uid=1001(jru) gid=1001(jru) groups=1001(jru), 1100(teamtwo)As you can see, jru is a member of the
groups jru and
teamtwo.For more information about &man.pw.8;, see its manual page, and
for more information on the format of
/etc/group, consult the &man.group.5; manual
page.
diff --git a/zh_TW.Big5/books/porters-handbook/book.sgml b/zh_TW.Big5/books/porters-handbook/book.sgml
index 1611137383..90cf5ca7b7 100644
--- a/zh_TW.Big5/books/porters-handbook/book.sgml
+++ b/zh_TW.Big5/books/porters-handbook/book.sgml
@@ -1,12426 +1,12422 @@
%books.ent;
]>
FreeBSD Porter's HandbookFreeBSD 文件計劃April 200020002001200220032004200520062007FreeBSD 文件計劃
&bookinfo.trademarks;
&bookinfo.legalnotice;
楔子幾乎每個 FreeBSD 愛用者都是透過 FreeBSD Ports Collection
來裝各式應用程式("ports")。如同 FreeBSD 的其他部分一樣,
這些 ports 都主要來自許多志工的努力成果,所以在閱讀這份文件時,
請務必感恩在心。在 FreeBSD 上面,每個人都可以提交新的 port,
或假如該 port 並沒有人維護的話,可以自願維護 —
這點並不需要任何 commit 的權限,就可以來做這件事情。自行打造 port那麼,開始對自行製作 port 或更新現有 port 有一些興趣了嗎?太好囉!下面將介紹一些建立 port 時該注意的事項。如果是想升級現有的 port
,那麼也請參閱 說明。因為這份文件可能講得不是十分詳細,可能需要參考
/usr/ports/Mk/bsd.port.mk 這檔是所有 port 的
Makefile 檔都會用到的。 就算你不是每天不斷 hacking Makefiles
,也都可以藉由它來對整個 port 機制、Makefile 更瞭解,
裡面的註釋相當詳細。 此外,若有其他特定 port 的問題,也可以到
&a.ports; 來獲得答案。本文內所提及的環境變數
(VAR)部份,
只有一些可以替換(overridden)。大部份的環境變數(非全部)通常都會寫在
/usr/ports/Mk/bsd.port.mk 內,其他的也是差不多。
請注意:該檔並非使用一般的 tab 設定值,而是採用 1 個 tab 等於 4 個
space。
:Emacs 與 Vim
應該都會在載入該檔時順便讀取相關設定值。
&man.vi.1; 及 &man.ex.1; 這兩個程式也都可以打
:set tabstop=4 以修改設定值。打造 Port 快速上手篇本節主要介紹如何來快速打造 port,然而,
很多時候這些內容並不是很夠用,建議閱讀本文件中更深奧的地方。首先取得該應用程式的原始程式碼壓縮檔(tarball),並把它放到
DISTDIR,預設路徑應該是
/usr/ports/distfiles。下面的例子,是假設並不需要再修改該應用程式的原始碼,就可以在
FreeBSD 上編譯成功的;假如還需要另外修改才能成功編譯的話,
那麼請參考下一章的說明。編寫 Makefile最簡單的 Makefile 大概是像這樣:# New ports collection makefile for: oneko
# Date created: 5 December 1994
# Whom: asami
#
# $FreeBSD$
#
PORTNAME= oneko
PORTVERSION= 1.1b
CATEGORIES= games
MASTER_SITES= ftp://ftp.cs.columbia.edu/archives/X11R5/contrib/
MAINTAINER= asami@FreeBSD.org
COMMENT= A cat chasing a mouse all over the screen
MAN1= oneko.1
MANCOMPRESSED= yes
USE_IMAKE= yes
.include <bsd.port.mk>嗯,大致就是這樣,看看你已經領略多少了呢?
看到 $FreeBSD$ 這一行的話,別想太多
,它是 RCS ID 用途,當該 port 正式進入 port tree 時,
CVS 就會自動轉換為相關字串囉。 有關這點的細節部份,可以參閱 sample Makefile 章節。撰寫該軟體的說明檔無論是否打算再加工做成 package,有 2 個檔案是任何實體 port (Slave
port則不一定)都必須要具備的。 這 2 個檔分別是
pkg-descr 檔及 pkg-plist
檔。 這兩個檔案檔名前面都有 pkg-
以跟其他檔案做區別。pkg-descr這是此 port 的詳細說明檔,請用一段或幾段文字來說明該 port
的作用,並附上 WWW 網址(若有的話)。請注意,這檔絕非「該軟體的說明手冊」或是「如何編譯、使用該
port 的說明」。 若是從該軟體的 README
或 manpage 直接複製過來的話,請注意,因為它們通常都寫得太詳細、
格式較特別(比如 manpage 會自動調整空白),
請儘量避免這些冗長贅詞或採用特殊格式。若該軟體有官方版首頁的話,
請在此列出來。 每個網址請用 WWW: 作為開頭,
這樣子相關工具程式就會自動處理完畢。該 port 的 pkg-descr 內容,大致如下面例子
:This is a port of oneko, in which a cat chases a poor mouse all over
the screen.
:
(etc.)
WWW: http://www.oneko.org/pkg-plist這是該 port 所會裝的所有檔案清單,另外因為 package
會由這清單所產生,因此也被稱為『packing list
(打包清單)』。 以 ${PREFIX} 為基準點,
而用相對路徑表示。(${PREFIX} 通常是
/usr/local 或 /usr/X11R6)
但是如果該程式有安裝 man page 的話,則要以類似
MANn= 的方式寫在
Makefile 內,不能列在
pkg-plist 哦。
除了列出檔案以外,也要把該 port 所會建立的目錄也列進去,
方式有兩種:一種是寫在 pkg-plist 內的方式,
比如:@dirrm。 至於另外一種方式,則是寫在
Makefile 內,比如:
PLIST_FILES= 之類的方式。該 port 的 pkg-plist 內容,
大致如下面例子:bin/oneko
lib/X11/app-defaults/Oneko
lib/X11/oneko/cat1.xpm
lib/X11/oneko/cat2.xpm
lib/X11/oneko/mouse.xpm
@dirrm lib/X11/oneko關於 packing list 方面,可以參閱 &man.pkg.create.1; 會有詳解
。建議清單內的檔名,依照字母順序作排序,那麼下次要升級時,
會比較清楚、方便來更新這份清單。 手動生這份清單實在太苦了。尤其若該 port 會裝一大堆檔案的話,
請多善用 自動產生 packing
list 會比較省時省力唷。只有在一種情況下可以省略不用生 pkg-plist
檔: 若安裝的 port 相當單純,只有裝一些檔案,
以及都在同一目錄下的話,那麼可以在 Makefile
內改用 PLIST_FILES 及
PLIST_DIRS 來取代。
比如,可以在上述的 oneko port 內不必附上
pkg-plist ,而只需在
Makefile 內加入下列幾行:PLIST_FILES= bin/oneko \
lib/X11/app-defaults/Oneko \
lib/X11/oneko/cat1.xpm \
lib/X11/oneko/cat2.xpm \
lib/X11/oneko/mouse.xpm
PLIST_DIRS= lib/X11/oneko當然,若該 port 並無安裝自屬的目錄的話,就不必設
PLIST_DIRS 囉。然而,使用 PLIST_FILES 、PLIST_DIRS 是必須付出代價:
不能使用 &man.pkg.create.1; 內所說的 command sequences。
因此,這招僅適用於較簡單的 port ,以及簡化該 port 的作法。
此外,這招還有一個好處:可以減少 ports collection 的整體檔案總數。
所以,在考慮是否一定要用 pkg-plist 之前,
可以先斟酌這個替代方案看看。後面會介紹到如何運用 pkg-plist、
PLIST_FILES 這些技巧以因應 更複雜的狀況。產生 checksum 用途的 distinfo 檔只要打『make makesum』就好了,
接下來就會自動產生相對應的 distinfo 檔了唷
。若抓下來的檔案,它的 checksum 會經常變更,
而你也很確認所抓的來源是正確無誤的話,
(比如:來源是光碟或是每天自動產生的文件),那麼可以設定那些檔案為
IGNOREFILES 。 如此一來,在打
make makesum 的時候就不會計算那些檔案的 checksum
,而自動改為 IGNORE 囉。檢驗 port 是否完整、可行接下來,必須檢驗是否有符合 port 的遊戲規則,包括打包該 port
為 package。 以下有幾個需要確認的重要地方:若該 port 沒裝的東西,不要列在 pkg-plist
內。若該 port 有裝的東西,請務必列在
pkg-plist 內。該 port 可以用 reinstall 來重新安裝。該 port 在移除之後,確定都可 cleans up。建議的測試步驟順序:make installmake packagemake deinstallpkg_add package-namemake deinstallmake reinstallmake package確認在 package 和
deinstall 這兩個階段都沒有任何錯誤訊息出現。
完成第三步驟之後,檢查一下是否所裝的檔案、目錄都有移除完畢。 此外,
第四步驟完成後,也檢查一下以 package 裝的該軟體,是否都能正常運作
。最周密的自動方式就是透過裝
ports tinderbox。 它會建立
jails 並管理之,以便您可以測試上述所有步驟,
而不會真正影響您本身的作業系統。 詳情請參考
ports/ports-mgmt/tinderbox。以 portlint 來作檢驗請用 portlint 來檢查該 port
是否有遵循上述遊戲規則。 說到這
ports-mgmt/portlint,它是
ports collection 的其中一個套件。 它主要可以用來檢驗 Makefile 內容是否正確以及 package 是否有正確命名。提交(Submit) port首先,請確認是否有瞭解 DOs and DON'Ts 該章部分。現在你很高興終於打造出 port 來囉,唯一剩下要做的就是把它正式放到
FreeBSD ports tree 內,才能讓每個人都能分享使用這個 port。 請先拿掉
work 目錄或檔名像是
pkgname.tgz 的 package 可以砍掉。 接著,
只要用 shar `find port_dir` 來產生 shar 格式,
並配合 &man.send-pr.1; 程式以提交出去。(&man.send-pr.1;
的部分可以參閱
錯誤報告和意見發表)記得在填寫 PR 時『分類(Category)』選 ports,
還有『種類(Class)』填 change-request
(千萬別傻傻地把該 PR 的『Confidential(機密)』設為 yes!),
此外在『描述(Description)』
那邊寫上該程式的簡潔說明,而 shar 檔則附在『修正(Fix)
』欄位內。若 Synopsis 欄清楚描述該 PR 重點的話,那麼會讓整個流程更為順暢。
new ports 的話,我們習慣用:
New port: <category>/<portname>
<該 port 的簡介> ,而更新 port 的話,則是
Update port: <category>/<portname>
<本次 update 的簡介>。
若你也採用這樣的格式的話,那麼會被受理的機會就會越高囉。再次強調一點:不必附上原始 source 的 distfile
,也就是 work 目錄。 同時,也不必附上
make package 時產生的 package。送出 port 之後,請耐心等候佳音。
有時候可能需要等個幾天或幾個月時間,才會在 FreeBSD ports tree
上正式出現。 此外,隨時可以查閱
等待 committed to FreeBSD 的 port 列表。一旦我們開始處理你送來的 port 之後,如果有一些意見需要溝通的話,
那麼會先 feedback 給你,
之後確定都沒問題,就會放到 port tree 內囉!
你的大名會被記在 Additional FreeBSD Contributors
列表上,以及其他檔案。聽起來,挺不賴的不是嗎!? :-)Slow PortingOk...事實上並不太可能這麼簡單,port
方面可能需要作些修改才能正常使用。 因此,
本節將一步一步來介紹如何修改上一章的樣本以正常使用。How things work首先,先介紹一下在你所作的 port 目錄內打 make
時,所會作哪些事情的順序吧。
你可以另開一窗來看 bsd.port.mk
內容,以便瞭解我們下面在講什麼。但別太擔心是否完全看懂
bsd.port.mk 在做啥,很多人都還沒完全看完...
:->首先,進行 fetch 階段。
fetch 是確認 tarball 檔有沒有已在
DISTDIR 內了?若 fetch
在 DISTDIR 找不到的話,它會搜尋 Makefile
內的 MASTER_SITES URL
,或者是主 FTP 站專門放備份 distfiles 的目錄
。 假設都找不到的話,但是網路有接上 Internet 的話,它會試著用
FETCH 來抓所指定的檔案。
抓到之後,它會把檔案存到 DISTDIR
以便開始使用或日後運用。其次,進行 extract 階段,它會從
DISTDIR 內找出該 port 所需的檔案(通常是 gzip
格式的 tarball),然後解壓縮到 WRKDIR
所設定的臨時目錄名稱(預設是 work 目錄)內。之後,進行 patch 階段,
一開始會先套用 PATCHFILES 所指定的任何 patch
檔。 接著是 PATCHDIR(預設是
files 子目錄) 內的檔名為
patch-*
之類的檔案,會以字母順序而逐一套用 patch。接著是 configure 階段,可以照 port
的類型來作各種不同設定以調整,比如:若有放 scripts/configure 的話,
那麼就會跑裡面的設定。若有設 HAS_CONFIGURE 或是
GNU_CONFIGURE 的話,那麼就會跑
WRKSRC/configure若有設 USE_IMAKE 的話,那麼就會跑
XMKMF (預設是 xmkmf
-a) 。最後是 build 階段,它會在該
port 的 working directory(由 WRKSRC 所設定)
內開始編譯。 若有設 USE_GMAKE 的話,
那麼就會改用 GNU make 來編譯,
否則就用系統本身的 make 來編譯。上面講的都是打 make 時的預設階段。
此外,還可以設定各階段之前、之後要作的事情:透過定義
pre-something 或
post-something,
或者把這些檔名的 script 丟到 scripts 子目錄去,
這樣子它們就會在各預設階段的之前、之後進行囉。舉例來說,若在 Makefile 內設定
post-extract,而且在
scripts 子目錄內又有
pre-build 檔的話,那麼在作解壓縮之後,就會開始
post-extract 階段以進行解壓縮後的後續動作,
而在跑 build 階段之前,就會先執行 pre-build
這隻 script 作先期準備。 通常較簡單的修改動作,建議直接放在
Makefile 內就好了,
因為這樣會比較方便加上這些原本沒有的階段,同時也方便他人協助除錯
。預設的各階段動作都是照 bsd.port.mk 內的
do-something
之類所定義的。 舉例:do-extract
就是定義怎麼把檔案解壓縮的。
若對預設方式覺得不妥的話,都可以在該 port 的
Makefile 重新定義。The main targets (e.g.,
extract,
configure, etc.) do nothing more than
make sure all the stages up to that one are completed and call
the real targets or scripts, and they are not intended to be
changed. If you want to fix the extraction, fix
do-extract, but never ever change
the way extract operates!現在,你已經知道打 make 到底會作些什麼事囉,
接下來會教你如何作更完美的 port。取得原始的 source 檔取得原始的 source 檔(通常檔名是
foo.tar.gz
或 foo.tar.Z
之類的壓縮檔),然後會把抓下來的檔案放在 DISTDIR
內。 記得:抓的時候,儘量使用『該軟體主要的正式網站』上面的來源檔
,以確保檔案有效、可信。需要設 MASTER_SITES 以指定原始檔案是放在何處。
相關網址在 bsd.sites.mk
內有一些方便的速記表可以使用。 請盡可能多用對應這些網址的變數,
以避免同樣的一堆網址有重複很多次出現在 port tree 內。
否則,這些網址只要一有改變的話,那麼就會成為維護 port 的夢魘。如果該檔並沒有放在公開的 FTP 站或網站(HTTP)上,
或者該檔並非一般標準格式的話,
那麼可以考慮複製該檔,然後放到你可掌握、可信任的 FTP 站或網站(HTTP)
上,比如:你自己的網頁空間。若找不到地方(方便、可信任)來放檔案的話,
那麼可以 house(暫放) 在
ftp.FreeBSD.org 上的 committer 自屬空間內;
然而,這是最不理想的解法。
檔案要放到該 committer 的 freefall 上的
~/public_distfiles/ 目錄內才可以。
請與協助 commit 你的 port 的那位 committer 聯繫,
以便把檔案放到他的目錄內。
那位 committer 同時也會把 MASTER_SITES 設為
MASTER_SITE_LOCAL,並且把
MASTER_SITE_SUBDIR 設為他自己的
freefall 帳號名稱。若該 port 的原始檔打包會經常重包,但原作者卻沒更新版號的話,
請考慮把該檔改放到自己的網頁空間,並且把自己網頁空間列為
MASTER_SITES 的第一順位。
或者請與原作者聯繫:請他不要這樣做(不斷重包同樣的檔案);如此一來,
才有助於建立一定程度的 source code 版本控制。
把檔案另外複製一份放到自屬網頁空間的話,不但可有效防止使用者會發生
checksum mismatch(檔案經檢查有問題)
的錯誤訊息,也可降低我們 FTP 站維護者的工作量。此外,若該 port
的檔案僅有一個主要網址,
那麼建議:請在自屬網站上放上備份檔,並修改
MASTER_SITES 把你的網址列為第二順位。若該 port 需要一些額外 `patches'(可透過 Internet 下載),並放在
DISTDIR 內,不必擔心這些 patch
檔是否得都跟原始檔一樣來自同一網站,
這些情況有另外的解法(請看下面的 PATCHFILES 介紹部分)。量身打造 port解開壓縮檔,然後開始逐一修改,使該 port 在目前所用的 FreeBSD
版本上得以順利編譯。
所做的每個動作請都 仔細記錄,
如此一來才能迅速自動套用這些修改。
在完成 port 之後,每項動作包括:對於檔案的刪除、增加、修改,
要記得存為自動化的 script 或者 patch 檔形式,以利他人直接套用。若該 port 需要使用者的互動、自訂功能來編譯、安裝的話,
那麼建議揣摩看看 Larry Wall 的經典之作
Configure scripts 來完成類似效果。
Ports collection 的目的之一,就是讓每個 port 儘量用最小空間,
來做出軟體的 plug-and-play(即插即用)。除非有明確聲明,否則你所提交給 FreeBSD ports collection 的
patch 檔、相關 script 檔及其他檔案,都會假設是以標準的 BSD
版權形式來發佈。PatchingIn the preparation of the port, files that have been added or
changed can be picked up with a &man.diff.1;
for later feeding to &man.patch.1;. Each patch you
wish to apply should be saved into a file named
patch-* where
* indicates
the pathname of the file that is patched,
such as patch-Imakefile or
patch-src-config.h. These files should
be stored in PATCHDIR
(usually files/, from where they will be
automatically applied. All patches must be relative to
WRKSRC (generally the directory your port's
tarball unpacks itself into, that being where the build is done).
To make fixes and upgrades easier, you should avoid having more than
one patch fix the same file (e.g., patch-file and
patch-file2 both changing
WRKSRC/foobar.c).Please only use characters [-+._a-zA-Z0-9] for
naming your patches. Do not use any other characters besides them.
Do not name your patches like patch-aa or
patch-ab etc, always mention path and file name
in patch names.Do not put RCS strings in patches. CVS will mangle them when we
put the files into the ports tree, and when we check them out again,
they will come out different and the patch will fail. RCS strings
are surrounded by dollar ($) signs, and
typically start with $Id or
$RCS.Using the recurse () option to
&man.diff.1; to generate patches is fine, but please take
a look at the resulting patches to make sure you do not have any
unnecessary junk in there. In particular, diffs between two backup
files, Makefiles when the port uses
Imake or GNU configure, etc.,
are unnecessary and should be deleted. If you had to edit
configure.in and run
autoconf to regenerate
configure, do not take the diffs of
configure (it often grows to a few thousand
lines!); define USE_AUTOTOOLS=autoconf:261 and take the
diffs of configure.in.If you had to delete a file, then you can do it in the
post-extract target rather than as part of
the patch.Simple replacements can be performed directly from the port
Makefile using the in-place mode of
&man.sed.1;. This is very useful when you need to patch in
a variable value. Example:post-patch:
@${REINPLACE_CMD} -e 's|for Linux|for FreeBSD|g' ${WRKSRC}/README
@${REINPLACE_CMD} -e 's|-pthread|${PTHREAD_LIBS}|' ${WRKSRC}/configureQuite often, there is a situation when the software being
ported, especially if it is primarily developed on &windows;, uses
the CR/LF convention for most of its source files. This may cause
problems with further patching, compiler warnings, scripts
execution (/bin/sh^M not found), etc. To
quickly convert all files from CR/LF to just LF, add
USE_DOS2UNIX=yes to the port
Makefile. A list of files to convert can
be specified:USE_DOS2UNIX= util.c util.h若想要轉換所有子目錄內的某類別檔案,可以使用
DOS2UNIX_REGEX。 它的參數是
find 相容的正規表達式。 相關格式可參閱
&man.re.format.7;。 對於所指定副檔名的檔案之轉換而言,這相當好用,
舉例來說,只動所有原始碼部分而不改 binary 檔案:USE_DOS2UNIX= yes
DOS2UNIX_REGEX= .*\.(c|cpp|h)
- Configuring
+ 設定Include any additional customization commands in your
configure script and save it in the
scripts subdirectory. As mentioned above, you
can also do this with Makefile targets and/or
scripts with the name pre-configure or
post-configure.Handling user inputIf your port requires user input to build, configure, or install,
you must set IS_INTERACTIVE in your Makefile. This
will allow overnight builds to skip your port if the
user sets the variable BATCH in his environment (and
if the user sets the variable INTERACTIVE, then
only those ports requiring interaction are
built). This will save a lot of wasted time on the set of
machines that continually build ports (see below).It is also recommended that if there are reasonable default
answers to the questions, you check the
PACKAGE_BUILDING variable and turn off the
interactive script when it is set. This will allow us to build the
packages for CDROMs and FTP.Configuring the MakefileConfiguring the Makefile is pretty simple, and again we suggest
that you look at existing examples before starting. Also, there is a
sample Makefile in this
handbook, so take a look and please follow the ordering of variables
and sections in that template to make your port easier for others to
read.Now, consider the following problems in sequence as you design
your new Makefile:The original sourceDoes it live in DISTDIR as a standard
gzip'd tarball named something like
foozolix-1.2.tar.gz? If so, you can go on
to the next step. If not, you should look at overriding any of
the DISTVERSION, DISTNAME,
EXTRACT_CMD,
EXTRACT_BEFORE_ARGS,
EXTRACT_AFTER_ARGS,
EXTRACT_SUFX, or DISTFILES
variables, depending on how alien a format your port's
distribution file is. (The most common case is
EXTRACT_SUFX=.tar.Z, when the tarball is
condensed by regular compress, not
gzip.)In the worst case, you can simply create your own
do-extract target to override the
default, though this should be rarely, if ever,
necessary.NamingThe first part of the port's Makefile names
the port, describes its version number, and lists it in the correct
category.PORTNAME and PORTVERSIONYou should set PORTNAME to the
base name of your port, and PORTVERSION
to the version number of the port.PORTREVISION and
PORTEPOCHPORTREVISIONThe PORTREVISION variable is a
monotonically increasing value which is reset to 0 with
every increase of PORTVERSION (i.e.
every time a new official vendor release is made), and
appended to the package name if non-zero.
Changes to PORTREVISION are
used by automated tools (e.g. &man.pkg.version.1;)
to highlight the fact that a new package is
available.PORTREVISION should be increased
each time a change is made to the port which significantly
affects the content or structure of the derived
package.Examples of when PORTREVISION
should be bumped:Addition of patches to correct security
vulnerabilities, bugs, or to add new functionality to
the port.Changes to the port Makefile to enable or disable
compile-time options in the package.Changes in the packing list or the install-time
behavior of the package (e.g. change to a script
which generates initial data for the package, like ssh
host keys).Version bump of a port's shared library dependency
(in this case, someone trying to install the old
package after installing a newer version of the
dependency will fail since it will look for the old
libfoo.x instead of libfoo.(x+1)).Silent changes to the port distfile which have
significant functional differences, i.e. changes to
the distfile requiring a correction to
distinfo with no corresponding change to
PORTVERSION, where a diff
-ru of the old and new versions shows
non-trivial changes to the code.Examples of changes which do not require a
PORTREVISION bump:Style changes to the port skeleton with no
functional change to what appears in the resulting
package.Changes to MASTER_SITES or
other functional changes to the port which do not
affect the resulting package.Trivial patches to the distfile such as correction
of typos, which are not important enough that users of
the package should go to the trouble of
upgrading.Build fixes which cause a package to become
compilable where it was previously failing (as long as
the changes do not introduce any functional change on
any other platforms on which the port did previously
build). Since PORTREVISION reflects
the content of the package, if the package was not
previously buildable then there is no need to increase
PORTREVISION to mark a
change.A rule of thumb is to ask yourself whether a change
committed to a port is something which everyone
would benefit from having (either because of an
enhancement, fix, or by virtue that the new package will
actually work at all), and weigh that against that fact
that it will cause everyone who regularly updates their
ports tree to be compelled to update. If yes, the
PORTREVISION should be bumped.PORTEPOCHFrom time to time a software vendor or FreeBSD porter
will do something silly and release a version of their
software which is actually numerically less than the
previous version. An example of this is a port which goes
from foo-20000801 to foo-1.0 (the former will be
incorrectly treated as a newer version since 20000801 is a
numerically greater value than 1).In situations such as this, the
PORTEPOCH version should be increased.
If PORTEPOCH is nonzero it is appended
to the package name as described in section 0 above.
PORTEPOCH must never be decreased or reset
to zero, because that would cause comparison to a package
from an earlier epoch to fail (i.e. the package would not
be detected as out of date): the new version number (e.g.
1.0,1 in the above example) is still
numerically less than the previous version (20000801), but
the ,1 suffix is treated specially by
automated tools and found to be greater than the implied
suffix ,0 on the earlier package.Dropping or resetting PORTEPOCH
incorrectly leads
to no end of grief; if you do not understand the above discussion,
please keep after it until you do, or ask questions on
the mailing lists.It is expected that PORTEPOCH will
not be used for the majority of ports, and that sensible
use of PORTVERSION can often pre-empt
it becoming necessary if a future release of the software
should change the version structure. However, care is
needed by FreeBSD porters when a vendor release is made
without an official version number — such as a code
snapshot release. The temptation is to label the
release with the release date, which will cause problems
as in the example above when a new official release is
made.For example, if a snapshot release is made on the date
20000917, and the previous version of the software was
version 1.2, the snapshot release should be given a
PORTVERSION of 1.2.20000917 or similar,
not 20000917, so that the succeeding release, say 1.3, is
still a numerically greater value.Example of PORTREVISION and
PORTEPOCH usageThe gtkmumble port, version
0.10, is committed to the ports
collection:PORTNAME= gtkmumble
PORTVERSION= 0.10PKGNAME becomes
gtkmumble-0.10.A security hole is discovered which requires a local
FreeBSD patch. PORTREVISION is bumped
accordingly.PORTNAME= gtkmumble
PORTVERSION= 0.10
PORTREVISION= 1PKGNAME becomes
gtkmumble-0.10_1A new version is released by the vendor, numbered 0.2
(it turns out the author actually intended
0.10 to actually mean
0.1.0, not what comes after
0.9 - oops, too late now). Since the new minor
version 2 is numerically less than the
previous version 10, the
PORTEPOCH must be bumped to manually
force the new package to be detected as newer. Since it
is a new vendor release of the code,
PORTREVISION is reset to 0 (or removed
from the Makefile).PORTNAME= gtkmumble
PORTVERSION= 0.2
PORTEPOCH= 1PKGNAME becomes
gtkmumble-0.2,1The next release is 0.3. Since
PORTEPOCH never decreases, the version
variables are now:PORTNAME= gtkmumble
PORTVERSION= 0.3
PORTEPOCH= 1PKGNAME becomes
gtkmumble-0.3,1If PORTEPOCH were reset
to 0 with this upgrade, someone who had
installed the gtkmumble-0.10_1 package would not detect
the gtkmumble-0.3 package as newer, since
3 is still numerically less than
10. Remember, this is the whole point of
PORTEPOCH in the first place.PKGNAMEPREFIX and PKGNAMESUFFIXTwo optional variables, PKGNAMEPREFIX and
PKGNAMESUFFIX, are combined with
PORTNAME and
PORTVERSION to
form PKGNAME as
${PKGNAMEPREFIX}${PORTNAME}${PKGNAMESUFFIX}-${PORTVERSION}.
Make sure this conforms to our guidelines for a good package
name. In particular, you are not allowed to use a
hyphen (-) in
PORTVERSION. Also, if the package name
has the language- or the
-compiled.specifics part (see below), use
PKGNAMEPREFIX and
PKGNAMESUFFIX, respectively. Do not make
them part of PORTNAME.LATEST_LINK在某些情況,可能會同時存在有不同版本的同一程式。
由於它們可能會有同樣的 PORTNAME、
PKGNAMEPREFIX,甚至
PKGNAMESUFFIX 也相同,所以得讓這些程式有所不同,
才能讓 port 的 index 以及 package 能順利產生。 遇到這類情況,
the optional LATEST_LINK variable should be set to
a different value for all ports except the main
one — see the editors/vim5 and
editors/vim ports, and the
www/apache* family for examples of its use.
Note that how to choose a main version —
most popular, best supported,
least patched, and so on — is outside the
scope of this handbook's recommendations; we only tell you how to
specify the other ports' versions after you have picked a
main one.Package Naming ConventionsThe following are the conventions you should follow in naming your
packages. This is to have our package directory easy to scan, as
there are already thousands of packages and users are going to
turn away if they hurt their eyes!The package name should look like
language_region-name-compiled.specifics-version.numbers.The package name is defined as
${PKGNAMEPREFIX}${PORTNAME}${PKGNAMESUFFIX}-${PORTVERSION}.
Make sure to set the variables to conform to that format.FreeBSD strives to support the native language of its users.
The language- part should be a two
letter abbreviation of the natural language defined by ISO-639 if
the port is specific to a certain language. Examples are
ja for Japanese, ru for
Russian, vi for Vietnamese,
zh for Chinese, ko for
Korean and de for German.If the port is specific to a certain region within the
language area, add the two letter country code as well.
Examples are en_US for US English and
fr_CH for Swiss French.The language- part should
be set in the PKGNAMEPREFIX variable.The first letter of the name part
should be lowercase. (The rest of the name may contain
capital letters, so use your own discretion when you are
converting a software name that has some capital letters in it.)
There is a tradition of naming Perl 5 modules by
prepending p5- and converting the double-colon
separator to a hyphen; for example, the
Data::Dumper module becomes
p5-Data-Dumper.Make sure that the port's name and version are clearly
separated and placed into the PORTNAME and
PORTVERSION variables. The only reason for
PORTNAME to contain a version part is if
the upstream distribution is really named that way, as in
the textproc/libxml2 or
japanese/kinput2-freewnn ports. Otherwise,
the PORTNAME should not contain any
version-specific information. It is quite normal for several
ports to have the same PORTNAME, as the
www/apache* ports do; in that case,
different versions (and different index entries) are
distinguished by the PKGNAMEPREFIX,
PKGNAMESUFFIX, and
LATEST_LINK values.If the port can be built with different hardcoded defaults (usually
part of the directory name in a family of ports), the
-compiled.specifics part should state
the compiled-in defaults (the hyphen is optional). Examples are
papersize and font units.The -compiled.specifics part
should be set in the PKGNAMESUFFIX
variable.The version string should follow a dash
(-) and be a period-separated list of
integers and single lowercase alphabetics. In particular,
it is not permissible to have another dash inside the
version string. The only exception is the string
pl (meaning patchlevel), which can be
used only when there are no major and
minor version numbers in the software. If the software
version has strings like alpha, beta, rc, or pre, take
the first letter and put it immediately after a period.
If the version string continues after those names, the
numbers should follow the single alphabet without an extra
period between them.The idea is to make it easier to sort ports by looking
at the version string. In particular, make sure version
number components are always delimited by a period, and
if the date is part of the string, use the
yyyy.mm.dd
format, not
dd.mm.yyyy
or the non-Y2K compliant
yy.mm.dd
format.Here are some (real) examples on how to convert the name
as called by the software authors to a suitable package
name:Distribution NamePKGNAMEPREFIXPORTNAMEPKGNAMESUFFIXPORTVERSIONReasonmule-2.2.2(empty)mule(empty)2.2.2No changes requiredEmiClock-1.0.2(empty)emiclock(empty)1.0.2No uppercase names for single programsrdist-1.3alpha(empty)rdist(empty)1.3.aNo strings like alpha
allowedes-0.9-beta1(empty)es(empty)0.9.b1No strings like beta
allowedmailman-2.0rc3(empty)mailman(empty)2.0.r3No strings like rc
allowedv3.3beta021.src(empty)tiff(empty)3.3What the heck was that anyway?tvtwm(empty)tvtwm(empty)pl11Version string always requiredpiewm(empty)piewm(empty)1.0Version string always requiredxvgr-2.10pl1(empty)xvgr(empty)2.10.1pl allowed only when no
major/minor version numbersgawk-2.15.6ja-gawk(empty)2.15.6Japanese language versionpsutils-1.13(empty)psutils-letter1.13Papersize hardcoded at package build timepkfonts(empty)pkfonts3001.0Package for 300dpi fontsIf there is absolutely no trace of version information in the
original source and it is unlikely that the original author will ever
release another version, just set the version string to
1.0 (like the piewm example above). Otherwise, ask
the original author or use the date string
(yyyy.mm.dd)
as the version.CategorizationCATEGORIESWhen a package is created, it is put under
/usr/ports/packages/All and links are made from
one or more subdirectories of
/usr/ports/packages. The names of these
subdirectories are specified by the variable
CATEGORIES. It is intended to make life easier
for the user when he is wading through the pile of packages on the
FTP site or the CDROM. Please take a look at the current list of categories and pick the ones
that are suitable for your port.This list also determines where in the ports tree the port is
imported. If you put more than one category here, it is assumed
that the port files will be put in the subdirectory with the name in
the first category. See below for more
discussion about how to pick the right categories.Current list of categoriesHere is the current list of port categories. Those
marked with an asterisk (*) are
virtual categories—those that do not have
a corresponding subdirectory in the ports tree. They are only
used as secondary categories, and only for search purposes.For non-virtual categories, you will find a one-line
description in the COMMENT in that
subdirectory's Makefile.CategoryDescriptionNotesaccessibilityPorts to help disabled users.afterstep*Ports to support the
AfterStep
window manager.arabicArabic language support.archiversArchiving tools.astroAstronomical ports.audioSound support.benchmarksBenchmarking utilities.biologyBiology-related software.cadComputer aided design tools.chineseChinese language support.commsCommunication software.Mostly software to talk to your serial port.convertersCharacter code converters.databasesDatabases.deskutilsThings that used to be on the desktop before
computers were invented.develDevelopment utilities.Do not put libraries here just because they are
libraries—unless they truly do not belong anywhere
else, they should not be in this category.dnsDNS-related software.editorsGeneral editors.Specialized editors go in the section for those
tools (e.g., a mathematical-formula editor will go
in math).elisp*Emacs-lisp ports.emulatorsEmulators for other operating systems.Terminal emulators do not belong
here—X-based ones should go to
x11 and text-based ones to either
comms or misc,
depending on the exact functionality.financeMonetary, financial and related applications.frenchFrench language support.ftpFTP client and server utilities.If your port speaks both FTP and HTTP, put it in
ftp with a secondary
category of www.games遊戲。geography*地理圖資相關的軟體。german德文相關支援。gnome*Ports from the GNOME
Project.graphics圖形處理的工具軟體。gnustep*GNUstep 桌面環境相關的軟體。hamradio*Software for amateur radio.haskell*Software related to the Haskell language.hebrewHebrew language support.hungarianHungarian language support.ipv6*IPv6 related software.ircInternet Relay Chat utilities.japaneseJapanese language support.javaSoftware related to the Java language.The java category shall not be
the only one for a port. Save for ports directly related to
the Java language, porters are also encouraged not to
use java as the main category of a
port.kde*Ports from the K Desktop Environment (KDE)
Project.kld*Kernel loadable modules。koreanKorean language support.langProgramming languages.linux*Linux applications and support utilities.lisp*Software related to the Lisp language.mailMail software.mathNumerical computation software and other utilities
for mathematics.mboneMBone applications.miscMiscellaneous utilitiesBasically things that
do not belong anywhere else.
If at all possible, try to
find a better category for your port than
misc, as ports tend to get overlooked
in here.multimediaMultimedia software.netMiscellaneous networking software.net-imInstant messaging software.net-mgmtNetworking management software.net-p2pPeer to peer network applications.newsUSENET news software.palmSoftware support for the Palm™ series.parallel*Applications dealing with parallelism in computing.pear*Ports related to the Pear PHP framework.perl5*Ports that require Perl version 5 to run.plan9*Various programs from Plan9.polishPolish language support.ports-mgmtFreeBSD ports 及 packages 的管理、安裝、開發。portuguesePortuguese language support.printPrinting software.Desktop publishing tools
(previewers, etc.) belong here too.python*Software related to the Python language.ruby*Software related to the Ruby language.rubygems*Ports of RubyGems packages.russianRussian language support.scheme*Software related to the Scheme language.scienceScientific ports that do not fit into other
categories such as astro,
biology and
math.securitySecurity utilities.shellsCommand line shells.spanish*西班牙文的相關支援。sysutilsSystem utilities.tcl*使用 Tcl 語言的軟體。tcl80*Ports that use Tcl version 8.0 to run.tcl82*Ports that use Tcl version 8.2 to run.tcl83*Ports that use Tcl version 8.3 to run.tcl84*Ports that use Tcl version 8.4 to run.textprocText processing utilities.It does not include
desktop publishing tools, which go to print.tk*使用 Tk 語言的程式。tk80*Ports that use Tk version 8.0 to run.tk82*Ports that use Tk version 8.2 to run.tk83*Ports that use Tk version 8.3 to run.tk84*Ports that use Tk version 8.4 to run.tkstep80*Ports that use TkSTEP version 8.0 to run.ukrainianUkrainian language support.vietnameseVietnamese language support.windowmaker*Ports to support the WindowMaker window
manager.wwwSoftware related to the World Wide Web.HTML language
support belongs here too.x11The X Window System and friends.This category is only
for software that directly supports the window system. Do not
put regular X applications here; most of them should go
into other x11-* categories (see below).
If your port is an X
application, define USE_XLIB (implied by
USE_IMAKE) and put it in the appropriate
category.x11-clocksX11 clocks.x11-driversX11 驅動程式。x11-fmX11 file managers.x11-fontsX11 fonts and font utilities.x11-serversX11 servers.x11-themesX11 themes.x11-toolkitsX11 toolkits.x11-wmX11 window managers.xfce*Xfce
桌面環境的相關軟體。zope*Zope support.Choosing the right categoryAs many of the categories overlap, you often have to choose
which of the categories should be the primary category of your port.
There are several rules that govern this issue. Here is the list of
priorities, in decreasing order of precedence:The first category must be a physical category (see
above). This is
necessary to make the packaging work. Virtual categories and
physical categories may be intermixed after that.Language specific categories always come first. For
example, if your port installs Japanese X11 fonts, then your
CATEGORIES line would read japanese
x11-fonts.Specific categories are listed before less-specific ones. For
instance, an HTML editor should be listed as www
editors, not the other way around. Also, you should not
list net when the port belongs to
any of irc, mail,
mbone, news,
security, or www, as
net is included implicitly.x11 is used as a secondary category only
when the primary category is a natural language. In particular,
you should not put x11 in the category line
for X applications.Emacs modes should be
placed in the same ports category as the application
supported by the mode, not in
editors. For example, an
Emacs mode to edit source
files of some programming language should go into
lang.
會安裝 kernel loadable modules 的 port 請在
CATEGORIES 內加上 kld
這個虛擬目錄。misc
should not appear with any other non-virtual category.
If you have misc with something else in
your CATEGORIES line, that means you can
safely delete misc and just put the port
in that other subdirectory!If your port truly does not belong anywhere else, put it in
misc.If you are not sure about the category, please put a comment to
that effect in your &man.send-pr.1; submission so we can
discuss it before we import it. If you are a committer, send a note
to the &a.ports; so we can discuss it first. Too often, new ports are
imported to the wrong category only to be moved right away.
This causes unnecessary and undesirable bloat in the master
source repository.Proposing a new categoryAs the Ports Collection has grown over time, various new
categories have been introduced. New categories can either
be virtual categories—those that do
not have a corresponding subdirectory in the ports tree—
or physical categories—those that
do. The following text discusses the issues involved in creating
a new physical category so that you can understand them before
you propose one.Our existing practice has been to avoid creating a new
physical category unless either a large number of ports would
logically belong to it, or the ports that would belong to it
are a logically distinct group that is of limited general
interest (for instance, categories related to spoken human
languages), or preferably both.The rationale for this is that such a change creates a
fair amount of work for both the committers and also
for all users who track changes to the Ports Collection. In
addition, proposed category changes just naturally seem to
attract controversy. (Perhaps this is because there is no
clear consensus on when a category is too big,
nor whether categories should lend themselves to browsing (and
thus what number of categories would be an ideal number), and
so forth.)Here is the procedure:Propose the new category on &a.ports;. You should
include a detailed rationale for the new category,
including why you feel the existing categories are not
sufficient, and the list of existing ports proposed to move.
(If there are new ports pending in
GNATS that would fit this
category, list them too.) If you are the maintainer and/or
submitter, respectively, mention that as it may help you
to make your case.Participate in the discussion.If it seems that there is support for your idea,
file a PR which includes both the rationale and the list
of existing ports that need to be moved. Ideally, this
PR should also include patches for the following:Makefiles for the
new ports once they are repocopiedMakefile for the
new categoryMakefile for the
old ports' categoriesMakefiles for ports
that depend on the old ports(for extra credit, you can include the other
files that have to change, as per the procedure
in the Committer's Guide.)Since it affects the ports infrastructure and involves
not only performing repo-copies but also possibly running
regression tests on the build cluster, the PR should be
assigned to the &a.portmgr;.If that PR is approved, a committer will need to follow
the rest of the procedure that is
outlined in the Committer's Guide.Proposing a new virtual category should be similar to
the above but much less involved, since no ports will
actually have to move. In this case, the only patches to
include in the PR would be those to add the new category to the
CATEGORIES of the affected ports.Proposing reorganizing all the categoriesOccasionally someone proposes reorganizing the categories
with either a 2-level structure, or some other kind of keyword
structure. To date, nothing has come of any of these proposals
because, while they are very easy to make, the effort involved to
retrofit the entire existing ports collection with any kind of
reorganization is daunting to say the very least. Please read
the history of these proposals in the mailing list archives before
you post this idea; furthermore, you should be prepared to be
challenged to offer a working prototype.The distribution filesThe second part of the Makefile describes the
files that must be downloaded in order to build the port, and where
they can be downloaded from.DISTVERSION/DISTNAMEDISTNAME is the name of the port as
called by the authors of the software.
DISTNAME defaults to
${PORTNAME}-${PORTVERSION}, so override it only if necessary.
DISTNAME is only used in two places.
First, the distribution file list
(DISTFILES) defaults to
${DISTNAME}${EXTRACT_SUFX}.
Second, the distribution file is expected to extract into a
subdirectory named WRKSRC, which defaults
to work/${DISTNAME}.Some vendor's distribution names which do not fit into the
${PORTNAME}-${PORTVERSION}-scheme can be handled
automatically by setting DISTVERSION.
PORTVERSION and DISTNAME will be
derived automatically, but can of course be overridden. The following
table lists some examples:DISTVERSIONPORTVERSION0.7.1d0.7.1.d10Alpha310.a33Beta7-pre23.b7.p28:f_178f.17PKGNAMEPREFIX and
PKGNAMESUFFIX do not affect
DISTNAME. Also note that if
WRKSRC is equal to
work/${PORTNAME}-${PORTVERSION}
while the original source archive is named something other than
${PORTNAME}-${PORTVERSION}${EXTRACT_SUFX},
you should probably leave DISTNAME
alone— you are better off defining
DISTFILES than having to set both
DISTNAME and WRKSRC
(and possibly EXTRACT_SUFX).MASTER_SITESRecord the directory part of the FTP/HTTP-URL pointing at the
original tarball in MASTER_SITES. Do not forget
the trailing slash (/)!The make macros will try to use this
specification for grabbing the distribution file with
FETCH if they cannot find it already on the
system.It is recommended that you put multiple sites on this list,
preferably from different continents. This will safeguard against
wide-area network problems. We are even planning to add support
for automatically determining the closest master site and fetching
from there; having multiple sites will go a long way towards
helping this effort.If the original tarball is part of one of the popular
archives such as X-contrib, GNU, or Perl CPAN, you may be able
refer to those sites in an easy compact form using
MASTER_SITE_*
(比如:MASTER_SITE_XCONTRIB、
MASTER_SITE_GNU、
MASTER_SITE_PERL_CPAN)。 Simply set
MASTER_SITES to one of these variables and
MASTER_SITE_SUBDIR to the path within the
archive. Here is an example:MASTER_SITES= ${MASTER_SITE_XCONTRIB}
MASTER_SITE_SUBDIR= applicationsThese variables are defined in
/usr/ports/Mk/bsd.sites.mk. There are
new entries added all the time, so make sure to check the
latest version of this file before submitting a port.The user can also set the MASTER_SITE_*
variables in /etc/make.conf to override our
choices, and use their favorite mirrors of these popular archives
instead.EXTRACT_SUFXIf you have one distribution file, and it uses an odd suffix to
indicate the compression mechanism, set
EXTRACT_SUFX.For example, if the distribution file was named
foo.tgz instead of the more normal
foo.tar.gz, you would write:DISTNAME= foo
EXTRACT_SUFX= .tgzThe USE_BZIP2 and USE_ZIP
variables automatically set EXTRACT_SUFX to
.tar.bz2 or .zip as necessary. If
neither of these are set then EXTRACT_SUFX
defaults to .tar.gz.You never need to set both EXTRACT_SUFX and
DISTFILES.DISTFILESSometimes the names of the files to be downloaded have no
resemblance to the name of the port. For example, it might be
called source.tar.gz or similar. In other
cases the application's source code might be in several different
archives, all of which must be downloaded.If this is the case, set DISTFILES to be a
space separated list of all the files that must be
downloaded.DISTFILES= source1.tar.gz source2.tar.gzIf not explicitly set, DISTFILES defaults to
${DISTNAME}${EXTRACT_SUFX}.EXTRACT_ONLYIf only some of the DISTFILES must be
extracted—for example, one of them is the source code, while
another is an uncompressed document—list the filenames that
must be extracted in EXTRACT_ONLY.DISTFILES= source.tar.gz manual.html
EXTRACT_ONLY= source.tar.gzIf none of the DISTFILES
should be uncompressed then set EXTRACT_ONLY to
the empty string.EXTRACT_ONLY=PATCHFILESIf your port requires some additional patches that are available
by FTP or HTTP, set PATCHFILES to the names of
the files and PATCH_SITES to the URL of the
directory that contains them (the format is the same as
MASTER_SITES).If the patch is not relative to the top of the source tree
(i.e., WRKSRC) because it contains some extra
pathnames, set PATCH_DIST_STRIP accordingly. For
instance, if all the pathnames in the patch have an extra
foozolix-1.0/ in front of the filenames, then set
PATCH_DIST_STRIP=-p1.Do not worry if the patches are compressed; they will be
decompressed automatically if the filenames end with
.gz or .Z.If the patch is distributed with some other files, such as
documentation, in a gzip'd tarball, you cannot just use
PATCHFILES. If that is the case, add the name
and the location of the patch tarball to
DISTFILES and MASTER_SITES.
Then, use the EXTRA_PATCHES variable to
point to those files and bsd.port.mk
will automatically apply them for you. In particular, do
not copy patch files into the
PATCHDIR directory—that directory may
not be writable.The tarball will have been extracted alongside the
regular source by then, so there is no need to explicitly extract
it if it is a regular gzip'd or compress'd tarball. If you do the
latter, take extra care not to overwrite something that already
exists in that directory. Also, do not forget to add a command to
remove the copied patch in the pre-clean
target.Multiple distribution files or patches from different
sites and subdirectories
(MASTER_SITES:n)(Consider this to be a somewhat advanced topic;
those new to this document may wish to skip this section at first).
This section has information on the fetching mechanism
known as both MASTER_SITES:n and
MASTER_SITES_NN. We will refer to this
mechanism as MASTER_SITES:n
hereon.A little background first. OpenBSD has a neat feature
inside both DISTFILES and
PATCHFILES variables, both files and
patches can be postfixed with :n
identifiers where n both can be
[0-9] and denote a group designation.
For example:DISTFILES= alpha:0 beta:1In OpenBSD, distribution file alpha
will be associated with variable
MASTER_SITES0 instead of our common
MASTER_SITES and
beta with
MASTER_SITES1.This is a very interesting feature which can decrease
that endless search for the correct download site.Just picture 2 files in DISTFILES and
20 sites in MASTER_SITES, the sites slow
as hell where beta is carried by all
sites in MASTER_SITES, and
alpha can only be found in the 20th
site. It would be such a waste to check all of them if
maintainer knew this beforehand, would it not? Not a good
start for that lovely weekend!Now that you have the idea, just imagine more
DISTFILES and more
MASTER_SITES. Surely our
distfiles survey meister would appreciate the
relief to network strain that this would bring.In the next sections, information will follow on the
FreeBSD implementation of this idea. We improved a bit on
OpenBSD's concept.Simplified informationThis section tells you how to quickly prepare fine
grained fetching of multiple distribution files and
patches from different sites and subdirectories. We
describe here a case of simplified
MASTER_SITES:n usage. This will be
sufficient for most scenarios. However, if you need
further information, you will have to refer to the next
section.Some applications consist of multiple distribution
files that must be downloaded from a number of different
sites. For example,
Ghostscript consists of the
core of the program, and then a large number of driver
files that are used depending on the user's printer. Some
of these driver files are supplied with the core, but many
others must be downloaded from a variety of different
sites.To support this, each entry in
DISTFILES may be followed by a colon
and a tag name. Each site listed in
MASTER_SITES is then followed by a
colon, and the tag that indicates which distribution files
should be downloaded from this site.For example, consider an application with the source
split in two parts, source1.tar.gz
and source2.tar.gz, which must be
downloaded from two different sites. The port's
Makefile would include lines like
.Simplified use of MASTER_SITES:n
with 1 file per siteMASTER_SITES= ftp://ftp.example1.com/:source1 \
ftp://ftp.example2.com/:source2
DISTFILES= source1.tar.gz:source1 \
source2.tar.gz:source2Multiple distribution files can have the same tag.
Continuing the previous example, suppose that there was a
third distfile, source3.tar.gz, that
should be downloaded from
ftp.example2.com. The
Makefile would then be written like
.Simplified use of MASTER_SITES:n
with more than 1 file per siteMASTER_SITES= ftp://ftp.example1.com/:source1 \
ftp://ftp.example2.com/:source2
DISTFILES= source1.tar.gz:source1 \
source2.tar.gz:source2 \
source3.tar.gz:source2Detailed informationOkay, so the previous section example did not reflect
your needs? In this section we will explain in detail how
the fine grained fetching mechanism
MASTER_SITES:n works and how you can
modify your ports to use it.Elements can be postfixed with
:n where
n is
[^:,]+, i.e.,
n could conceptually be any
alphanumeric string but we will limit it to
[a-zA-Z_][0-9a-zA-Z_]+ for
now.Moreover, string matching is case sensitive;
i.e., n is different from
N.However, the following words cannot be used for
postfixing purposes since they yield special meaning:
default, all and
ALL (they are used internally in
item ).
Furthermore, DEFAULT is a special
purpose word (check item ).Elements postfixed with :n
belong to the group n,
:m belong to group
m and so forth.Elements without a postfix are groupless, i.e.,
they all belong to the special group
DEFAULT. If you postfix any
elements with DEFAULT, you are just
being redundant unless you want to have an element
belonging to both DEFAULT and other
groups at the same time (check item ).The following examples are equivalent but the
first one is preferred:MASTER_SITES= alpha
MASTER_SITES= alpha:DEFAULTGroups are not exclusive, an element may belong to
several different groups at the same time and a group
can either have either several different elements or
none at all. Repeated elements within the same group
will be simply that, repeated elements.When you want an element to belong to several
groups at the same time, you can use the comma
operator (,).Instead of repeating it several times, each time
with a different postfix, we can list several groups
at once in a single postfix. For instance,
:m,n,o marks an element that
belongs to group m,
n and o.All the following examples are equivalent but the
last one is preferred:MASTER_SITES= alpha alpha:SOME_SITE
MASTER_SITES= alpha:DEFAULT alpha:SOME_SITE
MASTER_SITES= alpha:SOME_SITE,DEFAULT
MASTER_SITES= alpha:DEFAULT,SOME_SITEAll sites within a given group are sorted
according to MASTER_SORT_AWK. All
groups within MASTER_SITES and
PATCH_SITES are sorted as
well.Group semantics can be used in any of the
following variables MASTER_SITES,
PATCH_SITES,
MASTER_SITE_SUBDIR,
PATCH_SITE_SUBDIR,
DISTFILES, and
PATCHFILES according to the
following syntax:All MASTER_SITES,
PATCH_SITES,
MASTER_SITE_SUBDIR and
PATCH_SITE_SUBDIR elements must
be terminated with the forward slash
/ character. If any elements
belong to any groups, the group postfix
:n
must come right after the terminator
/. The
MASTER_SITES:n mechanism relies
on the existence of the terminator
/ to avoid confusing elements
where a :n is a valid part of
the element with occurrences where
:n denotes group
n. For compatibility purposes,
since the / terminator was not
required before in both
MASTER_SITE_SUBDIR and
PATCH_SITE_SUBDIR elements, if
the postfix immediate preceding character is not
a / then :n
will be considered a valid part of the element
instead of a group postfix even if an element is
postfixed with :n. See both
and .Detailed use of
MASTER_SITES:n in
MASTER_SITE_SUBDIRMASTER_SITE_SUBDIR= old:n new/:NEWDirectories within group
DEFAULT -> old:nDirectories within group
NEW -> newDetailed use of
MASTER_SITES:n with comma
operator, multiple files, multiple sites and
multiple subdirectoriesMASTER_SITES= http://site1/%SUBDIR%/ http://site2/:DEFAULT \
http://site3/:group3 http://site4/:group4 \
http://site5/:group5 http://site6/:group6 \
http://site7/:DEFAULT,group6 \
http://site8/%SUBDIR%/:group6,group7 \
http://site9/:group8
DISTFILES= file1 file2:DEFAULT file3:group3 \
file4:group4,group5,group6 file5:grouping \
file6:group7
MASTER_SITE_SUBDIR= directory-trial:1 directory-n/:groupn \
directory-one/:group6,DEFAULT \
directoryThe previous example results in the
following fine grained fetching. Sites are
listed in the exact order they will be
used.file1 will be
fetched fromMASTER_SITE_OVERRIDEhttp://site1/directory-trial:1/http://site1/directory-one/http://site1/directory/http://site2/http://site7/MASTER_SITE_BACKUPfile2 will be
fetched exactly as
file1 since they
both belong to the same groupMASTER_SITE_OVERRIDEhttp://site1/directory-trial:1/http://site1/directory-one/http://site1/directory/http://site2/http://site7/MASTER_SITE_BACKUPfile3 will be
fetched fromMASTER_SITE_OVERRIDEhttp://site3/MASTER_SITE_BACKUPfile4 will be
fetched fromMASTER_SITE_OVERRIDEhttp://site4/http://site5/http://site6/http://site7/http://site8/directory-one/MASTER_SITE_BACKUPfile5 will be
fetched fromMASTER_SITE_OVERRIDEMASTER_SITE_BACKUPfile6 will be
fetched fromMASTER_SITE_OVERRIDEhttp://site8/MASTER_SITE_BACKUPHow do I group one of the special variables from
bsd.sites.mk, e.g.,
MASTER_SITE_SOURCEFORGE?See .Detailed use of
MASTER_SITES:n with
MASTER_SITE_SOURCEFORGEMASTER_SITES= http://site1/ ${MASTER_SITE_SOURCEFORGE:S/$/:sourceforge,TEST/}
DISTFILES= something.tar.gz:sourceforgesomething.tar.gz will be
fetched from all sites within
MASTER_SITE_SOURCEFORGE.How do I use this with PATCH*
variables?All examples were done with
MASTER* variables but they work
exactly the same for PATCH* ones as
can be seen in .Simplified use of
MASTER_SITES:n with
PATCH_SITES.PATCH_SITES= http://site1/ http://site2/:test
PATCHFILES= patch1:testWhat does change for ports? What does not?All current ports remain the same. The
MASTER_SITES:n feature code is only
activated if there are elements postfixed with
:n like
elements according to the aforementioned syntax rules,
especially as shown in item .The port targets remain the same:
checksum,
makesum,
patch,
configure,
build, etc. With the obvious
exceptions of do-fetch,
fetch-list,
master-sites and
patch-sites.do-fetch: deploys the
new grouping postfixed
DISTFILES and
PATCHFILES with their matching
group elements within both
MASTER_SITES and
PATCH_SITES which use matching
group elements within both
MASTER_SITE_SUBDIR and
PATCH_SITE_SUBDIR. Check .fetch-list: works
like old fetch-list with
the exception that it groups just like
do-fetch.master-sites and
patch-sites:
(incompatible with older versions) only return the
elements of group DEFAULT; in
fact, they execute targets
master-sites-default and
patch-sites-default
respectively.Furthermore, using target either
master-sites-all or
patch-sites-all is
preferred to directly checking either
MASTER_SITES or
PATCH_SITES. Also,
directly checking is not guaranteed to work in any
future versions. Check item
for more information on these new port
targets.New port targetsThere are
master-sites-n
and
patch-sites-n
targets which will list the elements of the
respective group n
within MASTER_SITES and
PATCH_SITES respectively. For
instance, both
master-sites-DEFAULT and
patch-sites-DEFAULT will
return the elements of group
DEFAULT,
master-sites-test and
patch-sites-test of group
test, and thereon.There are new targets
master-sites-all and
patch-sites-all which do
the work of the old
master-sites and
patch-sites ones. They
return the elements of all groups as if they all
belonged to the same group with the caveat that it
lists as many
MASTER_SITE_BACKUP and
MASTER_SITE_OVERRIDE as there
are groups defined within either
DISTFILES or
PATCHFILES; respectively for
master-sites-all and
patch-sites-all.DIST_SUBDIRDo not let your port clutter
/usr/ports/distfiles. If your port requires a
lot of files to be fetched, or contains a file that has a name that
might conflict with other ports (e.g.,
Makefile), set DIST_SUBDIR
to the name of the port (${PORTNAME} or
${PKGNAMEPREFIX}${PORTNAME}
should work fine). This will change
DISTDIR from the default
/usr/ports/distfiles to
/usr/ports/distfiles/DIST_SUBDIR,
and in effect puts everything that is required for your port into
that subdirectory.It will also look at the subdirectory with the same name on the
backup master site at ftp.FreeBSD.org.
(Setting DISTDIR explicitly in your
Makefile will not accomplish this, so please use
DIST_SUBDIR.)This does not affect the MASTER_SITES you
define in your Makefile.ALWAYS_KEEP_DISTFILESIf your port uses binary distfiles and has a license that
requires that the source code is provided with packages distributed
in binary form, e.g. GPL, ALWAYS_KEEP_DISTFILES
will instruct the &os; build cluster to keep a copy of the files
specified in DISTFILES. Users of these ports
will generally not need these files, so it is a good idea to only
add the source distfiles to DISTFILES when
PACKAGE_BUILDING is defined.
Use of ALWAYS_KEEP_DISTFILES..if defined(PACKAGE_BUILDING)
DISTFILES+= foo.tar.gz
ALWAYS_KEEP_DISTFILES= yes
.endifWhen adding extra files to DISTFILES,
make sure you also add them to distinfo.
Also, the additional files will normally be extracted into
WRKDIR as well, which for some ports may
lead to undesirable sideeffects and require special handling.MAINTAINERSet your mail-address here. Please. :-)Note that only a single address without the comment part is
allowed as a MAINTAINER value.
The format used should be user@hostname.domain.
Please do not include any descriptive text such as your real
name in this entry—that merely confuses
bsd.port.mk.The maintainer is responsible for keeping the port up to
date, and ensuring the port works correctly.
For a detailed description of the responsibilities of a port
maintainer, refer to the The
challenge for port maintainers section.Changes to the port will be sent to the maintainer of
a port for a review and an approval before being committed.
If the maintainer does not respond to an update
request after two weeks (excluding major public
holidays), then that is considered a maintainer timeout, and the
update may be made without explicit maintainer approval. If the
maintainer does not respond within three months, then that
maintainer is considered absent without leave, and can be
replaced as the maintainer of the particular port in question.
Exceptions to this are anything maintained by the &a.portmgr;, or
the &a.security-officer;. No unauthorized commits may ever be
made to ports maintained by those groups.We reserve the right to modify the maintainer's submission
to better match existing policies and style of the Ports
Collection without explicit blessing from the submitter.
Also, large infrastructural changes can result in
a port being modified without maintainer's consent.
This kind of changes will never affect the port's
functionality.The &a.portmgr; reserves the right to revoke or override
anyone's maintainership for any reason, and the &a.security-officer;
reserves the right to revoke or override maintainership for security
reasons.COMMENTThis is a one-line description of the port.
Please do not include the package name (or
version number of the software) in the comment. The comment
should begin with a capital and end without a period. Here
is an example:COMMENT= A cat chasing a mouse all over the screenThe COMMENT variable should immediately follow the MAINTAINER
variable in the Makefile.Please try to keep the COMMENT line less than 70
characters, as it is displayed to users as a one-line
summary of the port.DependenciesMany ports depend on other ports. There are seven variables that
you can use to ensure that all the required bits will be on the
user's machine. There are also some pre-supported dependency
variables for common cases, plus a few more to control the behavior
of dependencies.LIB_DEPENDSThis variable specifies the shared libraries this port depends
on. It is a list of
lib:dir:target
tuples where lib is the name of the
shared library, dir is the
directory in which to find it in case it is not available, and
target is the target to call in that
directory. For example,
LIB_DEPENDS= jpeg.9:${PORTSDIR}/graphics/jpeg
will check for a shared jpeg library with major version 9, and
descend into the graphics/jpeg subdirectory
of your ports tree to build and install it if it is not found.
The target part can be omitted if it is
equal to DEPENDS_TARGET (which defaults to
install).The lib part is a regular
expression which is being looked up in the
ldconfig -r output. Values such as
intl.[5-7] and intl are
allowed. The first pattern,
intl.[5-7], will match any of:
intl.5, intl.6 or
intl.7. The second pattern,
intl, will match any version of the
intl library.The dependency is checked twice, once from within the
extract target and then from within the
install target. Also, the name of the
dependency is put into the package so that
&man.pkg.add.1; will automatically install it if it is
not on the user's system.RUN_DEPENDSThis variable specifies executables or files this port depends
on during run-time. It is a list of
path:dir:target
tuples where path is the name of the
executable or file, dir is the
directory in which to find it in case it is not available, and
target is the target to call in that
directory. If path starts with a slash
(/), it is treated as a file and its existence
is tested with test -e; otherwise, it is
assumed to be an executable, and which -s is
used to determine if the program exists in the search path.For example,RUN_DEPENDS= ${LOCALBASE}/etc/innd:${PORTSDIR}/news/inn \
wish8.0:${PORTSDIR}/x11-toolkits/tk80will check if the file or directory
/usr/local/etc/innd exists, and build and
install it from the news/inn subdirectory of
the ports tree if it is not found. It will also see if an
executable called wish8.0 is in the search
path, and descend into the x11-toolkits/tk80
subdirectory of your ports tree to build and install it if it is
not found.In this case, innd is actually an
executable; if an executable is in a place that is not expected
to be in the search path, you should use the full
pathname.The official search PATH used on the ports
build cluster is/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/binThe dependency is checked from within the
install target. Also, the name of the
dependency is put into the package so that
&man.pkg.add.1; will automatically install it if it is
not on the user's system. The target
part can be omitted if it is the same as
DEPENDS_TARGET.BUILD_DEPENDSThis variable specifies executables or files this port
requires to build. Like RUN_DEPENDS, it is a
list of
path:dir:target
tuples. For example, BUILD_DEPENDS=
unzip:${PORTSDIR}/archivers/unzip will check
for an executable called unzip, and descend
into the archivers/unzip subdirectory of your
ports tree to build and install it if it is not found.build here means everything from extraction to
compilation. The dependency is checked from within the
extract target. The
target part can be omitted if it is
the same as DEPENDS_TARGETFETCH_DEPENDSThis variable specifies executables or files this port
requires to fetch. Like the previous two, it is a list of
path:dir:target
tuples. For example, FETCH_DEPENDS=
ncftp2:${PORTSDIR}/net/ncftp2 will check for an
executable called ncftp2, and descend into the
net/ncftp2 subdirectory of your ports tree to
build and install it if it is not found.The dependency is checked from within the
fetch target. The
target part can be omitted if it is the
same as DEPENDS_TARGET.EXTRACT_DEPENDSThis variable specifies executables or files this port
requires for extraction. Like the previous, it is a list of
path:dir:target
tuples. For example, EXTRACT_DEPENDS=
unzip:${PORTSDIR}/archivers/unzip will check
for an executable called unzip, and descend
into the archivers/unzip subdirectory of
your ports tree to build and install it if it is not found.The dependency is checked from within the
extract target. The
target part can be omitted if it is the
same as DEPENDS_TARGET.Use this variable only if the extraction does not already
work (the default assumes gzip) and cannot
be made to work using USE_ZIP or
USE_BZIP2 described in .PATCH_DEPENDSThis variable specifies executables or files this port
requires to patch. Like the previous, it is a list of
path:dir:target
tuples. For example, PATCH_DEPENDS=
${NONEXISTENT}:${PORTSDIR}/java/jfc:extract
will descend into the
java/jfc subdirectory of your ports tree to
extract it.The dependency is checked from within the
patch target. The
target part can be omitted if it is the
same as DEPENDS_TARGET.USE_*A number of variables exist in order to encapsulate common
dependencies that many ports have. Although their use is
optional, they can help to reduce the verbosity of the port
Makefiles. Each of them is styled
as USE_*. The
usage of these variables is restricted to the port
Makefiles and
ports/Mk/bsd.*.mk and is not designed
to encapsulate user-settable options — use
WITH_* and
WITHOUT_*
for that purpose.It is always incorrect to set
any USE_*
in /etc/make.conf. For instance,
setting USE_GCC=3.2
would adds a dependency on gcc32 for every port,
including gcc32 itself!
The USE_*
variablesVariableMeansUSE_BZIP2The port's tarballs are compressed with
bzip2.USE_ZIPThe port's tarballs are compressed with
zip.USE_BISONThe port uses bison for
building.USE_CDRTOOLS該 port 需要 cdrecord,
無論是 sysutils/cdrtools 或 sysutils/cdrtools-cjk 哪一種的
cdrecord 皆可,視使用者偏好而定
。USE_GCCThe port requires a specific version of
gcc to build. The exact version can be
specified with value such as 3.2.
The minimal required version can be specified as
3.2+. The gcc from
the base system is used when it satisfies the requested
version, otherwise an appropriate gcc is
compiled from ports and the CC and
CXX variables are adjusted.
Variables related to gmake and
the configure script are described in
, while
autoconf,
automake and
libtool are described in
. Perl
related variables are described in .
X11 variables are listed in . deals with GNOME and with KDE related variables. documents Java variables, while contains information on
Apache, PHP
and PEAR modules. Python is discussed
in , while
Ruby in .
provides variables used for
SDL applications and finally,
contains information on
Xfce.Minimal version of a dependencyA minimal version of a dependency can be specified in any
*_DEPENDS variable except
LIB_DEPENDS using the following
syntax:p5-Spiffy>=0.26:${PORTSDIR}/devel/p5-SpiffyThe first field contains a dependent package name,
which must match the entry in the package database,
a comparison sign, and a package version. The dependency
is satisfied if p5-Spiffy-0.26 or newer is installed on
the machine.Notes on dependenciesAs mentioned above, the default target to call when a
dependency is required is DEPENDS_TARGET.
It defaults to install. This is a user
variable; it is never defined in a port's
Makefile. If your port needs a special way
to handle a dependency, use the :target part of
the *_DEPENDS variables instead of redefining
DEPENDS_TARGET.When you type make clean, its dependencies
are automatically cleaned too. If you do not wish this to happen,
define the variable NOCLEANDEPENDS in your
environment. This may be particularly desirable if the port
has something that takes a long time to rebuild in its
dependency list, such as KDE, GNOME or Mozilla.To depend on another port unconditionally, use the
variable ${NONEXISTENT} as the first field
of BUILD_DEPENDS or
RUN_DEPENDS. Use this only when you need to
get the source of the other port. You can often save
compilation time by specifying the target too. For
instance
BUILD_DEPENDS= ${NONEXISTENT}:${PORTSDIR}/graphics/jpeg:extract
will always descend to the jpeg port and extract it.Circular dependencies are fatalDo not introduce any circular dependencies into the
ports tree!The ports building technology does not tolerate
circular dependencies. If you introduce one, you will have
someone, somewhere in the world, whose FreeBSD installation will
break almost immediately, with many others quickly to follow.
These can really be hard to detect; if in doubt, before
you make that change, make sure you have done the following:
cd /usr/ports; make index. That process
can be quite slow on older machines, but you may be able to
save a large number of people—including yourself—
a lot of grief in the process.MASTERDIRIf your port needs to build slightly different versions of
packages by having a variable (for instance, resolution, or paper
size) take different values, create one subdirectory per package to
make it easier for users to see what to do, but try to share as many
files as possible between ports. Typically you only need a very short
Makefile in all but one of the directories if you
use variables cleverly. In the sole Makefile,
you can use MASTERDIR to specify the directory
where the rest of the files are. Also, use a variable as part of
PKGNAMESUFFIX so
the packages will have different names.This will be best demonstrated by an example. This is part of
japanese/xdvi300/Makefile;PORTNAME= xdvi
PORTVERSION= 17
PKGNAMEPREFIX= ja-
PKGNAMESUFFIX= ${RESOLUTION}
:
# default
RESOLUTION?= 300
.if ${RESOLUTION} != 118 && ${RESOLUTION} != 240 && \
${RESOLUTION} != 300 && ${RESOLUTION} != 400
@${ECHO_MSG} "Error: invalid value for RESOLUTION: \"${RESOLUTION}\""
@${ECHO_MSG} "Possible values are: 118, 240, 300 (default) and 400."
@${FALSE}
.endifjapanese/xdvi300 also has all the regular
patches, package files, etc. If you type make
there, it will take the default value for the resolution (300) and
build the port normally.As for other resolutions, this is the entirexdvi118/Makefile:RESOLUTION= 118
MASTERDIR= ${.CURDIR}/../xdvi300
.include "${MASTERDIR}/Makefile"(xdvi240/Makefile and
xdvi400/Makefile are similar). The
MASTERDIR definition tells
bsd.port.mk that the regular set of
subdirectories like FILESDIR and
SCRIPTDIR are to be found under
xdvi300. The RESOLUTION=118
line will override the RESOLUTION=300 line in
xdvi300/Makefile and the port will be built with
resolution set to 118.ManpagesThe MAN[1-9LN] variables will automatically add
any manpages to pkg-plist (this means you must
not list manpages in the
pkg-plist—see generating PLIST for more). It also
makes the install stage automatically compress or uncompress manpages
depending on the setting of NOMANCOMPRESS in
/etc/make.conf.If your port tries to install multiple names for manpages using
symlinks or hardlinks, you must use the MLINKS
variable to identify these. The link installed by your port will
be destroyed and recreated by bsd.port.mk
to make sure it points to the correct file. Any manpages
listed in MLINKS must not be listed in the
pkg-plist.To specify whether the manpages are compressed upon installation,
use the MANCOMPRESSED variable. This variable can
take three values, yes, no and
maybe. yes means manpages are
already installed compressed, no means they are
not, and maybe means the software already respects
the value of NOMANCOMPRESS so
bsd.port.mk does not have to do anything
special.MANCOMPRESSED is automatically set to
yes if USE_IMAKE is set and
NO_INSTALL_MANPAGES is not set, and to
no otherwise. You do not have to explicitly define
it unless the default is not suitable for your port.If your port anchors its man tree somewhere other than
MANPREFIX, you can use the
MANPREFIX to set it. Also, if only manpages in
certain sections go in a non-standard place, such as some perl modules
ports, you can set individual man paths using
MANsectPREFIX (where
sect is one of 1-9,
L or N).If your manpages go to language-specific subdirectories, set the
name of the languages to MANLANG. The value of
this variable defaults to "" (i.e., English
only).Here is an example that puts it all together.MAN1= foo.1
MAN3= bar.3
MAN4= baz.4
MLINKS= foo.1 alt-name.8
MANLANG= "" ja
MAN3PREFIX= ${PREFIX}/share/foobar
MANCOMPRESSED= yesThis states that six files are installed by this port;${MANPREFIX}/man/man1/foo.1.gz
${MANPREFIX}/man/ja/man1/foo.1.gz
${PREFIX}/share/foobar/man/man3/bar.3.gz
${PREFIX}/share/foobar/man/ja/man3/bar.3.gz
${MANPREFIX}/man/man4/baz.4.gz
${MANPREFIX}/man/ja/man4/baz.4.gzAdditionally ${MANPREFIX}/man/man8/alt-name.8.gz
may or may not be installed by your port. Regardless, a
symlink will be made to join the foo(1) manpage and
alt-name(8) manpage.If only some manpages are translated, you can use several variables
dynamically created from MANLANG content:MANLANG= "" de ja
MAN1= foo.1
MAN1_EN= bar.1
MAN3_DE= baz.3This translates into this list of files:${MANPREFIX}/man/man1/foo.1.gz
${MANPREFIX}/man/de/man1/foo.1.gz
${MANPREFIX}/man/ja/man1/foo.1.gz
${MANPREFIX}/man/man1/bar.1.gz
${MANPREFIX}/man/de/man3/baz.3.gzInfo filesIf your package needs to install GNU info files, they should be
listed in the INFO variable (without the trailing
.info), one entry per document. These files
are assumed to be installed to
PREFIX/INFO_PATH.
You can change INFO_PATH if your package uses
a different location. However, this is not recommended. These entries
contain just the path relative to
PREFIX/INFO_PATH.
For example, lang/gcc33 installs
info files to
PREFIX/INFO_PATH/gcc33,
and INFO will be something like this:
INFO= gcc33/cpp gcc33/cppinternals gcc33/g77 ...
Appropriate installation/de-installation code will be automatically
added to the temporary pkg-plist before package
registration.Makefile OptionsSome large applications can be built in a number of
configurations, adding functionality if one of a number of
libraries or applications is available. Examples include
choice of natural (human) language, GUI versus command-line,
or type of database to support. Since not all users
want those libraries or applications, the ports system
provides hooks that the port author can use to control which
configuration should be built. Supporting these properly will
make users happy, and effectively provide 2 or more ports for the
price of one.KnobsWITH_* and
WITHOUT_*These variables are designed to be set by the system
administrator. There are many that are standardized in
ports/Mk/bsd.*.mk; others are not,
which can be confusing. If you need to add such a
configuration variable, please consider using one of the
ones from the following list.You should not assume that a
WITH_*
necessarily has a corresponding
WITHOUT_*
variable and vice versa. In general, the default is
simply assumed.Unless otherwise specified, these variables are only
tested for being set or not set, rather than being set to
some kind of variable such as YES or
NO.
The WITH_*
and WITHOUT_*
variablesVariableMeansWITH_APACHE2If set, use
www/apache20
instead of the default of
www/apache13.WITH_BERKELEY_DBDefine this variable to specify the ability to
use a variant of the Berkeley database package such as
databases/db41.
An associated variable,
WITH_BDB_VER, may be
set to values such as 2, 3, 4, 41 or 42.WITH_MYSQLDefine this variable to specify the ability to
use a variant of the MySQL database package such as
databases/mysql40-server.
An associated variable,
WANT_MYSQL_VER, may be
set to values such as 323, 40, 41, or 50.WITHOUT_NLSIf set, says that internationalization is not
needed, which can save compile time. By default,
internationalization is used.WITH_OPENSSL_BASEUse the version of OpenSSL in the base system.WITH_OPENSSL_PORTUse the version of OpenSSL from
security/openssl,
overwriting the version that was originally installed
in the base system.WITH_POSTGRESQLDefine this variable to specify the ability to
use a variant of the PostGreSQL database package such as
databases/postgresql72.
WITHOUT_X11If the port can be built both with and without
X support, then it should normally be built with
X support. If this variable is defined, then
the version that does not have X support should
be built instead.
Knob namingIt is recommended that porters use like-named knobs, for the
benefit of end-users and to help keep the number of knob names down.
A list of popular knob names can be found in the
KNOBS
file.Knob names should reflect what the knob is and does.
When a port has a lib-prefix in the PORTNAME
the lib-prefix should be dropped in knob naming.OPTIONSBackgroundThe OPTIONS variable gives the user who
installs the port a dialog with the available options and saves
them to /var/db/ports/portname/options.
Next time when the port has to be rebuild, the options are reused.
Never again you will have to remember all the twenty
WITH_* and
WITHOUT_* options you
used to build this port!When the user runs make config (or runs
make build for the first time), the framework will
check for
/var/db/ports/portname/options.
If that file does not exist, it will use the values of
OPTIONS to create a dialogbox where the options
can be enabled or disabled. Then the
options file is saved and the selected
variables will be used when building the port.If a new version of the port adds new
OPTIONS, the dialog will be presented to the
user, with the saved values of old OPTIONS
prefilled.Use make showconfig to see the saved
configuration. Use make rmconfig to remove the
saved configuration.SyntaxThe syntax for the OPTIONS variable is:
OPTIONS= OPTION "descriptive text" default ...
The value for default is either ON or
OFF. Multiple repetitions of these three fields
are allowed.OPTIONS definition must appear before
the inclusion of bsd.port.pre.mk.
The WITH_* and WITHOUT_*
variables can only be tested after the inclusion of
bsd.port.pre.mk.ExampleSimple use of OPTIONSOPTIONS= FOO "Enable option foo" On \
BAR "Support feature bar" Off
.include <bsd.port.pre.mk>
.if defined(WITHOUT_FOO)
CONFIGURE_ARGS+= --without-foo
.else
CONFIGURE_ARGS+= --with-foo
.endif
.if defined(WITH_BAR)
RUN_DEPENDS+= bar:${PORTSDIR}/bar/bar
.endif
.include <bsd.port.post.mk>Feature auto-activationWhen using a GNU configure script, keep an eye on which optional
features are activated by auto-detection. Explicitly disable
optional features you do not wish to be used by passing respective
--without-xxx or --disable-xxx
in CONFIGURE_ARGS.Wrong handling of an option.if defined(WITH_FOO)
LIB_DEPENDS+= foo.0:${PORTSDIR}/devel/foo
CONFIGURE_ARGS+= --enable-foo
.endifIn the example above, imagine a library libfoo is installed on
the system. User does not want this application to use libfoo, so he
toggled the option off in the make config dialog.
But the application's configure script detects the library present in
the system and includes its support in the resulting executable. Now
when user decides to remove libfoo from the system, the ports system
does not protest (no dependency on libfoo was recorded) but the
application breaks.Correct handling of an option.if defined(WITH_FOO)
LIB_DEPENDS+= foo.0:${PORTSDIR}/devel/foo
CONFIGURE_ARGS+= --enable-foo
.else
CONFIGURE_ARGS+= --disable-foo
.endifIn the second example, the library libfoo is explicitly disabled.
The configure script does not enable related features in the
application, despite library's presence in the system.Specifying the working directoryEach port is extracted in to a working directory, which must be
writable. The ports system defaults to having the
DISTFILES unpack in to a directory called
${DISTNAME}. In other words, if you have
set:PORTNAME= foo
PORTVERSION= 1.0then the port's distribution files contain a top-level directory,
foo-1.0, and the rest of the files are located
under that directory.There are a number of variables you can override if that is not the
case.WRKSRCThe variable lists the name of the directory that is created when
the application's distfiles are extracted. If our previous example
extracted into a directory called foo (and not
foo-1.0) you would write:WRKSRC= ${WRKDIR}/fooor possiblyWRKSRC= ${WRKDIR}/${PORTNAME}NO_WRKSUBDIRIf the port does not extract in to a subdirectory at all then
you should set NO_WRKSUBDIR to indicate
that.NO_WRKSUBDIR= yesCONFLICTSIf your package cannot coexist with other packages
(because of file conflicts, runtime incompatibility, etc.),
list the other package names in the CONFLICTS
variable. You can use shell globs like * and
? here. Packages names should be
enumerated the same way they appear in
/var/db/pkg. Please make sure that
CONFLICTS does not match this port's
package itself, or else forcing its installation with
FORCE_PKG_REGISTER will no longer work.
CONFLICTS automatically sets
IGNORE, which is more fully documented
in .When removing one of several conflicting ports, it is advisable to
retain the CONFLICTS entries in those other ports
for a few months to cater for users who only update once in a
while.Installing filesINSTALL_* macrosDo use the macros provided in bsd.port.mk
to ensure correct modes and ownership of files in your own
*-install targets.INSTALL_PROGRAM is a command to install
binary executables.INSTALL_SCRIPT is a command to install
executable scripts.INSTALL_KLD is a command to install
kernel loadable modules. Some architectures don't like it when
the modules are stripped, therefor use this command instead
of INSTALL_PROGRAM.INSTALL_DATA is a command to install
sharable data.INSTALL_MAN is a command to install
manpages and other documentation (it does not compress
anything).These are basically the install command with
all the appropriate flags.Stripping BinariesDo not strip binaries manually unless you have to. All binaries
should be stripped, but the INSTALL_PROGRAM
macro will install and strip a binary at the same time (see the next
section).If you need to strip a file, but do not wish to use the
INSTALL_PROGRAM macro,
${STRIP_CMD} will strip your program. This is
typically done within the post-install
target. For example:post-install:
${STRIP_CMD} ${PREFIX}/bin/xdlUse the &man.file.1; command on the installed executable to
check whether the binary is stripped or not. If it does not say
not stripped, it is stripped. Additionally,
&man.strip.1; will not strip a previously stripped program; it
will instead exit cleanly.Installing a whole tree of filesSometimes, there is a need to install a big number of files,
preserving their hierarchical organization, ie. copying over a whole
directory tree from WRKSRC to a target directory
under PREFIX.Two macros exists for this situation. The advantage of using
these macros instead of cp is that they guarantee
proper file ownership and permissions on target files. First macro,
COPYTREE_BIN, will set all the installed files to
be executable, thus being suitable for installing into
PREFIX/bin. The second
macro, COPYTREE_SHARE, does not set executable
permissions on files, and is therefore suitable for installing files
under PREFIX/share
target.post-install:
${MKDIR} ${EXAMPLESDIR}
(cd ${WRKSRC}/examples/ && ${COPYTREE_SHARE} \* ${EXAMPLESDIR})This example will install the contents of
examples directory in the vendor distfile to the
proper examples location of your port.post-install:
${MKDIR} ${DATADIR}/summer
(cd ${WRKSRC}/temperatures/ && ${COPYTREE_SHARE} "June July August" ${DATADIR}/summer/)And this example will install the data of summer months to the
summer subdirectory of a
DATADIR.Additional find arguments can be passed via
the third argument to the COPYTREE_* macros.
For example, to install all files from the first example except
Makefiles, one can use the following command.post-install:
${MKDIR} ${EXAMPLESDIR}
(cd ${WRKSRC}/examples/ && \
${COPYTREE_SHARE} \* ${EXAMPLESDIR} "! -name Makefile")Note that these macros does not add the installed files to
pkg-plist. You still need to list them.Install additional documentationIf your software has some documentation other than the standard
man and info pages that you think is useful for the user, install it
under PREFIX/share/doc.
This can be done, like the previous item, in the
post-install target.Create a new directory for your port. The directory name should
reflect what the port is. This usually means
PORTNAME. However, if you
think the user might want different versions of the port to be
installed at the same time, you can use the whole
PKGNAME.Make the installation dependent on the variable
NOPORTDOCS so that users can disable it in
/etc/make.conf, like this:post-install:
.if !defined(NOPORTDOCS)
${MKDIR} ${DOCSDIR}
${INSTALL_MAN} ${WRKSRC}/docs/xvdocs.ps ${DOCSDIR}
.endifHere are some handy variables and how they are expanded
by default when used
in the Makefile:DATADIR gets expanded to
PREFIX/share/PORTNAME.DATADIR_REL gets expanded to
share/PORTNAME.DOCSDIR gets expanded to
PREFIX/share/doc/PORTNAME.DOCSDIR_REL gets expanded to
share/doc/PORTNAME.EXAMPLESDIR gets expanded to
PREFIX/share/examples/PORTNAME.EXAMPLESDIR_REL gets expanded to
share/examples/PORTNAME.NOPORTDOCS only controls additional
documentation installed in DOCSDIR. It does not
apply to standard man pages and info pages. Things installed in
DATADIR and EXAMPLESDIR
are controlled by NOPORTDATA and
NOPORTEXAMPLES, respectively.These variables are exported to PLIST_SUB.
Their values will appear there as pathnames relative to
PREFIX if possible.
That is, share/doc/PORTNAME
will be substituted for %%DOCSDIR%%
in the packing list by default, and so on.
(See more on pkg-plist substitution
here.)All conditionally installed documentation files and directories should
be included in pkg-plist with the
%%PORTDOCS%% prefix, for example:%%PORTDOCS%%%%DOCSDIR%%/AUTHORS
%%PORTDOCS%%%%DOCSDIR%%/CONTACT
%%PORTDOCS%%@dirrm %%DOCSDIR%%As an alternative to enumerating the documentation files
in pkg-plist, a port can set the variable
PORTDOCS to a list of file names and shell
glob patterns to add to the final packing list.
The names will be relative to DOCSDIR.
Therefore, a port that utilizes PORTDOCS and
uses a non-default location for its documentation should set
DOCSDIR accordingly.
If a directory is listed in PORTDOCS
or matched by a glob pattern from this variable,
the entire subtree of contained files and directories will be
registered in the final packing list. If NOPORTDOCS
is defined then files and directories listed in
PORTDOCS would not be installed and neither
would be added to port packing list.
Installing the documentation at PORTDOCS
as shown above remains up to the port itself.
A typical example of utilizing PORTDOCS
looks as follows:PORTDOCS= README.* ChangeLog docs/*The equivalents of PORTDOCS for files
installed under DATADIR and
EXAMPLESDIR are PORTDATA
and PORTEXAMPLES, respectively.You can also use the pkg-message file to
display messages upon installation. See the section on using
pkg-message for details.
The pkg-message file does not need to be
added to pkg-plist.Subdirectories under PREFIXTry to let the port put things in the right subdirectories of
PREFIX. Some ports lump everything and put it in
the subdirectory with the port's name, which is incorrect. Also,
many ports put everything except binaries, header files and manual
pages in a subdirectory of lib, which does
not work well with the BSD paradigm. Many of the files should be
moved to one of the following: etc
(setup/configuration files), libexec
(executables started internally), sbin
(executables for superusers/managers), info
(documentation for info browser) or share
(architecture independent files). See &man.hier.7; for details;
the rules governing
/usr pretty much apply to
/usr/local too. The exception are ports
dealing with USENET news. They may use
PREFIX/news as a destination
for their files.Special considerationsThere are some more things you have to take into account when you
create a port. This section explains the most common of those.Shared LibrariesIf your port installs one or more shared libraries, define a
USE_LDCONFIG make variable, which will instruct
a bsd.port.mk to run
${LDCONFIG} -m on the directory where the
new library is installed (usually
PREFIX/lib) during
post-install target to register it into the
shared library cache. This variable, when defined, will also
facilitate addition of an appropriate
@exec /sbin/ldconfig -m and
@unexec /sbin/ldconfig -R pair into your
pkg-plist file, so that a user who installed
the package can start using the shared library immediately and
de-installation will not cause the system to still believe the
library is there.USE_LDCONFIG= yesIf you need, you can override the default directory
by setting the USE_LDCONFIG
value to a list of directories into which
shared libraries are to be installed. For example if your port
installs shared libraries into
PREFIX/lib/foo and
PREFIX/lib/bar directories
you could use the following in your
Makefile:USE_LDCONFIG= ${PREFIX}/lib/foo ${PREFIX}/lib/barPlease
double-check, often this is not necessary at all or can be avoided
through -rpath or setting LD_RUN_PATH
during linking (see lang/moscow_ml
for an example), or through a shell-wrapper which sets
LD_LIBRARY_PATH before invoking the binary, like
www/mozilla does.When installing 32-bit libraries on 64-bit system, use
USE_LDCONFIG32 instead.Try to keep shared library version numbers in the
libfoo.so.0 format. Our runtime linker only
cares for the major (first) number.When the major library version number increments in the update
to the new port version, all other ports that link to the affected
library should have their PORTREVISION incremented,
to force recompilation with the new library version.Ports with distribution restrictionsLicenses vary, and some of them place restrictions on how the
application can be packaged, whether it can be sold for profit, and so
on.It is your responsibility as a porter to read the licensing
terms of the software and make sure that the FreeBSD project will
not be held accountable for violating them by redistributing the
source or compiled binaries either via FTP/HTTP or CD-ROM. If in doubt,
please contact the &a.ports;.In situations like this, the variables described in the following
sections can be set.NO_PACKAGEThis variable indicates that we may not generate a binary
package of the application. For instance, the license may
disallow binary redistribution, or it may prohibit distribution
of packages created from patched sources.However, the port's DISTFILES may be
freely mirrored on FTP/HTTP. They may also be distributed on
a CD-ROM (or similar media) unless NO_CDROM
is set as well.NO_PACKAGE should also be used if the binary
package is not generally useful, and the application should always
be compiled from the source code. For example, if the application
has configuration information that is site specific hard coded in to
it at compile time, set NO_PACKAGE.NO_PACKAGE should be set to a string
describing the reason why the package should not be
generated.NO_CDROMThis variable alone indicates that, although we are allowed
to generate binary packages, we may put neither those packages
nor the port's DISTFILES onto a CD-ROM (or
similar media) for resale. However, the binary packages and
the port's DISTFILES will still be available
via FTP/HTTP.If this variable is set along with
NO_PACKAGE, then only the port's
DISTFILES will be available, and only via
FTP/HTTP.NO_CDROM should be set to a string
describing the reason why the port cannot be redistributed
on CD-ROM. For instance, this should be used if the port's license
is for non-commercial use only.NOFETCHFILESFiles defined in the NOFETCHFILES
variable are not fetchable from any of the
MASTER_SITES. An example of such a
file is when the file is supplied on CD-ROM by the
vendor.Tools which check for the availability of these files
on the MASTER_SITES should ignore these
files and not report about them.RESTRICTEDSet this variable alone if the application's license permits
neither mirroring the application's DISTFILES
nor distributing the binary package in any way.NO_CDROM or NO_PACKAGE
should not be set along with RESTRICTED
since the latter variable implies the former ones.RESTRICTED should be set to a string
describing the reason why the port cannot be redistributed.
Typically, this indicates that the port contains proprietary
software and that the user will need to manually download the
DISTFILES, possibly after registering for the
software or agreeing to accept the terms of an
EULA.RESTRICTED_FILESWhen RESTRICTED or NO_CDROM
is set, this variable defaults to ${DISTFILES}
${PATCHFILES}, otherwise it is empty. If only some of the
distribution files are restricted, then set this variable to list
them.Note that the port committer should add an entry to
/usr/ports/LEGAL for every listed distribution
file, describing exactly what the restriction entails.Building mechanismsmake, gmake, and
imakeIf your port uses GNU make, set
USE_GMAKE=yes.
Variables for ports related to gmakeVariableMeansUSE_GMAKEThe port requires gmake to
build.GMAKEThe full path for gmake if it is not
in the PATH.
If your port is an X application that creates
Makefile files from
Imakefile files using
imake, then set
USE_IMAKE=yes. This will cause the
configure stage to automatically do an xmkmf -a.
If the flag is a problem for your port, set
XMKMF=xmkmf. If the port uses
imake but does not understand the
install.man target,
NO_INSTALL_MANPAGES=yes should be set.If your port's source Makefile has
something else than all as the main build
target, set ALL_TARGET accordingly. Same goes
for install and
INSTALL_TARGET.configure scriptIf your port uses the configure script to
generate Makefile files from
Makefile.in files, set
GNU_CONFIGURE=yes. If you want to give extra
arguments to the configure script (the default
argument is --prefix=${PREFIX}
--infodir=${PREFIX}/${INFO_PATH}
--mandir=${MANPREFIX}/man
${CONFIGURE_TARGET}), set those
extra arguments in CONFIGURE_ARGS. Extra
environment variables can be passed using
CONFIGURE_ENV variable.If your package uses GNU configure, and
the resulting executable file has a strange name
like
i386-portbld-freebsd4.7-appname,
you will need to additionally override the
CONFIGURE_TARGET variable to specify the
target in the way required by scripts generated by recent
versions of autoconf. Add the following line
immediately after the GNU_CONFIGURE=yes line
in your Makefile:CONFIGURE_TARGET=--build=${MACHINE_ARCH}-portbld-freebsd${OSREL}
Variables for ports that use configureVariableMeansGNU_CONFIGUREThe port uses configure script to
prepare build.HAS_CONFIGURESame as GNU_CONFIGURE, except
default configure target is not added to
CONFIGURE_ARGS.CONFIGURE_ARGSAdditional arguments passed to
configure script.CONFIGURE_ENVAdditional environment variables to be set
for configure script run.CONFIGURE_TARGETOverride default configure target. Default value is
${MACHINE_ARCH}-portbld-freebsd${OSREL}.
Using sconsIf your port uses SCons, define
USE_SCONS=yes.
Variables for ports that use sconsVariableMeansSCONS_ARGSPort specific SCons flags passed to the SCons
environment.SCONS_BUILDENVVariables to be set in system environment.SCONS_ENVVariables to be set in SCons environment.SCONS_TARGETLast argument passed to SCons, similar to
MAKE_TARGET.
Using GNU autotoolsIntroductionThe various GNU autotools provide an abstraction mechanism for
building a piece of software over a wide variety of operating
systems and machine architectures. Within the Ports Collection,
an individual port can make use of these tools via a simple
construct:USE_AUTOTOOLS= tool:version[:operation] ...At the time of writing, tool can be
one of libtool, libltdl,
autoconf, autoheader,
automake or aclocal.version specifies the particular
tool revision to be used (see
devel/{automake,autoconf,libtool}[0-9]+ for
valid versions).operation is an optional extension
to modify how the tool is used.Multiple tools can be specified at once, either by including
them all on a single line, or using the +=
Makefile construct.Finally, there is the special tool, called
autotools, which is a convenience function
to bring in all available versions of the autotools to allow
for cross-development work. This can also be accomplished
by installing the devel/autotools port.libtoolShared libraries using the GNU building framework usually use
libtool to adjust the compilation and
installation of shared libraries to match the specifics of the
underlying operating system. The usual practice is to use copy of
libtool bundled with the application. In case
you need to use external libtool, you can use
the version provided by The Ports Collection:USE_AUTOTOOLS= libtool:version[:env]With no additional operations,
libtool:version tells
the building framework to patch the configure script with the
system-installed copy of libtool.
The GNU_CONFIGURE is implied.
Further, a number of make and shell
variables will be assigned for onward use by the port. See
bsd.autotools.mk for details.With the :env operation, only the
environment will be set up.Finally, LIBTOOLFLAGS and
LIBTOOLFILES can be optionally set to override
the most likely arguments to, and files patched by,
libtool. Most ports are unlikely to need this.
See bsd.autotools.mk for further
details.libltdlSome ports make use of the libltdl library
package, which is part of the libtool suite.
Use of this library does not automatically necessitate the use of
libtool itself, so a separate construct is
provided.USE_AUTOTOOLS= libltdl:versionCurrently, all this does is to bring in a
LIB_DEPENDS on the appropriate
libltdl port, and is provided as a convenience
function to help eliminate any dependencies on the autotools ports
outside of the USE_AUTOTOOLS framework. There
are no optional operations for this tool.autoconf and
autoheaderSome ports do not contain a configure script, but do contain an
autoconf template in the configure.ac file.
You can use the following assignments to let
autoconf create the configure script, and also
have autoheader create template headers for use
by the configure script.USE_AUTOTOOLS= autoconf:version[:env]andUSE_AUTOTOOLS= autoheader:versionwhich also implies the use of
autoconf:version.Similarly to libtool, the inclusion of the
optional :env operation simply sets up the
environment for further use. Without it, patching and
reconfiguration of the port is carried out.The additional optional variables
AUTOCONF_ARGS and
AUTOHEADER_ARGS can be overridden by the port
Makefile if specifically requested. As with
the libtool equivalents, most ports are unlikely
to need this.automake and
aclocalSome packages only contain Makefile.am
files. These have to be converted into
Makefile.in files using
automake, and the further processed by
configure to generate an actual
Makefile.Similarly, packages occasionally do not ship with included
aclocal.m4 files, again required to build the
software. This can be achieved with aclocal,
which scans configure.ac or
configure.in.aclocal has a similar relationship to
automake as autoheader does
to autoconf, described in the previous section.
aclocal implies the use of
automake, thus we have:USE_AUTOTOOLS= automake:version[:env]andUSE_AUTOTOOLS= aclocal:versionwhich also implies the use of
automake:version.Similarly to libtool and
autoconf, the inclusion of the optional
:env operation simply sets up the environment
for further use. Without it, reconfiguration of the port is
carried out.As with
autoconf and autoheader, both
automake and aclocal have
optional argument variables, AUTOMAKE_ARGS and
ACLOCAL_ARGS respectively, which may be
overriden by the port Makefile if
required.Using GNU gettextBasic usageIf your port requires gettext,
just set USE_GETTEXT to yes,
and your port will grow the dependency on devel/gettext. The value of
USE_GETTEXT can also specify the required
version of the libintl library, the basic
part of gettext, but using this
feature is strongly discouraged:
Your port should work with just the current version of
devel/gettext.A rather common case is a port using
gettext and configure.
Generally, GNU configure should be
able to locate gettext automatically.
If it ever fails to, hints at the location of
gettext can be passed in
CPPFLAGS and LDFLAGS as
follows:USE_GETTEXT= yes
CPPFLAGS+= -I${LOCALBASE}/include
LDFLAGS+= -L${LOCALBASE}/lib
GNU_CONFIGURE= yes
CONFIGURE_ENV= CPPFLAGS="${CPPFLAGS}" \
LDFLAGS="${LDFLAGS}"Of course, the code can be more compact if there are no
more flags to pass to configure:USE_GETTEXT= yes
GNU_CONFIGURE= yes
CONFIGURE_ENV= CPPFLAGS="-I${LOCALBASE}/include" \
LDFLAGS="-L${LOCALBASE}/lib"Optional usageSome software products allow for disabling NLS,
e.g., through passing to
configure. In that case, your port
should use gettext conditionally,
depending on the status of WITHOUT_NLS.
For ports of low to medium complexity, you can rely on the
following idiom:GNU_CONFIGURE= yes
.if !defined(WITHOUT_NLS)
USE_GETTEXT= yes
PLIST_SUB+= NLS=""
.else
CONFIGURE_ARGS+= --disable-nls
PLIST_SUB+= NLS="@comment "
.endifThe next item on your to-do list is to arrange so that
the message catalog files are included in the packing list
conditionally. The Makefile part of
this task is already provided by the idiom. It is explained
in the section on advanced
pkg-plist practices. In a
nutshell, each occurrence of %%NLS%% in
pkg-plist will be replaced by
@comment if NLS is
disabled, or by a null string if NLS is enabled. Consequently,
the lines prefixed by %%NLS%% will become
mere comments in the final packing list if NLS is off;
otherwise the prefix will be just left out. All you need
to do now is insert %%NLS%% before each
path to a message catalog file in pkg-plist.
For example:%%NLS%%share/locale/fr/LC_MESSAGES/foobar.mo
%%NLS%%share/locale/no/LC_MESSAGES/foobar.moIn high complexity cases, you may need to use more advanced
techniques than the recipe given here, such as dynamic packing list generation.Handling message catalog directoriesThere is a point to note about installing message catalog
files. The target directories for them, which reside under
LOCALBASE/share/locale,
should rarely be created and removed by your port. The
most popular languages have their respective directories
listed in /etc/mtree/BSD.local.dist;
that is, they are a part of the base system. The directories
for many other languages are governed by the devel/gettext port. You may want
to consult its pkg-plist and see whether
your port is going to install a message catalog file for a
unique language.Using perlIf MASTER_SITES is set to
MASTER_SITE_PERL_CPAN, then preferred value of
MASTER_SITE_SUBDIR is top-level hierarchy name.
For example, the recommend value for p5-Module-Name
is Module. The top-level hierarchy can be examined
at cpan.org.
This keeps the port working when the author of the module
changes.The exception to this rule is when the relevant directory does not
exist or the distfile does not exist in the directory. In such case, using
author's id as MASTER_SITE_SUBDIR is allowed.All of the tunable knobs below accept both YES
and a version string, like 5.8.0+. Using
YES means that the port can be used with all
of the supported Perl versions. If a port
only works with specific versions of Perl,
it can be indicated with a version string, specifying a minimal version
(e.g. 5.7.3+), a maximal version (e.g.
5.8.0-) or an exact version (e.g.
5.8.3).
Variables for ports that use perlVariableMeansUSE_PERL5Says that the port uses perl 5 to build and run.USE_PERL5_BUILDSays that the port uses perl 5 to build.USE_PERL5_RUNSays that the port uses perl 5 to run.PERLThe full path of perl 5, either in the
system or installed from a port, but without the version
number. Use this if you need to replace
#!lines in scripts.PERL_CONFIGUREConfigure using Perl's MakeMaker. It implies
USE_PERL5.PERL_MODBUILDConfigure, build and install using Module::Build. It
implies PERL_CONFIGURE.Read only variablesPERL_VERSIONThe full version of perl installed (e.g.,
5.00503).PERL_VERThe short version of perl installed (e.g.,
5.005).PERL_LEVELThe installed perl version as an integer of the form MNNNPP
(e.g., 500503).PERL_ARCHWhere perl stores architecture dependent libraries.
Defaults to ${ARCH}-freebsd.PERL_PORTName of the perl port that is
installed (e.g., perl5).SITE_PERLDirectory name where site specific
perl packages go.
This value is added to PLIST_SUB.
Perl 模組的 port,由於沒有正式的網站,所以
pkg-descr 內的 WWW 應該指向至
cpan.org。 比較好的 URL 格式是
http://search.cpan.org/dist/Module-Name/
(包括結尾的 / 斜線符號)。Using X11X.Org componentsThe X11 implementation available in The Ports Collection is X.Org.
If your application depends on X components, set
USE_XORG to the list of required components.
Available components, at the time of writing, are:bigreqsproto compositeproto damageproto dmx dmxproto
evieproto fixesproto fontcacheproto fontenc fontsproto fontutil
glproto ice inputproto kbproto libfs oldx printproto randrproto
recordproto renderproto resourceproto scrnsaverproto sm trapproto
videoproto x11 xau xaw xaw6 xaw7 xaw8 xbitmaps xcmiscproto xcomposite
xcursor xdamage xdmcp xevie xext xextproto xf86bigfontproto
xf86dgaproto xf86driproto xf86miscproto xf86rushproto
xf86vidmodeproto xfixes xfont xfontcache xft xi xinerama
xineramaproto xkbfile xkbui xmu xmuu xorg-server xp xpm xprintapputil
xprintutil xpr oto xproxymngproto xrandr xrender xres xscrnsaver xt
xtrans xtrap xtst xv xvmc xxf86dga xxf86misc xxf86vm.Always up-to-date list can be found in
/usr/ports/Mk/bsd.xorg.mk.The Mesa Project is an effort to provide free OpenGL
implementation. You can specify a dependency on various components
of this project with USE_GL variable.
Valid options are: glut, glu, glw, gl and
linux. For backwards compatibility, the value
of yes maps to glu.USE_XORG exampleUSE_XORG= xrender xft xkbfile xt xaw
USE_GL= gluMany ports define USE_XLIB, which makes
the port depend on all the 50 or so libraries. This variable
exists for backwards compatibility, as it predates modular X.Org,
and should not be used on new ports.
Variables for ports that use XUSE_XLIBThe port uses the X libraries. Deprecated - use a list of
X.Org components in USE_XORG variable
instead.USE_IMAKE會用到 imake 的 port。USE_X_PREFIXDeprecated. Today it is equivalent to
USE_XLIB and can be replaced by it
freely.XMKMFSet to the path of xmkmf if not in the
PATH. Defaults to xmkmf
-a.
Variables for depending on individual parts of X11X_IMAKE_PORTPort providing imake and several
other utilities used to build X11.X_LIBRARIES_PORTPort providing X11 libraries.X_CLIENTS_PORTPort providing X clients.X_SERVER_PORTPort providing X server.X_FONTSERVER_PORTPort providing font server.X_PRINTSERVER_PORTPort providing print server.X_VFBSERVER_PORTPort providing virtual framebuffer server.X_NESTSERVER_PORTPort providing a nested X server.X_FONTS_ENCODINGS_PORTPort providing encodings for fonts.X_FONTS_MISC_PORTPort providing miscellaneous bitmap fonts.X_FONTS_100DPI_PORTPort providing 100dpi bitmap fonts.X_FONTS_75DPI_PORTPort providing 75dpi bitmap fonts.X_FONTS_CYRILLIC_PORTPort providing cyrillic bitmap fonts.X_FONTS_TTF_PORTPort providing &truetype; fonts.X_FONTS_TYPE1_PORTPort providing Type1 fonts.X_MANUALS_PORTPort providing developer oriented manual pages
Using X11 related variables in port# Use X11 libraries and depend on
# font server as well as cyrillic fonts.
RUN_DEPENDS= ${X11BASE}/bin/xfs:${X_FONTSERVER_PORT} \
${X11BASE}/lib/X11/fonts/cyrillic/crox1c.pcf.gz:${X_FONTS_CYRILLIC_PORT}
USE_XLIB= yesPorts that require MotifIf your port requires a Motif library, define
USE_MOTIF in the Makefile.
Default Motif implementation is
x11-toolkits/open-motif.
Users can choose
x11-toolkits/lesstif instead
by setting WANT_LESSTIF variable.The MOTIFLIB variable will be set by
bsd.port.mk to reference the appropriate
Motif library. Please patch the source of your port to
use ${MOTIFLIB} wherever the Motif library is referenced in the original
Makefile or
Imakefile.There are two common cases:If the port refers to the Motif library as
-lXm in its Makefile or
Imakefile, simply substitute
${MOTIFLIB} for it.If the port uses XmClientLibs in its
Imakefile, change it to
${MOTIFLIB} ${XTOOLLIB}
${XLIB}.Note that MOTIFLIB (usually) expands to
-L/usr/X11R6/lib -lXm or
/usr/X11R6/lib/libXm.a, so there is no need to
add -L or -l in front.X11 fontsIf your port installs fonts for the X Window System, put them in
X11BASE/lib/X11/fonts/local.Getting fake DISPLAY using XvfbSome applications require a working X11 display for compilation to
succeed. This pose a problem for the FreeBSD package building
cluster, which operates headless. When the following canonical hack
is used, the package cluster will start the virtual framebuffer
X server. The working DISPLAY is then passed
to the build.USE_DISPLAY= yesDesktop entries可藉由設定
DESKTOP_ENTRIES 變數,以輕鬆設定 port 的 X 選單項目
(Desktop Entries,請參閱
Freedesktop standard)。 這些項目會在相應的桌面環境如 GNOME
或 KDE 的應用程式選單中出現。 .desktop 檔案
將會被建立、安裝以及自動加入 pkg-plist
中。語法為:DESKTOP_ENTRIES= "NAME" "COMMENT" "ICON" "COMMAND" "CATEGORY" StartupNotify可供使用的分類可參考
Freedesktop 網站。 而 StartupNotify
變數會決定程式,是否支援 startup noficication 的環境。
範例:DESKTOP_ENTRIES= "ToME" "Roguelike game based on JRR Tolkien's work" \
"${DATADIR}/xtra/graf/tome-128.png" \
"tome -v -g" "Application;Game;RolePlaying" \
falseUsing GNOMEThe FreeBSD/GNOME project uses its own set of variables
to define which GNOME components a
particular port uses. A
comprehensive
list of these variables exists within the FreeBSD/GNOME
project's homepage.Using KDEVariable definitions
Variables for ports that use KDEUSE_KDELIBS_VERThe port uses KDE libraries. It specifies the
major version of KDE to use and implies
USE_QT_VER of the appropriate
version. The only possible value is
3.USE_KDEBASE_VERThe port uses KDE base. It specifies the major
version of KDE to use and implies
USE_QT_VER of the appropriate version.
The only possible value is 3.
Ports that require Qt
Variables for ports that use QtUSE_QT_VERThe port uses the Qt toolkit. Possible values
are 3 and 4;
each specify the major version of Qt to use. Appropriate
parameters are passed to configure
script and make.QT_PREFIXSet to the path where Qt installed to (read-only
variable).MOCSet to the path of moc
(read-only variable). Default set according to
USE_QT_VER value.QTCPPFLAGSAdditional compiler flags passed via
CONFIGURE_ENV for Qt toolkit.
Default set according to
USE_QT_VER.QTCFGLIBSAdditional libraries for linking passed via
CONFIGURE_ENV for Qt toolkit.
Default set according to
USE_QT_VER.QTNONSTANDARDSuppress modification of
CONFIGURE_ENV,
CONFIGURE_ARGS, and
MAKE_ENV.
Additional variables for ports that use Qt 4.xQT_COMPONENTSSpecify tool and library dependencies for Qt4.
See below for details.UICSet to the path of uic (read-only
variable). Default set according to
USE_QT_VER value.QMAKESet to the path of qmake
(read-only variable). Default set according to
USE_QT_VER value.QMAKESPECSet to the path of configuration file for
qmake (read-only variable). Default
set according to USE_QT_VER
value.
When USE_QT_VER is set, some useful
settings are passed to configure script:CONFIGURE_ARGS+= --with-qt-includes=${QT_PREFIX}/include \
--with-qt-libraries=${QT_PREFIX}/lib \
--with-extra-libs=${LOCALBASE}/lib \
--with-extra-includes=${LOCALBASE}/include
CONFIGURE_ENV+= MOC="${MOC}" CPPFLAGS="${CPPFLAGS} ${QTCPPFLAGS}" LIBS="${QTCFGLIBS}" \
QTDIR="${QT_PREFIX}" KDEDIR="${KDE_PREFIX}"If USE_QT_VER is set to 4,
the following settings are also deployed:CONFIGURE_ENV+= UIC="${UIC}" QMAKE="${QMAKE}" QMAKESPEC="${QMAKESPEC}"
MAKE_ENV+= QMAKESPEC="${QMAKESPEC}"Component selection (Qt 4.x only)When USE_QT_VER is set to 4, individual
Qt4 tool and library dependencies can be specified in the
QT_COMPONENTS variable. Every component
can be suffixed by either _build or _run,
the suffix indicating whether the component should be depended on at
buildtime or runtime, respectively. If unsuffixed, the component will be
depended on at both build- and runtime. Usually, library components
should be specified unsuffixed, tool components should be
specified with the _build suffix and plugin components
should be specified with the _run suffix. The most commonly
used components are listed below (all available components are
listed in _QT_COMPONENTS_ALL in
/usr/ports/Mk/bsd.qt.mk):
Available Qt4 library componentsNameDescriptioncorelibcore library (can be omitted unless the port
uses nothing but corelib)guigraphical user interface librarynetworknetwork libraryopenglOpenGL libraryqt3supportQt3 compatibility libraryqtestlibunit testing libraryscriptscript librarysqlSQL libraryxmlXML library
You can determine which libraries the application depends
on, by running ldd on the main executable
after a successful compilation.
Available Qt4 tool componentsNameDescriptionmocmeta object compiler (needed for almost
every Qt application at buildtime)qmakeMakefile generator / build utilityrccresource compiler (need if the application comes
with *.rc or *.qrc
files)uicuser interface compiler (needed if the application
comes with *.ui files created by Qt Designer
- in practice, every Qt application with a GUI)
Available Qt4 plugin componentsNameDescriptioniconenginesSVG icon engine plugin (if the application
ships SVG icons)imageformatsimageformat plugins for GIF, JPEG, MNG and
SVG (if the application ships image files)
Selecting Qt4 componentsIn this example, the ported application uses the
Qt4 graphical user interface library, the Qt4 core
library, all of the Qt4 code generation tools and Qt4's
Makefile generator. Since the gui library implies a
dependency on the core library, corelib does
not need to be specified. The Qt4 code generation
tools moc, uic and rcc, as well as the Makefile generator
qmake are only needed at buildtime, thus they are specified
with the _build suffix:USE_QT_VER= 4
QT_COMPONENTS= gui moc_build qmake_build rcc_build uic_buildAdditional considerationsIf the application does not provide a
configure file but a .pro
file, you can use the following:HAS_CONFIGURE= yes
do-configure:
@cd ${WRKSRC} && ${SETENV} ${CONFIGURE_ENV} \
${QMAKE} -unix PREFIX=${PREFIX} texmaker.proNote the similarity to the qmake line
from the provided BUILD.sh script. Passing
CONFIGURE_ENV ensures qmake
will see the QMAKESPEC variable, without which
it cannot work. qmake generates standard
Makefiles, so it is not necessary to write our own
build target.Qt applications often are written to be cross-platform
and often X11/Unix isn't the platform they are developed on,
which in turn often leads to certain loose ends, like:Missing additional includepaths.
Many applications come with system tray icon support, but
neglect to look for includes and/or libraries in the X11
directories. You can tell qmake to
add directories to the include and library searchpaths
via the commandline, for example:${QMAKE} -unix PREFIX=${PREFIX} INCLUDEPATH+=${X11BASE}/include \
LIBS+=-L${X11BASE}/lib sillyapp.proBogus installation paths.
Sometimes data such as icons or .desktop files are by
default installed into directories which aren't scanned by
XDG-compatible applications. editors/texmaker
is an example for this - look at patch-texmaker.pro
in the files directory of that port
for a template on how to remedy this directly in the Qmake
project file.Using JavaVariable definitionsIf your port needs a Java™ Development Kit (JDK) to
either build, run or even extract the distfile, then it should
define USE_JAVA.There are several JDKs in the ports collection, from various
vendors, and in several versions. If your port must use one of
these versions, you can define which one. The most current
version is java/jdk15.
Variables that may be set by ports that use JavaVariableMeansUSE_JAVAShould be defined for the remaining variables to have any
effect.JAVA_VERSIONList of space-separated suitable Java versions for
the port. An optional "+" allows you to
specify a range of versions (allowed values:
1.1[+] 1.2[+] 1.3[+] 1.4[+]).JAVA_OSList of space-separated suitable JDK port operating
systems for the port (allowed values: native
linux).JAVA_VENDORList of space-separated suitable JDK port vendors for
the port (allowed values: freebsd bsdjava sun ibm
blackdown).JAVA_BUILDWhen set, it means that the selected JDK port should
be added to the build dependencies of the port.JAVA_RUNWhen set, it means that the selected JDK port should
be added to the run dependencies of the port.JAVA_EXTRACTWhen set, it means that the selected JDK port should
be added to the extract dependencies of the port.USE_JIKESWhether the port should or should not use the
jikes bytecode compiler to build. When
no value is set for this variable, the port will use
jikes to build if available. You may
also explicitly forbid or enforce the use of
jikes (by setting 'no'
or 'yes'). In the later case, devel/jikes will be added to build
dependencies of the port. In any case that jikes
is actually used in place of javac, then the
HAVE_JIKES variable is defined by
bsd.java.mk.
Below is the list of all settings a port will receive after
setting USE_JAVA:
Variables provided to ports that use JavaVariableValueJAVA_PORTThe name of the JDK port (e.g.
'java/jdk14').JAVA_PORT_VERSIONThe full version of the JDK port (e.g.
'1.4.2'). If you only need the first
two digits of this version number, use
${JAVA_PORT_VERSION:C/^([0-9])\.([0-9])(.*)$/\1.\2/}.JAVA_PORT_OSThe operating system used by the JDK port (e.g.
'linux').JAVA_PORT_VENDORThe vendor of the JDK port (e.g.
'sun').JAVA_PORT_OS_DESCRIPTIONDescription of the operating system used by the JDK port
(e.g. 'Linux').JAVA_PORT_VENDOR_DESCRIPTIONDescription of the vendor of the JDK port (e.g.
'FreeBSD Foundation').JAVA_HOMEPath to the installation directory of the JDK (e.g.
'/usr/local/jdk1.3.1').JAVACPath to the Java compiler to use (e.g.
'/usr/local/jdk1.1.8/bin/javac' or
'/usr/local/bin/jikes').JARPath to the jar tool to use (e.g.
'/usr/local/jdk1.2.2/bin/jar' or
'/usr/local/bin/fastjar').APPLETVIEWERPath to the appletviewer utility (e.g.
'/usr/local/linux-jdk1.2.2/bin/appletviewer').JAVAPath to the java executable. Use
this for executing Java programs (e.g.
'/usr/local/jdk1.3.1/bin/java').JAVADOCPath to the javadoc utility
program.JAVAHPath to the javah program.JAVAPPath to the javap program.JAVA_KEYTOOLPath to the keytool utility program.
This variable is available only if the JDK is Java 1.2 or
higher.JAVA_N2APath to the native2ascii tool.JAVA_POLICYTOOLPath to the policytool program.
This variable is available only if the JDK is Java 1.2 or
higher.JAVA_SERIALVERPath to the serialver utility
program.RMICPath to the RMI stub/skeleton generator,
rmic.RMIREGISTRYPath to the RMI registry program,
rmiregistry.RMIDPath to the RMI daemon program rmid.
This variable is only available if the JDK is Java 1.2
or higher.JAVA_CLASSESPath to the archive that contains the JDK class
files. On JDK 1.2 or later, this is
${JAVA_HOME}/jre/lib/rt.jar. Earlier
JDKs used
${JAVA_HOME}/lib/classes.zip.HAVE_JIKESDefined whenever jikes is used by
the port (see USE_JIKES above).
You may use the java-debug make target
to get information for debugging your port. It will display the
value of many of the forecited variables.Additionally, the following constants are defined so all
Java ports may be installed in a consistent way:
Constants defined for ports that use JavaConstantValueJAVASHAREDIRThe base directory for everything related to Java.
Default: ${PREFIX}/share/java.
JAVAJARDIRThe directory where JAR files should be installed.
Default:
${JAVASHAREDIR}/classes.JAVALIBDIRThe directory where JAR files installed by other
ports are located. Default:
${LOCALBASE}/share/java/classes.
The related entries are defined in both
PLIST_SUB (documented in
) and
SUB_LIST.Building with AntWhen the port is to be built using Apache Ant, it has to
define USE_ANT. Ant is thus considered to be
the sub-make command. When no do-build target
is defined by the port, a default one will be set that simply
runs Ant according to MAKE_ENV,
MAKE_ARGS and ALL_TARGETS.
This is similar to the USE_GMAKE mechanism,
which is documented in .If jikes is used in place of
javac (see USE_JIKES in
), then Ant will automatically
use it to build the port.Best practicesWhen porting a Java library, your port should install the
JAR file(s) in ${JAVAJARDIR}, and everything
else under ${JAVASHAREDIR}/${PORTNAME}
(except for the documentation, see below). In order to reduce
the packing file size, you may reference the JAR file(s) directly
in the Makefile. Just use the following
statement (where myport.jar is the name
of the JAR file installed as part of the port):PLIST_FILES+= %%JAVAJARDIR%%/myport.jarWhen porting a Java application, the port usually installs
everything under a single directory (including its JAR
dependencies). The use of
${JAVASHAREDIR}/${PORTNAME} is strongly
encouraged in this regard. It is up the porter to decide
whether the port should install the additional JAR dependencies
under this directory or directly use the already installed ones
(from ${JAVAJARDIR}).Regardless of the type of your port (library or application),
the additional documentation should be installed in the
same location as for
any other port. The JavaDoc tool is known to produce a
different set of files depending on the version of the JDK that
is used. For ports that do not enforce the use of a particular
JDK, it is therefore a complex task to specify the packing list
(pkg-plist). This is one reason why
porters are strongly encouraged to use the
PORTDOCS macro. Moreover, even if you can
predict the set of files that will be generated by
javadoc, the size of the resulting
pkg-plist advocates for the use of
PORTDOCS.The default value for DATADIR is
${PREFIX}/share/${PORTNAME}. It is a good
idea to override DATADIR to
${JAVASHAREDIR}/${PORTNAME} for Java ports.
Indeed, DATADIR is automatically added to
PLIST_SUB (documented in ) so you may use
%%DATADIR%% directly in
pkg-plist.As for the choice of building Java ports from source or
directly installing them from a binary distribution, there is
no defined policy at the time of writing. However, people from
the &os; Java Project
encourage porters to have their ports built from source whenever
it is a trivial task.All the features that have been presented in this section
are implemented in bsd.java.mk. If you
ever think that your port needs more sophisticated Java support,
please first have a look at the
bsd.java.mk CVS log as it usually takes some time to
document the latest features. Then, if you think the support
you are lacking would be beneficial to many other Java ports,
feel free to discuss it on the &a.java;.Although there is a java category for
PRs, it refers to the JDK porting effort from the &os; Java
project. Therefore, you should submit your Java port in the
ports category as for any other port, unless
the issue you are trying to resolve is related to either a JDK
implementation or bsd.java.mk.Similarly, there is a defined policy regarding the
CATEGORIES of a Java port, which is detailed
in .Web applications, Apache and PHPApache
Variables for ports that use ApacheUSE_APACHEThe port requires Apache. Possible values:
yes (gets any version),
1.3, 2.0,
2.2, 2.0+,
etc. Default dependency is on version
1.3.WITH_APACHE2The port requires Apache 2.0. Without this variable,
the port will depend on Apache 1.3. This variable is
deprecated and should not be used anymore.APXSFull path to the apxs binary.
Can be overriden in your port.HTTPDFull path to the httpd binary.
Can be overriden in your port.APACHE_VERSIONThe version of present Apache installation (read-only
variable). This variable is only available after inclusion
of bsd.port.pre.mk. Possible values:
13, 20,
22.APACHEMODDIRDirectory for Apache modules. This variable is
automatically expanded in pkg-plist.APACHEINCLUDEDIRDirectory for Apache headers. This variable is
automatically expanded in pkg-plist.APACHEETCDIRDirectory for Apache configuration files. This
variable is automatically expanded in pkg-plist.
Web 應用程式Web 應用程式應該安裝到
PREFIX/www/appname
。 For your convenience, this path is available both in
Makefile and in pkg-plist
as WWWDIR, and the path relative to
PREFIX is available in
Makefile as
WWWDIR_REL.The user and group of web server process are available as
WWWOWN and WWWGRP, in case you
need to change the ownership of some files. The default values of
both are www. If you want different values for
your port, use WWWOWN?= myuser notation, to allow
user to override it easily.請別過於相依 Apache,除非這些程式有明確需要,而得相依 Apache
。也許有些使用者,會想在其他非 Apache 的 Web 伺服器上執行這些網頁程式。PHP
Variables for ports that use PHPUSE_PHPThe port requires PHP. The value yes
adds a dependency on PHP. The list of required PHP extensions
can be specified instead. Example: pcre xml
gettextDEFAULT_PHP_VERSelects which major version of PHP will be installed as
a dependency when no PHP is installed yet. Default is
4. Possible values: 4,
5IGNORE_WITH_PHPThe port does not work with PHP of the given version.
Possible values: 4,
5USE_PHPIZEThe port will be built as a PHP extension.USE_PHPEXTThe port will be treated as a PHP extension, including
installation and registration in the extension registry.USE_PHP_BUILDSet PHP as a build dependency.WANT_PHP_CLIWant the CLI (command line) version of PHP.WANT_PHP_CGIWant the CGI version of PHP.WANT_PHP_MODWant the Apache module version of PHP.WANT_PHP_SCRWant the CLI or the CGI version of PHP.WANT_PHP_WEBWant the Apache module or the CGI version of PHP.
PEAR modulesPorting PEAR modules is a very simple process.Use the variables FILES,
TESTS, DATA,
SQLS, SCRIPTFILES,
DOCS and EXAMPLES to list the
files you want to install. All listed files will be automatically
installed into the appropriate locations and added to
pkg-plist.Include
${PORTSDIR}/devel/pear/bsd.pear.mk
on the last line of the Makefile.Example Makefile for PEAR classPORTNAME= Date
PORTVERSION= 1.4.3
CATEGORIES= devel www pear
MAINTAINER= example@domain.com
COMMENT= PEAR Date and Time Zone Classes
BUILD_DEPENDS= ${PEARDIR}/PEAR.php:${PORTSDIR}/devel/pear-PEAR
RUN_DEPENDS= ${BUILD_DEPENDS}
FILES= Date.php Date/Calc.php Date/Human.php Date/Span.php \
Date/TimeZone.php
TESTS= test_calc.php test_date_methods_span.php testunit.php \
testunit_date.php testunit_date_span.php wknotest.txt \
bug674.php bug727_1.php bug727_2.php bug727_3.php \
bug727_4.php bug967.php weeksinmonth_4_monday.txt \
weeksinmonth_4_sunday.txt weeksinmonth_rdm_monday.txt \
weeksinmonth_rdm_sunday.txt
DOCS= TODO
_DOCSDIR= .
.include <bsd.port.pre.mk>
.include "${PORTSDIR}/devel/pear/bsd.pear.mk"
.include <bsd.port.post.mk>Using PythonThe Ports Collection supports parallel installation of multiple
Python versions. Ports should make sure to use a correct
python interpreter, according to the user-settable
PYTHON_VERSION variable. Most prominently, this
means replacing the path to python executable in
scripts with the value of PYTHON_CMD
variable.Ports that install files under PYTHON_SITELIBDIR
should use the pyXY- package name prefix, so their
package name embeds the version of Python they are installed
into.PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX}
Most useful variables for ports that use PythonUSE_PYTHONThe port needs Python. Minimal required version can be
specified with values such as 2.3+.
Version ranges can also be specified, by separating two version
numbers with a dash, e.g.: 2.1-2.3USE_PYDISTUTILSUse Python distutils for configuring, compiling and
installing. This is required when the port comes with
setup.py. This overrides the
do-build and
do-install targets
and may also override do-configure if
GNU_CONFIGURE is not defined.PYTHON_PKGNAMEPREFIXUsed as a PKGNAMEPREFIX to distinguish
packages for different Python versions.
Example: py24-PYTHON_SITELIBDIRLocation of the site-packages tree, that contains
installation path of Python (usually LOCALBASE).
The PYTHON_SITELIBDIR variable can be very
useful when installing Python modules.PYTHONPREFIX_SITELIBDIRThe PREFIX-clean variant of PYTHON_SITELIBDIR.
Always use
%%PYTHON_SITELIBDIR%% in
pkg-plist when possible. The default value of
%%PYTHON_SITELIBDIR%% is
lib/python%%PYTHON_VERSION%%/site-packagesPYTHON_CMDPython interpreter command line, including version
number.PYNUMERICDependency line for numeric extension.PYNUMPYDependency line for the new numeric extension, numpy.
(PYNUMERIC is deprecated by upstream vendor).PYXMLDependency line for XML extension (not needed for
Python 2.0 and higher as it is also in base distribution).USE_TWISTEDAdd dependency on twistedCore. The list of required
components can be specified as a value of this
variable. Example: web lore pair
flowUSE_ZOPEAdd dependency on Zope, a web application platform.
Change Python dependency to Python 2.3. Set
ZOPEBASEDIR containing a directory with
Zope installation.
A complete list of available variables can be found in
/usr/ports/Mk/bsd.python.mk.Using EmacsThis section is yet to be written.Using Ruby
Useful variables for ports that use RubyVariableDescriptionUSE_RUBYThe port requires Ruby.USE_RUBY_EXTCONFThe port uses extconf.rb to
configure.USE_RUBY_SETUPThe port uses setup.rb to
configure.RUBY_SETUPSet to the alternative name of
setup.rb. Common value is
install.rb.
The following table shows the selected variables available to port
authors via the ports infrastructure. These variables should be used
to install files into their proper locations. Use them in
pkg-plist as much as possible. These variables
should not be redefined in the port.
Selected read-only variables for ports that use RubyVariableDescriptionExample valueRUBY_PKGNAMEPREFIXUsed as a PKGNAMEPREFIX to distinguish
packages for different Ruby versions.ruby18-RUBY_VERSIONFull version of Ruby in the form of
x.y.z.1.8.2RUBY_SITELIBDIRArchitecture independent libraries installation
path./usr/local/lib/ruby/site_ruby/1.8RUBY_SITEARCHLIBDIRArchitecture dependent libraries installation
path./usr/local/lib/ruby/site_ruby/1.8/amd64-freebsd6RUBY_MODDOCDIRModule documentation installation path./usr/local/share/doc/ruby18/patsyRUBY_MODEXAMPLESDIRModule examples installation path./usr/local/share/examples/ruby18/patsy
A complete list of available variables can be found in
/usr/ports/Mk/bsd.ruby.mk.Using SDLThe USE_SDL variable is used to autoconfigure
the dependencies for ports which use an SDL based library like
devel/sdl12 and
x11-toolkits/sdl_gui.The following SDL libraries are recognized at the moment:sdl: devel/sdl12gfx: graphics/sdl_gfxgui: x11-toolkits/sdl_guiimage: graphics/sdl_imageldbad: devel/sdl_ldbadmixer: audio/sdl_mixermm: devel/sdlmmnet: net/sdl_netsound: audio/sdl_soundttf: graphics/sdl_ttfTherefore, if a port has a dependency on
net/sdl_net and
audio/sdl_mixer,
the syntax will be:USE_SDL= net mixerThe dependency devel/sdl12,
which is required by net/sdl_net and
audio/sdl_mixer, is automatically
added as well.If you use USE_SDL, it will automatically:Add a dependency on sdl12-config to
BUILD_DEPENDSAdd the variable SDL_CONFIG to
CONFIGURE_ENVAdd the dependencies of the selected libraries to the
LIB_DEPENDSTo check whether an SDL library is available, you can do it
with the WANT_SDL variable:WANT_SDL=yes
.include <bsd.port.pre.mk>
.if ${HAVE_SDL:Mmixer}!=""
USE_SDL+= mixer
.endif
.include <bsd.port.post.mk>Using wxWidgetsThis section describes the status of the
wxWidgets libraries in the ports tree and
its integration with the ports system.IntroductionThere are many versions of the
wxWidgets libraries which conflict
between them (install files under the same name). In the ports tree
this problem has been solved by installing each version under a
different name using version number suffixes.The obvious disadvantage of this is that each application has to
be modified to find the expected version. Fortunately, most of the
applications call the wx-config script to
determine the necessary compiler and linker flags. The script is
named differently for every available version. Majority of
applications respect an environment variable, or accept a configure
argument, to specify which wx-config script to
call. Otherwise they have to be patched.Version selectionTo make your port use a specific version of
wxWidgets there are two variables
available for defining (if only one is defined the other will be set
to a default value):
Variables to select wxWidgets
versionsVariableDescriptionDefault valueUSE_WXList of versions the port can useAll available versionsUSE_WX_NOTList of versions the port can not useNone
The following is a list of available
wxWidgets versions and the corresponding
ports in the tree:
Available wxWidgets
versionsVersionPort2.4x11-toolkits/wxgtk242.6x11-toolkits/wxgtk262.8x11-toolkits/wxgtk28
The versions starting from 2.5 also come in
Unicode version and are installed by a slave port named like the
normal one plus a -unicode suffix, but this can
be handled with variables (see ).The variables in can be set
to one or more of the following combinations separated by
spaces:
wxWidgets version
specificationsDescriptionExampleSingle version2.4Ascending range2.4+Descending range2.6-Full range (must be ascending)2.4-2.6
There are also some variables to select the preferred versions
from the available ones. They can be set to a list of versions, the
first ones will have higher priority.
Variables to select preferred
wxWidgets versionsNameDesigned forWANT_WX_VERthe portWITH_WX_VERthe user
Component selectionThere are other applications that, while not being
wxWidgets libraries, are related to them.
These applications can be specified in the
WX_COMPS variable. The following components are
available:
Available wxWidgets
componentsNameDescriptionVersion restrictionwxmain librarynonecontribcontributed librariesnonepythonwxPython
(Python bindings)2.4-2.6mozillawxMozilla2.4svgwxSVG2.6
The dependency type can be selected for each component by adding
a suffix separated by a semicolon. If not present then a default
type will be used (see ). The
following types are available:
Available wxWidgets dependency
typesNameDescriptionbuildComponent is required for building, equivalent to
BUILD_DEPENDSrunComponent is required for running, equivalent to
RUN_DEPENDSlibComponent is required for building and running,
equivalent to LIB_DEPENDS
The default values for the components are detailed in the
following table:
Selecting wxWidgets
componentsThe following fragment corresponds to a port which uses
wxWidgets version
2.4 and its contributed libraries.USE_WX= 2.4
WX_COMPS= wx contribUnicodeThe wxWidgets library supports
Unicode since version 2.5. In the ports tree
both versions are available and can be selected with the following
variables:
Variables to select Unicode in
wxWidgets
versionsVariableDescriptionDesigned forWX_UNICODEThe port works only with the
Unicode versionthe portWANT_UNICODEThe port works with both versions but prefers the
Unicode onethe portWITH_UNICODEThe port will use the Unicode versionthe userWITHOUT_UNICODEThe port will use the normal version if
supported (when WX_UNICODE is not
defined)the user
Do not use WX_UNICODE for ports that can
use both Unicode and normal versions. If you want the port to use
Unicode by default define WANT_UNICODE
instead.Detecting installed versionsTo detect an installed version you have to define
WANT_WX. If you do not set it to a specific
version then the components will have a version suffix. The
HAVE_WX variable will be filled after
detection.Detecting installed wxWidgets
versions and componentsThe following fragment can be used in a port that uses
wxWidgets if it is installed, or an
option is selected.WANT_WX= yes
.include <bsd.port.pre.mk>
.if defined(WITH_WX) || ${HAVE_WX:Mwx-2.4} != ""
USE_WX= 2.4
CONFIGURE_ARGS+=--enable-wx
.endifThe following fragment can be used in a port that enables
wxPython support if it is installed or
if an option is selected, in addition to
wxWidgets, both version
2.6.USE_WX= 2.6
WX_COMPS= wx
WANT_WX= 2.6
.include <bsd.port.pre.mk>
.if defined(WITH_WXPYTHON) || ${HAVE_WX:Mpython} != ""
WX_COMPS+= python
CONFIGURE_ARGS+=--enable-wxpython
.endifDefined variablesThe following variables are available in the port (after
defining one from ).
Variables defined for ports that use
wxWidgetsNameDescriptionWX_CONFIGThe path to the wxWidgetswx-config script (with different
name)WXRC_CMDThe path to the wxWidgetswxrc program (with different
name)WX_VERSIONThe wxWidgets version that
is going to be used (e.g., 2.6)WX_UNICODEIf not defined but Unicode is going to be used then it
will be defined
Processing in bsd.port.pre.mkIf you need to use the variables for running commands right
after including bsd.port.pre.mk you need to
define WX_PREMK.If you define WX_PREMK, then the version,
dependencies, components and defined variables will not change if
you modify the wxWidgets port variables
after including
bsd.port.pre.mk.Using wxWidgets variables in
commandsThe following fragment illustrates the use of
WX_PREMK by running the
wx-config script to obtain the full version
string, assign it to a variable and pass it to the program.USE_WX= 2.4
WX_PREMK= yes
.include <bsd.port.pre.mk>
.if exists(${WX_CONFIG})
VER_STR!= ${WX_CONFIG} --release
PLIST_SUB+= VERSION="${VER_STR}"
.endifThe wxWidgets variables can be
safely used in commands when they are inside targets without the
need of WX_PREMK.Additional configure argumentsSome GNU configure scripts can not find
wxWidgets with just the
WX_CONFIG environment variable set, requiring
additional arguments. The WX_CONF_ARGS variable
can be used for provide them.
Legal values for WX_CONF_ARGSPossible valueResulting argumentabsolute--with-wx-config=${WX_CONFIG}relative--with-wx=${X11BASE}
--with-wx-config=${WX_CONFIG:T}
Using LuaThis section describes the status of the
Lua libraries in the ports tree and its
integration with the ports system.IntroductionThere are many versions of the Lua
libraries and corresponding interpreters, which conflict between
them (install files under the same name). In the ports tree this
problem has been solved by installing each version under a different
name using version number suffixes.The obvious disadvantage of this is that each application has to
be modified to find the expected version. But it can be solved by
adding some additional flags to the compiler and linker.Version selectionTo make your port use a specific version of
Lua there are two variables available
for defining (if only one is defined the other will be set to a
default value):
Variables to select Lua
versionsVariableDescriptionDefault valueUSE_LUAList of versions the port can useAll available versionsUSE_LUA_NOTList of versions the port can not useNone
The following is a list of available
Lua versions and the corresponding ports
in the tree:
Available Lua versionsVersionPort4.0lang/lua45.0lang/lua505.1lang/lua
The variables in can be set
to one or more of the following combinations separated by
spaces:
Lua version specificationsDescriptionExampleSingle version4.0Ascending range5.0+Descending range5.0-Full range (must be ascending)5.0-5.1
There are also some variables to select the preferred versions
from the available ones. They can be set to a list of versions, the
first ones will have higher priority.
Variables to select preferred Lua
versionsNameDesigned forWANT_LUA_VERthe portWITH_LUA_VERthe user
Selecting the Lua versionThe following fragment is from a port which can use
Lua version 5.0 or
5.1, and uses 5.0 by
default. It can be overriden by the user using
WITH_LUA_VER.USE_LUA= 5.0-5.1
WANT_LUA_VER= 5.0Component selectionThere are other applications that, while not being
Lua libraries, are related to them.
These applications can be specified in the
LUA_COMPS variable. The following components are
available:
Available Lua componentsNameDescriptionVersion restrictionluamain librarynonetoluaLibrary for accesing C/C++ code4.0-5.0rubyRuby bindings4.0-5.0
There are more components but they are modules for the
interpreter, not used by applications (only by other
modules).The dependency type can be selected for each component by adding
a suffix separated by a semicolon. If not present then a default
type will be used (see ). The
following types are available:
Available Lua dependency
typesNameDescriptionbuildComponent is required for building, equivalent to
BUILD_DEPENDSrunComponent is required for running, equivalent to
RUN_DEPENDSlibComponent is required for building and running,
equivalent to LIB_DEPENDS
The default values for the components are detailed in the
following table:
Default Lua dependency
typesComponentDependency typelualib for 4.0-5.0
(shared) and build for
5.1 (static)toluabuild (static)rubylib (shared)
Selecting Lua componentsThe following fragment corresponds to a port which uses
Lua version 4.0 and
its Ruby bindings.USE_LUA= 4.0
LUA_COMPS= lua rubyDetecting installed versionsTo detect an installed version you have to define
WANT_LUA. If you do not set it to a specific
version then the components will have a version suffix. The
HAVE_LUA variable will be filled after
detection.Detecting installed Lua versions
and componentsThe following fragment can be used in a port that uses
Lua if it is installed, or an option is
selected.WANT_LUA= yes
.include <bsd.port.pre.mk>
.if defined(WITH_LUA5) || ${HAVE_LUA:Mlua-5.[01]} != ""
USE_LUA= 5.0-5.1
CONFIGURE_ARGS+=--enable-lua5
.endifThe following fragment can be used in a port that enables
tolua support if it is installed or if
an option is selected, in addition to
Lua, both version
4.0.USE_LUA= 4.0
LUA_COMPS= lua
WANT_LUA= 4.0
.include <bsd.port.pre.mk>
.if defined(WITH_TOLUA) || ${HAVE_LUA:Mtolua} != ""
LUA_COMPS+= tolua
CONFIGURE_ARGS+=--enable-tolua
.endifDefined variablesThe following variables are available in the port (after
defining one from ).
Variables defined for ports that use
LuaNameDescriptionLUA_VERThe Lua version that is
going to be used (e.g., 5.1)LUA_VER_SHThe Lua shared library major
version (e.g., 1)LUA_VER_STRThe Lua version without the
dots (e.g., 51)LUA_PREFIXThe prefix where Lua (and
components) is installedLUA_SUBDIRThe directory under ${PREFIX}/bin,
${PREFIX}/share and
${PREFIX}/lib where
Lua is installedLUA_INCDIRThe directory where Lua and
tolua header files are
installedLUA_LIBDIRThe directory where Lua and
tolua libraries are
installedLUA_MODLIBDIRThe directory where Lua
module libraries (.so) are
installedLUA_MODSHAREDIRThe directory where Lua
modules (.lua) are installedLUA_PKGNAMEPREFIXThe package name prefix used by
Lua modulesLUA_CMDThe path to the Lua
interpreterLUAC_CMDThe path to the Lua
compilerTOLUA_CMDThe path to the tolua
program
Telling the port where to find
LuaThe following fragment shows how to tell a port that uses a
configure script where the Lua header
files and libraries are.
USE_LUA= 4.0
GNU_CONFIGURE= yes
CONFIGURE_ENV= CPPFLAGS="-I${LUA_INCDIR}" LDFLAGS="-L${LUA_LIBDIR}"Processing in bsd.port.pre.mkIf you need to use the variables for running commands right
after including bsd.port.pre.mk you need to
define LUA_PREMK.If you define LUA_PREMK, then the version,
dependencies, components and defined variables will not change if
you modify the Lua port variables
after including
bsd.port.pre.mk.Using Lua variables in
commandsThe following fragment illustrates the use of
LUA_PREMK by running the
Lua interpreter to obtain the full
version string, assign it to a variable and pass it to the
program.USE_LUA= 5.0
LUA_PREMK= yes
.include <bsd.port.pre.mk>
.if exists(${LUA_CMD})
VER_STR!= ${LUA_CMD} -v
CFLAGS+= -DLUA_VERSION_STRING="${VER_STR}"
.endifThe Lua variables can be safely
used in commands when they are inside targets without the need of
LUA_PREMK.Using XfceThe USE_XFCE variable is used to autoconfigure
the dependencies for ports which use an Xfce based library or application
like
x11-toolkits/libxfce4gui and
x11-wm/xfce4-panel.The following Xfce libraries and applications are recognized at
the moment:libexo: x11/libexolibgui: x11-toolkits/libxfce4guilibutil: x11/libxfce4utillibmcs: x11/libxfce4mcsmcsmanager: sysutils/xfce4-mcs-managerpanel: x11-wm/xfce4-panelthunar: x11-fm/thunarwm: x11-wm/xfce4-wmxfdev: dev/xfce4-dev-toolsThe following additional parameters are recognized:configenv: Use this if your port requires a special modified
CONFIGURE_ENV to find it's required libraries.
-I${LOCALBASE}/include -L${LOCALBASE}/lib
gets added to CPPFLAGS to CONFIGURE_ENV.Therefore, if a port has a dependency on
sysutils/xfce4-mcs-manager and
requires the special CPPFLAGS in its configure environment,
the syntax will be:USE_XFCE= mcsmanager configenvStarting and stopping services (rc scripts)rc.d scripts are used to start services on system
startup, and to give administrators a standard way of stopping,
starting and restarting the service. Ports integrate into
the system rc.d framework. Details on its usage
can be found in
the rc.d Handbook
chapter. Detailed explanation of available commands is
provided in
&man.rc.8; and &man.rc.subr.8;. Finally, there is
an article
on practical aspects of rc.d scripting.One or more rc scripts can be installed:USE_RC_SUBR= doormandScripts must be placed in the files
subdirectory and a .in suffix must be added to their
filename. The only difference from a base system rc.d script is that the
. /etc/rc.subr line must be replaced with the
. %%RC_SUBR%%, because older versions of &os;
do not have an /etc/rc.subr file. Standard
SUB_LIST expansions are used too.
Use of the %%PREFIX%%,
%%LOCALBASE%%, and
%%X11BASE%% expansions is strongly encouraged as well.
More on
SUB_LIST in the relevant section.Prior to &os; 6.1-RELEASE, integration with &man.rcorder.8; is available by using
USE_RCORDER instead of
USE_RC_SUBR.
However, use of this method is deprecated.As of &os; 6.1-RELEASE, local rc.d
scripts (including those installed by ports) are included in
the overall &man.rcorder.8; of the base system.Example simple rc.d script:#!/bin/sh
# PROVIDE: doormand
# REQUIRE: LOGIN
#
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf
# to enable this service:
#
# doormand_enable (bool): Set to NO by default.
# Set it to YES to enable doormand.
# doormand_config (path): Set to %%PREFIX%%/etc/doormand/doormand.cf
# by default.
#
. %%RC_SUBR%%
name="doormand"
rcvar=${name}_enable
command=%%PREFIX%%/sbin/${name}
pidfile=/var/run/${name}.pid
load_rc_config $name
: ${doormand_enable="NO"}
: ${doormand_config="%%PREFIX%%/etc/doormand/doormand.cf"}
command_args="-p $pidfile -f $doormand_config"
run_rc_command "$1"The "=" style of default variable assignment
is preferable to the ":=" style here, since the
former sets a default value only if the variable is unset,
and the latter sets one if the variable is unset
or null.
A user might very well include something like
doormand_flags="" in their
rc.conf.local file, and a variable
substitution using ":=" would inappropriately
override the user's intention.The suffix of the rc script is provided in
RC_SUBR_SUFFIX for further use in the port's
Makefile. Current versions of &os; do not add
any suffix to the script name, but older versions used to add
.sh suffix.No new scripts should be added with the .sh
suffix. At some point there will be a mass repocopy of all the
scripts that still have that suffix.Stopping services at deinstallIt is possible to have a service stopped automatically as part of
the deinstall routine. We advise using this feature only when it's
absolutely necessary to stop a service before it's files go
away. Usually, it's up to the administrator's discretion to decide,
whether to stop the service on deinstall or not. Also note this
affects upgrades, too.Line like this goes to the pkg-plist:@stopdaemon doormandThe argument must match the content of
USE_RC_SUBR variable.Advanced pkg-plist practicesChanging pkg-plist based on make
variablesSome ports, particularly the p5- ports,
need to change their pkg-plist depending on
what options they are configured with (or version of
perl, in the case of p5-
ports). To make this easy, any instances in the
pkg-plist of %%OSREL%%,
%%PERL_VER%%, and
%%PERL_VERSION%% will be substituted for
appropriately. The value of %%OSREL%% is the
numeric revision of the operating system (e.g.,
4.9). %%PERL_VERSION%% is
the full version number of perl (e.g.,
5.00502) and %%PERL_VER%%
is the perl version number minus
the patchlevel (e.g., 5.005). Several other
%%VARS%% related to
port's documentation files are described in the relevant section.If you need to make other substitutions, you can set the
PLIST_SUB variable with a list of
VAR=VALUE
pairs and instances of
%%VAR%% will be
substituted with VALUE in the
pkg-plist.For instance, if you have a port that installs many files in a
version-specific subdirectory, you can put something likeOCTAVE_VERSION= 2.0.13
PLIST_SUB= OCTAVE_VERSION=${OCTAVE_VERSION}in the Makefile and use
%%OCTAVE_VERSION%% wherever the version shows up
in pkg-plist. That way, when you upgrade the port,
you will not have to change dozens (or in some cases, hundreds) of
lines in the pkg-plist.This substitution (as well as addition of any manual pages) will be done between
the pre-install and
do-install targets, by reading from
PLIST and writing to
TMPPLIST
(default:
WRKDIR/.PLIST.mktmp). So if
your port builds PLIST
on the fly, do so in or
before pre-install. Also, if your port
needs to edit the resulting file, do so in
post-install to a file named
TMPPLIST.Another possibility to modify port's packing list is based
on setting the variables PLIST_FILES and
PLIST_DIRS. The value of each variable
is regarded as a list of pathnames to
write to TMPPLIST
along with PLIST
contents. Names listed in PLIST_FILES
and PLIST_DIRS are subject to
%%VAR%%
substitution, as described above.
Except for that, names from PLIST_FILES
will appear in the final packing list unchanged,
while @dirrm will be
prepended to names from PLIST_DIRS.
To take effect, PLIST_FILES and
PLIST_DIRS must be set before
TMPPLIST is written,
i.e. in pre-install or earlier.Empty directoriesCleaning up empty directoriesDo make your ports remove empty directories when they are
de-installed. This is usually accomplished by adding
@dirrm lines for all directories that are
specifically created by the port. You need to delete subdirectories
before you can delete parent directories. :
lib/X11/oneko/pixmaps/cat.xpm
lib/X11/oneko/sounds/cat.au
:
@dirrm lib/X11/oneko/pixmaps
@dirrm lib/X11/oneko/sounds
@dirrm lib/X11/onekoHowever, sometimes @dirrm will give you
errors because other ports share the same directory. You
can use @dirrmtry to
remove only empty directories without warning.@dirrmtry share/doc/gimpThis will neither print any error messages nor cause
&man.pkg.delete.1; to exit abnormally even if
${PREFIX}/share/doc/gimp is not
empty due to other ports installing some files in there.Creating empty directoriesEmpty directories created during port installation need special
attention. They will not get created when installing the package,
because packages only store the files, and &man.pkg.add.1; creates
directories for them as needed. To make sure the empty directory
is created when installing the package, add this line to
pkg-plist above the corresponding
@dirrm line:@exec mkdir -p %D/share/foo/templatesConfiguration filesIf your port requires some configuration files in
PREFIX/etc, do
not just install them and list them in
pkg-plist. That will cause
&man.pkg.delete.1; to delete files carefully edited by
the user and a new installation to wipe them out.Instead, install sample files with a suffix
(filename.sample
will work well). Copy the sample file as the real configuration
file, if it does not exist. On deinstall, delete the configuration
file, but only if it was not modified by the user. You need to
handle this both in the port Makefile, and in
the pkg-plist (for installation from
the package).Example of the Makefile part:post-install:
@if [ ! -f ${PREFIX}/etc/orbit.conf ]; then \
${CP} -p ${PREFIX}/etc/orbit.conf.sample ${PREFIX}/etc/orbit.conf ; \
fiExample of the pkg-plist part:@unexec if cmp -s %D/etc/orbit.conf.sample %D/etc/orbit.conf; then rm -f %D/etc/orbit.conf; fi
etc/orbit.conf.sample
@exec if [ ! -f %D/etc/orbit.conf ] ; then cp -p %D/%F %B/orbit.conf; fiAlternatively, print out a message pointing out that the
user has to copy and edit the file before the software can be made
to work.Dynamic vs. static package listA static package list is a package list
which is available in the Ports Collection either as a
pkg-plist file (with or without variable
substitution), or embedded into the Makefile
via PLIST_FILES and PLIST_DIRS.
Even if the contents are auto-generated by a tool or a target
in the Makefile before the inclusion into the
Ports Collection by a committer, this is still considered a
static list, since it is possible to examine it without having
to download or compile the distfile.A dynamic package list is a package list
which is generated at the time the port is compiled based upon the
files and directories which are installed. It is not possible to
examine it before the source code of the ported application
is downloaded and compiled, or after running a make
clean.While the use of dynamic package lists is not forbidden,
maintainers should use static package lists wherever possible, as it
enables users to &man.grep.1; through available ports to discover,
for example, which port installs a certain file. Dynamic lists
should be primarily used for
complex ports where the package list changes drastically based upon
optional features of the port (and thus maintaining a static package
list is infeasible), or ports which change the
package list based upon the version of dependent software used (e.g.
ports which generate docs with
Javadoc).Maintainers who prefer dynamic package lists are encouraged to
add a new target to their port which generates the
pkg-plist file so that users may examine
the contents.自動產生 package list首先,先確認您的 port 除了 pkg-plist
尚未搞定之外,其他都完成了。接著,建立臨時目錄以供該 port 安裝,並且把所有相依套件都裝好
。&prompt.root; mkdir /var/tmp/$(make -V PORTNAME)
&prompt.root; mtree -U -f $(make -V MTREE_FILE) -d -e -p /var/tmp/$(make -V PORTNAME)
&prompt.root; make depends PREFIX=/var/tmp/$(make -V PORTNAME)把這目錄架構存到新檔案。&prompt.root; (cd /var/tmp/$(make -V PORTNAME) && find -d * -type d) | sort > OLD-DIRS新增空的 pkg-plist 檔案:&prompt.root; :>pkg-plist若該 port 有遵循 PREFIX(也應該要遵循),
接著就可以安裝該 port 並產生檔案清單。&prompt.root; make install PREFIX=/var/tmp/$(make -V PORTNAME)
&prompt.root; (cd /var/tmp/$(make -V PORTNAME) && find -d * \! -type d) | sort > pkg-plist這時要記得把新建的目錄,也加到檔案清單內。&prompt.root; (cd /var/tmp/$(make -V PORTNAME) && find -d * -type d) | sort | comm -13 OLD-DIRS - | sort -r | sed -e 's#^#@dirrm #' >> pkg-plist
- Finally, you need to tidy up the packing list by hand; it is not
- all automated. Manual pages should be listed in
- the port's Makefile under
- MANn, and not in the
- package list. User configuration files should be removed, or
- installed as
- filename.sample.
+ 最後,您應該手動整理檔案清單(這不是全部自動化處理的)。Man page 則應該利用 MANn 的方式
+ 寫在 port 的 Makefile 而不是寫在檔案清單中。
+ 使用者設定檔應該移除,或更名為filename.sample。
The info/dir file should not be listed
and appropriate install-info lines should
be added as noted in the info
files section. Any
libraries installed by the port should be listed as specified in the
shared libraries section.Alternatively, use the plist script in
/usr/ports/Tools/scripts/ to build the
package list automatically. The first step is the same as
above: take the first three lines, that is,
mkdir, mtree and
make depends. Then build and install the
port:&prompt.root; make install PREFIX=/var/tmp/port-nameAnd let plist create the
pkg-plist file:&prompt.root; /usr/ports/Tools/scripts/plist -Md -m /etc/mtree/BSD.port-type.dist /var/tmp/port-name > pkg-plistThe packing list still has to be tidied up by hand as
stated above.The pkg-* filesThere are some tricks we have not mentioned yet about the
pkg-* files
that come in handy sometimes.pkg-messageIf you need to display a message to the installer, you may place
the message in pkg-message. This capability is
often useful to display additional installation steps to be taken
after a &man.pkg.add.1; or to display licensing
information.When some lines about the build-time knobs or warnings
have to be displayed, use ECHO_MSG. The
pkg-message file is only for
post-installation steps. Likewise, the distinction between
ECHO_MSG and ECHO_CMD
should be kept in mind. The former is for printing
informational text to the screen, while the latter is for
command pipelining.A good example for both can be found in
shells/bash2/Makefile:update-etc-shells:
@${ECHO_MSG} "updating /etc/shells"
@${CP} /etc/shells /etc/shells.bak
@( ${GREP} -v ${PREFIX}/bin/bash /etc/shells.bak; \
${ECHO_CMD} ${PREFIX}/bin/bash) >/etc/shells
@${RM} /etc/shells.bakThe pkg-message file does not need to be
added to pkg-plist. Also, it will not get
automatically printed if the user is using the port, not the
package, so you should probably display it from the
post-install target yourself.pkg-installIf your port needs to execute commands when the binary package
is installed with &man.pkg.add.1; you can do this via the
pkg-install script. This script will
automatically be added to the package, and will be run twice by
&man.pkg.add.1;: the first time as
${SH} pkg-install ${PKGNAME}
PRE-INSTALL and the second time as
${SH} pkg-install ${PKGNAME} POST-INSTALL.
$2 can be tested to determine which mode
the script is being run in. The PKG_PREFIX
environmental variable will be set to the package installation
directory. See &man.pkg.add.1; for
additional information.This script is not run automatically if you install the port
with make install. If you are depending on it
being run, you will have to explicitly call it from your port's
Makefile, with a line like
PKG_PREFIX=${PREFIX} ${SH} ${PKGINSTALL}
${PKGNAME} PRE-INSTALL.pkg-deinstallThis script executes when a package is removed.
This script will be run twice by &man.pkg.delete.1;.
The first time as ${SH} pkg-deinstall ${PKGNAME}
DEINSTALL and the second time as
${SH} pkg-deinstall ${PKGNAME} POST-DEINSTALL.
pkg-reqIf your port needs to determine if it should install or not, you
can create a pkg-reqrequirements
script. It will be invoked automatically at
installation/de-installation time to determine whether or not
installation/de-installation should proceed.The script will be run at installation time by
&man.pkg.add.1; as
pkg-req ${PKGNAME} INSTALL.
At de-installation time it will be run by
&man.pkg.delete.1; as
pkg-req ${PKGNAME} DEINSTALL.Changing the names of
pkg-* filesAll the names of pkg-* files
are defined using variables so you can change them in your
Makefile if need be. This is especially useful
when you are sharing the same pkg-* files
among several ports or have to write to one of the above files (see
writing to places other than
WRKDIR for why it is a bad idea to write
directly into the pkg-* subdirectory).Here is a list of variable names and their default
values. (PKGDIR defaults to
${MASTERDIR}.)VariableDefault valueDESCR${PKGDIR}/pkg-descrPLIST${PKGDIR}/pkg-plistPKGINSTALL${PKGDIR}/pkg-installPKGDEINSTALL${PKGDIR}/pkg-deinstallPKGREQ${PKGDIR}/pkg-reqPKGMESSAGE${PKGDIR}/pkg-messagePlease change these variables rather than overriding
PKG_ARGS. If you change
PKG_ARGS, those files will not correctly be
installed in /var/db/pkg upon install from a
port.Making use of SUB_FILES and
SUB_LISTThe SUB_FILES and SUB_LIST
variables are useful for dynamic values in port files, such as the
installation PREFIX in
pkg-message.The SUB_FILES variable specifies a list
of files to be automatically modified. Each
file in the
SUB_FILES list must have a corresponding
file.in present
in FILESDIR. A modified version will
be created in WRKDIR. Files defined as a
value of USE_RC_SUBR (or the deprecated
USE_RCORDER)
are automatically added to the
SUB_FILES. For the files
pkg-message,
pkg-install, pkg-deinstall
and pkg-reg, the corresponding Makefile variable
is automatically set to point to the processed version.The SUB_LIST variable is a list of
VAR=VALUE pairs. For each pair
%%VAR%% will get replaced
with VALUE in each file listed in
SUB_FILES. Several common pairs are
automatically defined: PREFIX,
LOCALBASE, X11BASE,
DATADIR, DOCSDIR,
EXAMPLESDIR. Any line beginning with
@comment will be deleted from resulting files
after a variable substitution.The following example will replace %%ARCH%%
with the system architecture
in a pkg-message:SUB_FILES= pkg-message
SUB_LIST= ARCH=${ARCH}Note that for this example, the
pkg-message.in file must exist in
FILESDIR.Example of a good pkg-message.in:Now it is time to configure this package.
Copy %%PREFIX%%/share/examples/putsy/%%ARCH%%.conf into your home directory
as .putsy.conf and edit it.Testing your portRunning make describeSeveral of the &os; port maintenance tools, such as
&man.portupgrade.1;, rely on a database called
/usr/ports/INDEX which keeps track of such
items as port dependencies. INDEX is created
by the top-level ports/Makefile via
make index, which descends into each
port subdirectory and executes make describe
there. Thus, if make describe fails in any
port, no one can generate INDEX, and many
people will quickly become unhappy.It is important to be able to generate this file no
matter what options are present in make.conf,
so please avoid doing things such as using .error
statements when (for instance) a dependency is not satisfied.
(See .)If make describe produces a string
rather than an error message, you are probably safe. See
bsd.port.mk for the meaning of the
string produced.Also note that running a recent version of
portlint (as specified in the next section)
will cause make describe to be run
automatically.PortlintDo check your work with portlint
before you submit or commit it. portlint
warns you about many common errors, both functional and
stylistic. For a new (or repocopied) port,
portlint -A is the most thorough; for an
existing port, portlint -C is sufficient.Since portlint uses heuristics to
try to figure out errors, it can produce false positive
warnings. In addition, occasionally something that is
flagged as a problem really cannot be done in any other
way due to limitations in the ports framework. When in
doubt, the best thing to do is ask on &a.ports;.Port ToolsThe ports-mgmt/porttools
program is part of the Ports Collection.port is the front-end script,
which can help you simplify the testing job. Whenever you want
to test a new port or update an existing one, you can use
port test to test your port, including the
portlint
checking. This command also detects and lists any files that
are not listed in pkg-plist. See the
following example:&prompt.root; port test /usr/ports/net/csupPREFIX 以及 DESTDIRPREFIX 變數會決定該 port 所會安裝的位置,
通常是 /usr/local 或 /opt
。 使用者可以藉由設定 PREFIX 決定要裝在哪邊,
而你所維護的 port 必須遵循該規則。若使用者有設定 DESTDIR 變數,
那麼它會採用所設定的環境,通常可能是 jail 環境或者是並非掛載於
/ 上的系統。 通常 port 會裝在
DESTDIR/PREFIX 底下,
並且會紀錄在 DESTDIR/var/db/pkg 內的套件資料庫。
由於事實上 DESTDIR 會由 ports 架構透過
&man.chroot.8; 來自動處理,所以您不需去作相關修改或刻意維護
DESTDIR 相容的 ports。PREFIX 變數若無特別設定,會與
LOCALBASE 相同 (預設為
/usr/local)。 若有設定
USE_X_PREFIX 或 USE_IMAKE,
那麼 PREFIX 則為 X11BASE (
為了相容的理由,預設仍為 /usr/X11R6,
但不久後會徹底移除)。 若有設定 USE_LINUX_PREFIX,
那麼 PREFIX 則為 LINUXBASE (
預設為 /compat/linux)。Avoiding the hard-coding of /usr/local or
/usr/X11R6 anywhere in the source will make the
port much more flexible and able to cater to the needs of other
sites. For X ports that use imake, this is
automatic; otherwise, this can often be done by simply replacing the
occurrences of /usr/local (or
/usr/X11R6 for X ports that do not use imake)
in the various Makefiles in the port to read
${PREFIX}, as this variable is automatically passed
down to every stage of the build and install processes.Make sure your application is not installing things in
/usr/local instead of PREFIX.
A quick test for this is to do this is:&prompt.root; make clean; make package PREFIX=/var/tmp/port-nameIf anything is installed outside of PREFIX,
the package creation process will complain that it
cannot find the files.This does not test for the existence of internal references,
or correct use of LOCALBASE for references to
files from other ports. Testing the installation in
/var/tmp/port-name
to do that while you have it installed would do that.Do not set USE_X_PREFIX unless your port
truly requires it (i.e., it needs to
reference files in X11BASE).The variable PREFIX can be reassigned in your
Makefile or in the user's environment.
However, it is strongly discouraged for individual ports to set this
variable explicitly in the Makefiles.Also, refer to programs/files from other ports with the
variables mentioned above, not explicit pathnames. For instance, if
your port requires a macro PAGER to be the full
pathname of less, use the compiler flag:
-DPAGER=\"${LOCALBASE}/bin/less\"
instead of
-DPAGER=\"/usr/local/bin/less\". This way it will
have a better chance of working if the system administrator has
moved the whole /usr/local tree somewhere else.TinderboxIf you're an avid ports contributor, you might want to take a
look at Tinderbox. It is a powerful
system for building and testing ports based on the scripts used on
Pointyhat. You can install
Tinderbox using
ports-mgmt/tinderbox port. Be sure
to read supplied documentation since the configuration is not
trivial.Visit the Tinderbox website
for more details.UpgradingWhen you notice that a port is out of date compared to the latest
version from the original authors, you should first ensure that you
have the latest
port. You can find them in the
ports/ports-current directory of the &os; FTP mirror
sites. However, if you are working with more than a few
ports, you will probably find it easier to use
CVSup to keep your whole ports collection
up-to-date, as described in the
Handbook.
This will have the added benefit of tracking all the ports'
dependencies.The next step is to see if there is an update already pending.
To do this, you have two options. There is a searchable interface
to the
FreeBSD Problem Report (PR) database (also known as
GNATS). Select ports in the
dropdown, and enter the name of the port.However, sometimes people forget to put the name of the port
into the Synopsis field in an unambiguous fashion. In that case,
you can try the
FreeBSD Ports Monitoring System (also known as
portsmon). This system attempts to classify
port PRs by portname. To search for PRs about a particular port,
use the
Overview of One Port.If there is no pending PR, the next step is to send an email
to the port's maintainer, as shown by
make maintainer. That person may
already be working on an upgrade, or have a reason to not upgrade the
port right now (because of, for example, stability problems of the new
version); you would not want to duplicate their work. Note that
unmaintained ports are listed with a maintainer of
ports@FreeBSD.org, which is just the general
ports mailing list, so sending mail there
probably will not help in this case.If the maintainer asks you to do the upgrade or there is
no maintainer, then you have a chance to help out &os; by
preparing the update yourself! Please make the changes and save
the result of the
recursive diff output
of the new and old
ports directories (e.g., if your modified port directory is
called superedit and the original is in our tree
as superedit.bak, then save the result of
diff -ruN superedit.bak superedit). Either
unified or context diff is fine, but port committers generally
prefer unified diffs. Note the use of the -N
option—this is the accepted way to force diff to properly
deal with the case of new files being added or old files being
deleted. Before sending us the diff, please examine the
output to make sure all the changes make sense. To
simplify common operations with patch files, you can use
/usr/ports/Tools/scripts/patchtool.py.
Before using it, please read
/usr/ports/Tools/scripts/README.patchtool.If the port is unmaintained, and you are actively using
it yourself, please consider volunteering to become its
maintainer. &os; has over 2000 ports without maintainers,
and this is an area where more volunteers are always needed.
(For a detailed description of the responsibilities of maintainers,
refer to the section in the
Developer's Handbook.)最好的方式是使用 &man.send-pr.1; 並附上 diff 一併回報(類別請選
ports)。 若你是該 port 的維護者,請記得在 synopsis
那行的開頭註明 [maintainer update],並且在 PR 的
Class 分類填上 maintainer-update。
否則,該 PR 的 Class 處就是填
change-request。
Please mention any added or
deleted files in the message, as they have to be explicitly specified
to &man.cvs.1; when doing a commit. If the diff is more than about 20KB,
please compress and uuencode it; otherwise, just include it in the PR
as is.Before you &man.send-pr.1;, you should review the
Writing the problem report section in the Problem
Reports article; it contains far more information about how to write
useful problem reports.If your upgrade is motivated by security concerns or a
serious fault in the currently committed port, please notify
the &a.portmgr; to request immediate rebuilding and
redistribution of your port's package. Unsuspecting users
of &man.pkg.add.1; will otherwise continue to install the
old version via pkg_add -r for several
weeks.Once again, please use &man.diff.1; and not &man.shar.1; to send
updates to existing ports!Now that you have done all that, you will want to read about
how to keep up-to-date in .Ports securityWhy security is so importantBugs are occasionally introduced to the software.
Arguably, the most dangerous of them are those opening
security vulnerabilities. From the technical viewpoint,
such vulnerabilities are to be closed by exterminating
the bugs that caused them. However, the policies for
handling mere bugs and security vulnerabilities are
very different.A typical small bug affects only those users who have
enabled some combination of options triggering the bug.
The developer will eventually release a patch followed
by a new version of the software, free of the bug, but
the majority of users will not take the trouble of upgrading
immediately because the bug has never vexed them. A
critical bug that may cause data loss represents a graver
issue. Nevertheless, prudent users know that a lot of
possible accidents, besides software bugs, are likely to
lead to data loss, and so they make backups of important
data; in addition, a critical bug will be discovered
really soon.A security vulnerability is all different. First,
it may remain unnoticed for years because often it does
not cause software malfunction. Second, a malicious party
can use it to gain unauthorized access to a vulnerable
system, to destroy or alter sensitive data; and in the
worst case the user will not even notice the harm caused.
Third, exposing a vulnerable system often assists attackers
to break into other systems that could not be compromised
otherwise. Therefore closing a vulnerability alone is
not enough: the audience should be notified of it in most
clear and comprehensive manner, which will allow to
evaluate the danger and take appropriate actions.Fixing security vulnerabilitiesWhile on the subject of ports and packages, a security
vulnerability may initially appear in the original
distribution or in the port files. In the former case,
the original software developer is likely to release a
patch or a new version instantly, and you will
only need to update the port promptly with respect to
the author's fix. If the fix is delayed for some reason,
you should either mark the port as
FORBIDDEN
or introduce a patch file of your own to the port. In
the case of a vulnerable port, just fix the port as soon as
possible. In either case, the
standard procedure for submitting your change should
be followed unless you have rights to commit it directly
to the ports tree.Being a ports committer is not enough to commit to
an arbitrary port. Remember that ports usually have
maintainers, whom you should respect.Please make sure that the port's revision is bumped
as soon as the vulnerability has been closed.
That is how the users who upgrade installed packages
on a regular basis will see they need to run an update.
Besides, a new package will be built and distributed
over FTP and WWW mirrors, replacing the vulnerable one.
PORTREVISION should be bumped unless
PORTVERSION has changed in the course
of correcting the vulnerability. That is you should
bump PORTREVISION if you have added a
patch file to the port, but you should not if you have updated
the port to the latest software version and thus already
touched PORTVERSION. Please refer to the
corresponding section
for more information.Keeping the community informedThe VuXML databaseA very important and urgent step to take as early as
a security vulnerability is discovered is to notify the
community of port users about the jeopardy. Such
notification serves two purposes. First, should the danger
be really severe, it will be wise to apply an instant workaround,
e.g., stop the affected network service or even deinstall
the port completely, until the vulnerability is closed.
Second, a lot of users tend to upgrade installed packages
just occasionally. They will know from the notification
that they must update the package
without delay as soon as a corrected version is available.Given the huge number of ports in the tree,
a security advisory cannot be issued on each incident
without creating a flood and losing the attention of
the audience by the time it comes to really serious
matters. Therefore security vulnerabilities found in
ports are recorded in the FreeBSD VuXML
database. The Security Officer Team members
are monitoring it for issues requiring their
intervention.If you have committer rights, you can update the VuXML
database by yourself. So you will both help the Security
Officer Team and deliver the crucial information to the
community earlier. However, if you are not a committer,
or you believe you have found an exceptionally severe
vulnerability, or whatever, please do not hesitate to
contact the Security Officer Team directly as described
on the FreeBSD
Security Information page.All right, you elected the hard way. As it may be obvious
from its title, the VuXML database is essentially an
XML document. Its source file vuln.xml
is kept right inside the port security/vuxml. Therefore
the file's full pathname will be
PORTSDIR/security/vuxml/vuln.xml.
Each time you discover a security vulnerability in a
port, please add an entry for it to that file.
Until you are familiar with VuXML, the best thing you can
do is to find an existing entry fitting your case, then copy
it and use as a template.A short introduction to VuXMLThe full-blown XML is complex and far beyond the scope of
this book. However, to gain basic insight on the structure
of a VuXML entry, you need only the notion of tags. XML
tag names are enclosed in angle brackets. Each opening
<tag> must have a matching closing </tag>.
Tags may be nested. If nesting, the inner tags must be
closed before the outer ones. There is a hierarchy of
tags, i.e. more complex rules of nesting them. Sounds
very similar to HTML, doesn't it? The major difference
is that XML is eXtensible, i.e. based
on defining custom tags. Due to its intrinsic structure,
XML puts otherwise amorphous data into shape. VuXML is
particularly tailored to mark up descriptions of security
vulnerabilities.Now let's consider a realistic VuXML entry:<vuln vid="f4bc80f4-da62-11d8-90ea-0004ac98a7b9">
<topic>Several vulnerabilities found in Foo</topic>
<affects>
<package>
<name>foo</name>
<name>foo-devel</name>
<name>ja-foo</name>
<range><ge>1.6</ge><lt>1.9</lt></range>
<range><ge>2.*</ge><lt>2.4_1</lt></range>
<range><eq>3.0b1</eq></range>
</package>
<package>
<name>openfoo</name>
<range><lt>1.10_7</lt></range>
<range><ge>1.2,1</ge><lt>1.3_1,1</lt></range>
</package>
</affects>
<description>
<body xmlns="http://www.w3.org/1999/xhtml">
<p>J. Random Hacker reports:</p>
<blockquote
cite="http://j.r.hacker.com/advisories/1">
<p>Several issues in the Foo software may be exploited
via carefully crafted QUUX requests. These requests will
permit the injection of Bar code, mumble theft, and the
readability of the Foo administrator account.</p>
</blockquote>
</body>
</description>
<references>
<freebsdsa>SA-10:75.foo</freebsdsa>
<freebsdpr>ports/987654</freebsdpr>
<cvename>CAN-2010-0201</cvename>
<cvename>CAN-2010-0466</cvename>
<bid>96298</bid>
<certsa>CA-2010-99</certsa>
<certvu>740169</certvu>
<uscertsa>SA10-99A</uscertsa>
<uscertta>SA10-99A</uscertta>
<mlist msgid="201075606@hacker.com">http://marc.theaimsgroup.com/?l=bugtraq&m=203886607825605</mlist>
<url>http://j.r.hacker.com/advisories/1</url>
</references>
<dates>
<discovery>2010-05-25</discovery>
<entry>2010-07-13</entry>
<modified>2010-09-17</entry>
</dates>
</vuln>The tag names are supposed to be self-descriptive,
so we shall take a closer look only at fields you will need
to fill in by yourself:This is the top-level tag of a VuXML entry. It has
a mandatory attribute, vid,
specifying a universally unique identifier (UUID) for
this entry (in quotes). You should generate a UUID
for each new VuXML entry (and do not forget to substitute
it for the template UUID unless you are writing the
entry from scratch). You can use &man.uuidgen.1; to
generate a VuXML UUID; alternatively, if you are using
FreeBSD 4.x, you may install the port devel/p5-Data-UUID and issue
the following command:perl -MData::UUID -le 'print lc new Data::UUID->create_str'This is a one-line description of the issue found.The names of packages affected are listed there.
Multiple names can be given since several packages may be
based on a single master port or software product. This
may include stable and development branches, localized
versions, and slave ports featuring different choices of
important build-time configuration options.It is your responsibility to find all such related
packages when writing a VuXML entry. Keep in mind that
make search name=foo is your friend.
The primary points to look for are as follows:the foo-devel variant
for a foo port;other variants with a suffix like
-a4 (for print-related packages),
-without-gui (for packages with X
support disabled), or similar;jp-, ru-,
zh-, and other possible localized
variants in the corresponding national categories of
the ports collection.Affected versions of the package(s) are specified
there as one or more ranges using a combination of
<lt>, <le>,
<eq>, <ge>,
and <gt> elements. The
version ranges given should not overlap.In a range specification, * (asterisk)
denotes the smallest version number. In particular,
2.* is less than 2.a.
Therefore an asterisk may be used for a range to match all
possible alpha, beta,
and RC versions. For instance,
<ge>2.*</ge><lt>3.*</lt>
will selectively match every 2.x version while
<ge>2.0</ge><lt>3.0</lt>
will obviously not since the latter misses
2.r3 and matches
3.b.The above example
specifies that affected are versions from 1.6
to 1.9 inclusive, versions
2.x before 2.4_1,
and version 3.0b1.Several related package groups (essentially, ports)
can be listed in the <affected>
section. This can be used if several software products
(say FooBar, FreeBar and OpenBar) grow from the same code base
and still share its bugs and vulnerabilities. Note the
difference from listing multiple names within a single
<package> section.The version ranges should allow for
PORTEPOCH and
PORTREVISION if applicable.
Please remember that according to the collation rules,
a version with a non-zero PORTEPOCH is
greater than any version without
PORTEPOCH, e.g., 3.0,1
is greater than 3.1 or even than
8.9.This is a summary of the issue.
XHTML is used in this field. At least enclosing
<p> and </p>
should appear. More complex mark-up may be used, but only for
the sake of accuracy and clarity: No eye candy please.This section contains references to relevant documents.
As many references as apply are encouraged.This is a
FreeBSD
security advisory.This is a
FreeBSD
problem report.This is a Mitre
CVE identifier.This is a
SecurityFocus
Bug ID.This is a
US-CERT
security advisory.This is a
US-CERT
vulnerability note.This is a
US-CERT
Cyber Security Alert.This is a
US-CERT
Technical Cyber Security Alert.This is a URL to an archived posting in a mailing list.
The attribute msgid is optional and
may specify the message ID of the posting.This is a generic URL. It should be used only if none of
the other reference categories apply.This is the date when the issue was disclosed
(YYYY-MM-DD).This is the date when the entry was added
(YYYY-MM-DD).This is the date when any information in the entry
was last modified (YYYY-MM-DD).
New entries must not include this field. It should be added
upon editing an existing entry.Testing your changes to the VuXML databaseAssume you just wrote or filled in an entry for a
vulnerability in the package clamav
that has been fixed in version 0.65_7.As a prerequisite, you need to install fresh versions of the
ports ports-mgmt/portaudit and
ports-mgmt/portaudit-db.First, check whether there already is an entry for this
vulnerability. If there were such entry, it would match the
previous version of the package,
0.65_6:&prompt.user; packaudit
&prompt.user; portaudit clamav-0.65_6To run packaudit, you must have
permission to write to its
DATABASEDIR,
typically /var/db/portaudit.If there is none found, you get the green light to add
a new entry for this vulnerability. Now you can generate
a brand-new UUID (assume it's
74a9541d-5d6c-11d8-80e3-0020ed76ef5a) and
add your new entry to the VuXML database. Please verify
its syntax after that as follows:&prompt.user; cd ${PORTSDIR}/security/vuxml && make validateYou will need at least one of the following packages
installed: textproc/libxml2,
textproc/jade.Now rebuild the portaudit database
from the VuXML file:&prompt.user; packauditTo verify that the <affected>
section of your entry will match correct package(s), issue
the following command:&prompt.user; portaudit -f /usr/ports/INDEX -r 74a9541d-5d6c-11d8-80e3-0020ed76ef5aPlease refer to &man.portaudit.1; for better understanding
of the command syntax.Make sure that your entry produces no spurious matches
in the output.Now check whether the right package versions are matched
by your entry:&prompt.user; portaudit clamav-0.65_6 clamav-0.65_7
Affected package: clamav-0.65_6 (matched by clamav<0.65_7)
Type of problem: clamav remote denial-of-service.
Reference: <http://www.freebsd.org/ports/portaudit/74a9541d-5d6c-11d8-80e3-0020ed76ef5a.html>
1 problem(s) found.Obviously, the former version should match while the
latter one should not.Finally, verify whether the web page generated from the
VuXML database looks like expected:&prompt.user; mkdir -p ~/public_html/portaudit
&prompt.user; packaudit
&prompt.user; lynx ~/public_html/portaudit/74a9541d-5d6c-11d8-80e3-0020ed76ef5a.htmlDos and Don'tsIntroductionHere is a list of common dos and don'ts that you encounter during
the porting process. You should check your own port against this list,
but you can also check ports in the PR database that others have
submitted. Submit any comments on ports you check as described in
Bug Reports and General
Commentary. Checking ports in the PR database will both make
it faster for us to commit them, and prove that you know what you are
doing.WRKDIRDo not write anything to files outside
WRKDIR. WRKDIR is the only
place that is guaranteed to be writable during the port build (see
installing ports from a CDROM for an
example of building ports from a read-only tree). If you need to
modify one of the pkg-*
files, do so by redefining a variable, not by
writing over it.WRKDIRPREFIXMake sure your port honors WRKDIRPREFIX.
Most ports do not have to worry about this. In particular, if you
are referring to a WRKDIR of another port, note
that the correct location is
WRKDIRPREFIXPORTSDIR/subdir/name/work not PORTSDIR/subdir/name/work or .CURDIR/../../subdir/name/work or some such.Also, if you are defining WRKDIR yourself,
make sure you prepend
${WRKDIRPREFIX}${.CURDIR} in the
front.Differentiating operating systems and OS versionsYou may come across code that needs modifications or conditional
compilation based upon what version of Unix it is running under. If
you need to make such changes to the code for conditional
compilation, make sure you make the changes as general as possible
so that we can back-port code to older FreeBSD systems and cross-port
to other BSD systems such as 4.4BSD from CSRG, BSD/386, 386BSD,
NetBSD, and OpenBSD.The preferred way to tell 4.3BSD/Reno (1990) and newer versions
of the BSD code apart is by using the BSD macro
defined in
sys/param.h.
Hopefully that
file is already included; if not, add the code:#if (defined(__unix__) || defined(unix)) && !defined(USG)
#include <sys/param.h>
#endifto the proper place in the .c file. We
believe that every system that defines these two symbols has
sys/param.h. If you find a system that
does not, we would like to know. Please send mail to the
&a.ports;.Another way is to use the GNU Autoconf style of doing
this:#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endifDo not forget to add -DHAVE_SYS_PARAM_H to the
CFLAGS in the Makefile for
this method.Once you have sys/param.h included, you may
use:#if (defined(BSD) && (BSD >= 199103))to detect if the code is being compiled on a 4.3 Net2 code base
or newer (e.g. FreeBSD 1.x, 4.3/Reno, NetBSD 0.9, 386BSD, BSD/386
1.1 and below).Use:#if (defined(BSD) && (BSD >= 199306))to detect if the code is being compiled on a 4.4 code base or
newer (e.g. FreeBSD 2.x, 4.4, NetBSD 1.0, BSD/386 2.0 or
above).The value of the BSD macro is
199506 for the 4.4BSD-Lite2 code base. This is
stated for informational purposes only. It should not be used to
distinguish between versions of FreeBSD based only on 4.4-Lite vs.
versions that have merged in changes from 4.4-Lite2. The
__FreeBSD__ macro should be used instead.Use sparingly:__FreeBSD__ is defined in all versions of
FreeBSD. Use it if the change you are making
only affects FreeBSD. Porting gotchas like
the use of sys_errlist[] vs
strerror() are Berkeley-isms, not FreeBSD
changes.In FreeBSD 2.x, __FreeBSD__ is defined to
be 2. In earlier versions, it is
1. Later versions always bump it to match
their major version number.If you need to tell the difference between a FreeBSD 1.x
system and a FreeBSD 2.x or above system, usually the right answer
is to use the BSD macros described above. If
there actually is a FreeBSD specific change (such as special
shared library options when using ld) then it
is OK to use __FreeBSD__ and #if
__FreeBSD__ > 1 to detect a FreeBSD 2.x and later
system. If you need more granularity in detecting FreeBSD
systems since 2.0-RELEASE you can use the following:#if __FreeBSD__ >= 2
#include <osreldate.h>
# if __FreeBSD_version >= 199504
/* 2.0.5+ release specific code here */
# endif
#endifIn the hundreds of ports that have been done, there have only
been one or two cases where __FreeBSD__ should
have been used. Just because an earlier port screwed up and used it
in the wrong place does not mean you should do so too.FreeBSD 版本速查表(__FreeBSD_version)以下是 sys/param.h 內的 __FreeBSD_version 版本速查表:
__FreeBSD_version valuesRelease__FreeBSD_version2.0-RELEASE1194112.1-CURRENT199501, 1995032.0.5-RELEASE1995042.2-CURRENT before 2.11995082.1.0-RELEASE1995112.2-CURRENT before 2.1.51995122.1.5-RELEASE1996072.2-CURRENT before 2.1.61996082.1.6-RELEASE1996122.1.7-RELEASE1996122.2-RELEASE2200002.2.1-RELEASE220000 (no change)2.2-STABLE after 2.2.1-RELEASE220000 (no change)2.2-STABLE after texinfo-3.92210012.2-STABLE after top2210022.2.2-RELEASE2220002.2-STABLE after 2.2.2-RELEASE2220012.2.5-RELEASE2250002.2-STABLE after 2.2.5-RELEASE2250012.2-STABLE after ldconfig -R merge2250022.2.6-RELEASE2260002.2.7-RELEASE2270002.2-STABLE after 2.2.7-RELEASE2270012.2-STABLE after &man.semctl.2; change2270022.2.8-RELEASE2280002.2-STABLE after 2.2.8-RELEASE2280013.0-CURRENT before &man.mount.2; change3000003.0-CURRENT after &man.mount.2; change3000013.0-CURRENT after &man.semctl.2; change3000023.0-CURRENT after ioctl arg changes3000033.0-CURRENT after ELF conversion3000043.0-RELEASE3000053.0-CURRENT after 3.0-RELEASE3000063.0-STABLE after 3/4 branch3000073.1-RELEASE3100003.1-STABLE after 3.1-RELEASE3100013.1-STABLE after C++ constructor/destructor order
change3100023.2-RELEASE3200003.2-STABLE3200013.2-STABLE after binary-incompatible IPFW and
socket changes3200023.3-RELEASE3300003.3-STABLE3300013.3-STABLE after adding &man.mkstemp.3;
to libc3300023.4-RELEASE3400003.4-STABLE3400013.5-RELEASE3500003.5-STABLE3500014.0-CURRENT after 3.4 branch4000004.0-CURRENT after change in dynamic linker
handling4000014.0-CURRENT after C++ constructor/destructor
order change4000024.0-CURRENT after functioning &man.dladdr.3;4000034.0-CURRENT after __deregister_frame_info dynamic
linker bug fix (also 4.0-CURRENT after EGCS 1.1.2
integration)
4000044.0-CURRENT after &man.suser.9; API change
(also 4.0-CURRENT after newbus)4000054.0-CURRENT after cdevsw registration change4000064.0-CURRENT after the addition of so_cred for
socket level credentials4000074.0-CURRENT after the addition of a poll syscall
wrapper to libc_r4000084.0-CURRENT after the change of the kernel's
dev_t type to struct
specinfo pointer4000094.0-CURRENT after fixing a hole
in &man.jail.2;4000104.0-CURRENT after the sigset_t
datatype change4000114.0-CURRENT after the cutover to the GCC 2.95.2
compiler4000124.0-CURRENT after adding pluggable linux-mode
ioctl handlers4000134.0-CURRENT after importing OpenSSL4000144.0-CURRENT after the C++ ABI change in GCC 2.95.2
from -fvtable-thunks to -fno-vtable-thunks by
default4000154.0-CURRENT after importing OpenSSH4000164.0-RELEASE4000174.0-STABLE after 4.0-RELEASE4000184.0-STABLE after the introduction of delayed
checksums.4000194.0-STABLE after merging libxpg4 code into
libc.4000204.0-STABLE after upgrading Binutils to 2.10.0, ELF
branding changes, and tcsh in the base system.4000214.1-RELEASE4100004.1-STABLE after 4.1-RELEASE4100014.1-STABLE after &man.setproctitle.3; moved from
libutil to libc.4100024.1.1-RELEASE4110004.1.1-STABLE after 4.1.1-RELEASE4110014.2-RELEASE4200004.2-STABLE after combining libgcc.a and
libgcc_r.a, and associated GCC linkage changes.4200014.3-RELEASE4300004.3-STABLE after wint_t introduction.4300014.3-STABLE after PCI powerstate API merge.4300024.4-RELEASE4400004.4-STABLE after d_thread_t introduction.4400014.4-STABLE after mount structure changes (affects
filesystem klds).4400024.4-STABLE after the userland components of smbfs
were imported.4400034.5-RELEASE4500004.5-STABLE after the usb structure element rename.4500014.5-STABLE after the
sendmail_enable &man.rc.conf.5;
variable was made to take the value
NONE.4500044.5-STABLE after moving to XFree86 4 by default
for package builds.4500054.5-STABLE after accept filtering was fixed so
that is no longer susceptible to an easy DoS.4500064.6-RELEASE4600004.6-STABLE &man.sendfile.2; fixed to comply with
documentation, not to count any headers sent against
the amount of data to be sent from the file.4600014.6.2-RELEASE4600024.6-STABLE4601004.6-STABLE after MFC of `sed -i'.4601014.6-STABLE after MFC of many new pkg_install
features from the HEAD.4601024.7-RELEASE4700004.7-STABLE470100Start generated __std{in,out,err}p references rather
than __sF. This changes std{in,out,err} from a
compile time expression to a runtime one.4701014.7-STABLE after MFC of mbuf changes to replace
m_aux mbufs by m_tag's4701024.7-STABLE gets OpenSSL 0.9.74701034.8-RELEASE4800004.8-STABLE4801004.8-STABLE after &man.realpath.3; has been made
thread-safe4801014.8-STABLE 3ware API changes to twe.4801024.9-RELEASE4900004.9-STABLE4901004.9-STABLE after e_sid was added to struct
kinfo_eproc.4901014.9-STABLE after MFC of libmap functionality
for rtld.4901024.10-RELEASE4910004.10-STABLE4911004.10-STABLE after MFC of revision 20040629 of
the package tools4911014.10-STABLE after VM fix dealing with unwiring
of fictitious pages4911024.11-RELEASE4920004.11-STABLE4921004.11-STABLE after adding libdata/ldconfig directories
to mtree files.4921015.0-CURRENT5000005.0-CURRENT after adding addition ELF header fields,
and changing our ELF binary branding method.5000015.0-CURRENT after kld metadata changes.5000025.0-CURRENT after buf/bio changes.5000035.0-CURRENT after binutils upgrade.5000045.0-CURRENT after merging libxpg4 code into
libc and after TASKQ interface introduction.5000055.0-CURRENT after the addition of AGP
interfaces.5000065.0-CURRENT after Perl upgrade to 5.6.05000075.0-CURRENT after the update of KAME code to
2000/07 sources.5000085.0-CURRENT after ether_ifattach() and
ether_ifdetach() changes.5000095.0-CURRENT after changing mtree defaults
back to original variant, adding -L to follow
symlinks.5000105.0-CURRENT after kqueue API changed.5000115.0-CURRENT after &man.setproctitle.3; moved from
libutil to libc.5000125.0-CURRENT after the first SMPng commit.5000135.0-CURRENT after <sys/select.h> moved to
<sys/selinfo.h>.5000145.0-CURRENT after combining libgcc.a and
libgcc_r.a, and associated GCC linkage changes.5000155.0-CURRENT after change allowing libc and libc_r
to be linked together, deprecating -pthread
option.5000165.0-CURRENT after switch from struct ucred to
struct xucred to stabilize kernel-exported API for
mountd et al.5000175.0-CURRENT after addition of CPUTYPE make variable
for controlling CPU-specific optimizations.5000185.0-CURRENT after moving machine/ioctl_fd.h to
sys/fdcio.h5000195.0-CURRENT after locale names renaming.5000205.0-CURRENT after Bzip2 import.
Also signifies removal of S/Key.5000215.0-CURRENT after SSE support.5000225.0-CURRENT after KSE Milestone 2.5000235.0-CURRENT after d_thread_t,
and moving UUCP to ports.5000245.0-CURRENT after ABI change for descriptor
and creds passing on 64 bit platforms.5000255.0-CURRENT after moving to XFree86 4 by default for
package builds, and after the new libc strnstr() function
was added.5000265.0-CURRENT after the new libc strcasestr() function
was added.5000275.0-CURRENT after the userland components of smbfs
were imported.5000285.0-CURRENT after the new C99 specific-width
integer types were added.(Not incremented.)5.0-CURRENT after a change was made in the return
value of &man.sendfile.2;.5000295.0-CURRENT after the introduction of the
type fflags_t, which is the
appropriate size for file flags.5000305.0-CURRENT after the usb structure element rename.5000315.0-CURRENT after the introduction of
Perl 5.6.1.5000325.0-CURRENT after the
sendmail_enable &man.rc.conf.5;
variable was made to take the value
NONE.5000335.0-CURRENT after mtx_init() grew a third argument.5000345.0-CURRENT with Gcc 3.1.5000355.0-CURRENT without Perl in /usr/src5000365.0-CURRENT after the addition of &man.dlfunc.3;5000375.0-CURRENT after the types of some struct
sockbuf members were changed and the structure was
reordered.5000385.0-CURRENT after GCC 3.2.1 import.
Also after headers stopped using
_BSD_FOO_T_ and started using _FOO_T_DECLARED.
This value can also be used as a conservative
estimate of the start of &man.bzip2.1; package
support.5000395.0-CURRENT after various changes to disk functions
were made in the name of removing dependency on disklabel
structure internals.5000405.0-CURRENT after the addition of &man.getopt.long.3;
to libc.5000415.0-CURRENT after Binutils 2.13 upgrade, which
included new FreeBSD emulation, vec, and output format.
5000425.0-CURRENT after adding weak pthread_XXX stubs
to libc, obsoleting libXThrStub.so. 5.0-RELEASE.5000435.0-CURRENT after branching for RELENG_5_0500100<sys/dkstat.h> is empty and should
not be included.5001015.0-CURRENT after the d_mmap_t interface
change.5001025.0-CURRENT after taskqueue_swi changed to run
without Giant, and taskqueue_swi_giant added to run
with Giant.500103cdevsw_add() and cdevsw_remove() no
longer exists.
Appearance of MAJOR_AUTO allocation facility.5001045.0-CURRENT after new cdevsw initialization method.500105devstat_add_entry() has been replaced by
devstat_new_entry()500106Devstat interface change; see sys/sys/param.h 1.149500107Token-Ring interface changes.500108Addition of vm_paddr_t.5001095.0-CURRENT after &man.realpath.3; has been made
thread-safe5001105.0-CURRENT after &man.usbhid.3; has been synced with
NetBSD5001115.0-CURRENT after new NSS implementation
and addition of POSIX.1 getpw*_r, getgr*_r
functions5001125.0-CURRENT after removal of the old rc system.5001135.1-RELEASE.5010005.1-CURRENT after branching for RELENG_5_1.5011005.1-CURRENT after correcting the semantics of
sigtimedwait(2) and sigwaitinfo(2).5011015.1-CURRENT after adding the lockfunc and lockfuncarg
fields to &man.bus.dma.tag.create.9;.5011025.1-CURRENT after GCC 3.3.1-pre 20030711 snapshot
integration.5011035.1-CURRENT 3ware API changes to twe.5011045.1-CURRENT dynamically-linked /bin and /sbin
support and movement of libraries to /lib.5011055.1-CURRENT after adding kernel support for
Coda 6.x.5011065.1-CURRENT after 16550 UART constants moved from
<dev/sio/sioreg.h> to
<dev/ic/ns16550.h>.
Also when libmap functionality was unconditionally
supported by rtld.5011075.1-CURRENT after PFIL_HOOKS API update5011085.1-CURRENT after adding kiconv(3)5011095.1-CURRENT after changing default operations
for open and close in cdevsw5011105.1-CURRENT after changed layout of cdevsw501111 5.1-CURRENT after adding kobj multiple inheritance
501112 5.1-CURRENT after the if_xname change in
struct ifnet501113 5.1-CURRENT after changing /bin and /sbin to
be dynamically linked5011145.2-RELEASE5020005.2.1-RELEASE5020105.2-CURRENT after branching for RELENG_5_25021005.2-CURRENT after __cxa_atexit/__cxa_finalize
functions were added to libc.5021015.2-CURRENT after change of default thread library
from libc_r to libpthread.5021025.2-CURRENT after device driver API megapatch.
5021035.2-CURRENT after getopt_long_only() addition.
5021045.2-CURRENT after NULL is made into ((void *)0)
for C, creating more warnings.
5021055.2-CURRENT after pf is linked to the build and
install.
5021065.2-CURRENT after time_t is changed to a
64-bit value on sparc64.
5021075.2-CURRENT after Intel C/C++ compiler support in some headers and execve(2) changes to be more strictly conforming to POSIX.
5021085.2-CURRENT after the introduction of the
bus_alloc_resource_any API
5021095.2-CURRENT after the addition of UTF-8 locales
5021105.2-CURRENT after the removal of the getvfsent(3)
API
5021115.2-CURRENT after the addition of the .warning
directive for make.5021125.2-CURRENT after ttyioctl() was made mandatory
for serial drivers.5021135.2-CURRENT after import of the ALTQ framework.
5021145.2-CURRENT after changing sema_timedwait(9) to
return 0 on success and a non-zero error code on
failure.
5021155.2-CURRENT after changing kernel dev_t to
be pointer to struct cdev *.
5021165.2-CURRENT after changing kernel udev_t to dev_t.
5021175.2-CURRENT after adding support for CLOCK_VIRTUAL
and CLOCK_PROF to clock_gettime(2) and clock_getres(2).
5021185.2-CURRENT after changing network interface
cloning overhaul.
5021195.2-CURRENT after the update of the package tools
to revision 20040629.
5021205.2-CURRENT after marking Bluetooth code as
non-i386 specific.
5021215.2-CURRENT after the introduction of the KDB
debugger framework, the conversion of DDB into a
backend and the introduction of the GDB backend.
5021225.2-CURRENT after change to make
VFS_ROOT take a struct
thread argument as does vflush. Struct kinfo_proc
now has a user data pointer.
The switch of the default X implementation to
xorg was also made at this time.
5021235.2-CURRENT after the change to separate the way
ports rc.d and legacy scripts are started.
5021245.2-CURRENT after the backout of the
previous change.
5021255.2-CURRENT after the removal of
kmem_alloc_pageable() and the import of gcc 3.4.2.
5021265.2-CURRENT after changing the UMA kernel
API to allow ctors/inits to fail.
5021275.2-CURRENT after the change of the
vfs_mount signature as well as global replacement of
PRISON_ROOT with SUSER_ALLOWJAIL for the suser(9)
API.
5021285.3-BETA/RC before the pfil API change5030005.3-RELEASE5030015.3-STABLE after branching for RELENG_5_35031005.3-STABLE after addition of glibc style
&man.strftime.3; padding options.5031015.3-STABLE after OpenBSD's nc(1) import MFC.5031025.4-PRERELEASE after the MFC of the fixes in
<src/include/stdbool.h> and
<src/sys/i386/include/_types.h>
for using the GCC-compatibility of the Intel C/C++ compiler.5031035.4-PRERELEASE after the MFC of the change of
ifi_epoch from wall clock time to uptime.5031045.4-PRERELEASE after the MFC of the fix of EOVERFLOW check in vswprintf(3).5031055.4-RELEASE.5040005.4-STABLE after branching for RELENG_5_45041005.4-STABLE after increasing the default
thread stacksizes5041015.4-STABLE after the addition of sha2565041025.4-STABLE after the MFC of if_bridge5041035.4-STABLE after the MFC of bsdiff and portsnap5041045.4-STABLE after MFC of ldconfig_local_dirs
change.5041055.5-RELEASE.5050005.5-STABLE after branching for RELENG_5_55051006.0-CURRENT6000006.0-CURRENT after permanently enabling PFIL_HOOKS
in the kernel.
6000016.0-CURRENT after initial addition of
ifi_epoch to struct if_data. Backed out after a
few days. Do not use this value.
6000026.0-CURRENT after the re-addition of the
ifi_epoch member of struct if_data.
6000036.0-CURRENT after addition of the struct inpcb
argument to the pfil API.
6000046.0-CURRENT after addition of the "-d
DESTDIR" argument to newsyslog.
6000056.0-CURRENT after addition of glibc style
&man.strftime.3; padding options.
6000066.0-CURRENT after addition of 802.11 framework
updates.
6000076.0-CURRENT after changes to VOP_*VOBJECT() functions
and introduction of MNTK_MPSAFE flag for Giantfree filesystems.
6000086.0-CURRENT after addition of the cpufreq framework
and drivers.
6000096.0-CURRENT after importing OpenBSD's nc(1).6000106.0-CURRENT after removing semblance of SVID2
matherr() support.6000116.0-CURRENT after increase of default thread stacks'
size.6000126.0-CURRENT after fixes in
<src/include/stdbool.h> and
<src/sys/i386/include/_types.h>
for using the GCC-compatibility of the Intel C/C++ compiler.6000136.0-CURRENT after EOVERFLOW checks in vswprintf(3) fixed.6000146.0-CURRENT after changing the struct if_data
member, ifi_epoch, from wall clock time to uptime.6000156.0-CURRENT after LC_CTYPE disk format changed.6000166.0-CURRENT after NLS catalogs disk format changed.6000176.0-CURRENT after LC_COLLATE disk format changed.600018Installation of acpica includes into /usr/include.600019Addition of MSG_NOSIGNAL flag to send(2) API.600020Addition of fields to cdevsw600021Removed gtar from base system.600022LOCAL_CREDS, LOCAL_CONNWAIT socket options added to unix(4).600023&man.hwpmc.4; and related tools added to 6.0-CURRENT.600024struct icmphdr added to 6.0-CURRENT.600025pf updated to 3.7.600026Kernel libalias and ng_nat introduced.600027POSIX ttyname_r(3) made available through unistd.h and libc.6000286.0-CURRENT after libpcap updated to v0.9.1 alpha 096.6000296.0-CURRENT after importing NetBSD's if_bridge(4).6000306.0-CURRENT after struct ifnet was broken out
of the driver softcs.6000316.0-CURRENT after the import of libpcap v0.9.1.6000326.0-STABLE after bump of all shared library
versions that had not been changed since
RELENG_5.6000336.0-STABLE after credential argument is added to
dev_clone event handler. 6.0-RELEASE.6000346.0-STABLE after 6.0-RELEASE6001006.0-STABLE after incorporating scripts from the
local_startup directories into the base &man.rcorder.8;.6001016.0-STABLE after updating the ELF types and
constants.6001026.0-STABLE after MFC of pidfile(3) API.6001036.0-STABLE after MFC of ldconfig_local_dirs
change.6001046.0-STABLE after NLS catalog support of
csh(1).6001056.1-RELEASE6010006.1-STABLE after 6.1-RELEASE.6011006.1-STABLE after the import of csup.6011016.1-STABLE after the iwi(4) update.6011026.1-STABLE after the resolver update to
BIND9, and exposure of reentrant version of
netdb functions.6011036.1-STABLE after DSO (dynamic shared
objects) support has been enabled in
OpenSSL.6011046.1-STABLE after 802.11 fixups changed the
api for the IEEE80211_IOC_STA_INFO ioctl.6011046.2-RELEASE6020006.2-STABLE after 6.2-RELEASE.6021006.2-STABLE after the addition of Wi-Spy
quirk.6021016.2-STABLE after pci_find_extcap() addition.6021026.2-STABLE after MFC of dlsym change to look
for a requested symbol both
in specified dso and its implicit dependencies.6021036.2-STABLE after MFC of ng_deflate(4) and
ng_pred1(4) netgraph nodes and new compression and
encryption modes for ng_ppp(4) node.6021046.2-STABLE after MFC of BSD licensed version of &man.gzip.1;
ported from NetBSD.6021056.2-STABLE after MFC of PCI MSI and MSI-X
support.6021066.2-STABLE after MFC of ncurses 5.6 and wide
character support.6021076.2-STABLE after MFC of CAM 'SG' peripheral device,
which implements a subset of Linux SCSI SG passthrough device API.6021086.2-STABLE after MFC of readline 5.2 patchset 002.6021096.2-STABLE after MFC of pmap_invalidate_cache(),
pmap_change_attr(), pmap_mapbios(), pmap_mapdev_attr(),
and pmap_unmapbios() for amd64 and i386.6021106.2-STABLE after MFC of BOP_BDFLUSH and caused
breakage of the filesystem modules KBI.6021116.2-STABLE after libutil(3) MFC's.6021127.0-CURRENT.7000007.0-CURRENT after bump of all shared library
versions that had not been changed since
RELENG_5.7000017.0-CURRENT after credential argument is added to
dev_clone event handler.7000027.0-CURRENT after memmem(3) is added to libc.7000037.0-CURRENT after solisten(9) kernel arguments
are modified to accept a backlog parameter.7000047.0-CURRENT after IFP2ENADDR() was changed to return
a pointer to IF_LLADDR().7000057.0-CURRENT after addition of if_addr
member to struct ifnet and IFP2ENADDR()
removal.7000067.0-CURRENT after incorporating scripts from the
local_startup directories into the base &man.rcorder.8;.7000077.0-CURRENT after removal of MNT_NODEV mount
option.7000087.0-CURRENT after ELF-64 type changes and symbol
versioning.7000097.0-CURRENT after addition of hostb and vgapci
drivers, addition of pci_find_extcap(), and changing
the AGP drivers to no longer map the aperture.7000107.0-CURRENT after tv_sec was made time_t on
all platforms but Alpha.7000117.0-CURRENT after ldconfig_local_dirs change.7000127.0-CURRENT after changes to
/etc/rc.d/abi to support
/compat/linux/etc/ld.so.cache
being a symlink in a readonly filesystem.7000137.0-CURRENT after pts import.7000147.0-CURRENT after the introduction of version 2
of &man.hwpmc.4;'s ABI.7000157.0-CURRENT after addition of &man.fcloseall.3;
to libc.7000167.0-CURRENT after removal of ip6fw.7000177.0-CURRENT after import of snd_emu10kx.7000187.0-CURRENT after import of OpenSSL 0.9.8b.7000197.0-CURRENT after addition of bus_dma_get_tag
function7000207.0-CURRENT after libpcap 0.9.4 and
tcpdump 3.9.4 import.7000217.0-CURRENT after dlsym change to look
for a requested symbol both
in specified dso and its implicit dependencies.7000227.0-CURRENT after adding new sound IOCTLs.7000237.0-CURRENT after import of OpenSSL 0.9.8d.7000247.0-CURRENT after the addition of libelf.7000257.0-CURRENT after major changes on sound
sysctls.7000267.0-CURRENT after the addition of Wi-Spy
quirk.7000277.0-CURRENT after the addition of sctp calls to libc
7000287.0-CURRENT after the GNU &man.gzip.1; implementation was
replaced with a BSD licensed version ported from NetBSD.7000297.0-CURRENT after the removal of IPIP tunnel encapsulation (VIFF_TUNNEL) from the IPv4 multicast forwarding code.
7000307.0-CURRENT after the modification of bus_setup_intr() (newbus).
7000317.0-CURRENT after the inclusion of ipw(4) and iwi(4) firmwares.
7000327.0-CURRENT after the inclusion of ncurses wide character support.
7000337.0-CURRENT after changes to how insmntque(),
getnewvnode(), and vfs_hash_insert() work.
7000347.0-CURRENT after addition of a notify mechanism
for CPU frequency changes.
7000357.0-CURRENT after import of the ZFS filesystem.7000367.0-CURRENT after addition of CAM 'SG' peripheral device,
which implements a subset of Linux SCSI SG passthrough device API.7000377.0-CURRENT after changing &man.getenv.3;, &man.putenv.3;,
&man.setenv.3; and &man.unsetenv.3; to be POSIX
conformant.7000387.0-CURRENT after the changes in 700038 were
backed out.7000397.0-CURRENT after the addition of &man.flopen.3;
to libutil.7000407.0-CURRENT after enabling symbol versioning, and changing
the default thread library to libthr.7000417.0-CURRENT after the import of gcc 4.2.0.7000427.0-CURRENT after bump of all shared library
versions that had not been changed since
RELENG_6.7000437.0-CURRENT after changing the argument for
vn_open()/VOP_OPEN() from filedescriptor index to the
struct file *.7000447.0-CURRENT after changing &man.pam.nologin.8; to
provide an account management function instead of an
authentication function to the PAM framework.7000457.0-CURRENT after updated 802.11 wireless
support.7000467.0-CURRENT after adding TCP LRO interface
capabilities.7000477.0-CURRENT after
RFC 3678 API support added to the IPv4 stack.
Legacy RFC 1724 behaviour of the IP_MULTICAST_IF
ioctl has now been removed; 0.0.0.0/8 may no longer
be used to specify an interface index.
struct ipmreqn should be used instead.7000487.0-CURRENT after importing pf from OpenBSD
4.17000497.0-CURRENT after adding IPv6 support for
FAST_IPSEC, deleting KAME IPSEC, and renaming
FAST_IPSEC to IPSEC.(not changed)7.0-CURRENT after converting setenv/putenv/etc.
calls from traditional BSD to POSIX.7000507.0-CURRENT after adding new mmap/lseek/etc
syscalls.7000517.0-CURRENT after moving I4B headers to
include/i4b.7000527.0-CURRENT after the addition of support for
PCI domains7000538.0-CURRENT.800000
Note that 2.2-STABLE sometimes identifies itself as
2.2.5-STABLE after the 2.2.5-RELEASE. The pattern
used to be year followed by the month, but we decided to change it
to a more straightforward major/minor system starting from 2.2.
This is because the parallel development on several branches made
it infeasible to classify the releases simply by their real
release dates. If you are making a port now, you do not have to
worry about old -CURRENTs; they are listed here just for your
reference.Writing something after
bsd.port.mkDo not write anything after the .include
<bsd.port.mk> line. It usually can be avoided by
including bsd.port.pre.mk somewhere in the
middle of your Makefile and
bsd.port.post.mk at the end.You need to include either the
bsd.port.pre.mk/bsd.port.post.mk pair or
bsd.port.mk only; do not mix these two usages.bsd.port.pre.mk only defines a few
variables, which can be used in tests in the
Makefile, bsd.port.post.mk
defines the rest.Here are some important variables defined in
bsd.port.pre.mk (this is not the complete list,
please read bsd.port.mk for the complete
list).VariableDescriptionARCHThe architecture as returned by uname
-m (e.g., i386)OPSYSThe operating system type, as returned by
uname -s (e.g.,
FreeBSD)OSRELThe release version of the operating system (e.g.,
2.1.5 or
2.2.7)OSVERSIONThe numeric version of the operating system; the same as
__FreeBSD_version.PORTOBJFORMATThe object format of the system
(elf or aout;
note that for modern versions of FreeBSD,
aout is deprecated.)LOCALBASEThe base of the local tree (e.g.,
/usr/local/)X11BASEThe base of the X11 tree (e.g.,
/usr/X11R6)PREFIXWhere the port installs itself (see more on
PREFIX).If you have to define the variables
USE_IMAKE, USE_X_PREFIX, or
MASTERDIR, do so before including
bsd.port.pre.mk.Here are some examples of things you can write after
bsd.port.pre.mk:# no need to compile lang/perl5 if perl5 is already in system
.if ${OSVERSION} > 300003
BROKEN= perl is in system
.endif
# only one shlib version number for ELF
.if ${PORTOBJFORMAT} == "elf"
TCL_LIB_FILE= ${TCL_LIB}.${SHLIB_MAJOR}
.else
TCL_LIB_FILE= ${TCL_LIB}.${SHLIB_MAJOR}.${SHLIB_MINOR}
.endif
# software already makes link for ELF, but not for a.out
post-install:
.if ${PORTOBJFORMAT} == "aout"
${LN} -sf liblinpack.so.1.0 ${PREFIX}/lib/liblinpack.so
.endifYou did remember to use tab instead of spaces after
BROKEN= and
TCL_LIB_FILE=, did you not?
:-).在 wrapper scripts 中使用 exec 述句若某 port 為了執行其他程式而安裝了一個 shell script,
而該程式同時也是該 script 最後一個動作,那麼需要確定該 script
是用 exec 述句(statement),舉例而言:#!/bin/sh
exec %%LOCALBASE%%/bin/java -jar %%DATADIR%%/foo.jar "$@"exec 述句以所指定的程式取代了該 shell
的程序。 若省略 exec ,那麼該 shell 程序
將會在程式執行中一直存在於記憶體,這無疑地浪費了系統資源。UIDs 及 GIDsThe current list of reserved UIDs and GIDs can be found
in ports/UIDs and
ports/GIDs.If your port requires a certain user to be on the installed
system, let the pkg-install script call
pw to create it automatically. Look at
net/cvsup-mirror for an example.
Please note that this is strongly discouraged, please register
user/group ID numbers as stated below.If your port must use the same user/group ID number when it is
installed as a binary package as when it was compiled, then you must
choose a free UID from 50 to 999 and register it either in
ports/UIDs (for users) or in
ports/GIDs (for groups). Look at
japanese/Wnn6 for an example.Make sure you do not use a UID already used by the system or
other ports.Please include a patch against these two files when you
require a new user or group to be created for your
port.Do things rationallyThe Makefile should do things simply and
reasonably. If you can make it a couple of lines shorter or more
readable, then do so. Examples include using a make
.if construct instead of a shell
if construct, not redefining
do-extract if you can redefine
EXTRACT* instead, and using
GNU_CONFIGURE instead of CONFIGURE_ARGS
+= --prefix=${PREFIX}.If you find yourself having to write a lot
of new code to try to do something, please go back and review
bsd.port.mk to see if it contains an
existing implementation of what you are trying to do. While
hard to read, there are a great many seemingly-hard problems for
which bsd.port.mk already provides a
shorthand solution.Respect both CC and
CXXThe port should respect both CC
and CXX variables. What we mean by this
is that the port should not set the values of these variables
absolutely, overriding existing values; instead, it should append
whatever values it needs to the existing values. This is so that
build options that affect all ports can be set globally.If the port does not respect these variables,
please add NO_PACKAGE=ignores either cc or
cxx to the Makefile.An example of a Makefile respecting
both CC and CXX
variables follows. Note the ?=:CC?= gccCXX?= g++Here is an example which respects neither
CC nor CXX
variables:CC= gccCXX= g++Both CC and CXX
variables can be defined on FreeBSD systems in
/etc/make.conf. The first example
defines a value if it was not previously set in
/etc/make.conf, preserving any
system-wide definitions. The second example clobbers
anything previously defined.Respect CFLAGSThe port should respect the CFLAGS variable.
What we mean by this is that the port should not set the value of
this variable absolutely, overriding the existing value; instead,
it should append whatever values it needs to the existing value.
This is so that build options that affect all ports can be set
globally.If it does not, please add NO_PACKAGE=ignores
cflags to the Makefile.An example of a Makefile respecting
the CFLAGS variable follows. Note the
+=:CFLAGS+= -Wall -WerrorHere is an example which does not respect the
CFLAGS variable:CFLAGS= -Wall -WerrorThe CFLAGS variable is defined on
FreeBSD systems in /etc/make.conf. The
first example appends additional flags to the
CFLAGS variable, preserving any system-wide
definitions. The second example clobbers anything previously
defined.You should remove optimization flags from the third party
Makefiles. System CFLAGS
contains system-wide optimization flags. An example from
an unmodified Makefile:CFLAGS= -O3 -funroll-loops -DHAVE_SOUNDUsing system optimization flags, the
Makefile would look similar to the
following example:CFLAGS+= -DHAVE_SOUNDThreading librariesThe threading library must be linked to the binaries
using a special linker flag -pthread on
&os;. If a port insists on linking
-lpthread or -lc_r
directly, patch it to use PTHREAD_LIBS
variable provided by the ports framework. This variable
usually has the value of -pthread, but
on certain architectures and &os; versions it can have
different values, so do not just hardcode
-pthread into patches and always use
PTHREAD_LIBS.If building the port errors out with unrecognized
option '-pthread' when setting
PTHREAD_LIBS, it may be desirable to use
gcc as linker by setting
CONFIGURE_ENV to LD=${CC}.
The -pthread option is not supported by
ld directly.FeedbackDo send applicable changes/patches to the original
author/maintainer for inclusion in next release of the code. This
will only make your job that much easier for the next
release.README.htmlDo not include the README.html file. This
file is not part of the cvs collection but is generated using the
make readme command.
Marking a port not installable with BROKEN,
FORBIDDEN, or IGNOREIn certain cases users should be prevented from installing
a port. To tell a user that
a port should not be installed, there are several
make variables that can be used in a port's
Makefile. The value of the following
make variables will be the reason that is
given back to users for why the port refuses to install itself.
Please use the correct make variable as
each make variable conveys radically different meanings to
both users, and to automated systems that depend on the
Makefiles, such as
the ports build cluster,
FreshPorts, and
portsmon.VariablesBROKEN is reserved for ports that
currently do not compile, install, or deinstall correctly.
It should be used for ports where the problem is
believed to be temporary.If instructed, the build cluster will still attempt to
try to build
them to see if the underlying problem has been
resolved. (However, in general, the cluster is run without
this.)For instance, use
BROKEN when a port:does not compilefails its configuration or installation processinstalls files outside of
${LOCALBASE} and
${X11BASE}does not remove all its files cleanly upon
deinstall (however, it may be acceptable, and desirable,
for the port to leave user-modified files behind)FORBIDDEN is used for ports that
do contain a security vulnerability or induce grave
concern regarding the security of a FreeBSD system with
a given port installed (ex: a reputably insecure program
or a program that provides easily exploitable services).
Ports should be marked as FORBIDDEN
as soon as a particular piece of software has a
vulnerability and there is no released upgrade. Ideally
ports should be upgraded as soon as possible when a
security vulnerability is discovered so as to reduce the
number of vulnerable FreeBSD hosts (we like being known
for being secure), however sometimes there is a
noticeable time gap between disclosure of a
vulnerability and an updated release of the
vulnerable software. Do not mark a port
FORBIDDEN for any reason other than
security.IGNORE is reserved for ports that
should not be built for some other reason.
It should be used for ports where the problem is
believed to be structural.
The build
cluster will not, under any
circumstances, build ports marked as
IGNORE. For instance, use
IGNORE when a port:compiles but does not run properlydoes not work on the installed version of &os;requires &os; kernel sources to build, but the
user does not have them installedhas a distfile which may not be automatically
fetched due to licensing restrictionsdoes not work with some other currently installed
port (for instance, the port depends on
www/apache21 but
www/apache13
is installed)If a port would conflict with a currently installed
port (for example, if they install a file in the same
place that perfoms a different function),
use
CONFLICTS instead.
CONFLICTS will set
IGNORE by itself.If a port should be marked IGNORE
only on certain architectures, there are two other
convenience variables that will automatically set
IGNORE for you:
ONLY_FOR_ARCHS and
NOT_FOR_ARCHS. Examples:ONLY_FOR_ARCHS= i386 amd64NOT_FOR_ARCHS= alpha ia64 sparc64A custom IGNORE message can be set
using ONLY_FOR_ARCHS_REASON and
NOT_FOR_ARCHS_REASON. Per architecture
entries are possible with
ONLY_FOR_ARCHS_REASON_ARCH
and
NOT_FOR_ARCHS_REASON_ARCH.
If a port fetches i386 binaries and installs them,
IA32_BINARY_PORT should be set. If this
variable is set, it will be checked whether the
/usr/lib32 directory is available for
IA32 versions of libraries and whether the kernel
has IA32 compatibility compiled in. If one of these two
dependencies is not satisfied, IGNORE will
be set automatically.Implementation NotesThe strings should not be quoted.
Also, the wording of the string should be somewhat
different due to the way the information is shown to the
user. Examples:BROKEN= this port is unsupported on FreeBSD 5.xIGNORE= is unsupported on FreeBSD 5.xresulting in the following output from
make describe:===> foobar-0.1 is marked as broken: this port is unsupported on FreeBSD 5.x.===> foobar-0.1 is unsupported on FreeBSD 5.x.Marking a port for removal with DEPRECATED
or EXPIRATION_DATEDo remember that BROKEN and
FORBIDDEN are to be used as a
temporary resort if a port is not working. Permanently
broken ports should be removed from the tree
entirely.When it makes sense to do so, users can be warned about
a pending port removal with DEPRECATED
and EXPIRATION_DATE. The former is
simply a string stating why the port is scheduled for removal;
the latter is a string in ISO 8601 format (YYYY-MM-DD). Both
will be shown to the user.It is possible to set DEPRECATED
without an EXPIRATION_DATE (for
instance, recommending a newer version of the port), but
the converse does not make any sense.There is no set policy on how much notice to give.
Current practice seems to be one month for security-related
issues and two months for build issues. This also gives any
interested committers a little time to fix the problems.Avoid use of the .error constructThe correct way for a Makefile to
signal that the port can not be installed due to some external
factor (for instance, the user has specified an illegal
combination of build options) is to set a nonblank value to
IGNORE. This value will be formatted and
shown to the user by make install.It is a common mistake to use .error
for this purpose. The problem with this is that many
automated tools that work with the ports tree will fail in
this situation. The most common occurrence of this is seen
when trying to build /usr/ports/INDEX
(see ). However, even more
trivial commands such as make -V maintainer
also fail in this scenario. This is not acceptable.How to avoid using .errorAssume that someone has the line
USE_POINTYHAT=yes
in make.conf. The first of
the next two Makefile snippets will
cause make index to fail, while the
second one will not:.if USE_POINTYHAT
.error "POINTYHAT is not supported"
.endif.if USE_POINTYHAT
IGNORE=POINTYHAT is not supported
.endifsysctl 使用時機sysctl 除了在 targets 之外,都不鼓勵使用。
這是因為任何 makevar
的評估都有可能會使得程序執行速度變慢。例如在
make index 的過程中就會需要用到
sysctl。若要使用 &man.sysctl.8; 則必須透過 SYSCTL
此一變數才可,因為這樣才會包含完整路徑,
同時也可以隨時因應使用者需求而替換為其他路徑。Rerolling distfilesSometimes the authors of software change the content of
released distfiles without changing the file's name. You have
to verify that the changes are official and have been performed
by the author. It has happened in the past that the distfile
was silently altered on the download servers with the intent
to cause harm or compromise end user security.Put the old distfile aside, download the new one, unpack
them and compare the content with &man.diff.1;. If you see
nothing suspicious, you can update distinfo.
Be sure to summarize the differences in your PR or commit log,
so that other people know that you have taken care to ensure
that nothing bad has happened.You might also want to contact the authors of the software
and confirm the changes with them.Necessary workaroundsSometimes it is necessary to work around bugs in
software included with older versions of &os;.Some versions of &man.make.1; were broken
on at least 4.8 and 5.0 with respect to handling
comparisons based on OSVERSION.
This would often lead to failures during
make describe (and thus, the overall
ports make index). The workaround is
to enclose the conditional comparison in spaces, e.g.:
if ( ${OSVERSION} > 500023 )
Be aware that test-installing a port on 4.9 or 5.2
will not detect this problem.MiscellaneaThe files
pkg-descr and pkg-plist
should each be double-checked. If you are reviewing a port and feel
they can be worded better, do so.Do not copy more copies of the GNU General Public License into
our system, please.Please be careful to note any legal issues! Do not let us
illegally distribute software!A Sample MakefileHere is a sample Makefile that you can use to
create a new port. Make sure you remove all the extra comments (ones
between brackets)!It is recommended that you follow this format (ordering of
variables, empty lines between sections, etc.). This format is
designed so that the most important information is easy to locate. We
recommend that you use portlint to check the
Makefile.[the header...just to make it easier for us to identify the ports.]
# New ports collection makefile for: xdvi
[the "version required" line is only needed when the PORTVERSION
variable is not specific enough to describe the port.]
# Date created: 26 May 1995
[this is the person who did the original port to FreeBSD, in particular, the
person who wrote the first version of this Makefile. Remember, this should
not be changed when upgrading the port later.]
# Whom: Satoshi Asami <asami@FreeBSD.org>
#
# $FreeBSD$
[ ^^^^^^^^^ This will be automatically replaced with RCS ID string by CVS
when it is committed to our repository. If upgrading a port, do not alter
this line back to "$FreeBSD$". CVS deals with it automatically.]
#
[section to describe the port itself and the master site - PORTNAME
and PORTVERSION are always first, followed by CATEGORIES,
and then MASTER_SITES, which can be followed by MASTER_SITE_SUBDIR.
PKGNAMEPREFIX and PKGNAMESUFFIX, if needed, will be after that.
Then comes DISTNAME, EXTRACT_SUFX and/or DISTFILES, and then
EXTRACT_ONLY, as necessary.]
PORTNAME= xdvi
PORTVERSION= 18.2
CATEGORIES= print
[do not forget the trailing slash ("/")!
if you are not using MASTER_SITE_* macros]
MASTER_SITES= ${MASTER_SITE_XCONTRIB}
MASTER_SITE_SUBDIR= applications
PKGNAMEPREFIX= ja-
DISTNAME= xdvi-pl18
[set this if the source is not in the standard ".tar.gz" form]
EXTRACT_SUFX= .tar.Z
[section for distributed patches -- can be empty]
PATCH_SITES= ftp://ftp.sra.co.jp/pub/X11/japanese/
PATCHFILES= xdvi-18.patch1.gz xdvi-18.patch2.gz
[maintainer; *mandatory*! This is the person who is volunteering to
handle port updates, build breakages, and to whom a users can direct
questions and bug reports. To keep the quality of the Ports Collection
as high as possible, we no longer accept new ports that are assigned to
"ports@FreeBSD.org".]
MAINTAINER= asami@FreeBSD.org
COMMENT= A DVI Previewer for the X Window System
[dependencies -- can be empty]
RUN_DEPENDS= gs:${PORTSDIR}/print/ghostscript
LIB_DEPENDS= Xpm.5:${PORTSDIR}/graphics/xpm
[this section is for other standard bsd.port.mk variables that do not
belong to any of the above]
[If it asks questions during configure, build, install...]
IS_INTERACTIVE= yes
[If it extracts to a directory other than ${DISTNAME}...]
WRKSRC= ${WRKDIR}/xdvi-new
[If the distributed patches were not made relative to ${WRKSRC}, you
may need to tweak this]
PATCH_DIST_STRIP= -p1
[If it requires a "configure" script generated by GNU autoconf to be run]
GNU_CONFIGURE= yes
[If it requires GNU make, not /usr/bin/make, to build...]
USE_GMAKE= yes
[If it is an X application and requires "xmkmf -a" to be run...]
USE_IMAKE= yes
[et cetera.]
[non-standard variables to be used in the rules below]
MY_FAVORITE_RESPONSE= "yeah, right"
[then the special rules, in the order they are called]
pre-fetch:
i go fetch something, yeah
post-patch:
i need to do something after patch, great
pre-install:
and then some more stuff before installing, wow
[and then the epilogue]
.include <bsd.port.mk>Keeping UpThe &os; Ports Collection is constantly changing. Here is
some information on how to keep up.FreshPortsOne of the easiest ways to learn about updates that have
already been committed is by subscribing to
FreshPorts.
You can select multiple ports to monitor. Maintainers are
strongly encouraged to subscribe, because they will receive
notification of not only their own changes, but also any
changes that any other &os; committer has made. (These are
often necessary to keep up with changes in the underlying
ports framework—although it would be most polite to
receive an advance heads-up from those committing such changes,
sometimes this is overlooked or just simply impractical.
Also, in some cases, the changes are very minor in nature.
We expect everyone to use their best judgement in these
cases.)If you wish to use FreshPorts, all you need is an
account. If your registered email address is
@FreeBSD.org, you will see the opt-in link on the
right hand side of the webpages.
For those of you who already have a FreshPorts account, but are not
using your @FreeBSD.org email address,
just change your email to @FreeBSD.org, subscribe,
then change it back again.FreshPorts also has
a sanity test feature which automatically tests each commit to the
FreeBSD ports tree. If subscribed to this service, you will be
notified of any errors which FreshPorts detects during sanity
testing of your commits.The Web Interface to the Source RepositoryIt is possible to browse the files in the source repository by
using a web interface. Changes that affect the entire port system
are now documented in the
CHANGES file. Changes that affect individual ports
are now documented in the
UPDATING file. However, the definitive answer to any
question is undoubtedly to read the source code of
bsd.port.mk, and associated files.The &os; Ports Mailing ListIf you maintain ports, you should consider following the
&a.ports;. Important changes to the way ports work will be announced
there, and then committed to CHANGES.The &os; Port Building Cluster on
pointyhat.FreeBSD.orgOne of the least-publicized strengths of &os; is that
an entire cluster of machines is dedicated to continually
building the Ports Collection, for each of the major OS
releases and for each Tier-1 architecture. You can find
the results of these builds at
package building logs
and errors.Individual ports are built unless they are specifically
marked with IGNORE. Ports that are
marked with BROKEN will still be attempted,
to see if the underlying problem has been resolved. (This
is done by passing TRYBROKEN to the
port's Makefile.)The &os; Port Distfile SurveyThe build cluster is dedicated to building the latest
release of each port with distfiles that have already been
fetched. However, as the Internet continually changes,
distfiles can quickly go missing. The FreeBSD
Ports distfiles survey attempts to query every
download site for every port to find out if each distfile
is still currently available. Maintainers are asked to
check this report periodically, not only to speed up the
building process for users, but to help avoid wasting
bandwidth of the sites that volunteer to host all these
distfiles.The &os; Ports Monitoring SystemAnother handy resource is the
FreeBSD Ports Monitoring System (also known as
portsmon). This system comprises a
database that processes information from several sources
and allows its to be browsed via a web interface. Currently,
the ports Problem Reports (PRs), the error logs from
the build cluster, and individual files from the ports
collection are used. In the future, this will be expanded
to include the distfile survey, as well as other sources.To get started, you can view all information about a
particular port by using the
Overview of One Port.As of this writing, this is the only resource available
that maps GNATS PR entries to portnames. (PR submitters
do not always include the portname in their Synopsis, although
we would prefer that they did.) So, portsmon
is a good place to start if you want to find out whether an
existing port has any PRs filed against it and/or any build
errors; or, to find out if a new port that you may be thinking
about creating has already been submitted.