2009年12月29日 星期二

人生教我的45個功課


人生教我的45個功課 作者: Regina Brett


Regina Brett,90歲,來自俄亥俄州,克里夫蘭,Plain Dealer 


他說:為了慶祝變得更老了,我曾經寫下人生教我的45個功課。這是我寫過最叫座的專欄。
我這把老骨頭8月就要90歲了,所以,再一次,在這裡呈現這一個專欄。

1
。 人生是不公平,但還是好得很。

2
。 懷疑的時候,為未來踏出一小步。

3
。 人生太短,短到來不及浪費時間去恨任何一個人。

4
。 生病的時候,你的工作不會照顧妳。你的朋友和父母會。保持聯絡。

5
。 每一個月付清你的信用卡。

6
。 你不需要每一次都吵贏。同意你不同意的。

7
。 找人一起哭。它比獨自啜泣更加療愈。

8
。 對上帝生氣沒有關係。祂受得了。

9
。 退休存款從你的第一張薪水條開始。

10
。講到巧克力,抗拒只是徒勞無功。

11
。和你的過去和解,所以它不會搞砸你的當下。

12
。讓你的孩子看到你哭沒有關係。

13
。別拿自己的人生和他人做比較。你根本不清楚他們的人生是怎麼一回事。

14
。如果一段親密關係要偷偷摸摸,你根本不應該涉入。

15
。一眨眼的功夫什麼都會變。但是別擔心: 上帝從來不眨眼。

16
。深吸一口氣。它會安定你的腦。

17
。沒用,不美,或不喜悅的東西都丟掉。

18
。沒讓你死的真的會讓你更堅強。

19
。重拾快樂童年永不嫌晚。但這第二次只能靠你不靠人。

20
。當關乎追求你生命的所愛,不要把不要當答案。

21
。點蠟燭,用好的床單,穿上炫麗的內衣。不要特殊場合才用。今天就是特別的一天。

22
。準備要過於周全,然後隨遇而安。

23
。現在就離經叛道。不要一把年紀了才開始穿上紫色。

24
。最重要的性器官是腦袋。 

25
。除了你,沒有人在主宰你的快樂。

26
。把所謂的不幸用這一句話把它表框起來 "五年後,這還重要嗎?"

27
。永遠選擇生活。

28
。原諒每一個人每一件事。

29
。別人怎麼看你不干你的事。

30
。時間會痊癒幾乎每一件事。要給時間,時間。

31
。無論情況多好或多壞,它都會變的。

32
。不要那麼認真的看待自己。沒有人會這樣看待你的。

33
。相信奇蹟。

34
。上帝愛你是因為祂就是這樣,不是因為你做了什麼或是沒做什麼。

35
。不要稽查人生。現在就呈現和做最大的發揮。

36
。變老了打敗另一種選項 - 死得早。

37
。你的孩子只有一個童年。

38
。最後真正最重要的是你愛過。

39
。每一天都出門。奇蹟在四處等著。

40
。如果我們都把我們的問題都丟成一堆,然後看看其他人的,我們會把我們的撿回來。

41
。忌妒浪費時間。你已經擁有你所需要的了。

42
。最好的都還沒來。

43
。不管你感覺如何,起來,穿好和呈現。

44
。讓自己每天快樂。

45
。人生不會打上蝴蝶結,但它仍然是一份禮物。

2009年12月2日 星期三

DirectX9 How-To; [ VB.NET ]


DirectX9 How-To; [ VB.NET 2005 ]


2009年11月25日 星期三

虛擬樂高積木軟體,讓你在電腦裡也能玩樂高!


本文章發佈於免費資源網路社群,轉貼時請註明原文連結並保留本訊息,謝謝。
文章連結:http://www.freegroup.org/2009/11/lego-digital-designer/
lego digital designer 01 虛擬樂高積木軟體,讓你在電腦裡也能玩樂高!
作者/Pseric(2009-11-23)
LEGO Digital Designer(簡稱LDD)樂高數位設計師是由樂高公司提供的免費軟體,分為 PC 與 Mac 版本。透過這個軟體使用者就可以在電腦裡拼裝積木,完成後還可以變成說明書,引導使用者讓實體積木組合起來,非常有趣。LDD 目前支援一般的 DESIGNbyMe 積木,也支援 CREATOR 與 Mindstorms 系列。


筆者使用 Mac 版作為範例介紹,與 PC 版應無太大差異,除了安裝過程不一樣以外,LDD 的介面應該相同。
lego digital designer 02 虛擬樂高積木軟體,讓你在電腦裡也能玩樂高!
Mac 版的 LDD 共會佔用 109.5MB 的硬碟空間,安裝後如果不想使用直接從應用程式移除即可。
lego digital designer 03 虛擬樂高積木軟體,讓你在電腦裡也能玩樂高!
安裝後開啟軟體,可以選擇要使用的積木系列,使用者能夠開啟預設的一些成品模型,或是開啟新的模版來自行組裝。下圖是採用 DESIGNbyMe 積木預設的房屋模型,滑鼠左鍵可以移動或搬移積木,右鍵按著則可以調整觀看的角度。
lego digital designer 04 虛擬樂高積木軟體,讓你在電腦裡也能玩樂高!
右上角可以切換模式,分別是組裝模式環境模式說明書模式,下圖是以說明書來展示如何組裝該模型,共有 56 個步驟,一般使用時若你手動組裝完樂高模型,點選說明書模式就會自動產生步驟導引,非常方便。
lego digital designer 05 虛擬樂高積木軟體,讓你在電腦裡也能玩樂高!
前面有介紹過,LDD 也支援 Mindstorms 樂高系列,怎樣?夠酷吧!有時候用 LDD 過過癮也不錯。
lego digital designer 06 虛擬樂高積木軟體,讓你在電腦裡也能玩樂高!
好了,大致上的介面就是這樣,至於一些細部的功能或特色就不詳加闡述,如果使用者有興趣的話不妨前往樂高網站下載LEGO Digital Designer來玩玩吧!

2009年10月29日 星期四

C語言常見錯誤小結

C語言常見錯誤小結
出處:http://fanqiang.chinaunix.net/a4/b2/20010706/220800825_b.html



C語言的最大特點是:功能強、使用方便靈活。C編譯的程序對語法檢查並不象其它高級語言那嚴格,這就給編程 人員留下“靈活的余地”,但還是由這個靈活給程序的調試帶來了許多不便,尤其對初學C語言的人來說,經常會出一些連自己都不知道錯在哪裡的錯誤。看著有錯 的程序,不知該如何改起,本人通過對C的學習,積累了一些C編程時常犯的錯誤,寫給各位學員以供參考。

1.書寫標識符時,忽略了大小寫字母的區別。

main()
{
     int a=5;
     printf("%d",A);
}

編譯程序把a和A認為是兩個不同的變量名,而顯示出錯信息。C認為大寫字母和小寫字母是兩個不同的字符。習慣上,符號常量名用大寫,變量名用小寫表示,以增加可讀性。
2.忽略了變量的類型,進行了不合法的運算。

main()
{
     float a,b;
     printf("%d",a%b);
}

%是求余運算,得到a/b的整余數。整型變量a和b可以進行求余運算,而實型變量則不允許進行“求余”運算。
3.將字符常量與字符串常量混淆。
char c;
c="a";

在這裡就混淆了字符常量與字符串常量,字符常量是由一對單引號括起來的單個字符,字符串常量是一對雙引號括起來的字符序列。C規定以“\”作字符串結束標 志,它是由系統自動加上的,所以字符串“a”實際上包含兩個字符:‘a'和‘\',而把它賦給一個字符變量是不行的。
4.忽略了“=”與“==”的區別。 
在許多高級語言中,用“=”符號作為關系運算符“等”。如在BASIC程序中可以寫
if (a=3) then …
但C語言中,“=”是賦值運算符,“==”是關系運算符。如:
if (a==3) a=b;
前者是進行比較,a是否和3相等,者表示如果a和3相等,把b值賦給a。由習慣問題,初學者往往會犯這樣的錯誤。

5.忘記加分號。
分號是C語句中不可缺少的一部分,語句末尾必須有分號。
a=1
b=2

編譯時,編譯程序在“a=1”面沒發現分號,就把下一行“b=2”也作為上一行語句的一部分,這就會出現語法錯誤。改錯時,有時在被指出有錯的一行中未發現錯誤,就需要看一下上一行是否漏掉了分號。
{
     z=x+y;
     t=z/100;
     printf("%f",t);
}

對復合語句來說,最一個語句中最的分號不能忽略不寫(這是和PASCAL不同的)。
6.多加分號。
對一個復合語句,如:
{

     z=x+y;
     t=z/100;
     printf("%f",t);
};
復合語句的花括號不應再加分號,否則將會畫蛇添足。
又如:
if (a%3==0);
I++;
本是如果3整除a,則I加1。但由if (a%3==0)多加了分號,則if語句到此結束,程序將執行I++語句,不論3是否整除a,I都將自動加1。
再如:
for (I=0;I<5;I++);
{

     scanf("%d",&x);
     printf("%d",x);

}
本意是先輸入5個數,每輸入一個數再將它輸出。由for()多加了一個分號,使循環體變為空語句,此時只能輸入一個數並輸出它。

7.輸入變量時忘記加地址運算符“&”。
int a,b;
scanf("%d%d",a,b);
這是不合法的。Scanf函數的作用是:按照a、b在內存的地址將a、b的值存進去。“&a”指a在內存中的地址。

8.輸入數據的方式與要求不符。
scanf("%d%d",&a,&b);
輸入時,不能用逗號作兩個數據間的分隔符,如下面輸入不合法:
3,4
輸入數據時,在兩個數據之間以一個或多個空格間隔,也可用回車鍵,跳格鍵tab。
scanf("%d,%d",&a,&b);
C規定:如果在“格式控制”字符串中除了格式說明以外還有其它字符,則在輸入數據時應輸入與這些字符相同的字符。下面輸入是合法的:
3,4
此時不用逗號而用空格或其它字符是不對的。
3 4 3:4
又如:
scanf("a=%d,b=%d",&a,&b);
輸入應如以下形式:
a=3,b=4

9.輸入字符的格式與要求不一致。
在用“%c”格式輸入字符時,“空格字符”和“轉義字符”都作為有效字符輸入。
scanf("%c%c%c",&c1,&c2,&c3);
如輸入a b c
字符“a”送給c1,字符“ ”送給c2,字符“b”送給c3,因為%c只要求讀入一個字符,面不需要用空格作為兩個字符的間隔。

10.輸入輸出的數據類型與所用格式說明符不一致。
例如,a已定義為整型,b定義為實型
a=3;b=4.5;
printf("%f%d\n",a,b);
編譯時不給出出錯信息,但運行結果將與原意不符。這種錯誤尤其需要注意。

11.輸入數據時,企圖規定精度。
scanf("%7.2f",&a);
這樣做是不合法的,輸入數據時不能規定精度。


12.switch語句中漏寫break語句。
例如:根據考試成績的等級打印出百分制數段。
switch(grade)
{

     case 'A':printf("85~100\n");
     case 'B':printf("70~84\n");
     case 'C':printf("60~69\n");
     case 'D':printf("<60\n");
     default:printf("error\n");

}
由於漏寫了break語句,case只起標號的作用,而不起判斷作用。因此,當grade值為A時,printf函數在執行完第一個語句接著執行第二、三、四、五個printf函數語句。正確寫法應在每個分支再加上“break;”。例如
case 'A':printf("85~100\n");break;

13.忽視了while和do-while語句在細節上的區別。
(1)
main()
{

     int a=0,I;
     scanf("%d",&I);
     while(I<=10)
     {

          a=a+I;
          I++;
     }
     printf("%d",a);
}

(2)
main()
{

     int a=0,I;
     scanf("%d",&I);
     do
     {

         a=a+I;
         I++;
     }while(I<=10);
     printf("%d",a);
}
可以看到,當輸入I的值小或等10時,二者得到的結果相同。而當I>10時,二者結果就不同了。因為while循環是先判斷執行,而do- while循環是先執行判斷。對大10的數while循環一次也不執行循環體,而do-while語句則要執行一次循環體。

14.定義數組時誤用變量。
int n;
scanf("%d",&n);
int a[n];
數組名用方括號括起來的是常量表達式,可以包括常量和符號常量。即C不允許對數組的大小作動態定義。


15.在定義數組時,將定義的“元素個數”誤認為是可使的最大下標值。
main()
{

     static int a[10]={1,2,3,4,5,6,7,8,9,10};
     printf("%d",a[10]);
}
C語言規定:定義時用a[10],表示a數組有10個元素。其下標值由0開始,所以數組元素a[10]是不存在的。

16.初始化數組時,未使用靜態存儲。
int a[3]={0,1,2};
這樣初始化數組是不對的。C語言規定只有靜態存儲(static)數組和外部存儲(exterm)數組才能初始化。應改為:
static int a[3]={0,1,2};

17.在不應加地址運算符&的位置加了地址運算符。
scanf("%s",&str);
C語言編譯系統對數組名的處理是:數組名代表該數組的起始地址,且scanf函數中的輸入項是字符數組名,不必要再加地址符&。應改為:
scanf("%s",str);

18.同時定義了形參和函數中的局部變量。

int max(x,y)
int x,y,z;
{

     z=x>y?x:y;
     return(z);
}
形參應該在函數體外定義,而局部變量應該在函數體內定義。應改為:
int max(x,y)
int x,y;
{

     int z;
     z=x>y?x:y;
     return(z);
}




2009年9月29日 星期二

XFS Backup/Restore

 XFS Backup/Restore

轉載

一般 unix base 的備份多使用 tar, cpio, dump 之類的軟體. 最常看見的應該算是 tar 了. 不過 tar 目前只能備份標準的一些檔案屬性, 對於 XFS 來說,額外的 ACL 屬性就沒有辦法了. 所以如果使用 XFS, 通常就會利用本身所提供的工具來備份.

下面的 script 就是利用 xfsdump, bzip2, dd 備份資料到磁帶上. 備份後會測試一次, 以確定資料完整.

#!/bin/sh

# 磁帶機的裝置名稱
TAPE_DEV="/dev/nst0"

# null 裝置名稱
NULL_DEV="/dev/null"

# 指令檔存放的路徑
CMD_PATH="/etc/backup"

# 磁帶的區塊大小 (TR-5 使用 9-65536, 備份與還原必須使用相同設定)
# 配合壓縮軟體與 dd 時, 若設定過大會有問題
BLOCK_SIZE=1024

# 備份的等級, 0 為完全備份
BACKUP_LEVEL=0

# 備份時顯示的間格秒數
TIME_DISPLAY=300

# 備份的指令檔
DUMP_CMD="/usr/sbin/xfsdump"

# 還原備份的指令檔
RESTORE_CMD="/usr/sbin/xfsrestore"

# mt 指令
MT_CMD="/bin/mt"

# dd 指令
DD_CMD="/bin/dd"

# 壓縮程式
ZIP_CMD="/usr/bin/bzip2"

# ls 指令
LS_CMD="/bin/ls"

# head 指令
HEAD_CMD="/usr/bin/head"

# 備份路徑設定檔
# 檔案格式如下:
#
#/dev/hda1 /
#/dev/vg01/ora /home/oracle oracle_stop oracle_start
VOLS_INCL_FILE="${CMD_PATH}/vols.include.xfsdump"

if [ -f ${VOLS_INCL_FILE} ]; then
date
echo "---------------------------------------------------------------"
echo "如果要還原備份資料, 可以使用下面的指令:"
echo "${DD_CMD} bs=${BLOCK_SIZE} conv=sync if=${TAPE_DEV} | \ "
echo " ${ZIP_CMD} -dqv | \ "
echo " ${RESTORE_CMD} -p ${TIME_DISPLAY} -J - /path/to/restore/"
echo "---------------------------------------------------------------"
echo

echo "---------------------------------------------------------------"
echo "列出本檔案的內容 - ${0}"
echo "---------------------------------------------------------------"
cat ${0}
echo "---------------------------------------------------------------"
echo "檔案結束!"
echo "---------------------------------------------------------------"
echo

echo "---------------------------------------------------------------"
echo "將磁帶回轉, 並設定區塊大小"
echo "cmd: ${MT_CMD} -f ${TAPE_DEV} retension"
echo "cmd: ${MT_CMD} -f ${TAPE_DEV} rewind"
echo "cmd: ${MT_CMD} -f ${TAPE_DEV} setblk ${BLOCK_SIZE}"
echo "---------------------------------------------------------------"
echo
${MT_CMD} -f ${TAPE_DEV} retension
${MT_CMD} -f ${TAPE_DEV} rewind
${MT_CMD} -f ${TAPE_DEV} setblk ${BLOCK_SIZE}

echo "---------------------------------------------------------------"
echo "載入設定檔: ${VOLS_INCL_FILE}"
index=0
declare -a device_names
declare -a session_names
declare -a before_cmds
declare -a after_cmds
exec 9<&0
exec <${VOLS_INCL_FILE}
while read DEVICE_NAME SESSION_NAME BEFORE_CMD AFTER_CMD
do
case "${DEVICE_NAME}" in
""|\#*)
continue;
;;
esac
device_names[$index]=${DEVICE_NAME}
session_names[$index]=${SESSION_NAME}
before_cmds[$index]=${BEFORE_CMD}
after_cmds[$index]=${AFTER_CMD}
let "index += 1"
done
echo "共有 ${index} 個檔案系統要備份!"
echo "---------------------------------------------------------------"
exec 0<&9 9<&-

num=0
while [ "$num" -lt "$index" ]; do
DEVICE_NAME=${device_names[$num]}
SESSION_NAME=${session_names[$num]}
BEFORE_CMD=${before_cmds[$num]}
AFTER_CMD=${after_cmds[$num]}
let "num += 1"

date
echo "---------------------------------------------------------------"
echo "備份 ${DEVICE_NAME} 到磁帶 ${TAPE_DEV} 中..."
echo "---------------------------------------------------------------"
if [ "${BEFORE_CMD}" != "" ]; then
echo " *** 執行備份前置指令: ${CMD_PATH}/${BEFORE_CMD}"
${CMD_PATH}/${BEFORE_CMD}
fi
echo " *** 開始備份..."
echo "cmd: ${DUMP_CMD} \
-l ${BACKUP_LEVEL} \
-o \
-p ${TIME_DISPLAY} \
-J \
-F \
-M weekly_backup \
-L ${SESSION_NAME} \
- ${DEVICE_NAME} | \
${ZIP_CMD} -9qv | \
${DD_CMD} bs=${BLOCK_SIZE} conv=sync of=${TAPE_DEV}"
${DUMP_CMD} \
-l ${BACKUP_LEVEL} \
-o \
-p ${TIME_DISPLAY} \
-J \
-F \
-M weekly_backup \
-L ${SESSION_NAME} \
- ${DEVICE_NAME} | \
${ZIP_CMD} -9qv | \
${DD_CMD} bs=${BLOCK_SIZE} conv=sync of=${TAPE_DEV}
echo " *** 備份完成!"
if [ "${AFTER_CMD}" != "" ]; then
echo " *** 執行備份後置指令: ${CMD_PATH}/${AFTER_CMD}"
${CMD_PATH}/${AFTER_CMD}
fi
done

date
echo "---------------------------------------------------------------"
echo "備份完成!"
echo "---------------------------------------------------------------"

echo "---------------------------------------------------------------"
echo "將磁帶回轉"
echo "cmd: ${MT_CMD} -f ${TAPE_DEV} rewind"
echo "---------------------------------------------------------------"
echo
${MT_CMD} -f ${TAPE_DEV} rewind

num=0
lnum=0
while [ "$num" -lt "$index" ]; do
DEVICE_NAME=${device_names[$num]}
SESSION_NAME=${session_names[$num]}
BEFORE_CMD=${before_cmds[$num]}
AFTER_CMD=${after_cmds[$num]}
let "num += 1"

date
echo "---------------------------------------------------------------"
echo "測試備份內容 ${DEVICE_NAME}"
echo "---------------------------------------------------------------"
echo "cmd: ${DD_CMD} bs=${BLOCK_SIZE} conv=sync if=${TAPE_DEV} | ${ZIP_CMD} -tqv"
${DD_CMD} bs=${BLOCK_SIZE} conv=sync if=${TAPE_DEV} | ${ZIP_CMD} -tqv
echo
echo "---------------------------------------------------------------"
echo "如果要還原備份資料, 可以使用下面的指令:"
echo "${MT_CMD} -f ${TAPE_DEV} rewind"
echo "${MT_CMD} -f ${TAPE_DEV} fsf ${lnum}"
echo "${DD_CMD} bs=${BLOCK_SIZE} conv=sync if=${TAPE_DEV} | \ "
echo " ${ZIP_CMD} -dqv | \ "
echo " ${RESTORE_CMD} -p ${TIME_DISPLAY} -J - /path/to/restore/"
echo "---------------------------------------------------------------"
echo
let "lnum += 1"
done
fi

date
echo "---------------------------------------------------------------"
echo "將磁帶回轉"
echo "cmd: ${MT_CMD} -f ${TAPE_DEV} rewind"
echo "---------------------------------------------------------------"
echo
${MT_CMD} -f ${TAPE_DEV} rewind

date
exit 0

本文的最新版本可以由下列的網頁取得:

http://www.teatime.com.tw/~tommy/doc/xfs_backup.txt

postfix 說明

postfix 說明
轉載

以下是個人在 FreeBSD 上裝 postfix 的一些說明文件,由於檔案較大,故分成七個部份,希望對有需要的人有所幫助。

Postfix 是一套使用於架設 mail server 的軟體,其協定為 smpt (port 25),亦是各信件主機傳送信件或是你要將信件傳送至信件主機的通訊協定,在一般 unix-like 中大多是使用 sendmail ,那麼改用 Postfix 有何好處呢?請看以下說明:

1.安全性:sendmail 最為人詬病的就是其安全性,而 Postfix 可有效的改善這種現象,因其在執行時並不以 root 身份執行

2.簡單、快速:使用過 sendmail 的人便知道,sendmail 的設定檔並不很友善,而 Postfix 的設定檔簡單,只需設定一個重要的檔案 main.cf,且其說明詳細,如此在設定時可讓人快速的,省掉一些設定時的麻煩。另外,Postfix 的執行時是由一些分開的小程式個別執行,因此其執行效率較佳

3.相容性:Postfix 就是為了改善 sendmail 的一些缺點而設計的,因此其和 sendmail 的相容性極佳,在轉移上無任何問題

4.使用資源較少

5.為一免費的開放碼軟體

6.是供一些有用的工具軟體,便於日常管理及加強與 sendmail 的溝通

如同在 Postfix 概說中所說的,Postfix 是提供發信的功能,因此一個完整的 mail server 尚需提供收信功能。在 FreeBSD 中提供 qpopper 可達到此功能,以下介紹透過 FreeBSD 的 ports 來安裝 qpopper:

# cd /usr/ports/mail/qpopper
# make install

當安裝完成後,還需修改以下事項:

將 sendmail disable,請編輯 /etc/rc.conf ,將 sendmail_enable="YES" 設定為 sendmail_enable="NO",使用 killall -9 sendmail 停止掉 sendmail daemon

編輯 /etc/inetd.conf ,修改此行 pop3 stream tcp nowait root /usr/local/libexec/qpopper popper -s ,-s 的意思是啟動記錄檔

重新啟動 inetd,執行 killall -HUP inetd

經過以上 step ,測試一下 pop3 是否正常:

# telnet 0 110
Trying 0.0.0.0...
Connect to 0.
Escape character is '^]'.
+OK Qpopper (Version 以下省略..)

出現以上訊息,代表你的 Qpopper 已能正常工作,請鍵入 quit 結束連線..

Postfix 是提供發信的功能(透過 port 25),同樣的,我們透過方便的 ports 來安裝:

# cd /usr/ports/mail/postfix
# make install

在安裝過程中,會問你是否安裝帳號,請按 yes 確定

當安裝完成後,還需修改以下事項。由於 postfix 執行方式,是透過 standalone 而非由 inetd 來控制,因此我們需在 /usr/local/etc/rc.d 中建立一個 shell script 檔,以便開機時能啟動 postfix,建立方式如下:

# cd /usr/local/etc/rc.d
# ee postfixd.sh <- 這個名稱你可自取

在 postfixd.sh 中輸入以下資料:

#!/bin/sh
/usr/local/sbin/postfix start &
echo " postfix "

存檔後,啟動 postfix ,執行

# /bin/sh /usr/local/etc/rc.d/postfixd.sh

# /usr/local/sbin/postfix start

測試 Postfix 是否正常執行:

# telnet 0 25
Trying 0.0.0.0...
Connect to 0.
Escape character is '^]'.
220 cmlab.idv.tw ESMTP Postfix

出現以上訊息,代表你的 Postfix 已能正常執行,現在鍵入 quit 結束連線

在設定 Postfix ,我們需先了解 Postfix 的設定檔案,請參照以下說明:

Postfix 的設定檔案在 /usr/local/etc/postfix 目錄下,檔案分為以下類型
main.cf 這是 Postfix 最重要的設定檔,所有的設定都在此設定,這也是我們討論的重點
1.master.cf 這是用來設定 Postfix 信件處理時程式的相關設定( Postfix 是由於多個小程式共同處理信件的),一般我們不需也不建議去更改它

2.以 sample -* .cf ,這些是一些 sample 參考檔案,如 sample-main.cf、sample-master.cf .. 等,我們不需更改這些檔案,因為 Postfix 的主要設定檔是在 main.cf ,這些只是提供參考用

3.sample.access 和 sample-aliases 這二個檔和 sendmail 中的一樣,用來設定別名及存取控制

4.設定時我們可參考 sample-*.cf 檔案,將想變動的部份加至 main.cf 中即可

一般我們在設定 mail server 時,重點皆是擺在網域的設定、relay 的存取控制、以及一些安全措施(如信箱大小..等),因此我們就這些問題討論:

以下以網域名稱為 cmlab.idv.tw、主機名稱為 mail.cmlab.idv.tw 來做說明:

=> 設定網域名稱
mydomain = cmlab.idv.tw

=> 設定主機名稱(host name)
myhostname = mail.cmlab.idv.tw

=> 設定 aliases 的目錄
alias_maps = hash:/usr/local/etc/postfix/aliases
建立好你的 aliases 檔後(亦可由原先 sendmail 的 aliases 檔案拷貝過來,或將 sample-aliases 改為 aliases 使用),並轉換為 aliases.db

=> 將 aliases 檔轉換為 aliases.db
# cd /usr/local/etc/postfix
# /usr/local/sbin/postalias hash:aliases

=> 利用 access 檔來做存取限制,可參考在 /usr/local/etc/postfix/sample-access 檔案
在 access 中的設定格式如下:
設定對象 <設定方式>
其中設定對象可用主機名稱、主機 ip、網域、或郵件地址..
<設定方式> 主要有 REJECT、OK
如以下的設定
61.219.230.5 OK
cmlab.idv.tw OK
bad.com REJECT
test@com.tw OK

=> 用 postmap 將 access 轉換成 access.db
# cd /usr/local/etc/postfix
# /usr/local/sbin/postmap hash:access

=> 另外建議在 main.cf 中自行加上以下設定
mailbox_size_limit = 102400000 ->這是用來設定信箱大小,單位是 byte,如沒設定則內定值為 50 M,如本例將信箱大小設為 100 M
disable_vrfy_command = yes -> 將vrfy 功能關掉
smtpd_recipient_limit = 100 -> 限定每一封信可寄給幾個人,如本例為 100


=> 經過以上設定後,你便可測試你的 mail server 是否正常(通常可借由寄一封信到外面的主機,及從外面的主機寄一封信到 local 來確定 mail server 是否正常)

在設定 Postfix 後,我們來了解 Postfix 的檔案結構,請參照以下說明:

Postfix 的設定檔案在 /usr/local/etc/postfix 目錄下,檔案分為以下類型

1.main.cf 這是 Postfix 最重要的設定檔,所有的設定都在此設定,這也是我們討論的重點

2.master.cf 這是用來設定 Postfix 信件處理時程式的相關設定( Postfix 是由於多個小程式共同處理信件的),一般我們不需也不建議去更改它

3.以 sample -* .cf ,這些是一些 sample 參考檔案,如 sample-main.cf、sample-master.cf .. 等,我們不需更改這些檔案,因為 Postfix 的主要設定檔是在 main.cf ,這些只是提供參考用

4.sample-access 和 sample-aliases 這二個檔和 sendmail 中的一樣,用來設定別名及存取控制

5.Postfix 的執行檔在 /usr/local/sbin 目錄下,都是一些 post* 的檔案,如 postcat、postsuper,另還有一個和 sendmail (沒錯,就和 sendmail 一樣),可用來取代 sendmail 用的

6.信件放在 /var/mail 之下

7.mail queue 在 /var/spool/postfix 目錄下,是由一些分門別類的目錄所構成,有興趣的朋友可自行研究看看

8.系統日誌檔在 /var/log/maillog,建議時時查看,以維護系統的安全,亦可檢查信件來往正不正常

Postfix 在設計初,便是為了取代 sendmail ,因此和 sendmail 的相容性極佳,在此我們來研究一下 Postfix 如何和 sendmail 互通有無。

Postfix 的設定檔 mail.cf 和 sendmail 的 sendmail.cf 相當,不過簡單易懂

Postfix 可以使用 sendmail 的 access 及 aliases 檔,方法如下:
=> 將 aliases 檔轉換為 aliases.db
# cd /usr/local/etc/postfix
# /usr/local/sbin/postalias hash:aliases

=> 用 postmap 將 access 轉換成 access.db
# cd /usr/local/etc/postfix
# /usr/local/sbin/postmap hash:acces

sendmail 提供的一些指令,如 mailq .. ,Postfix 亦可達到其功能,方法如下:
=> 將 /etc/mail/mailer.conf 裡面的四項設定改成:
sendmail /usr/local/sbin/sendmail
send-mail /usr/local/sbin/sendmail
mailq /usr/local/sbin/sendmail
newaliases /usr/local/sbin/sendmail

如此則可在 Postfix 中使用 mailq 來查看目前 mail queue 的狀況,另外 Posfix 所提供的 sendmail 指令,亦可提供大部份先前 sendmail 的功能,各位朋友可用好男人 man sendmail 來查看,以下提供一些說明(請注意路徑):

=> 查詢目前 mail queue,和原 sendmail 的 mailq 功能一樣
# /usr/local/sbin/sendmail -bp

=> 立即送出信件
# /usr/local/sbin/sendmail -q

=> 模仿原 sendmail 的 newaliases 功能
# /usr/local/sbin/sendmail -I

在 /usr/local/sbin 這個目錄中,Postfix 提供了一些工具程式,皆是以 post 開頭,如 postcat、postfix、postsuper .. 等,其中有些是在信件處理時使用的,不建議在一般 command line 下用,我們就一些實用的指令來做說明:

=> postfix 這個指令用來啟動、停止、重新啟動 postfix daemon,如
# /usr/local/sbin/postfix start -> 啟動 postfix
# /usr/local/sbin/postfix stop -> 停止postfix
# /usr/local/sbin/postfix reload -> 重新啟動 postfix

=> postalias 這個指令用來將 aliases 檔轉為 aliases.db 檔
# cd /usr/local/etc/postfix
# /usr/local/sbin/postalias hash:aliases

=> postmap 將 access 檔轉為 access.db 檔
# cd /usr/local/etc/postfix
# /usr/local/sbin/postmap hash:access

=> postsuper 從其名稱不難得知,這是 Postfix 中最 super 的指令了,其詳細用法可用 man postsuper 查看,在此只做簡單說明:
# /usr/local/sbin/postsuper -d -> 將某一封 queue message 刪掉
# /usr/local/sbin/postsuper -d ALL -> 刪除所有的 queue
# /usr/local/sbin/postsuper -sv -> 檢查和修復 postfix 的信件檔

Ports安裝設定

Ports安裝設定
轉載

安裝應用軟體:The Ports collection
本文件操作於:FreeBSD 4.4-RELEASE

Ports安裝設定:

安裝應用軟體:The Ports collection
本文件操作於:FreeBSD 4.4-RELEASE
Ports安裝設定:
用Ports的方式安裝基本的應用軟體。而FreeBSD原則上會到各應用軟體的總站臺下載原始程式後才編譯、安裝,如此速度上會顯得很慢。因此,我們必須設定FreeBSD只需到交大資工系(或者是臺灣地區其他的mirror站)來抓取原始程式碼即可。

cp /etc/defaults/make.conf /etc/
vi /etc/make.conf

將:

# Port master sites.
#
# If you want your port fetches to go somewhere else than the default
# (specified below) in case the distfile/patchfile was not found,
# uncomment this and change it to a location nearest you. (Don't
# remove the "/${DIST_SUBDIR}/" part.)
#
#MASTER_SITE_BACKUP?= \
# ftp://ftp.freebsd.org/pub/FreeBSD/ports/distfiles/${DIST_SUBDIR}/
#
# If you want your port fetches to check the above site first (before
# the MASTER_SITES specified in the port Makefiles), uncomment the
# line below. You can also change the right side to point to wherever
# you want.
#
#MASTER_SITE_OVERRIDE?= ${MASTER_SITE_BACKUP}
#

改為:

# Port master sites.
#
# If you want your port fetches to go somewhere else than the default
# (specified below) in case the distfile/patchfile was not found,
# uncomment this and change it to a location nearest you. (Don't
# remove the "/${DIST_SUBDIR}/" part.)
#

MASTER_SITE_BACKUP?= \
ftp://ftp.tw.freebsd.org/pub/FreeBSD/distfiles/${DIST_SUBDIR}/\
ftp://ftp5.tw.freebsd.org/pub/FreeBSD/distfiles/${DIST_SUBDIR}/\
ftp://ftp10.tw.freebsd.org/pub/FreeBSD/distfiles/${DIST_SUBDIR}/\
ftp://ftp2.tw.freebsd.org/pub/FreeBSD/distfiles/${DIST_SUBDIR}/\
ftp://ftp3.tw.freebsd.org/pub/FreeBSD/distfiles/${DIST_SUBDIR}/\
ftp://ftp4.tw.freebsd.org/pub/FreeBSD/distfiles/${DIST_SUBDIR}/\
ftp://ftp7.tw.freebsd.org/pub/FreeBSD/distfiles/${DIST_SUBDIR}/\
ftp://ftp8.tw.freebsd.org/pub/FreeBSD/distfiles/${DIST_SUBDIR}/\
ftp://ftp9.tw.freebsd.org/pub/FreeBSD/distfiles/${DIST_SUBDIR}/\
ftp://ftp11.tw.freebsd.org/pub/FreeBSD/distfiles/${DIST_SUBDIR}/\
ftp://ftp12.tw.freebsd.org/pub/FreeBSD/distfiles/${DIST_SUBDIR}/\
ftp://ftp.freebsd.org/pub/FreeBSD/ports/distfiles/${DIST_SUBDIR}/

#
# If you want your port fetches to check the above site first (before
# the MASTER_SITES specified in the port Makefiles), uncomment the
# line below. You can also change the right side to point to wherever
# you want.
#
MASTER_SITE_OVERRIDE?= ${MASTER_SITE_BACKUP}
#

上述站台的排列原則是,哪一台的網路連線與您的網路環境最佳者,排在第一個。

抓檔案時,如果第一台抓不到,會依序向第二台詢問有沒有。如果都問完了,還是沒有,就會到國外的原始站台去抓。不過,這種情形應該很少見到。

開始用Ports安裝應用軟體:

cd /usr/ports/net/cvsup-without-gui; make install clean
cd /usr/ports/sysutils/portupgrade ; make install clean
cd /usr/ports/ftp/wget ; make install clean
cd /usr/ports/security/sudo ; make install clean
cd /usr/ports/shells/bash2 ; make install clean
cd /usr/ports/ftp/ncftp3 ; make install clean
cd /usr/ports/mail/imap-uw ; make install clean
cd /usr/ports/mail/qpopper ; make install clean
cd /usr/ports/security/pidentd ; make install clean
cd /usr/ports/misc/gnuls ; make install clean

其中,cvsup-without-gui 與 portupgrade 是屬於系統更新( src 及 ports-tree )的工具軟體,建議您一定要裝。

查看安裝之後的結果:

pkg_info
autoconf-2.13_1 Automatically configure source code on many Un*x platforms
bash-2.05 The GNU Bourne Again Shell
gettext-0.10.35 GNU gettext package
gettext-0.10.38 GNU gettext package
gmake-3.79.1 GNU version of 'make' utility
isc-dhcp3-3.0.r11 ISC Dynamic Host Configuration Protocol client and server code
libiconv-1.7_1 A character set conversion library
libtool-1.3.4_2 Generic shared library support script
m4-1.4 GNU's m4
ncftp3-3.0.3 ftp replacement with advanced user interface
pidentd-2.8.5 An RFC1413 identification server
qpopper-4.0.3_1 Berkeley POP 3 server (now maintained by Qualcomm)
wget-1.7_3 Retrieve files from the 'net via HTTP and FTP

大海撈針:搜尋某一ports
cd /usr/ports
make search key="popper" | more
cd /usr/ports
make search key="libiconv" | grep Path: | grep libiconv

Port: qpopper-2.53_2
Path: /usr/ports/mail/popper
Info: Berkeley POP 3 server (now maintained by Qualcomm)
Maint: ache@freebsd.org
Index: mail
B-deps:
R-deps:

Port: qpopper-4.0.3_1
Path: /usr/ports/mail/qpopper
Info: Berkeley POP 3 server (now maintained by Qualcomm)
Maint: lioux@FreeBSD.org
Index: mail ipv6
B-deps: autoconf-2.13_1 m4-1.4
R-deps:

Port:軟體名稱,Path:路徑,Info:訊息,Maint:維護者,Index:類型。

cd /usr/ports
make search key="libiconv" | grep Path: | grep libiconv

ports-tree的更新

cd /usr/ports

fetch ftp://freebsd.csie.nctu.edu.tw/pub/CVSup/cvsupfile-ports
cvsup -g -L 2 cvsupfile-ports

我以HiNet-ADSL在FreeBSD 4.2-RELEASE上至NCTU更新ports,共花費了01:07:00。

而在苗栗縣網中,以FreeBSD 4.6-RELEASE至NCTU更新ports,只花費了00:05:00。

這個更新的內容預設值是全部的ports,所需耗費的時間相對就很長。您可以只選擇其中的一部份來更新即可,只要改cvsupfile-ports檔案最底下的那一行(ports-all)。

ports-base: /usr/ports/... misc files at the top of /usr/ports
ports-archivers: /usr/ports/archivers archiving tools
ports-audio: /usr/ports/audio sound support
ports-benchmarks: /usr/ports/benchmarks benchmarks
ports-cad: /usr/ports/cad CAD tools
ports-comms: /usr/ports/comms communication software
ports-databases: /usr/ports/databases databases
ports-devel: /usr/ports/devel development utilities
ports-editors: /usr/ports/editors editors
ports-emulators: /usr/ports/emulators emulators for other OSes
ports-games: /usr/ports/games games
ports-graphics: /usr/ports/graphics various graphics utilities
ports-japanese: /usr/ports/japanese Japanese software.
ports-lang: /usr/ports/lang programming languages
ports-mail: /usr/ports/mail mail software
ports-math: /usr/ports/math numerical computation software
ports-misc: /usr/ports/misc miscellaneous utilities
ports-net: /usr/ports/net networking software
ports-news: /usr/ports/news USENET news software
ports-plan9: /usr/ports/plan9 various programs from Plan9
ports-print: /usr/ports/print printing software
ports-russian: /usr/ports/russian Russian software
ports-security: /usr/ports/security ``security'' utilities, for better or for worse
ports-shells: /usr/ports/shells various UN*X shells
ports-sysutils: /usr/ports/sysutils system utilities
ports-www: /usr/ports/www software related to the world wide web
ports-x11: /usr/ports/x11 X11 software

用 ports 安裝的軟體,遇有該軟體版本更新時如何處置?
請先做「ports-tree的更新」的動作,之後再分別執行下列三道指令:

portsdb -Uu

pkgdb -F

portupgrade -acCv

備註:執行 portsdb -Uu 時,會有令人覺得當機的味道。別耽心,耐心的稍等一下下就好。

portupgrade時,改變預設的編譯安裝選項
編輯 /usr/local/etc/pkgtools.conf

MAKE_ARGS = {
'databases/mysql323-*' => 'WITH_CHARSET=big5',
'databases/mysql323-*' => 'SKIP_INSTALL_DB=yes',
'databases/phpmyadmin' => 'MYADMDIR?=www/data/phpMyAdmin',
'www/apache13' => 'WITH_APACHE_SUEXEC=yes',
}

mysql 安裝時,預設不支援中文;而phpMyAdmin預設的安裝路徑則在www/data.default/phpMyAdmin,與apache不同,害我裝了之後找好久才找到。

版本衝突時
pkgdb -F

Duplicated origin: sysutils/portupgrade - portupgrade-20020706 portupgrade-20020805
Unregister any of them? [no] yes

Unregister portupgrade-20020706 keeping the installed files intact? [no] no

portupgrade 強制更新 (操作於 FreeBSD 4.6.2-RELEASE )

* 未更新 PORTS-TREE 前,portupgrade 已安裝的版本:

pkg_info | grep portupgrade
portupgrade-20020429 Very powerful FreeBSD ports/packages upgrading tool and mor

* 更新 PORTS-TREE 之後,PORTS 中 portupgrade 的版本:

grep \PORTVERSION= /usr/ports/sysutils/portupgrade/Makefile

PORTVERSION= 20020805

* 執行 portupgrade 後,portupgrade 自己並未更新。

* 強制以新的portupgrade取代舊的portupgrade-20020429

portupgrade -o /usr/ports/sysutils/portupgrade portupgrade-20020429

* 再檢查一遍portupgrade 安裝的版本:

pkg_info | grep portupgrade

portupgrade-20020805 Very powerful FreeBSD ports/packages upgrading tool and mor

FreshPorts
http://freshports.org/

每一個ports都有專人負責,其更新也是非常迅速,這兒有第一手資料。

網路上的相關文件:
http://freebsd.sinica.edu.tw/~statue/handbook/ports.html
http://freebsd.sinica.edu.tw/pipermail/freebsd-taiwan-doc/2001-April/000013.html
http://www.lsps.tp.edu.tw/~gsyan/freebsd2001/ports.html
http://ohaha.ks.edu.tw/ports.htm
http://ohaha.ks.edu.tw/portupgrade.htm
http://ohaha.ks.edu.tw/portexec.htm
http://www.study-area.net/freebsd/how_to_use_ports_package/how_to_use_ports.htm
http://freebsd.csie.nctu.edu.tw/handbook.big5/handbook197.html

其他:

* make install : 安裝所選定的 Port
* make deinstall : 移除已安裝的 Port
* make reinstall : 移除之後再安裝一次
* make clean : 安裝完畢後移除 make 資料夾下的檔案
* make distclean : 移除安裝後的原始檔案,以節省磁碟空間

* make install
* make install clean
* make install clean distclean

網絡文件系統(NFS)

網絡文件系統(NFS)

轉載

在眾多的文件系統中,FreeBSD的支持的是非常獨特的,那就是網絡文件系統(NFS)。NFS可以使一台或几台机器通過網絡共享目錄或文件。使用NFS,用戶和程序能夠訪問遠程系統上的文件就如同訪問本地的一樣。

NFS有以下几種特性: 
本地工作站無須太多磁盤空間,因為常用的數据被存放在單一的机器上並且還會剩余一些空間可被網絡上的其它人訪問。

在網絡上,每個用戶不一定需要有唯一的home目錄。一旦建立一個可以通過NFS使用的目錄,那麼它可以被網絡上任何處訪問。 

像軟盤和CD-ROM能夠在網絡上被其它机器訪問,而不需要額外的硬件。 

它如何工作 
NFS由兩個方面組成--客戶端和服務器端。考慮到它們的聯系,客戶端需要服務器端所擁有的數据。服務器與客戶共享數据。為了這個系統正常地工作,少數進程不得不在限制下運行。 

服務器必須運行以下几個守護進程: 
nfsd--NFS的守護進程,它響應客戶的請求。 
mountd--NFS Mount守護進程,真正實現nfsd傳遞給它的客戶請求。 

客戶端只需要運行一個守護進程: 
nfsiod--NFS异步I/O守護進程,響應從NFS服務器來的請求。 

設置NFS 
非常幸運,在FreeBSD系統上設置它是非常容易的。只需通過极少的修改/etc/rc.conf文件,就可以在啟動時運行這個進程了。 

在NFS服務器上,請确定你有: 
nfs_server_enable="YES" 
nfs_server_flags="-u -t -n 4" 
mountd_flags="-r" 
每當NFS服務器啟動時,mountd就自動運行了。-u和-t標志,告訴nfsd是否服務于UDP和TCP的客戶端。-n 4標志,告訴nfsd運行自己的4個相同的拷貝。 

在客戶端,确定你有: 
nfs_client_enable="YES" 
nfs_client_flags="-n 4" 
像nfsd,-n 4告訴nfsiod運行自己的4個拷貝。 

最后一個設置是要求你建立一個叫作/etc/exports的文件。這個文件指定你的服務器使用何種文件系統,以及哪几個客戶端將要共享。這個文件中的每一行指定一個需要被共享的文件系統。在文件可以使用的這些選擇是比較煩的,但只需要涉及其中一部分。你可以查找man page。 

這兒有几個例子: 
以下的几行輸出/cdrom到三個"笨"机器上,它們有相同的域名,或者在你的/etc/hosts文件中登錄過。-ro標志使得共享的文件系統只讀,通過這個標志,遠程系統將不可能在共享文件系統上作任何更改。 
/cdrom -ro moe larry curly 
下一行輸出/home通過IP地址到三台主机。這是一個非常有用的設置,如果你有一個私有的網絡,但沒有DNS。-alldirs標志可以使指定的文件系統中的所有目錄被輸出。 
/home -alldirs 10.0.0.2 10.0.0.3 10.0.0.4 
下一行輸出/a到兩台机器上,它們與NFS服務器在不同域上。-maproot=0標志允許在遠程系統上的root用戶,使用root權限向共享文件系統寫入。除去-maproot=0標志,即使一些人有root權限訪問遠程系統,但它們不可以修改共享文件系統。 
/a -maproot=0 host.domain.com box.example.com 
為了使客戶能夠共享一個輸出的文件系統,它必須有這個權限。确定你的客戶列表在你的/etc/exports文件中。 
現在你已經改動了設置,你可以reboot並且在啟動時運行了。或者你也可以在命令行下輸入: 

在NFS服務器上: 
# nfsd -u -t -n 4 
# mountd -r 
在NFS客戶上: 
# nfsiod -n 4 
現在你已經准備真正地挂起一個遠程文件系統。有兩種方法。在這個例子中,服務器名字是server,而客戶端是client。如果你只是臨時挂起一個遠程文件系統或希望測試一下你的設置,你可以在客戶机的命令行下,以root的權限輸入: 
# mount server:/home /mnt 
這樣將挂起在server上的/home到client的/mnt。如果一切都設置正确,那麼你可以在/mnt下看見server上的文件. 
如果你愿意每次啟動時都挂起一人遠程文件系統,那麼你就需要修改你的/etc/fstab文件.例如: 
server:/home /mnt nfs rw 0 0 
更多細節請參見fstab的man page. 


實際使用 

NFS有許多非常"酷"的用途.我在我管理的網絡上大量使用它.以下只是我使用它的一部分方法:. 

在網絡上,有好几台机器,但是只有一台机器有CD-ROM.為什麼?因為我使用NFS使用所有的机器共享CD-ROM.而對于軟驅其實也一樣. 

如此多的机器,而你的個人文件就存儲地非常地分散了.我使用一台中央NFS服務器存儲了所有的用戶的home目錄,並且與其它机器一起共享它們,所以無論從何處登錄,我總是有相同的home目錄. 

當你准備在其中的一台机器上重新安裝FreeBSD,使用NFS是一種方法.只要將光盤放入你的文件服務器,然后一切照舊. 
我有一個公共目錄:/usr/ports/distfiles,所有的机器都共享它.這樣,當我將要在一台已經安裝過某個port的机器上安裝這個port時,我不需要重新再下載一遍所有的源文件. 

問題匯總 
某些ISA的以太網卡可能會引起一些問題,特別是在NFS上.這些困難在FreeBSD上並不特別明顯,但系統可能會受影響. 

這些問題几乎總是發生在以及聯網的高性能工作站上,例如Sun公司的机器.NFS挂起將會工作非常好,一些操作也是成功的,但是突然server對client沒有了響應,即使另外的系統請求繼續被響應.這些問題通常在client系統上,無論client是FreeBSD或者是其它的工作站.許多系統上,一旦這個問題出現,系統將無法正常關閉.唯一的解決方法就是經常重置client,因為NFS的情況不能解決. 
盡管這個"正确"的解決方法是對付運行FreeBSD的高性能工作站,但這也是一個簡單的安全的方法.如果FreeBSD系統是server,client運行時要有參數-w=1024.如果FreeBSD是client,那麼挂起NFS文件系統時,要有參數-r=1024.如果需要在client上自動挂起NFS,這些選擇需要在fstab的第四個域中輸入,或使用mount命令的-o參數手動挂起. 

需要注意的是,在NFS server和client在不同的網絡上時,這個問題也會出現.如果是這個原因,請确定你的路由器有必須支持UDP信息. 

下例中,fastws是高性能工作站的host名,freebox是一台有低效率網卡的FreeBSD系統.當然,/sharedfs將作為NFS文件系統,而在client上就是/project.在所用情況下,注意附加選項. 

將freebox作為client:在/etc/fstab中輸入 
fastws:/sharedfs /project nfs rw,-r=1024 0 0 
如果是手工挂起: 
# mount -t nfs -o -r=1024 fastws:/sharedfs /project 
將freebox作為server,在fastws的/etc/fstab中輸入: 
freebox:/sharedfs /project nfs rw,-w=1024 0 0 
如果需要手工挂起: 
# mount -t nfs -o -w=1024 freebox:/sharedfs /project 
几乎任何16-bit以太網卡不需要以上的關于讀寫的限制. 

對于細心的人,可能已經看出,何處出了這種錯誤,也就說明了此處為什麼不可恢復正常的原因了.NFS是典型的每塊8K的文件系統.(當然也可以優化成更小的).當最大的數据包在1500字節時,NFS的塊被分成几個數据包,盡管它對于上層協議來說,還是一個獨立的需要接收,确認並且組合的單元.高性能工作站能夠從組成NFS單元的一個個緊接著的小包中還原這個包.在低效率的網卡中,后面的小包由于超時在與其在相同NFS單元中前面的小包到達目的地之前就會溢出,使用得整個單元不能被還原,並且不會發出确認信號.結果,工作站會超時,並且會重新再試一次,但是以8K一個單元,還是出現以上的錯誤,就這樣永遠休止. 

使單元的大小小于數据包的尺寸限制,這樣就可以确保信號會被接收,並且收到确認信號,從而避免以上局面. 

當高性能服務器對一台配有高效的網卡的机器輸入數据時,超時溢出仍會發生,但是這種超時溢出與以上所述的NFS的單元錯誤並不相同.當超時溢出發生時,受到影響的單元會被重傳,而這次是它們被接收,确認,還原可能會成功. 

FreeBSD diskless 無碟開機

FreeBSD diskless 無碟開機

以下內容從網路轉載

因為架設平行運算的關係,所以灌了不少台FreeBSD,後來發現每台都跑去灌實在是很麻煩,
而且維護起來也不容易,所以才想嘗試製作diskless試試看,但是我還不知道這樣搞會不會降低平
行運算的效能,還要進行測試,回歸主題,分享一下這幾天架設FreeBSD的diskless的過程吧!

Master
OS: FreeBSD 5.0 Release-p7
CPU:P3-450
LanCard:Intel(R) PRO/1000

Client
CPU:P2-300 , P3-550 , K7-700 , P4-3G
LanCard:Intel(R) PRO/100

製作Diskless首先就是要先從網路讀取kernel,至少有兩種方式可以達到
1. PXEboot
2. etherboot port (/usr/port/net/etherboot)

第二種etherboot還要準備開機片進入DOS才有辦法啟動,有點小麻煩
手上剛好又都是Intel的網路卡,所以我用PXEboot + NFSRoot 來達成

1. 先把TFTP跑起來
# ee /etc/inetd.conf
代碼:
tftp dgram udp wait root /usr/libexec/tftpd tftpd -s /usr/tftpboot

# killall -1 inetd
/usr/tftpboot 自己修改自己要的目錄

2. 設定DHCP(net/isc-dhcp3)
# ee /usr/local/etc/dhcpd.conf
修改成下列選項
代碼:
group {
subnet 192.168.0.0 netmask 255.255.255.0 {
option subnet-mask 255.255.255.0;
range dynamic-bootp 192.168.0.3 192.168.0.10;
option root-path "192.168.0.2:/home/diskless";
filename "pxeboot";
option routers 192.168.0.2;
}


192.168.0.2:/home/diskless是NFS的分享格式,這個目錄也就是Client讀取的時候的根目錄,我把它放在/home/diskless

my dhcp.conf http://bin.twbbs.org/tmp/dhcpd.conf

3. 修改NFS分享
確認NFS Server有開啟
/etc/rc.conf
代碼:
nfs_server_enable="YES"
rpcbind_enable="YES"

修改/etc/exports
代碼:
/home -alldir -ro -netmask 192.168.0 -netmask 255.255.255.0

重跑mountd
#killall -1 mountd
備註 : 如果要共享/usr的話,記得把/usr設定分享

4. 準備Root System所需要的檔案
最方便的方式就是去把ISO-Image的第二片給抓回來修改,因為這一片是Live-CD格式
ftp://freebsd.csie.nctu.edu.tw/pub/releases/i386/ISO-IMAGES/5.0/5.0-RELEASE-i386-disc2.iso

掛入系統,複製到/home/diskless
# mkdir -p /home/diskless
# mdconfig -a -t vnode -f 5.0-RELEASE-i386-disc2.iso
# mount_cd9660 /dev/md0 /mnt
# cd /home/diskless
# rsync --progress -avr /mnt/ .
# umount /mnt
# mdconfig -d -u 0

備註:FreeBSD 4.x請改用vnconfig

6. 設定Root System
cd /home/diskless
(1) 先刪除一些用不到的目錄和檔案,不刪也可以
rm -rf boot.catalog cdrom.inf COPYRIGHT floppies rr_moved

(2) 修改etc/hosts和etc/

(3) 修改etc/fstab
代碼:

# Device Mountpoint FStype Options Dump Pass#
192.168.0.2:/home/diskless / nfs ro 0 0
#192.168.0.2:/usr /usr nfs ro 0 0


備註:如果/usr要分享就一起掛上去
FreeBSD 4.x 要加掛procfs喔

(4) 修改etc/rc.conf
代碼:

hostname="hostname"
kern_securelevel_enable="NO"
moused_enable="YES"
sendmail_enable="NO"
sshd_enable="YES"
usbd_enable="YES"
nfs_client_enable="YES"

跟網路有關的選項就不需要設定了,之前DHCP取過了

(6) 修改 etc/rc
大約第53行的位置請加入下列選項
代碼:

mdconfig -a -t malloc -s 4m
newfs /dev/md0
mount /dev/md0 /etc
cp -R /conf/etc.`ifconfig fxp0 | grep inet | awk -F ' ' '{printf $2}'`/* /etc
請把fxp0置換成你的Client端的網路卡代號

備註:FreeBSD 4.x請使用vnconfig

7. 設定每台Client不同設定檔
這個步驟是我希望讓每一台機器擁有不同的etc做的
# cd /home/diskless
# mkdir conf
# cp -R etc conf/etc.

請注意,把換成diskless的時候取得的IP選項,這樣
就可以讓每一台機器在boot的時候讀取不同的/etc設定

8. 編一個Diskless的kernel出來吧
# cd /usr/src/sys/i386/conf
# cp GENERIC Diskless
# ee Diskless
修改符合你Client的選項,並加入下面選項
代碼:
options NFS_ROOT

# config Diskless
# cd ../compile/Diskless
# make depend ; make kernel
# cd /home/diskless/boot/kernel
# cp /usr/src/sys/i386/compile/Diskless/kernel .
取代home/diskless/boot/下的kernel就可以了

9. 最後,置放pxeboot檔案
先修改/home/diskless/boot/loader.conf
把這三行都標記起來
代碼:
#mfsroot_load="YES"
#mfsroot_type="mfs_root"
#mfsroot_name="/boot/mfsroot"

然後複製pxeboot
# cp /home/diskless/boot/pxeboot /usr/tftpboot

完成! 謝謝各位收看!

這篇是雜牌軍啊!收看了好多份文件拼拼湊湊弄起來的
所以很多做法我不確定是不是正規做法,如果大家覺得哪裡怪怪的
可以修改的更好一定要通知我啊............

另外......我沒有放swap進去,我實在是不知道diskless該怎麼去加swap比較好
(NFS分享可讀寫檔案放swap? 這樣我是怕有安全性的問題啊! swap不就隨時可以被別台電腦dump走資料)

使用上感覺起來目前是還沒有什麼慢的感覺,失去了硬碟的聲音感覺好安靜,X-Window晚點裝上去在測試看看有沒有慢的感覺.........呵呵!

參考資料
http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/diskless.html
http://www.iet.unipi.it/~luigi/diskless.html
http://akiba.to/diskless.html
http://info.iet.unipi.it/~luigi/diskless981113/
http://www.eldemonio.org/docs/freebsd/diskless.html
http://ezine.daemonnews.org/200301/sparc64-nfsroot.html
http://freebsd.sinica.edu.tw/docs/handbook-2.1.0/handbook178.html
http://www.fanqiang.com/a1/b2/20010416/145643_b.html

apache + modssl with php4 enabled

apache + modssl with php4 enabled
轉載

甚麼是ssl?
security socket layer指的是透過加密機制來保護client端與server端之間傳輸的資料


apache web server對於ssl加密保護的選擇
目前在ports tree裡面有兩種選擇:
01./usr/ports/www/apache13-modssl/
02./usr/ports/www/apache13-ssl/
這兩者之間最主要的差別在於apache13-ssl是直接將ssl包成apache的一部份,而apache13-modssl則是採用模組的方式
來載入ssl,兩者都可以讓web server使用ssl加密傳輸資料,各有好有壞,在這邊,我選擇apache13-modssl
目前for apache2的modssl只有rh有作成for rh8的rpm檔,在FreeBSD上目前還沒有出現,暫時不考慮使用apache2

為甚麼需要apache + modssl?
除了架設電子商務網站的需求之外,最常見的原因就是為了發展能夠在web上使用的應用程式如:web mail , web apps等
有需要對傳輸的資料作保護的應用,特別是企業如果提供使用者web mail功能,為了防範使用者密碼被竊取,加上ssl保護
是必須的,對於電子商務網站而言更是取得消費者信任的必要的東西,這邊不討論對於電子商務的應用的部份

甚麼是php?
php是目前在web上應用的相當廣泛的一種script語言,也有許多的web ap使用php來開發,如phpbb這個相當有名的討論版程式
這裡只介紹怎麼將php4安裝成apache + modssl的模組
這邊只介紹以ports安裝,在安裝前務必要先更新過ports tree

安裝apache + modssl
cd /usr/ports/www/apache13-modssl/
make install clean

安裝mod_php4
cd /usr/ports/www/mod_php4
make install clean
這時會出現一個選單,其中有些選項是互相衝突的,例如gd1 , gd2這兩個功能是互相衝突的,如果發現這樣的問題時
make clean之後在重新make install clean重新選取一次

ports安裝最大的好處在於,ports maintainer已經事先做好的script,能夠自動為使用者修改httpd.conf,使用者只要完成
這些手續之後,如果編譯系統無誤的話,就已經建制完成了有ssl加密保護的apache server

apache + modssl的設定檔說明
上面這些動作編譯完成之後,/usr/local/etc/apache/會出現apache13-modssl的設定檔


.htaccess的應用


使用者個人網頁


mod_php4的設定檔說明
安裝完成mod_php4之後,預設不會有php.ini,必須自己手動將php.ini.dist複製成php.ini
cp /usr/local/etc/php.ini.dist /usr/local/etc/php.ini


啟動apache server
預設安裝完成之後並不會自動在/usr/local/etc/rc.d/裡面產生apache.sh,需要自己手動將apache.sh.dist複製成apache.sh
並加上可執行的屬性
cp /usr/local/etc/rc.d/apache.sh.dist /usr/local/etc/rc.d/apache.sh
chmod +x /usr/local/etc/rc.d/apache.sh
/usr/local/etc/rc.d/apache.sh start
這樣就啟動了web server

測試服務是否正常
sockstat | grep http有看到出現就表示apache已經成功的執行了
www httpd 52640 16 tcp4 *:443 *:*
www httpd 52640 17 tcp4 *:80 *:*
這時候在用瀏覽器輸入http://your.server.ip.address/就可以看到預設的網頁了

建立apache專用的newsyslog.conf選項
在/etc/newsyslog.conf中加入這兩行指令
/var/log/httpd-access.log 644 7 100 24 B /var/run/httpd.pid 30
/var/log/httpd-error.log 644 7 100 24 B /var/run/httpd.pid 30

搜尋並安裝適合的webmail
通常為了方便使用者在公司外使用信箱,一般都會提供webmail的功能,當然,前提是mail server的功能必須先能夠正常工作
ports tree中也提供了許多種的webmail可以選擇,有支援imap4的,有支援其他功能的,可以簡單的使用指令來搜尋
cd /usr/ports/
make search key=webmail | more
這邊選擇中文支援程度比較好,且主要由成大電機開發與維護的openwebmail來安裝
cd /usr/ports/mail/openwebmail/
make install clean

修改成中文版
修改/usr/local/www/cgi-bin-dist/openwebmail/etc/openwebmail.conf中的
default_language改成zh_TW.Big5

建立openwebmail的log檔
cd /var/log/
touch openwebmail.log

使用瀏覽器開啟http://your.server.ip.address/cgi-bin/openwebmail/openwebmail.pl就可以看到登入畫面了


Posted by antony at 02:52 PM | Comments (0) | TrackBack
ports 的原理
轉載

再談ports的原理之前必須先理解:誰有權力去更動ports裡面的東西
port maintainer:負責維護自己有興趣的port的更新、問題修正等相關問題(任何人都可以擔任)
port committer:負責對port maintainer做出來的port做再次確認的工作,有問題的話也會加以修正
(需要一定的考核之後才能成為committer)


接下來必須瞭解:什麼是dependency(相依性) , dependency hell
以openwebmail為例,這是一個web mail(web interface mua),可想而知,必須要有web server才能跑
openwebmail,而少了web server,openwebmail就無法正常工作,於是openwebmail有了web server這個
dependency(相依性)
而web server在這裡以apache為例,要安裝apache就必須先安裝好expat2這個軟體,這樣一路連貫下去直
到滿足所有openwebmail所需要的相依性
而在安裝軟體時最怕遇到的就是dependency hell,也就是安裝一個東西,這東西有很多相依性,而有相依
性的東西又有很多相依性,使的安裝軟體非常的痛苦
在程式開發的觀點來看的話,寫一個軟體,但其中有呼叫其他lib提供的function,這時候寫出來的軟體對
提供function的lib就有了相依性,如果這個lib又有其他的相依性,就很容易形成安裝軟體時的
dependency hell

理解了相依性的問題之後,再來談ports的架構

分類:依照不同的用途來分類

搜尋:針對INDEX做搜尋
make search key=
make search name=

安裝最簡單的方法為
cd /usr/ports/xxxx/yyyy/
make install clean

解析一個port
damon[/usr/ports/chinese/xcin25]-damon->ls
Makefile README.html distinfo files/ pkg-descr pkg-plist
這是一個很典型的port,裡面有
Makefile:定義了編譯時所使用的參數
README.html:說明檔
distinfo:記錄了所抓下來的檔案的md5 checksum
files/:放的是port maintainer所寫的patch
pkg-descr:port maintainer所寫的簡單的說明
pkg-plist:記錄了安裝了哪些檔案到什麼地方

先看pkg-descr
damon[/usr/ports/chinese/xcin25]-damon->cat pkg-descr
xcin is a Chinese INput application in X, well support in both Traditional
Chinese(Big5) and Simplified Chinese(GB) charsets. New version of xcin support
standard XIM too. You can activate one xcin-XIM server, meanwhile, use
different locale configuration to input Big5/GB words at the different
sessions. This port is current version of xcin, code rewritten by
Tung-Han Hsieh .

WWW: http://xcin.linux.org.tw/

Porting to FreeBSD by Yung-Jen Hung
& Keith Jang .

再來看pkg-plist
damon[/usr/ports/chinese/xcin25]-damon->cat pkg-plist
bin/xcin2.5
etc/xcinrc
lib/X11/xcin25/bimsphone.a
lib/X11/xcin25/bimsphone.la
lib/X11/xcin25/bimsphone.so
lib/X11/xcin25/bin/cin2tab
lib/X11/xcin25/chewing.a
lib/X11/xcin25/chewing.la
lib/X11/xcin25/chewing.so
%%PORTDOCS%%lib/X11/xcin25/doc/Bugs
%%PORTDOCS%%lib/X11/xcin25/doc/COPYING
%%PORTDOCS%%lib/X11/xcin25/doc/CREDITS
以下省略

再來看Makefile
# New ports collection makefile for: xcin25
# Date created: 18 Oct 1999
# Whom: Keith Jang
#
# $FreeBSD: ports/chinese/xcin25/Makefile,v 1.46 2003/02/21 11:06:31 knu Exp $
#

PORTNAME= xcin
PORTVERSION= 2.5.3.p2
PORTREVISION= 2
CATEGORIES= chinese x11
MASTER_SITES= ftp://xcin.linux.org.tw/pub/xcin/xcin/ \
ftp://xcin.linux.org.tw/pub/xcin/xcin/devel/ \
http://chewing.good-man.org/snapshot/
DISTNAME= ${PORTNAME}-${PORTVERSION:S/p/pre/}
DISTFILES= ${DISTNAME}${EXTRACT_SUFX} chewing-2002Jan07-snapshot.tar.gz

MAINTAINER= kcwu@ck.tp.edu.tw
COMMENT= Chinese input method server under X

LIB_DEPENDS= tabe.2:${PORTSDIR}/chinese/libtabe \
intl.4:${PORTSDIR}/devel/gettext \
iconv.3:${PORTSDIR}/converters/libiconv
.if !defined(USE_DB2)
LIB_DEPENDS+= db3.3:${PORTSDIR}/databases/db3
.else
LIB_DEPENDS+= db2.0:${PORTSDIR}/databases/db2
.endif
RUN_DEPENDS= ${X11BASE}/lib/X11/fonts/local/kc15f.pcf.gz:${PORTSDIR}/chinese/
kcfonts \
${LOCALBASE}/share/tabe/libtabe-0.2.5:${PORTSDIR}/chinese/libtabe

WRKSRC= ${WRKDIR}/xcin
USE_X_PREFIX= yes
GNU_CONFIGURE= yes
INSTALLS_SHLIB= yes
CONFIGURE_ARGS= --prefix=${PREFIX} \
--x-libraries=${X11BASE}/lib \
--with-xcin-dir=${PREFIX}/lib/X11/xcin25 \
--with-db-lib=${LOCALBASE}/lib \
--with-tabe-inc=${LOCALBASE}/include/tabe \
--with-tabe-lib=${LOCALBASE}/lib \
--with-intl-inc=${LOCALBASE}/include \
--with-intl-lib=${LOCALBASE}/lib \
--with-iconv-inc=${LOCALBASE}/include \
--with-iconv-lib=${LOCALBASE}/lib

.if !defined(USE_DB2)
CONFIGURE_ARGS+= --with-db-inc=${LOCALBASE}/include/db3
.else
CONFIGURE_ARGS+= --with-db-inc=${LOCALBASE}/include/db2
.endif

MAN1= xcin.1

pre-fetch:
.if !defined(USE_DB2)
@${ECHO} --
@${ECHO} "Type \"make -DUSE_DB2\" if you want use DB2."
@${ECHO} "Otherwise, xcin2.5 will use DB3."
@${ECHO} --
.endif

post-extract:
${MV} ${WRKDIR}/chewing ${WRKSRC}/src/Cinput

post-patch:
@cd ${WRKSRC}/src/Cinput/chewing; ${SH} ./patch_chewing

post-install:
.if !defined(NOPORTDOCS)
${MKDIR} ${PREFIX}/lib/X11/xcin25/doc
.for DOC in Bugs COPYING CREDITS Changes Cin CopyRight FAQ README \
SETUP Todo Usage UserGuide
${INSTALL_DATA} ${WRKSRC}/doc/${DOC} ${PREFIX}/lib/X11/xcin25/doc
.endfor
${MKDIR} ${PREFIX}/lib/X11/xcin25/doc/En
${MKDIR} ${PREFIX}/lib/X11/xcin25/doc/En/internal
.for En in README.En SETUP.En Usage.En UserGuide.En
${INSTALL_DATA} ${WRKSRC}/doc/En/${En} ${PREFIX}/lib/X11/xcin25/doc/En
.endfor
.for Eninternal in module.En structer.En
${INSTALL_DATA} ${WRKSRC}/doc/En/internal/${Eninternal} ${PREFIX}/lib/X1
1/xcin25/doc/En/internal
.endfor
${MKDIR} ${PREFIX}/lib/X11/xcin25/doc/history
${INSTALL_DATA} ${WRKSRC}/doc/history/Changes-19991011 \
${PREFIX}/lib/X11/xcin25/doc/history
${MKDIR} ${PREFIX}/lib/X11/xcin25/doc/internal
.for INTERNAL in IMdkit gen_inp gui_request module structer
${INSTALL_DATA} ${WRKSRC}/doc/internal/${INTERNAL} \
${PREFIX}/lib/X11/xcin25/doc/internal
.endfor
${MKDIR} ${PREFIX}/lib/X11/xcin25/doc/modules
.for MODULES in bimsphone gen_inp im_comm zh_hex
${INSTALL_DATA} ${WRKSRC}/doc/modules/${MODULES} \
${PREFIX}/lib/X11/xcin25/doc/modules
.endfor
.endif

.include

再談什麼是Makefile , /usr/ports/Mk/之前必須先理解:什麼module的概念,什麼是include的概念
在程式開發時,可以採用module的作法,把常用的function寫成module,以後需要用到時再把module
include進來
理解了什麼是module , include之後,再來看/usr/ports/Mk/
damon[/usr/ports/Mk]-damon->ls
bsd.emacs.mk bsd.kde.mk bsd.port.pre.mk bsd.ruby.mk
bsd.gnome.mk bsd.port.mk bsd.port.subdir.mk bsd.sites.mk
bsd.java.mk bsd.port.post.mk bsd.python.mk
這裡可以看到core team已經為幾個主要的ports分別建立了在編譯時所需要用的參數,可以用module
的觀念來理解這些mk檔的用途

這裡只對bsd.port.mk做部分解讀,其餘觀念相同
#-*- mode: makefile; tab-width: 4; -*-
# ex:ts=4
#
# $FreeBSD: ports/Mk/bsd.port.mk,v 1.447 2003/04/19 22:35:28 kris Exp $
# $NetBSD: $
#
# bsd.port.mk - 940820 Jordan K. Hubbard.
# This file is in the public domain.
#
# Please view me with 4 column tabs!

# This is the master file for the most common elements to all port
# Makefile in the ports system. For a more general overview of its
# use and importance, see the Porter's Handbook.

# There are two different types of "maintainers" in the ports framework.
# The maintainer alias of the bsd.port.mk file is listed below in the
# FreeBSD_MAINTAINER entry. You should consult them if you have any
# questions/suggestions regarding this file.
#
# DO NOT COMMIT CHANGES TO THIS FILE BY YOURSELF, EVEN IF YOU DID NOT GET
# A RESPONSE FROM THE MAINTAINER(S) WITHIN A REASONABLE TIMEFRAME! ALL
# UNAUTHORISED CHANGES WILL BE UNCONDITIONALLY REVERTED!
FreeBSD_MAINTAINER= portmgr@FreeBSD.org

# For each port, the MAINTAINER variable is what you should consult for
# contact information on the person(s) to contact if you have questions/
# suggestions about that specific port. By default (if no MAINTAINER
# is listed), a port is maintained by the subscribers of the ports@FreeBSD.org
# mailing list, and any correspondence should be directed there.
#
# MAINTAINER - The e-mail address of the contact person for this port
# (default: ports@FreeBSD.org).
#
# These are meta-variables that are automatically set to the system
# you are running on. These are provided in case you need to take
# different actions for different values.
#
# ARCH - The architecture, as returned by "uname -p".
# OPSYS - Portability clause. This is the operating system the
# makefile is being used on. Automatically set to
# "FreeBSD," "NetBSD," or "OpenBSD" as appropriate.
# OSREL - The release version (numeric) of the operating system.
# OSVERSION - The value of __FreeBSD_version.
# PORTOBJFORMAT - The object format ("aout" or "elf").
#
# This is the beginning of the list of all variables that need to be
# defined in a port, listed in order that they should be included
# to fit in with existing conventions. (Exception: MAINTAINER actually
# should appear after EXTRACT_ONLY and before MASTER_SITE_BACKUP).
#
# These variables are used to identify your port.
#
# PORTNAME - Name of software. Mandatory.
# PORTVERSION - Version of software. Mandatory.
# PORTREVISION - Version of port. Optional. Commonly used to indicate
# that an update has happened that affects the port
# framework itself, but not the distributed software
# (e.g., local patches or Makefile changes).
# PORTEPOCH - Optional. In certain odd cases, the PORTREVISION logic
# can be fooled by ports that appear to go backwards
# numerically (e.g. if port-0.3 is newer than port-1998).
# In this case, incrementing PORTEPOCH forces the revision.
# Default: 0 (no effect).
# PKGNAMEPREFIX - Prefix to specify that port is language-specific, etc.
# Optional.
# PKGNAMESUFFIX - Suffix to specify compilation options. Optional.
# PKGNAME - Always defined as
# ${PKGNAMEPREFIX}${PORTNAME}${PKGNAMESUFFIX}-${PORTVERSION}.
# Do not define this in your Makefile.
# DISTNAME - Name of port or distribution used in generating
# WRKSRC and DISTFILES below (default:
# ${PORTNAME}-${PORTVERSION}).
# CATEGORIES - A list of descriptive categories into which this port falls.
# Mandatory.
#
# These variable describe how to fetch files required for building the port.
#
# DISTFILES - Name(s) of archive file(s) containing distribution
# (default: ${DISTNAME}${EXTRACT_SUFX}). Set this to
# an empty string if the port doesn't require it.
# EXTRACT_SUFX - Suffix for archive names (default: .tar.bz2 if USE_BZIP2
# is set, .zip if USE_ZIP is set, .tar.gz otherwise).
# You never have to set both DISTFILES and EXTRACT_SUFX.
# MASTER_SITES - Primary location(s) for distribution files if not found
# locally. See bsd.sites.mk for common choices for
# MASTER_SITES.
# MASTER_SITE_SUBDIR - Subdirectory of MASTER_SITES (default: empty).
# Will sometimes need to be set to ${PORTNAME} for (e.g.)
# MASTER_SITE_SOURCEFORGE. Only guaranteed to work for
# choices of ${MASTER_SITES} defined in bsd.sites.mk.
# PATCHFILES - Name(s) of additional files that contain distribution
# patches (default: none). make will look for them at
# PATCH_SITES (see below). They will automatically be
# uncompressed before patching if the names end with
這邊可以發現,core team為每個可以用在Makefile中的指令都做了簡單的說明,詳細看完這些說明的話
更能夠理解為什麼FreeBSD能做到每次安裝完的軟體,設定檔、執行檔該放哪裡就是放哪裡,man page該放
在哪一個部分就是在哪個部分,怎麼讓ports安裝的軟體也做到,這些都定義在/usr/ports/Mk/中的這些
設定檔,尤其是LOCALBASE , X11BASE這類的參數,每個port maintainer在做port時都必須按照這些規範
來放安裝之後的檔案

前面都是為這些指令做說明,再來看相對應的動作的部分
# Start of pre-makefile section.
.if !defined(AFTERPORTMK)

.if defined(_PREMKINCLUDED)
.BEGIN:
@${ECHO_CMD} "${PKGNAME}: You cannot include bsd.port[.pre].mk twice"
@${FALSE}
.endif

_PREMKINCLUDED= yes

AWK?= /usr/bin/awk
BASENAME?= /usr/bin/basename
.if exists(/usr/bin/bzip2)
BZCAT?= /usr/bin/bzcat
BZIP2_CMD?= /usr/bin/bzip2
.else
BZCAT?= ${LOCALBASE}/bin/bzcat
BZIP2_CMD?= ${LOCALBASE}/bin/bzip2
BZIP2DEPENDS= yes
.endif
CAT?= /bin/cat
CHGRP?= /usr/bin/chgrp
CHMOD?= /bin/chmod
CHOWN?= /usr/sbin/chown
CP?= /bin/cp
CUT?= /usr/bin/cut
DC?= /usr/bin/dc
EGREP?= /usr/bin/egrep
EXPR?= /bin/expr
FALSE?= false # Shell builtin
FILE?= /usr/bin/file
FIND?= /usr/bin/find
GREP?= /usr/bin/grep
GUNZIP_CMD?= /usr/bin/gunzip -f
GZCAT?= /usr/bin/gzcat
GZIP?= -9
GZIP_CMD?= /usr/bin/gzip -nf ${GZIP}
HEAD?= /usr/bin/head
ID?= /usr/bin/id
IDENT?= /usr/bin/ident
LDCONFIG?= /sbin/ldconfig
LN?= /bin/ln
這邊定義了每個所需要的指令放的絕對位置

# ECHO is defined in /usr/share/mk/sys.mk, which can either be "echo",
# or "true" if the make flag -s is given. Use ECHO_CMD where you mean
# the echo command.
ECHO_CMD?= echo # Shell builtin

# Used to print all the '===>' style prompts - override this to turn them off.
ECHO_MSG?= ${ECHO_CMD}

# Get the architecture
.if !defined(ARCH)
ARCH!= ${UNAME} -p
.endif

# Kludge for pre-3.0 systems
MACHINE_ARCH?= i386

# Get the operating system type
.if !defined(OPSYS)
OPSYS!= ${UNAME} -s
.endif
這裡定義了前面說明的地方提到的每一個能夠利用在Makefile中的指令所相對應的動作,對於shell
script有研究的話更容易理解這些變數(都是大寫的那些字串)的傳遞,就不多做說明,但需要絕對
注意的是:除非知道自己在幹嘛,否則絕對不要任意修改/usr/ports/Mk/裡面的設定檔

這時再回過頭來看Makefile,可以發現,其實就是實際再利用bsd.port.mk裡面所先定義好的參數與
function來告訴compiler做什麼動作,這也是就為什麼每個port maintainer寫的Makefile都會有一行
.include
當然有需要的話會include其他的mk檔
這時就可以很簡單的理解ports怎麼解決相依性的問題以及自動安裝所需要的有相依性的軟體了,答案
很簡單,就靠BUILD_DEPENDS , RUN_DEPENDS , LIB_DEPENDS這幾個與相依性有關係的指令,至於這些
指令之間的差異,就不再多做說明,bsd.port.mk裡面說的很詳細了
而由誰來確定這些相依性呢?port maintainer會先確定相依性之後加入這些參數,而committet ,
port maintainer都會實際測試過沒問題之後才會submit到ports tree裡面讓大家透過cvsup來更新


port的參數
前面可以看到,在/usr/ports/xxxx/yyyy/Makefile裡面定義了所有的安裝參數,通常port maintainer
都會做好了選項,如
.if !defined(USE_DB2)
LIB_DEPENDS+= db3.3:${PORTSDIR}/databases/db3
.else
LIB_DEPENDS+= db2.0:${PORTSDIR}/databases/db2
.endif
.if !defined(USE_DB2)
@${ECHO} --
@${ECHO} "Type \"make -DUSE_DB2\" if you want use DB2."
@${ECHO} "Otherwise, xcin2.5 will use DB3."
@${ECHO} --
.endif
這類的訊息來告訴使用者,這個port有什麼選項可以使用,這時候
cd /usr/ports/chinese/xcin25/
make install clean
就會看到
Type \"make -DUSE_DB2\" if you want use DB2.
Otherwise, xcin2.5 will use DB3.
這樣的訊息,如果有多個時候會出現多個,或是如mod_php4實在太多的話,port maintainer甚至會
做一個簡單的選單來讓使用者選擇需要加入哪些參數,再透過if來判斷加入哪些需要的相依性
如果有缺少自己想要的參數,要自己加入也可以加在
CONFIGURE_ARGS= --prefix=${PREFIX} \
--x-libraries=${X11BASE}/lib \
--with-xcin-dir=${PREFIX}/lib/X11/xcin25 \
--with-db-lib=${LOCALBASE}/lib \
--with-tabe-inc=${LOCALBASE}/include/tabe \
--with-tabe-lib=${LOCALBASE}/lib \
--with-intl-inc=${LOCALBASE}/include \
--with-intl-lib=${LOCALBASE}/lib \
--with-iconv-inc=${LOCALBASE}/include \
--with-iconv-lib=${LOCALBASE}/lib
這邊自己手動加入,不過很少有需要自己手動調整參數的狀況
有需要加入自己特殊的patch的話,可以放在files/裡面,在修改Makefile來加入這些patch
這些都是簡單的方法來保持ports安裝的軟體的彈性,但同時,如果不想要了,也可以簡單的移除不需要的
軟體

一些其他的利用
在bsd.port.mk中可以發現,ports對於make install這個動作,預設就是只有安裝上去,而對於有相依性的
軟體也只是安裝上去而已,這時候如果說我管理了十台機器,十台機器都想安裝同樣的軟體時,分別到十台
機器上下cd /usr/ports/xxxx/yyyy/ ; make install clean很浪費時間
這時候可以在其他一台cpu速度比較快的機器上建立好package,其他機器只要用pkg_add指令就可以完成安裝
了,在bsd.port.mk中定義了,如果要做成package時,如果沒有找到/usr/ports/packages/的話就放在
/usr/ports/xxxx/yyyy/中,而發現DEPENDS_TARGET預設都是install,又發現package這個參數可以包成package
於是,最簡單的解決方法就是
cd /usr/ports/
mkdir packages
cd /usr/ports/xxxx/yyyy
make DEPENDS_TARGET=package package clean
等這台編譯完成之後,到/usr/ports/packages/All/驗收剛剛編譯好的package
也許這也是每次有新的release推出時,製作package的方法,不過我不確定