aboutsummaryrefslogtreecommitdiff
path: root/zh_TW.UTF-8/books
diff options
context:
space:
mode:
authorLi-Wen Hsu <lwhsu@FreeBSD.org>2014-05-29 16:48:07 +0000
committerLi-Wen Hsu <lwhsu@FreeBSD.org>2014-05-29 16:48:07 +0000
commit163ba6b752e2d1b900f88ba29324ed5998b14551 (patch)
tree3010592efec60252103b5e76eab918b0491bb533 /zh_TW.UTF-8/books
parent536050cea8f16998f8fbddf6b4aff8469e149ec0 (diff)
downloaddoc-163ba6b752e2d1b900f88ba29324ed5998b14551.tar.gz
doc-163ba6b752e2d1b900f88ba29324ed5998b14551.zip
Convert zh_TW from Big5 to UTF-8.
Approved by: bcr
Notes
Notes: svn path=/head/; revision=44974
Diffstat (limited to 'zh_TW.UTF-8/books')
-rw-r--r--zh_TW.UTF-8/books/Makefile13
-rw-r--r--zh_TW.UTF-8/books/Makefile.inc5
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/Makefile42
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/book.xml183
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/chapters.ent33
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/introduction/chapter.xml186
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/ipv6/chapter.xml1571
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/kerneldebug/Makefile15
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/kerneldebug/chapter.xml848
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/l10n/chapter.xml75
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/policies/Makefile15
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/policies/chapter.xml402
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/secure/chapter.xml518
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/sockets/chapter.xml1780
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/testing/chapter.xml212
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/tools/chapter.xml2139
-rw-r--r--zh_TW.UTF-8/books/developers-handbook/x86/chapter.xml6486
-rw-r--r--zh_TW.UTF-8/books/faq/Makefile27
-rw-r--r--zh_TW.UTF-8/books/faq/book.xml11876
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/Makefile51
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/book.xml234
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/chapters.ent27
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/doc-build/chapter.xml486
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/examples/appendix.xml336
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/overview/chapter.xml241
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/psgml-mode/chapter.xml165
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/see-also/chapter.xml122
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/sgml-markup/chapter.xml2682
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/sgml-primer/chapter.xml1543
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/structure/chapter.xml281
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/stylesheets/chapter.xml92
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/the-website/chapter.xml191
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/tools/chapter.xml235
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/translations/chapter.xml383
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/writing-style/chapter.xml440
-rw-r--r--zh_TW.UTF-8/books/handbook/Makefile269
-rw-r--r--zh_TW.UTF-8/books/handbook/advanced-networking/Makefile16
-rw-r--r--zh_TW.UTF-8/books/handbook/advanced-networking/chapter.xml5438
-rw-r--r--zh_TW.UTF-8/books/handbook/audit/Makefile16
-rw-r--r--zh_TW.UTF-8/books/handbook/audit/chapter.xml567
-rw-r--r--zh_TW.UTF-8/books/handbook/basics/Makefile16
-rw-r--r--zh_TW.UTF-8/books/handbook/basics/chapter.xml2366
-rw-r--r--zh_TW.UTF-8/books/handbook/basics/example-dir1.dot7
-rw-r--r--zh_TW.UTF-8/books/handbook/basics/example-dir2.dot8
-rw-r--r--zh_TW.UTF-8/books/handbook/basics/example-dir3.dot8
-rw-r--r--zh_TW.UTF-8/books/handbook/basics/example-dir4.dot9
-rw-r--r--zh_TW.UTF-8/books/handbook/basics/example-dir5.dot9
-rw-r--r--zh_TW.UTF-8/books/handbook/bibliography/Makefile16
-rw-r--r--zh_TW.UTF-8/books/handbook/bibliography/chapter.xml630
-rw-r--r--zh_TW.UTF-8/books/handbook/book.xml274
-rw-r--r--zh_TW.UTF-8/books/handbook/boot/Makefile16
-rw-r--r--zh_TW.UTF-8/books/handbook/boot/chapter.xml802
-rw-r--r--zh_TW.UTF-8/books/handbook/chapters.ent71
-rw-r--r--zh_TW.UTF-8/books/handbook/colophon.xml21
-rw-r--r--zh_TW.UTF-8/books/handbook/config/Makefile16
-rw-r--r--zh_TW.UTF-8/books/handbook/config/chapter.xml3095
-rw-r--r--zh_TW.UTF-8/books/handbook/cutting-edge/Makefile16
-rw-r--r--zh_TW.UTF-8/books/handbook/cutting-edge/chapter.xml1535
-rw-r--r--zh_TW.UTF-8/books/handbook/desktop/Makefile16
-rw-r--r--zh_TW.UTF-8/books/handbook/desktop/chapter.xml1037
-rw-r--r--zh_TW.UTF-8/books/handbook/disks/Makefile16
-rw-r--r--zh_TW.UTF-8/books/handbook/disks/chapter.xml3849
-rw-r--r--zh_TW.UTF-8/books/handbook/eresources/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/eresources/chapter.xml1676
-rw-r--r--zh_TW.UTF-8/books/handbook/firewalls/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/firewalls/chapter.xml3260
-rw-r--r--zh_TW.UTF-8/books/handbook/geom/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/geom/chapter.xml356
-rw-r--r--zh_TW.UTF-8/books/handbook/install/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/install/chapter.xml4503
-rw-r--r--zh_TW.UTF-8/books/handbook/install/example-dir1.dot7
-rw-r--r--zh_TW.UTF-8/books/handbook/install/example-dir2.dot8
-rw-r--r--zh_TW.UTF-8/books/handbook/install/example-dir3.dot8
-rw-r--r--zh_TW.UTF-8/books/handbook/install/example-dir4.dot9
-rw-r--r--zh_TW.UTF-8/books/handbook/install/example-dir5.dot9
-rw-r--r--zh_TW.UTF-8/books/handbook/introduction/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/introduction/chapter.xml842
-rw-r--r--zh_TW.UTF-8/books/handbook/jails/chapter.xml793
-rw-r--r--zh_TW.UTF-8/books/handbook/kernelconfig/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/kernelconfig/chapter.xml1387
-rw-r--r--zh_TW.UTF-8/books/handbook/l10n/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/l10n/chapter.xml884
-rw-r--r--zh_TW.UTF-8/books/handbook/linuxemu/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/linuxemu/chapter.xml3281
-rw-r--r--zh_TW.UTF-8/books/handbook/mac/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/mac/chapter.xml2274
-rw-r--r--zh_TW.UTF-8/books/handbook/mail/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/mail/chapter.xml2227
-rw-r--r--zh_TW.UTF-8/books/handbook/mirrors/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/mirrors/chapter.xml3190
-rw-r--r--zh_TW.UTF-8/books/handbook/multimedia/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/multimedia/chapter.xml1741
-rw-r--r--zh_TW.UTF-8/books/handbook/network-servers/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/network-servers/chapter.xml5074
-rw-r--r--zh_TW.UTF-8/books/handbook/pgpkeys/Makefile18
-rw-r--r--zh_TW.UTF-8/books/handbook/pgpkeys/chapter.xml41
-rw-r--r--zh_TW.UTF-8/books/handbook/ports/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/ports/chapter.xml1300
-rw-r--r--zh_TW.UTF-8/books/handbook/ppp-and-slip/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/ppp-and-slip/chapter.xml3116
-rw-r--r--zh_TW.UTF-8/books/handbook/preface/preface.xml510
-rw-r--r--zh_TW.UTF-8/books/handbook/printing/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/printing/chapter.xml4737
-rw-r--r--zh_TW.UTF-8/books/handbook/security/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/security/chapter.xml4992
-rw-r--r--zh_TW.UTF-8/books/handbook/serialcomms/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/serialcomms/chapter.xml2856
-rw-r--r--zh_TW.UTF-8/books/handbook/txtfiles.ent72
-rw-r--r--zh_TW.UTF-8/books/handbook/users/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/users/chapter.xml940
-rw-r--r--zh_TW.UTF-8/books/handbook/vinum/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/vinum/chapter.xml1458
-rw-r--r--zh_TW.UTF-8/books/handbook/virtualization/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/virtualization/chapter.xml886
-rw-r--r--zh_TW.UTF-8/books/handbook/x11/Makefile15
-rw-r--r--zh_TW.UTF-8/books/handbook/x11/chapter.xml1516
-rw-r--r--zh_TW.UTF-8/books/porters-handbook/Makefile39
-rw-r--r--zh_TW.UTF-8/books/porters-handbook/book.xml12963
118 files changed, 121377 insertions, 0 deletions
diff --git a/zh_TW.UTF-8/books/Makefile b/zh_TW.UTF-8/books/Makefile
new file mode 100644
index 0000000000..176ffedb82
--- /dev/null
+++ b/zh_TW.UTF-8/books/Makefile
@@ -0,0 +1,13 @@
+# $FreeBSD$
+
+SUBDIR = developers-handbook
+#SUBDIR+= faq
+SUBDIR+= fdp-primer
+SUBDIR+= handbook
+SUBDIR+= porters-handbook
+#SUBDIR+= zh-tut
+
+ROOT_SYMLINKS = faq fdp-primer handbook porters-handbook
+
+DOC_PREFIX?= ${.CURDIR}/../..
+.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/books/Makefile.inc b/zh_TW.UTF-8/books/Makefile.inc
new file mode 100644
index 0000000000..dd9acff37a
--- /dev/null
+++ b/zh_TW.UTF-8/books/Makefile.inc
@@ -0,0 +1,5 @@
+#
+# $FreeBSD$
+#
+
+DESTDIR?= ${DOCDIR}/zh_TW.UTF-8/books/${.CURDIR:T}
diff --git a/zh_TW.UTF-8/books/developers-handbook/Makefile b/zh_TW.UTF-8/books/developers-handbook/Makefile
new file mode 100644
index 0000000000..81fed7b836
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/Makefile
@@ -0,0 +1,42 @@
+#
+# $FreeBSD$
+#
+# Build the FreeBSD Developers' Handbook.
+#
+
+MAINTAINER=doc@FreeBSD.org
+
+DOC?= book
+
+FORMATS?= html-split
+
+INSTALL_COMPRESSED?= gz
+INSTALL_ONLY_COMPRESSED?=
+
+# Images
+IMAGES_EN= sockets/layers.eps sockets/sain.eps sockets/sainfill.eps sockets/sainlsb.eps sockets/sainmsb.eps sockets/sainserv.eps sockets/serv.eps sockets/serv2.eps sockets/slayers.eps
+
+#
+# SRCS lists the individual XML files that make up the document. Changes
+# to any of these files will force a rebuild
+#
+
+# XML content
+SRCS= book.xml
+SRCS+= introduction/chapter.xml
+SRCS+= ipv6/chapter.xml
+SRCS+= kerneldebug/chapter.xml
+SRCS+= l10n/chapter.xml
+SRCS+= policies/chapter.xml
+SRCS+= secure/chapter.xml
+SRCS+= sockets/chapter.xml
+SRCS+= testing/chapter.xml
+SRCS+= tools/chapter.xml
+SRCS+= x86/chapter.xml
+
+# Entities
+
+URL_RELPREFIX?= ../../../..
+DOC_PREFIX?= ${.CURDIR}/../../..
+
+.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/books/developers-handbook/book.xml b/zh_TW.UTF-8/books/developers-handbook/book.xml
new file mode 100644
index 0000000000..6b48de373f
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/book.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
+ "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd" [
+<!ENTITY % chapters SYSTEM "chapters.ent"> %chapters;
+]>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.52
+-->
+<book xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="zh_tw">
+ <info><title>FreeBSD Developers' Handbook</title>
+
+
+ <author><orgname>FreeBSD 文件計畫</orgname></author>
+
+ <pubdate>August 2000</pubdate>
+
+ <copyright>
+ <year>2000</year>
+ <year>2001</year>
+ <year>2002</year>
+ <year>2003</year>
+ <year>2004</year>
+ <year>2005</year>
+ <year>2006</year>
+ <year>2007</year>
+ <holder>The FreeBSD Documentation Project</holder>
+ </copyright>
+
+ &legalnotice;
+
+ <legalnotice xml:id="trademarks" role="trademarks">
+ &tm-attrib.freebsd;
+ &tm-attrib.apple;
+ &tm-attrib.ibm;
+ &tm-attrib.ieee;
+ &tm-attrib.intel;
+ &tm-attrib.linux;
+ &tm-attrib.microsoft;
+ &tm-attrib.opengroup;
+ &tm-attrib.sun;
+ &tm-attrib.general;
+ </legalnotice>
+
+ <releaseinfo>$FreeBSD$</releaseinfo>
+
+ <abstract>
+ <para>
+ 歡迎使用 Developers' Handbook!
+ 這份文件是由許多人 <emphasis>不斷撰寫</emphasis> 而成的,
+ 而且許多章節仍需更新或者內容還是一片空白,
+ 如果你想幫忙 FreeBSD 文件計劃,
+ 請寄信到 &a.doc;。
+ </para>
+
+ <para>
+ 最新版的文件都在 <link xlink:href="&url.base;/index.html">FreeBSD 官網</link> 上面,
+ 也可從 <link xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/">FreeBSD FTP server</link> 下載不同格式的資料。
+ 當然也可以在其他的 <link xlink:href="&url.books.handbook;/mirrors-ftp.html">mirror站</link>下載。
+ </para>
+
+ </abstract>
+ </info>
+
+ <part xml:id="Basics">
+ <title>基本概念</title>
+
+ &chap.introduction;
+ &chap.tools;
+ &chap.secure;
+ &chap.l10n;
+ &chap.policies;
+ &chap.testing;
+ </part>
+
+ <part xml:id="ipc">
+ <title>Interprocess Communication(IPC)</title>
+
+ &chap.sockets;
+ &chap.ipv6;
+
+ </part>
+
+ <part xml:id="kernel">
+ <title>Kernel(核心)</title>
+
+ &chap.kerneldebug;
+
+ </part>
+
+ <part xml:id="architectures">
+ <title>Architectures(電腦架構)</title>
+
+ &chap.x86;
+
+ </part>
+
+ <part xml:id="appendices">
+ <title>附錄</title>
+
+ <bibliography>
+
+ <biblioentry xml:id="COD" xreflabel="1">
+ <authorgroup>
+ <author><personname><firstname>Dave</firstname><othername role="MI">A</othername><surname>Patterson</surname></personname></author>
+ <author><personname><firstname>John</firstname><othername role="MI">L</othername><surname>Hennessy</surname></personname></author>
+ </authorgroup>
+ <copyright><year>1998</year><holder>Morgan Kaufmann Publishers,
+ Inc.</holder></copyright>
+ <biblioid class="isbn">1-55860-428-6</biblioid>
+ <publisher>
+ <publishername>Morgan Kaufmann Publishers, Inc.</publishername>
+ </publisher>
+ <citetitle>Computer Organization and Design</citetitle>
+ <subtitle>The Hardware / Software Interface</subtitle>
+ <pagenums>1-2</pagenums>
+ </biblioentry>
+
+ <biblioentry xreflabel="2">
+ <authorgroup>
+ <author><personname><firstname>W.</firstname><othername role="Middle">Richard</othername><surname>Stevens</surname></personname></author>
+ </authorgroup>
+ <copyright><year>1993</year><holder>Addison Wesley Longman,
+ Inc.</holder></copyright>
+ <biblioid class="isbn">0-201-56317-7</biblioid>
+ <publisher>
+ <publishername>Addison Wesley Longman, Inc.</publishername>
+ </publisher>
+ <citetitle>Advanced Programming in the Unix Environment</citetitle>
+ <pagenums>1-2</pagenums>
+ </biblioentry>
+
+ <biblioentry xreflabel="3">
+ <authorgroup>
+ <author><personname><firstname>Marshall</firstname><othername role="Middle">Kirk</othername><surname>McKusick</surname></personname></author>
+ <author><personname><firstname>Keith</firstname><surname>Bostic</surname></personname></author>
+ <author><personname><firstname>Michael</firstname><othername role="MI">J</othername><surname>Karels</surname></personname></author>
+ <author><personname><firstname>John</firstname><othername role="MI">S</othername><surname>Quarterman</surname></personname></author>
+ </authorgroup>
+ <copyright><year>1996</year><holder>Addison-Wesley Publishing Company,
+ Inc.</holder></copyright>
+ <biblioid class="isbn">0-201-54979-4</biblioid>
+ <publisher>
+ <publishername>Addison-Wesley Publishing Company, Inc.</publishername>
+ </publisher>
+ <citetitle>The Design and Implementation of the 4.4 BSD Operating System</citetitle>
+ <pagenums>1-2</pagenums>
+ </biblioentry>
+
+ <biblioentry xml:id="Phrack" xreflabel="4">
+ <authorgroup>
+ <author><personname><firstname>Aleph</firstname><surname>One</surname></personname></author>
+ </authorgroup>
+ <citetitle>Phrack 49; "Smashing the Stack for Fun and Profit"</citetitle>
+ </biblioentry>
+
+ <biblioentry xml:id="StackGuard" xreflabel="5">
+ <authorgroup>
+ <author><personname><firstname>Chrispin</firstname><surname>Cowan</surname></personname></author>
+ <author><personname><firstname>Calton</firstname><surname>Pu</surname></personname></author>
+ <author><personname><firstname>Dave</firstname><surname>Maier</surname></personname></author>
+ </authorgroup>
+ <citetitle>StackGuard; Automatic Adaptive Detection and Prevention of
+ Buffer-Overflow Attacks</citetitle>
+ </biblioentry>
+
+ <biblioentry xml:id="OpenBSD" xreflabel="6">
+ <authorgroup>
+ <author><personname><firstname>Todd</firstname><surname>Miller</surname></personname></author>
+ <author><personname><firstname>Theo</firstname><surname>de Raadt</surname></personname></author>
+ </authorgroup>
+ <citetitle>strlcpy and strlcat -- consistent, safe string copy and
+ concatenation.</citetitle>
+ </biblioentry>
+
+ </bibliography>
+
+ &chap.index;
+ </part>
+
+</book>
diff --git a/zh_TW.UTF-8/books/developers-handbook/chapters.ent b/zh_TW.UTF-8/books/developers-handbook/chapters.ent
new file mode 100644
index 0000000000..481ce9a436
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/chapters.ent
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Creates entities for each chapter in the FreeBSD Developer's
+ Handbook. Each entity is named chap.foo, where foo is the value
+ of the id attribute on that chapter, and corresponds to the name of
+ the directory in which that chapter's .xml file is stored.
+
+ Chapters should be listed in the order in which they are referenced.
+
+ $FreeBSD$
+-->
+
+<!-- Part one -->
+<!ENTITY chap.introduction SYSTEM "introduction/chapter.xml">
+<!ENTITY chap.tools SYSTEM "tools/chapter.xml">
+<!ENTITY chap.secure SYSTEM "secure/chapter.xml">
+<!ENTITY chap.l10n SYSTEM "l10n/chapter.xml">
+<!ENTITY chap.policies SYSTEM "policies/chapter.xml">
+<!ENTITY chap.testing SYSTEM "testing/chapter.xml">
+
+<!-- Part two - IPC -->
+<!ENTITY chap.sockets SYSTEM "sockets/chapter.xml">
+<!ENTITY chap.ipv6 SYSTEM "ipv6/chapter.xml">
+
+<!-- Part three - Kernel -->
+<!ENTITY chap.dma SYSTEM "dma/chapter.xml">
+<!ENTITY chap.kerneldebug SYSTEM "kerneldebug/chapter.xml">
+
+<!-- Part five - Architectures -->
+<!ENTITY chap.x86 SYSTEM "x86/chapter.xml">
+
+<!-- Part six - Appendices -->
+<!ENTITY chap.index "<index xmlns='http://docbook.org/ns/docbook'/>">
diff --git a/zh_TW.UTF-8/books/developers-handbook/introduction/chapter.xml b/zh_TW.UTF-8/books/developers-handbook/introduction/chapter.xml
new file mode 100644
index 0000000000..636eff06d5
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/introduction/chapter.xml
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.18
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="introduction">
+ <info><title>簡介</title>
+ <authorgroup>
+ <author><personname><firstname>Murray</firstname><surname>Stokely</surname></personname><contrib>Contributed by </contrib></author>
+ <author><personname><firstname>Jeroen</firstname><surname>Ruigrok van der Werven</surname></personname></author>
+ </authorgroup>
+ </info>
+
+
+ <sect1 xml:id="introduction-devel">
+ <title>在 FreeBSD 開發程式</title>
+ <para>好了我們開始吧!我想你的 FreeBSD 已經安裝好了,而且已經準備好要用它寫點程式了吧?
+ 但是要從哪裡開始呢?&os; 有提供寫程式的程式或環境嗎?
+ 身為 programer 的我可以做什麼呢?</para>
+
+ <para>本章試著回答你一些問題,當然,單就 programming 程度來說可分很多種層次,
+ 有的人只是單純當興趣,有的則是他的專業,
+ 本章主要內容是針對程式初學者,
+ 當然,對於那些不熟 &os; 的程式開發者而言,本文件內容也是十分實用的。</para>
+ </sect1>
+
+ <sect1 xml:id="introduction-bsdvision">
+ <title>The BSD Vision</title>
+
+ <para>為了讓你寫出來的程式在 &unix; like系統上具有良好的使用性、效能和穩定性,
+ 我們必須跟你介紹一些程式概念(original software tools ideology)。 </para>
+ </sect1>
+
+ <sect1 xml:id="introduction-archguide">
+ <title>程式架構指南</title>
+
+ <para>我們想介紹的概念如下</para>
+
+ <itemizedlist>
+
+ <listitem><para>在整個程式還沒寫完前,不要增加新的功能。</para></listitem>
+
+ <listitem><para>另外一個重點就是,讓你自己選擇你的程式將會具有何種功能,
+ 而不是讓別人決定,不想要去滿足全世界的需求,除非你想讓你的程式具有擴充性或相容性。</para></listitem>
+
+ <listitem><para>千萬記住:在沒有相關經驗時,參考範例程式碼所寫出來的程式,
+ 會比自己憑空寫出來的好。</para></listitem>
+
+ <listitem><para>當你寫的程式沒辦法完全解決問題時,最好的方法就是不要試著要去解決它。</para></listitem>
+
+ <listitem><para>若用 10% 的心力就能輕鬆完成 90% 的工作份量,就用這個簡單法子吧。</para></listitem>
+
+ <listitem><para>盡可能地簡化問題的複雜。</para></listitem>
+
+ <listitem><para>提供機制(mechanism),而非原則(policy)。
+ 比方說,把使用者介面選擇權交由使用者來決定。</para></listitem>
+
+ </itemizedlist>
+
+ <para>以上摘自 Scheifler &amp; Gettys 的 "X Window System" 論文</para>
+
+ </sect1>
+
+ <sect1 xml:id="introduction-layout">
+ <title><filename>/usr/src</filename> 的架構</title>
+
+ <para>完整的 FreeBSD 原始碼都在公開的 CVS repository 中。
+ 通常 FreeBSD 原始碼都會裝在 <filename>/usr/src</filename>,
+ 而且包含下列子目錄:</para>
+
+ <para>
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Directory</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><filename>bin/</filename></entry>
+ <entry>Source for files in
+ <filename>/bin</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>contrib/</filename></entry>
+ <entry>Source for files from contributed software.</entry>
+ </row>
+
+ <row>
+ <entry><filename>crypto/</filename></entry>
+ <entry>Cryptographical sources</entry>
+ </row>
+
+ <row>
+ <entry><filename>etc/</filename></entry>
+ <entry>Source for files in <filename>/etc</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>games/</filename></entry>
+ <entry>Source for files in <filename>/usr/games</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>gnu/</filename></entry>
+ <entry>Utilities covered by the GNU Public License</entry>
+ </row>
+
+ <row>
+ <entry><filename>include/</filename></entry>
+ <entry>Source for files in <filename>/usr/include</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>kerberos5/</filename></entry>
+ <entry>Source for Kerberos version 5</entry>
+ </row>
+
+ <row>
+ <entry><filename>lib/</filename></entry>
+ <entry>Source for files in <filename>/usr/lib</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>libexec/</filename></entry>
+ <entry>Source for files in <filename>/usr/libexec</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>release/</filename></entry>
+ <entry>Files required to produce a FreeBSD release</entry>
+ </row>
+
+ <row>
+ <entry><filename>rescue/</filename></entry>
+ <entry>Build system for the
+ <filename>/rescue</filename> utilities</entry>
+ </row>
+
+ <row>
+ <entry><filename>sbin/</filename></entry>
+ <entry>Source for files in <filename>/sbin</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>secure/</filename></entry>
+ <entry>FreeSec sources</entry>
+ </row>
+
+ <row>
+ <entry><filename>share/</filename></entry>
+ <entry>Source for files in <filename>/usr/share</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>sys/</filename></entry>
+ <entry>Kernel source files</entry>
+ </row>
+
+ <row>
+ <entry><filename>tools/</filename></entry>
+ <entry>Tools used for maintenance and testing of
+ FreeBSD</entry>
+ </row>
+
+ <row>
+ <entry><filename>usr.bin/</filename></entry>
+ <entry>Source for files in <filename>/usr/bin</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>usr.sbin/</filename></entry>
+ <entry>Source for files in <filename>/usr/sbin</filename></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/developers-handbook/ipv6/chapter.xml b/zh_TW.UTF-8/books/developers-handbook/ipv6/chapter.xml
new file mode 100644
index 0000000000..a7b78244fb
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/ipv6/chapter.xml
@@ -0,0 +1,1571 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="ipv6">
+ <title>IPv6 Internals</title>
+
+ <sect1 xml:id="ipv6-implementation">
+ <info><title>IPv6/IPsec Implementation</title>
+ <authorgroup>
+ <author><personname><firstname>Yoshinobu</firstname><surname>Inoue</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <para>This section should explain IPv6 and IPsec related implementation
+ internals. These functionalities are derived from <link xlink:href="http://www.kame.net/">KAME project</link></para>
+
+ <sect2 xml:id="ipv6details">
+ <title>IPv6</title>
+
+ <sect3>
+ <title>Conformance</title>
+
+ <para>The IPv6 related functions conforms, or tries to conform to
+ the latest set of IPv6 specifications. For future reference we list
+ some of the relevant documents below (<emphasis>NOTE</emphasis>: this
+ is not a complete list - this is too hard to maintain...).</para>
+
+ <para>For details please refer to specific chapter in the document,
+ RFCs, manual pages, or comments in the source code.</para>
+
+ <para>Conformance tests have been performed on the KAME STABLE kit
+ at TAHI project. Results can be viewed at
+ <uri xlink:href="http://www.tahi.org/report/KAME/">http://www.tahi.org/report/KAME/</uri>.
+ We also attended Univ. of New Hampshire IOL tests
+ (<uri xlink:href="http://www.iol.unh.edu/">http://www.iol.unh.edu/</uri>) in the
+ past, with our past snapshots.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>RFC1639: FTP Operation Over Big Address Records
+ (FOOBAR)</para>
+ <itemizedlist>
+ <listitem>
+ <para>RFC2428 is preferred over RFC1639. FTP clients will
+ first try RFC2428, then RFC1639 if failed.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC1886: DNS Extensions to support IPv6</para>
+ </listitem>
+
+ <listitem>
+ <para>RFC1933: Transition Mechanisms for IPv6 Hosts and
+ Routers</para>
+ <itemizedlist>
+ <listitem>
+ <para>IPv4 compatible address is not supported.</para>
+ </listitem>
+ <listitem>
+ <para>automatic tunneling (described in 4.3 of this RFC) is not
+ supported.</para>
+ </listitem>
+ <listitem>
+ <para>&man.gif.4; interface implements IPv[46]-over-IPv[46]
+ tunnel in a generic way, and it covers "configured tunnel"
+ described in the spec. See <link linkend="gif">23.5.1.5</link>
+ in this document for details.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC1981: Path MTU Discovery for IPv6</para>
+ </listitem>
+
+ <listitem>
+ <para>RFC2080: RIPng for IPv6</para>
+ <itemizedlist>
+ <listitem>
+ <para>usr.sbin/route6d support this.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC2292: Advanced Sockets API for IPv6</para>
+ <itemizedlist>
+ <listitem>
+ <para>For supported library functions/kernel APIs, see
+ <filename>sys/netinet6/ADVAPI</filename>.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC2362: Protocol Independent Multicast-Sparse
+ Mode (PIM-SM)</para>
+ <itemizedlist>
+ <listitem>
+ <para>RFC2362 defines packet formats for PIM-SM.
+ <filename>draft-ietf-pim-ipv6-01.txt</filename> is
+ written based on this.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC2373: IPv6 Addressing Architecture</para>
+ <itemizedlist>
+ <listitem>
+ <para>supports node required addresses, and conforms to
+ the scope requirement.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC2374: An IPv6 Aggregatable Global Unicast Address
+ Format</para>
+ <itemizedlist>
+ <listitem>
+ <para>supports 64-bit length of Interface ID.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC2375: IPv6 Multicast Address Assignments</para>
+ <itemizedlist>
+ <listitem>
+ <para>Userland applications use the well-known addresses
+ assigned in the RFC.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC2428: FTP Extensions for IPv6 and NATs</para>
+ <itemizedlist>
+ <listitem>
+ <para>RFC2428 is preferred over RFC1639. FTP clients will
+ first try RFC2428, then RFC1639 if failed.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC2460: IPv6 specification</para>
+ </listitem>
+
+ <listitem>
+ <para>RFC2461: Neighbor discovery for IPv6</para>
+ <itemizedlist>
+ <listitem>
+ <para>See <link linkend="neighbor-discovery">23.5.1.2</link>
+ in this document for details.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC2462: IPv6 Stateless Address Autoconfiguration</para>
+ <itemizedlist>
+ <listitem>
+ <para>See <link linkend="ipv6-pnp">23.5.1.4</link> in this
+ document for details.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC2463: ICMPv6 for IPv6 specification</para>
+ <itemizedlist>
+ <listitem>
+ <para>See <link linkend="icmpv6">23.5.1.9</link> in this
+ document for details.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC2464: Transmission of IPv6 Packets over Ethernet
+ Networks</para>
+ </listitem>
+
+ <listitem>
+ <para>RFC2465: MIB for IPv6: Textual Conventions and General
+ Group</para>
+ <itemizedlist>
+ <listitem>
+ <para>Necessary statistics are gathered by the kernel. Actual
+ IPv6 MIB support is provided as a patchkit for ucd-snmp.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC2466: MIB for IPv6: ICMPv6 group</para>
+ <itemizedlist>
+ <listitem>
+ <para>Necessary statistics are gathered by the kernel. Actual
+ IPv6 MIB support is provided as patchkit for ucd-snmp.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC2467: Transmission of IPv6 Packets over FDDI
+ Networks</para>
+ </listitem>
+
+ <listitem>
+ <para>RFC2497: Transmission of IPv6 packet over ARCnet
+ Networks</para>
+ </listitem>
+
+ <listitem>
+ <para>RFC2553: Basic Socket Interface Extensions for IPv6</para>
+ <itemizedlist>
+ <listitem>
+ <para>IPv4 mapped address (3.7) and special behavior of IPv6
+ wildcard bind socket (3.8) are supported. See <link linkend="ipv6-wildcard-socket">23.5.1.12</link>
+ in this document for details.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC2675: IPv6 Jumbograms</para>
+ <itemizedlist>
+ <listitem>
+ <para>See <link linkend="ipv6-jumbo">23.5.1.7</link> in
+ this document for details.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>RFC2710: Multicast Listener Discovery for IPv6</para>
+ </listitem>
+
+ <listitem>
+ <para>RFC2711: IPv6 router alert option</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>draft-ietf-ipngwg-router-renum-08</filename>: Router
+ renumbering for IPv6</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>draft-ietf-ipngwg-icmp-namelookups-02</filename>:
+ IPv6 Name Lookups Through ICMP</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>draft-ietf-ipngwg-icmp-name-lookups-03</filename>:
+ IPv6 Name Lookups Through ICMP</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>draft-ietf-pim-ipv6-01.txt</filename>:
+ PIM for IPv6</para>
+ <itemizedlist>
+ <listitem>
+ <para>&man.pim6dd.8; implements dense mode. &man.pim6sd.8;
+ implements sparse mode.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para><filename>draft-itojun-ipv6-tcp-to-anycast-00</filename>:
+ Disconnecting TCP connection toward IPv6 anycast address</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>draft-yamamoto-wideipv6-comm-model-00</filename>
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>See <link linkend="ipv6-sas">23.5.1.6</link> in this
+ document for details.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para><filename>draft-ietf-ipngwg-scopedaddr-format-00.txt
+ </filename>: An Extension of Format for IPv6 Scoped
+ Addresses</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+
+ <sect3 xml:id="neighbor-discovery">
+ <title>Neighbor Discovery</title>
+
+ <para>Neighbor Discovery is fairly stable. Currently Address
+ Resolution, Duplicated Address Detection, and Neighbor Unreachability
+ Detection are supported. In the near future we will be adding Proxy
+ Neighbor Advertisement support in the kernel and Unsolicited Neighbor
+ Advertisement transmission command as admin tool.</para>
+
+ <para>If DAD fails, the address will be marked "duplicated" and
+ message will be generated to syslog (and usually to console). The
+ "duplicated" mark can be checked with &man.ifconfig.8;. It is
+ administrators' responsibility to check for and recover from DAD
+ failures. The behavior should be improved in the near future.</para>
+
+ <para>Some of the network driver loops multicast packets back to itself,
+ even if instructed not to do so (especially in promiscuous mode).
+ In such cases DAD may fail, because DAD engine sees inbound NS packet
+ (actually from the node itself) and considers it as a sign of duplicate.
+ You may want to look at #if condition marked "heuristics" in
+ sys/netinet6/nd6_nbr.c:nd6_dad_timer() as workaround (note that the code
+ fragment in "heuristics" section is not spec conformant).</para>
+
+ <para>Neighbor Discovery specification (RFC2461) does not talk about
+ neighbor cache handling in the following cases:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>when there was no neighbor cache entry, node
+ received unsolicited RS/NS/NA/redirect packet without
+ link-layer address</para>
+ </listitem>
+ <listitem>
+ <para>neighbor cache handling on medium without link-layer
+ address (we need a neighbor cache entry for IsRouter bit)</para>
+ </listitem>
+ </orderedlist>
+
+ <para>For first case, we implemented workaround based on discussions
+ on IETF ipngwg mailing list. For more details, see the comments in
+ the source code and email thread started from (IPng 7155), dated
+ Feb 6 1999.</para>
+
+ <para>IPv6 on-link determination rule (RFC2461) is quite different
+ from assumptions in BSD network code. At this moment, no on-link
+ determination rule is supported where default router list is empty
+ (RFC2461, section 5.2, last sentence in 2nd paragraph - note that
+ the spec misuse the word "host" and "node" in several places in
+ the section).</para>
+
+ <para>To avoid possible DoS attacks and infinite loops, only 10
+ options on ND packet is accepted now. Therefore, if you have 20
+ prefix options attached to RA, only the first 10 prefixes will be
+ recognized. If this troubles you, please ask it on FREEBSD-CURRENT
+ mailing list and/or modify nd6_maxndopt in
+ <filename>sys/netinet6/nd6.c</filename>. If there are high demands
+ we may provide sysctl knob for the variable.</para>
+ </sect3>
+
+ <sect3 xml:id="ipv6-scope-index">
+ <title>Scope Index</title>
+
+ <para>IPv6 uses scoped addresses. Therefore, it is very important to
+ specify scope index (interface index for link-local address, or
+ site index for site-local address) with an IPv6 address. Without
+ scope index, scoped IPv6 address is ambiguous to the kernel, and
+ kernel will not be able to determine the outbound interface for a
+ packet.</para>
+
+ <para>Ordinary userland applications should use advanced API
+ (RFC2292) to specify scope index, or interface index. For similar
+ purpose, sin6_scope_id member in sockaddr_in6 structure is defined
+ in RFC2553. However, the semantics for sin6_scope_id is rather vague.
+ If you care about portability of your application, we suggest you to
+ use advanced API rather than sin6_scope_id.</para>
+
+ <para>In the kernel, an interface index for link-local scoped address is
+ embedded into 2nd 16bit-word (3rd and 4th byte) in IPv6 address. For
+ example, you may see something like:
+ </para>
+
+ <screen> fe80:1::200:f8ff:fe01:6317
+ </screen>
+
+ <para>in the routing table and interface address structure (struct
+ in6_ifaddr). The address above is a link-local unicast address
+ which belongs to a network interface whose interface identifier is 1.
+ The embedded index enables us to identify IPv6 link local
+ addresses over multiple interfaces effectively and with only a
+ little code change.</para>
+
+ <para>Routing daemons and configuration programs, like &man.route6d.8;
+ and &man.ifconfig.8;, will need to manipulate the "embedded" scope
+ index. These programs use routing sockets and ioctls (like
+ SIOCGIFADDR_IN6) and the kernel API will return IPv6 addresses with
+ 2nd 16bit-word filled in. The APIs are for manipulating kernel
+ internal structure. Programs that use these APIs have to be prepared
+ about differences in kernels anyway.</para>
+
+ <para>When you specify scoped address to the command line, NEVER write
+ the embedded form (such as ff02:1::1 or fe80:2::fedc). This is not
+ supposed to work. Always use standard form, like ff02::1 or
+ fe80::fedc, with command line option for specifying interface (like
+ <command>ping6 -I ne0 ff02::1</command>). In general, if a command
+ does not have command line option to specify outgoing interface, that
+ command is not ready to accept scoped address. This may seem to be
+ opposite from IPv6's premise to support "dentist office" situation.
+ We believe that specifications need some improvements for this.</para>
+
+ <para>Some of the userland tools support extended numeric IPv6 syntax,
+ as documented in
+ <filename>draft-ietf-ipngwg-scopedaddr-format-00.txt</filename>. You
+ can specify outgoing link, by using name of the outgoing interface
+ like "fe80::1%ne0". This way you will be able to specify link-local
+ scoped address without much trouble.</para>
+
+ <para>To use this extension in your program, you will need to use
+ &man.getaddrinfo.3;, and &man.getnameinfo.3; with NI_WITHSCOPEID.
+ The implementation currently assumes 1-to-1 relationship between a
+ link and an interface, which is stronger than what specs say.</para>
+ </sect3>
+
+ <sect3 xml:id="ipv6-pnp">
+ <title>Plug and Play</title>
+
+ <para>Most of the IPv6 stateless address autoconfiguration is implemented
+ in the kernel. Neighbor Discovery functions are implemented in the
+ kernel as a whole. Router Advertisement (RA) input for hosts is
+ implemented in the kernel. Router Solicitation (RS) output for
+ endhosts, RS input for routers, and RA output for routers are
+ implemented in the userland.</para>
+
+ <sect4>
+ <title>Assignment of link-local, and special addresses</title>
+
+ <para>IPv6 link-local address is generated from IEEE802 address
+ (Ethernet MAC address). Each of interface is assigned an IPv6
+ link-local address automatically, when the interface becomes up
+ (IFF_UP). Also, direct route for the link-local address is added
+ to routing table.</para>
+
+ <para>Here is an output of netstat command:</para>
+
+<screen>Internet6:
+Destination Gateway Flags Netif Expire
+fe80:1::%ed0/64 link#1 UC ed0
+fe80:2::%ep0/64 link#2 UC ep0</screen>
+
+ <para>Interfaces that has no IEEE802 address (pseudo interfaces
+ like tunnel interfaces, or ppp interfaces) will borrow IEEE802
+ address from other interfaces, such as Ethernet interfaces,
+ whenever possible. If there is no IEEE802 hardware attached,
+ a last resort pseudo-random value, MD5(hostname), will
+ be used as source of link-local address. If it is not suitable
+ for your usage, you will need to configure the link-local address
+ manually.</para>
+
+ <para>If an interface is not capable of handling IPv6 (such as
+ lack of multicast support), link-local address will not be
+ assigned to that interface. See section 2 for details.</para>
+
+ <para>Each interface joins the solicited multicast address and the
+ link-local all-nodes multicast addresses (e.g. fe80::1:ff01:6317
+ and ff02::1, respectively, on the link the interface is attached).
+ In addition to a link-local address, the loopback address (::1)
+ will be assigned to the loopback interface. Also, ::1/128 and
+ ff01::/32 are automatically added to routing table, and loopback
+ interface joins node-local multicast group ff01::1.</para>
+ </sect4>
+
+ <sect4>
+ <title>Stateless address autoconfiguration on hosts</title>
+
+ <para>In IPv6 specification, nodes are separated into two categories:
+ <emphasis>routers</emphasis> and <emphasis>hosts</emphasis>. Routers
+ forward packets addressed to others, hosts does not forward the
+ packets. net.inet6.ip6.forwarding defines whether this node is
+ router or host (router if it is 1, host if it is 0).</para>
+
+ <para>When a host hears Router Advertisement from the router, a host
+ may autoconfigure itself by stateless address autoconfiguration.
+ This behavior can be controlled by net.inet6.ip6.accept_rtadv (host
+ autoconfigures itself if it is set to 1). By autoconfiguration,
+ network address prefix for the receiving interface (usually global
+ address prefix) is added. Default route is also configured.
+ Routers periodically generate Router Advertisement packets. To
+ request an adjacent router to generate RA packet, a host can
+ transmit Router Solicitation. To generate a RS packet at any time,
+ use the <emphasis>rtsol</emphasis> command. &man.rtsold.8; daemon is
+ also available. &man.rtsold.8; generates Router Solicitation whenever
+ necessary, and it works great for nomadic usage (notebooks/laptops).
+ If one wishes to ignore Router Advertisements, use sysctl to set
+ net.inet6.ip6.accept_rtadv to 0.</para>
+
+ <para>To generate Router Advertisement from a router, use the
+ &man.rtadvd.8; daemon.</para>
+
+ <para>Note that, IPv6 specification assumes the following items, and
+ nonconforming cases are left unspecified:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Only hosts will listen to router advertisements</para>
+ </listitem>
+ <listitem>
+ <para>Hosts have single network interface (except loopback)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Therefore, this is unwise to enable net.inet6.ip6.accept_rtadv
+ on routers, or multi-interface host. A misconfigured node can
+ behave strange (nonconforming configuration allowed for those who
+ would like to do some experiments).</para>
+
+ <para>To summarize the sysctl knob:</para>
+
+ <screen> accept_rtadv forwarding role of the node
+ --- --- ---
+ 0 0 host (to be manually configured)
+ 0 1 router
+ 1 0 autoconfigured host
+ (spec assumes that host has single
+ interface only, autoconfigured host
+ with multiple interface is
+ out-of-scope)
+ 1 1 invalid, or experimental
+ (out-of-scope of spec)</screen>
+
+ <para>RFC2462 has validation rule against incoming RA prefix
+ information option, in 5.5.3 (e). This is to protect hosts from
+ malicious (or misconfigured) routers that advertise very short
+ prefix lifetime. There was an update from Jim Bound to ipngwg
+ mailing list (look for "(ipng 6712)" in the archive) and it is
+ implemented Jim's update.</para>
+
+ <para>See <link linkend="neighbor-discovery">23.5.1.2</link> in
+ the document for relationship between DAD and
+ autoconfiguration.</para>
+ </sect4>
+ </sect3>
+
+ <sect3 xml:id="gif">
+ <title>Generic tunnel interface</title>
+
+ <para>GIF (Generic InterFace) is a pseudo interface for configured
+ tunnel. Details are described in &man.gif.4;. Currently</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>v6 in v6</para>
+ </listitem>
+ <listitem>
+ <para>v6 in v4</para>
+ </listitem>
+ <listitem>
+ <para>v4 in v6</para>
+ </listitem>
+ <listitem>
+ <para>v4 in v4</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>are available. Use &man.gifconfig.8; to assign physical (outer)
+ source and destination address to gif interfaces. Configuration that
+ uses same address family for inner and outer IP header (v4 in v4, or
+ v6 in v6) is dangerous. It is very easy to configure interfaces and
+ routing tables to perform infinite level of tunneling.
+ <emphasis>Please be warned</emphasis>.</para>
+
+ <para>gif can be configured to be ECN-friendly. See <link linkend="ipsec-ecn">23.5.4.5</link> for ECN-friendliness of
+ tunnels, and &man.gif.4; for how to configure.</para>
+
+ <para>If you would like to configure an IPv4-in-IPv6 tunnel with gif
+ interface, read &man.gif.4; carefully. You will need to
+ remove IPv6 link-local address automatically assigned to the gif
+ interface.</para>
+ </sect3>
+
+ <sect3 xml:id="ipv6-sas">
+ <title>Source Address Selection</title>
+
+ <para>Current source selection rule is scope oriented (there are some
+ exceptions - see below). For a given destination, a source IPv6
+ address is selected by the following rule:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>If the source address is explicitly specified by
+ the user (e.g. via the advanced API), the specified address
+ is used.</para>
+ </listitem>
+
+ <listitem>
+ <para>If there is an address assigned to the outgoing
+ interface (which is usually determined by looking up the
+ routing table) that has the same scope as the destination
+ address, the address is used.</para>
+
+ <para>This is the most typical case.</para>
+ </listitem>
+
+ <listitem>
+ <para>If there is no address that satisfies the above
+ condition, choose a global address assigned to one of
+ the interfaces on the sending node.</para>
+ </listitem>
+
+ <listitem>
+ <para>If there is no address that satisfies the above condition,
+ and destination address is site local scope, choose a site local
+ address assigned to one of the interfaces on the sending node.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>If there is no address that satisfies the above condition,
+ choose the address associated with the routing table entry for the
+ destination. This is the last resort, which may cause scope
+ violation.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>For instance, ::1 is selected for ff01::1,
+ fe80:1::200:f8ff:fe01:6317 for fe80:1::2a0:24ff:feab:839b (note
+ that embedded interface index - described in <link linkend="ipv6-scope-index">23.5.1.3</link> - helps us
+ choose the right source address. Those embedded indices will not
+ be on the wire). If the outgoing interface has multiple address for
+ the scope, a source is selected longest match basis (rule 3). Suppose
+ 3ffe:501:808:1:200:f8ff:fe01:6317 and 3ffe:2001:9:124:200:f8ff:fe01:6317
+ are given to the outgoing interface. 3ffe:501:808:1:200:f8ff:fe01:6317
+ is chosen as the source for the destination 3ffe:501:800::1.</para>
+
+ <para>Note that the above rule is not documented in the IPv6 spec.
+ It is considered "up to implementation" item. There are some cases
+ where we do not use the above rule. One example is connected TCP
+ session, and we use the address kept in tcb as the source. Another
+ example is source address for Neighbor Advertisement. Under the spec
+ (RFC2461 7.2.2) NA's source should be the target address of the
+ corresponding NS's target. In this case we follow the spec rather
+ than the above longest-match rule.</para>
+
+ <para>For new connections (when rule 1 does not apply), deprecated
+ addresses (addresses with preferred lifetime = 0) will not be chosen
+ as source address if other choices are available. If no other choices
+ are available, deprecated address will be used as a last resort. If
+ there are multiple choice of deprecated addresses, the above scope
+ rule will be used to choose from those deprecated addresses. If you
+ would like to prohibit the use of deprecated address for some reason,
+ configure net.inet6.ip6.use_deprecated to 0. The issue related to
+ deprecated address is described in RFC2462 5.5.4 (NOTE: there is
+ some debate underway in IETF ipngwg on how to use "deprecated"
+ address).</para>
+ </sect3>
+
+ <sect3 xml:id="ipv6-jumbo">
+ <title>Jumbo Payload</title>
+
+ <para>The Jumbo Payload hop-by-hop option is implemented and can
+ be used to send IPv6 packets with payloads longer than 65,535 octets.
+ But currently no physical interface whose MTU is more than 65,535 is
+ supported, so such payloads can be seen only on the loopback
+ interface (i.e. lo0).</para>
+
+ <para>If you want to try jumbo payloads, you first have to reconfigure
+ the kernel so that the MTU of the loopback interface is more than
+ 65,535 bytes; add the following to the kernel configuration file:</para>
+
+ <para><literal>
+ options "LARGE_LOMTU" #To test jumbo payload
+ </literal></para>
+
+ <para>and recompile the new kernel.</para>
+
+ <para>Then you can test jumbo payloads by the &man.ping6.8; command
+ with -b and -s options. The -b option must be specified to enlarge
+ the size of the socket buffer and the -s option specifies the length
+ of the packet, which should be more than 65,535. For example,
+ type as follows:</para>
+
+ <screen>&prompt.user; <userinput>ping6 -b 70000 -s 68000 ::1</userinput></screen>
+
+ <para>The IPv6 specification requires that the Jumbo Payload option
+ must not be used in a packet that carries a fragment header. If
+ this condition is broken, an ICMPv6 Parameter Problem message must
+ be sent to the sender. specification is followed, but you cannot
+ usually see an ICMPv6 error caused by this requirement.</para>
+
+ <para>When an IPv6 packet is received, the frame length is checked and
+ compared to the length specified in the payload length field of the
+ IPv6 header or in the value of the Jumbo Payload option, if any. If
+ the former is shorter than the latter, the packet is discarded and
+ statistics are incremented. You can see the statistics as output of
+ &man.netstat.8; command with `-s -p ip6' option:</para>
+
+ <screen>&prompt.user; <userinput>netstat -s -p ip6</userinput>
+ ip6:
+ (snip)
+ 1 with data size &lt; data length</screen>
+
+ <para>So, kernel does not send an ICMPv6 error unless the erroneous
+ packet is an actual Jumbo Payload, that is, its packet size is more
+ than 65,535 bytes. As described above, currently no physical interface
+ with such a huge MTU is supported, so it rarely returns an
+ ICMPv6 error.</para>
+
+ <para>TCP/UDP over jumbogram is not supported at this moment. This
+ is because we have no medium (other than loopback) to test this.
+ Contact us if you need this.</para>
+
+ <para>IPsec does not work on jumbograms. This is due to some
+ specification twists in supporting AH with jumbograms (AH header
+ size influences payload length, and this makes it real hard to
+ authenticate inbound packet with jumbo payload option as well as AH).
+ </para>
+
+ <para>There are fundamental issues in *BSD support for jumbograms.
+ We would like to address those, but we need more time to finalize
+ these. To name a few:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>mbuf pkthdr.len field is typed as "int" in 4.4BSD, so
+ it will not hold jumbogram with len &gt; 2G on 32bit architecture
+ CPUs. If we would like to support jumbogram properly, the field
+ must be expanded to hold 4G + IPv6 header + link-layer header.
+ Therefore, it must be expanded to at least int64_t
+ (u_int32_t is NOT enough).</para>
+ </listitem>
+
+ <listitem>
+ <para>We mistakingly use "int" to hold packet length in many
+ places. We need to convert them into larger integral type.
+ It needs a great care, as we may experience overflow during
+ packet length computation.</para>
+ </listitem>
+
+ <listitem>
+ <para>We mistakingly check for ip6_plen field of IPv6 header
+ for packet payload length in various places. We should be
+ checking mbuf pkthdr.len instead. ip6_input() will perform
+ sanity check on jumbo payload option on input, and we can
+ safely use mbuf pkthdr.len afterwards.</para>
+ </listitem>
+
+ <listitem>
+ <para>TCP code needs a careful update in bunch of places, of
+ course.</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+
+ <sect3>
+ <title>Loop prevention in header processing</title>
+
+ <para>IPv6 specification allows arbitrary number of extension headers
+ to be placed onto packets. If we implement IPv6 packet processing
+ code in the way BSD IPv4 code is implemented, kernel stack may
+ overflow due to long function call chain. sys/netinet6 code
+ is carefully designed to avoid kernel stack overflow. Because of
+ this, sys/netinet6 code defines its own protocol switch
+ structure, as "struct ip6protosw" (see
+ <filename>netinet6/ip6protosw.h</filename>). There is no such
+ update to IPv4 part (sys/netinet) for compatibility, but small
+ change is added to its pr_input() prototype. So "struct ipprotosw"
+ is also defined. Because of this, if you receive IPsec-over-IPv4
+ packet with massive number of IPsec headers, kernel stack may blow
+ up. IPsec-over-IPv6 is okay. (Off-course, for those all IPsec
+ headers to be processed, each such IPsec header must pass each
+ IPsec check. So an anonymous attacker will not be able to do such an
+ attack.)</para>
+ </sect3>
+
+ <sect3 xml:id="icmpv6">
+ <title>ICMPv6</title>
+
+ <para>After RFC2463 was published, IETF ipngwg has decided to
+ disallow ICMPv6 error packet against ICMPv6 redirect, to prevent
+ ICMPv6 storm on a network medium. This is already implemented
+ into the kernel.</para>
+ </sect3>
+
+ <sect3>
+ <title>Applications</title>
+
+ <para>For userland programming, we support IPv6 socket API as
+ specified in RFC2553, RFC2292 and upcoming Internet drafts.</para>
+
+ <para>TCP/UDP over IPv6 is available and quite stable. You can
+ enjoy &man.telnet.1;, &man.ftp.1;, &man.rlogin.1;, &man.rsh.1;,
+ &man.ssh.1;, etc. These applications are protocol independent.
+ That is, they automatically chooses IPv4 or IPv6 according to DNS.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Kernel Internals</title>
+
+ <para>While ip_forward() calls ip_output(), ip6_forward() directly
+ calls if_output() since routers must not divide IPv6 packets into
+ fragments.</para>
+
+ <para>ICMPv6 should contain the original packet as long as possible
+ up to 1280. UDP6/IP6 port unreach, for instance, should contain
+ all extension headers and the *unchanged* UDP6 and IP6 headers.
+ So, all IP6 functions except TCP never convert network byte
+ order into host byte order, to save the original packet.</para>
+
+ <para>tcp_input(), udp6_input() and icmp6_input() can not assume that
+ IP6 header is preceding the transport headers due to extension
+ headers. So, in6_cksum() was implemented to handle packets whose IP6
+ header and transport header is not continuous. TCP/IP6 nor UDP6/IP6
+ header structures do not exist for checksum calculation.</para>
+
+ <para>To process IP6 header, extension headers and transport headers
+ easily, network drivers are now required to store packets in one
+ internal mbuf or one or more external mbufs. A typical old driver
+ prepares two internal mbufs for 96 - 204 bytes data, however, now
+ such packet data is stored in one external mbuf.</para>
+
+ <para><command>netstat -s -p ip6</command> tells you whether or not
+ your driver conforms such requirement. In the following example,
+ "cce0" violates the requirement. (For more information, refer to
+ Section 2.)</para>
+
+ <screen>Mbuf statistics:
+ 317 one mbuf
+ two or more mbuf::
+ lo0 = 8
+ cce0 = 10
+ 3282 one ext mbuf
+ 0 two or more ext mbuf
+ </screen>
+
+ <para>Each input function calls IP6_EXTHDR_CHECK in the beginning to
+ check if the region between IP6 and its header is continuous.
+ IP6_EXTHDR_CHECK calls m_pullup() only if the mbuf has M_LOOP flag,
+ that is, the packet comes from the loopback interface. m_pullup()
+ is never called for packets coming from physical network interfaces.
+ </para>
+
+ <para>Both IP and IP6 reassemble functions never call m_pullup().</para>
+ </sect3>
+
+ <sect3 xml:id="ipv6-wildcard-socket">
+ <title>IPv4 mapped address and IPv6 wildcard socket</title>
+
+ <para>RFC2553 describes IPv4 mapped address (3.7) and special behavior
+ of IPv6 wildcard bind socket (3.8). The spec allows you to:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Accept IPv4 connections by AF_INET6 wildcard bind
+ socket.</para>
+ </listitem>
+ <listitem>
+ <para>Transmit IPv4 packet over AF_INET6 socket by using
+ special form of the address like ::ffff:10.1.1.1.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>but the spec itself is very complicated and does not specify
+ how the socket layer should behave. Here we call the former one
+ "listening side" and the latter one "initiating side", for
+ reference purposes.</para>
+
+ <para>You can perform wildcard bind on both of the address families,
+ on the same port.</para>
+
+ <para>The following table show the behavior of FreeBSD 4.x.</para>
+
+ <screen>listening side initiating side
+ (AF_INET6 wildcard (connection to ::ffff:10.1.1.1)
+ socket gets IPv4 conn.)
+ --- ---
+FreeBSD 4.x configurable supported
+ default: enabled
+ </screen>
+
+ <para>The following sections will give you more details, and how you can
+ configure the behavior.</para>
+
+ <para>Comments on listening side:</para>
+
+ <para>It looks that RFC2553 talks too little on wildcard bind issue,
+ especially on the port space issue, failure mode and relationship
+ between AF_INET/INET6 wildcard bind. There can be several separate
+ interpretation for this RFC which conform to it but behaves differently.
+ So, to implement portable application you should assume nothing
+ about the behavior in the kernel. Using &man.getaddrinfo.3; is the
+ safest way. Port number space and wildcard bind issues were discussed
+ in detail on ipv6imp mailing list, in mid March 1999 and it looks
+ that there is no concrete consensus (means, up to implementers).
+ You may want to check the mailing list archives.</para>
+
+ <para>If a server application would like to accept IPv4 and IPv6
+ connections, there will be two alternatives.</para>
+
+ <para>One is using AF_INET and AF_INET6 socket (you will need two
+ sockets). Use &man.getaddrinfo.3; with AI_PASSIVE into ai_flags,
+ and &man.socket.2; and &man.bind.2; to all the addresses returned.
+ By opening multiple sockets, you can accept connections onto the
+ socket with proper address family. IPv4 connections will be
+ accepted by AF_INET socket, and IPv6 connections will be accepted
+ by AF_INET6 socket.</para>
+
+ <para>Another way is using one AF_INET6 wildcard bind socket. Use
+ &man.getaddrinfo.3; with AI_PASSIVE into ai_flags and with
+ AF_INET6 into ai_family, and set the 1st argument hostname to
+ NULL. And &man.socket.2; and &man.bind.2; to the address returned.
+ (should be IPv6 unspecified addr). You can accept either of IPv4
+ and IPv6 packet via this one socket.</para>
+
+ <para>To support only IPv6 traffic on AF_INET6 wildcard binded socket
+ portably, always check the peer address when a connection is made
+ toward AF_INET6 listening socket. If the address is IPv4 mapped
+ address, you may want to reject the connection. You can check the
+ condition by using IN6_IS_ADDR_V4MAPPED() macro.</para>
+
+ <para>To resolve this issue more easily, there is system dependent
+ &man.setsockopt.2; option, IPV6_BINDV6ONLY, used like below.</para>
+
+ <screen> int on;
+
+ setsockopt(s, IPPROTO_IPV6, IPV6_BINDV6ONLY,
+ (char *)&amp;on, sizeof (on)) &lt; 0));
+ </screen>
+
+ <para>When this call succeed, then this socket only receive IPv6
+ packets.</para>
+
+ <para>Comments on initiating side:</para>
+
+ <para>Advise to application implementers: to implement a portable
+ IPv6 application (which works on multiple IPv6 kernels), we believe
+ that the following is the key to the success:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>NEVER hardcode AF_INET nor AF_INET6.</para>
+ </listitem>
+
+ <listitem>
+ <para>Use &man.getaddrinfo.3; and &man.getnameinfo.3;
+ throughout the system. Never use gethostby*(), getaddrby*(),
+ inet_*() or getipnodeby*(). (To update existing applications
+ to be IPv6 aware easily, sometime getipnodeby*() will be
+ useful. But if possible, try to rewrite the code to use
+ &man.getaddrinfo.3; and &man.getnameinfo.3;.)</para>
+ </listitem>
+
+ <listitem>
+ <para>If you would like to connect to destination, use
+ &man.getaddrinfo.3; and try all the destination returned,
+ like &man.telnet.1; does.</para>
+ </listitem>
+
+ <listitem>
+ <para>Some of the IPv6 stack is shipped with buggy
+ &man.getaddrinfo.3;. Ship a minimal working version with
+ your application and use that as last resort.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>If you would like to use AF_INET6 socket for both IPv4 and
+ IPv6 outgoing connection, you will need to use &man.getipnodebyname.3;.
+ When you would like to update your existing application to be IPv6
+ aware with minimal effort, this approach might be chosen. But please
+ note that it is a temporal solution, because &man.getipnodebyname.3;
+ itself is not recommended as it does not handle scoped IPv6 addresses
+ at all. For IPv6 name resolution, &man.getaddrinfo.3; is the
+ preferred API. So you should rewrite your application to use
+ &man.getaddrinfo.3;, when you get the time to do it.</para>
+
+ <para>When writing applications that make outgoing connections,
+ story goes much simpler if you treat AF_INET and AF_INET6 as totally
+ separate address family. {set,get}sockopt issue goes simpler,
+ DNS issue will be made simpler. We do not recommend you to rely
+ upon IPv4 mapped address.</para>
+
+ <sect4>
+ <title>unified tcp and inpcb code</title>
+
+ <para>FreeBSD 4.x uses shared tcp code between IPv4 and IPv6
+ (from sys/netinet/tcp*) and separate udp4/6 code. It uses
+ unified inpcb structure.</para>
+
+ <para>The platform can be configured to support IPv4 mapped address.
+ Kernel configuration is summarized as follows:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>By default, AF_INET6 socket will grab IPv4
+ connections in certain condition, and can initiate
+ connection to IPv4 destination embedded in IPv4 mapped
+ IPv6 address.</para>
+ </listitem>
+
+ <listitem>
+ <para>You can disable it on entire system with sysctl like
+ below.</para>
+
+ <para>
+ <command>sysctl net.inet6.ip6.mapped_addr=0</command>
+ </para>
+
+ </listitem>
+ </itemizedlist>
+
+ <sect5>
+ <title>listening side</title>
+
+ <para>Each socket can be configured to support special AF_INET6
+ wildcard bind (enabled by default). You can disable it on
+ each socket basis with &man.setsockopt.2; like below.</para>
+
+ <screen> int on;
+
+ setsockopt(s, IPPROTO_IPV6, IPV6_BINDV6ONLY,
+ (char *)&amp;on, sizeof (on)) &lt; 0));
+ </screen>
+
+ <para>Wildcard AF_INET6 socket grabs IPv4 connection if and only
+ if the following conditions are satisfied:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>there is no AF_INET socket that matches the IPv4
+ connection</para>
+ </listitem>
+
+ <listitem>
+ <para>the AF_INET6 socket is configured to accept IPv4
+ traffic, i.e. getsockopt(IPV6_BINDV6ONLY) returns 0.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>There is no problem with open/close ordering.</para>
+ </sect5>
+
+ <sect5>
+ <title>initiating side</title>
+
+ <para>FreeBSD 4.x supports outgoing connection to IPv4 mapped
+ address (::ffff:10.1.1.1), if the node is configured to support
+ IPv4 mapped address.</para>
+ </sect5>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>sockaddr_storage</title>
+
+ <para>When RFC2553 was about to be finalized, there was discussion on
+ how struct sockaddr_storage members are named. One proposal is to
+ prepend "__" to the members (like "__ss_len") as they should not be
+ touched. The other proposal was not to prepend it (like "ss_len")
+ as we need to touch those members directly. There was no clear
+ consensus on it.</para>
+
+ <para>As a result, RFC2553 defines struct sockaddr_storage as
+ follows:</para>
+
+ <screen> struct sockaddr_storage {
+ u_char __ss_len; /* address length */
+ u_char __ss_family; /* address family */
+ /* and bunch of padding */
+ };
+ </screen>
+
+ <para>On the contrary, XNET draft defines as follows:</para>
+
+ <screen> struct sockaddr_storage {
+ u_char ss_len; /* address length */
+ u_char ss_family; /* address family */
+ /* and bunch of padding */
+ };
+ </screen>
+
+ <para>In December 1999, it was agreed that RFC2553bis should pick
+ the latter (XNET) definition.</para>
+
+ <para>Current implementation conforms to XNET definition, based on
+ RFC2553bis discussion.</para>
+
+ <para>If you look at multiple IPv6 implementations, you will be able
+ to see both definitions. As an userland programmer, the most
+ portable way of dealing with it is to:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>ensure ss_family and/or ss_len are available on the
+ platform, by using GNU autoconf,</para>
+ </listitem>
+
+ <listitem>
+ <para>have -Dss_family=__ss_family to unify all occurrences
+ (including header file) into __ss_family, or</para>
+ </listitem>
+
+ <listitem>
+ <para>never touch __ss_family. cast to sockaddr * and use sa_family
+ like:</para>
+
+ <screen> struct sockaddr_storage ss;
+ family = ((struct sockaddr *)&amp;ss)-&gt;sa_family
+ </screen>
+
+ </listitem>
+ </orderedlist>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Network Drivers</title>
+
+ <para>Now following two items are required to be supported by standard
+ drivers:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>mbuf clustering requirement. In this stable release, we
+ changed MINCLSIZE into MHLEN+1 for all the operating systems
+ in order to make all the drivers behave as we expect.</para>
+ </listitem>
+
+ <listitem>
+ <para>multicast. If &man.ifmcstat.8; yields no multicast group for
+ a interface, that interface has to be patched.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>If any of the drivers do not support the requirements, then
+ the drivers can not be used for IPv6 and/or IPsec communication. If
+ you find any problem with your card using IPv6/IPsec, then, please
+ report it to the &a.bugs;.</para>
+
+ <para>(NOTE: In the past we required all PCMCIA drivers to have a
+ call to in6_ifattach(). We have no such requirement any more)</para>
+ </sect2>
+
+ <sect2>
+ <title>Translator</title>
+
+ <para>We categorize IPv4/IPv6 translator into 4 types:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>Translator A</emphasis> --- It is used in the early
+ stage of transition to make it possible to establish a
+ connection from an IPv6 host in an IPv6 island to an IPv4 host
+ in the IPv4 ocean.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Translator B</emphasis> --- It is used in the early
+ stage of transition to make it possible to establish a connection
+ from an IPv4 host in the IPv4 ocean to an IPv6 host in an
+ IPv6 island.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Translator C</emphasis> --- It is used in the late
+ stage of transition to make it possible to establish a
+ connection from an IPv4 host in an IPv4 island to an IPv6 host
+ in the IPv6 ocean.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Translator D</emphasis> --- It is used in the late
+ stage of transition to make it possible to establish a
+ connection from an IPv6 host in the IPv6 ocean to an IPv4 host
+ in an IPv4 island.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>TCP relay translator for category A is supported. This is called
+ "FAITH". We also provide IP header translator for category A.
+ (The latter is not yet put into FreeBSD 4.x yet.)</para>
+
+ <sect3>
+ <title>FAITH TCP relay translator</title>
+
+ <para>FAITH system uses TCP relay daemon called &man.faithd.8; helped
+ by the kernel. FAITH will reserve an IPv6 address prefix, and relay
+ TCP connection toward that prefix to IPv4 destination.</para>
+
+ <para>For example, if the reserved IPv6 prefix is
+ 3ffe:0501:0200:ffff::, and the IPv6 destination for TCP connection
+ is 3ffe:0501:0200:ffff::163.221.202.12, the connection will be
+ relayed toward IPv4 destination 163.221.202.12.</para>
+
+ <screen> destination IPv4 node (163.221.202.12)
+ ^
+ | IPv4 tcp toward 163.221.202.12
+ FAITH-relay dual stack node
+ ^
+ | IPv6 TCP toward 3ffe:0501:0200:ffff::163.221.202.12
+ source IPv6 node
+ </screen>
+
+ <para>&man.faithd.8; must be invoked on FAITH-relay dual stack
+ node.</para>
+
+ <para>For more details, consult
+ <filename>src/usr.sbin/faithd/README</filename></para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="ipsec-implementation">
+ <title>IPsec</title>
+
+ <para>IPsec is mainly organized by three components.</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Policy Management</para>
+ </listitem>
+
+ <listitem>
+ <para>Key Management</para>
+ </listitem>
+
+ <listitem>
+ <para>AH and ESP handling</para>
+ </listitem>
+ </orderedlist>
+
+ <sect3>
+ <title>Policy Management</title>
+
+ <para>The kernel implements experimental policy management code.
+ There are two way to manage security policy. One is to configure
+ per-socket policy using &man.setsockopt.2;. In this cases, policy
+ configuration is described in &man.ipsec.set.policy.3;. The other
+ is to configure kernel packet filter-based policy using PF_KEY
+ interface, via &man.setkey.8;.</para>
+
+ <para>The policy entry is not re-ordered with its
+ indexes, so the order of entry when you add is very significant.</para>
+ </sect3>
+
+ <sect3>
+ <title>Key Management</title>
+
+ <para>The key management code implemented in this kit (sys/netkey)
+ is a home-brew PFKEY v2 implementation. This conforms to RFC2367.
+ </para>
+
+ <para>The home-brew IKE daemon, "racoon" is included in the
+ kit (kame/kame/racoon). Basically you will need to run racoon as
+ daemon, then set up a policy to require keys (like
+ <command>ping -P 'out ipsec esp/transport//use'</command>).
+ The kernel will contact racoon daemon as necessary to exchange
+ keys.</para>
+ </sect3>
+
+ <sect3>
+ <title>AH and ESP handling</title>
+
+ <para>IPsec module is implemented as "hooks" to the standard IPv4/IPv6
+ processing. When sending a packet, ip{,6}_output() checks if ESP/AH
+ processing is required by checking if a matching SPD (Security
+ Policy Database) is found. If ESP/AH is needed,
+ {esp,ah}{4,6}_output() will be called and mbuf will be updated
+ accordingly. When a packet is received, {esp,ah}4_input() will be
+ called based on protocol number, i.e. (*inetsw[proto])().
+ {esp,ah}4_input() will decrypt/check authenticity of the packet,
+ and strips off daisy-chained header and padding for ESP/AH. It is
+ safe to strip off the ESP/AH header on packet reception, since we
+ will never use the received packet in "as is" form.</para>
+
+ <para>By using ESP/AH, TCP4/6 effective data segment size will be
+ affected by extra daisy-chained headers inserted by ESP/AH. Our
+ code takes care of the case.</para>
+
+ <para>Basic crypto functions can be found in directory "sys/crypto".
+ ESP/AH transform are listed in {esp,ah}_core.c with wrapper functions.
+ If you wish to add some algorithm, add wrapper function in
+ {esp,ah}_core.c, and add your crypto algorithm code into
+ sys/crypto.</para>
+
+ <para>Tunnel mode is partially supported in this release, with the
+ following restrictions:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>IPsec tunnel is not combined with GIF generic tunneling
+ interface. It needs a great care because we may create an
+ infinite loop between ip_output() and tunnelifp-&gt;if_output().
+ Opinion varies if it is better to unify them, or not.</para>
+ </listitem>
+
+ <listitem>
+ <para>MTU and Don't Fragment bit (IPv4) considerations need more
+ checking, but basically works fine.</para>
+ </listitem>
+
+ <listitem>
+ <para>Authentication model for AH tunnel must be revisited.
+ We will need to improve the policy management engine,
+ eventually.</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+
+ <sect3>
+ <title>Conformance to RFCs and IDs</title>
+
+ <para>The IPsec code in the kernel conforms (or, tries to conform)
+ to the following standards:</para>
+
+ <para>"old IPsec" specification documented in
+ <filename>rfc182[5-9].txt</filename></para>
+
+ <para>"new IPsec" specification documented in
+ <filename>rfc240[1-6].txt</filename>,
+ <filename>rfc241[01].txt</filename>, <filename>rfc2451.txt</filename>
+ and <filename>draft-mcdonald-simple-ipsec-api-01.txt</filename>
+ (draft expired, but you can take from <link xlink:href="ftp://ftp.kame.net/pub/internet-drafts/">
+ ftp://ftp.kame.net/pub/internet-drafts/</link>).
+ (NOTE: IKE specifications, <filename>rfc241[7-9].txt</filename> are
+ implemented in userland, as "racoon" IKE daemon)</para>
+
+ <para>Currently supported algorithms are:</para>
+ <itemizedlist>
+ <listitem>
+ <para>old IPsec AH</para>
+ <itemizedlist>
+ <listitem>
+ <para>null crypto checksum (no document, just for
+ debugging)</para>
+ </listitem>
+ <listitem>
+ <para>keyed MD5 with 128bit crypto checksum
+ (<filename>rfc1828.txt</filename>)</para>
+ </listitem>
+ <listitem>
+ <para>keyed SHA1 with 128bit crypto checksum
+ (no document)</para>
+ </listitem>
+ <listitem>
+ <para>HMAC MD5 with 128bit crypto checksum
+ (<filename>rfc2085.txt</filename>)</para>
+ </listitem>
+ <listitem>
+ <para>HMAC SHA1 with 128bit crypto checksum
+ (no document)</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>old IPsec ESP</para>
+ <itemizedlist>
+ <listitem>
+ <para>null encryption (no document, similar to
+ <filename>rfc2410.txt</filename>)</para>
+ </listitem>
+ <listitem>
+ <para>DES-CBC mode (<filename>rfc1829.txt</filename>)</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>new IPsec AH</para>
+ <itemizedlist>
+ <listitem>
+ <para>null crypto checksum (no document,
+ just for debugging)</para>
+ </listitem>
+ <listitem>
+ <para>keyed MD5 with 96bit crypto checksum
+ (no document)</para>
+ </listitem>
+ <listitem>
+ <para>keyed SHA1 with 96bit crypto checksum
+ (no document)</para>
+ </listitem>
+ <listitem>
+ <para>HMAC MD5 with 96bit crypto checksum
+ (<filename>rfc2403.txt</filename>)</para>
+ </listitem>
+ <listitem>
+ <para>HMAC SHA1 with 96bit crypto checksum
+ (<filename>rfc2404.txt</filename>)</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>new IPsec ESP</para>
+ <itemizedlist>
+ <listitem>
+ <para>null encryption
+ (<filename>rfc2410.txt</filename>)</para>
+ </listitem>
+ <listitem>
+ <para>DES-CBC with derived IV
+ (<filename>draft-ietf-ipsec-ciph-des-derived-01.txt</filename>,
+ draft expired)</para>
+ </listitem>
+ <listitem>
+ <para>DES-CBC with explicit IV
+ (<filename>rfc2405.txt</filename>)</para>
+ </listitem>
+ <listitem>
+ <para>3DES-CBC with explicit IV
+ (<filename>rfc2451.txt</filename>)</para>
+ </listitem>
+ <listitem>
+ <para>BLOWFISH CBC
+ (<filename>rfc2451.txt</filename>)</para>
+ </listitem>
+ <listitem>
+ <para>CAST128 CBC
+ (<filename>rfc2451.txt</filename>)</para>
+ </listitem>
+ <listitem>
+ <para>RC5 CBC
+ (<filename>rfc2451.txt</filename>)</para>
+ </listitem>
+ <listitem>
+ <para>each of the above can be combined with:</para>
+ <itemizedlist>
+ <listitem>
+ <para>ESP authentication with HMAC-MD5(96bit)</para>
+ </listitem>
+ <listitem>
+ <para>ESP authentication with HMAC-SHA1(96bit)</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+
+ <para>The following algorithms are NOT supported:</para>
+ <itemizedlist>
+ <listitem>
+
+ <para>old IPsec AH</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>HMAC MD5 with 128bit crypto checksum + 64bit
+ replay prevention (<filename>rfc2085.txt</filename>)</para>
+ </listitem>
+ <listitem>
+ <para>keyed SHA1 with 160bit crypto checksum + 32bit padding
+ (<filename>rfc1852.txt</filename>)</para>
+ </listitem>
+ </itemizedlist>
+
+ </listitem>
+ </itemizedlist>
+
+ <para>IPsec (in kernel) and IKE (in userland as "racoon") has been
+ tested at several interoperability test events, and it is known to
+ interoperate with many other implementations well. Also, current
+ IPsec implementation as quite wide coverage for IPsec crypto
+ algorithms documented in RFC (we cover algorithms without intellectual
+ property issues only).</para>
+ </sect3>
+
+ <sect3 xml:id="ipsec-ecn">
+ <title>ECN consideration on IPsec tunnels</title>
+
+ <para>ECN-friendly IPsec tunnel is supported as described in
+ <filename>draft-ipsec-ecn-00.txt</filename>.</para>
+
+ <para>Normal IPsec tunnel is described in RFC2401. On encapsulation,
+ IPv4 TOS field (or, IPv6 traffic class field) will be copied from inner
+ IP header to outer IP header. On decapsulation outer IP header
+ will be simply dropped. The decapsulation rule is not compatible
+ with ECN, since ECN bit on the outer IP TOS/traffic class field will be
+ lost.</para>
+
+ <para>To make IPsec tunnel ECN-friendly, we should modify encapsulation
+ and decapsulation procedure. This is described in <link xlink:href="http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt">
+ http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt</link>,
+ chapter 3.</para>
+
+ <para>IPsec tunnel implementation can give you three behaviors, by
+ setting net.inet.ipsec.ecn (or net.inet6.ipsec6.ecn) to some
+ value:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>RFC2401: no consideration for ECN (sysctl value -1)</para>
+ </listitem>
+ <listitem>
+ <para>ECN forbidden (sysctl value 0)</para>
+ </listitem>
+ <listitem>
+ <para>ECN allowed (sysctl value 1)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Note that the behavior is configurable in per-node manner,
+ not per-SA manner (draft-ipsec-ecn-00 wants per-SA configuration,
+ but it looks too much for me).</para>
+
+ <para>The behavior is summarized as follows (see source code for
+ more detail):</para>
+
+ <screen>
+ encapsulate decapsulate
+ --- ---
+RFC2401 copy all TOS bits drop TOS bits on outer
+ from inner to outer. (use inner TOS bits as is)
+
+ECN forbidden copy TOS bits except for ECN drop TOS bits on outer
+ (masked with 0xfc) from inner (use inner TOS bits as is)
+ to outer. set ECN bits to 0.
+
+ECN allowed copy TOS bits except for ECN use inner TOS bits with some
+ CE (masked with 0xfe) from change. if outer ECN CE bit
+ inner to outer. is 1, enable ECN CE bit on
+ set ECN CE bit to 0. the inner.
+
+ </screen>
+
+ <para>General strategy for configuration is as follows:</para>
+ <itemizedlist>
+ <listitem>
+ <para>if both IPsec tunnel endpoint are capable of ECN-friendly
+ behavior, you should better configure both end to <quote>ECN allowed</quote>
+ (sysctl value 1).</para>
+ </listitem>
+ <listitem>
+ <para>if the other end is very strict about TOS bit, use "RFC2401"
+ (sysctl value -1).</para>
+ </listitem>
+ <listitem>
+ <para>in other cases, use "ECN forbidden" (sysctl value 0).</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The default behavior is "ECN forbidden" (sysctl value 0).</para>
+
+ <para>For more information, please refer to:</para>
+
+ <para><link xlink:href="http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt">
+ http://www.aciri.org/floyd/papers/draft-ipsec-ecn-00.txt</link>,
+ RFC2481 (Explicit Congestion Notification),
+ src/sys/netinet6/{ah,esp}_input.c</para>
+
+ <para>(Thanks goes to Kenjiro Cho <email>kjc@csl.sony.co.jp</email>
+ for detailed analysis)</para>
+ </sect3>
+
+ <sect3>
+ <title>Interoperability</title>
+
+ <para>Here are (some of) platforms that KAME code have tested
+ IPsec/IKE interoperability in the past. Note that both ends may
+ have modified their implementation, so use the following list just
+ for reference purposes.</para>
+
+ <para>Altiga, Ashley-laurent (vpcom.com), Data Fellows (F-Secure),
+ Ericsson ACC, FreeS/WAN, HITACHI, IBM &aix;, IIJ, Intel,
+ &microsoft; &windowsnt;, NIST (linux IPsec + plutoplus), Netscreen, OpenBSD,
+ RedCreek, Routerware, SSH, Secure Computing, Soliton, Toshiba,
+ VPNet, Yamaha RT100i</para>
+ </sect3>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/developers-handbook/kerneldebug/Makefile b/zh_TW.UTF-8/books/developers-handbook/kerneldebug/Makefile
new file mode 100644
index 0000000000..0f3b90b3e1
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/kerneldebug/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= kerneldebug/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/developers-handbook/kerneldebug/chapter.xml b/zh_TW.UTF-8/books/developers-handbook/kerneldebug/chapter.xml
new file mode 100644
index 0000000000..a2cd16fa99
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/kerneldebug/chapter.xml
@@ -0,0 +1,848 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="kerneldebug">
+ <info><title>Kernel Debugging</title>
+ <authorgroup>
+ <author><personname><firstname>Paul</firstname><surname>Richards</surname></personname><contrib>Contributed by </contrib></author>
+ <author><personname><firstname>J&ouml;rg</firstname><surname>Wunsch</surname></personname></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="kerneldebug-obtain">
+ <title>Obtaining a Kernel Crash Dump</title>
+
+ <para>When running a development kernel (eg: &os.current;), such as a
+ kernel under extreme conditions (eg: very high load averages,
+ tens of thousands of connections, exceedingly high number of
+ concurrent users, hundreds of &man.jail.8;s, etc.), or using a
+ new feature or device driver on &os.stable; (eg:
+ <acronym>PAE</acronym>), sometimes a kernel will panic. In the
+ event that it does, this chapter will demonstrate how to extract
+ useful information out of a crash.</para>
+
+ <para>A system reboot is inevitable once a kernel panics. Once a
+ system is rebooted, the contents of a system's physical memory
+ (<acronym>RAM</acronym>) is lost, as well as any bits that are
+ on the swap device before the panic. To preserve the bits in
+ physical memory, the kernel makes use of the swap device as a
+ temporary place to store the bits that are in RAM across a
+ reboot after a crash. In doing this, when &os; boots after a
+ crash, a kernel image can now be extracted and debugging can
+ take place.</para>
+
+ <note><para>A swap device that has been configured as a dump
+ device still acts as a swap device. Dumps to non-swap devices
+ (such as tapes or CDRWs, for example) are not supported at this time. A
+ <quote>swap device</quote> is synonymous with a <quote>swap
+ partition.</quote></para></note>
+
+ <para>To be able to extract a usable core, it is required that at
+ least one swap partition be large enough to hold all of the bits
+ in physical memory. When a kernel panics, before the system
+ reboots, the kernel is smart enough to check to see if a swap
+ device has been configured as a dump device. If there is a
+ valid dump device, the kernel dumps the contents of what is in
+ physical memory to the swap device.</para>
+
+ <sect2 xml:id="config-dumpdev">
+ <title>Configuring the Dump Device</title>
+
+ <para>Before the kernel will dump the contents of its physical
+ memory to a dump device, a dump device must be configured. A
+ dump device is specified by using the &man.dumpon.8; command
+ to tell the kernel where to save kernel crash dumps. The
+ &man.dumpon.8; program must be called after the swap partition
+ has been configured with &man.swapon.8;. This is normally
+ handled by setting the <varname>dumpdev</varname> variable in
+ &man.rc.conf.5; to the path of the swap device (the
+ recommended way to extract a kernel dump).</para>
+
+ <para>Alternatively, the dump device can be hard-coded via the
+ <literal>dump</literal> clause in the &man.config.5; line of
+ a kernel configuration file. This approach is deprecated and should
+ be used only if a kernel is crashing before &man.dumpon.8; can be executed.</para>
+
+ <tip><para>Check <filename>/etc/fstab</filename> or
+ &man.swapinfo.8; for a list of swap devices.</para></tip>
+
+ <important><para>Make sure the <varname>dumpdir</varname>
+ specified in &man.rc.conf.5; exists before a kernel
+ crash!</para>
+
+ <screen>&prompt.root; <userinput>mkdir /var/crash</userinput>
+&prompt.root; <userinput>chmod 700 /var/crash</userinput></screen>
+
+ <para>Also, remember that the contents of
+ <filename>/var/crash</filename> is sensitive and very likely
+ contains confidential information such as passwords.</para>
+ </important>
+ </sect2>
+
+ <sect2 xml:id="extract-dump">
+ <title>Extracting a Kernel Dump</title>
+
+ <para>Once a dump has been written to a dump device, the dump
+ must be extracted before the swap device is mounted.
+ To extract a dump
+ from a dump device, use the &man.savecore.8; program. If
+ <varname>dumpdev</varname> has been set in &man.rc.conf.5;,
+ &man.savecore.8; will be called automatically on the first
+ multi-user boot after the crash and before the swap device
+ is mounted. The location of the extracted core is placed in
+ the &man.rc.conf.5; value <varname>dumpdir</varname>, by
+ default <filename>/var/crash</filename> and will be named
+ <filename>vmcore.0</filename>.</para>
+
+ <para>In the event that there is already a file called
+ <filename>vmcore.0</filename> in
+ <filename>/var/crash</filename> (or whatever
+ <varname>dumpdir</varname> is set to), the kernel will
+ increment the trailing number for every crash to avoid
+ overwriting an existing <filename>vmcore</filename> (eg:
+ <filename>vmcore.1</filename>). While debugging, it is
+ highly likely that you will want to use the highest version
+ <filename>vmcore</filename> in
+ <filename>/var/crash</filename> when searching for the right
+ <filename>vmcore</filename>.</para>
+
+ <tip>
+ <para>If you are testing a new kernel but need to boot a different one in
+ order to get your system up and running again, boot it only into single
+ user mode using the <option>-s</option> flag at the boot prompt, and
+ then perform the following steps:</para>
+
+ <screen>&prompt.root; <userinput>fsck -p</userinput>
+&prompt.root; <userinput>mount -a -t ufs</userinput> # make sure /var/crash is writable
+&prompt.root; <userinput>savecore /var/crash /dev/ad0s1b</userinput>
+&prompt.root; <userinput>exit</userinput> # exit to multi-user</screen>
+
+ <para>This instructs &man.savecore.8; to extract a kernel dump
+ from <filename>/dev/ad0s1b</filename> and place the contents in
+ <filename>/var/crash</filename>. Do not forget to make sure the
+ destination directory <filename>/var/crash</filename> has enough
+ space for the dump. Also, do not forget to specify the correct path to your swap
+ device as it is likely different than
+ <filename>/dev/ad0s1b</filename>!</para></tip>
+
+ <para>The recommended, and certainly the easiest way to automate
+ obtaining crash dumps is to use the <varname>dumpdev</varname>
+ variable in &man.rc.conf.5;.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="kerneldebug-gdb">
+ <title>Debugging a Kernel Crash Dump with <command>kgdb</command></title>
+
+ <note>
+ <para>This section covers &man.kgdb.1; as found in &os;&nbsp;5.3
+ and later. In previous versions, one must use
+ <command>gdb -k</command> to read a core dump file.</para>
+ </note>
+
+ <para>Once a dump has been obtained, getting useful information
+ out of the dump is relatively easy for simple problems. Before
+ launching into the internals of &man.kgdb.1; to debug
+ the crash dump, locate the debug version of your kernel
+ (normally called <filename>kernel.debug</filename>) and the path
+ to the source files used to build your kernel (normally
+ <filename>/usr/obj/usr/src/sys/KERNCONF</filename>,
+ where <filename>KERNCONF</filename>
+ is the <varname>ident</varname> specified in a kernel
+ &man.config.5;). With those two pieces of info, let the
+ debugging commence!</para>
+
+ <para>To enter into the debugger and begin getting information
+ from the dump, the following steps are required at a minimum:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/obj/usr/src/sys/KERNCONF</userinput>
+&prompt.root; <userinput>kgdb kernel.debug /var/crash/vmcore.0</userinput></screen>
+
+ <para>You can debug the crash dump using the kernel sources just like
+ you can for any other program.</para>
+
+ <para>This first dump is from a 5.2-BETA kernel and the crash
+ comes from deep within the kernel. The output below has been
+ modified to include line numbers on the left. This first trace
+ inspects the instruction pointer and obtains a back trace. The
+ address that is used on line 41 for the <command>list</command>
+ command is the instruction pointer and can be found on line
+ 17. Most developers will request having at least this
+ information sent to them if you are unable to debug the problem
+ yourself. If, however, you do solve the problem, make sure that
+ your patch winds its way into the source tree via a problem
+ report, mailing lists, or by being able to commit it!</para>
+
+ <screen> 1:&prompt.root; <userinput>cd /usr/obj/usr/src/sys/KERNCONF</userinput>
+ 2:&prompt.root; <userinput>kgdb kernel.debug /var/crash/vmcore.0</userinput>
+ 3:GNU gdb 5.2.1 (FreeBSD)
+ 4:Copyright 2002 Free Software Foundation, Inc.
+ 5:GDB is free software, covered by the GNU General Public License, and you are
+ 6:welcome to change it and/or distribute copies of it under certain conditions.
+ 7:Type "show copying" to see the conditions.
+ 8:There is absolutely no warranty for GDB. Type "show warranty" for details.
+ 9:This GDB was configured as "i386-undermydesk-freebsd"...
+10:panic: page fault
+11:panic messages:
+12:---
+13:Fatal trap 12: page fault while in kernel mode
+14:cpuid = 0; apic id = 00
+15:fault virtual address = 0x300
+16:fault code: = supervisor read, page not present
+17:instruction pointer = 0x8:0xc0713860
+18:stack pointer = 0x10:0xdc1d0b70
+19:frame pointer = 0x10:0xdc1d0b7c
+20:code segment = base 0x0, limit 0xfffff, type 0x1b
+21: = DPL 0, pres 1, def32 1, gran 1
+22:processor eflags = resume, IOPL = 0
+23:current process = 14394 (uname)
+24:trap number = 12
+25:panic: page fault
+26 cpuid = 0;
+27:Stack backtrace:
+28
+29:syncing disks, buffers remaining... 2199 2199 panic: mi_switch: switch in a critical section
+30:cpuid = 0;
+31:Uptime: 2h43m19s
+32:Dumping 255 MB
+33: 16 32 48 64 80 96 112 128 144 160 176 192 208 224 240
+34:---
+35:Reading symbols from /boot/kernel/snd_maestro3.ko...done.
+36:Loaded symbols for /boot/kernel/snd_maestro3.ko
+37:Reading symbols from /boot/kernel/snd_pcm.ko...done.
+38:Loaded symbols for /boot/kernel/snd_pcm.ko
+39:#0 doadump () at /usr/src/sys/kern/kern_shutdown.c:240
+40:240 dumping++;
+41:<prompt>(kgdb)</prompt> <userinput>list *0xc0713860</userinput>
+42:0xc0713860 is in lapic_ipi_wait (/usr/src/sys/i386/i386/local_apic.c:663).
+43:658 incr = 0;
+44:659 delay = 1;
+45:660 } else
+46:661 incr = 1;
+47:662 for (x = 0; x &lt; delay; x += incr) {
+48:663 if ((lapic-&gt;icr_lo &amp; APIC_DELSTAT_MASK) == APIC_DELSTAT_IDLE)
+49:664 return (1);
+50:665 ia32_pause();
+51:666 }
+52:667 return (0);
+53:<prompt>(kgdb)</prompt> <userinput>backtrace</userinput>
+54:#0 doadump () at /usr/src/sys/kern/kern_shutdown.c:240
+55:#1 0xc055fd9b in boot (howto=260) at /usr/src/sys/kern/kern_shutdown.c:372
+56:#2 0xc056019d in panic () at /usr/src/sys/kern/kern_shutdown.c:550
+57:#3 0xc0567ef5 in mi_switch () at /usr/src/sys/kern/kern_synch.c:470
+58:#4 0xc055fa87 in boot (howto=256) at /usr/src/sys/kern/kern_shutdown.c:312
+59:#5 0xc056019d in panic () at /usr/src/sys/kern/kern_shutdown.c:550
+60:#6 0xc0720c66 in trap_fatal (frame=0xdc1d0b30, eva=0)
+61: at /usr/src/sys/i386/i386/trap.c:821
+62:#7 0xc07202b3 in trap (frame=
+63: {tf_fs = -1065484264, tf_es = -1065484272, tf_ds = -1065484272, tf_edi = 1, tf_esi = 0, tf_ebp = -602076292, tf_isp = -602076324, tf_ebx = 0, tf_edx = 0, tf_ecx = 1000000, tf_eax = 243, tf_trapno = 12, tf_err = 0, tf_eip = -1066321824, tf_cs = 8, tf_eflags = 65671, tf_esp = 243, tf_ss = 0})
+64: at /usr/src/sys/i386/i386/trap.c:250
+65:#8 0xc070c9f8 in calltrap () at {standard input}:94
+66:#9 0xc07139f3 in lapic_ipi_vectored (vector=0, dest=0)
+67: at /usr/src/sys/i386/i386/local_apic.c:733
+68:#10 0xc0718b23 in ipi_selected (cpus=1, ipi=1)
+69: at /usr/src/sys/i386/i386/mp_machdep.c:1115
+70:#11 0xc057473e in kseq_notify (ke=0xcc05e360, cpu=0)
+71: at /usr/src/sys/kern/sched_ule.c:520
+72:#12 0xc0575cad in sched_add (td=0xcbcf5c80)
+73: at /usr/src/sys/kern/sched_ule.c:1366
+74:#13 0xc05666c6 in setrunqueue (td=0xcc05e360)
+75: at /usr/src/sys/kern/kern_switch.c:422
+76:#14 0xc05752f4 in sched_wakeup (td=0xcbcf5c80)
+77: at /usr/src/sys/kern/sched_ule.c:999
+78:#15 0xc056816c in setrunnable (td=0xcbcf5c80)
+79: at /usr/src/sys/kern/kern_synch.c:570
+80:#16 0xc0567d53 in wakeup (ident=0xcbcf5c80)
+81: at /usr/src/sys/kern/kern_synch.c:411
+82:#17 0xc05490a8 in exit1 (td=0xcbcf5b40, rv=0)
+83: at /usr/src/sys/kern/kern_exit.c:509
+84:#18 0xc0548011 in sys_exit () at /usr/src/sys/kern/kern_exit.c:102
+85:#19 0xc0720fd0 in syscall (frame=
+86: {tf_fs = 47, tf_es = 47, tf_ds = 47, tf_edi = 0, tf_esi = -1, tf_ebp = -1077940712, tf_isp = -602075788, tf_ebx = 672411944, tf_edx = 10, tf_ecx = 672411600, tf_eax = 1, tf_trapno = 12, tf_err = 2, tf_eip = 671899563, tf_cs = 31, tf_eflags = 642, tf_esp = -1077940740, tf_ss = 47})
+87: at /usr/src/sys/i386/i386/trap.c:1010
+88:#20 0xc070ca4d in Xint0x80_syscall () at {standard input}:136
+89:---Can't read userspace from dump, or kernel process---
+90:<prompt>(kgdb)</prompt> <userinput>quit</userinput></screen>
+
+
+ <para>This next trace is an older dump from the FreeBSD 2 time
+ frame, but is more involved and demonstrates more of the
+ features of <command>gdb</command>. Long lines have been folded
+ to improve readability, and the lines are numbered for
+ reference. Despite this, it is a real-world error trace taken
+ during the development of the pcvt console driver.</para>
+
+<screen> 1:Script started on Fri Dec 30 23:15:22 1994
+ 2:&prompt.root; <userinput>cd /sys/compile/URIAH</userinput>
+ 3:&prompt.root; <userinput>gdb -k kernel /var/crash/vmcore.1</userinput>
+ 4:Reading symbol data from /usr/src/sys/compile/URIAH/kernel
+...done.
+ 5:IdlePTD 1f3000
+ 6:panic: because you said to!
+ 7:current pcb at 1e3f70
+ 8:Reading in symbols for ../../i386/i386/machdep.c...done.
+ 9:<prompt>(kgdb)</prompt> <userinput>backtrace</userinput>
+10:#0 boot (arghowto=256) (../../i386/i386/machdep.c line 767)
+11:#1 0xf0115159 in panic ()
+12:#2 0xf01955bd in diediedie () (../../i386/i386/machdep.c line 698)
+13:#3 0xf010185e in db_fncall ()
+14:#4 0xf0101586 in db_command (-266509132, -266509516, -267381073)
+15:#5 0xf0101711 in db_command_loop ()
+16:#6 0xf01040a0 in db_trap ()
+17:#7 0xf0192976 in kdb_trap (12, 0, -272630436, -266743723)
+18:#8 0xf019d2eb in trap_fatal (...)
+19:#9 0xf019ce60 in trap_pfault (...)
+20:#10 0xf019cb2f in trap (...)
+21:#11 0xf01932a1 in exception:calltrap ()
+22:#12 0xf0191503 in cnopen (...)
+23:#13 0xf0132c34 in spec_open ()
+24:#14 0xf012d014 in vn_open ()
+25:#15 0xf012a183 in open ()
+26:#16 0xf019d4eb in syscall (...)
+27:<prompt>(kgdb)</prompt> <userinput>up 10</userinput>
+28:Reading in symbols for ../../i386/i386/trap.c...done.
+29:#10 0xf019cb2f in trap (frame={tf_es = -260440048, tf_ds = 16, tf_\
+30:edi = 3072, tf_esi = -266445372, tf_ebp = -272630356, tf_isp = -27\
+31:2630396, tf_ebx = -266427884, tf_edx = 12, tf_ecx = -266427884, tf\
+32:_eax = 64772224, tf_trapno = 12, tf_err = -272695296, tf_eip = -26\
+33:6672343, tf_cs = -266469368, tf_eflags = 66066, tf_esp = 3072, tf_\
+34:ss = -266427884}) (../../i386/i386/trap.c line 283)
+35:283 (void) trap_pfault(&amp;frame, FALSE);
+36:<prompt>(kgdb)</prompt> <userinput>frame frame-&gt;tf_ebp frame-&gt;tf_eip</userinput>
+37:Reading in symbols for ../../i386/isa/pcvt/pcvt_drv.c...done.
+38:#0 0xf01ae729 in pcopen (dev=3072, flag=3, mode=8192, p=(struct p\
+39:roc *) 0xf07c0c00) (../../i386/isa/pcvt/pcvt_drv.c line 403)
+40:403 return ((*linesw[tp-&gt;t_line].l_open)(dev, tp));
+41:<prompt>(kgdb)</prompt> <userinput>list</userinput>
+42:398
+43:399 tp-&gt;t_state |= TS_CARR_ON;
+44:400 tp-&gt;t_cflag |= CLOCAL; /* cannot be a modem (:-) */
+45:401
+46:402 #if PCVT_NETBSD || (PCVT_FREEBSD &gt;= 200)
+47:403 return ((*linesw[tp-&gt;t_line].l_open)(dev, tp));
+48:404 #else
+49:405 return ((*linesw[tp-&gt;t_line].l_open)(dev, tp, flag));
+50:406 #endif /* PCVT_NETBSD || (PCVT_FREEBSD &gt;= 200) */
+51:407 }
+52:<prompt>(kgdb)</prompt> <userinput>print tp</userinput>
+53:Reading in symbols for ../../i386/i386/cons.c...done.
+54:$1 = (struct tty *) 0x1bae
+55:<prompt>(kgdb)</prompt> <userinput>print tp-&gt;t_line</userinput>
+56:$2 = 1767990816
+57:<prompt>(kgdb)</prompt> <userinput>up</userinput>
+58:#1 0xf0191503 in cnopen (dev=0x00000000, flag=3, mode=8192, p=(st\
+59:ruct proc *) 0xf07c0c00) (../../i386/i386/cons.c line 126)
+60: return ((*cdevsw[major(dev)].d_open)(dev, flag, mode, p));
+61:<prompt>(kgdb)</prompt> <userinput>up</userinput>
+62:#2 0xf0132c34 in spec_open ()
+63:<prompt>(kgdb)</prompt> <userinput>up</userinput>
+64:#3 0xf012d014 in vn_open ()
+65:<prompt>(kgdb)</prompt> <userinput>up</userinput>
+66:#4 0xf012a183 in open ()
+67:<prompt>(kgdb)</prompt> <userinput>up</userinput>
+68:#5 0xf019d4eb in syscall (frame={tf_es = 39, tf_ds = 39, tf_edi =\
+69: 2158592, tf_esi = 0, tf_ebp = -272638436, tf_isp = -272629788, tf\
+70:_ebx = 7086, tf_edx = 1, tf_ecx = 0, tf_eax = 5, tf_trapno = 582, \
+71:tf_err = 582, tf_eip = 75749, tf_cs = 31, tf_eflags = 582, tf_esp \
+72:= -272638456, tf_ss = 39}) (../../i386/i386/trap.c line 673)
+73:673 error = (*callp-&gt;sy_call)(p, args, rval);
+74:<prompt>(kgdb)</prompt> <userinput>up</userinput>
+75:Initial frame selected; you cannot go up.
+76:<prompt>(kgdb)</prompt> <userinput>quit</userinput></screen>
+ <para>Comments to the above script:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>line 6:</term>
+
+ <listitem>
+ <para>This is a dump taken from within DDB (see below), hence the
+ panic comment <quote>because you said to!</quote>, and a rather
+ long stack trace; the initial reason for going into DDB has been a
+ page fault trap though.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>line 20:</term>
+
+ <listitem>
+ <para>This is the location of function <function>trap()</function>
+ in the stack trace.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>line 36:</term>
+
+ <listitem>
+ <para>Force usage of a new stack frame; this is no longer necessary.
+ The stack frames are supposed to point to the right
+ locations now, even in case of a trap.
+ From looking at the code in source line 403, there is a
+ high probability that either the pointer access for
+ <quote>tp</quote> was messed up, or the array access was out of
+ bounds.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>line 52:</term>
+
+ <listitem>
+ <para>The pointer looks suspicious, but happens to be a valid
+ address.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>line 56:</term>
+
+ <listitem>
+ <para>However, it obviously points to garbage, so we have found our
+ error! (For those unfamiliar with that particular piece of code:
+ <literal>tp-&gt;t_line</literal> refers to the line discipline of
+ the console device here, which must be a rather small integer
+ number.)</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <tip><para>If your system is crashing regularly and you are running
+ out of disk space, deleting old <filename>vmcore</filename>
+ files in <filename>/var/crash</filename> could save a
+ considerable amount of disk space!</para></tip>
+ </sect1>
+
+ <sect1 xml:id="kerneldebug-ddd">
+ <title>Debugging a Crash Dump with DDD</title>
+
+ <para>Examining a kernel crash dump with a graphical debugger like
+ <command>ddd</command> is also possible (you will need to install
+ the <package>devel/ddd</package> port in order to use the
+ <command>ddd</command> debugger). Add the <option>-k</option>
+ option to the <command>ddd</command> command line you would use
+ normally. For example;</para>
+
+ <screen>&prompt.root; <userinput>ddd -k /var/crash/kernel.0 /var/crash/vmcore.0</userinput></screen>
+
+ <para>You should then be able to go about looking at the crash dump using
+ <command>ddd</command>'s graphical interface.</para>
+ </sect1>
+
+ <sect1 xml:id="kerneldebug-post-mortem">
+ <title>Post-Mortem Analysis of a Dump</title>
+
+ <para>What do you do if a kernel dumped core but you did not expect it,
+ and it is therefore not compiled using <command>config -g</command>? Not
+ everything is lost here. Do not panic!</para>
+
+ <para>Of course, you still need to enable crash dumps. See above for the
+ options you have to specify in order to do this.</para>
+
+ <para>Go to your kernel config directory
+ (<filename>/usr/src/sys/arch/conf</filename>)
+ and edit your configuration file. Uncomment (or add, if it does not
+ exist) the following line:</para>
+
+ <programlisting>makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols</programlisting>
+
+ <para>Rebuild the kernel. Due to the time stamp change on the Makefile,
+ some other object files will be rebuilt, for example
+ <filename>trap.o</filename>. With a bit of luck, the added
+ <option>-g</option> option will not change anything for the generated
+ code, so you will finally get a new kernel with similar code to the
+ faulting one but with some debugging symbols. You should at least verify the
+ old and new sizes with the &man.size.1; command. If there is a
+ mismatch, you probably need to give up here.</para>
+
+ <para>Go and examine the dump as described above. The debugging symbols
+ might be incomplete for some places, as can be seen in the stack trace
+ in the example above where some functions are displayed without line
+ numbers and argument lists. If you need more debugging symbols, remove
+ the appropriate object files, recompile the kernel again and repeat the
+ <command>gdb -k</command>
+ session until you know enough.</para>
+
+ <para>All this is not guaranteed to work, but it will do it fine in most
+ cases.</para>
+ </sect1>
+
+ <sect1 xml:id="kerneldebug-online-ddb">
+ <title>On-Line Kernel Debugging Using DDB</title>
+
+ <para>While <command>gdb -k</command> as an off-line debugger provides a very
+ high level of user interface, there are some things it cannot do. The
+ most important ones being breakpointing and single-stepping kernel
+ code.</para>
+
+ <para>If you need to do low-level debugging on your kernel, there is an
+ on-line debugger available called DDB. It allows setting of
+ breakpoints, single-stepping kernel functions, examining and changing
+ kernel variables, etc. However, it cannot access kernel source files,
+ and only has access to the global and static symbols, not to the full
+ debug information like <command>gdb</command> does.</para>
+
+ <para>To configure your kernel to include DDB, add the option line
+
+ <programlisting>options DDB</programlisting>
+
+ to your config file, and rebuild. (See <link xlink:href="&url.books.handbook;/index.html">The FreeBSD Handbook</link> for details on
+ configuring the FreeBSD kernel).</para>
+
+ <note>
+ <para>If you have an older version of the boot blocks, your
+ debugger symbols might not be loaded at all. Update the boot blocks;
+ the recent ones load the DDB symbols automatically.</para>
+ </note>
+
+ <para>Once your DDB kernel is running, there are several ways to enter
+ DDB. The first, and earliest way is to type the boot flag
+ <option>-d</option> right at the boot prompt. The kernel will start up
+ in debug mode and enter DDB prior to any device probing. Hence you can
+ even debug the device probe/attach functions.</para>
+
+ <para>The second scenario is to drop to the debugger once the
+ system has booted. There are two simple ways to accomplish
+ this. If you would like to break to the debugger from the
+ command prompt, simply type the command:</para>
+
+ <screen>&prompt.root; <userinput>sysctl debug.enter_debugger=ddb</userinput></screen>
+
+ <para>Alternatively, if you are at the system console, you may use
+ a hot-key on the keyboard. The default break-to-debugger
+ sequence is <keycombo action="simul"><keycap>Ctrl</keycap>
+ <keycap>Alt</keycap><keycap>ESC</keycap></keycombo>. For
+ syscons, this sequence can be remapped and some of the
+ distributed maps out there do this, so check to make sure you
+ know the right sequence to use. There is an option available
+ for serial consoles that allows the use of a serial line BREAK on the
+ console line to enter DDB (<literal>options BREAK_TO_DEBUGGER</literal>
+ in the kernel config file). It is not the default since there are a lot
+ of serial adapters around that gratuitously generate a BREAK
+ condition, for example when pulling the cable.</para>
+
+ <para>The third way is that any panic condition will branch to DDB if the
+ kernel is configured to use it. For this reason, it is not wise to
+ configure a kernel with DDB for a machine running unattended.</para>
+
+ <para>The DDB commands roughly resemble some <command>gdb</command>
+ commands. The first thing you probably need to do is to set a
+ breakpoint:</para>
+
+ <screen><userinput>b function-name</userinput>
+<userinput>b address</userinput></screen>
+
+ <para>Numbers are taken hexadecimal by default, but to make them distinct
+ from symbol names; hexadecimal numbers starting with the letters
+ <literal>a-f</literal> need to be preceded with <literal>0x</literal>
+ (this is optional for other numbers). Simple expressions are allowed,
+ for example: <literal>function-name + 0x103</literal>.</para>
+
+ <para>To continue the operation of an interrupted kernel, simply
+ type:</para>
+
+ <screen><userinput>c</userinput></screen>
+
+ <para>To get a stack trace, use:</para>
+
+ <screen><userinput>trace</userinput></screen>
+
+ <note>
+ <para>Note that when entering DDB via a hot-key, the kernel is currently
+ servicing an interrupt, so the stack trace might be not of much use
+ to you.</para>
+ </note>
+
+ <para>If you want to remove a breakpoint, use</para>
+
+
+ <screen><userinput>del</userinput>
+<userinput>del address-expression</userinput></screen>
+
+ <para>The first form will be accepted immediately after a breakpoint hit,
+ and deletes the current breakpoint. The second form can remove any
+ breakpoint, but you need to specify the exact address; this can be
+ obtained from:</para>
+
+ <screen><userinput>show b</userinput></screen>
+
+ <para>To single-step the kernel, try:</para>
+
+ <screen><userinput>s</userinput></screen>
+
+ <para>This will step into functions, but you can make DDB trace them until
+ the matching return statement is reached by:</para>
+
+ <screen><userinput>n</userinput></screen>
+
+ <note>
+ <para>This is different from <command>gdb</command>'s
+ <command>next</command> statement; it is like <command>gdb</command>'s
+ <command>finish</command>.</para>
+ </note>
+
+ <para>To examine data from memory, use (for example):
+
+ <screen><userinput>x/wx 0xf0133fe0,40</userinput>
+<userinput>x/hd db_symtab_space</userinput>
+<userinput>x/bc termbuf,10</userinput>
+<userinput>x/s stringbuf</userinput></screen>
+
+ for word/halfword/byte access, and hexadecimal/decimal/character/ string
+ display. The number after the comma is the object count. To display
+ the next 0x10 items, simply use:</para>
+
+ <screen><userinput>x ,10</userinput></screen>
+
+ <para>Similarly, use
+
+ <screen><userinput>x/ia foofunc,10</userinput></screen>
+
+ to disassemble the first 0x10 instructions of
+ <function>foofunc</function>, and display them along with their offset
+ from the beginning of <function>foofunc</function>.</para>
+
+ <para>To modify memory, use the write command:</para>
+
+ <screen><userinput>w/b termbuf 0xa 0xb 0</userinput>
+<userinput>w/w 0xf0010030 0 0</userinput></screen>
+
+ <para>The command modifier
+ (<literal>b</literal>/<literal>h</literal>/<literal>w</literal>)
+ specifies the size of the data to be written, the first following
+ expression is the address to write to and the remainder is interpreted
+ as data to write to successive memory locations.</para>
+
+ <para>If you need to know the current registers, use:</para>
+
+ <screen><userinput>show reg</userinput></screen>
+
+ <para>Alternatively, you can display a single register value by e.g.
+
+ <screen><userinput>p $eax</userinput></screen>
+
+ and modify it by:</para>
+
+ <screen><userinput>set $eax new-value</userinput></screen>
+
+ <para>Should you need to call some kernel functions from DDB, simply
+ say:</para>
+
+ <screen><userinput>call func(arg1, arg2, ...)</userinput></screen>
+
+ <para>The return value will be printed.</para>
+
+ <para>For a &man.ps.1; style summary of all running processes, use:</para>
+
+ <screen><userinput>ps</userinput></screen>
+
+ <para>Now you have examined why your kernel failed, and you wish to
+ reboot. Remember that, depending on the severity of previous
+ malfunctioning, not all parts of the kernel might still be working as
+ expected. Perform one of the following actions to shut down and reboot
+ your system:</para>
+
+ <screen><userinput>panic</userinput></screen>
+
+ <para>This will cause your kernel to dump core and reboot, so you can
+ later analyze the core on a higher level with <command>gdb</command>. This command
+ usually must be followed by another <command>continue</command>
+ statement.</para>
+
+ <screen><userinput>call boot(0)</userinput></screen>
+
+ <para>Which might be a good way to cleanly shut down the running system,
+ <function>sync()</function> all disks, and finally reboot. As long as
+ the disk and filesystem interfaces of the kernel are not damaged, this
+ might be a good way for an almost clean shutdown.</para>
+
+ <screen><userinput>call cpu_reset()</userinput></screen>
+
+ <para>This is the final way out of disaster and almost the same as hitting the
+ Big Red Button.</para>
+
+ <para>If you need a short command summary, simply type:</para>
+
+ <screen><userinput>help</userinput></screen>
+
+ <para>However, it is highly recommended to have a printed copy of the
+ &man.ddb.4; manual page ready for a debugging
+ session. Remember that it is hard to read the on-line manual while
+ single-stepping the kernel.</para>
+ </sect1>
+
+ <sect1 xml:id="kerneldebug-online-gdb">
+ <title>On-Line Kernel Debugging Using Remote GDB</title>
+
+ <para>This feature has been supported since FreeBSD 2.2, and it is
+ actually a very neat one.</para>
+
+ <para>GDB has already supported <emphasis>remote debugging</emphasis> for
+ a long time. This is done using a very simple protocol along a serial
+ line. Unlike the other methods described above, you will need two
+ machines for doing this. One is the host providing the debugging
+ environment, including all the sources, and a copy of the kernel binary
+ with all the symbols in it, and the other one is the target machine that
+ simply runs a similar copy of the very same kernel (but stripped of the
+ debugging information).</para>
+
+ <para>You should configure the kernel in question with <command>config
+ -g</command>, include <option>DDB</option> into the configuration, and
+ compile it as usual. This gives a large binary, due to the
+ debugging information. Copy this kernel to the target machine, strip
+ the debugging symbols off with <command>strip -x</command>, and boot it
+ using the <option>-d</option> boot option. Connect the serial line
+ of the target machine that has "flags 080" set on its sio device
+ to any serial line of the debugging host.
+ Now, on the debugging machine, go to the compile directory of the target
+ kernel, and start <command>gdb</command>:</para>
+
+ <screen>&prompt.user; <userinput>gdb -k kernel</userinput>
+GDB is free software and you are welcome to distribute copies of it
+ under certain conditions; type "show copying" to see the conditions.
+There is absolutely no warranty for GDB; type "show warranty" for details.
+GDB 4.16 (i386-unknown-freebsd),
+Copyright 1996 Free Software Foundation, Inc...
+<prompt>(kgdb)</prompt> </screen>
+
+ <para>Initialize the remote debugging session (assuming the first serial
+ port is being used) by:</para>
+
+ <screen><prompt>(kgdb)</prompt> <userinput>target remote /dev/cuaa0</userinput></screen>
+
+ <para>Now, on the target host (the one that entered DDB right before even
+ starting the device probe), type:</para>
+
+ <screen>Debugger("Boot flags requested debugger")
+Stopped at Debugger+0x35: movb $0, edata+0x51bc
+<prompt>db&gt;</prompt> <userinput>gdb</userinput></screen>
+
+ <para>DDB will respond with:</para>
+
+ <screen>Next trap will enter GDB remote protocol mode</screen>
+
+ <para>Every time you type <command>gdb</command>, the mode will be toggled
+ between remote GDB and local DDB. In order to force a next trap
+ immediately, simply type <command>s</command> (step). Your hosting GDB
+ will now gain control over the target kernel:</para>
+
+ <screen>Remote debugging using /dev/cuaa0
+Debugger (msg=0xf01b0383 "Boot flags requested debugger")
+ at ../../i386/i386/db_interface.c:257
+<prompt>(kgdb)</prompt></screen>
+
+ <para>You can use this session almost as any other GDB session, including
+ full access to the source, running it in gud-mode inside an Emacs window
+ (which gives you an automatic source code display in another Emacs
+ window), etc.</para>
+ </sect1>
+
+ <sect1 xml:id="kerneldebug-kld">
+ <title>Debugging Loadable Modules Using GDB</title>
+
+ <para>When debugging a panic that occurred within a module, or
+ using remote GDB against a machine that uses dynamic modules,
+ you need to tell GDB how to obtain symbol information for those
+ modules.</para>
+
+ <para>First, you need to build the module(s) with debugging
+ information:</para>
+
+ <screen>&prompt.root; <userinput>cd /sys/modules/linux</userinput>
+&prompt.root; <userinput>make clean; make COPTS=-g</userinput></screen>
+
+ <para>If you are using remote GDB, you can run
+ <command>kldstat</command> on the target machine to find out
+ where the module was loaded:</para>
+
+ <screen>&prompt.root; <userinput>kldstat</userinput>
+Id Refs Address Size Name
+ 1 4 0xc0100000 1c1678 kernel
+ 2 1 0xc0a9e000 6000 linprocfs.ko
+ 3 1 0xc0ad7000 2000 warp_saver.ko
+ 4 1 0xc0adc000 11000 linux.ko</screen>
+
+ <para>If you are debugging a crash dump, you will need to walk the
+ <literal>linker_files</literal> list, starting at
+ <literal>linker_files-&gt;tqh_first</literal> and following the
+ <literal>link.tqe_next</literal> pointers until you find the
+ entry with the <literal>filename</literal> you are looking for.
+ The <literal>address</literal> member of that entry is the load
+ address of the module.</para>
+
+ <para>Next, you need to find out the offset of the text section
+ within the module:</para>
+
+ <screen>&prompt.root; <userinput>objdump --section-headers /sys/modules/linux/linux.ko | grep text</userinput>
+ 3 .rel.text 000016e0 000038e0 000038e0 000038e0 2**2
+ 10 .text 00007f34 000062d0 000062d0 000062d0 2**2</screen>
+
+ <para>The one you want is the <literal>.text</literal> section,
+ section 10 in the above example. The fourth hexadecimal field
+ (sixth field overall) is the offset of the text section within
+ the file. Add this offset to the load address of the module to
+ obtain the relocation address for the module's code. In our
+ example, we get 0xc0adc000 + 0x62d0 = 0xc0ae22d0. Use the
+ <command>add-symbol-file</command> command in GDB to tell the
+ debugger about the module:</para>
+
+ <screen><prompt>(kgdb)</prompt> <userinput>add-symbol-file /sys/modules/linux/linux.ko 0xc0ae22d0</userinput>
+add symbol table from file "/sys/modules/linux/linux.ko" at text_addr = 0xc0ae22d0?
+(y or n) <userinput>y</userinput>
+Reading symbols from /sys/modules/linux/linux.ko...done.
+<prompt>(kgdb)</prompt></screen>
+
+ <para>You should now have access to all the symbols in the
+ module.</para>
+ </sect1>
+
+ <sect1 xml:id="kerneldebug-console">
+ <title>Debugging a Console Driver</title>
+
+ <para>Since you need a console driver to run DDB on, things are more
+ complicated if the console driver itself is failing. You might remember
+ the use of a serial console (either with modified boot blocks, or by
+ specifying <option>-h</option> at the <prompt>Boot:</prompt> prompt),
+ and hook up a standard terminal onto your first serial port. DDB works
+ on any configured console driver, including a serial
+ console.</para>
+ </sect1>
+
+ <sect1 xml:id="kerneldebug-deadlocks">
+ <title>Debugging the Deadlocks</title>
+
+ <para>You may experience so called deadlocks, the situation where
+ system stops doing useful work. To provide the helpful bug report
+ in this situation, you shall use ddb as described above. Please,
+ include the output of <command>ps</command> and
+ <command>trace</command> for suspected processes in the
+ report.</para>
+
+ <para>If possible, consider doing further investigation. Receipt
+ below is especially useful if you suspect deadlock occurs in the
+ VFS layer. Add the options
+ <programlisting>makeoptions DEBUG=-g
+ options INVARIANTS
+ options INVARIANT_SUPPORT
+ options WITNESS
+ options DEBUG_LOCKS
+ options DEBUG_VFS_LOCKS
+ options DIAGNOSTIC</programlisting>
+
+ to the kernel config. When deadlock occurs, in addition to the
+ output of the <command>ps</command> command, provide information
+ from the <command>show allpcpu</command>, <command>show
+ alllocks</command>, <command>show lockedvnods</command> and
+ <command>show alltrace</command>.</para>
+
+ <para>For threaded processes, to obtain meaningful backtraces, use
+ <command>thread thread-id</command> to switch to the thread
+ stack, and do backtrace with <command>where</command>.</para>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/developers-handbook/l10n/chapter.xml b/zh_TW.UTF-8/books/developers-handbook/l10n/chapter.xml
new file mode 100644
index 0000000000..548fd08e3a
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/l10n/chapter.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="l10n">
+ <title>Localization and Internationalization - L10N and I18N</title>
+
+ <sect1 xml:id="l10n-programming">
+ <title>Programming I18N Compliant Applications</title>
+ <indexterm><primary>Qt</primary></indexterm>
+ <indexterm><primary>GTK</primary></indexterm>
+ <para>To make your application more useful for speakers of other
+ languages, we hope that you will program I18N compliant. The GNU
+ gcc compiler and GUI libraries like QT and GTK support I18N through
+ special handling of strings. Making a program I18N compliant is
+ very easy. It allows contributors to port your application to
+ other languages quickly. Refer to the library specific I18N
+ documentation for more details.</para>
+
+ <para>In contrast with common perception, I18N compliant code is
+ easy to write. Usually, it only involves wrapping your strings
+ with library specific functions. In addition, please be sure to
+ allow for wide or multibyte character support.</para>
+
+ <sect2>
+ <title>A Call to Unify the I18N Effort</title>
+
+ <para>It has come to our attention that the individual I18N/L10N
+ efforts for each country has been repeating each others'
+ efforts. Many of us have been reinventing the wheel repeatedly
+ and inefficiently. We hope that the various major groups in
+ I18N could congregate into a group effort similar to the Core
+ Team's responsibility.</para>
+
+ <para>Currently, we hope that, when you write or port I18N
+ programs, you would send it out to each country's related
+ FreeBSD mailing list for testing. In the future, we hope to
+ create applications that work in all the languages
+ out-of-the-box without dirty hacks.</para>
+
+ <para>The &a.i18n; has been established. If you are an I18N/L10N
+ developer, please send your comments, ideas, questions, and
+ anything you deem related to it.</para>
+ </sect2>
+
+ <sect2>
+ <title>Perl and Python</title>
+ <indexterm>
+ <primary>Perl</primary>
+ </indexterm>
+ <indexterm>
+ <primary>Python</primary>
+ </indexterm>
+
+ <para>Perl and Python have I18N and wide character handling
+ libraries. Please use them for I18N compliance.</para>
+
+ <para>In older FreeBSD versions,
+ Perl may give warnings about not having a wide character locale
+ installed on your system. You can set the
+ environment variable <envar>LD_PRELOAD</envar> to
+ <filename>/usr/lib/libxpg4.so</filename> in your shell.</para>
+
+ <para>In <literal>sh</literal>-based shells:</para>
+
+ <programlisting><envar>LD_PRELOAD=/usr/lib/libxpg4.so</envar></programlisting>
+
+ <para>In <literal>C</literal>-based shells:</para>
+
+ <programlisting><envar>setenv LD_PRELOAD /usr/lib/libxpg4.so</envar></programlisting>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/developers-handbook/policies/Makefile b/zh_TW.UTF-8/books/developers-handbook/policies/Makefile
new file mode 100644
index 0000000000..771a262e60
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/policies/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= policies/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/developers-handbook/policies/chapter.xml b/zh_TW.UTF-8/books/developers-handbook/policies/chapter.xml
new file mode 100644
index 0000000000..9dffb99394
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/policies/chapter.xml
@@ -0,0 +1,402 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="policies">
+ <info><title>Source Tree Guidelines and Policies</title>
+ <authorgroup>
+ <author><personname><firstname>Poul-Henning</firstname><surname>Kamp</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <para>This chapter documents various guidelines and policies in force for
+ the FreeBSD source tree.</para>
+
+ <sect1 xml:id="policies-maintainer">
+ <title><varname>MAINTAINER</varname> on Makefiles</title>
+ <indexterm><primary>ports maintainer</primary></indexterm>
+
+ <para>If a particular portion of the FreeBSD distribution is being
+ maintained by a person or group of persons, they can communicate this
+ fact to the world by adding a
+
+ <programlisting>MAINTAINER= email-addresses</programlisting>
+
+ line to the <filename>Makefile</filename>s covering this portion of the
+ source tree.</para>
+
+ <para>The semantics of this are as follows:</para>
+
+ <para>The maintainer owns and is responsible for that code. This means
+ that he is responsible for fixing bugs and answering problem reports
+ pertaining to that piece of the code, and in the case of contributed
+ software, for tracking new versions, as appropriate.</para>
+
+ <para>Changes to directories which have a maintainer defined shall be sent
+ to the maintainer for review before being committed. Only if the
+ maintainer does not respond for an unacceptable period of time, to
+ several emails, will it be acceptable to commit changes without review
+ by the maintainer. However, it is suggested that you try to have the
+ changes reviewed by someone else if at all possible.</para>
+
+ <para>It is of course not acceptable to add a person or group as
+ maintainer unless they agree to assume this duty. On the other hand it
+ does not have to be a committer and it can easily be a group of
+ people.</para>
+ </sect1>
+
+ <sect1 xml:id="policies-contributed">
+ <info><title>Contributed Software</title>
+ <authorgroup>
+ <author><personname><firstname>Poul-Henning</firstname><surname>Kamp</surname></personname><contrib>Contributed by </contrib></author>
+ <author><personname><firstname>David</firstname><surname>O'Brien</surname></personname></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <indexterm><primary>contributed software</primary></indexterm>
+
+ <para>Some parts of the FreeBSD distribution consist of software that is
+ actively being maintained outside the FreeBSD project. For historical
+ reasons, we call this <emphasis>contributed</emphasis> software. Some
+ examples are <application>sendmail</application>, <application>gcc</application> and <application>patch</application>.</para>
+
+ <para>Over the last couple of years, various methods have been used in
+ dealing with this type of software and all have some number of
+ advantages and drawbacks. No clear winner has emerged.</para>
+
+ <para>Since this is the case, after some debate one of these methods has
+ been selected as the <quote>official</quote> method and will be required
+ for future imports of software of this kind. Furthermore, it is
+ strongly suggested that existing contributed software converge on this
+ model over time, as it has significant advantages over the old method,
+ including the ability to easily obtain diffs relative to the
+ <quote>official</quote> versions of the source by everyone (even without
+ cvs access). This will make it significantly easier to return changes
+ to the primary developers of the contributed software.</para>
+
+ <para>Ultimately, however, it comes down to the people actually doing the
+ work. If using this model is particularly unsuited to the package being
+ dealt with, exceptions to these rules may be granted only with the
+ approval of the core team and with the general consensus of the other
+ developers. The ability to maintain the package in the future will be a
+ key issue in the decisions.</para>
+
+ <note>
+ <para>Because of some unfortunate design limitations with the RCS file
+ format and CVS's use of vendor branches, minor, trivial and/or
+ cosmetic changes are <emphasis>strongly discouraged</emphasis> on
+ files that are still tracking the vendor branch. <quote>Spelling
+ fixes</quote> are explicitly included here under the
+ <quote>cosmetic</quote> category and are to be avoided for files with
+ revision 1.1.x.x. The repository bloat impact from a single character
+ change can be rather dramatic.</para>
+ </note>
+
+ <para>The <application>Tcl</application> embedded programming
+ language will be used as example of how this model works:</para>
+
+ <para><filename>src/contrib/tcl</filename> contains the source as
+ distributed by the maintainers of this package. Parts that are entirely
+ not applicable for FreeBSD can be removed. In the case of Tcl, the
+ <filename>mac</filename>, <filename>win</filename> and
+ <filename>compat</filename> subdirectories were eliminated before the
+ import.</para>
+
+ <para><filename>src/lib/libtcl</filename> contains only a <application>bmake</application> style
+ <filename>Makefile</filename> that uses the standard
+ <filename>bsd.lib.mk</filename> makefile rules to produce the library
+ and install the documentation.</para>
+
+ <para><filename>src/usr.bin/tclsh</filename> contains only a bmake style
+ <filename>Makefile</filename> which will produce and install the
+ <command>tclsh</command> program and its associated man-pages using the
+ standard <filename>bsd.prog.mk</filename> rules.</para>
+
+ <para><filename>src/tools/tools/tcl_bmake</filename> contains a couple of
+ shell-scripts that can be of help when the tcl software needs updating.
+ These are not part of the built or installed software.</para>
+
+ <para>The important thing here is that the
+ <filename>src/contrib/tcl</filename> directory is created according to
+ the rules: it is supposed to contain the sources as distributed (on a
+ proper CVS vendor-branch and without RCS keyword expansion) with as few
+ FreeBSD-specific changes as possible. The 'easy-import' tool on
+ <systemitem>freefall</systemitem> will assist in doing the import, but if there are any doubts on
+ how to go about it, it is imperative that you ask first and not blunder
+ ahead and hope it <quote>works out</quote>. CVS is not forgiving of
+ import accidents and a fair amount of effort is required to back out
+ major mistakes.</para>
+
+ <para>Because of the previously mentioned design limitations with CVS's
+ vendor branches, it is required that <quote>official</quote> patches from
+ the vendor be applied to the original distributed sources and the result
+ re-imported onto the vendor branch again. Official patches should never
+ be patched into the FreeBSD checked out version and <quote>committed</quote>, as this
+ destroys the vendor branch coherency and makes importing future versions
+ rather difficult as there will be conflicts.</para>
+
+ <para>Since many packages contain files that are meant for compatibility
+ with other architectures and environments that FreeBSD, it is
+ permissible to remove parts of the distribution tree that are of no
+ interest to FreeBSD in order to save space. Files containing copyright
+ notices and release-note kind of information applicable to the remaining
+ files shall <emphasis>not</emphasis> be removed.</para>
+
+ <para>If it seems easier, the <command>bmake</command>
+ <filename>Makefile</filename>s can be produced from the dist tree
+ automatically by some utility, something which would hopefully make it
+ even easier to upgrade to a new version. If this is done, be sure to
+ check in such utilities (as necessary) in the
+ <filename>src/tools</filename> directory along with the port itself so
+ that it is available to future maintainers.</para>
+
+ <para>In the <filename>src/contrib/tcl</filename> level directory, a file
+ called <filename>FREEBSD-upgrade</filename> should be added and it
+ should state things like:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Which files have been left out.</para>
+ </listitem>
+
+ <listitem>
+ <para>Where the original distribution was obtained from and/or the
+ official master site.</para>
+ </listitem>
+
+ <listitem>
+ <para>Where to send patches back to the original authors.</para>
+ </listitem>
+
+ <listitem>
+ <para>Perhaps an overview of the FreeBSD-specific changes that have
+ been made.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>However, please do not import <filename>FREEBSD-upgrade</filename>
+ with the contributed source. Rather you should <command>cvs add
+ FREEBSD-upgrade ; cvs ci</command> after the initial import. Example
+ wording from <filename>src/contrib/cpio</filename> is below:</para>
+
+ <programlisting>This directory contains virgin sources of the original distribution files
+on a "vendor" branch. Do not, under any circumstances, attempt to upgrade
+the files in this directory via patches and a cvs commit. New versions or
+official-patch versions must be imported. Please remember to import with
+"-ko" to prevent CVS from corrupting any vendor RCS Ids.
+
+For the import of GNU cpio 2.4.2, the following files were removed:
+
+ INSTALL cpio.info mkdir.c
+ Makefile.in cpio.texi mkinstalldirs
+
+To upgrade to a newer version of cpio, when it is available:
+ 1. Unpack the new version into an empty directory.
+ [Do not make ANY changes to the files.]
+
+ 2. Remove the files listed above and any others that don't apply to
+ FreeBSD.
+
+ 3. Use the command:
+ cvs import -ko -m 'Virgin import of GNU cpio v&lt;version&gt;' \
+ src/contrib/cpio GNU cpio_&lt;version&gt;
+
+ For example, to do the import of version 2.4.2, I typed:
+ cvs import -ko -m 'Virgin import of GNU v2.4.2' \
+ src/contrib/cpio GNU cpio_2_4_2
+
+ 4. Follow the instructions printed out in step 3 to resolve any
+ conflicts between local FreeBSD changes and the newer version.
+
+Do not, under any circumstances, deviate from this procedure.
+
+To make local changes to cpio, simply patch and commit to the main
+branch (aka HEAD). Never make local changes on the GNU branch.
+
+All local changes should be submitted to "cpio@gnu.ai.mit.edu" for
+inclusion in the next vendor release.
+
+obrien@FreeBSD.org - 30 March 1997</programlisting>
+ </sect1>
+
+ <sect1 xml:id="policies-encumbered">
+ <title>Encumbered Files</title>
+
+ <para>It might occasionally be necessary to include an encumbered file in
+ the FreeBSD source tree. For example, if a device requires a small
+ piece of binary code to be loaded to it before the device will operate,
+ and we do not have the source to that code, then the binary file is said
+ to be encumbered. The following policies apply to including encumbered
+ files in the FreeBSD source tree.</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Any file which is interpreted or executed by the system CPU(s)
+ and not in source format is encumbered.</para>
+ </listitem>
+
+ <listitem>
+ <para>Any file with a license more restrictive than BSD or GNU is
+ encumbered.</para>
+ </listitem>
+
+ <listitem>
+ <para>A file which contains downloadable binary data for use by the
+ hardware is not encumbered, unless (1) or (2) apply to it. It must
+ be stored in an architecture neutral ASCII format (file2c or
+ uuencoding is recommended).</para>
+ </listitem>
+
+ <listitem>
+ <para>Any encumbered file requires specific approval from the
+ <link xlink:href="&url.articles.contributors;/staff-core.html">Core team</link> before it is added to the
+ CVS repository.</para>
+ </listitem>
+
+ <listitem>
+ <para>Encumbered files go in <filename>src/contrib</filename> or
+ <filename>src/sys/contrib</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para>The entire module should be kept together. There is no point in
+ splitting it, unless there is code-sharing with non-encumbered
+ code.</para>
+ </listitem>
+
+ <listitem>
+ <para>Object files are named
+ <filename>arch/filename.o.uu&gt;</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Kernel files:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Should always be referenced in
+ <filename>conf/files.*</filename> (for build simplicity).</para>
+ </listitem>
+
+ <listitem>
+ <para>Should always be in <filename>LINT</filename>, but the
+ <link xlink:href="&url.articles.contributors;/staff-core.html">Core team</link> decides per case if it
+ should be commented out or not. The
+ <link xlink:href="&url.articles.contributors;/staff-core.html">Core team</link> can, of course, change
+ their minds later on.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <firstterm>Release Engineer</firstterm>
+ decides whether or not it goes into the release.</para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+
+ <listitem>
+ <para>User-land files:</para>
+
+ <orderedlist>
+ <listitem>
+ <indexterm><primary>core team</primary></indexterm>
+ <para>The <link xlink:href="&url.articles.contributors;/staff-core.html">Core team</link> decides if
+ the code should be part of <command>make world</command>.</para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>release engineer</primary></indexterm>
+ <para>The <link xlink:href="&url.articles.contributors;/staff-who.html">Release Engineer</link>
+ decides if it goes into the release.</para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+ </orderedlist>
+ </sect1>
+
+ <sect1 xml:id="policies-shlib">
+ <info><title>Shared Libraries</title>
+ <authorgroup>
+ <author><personname><firstname>Satoshi</firstname><surname>Asami</surname></personname><contrib>Contributed by </contrib></author>
+ <author><personname><firstname>Peter</firstname><surname>Wemm</surname></personname></author>
+ <author><personname><firstname>David</firstname><surname>O'Brien</surname></personname></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <para>If you are adding shared library support to a port or other piece of
+ software that does not have one, the version numbers should follow these
+ rules. Generally, the resulting numbers will have nothing to do with
+ the release version of the software.</para>
+
+ <para>The three principles of shared library building are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Start from <literal>1.0</literal></para>
+ </listitem>
+
+ <listitem>
+ <para>If there is a change that is backwards compatible, bump minor
+ number (note that ELF systems ignore the minor number)</para>
+ </listitem>
+
+ <listitem>
+ <para>If there is an incompatible change, bump major number</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>For instance, added functions and bugfixes result in the minor
+ version number being bumped, while deleted functions, changed function
+ call syntax, etc. will force the major version number to change.</para>
+
+ <para>Stick to version numbers of the form major.minor
+ (<replaceable>x</replaceable>.<replaceable>y</replaceable>). Our a.out
+ dynamic linker does not handle version numbers of the form
+ <replaceable>x</replaceable>.<replaceable>y</replaceable>.<replaceable>z</replaceable>
+ well. Any version number after the <replaceable>y</replaceable>
+ (i.e. the third digit) is totally ignored when comparing shared lib
+ version numbers to decide which library to link with. Given two shared
+ libraries that differ only in the <quote>micro</quote> revision,
+ <command>ld.so</command> will link with the higher one. That is, if you link
+ with <filename>libfoo.so.3.3.3</filename>, the linker only records
+ <literal>3.3</literal> in the headers, and will link with anything
+ starting with
+ <replaceable>libfoo.so.3</replaceable>.<replaceable>(anything &gt;=
+ 3)</replaceable>.<replaceable>(highest
+ available)</replaceable>.</para>
+
+ <note>
+ <para><command>ld.so</command> will always use the highest
+ <quote>minor</quote> revision. For instance, it will use
+ <filename>libc.so.2.2</filename> in preference to
+ <filename>libc.so.2.0</filename>, even if the program was initially
+ linked with <filename>libc.so.2.0</filename>.</para>
+ </note>
+
+ <para>In addition, our ELF dynamic linker does not handle minor version
+ numbers at all. However, one should still specify a major and minor
+ version number as our <filename>Makefile</filename>s <quote>do the right thing</quote>
+ based on the type of system.</para>
+
+ <para>For non-port libraries, it is also our policy to change the shared
+ library version number only once between releases. In addition, it is
+ our policy to change the major shared library version number only once
+ between major OS releases (i.e. from 3.0 to 4.0). When you make a
+ change to a system library that requires the version number to be
+ bumped, check the <filename>Makefile</filename>'s commit logs. It is the
+ responsibility of the committer to ensure that the first such change
+ since the release will result in the shared library version number in
+ the <filename>Makefile</filename> to be updated, and any subsequent
+ changes will not.</para>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/developers-handbook/secure/chapter.xml b/zh_TW.UTF-8/books/developers-handbook/secure/chapter.xml
new file mode 100644
index 0000000000..e382c5fc69
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/secure/chapter.xml
@@ -0,0 +1,518 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="secure">
+ <info><title>Secure Programming</title>
+ <authorgroup>
+ <author><personname><firstname>Murray</firstname><surname>Stokely</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="secure-synopsis"><title>Synopsis</title>
+
+ <para>This chapter describes some of the security issues that
+ have plagued &unix; programmers for decades and some of the new
+ tools available to help programmers avoid writing exploitable
+ code.</para>
+ </sect1>
+
+ <sect1 xml:id="secure-philosophy"><title>Secure Design
+ Methodology</title>
+
+ <para>Writing secure applications takes a very scrutinous and
+ pessimistic outlook on life. Applications should be run with
+ the principle of <quote>least privilege</quote> so that no
+ process is ever running with more than the bare minimum access
+ that it needs to accomplish its function. Previously tested
+ code should be reused whenever possible to avoid common
+ mistakes that others may have already fixed.</para>
+
+ <para>One of the pitfalls of the &unix; environment is how easy it
+ is to make assumptions about the sanity of the environment.
+ Applications should never trust user input (in all its forms),
+ system resources, inter-process communication, or the timing of
+ events. &unix; processes do not execute synchronously so logical
+ operations are rarely atomic.</para>
+ </sect1>
+
+ <sect1 xml:id="secure-bufferov"><title>Buffer Overflows</title>
+
+ <para>Buffer Overflows have been around since the very
+ beginnings of the Von-Neuman <xref linkend="COD"/> architecture.
+
+ <indexterm><primary>buffer overflow</primary></indexterm>
+ <indexterm><primary>Von-Neuman</primary></indexterm>
+
+ They first gained widespread notoriety in 1988 with the Morris
+ Internet worm. Unfortunately, the same basic attack remains
+
+ <indexterm><primary>Morris Internet worm</primary></indexterm>
+
+ effective today. Of the 17 CERT security advisories of 1999, 10
+
+ <indexterm>
+ <primary>CERT</primary><secondary>security advisories</secondary>
+ </indexterm>
+
+ of them were directly caused by buffer-overflow software bugs.
+ By far the most common type of buffer overflow attack is based
+ on corrupting the stack.</para>
+
+ <indexterm><primary>stack</primary></indexterm>
+ <indexterm><primary>arguments</primary></indexterm>
+
+ <para>Most modern computer systems use a stack to pass arguments
+ to procedures and to store local variables. A stack is a last
+ in first out (LIFO) buffer in the high memory area of a process
+ image. When a program invokes a function a new "stack frame" is
+
+ <indexterm><primary>LIFO</primary></indexterm>
+ <indexterm>
+ <primary>process image</primary>
+ <secondary>stack pointer</secondary>
+ </indexterm>
+
+ created. This stack frame consists of the arguments passed to
+ the function as well as a dynamic amount of local variable
+ space. The "stack pointer" is a register that holds the current
+
+ <indexterm><primary>stack frame</primary></indexterm>
+ <indexterm><primary>stack pointer</primary></indexterm>
+
+ location of the top of the stack. Since this value is
+ constantly changing as new values are pushed onto the top of the
+ stack, many implementations also provide a "frame pointer" that
+ is located near the beginning of a stack frame so that local
+ variables can more easily be addressed relative to this
+ value. <xref linkend="COD"/> The return address for function
+
+ <indexterm><primary>frame pointer</primary></indexterm>
+ <indexterm>
+ <primary>process image</primary>
+ <secondary>frame pointer</secondary>
+ </indexterm>
+ <indexterm><primary>return address</primary></indexterm>
+ <indexterm><primary>stack-overflow</primary></indexterm>
+
+ calls is also stored on the stack, and this is the cause of
+ stack-overflow exploits since overflowing a local variable in a
+ function can overwrite the return address of that function,
+ potentially allowing a malicious user to execute any code he or
+ she wants.</para>
+
+ <para>Although stack-based attacks are by far the most common,
+ it would also be possible to overrun the stack with a heap-based
+ (malloc/free) attack.</para>
+
+ <para>The C programming language does not perform automatic
+ bounds checking on arrays or pointers as many other languages
+ do. In addition, the standard C library is filled with a
+ handful of very dangerous functions.</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <tbody>
+ <row><entry><function>strcpy</function>(char *dest, const char
+ *src)</entry>
+ <entry><simpara>May overflow the dest buffer</simpara></entry>
+ </row>
+
+ <row><entry><function>strcat</function>(char *dest, const char
+ *src)</entry>
+ <entry><simpara>May overflow the dest buffer</simpara></entry>
+ </row>
+
+ <row><entry><function>getwd</function>(char *buf)</entry>
+ <entry><simpara>May overflow the buf buffer</simpara></entry>
+ </row>
+
+ <row><entry><function>gets</function>(char *s)</entry>
+ <entry><simpara>May overflow the s buffer</simpara></entry>
+ </row>
+
+ <row><entry><function>[vf]scanf</function>(const char *format,
+ ...)</entry>
+ <entry><simpara>May overflow its arguments.</simpara></entry>
+ </row>
+
+ <row><entry><function>realpath</function>(char *path, char
+ resolved_path[])</entry>
+ <entry><simpara>May overflow the path buffer</simpara></entry>
+ </row>
+
+ <row><entry><function>[v]sprintf</function>(char *str, const char
+ *format, ...)</entry>
+ <entry><simpara>May overflow the str buffer.</simpara></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <sect2><title>Example Buffer Overflow</title>
+
+ <para>The following example code contains a buffer overflow
+ designed to overwrite the return address and skip the
+ instruction immediately following the function call. (Inspired
+ by <xref linkend="Phrack"/>)</para>
+
+<programlisting>#include <tag>stdio.h</tag>
+
+void manipulate(char *buffer) {
+ char newbuffer[80];
+ strcpy(newbuffer,buffer);
+}
+
+int main() {
+ char ch,buffer[4096];
+ int i=0;
+
+ while ((buffer[i++] = getchar()) != '\n') {};
+
+ i=1;
+ manipulate(buffer);
+ i=2;
+ printf("The value of i is : %d\n",i);
+ return 0;
+}</programlisting>
+
+ <para>Let us examine what the memory image of this process would
+ look like if we were to input 160 spaces into our little program
+ before hitting return.</para>
+
+ <para>[XXX figure here!]</para>
+
+ <para>Obviously more malicious input can be devised to execute
+ actual compiled instructions (such as exec(/bin/sh)).</para>
+ </sect2>
+
+ <sect2><title>Avoiding Buffer Overflows</title>
+
+ <para>The most straightforward solution to the problem of
+ stack-overflows is to always use length restricted memory and
+ string copy functions. <function>strncpy</function> and
+ <function>strncat</function> are part of the standard C library.
+
+ <indexterm>
+ <primary>string copy functions</primary>
+ <secondary>strncpy</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>string copy functions</primary>
+ <secondary>strncat</secondary>
+ </indexterm>
+
+ These functions accept a length value as a parameter which
+ should be no larger than the size of the destination buffer.
+ These functions will then copy up to `length' bytes from the
+ source to the destination. However there are a number of
+ problems with these functions. Neither function guarantees NUL
+ termination if the size of the input buffer is as large as the
+
+ <indexterm><primary>NUL termination</primary></indexterm>
+
+ destination. The length parameter is also used inconsistently
+ between strncpy and strncat so it is easy for programmers to get
+ confused as to their proper usage. There is also a significant
+ performance loss compared to <function>strcpy</function> when
+ copying a short string into a large buffer since
+ <function>strncpy</function> NUL fills up the size
+ specified.</para>
+
+ <para>In OpenBSD, another memory copy implementation has been
+
+ <indexterm><primary>OpenBSD</primary></indexterm>
+
+ created to get around these problem. The
+ <function>strlcpy</function> and <function>strlcat</function>
+ functions guarantee that they will always null terminate the
+ destination string when given a non-zero length argument. For
+ more information about these functions see <xref linkend="OpenBSD"/>. The OpenBSD <function>strlcpy</function> and
+ <function>strlcat</function> instructions have been in FreeBSD
+ since 3.3.</para>
+
+ <indexterm>
+ <primary>string copy functions</primary>
+ <secondary>strlcpy</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>string copy functions</primary>
+ <secondary>strlcat</secondary>
+ </indexterm>
+
+ <sect3><title>Compiler based run-time bounds checking</title>
+
+ <indexterm><primary>bounds checking</primary>
+ <secondary>compiler-based</secondary></indexterm>
+
+ <para>Unfortunately there is still a very large assortment of
+ code in public use which blindly copies memory around without
+ using any of the bounded copy routines we just discussed.
+ Fortunately, there is another solution. Several compiler
+ add-ons and libraries exist to do Run-time bounds checking in
+ C/C++.</para>
+
+ <indexterm><primary>StackGuard</primary></indexterm>
+ <indexterm><primary>gcc</primary></indexterm>
+
+ <para>StackGuard is one such add-on that is implemented as a
+ small patch to the gcc code generator. From the <link xlink:href="http://immunix.org/stackguard.html">StackGuard
+ website</link>:
+
+ <blockquote><para>"StackGuard detects and defeats stack
+ smashing attacks by protecting the return address on the stack
+ from being altered. StackGuard places a "canary" word next to
+ the return address when a function is called. If the canary
+ word has been altered when the function returns, then a stack
+ smashing attack has been attempted, and the program responds
+ by emitting an intruder alert into syslog, and then
+ halts."</para></blockquote>
+
+ <blockquote><para>"StackGuard is implemented as a small patch
+ to the gcc code generator, specifically the function_prolog()
+ and function_epilog() routines. function_prolog() has been
+ enhanced to lay down canaries on the stack when functions
+ start, and function_epilog() checks canary integrity when the
+ function exits. Any attempt at corrupting the return address
+ is thus detected before the function
+ returns."</para></blockquote>
+ </para>
+
+ <indexterm><primary>buffer overflow</primary></indexterm>
+
+ <para>Recompiling your application with StackGuard is an
+ effective means of stopping most buffer-overflow attacks, but
+ it can still be compromised.</para>
+
+ </sect3>
+
+ <sect3><title>Library based run-time bounds checking</title>
+
+ <indexterm>
+ <primary>bounds checking</primary>
+ <secondary>library-based</secondary>
+ </indexterm>
+
+ <para>Compiler-based mechanisms are completely useless for
+ binary-only software for which you cannot recompile. For
+ these situations there are a number of libraries which
+ re-implement the unsafe functions of the C-library
+ (<function>strcpy</function>, <function>fscanf</function>,
+ <function>getwd</function>, etc..) and ensure that these
+ functions can never write past the stack pointer.</para>
+
+ <itemizedlist>
+ <listitem><simpara>libsafe</simpara></listitem>
+ <listitem><simpara>libverify</simpara></listitem>
+ <listitem><simpara>libparanoia</simpara></listitem>
+ </itemizedlist>
+
+ <para>Unfortunately these library-based defenses have a number
+ of shortcomings. These libraries only protect against a very
+ small set of security related issues and they neglect to fix
+ the actual problem. These defenses may fail if the
+ application was compiled with -fomit-frame-pointer. Also, the
+ LD_PRELOAD and LD_LIBRARY_PATH environment variables can be
+ overwritten/unset by the user.</para>
+ </sect3>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="secure-setuid"><title>SetUID issues</title>
+
+ <indexterm><primary>seteuid</primary></indexterm>
+
+ <para>There are at least 6 different IDs associated with any
+ given process. Because of this you have to be very careful with
+ the access that your process has at any given time. In
+ particular, all seteuid applications should give up their
+ privileges as soon as it is no longer required.</para>
+
+ <indexterm>
+ <primary>user IDs</primary>
+ <secondary>real user ID</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>user IDs</primary>
+ <secondary>effective user ID</secondary>
+ </indexterm>
+
+ <para>The real user ID can only be changed by a superuser
+ process. The <application>login</application> program sets this
+ when a user initially logs in and it is seldom changed.</para>
+
+ <para>The effective user ID is set by the
+ <function>exec()</function> functions if a program has its
+ seteuid bit set. An application can call
+ <function>seteuid()</function> at any time to set the effective
+ user ID to either the real user ID or the saved set-user-ID.
+ When the effective user ID is set by <function>exec()</function>
+ functions, the previous value is saved in the saved set-user-ID.</para>
+
+ </sect1>
+
+ <sect1 xml:id="secure-chroot"><title>Limiting your program's environment</title>
+
+ <indexterm><primary>chroot()</primary></indexterm>
+
+ <para>The traditional method of restricting a process
+ is with the <function>chroot()</function> system call. This
+ system call changes the root directory from which all other
+ paths are referenced for a process and any child processes. For
+ this call to succeed the process must have execute (search)
+ permission on the directory being referenced. The new
+ environment does not actually take effect until you
+ <function>chdir()</function> into your new environment. It
+ should also be noted that a process can easily break out of a
+ chroot environment if it has root privilege. This could be
+ accomplished by creating device nodes to read kernel memory,
+ attaching a debugger to a process outside of the jail, or in
+ many other creative ways.</para>
+
+ <para>The behavior of the <function>chroot()</function> system
+ call can be controlled somewhat with the
+ kern.chroot_allow_open_directories <command>sysctl</command>
+ variable. When this value is set to 0,
+ <function>chroot()</function> will fail with EPERM if there are
+ any directories open. If set to the default value of 1, then
+ <function>chroot()</function> will fail with EPERM if there are
+ any directories open and the process is already subject to a
+ <function>chroot()</function> call. For any other value, the
+ check for open directories will be bypassed completely.</para>
+
+ <sect2><title>FreeBSD's jail functionality</title>
+
+ <indexterm><primary>jail</primary></indexterm>
+
+ <para>The concept of a Jail extends upon the
+ <function>chroot()</function> by limiting the powers of the
+ superuser to create a true `virtual server'. Once a prison is
+ set up all network communication must take place through the
+ specified IP address, and the power of "root privilege" in this
+ jail is severely constrained.</para>
+
+ <para>While in a prison, any tests of superuser power within the
+ kernel using the <function>suser()</function> call will fail.
+ However, some calls to <function>suser()</function> have been
+ changed to a new interface <function>suser_xxx()</function>.
+ This function is responsible for recognizing or denying access
+ to superuser power for imprisoned processes.</para>
+
+ <para>A superuser process within a jailed environment has the
+ power to:</para>
+
+ <itemizedlist>
+ <listitem><simpara>Manipulate credential with
+ <function>setuid</function>, <function>seteuid</function>,
+ <function>setgid</function>, <function>setegid</function>,
+ <function>setgroups</function>, <function>setreuid</function>,
+ <function>setregid</function>, <function>setlogin</function></simpara></listitem>
+ <listitem><simpara>Set resource limits with <function>setrlimit</function></simpara></listitem>
+ <listitem><simpara>Modify some sysctl nodes
+ (kern.hostname)</simpara></listitem>
+ <listitem><simpara><function>chroot()</function></simpara></listitem>
+ <listitem><simpara>Set flags on a vnode:
+ <function>chflags</function>,
+ <function>fchflags</function></simpara></listitem>
+ <listitem><simpara>Set attributes of a vnode such as file
+ permission, owner, group, size, access time, and modification
+ time.</simpara></listitem>
+ <listitem><simpara>Bind to privileged ports in the Internet
+ domain (ports &lt; 1024)</simpara></listitem>
+ </itemizedlist>
+
+ <para><function>Jail</function> is a very useful tool for
+ running applications in a secure environment but it does have
+ some shortcomings. Currently, the IPC mechanisms have not been
+ converted to the <function>suser_xxx</function> so applications
+ such as MySQL cannot be run within a jail. Superuser access
+ may have a very limited meaning within a jail, but there is
+ no way to specify exactly what "very limited" means.</para>
+ </sect2>
+
+ <sect2><title>&posix;.1e Process Capabilities</title>
+
+ <indexterm><primary>POSIX.1e Process Capabilities</primary></indexterm>
+ <indexterm><primary>TrustedBSD</primary></indexterm>
+
+ <para>&posix; has released a working draft that adds event
+ auditing, access control lists, fine grained privileges,
+ information labeling, and mandatory access control.</para>
+ <para>This is a work in progress and is the focus of the <link xlink:href="http://www.trustedbsd.org/">TrustedBSD</link> project. Some
+ of the initial work has been committed to &os.current;
+ (cap_set_proc(3)).</para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="secure-trust"><title>Trust</title>
+
+ <para>An application should never assume that anything about the
+ users environment is sane. This includes (but is certainly not
+ limited to): user input, signals, environment variables,
+ resources, IPC, mmaps, the filesystem working directory, file
+ descriptors, the # of open files, etc.</para>
+
+ <indexterm><primary>positive filtering</primary></indexterm>
+ <indexterm><primary>data validation</primary></indexterm>
+
+ <para>You should never assume that you can catch all forms of
+ invalid input that a user might supply. Instead, your
+ application should use positive filtering to only allow a
+ specific subset of inputs that you deem safe. Improper data
+ validation has been the cause of many exploits, especially with
+ CGI scripts on the world wide web. For filenames you need to be
+ extra careful about paths ("../", "/"), symbolic links, and
+ shell escape characters.</para>
+
+ <indexterm><primary>Perl Taint mode</primary></indexterm>
+
+ <para>Perl has a really cool feature called "Taint" mode which
+ can be used to prevent scripts from using data derived outside
+ the program in an unsafe way. This mode will check command line
+ arguments, environment variables, locale information, the
+ results of certain syscalls (<function>readdir()</function>,
+ <function>readlink()</function>,
+ <function>getpwxxx()</function>, and all file input.</para>
+
+ </sect1>
+
+ <sect1 xml:id="secure-race-conditions">
+ <title>Race Conditions</title>
+
+ <para>A race condition is anomalous behavior caused by the
+ unexpected dependence on the relative timing of events. In
+ other words, a programmer incorrectly assumed that a particular
+ event would always happen before another.</para>
+
+ <indexterm><primary>race conditions</primary>
+ <secondary>signals</secondary></indexterm>
+
+ <indexterm><primary>race conditions</primary>
+ <secondary>access checks</secondary></indexterm>
+
+ <indexterm><primary>race conditions</primary>
+ <secondary>file opens</secondary></indexterm>
+
+ <para>Some of the common causes of race conditions are signals,
+ access checks, and file opens. Signals are asynchronous events
+ by nature so special care must be taken in dealing with them.
+ Checking access with <function>access(2)</function> then
+ <function>open(2)</function> is clearly non-atomic. Users can
+ move files in between the two calls. Instead, privileged
+ applications should <function>seteuid()</function> and then call
+ <function>open()</function> directly. Along the same lines, an
+ application should always set a proper umask before
+ <function>open()</function> to obviate the need for spurious
+ <function>chmod()</function> calls.</para>
+
+ </sect1>
+
+ </chapter>
diff --git a/zh_TW.UTF-8/books/developers-handbook/sockets/chapter.xml b/zh_TW.UTF-8/books/developers-handbook/sockets/chapter.xml
new file mode 100644
index 0000000000..38d74e686c
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/sockets/chapter.xml
@@ -0,0 +1,1780 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="sockets">
+ <info><title>Sockets</title>
+ <authorgroup>
+ <author><personname><firstname>G. Adam</firstname><surname>Stanislav</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="sockets-synopsis">
+ <title>Synopsis</title>
+
+ <para><acronym>BSD</acronym> sockets take interprocess
+ communications to a new level. It is no longer necessary for the
+ communicating processes to run on the same machine. They still
+ <emphasis>can</emphasis>, but they do not have to.</para>
+
+ <para>Not only do these processes not have to run on the same
+ machine, they do not have to run under the same operating
+ system. Thanks to <acronym>BSD</acronym> sockets, your FreeBSD
+ software can smoothly cooperate with a program running on a
+ &macintosh;, another one running on a &sun; workstation, yet another
+ one running under &windows; 2000, all connected with an
+ Ethernet-based local area network.</para>
+
+ <para>But your software can equally well cooperate with processes
+ running in another building, or on another continent, inside a
+ submarine, or a space shuttle.</para>
+
+ <para>It can also cooperate with processes that are not part of a
+ computer (at least not in the strict sense of the word), but of
+ such devices as printers, digital cameras, medical equipment.
+ Just about anything capable of digital communications.</para>
+
+ </sect1>
+
+ <sect1 xml:id="sockets-diversity">
+ <title>Networking and Diversity</title>
+
+ <para>We have already hinted on the <emphasis>diversity</emphasis>
+ of networking. Many different systems have to talk to each
+ other. And they have to speak the same language. They also have
+ to <emphasis>understand</emphasis> the same language the same
+ way.</para>
+
+ <para>People often think that <emphasis>body language</emphasis>
+ is universal. But it is not. Back in my early teens, my father
+ took me to Bulgaria. We were sitting at a table in a park in
+ Sofia, when a vendor approached us trying to sell us some
+ roasted almonds.</para>
+
+ <para>I had not learned much Bulgarian by then, so, instead of
+ saying no, I shook my head from side to side, the
+ <quote>universal</quote> body language for
+ <emphasis>no</emphasis>. The vendor quickly started serving us
+ some almonds.</para>
+
+ <para>I then remembered I had been told that in Bulgaria shaking
+ your head sideways meant <emphasis>yes</emphasis>. Quickly, I
+ started nodding my head up and down. The vendor noticed, took
+ his almonds, and walked away. To an uninformed observer, I did
+ not change the body language: I continued using the language of
+ shaking and nodding my head. What changed was the
+ <emphasis>meaning</emphasis> of the body language. At first, the
+ vendor and I interpreted the same language as having completely
+ different meaning. I had to adjust my own interpretation of that
+ language so the vendor would understand.</para>
+
+ <para>It is the same with computers: The same symbols may have
+ different, even outright opposite meaning. Therefore, for
+ two computers to understand each other, they must not only
+ agree on the same <emphasis>language</emphasis>, but on the
+ same <emphasis>interpretation</emphasis> of the language.
+ </para>
+ </sect1>
+
+ <sect1 xml:id="sockets-protocols">
+ <title>Protocols</title>
+
+ <para>While various programming languages tend to have complex
+ syntax and use a number of multi-letter reserved words (which
+ makes them easy for the human programmer to understand), the
+ languages of data communications tend to be very terse. Instead
+ of multi-byte words, they often use individual
+ <emphasis>bits</emphasis>. There is a very convincing reason
+ for it: While data travels <emphasis>inside</emphasis> your
+ computer at speeds approaching the speed of light, it often
+ travels considerably slower between two computers.</para>
+
+ <para>Because the languages used in data communications are so
+ terse, we usually refer to them as
+ <emphasis>protocols</emphasis> rather than languages.</para>
+
+ <para>As data travels from one computer to another, it always uses
+ more than one protocol. These protocols are
+ <emphasis>layered</emphasis>. The data can be compared to the
+ inside of an onion: You have to peel off several layers of
+ <quote>skin</quote> to get to the data. This is best
+ illustrated with a picture:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="sockets/layers"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced">+----------------+
+| Ethernet |
+|+--------------+|
+|| IP ||
+||+------------+||
+||| TCP |||
+|||+----------+|||
+|||| HTTP ||||
+||||+--------+||||
+||||| PNG |||||
+|||||+------+|||||
+|||||| Data ||||||
+|||||+------+|||||
+||||+--------+||||
+|||+----------+|||
+||+------------+||
+|+--------------+|
++----------------+</literallayout>
+ </textobject>
+
+ <textobject>
+ <phrase>Protocol Layers</phrase>
+ </textobject>
+ </mediaobject>
+
+ <para>In this example, we are trying to get an image from a web
+ page we are connected to via an Ethernet.</para>
+
+ <para>The image consists of raw data, which is simply a sequence
+ of <acronym>RGB</acronym> values that our software can process,
+ i.e., convert into an image and display on our monitor.</para>
+
+ <para>Alas, our software has no way of knowing how the raw data is
+ organized: Is it a sequence of <acronym>RGB</acronym> values, or
+ a sequence of grayscale intensities, or perhaps of
+ <acronym>CMYK</acronym> encoded colors? Is the data represented
+ by 8-bit quanta, or are they 16 bits in size, or perhaps 4 bits?
+ How many rows and columns does the image consist of? Should
+ certain pixels be transparent?</para>
+
+ <para>I think you get the picture...</para>
+
+ <para>To inform our software how to handle the raw data, it is
+ encoded as a <acronym>PNG</acronym> file. It could be a
+ <acronym>GIF</acronym>, or a <acronym>JPEG</acronym>, but it is
+ a <acronym>PNG</acronym>.</para>
+
+ <para>And <acronym>PNG</acronym> is a protocol.</para>
+
+ <para>At this point, I can hear some of you yelling,
+ <emphasis><quote>No, it is not! It is a file
+ format!</quote></emphasis></para>
+
+ <para>Well, of course it is a file format. But from the
+ perspective of data communications, a file format is a protocol:
+ The file structure is a <emphasis>language</emphasis>, a terse
+ one at that, communicating to our <emphasis>process</emphasis>
+ how the data is organized. Ergo, it is a
+ <emphasis>protocol</emphasis>.</para>
+
+ <para>Alas, if all we received was the <acronym>PNG</acronym>
+ file, our software would be facing a serious problem: How is it
+ supposed to know the data is representing an image, as opposed
+ to some text, or perhaps a sound, or what not? Secondly, how is
+ it supposed to know the image is in the <acronym>PNG</acronym>
+ format as opposed to <acronym>GIF</acronym>, or
+ <acronym>JPEG</acronym>, or some other image format?</para>
+
+ <para>To obtain that information, we are using another protocol:
+ <acronym>HTTP</acronym>. This protocol can tell us exactly that
+ the data represents an image, and that it uses the
+ <acronym>PNG</acronym> protocol. It can also tell us some other
+ things, but let us stay focused on protocol layers here.
+ </para>
+
+ <para>So, now we have some data wrapped in the <acronym>PNG</acronym>
+ protocol, wrapped in the <acronym>HTTP</acronym> protocol.
+ How did we get it from the server?</para>
+
+ <para>By using <acronym>TCP/IP</acronym> over Ethernet, that is
+ how. Indeed, that is three more protocols. Instead of
+ continuing inside out, I am now going to talk about Ethernet,
+ simply because it is easier to explain the rest that way.</para>
+
+ <para>Ethernet is an interesting system of connecting computers in
+ a <emphasis>local area network</emphasis>
+ (<acronym>LAN</acronym>). Each computer has a <emphasis>network
+ interface card</emphasis> (<acronym>NIC</acronym>), which has a
+ unique 48-bit <acronym>ID</acronym> called its
+ <emphasis>address</emphasis>. No two Ethernet
+ <acronym>NIC</acronym>s in the world have the same address.
+ </para>
+
+ <para>These <acronym>NIC</acronym>s are all connected with each
+ other. Whenever one computer wants to communicate with another
+ in the same Ethernet <acronym>LAN</acronym>, it sends a message
+ over the network. Every <acronym>NIC</acronym> sees the
+ message. But as part of the Ethernet
+ <emphasis>protocol</emphasis>, the data contains the address of
+ the destination <acronym>NIC</acronym> (among other things). So,
+ only one of all the network interface cards will pay attention
+ to it, the rest will ignore it.</para>
+
+ <para>But not all computers are connected to the same
+ network. Just because we have received the data over our
+ Ethernet does not mean it originated in our own local area
+ network. It could have come to us from some other network (which
+ may not even be Ethernet based) connected with our own network
+ via the Internet.</para>
+
+ <para>All data is transferred over the Internet using
+ <acronym>IP</acronym>, which stands for <emphasis>Internet
+ Protocol</emphasis>. Its basic role is to let us know where in
+ the world the data has arrived from, and where it is supposed to
+ go to. It does not <emphasis>guarantee</emphasis> we will
+ receive the data, only that we will know where it came from
+ <emphasis>if</emphasis> we do receive it.</para>
+
+ <para>Even if we do receive the data, <acronym>IP</acronym> does
+ not guarantee we will receive various chunks of data in the same
+ order the other computer has sent it to us. So, we can receive
+ the center of our image before we receive the upper left corner
+ and after the lower right, for example.</para>
+
+ <para>It is <acronym>TCP</acronym> (<emphasis>Transmission Control
+ Protocol</emphasis>) that asks the sender to resend any lost
+ data and that places it all into the proper order.</para>
+
+ <para>All in all, it took <emphasis>five</emphasis> different
+ protocols for one computer to communicate to another what an
+ image looks like. We received the data wrapped into the
+ <acronym>PNG</acronym> protocol, which was wrapped into the
+ <acronym>HTTP</acronym> protocol, which was wrapped into the
+ <acronym>TCP</acronym> protocol, which was wrapped into the
+ <acronym>IP</acronym> protocol, which was wrapped into the
+ <acronym>Ethernet</acronym> protocol.</para>
+
+ <para>Oh, and by the way, there probably were several other
+ protocols involved somewhere on the way. For example, if our
+ <acronym>LAN</acronym> was connected to the Internet through a
+ dial-up call, it used the <acronym>PPP</acronym> protocol over
+ the modem which used one (or several) of the various modem
+ protocols, et cetera, et cetera, et cetera...</para>
+
+ <para>As a developer you should be asking by now,
+ <emphasis><quote>How am I supposed to handle it
+ all?</quote></emphasis></para>
+
+ <para>Luckily for you, you are <emphasis>not</emphasis> supposed
+ to handle it all. You <emphasis>are</emphasis> supposed to
+ handle some of it, but not all of it. Specifically, you need not
+ worry about the physical connection (in our case Ethernet and
+ possibly <acronym>PPP</acronym>, etc). Nor do you need to handle
+ the Internet Protocol, or the Transmission Control
+ Protocol.</para>
+
+ <para>In other words, you do not have to do anything to receive
+ the data from the other computer. Well, you do have to
+ <emphasis>ask</emphasis> for it, but that is almost as simple as
+ opening a file.</para>
+
+ <para>Once you have received the data, it is up to you to figure
+ out what to do with it. In our case, you would need to
+ understand the <acronym>HTTP</acronym> protocol and the
+ <acronym>PNG</acronym> file structure.</para>
+
+ <para>To use an analogy, all the internetworking protocols become
+ a gray area: Not so much because we do not understand how it
+ works, but because we are no longer concerned about it. The
+ sockets interface takes care of this gray area for us:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="sockets/slayers"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced">+----------------+
+|xxxxEthernetxxxx|
+|+--------------+|
+||xxxxxxIPxxxxxx||
+||+------------+||
+|||xxxxxTCPxxxx|||
+|||+----------+|||
+|||| HTTP ||||
+||||+--------+||||
+||||| PNG |||||
+|||||+------+|||||
+|||||| Data ||||||
+|||||+------+|||||
+||||+--------+||||
+|||+----------+|||
+||+------------+||
+|+--------------+|
++----------------+</literallayout>
+ </textobject>
+
+ <textobject>
+ <phrase>Sockets Covered Protocol Layers</phrase>
+ </textobject>
+ </mediaobject>
+
+ <para>We only need to understand any protocols that tell us how to
+ <emphasis>interpret the data</emphasis>, not how to
+ <emphasis>receive</emphasis> it from another process, nor how to
+ <emphasis>send</emphasis> it to another process.</para>
+
+ </sect1>
+
+ <sect1 xml:id="sockets-model">
+ <title>The Sockets Model</title>
+
+ <para><acronym>BSD</acronym> sockets are built on the basic &unix;
+ model: <emphasis>Everything is a file.</emphasis> In our
+ example, then, sockets would let us receive an <emphasis>HTTP
+ file</emphasis>, so to speak. It would then be up to us to
+ extract the <emphasis><acronym>PNG</acronym> file</emphasis>
+ from it.
+ </para>
+
+ <para>Because of the complexity of internetworking, we cannot just
+ use the <function role="syscall">open</function> system call, or
+ the <function>open()</function> C function. Instead, we need to
+ take several steps to <quote>opening</quote> a socket.</para>
+
+ <para>Once we do, however, we can start treating the
+ <emphasis>socket</emphasis> the same way we treat any
+ <emphasis>file descriptor</emphasis>: We can
+ <function>read</function> from it, <function>write</function> to
+ it, <function>pipe</function> it, and, eventually,
+ <function>close</function> it.</para>
+
+ </sect1>
+
+ <sect1 xml:id="sockets-essential-functions">
+ <title>Essential Socket Functions</title>
+
+ <para>While FreeBSD offers different functions to work with
+ sockets, we only <emphasis>need</emphasis> four to
+ <quote>open</quote> a socket. And in some cases we only need
+ two.</para>
+
+ <sect2 xml:id="sockets-client-server">
+ <title>The Client-Server Difference</title>
+
+ <para>Typically, one of the ends of a socket-based data
+ communication is a <emphasis>server</emphasis>, the other is a
+ <emphasis>client</emphasis>.</para>
+
+ <sect3 xml:id="sockets-common-elements">
+ <title>The Common Elements</title>
+
+ <sect4 xml:id="sockets-socket">
+ <title><function>socket</function></title>
+
+ <para>The one function used by both, clients and servers, is
+ &man.socket.2;. It is declared this way:</para>
+
+<programlisting>
+int socket(int domain, int type, int protocol);
+</programlisting>
+
+ <para>The return value is of the same type as that of
+ <function>open</function>, an integer. FreeBSD allocates
+ its value from the same pool as that of file handles.
+ That is what allows sockets to be treated the same way as
+ files.</para>
+
+ <para>The <varname>domain</varname> argument tells the
+ system what <emphasis>protocol family</emphasis> you want
+ it to use. Many of them exist, some are vendor specific,
+ others are very common. They are declared in
+ <filename>sys/socket.h</filename>.</para>
+
+ <para>Use <constant>PF_INET</constant> for
+ <acronym>UDP</acronym>, <acronym>TCP</acronym> and other
+ Internet protocols (<acronym>IP</acronym>v4).</para>
+
+ <para>Five values are defined for the
+ <varname>type</varname> argument, again, in
+ <filename>sys/socket.h</filename>. All of them start with
+ <quote><constant>SOCK_</constant></quote>. The most
+ common one is <constant>SOCK_STREAM</constant>, which
+ tells the system you are asking for a <emphasis>reliable
+ stream delivery service</emphasis> (which is
+ <acronym>TCP</acronym> when used with
+ <constant>PF_INET</constant>).</para>
+
+ <para>If you asked for <constant>SOCK_DGRAM</constant>, you
+ would be requesting a <emphasis>connectionless datagram
+ delivery service</emphasis> (in our case,
+ <acronym>UDP</acronym>).</para>
+
+ <para>If you wanted to be in charge of the low-level
+ protocols (such as <acronym>IP</acronym>), or even network
+ interfaces (e.g., the Ethernet), you would need to specify
+ <constant>SOCK_RAW</constant>.</para>
+
+ <para>Finally, the <varname>protocol</varname> argument
+ depends on the previous two arguments, and is not always
+ meaningful. In that case, use <constant>0</constant> for
+ its value.</para>
+
+ <note xml:id="sockets-unconnected">
+ <title>The Unconnected Socket</title>
+
+ <para>Nowhere, in the <function>socket</function> function
+ have we specified to what other system we should be
+ connected. Our newly created socket remains
+ <emphasis>unconnected</emphasis>.</para>
+
+ <para>This is on purpose: To use a telephone analogy, we
+ have just attached a modem to the phone line. We have
+ neither told the modem to make a call, nor to answer if
+ the phone rings.</para>
+ </note>
+
+ </sect4>
+
+ <sect4 xml:id="sockets-sockaddr">
+ <title><varname>sockaddr</varname></title>
+
+ <para>Various functions of the sockets family expect the
+ address of (or pointer to, to use C terminology) a small
+ area of the memory. The various C declarations in the
+ <filename>sys/socket.h</filename> refer to it as
+ <varname>struct sockaddr</varname>. This structure is
+ declared in the same file:</para>
+
+<programlisting>
+/*
+ * Structure used by kernel to store most
+ * addresses.
+ */
+struct sockaddr {
+ unsigned char sa_len; /* total length */
+ sa_family_t sa_family; /* address family */
+ char sa_data[14]; /* actually longer; address value */
+};
+#define SOCK_MAXADDRLEN 255 /* longest possible addresses */
+</programlisting>
+
+ <para>Please note the <emphasis>vagueness</emphasis> with
+ which the <varname>sa_data</varname> field is declared,
+ just as an array of <constant>14</constant> bytes, with
+ the comment hinting there can be more than
+ <constant>14</constant> of them.</para>
+
+ <para>This vagueness is quite deliberate. Sockets is a very
+ powerful interface. While most people perhaps think of it
+ as nothing more than the Internet interface&mdash;and most
+ applications probably use it for that
+ nowadays&mdash;sockets can be used for just about
+ <emphasis>any</emphasis> kind of interprocess
+ communications, of which the Internet (or, more precisely,
+ <acronym>IP</acronym>) is only one.</para>
+
+ <para>The <filename>sys/socket.h</filename> refers to the
+ various types of protocols sockets will handle as
+ <emphasis>address families</emphasis>, and lists them
+ right before the definition of
+ <varname>sockaddr</varname>:</para>
+
+<programlisting>
+/*
+ * Address families.
+ */
+#define AF_UNSPEC 0 /* unspecified */
+#define AF_LOCAL 1 /* local to host (pipes, portals) */
+#define AF_UNIX AF_LOCAL /* backward compatibility */
+#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
+#define AF_IMPLINK 3 /* arpanet imp addresses */
+#define AF_PUP 4 /* pup protocols: e.g. BSP */
+#define AF_CHAOS 5 /* mit CHAOS protocols */
+#define AF_NS 6 /* XEROX NS protocols */
+#define AF_ISO 7 /* ISO protocols */
+#define AF_OSI AF_ISO
+#define AF_ECMA 8 /* European computer manufacturers */
+#define AF_DATAKIT 9 /* datakit protocols */
+#define AF_CCITT 10 /* CCITT protocols, X.25 etc */
+#define AF_SNA 11 /* IBM SNA */
+#define AF_DECnet 12 /* DECnet */
+#define AF_DLI 13 /* DEC Direct data link interface */
+#define AF_LAT 14 /* LAT */
+#define AF_HYLINK 15 /* NSC Hyperchannel */
+#define AF_APPLETALK 16 /* Apple Talk */
+#define AF_ROUTE 17 /* Internal Routing Protocol */
+#define AF_LINK 18 /* Link layer interface */
+#define pseudo_AF_XTP 19 /* eXpress Transfer Protocol (no AF) */
+#define AF_COIP 20 /* connection-oriented IP, aka ST II */
+#define AF_CNT 21 /* Computer Network Technology */
+#define pseudo_AF_RTIP 22 /* Help Identify RTIP packets */
+#define AF_IPX 23 /* Novell Internet Protocol */
+#define AF_SIP 24 /* Simple Internet Protocol */
+#define pseudo_AF_PIP 25 /* Help Identify PIP packets */
+#define AF_ISDN 26 /* Integrated Services Digital Network*/
+#define AF_E164 AF_ISDN /* CCITT E.164 recommendation */
+#define pseudo_AF_KEY 27 /* Internal key-management function */
+#define AF_INET6 28 /* IPv6 */
+#define AF_NATM 29 /* native ATM access */
+#define AF_ATM 30 /* ATM */
+#define pseudo_AF_HDRCMPLT 31 /* Used by BPF to not rewrite headers
+ * in interface output routine
+ */
+#define AF_NETGRAPH 32 /* Netgraph sockets */
+#define AF_SLOW 33 /* 802.3ad slow protocol */
+#define AF_SCLUSTER 34 /* Sitara cluster protocol */
+#define AF_ARP 35
+#define AF_BLUETOOTH 36 /* Bluetooth sockets */
+#define AF_MAX 37
+
+</programlisting>
+
+ <para>The one used for <acronym>IP</acronym> is
+ <symbol>AF_INET</symbol>. It is a symbol for the constant
+ <constant>2</constant>.</para>
+
+ <para>It is the <emphasis>address family</emphasis> listed
+ in the <varname>sa_family</varname> field of
+ <varname>sockaddr</varname> that decides how exactly the
+ vaguely named bytes of <varname>sa_data</varname> will be
+ used.</para>
+
+ <para>Specifically, whenever the <emphasis>address
+ family</emphasis> is <symbol>AF_INET</symbol>, we can use
+ <varname>struct sockaddr_in</varname> found in
+ <filename>netinet/in.h</filename>, wherever
+ <varname>sockaddr</varname> is expected:</para>
+
+<programlisting>
+/*
+ * Socket address, internet style.
+ */
+struct sockaddr_in {
+ uint8_t sin_len;
+ sa_family_t sin_family;
+ in_port_t sin_port;
+ struct in_addr sin_addr;
+ char sin_zero[8];
+};
+</programlisting>
+
+ <para>We can visualize its organization this way:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="sockets/sain"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced"> 0 1 2 3
+ +--------+--------+-----------------+
+ 0 | 0 | Family | Port |
+ +--------+--------+-----------------+
+ 4 | IP Address |
+ +-----------------------------------+
+ 8 | 0 |
+ +-----------------------------------+
+12 | 0 |
+ +-----------------------------------+</literallayout>
+ </textobject>
+
+ <textobject>
+ <phrase>sockaddr_in</phrase>
+ </textobject>
+ </mediaobject>
+
+ <para>The three important fields are
+ <varname>sin_family</varname>, which is byte 1 of the
+ structure, <varname>sin_port</varname>, a 16-bit value
+ found in bytes 2 and 3, and <varname>sin_addr</varname>, a
+ 32-bit integer representation of the <acronym>IP</acronym>
+ address, stored in bytes 4-7.</para>
+
+ <para>Now, let us try to fill it out. Let us assume we are
+ trying to write a client for the
+ <emphasis>daytime</emphasis> protocol, which simply states
+ that its server will write a text string representing the
+ current date and time to port 13. We want to use
+ <acronym>TCP/IP</acronym>, so we need to specify
+ <constant>AF_INET</constant> in the address family
+ field. <constant>AF_INET</constant> is defined as
+ <constant>2</constant>. Let us use the
+ <acronym>IP</acronym> address of <systemitem class="ipaddress">192.43.244.18</systemitem>, which is the time
+ server of US federal government (<systemitem class="fqdomainname">time.nist.gov</systemitem>).</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="sockets/sainfill"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced"> 0 1 2 3
+ +--------+--------+-----------------+
+ 0 | 0 | 2 | 13 |
+ +-----------------+-----------------+
+ 4 | 192.43.244.18 |
+ +-----------------------------------+
+ 8 | 0 |
+ +-----------------------------------+
+12 | 0 |
+ +-----------------------------------+</literallayout>
+ </textobject>
+
+ <textobject>
+ <phrase>Specific example of sockaddr_in</phrase>
+ </textobject>
+ </mediaobject>
+
+ <para>By the way the <varname>sin_addr</varname> field is
+ declared as being of the <varname>struct in_addr</varname>
+ type, which is defined in
+ <filename>netinet/in.h</filename>:</para>
+
+<programlisting>
+/*
+ * Internet address (a structure for historical reasons)
+ */
+struct in_addr {
+ in_addr_t s_addr;
+};
+</programlisting>
+
+ <para>In addition, <varname>in_addr_t</varname> is a 32-bit
+ integer.</para>
+
+ <para>The <systemitem class="ipaddress">192.43.244.18</systemitem> is
+ just a convenient notation of expressing a 32-bit integer
+ by listing all of its 8-bit bytes, starting with the
+ <emphasis>most significant</emphasis> one.</para>
+
+ <para>So far, we have viewed <varname>sockaddr</varname> as
+ an abstraction. Our computer does not store
+ <varname>short</varname> integers as a single 16-bit
+ entity, but as a sequence of 2 bytes. Similarly, it stores
+ 32-bit integers as a sequence of 4 bytes.</para>
+
+ <para>Suppose we coded something like this:</para>
+
+<programlisting>
+ sa.sin_family = AF_INET;
+ sa.sin_port = 13;
+ sa.sin_addr.s_addr = (((((192 &lt;&lt; 8) | 43) &lt;&lt; 8) | 244) &lt;&lt; 8) | 18;
+</programlisting>
+
+ <para>What would the result look like?</para>
+
+ <para>Well, that depends, of course. On a &pentium;, or other
+ x86, based computer, it would look like this:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="sockets/sainlsb"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced"> 0 1 2 3
+ +--------+--------+--------+--------+
+ 0 | 0 | 2 | 13 | 0 |
+ +--------+--------+--------+--------+
+ 4 | 18 | 244 | 43 | 192 |
+ +-----------------------------------+
+ 8 | 0 |
+ +-----------------------------------+
+12 | 0 |
+ +-----------------------------------+</literallayout>
+ </textobject>
+
+ <textobject>
+ <phrase>sockaddr_in on an Intel system</phrase>
+ </textobject>
+ </mediaobject>
+
+ <para>On a different system, it might look like this:
+ </para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="sockets/sainmsb"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced"> 0 1 2 3
+ +--------+--------+--------+--------+
+ 0 | 0 | 2 | 0 | 13 |
+ +--------+--------+--------+--------+
+ 4 | 192 | 43 | 244 | 18 |
+ +-----------------------------------+
+ 8 | 0 |
+ +-----------------------------------+
+12 | 0 |
+ +-----------------------------------+</literallayout>
+ </textobject>
+
+ <textobject>
+ <phrase>sockaddr_in on an MSB system</phrase>
+ </textobject>
+ </mediaobject>
+
+ <para>And on a PDP it might look different yet. But the
+ above two are the most common ways in use today.</para>
+
+ <para>Ordinarily, wanting to write portable code,
+ programmers pretend that these differences do not
+ exist. And they get away with it (except when they code in
+ assembly language). Alas, you cannot get away with it that
+ easily when coding for sockets.</para>
+
+ <para>Why?</para>
+
+ <para>Because when communicating with another computer, you
+ usually do not know whether it stores data <emphasis>most
+ significant byte</emphasis> (<acronym>MSB</acronym>) or
+ <emphasis>least significant byte</emphasis>
+ (<acronym>LSB</acronym>) first.</para>
+
+ <para>You might be wondering, <emphasis><quote>So, will
+ sockets not handle it for me?</quote></emphasis></para>
+
+ <para>It will not.</para>
+
+ <para>While that answer may surprise you at first, remember
+ that the general sockets interface only understands the
+ <varname>sa_len</varname> and <varname>sa_family</varname>
+ fields of the <varname>sockaddr</varname> structure. You
+ do not have to worry about the byte order there (of
+ course, on FreeBSD <varname>sa_family</varname> is only 1
+ byte anyway, but many other &unix; systems do not have
+ <varname>sa_len</varname> and use 2 bytes for
+ <varname>sa_family</varname>, and expect the data in
+ whatever order is native to the computer).</para>
+
+ <para>But the rest of the data is just
+ <varname>sa_data[14]</varname> as far as sockets
+ goes. Depending on the <emphasis>address
+ family</emphasis>, sockets just forwards that data to its
+ destination.</para>
+
+ <para>Indeed, when we enter a port number, it is because we
+ want the other computer to know what service we are asking
+ for. And, when we are the server, we read the port number
+ so we know what service the other computer is expecting
+ from us. Either way, sockets only has to forward the port
+ number as data. It does not interpret it in any way.</para>
+
+ <para>Similarly, we enter the <acronym>IP</acronym> address
+ to tell everyone on the way where to send our data
+ to. Sockets, again, only forwards it as data.</para>
+
+ <para>That is why, we (the <emphasis>programmers</emphasis>,
+ not the <emphasis>sockets</emphasis>) have to distinguish
+ between the byte order used by our computer and a
+ conventional byte order to send the data in to the other
+ computer.</para>
+
+ <para>We will call the byte order our computer uses the
+ <emphasis>host byte order</emphasis>, or just the
+ <emphasis>host order</emphasis>.</para>
+
+ <para>There is a convention of sending the multi-byte data
+ over <acronym>IP</acronym>
+ <emphasis><acronym>MSB</acronym> first</emphasis>. This,
+ we will refer to as the <emphasis>network byte
+ order</emphasis>, or simply the <emphasis>network
+ order</emphasis>.</para>
+
+ <para>Now, if we compiled the above code for an Intel based
+ computer, our <emphasis>host byte order</emphasis> would
+ produce:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="sockets/sainlsb"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced"> 0 1 2 3
+ +--------+--------+--------+--------+
+ 0 | 0 | 2 | 13 | 0 |
+ +--------+--------+--------+--------+
+ 4 | 18 | 244 | 43 | 192 |
+ +-----------------------------------+
+ 8 | 0 |
+ +-----------------------------------+
+12 | 0 |
+ +-----------------------------------+</literallayout>
+ </textobject>
+
+ <textobject>
+ <phrase>Host byte order on an Intel system</phrase>
+ </textobject>
+ </mediaobject>
+
+ <para>But the <emphasis>network byte order</emphasis>
+ requires that we store the data <acronym>MSB</acronym>
+ first:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="sockets/sainmsb"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced"> 0 1 2 3
+ +--------+--------+--------+--------+
+ 0 | 0 | 2 | 0 | 13 |
+ +--------+--------+--------+--------+
+ 4 | 192 | 43 | 244 | 18 |
+ +-----------------------------------+
+ 8 | 0 |
+ +-----------------------------------+
+12 | 0 |
+ +-----------------------------------+</literallayout>
+ </textobject>
+
+ <textobject>
+ <phrase>Network byte order</phrase>
+ </textobject>
+ </mediaobject>
+
+ <para>Unfortunately, our <emphasis>host order</emphasis> is
+ the exact opposite of the <emphasis>network
+ order</emphasis>.</para>
+
+ <para>We have several ways of dealing with it. One would be
+ to <emphasis>reverse</emphasis> the values in our code:
+ </para>
+
+<programlisting>
+ sa.sin_family = AF_INET;
+ sa.sin_port = 13 &lt;&lt; 8;
+ sa.sin_addr.s_addr = (((((18 &lt;&lt; 8) | 244) &lt;&lt; 8) | 43) &lt;&lt; 8) | 192;
+</programlisting>
+
+ <para>This will <emphasis>trick</emphasis> our compiler
+ into storing the data in the <emphasis>network byte
+ order</emphasis>. In some cases, this is exactly the way
+ to do it (e.g., when programming in assembly
+ language). In most cases, however, it can cause a
+ problem.</para>
+
+ <para>Suppose, you wrote a sockets-based program in C. You
+ know it is going to run on a &pentium;, so you enter all
+ your constants in reverse and force them to the
+ <emphasis>network byte order</emphasis>. It works
+ well.</para>
+
+ <para>Then, some day, your trusted old &pentium; becomes a
+ rusty old &pentium;. You replace it with a system whose
+ <emphasis>host order</emphasis> is the same as the
+ <emphasis>network order</emphasis>. You need to recompile
+ all your software. All of your software continues to
+ perform well, except the one program you wrote.</para>
+
+ <para>You have since forgotten that you had forced all of
+ your constants to the opposite of the <emphasis>host
+ order</emphasis>. You spend some quality time tearing out
+ your hair, calling the names of all gods you ever heard
+ of (and some you made up), hitting your monitor with a
+ nerf bat, and performing all the other traditional
+ ceremonies of trying to figure out why something that has
+ worked so well is suddenly not working at all.</para>
+
+ <para>Eventually, you figure it out, say a couple of swear
+ words, and start rewriting your code.</para>
+
+ <para>Luckily, you are not the first one to face the
+ problem. Someone else has created the &man.htons.3; and
+ &man.htonl.3; C functions to convert a
+ <varname>short</varname> and <varname>long</varname>
+ respectively from the <emphasis>host byte
+ order</emphasis> to the <emphasis>network byte
+ order</emphasis>, and the &man.ntohs.3; and &man.ntohl.3;
+ C functions to go the other way.</para>
+
+ <para>On <emphasis><acronym>MSB</acronym>-first</emphasis>
+ systems these functions do nothing. On
+ <emphasis><acronym>LSB</acronym>-first</emphasis> systems
+ they convert values to the proper order.</para>
+
+ <para>So, regardless of what system your software is
+ compiled on, your data will end up in the correct order
+ if you use these functions.</para>
+
+ </sect4>
+
+ </sect3>
+
+ <sect3 xml:id="sockets-client-functions">
+ <title>Client Functions</title>
+
+ <para>Typically, the client initiates the connection to the
+ server. The client knows which server it is about to call:
+ It knows its <acronym>IP</acronym> address, and it knows the
+ <emphasis>port</emphasis> the server resides at. It is akin
+ to you picking up the phone and dialing the number (the
+ <emphasis>address</emphasis>), then, after someone answers,
+ asking for the person in charge of wingdings (the
+ <emphasis>port</emphasis>).</para>
+
+ <sect4 xml:id="sockets-connect">
+ <title><function>connect</function></title>
+
+ <para>Once a client has created a socket, it needs to
+ connect it to a specific port on a remote system. It uses
+ &man.connect.2;:</para>
+
+<programlisting>
+int connect(int s, const struct sockaddr *name, socklen_t namelen);
+</programlisting>
+
+ <para>The <varname>s</varname> argument is the socket, i.e.,
+ the value returned by the <function>socket</function>
+ function. The <varname>name</varname> is a pointer to
+ <varname>sockaddr</varname>, the structure we have talked
+ about extensively. Finally, <varname>namelen</varname>
+ informs the system how many bytes are in our
+ <varname>sockaddr</varname> structure.</para>
+
+ <para>If <function>connect</function> is successful, it
+ returns <constant>0</constant>. Otherwise it returns
+ <constant>-1</constant> and stores the error code in
+ <varname>errno</varname>.</para>
+
+ <para>There are many reasons why
+ <function>connect</function> may fail. For example, with
+ an attempt to an Internet connection, the
+ <acronym>IP</acronym> address may not exist, or it may be
+ down, or just too busy, or it may not have a server
+ listening at the specified port. Or it may outright
+ <emphasis>refuse</emphasis> any request for specific
+ code.</para>
+
+ </sect4>
+
+ <sect4 xml:id="sockets-first-client">
+ <title>Our First Client</title>
+
+ <para>We now know enough to write a very simple client, one
+ that will get current time from <systemitem class="ipaddress">192.43.244.18</systemitem> and print it to
+ <filename>stdout</filename>.</para>
+
+<programlisting>
+/*
+ * daytime.c
+ *
+ * Programmed by G. Adam Stanislav
+ */
+#include &lt;stdio.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;sys/socket.h&gt;
+#include &lt;netinet/in.h&gt;
+
+int main() {
+ register int s;
+ register int bytes;
+ struct sockaddr_in sa;
+ char buffer[BUFSIZ+1];
+
+ if ((s = socket(PF_INET, SOCK_STREAM, 0)) &lt; 0) {
+ perror("socket");
+ return 1;
+ }
+
+ bzero(&amp;sa, sizeof sa);
+
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons(13);
+ sa.sin_addr.s_addr = htonl((((((192 &lt;&lt; 8) | 43) &lt;&lt; 8) | 244) &lt;&lt; 8) | 18);
+ if (connect(s, (struct sockaddr *)&amp;sa, sizeof sa) &lt; 0) {
+ perror("connect");
+ close(s);
+ return 2;
+ }
+
+ while ((bytes = read(s, buffer, BUFSIZ)) &gt; 0)
+ write(1, buffer, bytes);
+
+ close(s);
+ return 0;
+}
+</programlisting>
+
+ <para>Go ahead, enter it in your editor, save it as
+ <filename>daytime.c</filename>, then compile and run
+ it:</para>
+
+<screen>&prompt.user; <userinput>cc -O3 -o daytime daytime.c</userinput>
+&prompt.user; <userinput>./daytime</userinput>
+
+52079 01-06-19 02:29:25 50 0 1 543.9 UTC(NIST) *
+&prompt.user;</screen>
+
+ <para>In this case, the date was June 19, 2001, the time was
+ 02:29:25 <acronym>UTC</acronym>. Naturally, your results
+ will vary.</para>
+
+ </sect4>
+
+ </sect3>
+
+ <sect3 xml:id="sockets-server-functions">
+ <title>Server Functions</title>
+
+ <para>The typical server does not initiate the
+ connection. Instead, it waits for a client to call it and
+ request services. It does not know when the client will
+ call, nor how many clients will call. It may be just sitting
+ there, waiting patiently, one moment, The next moment, it
+ can find itself swamped with requests from a number of
+ clients, all calling in at the same time.</para>
+
+ <para>The sockets interface offers three basic functions to
+ handle this.</para>
+
+ <sect4 xml:id="sockets-bind">
+ <title><function>bind</function></title>
+
+ <para>Ports are like extensions to a phone line: After you
+ dial a number, you dial the extension to get to a specific
+ person or department.</para>
+
+ <para>There are 65535 <acronym>IP</acronym> ports, but a
+ server usually processes requests that come in on only one
+ of them. It is like telling the phone room operator that
+ we are now at work and available to answer the phone at a
+ specific extension. We use &man.bind.2; to tell sockets
+ which port we want to serve.</para>
+
+<programlisting>
+int bind(int s, const struct sockaddr *addr, socklen_t addrlen);
+</programlisting>
+
+ <para>Beside specifying the port in <varname>addr</varname>,
+ the server may include its <acronym>IP</acronym>
+ address. However, it can just use the symbolic constant
+ <symbol>INADDR_ANY</symbol> to indicate it will serve all
+ requests to the specified port regardless of what its
+ <acronym>IP</acronym> address is. This symbol, along with
+ several similar ones, is declared in
+ <filename>netinet/in.h</filename></para>
+
+<programlisting>
+#define INADDR_ANY (u_int32_t)0x00000000
+</programlisting>
+
+ <para>Suppose we were writing a server for the
+ <emphasis>daytime</emphasis> protocol over
+ <acronym>TCP</acronym>/<acronym>IP</acronym>. Recall that
+ it uses port 13. Our <varname>sockaddr_in</varname>
+ structure would look like this:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="sockets/sainserv"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced"> 0 1 2 3
+ +--------+--------+--------+--------+
+ 0 | 0 | 2 | 0 | 13 |
+ +--------+--------+--------+--------+
+ 4 | 0 |
+ +-----------------------------------+
+ 8 | 0 |
+ +-----------------------------------+
+12 | 0 |
+ +-----------------------------------+</literallayout>
+ </textobject>
+
+ <textobject>
+ <phrase>Example Server sockaddr_in</phrase>
+ </textobject>
+ </mediaobject>
+ </sect4>
+
+ <sect4 xml:id="sockets-listen">
+ <title><function>listen</function></title>
+
+ <para>To continue our office phone analogy, after you have
+ told the phone central operator what extension you will be
+ at, you now walk into your office, and make sure your own
+ phone is plugged in and the ringer is turned on. Plus, you
+ make sure your call waiting is activated, so you can hear
+ the phone ring even while you are talking to someone.</para>
+
+ <para>The server ensures all of that with the &man.listen.2;
+ function.</para>
+
+<programlisting>
+int listen(int s, int backlog);
+</programlisting>
+
+ <para>In here, the <varname>backlog</varname> variable tells
+ sockets how many incoming requests to accept while you are
+ busy processing the last request. In other words, it
+ determines the maximum size of the queue of pending
+ connections.</para>
+
+ </sect4>
+
+ <sect4 xml:id="sockets-accept">
+ <title><function>accept</function></title>
+
+ <para>After you hear the phone ringing, you accept the call
+ by answering the call. You have now established a
+ connection with your client. This connection remains
+ active until either you or your client hang up.</para>
+
+ <para>The server accepts the connection by using the
+ &man.accept.2; function.</para>
+
+<programlisting>
+int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
+</programlisting>
+
+ <para>Note that this time <varname>addrlen</varname> is a
+ pointer. This is necessary because in this case it is the
+ socket that fills out <varname>addr</varname>, the
+ <varname>sockaddr_in</varname> structure.</para>
+
+ <para>The return value is an integer. Indeed, the
+ <function>accept</function> returns a <emphasis>new
+ socket</emphasis>. You will use this new socket to
+ communicate with the client.</para>
+
+ <para>What happens to the old socket? It continues to listen
+ for more requests (remember the <varname>backlog</varname>
+ variable we passed to <function>listen</function>?) until
+ we <function>close</function> it.</para>
+
+ <para>Now, the new socket is meant only for
+ communications. It is fully connected. We cannot pass it
+ to <function>listen</function> again, trying to accept
+ additional connections.</para>
+
+ </sect4>
+
+ <sect4 xml:id="sockets-first-server">
+ <title>Our First Server</title>
+
+ <para>Our first server will be somewhat more complex than
+ our first client was: Not only do we have more sockets
+ functions to use, but we need to write it as a
+ daemon.</para>
+
+ <para>This is best achieved by creating a <emphasis>child
+ process</emphasis> after binding the port. The main
+ process then exits and returns control to the
+ <application>shell</application> (or whatever program
+ invoked it).</para>
+
+ <para>The child calls <function>listen</function>, then
+ starts an endless loop, which accepts a connection, serves
+ it, and eventually closes its socket.</para>
+
+<programlisting>
+/*
+ * daytimed - a port 13 server
+ *
+ * Programmed by G. Adam Stanislav
+ * June 19, 2001
+ */
+#include &lt;stdio.h&gt;
+#include &lt;time.h&gt;
+#include &lt;unistd.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;sys/socket.h&gt;
+#include &lt;netinet/in.h&gt;
+
+#define BACKLOG 4
+
+int main() {
+ register int s, c;
+ int b;
+ struct sockaddr_in sa;
+ time_t t;
+ struct tm *tm;
+ FILE *client;
+
+ if ((s = socket(PF_INET, SOCK_STREAM, 0)) &lt; 0) {
+ perror("socket");
+ return 1;
+ }
+
+ bzero(&amp;sa, sizeof sa);
+
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons(13);
+
+ if (INADDR_ANY)
+ sa.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ if (bind(s, (struct sockaddr *)&amp;sa, sizeof sa) &lt; 0) {
+ perror("bind");
+ return 2;
+ }
+
+ switch (fork()) {
+ case -1:
+ perror("fork");
+ return 3;
+ break;
+ default:
+ close(s);
+ return 0;
+ break;
+ case 0:
+ break;
+ }
+
+ listen(s, BACKLOG);
+
+ for (;;) {
+ b = sizeof sa;
+
+ if ((c = accept(s, (struct sockaddr *)&amp;sa, &amp;b)) &lt; 0) {
+ perror("daytimed accept");
+ return 4;
+ }
+
+ if ((client = fdopen(c, "w")) == NULL) {
+ perror("daytimed fdopen");
+ return 5;
+ }
+
+ if ((t = time(NULL)) &lt; 0) {
+ perror("daytimed time");
+
+ return 6;
+ }
+
+ tm = gmtime(&amp;t);
+ fprintf(client, "%.4i-%.2i-%.2iT%.2i:%.2i:%.2iZ\n",
+ tm-&gt;tm_year + 1900,
+ tm-&gt;tm_mon + 1,
+ tm-&gt;tm_mday,
+ tm-&gt;tm_hour,
+ tm-&gt;tm_min,
+ tm-&gt;tm_sec);
+
+ fclose(client);
+ }
+}
+</programlisting>
+
+ <para>We start by creating a socket. Then we fill out the
+ <varname>sockaddr_in</varname> structure in
+ <varname>sa</varname>. Note the conditional use of
+ <symbol>INADDR_ANY</symbol>:</para>
+
+<programlisting>
+ if (INADDR_ANY)
+ sa.sin_addr.s_addr = htonl(INADDR_ANY);
+</programlisting>
+
+ <para>Its value is <constant>0</constant>. Since we have
+ just used <function>bzero</function> on the entire
+ structure, it would be redundant to set it to
+ <constant>0</constant> again. But if we port our code to
+ some other system where <symbol>INADDR_ANY</symbol> is
+ perhaps not a zero, we need to assign it to
+ <varname>sa.sin_addr.s_addr</varname>. Most modern C
+ compilers are clever enough to notice that
+ <symbol>INADDR_ANY</symbol> is a constant. As long as it
+ is a zero, they will optimize the entire conditional
+ statement out of the code.</para>
+
+ <para>After we have called <function>bind</function>
+ successfully, we are ready to become a
+ <emphasis>daemon</emphasis>: We use
+ <function>fork</function> to create a child process. In
+ both, the parent and the child, the <varname>s</varname>
+ variable is our socket. The parent process will not need
+ it, so it calls <function>close</function>, then it
+ returns <constant>0</constant> to inform its own parent it
+ had terminated successfully.</para>
+
+ <para>Meanwhile, the child process continues working in the
+ background. It calls <function>listen</function> and sets
+ its backlog to <constant>4</constant>. It does not need a
+ large value here because <emphasis>daytime</emphasis> is
+ not a protocol many clients request all the time, and
+ because it can process each request instantly anyway.</para>
+
+ <para>Finally, the daemon starts an endless loop, which
+ performs the following steps:</para>
+
+ <procedure>
+ <step><para> Call <function>accept</function>. It waits
+ here until a client contacts it. At that point, it
+ receives a new socket, <varname>c</varname>, which it
+ can use to communicate with this particular client.
+ </para></step>
+
+ <step><para>It uses the C function
+ <function>fdopen</function> to turn the socket from a
+ low-level <emphasis>file descriptor</emphasis> to a
+ C-style <varname>FILE</varname> pointer. This will allow
+ the use of <function>fprintf</function> later on.
+ </para></step>
+
+ <step><para>It checks the time, and prints it in the
+ <emphasis><acronym>ISO</acronym> 8601</emphasis> format
+ to the <varname>client</varname> <quote>file</quote>. It
+ then uses <function>fclose</function> to close the
+ file. That will automatically close the socket as well.
+ </para></step>
+
+ </procedure>
+
+ <para>We can <emphasis>generalize</emphasis> this, and use
+ it as a model for many other servers:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="sockets/serv"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced">+-----------------+
+| Create Socket |
++-----------------+
+ |
++-----------------+
+| Bind Port | Daemon Process
++-----------------+
+ | +--------+
+ +-------------+--&gt;| Init |
+ | | +--------+
++-----------------+ | |
+| Exit | | +--------+
++-----------------+ | | Listen |
+ | +--------+
+ | |
+ | +--------+
+ | | Accept |
+ | +--------+
+ | |
+ | +--------+
+ | | Serve |
+ | +--------+
+ | |
+ | +--------+
+ | | Close |
+ |&lt;--------+</literallayout>
+ </textobject>
+
+ <textobject>
+ <phrase>Sequential Server</phrase>
+ </textobject>
+ </mediaobject>
+
+ <para>This flowchart is good for <emphasis>sequential
+ servers</emphasis>, i.e., servers that can serve one
+ client at a time, just as we were able to with our
+ <emphasis>daytime</emphasis> server. This is only possible
+ whenever there is no real <quote>conversation</quote>
+ going on between the client and the server: As soon as the
+ server detects a connection to the client, it sends out
+ some data and closes the connection. The entire operation
+ may take nanoseconds, and it is finished.</para>
+
+ <para>The advantage of this flowchart is that, except for
+ the brief moment after the parent
+ <function>fork</function>s and before it exits, there is
+ always only one <emphasis>process</emphasis> active: Our
+ server does not take up much memory and other system
+ resources.</para>
+
+ <para>Note that we have added <emphasis>initialize
+ daemon</emphasis> in our flowchart. We did not need to
+ initialize our own daemon, but this is a good place in the
+ flow of the program to set up any
+ <function>signal</function> handlers, open any files we
+ may need, etc.</para>
+
+ <para>Just about everything in the flow chart can be used
+ literally on many different servers. The
+ <emphasis>serve</emphasis> entry is the exception. We
+ think of it as a <emphasis><quote>black
+ box</quote></emphasis>, i.e., something you design
+ specifically for your own server, and just <quote>plug it
+ into the rest.</quote></para>
+
+ <para>Not all protocols are that simple. Many receive a
+ request from the client, reply to it, then receive another
+ request from the same client. Because of that, they do not
+ know in advance how long they will be serving the
+ client. Such servers usually start a new process for each
+ client. While the new process is serving its client, the
+ daemon can continue listening for more connections.</para>
+
+ <para>Now, go ahead, save the above source code as
+ <filename>daytimed.c</filename> (it is customary to end
+ the names of daemons with the letter
+ <constant>d</constant>). After you have compiled it, try
+ running it:</para>
+
+<screen>&prompt.user; <userinput>./daytimed</userinput>
+bind: Permission denied
+&prompt.user;</screen>
+
+ <para>What happened here? As you will recall, the
+ <emphasis>daytime</emphasis> protocol uses port 13. But
+ all ports below 1024 are reserved to the superuser
+ (otherwise, anyone could start a daemon pretending to
+ serve a commonly used port, while causing a security
+ breach).</para>
+
+ <para>Try again, this time as the superuser:</para>
+
+<screen>&prompt.root; <userinput>./daytimed</userinput>
+&prompt.root;</screen>
+
+ <para>What... Nothing? Let us try again:</para>
+
+<screen>&prompt.root; <userinput>./daytimed</userinput>
+
+bind: Address already in use
+&prompt.root;</screen>
+
+ <para>Every port can only be bound by one program at a
+ time. Our first attempt was indeed successful: It started
+ the child daemon and returned quietly. It is still running
+ and will continue to run until you either kill it, or any
+ of its system calls fail, or you reboot the system.</para>
+
+ <para>Fine, we know it is running in the background. But is
+ it working? How do we know it is a proper
+ <emphasis>daytime</emphasis> server? Simple:</para>
+
+<screen>&prompt.user; <userinput>telnet localhost 13</userinput>
+
+Trying ::1...
+telnet: connect to address ::1: Connection refused
+Trying 127.0.0.1...
+Connected to localhost.
+Escape character is '^]'.
+2001-06-19T21:04:42Z
+Connection closed by foreign host.
+&prompt.user;</screen>
+
+ <para><application>telnet</application> tried the new
+ <acronym>IP</acronym>v6, and failed. It retried with
+ <acronym>IP</acronym>v4 and succeeded. The daemon
+ works.</para>
+
+ <para>If you have access to another &unix; system via
+ <application>telnet</application>, you can use it to test
+ accessing the server remotely. My computer does not have a
+ static <acronym>IP</acronym> address, so this is what I
+ did:</para>
+
+<screen>&prompt.user; <userinput>who</userinput>
+
+whizkid ttyp0 Jun 19 16:59 (216.127.220.143)
+xxx ttyp1 Jun 19 16:06 (xx.xx.xx.xx)
+&prompt.user; <userinput>telnet 216.127.220.143 13</userinput>
+
+Trying 216.127.220.143...
+Connected to r47.bfm.org.
+Escape character is '^]'.
+2001-06-19T21:31:11Z
+Connection closed by foreign host.
+&prompt.user;</screen>
+
+ <para>Again, it worked. Will it work using the domain name?
+ </para>
+
+<screen>&prompt.user; <userinput>telnet r47.bfm.org 13</userinput>
+
+Trying 216.127.220.143...
+Connected to r47.bfm.org.
+Escape character is '^]'.
+2001-06-19T21:31:40Z
+Connection closed by foreign host.
+&prompt.user;</screen>
+
+ <para>By the way, <application>telnet</application> prints
+ the <emphasis>Connection closed by foreign host</emphasis>
+ message after our daemon has closed the socket. This shows
+ us that, indeed, using
+ <function>fclose(client);</function> in our code works as
+ advertised.</para>
+
+ </sect4>
+
+ </sect3>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="sockets-helper-functions">
+ <title>Helper Functions</title>
+
+ <para>FreeBSD C library contains many helper functions for sockets
+ programming. For example, in our sample client we hard coded
+ the <systemitem class="fqdomainname">time.nist.gov</systemitem>
+ <acronym>IP</acronym> address. But we do not always know the
+ <acronym>IP</acronym> address. Even if we do, our software is
+ more flexible if it allows the user to enter the
+ <acronym>IP</acronym> address, or even the domain name.
+ </para>
+
+ <sect2 xml:id="sockets-gethostbyname">
+ <title><function>gethostbyname</function></title>
+
+ <para>While there is no way to pass the domain name directly to
+ any of the sockets functions, the FreeBSD C library comes with
+ the &man.gethostbyname.3; and &man.gethostbyname2.3; functions,
+ declared in <filename>netdb.h</filename>.</para>
+
+<programlisting>
+struct hostent * gethostbyname(const char *name);
+struct hostent * gethostbyname2(const char *name, int af);
+</programlisting>
+
+ <para>Both return a pointer to the <varname>hostent</varname>
+ structure, with much information about the domain. For our
+ purposes, the <varname>h_addr_list[0]</varname> field of the
+ structure points at <varname>h_length</varname> bytes of the
+ correct address, already stored in the <emphasis>network byte
+ order</emphasis>.</para>
+
+ <para>This allows us to create a much more flexible&mdash;and
+ much more useful&mdash;version of our
+ <application>daytime</application> program:</para>
+
+<programlisting>
+/*
+ * daytime.c
+ *
+ * Programmed by G. Adam Stanislav
+ * 19 June 2001
+ */
+#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;sys/socket.h&gt;
+#include &lt;netinet/in.h&gt;
+#include &lt;netdb.h&gt;
+
+int main(int argc, char *argv[]) {
+ register int s;
+ register int bytes;
+ struct sockaddr_in sa;
+ struct hostent *he;
+ char buf[BUFSIZ+1];
+ char *host;
+
+ if ((s = socket(PF_INET, SOCK_STREAM, 0)) &lt; 0) {
+ perror("socket");
+ return 1;
+ }
+
+ bzero(&amp;sa, sizeof sa);
+
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons(13);
+
+ host = (argc &gt; 1) ? (char *)argv[1] : "time.nist.gov";
+
+ if ((he = gethostbyname(host)) == NULL) {
+ perror(host);
+ return 2;
+ }
+
+ bcopy(he-&gt;h_addr_list[0],&amp;sa.sin_addr, he-&gt;h_length);
+
+ if (connect(s, (struct sockaddr *)&amp;sa, sizeof sa) &lt; 0) {
+ perror("connect");
+ return 3;
+ }
+
+ while ((bytes = read(s, buf, BUFSIZ)) &gt; 0)
+ write(1, buf, bytes);
+
+ close(s);
+ return 0;
+}
+</programlisting>
+
+ <para>We now can type a domain name (or an <acronym>IP</acronym>
+ address, it works both ways) on the command line, and the
+ program will try to connect to its
+ <emphasis>daytime</emphasis> server. Otherwise, it will still
+ default to <systemitem class="fqdomainname">time.nist.gov</systemitem>. However, even in
+ this case we will use <function>gethostbyname</function>
+ rather than hard coding <systemitem class="ipaddress">192.43.244.18</systemitem>. That way, even if its
+ <acronym>IP</acronym> address changes in the future, we will
+ still find it.</para>
+
+ <para>Since it takes virtually no time to get the time from your
+ local server, you could run <application>daytime</application>
+ twice in a row: First to get the time from <systemitem class="fqdomainname">time.nist.gov</systemitem>, the second time from
+ your own system. You can then compare the results and see how
+ exact your system clock is:</para>
+
+<screen>&prompt.user; <userinput>daytime ; daytime localhost</userinput>
+
+
+52080 01-06-20 04:02:33 50 0 0 390.2 UTC(NIST) *
+2001-06-20T04:02:35Z
+&prompt.user;</screen>
+
+ <para>As you can see, my system was two seconds ahead of the
+ <acronym>NIST</acronym> time.</para>
+
+ </sect2>
+
+ <sect2 xml:id="sockets-getservbyname">
+ <title><function>getservbyname</function></title>
+
+ <para>Sometimes you may not be sure what port a certain service
+ uses. The &man.getservbyname.3; function, also declared in
+ <filename>netdb.h</filename> comes in very handy in those
+ cases:</para>
+
+<programlisting>
+struct servent * getservbyname(const char *name, const char *proto);
+</programlisting>
+
+ <para>The <varname>servent</varname> structure contains the
+ <varname>s_port</varname>, which contains the proper port,
+ already in <emphasis>network byte order</emphasis>.</para>
+
+ <para>Had we not known the correct port for the
+ <emphasis>daytime</emphasis> service, we could have found it
+ this way:</para>
+
+<programlisting>
+ struct servent *se;
+ ...
+ if ((se = getservbyname("daytime", "tcp")) == NULL {
+ fprintf(stderr, "Cannot determine which port to use.\n");
+ return 7;
+ }
+ sa.sin_port = se-&gt;s_port;
+</programlisting>
+
+ <para>You usually do know the port. But if you are developing a
+ new protocol, you may be testing it on an unofficial
+ port. Some day, you will register the protocol and its port
+ (if nowhere else, at least in your
+ <filename>/etc/services</filename>, which is where
+ <function>getservbyname</function> looks). Instead of
+ returning an error in the above code, you just use the
+ temporary port number. Once you have listed the protocol in
+ <filename>/etc/services</filename>, your software will find
+ its port without you having to rewrite the code.</para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="sockets-concurrent-servers">
+ <title>Concurrent Servers</title>
+
+ <para>Unlike a sequential server, a <emphasis>concurrent
+ server</emphasis> has to be able to serve more than one client
+ at a time. For example, a <emphasis>chat server</emphasis> may
+ be serving a specific client for hours&mdash;it cannot wait till
+ it stops serving a client before it serves the next one.</para>
+
+ <para>This requires a significant change in our flowchart:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="sockets/serv2"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced">+-----------------+
+| Create Socket |
++-----------------+
+ |
++-----------------+
+| Bind Port | Daemon Process
++-----------------+
+ | +--------+
+ +-------------+--&gt;| Init |
+ | | +--------+
++-----------------+ | |
+| Exit | | +--------+
++-----------------+ | | Listen |
+ | +--------+
+ | |
+ | +--------+
+ | | Accept |
+ | +--------+
+ | | +------------------+
+ | +------&gt;| Close Top Socket |
+ | | +------------------+
+ | +--------+ |
+ | | Close | +------------------+
+ | +--------+ | Serve |
+ | | +------------------+
+ |&lt;--------+ |
+ +------------------+
+ | Close Acc Socket |
+ +--------+ +------------------+
+ | Signal | |
+ +--------+ +------------------+
+ | Exit |
+ +------------------+</literallayout>
+ </textobject>
+
+ <textobject>
+ <phrase>Concurrent Server</phrase>
+ </textobject>
+ </mediaobject>
+
+ <para>We moved the <emphasis>serve</emphasis> from the
+ <emphasis>daemon process</emphasis> to its own <emphasis>server
+ process</emphasis>. However, because each child process inherits
+ all open files (and a socket is treated just like a file), the
+ new process inherits not only the <emphasis><quote>accepted
+ handle,</quote></emphasis> i.e., the socket returned by the
+ <function>accept</function> call, but also the <emphasis>top
+ socket</emphasis>, i.e., the one opened by the top process right
+ at the beginning.</para>
+
+ <para>However, the <emphasis>server process</emphasis> does not
+ need this socket and should <function>close</function> it
+ immediately. Similarly, the <emphasis>daemon process</emphasis>
+ no longer needs the <emphasis>accepted socket</emphasis>, and
+ not only should, but <emphasis>must</emphasis>
+ <function>close</function> it&mdash;otherwise, it will run out
+ of available <emphasis>file descriptors</emphasis> sooner or
+ later.</para>
+
+ <para>After the <emphasis>server process</emphasis> is done
+ serving, it should close the <emphasis>accepted
+ socket</emphasis>. Instead of returning to
+ <function>accept</function>, it now exits.
+ </para>
+
+ <para>Under &unix;, a process does not really
+ <emphasis>exit</emphasis>. Instead, it
+ <emphasis>returns</emphasis> to its parent. Typically, a parent
+ process <function>wait</function>s for its child process, and
+ obtains a return value. However, our <emphasis>daemon
+ process</emphasis> cannot simply stop and wait. That would
+ defeat the whole purpose of creating additional processes. But
+ if it never does <function>wait</function>, its children will
+ become <emphasis>zombies</emphasis>&mdash;no longer functional
+ but still roaming around.</para>
+
+ <para>For that reason, the <emphasis>daemon process</emphasis>
+ needs to set <emphasis>signal handlers</emphasis> in its
+ <emphasis>initialize daemon</emphasis> phase. At least a
+ <symbol>SIGCHLD</symbol> signal has to be processed, so the
+ daemon can remove the zombie return values from the system and
+ release the system resources they are taking up.</para>
+
+ <para>That is why our flowchart now contains a <emphasis>process
+ signals</emphasis> box, which is not connected to any other box.
+ By the way, many servers also process <symbol>SIGHUP</symbol>,
+ and typically interpret as the signal from the superuser that
+ they should reread their configuration files. This allows us to
+ change settings without having to kill and restart these
+ servers.</para>
+
+ </sect1>
+
+</chapter>
diff --git a/zh_TW.UTF-8/books/developers-handbook/testing/chapter.xml b/zh_TW.UTF-8/books/developers-handbook/testing/chapter.xml
new file mode 100644
index 0000000000..fde68a1b61
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/testing/chapter.xml
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="testing">
+ <title>Regression and Performance Testing</title>
+
+ <para>Regression tests are used to exercise a particular bit of the
+ system to check that it works as expected, and to make sure that
+ old bugs are not reintroduced.</para>
+
+ <para>The &os; regression testing tools can be found in the &os;
+ source tree in the directory <filename>src/tools/regression</filename>.</para>
+
+ <section xml:id="testing-micro-benchmark">
+ <title>Micro Benchmark Checklist</title>
+
+ <para>This section contains hints for doing proper
+ micro-benchmarking on &os; or of &os; itself.</para>
+
+ <para>It is not possible to use all of the suggestions below every
+ single time, but the more used, the better the benchmark's
+ ability to test small differences will be.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Disable <acronym>APM</acronym> and any other kind of
+ clock fiddling (<acronym>ACPI</acronym> ?).</para>
+ </listitem>
+
+ <listitem>
+ <para>Run in single user mode. E.g. &man.cron.8;, and and
+ other daemons only add noise. The &man.sshd.8; daemon can
+ also cause problems. If ssh access is required during test
+ either disable the SSHv1 key regeneration, or kill the
+ parent <command>sshd</command> daemon during the tests.</para>
+ </listitem>
+
+ <listitem>
+ <para>Do not run &man.ntpd.8;.</para>
+ </listitem>
+
+ <listitem>
+ <para>If &man.syslog.3; events are generated, run
+ &man.syslogd.8; with an empty
+ <filename>/etc/syslogd.conf</filename>, otherwise, do not
+ run it.</para>
+ </listitem>
+
+ <listitem>
+ <para>Minimize disk-I/O, avoid it entirely if possible.</para>
+ </listitem>
+
+ <listitem>
+ <para>Do not mount file systems that are not needed.</para>
+ </listitem>
+
+ <listitem>
+ <para>Mount <filename>/</filename>,
+ <filename>/usr</filename>, and any other
+ file system as read-only if possible. This removes atime
+ updates to disk (etc.) from the I/O picture.</para>
+ </listitem>
+
+ <listitem>
+ <para>Reinitialize the read/write test file system with
+ &man.newfs.8; and populate it from a &man.tar.1; or
+ &man.dump.8; file before every run. Unmount and mount it
+ before starting the test. This results in a consistent file
+ system layout. For a worldstone test this would apply to
+ <filename>/usr/obj</filename> (just
+ reinitialize with <command>newfs</command> and mount). To
+ get 100% reproducibility, populate the file system from a
+ &man.dd.1; file (i.e.: <command>dd
+ if=myimage of=/dev/ad0s1h
+ bs=1m</command>)</para>
+ </listitem>
+
+ <listitem>
+ <para>Use malloc backed or preloaded &man.md.4;
+ partitions.</para>
+ </listitem>
+
+ <listitem>
+ <para>Reboot between individual iterations of the test, this
+ gives a more consistent state.</para>
+ </listitem>
+
+ <listitem>
+ <para>Remove all non-essential device drivers from the kernel.
+ For instance if USB is not needed for the test, do not put
+ USB in the kernel. Drivers which attach often have timeouts
+ ticking away.</para>
+ </listitem>
+
+ <listitem>
+ <para>Unconfigure hardware that are not in use. Detach disks
+ with &man.atacontrol.8; and &man.camcontrol.8; if the disks
+ are not used for the test.</para>
+ </listitem>
+
+ <listitem>
+ <para>Do not configure the network unless it is being tested,
+ or wait until after the test has been performed to ship the
+ results off to another computer.</para>
+
+ <para>If the system must be connected to a public network,
+ watch out for spikes of broadcast traffic. Even though it
+ is hardly noticeable, it will take up CPU cycles. Multicast
+ has similar caveats.</para>
+ </listitem>
+
+ <listitem>
+ <para>Put each file system on its own disk. This minimizes
+ jitter from head-seek optimizations.</para>
+ </listitem>
+
+ <listitem>
+ <para>Minimize output to serial or VGA consoles. Running
+ output into files gives less jitter. (Serial consoles
+ easily become a bottleneck.) Do not touch keyboard while
+ the test is running, even <keycap>space</keycap> or
+ <keycap>back-space</keycap> shows up in the numbers.</para>
+ </listitem>
+
+ <listitem>
+ <para>Make sure the test is long enough, but not too long. If
+ the test is too short, timestamping is a problem. If it is
+ too long temperature changes and drift will affect the
+ frequency of the quartz crystals in the computer. Rule of
+ thumb: more than a minute, less than an hour.</para>
+ </listitem>
+
+ <listitem>
+ <para>Try to keep the temperature as stable as possible around
+ the machine. This affects both quartz crystals and disk
+ drive algorithms. To get real stable clock, consider
+ stabilized clock injection. E.g. get a OCXO + PLL, inject
+ output into clock circuits instead of motherboard xtal.
+ Contact &a.phk; for more information about this.</para>
+ </listitem>
+
+ <listitem>
+ <para>Run the test at least 3 times but it is better to run
+ more than 20 times both for <quote>before</quote> and
+ <quote>after</quote> code. Try to interleave if possible
+ (i.e.: do not run 20 times before then 20 times after), this
+ makes it possible to spot environmental effects. Do not
+ interleave 1:1, but 3:3, this makes it possible to spot
+ interaction effects.</para>
+
+ <para>A good pattern is: <literal>bababa{bbbaaa}*</literal>.
+ This gives hint after the first 1+1 runs (so it is possible
+ to stop the test if it goes entirely the wrong way), a
+ standard deviation after the first 3+3 (gives a good
+ indication if it is going to be worth a long run) and
+ trending and interaction numbers later on.</para>
+ </listitem>
+
+ <listitem>
+ <para>Use <filename>usr/src/tools/tools/ministat</filename>
+ to see if the numbers are significant. Consider buying
+ <quote>Cartoon guide to statistics</quote> ISBN:
+ 0062731025, highly recommended, if you have forgotten or
+ never learned about standard deviation and Student's
+ T.</para>
+ </listitem>
+
+ <listitem>
+ <para>Do not use background &man.fsck.8; unless the test is a
+ benchmark of background <command>fsck</command>. Also,
+ disable <varname>background_fsck</varname> in
+ <filename>/etc/rc.conf</filename> unless the benchmark is
+ not started at least 60+<quote><command>fsck</command>
+ runtime</quote> seconds after the boot, as &man.rc.8; wakes
+ up and checks if <command>fsck</command> needs to run on any
+ file systems when background <command>fsck</command> is
+ enabled. Likewise, make sure there are no snapshots lying
+ around unless the benchmark is a test with snapshots.</para>
+ </listitem>
+
+ <listitem>
+ <para>If the benchmark show unexpected bad performance, check
+ for things like high interrupt volume from an unexpected
+ source. Some versions of <acronym>ACPI</acronym> have been
+ reported to <quote>misbehave</quote> and generate excess
+ interrupts. To help diagnose odd test results, take a few
+ snapshots of <command>vmstat -i</command> and look for
+ anything unusual.</para>
+ </listitem>
+
+ <listitem>
+ <para>Make sure to be careful about optimization parameters
+ for kernel and userspace, likewise debugging. It is easy to
+ let something slip through and realize later the test was
+ not comparing the same thing.</para>
+ </listitem>
+
+ <listitem>
+ <para>Do not ever benchmark with the
+ <literal>WITNESS</literal> and <literal>INVARIANTS</literal>
+ kernel options enabled unless the test is interested to
+ benchmarking those features. <literal>WITNESS</literal> can
+ cause 400%+ drops in performance. Likewise, userspace
+ &man.malloc.3; parameters default differently in -CURRENT
+ from the way they ship in production releases.</para>
+ </listitem>
+ </itemizedlist>
+ </section>
+</chapter>
diff --git a/zh_TW.UTF-8/books/developers-handbook/tools/chapter.xml b/zh_TW.UTF-8/books/developers-handbook/tools/chapter.xml
new file mode 100644
index 0000000000..c9ca702ca2
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/tools/chapter.xml
@@ -0,0 +1,2139 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.46
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="tools">
+ <info><title>程式開發工具</title>
+ <authorgroup>
+ <author><personname><firstname>James</firstname><surname>Raynard</surname></personname><contrib>Contributed by </contrib></author>
+ <author><personname><firstname>Murray</firstname><surname>Stokely</surname></personname></author>
+ </authorgroup>
+ </info>
+
+
+ <sect1 xml:id="tools-synopsis"><title>概敘</title>
+
+ <para>本章將介紹如何使用一些 FreeBSD 所提供的程式開發工具(programing tools),
+ 本章所介紹的工具程式在其他版本的 &unix; 上也可使用,
+ 在此 <emphasis>並不會</emphasis> 嘗試描述寫程式時的每個細節,
+ 本章大部分篇幅都是假設你以前沒有或只有少數的寫程式經驗,
+ 不過,還是希望大多數的程式開發人員都能從中重新得到一些啟發。</para>
+
+ </sect1>
+
+ <sect1 xml:id="tools-intro"><title>簡介</title>
+
+ <para>FreeBSD 提供一個非常棒的開發環境,
+ 比如說像是 C、C++、Fortran 和 assembler(組合語言)的編譯器(compiler),
+ 在 FreeBSD 中都已經包含在基本的系統中了
+ 更別提 Perl 和其他標準 &unix; 工具,像是<command>sed</command> 以及 <command>awk</command>,
+ 如果你還是覺得不夠,FreeBSD在 Ports collection 中還提供其他的編譯器和直譯器(interpreter),
+ FreeBSD 相容許多標準,像是 <acronym>&posix;</acronym> 和 <acronym>ANSI</acronym> C,
+ 當然還有它所繼承的 BSD 傳統。
+ 所以在 FreeBSD 上寫的程式不需修改或頂多稍微修改,就可以在許多平台上編譯、執行。</para>
+
+ <para>無論如何,就算你從來沒在 &unix; 平台上寫過程式,也可以徹底感受到FreeBSD 令人無法抗拒的迷人魔力。
+ 本章的目標就是協助你快速上手,而暫時不需深入太多進階主題,
+ 並且講解一些基礎概念,以讓你可以瞭解我們在講些什麼。</para>
+
+ <para>本章內容並不要求你得有程式開發經驗,或者你只有一點點的經驗而已。
+ 不過,我們假設你已經會 &unix; 系統的基本操作,
+ 而且更重要的是,請保持樂於學習的心態!</para>
+
+ </sect1>
+
+ <sect1 xml:id="tools-programming">
+ <title>Programming 概念</title>
+
+ <para>簡單的說,程式只是一堆指令的集合體;而這些指令是用來告訴電腦應該要作那些事情。
+ 有時候,指令的執行取決於前一個指令的結果而定。
+ 本章將會告訴你有 2 個主要的方法,讓你可以對電腦下達這些指示(instruction) 或 <quote>命令(commands)</quote>。
+ 第一個方法就是 <firstterm>直譯器(interpreter)</firstterm>,
+ 而第二個方法是 <firstterm>編譯器(compiler)</firstterm>。
+ 由於對於電腦而言,人類語言的語意過於模糊而太難理解,
+ 因此命令(commands)就常會以一種(或多種)程式語言寫成,用來指示電腦所要執行的特定動作為何。</para>
+
+ <sect2>
+ <title>直譯器</title>
+
+ <para>使用直譯器時,所使用的程式語言就像變成一個會和你互動的環境。
+ 當在命令提示列上打上命令時,直譯器會即時執行該命令。
+ 在比較複雜的程式中,可以把所有想下達的命令統統輸入到某檔案裡面去,
+ 然後呼叫直譯器去讀取該檔案,並且執行你寫在這個檔案中的指令。
+ 如果所下的指令有錯誤產生,大多數的直譯器會進入偵錯模式(debugger),
+ 並且顯示相關錯誤訊息,以便對程式除錯。</para>
+
+ <para>這種方式好處在於:可以立刻看到指令的執行結果,以及錯誤也可迅速修正。
+ 相對的,最大的壞處便是當你想把你寫的程式分享給其他人時,這些人必須要有跟你一樣的直譯器。
+ 而且別忘了,他們也要會使用直譯器直譯程式才行。
+ 當然使用者也不希望不小心按錯鍵,就進入偵錯模式而不知所措。
+ 就執行效率而言,直譯器會使用到很多的記憶體,
+ 而且這類直譯式程式,通常並不會比編譯器所編譯的程式的更有效率。</para>
+
+ <para>筆者個人認為,如果你之前沒有學過任何程式語言,最好先學學習直譯式語言(interpreted languages),
+ 像是 Lisp,Smalltalk,Perl 和 Basic 都是,&unix; 的 shell 像是 <command>sh</command> 和 <command>csh</command>
+ 它們本身就是直譯器,事實上,很多人都在它們自己機器上撰寫各式的 shell <quote>script</quote>,
+ 來順利完成各項 <quote>housekeeping(維護)</quote> 任務。
+ &unix; 的使用哲學之一就是提供大量的小工具,
+ 並使用 shell script 來組合運用這些小工具,以便工作更有效率。</para>
+ </sect2>
+
+ <sect2>
+ <title>FreeBSD 提供的直譯器</title>
+
+ <para>下面這邊有份 &os; Ports Collection 所提供的直譯器清單,還有討論一些比較受歡迎的直譯式語言</para>
+
+ <para>至於如何使用 Ports Collection 安裝的說明,可參閱 FreeBSD Handbook 中的
+ <link xlink:href="&url.books.handbook;/ports-using.html">Ports章節</link>。</para>
+ <variablelist>
+ <varlistentry>
+ <term><acronym>BASIC</acronym></term>
+
+ <listitem>
+ <para>BASIC 是 Beginner's ALL-purpose Symbolic Instruction Code 的縮寫。
+ BASIC 於 1950 年代開始發展,最初開發這套語言的目的是為了教導當時的大學學生如何寫程式。
+ 到了 1980,<acronym>BASIC</acronym>已經是很多 programmer 第一個學習的程式語言了。
+ 此外,BASIC 也是 Visual Basic 的基礎。</para>
+
+ <para>FreeBSD Ports Collection 也有收錄相關的 BASIC 直譯器。
+ Bywater Basic 直譯器放在 <package>lang/bwbasic</package>。
+ 而 Phil Cockroft's Basic 直譯器(早期也叫 Rabbit Basic)放在 <package>lang/pbasic</package>。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Lisp</term>
+
+ <listitem>
+ <para>LISP 是在 1950 年代開始發展的一個直譯式語言,而且 LISP 就是一種
+ <quote>number-crunching</quote> languages(迅速進行大量運算的程式語言),在當時算是一個普遍的程式語言。
+ LISP 的表達不是基於數字(numbers),而是基於表(lists)。
+ 而最能表示出 LISP 特色的地方就在於: LISP 是 <quote>List Processing</quote> 的縮寫。
+ 在<acronym>人工智慧(Artificial Intelligence, AI)</acronym>領域上 LISP 的各式應用非常普遍。</para>
+
+ <para>LISP 是非常強悍且複雜的程式語言,但是缺點是程式碼會非常大而且難以操作。</para>
+
+ <para>絕大部分的 LISP 直譯器都可以在 &unix; 系統上運作,當然 &os; 的 Ports Collection 也有收錄。
+ GNU Common Lisp 收錄在 <package>lang/gcl</package>,
+ Bruno Haible 和 Michael Stoll 的 CLISP 收錄在 <package>lang/clisp</package>
+ ,此外 CMUCL(包含一個已經最佳化的編譯器),
+ 以及其他簡化版的 LISP 直譯器(比如以 C 語言寫的 SLisp,只用幾百行程式碼就實作大多數 Common Lisp 的功能)
+ 則是分別收錄在 <package>lang/cmucl</package> 以及
+ <package>lang/slisp</package>。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Perl</term>
+
+ <listitem>
+ <para>對系統管理者而言,最愛用 perl 來撰寫 scripts 以管理主機,
+ 同時也經常用來寫 WWW 主機上的 <acronym>CGI</acronym> Script 程式。</para>
+
+ <para>Perl 在 Ports Collection 內的 <package>lang/perl5</package>。
+ 而 &os; 4.X 則是把 Perl 裝在 <command>/usr/bin/perl</command>。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Scheme</term>
+
+ <listitem>
+ <para>Scheme 是 LISP 的另一分支,Scheme 的特點就是比 Common LISP 還要簡潔有力。
+ 由於 Scheme 簡單,所以很多大學拿來當作第一堂程式語言教學教材。
+ 而且對於研究人員來說也可以快速的開發他們所需要的程式。</para>
+
+ <para>Scheme 收錄在 <package>lang/elk</package>,
+ Elk Scheme 直譯器(由麻省理工學院所發展的 Scheme 直譯器)收錄在
+ <package>lang/mit-scheme</package>,
+ SCM Scheme Interpreter 收錄在 <package>lang/scm</package>。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Icon</term>
+
+ <listitem>
+ <para>Icon 屬高階程式語言,Icon 具有強大的字串(String)和結構(Structure)處理能力。
+ &os; Ports Collection 所收錄的 Icon 直譯器版本則是放在
+ <package>lang/icon</package>。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Logo</term>
+
+ <listitem>
+ <para>Logo 是種容易學習的程式語言,最常在一些教學課程中被拿來當作開頭範例。
+ 如果要給小朋友開始上程式語言課的話,Logo 是相當不錯的選擇。
+ 因為,即使對小朋友來說,要用 Logo 來秀出複雜多邊形圖形是相當輕鬆容易的。</para>
+
+ <para>Logo 在 &os; Ports Collection 的最新版則是放在 <package>lang/logo</package>。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Python</term>
+
+ <listitem>
+ <para>Python 是物件導向的直譯式語言,
+ Python 的擁護者總是宣稱 Python 是最好入門的程式語言。
+ 雖然 Python 可以很簡單的開始,但是不代表它就會輸給其他直譯式語言(像是 Perl 和 Tcl),
+ 事實證明 Python 也可以拿來開發大型、複雜的應用程式。</para>
+
+ <para>&os; Ports Collection 收錄在 <package>lang/python</package>。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Ruby</term>
+
+ <listitem>
+ <para>Ruby 是純物件導向的直譯式語言。
+ Ruby 目前非常流行,原因在於他易懂的程式語法結構,在撰寫程式時的彈性,
+ 以及天生具有輕易的發展維護大型專案的能力。</para>
+
+ <para>&os; Ports Collection 收錄在 <package>lang/ruby8</package>。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Tcl and Tk</term>
+
+ <listitem>
+ <para>Tcl 是內嵌式的直譯式語言,讓 Tcl 可以如此廣泛運用的原因是 Tcl 的移植性。
+ Tcl 也可以快速發展一個簡單但是具有雛型的程式或者具有完整功能的程式。</para>
+
+ <para>Tcl 許多的版本都可在 &os; 上運作,而最新的 Tcl 版本為 Tcl 8.4,
+ &os; Ports Collection 收錄在 <package>lang/tcl84</package>。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>編譯器</title>
+
+ <para>編譯器和直譯器兩者相比的話,有些不同,首先就是必須先把程式碼統統寫入到檔案裡面,
+ 然後必須執行編譯器來試著編譯程式,如果編譯器不接受所寫的程式,那就必須一直修改程式,
+ 直到編譯器接受且把你的程式編譯成執行檔。
+ 此外,也可以在提示命令列,或在除錯器中執行你編譯好的程式看看它是否可以運作。
+ <footnote>
+ <para>如果在提示命令列下執行,那麼有可能會產生 core dump。</para>
+ </footnote></para>
+
+ <para>很明顯的,使用編譯器並不像直譯器般可以馬上得到結果。
+ 不管如何,編譯器允許你作很多直譯器不可能或者是很難達到的事情。
+ 例如:撰寫和作業系統密切互動的程式,甚至是你自己寫的作業系統!
+ 當你想要寫出高效率的程式時,編譯器便派上用場了。
+ 編譯器可以在編譯時順便最佳化你的程式,但是直譯器卻不行。
+ 而編譯器與直譯器最大的差別在於:當你想把你寫好的程式拿到另外一台機器上跑時,
+ 你只要將編譯器編譯出來的可執行檔,拿到新機器上便可以執行,
+ 而直譯器則必須要求新機器上,必須要有跟另一台機器上相同的直譯器,
+ 才能組譯執行你的程式!</para>
+
+ <para>編譯式的程式語言包含 Pascal、C 和 C++,
+ C 和 C++ 不是一個親和力十足的語言,但是很適合具有經驗的 Programmer。
+ Pascal 其實是一個設計用來教學用的程式語言,而且也很適合用來入門,
+ &os; 預設並沒有把 Pascal 整合進 base system 中,
+ 但是 GNU Pascal Compiler 和 Free Pascal Compiler 都可分別在
+ <package>lang/gpc</package> 和 <package>lang/fpc</package> 中找到。</para>
+
+ <para>如果你用不同的程式來寫編譯式程式,那麼不斷地編輯-編譯-執行-除錯的這個循環肯定會很煩人,
+ 為了更簡化、方便程式開發流程,很多商業編譯器廠商開始發展所謂的 <acronym>IDE</acronym>
+ (Integrated Development Environments) 開發環境,
+ FreeBSD 預設並沒有把 IDE 整合進 base system 中,
+ 但是你可透過 <package>devel/kdevelop</package> 安裝 kdevelop
+ 或使用 <application>Emacs</application> 來體驗 IDE 開發環境。
+ 在後面的 <xref linkend="emacs"/> 專題將介紹,如何以 <application>Emacs</application> 來作為 IDE 開發環境。</para>
+ </sect2>
+
+
+ </sect1>
+
+
+ <sect1 xml:id="tools-compiling">
+ <title>用 <command>cc</command> 來編譯程式</title>
+
+ <para>本章範例只有針對 GNU C compiler 和 GNU C++ compiler 作說明,
+ 這兩個在 FreeBSD base system 中就有了,
+ 直接打 <command>cc</command> 或 <command>gcc</command> 就可以執行。
+ 至於,如何用直譯器產生程式的說明,通常可在直譯器的文件或線上文件找到說明,因此不再贅述。</para>
+
+ <para>當你寫完你的傑作後,接下來便是讓這個程式可以在 FreeBSD 上執行,
+ 通常這些要一些步驟才能完成,有些步驟則需要不同程式來完成。</para>
+
+ <procedure>
+ <step>
+ <para>預先處理(Pre-process)你的程式碼,移除程式內的註解,和其他技巧,
+ 像是 expanding(擴大) C 的 marco。</para>
+ </step>
+
+ <step>
+ <para>確認你的程式語法是否確實遵照 C/C++ 的規定,如果沒有符合的話,編譯器會出現警告。</para>
+ </step>
+
+ <step>
+ <para>將原始碼轉成組合語言 &mdash; 它跟機器語言(machine code)非常相近,但仍在人類可理解的範圍內(據說應該是這樣)。
+ <footnote>
+ <para>嚴格說起來,在這個階段 <command>cc</command> 並不是真的把原始程式轉成組合語言,
+ 而是轉為 machine-independent 的 <firstterm>p-code</firstterm>。</para>
+ </footnote></para>
+ </step>
+
+ <step>
+ <para>把組合語言轉成機器語言 &mdash; 是的,這裡說的機器語言就是常提到的 bit 和 byte,也就是 1 和 0。</para>
+ </step>
+
+ <step>
+ <para>確認程式中用到的函式呼叫、全域變數是否正確,舉例來說:如若呼叫了不存在的函式,編譯器會顯示警告。</para>
+ </step>
+
+ <step>
+ <para>如果程式是由程式碼檔案來編譯,編譯器會整合起來。</para>
+ </step>
+
+ <step>
+ <para>編譯器會負責產生東西,讓系統上的 run-time loader 可以把程式載入記憶體內執行。</para>
+ </step>
+
+ <step>
+ <para>最後會把編譯完的執行檔存在硬碟上。</para>
+ </step>
+ </procedure>
+
+ <para>通常 <firstterm>編譯(compiling)</firstterm> 是指第 1 到第 4 個步驟。
+ &mdash; 其他步驟則稱為 <firstterm>連結(linking)</firstterm>,
+ 有時候步驟 1 也可以是指 <firstterm>預先處理(pre-processing)</firstterm>,
+ 而步驟 3 到步驟 4 則是 <firstterm>組譯(assembling)</firstterm>。</para>
+
+ <para>幸運的是,你可以不用理會以上細節,編譯器都會自動完成。
+ 因為 <command>cc</command> 只是是個前端程式(front end),它會依照正確的參數來呼叫相關程式幫你處理。
+ 只需打:</para>
+ <screen>&prompt.user; <userinput>cc foobar.c</userinput></screen>
+
+ <para>上述指令會把 <filename>foobar.c</filename> 開始編譯,並完成上述動作。
+ 如果你有許多檔案需要編譯,那請打類似下列指令即可:</para>
+
+ <screen>&prompt.user; <userinput>cc foo.c bar.c</userinput></screen>
+
+ <para>記住語法錯誤檢查就是 &mdash; 純粹檢查語法錯誤與否,
+ 而不會幫你檢測任何邏輯錯誤,比如:無限迴圈,或是排序方式想用 binary sort 卻弄成 bubble sort。
+ <footnote>
+ <para>剛所說的 binary sort 和 bubble sort 問題,
+ 在已排序好的序列中,binary sort 搜索效率會比 bubble sort 好。</para>
+ </footnote></para>
+
+ <para><command>cc</command> 有非常多的選項,都可透過線上手冊來查。
+ 下面只提一些必要且重要的選項,以作為例子。</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-o <replaceable>檔名</replaceable></option></term>
+
+ <listitem>
+ <para><option>-o</option> 編譯後的執行檔檔名,如果沒有使用這選項的話,
+ 編譯好的程式預設檔名將會是 <filename>a.out</filename>
+
+ <footnote>
+ <para>至於 <option>-o</option> 的原因,則是一團歷史迷霧了。</para>
+ </footnote></para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc foobar.c</userinput> <lineannotation>執行檔就是 a.out</lineannotation>
+&prompt.user; <userinput>cc -o foobar foobar.c</userinput> <lineannotation>執行檔就是 foobar</lineannotation>
+ </screen>
+ </informalexample>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-c</option></term>
+
+ <listitem>
+ <para>使用 <option>-c</option> 時,只會編譯原始碼,而不作連結(linking)。
+ 當只想確認語法是否正確或使用 Makefile 來編譯程式時,這個選項非常有用。</para>
+
+ <informalexample>
+ <screen>
+ &prompt.user; <userinput>cc -c foobar.c</userinput>
+ </screen>
+ </informalexample>
+
+ <para>這會產生叫做 <filename>foobar</filename> 的 <firstterm>object file</firstterm>(非執行檔)。
+ 這檔可以與其他的 object file 連結在一起,而成執行檔。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-g</option></term>
+
+ <listitem>
+ <para><option>-g</option> 將會把一些給 gdb 用的除錯訊息包進去執行檔裡面,所謂的除錯訊息例如:
+ 程式在第幾行出錯、那個程式第幾行做什麼函式呼叫等等。除錯資訊<emphasis>非常</emphasis>好用。
+ 但缺點就是:對於程式來說,額外的除錯訊息會讓編譯出來的程式比較肥些。
+ <option>-g</option> 的適用時機在於:當程式還在開發時使用就好,
+ 而當你要釋出你的 <quote>發行版本(release version)</quote>
+ 或者確認程式可運作正常的話,就不必用 <option>-g</option> 這選項了。</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -g foobar.c</userinput>
+ </screen>
+ </informalexample>
+
+ <para>這動作會產生有含除錯訊息的執行檔。
+ <footnote>
+ <para>請注意,因為上例沒用 <option>-o</option> 以指定執行檔名稱,
+ 所以執行檔會是 <filename>a.out</filename> 這檔。
+ 那麼,要如何產生 <filename>foobar</filename> 的執行檔並內含除錯訊息,
+ 這就留待看倌們練習一下囉。</para>
+ </footnote></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-O</option></term>
+
+ <listitem>
+ <para><option>-O</option> 會產生最佳化的執行檔,
+ 編譯器會使用一些技巧,來讓程式可以跑的比未經最佳化的程式還快,
+ 可以在大寫 O 後面加上數字來指明想要的最佳化層級。
+ 但是最佳化還是會有一些錯誤,舉例來說在 FreeBSD 2.10 release 中用 <command>cc</command>
+ 且指定 <option>-O2</option> 時,在某些情形下會產生錯誤的執行檔。</para>
+
+ <para>只有當要釋出發行版本、或者加速程式時,才需要使用最佳化選項。</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -O -o foobar foobar.c</userinput>
+ </screen>
+ </informalexample>
+
+ <para>這會產生 <filename>foobar</filename> 執行檔的最佳化版本。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>以下三個參數將會強迫 <command>cc</command> 確認程式碼是否符合一些國際標準的規範,
+ 也就是通常說的 <acronym>ANSI</acronym> 標準,
+ 而 <acronym>ANSI</acronym> 嚴格來講屬 <acronym>ISO</acronym> 標準。</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-Wall</option></term>
+
+ <listitem>
+ <para><option>-Wall</option> 顯示 <command>cc</command> 維護者所認為值得注意的所有警告訊息。
+ 不過這名字可能會造成誤解,事實上它並未完全顯示 <command>cc</command> 所能注意到的各項警告訊息。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-ansi</option></term>
+
+ <listitem>
+ <para><option>-ansi</option> 關閉 <command>cc</command> 特有的某些特殊非 ANSI C 標準功能。
+ 不過這名字可能會造成誤解,事實上它並不保證你的程式會完全符合 ANSI 標準。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-pedantic</option></term>
+
+ <listitem>
+ <para>全面關閉 <command>cc</command> 所特有的非 <acronym>ANSI</acronym> C 標準功能。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>除了這些參數,<command>cc</command> 還允許你使用一些額外的參數取代標準參數,有些額外參數非常有用,
+ 但是實際上並不是所有的編譯器都有提供這些參數。
+ 照標準來寫程式的最主要目的就是,希望你寫出來的程式可以在所有編譯器上編譯、執行無誤,
+ 當程式可以達成上述目的時,就稱為 <firstterm>portable code(移植性良好的程式碼)</firstterm>。</para>
+
+ <para>一般來說,在撰寫程式時就應要注意『移植性』。
+ 否則。當想把程式拿到另外一台機器上跑的時候,就可能得需要重寫程式。</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -Wall -ansi -pedantic -o foobar foobar.c</userinput></screen>
+ </informalexample>
+
+ <para>上述指令會確認 <filename>foobar.c</filename> 內的語法是否符合標準,
+ 並且產生名為 <filename>foobar</filename> 的執行檔。</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-l<replaceable>library</replaceable></option></term>
+
+ <listitem>
+ <para>告訴 gcc 在連結(linking)程式時你需要用到的函式庫名稱。</para>
+
+ <para>最常見的情況就是,當你在程式中使用了 C 數學函式庫,
+ 跟其他作業平台不一樣的是,這函示學函式都不在標準函式庫(library)中,
+ 因此編譯器並不知道這函式庫名稱,你必須告訴編譯器要加上它才行。</para>
+
+ <para>規則很簡單,如果有個函式庫叫做 <filename>libsomething.a</filename>,
+ 就必須在編譯時加上參數 <option>-l<replaceable>something</replaceable></option> 才行。
+ 舉例來說,數學函式庫叫做 <filename>libm.a</filename>,
+ 所以你必須給 <command>cc</command> 的參數就是 <option>-lm</option>。
+ 一般情況下,通常會把這參數必須放在指令的最後。</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -o foobar foobar.c -lm</userinput>
+ </screen>
+ </informalexample>
+
+ <para>上面這指令會讓 gcc 跟數學函式庫作連結,以便你的程式可以呼叫函式庫內含的數學函式。</para>
+
+ <para>如果你正在編譯的程式是 C++ 程式碼,你還必須額外指定 <option>-lg++</option> 或者是
+ <option>-lstdc++</option>。
+ 如果你的 FreeBSD 是 2.2(含)以後版本,
+ 你可以用指令 <command>c++</command> 來取代 <command>cc</command>。
+ 在 FreeBSD 上 <command>c++</command> 也可以用 <command>g++</command> 取代。</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -o foobar foobar.cc -lg++</userinput> <lineannotation>適用 FreeBSD 2.1.6 或更早期的版本</lineannotation>
+&prompt.user; <userinput>cc -o foobar foobar.cc -lstdc++</userinput> <lineannotation>適用 FreeBSD 2.2 及之後的版本</lineannotation>
+&prompt.user; <userinput>c++ -o foobar foobar.cc</userinput>
+ </screen>
+ </informalexample>
+
+ <para>上述指令都會從原始檔 <filename>foobar.cc</filename> 編譯產生名為 <filename>fooboar</filename> 的執行檔。
+ 這邊要提醒的是在 &unix; 系統中 C++ 程式傳統都以 <filename>.C</filename>、
+ <filename>.cxx</filename> 或者是 <filename>.cc</filename> 作為副檔名,
+ 而非 &ms-dos; 那種以 <filename>.cpp</filename> 作為副檔名的命名方式(不過也越來越普遍了)。
+ <command>gcc</command> 會依副檔名來決定用哪一種編譯器編譯,
+ 然而,現在已經不再限制副檔名了,
+ 所以可以自由的使用 <filename>.cpp</filename> 作為 C++ 程式碼的副檔名!</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <sect2>
+ <title>常見的 <command>cc</command> 問題</title>
+
+ <qandaset>
+ <qandaentry>
+ <question>
+ <para>我用 <function>sin()</function> 函示撰寫我的程式,
+ 但是有個錯誤訊息(如下),這代表著?</para>
+
+ <informalexample>
+ <screen>/var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment
+ </screen>
+ </informalexample>
+ </question>
+
+ <answer>
+ <para>當使用 <function>sin()</function> 這類的數學函示時,
+ 你必須告訴 cc 要和數學函式庫作連結(linking),就像這樣:</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -o foobar foobar.c -lm</userinput>
+ </screen>
+ </informalexample>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>好吧,我試著寫些簡單的程式,來練習使用 -lm 選項(該程式會運算 2.1 的 6 次方)</para>
+
+ <informalexample>
+ <programlisting>#include &lt;stdio.h&gt;
+
+int main() {
+ float f;
+
+ f = pow(2.1, 6);
+ printf("2.1 ^ 6 = %f\n", f);
+ return 0;
+}
+ </programlisting>
+ </informalexample>
+
+ <para>然後進行編譯:</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc temp.c -lm</userinput>
+ </screen>
+ </informalexample>
+
+ <para>編譯後執行程式,得到下面這結果:</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>./a.out</userinput>
+2.1 ^ 6 = 1023.000000
+ </screen>
+ </informalexample>
+
+ <para>很明顯的,程式結果<emphasis>不是</emphasis>正確答案,到底是哪邊出錯?</para>
+ </question>
+
+ <answer>
+ <para>當編譯器發現你呼叫一個函示時,它會確認該函示的回傳值類型(prototype),
+ 如果沒有特別指明,則預設的回傳值類型為 <type>int(整數)</type>。
+ 很明顯的,你的程式所需要的並不是回傳值類別為 <type>int</type>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>那如何才可以修正剛所說的問題?</para>
+ </question>
+
+ <answer>
+ <para>數學函示的回傳值類型(prototype)會定義在 <filename>math.h</filename>,
+ 如果你有 include 這檔,編譯器就會知道該函示的回傳值類型,如此一來該運算就會得到正確的結果!</para>
+
+ <informalexample>
+ <programlisting>#include &lt;math.h&gt;
+#include &lt;stdio.h&gt;
+
+int main() {
+...
+ </programlisting>
+ </informalexample>
+
+ <para>加了上述內容之後,再重新編譯,最後執行:</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>./a.out</userinput>
+2.1 ^ 6 = 85.766121
+ </screen>
+ </informalexample>
+
+ <para>如果有用到數學函式,<emphasis>請確定</emphasis>要有 include <filename>math.h</filename> 這檔,
+ 而且記得要和數學函式庫作連結。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>已經編譯好 <filename>foobar.c</filename>,
+ 但是編譯後找不到 <filename>foobar</filename> 執行檔。 該去哪邊找呢?</para>
+ </question>
+
+ <answer>
+ <para>記得,除非有指定編譯結果的執行檔檔名,否則預設的執行檔檔名是 a.out。
+ 用 <option>-o&nbsp;<replaceable>filename</replaceable></option> 參數,
+ 就可以達到所想要的結果,比如:</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>cc -o foobar foobar.c</userinput>
+ </screen>
+ </informalexample>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>好,有個編譯好的程式叫做 <filename>foobar</filename>,
+ 用 <command>ls</command> 指令時可以看到,
+ 但執行時,訊息卻說卻沒有這檔案。為什麼?</para>
+ </question>
+
+ <answer>
+ <para>與 &ms-dos; 不同的是,除非有指定執行檔的路徑,
+ 否則 &unix; 系統並不會在目前的目錄下尋找你想執行的檔案。
+ 在指令列下打 <command>./foobar</command> 代表
+ <quote>執行在這個目錄底下名為 <filename>foobar</filename> 的程式</quote>,
+ 或者也可以更改 <envar>PATH</envar> 環境變數設定如下,以達成類似效果:</para>
+
+ <informalexample>
+ <screen>bin:/usr/bin:/usr/local/bin:.
+ </screen>
+ </informalexample>
+
+ <para>上一行最後的 "." 代表<quote>如果在前面寫的其他目錄找不到,就找目前的目錄</quote>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>試著執行 <filename>test</filename> 執行檔,
+ 但是卻沒有任何事發生,到底是哪裡出錯了?</para>
+ </question>
+
+ <answer>
+ <para>大多數的 &unix; 系統都會在路徑 <filename>/usr/bin</filename> 擺放執行檔。
+ 除非有指定使用在目前目錄內的 <filename>test</filename>,否則 shell 會優先選擇位在
+ <filename>/usr/bin</filename> 的 <filename>test</filename>,
+ 要指定檔名的話,作法類似:</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>./test</userinput>
+ </screen>
+ </informalexample>
+
+ <para>為了避免上述困擾,請為你的程式取更好的名稱吧!</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>當執行我寫的程式時剛開始正常,
+ 接下來卻出現 <errorname>core dumped</errorname> 錯誤訊息。這錯誤訊息到底代表什麼?</para>
+ </question>
+
+ <answer>
+ <para>關於 <firstterm>core dumped</firstterm> 這個名稱的由來,
+ 可以追溯到早期的 &unix; 系統開始使用 core memory 對資料排序時。
+ 基本上當程式在很多情況下發生錯誤後,
+ 作業系統會把 core memory 中的資訊寫入 <filename>core</filename> 這檔案中,
+ 以便讓 programmer 知道程式到底是為何出錯。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>真是太神奇了!程式居然發生 <errorname>core dumped</errorname> 了,該怎麼辦?</para>
+ </question>
+
+ <answer>
+ <para>請用 <command>gdb</command> 來分析 core 結果(詳情請參考 <xref linkend="debugging"/>)。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>當程式已經把 core memory 資料 dump 出來後,
+ 同時也出現另一個錯誤 <errorname>segmentation fault</errorname> 這意思是?</para>
+ </question>
+
+ <answer>
+ <para>基本上,這個錯誤表示你的程式在記憶體中試著做一個嚴重的非法運作(illegal operation),
+ &unix; 就是被設計來保護整個作業系統免於被惡質的程式破壞,所以才會告訴你這個訊息。</para>
+
+ <para>最常造成<quote>segmentation fault</quote>的原因通常為:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>試著對一個 <symbol>NULL</symbol> 的指標(pointer)作寫入的動作,如</para>
+
+ <programlisting>char *foo = NULL;
+strcpy(foo, "bang!");
+ </programlisting>
+ </listitem>
+
+ <listitem>
+ <para>使用一個尚未初始化(initialized)的指標,如:</para>
+
+ <programlisting>char *foo;
+strcpy(foo, "bang!");
+ </programlisting>
+
+ <para>尚未初始化的指標的初始值將會是隨機的,如果你夠幸運的話,
+ 這個指標的初始值會指向 kernel 已經用到的記憶體位置,
+ kernel 會結束掉這個程式以確保系統運作正常。如果你不夠幸運,
+ 初始指到的記憶體位置是你程式必須要用到的資料結構(data structures)的位置,
+ 當這個情形發生時程式將會當的不知其所以然。</para>
+ </listitem>
+
+ <listitem>
+ <para>試著寫入超過陣列(array)元素個數,如:</para>
+
+ <programlisting>int bar[20];
+bar[27] = 6;
+ </programlisting>
+ </listitem>
+
+ <listitem>
+ <para>試著讀寫在唯讀記憶體(read-only memory)中的資料,如:</para>
+
+ <programlisting>char *foo = "My string";
+strcpy(foo, "bang!");
+ </programlisting>
+
+ <para>&unix; compilers often put string literals like
+ <literal>"My string"</literal> into read-only areas
+ of memory.</para>
+ </listitem>
+
+ <listitem>
+ <para>Doing naughty things with
+ <function>malloc()</function> and
+ <function>free()</function>, eg</para>
+
+ <programlisting>char bar[80];
+free(bar);
+ </programlisting>
+
+ <para>or</para>
+
+ <programlisting>char *foo = malloc(27);
+free(foo);
+free(foo);
+ </programlisting>
+ </listitem>
+ </itemizedlist>
+
+ <para>Making one of these mistakes will not always lead to
+ an error, but they are always bad practice. Some
+ systems and compilers are more tolerant than others,
+ which is why programs that ran well on one system can
+ crash when you try them on an another.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>Sometimes when I get a core dump it says
+ <errorname>bus error</errorname>. It says in my &unix;
+ book that this means a hardware problem, but the
+ computer still seems to be working. Is this
+ true?</para>
+ </question>
+
+ <answer>
+ <para>No, fortunately not (unless of course you really do
+ have a hardware problem&hellip;). This is usually
+ another way of saying that you accessed memory in a way
+ you should not have.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>This dumping core business sounds as though it could
+ be quite useful, if I can make it happen when I want to.
+ Can I do this, or do I have to wait until there is an
+ error?</para>
+ </question>
+
+ <answer>
+ <para>Yes, just go to another console or xterm, do</para>
+
+ <screen>&prompt.user; <userinput>ps</userinput>
+ </screen>
+
+ <para>to find out the process ID of your program, and
+ do</para>
+
+ <screen>&prompt.user; <userinput>kill -ABRT pid</userinput>
+ </screen>
+
+ <para>where
+ <parameter><replaceable>pid</replaceable></parameter> is
+ the process ID you looked up.</para>
+
+ <para>This is useful if your program has got stuck in an
+ infinite loop, for instance. If your program happens to
+ trap <symbol>SIGABRT</symbol>, there are several other
+ signals which have a similar effect.</para>
+
+ <para>Alternatively, you can create a core dump from
+ inside your program, by calling the
+ <function>abort()</function> function. See the manual page
+ of &man.abort.3; to learn more.</para>
+
+ <para>If you want to create a core dump from outside your
+ program, but do not want the process to terminate, you
+ can use the <command>gcore</command> program. See the
+ manual page of &man.gcore.1; for more information.</para>
+
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="tools-make">
+ <title>Make</title>
+
+ <sect2>
+ <title>What is <command>make</command>?</title>
+
+ <para>When you are working on a simple program with only one or
+ two source files, typing in</para>
+
+ <screen>&prompt.user; <userinput>cc file1.c file2.c</userinput></screen>
+
+ <para>is not too bad, but it quickly becomes very tedious when
+ there are several files&mdash;and it can take a while to
+ compile, too.</para>
+
+ <para>One way to get around this is to use object files and only
+ recompile the source file if the source code has changed. So
+ we could have something like:</para>
+
+ <screen>&prompt.user; <userinput>cc file1.o file2.o</userinput> &hellip; <userinput>file37.c</userinput> &hellip;</screen>
+
+ <para>if we had changed <filename>file37.c</filename>, but not any
+ of the others, since the last time we compiled. This may
+ speed up the compilation quite a bit, but does not solve the
+ typing problem.</para>
+
+ <para>Or we could write a shell script to solve the typing
+ problem, but it would have to re-compile everything, making it
+ very inefficient on a large project.</para>
+
+ <para>What happens if we have hundreds of source files lying
+ about? What if we are working in a team with other people who
+ forget to tell us when they have changed one of their source
+ files that we use?</para>
+
+ <para>Perhaps we could put the two solutions together and write
+ something like a shell script that would contain some kind of
+ magic rule saying when a source file needs compiling. Now all
+ we need now is a program that can understand these rules, as
+ it is a bit too complicated for the shell.</para>
+
+ <para>This program is called <command>make</command>. It reads
+ in a file, called a <firstterm>makefile</firstterm>, that
+ tells it how different files depend on each other, and works
+ out which files need to be re-compiled and which ones do not.
+ For example, a rule could say something like <quote>if
+ <filename>fromboz.o</filename> is older than
+ <filename>fromboz.c</filename>, that means someone must have
+ changed <filename>fromboz.c</filename>, so it needs to be
+ re-compiled.</quote> The makefile also has rules telling
+ make <emphasis>how</emphasis> to re-compile the source file,
+ making it a much more powerful tool.</para>
+
+ <para>Makefiles are typically kept in the same directory as the
+ source they apply to, and can be called
+ <filename>makefile</filename>, <filename>Makefile</filename>
+ or <filename>MAKEFILE</filename>. Most programmers use the
+ name <filename>Makefile</filename>, as this puts it near the
+ top of a directory listing, where it can easily be
+ seen.
+
+ <footnote>
+ <para>They do not use the <filename>MAKEFILE</filename> form
+ as block capitals are often used for documentation files
+ like <filename>README</filename>.</para>
+ </footnote></para>
+ </sect2>
+
+ <sect2>
+ <title>Example of using <command>make</command></title>
+
+ <para>Here is a very simple make file:</para>
+
+ <programlisting>foo: foo.c
+ cc -o foo foo.c</programlisting>
+
+ <para>It consists of two lines, a dependency line and a creation
+ line.</para>
+
+ <para>The dependency line here consists of the name of the
+ program (known as the <firstterm>target</firstterm>), followed
+ by a colon, then whitespace, then the name of the source file.
+ When <command>make</command> reads this line, it looks to see
+ if <filename>foo</filename> exists; if it exists, it compares
+ the time <filename>foo</filename> was last modified to the
+ time <filename>foo.c</filename> was last modified. If
+ <filename>foo</filename> does not exist, or is older than
+ <filename>foo.c</filename>, it then looks at the creation line
+ to find out what to do. In other words, this is the rule for
+ working out when <filename>foo.c</filename> needs to be
+ re-compiled.</para>
+
+ <para>The creation line starts with a <token>tab</token> (press
+ the <keycap>tab</keycap> key) and then the command you would
+ type to create <filename>foo</filename> if you were doing it
+ at a command prompt. If <filename>foo</filename> is out of
+ date, or does not exist, <command>make</command> then executes
+ this command to create it. In other words, this is the rule
+ which tells make how to re-compile
+ <filename>foo.c</filename>.</para>
+
+ <para>So, when you type <userinput>make</userinput>, it will
+ make sure that <filename>foo</filename> is up to date with
+ respect to your latest changes to <filename>foo.c</filename>.
+ This principle can be extended to
+ <filename>Makefile</filename>s with hundreds of
+ targets&mdash;in fact, on FreeBSD, it is possible to compile
+ the entire operating system just by typing <userinput>make
+ world</userinput> in the appropriate directory!</para>
+
+ <para>Another useful property of makefiles is that the targets
+ do not have to be programs. For instance, we could have a make
+ file that looks like this:</para>
+
+ <programlisting>foo: foo.c
+ cc -o foo foo.c
+
+install:
+ cp foo /home/me</programlisting>
+
+ <para>We can tell make which target we want to make by
+ typing:</para>
+
+ <screen>&prompt.user; <userinput>make target</userinput></screen>
+
+ <para><command>make</command> will then only look at that target
+ and ignore any others. For example, if we type
+ <userinput>make foo</userinput> with the makefile above, make
+ will ignore the <buildtarget>install</buildtarget> target.</para>
+
+ <para>If we just type <userinput>make</userinput> on its own,
+ make will always look at the first target and then stop
+ without looking at any others. So if we typed
+ <userinput>make</userinput> here, it will just go to the
+ <buildtarget>foo</buildtarget> target, re-compile
+ <filename>foo</filename> if necessary, and then stop without
+ going on to the <buildtarget>install</buildtarget> target.</para>
+
+ <para>Notice that the <buildtarget>install</buildtarget> target does not
+ actually depend on anything! This means that the command on
+ the following line is always executed when we try to make that
+ target by typing <userinput>make install</userinput>. In this
+ case, it will copy <filename>foo</filename> into the user's
+ home directory. This is often used by application makefiles,
+ so that the application can be installed in the correct
+ directory when it has been correctly compiled.</para>
+
+ <para>This is a slightly confusing subject to try to explain.
+ If you do not quite understand how <command>make</command>
+ works, the best thing to do is to write a simple program like
+ <quote>hello world</quote> and a make file like the one above
+ and experiment. Then progress to using more than one source
+ file, or having the source file include a header file. The
+ <command>touch</command> command is very useful here&mdash;it
+ changes the date on a file without you having to edit
+ it.</para>
+ </sect2>
+
+ <sect2>
+ <title>Make and include-files</title>
+
+ <para>C code often starts with a list of files to include, for
+ example stdio.h. Some of these files are system-include
+ files, some of them are from the project you are now working
+ on:
+ </para>
+
+ <programlisting>#include &lt;stdio.h&gt;
+#include "foo.h"
+
+int main(....</programlisting>
+
+ <para>To make sure that this file is recompiled the moment
+ <filename>foo.h</filename> is changed, you have to add it in
+ your <filename>Makefile</filename>:</para>
+
+ <programlisting>foo: foo.c foo.h</programlisting>
+
+ <para>The moment your project is getting bigger and you have
+ more and more own include-files to maintain, it will be a
+ pain to keep track of all include files and the files which
+ are depending on it. If you change an include-file but
+ forget to recompile all the files which are depending on
+ it, the results will be devastating. <command>gcc</command>
+ has an option to analyze your files and to produce a list
+ of include-files and their dependencies: <option>-MM</option>.
+ </para>
+
+ <para>If you add this to your Makefile:</para>
+
+ <programlisting>depend:
+ gcc -E -MM *.c &gt; .depend</programlisting>
+
+ <para>and run <userinput>make depend</userinput>, the file
+ <filename>.depend</filename> will appear with a list of
+ object-files, C-files and the include-files:</para>
+
+ <programlisting>foo.o: foo.c foo.h</programlisting>
+
+ <para>If you change <filename>foo.h</filename>, next time
+ you run <command>make</command> all files depending on
+ <filename>foo.h</filename> will be recompiled.</para>
+
+ <para>Do not forget to run <command>make depend</command> each
+ time you add an include-file to one of your files.</para>
+ </sect2>
+
+ <sect2>
+ <title>FreeBSD Makefiles</title>
+
+ <para>Makefiles can be rather complicated to write. Fortunately,
+ BSD-based systems like FreeBSD come with some very powerful
+ ones as part of the system. One very good example of this is
+ the FreeBSD ports system. Here is the essential part of a
+ typical ports <filename>Makefile</filename>:</para>
+
+ <programlisting>MASTER_SITES= ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/
+DISTFILES= scheme-microcode+dist-7.3-freebsd.tgz
+
+.include &lt;bsd.port.mk&gt;</programlisting>
+
+ <para>Now, if we go to the directory for this port and type
+ <userinput>make</userinput>, the following happens:</para>
+
+ <procedure>
+ <step>
+ <para>A check is made to see if the source code for this
+ port is already on the system.</para>
+ </step>
+
+ <step>
+ <para>If it is not, an FTP connection to the URL in
+ <symbol>MASTER_SITES</symbol> is set up to download the
+ source.</para>
+ </step>
+
+ <step>
+ <para>The checksum for the source is calculated and compared
+ it with one for a known, good, copy of the source. This
+ is to make sure that the source was not corrupted while in
+ transit.</para>
+ </step>
+
+ <step>
+ <para>Any changes required to make the source work on
+ FreeBSD are applied&mdash;this is known as
+ <firstterm>patching</firstterm>.</para>
+ </step>
+
+ <step>
+ <para>Any special configuration needed for the source is
+ done. (Many &unix; program distributions try to work out
+ which version of &unix; they are being compiled on and which
+ optional &unix; features are present&mdash;this is where
+ they are given the information in the FreeBSD ports
+ scenario).</para>
+ </step>
+
+ <step>
+ <para>The source code for the program is compiled. In
+ effect, we change to the directory where the source was
+ unpacked and do <command>make</command>&mdash;the
+ program's own make file has the necessary information to
+ build the program.</para>
+ </step>
+
+ <step>
+ <para>We now have a compiled version of the program. If we
+ wish, we can test it now; when we feel confident about the
+ program, we can type <userinput>make install</userinput>.
+ This will cause the program and any supporting files it
+ needs to be copied into the correct location; an entry is
+ also made into a <database>package database</database>, so
+ that the port can easily be uninstalled later if we change
+ our mind about it.</para>
+ </step>
+ </procedure>
+
+ <para>Now I think you will agree that is rather impressive for a
+ four line script!</para>
+
+ <para>The secret lies in the last line, which tells
+ <command>make</command> to look in the system makefile called
+ <filename>bsd.port.mk</filename>. It is easy to overlook this
+ line, but this is where all the clever stuff comes
+ from&mdash;someone has written a makefile that tells
+ <command>make</command> to do all the things above (plus a
+ couple of other things I did not mention, including handling
+ any errors that may occur) and anyone can get access to that
+ just by putting a single line in their own make file!</para>
+
+ <para>If you want to have a look at these system makefiles,
+ they are in <filename>/usr/share/mk</filename>, but it is
+ probably best to wait until you have had a bit of practice with
+ makefiles, as they are very complicated (and if you do look at
+ them, make sure you have a flask of strong coffee
+ handy!)</para>
+ </sect2>
+
+ <sect2>
+ <title>More advanced uses of <command>make</command></title>
+
+ <para><command>Make</command> is a very powerful tool, and can
+ do much more than the simple example above shows.
+ Unfortunately, there are several different versions of
+ <command>make</command>, and they all differ considerably.
+ The best way to learn what they can do is probably to read the
+ documentation&mdash;hopefully this introduction will have
+ given you a base from which you can do this.</para>
+
+ <para>The version of make that comes with FreeBSD is the
+ <application>Berkeley make</application>; there is a tutorial
+ for it in <filename>/usr/share/doc/psd/12.make</filename>. To
+ view it, do</para>
+
+ <screen>&prompt.user; <userinput>zmore paper.ascii.gz</userinput></screen>
+
+ <para>in that directory.</para>
+
+ <para>Many applications in the ports use <application>GNU
+ make</application>, which has a very good set of
+ <quote>info</quote> pages. If you have installed any of these
+ ports, <application>GNU make</application> will automatically
+ have been installed as <command>gmake</command>. It is also
+ available as a port and package in its own right.</para>
+
+ <para>To view the info pages for <application>GNU
+ make</application>, you will have to edit the
+ <filename>dir</filename> file in the
+ <filename>/usr/local/info</filename> directory to add an entry
+ for it. This involves adding a line like</para>
+
+ <programlisting> * Make: (make). The GNU Make utility.</programlisting>
+
+ <para>to the file. Once you have done this, you can type
+ <userinput>info</userinput> and then select
+ <guimenuitem>make</guimenuitem> from the menu (or in
+ <application>Emacs</application>, do <userinput>C-h
+ i</userinput>).</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="debugging">
+ <title>Debugging</title>
+
+ <sect2>
+ <title>The Debugger</title>
+
+ <para>The debugger that comes with FreeBSD is called
+ <command>gdb</command> (<application>GNU
+ debugger</application>). You start it up by typing</para>
+
+ <screen>&prompt.user; <userinput>gdb progname</userinput></screen>
+
+ <para>although most people prefer to run it inside
+ <application>Emacs</application>. You can do this by:</para>
+
+ <screen><userinput>M-x gdb RET progname RET</userinput></screen>
+
+ <para>Using a debugger allows you to run the program under more
+ controlled circumstances. Typically, you can step through the
+ program a line at a time, inspect the value of variables,
+ change them, tell the debugger to run up to a certain point
+ and then stop, and so on. You can even attach to a program
+ that is already running, or load a core file to investigate why
+ the program crashed. It is even possible to debug the kernel,
+ though that is a little trickier than the user applications
+ we will be discussing in this section.</para>
+
+ <para><command>gdb</command> has quite good on-line help, as
+ well as a set of info pages, so this section will concentrate
+ on a few of the basic commands.</para>
+
+ <para>Finally, if you find its text-based command-prompt style
+ off-putting, there is a graphical front-end for it (<link xlink:href="&url.base;/ports/devel.html">xxgdb</link>) in the ports
+ collection.</para>
+
+ <para>This section is intended to be an introduction to using
+ <command>gdb</command> and does not cover specialized topics
+ such as debugging the kernel.</para>
+ </sect2>
+
+ <sect2>
+ <title>Running a program in the debugger</title>
+
+ <para>You will need to have compiled the program with the
+ <option>-g</option> option to get the most out of using
+ <command>gdb</command>. It will work without, but you will only
+ see the name of the function you are in, instead of the source
+ code. If you see a line like:</para>
+
+ <screen>&hellip; (no debugging symbols found) &hellip;</screen>
+
+ <para>when <command>gdb</command> starts up, you will know that
+ the program was not compiled with the <option>-g</option>
+ option.</para>
+
+ <para>At the <command>gdb</command> prompt, type
+ <userinput>break main</userinput>. This will tell the
+ debugger to skip over the preliminary set-up code in the
+ program and start at the beginning of your code. Now type
+ <userinput>run</userinput> to start the program&mdash;it will
+ start at the beginning of the set-up code and then get stopped
+ by the debugger when it calls <function>main()</function>.
+ (If you have ever wondered where <function>main()</function>
+ gets called from, now you know!).</para>
+
+ <para>You can now step through the program, a line at a time, by
+ pressing <command>n</command>. If you get to a function call,
+ you can step into it by pressing <command>s</command>. Once
+ you are in a function call, you can return from stepping into a
+ function call by pressing <command>f</command>. You can also
+ use <command>up</command> and <command>down</command> to take
+ a quick look at the caller.</para>
+
+ <para>Here is a simple example of how to spot a mistake in a
+ program with <command>gdb</command>. This is our program
+ (with a deliberate mistake):</para>
+
+ <programlisting>#include &lt;stdio.h&gt;
+
+int bazz(int anint);
+
+main() {
+ int i;
+
+ printf("This is my program\n");
+ bazz(i);
+ return 0;
+}
+
+int bazz(int anint) {
+ printf("You gave me %d\n", anint);
+ return anint;
+}</programlisting>
+
+ <para>This program sets <symbol>i</symbol> to be
+ <literal>5</literal> and passes it to a function
+ <function>bazz()</function> which prints out the number we
+ gave it.</para>
+
+ <para>When we compile and run the program we get</para>
+
+ <screen>&prompt.user; <userinput>cc -g -o temp temp.c</userinput>
+&prompt.user; <userinput>./temp</userinput>
+This is my program
+anint = 4231</screen>
+
+ <para>That was not what we expected! Time to see what is going
+ on!</para>
+
+ <screen>&prompt.user; <userinput>gdb temp</userinput>
+GDB is free software and you are welcome to distribute copies of it
+ under certain conditions; type "show copying" to see the conditions.
+There is absolutely no warranty for GDB; type "show warranty" for details.
+GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
+(gdb) <userinput>break main</userinput> <lineannotation>Skip the set-up code</lineannotation>
+Breakpoint 1 at 0x160f: file temp.c, line 9. <lineannotation>gdb puts breakpoint at main()</lineannotation>
+(gdb) <userinput>run</userinput> <lineannotation>Run as far as main()</lineannotation>
+Starting program: /home/james/tmp/temp <lineannotation>Program starts running</lineannotation>
+
+Breakpoint 1, main () at temp.c:9 <lineannotation>gdb stops at main()</lineannotation>
+(gdb) <userinput>n</userinput> <lineannotation>Go to next line</lineannotation>
+This is my program <lineannotation>Program prints out</lineannotation>
+(gdb) <userinput>s</userinput> <lineannotation>step into bazz()</lineannotation>
+bazz (anint=4231) at temp.c:17 <lineannotation>gdb displays stack frame</lineannotation>
+(gdb)</screen>
+
+ <para>Hang on a minute! How did <symbol>anint</symbol> get to be
+ <literal>4231</literal>? Did we not we set it to be
+ <literal>5</literal> in <function>main()</function>? Let's
+ move up to <function>main()</function> and have a look.</para>
+
+ <screen>(gdb) <userinput>up</userinput> <lineannotation>Move up call stack</lineannotation>
+#1 0x1625 in main () at temp.c:11 <lineannotation>gdb displays stack frame</lineannotation>
+(gdb) <userinput>p i</userinput> <lineannotation>Show us the value of i</lineannotation>
+$1 = 4231 <lineannotation>gdb displays 4231</lineannotation></screen>
+
+ <para>Oh dear! Looking at the code, we forgot to initialize
+ <symbol>i</symbol>. We meant to put</para>
+
+ <programlisting><lineannotation>&hellip;</lineannotation>
+main() {
+ int i;
+
+ i = 5;
+ printf("This is my program\n");
+<lineannotation>&hellip;</lineannotation></programlisting>
+
+ <para>but we left the <literal>i=5;</literal> line out. As we
+ did not initialize <symbol>i</symbol>, it had whatever number
+ happened to be in that area of memory when the program ran,
+ which in this case happened to be
+ <literal>4231</literal>.</para>
+
+ <note>
+ <para><command>gdb</command> displays the stack frame every
+ time we go into or out of a function, even if we are using
+ <command>up</command> and <command>down</command> to move
+ around the call stack. This shows the name of the function
+ and the values of its arguments, which helps us keep track
+ of where we are and what is going on. (The stack is a
+ storage area where the program stores information about the
+ arguments passed to functions and where to go when it
+ returns from a function call).</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Examining a core file</title>
+
+ <para>A core file is basically a file which contains the
+ complete state of the process when it crashed. In <quote>the
+ good old days</quote>, programmers had to print out hex
+ listings of core files and sweat over machine code manuals,
+ but now life is a bit easier. Incidentally, under FreeBSD and
+ other 4.4BSD systems, a core file is called
+ <filename>progname.core</filename> instead of just
+ <filename>core</filename>, to make it clearer which program a
+ core file belongs to.</para>
+
+ <para>To examine a core file, start up <command>gdb</command> in
+ the usual way. Instead of typing <command>break</command> or
+ <command>run</command>, type</para>
+
+ <screen>(gdb) <userinput>core progname.core</userinput></screen>
+
+ <para>If you are not in the same directory as the core file,
+ you will have to do <userinput>dir
+ /path/to/core/file</userinput> first.</para>
+
+ <para>You should see something like this:</para>
+
+ <screen>&prompt.user; <userinput>gdb a.out</userinput>
+GDB is free software and you are welcome to distribute copies of it
+ under certain conditions; type "show copying" to see the conditions.
+There is absolutely no warranty for GDB; type "show warranty" for details.
+GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
+(gdb) <userinput>core a.out.core</userinput>
+Core was generated by `a.out'.
+Program terminated with signal 11, Segmentation fault.
+Cannot access memory at address 0x7020796d.
+#0 0x164a in bazz (anint=0x5) at temp.c:17
+(gdb)</screen>
+
+ <para>In this case, the program was called
+ <filename>a.out</filename>, so the core file is called
+ <filename>a.out.core</filename>. We can see that the program
+ crashed due to trying to access an area in memory that was not
+ available to it in a function called
+ <function>bazz</function>.</para>
+
+ <para>Sometimes it is useful to be able to see how a function was
+ called, as the problem could have occurred a long way up the
+ call stack in a complex program. The <command>bt</command>
+ command causes <command>gdb</command> to print out a
+ back-trace of the call stack:</para>
+
+ <screen>(gdb) <userinput>bt</userinput>
+#0 0x164a in bazz (anint=0x5) at temp.c:17
+#1 0xefbfd888 in end ()
+#2 0x162c in main () at temp.c:11
+(gdb)</screen>
+
+ <para>The <function>end()</function> function is called when a
+ program crashes; in this case, the <function>bazz()</function>
+ function was called from <function>main()</function>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Attaching to a running program</title>
+
+ <para>One of the neatest features about <command>gdb</command>
+ is that it can attach to a program that is already running. Of
+ course, that assumes you have sufficient permissions to do so.
+ A common problem is when you are stepping through a program
+ that forks, and you want to trace the child, but the debugger
+ will only let you trace the parent.</para>
+
+ <para>What you do is start up another <command>gdb</command>,
+ use <command>ps</command> to find the process ID for the
+ child, and do</para>
+
+ <screen>(gdb) <userinput>attach pid</userinput></screen>
+
+ <para>in <command>gdb</command>, and then debug as usual.</para>
+
+ <para><quote>That is all very well,</quote> you are probably
+ thinking, <quote>but by the time I have done that, the child
+ process will be over the hill and far away</quote>. Fear
+ not, gentle reader, here is how to do it (courtesy of the
+ <command>gdb</command> info pages):</para>
+
+ <screen><lineannotation>&hellip;</lineannotation>
+if ((pid = fork()) &lt; 0) /* _Always_ check this */
+ error();
+else if (pid == 0) { /* child */
+ int PauseMode = 1;
+
+ while (PauseMode)
+ sleep(10); /* Wait until someone attaches to us */
+ <lineannotation>&hellip;</lineannotation>
+} else { /* parent */
+ <lineannotation>&hellip;</lineannotation></screen>
+
+ <para>Now all you have to do is attach to the child, set
+ <symbol>PauseMode</symbol> to <literal>0</literal>, and wait
+ for the <function>sleep()</function> call to return!</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="emacs">
+ <title>Using Emacs as a Development Environment</title>
+
+ <sect2>
+ <title>Emacs</title>
+
+ <para>Unfortunately, &unix; systems do not come with the kind of
+ everything-you-ever-wanted-and-lots-more-you-did-not-in-one-gigantic-package
+ integrated development environments that other systems
+ have.
+
+ <footnote>
+ <para>Some powerful, free IDEs now exist, such as KDevelop
+ in the ports collection.</para>
+ </footnote>
+
+ However, it is possible to set up your own environment. It
+ may not be as pretty, and it may not be quite as integrated,
+ but you can set it up the way you want it. And it is free.
+ And you have the source to it.</para>
+
+ <para>The key to it all is Emacs. Now there are some people who
+ loathe it, but many who love it. If you are one of the former,
+ I am afraid this section will hold little of interest to you.
+ Also, you will need a fair amount of memory to run it&mdash;I would
+ recommend 8MB in text mode and 16MB in X as the bare minimum
+ to get reasonable performance.</para>
+
+ <para>Emacs is basically a highly customizable
+ editor&mdash;indeed, it has been customized to the point where
+ it is more like an operating system than an editor! Many
+ developers and sysadmins do in fact spend practically all
+ their time working inside Emacs, leaving it only to log
+ out.</para>
+
+ <para>It is impossible even to summarize everything Emacs can do
+ here, but here are some of the features of interest to
+ developers:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Very powerful editor, allowing search-and-replace on
+ both strings and regular expressions (patterns), jumping
+ to start/end of block expression, etc, etc.</para>
+ </listitem>
+
+ <listitem>
+ <para>Pull-down menus and online help.</para>
+ </listitem>
+
+ <listitem>
+ <para>Language-dependent syntax highlighting and
+ indentation.</para>
+ </listitem>
+
+ <listitem>
+ <para>Completely customizable.</para>
+ </listitem>
+
+ <listitem>
+ <para>You can compile and debug programs within
+ Emacs.</para>
+ </listitem>
+
+ <listitem>
+ <para>On a compilation error, you can jump to the offending
+ line of source code.</para>
+ </listitem>
+
+ <listitem>
+ <para>Friendly-ish front-end to the <command>info</command>
+ program used for reading GNU hypertext documentation,
+ including the documentation on Emacs itself.</para>
+ </listitem>
+
+ <listitem>
+ <para>Friendly front-end to <command>gdb</command>, allowing
+ you to look at the source code as you step through your
+ program.</para>
+ </listitem>
+
+ <listitem>
+ <para>You can read Usenet news and mail while your program
+ is compiling.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>And doubtless many more that I have overlooked.</para>
+
+ <para>Emacs can be installed on FreeBSD using <link xlink:href="&url.base;/ports/editors.html">the Emacs
+ port</link>.</para>
+
+ <para>Once it is installed, start it up and do <userinput>C-h
+ t</userinput> to read an Emacs tutorial&mdash;that means
+ hold down the <keycap>control</keycap> key, press
+ <keycap>h</keycap>, let go of the <keycap>control</keycap>
+ key, and then press <keycap>t</keycap>. (Alternatively, you
+ can you use the mouse to select <guimenuitem>Emacs
+ Tutorial</guimenuitem> from the <guimenu>Help</guimenu>
+ menu).</para>
+
+ <para>Although Emacs does have menus, it is well worth learning
+ the key bindings, as it is much quicker when you are editing
+ something to press a couple of keys than to try to find the
+ mouse and then click on the right place. And, when you are
+ talking to seasoned Emacs users, you will find they often
+ casually throw around expressions like <quote><literal>M-x
+ replace-s RET foo RET bar RET</literal></quote> so it is
+ useful to know what they mean. And in any case, Emacs has far
+ too many useful functions for them to all fit on the menu
+ bars.</para>
+
+ <para>Fortunately, it is quite easy to pick up the key-bindings,
+ as they are displayed next to the menu item. My advice is to
+ use the menu item for, say, opening a file until you
+ understand how it works and feel confident with it, then try
+ doing C-x C-f. When you are happy with that, move on to
+ another menu command.</para>
+
+ <para>If you can not remember what a particular combination of
+ keys does, select <guimenuitem>Describe Key</guimenuitem> from
+ the <guimenu>Help</guimenu> menu and type it in&mdash;Emacs
+ will tell you what it does. You can also use the
+ <guimenuitem>Command Apropos</guimenuitem> menu item to find
+ out all the commands which contain a particular word in them,
+ with the key binding next to it.</para>
+
+ <para>By the way, the expression above means hold down the
+ <keysym>Meta</keysym> key, press <keysym>x</keysym>, release
+ the <keysym>Meta</keysym> key, type
+ <userinput>replace-s</userinput> (short for
+ <literal>replace-string</literal>&mdash;another feature of
+ Emacs is that you can abbreviate commands), press the
+ <keysym>return</keysym> key, type <userinput>foo</userinput>
+ (the string you want replaced), press the
+ <keysym>return</keysym> key, type bar (the string you want to
+ replace <literal>foo</literal> with) and press
+ <keysym>return</keysym> again. Emacs will then do the
+ search-and-replace operation you have just requested.</para>
+
+ <para>If you are wondering what on earth the
+ <keysym>Meta</keysym> key is, it is a special key that many
+ &unix; workstations have. Unfortunately, PC's do not have one,
+ so it is usually the <keycap>alt</keycap> key (or if you are
+ unlucky, the <keysym>escape</keysym> key).</para>
+
+ <para>Oh, and to get out of Emacs, do <command>C-x C-c</command>
+ (that means hold down the <keysym>control</keysym> key, press
+ <keysym>x</keysym>, press <keysym>c</keysym> and release the
+ <keysym>control</keysym> key). If you have any unsaved files
+ open, Emacs will ask you if you want to save them. (Ignore
+ the bit in the documentation where it says
+ <command>C-z</command> is the usual way to leave
+ Emacs&mdash;that leaves Emacs hanging around in the
+ background, and is only really useful if you are on a system
+ which does not have virtual terminals).</para>
+ </sect2>
+
+ <sect2>
+ <title>Configuring Emacs</title>
+
+ <para>Emacs does many wonderful things; some of them are built
+ in, some of them need to be configured.</para>
+
+ <para>Instead of using a proprietary macro language for
+ configuration, Emacs uses a version of Lisp specially adapted
+ for editors, known as Emacs Lisp. Working with Emacs Lisp can
+ be quite helpful if you want to go on and learn something like
+ Common Lisp. Emacs Lisp has many features of Common Lisp,
+ although it is considerably smaller (and thus easier to
+ master).</para>
+
+ <para>The best way to learn Emacs Lisp is to download the <link xlink:href="ftp://ftp.gnu.org/old-gnu/emacs/elisp-manual-19-2.4.tar.gz">Emacs
+ Tutorial</link></para>
+
+ <para>However, there is no need to actually know any Lisp to get
+ started with configuring Emacs, as I have included a sample
+ <filename>.emacs</filename> file, which should be enough to
+ get you started. Just copy it into your home directory and
+ restart Emacs if it is already running; it will read the
+ commands from the file and (hopefully) give you a useful basic
+ setup.</para>
+ </sect2>
+
+ <sect2>
+ <title>A sample <filename>.emacs</filename> file</title>
+
+ <para>Unfortunately, there is far too much here to explain it in
+ detail; however there are one or two points worth
+ mentioning.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Everything beginning with a <literal>;</literal> is a comment
+ and is ignored by Emacs.</para>
+ </listitem>
+
+ <listitem>
+ <para>In the first line, the
+ <literal>-*-&nbsp;Emacs-Lisp&nbsp;-*-</literal> is so that
+ we can edit the <filename>.emacs</filename> file itself
+ within Emacs and get all the fancy features for editing
+ Emacs Lisp. Emacs usually tries to guess this based on
+ the filename, and may not get it right for
+ <filename>.emacs</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <keysym>tab</keysym> key is bound to an
+ indentation function in some modes, so when you press the
+ tab key, it will indent the current line of code. If you
+ want to put a <token>tab</token> character in whatever
+ you are writing, hold the <keysym>control</keysym> key down
+ while you are pressing the <keysym>tab</keysym> key.</para>
+ </listitem>
+
+ <listitem>
+ <para>This file supports syntax highlighting for C, C++,
+ Perl, Lisp and Scheme, by guessing the language from the
+ filename.</para>
+ </listitem>
+
+ <listitem>
+ <para>Emacs already has a pre-defined function called
+ <function>next-error</function>. In a compilation output
+ window, this allows you to move from one compilation error
+ to the next by doing <command>M-n</command>; we define a
+ complementary function,
+ <function>previous-error</function>, that allows you to go
+ to a previous error by doing <command>M-p</command>. The
+ nicest feature of all is that <command>C-c C-c</command>
+ will open up the source file in which the error occurred
+ and jump to the appropriate line.</para>
+ </listitem>
+
+ <listitem>
+ <para>We enable Emacs's ability to act as a server, so that
+ if you are doing something outside Emacs and you want to
+ edit a file, you can just type in</para>
+
+ <screen>&prompt.user; <userinput>emacsclient filename</userinput>
+ </screen>
+
+ <para>and then you can edit the file in your
+ Emacs!
+
+ <footnote>
+ <para>Many Emacs users set their <envar>EDITOR</envar>
+ environment to
+ <literal>emacsclient</literal> so this happens every
+ time they need to edit a file.</para>
+ </footnote></para>
+ </listitem>
+ </itemizedlist>
+
+ <example>
+ <title>A sample <filename>.emacs</filename> file</title>
+
+ <programlisting>;; -*-Emacs-Lisp-*-
+
+;; This file is designed to be re-evaled; use the variable first-time
+;; to avoid any problems with this.
+(defvar first-time t
+ "Flag signifying this is the first time that .emacs has been evaled")
+
+;; Meta
+(global-set-key "\M- " 'set-mark-command)
+(global-set-key "\M-\C-h" 'backward-kill-word)
+(global-set-key "\M-\C-r" 'query-replace)
+(global-set-key "\M-r" 'replace-string)
+(global-set-key "\M-g" 'goto-line)
+(global-set-key "\M-h" 'help-command)
+
+;; Function keys
+(global-set-key [f1] 'manual-entry)
+(global-set-key [f2] 'info)
+(global-set-key [f3] 'repeat-complex-command)
+(global-set-key [f4] 'advertised-undo)
+(global-set-key [f5] 'eval-current-buffer)
+(global-set-key [f6] 'buffer-menu)
+(global-set-key [f7] 'other-window)
+(global-set-key [f8] 'find-file)
+(global-set-key [f9] 'save-buffer)
+(global-set-key [f10] 'next-error)
+(global-set-key [f11] 'compile)
+(global-set-key [f12] 'grep)
+(global-set-key [C-f1] 'compile)
+(global-set-key [C-f2] 'grep)
+(global-set-key [C-f3] 'next-error)
+(global-set-key [C-f4] 'previous-error)
+(global-set-key [C-f5] 'display-faces)
+(global-set-key [C-f8] 'dired)
+(global-set-key [C-f10] 'kill-compilation)
+
+;; Keypad bindings
+(global-set-key [up] "\C-p")
+(global-set-key [down] "\C-n")
+(global-set-key [left] "\C-b")
+(global-set-key [right] "\C-f")
+(global-set-key [home] "\C-a")
+(global-set-key [end] "\C-e")
+(global-set-key [prior] "\M-v")
+(global-set-key [next] "\C-v")
+(global-set-key [C-up] "\M-\C-b")
+(global-set-key [C-down] "\M-\C-f")
+(global-set-key [C-left] "\M-b")
+(global-set-key [C-right] "\M-f")
+(global-set-key [C-home] "\M-&lt;")
+(global-set-key [C-end] "\M-&gt;")
+(global-set-key [C-prior] "\M-&lt;")
+(global-set-key [C-next] "\M-&gt;")
+
+;; Mouse
+(global-set-key [mouse-3] 'imenu)
+
+;; Misc
+(global-set-key [C-tab] "\C-q\t") ; Control tab quotes a tab.
+(setq backup-by-copying-when-mismatch t)
+
+;; Treat 'y' or &lt;CR&gt; as yes, 'n' as no.
+(fset 'yes-or-no-p 'y-or-n-p)
+(define-key query-replace-map [return] 'act)
+(define-key query-replace-map [?\C-m] 'act)
+
+;; Load packages
+(require 'desktop)
+(require 'tar-mode)
+
+;; Pretty diff mode
+(autoload 'ediff-buffers "ediff" "Intelligent Emacs interface to diff" t)
+(autoload 'ediff-files "ediff" "Intelligent Emacs interface to diff" t)
+(autoload 'ediff-files-remote "ediff"
+ "Intelligent Emacs interface to diff")
+
+(if first-time
+ (setq auto-mode-alist
+ (append '(("\\.cpp$" . c++-mode)
+ ("\\.hpp$" . c++-mode)
+ ("\\.lsp$" . lisp-mode)
+ ("\\.scm$" . scheme-mode)
+ ("\\.pl$" . perl-mode)
+ ) auto-mode-alist)))
+
+;; Auto font lock mode
+(defvar font-lock-auto-mode-list
+ (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode)
+ "List of modes to always start in font-lock-mode")
+
+(defvar font-lock-mode-keyword-alist
+ '((c++-c-mode . c-font-lock-keywords)
+ (perl-mode . perl-font-lock-keywords))
+ "Associations between modes and keywords")
+
+(defun font-lock-auto-mode-select ()
+ "Automatically select font-lock-mode if the current major mode is in font-lock-auto-mode-list"
+ (if (memq major-mode font-lock-auto-mode-list)
+ (progn
+ (font-lock-mode t))
+ )
+ )
+
+(global-set-key [M-f1] 'font-lock-fontify-buffer)
+
+;; New dabbrev stuff
+;(require 'new-dabbrev)
+(setq dabbrev-always-check-other-buffers t)
+(setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
+(add-hook 'emacs-lisp-mode-hook
+ '(lambda ()
+ (set (make-local-variable 'dabbrev-case-fold-search) nil)
+ (set (make-local-variable 'dabbrev-case-replace) nil)))
+(add-hook 'c-mode-hook
+ '(lambda ()
+ (set (make-local-variable 'dabbrev-case-fold-search) nil)
+ (set (make-local-variable 'dabbrev-case-replace) nil)))
+(add-hook 'text-mode-hook
+ '(lambda ()
+ (set (make-local-variable 'dabbrev-case-fold-search) t)
+ (set (make-local-variable 'dabbrev-case-replace) t)))
+
+;; C++ and C mode...
+(defun my-c++-mode-hook ()
+ (setq tab-width 4)
+ (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
+ (define-key c++-mode-map "\C-ce" 'c-comment-edit)
+ (setq c++-auto-hungry-initial-state 'none)
+ (setq c++-delete-function 'backward-delete-char)
+ (setq c++-tab-always-indent t)
+ (setq c-indent-level 4)
+ (setq c-continued-statement-offset 4)
+ (setq c++-empty-arglist-indent 4))
+
+(defun my-c-mode-hook ()
+ (setq tab-width 4)
+ (define-key c-mode-map "\C-m" 'reindent-then-newline-and-indent)
+ (define-key c-mode-map "\C-ce" 'c-comment-edit)
+ (setq c-auto-hungry-initial-state 'none)
+ (setq c-delete-function 'backward-delete-char)
+ (setq c-tab-always-indent t)
+;; BSD-ish indentation style
+ (setq c-indent-level 4)
+ (setq c-continued-statement-offset 4)
+ (setq c-brace-offset -4)
+ (setq c-argdecl-indent 0)
+ (setq c-label-offset -4))
+
+;; Perl mode
+(defun my-perl-mode-hook ()
+ (setq tab-width 4)
+ (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
+ (setq perl-indent-level 4)
+ (setq perl-continued-statement-offset 4))
+
+;; Scheme mode...
+(defun my-scheme-mode-hook ()
+ (define-key scheme-mode-map "\C-m" 'reindent-then-newline-and-indent))
+
+;; Emacs-Lisp mode...
+(defun my-lisp-mode-hook ()
+ (define-key lisp-mode-map "\C-m" 'reindent-then-newline-and-indent)
+ (define-key lisp-mode-map "\C-i" 'lisp-indent-line)
+ (define-key lisp-mode-map "\C-j" 'eval-print-last-sexp))
+
+;; Add all of the hooks...
+(add-hook 'c++-mode-hook 'my-c++-mode-hook)
+(add-hook 'c-mode-hook 'my-c-mode-hook)
+(add-hook 'scheme-mode-hook 'my-scheme-mode-hook)
+(add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-hook)
+(add-hook 'lisp-mode-hook 'my-lisp-mode-hook)
+(add-hook 'perl-mode-hook 'my-perl-mode-hook)
+
+;; Complement to next-error
+(defun previous-error (n)
+ "Visit previous compilation error message and corresponding source code."
+ (interactive "p")
+ (next-error (- n)))
+
+;; Misc...
+(transient-mark-mode 1)
+(setq mark-even-if-inactive t)
+(setq visible-bell nil)
+(setq next-line-add-newlines nil)
+(setq compile-command "make")
+(setq suggest-key-bindings nil)
+(put 'eval-expression 'disabled nil)
+(put 'narrow-to-region 'disabled nil)
+(put 'set-goal-column 'disabled nil)
+(if (&gt;= emacs-major-version 21)
+ (setq show-trailing-whitespace t))
+
+;; Elisp archive searching
+(autoload 'format-lisp-code-directory "lispdir" nil t)
+(autoload 'lisp-dir-apropos "lispdir" nil t)
+(autoload 'lisp-dir-retrieve "lispdir" nil t)
+(autoload 'lisp-dir-verify "lispdir" nil t)
+
+;; Font lock mode
+(defun my-make-face (face color &amp;optional bold)
+ "Create a face from a color and optionally make it bold"
+ (make-face face)
+ (copy-face 'default face)
+ (set-face-foreground face color)
+ (if bold (make-face-bold face))
+ )
+
+(if (eq window-system 'x)
+ (progn
+ (my-make-face 'blue "blue")
+ (my-make-face 'red "red")
+ (my-make-face 'green "dark green")
+ (setq font-lock-comment-face 'blue)
+ (setq font-lock-string-face 'bold)
+ (setq font-lock-type-face 'bold)
+ (setq font-lock-keyword-face 'bold)
+ (setq font-lock-function-name-face 'red)
+ (setq font-lock-doc-string-face 'green)
+ (add-hook 'find-file-hooks 'font-lock-auto-mode-select)
+
+ (setq baud-rate 1000000)
+ (global-set-key "\C-cmm" 'menu-bar-mode)
+ (global-set-key "\C-cms" 'scroll-bar-mode)
+ (global-set-key [backspace] 'backward-delete-char)
+ ; (global-set-key [delete] 'delete-char)
+ (standard-display-european t)
+ (load-library "iso-transl")))
+
+;; X11 or PC using direct screen writes
+(if window-system
+ (progn
+ ;; (global-set-key [M-f1] 'hilit-repaint-command)
+ ;; (global-set-key [M-f2] [?\C-u M-f1])
+ (setq hilit-mode-enable-list
+ '(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode
+ scheme-mode)
+ hilit-auto-highlight nil
+ hilit-auto-rehighlight 'visible
+ hilit-inhibit-hooks nil
+ hilit-inhibit-rebinding t)
+ (require 'hilit19)
+ (require 'paren))
+ (setq baud-rate 2400) ; For slow serial connections
+ )
+
+;; TTY type terminal
+(if (and (not window-system)
+ (not (equal system-type 'ms-dos)))
+ (progn
+ (if first-time
+ (progn
+ (keyboard-translate ?\C-h ?\C-?)
+ (keyboard-translate ?\C-? ?\C-h)))))
+
+;; Under UNIX
+(if (not (equal system-type 'ms-dos))
+ (progn
+ (if first-time
+ (server-start))))
+
+;; Add any face changes here
+(add-hook 'term-setup-hook 'my-term-setup-hook)
+(defun my-term-setup-hook ()
+ (if (eq window-system 'pc)
+ (progn
+;; (set-face-background 'default "red")
+ )))
+
+;; Restore the "desktop" - do this as late as possible
+(if first-time
+ (progn
+ (desktop-load-default)
+ (desktop-read)))
+
+;; Indicate that this file has been read at least once
+(setq first-time nil)
+
+;; No need to debug anything now
+
+(setq debug-on-error nil)
+
+;; All done
+(message "All done, %s%s" (user-login-name) ".")
+ </programlisting>
+ </example>
+ </sect2>
+
+ <sect2>
+ <title>Extending the Range of Languages Emacs Understands</title>
+
+ <para>Now, this is all very well if you only want to program in
+ the languages already catered for in the
+ <filename>.emacs</filename> file (C, C++, Perl, Lisp and
+ Scheme), but what happens if a new language called
+ <quote>whizbang</quote> comes out, full of exciting
+ features?</para>
+
+ <para>The first thing to do is find out if whizbang comes with
+ any files that tell Emacs about the language. These usually
+ end in <filename>.el</filename>, short for <quote>Emacs
+ Lisp</quote>. For example, if whizbang is a FreeBSD port, we
+ can locate these files by doing</para>
+
+ <screen>&prompt.user; <userinput>find /usr/ports/lang/whizbang -name "*.el" -print</userinput></screen>
+
+ <para>and install them by copying them into the Emacs site Lisp
+ directory. On FreeBSD 2.1.0-RELEASE, this is
+ <filename>/usr/local/share/emacs/site-lisp</filename>.</para>
+
+ <para>So for example, if the output from the find command
+ was</para>
+
+ <screen>/usr/ports/lang/whizbang/work/misc/whizbang.el</screen>
+
+ <para>we would do</para>
+
+ <screen>&prompt.root; <userinput>cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp</userinput></screen>
+
+ <para>Next, we need to decide what extension whizbang source
+ files have. Let's say for the sake of argument that they all
+ end in <filename>.wiz</filename>. We need to add an entry to
+ our <filename>.emacs</filename> file to make sure Emacs will
+ be able to use the information in
+ <filename>whizbang.el</filename>.</para>
+
+ <para>Find the <symbol>auto-mode-alist entry</symbol> in
+ <filename>.emacs</filename> and add a line for whizbang, such
+ as:</para>
+
+ <programlisting><lineannotation>&hellip;</lineannotation>
+("\\.lsp$" . lisp-mode)
+("\\.wiz$" . whizbang-mode)
+("\\.scm$" . scheme-mode)
+<lineannotation>&hellip;</lineannotation></programlisting>
+
+ <para>This means that Emacs will automatically go into
+ <function>whizbang-mode</function> when you edit a file ending
+ in <filename>.wiz</filename>.</para>
+
+ <para>Just below this, you will find the
+ <symbol>font-lock-auto-mode-list</symbol> entry. Add
+ <function>whizbang-mode</function> to it like so:</para>
+
+ <programlisting>;; Auto font lock mode
+(defvar font-lock-auto-mode-list
+ (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'whizbang-mode 'lisp-mode 'perl-mode 'scheme-mode)
+ "List of modes to always start in font-lock-mode")</programlisting>
+
+ <para>This means that Emacs will always enable
+ <function>font-lock-mode</function> (ie syntax highlighting)
+ when editing a <filename>.wiz</filename> file.</para>
+
+ <para>And that is all that is needed. If there is anything else
+ you want done automatically when you open up a
+ <filename>.wiz</filename> file, you can add a
+ <function>whizbang-mode hook</function> (see
+ <function>my-scheme-mode-hook</function> for a simple example
+ that adds <function>auto-indent</function>).</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="tools-reading">
+ <title>Further Reading</title>
+
+ <para>For information about setting up a development environment
+ for contributing fixes to FreeBSD itself, please see
+ &man.development.7;.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Brian Harvey and Matthew Wright
+ <emphasis>Simply Scheme</emphasis>
+ MIT 1994.<!-- <br> -->
+ ISBN 0-262-08226-8</para>
+ </listitem>
+
+ <listitem>
+ <para>Randall Schwartz
+ <emphasis>Learning Perl</emphasis>
+ O'Reilly 1993<!-- <br> -->
+ ISBN 1-56592-042-2</para>
+ </listitem>
+
+ <listitem>
+ <para>Patrick Henry Winston and Berthold Klaus Paul Horn
+ <emphasis>Lisp (3rd Edition)</emphasis>
+ Addison-Wesley 1989<!-- <br> -->
+ ISBN 0-201-08319-1</para>
+ </listitem>
+
+ <listitem>
+ <para>Brian W. Kernighan and Rob Pike
+ <emphasis>The Unix Programming Environment</emphasis>
+ Prentice-Hall 1984<!-- <br> -->
+ ISBN 0-13-937681-X</para>
+ </listitem>
+
+ <listitem>
+ <para>Brian W. Kernighan and Dennis M. Ritchie
+ <emphasis>The C Programming Language (2nd Edition)</emphasis>
+ Prentice-Hall 1988<!-- <br> -->
+ ISBN 0-13-110362-8</para>
+ </listitem>
+
+ <listitem>
+ <para>Bjarne Stroustrup
+ <emphasis>The C++ Programming Language</emphasis>
+ Addison-Wesley 1991<!-- <br> -->
+ ISBN 0-201-53992-6</para>
+ </listitem>
+
+ <listitem>
+ <para>W. Richard Stevens
+ <emphasis>Advanced Programming in the Unix Environment</emphasis>
+ Addison-Wesley 1992<!-- <br> -->
+ ISBN 0-201-56317-7</para>
+ </listitem>
+
+ <listitem>
+ <para>W. Richard Stevens
+ <emphasis>Unix Network Programming</emphasis>
+ Prentice-Hall 1990<!-- <br> -->
+ ISBN 0-13-949876-1</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+</chapter>
diff --git a/zh_TW.UTF-8/books/developers-handbook/x86/chapter.xml b/zh_TW.UTF-8/books/developers-handbook/x86/chapter.xml
new file mode 100644
index 0000000000..b9e4fc44a3
--- /dev/null
+++ b/zh_TW.UTF-8/books/developers-handbook/x86/chapter.xml
@@ -0,0 +1,6486 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ This file is automatically generated. Please do not make commits
+ to this file. Updates should be sent to the author :
+
+ G. Adam Stanislav (adam@redprince.net)
+
+ This chapter is an exception to our general rule, and the author
+ retains the copyright. Among other things, this means that this
+ chapter should not be included in any printed version of the
+ Developer's Handbook without Adam's explicit permission.
+
+ Eventually we will have to replace this chapter or convince the
+ author to assign us the copyright. For now, it is valuable
+ content so it should stay.
+
+ $FreeBSD$
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="x86">
+
+<title>x86 Assembly Language Programming</title>
+<para>
+<emphasis>
+This chapter was written by &a.stanislav;.
+</emphasis></para>
+
+
+
+<sect1 xml:id="x86-intro">
+<title>Synopsis</title>
+
+<para>
+Assembly language programming under &unix; is highly undocumented. It
+is generally assumed that no one would ever want to use it because
+various &unix; systems run on different microprocessors, so everything
+should be written in C for portability.
+</para>
+
+<para>
+In reality, C portability is quite a myth. Even C programs need
+to be modified when ported from one &unix; to another, regardless of
+what processor each runs on. Typically, such a program is full
+of conditional statements depending on the system it is
+compiled for.
+</para>
+
+<para>
+Even if we believe that all of &unix; software should be written in C,
+or some other high-level language, we still need assembly language
+programmers: Who else would write the section of C library
+that accesses the kernel?
+</para>
+
+<para>
+In this chapter I will attempt to show you
+how you can use assembly language writing
+&unix; programs, specifically under FreeBSD.
+</para>
+
+<para>
+This chapter does not explain the basics of assembly language.
+There are enough resources about that (for a complete
+online course in assembly language, see Randall Hyde's
+<link xlink:href="http://webster.cs.ucr.edu/">Art
+of Assembly Language</link>; or if you prefer
+a printed book, take a look at Jeff Duntemann's
+<link xlink:href="http://www.int80h.org/cgi-bin/isbn?isbn=0471375233">Assembly
+Language Step-by-Step</link>). However,
+once the chapter is finished, any assembly language programmer
+will be able to write programs for FreeBSD
+quickly and efficiently.
+</para>
+
+<para>
+Copyright &copy; 2000-2001 G. Adam Stanislav. All rights reserved.
+</para>
+
+</sect1>
+
+<sect1 xml:id="x86-the-tools">
+<title>The Tools</title>
+
+<sect2 xml:id="x86-the-assembler">
+<title>The Assembler</title>
+
+<para>
+The most important tool for assembly language programming is the
+assembler, the software that converts assembly language code
+into machine language.
+</para>
+
+<para>
+Two very different assemblers are available for FreeBSD. One is
+<citerefentry><refentrytitle>as</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+which uses the traditional &unix; assembly language syntax. It
+comes with the system.
+</para>
+
+<para>
+The other is <application>/usr/ports/devel/nasm</application>.
+It uses the Intel syntax. Its main advantage is that it
+can assemble code for many operating systems. It needs
+to be installed separately, but is completely free.
+</para>
+
+<para>
+This chapter uses <application>nasm</application>
+syntax because most assembly language programmers
+coming to FreeBSD from other operating systems
+will find it easier to understand. And, because,
+quite frankly, that is what I am used to.
+</para>
+
+</sect2>
+
+<sect2 xml:id="x86-the-linker">
+<title>The Linker</title>
+
+<para>
+The output of the assembler, like that of any
+compiler, needs to be linked to form an executable file.
+</para>
+
+<para>
+The standard
+<citerefentry><refentrytitle>ld</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+linker comes with FreeBSD. It works with the
+code assembled with either assembler.
+</para>
+
+</sect2>
+</sect1>
+
+<sect1 xml:id="x86-system-calls">
+<title>System Calls</title>
+
+<sect2 xml:id="x86-default-calling-convention">
+<title>Default Calling Convention</title>
+
+<para>
+By default, the FreeBSD kernel uses the C calling
+convention. Further, although the kernel is accessed
+using <function role="opcode">int 80h</function>,
+it is assumed the program will call a function that
+issues <function role="opcode">int 80h</function>, rather than
+issuing <function role="opcode">int 80h</function> directly.
+</para>
+
+<para>
+This convention is very convenient, and quite superior to the
+&microsoft; convention used by <acronym>&ms-dos;</acronym>.
+Why? Because the &unix; convention allows any program written in
+any language to access the kernel.
+</para>
+
+<para>
+An assembly language program can do that as well.
+For example, we could open a file:
+</para>
+
+<programlisting>
+kernel:
+ int 80h ; Call kernel
+ ret
+
+open:
+ push dword mode
+ push dword flags
+ push dword path
+ mov eax, 5
+ call kernel
+ add esp, byte 12
+ ret
+</programlisting>
+
+<para>
+This is a very clean and portable way of coding. If you need to
+port the code to a &unix; system which uses a different interrupt,
+or a different way of passing parameters, all you need to change
+is the kernel procedure.
+</para>
+
+<para>
+But assembly language programmers like to shave off cycles. The above example
+requires a <function role="opcode">call/ret</function> combination.
+We can eliminate it by
+<function role="opcode">push</function>ing an extra dword:
+</para>
+
+<programlisting>
+open:
+ push dword mode
+ push dword flags
+ push dword path
+ mov eax, 5
+ push eax ; Or any other dword
+ int 80h
+ add esp, byte 16
+</programlisting>
+
+<para>
+The <constant>5</constant> that we have placed in
+<varname role="register">EAX</varname> identifies
+the kernel function, in this case <function role="syscall">open</function>.
+</para>
+
+</sect2>
+<sect2 xml:id="x86-alternate-calling-convention">
+<title>Alternate Calling Convention</title>
+<para>
+FreeBSD is an extremely flexible system. It offers other ways of
+calling the kernel. For it to work, however, the system must
+have Linux emulation installed.
+</para>
+
+<para>
+Linux is a &unix; like system. However, its kernel uses the same
+system-call convention of passing parameters in registers
+<acronym>&ms-dos;</acronym> does. As with the &unix; convention,
+the function number is placed in <varname role="register">EAX</varname>.
+The parameters, however, are not passed on the stack but in
+<varname role="register">EBX, ECX, EDX, ESI, EDI, EBP</varname>:
+</para>
+
+<programlisting>
+open:
+ mov eax, 5
+ mov ebx, path
+ mov ecx, flags
+ mov edx, mode
+ int 80h
+</programlisting>
+
+<para>
+This convention has a great disadvantage over
+the &unix; way, at least as far as assembly language programming
+is concerned: Every time you make a kernel call
+you must <function role="opcode">push</function> the registers, then
+<function role="opcode">pop</function> them later. This makes your code
+bulkier and slower. Nevertheless, FreeBSD gives
+you a choice.
+</para>
+
+<para>
+If you do choose the Linux convention, you must let
+the system know about it. After your program is assembled and
+linked, you need to brand the executable:
+</para>
+
+<screen>&prompt.user; <userinput>brandelf -f Linux filename</userinput></screen>
+
+</sect2>
+
+<sect2 xml:id="x86-use-geneva">
+<title>Which Convention Should You Use?</title>
+
+<para>
+If you are coding specifically for FreeBSD, you should always
+use the &unix; convention: It is faster, you can store global
+variables in registers, you do not have to brand
+the executable, and you do not impose the installation of
+the Linux emulation package on the target system.
+</para>
+
+<para>
+If you want to create portable code that can also run
+on Linux, you will probably still want to give the FreeBSD
+users as efficient a code as possible. I will show you
+how you can accomplish that after I have explained the basics.
+</para>
+
+</sect2>
+
+<sect2 xml:id="x86-call-numbers">
+<title>Call Numbers</title>
+
+<para>
+To tell the kernel which system service you are calling,
+place its number in <varname role="register">EAX</varname>. Of course, you need
+to know what the number is.
+</para>
+
+<sect3 xml:id="x86-the-syscalls-file">
+<title>The <filename>syscalls</filename> File</title>
+
+<para>
+The numbers are listed in <filename>syscalls</filename>.
+<command>locate syscalls</command> finds this file
+in several different formats, all produced automatically
+from <filename>syscalls.master</filename>.
+</para>
+
+<para>
+You can find the master file for the default &unix; calling
+convention in
+<filename>/usr/src/sys/kern/syscalls.master</filename>.
+If you need to use the other convention implemented
+in the Linux emulation mode, read
+<filename>/usr/src/sys/i386/linux/syscalls.master</filename>.
+</para>
+
+<note>
+<para>
+Not only do FreeBSD and Linux use different calling
+conventions, they sometimes use different numbers for
+the same functions.
+</para>
+</note>
+
+<para>
+<filename>syscalls.master</filename> describes how
+the call is to be made:
+</para>
+
+<programlisting>
+0 STD NOHIDE { int nosys(void); } syscall nosys_args int
+1 STD NOHIDE { void exit(int rval); } exit rexit_args void
+2 STD POSIX { int fork(void); }
+3 STD POSIX { ssize_t read(int fd, void *buf, size_t nbyte); }
+4 STD POSIX { ssize_t write(int fd, const void *buf, size_t nbyte); }
+5 STD POSIX { int open(char *path, int flags, int mode); }
+6 STD POSIX { int close(int fd); }
+etc...
+</programlisting>
+<para>
+It is the leftmost column that tells us the number to place in
+<varname role="register">EAX</varname>.
+</para>
+
+<para>
+The rightmost column tells us what parameters to
+<function role="opcode">push</function>. They are <function role="opcode">push</function>ed
+<emphasis>from right to left</emphasis>.
+</para>
+
+<informalexample>
+<para>
+For example, to <function>open</function> a file, we need
+to <function role="opcode">push</function> the <varname>mode</varname> first,
+then <varname>flags</varname>, then the address at which
+the <varname>path</varname> is stored.
+</para>
+</informalexample>
+
+</sect3>
+
+</sect2>
+
+</sect1>
+
+<sect1 xml:id="x86-return-values">
+<title>Return Values</title>
+
+<para>
+A system call would not be useful most of the time
+if it did not return some kind of a value: The file
+descriptor of an open file, the number of bytes read
+to a buffer, the system time, etc.
+</para>
+
+<para>
+Additionally, the system needs to inform us if an error
+occurs: A file does not exist, system resources are exhausted,
+we passed an invalid parameter, etc.
+</para>
+
+<sect2 xml:id="x86-man-pages">
+<title>Man Pages</title>
+
+<para>
+The traditional place to look for information about various
+system calls under &unix; systems are the manual pages.
+FreeBSD describes its system calls in section 2, sometimes
+in section 3.
+</para>
+
+<para>
+For example, <citerefentry><refentrytitle>open</refentrytitle><manvolnum>2</manvolnum></citerefentry> says:
+</para>
+
+<blockquote>
+<para>
+If successful, <function>open()</function> returns a non-negative
+integer, termed a file descriptor. It returns <varname>-1</varname> on failure,
+and sets <varname>errno</varname> to indicate the error.
+</para>
+
+</blockquote>
+<para>
+The assembly language programmer new to &unix; and FreeBSD will
+immediately ask the puzzling question: Where is
+<varname>errno</varname> and how do I get to it?
+</para>
+
+<note>
+<para>
+The information presented in the manual pages applies
+to C programs. The assembly language programmer needs additional
+information.
+</para>
+</note>
+
+</sect2>
+
+<sect2 xml:id="x86-where-return-values">
+<title>Where Are the Return Values?</title>
+
+<para>
+Unfortunately, it depends... For most system calls it is
+in <varname role="register">EAX</varname>, but not for all.
+A good rule of thumb,
+when working with a system call for
+the first time, is to look for
+the return value in <varname role="register">EAX</varname>.
+If it is not there, you
+need further research.
+</para>
+
+<note>
+<para>
+I am aware of one system call that returns the value in
+<varname role="register">EDX</varname>: <function role="syscall">SYS_fork</function>. All others
+I have worked with use <varname role="register">EAX</varname>.
+But I have not worked with them all yet.
+</para>
+</note>
+
+<tip>
+<para>
+If you cannot find the answer here or anywhere else,
+study <application>libc</application> source code and see how it
+interfaces with the kernel.
+</para>
+</tip>
+
+</sect2>
+<sect2 xml:id="x86-where-errno">
+<title>Where Is <varname>errno</varname>?</title>
+
+<para>
+Actually, nowhere...
+</para>
+
+<para>
+<varname>errno</varname> is part of the C language, not the
+&unix; kernel. When accessing kernel services directly, the
+error code is returned in <varname role="register">EAX</varname>,
+the same register the proper
+return value generally ends up in.
+</para>
+
+<para>
+This makes perfect sense. If there is no error, there is
+no error code. If there is an error, there is no return
+value. One register can contain either.
+</para>
+
+</sect2>
+
+<sect2 xml:id="x86-how-to-know-error">
+<title>Determining an Error Occurred</title>
+
+<para>
+When using the standard FreeBSD calling convention,
+the <varname role="register">carry flag</varname> is cleared upon success,
+set upon failure.
+</para>
+
+<para>
+When using the Linux emulation mode, the signed
+value in <varname role="register">EAX</varname> is non-negative upon success,
+and contains the return value. In case of an error, the value
+is negative, i.e., <varname>-errno</varname>.
+</para>
+
+</sect2>
+
+</sect1>
+
+<sect1 xml:id="x86-portable-code">
+<title>Creating Portable Code</title>
+
+<para>
+Portability is generally not one of the strengths of assembly language.
+Yet, writing assembly language programs for different platforms is
+possible, especially with <application>nasm</application>. I have written
+assembly language libraries that can be assembled for such different
+operating systems as &windows; and FreeBSD.
+</para>
+
+<para>
+It is all the more possible when you want your code to run
+on two platforms which, while different, are based on
+similar architectures.
+</para>
+
+<para>
+For example, FreeBSD is &unix;, Linux is &unix; like. I only
+mentioned three differences between them (from an assembly language
+programmer's perspective): The calling convention, the
+function numbers, and the way of returning values.
+</para>
+
+<sect2 xml:id="x86-deal-with-function-numbers"><title>Dealing with Function Numbers</title>
+
+<para>
+In many cases the function numbers are the same. However,
+even when they are not, the problem is easy to deal with:
+Instead of using numbers in your code, use constants which
+you have declared differently depending on the target
+architecture:
+</para>
+
+<programlisting>
+%ifdef LINUX
+%define SYS_execve 11
+%else
+%define SYS_execve 59
+%endif
+</programlisting>
+</sect2>
+<sect2 xml:id="x86-deal-with-geneva"><title>Dealing with Conventions</title>
+<para>
+Both, the calling convention, and the return value (the
+<varname>errno</varname> problem) can be resolved with macros:
+</para>
+
+<programlisting>
+%ifdef LINUX
+
+%macro system 0
+ call kernel
+%endmacro
+
+align 4
+kernel:
+ push ebx
+ push ecx
+ push edx
+ push esi
+ push edi
+ push ebp
+
+ mov ebx, [esp+32]
+ mov ecx, [esp+36]
+ mov edx, [esp+40]
+ mov esi, [esp+44]
+ mov ebp, [esp+48]
+ int 80h
+
+ pop ebp
+ pop edi
+ pop esi
+ pop edx
+ pop ecx
+ pop ebx
+
+ or eax, eax
+ js .errno
+ clc
+ ret
+
+.errno:
+ neg eax
+ stc
+ ret
+
+%else
+
+%macro system 0
+ int 80h
+%endmacro
+
+%endif
+</programlisting>
+
+</sect2>
+
+<sect2 xml:id="x86-deal-with-other-portability"><title>Dealing with Other Portability Issues</title>
+
+<para>
+The above solutions can handle most cases of writing code
+portable between FreeBSD and Linux. Nevertheless, with some
+kernel services the differences are deeper.
+</para>
+
+<para>
+In that case, you need to write two different handlers
+for those particular system calls, and use conditional
+assembly. Luckily, most of your code does something other
+than calling the kernel, so usually you will only need
+a few such conditional sections in your code.
+</para>
+
+</sect2>
+
+<sect2 xml:id="x86-portable-library"><title>Using a Library</title>
+
+<para>
+You can avoid portability issues in your main code altogether
+by writing a library of system calls. Create a separate library
+for FreeBSD, a different one for Linux, and yet other libraries
+for more operating systems.
+</para>
+
+<para>
+In your library, write a separate function (or procedure, if
+you prefer the traditional assembly language terminology) for each system
+call. Use the C calling convention of passing parameters.
+But still use <varname role="register">EAX</varname> to pass the call number in.
+In that case, your FreeBSD library can be very simple, as
+many seemingly different functions can be just labels to
+the same code:
+</para>
+
+<programlisting>
+sys.open:
+sys.close:
+[etc...]
+ int 80h
+ ret
+</programlisting>
+
+<para>
+Your Linux library will require more different functions.
+But even here you can group system calls using the same
+number of parameters:
+</para>
+
+<programlisting>
+sys.exit:
+sys.close:
+[etc... one-parameter functions]
+ push ebx
+ mov ebx, [esp+12]
+ int 80h
+ pop ebx
+ jmp sys.return
+
+...
+
+sys.return:
+ or eax, eax
+ js sys.err
+ clc
+ ret
+
+sys.err:
+ neg eax
+ stc
+ ret
+</programlisting>
+
+<para>
+The library approach may seem inconvenient at first because
+it requires you to produce a separate file your code depends
+on. But it has many advantages: For one, you only need to
+write it once and can use it for all your programs. You can
+even let other assembly language programmers use it, or perhaps use
+one written by someone else. But perhaps the greatest
+advantage of the library is that your code can be ported
+to other systems, even by other programmers, by simply
+writing a new library without any changes to your code.
+</para>
+
+<para>
+If you do not like the idea of having a library, you can
+at least place all your system calls in a separate assembly language file
+and link it with your main program. Here, again, all porters
+have to do is create a new object file to link with your
+main program.
+</para>
+
+</sect2>
+
+<sect2 xml:id="x86-portable-include">
+<title>Using an Include File</title>
+
+<para>
+If you are releasing your software as (or with)
+source code, you can use macros and place them
+in a separate file, which you include in your
+code.
+</para>
+
+<para>
+Porters of your software will simply write a new
+include file. No library or external object file
+is necessary, yet your code is portable without any
+need to edit the code.
+</para>
+
+<note>
+<para>
+This is the approach we will use throughout this chapter.
+We will name our include file <filename>system.inc</filename>, and
+add to it whenever we deal with a new system call.
+</para>
+</note>
+
+<para>
+We can start our <filename>system.inc</filename> by declaring the
+standard file descriptors:
+</para>
+
+<programlisting>
+%define stdin 0
+%define stdout 1
+%define stderr 2
+</programlisting>
+
+<para>
+Next, we create a symbolic name for each system call:
+</para>
+
+<programlisting>
+%define SYS_nosys 0
+%define SYS_exit 1
+%define SYS_fork 2
+%define SYS_read 3
+%define SYS_write 4
+; [etc...]
+</programlisting>
+
+<para>
+We add a short, non-global procedure with a long name,
+so we do not accidentally reuse the name in our code:
+</para>
+
+<programlisting>
+section .text
+align 4
+access.the.bsd.kernel:
+ int 80h
+ ret
+</programlisting>
+
+<para>
+We create a macro which takes one argument, the syscall number:
+</para>
+
+<programlisting>
+%macro system 1
+ mov eax, %1
+ call access.the.bsd.kernel
+%endmacro
+</programlisting>
+
+<para>
+Finally, we create macros for each syscall. These macros take
+no arguments.
+</para>
+
+<programlisting>
+%macro sys.exit 0
+ system SYS_exit
+%endmacro
+
+%macro sys.fork 0
+ system SYS_fork
+%endmacro
+
+%macro sys.read 0
+ system SYS_read
+%endmacro
+
+%macro sys.write 0
+ system SYS_write
+%endmacro
+
+; [etc...]
+</programlisting>
+
+<para>
+Go ahead, enter it into your editor and save it as
+<filename>system.inc</filename>. We will add more to it as we
+discuss more syscalls.
+</para>
+
+</sect2>
+
+</sect1>
+
+<sect1 xml:id="x86-first-program">
+<title>Our First Program</title>
+
+<para>
+We are now ready for our first program, the mandatory
+<application>Hello, World!</application>
+</para>
+
+<programlisting>
+ 1: %include 'system.inc'
+ 2:
+ 3: section .data
+ 4: hello db 'Hello, World!', 0Ah
+ 5: hbytes equ $-hello
+ 6:
+ 7: section .text
+ 8: global _start
+ 9: _start:
+10: push dword hbytes
+11: push dword hello
+12: push dword stdout
+13: sys.write
+14:
+15: push dword 0
+16: sys.exit
+</programlisting>
+
+<para>
+Here is what it does: Line 1 includes the defines, the macros,
+and the code from <filename>system.inc</filename>.
+</para>
+
+<para>
+Lines 3-5 are the data: Line 3 starts the data section/segment.
+Line 4 contains the string "Hello, World!" followed by a new
+line (<constant>0Ah</constant>). Line 5 creates a constant that contains
+the length of the string from line 4 in bytes.
+</para>
+
+<para>
+Lines 7-16 contain the code. Note that FreeBSD uses the <emphasis>elf</emphasis>
+file format for its executables, which requires every
+program to start at the point labeled <varname>_start</varname> (or, more
+precisely, the linker expects that). This label has to be
+global.
+</para>
+
+<para>
+Lines 10-13 ask the system to write <varname>hbytes</varname> bytes
+of the <varname>hello</varname> string to <varname>stdout</varname>.
+</para>
+
+<para>
+Lines 15-16 ask the system to end the program with the return
+value of <constant>0</constant>. The <function role="syscall">SYS_exit</function> syscall never
+returns, so the code ends there.
+</para>
+
+<note>
+<para>
+If you have come to &unix; from <acronym>&ms-dos;</acronym>
+assembly language background, you may be used to writing directly
+to the video hardware. You will never have to worry about
+this in FreeBSD, or any other flavor of &unix;. As far as
+you are concerned, you are writing to a file known as
+<filename>stdout</filename>. This can be the video screen, or
+a <application>telnet</application> terminal, or an actual file,
+or even the input of another program. Which one it is,
+is for the system to figure out.
+</para>
+</note>
+
+<sect2 xml:id="x86-assemble-1"><title>Assembling the Code</title>
+
+<para>
+Type the code (except the line numbers) in an editor, and save
+it in a file named <filename>hello.asm</filename>. You need
+<application>nasm</application> to assemble it.
+</para>
+
+<sect3 xml:id="x86-get-nasm"><title>Installing <application>nasm</application></title>
+
+<para>
+If you do not have <application>nasm</application>, type:
+</para>
+
+<screen>&prompt.user; <userinput>su</userinput>
+Password:<userinput>your root password</userinput>
+&prompt.root; <userinput>cd /usr/ports/devel/nasm</userinput>
+&prompt.root; <userinput>make install</userinput>
+&prompt.root; <userinput>exit</userinput>
+&prompt.user;</screen>
+
+<para>
+You may type <userinput>make install clean</userinput> instead of just
+<userinput>make install</userinput> if you do not want to keep
+<application>nasm</application> source code.
+</para>
+
+<para>
+Either way, FreeBSD will automatically download
+<application>nasm</application> from the Internet,
+compile it, and install it on your system.
+</para>
+
+<note>
+<para>
+If your system is not FreeBSD, you need to get
+<application>nasm</application> from its
+<link xlink:href="http://www.web-sites.co.uk/nasm/">home
+page</link>. You can still use it to assemble FreeBSD code.
+</para>
+</note>
+
+<para>
+Now you can assemble, link, and run the code:
+</para>
+
+<screen>&prompt.user; <userinput>nasm -f elf hello.asm</userinput>
+&prompt.user; <userinput>ld -s -o hello hello.o</userinput>
+&prompt.user; <userinput>./hello</userinput>
+Hello, World!
+&prompt.user;</screen>
+
+</sect3>
+
+</sect2>
+
+</sect1>
+
+<sect1 xml:id="x86-unix-filters">
+<title>Writing &unix; Filters</title>
+
+<para>
+A common type of &unix; application is a filter&mdash;a program
+that reads data from the <filename>stdin</filename>, processes it
+somehow, then writes the result to <filename>stdout</filename>.
+</para>
+
+<para>
+In this chapter, we shall develop a simple filter, and
+learn how to read from <filename>stdin</filename> and write to
+<filename>stdout</filename>. This filter will convert each byte
+of its input into a hexadecimal number followed by a
+blank space.
+</para>
+
+<programlisting>
+%include 'system.inc'
+
+section .data
+hex db '0123456789ABCDEF'
+buffer db 0, 0, ' '
+
+section .text
+global _start
+_start:
+ ; read a byte from stdin
+ push dword 1
+ push dword buffer
+ push dword stdin
+ sys.read
+ add esp, byte 12
+ or eax, eax
+ je .done
+
+ ; convert it to hex
+ movzx eax, byte [buffer]
+ mov edx, eax
+ shr dl, 4
+ mov dl, [hex+edx]
+ mov [buffer], dl
+ and al, 0Fh
+ mov al, [hex+eax]
+ mov [buffer+1], al
+
+ ; print it
+ push dword 3
+ push dword buffer
+ push dword stdout
+ sys.write
+ add esp, byte 12
+ jmp short _start
+
+.done:
+ push dword 0
+ sys.exit
+</programlisting>
+<para>
+In the data section we create an array called <varname>hex</varname>.
+It contains the 16 hexadecimal digits in ascending order.
+The array is followed by a buffer which we will use for
+both input and output. The first two bytes of the buffer
+are initially set to <constant>0</constant>. This is where we will write
+the two hexadecimal digits (the first byte also is
+where we will read the input). The third byte is a
+space.
+</para>
+
+<para>
+The code section consists of four parts: Reading the byte,
+converting it to a hexadecimal number, writing the result,
+and eventually exiting the program.
+</para>
+
+<para>
+To read the byte, we ask the system to read one byte
+from <filename>stdin</filename>, and store it in the first byte
+of the <varname>buffer</varname>. The system returns the number
+of bytes read in <varname role="register">EAX</varname>. This will be <constant>1</constant>
+while data is coming, or <constant>0</constant>, when no more input
+data is available. Therefore, we check the value of
+<varname role="register">EAX</varname>. If it is <constant>0</constant>,
+we jump to <varname>.done</varname>, otherwise we continue.
+</para>
+
+<note>
+<para>
+For simplicity sake, we are ignoring the possibility
+of an error condition at this time.
+</para>
+</note>
+
+<para>
+The hexadecimal conversion reads the byte from the
+<varname>buffer</varname> into <varname role="register">EAX</varname>, or actually just
+<varname role="register">AL</varname>, while clearing the remaining bits of
+<varname role="register">EAX</varname> to zeros. We also copy the byte to
+<varname role="register">EDX</varname> because we need to convert the upper
+four bits (nibble) separately from the lower
+four bits. We store the result in the first two
+bytes of the buffer.
+</para>
+
+<para>
+Next, we ask the system to write the three bytes
+of the buffer, i.e., the two hexadecimal digits and
+the blank space, to <filename>stdout</filename>. We then
+jump back to the beginning of the program and
+process the next byte.
+</para>
+
+<para>
+Once there is no more input left, we ask the system
+to exit our program, returning a zero, which is
+the traditional value meaning the program was
+successful.
+</para>
+
+<para>
+Go ahead, and save the code in a file named <filename>hex.asm</filename>,
+then type the following (the <userinput>^D</userinput> means press the
+control key and type <userinput>D</userinput> while holding the
+control key down):
+</para>
+
+<screen>&prompt.user; <userinput>nasm -f elf hex.asm</userinput>
+&prompt.user; <userinput>ld -s -o hex hex.o</userinput>
+&prompt.user; <userinput>./hex</userinput>
+<userinput>Hello, World!</userinput>
+48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A <userinput>Here I come!</userinput>
+48 65 72 65 20 49 20 63 6F 6D 65 21 0A <userinput>^D</userinput> &prompt.user;</screen>
+
+<note>
+<para>
+If you are migrating to &unix; from <acronym>&ms-dos;</acronym>,
+you may be wondering why each line ends with <constant>0A</constant>
+instead of <constant>0D 0A</constant>.
+This is because &unix; does not use the cr/lf convention, but
+a "new line" convention, which is <constant>0A</constant> in hexadecimal.
+</para>
+</note>
+
+<para>
+Can we improve this? Well, for one, it is a bit confusing because
+once we have converted a line of text, our input no longer
+starts at the beginning of the line. We can modify it to print
+a new line instead of a space after each <constant>0A</constant>:
+</para>
+
+<programlisting>
+%include 'system.inc'
+
+section .data
+hex db '0123456789ABCDEF'
+buffer db 0, 0, ' '
+
+section .text
+global _start
+_start:
+ mov cl, ' '
+
+.loop:
+ ; read a byte from stdin
+ push dword 1
+ push dword buffer
+ push dword stdin
+ sys.read
+ add esp, byte 12
+ or eax, eax
+ je .done
+
+ ; convert it to hex
+ movzx eax, byte [buffer]
+ mov [buffer+2], cl
+ cmp al, 0Ah
+ jne .hex
+ mov [buffer+2], al
+
+.hex:
+ mov edx, eax
+ shr dl, 4
+ mov dl, [hex+edx]
+ mov [buffer], dl
+ and al, 0Fh
+ mov al, [hex+eax]
+ mov [buffer+1], al
+
+ ; print it
+ push dword 3
+ push dword buffer
+ push dword stdout
+ sys.write
+ add esp, byte 12
+ jmp short .loop
+
+.done:
+ push dword 0
+ sys.exit
+</programlisting>
+<para>
+We have stored the space in the <varname role="register">CL</varname> register. We can
+do this safely because, unlike &microsoft.windows;, &unix; system
+calls do not modify the value of any register they do not use
+to return a value in.
+</para>
+
+<para>
+That means we only need to set <varname role="register">CL</varname> once. We have, therefore,
+added a new label <varname>.loop</varname> and jump to it for the next byte
+instead of jumping at <varname>_start</varname>. We have also added the
+<varname>.hex</varname> label so we can either have a blank space or a
+new line as the third byte of the <varname>buffer</varname>.
+</para>
+
+<para>
+Once you have changed <filename>hex.asm</filename> to reflect
+these changes, type:
+</para>
+
+<screen>&prompt.user; <userinput>nasm -f elf hex.asm</userinput>
+&prompt.user; <userinput>ld -s -o hex hex.o</userinput>
+&prompt.user; <userinput>./hex</userinput>
+<userinput>Hello, World!</userinput>
+48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A
+<userinput>Here I come!</userinput>
+48 65 72 65 20 49 20 63 6F 6D 65 21 0A
+<userinput>^D</userinput> &prompt.user;</screen>
+
+<para>
+That looks better. But this code is quite inefficient! We
+are making a system call for every single byte twice (once
+to read it, another time to write the output).
+</para>
+
+</sect1>
+
+<sect1 xml:id="x86-buffered-io">
+<title>Buffered Input and Output</title>
+
+<para>
+We can improve the efficiency of our code by buffering our
+input and output. We create an input buffer and read a whole
+sequence of bytes at one time. Then we fetch them one by one
+from the buffer.
+</para>
+
+<para>
+We also create an output buffer. We store our output in it until
+it is full. At that time we ask the kernel to write the contents
+of the buffer to <filename>stdout</filename>.
+</para>
+
+<para>
+The program ends when there is no more input. But we still need
+to ask the kernel to write the contents of our output buffer
+to <filename>stdout</filename> one last time, otherwise some of our output
+would make it to the output buffer, but never be sent out.
+Do not forget that, or you will be wondering why some of your
+output is missing.
+</para>
+
+<programlisting>
+%include 'system.inc'
+
+%define BUFSIZE 2048
+
+section .data
+hex db '0123456789ABCDEF'
+
+section .bss
+ibuffer resb BUFSIZE
+obuffer resb BUFSIZE
+
+section .text
+global _start
+_start:
+ sub eax, eax
+ sub ebx, ebx
+ sub ecx, ecx
+ mov edi, obuffer
+
+.loop:
+ ; read a byte from stdin
+ call getchar
+
+ ; convert it to hex
+ mov dl, al
+ shr al, 4
+ mov al, [hex+eax]
+ call putchar
+
+ mov al, dl
+ and al, 0Fh
+ mov al, [hex+eax]
+ call putchar
+
+ mov al, ' '
+ cmp dl, 0Ah
+ jne .put
+ mov al, dl
+
+.put:
+ call putchar
+ jmp short .loop
+
+align 4
+getchar:
+ or ebx, ebx
+ jne .fetch
+
+ call read
+
+.fetch:
+ lodsb
+ dec ebx
+ ret
+
+read:
+ push dword BUFSIZE
+ mov esi, ibuffer
+ push esi
+ push dword stdin
+ sys.read
+ add esp, byte 12
+ mov ebx, eax
+ or eax, eax
+ je .done
+ sub eax, eax
+ ret
+
+align 4
+.done:
+ call write ; flush output buffer
+ push dword 0
+ sys.exit
+
+align 4
+putchar:
+ stosb
+ inc ecx
+ cmp ecx, BUFSIZE
+ je write
+ ret
+
+align 4
+write:
+ sub edi, ecx ; start of buffer
+ push ecx
+ push edi
+ push dword stdout
+ sys.write
+ add esp, byte 12
+ sub eax, eax
+ sub ecx, ecx ; buffer is empty now
+ ret
+</programlisting>
+<para>
+We now have a third section in the source code, named
+<varname>.bss</varname>. This section is not included in our
+executable file, and, therefore, cannot be initialized. We use
+<function role="opcode">resb</function> instead of <function role="opcode">db</function>.
+It simply reserves the requested size of uninitialized memory
+for our use.
+</para>
+
+<para>
+We take advantage of the fact that the system does not modify the
+registers: We use registers for what, otherwise, would have to be
+global variables stored in the <varname>.data</varname> section. This is
+also why the &unix; convention of passing parameters to system calls
+on the stack is superior to the Microsoft convention of passing
+them in the registers: We can keep the registers for our own use.
+</para>
+
+<para>
+We use <varname role="register">EDI</varname> and <varname role="register">ESI</varname> as pointers to the next byte
+to be read from or written to. We use <varname role="register">EBX</varname> and
+<varname role="register">ECX</varname> to keep count of the number of bytes in the
+two buffers, so we know when to dump the output to, or read more
+input from, the system.
+</para>
+
+<para>
+Let us see how it works now:
+</para>
+
+<screen>&prompt.user; <userinput>nasm -f elf hex.asm</userinput>
+&prompt.user; <userinput>ld -s -o hex hex.o</userinput>
+&prompt.user; <userinput>./hex</userinput>
+<userinput>Hello, World!</userinput>
+<userinput>Here I come!</userinput>
+48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A
+48 65 72 65 20 49 20 63 6F 6D 65 21 0A
+<userinput>^D</userinput> &prompt.user;</screen>
+
+<para>
+Not what you expected? The program did not print the output
+until we pressed <userinput>^D</userinput>. That is easy to fix by
+inserting three lines of code to write the output every time
+we have converted a new line to <constant>0A</constant>. I have marked
+the three lines with &gt; (do not copy the &gt; in your
+<filename>hex.asm</filename>).
+</para>
+
+<programlisting>
+%include 'system.inc'
+
+%define BUFSIZE 2048
+
+section .data
+hex db '0123456789ABCDEF'
+
+section .bss
+ibuffer resb BUFSIZE
+obuffer resb BUFSIZE
+
+section .text
+global _start
+_start:
+ sub eax, eax
+ sub ebx, ebx
+ sub ecx, ecx
+ mov edi, obuffer
+
+.loop:
+ ; read a byte from stdin
+ call getchar
+
+ ; convert it to hex
+ mov dl, al
+ shr al, 4
+ mov al, [hex+eax]
+ call putchar
+
+ mov al, dl
+ and al, 0Fh
+ mov al, [hex+eax]
+ call putchar
+
+ mov al, ' '
+ cmp dl, 0Ah
+ jne .put
+ mov al, dl
+
+.put:
+ call putchar
+&gt; cmp al, 0Ah
+&gt; jne .loop
+&gt; call write
+ jmp short .loop
+
+align 4
+getchar:
+ or ebx, ebx
+ jne .fetch
+
+ call read
+
+.fetch:
+ lodsb
+ dec ebx
+ ret
+
+read:
+ push dword BUFSIZE
+ mov esi, ibuffer
+ push esi
+ push dword stdin
+ sys.read
+ add esp, byte 12
+ mov ebx, eax
+ or eax, eax
+ je .done
+ sub eax, eax
+ ret
+
+align 4
+.done:
+ call write ; flush output buffer
+ push dword 0
+ sys.exit
+
+align 4
+putchar:
+ stosb
+ inc ecx
+ cmp ecx, BUFSIZE
+ je write
+ ret
+
+align 4
+write:
+ sub edi, ecx ; start of buffer
+ push ecx
+ push edi
+ push dword stdout
+ sys.write
+ add esp, byte 12
+ sub eax, eax
+ sub ecx, ecx ; buffer is empty now
+ ret
+</programlisting>
+
+<para>
+Now, let us see how it works:
+</para>
+
+<screen>&prompt.user; <userinput>nasm -f elf hex.asm</userinput>
+&prompt.user; <userinput>ld -s -o hex hex.o</userinput>
+&prompt.user; <userinput>./hex</userinput>
+<userinput>Hello, World!</userinput>
+48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A
+<userinput>Here I come!</userinput>
+48 65 72 65 20 49 20 63 6F 6D 65 21 0A
+<userinput>^D</userinput> &prompt.user;</screen>
+
+<para>
+Not bad for a 644-byte executable, is it!
+</para>
+
+<note>
+<para>
+This approach to buffered input/output still
+contains a hidden danger. I will discuss&mdash;and
+fix&mdash;it later, when I talk about the
+<link linkend="x86-buffered-dark-side">dark
+side of buffering</link>.</para>
+</note>
+
+<sect2 xml:id="x86-ungetc">
+<title>How to Unread a Character</title>
+
+<warning><para>
+This may be a somewhat advanced topic, mostly of interest to
+programmers familiar with the theory of compilers. If you wish,
+you may <link linkend="x86-command-line">skip to the next
+section</link>, and perhaps read this later.
+</para>
+</warning>
+<para>
+While our sample program does not require it, more sophisticated
+filters often need to look ahead. In other words, they may need
+to see what the next character is (or even several characters).
+If the next character is of a certain value, it is part of the
+token currently being processed. Otherwise, it is not.
+</para>
+
+<para>
+For example, you may be parsing the input stream for a textual
+string (e.g., when implementing a language compiler): If a
+character is followed by another character, or perhaps a digit,
+it is part of the token you are processing. If it is followed by
+white space, or some other value, then it is not part of the
+current token.
+</para>
+
+<para>
+This presents an interesting problem: How to return the next
+character back to the input stream, so it can be read again
+later?
+</para>
+
+<para>
+One possible solution is to store it in a character variable,
+then set a flag. We can modify <function>getchar</function> to check the flag,
+and if it is set, fetch the byte from that variable instead of the
+input buffer, and reset the flag. But, of course, that slows us
+down.
+</para>
+
+<para>
+The C language has an <function>ungetc()</function> function, just for that
+purpose. Is there a quick way to implement it in our code?
+I would like you to scroll back up and take a look at the
+<function>getchar</function> procedure and see if you can find a nice and
+fast solution before reading the next paragraph. Then come back
+here and see my own solution.
+</para>
+
+<para>
+The key to returning a character back to the stream is in how
+we are getting the characters to start with:
+</para>
+
+<para>
+First we check if the buffer is empty by testing the value
+of <varname role="register">EBX</varname>. If it is zero, we call the
+<function>read</function> procedure.
+</para>
+
+<para>
+If we do have a character available, we use <function role="opcode">lodsb</function>, then
+decrease the value of <varname role="register">EBX</varname>. The <function role="opcode">lodsb</function>
+instruction is effectively identical to:
+</para>
+
+<programlisting>
+ mov al, [esi]
+ inc esi
+</programlisting>
+
+<para>
+The byte we have fetched remains in the buffer until the next
+time <function>read</function> is called. We do not know when that happens,
+but we do know it will not happen until the next call to
+<function>getchar</function>. Hence, to "return" the last-read byte back
+to the stream, all we have to do is decrease the value of
+<varname role="register">ESI</varname> and increase the value of <varname role="register">EBX</varname>:
+</para>
+
+<programlisting>
+ungetc:
+ dec esi
+ inc ebx
+ ret
+</programlisting>
+
+<para>
+But, be careful! We are perfectly safe doing this if our look-ahead
+is at most one character at a time. If we are examining more than
+one upcoming character and call <function>ungetc</function> several times
+in a row, it will work most of the time, but not all the time
+(and will be tough to debug). Why?
+</para>
+
+<para>
+Because as long as <function>getchar</function> does not have to call
+<function>read</function>, all of the pre-read bytes are still in the buffer,
+and our <function>ungetc</function> works without a glitch. But the moment
+<function>getchar</function> calls <function>read</function>,
+the contents of the buffer change.
+</para>
+
+<para>
+We can always rely on <function>ungetc</function> working properly on the last
+character we have read with <function>getchar</function>, but not on anything
+we have read before that.
+</para>
+
+<para>
+If your program reads more than one byte ahead, you have at least
+two choices:
+</para>
+
+<para>
+If possible, modify the program so it only reads one byte ahead.
+This is the simplest solution.
+</para>
+
+<para>
+If that option is not available, first of all determine the maximum
+number of characters your program needs to return to the input
+stream at one time. Increase that number slightly, just to be
+sure, preferably to a multiple of 16&mdash;so it aligns nicely.
+Then modify the <varname>.bss</varname> section of your code, and create
+a small "spare" buffer right before your input buffer,
+something like this:
+</para>
+
+<programlisting>
+section .bss
+ resb 16 ; or whatever the value you came up with
+ibuffer resb BUFSIZE
+obuffer resb BUFSIZE
+</programlisting>
+
+<para>
+You also need to modify your <function>ungetc</function> to pass the value
+of the byte to unget in <varname role="register">AL</varname>:
+</para>
+
+<programlisting>
+ungetc:
+ dec esi
+ inc ebx
+ mov [esi], al
+ ret
+</programlisting>
+
+<para>
+With this modification, you can call <function>ungetc</function>
+up to 17 times in a row safely (the first call will still
+be within the buffer, the remaining 16 may be either within
+the buffer or within the "spare").
+</para>
+
+</sect2>
+
+</sect1>
+
+<sect1 xml:id="x86-command-line"><title>Command Line Arguments</title>
+
+<para>
+Our <application>hex</application> program will be more useful if it can
+read the names of an input and output file from its command
+line, i.e., if it can process the command line arguments.
+But... Where are they?
+</para>
+
+<para>
+Before a &unix; system starts a program, it <function role="opcode">push</function>es some
+data on the stack, then jumps at the <varname>_start</varname>
+label of the program. Yes, I said jumps, not calls. That means the
+data can be accessed by reading <varname>[esp+offset]</varname>,
+or by simply <function role="opcode">pop</function>ping it.
+</para>
+
+<para>
+The value at the top of the stack contains the number of
+command line arguments. It is traditionally called
+<varname>argc</varname>, for "argument count."
+</para>
+
+<para>
+Command line arguments follow next, all <varname>argc</varname> of them.
+These are typically referred to as <varname>argv</varname>, for
+"argument value(s)." That is, we get <varname>argv[0]</varname>,
+<varname>argv[1]</varname>, <varname>...</varname>,
+<varname>argv[argc-1]</varname>. These are not the actual
+arguments, but pointers to arguments, i.e., memory addresses of
+the actual arguments. The arguments themselves are
+NUL-terminated character strings.
+</para>
+
+<para>
+The <varname>argv</varname> list is followed by a NULL pointer,
+which is simply a <constant>0</constant>. There is more, but this is
+enough for our purposes right now.
+</para>
+
+<note>
+<para>
+If you have come from the <acronym>&ms-dos;</acronym> programming
+environment, the main difference is that each argument is in
+a separate string. The second difference is that there is no
+practical limit on how many arguments there can be.
+</para>
+</note>
+
+<para>
+Armed with this knowledge, we are almost ready for the next
+version of <filename>hex.asm</filename>. First, however, we need to
+add a few lines to <filename>system.inc</filename>:
+</para>
+
+<para>
+First, we need to add two new entries to our list of system
+call numbers:
+</para>
+
+<programlisting>
+%define SYS_open 5
+%define SYS_close 6
+</programlisting>
+
+<para>
+Then we add two new macros at the end of the file:
+</para>
+
+<programlisting>
+%macro sys.open 0
+ system SYS_open
+%endmacro
+
+%macro sys.close 0
+ system SYS_close
+%endmacro
+</programlisting>
+
+<para>
+Here, then, is our modified source code:
+</para>
+
+<programlisting>
+%include 'system.inc'
+
+%define BUFSIZE 2048
+
+section .data
+fd.in dd stdin
+fd.out dd stdout
+hex db '0123456789ABCDEF'
+
+section .bss
+ibuffer resb BUFSIZE
+obuffer resb BUFSIZE
+
+section .text
+align 4
+err:
+ push dword 1 ; return failure
+ sys.exit
+
+align 4
+global _start
+_start:
+ add esp, byte 8 ; discard argc and argv[0]
+
+ pop ecx
+ jecxz .init ; no more arguments
+
+ ; ECX contains the path to input file
+ push dword 0 ; O_RDONLY
+ push ecx
+ sys.open
+ jc err ; open failed
+
+ add esp, byte 8
+ mov [fd.in], eax
+
+ pop ecx
+ jecxz .init ; no more arguments
+
+ ; ECX contains the path to output file
+ push dword 420 ; file mode (644 octal)
+ push dword 0200h | 0400h | 01h
+ ; O_CREAT | O_TRUNC | O_WRONLY
+ push ecx
+ sys.open
+ jc err
+
+ add esp, byte 12
+ mov [fd.out], eax
+
+.init:
+ sub eax, eax
+ sub ebx, ebx
+ sub ecx, ecx
+ mov edi, obuffer
+
+.loop:
+ ; read a byte from input file or stdin
+ call getchar
+
+ ; convert it to hex
+ mov dl, al
+ shr al, 4
+ mov al, [hex+eax]
+ call putchar
+
+ mov al, dl
+ and al, 0Fh
+ mov al, [hex+eax]
+ call putchar
+
+ mov al, ' '
+ cmp dl, 0Ah
+ jne .put
+ mov al, dl
+
+.put:
+ call putchar
+ cmp al, dl
+ jne .loop
+ call write
+ jmp short .loop
+
+align 4
+getchar:
+ or ebx, ebx
+ jne .fetch
+
+ call read
+
+.fetch:
+ lodsb
+ dec ebx
+ ret
+
+read:
+ push dword BUFSIZE
+ mov esi, ibuffer
+ push esi
+ push dword [fd.in]
+ sys.read
+ add esp, byte 12
+ mov ebx, eax
+ or eax, eax
+ je .done
+ sub eax, eax
+ ret
+
+align 4
+.done:
+ call write ; flush output buffer
+
+ ; close files
+ push dword [fd.in]
+ sys.close
+
+ push dword [fd.out]
+ sys.close
+
+ ; return success
+ push dword 0
+ sys.exit
+
+align 4
+putchar:
+ stosb
+ inc ecx
+ cmp ecx, BUFSIZE
+ je write
+ ret
+
+align 4
+write:
+ sub edi, ecx ; start of buffer
+ push ecx
+ push edi
+ push dword [fd.out]
+ sys.write
+ add esp, byte 12
+ sub eax, eax
+ sub ecx, ecx ; buffer is empty now
+ ret
+</programlisting>
+
+<para>
+In our <varname>.data</varname> section we now have two new variables,
+<varname>fd.in</varname> and <varname>fd.out</varname>. We store the input and
+output file descriptors here.
+</para>
+
+<para>
+In the <varname>.text</varname> section we have replaced the references
+to <varname>stdin</varname> and <varname>stdout</varname> with
+<varname>[fd.in]</varname> and <varname>[fd.out]</varname>.
+</para>
+
+<para>
+The <varname>.text</varname> section now starts with a simple error
+handler, which does nothing but exit the program with a return
+value of <constant>1</constant>.
+The error handler is before <varname>_start</varname> so we are
+within a short distance from where the errors occur.
+</para>
+
+<para>
+Naturally, the program execution still begins at <varname>_start</varname>.
+First, we remove <varname>argc</varname> and <varname>argv[0]</varname> from the
+stack: They are of no interest to us (in this program, that is).
+</para>
+
+<para>
+We pop <varname>argv[1]</varname> to <varname role="register">ECX</varname>. This
+register is particularly suited for pointers, as we can handle
+NULL pointers with <function role="opcode">jecxz</function>. If <varname>argv[1]</varname>
+is not NULL, we try to open the file named in the first
+argument. Otherwise, we continue the program as before: Reading
+from <varname>stdin</varname>, writing to <varname>stdout</varname>.
+If we fail to open the input file (e.g., it does not exist),
+we jump to the error handler and quit.
+</para>
+
+<para>
+If all went well, we now check for the second argument. If
+it is there, we open the output file. Otherwise, we send
+the output to <varname>stdout</varname>. If we fail to open the output
+file (e.g., it exists and we do not have the write permission),
+we, again, jump to the error handler.
+</para>
+
+<para>
+The rest of the code is the same as before, except we close
+the input and output files before exiting, and, as mentioned,
+we use <varname>[fd.in]</varname> and <varname>[fd.out]</varname>.
+</para>
+
+<para>
+Our executable is now a whopping 768 bytes long.
+</para>
+
+<para>
+Can we still improve it? Of course! Every program can be improved.
+Here are a few ideas of what we could do:
+</para>
+
+<itemizedlist>
+<listitem>
+<para>
+Have our error handler print a message to
+<varname>stderr</varname>.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Add error handlers to the <function>read</function>
+and <function>write</function> functions.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Close <varname>stdin</varname> when we open an input file,
+<varname>stdout</varname> when we open an output file.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Add command line switches, such as <parameter>-i</parameter>
+and <parameter>-o</parameter>, so we can list the input and
+output files in any order, or perhaps read from
+<varname>stdin</varname> and write to a file.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Print a usage message if command line arguments are incorrect.
+</para>
+</listitem>
+
+</itemizedlist>
+<para>
+I shall leave these enhancements as an exercise to the reader:
+You already know everything you need to know to implement them.
+</para>
+
+</sect1>
+
+<sect1 xml:id="x86-environment">
+<title>&unix; Environment</title>
+
+<para>
+An important &unix; concept is the environment, which is defined by
+<emphasis>environment variables</emphasis>. Some are set by the system, others
+by you, yet others by the <application>shell</application>, or any program
+that loads another program.
+</para>
+
+<sect2 xml:id="x86-find-environment">
+<title>How to Find Environment Variables</title>
+
+<para>
+I said earlier that when a program starts executing, the stack
+contains <varname>argc</varname> followed by the NULL-terminated
+<varname>argv</varname> array, followed by something else. The
+"something else" is the <emphasis>environment</emphasis>, or,
+to be more precise, a NULL-terminated array of pointers to
+<emphasis>environment variables</emphasis>. This is often referred
+to as <varname>env</varname>.
+</para>
+
+<para>
+The structure of <varname>env</varname> is the same as that of
+<varname>argv</varname>, a list of memory addresses followed by a
+NULL (<constant>0</constant>). In this case, there is no
+<varname>"envc"</varname>&mdash;we figure out where the array ends
+by searching for the final NULL.
+</para>
+
+<para>
+The variables usually come in the <varname>name=value</varname>
+format, but sometimes the <varname>=value</varname> part
+may be missing. We need to account for that possibility.
+</para>
+
+</sect2>
+
+<sect2 xml:id="x86-webvar">
+<title>webvars</title>
+
+<para>
+I could just show you some code that prints the environment
+the same way the &unix; <application>env</application> command does. But
+I thought it would be more interesting to write a simple
+assembly language CGI utility.
+</para>
+
+<sect3 xml:id="x86-cgi">
+<title>CGI: A Quick Overview</title>
+
+<para>
+I have a
+<link xlink:href="http://www.whizkidtech.redprince.net/cgi-bin/tutorial">detailed
+<acronym>CGI</acronym> tutorial</link> on my web site,
+but here is a very quick overview of <acronym>CGI</acronym>:
+</para>
+
+<itemizedlist>
+<listitem>
+<para>
+The web server communicates with the <acronym>CGI</acronym>
+program by setting <emphasis>environment variables</emphasis>.
+</para>
+</listitem>
+
+<listitem>
+<para>
+The <acronym>CGI</acronym> program
+sends its output to <filename>stdout</filename>.
+The web server reads it from there.
+</para>
+</listitem>
+
+<listitem>
+<para>
+It must start with an <acronym>HTTP</acronym>
+header followed by two blank lines.
+</para>
+</listitem>
+
+<listitem>
+<para>
+It then prints the <acronym>HTML</acronym>
+code, or whatever other type of data it is producing.
+</para>
+</listitem>
+
+</itemizedlist>
+<note>
+<para>
+While certain <emphasis>environment variables</emphasis> use
+standard names, others vary, depending on the web server. That
+makes <application>webvars</application>
+quite a useful diagnostic tool.
+</para>
+</note>
+
+</sect3>
+
+<sect3 xml:id="x86-webvars-the-code">
+<title>The Code</title>
+
+<para>
+Our <application>webvars</application> program, then, must send out
+the <acronym>HTTP</acronym> header followed by some
+<acronym>HTML</acronym> mark-up. It then must read
+the <emphasis>environment variables</emphasis> one by one
+and send them out as part of the
+<acronym>HTML</acronym> page.
+</para>
+
+<para>
+The code follows. I placed comments and explanations
+right inside the code:
+</para>
+
+<programlisting>
+;;;;;;; webvars.asm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; Copyright (c) 2000 G. Adam Stanislav
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions
+; are met:
+; 1. Redistributions of source code must retain the above copyright
+; notice, this list of conditions and the following disclaimer.
+; 2. Redistributions in binary form must reproduce the above copyright
+; notice, this list of conditions and the following disclaimer in the
+; documentation and/or other materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+; SUCH DAMAGE.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; Version 1.0
+;
+; Started: 8-Dec-2000
+; Updated: 8-Dec-2000
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+%include 'system.inc'
+
+section .data
+http db 'Content-type: text/html', 0Ah, 0Ah
+ db '&lt;?xml version="1.0" encoding="utf-8"?&gt;', 0Ah
+ db '&lt;!DOCTYPE html PUBLIC "-//W3C/DTD XHTML Strict//EN" '
+ db '"DTD/xhtml1-strict.dtd"&gt;', 0Ah
+ db '&lt;html xmlns="http://www.w3.org/1999/xhtml" '
+ db 'xml.lang="en" lang="en"&gt;', 0Ah
+ db '&lt;head&gt;', 0Ah
+ db '&lt;title&gt;Web Environment&lt;/title&gt;', 0Ah
+ db '&lt;meta name="author" content="G. Adam Stanislav" /&gt;', 0Ah
+ db '&lt;/head&gt;', 0Ah, 0Ah
+ db '&lt;body bgcolor="#ffffff" text="#000000" link="#0000ff" '
+ db 'vlink="#840084" alink="#0000ff"&gt;', 0Ah
+ db '&lt;div class="webvars"&gt;', 0Ah
+ db '&lt;h1&gt;Web Environment&lt;/h1&gt;', 0Ah
+ db '&lt;p&gt;The following &lt;b&gt;environment variables&lt;/b&gt; are defined '
+ db 'on this web server:&lt;/p&gt;', 0Ah, 0Ah
+ db '&lt;table align="center" width="80" border="0" cellpadding="10" '
+ db 'cellspacing="0" class="webvars"&gt;', 0Ah
+httplen equ $-http
+left db '&lt;tr&gt;', 0Ah
+ db '&lt;td class="name"&gt;&lt;tt&gt;'
+leftlen equ $-left
+middle db '&lt;/tt&gt;&lt;/td&gt;', 0Ah
+ db '&lt;td class="value"&gt;&lt;tt&gt;&lt;b&gt;'
+midlen equ $-middle
+undef db '&lt;i&gt;(undefined)&lt;/i&gt;'
+undeflen equ $-undef
+right db '&lt;/b&gt;&lt;/tt&gt;&lt;/td&gt;', 0Ah
+ db '&lt;/tr&gt;', 0Ah
+rightlen equ $-right
+wrap db '&lt;/table&gt;', 0Ah
+ db '&lt;/div&gt;', 0Ah
+ db '&lt;/body&gt;', 0Ah
+ db '&lt;/html&gt;', 0Ah, 0Ah
+wraplen equ $-wrap
+
+section .text
+global _start
+_start:
+ ; First, send out all the http and xhtml stuff that is
+ ; needed before we start showing the environment
+ push dword httplen
+ push dword http
+ push dword stdout
+ sys.write
+
+ ; Now find how far on the stack the environment pointers
+ ; are. We have 12 bytes we have pushed before "argc"
+ mov eax, [esp+12]
+
+ ; We need to remove the following from the stack:
+ ;
+ ; The 12 bytes we pushed for sys.write
+ ; The 4 bytes of argc
+ ; The EAX*4 bytes of argv
+ ; The 4 bytes of the NULL after argv
+ ;
+ ; Total:
+ ; 20 + eax * 4
+ ;
+ ; Because stack grows down, we need to ADD that many bytes
+ ; to ESP.
+ lea esp, [esp+20+eax*4]
+ cld ; This should already be the case, but let's be sure.
+
+ ; Loop through the environment, printing it out
+.loop:
+ pop edi
+ or edi, edi ; Done yet?
+ je near .wrap
+
+ ; Print the left part of HTML
+ push dword leftlen
+ push dword left
+ push dword stdout
+ sys.write
+
+ ; It may be tempting to search for the '=' in the env string next.
+ ; But it is possible there is no '=', so we search for the
+ ; terminating NUL first.
+ mov esi, edi ; Save start of string
+ sub ecx, ecx
+ not ecx ; ECX = FFFFFFFF
+ sub eax, eax
+repne scasb
+ not ecx ; ECX = string length + 1
+ mov ebx, ecx ; Save it in EBX
+
+ ; Now is the time to find '='
+ mov edi, esi ; Start of string
+ mov al, '='
+repne scasb
+ not ecx
+ add ecx, ebx ; Length of name
+
+ push ecx
+ push esi
+ push dword stdout
+ sys.write
+
+ ; Print the middle part of HTML table code
+ push dword midlen
+ push dword middle
+ push dword stdout
+ sys.write
+
+ ; Find the length of the value
+ not ecx
+ lea ebx, [ebx+ecx-1]
+
+ ; Print "undefined" if 0
+ or ebx, ebx
+ jne .value
+
+ mov ebx, undeflen
+ mov edi, undef
+
+.value:
+ push ebx
+ push edi
+ push dword stdout
+ sys.write
+
+ ; Print the right part of the table row
+ push dword rightlen
+ push dword right
+ push dword stdout
+ sys.write
+
+ ; Get rid of the 60 bytes we have pushed
+ add esp, byte 60
+
+ ; Get the next variable
+ jmp .loop
+
+.wrap:
+ ; Print the rest of HTML
+ push dword wraplen
+ push dword wrap
+ push dword stdout
+ sys.write
+
+ ; Return success
+ push dword 0
+ sys.exit
+</programlisting>
+
+<para>
+This code produces a 1,396-byte executable. Most of it is data,
+i.e., the <acronym>HTML</acronym> mark-up we need to send out.
+</para>
+
+<para>
+Assemble and link it as usual:
+</para>
+
+<screen>&prompt.user; <userinput>nasm -f elf webvars.asm</userinput>
+&prompt.user; <userinput>ld -s -o webvars webvars.o</userinput></screen>
+
+<para>
+To use it, you need to upload <filename>webvars</filename> to your
+web server. Depending on how your web server is set up, you
+may have to store it in a special <filename>cgi-bin</filename> directory,
+or perhaps rename it with a <filename>.cgi</filename> extension.
+</para>
+
+<para>
+Then you need to use your browser to view its output.
+To see its output on my web server, please go to
+<link xlink:href="http://www.int80h.org/webvars/"><filename>http://www.int80h.org/webvars/</filename></link>.
+If curious about the additional environment variables
+present in a password protected web directory, go to
+<link xlink:href="http://www.int80h.org/private/"><filename>http://www.int80h.org/private/</filename></link>,
+using the name <userinput>asm</userinput> and password
+<userinput>programmer</userinput>.
+</para>
+
+</sect3>
+
+</sect2>
+
+</sect1>
+
+<sect1 xml:id="x86-files">
+<title>Working with Files</title>
+
+<para>
+We have already done some basic file work: We know how
+to open and close them, how to read and write them using
+buffers. But &unix; offers much more functionality when it
+comes to files. We will examine some of it in this section,
+and end up with a nice file conversion utility.
+</para>
+
+<para>
+Indeed, let us start at the end, that is, with the file
+conversion utility. It always makes programming easier
+when we know from the start what the end product is
+supposed to do.
+</para>
+
+<para>
+One of the first programs I wrote for &unix; was
+<link xlink:href="ftp://ftp.int80h.org/unix/tuc/"><application>tuc</application></link>,
+a text-to-&unix; file converter. It converts a text
+file from other operating systems to a &unix; text file.
+In other words, it changes from different kind of line endings
+to the newline convention of &unix;. It saves the output
+in a different file. Optionally, it converts a &unix; text
+file to a <acronym>DOS</acronym> text file.
+</para>
+
+<para>
+I have used <application>tuc</application> extensively, but always
+only to convert from some other <acronym>OS</acronym>
+to &unix;, never the other way. I have always wished
+it would just overwrite the file instead of me having
+to send the output to a different file. Most of the time,
+I end up using it like this:
+</para>
+
+<screen>&prompt.user; <userinput>tuc myfile tempfile</userinput>
+&prompt.user; <userinput>mv tempfile myfile</userinput></screen>
+
+<para>
+It would be nice to have a <application>ftuc</application>,
+i.e., <emphasis>fast tuc</emphasis>, and use it like this:
+</para>
+
+<screen>&prompt.user; <userinput>ftuc myfile</userinput></screen>
+
+<para>
+In this chapter, then, we will write
+<application>ftuc</application> in assembly language
+(the original <application>tuc</application>
+is in C), and study various
+file-oriented kernel services in the process.
+</para>
+
+<para>
+At first sight, such a file conversion is very
+simple: All you have to do is strip the carriage
+returns, right?
+</para>
+
+<para>
+If you answered yes, think again: That approach will
+work most of the time (at least with <acronym>MS
+DOS</acronym> text files), but will fail occasionally.
+</para>
+
+<para>
+The problem is that not all non &unix; text files end their
+line with the carriage return / line feed sequence. Some
+use carriage returns without line feeds. Others combine several
+blank lines into a single carriage return followed by several
+line feeds. And so on.
+</para>
+
+<para>
+A text file converter, then, must be able to handle
+any possible line endings:
+</para>
+
+<itemizedlist>
+<listitem>
+<para>
+carriage return / line feed
+</para>
+</listitem>
+
+<listitem>
+<para>
+carriage return
+</para>
+</listitem>
+
+<listitem>
+<para>
+line feed / carriage return
+</para>
+</listitem>
+
+<listitem>
+<para>
+line feed
+</para>
+</listitem>
+
+</itemizedlist>
+<para>
+It should also handle files that use some kind of a
+combination of the above (e.g., carriage return followed
+by several line feeds).
+</para>
+
+<sect2 xml:id="x86-finite-state-machine">
+<title>Finite State Machine</title>
+
+<para>
+The problem is easily solved by the use of a technique
+called <emphasis>finite state machine</emphasis>, originally developed
+by the designers of digital electronic circuits. A
+<emphasis>finite state machine</emphasis> is a digital circuit
+whose output is dependent not only on its input but on
+its previous input, i.e., on its state. The microprocessor
+is an example of a <emphasis>finite state machine</emphasis>: Our
+assembly language code is assembled to machine language in which
+some assembly language code produces a single byte
+of machine language, while others produce several bytes.
+As the microprocessor fetches the bytes from the memory
+one by one, some of them simply change its state rather than
+produce some output. When all the bytes of the op code are
+fetched, the microprocessor produces some output, or changes
+the value of a register, etc.
+</para>
+
+<para>
+Because of that, all software is essentially a sequence of state
+instructions for the microprocessor. Nevertheless, the concept
+of <emphasis>finite state machine</emphasis> is useful in software design as well.
+</para>
+
+<para>
+Our text file converter can be designed as a <emphasis>finite state machine</emphasis> with three
+possible states. We could call them states 0-2,
+but it will make our life easier if we give them symbolic names:
+</para>
+
+<itemizedlist>
+<listitem>
+<para>
+<symbol>ordinary
+</symbol></para>
+</listitem>
+
+<listitem>
+<para>
+<symbol>cr
+</symbol></para>
+</listitem>
+
+<listitem>
+<para>
+<symbol>lf
+</symbol></para>
+</listitem>
+
+</itemizedlist>
+<para>
+Our program will start in the <symbol>ordinary</symbol>
+state. During this state, the program action depends on
+its input as follows:
+</para>
+
+<itemizedlist>
+<listitem>
+<para>
+If the input is anything other than a carriage return
+or line feed, the input is simply passed on to the output. The
+state remains unchanged.
+</para>
+</listitem>
+
+<listitem>
+<para>
+If the input is a carriage return, the state is changed
+to <symbol>cr</symbol>. The input is then discarded, i.e.,
+no output is made.
+</para>
+</listitem>
+
+<listitem>
+<para>
+If the input is a line feed, the state is changed to
+<symbol>lf</symbol>. The input is then discarded.
+</para>
+</listitem>
+
+</itemizedlist>
+<para>
+Whenever we are in the <symbol>cr</symbol> state, it is
+because the last input was a carriage return, which was
+unprocessed. What our software does in this state again
+depends on the current input:
+</para>
+
+<itemizedlist>
+<listitem>
+<para>
+If the input is anything other than a carriage return
+or line feed, output a line feed, then output the input, then
+change the state to <symbol>ordinary</symbol>.
+</para>
+</listitem>
+
+<listitem>
+<para>
+If the input is a carriage return, we have received
+two (or more) carriage returns in a row. We discard the
+input, we output a line feed, and leave the state unchanged.
+</para>
+</listitem>
+
+<listitem>
+<para>
+If the input is a line feed, we output the line feed
+and change the state to <symbol>ordinary</symbol>. Note that
+this is not the same as the first case above &ndash; if we tried
+to combine them, we would be outputting two line feeds
+instead of one.
+</para>
+</listitem>
+
+</itemizedlist>
+<para>
+Finally, we are in the <symbol>lf</symbol> state after
+we have received a line feed that was not preceded by a
+carriage return. This will happen when our file already is
+in &unix; format, or whenever several lines in a row are
+expressed by a single carriage return followed by several
+line feeds, or when line ends with a line feed /
+carriage return sequence. Here is how we need to handle
+our input in this state:
+</para>
+
+<itemizedlist>
+<listitem>
+<para>
+If the input is anything other than a carriage return or
+line feed, we output a line feed, then output the input, then
+change the state to <symbol>ordinary</symbol>. This is exactly
+the same action as in the <symbol>cr</symbol> state upon
+receiving the same kind of input.
+</para>
+</listitem>
+
+<listitem>
+<para>
+If the input is a carriage return, we discard the input,
+we output a line feed, then change the state to <symbol>ordinary</symbol>.
+</para>
+</listitem>
+
+<listitem>
+<para>
+If the input is a line feed, we output the line feed,
+and leave the state unchanged.
+</para>
+</listitem>
+
+</itemizedlist>
+<sect3 xml:id="x86-final-state">
+<title>The Final State</title>
+
+<para>
+The above <emphasis>finite state machine</emphasis> works for the entire file, but leaves
+the possibility that the final line end will be ignored. That will
+happen whenever the file ends with a single carriage return or
+a single line feed. I did not think of it when I wrote
+<application>tuc</application>, just to discover that
+occasionally it strips the last line ending.
+</para>
+
+<para>
+This problem is easily fixed by checking the state after the
+entire file was processed. If the state is not
+<symbol>ordinary</symbol>, we simply
+need to output one last line feed.
+</para>
+
+<note>
+<para>
+Now that we have expressed our algorithm as a <emphasis>finite state machine</emphasis>,
+we could easily design a dedicated digital electronic
+circuit (a "chip") to do the conversion for us. Of course,
+doing so would be considerably more expensive than writing
+an assembly language program.
+</para>
+</note>
+
+</sect3>
+
+<sect3 xml:id="x86-tuc-counter">
+<title>The Output Counter</title>
+
+<para>
+Because our file conversion program may be combining two
+characters into one, we need to use an output counter. We
+initialize it to <constant>0</constant>, and increase it
+every time we send a character to the output. At the end of
+the program, the counter will tell us what size we need
+to set the file to.
+</para>
+
+</sect3>
+
+</sect2>
+
+<sect2 xml:id="x86-software-fsm">
+<title>Implementing FSM in Software</title>
+
+<para>
+The hardest part of working with a <emphasis>finite state machine</emphasis>
+is analyzing the problem and expressing it as a
+<emphasis>finite state machine</emphasis>. That accomplished,
+the software almost writes itself.
+</para>
+
+<para>
+In a high-level language, such as C, there are several main
+approaches. One is to use a <function role="statement">switch</function> statement
+which chooses what function should be run. For example,
+</para>
+
+<programlisting>
+ switch (state) {
+ default:
+ case REGULAR:
+ regular(inputchar);
+ break;
+ case CR:
+ cr(inputchar);
+ break;
+ case LF:
+ lf(inputchar);
+ break;
+ }
+</programlisting>
+
+<para>
+Another approach is by using an array of function pointers,
+something like this:
+</para>
+
+<programlisting>
+ (output[state])(inputchar);
+</programlisting>
+
+<para>
+Yet another is to have <varname>state</varname> be a
+function pointer, set to point at the appropriate function:
+</para>
+
+<programlisting>
+ (*state)(inputchar);
+</programlisting>
+<para>
+This is the approach we will use in our program because it is very easy to do in assembly language, and very fast, too. We will simply keep the address of the right procedure in <varname role="register">EBX</varname>, and then just issue:</para>
+
+<programlisting>
+ call ebx
+</programlisting>
+
+<para>
+This is possibly faster than hardcoding the address in the code
+because the microprocessor does not have to fetch the address from
+the memory&mdash;it is already stored in one of its registers. I said
+<emphasis>possibly</emphasis> because with the caching modern
+microprocessors do, either way may be equally fast.
+</para>
+
+</sect2>
+
+<sect2 xml:id="memory-mapped-files">
+<title>Memory Mapped Files</title>
+
+<para>
+Because our program works on a single file, we cannot use the
+approach that worked for us before, i.e., to read from an input
+file and to write to an output file.
+</para>
+
+<para>
+&unix; allows us to map a file, or a section of a file,
+into memory. To do that, we first need to open the file with the
+appropriate read/write flags. Then we use the <function role="syscall">mmap</function>
+system call to map it into the memory. One nice thing about
+<function role="syscall">mmap</function> is that it automatically works with
+virtual memory: We can map more of the file into the memory than
+we have physical memory available, yet still access it through
+regular memory op codes, such as <function role="opcode">mov</function>,
+<function role="opcode">lods</function>, and <function role="opcode">stos</function>.
+Whatever changes we make to the memory image of the file will be
+written to the file by the system. We do not even have to keep
+the file open: As long as it stays mapped, we can
+read from it and write to it.
+</para>
+
+<para>
+The 32-bit Intel microprocessors can access up to four
+gigabytes of memory &ndash; physical or virtual. The FreeBSD system
+allows us to use up to a half of it for file mapping.
+</para>
+
+<para>
+For simplicity sake, in this tutorial we will only convert files
+that can be mapped into the memory in their entirety. There are
+probably not too many text files that exceed two gigabytes in size.
+If our program encounters one, it will simply display a message
+suggesting we use the original
+<application>tuc</application> instead.
+</para>
+
+<para>
+If you examine your copy of <filename>syscalls.master</filename>,
+you will find two separate syscalls named <function role="syscall">mmap</function>.
+This is because of evolution of &unix;: There was the traditional
+<acronym>BSD</acronym> <function role="syscall">mmap</function>,
+syscall 71. That one was superseded by the <acronym>&posix;</acronym> <function role="syscall">mmap</function>,
+syscall 197. The FreeBSD system supports both because
+older programs were written by using the original <acronym>BSD</acronym>
+version. But new software uses the <acronym>&posix;</acronym> version,
+which is what we will use.
+</para>
+
+<para>
+The <filename>syscalls.master</filename> file lists
+the <acronym>&posix;</acronym> version like this:
+</para>
+
+<programlisting>
+197 STD BSD { caddr_t mmap(caddr_t addr, size_t len, int prot, \
+ int flags, int fd, long pad, off_t pos); }
+</programlisting>
+
+<para>
+This differs slightly from what
+<citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+says. That is because
+<citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+describes the C version.
+</para>
+
+<para>
+The difference is in the <varname>long pad</varname> argument, which is not present in the C version. However, the FreeBSD syscalls add a 32-bit pad after <function role="opcode">push</function>ing a 64-bit argument. In this case, <varname>off_t</varname> is a 64-bit value.</para>
+
+<para>
+When we are finished working with a memory-mapped file,
+we unmap it with the <function role="syscall">munmap</function> syscall:
+</para>
+
+<tip>
+<para>
+For an in-depth treatment of <function role="syscall">mmap</function>, see
+W. Richard Stevens'
+<link xlink:href="http://www.int80h.org/cgi-bin/isbn?isbn=0130810819">Unix
+Network Programming, Volume 2, Chapter 12</link>.
+</para>
+</tip>
+
+</sect2>
+
+<sect2 xml:id="x86-file-size">
+<title>Determining File Size</title>
+
+<para>
+Because we need to tell <function role="syscall">mmap</function> how many bytes
+of the file to map into the memory, and because we want to map
+the entire file, we need to determine the size of the file.
+</para>
+
+<para>
+We can use the <function role="syscall">fstat</function> syscall to get all
+the information about an open file that the system can give us.
+That includes the file size.
+</para>
+
+<para>
+Again, <filename>syscalls.master</filename> lists two versions
+of <function role="syscall">fstat</function>, a traditional one
+(syscall 62), and a <acronym>&posix;</acronym> one
+(syscall 189). Naturally, we will use the
+<acronym>&posix;</acronym> version:
+</para>
+
+<programlisting>
+189 STD POSIX { int fstat(int fd, struct stat *sb); }
+</programlisting>
+
+<para>
+This is a very straightforward call: We pass to it the address
+of a <varname remap="structname">stat</varname> structure and the descriptor
+of an open file. It will fill out the contents of the
+<varname remap="structname">stat</varname> structure.
+</para>
+
+<para>
+I do, however, have to say that I tried to declare the
+<varname remap="structname">stat</varname> structure in the
+<varname>.bss</varname> section, and
+<function role="syscall">fstat</function> did not like it: It set the carry
+flag indicating an error. After I changed the code to allocate
+the structure on the stack, everything was working fine.
+</para>
+
+</sect2>
+
+<sect2 xml:id="x86-ftruncate">
+<title>Changing the File Size</title>
+
+<para>
+Because our program may combine carriage return / line feed
+sequences into straight line feeds, our output may be smaller
+than our input. However, since we are placing our output into
+the same file we read the input from, we may have to change the
+size of the file.
+</para>
+
+<para>
+The <function role="syscall">ftruncate</function> system call allows us to do
+just that. Despite its somewhat misleading name, the
+<function role="syscall">ftruncate</function> system call can be used to both
+truncate the file (make it smaller) and to grow it.
+</para>
+
+<para>
+And yes, we will find two versions of <function role="syscall">ftruncate</function>
+in <filename>syscalls.master</filename>, an older one
+(130), and a newer one (201). We will use
+the newer one:
+</para>
+
+<programlisting>
+201 STD BSD { int ftruncate(int fd, int pad, off_t length); }
+</programlisting>
+
+<para>
+Please note that this one contains a <varname>int pad</varname> again.
+</para>
+
+</sect2>
+
+<sect2 xml:id="x86-ftuc">
+<title>ftuc</title>
+
+<para>
+We now know everything we need to write <application>ftuc</application>.
+We start by adding some new lines in <filename>system.inc</filename>.
+First, we define some constants and structures, somewhere at
+or near the beginning of the file:
+</para>
+
+<programlisting>
+;;;;;;; open flags
+%define O_RDONLY 0
+%define O_WRONLY 1
+%define O_RDWR 2
+
+;;;;;;; mmap flags
+%define PROT_NONE 0
+%define PROT_READ 1
+%define PROT_WRITE 2
+%define PROT_EXEC 4
+;;
+%define MAP_SHARED 0001h
+%define MAP_PRIVATE 0002h
+
+;;;;;;; stat structure
+struc stat
+st_dev resd 1 ; = 0
+st_ino resd 1 ; = 4
+st_mode resw 1 ; = 8, size is 16 bits
+st_nlink resw 1 ; = 10, ditto
+st_uid resd 1 ; = 12
+st_gid resd 1 ; = 16
+st_rdev resd 1 ; = 20
+st_atime resd 1 ; = 24
+st_atimensec resd 1 ; = 28
+st_mtime resd 1 ; = 32
+st_mtimensec resd 1 ; = 36
+st_ctime resd 1 ; = 40
+st_ctimensec resd 1 ; = 44
+st_size resd 2 ; = 48, size is 64 bits
+st_blocks resd 2 ; = 56, ditto
+st_blksize resd 1 ; = 64
+st_flags resd 1 ; = 68
+st_gen resd 1 ; = 72
+st_lspare resd 1 ; = 76
+st_qspare resd 4 ; = 80
+endstruc
+</programlisting>
+
+<para>
+We define the new syscalls:
+</para>
+
+<programlisting>
+%define SYS_mmap 197
+%define SYS_munmap 73
+%define SYS_fstat 189
+%define SYS_ftruncate 201
+</programlisting>
+
+<para>
+We add the macros for their use:
+</para>
+
+<programlisting>
+%macro sys.mmap 0
+ system SYS_mmap
+%endmacro
+
+%macro sys.munmap 0
+ system SYS_munmap
+%endmacro
+
+%macro sys.ftruncate 0
+ system SYS_ftruncate
+%endmacro
+
+%macro sys.fstat 0
+ system SYS_fstat
+%endmacro
+</programlisting>
+
+<para>
+And here is our code:
+</para>
+
+<programlisting>
+;;;;;;; Fast Text-to-Unix Conversion (ftuc.asm) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Started: 21-Dec-2000
+;; Updated: 22-Dec-2000
+;;
+;; Copyright 2000 G. Adam Stanislav.
+;; All rights reserved.
+;;
+;;;;;;; v.1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+%include 'system.inc'
+
+section .data
+ db 'Copyright 2000 G. Adam Stanislav.', 0Ah
+ db 'All rights reserved.', 0Ah
+usg db 'Usage: ftuc filename', 0Ah
+usglen equ $-usg
+co db "ftuc: Can't open file.", 0Ah
+colen equ $-co
+fae db 'ftuc: File access error.', 0Ah
+faelen equ $-fae
+ftl db 'ftuc: File too long, use regular tuc instead.', 0Ah
+ftllen equ $-ftl
+mae db 'ftuc: Memory allocation error.', 0Ah
+maelen equ $-mae
+
+section .text
+
+align 4
+memerr:
+ push dword maelen
+ push dword mae
+ jmp short error
+
+align 4
+toolong:
+ push dword ftllen
+ push dword ftl
+ jmp short error
+
+align 4
+facerr:
+ push dword faelen
+ push dword fae
+ jmp short error
+
+align 4
+cantopen:
+ push dword colen
+ push dword co
+ jmp short error
+
+align 4
+usage:
+ push dword usglen
+ push dword usg
+
+error:
+ push dword stderr
+ sys.write
+
+ push dword 1
+ sys.exit
+
+align 4
+global _start
+_start:
+ pop eax ; argc
+ pop eax ; program name
+ pop ecx ; file to convert
+ jecxz usage
+
+ pop eax
+ or eax, eax ; Too many arguments?
+ jne usage
+
+ ; Open the file
+ push dword O_RDWR
+ push ecx
+ sys.open
+ jc cantopen
+
+ mov ebp, eax ; Save fd
+
+ sub esp, byte stat_size
+ mov ebx, esp
+
+ ; Find file size
+ push ebx
+ push ebp ; fd
+ sys.fstat
+ jc facerr
+
+ mov edx, [ebx + st_size + 4]
+
+ ; File is too long if EDX != 0 ...
+ or edx, edx
+ jne near toolong
+ mov ecx, [ebx + st_size]
+ ; ... or if it is above 2 GB
+ or ecx, ecx
+ js near toolong
+
+ ; Do nothing if the file is 0 bytes in size
+ jecxz .quit
+
+ ; Map the entire file in memory
+ push edx
+ push edx ; starting at offset 0
+ push edx ; pad
+ push ebp ; fd
+ push dword MAP_SHARED
+ push dword PROT_READ | PROT_WRITE
+ push ecx ; entire file size
+ push edx ; let system decide on the address
+ sys.mmap
+ jc near memerr
+
+ mov edi, eax
+ mov esi, eax
+ push ecx ; for SYS_munmap
+ push edi
+
+ ; Use EBX for state machine
+ mov ebx, ordinary
+ mov ah, 0Ah
+ cld
+
+.loop:
+ lodsb
+ call ebx
+ loop .loop
+
+ cmp ebx, ordinary
+ je .filesize
+
+ ; Output final lf
+ mov al, ah
+ stosb
+ inc edx
+
+.filesize:
+ ; truncate file to new size
+ push dword 0 ; high dword
+ push edx ; low dword
+ push eax ; pad
+ push ebp
+ sys.ftruncate
+
+ ; close it (ebp still pushed)
+ sys.close
+
+ add esp, byte 16
+ sys.munmap
+
+.quit:
+ push dword 0
+ sys.exit
+
+align 4
+ordinary:
+ cmp al, 0Dh
+ je .cr
+
+ cmp al, ah
+ je .lf
+
+ stosb
+ inc edx
+ ret
+
+align 4
+.cr:
+ mov ebx, cr
+ ret
+
+align 4
+.lf:
+ mov ebx, lf
+ ret
+
+align 4
+cr:
+ cmp al, 0Dh
+ je .cr
+
+ cmp al, ah
+ je .lf
+
+ xchg al, ah
+ stosb
+ inc edx
+
+ xchg al, ah
+ ; fall through
+
+.lf:
+ stosb
+ inc edx
+ mov ebx, ordinary
+ ret
+
+align 4
+.cr:
+ mov al, ah
+ stosb
+ inc edx
+ ret
+
+align 4
+lf:
+ cmp al, ah
+ je .lf
+
+ cmp al, 0Dh
+ je .cr
+
+ xchg al, ah
+ stosb
+ inc edx
+
+ xchg al, ah
+ stosb
+ inc edx
+ mov ebx, ordinary
+ ret
+
+align 4
+.cr:
+ mov ebx, ordinary
+ mov al, ah
+ ; fall through
+
+.lf:
+ stosb
+ inc edx
+ ret
+</programlisting>
+
+<warning><para>
+Do not use this program on files stored on a disk formated
+by <acronym>&ms-dos;</acronym> or &windows;. There seems to be a
+subtle bug in the FreeBSD code when using <function role="syscall">mmap</function>
+on these drives mounted under FreeBSD: If the file is over
+a certain size, <function role="syscall">mmap</function> will just fill the memory
+with zeros, and then copy them to the file overwriting
+its contents.
+</para>
+</warning>
+</sect2>
+
+</sect1>
+
+<sect1 xml:id="x86-one-pointed-mind">
+<title>One-Pointed Mind</title>
+
+<para>
+As a student of Zen, I like the idea of a one-pointed mind:
+Do one thing at a time, and do it well.
+</para>
+
+<para>
+This, indeed, is very much how &unix; works as well. While
+a typical &windows; application is attempting to do everything
+imaginable (and is, therefore, riddled with bugs), a
+typical &unix; program does only one thing, and it does it
+well.
+</para>
+
+<para>
+The typical &unix; user then essentially assembles his own
+applications by writing a shell script which combines the
+various existing programs by piping the output of one
+program to the input of another.
+</para>
+
+<para>
+When writing your own &unix; software, it is generally a
+good idea to see what parts of the problem you need to
+solve can be handled by existing programs, and only
+write your own programs for that part of the problem
+that you do not have an existing solution for.
+</para>
+
+<sect2 xml:id="x86-csv"><title>CSV</title>
+
+<para>
+I will illustrate this principle with a specific real-life
+example I was faced with recently:
+</para>
+
+<para>
+I needed to extract the 11th field of each record from a
+database I downloaded from a web site. The database was a
+<acronym>CSV</acronym> file, i.e., a list of
+<emphasis>comma-separated values</emphasis>. That is quite
+a standard format for sharing data among people who may be
+using different database software.
+</para>
+
+<para>
+The first line of the file contains the list of various fields
+separated by commas. The rest of the file contains the data
+listed line by line, with values separated by commas.
+</para>
+
+<para>
+I tried <application>awk</application>, using the comma as a separator.
+But because several lines contained a quoted comma,
+<application>awk</application> was extracting the wrong field
+from those lines.
+</para>
+
+<para>
+Therefore, I needed to write my own software to extract the 11th
+field from the <acronym>CSV</acronym> file. However, going with the &unix;
+spirit, I only needed to write a simple filter that would do the
+following:
+</para>
+
+<itemizedlist>
+<listitem>
+<para>
+Remove the first line from the file;
+</para>
+</listitem>
+
+<listitem>
+<para>
+Change all unquoted commas to a different character;
+</para>
+</listitem>
+
+<listitem>
+<para>
+Remove all quotation marks.
+</para>
+</listitem>
+
+</itemizedlist>
+<para>
+Strictly speaking, I could use <application>sed</application> to remove
+the first line from the file, but doing so in my own program
+was very easy, so I decided to do it and reduce the size of
+the pipeline.
+</para>
+
+<para>
+At any rate, writing a program like this took me about
+20 minutes. Writing a program that extracts the 11th field
+from the <acronym>CSV</acronym> file would take a lot longer,
+and I could not reuse it to extract some other field from some
+other database.
+</para>
+
+<para>
+This time I decided to let it do a little more work than
+a typical tutorial program would:
+</para>
+
+<itemizedlist>
+<listitem>
+<para>
+It parses its command line for options;
+</para>
+</listitem>
+
+<listitem>
+<para>
+It displays proper usage if it finds wrong arguments;
+</para>
+</listitem>
+
+<listitem>
+<para>
+It produces meaningful error messages.
+</para>
+</listitem>
+
+</itemizedlist>
+<para>
+Here is its usage message:
+</para>
+
+<screen>Usage: csv [-t&lt;delim&gt;] [-c&lt;comma&gt;] [-p] [-o &lt;outfile&gt;] [-i &lt;infile&gt;]</screen>
+
+<para>
+All parameters are optional, and can appear in any order.
+</para>
+
+<para>
+The <parameter>-t</parameter> parameter declares what to replace
+the commas with. The <constant>tab</constant> is the default here.
+For example, <parameter>-t;</parameter> will replace all unquoted
+commas with semicolons.
+</para>
+
+<para>
+I did not need the <parameter>-c</parameter> option, but it may
+come in handy in the future. It lets me declare that I want a
+character other than a comma replaced with something else.
+For example, <parameter>-c@</parameter> will replace all at signs
+(useful if you want to split a list of email addresses
+to their user names and domains).
+</para>
+
+<para>
+The <parameter>-p</parameter> option preserves the first line, i.e.,
+it does not delete it. By default, we delete the first
+line because in a <acronym>CSV</acronym> file it contains the field
+names rather than data.
+</para>
+
+<para>
+The <parameter>-i</parameter> and <parameter>-o</parameter>
+options let me specify the input and the output files. Defaults
+are <filename>stdin</filename> and <filename>stdout</filename>,
+so this is a regular &unix; filter.
+</para>
+
+<para>
+I made sure that both <parameter>-i filename</parameter> and
+<parameter>-ifilename</parameter> are accepted. I also made
+sure that only one input and one output files may be
+specified.
+</para>
+
+<para>
+To get the 11th field of each record, I can now do:
+</para>
+
+<screen>&prompt.user; <userinput>csv '-t;' data.csv | awk '-F;' '{print $11}'</userinput></screen>
+
+<para>
+The code stores the options (except for the file descriptors)
+in <varname role="register">EDX</varname>: The comma in <varname role="register">DH</varname>, the new
+separator in <varname role="register">DL</varname>, and the flag for
+the <parameter>-p</parameter> option in the highest bit of
+<varname role="register">EDX</varname>, so a check for its sign will give us a
+quick decision what to do.
+</para>
+
+<para>
+Here is the code:
+</para>
+
+<programlisting>
+;;;;;;; csv.asm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; Convert a comma-separated file to a something-else separated file.
+;
+; Started: 31-May-2001
+; Updated: 1-Jun-2001
+;
+; Copyright (c) 2001 G. Adam Stanislav
+; All rights reserved.
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+%include 'system.inc'
+
+%define BUFSIZE 2048
+
+section .data
+fd.in dd stdin
+fd.out dd stdout
+usg db 'Usage: csv [-t&lt;delim&gt;] [-c&lt;comma&gt;] [-p] [-o &lt;outfile&gt;] [-i &lt;infile&gt;]', 0Ah
+usglen equ $-usg
+iemsg db "csv: Can't open input file", 0Ah
+iemlen equ $-iemsg
+oemsg db "csv: Can't create output file", 0Ah
+oemlen equ $-oemsg
+
+section .bss
+ibuffer resb BUFSIZE
+obuffer resb BUFSIZE
+
+section .text
+align 4
+ierr:
+ push dword iemlen
+ push dword iemsg
+ push dword stderr
+ sys.write
+ push dword 1 ; return failure
+ sys.exit
+
+align 4
+oerr:
+ push dword oemlen
+ push dword oemsg
+ push dword stderr
+ sys.write
+ push dword 2
+ sys.exit
+
+align 4
+usage:
+ push dword usglen
+ push dword usg
+ push dword stderr
+ sys.write
+ push dword 3
+ sys.exit
+
+align 4
+global _start
+_start:
+ add esp, byte 8 ; discard argc and argv[0]
+ mov edx, (',' &lt;&lt; 8) | 9
+
+.arg:
+ pop ecx
+ or ecx, ecx
+ je near .init ; no more arguments
+
+ ; ECX contains the pointer to an argument
+ cmp byte [ecx], '-'
+ jne usage
+
+ inc ecx
+ mov ax, [ecx]
+
+.o:
+ cmp al, 'o'
+ jne .i
+
+ ; Make sure we are not asked for the output file twice
+ cmp dword [fd.out], stdout
+ jne usage
+
+ ; Find the path to output file - it is either at [ECX+1],
+ ; i.e., -ofile --
+ ; or in the next argument,
+ ; i.e., -o file
+
+ inc ecx
+ or ah, ah
+ jne .openoutput
+ pop ecx
+ jecxz usage
+
+.openoutput:
+ push dword 420 ; file mode (644 octal)
+ push dword 0200h | 0400h | 01h
+ ; O_CREAT | O_TRUNC | O_WRONLY
+ push ecx
+ sys.open
+ jc near oerr
+
+ add esp, byte 12
+ mov [fd.out], eax
+ jmp short .arg
+
+.i:
+ cmp al, 'i'
+ jne .p
+
+ ; Make sure we are not asked twice
+ cmp dword [fd.in], stdin
+ jne near usage
+
+ ; Find the path to the input file
+ inc ecx
+ or ah, ah
+ jne .openinput
+ pop ecx
+ or ecx, ecx
+ je near usage
+
+.openinput:
+ push dword 0 ; O_RDONLY
+ push ecx
+ sys.open
+ jc near ierr ; open failed
+
+ add esp, byte 8
+ mov [fd.in], eax
+ jmp .arg
+
+.p:
+ cmp al, 'p'
+ jne .t
+ or ah, ah
+ jne near usage
+ or edx, 1 &lt;&lt; 31
+ jmp .arg
+
+.t:
+ cmp al, 't' ; redefine output delimiter
+ jne .c
+ or ah, ah
+ je near usage
+ mov dl, ah
+ jmp .arg
+
+.c:
+ cmp al, 'c'
+ jne near usage
+ or ah, ah
+ je near usage
+ mov dh, ah
+ jmp .arg
+
+align 4
+.init:
+ sub eax, eax
+ sub ebx, ebx
+ sub ecx, ecx
+ mov edi, obuffer
+
+ ; See if we are to preserve the first line
+ or edx, edx
+ js .loop
+
+.firstline:
+ ; get rid of the first line
+ call getchar
+ cmp al, 0Ah
+ jne .firstline
+
+.loop:
+ ; read a byte from stdin
+ call getchar
+
+ ; is it a comma (or whatever the user asked for)?
+ cmp al, dh
+ jne .quote
+
+ ; Replace the comma with a tab (or whatever the user wants)
+ mov al, dl
+
+.put:
+ call putchar
+ jmp short .loop
+
+.quote:
+ cmp al, '"'
+ jne .put
+
+ ; Print everything until you get another quote or EOL. If it
+ ; is a quote, skip it. If it is EOL, print it.
+.qloop:
+ call getchar
+ cmp al, '"'
+ je .loop
+
+ cmp al, 0Ah
+ je .put
+
+ call putchar
+ jmp short .qloop
+
+align 4
+getchar:
+ or ebx, ebx
+ jne .fetch
+
+ call read
+
+.fetch:
+ lodsb
+ dec ebx
+ ret
+
+read:
+ jecxz .read
+ call write
+
+.read:
+ push dword BUFSIZE
+ mov esi, ibuffer
+ push esi
+ push dword [fd.in]
+ sys.read
+ add esp, byte 12
+ mov ebx, eax
+ or eax, eax
+ je .done
+ sub eax, eax
+ ret
+
+align 4
+.done:
+ call write ; flush output buffer
+
+ ; close files
+ push dword [fd.in]
+ sys.close
+
+ push dword [fd.out]
+ sys.close
+
+ ; return success
+ push dword 0
+ sys.exit
+
+align 4
+putchar:
+ stosb
+ inc ecx
+ cmp ecx, BUFSIZE
+ je write
+ ret
+
+align 4
+write:
+ jecxz .ret ; nothing to write
+ sub edi, ecx ; start of buffer
+ push ecx
+ push edi
+ push dword [fd.out]
+ sys.write
+ add esp, byte 12
+ sub eax, eax
+ sub ecx, ecx ; buffer is empty now
+.ret:
+ ret
+</programlisting>
+
+<para>
+Much of it is taken from <filename>hex.asm</filename> above. But there
+is one important difference: I no longer call <function>write</function>
+whenever I am outputting a line feed. Yet, the code can be
+used interactively.
+</para>
+
+<para>
+I have found a better solution for the interactive problem
+since I first started writing this chapter. I wanted to
+make sure each line is printed out separately only when needed.
+After all, there is no need to flush out every line when used
+non-interactively.
+</para>
+
+<para>
+The new solution I use now is to call <function>write</function> every
+time I find the input buffer empty. That way, when running in
+the interactive mode, the program reads one line from the user's
+keyboard, processes it, and sees its input buffer is empty. It
+flushes its output and reads the next line.
+</para>
+
+<sect3 xml:id="x86-buffered-dark-side">
+<title>The Dark Side of Buffering</title>
+<para>
+This change prevents a mysterious lockup
+in a very specific case. I refer to it as the
+<emphasis>dark side of buffering</emphasis>, mostly
+because it presents a danger that is not
+quite obvious.
+</para>
+
+<para>
+It is unlikely to happen with a program like the
+<application>csv</application> above, so let us consider yet
+another filter: In this case we expect our input
+to be raw data representing color values, such as
+the <emphasis>red</emphasis>, <emphasis>green</emphasis>, and
+<emphasis>blue</emphasis> intensities of a pixel. Our
+output will be the negative of our input.
+</para>
+
+<para>
+Such a filter would be very simple to write.
+Most of it would look just like all the other
+filters we have written so far, so I am only
+going to show you its inner loop:
+</para>
+
+<programlisting>
+.loop:
+ call getchar
+ not al ; Create a negative
+ call putchar
+ jmp short .loop
+</programlisting>
+<para>
+Because this filter works with raw data,
+it is unlikely to be used interactively.
+</para>
+
+<para>
+But it could be called by image manipulation software.
+And, unless it calls <function>write</function> before each call
+to <function>read</function>, chances are it will lock up.
+</para>
+
+<para>
+Here is what might happen:
+</para>
+
+<procedure><step><para>
+The image editor will load our filter using the
+C function <function>popen()</function>.
+</para>
+</step>
+<step><para>
+It will read the first row of pixels from
+a bitmap or pixmap.
+</para>
+</step>
+<step><para>
+It will write the first row of pixels to
+the <emphasis>pipe</emphasis> leading to
+the <varname>fd.in</varname> of our filter.
+</para>
+</step>
+<step><para>
+Our filter will read each pixel
+from its input, turn it to a negative,
+and write it to its output buffer.
+</para>
+</step>
+<step><para>
+Our filter will call <function>getchar</function>
+to fetch the next pixel.
+</para>
+</step>
+<step><para>
+<function>getchar</function> will find an empty
+input buffer, so it will call
+<function>read</function>.
+</para>
+</step>
+<step><para>
+<function>read</function> will call the
+<function role="syscall">SYS_read</function> system call.
+</para>
+</step>
+<step><para>
+The <emphasis>kernel</emphasis> will suspend
+our filter until the image editor
+sends more data to the pipe.
+</para>
+</step>
+<step><para>
+The image editor will read from the
+other pipe, connected to the
+<varname>fd.out</varname> of our filter so it can set the first row of the
+output image <emphasis>before</emphasis>
+it sends us the second row of the input.
+</para>
+</step>
+<step><para>
+The <emphasis>kernel</emphasis> suspends
+the image editor until it receives
+some output from our filter, so it
+can pass it on to the image editor.
+</para>
+</step>
+</procedure>
+<para>
+At this point our filter waits for the image
+editor to send it more data to process, while
+the image editor is waiting for our filter
+to send it the result of the processing
+of the first row. But the result sits in
+our output buffer.
+</para>
+
+<para>
+The filter and the image editor will continue
+waiting for each other forever (or, at least,
+until they are killed). Our software has just
+entered a
+<link linkend="secure-race-conditions">race condition</link>.
+</para>
+
+<para>
+This problem does not exist if our filter flushes
+its output buffer <emphasis>before</emphasis> asking the
+<emphasis>kernel</emphasis> for more input data.
+</para>
+
+</sect3>
+
+</sect2>
+
+</sect1>
+
+<sect1 xml:id="x86-fpu">
+<title>Using the <acronym>FPU</acronym></title>
+<para>
+Strangely enough, most of assembly language literature does not
+even mention the existence of the <acronym>FPU</acronym>,
+or <emphasis>floating point unit</emphasis>, let alone discuss
+programming it.
+</para>
+
+<para>
+Yet, never does assembly language shine more than when
+we create highly optimized <acronym>FPU</acronym>
+code by doing things that can be done <emphasis>only</emphasis> in assembly language.</para>
+
+<sect2 xml:id="x86-fpu-organization"><title>Organization of the <acronym>FPU</acronym></title>
+<para>
+The <acronym>FPU</acronym> consists of 8 80&ndash;bit floating&ndash;point registers.
+These are organized in a stack fashion&mdash;you can
+<function>push</function> a value on <acronym>TOS</acronym>
+(<emphasis>top of stack</emphasis>) and you can
+<function>pop</function> it.
+</para>
+
+<para>
+That said, the assembly language op codes are not <function role="opcode">push</function>
+and <function role="opcode">pop</function> because those are already taken.</para>
+
+<para>
+You can <function>push</function> a value on <acronym>TOS</acronym>
+by using <function role="opcode">fld</function>, <function role="opcode">fild</function>,
+and <function role="opcode">fbld</function>. Several other op codes
+let you <function>push</function> many common
+<emphasis>constants</emphasis>&mdash;such as <emphasis>pi</emphasis>&mdash;on
+the <acronym>TOS</acronym>.
+</para>
+
+<para>
+Similarly, you can <function>pop</function> a value by
+using <function role="opcode">fst</function>, <function role="opcode">fstp</function>,
+<function role="opcode">fist</function>, <function role="opcode">fistp</function>, and
+<function role="opcode">fbstp</function>. Actually, only the op
+codes that end with a <emphasis>p</emphasis> will
+literally <function>pop</function> the value,
+the rest will <function>store</function> it
+somewhere else without removing it from
+the <acronym>TOS</acronym>.
+</para>
+
+<para>
+We can transfer the data between the
+<acronym>TOS</acronym> and the computer memory either as
+a 32&ndash;bit, 64&ndash;bit, or 80&ndash;bit <emphasis>real</emphasis>,
+a 16&ndash;bit, 32&ndash;bit, or 64&ndash;bit <emphasis>integer</emphasis>,
+or an 80&ndash;bit <emphasis>packed decimal</emphasis>.
+</para>
+
+<para>
+The 80&ndash;bit <emphasis>packed decimal</emphasis> is
+a special case of <emphasis>binary coded
+decimal</emphasis> which is very convenient when
+converting between the <acronym>ASCII</acronym>
+representation of data and the internal
+data of the <acronym>FPU</acronym>. It allows us to use
+18 significant digits.
+</para>
+
+<para>
+No matter how we represent data in the memory,
+the <acronym>FPU</acronym> always stores it in the 80&ndash;bit
+<emphasis>real</emphasis> format in its registers.
+</para>
+
+<para>
+Its internal precision is at least 19 decimal
+digits, so even if we choose to display results
+as <acronym>ASCII</acronym> in the full
+18&ndash;digit precision, we are still showing
+correct results.
+</para>
+
+<para>
+We can perform mathematical operations on the
+<acronym>TOS</acronym>: We can calculate its
+<emphasis>sine</emphasis>, we can <emphasis>scale</emphasis> it
+(i.e., we can multiply or divide it by a power
+of 2), we can calculate its base&ndash;2
+<emphasis>logarithm</emphasis>, and many other things.
+</para>
+
+<para>
+We can also <emphasis>multiply</emphasis> or
+<emphasis>divide</emphasis> it by, <emphasis>add</emphasis>
+it to, or <emphasis>subtract</emphasis> it from,
+any of the <acronym>FPU</acronym> registers (including
+itself).
+</para>
+
+<para>
+The official Intel op code for the
+<acronym>TOS</acronym> is <varname role="register">st</varname>, and
+for the <emphasis>registers</emphasis>
+<varname role="register">st(0)</varname>&ndash;<varname role="register">st(7)</varname>.
+<varname role="register">st</varname> and <varname role="register">st(0)</varname>, then,
+refer to the same register.
+</para>
+
+<para>
+For whatever reasons, the original author of
+<application>nasm</application> has decided to use
+different op codes, namely
+<varname role="register">st0</varname>&ndash;<varname role="register">st7</varname>.
+In other words, there are no parentheses,
+and the <acronym>TOS</acronym> is always
+<varname role="register">st0</varname>, never just <function role="opcode">st</function>.
+</para>
+
+<sect3 xml:id="x86-fpu-packed-decimal">
+<title>The Packed Decimal Format</title>
+<para>
+The <emphasis>packed decimal</emphasis> format
+uses 10 bytes (80 bits) of
+memory to represent 18 digits. The
+number represented there is always an
+<emphasis>integer</emphasis>.
+</para>
+
+<tip>
+<para>
+You can use it to get decimal places
+by multiplying the <acronym>TOS</acronym>
+by a power of 10 first.
+</para>
+</tip>
+
+<para>
+The highest bit of the highest byte
+(byte 9) is the <emphasis>sign bit</emphasis>:
+If it is set, the number is <emphasis>negative</emphasis>,
+otherwise, it is <emphasis>positive</emphasis>.
+The rest of the bits of this byte are unused/ignored.
+</para>
+
+<para>
+The remaining 9 bytes store the 18 digits
+of the number: 2 digits per byte.</para>
+
+<para>
+The <emphasis>more significant digit</emphasis> is
+stored in the high <emphasis>nibble</emphasis>
+(4 bits), the <emphasis>less significant
+digit</emphasis> in the low <emphasis>nibble</emphasis>.
+</para>
+
+<para>
+That said, you might think that <constant>-1234567</constant>
+would be stored in the memory like this (using
+hexadecimal notation):
+</para>
+
+<programlisting>
+80 00 00 00 00 00 01 23 45 67
+</programlisting>
+<para>
+Alas it is not! As with everything else of Intel make,
+even the <emphasis>packed decimal</emphasis> is
+<emphasis>little&ndash;endian</emphasis>.</para>
+
+<para>
+That means our <constant>-1234567</constant>
+is stored like this:
+</para>
+
+<programlisting>
+67 45 23 01 00 00 00 00 00 80
+</programlisting>
+<para>
+Remember that, or you will be pulling your hair out
+in desperation!
+</para>
+
+<note>
+<para>
+The book to read&mdash;if you can find it&mdash;is Richard Startz'
+<link xlink:href="http://www.int80h.org/cgi-bin/isbn?isbn=013246604X">8087/80287/80387
+for the IBM PC &amp; Compatibles</link>.
+Though it does seem to take the fact about the
+little&ndash;endian storage of the <emphasis>packed
+decimal</emphasis> for granted. I kid you not about the
+desperation of trying to figure out what was wrong
+with the filter I show below <emphasis>before</emphasis>
+it occurred to me I should try the
+little&ndash;endian order even for this type of data.
+</para>
+</note>
+
+</sect3>
+
+</sect2>
+
+<sect2 xml:id="x86-pinhole-photography">
+<title>Excursion to Pinhole Photography</title>
+<para>
+To write meaningful software, we must not only
+understand our programming tools, but also the
+field we are creating software for.
+</para>
+
+<para>
+Our next filter will help us whenever we want
+to build a <emphasis>pinhole camera</emphasis>,
+so, we need some background in <emphasis>pinhole
+photography</emphasis> before we can continue.
+</para>
+
+<sect3 xml:id="x86-camera">
+<title>The Camera</title>
+<para>
+The easiest way to describe any camera ever built
+is as some empty space enclosed in some
+lightproof material, with a small hole in the
+enclosure.
+</para>
+
+<para>
+The enclosure is usually sturdy (e.g., a box),
+though sometimes it is flexible (the bellows).
+It is quite dark inside the camera. However, the
+hole lets light rays in through a single point
+(though in some cases there may be several).
+These light rays form an image, a representation
+of whatever is outside the camera, in front of the
+hole.
+</para>
+
+<para>
+If some light sensitive material (such as film)
+is placed inside the camera, it can capture the
+image.</para>
+
+<para>
+The hole often contains a <emphasis>lens</emphasis>, or
+a lens assembly, often called the <emphasis>objective</emphasis>.
+</para>
+
+</sect3>
+
+<sect3 xml:id="x86-the-pinhole">
+<title>The Pinhole</title>
+<para>
+But, strictly speaking, the lens is not necessary:
+The original cameras did not use a lens but a
+<emphasis>pinhole</emphasis>. Even today, <emphasis>pinholes</emphasis>
+are used, both as a tool to study how cameras
+work, and to achieve a special kind of image.
+</para>
+
+<para>
+The image produced by the <emphasis>pinhole</emphasis>
+is all equally sharp. Or <emphasis>blurred</emphasis>.
+There is an ideal size for a pinhole: If it is
+either larger or smaller, the image loses its
+sharpness.</para>
+
+</sect3>
+
+<sect3 xml:id="x86-focal-length">
+<title>Focal Length</title>
+<para>
+This ideal pinhole diameter is a function
+of the square root of <emphasis>focal
+length</emphasis>, which is the distance of the
+pinhole from the film.
+</para>
+
+<programlisting>
+ D = PC * sqrt(FL)
+</programlisting>
+<para>
+In here, <varname>D</varname> is the
+ideal diameter of the pinhole,
+<varname>FL</varname> is the focal length,
+and <constant>PC</constant> is a pinhole
+constant. According to Jay Bender,
+its value is <constant>0.04</constant>, while
+Kenneth Connors has determined it to
+be <constant>0.037</constant>. Others have
+proposed other values. Plus, this
+value is for the daylight only: Other types
+of light will require a different constant,
+whose value can only be determined by
+experimentation.
+</para>
+
+</sect3>
+
+<sect3 xml:id="x86-f-number">
+<title>The F&ndash;Number</title>
+<para>
+The f&ndash;number is a very useful measure of
+how much light reaches the film. A light
+meter can determine that, for example,
+to expose a film of specific sensitivity
+with f5.6 may require the exposure to last
+1/1000 sec.</para>
+
+<para>
+It does not matter whether it is a 35&ndash;mm
+camera, or a 6x9cm camera, etc.
+As long as we know the f&ndash;number, we can determine
+the proper exposure.
+</para>
+
+<para>
+The f&ndash;number is easy to calculate:
+</para>
+
+<programlisting>
+ F = FL / D
+</programlisting>
+<para>
+In other words, the f&ndash;number equals the focal
+length divided by the diameter of the pinhole.
+It also means a higher f&ndash;number either implies
+a smaller pinhole or a larger focal distance,
+or both. That, in turn, implies, the higher
+the f&ndash;number, the longer the exposure has to be.
+</para>
+
+<para>
+Furthermore, while pinhole diameter and focal
+distance are one&ndash;dimensional measurements,
+both, the film and the pinhole, are two&ndash;dimensional.
+That means that
+if you have measured the exposure at f&ndash;number
+<varname>A</varname> as <varname>t</varname>, then the exposure
+at f&ndash;number <varname>B</varname> is:</para>
+
+<programlisting>
+ t * (B / A)&#178;
+</programlisting>
+</sect3>
+
+<sect3 xml:id="x86-normalized-f-number">
+<title>Normalized F&ndash;Number</title>
+<para>
+While many modern cameras can change the diameter
+of their pinhole, and thus their f&ndash;number, quite
+smoothly and gradually, such was not always the case.
+</para>
+
+<para>
+To allow for different f&ndash;numbers, cameras typically
+contained a metal plate with several holes of
+different sizes drilled to them.
+</para>
+
+<para>
+Their sizes were chosen according to the above
+formula in such a way that the resultant f&ndash;number
+was one of standard f&ndash;numbers used on all cameras
+everywhere. For example, a very old Kodak Duaflex IV
+camera in my possession has three such holes for
+f&ndash;numbers 8, 11, and 16.
+</para>
+
+<para>
+A more recently made camera may offer f&ndash;numbers of
+2.8, 4, 5.6, 8, 11,
+16, 22, and 32 (as well as others).
+These numbers were not chosen arbitrarily: They all are
+powers of the square root of 2, though they may
+be rounded somewhat.
+</para>
+
+</sect3>
+
+<sect3 xml:id="x86-f-stop">
+<title>The F&ndash;Stop</title>
+<para>
+A typical camera is designed in such a way that setting
+any of the normalized f&ndash;numbers changes the feel of the
+dial. It will naturally <emphasis>stop</emphasis> in that
+position. Because of that, these positions of the dial
+are called f&ndash;stops.</para>
+
+<para>
+Since the f&ndash;numbers at each stop are powers of the
+square root of 2, moving the dial by 1
+stop will double the amount of light required for
+proper exposure. Moving it by 2 stops will
+quadruple the required exposure. Moving the dial by
+3 stops will require the increase in exposure
+8 times, etc.
+</para>
+
+</sect3>
+
+</sect2>
+
+<sect2 xml:id="x86-pinhole-software">
+<title>Designing the Pinhole Software</title>
+<para>
+We are now ready to decide what exactly we want our
+pinhole software to do.
+</para>
+
+<sect3 xml:id="xpinhole-processing-input">
+<title>Processing Program Input</title>
+<para>
+Since its main purpose is to help us design a working
+pinhole camera, we will use the <emphasis>focal
+length</emphasis> as the input to the program. This is something
+we can determine without software: Proper focal length
+is determined by the size of the film and by the need
+to shoot "regular" pictures, wide angle pictures, or
+telephoto pictures.
+</para>
+
+<para>
+Most of the programs we have written so far worked with
+individual characters, or bytes, as their input: The
+<application>hex</application> program converted individual bytes
+into a hexadecimal number, the <application>csv</application>
+program either let a character through, or deleted it,
+or changed it to a different character, etc.
+</para>
+
+<para>
+One program, <application>ftuc</application> used the state machine
+to consider at most two input bytes at a time.
+</para>
+
+<para>
+But our <application>pinhole</application> program cannot just
+work with individual characters, it has to deal with
+larger syntactic units.
+</para>
+
+<para>
+For example, if we want the program to calculate the
+pinhole diameter (and other values we will discuss
+later) at the focal lengths of <constant>100 mm</constant>,
+<constant>150 mm</constant>, and <constant>210 mm</constant>, we may want
+to enter something like this:</para>
+
+<screen><userinput>100, 150, 210</userinput></screen>
+<para>
+Our program needs to consider more than a single byte of
+input at a time. When it sees the first <constant>1</constant>,
+it must understand it is seeing the first digit of a
+decimal number. When it sees the <constant>0</constant> and
+the other <constant>0</constant>, it must know it is seeing
+more digits of the same number.
+</para>
+
+<para>
+When it encounters the first comma, it must know it is
+no longer receiving the digits of the first number.
+It must be able to convert the digits of the first number
+into the value of <constant>100</constant>. And the digits of the
+second number into the value of <constant>150</constant>. And,
+of course, the digits of the third number into the
+numeric value of <constant>210</constant>.
+</para>
+
+<para>
+We need to decide what delimiters to accept: Do the
+input numbers have to be separated by a comma? If so,
+how do we treat two numbers separated by something else?
+</para>
+
+<para>
+Personally, I like to keep it simple. Something either
+is a number, so I process it. Or it is not a number,
+so I discard it. I do not like the computer complaining
+about me typing in an extra character when it is
+<emphasis>obvious</emphasis> that it is an extra character. Duh!
+</para>
+
+<para>
+Plus, it allows me to break up the monotony of computing
+and type in a query instead of just a number:
+</para>
+
+<screen><userinput>What is the best pinhole diameter for the focal length of 150?</userinput></screen>
+<para>
+There is no reason for the computer to spit out
+a number of complaints:
+</para>
+
+<screen>Syntax error: What
+Syntax error: is
+Syntax error: the
+Syntax error: best</screen>
+<para>
+Et cetera, et cetera, et cetera.</para>
+
+<para>
+Secondly, I like the <constant>#</constant> character to denote
+the start of a comment which extends to the end of the
+line. This does not take too much effort to code, and
+lets me treat input files for my software as executable
+scripts.
+</para>
+
+<para>
+In our case, we also need to decide what units the
+input should come in: We choose <emphasis>millimeters</emphasis>
+because that is how most photographers measure
+the focus length.
+</para>
+
+<para>
+Finally, we need to decide whether to allow the use
+of the decimal point (in which case we must also
+consider the fact that much of the world uses a
+decimal <emphasis>comma</emphasis>).</para>
+
+<para>
+In our case allowing for the decimal point/comma
+would offer a false sense of precision: There is
+little if any noticeable difference between the
+focus lengths of <constant>50</constant> and <constant>51</constant>,
+so allowing the user to input something like
+<constant>50.5</constant> is not a good idea. This is
+my opinion, mind you, but I am the one writing
+this program. You can make other choices in yours,
+of course.
+</para>
+
+</sect3>
+
+<sect3 xml:id="x86-pinhole-options">
+<title>Offering Options</title>
+<para>
+The most important thing we need to know when building
+a pinhole camera is the diameter of the pinhole. Since
+we want to shoot sharp images, we will use the above
+formula to calculate the pinhole diameter from focal length.
+As experts are offering several different values for the
+<constant>PC</constant> constant, we will need to have the choice.
+</para>
+
+<para>
+It is traditional in &unix; programming to have two main ways
+of choosing program parameters, plus to have a default for
+the time the user does not make a choice.
+</para>
+
+<para>
+Why have two ways of choosing?</para>
+
+<para>
+One is to allow a (relatively) <emphasis>permanent</emphasis>
+choice that applies automatically each time the
+software is run without us having to tell it over and
+over what we want it to do.
+</para>
+
+<para>
+The permanent choices may be stored in a configuration
+file, typically found in the user's home directory.
+The file usually has the same name as the application
+but is started with a dot. Often <emphasis>"rc"</emphasis>
+is added to the file name. So, ours could be
+<filename>~/.pinhole</filename> or <filename>~/.pinholerc</filename>.
+(The <filename>~/</filename> means current user's
+home directory.)
+</para>
+
+<para>
+The configuration file is used mostly by programs
+that have many configurable parameters. Those
+that have only one (or a few) often use a different
+method: They expect to find the parameter in an
+<emphasis>environment variable</emphasis>. In our case,
+we might look at an environment variable named
+<varname>PINHOLE</varname>.
+</para>
+
+<para>
+Usually, a program uses one or the other of the
+above methods. Otherwise, if a configuration
+file said one thing, but an environment variable
+another, the program might get confused (or just
+too complicated).
+</para>
+
+<para>
+Because we only need to choose <emphasis>one</emphasis>
+such parameter, we will go with the second method
+and search the environment for a variable named
+<varname>PINHOLE</varname>.</para>
+
+<para>
+The other way allows us to make <emphasis>ad hoc</emphasis>
+decisions: <emphasis>"Though I usually want
+you to use 0.039, this time I want 0.03872."</emphasis>
+In other words, it allows us to <emphasis>override</emphasis>
+the permanent choice.
+</para>
+
+<para>
+This type of choice is usually done with command
+line parameters.
+</para>
+
+<para>
+Finally, a program <emphasis>always</emphasis> needs a
+<emphasis>default</emphasis>. The user may not make
+any choices. Perhaps he does not know what
+to choose. Perhaps he is "just browsing."
+Preferably, the default will be the value
+most users would choose anyway. That way
+they do not need to choose. Or, rather, they
+can choose the default without an additional
+effort.
+</para>
+
+<para>
+Given this system, the program may find conflicting
+options, and handle them this way:
+</para>
+
+<procedure><step><para>
+If it finds an <emphasis>ad hoc</emphasis> choice
+(e.g., command line parameter), it should
+accept that choice. It must ignore any permanent
+choice and any default.
+</para>
+</step>
+<step><para>
+<emphasis>Otherwise</emphasis>, if it finds
+a permanent option (e.g., an environment
+variable), it should accept it, and ignore
+the default.</para>
+</step>
+<step><para>
+<emphasis>Otherwise</emphasis>, it should use
+the default.
+</para>
+</step>
+</procedure>
+<para>
+We also need to decide what <emphasis>format</emphasis>
+our <constant>PC</constant> option should have.
+</para>
+
+<para>
+At first site, it seems obvious to use the
+<varname>PINHOLE=0.04</varname> format for the
+environment variable, and <parameter>-p0.04</parameter>
+for the command line.
+</para>
+
+<para>
+Allowing that is actually a security risk.
+The <constant>PC</constant> constant is a very small
+number. Naturally, we will test our software
+using various small values of <constant>PC</constant>.
+But what will happen if someone runs the program
+choosing a huge value?
+</para>
+
+<para>
+It may crash the program because we have not
+designed it to handle huge numbers.
+</para>
+
+<para>
+Or, we may spend more time on the program so
+it can handle huge numbers. We might do that
+if we were writing commercial software for
+computer illiterate audience.
+</para>
+
+<para>
+Or, we might say, <emphasis>"Tough!
+The user should know better.""</emphasis>
+</para>
+
+<para>
+Or, we just may make it impossible for the user
+to enter a huge number. This is the approach we
+will take: We will use an <emphasis>implied 0.</emphasis>
+prefix.
+</para>
+
+<para>
+In other words, if the user wants <constant>0.04</constant>,
+we will expect him to type <parameter>-p04</parameter>,
+or set <varname>PINHOLE=04</varname> in his environment.
+So, if he says <parameter>-p9999999</parameter>, we will
+interpret it as <constant>0.9999999</constant>&mdash;still
+ridiculous but at least safer.
+</para>
+
+<para>
+Secondly, many users will just want to go with either
+Bender's constant or Connors' constant.
+To make it easier on them, we will interpret
+<parameter>-b</parameter> as identical to <parameter>-p04</parameter>,
+and <parameter>-c</parameter> as identical to <parameter>-p037</parameter>.
+</para>
+
+</sect3>
+
+<sect3 xml:id="x86-pinhole-output">
+<title>The Output</title>
+<para>
+We need to decide what we want our software to
+send to the output, and in what format.
+</para>
+
+<para>
+Since our input allows for an unspecified number
+of focal length entries, it makes sense to use
+a traditional database&ndash;style output of showing
+the result of the calculation for each
+focal length on a separate line, while
+separating all values on one line by a
+<constant>tab</constant> character.
+</para>
+
+<para>
+Optionally, we should also allow the user
+to specify the use of the <acronym>CSV</acronym>
+format we have studied earlier. In this case,
+we will print out a line of comma&ndash;separated
+names describing each field of every line,
+then show our results as before, but substituting
+a <constant>comma</constant> for the <constant>tab</constant>.</para>
+
+<para>
+We need a command line option for the <acronym>CSV</acronym>
+format. We cannot use <parameter>-c</parameter> because
+that already means <emphasis>use Connors' constant</emphasis>.
+For some strange reason, many web sites refer to
+<acronym>CSV</acronym> files as <emphasis>"Excel
+spreadsheet"</emphasis> (though the <acronym>CSV</acronym>
+format predates Excel). We will, therefore, use
+the <parameter>-e</parameter> switch to inform our software
+we want the output in the <acronym>CSV</acronym> format.
+</para>
+
+<para>
+We will start each line of the output with the
+focal length. This may sound repetitious at first,
+especially in the interactive mode: The user
+types in the focal length, and we are repeating it.
+</para>
+
+<para>
+But the user can type several focal lengths on one
+line. The input can also come in from a file or
+from the output of another program. In that case
+the user does not see the input at all.
+</para>
+
+<para>
+By the same token, the output can go to a file
+which we will want to examine later, or it could
+go to the printer, or become the input of another
+program.
+</para>
+
+<para>
+So, it makes perfect sense to start each line with
+the focal length as entered by the user.
+</para>
+
+<para>
+No, wait! Not as entered by the user. What if the user
+types in something like this:</para>
+
+<screen><userinput>00000000150</userinput></screen>
+<para>
+Clearly, we need to strip those leading zeros.</para>
+
+<para>
+So, we might consider reading the user input as is,
+converting it to binary inside the <acronym>FPU</acronym>,
+and printing it out from there.
+</para>
+
+<para>
+But...</para>
+
+<para>
+What if the user types something like this:
+</para>
+
+<screen><userinput>17459765723452353453534535353530530534563507309676764423</userinput></screen>
+<para>
+Ha! The packed decimal <acronym>FPU</acronym> format
+lets us input 18&ndash;digit numbers. But the
+user has entered more than 18 digits. How
+do we handle that?
+</para>
+
+<para>
+Well, we <emphasis>could</emphasis> modify our code to read
+the first 18 digits, enter it to the <acronym>FPU</acronym>,
+then read more, multiply what we already have on the
+<acronym>TOS</acronym> by 10 raised to the number
+of additional digits, then <function>add</function> to it.
+</para>
+
+<para>
+Yes, we could do that. But in <emphasis>this</emphasis>
+program it would be ridiculous (in a different one it may be just the thing to do): Even the circumference of the Earth expressed in
+millimeters only takes 11 digits. Clearly,
+we cannot build a camera that large (not yet,
+anyway).
+</para>
+
+<para>
+So, if the user enters such a huge number, he is
+either bored, or testing us, or trying to break
+into the system, or playing games&mdash;doing
+anything but designing a pinhole camera.
+</para>
+
+<para>
+What will we do?</para>
+
+<para>
+We will slap him in the face, in a manner of speaking:</para>
+
+<screen>17459765723452353453534535353530530534563507309676764423 ??? ??? ??? ??? ???</screen>
+<para>
+To achieve that, we will simply ignore any leading zeros.
+Once we find a non&ndash;zero digit, we will initialize a
+counter to <constant>0</constant> and start taking three steps:
+</para>
+
+<procedure>
+<step><para>
+Send the digit to the output.
+</para>
+</step>
+<step><para>
+Append the digit to a buffer we will use later to
+produce the packed decimal we can send to the
+<acronym>FPU</acronym>.
+</para>
+</step>
+<step><para>
+Increase the counter.
+</para>
+</step>
+</procedure>
+<para>
+Now, while we are taking these three steps,
+we also need to watch out for one of two
+conditions:</para>
+
+<itemizedlist>
+<listitem>
+<para>
+If the counter grows above 18,
+we stop appending to the buffer. We
+continue reading the digits and sending
+them to the output.
+</para>
+</listitem>
+
+<listitem>
+<para>
+If, or rather <emphasis>when</emphasis>,
+the next input character is not
+a digit, we are done inputting
+for now.
+</para>
+
+<para>
+Incidentally, we can simply
+discard the non&ndash;digit, unless it
+is a <constant>#</constant>, which we must
+return to the input stream. It
+starts a comment, so we must see it
+after we are done producing output
+and start looking for more input.
+</para>
+</listitem>
+
+</itemizedlist>
+<para>
+That still leaves one possibility
+uncovered: If all the user enters
+is a zero (or several zeros), we
+will never find a non&ndash;zero to
+display.</para>
+
+<para>
+We can determine this has happened
+whenever our counter stays at <constant>0</constant>.
+In that case we need to send <constant>0</constant>
+to the output, and perform another
+"slap in the face":
+</para>
+
+<screen>0 ??? ??? ??? ??? ???</screen>
+<para>
+Once we have displayed the focal
+length and determined it is valid
+(greater than <constant>0</constant>
+but not exceeding 18 digits),
+we can calculate the pinhole diameter.
+</para>
+
+<para>
+It is not by coincidence that <emphasis>pinhole</emphasis>
+contains the word <emphasis>pin</emphasis>. Indeed,
+many a pinhole literally is a <emphasis>pin
+hole</emphasis>, a hole carefully punched with the
+tip of a pin.
+</para>
+
+<para>
+That is because a typical pinhole is very
+small. Our formula gets the result in
+millimeters. We will multiply it by <constant>1000</constant>,
+so we can output the result in <emphasis>microns</emphasis>.
+</para>
+
+<para>
+At this point we have yet another trap to face:
+<emphasis>Too much precision.</emphasis>
+</para>
+
+<para>
+Yes, the <acronym>FPU</acronym> was designed
+for high precision mathematics. But we
+are not dealing with high precision
+mathematics. We are dealing with physics
+(optics, specifically).
+</para>
+
+<para>
+Suppose we want to convert a truck into
+a pinhole camera (we would not be the
+first ones to do that!). Suppose its box is
+<constant>12</constant>
+meters long, so we have the focal length
+of <constant>12000</constant>. Well, using Bender's constant, it gives us square root of
+<constant>12000</constant> multiplied by <constant>0.04</constant>,
+which is <constant>4.381780460</constant> millimeters,
+or <constant>4381.780460</constant> microns.
+</para>
+
+<para>
+Put either way, the result is absurdly precise.
+Our truck is not <emphasis>exactly</emphasis> <constant>12000</constant>
+millimeters long. We did not measure its length
+with such a precision, so stating we need a pinhole
+with the diameter of <constant>4.381780460</constant>
+millimeters is, well, deceiving. <constant>4.4</constant>
+millimeters would do just fine.
+</para>
+
+<note>
+<para>
+I "only" used ten digits in the above example.
+Imagine the absurdity of going for all 18!
+</para>
+</note>
+
+<para>
+We need to limit the number of significant
+digits of our result. One way of doing it
+is by using an integer representing microns.
+So, our truck would need a pinhole with the diameter
+of <constant>4382</constant> microns. Looking at that number, we still decide that <constant>4400</constant> microns,
+or <constant>4.4</constant> millimeters is close enough.
+</para>
+
+<para>
+Additionally, we can decide that no matter how
+big a result we get, we only want to display four
+significant digits (or any other number
+of them, of course). Alas, the <acronym>FPU</acronym>
+does not offer rounding to a specific number
+of digits (after all, it does not view the
+numbers as decimal but as binary).
+</para>
+
+<para>
+We, therefore, must devise an algorithm to reduce
+the number of significant digits.
+</para>
+
+<para>
+Here is mine (I think it is awkward&mdash;if
+you know a better one, <emphasis>please</emphasis>, let me know):</para>
+
+<procedure>
+<step><para>
+Initialize a counter to <constant>0</constant>.
+</para>
+</step>
+<step><para>
+While the number is greater than or equal to
+<constant>10000</constant>, divide it by
+<constant>10</constant> and increase the counter.
+</para>
+</step>
+<step><para>
+Output the result.</para>
+</step>
+<step><para>
+While the counter is greater than <constant>0</constant>,
+output <constant>0</constant> and decrease the counter.
+</para>
+</step>
+</procedure>
+<note>
+<para>
+The <constant>10000</constant> is only good if you want
+<emphasis>four</emphasis> significant digits. For any other
+number of significant digits, replace
+<constant>10000</constant> with <constant>10</constant>
+raised to the number of significant digits.
+</para>
+</note>
+
+<para>
+We will, then, output the pinhole diameter
+in microns, rounded off to four significant
+digits.
+</para>
+
+<para>
+At this point, we know the <emphasis>focal
+length</emphasis> and the <emphasis>pinhole
+diameter</emphasis>. That means we have enough
+information to also calculate the
+<emphasis>f&ndash;number</emphasis>.
+</para>
+
+<para>
+We will display the f&ndash;number, rounded to
+four significant digits. Chances are the
+f&ndash;number will tell us very little. To make
+it more meaningful, we can find the nearest
+<emphasis>normalized f&ndash;number</emphasis>, i.e.,
+the nearest power of the square root
+of 2.
+</para>
+
+<para>
+We do that by multiplying the actual f&ndash;number
+by itself, which, of course, will give us
+its <function>square</function>. We will then calculate
+its base&ndash;2 logarithm, which is much
+easier to do than calculating the
+base&ndash;square&ndash;root&ndash;of&ndash;2 logarithm!
+We will round the result to the nearest integer.
+Next, we will raise 2 to the result. Actually,
+the <acronym>FPU</acronym> gives us a good shortcut
+to do that: We can use the <function role="opcode">fscale</function>
+op code to "scale" 1, which is
+analogous to <function role="opcode">shift</function>ing an
+integer left. Finally, we calculate the square
+root of it all, and we have the nearest
+normalized f&ndash;number.
+</para>
+
+<para>
+If all that sounds overwhelming&mdash;or too much
+work, perhaps&mdash;it may become much clearer
+if you see the code. It takes 9 op
+codes altogether:</para>
+
+<programlisting>
+ fmul st0, st0
+ fld1
+ fld st1
+ fyl2x
+ frndint
+ fld1
+ fscale
+ fsqrt
+ fstp st1
+</programlisting>
+<para>
+The first line, <function role="opcode">fmul st0, st0</function>, squares
+the contents of the <acronym>TOS</acronym>
+(top of the stack, same as <varname role="register">st</varname>,
+called <varname role="register">st0</varname> by <application>nasm</application>).
+The <function role="opcode">fld1</function> pushes <constant>1</constant>
+on the <acronym>TOS</acronym>.</para>
+
+<para>
+The next line, <function role="opcode">fld st1</function>, pushes
+the square back to the <acronym>TOS</acronym>.
+At this point the square is both in <varname role="register">st</varname>
+and <varname role="register">st(2)</varname> (it will become
+clear why we leave a second copy on the stack
+in a moment). <varname role="register">st(1)</varname> contains
+<constant>1</constant>.
+</para>
+
+<para>
+Next, <function role="opcode">fyl2x</function> calculates base&ndash;2
+logarithm of <varname role="register">st</varname> multiplied by
+<varname role="register">st(1)</varname>. That is why we placed <constant>1</constant> on <varname role="register">st(1)</varname> before.</para>
+
+<para>
+At this point, <varname role="register">st</varname> contains
+the logarithm we have just calculated,
+<varname role="register">st(1)</varname> contains the square
+of the actual f&ndash;number we saved for later.
+</para>
+
+<para>
+<function role="opcode">frndint</function> rounds the <acronym>TOS</acronym>
+to the nearest integer. <function role="opcode">fld1</function> pushes
+a <constant>1</constant>. <function role="opcode">fscale</function> shifts the
+<constant>1</constant> we have on the <acronym>TOS</acronym>
+by the value in <varname role="register">st(1)</varname>,
+effectively raising 2 to <varname role="register">st(1)</varname>.
+</para>
+
+<para>
+Finally, <function role="opcode">fsqrt</function> calculates
+the square root of the result, i.e.,
+the nearest normalized f&ndash;number.
+</para>
+
+<para>
+We now have the nearest normalized
+f&ndash;number on the <acronym>TOS</acronym>,
+the base&ndash;2 logarithm rounded to the
+nearest integer in <varname role="register">st(1)</varname>,
+and the square of the actual f&ndash;number
+in <varname role="register">st(2)</varname>. We are saving
+the value in <varname role="register">st(2)</varname> for later.
+</para>
+
+<para>
+But we do not need the contents of
+<varname role="register">st(1)</varname> anymore. The last
+line, <function role="opcode">fstp st1</function>, places the
+contents of <varname role="register">st</varname> to
+<varname role="register">st(1)</varname>, and pops. As a
+result, what was <varname role="register">st(1)</varname>
+is now <varname role="register">st</varname>, what was <varname role="register">st(2)</varname>
+is now <varname role="register">st(1)</varname>, etc.
+The new <varname role="register">st</varname> contains the
+normalized f&ndash;number. The new
+<varname role="register">st(1)</varname> contains the square
+of the actual f&ndash;number we have
+stored there for posterity.
+</para>
+
+<para>
+At this point, we are ready to output
+the normalized f&ndash;number. Because it is
+normalized, we will not round it off to
+four significant digits, but will
+send it out in its full precision.
+</para>
+
+<para>
+The normalized f-number is useful as long
+as it is reasonably small and can be found
+on our light meter. Otherwise we need a
+different method of determining proper
+exposure.
+</para>
+
+<para>
+Earlier we have figured out the formula
+of calculating proper exposure at an arbitrary
+f&ndash;number from that measured at a different
+f&ndash;number.
+</para>
+
+<para>
+Every light meter I have ever seen can determine
+proper exposure at f5.6. We will, therefore,
+calculate an <emphasis>"f5.6 multiplier,"</emphasis>
+i.e., by how much we need to multiply the exposure measured
+at f5.6 to determine the proper exposure
+for our pinhole camera.
+</para>
+
+<para>
+From the above formula we know this factor can be
+calculated by dividing our f&ndash;number (the
+actual one, not the normalized one) by
+<constant>5.6</constant>, and squaring the result.
+</para>
+
+<para>
+Mathematically, dividing the square of our
+f&ndash;number by the square of <constant>5.6</constant>
+will give us the same result.
+</para>
+
+<para>
+Computationally, we do not want to square
+two numbers when we can only square one.
+So, the first solution seems better at first.
+</para>
+
+<para>
+But...</para>
+
+<para>
+<constant>5.6</constant> is a <emphasis>constant</emphasis>.
+We do not have to have our <acronym>FPU</acronym>
+waste precious cycles. We can just tell it
+to divide the square of the f&ndash;number by
+whatever <constant>5.6&#178;</constant> equals to.
+Or we can divide the f&ndash;number by <constant>5.6</constant>,
+and then square the result. The two ways
+now seem equal.
+</para>
+
+<para>
+But, they are not!</para>
+
+<para>
+Having studied the principles of photography
+above, we remember that the <constant>5.6</constant>
+is actually square root of 2 raised to
+the fifth power. An <emphasis>irrational</emphasis>
+number. The square of this number is
+<emphasis>exactly</emphasis> <constant>32</constant>.
+</para>
+
+<para>
+Not only is <constant>32</constant> an integer,
+it is a power of 2. We do not need
+to divide the square of the f&ndash;number by
+<constant>32</constant>. We only need to use
+<function role="opcode">fscale</function> to shift it right by
+five positions. In the <acronym>FPU</acronym>
+lingo it means we will <function role="opcode">fscale</function> it
+with <varname role="register">st(1)</varname> equal to
+<constant>-5</constant>. That is <emphasis>much
+faster</emphasis> than a division.
+</para>
+
+<para>
+So, now it has become clear why we have
+saved the square of the f&ndash;number on the
+top of the <acronym>FPU</acronym> stack.
+The calculation of the f5.6 multiplier
+is the easiest calculation of this
+entire program! We will output it rounded
+to four significant digits.
+</para>
+
+<para>
+There is one more useful number we can calculate:
+The number of stops our f&ndash;number is from f5.6.
+This may help us if our f&ndash;number is just outside
+the range of our light meter, but we have
+a shutter which lets us set various speeds,
+and this shutter uses stops.
+</para>
+
+<para>
+Say, our f&ndash;number is 5 stops from
+f5.6, and the light meter says
+we should use 1/1000 sec.
+Then we can set our shutter speed to 1/1000
+first, then move the dial by 5 stops.
+</para>
+
+<para>
+This calculation is quite easy as well. All
+we have to do is to calculate the base-2
+logarithm of the f5.6 multiplier
+we had just calculated (though we need its
+value from before we rounded it off). We then
+output the result rounded to the nearest integer.
+We do not need to worry about having more than
+four significant digits in this one: The result
+is most likely to have only one or two digits
+anyway.</para>
+
+</sect3>
+
+</sect2>
+
+<sect2 xml:id="x86-fpu-optimizations">
+<title>FPU Optimizations</title>
+<para>
+In assembly language we can optimize the <acronym>FPU</acronym>
+code in ways impossible in high languages,
+including C.
+</para>
+
+<para>
+Whenever a C function needs to calculate
+a floating&ndash;point value, it loads all necessary
+variables and constants into <acronym>FPU</acronym>
+registers. It then does whatever calculation is
+required to get the correct result. Good C
+compilers can optimize that part of the code really
+well.
+</para>
+
+<para>
+It "returns" the value by leaving
+the result on the <acronym>TOS</acronym>.
+However, before it returns, it cleans up.
+Any variables and constants it used in its
+calculation are now gone from the <acronym>FPU</acronym>.
+</para>
+
+<para>
+It cannot do what we just did above: We calculated
+the square of the f&ndash;number and kept it on the
+stack for later use by another function.
+</para>
+
+<para>
+We <emphasis>knew</emphasis> we would need that value
+later on. We also knew we had enough room on the
+stack (which only has room for 8 numbers)
+to store it there.
+</para>
+
+<para>
+A C compiler has no way of knowing
+that a value it has on the stack will be
+required again in the very near future.
+</para>
+
+<para>
+Of course, the C programmer may know it.
+But the only recourse he has is to store the
+value in a memory variable.
+</para>
+
+<para>
+That means, for one, the value will be changed
+from the 80-bit precision used internally
+by the <acronym>FPU</acronym> to a C <emphasis>double</emphasis>
+(64 bits) or even <emphasis>single</emphasis> (32
+bits).
+</para>
+
+<para>
+That also means that the value must be moved
+from the <acronym>TOS</acronym> into the memory,
+and then back again. Alas, of all <acronym>FPU</acronym>
+operations, the ones that access the computer
+memory are the slowest.
+</para>
+
+<para>
+So, whenever programming the <acronym>FPU</acronym>
+in assembly language, look for the ways of keeping
+intermediate results on the <acronym>FPU</acronym>
+stack.
+</para>
+
+<para>
+We can take that idea even further! In our
+program we are using a <emphasis>constant</emphasis>
+(the one we named <constant>PC</constant>).
+</para>
+
+<para>
+It does not matter how many pinhole diameters
+we are calculating: 1, 10, 20,
+1000, we are always using the same constant.
+Therefore, we can optimize our program by keeping
+the constant on the stack all the time.
+</para>
+
+<para>
+Early on in our program, we are calculating the
+value of the above constant. We need to divide
+our input by <constant>10</constant> for every digit in the
+constant.
+</para>
+
+<para>
+It is much faster to multiply than to divide.
+So, at the start of our program, we divide <constant>10</constant>
+into <constant>1</constant> to obtain <constant>0.1</constant>, which we
+then keep on the stack: Instead of dividing the
+input by <constant>10</constant> for every digit,
+we multiply it by <constant>0.1</constant>.
+</para>
+
+<para>
+By the way, we do not input <constant>0.1</constant> directly,
+even though we could. We have a reason for that:
+While <constant>0.1</constant> can be expressed with just one
+decimal place, we do not know how many <emphasis>binary</emphasis>
+places it takes. We, therefore, let the <acronym>FPU</acronym>
+calculate its binary value to its own high precision.
+</para>
+
+<para>
+We are using other constants: We multiply the pinhole
+diameter by <constant>1000</constant> to convert it from
+millimeters to microns. We compare numbers to
+<constant>10000</constant> when we are rounding them off to
+four significant digits. So, we keep both, <constant>1000</constant>
+and <constant>10000</constant>, on the stack. And, of course,
+we reuse the <constant>0.1</constant> when rounding off numbers
+to four digits.
+</para>
+
+<para>
+Last but not least, we keep <constant>-5</constant> on the stack.
+We need it to scale the square of the f&ndash;number,
+instead of dividing it by <constant>32</constant>. It is not
+by coincidence we load this constant last. That makes
+it the top of the stack when only the constants
+are on it. So, when the square of the f&ndash;number is
+being scaled, the <constant>-5</constant> is at <varname role="register">st(1)</varname>,
+precisely where <function role="opcode">fscale</function> expects it to be.
+</para>
+
+<para>
+It is common to create certain constants from
+scratch instead of loading them from the memory.
+That is what we are doing with <constant>-5</constant>:
+</para>
+
+<programlisting>
+ fld1 ; TOS = 1
+ fadd st0, st0 ; TOS = 2
+ fadd st0, st0 ; TOS = 4
+ fld1 ; TOS = 1
+ faddp st1, st0 ; TOS = 5
+ fchs ; TOS = -5
+</programlisting>
+<para>
+We can generalize all these optimizations into one rule:
+<emphasis>Keep repeat values on the stack!</emphasis>
+</para>
+
+<tip>
+<para>
+<emphasis>&postscript;</emphasis> is a stack&ndash;oriented
+programming language. There are many more books
+available about &postscript; than about the
+<acronym>FPU</acronym> assembly language: Mastering
+&postscript; will help you master the <acronym>FPU</acronym>.
+</para>
+</tip>
+
+</sect2>
+
+<sect2 xml:id="x86-pinhole-the-code">
+<title><application>pinhole</application>&mdash;The Code</title>
+<programlisting>
+;;;;;;; pinhole.asm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; Find various parameters of a pinhole camera construction and use
+;
+; Started: 9-Jun-2001
+; Updated: 10-Jun-2001
+;
+; Copyright (c) 2001 G. Adam Stanislav
+; All rights reserved.
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+%include 'system.inc'
+
+%define BUFSIZE 2048
+
+section .data
+align 4
+ten dd 10
+thousand dd 1000
+tthou dd 10000
+fd.in dd stdin
+fd.out dd stdout
+envar db 'PINHOLE=' ; Exactly 8 bytes, or 2 dwords long
+pinhole db '04,', ; Bender's constant (0.04)
+connors db '037', 0Ah ; Connors' constant
+usg db 'Usage: pinhole [-b] [-c] [-e] [-p &lt;value&gt;] [-o &lt;outfile&gt;] [-i &lt;infile&gt;]', 0Ah
+usglen equ $-usg
+iemsg db "pinhole: Can't open input file", 0Ah
+iemlen equ $-iemsg
+oemsg db "pinhole: Can't create output file", 0Ah
+oemlen equ $-oemsg
+pinmsg db "pinhole: The PINHOLE constant must not be 0", 0Ah
+pinlen equ $-pinmsg
+toobig db "pinhole: The PINHOLE constant may not exceed 18 decimal places", 0Ah
+biglen equ $-toobig
+huhmsg db 9, '???'
+separ db 9, '???'
+sep2 db 9, '???'
+sep3 db 9, '???'
+sep4 db 9, '???', 0Ah
+huhlen equ $-huhmsg
+header db 'focal length in millimeters,pinhole diameter in microns,'
+ db 'F-number,normalized F-number,F-5.6 multiplier,stops '
+ db 'from F-5.6', 0Ah
+headlen equ $-header
+
+section .bss
+ibuffer resb BUFSIZE
+obuffer resb BUFSIZE
+dbuffer resb 20 ; decimal input buffer
+bbuffer resb 10 ; BCD buffer
+
+section .text
+align 4
+huh:
+ call write
+ push dword huhlen
+ push dword huhmsg
+ push dword [fd.out]
+ sys.write
+ add esp, byte 12
+ ret
+
+align 4
+perr:
+ push dword pinlen
+ push dword pinmsg
+ push dword stderr
+ sys.write
+ push dword 4 ; return failure
+ sys.exit
+
+align 4
+consttoobig:
+ push dword biglen
+ push dword toobig
+ push dword stderr
+ sys.write
+ push dword 5 ; return failure
+ sys.exit
+
+align 4
+ierr:
+ push dword iemlen
+ push dword iemsg
+ push dword stderr
+ sys.write
+ push dword 1 ; return failure
+ sys.exit
+
+align 4
+oerr:
+ push dword oemlen
+ push dword oemsg
+ push dword stderr
+ sys.write
+ push dword 2
+ sys.exit
+
+align 4
+usage:
+ push dword usglen
+ push dword usg
+ push dword stderr
+ sys.write
+ push dword 3
+ sys.exit
+
+align 4
+global _start
+_start:
+ add esp, byte 8 ; discard argc and argv[0]
+ sub esi, esi
+
+.arg:
+ pop ecx
+ or ecx, ecx
+ je near .getenv ; no more arguments
+
+ ; ECX contains the pointer to an argument
+ cmp byte [ecx], '-'
+ jne usage
+
+ inc ecx
+ mov ax, [ecx]
+ inc ecx
+
+.o:
+ cmp al, 'o'
+ jne .i
+
+ ; Make sure we are not asked for the output file twice
+ cmp dword [fd.out], stdout
+ jne usage
+
+ ; Find the path to output file - it is either at [ECX+1],
+ ; i.e., -ofile --
+ ; or in the next argument,
+ ; i.e., -o file
+
+ or ah, ah
+ jne .openoutput
+ pop ecx
+ jecxz usage
+
+.openoutput:
+ push dword 420 ; file mode (644 octal)
+ push dword 0200h | 0400h | 01h
+ ; O_CREAT | O_TRUNC | O_WRONLY
+ push ecx
+ sys.open
+ jc near oerr
+
+ add esp, byte 12
+ mov [fd.out], eax
+ jmp short .arg
+
+.i:
+ cmp al, 'i'
+ jne .p
+
+ ; Make sure we are not asked twice
+ cmp dword [fd.in], stdin
+ jne near usage
+
+ ; Find the path to the input file
+ or ah, ah
+ jne .openinput
+ pop ecx
+ or ecx, ecx
+ je near usage
+
+.openinput:
+ push dword 0 ; O_RDONLY
+ push ecx
+ sys.open
+ jc near ierr ; open failed
+
+ add esp, byte 8
+ mov [fd.in], eax
+ jmp .arg
+
+.p:
+ cmp al, 'p'
+ jne .c
+ or ah, ah
+ jne .pcheck
+
+ pop ecx
+ or ecx, ecx
+ je near usage
+
+ mov ah, [ecx]
+
+.pcheck:
+ cmp ah, '0'
+ jl near usage
+ cmp ah, '9'
+ ja near usage
+ mov esi, ecx
+ jmp .arg
+
+.c:
+ cmp al, 'c'
+ jne .b
+ or ah, ah
+ jne near usage
+ mov esi, connors
+ jmp .arg
+
+.b:
+ cmp al, 'b'
+ jne .e
+ or ah, ah
+ jne near usage
+ mov esi, pinhole
+ jmp .arg
+
+.e:
+ cmp al, 'e'
+ jne near usage
+ or ah, ah
+ jne near usage
+ mov al, ','
+ mov [huhmsg], al
+ mov [separ], al
+ mov [sep2], al
+ mov [sep3], al
+ mov [sep4], al
+ jmp .arg
+
+align 4
+.getenv:
+ ; If ESI = 0, we did not have a -p argument,
+ ; and need to check the environment for "PINHOLE="
+ or esi, esi
+ jne .init
+
+ sub ecx, ecx
+
+.nextenv:
+ pop esi
+ or esi, esi
+ je .default ; no PINHOLE envar found
+
+ ; check if this envar starts with 'PINHOLE='
+ mov edi, envar
+ mov cl, 2 ; 'PINHOLE=' is 2 dwords long
+rep cmpsd
+ jne .nextenv
+
+ ; Check if it is followed by a digit
+ mov al, [esi]
+ cmp al, '0'
+ jl .default
+ cmp al, '9'
+ jbe .init
+ ; fall through
+
+align 4
+.default:
+ ; We got here because we had no -p argument,
+ ; and did not find the PINHOLE envar.
+ mov esi, pinhole
+ ; fall through
+
+align 4
+.init:
+ sub eax, eax
+ sub ebx, ebx
+ sub ecx, ecx
+ sub edx, edx
+ mov edi, dbuffer+1
+ mov byte [dbuffer], '0'
+
+ ; Convert the pinhole constant to real
+.constloop:
+ lodsb
+ cmp al, '9'
+ ja .setconst
+ cmp al, '0'
+ je .processconst
+ jb .setconst
+
+ inc dl
+
+.processconst:
+ inc cl
+ cmp cl, 18
+ ja near consttoobig
+ stosb
+ jmp short .constloop
+
+align 4
+.setconst:
+ or dl, dl
+ je near perr
+
+ finit
+ fild dword [tthou]
+
+ fld1
+ fild dword [ten]
+ fdivp st1, st0
+
+ fild dword [thousand]
+ mov edi, obuffer
+
+ mov ebp, ecx
+ call bcdload
+
+.constdiv:
+ fmul st0, st2
+ loop .constdiv
+
+ fld1
+ fadd st0, st0
+ fadd st0, st0
+ fld1
+ faddp st1, st0
+ fchs
+
+ ; If we are creating a CSV file,
+ ; print header
+ cmp byte [separ], ','
+ jne .bigloop
+
+ push dword headlen
+ push dword header
+ push dword [fd.out]
+ sys.write
+
+.bigloop:
+ call getchar
+ jc near done
+
+ ; Skip to the end of the line if you got '#'
+ cmp al, '#'
+ jne .num
+ call skiptoeol
+ jmp short .bigloop
+
+.num:
+ ; See if you got a number
+ cmp al, '0'
+ jl .bigloop
+ cmp al, '9'
+ ja .bigloop
+
+ ; Yes, we have a number
+ sub ebp, ebp
+ sub edx, edx
+
+.number:
+ cmp al, '0'
+ je .number0
+ mov dl, 1
+
+.number0:
+ or dl, dl ; Skip leading 0's
+ je .nextnumber
+ push eax
+ call putchar
+ pop eax
+ inc ebp
+ cmp ebp, 19
+ jae .nextnumber
+ mov [dbuffer+ebp], al
+
+.nextnumber:
+ call getchar
+ jc .work
+ cmp al, '#'
+ je .ungetc
+ cmp al, '0'
+ jl .work
+ cmp al, '9'
+ ja .work
+ jmp short .number
+
+.ungetc:
+ dec esi
+ inc ebx
+
+.work:
+ ; Now, do all the work
+ or dl, dl
+ je near .work0
+
+ cmp ebp, 19
+ jae near .toobig
+
+ call bcdload
+
+ ; Calculate pinhole diameter
+
+ fld st0 ; save it
+ fsqrt
+ fmul st0, st3
+ fld st0
+ fmul st5
+ sub ebp, ebp
+
+ ; Round off to 4 significant digits
+.diameter:
+ fcom st0, st7
+ fstsw ax
+ sahf
+ jb .printdiameter
+ fmul st0, st6
+ inc ebp
+ jmp short .diameter
+
+.printdiameter:
+ call printnumber ; pinhole diameter
+
+ ; Calculate F-number
+
+ fdivp st1, st0
+ fld st0
+
+ sub ebp, ebp
+
+.fnumber:
+ fcom st0, st6
+ fstsw ax
+ sahf
+ jb .printfnumber
+ fmul st0, st5
+ inc ebp
+ jmp short .fnumber
+
+.printfnumber:
+ call printnumber ; F number
+
+ ; Calculate normalized F-number
+ fmul st0, st0
+ fld1
+ fld st1
+ fyl2x
+ frndint
+ fld1
+ fscale
+ fsqrt
+ fstp st1
+
+ sub ebp, ebp
+ call printnumber
+
+ ; Calculate time multiplier from F-5.6
+
+ fscale
+ fld st0
+
+ ; Round off to 4 significant digits
+.fmul:
+ fcom st0, st6
+ fstsw ax
+ sahf
+
+ jb .printfmul
+ inc ebp
+ fmul st0, st5
+ jmp short .fmul
+
+.printfmul:
+ call printnumber ; F multiplier
+
+ ; Calculate F-stops from 5.6
+
+ fld1
+ fxch st1
+ fyl2x
+
+ sub ebp, ebp
+ call printnumber
+
+ mov al, 0Ah
+ call putchar
+ jmp .bigloop
+
+.work0:
+ mov al, '0'
+ call putchar
+
+align 4
+.toobig:
+ call huh
+ jmp .bigloop
+
+align 4
+done:
+ call write ; flush output buffer
+
+ ; close files
+ push dword [fd.in]
+ sys.close
+
+ push dword [fd.out]
+ sys.close
+
+ finit
+
+ ; return success
+ push dword 0
+ sys.exit
+
+align 4
+skiptoeol:
+ ; Keep reading until you come to cr, lf, or eof
+ call getchar
+ jc done
+ cmp al, 0Ah
+ jne .cr
+ ret
+
+.cr:
+ cmp al, 0Dh
+ jne skiptoeol
+ ret
+
+align 4
+getchar:
+ or ebx, ebx
+ jne .fetch
+
+ call read
+
+.fetch:
+ lodsb
+ dec ebx
+ clc
+ ret
+
+read:
+ jecxz .read
+ call write
+
+.read:
+ push dword BUFSIZE
+ mov esi, ibuffer
+ push esi
+ push dword [fd.in]
+ sys.read
+ add esp, byte 12
+ mov ebx, eax
+ or eax, eax
+ je .empty
+ sub eax, eax
+ ret
+
+align 4
+.empty:
+ add esp, byte 4
+ stc
+ ret
+
+align 4
+putchar:
+ stosb
+ inc ecx
+ cmp ecx, BUFSIZE
+ je write
+ ret
+
+align 4
+write:
+ jecxz .ret ; nothing to write
+ sub edi, ecx ; start of buffer
+ push ecx
+ push edi
+ push dword [fd.out]
+ sys.write
+ add esp, byte 12
+ sub eax, eax
+ sub ecx, ecx ; buffer is empty now
+.ret:
+ ret
+
+align 4
+bcdload:
+ ; EBP contains the number of chars in dbuffer
+ push ecx
+ push esi
+ push edi
+
+ lea ecx, [ebp+1]
+ lea esi, [dbuffer+ebp-1]
+ shr ecx, 1
+
+ std
+
+ mov edi, bbuffer
+ sub eax, eax
+ mov [edi], eax
+ mov [edi+4], eax
+ mov [edi+2], ax
+
+.loop:
+ lodsw
+ sub ax, 3030h
+ shl al, 4
+ or al, ah
+ mov [edi], al
+ inc edi
+ loop .loop
+
+ fbld [bbuffer]
+
+ cld
+ pop edi
+ pop esi
+ pop ecx
+ sub eax, eax
+ ret
+
+align 4
+printnumber:
+ push ebp
+ mov al, [separ]
+ call putchar
+
+ ; Print the integer at the TOS
+ mov ebp, bbuffer+9
+ fbstp [bbuffer]
+
+ ; Check the sign
+ mov al, [ebp]
+ dec ebp
+ or al, al
+ jns .leading
+
+ ; We got a negative number (should never happen)
+ mov al, '-'
+ call putchar
+
+.leading:
+ ; Skip leading zeros
+ mov al, [ebp]
+ dec ebp
+ or al, al
+ jne .first
+ cmp ebp, bbuffer
+ jae .leading
+
+ ; We are here because the result was 0.
+ ; Print '0' and return
+ mov al, '0'
+ jmp putchar
+
+.first:
+ ; We have found the first non-zero.
+ ; But it is still packed
+ test al, 0F0h
+ jz .second
+ push eax
+ shr al, 4
+ add al, '0'
+ call putchar
+ pop eax
+ and al, 0Fh
+
+.second:
+ add al, '0'
+ call putchar
+
+.next:
+ cmp ebp, bbuffer
+ jb .done
+
+ mov al, [ebp]
+ push eax
+ shr al, 4
+ add al, '0'
+ call putchar
+ pop eax
+ and al, 0Fh
+ add al, '0'
+ call putchar
+
+ dec ebp
+ jmp short .next
+
+.done:
+ pop ebp
+ or ebp, ebp
+ je .ret
+
+.zeros:
+ mov al, '0'
+ call putchar
+ dec ebp
+ jne .zeros
+
+.ret:
+ ret
+</programlisting>
+<para>
+The code follows the same format as all the other
+filters we have seen before, with one subtle
+exception:
+</para>
+
+<blockquote>
+<para>
+We are no longer assuming that the end of input
+implies the end of things to do, something we
+took for granted in the <emphasis>character&ndash;oriented</emphasis>
+filters.
+</para>
+
+<para>
+This filter does not process characters. It
+processes a <emphasis>language</emphasis>
+(albeit a very simple
+one, consisting only of numbers).
+</para>
+
+<para>
+When we have no more input, it can mean one
+of two things:</para>
+
+<itemizedlist><listitem>
+<para>
+We are done and can quit. This is the
+same as before.
+</para>
+</listitem>
+
+<listitem>
+<para>
+The last character we have read was a digit.
+We have stored it at the end of our
+<acronym>ASCII</acronym>&ndash;to&ndash;float conversion
+buffer. We now need to convert
+the contents of that buffer into a
+number and write the last line of our
+output.
+</para>
+</listitem>
+
+</itemizedlist>
+<para>
+For that reason, we have modified our <function>getchar</function>
+and our <function>read</function> routines to return with
+the <varname role="register">carry flag</varname> <emphasis>clear</emphasis> whenever we are
+fetching another character from the input, or the
+<varname role="register">carry flag</varname> <emphasis>set</emphasis> whenever there is no more
+input.
+</para>
+
+<para>
+Of course, we are still using assembly language magic
+to do that! Take a good look at <function>getchar</function>.
+It <emphasis>always</emphasis> returns with the
+<varname role="register">carry flag</varname> <emphasis>clear</emphasis>.
+</para>
+
+<para>
+Yet, our main code relies on the <varname role="register">carry
+flag</varname> to tell it when to quit&mdash;and it works.
+</para>
+
+<para>
+The magic is in <function>read</function>. Whenever it
+receives more input from the system, it just
+returns to <function>getchar</function>, which
+fetches a character from the input buffer,
+<emphasis>clears</emphasis> the <varname role="register">carry flag</varname>
+and returns.
+</para>
+
+<para>
+But when <function>read</function> receives no more
+input from the system, it does <emphasis>not</emphasis>
+return to <function>getchar</function> at all.
+Instead, the <function role="opcode">add esp, byte 4</function>
+op code adds <constant>4</constant> to <varname role="register">ESP</varname>,
+<emphasis>sets</emphasis> the <varname role="register">carry
+flag</varname>, and returns.
+</para>
+
+<para>
+So, where does it return to? Whenever a
+program uses the <function role="opcode">call</function> op code,
+the microprocessor <function role="opcode">push</function>es the
+return address, i.e., it stores it on
+the top of the stack (not the <acronym>FPU</acronym>
+stack, the system stack, which is in the memory).
+When a program uses the <function role="opcode">ret</function>
+op code, the microprocessor <function role="opcode">pop</function>s
+the return value from the stack, and jumps
+to the address that was stored there.
+</para>
+
+<para>
+But since we added <constant>4</constant> to
+<varname role="register">ESP</varname> (which is the stack
+pointer register), we have effectively
+given the microprocessor a minor case
+of <emphasis>amnesia</emphasis>: It no longer
+remembers it was <function>getchar</function>
+that <function role="opcode">call</function>ed <function>read</function>.
+</para>
+
+<para>
+And since <function>getchar</function> never
+<function role="opcode">push</function>ed anything before
+<function role="opcode">call</function>ing <function>read</function>,
+the top of the stack now contains the
+return address to whatever or whoever
+<function role="opcode">call</function>ed <function>getchar</function>.
+As far as that caller is concerned,
+he <function role="opcode">call</function>ed <function>getchar</function>,
+which <function role="opcode">ret</function>urned with the
+<varname role="register">carry flag</varname> set!
+</para>
+
+</blockquote>
+<para>
+Other than that, the <function>bcdload</function>
+routine is caught up in the middle of a
+Lilliputian conflict between the Big&ndash;Endians
+and the Little&ndash;Endians.
+</para>
+
+<para>
+It is converting the text representation
+of a number into that number: The text
+is stored in the big&ndash;endian order, but
+the <emphasis>packed decimal</emphasis> is little&ndash;endian.
+</para>
+
+<para>
+To solve the conflict, we use the <function>std</function>
+op code early on. We cancel it with <function>cld</function>
+later on: It is quite important we do not
+<function>call</function> anything that may depend on
+the default setting of the <emphasis>direction
+flag</emphasis> while <function>std</function> is active.
+</para>
+
+<para>
+Everything else in this code should be quite
+clear, providing you have read the entire chapter
+that precedes it.
+</para>
+
+<para>
+It is a classical example of the adage that
+programming requires a lot of thought and only
+a little coding. Once we have thought through every
+tiny detail, the code almost writes itself.
+</para>
+
+</sect2>
+
+<sect2 xml:id="x86-pinhole-using">
+<title>Using <application>pinhole</application></title>
+<para>
+Because we have decided to make the program
+<emphasis>ignore</emphasis> any input except for numbers
+(and even those inside a comment), we can
+actually perform <emphasis>textual queries</emphasis>.
+We do not <emphasis>have to</emphasis>, but we <emphasis>can</emphasis>.
+</para>
+
+<para>
+In my humble opinion, forming a textual query,
+instead of having to follow a very strict
+syntax, makes software much more user friendly.
+</para>
+
+<para>
+Suppose we want to build a pinhole camera to use the
+4x5 inch film. The standard focal
+length for that film is about 150mm. We want
+to <emphasis>fine&ndash;tune</emphasis> our focal length so the
+pinhole diameter is as round a number as possible.
+Let us also suppose we are quite comfortable with
+cameras but somewhat intimidated by computers.
+Rather than just have to type in a bunch of numbers,
+we want to <emphasis>ask</emphasis> a couple of questions.
+</para>
+
+<para>
+Our session might look like this:</para>
+
+<screen>&prompt.user; <userinput>pinhole
+
+Computer,
+
+What size pinhole do I need for the focal length of 150?</userinput>
+150 490 306 362 2930 12
+<userinput>Hmmm... How about 160?</userinput>
+160 506 316 362 3125 12
+<userinput>Let's make it 155, please.</userinput>
+155 498 311 362 3027 12
+<userinput>Ah, let's try 157...</userinput>
+157 501 313 362 3066 12
+<userinput>156?</userinput>
+156 500 312 362 3047 12
+<userinput>That's it! Perfect! Thank you very much!
+^D</userinput></screen>
+<para>
+We have found that while for the focal length
+of 150, our pinhole diameter should be 490
+microns, or 0.49 mm, if we go with the almost
+identical focal length of 156 mm, we can
+get away with a pinhole diameter of exactly
+one half of a millimeter.
+</para>
+
+</sect2>
+
+<sect2 xml:id="x86-pinhole-scripting">
+<title>Scripting</title>
+<para>
+Because we have chosen the <constant>#</constant>
+character to denote the start of a comment,
+we can treat our <application>pinhole</application>
+software as a <emphasis>scripting language</emphasis>.
+</para>
+
+<para>
+You have probably seen <application>shell</application>
+<emphasis>scripts</emphasis> that start with:</para>
+
+<programlisting>
+#! /bin/sh
+</programlisting>
+<para>
+...or...</para>
+
+<programlisting>
+#!/bin/sh
+</programlisting> <para>
+...because the blank space after the <function>#!</function>
+is optional.
+</para>
+
+<para>
+Whenever &unix; is asked to run an executable
+file which starts with the <function>#!</function>,
+it assumes the file is a script. It adds the
+command to the rest of the first line of the
+script, and tries to execute that.
+</para>
+
+<para>
+Suppose now that we have installed <application>pinhole</application>
+in <application>/usr/local/bin/</application>, we can now
+write a script to calculate various pinhole
+diameters suitable for various focal lengths
+commonly used with the 120 film.</para>
+
+<para>
+The script might look something like this:</para>
+
+<programlisting>
+#! /usr/local/bin/pinhole -b -i
+# Find the best pinhole diameter
+# for the 120 film
+
+### Standard
+80
+
+### Wide angle
+30, 40, 50, 60, 70
+
+### Telephoto
+100, 120, 140
+</programlisting>
+<para>
+Because 120 is a medium size film,
+we may name this file <application>medium</application>.
+</para>
+
+<para>
+We can set its permissions to execute,
+and run it as if it were a program:
+</para>
+
+<screen>&prompt.user; <userinput>chmod 755 medium</userinput>
+&prompt.user; <userinput>./medium</userinput></screen>
+<para>
+&unix; will interpret that last command as:</para>
+
+<screen>&prompt.user; <userinput>/usr/local/bin/pinhole -b -i ./medium</userinput></screen>
+<para>
+It will run that command and display:
+</para>
+
+<screen>80 358 224 256 1562 11
+30 219 137 128 586 9
+40 253 158 181 781 10
+50 283 177 181 977 10
+60 310 194 181 1172 10
+70 335 209 181 1367 10
+100 400 250 256 1953 11
+120 438 274 256 2344 11
+140 473 296 256 2734 11</screen>
+<para>
+
+Now, let us enter:</para>
+
+<screen>&prompt.user; <userinput>./medium -c</userinput></screen>
+<para>
+&unix; will treat that as:</para>
+
+<screen>&prompt.user; <userinput>/usr/local/bin/pinhole -b -i ./medium -c</userinput></screen>
+<para>
+That gives it two conflicting options:
+<parameter>-b</parameter> and <parameter>-c</parameter>
+(Use Bender's constant and use Connors'
+constant). We have programmed it so
+later options override early ones&mdash;our
+program will calculate everything
+using Connors' constant:
+</para>
+
+<screen>80 331 242 256 1826 11
+30 203 148 128 685 9
+40 234 171 181 913 10
+50 262 191 181 1141 10
+60 287 209 181 1370 10
+70 310 226 256 1598 11
+100 370 270 256 2283 11
+120 405 296 256 2739 11
+140 438 320 362 3196 12</screen>
+<para>
+We decide we want to go with Bender's
+constant after all. We want to save its
+values as a comma&ndash;separated file:
+</para>
+
+<screen>&prompt.user; <userinput>./medium -b -e &gt; bender</userinput>
+&prompt.user; <userinput>cat bender</userinput>
+focal length in millimeters,pinhole diameter in microns,F-number,normalized F-number,F-5.6 multiplier,stops from F-5.6
+80,358,224,256,1562,11
+30,219,137,128,586,9
+40,253,158,181,781,10
+50,283,177,181,977,10
+60,310,194,181,1172,10
+70,335,209,181,1367,10
+100,400,250,256,1953,11
+120,438,274,256,2344,11
+140,473,296,256,2734,11
+&prompt.user;</screen>
+</sect2>
+
+</sect1>
+
+<sect1 xml:id="x86-caveats">
+<title>Caveats</title>
+
+<para>
+Assembly language programmers who "grew up" under
+<acronym>&ms-dos;</acronym> and &windows; often tend to take shortcuts.
+Reading the keyboard scan codes and writing directly to video
+memory are two classical examples of practices which, under
+<acronym>&ms-dos;</acronym> are not frowned upon but considered the
+right thing to do.
+</para>
+
+<para>
+The reason? Both the <acronym>PC BIOS</acronym> and
+<acronym>&ms-dos;</acronym> are notoriously
+slow when performing these operations.
+</para>
+
+<para>
+You may be tempted to continue similar practices in the
+&unix; environment. For example, I have seen a web site which
+explains how to access the keyboard scan codes on a popular &unix; clone.
+</para>
+
+<para>
+That is generally a <emphasis>very bad idea</emphasis>
+in &unix; environment! Let me explain why.
+</para>
+
+<sect2 xml:id="x86-protected">
+<title>&unix; Is Protected</title>
+
+<para>
+For one thing, it may simply not be possible. &unix; runs in
+protected mode. Only the kernel and device drivers are allowed
+to access hardware directly. Perhaps a particular &unix; clone
+will let you read the keyboard scan codes, but chances are a real
+&unix; operating system will not. And even if one version may let you
+do it, the next one may not, so your carefully crafted software may
+become a dinosaur overnight.
+</para>
+
+</sect2>
+
+<sect2 xml:id="x86-abstraction">
+<title>&unix; Is an Abstraction</title>
+
+<para>
+But there is a much more important reason not to try
+accessing the hardware directly (unless, of course,
+you are writing a device driver), even on the &unix; like
+systems that let you do it:
+</para>
+
+<para>
+<emphasis>&unix; is an abstraction!
+</emphasis></para>
+
+<para>
+There is a major difference in the philosophy of design
+between <acronym>&ms-dos;</acronym> and &unix;.
+<acronym>&ms-dos;</acronym> was designed as a single-user
+system. It is run on a computer with a keyboard and a video
+screen attached directly to that computer. User input is almost
+guaranteed to come from that keyboard. Your program's output
+virtually always ends up on that screen.
+</para>
+
+<para>
+This is NEVER guaranteed under &unix;. It is quite common
+for a &unix; user to pipe and redirect program input and output:
+</para>
+
+<screen>&prompt.user; <userinput>program1 | program2 | program3 &gt; file1</userinput></screen>
+
+<para>
+If you have written <application>program2</application>, your input
+does not come from the keyboard but from the output of
+<application>program1</application>. Similarly, your output does not
+go to the screen but becomes the input for
+<application>program3</application> whose output, in turn,
+goes to <filename>file1</filename>.
+</para>
+
+<para>
+But there is more! Even if you made sure that your input comes
+from, and your output goes to, the terminal, there is no guarantee
+the terminal is a PC: It may not have its video memory
+where you expect it, nor may its keyboard be producing
+<acronym>PC</acronym>-style scan codes. It may be a &macintosh;,
+or any other computer.
+</para>
+
+<para>
+Now you may be shaking your head: My software is in
+<acronym>PC</acronym> assembly language, how can
+it run on a &macintosh;? But I did not say your software
+would be running on a &macintosh;, only that its terminal
+may be a &macintosh;.
+</para>
+
+<para>
+Under &unix;, the terminal does not have to be directly
+attached to the computer that runs your software, it can
+even be on another continent, or, for that matter, on another
+planet. It is perfectly possible that a &macintosh; user in
+Australia connects to a &unix; system in North America (or
+anywhere else) via <application>telnet</application>. The
+software then runs on one computer, while the terminal is
+on a different computer: If you try to read the scan codes,
+you will get the wrong input!
+</para>
+
+<para>
+Same holds true about any other hardware: A file you are reading
+may be on a disk you have no direct access to. A camera you are
+reading images from may be on a space shuttle, connected to you
+via satellites.
+</para>
+
+<para>
+That is why under &unix; you must never make any assumptions about
+where your data is coming from and going to. Always let the
+system handle the physical access to the hardware.
+</para>
+
+<note>
+<para>
+These are caveats, not absolute rules. Exceptions are possible.
+For example, if a text editor has determined it is running
+on a local machine, it may want to read the scan codes
+directly for improved control. I am not mentioning these caveats
+to tell you what to do or what not to do, just to make you aware
+of certain pitfalls that await you if you have just arrived to &unix;
+form <acronym>&ms-dos;</acronym>. Of course, creative people often break
+rules, and it is OK as long as they know they are breaking
+them and why.
+</para>
+</note>
+
+</sect2>
+
+</sect1>
+
+
+<sect1 xml:id="x86-acknowledgements">
+<title>Acknowledgements</title>
+
+<para>
+This tutorial would never have been possible without the
+help of many experienced FreeBSD programmers from the
+&a.hackers;, many of whom have patiently
+answered my questions, and pointed me in the right direction
+in my attempts to explore the inner workings of &unix;
+system programming in general and FreeBSD in particular.
+</para>
+
+<para>
+Thomas M. Sommers opened the door for me. His
+<link xlink:href="http://user.nj.net/~tms/hello.html">How
+do I write "Hello, world" in FreeBSD assembler?</link>
+web page was my first encounter with an example of
+assembly language programming under FreeBSD.
+</para>
+
+<para>
+Jake Burkholder has kept the door open by willingly
+answering all of my questions and supplying me with
+example assembly language source code.
+</para>
+
+<para>
+Copyright &copy; 2000-2001 G. Adam Stanislav. All rights reserved.
+</para>
+
+</sect1>
+
+
+</chapter>
diff --git a/zh_TW.UTF-8/books/faq/Makefile b/zh_TW.UTF-8/books/faq/Makefile
new file mode 100644
index 0000000000..8f5b9cf136
--- /dev/null
+++ b/zh_TW.UTF-8/books/faq/Makefile
@@ -0,0 +1,27 @@
+#
+# $FreeBSD$
+#
+# Build the FreeBSD Chinese FAQ
+#
+
+MAINTAINER=vanilla@FreeBSD.org ijliao@FreeBSD.org clive@FreeBSD.org \
+ clsung@FreeBSD.org chinsan@FreeBSD.org
+
+DOC?= book
+
+FORMATS?= html-split html
+
+INSTALL_COMPRESSED?= gz
+INSTALL_ONLY_COMPRESSED?=
+
+WITH_BIBLIOXREF_TITLE?=YES
+#
+# SRCS lists the individual XML files that make up the document. Changes
+# to any of these files will force a rebuild
+#
+
+# XML content
+SRCS= book.xml
+
+DOC_PREFIX?= ${.CURDIR}/../../..
+.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/books/faq/book.xml b/zh_TW.UTF-8/books/faq/book.xml
new file mode 100644
index 0000000000..331d6f5653
--- /dev/null
+++ b/zh_TW.UTF-8/books/faq/book.xml
@@ -0,0 +1,11876 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book PUBLIC "-//FreeBSD//DTD DocBook XML V4.5-Based Extension//EN"
+ "../../../share/xml/freebsd45.dtd" [
+<!ENTITY bibliography SYSTEM "../../../share/xml/bibliography.xml">
+]>
+
+<!-- The FreeBSD Traditional Chinese Documentation Project -->
+<!-- Original Revision: 1.772 -->
+
+<book lang='zh_tw'>
+ <bookinfo>
+ <title>FreeBSD 5.X、6.X 常見問答集</title>
+
+ <corpauthor>FreeBSD 文件計畫</corpauthor>
+
+ <copyright>
+ <year>1995</year>
+ <year>1996</year>
+ <year>1997</year>
+ <year>1998</year>
+ <year>1999</year>
+ <year>2000</year>
+ <year>2001</year>
+ <year>2002</year>
+ <year>2003</year>
+ <year>2004</year>
+ <year>2005</year>
+ <year>2006</year>
+ <year>2007</year>
+ <year>2008</year>
+ <holder>FreeBSD 文件計畫</holder>
+ </copyright>
+
+ &legalnotice;
+
+ <legalnotice id="trademarks" role="trademarks">
+ &tm-attrib.freebsd;
+ &tm-attrib.3com;
+ &tm-attrib.adobe;
+ &tm-attrib.creative;
+ &tm-attrib.cvsup;
+ &tm-attrib.ibm;
+ &tm-attrib.ieee;
+ &tm-attrib.intel;
+ &tm-attrib.iomega;
+ &tm-attrib.linux;
+ &tm-attrib.microsoft;
+ &tm-attrib.mips;
+ &tm-attrib.netscape;
+ &tm-attrib.opengroup;
+ &tm-attrib.oracle;
+ &tm-attrib.sgi;
+ &tm-attrib.sparc;
+ &tm-attrib.sun;
+ &tm-attrib.usrobotics;
+ &tm-attrib.xfree86;
+ &tm-attrib.general;
+ </legalnotice>
+
+ <releaseinfo>$FreeBSD$</releaseinfo>
+
+ <abstract>
+ <para>這份文件是 FreeBSD 5.X 及 6.X 的常見問答集。
+ 除非有特別加註,否則這些項目都適用於 FreeBSD 5.0 及以後的版本。
+ (如果條目內容中有 &lt;XXX&gt; 則是尚未完成中譯的部份。)
+ 如果您對協助本文件/翻譯計畫的進行有興趣的話,請寄 e-mail 到
+ &a.doc;。此外,隨時可從 <ulink
+ url="http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/faq/index.html">
+ FreeBSD 網站</ulink> 拿到這份文件的最新版本。
+ 也可以利用 HTTP 來下載一份龐大的 <ulink url="book.html">HTML</ulink>
+ 文件,或是經由 <ulink url="ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/">
+ FreeBSD FTP 站</ulink> 下載純文字、&postscript;、或 PDF 版本的檔案。
+ 您也可以在這裡使用 <ulink
+ url="&url.base;/search/search.html">搜尋資料</ulink> 的功能。</para>
+ </abstract>
+ </bookinfo>
+
+ <chapter id="introduction">
+ <chapterinfo>
+ <author>
+ <firstname>Ying-Chieh</firstname>
+ <surname>Liao</surname>
+ <affiliation>
+ <address><email>ijliao@FreeBSD.org</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>前言、一般問題</title>
+
+ <para>歡迎使用 FreeBSD 4.X-6.X FAQ!</para>
+
+ <para>跟其他 Usenet 上的 FAQ 一樣,這份文件涵蓋了有關 FreeBSD
+ 這套作業系統最常被問到的問題 (當然包括了回答!)。
+ 雖然說我們本來的目的是為了減少網路頻寬的浪費,
+ 以及避免同樣的問題一再出現,但事實上 FAQ
+ 已被公認為是值得閱讀的文件資源。</para>
+
+ <para>我們已經儘可能地使這份 FAQ 更豐富了。如果您對如何改善、
+ 進步方面有任何建議,請隨時寄電子郵件給 &a.doc;。</para>
+
+ <qandaset>
+ <qandaentry>
+ <question id="what-is-FreeBSD">
+ <para>什麼是 FreeBSD?</para>
+ </question>
+
+ <answer>
+ <para>簡單地來說,FreeBSD 是一套可以在 Alpha/AXP, AMD64 及
+ &intel; EM64T, &i386; IA-64, PC-98, &ultrasparc; 上執行的
+ UN*X-like 作業系統,它是根據 U.C. Berkeley 所開發出來的
+ <quote>4.4BSD-Lite</quote>,並加上了許多 <quote>4.4BSD-Lite2</quote>
+ 的增強功能。它同時也間接使用了 U.C. Berkeley 所開發出來並由
+ William Jolitz 移植到 i386 的 <quote>Net/2</quote>,也就是
+ <quote>386BSD</quote>,
+ 不過現在 386BSD 的程式碼只剩下極少數還留存在 FreeBSD 中。
+ 您可以在 <ulink url="&url.base;/index.html">FreeBSD 首頁
+ </ulink> 找到 FreeBSD 以及它可以幫您做些什麼的相關資訊。</para>
+
+ <para>FreeBSD 已被廣泛地被世界各地的公司行號、ISP、研究人員、
+ 電腦專家、學生,以及家庭用戶所使用,用在工作、教育以及娛樂上。</para>
+
+ <para>如果想看關於 FreeBSD 更深入的資料,請看
+ <ulink url="&url.books.handbook;/index.html">FreeBSD 使用手冊
+ </ulink>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="FreeBSD-goals">
+ <para>發展 FreeBSD 的目的是什麼?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 計畫的目的是提供可以任意使用且沒有限制的軟體。
+ 我們在程式碼 (以及計晝本身) 上付出了大量心血,
+ 當然不會介意來點金錢上的回饋,不過我們絕對不會如此堅持。
+ 我們相信我們首要的<quote>任務</quote>
+ 就是提供程式碼給每一個使用者,
+ 不管他們打算用來幹嘛;這麼一來,
+ 這些程式碼才能被用在最多地方,也才能發揮它們最大的效益。
+ 我們相信這就是自由軟體最基本的目標之一,
+ 而且我們會盡全力去支持它。</para>
+
+ <para>在我們 source tree 中有部份的程式碼是採用所謂的 <ulink
+ url="http://www.FreeBSD.org/copyright/COPYING">GPL</ulink> 或是
+ <ulink url="http://www.FreeBSD.org/copyright/COPYING.LIB">LGPL
+ </ulink> 版權宣告,
+ 雖然這些版權宣告是用來保障而非限制使用者的權利,
+ 畢竟是不那麼自由了些。
+ 由於這些 GPL 的軟體在商業使用上會引起非常複雜的版權問題,
+ 因此只要有機會,我們會盡量以採用比較寬鬆的
+ <ulink url="http://www.FreeBSD.org/copyright/freebsd-license.html">
+ FreeBSD 版權</ulink>的軟體來取代這些 GPL 版權宣告的軟體。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="bsd-license-restrictions">
+ <para>FreeBSD 版權有任何限制嗎?</para>
+ </question>
+
+ <answer>
+ <para>有的。但是這並不是限制你怎麼去使用這些程式碼,而是你怎麼看待
+ FreeBSD 這個計畫。如果你有版權焦慮症的話,請閱讀<ulink
+ url="http://www.FreeBSD.org/copyright/freebsd-license.html">
+ 版權本文</ulink>。簡單地來說,這份版權的重點可以條列如下。</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>請勿宣稱是您寫了這個程式。</para>
+ </listitem>
+
+ <listitem>
+ <para>如果它出問題了,不要控告我們。</para>
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="replace-current-OS">
+ <para>FreeBSD 可以取代我現在在用的作業系統嗎?</para>
+ </question>
+
+ <answer>
+ <para>對大部份的人來說是這樣沒錯,
+ 但事實上這問題並沒有這麼好回答。</para>
+
+ <para>大部份的人並不是真正在使用一個作業系統。
+ 他們使用的是應用程式;而那些應用程式才是真正用到作業系統的東西。
+ FreeBSD 是設計用來提供一個強韌且功能完整的作業環境給應用程式來執行。
+ 它支援了多種瀏覽器,辦公室套件軟體,電子郵件閱讀軟體,繪圖程式,
+ 程式設計環境,網路伺服器軟體,以及幾乎所有你想要的東西。
+ 大部份的程式都可以靠 <ulink
+ url="http://www.freebsd.org/ports/">Ports Collection</ulink>
+ 來管理。</para>
+
+ <para>但是如果你想要使用的應用程式只能在某個特定的作業系統上面執行
+ 的話,你就不能輕易地把它換掉,或者指望在 FreeBSD 上有很相似的應用
+ 程式才有機會。如果你想要的是一個強健的辦公室或是網路伺服器,或是
+ 一部穩定的工作站,或是想在不被中斷的環境下工作的話,FreeBSD 無疑
+ 是您的最佳選擇。世界各地有很多使用者,包括初學或資深的 &unix; 管理
+ 人員都選用 FreeBSD 當他們唯一的桌上作業系統。</para>
+
+ <para>如果你是從其他的 &unix; 環境轉換到 FreeBSD 的話,
+ 基本上是大同小異的。但是如果你之前用的是圖形界面的作業系統,
+ 例如說是 &windows; 或是比較古老的 &macos; 的話,
+ 可能就要多花一點時間來學習怎麼用 &unix; 的方式來做。
+ 你可以從這份 FAQ 和 <ulink
+ url="&url.books.handbook;/index.html">
+ FreeBSD 使用手冊</ulink> 來入門。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="why-called-FreeBSD">
+ <para>為什麼要叫做 FreeBSD?</para>
+ </question>
+
+ <answer>
+ <itemizedlist>
+ <listitem>
+ <para>您可以免費使用它,即使是用於商業用途。</para>
+ </listitem>
+
+ <listitem>
+ <para>整個 FreeBSD 作業系統完整的原始程式都可以免費取得,而且不
+ 管是在使用,散佈或是整合進其他程式等各方面也只受到最小的限
+ 制 (不論是否用於商業用途)。</para>
+ </listitem>
+
+ <listitem>
+ <para>任何人都可以自由地把他對系統的改良或錯誤修正的程式碼加入
+ source tree 之中 (當然要符合幾個先決條件)。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>特別值得注意的是這裡的 <quote>free</quote> 出現了兩次,而且它們
+ 的意思是不一樣的:一種代表 <quote>免費</quote>,另一種代表
+ <quote>自由</quote>。您可以拿 FreeBSD 去做任何您想要做的事,除了一些
+ <emphasis>例外</emphasis>,例如您宣稱 FreeBSD 是您寫的。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="differences-to-other-bsds">
+ <para>FreeBSD 及 NetBSD, OpenBSD 以及其他
+ open source BSD 作業系統之間有何不同之處呢?</para>
+ </question>
+
+ <answer>
+ <para>James Howard 在 <ulink url="http://www.daemonnews.org/">
+ DaemonNews</ulink> 上面寫了 <ulink
+ url="http://ezine.daemonnews.org/200104/bsd_family.html">
+ The BSD Family Tree</ulink> 的文件,裡面說明了這些歷史淵源及這些
+ *BSD 家族計畫之間的差異。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="latest-version">
+ <para>最新版的 FreeBSD 是那一版?</para>
+ </question>
+
+<!--
+ This answer is a hack to deal with the fact that for now there are
+ multiple "latest" versions of FreeBSD.
+ 這個有點難以回答,事實上 FreeBSD 有許多種類的『最新版』。
+-->
+
+ <answer>
+ <para>就 FreeBSD 目前的發展而言,有兩個主要發展分支:
+ 由 <emphasis>5-STABLE</emphasis> 所發行(release)的 5.X 系列、
+ 由 <emphasis>6-STABLE</emphasis> 所發行(release)的 6.X
+ 系列這兩個分支。</para>
+
+ <para>在 5.3 release 之前,4.X 系列仍屬
+ <emphasis>-STABLE</emphasis> 分支。
+ 自從 5.3 開始,5.X 系列開始規劃新的
+ <emphasis>-STABLE</emphasis> 分支發展重點,
+ 而 4.X 將只著重在重大問題上(比如:漏洞修補、安全維護)
+ 以及所謂的 &quot;extended support&quot;
+ ,不再會有新的突破性發展。另一方面,5-STABLE
+ 分支雖然仍將繼續發行,但是由於它只是 “legacy” 過渡期分支,
+ 所以大多數主力都已轉移到 6-STABLE 繼續開發。</para>
+
+<!-- note: the entity definitions are out of date -->
+ <para>於 &rel.current.date; 所發行的 <ulink
+ url="ftp://ftp.FreeBSD.org/pub/FreeBSD/releases/i386/&rel.current;-RELEASE">&rel.current;</ulink>
+ 版是目前最新的 <emphasis>6-STABLE</emphasis> 分支;
+ 而於 &rel2.current.date; 所發行的 <ulink
+ url="ftp://ftp.FreeBSD.org/pub/FreeBSD/releases/i386/&rel2.current;-RELEASE/">&rel2.current;</ulink>
+ 版則是目前最新的 <emphasis>5-STABLE</emphasis> 分支。</para>
+
+ <para>簡單地來說,<emphasis>-STABLE</emphasis> 的主要訴求對象是對於
+ 穩定性及低變異性的需求遠勝過對最新 <emphasis>-CURRENT</emphasis>
+ snapshot 中特別新功能的需求,例如 ISP 或公司行號的使用者。這兩個
+ branch 都有可能會產生 release 版,但只有當你能接受
+ <emphasis>-CURRENT</emphasis> 遠比 <emphasis>-STABLE</emphasis>
+ 容易更動這一點,才應該用 <emphasis>-CURRENT</emphasis>。</para>
+
+ <para>Release 版<link linkend="release-freq">每幾個月</link>才會發
+ 行一次。雖然如此,有很多人和 FreeBSD 原始碼同步更新(詳見
+ <link linkend="current">&os.current;</link> 和 <link
+ linkend="stable">&os.stable;</link> 的相關問題),但因為原始碼
+ 是一直不斷地在變動的,所以如果要這麼做的話得要花上更多的精
+ 力。</para>
+
+ <para>其他更多相關 FreeBSD 發行情報,可由 FreeBSD 網站上的 <ulink
+ url="http://www.FreeBSD.org/releng/index.html">
+ Release Engineering</ulink> 得知。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="current">
+ <para>什麼是 &os.current;?</para>
+ </question>
+
+ <answer>
+ <para><ulink
+ url="&url.books.handbook;/cutting-edge.html#CURRENT">
+ &os.current;</ulink> 指的是正在發展中的作業系統版本,
+ 它終將在適當的時機成為 &os.stable; 分支。
+ 它實在是只適合給系統發展者以及有毅力的業餘愛好者使用。
+ 如果想要得到有關如何使用 -CURRENT 的深入資訊,請參考 <ulink
+ url="&url.books.handbook;/index.html">使用手冊</ulink> 的 <ulink
+ url="&url.books.handbook;/cutting-edge.html#CURRENT">相關部份
+ </ulink>。</para>
+
+ <para>如果您對作業系統本身並不是很熟悉,或是您沒辦法分辨您遇到的問
+ 題是真的發生了問題亦或是暫時性的小狀況,那麼您就不應該使用
+ &os.current;。這個分支的程式碼有時候變動得很快,而且可能會因此
+ 而使您有好幾天的時間無法更新您的系統。我們假設使用
+ &os.current; 的使用者都有能力去分析他們所遇到的問題並且只回報
+ 真正的問題而非<quote>小狀況</quote>。如果您在 -CURRENT mailing
+ list 中提到類似<quote>make world 造成一些有關 groups 的錯
+ 誤</quote>之類的問題的話,也許會被其他人輕視。</para>
+
+ <para>我們每天都會根據目前 -CURRENT 和 -STABLE 的狀況對這兩個分支各
+ 發行一個 <ulink url="&url.base;/snapshots/">snapshot
+ </ulink> 版。有的時候甚至還會發行可供取得的版本。發表這些 snapshot
+ 的目的在於:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>測試最新版的安裝程式。</para>
+ </listitem>
+
+ <listitem>
+ <para>提供一個簡單的方法給那些喜歡使用 -CURRENT 或是 -STABLE,
+ 但是沒有時間和頻寬去每天昇級的使用者。</para>
+ </listitem>
+
+ <listitem>
+ <para>為了替我們發展中的程式保留一個固定的參考點,以防止我們未
+ 來造成不幸。(雖然一般而言 CVS 可以防止類似這種的可怕事件 :)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>為了確保所有需要測試的新功能都可以得到最多的測試。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>我們不對 -CURRENT snapshot 做任何形式的<quote>品質保
+ 證</quote>。如果你想要的是一個穩定且經過充分測試過的系統的話,
+ 最好選擇使用完整 release 的版本,或是使用 -STABLE snapshots。</para>
+
+ <para>您可以直接從 <ulink
+ url="&url.base;/snapshots/">
+ snapshots</ulink> 處取得 -CURRENT 的
+ snapshot release。</para>
+
+ <para>對每個有在活動的分支而言,平均每天都會產生一次 snapshots。
+ </para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="stable">
+ <para>什麼是 &os.stable;?</para>
+ </question>
+
+ <answer>
+ <para>回溯到 FreeBSD 2.0.5 剛發表的時候,我們決定把 FreeBSD 的發展
+ 分成兩支。一支叫做 <ulink
+ url="&url.books.handbook;/current-stable.html#STABLE">-STABLE
+ </ulink>,我們只對它做錯誤修正及小幅度的修改 (這是給 ISP
+ 和商業公司等,對實驗中功能不感興趣的單位所使用的)。
+ 另外一支叫做 <ulink
+ url="&url.books.handbook;/current-stable.html#CURRENT">-CURRENT
+ </ulink>,從 2.0 版發行以後,就不斷地朝著 6.2-RELEASE
+ (含後續的版本)前進著。</para>
+
+ <para>6-STABLE 分支是從 6.0-RELEASE 開始 (5-STABLE 分支算是
+ 5.3-RELEASE 之後才開始的),然後原本的 &os.current;
+ 就會成為 7-CURRENT。</para>
+
+
+ <para>2.2-STABLE 這個分支隨著 2.2.8 的發表而功成身退。3-STABLE 這個
+ 分支則是結束在 3.5.1 發表之後,它也是 3.X 的最後一次發表。之後除了
+ 安全漏洞的後續修正之外,這些分支就幾乎沒有再更動過。 而
+ 5-STABLE 分支的支援將仍持續一段時間,
+ 但主要焦點僅在於安全方面的漏洞、臭蟲及其他嚴重問題的修補。</para>
+
+ <para>6-STABLE 是目前正在發展中的 -STABLE 分支。 6-STABLE
+ 的最新的一次發表是在 &rel.current.date; 發行的
+ &rel.current;-RELEASE。</para>
+
+ <para>7-CURRENT 這個分支是 &os; 的 -CURRENT 分支,
+ 仍然不斷地在發展當中。 如果想要知道更多關於這個分支的資訊的話,
+ 請參考 <link
+ linkend="current">什麼是 &os;-CURRENT?</link>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="naming">
+ <para>FreeBSD 版本命名原則是什麼呢?</para>
+ </question>
+
+ <answer>
+ <para>您可能會看到以下幾種 FreeBSD 的版本名稱:</para>
+ <itemizedlist>
+ <listitem>
+ <para>1) 4.4.2-RELEASE、4.4-BETA:最前面的數字 A.B.C 裡,
+ A 表示主要的作業系統版本(Major),
+ B 表示次要的作業系統版本(Minor),
+ C 表示些微修正版本(Patch)。 後面的英文表示是否為正式版,
+ 通常是測試版(ALPHA、BETA、GAMMA)、正式版(RELEASE)。</para>
+ </listitem>
+
+ <listitem>
+ <para>2) 6.0-STABLE、7.0-CURRENT:
+ 通常 FreeBSD 會有一個以發展新功能為主的版本,稱為 -CURRENT
+ ,目前 CURRENT 版本是 7.0; FreeBSD
+ 也會有一個以維護穩定性及系統安全為主的版本,稱為 -STABLE,
+ 目前 STABLE 的版本是 6.0。 雖然如此,並不代表 -STABLE
+ 就沒有新功能,也不代表 _CURRENT 就不穩定不安全,
+ 這兩個版本是相輔相成的,而且終有一天 7.0-CURRENT
+ 會變成 7.0-STABLE,而開始 8.0-CURRENT 的發展。 不過一般來說,
+ 由於 -CURRENT 系統開發的速度相當快,跟 -STABLE
+ 相比較不穩定,而且最好是有相當經驗的使用者才來使用。
+ 如果是商業環境或是伺服器站台,最好還是跑 -STABLE 與
+ -RELEASE 比較好。 由於 -STABLE 與 -CURRENT
+ 都是一直在開發維護中的版本,
+ 因此沒有一個特定的數字版本可以稱呼,
+ 因此通常我們會以編譯日期來代表是哪個時候的 -STABLE 或 -CURRENT
+ ,例如「4.4-STABLE、編譯日期 2001/10/08」。</para>
+ </listitem>
+
+ <listitem><para>
+3) 5.0-011025-SNAP、4.2-010816-RELENG:
+ SNAP 與 RELENG 並不是正式發行的版本,其中 3.0-970625-SNAP 表示是
+ 在 2001 年 10 月 25 日發行的 5.0 測試版(SNAPshot),通常是指 CURRENT
+ 的版本。而 4.2-010816-RELENG 表示是在 2001 年 8 月 16 日發行的
+ 4.2 非正式的穩定版,通常是指 STABLE 的版本。
+ 通常 FreeBSD 核心小組會不定時釋出 SNAP 以供測試,然後有一天 SNAP
+ 會變成 ALPHA->BETA->GAMMA,再來是 RELEASE,而後可能會有不定時的
+ RELENG 以供測試使用,但是 RELENG 的穩定性通常又比前期的 RELEASE
+ 來的好。</para>
+ </listitem>
+ </itemizedlist>
+
+<para>
+您要是習慣微軟的術語,這樣說好了,SNAP 是開發期間的內部流出版,
+那個日期(011025)就是Build Number,而 ALPHA 與 BETA 是搶鮮版,
+RELEASE(RELENG 勉強也算)是正式版,這樣應該了解了吧。
+</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="release-freq">
+ <para>每次新的 FreeBSD 將於什麼時候推出?</para>
+ </question>
+
+ <answer>
+ <para>一般而言,&a.re; 平均每四個月發行一次 release,每次新版本的發表時程都會事先公告,
+ 相關的開發人員就會知道,什麼時候該先把手邊的計劃完成並且測試過,
+ 此外,這些更動都已經完整地測試過,且不會影響系統穩定度。
+ 雖然,等這些好東西進入 -STABLE 的時間令人等得有些不耐煩,
+ 但是大多數的使用者都認為這種謹慎的態度是 FreeBSD 最好的優點之一。</para>
+
+ <para>有關發行情報的更多細節部分(包括 release 的行程表、進度),都可在 FreeBSD 網站上的
+ <ulink url="http://www.FreeBSD.org/releng/index.html">發行情報</ulink> 上面獲得。</para>
+
+ <para>為了滿足那些需要 (或想要) 新鮮刺激感的使用者,
+ 上面(-CURRENT的部分)已經提到我們每天都會發行 snapshots 版可供使用。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="responsible">
+ <para>誰負責 FreeBSD 的發展?</para>
+ </question>
+
+ <answer>
+ <para>如果是一些有關 FreeBSD 計畫的關鍵性決定,像是整個計畫的走向
+ 或是決定誰可以改 source tree 裡的程式碼這類的事,是由一個由 9 個
+ 人所組成的 <ulink
+ url="&url.articles.contributors;/article.html#STAFF-CORE">core
+ team</ulink> 來決定。而有另一群超過 300 個人的 <ulink
+ url="&url.articles.contributors;/article.html#STAFF-COMMITTERS">
+ commiters</ulink> 有權利可以直接修改 FreeBSD 的 source tree。
+ </para>
+
+ <para>無論如何,大多數的改變都會事前在 <link linkend="mailing">
+ mailing lists</link> 先討論過,而且不分角色,每個人都可以參與討論。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="where-get">
+ <para>我要如何取得 FreeBSD?</para>
+ </question>
+
+ <answer>
+ <para>每個 FreeBSD 的重要版本都可以經由匿名 ftp 從 <ulink
+ url="ftp://ftp.FreeBSD.org/pub/FreeBSD/">FreeBSD FTP 站</ulink>取得:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>如果需要 6-STABLE 的最新版,也就是 &rel.current;-RELEASE,請到 <ulink
+ url="ftp://ftp.FreeBSD.org/pub/FreeBSD/releases/i386/&rel.current;-RELEASE/">&rel.current;-RELEASE </ulink>這個目錄</para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="ftp://current.FreeBSD.org/pub/FreeBSD/">7-CURRENT Snapshot</ulink>
+ 通常也是每天都會做一份,這是從 <link linkend="current">-CURRENT</link> 分支做出來的,
+ 主要是為了提供給那些熱心的測試者和開發人員。</para>
+ </listitem>
+
+ <listitem>
+ <para>如果需要 5-STABLE 的最新版,也就是 &rel2.current;-RELEASE,請到 <ulink
+ url="ftp://ftp.FreeBSD.org/pub/FreeBSD/releases/i386/&rel2.current;-RELEASE/">&rel2.current;-RELEASE </ulink>這個目錄</para>
+ </listitem>
+
+ <listitem>
+ <para><ulink
+ url="ftp://current.FreeBSD.org/pub/FreeBSD/snapshots/">5.X、6X snapshots</ulink>
+ 通常每天都會做一份。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>FreeBSD 的 CD、DVD,還有其他取得方式可以在 <ulink url="&url.books.handbook;/mirrors.html">使用手冊</ulink> 中找到解答。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="access-pr">
+ <para>我要如何去查詢、提交問題回報(Problem Report,簡稱PR)資料庫呢?</para>
+ </question>
+
+ <answer>
+ <para>所有使用者的變更要求都可以經由網頁介面的
+ <ulink url="http://www.FreeBSD.org/cgi/query-pr-summary.cgi?query">
+ PR查詢介面</ulink> 來察看 (或是回報) 我們的錯誤回報資料庫。</para>
+
+ <para>也可以使用 &man.send-pr.1; 這個指令透過電子郵件來回報問題、要求變更。
+ 或者是經由 <ulink url="http://www.FreeBSD.org/send-pr.html">網頁介面的 PR</ulink> 來送出問題回報。</para>
+
+ <para>然而,在您回報問題之前,請先閱讀 <ulink
+ url="&url.articles.problem-reports;/article.html">如何撰寫
+ FreeBSD 的問題回報單</ulink>,這是一篇告訴你怎樣才能寫出一篇真正有用的
+ 問題回報單。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="other-info-sources">
+ <para>還有其他有關 FreeBSD 的資訊嗎?</para>
+ </question>
+
+ <answer>
+ <para>詳見 <ulink
+ url="http://www.FreeBSD.org">FreeBSD</ulink> 網站上的 <ulink
+ url="http://www.FreeBSD.org/docs.html">文件</ulink> 列表。</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+ <chapter id="support">
+ <chapterinfo>
+ <author>
+ <firstname>Chin-San</firstname>
+ <surname>Huang</surname>
+ <affiliation>
+ <address><email>chinsan.tw@gmail.com</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>文件與技術支援</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="books">
+ <para>關於 FreeBSD 有哪些好書可以推薦閱讀的嗎?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 文件計畫已陸續發表了相當廣泛範圍的文件,可在 <ulink
+ url="http://www.FreeBSD.org/docs.html"></ulink> 取得。另外,
+ FreeBSD 本身的 manual(一般通稱的man)、doc也如同套件軟體一樣,可以輕鬆地裝在您系統上。
+ </para>
+
+ <para>此外,也建議參閱本份 FAQ 最後所列的參考書目表(Bibliography)與 FreeBSD 使用手冊。
+ </para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="doc-formats">
+ <para>這些文件有其他格式的嗎?像是:純文字(ASCII)或 &postscript; 之類的格式?</para>
+ </question>
+
+ <answer>
+ <para>有的。這些文件都分別以不同格式儲存以及壓縮處理,放在
+ FTP 上面,可以從各 FreeBSD FTP 站的 <ulink
+ url="ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/">/pub/FreeBSD/doc/</ulink>
+ 目錄內找到你要的。</para>
+
+ <para>文件的分類方面主要是一些不同性質所組成:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>文件名稱,比如:<literal>faq(常見問答集)</literal>或是
+ <literal>handbook(FreeBSD 使用手冊)</literal>等等。</para>
+ </listitem>
+
+ <listitem>
+ <para>各國翻譯的的文件:這主要是由 locale 名稱來決定的
+ (不清楚的話,可參考您的 FreeBSD 作業系統上的 <filename>/usr/share/locale</filename>)
+ 目前文件總共有下列幾種語言(及編碼)有翻譯:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Locale 名稱</entry>
+
+ <entry>說明(所代表的語系、編碼)</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>en_US.ISO8859-1</literal></entry>
+
+ <entry>美式英文(US English)</entry>
+ </row>
+
+ <row>
+ <entry><literal>de_DE.ISO8859-1</literal></entry>
+
+ <entry>德文(German)</entry>
+ </row>
+
+ <row>
+ <entry><literal>es_ES.ISO8859-1</literal></entry>
+
+ <entry>西班牙文(Spanish)</entry>
+ </row>
+
+ <row>
+ <entry><literal>fr_FR.ISO8859-1</literal></entry>
+
+ <entry>法文(French)</entry>
+ </row>
+
+ <row>
+ <entry><literal>it_IT.ISO8859-15</literal></entry>
+
+ <entry>義大利文(Italian)</entry>
+ </row>
+
+ <row>
+ <entry><literal>ja_JP.eucJP</literal></entry>
+
+ <entry>日文(Japanese,編碼方式:EUC)</entry>
+ </row>
+
+ <row>
+ <entry><literal>ru_RU.KOI8-R</literal></entry>
+
+ <entry>俄文(Russian,編碼方式:KOI8-R)</entry>
+ </row>
+
+ <row>
+ <entry><literal>zh_CN.GB2312</literal></entry>
+
+ <entry>簡體中文(Simplified Chinese,編碼方式:GB2312)</entry>
+ </row>
+
+ <row>
+ <entry><literal>zh_TW.UTF-8</literal></entry>
+
+ <entry>正體中文(Traditional Chinese,編碼方式:UTF-8)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <note>
+ <para>上列的各國翻譯語系文件中,並非所有文件都有翻譯。</para>
+ </note>
+ </listitem>
+
+ <listitem>
+ <para>文件的格式:每份文件都以各種不同格式儲存,每種格式都各有好壞,
+ 有些格式適合線上閱讀,而有些則適合列印出美觀的文件。
+ 我們都提供這些不同格式的文件,來確保無論是螢幕上、列印紙本,每個人都可以正常地閱讀內容,
+ 目前可供使用的格式如下:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>格式</entry>
+
+ <entry>說明</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>html-split</literal></entry>
+
+ <entry>章節模式</entry>
+ </row>
+
+ <row>
+ <entry><literal>html</literal></entry>
+
+ <entry>完整模式</entry>
+ </row>
+
+ <row>
+ <entry><literal>pdb</literal></entry>
+
+ <entry>Palm Pilot 資料格式,使用
+ <ulink url="http://www.iSilo.com/">iSilo</ulink>
+ 程式來閱讀</entry>
+ </row>
+
+ <row>
+ <entry><literal>pdf</literal></entry>
+
+ <entry>Adobe's PDF 格式</entry>
+ </row>
+
+ <row>
+ <entry><literal>ps</literal></entry>
+
+ <entry>&postscript; 格式</entry>
+ </row>
+
+ <row>
+ <entry><literal>rtf</literal></entry>
+
+ <entry>Microsoft's RTF格式<footnote>
+ <para>當使用 MS Word 來開啟 RTF 格式的話,頁數顯示並不會自動更新。
+ (在開啟文件後,要按 <keycombo
+ action="simul"><keycap>CTRL</keycap><keycap>A</keycap></keycombo>,
+ <keycombo
+ action="simul"><keycap>CTRL</keycap><keycap>END</keycap></keycombo>,
+ <keycap>F9</keycap>,這樣子才會更新頁數的顯示。)</para>
+ </footnote>
+ </entry>
+ </row>
+
+ <row>
+ <entry><literal>txt</literal></entry>
+
+ <entry>純文字(ASCII)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </listitem>
+
+ <listitem>
+ <para>文件的壓縮、打包方式:目前有三種方式:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>當採用
+ <literal>章節模式(html-split)</literal>,章節模式所產生的各檔案會先使用
+ &man.tar.1; 來壓縮。檔名結尾有 <filename>.tar</filename> 的檔案就是 tar 格式。
+ 接著,會再以下列方式再壓縮。
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>其他格式的檔案都會是單一檔案,檔名通常會是:
+ <filename>book.<replaceable>格式</replaceable></filename>
+ (舉例: <filename>book.pdb</filename>,
+ <filename>book.html</filename> 等等..後面通常加上『.格式』).</para>
+ <para>而這些檔案會分別以兩種壓縮型態進行壓縮,而存成兩種壓縮型態。</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>格式</entry>
+
+ <entry>說明</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>zip</literal></entry>
+
+ <entry>Zip 格式,若要在 FreeBSD 上解壓 zip 檔,則必須先安裝
+ <filename role="package">chinese/unzip</filename> 或
+ <filename role="package">archivers/unzip</filename>。
+ </entry>
+ </row>
+
+ <row>
+ <entry><literal>bz2</literal></entry>
+
+ <entry>BZip2 格式,雖然不如 zip 格式的廣泛使用,但是好處在於可壓縮成更小的檔案。
+ 要解壓 bz2 格式的話,需先安裝 <filename role="package">archivers/bzip2
+ </filename>。</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>所以像是 Handbook 的 &postscript; 版格式,會以 BZip2 格式壓縮,
+ 存放在 <filename>handbook/</filename> 目錄內,
+ 檔名就是<filename>book.ps.bz2</filename>。</para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+ </itemizedlist>
+
+ <para>選擇想要下載的文件格式與壓縮型態之後,則要決定是否以 FreeBSD <emphasis>套件(package)</emphasis>
+ 型態來下載。</para>
+
+ <para>下載、安裝『package』的好處在於:可以透過一般 FreeBSD
+ 套件管理方式來進行管理,比如 &man.pkg.add.1; 及
+ &man.pkg.delete.1;。</para>
+
+
+ <para>若決定好要下載、安裝『package』的話,必須要確認所要下載的檔名。
+ 文件計畫的套件(package)通常是放在是 <filename>packages</filename> 的目錄內,
+ 每個文件計畫的套件檔名通常是:
+ <filename><replaceable>文件名稱</replaceable>.<replaceable>語系</replaceable>.<replaceable>編碼</replaceable>.<replaceable>格式</replaceable>.tgz</filename>
+ 。</para>
+
+ <para>舉個例子,英文版的 FAQ (格式選擇 PDF)在 package 就叫做
+ <filename>faq.en_US.ISO8859-1.pdf.tgz</filename>。</para>
+
+ <para>再舉個例子,中文版的 FAQ (格式選擇 PDF)在 package 就叫做
+ <filename>faq.zh_TW.UTF-8.pdf.tgz</filename>。</para>
+
+ <para>知道這點之後,就可以用下面指令來安裝中文版 FAQ 套件:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/packages/faq.zh_TW.UTF-8.pdf.tgz</userinput></screen>
+
+ <para>完成之後,可以用 &man.pkg.info.1; 來找出檔案裝在哪邊:</para>
+
+ <screen>&prompt.root; <userinput>pkg_info -f faq.zh_TW.UTF-8.pdf</userinput>
+Information for faq.zh_TW.UTF-8.pdf:
+
+Packing list:
+ Package name: faq.zh_TW.UTF-8.pdf
+ CWD to /usr/share/doc/zh_TW.UTF-8/books/faq
+File: book.pdf
+ CWD to .
+File: +COMMENT (ignored)
+File: +DESC (ignored)</screen>
+
+ <para>如同您所看到的 <filename>book.pdf</filename> 會被安裝到
+ <filename>/usr/share/doc/zh_TW.UTF-8/books/faq</filename> 內。</para>
+
+ <para>若不想用 package 方式安裝,那麼就需手動下載、解壓縮、複製到你想要擺放的位置去。</para>
+
+ <para>舉例,章節模式(split HTML)版的英文 FAQ (壓縮為 &man.bzip2.1;)會放在
+ <filename>doc/en_US.ISO8859-1/books/faq/book.html-split.tar.bz2</filename>
+ 要下載、解壓的話,則要打:</para>
+
+ <screen>&prompt.root; <userinput>fetch ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/en_US.ISO8859-1/books/faq/book.html-split.tar.bz2</userinput>
+&prompt.root; <userinput>bzip2 -d book.html-split.tar.bz2</userinput>
+&prompt.root; <userinput>tar xvf book.html-split.tar</userinput></screen>
+
+ <para>這時你會看到一堆 <filename>.html</filename> 的檔案,
+ 主要的目錄檔為 <filename>index.html</filename>
+ 內含主目錄及連結到其他文件。(若有需要的話,也可以複製或搬移這些檔案到同一目錄下)</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="mailing">
+ <para>哪裡有關於 FreeBSD 的郵遞論壇(mailing lists)呢?</para>
+ </question>
+
+ <answer>
+ <para>這個問題,可以從 FreeBSD 使用手冊上面的 <ulink
+ url="&url.books.handbook;/eresources.html#ERESOURCES-MAIL">郵遞論壇(mailing-lists)</ulink>
+ 部分獲得答案。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="newsgroups">
+ <para>有哪些可以使用的 FreeBSD 新聞群組(news groups)呢?</para>
+ </question>
+
+ <answer>
+ <para>這答案可以從 FreeBSD 使用手冊上面的 <ulink
+ url="&url.books.handbook;/eresources-news.html">新聞群組(newsgroups)</ulink>
+ 部分獲得答案。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="man">
+ <para>在文件中常看到類似 "pf(4)"、"pfctl(8)" 等這些字樣代表什麼意思呢?</para>
+ </question>
+
+ <answer>
+ <para>這表示 man 的章節,系統上一般有八個章節:</para>
+ <itemizedlist>
+ <listitem>
+ <para>1->generl commands</para>
+ </listitem>
+
+ <listitem>
+ <para>2->system calls and error numbers </para>
+ </listitem>
+
+ <listitem>
+ <para>3->C libraries</para>
+ </listitem>
+
+ <listitem>
+ <para>4->devices and device drivers</para>
+ </listitem>
+
+ <listitem>
+ <para>5->file formats</para>
+ </listitem>
+
+ <listitem>
+ <para>6->games</para>
+ </listitem>
+
+ <listitem>
+ <para>7->miscellaneous information pages</para>
+ </listitem>
+
+ <listitem>
+ <para>8->system maintenance and operation commands</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>比如:pf(4) 就是指 <command>man 4 pf</command>。</para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="irc">
+ <para>有哪些 FreeBSD IRC (Internet Relay Chat)頻道呢?</para>
+ </question>
+
+ <answer>
+ <para>有的,大部分的 IRC 主機都有 FreeBSD 聊天頻道:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="http://www.efnet.org/index.php">EFNet</ulink> 的
+ <literal>#FreeBSD</literal> 頻道是個 FreeBSD 論壇,
+ 但可不適合那些想不勞而獲或者搬救兵用的。
+ 這裡是聊天用的頻道,話題範圍甚至涉及『性、運動、核武』等,
+ 請注意:我們已經警告過你了!本頻道可經由
+ <hostid>irc.chat.org</hostid> 進入。</para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="http://www.efnet.org/index.php">EFNet</ulink> 的
+ <literal>#FreeBSDhelp</literal> 頻道乃是給 FreeBSD
+ 使用者之間交流的,來這裡提問會比 <literal>#FreeBSD</literal>
+ 好一些,當然請不要一股腦隨便亂問。</para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="http://www.dal.net/">DALNET</ulink> 的
+ <literal>#FreeBSD</literal> 頻道,可由
+ <hostid>irc.dal.net</hostid>(位於美國)及
+ <hostid>irc.eu.dal.net</hostid>(位於歐洲)進入。</para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="http://www.dal.net/">DALNET</ulink> 的
+ <literal>#FreeBSDHelp</literal> 頻道,可由
+ <hostid>irc.dal.net</hostid>(位於美國)及
+ <hostid>irc.eu.dal.net</hostid>(位於歐洲)進入。</para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="http://www.undernet.org/">UNDERNET</ulink> 的
+ <literal>#FreeBSD</literal> 頻道,可由
+ <hostid>us.undernet.org</hostid>(位於美國)及
+ <hostid>eu.undernet.org</hostid>(位於歐洲)進入。
+ 由於這是個輔助新手用的頻道,
+ 請記得閱讀別人向你提及的連結或檔案。</para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="http://www.rusnet.org.ru/">RUSNET</ulink> 的
+ <literal>#FreeBSD</literal> 頻道是俄語國家的 &os; 使用者頻道。
+ 這裡同時也是一般交流的討論好去處。</para>
+ </listitem>
+
+ <listitem>
+ <para><ulink
+ url="http://freenode.net/irc_servers.shtml">freebsd-gnome
+ </ulink> 的 <literal>#FreeBSD</literal> 頻道,可由
+ <hostid>irc.freenode.net</hostid> 進入,
+ 這是 Gnome 的 &os; 使用者頻道。</para>
+ </listitem>
+
+ <listitem>
+ <para><ulink url="http://freenode.net/irc_servers.shtml">freenode</ulink>
+ 的 <literal>#bsdchat</literal> 頻道,可由
+ <hostid>irc.freenode.net</hostid> 進入,
+ 這是台灣的 &os; 使用者頻道。(UTF-8 編碼)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>上述每個頻道都不一樣,風格迥異而各具特色,且並沒有相連,
+ 因此,你得多方嘗試才能找到適合自己的頻道。
+ 而有些地方與所有的 IRC 文化類似,就是請注意自己言行是否恰當,
+ 另外可能跟頻道內一些年輕/老一輩的會有些代溝需要適應,
+ 總之請多保持禮貌。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="training">
+ <para>可以從哪邊獲得 FreeBSD 的教育課程訓練及技術支援呢?</para>
+ </question>
+
+ <answer>
+ <para>DaemonNews 有專門提供 FreeBSD 的教育課程訓練及技術支援。
+ 詳情請到 <ulink url="http://www.bsdmall.com/">BSD Mall</ulink>
+ 察看,謝謝。</para>
+
+ <para>FreeBSD Mall 有提供 BSD 技術支援付費服務,
+ 詳情請到 <ulink
+ url="http://www.freebsdmall.com/">FreeBSD Mall</ulink> 察看,謝謝。</para>
+
+
+ <para>其他任何有提供教育課程訓練及技術支援的組織、單位,若也想列表於此的話,
+ 請與 &a.doc; 聯絡,謝謝。</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+ <chapter
+ id="install">
+ <chapterinfo>
+ <author>
+ <firstname>Nik</firstname>
+ <surname>Clayton</surname>
+ <affiliation>
+ <address><email>nik@FreeBSD.org</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>安裝</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="floppy-download">
+ <para>若要用軟碟片開機來安裝 FreeBSD 的話,要下載哪些檔案呢?</para>
+ </question>
+
+ <answer>
+ <para>&os; 4.X 的話,需要兩個 image 檔:
+ <filename>floppies/kernel.flp</filename> 及
+ <filename>floppies/mfsroot.flp</filename>。image 檔必須用工具像是
+ <command>fdimage</command> 或 &man.dd.1; 來傳送到磁片上。
+ 若是在 &os; 5.3 (及之後版本)有重新規劃開機片架構,所以要抓的是
+ <filename>floppies/boot.flp</filename> 以及 <filename>floppies/kern<replaceable>X</replaceable></filename>
+ 檔案(目前 X 為 1 跟 2 兩個,加上 <filename>floppies/boot.flp</filename>,總共是 3 個檔案)。</para>
+
+ <para>若想自己下載 distributions 的話(比如以 &ms-dos; 檔案系統格式安裝),
+ 以下是建議要抓的 distributions :</para>
+
+
+ <itemizedlist>
+ <listitem>
+ <para>base/ (4.X 版本則為 bin/)</para>
+ </listitem>
+
+ <listitem>
+ <para>manpages/</para>
+ </listitem>
+
+ <listitem>
+ <para>compat*/</para>
+ </listitem>
+
+ <listitem>
+ <para>doc/</para>
+ </listitem>
+
+ <listitem>
+ <para>src/ssys.*</para>
+ </listitem>
+ </itemizedlist>
+
+
+ <para>完整安裝步驟以及大部分的安裝問題,請參閱 FreeBSD 使用手冊的
+ <ulink url="&url.books.handbook;/install.html">安裝 FreeBSD</ulink> 章節</para>
+
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="floppy-image-too-large">
+ <para>若磁片裝不下 image 檔的話,該怎麼辦呢?</para>
+ </question>
+
+ <answer>
+ <para>一張 3.5 英吋(1.44MB) 的磁碟片是可以裝上 1474560 bytes 的資料
+ ,而開機片的 image 檔案大小實際上也是 1474560 bytes。</para>
+
+ <para>在製作開機片時,常見錯誤有:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>使用 <acronym>FTP</acronym> 來下載檔案時,
+ 未選擇 <emphasis>binary</emphasis> 傳輸模式來下載。</para>
+
+
+ <para>有些 FTP client端程式,是預設將傳輸模式設定為
+ <emphasis>ascii</emphasis> 模式,而且會修改接收到的檔案行尾字串為 client 端的作業系統方式
+ ,比如 newline(&unix;格式) 到了作業系統為 &windows; 的 client 端會被改為 CR-LF(&ms-dos;格式),
+ 這會使得 image 檔本身遭到修改而無法正常使用。因此,如果下載的 image
+ 檔案大小若與 FTP 主機上面的檔案『<emphasis>不一致</emphasis>』
+ 的話,請重新使用 binary 傳輸模式下載即可。</para>
+
+ <para>FTP 指令: 進入 FTP 之後,打 <emphasis>binary</emphasis>
+ 指令,即可切換到 binary 傳輸模式,然後再下載相關 image 檔案。</para>
+ </listitem>
+
+ <listitem>
+ <para>直接用 &ms-dos; 的 <command>copy</command> 指令(或類似
+ 的 GUI 程式、或是視窗上直接複製)來複製開機用的 image 檔到磁片上。
+ </para>
+
+ <para>不可以用像是 <command>copy</command> 這類程式直接將 image
+ 檔複製到磁片上,因為 image 檔本身包含了完整的磁軌資料,所以不能單純用複製方式,
+ 而必須使用低階工具程式(像是 <command>fdimage</command> 或 <command>rawrite</command>),
+ 以 <quote>raw</quote> 方式傳送到磁片上。(這部分可參閱 FreeBSD 使用手冊上的 <ulink
+ url="&url.books.handbook;/install.html">安裝 FreeBSD</ulink>)</para>
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="install-instructions-location">
+ <para>可以在哪邊找到安裝 FreeBSD 的解說步驟呢?</para>
+ </question>
+
+ <answer>
+ <para>安裝步驟的解說,請參閱 FreeBSD 使用手冊上的
+ <ulink url="&url.books.handbook;/install.html">安裝 FreeBSD</ulink> 章節部分。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="need-to-run">
+ <para>要跑 FreeBSD 需要什麼的配備呢?</para>
+ </question>
+
+ <answer>
+ <para>&os; 4.X 之前的版本,硬體需求為 386 或更高級的 PC
+ ,記憶體(RAM)至少要 5 MB 或更多,硬碟空間至少要 60 MB 或更多。
+ 不過,&os; 『系統安裝程式』的記憶體(RAM)需求為至少 16 MB。</para>
+
+ <para>從 &os; 5.X 起,硬體需求為 486 或更高級的 PC
+ ,記憶體(RAM)至少要 24 MB 或更多,硬碟空間至少要 150 MB 或更多。
+ </para>
+
+ <para>&os; 的所有版本都可以只用低階的 MDA 規格顯示卡,不過...要跑 X11R6 視窗的話,
+ 還是至少用 VGA 或更好規格的顯示卡來用吧。</para>
+
+ <para>這部分也可參閱 <xref linkend="hardware"/>。</para>
+
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="four-meg-ram-install">
+ <para>我電腦 RAM 只有 4MB 而已,可以裝 FreeBSD 嗎?</para>
+ </question>
+
+ <answer>
+ <para>安裝 &os; 4.X 的記憶體需求為至少 5 MB ,而
+ 安裝 &os; 5.X (含之後版本) 則是至少要 8 MB 。</para>
+
+ <para>在 5.X 之前的所有 &os; 版本,都可以只用 4 MB 的記憶體來
+ <emphasis>『運作』</emphasis>,不過,前面那節我們說過了『系統安裝程式』的話,
+ 則無法只用 4 MB 的記憶體來執行。因此,你可以先在『系統安裝程式』這步驟之前,
+ 先將記憶體加到 16 MB 以上,安裝完 FreeBSD 之後,就可以把多餘的記憶體拿下來。
+ 或者是,先把要安裝的硬碟拿到有足夠記憶體的機器上先裝好,
+ 然後再把硬碟放回原機器。</para>
+
+ <para>此外,只用 4 MB 的記憶體來運作的話,必須要自製 kernel(拿掉不必要的以及犧牲一些東西)。
+ 也有人成功只用 2 MB 的記憶體以 &os; 開機(雖然這樣的系統幾乎等於廢了..)</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="custom-boot-floppy">
+ <para>要怎樣才能自行打造專用的開機、安裝磁片呢?</para>
+ </question>
+
+ <answer>
+ <para>目前,還沒有辦法<emphasis>『只』</emphasis>自製專用的開機、安裝磁片。
+ 必須透過自行打造完整作業系統的 release(發行),這樣裡面才會包括自己的開機、安裝磁片。</para>
+
+ <para>若想自行打造、發行(release)一個完整的作業系統,請參閱這篇
+ <ulink url="&url.articles.releng;/article.html">Release Engineering</ulink> 文章。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="windows-coexist">
+ <para>&windows; 可以與 FreeBSD 共存於電腦上嗎?</para>
+ </question>
+
+ <answer>
+ <para>先裝 &windows; 再裝 FreeBSD。
+ 那麼 FreeBSD 多重開機管理員(boot manager)就會出現選單讓你選擇要以 &windows; 或
+ FreeBSD 來開機。不過,若你是先裝 FreeBSD 再裝 &windows; 的話,
+ 那麼 &windows; 將會不問先宰,把 FreeBSD 的多重開機管理員(boot manager)蓋掉,
+ 當你遇上這種情況時,請參考下一節說明。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="win95-damaged-boot-manager">
+ <para>嗚.. &windows; 把我的多重開機管理員(boot manager)拿掉了!要怎麼救回來呢?</para>
+ </question>
+
+ <answer>
+ <para>可以用以下三種方式之一,來救回你的 FreeBSD 多重開機管理員(boot manager):</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>可以從各 FreeBSD FTP 站的 <ulink url="ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/">/pub/FreeBSD/tools/</ulink>
+ 找到 <filename>bootinst.exe</filename> 及 <filename>boot.bin</filename> 這兩個檔,
+ 以 binary 傳輸模式下載後,複製到磁片上,再用 DOS 開機片開機,
+ 接著打類似下面的指令:</para>
+
+ <screen><prompt>&gt;</prompt> <userinput>bootinst.exe boot.bin</userinput></screen>
+
+ <para>這樣,多重開機管理員(boot manager)就會重裝完畢了。</para>
+ </listitem>
+
+ <listitem>
+ <para>用 FreeBSD 開機片開機,然後選單那邊選 Custom installation(自訂安裝),
+ 再選 Partition,接著選擇你要裝多重開機管理員(boot manager)的硬碟(通常是第一顆),
+ 然後會出現 partition editor 的畫面,這時請不要做任何修改,直接按 W 儲存,
+ 這時程式就會問是否要確定 Write ,最後出現 Boot Manager 選擇畫面,
+ 記得要選 <quote>Boot Manager</quote> ,這樣就會重新將多重開機管理員(boot manager)
+ 安裝到硬碟上。現在,就大功告成可以離開安裝選單並重開機了。</para>
+ </listitem>
+
+ <listitem>
+ <para>用 FreeBSD 開機片或是開機光碟開機,然後選單那邊選 <quote>Fixit</quote>
+ ,或是以 Fixit 開機片或是光碟安裝的第二片(選擇 <quote>live</quote> filesystem
+ 選項)然後就會進入 fixit shell 了,接著打下列指令:</para>
+
+ <screen><prompt>Fixit#</prompt> <userinput>fdisk -B -b /boot/boot0 <replaceable>bootdevice</replaceable></userinput></screen>
+
+ <para>請將上面的 <replaceable>bootdevice</replaceable> 修改為您實際的開機硬碟代號
+ 比如 <devicename>ad0</devicename> (第一顆 IDE 硬碟)
+ ,或是<devicename>ad4</devicename> (first IDE disk on
+ auxiliary controller), <devicename>da0</devicename> (第一顆
+ SCSI 硬碟)等等。</para>
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="boot-on-thinkpad">
+ <para>IBM Thinkpad A系列、T系列或 X系列的筆記型電腦裝完 FreeBSD 之後重開機,就當了,該怎麼辦呢?</para>
+ </question>
+
+ <answer>
+ <para>(本問題主要是發生在 2000 ~ 2001 四月間時)這些 IBM 機器上的 BIOS 早期版本有個臭蟲(bug)會把
+ FreeBSD 分割區誤認為是 FAT 格式分割區,然後當 BIOS 試著偵測 FreeBSD 分割區時,就會當了。</para>
+
+ <para>根據 IBM 方面的說法<footnote><para>一封來自 Keith
+ Frechette 的 e-mail <email>kfrechet@us.ibm.com</email>。</para></footnote>
+ ,以下型號/BIOS版本的機種,已經都有修正:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>型號</entry>
+ <entry>BIOS 版本</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>T20</entry>
+ <entry>IYET49WW(含之後)</entry>
+ </row>
+
+ <row>
+ <entry>T21</entry>
+ <entry>KZET22WW(含之後)</entry>
+ </row>
+
+ <row>
+ <entry>A20p</entry>
+ <entry>IVET62WW(含之後)</entry>
+ </row>
+
+ <row>
+ <entry>A20m</entry>
+ <entry>IWET54WW(含之後)</entry>
+ </row>
+
+ <row>
+ <entry>A21p</entry>
+ <entry>KYET27WW(含之後)</entry>
+ </row>
+
+ <row>
+ <entry>A21m</entry>
+ <entry>KXET24WW(含之後)</entry>
+ </row>
+
+ <row>
+ <entry>A21e</entry>
+ <entry>KUET30WW</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>這些後期的 IBM BIOS 修訂版大多已經修正此一臭蟲。Jacques Vidrine 寫給 &a.mobile; 的
+ <ulink url="http://docs.FreeBSD.org/cgi/mid.cgi?20010427133759.A71732">這封信
+ </ulink> 上面說明了若你新的 IBM 筆記型電腦無法順利以 FreeBSD 開機的解法步驟
+ (假設可以升級或降級 BIOS 版本的話)。</para>
+
+ <para>如果機器用的是較古早版本的 BIOS,而且不適合更新 BIOS 的話,那麼以下我們會介紹暫時解法,
+ 教你如何修改 FreeBSD 分割區所使用的 ID ,並安裝相關修補程式。</para>
+
+ <para>First, you will need to restore the machine to a state where
+ it can get through its self-test screen. Doing this requires
+ powering up the machine without letting it find a FreeBSD
+ partition on its primary disk. One way is to remove the hard disk
+ and temporarily move it to an older ThinkPad (such as a ThinkPad
+ 600) or a desktop PC with an appropriate conversion cable. Once
+ it is there, you can delete the FreeBSD partition and move the hard
+ disk back. The ThinkPad should now be in a bootable state
+ again.</para>
+
+ <para>With the machine functional again, you can use the workaround
+ procedure described here to get a working FreeBSD
+ installation.</para>
+
+ <procedure>
+ <step>
+ <para>從 <ulink url="http://people.FreeBSD.org/~bmah/ThinkPad/"></ulink>
+ 來下載 <filename>boot1</filename> 及 <filename>boot2</filename> 這兩個檔。
+ 把這兩個檔案放在磁片、光碟或其他硬碟上。</para>
+ </step>
+
+ <step>
+ <para>以一般安裝 FreeBSD 裝到 ThinkPad 上,記得
+ <emphasis>『不要用』</emphasis> <literal>Dangerously
+ Dedicated</literal> 模式。 此外,<emphasis>『不要』</emphasis>
+ 在完成安裝之後就重開機。</para>
+ </step>
+
+ <step>
+ <para>進入 shell:(按 <keycombo action="simul"><keycap>ALT</keycap><keycap>F4</keycap></keycombo>)
+ 切換到<quote>Emergency Holographic Shell</quote> 或是選單上面選擇
+ <quote>fixit</quote> shell。</para>
+ </step>
+
+ <step>
+ <para>用 &man.fdisk.8; 把 FreeBSD 分割區 ID 由 <literal>165</literal> 改為
+ <literal>166</literal>(OpenBSD所使用的ID)。</para>
+ </step>
+
+ <step>
+ <para>把剛剛提的 <filename>boot1</filename> 跟
+ <filename>boot2</filename> 這兩個檔案放到目前的硬碟檔案系統上。</para>
+ </step>
+
+ <step>
+ <para>以 &man.disklabel.8; 把 <filename>boot1</filename> 及
+ <filename>boot2</filename> 存到你的 FreeBSD slice 上面。</para>
+
+ <screen>&prompt.root; <userinput>disklabel -B -b boot1 -s boot2 ad0s<replaceable>n</replaceable></userinput></screen>
+
+ <para><replaceable>「n」</replaceable> 是你裝 FreeBSD 的 slice,
+ 請將 <replaceable>「n」</replaceable> 改為符合你系統現況的 slice。</para>
+ </step>
+
+ <step>
+ <para>重開機,在 boot prompt 會看到有 <literal>OpenBSD</literal> 的選項,
+ 選它,這樣就會以 FreeBSD 開機。</para>
+ </step>
+ </procedure>
+
+ <para>另外,至於如何讓 OpenBSD 及 FreeBSD 並存在同一台 IBM ThinkPad 上...
+ 這個問題就交給各位看倌們去嘗試了 :p</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="install-bad-blocks">
+ <para>有壞軌的硬碟可以拿來裝 FreeBSD 嘛?</para>
+ </question>
+
+ <answer>
+ <para>(如果很堅持的話)也是可以,不過這想法顯然不太明智。:(</para>
+
+ <para>如果在一般較新的 IDE 硬碟上看到有壞軌,很有可能代表:這顆硬碟即將掛點了。
+ (因為目前所有較新的 IDE 硬碟,內部都有自動 remapping 壞軌的能力。
+ 如果看到有壞軌,則表示它內部自動 remapping 功能失效,無法處理壞軌,
+ 也就是說這顆硬碟已經是嚴重損壞程度了。)我們建議買顆新硬碟比較乾脆些唷。</para>
+
+ <para>如果是 SCSI 硬碟有壞軌的話,請試著參考這個
+ <link linkend="awre">解法</link>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="boot-floppy-strangeness">
+ <para>用安裝磁片開機時,卻有些怪現象發生!這是什麼情況呢?</para>
+ </question>
+
+ <answer>
+ <para>若看到一些怪異現象,像是開機片開機開到一半就當了,磁碟機完全沒任何動作、
+ 或是不斷反覆重開機,請先檢查以下幾個線索:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>請確定是否為全新、沒有磁軌錯誤的磁片?
+ (最好使用新買的,而非雜誌、書本附贈的,甚至還放在床底下三年了...=_="")</para>
+ </listitem>
+
+ <listitem>
+ <para>請確定是否有用 binary(或image)傳輸模式來下載 image 檔?
+ (不用覺得不好意思,即使是我們也曾意外以 ASCII 傳輸模式來下載 binary 檔案!)</para>
+ </listitem>
+
+ <listitem>
+ <para>若你是 &windows; 95/98/ME/NT/2000/XP/2003 來下載、製作開機磁片的話,
+ 請確定是否有在 DOS 模式使用 <command>fdimage</command> 或
+ <command>rawrite</command> 這兩個工具程式?剛講的這些作業系統,
+ 都會影響程式去直接寫入硬體,像是製作開機片之類的動作。
+ 有時候,在 GUI 介面上的 DOS shell 也可能會發生這樣的問題。
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>此外,直接透過 &netscape; 瀏覽器下載 image 檔的話,也有類似現象。
+ 所以,如果可以的話,請改用其他可以調整設定的 FTP client端程式來進行下載。
+ (當然,要記得調 binary 傳輸模式)</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="no-install-cdrom">
+ <para>用光碟開機片來安裝,但光碟開機後,安裝程式說找不到光碟...這是怎麼了?</para>
+ </question>
+
+ <answer>
+ <para>通常問題在於光碟機設定錯誤。目前很多電腦的出廠標準配備都有光碟機,並且
+ 會預先設定為 IDE 通道上面 Secondary 的 Slave 設備,而 Secondary 上面的
+ 卻沒有 Master 設備。以 ATAPI 的規格而言,這是錯誤的設定,然而 &windows; 的作法
+ 是不理會這些規格上的設定問題,而且開機時 BIOS 偵測也會略過這點。
+ 這也就是為什麼 BIOS 可以看到光碟,並且可用光碟開機,但 FreeBSD
+ 無法正常抓到光碟以順利進行安裝。</para>
+
+ <para>解法:重新設定系統,讓光碟成為它所連接那條 IDE 通道的 Master,
+ 或者只有一條 IDE 通道的話,那就讓光碟機成為 Slave
+ ,當然該 IDE 通道上至少要有 Master 設備。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="install-PLIP">
+ <para>我可以用 PLIP(Parallel Line IP)方式來安裝 FreeBSD 到筆記型電腦上嗎?</para>
+ </question>
+
+ <answer>
+ <para>可以,用一條普通的 Laplink 線就可以囉。若有這方面需求的話,請參閱 FreeBSD 使用手冊中的
+ <ulink url="&url.books.handbook;/network-plip.html">PLIP
+ 章節</ulink> 的細部設定</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="geometry">
+ <para>該用哪一種硬碟設定參數(geometry)呢?</para>
+ </question>
+
+ <answer>
+ <note>
+ <para>這裡的『硬碟設定參數(geometry)』,指的是硬碟上的
+ 「cylinders」、「heads」、「sectors/track」 這三個設定參數。
+ 接下來的文章內,為了方便介紹,將簡稱為『C/H/S』。
+ 這些設定參數是讓 PC 上的 BIOS 能順利地正常判別硬碟,
+ 與硬碟本身讀寫的重要因素。</para>
+ </note>
+
+ <para>對剛接手的系統管理者新手而言,這些設定參數常造成一些困擾。
+ 首先,SCSI 硬碟上的 <emphasis>physical</emphasis> geometry
+ 跟 FreeBSD 上的 disk blocks 是完全無關的。事實上,
+ 就硬碟上磁區密度的變化而言,並沒有所謂『physical geometry』這種東西。
+ 硬碟製造商所說的『physical geometry』通常是指:
+ 硬碟上所使用最小空間來存放資料的設定參數(geometry)。
+ 以 IDE 硬碟而言,FreeBSD 用以存取硬碟設定的方式是 C/H/S ,
+ 然而,目前市面上的硬碟早就在內部運作時,就自動轉換為 block 方式
+ 了。</para>
+
+ <para>真正關鍵的地方,其實是在於 『<emphasis>logical</emphasis>
+ geometry』— 這是 BIOS 偵測硬碟時所得到的設定,並且用來決定硬碟存取方式。
+ 由於 FreeBSD 是採用 BIOS 的偵測設定值,所以如何來讓 BIOS 偵測到的設定值保持正確,
+ 是十分重要。尤其是同一顆硬碟上有多個作業系統的情況,
+ 它們都必須採用一致的硬碟設定參數(geometry),
+ 否則就會有開機進不去作業系統的嚴重問題了。</para>
+
+ <para>以 SCSI 硬碟而言,硬碟設定參數(geometry)是由 SCSI 卡上的
+ extended translation(通常指的是有標示 <quote>support &gt;1GB</quote>(支援 1GB 以上容量,或類似名詞)
+ 支援與否來作決定。
+ 如果不支援,那麼就會採用 <replaceable>N</replaceable> cylinders、
+ 64 heads、 32 sectors/track 作為硬碟設定參數(geometry),這裡講的『<replaceable>N</replaceable>』
+ 是指硬碟的容量(單位:MB)。舉個例子來說,一顆 2GB 硬碟應該是
+ 2048 cylinders、64 heads、32 sectors/track。</para>
+
+ <para>如果該 SCSI 有支援使用 extended translation 的話,
+ (通常這個方式在 &ms-dos; 使用上有某些限制),並且硬碟容量大於 1GB,
+ 那麼硬碟設定參數(geometry)就會使用像是:
+ M cylinders、255 heads、每磁軌 63 sectors(請注意:不是『64』哦),
+ 這裡講的『<literal>M</literal>』是指硬碟的容量(單位:MB)再除以
+ 7.844238 所得出的數值喔!所以,這個例子的話,同樣是 2GB 硬碟應該是
+ 261 cylinders、255 heads、每磁軌 63 sectors。</para>
+
+ <para>若對上面講的不瞭解,或是 FreeBSD 在安裝時所偵測到的硬碟設定參數(geometry)
+ 有問題的話,最簡單的解法通常是在硬碟上建立一塊小小的 DOS 分割區(partition)。
+ 這樣一來,就可以偵測到正確的硬碟設定參數了,而且,
+ 如果不想繼續留著那小塊 DOS 分割區的話,可以隨時用 partition editor
+ 來拿掉它。或者把它留著當作網路卡驅動程式使用,或隨你高興怎麼用它。</para>
+
+ <para>此外呢,有個免費好用的工具程式叫做『<filename>pfdisk.exe</filename>』,
+ 這個程式放在各 FreeBSD FTP 站或光碟的 <filename>tools</filename> 目錄下,
+ 它可以用來找出硬碟上其他作業系統所使用的硬碟設定參數,
+ 然後就可以在 partition editor 內輸入剛剛找到的那些設定參數就可以了。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="disk-divide-restrictions">
+ <para>分割磁碟機時有任何限制嗎﹖</para>
+ </question>
+
+ <answer>
+ <para>有,你必須確認你的 root 分割區是在 1024 cylinders 之內,讓
+ BIOS 可以從其中啟動核心。(注意:這是 PC 的 BIOS 功能限制,而不
+ 是 FreeBSD 的)</para>
+
+ <para>以 SCSI 硬碟而言,通常是把 <literal>root</literal> (<filename>/</filename>)
+ 分割區放到硬碟最前面的 1024MB (如果有支援 extended translation 的話,
+ 那麼是最前面的 4096MB — 這點請參考上一小節)。而 IDE 硬碟的話,相對應的則是 504MB。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="disk-manager">
+ <para>可以使用哪些磁碟管理程式(disk managers)呢?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 可以用 Ontrack Disk Manager 並且運作正常,
+ 至於其他的 disk manager 則不在正式支援之列。</para>
+
+ <para>若整顆硬碟只裝 FreeBSD ,那麼就不用再裝 disk manager 了。
+ 只要把硬碟設定為 BIOS 所能抓到的最大空間,那麼 FreeBSD 就可算出實際上可使用的空間了。
+ 如果,正在使用的是古早 MFM 控制卡的舊式硬碟,
+ 那麼就需要在 FreeBSD內作 cylinders 相關設定了。</para>
+
+ <para>如果想在磁碟上使用 FreeBSD 和另外的作業系統,也可以不裝 disk manager,
+ 只要確定 FreeBSD 的啟動分割區跟其他作業系統的 slice 都位於開始的 1024 cylinders
+ 內就可以了。如果你相當地高明的話,一個 20MB 的啟動分割區應該就夠用了。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="missing-os">
+ <para>FreeBSD 安裝完畢後重開機,但是電腦卻說 <errorname>Missing Operating
+ System</errorname>這是怎麼了?</para>
+ </question>
+
+ <answer>
+ <para>通常原因出在 FreeBSD 及 DOS 或其他作業系統在硬碟的 <link
+ linkend="geometry">設定參數(geometry)</link>上的規劃有相衝。解法是重裝,但是請照
+ 上述的相關章節步驟來做。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="stop-at-boot-manager">
+ <para>為什麼機器上多重開機管理員(boot manager)出現了 <prompt>F?</prompt> 這個選單畫面,
+ 但卻不會自動跳過而繼續開機呢?</para>
+ </question>
+
+ <answer>
+ <para>這個症狀是本文上面所提的另外一個問題了,原因在於 BIOS 上跟 FreeBSD
+ 上面兩邊的硬碟的 <link linkend="geometry">設定參數(geometry)</link> 並不一致。
+ 若你硬碟或 BIOS 支援 cylinder translation
+ (通常會被標為 <quote>support &gt;1GB(支援 1 GB以上容量)</quote>的話,
+ 試試看更改相關設定,並重裝 FreeBSD。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="need-complete-sources">
+ <para>安裝 FreeBSD 時,需要安裝完整的 sources 嗎?</para>
+ </question>
+
+ <answer>
+ <para>一般來說,這是用不著的。然而,我們強烈建議您的 source 至少要裝
+ <literal>base</literal>(包含了本文中所提的一些檔案)、以及
+ <literal>sys</literal> (kernel 的 source 檔)。
+ 雖然,作業系統本身運是不需要裝 source 檔,但是 &man.config.8; 這個 kernel設定程式則需要 src 。
+ 若沒裝 kernel 的 source 檔,仍然可以用其他地方透過 NFS 掛載的唯讀檔案系統,
+ 來編譯程式。
+ 但由於 kernel-source 本身的限制,我們建議不要直接 mount 在 <filename>/usr/src</filename>,
+ 最好是用 symbolic link(參閱 &man.ln.1;) 將掛載的路徑,設定連結到<filename>/usr/src</filename>
+ 目錄。</para>
+
+ <para>在機器上直接裝有 source 並且瞭解相關編譯過程,這樣子日後升級
+ FreeBSD 會來得方便多。</para>
+
+ <para>若忘了裝相關 source 的話,可以事後用 <command>sysinstalll</command>
+ (&os; 5.2 之前版本則是 <command>/stand/sysinstall</command>) 來補裝,選單:Configure → Distributions → src。
+ </para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="need-kernel">
+ <para>需要重新 build kernel 嗎?</para>
+ </question>
+
+ <answer>
+ <para>在很久很久以前,原本重新 build kernel 在 FreeBSD 安裝過程中,
+ 是絕對必需的步驟之一。但目前早就不用這麼麻煩了,
+ 目前主要常見的版本都使用更友善的 kernel 設定指令。
+ &os; 4.X(含之前版本),在 FreeBSD 啟動提示號(boot:)時,使用 <option>"-c"</option> flag
+ 就會進入設定畫面,來對 kernel 作常見的 ISA 卡細節設定。
+ 而 &os; 5.X(含之後版本)的話,則是以更具彈性的 "hints" 設定方式。</para>
+
+ <para>如果想更節省 RAM 的使用、縮短開機流程,那麼建議:新的 kernel 設定檔只要包含你需要的驅動程式,
+ 然後重新編譯、安裝 kernel 並重開機。然而呢,這點對大多數的系統來說,
+ 這不一定是必要的。</para>
+
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="password-encryption">
+ <para>密碼編碼該採用 DES、Blowfish 或 MD5 的哪一種?該怎麼設定呢?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 預設的密碼編碼方式是採 <emphasis>MD5</emphasis>。
+ 就密碼編碼方式而言,MD5 方式一般被視為比傳統 &unix; 的 <emphasis>DES</emphasis> 方式較為安全。
+ 然而,若有需要在使用舊環境(較不安全的密碼編碼方式的),DES 密碼編碼方式一樣可以使用。
+ (若使用 sysinstall 時有選擇 <quote>crypto</quote> 套件,或是從 source 內編譯安裝)
+ 有裝 crypto 的話,crypto libraries 也支援更安全的 Blowfish 編碼方式。</para>
+
+ <para>密碼編碼的方式是由 <filename>/etc/login.conf</filename> 內的
+ <quote>passwd_format</quote> 欄位來決定的。該欄設定值,(若有裝 crypto 的話)可以是
+ <quote>des</quote> 或 <quote>blf</quote> 或是原本的 <quote>md5</quote>。
+ 詳情請參閱 &man.login.conf.5; 說明。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="boot-floppy-hangs">
+ <para>為什麼開機磁片開到一半,就出現
+ <literal>Probing Devices...</literal> 的畫面訊息,然後就停住了?</para>
+ </question>
+
+ <answer>
+
+ <para>若機器上有裝 IDE 介面的 Iomega &iomegazip; 或是 &jaz; 的話,
+ 因為這些設備可能跟開機片有相衝,請先拿掉這些設備再重試。
+ 當整個作業系統裝好後,就可以把這些設備接回去使用了。
+ 希望這點在日後 release 的 FreeBSD 可以獲得徹底解決。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="panic-on-install-reboot">
+ <para>系統裝完並重開機後,為什麼卻出現 <errorname>panic: can't mount root</errorname>?</para>
+ </question>
+
+ <answer>
+ <para>這個錯誤是因為啟動磁區跟 kernel 兩者對磁碟裝置的認知不相同。
+ 通常這問題會發生在有兩顆 IDE 硬碟的系統,比如:硬碟 Jumper 設定為 Master、
+ 或是兩條 IDE 排線各只連接一顆硬碟,但是裝 FreeBSD 那顆開機硬碟,
+ 卻接在 Secondary IDE 排線上。
+ 如此一來,在開機時當 kernel 指定第二個 IDE 控制器的第一個磁碟機 ad2,
+ 啟動磁區卻認為系統是裝在 ad0(BIOS偵測的第二顆硬碟)!
+ 偵測完裝置後,kernel 試著把啟動磁區所認為的開機硬碟(ad0) mount
+ 起來,事實上應該是 ad2 才對,所以就會出現上面的錯誤訊息了。</para>
+
+ <para>解法如下,請選擇其中一種方式就好:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>重開機並在出現『<literal>Booting kernel in 10 seconds; hit [Enter] to interrupt</literal>』
+ 提示的時候,按下 <keycap>Enter</keycap>鍵。
+ 這樣子就會進入 boot loader 畫面:</para>
+
+ <para>請輸入
+ <literal>
+ set
+ root_disk_unit="<replaceable>disk_number</replaceable>"
+ </literal> 這裡的『<replaceable>disk_number</replaceable>』請依據情況換成相關代號:
+ 若 FreeBSD 硬碟是設定裝在 Primary IDE 接線的 Master,就設為 0 ;
+ 若是 Primary IDE 接線的 Slave,就設為 1;
+ 若是 Secondary IDE 接線的 Master,就設為 2;
+ 若是 Secondary IDE 接線的 Slave,就設為 3。</para>
+
+ <para>接著請再輸入 <literal>boot</literal>,然後系統應該就可以正常開機了。</para>
+
+ <para>若要每次開機都自動設定,而不必每次都打一次,那麼就在 <filename>/boot/loader.conf.local</filename>
+ 檔案內加上 <literal>root_disk_unit="<replaceable>disk_number</replaceable>"</literal>
+ 這行
+ (當然,『<replaceable>disk_number</replaceable>』要改成相關代號)</para>
+ </listitem>
+
+ <listitem>
+ <para>把 FreeBSD 硬碟改接到 Primary IDE 接線上,如此一來就可順利使用。</para>
+ </listitem>
+ </orderedlist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="memory-limits">
+ <para>記憶體最大限制為多少?</para>
+ </question>
+
+ <answer>
+ <para>一般 &i386; 機器上最多可支援到 4 GB(gigabytes)。
+ 而自 &os; 4.9 及 5.1 可以開始使用 &man.pae.4; 來支援更多的記憶體。
+ 有關這點,需要在 kernel 設定檔內加入下列內容並重新編譯 kernel,才能使用 PAE。</para>
+
+ <programlisting>options PAE</programlisting>
+
+ <para>&os; 在 pc98 機器上最多則只支援 4 GB ,而且不能使用 PAE。
+ 在 Alpha 機器上,記憶體限制方面要視所使用的型號支援程度而定,這點請參閱
+ 所使用的 Alpha 硬體規格表。至於其他架構的 &os; 理論上最多可使用的記憶體,有較多的限制。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ffs-limits">
+ <para>檔案系統最大限制為多少?</para>
+ </question>
+
+ <answer>
+ <para>就檔案系統方面,理論上的限制是最多到 8TB(2G blocks),
+ 或是使用內定 8K block 大小時,限制是 16TB。
+ 實際上,目前軟體使用上限制只能用到 1 TB,
+ 然而如果是有另行改造過檔案系統,那麼達到 4TB 的目標是可行的
+ (也有人成功過)。</para>
+
+ <para>單一檔案的大小方面,假如 block 以 4K 作規劃的話,
+ 則最大是趨近 1G blocks(4TB)。</para>
+
+ <table>
+ <title>檔案大小的最大限制</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>檔案系統 block 大小</entry>
+
+ <entry>works</entry>
+
+ <entry>should work</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>4K</entry>
+
+ <entry>4T-1</entry>
+
+ <entry>&gt;4T</entry>
+ </row>
+
+ <row>
+ <entry>8K</entry>
+
+ <entry>&gt;32G</entry>
+
+ <entry>32T-1</entry>
+ </row>
+
+ <row>
+ <entry>16K</entry>
+
+ <entry>&gt;128G</entry>
+
+ <entry>32T-1</entry>
+ </row>
+
+ <row>
+ <entry>32K</entry>
+
+ <entry>&gt;512G</entry>
+
+ <entry>64T-1</entry>
+ </row>
+
+ <row>
+ <entry>64K</entry>
+
+ <entry>&gt;2048G</entry>
+
+ <entry>128T-1</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>When the fs block size is 4K, triple indirect blocks work
+ and everything should be limited by the maximum fs block number
+ that can be represented using triple indirect blocks (approx.
+ 1K^3 + 1K^2 + 1K), but everything is limited by a (wrong) limit
+ of 1G-1 on fs block numbers. The limit on fs block numbers
+ should be 2G-1. There are some bugs for fs block numbers near
+ 2G-1, but such block numbers are unreachable when the fs block
+ size is 4K.</para>
+
+ <para>block 大小如果是 8K 或更大,檔案系統 block 數目會被限制在 2G-1
+ ,但實際上應該說限制是 1G-1 才對,因為採用 2G-1 block 的檔案系統會導致一些問題。
+ </para>
+
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="archsw-readin-failed-error">
+ <para>為何在啟動新的 kernel 時,看到
+ <errorname>archsw.readin.failed</errorname> 錯誤訊息?</para>
+ </question>
+
+ <answer>
+ <para>原因出在你的 world 以及 kernel 並不同步,舉例:kernel 用 4.11,
+ 而 world 卻是 4.8,這樣是會有問題的。
+ 請再次確認,是否有以 <command>make buildworld</command> 及
+ <command>make buildkernel</command> 來正常更新 kernel。</para>
+
+ <para>在啟動 loader 之前,會看到 "|" 這個符號在轉動,這時可以按任何鍵中斷,
+ 然後再指定要載入哪個 kernel 來開機。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="security-profiles">
+ <para><quote>security profiles</quote> 是指什麼?</para>
+ </question>
+
+ <answer>
+ <para>A <quote>security profile</quote> is a set of configuration
+ options that attempts to achieve the desired ratio of security
+ to convenience by enabling and disabling certain programs and
+ other settings. For full details, see the <ulink
+ url="&url.books.handbook;/install-post.html#SECURITYPROFILE">Security
+ Profile</ulink> section of the Handbook's <ulink
+ url="&url.books.handbook;/install-post.html">post-install
+ chapter</ulink>.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="boot-acpi">
+ <para>在開機時,選擇使用 ACPI 則在安裝過程就掛了,該怎麼辦?</para>
+ </question>
+
+ <answer>
+ <para>試試看關閉 ACPI support。 當在載入 bootloader時,按下空白鍵。
+ 系統會顯示 <screen>OK</screen> 這時輸入
+ <screen><userinput>unset acpi_load</userinput></screen> 接著打
+ <screen><userinput>boot</userinput></screen>
+ 以繼續開機,這樣子應該就可以了。</para>
+ </answer>
+ </qandaentry>
+
+ </qandaset>
+ </chapter>
+
+ <chapter
+ id="hardware">
+ <title>硬體支援方面</title>
+
+ <sect1 id="compatibility-general">
+ <title>一般問題</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="which-hardware-to-get">
+ <para>我想組裝自己的 FreeBSD 機器,有哪些型號、品牌、規格是支援程度最好的呢?</para>
+ </question>
+
+ <answer>
+ <para>有關這點,在 FreeBSD 討論區上時常有人討論。雖然硬體汰換速度很快,
+ 可能隨時有新規格、新產品出現,然而這些都在我們意料之中,
+ 我們 <emphasis>仍然</emphasis> 強烈建議:在詢問有關最新規格硬體的支援問題之前,
+ 請先參閱 &os;
+ <ulink url="&rel.current.hardware;">&rel.current;</ulink>
+ 或
+ <ulink url="&rel2.current.hardware;">&rel2.current;</ulink>的支援硬體列表,
+ 或是搜尋<ulink url="http://www.FreeBSD.org/search/#mailinglists">討論區的舊文章</ulink>,
+ 也許,上週才剛恰巧有人討論過你所要問的硬體。</para>
+
+ <para>如果要找有關筆記型電腦方面,請到 FreeBSD-mobile 筆記型電腦討論區。
+ 不然,就到 FreeBSD-questions 討論區,或是特定硬體規格(比如 pc98, Alpha)的專屬討論區吧。
+ </para>
+ </answer>
+ </qandaentry>
+
+ </qandaset>
+ </sect1>
+
+ <sect1 id="compatibility-processors">
+ <title>硬體架構及 CPU</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="architectures">
+ <para>FreeBSD 有支援 x86 之外的硬體架構平台嗎?</para>
+ </question>
+
+ <answer>
+
+ <para>有的,FreeBSD 目前可以在 Intel x86 and DEC
+ (現在的 HP-Compaq) Alpha 架構上面運作。自 FreeBSD 5.0 之後的版本,則
+ 可支援 AMD64 及 Intel EM64T, IA-64 以及 &sparc64; 架構。
+ 未來平台支援上還會有 &mips; 及
+ &powerpc;,細節請分別參閱 &a.mips; 或 &a.ppc;。
+ 一般而言,新的硬體架構平台方面,都是到 &a.platforms; 討論。</para>
+
+ <para>若你機器不是以上架構或是比較奇特的,而想立刻試試看 BSD 的魔力,
+ 我們建議你可以考慮使用 <ulink
+ url="http://www.netbsd.org/">NetBSD</ulink> 或 <ulink
+ url="http://www.openbsd.org/">OpenBSD</ulink>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="smp-support">
+ <para>FreeBSD 支援 CPU 對稱多工處理(SMP, Symmetric Multiprocessing)嗎?</para>
+ </question>
+
+ <answer>
+ <para>有的。 SMP 在 &os; 5.2 預設的 kernel(<emphasis>GENERIC</emphasis>)已有啟動。
+ </para>
+
+ <para>在 &os; 5.3 要 release 時,SMP相關設定也是預設就有啟動。
+ 然而,在一些較新型的機器(像是 emt64)上卻又有些問題,
+ 所以還是決定在相關問題、安全議題未獲解決前,先關閉 SMP 的相關啟動。
+ 這點,正是 &os; 5.4 所優先考慮的方向。</para>
+
+ <para>&os; 4.X 的話,預設的 kernel 並沒有啟動 SMP,
+ 因此,必須要把 options SMP 加入 kernel 設定檔並重新編譯才能啟動。
+ 至於還有哪些相關設定要放入 kernel 設定檔,請參閱<filename>/sys/i386/conf/LINT</filename>。
+ </para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </sect1>
+
+ <sect1 id="compatibility-drives">
+ <title>硬碟、磁帶機以及光碟、DVD、燒錄機</title>
+
+ <qandaset>
+
+ <qandaentry>
+ <question id="supported-hard-drives">
+ <para>FreeBSD 可支援哪些種類的硬碟呢?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 都支援 EIDE 及 SCSI 介面的硬碟(以及 SCSI 卡,請看下一節說明)
+ 以及 <quote>Western Digital</quote> 介面的硬碟 (MFM、 RLL、
+ ESDI,當然包含 IDE),不過有一些少數的 ESDI 晶片組的(型號:WD1002/3/6/7)
+ 可能無法正常運作。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="supported-scsi-controllers">
+ <para>支援哪些 SCSI 卡、設備呢?</para>
+ </question>
+
+ <answer>
+ <para>請參閱 &os; 的硬體支援表(
+ <ulink url="&rel.current.hardware;">&rel.current;</ulink> 或
+ <ulink url="&rel2.current.hardware;">&rel2.current;</ulink>)</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="tape-support">
+ <para>支援哪些磁帶機呢?</para>
+ </question>
+
+ <answer>
+
+ <para>FreeBSD 支援 SCSI 及 QIC-36 (QIC-02 介面) 規格的磁帶機。
+ 同時包含了 8-mm (也就是 Exabyte) 及 DAT 磁帶機。</para>
+
+ <para>有些早期版本的 8-mm 磁帶機並不是完全相容於 SCSI-2 規格,
+ 所以可能在 FreeBSD 上表現不是很好。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="tape-changer-support">
+ <para>FreeBSD 支援磁帶自動換帶機嗎?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 可以用 &man.ch.4; 上面所列的機種,搭配 &man.chio.1; 指令,
+ 來使用 SCSI 種類的自動換帶機,細節部分請參閱 &man.chio.1; 說明。</para>
+
+ <para>If you are not using <application>AMANDA</application>
+ or some other product that already understands changers,
+ remember that they only know how to move a tape from one
+ point to another, so you need to keep track of which slot a
+ tape is in, and which slot the tape currently in the drive
+ needs to go back to.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="supported-cdrom-drives">
+ <para>FreeBSD 可支援哪些種類的光碟機呢?</para>
+ </question>
+
+ <answer>
+ <para>只要是有支援的 SCSI 卡上所接的任一 SCSI 光碟機都有支援。</para>
+
+ <para>此外,也支援下列的光碟機:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Mitsumi LU002 (8bit), LU005 (16bit) 及 FX001D
+ (16bit 2x Speed)</para>
+ </listitem>
+
+ <listitem>
+ <para>Sony CDU 31/33A</para>
+ </listitem>
+
+ <listitem>
+ <para>Sound Blaster 非 SCSI 介面的光碟機</para>
+ </listitem>
+
+ <listitem>
+ <para>Matsushita/Panasonic 光碟機</para>
+ </listitem>
+
+ <listitem>
+ <para>相容 ATAPI 規格的 IDE CDROMs</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>相對於 SCSI 機種而言,其他非 SCSI 的光碟機都是比較慢,
+ 此外,有些 ATAPI 種類的光碟機可能無法順利運作</para>
+
+ <para>Daemon News 以及 FreeBSD Mall 所發行的正式 FreeBSD 光碟以及燒錄用的影像檔(ISO),
+ 都可以直接用於開機光碟使用。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="supported-cdrw-drives">
+ <para>FreeBSD 支援哪些光碟燒錄機的驅動程式呢?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 支援任何相容 ATAPI 標準的 IDE CD-R 或 CD-RW 光碟燒錄機,
+ 細節請參閱 &man.burncd.8; 說明。</para>
+
+ <para>FreeBSD 也支援任何 SCSI CD-R 或 CD-RW 光碟燒錄機。
+ 請用 port 或 packag 機制來安裝、使用 <command>cdrecord</command> ,
+ 並確定您的 kernel 內有將 <devicename>pass</devicename>設備一併編譯在內。
+ (預設的 kernel.GENERIC 都會有 device pass 這段)</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="zip-support">
+ <para>FreeBSD 支援 Iomega &iomegazip; 嗎?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 支援外接式的 SCSI 及 ATAPI(IDE) 介面的 Iomega &iomegazip;。
+ 不過 SCSI ZIP 只能被設為 SCSI ID 5 或是 6 才可以運作,但如果
+ SCSI 卡上的 BIOS 支援它,你甚至可以用它來開機。
+ 我們不曉得哪一塊卡可以把卡的 ID 設在除了 0 或 1 以外的地方而開機成功,
+ 因此,如果想改 SCSI ID 的話,請務必參閱該型號的說明手冊。</para>
+
+ <para>FreeBSD 同時也支援 Parallel Port Zip磁碟機。請檢查 kernel
+ 設定檔是否有:
+ <devicename>scbus0</devicename>、
+ <devicename>da0</devicename>、
+ <devicename>ppbus0</devicename>,以及
+ <devicename>vp0</devicename> 這些驅動程式 (預設的 GENERIC kernel
+ 除了 <devicename>vp0</devicename> 沒包進去,其他三者都會有)。
+ 加了這幾個驅動程式之後,Parallel Port Zip 就會成為
+ <devicename>/dev/da0s4</devicename>。</para>
+
+ <para>這時,就可以用像是 <command>mount /dev/da0s4 /mnt</command> 或
+ (DOS 檔案系統)<command>mount_msdos /dev/da0s4 /mnt</command>
+ 之類的指令來掛載、讀寫。</para>
+
+ <para>也可以參閱下面有關<link linkend="media-change">隨身磁片
+ </link>部分,以及<link
+ linkend="removable-drives">抽取碟、隨身碟的『格式化』討論</link>
+ 的部分</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="jaz-zip-removable-support">
+ <para>FreeBSD 有支援 &jaz;、EZ 及其他類似的隨身磁片嗎?</para>
+ </question>
+
+ <answer>
+ <para>可以啊,除了 IDE 的 EZ drive 外,其他的應該都是 SCSI 介面,
+ 所以在 FreeBSD 上都會以 SCSI 硬碟來處理。</para>
+
+ <para>當然,你必須確定在開機時,這些設備的電源是打開的,
+ 以便讓 FreeBSD 可以偵測到。</para>
+
+ <para><anchor id="media-change"/>如果在磁碟運中狀態中,要更換磁片的話,
+ 記得先看一下 &man.mount.8;、&man.umount.8;、
+ 以及(SCSI的話)&man.camcontrol.8; 或 &man.atacontrol.8; 還有 FAQ 後面有關
+ <link linkend="removable-drives">使用抽取碟、隨身碟的討論
+ </link>。</para>
+ </answer>
+ </qandaentry>
+
+ </qandaset>
+
+ </sect1>
+
+ <sect1 id="compatibility-kbd-mice">
+ <title>鍵盤、滑鼠</title>
+
+ <qandaset>
+
+ <qandaentry>
+ <question id="usbkbd">
+ <para>FreeBSD 有支援 USB 鍵盤嗎?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD (尤其是有支援 USB keyboards。 Enable USB support in
+ <filename>/etc/rc.conf</filename>.</para>
+
+ <para>若有開 USB 鍵盤支援而且同時接上 AT 跟 USB 鍵盤的話,那麼 AT 鍵盤會變成
+ <devicename>/dev/kbd0</devicename>,而 USB 鍵盤則是
+ <devicename>/dev/kbd1</devicename>。如果只接 USB 鍵盤,那麼它就是
+ <devicename>/dev/ukbd0</devicename> 囉。</para>
+
+ <para>如果想在 console 上使用 USB 鍵盤的話,那麼必須設定 console 指定用 USB 鍵盤。
+ 可以在系統開機程序時,加上下列指令:</para>
+
+ <screen>&prompt.root; <userinput>kbdcontrol -k /dev/kbd1 &lt; /dev/ttyv0 &gt; /dev/null</userinput></screen>
+
+ <para>注意:若只有 USB 鍵盤的話,也就是 <devicename>/dev/ukbd0</devicename>,
+ 那麼請改用下列指令:</para>
+
+ <screen>&prompt.root; <userinput>kbdcontrol -k /dev/ukbd0 &lt; /dev/ttyv0 &gt; /dev/null</userinput></screen>
+
+ <para>建議:可以把上述指令放入 <filename>/etc/rc.i386</filename> 。</para>
+
+ <para>設定成功之後,USB 鍵盤不用作任何特別設定,就可以在 X 視窗環境上正常運作囉。</para>
+
+ <para>USB 鍵盤的熱插拔(Hot-plugging and unplugging)在 &os; 可能還無法完全正常運作,
+ 建議:在系統開機前就先接上鍵盤,直到關機為止,以避免不必要的困擾。</para>
+
+ <para>相關細節請參閱 &man.ukbd.4; 的說明。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="busmouse">
+ <para>古早的 bus 滑鼠,要怎麼設定呢?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 支援一些廠商(像是:Microsoft、Logitech、ATI)所做的 bus 及 InPort bus 介面的滑鼠。
+ 然而,預設的 kernel(GENERIC)已經不內含它們的驅動程式。
+ 因此,要加入下列到 kernel 設定檔並重新編譯、安裝,才能啟用:</para>
+
+ <programlisting>device mse0 at isa? port 0x23c irq5</programlisting>
+
+ <para>Bus 滑鼠通常要搭配專用的介面卡才能使用。
+ 這些卡可以設定 port address 及 IRQ 值,這些細節請參閱你的滑鼠說明手冊及
+ &man.mse.4; 說明。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ps2mouse">
+ <para>PS/2 (<quote>mouse port</quote> 或
+ <quote>keyboard</quote>)的滑鼠要怎麼設定才好呢?</para>
+ </question>
+
+ <answer>
+ <para>PS/2 滑鼠都有支援,所需要用到的驅動程式 <devicename>psm</devicename>
+ 在預設的 kernel(GENERIC)已有內含了。</para>
+
+ <para>若你自訂的 kernel 內漏了 psm 的話,那麼就再把下列內容加到 kernel
+ 設定檔並重新編譯、安裝:</para>
+
+ <programlisting>device psm0 at atkbdc? irq 12</programlisting>
+
+ <para>當開機時 kernel 有正確偵測到 <devicename>psm0</devicename>
+ ,請務必確認在 <filename>/dev</filename> 內有
+ <devicename>psm0</devicename> 。
+ 如果沒有的話,那麼就用 <username>root</username> 來打下列指令來建立吧:</para>
+
+ <screen>&prompt.root; <userinput>cd /dev; sh MAKEDEV psm0</userinput></screen>
+
+ <note>
+ <para>如果是 &os; 5.0-RELEASE(含之後版本)的話,因為採用 &man.devfs.5; 機制的因素,
+ 所以會自動在 <filename>/dev</filename> 下建立相關設備的節點,因此就可以略過上面這一步。</para>
+ </note>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="moused">
+ <para>如果不用 X Window 環境的話,也可以用滑鼠嗎?</para>
+ </question>
+
+ <answer>
+ <para>若使用 console 的預設驅動程式(也就是 &man.syscons.4;),
+ 那麼就可以在文字介面的 console 上面用滑鼠來剪貼文字了。
+ 那麼要啟動 &man.moused.8; 並開啟游標顯示,
+ 請打下列指令:</para>
+
+ <screen>&prompt.root; <userinput>moused -p /dev/<replaceable>xxxx</replaceable> -t <replaceable>yyyy</replaceable></userinput>
+&prompt.root; <userinput>vidcontrol -m on</userinput></screen>
+
+ <para>其中『<replaceable>xxxx</replaceable>』是滑鼠的設備名稱,而
+ 『<replaceable>yyyy</replaceable>』則是滑鼠所使用的 protocol 種類。
+ 目前的 moused 可以自動偵測(除了舊式的 serial
+ 滑鼠之外)大多數滑鼠所使用的 protocol 種類,而不用刻意去指定。
+ 『protocol 種類』設定用
+ <literal>auto</literal> 就會自動偵測了。若自動偵測失敗的話,請參閱 &man.moused.8;
+ 裡面的 type 那段說明。</para>
+
+ <para>如果用的是 PS/2 滑鼠,只要把
+ <literal>moused_enable="YES"</literal> 加到
+ <filename>/etc/rc.conf</filename> ,這樣每次開機就會自動啟動了。
+ 此外,如果要在所有 virtual terminals 上也能使用滑鼠,
+ 而不限定只有 console 的話,那麼請再把
+ <literal>allscreens_flags="-m on"</literal> 加到 <filename>/etc/rc.conf</filename> 裡面即可。</para>
+
+ <para>moused 在執行中的時候,如果要使用滑鼠相關功能,都必須透過 moused
+ 或其他程式像是 X 視窗來進行。請參閱 FAQ 中有關<link
+ linkend="x-and-moused">『為什麼不能在 X 視窗裡使用滑鼠?』</link>以瞭解相關細節。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="text-mode-cut-paste">
+ <para>在文字模式的 console 環境要怎麼用滑鼠來剪貼文字呢?</para>
+ </question>
+
+ <answer>
+ <para>當執行 moused 後,(參閱<link linkend="moused">前一節</link>)
+ 按住左鍵,接著移動滑鼠來選擇一個區域之後放開,這樣就完成『複製』。
+ 要『貼上』的話,按滑鼠中鍵就可以了。
+ 要『延伸選取區』的話,按滑鼠右鍵</para>
+
+
+ <para>如果你的滑鼠沒有中鍵,你可以用模擬的方式,或是重新定義滑鼠按鍵的方式,
+ 來達成「延伸」的功能。詳情請參閱 &man.moused.8; 說明。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="mouse-wheel-buttons">
+ <para>我滑鼠上面的滾輪、滾輪按鈕,可以在 console 上使用嗎?</para>
+ </question>
+
+ <answer>
+ <para>這個答案嘛...,很不幸地,在大多數的情況下不行。
+ 這些有滾輪的滑鼠需要用特殊驅動程式才行,
+ 除非,滑鼠驅動程式或使用者自己的應用程式有支援,
+ 不然,這些滑鼠只能夠當成是普通的兩鍵或三鍵的滑鼠來用而已。
+ </para>
+
+ <para>如果要在 X 視窗環境上使用滾輪的話,請參閱
+ <link linkend="x-and-wheel"> X 視窗上的滾輪使用
+ </link>說明。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="laptop-mouse-trackball">
+ <para>要怎麼在筆記型電腦上使用滑鼠、軌跡球、觸控板呢?</para>
+ </question>
+
+ <answer>
+ <para>請參閱<link linkend="ps2mouse">前面的 PS/2 滑鼠的問答
+ </link>。</para>
+ </answer>
+ </qandaentry>
+
+ </qandaset>
+
+ </sect1>
+
+ <sect1 id="compatibility-networking">
+ <title>網路跟 serial 設備</title>
+
+ <qandaset>
+
+ <qandaentry>
+ <question id="network-cards">
+ <para>FreeBSD 支援哪些網路卡呢?</para>
+ </question>
+
+ <answer>
+ <para>請參考 &os; 各版本的硬體支援列表。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="internal-plugnplay-modem">
+ <para>為什麼 FreeBSD 找不到 PnP(隨插隨用,Plug &amp; Play)規格的 modem?</para>
+ </question>
+
+ <answer>
+ <para>原因在於:需要把 modem 的 PnP ID 加到 serial 驅動程式的 PnP ID 表,作法如下:</para>
+ <orderedlist>
+ <listitem>
+ <para>首先,在 kernel 設定檔內加入 <literal>controller pnp0</literal>,
+ 並重新編譯、安裝 kernel,最後重開機就會啟動 PnP 支援。</para>
+ </listitem>
+
+ <listitem>
+ <para>然後,kernel 會把偵測到所有設備上的 PnP ID 都列出。
+ 這時,修改 <filename>/usr/src/sys/isa/sio.c</filename>(大約第752行左右的地方),
+ 可以搜尋 <literal>SUP1310</literal> 當關鍵字(位於 <literal>sio_ids[]</literal> 表內),
+ 請將剛才 kernel 顯示的 modem 的 PnP ID 複製到相關位置。</para>
+ </listitem>
+
+ <listitem>
+ <para>這時,再重新編譯、安裝 kernel,最後重開機應該就會正確偵測到 modem 了。</para>
+ </listitem>
+ </orderedlist>
+
+ <para>此外,也可以在開機時以 <literal>pnp</literal> 指令來手動設定 PnP 設備,
+ 來讓 kernel 得以正確偵測,舉例:</para>
+
+ <programlisting>pnp 1 0 enable os irq0 3 drq0 0 port0 0x2f8</programlisting>
+
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="support-winmodem">
+ <para>FreeBSD 支援像是 Winmodems 之類的軟體 modem 嗎?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 可以安裝額外的軟體來支援軟體 modem。
+ 像是 <filename role="package">comms/ltmdm</filename> 可支援常見的 Lucent LT 晶片,
+ <filename role="package">comms/mwavem</filename> 則可支援 IBM Thinkpad 600 及 700
+ 筆記型電腦上面的 modem。</para>
+
+ <para>然而,並不能用軟體 modem 來安裝 FreeBSD,
+ 因為:這類軟體必須在作業系統安裝完畢之後,才能安裝。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="support-broadcom">
+ <para>有 Broadcom 43xx 無線網卡的原生驅動程式(Native driver)嗎?</para>
+ </question>
+
+ <answer>
+ <para>沒有,而且也不太可能會有。</para>
+
+ <para>Broadcom 拒絕公開有關無線網卡晶片的驅動程式相關說明,
+ 主因大概是他們用軟體來控制無線傳輸方式。
+ 事實上,因為要能通過美國聯邦電信委員會(FCC)檢磁安規的話,
+ 必須確保產品不能讓使用者不能隨意更動相關設定,比如:電磁波頻率、相關模組參數、輸出電源等。
+ 但是,如果我們不知道如何去控制晶片的話,那麼撰寫驅動程式之路恐怕不太可行。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="multiport-serial-support">
+ <para>FreeBSD 支援哪些 multi-port serial卡呢?</para>
+ </question>
+
+ <answer>
+ <para>請參閱使用手冊上的 <ulink
+ url="&url.books.handbook;/install.html#INSTALL-MISC">安裝篇—其他硬體
+ </ulink> 列表。</para>
+
+ <para>雖然有些卡是沒牌的(尤其是有標明:相容 AST 規格)但也可以正常使用。</para>
+
+ <para>至於卡的設定方面,請參閱 &man.sio.4; 的說明。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="serial-console-prompt">
+ <para>在 serial console 上要如何才會出現 boot: 提示呢?</para>
+ </question>
+
+ <answer>
+ <orderedlist>
+ <listitem>
+ <para>kernel 設定檔加入
+ <literal>options COMCONSOLE</literal></para>
+ </listitem>
+
+ <listitem>
+ <para>建立 /boot.config 檔,並且該檔裡面內容只填上 <option>-P</option></para>
+ </listitem>
+
+ <listitem>
+ <para>把鍵盤從機器上拔掉</para>
+ </listitem>
+ </orderedlist>
+
+ <para>細節請看
+ <filename>/usr/src/sys/i386/boot/biosboot/README.serial</filename>
+ </para>
+ </answer>
+ </qandaentry>
+
+ </qandaset>
+
+ </sect1>
+
+ <sect1 id="compatibility-sound">
+ <title>音效卡</title>
+
+ <qandaset>
+
+ <qandaentry>
+ <question id="sound-card-support">
+ <para>FreeBSD 支援哪些音效卡?</para>
+ </question>
+
+ <answer>
+ <para>&os; 支援各種音效卡,包括了 &soundblaster;、
+ &soundblaster; Pro、&soundblaster; 16、Pro Audio Spectrum 16、
+ AdLib、及 Gravis UltraSound sound cards (細節請參閱
+ <ulink url="&url.base;/releases/">&os; 發行情報</ulink>
+ 以及 &man.snd.4; 的說明)。
+ 此外,對 MPU-401 及 MIDI 相容規格的也有一定程度的支援,而
+ &microsoft; Sound System 規格也有支援。</para>
+
+ <note>
+ <para>驅動程式僅適用於『音效』部分! 除了 &soundblaster; 之外,
+ 目前音效驅動程式並不支援這些音效卡上的光碟機, SCSI設備或搖桿。
+ &soundblaster; 的 SCSI 介面及某些非 SCSI 的光碟機是有支援,但無法用來開機。
+ </para>
+ </note>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="es1370-silent-pcm">
+ <para>&man.pcm.4; 所支援的音效卡沒有聲音,有什麼暫時解決方式嗎?</para>
+ </question>
+
+ <answer>
+ <para>因為有些像是 es1370 晶片的音效卡會在每次開機時把音量調為零。
+ 暫時解法是在每次開機時執行下面指令,或是加到 /etc/rc.local 內:</para>
+
+ <screen>&prompt.root; <userinput>mixer pcm 100 vol 100 cd 100</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ </qandaset>
+
+ </sect1>
+
+ <sect1 id="compatibility-other">
+ <title>其他怪異問題(ACPI、重開機後掛了..等)</title>
+
+ <qandaset>
+
+ <qandaentry>
+ <question id="other-device-support">
+ <para>FreeBSD 還支援其他哪些硬體呢?</para>
+ </question>
+
+ <answer>
+ <para>請參閱使用手冊上的 <ulink
+ url="&url.books.handbook;/install.html#INSTALL-MISC">安裝篇—其他硬體</ulink>
+ 。</para>
+
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="power-management-support">
+ <para>FreeBSD 支援筆記型電腦的省電管理功能嗎?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 4.X(含之後版本)在某些機種上都有支援 <acronym>APM</acronym>。
+ 細節請參閱 &man.apm.4; 的說明。</para>
+
+ <para>FreeBSD 5.X(含之後版本)支援在目前大部分機種上都有的
+ <acronym>ACPI</acronym> 功能。
+ 細節請參閱 &man.acpi.4; 的說明。若機器上同時都有 <acronym>APM</acronym>
+ 及 <acronym>ACPI</acronym> 功能的話,我們建議你可以兩者都試試看,
+ 看看哪一種比較符合你的需求。</para>
+
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="disable-acpi">
+ <para>該如何關閉 ACPI?</para>
+ </question>
+
+ <answer>
+ <para>把 <screen>hint.acpi.0.disabled="1"</screen>
+ 這段加到 <filename>/boot/device.hints</filename> 即可。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="micron-hang-boot">
+ <para>Micron 電腦總是在 &os; 啟動時就掛掉,該怎麼辦呢?</para>
+ </question>
+
+ <answer>
+ <para>有些 Micron 主機板上的 BIOS 在 PCI 方面會有問題,
+ 這會導致 PCI 設備會被 BIOS 偵測為不正確設定,而進入 FreeBSD 就掛掉。</para>
+
+ <para>暫時解決方式:關閉 BIOS 內 <quote>Plug and Play Operating System</quote>
+ 的設定。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="micron-3comnic-failure">
+ <para>&tm.3com; PCI 介面網路卡無法在 Micron 電腦上使用,該怎麼辦?</para>
+ </question>
+
+ <answer>
+ <para>這問題跟前面的問題因素一樣,總之,就是關閉 BIOS 中有關 OS PnP 的設定。</para>
+
+ <para>暫時解決方式:關閉 BIOS 內 <quote>Plug and Play Operating System</quote>
+ 的設定。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="asusk7v-boot-failure">
+ <para>主機板是用華碩(ASUS) K7V,可是用開機片開到一半就當了,怎麼辦呢?</para>
+ </question>
+
+ <answer>
+ <para>進入 BIOS 設定,並關閉 <quote>boot virus protection</quote> 設定即可。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="newcard-does-not-work">
+ <para>PCMCIA 卡無法使用,並出現錯誤訊息
+ <quote>cbb0: unsupported card type detected.</quote>
+ 該怎麼辦?</para>
+ </question>
+
+ <answer>
+ <para>可以試試看改用舊的方式,請先修改 kernel 設定檔,拿掉下面這幾行:
+ <programlisting>device cbb
+device pccard
+device cardbus</programlisting>
+ 然後加上:
+ <programlisting>device pcic
+device card 1</programlisting>
+ 最後請參閱 Handbook 中
+ <ulink url="&url.books.handbook;/kernelconfig.html">調整 FreeBSD Kernel</ulink>
+ 章節,以重新編譯、安裝新的 kernel。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="dell-poweredge-failure">
+ <para>為什麼 &dell; &poweredge; 2850 裝完 FreeBSD 之後,重開機接著鍵盤就掛了?</para>
+ </question>
+
+ <answer>
+ <para>(本題由 cdsheen 提供)嚐試在 &dell; &poweredge; 2850 上面安裝 &os; 6.0,
+ 不過安裝完成、並重新開機之後,發現 console 的鍵盤不能動了,
+ 同樣的情況似乎也存在於 &os; 5.3 及 &os; 5.4,
+ 經過一番搜尋,發覺是因為這台機器上面有一個 <quote>Dell Remote Access Controller (DRAC)</quote>,
+ 這個裝置會被系統辨識成一個 USB Keyboard,所以導致開完機之後,正常的 PS/2 鍵盤反而不能動了!</para>
+
+ <para>暫時解決方式如下:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>先以 Single User Mode 進入系統</para>
+ </listitem>
+
+ <listitem>
+ <para>在命令列模式下,先執行下列命令:</para>
+ <screen>&prompt.root; <userinput>fsck -y <filename>/</filename></userinput></screen>
+ <screen>&prompt.root; <userinput>mount -u <filename>/</filename></userinput></screen>
+ </listitem>
+
+ <listitem>
+ <para>然後編輯 <filename>/etc/devd.conf</filename>,把對於 USB Keyboard 的支援暫時拿掉,
+ 也就是把下面幾行開頭加上 #</para>
+ <programlisting>
+# When a USB keyboard arrives, attach it as the console keyboard.
+#attach 100 {
+# device-name "ukbd0";
+# action "kbdcontrol -k /dev/ukbd0 &lt; /dev/console &amp;&amp; /etc/rc.d/syscons restart";
+#};
+#detach 100 {
+# device-name "ukbd0";
+# action "kbdcontrol -k /dev/kbd0 &lt; /dev/console";
+#};
+</programlisting>
+ </listitem>
+
+ <listitem>
+ <para>然後輸入 <command>exit</command>離開 Single User Mode 之後,
+ 就可以順利進入系統、而且鍵盤也可以正常運作,下次開機也不會有問題!</para>
+ </listitem>
+ </orderedlist>
+
+ <para>另外,&dell; 的 DRAC/BMC 看起來有蠻多不錯的遠端存取功能,有興趣的人可以玩玩看...</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+
+ </sect1>
+
+ </chapter>
+
+ <chapter id="troubleshoot">
+ <chapterinfo>
+ <author>
+ <firstname>William</firstname>
+ <surname>Liao</surname>
+ <affiliation>
+ <address><email>chliao@tpts4.seed.net.tw</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>常見問題解決</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="pae">
+ <para>為什麼 &os; 抓到錯誤的記憶體容量?</para>
+ </question>
+
+ <answer>
+ <para>抓到錯誤的記憶體容量是因為物理位址跟虛擬位址兩者是不同的。</para>
+
+ <para>The convention for most PC hardware is to use the memory area
+ between 3.5G and 4G for a special purpose (usually for PCI). This
+ address space is used to access PCI hardware. As a result real,
+ physical memory can not appear in that address space.</para>
+
+ <para>What happens to the memory that should appear in that location
+ is dependent on your hardware. Unfortunately, some hardware does
+ nothing and the ability to use that last 500M of RAM is entirely
+ lost.</para>
+
+ <para>Luckily, most hardware remaps the memory to a higher location
+ so that it can still be used. However, this can cause some
+ confusion if you watch the boot messages.</para>
+
+ <para>On a 32 bit version of &os;, the memory appears lost, since it
+ will be remapped above 4G, which a 32 bit kernel is unable to
+ access. In this case, the solution is to build a PAE enabled
+ kernel. See <link linkend="memory-limits">this FAQ entry</link>
+ for more information.</para>
+
+ <para>On a 64 bit version of &os;, or when running a PAE-enabled
+ kernel, &os; will correctly detect and remap the memory so it is
+ usable. During boot, however, it may seem as if &os; is detecting
+ more memory than the system really has. This is normal and the
+ available memory will be corrected as the boot process
+ completes.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="awre">
+ <para>硬碟有壞軌時該怎麼辦?</para>
+ </question>
+
+ <answer>
+ <para>若是 SCSI 硬碟的話,那麼磁碟機應該有能力自動作 re-mapping
+ 的動作。然而,因為一些未知的因素,在出廠時,很多硬碟的這項
+ 功能是關閉的...</para>
+
+ <para>要將其重新開啟,您需要編輯裝置的第一個 page 模式
+ (first device page mode),在 FreeBSD 上可以用下面的指令辦到
+ (以 <username>root</username>身分執行)</para>
+
+ <screen>&prompt.root; <userinput>scsi -f /dev/rsd0c -m 1 -e -P 3</userinput></screen>
+
+ <para>然後將 AWRE 和 ARRE 的數值從 0 變成 1:-</para>
+
+ <programlisting>AWRE(Auto Write Reallocation Enbld): 1
+ARRE(Auto Read Reallocation Enbld): 1</programlisting>
+
+ <para>以下這段是由 Ted Mittelstaedt
+ <email>tedm@toybox.placo.com</email>所提供:</para>
+
+ <para>若為 IDE 硬碟,任何的壞軌通常都是麻煩的預兆。目前所有較新的
+ IDE 硬碟,內部都有自動 remapping 壞軌的能力。目前所有 IDE 硬碟
+ 製造商,都提供了更久的保證,而且會幫您更換出現壞軌的硬碟。</para>
+
+ <para>如果您仍想要修復產生壞軌的 IDE 硬碟,您仍可以試著去下載 IDE
+ 硬碟製造商所提供的檢測程式,並用它來檢查您的硬碟。有時這些軟體可
+ 以強迫重新檢查硬碟的壞軌,並將它們標示出來。</para>
+
+ <para>對 ESDI,RLL 及 MFM 的硬碟來說,通常壞軌是正常現象,也不是什
+ 麼麻煩的前兆。在 PC 上,磁碟控制卡和 BIOS 負責標示壞軌的任務。這
+ 對一些使用 BIOS來存取磁碟的作業環境(如 DOS)是沒有問題的。然而,
+ FreeBSD 的磁碟驅動程式並不經過 BIOS 來存取磁碟,所以,有個 bad144
+ 的機制用來取代這項功能。bad144 只能用在 wd 這個磁碟驅動程式上(這
+ 個代表了 FreeBSD 4.0 並不支援它),它也無法用在 SCSI 硬碟上。
+ bad144的工作方法是將所有找到的壞軌資料存到一個特別的檔案裏。</para>
+
+ <para>使用 bad144 的警告 - 存著壞軌資料的特別檔案是放在硬碟的最後
+ 一軌上。因為這個檔案儲存的壞軌資料中,有可能有些資料是指向硬碟最
+ 前端所發生的壞軌情形,就是可能儲存 /kernel 這個檔的地方,所以它
+ 一定要能被開機程式所讀取,而開機程式是透過 BIOS 來讀取 kernel
+ 檔。這表示了使用 bad144 的硬碟絕不能擁有超過 1024 個 cylinder,
+ 16 個 head 及 63 個 sector。而這使得欲使用 bad144 的硬碟的大小不
+ 能大於 500 MB。</para>
+
+ <para>要使用 bad144 很簡單,只要在開始安裝時,在 FreeBSD fdisk 畫面
+ 把<quote>Bad Block</quote> 掃瞄設為 ON 即可。在 FreeBSD 2.2.7 以
+ 後都可以使用此方法。但這個硬碟的 cylinder 一定要在 1024 以下。使
+ 用前,我們建議這個硬碟要至少先使用四個小時,以便熱膨脹與磁軌偏移
+ 達一般狀態。</para>
+
+ <para>如果這個硬碟擁有超過 1024 個 cylinder(像大容量的 ESDI 硬碟)
+ ,ESDI 控制卡利用一個特別的轉換模式使它能在 DOS 下工作。而如果您
+ 在 fdisk 裏的 <quote>set geometry</quote> 中輸入
+ <quote>轉換過</quote> 的 geometry,wd 這個驅動程式能了解這些轉換
+ 模式。您也絕對不能使用 dangerously dedicated 模式來建立 FreeBSD
+ 的分割區,因為它會忽略 geometry 這個參數。此外,就算 fdisk 使用
+ 您所輸入的 geometry 參數,它依然會去讀取這硬碟的真正資料,而會嘗
+ 試去建立一個過大的 FreeBSD 分割區。如果磁碟的 geometry 已經被
+ <quote>轉換</quote> 過了,那麼 這個分割區 <quote>必須</quote>
+ 以手動輸入 block 數目的方法來建立。</para>
+
+ <para>一個快速的小技巧是利用 ESDI 控制卡來設定大容量的 ESDI 硬碟,
+ 用 DOS 開機片開機,再將它 format 為 DOS 的分割區。然後重開機進入
+ FreeBSD 安裝程序,在 fdisk 畫面,把DOS 分割區的 blocksize 和
+ block number 抄下來。然後重新設定 geometry 使其跟 DOS 使用的一樣。
+ 刪除 DOS 分割區,然後使用您剛剛抄下的 blocksize 來建立一個
+ <quote>cooperative</quote> FreeBSD 分割區。然後設定這個分割區為可
+ 開機,再打開壞軌掃瞄。在真正的安裝過程中,bad144 會在任何檔案系統
+ 被建立前先被執行。(您可以按 Alt-F2 來監看這一切)如果在建立壞軌資
+ 料檔時發生了問題,您會需要設定一個較大的磁碟 geometry - 這表示您
+ 需要重開機,然後全部再重新開始(包括重新分割以及在 DOS 下重新
+ format)。</para>
+
+ <para>如果 remapping 的功能已經啟動了,而您依然一直看到壞軌產生,
+ 那麼考慮換一台硬碟吧。壞軌的情形只會隨時間增加而更為嚴重。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="hpnetserver-scsi-failure">
+ <para>為什麼 FreeBSD 抓不到 HP Netserver 的 SCSI 控制卡?</para>
+ </question>
+
+ <answer>
+ <para>基本上這個是一個已知的問題。在 HP Netserver 機器上的 on-board
+ EISA 介面 SCSI 控制卡占據了定址為第 11 的 EISA 槽,因此所有的
+ <quote>真實</quote> EISA 槽都在它之前。可是,在 EISA 定址空間
+ &gt;= 10 時,會與指定給 PCI 用的定址空間相衝突,且 FreeBSD 的
+ auto-configuration 無法正確的處理這個情形。</para>
+
+ <para>因此,現在你能做的最好事情就是在 kernel 裏設定
+ <literal>EISA_SLOTS</literal> 這個選項為 12 ,然後當作沒有這個
+ 問題 :)。請依照 <ulink url="../../handbook/kernelconfig.html">
+ Handbook 中有關 kernel 的設定</ulink> 裏所說的方法來設定與編譯
+ 您的 kernel。</para>
+
+ <para>當然,在安裝 FreeBSD 到這種機器上時,這是一個雞生蛋蛋生雞的
+ 問題。為了解決這個問題,在 <emphasis>UserConfig</emphasis> 中有
+ 一個特別的方法,安裝時不要進入 <quote>visual</quote> 介面,相反
+ 的,在命令列模式中,鍵入</para>
+
+ <programlisting>eisa 12
+quit</programlisting>
+
+ <para>然後就如以往一樣安裝您的系統。不過我們建議您編譯與安裝一個
+ 屬於自己的 kernel,但</para>
+
+ <para>希望在未來的版本中能對這個問題有一個好的解決方法。</para>
+
+ <note>
+ <para>您無法在 HP Netserver 上使用
+ <literal>dangerously dedicated</literal> 磁碟模式。您可以參考
+ <link linkend="dedicate">這份註解</link> 以獲得更多資訊。</para>
+ </note>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ed1-timeout">
+ <para>一直看到類似
+ <errorname>ed1: timeout</errorname> 的訊息。它們是什麼意思呢?
+ </para>
+ </question>
+
+ <answer>
+ <para>這個通常是由於中斷衝突(interrupt conflict)所造成的
+ (例如:兩塊卡使用到了相同的 IRQ)。 FreeBSD 在 2.0.5 版以前都容許這個情形,
+ 就算有 IRQ 衝突情形,網路卡也應該仍可正常運作。然而,在 2.0.5 版及其以後,
+ 已不再容許有 IRQ 衝突的情形了。請於開機時使用 -c 這個選項,
+ 然後更改 ed0/de0/..等的設定,使其和您網路卡本身的設定一致。</para>
+
+ <para>如果您是使用您網路卡上的 BNC 接頭,您或許也會因不良的終端電阻設定,
+ 而發生裝置(device) timeout 的情形。要檢查是否有這種情形,
+ 您可以在網路卡上直接接上終端電阻(不要接網路線),
+ 然後,看看這個錯誤訊息是不是就消失了。</para>
+
+ <para>有些 NE2000 的相容卡,如果它的 UTP 埠沒有接網路線,
+ 或是該網路線並沒被使用的話,也會出現這個錯誤訊息。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="bad-3c509">
+ <para>&tm.3com; 3C509 網路卡莫名其妙罷工?</para>
+ </question>
+
+ <answer>
+ <para>這塊卡有個不好的地方在於它常常會遺失本身的設定資料。請使用該
+ 卡的 DOS 工具 <command>3c5x9.exe</command> 來更新卡上設定。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="printer-slow">
+ <para>平行埠印表速度破天荒的慢,該怎麼辦?</para>
+ </question>
+
+ <answer>
+ <para>如果唯一的問題就是速度很慢的話,試著改變您的 <ulink
+ url="../handbook/printing-intro-setup.html#PRINTING-PARALLEL-PORT-MODE">
+ 印表機連接埠設定</ulink> 這個在手冊中的
+ <ulink url="../handbook/printing-intro-setup.html">印表機設定
+ </ulink> 這個章節有加以討論。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="signal11">
+ <para>程式有時會因 <errorname>Signal 11</errorname> 錯誤而停止?</para>
+ </question>
+
+ <answer>
+ <para>Signal 11 這個錯誤是因為你的 process 嘗試要存取一塊記憶體,
+ 而你的作業系統並不允許它做這個動作而發生的。如果這種情形常常不
+ 定時發生,那麼你應該要開始看看是不是哪裡出問題了。</para>
+
+ <para>這些問題可能是與下列情形有關:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>如果這個問題只在某一個您自己寫的某個特定程式發生,那
+ 麼很有可能是您的程式碼有問題。</para>
+ </listitem>
+
+ <listitem>
+ <para>如果這個問題是在 FreeBSD 的某些系統檔案發生,有可能是
+ 因為程式有問題,但通常在我們這群讀 FAQ 的使用者去跑這些有
+ 問題的程式碼前,它們早就就已經被解決了(這是 -current 在做
+ 的事)。</para>
+ </listitem>
+ </orderedlist>
+
+ <para>尤其如果你在編譯一個程式,但是每次編譯器跑出來的結果都不一樣
+ 的話,這是一個無解的問題,而<emphasis>不是</emphasis> FreeBSD 臭蟲。</para>
+
+ <para>舉例來說,假設您正在跑 <quote>make buildworld</quote>,
+ 而 compiler 在將 <filename>ls.c</filename> 編譯成
+ <filename>ls.o</filename> 時發生錯誤,這時請再跑一次
+ <quote>make buildworld</quote>,如果 compiler 依然在同樣的地方發
+ 生問題,那麼就是程式碼有問題--請更新原始碼然後再試試看。而如果
+ compiler 是在其他的地方發生錯誤,那麼幾乎可以確定是硬體的問題了。
+ </para>
+
+ <para>您這時應該做什麼:</para>
+
+ <para>如果是第一種情形,可以使用一些 debugger,如:gdb,來找出程式
+ 是在那兒會去嘗試存取錯誤的記憶體位址,然後再修正它。</para>
+
+ <para>如果是第二種情形,就需要檢查看看是不是硬體的問題了。</para>
+
+ <para>一些造成硬體不穩的原因包括:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>可能是硬碟過熱:請檢查機殼內的風扇是否運作正常,因為您
+ 的硬碟(或者還有其他的硬體裝置)過熱了。</para>
+ </listitem>
+
+ <listitem>
+ <para>處理器過熱:這個有可能是因為超頻,或者是處理器的風扇掛了。
+ 不論是哪種原因,您都需要將所有的元件回復到它們原先設定的工作狀
+ 態,這樣才能解決這個問題。舉個例子來說:將處理器調回原先的工作
+ 頻率。</para>
+
+ <para>如果您還是堅持要超頻的話,請謹記,與其燒壞而需要換新的一台
+ 主機,不如將速度調慢一點!除此之外,不管你覺得它安不安全,一般
+ 人對於您因為超頻而發生的問題,是不會有什麼同情心的。</para>
+ </listitem>
+
+ <listitem>
+ <para>不穩定的記憶體:如果主機上有安裝數根 SIMM/DIMM 記憶體,
+ 試著把它們全拆下來,然後一根一根插上去做測試,藉此縮小範圍,
+ 以便找出有問題的某根記憶體或是某種記憶體組合。</para>
+ </listitem>
+
+ <listitem>
+ <para>最佳化過頭的主機板設定:在 BIOS 裏或是有些主機板的 jumper
+ 上,有時可以更改一些 timing,但在大多數的情形裏,使用預設值就
+ 已經足夠了。況且有時候把 RAM 的 wait states 設太小,或是在
+ BIOS 裏,把 <quote>RAM Speed: Turbo</quote> 這個或是其他類似
+ 的選項打開都有可能會造成一些不正常的現象。一個解決的方法是把
+ BIOS 設回預設值,不過在這之前記得先記下目前的設定!</para>
+ </listitem>
+
+ <listitem>
+ <para>供給主機板的電力不乾淨或是不足。試著把系統內沒有用到的
+ I/O 卡.硬碟或是 CDROM 暫時拆掉或是拔掉電源線,看看你的電源
+ 供應器是不是能夠在小一點的負荷下正常工作。不然就是換上另一
+ 個新的電源供應器,最好是瓦數高一點的(打個比方來說,如果原
+ 先的電源供應器是 250 瓦的,那麼就換上 300 瓦的試試)。</para>
+ </listitem>
+
+ </orderedlist>
+
+ <para>請順便參閱 SIG11 FAQ(連結在下面),雖然它是站在 Linux 的角
+ 度寫的,可是裡面對這些問題有許多很棒的解說。它裡面也有討論為什麼
+ 有問題的記憶體能通過軟體或硬體的測試的原因。</para>
+
+ <para>最後,如果上面這些原因都排除了,那麼有可能是遇到了 FreeBSD
+ 裏的一隻臭蟲,請參閱指示做一個問題回報。</para>
+
+ <para>這兒有一個更詳細的 FAQ - <ulink
+ url="http://www.bitwizard.nl/sig11/">
+ the SIG11 problem FAQ</ulink></para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="trap-12-panic">
+ <para>當機時出現:<errorname>Fatal trap 12: page fault in kernel mode</errorname>
+ ,或是 <errorname>panic:</errorname> 以及一堆錯誤訊息,該怎麼辦?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 的開發者對於這些錯誤訊息相當的有興趣,但是他們需要
+ 更詳細的一些細節。請把您的當機的訊息全部複製下來,接著查閱 FAQ
+ 裏 <link linkend="kernel-panic-troubleshooting">kernel
+ panics</link> 這節,依說明編譯一個含除錯碼的 kernel,以取得函式
+ 呼叫順序(backtrace)。這個聽起來很難,但實際上並不需要任何程式
+ 設計的能力,您只需要依照指示做即可。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="screen-loses-sync">
+ <para>為什麼當我開機時,螢幕變黑,且不停閃動?</para>
+ </question>
+
+ <answer>
+ <para>這個問題,已知是由 ATI Mach 64 顯示卡所引起的。因為這塊卡
+ 使用到 <literal>2e8</literal> 這個位址,而這與第四個序列埠
+ (serial port)所使用的位址相同。而在 &man.sio.4; 這個驅動
+ 程式裏,不知道是 bug 或是功能(feature),就算您沒有第四個序
+ 列埠,或是已經將 sio3(第四個序列埠)取消了,它
+ <emphasis>依然</emphasis>會去嘗試驅動它。</para>
+
+ <para>直到這個問題被解決以前,您可以使用這個方法:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>在看到開機提示時輸入 <option>-c</option>
+ (這會讓 kernel 進入設定模式)。</para>
+ </listitem>
+
+ <listitem>
+ <para>取消 <devicename>sio0</devicename> ,
+ <devicename>sio1</devicename> ,
+ <devicename>sio2</devicename> 和
+ <devicename>sio3</devicename>(全部)。
+ 這可以讓 sio 驅動程式不動作 -&gt; 於是問題解決。</para>
+ </listitem>
+
+ <listitem>
+ <para>輸入 exit 以繼續啟動程序。</para>
+ </listitem>
+ </orderedlist>
+
+ <para>如果您想要使用您的序列埠,您需要修改
+ <filename>/usr/src/sys/i386/isa/sio.c</filename>,在該檔中找出
+ <literal>0x2e8</literal> 這個字串,移除這個字串及它前面的逗號
+ (保留後面的),然後重新編譯一個新的 kernel。</para>
+
+ <para>就算使用了上面這些方法,X Window 仍然有可能無法順利執行。
+ 如果發生了這種情形,請確定你用的 XFree86 的版本是最新的 XFree86
+ 3.3.3 或是其後的版本。它們有內建支援 Mach 64 這張卡,甚至為了這
+ 些卡還附有一個特別的 X Server</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="reallybigram">
+ <para>為什麼我的系統裝有 128 MB 的 RAM,而 FreeBSD 只用了其中的
+ 64MB?</para>
+ </question>
+
+ <answer>
+ <para>因為 FreeBSD 是使用呼叫 BIOS 來取得記憶體大小的方法,因此它
+ 只能偵測到 16 bits 位元長度的 KByte 大小(65535 KBytes = 64MB)
+ (或者更少..。有些 BIOS 將最高記憶體大小限為只有 16MB)
+ 如果您擁有 64MB 以上的 RAM,FreeBSD 會嘗試去偵測出它,但是有可能
+ 會失敗。</para>
+
+ <para>要解決這個問題,您需要使用下面所提的 kernel 設定選項。雖然有
+ 方法可以從 BIOS 中取得記憶體的完整資訊,但是目前我們在開機區中並
+ 沒有多餘的空間來做這件事。當某天開機區空間不足的情形獲得解決時,
+ 我們將會使用 BIOS 的延伸功能來取得記憶體的完整資訊...但現在我們
+ 將它放在 kernel 設定選項中。</para>
+
+ <para><literal>options "MAXMEM=<replaceable>n</replaceable>"</literal></para>
+
+ <para><replaceable>n</replaceable> 是指您的記憶體大小,以 KB
+ 為單位。以一台有 128MB RAM 的機器來說,您可使用
+ <literal>131072</literal>這個數字。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="kmem-map-too-small">
+ <para>機器上的 RAM 有 1GB 以上,可是為何卻收到 <quote>kmem_map too small</quote>
+ 的 panic 錯誤訊息?
+ </para>
+ </question>
+
+ <answer>
+ <para>通常 FreeBSD 會依據機器狀況來自動調整 kernel 相關參數設定,比如:
+ 根據機器所裝的 RAM 大小來決定同時可開啟的檔案數量多寡。
+ 然而,在 1GB RAM(含以上) 的機器上,這個『自動調整』的機制可能有時會高估:
+ 比方說..開機時,kernel 會先配置各種不同用途的表格及其他架構放到記憶體上,
+ 然後,當整個作業系統都開始運作之後,kernel 就會開始不夠空間來做記憶體配置的動態調整,
+ 於是就 panic 掛了。</para>
+
+ <para>解法是:把 <option>VM_KMEM_SIZE_MAX</option> 加到 kernel 設定檔內,
+ 並重新編譯 kernel,比如:</para>
+
+ <para><literal><option>options VM_KMEM_SIZE_MAX=419430400</option></literal></para>
+
+ <para>
+ 這樣會設定 400&nbsp;MB 來給 kernel 使用,而且採用 400&nbsp;MB 的話,
+ 目前在 6GB RAM 的機器上都可被有效運用。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="panic-kmemmap-too-small">
+ <para>機器上 RAM 不到 1GB ,但仍會出現
+ <errorname>kmem_map too small!</errorname> 的 panic 錯誤訊息
+ </para>
+ </question>
+
+ <answer>
+ <para>之所以 panic 的原因在於系統用光了給 network buffer 用途的 virtual memory
+ (尤其是 mbuf clusters)。解法是增加給 mbuf clusters 用的 virtual memory
+ 數量,這步驟請參閱 FreeBSD 使用手冊的
+ <ulink
+ url="&url.books.handbook;/configtuning-kernel-limits.html#NMBCLUSTERS">網路限制篇</ulink>
+ 。</para>
+ </answer>
+ </qandaentry>
+
+<!--
+以下為舊版 faq 內容
+ <para>這個 panic 的原因是表示系統用光了給網路緩衝區的所有的虛
+ 擬記憶體(特別是 mbuf clusters)。您可以增加給 mbuf clusters
+ 的 VM 的數量,只要加入:</para>
+
+ <para><literal>options "NMBCLUSTERS=<replaceable>n</replaceable>"</literal></para>
+
+ <para>在您的 kernel 設定檔中,<replaceable>n</replaceable>
+ 是一個在 512-4096 間的數字,依您想提供多少同時的 TCP 連接數目
+ 多寡而定。我會建議試試 2048 - 這數字應該可以完全避免這個 panic
+ 了。您可以執行: <command>netstat -m</command>
+ (see &man.netstat.1;)來監看有多少 mbuf clusters 在系統上正被
+ 配置/使用。NMBCLUSTERS 的數值內定為 <literal>512 + MAXUSERS * 16
+ </literal>。</para>
+-->
+
+ <qandaentry>
+ <question id="proc-table-full">
+ <para>為什麼我一直看到 <errorname>/kernel: proc: table
+ is full</errorname> 這個錯誤訊息?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD kernel 只允許一定數量的 process 在同一時間裡同
+ 時運作。而這個數目是根據 kernel 設定檔裡面的
+ <literal>MAXUSERS</literal> 值來決定的。<literal>MAXUSERS</literal>
+ 這個值也會影響其他的 kernel 內定值,比如說 network buffer
+ (請參閱<link linkend="panic-kmemmap-too-small">這個</link>之前討
+ 論過的問題)。如果機器負荷(load)很重,您可能需要增加
+ <literal>MAXUSERS</literal> 這個值。這麼作會一併提高系統的其他內
+ 定值,包括最大可擁有的 process 數等。</para>
+
+ <para>若要調整 <literal>MAXUSERS</literal>,請參閱 FreeBSD 使用手冊中的 <ulink
+ url="&url.books.handbook;/configtuning-kernel-limits.html#KERN-MAXFILES">
+ 檔案/Process的限制</ulink> 章節。
+ (雖然該處指的是『檔案的開啟數量限制』,但也適用於 process部分。)</para>
+
+ <para>在 FreeBSD 4.4 之後,<literal>MAXUSERS</literal> 已經變成可
+ 以靠著更改 <filename>/boot/loader.conf</filename> 裏的
+ <varname>kern.maxusers</varname> 這個值而調整的變數了。而在之前
+ 的 FreeBSD 版本中,這個值只能在 kernel 設定檔裏調整。</para>
+
+ <para>如果機器負荷並不重,而您只是需要同時跑很多很多 process,
+ 那麼也可以直接用 sysctl 調整 <varname>kern.maxproc</varname> 值。
+ 假如這些 process 都是屬於某個使用者的,那麼您還需要另
+ 外調整 <varname>kern.maxprocperuid</varname> 這個值,使它比新
+ 的 <varname>kern.maxproc</varname> 這個值少 1 (一定要少 1 ,
+ 因為 &man.init.8; 這個系統程式絕對要保持在運作狀態)。</para>
+
+ <para>如果想在每次開機都要更改 sysctl 的值,而且您的 FreeBSD 是
+ 最近的版本的話,請在 <filename>/etc/sysctl.conf</filename> 這
+ 個檔中設定,而如果是舊的版本,可以在
+ <filename>/etc/rc.local</filename> 中作設定。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="cmap-busy-panic">
+ <para>為什麼用新 kernel 開機時,出現 <errorname>CMAP
+ busy</errorname> 這個錯誤訊息?</para>
+ </question>
+
+ <answer>
+ <para>用來偵測 <filename>/var/db/kvm_*.db</filename> 過時檔案的機制偶爾會發生問題,而使用到了一個不協調
+ (mismatch)的檔案有時就會導致 panic。</para>
+
+ <para>如果發生了這個問題,請重新開機,進入 single 使用者模式,然後執行:</para>
+
+ <screen>&prompt.root; <userinput>rm /var/db/kvm_*.db</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="brkadrint-illegal-host-access">
+ <para>請問這個訊息:<errorname>ahc0: brkadrint, Illegal Host Access at seqaddr 0x0</errorname>
+ 是什麼意思?</para>
+ </question>
+
+ <answer>
+ <para>這是一個和 Ultrastor SCSI 控制卡有關的衝突(conflict)。</para>
+
+ <para>在開機時,進入 kernel 設定選單取消
+ <devicename>uha0</devicename>,它是造成這個問題的原因。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="aci0-illegal-cable">
+ <para>開機時,看到這個錯誤訊息 <errorname>ahc0: illegal cable configuration</errorname>。
+ 我的排線確定有接對。 是出了什麼問題呢?</para>
+ </question>
+
+ <answer>
+ <para>您的主機板可能不支援自動終端電阻設定。請進到 SCSI 的 BIOS
+ 裡面手動指定正確的終端電阻順序,而不要使用自動設定。
+ AIC7XXX 的驅動程式並無法知道有沒有這些排線偵測(以及自動終端電阻設定)的電路(external logic)
+ 存在。如果 EEPROM 裡面的設定是 "automatic termination" 時,它只會單純假定這些電路當然是存在的。
+ 若缺少了這個電路,驅動程式在設定終端電阻時就常常出問題。
+ 而這種問題將導致 SCSI 匯流排的可靠性降低。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="mail-loopback">
+ <para>為什麼 Sendmail 一直出現
+ <quote><errorname>mail loops back to myself</errorname></quote>
+ 這個錯誤訊息?</para>
+ </question>
+
+ <answer>
+ <para>這個問題在 sendmail 的 FAQ 中是這樣回答的:-</para>
+
+<literallayout> * 我一直收到有關 "Local configuration error" 的信件,例如:
+
+ 553 relay.domain.net config error: mail loops back to myself
+ 554 &lt;user@domain.net&gt;... Local configuration error
+
+ 我要如何解決這個問題?
+
+ 您利用 MX 設定,讓要寄到某 domain(如: domain.net)的信件,
+ 寄到您所指定的機器(在這個例子中為 relay.domain.net),但是這
+ 部機器並未被設定接受 domain.net 的信件。請把 domain.net 加到
+ /etc/sendmail.cw 中(如果您有使用 FEATURE(use_cw_file)) 或是
+ 在 sendmail.cf 中加入 "Cw domain.net"
+ </literallayout>
+
+ <para>最新版本的 <ulink url="ftp://rtfm.mit.edu/pub/usenet/news.answers/mail/sendmail-faq">sendmail
+ FAQ</ulink> 現在已不再隨著 sendmail <quote>出貨</quote>。
+ 它目前是被定期的發表在 <ulink
+ url="news:comp.mail.sendmail">comp.mail.sendmail</ulink>,
+ <ulink url="news:comp.mail.misc">comp.mail.misc</ulink>,<ulink
+ url="news:comp.mail.smail">comp.mail.smail</ulink>,<ulink
+ url="news:comp.answers">comp.answers</ulink>,和 <ulink
+ url="news:news.answers">news.answers</ulink>. 您也可以寄一封
+ Email 到 <email>mail-server@rtfm.mit.edu</email>,然後在信件內文
+ 中寫上
+ <literal>send usenet/news.answers/mail/sendmail-faq</literal>
+ 以取得這份 FAQ 文件。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="remote-fullscreen">
+ <para>為什麼執行遠端機器(remote machine)的全螢幕的軟體時,
+ 有不正常的情形?</para>
+ </question>
+
+ <answer>
+ <para>或許遠端機器並非將您的終端機模式設為 FreeBSD console 所用的
+ <literal>cons25</literal>,而是設為其它模式。</para>
+
+ <para>這兒有幾個解決這個問題的方法:</para>
+ <itemizedlist>
+ <listitem>
+ <para>在 logging 進遠端機器後,更改您的 shell 變數 TERM 為
+ <literal>ansi</literal> 或是 <literal>sco</literal>
+ ﹙如果遠端機器支援這些模式的話)。</para>
+ </listitem>
+
+ <listitem>
+ <para>使用支援 VT100 的模擬軟體,如 FreeBSD console 下的
+ <application>screen</application> 軟體。
+ <application>screen</application> 提供您在一個 terminal
+ 裏同時跑好幾個 session 的能力,而且它本身也是一個相當好
+ 的軟體。每個 <application>screen</application> 都像是一個
+ VT100 的終端機,所以遠端機器的 TERM 變數應該設為
+ <literal>vt100</literal>。</para>
+ </listitem>
+
+ <listitem>
+ <para>在遠端機器的終端機資料庫(terminal database)中加入
+ <literal>cons25</literal> 的資料。加入的方法視遠端機器的
+ 作業系統不同而有所差異。請參閱遠端機器給系統管理員的說明
+ 書,應該會有所幫助。</para>
+ </listitem>
+
+ <listitem>
+ <para>啟動 FreeBSD 的 X 伺服器,然後使用一些 X Window 下的
+ 終端機模擬器來登入遠端機器,例如 <command>xterm</command>
+ 或 <command>rxvt</command>。而遠端機器的 TERM 變數應該要
+ 設為 <literal>xterm</literal> 或 <literal>vt100</literal>。
+ </para>
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="calcru-negative">
+ <para>為什麼我的機器一直顯示
+ <errorname>calcru: negative time...</errorname>?</para>
+ </question>
+
+ <answer>
+ <para>跟中斷(interrupt)有關的不同硬體 與/或 軟體的搭配都有可能造成
+ 這個問題。這有可能是 bug 或是某個裝置本身的問題。在平行埠上使用
+ 大的 MTU 來作 TCP/IP 傳輸可以重現這個問題。若是圖形加速卡造成這個
+ 問題的話,您應該先檢查卡的中斷設定。</para>
+
+ <para>這個問題的邊際效應是會造成有些 process 出現
+ <quote>SIGXCPU exceeded cpu time limit</quote> 的訊息,而不正常
+ 停止。</para>
+
+ <para>若是 FreeBSD 3.0 或是 1998 年 11 月 29 日以後其他版本,萬一
+ 這個問題一直無法以其他方法解決,就只能設定 sysctl 變數:</para>
+
+ <screen>&prompt.root; <userinput>sysctl -w kern.timecounter.method=1</userinput></screen>
+
+ <para>這樣會對效能有些影響,但是若考慮到這個問題帶來的後果,這樣做
+ 是值得的。如果這個問題還是存在的話,讓 sysctl 那個值依然設為 1,
+ 然後增加 kernel 設定檔中 <literal>NTIMECOUNTER</literal> 這個選
+ 項的數值。如果您將 <literal>NTIMECOUNTER</literal> 增加到 20 依
+ 然無法解決這個問題,那麼您機器上的中斷已經多到無法讓計數器維持在
+ 可靠的狀態了。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="pcm0-not-found">
+ <para>出現 <errorname>pcm0 not found</errorname> 這個訊息,或者是
+ 我的音效卡變成了 <devicename>pcm1</devicename>,但在 kernel 設定
+ 檔裏我是設 <literal>device pcm0</literal> 啊。這是怎麼回事呢?
+ </para>
+ </question>
+
+ <answer>
+ <para>如果您在 FreeBSD 3.x 上使用 PCI 音效卡就會發生這種問題。
+ 因為<devicename>pcm0</devicename> 這個 device 是內定保留給 ISA
+ 的音效卡的,所以如果您有一張 PCI 的音效卡,您就會遇到這個問題,
+ 而您的卡會變成 <devicename>pcm1</devicename>。</para>
+
+ <note>
+ <para>如果您只把 kernel 設定檔中的設定改成
+ <literal>device pcm1</literal> 是無法除去這個警告訊息的,
+ 這樣會造成 <devicename>pcm1</devicename> 被保留給 ISA 音效卡,
+ 而 PCI 音效卡則會變成 <devicename>pcm2</devicename>
+ (外加 <errorname>pcm1 not found</errorname> 的警告訊息)。
+ </para>
+ </note>
+
+ <para>如果您有一張 PCI 的音效卡,您需要 make
+ <devicename>snd1</devicename> 這個 device,而不是
+ <devicename>snd0</devicename>:</para>
+
+ <screen>&prompt.root; <userinput>cd /dev</userinput>
+&prompt.root; <userinput>./MAKEDEV snd1</userinput></screen>
+
+ <para>這個問題在 FreeBSD 4.x 上並不會發生,因為很多人投下了許多心
+ 力讓它更<emphasis>PnP 導向</emphasis>,而且
+ <devicename>pcm0</devicename> 這個 device 也不再是只保留給 ISA
+ 的音效卡了。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="pnp-not-found">
+ <para>為什麼在更新到 FreeBSD 4.X 後會抓不到我的 PnP 卡
+ (或者是抓成 <literal>unknown</literal>)?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 4.X 現在已經更 <emphasis>PnP 導向</emphasis>了,
+ 而邊際效應就是會發生有些在 FreeBSD 3.X 可以用的 PnP 裝置
+ (如音效卡或是內插式數據機)變成無法使用。</para>
+
+ <para>這個原因可以用一封由 Peter Wemm 發到 freebsd-questions
+ 這個 mailing list 上的信來解釋,它原本是解釋為什麼有一個內
+ 插式數據機,在系統升級到 FreeBSD 4.x 後,就沒法被抓到了
+ (在 <literal>[]</literal> 裏的是另外加的註解,讓內容更易懂)。
+ </para>
+
+ <blockquote>
+ <para>The PNP bios preconfigured it [the modem] and left it
+ laying around in port space,so [in 3.x] the old-style ISA
+ probes <quote>found</quote> it there.</para>
+
+ <para>Under 4.0,the ISA code is much more PnP-centric. It was
+ possible [in 3.x] for an ISA probe to find a
+ <quote>stray</quote> device and then for the PNP device id to
+ match and then fail due to resource conflicts. So,it
+ disables the programmable cards first so this double probing
+ cannot happen. It also means that it needs to know the PnP
+ id's for supported PnP hardware. Making this more user
+ tweakable is on the TODO list.</para>
+ </blockquote>
+
+ <para>如果要讓裝置能再度運作,我們需要找出它的 PnP id,然後再將它
+ 加入一份在偵測 ISA 裝置時會使用的表中。可以執行 &man.pnpinfo.8;
+ 來偵測這個裝置,舉例來說,下面是 &man.pnpinfo.8; 抓到的一個內插
+ 式數據機的資料:</para>
+
+ <screen>&prompt.root; <userinput>pnpinfo</userinput>
+Checking for Plug-n-Play devices...
+
+Card assigned CSN #1
+Vendor ID PMC2430 (0x3024a341),Serial Number 0xffffffff
+PnP Version 1.0,Vendor Version 0
+Device Description: Pace 56 Voice Internal Plug & Play Modem
+
+Logical Device ID: PMC2430 0x3024a341 #0
+ Device supports I/O Range Check
+TAG Start DF
+ I/O Range 0x3f8 .. 0x3f8,alignment 0x8,len 0x8
+ [16-bit addr]
+ IRQ: 4 - only one type (true/edge)</screen>
+
+ <para>[more TAG lines elided]</para>
+
+ <screen>TAG End DF
+End Tag
+
+Successfully got 31 resources,1 logical fdevs
+-- card select # 0x0001
+
+CSN PMC2430 (0x3024a341),Serial Number 0xffffffff
+
+Logical device #0
+IO: 0x03e8 0x03e8 0x03e8 0x03e8 0x03e8 0x03e8 0x03e8 0x03e8
+IRQ 5 0
+DMA 4 0
+IO range check 0x00 activate 0x01</screen>
+
+ <para>您所需要的資訊是一開始看到的 <quote>Vendor ID</quote>
+ 這一行。括號中的十六位元碼(這個例子中是 0x3024a341)就是
+ PnP id,而在這之前的字串(PMC2430)則是一個獨一無二的 ASCII id。
+ 而這些資料需要被加到 <filename>/usr/src/sys/isa/sio.c</filename>
+ 這個檔案裏。</para>
+
+ <para>為了防止任何東西出錯,您應該要先備份目前的
+ <filename>sio.c</filename>。而且您要 submit PR 時也需要這個
+ 原始檔案來做出 patch(您應該會將它 submit PR 吧..:)..)。
+ 接著就編輯 <filename>sio.c</filename> 找尋下面這行</para>
+
+ <programlisting>static struct isa_pnp_id sio_ids[] = {</programlisting>
+
+ <para>接著往下捲動,找個正確的位置來插入您的裝置資訊。您看到的就
+ 下面這個樣子,它們是照右邊註解裡面的 ASCII 這個 Vender ID 做排
+ 序的,或是 &man.pnpinfo.8; 所找到的一部分
+ <emphasis>裝置描述</emphasis>:</para>
+
+ <programlisting>{0x0f804f3f,NULL}, /* OZO800f - Zoom 2812 (56k Modem) */
+{0x39804f3f,NULL}, /* OZO8039 - Zoom 56k flex */
+{0x3024a341,NULL}, /* PMC2430 - Pace 56 Voice Internal Modem */
+{0x1000eb49,NULL}, /* ROK0010 - Rockwell ? */
+{0x5002734a,NULL}, /* RSS0250 - 5614Jx3(G) Internal Modem */</programlisting>
+
+ <para>把您這個裝置的十六進位的 Vender ID 加到正確的地方,存檔,
+ 然後重新編一個 kernel,再重開機。之後這個裝置應該就會像在
+ FreeBSD 3.X 下,被偵測為 <literal>sio</literal> 裝置了。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="nlist-failed">
+ <para>為什麼我常常在跑一些程式(例如 <command>top</command> 或
+ <command>systat</command>)的時候出現
+ <errorname>nlist failed</errorname> 這個錯誤訊息?</para>
+ </question>
+
+ <answer>
+ <para>這個問題是因為您跑的程式需要一個特別的 kernel symbol,可是
+ 不知道什麼原因而找不到﹔而會發生這個問題可能是因為下面兩個原因:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>您的 kernel 和 userland 的檔案版本並不一致(例如說,您
+ 編了一個新的 kernel,但是並沒有執行對應的
+ <maketarget>installworld</maketarget>,或是其他類似情形),
+ 因此 symbol table 的內容就和應用程式編譯時的不太一樣了。如
+ 果是這種情形,請執行完整的升級步驟(請參閱
+ <filename>/usr/src/UPDATING</filename> 以得知正確的流
+ 程)。</para>
+ </listitem>
+
+ <listitem>
+ <para>您沒有用 <command>/boot/loader</command> 來載入您的
+ kernel,而是直接由 boot2 開機(請參閱 &man.boot.8;)。
+ 雖然說跳過 <command>/boot/loader</command> 並沒有什麼錯,
+ 但是它在 kernel symbols 跟應用程式的溝通方面佔了很重的份量。
+ </para>
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="connection-delay">
+ <para>為什麼我用 <command>ssh</command> 或 <command>telnet</command>
+ 連到我的電腦時,會等待很長的一段時間才能連上?</para>
+ </question>
+
+ <answer>
+ <para>症狀:TCP 連線建立之後和詢問密碼之前(如果是在說 &man.telnet.1;
+ 的話,則是 login 提示符號跳出來之前),要等待很長的一段時
+ 間。</para>
+
+ <para>問題所在:這種延遲情形常常是因為伺服軟體(server software)
+ 嘗試要將客戶端(client)的 IP 位址轉換成主機名稱。因為很多伺服
+ 軟體,包括 FreeBSD 內建的 Telnet 和 SSH,為了將主機名稱寫入紀
+ 錄檔中以供管理者作參考,而會做這項動作。</para>
+
+ <para>解決方法:如果這個問題在您連接不同的伺服器時都會發生,那麼
+ 問題是在您客戶端這一方﹔同樣的,如果別人只有在連到您的伺服器上
+ 才會發生這個情形,那麼問題就是在伺服器這邊了。</para>
+
+ <para>如果是客戶端這方有問題,唯一的方法就是將 DNS 伺服器修好,
+ 這樣對方伺服器才能正確的轉換名稱。如果問題是在內部區域網路發
+ 生的,這應該是伺服器有問題,請詳細檢查一下﹔相反的,如果是您
+ 在上 Internet 時發生的,那麼您需要跟您的 ISP 聯絡,請他們解決
+ 這個問題。</para>
+
+ <para>如果是伺服器這邊的問題,而且是發生在內部區域網路,那麼您需
+ 要設定這個伺服器,使它能正確將內部網路的 IP 位址轉換為主機名稱。
+ 請參閱 &man.hosts.5; 和 &man.named.8; 的說明以獲得更多資訊。如
+ 果是在 Internet 上的伺服器發生這個問題,那麼有可能是您伺服器的
+ 轉換功能出問題。您可以試試查詢另一個主機名稱,比如:
+ <hostid>www.yahoo.com</hostid>。如果查不到,那麼可以確定是您這
+ 邊出問題了。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="stray-irq">
+ <para><errorname>stray IRQ</errorname> 這個錯誤訊息是什麼意思?</para>
+ </question>
+ <answer>
+ <para>Stray IRQs 是硬體 IRQ 有點小問題的現象,大多是因為硬體本身
+ 在發出中斷需求後,又取消了它自己的中斷要求。</para>
+ <para>有三個方法可以應付這個問題:</para>
+ <itemizedlist>
+ <listitem>
+ <para>不理會這個警告。反正一個 irq 出現五次警告後系統就不會
+ 再顯示了。</para>
+ </listitem>
+ <listitem>
+ <para>把 <function>isa_strayintr()</function> 裏的值,由 5
+ 改成 0,這樣所有的警告訊息都不會出現。</para>
+ </listitem>
+ <listitem>
+ <para>安裝使用 irq 7 的平行埠硬體設備,以及它的 PPP 驅動程式
+ (這個大部分系統都有做),接著安裝 ide 硬碟或是其他會使用
+ irq 15 的硬體設備以及它的驅動程式。</para>
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="file-table-full">
+ <para>為什麼 <errorname>file: table is full</errorname> 這個訊息
+ 一直在 dmesg 裏重複出現?</para>
+ </question>
+ <answer>
+ <para>這個錯誤訊息代表了您系統的 file descriptors 已經使用光了。
+ 請參閱手冊內 <ulink url="../handbook/configtuning-kernel-limits.html">
+ Tuning Kernel Limits</ulink> 裡面的 <ulink
+ url="../handbook/configtuning-kernel-limits.html#KERN-MAXFILES">
+ kern.maxfiles</ulink> 這個章節,裡面有一些討論及解決方法。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="laptop-clock-skew">
+ <para>為什麼我筆記型電腦上的時鐘一直顯示錯誤的時間?</para>
+ </question>
+
+ <answer>
+ <para>您的筆記型電腦裡有兩個以上的時鐘,而 FreeBSD 選到了錯的
+ 那個。</para>
+
+ <para>執行 &man.dmesg.8;,檢查一下有 <literal>Timecounter</literal>
+ 字串的那幾行。最後一行是 FreeBSD 選用的,通常是
+ <literal>TSC</literal>。</para>
+
+ <screen>&prompt.root; <userinput>dmesg | grep Timecounter</userinput>
+Timecounter "i8254" frequency 1193182 Hz
+Timecounter "TSC" frequency 595573479 Hz</screen>
+
+ <para>您可以執行 &man.sysctl.3; 看一下
+ <varname>kern.timecounter.hardware</varname> 這個值做確認。</para>
+
+ <screen>&prompt.root; <userinput>sysctl kern.timecounter.hardware</userinput>
+kern.timecounter.hardware: TSC</screen>
+
+ <para>BIOS 可能在一些情形下會更改 TSC 的時脈&mdash;有時候是因為
+ 在使用電池工作時會更改處理器的速度,另外也有可能是進入了省電模
+ 式,可是 FreeBSD 並不會察覺到這些調整,而會發生時間增加或是減
+ 少的情形。</para>
+
+ <para>在上面的例子當中,我們看到還有 <literal>i8254</literal>
+ 這個時鐘可以選擇,執行 &man.sysctl.3; 用手動的方式將這個值寫入
+ <varname>kern.timecounter.hardware</varname> 中。</para>
+
+ <screen>&prompt.root; <userinput>sysctl -w kern.timecounter.hardware=i8254</userinput>
+kern.timecounter.hardware: TSC -&gt; i8254</screen>
+
+ <para>這樣您的筆記型電腦應該就可以保持正確的時間了。</para>
+
+ <para>如果要讓這個更改的動作再每次開機時自動執行,在
+ <filename>/etc/sysctl.conf</filename> 裏加入下面這行。</para>
+
+ <programlisting>kern.timecounter.hardware=i8254</programlisting>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="null-null">
+ <para>為什麼我的筆記型電腦無法正確的偵測到 PC card ?</para>
+ </question>
+
+ <answer>
+ <para>這個問題常常發生在灌了多個作業系統的筆記型電腦上。有些非
+ BSD 的作業系統會讓 PC card 的硬體裝置處在一個不一致的狀態下
+ (inconsistent state)。使得 <command>pccardd</command> 在偵
+ 測這片卡時,無法抓到正確的型號,而是
+ <errorname>"(null)""(null)"</errorname>。</para>
+
+ <para>您需要移除 PC card 插槽的電源以重置這個硬體裝置。一個方法是
+ 將您的筆記型電腦關機(不是休眠模式,也不是待命模式﹔要完全的關
+ 機)。等個幾秒鐘再重開機。這樣您的 PC card 應該就正常了。</para>
+
+ <para>有時有些筆記型電腦雖然看起來已經關機了,但實際上並沒有。
+ 如果您發現上面那個方法沒有用,請關機,移除電池,等個幾秒鐘,
+ 把電池裝上去然後重開機。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="boot-read-error">
+ <para>為什麼在 BIOS 畫面之後,FreeBSD 的 boot loader 顯示
+ <errorname>Read error</errorname> 然後就停止不動了?</para>
+ </question>
+
+ <answer>
+ <para>這是因為FreeBSD 的 boot loader 無法正確的找出硬碟的
+ geometry。這樣的話,就需要在用 fdisk 分割或是修改 FreeBSD
+ 的 slice 時,手動將正確的值輸入進去了。</para>
+ <para>正確的硬碟 geometry 值在 BIOS 裡面可以查的到。注意該硬碟的
+ cylinders,heads 以及 sectors 這些數值。</para>
+ <para>在執行 &man.sysinstall.8;的 fdisk 時,按下 <keycap>G</keycap>
+ 以便手動設定硬碟的 geometry。</para>
+ <para>這時會有一個對話框跳出來,詢問您有關 cylinders,heads 以及
+ sectors 這些東西的值。請將剛剛在 BIOS 查到的數字,以 / 作分隔輸
+ 入進去。</para>
+ <para>舉例來說,如果是 5000 cylinders,250 sectors 和 60 sectors
+ 就輸入 <userinput>5000/250/60</userinput></para>
+ <para>輸入完後請按 enter 鍵確認,最後按下 <keycap>W</keycap> 鍵把
+ 新的分割區表寫入硬碟當中。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="bootmanager-restore">
+ <para>另一個作業系統摧毀了我的 Boot Manager。我要怎麼樣才能把它還
+ 原回來?</para>
+ </question>
+
+ <answer>
+ <para>執行 &man.sysinstall.8; 接著選 Configure,然後選 Fdisk。
+ 再來用<keycap>空白</keycap>鍵選擇原先 Boot Manager 所在的硬碟。
+ 按下 <keycap>W</keycap> 鍵來作寫入的動作。這時會跳出一個提示
+ 訊息,詢問您要安裝哪一個 boot loader。請選擇 Boot Manager,
+ 這樣就可以將它還原了。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="indefinite-wait-buffer">
+ <para>這個錯誤訊息:<errorname>swap_pager: indefinite
+ wait buffer:</errorname> 是什麼意思呢?</para>
+ </question>
+
+ <answer>
+ <para>這個訊息是說有一個執行程序正在嘗試將分頁記憶體(page memory)
+ 寫入硬碟中,而這個動作嘗試了 20 秒鐘仍然無法成功。這個有可能是因為
+ 硬碟有壞軌、電路或排線有問題、以及其他跟硬碟讀出寫入有關的硬體設備。
+ 如果真的是硬碟壞軌的問題,您應該會在
+ <filename>/var/log/messages</filename>這個檔案中,或是在執行
+ <command>dmesg</command>這個指令後,看到有關磁碟錯誤的訊息。
+ 如果沒有,那麼請檢查您的排線還有接頭連接是否良好。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="touch-not-found">
+ <para>為何在 buildworld/installworld 時,會趴在
+ <errorname>touch: not found</errorname> 的錯誤訊息?</para>
+ </question>
+
+ <answer>
+ <para>這錯誤訊息並不是指 &man.touch.1; 程式不見了,事實上可能是該檔檔案時間被設為未來的時間。
+ 若機器上的 CMOS-clock 時鐘設定為當地時間
+ (非格林威治時間,比如台灣時間為 GMT +08:00 ,也就是 CST 中原標準時間),
+ 那麼請在開機時,先選 single user 模式進入,然後打
+ <command>adjkerntz&nbsp;-i</command>
+ 來調整 kernel clock 與機器上的 CMOS-clock 來同步。</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+ <chapter id="commercial">
+ <chapterinfo>
+ <author>
+ <firstname>Vanilla</firstname>
+ <surname>Shu</surname>
+ <affiliation>
+ <address><email>vanilla@FreeBSD.org</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>商業軟體</title>
+
+ <note>
+ <para>這一節的內容還是相當少,不過我們當然希望各個公司能為它加點內容 :)
+ FreeBSD 組織和列在這裡的任何一家公司都沒有金錢上的利害關係,列出來純粹只是對大眾公開介紹(同時也認為在 FreeBSD
+ 上的商機若興旺,會對 FreeBSD 可長可久有極正面的效益)。我們鼓勵商業軟體的廠商把他們的產品包括在下面的名單中,在
+ <ulink url="../../../../commercial/index.html">Vendors page</ulink> 可以看到更長的列表。</para>
+ </note>
+
+ <qandaset>
+ <qandaentry>
+ <question id="officesuite">
+ <para>在哪邊找到給 FreeBSD 用的 Office 套件呢?</para>
+ </question>
+
+ <answer>
+ <para><ulink
+ url="http://www.openoffice.org">OpenOffice</ulink> 這套 open-source 性質的 office
+ 可以在 FreeBSD 上正常運用自如,而 &linux; 版的
+ <ulink
+ url="http://www.sun.com/staroffice/">StarOffice</ulink>,
+ 這套 closed-source 的 OpenOffice 加值版,也可以在 FreeBSD 上正常使用。</para>
+
+ <para>FreeBSD 上還有許多編排軟體、試算表(Spreadsheet)以及繪圖軟體都可用 Ports
+ Collection 來安裝喔。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="motif">
+ <para>在哪邊可找到給 FreeBSD 用的 Motif?</para>
+ </question>
+
+ <answer>
+ <para>Open Group 釋出了 Motif 2.1.30 的原始碼,可以透過
+ <literal>open-motif</literal> package 安裝,或是由 ports 自行
+ 編譯。相關的資訊,請參考 handbook 中的 <ulink
+ url="../handbook/ports.html">ports</ulink> 章節。
+
+ <note>
+ <para>Open Motif 只能在同樣也是 <ulink
+ url="http://www.opensource.org/">open source</ulink>
+ 的作業系統或計劃中使用。</para>
+ </note>
+ </para>
+
+ <para>另外,也是有商業版本的 Motif 存在。也許這種版本的 Motif
+ 不是免費的,但是絕對允許用在 closed-source 的環境下。
+ <link linkend="apps2go">Apps2go</link> 提供了最便宜的 FreeBSD
+ (包括 i386 跟 alpha)版本的 ELF Motif 2.1.20 套件。
+ <anchor id="apps2go"/></para>
+
+ <para>目前提供兩種不同環境的版本, <quote>發展用版本</quote> 及
+ <quote>runtime 版本</quote> 。這兩種套件都包括:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>OSF/Motif manager, xmbind, panner, wsm.</para>
+ </listitem>
+
+ <listitem>
+ <para>Development kit with uil, mrm, xm, xmcxx, include
+ and Imake files.</para>
+ </listitem>
+
+ <listitem>
+ <para>Static and dynamic ELF libraries (for use with
+ FreeBSD 3.0 and above).</para>
+ </listitem>
+
+ <listitem>
+ <para>Demonstration applets.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>因為 <emphasis>Apps2go</emphasis> 也有提供 NetBSD 和 OpenBSD
+ 的版本,所以在訂購時請特別指定是要 FreeBSD 版本的 Motif!
+ 他們目前只提供以 FTP 的方式取得這份套件。</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>更多資訊</term>
+ <listitem>
+ <para><ulink url="http://www.apps2go.com/">
+ Apps2go WWW page</ulink></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>或</term>
+ <listitem>
+ <para>
+ <email>sales@apps2go.com</email> 或
+ <email>support@apps2go.com</email>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>或</term>
+ <listitem>
+ <para>phone (817) 431 8775 or +1 817 431-8775</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>也可以聯絡 <link linkend="xig">Xi Graphics</link>,他們提供了一個
+ FreeBSD a.out 格式的 Motif 2.0 套件。</para>
+
+ <para>在這套件中包括了:</para>
+ <itemizedlist>
+ <listitem>
+ <para>OSF/Motif manager, xmbind, panner, wsm.</para>
+ </listitem>
+
+ <listitem>
+ <para>Development kit with uil, mrm, xm, xmcxx, include
+ and Imake files.</para>
+ </listitem>
+
+ <listitem>
+ <para>Static and dynamic libraries (for use with FreeBSD
+ 2.2.8 and earlier).</para>
+ </listitem>
+
+ <listitem>
+ <para>Demonstration applets.</para>
+ </listitem>
+
+ <listitem>
+ <para>Preformatted man pages.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>在你跟他們訂購 Motif 時,請一定註明你要的是 FreeBSD 的版本!
+ 因為 <emphasis>Xi Graphics</emphasis> 也同時提供了 BSDI 跟 Linux
+ 版本的 Motif。目前發行的版本是放在四塊磁片中,將來他們會將所有的
+ 東西都放到光碟裡,就像他們所發行的 CDE 一樣。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="cde">
+ <para>在哪邊可找到給 FreeBSD 用的 CDE?</para>
+ </question>
+
+ <answer>
+ <para><link linkend="xig">Xi Graphics</link> 以前有賣 FreeBSD 用的
+ CDE,不過現已停止發售了。</para>
+
+ <para>就許多方面而言,<ulink url="http://www.kde.org/">KDE</ulink> 這個 open
+ source 的桌面環境與 CDE 相當類似。此外,你可能會喜歡使用 <ulink
+ url="http://www.xfce.org/">xfce</ulink>。KDE 及 xfce 都可由 <ulink url="&url.base;/ports/index.html">ports
+ 機制</ulink>來安裝。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="commercial-xserver">
+ <para>有沒有要錢,但是高效率的 X servers?</para>
+ </question>
+
+ <answer>
+ <para>有, <ulink url="http://www.xig.com/">Xi Graphics</ulink>
+ 有提供給 FreeBSD(或其他 Intel 平台上)用的 X 視窗加速產品。</para>
+
+
+ <para>Xi Graphics 所提供的高效能 X Server 有非常簡單的設定方式,
+ 並且支援了目前市面上當紅的各大廠牌的顯示卡。它只給你 Binary 檔案,
+ 是用磁片的方式發行,FreeBSD 跟 Linux 版本都相同。Xi Graphics 同時
+ 也提供了專門給筆記型電腦用的高效能 X Server。<anchor id="xig"/></para>
+
+ <para>5.0 版有提供免費的相容 <quote>demo</quote> 版本</para>
+
+ <para>Xi Graphics 也有在賣 FreeBSD 用的 Motif 跟 CDE(往上面看看)。
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>更多的資訊</term>
+ <listitem>
+ <para><ulink url="http://www.xig.com/">
+ Xi Graphics WWW page</ulink></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>或</term>
+ <listitem>
+ <para><email>sales@xig.com</email>
+ 或 <email>support@xig.com</email>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>或</term>
+ <listitem>
+ <para>phone (800) 946 7433 or +1 303 298-7478.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="database-systems">
+ <para>在 FreeBSD 上有任何的資料庫嗎?</para>
+ </question>
+
+ <answer>
+ <para>有! 請看 FreeBSD 網站上 <ulink
+ url="../../../../commercial/software_bycat.html#CATEGORY_DATABASE">
+ 商業軟體公司 </ulink> 這一部份。</para>
+
+ <para>還有請參考 ports 中 <ulink
+ url="../../../../ports/databases.html">
+ Databases</ulink> 相關的收集。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="oracle-support">
+ <para>可以在 FreeBSD 上執行 Oracle 嗎?</para>
+ </question>
+
+ <answer>
+ <para>可以,下面這個網頁會說明如何在 FreeBSD 上執行 Linux
+ 版的 Oracle:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink
+ url="http://www.scc.nl/~marcel/howto-oracle.html">
+ http://www.scc.nl/~marcel/howto-oracle.html</ulink></para>
+ </listitem>
+
+ <listitem>
+ <para><ulink
+ url="http://www.lf.net/lf/pi/oracle/install-linux-oracle-on-freebsd">
+
+ http://www.lf.net/lf/pi/oracle/install-linux-oracle-on-freebsd</ulink></para>
+
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+ <chapter id="applications">
+ <chapterinfo>
+ <author>
+ <firstname>Kang-min</firstname>
+ <surname>Liu</surname>
+ <affiliation>
+ <address><email>gugod@gugod.org</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>一般應用程式</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="user-apps">
+ <para>嗯..我要在哪找到我要的程式呢?</para>
+ </question>
+
+ <answer>
+ <para>請看看 <ulink url="../../../../ports/index.html">ports
+ 目錄</ulink> 吧。這邊有份已經 port 到 FreeBSD 的軟體列表。
+ 目前有超過 &os.numports; 個軟體已經被port 到 FreeBSD 上,並且每天
+ 都在增加中。所以有空就多看看這份列表,不然你也可以訂閱
+ <literal>freebsd-announce</literal> <link linkend="mailing">
+ 這份 mailing list</link>,會有人將每個星期最新的軟體列表貼在上面。</para>
+
+ <para>大部份的 ports 應該都可以在 4.X、5.X 跟 6.X 的系統上使用。
+ 每次當 FreeBSD release 新版時,都會有一份 ports tree 被放在這一個
+ release cd 裡面的 <filename>ports/</filename> 目錄裡。</para>
+
+ <para>我們也支援一種叫 <quote>package</quote> 的概念,基本上
+ 就是 gzip 壓縮、可用來發行的 binary 檔案,但是裡面藏了一
+ 些相當有用的資訊,可以給各種自訂安裝來使用。使用者不必知
+ 道某個 package 裡究竟有包括哪些檔案,就可`以很方便地重複將
+ 它安裝/反安裝。</para>
+
+ <para>你可以執行 <filename>sysinstall</filename>(&os; 5.2 之前版本則是 <command>/stand/sysinstall</command>) 後,
+ 在 post-configuration 選單下選擇 package 這個安裝選項;或
+ 是對某個有興趣的 package 檔案執行 &man.pkg.add.1;
+ 把它裝起來。Package 檔案通常以 <filename>.tgz</filename> 或 <filename>.tbz</filename>
+ 為副檔名,手上有 FreeBSD CDROM 的人可以在 <filename>packages/All</filename> 這個目錄下找到這類檔案。
+ 對不同的 FreeBSD 版本,也可以從下列位址由網路上取得:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>給 4.X-RELEASE/4-STABLE 用的</term>
+ <listitem>
+ <para><ulink
+ url="ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-4-stable/">
+ ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-4-stable/</ulink></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>給 5.X-RELEASE/5-STABLE 用的</term>
+ <listitem>
+ <para><ulink
+ url="ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-5-stable/">
+ ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-5-stable</ulink></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>給 6.X-RELEASE/6-STABLE 用的</term>
+ <listitem>
+ <para><ulink
+ url="ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-6-stable/">
+ ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-6-stable</ulink></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>給 7-CURRENT 用的</term>
+ <listitem>
+ <para><ulink
+ url="ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-7-current/">
+ ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-7-current</ulink></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>或是離你最近的 mirror 站。</para>
+
+ <para>要注意的是,因為新的 port 一直在增加中,所以並不是所有 port
+ 都有相對應的 package。最好定時檢查<ulink
+ url="ftp://ftp.FreeBSD.org/pub/FreeBSD/">ftp.FreeBSD.org</ulink>
+ ,看看有哪些 package 可以用。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="configure-inn">
+ <para>該怎麼設定 INN(Internet News) 來當 news server?</para>
+ </question>
+
+ <answer>
+ <para>以 package 或 port 方式來裝好 <filename
+ role="package">news/inn</filename> 之後,<ulink
+ url="http://www.visi.com/~barr/INN.html">Dave
+ Barr's INN Page</ulink> 是個非常好的 INN 入門處,你可以在那邊找到 INN 的 FAQ。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="java">
+ <para>FreeBSD 有支援 &java; 嗎?</para>
+ </question>
+
+ <answer>
+ <para>有啊,請看 <ulink
+ url="&url.base;/java/index.html">
+ http://www.FreeBSD.org/java/</ulink></para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="missing-libcso30">
+ <para>我可以在哪邊找到 libc.so.3.0?</para>
+ </question>
+
+ <answer>
+ <para>你可能在一台 2.1.x 的機器上,跑著給 2.2/3.x/4.0 的軟體。
+ 請再往上面一個章節看,正確的取得給你機器用的 port/package。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="missing-libcso40">
+ <para>為何我得到了這個訊息 ?<errorname>Error: can't find
+ libc.so.4.0</errorname>?</para>
+ </question>
+
+ <answer>
+ <para>你不小心抓了給 4.X 及 5.X 系統用的 package,並且嘗試著
+ 去裝在你的 2.X 或 3.X 的系統上面。請下載正確版本的 package。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="emul">
+ <para> ghostscript 在我的 386/486SX 上有點問題呢!</para>
+ </question>
+
+ <answer>
+ <para>你沒有浮點運算器,對吧?你必須在你的 kernel 中加入數學
+ 運算模擬器,你可以跟著下面的步驟做,並在更改過你的 kernel 設定
+ 檔後,重新編譯過一次。</para>
+
+ <programlisting>options GPL_MATH_EMULATE</programlisting>
+
+ <note>
+ <para>當你加入上一行的同時,你必須將
+ <literal>MATH_EMULATE</literal> 移除掉。</para>
+ </note>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="sco-socksys">
+ <para>為什麼當我執行 SCO/iBCS2 的程式時,它在
+ <errorname>socksys</errorname> 這個地方出了問題?
+ (FreeBSD 3.0 以及更早的版本才有此問題。)</para></question>
+
+ <answer>
+ <para>你必須先修改 <filename>/etc/sysconfig</filename> (或是
+ <filename>/etc/rc.conf</filename>, 請讀 &man.rc.conf.5;)
+ 這檔案最後一個章節,將下面所講到的變數設成
+ <literal>YES</literal>:</para>
+
+ <programlisting># Set to YES if you want ibcs2 (SCO) emulation
+ loaded at startup ibcs2=NO</programlisting>
+
+ <para>這會在開機時將 ibcs2 這一個 kernel 模組載入。</para>
+
+ <para>你還要將你的 /compat/ibcs2/dev 改成下面這樣:</para>
+
+ <screen>lrwxr-xr-x 1 root wheel 9 Oct 15 22:20 X0R@ -&gt; /dev/null
+lrwxr-xr-x 1 root wheel 7 Oct 15 22:20 nfsd@ -&gt; socksys
+-rw-rw-r-- 1 root wheel 0 Oct 28 12:02 null
+lrwxr-xr-x 1 root wheel 9 Oct 15 22:20 socksys@ -&gt; /dev/null
+crw-rw-rw- 1 root wheel 41, 1 Oct 15 22:14 spx</screen>
+
+ <para>你只需要將 socksys 轉向到 <devicename>/dev/null</devicename>
+ (請讀 &man.null.4;) 去騙過 open &amp; close 的動作。在 -current
+ 裡面的 ibcs2 相關程式碼將會處理其餘的部份,這種作法比以前的方式
+ 乾淨太多了。假如你想要使用 <devicename>spx</devicename> 方面的
+ 程式,在你的 kernel 設定檔裡面 加上<literal>SPX_HACK</literal>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ms-frontpage">
+ <para>我該使用那個版本的 Microsoft FrontPage?</para>
+ </question>
+
+ <answer>
+ <para>Use the Port, Luke!在 ports tree 中已經有一個包含 FrontPage
+ 的 Apache 版本了。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ports-3x">
+ <para>為什麼我無法在 3.X-STABLE 機器上順利編好這個 port?</para>
+ </question>
+
+ <answer>
+ <para>如果你的 FreeBSD 版本相較 -CURRENT 或 -STABLE 之下是很古
+ 早的話,或許你會需要一個升級 ports 的工具,在
+ <ulink url="../../../../ports/index.html">
+ http://www.FreeBSD.org/ports/</ulink>。如果你以將其更新卻仍無用,
+ 那麼一定是某人更動之後造成 -CURRENT 才能用,-STABLE 無法用的情況。
+ 由於 ports 內所收集的軟體在 -CURRENT 或是 -STABLE 上都要能用,
+ 所以請儘速送出關於此問題的蟲報告;請使用 &man.send-pr.1; 這個指
+ 令來送蟲報告。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="find-ldso">
+ <para>那裡可以找得到 ld.so?</para>
+ </question>
+
+ <answer>
+ <para>有些 a.out 格式的應用程式會需要 a.out 格式的函式庫,
+ Netscape Navigator 就是一個例子。不過用 ELF 函式庫編起來
+ 的 FreeBSD 預設並不會安裝舊的 a.out 函式庫,所以您可能會得
+ 到類似找不到 <filename>/usr/libexec/ld.so</filename> 的抱怨訊
+ 息。如果說您的系統有這安裝 a.out 函式庫的必要,這些函式庫
+ (compat22) 也能夠利用 &man.sysinstall.8; 來安裝。或者利用
+ FreeBSD 原始碼來安裝:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src/lib/compat/compat22</userinput>&prompt.root; <userinput>make install clean</userinput></screen>
+
+ <para>如果你希望每次 <command>make world</command> 時會自動更新
+ compat22 函式庫,那麼修改 <filename>/etc/make.conf</filename>,
+ 加入 <varname>COMPAT22=YES</varname>。這些相容於古老版本的函式庫
+ 已經沒什麼在更新了,所以一般說來是不需要這樣的。</para>
+
+ <para>同時也請您看一下 3.1-RELEASE 和 3.2-RELEASE 的勘誤表(ERRATA)。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ports-update">
+ <para>我更新了系統原始碼,現在我要怎樣升級某個已經安裝上
+ 的 ports ?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 本身並沒有自動升級 ports 的工具,但有一些可以讓升級
+ 簡化一些的小程式。你也可以自己裝上額外的工具來處理。</para>
+
+ <para>&man.pkg.version.1; 指令可以自動產生用來達到自動升級到
+ ports tree 最新版本的 script。</para>
+
+ <screen>&prompt.root; <userinput>pkg_version <option>-c</option> > <replaceable>/tmp/myscript</replaceable></userinput></screen>
+
+ <para><emphasis>一定要</emphasis>在手動修改一下產生出來的 script。
+ 目前的 &man.pkg.version.1; 在 script 最前面加入 &man.exit.1; 強
+ 迫你去修改它。</para>
+
+ <para>你應將執行 script 所產生的輸出記錄下來,因為裡面會有記載某些
+ 尚未升級但已經更新的 ports。不過你不一定要去升級它們。通常是因為
+ 有某個共用的函式庫已經改變版本號了,才要去重編一次那些使用到該函
+ 式庫的 ports。</para>
+
+ <para>如果你的硬碟空間很夠,那麼可以用 <command>portupgrade</command>
+ 這個工具來做全自動處裡。<command>portupgrade</command> 裡面也有
+ 一些小程式來簡化 package 升級,它在
+ <filename role="package">sysutils/portupgrade</filename>。
+ 這個工具是用 Ruby 這個語言寫的,所以並不適合加入到 FreeBSD 的原
+ 始碼中,不過並不會因此讓某些人不用它。</para>
+
+ <para>如果你的系統一直都處於開機狀態,可利用 &man.periodic.8; 系統,
+ 每個星期產生一張需要升級的清單。只要在
+ <filename>/etc/periodic.conf</filename> 加入
+ <literal>weekly_status_pkg_enable="YES"</literal> 就可以了。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="minima-sh">
+ <para>為什麼 <command>/bin/sh</command>這麼的小?為什麼 FreeBSD
+ 不改用 <command>bash</command> 或者是其他比較強悍的 shell?</para>
+ </question>
+
+ <answer>
+ <para>因為 POSIX 說,該要有這麼樣的一個 shell 在才行。</para>
+
+ <para>比較繁瑣的答案:許多人需要寫可以跨很多平台的 shell script 。
+ 這也是為何 POSIX 將 shell 以及工具命稱都定義的非常詳細的緣故。
+ 大部份的 script 都適用於 Bourne shell,又因為有幾個重要的
+ 寫程式所用到的程式或者函式 (&man.make.1; , &man.system.3;,
+ &man.popen.3;, 還有在 Perl 或者 Tcl 裡面呼叫系統程式的地方)
+ 都指定用 Bourne shell 。那麼因為 Bourne Shell 如此的廣泛常用,
+ 那麼它的執行效率便很重要,快速是它決定性的要點之一,還要不佔太多
+ 記憶體。</para>
+
+ <para>目前的 <command>/bin/sh</command> 已是我們嘔心瀝血之作,它已
+ 經盡量地符合標準規定。為了讓它非常小,我們拿掉了一些其他 shell
+ 有的方便功能。這也是為什麼 ports 裡面還有很多強悍的 shell ,像是
+ bash, scsh, tcsh 以及 zsh 。 (你可以自己比較一下這些 shell 執行
+ 時所佔的記憶體大小,去看看 <command>ps -u</command> 列出來的
+ <quote>VSZ</quote> 和 <quote>RSS</quote> 這兩個欄位就知道了。)
+ </para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="netscape-slow-startup">
+ <para>為什麼 Netscape 和 Opera 要花好久的時間才能啟動?</para>
+ </question>
+
+ <answer>
+ <para>通常是因為你的 DNS 沒有設定好。 Netscape 跟 Opera 在啟動的時候
+ 都會去檢查一下 DNS。直到 DNS 有回應,或者是斷定網路目前是斷線之後,
+ 它們才會顯示畫面出來。</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+
+ <chapter id="kernelconfig">
+ <chapterinfo>
+ <author>
+ <firstname>Kang-min</firstname>
+ <surname>Liu</surname>
+ <affiliation>
+ <address><email>gugod@gugod.org</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>kernel 設定</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="make-kernel">
+ <para>我想自訂 kernel,這會很困難嗎?</para>
+ </question>
+
+ <answer>
+ <para>不會!請查閱 <ulink url="../../handbook/kernelconfig.html">
+ 使用手冊中的 kernel 設定一節</ulink>。</para>
+
+ <note>
+ <para>我會建議你在你讓核心能正常工作後,做一個
+ <filename>kernel.YYMMDD</filename> 日期形式的備份,同時也備份
+ <filename>/module</filename>這個目錄至
+ <filename>/modules.YYMMDD</filename>。這樣下次如果你很不幸的玩
+ 壞了設定,至少可以不需要使用最原始的
+ <filename>kernel.GENERIC</filename>。如你正從一個 GENERIC
+ kernel 裡面不支援的控制器裡啟動時,這就顯得特別重要。</para>
+ </note>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="missing-hw-float">
+ <para>我的核心因為 <literal>_hw_float</literal>遺失而編譯失敗。
+ 該怎麼修正呢?</para>
+ </question>
+
+ <answer>
+ <para>讓我猜看看,你把 <devicename>npx0</devicename>
+ (詳見 &man.npx.4;) 從你的 kernel 設定檔移除了,因為你沒有數學運算器,
+ 對嗎?錯了!:-) 這個 <devicename>npx0</devicename>是
+ <emphasis>必須要有的</emphasis>。就算你沒有數學運算器,你還是
+ <emphasis>必須</emphasis> 引入 <devicename>npx0</devicename> 裝置。
+ </para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="why-kernel-big">
+ <para>為什麼造出來的 kernel 這麼大 (10MB 以上) ?</para>
+ </question>
+
+ <answer>
+ <para>這很有可能是因為,你把 kernel 編成 <emphasis>偵錯模式</emphasis>
+ 了。偵錯模式之下的 kernel 裡面會存著偵錯用的許多符號,因此會大幅
+ 增加 kernel 的大小。如果說你的 FreeBSD 是 3.0 以後的版本,這對於
+ 效能來說影響並不大,幾乎是沒有。而在系統會因某些原因 panic 時,
+ 有個偵錯模式的 kernel 在也挺有用的。</para>
+
+ <para>不過呢,如果你的磁碟空間很小,或者你就是不想用偵錯模式的
+ kernel 的話,請確認以下事情:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>kernel 設定檔裡面沒有這一行:</para>
+
+ <programlisting>makeoptions DEBUGS=-g </programlisting>
+ </listitem>
+
+ <listitem>
+ <para>執行 &man.config.8; 時沒有加上 <option>-g</option>
+ 這個選項。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>以上兩件事情都會讓你編出一個偵錯模式的 kernel。但只要避免之,
+ 就可以編出一個正常的 kernel,而你也會注意到,kernel 明顯的變小了;
+ 大部份的 kernel 都差不多在 1.5MB 到 2MB 之間。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="multiport-serial-interrupts">
+ <para>為何出現了 multi-port serial code 的中斷衝突?</para>
+ </question>
+
+ <answer>
+ <para>當我編譯一個 multi-port serial code 的核心時,它告訴我只有
+ 第一個被偵測到,其他的則因中斷衝突而跳過了,我該怎麼修正它?</para>
+
+ <para>這個問題是因為 FreeBSD 使用內建程式碼避免因為硬體或軟體衝突
+ 導致 kernel 過於肥大或無用。要修正這種情形的方法是除了一個 port
+ 外把其他所有的 IRQ 設定都做保留。這裡有一個範例:</para>
+
+ <programlisting>#
+# Multiport high-speed serial line - 16550 UARTS
+#
+device sio2 at isa? port 0x2a0 tty irq 5 flags 0x501 vector siointr
+device sio3 at isa? port 0x2a8 tty flags 0x501 vector siointr
+device sio4 at isa? port 0x2b0 tty flags 0x501 vector siointr
+device sio5 at isa? port 0x2b8 tty flags 0x501 vector siointr</programlisting>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="generic-kernel-build-failure">
+ <para>為什麼我一個 kernel 都編不起來?甚至 GENERIC 也不行?</para>
+ </question>
+
+ <answer>
+ <para>這有很多種可能的原因:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>你沒有用新的 <command>make buildkernel</command> 與
+ <command>make installkernel</command> 這兩個方法來編,而正好
+ 你的系統原始碼的版本和正在執行的系統核心版本不一樣 (像是,
+ 在跑 4.0-RELEASE 的系統上嘗試著編 4.3-RELEASE)。如果說你要升
+ 級系統的話,請務必去看看 <filename>/usr/src/UPDATING</filename>
+ 這個檔案,特別注意最後面的 <quote>COMMON ITEMS</quote>
+ 這個小節。</para>
+ </listitem>
+
+ <listitem>
+ <para>你已經用上 <command>make buildkernel</command> 以及
+ <command>make installkernel</command> 了,但是在
+ <command>make buildworld</command> 時失敗了。可惜的是,
+ <command>make buildkernel</command> 要成功,需要依賴
+ <command>make buildworld</command> 後造出來的一些檔案。</para>
+ </listitem>
+
+ <listitem>
+ <para>就算是你在編 <link linkend="stable">&os.stable;</link>,
+ 還是有可能你抓到了正在修改中,或著因為某些緣故而根本還沒改好
+ 的原始碼;雖然說 <link linkend="stable">&os.stable;</link>
+ 大部份的時候都是可以編的,但只有 RELEASE 才是保證可以編的。碰
+ 到這個問題時,再次更新原始碼並且再試試看。也有可能是放原始碼的
+ 伺服器出現某些問題,所以更新原始碼時也試試從不同伺服器來更新看
+ 看。</para>
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+ <chapter id="disks">
+ <title>硬碟、檔案系統、Boot Loader</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="new-huge-disk">
+ <para>我要怎麼把我的系統搬到新硬碟上面去?</para>
+ </question>
+
+ <answer>
+ <para>理想的方式是先在新硬碟上重裝好作業系統,然後把使用者相關程式、資料搬過去就好。
+ This is highly
+ recommended if you have been tracking -STABLE for more
+ than one release, or have updated a release instead of
+ installing a new one. You can install booteasy on both
+ disks with &man.boot0cfg.8;, and dual boot them until
+ you are happy with the new configuration. Skip the
+ next paragraph to find out how to move the data after
+ doing this.</para>
+
+ <para>Should you decide not to do a fresh install, you
+ need to partition and label the new disk with either
+ <filename>sysinstall</filename>(&os; 5.2 之前版本則是 <command>/stand/sysinstall</command>), or &man.fdisk.8;
+ and &man.disklabel.8;. You should also install booteasy
+ on both disks with &man.boot0cfg.8;, so that you can
+ dual boot to the old or new system after the copying
+ is done.</para>
+
+ <para>Now you have the new disk set up, and are ready
+ to move the data. Unfortunately, you cannot just blindly
+ copy the data. Things like device files (in
+ <filename>/dev</filename>), flags, and links tend to
+ screw that up. You need to use tools that understand
+ these things, which means &man.dump.8;.
+ Although it is suggested that you move the data in single user
+ mode, it is not required.</para>
+
+ <para>You should never use anything but &man.dump.8; and
+ &man.restore.8; to move the root filesystem. The
+ &man.tar.1; command may work - then again, it may not.
+ You should also use &man.dump.8; and &man.restore.8;
+ if you are moving a single partition to another empty
+ partition. The sequence of steps to use dump to move
+ a partitions data to a new partition is:</para>
+
+ <procedure>
+ <step>
+ <para>newfs the new partition.</para>
+ </step>
+
+ <step>
+ <para>mount it on a temporary mount point.</para>
+ </step>
+
+ <step>
+ <para>cd to that directory.</para>
+ </step>
+
+ <step>
+ <para>dump the old partition, piping output to the
+ new one.</para>
+ </step>
+ </procedure>
+
+ <para>For example, if you are going to move root to
+ <devicename>/dev/ad1s1a</devicename>, with
+ <filename>/mnt</filename> as the temporary mount point,
+ it is:</para>
+
+ <screen>&prompt.root; <userinput>newfs /dev/ad1s1a</userinput>
+&prompt.root; <userinput>mount /dev/ad1s1a /mnt</userinput>
+&prompt.root; <userinput>cd /mnt</userinput>
+&prompt.root; <userinput>dump 0af - / | restore xf -</userinput></screen>
+
+ <para>Rearranging your partitions with dump takes a bit more
+ work. To merge a partition like <filename>/var</filename>
+ into its parent, create the new partition large enough
+ for both, move the parent partition as described above,
+ then move the child partition into the empty directory
+ that the first move created:</para>
+
+ <screen>&prompt.root; <userinput>newfs /dev/ad1s1a</userinput>
+&prompt.root; <userinput>mount /dev/ad1s1a /mnt</userinput>
+&prompt.root; <userinput>cd /mnt</userinput>
+&prompt.root; <userinput>dump 0af - / | restore xf -</userinput>
+&prompt.root; <userinput>cd var</userinput>
+&prompt.root; <userinput>dump 0af - /var | restore xf -</userinput></screen>
+
+ <para>To split a directory from its parent, say putting
+ <filename>/var</filename> on its own partition when it was not
+ before, create both partitions, then mount the child partition
+ on the appropriate directory in the temporary mount point, then
+ move the old single partition:</para>
+
+ <screen>&prompt.root; <userinput>newfs /dev/ad1s1a</userinput>
+&prompt.root; <userinput>newfs /dev/ad1s1d</userinput>
+&prompt.root; <userinput>mount /dev/ad1s1a /mnt</userinput>
+&prompt.root; <userinput>mkdir /mnt/var</userinput>
+&prompt.root; <userinput>mount /dev/ad1s1d /mnt/var</userinput>
+&prompt.root; <userinput>cd /mnt</userinput>
+&prompt.root; <userinput>dump 0af - / | restore xf -</userinput></screen>
+
+ <para>You might prefer &man.cpio.1;, &man.pax.1;,
+ &man.tar.1; to &man.dump.8; for user data. At the time of
+ this writing, these are known to lose file flag information,
+ so use them with caution.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="dangerously-dedicated">
+ <para>Will a <quote>dangerously dedicated</quote> disk endanger
+ my health?</para>
+ </question>
+
+ <answer>
+
+ <para><anchor id="dedicate"/>The installation procedure allows
+ you to chose two different methods in partitioning your
+ hard disk(s). The default way makes it compatible with other
+ operating systems on the same machine, by using fdisk table
+ entries (called <quote>slices</quote> in FreeBSD), with a
+ FreeBSD slice that employs partitions of its own. Optionally,
+ one can chose to install a boot-selector to switch between the
+ possible operating systems on the disk(s). The alternative uses
+ the entire disk for FreeBSD, and makes no attempt to be
+ compatible with other operating systems.</para>
+
+ <para>So why it is called <quote>dangerous</quote>? A disk
+ in this mode does not contain what normal PC utilities
+ would consider a valid fdisk table. Depending on how well
+ they have been designed, they might complain at you once
+ they are getting in contact with such a disk, or even
+ worse, they might damage the BSD bootstrap without even
+ asking or notifying you. In addition, the
+ <quote>dangerously dedicated</quote> disk's layout is
+ known to confuse many BIOSes, including those from AWARD
+ (e.g. as found in HP Netserver and Micronics systems as
+ well as many others) and Symbios/NCR (for the popular
+ 53C8xx range of SCSI controllers). This is not a complete
+ list, there are more. Symptoms of this confusion include
+ the <errorname>read error</errorname> message printed by
+ the FreeBSD bootstrap when it cannot find itself, as well
+ as system lockups when booting.</para>
+
+ <para>Why have this mode at all then? It only saves a few kbytes
+ of disk space, and it can cause real problems for a new
+ installation. <quote>Dangerously dedicated</quote> mode's
+ origins lie in a desire to avoid one of the most common
+ problems plaguing new FreeBSD installers - matching the BIOS
+ <quote>geometry</quote> numbers for a disk to the disk
+ itself.</para>
+
+ <para><quote>Geometry</quote> is an outdated concept, but one
+ still at the heart of the PC's BIOS and its interaction with
+ disks. When the FreeBSD installer creates slices, it has to
+ record the location of these slices on the disk in a fashion
+ that corresponds with the way the BIOS expects to find them. If
+ it gets it wrong, you will not be able to boot.</para>
+
+ <para><quote>Dangerously dedicated</quote> mode tries to work
+ around this by making the problem simpler. In some cases, it
+ gets it right. But it is meant to be used as a last-ditch
+ alternative - there are better ways to solve the problem 99
+ times out of 100.</para>
+
+ <para>So, how do you avoid the need for <quote>DD</quote> mode
+ when you are installing? Start by making a note of the geometry
+ that your BIOS claims to be using for your disks. You can
+ arrange to have the kernel print this as it boots by specifying
+ <option>-v</option> at the <literal>boot:</literal> prompt, or
+ using <command>boot -v</command> in the loader. Just before the
+ installer starts, the kernel will print a list of BIOS
+ geometries. Do not panic - wait for the installer to start and
+ then use scrollback to read the numbers. Typically the BIOS
+ disk units will be in the same order that FreeBSD lists your
+ disks, first IDE, then SCSI.</para>
+
+ <para>When you are slicing up your disk, check that the disk
+ geometry displayed in the FDISK screen is correct (ie. it
+ matches the BIOS numbers); if it is wrong, use the
+ <keycap>g</keycap> key to fix it. You may have to do this if
+ there is absolutely nothing on the disk, or if the disk has been
+ moved from another system. Note that this is only an issue with
+ the disk that you are going to boot from; FreeBSD will sort
+ itself out just fine with any other disks you may have.</para>
+
+ <para>Once you have got the BIOS and FreeBSD agreeing about the
+ geometry of the disk, your problems are almost guaranteed to be
+ over, and with no need for <quote>DD</quote> mode at all. If,
+ however, you are still greeted with the dreaded <errorname>read
+ error</errorname> message when you try to boot, it is time to cross
+ your fingers and go for it - there is nothing left to
+ lose.</para>
+
+ <para>To return a <quote>dangerously dedicated</quote> disk
+ for normal PC use, there are basically two options. The first
+ is, you write enough NULL bytes over the MBR to make any
+ subsequent installation believe this to be a blank disk. You
+ can do this for example with</para>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/zero of=/dev/rda0 count=15</userinput></screen>
+
+ <para>Alternatively, the undocumented DOS
+ <quote>feature</quote></para>
+
+ <screen><prompt>C:\&gt;</prompt> <userinput>fdisk /mbr</userinput></screen>
+
+ <para>will to install a new master boot record as well, thus
+ clobbering the BSD bootstrap.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="safe-softupdates">
+ <para>Which partitions can safely use Soft Updates? I have
+ heard that Soft Updates on <filename>/</filename> can cause
+ problems.</para>
+ </question>
+
+ <answer>
+ <para>Short answer: you can usually use Soft Updates safely
+ on all partitions.</para>
+
+ <para>Long answer: There used to be some concern over using
+ Soft Updates on the root partition. Soft Updates has two
+ characteristics that caused this. First, a Soft Updates
+ partition has a small chance of losing data during a
+ system crash. (The partition will not be corrupted; the
+ data will simply be lost.) Also, Soft Updates can cause
+ temporary space shortages.</para>
+
+ <para>When using Soft Updates, the kernel can take up to
+ thirty seconds to actually write changes to the physical
+ disk. If you delete a large file, the file still resides
+ on disk until the kernel actually performs the deletion.
+ This can cause a very simple race condition. Suppose you
+ delete one large file and immediately create another large
+ file. The first large file is not yet actually removed
+ from the physical disk, so the disk might not have enough
+ room for the second large file. You get an error that the
+ partition does not have enough space, although you know
+ perfectly well that you just released a large chunk of
+ space! When you try again mere seconds later, the file
+ creation works as you expect. This has left more than one
+ user scratching his head and doubting his sanity, the
+ FreeBSD filesystem, or both.</para>
+
+ <para>If a system should crash after the kernel accepts a
+ chunk of data for writing to disk, but before that data is
+ actually written out, data could be lost or corrupted.
+ This risk is extremely small, but generally manageable.
+ Use of IDE write caching greatly increases this risk; it
+ is strongly recommended that you disable IDE write caching
+ when using Soft Updates.</para>
+
+ <para>These issues affect all partitions using Soft Updates.
+ So, what does this mean for the root partition?</para>
+
+ <para>Vital information on the root partition changes very
+ rarely. Files such as <filename>/kernel</filename> and
+ the contents of <filename>/etc</filename> only change
+ during system maintenance, or when users change their
+ passwords. If the system crashed during the
+ thirty-second window after such a change is made, it is
+ possible that data could be lost. This risk is negligible
+ for most applications, but you should be aware that it
+ exists. If your system cannot tolerate this much risk,
+ do not use Soft Updates on the root filesystem!</para>
+
+ <para><filename>/</filename> is traditionally one of the
+ smallest partitions. By default, FreeBSD puts the
+ <filename>/tmp</filename> directory on
+ <filename>/</filename>. If you have a busy
+ <filename>/tmp</filename>, you might see intermittent
+ space problems. Symlinking <filename>/tmp</filename> to
+ <filename>/var/tmp</filename> will solve this
+ problem.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="inappropriate-ccd">
+ <para>What is inappropriate about my ccd?</para>
+ </question>
+
+ <answer>
+ <para>The symptom of this is:</para>
+
+ <screen>&prompt.root; <userinput>ccdconfig -C</userinput>
+ccdconfig: ioctl (CCDIOCSET): /dev/ccd0c: Inappropriate file type or format</screen>
+
+ <para>This usually happens when you are trying to concatenate
+ the <literal>c</literal> partitions, which default to type
+ <literal>unused</literal>. The ccd driver requires the
+ underlying partition type to be FS_BSDFFS. Edit the disklabel
+ of the disks you are trying to concatenate and change the types
+ of partitions to <literal>4.2BSD</literal>.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ccd-disklabel">
+ <para>Why can I not edit the disklabel on my ccd?</para>
+ </question>
+
+ <answer>
+ <para>The symptom of this is:</para>
+
+ <screen>&prompt.root; <userinput>disklabel ccd0</userinput>
+(it prints something sensible here, so let us try to edit it)
+&prompt.root; <userinput>disklabel -e ccd0</userinput>
+(edit, save, quit)
+disklabel: ioctl DIOCWDINFO: No disk label on disk;
+use "disklabel -r" to install initial label</screen>
+
+ <para>This is because the disklabel returned by ccd is actually
+ a <quote>fake</quote> one that is not really on the disk.
+ You can solve this problem by writing it back explicitly,
+ as in:</para>
+
+ <screen>&prompt.root; <userinput>disklabel ccd0 &gt; /tmp/disklabel.tmp</userinput>
+&prompt.root; <userinput>disklabel -Rr ccd0 /tmp/disklabel.tmp</userinput>
+&prompt.root; <userinput>disklabel -e ccd0</userinput>
+(this will work now)</screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="mount-foreign-fs">
+ <para>Can I mount other foreign filesystems under FreeBSD?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD supports a variety of other
+ filesystems.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Digital UNIX</term>
+
+ <listitem>
+ <para>UFS CDROMs can be mounted directly on FreeBSD.
+ Mounting disk partitions from Digital UNIX and other
+ systems that support UFS may be more complex, depending
+ on the details of the disk partitioning for the operating
+ system in question.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&linux;</term>
+
+ <listitem>
+ <para>FreeBSD supports <literal>ext2fs</literal>
+ partitions. See &man.mount.ext2fs.8; for more
+ information.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&windowsnt;</term>
+
+ <listitem>
+ <para>FreeBSD includes a read-only NTFS driver. For
+ more information, see &man.mount.ntfs.8;.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>FAT</term>
+
+ <listitem>
+ <para>FreeBSD includes a read-write FAT driver. For
+ more information, see &man.mount.msdosfs.8;.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>FreeBSD also supports network filesystems such as NFS
+ (see &man.mount.nfs.8;), NetWare (see &man.mount.nwfs.8;),
+ and Microsoft-style SMB filesystems (see
+ &man.mount.smbfs.8;).</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="mount-dos">
+ <para>How do I mount a secondary DOS partition?</para>
+ </question>
+
+ <answer>
+
+ <para>The secondary DOS partitions are found after ALL the
+ primary partitions. For example, if you have an
+ <quote>E</quote> partition as the second DOS partition on
+ the second SCSI drive, you need to create the special files
+ for <quote>slice 5</quote> in <filename>/dev</filename>,
+ then mount <devicename>/dev/da1s5</devicename>:</para>
+
+ <screen>&prompt.root; <userinput>cd /dev</userinput>
+&prompt.root; <userinput>sh MAKEDEV da1s5</userinput>
+&prompt.root; <userinput>mount -t msdos /dev/da1s5 /dos/e</userinput></screen>
+
+ <note>
+ <para>You can omit this step if you are running FreeBSD
+ 5.0-RELEASE or newer with &man.devfs.5;
+ enabled.</para>
+ </note>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="crypto-filesystem">
+ <para>&os; 有檔案加密系統嗎?</para>
+ </question>
+
+ <answer>
+
+ <para>有啊! FreeBSD 5.0 起內建 &man.gbde.8;,而 FreeBSD 6.0
+ 又加上 &man.geli.8;。 而較早期的版本,請多利用 <filename
+ role="package">security/cfs</filename> port,謝謝。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="nt-bootloader">
+ <para>How can I use the &windowsnt; loader to boot FreeBSD?</para>
+ </question>
+
+ <answer>
+ <para>The general idea is that you copy the first sector of your
+ native root FreeBSD partition into a file in the DOS/&windowsnt;
+ partition. Assuming you name that file something like
+ <filename>c:\bootsect.bsd</filename> (inspired by
+ <filename>c:\bootsect.dos</filename>), you can then edit the
+ <filename>c:\boot.ini</filename> file to come up with something
+ like this:</para>
+
+ <programlisting>[boot loader]
+timeout=30
+default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
+[operating systems]
+multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows NT"
+C:\BOOTSECT.BSD="FreeBSD"
+C:\="DOS"</programlisting>
+
+ <para>If FreeBSD is installed on the same disk as the &windowsnt; boot
+ partition simply copy <filename>/boot/boot1</filename> to
+ <filename>C:\BOOTSECT.BSD</filename>. However, if FreeBSD is
+ installed on a different disk <filename>/boot/boot1</filename>
+ will not work, <filename>/boot/boot0</filename> is needed.</para>
+
+ <para><filename>/boot/boot0</filename> needs to be installed
+ using sysinstall(&os; 5.2 之前版本則是 <command>/stand/sysinstall</command>) by selecting the FreeBSD boot manager on
+ the screen which asks if you wish to use a boot
+ manager. This is because <filename>/boot/boot0</filename>
+ has the partition table area filled with NULL characters
+ but sysinstall copies the partition table before copying
+ <filename>/boot/boot0</filename> to the MBR.</para>
+
+ <warning>
+ <para><emphasis>Do not simply copy <filename>/boot/boot0</filename>
+ instead of <filename>/boot/boot1</filename>; you will
+ overwrite your partition table and render your computer
+ un-bootable!</emphasis></para>
+ </warning>
+
+ <para>When the FreeBSD boot manager runs it records the last
+ OS booted by setting the active flag on the partition table
+ entry for that OS and then writes the whole 512-bytes of itself
+ back to the MBR so if you just copy
+ <filename>/boot/boot0</filename> to
+ <filename>C:\BOOTSECT.BSD</filename> then it writes an empty
+ partition table, with the active flag set on one entry, to the
+ MBR.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="lilo-bootloader">
+ <para>How do I boot FreeBSD and &linux; from LILO?</para>
+ </question>
+
+ <answer>
+ <para>If you have FreeBSD and &linux; on the same disk, just follow
+ LILO's installation instructions for booting a non-&linux;
+ operating system. Very briefly, these are:</para>
+
+ <para>Boot &linux;, and add the following lines to
+ <filename>/etc/lilo.conf</filename>:</para>
+
+ <programlisting>other=/dev/hda2
+ table=/dev/hda
+ label=FreeBSD</programlisting>
+
+ <para>(the above assumes that your FreeBSD slice is known to
+ &linux; as <devicename>/dev/hda2</devicename>; tailor to
+ suit your setup). Then, run <command>lilo</command> as
+ <username>root</username> and you should be done.</para>
+
+ <para>If FreeBSD resides on another disk, you need to add
+ <literal>loader=/boot/chain.b</literal> to the LILO entry.
+ For example:</para>
+
+ <programlisting>other=/dev/dab4
+ table=/dev/dab
+ loader=/boot/chain.b
+ label=FreeBSD</programlisting>
+
+ <para>In some cases you may need to specify the BIOS drive number
+ to the FreeBSD boot loader to successfully boot off the second
+ disk. For example, if your FreeBSD SCSI disk is probed by BIOS
+ as BIOS disk 1, at the FreeBSD boot loader prompt you need to
+ specify:</para>
+
+ <screen>Boot: <userinput>1:da(0,a)/kernel</userinput></screen>
+
+ <para>You can configure
+ &man.boot.8;
+ to automatically do this for you at boot time.</para>
+
+ <para>The <ulink
+ url="http://sunsite.unc.edu/LDP/HOWTO/mini/Linux+FreeBSD.html">
+ &linux;+FreeBSD mini-HOWTO</ulink> is a good reference for
+ FreeBSD and &linux; interoperability issues.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="booteasy-loader">
+ <para>How do I boot FreeBSD and &linux; using BootEasy?</para>
+ </question>
+
+ <answer>
+ <para>Install LILO at the start of your &linux; boot partition
+ instead of in the Master Boot Record. You can then boot LILO
+ from BootEasy.</para>
+
+ <para>If you are running &windows; 95 and &linux; this is recommended
+ anyway, to make it simpler to get &linux; booting again if you
+ should need to reinstall &windows; 95 (which is a Jealous
+ Operating System, and will bear no other Operating Systems in
+ the Master Boot Record).</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="changing-bootprompt">
+ <para>How do I change the boot prompt from <literal>???</literal> to
+ something more meaningful?</para>
+ </question>
+
+ <answer>
+ <para>You can not do that with the standard boot manager without
+ rewriting it. There are a number of other boot managers
+ in the <filename>sysutils</filename> ports category that
+ provide this functionality.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="removable-drives">
+ <para>I have a new removable drive, how do I use it?</para>
+ </question>
+
+ <answer>
+
+ <para>Whether it is a removable drive like a &iomegazip; or an EZ drive
+ (or even a floppy, if you want to use it that way), or a new
+ hard disk, once it is installed and recognized by the system,
+ and you have your cartridge/floppy/whatever slotted in, things
+ are pretty much the same for all devices.</para>
+
+ <para>(this section is based on <ulink
+ url="http://www.vmunix.com/mark/FreeBSD/ZIP-FAQ.html">
+ Mark Mayo's ZIP FAQ</ulink>)</para>
+
+ <para>If it is a ZIP drive or a floppy, you have already got a DOS
+ filesystem on it, you can use a command like this:</para>
+
+ <screen>&prompt.root; <userinput>mount -t msdos /dev/fd0c /floppy</userinput></screen>
+
+ <para>if it is a floppy, or this:</para>
+
+ <screen>&prompt.root; <userinput>mount -t msdos /dev/da2s4 /zip</userinput></screen>
+
+ <para>for a ZIP disk with the factory configuration.</para>
+
+ <para>For other disks, see how they are laid out using
+ &man.fdisk.8; or
+ &man.sysinstall.8;.</para>
+
+ <para>The rest of the examples will be for a ZIP drive on da2,
+ the third SCSI disk.</para>
+
+ <para>Unless it is a floppy, or a removable you plan on sharing
+ with other people, it is probably a better idea to stick a BSD
+ filesystem on it. You will get long filename support, at least a
+ 2X improvement in performance, and a lot more stability. First,
+ you need to redo the DOS-level partitions/filesystems. You can
+ either use &man.fdisk.8; or
+ <filename>sysinstall</filename>(&os; 5.2 之前版本則是 <command>/stand/sysinstall</command>), or for a small drive
+ that you do not want to bother with multiple operating system
+ support on, just blow away the whole FAT partition table
+ (slices) and just use the BSD partitioning:</para>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/zero of=/dev/rda2 count=2</userinput>
+&prompt.root; <userinput>disklabel -Brw da2 auto</userinput></screen>
+
+ <para>You can use disklabel or
+ <filename>sysinstall</filename> to create multiple BSD
+ partitions. You will certainly want to do this if you are adding
+ swap space on a fixed disk, but it is probably irrelevant on a
+ removable drive like a ZIP.</para>
+
+ <para>Finally, create a new filesystem, this one is on our ZIP
+ drive using the whole disk:</para>
+
+ <screen>&prompt.root; <userinput>newfs /dev/rda2c</userinput></screen>
+
+ <para>and mount it:</para>
+
+ <screen>&prompt.root; <userinput>mount /dev/da2c /zip</userinput></screen>
+
+ <para>and it is probably a good idea to add a line like this
+ to <filename>/etc/fstab</filename> (see &man.fstab.5;) so
+ you can just type <command>mount /zip</command> in the
+ future:</para>
+
+ <programlisting>/dev/da2c /zip ffs rw,noauto 0 0</programlisting>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="mount-cd-superblock">
+ <para>Why do I get <errorname>Incorrect super block</errorname> when
+ mounting a CDROM?</para>
+ </question>
+
+ <answer>
+ <para>You have to tell &man.mount.8; the type of the device
+ that you want to mount. This is described in the <ulink
+ url="&url.books.handbook;/creating-cds.html"> Handbook section on
+ optical media</ulink>, specifically the section <ulink
+ url="&url.books.handbook;/creating-cds.html#MOUNTING-CD">Using Data
+ CDs</ulink>.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="cdrom-not-configured">
+ <para>Why do I get <errorname>Device not
+ configured</errorname> when mounting a CDROM?</para>
+ </question>
+
+ <answer>
+ <para>This generally means that there is no CDROM in the
+ CDROM drive, or the drive is not visible on the
+ bus. Please see the <ulink
+ url="&url.books.handbook;/creating-cds.html#MOUNTING-CD">Using Data
+ CDs</ulink> section of the Handbook for a detailed
+ discussion of this issue.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="cdrom-unicode-filenames">
+ <para>Why do all non-English characters in filenames show up as
+ <quote>?</quote> on my CDs when mounted in FreeBSD?</para>
+ </question>
+
+ <answer>
+ <para>Your CDROM probably uses the <quote>Joliet</quote>
+ extension for storing information about files and
+ directories. This is discussed in the Handbook chapter on
+ <ulink url="&url.books.handbook;/creating-cds.html">creating and
+ using CDROMs</ulink>, specifically the section on <ulink
+ url="&url.books.handbook;/creating-cds.html#MOUNTING-CD">Using Data
+ CDROMs</ulink>.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="burncd-isofs">
+ <para>I burned a CD under FreeBSD and now I can not read it
+ under any other operating system. Why?</para>
+ </question>
+
+ <answer>
+ <para>You most likely burned a raw file to your CD, rather
+ than creating an ISO 9660 filesystem. Take a look at the
+ <ulink url="&url.books.handbook;/creating-cds.html">Handbook
+ chapter on creating CDROMs</ulink>, particularly the
+ section on <ulink
+ url="&url.books.handbook;/creating-cds.html#RAWDATA-CD">burning raw
+ data CDs</ulink>.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="copy-cd">
+ <para>How can I create an image of a data CD?</para>
+ </question>
+
+ <answer>
+ <para>This is discussed in the Handbook section on <ulink
+ url="&url.books.handbook;/creating-cds.html#IMAGING-CD">duplicating
+ data CDs</ulink>. For more on working with CDROMs, see the
+ <ulink url="&url.books.handbook;/creating-cds.html">Creating CDs
+ Section</ulink> in the Storage chapter in the
+ Handbook.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="mount-audio-CD">
+ <para>Why can I not <command>mount</command> an audio
+ CD?</para>
+ </question>
+
+ <answer>
+ <para>If you try to mount an audio CD, you will get an error
+ like <errorname>cd9660: /dev/acd0c: Invalid
+ argument</errorname>. This is because
+ <command>mount</command> only works on filesystems. Audio
+ CDs do not have filesystems; they just have data. You
+ need a program that reads audio CDs, such as the
+ <filename role="package">audio/xmcd</filename> port.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="multi-session-CD">
+ <para>How do I <command>mount</command> a multi-session CD?</para>
+ </question>
+
+ <answer>
+ <para>By default, &man.mount.8; will attempt to mount the
+ last data track (session) of a CD. If you would like to
+ load an earlier session, you must use the
+ <option>-s</option> command line argument. Please see
+ &man.mount.cd9660.8; for specific examples.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="user-floppymount">
+ <para>How do I let ordinary users mount floppies, CDROMs and
+ other removable media?</para>
+ </question>
+
+ <answer>
+ <para>Ordinary users can be permitted to mount devices. Here is
+ how:</para>
+
+ <procedure>
+ <step>
+ <para>As <username>root</username> set the sysctl variable
+ <varname>vfs.usermount</varname> to
+ <literal>1</literal>.</para>
+
+ <screen>&prompt.root; <userinput>sysctl -w vfs.usermount=1</userinput></screen>
+ </step>
+
+ <step>
+ <para>As <username>root</username> assign the appropriate
+ permissions to the block device associated with the
+ removable media.</para>
+
+ <para>For example, to allow users to mount the first floppy
+ drive, use:</para>
+
+ <screen>&prompt.root; <userinput>chmod 666 /dev/fd0</userinput></screen>
+
+ <para>To allow users in the group
+ <groupname>operator</groupname> to mount the CDROM drive,
+ use:</para>
+
+ <screen>&prompt.root; <userinput>chgrp operator /dev/acd0c</userinput>
+&prompt.root; <userinput>chmod 640 /dev/acd0c</userinput></screen>
+ </step>
+
+ <step>
+ <para>If you are running &os; 5.X or later, you will need to alter
+ <filename>/etc/devfs.conf</filename> to make these changes
+ permanent across reboots.</para>
+
+ <para>As <username>root</username>, add the necessary lines to
+ <filename>/etc/devfs.conf</filename>. For example, to allow
+ users to mount the first floppy drive add:</para>
+
+ <programlisting># Allow all users to mount the floppy disk.
+own /dev/fd0 root:operator
+perm /dev/fd0 0666</programlisting>
+
+ <para>To allow users in the group <groupname>operator</groupname>
+ to mount the CD-ROM drive add:</para>
+
+ <programlisting># Allow members of the group operator to mount CD-ROMs.
+own /dev/acd0 root:operator
+perm /dev/acd0 0660</programlisting>
+ </step>
+
+ <step>
+ <para>Finally, add the line
+ <literal><varname>vfs.usermount</varname>=1</literal>
+ to the file <filename>/etc/sysctl.conf</filename> so
+ that it is reset at system boot time.</para>
+ </step>
+ </procedure>
+
+ <para>All users can now mount the floppy
+ <devicename>/dev/fd0</devicename> onto a directory that they
+ own:</para>
+
+ <screen>&prompt.user; <userinput>mkdir ~/my-mount-point</userinput>
+&prompt.user; <userinput>mount -t msdos /dev/fd0 ~/my-mount-point</userinput></screen>
+
+ <para>Users in group <groupname>operator</groupname> can now
+ mount the CDROM <devicename>/dev/acd0c</devicename> onto a
+ directory that they own:</para>
+
+ <screen>&prompt.user; <userinput>mkdir ~/my-mount-point</userinput>
+&prompt.user; <userinput>mount -t cd9660 /dev/acd0c ~/my-mount-point</userinput></screen>
+
+ <para>Unmounting the device is simple:</para>
+
+ <screen>&prompt.user; <userinput>umount ~/my-mount-point</userinput></screen>
+
+ <para>Enabling <varname>vfs.usermount</varname>, however,
+ has negative security implications. A better way to
+ access &ms-dos; formatted media is to use the
+ <filename role="package">emulators/mtools</filename>
+ package in the ports collection.</para>
+
+ <note>
+ <para>The device name used in the previous examples must be
+ changed according to your configuration.</para>
+ </note>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="du-vs-df">
+ <para>The <command>du</command> and <command>df</command>
+ commands show different amounts of disk space available.
+ What is going on?</para>
+ </question>
+
+ <answer>
+ <para>You need to understand what <command>du</command> and
+ <command>df</command> really do. <command>du</command>
+ goes through the directory tree, measures how large each
+ file is, and presents the totals. <command>df</command>
+ just asks the filesystem how much space it has left. They
+ seem to be the same thing, but a file without a directory
+ entry will affect <command>df</command> but not
+ <command>du</command>.</para>
+
+ <para>When a program is using a file, and you delete the
+ file, the file is not really removed from the filesystem
+ until the program stops using it. The file is immediately
+ deleted from the directory listing, however. You can see
+ this easily enough with a program such as
+ <command>more</command>. Assume you have a file large
+ enough that its presence affects the output of
+ <command>du</command> and <command>df</command>. (Since
+ disks can be so large today, this might be a
+ <emphasis>very</emphasis> large file!) If you delete this
+ file while using <command>more</command> on it,
+ <command>more</command> does not immediately choke and
+ complain that it cannot view the file. The entry is
+ simply removed from the directory so no other program or
+ user can access it. <command>du</command> shows that it
+ is gone &mdash; it has walked the directory tree and the file
+ is not listed. <command>df</command> shows that it is
+ still there, as the filesystem knows that
+ <command>more</command> is still using that space. Once
+ you end the <command>more</command> session,
+ <command>du</command> and <command>df</command> will
+ agree.</para>
+
+ <para>Note that Soft Updates can delay the freeing of disk
+ space; you might need to wait up to 30 seconds for the
+ change to be visible!</para>
+
+ <para>This situation is common on web servers. Many people
+ set up a FreeBSD web server and forget to rotate the log
+ files. The access log fills up <filename>/var</filename>.
+ The new administrator deletes the file, but the system
+ still complains that the partition is full. Stopping and
+ restarting the web server program would free the file,
+ allowing the system to release the disk space. To prevent
+ this from happening, set up &man.newsyslog.8;.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="add-swap-space">
+ <para>How can I add more swap space?</para>
+ </question>
+
+ <answer>
+ <para>In the <ulink
+ url="&url.books.handbook;/config-tuning.html">Configuration and
+ Tuning</ulink> section of the Handbook, you will find a
+ <ulink
+ url="&url.books.handbook;/adding-swap-space.html">section</ulink>
+ describing how to do this.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="manufacturer-disk-size">
+ <para>Why does &os; see my disk as smaller than the
+ manufacturer says it is?</para>
+ </question>
+
+ <answer>
+ <para>Disk manufacturers calculate gigabytes as a billion bytes
+ each, whereas &os; calculates them as 1,073,741,824 bytes
+ each. This explains why, for example, &os;'s boot messages
+ will report a disk that supposedly has 80GB as holding
+ 76319MB.</para>
+ <para>Also note that &os; will (by default)
+ <link linkend="disk-more-than-full">reserve</link> 8% of the disk
+ space.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="disk-more-than-full">
+ <para>How is it possible for a partition to be more than 100%
+ full?</para>
+ </question>
+
+ <answer>
+ <para>A portion of each UFS partition (8%, by default) is
+ reserved for use by the operating system and the
+ <username>root</username> user.
+ &man.df.1; does not count that space when
+ calculating the <literal>Capacity</literal> column, so it can
+ exceed 100%. Also, you will notice that the
+ <literal>Blocks</literal> column is always greater than the
+ sum of the <literal>Used</literal> and
+ <literal>Avail</literal> columns, usually by a factor of
+ 8%.</para>
+
+ <para>For more details, look up the <option>-m</option> option
+ in &man.tunefs.8;.</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+
+ <chapter id="admin">
+ <chapterinfo>
+ <author>
+ <firstname>Wei-Hon</firstname>
+ <surname>Chen</surname>
+ <affiliation>
+ <address><email>plasmaball@pchome.com.tw</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>系統管理</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="startup-config-files">
+ <para>系統起始設定檔在哪?</para>
+ </question>
+
+ <answer>
+
+ <para>從 2.0.5R 到 2.2.1R,主要的設定檔是
+ <filename>/etc/sysconfig</filename>。所有的選項都被指定在這個檔,
+ 而其他像 <filename>/etc/rc</filename> (參見 &man.rc.8;)
+ 和 <filename>/etc/netstart</filename> 只是引用它。</para>
+
+ <para>觀察 <filename>/etc/sysconfig</filename> 這個檔並修正其值以
+ 適合你的系統。這個檔用註解填滿以表示何處該放置什麼設定。</para>
+
+ <para>在 post-2.2.1 以後及 3.0,<filename>/etc/sysconfig</filename>
+ 亦更名為一個更容易描述的檔名叫 &man.rc.conf.5; ,並且語法簡化了些。
+ <filename>/etc/netstart</filename> 亦更名為
+ <filename>/etc/rc.network</filename> 因此所有的檔案都可以用
+ <command>cp /usr/src/etc/rc* /etc</command> 來拷貝。</para>
+
+ <para>在 3.1 以及,<filename>/etc/rc.conf</filename> 被移到
+ <filename>/etc/defaults/rc.conf</filename>。
+ <emphasis>千萬不要編輯這個檔!</emphasis> 如果
+ <filename>/etc/defaults/rc.conf</filename> 內有想要更動的項目,
+ 你應該將那一行的內容拷貝到 <filename>/etc/rc.conf</filename>,
+ 然後再修改它。</para>
+
+ <para>例如 FreeBSD 3.1 及以後的版本內,有一個 DNS 伺服器 named,
+ 而你想要啟動它。你所需要作的事就是:</para>
+ <screen>&prompt.root; <userinput>echo named_enable="YES" &gt;&gt; /etc/rc.conf</userinput></screen>
+
+ <para>想要在 FreeBSD 3.1 及以後的版本中,啟動本地端服務的話,將
+ shell script 置於 <filename>/usr/local/etc/rc.d</filename> 目錄
+ 下。這些 shell script 應該設定成可執行,並且檔名以 .sh 結束。
+ 在 FreeBSD 3.0 及更早的版本中,你應該直接編輯
+ <filename>/etc/rc.local</filename> 檔。</para>
+
+ <para><filename>/etc/rc.serial</filename>用來初始化序列埠
+ (像是鎖定埠的特性等)。</para>
+
+ <para><filename>/etc/rc.i386</filename> 是 Intel 專用設定,
+ 像是 iBCS2 模擬或是 PC 系統主控台設定。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="adding-users">
+ <para>該如何簡單地新增帳號?</para>
+ </question>
+
+ <answer>
+ <para>使用 &man.adduser.8; 指令。如果需要更複雜的使用方式,
+ 請用 &man.pw.8; 這個指令。</para>
+
+ <para>要再次移除使用者,使用 &man.rmuser.8; 指令。還有,
+ &man.pw.8; 也可以使用。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="root-not-found-cron-errors">
+ <para>在改完 crontab 檔案後,為什麼老是收到這樣的訊息:
+ <errorname>root: not found</errorname>?</para>
+ </question>
+
+ <answer>
+ <para>通常都是因為編輯了系統的 crontab
+ (<filename>/etc/crontab</filename>) 然後就用 &man.crontab.1;
+ 去安裝它:</para>
+
+ <screen>&prompt.root; <userinput>crontab /etc/crontab</userinput></screen>
+
+ <para>這樣作是不對的。系統的 crontab 和 &man.crontab.1;
+ 所更新的使用者的 crontab 格式並不一樣 (&man.crontab.5;
+ 說明文件針對差異處有詳細的說明)。</para>
+
+ <para>如果你已經用這種方法,額外多出的 crontab 只就是
+ <filename>/etc/crontab</filename> 的拷貝,只是格式是錯誤的。
+ 可用以下的命令刪除:</para>
+
+ <screen>&prompt.root; <userinput>crontab -r</userinput></screen>
+
+ <para>下次你編輯 <filename>/etc/crontab</filename> 檔案的時候,
+ 你不用作任何動作去通知 &man.cron.8; ,它自動會去偵測是否有更動。
+ </para>
+
+ <para>如果你想要每天、每週、或是每月固定執行某些動作一次,也許加個
+ shell script 在 <filename>/usr/local/etc/periodic</filename>
+ 目錄下會更好,系統的 cron 會固定執行 &man.periodic.8; 命令,
+ 它可將你的程式和其它的系統週期性工作一起執行。</para>
+
+ <para>這個錯誤的真正原因,是因為系統的 crontab 有一個額外的欄位,
+ 說明該命令要以什麼使用者身份執行。在 FreeBSD 的預設系統 crontab
+ 中,所有的項目都是 <username>root</username>。 當這個 crontab
+ 被當作是 <username>root</username> 的使用者 crontab (它和系統的
+ crontab 是 <emphasis>不</emphasis> 一樣的),&man.cron.8; 會以為
+ <literal>root</literal> 字串是欲執行的命令的第一個字,但是實際上
+ 並沒有這樣的命令存在。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="su-wheel-group">
+ <para>為什麼我想要用 su 成為 <username>root</username> 時,會得到
+ <errorname>you are not in the correct group to su root</errorname>
+ 的錯誤訊息?</para>
+ </question>
+
+ <answer>
+ <para>這是一個安全特性。想要利用 su 成為 <username>root</username>
+ (或其它有 superuser 權限的帳號),你一定要在
+ <groupname>wheel</groupname> 群組內。如果沒有這個特性的話,
+ 任何人只要在系統裡有帳號,並且恰巧知道 <username>root</username>
+ 的密碼,就可以取得 superuser 等級的權限以存取系統。有了這個特性,
+ 這樣的情況就不會發生;如果使用者不在 <groupname>wheel</groupname>
+ 群組內的話,&man.su.1; 會讓他們連試著鍵入密碼的機會都沒有。</para>
+
+ <para>要讓某人可以利用 su 成為 <username>root</username> 的話,
+ 只要把他們放入 <groupname>wheel</groupname> 群組內即可。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="rcconf-readonly">
+ <para>我在 <filename>rc.conf</filename> 還是某個起動檔案裡犯了錯誤,
+ 因為檔案系統變成唯讀的,我無法去編輯它。我該怎麼辦?</para>
+ </question>
+
+ <answer>
+ <para>當電腦問你 shell 完整路徑名時,只要按 <literal>ENTER
+ </literal>,然後執行 <command>mount /</command> 以讀寫模式
+ 重新掛載根檔案系統。你也許需要執行 <command>mount -a -t ufs
+ </command>,將你慣用的文字編輯器所在的檔案系統掛載上來。如果
+ 你慣用的文字編輯器在網路檔案系統上的話,你必須先手動將網路設定
+ 起來,以便將網路檔案系統掛載上來,或是使用本地端檔案系統上的
+ 編輯器,例如 &man.ed.1;。</para>
+
+ <para>如果你想要使用像 &man.vi.1; 或是 &man.emacs.1; 等的全螢幕
+ 文字編輯器的話,你也需要執行
+ <command>export TERM=cons25 </command>,以便讓這些編輯器能夠從
+ &man.termcap.5; 資料庫裡讀取正確的資料。</para>
+
+ <para>當你已經完成了這些步驟後,你可以照你平常修改文法錯誤的方式
+ 去編輯 <filename>/etc/rc.conf</filename> 檔案。在核心 (kernel)
+ 啟動時所顯示的錯誤訊息,能夠告訴你檔案中哪一行有錯誤。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="printer-setup">
+ <para>為什麼我沒辦法設定我的印表機?</para>
+ </question>
+
+ <answer>
+ <para>請參考一下 Handbook 中,有關列印的部份。它應該能夠解決
+ 你大部份的問題。請參考 <ulink url="../handbook/printing.html">
+ Handbook 中的列印部份</ulink>。</para>
+
+ <para>有些印表機需要主機支援的驅動程式 (host-based driver) 才能
+ 執行任何列印功能。FreeBSD 本身並不支援這些所謂的
+ <quote>WinPrinters</quote>。 如果你的印表機無法在 DOS 或
+ Windows NT 4.0 下執行,那它大概就是一台 WinPrinter。你唯一能使用
+ 這樣的印表機的希望,就是試試 <filename role="package">
+ print/pnm2ppa</filename> 支不支援它了。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="keyboard-mappings">
+ <para>我要怎麼樣修正我的系統所使用的鍵盤對映 (keyboard mapping)?
+ </para>
+ </question>
+
+ <answer>
+ <para>請參考 Handbook 中的 <ulink
+ url="../handbook/using-localization.html">using localization
+ </ulink> 章節,尤其是 <ulink
+ url="../handbook/using-localization.html#SETTING-CONSOLE">console
+ setup</ulink> 章節。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="pnp-resources">
+ <para>為什麼我在系統啟動時,得到 <errorname>unknown: &lt;PNP0303&gt;
+ can't assign resources</errorname> 的訊息?</para>
+ </question>
+
+ <answer>
+ <para>以下是從 &os.current; 通信論壇的一篇文章中節錄出來的。</para>
+
+ <blockquote>
+ <attribution>&a.wollman;, 2001 年四月 24 日</attribution>
+
+ <para><quote>無法指派資源 (can't assign resources)</quote> 訊息表示
+ 那些裝置是傳統的 ISA 裝置,而核心中已經編入不認得 PNP 的驅動程
+ 式。這些裝置包括鍵盤控制器,可程式化岔斷控制晶片,還有幾個標準
+ 設備。資源無法指派給這些裝置,是因為早已有驅動程式使用那些位址
+ 了。</para>
+ </blockquote>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="user-quotas">
+ <para>為什麼 user quotas 無法正常運作?</para>
+ </question>
+
+ <answer>
+
+ <orderedlist>
+ <listitem>
+ <para>可能你 kernel 設定未加入 quotas 支援(預設是無)。如果是這樣子的話,
+ 那麼請把下面這行加到 kernel 設定檔內並重新編譯、安裝:</para>
+ <programlisting>options QUOTA</programlisting>
+
+ <para>細節部分,請參閱 Handbook 內的 <ulink url="&url.books.handbook;/quotas.html">
+ quotas</ulink> 章節。</para>
+ </listitem>
+
+ <listitem>
+ <para>請不要直接在 <filename>/</filename> 打開 quotas </para>
+ </listitem>
+
+ <listitem>
+ <para>把 quotas 檔放在它必須強迫置入的檔案系統內,舉例:</para>
+
+ <informaltable frame="none">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>檔案系統</entry>
+ <entry>Quota 檔</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><filename>/usr</filename></entry>
+ <entry><filename>/usr/admin/quotas</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>/home</filename></entry>
+ <entry><filename>/home/admin/quotas</filename></entry>
+ </row>
+
+ <row>
+ <entry>&hellip;</entry>
+ <entry>&hellip;</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </listitem>
+ </orderedlist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="sysv-ipc">
+ <para>FreeBSD 支援 System V IPC 格式指令集?</para>
+ </question>
+
+ <answer>
+ <para>是的,FreeBSD 支援 System V-style IPC。這包括共享記憶體,
+ 訊息跟信號。你需要在你的 kernel 設定檔內加入下列幾行以啟動它們。</para>
+
+ <programlisting>options SYSVSHM # enable shared memory
+options SYSVSEM # enable for semaphores
+options SYSVMSG # enable for messaging</programlisting>
+
+ <note>
+ <para>在 FreeBSD 3.2 以及之後的版本,這些選項已經是
+ <emphasis>GENERIC</emphasis> 核心的一部份,也就是說它們已
+ 經編進了你的系統中。</para>
+ </note>
+
+ <para>重新編譯並安裝。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="uucpmail">
+ <para>我該如何讓 sendmail 透過 UUCP 來遞送郵件?</para>
+ </question>
+
+ <answer>
+ <para>跟隨 FreeBSD 套裝而來的 sendmail 設定是適合那些直接連上網際網路
+ 的站台。想透過 UUCP 交換郵件的站台必須另外安裝 sendmail 的設定檔案。
+ </para>
+
+ <para>手動修改 <filename>/etc/sendmail.cf</filename> 是絕對必要的。
+ 第 8 版的 sendmail 提供一個全新的入口以透過一些像 &man.m4.1;
+ 的處理就能產生設定檔,這事實上是一個高層概念等級的技巧性設定。
+ 你應該可以在 <filename>/usr/src/usr.sbin/sendmail/cf</filename>
+ 以下裡使用它:</para>
+
+ <para>假如你不是用 full sources 方式安裝系統,那麼 sendmail
+ 設定項目可能已經分散成好幾個來源分布檔在等著你,假設你已經
+ mount 光碟機,做以下動作:</para>
+
+ <screen>&prompt.root; <userinput>cd /cdrom/src</userinput>
+&prompt.root; <userinput>cat scontrib.?? | tar xzf - -C /usr/src contrib/sendmail</userinput></screen>
+
+ <para>別驚慌,這只有數十萬個位元組的大小。在 <filename>cf</filename>
+ 目錄裡的 <filename>README</filename> 可以提供一個 m4 設定法的基
+ 本介紹。</para>
+
+ <para>以 UUCP 遞送來說,建議你最好使用 <literal>mailertable</literal>
+ 特點。建構一個資料庫讓 sendmail 可以使用它自己的路徑決策。</para>
+
+ <para>首先,你必須建立自己的 <filename>.mc</filename> 檔。
+ <filename>/usr/src/usr.sbin/sendmail/cf/cf</filename> 目錄是這些
+ 檔案的家。查看一下,已經有好幾個範例檔,假設你已經命名自己的檔叫
+ <filename>foo.mc</filename>,你要做的只是把它轉換成一個有效的
+ <filename>sendmail.cf</filename>:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src/usr.sbin/sendmail/cf/cf</userinput>
+&prompt.root; <userinput>make foo.cf</userinput>
+&prompt.root; <userinput>cp foo.cf /etc/mail/sendmail.cf</userinput></screen>
+
+ <para>一個典型的 <filename>.mc</filename> 檔看起來可能像這樣:</para>
+
+ <programlisting>VERSIONID(`<replaceable>Your version number</replaceable>')
+OSTYPE(bsd4.4)
+
+FEATURE(accept_unresolvable_domains)
+FEATURE(nocanonify)
+FEATURE(mailertable, `hash -o /etc/mail/mailertable')
+
+define(`UUCP_RELAY', <replaceable>your.uucp.relay</replaceable>)
+define(`UUCP_MAX_SIZE', 200000)
+define(`confDONT_PROBE_INTERFACES')
+
+MAILER(local)
+MAILER(smtp)
+MAILER(uucp)
+
+Cw <replaceable>your.alias.host.name</replaceable>
+Cw <replaceable>youruucpnodename.UUCP</replaceable></programlisting>
+
+ <para><literal>accept_unresolvable_domains</literal>,
+ <literal>nocanonify</literal>, 和
+ <literal>confDONT_PROBE_INTERFACES</literal> 特性將避免任何在
+ 遞送郵件時會用到 DNS 的機會。<literal>UUCP_RELAY</literal>
+ 項目的出現理由很奇怪,就不要問為何了。簡單的放入一個網際網路
+ 上可以處理 .UUCP 虛擬網域位址的主機名稱;通常,你只需要在這
+ 裡填入你 ISP 的信件回覆處 (mail replay)。</para>
+
+ <para>你已經做到這裡了,你還需要這個叫
+ <filename>/etc/mail/mailertable</filename>。如果你只有一個用
+ 來傳遞所有郵件的對外通道的話,以下的檔案就足夠了:</para>
+
+ <programlisting>#
+# makemap hash /etc/mail/mailertable.db &lt; /etc/mail/mailertable
+ uucp-dom:<replaceable>your.uucp.relay</replaceable></programlisting>
+
+ <para>另一個更複雜的例子看起來像這樣:</para>
+
+ <programlisting>#
+# makemap hash /etc/mail/mailertable.db &lt; /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:</programlisting>
+
+
+ <para>如你所見,這是某個真實檔案裡的一部份。首三行處理網域定址信件
+ 不應該被送出到內定路徑,而由某些 UUCP 鄰居(UUCP neighbor)取代
+ 的特殊情形,這是為了 <quote>縮短</quote>遞送的路徑。下一行處理到
+ 本地乙太網路網域的信件讓它可以使用 SMTP 來遞送。最後,UUCP 鄰居提到
+ .UUCP 虛擬網域的記載,允許一個 <literal><replaceable>uucp-neighbor
+ </replaceable>!<replaceable>recipient</replaceable></literal> 推翻
+ 內定規則。最後一行則以一個單獨的句點做結束,以 UUCP 遞送到提供當
+ 你全世界性郵件閘門的UUCP 鄰居。所有在 <literal>uucp-dom:</literal>
+ 關鍵字裡的節點名稱必須都是有效的 UUCP 鄰居,你可以用
+ <literal>uuname</literal> 命令去確認。
+ </para>
+
+ <para>提醒你這個檔案在使用前必須被轉換成 DBM 資料庫檔案,最好在
+ mailertable 最上面用註解寫出命令列來完成這個工作。當你每次更換你
+ 的 mailertable 後你總是需要執行這個命令。</para>
+
+ <para>最後提示:如果你不確定某些特定的信件路徑可用,記得把
+ <option>-bt</option> 選項加到 sendmail。這會將 sendmail 啟動在
+ <emphasis>address test mode</emphasis>;只要按下
+ <literal>0</literal>,接著輸入你希望測試的信件路徑位址。
+ 最後一行告訴你使用內部的信件代理程式,代理程式的會通知目的主機,
+ 以及(可能轉換的)位址。要離開此模式請按 Control-D。</para>
+
+ <screen>&prompt.user; <userinput>sendmail -bt</userinput>
+ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
+Enter &lt;ruleset&gt; &lt;address&gt;
+<prompt>&gt;</prompt> <userinput>3,0 foo@example.com</userinput>
+canonify input: foo @ example . com
+..
+parse returns: $# uucp-dom $@ <replaceable>your.uucp.relay</replaceable> $: foo &lt; @ example . com . &gt;
+<prompt>&gt;</prompt> <userinput>^D</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ispmail">
+ <para>當我用撥接連上網路時該怎麼設定信件遞送?</para>
+ </question>
+
+ <answer>
+ <para>如果你已經有一個固定的 IP 數字,你不需要調整任何內定值。設好
+ 你要指定的網路名稱,其他的 sendmail 都會幫你做完。</para>
+
+ <para>如果你拿到的是動態配置的 IP 數字而使用撥接 ppp 連接到網際網
+ 路,你可能已經在你的 ISP 信件主機上有一個信箱。假設你的 ISP 網域
+ 是 <hostid role="domainname">example.net</hostid>,你的使用者名
+ 稱是 <username>user</username>。亦假設你稱自己的主機名稱是
+ <hostid role="fqdn">bsd.home</hostid> 而你的 ISP 告訴你可以使用
+ <hostid role="fqdn">relay.example.net</hostid> 當作信件回覆處。
+ </para>
+
+ <para>為了從你的信箱接收信件,你將需要安裝取信程式以便從信箱取回信件。
+ <application>Fetchmail</application> 是一個不錯的選擇,因為它支
+ 援許多不同的通訊協定,通常你的 ISP 會提供 POP3。如果你選擇使用
+ user-ppp,你可以在連線到網路成功後自動抓取你的信件,只要在
+ <filename>/etc/ppp/ppp.linkup</filename>裡面設定以下這項:</para>
+
+ <programlisting>MYADDR:
+ !bg su user -c fetchmail</programlisting>
+
+ <para>假使你正使用 <application>sendmail</application> (如下所示)
+ 傳送信件到非本地帳號,置入以下命令:</para>
+
+ <programlisting> !bg su user -c "sendmail -q"</programlisting>
+
+ <para>在上面那項命令之後。這會強迫 <application>sendmail</application>
+ 在連接上網路後馬上開始處理 mailqueue。</para>
+
+ <para>我假設你在 <hostid role="fqdn">bsd.home</hostid> 機器上有一個
+ <username>user</username> 的帳號。在 <hostid
+ role="fqdn">bsd.home</hostid> 機器上 <username>user</username>
+ 的家目錄裡建立一個 <filename>.fetchmailrc</filename> 的檔案:</para>
+
+ <programlisting>poll example.net protocol pop3 fetchall pass MySecret</programlisting>
+
+ <para>無須贅言,這個檔除了 <username>user</username> 外不應該被任
+ 何人讀取,因為它包含 <literal>MySecret</literal> 這個密碼。</para>
+
+ <para>為了在寄信時有正確的抬頭 <literal>from:</literal>,你必須告訴
+ <application>sendmail</application> 使用
+ <literal>user@example.net</literal> 而非
+ <literal>user@bsd.home</literal>。你可能會希望告訴
+ <application>sendmail</application> 從
+ <hostid role="fqdn">relay.example.net</hostid> 送出所有信件,
+ 加快信件傳送。</para>
+
+ <para>以下的 <filename>.mc</filename> 檔應能滿足你的要求:</para>
+
+ <programlisting>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')dnl</programlisting>
+
+ <para>如何轉換這個 <filename>.mc</filename> 檔案到
+ <filename>sendmail.cf</filename> 檔的詳細細節,請參考上一節。
+ 另外,在更新 <filename>sendmail.cf</filename> 以後不要忘記重新啟動
+ <application>sendmail</application>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="sendmail-alternative">
+ <para>除了 Sendmail 外,還有哪些郵件伺服器可以使用呢?</para>
+ </question>
+
+ <answer>
+ <para><ulink url="http://www.sendmail.org/">Sendmail</ulink>
+ 是 FreeBSD 預設使用的郵件伺服器,但是你還是可以很容易地以其它
+ 郵件伺服器 (例如,從 port 安裝的郵件伺服器) 取代之。</para>
+
+ <para>port 裡有很多可供選擇的郵件伺服器,像
+ <filename role="package">mail/exim</filename>、
+ <filename role="package">mail/postfix</filename>、
+ <filename role="package">mail/qmail</filename>、
+ <filename role="package">mail/zmailer</filename> 等,
+ 就是幾個很受歡迎的選擇。</para>
+
+ <para>多樣選擇是好事,而且大家有許多郵件伺服器可以使用也被認為是
+ 好事;所以請避免在通信論壇裡問像 <quote>Sendmail 有比 Qmail
+ 好嗎?</quote> 這樣的問題。如果你真的很想問的話,請先到通信論壇
+ archive 裡找一下。每一個郵件伺服器的優點與缺點,以前大概就已經
+ 討論好幾次了。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="forgot-root-pw">
+ <para>我忘了 <username>root</username> 密碼了!怎麼辦?</para>
+ </question>
+
+ <answer>
+ <para>不要驚慌!只要重新啟動系統,在看到 Boot: 時輸入
+ <userinput>boot -s</userinput> 即可進入單使用者模式
+ (在 3.2-RELEASE 之前的版本請改用 <userinput>-s</userinput>)。
+ 在問要使用哪個 shell 時,按下 ENTER。你會看到一個 &prompt.root;
+ 的提示號,輸入 <command>mount -u /</command> 以重新掛上(mount)
+ 你的根檔案系統可供讀/寫。執行 <command>passwd root</command>
+ 以更換 <username>root</username> 密碼,然後執行 &man.exit.1;
+ 繼續啟動程序。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="CAD-reboot">
+ <para>我該怎麼讓 Control-Alt-Delete 不會重新啟動系統?</para>
+ </question>
+
+ <answer>
+ <para>如果你是使用 FreeBSD 2.2.7-RELEASE 或之後版本的
+ syscons(系統內定的主控台驅動程式),把下列這行放到 kernel 設定檔內,
+ 然後重做一個新的核心:</para>
+
+ <programlisting>options SC_DISABLE_REBOOT</programlisting>
+
+ <para>若是使用 FreeBSD 2.2.5-RELEASE 或之後版本的 PCVT 主控台驅動
+ 程式,則以下列選項代替:</para>
+
+ <programlisting>options PCVT_CTRL_ALT_DEL</programlisting>
+
+ <para>其他更早期的 FreeBSD 版本,請修改你正在使用的主控台鍵盤對應,
+ 並將所有 <literal>boot</literal> 關鍵字以 <literal>nop</literal>
+ 取代。內定的鍵盤對應是在
+ <filename>/usr/share/syscons/keymaps/us.iso.kbd</filename>。
+ 你可能需要明白的吩咐 <filename>/etc/rc.conf</filename> 去讀取
+ 這個鍵盤對應以確保更動生效。當然如果你正在用適合你國籍的鍵盤對應,
+ 你應該編輯那一個。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="dos-to-unix-txt">
+ <para>我該怎麼把 DOS 文字檔案重新格式化成 UNIX 的?</para>
+ </question>
+
+ <answer>
+ <para>只要使用這個 perl 命令:</para>
+
+ <screen>&prompt.user; <userinput>perl -i.bak -npe 's/\r\n/\n/g' file ...</userinput></screen>
+
+ <para>file 就是要處理的檔案。這個修改是在內部完成,原始的檔案會儲存成
+ 副檔名為 .bak 的檔案。</para>
+
+ <para>或者你可以使用 &man.tr.1; 這個命令:</para>
+
+ <screen>&prompt.user; <userinput>tr -d '\r' &lt; <replaceable>dos-text-file</replaceable> &gt; <replaceable>unix-file</replaceable></userinput></screen>
+
+ <para><replaceable>dos-text-file</replaceable> 是包含 DOS 文字的
+ 檔案,而 <replaceable>unix-text-file</replaceable> 則是包含轉換
+ 的輸出結果。這比使用 perl 還要快上一點點。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="kill-by-name">
+ <para>我該怎麼用名稱砍掉 process?</para>
+ </question><answer>
+
+ <para>使用 &man.killall.1; 。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="root-acl">
+ <para>為何在 su 一直說我不在 <username>root</username> 的 ACL 裡?
+ </para>
+ </question>
+
+ <answer>
+ <para>這個錯誤是因為 Kerberos 分散認證系統。這個問題並不是很嚴重
+ 但是令人厭煩。你可以用 -K 選項去執行 su,或是像下個問題所描述的
+ 移除 Kerberos。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="uninstall-kerberos">
+ <para>我該怎麼移除 Kerberos?</para>
+ </question>
+
+ <answer>
+ <para>要從系統裡移除 Kerberos,重裝你正在執行的 release 版本的
+ bin distribution。如果你有 CDROM,你可以 mount cd(假設在 /cdrom)
+ 並執行:</para>
+
+ <screen>&prompt.root; <userinput>cd /cdrom/bin</userinput>
+&prompt.root; <userinput>./install.sh</userinput></screen>
+
+ <para>或者你也可以將 <filename>/etc/make.conf</filename> 裡的
+ "MAKE_KERBEROS" 選項全都拿掉,然後再 build world.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="add-pty">
+ <para>我該怎麼增加系統的虛擬終端機?</para>
+ </question>
+
+ <answer>
+ <para>如果你有許多 telnet,ssh,X 或是 screen 使用者,你或許會用完
+ 虛擬終端機,這能教你怎麼加更多:</para>
+
+ <procedure>
+ <step>
+ <para>建立並安裝一個新的 kernel 並且把這一行</para>
+
+ <programlisting>pseudo-device pty 256</programlisting>
+
+ <para>加入到設定檔裡。</para>
+ </step>
+
+ <step>
+ <para>執行這個命令:</para>
+
+ <screen>&prompt.root; <userinput>cd /dev</userinput>
+&prompt.root; <userinput>sh MAKEDEV pty{1,2,3,4,5,6,7}</userinput></screen>
+
+ <para>會造出 256 個虛擬終端機的裝置節點。</para>
+
+ </step>
+
+ <step>
+ <para>編輯 <filename>/etc/ttys</filename> 並加入符合 256
+ 個終端機的行數。它們應該符合已經存在單項的格式,舉例來說,
+ 它們看起來像:</para>
+
+ <programlisting>ttyqc none network</programlisting>
+
+ <para>字母設計的順序是
+ <literal>tty[pqrsPQRS][0-9a-v]</literal>,使用正規表示式。
+ </para>
+ </step>
+
+ <step>
+ <para>用新的 kernel 重新啟動電腦就可以了。</para>
+ </step>
+ </procedure>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="create-snd0">
+ <para>/dev/snd0 這個裝置做不出來!</para>
+ </question>
+
+ <answer>
+ <para>並沒 <devicename>snd</devicename> 這個裝置的存在。這個名字
+ 是用來當作各個組成 FreeBSD 聲音驅動程式組,諸如
+ <devicename>mixer</devicename>,
+ <devicename>sequencer</devicename>,以及
+ <devicename>dsp</devicename> 的簡稱。</para>
+
+ <para>可以用以下的命令作出這些裝置:</para>
+
+ <screen>&prompt.root; <userinput>cd /dev</userinput>
+&prompt.root; <userinput>sh MAKEDEV snd0</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="reread-rc">
+ <para>可以不用開機,重新讀取 <filename>/etc/rc.conf</filename>、
+ 再次啟動 <filename>/etc/rc</filename> 嗎?</para>
+ </question>
+
+ <answer>
+ <para>先進入單人使用者模式,然後再回到多使用者模式。</para>
+
+ <para>在主控台執行:</para>
+
+ <screen>&prompt.root; <userinput>shutdown now</userinput>
+(Note: without -r or -h)
+
+&prompt.root; <userinput>return</userinput>
+&prompt.root; <userinput>exit</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="release-candidate">
+ <para>我想要把我的系統昇級到最新的 -STABLE,但是得到的是 -RC 或
+ -PRERELEASE!怎麼了?</para>
+ </question>
+
+ <answer>
+ <para>簡單地說:那只是名字而已。RC 的意思是 <quote>Release Candiate,
+ 發行候選版本</quote>,它表示新版本快要發行了。在 FreeBSD 中,
+ -PRERELEASE 通常是發行前的程式碼凍結的代名詞。(有些發行版本中,
+ -BETA 標籤跟 -PRERELEASE 是相同意思的。)</para>
+
+ <para>詳細地說:FreeBSD 從兩個地方分支出它的發行版本。主版號、
+ 點零、release (例如 3.0-RELEASE 及 4.0-RELEASE) 的,是從發展過程
+ 開始時分支出來的,通常稱為 <link linkend="current">-CURRENT
+ </link>。有副版號的版本 (例如 3.1-RELEASE 或 4.2-RELEASE),是
+ 活躍的 <link linkend="stable">-STABLE</link> 分支中的發行版本
+ 快照。從 4.3-RELEASE 開始,每一個發行版本有它自己的分支,可為
+ 偏好極度保守的發展速度 (通常只會作安全方面的更新) 的人所用。</para>
+
+ <para>準備要製作發行版本時,其所在的分支會經過一定的程序。有一個是
+ 程式碼凍結。當程式碼凍結開始時,分支名稱會更名,以反映它快要成為
+ 一個發行版本了。舉個例子,如果原來的分支叫 4.5-STABLE,它的名字
+ 會變成 4.6-PRERELEASE 以表示程式碼已凍結,並且額外的發行前測試
+ 將要開始了。臭蟲更正仍可回報,以成為發行版本的一部份。當程式碼
+ 有了可成為發行版本的雛形時,它的名字就會變成 4.6-RC,以表示發行
+ 版本快好了。進入 RC 階段後,只有找到的最有影響的臭蟲才會被修正。
+ 當發行版本 (本例中為 4.6-RELEASE) 產生後,發行版本會有自己的分支,
+ 原分支會被更名為 4.6-STABLE。</para>
+
+ <para>想要得知更多有關版本號碼與各 CVS 分支的資訊,請參考
+ <ulink url="../../articles/releng/article.html">Release
+ Engineering</ulink> 一文。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="kernel-chflag-failure">
+ <para>我試著要安裝一個新的核心,但是無法 chflags。我該怎麼解決?
+ </para>
+ </question>
+
+ <answer>
+ <para>簡單地說:你的 securelevel 可能大於零。直接重新開機到
+ 單人模式,再安裝核心。</para>
+
+ <para>詳細地說:FreeBSD 在 securelevel 大於零情況下,不允許
+ 變更系統旗標 (system flags)。你可以用這個指令檢查你的
+ securelevel:</para>
+
+ <screen>&prompt.root; <userinput>sysctl kern.securelevel</userinput></screen>
+
+ <para>你沒有辦法降低 securelevel;你必須啟動系統到單人模式以
+ 安裝核心,或是修改 <filename>/etc/rc.conf</filename> 內的
+ securelevel 再重新開機。請參考 &man.init.8; 說明文件,以取得
+ 更多有關 securelevel 的資訊,還有 <filename>/etc/defaults/rc.conf
+ </filename> 和 &man.rc.conf.5; 說明文件,以取得更多有關 rc.conf
+ 的資訊。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="kernel-securelevel-time">
+ <para>在我的系統上,我無法變更時間超過一秒以上的範圍!
+ 我該怎麼辦?</para>
+ </question>
+
+ <answer>
+ <para>簡單地講:你系統的 securelevel 也許大於 1。直接重新開機至
+ 單人模式,然後再修改時間。</para>
+
+ <para>詳細地說:在 securelevel 大於 1 的情況下,FreeBSD 不允許時間
+ 變動大於一秒。你可以用以下的命令來檢查目前的 securelevel:</para>
+
+ <screen>&prompt.root; <userinput>sysctl kern.securelevel</userinput></screen>
+
+ <para>你無法降低 securelevel;你必須啟動電腦至單人模式下以修改時間,
+ 或是修改 <filename>/etc/rc.conf</filename> 再重新開機。請參考
+ &man.init.8; 說明文件,以取得更多有關 securelevel 的資訊,還有
+ <filename>/etc/defaults/rc.conf</filename> 和 &man.rc.conf.5;
+ 說明文件,以取得更多有關 rc.conf 的資訊。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="statd-mem-leak">
+ <para>為什麼 <command>rpc.statd</command> 用了 256 megabytes
+ 的記憶體?</para>
+ </question>
+
+ <answer>
+ <para>不,那不是 memory leak,而且它也不是真的用了 256 Mbyte
+ 的記憶體。它只是喜歡 (意思就是總會這樣作) 將一狗票的記憶體
+ 映謝到它自己的位址空間,以方便作事。就技術而言,這樣並沒有
+ 什麼不對;這樣只是會讓 &man.top.1; 和 &man.ps.1; 嚇一大跳而已。
+ </para>
+
+ <para>&man.rpc.statd.8; 會將它的狀態檔案 (位於 <filename>/var
+ </filename>) 映射至它的位址空間裡;為了防止需要的時候再增大所
+ 導致的重新映射,它一次會使用相當大的大小。從程式碼來看的話就
+ 更明顯了,可以看到 &man.mmap.2; 的長度參數為 <literal>0x10000000
+ </literal>,它是 IA32 架構上的十六分之一的定址空間,也就是
+ 256MB。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="unsetting-schg">
+ <para>為什麼我沒辦法取消 <literal>schg</literal> 檔案旗標?</para>
+ </question>
+
+ <answer>
+ <para>你正在一個提高了 securelevel (也就是大於 0) 的系統運作。
+ 降低 securelevel 再試試看。請參考 <link linkend="securelevel">
+ FAQ 中對 securelevel 的說明</link> 和 &man.init.8; 說明文件。
+ </para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ssh-shosts">
+ <para>為什麼近來的新版 FreeBSD 預設無法利用 <filename>.shosts
+ </filename> 完成 SSH 認證?</para>
+ </question>
+
+ <answer>
+ <para>為什麼近來新版 FreeBSD <filename>.shosts</filename> 認證預設
+ 為取消的原因,是因為 &man.ssh.1; 預設不安裝為 suid 成 <username>
+ root</username>。要 <quote>修正</quote> 這點,你可以作下列的
+ 任何一件事:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>要一勞永逸解決,請將 <filename>/etc/make.conf</filename>
+ 裡的 <makevar>ENABLE_SUID_SSH</makevar> 設成 <literal>true
+ </literal>,然後再重新 build ssh (或是執行 <command>make
+ world</command>)。</para>
+ </listitem>
+
+ <listitem>
+ <para>只作一時的修正的話,可以 <username>root</username> 身份
+ 執行 <command>chmod 4755 /usr/bin/ssh</command> 將
+ <filename>/usr/bin/ssh</filename> 設成 <literal>4555
+ </literal>。然後將 <makevar>ENABLE_SUID_SSH= true</makevar>
+ 加入 <filename>/etc/make.conf</filename> 裡,這樣下次
+ <command>make world</command> 執行就會生效了。</para>
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="vnlru">
+ <para>什麼是 <literal>vnlru</literal>?</para>
+ </question>
+
+ <answer>
+ <para>當系統達到上限 <varname>kern.maxvnodes</varname> 時,
+ <literal>vnlru</literal> 會清除並釋放 vnode。這個核心
+ 執行緒大部份的時間都沒事作,只有當你有很大的記憶體,而且
+ 正在存取上萬個小檔案時,才會被啟動。</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+ <chapter id="x">
+ <chapterinfo>
+ <author>
+ <firstname>Wei-Hon</firstname>
+ <surname>Chen</surname>
+ <affiliation>
+ <address><email>plasmaball@pchome.com.tw</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>X Window System 及 Virtual Consoles</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="running-X">
+ <para>我想要執行 X ,我該怎麼做?</para>
+ </question>
+
+ <answer>
+
+ <para>最簡單的方法就是在安裝系統的時候一併安裝。</para>
+
+ <para>然後看看 &man.xorgconfig.1; 的文件,這個程式可以
+ 幫您設定 &xorg; 相關設定,使它能夠正確運用您的顯示卡、滑鼠等週邊。此外,還可以用 &man.xorgcfg.1;
+ 的圖形介面來做相關設定。</para>
+
+ <para>您或許也想試試看 Xaccel server。詳情請看 <link linkend="xig">Xi Graphics</link>
+ 這一段。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="running-X-securelevels">
+ <para>我 <emphasis>試著</emphasis> 要執行 X, 但是當我鍵入
+ <command>startx</command> 時,得到
+ <errorname>KDENABIO failed (Operation not permitted)</errorname>
+ 錯誤。我該怎麼辦?</para>
+ </question>
+
+ <answer>
+ <para>你的系統一定提高了 securelevel,對不對?在一個提高了
+ securelevel 的系統上,是絕對無法起動 X 的。想知道為什麼,
+ 請參考 &man.init.8; 說明文件。</para>
+
+ <para>所以這個問題變成:你還能怎麼辦。基本上你有兩種選擇:
+ 將你的 securelevel 設回零 (通常在 <filename>/etc/rc.conf
+ </filename> 裡面設定),或是在啟動時執行 &man.xdm.1; (在
+ securelevel 被昇高前)。</para>
+
+ <para>請參考 <xref linkend="xdm-boot"/> 以取得更多有關啟動時
+ 執行 &man.xdm.1; 的資訊。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="x-and-moused">
+ <para>為什麼我不能在 X 裡使用滑鼠?</para>
+ </question>
+
+ <answer>
+ <para>如果您用的是 syscons (內定的 console 驅動程式) 的話,您可以
+ 經由設定 FreeBSD 來讓它支援在每個 virtual console 使用滑鼠。為了
+ 避免和 X 產生衝突,syscons 使用了一個叫做
+ <devicename>/dev/sysmouse</devicename> 的虛擬裝置。所有滑鼠產生的
+ event 都會利用 moused 來寫到 sysmouse 這個裝置。如果您希望在一個
+ 或以上的 virtual console 上使用滑鼠,<emphasis>並且</emphasis>
+ 能夠使用 X 的話,請參考
+ <xref linkend="moused" remap="another section"/> 並且設定好
+ moused。</para>
+
+ <para>然後編輯 <filename>/etc/XF86Config</filename> 這個檔案,
+ 並且確認你有以下這幾行的設定。</para>
+
+ <programlisting>Section Pointer
+Protocol "SysMouse"
+Device "/dev/sysmouse"
+....</programlisting>
+
+ <para>以上的例子,適用於 XFree86 3.3.2 及其後的版本。用於更早的
+ 版本的,其 <emphasis>Protocol</emphasis> 應為
+ <emphasis>MouseSystems</emphasis>。</para>
+
+ <para>有些人比較喜歡在設定 X 的時候用
+ <devicename>/dev/mouse</devicename> 這個裝置。如果您要讓它能夠
+ 正常工作的話,您就必須把 <devicename>/dev/mouse</devicename>
+ 連結到 <devicename>/dev/sysmouse</devicename> (請參考
+ &man.sysmouse.4;):</para>
+
+ <screen>&prompt.root; <userinput>cd /dev</userinput>
+&prompt.root; <userinput>rm -f mouse</userinput>
+&prompt.root; <userinput>ln -s sysmouse mouse</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="x-and-wheel">
+ <para>滑鼠的滾輪,能在 X 裡面使用嗎?</para>
+ </question>
+
+ <answer>
+ <para>可以。不過需要設定 X client 端程式。 請參考 <ulink
+ url="http://www.inria.fr/koala/colas/mouse-wheel-scroll/">
+ Colas Nahaboo 的網頁
+ (http://www.inria.fr/koala/colas/mouse-wheel-scroll/)
+ </ulink>.</para>
+
+ <para>如果你要使用 <application>imwheel</application> 程式,
+ 只要跟著下列步驟作即可。</para>
+
+ <orderedlist>
+ <listitem>
+ <para>轉換滾輪 event
+Translate the Wheel Events</para>
+
+ <para><application>imwheel</application> 程式的運作原理,
+ 是將滑鼠的第四鍵與第五鍵轉換成按鍵 event。因為如此,所以
+ 你必須讓滑鼠驅動程式將滑輪事件轉換成第四鍵與第五鍵 event。
+ 有兩種方法可以達到目的,一是讓 &man.moused.8; 作轉換,二是
+ 讓 X 本身去作 event 轉換。</para>
+
+ <orderedlist>
+ <listitem>
+ <para>使用 &man.moused.8; 來轉換滾輪 Event</para>
+
+ <para>要讓 &man.moused.8; 來作 event 轉換,只要在
+ 執行 &man.moused.8; 的命令列中加上 <option>-z 4</option>
+ 即可。舉個例子,如果你一般都是以
+ <command>moused -p /dev/psm0</command> 來起動
+ &man.moused.8; 的話,只要改成 <command>moused -p
+ /dev/psm0 -z 4</command> 即可。如果你是在開機過程中利用
+ <filename>/etc/rc.conf</filename> 來起動 &man.moused.8;,
+ 你可以在 <filename>/etc/rc.conf</filename> 中將
+ <varname>moused_flags</varname> 上加 <option>-z 4
+ </option> 即可。</para>
+
+ <para>你現在需要讓 X 知道你的滑鼠有五個按鍵,只要在
+ <filename>/etc/XF86Config</filename> 中的
+ <quote>Pointer</quote> 區塊中加上
+ <literal>Buttons 5</literal> 這一行即可。例如,
+ 你可能在 <filename>/etc/XF86Config</filename> 中有
+ 以下的 <quote>Pointer</quote> 區塊:</para>
+
+ <example>
+
+ <title>在 XFree86 3.3.x 系列的 XF86Config 設定檔的
+ <quote>Pointer</quote> 區塊中,以 moused 作轉換
+ 的滾輪鼠的設定範例</title>
+
+ <programlisting>Section "Pointer"
+ Protocol "SysMouse"
+ Device "/dev/sysmouse"
+ Buttons 5
+EndSection</programlisting>
+ </example>
+
+ <example>
+ <title>在 XFree86 4.x 系列的 XF86Config 設定檔的
+ <quote>InputDevice</quote> 區塊中,以 X Server 作轉換
+ 的滾輪鼠的設定範例</title>
+
+ <programlisting>Section "InputDevice"
+ Identifier "Mouse1"
+ Driver "mouse"
+ Option "Protocol" "auto"
+ Option "Device" "/dev/sysmouse"
+ Option "Buttons" "5"
+EndSection</programlisting>
+ </example>
+
+ <example>
+ <title>在 <quote>.emacs</quote> 中,設定滾輪鼠的原生
+ 頁面滾動支援範例</title>
+ <programlisting>;; wheel mouse
+(global-set-key [mouse-4] 'scroll-down)
+(global-set-key [mouse-5] 'scroll-up)</programlisting>
+ </example>
+
+ </listitem>
+
+ <listitem>
+ <para>利用你的 X Server 來作滾輪 Event 轉換</para>
+
+ <para>如果你沒有執行 &man.moused.8;,或是你不想利用
+ &man.moused.8; 去作滾輪 event 轉換,你可以改用
+ X server 來作這樣的 event 轉換。你得在 <filename>
+ /etc/XF86Config</filename> 檔案中作幾個更動。第一,
+ 你要為你的滑鼠選擇適當的通訊協定。大多數的滾輪鼠都
+ 使用 <quote>IntelliMouse</quote> 協定,不過 XFree86
+ 也支援其它的通訊協定,例如羅技的 MouseMan+ 滑鼠所用的
+ <quote>MouseManPlusPS/2</quote>。當你選好之後,只要
+ 加進一行 <quote>Pointer</quote> 區塊的 <varname>
+ Protocol</varname> 變數即可。</para>
+
+ <para>第二,你要告訴 X server 將捲動事件重新對映至滑鼠的
+ 第四和第五鍵。這可以利用 <varname>ZAxisMapping</varname>
+ 選項辦到。</para>
+
+ <para>舉個例子,如果你沒有使用 &man.moused.8;,而你有一個
+ IntelliMouse 安裝在 PS/2 滑鼠埠的話,你可以在
+ <filename>/etc/XF86Config</filename> 裡使用以下的設定。
+ </para>
+
+ <example>
+ <title>在 XF86Config 設定檔的 <quote>Pointer</quote>
+ 區塊中,以 X Server 作轉換的滾輪鼠的設定範例</title>
+
+ <programlisting>Section "Pointer"
+ Protocol "IntelliMouse"
+ Device "/dev/psm0"
+ ZAxisMapping 4 5
+EndSection</programlisting>
+ </example>
+
+ <example>
+ <title>在 XFree86 4.x 系列的 XF86Config 設定檔的
+ <quote>InputDevice</quote> 區塊中,以 X Server 作轉換
+ 的滾輪鼠的設定範例</title>
+
+ <programlisting>Section "InputDevice"
+ Identifier "Mouse1"
+ Driver "mouse"
+ Option "Protocol" "auto"
+ Option "Device" "/dev/psm0"
+ Option "ZAxisMapping" "4 5"
+EndSection</programlisting>
+ </example>
+
+ <example>
+ <title>在 <quote>.emacs</quote> 中,設定滾輪鼠的原生
+ 頁面滾動支援範例</title>
+ <programlisting>;; wheel mouse
+(global-set-key [mouse-4] 'scroll-down)
+(global-set-key [mouse-5] 'scroll-up)</programlisting>
+ </example>
+
+ </listitem>
+ </orderedlist>
+ </listitem>
+
+ <listitem>
+ <para>安裝 <application>imwheel</application></para>
+
+ <para>接下來,從 Ports 裡安裝 <application>imwheel
+ </application>。在 x11 類別裡可以找到它,它可以將
+ 滾輪 event 對映到鍵盤 event。舉個例子,它可以在你
+ 將滾輪往前推時,送出一個 <keycap>Page Up</keycap>
+ 到你的應用程式去。<application>Imwheel</application>
+ 利用一個設定檔,以便對應滾輪 event 至鍵盤 event,這樣
+ 它就可以在不同的應用程式中,送出不同的鍵盤按鍵。預設的
+ <application>imwheel</application> 設定檔是在
+ <filename>/usr/X11R6/etc/imwheelrc</filename>,如果你想
+ 編輯自訂的設定檔的話,可以將它複製到
+ <filename>~/.imwheelrc</filename>,然後依你的需要修改它。
+ 設定檔的格式在 &man.imwheel.1; 裡面有詳細的說明。</para>
+ </listitem>
+
+ <listitem>
+ <para>設定 <application>Emacs</application> 與
+ <application>Imwheel</application> 協同工作
+ (<emphasis>選擇性</emphasis>)</para>
+
+ <para>如果你使用 <application>emacs</application> 或是
+ <application>Xemacs</application> 的話,那你需要在你的
+ <filename>~/.emacs</filename> 檔案裡加上一小段設定。
+ <application>emacs</application> 請加上這一段:</para>
+
+ <example>
+ <title><application>Imwheel</application> 的
+ <application>Emacs</application> 設定</title>
+
+ <programlisting>;;; For imwheel
+(setq imwheel-scroll-interval 3)
+(defun imwheel-scroll-down-some-lines ()
+ (interactive)
+ (scroll-down imwheel-scroll-interval))
+(defun imwheel-scroll-up-some-lines ()
+ (interactive)
+ (scroll-up imwheel-scroll-interval))
+(global-set-key [?\M-\C-\)] 'imwheel-scroll-up-some-lines)
+(global-set-key [?\M-\C-\(] 'imwheel-scroll-down-some-lines)
+;;; end imwheel section</programlisting>
+ </example>
+
+ <para><application>Xemacs</application> 則在
+ <filename>~/.emacs</filename> 檔裡加上這一段:</para>
+
+ <example>
+ <title><application>Imwheel</application> 的
+ <application>Xemacs</application> 設定</title>
+
+ <programlisting>;;; For imwheel
+(setq imwheel-scroll-interval 3)
+(defun imwheel-scroll-down-some-lines ()
+ (interactive)
+ (scroll-down imwheel-scroll-interval))
+(defun imwheel-scroll-up-some-lines ()
+ (interactive)
+ (scroll-up imwheel-scroll-interval))
+(define-key global-map [(control meta \))] 'imwheel-scroll-up-some-lines)
+(define-key global-map [(control meta \()] 'imwheel-scroll-down-some-lines)
+;;; end imwheel section</programlisting>
+ </example>
+ </listitem>
+
+ <listitem>
+ <para>執行 <application>Imwheel</application></para>
+
+ <para>安裝之後,你可以直接在 xterm 裡鍵入 <command>imwheel
+ </command> 命令以起動它。它會以背景執行,並且馬上發揮效用。
+ 如果你確定要直接使用 <application>imwheel</application>,
+ 只要把它加進你自己的 <filename>.xinitrc</filename> 或
+ <filename>.xsession</filename> 內檔案即可。你可以不管
+ <application>imwheel</application> 所送出來有關 PID 檔案
+ 警告。那些警告只對 Linux 版的 <application>imwheel
+ </application> 有效而已。</para>
+ </listitem>
+ </orderedlist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="window-menu-weird">
+ <para>為什麼 X Window 的選單和對話框不能正常運作?</para>
+ </question>
+
+ <answer>
+ <para>把 Num Lock 關掉試試。</para>
+
+ <para>如果您的 Num Lock 在開機時的預設值是開著的話,您必須把下列
+ 這行放到 <filename>XF86Config</filename> 設定檔中的
+ <literal>Keyboard</literal> 部份。</para>
+
+ <programlisting># Let the server do the NumLock processing. This should only be
+# required when using pre-R6 clients
+ ServerNumLock</programlisting>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="virtual-console">
+ <para>什麼是 virtual console?我要怎麼做才能用多一點?</para>
+ </question>
+
+ <answer>
+ <para>簡單來說,virtual console 就是可以讓您不必做太多複雜的設定
+ 如使用網路或執行 X ,而在同一臺機器上同時做好幾件事的方法。</para>
+
+ <para>當啟動系統並顯示完所有開機訊息之後,您就會在螢幕上看到一個
+ login 的提示符號。在這個時候您就可以輸入您的 login name 以及
+ password ,然後就可以在第一個 virtual console 上開始工作了
+ (或者開始玩!) 。</para>
+
+ <para>在某些情況下,您可能會想要作其他的工作,例如說是看看您正在
+ 執行的程式的說明文件,或是當您在 FTP 傳輸的等待時間中看看您的
+ 郵件。您只需要按 Alt-F2 (按住 Alt 鍵不放,並按下 F2 鍵) ,然後
+ 您就會在第二個 <quote>virtual console</quote> 上看到一個 login
+ 提示符號!當您想要回到原來的工作時,請按 Alt-F1。</para>
+
+ <para>FreeBSD 在安裝時的預設值是使用三個 virtual console
+ (3.3-RELEASE 後為八個),您可以用 Alt-F1,Alt-F2,以及 Alt-F3
+ 在它們之間做切換。</para>
+
+ <para>如果您想要多一點 virtual console 的話,您只需要編輯
+ <filename>/etc/ttys</filename> 這個檔 (請參考 &man.ttys.5;),
+ 在 <quote>Virtual terminals</quote> 這個註解後面加入
+ <devicename>ttyv4</devicename> 到 <devicename>ttyvc</devicename>
+ 的欄位:</para>
+
+ <programlisting># Edit the existing entry for ttyv3 in /etc/ttys and change
+# "off" to "on".
+ttyv3 "/usr/libexec/getty Pc" cons25 on secure
+ttyv4 "/usr/libexec/getty Pc" cons25 on secure
+ttyv5 "/usr/libexec/getty Pc" cons25 on secure
+ttyv6 "/usr/libexec/getty Pc" cons25 on secure
+ttyv7 "/usr/libexec/getty Pc" cons25 on secure
+ttyv8 "/usr/libexec/getty Pc" cons25 on secure
+ttyv9 "/usr/libexec/getty Pc" cons25 on secure
+ttyva "/usr/libexec/getty Pc" cons25 on secure
+ttyvb "/usr/libexec/getty Pc" cons25 on secure</programlisting>
+
+ <para>您想用幾個就設幾個。您設越多 virtual terminal ,它們就用掉
+ 越多系統資源;如果您只有不到 8MB 的記憶體的話,這影響就大了。
+ 您可能也會想把 <literal>secure</literal> 換成
+ <literal>insecure</literal>。</para>
+
+ <important>
+ <para>如果您想要執行 X 的話,您 <emphasis>必須</emphasis>
+ 為它保留 (或關掉) 至少一個 virtual terminal 。這就是說,如果
+ 您想在按十二個 Alt 功能鍵時都有 login 提示符號,而且又在同一
+ 部電腦上也想執行 X 的話,那麼這真是太不幸了 - 您只能用十一個。
+ </para>
+ </important>
+
+ <para>取消一個 console 最簡單的方法就是把它關掉。舉例來說,如果
+ 您像上面講的一樣設定了全部的 12 個 terminal 並且想要執行 X ,
+ 您必需把 virtual terminal 12 從:</para>
+
+ <programlisting>ttyvb "/usr/libexec/getty Pc" cons25 on secure</programlisting>
+
+ <para>設成:</para>
+
+ <programlisting>ttyvb "/usr/libexec/getty Pc" cons25 off secure</programlisting>
+
+ <para>如果您的鍵盤只有 10 個功能鍵的話,您就要改成這樣:</para>
+
+<programlisting>ttyv9 "/usr/libexec/getty Pc" cons25 off secure
+ttyva "/usr/libexec/getty Pc" cons25 off secure
+ttyvb "/usr/libexec/getty Pc" cons25 off secure</programlisting>
+
+ <para>(您也可以直接把這幾行砍掉。)</para>
+
+ <para>一旦您改了 <filename>/etc/ttys</filename>,下一個步驟就是要
+ 確定您有足夠的 virtual terminal 裝置。最簡單的方法就是:</para>
+
+ <screen>&prompt.root; <userinput>cd /dev</userinput>
+&prompt.root; <userinput>sh MAKEDEV vty12</userinput></screen>
+
+ <para>再過來,想要啟動這些 virtual console 最簡單 (也是最乾淨)
+ 的做法就是重開機。然後,如果您不想重開機的話,您可以把 X Window
+ 關掉,然後用 <username>root</username> 的身份執行下列指令:</para>
+
+ <screen>&prompt.root; <userinput>kill -HUP 1</userinput></screen>
+
+ <para>當您執行這個命令前,您一定要完全把 X Window 關掉。如果
+ 您不這麼做的話,您的系統可能會在您執行 kill 命令後出現當掉或
+ 鎖死的情況。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="vty-from-x">
+ <para>我要怎麼從 X 切換到 virtual console?</para>
+ </question>
+
+ <answer>
+ <para>請用 <keycombo action="simul">
+ <keycap>Ctrl</keycap>
+ <keycap>Alt</keycap>
+ <keycap>F<replaceable>n</replaceable></keycap>
+ </keycombo> 以切回至 virtual console。
+ <keycombo action="simul">
+ <keycap>Ctrl</keycap>
+ <keycap>Alt</keycap>
+ <keycap>F1</keycap>
+ </keycombo> 可以切回至第一個 virtual console。</para>
+
+ <para>當你切回至文字 console 後,你就可以使用一般
+ <keycombo action="simul">
+ <keycap>Alt</keycap>
+ <keycap>F<replaceable>n</replaceable></keycap>
+ </keycombo> 按鍵組合,在各 console 之間切換。</para>
+
+ <para>要回到 X 的話,你必須切回至執行 X 的 virtual console。
+ 如果你是從命令列裡起動 X 的話 (例如使用 <command>startx</command>
+ 指令),那麼 X 會依附在下一個未使用的 virtual console,而不是它被
+ 起動的文字 console。如果你有八個使用中的 virtual terminal,那麼
+ X 就會在第九個上執行,你就可以使用
+ <keycombo action="simul">
+ <keycap>Alt</keycap>
+ <keycap>F9</keycap>
+ </keycombo> 以返回至 X 中。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="xdm-boot">
+ <para>我要怎麼做才能在開機時啟動 XDM?</para>
+ </question><answer>
+
+ <para>有兩種方法可以啟動 <ulink
+ url="http://www.FreeBSD.org/cgi/man.cgi?manpath=xfree86&amp;query=xdm">
+ xdm</ulink>。一種方法是從 <filename>/etc/ttys</filename> 來啟動,
+ 可以參考 &man.ttys.5; 說明文件中的範例;另一種方法是在
+ <filename>rc.local</filename> (請參考 &man.rc.8;) 執行 xdm,或是
+ 在 <filename>/usr/local/etc/rc.d</filename> 放一個
+ <filename>X.sh</filename>。這兩種方法都是合法的,如果您試某一種
+ 方法無效的話,您可以試試另外一種。這兩種方法的結果是一樣的:X
+ 會顯示一個圖形化的 login: 提示。</para>
+
+ <para>用 ttys 的方法的優點,在於指明了 X 在啟動時到底是用那個 vty,
+ 並且將 logout 時重新啟動 X server 的責任丟給 init。 rc.local
+ 的方法則是在當啟動 X 出了問題時,可以很輕鬆地把 xdm 殺掉來解決
+ 問題。</para>
+
+ <para>如果是用 rc.local 的方法,在執行 <command>xdm</command>
+ 時您不能加任何參數(也就是跑成 daemon)。必須在 getty 執行後
+ 才能啟動 xdm,否則 getty 和 xdm 會互相衝突而鎖住 console。最好的
+ 方式是在 script 中加個 sleep,讓它暫停 10 秒鐘左右,接著才執行
+ xdm。</para>
+
+ <para>如果你是從 <filename>/etc/ttys</filename> 啟動
+ <command>xdm</command>,<command>xdm</command> 與 &man.getty.8;
+ 仍有機會互相衝突。一個避免它的方法,就是在
+ <filename>/usr/X11R6/lib/X11/xdm/Xservers</filename> 檔案中加入
+ <literal>vt</literal> 數字。</para>
+
+ <programlisting>:0 local /usr/X11R6/bin/X vt4</programlisting>
+
+ <para>上面的例子中,會指示 X server 在 <devicename>/dev/ttyv3
+ </devicename> 中執行。請注意數字是差一的。X server 從一開始數
+ vty,而 FreeBSD 核心則是從零開始數 vty 的。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="xconsole-failure">
+ <para>為什麼當我執行 xconsole 時,發生了
+ <errorname>Couldn't open console</errorname> 的錯誤?</para>
+ </question>
+
+ <answer>
+ <para>如果你是用 <command>startx</command> 來啟動 <command>startx
+ </command> 的話,<devicename>/dev/console</devicename> 的權限並
+ <emphasis>不會</emphasis> 改變,結果就是 <command>xterm -C
+ </command> 和 <command>xconsole</command> 這類的程式無法
+ 正常執行。</para>
+
+ <para>這一切的問題,都是因為 console 的權限是採用系統預設值。
+ 在一個多使用者的系統裡,我們不希望每個使用者都可以直接寫入系統
+ console 。如果使用者是從機器的 VTY 直接 login 的話,那麼
+ &man.fbtab.5; 可以解決這類的問題。</para>
+
+ <para>簡單地說,請確保 <filename>/etc/fbtab</filename> (請參考
+ &man.fbtab.5;) 這個檔案中的這一行沒有被註解掉:</para>
+
+ <programlisting>/dev/ttyv0 0600 /dev/console</programlisting>
+
+ <para>這一行設定的存在可以確保從 <devicename>/dev/ttyv0</devicename>
+ 登入的使用者可以控制 console。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="xfree86-root">
+ <para>以前我可以以一般使用者執行 XFree86,為什麼現在它說我一定要
+ 以 <username>root</username> 才能執行?</para>
+ </question>
+
+ <answer>
+ <para>所有的 X server 都需要以 <username>root</username> 來執行,
+ 才能直接存取你的視訊硬體。舊版本的 XFree86 (&lt;= 3.3.6) 會自動
+ 將所附的 server 以利用 <username>root</username> 身份執行的方式
+ 安裝起來 (setuid 為 <username>root</username>)。由於 X server
+ 都是體積龐大又複雜的程式,顯而易見地,這是一個安全上的災難。
+ 因為這個原因,新版的 XFree86 就不將這些 server 以 setuid 為
+ <username>root</username> 的方式安裝。</para>
+
+ <para>很明顯地,我們完全無法接受將 X server 以
+ <username>root</username> 的身份執行。起碼就安全上不是個好主意。
+ 有兩種方法可以以一般使用者的身份使用 X。第一是利用
+ <command>xdm</command> 或是其它的 display manager (例如
+ <command>kdm</command>);第二是利用 <command>Xwrapper</command>。
+ </para>
+
+ <para><command>xdm</command> 是一個處理圖形界面登入的 daemon。
+ 它通常在開機時執行起來,而且負責對使用者作身份認證,以及起動
+ 使用者的工作環境;它可說是圖形環境下的 &man.getty.8; 與
+ &man.login.1; 的對應程式。想得知更多有關 <command>xdm</command>
+ 的資訊,請參考 <ulink url="http://www.xfree86.org/support.html">
+ XFree86 文件</ulink>,以及其 <link linkend="xdm-boot">FAQ
+ 項目</link>。</para>
+
+ <para><command>Xwrapper</command> 是 X server 的包裝程式;它可以
+ 讓一般使用者可以手動起動 X server 的小工具,而還能維持一定的安全
+ 環境。它會檢查傳入的命令列參數,如果沒問題的話,就起動適當的
+ X server。如果你因為某種理由而不想執行 display manager 的話,
+ 它是為你而設定的。如果你安裝了完整的 ports,你可以在
+ <filename>/usr/ports/x11/wrapper</filename> 中找到它。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ps2-x">
+ <para>我的 PS/2 滑鼠在 X 中有點不正常?</para>
+ </question>
+
+ <answer>
+ <para>您的滑鼠和您的滑鼠驅動程式可能存在有不同步的現象。</para>
+
+ <para>在 2.2.5 以及更早的系統裡,從 X 切到 virtual terminal 然後
+ 再切回來就可以使它們重新做同步的動作。如果這個問題常常發生的話,
+ 您可以在您的 kernel 設定檔中加入下面這個選項然後重新編譯:</para>
+
+ <programlisting>options PSM_CHECKSYNC</programlisting>
+
+ <para>如果您沒有建立 kernel 的經驗,請看
+ <link linkend="make-kernel">自訂核心</link> 這一節。</para>
+
+ <para>加上這個選項以後,滑鼠和滑鼠驅動程式間的同步問題應該就比較
+ 不會出現了。如果這個問題仍然存在的話,在移動滑鼠時按按滑鼠按鍵
+ 可以使滑鼠和滑鼠驅動程式重新做同步的動作。</para>
+
+ <para>該注意的是這個選項並不是對每一個系統都有效,它可能會讓接在
+ PS/2 滑鼠位置的 ALPS GlidePoint 裝置失去 <quote>tap</quote>
+ 這項功能。</para>
+
+ <para>在 2.2.6 及其後的版本,同步的確認已經有了較好的解決辦法,
+ 而且這些都已經是 PS/2 滑鼠驅動程式的標準了。這個方法也可以在
+ GlidePoint 上正常工作。 (因為確認的程式碼已經成為一個標準功能,
+ 所以在這些版本中我們不在提供 PSM_CHECKSYNC 的選項了。) 不過在
+ 極少數的案例中,這些驅動程式會誤報同步性錯誤,然後您就會看到
+ 這樣的核心訊息:</para>
+
+ <programlisting>psmintr: out of sync (xxxx != yyyy)</programlisting>
+
+ <para>然後您就會發現您的滑鼠不能正常運作了。</para>
+
+ <para>如果您發生了這樣的狀況,您必須藉由把 PS/2 滑鼠驅動程式的 flag
+ 設成 0x100 來把同步確認的程式碼給取消掉。然後在開機提示符號時用
+ <option>-c</option> 選項來進入 <emphasis>UserConfig</emphasis>:
+ </para>
+
+ <screen>boot: <userinput>-c</userinput></screen>
+
+ <para>然後,在 <emphasis>UserConfig</emphasis> 命令列中鍵入:</para>
+
+ <screen>UserConfig&gt; <userinput>flags psm0 0x100</userinput>
+UserConfig&gt; <userinput>quit</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ps2-mousesystems">
+ <para>我的 PS/2 滑鼠不能透過 MouseSystem 來運作?</para>
+ </question>
+
+ <answer>
+ <para>有一些報告指出某些廠牌的 PS/2 滑鼠只能在
+ <quote>高解析度</quote> 狀態下才能運作。如果不是的話,滑鼠游標
+ 會常常跑到螢幕的左上角去。</para>
+
+ <para>非常不幸的,這個問題在 2.0.X 和 2.1.X 下是無解的。在 2.2
+ 到 2.2.5 版,您可以對 <filename>/sys/i386/isa/psm.c</filename>
+ 使用下列 patch 然後重建您的核心。如果您沒有建立 kernel 的經驗,
+ 請看 <link linkend="make-kernel">自訂核心</link> 這節。</para>
+
+ <programlisting>@@ -766,6 +766,8 @@
+ if (verbose &gt;= 2)
+ log(LOG_DEBUG, "psm%d: SET_DEFAULTS return code:%04x\n",
+ unit, i);
++ set_mouse_resolution(sc-&gt;kbdc, PSMD_RES_HIGH);
++
+ #if 0
+ set_mouse_scaling(sc-&gt;kbdc); /* 1:1 scaling */
+ set_mouse_mode(sc-&gt;kbdc); /* stream mode */</programlisting>
+
+ <para>在 2.2.6 及以後的版本,在 PS/2 滑鼠驅動程式中設定 0x04 的
+ flag 會把滑鼠設成高解析度模式。在開機提示符號時用
+ <option>-c</option> 選項來進入 <emphasis>UserConfig</emphasis>:
+ </para>
+
+ <screen>boot: <userinput>-c</userinput></screen>
+
+ <para>然後,在 <emphasis>UserConfig</emphasis> 的命令列中鍵入:
+ </para>
+
+ <screen>UserConfig&gt; <userinput>flags psm0 0x04</userinput>
+UserConfig&gt; <userinput>quit</userinput></screen>
+
+ <para>前一節有提到另一個可能導致滑鼠問題的原因。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="imake-tmpl">
+ <para>當我建立 X 程式時,<command>imake</command> 說它找不到
+ <filename>Imake.tmpl</filename>。它在哪兒?</para>
+ </question>
+
+ <answer>
+
+ <para><filename>Imake.tmpl</filename> 是 Imake 套件的一部份,Imake
+ 是標準的建立 X 程式的工具。 <filename>Imake.tmpl</filename>
+ 和其他數個 header file 一樣是建立 X 程式的必要檔案,您可以在
+ X prog distribution 中找到它們。您可以用 sysinstall(&os; 5.2 之前版本則是 <command>/stand/sysinstall</command>)
+ 來安裝或是直接從 X distribution 中手動安裝。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="xfree86-version">
+ <para>我在 build 一個 X 應用程式,它需要 XFree86 3.3.x,但是
+ 我已經安裝 XFree86 4.x 了。我該怎麼辦?</para>
+ </question>
+
+ <answer>
+ <para>要告訴 port 在編譯程式時,使用 XFree86 4.x 函式庫,你可以
+ 在 <filename>/etc/make.conf</filename> 裡 (如果你沒有這個檔,
+ 請建立它) 加上下面這一行:</para>
+
+ <programlisting>XFREE86_VERSION= 4</programlisting>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="mouse-button-reverse">
+ <para>我要怎麼做才能設定左撇子用的滑鼠?</para>
+ </question>
+
+ <answer>
+ <para>在您的 <filename>.xinitrc</filename> 或是
+ <filename>.xsession</filename> 中執行
+ <literal>xmodmap -e "pointer = 3 2 1"</literal> 的指令。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="install-splash">
+ <para>要如何安裝 splash 圖形顯示程式?那裡可以找得到呢?</para>
+ </question>
+
+ <answer>
+
+ <para>就在發行 FreeBSD 3.1 之前,我們加進了在開機時顯示
+ <quote>splash</quote> 圖形的新功能。目前用來顯示在螢幕上的檔案
+ 必須是 256 色的點矩陣圖形 (<filename>*.BMP</filename>) 或 ZSoft
+ PCX(<filename>*.PCX</filename>) 的格式。除此之外,解析度也必須在
+ 320x200 以下,才能和標準 VGA 顯示卡搭配使用。如果您編譯 kernel
+ 時有加入 VESA 支援,那麼最大解析度可以到 1024x768。注意 VESA 的
+ 支援需要加入 <literal>VM86</literal> 這個 kernel 選項。VESA
+ 支援實際上可以在編譯 kernel 時加入 <literal>VESA</literal> 選項、
+ 或載入 VESA 的 kld module 來達成。</para>
+
+ <para>您要修改控制 FreeBSD 開機步驟的設定檔,才能使用 splash
+ 顯示圖形的功能。設定檔在發行 FreeBSD 3.2 前有些更動,所以現在
+ 有兩個方法可以載入 splash 的功能:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>FreeBSD 3.1</para>
+
+ <para>先選出用來顯示在螢幕上的圖形,3.1 版只支援 Windows
+ 的點矩陣格式。選好了您要的圖檔後,將它拷到 <filename>
+ /boot/splash.bmp</filename>。接著把下面幾行加入
+ <filename>/boot/loader.rc</filename> 中:</para>
+
+ <programlisting>load kernel
+load -t splash_image_data /boot/splash.bmp
+load splash_bmp
+autoboot</programlisting>
+
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD 3.2+</para>
+
+ <para>除了加入對 PCX 檔案的支援外,FreeBSD 3.2 也改進了
+ 開機程序的設定方式。如果您願意的話,可以用上述 FreeBSD 3.1
+ 的方法,將 <literal>splash_bmp</literal> 換成
+ <literal>splash_pcx</literal> 來載入 PCX 檔案即可。
+ 如果想用新的設定方式,您的 <filename>/boot/loader.rc
+ </filename> 必須包括這幾行:</para>
+
+ <programlisting>include /boot/loader.4th
+start</programlisting>
+
+ <para>還需要一個包含以下幾行的 <filename>/boot/loader.conf
+ </filename>:</para>
+
+ <programlisting>splash_bmp_load="YES"
+bitmap_load="YES"</programlisting>
+
+ <para>這是假設您用 <filename>/boot/splash.bmp</filename>
+ 來當作 splash 的螢幕顯示。如果想用 PCX 的檔案,把它拷成
+ <filename>/boot/splash.pcx</filename>,如上述做出
+ <filename>/boot/loader.rc</filename>,再將這幾行加到
+ <filename>/boot/loader.conf</filename> 中:</para>
+
+ <programlisting>splash_pcx_load="YES"
+bitmap_load="YES"
+bitmap_name="/boot/splash.pcx"</programlisting>
+
+ </listitem>
+ </itemizedlist>
+
+ <para>現在就只剩下 splash 用來顯示的圖檔,您可以在
+ <ulink url="http://www.baldwin.cx/splash/">http://www.baldwin.cx/splash/</ulink> 找到各種樣品。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="windows-keys">
+ <para>我能在 X 裡使用鍵盤上的 <trademark class="registered">Windows
+ </trademark> 嗎?</para>
+ </question>
+
+ <answer>
+ <para>可以。你所要作的,就是利用 &man.xmodmap.1; 去定義你想使用
+ 的功能。</para>
+
+ <para>假設所有的 <quote><trademark class="registered">Windows</trademark></quote> 都是標準的,
+ 那它們的 keycode 分別為:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>115 - <trademark class="registered">Windows</trademark> 鍵,
+ 在左手的 Ctrl 與 Alt 鍵之間</para>
+ </listitem>
+
+ <listitem>
+ <para>116 - <trademark class="registered">Windows</trademark> 鍵,
+ 在 Alt-Gr 鍵右邊</para>
+ </listitem>
+
+ <listitem>
+ <para>117 - 選單鍵,右手的 Ctrl 鍵左邊</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>要讓左邊的 <trademark class="registered">Windows</trademark>
+ 鍵印出一個逗點,試試這個:</para>
+
+ <screen>&prompt.root; <userinput>xmodmap -e "keycode 115 = comma"</userinput></screen>
+
+ <para>你可能要重跑你的 windows manager,才會有動作。</para>
+
+ <para>要讓 <trademark class="registered">Windows</trademark> 鍵
+ 的對映在每次 X 起動時自動設定好,你可以在你的
+ <filename>~/.xinitrc</filename> 裡加上 <command>xmodmap</command>,
+ 或是最好建立一個 <filename>~/.xmodmaprc</filename> 檔案,裡面
+ 每一行就是一個 <command>xmodmap</command> 的選項,然後在你的
+ <filename>~/.xinitrc</filename> 裡加上:</para>
+
+
+ <programlisting>xmodmap $HOME/.xmodmaprc</programlisting>
+
+ <para>這一行。</para>
+
+ <para>例如,你想要將這三個鍵各對映到 F13、F14 和 F15。這讓你能
+ 在你的程式或是 window manager 內將其對應到便利的功能上,等一下
+ 我們會示範。</para>
+
+ <para>把這些放進 <filename>~/.xmodmaprc</filename> 裡:</para>
+
+ <programlisting>keycode 115 = F13
+keycode 116 = F14
+keycode 117 = F15</programlisting>
+
+ <para>假如你用 <command>fvwm2</command> 的話,你可以作這樣的對映,
+ 讓 F13 能夠讓游標所在的視窗縮成小圖示 (或是反過來)。F14 讓游標
+ 所在的視窗變成最上層的視窗,或是退到下層去 (如果它已經是最上層
+ 了的話)。F15 則將 Workplace (application) 選單叫出來,即使游標
+ 不在桌面上。當你沒有可見的桌面區域時,這個功能就相當地方便 (而且
+ 按鍵上的圖案和這個功能相吻合)。</para>
+
+ <para>以下的 <filename>~/.fvwmrc</filename> 設定可作出前述的功能。
+ </para>
+
+ <programlisting>Key F13 FTIWS A Iconify
+Key F14 FTIWS A RaiseLower
+Key F15 A A Menu Workplace Nop</programlisting>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="x-3d-acceleration">
+ <para>我要怎麼樣才能得到 OpenGL 的 3D 硬體加速功能?</para>
+ </question>
+
+ <answer>
+ <para>3D 加速功能的有無,視你所使用的 XFree86 版本與顯示晶片
+ 的型號而定。如果你的是 NVIDIA 晶片的話,請去
+ <ulink url="http://nvidia.netexplorer.org/">FreeBSD NVIDIA
+ Driver Initiative </ulink> 網頁看看,那裡有在 XFree86-4 上使用
+ NVIDIA 晶片的 3D 加速功能的討論。XFree86-4 上的其它顯示卡廠牌
+ 硬體加速功能的資訊, 包括 Matrox G200/G400, ATI Rage 128/Radeon,
+ 3dfx Voodoo 3, 4, 5, 以及 Banshee,可在 <ulink
+ url="http://gladstone.uoregon.edu/~eanholt/dri/">XFree86-4
+ Direct Rendering on FreeBSD</ulink> 網頁上找到。XFree 3.3 的
+ 使用者可以使用 Utah-GLX port,它可以在
+ <filename role="package">graphics/utah-glx</filename> 找到。
+ 使用它可以在 Matrox Gx00, ATI Rage Pro, SiS 6326, i810,
+ Savage, 以及舊的 NVIDIA 上得到有限的 OpenGL 加速。</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+ <chapter id="networking">
+ <chapterinfo>
+ <author>
+ <firstname>Biing Jong</firstname>
+ <surname>Lin</surname>
+ <affiliation>
+ <address><email>bjlin@stic.gov.tw</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>Networking</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="diskless-booting">
+ <para>我應該到哪邊找有關無磁碟開機
+ <quote>diskless booting</quote> 的資料?</para>
+ </question>
+
+ <answer>
+ <para><quote>Diskless booting</quote> 就是讓 FreeBSD 主機從網路
+ 上開機,並且從網路上的 server 上讀取其他必要的檔案,而非由主機
+ 的硬碟上取得這些檔案。詳細的資料可以參考 <ulink
+ url="../handbook/diskless.html"> FreeBSD 手冊的無磁碟開機篇
+ </ulink>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="router">
+ <para>FreeBSD 的主機可以當作某個網路上的路由器(router)嗎?</para>
+ </question>
+
+ <answer>
+ <para>是的。請參考 FreeBSD 手冊的網路進階篇 <ulink
+ url="../handbook/routing.html"> advanced
+ networking</ulink>,尤其是路由與閘道器 <ulink
+ url="../handbook/routing.html#DEDICATED-ROUTER">routing
+ and gateways</ulink>的部分。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="win95-connection">
+ <para>我可以透過 FreeBSD 將我的 Win95 機器連上 Internet 嗎?</para>
+ </question>
+
+ <answer>
+ <para>基本上,會問這種問題的人在家裡至少有兩台電腦,一台跑 FreeBSD
+ 另外一台跑 Win95;這個想法是將 FreeBSD 主機連上 Internet,然後透
+ 過這台 FreeBSD 主機,讓跑 Win95 的電腦能夠上網。這個問題算是前一
+ 個問題的一個特例</para> <para>... 答案是:可以的!在 FreeBSD 3.x
+ 版中,使用者模式(user-mode)的 &man.ppp.8; 包含了
+ <option>-nat</option> 選項。如果你在
+ <filename>/etc/rc.conf</filename> 使用<option>-nat</option>選項並
+ 設定 <literal>gateway_enable</literal> 為 <emphasis>YES</emphasis>
+ ,以這種設定啟動 &man.ppp.8; ,並且正確的設定你的 Windows 主機的
+ 話,這個做法應該是可以正常使用的。</para>
+
+ <para>關於本主題更詳細的資料可以參考 Steve Sims 所撰寫的 <ulink
+ url="../ppp-primer/index.html"> Pedantic PPP Primer</ulink> 一文。
+ </para>
+
+ <para>如果你使用的是核心模式 (kernel-mode) PPP,或者你有區域連線
+ (Ethernet connection) 可通達 Internet 的話,你將需要使用
+ &man.natd.8;。請查閱 FAQ 中關於 <link linkend="natd">natd</link>
+ 的部分。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="slip-ppp-support">
+ <para>FreeBSD 支援 SLIP 和 PPP 嗎?</para>
+ </question>
+
+ <answer>
+ <para>是的。你可以查查 man pages 中關於 &man.slattach.8;,
+ &man.sliplogin.8;,&man.ppp.8;,以及 &man.pppd.8; 的部分。
+ &man.ppp.8; 及 &man.pppd.8; 提供進出雙向連線的支援,另外
+ &man.sliplogin.8; 專門提供進入連線的支援,而 &man.slattach.8;
+ 專門提供向外連線的支援。</para>
+
+ <para>如果你需要更進一步的資料的話,請查閱 <ulink
+ url="../handbook/ppp-and-slip.html">FreeBSD 手冊中關於 PPP 與 SLIP
+ 的說明</ulink>。</para>
+
+ <para>如果你只能夠過 <quote>shell account</quote> 連線到 Internet
+ 的話,你也許可以試試 <filename role="package">net/slirp</filename>
+ 這個套件程式。這個套件程式可以提供你的電腦直接連上某些(限定的)服務
+ 連線,如 ftp 及 http 等等。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="natd">
+ <para>FreeBSD 支援 NAT 或 Masquerading 嗎?</para>
+ </question>
+
+ <answer>
+ <para>如果你有一個近端的子網路(有一台以上的機器),但是你的
+ Internet provider 卻只分配一個 IP number 給你(或者你只分配到一個
+ 動態的 IP number),你可以參考 &man.natd.8; 這個程式。 &man.natd.8;
+ 讓你可以透過這一個 IP number 讓整個子網路的電腦都能連上 internet。
+ </para>
+
+ <para>&man.ppp.8; 這個程式也提供類似的功能,如果你指定
+ <option>-nat</option> 選項。alias library (&man.libalias.3;)
+ 在這兩個處理方式中都會被使用到。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="parallel-connect">
+ <para>我如何將兩台 FreeBSD 主機用平行埠 (parallel line) 透過 PLIP
+ 連線?</para>
+ </question>
+
+ <answer>
+ <para>請參考手冊中關於 <ulink url="../handbook/plip.html">PLIP
+ section</ulink> 的部分。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="create-dev-net">
+ <para>我沒有辦法建立 <filename>/dev/ed0</filename> 這個 device,
+ 為什麼?</para>
+ </question>
+
+ <answer>
+ <para>因為不需要!在 Berkeley 網路架構中,只有 kernel 程式碼可以直
+ 接存取網路界面卡。請參考 <filename>/etc/rc.network</filename> 這
+ 個檔案和 manual pages 取得與其他不同網路程式。更進一步的資訊:如
+ 果你覺得你完全搞混了的話,您應該找一本與其他 BSD 相關作業系統網路
+ 管理有關書來參考;除了少數顯著的不同外,FreeBSD 的網路管理基本上和
+ SunOS 4.0 和 Ultrix 是一樣的。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ethernet-aliases">
+ <para>我如何建立 Ethernet aliases?</para>
+ </question>
+
+ <answer>
+ <para>如果你的 alias 位址跟你目前網路介面的位址在同一個子網路下的
+ 話,加入一個 <literal>netmask 0xffffffff</literal> 在你的
+ &man.ifconfig.8; command-line,範例如下:</para>
+ <screen>&prompt.root; <userinput>ifconfig ed0 alias 192.0.2.2 netmask 0xffffffff</userinput></screen>
+ <para>不然的話,就如同加入一個新的網路位址一樣輸入你的網路位址與子
+ 網路遮罩:</para>
+ <screen>&prompt.root; <userinput>ifconfig ed0 alias 172.16.141.5 netmask 0xffffff00</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="port-3c503">
+ <para>我如何指定我的 3C503 使用其他不同的的 network port?</para>
+ </question>
+
+ <answer>
+ <para>如果您想使用其他的 port,你必須在 &man.ifconfig.8; 的命令中
+ 指定額外的參數。內定的 port 是 <literal>link0</literal>。要使用
+ AUI port 代替 BNC port 的話,改用 <literal>link2</literal>。這些
+ flags 應該改變ifconfig_* 的變數來指定, 你可以在
+ <filename>/etc/rc.conf</filename> 這個檔案裡面找到 (請參考
+ &man.rc.conf.5;)。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="nfs">
+ <para>為什麼我在使用 FreeBSD 的 NFS 時出現問題?</para>
+ </question>
+
+ <answer>
+ <para>我們用含蓄一點的說法,某些 PC 的網路卡比其他的好,這種狀況在
+ 造成 NFS 這種對網路敏感的程式有時會出現問題。</para>
+
+ <para>參考 <ulink url="../handbook/nfs.html">
+ the Handbook entry on NFS</ulink> 以獲得這個主題的更多資訊。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="nfs-linux">
+ <para>為什麼我不能 NFS-mount Linux 的機器?</para>
+ </question>
+
+ <answer>
+ <para>某些版本的 Linux NFS 程式碼只接受 privileged port 的
+ mount request;試用這行指令看看</para>
+
+ <screen>&prompt.root; <userinput>mount -o -P linuxbox:/blah /mnt</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="nfs-sun">
+ <para>為什麼我不能 NFS-mount Sun 的機器?</para>
+ </question>
+
+ <answer>
+ <para>跑 SunOS 4.X 的 Sun 工作站只接受來自 privileged port 的
+ mount request;試用這行指令看看</para>
+
+ <screen>&prompt.root; <userinput>mount -o -P sunbox:/blah /mnt</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="exports-errors">
+ <para>為什麼 <command>mountd</command> 一直鬼叫說
+ <errorname>can't change attributes</errorname> 而且我一直看到
+ <errorname>bad exports list</errorname> 這個訊息在我的 FreeBSD NFS
+ 伺服器上?</para>
+ </question>
+
+ <answer>
+ <para>這個問題最常發生的原因是在於不了解
+ <filename>/etc/exports</filename> 的正確格式。請詳讀
+ &man.exports.5; 以及手冊中關於 <ulink
+ url="../handbook/nfs.html">NFS</ulink> 的部分,特別是<ulink
+ url="../handbook/nfs.html#CONFIGURING-NFS">configuring
+ NFS</ulink>這一段。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-nextstep">
+ <para>為什麼我在使用 PPP 連線到 NeXTStep 機器時有問題?</para>
+ </question>
+
+ <answer>
+
+ <para>把 TCP extensions 取消,這個設定在
+ <filename>/etc/rc.conf</filename> 裡面(參考 &man.rc.conf.5;) 把
+ 以下這個值設成 NO:</para>
+
+ <programlisting>tcp_extensions=NO</programlisting>
+
+ <para>Xylogic 的 Annex 主機也有相同的問題,您要做相同的修改才能連
+ 上這些主機。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ip-multicast">
+ <para>我要怎樣才能把 IP multicast support 打開?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 2.0 以後的版本內定都有 支援 Multicast host 操作。如果
+ 您想將您的主機設定成 multicast router 的話,您必須重新 compile 您
+ 的 kernel,加入 <literal>MROUTING</literal> 的選項,並且執行
+ &man.mrouted.8; FreeBSD 2.2 及之後的版本會在開機時執行
+ &man.mrouted.8; 如果在 <filename>/etc/rc.conf</filename> 中
+ <literal>mrouted_enable</literal> 設定為 <literal>"YES"</literal>
+ </para>
+
+ <para>MBONE 的各種工具可以在他們 ports 下所屬叫做 <ulink
+ url="http://www.FreeBSD.org/ports/mbone.html">mbone</ulink> 目錄
+ 中找到。如果您在找視訊會議的工具如 <command>vic</command> 以及
+ <command>vat</command>的話,到那邊找找吧!</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="dec-pci-chipset">
+ <para>哪些網路卡是使用 DEC PCI chipset?</para>
+ </question><answer>
+
+ <para>以下是 Glen Foster <email>gfoster@driver.nsta.org</email>
+ 提供的清單:</para>
+
+ <table>
+ <title>Network cards based on the DEC PCI chipset</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Vendor</entry>
+ <entry>Model</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>ASUS</entry>
+ <entry>PCI-L101-TB</entry>
+ </row>
+ <row>
+ <entry>Accton</entry>
+ <entry>ENI1203</entry>
+ </row>
+ <row>
+ <entry>Cogent</entry>
+ <entry>EM960PCI</entry>
+ </row>
+ <row>
+ <entry>Compex</entry>
+ <entry>ENET32-PCI</entry>
+ </row>
+ <row>
+ <entry>D-Link</entry>
+ <entry>DE-530</entry>
+ </row>
+ <row>
+ <entry>Dayna</entry>
+ <entry>DP1203, DP2100</entry>
+ </row>
+ <row>
+ <entry>DEC</entry>
+ <entry>DE435, DE450</entry>
+ </row>
+ <row>
+ <entry>Danpex</entry>
+ <entry>EN-9400P3</entry>
+ </row>
+ <row>
+ <entry>JCIS</entry>
+ <entry>Condor JC1260</entry>
+ </row>
+ <row>
+ <entry>Linksys</entry>
+ <entry>EtherPCI</entry>
+ </row>
+ <row>
+ <entry>Mylex</entry>
+ <entry>LNP101</entry>
+ </row>
+ <row>
+ <entry>SMC</entry>
+ <entry>EtherPower 10/100 (Model 9332)</entry>
+ </row>
+ <row>
+ <entry>SMC</entry>
+ <entry>EtherPower (Model 8432)</entry>
+ </row>
+ <row>
+ <entry>TopWare</entry>
+ <entry>TE-3500P</entry>
+ </row>
+ <row>
+ <entry>Znyx (2.2.x)</entry>
+ <entry>ZX312, ZX314, ZX342, ZX345, ZX346, ZX348</entry>
+ </row>
+ <row>
+ <entry>Znyx (3.x)</entry>
+ <entry>ZX345Q, ZX346Q, ZX348Q, ZX412Q, ZX414, ZX442, ZX444,
+ ZX474, ZX478, ZX212, ZX214 (10mbps/hd)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="fqdn-hosts">
+ <para>為什麼要用 FQDN 才能連到其他機器?</para>
+ </question>
+
+ <answer>
+ <para>你也許會發現要連的機器其實是在另一個網域。舉個例子,假設你是在
+ foo.bar.edu 這個網域中,想要連到在一台叫 <hostid>mumble</hostid>
+ 的主機,他在 <hostid role="domainname">example.org</hostid> 網域下,
+ 你必須用 Fully-Qualified Domain Name <hostid
+ role="fqdn">mumble.example.org</hostid>,而不是只用
+ <hostid>mumble</hostid>。</para>
+
+ <para>傳統的 BSD BIND resolver 允許用這種方式解出機器的位址,但是
+ FreeBSD 內附 <application>bind</application> (see &man.named.8;)
+ 版本內定方式,則是除了你所在的網域以外,不支援其他非 FQDN 的縮寫。
+ 所以如 <hostid>mumble</hostid> 必須在 <hostid
+ role="fqdn">mumble.foo.example.org</hostid>,否則就會從網域的最底
+ 層開始找。</para>
+
+ <para>這和先前的做法不同,也就是不用
+ <hostid role="domainname">mumble.example.org</hostid>,和
+ <hostid role="domainname">mumble.edu</hostid> 繼續搜尋。
+ 看一下 RFC 1535,裡面有提到為什麼之前的做法不好,甚至算是個安全
+ 漏洞。</para>
+
+ <para>這裡有個不錯的解法, 你可以加入一行</para>
+
+ <programlisting>search foo.example.org example.org</programlisting>
+
+ <para>instead of the previous</para>
+
+ <programlisting>domain foo.example.org</programlisting>
+
+ <para>在你的 <filename>/etc/resolv.conf</filename> 檔案中 (請參考
+ &man.resolv.conf.5;)。但是要確定搜尋順序不會違反 RFC 1535 所謂的
+ <quote>boundary between local and public administration</quote>。
+ </para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="network-permission-denied">
+ <para>為什麼我在連線時一直出現
+ <errorname>Permission denied</errorname> 的錯誤訊息?</para>
+ </question>
+
+ <answer>
+ <para> 如果在編譯 kernel 時加入 <literal>IPFIREWALL</literal> 選項,
+ 請注意 2.1.7R 內定是拒絕所有未經核准的網路封包(但在開發
+ 2.1-STABLE 時改掉了)。</para>
+
+ <para>I如果不小心弄錯了 firewall 的設定,你可以以
+ <username>root</username> 執行以下命令網路功能就會恢復正常:</para>
+
+ <screen>&prompt.root; <userinput>ipfw add 65534 allow all from any to any</userinput></screen>
+
+ <para>也可以在 <filename>/etc/rc.conf</filename> 加入
+ <literal>firewall_type="open"</literal> 的選項。</para>
+
+ <para>如果想知道如何設定 FreeBSD firewall,請參考 <ulink
+ url="../handbook/firewalls.html">手冊中相關章節</ulink>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ipfw-overhead">
+ <para>IPFW 會造成多大的網路延遲?</para>
+ </question>
+
+ <answer>
+ <para>請參考手冊中 <ulink
+ url="../handbook/firewalls.html">Firewalls</ulink> 章節,特別是
+ <ulink url="../handbook/firewalls.html#IPFW-OVERHEAD">IPFW
+ Overhead & Optimization</ulink> 這一段。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ipfw-fwd">
+ <para>為什麼我的 <command>ipfw</command> <quote>fwd</quote>
+ redirect 規則將服務轉向其他機器時無法正常運作?</para>
+ </question>
+
+ <answer>
+ <para>可能是你除了轉送封包以外還額外想進行位址轉譯
+ (network address translation, NAT),<quote>fwd</quote> 規則所進
+ 行的動作就如同字面所示;僅轉送封包,它並不會去修改封包中的資料。
+ 假設我們有如下的規則:</para>
+
+ <screen>01000 fwd <replaceable>10.0.0.1</replaceable> from any to <replaceable>foo 21</replaceable></screen>
+
+ <para>當一個通往特定目標位址 <replaceable>foo</replaceable> 的封包
+ 送達主機時,根據這條規則,封包將被轉送至
+ <replaceable>10.0.0.1</replaceable>,但是它的目標位址卻仍然是
+ <replaceable>foo</replaceable>!封包的目標位址並
+ <emphasis>沒有</emphasis> 更改為
+ <replaceable>10.0.0.1</replaceable>。大部分的主機會將封包丟棄,
+ 因為他們並不是這個目標位址。因此,使用 <quote>fwd</quote> 規則
+ 時往往不如使用者所預期的那般順利。這種行為是系統特性,而非錯誤。
+ </para>
+
+ <para>參考 <link linkend="service-redirect">關於服務轉向的常見問
+ 答集</link>, &man.natd.8; 手冊,或者是使用 <ulink
+ url="../../../../ports/index.html">ports collection</ulink> 中許
+ 多服務轉向的工具來正確的完成你想進行的工作。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="service-redirect">
+ <para>要如何把對某台機器的網路服務要求(service request)轉向到另一台?
+ </para>
+ </question>
+
+ <answer>
+ <para>在 ports 目錄的<quote>sysutils</quote>分類中有個叫
+ <literal>socket</literal> 的套件,可以幫你轉向 FTP 或其他類似的
+ 網路服務。只要把該網路服務的命令改成呼叫 socket 即可,如下所示:
+ </para>
+
+ <programlisting>ftp stream tcp nowait nobody /usr/local/bin/socket socket <replaceable>ftp.example.com</replaceable> <replaceable>ftp</replaceable></programlisting>
+
+ <para>其中 <replaceable>ftp.example.com</replaceable> 與
+ <replaceable>ftp</replaceable> 分別是被轉到的機器和 port 名稱。
+ </para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="bandwidth-mgr-tool">
+ <para>那裡可以找到管理頻寬的工具?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 上有三套頻寬管理工具: &man.dummynet.4; 已經整合進入
+ FreeBSD 系統(更詳細的用途, &man.ipfw.4;); <ulink
+ url="http://www.csl.sony.co.jp/person/kjc/programs.html">ALTQ</ulink>
+ 可以免費使用,<ulink
+ url="http://www.etinc.com/">Emerging Technologies</ulink>
+ 推出的 Bandwidth Manager 則是商用軟體。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="bpf-not-configured">
+ <para>怎麼會跑出
+ <errorname>/dev/bpf0: device not configured</errorname>這個訊息?
+ </para>
+ </question>
+
+ <answer>
+ <para>你執行了一個需要柏克萊封包過濾器 (Berkeley Packet Filter) 的
+ 程式 (&man.bpf.4;),但是你在 kernel 中沒有啟動它。把下面這一行加
+ 入 kernel 設定檔中,編譯一個新的 kernel:</para>
+
+ <programlisting>pseudo-device bpf # Berkeley Packet Filter</programlisting>
+
+ <para>在重新開機之後,還要做出 device node,在
+ <filename>/dev</filename> 下執行:</para>
+
+ <screen>&prompt.root; <userinput>sh MAKEDEV bpf0</userinput></screen>
+
+ <para>如果想要更進一步知道如何做出各種 device node,請參閱 <ulink
+ url="../handbook/kernelconfig-nodes.html">Handbook 關於週邊節點的說明</ulink>
+ 。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="mount-smb-share">
+ <para>我要怎樣才能將 Windows 機器中的磁碟掛入系統, 就像 Linux 提供
+ 的 smbmount 那樣?</para>
+ </question>
+
+ <answer>
+ <para>使用 <application>SMBFS</application> 工具組。這套工具組中
+ 包含了一系列的 kernel 修改還有使用者的工具程式(userland programs)。
+ 這些程式和資訊在 ports 收藏中
+ <filename role="package">net/smbfs</filename> 下可以找到。在
+ 4.5-RELEASE 之後的版本則是系統中內建。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="icmp-response-bw-limit">
+ <para>我在系統日誌中發現以下訊息:
+ <quote>icmp-response bandwidth limit 300/200 pps</quote>,這是
+ 蝦米碗糕?</para>
+ </question>
+
+ <answer>
+ <para>這是系統核心告訴你有某些活動引發它送出比它所認為應該送出更
+ 多的 ICMP 或 TCP 重置訊息 (RST)。ICMP 回應訊息常常是因為有人嘗
+ 試連接未被使用的 UDP 通訊埠。TCP 重置訊息則是有人嘗試連接未開
+ 放 TCP 通訊埠造成的結果。以下這些活動可能就是造成這些訊息的原因:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>暴力法的服務組絕攻擊(DoS)方式
+ (相較於針對特殊弱點使用單一封包的攻擊方式)。</para>
+ </listitem>
+
+ <listitem>
+ <para>大量的通訊埠掃描(相較於僅嘗試少數的常見服務通訊埠)。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>出現的數字中第一個代表根據這些流量 kernel 應該送出的封包數,
+ 第二個數字則是 kernel 目前限制最大發送數。你可以利用 sysctl 修改
+ <varname>net.inet.icmp.icmplim</varname> 變數值來更改最大值。舉
+ 例來說,如果希望修改限制為 <literal>300</literal> packets per
+ second:</para>
+
+ <screen>&prompt.root; <userinput>sysctl -w net.inet.icmp.icmplim=300</userinput></screen>
+
+ <para>如果你不想在系統紀錄中看到這些訊息,但是仍然希望保持回應的限
+ 制的話,你可以利用 sysctl 修改
+ <varname>net.inet.icmp.icmplim_output</varname> 變數來取消這些訊
+ 息:</para>
+
+ <screen>&prompt.root; <userinput>sysctl -w net.inet.icmp.icmplim_output=0</userinput></screen>
+
+ <para>最後,如果你想取消這些限制的話,你可以設定
+ <varname>net.inet.icmp.icmplim</varname> (如上例所示) 為
+ <literal>0</literal>。基於上述理由,我們不建議你取消這些限制。
+ </para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="unknown-hw-addr-format">
+ <para>這個錯誤訊息
+ <errorname>arp: unknown hardware address format</errorname>
+ 是什麼意思?</para>
+ </question>
+
+ <answer>
+ <para>這代表你的區域網路連線上有一些設備使用 FreeBSD 看不懂的 MAC
+ 格式。這通常是代表有人在你的區域網路上進行實驗,最常見的就是
+ cable modem 的連線。這訊息無害,而且應該不至於影響到 FreeBSD 主
+ 機的效能。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="cvsup-missing-libs">
+ <para>我剛剛裝好 CVSup 套件,但是在嘗試執行時發生了錯誤,要怎麼辦?
+ </para>
+ </question>
+
+ <answer>
+ <para>首先,看看錯誤的訊息是否如下:</para>
+
+ <programlisting>/usr/libexec/ld-elf.so.1: Shared object "libXaw.so.6" not found</programlisting>
+
+ <para>這種錯誤訊息代表你主機上安裝的
+ <filename role="package">net/cvsup</filename> 沒有包含
+ <application>XFree86</application> 套件。如果你想要使用
+ <application>CVSup</application> 內建的圖形介面
+ <acronym>GUI</acronym> 的話,你需要安裝
+ <application>XFree86</application>。此外,如果你只想以命令列方
+ 式使用 <application>CVSup</application> 的話,你應該先移除之前
+ 安裝的套件。並安裝
+ <filename role="package">net/cvsup-without-gui</filename> 這套
+ 軟體。在 FreeBSD 手冊中 <ulink
+ url="http://www.freebsd.org/handbook/cvsup.html">CVSup</ulink>
+ 段落中有更詳細的說明。</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+ <chapter id="security">
+ <chapterinfo>
+ <author>
+ <firstname>Biing Jong</firstname>
+ <surname>Lin</surname>
+ <affiliation>
+ <address><email>bjlin@stic.gov.tw</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>系統安全篇</title>
+ <qandaset>
+ <qandaentry>
+ <question id="sandbox">
+ <para>什麼是 sandbox?</para>
+ </question><answer>
+
+ <para><quote>Sandbox</quote> 是系統安全用的術語,有兩個意義:</para>
+
+ <itemizedlist>
+ <listitem>
+
+ <para>放在某些虛擬防護牆裡的執行程序,這些防護牆是用來阻止
+ 某些人侵入這道程序,進而出入於更大的系統中。</para>
+
+ <para>這道程序可以完全在防護牆裡 <quote>動作</quote>。也就
+ 是說,它所執行的任何程式不可能會滲透到牆的外面。所以如果
+ 您對它有安全上的顧慮,並不需要特別去監聽它的一舉一動,反
+ 正它只能在牆內活動。</para>
+
+ <para>舉例來說,可以用 userid 來做這道防護牆,這正是 security
+ 和 named 說明文件中的定義。</para>
+
+ <para>現在就用 <literal>ntalk</literal> 這個服務作說明(見
+ /etc/inetd.conf)。這個服務以前的 userid 是
+ <username>root</username>,現在執行時則是用
+ <username>tty</username>。<username>tty</username>
+ 這個使用者就是一個 sandbox,如果有人能夠順利用 ntalk
+ 侵入系統,現在他就算進得來也只能用這個 userid。</para>
+ </listitem>
+
+ <listitem>
+ <para>放在某個模擬機器裡的程式,這比上述來得更嚴密。基本上
+ 這表示能侵入該程式的人相信他能再進入所屬的機器,但事實上
+ 只會進入模擬出來的機器,無法進一步修改任何真實的資料。</para>
+
+ <para>達到這個目的最常用的方法,就是在某個子目錄下做出模擬的
+ 環境,然後用 chroot 執行該程式,這樣該程式的根目錄便是這個
+ 子目錄,而非系統真正的根目錄。</para>
+
+ <para>另一個常見作法是將某個檔案系統 mount 成唯讀,但在它
+ 上面另外製造出程式以為可以寫入的檔案系統。這個程式會相信
+ 它可以對其他檔案讀寫,但只有它看不到這個唯讀效應 - 系統
+ 執行的一般程式都看得到。</para>
+
+ <para>我們試圖將這類 sandbox 盡量透明化,讓使用者或侵入者
+ 無法看到他是否在某個 sandbox 裡面。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>UNIX 實作兩種 sandbox,一個在程式層面,另一個則是由 userid
+ 來達成。</para>
+
+ <para>每個 UNIX 執行程序會用防火牆將它和所有其他程序隔開,某個程序
+ 不可以隨意修改其他程序位址的資料。這和 Windows 中,程式可以輕易
+ 修改其他位址資料,結果導致當機的情形大不相同。</para>
+
+ <para>每個 UNIX 程序都屬於某個特定的 userid。如果該 userid 不是
+ <username>root</username>,就會將它和其他使用者的程序隔開。
+ Userid 同時也用於硬碟資料的存取權上。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="securelevel">
+ <para>什麼是 securelevel?</para>
+ </question>
+
+ <answer>
+ <para>securelevel 是核心中所實作的一個安全機制。基本上當
+ securelevel 是正值時,核心會限制某些工作;即使是 superuser
+ (也就是 <username>root</username>) 也無法完成那些工作。在撰寫
+ 本文時,securelevel 機制在一般的限制外,還能夠限制以下的功能:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>清除某些特定的檔案旗標,例如 <literal>schg</literal>
+ (系統唯讀標旗, the system immutable flag)</para>
+ </listitem>
+
+ <listitem>
+ <para>經由 <devicename>/dev/mem</devicename> 與
+ <devicename>/dev/kmem</devicename>, 將資料寫入至核心記憶體中
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>載入核心模組</para>
+ </listitem>
+
+ <listitem>
+ <para>更動 &man.ipfirewall.4; 規則。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>想要檢查在某個運作中的系統的 securelevel 狀態,只要執行以下
+ 命令即可:</para>
+
+ <screen>&prompt.root; <userinput>sysctl kern.securelevel</userinput></screen>
+
+ <para>輸出的結果會包含一個 &man.sysctl.8; 變數名稱 (在這個例子中,
+ 它是 <varname>kern.securelevel</varname>) 以及一個數字。後者即是
+ 目前的 securelevel 值。如果它是一個正值 (也就是大於 0),表示至少
+ 有一些 securelevel 的保護機制已經開啟了。</para>
+
+ <para>你沒有辦法降低一個運作中的系統的 securelevel;如果可以的話,
+ 就失去了這個機制的意義了。如果你要作一些需要 securelevel 為
+ 非正值才可以的動作的話 (例如 <maketarget>installworld</maketarget>
+ 或更動日期),你需要修改 <filename>/etc/rc.conf</filename> 內的
+ securelevel 設定 (找找 <varname>kern_securelevel</varname> 和
+ <varname>kern_securelevel_enable</varname> 變數),然後重新開機。
+ </para>
+
+ <para>想要知道更多有關於 securelevel 與各個不同等級影響的細節,
+ 請參考 &man.init.8; 說明文件。</para>
+
+ <warning>
+ <para>securelevel 可不是萬靈丹;它有許多已知的缺陷,往往造成
+ 一種安全的假象。</para>
+
+ <para>它一個最大的問題,就是要讓這個功能完全有效的話,在
+ securelevel 發揮作用前的啟動過程中,所有使用到的檔案都
+ 必須被保護起來。如果一個攻擊者在 securelevel 有效前 (由於
+ 有些系統在啟動中所作的事情,無法在較高的 securelevel 中
+ 正常運作,所以這會在啟動過程中後期才會運作),能讓他們的程式
+ 被執行的話,securelevel 的保護就完全無效了。保護啟動程序
+ 中所有的檔案在技術上是可行的,但是如果真的這樣作的話,系統
+ 維護將會變成一場夢魘。即使只是修改一個設定檔,也必須將整個
+ 系統關閉,至少也得到單人模式。</para>
+
+ <para>除了這點,還有許多其它的東西都在通信論壇上討論,尤其是
+ freebsd-security。請到 <ulink
+ url="../../../../search/index.html">這裡</ulink> 搜尋以前的
+ 討論。有些人希望 securelevel 能夠儘快消失,由另一個更優秀的
+ 機制取代,不過機會有點渺茫。</para>
+
+ <para>風險自行承擔。</para>
+ </warning>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="extra-named-port">
+ <para>BIND (<command>named</command>) 除了在通訊埠 53 以外也在
+ 其他高編號通訊埠 (high-numbered port) 聆聽 (Listen)。
+ 這是怎麼回事?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 3.0 後的版本使用一個特殊的 BIND 版本,這個版本會使
+ 用隨機的高編號通訊埠來回應外部的查詢。如果你因為要適合防火牆的
+ 設定或是單純的想讓自己看來舒服一點而想用 53 通訊埠回應外部查詢,
+ 那麼你可以嘗試更改以下檔案相關內容
+ <filename>/etc/namedb/named.conf</filename>:</para>
+
+ <programlisting>options {
+ query-source address * port 53;
+};</programlisting>
+
+ <para>你也可以將 <literal>*</literal> 更改為特定 IP address,
+ 藉以加強控制條件。</para>
+
+ <para>順便恭喜你。能夠讀取你系統上的 &man.sockstat.1; 報告並且注意
+ 不正常狀況是一件好事!</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="sendmail-port-587">
+ <para>Sendmail 除了在標準的通訊埠 25 外也在通訊埠 587 聆聽!這是怎
+ 麼回事?</para>
+ </question>
+
+ <answer>
+ <para>較新版本的 Sendmail 支援 mail submission 這項功能,並且使
+ 用通訊埠 587。這項功能還沒有被廣泛支援但是支援的數目正在增長
+ 中。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="toor-account">
+ <para>我發現了這個 UID 0 <username>toor</username> 帳號,這是什麼
+ 碗糕?我被黑掉了嗎?</para>
+ </question>
+
+ <answer>
+ <para>放心。<username>toor</username> 是一個
+ <quote>alternative</quote> 管理者帳號 (toor 是 root 的轉向拼法)。
+ 以往是跟隨 &man.bash.1; 安裝而建制的,後來則成為系統內定建制的一
+ 個帳號。這個帳號將伴隨一個非標準的 shell 測試使用, 讓你不需要去
+ 更改到 <username>root</username> 的內建 shell。因為這些其他的 shell
+ 並沒有跟隨系統預設值安裝 (舉例來說,某些由 ports 安裝的
+ shell package),而被內定安裝在 <filename>/usr/local/bin</filename>
+ 目錄下,有可能存在不同的檔案系統中。 倘若 <username>root</username>
+ 的 shell 被放在 <filename>/usr/local/bin</filename>,且
+ <filename>/usr</filename> (或是其他包含著
+ <filename>/usr/local/bin</filename> 這個子目錄的檔案系統)
+ 因為某些原因並沒有被正常的 mount 起來的話,<username>root</username>
+ 將無法正常的登入系統進行維修 (雖然說你重開機成單人模式就會問你要
+ 載入哪個 shell)。</para>
+
+ <para>有些人使用 <username>toor</username> 帳號進行每日的
+ <username>root</username> 維護工作,如此可以使用非標準的
+ shell,而 <username>root</username> 可以保留標準 shell,
+ 以因應單一使用者模式 (single user mode) 或緊急狀況處理。
+ 依照系統內定值,你將無法使用 <username>toor</username> 登入,
+ 因為這個帳號尚未更改密碼設定。因此你如果你想啟動這個帳號,你需要
+ 使用 <username>root</username> 登入系統並且修改
+ <username>toor</username> 的密碼。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="suidperl">
+ <para>為什麼 <command>suidperl</command> 無法正常運作?</para>
+ </question>
+
+ <answer>
+ <para>因為某些安全的考,<command>suidperl</command> 內定的安裝
+ 並沒有設定 suid bit。系統管理者可以依照以下命令啟動 suid 設定。
+ </para>
+
+ <screen>&prompt.root; <userinput>chmod u+s /usr/bin/suidperl</userinput></screen>
+
+ <para>如果你想要在由 source 升級時 <command>suidperl</command> 內定
+ 啟動 suid 功能的話,編輯 <filename>/etc/make.conf</filename> 加入
+ <varname>ENABLE_SUIDPERL=true</varname> 然後執行
+ <command>make buildworld</command>。</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+ <chapter id="ppp">
+ <title>PPP</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="userppp">
+ <para>I cannot make &man.ppp.8; work. What am I doing wrong?</para>
+ </question>
+
+ <answer>
+ <para>You should first read the
+ &man.ppp.8;
+ man page and the <ulink
+ url="../handbook/ppp-and-slip.html#USERPPP">
+ PPP section of the handbook</ulink>. Enable logging with
+ the command</para>
+
+ <programlisting>set log Phase Chat Connect Carrier lcp ipcp ccp command</programlisting>
+
+ <para>This command may be typed at the
+ &man.ppp.8; command prompt or it may be
+ entered in the <filename>/etc/ppp/ppp.conf</filename>
+ configuration file (the start of the
+ <literal>default</literal> section is the best
+ place to put it). Make sure that
+ <filename>/etc/syslog.conf</filename> (see &man.syslog.conf.5;) contains the lines</para>
+
+ <programlisting>!ppp
+*.* /var/log/ppp.log</programlisting>
+
+ <para>and that the file <filename>/var/log/ppp.log</filename>
+ exists. You can now find out a lot about what is going on
+ from the log file. Do not worry if it does not all make sense.
+ If you need to get help from someone, it may make sense to
+ them.</para>
+
+ <para>If your version of &man.ppp.8; does not understand the
+ <command>set log</command> command, you should download the
+ <ulink url="http://people.FreeBSD.org/~brian/">
+ latest version</ulink>. It will build on FreeBSD version
+ 2.1.5 and higher.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-hangs">
+ <para>Why does &man.ppp.8; hang when I run it?</para>
+ </question>
+
+ <answer>
+ <para>This is usually because your hostname will not resolve.
+ The best way to fix this is to make sure that
+ <filename>/etc/hosts</filename> is consulted by your
+ resolver first by editing <filename>/etc/host.conf</filename>
+ and putting the <literal>hosts</literal> line first. Then,
+ simply put an entry in <filename>/etc/hosts</filename> for
+ your local machine. If you have no local network, change your
+ <hostid>localhost</hostid> line:</para>
+
+ <programlisting>127.0.0.1 foo.bar.com foo localhost</programlisting>
+
+ <para>Otherwise, simply add another entry for your host.
+ Consult the relevant man pages for more details.</para>
+
+ <para>You should be able to successfully
+ <command>ping -c1 `hostname`</command> when you are done.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-nodial-auto">
+ <para>Why will &man.ppp.8; not dial in <literal>-auto</literal>
+ mode?</para>
+ </question>
+
+ <answer>
+ <para>First, check that you have got a default route. By running
+ <command>netstat -rn</command> (see &man.netstat.1;), you should see two entries like this:</para>
+
+ <programlisting>Destination Gateway Flags Refs Use Netif Expire
+default 10.0.0.2 UGSc 0 0 tun0
+10.0.0.2 10.0.0.1 UH 0 0 tun0</programlisting>
+
+ <para>This is assuming that you have used the addresses from the
+ handbook, the man page or from the ppp.conf.sample file.
+ If you do not have a default route, it may be because you are
+ running an old version of &man.ppp.8;
+ that does not understand the word <literal>HISADDR</literal>
+ in the ppp.conf file. If your version of
+ &man.ppp.8; is from before FreeBSD
+ 2.2.5, change the</para>
+
+ <programlisting>add 0 0 HISADDR</programlisting>
+
+ <para>line to one saying</para>
+
+
+ <programlisting>add 0 0 10.0.0.2</programlisting>
+
+ <para>Another reason for the default route line being missing
+ is that you have mistakenly set up a default router in your
+ <filename>/etc/rc.conf</filename> (see &man.rc.conf.5;) file (this file was called
+ <filename>/etc/sysconfig</filename> prior to release 2.2.2),
+ and you have omitted the line saying</para>
+
+ <programlisting>delete ALL</programlisting>
+
+ <para>from <filename>ppp.conf</filename>. If this is the case,
+ go back to the <ulink
+ url="../handbook/ppp-and-slip.html#USERPPP-FINAL">
+ Final system configuration</ulink> section of the
+ handbook.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="no-route-to-host">
+ <para>What does <errorname>No route to host</errorname> mean?</para>
+ </question>
+
+ <answer>
+ <para>This error is usually due to a missing</para>
+
+ <programlisting>MYADDR:
+ delete ALL
+ add 0 0 HISADDR</programlisting>
+
+ <para>section in your <filename>/etc/ppp/ppp.linkup</filename>
+ file. This is only necessary if you have a dynamic IP address
+ or do not know the address of your gateway. If you are using
+ interactive mode, you can type the following after entering
+ <literal>packet mode</literal> (packet mode is
+ indicated by the capitalized <acronym>PPP</acronym> in the
+ prompt):</para>
+
+ <programlisting>delete ALL
+add 0 0 HISADDR</programlisting>
+
+ <para>Refer to the <ulink
+ url="../handbook/ppp-and-slip.html#USERPPP-DYNAMICIP">
+ PPP and Dynamic IP addresses</ulink> section of the handbook
+ for further details.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="connection-threeminutedrop">
+ <para>Why does my connection drop after about 3 minutes?</para>
+ </question>
+
+ <answer>
+ <para>The default PPP timeout is 3 minutes. This can be
+ adjusted with the line</para>
+
+ <programlisting>set timeout <replaceable>NNN</replaceable></programlisting>
+
+ <para>where <replaceable>NNN</replaceable> is the number of
+ seconds of inactivity before the connection is closed. If
+ <replaceable>NNN</replaceable> is zero, the connection is never
+ closed due to a timeout. It is possible to put this command in
+ the <filename>ppp.conf</filename> file, or to type it at the
+ prompt in interactive mode. It is also possible to adjust it on
+ the fly while the line is active by connecting to
+ <application>ppp</application>s server socket using
+ &man.telnet.1; or &man.pppctl.8;.
+ Refer to the
+ &man.ppp.8; man
+ page for further details.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-drop-heavy-load">
+ <para>Why does my connection drop under heavy load?</para>
+ </question>
+
+ <answer>
+ <para>If you have Link Quality Reporting (LQR) configured,
+ it is possible that too many LQR packets are lost between
+ your machine and the peer. Ppp deduces that the line must
+ therefore be bad, and disconnects. Prior to FreeBSD version
+ 2.2.5, LQR was enabled by default. It is now disabled by
+ default. LQR can be disabled with the line</para>
+
+ <programlisting>disable lqr</programlisting>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-drop-random">
+ <para>Why does my connection drop after a random amount of
+ time?</para>
+ </question>
+
+ <answer>
+ <para>Sometimes, on a noisy phone line or even on a line with
+ call waiting enabled, your modem may hang up because it
+ thinks (incorrectly) that it lost carrier.</para>
+
+ <para>There is a setting on most modems for determining how
+ tolerant it should be to temporary losses of carrier. On a
+ USR Sportster for example, this is measured by the S10
+ register in tenths of a second. To make your modem more
+ forgiving, you could add the following send-expect sequence
+ to your dial string:</para>
+
+ <programlisting>set dial "...... ATS10=10 OK ......"</programlisting>
+
+ <para>Refer to your modem manual for details.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-hangs-random">
+ <para>Why does my connection hang after a random amount of
+ time?</para>
+ </question><answer>
+
+ <para>Many people experience hung connections with no apparent
+ explanation. The first thing to establish is which side of
+ the link is hung.</para>
+
+ <para>If you are using an external modem, you can simply try
+ using &man.ping.8; to see if the
+ <acronym>TD</acronym> light is flashing when you transmit data.
+ If it flashes (and the <acronym>RD</acronym> light does not),
+ the problem is with the remote end. If <acronym>TD</acronym>
+ does not flash, the problem is local. With an internal modem,
+ you will need to use the <literal>set server</literal> command in
+ your <filename>ppp.conf</filename> file. When the hang occurs,
+ connect to &man.ppp.8; using &man.pppctl.8;. If your network connection
+ suddenly revives (PPP was revived due to the activity on the
+ diagnostic socket) or if you cannot connect (assuming the
+ <literal>set socket</literal> command succeeded at startup
+ time), the problem is local. If you can connect and things are
+ still hung, enable local async logging with <literal>set log
+ local async</literal> and use &man.ping.8; from
+ another window or terminal to make use of the link. The async
+ logging will show you the data being transmitted and received
+ on the link. If data is going out and not coming back, the
+ problem is remote.</para>
+
+ <para>Having established whether the problem is local or remote,
+ you now have two possibilities:</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-remote-not-responding">
+ <para>The remote end is not responding. What can I do?</para>
+ </question>
+
+ <answer>
+ <para>There is very little you can do about this. Most ISPs
+ will refuse to help if you are not running a Microsoft OS.
+ You can <literal>enable lqr</literal> in your
+ <filename>ppp.conf</filename> file, allowing &man.ppp.8; to detect
+ the remote failure and hang up, but this detection is
+ relatively slow and therefore not that useful. You may want to
+ avoid telling your ISP that you are running user-PPP...</para>
+
+ <para>First, try disabling all local compression by adding the
+ following to your configuration:</para>
+
+ <programlisting>disable pred1 deflate deflate24 protocomp acfcomp shortseq vj
+deny pred1 deflate deflate24 protocomp acfcomp shortseq vj</programlisting>
+
+ <para>Then reconnect to ensure that this makes no difference.
+ If things improve or if the problem is solved completely,
+ determine which setting makes the difference through trial
+ and error. This will provide good ammunition when you contact
+ your ISP (although it may make it apparent that you are not
+ running a Microsoft product).</para>
+
+ <para>Before contacting your ISP, enable async logging locally
+ and wait until the connection hangs again. This may use up
+ quite a bit of disk space. The last data read from the port
+ may be of interest. It is usually ascii data, and may even
+ describe the problem
+ (<quote>Memory fault, core dumped</quote>?).</para>
+
+ <para>If your ISP is helpful, they should be able to enable
+ logging on their end, then when the next link drop occurs,
+ they may be able to tell you why their side is having a
+ problem. Feel free to send the details to &a.brian;, or
+ even to ask your ISP to contact me directly.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-hung">
+ <para>&man.ppp.8; has hung. What can I do?</para>
+ </question>
+
+ <answer>
+ <para>Your best bet here is to rebuild &man.ppp.8; by adding
+ <literal>CFLAGS+=-g</literal> and <literal>STRIP=</literal>
+ to the end of the Makefile, then doing a
+ <command>make clean &amp;&amp; make &amp;&amp; make
+ install</command>. When &man.ppp.8; hangs, find the &man.ppp.8; process id
+ with <command>ps ajxww | fgrep ppp</command> and run
+ <command>gdb ppp <replaceable>PID</replaceable></command>.
+ From the gdb prompt, you can then use <command>bt</command>
+ to get a stack trace.</para>
+
+ <para>Send the results to <email>brian@Awfulhak.org</email>.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-loginok-thennothing">
+ <para>Why does nothing happen after the <quote>Login OK!</quote>
+ message?</para>
+ </question>
+
+ <answer>
+ <para>Prior to FreeBSD version 2.2.5, once the link was
+ established, &man.ppp.8;
+ would wait for the peer to initiate the Line Control Protocol
+ (LCP). Many ISPs will not initiate negotiations and expect
+ the client to do so. To force
+ &man.ppp.8; to initiate the LCP, use the
+ following line:</para>
+
+ <programlisting>set openmode active</programlisting>
+
+ <note>
+ <para>It usually does no
+ harm if both sides initiate negotiation, so openmode is now
+ active by default. However, the next section explains when
+ it <emphasis>does</emphasis> do some harm.</para>
+ </note>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-same-magic">
+ <para>I keep seeing errors about magic being the same. What does
+ it mean?</para>
+ </question>
+
+ <answer>
+ <para>Occasionally, just after connecting, you may see messages
+ in the log that say <quote>magic is the same</quote>.
+ Sometimes, these messages are harmless, and sometimes one side
+ or the other exits. Most PPP implementations cannot survive
+ this problem, and even if the link seems to come up, you will see
+ repeated configure requests and configure acknowledgments in
+ the log file until &man.ppp.8; eventually gives up and closes the
+ connection.</para>
+
+ <para>This normally happens on server machines with slow disks
+ that are spawning a getty on the port, and executing &man.ppp.8; from
+ a login script or program after login. I have also heard reports
+ of it happening consistently when using slirp. The reason is
+ that in the time taken between &man.getty.8; exiting and &man.ppp.8; starting,
+ the client-side &man.ppp.8; starts sending Line Control Protocol (LCP)
+ packets. Because ECHO is still switched on for the port on
+ the server, the client &man.ppp.8; sees these packets
+ <quote>reflect</quote> back.</para>
+
+ <para>One part of the LCP negotiation is to establish a magic
+ number for each side of the link so that
+ <quote>reflections</quote> can be detected. The protocol says
+ that when the peer tries to negotiate the same magic number, a
+ NAK should be sent and a new magic number should be chosen.
+ During the period that the server port has ECHO turned on, the
+ client &man.ppp.8; sends LCP packets, sees the same magic in the
+ reflected packet and NAKs it. It also sees the NAK reflect
+ (which also means &man.ppp.8; must change its magic). This produces a
+ potentially enormous number of magic number changes, all of
+ which are happily piling into the server's tty buffer. As soon
+ as &man.ppp.8; starts on the server, it is flooded with magic number
+ changes and almost immediately decides it has tried enough to
+ negotiate LCP and gives up. Meanwhile, the client, who no
+ longer sees the reflections, becomes happy just in time to see
+ a hangup from the server.</para>
+
+ <para>This can be avoided by allowing the peer to start
+ negotiating with the following line in your ppp.conf
+ file:</para>
+
+ <programlisting>set openmode passive</programlisting>
+
+ <para>This tells &man.ppp.8; to wait for the server to initiate LCP
+ negotiations. Some servers however may never initiate
+ negotiations. If this is the case, you can do something
+ like:</para>
+
+ <programlisting>set openmode active 3</programlisting>
+
+ <para>This tells &man.ppp.8; to be passive for 3 seconds, and then to
+ start sending LCP requests. If the peer starts sending
+ requests during this period, &man.ppp.8; will immediately respond
+ rather than waiting for the full 3 second period.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-lcp-constant">
+ <para>LCP negotiations continue until the connection is
+ closed. What is wrong?</para>
+ </question>
+
+ <answer>
+ <para>There is currently an implementation mis-feature in
+ &man.ppp.8; where it does not associate
+ LCP, CCP &amp; IPCP responses with their original requests. As
+ a result, if one PPP
+ implementation is more than 6 seconds slower than the other
+ side, the other side will send two additional LCP configuration
+ requests. This is fatal.</para>
+
+ <para>Consider two implementations,
+ <hostid>A</hostid> and
+ <hostid>B</hostid>. <hostid>A</hostid> starts
+ sending LCP requests immediately after connecting and
+ <hostid>B</hostid> takes 7 seconds to start. When
+ <hostid>B</hostid> starts, <hostid>A</hostid>
+ has sent 3 LCP REQs. We are assuming the line has ECHO switched
+ off, otherwise we would see magic number problems as described in
+ the previous section. <hostid>B</hostid> sends a
+ REQ, then an ACK to the first of
+ <hostid>A</hostid>'s REQs. This results in
+ <hostid>A</hostid> entering the <acronym>OPENED</acronym>
+ state and sending and ACK (the first) back to
+ <hostid>B</hostid>. In the meantime,
+ <hostid>B</hostid> sends back two more ACKs in response to
+ the two additional REQs sent by <hostid>A</hostid>
+ before <hostid>B</hostid> started up.
+ <hostid>B</hostid> then receives the first ACK from
+ <hostid>A</hostid> and enters the
+ <acronym>OPENED</acronym> state.
+ <hostid>A</hostid> receives the second ACK from
+ <hostid>B</hostid> and goes back to the
+ <acronym>REQ-SENT</acronym> state, sending another (forth) REQ
+ as per the RFC. It then receives the third ACK and enters the
+ <acronym>OPENED</acronym> state. In the meantime,
+ <hostid>B</hostid> receives the forth REQ from
+ <hostid>A</hostid>, resulting in it reverting to the
+ <acronym>ACK-SENT</acronym> state and sending
+ another (second) REQ and (forth) ACK as per the RFC.
+ <hostid>A</hostid> gets the REQ, goes into
+ <acronym>REQ-SENT</acronym> and sends another REQ. It
+ immediately receives the following ACK and enters
+ <acronym>OPENED</acronym>.</para>
+
+ <para>This goes on until one side figures out that they are
+ getting nowhere and gives up.</para>
+
+ <para>The best way to avoid this is to configure one side to be
+ <literal>passive</literal> - that is, make one side
+ wait for the other to start negotiating. This can be done
+ with the</para>
+
+ <programlisting>set openmode passive</programlisting>
+
+ <para>command. Care should be taken with this option. You
+ should also use the</para>
+
+ <programlisting>set stopped N</programlisting>
+
+ <para>command to limit the amount of time that
+ &man.ppp.8; waits for the peer to begin
+ negotiations. Alternatively, the</para>
+
+ <programlisting>set openmode active N</programlisting>
+
+ <para>command (where <replaceable>N</replaceable> is the
+ number of seconds to wait before starting negotiations) can be
+ used. Check the manual page for details.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-lockups">
+ <para>Why does &man.ppp.8; lock up shortly after connection?</para>
+ </question>
+
+ <answer>
+ <para>Prior to version 2.2.5 of FreeBSD, it was possible that
+ your link was disabled shortly after connection due to
+ &man.ppp.8; mis-handling Predictor1
+ compression negotiation. This would only happen if both sides
+ tried to negotiate different Compression Control Protocols
+ (CCP). This problem is now corrected, but if you are still
+ running an old version of &man.ppp.8;
+ the problem can be circumvented with the line</para>
+
+ <programlisting>disable pred1</programlisting>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-shell-test-lockup">
+ <para>Why does &man.ppp.8; lock up when I shell out to test it?</para>
+ </question>
+
+ <answer>
+ <para>When you execute the <command>shell</command> or
+ <command>!</command> command, &man.ppp.8; executes a
+ shell (or if you have passed any arguments,
+ &man.ppp.8; will execute those arguments). Ppp will
+ wait for the command to complete before continuing. If you
+ attempt to use the PPP link while running the command, the link
+ will appear to have frozen. This is because
+ &man.ppp.8; is waiting for the command to
+ complete.</para>
+
+ <para>If you wish to execute commands like this, use the
+ <command>!bg</command> command instead. This will execute
+ the given command in the background, and &man.ppp.8; can continue to
+ service the link.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-nullmodem">
+ <para>Why does &man.ppp.8; over a null-modem cable never exit?</para>
+ </question>
+
+ <answer>
+ <para>There is no way for &man.ppp.8; to
+ automatically determine that a direct connection has been
+ dropped. This is due to the lines that are used in a
+ null-modem serial cable. When using this sort of connection,
+ LQR should always be enabled with the line</para>
+
+ <programlisting>enable lqr</programlisting>
+
+ <para>LQR is accepted by default if negotiated by the peer.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-auto-noreasondial">
+ <para>Why does &man.ppp.8; dial for no reason in -auto mode?</para>
+ </question><answer>
+
+ <para>If &man.ppp.8; is dialing
+ unexpectedly, you must determine the cause, and set up Dial
+ filters (dfilters) to prevent such dialing.</para>
+
+ <para>To determine the cause, use the following line:</para>
+
+ <programlisting>set log +tcp/ip</programlisting>
+
+ <para>This will log all traffic through the connection. The
+ next time the line comes up unexpectedly, you will see the
+ reason logged with a convenient timestamp next to it.</para>
+
+ <para>You can now disable dialing under these circumstances.
+ Usually, this sort of problem arises due to DNS lookups. To
+ prevent DNS lookups from establishing a connection (this will
+ <emphasis>not</emphasis> prevent
+ &man.ppp.8; from passing the packets
+ through an established connection), use the following:</para>
+
+ <programlisting>set dfilter 1 deny udp src eq 53
+set dfilter 2 deny udp dst eq 53
+set dfilter 3 permit 0/0 0/0</programlisting>
+
+ <para>This is not always suitable, as it will effectively break
+ your demand-dial capabilities - most programs will need a DNS
+ lookup before doing any other network related things.</para>
+
+ <para>In the DNS case, you should try to determine what is
+ actually trying to resolve a host name. A lot of the time,
+ &man.sendmail.8; is the culprit. You should make sure that
+ you tell sendmail not to do any DNS lookups in its
+ configuration file. See the section on
+ <link linkend="ispmail">Mail Configuration</link> for details
+ on how to create your own configuration file and what should
+ go into it. You may also want to add the following line to
+ your <filename>.mc</filename> file:</para>
+
+ <programlisting>define(`confDELIVERY_MODE', `d')dnl</programlisting>
+
+ <para>This will make sendmail queue everything until the queue
+ is run (usually, sendmail is invoked with
+ <option>-bd -q30m</option>, telling it to run the queue every
+ 30 minutes) or until a <command>sendmail -q</command> is done
+ (perhaps from your ppp.linkup file).</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ccp-errors">
+ <para>What do these CCP errors mean?</para>
+ </question>
+
+ <answer>
+ <para>I keep seeing the following errors in my log file:</para>
+
+ <programlisting>CCP: CcpSendConfigReq
+CCP: Received Terminate Ack (1) state = Req-Sent (6)</programlisting>
+
+ <para>This is because &man.ppp.8; is trying to negotiate Predictor1
+ compression, and the peer does not want to negotiate any
+ compression at all. The messages are harmless, but if you
+ wish to remove them, you can disable Predictor1 compression
+ locally too:</para>
+
+ <programlisting>disable pred1</programlisting>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-lockup-ioerrors">
+ <para>Why does &man.ppp.8; lock up during file transfers with IO
+ errors?</para>
+ </question>
+
+ <answer>
+ <para>Under FreeBSD 2.2.2 and before, there was a bug in the
+ tun driver that prevents incoming packets of a size larger
+ than the tun interface's MTU size. Receipt of a packet
+ greater than the MTU size results in an IO error being logged
+ via syslogd.</para>
+
+ <para>The PPP specification says that an MRU of 1500 should
+ <emphasis>always</emphasis> be accepted as a minimum,
+ despite any LCP negotiations, therefore it is possible that
+ should you decrease the MTU to less than 1500, your ISP will
+ transmit packets of 1500 regardless, and you will tickle this
+ non-feature - locking up your link.</para>
+
+ <para>The problem can be circumvented by never setting an MTU of
+ less than 1500 under FreeBSD 2.2.2 or before.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-connectionspeed">
+ <para>Why does &man.ppp.8; not log my connection speed?</para>
+ </question>
+
+ <answer>
+
+ <para>In order to log all lines of your modem
+ <quote>conversation</quote>, you must enable the
+ following:</para>
+
+ <programlisting>set log +connect</programlisting>
+
+ <para>This will make &man.ppp.8; log
+ everything up until the last requested <quote>expect</quote>
+ string.</para>
+
+ <para>If you wish to see your connect speed and are using PAP
+ or CHAP (and therefore do not have anything to
+ <quote>chat</quote> after the CONNECT in the dial script - no
+ <literal>set login</literal> script), you must make sure that
+ you instruct &man.ppp.8; to <quote>expect</quote> the whole CONNECT
+ line, something like this:</para>
+
+ <programlisting>set dial "ABORT BUSY ABORT NO\\sCARRIER TIMEOUT 4 \
+ \"\" ATZ OK-ATZ-OK ATDT\\T TIMEOUT 60 CONNECT \\c \\n"</programlisting>
+
+ <para>Here, we get our CONNECT, send nothing, then expect a
+ line-feed, forcing &man.ppp.8; to read
+ the whole CONNECT response.</para>
+
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-ignores-backslash">
+ <para>Why does &man.ppp.8; ignore the <literal>\</literal> character
+ in my chat script?</para>
+ </question><answer>
+
+ <para>Ppp parses each line in your config files so that it can
+ interpret strings such as
+ <literal>set phone "123 456 789"</literal> correctly (and
+ realize that the number is actually only
+ <emphasis>one</emphasis> argument. In order to specify a
+ <literal>&quot;</literal> character, you must escape it
+ using a backslash (<literal>\</literal>).</para>
+
+ <para>When the chat interpreter parses each argument, it
+ re-interprets the argument in order to find any special
+ escape sequences such as <literal>\P</literal> or
+ <literal>\T</literal> (see the man page). As a result of this
+ double-parsing, you must remember to use the correct number of
+ escapes.</para>
+
+ <para>If you wish to actually send a <literal>\</literal>
+ character to (say) your modem, you would need something
+ like:</para>
+
+ <programlisting>set dial "\"\" ATZ OK-ATZ-OK AT\\\\X OK"</programlisting>
+
+ <para>resulting in the following sequence:</para>
+
+ <programlisting>ATZ
+OK
+AT\X
+OK</programlisting>
+
+ <para>or</para>
+
+ <programlisting>set phone 1234567
+set dial "\"\" ATZ OK ATDT\\T"</programlisting>
+
+ <para>resulting in the following sequence:</para>
+
+ <programlisting>ATZ
+OK
+ATDT1234567</programlisting>
+
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-segfault-nocore">
+ <para>Why does &man.ppp.8; get a seg-fault, but I see no
+ <filename>ppp.core</filename> file?</para>
+ </question>
+
+ <answer>
+ <para>Ppp (or any other program for that matter) should never
+ dump core. Because &man.ppp.8; runs with an effective user id of 0,
+ the operating system will not write &man.ppp.8;'s core image to disk
+ before terminating it. If, however &man.ppp.8;
+ is actually terminating due to a
+ segmentation violation or some other signal that normally
+ causes core to be dumped, <emphasis>and</emphasis>
+ you are sure you are using the latest version (see the start of
+ this section), then you should do the following:</para>
+
+ <screen>&prompt.user; <userinput>tar xfz ppp-*.src.tar.gz</userinput>
+&prompt.user; <userinput>cd ppp*/ppp</userinput>
+&prompt.user; <userinput>echo STRIP= &gt;&gt;Makefile</userinput>
+&prompt.user; <userinput>echo CFLAGS+=-g &gt;&gt;Makefile</userinput>
+&prompt.user; <userinput>make clean all</userinput>
+&prompt.user; <userinput>su</userinput>
+&prompt.root; <userinput>make install</userinput>
+&prompt.root; <userinput>chmod 555 /usr/sbin/ppp</userinput></screen>
+
+ <para>You will now have a debuggable version of &man.ppp.8; installed.
+ You will have to be <username>root</username> to run &man.ppp.8; as all of its privileges
+ have been revoked. When you start &man.ppp.8;, take a careful note
+ of what your current directory was at the time.</para>
+
+ <para>Now, if and when &man.ppp.8; receives the segmentation violation,
+ it will dump a core file called <filename>ppp.core</filename>. You should then do
+ the following:</para>
+
+ <screen>&prompt.user; <userinput>su</userinput>
+&prompt.root; <userinput>gdb /usr/sbin/ppp ppp.core</userinput>
+<prompt>(gdb)</prompt> <userinput>bt</userinput>
+.....
+<prompt>(gdb)</prompt> <userinput>f 0</userinput>
+....
+<prompt>(gdb)</prompt> <userinput>i args</userinput>
+....
+<prompt>(gdb)</prompt> <userinput>l</userinput>
+.....</screen>
+
+ <para>All of this information should be given alongside your
+ question, making it possible to diagnose the problem.</para>
+
+ <para>If you are familiar with gdb, you may wish to find out some
+ other bits and pieces such as what actually caused the dump and
+ the addresses &amp; values of the relevant variables.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-autodialprocess-noconnect">
+ <para>Why does the process that forces a dial in auto mode never
+ connect?</para>
+ </question>
+
+ <answer>
+ <para>This was a known problem with
+ &man.ppp.8; set up to negotiate a
+ dynamic local IP number with the peer in auto mode. It is
+ fixed in the latest version - search the man page for
+ <literal>iface</literal>.</para>
+
+ <para>The problem was that when that initial program calls
+ &man.connect.2;, the IP number of the tun interface is assigned
+ to the socket endpoint. The kernel creates the first outgoing
+ packet and writes it to the tun device.
+ &man.ppp.8; then reads the packet and
+ establishes a connection. If, as a result of
+ &man.ppp.8;'s dynamic IP assignment, the
+ interface address is changed, the original socket endpoint will
+ be invalid. Any subsequent packets sent to the peer will
+ usually be dropped. Even if they are not, any responses will
+ not route back to the originating machine as the IP number is
+ no longer owned by that machine.</para>
+
+ <para>There are several theoretical ways to approach this
+ problem. It would be nicest if the peer would re-assign the
+ same IP number if possible <literal>:-)</literal>
+ The current version of &man.ppp.8; does
+ this, but most other implementations do not.</para>
+
+ <para>The easiest method from our side would be to never change
+ the tun interface IP number, but instead to change all outgoing
+ packets so that the source IP number is changed from the
+ interface IP to the negotiated IP on the fly. This is
+ essentially what the <literal>iface-alias</literal> option in
+ the latest version of &man.ppp.8; is
+ doing (with the help of
+ &man.libalias.3; and &man.ppp.8;'s <option>-nat</option> switch) -
+ it is maintaining all previous interface addresses and NATing
+ them to the last negotiated address.</para>
+
+ <para>Another alternative (and probably the most reliable) would
+ be to implement a system call that changes all bound sockets
+ from one IP to another. &man.ppp.8; would
+ use this call to modify the sockets of all existing programs
+ when a new IP number is negotiated. The same system call could
+ be used by dhcp clients when they are forced to re-bind() their
+ sockets.</para>
+
+ <para>Yet another possibility is to allow an interface to be
+ brought up without an IP number. Outgoing packets would be
+ given an IP number of 255.255.255.255 up until the first
+ SIOCAIFADDR ioctl is done. This would result in fully binding
+ the socket. It would be up to &man.ppp.8;
+ to change the source IP number, but only if it is set to
+ 255.255.255.255, and only the IP number and IP checksum would
+ need to change. This, however is a bit of a hack as the kernel
+ would be sending bad packets to an improperly configured
+ interface, on the assumption that some other mechanism is
+ capable of fixing things retrospectively.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ppp-nat-games">
+ <para>Why do most games not work with the -nat switch?</para>
+ </question>
+
+ <answer>
+ <para>The reason games and the like do not work when libalias
+ is in use is that the machine on the outside will try to open a
+ connection or send (unsolicited) UDP packets to the machine on
+ the inside. The NAT software does not know that it should send
+ these packets to the interior machine.</para>
+
+ <para>To make things work, make sure that the only thing
+ running is the software that you are having problems with, then
+ either run tcpdump on the tun interface of the gateway or
+ enable &man.ppp.8; tcp/ip logging (<literal>set log +tcp/ip</literal>)
+ on the gateway.</para>
+
+ <para>When you start the offending software, you should see
+ packets passing through the gateway machine. When something
+ comes back from the outside, it will be dropped (that is the
+ problem). Note the port number of these packets then shut down
+ the offending software. Do this a few times to see if the port
+ numbers are consistent. If they are, then the following line in
+ the relevant section of <filename>/etc/ppp/ppp.conf</filename> will make the
+ software functional:</para>
+
+ <programlisting>nat port <replaceable>proto</replaceable> <replaceable>internalmachine</replaceable>:<replaceable>port</replaceable> <replaceable>port</replaceable></programlisting>
+
+ <para>where <replaceable>proto</replaceable> is either
+ <literal>tcp</literal> or <literal>udp</literal>,
+ <replaceable>internalmachine</replaceable> is the machine that
+ you want the packets to be sent to and
+ <replaceable>port</replaceable> is the destination port number
+ of the packets.</para>
+
+ <para>You will not be able to use the software on other machines
+ without changing the above command, and running the software
+ on two internal machines at the same time is out of the question
+ - after all, the outside world is seeing your entire internal
+ network as being just a single machine.</para>
+
+ <para>If the port numbers are not consistent, there are three
+ more options:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Submit support in
+ libalias. Examples of <quote>special cases</quote> can be found
+ in <filename>/usr/src/lib/libalias/alias_*.c</filename>
+ (<filename>alias_ftp.c</filename> is a good prototype). This
+ usually involves reading certain recognised outgoing packets,
+ identifying the instruction that tells the outside machine to
+ initiate a connection back to the internal machine on a
+ specific (random) port and setting up a <quote>route</quote> in
+ the alias table so that the subsequent packets know where to
+ go.</para>
+
+ <para>This is the most difficult solution, but it is the best
+ and will make the software work with multiple machines.</para>
+ </listitem>
+
+ <listitem>
+ <para>Use a proxy. The
+ application may support socks5 for example, or (as in the
+ <quote>cvsup</quote> case) may have a <quote>passive</quote>
+ option that avoids ever requesting that the peer open
+ connections back to the local machine.</para>
+ </listitem>
+
+ <listitem>
+ <para>Redirect everything to
+ the internal machine using <literal>nat addr</literal>. This
+ is the sledge-hammer approach.</para>
+ </listitem>
+ </orderedlist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="useful-port-numbers">
+ <para>Has anybody made a list of useful port numbers?</para>
+ </question><answer>
+
+ <para>Not yet, but this is intended to grow into such a list
+ (if any interest is shown). In each example,
+ <replaceable>internal</replaceable> should be replaced with
+ the IP number of the machine playing the game.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><application>Asheron's Call</application></para>
+
+ <para><literal>nat port udp
+ <replaceable>internal</replaceable>
+ :65000 65000</literal></para>
+
+ <para>Manually change the port number within the game to
+ 65000. If you have got a number of machines that you wish
+ to play on assign a unique port number for each (i.e.
+ 65001, 65002, etc) and add a <literal>nat port</literal>
+ line for each one.</para>
+ </listitem>
+
+ <listitem>
+ <para><application>Half Life</application></para>
+
+ <para><literal>nat port udp
+ <replaceable>internal</replaceable>:27005
+ 27015</literal></para>
+ </listitem>
+
+ <listitem>
+ <para><application>PCAnywhere 8.0</application></para>
+
+ <para><literal>nat port udp
+ <replaceable>internal</replaceable>:5632
+ 5632</literal></para>
+
+ <para><literal>nat port tcp
+ <replaceable>internal</replaceable>:5631
+ 5631</literal></para>
+ </listitem>
+
+ <listitem>
+ <para><application>Quake</application></para>
+
+ <para><literal>nat port udp
+ <replaceable>internal</replaceable>:6112
+ 6112</literal></para>
+
+ <para>Alternatively, you may want to take a look at <ulink
+ url="http://www.battle.net/support/proxy/">
+ www.battle.net</ulink> for Quake proxy support.</para>
+ </listitem>
+
+ <listitem>
+ <para><application>Quake 2</application></para>
+
+ <para><literal>nat port udp
+ <replaceable>internal</replaceable>:27901
+ 27910</literal></para>
+ <para><literal>nat port udp
+ <replaceable>internal</replaceable>:60021
+ 60021</literal></para>
+ <para><literal>nat port udp
+ <replaceable>internal</replaceable>:60040
+ 60040</literal></para>
+ </listitem>
+
+ <listitem>
+ <para><application>Red Alert</application></para>
+
+ <para><literal>nat port udp
+ <replaceable>internal</replaceable>:8675
+ 8675</literal></para>
+
+ <para><literal>nat port udp
+ <replaceable>internal</replaceable>:5009
+ 5009</literal></para>
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="fcs-errors">
+ <para>What are FCS errors?</para>
+ </question>
+
+ <answer>
+ <para>FCS stands for <literal>F</literal>rame
+ <literal>C</literal>heck
+ <literal>S</literal>equence. Each PPP packet
+ has a checksum attached to ensure that the data being
+ received is the data being sent. If the FCS of an incoming
+ packet is incorrect, the packet is dropped and the HDLC FCS
+ count is increased. The HDLC error values can be displayed
+ using the <literal>show hdlc</literal> command.</para>
+
+ <para>If your link is bad (or if your serial driver is dropping
+ packets), you will see the occasional FCS error. This is not
+ usually worth worrying about although it does slow down the
+ compression protocols substantially. If you have an external
+ modem, make sure your cable is properly shielded from
+ interference - this may eradicate the problem.</para>
+
+ <para>If your link freezes as soon as you have connected and you
+ see a large number of FCS errors, this may be because your link
+ is not 8 bit clean. Make sure your modem is not using software
+ flow control (XON/XOFF). If your datalink
+ <emphasis>must</emphasis> use software flow control, use the
+ command <literal>set accmap 0x000a0000</literal> to tell
+ &man.ppp.8; to escape the <literal>^Q</literal> and
+ <literal>^S</literal> characters.</para>
+
+ <para>Another reason for seeing too many FCS errors may be that
+ the remote end has stopped talking <acronym>PPP</acronym>. You
+ may want to enable <literal>async</literal> logging at this
+ point to determine if the incoming data is actually a login or
+ shell prompt. If you have a shell prompt at the remote end,
+ it is possible to terminate &man.ppp.8; without dropping the line by
+ using the <literal>close lcp</literal> command (a following
+ <literal>term</literal> command will reconnect you to the shell
+ on the remote machine.</para>
+
+ <para>If nothing in your log file indicates why the link might
+ have been terminated, you should ask the remote administrator
+ (your ISP?) why the session was terminated.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry id="PPPoEwithNAT">
+ <question id="macos-win98-pppoe-freeze">
+ <para>Why do MacOS and Windows 98 connections freeze when
+ running PPPoE on the gateway?</para>
+ </question>
+
+ <answer>
+ <para>Thanks to Michael Wozniak
+ <email>mwozniak@netcom.ca</email> for figuring this out and
+ Dan Flemming <email>danflemming@mac.com</email> for the Mac
+ solution:</para>
+
+ <para>This is due to what is called a <quote>Black Hole</quote>
+ router. MacOS and Windows 98 (and maybe other Microsoft OSs)
+ send TCP packets with a requested segment size too big to fit
+ into a PPPoE frame (MTU is 1500 by default for Ethernet)
+ <emphasis>and</emphasis> have the <quote>do not
+ fragment</quote> bit set (default of TCP) and the Telco router
+ is not sending ICMP <quote>must fragment</quote> back to the
+ www site you are trying to load. (Alternatively, the router is
+ sending the ICMP packet correctly, but the firewall at the www
+ site is dropping it.) When the www server is sending
+ you frames that do not fit into the PPPoE pipe the Telco router
+ drops them on the floor and your page does not load (some
+ pages/graphics do as they are smaller than a MSS.) This seems
+ to be the default of most Telco PPPoE configurations (if only
+ they knew how to program a router... sigh...)</para>
+
+ <para>One fix is to use regedit on your 95/98 boxes to add the
+ following registry entry...</para>
+
+ <programlisting>HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Class\NetTrans\0000\MaxMTU</programlisting>
+
+ <para>It should be a string with a value <quote>1436</quote>, as
+ some ADSL routers are reported to be unable to deal with packets
+ larger than this. This registry key has been changed to
+ <literal>Tcpip\Parameters\Interfaces\<replaceable>ID for adapter</replaceable>\MTU</literal>
+ in Windows 2000 and becomes a DWORD.</para>
+
+ <para>Refer to the Microsoft Knowledge Base documents <ulink
+ url="http://support.microsoft.com/support/kb/articles/Q158/4/74.asp">Q158474
+ - Windows TCPIP Registry Entries</ulink> and <ulink
+ url="http://support.microsoft.com/support/kb/articles/Q120/6/42.asp">Q120642
+ - TCPIP & NBT Configuration Parameters for Windows
+ NT</ulink> for more information on changing Windows MTU to
+ work with a NAT router.</para>
+
+ <para>Another regedit possibility under Windows 2000 is to
+ set the
+ <literal>Tcpip\Parameters\Interfaces\<replaceable>ID for
+ adapter</replaceable>\EnablePMTUBHDetect</literal> DWORD
+ to 1 as mentioned in the Microsoft document 120642
+ mentioned above.</para>
+
+ <para>Unfortunately, MacOS does not provide an interface for
+ changing TCP/IP settings. However, there is commercial software
+ available, such as OTAdvancedTuner (OT for OpenTransport, the
+ MacOS TCP/IP stack) by <ulink
+ url="http://www.softworks.com/">Sustainable Softworks</ulink>,
+ that will allow users to customize TCP/IP settings. MacOS NAT
+ users should select <literal>ip_interface_MTU</literal> from
+ the drop-down menu, enter <literal>1450</literal> instead of
+ <literal>1500</literal> in the box, click the box next to
+ <literal>Save as Auto Configure</literal>, and click
+ <literal>Make Active</literal>.</para>
+
+ <para>The latest version of &man.ppp.8;
+ (2.3 or greater) has an <command>enable tcpmssfixup</command>
+ command that will automatically adjust the MSS to an appropriate
+ value. This facility is enabled by default. If you are stuck
+ with an older version of &man.ppp.8;, you
+ may want to look at the <application>tcpmssd</application>
+ port.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="desperation">
+ <para>None of this helps - I am desperate! What can I do?</para>
+ </question>
+
+ <answer>
+ <para>If all else fails, send as much information as you can,
+ including your config files, how you are starting
+ &man.ppp.8;, the relevant parts of your
+ log file and the output of the <command>netstat -rn</command>
+ command (before and after connecting) to the &a.questions; or
+ the <ulink url="news:comp.unix.bsd.freebsd.misc">
+ comp.unix.bsd.freebsd.misc</ulink> news group, and someone
+ should point you in the right direction.</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+ <chapter id="serial">
+ <title>Serial Communications</title>
+
+ <para>This section answers common questions about serial
+ communications with FreeBSD. PPP and SLIP are covered in the
+ <xref linkend="networking" remap="Networking"/> section.</para>
+
+
+ <qandaset>
+ <qandaentry>
+ <question id="found-serial">
+ <para>How do I tell if FreeBSD found my serial ports?</para>
+ </question>
+
+ <answer>
+ <para>As the FreeBSD kernel boots, it will probe for the serial
+ ports in your system for which the kernel was configured.
+ You can either watch your system closely for the messages it
+ prints or run the command</para>
+
+ <screen>&prompt.user; <userinput>dmesg | grep sio</userinput></screen>
+
+ <para>after your system is up and running.</para>
+
+ <para>Here is some example output from the above command:</para>
+
+ <programlisting>sio0 at 0x3f8-0x3ff irq 4 on isa
+sio0: type 16550A
+sio1 at 0x2f8-0x2ff irq 3 on isa
+sio1: type 16550A</programlisting>
+
+ <para>This shows two serial ports. The first is on irq 4, is
+ using port address <literal>0x3f8</literal>, and has a
+ 16550A-type UART chip. The second uses the same kind of chip
+ but is on irq 3 and is at port address <literal>0x2f8</literal>.
+ Internal modem cards are treated just like serial ports---except
+ that they always have a modem <quote>attached</quote> to the
+ port.</para>
+
+ <para>The <filename>GENERIC</filename> kernel includes support
+ for two serial ports using the same irq and port address
+ settings in the above example. If these settings are not
+ right for your system, or if you have added modem cards or have
+ more serial ports than your kernel is configured for, just
+ reconfigure your kernel. See section
+ <link linkend="make-kernel">about building a kernel</link> for
+ more details.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="found-modem">
+ <para>How do I tell if FreeBSD found my modem cards?</para>
+ </question>
+
+ <answer>
+ <para>Refer to the answer to the previous question.</para>
+
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="missing-tty0X">
+ <para>I just upgraded to 2.0.5 and my
+ <devicename>tty0<replaceable>X</replaceable></devicename>
+ are missing! How do I solve this problem?</para>
+ </question>
+
+ <answer>
+ <para>Do not worry, they have been merged with the
+ <devicename>ttyd<replaceable>X</replaceable></devicename> devices. You will have to change
+ any old configuration files you have, though.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="access-serial-ports">
+ <para>How do I access the serial ports on FreeBSD?</para>
+ </question>
+
+ <answer>
+ <para>The third serial port,
+ <devicename>sio2</devicename>
+ (see &man.sio.4;, known as COM3 in DOS), is on <devicename>/dev/cuaa2</devicename>
+ for dial-out devices, and on <devicename>/dev/ttyd2</devicename>
+ for dial-in devices. What is the difference between these two
+ classes of devices?</para>
+
+ <para>You use <devicename>ttyd<replaceable>X</replaceable></devicename> for dial-ins. When
+ opening <devicename>/dev/ttyd<replaceable>X</replaceable></devicename> in blocking mode, a
+ process will wait for the corresponding
+ <devicename>cuaa<replaceable>X</replaceable></devicename> device to become inactive, and then
+ wait for the carrier detect line to go active. When you open
+ the <devicename>cuaa<replaceable>X</replaceable></devicename> device, it makes sure the serial
+ port is not already in use by the <devicename>ttyd<replaceable>X</replaceable></devicename>
+ device. If the port is available, it <quote>steals</quote> it
+ from the <devicename>ttyd<replaceable>X</replaceable></devicename> device. Also, the
+ <devicename>cuaa<replaceable>X</replaceable></devicename> device does not care about carrier
+ detect. With this scheme and an auto-answer modem, you can have
+ remote users log in and you can still dial out with the same
+ modem and the system will take care of all the
+ conflicts.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="enable-multiport-serial">
+ <para>How do I enable support for a multiport serial
+ card?</para>
+ </question>
+
+ <answer>
+ <para>Again, the section on kernel configuration provides
+ information about configuring your kernel. For a multiport
+ serial card, place an &man.sio.4; line
+ for each serial port on the card in the kernel configuration
+ file. But place the irq and vector specifiers on only one of
+ the entries. All of the ports on the card should share one irq.
+ For consistency, use the last serial port to specify the irq.
+ Also, specify the <literal>COM_MULTIPORT</literal>
+ option.</para>
+
+ <para>The following example is for an AST 4-port serial card on
+ irq 7:</para>
+
+ <programlisting>options "COM_MULTIPORT"
+device sio4 at isa? port 0x2a0 tty flags 0x781
+device sio5 at isa? port 0x2a8 tty flags 0x781
+device sio6 at isa? port 0x2b0 tty flags 0x781
+device sio7 at isa? port 0x2b8 tty flags 0x781 irq 7 vector siointr</programlisting>
+
+ <para>The flags indicate that the master port has minor number 7
+ (<literal>0x700</literal>), diagnostics enabled during probe
+ (<literal>0x080</literal>), and all the ports share an irq
+ (<literal>0x001</literal>).</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="multiport-serial-share-irq">
+ <para>Can FreeBSD handle multiport serial cards sharing
+ irqs?</para>
+ </question>
+
+ <answer>
+ <para>Not yet. You will have to use a different irq for each
+ card.</para>
+
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="default-serial-params">
+ <para>Can I set the default serial parameters for a
+ port?</para>
+ </question>
+
+ <answer>
+ <para>The <devicename>ttyd<replaceable>X</replaceable></devicename> (or
+ <devicename>cuaa<replaceable>X</replaceable></devicename>) device is the regular device
+ you will want to open for your applications. When a process
+ opens the device, it will have a default set of terminal I/O
+ settings. You can see these settings with the command</para>
+
+ <screen>&prompt.root; <userinput>stty -a -f /dev/ttyd1</userinput></screen>
+
+ <para>When you change the settings to this device, the settings
+ are in effect until the device is closed. When it is reopened,
+ it goes back to the default set. To make changes to the
+ default set, you can open and adjust the settings of the
+ <quote>initial state</quote> device. For example, to turn on
+ <acronym>CLOCAL</acronym> mode, 8 bits, and
+ <acronym>XON/XOFF</acronym> flow control by default for
+ ttyd5, do:</para>
+
+ <screen>&prompt.root; <userinput>stty -f /dev/ttyid5 clocal cs8 ixon ixoff</userinput></screen>
+
+ <para>A good place to do this is in
+ <filename>/etc/rc.serial</filename>. Now, an application will
+ have these settings by default when it opens
+ <filename>ttyd5</filename>. It can still change these settings
+ to its liking, though.</para>
+
+ <para>You can also prevent certain settings from being changed
+ by an application by making adjustments to the
+ <quote>lock state</quote> device. For example, to lock the
+ speed of <devicename>ttyd5</devicename> to 57600 bps, do</para>
+
+ <screen>&prompt.root; <userinput>stty -f /dev/ttyld5 57600</userinput></screen>
+
+ <para>Now, an application that opens <devicename>ttyd5</devicename>
+ and tries to change the speed of the port will be stuck with
+ 57600 bps.</para>
+
+ <para>Naturally, you should make the initial state and lock state
+ devices writable only by <username>root</username>. The
+ &man.MAKEDEV.8;
+ script does <emphasis>NOT</emphasis> do this when it creates the
+ device entries.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="enable-dialup">
+ <para>How can I enable dialup logins on my modem?</para>
+ </question>
+
+ <answer>
+ <para>So you want to become an Internet service provider, eh?
+ First, you will need one or more modems that can auto-answer.
+ Your modem will need to assert carrier-detect when it detects a
+ carrier and not assert it all the time. It will need to hang up
+ the phone and reset itself when the data terminal ready
+ (<acronym>DTR</acronym>) line goes from on to off. It should
+ probably use <filename>RTS/CTS</filename> flow control or no
+ local flow control at all. Finally, it must use a constant
+ speed between the computer and itself, but (to be nice to your
+ callers) it should negotiate a speed between itself and the
+ remote modem.</para>
+
+ <para>For many Hayes command-set--compatible modems, this
+ command will make these settings and store them in
+ nonvolatile memory:</para>
+
+ <programlisting>AT &amp;C1 &amp;D3 &amp;K3 &amp;Q6 S0=1 &amp;W</programlisting>
+
+ <para>See the section <link linkend="direct-at">on sending AT
+ commands</link> below for information on how to make these
+ settings without resorting to an MS-DOS terminal program.</para>
+
+ <para>Next, make an entry in
+ <filename>/etc/ttys</filename> (see &man.ttys.5;) for the modem. This file lists all the ports
+ on which the operating system will await logins. Add a line
+ that looks something like this:</para>
+
+ <programlisting>ttyd1 "/usr/libexec/getty std.57600" dialup on insecure</programlisting>
+
+ <para>This line indicates that the second serial port
+ (<devicename>/dev/ttyd1</devicename>) has a modem connected
+ running at 57600 bps and no parity
+ (<literal>std.57600</literal>, which comes from the file
+ <filename>/etc/gettytab</filename>, see &man.gettytab.5;).
+ The terminal type for this port is <literal>dialup</literal>.
+ The port is <literal>on</literal> and is
+ <literal>insecure</literal>---meaning <username>root</username>
+ logins on the port are not allowed. For dialin ports like this one,
+ use the <devicename>ttyd<replaceable>X</replaceable></devicename>
+ entry.</para>
+
+ <para>It is common practice to use <literal>dialup</literal> as
+ the terminal type. Many users set up in their <filename>.profile</filename> or
+ <filename>.login</filename> files a prompt for the actual terminal type if the
+ starting type is dialup. The example shows the port as
+ insecure. To become <username>root</username> on this port, you
+ have to login as a regular user, then &man.su.1; to become
+ <username>root</username>. If you use <literal>secure</literal>
+ then <username>root</username> can login in directly.</para>
+
+ <para>After making modifications to
+ <filename>/etc/ttys</filename>, you need to send a hangup or
+ <acronym>HUP</acronym> signal to the
+ &man.init.8; process:</para>
+
+ <screen>&prompt.root; <userinput>kill -HUP 1</userinput></screen>
+
+ <para>This forces the &man.init.8; process to reread
+ <filename>/etc/ttys</filename>. The init process will then start getty
+ processes on all <literal>on</literal> ports. You can find
+ out if logins are available for your port by typing</para>
+
+ <screen>&prompt.user; <userinput>ps -ax | grep '[t]tyd1'</userinput></screen>
+
+ <para>You should see something like:</para>
+
+ <programlisting>747 ?? I 0:00.04 /usr/libexec/getty std.57600 ttyd1</programlisting>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="dumb-terminal">
+ <para>How can I connect a dumb terminal to my FreeBSD
+ box?</para>
+ </question>
+
+ <answer>
+ <para>If you are using another computer as a terminal into your
+ FreeBSD system, get a null modem cable to go between the two
+ serial ports. If you are using an actual terminal, see its
+ accompanying instructions.</para>
+
+ <para>Then, modify
+ <filename>/etc/ttys</filename> (see &man.ttys.5;), like above. For example, if you are
+ hooking up a WYSE-50 terminal to the fifth serial port,
+ use an entry like this:</para>
+
+ <programlisting>ttyd4 "/usr/libexec/getty std.38400" wyse50 on secure</programlisting>
+
+ <para>This example shows that the port on
+ <devicename>/dev/ttyd4</devicename> has a wyse50 terminal
+ connected at 38400 bps with no parity
+ (<literal>std.38400</literal> from
+ <filename>/etc/gettytab</filename>, see &man.gettytab.5;) and <username>root</username> logins are
+ allowed (<literal>secure</literal>).</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="cannot-tip">
+ <para>Why can I not run <command>tip</command> or
+ <command>cu</command>?</para>
+ </question>
+
+ <answer>
+ <para>On your system, the programs &man.tip.1;
+ and &man.cu.1;
+ are probably executable only by
+ <username>uucp</username>
+ and group <groupname>dialer</groupname>. You can use the group
+ <groupname>dialer</groupname> to control who has access to your
+ modem or remote systems. Just add yourself to group
+ dialer.</para>
+
+ <para>Alternatively, you can let everyone on your system
+ run &man.tip.1; and &man.cu.1; by
+ typing:</para>
+
+ <screen>&prompt.root; <userinput>chmod 4511 /usr/bin/cu</userinput>
+&prompt.root; <userinput>chmod 4511 /usr/bin/tip</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="hayes-unsupported">
+ <para>My stock Hayes modem is not supported---what
+ can I do?</para>
+ </question>
+
+ <answer>
+ <para>Actually, the man page for &man.tip.1; is
+ out of date. There is a generic Hayes dialer already built in.
+ Just use <literal>at=hayes</literal> in your
+ <filename>/etc/remote</filename> (see &man.remote.5;) file.</para>
+
+ <para>The Hayes driver is not smart enough to recognize some of
+ the advanced features of newer modems---messages like
+ <literal>BUSY</literal>, <literal>NO DIALTONE</literal>, or
+ <literal>CONNECT 115200</literal> will just confuse it. You
+ should turn those messages off when you use &man.tip.1;
+ (using <literal>ATX0&amp;W</literal>).</para>
+
+ <para>Also, the dial timeout for &man.tip.1; is 60
+ seconds. Your modem should use something less, or else tip
+ will think there is a communication problem. Try
+ <literal>ATS7=45&amp;W</literal>.</para>
+
+ <para>Actually, as shipped &man.tip.1; does not yet
+ support it fully. The solution is to edit the file
+ <filename>tipconf.h</filename> in the directory
+ <filename>/usr/src/usr.bin/tip/tip</filename>. Obviously you
+ need the source distribution to do this.</para>
+
+ <para>Edit the line <literal>#define HAYES 0</literal>
+ to <literal>#define HAYES 1</literal>. Then
+ <command>make</command> and <command>make install</command>.
+ Everything works nicely after that.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="direct-at">
+ <para>How am I expected to enter these AT commands?</para>
+ </question>
+
+ <answer>
+ <para>Make what is called a <quote>direct</quote> entry in your
+ <filename>/etc/remote</filename> file (see &man.remote.5;). For example, if your modem is hooked
+ up to the first serial port, <devicename>/dev/cuaa0</devicename>,
+ then put in the following line:</para>
+
+ <programlisting>cuaa0:dv=/dev/cuaa0:br#19200:pa=none</programlisting>
+
+ <para>Use the highest bps rate your modem supports in the br
+ capability. Then, type
+ <command>tip <devicename>cuaa0</devicename></command> (see &man.tip.1;)
+ and you will be connected to your modem.</para>
+
+ <para>If there is no <devicename>/dev/cuaa0</devicename> on your
+ system, do this:</para>
+
+ <screen>&prompt.root; <userinput>cd /dev</userinput>
+&prompt.root; <userinput>sh MAKEDEV cuaa0</userinput></screen>
+
+ <para>Or use cu as <username>root</username> with the following command:</para>
+
+ <screen>&prompt.root; <userinput>cu -l<replaceable>line</replaceable> -s<replaceable>speed</replaceable></userinput></screen>
+
+ <para>with <replaceable>line</replaceable> being the serial port (e.g.
+ <devicename>/dev/cuaa0</devicename>) and <replaceable>speed</replaceable> being the speed
+ (e.g.<literal>57600</literal>). When you are done entering
+ the AT commands hit <literal>~.</literal> to exit.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="gt-failure">
+ <para>Why does the <literal>&lt;@&gt;</literal> sign for the pn
+ capability not work?</para></question><answer>
+
+ <para>The <literal>&lt;@&gt;</literal> sign in the phone number
+ capability tells tip to look in
+ <filename>/etc/phones</filename> for a phone number. But the
+ <literal>&lt;@&gt;</literal> sign is also a special character
+ in capability files like <filename>/etc/remote</filename>.
+ Escape it with a backslash:</para>
+
+ <programlisting>pn=\@</programlisting>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="dial-command-line">
+ <para>How can I dial a phone number on the command
+ line?</para>
+ </question><answer>
+
+ <para>Put what is called a <quote>generic</quote> entry in your
+ <filename>/etc/remote</filename> file (see &man.remote.5;). For example:</para>
+
+ <programlisting>tip115200|Dial any phone number at 115200 bps:\
+ :dv=/dev/cuaa0:br#115200:at=hayes:pa=none:du:
+tip57600|Dial any phone number at 57600 bps:\
+ :dv=/dev/cuaa0:br#57600:at=hayes:pa=none:du:</programlisting>
+
+ <para>Then you can do something like <command>tip -115200
+ 5551234</command>. If you prefer &man.cu.1;
+ over
+ &man.tip.1;, use a generic cu entry:</para>
+
+ <programlisting>cu115200|Use cu to dial any number at 115200bps:\
+ :dv=/dev/cuaa1:br#57600:at=hayes:pa=none:du:</programlisting>
+
+ <para>and type <command>cu 5551234 -s 115200</command>.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="set-bps">
+ <para>Do I have to type in the bps rate every time I do
+ that?</para>
+ </question><answer>
+
+ <para>Put in an entry for <literal>tip1200</literal> or
+ <literal>cu1200</literal>, but go ahead and use whatever bps
+ rate is appropriate with the br capability.
+ &man.tip.1;
+ thinks a good default is 1200 bps which is why it looks for
+ a <literal>tip1200</literal> entry. You do not have to use 1200
+ bps, though.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="terminal-server">
+ <para>How can I more easily access a number of hosts through a
+ terminal server?</para>
+ </question>
+
+ <answer>
+ <para>Rather than waiting until you are connected and typing
+ <literal>CONNECT <replaceable>host</replaceable></literal>
+ each time, use tip's <literal>cm</literal> capability. For
+ example, these entries in
+ <filename>/etc/remote</filename> (see &man.remote.5;):</para>
+
+ <programlisting>pain|pain.deep13.com|Forrester's machine:\
+ :cm=CONNECT pain\n:tc=deep13:
+muffin|muffin.deep13.com|Frank's machine:\
+ :cm=CONNECT muffin\n:tc=deep13:
+deep13:Gizmonics Institute terminal server:\
+ :dv=/dev/cuaa2:br#38400:at=hayes:du:pa=none:pn=5551234:</programlisting>
+
+ <para>will let you type <command>tip pain</command> or
+ <command>tip muffin</command> to connect to the hosts
+ <hostid>pain</hostid> or <hostid>muffin</hostid>; and
+ <command>tip deep13</command> to get to the terminal
+ server.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="tip-multiline">
+ <para>Can tip try more than one line for each site?</para>
+ </question>
+
+ <answer>
+ <para>This is often a problem where a university has several
+ modem lines and several thousand students trying to use
+ them...</para>
+
+ <para>Make an entry for your university in
+ <filename>/etc/remote</filename> (see &man.remote.5;) and use <literal>&lt;\@&gt;</literal> for
+ the <literal>pn</literal> capability:</para>
+
+ <programlisting>big-university:\
+ :pn=\@:tc=dialout
+dialout:\
+ :dv=/dev/cuaa3:br#9600:at=courier:du:pa=none:</programlisting>
+
+ <para>Then, list the phone numbers for the university in
+ <filename>/etc/phones</filename> (see &man.phones.5;):</para>
+
+ <programlisting>big-university 5551111
+big-university 5551112
+big-university 5551113
+big-university 5551114</programlisting>
+
+ <para>&man.tip.1;
+ will try each one in the listed order, then give
+ up. If you want to keep retrying, run &man.tip.1;
+ in a while loop.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="multi-controlp">
+ <para>Why do I have to hit CTRL+P twice to send CTRL+P
+ once?</para>
+ </question>
+
+ <answer>
+ <para>CTRL+P is the default <quote>force</quote> character,
+ used to tell &man.tip.1;
+ that the next character is literal data. You can set the
+ force character to any other character with the
+ <literal>~s</literal> escape, which means <quote>set a
+ variable</quote>.</para>
+
+ <para>Type <literal>~sforce=<replaceable>single-char
+ </replaceable></literal> followed by a newline.
+ <replaceable>single-char</replaceable> is any single character.
+ If you leave out <replaceable>single-char</replaceable>,
+ then the force character is the nul character, which you can
+ get by typing CTRL+2 or CTRL+SPACE. A pretty good value for
+ <replaceable>single-char</replaceable> is SHIFT+CTRL+6, which
+ I have seen only used on some terminal servers.</para>
+
+ <para>You can have the force character be whatever you want by
+ specifying the following in your
+ <filename>$HOME/.tiprc</filename> file:</para>
+
+ <programlisting>force=<replaceable>single-char</replaceable></programlisting>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="uppercase">
+ <para>Why is everything I type suddenly in UPPER CASE?</para>
+ </question>
+
+ <answer>
+ <para>You must have pressed CTRL+A, &man.tip.1;
+ <quote>raise character</quote>, specially
+ designed for people with broken caps-lock keys. Use
+ <literal>~s</literal> as above and set the variable
+ <quote>raisechar</quote> to something reasonable. In fact,
+ you can set it to the same as the force character, if you
+ never expect to use either of these features.</para>
+
+ <para>Here is a sample .tiprc file perfect for Emacs users who
+ need to type CTRL+2 and CTRL+A a lot:</para>
+
+ <programlisting>force=^^
+raisechar=^^</programlisting>
+
+<para>The ^^ is SHIFT+CTRL+6.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="tip-filetransfer">
+ <para>How can I do file transfers with
+ <command>tip</command>?</para>
+ </question>
+
+ <answer>
+ <para>If you are talking to another Unix system, you can send
+ and receive files with <literal>~p</literal> (put) and
+ <literal>~t</literal> (take). These commands run
+ &man.cat.1; and
+ &man.echo.1; on the remote system to accept and send files.
+ The syntax is:</para>
+
+ <programlisting>~p &lt;local-file&gt; [&lt;remote-file&gt;]
+~t &lt;remote-file&gt; [&lt;local-file&gt;]</programlisting>
+
+ <para>There is no error checking, so you probably should use
+ another protocol, like zmodem.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="zmodem-tip">
+ <para>How can I run zmodem with
+ <application>tip</application>?</para>
+ </question>
+
+ <answer>
+ <para>First, install one of the zmodem programs from the
+ ports collection (such as one of the two from the comms
+ category, <application>lrzsz</application> or
+ <application>rzsz</application>.</para>
+
+ <para>To receive files, start the sending program on the
+ remote end. Then, press enter and type
+ <literal>~C rz</literal> (or <literal>~C lrz</literal> if you
+ installed <application>lrzsz</application>) to begin
+ receiving them locally.</para>
+
+ <para>To send files, start the receiving program on the remote
+ end. Then, press enter and type
+ <literal>~C sz <replaceable>files</replaceable></literal>
+ (or <literal>~C lsz <replaceable>files</replaceable></literal>)
+ to send them to the remote system.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="cannot-find-serial">
+ <para>Why does FreeBSD not find my serial ports, even
+ when the settings are correct?</para>
+ </question>
+
+ <answer>
+ <para>Motherboards and cards with Acer UARTs do not probe
+ properly under the FreeBSD sio probe. Obtain a patch from
+ <ulink url="http://www.lemis.com/serial-port-patch.html">
+ www.lemis.com</ulink> to fix your problem.</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+ <chapter id="misc">
+ <title>其它各式各樣的問題</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="more-swap">
+ <para>為甚麼 FreeBSD 用的置換(swap)空間比 Linux 多?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD僅是看起來置換空間(swap)用的比Linux多而已。在事實上,
+ 並不然。主要的差異是在於,FreeBSD積極的將閒置無用的主記憶體內容
+ 推入置換空間(swap)中,以使得主記憶體可以更為有效率的被使用。而
+ Linux的策略是將置換空間(swap)用來作為解決記憶體問題的最終手段。
+ 較頻繁的使用置換空間(swap)。是一種更有效率的使用主記憶體的手段。
+ </para>
+
+ <para>註:當一方面FreeBSD積極的使用置換空間(swap)的同時,你必需注
+ 意到,FreeBSD並不會任意的將所有的東西都推入置換空間(swap)中。如此,
+ 你才不會在一夜宿醉起床後發現,整個系統都被倒進了置換空間(swap)之中。
+ </para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="top-freemem">
+ <para>即使我只有運行少數程式,為什麼 <command>top</command> 顯示出
+ 來的剩餘記憶體還是很少?</para>
+ </question>
+
+ <answer>
+ <para>簡單的答案是,所有未使用到的閒置記憶體都是被浪費的記憶體,
+ 任何未被你的程式所利用到的記憶體將被核心(kernel)用來當
+ 作磁碟快取(disk cache)。而這種記憶體被 &man.top.1; 標記為
+ <literal>閒置的(Inact)</literal>,<literal>快取(Cache)</literal>,
+ 以及 <literal>緩衝區(Buf)</literal>,並負責在各個不同的位置負責
+ 暫存資料。被暫存(cached)的資料代表系統不需要去存取較慢的磁碟裝置
+ 就可以得到資料,如此,可以提升系統的效能。總而言之,&man.top.1;
+ 顯示出較少的 <literal>閒置(Free)</literal> 記憶體是好的,只要顯示
+ 出來的值不是 <literal>非常</literal> 的低。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="aout-elf">
+ <para>為甚麼要用(甚麼是) a.out 和 ELF 執行檔格式?</para>
+ </question>
+
+ <answer>
+ <para>要了解為什麼Freebsd使用 <filename>ELF</filename> 格式,你有必
+ 要先認識一下三種在目前 Unix 系統中最被廣泛應用到的執行檔格式:
+ </para>
+
+ <note>
+ <para>在 FreeBSD 3.x 之前,FreeBSD 使用 a.out 格式。</para>
+ </note>
+
+ <itemizedlist>
+ <listitem>
+ <para>&man.a.out.5;</para>
+
+ <para>這是最早,同是也是 <quote>最典型</quote> 的Unix目的檔
+ 格式。這種格式的檔案使用一種短且緊密的檔頭,同時,伴隨著一
+ 個魔術數字用來辨識格式。(參考 &man.a.out.5; 有更多詳細的說
+ 明)。它包含有三個節區: .text .data 及 .bss 加上一個符號表
+ 及字串表。</para>
+ </listitem>
+
+ <listitem>
+ <para><acronym>COFF</acronym></para>
+
+ <para>SVR3目的檔格式。檔頭包含了一個節區表,所以可以具備比
+ .text .data .bss 還多的節區。</para>
+ </listitem>
+
+ <listitem>
+ <para><acronym>ELF</acronym></para>
+
+ <para>ELF為 <acronym>COFF</acronym> 格式的後繼者,主要的特徵為
+ 可以具有複數節區段,並可以使用32-bits或是64-bits的數值。
+ 主要的缺點為: <acronym>ELF</acronym> 格式是在每個系統中只
+ 會有一種 ABI 的假設為前題被設計出來的。但是,在事實上,這個
+ 假設錯的離譜。因為,縱使在商用的 SYSV 世界裡,也至少有 SVR4,
+ Solaris 和 SCO 三種 ABI。</para>
+
+ <para>譯註:ABI(Application Binary Interface)。如果一定要翻譯,
+ 就叫它 <emphasis>應用程式二進位介面</emphasis> 好了。 ABI被發
+ 展出來的用意,是為了促使在相同CPU所發展出來的應用程式,能夠
+ 在不同的系統上,作到二元檔(Binary Code)相容。比方說,
+ <acronym>Sun</acronym> 所提出的 <acronym>Solaris ABI</acronym>
+ ,保證執行檔能夠在相同 CPU 的 Solaris 系統上執行,另一個例子是
+ Windows 系統。同屬於 Intel x86 版本的執行檔能夠自由的在Windows
+ 9x/me及Windows NT/2k/XP之間執行。</para>
+
+ <para>FreeBSD提供一個公用程式將程式所需的ABI資訊烙上,藉此試著
+ 去解決這個問題。請參考 &man.brandelf.1; 以取得更多資訊。i
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>FreeBSD 來自 <quote>傳統</quote> 的陣營。在傳統上,FreeBSD都
+ 使用 &man.a.out.5; 格式,這樣的技術在好幾代的 BSD 都被證明是可靠的。
+ 雖然,在FreeBSD上可以建立以及正確的執行原生 <acronym>ELF</acronym>
+ 格式檔案(包含核心)。然而, FreeBSD在一開始反對將預設格式轉換為 ELF,
+ 為什麼呢?當Linux開始痛苦的轉換至 <acronym>ELF</acronym> 格式時,
+ 並非是為了要逃離 <filename>a.out</filename> 格式。相反的,這是因
+ 為之前 Linux的共享函式庫(shared libraries)採用以跳躍表格
+ (jump-table)為基礎的技術去設計。這是一種讓發展者感到困擾,且非常
+ 難以使用,不具足夠彈性的方法。既然,已經存在的
+ <acronym>ELF</acronym> 工具提供了共享函式庫(shared libraries)的解
+ 決方案,而且,那看起來是個 <quote>前衛的方法</quote>,因此,所需
+ 的轉換代價就可接受因而轉換。</para>
+
+ <para>在FreeBSD的狀況中,我們的共享函式庫(shared libraries)機制和
+ <application>SunOS</application> 的型式非常相近,且易於使用。然而,
+ 從 3.0 開始,FreeBSD 正式將 <acronym>ELF</acronym> 改為預設格式。
+ 雖然,<filename>a.out</filename> 格式依舊如以往般的好,但是,我們
+ 編譯工具的撰寫者,GNU 的成員,他們中止了對
+ <filename>a.out</filename> 格式的支援與維護。在這種狀況下,迫使
+ 我們必須自行維護另一份版本的 compiler 和 linker,也使得我們無法
+ 從最新的 GNU 發展成果中獲得好處。此外,對 ISO-C++ 的需求,尤其是
+ 建構子(constructors)和解構子(destructors),也帶動未來版本中對
+ <acronym>ELF</acronym> 的原生支援。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="binary-formats">
+ <para>是的, 但是, 為什麼會有這麼多不同格式的執行檔存在呢?</para>
+ </question>
+
+ <answer>
+ <para>在黑暗而遙遠的過去,僅有簡陋的硬體存在。而因為硬體簡陋,當然也
+ 只能執行小而簡單的系統。a.out 格式是基於那個時代所需要,而被創造
+ 出來的(例如像PDP-11)。在這之後,許多人試著將 Unix 移植到其他平台
+ 時,他們也保留了 a.out 格式的執行檔。因為,這對早期的 Motorola 68k,
+ VAXen 之類的系統已經足夠使用了。</para>
+
+ <para>然而,人並不會滿足於現狀。一些聰明的硬體工程師想到了,如果能
+ 讓軟體多處理一些事,那 CPU 的電晶體數就能少一點,並且跑得更快。要
+ 在這種新式的硬體上工作(現在稱為RISC),<filename>a.out</filename>
+ 這種格式就不合適了。基於這樣的現實所需,更多的執行檔格式被發展出
+ 來,以提供比簡單且受到許多限制的 <filename>a.out</filename> 格式
+ 更好的效能。比方像是 <acronym>COFF</acronym>,
+ <acronym>ECOFF</acronym>,已及一些較不為人所周知的格式紛紛被創造
+ 出來。但是,這些格式都已達到各自的極限,直到有一天
+ <acronym>ELF</acronym> 的出現。</para>
+
+ <para>此外,當程式的體積越來越大,而磁碟空間和主記憶體相對來說都較
+ 小時,共享函式庫(shared libraries)的觀念被發展出來了。在這同時,
+ 虛擬記憶體系統(VM System)也變得越來越精巧。當每一種進步都在
+ <filename>a.out</filename>格式上被發展出來時,它的可用性也同時變
+ 得越來越低。另外,人們還希望程式能在執行期間動態載入,或是將已經
+ 執行過且沒有用的初始化程式碼丟棄,藉以節省更多的記憶。程式語言在
+ 這個時期也便得更精巧,人們也希望在 main 之前自動的執行更多的東西。
+ 因此,許多繁雜且另人嘆為觀止的技巧被用在 <filename>a.out</filename>
+ 格式上去解決這些問題。但是,由於 <filename>a.out</filename> 格式
+ 先天的限制,要解決這些問題必需付出更多的代價及時間成本,並讓程式
+ 的複雜度大為提升。而 <acronym>ELF</acronym> 格式可以一舉解決這一
+ 切問題。但是,要將整個系統從根本轉換過去,將會有不短的陣痛期,因
+ 此, <acronym>ELF</acronym>格式將會有一陣子與
+ <filename>a.out</filename> 並存。</para>
+
+ <para>然而,隨著時間的過去,FreeBSD的 build tools 演化成平行的兩個
+ 支線(尤其是組譯器和載入器)。FreeBSD這條路加進了共享函式庫
+ (shared libraries)並修正了一些錯誤。而原來發展這些程式的 GNU 成員
+ 則為了因應現況,重寫了這些程式,以更簡單的方式對跨平台編譯
+ (building cross compilers),以及多種格式
+ (plugging in different formats) 作出了支援。許多人想作出以 FreeBSD
+ 為目的平台的跨平台編譯器。但不幸的是,FreeBSD 的 as 和 ld 不能作
+ 這項工作。新的 GNU 工具程式加入了跨平台編譯 (Cross Compiler),
+ <acronym>ELF</acronym>格式支援,共享函式庫(shared libraries),
+ C++ 的擴充... 等等。此外,許多廠商以 <acronym>ELF</acronym> 格式
+ 發行其產品,如果這些東西能在 FreeBSD 上執行的話當然是最好的。既然,
+ 能夠執行 <acronym>ELF</acronym> 格式的執行檔了,為什麼還須要
+ <filename>a.out</filename> 呢?它已經是一匹垂垂老矣的馬了,在竭力
+ 盡忠的奉獻這麼多年之後,該是讓它在牧場肥沃的草地上好好休息的時候
+ 了。</para>
+
+ <para><acronym>ELF</acronym> 格式比 a.out 具有更良好的展現能力,並
+ 且在底層系統中具有更多的可擴展性。<acronym>ELF</acronym> 工具程式
+ 更容易被維護,且提供跨平台編譯的支援,這一點對很多人來說是很重要
+ 的。<acronym>ELF</acronym> 格式可能比 a.out 慢一點,但是其差異非
+ 常難測量出來。這兩者間還有許多細節上的不同,比方說分頁對應的方式,
+ 程式碼初始化的方法...等等。這些並不是很重要,但是,兩者就是不同。
+ 以後,GENERIC 核心(kernel)將會移除對 <filename>a.out</filename>
+ 格式。當不在有執行傳統 <filename>a.out</filename> 程式的須要時,
+ 將會從核心(kernel)中移除。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="chmod-symlinks">
+ <para>為甚麼chmod不會改變符號連結(symlink)的存取權限?</para>
+ </question>
+
+ <answer>
+ <para>Symlinks 本身並沒有存取權限,同時,在預設的狀況下,
+ &man.chmod.1; 將不會跟隨著 symlinks 去改便目標檔案的存取權限。因此,
+ 如果你有一個檔案 <filename>foo</filename>,同時,有一個 symlink
+ <filename>bar</filename> 指向這個檔案,以下這個命令將永遠會成功
+ 的被執行。</para>
+
+ <screen>&prompt.user; <userinput>chmod g-w bar</userinput></screen>
+
+ <para>然而,在 <filename>foo</filename> 上的存取權限將不會被改
+ 變。</para>
+
+ <para>你必需使用 <option>-H</option> 或是將 <option>-L</option>
+ 與 <option>-R</option> 選項一起使用,參考 &man.chmod.1; 以及
+ &man.symlink.7; 以取得更多的資訊。</para>
+
+ <warning>
+ <para>使用選項 <option>-R</option> 會讓 &man.chmod.1; 以
+ <acronym>遞迴(RECURSIVE)</acronym> 的方式工作。當你把
+ &man.chmod.1; 用在目錄或是連結到目錄的符號連結時更要小心。
+ 如果你要改變一個符號連結參考到的目錄之存取權限 &man.chmod.1; ,
+ 且注意不要加上任何選項,並且在 symlink 的結尾加上斜線
+ (<filename>/</filename>)。舉例來說,如果
+ <filename>foo</filename> 連結到目錄 <filename>bar</filename>,
+ 而你要更改 <filename>foo</filename> (實際上是
+ <filename>bar</filename>),那就使用:</para>
+
+ <screen>&prompt.user; <userinput>chmod 555 foo/</userinput></screen>
+
+ <para>結尾的斜線會使得 &man.chmod.1; 改變
+ <filename>foo</filename> 所指向的目錄 <filename>bar</filename>
+ 的權限。</para>
+ </warning>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="login-8char">
+ <para>為什麼在 FreeBSD 2.2.x 及更早的版本中,登入名稱(login names)
+ 被限制在八個字元以下呢?</para>
+ </question>
+
+ <answer>
+ <para>你可能認為修改 <literal>UT_NAMESIZE</literal> 後在重新編譯整個
+ 系統是很容易的事。而且在這之後,每件事都可以運作的很好。不幸的是,
+ 有許多的程式和工具(包含系統工具)把數字寫死在程式裡頭(並非總是
+ <literal>8</literal> 或 <literal>9</literal>,有時可能是古怪的
+ <literal>15</literal> 或 <literal>20</literal>)。這不僅僅是會將
+ 你的系統記錄檔弄壞而已(來自於變動長度和固定長度記錄的差異),同時
+ 也會破壞 Sun 的 NIS Client 的運作。同時,和其他的Unix系統之間也
+ 有可能會產生未知的問題。</para>
+
+ <para>在FreeBSD 3.0 及之後的版本,帳號的最大長度增加到16個字元,
+ 同時,那些將長度寫死的程式也被找出來並作了適當的修正。正因為影響
+ 系統的範圍很廣,所以直到3.0版之後才算大致修正完成。</para>
+
+ <para>如果你有自信在出問題的時後能自行解決,你可以利用下面的方法讓
+ 較早期的版本支援較長的帳號。首先,修改
+ <filename>/usr/include/utmp.h</filename> 中的UT_NAMESIZE。
+ 然後,你必須把 <filename>/usr/include/sys/param.h</filename>
+ 中的 MAXLOGNAME 改成跟 UT_NAMESIZE 相同。最後,如果你是從原始程
+ 式建立系統, 別忘了 /usr/include 每次都會被更新。
+ 修改 /usr/src/.. 中適當的檔案。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="dos-binaries">
+ <para>我能在FreeBSD下執行DOS程式嗎?</para>
+ </question>
+
+ <answer>
+ <para>是的,自3.0版起你可以使用BSDI的
+ <application>doscmd</application> DOS 模擬器,如果你對這個東西
+ 有興趣,或是想加入發展行列,請寄一封電子郵件到 &a.emulation; 。
+ </para>
+
+ <para>對於3.0之前的系統,在 ports 中有一套軟體可以模儗 8088,並提
+ 供足夠的BIOS中斷服務以執行DOS文字模式的程式,這套軟體叫做
+ <application>pcemu</application>,同時,運行它須要
+ X Windows(由XFree86提供)。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="translation">
+ <para>如果要把FreeBSD文件翻譯成我的母語,我需要作什麼?</para>
+ </question>
+
+ <answer>
+ <para>參閱FreeBSD文件中的 <ulink
+ url="../fdp-primer/translations.html">翻譯常見問答</ulink>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="freebsd-mail-bounces">
+ <para>為什麼我寄到 FreeBSD.org 相關地址的電子郵件都被退回了呢?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD.org 的郵件系統對於進來的郵件採取嚴格的檢查,並且退回
+ 所有設定不正確,或是潛在的垃圾郵件。你的郵件被退回可能是因為下列
+ 原因所引起:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>這封電子郵件來自已知的垃圾郵件區域或是IP中。</para>
+
+ <para>FreeBSD郵件伺服器將拒絕接收已知的垃圾郵件來源的電子郵件。
+ 如果提供你網路服務的公司或是網域中有產生過垃圾郵件或是有垃圾
+ 郵件轉播站,請你換一個服務提供者,或是乾脆放棄。</para>
+ </listitem>
+
+ <listitem>
+ <para>電子郵件的本文僅有HTML。</para>
+
+ <para>郵件應該已純文字格式發送,請設定你的電子郵件軟體送出純文
+ 字格式。</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD的郵件處理程式無法由IP反查送件主機的IP。</para>
+
+ <para>設置 DNS 反查是接受一台主機郵件的一個標準要求,請為您的郵件
+ 主機設置 DNS 反查。許多提供家庭網路服務 (DSL,cable,dialup 等)
+ 的公司並不提供這樣的服務。在這種情況下,請透過網路服務提供者的
+ 郵件伺服器送出您的電子郵件。</para>
+ </listitem>
+
+ <listitem>
+ <para>在 SMTP 使用 EHLO/HELO 命令時所給予的 hostname 無法被解析到
+ 一個 IP 位置。</para>
+
+ <para>在郵件被接受以前,一個充分合格,且可被解析的主機名稱在
+ SMTP 協定的對談中是必要的。如果你沒有在 DNS 伺服器中登記你
+ 的主機名稱,請透過網路服務提供者的郵件伺服器送出您的電子郵
+ 件。</para>
+ </listitem>
+
+ <listitem>
+ <para>你的訊息中夾帶著一個 message ID 以 <quote>localhost</quote>
+ 字串結束。</para>
+
+ <para>某些郵件軟體產生某些不正確的 message ID,這將不被接受。
+ 你必需更改設定讓你的郵件軟體產生正確的 message ID,如果這無
+ 法解決,考慮說服你的郵件軟體作者更新程式以處理這個問題。</para>
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="free-account">
+ <para>我可以在哪裡找到一個免費的FreeBSD帳號?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD的伺服器本身不提供任何對外的服務,其他的單位中,
+ 有人提供開放的 Unix 系統服務。其中有些可能要收取些許費用。</para>
+
+ <para><ulink url="http://www.arbornet.org/">Arbornet, Inc</ulink>,
+ 也被稱為 M-Net,自 1983 年起就開始提供 Unix 系統服務。一開始,
+ 他們使用 Altos 並執行 System III。他們在 1991 年轉換系統成為
+ BSD/OS。在 2000 年六月,他們再度更換成為 FreeBSD。M-Net 能讓使
+ 用者透過 SSH 及 telnet 連線到主機,並提供完整的 FreeBSD 軟體以
+ 供使用。然而,M-Net 作為一個非盈利組織運行,存取權只限於成員和
+ 贊助者,M-Net 也提供 BBS 系統和網路聊天服務。</para>
+
+ <para><ulink url="http://www.grex.org/">Grex</ulink> 提供了非常
+ 類似 M-Net 的服務,包括了 BBS 系統和網路聊天。然而,機器是使用
+ Sun 4M,並執行 SunOS。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="sup-define">
+ <para>什麼是 <command>sup</command>,我該如何使用它?</para>
+ </question>
+
+ <answer>
+ <para><ulink url="http://www.FreeBSD.org/cgi/ports.cgi?^sup">
+ SUP</ulink> 的意思是 Software Update Protocol,由 CMU 發展,
+ 用來維持整個發展的同步。我們利用它保持遠端的站台和原始站台之間
+ 的同步工作。</para>
+
+ <para>然而,SUP 在頻寬的使用上並不太友善,同時,目前也不再使用了。
+ 目前建議維持原始碼同步更新的方法是
+ <ulink url="../handbook/synching.html#CVSUP">CVSup</ulink>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="daemon-name">
+ <para>這個可愛的小紅人叫作什麼?</para>
+ </question>
+
+ <answer>
+ <para>似乎,他並沒有一個正式的名字,姑且就稱其為
+ <quote>BSD 小惡魔</quote> 吧。如果你執意要使用一個名字。那就叫他
+ <quote>小動物(beastie)</quote> 吧。註:<quote>beastie</quote>
+ 在讀音上跟 <quote>BSD</quote> 很接近。</para>
+
+ <para>你可以在BSD小惡魔的 <ulink
+ url="http://www.mckusick.com/beastie/index.html">主頁</ulink>
+ 上取得更多的資訊。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="use-beastie">
+ <para>我能使用 BSD 小惡魔圖案嗎?</para>
+ </question>
+
+ <answer>
+ <para>也許吧,我也不確定。BSD小惡魔圖案的版權是屬於馬歇爾蘇格蘭教會的
+ Marshall Kirk McKusick 所擁有。你可以試著去查看網頁<ulink
+ url="http://www.mckusick.com/beastie/mainpage/copyright.html">關於BSD小惡魔肖像</ulink>
+ 以取得更詳細的使用細節。</para>
+
+ <para>總而言之,如果你純粹為了自己想要鑑賞,那麼,你可以自由的使用肖像。如果你是個人使用,只要情況適當,應該都會被許可。
+ 如果你想在商業上使用,則你必需聯繫蘇格蘭教會的 Kirk McKusick 以取得許可。
+ 如果你需要更進一步詳細的資訊,請參考 <ulink
+ url="http://www.mckusick.com/beastie/index.html">BSD小惡魔的首頁</ulink>。
+ </para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="daemon-images">
+ <para>你有任何的 BSD 小惡魔圖案可以讓我使用嗎?</para>
+ </question>
+
+ <answer>
+ <para>你可以在 <filename>/usr/share/examples/BSD_daemon/</filename> 找到 Xfig 及 eps 兩種格式的圖檔。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="glossary">
+ <para>我在文件、郵遞論壇上,常會看到一些縮寫字、技術字彙,這些可以去哪邊查呢?</para>
+ </question>
+
+ <answer>
+ <para>請參閱 <ulink
+ url="&url.books.handbook;/freebsd-glossary.html">
+ &os; 字彙表</ulink>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="bikeshed-painting">
+ <para>為什麼我該在意腳踏車車棚的顏色?</para>
+ </question>
+
+ <answer>
+ <para>最短最短的答案是:『不用在意』。稍微長一點的答案是:『雖然你有能力自己去建造一座腳踏車車棚,但是,
+ 這不代表因為你不喜歡現在這個車棚的顏色,就要中止他的建築。』這個比喻的意思是,
+ 你不需要去爭論每一個細項特徵,只因為你有辦法去作它。
+ 某些人的評論是:『雜音的程度,與變化的複雜性是成反比』。</para>
+
+ <para>更長且較完整的答案是,在經過長時間爭論關於是否該將 &man.sleep.1;
+ 的秒參數移除,&a.phk;發表了一篇長論 <quote><ulink
+ url="http://www.FreeBSD.org/cgi/getmsg.cgi?fetch=506636+517178+/usr/local/www/db/text/1999/freebsd-hackers/19991003.freebsd-hackers">
+ 在青翠草地上的腳踏車車棚(任何顏色的)...</ulink></quote>。以下,僅摘要該則文章部分內容:</para>
+
+ <blockquote>
+ <attribution>&a.phk; on freebsd-hackers, October
+ 2, 1999</attribution>
+
+ <para><quote>什麼是關於這個腳踏車車棚?</quote> 部分的人這樣的詢問我。</para>
+
+ <para>這是一個非常長遠的故事,否則就是一個古老的故事。但是事實上,
+ 這個故事非常的短。C·諾斯科特·帕金森(C. Northcote Parkinson) 在 1960
+ 年代初期寫了一本書,書名為 <quote>Parkinson's Law(中文書名:升官有道-暴露上司心態之帕金森定律)</quote>
+ ,這本書包含了很多具有卓見的動態管理學。</para>
+
+ <para>[引述一點在這本書上的評論]</para>
+
+ <para>在這個被捲入腳踏車車棚案的特殊例子,主要的要素是核能發電場,我想,這足以說明這本書的年齡。</para>
+
+ <para>帕金森展示了該如何在董事會中贏得贊同去建造一座數百萬或甚至十億美元的核能發電場,
+ 但是,如果你想要去建造一座腳踏車車棚,你將會被糾纏在無窮無盡的討論之中。</para>
+
+ <para>他(帕金森)並解釋,這是因為一個核能發電場是這樣的廣闊,這樣的昂貴,並且這樣的複雜,
+ 以至於人們無法掌握它,而並非嘗試,他們急切的希望有人能夠幫他們處理並解決所有瑣碎的細項。
+ Richard P. Feynmann 給了一些有趣,且非常一針見血的論點,在他的書提到了 Los Alamos 的例子。</para>
+
+ <para>另一方面,任何人都能自己在週末組裝一座腳踏車車棚出來,並且仍有閒聊可以觀賞電視及玩遊戲。
+ 因此,無論你作了多麼完善的準備,也不管你提出的方案是多麼的妥當,某些人仍將抓住機會跑出來告訴你,
+ 他正在作同樣的事,正在付出努力,他就在 <emphasis>這裡</emphasis>。</para>
+
+ <para>在丹麥,我們稱這個叫作『虎死留皮』(setting your fingerprint)。這關係到你個人的驕傲和聲望,
+ 這關係到你是否可以指著某地後對著別人說:『這裡! 這是 <emphasis>我</emphasis> 作的。』
+ 這是政治人物很重要的一個特徵。但是,時機是大多數人民所賦與的。想想那些留在水泥地上的腳印吧。</para>
+ </blockquote>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+ <chapter id="funnies">
+ <chapterinfo>
+ <author>
+ <firstname>Edward</firstname>
+ <surname>Chuang</surname>
+ <affiliation>
+ <address><email>edwardc@firebird.org.tw</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>FreeBSD 冷笑話集</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="very-very-cool">
+ <para>How cool is FreeBSD?</para>
+ </question>
+
+ <answer>
+ <para>問:有人做過 FreeBSD 執行時的溫度測試嗎? 我知道 Linux
+ 比 DOS 涼,但沒聽人提過 FreeBSD,似乎很熱。</para>
+
+ <para>答:沒有,但是在味覺上有做過無數次測試。我們矇上自願受試者的
+ 眼睛,事先再給他們服用 250 毫克的 LSD-25 迷幻藥。35% 的受試者說
+ FreeBSD 嘗起來像橘子,而 Linux 則是紫色的榛樹果實。據我所知,沒
+ 有一組提到溫度上特別的差異。後來發現,有太多受試者在測試時夢遊走
+ 出房間影響到數據,最後只得放棄整個調查。我想大部份的受試者現在在
+ Apple 工作,繼 Drag and Drop 之後,研究全新的 <quote>Scratch and
+ Sniff</quote> 圖形界面。It's a funny old business we're in!</para>
+
+ <para>不開玩笑了,FreeBSD 和 Linux 都使用 <acronym>HLT</acronym>
+ (halt) 指令,可在系統閒置時降低電力的使用也減少了熱的產生。如果有設定 APM(Automatic Power Management)
+ ,FreeBSD 也可以讓 CPU 進入省電模式。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="letmeoutofhere">
+ <para>誰在我的記憶體插槽中沙沙作響??</para>
+ </question>
+
+ <answer>
+ <para>問:FreeBSD 編譯核心時有做甚麼 <quote>奇特</quote> 的事
+ 讓記憶體沙沙作響嗎?當編譯時(還有開機時確認軟碟後的短暫時間),
+ 也種似乎來自記憶體插槽的奇怪聲音。</para>
+
+ <para>答:是的!在 BSD 的文件中你會常常看到 <quote>背後靈</quote>,
+ 大部份的人都不知道那是一種實際存在的精神體 --- 掌控著你的電腦。
+ 你聽到的聲音是這些背後靈以高音口哨在溝通怎樣做許多的系統管理工
+ 作。</para>
+
+ <para>如果這些聲音很困擾你,來自 DOS 的
+ <command>fdisk /mbr</command> 就能擺脫,但如果有相反的效果
+ 也不要驚訝。事實上,如果在儀式中聽到 Bill Gates 恐怖的聲音從內
+ 建的喇叭傳來,馬上逃而且不要回頭! 從 BSD 背後靈不平衡的影響中
+ 解放,DOS 和 Windows 背後靈通常都能重新控制整台機器並對你的靈
+ 魂詛咒。如果有選擇,我想我寧願習慣奇怪的聲音。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="changing-lightbulbs">
+ <para>要幾個 FreeBSD hacker 才能換掉一個電燈泡?</para>
+ </question>
+
+ <answer>
+ <para>一千一百七十二個:</para>
+
+ <para>二十三個在 -current 上抱怨看不到光了;</para>
+
+ <para>四個宣稱這是設定上的問題,所以像這樣的 email 應該放在
+ -questions;</para>
+
+ <para>三個 submit PR,其中一個送錯到 doc 下,並且內容只
+ 有”這裡好暗”;</para>
+
+ <para>一個 commit 尚未測試的電燈泡,造成不能 buildworld,
+ 五分鐘後他把原來的燈泡換回來;</para>
+
+ <para>八個煽起 flame war,責怪送出 PR 的人沒有包括 patch;</para>
+
+ <para>五個埋怨 buildworld 爛掉了;</para>
+
+ <para>三十一個說 buildworld 可以用,不能用的人一定是 cvsup 的
+ 時機不對;</para>
+
+ <para>一個把換成新燈泡的 patch 丟到 -hackers 上;</para>
+
+ <para>一個說他三年前就做出了 patch,但送到 -current 後卻被忽略掉,
+ 所以他對整個 PR 系統有很不好的印象。此外,他也認為拿出的新燈泡無
+ 法反光;</para>
+
+ <para>三十七個咆哮說電燈泡不屬於基本系統的一部份,所以 committer
+ 不能不先諮詢整個 Community 的意見就這樣做下去。還有,-core
+ 到底和這件事有什麼關係?!</para>
+
+ <para>兩百人抱怨換燈泡之後,腳踏車棚的顏色變得好奇怪;</para>
+
+ <para>三個指出,用來換燈泡的 patch 不符合 &man.style.9; 的規定;</para>
+
+ <para>十七個埋怨拿出來的新燈泡為什麼是用 GPL;</para>
+
+ <para>五百八十六人陷入一場 flame war,在 GPL、BSD、MIT、NPL
+ 各個 license 和 FSF 某位不具名創辦人士個人衛生之間,比較彼此
+ 的優勢;</para>
+
+ <para>七個將這一串討論的不同部份分別移到 -chat 和 -advocacy;</para>
+
+ <para>就算提出的新燈泡比舊的暗,還是有一個把它 commit 進來;</para>
+
+ <para>兩個換回原先的燈泡,並且留下極為憤怒的 commit 訊息。他們認為
+ 與其讓 FreeBSD 用暗燈泡,還不如乾脆待在黑暗中算了;</para>
+
+ <para>四十六人對取消不用暗燈泡這件事大聲疾呼,要求 -core
+ 立刻提出澄清;</para>
+
+ <para>十一個要求換成小一點的電燈泡,以便未來 FreeBSD 如果移植到
+ 電子雞上後會更為方便;</para>
+
+ <para>七十三人抱怨 -hackers 和 -chat 上的 SNR,藉 unsubscribe
+ 來表示抗議;</para>
+
+ <para>十三個送出”unsubscribe”、”我要如何 unsubscribe”或”拜託把
+ 我從 list 名單中刪掉”,信的最後面則是一般由 majordomo 加上去
+ 的 footer;</para>
+
+ <para>當每個人忙於彼此叫罵時,有個傢伙趁沒人注意,把可以用的燈泡偷
+ 偷換上去;</para>
+
+ <para>三十一個指出如果用 TenDRA 編譯新的燈泡,會比舊的來得亮
+ 0.364%(雖然燈泡會被編譯成正六面體),所以 FreeBSD 內定的編譯器
+ 應該是 TenDRA,而不是 EGCS;</para>
+
+ <para>有個人說新燈泡缺乏美感;</para>
+
+ <para>九個人(包括原先送 PR 的人)問”什麼是 MFC?”;</para>
+
+ <para>五十七個抱怨自從換了燈泡後,兩個星期都沒有光出現。</para>
+
+ <para><emphasis>&a.nik; 補注:</emphasis></para>
+
+ <para><emphasis>剛看到時,我快笑翻了。</emphasis></para>
+
+ <para><emphasis>然後想到,”等一下,不是應該還有一個要將這些記在
+ list 上嗎?”</emphasis></para>
+
+ <para><emphasis>接著終於了解我的使命 :-)</emphasis></para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="dev-null">
+ <para>寫入 <filename>/dev/null</filename> 的資料跑到哪裡去了?</para>
+ </question>
+ <answer>
+ <para>在 CPU 中有一種特別的資料散熱器,利用排出散熱片/風扇組合時,
+ 轉換成熱能.這就是為什麼 CPU 冷卻日趨重要的原因;當人們使用更快
+ 的處理器時,他們變成不在乎有越來越多他們的資料都送進了
+ <filename>/dev/null</filename> ,而使的他們的 CPU 過熱.
+ 如果你刪除了 <filename>/dev/null</filename> (那將會有效的關閉
+ CPU 的資料散熱器) 你的 CPU 也許會降低工作溫度,但是你的系統將
+ 會很快的像是罹患了便秘伴隨著所有超出的資料開始變成行為不正常。
+ 如果你有快速的網路連線,你可以利用讀取
+ <filename>/dev/random</filename> 並將他隨意傳送至各處,
+ 來降低你 CPU 的溫度;然而你將陷入使你網路連線或
+ <filename>/</filename> 有過熱的風險或是惹惱你的 ISP,
+ 大部分的資料最終將會在他們的設備上轉換成熱,不過他們通常都擁有
+ 好的散熱,所以如果你做的不太過分,應該是沒什麼大不了的。</para>
+
+ <para><emphasis>Paul Robinson 補充:</emphasis></para>
+
+ <para>中文版 FAQ 注:以下短文屬於美式幽默,恐翻譯後造成語焉不詳,
+ 語意不通的情形,故保留原汁原味讓讀者自行品嚐。</para>
+
+ <para>There are other methods. As every good sysadmin knows,
+ it is part of standard practise to send data to the screen
+ of interesting variety to keep all the pixies that make up
+ your picture happy. Screen pixies (commonly mis-typed or
+ re-named as 'pixels') are categorised by the type of hat
+ they wear (red, green or blue) and will hide or appear
+ (thereby showing the colour of their hat) whenever they
+ receive a little piece of food. Video cards turn data into
+ pixie-food, and then send them to the pixies - the more
+ expensive the card, the better the food, so the better
+ behaved the pixies are. They also need constant simulation
+ - this is why screen savers exist.</para>
+
+ <para>To take your suggestions further, you could just throw
+ the random data to console, thereby letting the pixies
+ consume it. This causes no heat to be produced at all,
+ keeps the pixies happy and gets rid of your data quite
+ quickly, even if it does make things look a bit messy on
+ your screen.</para>
+
+ <para>Incidentally, as an ex-admin of a large ISP who
+ experienced many problems attempting to maintain a stable
+ temperature in a server room, I would strongly discourage
+ people sending the data they do not want out to the
+ network. The fairies who do the packet switching and
+ routing get annoyed by it as well.</para>
+ </answer>
+ </qandaentry>
+
+
+ <qandaentry>
+ <question id="pttlz">
+ <para>1993 年就有『make world』了?</para>
+ </question>
+
+ <answer>
+ <para>問:根據 jkh 的 <ulink
+ url="http://www.freebsd.org/cgi/cvsweb.cgi/src/Makefile.diff?r1=1.5;r2=1.6;f=h">
+ 這份 commit</ulink>,應該是 Aug 13 22:47:28 1994 UTC
+ 之後才會有 make world,怎麼會有在那之前會有呢?</para>
+
+ <para>答:根據 pttlz.bbs@ptt.cc (工蟻) 於 Apr 7 17:09:47 2008 CST 自稱:
+ 『make world 是我古早 (15 年前) 時玩 freebsd 時用的』,所以 1993 年就有
+ pttlz 的『make world』存在了,請注意人家可是自稱『15 年前』的長輩,
+ 請勿對長輩權威挑戰,謝謝!</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+ <chapter id="advanced">
+ <chapterinfo>
+ <author>
+ <firstname>En-Ran</firstname>
+ <surname>Zhou</surname>
+ <affiliation>
+ <address><email>zhouer@tfcis.org</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>進階主題</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="learn-advanced">
+ <para>如何能學習更多有關 FreeBSD 內部的東西?</para>
+ </question>
+
+ <answer>
+ <para>目前市面上還沒有探討作業系統內部的書是專為 FreeBSD 而寫
+ 的。然而,許多一般的 UNIX 知識都可以直接應用在 FreeBSD 上。附
+ 加一點,仍然有相關的書是專為 BSD 所寫的。</para>
+
+ <para>請參考 Handbook 的<ulink
+ url="../handbook/bibliography-osinternals.html">作業系統內部之參考書目</ulink>
+ 。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="how-to-contribute">
+ <para>如何能為 FreeBSD 出一份力?</para>
+ </question>
+
+ <answer>
+ <para>請參考這篇文章 <ulink
+ url="../../articles/contributing/article.html">Contributing
+ to FreeBSD</ulink> 來提供您的建議。如果您能幫忙那就更歡迎了!</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="define-snap-release">
+ <para>SNAP 和 RELEASE 是什麼?</para>
+ </question>
+
+ <answer>
+ <para>目前有三個活躍/半活躍的分支在 FreeBSD 的 <ulink
+ url="http://www.FreeBSD.org/cgi/cvsweb.cgi">CVS Repository</ulink>
+ (古早分支已經幾乎沒在更新了,因為通常只有三個活躍的發展分支):
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>RELENG_5</literal> 即
+ <emphasis>5-STABLE</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para><literal>RELENG_6</literal> 即
+ <emphasis>6-STABLE</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para><literal>HEAD</literal> 即
+ <emphasis>-CURRENT</emphasis> 也就是目前的
+ <emphasis>7.X-CURRENT</emphasis></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>與上面其他兩個分支相比,其實 <literal>HEAD</literal> 並不是真正
+ 的 branch tag,它只是個 symbolic constant,代表 <quote><emphasis>current
+ (尚未分支的發展中版本)</emphasis></quote>,通常我們會簡寫為 <quote>-CURRENT</quote>。</para>
+
+ <para>就現在而言,<quote>-CURRENT</quote> 就是指 7.X 的發展;
+ 而 <literal>5-STABLE</literal> 分支(<symbol>RELENG_5</symbol>)是在 2004 年 10 月從
+ <quote>-CURRENT</quote> fork 出來的;
+ <literal>6-STABLE</literal> 分支(<symbol>RELENG_6</symbol>)是在 2005 年 11 月從
+ <quote>-CURRENT</quote> fork 出來的。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="custrel">
+ <para>要怎麼作出自己的 release?</para>
+ </question>
+
+ <answer>
+ <para>請參照 <ulink
+ url="../../articles/releng/article.html">Release 工程</ulink>
+ 文章說明。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="makeworld-clobbers">
+ <para>為何 <command>make world</command> 會把原來裝的 binary 檔都換掉了?</para>
+ </question>
+
+ <answer>
+ <para>沒錯,就是這樣子。如名字所示,<command>make world</command>
+ 會重新編譯系統內建的每個 binary 檔,這樣在結束時就可確定有個一致且乾淨的環境(所以要花上好一段時間)。</para>
+
+ <para>在執行 <command>make world</command> 或
+ <command>make install</command> 時,如果有設
+ <literal>DESTDIR</literal> 這個環境變數,新產生的 binary 將會裝在
+ <literal>${DESTDIR}</literal> 下同樣的目錄樹中。但在某些修改
+ shared library 和重建 binary 的無特定情況下,這樣做可能會使
+ <command>make world</command> 失敗。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="cvsup-round-robin">
+ <para>Why isn't cvsup.FreeBSD.org a round robin DNS entry to
+ share the load amongst the various CVSup servers?</para>
+ </question>
+
+ <answer>
+ <para>While CVSup mirrors update from the master CVSup
+ server hourly, this update might happen at any time during
+ the hour. This means that some servers have newer code
+ than others, even though all servers have code that is
+ less than an hour old. If <hostid role="fqdn">cvsup.FreeBSD.org</hostid> was a round
+ robin DNS entry that simply redirected users to a random
+ CVSup server, running CVSup twice in a row could download
+ code older than the code already on the system.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="bus-speed-defaulted">
+ <para>在系統開機時,出現 <quote>(bus speed defaulted)</quote>。</para>
+ </question>
+
+ <answer>
+
+ <para>Adaptec 1542 SCSI 卡允許使用者用軟體調整匯流排的存取速度。
+ 早期的 1542 驅動程式試圖將它設成可用的最快速度,但後來發現在一
+ 些機器上不能用,所以現在要在 kernel 設定中加
+ <symbol>TUNE_1542</symbol> 這個選項來啟動這個功能。在支援的機器
+ 上用這個選項會使硬碟存取更快,但在不支援的機器上有可能會毀掉資料。
+ </para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="ctm">
+ <para>在網路頻寬有限的情況下,我也可以跟上 current 的發展嗎?</para>
+ </question>
+
+ <answer>
+ <para>是的,藉著 <ulink url="../handbook/synching.html#CTM">CTM
+ </ulink> 您就可以<literal>不用</literal>下載全部的程式碼。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="split-240k">
+ <para>是怎麼把發行版本中的檔案切成一個個 240k 的小檔案的?</para>
+ </question>
+
+ <answer>
+ <para>以 BSD 為基礎的較新系統有個 <option>-b</option> 選項
+ 可以把檔案以任意數目 byte 切開。</para>
+
+ <para>這裡是 <filename>/usr/src/Makefile</filename> 中的一個
+ 例子:</para>
+
+ <programlisting>bin-tarball:
+(cd ${DISTDIR}; \
+tar cf - . \
+gzip --no-name -9 -c | \
+split -b 240640 - \
+${RELEASEDIR}/tarballs/bindist/bin_tgz.)</programlisting>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="submitting-kernel-extensions">
+ <para>我在 kernel 中加了新功能,我要把它寄給誰?</para>
+ </question>
+
+ <answer>
+ <para>請參考 <ulink
+ url="../../articles/contributing/article.html">Contributing
+ to FreeBSD</ulink> 中的文章,以了解要如何提供您的程式碼。</para>
+
+ <para>同時也謝謝您的關心!</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="pnp-initialize">
+ <para>ISA 的隨插即用卡是如何偵測及初始化的?</para>
+ </question>
+
+ <answer>
+ <para>由 Frank Durda IV 所寫:
+ <email>uhclem@nemesis.lonestar.org</email></para>
+
+ <para>簡單的說,當主機發出是否有 PnP 卡的詢問訊號時,所有的 PnP 卡
+ 會在幾個固定的 I/O port 作回應。所以當偵測 PnP 的程式開始時,它
+ 會先問有沒有 PnP 卡在,接著所有 PnP 卡會在它讀的 port 以自己的
+ 型號 # 作回答,這樣偵測程式就會得到一個 wired-OR <quote>yes</quote>
+ 的數字,其中至少會有一個 bit 是打開的。然後偵測程式會要求型號
+ (由 Microsoft/Intel指定)小於 X 的卡<quote>離線</quote>。再去看是
+ 否還有卡回答同樣的詢問,如果得到 <literal>0</literal>,就表示沒
+ 有型號大於 X 的卡。 現在程式會問是否有型號小於 <literal>X</literal>
+ 的卡,如果有的話,程式再要型號大於 X-(limit/4) 的卡離線,然後重覆
+ 上面的動作。用重複這種類似 semi-binary search 的方法,在某範圍內
+ 找個幾次後,測程式最後會在機器中區分出所有的 PnP 卡,搜尋次數也
+ 遠低於一個個找的 2^64 次。</para>
+
+ <para>一張卡的 ID 由兩個 32-bit(所以上面是 2&circ;64) + 8bit 偵錯碼
+ 組成,第一個 32 bits 是用來區分各家廠商的。這些廠商從來沒有出來澄
+ 清過,但看來應假設同一家出的不同種類的卡的廠商 ID 有可能不同。用
+ 32 bits 只來表示不同廠商的想法實在有點過頭了。</para>
+
+ <para>第二個 32 bits 則是型號 #、乙太網路位址、或一些使這張卡獨特的
+ 資料。除非第一個 32 bits 不同,否則廠商不可能作出第二個 32 bit 相
+ 同的兩張卡。所以在一台機器中可以有同樣的好幾張卡,然而他們整個
+ 64 bits 還是會都不一樣。</para>
+
+ <para>這兩個 32 bit 絕對不可以全為零,這才能使得最開始 binary search
+ 中的 wired-OR 會得到一個非零數字。</para>
+
+ <para>一旦系統區分出所有卡的 ID,接著會經由同樣的 I/O port 一個個重
+ 新啟動每張卡,接著找出已知介面卡所需的資源、有哪些中斷可以使用等
+ 等。所有卡都會被掃描一次,來收集這些資料。</para>
+
+ <para>這些資訊接著和硬碟上的 ECU 檔案、或 MLB BIOS 裡的資料結合在一
+ 起,通常是綜合 ECU 和 MLB 裡的 BIOS PnP 資料,這些週邊並不支援真正
+ 的 PnP,然而偵測程式在檢查 BIOS 和 ECU 資料後,它可以避免 PnP 週邊
+ 和那些偵測不到的相衝突。</para>
+
+ <para>接著再度拜訪這些 PnP 週邊,這次會把可用的 I/O、DMA、IRQ 和記憶
+ 體映射的位址都指定給它們。這些週邊就會出現在所指定的地方,直到下一
+ 次重新開機為止,不過也沒有人說不能把它們隨時移來移去。</para>
+
+ <para>上面有相當多的簡化,但你應該已經了解大致的過程。</para>
+
+ <para>Microsoft 把表示印表機狀態的幾個主要 port 拿來作 PnP,他們的
+ 邏輯是沒有一張卡會在這些地方解碼作相反的 I/O cycles。但是我找到
+ 一款早期仍在評估 PnP 提案時的 IBM 原廠 printer board,它的確去解
+ 對這些狀態 port 的寫入資料,但是 MS <quote>說了就算</quote>。所以
+ 它們的確有對印表機狀態 port 寫入,還有讀取該位址 +
+ <literal>0x800</literal>、和另一個在 <literal>0x200</literal> 及
+ <literal>0x3ff</literal> 之間的 port。</para>
+
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="major-numbers">
+ <para>我為某設備寫了驅動程式,能不能給它一個 major number?</para>
+ </question>
+
+ <answer>
+ <para>這要看你是否打算將這個驅動程式公開使用,如果是的話,請把它的
+ 原始碼送一份給我們,還有 <filename>files.i386</filename> 修改的
+ 部份、kernel 設定檔樣本、以及用來產生設備檔的 &man.MAKEDEV.8;。
+ 如果你不打算公開、或因為版權問題而不能公開的話,我們有特地保留
+ character major number 32 和 block major number 8 給這方面的使用,
+ 直接用這兩個就好了。不論如何,我們都會很感激你能在 &a.hackers;
+ 發表驅動程式的消息。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="alternate-directory-layout">
+ <para>關於更動目錄放置的原則?</para>
+ </question>
+
+ <answer>
+ <para>在回答關於更動目錄放置的原則方面,我在 1983 年寫好目前的作法
+ 後就沒有再改變過,這種方式是針對原先的 FFS 檔案系統,後來也沒有
+ 對它作任何更動。它在避免 cylinder group 被填滿這方面做得相當成功,
+ 但是就像有些人已經注意到,它和 find 就配合得不大好。大部份的檔案
+ 系統是由那些用 depth first search(aka ftw) 產生的 archive 製造出
+ 來,解出來的目錄 inode 會橫跨好幾個 cylinder group,如果以後要做
+ depth first search 的話,這是最糟糕的情況之一。如果我們知道總共
+ 會產生多少目錄的話,解法是在做任何存取/寫入動作之前,在每個
+ cylinder group 上先造出(所有目錄數/cylinder greoup 的數目)這麼多
+ 的目錄。很明顯的,我們必須要有根據地去猜這 個數字,就算一個像 10
+ 的很小固定數目也會使效率以級數成長。區分 restore (即解開上述的
+ archive) 和一般檔案操作的方法可以是(現在用的演算法可能要更敏感):
+ 如果一些目錄(最多 10 個)都在 10 秒內產 生的話,那麼就把這些目錄
+ 聚集在同一個 cylinder group。不管怎樣, 我的經驗指出這是一個已經
+ 充份實驗過的部份。</para>
+
+ <para>Kirk McKusick, September 1998</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="kernel-panic-troubleshooting">
+ <para>如何在 kernel panics 時得到最多的資訊?</para>
+ </question>
+
+ <answer>
+ <para><emphasis>[這節是從 &a.wpaul; 在 &os.current; <link
+ linkend="mailing">mailing list</link> 上發表的信中節錄,
+ &a.des; 修正了打字錯誤、再加上括弧裡的注解。]</emphasis></para>
+
+ <programlisting>From: Bill Paul &lt;wpaul@skynet.ctr.columbia.edu&gt;
+Subject: Re: the fs fun never stops
+To: Ben Rosengart
+Date: Sun, 20 Sep 1998 15:22:50 -0400 (EDT)
+Cc: current@FreeBSD.org</programlisting>
+
+ <para><emphasis>[Ben 發表了下面的 panic 訊息]</emphasis></para>
+
+ <programlisting>&gt; Fatal trap 12: page fault while in kernel mode
+&gt; fault virtual address = 0x40
+&gt; fault code = supervisor read, page not present
+&gt; instruction pointer = 0x8:0xf014a7e5
+ ^^^^^^^^^^
+&gt; stack pointer = 0x10:0xf4ed6f24
+&gt; frame pointer = 0x10:0xf4ed6f28
+&gt; code segment = base 0x0, limit 0xfffff, type 0x1b
+&gt; = DPL 0, pres 1, def32 1, gran 1
+&gt; processor eflags = interrupt enabled, resume, IOPL = 0
+&gt; current process = 80 (mount)
+&gt; interrupt mask =
+&gt; trap number = 12
+&gt; panic: page fault</programlisting>
+
+ <para>當你看到像這樣的訊息時,只把它拷一份送上來是不夠的。我在上面
+ 特地標明的 instruction pointer 值相當重要,不幸的是它會因設定而
+ 不同。換句話說,這個值會跟你用的 kernel image 檔而變動。如果是用
+ 某個 snapshot 版本的 GENERIC kernel,也許其他人可以追蹤到出問題
+ 的函式,但如果你是用自訂的 kernel,那麼只有
+ <emphasis>你</emphasis>才能告訴我們問題出在那裡。</para>
+
+ <para>要做的事包括這些:</para>
+
+ <procedure>
+ <step>
+ <para>把 instruction pointer 的值記下來。注意在前面的
+ <literal>0x8:</literal> 在這個情況中並不重要,我們要的是
+ <literal>0xf0xxxxxx</literal>。</para>
+ </step>
+
+ <step>
+ <para>當系統重新開機後,執行這道命令:
+
+ <screen>&prompt.user; <userinput>nm -n /(造成 panic 的 kernel 檔案) | grep f0xxxxxx</userinput></screen>
+
+ 其中 <literal>f0xxxxxx</literal> 就是記下來的
+ instruction pointer 值。有可能不會剛好找到完整的這個字串,
+ 這是因為 kernel symbol table 裡的各個 symbol 只是函式的進
+ 入點,但 instruction pointer 所指的位址有可能是在函式內的
+ 某一處,而不一定在開頭。所以如果找不到整個字串,那麼把
+ instruction pointer 值的最後一個數字拿掉,再試一次:
+
+ <screen>&prompt.user; <userinput>nm -n /(造成 panic 的 kernel 檔案) | grep f0xxxxx</userinput></screen>
+
+ 如果這樣也找不到,那就把另一個數字去掉再找,一直重複到找到
+ 為止, 結果是一串可能造成 panic 的函式列表。這樣比直接找到
+ 出問題的函式來得差,但至少好過什麼都沒有。</para>
+
+ </step>
+ </procedure>
+
+ <para>我常常看到人們顯示一大片 panic 訊息,但很少看到有人花一點時間
+ 把 instruction pointer 和 kernel symbol table 中的函式比較一下。
+ </para>
+
+ <para>要追蹤出造成 panic 原因的最好方法是先做出 crash dump,然後用
+ &man.gdb.1; 在上面做 stack trace。</para>
+
+ <para>不管是那一種,我通常是用這個方法:</para>
+
+ <procedure>
+ <step>
+ <para>寫好 kernel 設定檔。如果你需要用 kernel debugger,在設
+ 定檔中加上 <literal>options DDB</literal> 這個選項。
+ (當我懷疑有出現無窮迴圈時,通常會用這個來設定中斷點。)
+ </para>
+ </step>
+
+ <step>
+ <para>用 <command>config -g
+ <replaceable>KERNELCONFIG</replaceable></command>
+ 做出用來編譯的目錄。</para>
+ </step>
+
+ <step>
+ <para><command>cd /sys/compile/
+ <replaceable>KERNELCONFIG</replaceable>; make
+ </command></para>
+ </step>
+
+ <step>
+ <para>等待 kernel 編譯結束。</para>
+ </step>
+
+ <step>
+ <para><command>make install</command></para>
+ </step>
+
+ <step>
+ <para>重新開機</para>
+ </step>
+ </procedure>
+
+ <para>&man.make.1; 將會製造出兩個 kernel。<filename>kernel</filename>
+ 還有 <filename>kernel.debug</filename>。
+ <filename>kernel</filename> 將會被安裝到
+ <filename>/kernel</filename>,而 <filename>kernel.debug</filename>
+ 可用來給 &man.gdb.1; 當作 debugging symbols 的來源。</para>
+
+ <para>要確定能抓到 crash dump,先編輯
+ <filename>/etc/rc.conf</filename> 將 <literal>dumpdev</literal> 指
+ 到 swap 分割區。這樣 &man.rc.8; 會用 &man.dumpon.8; 來啟動
+ crash dump,你也可以手動執行 &man.dumpon.8; 在 panic 之後,
+ crash dump 可以用 &man.savecore.8; 存起來;如果
+ <filename>/etc/rc.conf</filename> 裡有設 <literal>dumpdev</literal>
+ 那麼重新開機後 &man.rc.8; 會自動執行 &man.savecore.8; 把
+ crash dump 存在 <filename>/var/crash</filename>。</para>
+
+ <note>
+ <para>FreeBSD 的 crash dump 通常和機器裡的實際記憶體一樣大,就
+ 像如果有 64MB 記憶體,crash dump 大小就是 64MB。所以要確定
+ <filename>/var/crash</filename> 下有足夠的空間,或是可以手
+ 動執行 &man.savecore.8; 把 crash dump 放到另一個空間較夠的
+ 目錄下。另一種也許可以限制 crash dump 的方法,是在 kernel
+ 設定檔中用 <literal>options MAXMEM=(foo)</literal>,將 kernel
+ 可用的記憶體限制在合理的大小。舉例來說,如果你有 128MB 的記憶
+ 體,但是可以限制 kernel 只能用 16MB 的記憶體,這樣 crash dump
+ 就是 16MB 而不是 128MB 了。</para>
+ </note>
+
+ <para>一旦發現有了 crash dump,就可以用 &man.gdb.1; 來做
+ stack trace ,如下所示:</para>
+
+ <screen>&prompt.user; <userinput>gdb -k /sys/compile/KERNELCONFIG/kernel.debug /var/crash/vmcore.0</userinput>
+<prompt>(gdb)</prompt> <userinput>where</userinput></screen>
+
+ <para>要注意可能會出現好幾個螢幕的可用資訊,你可以用 &man.script.1;
+ 把所有輸出都存起來。用包括所有 debug symbol 的 kernel 來除錯,這
+ 樣應該可以直接顯示 panic 是發生在那一行。通常是由下往上讀
+ stack strace,這樣才能一個個追蹤出有哪些動作引到 crash。也可以用
+ &man.gdb.1; 把各種變數或結構的內容印出來,以檢查系統 crash 時的
+ 實際狀態。</para>
+
+ <para>好啦,如果你有第二台電腦而且有夠瘋狂,可以將 &man.gdb.1; 設定
+ 成遠端除錯。這樣你可以在一台機器中用 &man.gdb.1; 去除錯另一台裡的
+ kernel,可以執行的包括設定中斷點、在 kernel 原始碼中一步步執行等
+ 等,就像在一般使用者程式上除錯一樣。由於沒有什麼機會為除錯而設置
+ 兩台並鄰電腦,所以我還沒有這樣玩過。</para>
+
+ <para><emphasis>[Bill 補充:"我忘了提到一點:如果你有啟動 DDB 而
+ kernel 也已經進入除錯器,可以在 DDB 命令列下打 'panic',強迫產生
+ panic (還有 crash dump)。也有可能在 panic 階段時再進入除錯器,
+ 如果這樣的話,輸入 'continue',接著它就會完成 crash dump。" -ed]
+ </emphasis></para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="dlsym-failure">
+ <para>為什麼 dlsym() 不能操作 ELF 執行檔?</para>
+ </question>
+
+ <answer>
+ <para>在 ELF 一系列的工具中,內定是不會讓 dynamic linker 看到執行
+ 檔裡定義了哪些 symbol。所以 <function>dlsym()</function> 沒有辦
+ 法用藉由呼叫 <function>dlopen(NULL, flags)</function> 取得的
+ handle,用它去搜尋有那些 symbol 一定會失敗。</para>
+
+ <para>如果你想要用 <function>dlsym()</function> 找出某個 process
+ 的主執行檔中有哪些 symbol,則要在 link 時對 ELF linker (&man.ld.1;)
+ 加上 <option>-export-dynamic</option> 這個參數。</para>
+
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="change-kernel-address-space">
+ <para>我要如何增加或減少 kernel 能定址的空間?</para>
+ </question>
+
+ <answer>
+ <para>預設值是,FreeBSD 3.x 的 kernel 可以定址的空間是 256 MB 而
+ FreeBSD 4.x 可以到 1 GB。如果是網路負荷相當重的伺服器
+ (例如大型 FTP 或 HTTP 伺服器),你也許會發現 256 MB 可能不大夠。
+ </para>
+
+ <para>所以,要如何增加定址空間呢?要從兩方面著手。首先首先告訴
+ kernel 本身要保留較大空間給自己。其次,既然是在定址空間的最上
+ 面載入 kernel,所以還要調低載入的位址,才不會和前面定址的範圍
+ 重疊。</para>
+
+ <para>增加 <filename>src/sys/i386/include/pmap.h</filename> 裡的
+ <literal>NKPDE</literal> 就可以達成第一個目標。1 GB 的定址空間會
+ 像這樣:</para>
+
+ <programlisting>#ifndef NKPDE
+#ifdef SMP
+#define NKPDE 254 /* addressable number of page tables/pde's */
+#else
+#define NKPDE 255 /* addressable number of page tables/pde's */
+#endif /* SMP */
+#endif</programlisting>
+
+ <para>要算出 <literal>NKPDE</literal> 的正確值,將想要的空間大小
+ (以 megabyte 為單位)除以 4,接著單 CPU 機器減 1,
+ 雙 CPU 則是減 2。</para>
+
+ <para>要解決第二個問題,必須自行算出 kernel 被載入的位址:求出
+ 0x100100000 減掉定址空間大小的值(以 byte 為單位),如 1 GB 大小就是
+ 0xc0100000。把<filename>src/sys/i386/conf/Makefile.i386</filename>
+ 裡的 <symbol>LOAD_ADDRESS</symbol> 設成這個值﹔接著在
+ <filename>src/sys/i386/conf/kernel.script</filename> 中,將
+ section 列表最前面的 location counter 設成相同的值,如下:</para>
+
+ <programlisting>OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(btext)
+SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/obj/elf/home/src/tmp/usr/i386-unknown-freebsdelf/lib);
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0xc0100000 + SIZEOF_HEADERS;
+ .interp : { *(.interp) }</programlisting>
+
+ <para>然後重新編譯您的 kernel。您可能會在執行 &man.ps.1;、&man.top.1;
+ 這類的程式時碰到問題﹔<command>make world</command> 應該就可以解決
+ (或把改過的 <filename>pmap.h</filename> 複製到
+ <filename>/usr/include/vm/</filename> 下,再手動編譯
+ <filename>libkvm</filename>,&man.ps.1; 還有 &man.top.1;)。</para>
+
+ <para>注意:kernel 所能定址的空間大小必須是 4 megabytes 的倍數。
+ </para>
+
+ <para>[&a.dg; 補充:<emphasis>我認為 kernel 定址空間大小應該要是 2
+ 的乘冪,但不大確定這一點。舊的啟動程式會動到
+ high order address bits,記得它假設至少有 256 MB。]</emphasis>
+ </para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+
+ <chapter id="acknowledgments">
+ <chapterinfo>
+ <author>
+ <firstname>Vanilla</firstname>
+ <surname>Shu</surname>
+ <affiliation>
+ <address><email>vanilla@FreeBSD.org</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>感謝</title>
+
+ <blockquote>
+ <attribution>FreeBSD Core Team</attribution>
+
+ <para>假如您在這份 FAQ 中找到錯誤的地方,或是您想增加些甚麼,
+ 請寫封信到 &a.faq; 。我們非常感謝您的建議,
+ 因為您的建議讓這份文件變得更好!</para>
+ </blockquote>
+
+ <variablelist>
+ <varlistentry>
+ <term>&a.jkh;</term>
+ <listitem>
+ <para>不停的更新過時的 FAQ</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.dwhite;</term>
+
+ <listitem>
+ <para>經常在 freebsd-questions 上回答問題</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.joerg;</term>
+
+ <listitem>
+ <para>經常在 Usenet 上回答問題</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.wollman;</term>
+
+ <listitem>
+ <para>Networking and formatting</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Jim Lowe</term>
+
+ <listitem>
+ <para>Multicast information</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.pds;</term>
+
+ <listitem>
+ <para>FreeBSD FAQ 這份文件的打字苦工</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>The FreeBSD Team</term>
+
+ <listitem>
+ <para>Kvetching, moaning, submitting data</para>
+
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>對於那些曾經對這份 FAQ 提供幫助,而我們沒提到的人們,
+ 我們由衷的感謝您!</para>
+ </chapter>
+
+
+ <chapter id="ports">
+ <chapterinfo>
+ <author>
+ <firstname>Yi-Feng</firstname>
+ <surname>Tzeng</surname>
+ <affiliation>
+ <address><email>yftzeng@iis.sinica.edu.tw</email></address>
+ </affiliation>
+ </author>
+ </chapterinfo>
+
+ <title>Ports and Packages 常見問題</title>
+
+ <qandaset>
+ <qandaentry>
+ <question id="make-fetch">
+ <para>如何只抓取 tarball?</para>
+ </question>
+
+ <answer>
+ <para>如果只希望抓取 tarball 下來的話,僅需輸入以下指令即可:
+ <screen>&prompt.root; <userinput>make fetch</userinput></screen>
+ 如果是要抓取單一的 port,以
+ <filename role="package">editors/joe</filename> 為例:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/joe</userinput>
+&prompt.root; <userinput>make fetch</userinput></screen>
+
+ <para>那麼,預設會將 <filename role="package">editors/joe</filename>
+ 的 tarball 下載至 <filename>/usr/ports/distfiles</filename>
+ 目錄下。</para>
+
+ <para>如果是希望抓取安裝此 ports 所有相關相依 ports 的 tarball,以
+ <filename role="package">systuils/portupgrade</filename> 為例的話,
+ 則:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/systuils/portupgrade</userinput>
+&prompt.root; <userinput>make fetch-recursive</userinput></screen>
+
+ <para>預設會將此 port 與所有需要的其他 port 的 tarball,下載至
+ <filename>/usr/ports/distfiles</filename> 目錄下。</para>
+
+ <para>如果是希望抓取全部所有 ports 的 tarball ,則:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports</userinput>
+&prompt.root; <userinput>make fetch</userinput></screen>
+
+ <para>則會所將全部所有 ports 的 tarball 下載至
+ <filename>/usr/ports/distfiles</filename> 目錄下。</para>
+
+ <para>如果是希望抓取 ftp 分類下所有 ports 的 tarball ,則:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/ftp</userinput>
+&prompt.root; <userinput>make fetch-recursive</userinput></screen>
+
+ <para>則會所將 ftp 分類下所有 ports 的 tarball 都下載至
+ <filename>/usr/ports/distfiles</filename> 目錄下。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-extract">
+ <para>如何僅做到解開 tarball的步驟?</para>
+ </question>
+
+ <answer>
+ <para>有時候習慣自己 patch 原始碼的時候,會很常用到這個功能。以
+ <filename role="package">editors/joe</filename> 為例:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/joe</userinput>
+&prompt.root; <userinput>make extract</userinput></screen>
+
+ <para>會將 tarball解開至
+ <filename>/usr/ports/editors/joe/work</filename> 目錄下。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-patch">
+ <para>如何僅做到解開 tarball 並補上官方提供的 patch ?</para>
+ </question>
+
+ <answer>
+ <para>此法與 <link linkend="make-extract">make extract</link>
+ 的方法有一些類似,不同於是先補上官方提供的 patch,再行 patch
+ 自己的修正。 有時候習慣自己 patch 原始碼的時候,
+ 則這個方式正好符合您的需求。
+ 以 <filename role="package">editors/joe</filename> 為例:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/joe</userinput></screen>
+ <screen>&prompt.root; <userinput>make patch</userinput></screen>
+
+ <para>會將 tarball解開至 <filename>/usr/ports/editors/joe/work</filename> 目錄下
+ ,並補上官方提供的 patch。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-install">
+ <para>如何安裝一個新的 port?</para>
+ </question>
+
+ <answer>
+ <para>如果系統上未安裝此軟體,則可以選擇安裝一個新的 port。
+ 以 <filename role="package">editors/joe</filename> 為例的話,則:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/joe</userinput></screen>
+ <screen>&prompt.root; <userinput>make install</userinput></screen>
+
+ <para>如此會在系統上安裝一個新的 joe 軟體。
+ 如果需要在安裝完成後,一併清除編輯時期所留下來的暫存目錄,則可配合 <userinput>make clean</userinput> 的方法一起使用,如:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/joe</userinput></screen>
+ <screen>&prompt.root; <userinput>make clean</userinput></screen>
+
+ <para>如果想要一次清掉所有 ports 產生的暫存資料,則只要回到 ports 的根目錄執行即可:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports</userinput></screen>
+ <screen>&prompt.root; <userinput>make clean</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-package">
+ <para>如何安裝一個新的 port,並打包(package)起來?</para>
+ </question>
+
+ <answer>
+ <para>將安裝完成的軟體打包起來,有許多便利性:包括在叢集系統中,可供其它機器使用,
+ 或將未來此軟體出問題可重新利用此 package 重新快速安裝。
+ 以 <filename role="package">editors/joe</filename> 為例的話,則:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/joe</userinput></screen>
+ <screen>&prompt.root; <userinput>make package</userinput></screen>
+
+ <para>如此會在系統上安裝一個新的 joe 軟體,並將此軟體打包(package)起來。
+ package 預設會在 <filename>/usr/ports/editors/joe</filename> 目錄下,如果希望集中管理的話,建議做如下的步驟:</para>
+
+ <screen>&prompt.root; <userinput>mkdir -p /usr/ports/packages</userinput></screen>
+
+ <para>以後打包的 packages 都會存放在此目錄下,並且系統會自動做分類,以方便管理。
+ 如果需要在安裝完成後,一併清除編輯時期所留下來的暫存目錄,則可配合 make clean 一起使用,如:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/joe</userinput></screen>
+ <screen>&prompt.root; <userinput>make package clean</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-depend-package">
+ <para>如何打包一個 port,並將其所有相依的 ports 也打包起來?</para>
+ </question>
+
+ <answer>
+ <para>因為 <link linkend="make-package">make package</link> 只有打包單一套件,
+ 中間依賴的 ports 並沒有一起打包,這會出現一個常遇到的問題:
+ 就是如果一個 port 需要依賴其它的 ports,那麼必須將其它 ports 也一起打包,否則安裝 packages 會有相依性的問題。
+ 以 <filename role="package">sysutils/portupgrade</filename> 為例:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/sysutils/portupgrade</userinput></screen>
+ <screen>&prompt.root; <userinput>make DEPENDS_TARGET=package package</userinput></screen>
+
+ <para>如此會對所有 portupgrade 所相依賴的 ports 都一併打包,也包括自己本身。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="pkg-create">
+ <para>如何對一個已經安裝的 port 打包?</para>
+ </question>
+
+ <answer>
+ <para>如果安裝好一個套件,事前並未打包,事後想打包的話,則:
+ 以 <filename role="package">editors/joe</filename> 為例:</para>
+
+ <screen>&prompt.root; <userinput>cd /var/db/pkg</userinput></screen>
+ <screen>&prompt.root; <userinput>pkg_create -b joe-{版本號}</userinput></screen>
+
+ <para>會將已安裝的 port 打包起來,放在 <filename>/var/db/pkg</filename> 目錄下。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-clean">
+ <para>如何清理 ports 編輯期間所產生的暫存資料?</para>
+ </question>
+
+ <answer>
+ <para>在安裝 port 的時候,會有編譯期間所需要的工作目錄(work),因此通常安裝好一個套件後,會清除此暫存目錄,以節省硬碟空間。
+ 以 <filename role="package">editors/joe</filename> 為例:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/joe</userinput></screen>
+ <screen>&prompt.root; <userinput>make clean</userinput></screen>
+
+ <para>如果是希望清除所有 ports 的暫存目錄,則:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports</userinput></screen>
+ <screen>&prompt.root; <userinput>make clean</userinput></screen>
+
+ <para>如果是希望清除所有 ftp 分類的暫存目錄,則:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports/ftp</userinput></screen>
+ <screen>&prompt.root; <userinput>make clean</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-distclean">
+ <para>如何清理 ports 編輯期間所產生的暫存資料,以及 tarball 檔?</para>
+ </question>
+
+ <answer>
+ <para>在 <link linkend="make-clean">make clean</link> 僅只是清除編輯期間所需要的工作目錄(work),並沒有將編譯
+ ports 時一併下載的 tarball 刪除(相對應之 tarball 預設會存放在 <filename>/usr/ports/distfiles</filename>)
+ 如果想把 tarball 一併清除的話,以 <filename role="package">editors/joe</filename> 為例:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/joe</userinput></screen>
+ <screen>&prompt.root; <userinput>make distclean</userinput></screen>
+
+ <para><userinput>make distclean</userinput> 的步驟包含了 <userinput>make clean</userinput>
+ 的功能,也就是說除了會刪除 tarball 外,還會一併清除編譯時的暫存 work 目錄。</para>
+
+ <para>如果是希望清除所有 ports 的暫存 work 目錄及 tarball,則:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports</userinput></screen>
+ <screen>&prompt.root; <userinput>make distclean</userinput></screen>
+
+ <para>而如果是希望清除所有 ftp 分類的 work 目錄及 tarball,則:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports/ftp</userinput></screen>
+ <screen>&prompt.root; <userinput>make distclean</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-depends-list">
+ <para>如何在安裝 ports 前查詢所依賴的相關套件?</para>
+ </question>
+
+ <answer>
+ <para>在安裝 ports 前,可以查詢所依賴的相關套件。
+ 以 <filename role="package">mail/p5-Mail-SpamAssassin</filename> 為例:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/mail/p5-Mail-SpamAssassin</userinput></screen>
+ <screen>&prompt.root; <userinput>make all-depends-list</userinput></screen>
+ <para><userinput>make all-depends-list</userinput> 顯示此套件所有相依的套件。</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/mail/p5-Mail-SpamAssassin</userinput></screen>
+ <screen>&prompt.root; <userinput>make pretty-print-build-depends-list</userinput></screen>
+ <para><userinput>make all-depends-list</userinput> 顯示此套件在編譯期間所需要的套件。</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/mail/p5-Mail-SpamAssassin</userinput></screen>
+ <screen>&prompt.root; <userinput>make pretty-print-run-depends-list</userinput></screen>
+ <para><userinput>make all-depends-list</userinput> 顯示此套件要執行時所需要的套件。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-deinstall">
+ <para>如何移除已安裝的 ports?</para>
+ </question>
+
+ <answer>
+ <para>以 <filename role="package">editors/joe</filename> 為例:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/joe</userinput></screen>
+ <screen>&prompt.root; <userinput>make deinstall</userinput></screen>
+
+ <para>或是使用 <userinput>pkg_delete</userinput>:</para>
+ <screen>&prompt.root; <userinput>pkg_delete joe-{version}</userinput></screen>
+
+ <para>有時候套件之間的相依性會導致無法直接移除,如果要強制移除的話,則:</para>
+ <screen>&prompt.root; <userinput>pkg_delete -f joe-{version}</userinput></screen>
+ <para>但請注意:很有可能會導致其它相依到這軟體的套件執行起來出現問題。</para>
+ <para>至於二者的差別,請參考 <link linkend="deinstall-vs-pkg-delete">make deinstall 與 pkg_delete 有什麼不同</link></para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-deinstall-depends">
+ <para>如何一併移除所相依的 ports?</para>
+ </question>
+
+ <answer>
+ <para>以 <filename role="package">sysutils/portupgrade</filename> 為例:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/sysutils/portupgrade</userinput></screen>
+ <screen>&prompt.root; <userinput>make deinstall-depends</userinput></screen>
+
+ <para>執行此步驟前,請注意是否會移除其他套件也有共同相依的部分。建議先參考
+ <link linkend="make-depends-list">make-depends-list</link> 的方法來檢查。</para>
+
+ <para>或是使用</para>
+ <screen><userinput>pkg_delete</userinput></screen>
+ <para>這樣若仍有相依該套件的話,會先警告而不會移除。除非有另外加了 -f 參數來強制移除。</para>
+ <screen>&prompt.root; <userinput>pkg_delete -r portupgrade-{version}</userinput></screen>
+ <para>至於二者的差別,請參考 <link linkend="deinstall-vs-pkg-delete">make deinstall 與 pkg_delete 有什麼不同</link></para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-reinstall">
+ <para>如何重新安裝已安裝過的 ports?</para>
+ </question>
+
+ <answer>
+ <para>重新安裝的前提是:之前有安裝過或目前已安裝。以 <filename role="package">editors/joe</filename> 為例:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/joe</userinput></screen>
+ <screen>&prompt.root; <userinput>make deinstall clean install</userinput></screen>
+
+ <para>或是</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/joe</userinput></screen>
+ <screen>&prompt.root; <userinput>make reinstall</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-search">
+ <para>如何以關鍵字搜尋 ports?</para>
+ </question>
+
+ <answer>
+ <para>如果要從全部的 ports collection 中找尋與關鍵字 "ldap" 有關的 ports,則:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports</userinput></screen>
+ <screen>&prompt.root; <userinput>make search key=ldap</userinput></screen>
+
+ <para>如果只要從與 ftp 相關的 ports 下找尋與關鍵字 "ldap" 有關的 ports,則:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports/ftp</userinput></screen>
+ <screen>&prompt.root; <userinput>make search key=ldap</userinput></screen>
+
+ <para>還有另一個用法,方法只是將 key 換成 name。如果已經知道要搜尋 ports 的名稱,或只想找名稱相關的關鍵字 "ldap", 則:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports</userinput></screen>
+ <screen>&prompt.root; <userinput>make search name=ldap</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="upgrade-ports">
+ <para>如何升級已安裝的 ports?</para>
+ </question>
+
+ <answer>
+ <para>如果已經安裝套件,事後欲升級的話,必須先移除舊版的 port。以 <filename role="package">editors/joe</filename> 為例:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/joe</userinput></screen>
+ <screen>&prompt.root; <userinput>make clean reinstall</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="pkg-info">
+ <para>如何查詢目前系統安裝了哪些套件?</para>
+ </question>
+
+ <answer>
+ <para>查詢目前系統已安裝的全部套件:</para>
+
+ <screen>&prompt.root; <userinput>pkg_info</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="pkg-info-grep">
+ <para>如何查詢目前系統有沒有安裝這個關鍵字的套件?</para>
+ </question>
+
+ <answer>
+ <para>假設要找的關鍵字是 joe 的話:</para>
+ <screen>&prompt.root; <userinput>pkg_info | grep joe</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="pkg-info-W">
+ <para>如何查詢某個檔案是屬於哪些套件?</para>
+ </question>
+
+ <answer>
+ <para>如果想查詢 <filename>/usr/local/bin/joe</filename> 是屬於哪個套件的話,則:</para>
+ <screen>&prompt.root; <userinput>pkg_info -W /usr/local/bin/joe</userinput></screen>
+ <para>如果沒有回傳任何資訊的話,代表著這個檔案是由 FreeBSD 內建的。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="pkg-info-L">
+ <para>如何查詢某個套件安裝了哪些檔案?</para>
+ </question>
+
+ <answer>
+ <para>如果想查詢目前系統所安裝的 <filename role="package">joe</filename> 包含了哪些檔案,則:</para>
+ <screen>&prompt.root; <userinput>pkg_info -L /var/db/pkg/joe-{version}</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="reinstall-upgrade">
+ <para>如何安裝舊版的 ports?</para>
+ </question>
+
+ <answer>
+ <para>有時候會因為相依性,或是新版有問題,而會想裝舊版本的套件。
+ 這裡介紹的方法是利用 CVS 的好處,回歸到以前舊版本存在的日子,以安裝舊版本的套件。</para>
+
+ <para>首先,若我們要回復到某一個套件的版本時,需要去查詢 FreeBSD ports CVS repository。
+ 最常見的就是 <ulink url="http://www.freshports.org/">Freshports</ulink> 網站、 FreeBSD 的
+ <ulink url="http://lists.freebsd.org/pipermail/cvs-all/">Mailing FreeBSD cvs</ulink> 或是 FreeBSD
+ <ulink url="http://www.freebsd.org/cgi/cvsweb.cgi/ports/">ports cvsweb</ulink>。</para>
+
+ <para>查到該套件版本所依存的日子後,就修改 CVS tag。一般預設 ports 的 CVS tag 會寫在 <filename>/usr/share/examples/cvsup/ports-supfile</filename>
+ ,如要回溯到 2002/10/05 號的話,則:</para>
+ <screen>&prompt.root; <userinput>vi /usr/share/examples/cvsup/ports-supfile</userinput></screen>
+ <screen>*default date=2002.10.05.00.00.00 #將 date 改成當日</screen>
+
+ <para>然後按照一般 CVSup 或 csup 的時候一樣,執行 CVSup 或 csup (make update),此時的
+ ports collections 就會回到當時的情形,那麼該套件的舊版也會出現在 ports collections 中,只要安裝即可。</para>
+
+ <para>如果僅是想回溯某部份的 ports,則必須加上額外的資訊,如僅希望把 <filename role="package">lang/perl5.8</filename> 回溯,
+ 而我們得知此屬於 lang 中的一支,則:</para>
+ <screen>&prompt.root; <userinput>vi /usr/share/examples/cvsup/ports-supfile</userinput></screen>
+ <screen>#ports-all #將 ports-all 標示起來</screen>
+ <screen>ports-lang #加入這行</screen>
+ <para>最後,執行 CVSup 或 csup ,並安裝即可。目前若希望單獨回溯單一的 port,則比較麻煩。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="upgrade-ports-mk">
+ <para>如何更新 ports Mk?</para>
+ </question>
+
+ <answer>
+ <para>Mk (<filename>/usr/ports/Mk</filename>) 是編譯 ports 時所參考的設定,有時若發生 ports collections 太新,而導致 Mk 的內容不符,此時就是應該更新 Mk 的時候了。</para>
+ <screen>&prompt.root; <userinput>cd /usr/src</userinput></screen>
+ <screen>&prompt.root; <userinput>make update</userinput></screen>
+ <screen>&prompt.root; <userinput>cd /usr/src/share/mk</userinput></screen>
+ <screen>&prompt.root; <userinput>make install</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-use-sed-inplace">
+ <para>如何解決安裝 ports 時出現 sed -i 的錯誤?</para>
+ </question>
+
+ <answer>
+ <para>因為 BSD style 的 sed ,也就是 BSD 本身自有的 sed ,與一些 ports 編譯期間所執行的 sed 不一致,所以會導致一些語法錯誤。此時先安裝 sed_inplace (<filename role="package">textproc/sed_inplace</filename>),然後再安裝原本無法安裝的 ports:</para>
+ <screen>&prompt.root; <userinput>make -DUSE_REINPLACE install</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="pkg-version">
+ <para>如何列出所有可以升級的 ports?</para>
+ </question>
+
+ <answer>
+ <para>ports collection 的更新速度很快,在每次更新 ports collections 後,往往會出現比目前現
+ 在安裝的套件還新的版本,可以令系統自行整理並提供可升級套件的列表:</para>
+ <screen>&prompt.root; <userinput>pkg_version -c</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="grep-defined-makefile">
+ <para>如何得知 ports 所提供的編譯參數?</para>
+ </question>
+
+ <answer>
+ <para>所有的 ports collections 中所提供的編譯參數都會在對應的 Makefile 檔案內詳述,
+ 如 <filename role="package">sysutils/portupgrade</filename> 的話,則是位在 <filename>/usr/ports/sysutils/portupgrade/Makefile</filename>
+ 檔案下。</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports/sysutils/portupgrade</userinput></screen>
+ <screen>&prompt.root; <userinput>make -DNOPORTDOCS install</userinput></screen>
+
+ <para>那麼安裝此 ports 時,會將 NOPORTDOCS 所對應的相關參數指定進去。</para>
+ <para>有時候設定較人性化的 ports 會在安裝前提供參數供選擇,但是其實大部份的 ports 都沒有提
+ 供,因此必須自行去搜尋可編譯的參數,在此我提供的方式如下:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports/sysutils/portupgrade</userinput></screen>
+ <screen>&prompt.root; <userinput>grep defined Makefile</userinput></screen>
+
+ <para>如此幾乎可以知道所有提供的可編譯參數,雖然有時會多出其它的資料,不會這個確實是一個不
+ 錯可參考的方式。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-configure-args">
+ <para>如何手動加入編譯 ports 的參數?</para>
+ </question>
+
+ <answer>
+ <para>在 <link linkend="grep-defined-makefile">前面所述</link> 的方法,是 ports collections 有提供的前提之下,有時候並不是所有該軟體所支援的參數都會收納在 ports collections 中,因此有時候會需要手動加入編譯的參數。</para>
+ <para>如 ftp/pure-ftpd 中,如果不想把 inetd 的支援編入的選項,並沒有被 ports collections 所納入,因此必須手動加上這個編譯參數,如下:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports/ftp/pure-ftpd</userinput></screen>
+ <screen>&prompt.root; <userinput>make CONFIGURE_ARGS+="--without-inetd" install</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-prefix">
+ <para>如何指定 ports 的安裝路徑?</para>
+ </question>
+
+ <answer>
+ <para>預設 ports collecions 已安排安裝的路徑 (<filename>/usr/local/</filename>),如果不想將套件安裝在預設路徑的話,可以手動指定安裝路徑。以 <filename role="package">editors/joe</filename> 為例,則:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/joe</userinput></screen>
+ <screen>&prompt.root; <userinput>make PREFIX=/usr install</userinput></screen>
+ <para>那麼 joe 就會將檔案對應在 /usr 目錄下,而不是預設的 /usr/local 目錄下。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="force-pkg-register">
+ <para>安裝 ports 出現 FORCE_PKG_REGISTER 的錯誤訊息</para>
+ </question>
+
+ <answer>
+ <para>請參考 Ohaha 的 <ulink url="http://ohaha.ks.edu.tw/faq-0003.htm">FAQ</ulink>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="shared-object-not-found">
+ <para>安裝 ports 出現 Shared object libintl.so.X not found 的錯誤訊息</para>
+ </question>
+
+ <answer>
+ <para>請參考 Ohaha 的 <ulink url="http://ohaha.ks.edu.tw/faq-0004.htm">FAQ</ulink>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="pkg-add">
+ <para>如何安裝 packages?</para>
+ </question>
+
+ <answer>
+ <para>目前 FreeBSD 的 packages 是由 .tgz 所打包。如果想安裝一個 packages ,可使用 pkg_add,如安裝一個 joe 的 tgz:</para>
+ <screen>&prompt.root; <userinput>pkg_add joe-{version}.tgz</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="pkg-add-force">
+ <para>如何強制安裝 packages?</para>
+ </question>
+
+ <answer>
+ <para>由於有些 packages 會有與其他 packages 相依性的關係,所以必須先行安裝那些 packages 才
+能正常安裝。</para>
+ <para>如果須要強制安裝 packages ,可以不須安裝那些有相依性 packages ,但要注意的是強制安裝
+的結果可能會導致執行或運作的不正常。強制安裝 packages 的指令如下,如強制安裝一個 joe 的 tgz:</para>
+ <screen>&prompt.root; <userinput>pkg_add -f joe-{version}.tgz</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="pkg-info-r">
+ <para>如何查詢 packages 與其他 packages 之間的相依性?</para>
+ </question>
+
+ <answer>
+ <para>由於有些 packages 會有與其他 packages 相依性的關係,所以必須先行安裝那些 packages 才
+能正常安裝。</para>
+ <para>查詢 packages 與其他 packages 之間的相依性的指令如下,如查詢與 portupgrade 相依的其他 packages:</para>
+ <screen>&prompt.root; <userinput>pkg_info -r portupgrade-{version}.tgz</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="pkg-add-r">
+ <para>如何安裝遠端的 packages?</para>
+ </question>
+
+ <answer>
+ <para>有兩種設定方式,首先是 PACKAGEROOT,如:</para>
+ <screen>&prompt.root; <userinput>setenv PACKAGEROOT ftp://ftp.tw.freebsd.org</userinput></screen>
+
+ <para>另一種方式是設定 PACKAGESITE,好處是若該站台的 packages 倉儲並不是符合官方的設定或你
+想自己指定一個路徑。</para>
+ <para>以 ftp.tw.freebsd.org i386 的 current pakcages 為例:</para>
+ <screen>&prompt.root; <userinput>setenv PACKAGESITE ftp://ftp.tw.freebsd.org/pub/FreeBSD/ports/i386/packages-current/Latest/</userinput></screen>
+
+ <para>兩種方式選擇其中一種皆可,接下來的步驟都一樣。</para>
+ <para>往後要安裝 packages 的時候,如 portupgrade 的話,則:</para>
+ <screen>&prompt.root; <userinput>pkg_add -r portupgrade</userinput></screen>
+
+ <para>則系統會自動於 ftp.tw.freebsd.org 抓取所有與 portupgrade 相依的 packages 並安裝。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-index">
+ <para>如何更新 INDEX 對照表?</para>
+ </question>
+
+ <answer>
+ <para>4.x 的 INDEX 位於 <filename>/usr/ports/INDEX</filename>,5.x 位於 <filename>/usr/ports/INDEX-5</filename>,以此類推。</para>
+ <para>INDEX 是對照 ports 所有相依等資訊的對照表,若長期未更新的話,會導致 ports 對照失敗。
+官方有定期更新 INDEX,如果想自行更新的話,則:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports</userinput></screen>
+ <screen>&prompt.root; <userinput>make index</userinput></screen>
+
+ <para>如果想直接下載官方最新的 INDEX,則:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports</userinput></screen>
+ <screen>&prompt.root; <userinput>make fetchindex</userinput></screen>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="make-readmes">
+ <para>如何更新 INDEX HTML?</para>
+ </question>
+
+ <answer>
+ <para>FreeBSD 提供了用網頁的方式來觀看 ports collection,即可使用 lynx, w3m, links 或其它可瀏覽網頁的程式來查閱。製作全部 ports collection 的方式如下:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports</userinput></screen>
+ <screen>&prompt.root; <userinput>make readmes</userinput></screen>
+
+ <para>如果是僅須要做目前目錄下的資訊,或單一更新某一分類下的資訊,如 /usr/ports/ftp 的話,則:</para>
+ <screen>&prompt.root; <userinput>cd /usr/ports/ftp</userinput></screen>
+ <screen>&prompt.root; <userinput>make readme</userinput></screen>
+ <para>則僅會更新 /usr/ports/ftp 這個目錄的資訊,其上與其下的目錄皆不會更動到。執行成功後,會在相對應的目錄下產生 README.html 的檔案。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="sup-refuse">
+ <para>如何針對某些 ports 不做 ports update?</para>
+ </question>
+
+ <answer>
+ <para>若 ports 底下的某些分類完全用不到,則可以在 ports update 時,不做更新,以節省網路頻寬與時間。只要修改 <filename>/usr/sup/refuse</filename> 這個檔。</para>
+ <screen>&prompt.root; <userinput>ports/french</userinput></screen>
+ <screen>&prompt.root; <userinput>ports/german</userinput></screen>
+ <screen>&prompt.root; <userinput>ports/lang/perl5.8</userinput></screen>
+ <para>則上列目錄將不會更新。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question id="deinstall-vs-pkg-delete">
+ <para>make deinstall 與 pkg_delete 有什麼不同?</para>
+ </question>
+
+ <answer>
+ <para>簡單來說,make deinstall 會移除該 port,並且不會參照其相依的相關套件。</para>
+ <para>pkg_delete 在移除該 port 前,會參照其相依的相關套件,並且 pkg_delete 有支援 wild card ,如要移除所有 p 開頭的 ports,則:</para>
+ <screen>&prompt.root; <userinput>cd /var/db/pkg</userinput></screen>
+ <screen>&prompt.root; <userinput>pkg_delete p*</userinput></screen>
+
+ <para>要注意的是,如果使用 make deinstall,則最好確定系統目前所安裝的版本,與 ports collection 中顯示的版本符合,否則有可能會出現非預期性錯誤;而 pkg_delete 是因為直接
+刪除系統中所安裝的版本,所以沒有此問題。</para>
+ <para>因此,換句話說,當系統所安裝的版本符合 ports collections 中的版本,則可以使用 make deinstall 或 pkg_delete,否則的話最好用 pkg_delete。</para>
+ </answer>
+ </qandaentry>
+
+ </qandaset>
+ </chapter>
+
+ &bibliography;
+</book>
diff --git a/zh_TW.UTF-8/books/fdp-primer/Makefile b/zh_TW.UTF-8/books/fdp-primer/Makefile
new file mode 100644
index 0000000000..60eaeea096
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/Makefile
@@ -0,0 +1,51 @@
+#
+# $FreeBSD$
+#
+# Build the FreeBSD Documentation Project Primer.
+#
+
+MAINTAINER=doc@FreeBSD.org
+
+DOC?= book
+
+FORMATS?= html-split html
+
+INSTALL_COMPRESSED?= gz
+INSTALL_ONLY_COMPRESSED?=
+
+#
+# SRCS lists the individual XML files that make up the document. Changes
+# to any of these files will force a rebuild
+#
+
+# XML content
+SRCS= book.xml
+SRCS+= overview/chapter.xml
+SRCS+= psgml-mode/chapter.xml
+SRCS+= see-also/chapter.xml
+SRCS+= sgml-markup/chapter.xml
+SRCS+= sgml-primer/chapter.xml
+SRCS+= stylesheets/chapter.xml
+SRCS+= structure/chapter.xml
+SRCS+= doc-build/chapter.xml
+SRCS+= the-website/chapter.xml
+SRCS+= tools/chapter.xml
+SRCS+= translations/chapter.xml
+SRCS+= writing-style/chapter.xml
+
+SRCS+= examples/appendix.xml
+
+# Images from the cross-document image library
+IMAGES_LIB= callouts/1.png
+IMAGES_LIB+= callouts/2.png
+IMAGES_LIB+= callouts/3.png
+IMAGES_LIB+= callouts/4.png
+IMAGES_LIB+= callouts/5.png
+
+# Entities
+SRCS+= chapters.ent
+
+URL_RELPREFIX?= ../../../..
+DOC_PREFIX?= ${.CURDIR}/../../..
+
+.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/books/fdp-primer/book.xml b/zh_TW.UTF-8/books/fdp-primer/book.xml
new file mode 100644
index 0000000000..0863eb87ba
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/book.xml
@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
+ "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd" [
+<!ENTITY % chapters SYSTEM "chapters.ent"> %chapters;
+]>
+<!-- Copyright (c) 1998, 1999 Nik Clayton, All rights reserved.
+
+ Redistribution and use in source (SGML DocBook) and 'compiled' forms
+ (SGML, HTML, PDF, PostScript, RTF and so forth) with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code (SGML DocBook) must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+ 2. Redistributions in compiled form (transformed to other DTDs,
+ converted to PDF, PostScript, RTF and other formats) must reproduce
+ the above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ $FreeBSD$
+ Original revision: 1.27
+-->
+<book xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="zh_tw">
+ <info><title>FreeBSD 文件計畫入門書</title>
+
+
+ <author><orgname>FreeBSD 文件計劃</orgname></author>
+
+ <copyright>
+ <year>1998</year>
+ <year>1999</year>
+ <year>2000</year>
+ <year>2001</year>
+ <year>2002</year>
+ <year>2003</year>
+ <year>2004</year>
+ <year>2005</year>
+ <year>2006</year>
+ <year>2007</year>
+ <holder role="mailto:doceng@FreeBSD.org">DocEng</holder>
+ </copyright>
+
+ <pubdate role="rcs">$FreeBSD$</pubdate>
+
+ <releaseinfo>$FreeBSD$</releaseinfo>
+
+ &legalnotice;
+
+ <abstract>
+ <para>感謝您參與 FreeBSD 文件計劃(簡稱:FDP, FreeBSD Documentation Project),您的點滴貢獻,都相當寶貴。</para>
+
+ <para>本入手書內容包括:如何開始著手翻譯的各項細節,以及會用到的一些好用工具(包括:必備工具、輔助工具)
+ ,以及文件計畫的宗旨。</para>
+
+ <para>本文件還在草稿,尚未完稿。未完成的章節,我們會在章節名稱旁邊加註『<literal>*</literal> 』以作識別。</para>
+ </abstract>
+ </info>
+
+ <preface xml:id="preface">
+ <title>序言</title>
+
+ <sect1 xml:id="preface-prompts">
+ <title>Shell 提示符號(Prompts)</title>
+
+ <para>下表顯示出一般帳號與 root 的提示符號,在所有的文件例子中會用提示符號(prompt)
+ ,來提醒您該用哪種帳號才對。</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>帳號</entry>
+ <entry>提示符號(Prompt)</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>普通帳號</entry>
+ <entry>&prompt.user;</entry>
+ </row>
+
+ <row>
+ <entry><systemitem class="username">root</systemitem></entry>
+ <entry>&prompt.root;</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect1>
+
+ <sect1 xml:id="preface-conventions">
+ <title>書中所用的編排風格</title>
+
+ <para>下表為本書中所使用編排風格方式:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>代表意義</entry>
+ <entry>舉例</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>指令</entry>
+ <entry>使用 <command>ls -a</command> 來列出所有的檔案。</entry>
+ </row>
+
+ <row>
+ <entry>檔名</entry>
+ <entry>修改 <filename>.login</filename> 檔。</entry>
+ </row>
+
+ <row>
+ <entry>螢幕上會出現的訊息</entry>
+ <entry><screen>You have mail.</screen></entry>
+ </row>
+
+ <row>
+ <entry>輸入指令後,螢幕上會出現的對應內容。</entry>
+
+ <entry><screen>&prompt.user; <userinput>su</userinput>
+Password:</screen></entry>
+ </row>
+
+ <row>
+ <entry>要參考的線上手冊(manual)</entry>
+
+ <entry>以 <citerefentry>
+ <refentrytitle>su</refentrytitle>
+ <manvolnum>1</manvolnum>
+ </citerefentry> 來切換帳號。</entry>
+ </row>
+
+ <row>
+ <entry>在講到帳號(user)、群組(group)的名稱的時候...</entry>
+
+ <entry>只有 <systemitem class="username">root</systemitem> 才可以做這件事。</entry>
+ </row>
+
+ <row>
+ <entry>語氣的強調</entry>
+
+ <entry>你『必須』這麼做才行。</entry>
+ </row>
+
+ <row>
+ <entry>打指令時,可替換的部份</entry>
+
+ <entry>要刪除檔案的話,請打 <command>rm 要刪除的檔名</command></entry>
+ </row>
+
+ <row>
+ <entry>環境變數設定</entry>
+
+ <entry><envar>$HOME</envar> 是指帳號的家目錄所在處。</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect1>
+
+ <sect1 xml:id="preface-notes">
+ <title>『Note、Tip、Important、Warning、Example』的運用</title>
+
+ <para>以下文字是『注意』、『技巧』、『重要訊息』、『警告』、『範例』的運用。</para>
+
+ <note>
+ <para>表示需要注意的事項,其中包括您需要注意的事情,因為這些事情可能會影響到操作結果。</para>
+ </note>
+
+ <tip>
+ <para>提供可能對您有用或簡化操作方式的技巧說明。</para>
+ </tip>
+
+ <important>
+ <para>表示要特別注意的事情。一般來說,它們會包括操作指令時需要加的額外參數。</para>
+ </important>
+
+ <warning>
+ <para>表示警告事項,比如如果您不注意則可能導致的損失。這些損失可能是對您或硬體造成實際傷害,
+ 也可能是無法估計的損害,例如一時疏忽而刪除重要檔案...。</para>
+ </warning>
+
+ <example>
+ <title>這是舉例說明</title>
+
+ <para>這是舉例說明而已,通常包含應遵循的指令範例,或顯示某些特定動作所可能發生的結果。</para>
+ </example>
+ </sect1>
+
+ <sect1 xml:id="preface-acknowledgements">
+ <title>感謝</title>
+
+ <para>在此要感謝 Sue Blake, Patrick Durusau, Jon Hamilton, Peter
+ Flynn, Christopher Maden 這些人的協助與閱讀初期草稿,並提供許多寶貴的潤稿意見與評論。</para>
+ </sect1>
+ </preface>
+
+ &chap.overview;
+ &chap.tools;
+ &chap.xml-primer;
+ &chap.xml-markup;
+ &chap.stylesheets;
+ &chap.structure;
+ &chap.doc-build;
+ &chap.the-website;
+ &chap.translations;
+ &chap.writing-style;
+ &chap.psgml-mode;
+ &chap.see-also;
+
+ &app.examples;
+
+ <index/>
+</book>
diff --git a/zh_TW.UTF-8/books/fdp-primer/chapters.ent b/zh_TW.UTF-8/books/fdp-primer/chapters.ent
new file mode 100644
index 0000000000..a3d22b4c72
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/chapters.ent
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Creates entities for each chapter in the Documentation Project Primer.
+ Each entity is named chap.foo, where foo is the value of the id
+ attribute on that chapter, and corresponds to the name of the
+ directory in which that chapter's .xml file is stored.
+
+ Chapters should be listed in the order in which they are referenced.
+
+ $FreeBSD$
+ Original revision: 1.6
+-->
+
+<!ENTITY chap.overview SYSTEM "overview/chapter.xml">
+<!ENTITY chap.xml-primer SYSTEM "sgml-primer/chapter.xml">
+<!ENTITY chap.tools SYSTEM "tools/chapter.xml">
+<!ENTITY chap.xml-markup SYSTEM "sgml-markup/chapter.xml">
+<!ENTITY chap.stylesheets SYSTEM "stylesheets/chapter.xml">
+<!ENTITY chap.structure SYSTEM "structure/chapter.xml">
+<!ENTITY chap.the-website SYSTEM "the-website/chapter.xml">
+<!ENTITY chap.translations SYSTEM "translations/chapter.xml">
+<!ENTITY chap.writing-style SYSTEM "writing-style/chapter.xml">
+<!ENTITY chap.psgml-mode SYSTEM "psgml-mode/chapter.xml">
+<!ENTITY chap.see-also SYSTEM "see-also/chapter.xml">
+<!ENTITY chap.doc-build SYSTEM "doc-build/chapter.xml">
+
+<!ENTITY app.examples SYSTEM "examples/appendix.xml">
diff --git a/zh_TW.UTF-8/books/fdp-primer/doc-build/chapter.xml b/zh_TW.UTF-8/books/fdp-primer/doc-build/chapter.xml
new file mode 100644
index 0000000000..9932157881
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/doc-build/chapter.xml
@@ -0,0 +1,486 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 1999 Neil Blakey-Milner, All rights reserved.
+
+ Redistribution and use in source (SGML DocBook) and 'compiled' forms
+ (SGML HTML, PDF, PostScript, RTF and so forth) with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code (SGML DocBook) must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+ 2. Redistributions in compiled form (transformed to other DTDs,
+ converted to PDF, PostScript, RTF and other formats) must reproduce
+ the above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS DOCUMENTATION IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ $FreeBSD$
+ Original revision: 1.16
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="doc-build">
+ <title>The Documentation Build Process</title>
+
+ <para>This chapter's main purpose is to clearly explain <emphasis>how
+ the documentation build process is organized</emphasis>, and
+ <emphasis>how to affect modifications to this process</emphasis>.
+ </para>
+
+ <para>After you have finished reading this chapter you should:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Know what you need to build the FDP documentation, in
+ addition to those mentioned in the <link linkend="tools">SGML tools chapter</link>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Be able to read and understand the
+ <application>make</application> instructions that are present in
+ each document's <filename>Makefile</filename>s, as well as an
+ overview of the <filename>doc.project.mk</filename> includes.</para>
+ </listitem>
+
+ <listitem>
+ <para>Be able to customize the build process by using
+ <application>make</application> variables and
+ <application>make</application> targets.</para>
+ </listitem>
+ </itemizedlist>
+
+ <sect1 xml:id="doc-build-toolset">
+ <title>The FreeBSD Documentation Build Toolset</title>
+
+ <para>Here are your tools. Use them every way you can.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The primary build tool you will need is
+ <application>make</application>, but specifically
+ <application>Berkeley Make</application>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Package building is handled by FreeBSD's
+ <application>pkg_create</application>. If you are not using
+ FreeBSD, you will either have to live without packages, or
+ compile the source yourself.</para>
+ </listitem>
+
+ <listitem>
+ <para><application>gzip</application> is needed to create
+ compressed versions of the document.
+ <application>bzip2</application> compression and
+ <application>zip</application> archives are also supported.
+ <application>tar</application> is supported, but package
+ building demands it.</para>
+ </listitem>
+
+ <listitem>
+ <para><application>install</application> is the default method
+ to install the documentation. There are alternatives,
+ however.</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <para>It is unlikely you will have any trouble finding these last two, they
+ are mentioned for completeness only.</para>
+ </note>
+ </sect1>
+
+ <sect1 xml:id="doc-build-makefiles">
+ <title>Understanding Makefiles in the Documentation tree</title>
+
+ <para>There are three main types of <filename>Makefile</filename>s
+ in the FreeBSD Documentation Project tree.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="sub-make">Subdirectory
+ <filename>Makefile</filename>s</link> simply pass
+ commands to those directories below them.</para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="doc-make">Documentation
+ <filename>Makefile</filename>s</link> describe the
+ document(s) that should be produced from this directory.</para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="make-includes"><application>Make</application>
+ includes</link> are the glue that perform the document production,
+ and are usually of the form
+ <filename>doc.xxx.mk</filename>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <sect2 xml:id="sub-make">
+ <title>Subdirectory Makefiles</title>
+
+ <para>These <filename>Makefile</filename>s usually take the form of:</para>
+
+ <programlisting>SUBDIR =articles
+SUBDIR+=books
+
+COMPAT_SYMLINK = en
+
+DOC_PREFIX?= ${.CURDIR}/..
+.include "${DOC_PREFIX}/share/mk/doc.project.mk"</programlisting>
+
+ <para>In quick summary, the first four non-empty lines define the
+ <application>make</application> variables,
+ <varname>SUBDIR</varname>, <varname>COMPAT_SYMLINK</varname>,
+ and <varname>DOC_PREFIX</varname>.</para>
+
+ <para>The first <varname>SUBDIR</varname> statement, as well as
+ the <varname>COMPAT_SYMLINK</varname> statement, shows how to
+ assign a value to a variable, overriding any previous
+ value.</para>
+
+ <para>The second <varname>SUBDIR</varname> statement shows how a
+ value is appended to the current value of a variable. The
+ <varname>SUBDIR</varname> variable is now <literal>articles
+ books</literal>.</para>
+
+ <para>The <varname>DOC_PREFIX</varname> assignment shows how a
+ value is assigned to the variable, but only if it is not already
+ defined. This is useful if <varname>DOC_PREFIX</varname> is not
+ where this <filename>Makefile</filename> thinks it is - the user
+ can override this and provide the correct value.</para>
+
+ <para>Now what does it all mean? <varname>SUBDIR</varname>
+ mentions which subdirectories below this one the build process
+ should pass any work on to.</para>
+
+ <para><varname>COMPAT_SYMLINK</varname> is specific to
+ compatibility symlinks (amazingly enough) for languages to their
+ official encoding (<filename>doc/en</filename> would point to
+ <filename>en_US.ISO-8859-1</filename>).</para>
+
+ <para><varname>DOC_PREFIX</varname> is the path to the root of the
+ FreeBSD Document Project tree. This is not always that easy to
+ find, and is also easily overridden, to allow for flexibility.
+ <varname>.CURDIR</varname> is a <application>make</application>
+ builtin variable with the path to the current directory.</para>
+
+ <para>The final line includes the FreeBSD Documentation Project's
+ project-wide <application>make</application> system file
+ <filename>doc.project.mk</filename> which is the glue which
+ converts these variables into build instructions.</para>
+
+ </sect2>
+ <sect2 xml:id="doc-make">
+ <title>Documentation Makefiles</title>
+
+ <para>These <filename>Makefile</filename>s set a bunch of
+ <application>make</application> variables that describe how to
+ build the documentation contained in that directory.</para>
+
+ <para>Here is an example:</para>
+
+ <programlisting>MAINTAINER=nik@FreeBSD.org
+
+DOC?= book
+
+FORMATS?= html-split html
+
+INSTALL_COMPRESSED?= gz
+INSTALL_ONLY_COMPRESSED?=
+
+# SGML content
+SRCS= book.xml
+
+DOC_PREFIX?= ${.CURDIR}/../../..
+
+.include "$(DOC_PREFIX)/share/mk/docproj.docbook.mk"</programlisting>
+
+ <para>The <varname>MAINTAINER</varname> variable is a very
+ important one. This variable provides the ability to claim
+ ownership over a document in the FreeBSD Documentation
+ Project, whereby you gain the responsibility for maintaining
+ it.</para>
+
+ <para><varname>DOC</varname> is the name (sans the
+ <filename>.xml</filename> extension) of the main document
+ created by this directory. <varname>SRCS</varname> lists all
+ the individual files that make up the document. This should
+ also include important files in which a change should result
+ in a rebuild.</para>
+
+ <para><varname>FORMATS</varname> indicates the default formats
+ that should be built for this document.
+ <varname>INSTALL_COMPRESSED</varname> is the default list of
+ compression techniques that should be used in the document
+ build. <varname>INSTALL_ONLY_COMPRESS</varname>, empty by
+ default, should be non-empty if only compressed documents are
+ desired in the build.</para>
+
+ <note>
+ <para>We covered optional variable assignments in the
+ <link linkend="sub-make">previous section</link>.</para>
+ </note>
+
+ <para>The <varname>DOC_PREFIX</varname> and include statements
+ should be familiar already.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="make-includes">
+ <title>FreeBSD Documentation Project make includes</title>
+
+ <para>This is best explained by inspection of the code. Here are
+ the system include files:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><filename>doc.project.mk</filename> is the main project
+ include file, which includes all the following include files, as
+ necessary.</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>doc.subdir.mk</filename> handles traversing of
+ the document tree during the build and install processes.</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>doc.install.mk</filename> provides variables
+ that affect ownership and installation of documents.</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>doc.docbook.mk</filename> is included if
+ <varname>DOCFORMAT</varname> is <literal>docbook</literal>
+ and <varname>DOC</varname> is set.</para>
+ </listitem>
+ </itemizedlist>
+
+ <sect2>
+ <title>doc.project.mk</title>
+
+ <para>By inspection:</para>
+
+ <programlisting>DOCFORMAT?= docbook
+MAINTAINER?= doc@FreeBSD.org
+
+PREFIX?= /usr/local
+PRI_LANG?= en_US.ISO8859-1
+
+.if defined(DOC)
+.if ${DOCFORMAT} == "docbook"
+.include "doc.docbook.mk"
+.endif
+.endif
+
+.include "doc.subdir.mk"
+.include "doc.install.mk"</programlisting>
+
+ <sect3>
+
+ <title>Variables</title>
+
+ <para><varname>DOCFORMAT</varname> and <varname>MAINTAINER</varname>
+ are assigned default values, if these are not set by the
+ document make file.</para>
+
+ <para><varname>PREFIX</varname> is the prefix under which the
+ <link linkend="tools">documentation building tools</link> are
+ installed. For normal package and port installation, this is
+ <filename>/usr/local</filename>.</para>
+
+ <para><varname>PRI_LANG</varname> should be set to whatever
+ language and encoding is natural amongst users these documents are
+ being built for. US English is the default.</para>
+
+ <note>
+ <para><varname>PRI_LANG</varname> in no way affects what documents
+ can, or even will, be built. Its main use is creating links to
+ commonly referenced documents into the FreeBSD documentation
+ install root.</para>
+ </note>
+ </sect3>
+
+ <sect3>
+ <title>Conditionals</title>
+
+ <para>The <literal>.if defined(DOC)</literal> line is an example of
+ a <application>make</application> conditional which, like in
+ other programs, defines behavior if some condition is true or
+ if it is false. <literal>defined</literal> is a function which
+ returns whether the variable given is defined or not.</para>
+
+ <para><literal>.if ${DOCFORMAT} == "docbook"</literal>, next,
+ tests whether the <varname>DOCFORMAT</varname> variable is
+ <literal>"docbook"</literal>, and in this case, includes
+ <filename>doc.docbook.mk</filename>.</para>
+
+ <para>The two <literal>.endif</literal>s close the two above
+ conditionals, marking the end of their application.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>doc.subdir.mk</title>
+
+ <para>This is too long to explain by inspection, you should be
+ able to work it out with the knowledge gained from the previous
+ chapters, and a little help given here.</para>
+
+ <sect3>
+ <title>Variables</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><varname>SUBDIR</varname> is a list of subdirectories
+ that the build process should go further down
+ into.</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>ROOT_SYMLINKS</varname> is the name of
+ directories that should be linked to the document
+ install root from their actual locations, if the current
+ language is the primary language (specified by
+ <varname>PRI_LANG</varname>).</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>COMPAT_SYMLINK</varname> is described in the
+ <link linkend="sub-make">Subdirectory Makefile</link>
+ section.</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+
+ <sect3>
+ <title>Targets and macros</title>
+
+ <para>Dependencies are described by
+ <literal>target:
+ dependency1 dependency2 ...</literal>
+ tuples, where to build <literal>target</literal>, you need to build
+ the given dependencies first.</para>
+
+ <para>After that descriptive tuple, instructions on how to build
+ the target may be given, if the conversion process between the
+ target and its dependencies are not previously defined, or if
+ this particular conversion is not the same as the default
+ conversion method.</para>
+
+ <para>A special dependency <literal>.USE</literal> defines
+ the equivalent of a macro.</para>
+
+<programlisting>_SUBDIRUSE: .USE
+.for entry in ${SUBDIR}
+ @${ECHO} "===&gt; ${DIRPRFX}${entry}"
+ @(cd ${.CURDIR}/${entry} &amp;&amp; \
+ ${MAKE} ${.TARGET:S/realpackage/package/:S/realinstall/install/} DIRPRFX=${DIRPRFX}${entry}/ )
+.endfor</programlisting>
+
+ <para>In the above, <buildtarget>_SUBDIRUSE</buildtarget> is now a
+ macro which will execute the given commands when it is listed
+ as a dependency.</para>
+
+ <para>What sets this macro apart from other targets? Basically,
+ it is executed <emphasis>after</emphasis> the instructions
+ given in the build procedure it is listed as a dependency to,
+ and it does not adjust <varname>.TARGET</varname>, which is the
+ variable which contains the name of the target currently
+ being built.</para>
+
+<programlisting>clean: _SUBDIRUSE
+ rm -f ${CLEANFILES}</programlisting>
+
+ <para>In the above, <buildtarget>clean</buildtarget> will use the
+ <buildtarget>_SUBDIRUSE</buildtarget> macro after it has
+ executed the instruction
+ <command>rm -f ${CLEANFILES}</command>. In effect, this causes
+ <buildtarget>clean</buildtarget> to go further and further down
+ the directory tree, deleting built files as it goes
+ <emphasis>down</emphasis>, not on the way back up.</para>
+
+ <sect4>
+ <title>Provided targets</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><buildtarget>install</buildtarget> and
+ <buildtarget>package</buildtarget> both go down the
+ directory tree calling the real versions of themselves
+ in the subdirectories
+ (<buildtarget>realinstall</buildtarget> and
+ <buildtarget>realpackage</buildtarget>
+ respectively).</para>
+ </listitem>
+
+ <listitem>
+ <para><buildtarget>clean</buildtarget> removes files created
+ by the build process (and goes down the directory tree
+ too). <buildtarget>cleandir</buildtarget> does the same,
+ and also removes the object directory, if any.</para>
+ </listitem>
+ </itemizedlist>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>More on conditionals</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>exists</literal> is another condition
+ function which returns true if the given file exists.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>empty</literal> returns true if the given
+ variable is empty.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>target</literal> returns true if the given
+ target does not already exist.</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+
+ <sect3>
+ <title>Looping constructs in make (.for)</title>
+
+ <para><literal>.for</literal> provides a way to repeat a set of
+ instructions for each space-separated element in a variable.
+ It does this by assigning a variable to contain the current
+ element in the list being examined.</para>
+
+<programlisting>_SUBDIRUSE: .USE
+.for entry in ${SUBDIR}
+ @${ECHO} "===&gt; ${DIRPRFX}${entry}"
+ @(cd ${.CURDIR}/${entry} &amp;&amp; \
+ ${MAKE} ${.TARGET:S/realpackage/package/:S/realinstall/install/} DIRPRFX=${DIRPRFX}${entry}/ )
+.endfor</programlisting>
+
+ <para>In the above, if <varname>SUBDIR</varname> is empty, no
+ action is taken; if it has one or more elements, the
+ instructions between <literal>.for</literal> and
+ <literal>.endfor</literal> would repeat for every element,
+ with <varname>entry</varname> being replaced with the value of
+ the current element.</para>
+ </sect3>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/fdp-primer/examples/appendix.xml b/zh_TW.UTF-8/books/fdp-primer/examples/appendix.xml
new file mode 100644
index 0000000000..5fc6839c92
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/examples/appendix.xml
@@ -0,0 +1,336 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2000 Nik Clayton, All rights reserved.
+
+ Redistribution and use in source (SGML DocBook) and 'compiled' forms
+ (SGML HTML, PDF, PostScript, RTF and so forth) with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code (SGML DocBook) must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+ 2. Redistributions in compiled form (transformed to other DTDs,
+ converted to PDF, PostScript, RTF and other formats) must reproduce
+ the above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ $FreeBSD$
+ Original revision: 1.17
+-->
+<appendix xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="examples">
+ <title>範例</title>
+
+ <para>本附錄收錄一些 SGML 檔範例,以及用來轉換格式的相關指令。
+ 若已成功安裝文件計畫工具包的話,那麼就可以直接照下面範例來使用。</para>
+
+ <para>這些例子並不是很詳細 &mdash; 並未包括你可能想用的元件,
+ 尤其像是你文件的前頁(正文前的書頁,包括扉頁、序言、目錄等)
+ 若需參考更多 DocBook 標記語言文件的話,那麼可以透過 <application>CSup</application>、<application>CVSup</application>
+ 程式來抓 <literal>doc</literal> tree 部分,以察看本文件或其他文件的 SGML 原稿。
+ 或者,也可以線上瀏覽
+ <uri xlink:href="http://www.FreeBSD.org/cgi/cvsweb.cgi/doc/">http://www.FreeBSD.org/cgi/cvsweb.cgi/doc/</uri>。</para>
+
+ <para>為了避免不必要的困擾,這些例子採用標準的 DocBook 4.1 DTD 而非 FreeBSD 額外的 DTD。
+ 同時並採用 Norm Walsh 氏的樣式表(stylesheets),而非 FreeBSD 文件計劃有自行改過的樣式表。
+ 在一般使用 DocBook 的例子,這樣子會比較簡化環境,而不會造成額外困擾。</para>
+
+ <sect1 xml:id="examples-docbook-book">
+ <title>DocBook <tag>book</tag></title>
+
+ <example>
+ <title>DocBook <tag>book</tag></title>
+
+ <programlisting><![CDATA[<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+
+<book lang='zh_tw'>
+ <bookinfo>
+ <title>樣本書的例子</title>
+
+ <author>
+ <firstname>名(first name)</firstname>
+ <surname>姓(surname)</surname>
+ <affiliation>
+ <address><email>foo@example.com</email></address>
+ </affiliation>
+ </author>
+
+ <copyright>
+ <year>2000</year>
+ <holder>相關版權字樣</holder>
+ </copyright>
+
+ <abstract>
+ <para>該書若有摘要,就寫在這邊。</para>
+ </abstract>
+ </bookinfo>
+
+ <preface>
+ <title>序言</title>
+
+ <para>該書若有序言,就放在這邊。</para>
+ </preface>
+
+ <chapter>
+ <title>第一章</title>
+
+ <para>這是這本書的第一章。</para>
+
+ <sect1>
+ <title>第一節</title>
+
+ <para>這本書的第一節。</para>
+ </sect1>
+ </chapter>
+</book>]]></programlisting>
+ </example>
+ </sect1>
+
+ <sect1 xml:id="examples-docbook-article">
+ <title>DocBook <tag>article</tag></title>
+
+ <example>
+ <title>DocBook <tag>article</tag></title>
+
+ <programlisting><![CDATA[<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+
+<article lang='zh_tw'>
+ <articleinfo>
+ <title>文章樣本</title>
+
+ <author>
+ <firstname>名(first name)</firstname>
+ <surname>姓(surname)</surname>
+ <affiliation>
+ <address><email>foo@example.com</email></address>
+ </affiliation>
+ </author>
+
+ <copyright>
+ <year>2000</year>
+ <holder>相關版權字樣</holder>
+ </copyright>
+
+ <abstract>
+ <para>該文章若有摘要,就寫在這邊。</para>
+ </abstract>
+ </articleinfo>
+
+ <sect1>
+ <title>第一節</title>
+
+ <para>該文章的第一節。</para>
+
+ <sect2>
+ <title>第一小節(sub-section)</title>
+
+ <para>該文章的第一小節(sub-section)</para>
+ </sect2>
+ </sect1>
+</article>]]></programlisting>
+ </example>
+ </sect1>
+
+ <sect1 xml:id="examples-formatted">
+ <title>Producing formatted output</title>
+
+ <para>本節有些前提,假設:已經有裝 <package>textproc/docproj</package>
+ 上面所安裝各軟體,無論它們是用 port 方式安裝或是手動安裝。
+ 此外,假設所裝的軟體都放在 <filename>/usr/local/</filename> 下的子目錄,
+ 並且所安裝的相關執行檔,都有裝在你的 <envar>PATH</envar> 環境變數內的目錄。
+ 如有必要的話,請依你的系統環境而調整相關路徑。</para>
+
+ <sect2>
+ <title>使用 Jade</title>
+
+ <example>
+ <title>轉換 DocBook 為 HTML (完整模式)</title>
+
+ <screen>&prompt.user; <userinput>jade -V nochunks \ <co xml:id="examples-co-jade-1-nochunks"/>
+ -c /usr/local/share/xml/docbook/dsssl/modular/catalog \ <co xml:id="examples-co-jade-1-catalog"/>
+ -c /usr/local/share/xml/docbook/catalog \
+ -c /usr/local/share/xml/jade/catalog \
+ -d /usr/local/share/xml/docbook/dsssl/modular/html/docbook.dsl \<co xml:id="examples-co-jade-1-dsssl"/>
+ -t sgml <co xml:id="examples-co-jade-1-transform"/> file.xml &gt; file.html <co xml:id="examples-co-jade-1-filename"/></userinput></screen>
+
+ <calloutlist>
+ <callout arearefs="examples-co-jade-1-nochunks">
+ <para>Specifies the <literal>nochunks</literal> parameter to the
+ stylesheets, forcing all output to be written to
+ <abbrev>STDOUT</abbrev> (using Norm Walsh's stylesheets).</para>
+ </callout>
+
+ <callout arearefs="examples-co-jade-1-catalog">
+ <para>Specifies the catalogs that Jade will need to process.
+ Three catalogs are required. The first is a catalog that
+ contains information about the DSSSL stylesheets. The second
+ contains information about the DocBook DTD. The third contains
+ information specific to Jade.</para>
+ </callout>
+
+ <callout arearefs="examples-co-jade-1-dsssl">
+ <para>Specifies the full path to the DSSSL stylesheet that Jade
+ will use when processing the document.</para>
+ </callout>
+
+ <callout arearefs="examples-co-jade-1-transform">
+ <para>Instructs Jade to perform a
+ <emphasis>transformation</emphasis> from one DTD to another. In
+ this case, the input is being transformed from the DocBook DTD
+ to the HTML DTD.</para>
+ </callout>
+
+ <callout arearefs="examples-co-jade-1-filename">
+ <para>Specifies the file that Jade should process, and redirects
+ output to the specified <filename>.html</filename> file.</para>
+ </callout>
+ </calloutlist>
+ </example>
+
+ <example>
+ <title>轉換 DocBook 為 HTML (章節模式)</title>
+
+ <screen>&prompt.user; <userinput>jade \
+ -c /usr/local/share/xml/docbook/dsssl/modular/catalog \ <co xml:id="examples-co-jade-2-catalog"/>
+ -c /usr/local/share/xml/docbook/catalog \
+ -c /usr/local/share/xml/jade/catalog \
+ -d /usr/local/share/xml/docbook/dsssl/modular/html/docbook.dsl \<co xml:id="examples-co-jade-2-dsssl"/>
+ -t sgml <co xml:id="examples-co-jade-2-transform"/> file.xml <co xml:id="examples-co-jade-2-filename"/></userinput></screen>
+
+ <calloutlist>
+ <callout arearefs="examples-co-jade-2-catalog">
+ <para>Specifies the catalogs that Jade will need to process.
+ Three catalogs are required. The first is a catalog that
+ contains information about the DSSSL stylesheets. The second
+ contains information about the DocBook DTD. The third contains
+ information specific to Jade.</para>
+ </callout>
+
+ <callout arearefs="examples-co-jade-2-dsssl">
+ <para>Specifies the full path to the DSSSL stylesheet that Jade
+ will use when processing the document.</para>
+ </callout>
+
+ <callout arearefs="examples-co-jade-2-transform">
+ <para>Instructs Jade to perform a
+ <emphasis>transformation</emphasis> from one DTD to another. In
+ this case, the input is being transformed from the DocBook DTD
+ to the HTML DTD.</para>
+ </callout>
+
+ <callout arearefs="examples-co-jade-2-filename">
+ <para>Specifies the file that Jade should process. The
+ stylesheets determine how the individual HTML files will be
+ named, and the name of the <quote>root</quote> file (i.e., the
+ one that contains the start of the document.</para>
+ </callout>
+ </calloutlist>
+
+ <para>This example may still only generate one HTML file, depending on
+ the structure of the document you are processing, and the
+ stylesheet's rules for splitting output.</para>
+ </example>
+
+ <example xml:id="examples-docbook-postscript">
+ <title>轉換 DocBook 為 Postscript(PS) 格式</title>
+
+ <para>The source SGML file must be converted to a &tex; file.</para>
+
+ <screen>&prompt.user; <userinput>jade -Vtex-backend \ <co xml:id="examples-co-jade-3-tex-backend"/>
+ -c /usr/local/share/xml/docbook/dsssl/modular/catalog \ <co xml:id="examples-co-jade-3-catalog"/>
+ -c /usr/local/share/xml/docbook/catalog \
+ -c /usr/local/share/xml/jade/catalog \
+ -d /usr/local/share/xml/docbook/dsssl/modular/print/docbook.dsl \<co xml:id="examples-co-jade-3-dsssl"/>
+ -t tex <co xml:id="examples-co-jade-3-tex"/> file.xml</userinput></screen>
+
+ <calloutlist>
+ <callout arearefs="examples-co-jade-3-tex-backend">
+ <para>Customizes the stylesheets to use various options
+ specific to producing output for &tex;.</para>
+ </callout>
+
+ <callout arearefs="examples-co-jade-3-catalog">
+ <para>Specifies the catalogs that Jade will need to process. Three
+ catalogs are required. The first is a catalog that contains
+ information about the DSSSL stylesheets. The second contains
+ information about the DocBook DTD. The third contains
+ information specific to Jade.</para>
+ </callout>
+
+ <callout arearefs="examples-co-jade-3-dsssl">
+ <para>Specifies the full path to the DSSSL stylesheet that
+ Jade will use when processing the document.</para>
+ </callout>
+
+ <callout arearefs="examples-co-jade-3-tex">
+ <para>Instructs Jade to convert the output to &tex;.</para>
+ </callout>
+ </calloutlist>
+
+ <para>The generated <filename>.tex</filename> file must now be run
+ through <command>tex</command>, specifying the
+ <literal>&amp;jadetex</literal> macro package.</para>
+
+ <screen>&prompt.user; <userinput>tex "&amp;jadetex" file.tex</userinput></screen>
+
+ <para>You have to run <command>tex</command> <emphasis>at
+ least</emphasis> three times. The first run processes the
+ document, and determines areas of the document which are referenced
+ from other parts of the document, for use in indexing, and so
+ on.</para>
+
+ <para>Do not be alarmed if you see warning messages such as
+ <literal>LaTeX Warning: Reference `136' on page 5 undefined on input
+ line 728.</literal> at this point.</para>
+
+ <para>The second run reprocesses the document now that certain pieces
+ of information are known (such as the document's page length). This
+ allows index entries and other cross-references to be fixed
+ up.</para>
+
+ <para>The third pass performs any final cleanup necessary.</para>
+
+ <para>The output from this stage will be
+ <filename>file.dvi</filename>.</para>
+
+ <para>Finally, run <command>dvips</command> to convert the
+ <filename>.dvi</filename> file to Postscript.</para>
+
+ <screen>&prompt.user; <userinput>dvips -o file.ps file.dvi</userinput></screen>
+ </example>
+
+ <example>
+ <title>轉換 DocBook 為 PDF 格式</title>
+
+ <para>The first part of this process is identical to that when
+ converting DocBook to Postscript, using the same
+ <command>jade</command> command line (<xref linkend="examples-docbook-postscript"/>).</para>
+
+ <para>When the <filename>.tex</filename> file has been generated you
+ run pdfTeX. However, use the &amp;pdfjadetex macro package
+ instead.</para>
+
+ <screen>&prompt.user; <userinput>pdftex "&amp;pdfjadetex" file.tex</userinput></screen>
+
+ <para>Again, run this command three times.</para>
+
+ <para>This will generate
+ <filename>file.pdf</filename>, which does
+ not need to be processed any further.</para>
+ </example>
+ </sect2>
+ </sect1>
+</appendix>
diff --git a/zh_TW.UTF-8/books/fdp-primer/overview/chapter.xml b/zh_TW.UTF-8/books/fdp-primer/overview/chapter.xml
new file mode 100644
index 0000000000..d3f24e60ef
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/overview/chapter.xml
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 1998, 1999 Nik Clayton, All rights reserved.
+
+ Redistribution and use in source (SGML DocBook) and 'compiled' forms
+ (SGML HTML, PDF, PostScript, RTF and so forth) with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code (SGML DocBook) must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+ 2. Redistributions in compiled form (transformed to other DTDs,
+ converted to PDF, PostScript, RTF and other formats) must reproduce
+ the above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ $FreeBSD$
+ Original revision: 1.23
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="overview">
+ <title>概論</title>
+
+ <para>歡迎參與 FreeBSD 文件計劃。維持優秀質量的文件對 FreeBSD 的成功來說十分重要,
+ 而 FreeBSD 文件計劃(以下皆以 FDP 來代表 FreeBSD Documentation Project
+ 的縮寫) 則與這些文件撰寫、更新息息相關,因此您的點滴貢獻都是十分寶貴的。</para>
+
+ <para>本文件最主要的目的,就是清楚告訴您:『FDP 的架構有哪些』、『如何撰寫並提交文件給 FDP』、
+ 『如何有效運用工具來協助撰稿』。</para>
+
+ <para><indexterm>
+ <primary>Membership</primary>
+ </indexterm>
+ 我們歡迎每個熱心的志士來加入 FDP 行列。FDP 並不限定每月必須交出多少稿量,才能加入。
+ 您唯一須要作的就是訂閱 &a.doc; 。</para>
+
+ <para>讀完本份文件,您將會:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>瞭解有哪些文件是由 FDP 所維護的。</para>
+ </listitem>
+
+ <listitem>
+ <para>可以看懂 FDP 所維護的 SGML 原始文件。</para>
+ </listitem>
+
+ <listitem>
+ <para>知道如何來對文件作修改。</para>
+ </listitem>
+
+ <listitem>
+ <para>知道如何投稿自己的修改部份,並最後正式進入 FreeBSD 文件內。</para>
+ </listitem>
+ </itemizedlist>
+
+ <sect1 xml:id="overview-doc">
+ <title>FreeBSD 文件的組成部分</title>
+
+ <para>FDP 總共負責 FreeBSD 的 4 種類別的文件:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>線上手冊(manual)</term>
+
+ <listitem>
+ <para>英文版的系統 manual 並不是由 FDP 所撰寫的,因為它們是屬於 base system 的部份。
+ 然而,FDP 可以(也曾這麼做過)修改這些文件,來讓這些文件寫得更清楚,甚至是勘正錯誤的地方。</para>
+
+ <para>翻譯團隊負責將系統的線上手冊翻譯為不同的語言。 這些譯本都由 FDP 維護。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>FAQ</term>
+
+ <listitem>
+ <para>FAQ 主要是收集在各論壇或 newsgroup 會常問到或有可能會問到的 FreeBSD 相關問題與答案 。
+ (簡單講,就是『問答集』格式) 通常會擺在這裡面的問答格式,不會放太長的詳細內容。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>使用手冊(Handbook)</term>
+
+ <listitem>
+ <para>使用手冊主要是給 FreeBSD 使用者提供詳盡的線上參考資料。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Web site</term>
+
+ <listitem>
+ <para>FreeBSD 主要各項介紹方面的 WWW 部份,歡迎逛逛 <link xlink:href="&url.base;/index.html">http://www.FreeBSD.org/</link>
+ 以及許多其他 mirror 站。這網站是許多人第一次接觸 FreeBSD 的地方。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>這四個文件組成部分都可透過 FreeBSD CVS tree 來取得。也就是說,這些文件的修改記錄對於任何人都是公開的,
+ 而且無論是誰都可以用像是 <application>CSup</application>, <application>CVSup</application> 或
+ <application>CTM</application> 將文件取出來(checkout)並放在自己機器上做備份或副本參考等用途。</para>
+
+ <para>此外,許多人會寫些教學文件或維護有關 FreeBSD 內容的網站。(若作者同意的話)其中有些資料會保存在 FreeBSD 正式
+ CVS repository 內。而其他的文件,可能作者不希望被放在 FreeBSD repository 內而另存他處。
+ 總之,FDP 會盡力提供這些文件的連結。</para>
+ </sect1>
+
+ <sect1 xml:id="overview-before">
+ <title>在開工之前...</title>
+
+ <para>本文假設您已經瞭解:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>如何從 FreeBSD CVS repository 更新自己電腦上的 FreeBSD 文件部份(以 <application>CVS</application>
+ 或 <application>CSup</application> 或 <application>CVSup</application> 或是
+ <application>CTM</application>) 或是用
+ <application>CVSup</application> 來下載 <emphasis>checked-out</emphasis> 的副本</para>
+ </listitem>
+
+ <listitem>
+ <para>如何用 FreeBSD Ports 套件管理機制或 &man.pkg.add.1; 來下載、安裝軟體。</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="overview-quick-start">
+ <title>快速上手篇</title>
+
+ <para>若想先自行試試看,並有信心可以作得到,那麼就照下面步驟吧。</para>
+
+ <procedure>
+ <step>
+ <para>安裝 <package>textproc/docproj</package> 這個組合型 port(meta-port)。</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/textproc/docproj</userinput>
+&prompt.root; <userinput>make JADETEX=no install</userinput></screen>
+ </step>
+
+ <step>
+ <para>下載 FreeBSD <filename>doc</filename> tree 到本機上:
+ 無論是用 CSup 或 CVSup 的 <literal>checkout</literal> 模式,
+ 或是複製完整的 CVS repository 到本機上都可以。</para>
+
+ <para>若想在本機上只跑最低限度的 CVS repository 就好,那麼必須要
+ checkout 出 <filename>doc/share</filename> 以及 <filename>doc/en_US.ISO8859-1/share</filename>
+ 這兩個目錄才行。</para>
+
+ <screen>&prompt.user; <userinput>cvs checkout doc/share</userinput>
+&prompt.user; <userinput>cvs checkout doc/en_US.ISO8859-1/share</userinput></screen>
+
+ <para>若硬碟空間還算可以的話,那可以把所有語系的 doc 都 check out 出來:</para>
+
+ <screen>&prompt.user; <userinput>cvs checkout doc</userinput></screen>
+ </step>
+
+ <step>
+ <para>可依需要從 repository 中 checkout 出來你想修改某份現有的書籍或文章內容。
+ 若打算撰寫新書或新文章的話,可以參考現有的部分作為實例來做。</para>
+
+ <para>舉例來說,若想寫篇新文章,內容是有關在 FreeBSD 與 Windows 2000 之間建立 VPN 連線,
+ 那麼可以照類似下面這樣的作法:</para>
+
+ <procedure>
+ <step>
+ <para>Check out <filename>articles</filename> 目錄:</para>
+
+ <screen>&prompt.user; <userinput>cvs checkout doc/en_US.ISO8859-1/articles</userinput></screen>
+ </step>
+
+ <step>
+ <para>複製現有的文章作為範本。在這個例子中,您打算決定把新文章放在
+ <filename>vpn-w2k</filename> 的目錄下。</para>
+
+ <screen>&prompt.user; <userinput>cd doc/en_US.ISO8859-1/articles</userinput>
+&prompt.user; <userinput>cp -R committers-guide vpn-w2k</userinput></screen>
+ </step>
+ </procedure>
+
+ <para>若是要修改現有文章,像是 FAQ(擺在 <filename>doc/en_US.ISO8859-1/books/faq</filename>)
+ ,那麼要從 repository 中取出來(check out):</para>
+
+ <screen>&prompt.user; <userinput>cvs checkout doc/en_US.ISO8859-1/books/faq</userinput></screen>
+ </step>
+
+ <step>
+ <para>以編輯器來編寫 <filename>.xml</filename> 檔。</para>
+ </step>
+
+ <step>
+ <para>以 <buildtarget>lint</buildtarget> 當輔助參數,來快速檢測文件結構及連結有無錯誤,
+ 以下這個指令,實際上不會進行耗時的編書過程,只是先測試文件有無錯誤。</para>
+
+ <screen>&prompt.user; <userinput>make lint</userinput></screen>
+
+ <para>當編書的一切都就緒時,這時你可以用 <varname>FORMATS</varname>
+ 變數來指定產生的格式為哪一種。 目前支援的格式共有:
+ <literal>html</literal>, <literal>html-split</literal>,
+ <literal>txt</literal>, <literal>ps</literal>,
+ <literal>pdf</literal>, <literal>rtf</literal> 。
+ 所支援的格式列表最新版,可參考
+ <filename>doc/share/mk/doc.docbook.mk</filename> 檔。 請記得:
+ 在單一指令中,若要同時產生多種格式的話,應使用引號(quotes)來將這些格式括起來。</para>
+
+ <para>舉例來說,若只要產生
+ <literal>html</literal> 格式就好,那麼就打:</para>
+
+ <screen>&prompt.user; <userinput>make FORMATS=html</userinput></screen>
+
+ <para>但若希望有 <literal>html</literal> 及 <literal>txt</literal> 格式的話,
+ 你可能要打兩次 &man.make.1; 指令才能完成:</para>
+
+ <screen>&prompt.user; <userinput>make FORMATS=html</userinput>
+&prompt.user; <userinput>make FORMATS=txt</userinput></screen>
+
+ <para>其實,也可以用單一指令來完成:</para>
+
+ <screen>&prompt.user; <userinput>make FORMATS="html txt"</userinput></screen>
+ </step>
+
+ <step>
+ <para>最後,以 &man.send-pr.1; 來提交修改的部份。</para>
+ </step>
+ </procedure>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/fdp-primer/psgml-mode/chapter.xml b/zh_TW.UTF-8/books/fdp-primer/psgml-mode/chapter.xml
new file mode 100644
index 0000000000..6edba25352
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/psgml-mode/chapter.xml
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 1998, 1999 Nik Clayton, All rights reserved.
+
+ Redistribution and use in source (SGML DocBook) and 'compiled' forms
+ (SGML HTML, PDF, PostScript, RTF and so forth) with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code (SGML DocBook) must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+ 2. Redistributions in compiled form (transformed to other DTDs,
+ converted to PDF, PostScript, RTF and other formats) must reproduce
+ the above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ $FreeBSD$
+ Original revision: 1.10
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="psgml-mode">
+ <title>Using <literal>sgml-mode</literal> with
+ <application>Emacs</application></title>
+
+ <para>Recent versions of <application>Emacs</application> or <application>XEmacs</application> (available from the ports
+ collection) contain a very useful package called PSGML. Automatically
+ invoked when a file with the <filename>.xml</filename> extension is loaded,
+ or by typing <command>M-x sgml-mode</command>, it is a major mode for
+ dealing with SGML files, elements and attributes.</para>
+
+ <para>An understanding of some of the commands provided by this mode can
+ make working with SGML documents such as the Handbook much easier.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><command>C-c C-e</command></term>
+
+ <listitem>
+ <para>Runs <literal>sgml-insert-element</literal>. You will be
+ prompted for the name of the element to insert at the current point.
+ You can use the TAB key to complete the element. Elements that are
+ not valid at the current point will be disallowed.</para>
+
+ <para>The start and end tags for the element will be inserted. If the
+ element contains other, mandatory, elements then these will be
+ inserted as well.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>C-c =</command></term>
+
+ <listitem>
+ <para>Runs <literal>sgml-change-element-name</literal>. Place the
+ point within an element and run this command. You will be prompted
+ for the name of the element to change to. Both the start and end
+ tags of the current element will be changed to the new
+ element.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>C-c C-r</command></term>
+
+ <listitem>
+ <para>Runs <literal>sgml-tag-region</literal>. Select some text (move
+ to start of text, C-space, move to end of text, C-space) and then
+ run this command. You will be prompted for the element to use. This
+ element will then be inserted immediately before and after your
+ marked region.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>C-c -</command></term>
+
+ <listitem>
+ <para>Runs <literal>sgml-untag-element</literal>. Place the point
+ within the start or end tag of an element you want to remove, and
+ run this command. The element's start and end tags will be
+ removed.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>C-c C-q</command></term>
+
+ <listitem>
+ <para>Runs <literal>sgml-fill-element</literal>. Will recursively fill
+ (i.e., reformat) content from the current element in. The filling
+ <emphasis>will</emphasis> affect content in which whitespace is
+ significant, such as within <tag>programlisting</tag>
+ elements, so run this command with care.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>C-c C-a</command></term>
+
+ <listitem>
+ <para>Runs <literal>sgml-edit-attributes</literal>. Opens a second
+ buffer containing a list of all the attributes for the closest
+ enclosing element, and their current values. Use TAB to navigate
+ between attributes, <command>C-k</command> to remove an existing
+ value and replace it with a new one, <command>C-c C-c</command>
+ to close this buffer and return to the main document.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>C-c C-v</command></term>
+
+ <listitem>
+ <para>Runs <literal>sgml-validate</literal>. Prompts you to save the
+ current document (if necessary) and then runs an SGML validator. The
+ output from the validator is captured into a new buffer, and you can
+ then navigate from one troublespot to the next, fixing markup errors
+ as you go.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>C-c /</command></term>
+
+ <listitem>
+ <para>Runs <literal>sgml-insert-end-tag</literal>. Inserts the
+ end tag for the current open element.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>Doubtless there are other useful functions of this mode, but those are
+ the ones I use most often.</para>
+
+ <para>You can also use the following entries in
+ <filename>.emacs</filename> to set proper spacing, indentation,
+ and column width for working with the Documentation Project.</para>
+
+ <programlisting>
+ (defun local-sgml-mode-hook
+ (setq fill-column 70
+ indent-tabs-mode nil
+ next-line-add-newlines nil
+ standard-indent 4
+ sgml-indent-data t)
+ (auto-fill-mode t)
+ (setq sgml-catalog-files '("/usr/local/share/xml/catalog")))
+ (add-hook 'psgml-mode-hook
+ '(lambda () (local-psgml-mode-hook)))
+ </programlisting>
+
+</chapter>
diff --git a/zh_TW.UTF-8/books/fdp-primer/see-also/chapter.xml b/zh_TW.UTF-8/books/fdp-primer/see-also/chapter.xml
new file mode 100644
index 0000000000..89f409164e
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/see-also/chapter.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 1998, 1999 Nik Clayton, All rights reserved.
+
+ Redistribution and use in source (SGML DocBook) and 'compiled' forms
+ (SGML HTML, PDF, PostScript, RTF and so forth) with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code (SGML DocBook) must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+ 2. Redistributions in compiled form (transformed to other DTDs,
+ converted to PDF, PostScript, RTF and other formats) must reproduce
+ the above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ $FreeBSD$
+ Original revision: 1.13
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="see-also">
+ <title>他山之石</title>
+
+ <para>This document is deliberately not an exhaustive discussion of SGML,
+ the DTDs listed, and the FreeBSD Documentation Project. For more
+ information about these, you are encouraged to see the following web
+ sites.</para>
+
+ <sect1 xml:id="see-also-fdp">
+ <title>The FreeBSD Documentation Project</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="&url.base;/docproj/index.html">The FreeBSD
+ Documentation Project web pages</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="&url.books.handbook;/index.html">The FreeBSD Handbook</link></para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="see-also-sgml">
+ <title>SGML</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="http://www.oasis-open.org/cover/">The SGML/XML web
+ page</link>, a comprehensive SGML resource</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://etext.virginia.edu/bin/tei-tocs?div=DIV1&amp;id=SG">Gentle introduction to SGML</link></para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="see-also-html">
+ <title>HTML</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="http://www.w3.org/">The World Wide Web
+ Consortium</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.w3.org/TR/REC-html40/">The HTML 4.0
+ specification</link></para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="see-also-docbook">
+ <title>DocBook</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="http://www.oasis-open.org/docbook/">The DocBook
+ Technical Committee</link>, maintainers of the DocBook DTD</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.docbook.org/">DocBook: The Definitive
+ Guide</link>, the online documentation for the DocBook
+ DTD.</para>
+
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://docbook.sourceforge.net/">The DocBook Open
+ Repository</link> contains DSSSL stylesheets and other resources
+ for people using DocBook.</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="see-also-linuxdoc">
+ <title>The Linux Documentation Project</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="http://www.linuxdoc.org/">The Linux Documentation
+ Project web pages</link></para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/fdp-primer/sgml-markup/chapter.xml b/zh_TW.UTF-8/books/fdp-primer/sgml-markup/chapter.xml
new file mode 100644
index 0000000000..6b0907ff57
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/sgml-markup/chapter.xml
@@ -0,0 +1,2682 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 1998, 1999 Nik Clayton, All rights reserved.
+
+ Redistribution and use in source (SGML DocBook) and 'compiled' forms
+ (SGML HTML, PDF, PostScript, RTF and so forth) with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code (SGML DocBook) must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+ 2. Redistributions in compiled form (transformed to other DTDs,
+ converted to PDF, PostScript, RTF and other formats) must reproduce
+ the above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ $FreeBSD$
+ Original revision: 1.73
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="sgml-markup">
+ <title>SGML Markup</title>
+
+ <para>This chapter describes the two markup languages you will encounter
+ when you contribute to the FreeBSD documentation project. Each section
+ describes the markup language, and details the markup that you are likely
+ to want to use, or that is already in use.</para>
+
+ <para>These markup languages contain a large number of elements, and it can
+ be confusing sometimes to know which element to use for a particular
+ situation. This section goes through the elements you are most likely to
+ need, and gives examples of how you would use them.</para>
+
+ <para>This is <emphasis>not</emphasis> an exhaustive list of elements, since
+ that would just reiterate the documentation for each language. The aim of
+ this section is to list those elements more likely to be useful to you.
+ If you have a question about how best to markup a particular piece of
+ content, please post it to the &a.doc;.</para>
+
+ <note>
+ <title>Inline vs. block</title>
+
+ <para>In the remainder of this document, when describing elements,
+ <emphasis>inline</emphasis> means that the element can occur within a
+ block element, and does not cause a line break. A
+ <emphasis>block</emphasis> element, by comparison, will cause a line
+ break (and other processing) when it is encountered.</para>
+ </note>
+
+ <sect1 xml:id="sgml-markup-html">
+ <title>HTML</title>
+
+ <para>HTML, the HyperText Markup Language, is the markup language of
+ choice on the World Wide Web. More information can be found at
+ &lt;URL:<uri xlink:href="http://www.w3.org/">http://www.w3.org/</uri>&gt;.</para>
+
+ <para>HTML is used to markup pages on the FreeBSD web site. It should not
+ (generally) be used to mark up other documentation,
+ since DocBook offers a
+ far richer set of elements to choose from. Consequently, you will
+ normally only encounter HTML pages if you are writing for the web
+ site.</para>
+
+ <para>HTML has gone through a number of versions, 1, 2, 3.0, 3.2, and the
+ latest, 4.0 (available in both <emphasis>strict</emphasis> and
+ <emphasis>loose</emphasis> variants).</para>
+
+ <para>The HTML DTDs are available from the ports collection in the
+ <package>textproc/html</package> port. They are automatically
+ installed as part of the <package>textproc/docproj</package>
+ port.</para>
+
+ <sect2>
+ <title>Formal Public Identifier (FPI)</title>
+
+ <para>There are a number of HTML FPIs, depending upon the version (also
+ known as the level) of HTML that you want to declare your document to
+ be compliant with.</para>
+
+ <para>The majority of HTML documents on the FreeBSD web site comply with
+ the loose version of HTML 4.0.</para>
+
+ <programlisting>PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Sectional elements</title>
+
+ <para>An HTML document is normally split into two sections. The first
+ section, called the <emphasis>head</emphasis>, contains
+ meta-information about the document, such as its title, the name of
+ the author, the parent document, and so on. The second section, the
+ <emphasis>body</emphasis>, contains the content that will be displayed
+ to the user.</para>
+
+ <para>These sections are indicated with <tag>head</tag> and
+ <tag>body</tag> elements respectively. These elements are
+ contained within the top-level <tag>html</tag> element.</para>
+
+ <example>
+ <title>Normal HTML document structure</title>
+
+ <programlisting>&lt;html&gt;
+ &lt;head&gt;
+ &lt;title&gt;<replaceable>The document's title</replaceable>&lt;/title&gt;
+ &lt;/head&gt;
+
+ &lt;body&gt;
+
+ &hellip;
+
+ &lt;/body&gt;
+&lt;/html&gt;</programlisting>
+ </example>
+ </sect2>
+
+ <sect2>
+ <title>Block elements</title>
+
+ <sect3>
+ <title>Headings</title>
+
+ <para>HTML allows you to denote headings in your document, at up to
+ six different levels.</para>
+
+ <para>The largest and most prominent heading is <tag>h1</tag>,
+ then <tag>h2</tag>, continuing down to
+ <tag>h6</tag>.</para>
+
+ <para>The element's content is the text of the heading.</para>
+
+ <example>
+ <title><tag>h1</tag>, <tag>h2</tag>, etc.</title>
+
+ <para>Use:</para>
+
+ <programlisting>&lt;h1&gt;First section&lt;/h1&gt;
+
+&lt;!&hyphen;- Document introduction goes here -&hyphen;&gt;
+
+&lt;h2&gt;This is the heading for the first section&lt;/h2&gt;
+
+&lt;!&hyphen;- Content for the first section goes here -&hyphen;&gt;
+
+&lt;h3&gt;This is the heading for the first sub-section&lt;/h3&gt;
+
+&lt;!&hyphen;- Content for the first sub-section goes here -&hyphen;&gt;
+
+&lt;h2&gt;This is the heading for the second section&lt;/h2&gt;
+
+&lt;!&hyphen;- Content for the second section goes here -&hyphen;&gt;</programlisting>
+ </example>
+
+ <para>Generally, an HTML page should have one first level heading
+ (<tag>h1</tag>). This can contain many second level
+ headings (<tag>h2</tag>), which can in turn contain many
+ third level headings. Each
+ <tag>h<replaceable>n</replaceable></tag> element should have
+ the same element, but one further up the hierarchy, preceding it.
+ Leaving gaps in the numbering is to be avoided.</para>
+
+ <example>
+ <title>Bad ordering of
+ <tag>h<replaceable>n</replaceable></tag> elements</title>
+
+ <para>Use:</para>
+
+ <programlisting>&lt;h1&gt;First section&lt;/h1&gt;
+
+&lt;!&hyphen;- Document introduction -&hyphen;&gt;
+
+&lt;h3&gt;Sub-section&lt;/h3&gt;
+
+&lt;!&hyphen;- This is bad, &lt;h2&gt; has been left out -&hyphen;&gt;</programlisting>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Paragraphs</title>
+
+ <para>HTML supports a single paragraph element,
+ <tag>p</tag>.</para>
+
+ <example>
+ <title><tag>p</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<p>This is a paragraph. It can contain just about any
+ other element.</p>]]></programlisting>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Block quotations</title>
+
+ <para>A block quotation is an extended quotation from another document
+ that should not appear within the current paragraph.</para>
+
+ <example>
+ <title><tag>blockquote</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<p>A small excerpt from the US Constitution:</p>
+
+<blockquote>We the People of the United States, in Order to form
+ a more perfect Union, establish Justice, insure domestic
+ Tranquility, provide for the common defence, promote the general
+ Welfare, and secure the Blessings of Liberty to ourselves and our
+ Posterity, do ordain and establish this Constitution for the
+ United States of America.</blockquote>]]></programlisting>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Lists</title>
+
+ <para>You can present the user with three types of lists, ordered,
+ unordered, and definition.</para>
+
+ <para>Typically, each entry in an ordered list will be numbered, while
+ each entry in an unordered list will be preceded by a bullet point.
+ Definition lists are composed of two sections for each entry. The
+ first section is the term being defined, and the second section is
+ the definition of the term.</para>
+
+ <para>Ordered lists are indicated by the <tag>ol</tag>
+ element, unordered lists by the <tag>ul</tag> element, and
+ definition lists by the <tag>dl</tag> element.</para>
+
+ <para>Ordered and unordered lists contain listitems, indicated by the
+ <tag>li</tag> element. A listitem can contain textual
+ content, or it may be further wrapped in one or more
+ <tag>p</tag> elements.</para>
+
+ <para>Definition lists contain definition terms
+ (<tag>dt</tag>) and definition descriptions
+ (<tag>dd</tag>). A definition term can only contain inline
+ elements. A definition description can contain other block
+ elements.</para>
+
+ <example>
+ <title><tag>ul</tag> and <tag>ol</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<p>An unordered list. Listitems will probably be
+ preceded by bullets.</p>
+
+<ul>
+ <li>First item</li>
+
+ <li>Second item</li>
+
+ <li>Third item</li>
+</ul>
+
+<p>An ordered list, with list items consisting of multiple
+ paragraphs. Each item (note: not each paragraph) will be
+ numbered.</p>
+
+<ol>
+ <li><p>This is the first item. It only has one paragraph.</p></li>
+
+ <li><p>This is the first paragraph of the second item.</p>
+
+ <p>This is the second paragraph of the second item.</p></li>
+
+ <li><p>This is the first and only paragraph of the third
+ item.</p></li>
+</ol>]]></programlisting>
+ </example>
+
+ <example>
+ <title>Definition lists with <tag>dl</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<dl>
+ <dt>Term 1</dt>
+
+ <dd><p>Paragraph 1 of definition 1.</p>
+
+ <p>Paragraph 2 of definition 1.</p></dd>
+
+ <dt>Term 2</dt>
+
+ <dd><p>Paragraph 1 of definition 2.</p></dd>
+
+ <dt>Term 3</dt>
+
+ <dd><p>Paragraph 1 of definition 3.</p></dd>
+</dl>]]></programlisting>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Pre-formatted text</title>
+
+ <para>You can indicate that text should be shown to the user exactly
+ as it is in the file. Typically, this means that the text is shown
+ in a fixed font, multiple spaces are not merged into one, and line
+ breaks in the text are significant.</para>
+
+ <para>In order to do this, wrap the content in the
+ <tag>pre</tag> element.</para>
+
+ <example>
+ <title><tag>pre</tag></title>
+
+ <para>You could use <tag>pre</tag> to mark up an email
+ message:</para>
+
+ <programlisting><![CDATA[<pre> From: nik@FreeBSD.org
+ To: freebsd-doc@FreeBSD.org
+ Subject: New documentation available
+
+ There is a new copy of my primer for contributors to the FreeBSD
+ Documentation Project available at
+
+ &lt;URL:http://people.FreeBSD.org/~nik/primer/index.html&gt;
+
+ Comments appreciated.
+
+ N</pre>]]></programlisting>
+
+ <para>Keep in mind that <literal>&lt;</literal> and
+ <literal>&amp;</literal> still are recognized as special
+ characters in pre-formatted text. This is why the example
+ shown had to use <literal>&amp;lt;</literal> instead of
+ <literal>&lt;</literal>. For consistency,
+ <literal>&amp;gt;</literal> was used in place of
+ <literal>&gt;</literal>, too. Watch out for the special characters
+ that may appear in text copied from a plain-text source,
+ e.g., an email message or program code.</para>
+
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Tables</title>
+
+ <note>
+ <para>Most text-mode browsers (such as Lynx) do not render tables
+ particularly effectively. If you are relying on the tabular
+ display of your content, you should consider using alternative
+ markup to prevent confusion.</para>
+ </note>
+
+ <para>Mark up tabular information using the <tag>table</tag>
+ element. A table consists of one or more table rows
+ (<tag>tr</tag>), each containing one or more cells of table
+ data (<tag>td</tag>). Each cell can contain other block
+ elements, such as paragraphs or lists. It can also contain another
+ table (this nesting can repeat indefinitely). If the cell only
+ contains one paragraph then you do not need to include the
+ <tag>p</tag> element.</para>
+
+ <example>
+ <title>Simple use of <tag>table</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<p>This is a simple 2x2 table.</p>
+
+<table>
+ <tr>
+ <td>Top left cell</td>
+
+ <td>Top right cell</td>
+ </tr>
+
+ <tr>
+ <td>Bottom left cell</td>
+
+ <td>Bottom right cell</td>
+ </tr>
+</table>]]></programlisting></example>
+
+ <para>A cell can span multiple rows and columns. To indicate this,
+ add the <literal>rowspan</literal> and/or <literal>colspan</literal>
+ attributes, with values indicating the number of rows of columns
+ that should be spanned.</para>
+
+ <example>
+ <title>Using <literal>rowspan</literal></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<p>One tall thin cell on the left, two short cells next to
+ it on the right.</p>
+
+<table>
+ <tr>
+ <td rowspan="2">Long and thin</td>
+ </tr>
+
+ <tr>
+ <td>Top cell</td>
+
+ <td>Bottom cell</td>
+ </tr>
+</table>]]></programlisting>
+ </example>
+
+ <example>
+ <title>Using <literal>colspan</literal></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<p>One long cell on top, two short cells below it.</p>
+
+<table>
+ <tr>
+ <td colspan="2">Top cell</td>
+ </tr>
+
+ <tr>
+ <td>Bottom left cell</td>
+
+ <td>Bottom right cell</td>
+ </tr>
+</table>]]></programlisting>
+ </example>
+
+ <example>
+ <title>Using <literal>rowspan</literal> and
+ <literal>colspan</literal> together</title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<p>On a 3x3 grid, the top left block is a 2x2 set of
+ cells merged into one. The other cells are normal.</p>
+
+<table>
+ <tr>
+ <td colspan="2" rowspan="2">Top left large cell</td>
+
+ <td>Top right cell</td>
+ </tr>
+
+ <tr>
+ <td>Middle right cell</td>
+ </tr>
+
+ <tr>
+ <td>Bottom left cell</td>
+
+ <td>Bottom middle cell</td>
+
+ <td>Bottom right cell</td>
+ </tr>
+</table>]]></programlisting>
+ </example>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>In-line elements</title>
+
+ <sect3>
+ <title>Emphasizing information</title>
+
+ <para>You have two levels of emphasis available in HTML,
+ <tag>em</tag> and <tag>strong</tag>.
+ <tag>em</tag> is for a normal level of emphasis and
+ <tag>strong</tag> indicates stronger emphasis.</para>
+
+ <para>Typically, <tag>em</tag> is rendered in italic and
+ <tag>strong</tag> is rendered in bold. This is not always
+ the case, however, and you should not rely on it.</para>
+
+ <example>
+ <title><tag>em</tag> and <tag>strong</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<p><em>This</em> has been emphasized, while
+ <strong>this</strong> has been strongly emphasized.</p>]]></programlisting>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Bold and italics</title>
+
+ <para>Because HTML includes presentational markup, you can also
+ indicate that particular content should be rendered in bold or
+ italic. The elements are <tag>b</tag> and
+ <tag>i</tag> respectively.</para>
+
+ <example>
+ <title><tag>b</tag> and <tag>i</tag></title>
+
+ <programlisting><![CDATA[<p><b>This</b> is in bold, while <i>this</i> is
+ in italics.</p>]]></programlisting>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Indicating fixed pitch text</title>
+
+ <para>If you have content that should be rendered in a fixed pitch
+ (typewriter) typeface, use <tag>tt</tag> (for
+ <quote>teletype</quote>).</para>
+
+ <example>
+ <title><tag>tt</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<p>This document was originally written by
+ Nik Clayton, who can be reached by email as
+ <tt>nik@FreeBSD.org</tt>.</p>]]></programlisting>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Content size</title>
+
+ <para>You can indicate that content should be shown in a larger or
+ smaller font. There are three ways of doing this.</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Use <tag>big</tag> and <tag>small</tag>
+ around the content you wish to change size. These tags can be
+ nested, so <literal>&lt;big&gt;&lt;big&gt;This is much
+ bigger&lt;/big&gt;&lt;/big&gt;</literal> is possible.</para>
+ </listitem>
+
+ <listitem>
+ <para>Use <tag>font</tag> with the <literal>size</literal>
+ attribute set to <literal>+1</literal> or <literal>-1</literal>
+ respectively. This has the same effect as using
+ <tag>big</tag> or <tag>small</tag>. However,
+ the use of this approach is deprecated.</para>
+ </listitem>
+
+ <listitem>
+ <para>Use <tag>font</tag> with the <literal>size</literal>
+ attribute set to a number between 1 and 7. The default font size
+ is <literal>3</literal>. This approach is deprecated.</para>
+ </listitem>
+ </orderedlist>
+
+ <example>
+ <title><tag>big</tag>, <tag>small</tag>, and
+ <tag>font</tag></title>
+
+ <para>The following fragments all do the same thing.</para>
+
+ <programlisting><![CDATA[<p>This text is <small>slightly smaller</small>. But
+ this text is <big>slightly bigger</big>.</p>
+
+<p>This text is <font size="-1">slightly smaller</font>. But
+ this text is <font size="+1">slightly bigger</font.</p>
+
+<p>This text is <font size="2">slightly smaller</font>. But
+ this text is <font size="4">slightly bigger</font>.</p>]]></programlisting>
+ </example>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Links</title>
+
+ <note>
+ <para>Links are also in-line elements.</para>
+ </note>
+
+ <sect3>
+ <title>Linking to other documents on the WWW</title>
+
+ <para>In order to include a link to another document on the WWW you
+ must know the URL of the document you want to link to.</para>
+
+ <para>The link is indicated with <tag>a</tag>, and the
+ <literal>href</literal> attribute contains the URL of the target
+ document. The content of the element becomes the link, and is
+ normally indicated to the user in some way (underlining, change of
+ color, different mouse cursor when over the link, and so
+ on).</para>
+
+ <example>
+ <title>Using <literal>&lt;a href="..."&gt;</literal></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<p>More information is available at the
+ <a href="http://www.FreeBSD.org/">FreeBSD web site</a>.</p>]]></programlisting>
+ </example>
+
+ <para>These links will take the user to the top of the chosen
+ document.</para>
+ </sect3>
+
+ <sect3>
+ <title>Linking to other parts of documents</title>
+
+ <para>Linking to a point within another document (or within the same
+ document) requires that the document author include anchors that you
+ can link to.</para>
+
+ <para>Anchors are indicated with <tag>a</tag> and the
+ <literal>name</literal> attribute instead of
+ <literal>href</literal>.</para>
+
+ <example>
+ <title>Using <literal>&lt;a name="..."&gt;</literal></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<p><a name="para1">This</a> paragraph can be referenced
+ in other links with the name <tt>para1</tt>.</p>]]></programlisting>
+ </example>
+
+ <para>To link to a named part of a document, write a normal link to
+ that document, but include the name of the anchor after a
+ <literal>#</literal> symbol.</para>
+
+ <example>
+ <title>Linking to a named part of another document</title>
+
+ <para>Assume that the <literal>para1</literal> example resides in a
+ document called <filename>foo.html</filename>.</para>
+
+ <programlisting><![CDATA[<p>More information can be found in the
+ <a href="foo.html#para1">first paragraph</a> of
+ <tt>foo.html</tt>.</p>]]></programlisting>
+ </example>
+
+ <para>If you are linking to a named anchor within the same document
+ then you can omit the document's URL, and just include the name of
+ the anchor (with the preceding <literal>#</literal>).</para>
+
+ <example>
+ <title>Linking to a named part of the same document</title>
+
+ <para>Assume that the <literal>para1</literal> example resides in
+ this document:</para>
+
+ <programlisting><![CDATA[<p>More information can be found in the
+ <a href="#para1">first paragraph</a> of this
+ document.</p>]]></programlisting>
+ </example>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="sgml-markup-docbook">
+ <title>DocBook</title>
+
+ <para>DocBook was originally developed by HaL Computer Systems and O'Reilly
+ &amp; Associates to be a DTD for writing technical documentation
+ <footnote><para>A short history can be found under <link xlink:href="http://www.oasis-open.org/committees/docbook/intro.shtml">
+ http://www.oasis-open.org/committees/docbook/intro.shtml</link>.
+ </para></footnote>. Since 1998 it is maintained by the <link xlink:href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=docbook">
+ DocBook Technical Committee</link>. As such, and unlike LinuxDoc
+ and HTML, DocBook is very heavily oriented towards markup that
+ describes <emphasis>what</emphasis> something is, rather than describing
+ <emphasis>how</emphasis> it should be presented.</para>
+
+ <note>
+ <title><literal>formal</literal> vs. <literal>informal</literal></title>
+
+ <para>Some elements may exist in two forms, <emphasis>formal</emphasis>
+ and <emphasis>informal</emphasis>. Typically, the formal version of
+ the element will consist of a title followed by the informal
+ version of the element. The informal version will not have a
+ title.</para>
+ </note>
+
+ <para>The DocBook DTD is available from the ports collection in the
+ <package>textproc/docbook</package> port. It is automatically
+ installed as part of the <package>textproc/docproj</package>
+ port.</para>
+
+ <sect2>
+ <title>FreeBSD extensions</title>
+
+ <para>The FreeBSD Documentation Project has extended the DocBook DTD by
+ adding some new elements. These elements serve to make some of the
+ markup more precise.</para>
+
+ <para>Where a FreeBSD specific element is listed below it is clearly
+ marked.</para>
+
+ <para>Throughout the rest of this document, the term
+ <quote>DocBook</quote> is used to mean the FreeBSD extended DocBook
+ DTD.</para>
+
+ <note>
+ <para>There is nothing about these extensions that is FreeBSD
+ specific, it was just felt that they were useful enhancements for
+ this particular project. Should anyone from any of the other *nix
+ camps (NetBSD, OpenBSD, Linux, &hellip;) be interested in
+ collaborating on a standard DocBook extension set, please get in
+ touch with &a.doceng;.</para>
+ </note>
+
+ <para>The FreeBSD extensions are not (currently) in the ports
+ collection. They are stored in the FreeBSD CVS tree, as <link xlink:href="http://www.FreeBSD.org/cgi/cvsweb.cgi/doc/share/xml/freebsd.dtd">doc/share/xml/freebsd.dtd</link>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Formal Public Identifier (FPI)</title>
+
+ <para>In compliance with the DocBook guidelines for writing FPIs for
+ DocBook customizations, the FPI for the FreeBSD extended DocBook DTD
+ is:</para>
+
+ <programlisting>PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN"</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Document structure</title>
+
+ <para>DocBook allows you to structure your documentation in several
+ ways. In the FreeBSD Documentation Project we are using two primary
+ types of DocBook document: the book and the article.</para>
+
+ <para>A book is organized into <tag>chapter</tag>s. This is a
+ mandatory requirement. There may be <tag>part</tag>s between
+ the book and the chapter to provide another layer of organization.
+ The Handbook is arranged in this way.</para>
+
+ <para>A chapter may (or may not) contain one or more sections. These
+ are indicated with the <tag>sect1</tag> element. If a section
+ contains another section then use the <tag>sect2</tag>
+ element, and so on, up to <tag>sect5</tag>.</para>
+
+ <para>Chapters and sections contain the remainder of the content.</para>
+
+ <para>An article is simpler than a book, and does not use chapters.
+ Instead, the content of an article is organized into one or more
+ sections, using the same <tag>sect1</tag> (and
+ <tag>sect2</tag> and so on) elements that are used in
+ books.</para>
+
+ <para>Obviously, you should consider the nature of the documentation you
+ are writing in order to decide whether it is best marked up as a book
+ or an article. Articles are well suited to information that does not
+ need to be broken down into several chapters, and that is, relatively
+ speaking, quite short, at up to 20-25 pages of content. Books are
+ best suited to information that can be broken up into several
+ chapters, possibly with appendices and similar content as well.</para>
+
+ <para>The <link xlink:href="&url.base;/docs.html">FreeBSD
+ tutorials</link> are all marked up as articles, while this
+ document, the <link xlink:href="&url.books.faq;/index.html">FreeBSD
+ FAQ</link>, and the <link xlink:href="&url.books.handbook;/index.html">FreeBSD Handbook</link> are
+ all marked up as books.</para>
+
+ <sect3>
+ <title>Starting a book</title>
+
+ <para>The content of the book is contained within the
+ <tag>book</tag> element. As well as containing structural
+ markup, this element can contain elements that include additional
+ information about the book. This is either meta-information, used
+ for reference purposes, or additional content used to produce a
+ title page.</para>
+
+ <para>This additional information should be contained within
+ <tag>bookinfo</tag>.</para>
+
+ <example>
+ <title>Boilerplate <tag>book</tag> with
+ <tag>bookinfo</tag></title>
+
+ <!-- Can't put this in a marked section because of the
+ replaceable elements -->
+ <programlisting>&lt;book&gt;
+ &lt;bookinfo&gt;
+ &lt;title&gt;<replaceable>Your title here</replaceable>&lt;/title&gt;
+
+ &lt;author&gt;
+ &lt;firstname&gt;<replaceable>Your first name</replaceable>&lt;/firstname&gt;
+ &lt;surname&gt;<replaceable>Your surname</replaceable>&lt;/surname&gt;
+ &lt;affiliation&gt;
+ &lt;address&gt;&lt;email&gt;<replaceable>Your email address</replaceable>&lt;/email&gt;&lt;/address&gt;
+ &lt;/affiliation&gt;
+ &lt;/author&gt;
+
+ &lt;copyright&gt;
+ &lt;year&gt;<replaceable>1998</replaceable>&lt;/year&gt;
+ &lt;holder role="mailto:<replaceable>your email address</replaceable>"&gt;<replaceable>Your name</replaceable>&lt;/holder&gt;
+ &lt;/copyright&gt;
+
+ &lt;releaseinfo&gt;&#36;FreeBSD&#36;&lt;/releaseinfo&gt;
+
+ &lt;abstract&gt;
+ &lt;para&gt;<replaceable>Include an abstract of the book's contents here.</replaceable>&lt;/para&gt;
+ &lt;/abstract&gt;
+ &lt;/bookinfo&gt;
+
+ &hellip;
+
+&lt;/book&gt;</programlisting>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Starting an article</title>
+
+ <para>The content of the article is contained within the
+ <tag>article</tag> element. As well as containing
+ structural markup, this element can contain elements that include
+ additional information about the article. This is either
+ meta-information, used for reference purposes, or additional content
+ used to produce a title page.</para>
+
+ <para>This additional information should be contained within
+ <tag>articleinfo</tag>.</para>
+
+ <example>
+ <title>Boilerplate <tag>article</tag> with
+ <tag>articleinfo</tag></title>
+
+ <!-- Can't put this in a marked section because of the
+ replaceable elements -->
+ <programlisting>&lt;article&gt;
+ &lt;articleinfo&gt;
+ &lt;title&gt;<replaceable>Your title here</replaceable>&lt;/title&gt;
+
+ &lt;author&gt;
+ &lt;firstname&gt;<replaceable>Your first name</replaceable>&lt;/firstname&gt;
+ &lt;surname&gt;<replaceable>Your surname</replaceable>&lt;/surname&gt;
+ &lt;affiliation&gt;
+ &lt;address&gt;&lt;email&gt;<replaceable>Your email address</replaceable>&lt;/email&gt;&lt;/address&gt;
+ &lt;/affiliation&gt;
+ &lt;/author&gt;
+
+ &lt;copyright&gt;
+ &lt;year&gt;<replaceable>1998</replaceable>&lt;/year&gt;
+ &lt;holder role="mailto:<replaceable>your email address</replaceable>"&gt;<replaceable>Your name</replaceable>&lt;/holder&gt;
+ &lt;/copyright&gt;
+
+ &lt;releaseinfo&gt;&#36;FreeBSD&#36;&lt;/releaseinfo&gt;
+
+ &lt;abstract&gt;
+ &lt;para&gt;<replaceable>Include an abstract of the article's contents here.</replaceable>&lt;/para&gt;
+ &lt;/abstract&gt;
+ &lt;/articleinfo&gt;
+
+ &hellip;
+
+&lt;/article&gt;</programlisting>
+ </example>
+ </sect3>
+ <sect3>
+ <title>Indicating chapters</title>
+
+ <para>Use <tag>chapter</tag> to mark up your chapters. Each
+ chapter has a mandatory <tag>title</tag>. Articles do not
+ contain chapters, they are reserved for books.</para>
+
+ <example>
+ <title>A simple chapter</title>
+
+ <programlisting><![CDATA[<chapter>
+ <title>The chapter's title</title>
+
+ ...
+</chapter>]]></programlisting>
+ </example>
+
+ <para>A chapter cannot be empty; it must contain elements in addition
+ to <tag>title</tag>. If you need to include an empty
+ chapter then just use an empty paragraph.</para>
+
+ <example>
+ <title>Empty chapters</title>
+
+ <programlisting><![CDATA[<chapter>
+ <title>This is an empty chapter</title>
+
+ <para></para>
+</chapter>]]></programlisting>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Sections below chapters</title>
+
+ <para>In books, chapters may (but do not need to) be broken up into
+ sections, subsections, and so on. In articles, sections are the
+ main structural element, and each article must contain at least one
+ section. Use the
+ <tag>sect<replaceable>n</replaceable></tag> element. The
+ <replaceable>n</replaceable> indicates the section number, which
+ identifies the section level.</para>
+
+ <para>The first <tag>sect<replaceable>n</replaceable></tag> is
+ <tag>sect1</tag>. You can have one or more of these in a
+ chapter. They can contain one or more <tag>sect2</tag>
+ elements, and so on, down to <tag>sect5</tag>.</para>
+
+ <example>
+ <title>Sections in chapters</title>
+
+ <programlisting><![CDATA[<chapter>
+ <title>A sample chapter</title>
+
+ <para>Some text in the chapter.</para>
+
+ <sect1>
+ <title>First section (1.1)</title>
+
+ &hellip;
+ </sect1>
+
+ <sect1>
+ <title>Second section (1.2)</title>
+
+ <sect2>
+ <title>First sub-section (1.2.1)</title>
+
+ <sect3>
+ <title>First sub-sub-section (1.2.1.1)</title>
+
+ &hellip;
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Second sub-section (1.2.2)</title>
+
+ &hellip;
+ </sect2>
+ </sect1>
+</chapter>]]></programlisting>
+ </example>
+
+ <note>
+ <para>This example includes section numbers in the section titles.
+ You should not do this in your documents. Adding the section
+ numbers is carried out by the stylesheets (of which more
+ later), and you do not need to manage them yourself.</para>
+ </note>
+ </sect3>
+
+ <sect3>
+ <title>Subdividing using <tag>part</tag>s</title>
+
+ <para>You can introduce another layer of organization between
+ <tag>book</tag> and <tag>chapter</tag> with one or
+ more <tag>part</tag>s. This cannot be done in an
+ <tag>article</tag>.</para>
+
+ <programlisting><![CDATA[<part>
+ <title>Introduction</title>
+
+ <chapter>
+ <title>Overview</title>
+
+ ...
+ </chapter>
+
+ <chapter>
+ <title>What is FreeBSD?</title>
+
+ ...
+ </chapter>
+
+ <chapter>
+ <title>History</title>
+
+ ...
+ </chapter>
+</part>]]></programlisting>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Block elements</title>
+
+ <sect3>
+ <title>Paragraphs</title>
+
+ <para>DocBook supports three types of paragraphs:
+ <tag>formalpara</tag>, <tag>para</tag>, and
+ <tag>simpara</tag>.</para>
+
+ <para>Most of the time you will only need to use
+ <tag>para</tag>. <tag>formalpara</tag> includes a
+ <tag>title</tag> element, and <tag>simpara</tag>
+ disallows some elements from within <tag>para</tag>. Stick
+ with <tag>para</tag>.</para>
+
+ <example>
+ <title><tag>para</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para>This is a paragraph. It can contain just about any
+ other element.</para> ]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para>This is a paragraph. It can contain just about any other
+ element.</para>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Block quotations</title>
+
+ <para>A block quotation is an extended quotation from another document
+ that should not appear within the current paragraph. You will
+ probably only need it infrequently.</para>
+
+ <para>Blockquotes can optionally contain a title and an attribution
+ (or they can be left untitled and unattributed).</para>
+
+ <example>
+ <title><tag>blockquote</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para>A small excerpt from the US Constitution:</para>
+
+<blockquote>
+ <title>Preamble to the Constitution of the United States</title>
+
+ <attribution>Copied from a web site somewhere</attribution>
+
+ <para>We the People of the United States, in Order to form a more perfect
+ Union, establish Justice, insure domestic Tranquility, provide for the
+ common defence, promote the general Welfare, and secure the Blessings
+ of Liberty to ourselves and our Posterity, do ordain and establish this
+ Constitution for the United States of America.</para>
+</blockquote>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <blockquote>
+ <title>Preamble to the Constitution of the United States</title>
+
+ <attribution>Copied from a web site somewhere</attribution>
+
+ <para>We the People of the United States, in Order to form a more
+ perfect Union, establish Justice, insure domestic Tranquility,
+ provide for the common defence, promote the general Welfare, and
+ secure the Blessings of Liberty to ourselves and our Posterity,
+ do ordain and establish this Constitution for the United States
+ of America.</para>
+ </blockquote>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Tips, notes, warnings, cautions, important information and
+ sidebars.</title>
+
+ <para>You may need to include extra information separate from the
+ main body of the text. Typically this is <quote>meta</quote>
+ information that the user should be aware of.</para>
+
+ <para>Depending on the nature of the information, one of
+ <tag>tip</tag>, <tag>note</tag>,
+ <tag>warning</tag>, <tag>caution</tag>, and
+ <tag>important</tag> should be used. Alternatively, if the
+ information is related to the main text but is not one of the above,
+ use <tag>sidebar</tag>.</para>
+
+ <para>The circumstances in which to choose one of these elements over
+ another is unclear. The DocBook documentation suggests:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>A Note is for information that should be heeded by all
+ readers.</para>
+ </listitem>
+
+ <listitem>
+ <para>An Important element is a variation on Note.</para>
+ </listitem>
+
+ <listitem>
+ <para>A Caution is for information regarding possible data loss
+ or software damage.</para>
+ </listitem>
+
+ <listitem>
+ <para>A Warning is for information regarding possible hardware
+ damage or injury to life or limb.</para>
+ </listitem>
+ </itemizedlist>
+
+ <example>
+ <title><tag>warning</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<warning>
+ <para>Installing FreeBSD may make you want to delete Windows from your
+ hard disk.</para>
+</warning>]]></programlisting>
+ </example>
+
+ <!-- Need to do this outside of the example -->
+ <warning>
+ <para>Installing FreeBSD may make you want to delete Windows from
+ your hard disk.</para>
+ </warning>
+ </sect3>
+
+ <sect3>
+ <title>Lists and procedures</title>
+
+ <para>You will often need to list pieces of information to the user,
+ or present them with a number of steps that must be carried out in
+ order to accomplish a particular goal.</para>
+
+ <para>In order to do this, use <tag>itemizedlist</tag>,
+ <tag>orderedlist</tag>, or
+ <tag>procedure</tag><footnote><para>There are other types of
+ list element in DocBook, but we are not concerned with those at
+ the moment.</para>
+ </footnote>
+ </para>
+
+ <para><tag>itemizedlist</tag> and
+ <tag>orderedlist</tag> are similar to their counterparts in
+ HTML, <tag>ul</tag> and <tag>ol</tag>. Each one
+ consists of one or more <tag>listitem</tag> elements, and
+ each <tag>listitem</tag> contains one or more block
+ elements. The <tag>listitem</tag> elements are analogous to
+ HTML's <tag>li</tag> tags. However, unlike HTML, they are
+ required.</para>
+
+ <para><tag>procedure</tag> is slightly different. It consists
+ of <tag>step</tag>s, which may in turn consists of more
+ <tag>step</tag>s or <tag>substep</tag>s. Each
+ <tag>step</tag> contains block elements.</para>
+
+ <example>
+ <title><tag>itemizedlist</tag>,
+ <tag>orderedlist</tag>, and
+ <tag>procedure</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<itemizedlist>
+ <listitem>
+ <para>This is the first itemized item.</para>
+ </listitem>
+
+ <listitem>
+ <para>This is the second itemized item.</para>
+ </listitem>
+</itemizedlist>
+
+<orderedlist>
+ <listitem>
+ <para>This is the first ordered item.</para>
+ </listitem>
+
+ <listitem>
+ <para>This is the second ordered item.</para>
+ </listitem>
+</orderedlist>
+
+<procedure>
+ <step>
+ <para>Do this.</para>
+ </step>
+
+ <step>
+ <para>Then do this.</para>
+ </step>
+
+ <step>
+ <para>And now do this.</para>
+ </step>
+</procedure>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>This is the first itemized item.</para>
+ </listitem>
+
+ <listitem>
+ <para>This is the second itemized item.</para>
+ </listitem>
+ </itemizedlist>
+
+ <orderedlist>
+ <listitem>
+ <para>This is the first ordered item.</para>
+ </listitem>
+
+ <listitem>
+ <para>This is the second ordered item.</para>
+ </listitem>
+ </orderedlist>
+ </example>
+
+ <!-- Can't have <procedure> inside <example>, so this is a cheat -->
+
+ <procedure>
+ <step>
+ <para>Do this.</para>
+ </step>
+
+ <step>
+ <para>Then do this.</para>
+ </step>
+
+ <step>
+ <para>And now do this.</para>
+ </step>
+ </procedure>
+ </sect3>
+
+ <sect3>
+ <title>Showing file samples</title>
+
+ <para>If you want to show a fragment of a file (or perhaps a complete
+ file) to the user, wrap it in the <tag>programlisting</tag>
+ element.</para>
+
+ <para>White space and line breaks within
+ <tag>programlisting</tag> <emphasis>are</emphasis>
+ significant. In particular, this means that the opening tag should
+ appear on the same line as the first line of the output, and the
+ closing tag should appear on the same line as the last line of the
+ output, otherwise spurious blank lines may be included.</para>
+
+ <example>
+ <title><tag>programlisting</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para>When you have finished, your program should look like
+ this:</para>
+
+<programlisting>#include &lt;stdio.h&gt;
+
+int
+main(void)
+{
+ printf("hello, world\n");
+}</programlisting>]]></programlisting>
+
+ <para>Notice how the angle brackets in the
+ <literal>#include</literal> line need to be referenced by their
+ entities instead of being included literally.</para>
+
+ <para>Appearance:</para>
+
+ <para>When you have finished, your program should look like
+ this:</para>
+
+ <programlisting>#include &lt;stdio.h&gt;
+
+int
+main(void)
+{
+ printf("hello, world\n");
+}</programlisting>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Callouts</title>
+
+ <para>A callout is a mechanism for referring back to an earlier piece
+ of text or specific position within an earlier example without
+ linking to it within the text.</para>
+
+ <para>To do this, mark areas of interest in your example
+ (<tag>programlisting</tag>,
+ <tag>literallayout</tag>, or whatever) with the
+ <tag>co</tag> element. Each element must have a unique
+ <literal>id</literal> assigned to it. After the example include a
+ <tag>calloutlist</tag> that refers back to the example and
+ provides additional commentary.</para>
+
+ <example>
+ <title><tag>co</tag> and
+ <tag>calloutlist</tag></title>
+
+ <programlisting><![CDATA[<para>When you have finished, your program should look like
+ this:</para>
+
+<programlisting>#include &lt;stdio.h&gt; <co id="co-ex-include"/>
+
+int <co id="co-ex-return"/>
+main(void)
+{
+ printf("hello, world\n"); <co id="co-ex-printf"/>
+}</programlisting>
+
+<calloutlist>
+ <callout arearefs="co-ex-include">
+ <para>Includes the standard IO header file.</para>
+ </callout>
+
+ <callout arearefs="co-ex-return">
+ <para>Specifies that <function>main()</function> returns an
+ int.</para>
+ </callout>
+
+ <callout arearefs="co-ex-printf">
+ <para>The <function>printf()</function> call that writes
+ <literal>hello, world</literal> to standard output.</para>
+ </callout>
+</calloutlist>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para>When you have finished, your program should look like
+ this:</para>
+
+ <programlisting>#include &lt;stdio.h&gt; <co xml:id="co-ex-include"/>
+
+int <co xml:id="co-ex-return"/>
+main(void)
+{
+ printf("hello, world\n"); <co xml:id="co-ex-printf"/>
+}</programlisting>
+
+ <calloutlist>
+ <callout arearefs="co-ex-include">
+ <para>Includes the standard IO header file.</para>
+ </callout>
+
+ <callout arearefs="co-ex-return">
+ <para>Specifies that <function>main()</function> returns an
+ int.</para>
+ </callout>
+
+ <callout arearefs="co-ex-printf">
+ <para>The <function>printf()</function> call that writes
+ <literal>hello, world</literal> to standard output.</para>
+ </callout>
+ </calloutlist>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Tables</title>
+
+ <para>Unlike HTML, you do not need to use tables for layout purposes,
+ as the stylesheet handles those issues for you. Instead, just use
+ tables for marking up tabular data.</para>
+
+ <para>In general terms (and see the DocBook documentation for more
+ detail) a table (which can be either formal or informal) consists of
+ a <tag>table</tag> element. This contains at least one
+ <tag>tgroup</tag> element, which specifies (as an attribute)
+ the number of columns in this table group. Within the tablegroup
+ you can then have one <tag>thead</tag> element, which
+ contains elements for the table headings (column headings), and one
+ <tag>tbody</tag> which contains the body of the
+ table.</para>
+
+ <para>Both <tag>tgroup</tag> and <tag>thead</tag>
+ contain <tag>row</tag> elements, which in turn contain
+ <tag>entry</tag> elements. Each <tag>entry</tag>
+ element specifies one cell in the table.</para>
+
+ <example>
+ <title><tag>informaltable</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>This is column head 1</entry>
+ <entry>This is column head 2</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>Row 1, column 1</entry>
+ <entry>Row 1, column 2</entry>
+ </row>
+
+ <row>
+ <entry>Row 2, column 1</entry>
+ <entry>Row 2, column 2</entry>
+ </row>
+ </tbody>
+ </tgroup>
+</informaltable>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>This is column head 1</entry>
+ <entry>This is column head 2</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>Row 1, column 1</entry>
+ <entry>Row 1, column 2</entry>
+ </row>
+
+ <row>
+ <entry>Row 2, column 1</entry>
+ <entry>Row 2, column 2</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </example>
+
+ <para>Always use the <literal>pgwide</literal> attribute with
+ a value of <literal>1</literal> with the
+ <tag>informaltable</tag> element. A bug in Internet
+ Explorer can cause the table to render incorrectly if this
+ is omitted.</para>
+
+ <para>If you do not want a border around the table the
+ <literal>frame</literal> attribute can be added to the
+ <tag>informaltable</tag> element with a value of
+ <literal>none</literal> (i.e., <literal>&lt;informaltable
+ frame="none"&gt;</literal>).</para>
+
+ <example>
+ <title>Tables where <literal>frame="none"</literal></title>
+
+ <para>Appearance:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>This is column head 1</entry>
+ <entry>This is column head 2</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>Row 1, column 1</entry>
+ <entry>Row 1, column 2</entry>
+ </row>
+
+ <row>
+ <entry>Row 2, column 1</entry>
+ <entry>Row 2, column 2</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Examples for the user to follow</title>
+
+ <para>A lot of the time you need to show examples for the user to
+ follow. Typically, these will consist of dialogs with the computer;
+ the user types in a command, the user gets a response back, they
+ type in another command, and so on.</para>
+
+ <para>A number of distinct elements and entities come into play
+ here.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><tag>screen</tag></term>
+
+ <listitem>
+ <para>Everything the user sees in this example will be on the
+ computer screen, so the next element is
+ <tag>screen</tag>.</para>
+
+ <para>Within <tag>screen</tag>, white space is
+ significant.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><tag>prompt</tag>,
+ <literal>&amp;prompt.root;</literal> and
+ <literal>&amp;prompt.user;</literal></term>
+
+ <listitem>
+ <para>Some of the things the user will be seeing on the screen
+ are prompts from the computer (either from the operating system, command
+ shell, or application). These should be marked up using
+ <tag>prompt</tag>.</para>
+
+ <para>As a special case, the two shell prompts for the normal
+ user and the root user have been provided as entities. Every
+ time you want to indicate the user is at a shell prompt, use
+ one of <literal>&amp;prompt.root;</literal> and
+ <literal>&amp;prompt.user;</literal> as necessary. They do
+ not need to be inside <tag>prompt</tag>.</para>
+
+ <note>
+ <para><literal>&amp;prompt.root;</literal> and
+ <literal>&amp;prompt.user;</literal> are FreeBSD
+ extensions to DocBook, and are not part of the original
+ DTD.</para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><tag>userinput</tag></term>
+
+ <listitem>
+ <para>When displaying text that the user should type in, wrap it
+ in <tag>userinput</tag> tags. It will probably be
+ displayed differently to the user.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <example>
+ <title><tag>screen</tag>, <tag>prompt</tag>, and
+ <tag>userinput</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<screen>&prompt.user; <userinput>ls -1</userinput>
+foo1
+foo2
+foo3
+&prompt.user; <userinput>ls -1 | grep foo2</userinput>
+foo2
+&prompt.user; <userinput>su</userinput>
+<prompt>Password: </prompt>
+&prompt.root; <userinput>cat foo2</userinput>
+This is the file called 'foo2'</screen>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <screen>&prompt.user; <userinput>ls -1</userinput>
+foo1
+foo2
+foo3
+&prompt.user; <userinput>ls -1 | grep foo2</userinput>
+foo2
+&prompt.user; <userinput>su</userinput>
+<prompt>Password: </prompt>
+&prompt.root; <userinput>cat foo2</userinput>
+This is the file called 'foo2'</screen>
+ </example>
+
+ <note>
+ <para>Even though we are displaying the contents of the file
+ <filename>foo2</filename>, it is <emphasis>not</emphasis> marked
+ up as <tag>programlisting</tag>. Reserve
+ <tag>programlisting</tag> for showing fragments of files
+ outside the context of user actions.</para>
+ </note>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>In-line elements</title>
+
+ <sect3>
+ <title>Emphasizing information</title>
+
+ <para>When you want to emphasize a particular word or phrase, use
+ <tag>emphasis</tag>. This may be presented as italic, or
+ bold, or might be spoken differently with a text-to-speech
+ system.</para>
+
+ <para>There is no way to change the presentation of the emphasis
+ within your document, no equivalent of HTML's <tag>b</tag>
+ and <tag>i</tag>. If the information you are presenting is
+ important then consider presenting it in
+ <tag>important</tag> rather than
+ <tag>emphasis</tag>.</para>
+
+ <example>
+ <title><tag>emphasis</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para>FreeBSD is without doubt <emphasis>the</emphasis>
+ premiere Unix like operating system for the Intel architecture.</para>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para>FreeBSD is without doubt <emphasis>the</emphasis> premiere Unix
+ like operating system for the Intel architecture.</para>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Quotations</title>
+
+ <para>To quote text from another document or source, or to denote
+ a phrase that is used figuratively, use <tag>quote</tag>.
+ Within a <tag>quote</tag> tag, you may use most of the
+ markup tags available for normal text.</para>
+
+ <example>
+ <title>Quotations</title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para>However, make sure that the search does not go beyond the
+ <quote>boundary between local and public administration</quote>,
+ as RFC 1535 calls it.</para>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para>However, make sure that the search does not go beyond the
+ <quote>boundary between local and public administration</quote>,
+ as RFC 1535 calls it.</para>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Keys, mouse buttons, and combinations</title>
+
+ <para>To refer to a specific key on the keyboard, use
+ <tag>keycap</tag>. To refer to a mouse button, use
+ <tag>mousebutton</tag>. And to refer to combinations of key
+ presses or mouse clicks, wrap them all in
+ <tag>keycombo</tag>.</para>
+
+ <para><tag>keycombo</tag> has an attribute called
+ <literal>action</literal>, which may be one of
+ <literal>click</literal>, <literal>double-click</literal>,
+ <literal>other</literal>, <literal>press</literal>,
+ <literal>seq</literal>, or <literal>simul</literal>. The last two
+ values denote whether the keys or buttons should be pressed in
+ sequence, or simultaneously.</para>
+
+ <para>The stylesheets automatically add any connecting symbols, such
+ as <literal>+</literal>, between the key names, when wrapped in
+ <tag>keycombo</tag>.</para>
+
+ <example>
+ <title>Keys, mouse buttons, and combinations</title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para>To switch to the second virtual terminal, press
+ <keycombo action="simul"><keycap>Alt</keycap>
+ <keycap>F1</keycap></keycombo>.</para>
+
+<para>To exit <command>vi</command> without saving your work, type
+ <keycombo action="seq"><keycap>Esc</keycap><keycap>:</keycap>
+ <keycap>q</keycap><keycap>!</keycap></keycombo>.</para>
+
+<para>My window manager is configured so that
+ <keycombo action="simul"><keycap>Alt</keycap>
+ <mousebutton>right</mousebutton>
+ </keycombo> mouse button is used to move windows.</para>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para>To switch to the second virtual terminal, press
+ <keycombo action="simul"><keycap>Alt</keycap>
+ <keycap>F1</keycap></keycombo>.</para>
+
+ <para>To exit <command>vi</command> without saving your work, type
+ <keycombo action="seq"><keycap>Esc</keycap><keycap>:</keycap>
+ <keycap>q</keycap><keycap>!</keycap></keycombo>.</para>
+
+ <para>My window manager is configured so that
+ <keycombo action="simul"><keycap>Alt</keycap>
+ <mousebutton>right</mousebutton>
+ </keycombo> mouse button is used to move windows.</para>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Applications, commands, options, and cites</title>
+
+ <para>You will frequently want to refer to both applications and
+ commands when writing for the Handbook. The distinction between
+ them is simple: an application is the name for a suite (or possibly
+ just 1) of programs that fulfil a particular task. A command is the
+ name of a program that the user can run.</para>
+
+ <para>In addition, you will occasionally need to list one or more of
+ the options that a command might take.</para>
+
+ <para>Finally, you will often want to list a command with its manual
+ section number, in the <quote>command(number)</quote> format so
+ common in Unix manuals.</para>
+
+ <para>Mark up application names with
+ <tag>application</tag>.</para>
+
+ <para>When you want to list a command with its manual section number
+ (which should be most of the time) the DocBook element is
+ <tag>citerefentry</tag>. This will contain a further two
+ elements, <tag>refentrytitle</tag> and
+ <tag>manvolnum</tag>. The content of
+ <tag>refentrytitle</tag> is the name of the command, and the
+ content of <tag>manvolnum</tag> is the manual page
+ section.</para>
+
+ <para>This can be cumbersome to write, and so a series of <link linkend="sgml-primer-general-entities">general entities</link>
+ have been created to make this easier. Each entity takes the form
+ <literal>&amp;man.manual-page.manual-section;</literal>.</para>
+
+ <para>The file that contains these entities is in
+ <filename>doc/share/xml/man-refs.ent</filename>, and can be
+ referred to using this FPI:</para>
+
+ <programlisting>PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN"</programlisting>
+
+ <para>Therefore, the introduction to your documentation will probably
+ look like this:</para>
+
+ <programlisting>&lt;!DOCTYPE book PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
+
+&lt;!ENTITY % man PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN"&gt;
+%man;
+
+&hellip;
+
+]&gt;</programlisting>
+
+ <para>Use <tag>command</tag> when you want to include a
+ command name <quote>in-line</quote> but present it as something the
+ user should type in.</para>
+
+ <para>Use <tag>option</tag> to mark up the options
+ which will be passed to a command.</para>
+
+ <para>When referring to the same command multiple times in
+ close proximity it is preferred to use the
+ <literal>&amp;man.command.section;</literal>
+ notation to markup the first reference and use
+ <tag>command</tag> to markup subsequent references.
+ This makes the generated output, especially HTML, appear
+ visually better.</para>
+
+ <para>This can be confusing, and sometimes the choice is not always
+ clear. Hopefully this example makes it clearer.</para>
+
+ <example>
+ <title>Applications, commands, and options.</title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para><application>Sendmail</application> is the most
+ widely used Unix mail application.</para>
+
+<para><application>Sendmail</application> includes the
+ <citerefentry>
+ <refentrytitle>sendmail</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </citerefentry>, &man.mailq.8;, and &man.newaliases.8;
+ programs.</para>
+
+<para>One of the command line parameters to <citerefentry>
+ <refentrytitle>sendmail</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </citerefentry>, <option>-bp</option>, will display the current
+ status of messages in the mail queue. Check this on the command
+ line by running <command>sendmail -bp</command>.</para>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para><application>Sendmail</application> is the most widely used
+ Unix mail application.</para>
+
+ <para><application>Sendmail</application> includes the
+ <citerefentry>
+ <refentrytitle>sendmail</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </citerefentry>, <citerefentry>
+ <refentrytitle>mailq</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </citerefentry>, and <citerefentry>
+ <refentrytitle>newaliases</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </citerefentry> programs.</para>
+
+ <para>One of the command line parameters to <citerefentry>
+ <refentrytitle>sendmail</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </citerefentry>, <option>-bp</option>, will display the current
+ status of messages in the mail queue. Check this on the command
+ line by running <command>sendmail -bp</command>.</para>
+ </example>
+
+ <note>
+ <para>Notice how the
+ <literal>&amp;man.command.section;</literal> notation is easier to follow.</para>
+ </note>
+ </sect3>
+
+ <sect3>
+ <title>Files, directories, extensions</title>
+
+ <para>Whenever you wish to refer to the name of a file, a directory,
+ or a file extension, use <tag>filename</tag>.</para>
+
+ <example>
+ <title><tag>filename</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para>The SGML source for the Handbook in English can be
+ found in <filename>/usr/doc/en/handbook/</filename>. The first
+ file is called <filename>handbook.xml</filename> in that
+ directory. You should also see a <filename>Makefile</filename>
+ and a number of files with a <filename>.ent</filename>
+ extension.</para>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para>The SGML source for the Handbook in English can be found in
+ <filename>/usr/doc/en/handbook/</filename>. The first file is
+ called <filename>handbook.xml</filename> in that directory. You
+ should also see a <filename>Makefile</filename> and a number of
+ files with a <filename>.ent</filename> extension.</para>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>The name of ports</title>
+
+ <note>
+ <title>FreeBSD extension</title>
+
+ <para>These elements are part of the FreeBSD extension to DocBook,
+ and do not exist in the original DocBook DTD.</para>
+ </note>
+
+ <para>You might need to include the name of a program from the
+ FreeBSD Ports Collection in the documentation. Use the
+ <tag>filename</tag> tag with the <literal>role</literal>
+ attribute set to <literal>package</literal> to identify these.
+ Since ports
+ can be installed in any number of locations, only include
+ the category and the port name; do not include
+ <filename>/usr/ports</filename>.</para>
+
+ <example>
+ <title><tag>filename</tag> tag with
+ <literal>package</literal> role</title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para>Install the <filename role="package">net/ethereal</filename> port to view network traffic.</para>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para>Install the <package>net/ethereal</package>
+ port to view network traffic.</para>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Devices</title>
+
+ <note>
+ <title>FreeBSD extension</title>
+
+ <para>These elements are part of the FreeBSD extension to DocBook,
+ and do not exist in the original DocBook DTD.</para>
+ </note>
+
+ <para>When referring to devices you have two choices. You can either
+ refer to the device as it appears in <filename>/dev</filename>, or
+ you can use the name of the device as it appears in the kernel. For
+ this latter course, use <tag>devicename</tag>.</para>
+
+ <para>Sometimes you will not have a choice. Some devices, such as
+ networking cards, do not have entries in <filename>/dev</filename>,
+ or the entries are markedly different from those entries.</para>
+
+ <example>
+ <title><tag>devicename</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para><devicename>sio</devicename> is used for serial
+ communication in FreeBSD. <devicename>sio</devicename> manifests
+ through a number of entries in <filename>/dev</filename>, including
+ <filename>/dev/ttyd0</filename> and <filename>/dev/cuaa0</filename>.</para>
+
+<para>By contrast, the networking devices, such as
+ <devicename>ed0</devicename> do not appear in <filename>/dev</filename>.</para>
+
+<para>In MS-DOS, the first floppy drive is referred to as
+ <devicename>a:</devicename>. In FreeBSD it is
+ <filename>/dev/fd0</filename>.</para>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para><filename>sio</filename> is used for serial communication
+ in FreeBSD. <filename>sio</filename> manifests through a
+ number of entries in <filename>/dev</filename>, including
+ <filename>/dev/ttyd0</filename> and
+ <filename>/dev/cuaa0</filename>.</para>
+
+ <para>By contrast, the networking devices, such as
+ <filename>ed0</filename> do not appear in
+ <filename>/dev</filename>.</para>
+
+ <para>In MS-DOS, the first floppy drive is referred to as
+ <filename>a:</filename>. In FreeBSD it is
+ <filename>/dev/fd0</filename>.</para>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Hosts, domains, IP addresses, and so forth</title>
+
+ <note>
+ <title>FreeBSD extension</title>
+
+ <para>These elements are part of the FreeBSD extension to DocBook,
+ and do not exist in the original DocBook DTD.</para>
+ </note>
+
+ <para>You can markup identification information for networked
+ computers (hosts) in several ways, depending on the nature of the
+ information. All of them use <tag>hostid</tag> as the
+ element, with the <literal>role</literal> attribute selecting the
+ type of the marked up information.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>No role attribute, or
+ <literal>role="hostname"</literal></term>
+
+ <listitem>
+ <para>With no role attribute (i.e.,
+ <tag>hostid</tag>...<tag>/hostid</tag>) the
+ marked up information is the simple hostname, such as
+ <literal>freefall</literal> or <literal>wcarchive</literal>.
+ You can explicitly specify this with
+ <literal>role="hostname"</literal>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>role="domainname"</literal></term>
+
+ <listitem>
+ <para>The text is a domain name, such as
+ <literal>FreeBSD.org</literal> or
+ <literal>ngo.org.uk</literal>. There is no hostname
+ component.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>role="fqdn"</literal></term>
+
+ <listitem>
+ <para>The text is a Fully Qualified Domain Name, with both
+ hostname and domain name parts.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>role="ipaddr"</literal></term>
+
+ <listitem>
+ <para>The text is an IP address, probably expressed as a dotted
+ quad.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>role="ip6addr"</literal></term>
+
+ <listitem>
+ <para>The text is an IPv6 address.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>role="netmask"</literal></term>
+
+ <listitem>
+ <para>The text is a network mask, which might be expressed as a
+ dotted quad, a hexadecimal string, or as a
+ <literal>/</literal> followed by a number.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>role="mac"</literal></term>
+
+ <listitem>
+ <para>The text is an Ethernet MAC address, expressed as a series
+ of 2 digit hexadecimal numbers separated by colons.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <example>
+ <title><tag>hostid</tag> and roles</title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para>The local machine can always be referred to by the
+ name <hostid>localhost</hostid>, which will have the IP address
+ <hostid role="ipaddr">127.0.0.1</hostid>.</para>
+
+<para>The <hostid role="domainname">FreeBSD.org</hostid> domain
+ contains a number of different hosts, including
+ <hostid role="fqdn">freefall.FreeBSD.org</hostid> and
+ <hostid role="fqdn">bento.FreeBSD.org</hostid>.</para>
+
+<para>When adding an IP alias to an interface (using
+ <command>ifconfig</command>) <emphasis>always</emphasis> use a
+ netmask of <hostid role="netmask">255.255.255.255</hostid>
+ (which can also be expressed as <hostid
+ role="netmask">0xffffffff</hostid>.</para>
+
+<para>The MAC address uniquely identifies every network card
+ in existence. A typical MAC address looks like <hostid
+ role="mac">08:00:20:87:ef:d0</hostid>.</para>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para>The local machine can always be referred to by the name
+ <systemitem>localhost</systemitem>, which will have the IP address <systemitem class="ipaddress">127.0.0.1</systemitem>.</para>
+
+ <para>The <systemitem class="fqdomainname">FreeBSD.org</systemitem> domain
+ contains a number of different hosts, including <systemitem class="fqdomainname">freefall.FreeBSD.org</systemitem> and <systemitem class="fqdomainname">bento.FreeBSD.org</systemitem>.</para>
+
+ <para>When adding an IP alias to an interface (using
+ <command>ifconfig</command>) <emphasis>always</emphasis> use a
+ netmask of <systemitem class="netmask">255.255.255.255</systemitem> (which
+ can also be expressed as <systemitem class="netmask">0xffffffff</systemitem>.</para>
+
+ <para>The MAC address uniquely identifies every network card in
+ existence. A typical MAC address looks like <systemitem class="etheraddress">08:00:20:87:ef:d0</systemitem>.</para>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Usernames</title>
+
+ <note>
+ <title>FreeBSD extension</title>
+
+ <para>These elements are part of the FreeBSD extension to DocBook,
+ and do not exist in the original DocBook DTD.</para>
+ </note>
+
+ <para>When you need to refer to a specific username, such as
+ <literal>root</literal> or <literal>bin</literal>, use
+ <tag>username</tag>.</para>
+
+ <example>
+ <title><tag>username</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para>To carry out most system administration functions you
+ will need to be <username>root</username>.</para>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para>To carry out most system administration functions you will
+ need to be <systemitem class="username">root</systemitem>.</para>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Describing <filename>Makefile</filename>s</title>
+
+ <note>
+ <title>FreeBSD extension</title>
+
+ <para>These elements are part of the FreeBSD extension to DocBook,
+ and do not exist in the original DocBook DTD.</para>
+ </note>
+
+ <para>Two elements exist to describe parts of
+ <filename>Makefile</filename>s, <tag>maketarget</tag> and
+ <tag>makevar</tag>.</para>
+
+ <para><tag>maketarget</tag> identifies a build target exported
+ by a <filename>Makefile</filename> that can be given as a parameter
+ to <command>make</command>. <tag>makevar</tag> identifies a
+ variable that can be set (in the environment, on the
+ <command>make</command> command line, or within the
+ <filename>Makefile</filename>) to influence the process.</para>
+
+ <example>
+ <title><tag>maketarget</tag> and
+ <tag>makevar</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para>Two common targets in a <filename>Makefile</filename>
+ are <maketarget>all</maketarget> and <maketarget>clean</maketarget>.</para>
+
+<para>Typically, invoking <maketarget>all</maketarget> will rebuild the
+ application, and invoking <maketarget>clean</maketarget> will remove
+ the temporary files (<filename>.o</filename> for example) created by
+ the build process.</para>
+
+<para><maketarget>clean</maketarget> may be controlled by a number of
+ variables, including <makevar>CLOBBER</makevar> and
+ <makevar>RECURSE</makevar>.</para>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para>Two common targets in a <filename>Makefile</filename> are
+ <buildtarget>all</buildtarget> and
+ <buildtarget>clean</buildtarget>.</para>
+
+ <para>Typically, invoking <buildtarget>all</buildtarget> will rebuild
+ the application, and invoking <buildtarget>clean</buildtarget> will
+ remove the temporary files (<filename>.o</filename> for example)
+ created by the build process.</para>
+
+ <para><buildtarget>clean</buildtarget> may be controlled by a number
+ of variables, including <varname>CLOBBER</varname> and
+ <varname>RECURSE</varname>.</para>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Literal text</title>
+
+ <para>You will often need to include <quote>literal</quote> text in the
+ Handbook. This is text that is excerpted from another file, or
+ which should be copied from the Handbook into another file
+ verbatim.</para>
+
+ <para>Some of the time, <tag>programlisting</tag> will be
+ sufficient to denote this text. <tag>programlisting</tag>
+ is not always appropriate, particularly when you want to include a
+ portion of a file <quote>in-line</quote> with the rest of the
+ paragraph.</para>
+
+ <para>On these occasions, use <tag>literal</tag>.</para>
+
+ <example>
+ <title><tag>literal</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para>The <literal>maxusers 10</literal> line in the kernel
+ configuration file determines the size of many system tables, and is
+ a rough guide to how many simultaneous logins the system will
+ support.</para>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para>The <literal>maxusers 10</literal> line in the kernel
+ configuration file determines the size of many system tables, and
+ is a rough guide to how many simultaneous logins the system will
+ support.</para>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Showing items that the user <emphasis>must</emphasis> fill
+ in</title>
+
+ <para>There will often be times when you want to show the user what to
+ do, or refer to a file, or command line, or similar, where the user
+ cannot simply copy the examples that you provide, but must instead
+ include some information themselves.</para>
+
+ <para><tag>replaceable</tag> is designed for this eventuality.
+ Use it <emphasis>inside</emphasis> other elements to indicate parts
+ of that element's content that the user must replace.</para>
+
+ <example>
+ <title><tag>replaceable</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<informalexample>
+ <screen>&prompt.user; <userinput>man <replaceable>command</replaceable></userinput></screen>
+</informalexample>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <informalexample>
+ <screen>&prompt.user; <userinput>man command</userinput></screen>
+ </informalexample>
+
+ <para><tag>replaceable</tag> can be used in many different
+ elements, including <tag>literal</tag>. This example also
+ shows that <tag>replaceable</tag> should only be wrapped
+ around the content that the user <emphasis>is</emphasis> meant to
+ provide. The other content should be left alone.</para>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para>The <literal>maxusers <replaceable>n</replaceable></literal>
+ line in the kernel configuration file determines the size of many system
+ tables, and is a rough guide to how many simultaneous logins the system will
+ support.</para>
+
+<para>For a desktop workstation, <literal>32</literal> is a good value
+ for <replaceable>n</replaceable>.</para>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para>The <literal>maxusers n</literal>
+ line in the kernel configuration file determines the size of many
+ system tables, and is a rough guide to how many simultaneous
+ logins the system will support.</para>
+
+ <para>For a desktop workstation, <literal>32</literal> is a good
+ value for <replaceable>n</replaceable>.</para>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Quoting system errors</title>
+
+ <para>You might want to show errors generated by FreeBSD.
+ Mark these with <tag>errorname</tag>. This
+ indicates the exact error that appears.</para>
+
+ <example>
+ <title><tag>errorname</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[
+<screen><errorname>Panic: cannot mount root</errorname></screen> ]]>
+</programlisting>
+
+
+ <para>Appearance:</para>
+
+ <informalexample>
+ <screen><errorname>Panic: cannot mount root</errorname></screen>
+ </informalexample>
+ </example>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Images</title>
+
+ <important>
+ <para>Image support in the documentation is currently extremely
+ experimental. I think the mechanisms described here are unlikely to
+ change, but that is not guaranteed.</para>
+
+ <para>You will also need to install the
+ <package>graphics/ImageMagick</package> port, which is used to
+ convert between the different image formats. This is a big port,
+ and most of it is not required. However, while we are working on the
+ <filename>Makefile</filename>s and other infrastructure it makes
+ things easier. This port is <emphasis>not</emphasis> in the
+ <package>textproc/docproj</package> meta port, you must install it
+ by hand.</para>
+
+ <para>The best example of what follows in practice is the
+ <filename>doc/en_US.ISO8859-1/articles/vm-design/</filename> document.
+ If you are unsure of the description that follows, take a look at the
+ files in that directory to see how everything hangs together.
+ Experiment with creating different formatted versions of the
+ document to see how the image markup appears in the formatted
+ output.</para>
+ </important>
+
+ <sect3>
+ <title>Image formats</title>
+
+ <para>We currently support two formats for images. The format you
+ should use will depend on the nature of your image.</para>
+
+ <para>For images that are primarily vector based, such as network
+ diagrams, time lines, and similar, use Encapsulated Postscript, and
+ make sure that your images have the <filename>.eps</filename>
+ extension.</para>
+
+ <para>For bitmaps, such as screen captures, use the Portable Network
+ Graphic format, and make sure that your images have the
+ <filename>.png</filename> extension.</para>
+
+ <para>These are the <emphasis>only</emphasis> formats in which images
+ should be committed to the CVS repository.</para>
+
+ <para>Use the right format for the right image. It is to be expected
+ that your documentation will have a mix of EPS and PNG images. The
+ <filename>Makefile</filename>s ensure that the correct format image
+ is chosen depending on the output format that you use for your
+ documentation. <emphasis>Do not commit the same image to the
+ repository in two different formats</emphasis>.</para>
+
+ <important>
+ <para>It is anticipated that the Documentation Project will switch to
+ using the Scalable Vector Graphic (SVG) format for vector images.
+ However, the current state of SVG capable editing tools makes this
+ impractical.</para>
+ </important>
+ </sect3>
+
+ <sect3>
+ <title>Markup</title>
+
+ <para>The markup for an image is relatively simple. First, markup a
+ <tag>mediaobject</tag>. The <tag>mediaobject</tag>
+ can contain other, more specific objects. We are concerned with
+ two, the <tag>imageobject</tag> and the
+ <tag>textobject</tag>.</para>
+
+ <para>You should include one <tag>imageobject</tag>, and two
+ <tag>textobject</tag> elements. The
+ <tag>imageobject</tag> will point to the name of the image
+ file that will be used (without the extension). The
+ <tag>textobject</tag> elements contain information that will
+ be presented to the user as well as, or instead of, the
+ image.</para>
+
+ <para>There are two circumstances where this can happen.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>When the reader is viewing the documentation in HTML. In
+ this case, each image will need to have associated alternate
+ text to show the user, typically whilst the image is loading, or
+ if they hover the mouse pointer over the image.</para>
+ </listitem>
+
+ <listitem>
+ <para>When the reader is viewing the documentation in plain text.
+ In this case, each image should have an ASCII art equivalent to
+ show the user.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>An example will probably make things easier to understand.
+ Suppose you have an image, called <filename>fig1.png</filename>, that
+ you want to include in the document. This image is of a rectangle
+ with an A inside it. The markup for this would be as
+ follows.</para>
+
+ <programlisting>&lt;mediaobject&gt;
+ &lt;imageobject&gt;
+ &lt;imagedata fileref="fig1"&gt; <co xml:id="co-image-ext"/>
+ &lt;/imageobject&gt;
+
+ &lt;textobject&gt;
+ &lt;literallayout class="monospaced"&gt;+---------------+ <co xml:id="co-image-literal"/>
+| A |
++---------------+&lt;/literallayout&gt;
+ &lt;/textobject&gt;
+
+ &lt;textobject&gt;
+ &lt;phrase&gt;A picture&lt;/phrase&gt; <co xml:id="co-image-phrase"/>
+ &lt;/textobject&gt;
+&lt;/mediaobject&gt;</programlisting>
+
+ <calloutlist>
+ <callout arearefs="co-image-ext">
+ <para>Include an <tag>imagedata</tag> element inside the
+ <tag>imageobject</tag> element. The
+ <literal>fileref</literal> attribute should contain the filename
+ of the image to include, without the extension. The stylesheets
+ will work out which extension should be added to the filename
+ automatically.</para>
+ </callout>
+
+ <callout arearefs="co-image-literal">
+ <para>The first <tag>textobject</tag> should contain a
+ <tag>literallayout</tag> element, where the
+ <literal>class</literal> attribute is set to
+ <literal>monospaced</literal>. This is your opportunity to
+ demonstrate your ASCII art skills. This content will be used if
+ the document is converted to plain text.</para>
+
+ <para>Notice how the first and last lines of the content of the
+ <tag>literallayout</tag> element butt up next to the
+ element's tags. This ensures no extraneous white space is
+ included.</para>
+ </callout>
+
+ <callout arearefs="co-image-phrase">
+ <para>The second <tag>textobject</tag> should contain a
+ single <tag>phrase</tag> element. The contents of this
+ will become the <literal>alt</literal> attribute for the image
+ when this document is converted to HTML.</para>
+ </callout>
+ </calloutlist>
+ </sect3>
+
+ <sect3>
+ <title><filename>Makefile</filename> entries</title>
+
+ <para>Your images must be listed in the
+ <filename>Makefile</filename> in the <varname>IMAGES</varname>
+ variable. This variable should contain the name of all your
+ <emphasis>source</emphasis> images. For example, if you have
+ created three figures, <filename>fig1.eps</filename>,
+ <filename>fig2.png</filename>, <filename>fig3.png</filename>, then
+ your <filename>Makefile</filename> should have lines like this in
+ it.</para>
+
+ <programlisting>&hellip;
+IMAGES= fig1.eps fig2.png fig3.png
+&hellip;</programlisting>
+
+ <para>or</para>
+
+ <programlisting>&hellip;
+IMAGES= fig1.eps
+IMAGES+= fig2.png
+IMAGES+= fig3.png
+&hellip;</programlisting>
+
+ <para>Again, the <filename>Makefile</filename> will work out the
+ complete list of images it needs to build your source document, you
+ only need to list the image files <emphasis>you</emphasis>
+ provided.</para>
+ </sect3>
+
+ <sect3>
+ <title>Images and chapters in subdirectories</title>
+
+ <para>You must be careful when you separate your documentation into
+ smaller files (see <xref linkend="sgml-primer-include-using-gen-entities"/>) in
+ different directories.</para>
+
+ <para>Suppose you have a book with three chapters, and the chapters
+ are stored in their own directories, called
+ <filename>chapter1/chapter.xml</filename>,
+ <filename>chapter2/chapter.xml</filename>, and
+ <filename>chapter3/chapter.xml</filename>. If each chapter has
+ images associated with it, I suggest you place those images in each
+ chapter's subdirectory (<filename>chapter1/</filename>,
+ <filename>chapter2/</filename>, and
+ <filename>chapter3/</filename>).</para>
+
+ <para>However, if you do this you must include the directory names in
+ the <varname>IMAGES</varname> variable in the
+ <filename>Makefile</filename>, <emphasis>and</emphasis> you must
+ include the directory name in the <tag>imagedata</tag>
+ element in your document.</para>
+
+ <para>For example, if you have <filename>chapter1/fig1.png</filename>,
+ then <filename>chapter1/chapter.xml</filename> should
+ contain:</para>
+
+ <programlisting>&lt;mediaobject&gt;
+ &lt;imageobject&gt;
+ &lt;imagedata fileref="chapter1/fig1"&gt; <co xml:id="co-image-dir"/>
+ &lt;/imageobject&gt;
+
+ &hellip;
+
+&lt;/mediaobject&gt;</programlisting>
+
+ <calloutlist>
+ <callout arearefs="co-image-dir">
+ <para>The directory name must be included in the
+ <literal>fileref</literal> attribute.</para>
+ </callout>
+ </calloutlist>
+
+ <para>The <filename>Makefile</filename> must contain:</para>
+
+ <programlisting>&hellip;
+IMAGES= chapter1/fig1.png
+&hellip;</programlisting>
+
+ <para>Then everything should just work.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Links</title>
+
+ <note>
+ <para>Links are also in-line elements.</para>
+ </note>
+
+ <sect3>
+ <title>Linking to other parts of the same document</title>
+
+ <para>Linking within the same document requires you to specify
+ where you are linking from (i.e., the text the user will click, or
+ otherwise indicate, as the source of the link) and where you are
+ linking to (the link's destination).</para>
+
+ <para>Each element within DocBook has an attribute called
+ <literal>id</literal>. You can place text in this attribute to
+ uniquely name the element it is attached to.</para>
+
+ <para>This value will be used when you specify the link
+ source.</para>
+
+ <para>Normally, you will only be linking to chapters or sections, so
+ you would add the <literal>id</literal> attribute to these
+ elements.</para>
+
+ <example>
+ <title><literal>id on chapters and sections</literal></title>
+
+ <programlisting><![CDATA[<chapter id="chapter1">
+ <title>Introduction</title>
+
+ <para>This is the introduction. It contains a subsection,
+ which is identified as well.</para>
+
+ <sect1 id="chapter1-sect1">
+ <title>Sub-sect 1</title>
+
+ <para>This is the subsection.</para>
+ </sect1>
+</chapter>]]></programlisting>
+ </example>
+
+ <para>Obviously, you should use more descriptive values. The values
+ must be unique within the document (i.e., not just the file, but the
+ document the file might be included in as well). Notice how the
+ <literal>id</literal> for the subsection is constructed by appending
+ text to the <literal>id</literal> of the chapter. This helps to
+ ensure that they are unique.</para>
+
+ <para>If you want to allow the user to jump into a specific portion of
+ the document (possibly in the middle of a paragraph or an example),
+ use <tag>anchor</tag>. This element has no content, but
+ takes an <literal>id</literal> attribute.</para>
+
+ <example>
+ <title><tag>anchor</tag></title>
+
+ <programlisting><![CDATA[<para>This paragraph has an embedded
+ <anchor id="para1">link target in it. It will not show up in
+ the document.</para>]]></programlisting>
+ </example>
+
+ <para>When you want to provide the user with a link they can activate
+ (probably by clicking) to go to a section of the document that has
+ an <literal>id</literal> attribute, you can use either
+ <tag>xref</tag> or <tag>link</tag>.</para>
+
+ <para>Both of these elements have a <literal>linkend</literal>
+ attribute. The value of this attribute should be the value that you
+ have used in a <literal>id</literal> attribute (it does not matter
+ if that value has not yet occurred in your document; this will work
+ for forward links as well as backward links).</para>
+
+ <para>If you use <tag>xref</tag> then you have no control over
+ the text of the link. It will be generated for you.</para>
+
+ <example>
+ <title>Using <tag>xref</tag></title>
+
+ <para>Assume that this fragment appears somewhere in a document that
+ includes the <literal>id</literal> example:</para>
+
+ <programlisting><![CDATA[<para>More information can be found
+ in <xref linkend="chapter1">.</para>
+
+<para>More specific information can be found
+ in <xref linkend="chapter1-sect1">.</para>]]></programlisting>
+
+ <para>The text of the link will be generated automatically, and will
+ look like (<emphasis>emphasized</emphasis> text indicates the text
+ that will be the link):</para>
+
+ <blockquote>
+ <para>More information can be found in <emphasis>Chapter
+ One</emphasis>.</para>
+
+ <para>More specific information can be found in <emphasis>the
+ section called Sub-sect 1</emphasis>.</para>
+ </blockquote>
+ </example>
+
+ <para>Notice how the text from the link is derived from the section
+ title or the chapter number.</para>
+
+ <note>
+ <para>This means that you <emphasis>cannot</emphasis> use
+ <tag>xref</tag> to link to an <literal>id</literal>
+ attribute on an <tag>anchor</tag> element. The
+ <tag>anchor</tag> has no content, so the
+ <tag>xref</tag> cannot generate the text for the
+ link.</para>
+ </note>
+
+ <para>If you want to control the text of the link then use
+ <tag>link</tag>. This element wraps content, and the
+ content will be used for the link.</para>
+
+ <example>
+ <title>Using <tag>link</tag></title>
+
+ <para>Assume that this fragment appears somewhere in a document that
+ includes the <literal>id</literal> example.</para>
+
+ <programlisting><![CDATA[<para>More information can be found in
+ <link linkend="chapter1">the first chapter</link>.</para>
+
+<para>More specific information can be found in
+ <link linkend="chapter1-sect1">this</link> section.</para>]]></programlisting>
+
+ <para>This will generate the following
+ (<emphasis>emphasized</emphasis> text indicates the text that will
+ be the link):</para>
+
+ <blockquote>
+ <para>More information can be found in <emphasis>the first
+ chapter</emphasis>.</para>
+
+ <para>More specific information can be found in
+ <emphasis>this</emphasis> section.</para>
+ </blockquote>
+ </example>
+
+ <note>
+ <para>That last one is a bad example. Never use words like
+ <quote>this</quote> or <quote>here</quote> as the source for the
+ link. The reader will need to hunt around the surrounding context
+ to see where the link is actually taking them.</para>
+ </note>
+
+ <note>
+ <para>You <emphasis>can</emphasis> use <tag>link</tag> to
+ include a link to an <literal>id</literal> on an
+ <tag>anchor</tag> element, since the
+ <tag>link</tag> content defines the text that will be used
+ for the link.</para>
+ </note>
+ </sect3>
+
+ <sect3>
+ <title>Linking to documents on the WWW</title>
+
+ <para>Linking to external documents is much simpler, as long as you
+ know the URL of the document you want to link to. Use
+ <tag>ulink</tag>. The <literal>url</literal> attribute is
+ the URL of the page that the link points to, and the content of the
+ element is the text that will be displayed for the user to
+ activate.</para>
+
+ <example>
+ <title><tag>ulink</tag></title>
+
+ <para>Use:</para>
+
+ <programlisting><![CDATA[<para>Of course, you could stop reading this document and
+ go to the <ulink url="&url.base;/index.html">FreeBSD
+ home page</ulink> instead.</para>]]></programlisting>
+
+ <para>Appearance:</para>
+
+ <para>Of course, you could stop reading this document and go to the
+ <link xlink:href="&url.base;/index.html">FreeBSD home page</link>
+ instead.</para>
+ </example>
+ </sect3>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/fdp-primer/sgml-primer/chapter.xml b/zh_TW.UTF-8/books/fdp-primer/sgml-primer/chapter.xml
new file mode 100644
index 0000000000..eb17a7cd91
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/sgml-primer/chapter.xml
@@ -0,0 +1,1543 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 1998, 1999 Nik Clayton, All rights reserved.
+
+ Redistribution and use in source (SGML DocBook) and 'compiled' forms
+ (SGML, HTML, PDF, PostScript, RTF and so forth) with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code (SGML DocBook) must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+ 2. Redistributions in compiled form (transformed to other DTDs,
+ converted to PDF, PostScript, RTF and other formats) must reproduce
+ the above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ $FreeBSD$
+ Original revision: 1.45
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="sgml-primer">
+ <title>SGML Primer</title>
+
+ <para>FDP 文件幾乎都是以 SGML 相關程式寫的。本章會介紹 SGML 是什麼、
+ 如何閱讀、理解這些 SGML 原稿,以及本文件中所運用的各項 SGML 技巧。</para>
+
+ <para>本節部分靈感啟發來自 Mark Galassi 的這篇 <link xlink:href="http://nis-www.lanl.gov/~rosalia/mydocs/docbook-intro/docbook-intro.html">Get Going With DocBook</link>。</para>
+
+ <sect1 xml:id="sgml-primer-overview">
+ <title>簡介</title>
+
+ <para>Way back when, electronic text was simple to deal with. Admittedly,
+ you had to know which character set your document was written in (ASCII,
+ EBCDIC, or one of a number of others) but that was about it. Text was
+ text, and what you saw really was what you got. No frills, no
+ formatting, no intelligence.</para>
+
+ <para>Inevitably, this was not enough. Once you have text in a
+ machine-usable format, you expect machines to be able to use it and
+ manipulate it intelligently. You would like to indicate that certain
+ phrases should be emphasized, or added to a glossary, or be hyperlinks.
+ You might want filenames to be shown in a <quote>typewriter</quote> style
+ font for viewing on screen, but as <quote>italics</quote> when printed,
+ or any of a myriad of other options for presentation.</para>
+
+ <para>It was once hoped that Artificial Intelligence (AI) would make this
+ easy. Your computer would read in the document and automatically
+ identify key phrases, filenames, text that the reader should type in,
+ examples, and more. Unfortunately, real life has not happened quite
+ like that, and our computers require some assistance before they can
+ meaningfully process our text.</para>
+
+ <para>More precisely, they need help identifying what is what. You or I
+ can look at
+
+ <blockquote>
+ <para>To remove <filename>/tmp/foo</filename> use &man.rm.1;.</para>
+
+ <screen>&prompt.user; <userinput>rm /tmp/foo</userinput></screen>
+ </blockquote>
+
+ and easily see which parts are filenames, which are commands to be typed
+ in, which parts are references to manual pages, and so on. But the
+ computer processing the document cannot. For this we need
+ markup.</para>
+
+ <para><quote>Markup</quote> is commonly used to describe <quote>adding
+ value</quote> or <quote>increasing cost</quote>. The term takes on both
+ these meanings when applied to text. Markup is additional text included
+ in the document, distinguished from the document's content in some way,
+ so that programs that process the document can read the markup and use
+ it when making decisions about the document. Editors can hide the
+ markup from the user, so the user is not distracted by it.</para>
+
+ <para>The extra information stored in the markup <emphasis>adds
+ value</emphasis> to the document. Adding the markup to the document
+ must typically be done by a person&mdash;after all, if computers could
+ recognize the text sufficiently well to add the markup then there would
+ be no need to add it in the first place. This <emphasis>increases the
+ cost</emphasis> (i.e., the effort required) to create the
+ document.</para>
+
+ <para>The previous example is actually represented in this document like
+ this:</para>
+
+ <programlisting><![CDATA[
+<para>To remove <filename>/tmp/foo</filename> use &man.rm.1;.</para>
+
+<screen>&prompt.user; <userinput>rm /tmp/foo</userinput></screen>]]></programlisting>
+
+ <para>As you can see, the markup is clearly separate from the
+ content.</para>
+
+ <para>Obviously, if you are going to use markup you need to define what
+ your markup means, and how it should be interpreted. You will need a
+ markup language that you can follow when marking up your
+ documents.</para>
+
+ <para>Of course, one markup language might not be enough. A markup
+ language for technical documentation has very different requirements
+ than a markup language that was to be used for cookery recipes. This,
+ in turn, would be very different from a markup language used to describe
+ poetry. What you really need is a first language that you use to write
+ these other markup languages. A <emphasis>meta markup
+ language</emphasis>.</para>
+
+ <para>This is exactly what the Standard Generalized Markup Language (SGML)
+ is. Many markup languages have been written in SGML, including the two
+ most used by the FDP, HTML and DocBook.</para>
+
+ <para>Each language definition is more properly called a Document Type
+ Definition (DTD). The DTD specifies the name of the elements that can
+ be used, what order they appear in (and whether some markup can be used
+ inside other markup) and related information. A DTD is sometimes
+ referred to as an <emphasis>application</emphasis> of SGML.</para>
+
+ <para xml:id="sgml-primer-validating">A DTD is a <emphasis>complete</emphasis>
+ specification of all the elements that are allowed to appear, the order
+ in which they should appear, which elements are mandatory, which are
+ optional, and so forth. This makes it possible to write an SGML
+ <emphasis>parser</emphasis> which reads in both the DTD and a document
+ which claims to conform to the DTD. The parser can then confirm whether
+ or not all the elements required by the DTD are in the document in the
+ right order, and whether there are any errors in the markup. This is
+ normally referred to as <quote>validating the document</quote>.</para>
+
+ <note>
+ <para>This processing simply confirms that the choice of elements, their
+ ordering, and so on, conforms to that listed in the DTD. It does
+ <emphasis>not</emphasis> check that you have used
+ <emphasis>appropriate</emphasis> markup for the content. If you
+ tried to mark up all the filenames in your document as function
+ names, the parser would not flag this as an error (assuming, of
+ course, that your DTD defines elements for filenames and functions,
+ and that they are allowed to appear in the same place).</para>
+ </note>
+
+ <para>It is likely that most of your contributions to the Documentation
+ Project will consist of content marked up in either HTML or DocBook,
+ rather than alterations to the DTDs. For this reason this book will
+ not touch on how to write a DTD.</para>
+ </sect1>
+
+ <sect1 xml:id="sgml-primer-elements">
+ <title>Elements, tags, and attributes</title>
+
+ <para>All the DTDs written in SGML share certain characteristics. This is
+ hardly surprising, as the philosophy behind SGML will inevitably show
+ through. One of the most obvious manifestations of this philosophy is
+ that of <emphasis>content</emphasis> and
+ <emphasis>elements</emphasis>.</para>
+
+ <para>Your documentation (whether it is a single web page, or a lengthy
+ book) is considered to consist of content. This content is then divided
+ (and further subdivided) into elements. The purpose of adding markup is
+ to name and identify the boundaries of these elements for further
+ processing.</para>
+
+ <para>For example, consider a typical book. At the very top level, the
+ book is itself an element. This <quote>book</quote> element obviously
+ contains chapters, which can be considered to be elements in their own
+ right. Each chapter will contain more elements, such as paragraphs,
+ quotations, and footnotes. Each paragraph might contain further
+ elements, identifying content that was direct speech, or the name of a
+ character in the story.</para>
+
+ <para>You might like to think of this as <quote>chunking</quote> content.
+ At the very top level you have one chunk, the book. Look a little
+ deeper, and you have more chunks, the individual chapters. These are
+ chunked further into paragraphs, footnotes, character names, and so
+ on.</para>
+
+ <para>Notice how you can make this differentiation between different
+ elements of the content without resorting to any SGML terms. It really
+ is surprisingly straightforward. You could do this with a highlighter
+ pen and a printout of the book, using different colors to indicate
+ different chunks of content.</para>
+
+ <para>Of course, we do not have an electronic highlighter pen, so we need
+ some other way of indicating which element each piece of content belongs
+ to. In languages written in SGML (HTML, DocBook, et al) this is done by
+ means of <emphasis>tags</emphasis>.</para>
+
+ <para>A tag is used to identify where a particular element starts, and
+ where the element ends. <emphasis>The tag is not part of the element
+ itself</emphasis>. Because each DTD was normally written to mark up
+ specific types of information, each one will recognize different
+ elements, and will therefore have different names for the tags.</para>
+
+ <para>For an element called <replaceable>element-name</replaceable> the
+ start tag will normally look like
+ <literal>&lt;element-name&gt;</literal>. The
+ corresponding closing tag for this element is
+ <literal>&lt;/element-name&gt;</literal>.</para>
+
+ <example>
+ <title>Using an element (start and end tags)</title>
+
+ <para>HTML has an element for indicating that the content enclosed by
+ the element is a paragraph, called <literal>p</literal>. This
+ element has both start and end tags.</para>
+
+ <programlisting><![CDATA[<p>This is a paragraph. It starts with the start tag for
+ the 'p' element, and it will end with the end tag for the 'p'
+ element.</p>
+
+<p>This is another paragraph. But this one is much shorter.</p>]]></programlisting>
+ </example>
+
+ <para>Not all elements require an end tag. Some elements have no content.
+ For example, in HTML you can indicate that you want a horizontal line to
+ appear in the document. Obviously, this line has no content, so just
+ the start tag is required for this element.</para>
+
+ <example>
+ <title>Using an element (start tag only)</title>
+
+ <para>HTML has an element for indicating a horizontal rule, called
+ <literal>hr</literal>. This element does not wrap content, so only
+ has a start tag.</para>
+
+ <programlisting><![CDATA[<p>This is a paragraph.</p>
+
+<hr>
+
+<p>This is another paragraph. A horizontal rule separates this
+ from the previous paragraph.</p>]]></programlisting>
+ </example>
+
+ <para>If it is not obvious by now, elements can contain other elements.
+ In the book example earlier, the book element contained all the chapter
+ elements, which in turn contained all the paragraph elements, and so
+ on.</para>
+
+ <example>
+ <title>Elements within elements; <tag>em</tag></title>
+
+ <programlisting><![CDATA[<p>This is a simple <em>paragraph</em> where some
+ of the <em>words</em> have been <em>emphasized</em>.</p>]]></programlisting>
+ </example>
+
+ <para>The DTD will specify the rules detailing which elements can contain
+ other elements, and exactly what they can contain.</para>
+
+ <important>
+ <para>People often confuse the terms tags and elements, and use the
+ terms as if they were interchangeable. They are not.</para>
+
+ <para>An element is a conceptual part of your document. An element has
+ a defined start and end. The tags mark where the element starts and
+ end.</para>
+
+ <para>When this document (or anyone else knowledgeable about SGML) refers
+ to <quote>the &lt;p&gt; tag</quote> they mean the literal text
+ consisting of the three characters <literal>&lt;</literal>,
+ <literal>p</literal>, and <literal>&gt;</literal>. But the phrase
+ <quote>the &lt;p&gt; element</quote> refers to the whole
+ element.</para>
+
+ <para>This distinction <emphasis>is</emphasis> very subtle. But keep it
+ in mind.</para>
+ </important>
+
+ <para>Elements can have attributes. An attribute has a name and a value,
+ and is used for adding extra information to the element. This might be
+ information that indicates how the content should be rendered, or might
+ be something that uniquely identifies that occurrence of the element, or
+ it might be something else.</para>
+
+ <para>An element's attributes are written <emphasis>inside</emphasis> the
+ start tag for that element, and take the form
+ <literal>attribute-name="attribute-value"</literal>.</para>
+
+ <para>In sufficiently recent versions of HTML, the <tag>p</tag>
+ element has an attribute called <literal>align</literal>, which suggests
+ an alignment (justification) for the paragraph to the program displaying
+ the HTML.</para>
+
+ <para>The <literal>align</literal> attribute can take one of four defined
+ values, <literal>left</literal>, <literal>center</literal>,
+ <literal>right</literal> and <literal>justify</literal>. If the
+ attribute is not specified then the default is
+ <literal>left</literal>.</para>
+
+ <example>
+ <title>Using an element with an attribute</title>
+
+ <programlisting><![CDATA[<p align="left">The inclusion of the align attribute
+ on this paragraph was superfluous, since the default is left.</p>
+
+<p align="center">This may appear in the center.</p>]]></programlisting>
+ </example>
+
+ <para>Some attributes will only take specific values, such as
+ <literal>left</literal> or <literal>justify</literal>. Others will
+ allow you to enter anything you want. If you need to include quotes
+ (<literal>"</literal>) within an attribute then use single quotes around
+ the attribute value.</para>
+
+ <example>
+ <title>Single quotes around attributes</title>
+
+ <programlisting><![CDATA[<p align='right'>I am on the right!</p>]]></programlisting>
+ </example>
+
+ <para>Sometimes you do not need to use quotes around attribute values at
+ all. However, the rules for doing this are subtle, and it is far
+ simpler just to <emphasis>always</emphasis> quote your attribute
+ values.</para>
+
+ <para>The information on attributes, elements, and tags is stored
+ in SGML catalogs. The various Documentation Project tools use
+ these catalog files to validate your work. The tools in
+ <package>textproc/docproj</package> include a variety of SGML catalog
+ files. The FreeBSD Documentation Project includes its own set
+ of catalog files. Your tools need to know about both sorts of
+ catalog files.</para>
+
+ <sect2>
+ <title>For you to do&hellip;</title>
+
+ <para>In order to run the examples in this document you will need to
+ install some software on your system and ensure that an environment
+ variable is set correctly.</para>
+
+ <procedure>
+ <step>
+ <para>Download and install <package>textproc/docproj</package>
+ from the FreeBSD ports system. This is a
+ <emphasis>meta-port</emphasis> that should download and install
+ all of the programs and supporting files that are used by the
+ Documentation Project.</para>
+ </step>
+
+ <step>
+ <para>Add lines to your shell startup files to set
+ <envar>SGML_CATALOG_FILES</envar>. (If you are not working
+ on the English version of the documentation, you will want
+ to substitute the correct directory for your
+ language.)</para>
+
+ <example xml:id="sgml-primer-envars">
+ <title><filename>.profile</filename>, for &man.sh.1; and
+ &man.bash.1; users</title>
+
+ <programlisting>SGML_ROOT=/usr/local/share/xml
+SGML_CATALOG_FILES=${SGML_ROOT}/jade/catalog
+SGML_CATALOG_FILES=${SGML_ROOT}/iso8879/catalog:$SGML_CATALOG_FILES
+SGML_CATALOG_FILES=${SGML_ROOT}/html/catalog:$SGML_CATALOG_FILES
+SGML_CATALOG_FILES=${SGML_ROOT}/docbook/4.1/catalog:$SGML_CATALOG_FILES
+SGML_CATALOG_FILES=/usr/doc/share/xml/catalog:$SGML_CATALOG_FILES
+SGML_CATALOG_FILES=/usr/doc/en_US.ISO8859-1/share/xml/catalog:$SGML_CATALOG_FILES
+export SGML_CATALOG_FILES</programlisting>
+ </example>
+
+ <example>
+ <title><filename>.cshrc</filename>, for &man.csh.1; and
+ &man.tcsh.1; users</title>
+
+ <programlisting>setenv SGML_ROOT /usr/local/share/xml
+setenv SGML_CATALOG_FILES ${SGML_ROOT}/jade/catalog
+setenv SGML_CATALOG_FILES ${SGML_ROOT}/iso8879/catalog:$SGML_CATALOG_FILES
+setenv SGML_CATALOG_FILES ${SGML_ROOT}/html/catalog:$SGML_CATALOG_FILES
+setenv SGML_CATALOG_FILES ${SGML_ROOT}/docbook/4.1/catalog:$SGML_CATALOG_FILES
+setenv SGML_CATALOG_FILES /usr/doc/share/xml/catalog:$SGML_CATALOG_FILES
+setenv SGML_CATALOG_FILES /usr/doc/en_US.ISO8859-1/share/xml/catalog:$SGML_CATALOG_FILES</programlisting>
+ </example>
+
+ <para>Then either log out, and log back in again, or run those
+ commands from the command line to set the variable values.</para>
+ </step>
+ </procedure>
+
+ <procedure>
+ <step>
+ <para>Create <filename>example.xml</filename>, and enter the
+ following text:</para>
+
+ <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<html>
+ <head>
+ <title>An example HTML file</title>
+ </head>
+
+ <body>
+ <p>This is a paragraph containing some text.</p>
+
+ <p>This paragraph contains some more text.</p>
+
+ <p align="right">This paragraph might be right-justified.</p>
+ </body>
+</html>]]></programlisting>
+ </step>
+
+ <step>
+ <para>Try to validate this file using an SGML parser.</para>
+
+ <para>Part of <package>textproc/docproj</package> is the
+ <command>nsgmls</command> <link linkend="sgml-primer-validating">validating
+ parser</link>. Normally, <command>nsgmls</command> reads in a document
+ marked up according to an SGML DTD and returns a copy of the
+ document's Element Structure Information Set (ESIS, but that is
+ not important right now).</para>
+
+ <para>However, when <command>nsgmls</command> is given the <option>-s</option>
+ parameter, <command>nsgmls</command> will suppress its normal output, and
+ just print error messages. This makes it a useful way to check to
+ see if your document is valid or not.</para>
+
+ <para>Use <command>nsgmls</command> to check that your document is
+ valid:</para>
+
+ <screen>&prompt.user; <userinput>nsgmls -s example.xml</userinput></screen>
+
+ <para>As you will see, <command>nsgmls</command> returns without displaying any
+ output. This means that your document validated
+ successfully.</para>
+ </step>
+
+ <step>
+ <para>See what happens when required elements are omitted. Try
+ removing the <tag>title</tag> and
+ <tag>/title</tag> tags, and re-run the validation.</para>
+
+ <screen>&prompt.user; <userinput>nsgmls -s example.xml</userinput>
+nsgmls:example.xml:5:4:E: character data is not allowed here
+nsgmls:example.xml:6:8:E: end tag for "HEAD" which is not finished</screen>
+
+ <para>The error output from <command>nsgmls</command> is organized into
+ colon-separated groups, or columns.</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Column</entry>
+ <entry>Meaning</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>1</entry>
+ <entry>The name of the program generating the error. This
+ will always be <literal>nsgmls</literal>.</entry>
+ </row>
+
+ <row>
+ <entry>2</entry>
+ <entry>The name of the file that contains the error.</entry>
+ </row>
+
+ <row>
+ <entry>3</entry>
+ <entry>Line number where the error appears.</entry>
+ </row>
+
+ <row>
+ <entry>4</entry>
+ <entry>Column number where the error appears.</entry>
+ </row>
+
+ <row>
+ <entry>5</entry>
+ <entry>A one letter code indicating the nature of the
+ message. <literal>I</literal> indicates an informational
+ message, <literal>W</literal> is for warnings, and
+ <literal>E</literal> is for errors<footnote>
+ <para>It is not always the fifth column either.
+ <command>nsgmls -sv</command> displays
+ <literal>nsgmls:I: SP version "1.3"</literal>
+ (depending on the installed version). As you can see,
+ this is an informational message.</para>
+ </footnote>, and <literal>X</literal> is for
+ cross-references. As you can see, these messages are
+ errors.</entry>
+ </row>
+
+ <row>
+ <entry>6</entry>
+ <entry>The text of the error message.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>Simply omitting the <tag>title</tag> tags has
+ generated 2 different errors.</para>
+
+ <para>The first error indicates that content (in this case,
+ characters, rather than the start tag for an element) has occurred
+ where the SGML parser was expecting something else. In this case,
+ the parser was expecting to see one of the start tags for elements
+ that are valid inside <tag>head</tag> (such as
+ <tag>title</tag>).</para>
+
+ <para>The second error is because <tag>head</tag> elements
+ <emphasis>must</emphasis> contain a <tag>title</tag>
+ element. Because it does not <command>nsgmls</command> considers that the
+ element has not been properly finished. However, the closing tag
+ indicates that the element has been closed before it has been
+ finished.</para>
+ </step>
+
+ <step>
+ <para>Put the <literal>title</literal> element back in.</para>
+ </step>
+ </procedure>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="sgml-primer-doctype-declaration">
+ <title>The DOCTYPE declaration</title>
+
+ <para>The beginning of each document that you write must specify the name
+ of the DTD that the document conforms to. This is so that SGML parsers
+ can determine the DTD and ensure that the document does conform to
+ it.</para>
+
+ <para>This information is generally expressed on one line, in the DOCTYPE
+ declaration.</para>
+
+ <para>A typical declaration for a document written to conform with version
+ 4.0 of the HTML DTD looks like this:</para>
+
+ <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN">]]></programlisting>
+
+ <para>That line contains a number of different components.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>&lt;!</literal></term>
+
+ <listitem>
+ <para>Is the <emphasis>indicator</emphasis> that indicates that this
+ is an SGML declaration. This line is declaring the document type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DOCTYPE</literal></term>
+
+ <listitem>
+ <para>Shows that this is an SGML declaration for the document
+ type.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>html</literal></term>
+
+ <listitem>
+ <para>Names the first <link linkend="sgml-primer-elements">element</link> that
+ will appear in the document.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PUBLIC "-//W3C//DTD HTML 4.0//EN"</literal></term>
+
+ <listitem>
+ <para>Lists the Formal Public Identifier (FPI)<indexterm>
+ <primary>Formal Public Identifier</primary>
+ </indexterm>
+ for the DTD that this
+ document conforms to. Your SGML parser will use this to find the
+ correct DTD when processing this document.</para>
+
+ <para><literal>PUBLIC</literal> is not a part of the FPI, but
+ indicates to the SGML processor how to find the DTD referenced in
+ the FPI. Other ways of telling the SGML parser how to find the
+ DTD are shown <link linkend="sgml-primer-fpi-alternatives">later</link>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>&gt;</literal></term>
+
+ <listitem>
+ <para>Returns to the document.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <sect2>
+ <title>Formal Public Identifiers (FPIs)<indexterm significance="preferred">
+ <primary>Formal Public Identifier</primary>
+ </indexterm>
+</title>
+
+ <note>
+ <para>You do not need to know this, but it is useful background, and
+ might help you debug problems when your SGML processor can not locate
+ the DTD you are using.</para>
+ </note>
+
+ <para>FPIs must follow a specific syntax. This syntax is as
+ follows:</para>
+
+ <programlisting>"<replaceable>Owner</replaceable>//<replaceable>Keyword</replaceable> <replaceable>Description</replaceable>//<replaceable>Language</replaceable>"</programlisting>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>Owner</replaceable></term>
+
+ <listitem>
+ <para>This indicates the owner of the FPI.</para>
+
+ <para>If this string starts with <quote>ISO</quote> then this is an
+ ISO owned FPI. For example, the FPI <literal>"ISO
+ 8879:1986//ENTITIES Greek Symbols//EN"</literal> lists
+ <literal>ISO 8879:1986</literal> as being the owner for the set
+ of entities for Greek symbols. ISO 8879:1986 is the ISO number
+ for the SGML standard.</para>
+
+ <para>Otherwise, this string will either look like
+ <literal>-//Owner</literal> or
+ <literal>+//Owner</literal> (notice
+ the only difference is the leading <literal>+</literal> or
+ <literal>-</literal>).</para>
+
+ <para>If the string starts with <literal>-</literal> then the
+ owner information is unregistered, with a <literal>+</literal>
+ it identifies it as being registered.</para>
+
+ <para>ISO 9070:1991 defines how registered names are generated; it
+ might be derived from the number of an ISO publication, an ISBN
+ code, or an organization code assigned according to ISO 6523.
+ In addition, a registration authority could be created in order
+ to assign registered names. The ISO council delegated this to
+ the American National Standards Institute (ANSI).</para>
+
+ <para>Because the FreeBSD Project has not been registered the
+ owner string is <literal>-//FreeBSD</literal>. And as you can
+ see, the W3C are not a registered owner either.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>Keyword</replaceable></term>
+
+ <listitem>
+ <para>There are several keywords that indicate the type of
+ information in the file. Some of the most common keywords are
+ <literal>DTD</literal>, <literal>ELEMENT</literal>,
+ <literal>ENTITIES</literal>, and <literal>TEXT</literal>.
+ <literal>DTD</literal> is used only for DTD files,
+ <literal>ELEMENT</literal> is usually used for DTD fragments
+ that contain only entity or element declarations.
+ <literal>TEXT</literal> is used for SGML content (text and
+ tags).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>Description</replaceable></term>
+
+ <listitem>
+ <para>Any description you want to supply for the contents of this
+ file. This may include version numbers or any short text that
+ is meaningful to you and unique for the SGML system.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>Language</replaceable></term>
+
+ <listitem>
+ <para>This is an ISO two-character code that identifies the native
+ language for the file. <literal>EN</literal> is used for
+ English.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <sect3>
+ <title><filename>catalog</filename> files</title>
+
+ <para>If you use the syntax above and process this document
+ using an SGML processor, the processor will need to have some way of
+ turning the FPI into the name of the file on your computer that
+ contains the DTD.</para>
+
+ <para>In order to do this it can use a catalog file. A catalog file
+ (typically called <filename>catalog</filename>) contains lines that
+ map FPIs to filenames. For example, if the catalog file contained
+ the line:</para>
+
+ <programlisting>PUBLIC "-//W3C//DTD HTML 4.0//EN" "4.0/strict.dtd"</programlisting>
+
+ <para>The SGML processor would know to look up the DTD from
+ <filename>strict.dtd</filename> in the <filename>4.0</filename>
+ subdirectory of whichever directory held the
+ <filename>catalog</filename> file that contained that line.</para>
+
+ <para>Look at the contents of
+ <filename>/usr/local/share/xml/html/catalog</filename>. This is
+ the catalog file for the HTML DTDs that will have been installed as
+ part of the <package>textproc/docproj</package> port.</para>
+ </sect3>
+
+ <sect3>
+ <title><envar>SGML_CATALOG_FILES</envar></title>
+
+ <para>In order to locate a <filename>catalog</filename> file, your
+ SGML processor will need to know where to look. Many of them
+ feature command line parameters for specifying the path to one or
+ more catalogs.</para>
+
+ <para>In addition, you can set <envar>SGML_CATALOG_FILES</envar> to
+ point to the files. This environment variable should consist of a
+ colon-separated list of catalog files (including their full
+ path).</para>
+
+ <para>Typically, you will want to include the following files:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><filename>/usr/local/share/xml/docbook/4.1/catalog</filename></para>
+ </listitem>
+
+ <listitem>
+ <para><filename>/usr/local/share/xml/html/catalog</filename></para>
+ </listitem>
+
+ <listitem>
+ <para><filename>/usr/local/share/xml/iso8879/catalog</filename></para>
+ </listitem>
+
+ <listitem>
+ <para><filename>/usr/local/share/xml/jade/catalog</filename></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>You should <link linkend="sgml-primer-envars">already have done
+ this</link>.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="sgml-primer-fpi-alternatives">
+ <title>Alternatives to FPIs</title>
+
+ <para>Instead of using an FPI to indicate the DTD that the document
+ conforms to (and therefore, which file on the system contains the DTD)
+ you can explicitly specify the name of the file.</para>
+
+ <para>The syntax for this is slightly different:</para>
+
+ <programlisting><![CDATA[<!DOCTYPE html SYSTEM "/path/to/file.dtd">]]></programlisting>
+
+ <para>The <literal>SYSTEM</literal> keyword indicates that the SGML
+ processor should locate the DTD in a system specific fashion. This
+ typically (but not always) means the DTD will be provided as a
+ filename.</para>
+
+ <para>Using FPIs is preferred for reasons of portability. You do not
+ want to have to ship a copy of the DTD around with your document, and
+ if you used the <literal>SYSTEM</literal> identifier then everyone
+ would need to keep their DTDs in the same place.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="sgml-primer-sgml-escape">
+ <title>Escaping back to SGML</title>
+
+ <para>Earlier in this primer I said that SGML is only used when writing a
+ DTD. This is not strictly true. There is certain SGML syntax that you
+ will want to be able to use within your documents. For example,
+ comments can be included in your document, and will be ignored by the
+ parser. Comments are entered using SGML syntax. Other uses for SGML
+ syntax in your document will be shown later too.</para>
+
+ <para>Obviously, you need some way of indicating to the SGML processor
+ that the following content is not elements within the document, but is
+ SGML that the parser should act upon.</para>
+
+ <para>These sections are marked by <literal>&lt;! ... &gt;</literal> in
+ your document. Everything between these delimiters is SGML syntax as
+ you might find within a DTD.</para>
+
+ <para>As you may just have realized, the <link linkend="sgml-primer-doctype-declaration">DOCTYPE declaration</link>
+ is an example of SGML syntax that you need to include in your
+ document&hellip;</para>
+ </sect1>
+
+ <sect1 xml:id="sgml-primer-comments">
+ <title>註解</title>
+
+ <para>Comments are an SGML construction, and are normally only valid
+ inside a DTD. However, as <xref linkend="sgml-primer-sgml-escape"/>
+ shows, it is possible to use SGML syntax within your document.</para>
+
+ <para>The delimiter for SGML comments is the string
+ <quote><literal>--</literal></quote>. The first occurrence of this string
+ opens a comment, and the second closes it.</para>
+
+ <example>
+ <title>SGML generic comment</title>
+
+ <programlisting>&lt;!-- 測試註解 --&gt;</programlisting>
+
+ <programlisting>
+&lt;!&hyphen;- 這是註解 -&hyphen;&gt;
+
+&lt;!&hyphen;- 這也是註解 -&hyphen;&gt;
+
+&lt;!&hyphen;- 要寫多行註解的話,
+ 這是其中之一的方式 -&hyphen;&gt;
+
+&lt;!&hyphen;- 要寫多行註解, -&hyphen;
+ &hyphen;- 也可以這樣子用 -&hyphen;&gt;</programlisting>
+ </example>
+
+ <para>If you have used HTML before you may have been shown different rules
+ for comments. In particular, you may think that the string
+ <literal>&lt;!--</literal> opens a comment, and it is only closed by
+ <literal>--&gt;</literal>.</para>
+
+ <para>This is <emphasis>not</emphasis> the case. A lot of web browsers
+ have broken HTML parsers, and will accept that as valid. However, the
+ SGML parsers used by the Documentation Project are much stricter, and
+ will reject documents that make that error.</para>
+
+ <example>
+ <title>Erroneous SGML comments</title>
+
+ <programlisting>
+&lt;!&hyphen;- This is in the comment -&hyphen;
+
+ THIS IS OUTSIDE THE COMMENT!
+
+ &hyphen;- back inside the comment -&hyphen;&gt;</programlisting>
+
+ <para>The SGML parser will treat this as though it were actually:</para>
+
+ <programlisting>&lt;!THIS IS OUTSIDE THE COMMENT&gt;</programlisting>
+
+ <para>This is not valid SGML, and may give confusing error
+ messages.</para>
+
+ <programlisting>&lt;!&hyphen;&hyphen;&hyphen;&hyphen;&hyphen; This is a very bad idea &hyphen;&hyphen;&hyphen;&hyphen;&hyphen;&gt;</programlisting>
+
+ <para>As the example suggests, <emphasis>do not</emphasis> write
+ comments like that.</para>
+
+ <programlisting>&lt;!&hyphen;-===================================================-&hyphen;&gt;</programlisting>
+
+ <para>That is a (slightly) better approach, but it still potentially
+ confusing to people new to SGML.</para>
+ </example>
+
+ <sect2>
+ <title>For you to do&hellip;</title>
+
+ <procedure>
+ <step>
+ <para>Add some comments to <filename>example.xml</filename>, and
+ check that the file still validates using <command>nsgmls</command>.</para>
+ </step>
+
+ <step>
+ <para>Add some invalid comments to
+ <filename>example.xml</filename>, and see the error messages that
+ <command>nsgmls</command> gives when it encounters an invalid comment.</para>
+ </step>
+ </procedure>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="sgml-primer-entities">
+ <title>Entities</title>
+
+ <para>Entities are a mechanism for assigning names to chunks of content.
+ As an SGML parser processes your document, any entities it finds are
+ replaced by the content of the entity.</para>
+
+ <para>This is a good way to have re-usable, easily changeable chunks of
+ content in your SGML documents. It is also the only way to include one
+ marked up file inside another using SGML.</para>
+
+ <para>There are two types of entities which can be used in two different
+ situations; <emphasis>general entities</emphasis> and
+ <emphasis>parameter entities</emphasis>.</para>
+
+ <sect2 xml:id="sgml-primer-general-entities">
+ <title>General Entities</title>
+
+ <para>You cannot use general entities in an SGML context (although you
+ define them in one). They can only be used in your document.
+ Contrast this with <link linkend="sgml-primer-parameter-entities">parameter
+ entities</link>.</para>
+
+ <para>Each general entity has a name. When you want to reference a
+ general entity (and therefore include whatever text it represents in
+ your document), you write
+ <literal>&amp;entity-name;</literal>. For
+ example, suppose you had an entity called
+ <literal>current.version</literal> which expanded to the current
+ version number of your product. You could write:</para>
+
+ <programlisting><![CDATA[<para>The current version of our product is
+ &current.version;.</para>]]></programlisting>
+
+ <para>When the version number changes you can simply change the
+ definition of the value of the general entity and reprocess your
+ document.</para>
+
+ <para>You can also use general entities to enter characters that you
+ could not otherwise include in an SGML document. For example,
+ <literal>&lt;</literal> and <literal>&amp;</literal> cannot
+ normally appear in an SGML document. When the SGML
+ parser sees the <literal>&lt;</literal>
+ symbol it assumes that a tag (either a start tag
+ or an end tag) is about to appear, and when it sees the
+ <literal>&amp;</literal> symbol
+ it assumes the next text will be the name of an entity.</para>
+
+ <para>Fortunately, you can use the two general entities
+ <literal>&amp;lt;</literal> and <literal>&amp;amp;</literal>
+ whenever you need to include one or other of these.</para>
+
+ <para>A general entity can only be defined within an SGML context.
+ Typically, this is done immediately after the DOCTYPE
+ declaration.</para>
+
+ <example>
+ <title>Defining general entities</title>
+
+ <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN" [
+<!ENTITY current.version "3.0-RELEASE">
+<!ENTITY last.version "2.2.7-RELEASE">
+]>]]></programlisting>
+
+ <para>Notice how the DOCTYPE declaration has been extended by adding a
+ square bracket at the end of the first line. The two entities are
+ then defined over the next two lines, before the square bracket is
+ closed, and then the DOCTYPE declaration is closed.</para>
+
+ <para>The square brackets are necessary to indicate that we are
+ extending the DTD indicated by the DOCTYPE declaration.</para>
+ </example>
+ </sect2>
+
+ <sect2 xml:id="sgml-primer-parameter-entities">
+ <title>Parameter entities</title>
+
+ <para>Like <link linkend="sgml-primer-general-entities">general
+ entities</link>, parameter entities are used to assign names to
+ reusable chunks of text. However, where as general entities can only
+ be used within your document, parameter entities can only be used
+ within an <link linkend="sgml-primer-sgml-escape">SGML
+ context</link>.</para>
+
+ <para>Parameter entities are defined in a similar way to general
+ entities. However, instead of using
+ <literal>&amp;entity-name;</literal> to
+ refer to them, use
+ <literal>%entity-name;</literal><footnote>
+ <para><emphasis>P</emphasis>arameter entities use the
+ <emphasis>P</emphasis>ercent symbol.</para>
+ </footnote>. The definition also includes the <literal>%</literal>
+ between the <literal>ENTITY</literal> keyword and the name of the
+ entity.</para>
+
+ <example>
+ <title>Defining parameter entities</title>
+
+ <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN" [
+<!ENTITY % param.some "some">
+<!ENTITY % param.text "text">
+<!ENTITY % param.new "%param.some more %param.text">
+]>]]></programlisting>
+ </example>
+
+ <para>This may not seem particularly useful. It will be.</para>
+ </sect2>
+
+ <sect2>
+ <title>For you to do&hellip;</title>
+
+ <procedure>
+ <step>
+ <para>Add a general entity to
+ <filename>example.xml</filename>.</para>
+
+ <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" [
+<!ENTITY version "1.1">
+]>
+
+<html>
+ <head>
+ <title>An example HTML file</title>
+ </head>
+
+ <body>
+ <p>This is a paragraph containing some text.</p>
+
+ <p>This paragraph contains some more text.</p>
+
+ <p align="right">This paragraph might be right-justified.</p>
+
+ <p>The current version of this document is: &version;</p>
+ </body>
+</html>]]></programlisting>
+ </step>
+
+ <step>
+ <para>Validate the document using <command>nsgmls</command>.</para>
+ </step>
+
+ <step>
+ <para>Load <filename>example.xml</filename> into your web browser
+ (you may need to copy it to <filename>example.html</filename>
+ before your browser recognizes it as an HTML document).</para>
+
+ <para>Unless your browser is very advanced, you will not see the entity
+ reference <literal>&amp;version;</literal> replaced with the
+ version number. Most web browsers have very simplistic parsers
+ which do not handle proper SGML<footnote>
+ <para>This is a shame. Imagine all the problems and hacks (such
+ as Server Side Includes) that could be avoided if they
+ did.</para>
+ </footnote>.</para>
+ </step>
+
+ <step>
+ <para>The solution is to <emphasis>normalize</emphasis> your
+ document using an SGML normalizer. The normalizer reads in valid
+ SGML and outputs equally valid SGML which has been transformed in
+ some way. One of the ways in which the normalizer transforms the
+ SGML is to expand all the entity references in the document,
+ replacing the entities with the text that they represent.</para>
+
+ <para>You can use <command>sgmlnorm</command> to do this.</para>
+
+ <screen>&prompt.user; <userinput>sgmlnorm example.xml &gt; example.html</userinput></screen>
+
+ <para>You should find a normalized (i.e., entity references
+ expanded) copy of your document in
+ <filename>example.html</filename>, ready to load into your web
+ browser.</para>
+ </step>
+
+ <step>
+ <para>If you look at the output from <command>sgmlnorm</command>
+ you will see that it does not include a DOCTYPE declaration at
+ the start. To include this you need to use the <option>-d</option>
+ option:</para>
+
+ <screen>&prompt.user; <userinput>sgmlnorm -d example.xml &gt; example.html</userinput></screen>
+ </step>
+ </procedure>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="sgml-primer-include">
+ <title>Using entities to include files</title>
+
+ <para>Entities (both <link linkend="sgml-primer-general-entities">general</link> and <link linkend="sgml-primer-parameter-entities">parameter</link>) are
+ particularly useful when used to include one file inside another.</para>
+
+ <sect2 xml:id="sgml-primer-include-using-gen-entities">
+ <title>Using general entities to include files</title>
+
+ <para>Suppose you have some content for an SGML book organized into
+ files, one file per chapter, called
+ <filename>chapter1.xml</filename>,
+ <filename>chapter2.xml</filename>, and so forth, with a
+ <filename>book.xml</filename> file that will contain these
+ chapters.</para>
+
+ <para>In order to use the contents of these files as the values for your
+ entities, you declare them with the <literal>SYSTEM</literal> keyword.
+ This directs the SGML parser to use the contents of the named file as
+ the value of the entity.</para>
+
+ <example>
+ <title>Using general entities to include files</title>
+
+ <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN" [
+<!ENTITY chapter.1 SYSTEM "chapter1.xml">
+<!ENTITY chapter.2 SYSTEM "chapter2.xml">
+<!ENTITY chapter.3 SYSTEM "chapter3.xml">
+]>
+
+<html>
+
+ &chapter.1;
+ &chapter.2;
+ &chapter.3;
+</html>]]></programlisting>
+ </example>
+
+ <warning>
+ <para>When using general entities to include other files within a
+ document, the files being included
+ (<filename>chapter1.xml</filename>,
+ <filename>chapter2.xml</filename>, and so on) <emphasis>must
+ not</emphasis> start with a DOCTYPE declaration. This is a syntax
+ error.</para>
+ </warning>
+ </sect2>
+
+ <sect2>
+ <title>Using parameter entities to include files</title>
+
+ <para>Recall that parameter entities can only be used inside an SGML
+ context. Why then would you want to include a file within an SGML
+ context?</para>
+
+ <para>You can use this to ensure that you can reuse your general
+ entities.</para>
+
+ <para>Suppose that you had many chapters in your document, and you
+ reused these chapters in two different books, each book organizing the
+ chapters in a different fashion.</para>
+
+ <para>You could list the entities at the top of each book, but this
+ quickly becomes cumbersome to manage.</para>
+
+ <para>Instead, place the general entity definitions inside one file,
+ and use a parameter entity to include that file within your
+ document.</para>
+
+ <example>
+ <title>Using parameter entities to include files</title>
+
+ <para>First, place your entity definitions in a separate file, called
+ <filename>chapters.ent</filename>. This file contains the
+ following:</para>
+
+ <programlisting><![CDATA[<!ENTITY chapter.1 SYSTEM "chapter1.xml">
+<!ENTITY chapter.2 SYSTEM "chapter2.xml">
+<!ENTITY chapter.3 SYSTEM "chapter3.xml">]]></programlisting>
+
+ <para>Now create a parameter entity to refer to the contents of the
+ file. Then use the parameter entity to load the file into the
+ document, which will then make all the general entities available
+ for use. Then use the general entities as before:</para>
+
+ <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN" [
+<!ENTITY % chapters SYSTEM "chapters.ent">
+%chapters;
+]>
+
+<html>
+ &chapter.1;
+ &chapter.2;
+ &chapter.3;
+</html>]]></programlisting>
+ </example>
+ </sect2>
+
+ <sect2>
+ <title>For you to do&hellip;</title>
+
+ <sect3>
+ <title>Use general entities to include files</title>
+
+ <procedure>
+ <step>
+ <para>Create three files, <filename>para1.xml</filename>,
+ <filename>para2.xml</filename>, and
+ <filename>para3.xml</filename>.</para>
+
+ <para>Put content similar to the following in each file:</para>
+
+ <programlisting><![CDATA[<p>This is the first paragraph.</p>]]></programlisting>
+ </step>
+
+ <step>
+ <para>Edit <filename>example.xml</filename> so that it looks like
+ this:</para>
+
+ <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN" [
+<!ENTITY version "1.1">
+<!ENTITY para1 SYSTEM "para1.xml">
+<!ENTITY para2 SYSTEM "para2.xml">
+<!ENTITY para3 SYSTEM "para3.xml">
+]>
+
+<html>
+ <head>
+ <title>An example HTML file</title>
+ </head>
+
+ <body>
+ <p>The current version of this document is: &version;</p>
+
+ &para1;
+ &para2;
+ &para3;
+ </body>
+</html>]]></programlisting>
+ </step>
+
+ <step>
+ <para>Produce <filename>example.html</filename> by normalizing
+ <filename>example.xml</filename>.</para>
+
+ <screen>&prompt.user; <userinput>sgmlnorm -d example.xml &gt; example.html</userinput></screen>
+ </step>
+
+ <step>
+ <para>Load <filename>example.html</filename> into your web
+ browser, and confirm that the
+ <filename>paran.xml</filename> files
+ have been included in <filename>example.html</filename>.</para>
+ </step>
+ </procedure>
+ </sect3>
+
+ <sect3>
+ <title>Use parameter entities to include files</title>
+
+ <note>
+ <para>You must have taken the previous steps first.</para>
+ </note>
+
+ <procedure>
+ <step>
+ <para>Edit <filename>example.xml</filename> so that it looks like
+ this:</para>
+
+ <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN" [
+<!ENTITY % entities SYSTEM "entities.xml"> %entities;
+]>
+
+<html>
+ <head>
+ <title>An example HTML file</title>
+ </head>
+
+ <body>
+ <p>The current version of this document is: &version;</p>
+
+ &para1;
+ &para2;
+ &para3;
+ </body>
+</html>]]></programlisting>
+ </step>
+
+ <step>
+ <para>Create a new file, <filename>entities.xml</filename>, with
+ this content:</para>
+
+ <programlisting><![CDATA[<!ENTITY version "1.1">
+<!ENTITY para1 SYSTEM "para1.xml">
+<!ENTITY para2 SYSTEM "para2.xml">
+<!ENTITY para3 SYSTEM "para3.xml">]]></programlisting>
+ </step>
+
+ <step>
+ <para>Produce <filename>example.html</filename> by normalizing
+ <filename>example.xml</filename>.</para>
+
+ <screen>&prompt.user; <userinput>sgmlnorm -d example.xml &gt; example.html</userinput></screen>
+ </step>
+
+ <step>
+ <para>Load <filename>example.html</filename> into your web
+ browser, and confirm that the
+ <filename>paran.xml</filename> files
+ have been included in <filename>example.html</filename>.</para>
+ </step>
+ </procedure>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="sgml-primer-marked-sections">
+ <title>Marked sections</title>
+
+ <para>SGML provides a mechanism to indicate that particular pieces of the
+ document should be processed in a special way. These are termed
+ <quote>marked sections</quote>.</para>
+
+ <example>
+ <title>Structure of a marked section</title>
+
+ <programlisting>&lt;![ <replaceable>KEYWORD</replaceable> [
+ Contents of marked section
+]]&gt;</programlisting>
+ </example>
+
+ <para>As you would expect, being an SGML construct, a marked section
+ starts with <literal>&lt;!</literal>.</para>
+
+ <para>The first square bracket begins to delimit the marked
+ section.</para>
+
+ <para><replaceable>KEYWORD</replaceable> describes how this marked
+ section should be processed by the parser.</para>
+
+ <para>The second square bracket indicates that the content of the marked
+ section starts here.</para>
+
+ <para>The marked section is finished by closing the two square brackets,
+ and then returning to the document context from the SGML context with
+ <literal>&gt;</literal>.</para>
+
+ <sect2>
+ <title>Marked section keywords</title>
+
+ <sect3>
+ <title><literal>CDATA</literal>, <literal>RCDATA</literal></title>
+
+ <para>These keywords denote the marked sections <emphasis>content
+ model</emphasis>, and allow you to change it from the
+ default.</para>
+
+ <para>When an SGML parser is processing a document it keeps track
+ of what is called the <quote>content model</quote>.</para>
+
+ <para>Briefly, the content model describes what sort of content the
+ parser is expecting to see, and what it will do with it when it
+ finds it.</para>
+
+ <para>The two content models you will probably find most useful are
+ <literal>CDATA</literal> and <literal>RCDATA</literal>.</para>
+
+ <para><literal>CDATA</literal> is for <quote>Character Data</quote>.
+ If the parser is in this content model then it is expecting to see
+ characters, and characters only. In this model the
+ <literal>&lt;</literal> and <literal>&amp;</literal>
+ symbols lose their special status, and will be treated as ordinary
+ characters.</para>
+
+ <para><literal>RCDATA</literal> is for <quote>Entity references and
+ character data</quote> If the parser is in this content model then it
+ is expecting to see characters <emphasis>and</emphasis> entities.
+ <literal>&lt;</literal> loses its special status, but
+ <literal>&amp;</literal> will still be treated as
+ starting the beginning of a general entity.</para>
+
+ <para>This is particularly useful if you are including some verbatim
+ text that contains lots of <literal>&lt;</literal> and
+ <literal>&amp;</literal> characters. While you
+ could go through the text ensuring that every
+ <literal>&lt;</literal> is converted to a
+ <literal>&amp;lt;</literal> and every <literal>&amp;</literal>
+ is converted to a <literal>&amp;amp;</literal>, it can be
+ easier to mark the section as only containing CDATA. When the SGML
+ parser encounters this it will ignore the
+ <literal>&lt;</literal> and <literal>&amp;</literal> symbols
+ embedded in the content.</para>
+
+ <note>
+ <para>When you use <literal>CDATA</literal> or
+ <literal>RCDATA</literal> in examples of text marked up in SGML,
+ keep in mind that the content of <literal>CDATA</literal> is not
+ validated. You have to check the included SGML text using other
+ means. You could, for example, write the example in another
+ document, validate the example code, and then paste it to your
+ <literal>CDATA</literal> content.</para>
+ </note>
+ <!-- The nesting of CDATA within the next example is disgusting -->
+
+ <example>
+ <title>Using a CDATA marked section</title>
+
+ <programlisting>&lt;para&gt;Here is an example of how you would include some text
+ that contained many &lt;literal&gt;&amp;lt;&lt;/literal&gt;
+ and &lt;literal&gt;&amp;amp;&lt;/literal&gt; symbols. The sample
+ text is a fragment of HTML. The surrounding text (&lt;para&gt; and
+ &lt;programlisting&gt;) are from DocBook.&lt;/para&gt;
+
+&lt;programlisting&gt;
+ &lt;![CDATA[<![CDATA[
+ <p>This is a sample that shows you some of the elements within
+ HTML. Since the angle brackets are used so many times, it is
+ simpler to say the whole example is a CDATA marked section
+ than to use the entity names for the left and right angle
+ brackets throughout.</p>
+
+ <ul>
+ <li>This is a listitem</li>
+ <li>This is a second listitem</li>
+ <li>This is a third listitem</li>
+ </ul>
+
+ <p>This is the end of the example.</p>]]>
+ ]]&gt;
+&lt;/programlisting&gt;</programlisting>
+
+ <para>If you look at the source for this document you will see this
+ technique used throughout.</para>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title><literal>INCLUDE</literal> and
+ <literal>IGNORE</literal></title>
+
+ <para>If the keyword is <literal>INCLUDE</literal> then the contents
+ of the marked section will be processed. If the keyword is
+ <literal>IGNORE</literal> then the marked section is ignored and
+ will not be processed. It will not appear in the output.</para>
+
+ <example>
+ <title>Using <literal>INCLUDE</literal> and
+ <literal>IGNORE</literal> in marked sections</title>
+
+ <programlisting>&lt;![ INCLUDE [
+ This text will be processed and included.
+]]&gt;
+
+&lt;![ IGNORE [
+ This text will not be processed or included.
+]]&gt;</programlisting>
+ </example>
+
+ <para>By itself, this is not too useful. If you wanted to remove text
+ from your document you could cut it out, or wrap it in
+ comments.</para>
+
+ <para>It becomes more useful when you realize you can use <link linkend="sgml-primer-parameter-entities">parameter entities</link>
+ to control this. Remember that parameter entities can only be used
+ in SGML contexts, and the keyword of a marked section
+ <emphasis>is</emphasis> an SGML context.</para>
+
+ <para>For example, suppose that you produced a hard-copy version of
+ some documentation and an electronic version. In the electronic
+ version you wanted to include some extra content that was not to
+ appear in the hard-copy.</para>
+
+ <para>Create a parameter entity, and set its value to
+ <literal>INCLUDE</literal>. Write your document, using marked
+ sections to delimit content that should only appear in the
+ electronic version. In these marked sections use the parameter
+ entity in place of the keyword.</para>
+
+ <para>When you want to produce the hard-copy version of the document,
+ change the parameter entity's value to <literal>IGNORE</literal> and
+ reprocess the document.</para>
+
+ <example>
+ <title>Using a parameter entity to control a marked
+ section</title>
+
+ <programlisting>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN" [
+&lt;!ENTITY % electronic.copy "INCLUDE"&gt;
+]]&gt;
+
+...
+
+&lt;![ %electronic.copy [
+ This content should only appear in the electronic
+ version of the document.
+]]&gt;</programlisting>
+
+ <para>When producing the hard-copy version, change the entity's
+ definition to:</para>
+
+ <programlisting>&lt;!ENTITY % electronic.copy "IGNORE"&gt;</programlisting>
+
+ <para>On reprocessing the document, the marked sections that use
+ <literal>%electronic.copy</literal> as their keyword will be
+ ignored.</para>
+ </example>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>For you to do&hellip;</title>
+
+ <procedure>
+ <step>
+ <para>Create a new file, <filename>section.xml</filename>, that
+ contains the following:</para>
+
+ <programlisting>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN" [
+&lt;!ENTITY % text.output "INCLUDE"&gt;
+]&gt;
+
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;title&gt;An example using marked sections&lt;/title&gt;
+ &lt;/head&gt;
+
+ &lt;body&gt;
+ &lt;p&gt;This paragraph &lt;![CDATA[contains many &lt;
+ characters (&lt; &lt; &lt; &lt; &lt;) so it is easier
+ to wrap it in a CDATA marked section ]]&gt;&lt;/p&gt;
+
+ &lt;![IGNORE[
+ &lt;p&gt;This paragraph will definitely not be included in the
+ output.&lt;/p&gt;
+ ]]&gt;
+
+ &lt;![<![CDATA[%text.output]]> [
+ &lt;p&gt;This paragraph might appear in the output, or it
+ might not.&lt;/p&gt;
+
+ &lt;p&gt;Its appearance is controlled by the <![CDATA[%text.output]]>
+ parameter entity.&lt;/p&gt;
+ ]]&gt;
+ &lt;/body&gt;
+&lt;/html&gt;</programlisting>
+ </step>
+
+ <step>
+ <para>Normalize this file using &man.xmlnorm.1; and examine the
+ output. Notice which paragraphs have appeared, which have
+ disappeared, and what has happened to the content of the CDATA
+ marked section.</para>
+ </step>
+
+ <step>
+ <para>Change the definition of the <literal>text.output</literal>
+ entity from <literal>INCLUDE</literal> to
+ <literal>IGNORE</literal>. Re-normalize the file, and examine the
+ output to see what has changed.</para>
+ </step>
+ </procedure>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="sgml-primer-conclusion">
+ <title>Conclusion</title>
+
+ <para>That is the conclusion of this SGML primer. For reasons of space
+ and complexity several things have not been covered in depth (or at
+ all). However, the previous sections cover enough SGML for you to be
+ able to follow the organization of the FDP documentation.</para>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/fdp-primer/structure/chapter.xml b/zh_TW.UTF-8/books/fdp-primer/structure/chapter.xml
new file mode 100644
index 0000000000..c4feee84cb
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/structure/chapter.xml
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 1998, 1999 Nik Clayton, All rights reserved.
+
+ Redistribution and use in source (SGML DocBook) and 'compiled' forms
+ (SGML HTML, PDF, PostScript, RTF and so forth) with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code (SGML DocBook) must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+ 2. Redistributions in compiled form (transformed to other DTDs,
+ converted to PDF, PostScript, RTF and other formats) must reproduce
+ the above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ $FreeBSD$
+ Original revision: 1.17
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="structure">
+ <title>Structuring documents under <filename>doc/</filename></title>
+
+ <para>The <filename>doc/</filename> tree is organized in a particular
+ fashion, and the documents that are part of the FDP are in turn organized
+ in a particular fashion. The aim is to make it simple to add new
+ documentation into the tree and:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>make it easy to automate converting the document to other formats;</para>
+ </listitem>
+
+ <listitem>
+ <para>promote consistency between the different documentation
+ organizations, to make it easier to switch between working on
+ different documents;</para>
+ </listitem>
+
+ <listitem>
+ <para>make it easy to decide where in the tree new documentation should
+ be placed.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>In addition, the documentation tree has to accommodate documentation
+ that could be in many different languages and in many different
+ encodings. It is important that the structure of the documentation tree
+ does not enforce any particular defaults or cultural preferences.</para>
+
+ <sect1 xml:id="structure-top">
+ <title>The top level, <filename>doc/</filename></title>
+
+ <para>There are two types of directory under <filename>doc/</filename>,
+ each with very specific directory names and meanings.</para>
+
+ <segmentedlist>
+ <segtitle>Directory</segtitle>
+
+ <segtitle>Meaning</segtitle>
+
+ <seglistitem>
+ <seg><filename>share/</filename></seg>
+
+ <seg>Contains files that are not specific to the various translations
+ and encodings of the documentation. Contains subdirectories to
+ further categorize the information. For example, the files that
+ comprise the &man.make.1; infrastructure are in
+ <filename>share/mk</filename>, while the additional SGML support
+ files (such as the FreeBSD extended DocBook DTD) are in
+ <filename>share/xml</filename>.</seg>
+ </seglistitem>
+
+ <seglistitem>
+ <seg><filename>lang.encoding/</filename></seg>
+
+ <seg>One directory exists for each available translation and encoding
+ of the documentation, for example
+ <filename>en_US.ISO8859-1/</filename> and
+ <filename>zh_TW.UTF-8/</filename>. The names are long, but by fully
+ specifying the language and encoding we prevent any future headaches
+ should a translation team want to provide the documentation in the
+ same language but in more than one encoding. This also completely
+ isolates us from any problems that might be caused by a switch to
+ Unicode.</seg>
+ </seglistitem>
+ </segmentedlist>
+ </sect1>
+
+ <sect1 xml:id="structure-locale">
+ <title>The
+ <filename>lang.encoding/</filename> directories</title>
+
+ <para>These directories contain the documents themselves. The
+ documentation is split into up to three more categories at this
+ level, indicated by the different directory names.</para>
+
+ <segmentedlist>
+ <segtitle>Directory</segtitle>
+
+ <segtitle>Contents</segtitle>
+
+ <seglistitem>
+ <seg><filename>articles</filename></seg>
+
+ <seg>Documentation marked up as a DocBook <tag>article</tag>
+ (or equivalent). Reasonably short, and broken up into sections.
+ Normally only available as one HTML file.</seg>
+ </seglistitem>
+
+ <seglistitem>
+ <seg><filename>books</filename></seg>
+
+ <seg>Documentation marked up as a DocBook <tag>book</tag> (or
+ equivalent). Book length, and broken up into chapters. Normally
+ available as both one large HTML file (for people with fast
+ connections, or who want to print it easily from a browser) and
+ as a collection of linked, smaller files.</seg>
+ </seglistitem>
+
+ <seglistitem>
+ <seg><filename>man</filename></seg>
+
+ <seg>For translations of the system manual pages. This directory will
+ contain one or more
+ <filename>mann</filename> directories,
+ corresponding to the sections that have been translated.</seg>
+ </seglistitem>
+ </segmentedlist>
+
+ <para>Not every
+ <filename>lang.encoding</filename> directory will contain all of these directories. It depends
+ on how much translation has been accomplished by that translation
+ team.</para>
+ </sect1>
+
+ <sect1 xml:id="structure-document">
+ <title>Document specific information</title>
+
+ <para>This section contains specific notes about particular documents
+ managed by the FDP.</para>
+
+ <sect2>
+ <title>The Handbook</title>
+
+ <subtitle><filename>books/handbook/</filename></subtitle>
+
+ <para>The Handbook is written to comply with the FreeBSD DocBook
+ extended DTD.</para>
+
+ <para>The Handbook is organized as a DocBook <tag>book</tag>.
+ It is then divided into <tag>part</tag>s, each of which may
+ contain several <tag>chapter</tag>s.
+ <tag>chapter</tag>s are further subdivided into sections
+ (<tag>sect1</tag>) and subsections (<tag>sect2</tag>,
+ <tag>sect3</tag>) and so on.</para>
+
+ <sect3>
+ <title>Physical organization</title>
+
+ <para>There are a number of files and directories within the
+ <filename>handbook</filename> directory.</para>
+
+ <note>
+ <para>The Handbook's organization may change over time, and this
+ document may lag in detailing the organizational changes. If you
+ have any questions about how the Handbook is organized, please
+ contact the &a.doc;.</para>
+ </note>
+
+ <sect4>
+ <title><filename>Makefile</filename></title>
+
+ <para>The <filename>Makefile</filename> defines some variables that
+ affect how the SGML source is converted to other formats, and
+ lists the various source files that make up the Handbook. It then
+ includes the standard <filename>doc.project.mk</filename> file, to
+ bring in the rest of the code that handles converting documents
+ from one format to another.</para>
+ </sect4>
+
+ <sect4>
+ <title><filename>book.xml</filename></title>
+
+ <para>This is the top level document in the Handbook. It contains
+ the Handbook's <link linkend="sgml-primer-doctype-declaration">DOCTYPE
+ declaration</link>, as well as the elements that describe the
+ Handbook's structure.</para>
+
+ <para><filename>book.xml</filename> uses <link linkend="sgml-primer-parameter-entities">parameter
+ entities</link> to load in the files with the
+ <filename>.ent</filename> extension. These files (described later)
+ then define <link linkend="sgml-primer-general-entities">general
+ entities</link> that are used throughout the rest of the
+ Handbook.</para>
+ </sect4>
+
+ <sect4>
+ <title><filename>directory/chapter.xml</filename></title>
+
+ <para>Each chapter in the Handbook is stored in a file called
+ <filename>chapter.xml</filename> in a separate directory from the
+ other chapters. Each directory is named after the value of the
+ <literal>id</literal> attribute on the <tag>chapter</tag>
+ element.</para>
+
+ <para>For example, if one of the chapter files contains:</para>
+
+ <programlisting><![CDATA[
+<chapter id="kernelconfiguration">
+...
+</chapter>]]></programlisting>
+
+ <para>then it will be called <filename>chapter.xml</filename> in
+ the <filename>kernelconfiguration</filename> directory. In
+ general, the entire contents of the chapter will be held in this
+ file.</para>
+
+ <para>When the HTML version of the Handbook is produced, this will
+ yield <filename>kernelconfiguration.html</filename>. This is
+ because of the <literal>id</literal> value, and is not related to
+ the name of the directory.</para>
+
+ <para>In earlier versions of the Handbook the files were stored in
+ the same directory as <filename>book.xml</filename>, and named
+ after the value of the <literal>id</literal> attribute on the
+ file's <tag>chapter</tag> element. Moving them into
+ separate directories prepares for future plans for the Handbook.
+ Specifically, it will soon be possible to include images in each
+ chapter. It makes more sense for each image to be stored in a
+ directory with the text for the chapter than to try to keep the
+ text for all the chapters, and all the images, in one large
+ directory. Namespace collisions would be inevitable, and it is
+ easier to work with several directories with a few files in them
+ than it is to work with one directory that has many files in
+ it.</para>
+
+ <para>A brief look will show that there are many directories with
+ individual <filename>chapter.xml</filename> files, including
+ <filename>basics/chapter.xml</filename>,
+ <filename>introduction/chapter.xml</filename>, and
+ <filename>printing/chapter.xml</filename>.</para>
+
+ <important>
+ <para>Chapters and/or directories should not be named in a fashion
+ that reflects their ordering within the Handbook. This ordering
+ might change as the content within the Handbook is reorganized;
+ this sort of reorganization should not (generally) include the
+ need to rename files (unless entire chapters are being promoted
+ or demoted within the hierarchy).</para>
+ </important>
+
+ <para>Each <filename>chapter.xml</filename> file will not be a
+ complete SGML document. In particular, they will not have their
+ own DOCTYPE lines at the start of the files.</para>
+
+ <para>This is unfortunate as
+ it makes it impossible to treat these as generic SGML
+ files and simply convert them to HTML, RTF, PS, and other
+ formats in the same way the main Handbook is generated. This
+ <emphasis>would</emphasis> force you to rebuild the Handbook
+ every time you want to see the effect a change has had on just
+ one chapter.</para>
+ </sect4>
+ </sect3>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/fdp-primer/stylesheets/chapter.xml b/zh_TW.UTF-8/books/fdp-primer/stylesheets/chapter.xml
new file mode 100644
index 0000000000..b1ef0c7460
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/stylesheets/chapter.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 1998, 1999 Nik Clayton, All rights reserved.
+
+ Redistribution and use in source (SGML DocBook) and 'compiled' forms
+ (SGML HTML, PDF, PostScript, RTF and so forth) with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code (SGML DocBook) must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+ 2. Redistributions in compiled form (transformed to other DTDs,
+ converted to PDF, PostScript, RTF and other formats) must reproduce
+ the above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ $FreeBSD$
+ Original revision: 1.12
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="stylesheets">
+ <title>* Stylesheets</title>
+
+ <para>SGML says nothing about how a document should be displayed to the
+ user, or rendered on paper. To do that, various languages have been
+ developed to describe stylesheets, including DynaText, Panorama, SPICE,
+ JSSS, FOSI, CSS, and DSSSL.</para>
+
+ <para>For DocBook, we are using stylesheets written in DSSSL. For HTML we
+ are using CSS.</para>
+
+ <sect1 xml:id="stylesheets-dsssl">
+ <title>* DSSSL</title>
+
+ <para>The Documentation Project uses a slightly customized version of
+ Norm Walsh's modular DocBook stylesheets.</para>
+
+ <para>These can be found in
+ <package>textproc/dsssl-docbook-modular</package>.</para>
+
+ <para>The modified stylesheets are not in the ports system. Instead they
+ are part of the Documentation Project source repository, and can be
+ found in <filename>doc/share/xml/freebsd.dsl</filename>. It is well
+ commented, and pending completion of this section you are encouraged to
+ examine that file to see how some of the available options in the
+ standard stylesheets have been configured in order to customize the
+ output for the FreeBSD Documentation Project. That file also contains
+ examples showing how to extend the elements that the stylesheet
+ understands, which is how the FreeBSD specific elements have been
+ formatted.</para>
+ </sect1>
+
+ <sect1 xml:id="stylesheets-css">
+ <title>CSS</title>
+
+ <para>Cascading Stylesheets (CSS) are a mechanism for attaching style
+ information (font, weight, size, color, and so forth) to elements in an
+ HTML document without abusing HTML to do so.</para>
+
+ <sect2>
+ <title>The Web site (HTML documents)</title>
+
+ <para>The FreeBSD web site does not currently use CSS. Unfortunately,
+ the look and feel is constructed using abuses of HTML of varying
+ degrees. This should be fixed, and would be a good project for
+ someone looking to contribute to the documentation project.</para>
+ </sect2>
+
+ <sect2>
+ <title>The DocBook documents</title>
+
+ <para>The FreeBSD DSSSL stylesheets include a reference to a stylesheet,
+ <filename>docbook.css</filename>, which is expected to appear in the
+ same directory as the HTML files. The project-wide CSS file is copied
+ from <filename>doc/share/misc/docbook.css</filename> when documents
+ are converted to HTML, and is installed automatically.</para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/fdp-primer/the-website/chapter.xml b/zh_TW.UTF-8/books/fdp-primer/the-website/chapter.xml
new file mode 100644
index 0000000000..8e2a94ad94
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/the-website/chapter.xml
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 1998, 1999 Nik Clayton, All rights reserved.
+
+ Redistribution and use in source (SGML DocBook) and 'compiled' forms
+ (SGML HTML, PDF, PostScript, RTF and so forth) with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code (SGML DocBook) must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+ 2. Redistributions in compiled form (transformed to other DTDs,
+ converted to PDF, PostScript, RTF and other formats) must reproduce
+ the above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ $FreeBSD$
+ Original revision: 1.22
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="the-website">
+ <title>建構 Website</title>
+
+ <sect1 xml:id="the-website-prep">
+ <title>事前準備</title>
+
+ <para>請先準備約 200MB 空間,這些是要用來放 SGML 工具程式、CVS tree、
+ 臨時編譯用的空間,以及編譯好的網頁存放空間。若事先已有裝 SGML 工具程式、
+ CVS tree 的話,那麼只需頂多約 100MB 空間即可。</para>
+
+ <note>
+ <para>請確認一下你的相關文件製作所會用到的 ports 都是最新版!
+ 若不清楚所裝的版本為何,那麼就先以 &man.pkg.delete.1; 指令來移除舊版,
+ 接著才去裝 port。 舉例來說,若已裝的是 jade-1.1,
+ 但是我們目前需要的卻是 jade-1.2,那麼先用下列方式來移除舊版:</para>
+
+ <screen>&prompt.root; <userinput>pkg_delete jade-1.1</userinput></screen>
+ </note>
+
+ <para>接著,就是設定 CVS repository。需要至少 www, doc, ports 這三樣
+ CVS tree(當然還要加上 CVSROOT)。 請參閱
+ <link xlink:href="&url.books.handbook;/synching.html#CVSUP">CVSup 簡介</link>
+ 以瞭解如何來 mirror a CVS tree 或部分 CVS tree。</para>
+
+ <para>最低需求的 cvsup collections 為:<literal>www</literal>,
+ <literal>doc-all</literal>, <literal>cvs-base</literal> 以及
+ <literal>ports-base</literal>。</para>
+
+ <para>剛講的這些需要約 105MB 空間。</para>
+
+ <para>而完整的 CVS tree - 包括 <literal>src</literal>,
+ <literal>doc</literal>, <literal>www</literal> 以及
+ <literal>ports</literal> - 目前約為 940MB。</para>
+ </sect1>
+
+ <sect1 xml:id="the-website-build">
+ <title>Build the web pages from scratch</title>
+
+ <procedure>
+ <step>
+ <para>先建立要編譯的目錄(至少要有 60MB 空間),並切換到該目錄。</para>
+
+ <screen>&prompt.root; <userinput>mkdir /var/tmp/webbuild</userinput>
+&prompt.root; <userinput>cd /var/tmp/webbuild</userinput></screen>
+ </step>
+
+ <step>
+ <para>從 CVS tree 內 checkout 相關的 SGML 檔。</para>
+
+ <screen>&prompt.root; <userinput>cvs -R co www doc</userinput></screen>
+ </step>
+
+ <step>
+ <para>切到 <filename>www/en</filename> 目錄,然後打
+ &man.make.1; <buildtarget>all</buildtarget> 來產生網頁。</para>
+
+ <screen>&prompt.root; <userinput>cd en</userinput>
+&prompt.root; <userinput>make all</userinput></screen>
+ </step>
+ </procedure>
+ </sect1>
+
+ <sect1 xml:id="the-website-install">
+ <title>在你的網頁伺服器上安裝網頁</title>
+
+ <procedure>
+ <step>
+ <para>如果你已經離開 <filename>en</filename>
+ 這個目錄,請切換回這個目錄中。</para>
+
+ <screen>&prompt.root; <userinput>cd path/www/en</userinput></screen>
+ </step>
+
+ <step>
+ <para>執行 &man.make.1; <buildtarget>install</buildtarget> ,
+ 並將 <varname>DESTDIR</varname> 設定為你想安裝檔案的目錄名稱。</para>
+
+ <screen>&prompt.root; <userinput>make DESTDIR=/usr/local/www install</userinput></screen>
+ </step>
+
+ <step>
+ <para>如果你之前已經在相同的目錄中安裝了這些網頁,
+ 安裝過程並不會刪除任何既有或過期的網頁。
+ 舉例來說,如果你每日建構和安裝新的網頁副本,
+ 這個指令將會搜尋並刪除在三天內沒有更新的檔案。</para>
+
+ <screen>&prompt.root; <userinput>find /usr/local/www -ctime 3 -print0 | xargs -0 rm</userinput></screen>
+ </step>
+ </procedure>
+ </sect1>
+
+ <sect1 xml:id="the-website-env">
+ <title>環境變數</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>CVSROOT</envar></term>
+
+ <listitem>
+ <para>設定 CVS tree 的位置,此為必備條件。</para>
+
+ <screen><userinput>&prompt.root; CVSROOT=/home/ncvs; export CVSROOT</userinput></screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>ENGLISH_ONLY</varname></term>
+
+ <listitem>
+ <para>如果設定這個環境變數,而且值不為空白,
+ makefiles 將只會建構和安裝英文文件。
+ 所以將會略過其他的各國翻譯。例如:</para>
+
+ <screen>&prompt.root; <userinput>make ENGLISH_ONLY=YES all install</userinput></screen>
+
+ <para>如果你想要取消變數 <varname>ENGLISH_ONLY</varname>
+ 以及建構所有的頁面並包括翻譯,只要將變數 <varname>ENGLISH_ONLY</varname>
+ 的值設定成空白即可。</para>
+
+ <screen>&prompt.root; <userinput>make ENGLISH_ONLY="" all install clean</userinput></screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>WEB_ONLY</varname></term>
+
+ <listitem>
+ <para>如果有設定這個變數的話,
+ makefiles 將只會從 www 目錄建構及安裝 HTML 頁面。
+ 所有從 doc 目錄下的文件全部都會被忽略 (Handbook, FAQ, Tutorials)。
+ 例如:</para>
+
+ <screen>&prompt.root; <userinput>make WEB_ONLY=YES all install</userinput></screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>NOPORTSCVS</varname></term>
+
+ <listitem>
+ <para>如果設了這個變數,makefiles 就不會從 ports cvs repository
+ 取出檔案。 取而代之會從
+ <filename>/usr/ports</filename> (或是 <envar>PORTSBASE</envar>
+ 所設定的值) 內複製檔案。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para><envar>CVSROOT</envar> 是環境變數。
+ 你必須直接使用指令或是在 dot files (如: ~/.profile) 中
+ 設定這個環境變數。</para>
+
+ <para><varname>WEB_ONLY</varname>、<varname>ENGLISH_ONLY</varname> 及
+ <varname>NOPORTSCVS</varname> 都是 makefile 變數。
+ 你可以在 <filename>/etc/make.conf</filename>、<filename>Makefile.inc</filename>
+ 中設定這些變數,作法就像是用命令列或使用 dot files 來設定環境變數一般。</para>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/fdp-primer/tools/chapter.xml b/zh_TW.UTF-8/books/fdp-primer/tools/chapter.xml
new file mode 100644
index 0000000000..622e98e164
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/tools/chapter.xml
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 1998, 1999 Nik Clayton, All rights reserved.
+
+ Redistribution and use in source (SGML DocBook) and 'compiled' forms
+ (SGML, HTML, PDF, PostScript, RTF and so forth) with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code (SGML DocBook) must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+ 2. Redistributions in compiled form (transformed to other DTDs,
+ converted to PDF, PostScript, RTF and other formats) must reproduce
+ the above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ $FreeBSD$
+ Original revision: 1.32
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="tools">
+ <title>工具</title>
+
+ <para>FDP 使用一堆工具來協助管理 FreeBSD 文件、轉換文件格式等等。
+ 因此,若要進行 FDP 工作的話,必須要學會這些工具才行。</para>
+
+ <para>這些工具都可以用 Ports 或 Packages 來安裝,以節省許多安裝的工夫。</para>
+
+ <para>您必須安裝這些工具,才能使用接下來各章節會介紹到的例子。 這些工具的用法,會在後續相關章節談到。 </para>
+
+ <tip>
+ <title>建議安裝 <package>textproc/docproj</package></title>
+
+ <para>裝了
+ <package>textproc/docproj</package> 可以更省時省力,它是個
+ 組合型的 port(meta-port),本身並非軟體,只是將一些常用工具組合起來而已。
+ 裝了這個 port 之後,『應該』就會自動下載、安裝本章所會介紹到的工具了。
+ 若要處理中文的話,建議再裝 <package>chinese/docproj</package> 會比較好。</para>
+
+ <para>在這些 packages 當中,你可能會需要使用 JadeTeX 這個 macro 設定,
+ 一旦選擇使用該 macro 的話,它會接著去裝 &tex;。由於 &tex; 算是個蠻大的套件,
+ 除非你需要輸出 Postscript 或 PDF 格式,否則就不必裝了。</para>
+
+ <para>所以請考慮是否要節省編譯時間、硬碟空間,以判定要不要裝 JadeTeX (以及 &tex;)
+ 了。若要一併裝起來的話:</para>
+
+ <screen>&prompt.root; <userinput>make JADETEX=yes install</userinput></screen>
+
+ <para>或是,不裝的話:</para>
+
+ <screen>&prompt.root; <userinput>make JADETEX=no install</userinput></screen>
+
+ <para>或者,也可以選擇 <package>textproc/docproj-jadetex</package> 或是 <package>textproc/docproj-nojadetex</package> 這兩個之一來裝,
+ 它們都是已事先設定 <varname>JADETEX</varname> 變數的 slave ports,
+ 都一樣會裝 docproj 差別僅在於有沒有 JadeTeX 而已。
+ 請注意:若只要輸出 HTML 或 ASCII 格式文件,那就不用裝 <application>JadeTeX</application>,
+ 而若要輸出 PostScript、PDF 格式,就需要裝 &tex; 才行。</para>
+ </tip>
+
+ <sect1 xml:id="tools-mandatory">
+ <title>必備工具</title>
+
+ <sect2>
+ <title>軟體</title>
+
+ <para>這些都是在進行 FreeeBSD 文件計劃時所會需要用上的工具程式,
+ 而且可以用來轉換文件為 HTML、plain text以及 RTF 格式。這些相關套件在
+ <package>textproc/docproj</package> 都已經全部收錄了。</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><application>Jade</application>
+ (<package>textproc/jade</package>)</term>
+
+ <listitem>
+ <para>DSSSL 規格的實作程式,可用來把標記語言的文件(marked up)轉換為其他格式,像是:HTML 及 &tex;。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><application>Tidy</application>
+ (<package>www/tidy</package>)</term>
+
+ <listitem>
+ <para>HTML <quote>pretty printer</quote>,可用來把自動產生的 HTML 內容整理得更易閱讀、以便日後維護。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><application>Links</application>
+ (<package>www/links</package>)</term>
+
+ <listitem>
+ <para>文字操作模式的 WWW 瀏覽器(browser)可以把 HTML 檔轉為 plain text 格式。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><application>peps</application>
+ (<package>graphics/peps</package>)</term>
+
+ <listitem>
+ <para>文件中有些圖是存成 EPS 格式的,這些必須要轉為 PNG 格式,
+ 才能讓一般瀏覽器可以正常觀看。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>DTD 及 Entity</title>
+
+ <para>由於 FDP 有用到許多 DTD 跟 Entity,因此在開工前,要裝上這些才行。</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>HTML DTD (<package>textproc/html</package>)</term>
+
+ <listitem>
+ <para>HTML 是用於 WWW 的標記語言,且也是 FreeBSD 網頁所使用的格式。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>DocBook DTD (<package>textproc/docbook</package>)</term>
+
+ <listitem>
+ <para>DocBook 是專門用來製作技術文件的標示語言版本,
+ FreeBSD 全部文件都是以 DocBook 所寫成的。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ISO 8879 entities
+ (<package>textproc/iso8879</package>)</term>
+
+ <listitem>
+ <para>在 ISO 8879:1986 之中有 19 個 entity 被許多 DTD 所大量使用,
+ 包括了數學符號、拉丁字母符號(尖重音等音節符號也是)以及希臘符號。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>樣式表(Stylesheets)</title>
+
+ <para>這些樣式表都是用來轉換、重排文件的螢幕顯示、列印等效果處理</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Modular DocBook 樣式表
+ (<package>textproc/dsssl-docbook-modular</package>)</term>
+
+ <listitem>
+ <para>Modular DocBook 樣式表,是用來把 DocBook 的標記語言文件轉換為其他格式,像是:
+ HTML 或 RTF。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="tools-optional">
+ <title>輔助工具</title>
+
+ <para>不一定得裝下列的工具才行,但是,裝了之後會更容易進行各項工作,
+ 而且可輸出的格式也更具彈性。</para>
+
+ <sect2>
+ <title>軟體</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><application>JadeTeX</application> 及
+ <application>teTeX</application>
+ (<package>print/jadetex</package> 及
+ <package>print/teTeX</package>)</term>
+
+ <listitem>
+ <para><application>Jade</application> 與
+ <application>teTeX</application> 可用來把 DocBook 格式文件轉為
+ DVI, Postscript 及 PDF 格式。安裝時請記得加上
+ <application>JadeTeX</application> 這個 macro,這樣才會順便裝上這兩個套件。</para>
+
+ <para>若無意把文件轉換更多格式的話(舉例:只要 HTML, plain text, RTF 這些格式就夠的話)
+ ,那麼就不用裝
+ <application>JadeTeX</application> 與
+ <application>teTeX</application>。 如此一來可省下一些的編譯時間、安裝空間,
+ 因為 <application>teTeX</application> 大約要至少 30MB 空間。</para>
+
+ <important>
+ <para>若決定要裝
+ <application>JadeTeX</application> 以及
+ <application>teTeX</application> 的話,那麼在裝完 <application>JadeTeX</application> 之後,
+ 要記得設定 <application>teTeX</application> 才行。
+ <filename>print/jadetex/pkg-message</filename> 內有詳細介紹相關步驟。</para>
+ </important>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><application>Emacs</application> 或
+ <application>XEmacs</application>
+ (<package>editors/emacs</package> 或
+ <package>editors/xemacs</package>)</term>
+
+ <listitem>
+ <para>這兩者編輯器都具有處理 SGML DTD 標記文件的特殊模式。
+ 該模式提供一些指令,來簡化所需的打字次數,而且可以減少可能發生的錯誤。</para>
+
+ <para>不過,這些編輯器並不是必備的;任何文字編輯器都可以用來編輯標記語言文件。
+ 不過,你可以透過類似上述這樣的編輯器,來讓這些繁瑣作業更輕鬆有效率些。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>若有推薦其他好用的處理 SGML 文件程式,請來信讓 &a.doceng; 知道,
+ 如此一來,該軟體就會列入這裡介紹了。</para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/fdp-primer/translations/chapter.xml b/zh_TW.UTF-8/books/fdp-primer/translations/chapter.xml
new file mode 100644
index 0000000000..93e331fbe8
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/translations/chapter.xml
@@ -0,0 +1,383 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 1999 Nik Clayton, All rights reserved.
+
+ Redistribution and use in source (SGML DocBook) and 'compiled' forms
+ (SGML HTML, PDF, PostScript, RTF and so forth) with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code (SGML DocBook) must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+ 2. Redistributions in compiled form (transformed to other DTDs,
+ converted to PDF, PostScript, RTF and other formats) must reproduce
+ the above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ $FreeBSD$
+ Original revision: 1.29
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="translations">
+ <title>翻譯時的常見問題</title>
+
+ <para>本章是翻譯 FreeBSD 文件(包含:FAQ, Handbook, tutorials, manual pages等)的常見問題(FAQ)。</para>
+
+ <para>本文件 <emphasis>主要</emphasis> 是以 FreeBSD 德文翻譯計劃的翻譯 FAQ 為母本而來的,
+ 原始撰稿者為 Frank Gr&uuml;nder <email>elwood@mc5sys.in-berlin.de</email> ,並由
+ Bernd Warken <email>bwarken@mayn.de</email> 再翻譯回英文版。</para>
+
+ <para>The FAQ is maintained by the &a.doceng;.</para>
+
+ <qandaset>
+ <qandaentry>
+ <question>
+ <para>FAQ 的目的是?</para>
+ </question>
+
+ <answer>
+ <para>隨著越來越多人參與 freebsd-doc 郵遞論壇,而且希望將 FreeBSD 文件翻譯為各種語言版本。
+ 我們希望這份 FAQ 能儘可能為這些參與翻譯者提供快速的解惑。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para><phrase>i18n</phrase> 跟 <phrase>l10n</phrase> 是什麼呢?</para>
+ </question>
+
+ <answer>
+ <para><phrase>i18n</phrase> 是
+ <phrase>internationalization</phrase> 的簡寫,而 <phrase>l10n</phrase>
+ 則是 <phrase>localization</phrase> 的簡寫。這些都是為了書寫方便而用的簡寫。</para>
+
+ <para><phrase>i18n</phrase> 就是開頭為 <quote>i</quote> 後面有 18 個字母,最後接 <quote>n</quote>。
+ 同理,
+ <phrase>l10n</phrase> 則是開頭為 <quote>l</quote> 後面有 10 個字母,最後接 <quote>n</quote>。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>有專門給譯者參與討論的 mailing list 嗎?</para>
+ </question>
+
+ <answer>
+ <para>有啊,不同的語系翻譯者都各自有自屬的 mailing lists。這份 <link xlink:href="http://www.freebsd.org/docproj/translations.html">翻譯計劃清單</link>
+ 有列出各翻譯計劃的詳細 mailing lists 及相關網站。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>需要更多人一起參與翻譯嗎?</para>
+ </question>
+
+ <answer>
+ <para>當然囉,越多人參與翻譯,那麼就能夠越快翻完,而且英文版文件若有增減、更新的話,
+ 各翻譯版也可以儘快同步囉。</para>
+
+ <para>不一定得是專業譯者,才能參與翻譯的。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>有要求哪些語言能力呢?</para>
+ </question>
+
+ <answer>
+ <para>理論上,必須要對英文非常熟稔,而且很明顯地,對想翻譯的語言必須要能運用自如。</para>
+
+ <para>英文並非一定要會的。比如說,可以把西班牙文(Spanish)的 FAQ 翻譯為匈牙利文(Hungarian)。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>該學會哪些程式的使用呢?</para>
+ </question>
+
+ <answer>
+ <para>強烈建議在自己機器上也建立 FreeBSD CVS repository 的備份(至少文件部分),可以用
+ <application>CTM</application> 或
+ <application>CVSup</application> 都可以。Handbook 中的 "更新、升級 FreeBSD"
+ 一章內有提到如何使用這些程式。</para>
+
+ <para>此外,需要熟悉 <application>CVS</application> 用法。
+ 如此一來,你可以查閱不同版本之間的差異處。</para>
+
+ <para>[XXX To Do(尚未撰稿,仍待補充) -- 寫份上手說明(tutorial)來介紹如何以 CVSup
+ 取得文件部分,以及察看不同版本之間的差異。]</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>要怎麼找出來還有誰要跟我一起翻譯的呢?</para>
+ </question>
+
+ <answer>
+ <para><link xlink:href="http://www.FreeBSD.org/docproj/translations.html">文件計劃的翻譯</link> 這列了目前已知的各翻譯者成果
+ ,如果已經有其他人也在做跟你一樣的翻譯工作,那麼請不要重複浪費人力,
+ 請與他們聯繫看看還有哪些地方可以幫上忙的。</para>
+
+ <para>若上面並未列出你母語的翻譯,或是也有人要翻譯但還未公開宣布的話,那麼就寄信到 &a.doc; 吧。
+ </para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>都沒人翻譯為我所使用的語言,該怎麼辦?</para>
+ </question>
+
+ <answer>
+ <para>恭喜啊,你剛好踏上 <quote>FreeBSD
+ <replaceable>你的母語</replaceable> 文件翻譯計劃</quote> 的啟程之路,歡迎上船。</para>
+
+ <para>首先呢,先判斷是否有妥善規劃時間,因為你只有一個人在翻而已,
+ 因此,相關翻譯成果的公布、與其他可能會幫忙的志工們聯繫這些工作都是你的職責所在。</para>
+
+ <para>寫信到 &a.doc; 向大家宣布你正準備要翻譯,然後文件計劃的翻譯部分就會更新相關資料</para>
+
+ <para>若你的國家已經有人提供 FreeBSD 的 mirror(映設) 服務的話,那麼就先跟他們聯繫,
+ 並詢問你是否在上面可以有網頁空間來放相關計劃資料,
+ 以及是否可以有提供 email 帳號或 mailing list 服務。</para>
+
+ <para>然後,就開始翻文件囉,一開始翻譯的時候,先找些篇幅較短的文件會比較容易些
+ &mdash; 像是 FAQ 啦,或是如何上手之類的說明文章。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>已經翻好一些文件了,該寄到哪呢?</para>
+ </question>
+
+ <answer>
+ <para>這要看情況而定。 若你是在翻譯團隊內做的話(像是日本、德國),
+ 他們會有自己內部流程來決定翻譯文件怎麼送,這些大致流程會在他們網頁上面有寫。</para>
+
+ <para>若你是某語系的唯一翻譯者(或你是負責某翻譯計劃,並想把成果回饋給 FreeBSD 計劃)
+ ,那麼你就應該把自己的翻譯成果寄給 FreeBSD 計劃。(細節請看下個問題)</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>我是該語系的唯一翻譯者,該怎麼把翻譯成果寄出去呢?</para>
+
+ <para>或者</para>
+
+ <para>我們是翻譯團隊,該怎麼把我們成員翻譯成果寄出去呢?</para>
+ </question>
+
+ <answer>
+ <para>首先,請先確定你的翻譯成果組織條理分明,並可正確編譯,也就是說:
+ 把它擺到現有文件架構內是可以正確編譯成功的。</para>
+
+ <para>目前,FreeBSD 文件都是放在最上層的 <filename>doc/</filename> 目錄內。
+ 而該目錄下的則依其語系來做分類命名的,依照 ISO639 定義(<filename>/usr/share/misc/iso639</filename>
+ 的這個 FreeBSD 版本比 1999/01/20 還新)。</para>
+
+ <para>若你這個語系可能會有不同編碼方式(像是:中文)
+ 那麼就應該會像下面這樣,來依你所使用的編碼方式細分。</para>
+
+ <para>最後,你應該建立好各文件的目錄了。</para>
+
+ <para>舉例來說,假設有瑞典文(Swedish)版的翻譯,那麼應該會長像:</para>
+
+ <programlisting>doc/
+ sv_SE.ISO8859-1/
+ Makefile
+ books/
+ faq/
+ Makefile
+ book.xml</programlisting>
+
+ <para><literal>sv_SE.ISO8859-1</literal> 是依照
+ <filename>語系(lang).編碼(encoding)</filename>
+ 的規則來建立的譯名。
+ 請注意:其中有兩個 <filename>Makefiles</filename> 檔,它們是用來編書的。</para>
+
+ <para>然後請用 &man.tar.1; 與 &man.gzip.1; 來把你的翻譯文件壓縮起來,並寄到本計劃來。</para>
+
+ <screen>&prompt.user; <userinput>cd doc</userinput>
+&prompt.user; <userinput>tar cf swedish-docs.tar sv_SE.ISO8859-1</userinput>
+&prompt.user; <userinput>gzip -9 swedish-docs.tar</userinput></screen>
+
+ <para>接著,把 <filename>swedish-docs.tar.gz</filename> 放到網頁空間上,若你沒有自己網頁空間的話(ISP不提供)
+ ,那麼可以該檔寄到 &a.doceng; 來。</para>
+
+ <para>還有,記得用 &man.send-pr.1; 以正式通知大家;你已經寄出翻譯文件了,
+ 還有,若有人可以幫忙檢閱、複審文件的話,對翻譯品質較好,
+ 因為這也有助於提升翻譯品質的流暢度。</para>
+
+ <para>最後,會有人(可能是文件計劃總管,或是 &a.doceng; 成員)
+ 會檢閱你的翻譯文件,並確認是否可正常編譯。此外,他們會特別注意下列幾點:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>你的檔案是否都有用 RCS tag (像是 "ID" 之類的)?</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>sv_SE.ISO8859-1</filename> 是否可以順利 <command>make all</command> 編譯呢?</para>
+ </listitem>
+
+ <listitem>
+ <para><command>make install</command> 是否結果有正確?</para>
+ </listitem>
+ </orderedlist>
+
+ <para>若有問題的話,那麼檢閱者會叮嚀你,來讓這些翻譯成果可以正確使用。</para>
+
+ <para>若沒問題的話,那麼就會很快把你的翻譯成果 commit 進去了。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>可以加入某語系或某國家才有的東西到翻譯內容內嗎?</para>
+ </question>
+
+ <answer>
+ <para>我們希望不要這麼做。</para>
+
+ <para>舉例來說,假設你正準備把 Handbook 翻譯為韓文版,
+ 並希望把韓國零售處也加到你翻譯的 Handbook 韓文版內。</para>
+
+ <para>我們想不出來有啥原因,為什麼不把這些資訊提供給英文版呢?(或是德文、西班牙文、日文等 &hellip;)
+ 因為,有可能英語讀者跑去韓國時,會想買 FreeBSD 相關產品。
+ 此外,這也可以提升 FreeBSD 的可見度,很顯然的,這並不是件壞事啊。</para>
+
+ <para>若你有某國才有的資料,請(用 &man.send-pr.1; )提供給英文版 Handbook 以作為修訂
+ ,然後再把英文版的修訂部分,翻為你要翻譯的 Handbook 吧。</para>
+
+ <para>感恩,謝謝。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>要怎麼把該語系特有的字元寫進去翻譯內容呢?</para>
+ </question>
+
+ <answer>
+ <para>文件內所有的非 ASCII(Non-ASCII) 字元,都要使用 SGML entities 才能寫進去。</para>
+
+ <para>簡單來說,長相一開頭會是 &amp; 符號(&amp;),然後是該 entity 名稱,最後接上分號(;)。</para>
+
+ <para>這些 entity 名稱都是 ISO8879 所制訂的,而 port tree 內則在
+ <package>textproc/iso8879</package>。</para>
+
+ <para>以下舉一些例子:</para>
+
+ <segmentedlist>
+ <segtitle>Entity名稱</segtitle>
+
+ <segtitle>實際樣子</segtitle>
+
+ <segtitle>介紹</segtitle>
+
+ <seglistitem>
+ <seg>&amp;eacute;</seg>
+ <seg>&eacute;</seg>
+ <seg>小 <quote>e</quote>,並帶尖、重音(acute accent)</seg>
+ </seglistitem>
+
+ <seglistitem>
+ <seg>&amp;Eacute;</seg>
+ <seg>&Eacute;</seg>
+ <seg>大 <quote>E</quote>,並帶尖、重音(acute accent)</seg>
+ </seglistitem>
+
+ <seglistitem>
+ <seg>&amp;uuml;</seg>
+ <seg>&uuml;</seg>
+ <seg>小 <quote>u</quote>,並帶日耳曼語系中的母音變化(umlaut)</seg>
+ </seglistitem>
+ </segmentedlist>
+
+ <para>在裝了 iso8879 這個 port 之後,就可以在
+ <filename>/usr/local/share/xml/iso8879</filename> 找到這些的詳細列表。</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>如何稱呼讀者呢?</para>
+ </question>
+
+ <answer>
+ <para>在英文文件內,讀者都是以 <quote>you</quote> 來稱呼,而有些語言並沒有正式/非正式的區隔。</para>
+
+ <para>若你所要翻的語言可以區別這些差異,那麼請用該語系在一般技術文件上所使用的稱呼吧。
+ 如果容易造成困惑的話,那麼請改用較中性的稱呼來取代。</para>
+
+ <!--
+ 摘自 http://fatpipi.cirx.org/~vanilla/rules.txt
+ 如非必要,翻譯文章內盡量少用直接稱呼你我他的用字。
+ 如果真的得用,就採用第三人稱(用【他】而非【你】),還有就是用複數(用【你們】而非【你】),
+ 當然這還是得配合原文的上下語意。如果他是寫 "I" 而翻譯成 "我",則無可厚非。
+
+ 但是對於文內絕大多數的"You..... you ...etc"
+ 其實都可以把【你】簡化或是避免掉,這對閱讀時候的順暢感應該有幫助。
+ -->
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>翻譯成果內要不要附上一些其他訊息呢?</para>
+ </question>
+
+ <answer>
+ <para>當然要。</para>
+
+ <para>每份英文版原稿的開頭,通常會有像下面的內容:</para>
+
+ <programlisting>&lt;!--
+ The FreeBSD Documentation Project
+
+ &dollar;FreeBSD: doc/en_US.ISO8859-1/books/fdp-primer/translations/chapter.xml,v 1.5 2000/07/07 18:38:38 dannyboy Exp &dollar;
+--&gt;</programlisting>
+
+ <para>實際上的內容可能稍有不同,但每份原稿都會附上 &dollar;FreeBSD&dollar; 這一行以及
+ <literal>The FreeBSD Documentation Project</literal> 宣告。
+ 請注意:&dollar;FreeBSD 開頭的這行是會由 CVS 隨著每次異動而自動更改的,
+ 所以,新檔案的話請保持原狀(也就是只要寫 <literal>&dollar;FreeBSD&dollar;</literal> 就好了)。</para>
+
+ <para>翻譯文件中,必須都要有 &dollar;FreeBSD&dollar; 這行,並且把
+ <literal>FreeBSD Documentation Project</literal> 這行改為
+ <literal>The FreeBSD 你的語系
+ Documentation Project</literal>。</para>
+
+ <para>此外,還必須加上第三行來指出你所翻譯的,到底是以英文版原稿的哪一版本為母本所做的翻譯。</para>
+
+ <para>因此呢,西班牙文版(Spanish)的檔案開頭應該是長像這樣:</para>
+
+ <programlisting>&lt;!--
+ The FreeBSD Spanish Documentation Project
+
+ &dollar;FreeBSD: doc/es_ES.ISO8859-1/books/fdp-primer/translations/chapter.xml,v 1.3 1999/06/24 19:12:32 jesusr Exp &dollar;
+ Original revision: 1.11
+--&gt;</programlisting>
+ </answer>
+ </qandaentry>
+ </qandaset>
+</chapter>
diff --git a/zh_TW.UTF-8/books/fdp-primer/writing-style/chapter.xml b/zh_TW.UTF-8/books/fdp-primer/writing-style/chapter.xml
new file mode 100644
index 0000000000..158d232029
--- /dev/null
+++ b/zh_TW.UTF-8/books/fdp-primer/writing-style/chapter.xml
@@ -0,0 +1,440 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 1998 Nik Clayton, All rights reserved.
+
+ Redistribution and use in source (SGML DocBook) and 'compiled' forms
+ (SGML HTML, PDF, PostScript, RTF and so forth) with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code (SGML DocBook) must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer as the first lines of this file unmodified.
+
+ 2. Redistributions in compiled form (transformed to other DTDs,
+ converted to PDF, PostScript, RTF and other formats) must reproduce
+ the above copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+ $FreeBSD$
+ Original revision: 1.48
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="writing-style">
+ <title>文件的撰寫風格</title>
+
+ <para>由於 FreeBSD 文件是由眾多作者所維護的,為了保持寫作風格的一貫性,
+ 於是就產生較有共識的寫作規則,請各位記得要遵守。</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>使用美式英語</term>
+
+ <listitem>
+ <para>同一個字在不同種類的英語會有著不同的拼法。
+ 遇到拼字不同的情況,請採用美式英語拼法。 像是:
+ 請改用 <quote>color</quote>,而非 <quote>colour</quote>。
+ 請改用 <quote>rationalize</quote>,而非 <quote>rationalise</quote>
+ 等等類似字彙。</para>
+
+ <note>
+ <para>若文章採用英式英語也可以接受,但必須全篇文章都採用同一拼法才行
+ 。 而文件的其他部份,像是書、網頁、 manual
+ 說明等則必須採用美式英語。</para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>不要用簡寫</term>
+
+ <listitem>
+ <para>請不要簡寫(contraction)。 請務必將完整的字寫出來。 比如:
+ <quote>Don't use contractions</quote> 這句有用到簡寫,就要避免。</para>
+
+ <para>正式書面寫法避免簡寫的原因,乃是因為如此一來字句意思較精準,
+ 且對譯者會比較輕鬆些。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>正確使用 serial comma 以及頓號</term>
+
+ <listitem>
+ <para>英文段落通常會逗號(,)作為該句所提到的各項目的語氣區隔。
+ 並且會在最後一個提到的項目時,先加上逗號再接上 <quote>and</quote>,
+ 最後才是最後的項目。</para>
+
+ <para>舉個例子,看看下面這句:</para>
+
+ <blockquote>
+ <para>This is a list of one, two and three items.</para>
+ </blockquote>
+
+ <para>那麼這一句到底是有三個項目(<quote>one</quote>、<quote>two</quote>
+ 、<quote>three</quote>)呢?或者是只有兩個項目(<quote>one</quote>、
+ <quote>two and three</quote>)呢?</para>
+
+ <para>因此較妥的方式是以 serial comma 的方式,才能正確表達語意:</para>
+
+ <blockquote>
+ <para>This is a list of one, two, and three items.</para>
+ </blockquote>
+
+ <para>然而,在翻譯過程中,建議把逗號(,)部份改為頓號(、),並且
+ <quote>and</quote> 的部份可略而不翻,以免語意頓塞。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>避免使用贅詞</term>
+
+ <listitem>
+ <para>請試著避免使用贅詞(redundant phrase)。 尤其是
+ <quote>這個指令</quote>、<quote>這個檔案</quote>、<quote>man
+ 指令</quote> 這幾個通常都是不必要的贅詞。</para>
+
+ <para>以指令(command)方面舉例,比較妥當的用法是第二句的例子:</para>
+
+ <informalexample>
+ <para>使用 <command>cvsup</command> 指令來更新原始碼。</para>
+ </informalexample>
+
+ <informalexample>
+ <para>使用 <command>cvsup</command> 來更新原始碼。</para>
+ </informalexample>
+
+ <para>以檔案(filename)方面舉例,比較妥當的用法是第二句的例子:</para>
+
+ <informalexample>
+ <para>&hellip; 在這個
+ <filename>/etc/rc.local</filename> 檔案 &hellip;</para>
+ </informalexample>
+
+ <informalexample>
+ <para>&hellip; 在
+ <filename>/etc/rc.local</filename> 檔 &hellip;</para>
+ </informalexample>
+
+ <para>以 man(manual)方面舉例,比較妥當的用法是第二句(有用到 SGML
+ <tag>citerefentry</tag> 標籤):</para>
+
+ <informalexample>
+ <para>請打 <command>man csh</command> 指令以參閱詳情說明。</para>
+ </informalexample>
+
+ <informalexample>
+ <para>詳情請參閱 &man.csh.1;。</para>
+ </informalexample>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>每句後面加上兩個空白</term>
+
+ <listitem>
+ <para>為了使文章更易閱讀,以及讓 <application>Emacs</application>
+ 之類的工具容易運用,請在每一完整句子後面加上兩個空白。</para>
+
+ <para>不過,句號(.)後面有接大寫字母,
+ 並不一定表示前一個句點所在處就是完整句子,
+ 尤其是名字部份常常會有這現象。 像是 <quote>Jordan K. Hubbard</quote>
+ 這人名就是很好的例證:句號後面接空白,然後是大寫的
+ <literal>H</literal>,然而這肯定並不是兩段句子。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>撰寫風格的相關細節,可參閱 William Strunk 所寫的 <link xlink:href="http://www.bartleby.com/141/">Elements of Style</link>。</para>
+
+ <sect1 xml:id="writing-style-guide">
+ <title>Style guide</title>
+
+ <para>由於 Handbook 是由眾多作者所維護,為了保持寫作風格的一貫性,
+ 請遵守下列撰寫風格。</para>
+
+ <sect2>
+ <title>大小寫</title>
+
+ <para>Tag 的部份都是用小寫字母,譬如是用 <literal>&lt;para&gt;</literal>
+ ,<emphasis>而非</emphasis> <literal>&lt;PARA&gt;</literal>。</para>
+
+ <para>而 SGML 內文則是用大寫字母表示,像是:
+ <literal>&lt;!ENTITY&hellip;&gt;</literal> 及
+ <literal>&lt;!DOCTYPE&hellip;&gt;</literal>,
+ <emphasis>而不是</emphasis>
+ <literal>&lt;!entity&hellip;&gt;</literal> 及
+ <literal>&lt;!doctype&hellip;&gt;</literal>。</para>
+ </sect2>
+
+ <sect2>
+ <title>縮寫字</title>
+
+ <para>縮寫字(acronym)通常在書中第一次提到時,必須同時列出完整拼法,
+ 比如:"Network Time Protocol (<acronym role="Network Time Protocol">NTP</acronym>)"。
+ 定義縮寫字之後,應該儘量只使用該縮寫字(而非完整詞彙,
+ 除非使用完整詞彙可以更能表達語意)來表達即可。
+ 通常每本書只會第一次提到時,才會列出完整詞彙,
+ 但若您高興也可以在每章第一次提到時又列出完整詞彙。</para>
+
+ <para>此外,同一縮寫字在前三次使用時,須使用 &lt;acronym&gt; 標籤,
+ 並把完整詞彙附在 <literal>role</literal> 屬性內做說明。
+ 如此一來就會建立詞彙表,並且當滑鼠移至該縮寫字上方時,
+ 就會顯示完整詞彙。</para>
+ </sect2>
+
+ <sect2>
+ <title>縮排</title>
+
+ <para><emphasis>無論</emphasis> 檔案縮排設定為何,
+ 每個檔案一開始的縮排(indentation)都是從 0 縱列開始</para>
+
+ <para>未完的標籤會以多兩個空白來增加縮排,
+ 結尾的標籤則少兩個空白來縮減縮排。 若已達 8 個空白,則以 tab 取代之。
+ 此外,在 tab 前面不要再用空白,也不要在每行後面加上空白。
+ 每個 tag 的內文若超過一行的話,則接下來的就多兩個空白以做縮排。</para>
+
+ <para>舉個例子,這節所用的寫法大致是下面這樣:</para>
+
+ <programlisting><![CDATA[+--- 這是 0 縱列
+V
+<chapter>
+ <title>...</title>
+
+ <sect1>
+ <title>...</title>
+
+ <sect2>
+ <title>縮排</title>
+
+ <para><emphasis>無論</emphasis> 檔案縮排設定為何,
+ 每個檔案一開始的縮排(indentation)都是從 0 縱列開始。</para>
+
+ ...
+ </sect2>
+ </sect1>
+</chapter>]]></programlisting>
+
+ <para>若用 <application>Emacs</application> 或
+ <application>XEmacs</application> 來編輯這檔,那麼會自動進入
+ <literal>sgml-mode</literal> 模式,
+ 然後就會強制使用每個檔案最下方的環境設定。</para>
+
+ <para><application>Vim</application> 愛用者也可以用下列設定來調整:</para>
+
+ <programlisting>augroup sgmledit
+ autocmd FileType sgml set formatoptions=cq2l " 特殊格式選項
+ autocmd FileType sgml set textwidth=70 " 在 70 縱列處即自動換行
+ autocmd FileType sgml set shiftwidth=2 " 自動縮排 2 個空白
+ autocmd FileType sgml set softtabstop=2 " 按 Tab 會自動轉為兩個空白縮排
+ autocmd FileType sgml set tabstop=8 " 把 8 個空白轉為 tab
+ autocmd FileType sgml set autoindent " 自動縮排
+augroup END</programlisting>
+
+ </sect2>
+
+ <sect2>
+ <title>Tag 風格</title>
+
+ <sect3>
+ <title>Tag 空行</title>
+
+ <para>同一縮排等級的標籤要以空一行來做區隔,而不同縮排等級的則不必。
+ 比如:</para>
+
+ <informalexample>
+ <programlisting><![CDATA[<article lang='zh_tw'>
+ <articleinfo>
+ <title>NIS</title>
+
+ <pubdate>October 1999</pubdate>
+
+ <abstract>
+ <para>...
+ ...
+ ...</para>
+ </abstract>
+ </articleinfo>
+
+ <sect1>
+ <title>...</title>
+
+ <para>...</para>
+ </sect1>
+
+ <sect1>
+ <title>...</title>
+
+ <para>...</para>
+ </sect1>
+</article>]]></programlisting>
+ </informalexample>
+ </sect3>
+
+ <sect3>
+ <title>標籤的分行</title>
+
+ <para>像是 <tag>itemizedlist</tag>
+ 這類的標籤事實上本身不含任何文字資料,必須得由其他標籤來補充內文。
+ 這類的標籤會獨用一整行。</para>
+
+ <para>另外,像是 <tag>para</tag> 及
+ <tag>term</tag> 這類的標籤並不需搭配其他標籤,
+ 就可附上文字資料,並且在標籤後面的<emphasis>同一行</emphasis>
+ 內即可立即寫上這些內文。</para>
+
+ <para>當然,這兩類的標籤結尾時也是跟上面道理相同。</para>
+
+ <para>不過,當上述這兩種標籤混用時,會有很明顯的困擾。</para>
+
+ <para>當第一類標籤的後面接上第二類標籤的話,
+ 那麼要把這兩類標籤各自分行來寫。 後者標籤的段落,
+ 也是需要做適當縮排調整。</para>
+
+ <para>而第二類標籤結尾時,可以與第一類標籤的結尾放在同一行。</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>空白的更改</title>
+
+ <para>在 commit 修改時,<emphasis>請別在修改內容的同時,
+ 也一起更改編排格式</emphasis>。</para>
+
+ <para>如此一來,像是 Handbook 翻譯團隊才能迅速找出你改了哪些內容,
+ 而不用費心思去判斷該行的改變,是由於格式重排或者內容異動。</para>
+
+ <para>舉例說明,若要在某段加上兩個句子,如此一來該段落的某行勢必會超出 80
+ 縱列,這時請先 commmit 修改。 接著,再修飾過長行落的換行,然後再次
+ commit 之。 而第二次的 commit 紀錄,請明確說明這只是 whitespace-only
+ (修改空白而已) 的更改,如此一來,翻譯團隊就可以忽略第二次 commit 了
+ 。</para>
+ </sect2>
+
+ <sect2>
+ <title>Nonbreaking space</title>
+
+ <para>請避免一些情況下的斷行:造成版面醜醜的、或是須連貫表達的同一句子。
+ 斷行的情況會隨所閱讀的工具不同而有所不同。 尤其是透過純文字瀏覽器來看
+ HTML 時會更明顯看到類似下面這樣不好的編排段落:</para>
+
+ <literallayout class="monospaced">Data capacity ranges from 40 MB to 15
+GB. Hardware compression &hellip;</literallayout>
+
+ <para>請使用 <literal>&amp;nbsp;</literal> 以避免同句子之間的斷行,
+ 以下示範如何使用 nonbreaking spaces:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>在數字與單位之間:</para>
+ <programlisting><![CDATA[57600&nbsp;bps]]></programlisting>
+ </listitem>
+
+ <listitem>
+ <para>在程式名稱與版號之間:</para>
+ <programlisting><![CDATA[FreeBSD&nbsp;4.7]]></programlisting>
+ </listitem>
+
+ <listitem>
+ <para>multiword 之間 (使用時請小心,像是 <quote>The FreeBSD Brazilian
+ Portuguese Documentation Project</quote> 這類由三到四個字所組成的,
+ 則不用加。):</para>
+ <programlisting><![CDATA[Sun&nbsp;Microsystems]]></programlisting>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="writing-style-word-list">
+ <title>詞彙表</title>
+
+ <para>以下為 FreeBSD 文件計劃編排時所採用的小型詞彙表。
+ 若找不到要找的詞彙,請參閱 <link xlink:href="http://www.oreilly.com/oreilly/author/stylesheet.html">O'Reilly
+ word list</link>。</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>2.2.X</para>
+ </listitem>
+
+ <listitem>
+ <para>4.X-STABLE</para>
+ </listitem>
+
+ <listitem>
+ <para>CD-ROM</para>
+ </listitem>
+
+ <listitem>
+ <para>DoS <emphasis>(Denial of Service)</emphasis> </para>
+ </listitem>
+
+ <listitem>
+ <para>Ports Collection</para>
+ </listitem>
+
+ <listitem>
+ <para>IPsec</para>
+ </listitem>
+
+ <listitem>
+ <para>Internet</para>
+ </listitem>
+
+ <listitem>
+ <para>MHz</para>
+ </listitem>
+
+ <listitem>
+ <para>Soft Updates</para>
+ </listitem>
+
+ <listitem>
+ <para>Unix</para>
+ </listitem>
+
+ <listitem>
+ <para>disk label</para>
+ </listitem>
+
+ <listitem>
+ <para>email</para>
+ </listitem>
+
+ <listitem>
+ <para>file system</para>
+ </listitem>
+
+ <listitem>
+ <para>manual page</para>
+ </listitem>
+
+ <listitem>
+ <para>mail server</para>
+ </listitem>
+
+ <listitem>
+ <para>name server</para>
+ </listitem>
+
+ <listitem>
+ <para>null-modem</para>
+ </listitem>
+
+ <listitem>
+ <para>web server</para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/Makefile b/zh_TW.UTF-8/books/handbook/Makefile
new file mode 100644
index 0000000000..6dee2d0433
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/Makefile
@@ -0,0 +1,269 @@
+#
+# $FreeBSD$
+# Original revision: 1.108
+#
+# Build the FreeBSD Handbook.
+#
+
+.PATH: ${.CURDIR}/../../share/xml/glossary
+
+MAINTAINER= doc@FreeBSD.org
+
+DOC?= book
+
+FORMATS?= html-split
+
+INSTALL_COMPRESSED?= gz
+INSTALL_ONLY_COMPRESSED?=
+
+IMAGES_EN = advanced-networking/isdn-bus.eps
+IMAGES_EN+= advanced-networking/isdn-twisted-pair.eps
+IMAGES_EN+= advanced-networking/natd.eps
+IMAGES_EN+= advanced-networking/net-routing.pic
+IMAGES_EN+= advanced-networking/static-routes.pic
+IMAGES_EN+= geom/striping.pic
+IMAGES_EN+= install/adduser1.scr
+IMAGES_EN+= install/adduser2.scr
+IMAGES_EN+= install/adduser3.scr
+IMAGES_EN+= install/boot-loader-menu.scr
+IMAGES_EN+= install/boot-mgr.scr
+IMAGES_EN+= install/config-country.scr
+IMAGES_EN+= install/console-saver1.scr
+IMAGES_EN+= install/console-saver2.scr
+IMAGES_EN+= install/console-saver3.scr
+IMAGES_EN+= install/console-saver4.scr
+IMAGES_EN+= install/disklabel-auto.scr
+IMAGES_EN+= install/disklabel-ed1.scr
+IMAGES_EN+= install/disklabel-ed2.scr
+IMAGES_EN+= install/disklabel-fs.scr
+IMAGES_EN+= install/disklabel-root1.scr
+IMAGES_EN+= install/disklabel-root2.scr
+IMAGES_EN+= install/disklabel-root3.scr
+IMAGES_EN+= install/disk-layout.eps
+IMAGES_EN+= install/dist-set.scr
+IMAGES_EN+= install/dist-set2.scr
+IMAGES_EN+= install/docmenu1.scr
+IMAGES_EN+= install/ed0-conf.scr
+IMAGES_EN+= install/ed0-conf2.scr
+IMAGES_EN+= install/edit-inetd-conf.scr
+IMAGES_EN+= install/fdisk-drive1.scr
+IMAGES_EN+= install/fdisk-drive2.scr
+IMAGES_EN+= install/fdisk-edit1.scr
+IMAGES_EN+= install/fdisk-edit2.scr
+IMAGES_EN+= install/ftp-anon1.scr
+IMAGES_EN+= install/ftp-anon2.scr
+IMAGES_EN+= install/hdwrconf.scr
+IMAGES_EN+= install/keymap.scr
+IMAGES_EN+= install/main1.scr
+IMAGES_EN+= install/mainexit.scr
+IMAGES_EN+= install/main-std.scr
+IMAGES_EN+= install/main-options.scr
+IMAGES_EN+= install/main-doc.scr
+IMAGES_EN+= install/main-keymap.scr
+IMAGES_EN+= install/media.scr
+IMAGES_EN+= install/mouse1.scr
+IMAGES_EN+= install/mouse2.scr
+IMAGES_EN+= install/mouse3.scr
+IMAGES_EN+= install/mouse4.scr
+IMAGES_EN+= install/mouse5.scr
+IMAGES_EN+= install/mouse6.scr
+IMAGES_EN+= install/mta-main.scr
+IMAGES_EN+= install/net-config-menu1.scr
+IMAGES_EN+= install/net-config-menu2.scr
+IMAGES_EN+= install/nfs-server-edit.scr
+IMAGES_EN+= install/ntp-config.scr
+IMAGES_EN+= install/options.scr
+IMAGES_EN+= install/pkg-cat.scr
+IMAGES_EN+= install/pkg-confirm.scr
+IMAGES_EN+= install/pkg-install.scr
+IMAGES_EN+= install/pkg-sel.scr
+IMAGES_EN+= install/probstart.scr
+IMAGES_EN+= install/routed.scr
+IMAGES_EN+= install/security.scr
+IMAGES_EN+= install/sysinstall-exit.scr
+IMAGES_EN+= install/timezone1.scr
+IMAGES_EN+= install/timezone2.scr
+IMAGES_EN+= install/timezone3.scr
+IMAGES_EN+= install/userconfig.scr
+IMAGES_EN+= install/userconfig2.scr
+IMAGES_EN+= mail/mutt1.scr
+IMAGES_EN+= mail/mutt2.scr
+IMAGES_EN+= mail/mutt3.scr
+IMAGES_EN+= mail/pine1.scr
+IMAGES_EN+= mail/pine2.scr
+IMAGES_EN+= mail/pine3.scr
+IMAGES_EN+= mail/pine4.scr
+IMAGES_EN+= mail/pine5.scr
+
+IMAGES_EN+= install/example-dir1.eps
+IMAGES_EN+= install/example-dir2.eps
+IMAGES_EN+= install/example-dir3.eps
+IMAGES_EN+= install/example-dir4.eps
+IMAGES_EN+= install/example-dir5.eps
+IMAGES_EN+= security/ipsec-network.pic
+IMAGES_EN+= security/ipsec-crypt-pkt.pic
+IMAGES_EN+= security/ipsec-encap-pkt.pic
+IMAGES_EN+= security/ipsec-out-pkt.pic
+IMAGES_EN+= vinum/vinum-concat.pic
+IMAGES_EN+= vinum/vinum-mirrored-vol.pic
+IMAGES_EN+= vinum/vinum-raid10-vol.pic
+IMAGES_EN+= vinum/vinum-raid5-org.pic
+IMAGES_EN+= vinum/vinum-simple-vol.pic
+IMAGES_EN+= vinum/vinum-striped-vol.pic
+IMAGES_EN+= vinum/vinum-striped.pic
+IMAGES_EN+= virtualization/parallels-freebsd1.png
+IMAGES_EN+= virtualization/parallels-freebsd2.png
+IMAGES_EN+= virtualization/parallels-freebsd3.png
+IMAGES_EN+= virtualization/parallels-freebsd4.png
+IMAGES_EN+= virtualization/parallels-freebsd5.png
+IMAGES_EN+= virtualization/parallels-freebsd6.png
+IMAGES_EN+= virtualization/parallels-freebsd7.png
+IMAGES_EN+= virtualization/parallels-freebsd8.png
+IMAGES_EN+= virtualization/parallels-freebsd9.png
+IMAGES_EN+= virtualization/parallels-freebsd10.png
+IMAGES_EN+= virtualization/parallels-freebsd11.png
+IMAGES_EN+= virtualization/parallels-freebsd12.png
+IMAGES_EN+= virtualization/parallels-freebsd13.png
+IMAGES_EN+= virtualization/virtualpc-freebsd1.png
+IMAGES_EN+= virtualization/virtualpc-freebsd2.png
+IMAGES_EN+= virtualization/virtualpc-freebsd3.png
+IMAGES_EN+= virtualization/virtualpc-freebsd4.png
+IMAGES_EN+= virtualization/virtualpc-freebsd5.png
+IMAGES_EN+= virtualization/virtualpc-freebsd6.png
+IMAGES_EN+= virtualization/virtualpc-freebsd7.png
+IMAGES_EN+= virtualization/virtualpc-freebsd8.png
+IMAGES_EN+= virtualization/virtualpc-freebsd9.png
+IMAGES_EN+= virtualization/virtualpc-freebsd10.png
+IMAGES_EN+= virtualization/virtualpc-freebsd11.png
+IMAGES_EN+= virtualization/virtualpc-freebsd12.png
+IMAGES_EN+= virtualization/virtualpc-freebsd13.png
+IMAGES_EN+= virtualization/vmware-freebsd01.png
+IMAGES_EN+= virtualization/vmware-freebsd02.png
+IMAGES_EN+= virtualization/vmware-freebsd03.png
+IMAGES_EN+= virtualization/vmware-freebsd04.png
+IMAGES_EN+= virtualization/vmware-freebsd05.png
+IMAGES_EN+= virtualization/vmware-freebsd06.png
+IMAGES_EN+= virtualization/vmware-freebsd07.png
+IMAGES_EN+= virtualization/vmware-freebsd08.png
+IMAGES_EN+= virtualization/vmware-freebsd09.png
+IMAGES_EN+= virtualization/vmware-freebsd10.png
+IMAGES_EN+= virtualization/vmware-freebsd11.png
+IMAGES_EN+= virtualization/vmware-freebsd12.png
+
+# Images from the cross-document image library
+IMAGES_LIB= callouts/1.png
+IMAGES_LIB+= callouts/2.png
+IMAGES_LIB+= callouts/3.png
+IMAGES_LIB+= callouts/4.png
+IMAGES_LIB+= callouts/5.png
+IMAGES_LIB+= callouts/6.png
+IMAGES_LIB+= callouts/7.png
+IMAGES_LIB+= callouts/8.png
+IMAGES_LIB+= callouts/9.png
+IMAGES_LIB+= callouts/10.png
+IMAGES_LIB+= callouts/11.png
+IMAGES_LIB+= callouts/12.png
+IMAGES_LIB+= callouts/13.png
+IMAGES_LIB+= callouts/14.png
+IMAGES_LIB+= callouts/15.png
+
+#
+# SRCS lists the individual XML files that make up the document. Changes
+# to any of these files will force a rebuild
+#
+
+# XML content
+SRCS+= audit/chapter.xml
+SRCS+= book.xml
+SRCS+= colophon.xml
+SRCS+= advanced-networking/chapter.xml
+SRCS+= basics/chapter.xml
+SRCS+= bibliography/chapter.xml
+SRCS+= boot/chapter.xml
+SRCS+= config/chapter.xml
+SRCS+= cutting-edge/chapter.xml
+SRCS+= desktop/chapter.xml
+SRCS+= disks/chapter.xml
+SRCS+= eresources/chapter.xml
+SRCS+= firewalls/chapter.xml
+SRCS+= geom/chapter.xml
+SRCS+= install/chapter.xml
+SRCS+= introduction/chapter.xml
+SRCS+= jails/chapter.xml
+SRCS+= kernelconfig/chapter.xml
+SRCS+= l10n/chapter.xml
+SRCS+= linuxemu/chapter.xml
+SRCS+= mac/chapter.xml
+SRCS+= mail/chapter.xml
+SRCS+= mirrors/chapter.xml
+SRCS+= multimedia/chapter.xml
+SRCS+= network-servers/chapter.xml
+SRCS+= pgpkeys/chapter.xml
+SRCS+= ports/chapter.xml
+SRCS+= ppp-and-slip/chapter.xml
+SRCS+= preface/preface.xml
+SRCS+= printing/chapter.xml
+SRCS+= security/chapter.xml
+SRCS+= serialcomms/chapter.xml
+SRCS+= users/chapter.xml
+SRCS+= vinum/chapter.xml
+SRCS+= virtualization/chapter.xml
+SRCS+= x11/chapter.xml
+
+# Entities
+SRCS+= chapters.ent
+
+SYMLINKS= ${DESTDIR} index.html handbook.html
+
+# Turn on all the chapters.
+CHAPTERS?= ${SRCS:M*chapter.xml}
+
+XMLFLAGS+= ${CHAPTERS:S/\/chapter.xml//:S/^/-i chap./}
+XMLFLAGS+= -i chap.freebsd-glossary
+
+URL_RELPREFIX?= ../../../..
+DOC_PREFIX?= ${.CURDIR}/../../..
+
+#
+# rules generating lists of mirror site from XML database.
+#
+XMLDOCS= lastmod:::mirrors.lastmod.inc \
+ mirrors-ftp-index:::mirrors.xml.ftp.index.inc \
+ mirrors-ftp:::mirrors.xml.ftp.inc \
+ mirrors-cvsup-index:::mirrors.xml.cvsup.index.inc \
+ mirrors-cvsup:::mirrors.xml.cvsup.inc \
+ eresources-index:::eresources.xml.www.index.inc \
+ eresources:::eresources.xml.www.inc
+DEPENDSET.DEFAULT= transtable mirror
+XSLT.DEFAULT= ${XSL_MIRRORS}
+XML.DEFAULT= ${XML_MIRRORS}
+
+PARAMS.lastmod+= --param 'target' "'lastmod'"
+PARAMS.mirrors-ftp-index+= --param 'type' "'ftp'" \
+ --param 'proto' "'ftp'" \
+ --param 'target' "'index'"
+PARAMS.mirrors-ftp+= --param 'type' "'ftp'" \
+ --param 'proto' "'ftp'" \
+ --param 'target' "'handbook/mirrors/chapter.xml'"
+PARAMS.mirrors-cvsup-index+= --param 'type' "'cvsup'" \
+ --param 'proto' "'cvsup'" \
+ --param 'target' "'index'"
+PARAMS.mirrors-cvsup+= --param 'type' "'cvsup'" \
+ --param 'proto' "'cvsup'" \
+ --param 'target' "'handbook/mirrors/chapter.xml'"
+PARAMS.eresources-index+= --param 'type' "'www'" \
+ --param 'proto' "'http'" \
+ --param 'target' "'index'"
+PARAMS.eresources+= --param 'type' "'www'" \
+ --param 'proto' "'http'" \
+ --param 'target' "'handbook/eresources/chapter.xml'"
+
+SRCS+= mirrors.lastmod.inc \
+ mirrors.xml.ftp.inc \
+ mirrors.xml.ftp.index.inc \
+ mirrors.xml.cvsup.inc \
+ mirrors.xml.cvsup.index.inc \
+ eresources.xml.www.inc \
+ eresources.xml.www.index.inc
+
+.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/books/handbook/advanced-networking/Makefile b/zh_TW.UTF-8/books/handbook/advanced-networking/Makefile
new file mode 100644
index 0000000000..6bce63bf94
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/advanced-networking/Makefile
@@ -0,0 +1,16 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+# Original revision: 1.2
+#
+
+CHAPTERS= advanced-networking/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/advanced-networking/chapter.xml b/zh_TW.UTF-8/books/handbook/advanced-networking/chapter.xml
new file mode 100644
index 0000000000..4773be660f
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/advanced-networking/chapter.xml
@@ -0,0 +1,5438 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.402
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="advanced-networking">
+ <title>網路進階練功房</title>
+
+ <sect1 xml:id="advanced-networking-synopsis">
+ <title>概述</title>
+
+ <para>本章將介紹一些進階的網路設定主題。</para>
+
+ <para>讀完這章,您將了解:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>gateway(閘道)及 route(路由)的概念。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何設定 IEEE 802.11 以及藍芽(&bluetooth;)設備。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何以 FreeBSD 作為 bridge(橋接)。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何為無碟系統設定網路開機。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何設定 NAT(Network Address Translation)。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何透過 PLIP 方式來連接兩台電腦。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何在 FreeBSD 內設定 IPv6。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何設定 ATM。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何去善用 &os; 的 CARP(Common Access Redundancy Protocol)功能
+ 。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>在開始閱讀這章之前,您需要︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>瞭解 <filename>/etc/rc</filename> 相關 script 的概念。</para>
+ </listitem>
+
+ <listitem>
+ <para>熟悉基本常用的網路術語。</para>
+ </listitem>
+
+ <listitem>
+ <para>知道如何設定、安裝新的 FreeBSD kernel (<xref linkend="kernelconfig"/>)。</para>
+ </listitem>
+
+ <listitem>
+ <para>知道如何透過 port/package 安裝軟體 (<xref linkend="ports"/>)
+ 。</para>
+ </listitem>
+
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="network-routing">
+ <info><title>Gateways and Routes</title>
+ <authorgroup>
+ <author><personname><firstname>Coranth</firstname><surname>Gryphon</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>routing</primary></indexterm>
+ <indexterm><primary>gateway</primary></indexterm>
+ <indexterm><primary>subnet</primary></indexterm>
+ <para>為了讓一部電腦能找到另一部電腦,因此必需要有一種機制,
+ 讓這部電腦知道該怎麼做,這個機制就是路由選擇
+ (<firstterm>routing</firstterm>)。
+ 一條路由(<quote>route</quote>)是由一對位址所定義的:一個是
+ <quote>目的地(destination)</quote>以及另一個則是閘道
+ (<quote>gateway</quote>)。
+ 這對位址表示要送到<emphasis>目的地</emphasis>的封包,
+ 必須經過<emphasis>閘道</emphasis>。
+ 目的地分為三種類型:主機、子網路(subnet)、預設路由(
+ <quote>default route</quote>。 若都沒有其它的路由可以使用,
+ 這時就會使用預設路由,稍後我們會對預設路由作進一步的說明。 此外,
+ 閘道也可分為三種類型:主機、傳輸介面(interface,也稱為
+ <quote>links</quote>)、乙太網路硬體位址(MAC addresses)。</para>
+
+ <sect2>
+ <title>範例</title>
+
+ <para>為了方便說明不同類型的路由選擇(routing),以下使用
+ <command>netstat</command> 指令的結果作為介紹範例:</para>
+
+ <screen>&prompt.user; <userinput>netstat -r</userinput>
+Routing tables
+
+Destination Gateway Flags Refs Use Netif Expire
+
+default outside-gw UGSc 37 418 ppp0
+localhost localhost UH 0 181 lo0
+test0 0:e0:b5:36:cf:4f UHLW 5 63288 ed0 77
+10.20.30.255 link#1 UHLW 1 2421
+example.com link#1 UC 0 0
+host1 0:e0:a8:37:8:1e UHLW 3 4601 lo0
+host2 0:e0:a8:37:8:1e UHLW 0 5 lo0 =&gt;
+host2.example.com link#1 UC 0 0
+224 link#1 UC 0 0</screen>
+
+ <indexterm><primary>default route</primary></indexterm>
+ <para>The first two lines specify the default route (which we
+ will cover in the <link linkend="network-routing-default">next
+ section</link>) and the <systemitem>localhost</systemitem> route.</para>
+
+ <indexterm><primary>loopback device</primary></indexterm>
+ <para>The interface (<literal>Netif</literal> column) that this
+ routing table specifies to use for
+ <literal>localhost</literal> is <filename>lo0</filename>,
+ also known as the loopback device. This says to keep all
+ traffic for this destination internal, rather than sending it
+ out over the LAN, since it will only end up back where it
+ started.</para>
+
+ <indexterm>
+ <primary>Ethernet</primary>
+ <secondary>MAC address</secondary>
+ </indexterm>
+ <para>The next thing that stands out are the addresses beginning
+ with <systemitem class="etheraddress">0:e0:</systemitem>. These are Ethernet
+ hardware addresses, which are also known as MAC addresses.
+ FreeBSD will automatically identify any hosts
+ (<systemitem>test0</systemitem> in the example) on the local Ethernet
+ and add a route for that host, directly to it over the
+ Ethernet interface, <filename>ed0</filename>. There is
+ also a timeout (<literal>Expire</literal> column) associated
+ with this type of route, which is used if we fail to hear from
+ the host in a specific amount of time. When this happens, the
+ route to this host will be automatically deleted. These hosts
+ are identified using a mechanism known as RIP (Routing
+ Information Protocol), which figures out routes to local hosts
+ based upon a shortest path determination.</para>
+
+ <indexterm><primary>subnet</primary></indexterm>
+ <para>FreeBSD will also add subnet routes for the local subnet (<systemitem class="ipaddress">10.20.30.255</systemitem> is the broadcast address for the
+ subnet <systemitem class="ipaddress">10.20.30</systemitem>, and <systemitem class="fqdomainname">example.com</systemitem> is the domain name associated
+ with that subnet). The designation <literal>link#1</literal> refers
+ to the first Ethernet card in the machine. You will notice no
+ additional interface is specified for those.</para>
+
+ <para>Both of these groups (local network hosts and local subnets) have
+ their routes automatically configured by a daemon called
+ <application>routed</application>. If this is not run, then only
+ routes which are statically defined (i.e. entered explicitly) will
+ exist.</para>
+
+ <para>The <literal>host1</literal> line refers to our host, which it
+ knows by Ethernet address. Since we are the sending host, FreeBSD
+ knows to use the loopback interface (<filename>lo0</filename>)
+ rather than sending it out over the Ethernet interface.</para>
+
+ <para>The two <literal>host2</literal> lines are an example of
+ what happens when we use an &man.ifconfig.8; alias (see the
+ section on Ethernet for reasons why we would do this). The
+ <literal>=&gt;</literal> symbol after the
+ <filename>lo0</filename> interface says that not only are
+ we using the loopback (since this address also refers to the
+ local host), but specifically it is an alias. Such routes
+ only show up on the host that supports the alias; all other
+ hosts on the local network will simply have a
+ <literal>link#1</literal> line for such routes.</para>
+
+ <para>The final line (destination subnet <systemitem class="ipaddress">224</systemitem>) deals
+ with multicasting, which will be covered in another section.</para>
+
+ <para>Finally, various attributes of each route can be seen in
+ the <literal>Flags</literal> column. Below is a short table
+ of some of these flags and their meanings:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="4*"/>
+
+ <tbody>
+ <row>
+ <entry>U</entry>
+ <entry>Up: The route is active.</entry>
+ </row>
+
+ <row>
+ <entry>H</entry>
+ <entry>Host: The route destination is a single host.</entry>
+ </row>
+
+ <row>
+ <entry>G</entry>
+ <entry>Gateway: Send anything for this destination on to this
+ remote system, which will figure out from there where to send
+ it.</entry>
+ </row>
+
+ <row>
+ <entry>S</entry>
+ <entry>Static: This route was configured manually, not
+ automatically generated by the system.</entry>
+ </row>
+
+ <row>
+ <entry>C</entry>
+ <entry>Clone: Generates a new route based upon this route for
+ machines we connect to. This type of route is normally used
+ for local networks.</entry>
+ </row>
+
+ <row>
+ <entry>W</entry>
+ <entry>WasCloned: Indicated a route that was auto-configured
+ based upon a local area network (Clone) route.</entry>
+ </row>
+
+ <row>
+ <entry>L</entry>
+ <entry>Link: Route involves references to Ethernet
+ hardware.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2 xml:id="network-routing-default">
+ <title>Default Routes</title>
+
+ <indexterm><primary>default route</primary></indexterm>
+ <para>When the local system needs to make a connection to a remote host,
+ it checks the routing table to determine if a known path exists. If
+ the remote host falls into a subnet that we know how to reach (Cloned
+ routes), then the system checks to see if it can connect along that
+ interface.</para>
+
+ <para>If all known paths fail, the system has one last option: the
+ <quote>default</quote> route. This route is a special type of gateway
+ route (usually the only one present in the system), and is always
+ marked with a <literal>c</literal> in the flags field. For hosts on a
+ local area network, this gateway is set to whatever machine has a
+ direct connection to the outside world (whether via PPP link,
+ DSL, cable modem, T1, or another network interface).</para>
+
+ <para>If you are configuring the default route for a machine which
+ itself is functioning as the gateway to the outside world, then the
+ default route will be the gateway machine at your Internet Service
+ Provider's (ISP) site.</para>
+
+ <para>Let us look at an example of default routes. This is a common
+ configuration:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="advanced-networking/net-routing"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced">
+[Local2] &lt;--ether--&gt; [Local1] &lt;--PPP--&gt; [ISP-Serv] &lt;--ether--&gt; [T1-GW]
+ </literallayout>
+ </textobject>
+ </mediaobject>
+
+ <para>The hosts <systemitem>Local1</systemitem> and
+ <systemitem>Local2</systemitem> are at your site.
+ <systemitem>Local1</systemitem> is connected to an ISP via a dial up
+ PPP connection. This PPP server computer is connected through
+ a local area network to another gateway computer through an
+ external interface to the ISPs Internet feed.</para>
+
+ <para>The default routes for each of your machines will be:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Host</entry>
+ <entry>Default Gateway</entry>
+ <entry>Interface</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>Local2</entry>
+ <entry>Local1</entry>
+ <entry>Ethernet</entry>
+ </row>
+
+ <row>
+ <entry>Local1</entry>
+ <entry>T1-GW</entry>
+ <entry>PPP</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>A common question is <quote>Why (or how) would we set
+ the <systemitem>T1-GW</systemitem> to be the default gateway for
+ <systemitem>Local1</systemitem>, rather than the ISP server it is
+ connected to?</quote>.</para>
+
+ <para>Remember, since the PPP interface is using an address on the ISP's
+ local network for your side of the connection, routes for any other
+ machines on the ISP's local network will be automatically generated.
+ Hence, you will already know how to reach the <systemitem>T1-GW</systemitem>
+ machine, so there is no need for the intermediate step
+ of sending traffic to the ISP server.</para>
+
+ <para>It is common to use the address <systemitem class="ipaddress">X.X.X.1</systemitem> as the gateway address for your local
+ network. So (using the same example), if your local class-C address
+ space was <systemitem class="ipaddress">10.20.30</systemitem> and your ISP was
+ using <systemitem class="ipaddress">10.9.9</systemitem> then the default routes
+ would be:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Host</entry>
+ <entry>Default Route</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Local2 (10.20.30.2)</entry>
+ <entry>Local1 (10.20.30.1)</entry>
+ </row>
+ <row>
+ <entry>Local1 (10.20.30.1, 10.9.9.30)</entry>
+ <entry>T1-GW (10.9.9.1)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>You can easily define the default route via the
+ <filename>/etc/rc.conf</filename> file. In our example, on the
+ <systemitem>Local2</systemitem> machine, we added the following line
+ in <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>defaultrouter="10.20.30.1"</programlisting>
+
+ <para>It is also possible to do it directly from the command
+ line with the &man.route.8; command:</para>
+
+ <screen>&prompt.root; <userinput>route add default 10.20.30.1</userinput></screen>
+
+ <para>For more information on manual manipulation of network
+ routing tables, consult &man.route.8; manual page.</para>
+ </sect2>
+
+ <sect2>
+ <title>Dual Homed Hosts</title>
+ <indexterm><primary>dual homed hosts</primary></indexterm>
+ <para>There is one other type of configuration that we should cover, and
+ that is a host that sits on two different networks. Technically, any
+ machine functioning as a gateway (in the example above, using a PPP
+ connection) counts as a dual-homed host. But the term is really only
+ used to refer to a machine that sits on two local-area
+ networks.</para>
+
+ <para>In one case, the machine has two Ethernet cards, each
+ having an address on the separate subnets. Alternately, the
+ machine may only have one Ethernet card, and be using
+ &man.ifconfig.8; aliasing. The former is used if two
+ physically separate Ethernet networks are in use, the latter
+ if there is one physical network segment, but two logically
+ separate subnets.</para>
+
+ <para>Either way, routing tables are set up so that each subnet knows
+ that this machine is the defined gateway (inbound route) to the other
+ subnet. This configuration, with the machine acting as a router
+ between the two subnets, is often used when we need to implement
+ packet filtering or firewall security in either or both
+ directions.</para>
+
+ <para>If you want this machine to actually forward packets
+ between the two interfaces, you need to tell FreeBSD to enable
+ this ability. See the next section for more details on how
+ to do this.</para>
+ </sect2>
+
+ <sect2 xml:id="network-dedicated-router">
+ <title>Building a Router</title>
+
+ <indexterm><primary>router</primary></indexterm>
+
+ <para>A network router is simply a system that forwards packets
+ from one interface to another. Internet standards and good
+ engineering practice prevent the FreeBSD Project from enabling
+ this by default in FreeBSD. You can enable this feature by
+ changing the following variable to <literal>YES</literal> in
+ &man.rc.conf.5;:</para>
+
+ <programlisting>gateway_enable=YES # Set to YES if this host will be a gateway</programlisting>
+
+ <para>This option will set the &man.sysctl.8; variable
+ <varname>net.inet.ip.forwarding</varname> to
+ <literal>1</literal>. If you should need to stop routing
+ temporarily, you can reset this to <literal>0</literal> temporarily.</para>
+
+ <para>Your new router will need routes to know where to send the
+ traffic. If your network is simple enough you can use static
+ routes. FreeBSD also comes with the standard BSD routing
+ daemon &man.routed.8;, which speaks RIP (both version 1 and
+ version 2) and IRDP. Support for BGP v4, OSPF v2, and other
+ sophisticated routing protocols is available with the
+ <package>net/zebra</package> package.
+ Commercial products such as <application>&gated;</application> are also available for more
+ complex network routing solutions.</para>
+
+<indexterm><primary>BGP</primary></indexterm>
+<indexterm><primary>RIP</primary></indexterm>
+<indexterm><primary>OSPF</primary></indexterm>
+ </sect2>
+
+ <sect2>
+ <info><title>Setting Up Static Routes</title>
+ <authorgroup>
+ <author><personname><firstname>Al</firstname><surname>Hoang</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+ <!-- Feb 2004 -->
+
+
+ <sect3>
+ <title>Manual Configuration</title>
+
+ <para>Let us assume we have a network as follows:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="advanced-networking/static-routes"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced">
+ INTERNET
+ | (10.0.0.1/24) Default Router to Internet
+ |
+ |Interface xl0
+ |10.0.0.10/24
+ +------+
+ | | RouterA
+ | | (FreeBSD gateway)
+ +------+
+ | Interface xl1
+ | 192.168.1.1/24
+ |
+ +--------------------------------+
+ Internal Net 1 | 192.168.1.2/24
+ |
+ +------+
+ | | RouterB
+ | |
+ +------+
+ | 192.168.2.1/24
+ |
+ Internal Net 2
+ </literallayout>
+ </textobject>
+ </mediaobject>
+
+ <para>In this scenario, <systemitem>RouterA</systemitem> is our &os;
+ machine that is acting as a router to the rest of the
+ Internet. It has a default route set to <systemitem class="ipaddress">10.0.0.1</systemitem> which allows it to connect
+ with the outside world. We will assume that
+ <systemitem>RouterB</systemitem> is already configured properly and
+ knows how to get wherever it needs to go. (This is simple
+ in this picture. Just add a default route on
+ <systemitem>RouterB</systemitem> using <systemitem class="ipaddress">192.168.1.1</systemitem> as the gateway.)</para>
+
+ <para>If we look at the routing table for
+ <systemitem>RouterA</systemitem> we would see something like the
+ following:</para>
+
+ <screen>&prompt.user; <userinput>netstat -nr</userinput>
+Routing tables
+
+Internet:
+Destination Gateway Flags Refs Use Netif Expire
+default 10.0.0.1 UGS 0 49378 xl0
+127.0.0.1 127.0.0.1 UH 0 6 lo0
+10.0.0/24 link#1 UC 0 0 xl0
+192.168.1/24 link#2 UC 0 0 xl1</screen>
+
+ <para>With the current routing table <systemitem>RouterA</systemitem>
+ will not be able to reach our Internal Net 2. It does not
+ have a route for <systemitem class="ipaddress">192.168.2.0/24</systemitem>. One way to alleviate
+ this is to manually add the route. The following command
+ would add the Internal Net 2 network to
+ <systemitem>RouterA</systemitem>'s routing table using <systemitem class="ipaddress">192.168.1.2</systemitem> as the next hop:</para>
+
+ <screen>&prompt.root; <userinput>route add -net 192.168.2.0/24 192.168.1.2</userinput></screen>
+
+ <para>Now <systemitem>RouterA</systemitem> can reach any hosts on the
+ <systemitem class="ipaddress">192.168.2.0/24</systemitem>
+ network.</para>
+ </sect3>
+
+ <sect3>
+ <title>Persistent Configuration</title>
+
+ <para>The above example is perfect for configuring a static
+ route on a running system. However, one problem is that the
+ routing information will not persist if you reboot your &os;
+ machine. The way to handle the addition of a static route
+ is to put it in your <filename>/etc/rc.conf</filename>
+ file:</para>
+
+ <programlisting># Add Internal Net 2 as a static route
+static_routes="internalnet2"
+route_internalnet2="-net 192.168.2.0/24 192.168.1.2"</programlisting>
+
+ <para>The <literal>static_routes</literal> configuration
+ variable is a list of strings separated by a space. Each
+ string references to a route name. In our above example we
+ only have one string in <literal>static_routes</literal>.
+ This string is <replaceable>internalnet2</replaceable>. We
+ then add a configuration variable called
+ <literal>route_internalnet2</literal>
+ where we put all of the configuration parameters we would
+ give to the &man.route.8; command. For our example above we
+ would have used the command:</para>
+
+ <screen>&prompt.root; <userinput>route add -net 192.168.2.0/24 192.168.1.2</userinput></screen>
+
+ <para>so we need <literal>"-net 192.168.2.0/24 192.168.1.2"</literal>.</para>
+
+ <para>As said above, we can have more than one string in
+ <literal>static_routes</literal>. This allows us to
+ create multiple static routes. The following lines shows
+ an example of adding static routes for the <systemitem class="ipaddress">192.168.0.0/24</systemitem> and <systemitem class="ipaddress">192.168.1.0/24</systemitem> networks on an imaginary
+ router:</para>
+
+ <programlisting>static_routes="net1 net2"
+route_net1="-net 192.168.0.0/24 192.168.0.1"
+route_net2="-net 192.168.1.0/24 192.168.1.1"</programlisting>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Routing Propagation</title>
+ <indexterm><primary>routing propagation</primary></indexterm>
+ <para>We have already talked about how we define our routes to the
+ outside world, but not about how the outside world finds us.</para>
+
+ <para>We already know that routing tables can be set up so that all
+ traffic for a particular address space (in our examples, a class-C
+ subnet) can be sent to a particular host on that network, which will
+ forward the packets inbound.</para>
+
+ <para>When you get an address space assigned to your site, your service
+ provider will set up their routing tables so that all traffic for your
+ subnet will be sent down your PPP link to your site. But how do sites
+ across the country know to send to your ISP?</para>
+
+ <para>There is a system (much like the distributed DNS information) that
+ keeps track of all assigned address-spaces, and defines their point of
+ connection to the Internet Backbone. The <quote>Backbone</quote> are
+ the main trunk lines that carry Internet traffic across the country,
+ and around the world. Each backbone machine has a copy of a master
+ set of tables, which direct traffic for a particular network to a
+ specific backbone carrier, and from there down the chain of service
+ providers until it reaches your network.</para>
+
+ <para>It is the task of your service provider to advertise to the
+ backbone sites that they are the point of connection (and thus the
+ path inward) for your site. This is known as route
+ propagation.</para>
+ </sect2>
+
+ <sect2>
+ <title>Troubleshooting</title>
+ <indexterm>
+ <primary><command>traceroute</command></primary>
+ </indexterm>
+ <para>Sometimes, there is a problem with routing propagation, and some
+ sites are unable to connect to you. Perhaps the most useful command
+ for trying to figure out where routing is breaking down is the
+ &man.traceroute.8; command. It is equally useful if you cannot seem
+ to make a connection to a remote machine (i.e. &man.ping.8;
+ fails).</para>
+
+ <para>The &man.traceroute.8; command is run with the name of the remote
+ host you are trying to connect to. It will show the gateway hosts
+ along the path of the attempt, eventually either reaching the target
+ host, or terminating because of a lack of connection.</para>
+
+ <para>For more information, see the manual page for
+ &man.traceroute.8;.</para>
+ </sect2>
+
+ <sect2>
+ <title>Multicast Routing</title>
+ <indexterm>
+ <primary>multicast routing</primary>
+ </indexterm>
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>MROUTING</secondary>
+ </indexterm>
+ <para>FreeBSD supports both multicast applications and multicast
+ routing natively. Multicast applications do not require any
+ special configuration of FreeBSD; applications will generally
+ run out of the box. Multicast routing
+ requires that support be compiled into the kernel:</para>
+
+ <programlisting>options MROUTING</programlisting>
+
+ <para>In addition, the multicast routing daemon, &man.mrouted.8;
+ must be configured to set up tunnels and <acronym>DVMRP</acronym> via
+ <filename>/etc/mrouted.conf</filename>. More details on
+ multicast configuration may be found in the manual page for
+ &man.mrouted.8;.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-wireless">
+ <info><title>Wireless Networking</title>
+ <authorgroup>
+ <author><personname><othername>Loader</othername></personname></author>
+
+ <author><personname><firstname>Marc</firstname><surname>Fonvieille</surname></personname></author>
+
+ <author><personname><firstname>Murray</firstname><surname>Stokely</surname></personname></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>wireless networking</primary></indexterm>
+ <indexterm>
+ <primary>802.11</primary>
+ <see>wireless networking</see>
+ </indexterm>
+
+ <sect2>
+ <title>Wireless Networking Basics</title>
+
+ <para>Most wireless networks are based on the IEEE 802.11
+ standards. A basic wireless network consists of multiple
+ stations communicating with radios that broadcast in either
+ the 2.4GHz or 5GHz band (though this varies according to the
+ locale and is also changing to enable communication in the
+ 2.3GHz and 4.9GHz ranges).</para>
+
+ <para>802.11 networks are organized in two ways: in
+ <emphasis>infrastructure mode</emphasis> one station acts as a
+ master with all the other stations associating to it; the
+ network is known as a BSS and the master station is termed an
+ access point (AP). In a BSS all communication passes through
+ the AP; even when one station wants to communicate with
+ another wireless station messages must go through the AP. In
+ the second form of network there is no master and stations
+ communicate directly. This form of network is termed an IBSS
+ and is commonly known as an <emphasis>ad-hoc
+ network</emphasis>.</para>
+
+ <para>802.11 networks were first deployed in the 2.4GHz band
+ using protocols defined by the IEEE 802.11 and 802.11b
+ standard. These specifications include the operating
+ frequencies, MAC layer characteristics including framing and
+ transmission rates (communication can be done at various
+ rates). Later the 802.11a standard defined operation in the
+ 5GHz band, including different signalling mechanisms and
+ higher transmission rates. Still later the 802.11g standard
+ was defined to enable use of 802.11a signalling and
+ transmission mechanisms in the 2.4GHz band in such a way as to
+ be backwards compatible with 802.11b networks.</para>
+
+ <para>Separate from the underlying transmission techniques
+ 802.11 networks have a variety of security mechanisms. The
+ original 802.11 specifications defined a simple security
+ protocol called WEP. This protocol uses a fixed pre-shared key
+ and the RC4 cryptographic cipher to encode data transmitted on
+ a network. Stations must all agree on the fixed key in order
+ to communicate. This scheme was shown to be easily broken and
+ is now rarely used except to discourage transient users from
+ joining networks. Current security practice is given by the
+ IEEE 802.11i specification that defines new cryptographic
+ ciphers and an additional protocol to authenticate stations to
+ an access point and exchange keys for doing data
+ communication. Further, cryptographic keys are periodically
+ refreshed and there are mechanisms for detecting intrusion
+ attempts (and for countering intrusion attempts). Another
+ security protocol specification commonly used in wireless
+ networks is termed WPA. This was a precursor to 802.11i
+ defined by an industry group as an interim measure while
+ waiting for 802.11i to be ratified. WPA specifies a subset of
+ the requirements found in 802.11i and is designed for
+ implementation on legacy hardware. Specifically WPA requires
+ only the TKIP cipher that is derived from the original WEP
+ cipher. 802.11i permits use of TKIP but also requires support
+ for a stronger cipher, AES-CCM, for encrypting data. (The AES
+ cipher was not required in WPA because it was deemed too
+ computationally costly to be implemented on legacy
+ hardware.)</para>
+
+ <para>Other than the above protocol standards the other
+ important standard to be aware of is 802.11e. This defines
+ protocols for deploying multi-media applications such as
+ streaming video and voice over IP (VoIP) in an 802.11 network.
+ Like 802.11i, 802.11e also has a precursor specification
+ termed WME (later renamed WMM) that has been defined by an
+ industry group as a subset of 802.11e that can be deployed now
+ to enable multi-media applications while waiting for the final
+ ratification of 802.11e. The most important thing to know
+ about 802.11e and WME/WMM is that it enables prioritized
+ traffic use of a wireless network through Quality of Service
+ (QoS) protocols and enhanced media access protocols. Proper
+ implementation of these protocols enable high speed bursting
+ of data and prioritized traffic flow.</para>
+
+ <para>Since the 6.0 version, &os; supports networks that operate
+ using 802.11a, 802.11b, and 802.11g. The WPA and 802.11i
+ security protocols are likewise supported (in conjunction with
+ any of 11a, 11b, and 11g) and QoS and traffic prioritization
+ required by the WME/WMM protocols are supported for a limited
+ set of wireless devices.</para>
+ </sect2>
+
+ <sect2 xml:id="network-wireless-basic">
+ <title>Basic Setup</title>
+
+ <sect3>
+ <title>Kernel Configuration</title>
+
+ <para>To use wireless networking you need a wireless
+ networking card and to configure the kernel with the
+ appropriate wireless networking support. The latter is
+ separated into multiple modules so that you only need to
+ configure the software you are actually going to use.</para>
+
+ <para>The first thing you need is a wireless device. The most
+ commonly used devices are those that use parts made by
+ Atheros. These devices are supported by the &man.ath.4;
+ driver and require the following line to be added to the
+ <filename>/boot/loader.conf</filename> file:</para>
+
+ <programlisting>if_ath_load="YES"</programlisting>
+
+ <para>The Atheros driver is split up into three separate
+ pieces: the driver proper (&man.ath.4;), the hardware
+ support layer that handles chip-specific functions
+ (&man.ath.hal.4;), and an algorithm for selecting which of
+ several possible rates for transmitting frames
+ (ath_rate_sample here). When you load this support as
+ modules these dependencies are automatically handled for
+ you. If instead of an Atheros device you had another device
+ you would select the module for that device; e.g.:</para>
+
+ <programlisting>if_wi_load="YES"</programlisting>
+
+ <para>for devices based on the Intersil Prism parts
+ (&man.wi.4; driver).</para>
+
+ <note>
+ <para>In the rest of this document, we will use an
+ &man.ath.4; device, the device name in the examples must
+ be changed according to your configuration. A list of
+ available wireless drivers can be found at the beginning
+ of the &man.wlan.4; manual page. If a native &os; driver
+ for your wireless device does not exist, it may be
+ possible to directly use the &windows; driver with the
+ help of the <link linkend="config-network-ndis">NDIS</link> driver
+ wrapper.</para>
+ </note>
+
+ <para>With a device driver configured you need to also bring
+ in the 802.11 networking support required by the driver.
+ For the &man.ath.4; driver this is at least the &man.wlan.4;
+ module; this module is automatically loaded with the
+ wireless device driver. With that you will need the modules
+ that implement cryptographic support for the security
+ protocols you intend to use. These are intended to be
+ dynamically loaded on demand by the &man.wlan.4; module but
+ for now they must be manually configured. The following
+ modules are available: &man.wlan.wep.4;, &man.wlan.ccmp.4;
+ and &man.wlan.tkip.4;. Both &man.wlan.ccmp.4; and
+ &man.wlan.tkip.4; drivers are only needed if you intend to
+ use the WPA and/or 802.11i security protocols. If your
+ network is to run totally open (i.e., with no encryption)
+ then you do not even need the &man.wlan.wep.4; support. To
+ load these modules at boot time, add the following lines to
+ <filename>/boot/loader.conf</filename>:</para>
+
+ <programlisting>wlan_wep_load="YES"
+wlan_ccmp_load="YES"
+wlan_tkip_load="YES"</programlisting>
+
+ <para>With this information in the system bootstrap
+ configuration file (i.e.,
+ <filename>/boot/loader.conf</filename>), you have to reboot
+ your &os; box. If you do not want to reboot your machine
+ for the moment, you can just load the modules by hand using
+ &man.kldload.8;.</para>
+
+ <note>
+ <para>If you do not want to use modules, it is possible to
+ compile these drivers into the kernel by adding the
+ following lines to your kernel configuration file:</para>
+
+ <programlisting>device ath # Atheros IEEE 802.11 wireless network driver
+device ath_hal # Atheros Hardware Access Layer
+device ath_rate_sample # John Bicket's SampleRate control algorithm.
+device wlan # 802.11 support (Required)
+device wlan_wep # WEP crypto support for 802.11 devices
+device wlan_ccmp # AES-CCMP crypto support for 802.11 devices
+device wlan_tkip # TKIP and Michael crypto support for 802.11 devices</programlisting>
+
+ <para>With this information in the kernel configuration
+ file, recompile the kernel and reboot your &os;
+ machine.</para>
+ </note>
+
+ <para>When the system is up, we could find some information
+ about the wireless device in the boot messages, like
+ this:</para>
+
+ <screen>ath0: &lt;Atheros 5212&gt; mem 0xff9f0000-0xff9fffff irq 17 at device 2.0 on pci2
+ath0: Ethernet address: 00:11:95:d5:43:62
+ath0: mac 7.9 phy 4.5 radio 5.6</screen>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Infrastructure Mode</title>
+
+ <para>The infrastructure mode or BSS mode is the mode that is
+ typically used. In this mode, a number of wireless access
+ points are connected to a wired network. Each wireless
+ network has its own name, this name is called the SSID of the
+ network. Wireless clients connect to the wireless access
+ points.</para>
+
+ <sect3>
+ <title>&os; Clients</title>
+
+ <sect4>
+ <title>How to Find Access Points</title>
+
+ <para>To scan for networks, use the
+ <command>ifconfig</command> command. This request may
+ take a few moments to complete as it requires that the
+ system switches to each available wireless frequency and
+ probes for available access points. Only the super-user
+ can initiate such a scan:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0 up scan</userinput>
+SSID BSSID CHAN RATE S:N INT CAPS
+dlinkap 00:13:46:49:41:76 6 54M 29:0 100 EPS WPA WME
+freebsdap 00:11:95:c3:0d:ac 1 54M 22:0 100 EPS WPA</screen>
+
+ <note>
+ <para>You must mark the interface <option>up</option>
+ before you can scan. Subsequent scan requests do not
+ require you to mark the interface up again.</para>
+ </note>
+
+ <para>The output of a scan request lists each BSS/IBSS
+ network found. Beside the name of the network,
+ <literal>SSID</literal>, we find the
+ <literal>BSSID</literal> which is the MAC address of the
+ access point. The <literal>CAPS</literal> field
+ identifies the type of each network and the capabilities
+ of the stations operating there:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>E</literal></term>
+
+ <listitem>
+ <para>Extended Service Set (ESS). Indicates that the
+ station is part of an infrastructure network (in
+ contrast to an IBSS/ad-hoc network).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>I</literal></term>
+
+ <listitem>
+ <para>IBSS/ad-hoc network. Indicates that the station
+ is part of an ad-hoc network (in contrast to an ESS
+ network).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>P</literal></term>
+
+ <listitem>
+ <para>Privacy. Data confidentiality is required for
+ all data frames exchanged within the BSS. This means
+ that this BSS requires the station to use
+ cryptographic means such as WEP, TKIP or AES-CCMP to
+ encrypt/decrypt data frames being exchanged with
+ others.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>S</literal></term>
+
+ <listitem>
+ <para>Short Preamble. Indicates that the network is
+ using short preambles (defined in 802.11b High
+ Rate/DSSS PHY, short preamble utilizes a 56 bit sync
+ field in contrast to a 128 bit field used in long
+ preamble mode).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>s</literal></term>
+
+ <listitem>
+ <para>Short slot time. Indicates that the 802.11g
+ network is using a short slot time because there are
+ no legacy (802.11b) stations present.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>One can also display the current list of known
+ networks with:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0 list scan</userinput></screen>
+
+ <para>This information may be updated automatically by the
+ adapter or manually with a <option>scan</option> request.
+ Old data is automatically removed from the cache, so over
+ time this list may shrink unless more scans are
+ done.</para>
+ </sect4>
+
+ <sect4>
+ <title>Basic Settings</title>
+
+ <para>This section provides a simple example of how to make
+ the wireless network adapter work in &os; without
+ encryption. After you are familiar with these concepts,
+ we strongly recommend using <link linkend="network-wireless-wpa">WPA</link> to set up your
+ wireless network.</para>
+
+ <para>There are three basic steps to configure a wireless
+ network: selecting an access point, authenticating your
+ station, and configuring an IP address. The following
+ sections discuss each step.</para>
+
+ <sect5>
+ <title>Selecting an Access Point</title>
+
+ <para>Most of time it is sufficient to let the system
+ choose an access point using the builtin heuristics.
+ This is the default behaviour when you mark an interface
+ up or otherwise configure an interface by listing it in
+ <filename>/etc/rc.conf</filename>, e.g.:</para>
+
+ <programlisting>ifconfig_ath0="DHCP"</programlisting>
+
+ <para>If there are multiple access points and you want to
+ select a specific one, you can select it by its
+ SSID:</para>
+
+ <programlisting>ifconfig_ath0="ssid <replaceable>your_ssid_here</replaceable> DHCP"</programlisting>
+
+ <para>In an environment where there are multiple access
+ points with the same SSID (often done to simplify
+ roaming) it may be necessary to associate to one
+ specific device. In this case you can also specify the
+ BSSID of the access point (you can also leave off the
+ SSID):</para>
+
+ <programlisting>ifconfig_ath0="ssid <replaceable>your_ssid_here</replaceable> bssid <replaceable>xx:xx:xx:xx:xx:xx</replaceable> DHCP"</programlisting>
+
+ <para>There are other ways to constrain the choice of an
+ access point such as limiting the set of frequencies the
+ system will scan on. This may be useful if you have a
+ multi-band wireless card as scanning all the possible
+ channels can be time-consuming. To limit operation to a
+ specific band you can use the <option>mode</option>
+ parameter; e.g.:</para>
+
+ <programlisting>ifconfig_ath0="mode <replaceable>11g</replaceable> ssid <replaceable>your_ssid_here</replaceable> DHCP"</programlisting>
+
+ <para>will force the card to operate in 802.11g which is
+ defined only for 2.4GHz frequencies so any 5GHz channels
+ will not be considered. Other ways to do this are the
+ <option>channel</option> parameter, to lock operation to
+ one specific frequency, and the
+ <option>chanlist</option> parameter, to specify a list
+ of channels for scanning. More information about these
+ parameters can be found in the &man.ifconfig.8; manual
+ page.</para>
+ </sect5>
+
+ <sect5>
+ <title>Authentication</title>
+
+ <para>Once you have selected an access point your station
+ needs to authenticate before it can pass data.
+ Authentication can happen in several ways. The most
+ common scheme used is termed open authentication and
+ allows any station to join the network and communicate.
+ This is the authentication you should use for test
+ purpose the first time you set up a wireless network.
+ Other schemes require cryptographic handshakes be
+ completed before data traffic can flow; either using
+ pre-shared keys or secrets, or more complex schemes that
+ involve backend services such as RADIUS. Most users
+ will use open authentication which is the default
+ setting. Next most common setup is WPA-PSK, also known
+ as WPA Personal, which is described <link linkend="network-wireless-wpa-wpa-psk">below</link>.</para>
+
+ <note>
+ <para>If you have an &apple; &airport; Extreme base
+ station for an access point you may need to configure
+ shared-key authentication together with a WEP key.
+ This can be done in the
+ <filename>/etc/rc.conf</filename> file or using the
+ &man.wpa.supplicant.8; program. If you have a single
+ &airport; base station you can setup access with
+ something like:</para>
+
+ <programlisting>ifconfig_ath0="authmode shared wepmode on weptxkey <replaceable>1</replaceable> wepkey <replaceable>01234567</replaceable> DHCP"</programlisting>
+
+ <para>In general shared key authentication is to be
+ avoided because it uses the WEP key material in a
+ highly-constrained manner making it even easier to
+ crack the key. If WEP must be used (e.g., for
+ compatibility with legacy devices) it is better to use
+ WEP with <literal>open</literal> authentication. More
+ information regarding WEP can be found in the <xref linkend="network-wireless-wep"/>.</para>
+ </note>
+ </sect5>
+
+ <sect5>
+ <title>Getting an IP Address with DHCP</title>
+
+ <para>Once you have selected an access point and set the
+ authentication parameters, you will have to get an IP
+ address to communicate. Most of time you will obtain
+ your wireless IP address via DHCP. To achieve that,
+ simply edit <filename>/etc/rc.conf</filename> and add
+ <literal>DHCP</literal> to the configuration for your
+ device as shown in various examples above:</para>
+
+ <programlisting>ifconfig_ath0="DHCP"</programlisting>
+
+ <para>At this point, you are ready to bring up the
+ wireless interface:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/netif start</userinput></screen>
+
+ <para>Once the interface is running, use
+ <command>ifconfig</command> to see the status of the
+ interface <filename>ath0</filename>:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0</userinput>
+ath0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet6 fe80::211:95ff:fed5:4362%ath0 prefixlen 64 scopeid 0x1
+ inet 192.168.1.100 netmask 0xffffff00 broadcast 192.168.1.255
+ ether 00:11:95:d5:43:62
+ media: IEEE 802.11 Wireless Ethernet autoselect (OFDM/54Mbps)
+ status: associated
+ ssid dlinkap channel 6 bssid 00:13:46:49:41:76
+ authmode OPEN privacy OFF txpowmax 36 protmode CTS bintval 100</screen>
+
+ <para>The <literal>status: associated</literal> means you
+ are connected to the wireless network (to the
+ <literal>dlinkap</literal> network in our case). The
+ <literal>bssid 00:13:46:49:41:76</literal> part is the
+ MAC address of your access point; the
+ <literal>authmode</literal> line informs you that the
+ communication is not encrypted
+ (<literal>OPEN</literal>).</para>
+ </sect5>
+
+ <sect5>
+ <title>Static IP Address</title>
+
+ <para>In the case you cannot obtain an IP address from a
+ DHCP server, you can set a fixed IP address. Replace
+ the <literal>DHCP</literal> keyword shown above with the
+ address information. Be sure to retain any other
+ parameters you have set up for selecting an access
+ point:</para>
+
+ <programlisting>ifconfig_ath0="inet <replaceable>192.168.1.100</replaceable> netmask <replaceable>255.255.255.0</replaceable> ssid <replaceable>your_ssid_here</replaceable>"</programlisting>
+ </sect5>
+ </sect4>
+
+ <sect4 xml:id="network-wireless-wpa">
+ <title>WPA</title>
+
+ <para>WPA (Wi-Fi Protected Access) is a security protocol
+ used together with 802.11 networks to address the lack of
+ proper authentication and the weakness of <link linkend="network-wireless-wep">WEP</link>. WPA leverages
+ the 802.1X authentication protocol and uses one of several
+ ciphers instead of WEP for data integrity. The only
+ cipher required by WPA is TKIP (Temporary Key Integrity
+ Protocol) which is a cipher that extends the basic RC4
+ cipher used by WEP by adding integrity checking, tamper
+ detection, and measures for responding to any detected
+ intrusions. TKIP is designed to work on legacy hardware
+ with only software modification; it represents a
+ compromise that improves security but is still not
+ entirely immune to attack. WPA also specifies the
+ AES-CCMP cipher as an alternative to TKIP and that is
+ preferred when possible; for this specification the term
+ WPA2 (or RSN) is commonly used.</para>
+
+ <para>WPA defines authentication and encryption protocols.
+ Authentication is most commonly done using one of two
+ techniques: by 802.1X and a backend authentication service
+ such as RADIUS, or by a minimal handshake between the
+ station and the access point using a pre-shared secret.
+ The former is commonly termed WPA Enterprise with the
+ latter known as WPA Personal. Since most people will not
+ set up a RADIUS backend server for wireless network,
+ WPA-PSK is by far the most commonly encountered
+ configuration for WPA.</para>
+
+ <para>The control of the wireless connection and the
+ authentication (key negotiation or authentication with a
+ server) is done with the &man.wpa.supplicant.8; utility.
+ This program requires a configuration file,
+ <filename>/etc/wpa_supplicant.conf</filename>, to run.
+ More information regarding this file can be found in the
+ &man.wpa.supplicant.conf.5; manual page.</para>
+
+ <sect5 xml:id="network-wireless-wpa-wpa-psk">
+ <title>WPA-PSK</title>
+
+ <para>WPA-PSK also known as WPA-Personal is based on a
+ pre-shared key (PSK) generated from a given password and
+ that will be used as the master key in the wireless
+ network. This means every wireless user will share the
+ same key. WPA-PSK is intended for small networks where
+ the use of an authentication server is not possible or
+ desired.</para>
+
+ <warning>
+ <para>Always use strong passwords that are
+ sufficiently long and made from a rich alphabet so
+ they will not be guessed and/or attacked.</para>
+ </warning>
+
+ <para>The first step is the configuration of the
+ <filename>/etc/wpa_supplicant.conf</filename> file with
+ the SSID and the pre-shared key of your network:</para>
+
+ <programlisting>network={
+ ssid="freebsdap"
+ psk="freebsdmall"
+}</programlisting>
+
+ <para>Then, in <filename>/etc/rc.conf</filename>, we
+ indicate that the wireless device configuration will be
+ done with WPA and the IP address will be obtained with
+ DHCP:</para>
+
+ <programlisting>ifconfig_ath0="WPA DHCP"</programlisting>
+
+ <para>Then, we can bring up the interface:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/netif start</userinput>
+Starting wpa_supplicant.
+DHCPDISCOVER on ath0 to 255.255.255.255 port 67 interval 5
+DHCPDISCOVER on ath0 to 255.255.255.255 port 67 interval 6
+DHCPOFFER from 192.168.0.1
+DHCPREQUEST on ath0 to 255.255.255.255 port 67
+DHCPACK from 192.168.0.1
+bound to 192.168.0.254 -- renewal in 300 seconds.
+ath0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet6 fe80::211:95ff:fed5:4362%ath0 prefixlen 64 scopeid 0x1
+ inet 192.168.0.254 netmask 0xffffff00 broadcast 192.168.0.255
+ ether 00:11:95:d5:43:62
+ media: IEEE 802.11 Wireless Ethernet autoselect (OFDM/36Mbps)
+ status: associated
+ ssid freebsdap channel 1 bssid 00:11:95:c3:0d:ac
+ authmode WPA privacy ON deftxkey UNDEF TKIP 2:128-bit txpowmax 36
+ protmode CTS roaming MANUAL bintval 100</screen>
+
+ <para>Or you can try to configure it manually using the
+ same <filename>/etc/wpa_supplicant.conf</filename> <link linkend="network-wireless-wpa-wpa-psk">above</link>, and
+ run:</para>
+
+ <screen>&prompt.root; <userinput>wpa_supplicant -i ath0 -c /etc/wpa_supplicant.conf</userinput>
+Trying to associate with 00:11:95:c3:0d:ac (SSID='freebsdap' freq=2412 MHz)
+Associated with 00:11:95:c3:0d:ac
+WPA: Key negotiation completed with 00:11:95:c3:0d:ac [PTK=TKIP GTK=TKIP]</screen>
+
+ <para>The next operation is the launch of the
+ <command>dhclient</command> command to get the IP
+ address from the DHCP server:</para>
+
+ <screen>&prompt.root; <userinput>dhclient ath0</userinput>
+DHCPREQUEST on ath0 to 255.255.255.255 port 67
+DHCPACK from 192.168.0.1
+bound to 192.168.0.254 -- renewal in 300 seconds.
+&prompt.root; <userinput>ifconfig ath0</userinput>
+ath0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet6 fe80::211:95ff:fed5:4362%ath0 prefixlen 64 scopeid 0x1
+ inet 192.168.0.254 netmask 0xffffff00 broadcast 192.168.0.255
+ ether 00:11:95:d5:43:62
+ media: IEEE 802.11 Wireless Ethernet autoselect (OFDM/48Mbps)
+ status: associated
+ ssid freebsdap channel 1 bssid 00:11:95:c3:0d:ac
+ authmode WPA privacy ON deftxkey UNDEF TKIP 2:128-bit txpowmax 36
+ protmode CTS roaming MANUAL bintval 100</screen>
+
+ <note>
+ <para>If the <filename>/etc/rc.conf</filename> is set up
+ with the line <literal>ifconfig_ath0="DHCP"</literal>
+ then it is no need to run the
+ <command>dhclient</command> command manually,
+ <command>dhclient</command> will be launched after
+ <command>wpa_supplicant</command> plumbs the
+ keys.</para>
+ </note>
+
+ <para>In the case where the use of DHCP is not possible,
+ you can set a static IP address after
+ <command>wpa_supplicant</command> has authenticated the
+ station:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0 inet 192.168.0.100 netmask 255.255.255.0</userinput>
+&prompt.root; <userinput>ifconfig ath0</userinput>
+ath0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet6 fe80::211:95ff:fed5:4362%ath0 prefixlen 64 scopeid 0x1
+ inet 192.168.0.100 netmask 0xffffff00 broadcast 192.168.0.255
+ ether 00:11:95:d5:43:62
+ media: IEEE 802.11 Wireless Ethernet autoselect (OFDM/36Mbps)
+ status: associated
+ ssid freebsdap channel 1 bssid 00:11:95:c3:0d:ac
+ authmode WPA privacy ON deftxkey UNDEF TKIP 2:128-bit txpowmax 36
+ protmode CTS roaming MANUAL bintval 100</screen>
+
+ <para>When DHCP is not used, you also have to manually set
+ up the default gateway and the nameserver:</para>
+
+ <screen>&prompt.root; <userinput>route add default your_default_router</userinput>
+&prompt.root; <userinput>echo "nameserver your_DNS_server" &gt;&gt; /etc/resolv.conf</userinput></screen>
+ </sect5>
+
+ <sect5 xml:id="network-wireless-wpa-eap-tls">
+ <title>WPA with EAP-TLS</title>
+
+ <para>The second way to use WPA is with an 802.1X backend
+ authentication server, in this case WPA is called
+ WPA-Enterprise to make difference with the less secure
+ WPA-Personal with its pre-shared key. The
+ authentication in WPA-Enterprise is based on EAP
+ (Extensible Authentication Protocol).</para>
+
+ <para>EAP does not come with an encryption method, it was
+ decided to embed EAP inside an encrypted tunnel. Many
+ types of EAP authentication methods have been designed,
+ the most common methods are EAP-TLS, EAP-TTLS and
+ EAP-PEAP.</para>
+
+ <para>EAP-TLS (EAP with Transport Layer Security) is a
+ very well-supported authentication protocol in the
+ wireless world since it was the first EAP method to be
+ certified by the <link xlink:href="http://www.wi-fi.org/">Wi-Fi alliance</link>.
+ EAP-TLS will require three certificates to run: the CA
+ certificate (installed on all machines), the server
+ certificate for your authentication server, and one
+ client certificate for each wireless client. In this
+ EAP method, both authentication server and wireless
+ client authenticate each other in presenting their
+ respective certificates, and they verify that these
+ certificates were signed by your organization's
+ certificate authority (CA).</para>
+
+ <para>As previously, the configuration is done via
+ <filename>/etc/wpa_supplicant.conf</filename>:</para>
+
+ <programlisting>network={
+ ssid="freebsdap" <co xml:id="co-tls-ssid"/>
+ proto=RSN <co xml:id="co-tls-proto"/>
+ key_mgmt=WPA-EAP <co xml:id="co-tls-kmgmt"/>
+ eap=TLS <co xml:id="co-tls-eap"/>
+ identity="loader" <co xml:id="co-tls-id"/>
+ ca_cert="/etc/certs/cacert.pem" <co xml:id="co-tls-cacert"/>
+ client_cert="/etc/certs/clientcert.pem" <co xml:id="co-tls-clientcert"/>
+ private_key="/etc/certs/clientkey.pem" <co xml:id="co-tls-pkey"/>
+ private_key_passwd="freebsdmallclient" <co xml:id="co-tls-pwd"/>
+}</programlisting>
+
+ <calloutlist>
+ <callout arearefs="co-tls-ssid">
+ <para>This field indicates the network name
+ (SSID).</para>
+ </callout>
+
+ <callout arearefs="co-tls-proto">
+ <para>Here, we use RSN (IEEE 802.11i) protocol, i.e.,
+ WPA2.</para>
+ </callout>
+
+ <callout arearefs="co-tls-kmgmt">
+ <para>The <literal>key_mgmt</literal> line refers to
+ the key management protocol we use. In our case it
+ is WPA using EAP authentication:
+ <literal>WPA-EAP</literal>.</para>
+ </callout>
+
+ <callout arearefs="co-tls-eap">
+ <para>In this field, we mention the EAP method for our
+ connection.</para>
+ </callout>
+
+ <callout arearefs="co-tls-id">
+ <para>The <literal>identity</literal> field contains
+ the identity string for EAP.</para>
+ </callout>
+
+ <callout arearefs="co-tls-cacert">
+ <para>The <literal>ca_cert</literal> field indicates
+ the pathname of the CA certificate file. This file
+ is needed to verify the server certificat.</para>
+ </callout>
+
+ <callout arearefs="co-tls-clientcert">
+ <para>The <literal>client_cert</literal> line gives
+ the pathname to the client certificate file. This
+ certificate is unique to each wireless client of the
+ network.</para>
+ </callout>
+
+ <callout arearefs="co-tls-pkey">
+ <para>The <literal>private_key</literal> field is the
+ pathname to the client certificate private key
+ file.</para>
+ </callout>
+
+ <callout arearefs="co-tls-pwd">
+ <para>The <literal>private_key_passwd</literal> field
+ contains the passphrase for the private key.</para>
+ </callout>
+ </calloutlist>
+
+ <para>Then add the following line to
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>ifconfig_ath0="WPA DHCP"</programlisting>
+
+ <para>The next step is to bring up the interface with the
+ help of the <filename>rc.d</filename> facility:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/netif start</userinput>
+Starting wpa_supplicant.
+DHCPREQUEST on ath0 to 255.255.255.255 port 67
+DHCPREQUEST on ath0 to 255.255.255.255 port 67
+DHCPACK from 192.168.0.20
+bound to 192.168.0.254 -- renewal in 300 seconds.
+ath0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet6 fe80::211:95ff:fed5:4362%ath0 prefixlen 64 scopeid 0x1
+ inet 192.168.0.254 netmask 0xffffff00 broadcast 192.168.0.255
+ ether 00:11:95:d5:43:62
+ media: IEEE 802.11 Wireless Ethernet autoselect (DS/11Mbps)
+ status: associated
+ ssid freebsdap channel 1 bssid 00:11:95:c3:0d:ac
+ authmode WPA2/802.11i privacy ON deftxkey UNDEF TKIP 2:128-bit
+ txpowmax 36 protmode CTS roaming MANUAL bintval 100</screen>
+
+ <para>As previously shown, it is also possible to bring up
+ the interface manually with both
+ <command>wpa_supplicant</command> and
+ <command>ifconfig</command> commands.</para>
+ </sect5>
+
+ <sect5 xml:id="network-wireless-wpa-eap-ttls">
+ <title>WPA with EAP-TTLS</title>
+
+ <para>With EAP-TLS both the authentication server and the
+ client need a certificate, with EAP-TTLS (EAP-Tunneled
+ Transport Layer Security) a client certificate is
+ optional. This method is close to what some secure web
+ sites do , where the web server can create a secure SSL
+ tunnel even if the visitors do not have client-side
+ certificates. EAP-TTLS will use the encrypted TLS
+ tunnel for safe transport of the authentication
+ data.</para>
+
+ <para>The configuration is done via the
+ <filename>/etc/wpa_supplicant.conf</filename>
+ file:</para>
+
+ <programlisting>network={
+ ssid="freebsdap"
+ proto=RSN
+ key_mgmt=WPA-EAP
+ eap=TTLS <co xml:id="co-ttls-eap"/>
+ identity="test" <co xml:id="co-ttls-id"/>
+ password="test" <co xml:id="co-ttls-passwd"/>
+ ca_cert="/etc/certs/cacert.pem" <co xml:id="co-ttls-cacert"/>
+ phase2="auth=MD5" <co xml:id="co-ttls-pha2"/>
+}</programlisting>
+
+ <calloutlist>
+ <callout arearefs="co-ttls-eap">
+ <para>In this field, we mention the EAP method for our
+ connection.</para>
+ </callout>
+
+ <callout arearefs="co-ttls-id">
+ <para>The <literal>identity</literal> field contains
+ the identity string for EAP authentication inside
+ the encrypted TLS tunnel.</para>
+ </callout>
+
+ <callout arearefs="co-ttls-passwd">
+ <para>The <literal>password</literal> field contains
+ the passphrase for the EAP authentication.</para>
+ </callout>
+
+ <callout arearefs="co-ttls-cacert">
+ <para>The <literal>ca_cert</literal> field indicates
+ the pathname of the CA certificate file. This file
+ is needed to verify the server certificat.</para>
+ </callout>
+
+ <callout arearefs="co-ttls-pha2">
+ <para>In this field, we mention the authentication
+ method used in the encrypted TLS tunnel. In our
+ case, EAP with MD5-Challenge has been used. The
+ <quote>inner authentication</quote> phase is often
+ called <quote>phase2</quote>.</para>
+ </callout>
+ </calloutlist>
+
+ <para>You also have to add the following line to
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>ifconfig_ath0="WPA DHCP"</programlisting>
+
+ <para>The next step is to bring up the interface:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/netif start</userinput>
+Starting wpa_supplicant.
+DHCPREQUEST on ath0 to 255.255.255.255 port 67
+DHCPREQUEST on ath0 to 255.255.255.255 port 67
+DHCPREQUEST on ath0 to 255.255.255.255 port 67
+DHCPACK from 192.168.0.20
+bound to 192.168.0.254 -- renewal in 300 seconds.
+ath0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet6 fe80::211:95ff:fed5:4362%ath0 prefixlen 64 scopeid 0x1
+ inet 192.168.0.254 netmask 0xffffff00 broadcast 192.168.0.255
+ ether 00:11:95:d5:43:62
+ media: IEEE 802.11 Wireless Ethernet autoselect (DS/11Mbps)
+ status: associated
+ ssid freebsdap channel 1 bssid 00:11:95:c3:0d:ac
+ authmode WPA2/802.11i privacy ON deftxkey UNDEF TKIP 2:128-bit
+ txpowmax 36 protmode CTS roaming MANUAL bintval 100</screen>
+ </sect5>
+
+ <sect5 xml:id="network-wireless-wpa-eap-peap">
+ <title>WPA with EAP-PEAP</title>
+
+ <para>PEAP (Protected EAP) has been designed as an
+ alternative to EAP-TTLS. There are two types of PEAP
+ methods, the most common one is PEAPv0/EAP-MSCHAPv2. In
+ the rest of this document, we will use the PEAP term to
+ refer to that EAP method. PEAP is the most used EAP
+ standard after EAP-TLS, in other words if you have a
+ network with mixed OSes, PEAP should be the most
+ supported standard after EAP-TLS.</para>
+
+ <para>PEAP is similar to EAP-TTLS: it uses a server-side
+ certificate to authenticate clients by creating an
+ encrypted TLS tunnel between the client and the
+ authentication server, which protects the ensuing
+ exchange of authentication information. In term of
+ security the difference between EAP-TTLS and PEAP is
+ that PEAP authentication broadcasts the username in
+ clear, only the password is sent in the encrypted TLS
+ tunnel. EAP-TTLS will use the TLS tunnel for both
+ username and password.</para>
+
+ <para>We have to edit the
+ <filename>/etc/wpa_supplicant.conf</filename> file and
+ add the EAP-PEAP related settings:</para>
+
+ <programlisting>network={
+ ssid="freebsdap"
+ proto=RSN
+ key_mgmt=WPA-EAP
+ eap=PEAP <co xml:id="co-peap-eap"/>
+ identity="test" <co xml:id="co-peap-id"/>
+ password="test" <co xml:id="co-peap-passwd"/>
+ ca_cert="/etc/certs/cacert.pem" <co xml:id="co-peap-cacert"/>
+ phase1="peaplabel=0" <co xml:id="co-peap-pha1"/>
+ phase2="auth=MSCHAPV2" <co xml:id="co-peap-pha2"/>
+}</programlisting>
+
+ <calloutlist>
+ <callout arearefs="co-peap-eap">
+ <para>In this field, we mention the EAP method for our
+ connection.</para>
+ </callout>
+
+ <callout arearefs="co-peap-id">
+ <para>The <literal>identity</literal> field contains
+ the identity string for EAP authentication inside
+ the encrypted TLS tunnel.</para>
+ </callout>
+
+ <callout arearefs="co-peap-passwd">
+ <para>The <literal>password</literal> field contains
+ the passphrase for the EAP authentication.</para>
+ </callout>
+
+ <callout arearefs="co-peap-cacert">
+ <para>The <literal>ca_cert</literal> field indicates
+ the pathname of the CA certificate file. This file
+ is needed to verify the server certificat.</para>
+ </callout>
+
+ <callout arearefs="co-peap-pha1">
+ <para>This field contains the parameters for the
+ first phase of the authentication (the TLS
+ tunnel). According to the authentication server
+ used, you will have to specify a specific label
+ for the authentication. Most of time, the label
+ will be <quote>client EAP encryption</quote> which
+ is set by using <literal>peaplabel=0</literal>.
+ More information can be found in the
+ &man.wpa.supplicant.conf.5; manual page.</para>
+ </callout>
+
+ <callout arearefs="co-peap-pha2">
+ <para>In this field, we mention the authentication
+ protocol used in the encrypted TLS tunnel. In the
+ case of PEAP, it is
+ <literal>auth=MSCHAPV2</literal>.</para>
+ </callout>
+ </calloutlist>
+
+ <para>The following must be added to
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>ifconfig_ath0="WPA DHCP"</programlisting>
+
+ <para>Then, we can bring up the interface:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/netif start</userinput>
+Starting wpa_supplicant.
+DHCPREQUEST on ath0 to 255.255.255.255 port 67
+DHCPREQUEST on ath0 to 255.255.255.255 port 67
+DHCPREQUEST on ath0 to 255.255.255.255 port 67
+DHCPACK from 192.168.0.20
+bound to 192.168.0.254 -- renewal in 300 seconds.
+ath0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet6 fe80::211:95ff:fed5:4362%ath0 prefixlen 64 scopeid 0x1
+ inet 192.168.0.254 netmask 0xffffff00 broadcast 192.168.0.255
+ ether 00:11:95:d5:43:62
+ media: IEEE 802.11 Wireless Ethernet autoselect (DS/11Mbps)
+ status: associated
+ ssid freebsdap channel 1 bssid 00:11:95:c3:0d:ac
+ authmode WPA2/802.11i privacy ON deftxkey UNDEF TKIP 2:128-bit
+ txpowmax 36 protmode CTS roaming MANUAL bintval 100</screen>
+ </sect5>
+ </sect4>
+
+ <sect4 xml:id="network-wireless-wep">
+ <title>WEP</title>
+
+ <para>WEP (Wired Equivalent Privacy) is part of the original
+ 802.11 standard. There is no authentication mechanism,
+ only a weak form of access control, and it is easily to be
+ cracked.</para>
+
+ <para>WEP can be set up with
+ <command>ifconfig</command>:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0 inet 192.168.1.100 netmask 255.255.255.0 ssid my_net \
+ wepmode on weptxkey 3 wepkey 3:0x3456789012</userinput></screen>
+
+ <itemizedlist>
+ <listitem>
+ <para>The <literal>weptxkey</literal> means which WEP
+ key will be used in the transmission. Here we used the
+ third key. This must match the setting in the access
+ point.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <literal>wepkey</literal> means setting the
+ selected WEP key. It should in the format
+ <replaceable>index:key</replaceable>, if the index is
+ not given, key <literal>1</literal> is set. That is
+ to say we need to set the index if we use keys other
+ than the first key.</para>
+
+ <note>
+ <para>You must replace
+ the <literal>0x3456789012</literal> with the key
+ configured for use on the access point.</para>
+ </note>
+ </listitem>
+ </itemizedlist>
+
+ <para>You are encouraged to read &man.ifconfig.8; manual
+ page for further information.</para>
+
+ <para>The <command>wpa_supplicant</command> facility also
+ can be used to configure your wireless interface with WEP.
+ The example above can be set up by adding the following
+ lines to
+ <filename>/etc/wpa_supplicant.conf</filename>:</para>
+
+ <programlisting>network={
+ ssid="my_net"
+ key_mgmt=NONE
+ wep_key3=3456789012
+ wep_tx_keyidx=3
+}</programlisting>
+
+ <para>Then:</para>
+
+ <screen>&prompt.root; <userinput>wpa_supplicant -i ath0 -c /etc/wpa_supplicant.conf</userinput>
+Trying to associate with 00:13:46:49:41:76 (SSID='dlinkap' freq=2437 MHz)
+Associated with 00:13:46:49:41:76</screen>
+ </sect4>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Ad-hoc Mode</title>
+
+ <para>IBSS mode, also called ad-hoc mode, is designed for point
+ to point connections. For example, to establish an ad-hoc
+ network between the machine <systemitem>A</systemitem> and the machine
+ <systemitem>B</systemitem> we will just need to choose two IP adresses
+ and a SSID.</para>
+
+ <para>On the box <systemitem>A</systemitem>:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0 inet 192.168.0.1 netmask 255.255.255.0 ssid freebsdap mediaopt adhoc</userinput>
+&prompt.root; <userinput>ifconfig ath0</userinput>
+ ath0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet 192.168.0.1 netmask 0xffffff00 broadcast 192.168.0.255
+ inet6 fe80::211:95ff:fec3:dac%ath0 prefixlen 64 scopeid 0x4
+ ether 00:11:95:c3:0d:ac
+ media: IEEE 802.11 Wireless Ethernet autoselect &lt;adhoc&gt; (autoselect &lt;adhoc&gt;)
+ status: associated
+ ssid freebsdap channel 2 bssid 02:11:95:c3:0d:ac
+ authmode OPEN privacy OFF txpowmax 36 protmode CTS bintval 100</screen>
+
+ <para>The <literal>adhoc</literal> parameter indicates the
+ interface is running in the IBSS mode.</para>
+
+ <para>On <systemitem>B</systemitem>, we should be able to detect
+ <systemitem>A</systemitem>:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0 up scan</userinput>
+ SSID BSSID CHAN RATE S:N INT CAPS
+ freebsdap 02:11:95:c3:0d:ac 2 54M 19:0 100 IS</screen>
+
+ <para>The <literal>I</literal> in the output confirms the
+ machine <systemitem>A</systemitem> is in ad-hoc mode. We just have to
+ configure <systemitem>B</systemitem> with a different IP
+ address:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0 inet 192.168.0.2 netmask 255.255.255.0 ssid freebsdap mediaopt adhoc</userinput>
+&prompt.root; <userinput>ifconfig ath0</userinput>
+ ath0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet6 fe80::211:95ff:fed5:4362%ath0 prefixlen 64 scopeid 0x1
+ inet 192.168.0.2 netmask 0xffffff00 broadcast 192.168.0.255
+ ether 00:11:95:d5:43:62
+ media: IEEE 802.11 Wireless Ethernet autoselect &lt;adhoc&gt; (autoselect &lt;adhoc&gt;)
+ status: associated
+ ssid freebsdap channel 2 bssid 02:11:95:c3:0d:ac
+ authmode OPEN privacy OFF txpowmax 36 protmode CTS bintval 100</screen>
+
+ <para>Both <systemitem>A</systemitem> and <systemitem>B</systemitem> are now
+ ready to exchange informations.</para>
+ </sect2>
+
+ <sect2 xml:id="network-wireless-ap">
+ <title>&os; Host Access Points</title>
+
+ <para>&os; can act as an Access Point (AP) which eliminates the
+ need to buy a hardware AP or run an ad-hoc network. This can be
+ particularly useful when your &os; machine is acting as a
+ gateway to another network (e.g., the Internet).</para>
+
+ <sect3 xml:id="network-wireless-ap-basic">
+ <title>Basic Settings</title>
+
+ <para>Before configuring your &os; machine as an AP, the
+ kernel must be configured with the appropriate wireless
+ networking support for your wireless card. You also have to
+ add the support for the security protocols you intend to
+ use. For more details, see <xref linkend="network-wireless-basic"/>.</para>
+
+ <note>
+ <para>The use of the NDIS driver wrapper and the &windows;
+ drivers do not allow currently the AP operation. Only
+ native &os; wireless drivers support AP mode.</para>
+ </note>
+
+ <para>Once the wireless networking support is loaded, you can
+ check if your wireless device supports the host-based access
+ point mode (also know as hostap mode):</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0 list caps</userinput>
+ath0=783ed0f&lt;WEP,TKIP,AES,AES_CCM,IBSS,HOSTAP,AHDEMO,TXPMGT,SHSLOT,SHPREAMBLE,MONITOR,TKIPMIC,WPA1,WPA2,BURST,WME&gt;</screen>
+
+ <para>This output displays the card capabilities; the
+ <literal>HOSTAP</literal> word confirms this wireless card
+ can act as an Access Point. Various supported ciphers are
+ also mentioned: WEP, TKIP, WPA2, etc., these informations
+ are important to know what security protocols could be set
+ on the Access Point.</para>
+
+ <para>The wireless device can now be put into hostap mode and
+ configured with the correct SSID and IP address:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0 ssid freebsdap mode 11g mediaopt hostap</userinput> inet <replaceable>192.168.0.1</replaceable> netmask <replaceable>255.255.255.0</replaceable></screen>
+
+ <para>Use again <command>ifconfig</command> to see the status
+ of the <filename>ath0</filename> interface:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0</userinput>
+ ath0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet 192.168.0.1 netmask 0xffffff00 broadcast 192.168.0.255
+ inet6 fe80::211:95ff:fec3:dac%ath0 prefixlen 64 scopeid 0x4
+ ether 00:11:95:c3:0d:ac
+ media: IEEE 802.11 Wireless Ethernet autoselect mode 11g &lt;hostap&gt;
+ status: associated
+ ssid freebsdap channel 1 bssid 00:11:95:c3:0d:ac
+ authmode OPEN privacy OFF txpowmax 38 bmiss 7 protmode CTS burst dtimperiod 1 bintval 100</screen>
+
+ <para>The <literal>hostap</literal> parameter indicates the
+ interface is running in the host-based access point
+ mode.</para>
+
+ <para>The interface configuration can be done automatically at
+ boot time by adding the following line to
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>ifconfig_ath0="ssid <replaceable>freebsdap</replaceable> mode 11g mediaopt hostap inet <replaceable>192.168.0.1</replaceable> netmask <replaceable>255.255.255.0</replaceable>"</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Host-based Access Point without Authentication or
+ Encryption</title>
+
+ <para>Although it is not recommended to run an AP without any
+ authentication or encryption, this is a simple way to check
+ if your AP is working. This configuration is also important
+ for debugging client issues.</para>
+
+ <para>Once the AP configured as previously shown, it is
+ possible from another wireless machine to initiate a scan to
+ find the AP:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0 up scan</userinput>
+SSID BSSID CHAN RATE S:N INT CAPS
+freebsdap 00:11:95:c3:0d:ac 1 54M 22:1 100 ES</screen>
+
+ <para>The client machine found the Access Point and can be
+ associated with it:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0 ssid freebsdap inet 192.168.0.2 netmask 255.255.255.0</userinput>
+&prompt.root; <userinput>ifconfig ath0</userinput>
+ ath0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet6 fe80::211:95ff:fed5:4362%ath0 prefixlen 64 scopeid 0x1
+ inet 192.168.0.2 netmask 0xffffff00 broadcast 192.168.0.255
+ ether 00:11:95:d5:43:62
+ media: IEEE 802.11 Wireless Ethernet autoselect (OFDM/54Mbps)
+ status: associated
+ ssid freebsdap channel 1 bssid 00:11:95:c3:0d:ac
+ authmode OPEN privacy OFF txpowmax 36 protmode CTS bintval 100</screen>
+ </sect3>
+
+ <sect3>
+ <title>WPA Host-based Access Point</title>
+
+ <para>This section will focus on setting up &os; Access Point
+ using the WPA security protocol. More details regarding WPA
+ and the configuration of WPA-based wireless clients can be
+ found in the <xref linkend="network-wireless-wpa"/>.</para>
+
+ <para>The <application>hostapd</application> daemon is used to
+ deal with client authentication and keys management on the
+ WPA enabled Access Point.</para>
+
+ <para>In the following, all the configuration operations will
+ be performed on the &os; machine acting as AP. Once the
+ AP is correctly working, <application>hostapd</application>
+ should be automatically enabled at boot with the following
+ line in <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>hostapd_enable="YES"</programlisting>
+
+ <para>Before trying to configure
+ <application>hostapd</application>, be sure you have done
+ the basic settings introduced in the <xref linkend="network-wireless-ap-basic"/>.</para>
+
+ <sect4>
+ <title>WPA-PSK</title>
+
+ <para>WPA-PSK is intended for small networks where the use
+ of an backend authentication server is not possible or
+ desired.</para>
+
+ <para>The configuration is done in the
+ <filename>/etc/hostapd.conf</filename> file:</para>
+
+ <programlisting>interface=ath0 <co xml:id="co-ap-wpapsk-iface"/>
+debug=1 <co xml:id="co-ap-wpapsk-dbug"/>
+ctrl_interface=/var/run/hostapd <co xml:id="co-ap-wpapsk-ciface"/>
+ctrl_interface_group=wheel <co xml:id="co-ap-wpapsk-cifacegrp"/>
+ssid=freebsdap <co xml:id="co-ap-wpapsk-ssid"/>
+wpa=1 <co xml:id="co-ap-wpapsk-wpa"/>
+wpa_passphrase=freebsdmall <co xml:id="co-ap-wpapsk-pass"/>
+wpa_key_mgmt=WPA-PSK <co xml:id="co-ap-wpapsk-kmgmt"/>
+wpa_pairwise=CCMP TKIP <co xml:id="co-ap-wpapsk-pwise"/></programlisting>
+
+ <calloutlist>
+ <callout arearefs="co-ap-wpapsk-iface">
+ <para>This field indicates the wireless interface used
+ for the Access Point.</para>
+ </callout>
+
+ <callout arearefs="co-ap-wpapsk-dbug">
+ <para>This field sets the level of verbosity during the
+ execution of <application>hostapd</application>. A
+ value of <literal>1</literal> represents the minimal
+ level.</para>
+ </callout>
+
+ <callout arearefs="co-ap-wpapsk-ciface">
+ <para>The <literal>ctrl_interface</literal> field gives
+ the pathname of the directory used by
+ <application>hostapd</application> to stores its
+ domain socket files for the communication with
+ external programs such as &man.hostapd.cli.8;. The
+ default value is used here.</para>
+ </callout>
+
+ <callout arearefs="co-ap-wpapsk-cifacegrp">
+ <para>The <literal>ctrl_interface_group</literal> line
+ sets the group (here, it is the
+ <systemitem class="groupname">wheel</systemitem> group) allowed to access
+ to the control interface files.</para>
+ </callout>
+
+ <callout arearefs="co-ap-wpapsk-ssid">
+ <para>This field sets the network name.</para>
+ </callout>
+
+ <callout arearefs="co-ap-wpapsk-wpa">
+ <para>The <literal>wpa</literal> field enables WPA and
+ specifies which WPA authentication protocol will be
+ required. A value of <literal>1</literal> configures the
+ AP for WPA-PSK.</para>
+ </callout>
+
+ <callout arearefs="co-ap-wpapsk-pass">
+ <para>The <literal>wpa_passphrase</literal> field
+ contains the ASCII passphrase for the WPA
+ authentication.</para>
+
+ <warning>
+ <para>Always use strong passwords that are
+ sufficiently long and made from a rich alphabet so
+ they will not be guessed and/or attacked.</para>
+ </warning>
+ </callout>
+
+ <callout arearefs="co-ap-wpapsk-kmgmt">
+ <para>The <literal>wpa_key_mgmt</literal> line refers to
+ the key management protocol we use. In our case it is
+ WPA-PSK.</para>
+ </callout>
+
+ <callout arearefs="co-ap-wpapsk-pwise">
+ <para>The <literal>wpa_pairwise</literal> field
+ indicates the set of accepted encryption algorithms by
+ the Access Point. Here both TKIP (WPA) and CCMP
+ (WPA2) ciphers are accepted. CCMP cipher is an
+ alternative to TKIP and that is strongly preferred
+ when possible; TKIP should be used solely for stations
+ incapable of doing CCMP.</para>
+ </callout>
+ </calloutlist>
+
+ <para>The next step is to start
+ <application>hostapd</application>:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/hostapd forcestart</userinput></screen>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0</userinput>
+ ath0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 2290
+ inet 192.168.0.1 netmask 0xffffff00 broadcast 192.168.0.255
+ inet6 fe80::211:95ff:fec3:dac%ath0 prefixlen 64 scopeid 0x4
+ ether 00:11:95:c3:0d:ac
+ media: IEEE 802.11 Wireless Ethernet autoselect mode 11g &lt;hostap&gt;
+ status: associated
+ ssid freebsdap channel 1 bssid 00:11:95:c3:0d:ac
+ authmode WPA2/802.11i privacy MIXED deftxkey 2 TKIP 2:128-bit txpowmax 36 protmode CTS dtimperiod 1 bintval 100</screen>
+
+ <para>The Access Point is running, the clients can now be
+ associated with it, see <xref linkend="network-wireless-wpa"/> for more details. It is
+ possible to see the stations associated with the AP using
+ the <command>ifconfig ath0 list
+ sta</command> command.</para>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>WEP Host-based Access Point</title>
+
+ <para>It is not recommended to use WEP for setting up an
+ Access Point since there is no authentication mechanism and
+ it is easily to be cracked. Some legacy wireless cards only
+ support WEP as security protocol, these cards will only
+ allow to set up AP without authentication or encryption or
+ using the WEP protocol.</para>
+
+ <para>The wireless device can now be put into hostap mode and
+ configured with the correct SSID and IP address:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0 ssid freebsdap wepmode on weptxkey 3 wepkey 3:0x3456789012 mode 11g mediaopt hostap \
+ inet 192.168.0.1 netmask 255.255.255.0</userinput></screen>
+
+ <itemizedlist>
+ <listitem>
+ <para>The <literal>weptxkey</literal> means which WEP
+ key will be used in the transmission. Here we used the
+ third key (note that the key numbering starts with
+ <literal>1</literal>). This parameter must be specified
+ to really encrypt the data.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <literal>wepkey</literal> means setting the
+ selected WEP key. It should in the format
+ <replaceable>index:key</replaceable>, if the index is
+ not given, key <literal>1</literal> is set. That is
+ to say we need to set the index if we use keys other
+ than the first key.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Use again <command>ifconfig</command> to see the status
+ of the <filename>ath0</filename> interface:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0</userinput>
+ ath0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet 192.168.0.1 netmask 0xffffff00 broadcast 192.168.0.255
+ inet6 fe80::211:95ff:fec3:dac%ath0 prefixlen 64 scopeid 0x4
+ ether 00:11:95:c3:0d:ac
+ media: IEEE 802.11 Wireless Ethernet autoselect mode 11g &lt;hostap&gt;
+ status: associated
+ ssid freebsdap channel 1 bssid 00:11:95:c3:0d:ac
+ authmode OPEN privacy ON deftxkey 3 wepkey 3:40-bit txpowmax 36 protmode CTS dtimperiod 1 bintval 100</screen>
+
+ <para>From another wireless machine, it is possible to initiate
+ a scan to find the AP:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig ath0 up scan</userinput>
+SSID BSSID CHAN RATE S:N INT CAPS
+freebsdap 00:11:95:c3:0d:ac 1 54M 22:1 100 EPS</screen>
+
+ <para>The client machine found the Access Point and can be
+ associated with it using the correct parameters (key, etc.),
+ see <xref linkend="network-wireless-wep"/> for more
+ details.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Troubleshooting</title>
+
+ <para>If you are having trouble with wireless networking, there
+ are a number of steps you can take to help troubleshoot the
+ problem.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>If you do not see the access point listed when
+ scanning be sure you have not configured your wireless
+ device to a limited set of channels.</para>
+ </listitem>
+
+ <listitem>
+ <para>If you cannot associate to an access point verify the
+ configuration of your station matches the one of the
+ access point. This includes the authentication scheme and
+ any security protocols. Simplify your configuration as
+ much as possible. If you are using a security protocol
+ such as WPA or WEP configure the access point for open
+ authentication and no security to see if you can get
+ traffic to pass.</para>
+ </listitem>
+
+ <listitem>
+ <para>Once you can associate to the access point diagnose
+ any security configuration using simple tools like
+ &man.ping.8;.</para>
+
+ <para>The <command>wpa_supplicant</command> has much
+ debugging support; try running it manually with the
+ <option>-dd</option> option and look at the system
+ logs.</para>
+ </listitem>
+
+ <listitem>
+ <para>There are also many lower-level debugging tools. You
+ can enable debugging messages in the 802.11 protocol
+ support layer using the <command>wlandebug</command>
+ program found in
+ <filename>/usr/src/tools/tools/net80211</filename>. For
+ example:</para>
+
+ <screen>&prompt.root; <userinput>wlandebug -i ath0 +scan+auth+debug+assoc</userinput>
+ net.wlan.0.debug: 0 =&gt; 0xc80000&lt;assoc,auth,scan&gt;</screen>
+
+ <para>can be used to enable console messages related to
+ scanning for access points and doing the 802.11 protocol
+ handshakes required to arrange communication.</para>
+
+ <para>There are also many useful statistics maintained by
+ the 802.11 layer; the <command>wlanstats</command> tool
+ will dump these informations. These statistics should
+ identify all errors identified by the 802.11 layer.
+ Beware however that some errors are identified in the
+ device drivers that lie below the 802.11 layer so they may
+ not show up. To diagnose device-specific problems you
+ need to refer to the drivers' documentation.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>If the above information does not help to clarify the
+ problem, please submit a problem report and include output
+ from the above tools.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-bluetooth">
+ <info><title>Bluetooth</title>
+ <authorgroup>
+ <author><personname><firstname>Pav</firstname><surname>Lucistnik</surname></personname><contrib>Written by </contrib><affiliation>
+ <address><email>pav@FreeBSD.org</email></address>
+ </affiliation></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>Bluetooth</primary></indexterm>
+ <sect2>
+ <title>Introduction</title>
+ <para>Bluetooth is a wireless technology for creating personal networks
+ operating in the 2.4 GHz unlicensed band, with a range of 10 meters.
+ Networks are usually formed ad-hoc from portable devices such as
+ cellular phones, handhelds and laptops. Unlike the other popular
+ wireless technology, Wi-Fi, Bluetooth offers higher level service
+ profiles, e.g. FTP-like file servers, file pushing, voice transport,
+ serial line emulation, and more.</para>
+
+ <para>The Bluetooth stack in &os; is implemented using the Netgraph
+ framework (see &man.netgraph.4;). A broad variety of Bluetooth USB
+ dongles is supported by the &man.ng.ubt.4; driver. The Broadcom BCM2033
+ chip based Bluetooth devices are supported via the &man.ubtbcmfw.4; and
+ &man.ng.ubt.4; drivers. The 3Com Bluetooth PC Card 3CRWB60-A is
+ supported by the &man.ng.bt3c.4; driver. Serial and UART based
+ Bluetooth devices are supported via &man.sio.4;, &man.ng.h4.4;
+ and &man.hcseriald.8;. This section describes the use of the USB
+ Bluetooth dongle.</para>
+ </sect2>
+
+ <sect2>
+ <title>Plugging in the Device</title>
+ <para>By default Bluetooth device drivers are available as kernel modules.
+ Before attaching a device, you will need to load the driver into the
+ kernel:</para>
+
+ <screen>&prompt.root; <userinput>kldload ng_ubt</userinput></screen>
+
+ <para>If the Bluetooth device is present in the system during system
+ startup, load the module from
+ <filename>/boot/loader.conf</filename>:</para>
+
+ <programlisting>ng_ubt_load="YES"</programlisting>
+
+ <para>Plug in your USB dongle. The output similar to the following will
+ appear on the console (or in syslog):</para>
+
+ <screen>ubt0: vendor 0x0a12 product 0x0001, rev 1.10/5.25, addr 2
+ubt0: Interface 0 endpoints: interrupt=0x81, bulk-in=0x82, bulk-out=0x2
+ubt0: Interface 1 (alt.config 5) endpoints: isoc-in=0x83, isoc-out=0x3,
+ wMaxPacketSize=49, nframes=6, buffer size=294</screen>
+
+ <note>
+ <para>The Bluetooth stack has to be started manually on &os; 6.0, and
+ on &os; 5.X before 5.5. It is done automatically from &man.devd.8;
+ on &os; 5.5, 6.1 and newer.</para>
+
+ <para>Copy
+ <filename>/usr/share/examples/netgraph/bluetooth/rc.bluetooth</filename>
+ into some convenient place, like <filename>/etc/rc.bluetooth</filename>.
+ This script is used to start and stop the Bluetooth stack. It is a good
+ idea to stop the stack before unplugging the device, but it is not
+ (usually) fatal. When starting the stack, you will receive output similar
+ to the following:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.bluetooth start ubt0</userinput>
+BD_ADDR: 00:02:72:00:d4:1a
+Features: 0xff 0xff 0xf 00 00 00 00 00
+&lt;3-Slot&gt; &lt;5-Slot&gt; &lt;Encryption&gt; &lt;Slot offset&gt;
+&lt;Timing accuracy&gt; &lt;Switch&gt; &lt;Hold mode&gt; &lt;Sniff mode&gt;
+&lt;Park mode&gt; &lt;RSSI&gt; &lt;Channel quality&gt; &lt;SCO link&gt;
+&lt;HV2 packets&gt; &lt;HV3 packets&gt; &lt;u-law log&gt; &lt;A-law log&gt; &lt;CVSD&gt;
+&lt;Paging scheme&gt; &lt;Power control&gt; &lt;Transparent SCO data&gt;
+Max. ACL packet size: 192 bytes
+Number of ACL packets: 8
+Max. SCO packet size: 64 bytes
+Number of SCO packets: 8</screen>
+ </note>
+
+ </sect2>
+
+ <sect2>
+ <title>Host Controller Interface (HCI)</title>
+
+ <indexterm><primary>HCI</primary></indexterm>
+
+ <para>Host Controller Interface (HCI) provides a command interface to the
+ baseband controller and link manager, and access to hardware status and
+ control registers. This interface provides a uniform method of accessing
+ the Bluetooth baseband capabilities. HCI layer on the Host exchanges
+ data and commands with the HCI firmware on the Bluetooth hardware.
+ The Host Controller Transport Layer (i.e. physical bus) driver provides
+ both HCI layers with the ability to exchange information with each
+ other.</para>
+
+ <para>A single Netgraph node of type <emphasis>hci</emphasis> is
+ created for a single Bluetooth device. The HCI node is normally
+ connected to the Bluetooth device driver node (downstream) and
+ the L2CAP node (upstream). All HCI operations must be performed
+ on the HCI node and not on the device driver node. Default name
+ for the HCI node is <quote>devicehci</quote>.
+ For more details refer to the &man.ng.hci.4; manual page.</para>
+
+ <para>One of the most common tasks is discovery of Bluetooth devices in
+ RF proximity. This operation is called <emphasis>inquiry</emphasis>.
+ Inquiry and other HCI related operations are done with the
+ &man.hccontrol.8; utility. The example below shows how to find out
+ which Bluetooth devices are in range. You should receive the list of
+ devices in a few seconds. Note that a remote device will only answer
+ the inquiry if it put into <emphasis>discoverable</emphasis>
+ mode.</para>
+
+ <screen>&prompt.user; <userinput>hccontrol -n ubt0hci inquiry</userinput>
+Inquiry result, num_responses=1
+Inquiry result #0
+ BD_ADDR: 00:80:37:29:19:a4
+ Page Scan Rep. Mode: 0x1
+ Page Scan Period Mode: 00
+ Page Scan Mode: 00
+ Class: 52:02:04
+ Clock offset: 0x78ef
+Inquiry complete. Status: No error [00]</screen>
+
+ <para><literal>BD_ADDR</literal> is unique address of a Bluetooth
+ device, similar to MAC addresses of a network card. This address
+ is needed for further communication with a device. It is possible
+ to assign human readable name to a BD_ADDR.
+ The <filename>/etc/bluetooth/hosts</filename> file contains information
+ regarding the known Bluetooth hosts. The following example shows how
+ to obtain human readable name that was assigned to the remote
+ device:</para>
+
+ <screen>&prompt.user; <userinput>hccontrol -n ubt0hci remote_name_request 00:80:37:29:19:a4</userinput>
+BD_ADDR: 00:80:37:29:19:a4
+Name: Pav's T39</screen>
+
+ <para>If you perform an inquiry on a remote Bluetooth device, it will
+ find your computer as <quote>your.host.name (ubt0)</quote>. The name
+ assigned to the local device can be changed at any time.</para>
+
+ <para>The Bluetooth system provides a point-to-point connection (only two
+ Bluetooth units involved), or a point-to-multipoint connection. In the
+ point-to-multipoint connection the connection is shared among several
+ Bluetooth devices. The following example shows how to obtain the list
+ of active baseband connections for the local device:</para>
+
+ <screen>&prompt.user; <userinput>hccontrol -n ubt0hci read_connection_list</userinput>
+Remote BD_ADDR Handle Type Mode Role Encrypt Pending Queue State
+00:80:37:29:19:a4 41 ACL 0 MAST NONE 0 0 OPEN</screen>
+
+ <para>A <emphasis>connection handle</emphasis> is useful when termination
+ of the baseband connection is required. Note, that it is normally not
+ required to do it by hand. The stack will automatically terminate
+ inactive baseband connections.</para>
+
+ <screen>&prompt.root; <userinput>hccontrol -n ubt0hci disconnect 41</userinput>
+Connection handle: 41
+Reason: Connection terminated by local host [0x16]</screen>
+
+ <para>Refer to <command>hccontrol help</command> for a complete listing
+ of available HCI commands. Most of the HCI commands do not require
+ superuser privileges.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>Logical Link Control and Adaptation Protocol (L2CAP)</title>
+
+ <indexterm><primary>L2CAP</primary></indexterm>
+
+ <para>Logical Link Control and Adaptation Protocol (L2CAP) provides
+ connection-oriented and connectionless data services to upper layer
+ protocols with protocol multiplexing capability and segmentation and
+ reassembly operation. L2CAP permits higher level protocols and
+ applications to transmit and receive L2CAP data packets up to 64
+ kilobytes in length.</para>
+
+ <para>L2CAP is based around the concept of <emphasis>channels</emphasis>.
+ Channel is a logical connection on top of baseband connection. Each
+ channel is bound to a single protocol in a many-to-one fashion. Multiple
+ channels can be bound to the same protocol, but a channel cannot be
+ bound to multiple protocols. Each L2CAP packet received on a channel is
+ directed to the appropriate higher level protocol. Multiple channels
+ can share the same baseband connection.</para>
+
+ <para>A single Netgraph node of type <emphasis>l2cap</emphasis> is
+ created for a single Bluetooth device. The L2CAP node is normally
+ connected to the Bluetooth HCI node (downstream) and Bluetooth sockets
+ nodes (upstream). Default name for the L2CAP node is
+ <quote>devicel2cap</quote>. For more details refer to the
+ &man.ng.l2cap.4; manual page.</para>
+
+ <para>A useful command is &man.l2ping.8;, which can be used to ping
+ other devices. Some Bluetooth implementations might not return all of
+ the data sent to them, so <literal>0 bytes</literal> in the following
+ example is normal.</para>
+
+ <screen>&prompt.root; <userinput>l2ping -a 00:80:37:29:19:a4</userinput>
+0 bytes from 0:80:37:29:19:a4 seq_no=0 time=48.633 ms result=0
+0 bytes from 0:80:37:29:19:a4 seq_no=1 time=37.551 ms result=0
+0 bytes from 0:80:37:29:19:a4 seq_no=2 time=28.324 ms result=0
+0 bytes from 0:80:37:29:19:a4 seq_no=3 time=46.150 ms result=0</screen>
+
+ <para>The &man.l2control.8; utility is used to perform various operations
+ on L2CAP nodes. This example shows how to obtain the list of logical
+ connections (channels) and the list of baseband connections for the
+ local device:</para>
+
+ <screen>&prompt.user; <userinput>l2control -a 00:02:72:00:d4:1a read_channel_list</userinput>
+L2CAP channels:
+Remote BD_ADDR SCID/ DCID PSM IMTU/ OMTU State
+00:07:e0:00:0b:ca 66/ 64 3 132/ 672 OPEN
+&prompt.user; <userinput>l2control -a 00:02:72:00:d4:1a read_connection_list</userinput>
+L2CAP connections:
+Remote BD_ADDR Handle Flags Pending State
+00:07:e0:00:0b:ca 41 O 0 OPEN</screen>
+
+ <para>Another diagnostic tool is &man.btsockstat.1;. It does a job
+ similar to as &man.netstat.1; does, but for Bluetooth network-related
+ data structures. The example below shows the same logical connection as
+ &man.l2control.8; above.</para>
+
+ <screen>&prompt.user; <userinput>btsockstat</userinput>
+Active L2CAP sockets
+PCB Recv-Q Send-Q Local address/PSM Foreign address CID State
+c2afe900 0 0 00:02:72:00:d4:1a/3 00:07:e0:00:0b:ca 66 OPEN
+Active RFCOMM sessions
+L2PCB PCB Flag MTU Out-Q DLCs State
+c2afe900 c2b53380 1 127 0 Yes OPEN
+Active RFCOMM sockets
+PCB Recv-Q Send-Q Local address Foreign address Chan DLCI State
+c2e8bc80 0 250 00:02:72:00:d4:1a 00:07:e0:00:0b:ca 3 6 OPEN</screen>
+
+ </sect2>
+
+ <sect2>
+ <title>RFCOMM Protocol</title>
+
+ <indexterm><primary>RFCOMM</primary></indexterm>
+
+ <para>The RFCOMM protocol provides emulation of serial ports over the
+ L2CAP protocol. The protocol is based on the ETSI standard TS 07.10.
+ RFCOMM is a simple transport protocol, with additional provisions for
+ emulating the 9 circuits of RS-232 (EIATIA-232-E) serial ports. The
+ RFCOMM protocol supports up to 60 simultaneous connections (RFCOMM
+ channels) between two Bluetooth devices.</para>
+
+ <para>For the purposes of RFCOMM, a complete communication path involves
+ two applications running on different devices (the communication
+ endpoints) with a communication segment between them. RFCOMM is intended
+ to cover applications that make use of the serial ports of the devices
+ in which they reside. The communication segment is a Bluetooth link from
+ one device to another (direct connect).</para>
+
+ <para>RFCOMM is only concerned with the connection between the devices in
+ the direct connect case, or between the device and a modem in the
+ network case. RFCOMM can support other configurations, such as modules
+ that communicate via Bluetooth wireless technology on one side and
+ provide a wired interface on the other side.</para>
+
+ <para>In &os; the RFCOMM protocol is implemented at the Bluetooth sockets
+ layer.</para>
+ </sect2>
+
+ <sect2>
+ <title>Pairing of Devices</title>
+
+ <indexterm><primary>pairing</primary></indexterm>
+
+ <para>By default, Bluetooth communication is not authenticated, and any
+ device can talk to any other device. A Bluetooth device (for example,
+ cellular phone) may choose to require authentication to provide a
+ particular service (for example, Dial-Up service). Bluetooth
+ authentication is normally done with <emphasis>PIN codes</emphasis>.
+ A PIN code is an ASCII string up to 16 characters in length. User is
+ required to enter the same PIN code on both devices. Once user has
+ entered the PIN code, both devices will generate a
+ <emphasis>link key</emphasis>. After that the link key can be stored
+ either in the devices themselves or in a persistent storage. Next time
+ both devices will use previously generated link key. The described
+ above procedure is called <emphasis>pairing</emphasis>. Note that if
+ the link key is lost by any device then pairing must be repeated.</para>
+
+ <para>The &man.hcsecd.8; daemon is responsible for handling of all
+ Bluetooth authentication requests. The default configuration file is
+ <filename>/etc/bluetooth/hcsecd.conf</filename>. An example section for
+ a cellular phone with the PIN code arbitrarily set to
+ <quote>1234</quote> is shown below:</para>
+
+ <programlisting>device {
+ bdaddr 00:80:37:29:19:a4;
+ name "Pav's T39";
+ key nokey;
+ pin "1234";
+ }</programlisting>
+
+ <para>There is no limitation on PIN codes (except length). Some devices
+ (for example Bluetooth headsets) may have a fixed PIN code built in.
+ The <option>-d</option> switch forces the &man.hcsecd.8; daemon to stay
+ in the foreground, so it is easy to see what is happening. Set the
+ remote device to receive pairing and initiate the Bluetooth connection
+ to the remote device. The remote device should say that pairing was
+ accepted, and request the PIN code. Enter the same PIN code as you
+ have in <filename>hcsecd.conf</filename>. Now your PC and the remote
+ device are paired. Alternatively, you can initiate pairing on the remote
+ device.</para>
+
+ <para>On &os; 5.5, 6.1 and newer, the following line can be added to the
+ <filename>/etc/rc.conf</filename> file to have
+ <application>hcsecd</application> started automatically on system
+ start:</para>
+
+ <programlisting>hcsecd_enable="YES"</programlisting>
+
+ <para>The following is a sample of the
+ <application>hcsecd</application> daemon output:</para>
+
+<programlisting>hcsecd[16484]: Got Link_Key_Request event from 'ubt0hci', remote bdaddr 0:80:37:29:19:a4
+hcsecd[16484]: Found matching entry, remote bdaddr 0:80:37:29:19:a4, name 'Pav's T39', link key doesn't exist
+hcsecd[16484]: Sending Link_Key_Negative_Reply to 'ubt0hci' for remote bdaddr 0:80:37:29:19:a4
+hcsecd[16484]: Got PIN_Code_Request event from 'ubt0hci', remote bdaddr 0:80:37:29:19:a4
+hcsecd[16484]: Found matching entry, remote bdaddr 0:80:37:29:19:a4, name 'Pav's T39', PIN code exists
+hcsecd[16484]: Sending PIN_Code_Reply to 'ubt0hci' for remote bdaddr 0:80:37:29:19:a4</programlisting>
+
+ </sect2>
+
+ <sect2>
+ <title>Service Discovery Protocol (SDP)</title>
+
+ <indexterm><primary>SDP</primary></indexterm>
+
+ <para>The Service Discovery Protocol (SDP) provides the means for client
+ applications to discover the existence of services provided by server
+ applications as well as the attributes of those services. The attributes
+ of a service include the type or class of service offered and the
+ mechanism or protocol information needed to utilize the service.</para>
+
+ <para>SDP involves communication between a SDP server and a SDP client.
+ The server maintains a list of service records that describe the
+ characteristics of services associated with the server. Each service
+ record contains information about a single service. A client may
+ retrieve information from a service record maintained by the SDP server
+ by issuing a SDP request. If the client, or an application associated
+ with the client, decides to use a service, it must open a separate
+ connection to the service provider in order to utilize the service.
+ SDP provides a mechanism for discovering services and their attributes,
+ but it does not provide a mechanism for utilizing those services.</para>
+
+ <para>Normally, a SDP client searches for services based on some desired
+ characteristics of the services. However, there are times when it is
+ desirable to discover which types of services are described by an SDP
+ server's service records without any a priori information about the
+ services. This process of looking for any offered services is called
+ <emphasis>browsing</emphasis>.</para>
+
+ <para>The Bluetooth SDP server &man.sdpd.8; and command line client
+ &man.sdpcontrol.8; are included in the standard &os; installation.
+ The following example shows how to perform a SDP browse query.</para>
+
+ <screen>&prompt.user; <userinput>sdpcontrol -a 00:01:03:fc:6e:ec browse</userinput>
+Record Handle: 00000000
+Service Class ID List:
+ Service Discovery Server (0x1000)
+Protocol Descriptor List:
+ L2CAP (0x0100)
+ Protocol specific parameter #1: u/int/uuid16 1
+ Protocol specific parameter #2: u/int/uuid16 1
+
+Record Handle: 0x00000001
+Service Class ID List:
+ Browse Group Descriptor (0x1001)
+
+Record Handle: 0x00000002
+Service Class ID List:
+ LAN Access Using PPP (0x1102)
+Protocol Descriptor List:
+ L2CAP (0x0100)
+ RFCOMM (0x0003)
+ Protocol specific parameter #1: u/int8/bool 1
+Bluetooth Profile Descriptor List:
+ LAN Access Using PPP (0x1102) ver. 1.0
+</screen>
+
+ <para>... and so on. Note that each service has a list of attributes
+ (RFCOMM channel for example). Depending on the service you might need to
+ make a note of some of the attributes. Some Bluetooth implementations do
+ not support service browsing and may return an empty list. In this case
+ it is possible to search for the specific service. The example below
+ shows how to search for the OBEX Object Push (OPUSH) service:</para>
+
+ <screen>&prompt.user; <userinput>sdpcontrol -a 00:01:03:fc:6e:ec search OPUSH</userinput></screen>
+
+ <para>Offering services on &os; to Bluetooth clients is done with the
+ &man.sdpd.8; server. On &os; 5.5, 6.1 and newer, the following line can
+ be added to the <filename>/etc/rc.conf</filename> file:</para>
+
+ <programlisting>sdpd_enable="YES"</programlisting>
+
+ <para>Then the <application>sdpd</application> daemon can be started with:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/sdpd start</userinput></screen>
+
+ <para>On &os; 6.0, and on &os; 5.X before 5.5,
+ <application>sdpd</application> is not integrated into the system
+ startup scripts. It has to be started manually with:</para>
+
+ <screen>&prompt.root; <userinput>sdpd</userinput></screen>
+
+ <para>The local server application that wants to provide Bluetooth
+ service to the remote clients will register service with the local
+ SDP daemon. The example of such application is &man.rfcomm.pppd.8;.
+ Once started it will register Bluetooth LAN service with the local
+ SDP daemon.</para>
+
+ <para>The list of services registered with the local SDP server can be
+ obtained by issuing SDP browse query via local control channel:</para>
+
+ <screen>&prompt.root; <userinput>sdpcontrol -l browse</userinput></screen>
+
+ </sect2>
+
+ <sect2>
+ <title>Dial-Up Networking (DUN) and Network Access with PPP (LAN)
+ Profiles</title>
+
+ <para>The Dial-Up Networking (DUN) profile is mostly used with modems
+ and cellular phones. The scenarios covered by this profile are the
+ following:</para>
+
+ <itemizedlist>
+ <listitem><para>use of a cellular phone or modem by a computer as
+ a wireless modem for connecting to a dial-up Internet access server,
+ or using other dial-up services;</para></listitem>
+
+ <listitem><para>use of a cellular phone or modem by a computer to
+ receive data calls.</para></listitem>
+ </itemizedlist>
+
+ <para>Network Access with PPP (LAN) profile can be used in the following
+ situations:</para>
+
+ <itemizedlist>
+ <listitem><para>LAN access for a single Bluetooth device;
+ </para></listitem>
+
+ <listitem><para>LAN access for multiple Bluetooth devices;
+ </para></listitem>
+
+ <listitem><para>PC to PC (using PPP networking over serial cable
+ emulation).</para></listitem>
+ </itemizedlist>
+
+ <para>In &os; both profiles are implemented with &man.ppp.8; and
+ &man.rfcomm.pppd.8; - a wrapper that converts RFCOMM Bluetooth
+ connection into something PPP can operate with. Before any profile
+ can be used, a new PPP label in the <filename>/etc/ppp/ppp.conf</filename>
+ must be created. Consult &man.rfcomm.pppd.8; manual page for examples.
+ </para>
+
+ <para>In the following example &man.rfcomm.pppd.8; will be used to open
+ RFCOMM connection to remote device with BD_ADDR 00:80:37:29:19:a4 on
+ DUN RFCOMM channel. The actual RFCOMM channel number will be obtained
+ from the remote device via SDP. It is possible to specify RFCOMM channel
+ by hand, and in this case &man.rfcomm.pppd.8; will not perform SDP
+ query. Use &man.sdpcontrol.8; to find out RFCOMM
+ channel on the remote device.</para>
+
+ <screen>&prompt.root; <userinput>rfcomm_pppd -a 00:80:37:29:19:a4 -c -C dun -l rfcomm-dialup</userinput></screen>
+
+ <para>In order to provide Network Access with PPP (LAN) service the
+ &man.sdpd.8; server must be running. A new entry for LAN clients must
+ be created in the <filename>/etc/ppp/ppp.conf</filename> file. Consult
+ &man.rfcomm.pppd.8; manual page for examples. Finally, start RFCOMM PPP
+ server on valid RFCOMM channel number. The RFCOMM PPP server will
+ automatically register Bluetooth LAN service with the local SDP daemon.
+ The example below shows how to start RFCOMM PPP server.</para>
+
+ <screen>&prompt.root; <userinput>rfcomm_pppd -s -C 7 -l rfcomm-server</userinput></screen>
+
+ </sect2>
+
+ <sect2>
+ <title>OBEX Object Push (OPUSH) Profile</title>
+
+ <indexterm><primary>OBEX</primary></indexterm>
+
+ <para>OBEX is a widely used protocol for simple file transfers between
+ mobile devices. Its main use is in infrared communication, where it is
+ used for generic file transfers between notebooks or PDAs,
+ and for sending business cards or calendar entries between cellular
+ phones and other devices with PIM applications.</para>
+
+ <para>The OBEX server and client are implemented as a third-party package
+ <application>obexapp</application>, which is available as
+ <package>comms/obexapp</package> port.</para>
+
+ <para>OBEX client is used to push and/or pull objects from the OBEX server.
+ An object can, for example, be a business card or an appointment.
+ The OBEX client can obtain RFCOMM channel number from the remote device
+ via SDP. This can be done by specifying service name instead of RFCOMM
+ channel number. Supported service names are: IrMC, FTRN and OPUSH.
+ It is possible to specify RFCOMM channel as a number. Below is an
+ example of an OBEX session, where device information object is pulled
+ from the cellular phone, and a new object (business card) is pushed
+ into the phone's directory.</para>
+
+ <screen>&prompt.user; <userinput>obexapp -a 00:80:37:29:19:a4 -C IrMC</userinput>
+obex&gt; get telecom/devinfo.txt devinfo-t39.txt
+Success, response: OK, Success (0x20)
+obex&gt; put new.vcf
+Success, response: OK, Success (0x20)
+obex&gt; di
+Success, response: OK, Success (0x20)</screen>
+
+ <para>In order to provide OBEX Object Push service,
+ &man.sdpd.8; server must be running. A root folder, where all incoming
+ objects will be stored, must be created. The default path to the root
+ folder is <filename>/var/spool/obex</filename>. Finally, start OBEX
+ server on valid RFCOMM channel number. The OBEX server will
+ automatically register OBEX Object Push service with the local SDP
+ daemon. The example below shows how to start OBEX server.</para>
+
+ <screen>&prompt.root; <userinput>obexapp -s -C 10</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Serial Port Profile (SPP)</title>
+ <para>The Serial Port Profile (SPP) allows Bluetooth devices to perform
+ RS232 (or similar) serial cable emulation. The scenario covered by this
+ profile deals with legacy applications using Bluetooth as a cable
+ replacement, through a virtual serial port abstraction.</para>
+
+ <para>The &man.rfcomm.sppd.1; utility implements the Serial Port profile.
+ A pseudo tty is used as a virtual serial port abstraction. The example
+ below shows how to connect to a remote device Serial Port service.
+ Note that you do not have to specify a RFCOMM channel -
+ &man.rfcomm.sppd.1; can obtain it from the remote device via SDP.
+ If you would like to override this, specify a RFCOMM channel on the
+ command line.</para>
+
+ <screen>&prompt.root; <userinput>rfcomm_sppd -a 00:07:E0:00:0B:CA -t /dev/ttyp6</userinput>
+rfcomm_sppd[94692]: Starting on /dev/ttyp6...</screen>
+
+ <para>Once connected, the pseudo tty can be used as serial port:</para>
+
+ <screen>&prompt.root; <userinput>cu -l ttyp6</userinput></screen>
+
+ </sect2>
+
+ <sect2>
+ <title>Troubleshooting</title>
+
+ <sect3>
+ <title>A remote device cannot connect</title>
+ <para>Some older Bluetooth devices do not support role switching.
+ By default, when &os; is accepting a new connection, it tries to
+ perform a role switch and become master. Devices, which do not
+ support this will not be able to connect. Note that role switching is
+ performed when a new connection is being established, so it is not
+ possible to ask the remote device if it does support role switching.
+ There is a HCI option to disable role switching on the local
+ side:</para>
+
+ <screen>&prompt.root; <userinput>hccontrol -n ubt0hci write_node_role_switch 0</userinput></screen>
+
+ </sect3>
+
+ <sect3>
+ <title>Something is going wrong, can I see what exactly is happening?</title>
+ <para>Yes, you can. Use the third-party package
+ <application>hcidump</application>, which is available as
+ <package>comms/hcidump</package> port.
+ The <application>hcidump</application> utility is similar to
+ &man.tcpdump.1;. It can be used to display the content of the Bluetooth
+ packets on the terminal and to dump the Bluetooth packets to a
+ file.</para>
+ </sect3>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="network-bridging">
+ <info><title>Bridging</title>
+ <authorgroup>
+ <author><personname><firstname>Andrew</firstname><surname>Thompson</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <sect2>
+ <title>Introduction</title>
+ <indexterm><primary>IP subnet</primary></indexterm>
+ <indexterm><primary>bridge</primary></indexterm>
+ <para>It is sometimes useful to divide one physical network
+ (such as an Ethernet segment) into two separate network
+ segments without having to create IP subnets and use a router
+ to connect the segments together. A device that connects two
+ networks together in this fashion is called a
+ <quote>bridge</quote>. A FreeBSD system with two network
+ interface cards can act as a bridge.</para>
+
+ <para>The bridge works by learning the MAC layer addresses
+ (Ethernet addresses) of the devices on each of its network interfaces.
+ It forwards traffic between two networks only when its source and
+ destination are on different networks.</para>
+
+ <para>In many respects, a bridge is like an Ethernet switch with very
+ few ports.</para>
+ </sect2>
+
+ <sect2>
+ <title>Situations Where Bridging Is Appropriate</title>
+
+ <para>There are many common situations in which a bridge is used
+ today.</para>
+
+ <sect3>
+ <title>Connecting Networks</title>
+
+ <para>The basic operation of a bridge is to join two or more
+ network segments together. There are many reasons to use a
+ host based bridge over plain networking equipment such as
+ cabling constraints, firewalling or connecting pseudo
+ networks such as a Virtual Machine interface. A bridge can
+ also connect a wireless interface running in hostap mode to
+ a wired network and act as an access point.</para>
+ </sect3>
+
+ <sect3>
+ <title>Filtering/Traffic Shaping Firewall</title>
+ <indexterm><primary>firewall</primary></indexterm>
+ <indexterm><primary>NAT</primary></indexterm>
+
+ <para>A common situation is where firewall functionality is
+ needed without routing or network address translation (NAT).</para>
+
+ <para>An example is a small company that is connected via DSL
+ or ISDN to their ISP. They have a 13 globally-accessible IP
+ addresses from their ISP and have 10 PCs on their network.
+ In this situation, using a router-based firewall is
+ difficult because of subnetting issues.</para>
+
+ <indexterm><primary>router</primary></indexterm>
+ <indexterm><primary>DSL</primary></indexterm>
+ <indexterm><primary>ISDN</primary></indexterm>
+ <para>A bridge-based firewall can be configured and dropped into the
+ path just downstream of their DSL/ISDN router without any IP
+ numbering issues.</para>
+ </sect3>
+
+ <sect3>
+ <title>Network Tap</title>
+
+ <para>A bridge can join two network segments and be used to
+ inspect all Ethernet frames that pass between them. This can
+ either be from using &man.bpf.4;/&man.tcpdump.1; on the
+ bridge interface or by sending a copy of all frames out an
+ additional interface (span port).</para>
+ </sect3>
+
+ <sect3>
+ <title>Layer 2 VPN</title>
+
+ <para>Two Ethernet networks can be joined across an IP link by
+ bridging the networks to an EtherIP tunnel or a &man.tap.4;
+ based solution such as OpenVPN.</para>
+ </sect3>
+
+ <sect3>
+ <title>Layer 2 Redundancy</title>
+
+ <para>A network can be connected together with multiple links
+ and use the Spanning Tree Protocol to block redundant paths.
+ For an Ethernet network to function properly only one active
+ path can exist between two devices, Spanning Tree will
+ detect loops and put the redundant links into a blocked
+ state. Should one of the active links fail then the
+ protocol will calculate a different tree and reenable one of
+ the blocked paths to restore connectivity to all points in
+ the network.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Kernel Configuration</title>
+
+ <para>This section covers &man.if.bridge.4; bridge
+ implementation, a netgraph bridging driver is also available,
+ for more information see &man.ng.bridge.4; manual page.</para>
+
+ <para>The bridge driver is a kernel module and will be
+ automatically loaded by &man.ifconfig.8; when creating a
+ bridge interface. It is possible to compile the bridge in to
+ the kernel by adding <literal>device if_bridge</literal> to
+ your kernel configuration file.</para>
+
+ <para>Packet filtering can be used with any firewall package
+ that hooks in via the &man.pfil.9; framework. The firewall
+ can be loaded as a module or compiled into the kernel.</para>
+
+ <para>The bridge can be used as a traffic shaper with
+ &man.altq.4; or &man.dummynet.4;.</para>
+ </sect2>
+
+ <sect2>
+ <title>Enabling the Bridge</title>
+
+ <para>The bridge is created using interface cloning. To create
+ a bridge use &man.ifconfig.8;, if the bridge driver is not
+ present in the kernel then it will be loaded
+ automatically.</para>
+
+ <screen>&prompt.root; <userinput>ifconfig bridge create</userinput>
+bridge0
+&prompt.root; <userinput>ifconfig bridge0</userinput>
+bridge0: flags=8802&lt;BROADCAST,SIMPLEX,MULTICAST&gt; metric 0 mtu 1500
+ ether 96:3d:4b:f1:79:7a
+ id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
+ maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
+ root id 00:00:00:00:00:00 priority 0 ifcost 0 port 0</screen>
+
+ <para>A bridge interface is created and is automatically
+ assigned a randomly generated Ethernet address. The
+ <literal>maxaddr</literal> and <literal>timeout</literal>
+ parameters control how many MAC addresses the bridge will keep
+ in its forwarding table and how many seconds before each entry
+ is removed after it is last seen. The other parameters
+ control how Spanning Tree operates.</para>
+
+ <para>Add the member network interfaces to the bridge. For the
+ bridge to forward packets all member interfaces and the bridge
+ need to be up:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig bridge0 addm fxp0 addm fxp1 up</userinput>
+&prompt.root; <userinput>ifconfig fxp0 up</userinput>
+&prompt.root; <userinput>ifconfig fxp1 up</userinput></screen>
+
+ <para>The bridge is now forwarding Ethernet frames between
+ <filename>fxp0</filename> and
+ <filename>fxp1</filename>. The equivalent configuration
+ in <filename>/etc/rc.conf</filename> so the bridge is created
+ at startup is:</para>
+
+ <programlisting>cloned_interfaces="bridge0"
+ifconfig_bridge0="addm fxp0 addm fxp1 up"
+ifconfig_fxp0="up"
+ifconfig_fxp1="up"</programlisting>
+
+ <para>If the bridge host needs an IP address then the correct
+ place to set this is on the bridge interface itself rather
+ than one of the member interfaces. This can be set statically
+ or via DHCP:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig bridge0 inet 192.168.0.1/24</userinput></screen>
+
+ <para>It is also possible to assign an IPv6 address to a bridge
+ interface.</para>
+ </sect2>
+
+ <sect2>
+ <title>Firewalling</title>
+ <indexterm><primary>firewall</primary></indexterm>
+
+ <para>When packet filtering is enabled, bridged packets will
+ pass through the filter inbound on the originating interface,
+ on the bridge interface and outbound on the appropriate
+ interfaces. Either stage can be disabled. When direction of
+ the packet flow is important it is best to firewall on the
+ member interfaces rather than the bridge itself.</para>
+
+ <para>The bridge has several configurable settings for passing
+ non-IP and ARP packets, and layer2 firewalling with IPFW. See
+ &man.if.bridge.4; for more information.</para>
+ </sect2>
+
+ <sect2>
+ <title>Spanning Tree</title>
+
+ <para>The bridge driver implements the Rapid Spanning Tree
+ Protocol (RSTP or 802.1w) with backwards compatibility with
+ the legacy Spanning Tree Protocol (STP). Spanning Tree is
+ used to detect and remove loops in a network topology. RSTP
+ provides faster Spanning Tree convergence than legacy STP, the
+ protocol will exchange information with neighbouring switches
+ to quickly transition to forwarding without creating
+ loops.</para>
+
+ <para>The following table shows the supported operating
+ modes:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>OS Version</entry>
+ <entry>STP Modes</entry>
+ <entry>Default Mode</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>&os; 5.4&mdash;&os; 6.2</entry>
+ <entry>STP</entry>
+ <entry>STP</entry>
+ </row>
+
+ <row>
+ <entry>&os; 6.3+</entry>
+ <entry>RSTP or STP</entry>
+ <entry>STP</entry>
+ </row>
+
+ <row>
+ <entry>&os; 7.0+</entry>
+ <entry>RSTP or STP</entry>
+ <entry>RSTP</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>Spanning Tree can be enabled on member interfaces using
+ the <literal>stp</literal> command. For a bridge with
+ <filename>fxp0</filename> and
+ <filename>fxp1</filename> as the current interfaces,
+ enable STP with the following:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig bridge0 stp fxp0 stp fxp1</userinput>
+bridge0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; metric 0 mtu 1500
+ ether d6:cf:d5:a0:94:6d
+ id 00:01:02:4b:d4:50 priority 32768 hellotime 2 fwddelay 15
+ maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
+ root id 00:01:02:4b:d4:50 priority 32768 ifcost 0 port 0
+ member: fxp0 flags=1c7&lt;LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP&gt;
+ port 3 priority 128 path cost 200000 proto rstp
+ role designated state forwarding
+ member: fxp1 flags=1c7&lt;LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP&gt;
+ port 4 priority 128 path cost 200000 proto rstp
+ role designated state forwarding</screen>
+
+ <para>This bridge has a spanning tree ID of
+ <literal>00:01:02:4b:d4:50</literal> and a priority of
+ <literal>32768</literal>. As the <literal>root id</literal>
+ is the same it indicates that this is the root bridge for the
+ tree.</para>
+
+ <para>Another bridge on the network also has spanning tree
+ enabled:</para>
+
+ <screen>bridge0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; metric 0 mtu 1500
+ ether 96:3d:4b:f1:79:7a
+ id 00:13:d4:9a:06:7a priority 32768 hellotime 2 fwddelay 15
+ maxage 20 holdcnt 6 proto rstp maxaddr 100 timeout 1200
+ root id 00:01:02:4b:d4:50 priority 32768 ifcost 400000 port 4
+ member: fxp0 flags=1c7&lt;LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP&gt;
+ port 4 priority 128 path cost 200000 proto rstp
+ role root state forwarding
+ member: fxp1 flags=1c7&lt;LEARNING,DISCOVER,STP,AUTOEDGE,PTP,AUTOPTP&gt;
+ port 5 priority 128 path cost 200000 proto rstp
+ role designated state forwarding</screen>
+
+ <para>The line <literal>root id 00:01:02:4b:d4:50 priority 32768
+ ifcost 400000 port 4</literal> shows that the root bridge is
+ <literal>00:01:02:4b:d4:50</literal> as above and has a path
+ cost of <literal>400000</literal> from this bridge, the path
+ to the root bridge is via <literal>port 4</literal> which is
+ <filename>fxp0</filename>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Advanced Bridging</title>
+
+ <sect3>
+ <title>Reconstruct Traffic Flows</title>
+
+ <para>The bridge supports monitor mode, where the packets are
+ discarded after &man.bpf.4; processing, and are not
+ processed or forwarded further. This can be used to
+ multiplex the input of two or more interfaces into a single
+ &man.bpf.4; stream. This is useful for reconstructing the
+ traffic for network taps that transmit the RX/TX signals out
+ through two separate interfaces.</para>
+
+ <para>To read the input from four network interfaces as one
+ stream:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig bridge0 addm fxp0 addm fxp1 addm fxp2 addm fxp3 monitor up</userinput>
+&prompt.root; <userinput>tcpdump -i bridge0</userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Span Ports</title>
+
+ <para>A copy of every Ethernet frame received by the bridge
+ will be transmitted out a designated span port. The number
+ of span ports configured on a bridge is unlimited, if an
+ interface is designated as a span port then it may not also
+ be used as a regular bridge port. This is most useful for
+ snooping a bridged network passively on another host
+ connected to one of the span ports of the bridge.</para>
+
+ <para>To send a copy of all frames out the interface named
+ <filename>fxp4</filename>:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig bridge0 span fxp4</userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Private Interfaces</title>
+
+ <para>A private interface does not forward any traffic to any
+ other port that is also a private interface. The traffic is
+ blocked unconditionally so no Ethernet frames will be
+ forwarded, including ARP. If traffic needs to be
+ selectively blocked then a firewall should be used
+ instead.</para>
+ </sect3>
+
+ <sect3>
+ <title>Sticky Interfaces</title>
+
+ <para>If a bridge member interface is marked as sticky then
+ dynamically learned address entries are treated at static once
+ entered into the forwarding cache. Sticky entries are never
+ aged out of the cache or replaced, even if the address is seen
+ on a different interface. This gives the benefit of static
+ address entries without the need to pre-populate the
+ forwarding table, clients learnt on a particular segment of
+ the bridge can not roam to another segment.</para>
+
+ <para>Another example of using sticky addresses would be to
+ combine the bridge with VLANs to create a router where
+ customer networks are isolated without wasting IP address
+ space. Consider that <systemitem class="fqdomainname">CustomerA</systemitem> is on
+ <literal>vlan100</literal> and <systemitem class="fqdomainname">CustomerB</systemitem> is on
+ <literal>vlan101</literal>. The bridge has the address
+ <systemitem class="ipaddress">192.168.0.1</systemitem> and is also an
+ internet router.</para>
+
+ <screen>&prompt.root; <userinput>ifconfig bridge0 addm vlan100 sticky vlan100 addm vlan101 sticky vlan101</userinput>
+&prompt.root; <userinput>ifconfig bridge0 inet 192.168.0.1/24</userinput></screen>
+
+ <para>Both clients see <systemitem class="ipaddress">192.168.0.1</systemitem> as their default gateway
+ and since the bridge cache is sticky they can not spoof the
+ MAC address of the other customer to intercept their
+ traffic.</para>
+
+ <para>Any communication between the VLANs can be blocked using
+ private interfaces (or a firewall):</para>
+
+ <screen>&prompt.root; <userinput>ifconfig bridge0 private vlan100 private vlan101</userinput></screen>
+
+ <para>The customers are completely isolated from each other,
+ the full <systemitem class="netmask">/24</systemitem> address range
+ can be allocated without subnetting.</para>
+ </sect3>
+
+ <sect3>
+ <title>SNMP Monitoring</title>
+
+ <para>The bridge interface and STP parameters can be monitored
+ via the SNMP daemon which is included in the &os; base
+ system. The exported bridge MIBs conform to the IETF
+ standards so any SNMP client or monitoring package can be
+ used to retrieve the data.</para>
+
+ <para>On the bridge machine uncomment the
+ <literal>begemotSnmpdModulePath."bridge" =
+ "/usr/lib/snmp_bridge.so"</literal> line from
+ <filename>/etc/snmp.config</filename> and start the
+ <application>bsnmpd</application> daemon. Other
+ configuration such as community names and access lists may
+ need to be modified. See &man.bsnmpd.1; and
+ &man.snmp.bridge.3; for more information.</para>
+
+ <para>The following examples use the
+ <application>Net-SNMP</application> software (<package>net-mgmt/net-snmp</package>) to query a
+ bridge, the <package>net-mgmt/bsnmptools</package> port can also
+ be used. From the SNMP client host add to
+ <filename>$HOME/.snmp/snmp.conf</filename> the following
+ lines to import the bridge MIB definitions in to
+ <application>Net-SNMP</application>:</para>
+
+ <programlisting>mibdirs +/usr/share/snmp/mibs
+mibs +BRIDGE-MIB:RSTP-MIB:BEGEMOT-MIB:BEGEMOT-BRIDGE-MIB</programlisting>
+
+ <para>To monitor a single bridge via the IETF BRIDGE-MIB
+ (RFC4188) do</para>
+
+ <screen>&prompt.user; <userinput>snmpwalk -v 2c -c public bridge1.example.com mib-2.dot1dBridge</userinput>
+BRIDGE-MIB::dot1dBaseBridgeAddress.0 = STRING: 66:fb:9b:6e:5c:44
+BRIDGE-MIB::dot1dBaseNumPorts.0 = INTEGER: 1 ports
+BRIDGE-MIB::dot1dStpTimeSinceTopologyChange.0 = Timeticks: (189959) 0:31:39.59 centi-seconds
+BRIDGE-MIB::dot1dStpTopChanges.0 = Counter32: 2
+BRIDGE-MIB::dot1dStpDesignatedRoot.0 = Hex-STRING: 80 00 00 01 02 4B D4 50
+...
+BRIDGE-MIB::dot1dStpPortState.3 = INTEGER: forwarding(5)
+BRIDGE-MIB::dot1dStpPortEnable.3 = INTEGER: enabled(1)
+BRIDGE-MIB::dot1dStpPortPathCost.3 = INTEGER: 200000
+BRIDGE-MIB::dot1dStpPortDesignatedRoot.3 = Hex-STRING: 80 00 00 01 02 4B D4 50
+BRIDGE-MIB::dot1dStpPortDesignatedCost.3 = INTEGER: 0
+BRIDGE-MIB::dot1dStpPortDesignatedBridge.3 = Hex-STRING: 80 00 00 01 02 4B D4 50
+BRIDGE-MIB::dot1dStpPortDesignatedPort.3 = Hex-STRING: 03 80
+BRIDGE-MIB::dot1dStpPortForwardTransitions.3 = Counter32: 1
+RSTP-MIB::dot1dStpVersion.0 = INTEGER: rstp(2)</screen>
+
+ <para>The <literal>dot1dStpTopChanges.0</literal> value is two
+ which means that the STP bridge topology has changed twice,
+ a topology change means that one or more links in the
+ network have changed or failed and a new tree has been
+ calculated. The
+ <literal>dot1dStpTimeSinceTopologyChange.0</literal> value
+ will show when this happened.</para>
+
+ <para>To monitor multiple bridge interfaces one may use the
+ private BEGEMOT-BRIDGE-MIB:</para>
+
+ <screen>&prompt.user; <userinput>snmpwalk -v 2c -c public bridge1.example.com</userinput>
+enterprises.fokus.begemot.begemotBridge
+BEGEMOT-BRIDGE-MIB::begemotBridgeBaseName."bridge0" = STRING: bridge0
+BEGEMOT-BRIDGE-MIB::begemotBridgeBaseName."bridge2" = STRING: bridge2
+BEGEMOT-BRIDGE-MIB::begemotBridgeBaseAddress."bridge0" = STRING: e:ce:3b:5a:9e:13
+BEGEMOT-BRIDGE-MIB::begemotBridgeBaseAddress."bridge2" = STRING: 12:5e:4d:74:d:fc
+BEGEMOT-BRIDGE-MIB::begemotBridgeBaseNumPorts."bridge0" = INTEGER: 1
+BEGEMOT-BRIDGE-MIB::begemotBridgeBaseNumPorts."bridge2" = INTEGER: 1
+...
+BEGEMOT-BRIDGE-MIB::begemotBridgeStpTimeSinceTopologyChange."bridge0" = Timeticks: (116927) 0:19:29.27 centi-seconds
+BEGEMOT-BRIDGE-MIB::begemotBridgeStpTimeSinceTopologyChange."bridge2" = Timeticks: (82773) 0:13:47.73 centi-seconds
+BEGEMOT-BRIDGE-MIB::begemotBridgeStpTopChanges."bridge0" = Counter32: 1
+BEGEMOT-BRIDGE-MIB::begemotBridgeStpTopChanges."bridge2" = Counter32: 1
+BEGEMOT-BRIDGE-MIB::begemotBridgeStpDesignatedRoot."bridge0" = Hex-STRING: 80 00 00 40 95 30 5E 31
+BEGEMOT-BRIDGE-MIB::begemotBridgeStpDesignatedRoot."bridge2" = Hex-STRING: 80 00 00 50 8B B8 C6 A9</screen>
+
+ <para>To change the bridge interface being monitored via the
+ <literal>mib-2.dot1dBridge</literal> subtree do:</para>
+
+ <screen>&prompt.user; <userinput>snmpset -v 2c -c private bridge1.example.com</userinput>
+BEGEMOT-BRIDGE-MIB::begemotBridgeDefaultBridgeIf.0 s bridge2</screen>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-aggregation">
+ <info><title>Link Aggregation and Failover</title>
+ <authorgroup>
+ <author><personname><firstname>Andrew</firstname><surname>Thompson</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>lagg</primary></indexterm>
+ <indexterm><primary>failover</primary></indexterm>
+ <indexterm><primary>fec</primary></indexterm>
+ <indexterm><primary>lacp</primary></indexterm>
+ <indexterm><primary>loadbalance</primary></indexterm>
+ <indexterm><primary>roundrobin</primary></indexterm>
+
+ <sect2>
+ <title>Introduction</title>
+ <para>The &man.lagg.4; interface allows aggregation of multiple network
+ interfaces as one virtual interface for the purpose of providing
+ fault-tolerance and high-speed links.</para>
+ </sect2>
+
+ <sect2>
+ <title>Operating Modes</title>
+
+ <variablelist>
+
+ <varlistentry><term>failover</term>
+
+ <listitem>
+ <para>Sends and receives traffic only through the master port. If the
+ master port becomes unavailable, the next active port is used. The
+ first interface added is the master port; any interfaces added after
+ that are used as failover devices.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>fec</term>
+
+ <listitem>
+ <para>Supports Cisco EtherChannel. This is a static setup and does not
+ negotiate aggregation with the peer or exchange frames to monitor the
+ link, if the switch supports LACP then that should be used
+ instead.</para>
+
+ <para>Balances outgoing traffic across the active ports based on hashed
+ protocol header information and accepts incoming traffic from any
+ active port. The hash includes the Ethernet source and destination
+ address, and, if available, the VLAN tag, and the IPv4/IPv6 source
+ and destination address.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>lacp</term>
+
+ <listitem>
+ <para>Supports the IEEE 802.3ad Link Aggregation Control Protocol
+ (LACP) and the Marker Protocol. LACP will negotiate a set of
+ aggregable links with the peer in to one or more Link Aggregated
+ Groups. Each LAG is composed of ports of the same speed, set to
+ full-duplex operation. The traffic will be balanced across the ports
+ in the LAG with the greatest total speed, in most cases there will
+ only be one LAG which contains all ports. In the event of changes in
+ physical connectivity, Link Aggregation will quickly converge to a
+ new configuration.</para>
+
+ <para>Balances outgoing traffic across the active ports based on hashed
+ protocol header information and accepts incoming traffic from any
+ active port. The hash includes the Ethernet source and destination
+ address, and, if available, the VLAN tag, and the IPv4/IPv6 source
+ and destination address.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>loadbalance</term>
+
+ <listitem>
+ <para>This is an alias of <emphasis>fec</emphasis> mode.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry><term>roundrobin</term>
+
+ <listitem>
+ <para>Distributes outgoing traffic using a round-robin scheduler
+ through all active ports and accepts incoming traffic from any active
+ port. This mode will violate Ethernet frame ordering and should be
+ used with caution.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Examples</title>
+
+ <example xml:id="networking-lacp-aggregation-cisco">
+ <title>LACP aggregation with a Cisco switch</title>
+
+ <para>This example connects two interfaces on a &os; machine to the
+ switch as a single load balanced and fault tolerant link. More interfaces
+ can be added to increase throughput and fault tolerance. Since frame
+ ordering is mandatory on Ethernet links then any traffic between two
+ stations always flows over the same physical link limiting the maximum
+ speed to that of one interface. The transmit algorithm attempts to use as
+ much information as it can to distinguish different traffic flows and
+ balance across the available interfaces.</para>
+
+ <para>On the Cisco switch add the interfaces to the channel group.</para>
+
+ <screen>interface FastEthernet0/1
+ channel-group 1 mode active
+ channel-protocol lacp
+!
+interface FastEthernet0/2
+ channel-group 1 mode active
+ channel-protocol lacp
+!</screen>
+
+ <para>On the &os; machine create the lagg interface.</para>
+
+ <screen>&prompt.root; <userinput>ifconfig lagg0 create</userinput>
+&prompt.root; <userinput>ifconfig lagg0 up laggproto lacp laggport fxp0 laggport fxp1</userinput></screen>
+
+ <para>View the interface status from ifconfig; ports marked as
+ <emphasis>ACTIVE</emphasis> are part of the active aggregation group
+ that has been negotiated with the remote switch and traffic will be
+ transmitted and received. Use the verbose output of &man.ifconfig.8;
+ to view the LAG identifiers.</para>
+
+ <screen>lagg0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; metric 0 mtu 1500
+ options=8&lt;VLAN_MTU&gt;
+ ether 00:05:5d:71:8d:b8
+ media: Ethernet autoselect
+ status: active
+ laggproto lacp
+ laggport: fxp1 flags=1c&lt;ACTIVE,COLLECTING,DISTRIBUTING&gt;
+ laggport: fxp0 flags=1c&lt;ACTIVE,COLLECTING,DISTRIBUTING&gt;</screen>
+
+ <para>The switch will show which ports are active. For more detail use
+ <userinput>show lacp neighbor detail</userinput>.</para>
+
+ <screen>switch# show lacp neighbor
+Flags: S - Device is requesting Slow LACPDUs
+ F - Device is requesting Fast LACPDUs
+ A - Device is in Active mode P - Device is in Passive mode
+
+Channel group 1 neighbors
+
+Partner's information:
+
+ LACP port Oper Port Port
+Port Flags Priority Dev ID Age Key Number State
+Fa0/1 SA 32768 0005.5d71.8db8 29s 0x146 0x3 0x3D
+Fa0/2 SA 32768 0005.5d71.8db8 29s 0x146 0x4 0x3D</screen>
+
+ </example>
+ <example xml:id="networking-lagg-failover">
+ <title>Failover mode</title>
+
+ <para>Failover mode can be used to switch over to another interface if
+ the link is lost on the master.</para>
+
+ <screen>&prompt.root; <userinput>ifconfig lagg0 create</userinput>
+&prompt.root; <userinput>ifconfig lagg0 up laggproto failover laggport fxp0 laggport fxp1</userinput></screen>
+
+ <screen>lagg0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; metric 0 mtu 1500
+ options=8&lt;VLAN_MTU&gt;
+ ether 00:05:5d:71:8d:b8
+ media: Ethernet autoselect
+ status: active
+ laggproto failover
+ laggport: fxp1 flags=0&lt;&gt;
+ laggport: fxp0 flags=5&lt;MASTER,ACTIVE&gt;</screen>
+
+ <para>Traffic will be transmitted and received on
+ <filename>fxp0</filename>. If the link is lost on
+ <filename>fxp0</filename> then <filename>fxp1</filename> will
+ become the active link. If the link is restored on the master
+ interface then it will once again become the active link.</para>
+ </example>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-diskless">
+ <info><title>Diskless Operation</title>
+ <authorgroup>
+ <author><personname><firstname>Jean-Fran&ccedil;ois</firstname><surname>Dock&egrave;s</surname></personname><contrib>Updated by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Alex</firstname><surname>Dupre</surname></personname><contrib>Reorganized and enhanced by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>diskless workstation</primary></indexterm>
+ <indexterm><primary>diskless operation</primary></indexterm>
+
+ <para>A FreeBSD machine can boot over the network and operate without a
+ local disk, using file systems mounted from an <acronym>NFS</acronym> server. No system
+ modification is necessary, beyond standard configuration files.
+ Such a system is relatively easy to set up because all the necessary elements
+ are readily available:</para>
+ <itemizedlist>
+ <listitem>
+ <para>There are at least two possible methods to load the kernel over
+ the network:</para>
+ <itemizedlist>
+ <listitem>
+ <para><acronym>PXE</acronym>: The &intel; Preboot eXecution
+ Environment system is a form of smart boot ROM built into some
+ networking cards or motherboards. See &man.pxeboot.8; for more
+ details.</para>
+ </listitem>
+ <listitem>
+ <para>The <application>Etherboot</application>
+ port (<package>net/etherboot</package>) produces
+ ROM-able code to boot kernels over the network. The
+ code can be either burnt into a boot PROM on a network
+ card, or loaded from a local floppy (or hard) disk
+ drive, or from a running &ms-dos; system. Many network
+ cards are supported.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>A sample script
+ (<filename>/usr/share/examples/diskless/clone_root</filename>) eases
+ the creation and maintenance of the workstation's root file system
+ on the server. The script will probably require a little
+ customization but it will get you started very quickly.</para>
+ </listitem>
+
+ <listitem>
+ <para>Standard system startup files exist in <filename>/etc</filename>
+ to detect and support a diskless system startup.</para>
+ </listitem>
+
+ <listitem>
+ <para>Swapping, if needed, can be done either to an <acronym>NFS</acronym> file or to
+ a local disk.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>There are many ways to set up diskless workstations. Many
+ elements are involved, and most can be customized to suit local
+ taste. The following will describe variations on the setup of a complete system,
+ emphasizing simplicity and compatibility with the
+ standard FreeBSD startup scripts. The system described has the
+ following characteristics:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The diskless workstations use a shared
+ read-only <filename>/</filename> file system, and a shared
+ read-only <filename>/usr</filename>.</para>
+ <para>The root file system is a copy of a
+ standard FreeBSD root (typically the server's), with some
+ configuration files overridden by ones specific to diskless
+ operation or, possibly, to the workstation they belong to.</para>
+ <para>The parts of the root which have to be
+ writable are overlaid with &man.md.4; file systems. Any changes
+ will be lost when the system reboots.</para>
+ </listitem>
+ <listitem>
+ <para>The kernel is transferred and loaded either with
+ <application>Etherboot</application> or <acronym>PXE</acronym>
+ as some situations may mandate the use of either method.</para>
+ </listitem>
+ </itemizedlist>
+
+ <caution><para>As described, this system is insecure. It should
+ live in a protected area of a network, and be untrusted by
+ other hosts.</para>
+ </caution>
+
+ <para>All the information in this section has been tested
+ using &os; 5.2.1-RELEASE.</para>
+
+ <sect2>
+ <title>Background Information</title>
+
+ <para>Setting up diskless workstations is both relatively
+ straightforward and prone to errors. These are sometimes
+ difficult to diagnose for a number of reasons. For example:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Compile time options may determine different behaviors at
+ runtime.</para>
+ </listitem>
+
+ <listitem>
+ <para>Error messages are often cryptic or totally absent.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>In this context, having some knowledge of the background
+ mechanisms involved is very useful to solve the problems that
+ may arise.</para>
+
+ <para>Several operations need to be performed for a successful
+ bootstrap:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The machine needs to obtain initial parameters such as its IP
+ address, executable filename, server name, root path. This is
+ done using the <acronym>DHCP</acronym> or BOOTP protocols.
+ <acronym>DHCP</acronym> is a compatible extension of BOOTP, and
+ uses the same port numbers and basic packet format.</para>
+
+ <para>It is possible to configure a system to use only BOOTP.
+ The &man.bootpd.8; server program is included in the base &os;
+ system.</para>
+
+ <para>However, <acronym>DHCP</acronym> has a number of advantages
+ over BOOTP (nicer configuration files, possibility of using
+ <acronym>PXE</acronym>, plus many others not directly related to
+ diskless operation), and we will describe mainly a
+ <acronym>DHCP</acronym> configuration, with equivalent examples
+ using &man.bootpd.8; when possible. The sample configuration will
+ use the <application>ISC DHCP</application> software package
+ (release 3.0.1.r12 was installed on the test server).</para>
+ </listitem>
+
+ <listitem>
+ <para>The machine needs to transfer one or several programs to local
+ memory. Either <acronym>TFTP</acronym> or <acronym>NFS</acronym>
+ are used. The choice between <acronym>TFTP</acronym> and
+ <acronym>NFS</acronym> is a compile time option in several places.
+ A common source of error is to specify filenames for the wrong
+ protocol: <acronym>TFTP</acronym> typically transfers all files from
+ a single directory on the server, and would expect filenames
+ relative to this directory. <acronym>NFS</acronym> needs absolute
+ file paths.</para>
+ </listitem>
+
+ <listitem>
+ <para>The possible intermediate bootstrap programs and the kernel
+ need to be initialized and executed. There are several important
+ variations in this area:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><acronym>PXE</acronym> will load &man.pxeboot.8;, which is
+ a modified version of the &os; third stage loader. The
+ &man.loader.8; will obtain most parameters necessary to system
+ startup, and leave them in the kernel environment before
+ transferring control. It is possible to use a
+ <filename>GENERIC</filename> kernel in this case.</para>
+ </listitem>
+
+ <listitem>
+ <para><application>Etherboot</application>, will directly
+ load the kernel, with less preparation. You will need to
+ build a kernel with specific options.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><acronym>PXE</acronym> and <application>Etherboot</application>
+ work equally well; however, because kernels
+ normally let the &man.loader.8; do more work for them,
+ <acronym>PXE</acronym> is the preferred method.</para>
+
+ <para>If your <acronym>BIOS</acronym> and network cards support
+ <acronym>PXE</acronym>, you should probably use it.</para>
+ </listitem>
+
+ <listitem>
+ <para>Finally, the machine needs to access its file systems.
+ <acronym>NFS</acronym> is used in all cases.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>See also &man.diskless.8; manual page.</para>
+ </sect2>
+
+ <sect2>
+ <title>Setup Instructions</title>
+
+ <sect3>
+ <title>Configuration Using <application>ISC DHCP</application></title>
+ <indexterm>
+ <primary>DHCP</primary>
+ <secondary>diskless operation</secondary>
+ </indexterm>
+
+ <para>The <application>ISC DHCP</application> server can answer
+ both BOOTP and <acronym>DHCP</acronym> requests.</para>
+
+ <para><application>ISC DHCP
+ 3.0</application> is not part of the base
+ system. You will first need to install the
+ <package>net/isc-dhcp3-server</package> port or the
+ corresponding package.</para>
+
+ <para>Once <application>ISC DHCP</application> is installed, it
+ needs a configuration file to run (normally named
+ <filename>/usr/local/etc/dhcpd.conf</filename>). Here follows
+ a commented example, where host <systemitem>margaux</systemitem>
+ uses <application>Etherboot</application> and host
+ <systemitem>corbieres</systemitem> uses <acronym>PXE</acronym>:</para>
+
+ <programlisting>
+default-lease-time 600;
+max-lease-time 7200;
+authoritative;
+
+option domain-name "example.com";
+option domain-name-servers 192.168.4.1;
+option routers 192.168.4.1;
+
+subnet 192.168.4.0 netmask 255.255.255.0 {
+ use-host-decl-names on; <co xml:id="co-dhcp-host-name"/>
+ option subnet-mask 255.255.255.0;
+ option broadcast-address 192.168.4.255;
+
+ host margaux {
+ hardware ethernet 01:23:45:67:89:ab;
+ fixed-address margaux.example.com;
+ next-server 192.168.4.4; <co xml:id="co-dhcp-next-server"/>
+ filename "/data/misc/kernel.diskless"; <co xml:id="co-dhcp-filename"/>
+ option root-path "192.168.4.4:/data/misc/diskless"; <co xml:id="co-dhcp-root-path"/>
+ }
+ host corbieres {
+ hardware ethernet 00:02:b3:27:62:df;
+ fixed-address corbieres.example.com;
+ next-server 192.168.4.4;
+ filename "pxeboot";
+ option root-path "192.168.4.4:/data/misc/diskless";
+ }
+}
+ </programlisting>
+
+ <calloutlist>
+ <callout arearefs="co-dhcp-host-name"><para>This option tells
+ <application>dhcpd</application> to send the value in the
+ <literal>host</literal> declarations as the hostname for the
+ diskless host. An alternate way would be to add an
+ <literal>option host-name
+ margaux</literal> inside the
+ <literal>host</literal> declarations.</para>
+ </callout>
+
+ <callout arearefs="co-dhcp-next-server"><para>The
+ <literal>next-server</literal> directive designates
+ the <acronym>TFTP</acronym> or <acronym>NFS</acronym> server to
+ use for loading loader or kernel file (the default is to use
+ the same host as the
+ <acronym>DHCP</acronym> server).</para>
+ </callout>
+
+ <callout arearefs="co-dhcp-filename"><para>The
+ <literal>filename</literal> directive defines the file that
+ <application>Etherboot</application> or <acronym>PXE</acronym>
+ will load for the next execution step. It must be specified
+ according to the transfer method used.
+ <application>Etherboot</application> can be compiled to use
+ <acronym>NFS</acronym> or <acronym>TFTP</acronym>. The &os;
+ port configures <acronym>NFS</acronym> by default.
+ <acronym>PXE</acronym> uses <acronym>TFTP</acronym>, which is
+ why a relative filename is used here (this may depend on the
+ <acronym>TFTP</acronym> server configuration, but would be
+ fairly typical). Also, <acronym>PXE</acronym> loads
+ <filename>pxeboot</filename>, not the kernel. There are other
+ interesting possibilities, like loading
+ <filename>pxeboot</filename> from a &os; CD-ROM
+ <filename>/boot</filename> directory (as
+ &man.pxeboot.8; can load a <filename>GENERIC</filename> kernel,
+ this makes it possible to use <acronym>PXE</acronym> to boot
+ from a remote CD-ROM).</para>
+ </callout>
+
+ <callout arearefs="co-dhcp-root-path"><para>The
+ <literal>root-path</literal> option defines the path to
+ the root file system, in usual <acronym>NFS</acronym> notation.
+ When using <acronym>PXE</acronym>, it is possible to leave off
+ the host's IP as long as you do not enable the kernel option
+ BOOTP. The <acronym>NFS</acronym> server will then be
+ the same as the <acronym>TFTP</acronym> one.</para>
+ </callout>
+ </calloutlist>
+
+ </sect3>
+ <sect3>
+ <title>Configuration Using BOOTP</title>
+ <indexterm>
+ <primary>BOOTP</primary>
+ <secondary>diskless operation</secondary>
+ </indexterm>
+
+ <para>Here follows an equivalent <application>bootpd</application>
+ configuration (reduced to one client). This would be found in
+ <filename>/etc/bootptab</filename>.</para>
+
+ <para>Please note that <application>Etherboot</application>
+ must be compiled with the non-default option
+ <literal>NO_DHCP_SUPPORT</literal> in order to use BOOTP,
+ and that <acronym>PXE</acronym> <emphasis>needs</emphasis> <acronym>DHCP</acronym>. The only
+ obvious advantage of <application>bootpd</application> is
+ that it exists in the base system.</para>
+
+ <programlisting>
+.def100:\
+ :hn:ht=1:sa=192.168.4.4:vm=rfc1048:\
+ :sm=255.255.255.0:\
+ :ds=192.168.4.1:\
+ :gw=192.168.4.1:\
+ :hd="/tftpboot":\
+ :bf="/kernel.diskless":\
+ :rp="192.168.4.4:/data/misc/diskless":
+
+margaux:ha=0123456789ab:tc=.def100
+ </programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Preparing a Boot Program with
+ <application>Etherboot</application></title>
+
+ <indexterm>
+ <primary>Etherboot</primary>
+ </indexterm>
+
+ <para><link xlink:href="http://etherboot.sourceforge.net">Etherboot's Web
+ site</link> contains
+ <link xlink:href="http://etherboot.sourceforge.net/doc/html/userman/t1.html">
+ extensive documentation</link> mainly intended for Linux
+ systems, but nonetheless containing useful information. The
+ following will just outline how you would use
+ <application>Etherboot</application> on a FreeBSD
+ system.</para>
+
+ <para>You must first install the <package>net/etherboot</package> package or port.</para>
+
+ <para>You can change the <application>Etherboot</application>
+ configuration (i.e. to use <acronym>TFTP</acronym> instead of
+ <acronym>NFS</acronym>) by editing the <filename>Config</filename>
+ file in the <application>Etherboot</application> source
+ directory.</para>
+
+ <para>For our setup, we shall use a boot floppy. For other methods
+ (PROM, or &ms-dos; program), please refer to the
+ <application>Etherboot</application> documentation.</para>
+
+ <para>To make a boot floppy, insert a floppy in the drive on the
+ machine where you installed <application>Etherboot</application>,
+ then change your current directory to the <filename>src</filename>
+ directory in the <application>Etherboot</application> tree and
+ type:</para>
+
+ <screen>
+&prompt.root; <userinput>gmake bin32/devicetype.fd0</userinput>
+ </screen>
+
+ <para><replaceable>devicetype</replaceable> depends on the type of
+ the Ethernet card in the diskless workstation. Refer to the
+ <filename>NIC</filename> file in the same directory to determine the
+ right <replaceable>devicetype</replaceable>.</para>
+
+ </sect3>
+
+ <sect3>
+ <title>Booting with <acronym>PXE</acronym></title>
+
+ <para>By default, the &man.pxeboot.8; loader loads the kernel via
+ <acronym>NFS</acronym>. It can be compiled to use
+ <acronym>TFTP</acronym> instead by specifying the
+ <literal>LOADER_TFTP_SUPPORT</literal> option in
+ <filename>/etc/make.conf</filename>. See the comments in
+ <filename>/usr/share/examples/etc/make.conf</filename>
+ for instructions.</para>
+
+ <para>There are two other <filename>make.conf</filename>
+ options which may be useful for setting up a serial console diskless
+ machine: <literal>BOOT_PXELDR_PROBE_KEYBOARD</literal>, and
+ <literal>BOOT_PXELDR_ALWAYS_SERIAL</literal>.</para>
+
+ <para>To use <acronym>PXE</acronym> when the machine starts, you will
+ usually need to select the <literal>Boot from network</literal>
+ option in your <acronym>BIOS</acronym> setup, or type a function key
+ during the PC initialization.</para>
+ </sect3>
+
+ <sect3>
+ <title>Configuring the <acronym>TFTP</acronym> and <acronym>NFS</acronym> Servers</title>
+
+ <indexterm>
+ <primary>TFTP</primary>
+ <secondary>diskless operation</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>NFS</primary>
+ <secondary>diskless operation</secondary>
+ </indexterm>
+
+ <para>If you are using <acronym>PXE</acronym> or
+ <application>Etherboot</application> configured to use
+ <acronym>TFTP</acronym>, you need to enable
+ <application>tftpd</application> on the file server:</para>
+ <procedure>
+ <step>
+ <para>Create a directory from which <application>tftpd</application>
+ will serve the files, e.g. <filename>/tftpboot</filename>.</para>
+ </step>
+
+ <step>
+ <para>Add this line to your
+ <filename>/etc/inetd.conf</filename>:</para>
+
+ <programlisting>tftp dgram udp wait root /usr/libexec/tftpd tftpd -l -s /tftpboot</programlisting>
+
+ <note><para>It appears that at least some <acronym>PXE</acronym> versions want
+ the <acronym>TCP</acronym> version of <acronym>TFTP</acronym>. In this case, add a second line,
+ replacing <literal>dgram udp</literal> with <literal>stream
+ tcp</literal>.</para>
+ </note>
+ </step>
+ <step>
+ <para>Tell <application>inetd</application> to reread its configuration
+ file. The <option>inetd_enable="YES"</option> must be in
+ the <filename>/etc/rc.conf</filename> file for this
+ command to execute correctly:</para>
+ <screen>&prompt.root; <userinput>/etc/rc.d/inetd restart</userinput></screen>
+ </step>
+ </procedure>
+
+ <para>You can place the <filename>tftpboot</filename>
+ directory anywhere on the server. Make sure that the
+ location is set in both <filename>inetd.conf</filename> and
+ <filename>dhcpd.conf</filename>.</para>
+
+ <para>In all cases, you also need to enable <acronym>NFS</acronym> and export the
+ appropriate file system on the <acronym>NFS</acronym> server.</para>
+
+ <procedure>
+ <step>
+ <para>Add this to <filename>/etc/rc.conf</filename>:</para>
+ <programlisting>nfs_server_enable="YES"</programlisting>
+ </step>
+
+ <step>
+ <para>Export the file system where the diskless root directory
+ is located by adding the following to
+ <filename>/etc/exports</filename> (adjust the volume mount
+ point and replace <replaceable>margaux corbieres</replaceable>
+ with the names of the diskless workstations):</para>
+
+ <programlisting><replaceable>/data/misc</replaceable> -alldirs -ro <replaceable>margaux corbieres</replaceable></programlisting>
+ </step>
+ <step>
+ <para>Tell <application>mountd</application> to reread its configuration
+ file. If you actually needed to enable <acronym>NFS</acronym> in
+ <filename>/etc/rc.conf</filename>
+ at the first step, you probably want to reboot instead.</para>
+ <screen>&prompt.root; <userinput>/etc/rc.d/mountd restart</userinput></screen>
+ </step>
+ </procedure>
+
+ </sect3>
+
+ <sect3>
+ <title>Building a Diskless Kernel</title>
+
+ <indexterm>
+ <primary>diskless operation</primary>
+ <secondary>kernel configuration</secondary>
+ </indexterm>
+
+ <para>If using <application>Etherboot</application>, you need to
+ create a kernel configuration file for the diskless client
+ with the following options (in addition to the usual ones):</para>
+
+ <programlisting>
+options BOOTP # Use BOOTP to obtain IP address/hostname
+options BOOTP_NFSROOT # NFS mount root file system using BOOTP info
+ </programlisting>
+
+ <para>You may also want to use <literal>BOOTP_NFSV3</literal>,
+ <literal>BOOT_COMPAT</literal> and <literal>BOOTP_WIRED_TO</literal>
+ (refer to <filename>NOTES</filename>).</para>
+
+ <para>These option names are historical and slightly misleading as
+ they actually enable indifferent use of <acronym>DHCP</acronym> and
+ BOOTP inside the kernel (it is also possible to force strict BOOTP
+ or <acronym>DHCP</acronym> use).</para>
+
+ <para>Build the kernel (see <xref linkend="kernelconfig"/>),
+ and copy it to the place specified
+ in <filename>dhcpd.conf</filename>.</para>
+
+ <note>
+ <para>When using <acronym>PXE</acronym>, building a kernel with the
+ above options is not strictly necessary (though suggested).
+ Enabling them will cause more <acronym>DHCP</acronym> requests to be
+ issued during kernel startup, with a small risk of inconsistency
+ between the new values and those retrieved by &man.pxeboot.8; in some
+ special cases. The advantage of using them is that the host name
+ will be set as a side effect. Otherwise you will need to set the
+ host name by another method, for example in a client-specific
+ <filename>rc.conf</filename> file.</para>
+ </note>
+
+ <note>
+ <para>In order to be loadable with
+ <application>Etherboot</application>, a kernel needs to have
+ the device hints compiled in. You would typically set the
+ following option in the configuration file (see the
+ <filename>NOTES</filename> configuration comments file):</para>
+
+ <programlisting>hints "GENERIC.hints"</programlisting>
+ </note>
+
+ </sect3>
+
+ <sect3>
+ <title>Preparing the Root Filesystem</title>
+
+ <indexterm>
+ <primary>root file system</primary>
+ <secondary>diskless operation</secondary>
+ </indexterm>
+
+ <para>You need to create a root file system for the diskless
+ workstations, in the location listed as
+ <literal>root-path</literal> in
+ <filename>dhcpd.conf</filename>.</para>
+
+ <sect4>
+ <title>Using <command>make world</command> to populate root</title>
+
+ <para>This method is quick and
+ will install a complete virgin system (not only the root file system)
+ into <envar>DESTDIR</envar>.
+ All you have to do is simply execute the following script:</para>
+
+ <programlisting>#!/bin/sh
+export DESTDIR=/data/misc/diskless
+mkdir -p ${DESTDIR}
+cd /usr/src; make buildworld &amp;&amp; make buildkernel
+cd /usr/src/etc; make distribution</programlisting>
+
+ <para>Once done, you may need to customize your
+ <filename>/etc/rc.conf</filename> and
+ <filename>/etc/fstab</filename> placed into
+ <envar>DESTDIR</envar> according to your needs.</para>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>Configuring Swap</title>
+
+ <para>If needed, a swap file located on the server can be
+ accessed via <acronym>NFS</acronym>.</para>
+
+ <sect4>
+ <title><acronym>NFS</acronym> Swap</title>
+
+ <para>The kernel does not support enabling <acronym>NFS</acronym>
+ swap at boot time. Swap must be enabled by the startup scripts,
+ by mounting a writable file system and creating and enabling a
+ swap file. To create a swap file of appropriate size, you can do
+ like this:</para>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/zero of=/path/to/swapfile bs=1k count=1 oseek=100000</userinput></screen>
+
+ <para>To enable it you have to add the following line to your
+ <filename>rc.conf</filename>:</para>
+
+ <programlisting>swapfile=<replaceable>/path/to/swapfile</replaceable></programlisting>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>Miscellaneous Issues</title>
+
+
+ <sect4>
+ <title>Running with a Read-only <filename>/usr</filename></title>
+
+ <indexterm>
+ <primary>diskless operation</primary>
+ <secondary>/usr read-only</secondary>
+ </indexterm>
+
+ <para>If the diskless workstation is configured to run X, you
+ will have to adjust the <application>XDM</application> configuration file, which puts
+ the error log on <filename>/usr</filename> by default.</para>
+ </sect4>
+ <sect4>
+ <title>Using a Non-FreeBSD Server</title>
+
+ <para>When the server for the root file system is not running FreeBSD,
+ you will have to create the root file system on a
+ FreeBSD machine, then copy it to its destination, using
+ <command>tar</command> or <command>cpio</command>.</para>
+ <para>In this situation, there are sometimes
+ problems with the special files in <filename>/dev</filename>,
+ due to differing major/minor integer sizes. A solution to this
+ problem is to export a directory from the non-FreeBSD server,
+ mount this directory onto a FreeBSD machine, and
+ use &man.devfs.5; to allocate device nodes transparently for
+ the user.</para>
+
+ </sect4>
+
+ </sect3>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-isdn">
+ <title>ISDN</title>
+
+ <indexterm>
+ <primary>ISDN</primary>
+ </indexterm>
+
+ <para>A good resource for information on ISDN technology and hardware is
+ <link xlink:href="http://www.alumni.caltech.edu/~dank/isdn/">Dan Kegel's ISDN
+ Page</link>.</para>
+
+ <para>A quick simple road map to ISDN follows:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>If you live in Europe you might want to investigate the ISDN card
+ section.</para>
+ </listitem>
+
+ <listitem>
+ <para>If you are planning to use ISDN primarily to connect to the
+ Internet with an Internet Provider on a dial-up non-dedicated basis,
+ you might look into Terminal Adapters. This will give you the
+ most flexibility, with the fewest problems, if you change
+ providers.</para>
+ </listitem>
+
+ <listitem>
+ <para>If you are connecting two LANs together, or connecting to the
+ Internet with a dedicated ISDN connection, you might consider
+ the stand alone router/bridge option.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Cost is a significant factor in determining what solution you will
+ choose. The following options are listed from least expensive to most
+ expensive.</para>
+
+ <sect2 xml:id="network-isdn-cards">
+ <info><title>ISDN Cards</title>
+ <authorgroup>
+ <author><personname><firstname>Hellmuth</firstname><surname>Michaelis</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm>
+ <primary>ISDN</primary>
+ <secondary>cards</secondary>
+ </indexterm>
+
+ <para>FreeBSD's ISDN implementation supports only the DSS1/Q.931
+ (or Euro-ISDN) standard using passive cards. Some active cards
+ are supported where the firmware
+ also supports other signaling protocols; this also includes the
+ first supported Primary Rate (PRI) ISDN card.</para>
+
+ <para>The <application>isdn4bsd</application> software allows you to connect
+ to other ISDN routers using either IP over raw HDLC or by using
+ synchronous PPP: either by using kernel PPP with <literal>isppp</literal>, a
+ modified &man.sppp.4; driver, or by using userland &man.ppp.8;. By using
+ userland &man.ppp.8;, channel bonding of two or more ISDN
+ B-channels is possible. A telephone answering machine
+ application is also available as well as many utilities such as
+ a software 300 Baud modem.</para>
+
+ <para>Some growing number of PC ISDN cards are supported under
+ FreeBSD and the reports show that it is successfully used all
+ over Europe and in many other parts of the world.</para>
+
+ <para>The passive ISDN cards supported are mostly the ones with
+ the Infineon (formerly Siemens) ISAC/HSCX/IPAC ISDN chipsets,
+ but also ISDN cards with chips from Cologne Chip (ISA bus only),
+ PCI cards with Winbond W6692 chips, some cards with the
+ Tiger300/320/ISAC chipset combinations and some vendor specific
+ chipset based cards such as the AVM Fritz!Card PCI V.1.0 and the
+ AVM Fritz!Card PnP.</para>
+
+ <para>Currently the active supported ISDN cards are the AVM B1
+ (ISA and PCI) BRI cards and the AVM T1 PCI PRI cards.</para>
+
+ <para>For documentation on <application>isdn4bsd</application>,
+ have a look at <filename>/usr/share/examples/isdn/</filename>
+ directory on your FreeBSD system or at the <link xlink:href="http://www.freebsd-support.de/i4b/">homepage of
+ isdn4bsd</link> which also has pointers to hints, erratas and
+ much more documentation such as the <link xlink:href="http://people.FreeBSD.org/~hm/">isdn4bsd
+ handbook</link>.</para>
+
+ <para>In case you are interested in adding support for a
+ different ISDN protocol, a currently unsupported ISDN PC card or
+ otherwise enhancing <application>isdn4bsd</application>, please
+ get in touch with &a.hm;.</para>
+
+ <para>For questions regarding the installation, configuration
+ and troubleshooting <application>isdn4bsd</application>, a
+ &a.isdn.name; mailing list is available.</para>
+ </sect2>
+
+ <sect2>
+ <title>ISDN Terminal Adapters</title>
+
+ <para>Terminal adapters (TA), are to ISDN what modems are to regular
+ phone lines.</para>
+ <indexterm><primary>modem</primary></indexterm>
+ <para>Most TA's use the standard Hayes modem AT command set, and can be
+ used as a drop in replacement for a modem.</para>
+
+ <para>A TA will operate basically the same as a modem except connection
+ and throughput speeds will be much faster than your old modem. You
+ will need to configure <link linkend="ppp">PPP</link> exactly the same
+ as for a modem setup. Make sure you set your serial speed as high as
+ possible.</para>
+ <indexterm><primary>PPP</primary></indexterm>
+ <para>The main advantage of using a TA to connect to an Internet
+ Provider is that you can do Dynamic PPP. As IP address space becomes
+ more and more scarce, most providers are not willing to provide you
+ with a static IP anymore. Most stand-alone routers are not able to
+ accommodate dynamic IP allocation.</para>
+
+ <para>TA's completely rely on the PPP daemon that you are running for
+ their features and stability of connection. This allows you to
+ upgrade easily from using a modem to ISDN on a FreeBSD machine, if you
+ already have PPP set up. However, at the same time any problems you
+ experienced with the PPP program and are going to persist.</para>
+
+ <para>If you want maximum stability, use the kernel <link linkend="ppp">PPP</link> option, not the <link linkend="userppp">userland PPP</link>.</para>
+
+ <para>The following TA's are known to work with FreeBSD:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Motorola BitSurfer and Bitsurfer Pro</para>
+ </listitem>
+
+ <listitem>
+ <para>Adtran</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Most other TA's will probably work as well, TA vendors try to make
+ sure their product can accept most of the standard modem AT command
+ set.</para>
+
+ <para>The real problem with external TA's is that, like modems,
+ you need a good serial card in your computer.</para>
+
+ <para>You should read the <link xlink:href="&url.articles.serial-uart;/index.html">FreeBSD Serial
+ Hardware</link> tutorial for a detailed understanding of
+ serial devices, and the differences between asynchronous and
+ synchronous serial ports.</para>
+
+ <para>A TA running off a standard PC serial port (asynchronous) limits
+ you to 115.2&nbsp;Kbs, even though you have a 128&nbsp;Kbs connection.
+ To fully utilize the 128&nbsp;Kbs that ISDN is capable of,
+ you must move the TA to a synchronous serial card.</para>
+
+ <para>Do not be fooled into buying an internal TA and thinking you have
+ avoided the synchronous/asynchronous issue. Internal TA's simply have
+ a standard PC serial port chip built into them. All this will do is
+ save you having to buy another serial cable and find another empty
+ electrical socket.</para>
+
+ <para>A synchronous card with a TA is at least as fast as a stand-alone
+ router, and with a simple 386 FreeBSD box driving it, probably more
+ flexible.</para>
+
+ <para>The choice of synchronous card/TA v.s. stand-alone router is largely a
+ religious issue. There has been some discussion of this in
+ the mailing lists. We suggest you search the <link xlink:href="&url.base;/search/index.html">archives</link> for
+ the complete discussion.</para>
+ </sect2>
+
+ <sect2>
+ <title>Stand-alone ISDN Bridges/Routers</title>
+ <indexterm>
+ <primary>ISDN</primary>
+ <secondary>stand-alone bridges/routers</secondary>
+ </indexterm>
+ <para>ISDN bridges or routers are not at all specific to FreeBSD
+ or any other operating system. For a more complete
+ description of routing and bridging technology, please refer
+ to a networking reference book.</para>
+
+ <para>In the context of this section, the terms router and bridge will
+ be used interchangeably.</para>
+
+ <para>As the cost of low end ISDN routers/bridges comes down, it
+ will likely become a more and more popular choice. An ISDN
+ router is a small box that plugs directly into your local
+ Ethernet network, and manages its own connection to the other
+ bridge/router. It has built in software to communicate via
+ PPP and other popular protocols.</para>
+
+ <para>A router will allow you much faster throughput than a
+ standard TA, since it will be using a full synchronous ISDN
+ connection.</para>
+
+ <para>The main problem with ISDN routers and bridges is that
+ interoperability between manufacturers can still be a problem.
+ If you are planning to connect to an Internet provider, you
+ should discuss your needs with them.</para>
+
+ <para>If you are planning to connect two LAN segments together,
+ such as your home LAN to the office LAN, this is the simplest
+ lowest
+ maintenance solution. Since you are buying the equipment for
+ both sides of the connection you can be assured that the link
+ will work.</para>
+
+ <para>For example to connect a home computer or branch office
+ network to a head office network the following setup could be
+ used:</para>
+
+ <example>
+ <title>Branch Office or Home Network</title>
+
+ <indexterm><primary>10 base 2</primary></indexterm>
+ <para>Network uses a bus based topology with 10 base 2
+ Ethernet (<quote>thinnet</quote>). Connect router to network cable with
+ AUI/10BT transceiver, if necessary.</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="advanced-networking/isdn-bus"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced">---Sun workstation
+|
+---FreeBSD box
+|
+---Windows 95
+|
+Stand-alone router
+ |
+ISDN BRI line</literallayout>
+ </textobject>
+
+ <textobject>
+ <phrase>10 Base 2 Ethernet</phrase>
+ </textobject>
+ </mediaobject>
+
+ <para>If your home/branch office is only one computer you can use a
+ twisted pair crossover cable to connect to the stand-alone router
+ directly.</para>
+ </example>
+
+ <example>
+ <title>Head Office or Other LAN</title>
+
+ <indexterm><primary>10 base T</primary></indexterm>
+ <para>Network uses a star topology with 10 base T Ethernet
+ (<quote>Twisted Pair</quote>).</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="advanced-networking/isdn-twisted-pair"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced"> -------Novell Server
+ | H |
+ | ---Sun
+ | |
+ | U ---FreeBSD
+ | |
+ | ---Windows 95
+ | B |
+ |___---Stand-alone router
+ |
+ ISDN BRI line</literallayout>
+ </textobject>
+
+ <textobject>
+ <phrase>ISDN Network Diagram</phrase>
+ </textobject>
+ </mediaobject>
+ </example>
+
+ <para>One large advantage of most routers/bridges is that they allow you
+ to have 2 <emphasis>separate independent</emphasis> PPP connections to
+ 2 separate sites at the <emphasis>same</emphasis> time. This is not
+ supported on most TA's, except for specific (usually expensive) models
+ that
+ have two serial ports. Do not confuse this with channel bonding, MPP,
+ etc.</para>
+
+ <para>This can be a very useful feature if, for example, you
+ have an dedicated ISDN connection at your office and would
+ like to tap into it, but do not want to get another ISDN line
+ at work. A router at the office location can manage a
+ dedicated B channel connection (64&nbsp;Kbps) to the Internet
+ and use the other B channel for a separate data connection.
+ The second B channel can be used for dial-in, dial-out or
+ dynamically bonding (MPP, etc.) with the first B channel for
+ more bandwidth.</para>
+
+ <indexterm><primary>IPX/SPX</primary></indexterm>
+ <para>An Ethernet bridge will also allow you to transmit more than just
+ IP traffic. You can also send IPX/SPX or whatever other protocols you
+ use.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-natd">
+ <info><title>Network Address Translation</title>
+ <authorgroup>
+ <author><personname><firstname>Chern</firstname><surname>Lee</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <sect2 xml:id="network-natoverview">
+ <title>Overview</title>
+ <indexterm>
+ <primary><application>natd</application></primary>
+ </indexterm>
+ <para>FreeBSD's Network Address Translation daemon, commonly known as
+ &man.natd.8; is a daemon that accepts incoming raw IP packets,
+ changes the source to the local machine and re-injects these packets
+ back into the outgoing IP packet stream. &man.natd.8; does this by changing
+ the source IP address and port such that when data is received back,
+ it is able to determine the original location of the data and forward
+ it back to its original requester.</para>
+ <indexterm><primary>Internet connection sharing</primary></indexterm>
+ <indexterm><primary>NAT</primary></indexterm>
+ <para>The most common use of NAT is to perform what is commonly known as
+ Internet Connection Sharing.</para>
+ </sect2>
+
+ <sect2 xml:id="network-natsetup">
+ <title>Setup</title>
+ <para>Due to the diminishing IP space in IPv4, and the increased number
+ of users on high-speed consumer lines such as cable or DSL, people are
+ increasingly in need of an Internet Connection Sharing solution. The
+ ability to connect several computers online through one connection and
+ IP address makes &man.natd.8; a reasonable choice.</para>
+
+ <para>Most commonly, a user has a machine connected to a cable or DSL
+ line with one IP address and wishes to use this one connected computer to
+ provide Internet access to several more over a LAN.</para>
+
+ <para>To do this, the FreeBSD machine on the Internet must act as a
+ gateway. This gateway machine must have two NICs&mdash;one for connecting
+ to the Internet router, the other connecting to a LAN. All the
+ machines on the LAN are connected through a hub or switch.</para>
+
+ <note>
+ <para>There are many ways to get a LAN connected to the Internet
+ through a &os; gateway. This example will only cover a
+ gateway with at least two NICs.</para>
+ </note>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="advanced-networking/natd"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced"> _______ __________ ________
+ | | | | | |
+ | Hub |-----| Client B |-----| Router |----- Internet
+ |_______| |__________| |________|
+ |
+ ____|_____
+| |
+| Client A |
+|__________|</literallayout>
+ </textobject>
+
+ <textobject>
+ <phrase>Network Layout</phrase>
+ </textobject>
+ </mediaobject>
+
+ <para>A setup like this is commonly used to share an Internet
+ connection. One of the <acronym>LAN</acronym> machines is
+ connected to the Internet. The rest of the machines access
+ the Internet through that <quote>gateway</quote>
+ machine.</para>
+ </sect2>
+
+ <sect2 xml:id="network-natdkernconfiguration">
+ <title>Configuration</title>
+
+ <indexterm>
+ <primary>kernel</primary>
+ <secondary>configuration</secondary>
+ </indexterm>
+
+ <para>The following options must be in the kernel configuration
+ file:</para>
+ <programlisting>options IPFIREWALL
+options IPDIVERT</programlisting>
+
+ <para>Additionally, at choice, the following may also be suitable:</para>
+ <programlisting>options IPFIREWALL_DEFAULT_TO_ACCEPT
+options IPFIREWALL_VERBOSE</programlisting>
+
+ <para>The following must be in <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>gateway_enable="YES" <co xml:id="co-natd-gateway-enable"/>
+firewall_enable="YES" <co xml:id="co-natd-firewall-enable"/>
+firewall_type="OPEN" <co xml:id="co-natd-firewall-type"/>
+natd_enable="YES"
+natd_interface="<replaceable>fxp0</replaceable>" <co xml:id="co-natd-natd-interface"/>
+natd_flags="" <co xml:id="co-natd-natd-flags"/></programlisting>
+
+ <calloutlist>
+ <callout arearefs="co-natd-gateway-enable">
+ <para>Sets up the machine to act as a gateway. Running
+ <command>sysctl net.inet.ip.forwarding=1</command> would
+ have the same effect.</para>
+ </callout>
+
+ <callout arearefs="co-natd-firewall-enable">
+ <para>Enables the firewall rules in
+ <filename>/etc/rc.firewall</filename> at boot.</para>
+ </callout>
+
+ <callout arearefs="co-natd-firewall-type">
+ <para>This specifies a predefined firewall ruleset that
+ allows anything in. See
+ <filename>/etc/rc.firewall</filename> for additional
+ types.</para>
+ </callout>
+
+ <callout arearefs="co-natd-natd-interface">
+ <para>Indicates which interface to forward packets through
+ (the interface connected to the Internet).</para>
+ </callout>
+
+ <callout arearefs="co-natd-natd-flags">
+ <para>Any additional configuration options passed to
+ &man.natd.8; on boot.</para>
+ </callout>
+ </calloutlist>
+
+ <para>Having the previous options defined in
+ <filename>/etc/rc.conf</filename> would run
+ <command>natd -interface fxp0</command> at boot. This can also
+ be run manually.</para>
+
+ <note>
+ <para>It is also possible to use a configuration file for
+ &man.natd.8; when there are too many options to pass. In this
+ case, the configuration file must be defined by adding the
+ following line to <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>natd_flags="-f /etc/natd.conf"</programlisting>
+
+ <para>The <filename>/etc/natd.conf</filename> file will
+ contain a list of configuration options, one per line. For
+ example the next section case would use the following
+ file:</para>
+
+ <programlisting>redirect_port tcp 192.168.0.2:6667 6667
+redirect_port tcp 192.168.0.3:80 80</programlisting>
+
+ <para>For more information about the configuration file,
+ consult the &man.natd.8; manual page about the
+ <option>-f</option> option.</para>
+ </note>
+
+ <para>Each machine and interface behind the LAN should be
+ assigned IP address numbers in the private network space as
+ defined by <link xlink:href="ftp://ftp.isi.edu/in-notes/rfc1918.txt">RFC 1918</link>
+ and have a default gateway of the <application>natd</application> machine's internal IP
+ address.</para>
+
+ <para>For example, client <systemitem>A</systemitem> and
+ <systemitem>B</systemitem> behind the LAN have IP addresses of <systemitem class="ipaddress">192.168.0.2</systemitem> and <systemitem class="ipaddress">192.168.0.3</systemitem>, while the natd machine's
+ LAN interface has an IP address of <systemitem class="ipaddress">192.168.0.1</systemitem>. Client <systemitem>A</systemitem>
+ and <systemitem>B</systemitem>'s default gateway must be set to that
+ of the <application>natd</application> machine, <systemitem class="ipaddress">192.168.0.1</systemitem>. The <application>natd</application> machine's
+ external, or Internet interface does not require any special
+ modification for &man.natd.8; to work.</para>
+ </sect2>
+
+ <sect2 xml:id="network-natdport-redirection">
+ <title>Port Redirection</title>
+
+ <para>The drawback with &man.natd.8; is that the LAN clients are not accessible
+ from the Internet. Clients on the LAN can make outgoing connections to
+ the world but cannot receive incoming ones. This presents a problem
+ if trying to run Internet services on one of the LAN client machines.
+ A simple way around this is to redirect selected Internet ports on the
+ <application>natd</application> machine to a LAN client.
+ </para>
+
+ <para>For example, an IRC server runs on client <systemitem>A</systemitem>, and a web server runs
+ on client <systemitem>B</systemitem>. For this to work properly, connections received on ports
+ 6667 (IRC) and 80 (web) must be redirected to the respective machines.
+ </para>
+
+ <para>The <option>-redirect_port</option> must be passed to
+ &man.natd.8; with the proper options. The syntax is as follows:</para>
+ <programlisting> -redirect_port proto targetIP:targetPORT[-targetPORT]
+ [aliasIP:]aliasPORT[-aliasPORT]
+ [remoteIP[:remotePORT[-remotePORT]]]</programlisting>
+
+ <para>In the above example, the argument should be:</para>
+
+ <programlisting> -redirect_port tcp 192.168.0.2:6667 6667
+ -redirect_port tcp 192.168.0.3:80 80</programlisting>
+
+ <para>
+ This will redirect the proper <emphasis>tcp</emphasis> ports to the
+ LAN client machines.
+ </para>
+
+ <para>The <option>-redirect_port</option> argument can be used to indicate port
+ ranges over individual ports. For example, <replaceable>tcp
+ 192.168.0.2:2000-3000 2000-3000</replaceable> would redirect
+ all connections received on ports 2000 to 3000 to ports 2000
+ to 3000 on client <systemitem>A</systemitem>.</para>
+
+ <para>These options can be used when directly running
+ &man.natd.8;, placed within the
+ <literal>natd_flags=""</literal> option in
+ <filename>/etc/rc.conf</filename>,
+ or passed via a configuration file.</para>
+
+ <para>For further configuration options, consult &man.natd.8;</para>
+ </sect2>
+
+ <sect2 xml:id="network-natdaddress-redirection">
+ <title>Address Redirection</title>
+ <indexterm><primary>address redirection</primary></indexterm>
+ <para>Address redirection is useful if several IP addresses are
+ available, yet they must be on one machine. With this,
+ &man.natd.8; can assign each LAN client its own external IP address.
+ &man.natd.8; then rewrites outgoing packets from the LAN clients
+ with the proper external IP address and redirects
+ all traffic incoming on that particular IP address back to
+ the specific LAN client. This is also known as static NAT.
+ For example, the IP addresses <systemitem class="ipaddress">128.1.1.1</systemitem>,
+ <systemitem class="ipaddress">128.1.1.2</systemitem>, and
+ <systemitem class="ipaddress">128.1.1.3</systemitem> belong to the <application>natd</application> gateway
+ machine. <systemitem class="ipaddress">128.1.1.1</systemitem> can be used
+ as the <application>natd</application> gateway machine's external IP address, while
+ <systemitem class="ipaddress">128.1.1.2</systemitem> and
+ <systemitem class="ipaddress">128.1.1.3</systemitem> are forwarded back to LAN
+ clients <systemitem>A</systemitem> and <systemitem>B</systemitem>.</para>
+
+ <para>The <option>-redirect_address</option> syntax is as follows:</para>
+
+ <programlisting>-redirect_address localIP publicIP</programlisting>
+
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>localIP</entry>
+ <entry>The internal IP address of the LAN client.</entry>
+ </row>
+ <row>
+ <entry>publicIP</entry>
+ <entry>The external IP address corresponding to the LAN client.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>In the example, this argument would read:</para>
+
+ <programlisting>-redirect_address 192.168.0.2 128.1.1.2
+-redirect_address 192.168.0.3 128.1.1.3</programlisting>
+
+ <para>Like <option>-redirect_port</option>, these arguments are also placed within
+ the <literal>natd_flags=""</literal> option of <filename>/etc/rc.conf</filename>, or passed via a configuration file. With address
+ redirection, there is no need for port redirection since all data
+ received on a particular IP address is redirected.</para>
+
+ <para>The external IP addresses on the <application>natd</application> machine must be active and aliased
+ to the external interface. Look at &man.rc.conf.5; to do so.</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-plip">
+ <title>Parallel Line IP (PLIP)</title>
+
+ <indexterm><primary>PLIP</primary></indexterm>
+ <indexterm>
+ <primary>Parallel Line IP</primary>
+ <see>PLIP</see>
+ </indexterm>
+
+ <para>PLIP lets us run TCP/IP between parallel ports. It is
+ useful on machines without network cards, or to install on
+ laptops. In this section, we will discuss:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Creating a parallel (laplink) cable.</para>
+ </listitem>
+
+ <listitem>
+ <para>Connecting two computers with PLIP.</para>
+ </listitem>
+ </itemizedlist>
+
+ <sect2 xml:id="network-create-parallel-cable">
+ <title>Creating a Parallel Cable</title>
+
+ <para>You can purchase a parallel cable at most computer supply
+ stores. If you cannot do that, or you just want to know how
+ it is done, the following table shows how to make one out of a normal parallel
+ printer cable.</para>
+
+ <table frame="none">
+ <title>Wiring a Parallel Cable for Networking</title>
+
+ <tgroup cols="5">
+ <thead>
+ <row>
+ <entry>A-name</entry>
+
+ <entry>A-End</entry>
+
+ <entry>B-End</entry>
+
+ <entry>Descr.</entry>
+
+ <entry>Post/Bit</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literallayout>DATA0
+-ERROR</literallayout></entry>
+
+ <entry><literallayout>2
+15</literallayout></entry>
+
+ <entry><literallayout>15
+2</literallayout></entry>
+
+ <entry>Data</entry>
+
+ <entry><literallayout>0/0x01
+1/0x08</literallayout></entry>
+ </row>
+
+ <row>
+ <entry><literallayout>DATA1
++SLCT</literallayout></entry>
+
+ <entry><literallayout>3
+13</literallayout></entry>
+
+ <entry><literallayout>13
+3</literallayout></entry>
+
+ <entry>Data</entry>
+
+ <entry><literallayout>0/0x02
+1/0x10</literallayout></entry>
+ </row>
+
+ <row>
+ <entry><literallayout>DATA2
++PE</literallayout></entry>
+
+ <entry><literallayout>4
+12</literallayout></entry>
+
+ <entry><literallayout>12
+4</literallayout></entry>
+
+ <entry>Data</entry>
+
+ <entry><literallayout>0/0x04
+1/0x20</literallayout></entry>
+ </row>
+
+ <row>
+ <entry><literallayout>DATA3
+-ACK</literallayout></entry>
+
+ <entry><literallayout>5
+10</literallayout></entry>
+
+ <entry><literallayout>10
+5</literallayout></entry>
+
+ <entry>Strobe</entry>
+
+ <entry><literallayout>0/0x08
+1/0x40</literallayout></entry>
+ </row>
+
+ <row>
+ <entry><literallayout>DATA4
+BUSY</literallayout></entry>
+
+ <entry><literallayout>6
+11</literallayout></entry>
+
+ <entry><literallayout>11
+6</literallayout></entry>
+
+ <entry>Data</entry>
+
+ <entry><literallayout>0/0x10
+1/0x80</literallayout></entry>
+ </row>
+
+ <row>
+ <entry>GND</entry>
+
+ <entry>18-25</entry>
+
+ <entry>18-25</entry>
+
+ <entry>GND</entry>
+
+ <entry>-</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 xml:id="network-plip-setup">
+ <title>Setting Up PLIP</title>
+
+ <para>First, you have to get a laplink cable.
+ Then, confirm that both computers have a kernel with &man.lpt.4; driver
+ support:</para>
+
+ <screen>&prompt.root; <userinput>grep lp /var/run/dmesg.boot</userinput>
+lpt0: &lt;Printer&gt; on ppbus0
+lpt0: Interrupt-driven port</screen>
+
+ <para>The parallel port must be an interrupt driven port,
+ you should have lines similar to the
+ following in your in the
+ <filename>/boot/device.hints</filename> file:</para>
+
+ <programlisting>hint.ppc.0.at="isa"
+hint.ppc.0.irq="7"</programlisting>
+
+ <para>Then check if the kernel configuration file has a
+ <literal>device plip</literal> line or if the
+ <filename>plip.ko</filename> kernel module is loaded. In both
+ cases the parallel networking interface should appear when you
+ use the &man.ifconfig.8; command to display it:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig plip0</userinput>
+plip0: flags=8810&lt;POINTOPOINT,SIMPLEX,MULTICAST&gt; mtu 1500</screen>
+
+ <para>Plug the laplink cable into the parallel interface on
+ both computers.</para>
+
+ <para>Configure the network interface parameters on both
+ sites as <systemitem class="username">root</systemitem>. For example, if you want to connect
+ the host <systemitem>host1</systemitem> with another machine <systemitem>host2</systemitem>:</para>
+
+ <programlisting> host1 &lt;-----&gt; host2
+IP Address 10.0.0.1 10.0.0.2</programlisting>
+
+ <para>Configure the interface on <systemitem>host1</systemitem> by doing:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig plip0 10.0.0.1 10.0.0.2</userinput></screen>
+
+ <para>Configure the interface on <systemitem>host2</systemitem> by doing:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig plip0 10.0.0.2 10.0.0.1</userinput></screen>
+
+
+ <para>You now should have a working connection. Please read the
+ manual pages &man.lp.4; and &man.lpt.4; for more details.</para>
+
+ <para>You should also add both hosts to
+ <filename>/etc/hosts</filename>:</para>
+
+ <programlisting>127.0.0.1 localhost.my.domain localhost
+10.0.0.1 host1.my.domain host1
+10.0.0.2 host2.my.domain</programlisting>
+
+ <para>To confirm the connection works, go to each host and ping
+ the other. For example, on <systemitem>host1</systemitem>:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig plip0</userinput>
+plip0: flags=8851&lt;UP,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet 10.0.0.1 --&gt; 10.0.0.2 netmask 0xff000000
+&prompt.root; <userinput>netstat -r</userinput>
+Routing tables
+
+Internet:
+Destination Gateway Flags Refs Use Netif Expire
+host2 host1 UH 0 0 plip0
+&prompt.root; <userinput>ping -c 4 host2</userinput>
+PING host2 (10.0.0.2): 56 data bytes
+64 bytes from 10.0.0.2: icmp_seq=0 ttl=255 time=2.774 ms
+64 bytes from 10.0.0.2: icmp_seq=1 ttl=255 time=2.530 ms
+64 bytes from 10.0.0.2: icmp_seq=2 ttl=255 time=2.556 ms
+64 bytes from 10.0.0.2: icmp_seq=3 ttl=255 time=2.714 ms
+
+--- host2 ping statistics ---
+4 packets transmitted, 4 packets received, 0% packet loss
+round-trip min/avg/max/stddev = 2.530/2.643/2.774/0.103 ms</screen>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-ipv6">
+ <info><title>IPv6</title>
+ <authorgroup>
+ <author><personname><firstname>Aaron</firstname><surname>Kaplan</surname></personname><contrib>Originally Written by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Restructured and Added by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Brad</firstname><surname>Davis</surname></personname><contrib>Extended by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+ <para>IPv6 (also known as IPng <quote>IP next generation</quote>) is
+ the new version of the well known IP protocol (also known as
+ <acronym>IPv4</acronym>). Like the other current *BSD systems,
+ FreeBSD includes the KAME IPv6 reference implementation.
+ So your FreeBSD system comes with all you will need to experiment with IPv6.
+ This section focuses on getting IPv6 configured and running.</para>
+
+ <para>In the early 1990s, people became aware of the rapidly
+ diminishing address space of IPv4. Given the expansion rate of the
+ Internet there were two major concerns:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Running out of addresses. Today this is not so much of a concern
+ anymore since RFC1918 private address space
+ (<systemitem class="ipaddress">10.0.0.0/8</systemitem>,
+ <systemitem class="ipaddress">172.16.0.0/12</systemitem>, and
+ <systemitem class="ipaddress">192.168.0.0/16</systemitem>)
+ and Network Address Translation (<acronym>NAT</acronym>) are
+ being employed.</para>
+ </listitem>
+
+ <listitem>
+ <para>Router table entries were getting too large. This is
+ still a concern today.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>IPv6 deals with these and many other issues:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>128 bit address space. In other words theoretically there are
+ 340,282,366,920,938,463,463,374,607,431,768,211,456 addresses
+ available. This means there are approximately
+ 6.67 * 10^27 IPv6 addresses per square meter on our planet.</para>
+ </listitem>
+
+ <listitem>
+ <para>Routers will only store network aggregation addresses in their routing
+ tables thus reducing the average space of a routing table to 8192
+ entries.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>There are also lots of other useful features of IPv6 such as:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Address autoconfiguration (<link xlink:href="http://www.ietf.org/rfc/rfc2462.txt">RFC2462</link>)</para>
+ </listitem>
+
+ <listitem>
+ <para>Anycast addresses (<quote>one-out-of many</quote>)</para>
+ </listitem>
+
+ <listitem>
+ <para>Mandatory multicast addresses</para>
+ </listitem>
+
+ <listitem>
+ <para>IPsec (IP security)</para>
+ </listitem>
+
+ <listitem>
+ <para>Simplified header structure</para>
+ </listitem>
+
+ <listitem>
+ <para>Mobile <acronym>IP</acronym></para>
+ </listitem>
+
+ <listitem>
+ <para>IPv6-to-IPv4 transition mechanisms</para>
+ </listitem>
+ </itemizedlist>
+
+
+ <para>For more information see:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>IPv6 overview at <link xlink:href="http://playground.sun.com/pub/ipng/html/ipng-main.html">playground.sun.com</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.kame.net">KAME.net</link></para>
+ </listitem>
+ </itemizedlist>
+
+ <sect2>
+ <title>Background on IPv6 Addresses</title>
+ <para>There are different types of IPv6 addresses: Unicast, Anycast and
+ Multicast.</para>
+
+ <para>Unicast addresses are the well known addresses. A packet sent
+ to a unicast address arrives exactly at the interface belonging to
+ the address.</para>
+
+ <para>Anycast addresses are syntactically indistinguishable from unicast
+ addresses but they address a group of interfaces. The packet destined for
+ an anycast address will arrive at the nearest (in router metric)
+ interface. Anycast addresses may only be used by routers.</para>
+
+ <para>Multicast addresses identify a group of interfaces. A packet destined
+ for a multicast address will arrive at all interfaces belonging to the
+ multicast group.</para>
+
+ <note><para>The IPv4 broadcast address (usually <systemitem class="ipaddress">xxx.xxx.xxx.255</systemitem>) is expressed
+ by multicast addresses in IPv6.</para></note>
+
+ <table frame="none">
+ <title>Reserved IPv6 addresses</title>
+
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>IPv6 address</entry>
+ <entry>Prefixlength (Bits)</entry>
+ <entry>Description</entry>
+ <entry>Notes</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><systemitem>::</systemitem></entry>
+ <entry>128 bits</entry>
+ <entry>unspecified</entry>
+ <entry>cf. <systemitem class="ipaddress">0.0.0.0</systemitem> in
+ IPv4</entry>
+ </row>
+
+ <row>
+ <entry><systemitem>::1</systemitem></entry>
+ <entry>128 bits</entry>
+ <entry>loopback address</entry>
+ <entry>cf. <systemitem class="ipaddress">127.0.0.1</systemitem> in
+ IPv4</entry>
+ </row>
+
+ <row>
+ <entry><systemitem>::00:xx:xx:xx:xx</systemitem></entry>
+ <entry>96 bits</entry>
+ <entry>embedded IPv4</entry>
+ <entry>The lower 32 bits are the IPv4 address. Also
+ called <quote>IPv4 compatible IPv6
+ address</quote></entry>
+ </row>
+
+ <row>
+ <entry><systemitem>::ff:xx:xx:xx:xx</systemitem></entry>
+ <entry>96 bits</entry>
+ <entry>IPv4 mapped IPv6 address</entry>
+ <entry>The lower 32 bits are the IPv4 address.
+ For hosts which do not support IPv6.</entry>
+ </row>
+
+ <row>
+ <entry><systemitem>fe80::</systemitem> - <systemitem>feb::</systemitem></entry>
+ <entry>10 bits</entry>
+ <entry>link-local</entry>
+ <entry>cf. loopback address in IPv4</entry>
+ </row>
+
+ <row>
+ <entry><systemitem>fec0::</systemitem> - <systemitem>fef::</systemitem></entry>
+ <entry>10 bits</entry>
+ <entry>site-local</entry>
+ <entry>&nbsp;</entry>
+ </row>
+
+ <row>
+ <entry><systemitem>ff::</systemitem></entry>
+ <entry>8 bits</entry>
+ <entry>multicast</entry>
+ <entry>&nbsp;</entry>
+ </row>
+
+ <row>
+ <entry><systemitem>001</systemitem> (base
+ 2)</entry>
+ <entry>3 bits</entry>
+ <entry>global unicast</entry>
+ <entry>All global unicast addresses are assigned from
+ this pool. The first 3 bits are
+ <quote>001</quote>.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2>
+ <title>Reading IPv6 Addresses</title>
+ <para>The canonical form is represented as: <systemitem>x:x:x:x:x:x:x:x</systemitem>, each
+ <quote>x</quote> being a 16 Bit hex value. For example
+ <systemitem>FEBC:A574:382B:23C1:AA49:4592:4EFE:9982</systemitem></para>
+
+ <para>Often an address will have long substrings of all zeros
+ therefore one such substring per address can be abbreviated by <quote>::</quote>.
+ Also up to three leading <quote>0</quote>s per hexquad can be omitted.
+ For example <systemitem>fe80::1</systemitem>
+ corresponds to the canonical form
+ <systemitem>fe80:0000:0000:0000:0000:0000:0000:0001</systemitem>.</para>
+
+ <para>A third form is to write the last 32 Bit part in the
+ well known (decimal) IPv4 style with dots <quote>.</quote>
+ as separators. For example
+ <systemitem>2002::10.0.0.1</systemitem>
+ corresponds to the (hexadecimal) canonical representation
+ <systemitem>2002:0000:0000:0000:0000:0000:0a00:0001</systemitem>
+ which in turn is equivalent to
+ writing <systemitem>2002::a00:1</systemitem>.</para>
+
+ <para>By now the reader should be able to understand the following:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig</userinput></screen>
+
+ <programlisting>rl0: flags=8943&lt;UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet 10.0.0.10 netmask 0xffffff00 broadcast 10.0.0.255
+ inet6 fe80::200:21ff:fe03:8e1%rl0 prefixlen 64 scopeid 0x1
+ ether 00:00:21:03:08:e1
+ media: Ethernet autoselect (100baseTX )
+ status: active</programlisting>
+
+ <para><systemitem>fe80::200:21ff:fe03:8e1%rl0</systemitem>
+ is an auto configured link-local address. It is generated from the MAC
+ address as part of the auto configuration.</para>
+
+ <para>For further information on the structure of IPv6 addresses
+ see <link xlink:href="http://www.ietf.org/rfc/rfc3513.txt">RFC3513</link>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Getting Connected</title>
+
+ <para>Currently there are four ways to connect to other IPv6 hosts and networks:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Getting an IPv6 network from your upstream provider. Talk to your
+ Internet provider for instructions.</para>
+ </listitem>
+
+ <listitem>
+ <para>Tunnel via 6-to-4 (<link xlink:href="http://www.ietf.org/rfc/rfc3068.txt">RFC3068</link>)</para>
+ </listitem>
+
+ <listitem>
+ <para>Use the <package>net/freenet6</package> port if you are on a dial-up connection.</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>DNS in the IPv6 World</title>
+
+ <para>There used to be two types of DNS records for IPv6. The IETF
+ has declared A6 records obsolete. AAAA records are the standard
+ now.</para>
+
+ <para>Using AAAA records is straightforward. Assign your hostname to the new
+ IPv6 address you just received by adding:</para>
+
+ <programlisting>MYHOSTNAME AAAA MYIPv6ADDR</programlisting>
+
+ <para>To your primary zone DNS file. In case you do not serve your own
+ <acronym>DNS</acronym> zones ask your <acronym>DNS</acronym> provider.
+ Current versions of <application>bind</application> (version 8.3 and 9)
+ and <package>dns/djbdns</package> (with the IPv6 patch)
+ support AAAA records.</para>
+ </sect2>
+
+ <sect2>
+ <title>Applying the needed changes to <filename>/etc/rc.conf</filename></title>
+
+ <sect3>
+ <title>IPv6 Client Settings</title>
+
+ <para>These settings will help you configure a machine that will be on
+ your LAN and act as a client, not a router. To have &man.rtsol.8;
+ autoconfigure your interface on boot all you need to add is:</para>
+
+ <programlisting>ipv6_enable="YES"</programlisting>
+
+ <para>To statically assign an IP address such as <systemitem>
+ 2001:471:1f11:251:290:27ff:fee0:2093</systemitem>, to your
+ <filename>fxp0</filename> interface, add:</para>
+
+ <programlisting>ipv6_ifconfig_fxp0="2001:471:1f11:251:290:27ff:fee0:2093"</programlisting>
+
+ <para>To assign a default router of
+ <systemitem>2001:471:1f11:251::1</systemitem>
+ add the following to <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>ipv6_defaultrouter="2001:471:1f11:251::1"</programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>IPv6 Router/Gateway Settings</title>
+
+ <para>This will help you take the directions that your tunnel provider has
+ given you and convert it into settings that will persist through reboots.
+ To restore your tunnel on startup use something like the following in
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <para>List the Generic Tunneling interfaces that will be configured, for
+ example <filename>gif0</filename>:</para>
+
+ <programlisting>gif_interfaces="gif0"</programlisting>
+
+ <para>To configure the interface with a local endpoint of
+ <replaceable>MY_IPv4_ADDR</replaceable> to a remote endpoint of
+ <replaceable>REMOTE_IPv4_ADDR</replaceable>:</para>
+
+ <programlisting>gifconfig_gif0="<replaceable>MY_IPv4_ADDR REMOTE_IPv4_ADDR</replaceable>"</programlisting>
+
+ <para>To apply the IPv6 address you have been assigned for use as your
+ IPv6 tunnel endpoint, add:</para>
+
+ <programlisting>ipv6_ifconfig_gif0="<replaceable>MY_ASSIGNED_IPv6_TUNNEL_ENDPOINT_ADDR</replaceable>"</programlisting>
+
+ <para>Then all you have to do is set the default route for IPv6. This is
+ the other side of the IPv6 tunnel:</para>
+
+ <programlisting>ipv6_defaultrouter="<replaceable>MY_IPv6_REMOTE_TUNNEL_ENDPOINT_ADDR</replaceable>"</programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>IPv6 Tunnel Settings</title>
+
+ <para>If the server is to route IPv6 between the rest of your network
+ and the world, the following <filename>/etc/rc.conf</filename>
+ setting will also be needed:</para>
+
+ <programlisting>ipv6_gateway_enable="YES"</programlisting>
+
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Router Advertisement and Host Auto Configuration</title>
+
+ <para>This section will help you setup &man.rtadvd.8; to advertise the
+ IPv6 default route.</para>
+
+ <para>To enable &man.rtadvd.8; you will need the following in your
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>rtadvd_enable="YES"</programlisting>
+
+ <para>It is important that you specify the interface on which to do
+ IPv6 router solicitation. For example to tell &man.rtadvd.8; to use
+ <filename>fxp0</filename>:</para>
+
+ <programlisting>rtadvd_interfaces="fxp0"</programlisting>
+
+ <para>Now we must create the configuration file,
+ <filename>/etc/rtadvd.conf</filename>. Here is an example:</para>
+
+ <programlisting>fxp0:\
+ :addrs#1:addr="2001:471:1f11:246::":prefixlen#64:tc=ether:</programlisting>
+
+ <para>Replace <filename>fxp0</filename> with the interface you
+ are going to be using.</para>
+
+ <para>Next, replace <systemitem>2001:471:1f11:246::</systemitem>
+ with the prefix of your allocation.</para>
+
+ <para>If you are dedicated a <systemitem class="netmask">/64</systemitem> subnet
+ you will not need to change anything else. Otherwise, you will need to
+ change the <literal>prefixlen#</literal> to the correct value.</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-atm">
+ <info><title>Asynchronous Transfer Mode (ATM)</title>
+ <authorgroup>
+ <author><personname><firstname>Harti</firstname><surname>Brandt</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect2>
+ <title>Configuring classical IP over ATM (PVCs)</title>
+
+ <para>Classical IP over ATM (<acronym>CLIP</acronym>) is the
+ simplest method to use Asynchronous Transfer Mode (ATM)
+ with IP. It can be used with
+ switched connections (SVCs) and with permanent connections
+ (PVCs). This section describes how to set up a network based
+ on PVCs.</para>
+
+ <sect3>
+ <title>Fully meshed configurations</title>
+
+ <para>The first method to set up a <acronym>CLIP</acronym> with
+ PVCs is to connect each machine to each other machine in the
+ network via a dedicated PVC. While this is simple to
+ configure it tends to become impractical for a larger number
+ of machines. The example supposes that we have four
+ machines in the network, each connected to the <acronym role="Asynchronous Transfer Mode">ATM</acronym> network
+ with an <acronym role="Asynchronous Transfer Mode">ATM</acronym> adapter card. The first step is the planning of
+ the IP addresses and the <acronym role="Asynchronous Transfer Mode">ATM</acronym> connections between the
+ machines. We use the following:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Host</entry>
+ <entry>IP Address</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><systemitem>hostA</systemitem></entry>
+ <entry><systemitem class="ipaddress">192.168.173.1</systemitem></entry>
+ </row>
+
+ <row>
+ <entry><systemitem>hostB</systemitem></entry>
+ <entry><systemitem class="ipaddress">192.168.173.2</systemitem></entry>
+ </row>
+
+ <row>
+ <entry><systemitem>hostC</systemitem></entry>
+ <entry><systemitem class="ipaddress">192.168.173.3</systemitem></entry>
+ </row>
+
+ <row>
+ <entry><systemitem>hostD</systemitem></entry>
+ <entry><systemitem class="ipaddress">192.168.173.4</systemitem></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>To build a fully meshed net we need one ATM connection
+ between each pair of machines:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Machines</entry>
+ <entry>VPI.VCI couple</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><systemitem>hostA</systemitem> - <systemitem>hostB</systemitem></entry>
+ <entry>0.100</entry>
+ </row>
+
+ <row>
+ <entry><systemitem>hostA</systemitem> - <systemitem>hostC</systemitem></entry>
+ <entry>0.101</entry>
+ </row>
+
+ <row>
+ <entry><systemitem>hostA</systemitem> - <systemitem>hostD</systemitem></entry>
+ <entry>0.102</entry>
+ </row>
+
+ <row>
+ <entry><systemitem>hostB</systemitem> - <systemitem>hostC</systemitem></entry>
+ <entry>0.103</entry>
+ </row>
+
+ <row>
+ <entry><systemitem>hostB</systemitem> - <systemitem>hostD</systemitem></entry>
+ <entry>0.104</entry>
+ </row>
+
+ <row>
+ <entry><systemitem>hostC</systemitem> - <systemitem>hostD</systemitem></entry>
+ <entry>0.105</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>The VPI and VCI values at each end of the connection may
+ of course differ, but for simplicity we assume that they are
+ the same. Next we need to configure the ATM interfaces on
+ each host:</para>
+
+ <screen>hostA&prompt.root; <userinput>ifconfig hatm0 192.168.173.1 up</userinput>
+hostB&prompt.root; <userinput>ifconfig hatm0 192.168.173.2 up</userinput>
+hostC&prompt.root; <userinput>ifconfig hatm0 192.168.173.3 up</userinput>
+hostD&prompt.root; <userinput>ifconfig hatm0 192.168.173.4 up</userinput></screen>
+
+ <para>assuming that the ATM interface is
+ <filename>hatm0</filename> on all hosts. Now the PVCs
+ need to be configured on <systemitem>hostA</systemitem> (we assume that
+ they are already configured on the ATM switches, you need to
+ consult the manual for the switch on how to do this).</para>
+
+ <screen>hostA&prompt.root; <userinput>atmconfig natm add 192.168.173.2 hatm0 0 100 llc/snap ubr</userinput>
+hostA&prompt.root; <userinput>atmconfig natm add 192.168.173.3 hatm0 0 101 llc/snap ubr</userinput>
+hostA&prompt.root; <userinput>atmconfig natm add 192.168.173.4 hatm0 0 102 llc/snap ubr</userinput>
+
+hostB&prompt.root; <userinput>atmconfig natm add 192.168.173.1 hatm0 0 100 llc/snap ubr</userinput>
+hostB&prompt.root; <userinput>atmconfig natm add 192.168.173.3 hatm0 0 103 llc/snap ubr</userinput>
+hostB&prompt.root; <userinput>atmconfig natm add 192.168.173.4 hatm0 0 104 llc/snap ubr</userinput>
+
+hostC&prompt.root; <userinput>atmconfig natm add 192.168.173.1 hatm0 0 101 llc/snap ubr</userinput>
+hostC&prompt.root; <userinput>atmconfig natm add 192.168.173.2 hatm0 0 103 llc/snap ubr</userinput>
+hostC&prompt.root; <userinput>atmconfig natm add 192.168.173.4 hatm0 0 105 llc/snap ubr</userinput>
+
+hostD&prompt.root; <userinput>atmconfig natm add 192.168.173.1 hatm0 0 102 llc/snap ubr</userinput>
+hostD&prompt.root; <userinput>atmconfig natm add 192.168.173.2 hatm0 0 104 llc/snap ubr</userinput>
+hostD&prompt.root; <userinput>atmconfig natm add 192.168.173.3 hatm0 0 105 llc/snap ubr</userinput></screen>
+
+ <para>Of course other traffic contracts than UBR can be used
+ given the ATM adapter supports those. In this case the name
+ of the traffic contract is followed by the parameters of the
+ traffic. Help for the &man.atmconfig.8; tool can be
+ obtained with:</para>
+
+ <screen>&prompt.root; <userinput>atmconfig help natm add</userinput></screen>
+
+ <para>or in the &man.atmconfig.8; manual page.</para>
+
+ <para>The same configuration can also be done via
+ <filename>/etc/rc.conf</filename>.
+ For <systemitem>hostA</systemitem> this would look like:</para>
+
+<programlisting>network_interfaces="lo0 hatm0"
+ifconfig_hatm0="inet 192.168.173.1 up"
+natm_static_routes="hostB hostC hostD"
+route_hostB="192.168.173.2 hatm0 0 100 llc/snap ubr"
+route_hostC="192.168.173.3 hatm0 0 101 llc/snap ubr"
+route_hostD="192.168.173.4 hatm0 0 102 llc/snap ubr"</programlisting>
+
+ <para>The current state of all <acronym>CLIP</acronym> routes
+ can be obtained with:</para>
+
+ <screen>hostA&prompt.root; <userinput>atmconfig natm show</userinput></screen>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="carp">
+ <info><title>Common Access Redundancy Protocol (CARP)</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>CARP</primary></indexterm>
+ <indexterm><primary>Common Access Redundancy Protocol</primary></indexterm>
+
+ <para>The Common Access Redundancy Protocol, or
+ <acronym>CARP</acronym> allows multiple hosts to share the same
+ <acronym>IP</acronym> address. In some configurations, this may
+ be used for availability or load balancing. Hosts may use separate
+ <acronym>IP</acronym> addresses as well, as in the example provided
+ here.</para>
+
+ <para>To enable support for <acronym>CARP</acronym>, the &os;
+ kernel must be rebuilt with the following option:</para>
+
+ <programlisting>device carp</programlisting>
+
+ <para><acronym>CARP</acronym> functionality should now be available
+ and may be tuned via several <command>sysctl</command>
+ <acronym>OID</acronym>s. Devices themselves may be loaded via
+ the <command>ifconfig</command> command:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig carp0 create</userinput></screen>
+
+ <para>In a real environment, these interfaces will need unique
+ identification numbers known as a <acronym>VHID</acronym>. This
+ <acronym>VHID</acronym> or Virtual Host Identification will be
+ used to distinguish the host on the network.</para>
+
+ <sect2>
+ <title>Using CARP For Server Availability (CARP)</title>
+
+ <para>One use of <acronym>CARP</acronym>, as noted above, is for
+ server availability. This example will provide failover support
+ for three hosts, all with unique <acronym>IP</acronym>
+ addresses and providing the same web content. These machines will
+ act in conjunction with a Round Robin <acronym>DNS</acronym>
+ configuration. The failover machine will have two additional
+ <acronym>CARP</acronym> interfaces, one for each of the content
+ server's <acronym>IP</acronym>s. When a failure occurs, the
+ failover server should pick up the failed machine's
+ <acronym>IP</acronym> address. This means the failure should
+ go completely unnoticed to the user. The failover server
+ requires identical content and services as the other content
+ servers it is expected to pick up load for.</para>
+
+ <para>The two machines should be configured identically other
+ than their issued hostnames and <acronym>VHID</acronym>s.
+ This example calls these machines
+ <systemitem>hosta.example.org</systemitem> and
+ <systemitem>hostb.example.org</systemitem> respectively. First, the
+ required lines for a <acronym>CARP</acronym> configuration have
+ to be added to <filename>rc.conf</filename>. For
+ <systemitem>hosta.example.org</systemitem>, the
+ <filename>rc.conf</filename> file should contain the following
+ lines:</para>
+
+ <programlisting>hostname="hosta.example.org"
+ifconfig_fxp0="inet 192.168.1.3 netmask 255.255.255.0"
+cloned_interfaces="carp0"
+ifconfig_carp0="vhid 1 pass testpast 192.168.1.50/24"</programlisting>
+
+ <para>On <systemitem>hostb.example.org</systemitem> the following lines
+ should be in <filename>rc.conf</filename>:</para>
+
+ <programlisting>hostname="hostb.example.org"
+ifconfig_fxp0="inet 192.168.1.4 netmask 255.255.255.0"
+cloned_interfaces="carp0"
+ifconfig_carp0="vhid 2 pass testpass 192.168.1.51/24"</programlisting>
+
+ <note>
+ <para>It is very important that the passwords, specified by the
+ <option>pass</option> option to <command>ifconfig</command>,
+ are identical. The <filename>carp</filename> devices will
+ only listen to and accept advertisements from machines with the
+ correct password. The <acronym>VHID</acronym> must also be
+ different for each machine.</para>
+ </note>
+
+ <para>The third machine,
+ <systemitem>provider.example.org</systemitem>, should be prepared so that
+ it may handle failover from either host. This machine will require
+ two <filename>carp</filename> devices, one to handle each
+ host. The appropriate <filename>rc.conf</filename>
+ configuration lines will be similar to the following:</para>
+
+ <programlisting>hostname="provider.example.org"
+ifconfig_fxp0="inet 192.168.1.5 netmask 255.255.255.0"
+cloned_interfaces="carp0 carp1"
+ifconfig_carp0="vhid 1 advskew 100 pass testpass 192.168.1.50/24"
+ifconfig_carp1="vhid 2 advskew 100 pass testpass 192.168.1.51/24"</programlisting>
+
+ <para>Having the two <filename>carp</filename> devices will
+ allow <systemitem>provider.example.org</systemitem> to notice and pick
+ up the <acronym>IP</acronym> address of either machine should
+ it stop responding.</para>
+
+ <note>
+ <para>The default &os; kernel <emphasis>may</emphasis> have
+ preemption enabled. If so,
+ <systemitem>provider.example.org</systemitem> may not relinquish the
+ <acronym>IP</acronym> address back to the original content
+ server. In this case, an administrator may
+ <quote>nudge</quote> the interface. The following command
+ should be issued on
+ <systemitem>provider.example.org</systemitem>:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig carp0 down &amp;&amp; ifconfig carp0 up</userinput></screen>
+
+ <para>This should be done on the <filename>carp</filename>
+ interface which corresponds to the correct host.</para>
+ </note>
+
+ <para>At this point, <acronym>CARP</acronym> should be completely
+ enabled and available for testing. For testing, either networking has
+ to be restarted or the machines need to be rebooted.</para>
+
+ <para>More information is always available in the &man.carp.4;
+ manual page.</para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/audit/Makefile b/zh_TW.UTF-8/books/handbook/audit/Makefile
new file mode 100644
index 0000000000..2d71ed91f5
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/audit/Makefile
@@ -0,0 +1,16 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+# Original revision: 1.1
+#
+
+CHAPTERS= audit/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/audit/chapter.xml b/zh_TW.UTF-8/books/handbook/audit/chapter.xml
new file mode 100644
index 0000000000..5e899c5b88
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/audit/chapter.xml
@@ -0,0 +1,567 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+ $FreeBSD$
+ Original revision: 1.13
+-->
+<!-- Need more documentation on praudit, auditreduce, etc. Plus more info
+on the triggers from the kernel (log rotation, out of space, etc).
+And the /dev/audit special file if we choose to support that. Could use
+some coverage of integrating MAC with Event auditing and perhaps discussion
+on how some companies or organizations handle auditing and auditing
+requirements. -->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="audit">
+ <info><title>Security Event Auditing</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="audit-synopsis">
+ <title>Synopsis</title>
+
+ <indexterm><primary>AUDIT</primary></indexterm>
+ <indexterm>
+ <primary>Security Event Auditing</primary>
+ <see>MAC</see>
+ </indexterm>
+
+ <para>The &os;&nbsp;7-CURRENT development branch includes
+ support for Event Auditing based on the &posix;.1e draft and
+ Sun's published <acronym>BSM</acronym> API and file format.
+ Event auditing permits the selective logging of security-relevant
+ system events for the purposes of post-mortem analysis, system
+ monitoring, and intrusion detection. After some settling time in
+ &os;&nbsp;7-CURRENT, this support will be merged to &os;&nbsp;6-STABLE
+ and appear in subsequent releases.</para>
+
+ <warning>
+ <para>The audit facility in FreeBSD is considered experimental, and
+ production deployment should occur only after careful consideration
+ of the risks of deploying experimental software.</para>
+ </warning>
+
+ <para>This chapter will focus mainly on the installation and
+ configuration of Event Auditing. Explanation of audit policies,
+ and an example configuration will be provided for the
+ convenience of the reader.</para>
+
+ <para>After reading this chapter, you will know:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>What Event Auditing is and how it works.</para>
+ </listitem>
+
+ <listitem>
+ <para>How to configure Event Auditing on &os; for users
+ and processes.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Before reading this chapter, you should:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Understand &unix; and &os; basics
+ (<xref linkend="basics"/>).</para>
+ </listitem>
+
+ <listitem>
+ <para>Be familiar with the basics of kernel
+ configuration/compilation
+ (<xref linkend="kernelconfig"/>).</para>
+ </listitem>
+
+ <listitem>
+ <para>Have some familiarity with security and how it
+ pertains to &os; (<xref linkend="security"/>).</para>
+ </listitem>
+ </itemizedlist>
+
+ <warning>
+ <para>Event auditing can generate a great deal of log file
+ data, exceeding gigabytes a week in some configurations. An
+ administrator should read this chapter in its entirety to avoid
+ possible self-inflicted <acronym>DoS</acronym> attacks due to
+ improper configuration.</para>
+ </warning>
+
+ <para>The implementation of Event Auditing in &os; is similar to
+ that of the &sun; Basic Security Module, or <acronym>BSM</acronym>
+ library. Thus, the configuration is almost completely
+ interchangeable with &solaris; and Mac OS X/Darwin operating
+ systems.</para>
+ </sect1>
+
+ <sect1 xml:id="audit-inline-glossary">
+ <title>Key Terms - Words to Know</title>
+
+ <para>Before reading this chapter, a few key terms must be
+ explained. This is intended to clear up any confusion that
+ may occur and to avoid the abrupt introduction of new terms
+ and information.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>event</emphasis>: An auditable event is
+ an event that can be logged using the audit subsystem. The
+ administrator can configure which events will be audited.
+ Examples of security-relevant events include the creation of
+ a file, the building of a network connection, or the logging
+ in of a user. Events are either <quote>attributable</quote>,
+ meaning that they can be traced back to a user
+ authentication, or <quote>non-attributable</quote>. Examples
+ of non-attributable events are any events that occur before
+ authentication has succeeded in the login process, such as
+ failed authentication attempts.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>class</emphasis>: Events may be assigned to
+ one or more classes, usually based on the general category
+ of the events, such as <quote>file creation</quote>,
+ <quote>file access</quote>, or <quote>network</quote>. Login
+ and logout events are assigned to the <literal>lo</literal>
+ class. The use of classes allows the administrator to
+ specify high level auditing rules without having to specify
+ whether each individual auditable operation will be logged.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>record</emphasis>: A record is a log entry
+ describing a security event. Records typically have a
+ record event type, information on the subject (user) associated
+ with the event, time information, information on any objects,
+ such as files, and information on whether the event corresponded
+ to a successful operation.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>trail</emphasis>: An audit trail, or log file,
+ consists of a series of audit records describing security
+ events. Typically, trails are in roughly chronological
+ order with respect to the time events completed. Only
+ authorized processes are allowed to commit records to the
+ audit trail.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>prefix</emphasis>: A prefix is considered to
+ be the configuration element used to toggle auditing for
+ success and failed events.</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="audit-install">
+ <title>Installing Audit Support</title>
+
+ <para>Support for Event Auditing is installed with
+ the normal <buildtarget>installworld</buildtarget> process. An
+ administrator may confirm this by viewing the contents
+ of <filename>/etc/security</filename>. Files
+ beginning with the word <emphasis>audit</emphasis> should be present.
+ For example, <filename>audit_event</filename>.</para>
+
+ <para>In-kernel support for the framework must also exist. This
+ may be done by adding the following lines to the local kernel
+ configuration file:</para>
+
+ <programlisting>options AUDIT</programlisting>
+
+ <para>Rebuild and reinstall
+ the kernel via the normal process explained in
+ <xref linkend="kernelconfig"/>.</para>
+
+ <para>Once completed, enable the audit daemon by adding the
+ following line to &man.rc.conf.5;:</para>
+
+ <programlisting>auditd_enable="YES"</programlisting>
+
+ <para>Functionality not provided by the default may be added
+ here with the <option>auditd_flags</option> option.</para>
+ </sect1>
+
+ <sect1 xml:id="audit-config">
+ <title>Audit Configuration</title>
+
+ <para>All configuration files for security audit are found in
+ <filename>/etc/security</filename>. The following
+ files must be present before the audit daemon is started:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><filename>audit_class</filename> - Contains the
+ definitions of the audit classes.</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>audit_control</filename> - Controls aspects
+ of the audit subsystem, such as default audit classes,
+ minimum disk space to leave on the audit log volume,
+ etc.</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>audit_event</filename> - Defines the kernel
+ audit events. These map, mostly, to system calls.</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>audit_user</filename> - The events to audit
+ for individual users. Users not appearing here will be
+ subject to the default configuration in the control
+ configuration file.</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>audit_warn</filename> - A shell script
+ used by auditd to generate warning messages in
+ exceptional situations, such as when space for audit
+ records is running low.</para>
+ </listitem>
+ </itemizedlist>
+
+ <sect2>
+ <title>Audit File Syntax</title>
+
+ <para>The configuration file syntax is rather arcane, albeit easy
+ to work with. One thing an administrator must be leery about
+ is overriding system defaults. This could create potential
+ openings for audit data to not be collected properly.</para>
+
+ <para>The audit subsystem will accept both the short name and
+ long name with regards to configuration syntax. A syntax
+ map has been included below.</para>
+
+ <para>The following list contains all supported audit
+ classes:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><option>all</option> - <literal>all</literal> - All
+ audit flags set.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>ad</option> - <literal>administrative</literal>
+ - Administrative actions performed on the system as a
+ whole.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>ap</option> - <literal>application</literal> -
+ Application defined action.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>cl</option> - <literal>file_close</literal> -
+ Audit calls to the <function>close</function> system
+ call.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>ex</option> - <literal>exec</literal> - Audit
+ program or utility execution.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>fa</option> - <literal>file_attr_acc</literal>
+ - Audit the access of object attributes such as
+ &man.stat.1;, &man.pathconf.2; and similar events.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>fc</option> - <literal>file_creation</literal>
+ - Audit events where a file is created as a result.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>fd</option> - <literal>file_deletion</literal>
+ - Audit events where file deletion occurs.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>fm</option> - <literal>file_attr_mod</literal>
+ - Audit events where file attribute modification occurs,
+ such as &man.chown.8;, &man.chflags.1;, &man.flock.2;,
+ etc.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>fr</option> - <literal>file_read</literal>
+ - Audit events in which data is read, files are opened for
+ reading, etc.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>fw</option> - <literal>file_write</literal> -
+ Audit events in which data is written, files are written
+ or modified, etc.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>io</option> - <literal>ioctl</literal> - Audit
+ use of the &man.ioctl.2; system call.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>ip</option> - <literal>ipc</literal> - Audit
+ various forms of Inter-Process Communication, including POSIX
+ pipes and System V <acronym>IPC</acronym> operations.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>lo</option> - <literal>login_logout</literal> -
+ Audit &man.login.1; and &man.logout.1; events occurring
+ on the system.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>na</option> - <literal>non_attrib</literal> -
+ Audit non-attributable events.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>no</option> - <literal>no_class</literal> -
+ Null class used to disable event auditing.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>nt</option> - <literal>network</literal> -
+ Audit events related to network actions, such as
+ &man.connect.2; and &man.accept.2;.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>ot</option> - <literal>other</literal> -
+ Audit miscellaneous events.</para>
+ </listitem>
+
+ <listitem>
+ <para><option>pc</option> - <literal>process</literal> -
+ Audit process operations, such as &man.exec.3; and
+ &man.exit.3;.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Following is a list of all supported audit prefixes:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>none</literal> - Audit both the success
+ or failure of an event. For example, just listing a
+ class will result in the auditing of both success and
+ failure.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>+</literal> - Audit successful events
+ only.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>-</literal> - Audit failed events
+ only.</para>
+ </listitem>
+ </itemizedlist>
+
+ <warning>
+ <para>Using the <option>all</option> class with either the
+ positive or negative prefix can generate a large amount
+ of data at an extremely rapid rate.</para>
+ </warning>
+
+ <para>Extra prefixes used to modify the default configuration
+ values:</para>
+<!-- XXX: Perhaps a variable listing here. -->
+ <itemizedlist>
+ <listitem>
+ <para>^- - Disable auditing of failed events.</para>
+ </listitem>
+
+ <listitem>
+ <para>^+ - Enable auditing of successful events.</para>
+ </listitem>
+
+ <listitem>
+ <para>^ - Disable auditing of both successful and failed
+ events.</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>Configuration Files</title>
+
+ <para>In most cases, administrators will need to modify only two files
+ when configuring the audit system: <filename>audit_control</filename>
+ and <filename>audit_user</filename>. The first controls system-wide
+ audit paramaters and defaults for both attributable and
+ non-attributable events. The second may be used to tune the level
+ and nature of auditing for individual users.</para>
+
+ <sect3 xml:id="audit-auditcontrol">
+ <title>The <filename>audit_control</filename> File</title>
+
+ <para>The <filename>audit_control</filename> file contains some basic
+ defaults that the administrator may wish to modify. Perhaps
+ even set some new ones. Viewing the contents of this file,
+ we see the following:</para>
+
+ <programlisting>dir:/var/audit
+flags:lo
+minfree:20
+naflags:lo</programlisting>
+
+ <para>The <option>dir</option> option is used to set the default
+ directory where audit logs are stored. Audit is frequently
+ configured so that audit logs are stored on a dedicated file
+ system, so as to prevent interference between the audit
+ subsystem and other subsystems when file systems become full.
+ </para>
+
+ <para>The <option>flags</option> option is used to set the
+ system-wide defaults. The current setting, <option>lo</option>
+ configures the auditing of all &man.login.1; and &man.logout.1;
+ actions. A more complex example,
+ <option>lo,ad,-all,^-fa,^-fc,^-cl</option> audits all system
+ &man.login.1; and &man.logout.1; actions, all administrator
+ actions, all failed events in the system, and finally disables
+ auditing of failed attempts for <option>fa</option>,
+ <option>fc</option>, and <option>cl</option>. Even though
+ the <option>-all</option> turned on the auditing of all
+ failed attempts, the <option>^-</option> prefix will override
+ that for the latter options.</para>
+
+ <para>Notice that the previous paragraph shows the file is
+ read from left to right. As such, values further on the
+ right side may override a previous value specified to
+ its left.</para>
+
+ <para>The <option>minfree</option> option defines the minimum
+ percentage of free space for audit file systems. This
+ relates to the file system where audit logs are stored.
+ For example, if the <option>dir</option> specifies
+ <filename>/var/audit</filename> and
+ <option>minfree</option> is set to twenty (20), warning
+ messages will be generated when the
+ <filename>/var</filename> file system grows
+ to eighty (80) percent full.</para>
+
+ <para>The <option>naflags</option> option specifies audit
+ classes to be audited for non-attributed events &mdash;
+ that is, events for which there is no authenticated user.
+ </para>
+ </sect3>
+
+ <sect3 xml:id="audit-audituser">
+ <title>The <filename>audit_user</filename> File</title>
+
+ <para>The <filename>audit_user</filename> file permits the
+ administrator to determine which classes of audit events
+ should be logged for which system users.</para>
+
+ <para>The following is the defaults currently placed in
+ the <filename>audit_user</filename> file:</para>
+
+ <programlisting>root:lo:no
+audit:fc:no</programlisting>
+
+ <para>Notice how the default is to audit all cases of
+ <command>login</command>/<command>logout</command>
+ and disable auditing of all other actions for
+ <systemitem class="username">root</systemitem>. This configuration
+ also audits all file creation and disables all
+ other auditing for the <systemitem class="username">audit</systemitem>
+ user. While event auditing does not require a special
+ user exist, some configurations, specifically environments
+ making use of <acronym>MAC</acronym>, may require it.</para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="audit-administration">
+ <title>Event Audit Administration</title>
+
+ <para>Events written by the kernel audit subsystem cannot
+ be altered or read in plain text. Data is stored and accessed
+ in a method similar to that of &man.ktrace.1; and &man.kdump.1;,
+ that is, they may only be viewed by dumping them using the
+ <command>praudit</command> command; audit trails may be reduced
+ using the <command>auditreduce</command> command, which selects
+ records from an audit trail based on properties of interest, such
+ as the user, time of the event, and type of operation.</para>
+
+ <para>For example, the <command>praudit</command> utility will dump the
+ entire contents of a specified audit log in plain text. To dump an
+ audit log in its entirety, use:</para>
+
+ <screen>&prompt.root; <userinput>praudit /var/audit/AUDITFILE</userinput></screen>
+
+ <para>Where <replaceable>AUDITFILE</replaceable> is the audit log
+ of viewing choice. Since audit logs may contain enormous
+ amounts of data, an administrator may prefer to select records
+ for specific users. This is made possible with the following
+ command, where <systemitem class="username">trhodes</systemitem> is the user of
+ choice:</para>
+
+ <screen>&prompt.root; <userinput>auditreduce -e trhodes /var/audit/AUDITFILE | praudit</userinput></screen>
+
+ <para>This will select all audit records produced by the user
+ <systemitem class="username">trhodes</systemitem> stored in the
+ <replaceable>AUDITFILE</replaceable> file.</para>
+
+ <para>There are several other options available for reading audit
+ records, see the aforementioned command's manual pages for
+ a more in depth explanation.</para>
+
+ <sect2>
+ <title>Rotating Audit Log Files</title>
+
+ <para>Due to log reliability requirements, audit trails
+ are written to only by the kernel, and managed only by
+ <command>auditd</command>. Administrators should not
+ attempt to use &man.newsyslog.conf.5; or other tools to
+ directly rotate audit logs. Instead, the <command>audit</command>
+ management tool should be used to shut down auditing,
+ reconfigure the audit system, and perform log rotation.
+ The following command causes the audit daemon to create a
+ new audit log and signal the kernel to switch to using the
+ new log. The old log will be terminated and renamed, at
+ which point it may then be manipulated by the administrator.</para>
+
+ <screen>&prompt.root; <userinput>audit -n</userinput></screen>
+
+ <warning>
+ <para>If the <command>auditd</command> daemon is not currently
+ running, the previous command will fail and an error message
+ will be produced.</para>
+ </warning>
+
+ <para>Adding the following line to
+ <filename>/etc/crontab</filename> will force the rotation
+ every twelve hours from &man.cron.8;:</para>
+
+ <programlisting>* */12 * * * root /usr/sbin/audit -n</programlisting>
+
+ <para>The change will take effect once you have saved the
+ new <filename>/etc/crontab</filename>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Delegating Audit Review Rights</title>
+
+ <para>By default, only the root user has the right to read system audit
+ logs. However, that right may be delegated to members of the
+ <literal>audit</literal> group, as the audit directory and audit
+ trail files are assigned to that group, and made group-readable. As
+ the ability to track audit log contents provides significant insight
+ into the behavior of users and processes, it is recommended that the
+ delegation of audit review rights be performed with caution.</para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/basics/Makefile b/zh_TW.UTF-8/books/handbook/basics/Makefile
new file mode 100644
index 0000000000..69b6b899ac
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/basics/Makefile
@@ -0,0 +1,16 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+# Original revision: 1.1
+#
+
+CHAPTERS= basics/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/basics/chapter.xml b/zh_TW.UTF-8/books/handbook/basics/chapter.xml
new file mode 100644
index 0000000000..3ddf7df0aa
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/basics/chapter.xml
@@ -0,0 +1,2366 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.152
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="basics">
+ <info><title>UNIX 基礎概念</title>
+ <authorgroup>
+ <author><personname><firstname>Chris</firstname><surname>Shumway</surname></personname><contrib>Rewritten by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <sect1 xml:id="basics-synopsis">
+ <title>概述</title>
+
+ <para>接下來的這一章將涵蓋 FreeBSD 作業系統的基本指令及功能。
+ 大部份的內容在 &unix;-like 作業系統中都是相通的。
+ 如果您對這些內容熟悉的話,可以放心的跳過。
+ 如果您剛接觸 FreeBSD,那您一定要仔細的讀完這章。</para>
+
+ <para>讀完這章,您將了解:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>如何使用 FreeBSD 的<quote>virtual consoles</quote>。</para>
+ </listitem>
+ <listitem>
+ <para>&unix; 檔案權限運作的方式以及 &os; 中檔案的 flags。</para>
+ </listitem>
+ <listitem>
+ <para>預設的 &os; 檔案系統配置。</para>
+ </listitem>
+ <listitem>
+ <para>&os; 的磁碟結構。</para>
+ </listitem>
+ <listitem>
+ <para>如何掛載(mount)、卸載(umount)檔案系統</para>
+ </listitem>
+ <listitem>
+ <para>什麼是processes、daemons 以及 signals 。</para>
+ </listitem>
+ <listitem>
+ <para>什麼是 shell ,以及如何變更您預設的登入環境。</para>
+ </listitem>
+ <listitem>
+ <para>如何使用基本的文字編輯器。</para>
+ </listitem>
+ <listitem>
+ <para>什麼是 devices 和 device nodes 。</para>
+ </listitem>
+ <listitem>
+ <para>&os; 下使用的 binary 格式。</para>
+ </listitem>
+ <listitem>
+ <para>如何閱讀 manual pages 以獲得更多的資訊。</para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 xml:id="consoles">
+ <title>Virtual Consoles 和終端機</title>
+ <indexterm><primary>virtual consoles</primary></indexterm>
+ <indexterm><primary>terminals</primary></indexterm>
+
+ <para>有很多方法可以操作 FreeBSD ,其中一種就是在文字終端機上打字。
+ 如此使用 FreeBSD 即可輕易的體會到 &unix; 作業系統的威力和彈性。
+ 這一節描述什麼是<quote>終端機</quote>和 <quote>console</quote>
+ ,以及可以如何在 FreeBSD 中運用它們。</para>
+
+ <sect2 xml:id="consoles-intro">
+ <title>The Console</title>
+ <indexterm><primary>console</primary></indexterm>
+
+ <para>如果您沒有將 FreeBSD 設定成開機時自動進入圖形化模式,系統會在啟動的
+ script 跑完之後顯示登入的提示符號。 您將會看到像是這樣的東西:</para>
+
+ <screen>Additional ABI support:.
+Local package initialization:.
+Additional TCP options:.
+
+Fri Sep 20 13:01:06 EEST 2002
+
+FreeBSD/i386 (pc3.example.org) (ttyv0)
+
+login:</screen>
+
+ <para>這個訊息在您的系統上會有些許的不同,但是應該會看到類似的東西。
+ 我們感興趣的是最後兩行,最後兩行是:</para>
+
+ <programlisting>FreeBSD/i386 (pc3.example.org) (ttyv0)</programlisting>
+
+ <para>這行包含了剛開機完系統的資訊。 您看到的是在 Intel 或相容處理器的
+ x86 架構上執行的 <quote>FreeBSD</quote>的 console<footnote>
+ <para>這就是 <literal>i386</literal> 的意義。 注意即使您不是在
+ Intel 的 386 處理器上執行 FreeBSD ,一樣是<literal>i386</literal>。
+ 這不是指你的處理器的型號,這裡顯示的是你處理器的<quote>架構</quote>
+ </para>
+ </footnote>。 這台機器的名字(每台 &unix; 機器都有一個名字)是
+ <systemitem>pc3.example.org</systemitem>,而您現在看到的是它的系統
+ console&mdash; <filename>ttyv0</filename>終端機。</para>
+
+ <para>最後的一行應該都會是:</para>
+
+ <programlisting>login:</programlisting>
+
+ <para>這是您應該要輸入您的<quote>帳號名稱</quote>的地方。
+ 下一小節將告訴您如何登入 FreeBSD。</para>
+ </sect2>
+
+ <sect2 xml:id="consoles-login">
+ <title>登入 FreeBSD</title>
+
+ <para>FreeBSD 是一個 multiuser、multiprocessing 的系統。
+ 這是一個正式的名稱,指的是在單一機器上可以同時被不同人使用,
+ 但同時可以執行很多程式的系統。</para>
+
+ <para>每一種多使用者系統都需要可以分辨不同<quote>使用者</quote>的方法。
+ 在 FreeBSD (以及所有的 &unix;-like 作業系統)
+ 中,所有的使用者在執行程式之前必須先<quote>登入</quote>系統。
+ 每個使用者都有一組獨特的帳號名稱
+ (<quote>username</quote>)及密碼(<quote>password</quote>)。
+ FreeBSD 在允許使用者執行程式前將會先問這兩個問題。</para>
+
+ <indexterm><primary>startup scripts</primary></indexterm>
+ <para>在 FreeBSD 開機並跑完啟動的 script 之後<footnote>
+ <para>這些啟動的 script 是在開機的時候 FreeBSD 會自動執行的程式。
+ 他們主要的功能是將所有該執行的東西設定好,
+ 並將您設定成背景執行的服務啟動。</para>
+ </footnote>,它將會印出提示字元要求您輸入正確的帳號名稱:</para>
+
+ <screen>login:</screen>
+
+ <para>在這個範例裡,我們假設您的帳號是<systemitem class="username">john</systemitem>。
+ 在提示字元處輸入 <literal>john</literal> 並按下 <keycap>Enter</keycap>
+ 。 接著您應該會看到另一個提示字元要您輸入<quote>密碼</quote>:</para>
+
+ <screen>login: <userinput>john</userinput>
+Password:</screen>
+
+ <para>輸入 <systemitem class="username">john</systemitem> 的密碼,再按下
+ <keycap>Enter</keycap>。 輸入的密碼
+ <emphasis>不會顯示在螢幕上</emphasis>。
+ 您不需要為此擔心,這樣做是為了安全上的問題。</para>
+
+ <para>如果您輸入了正確的密碼,您應該已經登入 FreeBSD。
+ 現在就可以嘗試所有可用的指令了。</para>
+
+ <para>您應該會看到<acronym>MOTD</acronym>
+ (即今日訊息、Messages Of The Day),後面接著命令提示字元
+ (一個 <literal>#</literal>,<literal>$</literal>, 或是
+ <literal>%</literal> 字元)。 這就表示您已經成功登入
+ FreeBSD 了。</para>
+ </sect2>
+
+ <sect2 xml:id="consoles-virtual">
+ <title>多重 Console</title>
+
+ <para>在一個 Console 下執行 &unix; 當然是沒有問題,然而 FreeBSD
+ 是可以同時執行很多程式的。 像 FreeBSD
+ 這樣可以同時執行一大堆程式的作業系統,只有一個
+ console 可以輸入指令實在是有點浪費。 因此
+ <quote>virtual consoles</quote> 就顯得相當好用。</para>
+
+ <para>可以設定讓 FreeBSD 同時有很多 virtual console,
+ 用幾個按鍵的組合就可以從一個 virtual console 跳到別的 virtual console
+ 。 每一個 console 都有自已不同的輸出頻道,當從某一個 virtual console
+ 切換到下一個的時候,FreeBSD 會自動處理鍵盤輸入及螢幕輸出。</para>
+
+ <para>FreeBSD 保留了特別的按鍵組合來切換 console <footnote>
+ <para>在 &man.syscons.4;、&man.atkbd.4;、&man.vidcontrol.1;、以及
+ &man.kbdcontrol.1;等 manual page 中,對於 FreeBSD 的 console
+ 及鍵盤驅動程式有詳細的技術說明。 我們在這裡不討論細節,
+ 有興趣的讀者隨時可以在 manual pages
+ 中查到關於運作方式的更詳細且完整的解釋。</para></footnote>。
+ 您可以用 <keycombo><keycap>Alt</keycap><keycap>F1</keycap></keycombo>、
+ <keycombo><keycap>Alt</keycap><keycap>F2</keycap></keycombo>、到
+ <keycombo><keycap>Alt</keycap><keycap>F8</keycap></keycombo>
+ 來切換 FreeBSD 的不同 console。</para>
+
+ <para>當您從一個 console 切換到下一個的時候,FreeBSD
+ 會處理螢幕輸出的儲存及回復。
+ 這就<quote>好像</quote>有很多<quote>虛擬</quote>的螢幕和鍵盤,
+ 可以讓您輸入指令到 FreeBSD 執行。 在某一個 console
+ 上執行的程式並不會因為切到別的 console 而停止執行,切換到另一個
+ console 時,它們仍會繼續執行。</para>
+ </sect2>
+
+ <sect2 xml:id="consoles-ttys">
+ <title><filename>/etc/ttys</filename> 檔</title>
+
+ <para>FreeBSD 預設的虛擬 console 總共有 8 個,
+ 但這並非硬性規定,您可輕鬆設定這些虛擬 console 的數量增減。
+ 有關虛擬 console 的編號跟設定都在
+ <filename>/etc/ttys</filename> 這檔案內設定。</para>
+
+ <para>可以用 <filename>/etc/ttys</filename> 檔案來設定
+ FreeBSD 的虛擬 console。 檔案內每行非註解文字(該行開頭沒有
+ <literal>#</literal> 這字)都是設定終端機或虛擬 console。
+ FreeBSD 預設有 9 個虛擬 console 但只啟動 8 個,也就是以下以
+ <literal>ttyv</literal> 開頭的那幾行設定。</para>
+
+ <programlisting># name getty type status comments
+#
+ttyv0 "/usr/libexec/getty Pc" cons25 on secure
+# Virtual terminals
+ttyv1 "/usr/libexec/getty Pc" cons25 on secure
+ttyv2 "/usr/libexec/getty Pc" cons25 on secure
+ttyv3 "/usr/libexec/getty Pc" cons25 on secure
+ttyv4 "/usr/libexec/getty Pc" cons25 on secure
+ttyv5 "/usr/libexec/getty Pc" cons25 on secure
+ttyv6 "/usr/libexec/getty Pc" cons25 on secure
+ttyv7 "/usr/libexec/getty Pc" cons25 on secure
+ttyv8 "/usr/X11R6/bin/xdm -nodaemon" xterm off secure</programlisting>
+
+ <para>有關各欄位的設定以及其他選項,請參閱 &man.ttys.5; 說明。</para>
+ </sect2>
+
+ <sect2 xml:id="consoles-singleuser">
+ <title>Single User 模式的 Console</title>
+
+ <para>有關 <quote>single user 模式</quote> 的介紹在
+ <xref linkend="boot-singleuser"/>
+ 這邊有詳盡介紹。 在 single user 模式時,能夠使用的 console
+ 只有一個,並無虛擬 console 可用。 而 single user 模式相關設定值可以在
+ <filename>/etc/ttys</filename> 檔做調整。 下面以
+ <literal>console</literal> 開頭的那行,就是了:</para>
+
+ <programlisting># name getty type status comments
+#
+# If console is marked "insecure", then init will ask for the root password
+# when going to single-user mode.
+console none unknown off secure</programlisting>
+
+ <note>
+ <para>在 <literal>console</literal> 那行前面的註解有提到,可以把那行的
+ <literal>secure</literal> 改為 <literal>insecure</literal>,
+ 如此一來,即使 FreeBSD 進入 single user 模式,
+ 仍會要求您輸入 <systemitem class="username">root</systemitem> 的密碼。</para>
+
+ <para><emphasis>請審慎考慮是否要改為
+ <literal>insecure</literal></emphasis>。 因為萬一忘記
+ <systemitem class="username">root</systemitem> 密碼的話,若要登入 single user
+ 模式就有些麻煩了。儘管還有其他方式可以登入,但對不熟 FreeBSD
+ 開機程序的人而言,就會相當棘手。</para>
+ </note>
+ </sect2>
+
+ <sect2 xml:id="consoles-vidcontrol">
+ <title>更改 console 的顯示畫面</title>
+
+ <para>FreeBSD console 預設顯示大小可以調整為 1024x768、1280x1024
+ 或其他顯示卡與螢幕有支援的解析度大小。 要切換顯示大小,必須要重新編譯
+ kernel 並加入下面這兩項設定:</para>
+
+ <programlisting>options VESA
+options SC_PIXEL_MODE</programlisting>
+
+ <para>一旦 kernel 有加入這兩項並重新編譯完畢,就可以用 &man.vidcontrol.1;
+ 來偵測目前所支援的模式有哪些。 若要查看支援的模式,可以打:</para>
+
+ <screen>&prompt.root; <userinput>vidcontrol -i mode</userinput></screen>
+
+ <para>該指令會顯示該機器所支援的顯示模式清單。 然後可以在
+ <systemitem class="username">root</systemitem> console 內透過 &man.vidcontrol.1; 指令,
+ 來更改顯示模式:</para>
+
+ <screen>&prompt.root; <userinput>vidcontrol MODE_279</userinput></screen>
+
+ <para>若對新的顯示模式覺得還不錯,可以在 <filename>/etc/rc.conf</filename>
+ 設定之,以讓每次重開機後會自動生效。 以上面這情況為例,就是:</para>
+
+ <programlisting>allscreens_flags="MODE_279"</programlisting>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="permissions">
+ <title>權限</title>
+ <indexterm><primary>UNIX</primary></indexterm>
+
+ <para>FreeBSD 源自於 BSD &unix;,繼承了幾個重要的 &unix; 概念。
+ 首先也最明顯,它是一款 multi-user 作業系統。 它可以同時處理多人多工,
+ 負責徹底的分享與管理來自每位使用者對硬碟裝置、週邊設備、記憶體及
+ CPU 時間的要求。</para>
+
+ <para>也因為系統能夠支援多使用者,
+ 所以系統管理的一切都有權限來決定誰可以讀取、寫入或執行資源。
+ 這些權限分別使用三組八進位的數字儲存,一組代表檔案的所有者,
+ 一組代表檔案所屬的群組,而最後一組則代表其他所有人。
+ 表示這些數字的方式如下:</para>
+
+ <indexterm><primary>permissions</primary></indexterm>
+ <indexterm>
+ <primary>file permissions</primary>
+ </indexterm>
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>值</entry>
+ <entry>權限</entry>
+ <entry>目錄顯示</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>0</entry>
+ <entry>不可讀取, 不可寫入, 不可執行</entry>
+ <entry><literal>---</literal></entry>
+ </row>
+
+ <row>
+ <entry>1</entry>
+ <entry>不可讀取, 不可寫入, 可執行</entry>
+ <entry><literal>--x</literal></entry>
+ </row>
+
+ <row>
+ <entry>2</entry>
+ <entry>不可讀取, 可寫入, 不可執行</entry>
+ <entry><literal>-w-</literal></entry>
+ </row>
+
+ <row>
+ <entry>3</entry>
+ <entry>不可讀取, 可寫入, 可執行</entry>
+ <entry><literal>-wx</literal></entry>
+ </row>
+
+ <row>
+ <entry>4</entry>
+ <entry>可讀取, 不可寫入, 不可執行</entry>
+ <entry><literal>r--</literal></entry>
+ </row>
+
+ <row>
+ <entry>5</entry>
+ <entry>可讀取, 不可寫入, 可執行</entry>
+ <entry><literal>r-x</literal></entry>
+ </row>
+
+ <row>
+ <entry>6</entry>
+ <entry>可讀取, 可寫入, 不可執行</entry>
+ <entry><literal>rw-</literal></entry>
+ </row>
+
+ <row>
+ <entry>7</entry>
+ <entry>可讀取, 可寫入, 可執行</entry>
+ <entry><literal>rwx</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ <indexterm>
+ <primary><command>ls</command></primary>
+ </indexterm>
+ <indexterm><primary>directories</primary></indexterm>
+
+ <para>使用 &man.ls.1; 指令時,可以加上 <option>-l</option> 參數,
+ 來檢視詳細的目錄清單。
+ 清單中欄位的資訊包含檔案對所有者、群組及其他人的權限。
+ 在任一個目錄底下執行 <command>ls -l</command>,會顯示如下的結果:
+ </para>
+
+ <screen>&prompt.user; <userinput>ls -l</userinput>
+total 530
+-rw-r--r-- 1 root wheel 512 Sep 5 12:31 myfile
+-rw-r--r-- 1 root wheel 512 Sep 5 12:31 otherfile
+-rw-r--r-- 1 root wheel 7680 Sep 5 12:31 email.txt
+...</screen>
+
+ <para>在這裡告所您該如何區分 <command>ls -l</command>
+ 第一欄當中的資訊:</para>
+
+ <screen>-rw-r--r--</screen>
+
+ <para>第一個 (最左邊) 的字元用來表示這個檔案的類型為何,
+ 除標準檔案以外,尚有目錄、特殊字元裝置 (Special character device)、
+ Socket 及其他特殊虛擬檔案裝置 (Special pseudo-file device),
+ 在此例當中,<literal>-</literal> 表示該檔案為一個標準的檔案。
+ 範例中接下來的三個字元中,<literal>rw-</literal>
+ 代表所有者對檔案擁有的權限。 再接下來的三個字元,
+ <literal>r--</literal> 則代表群組對檔案擁有的權限,
+ 最後三個字元,<literal>r--</literal> 則代表其他人對檔案擁有的權限。
+ 破折號 (-) 表示沒有權限,範例中的這個檔案的權限,
+ 只允許所有者讀取、寫入檔案,群組以及其他人僅能讀取檔案。
+ 根據以上的表格,此種權限的檔案可以使用 <literal>644</literal> 來表示,
+ 每組數字分別代表檔案的三種權限。</para>
+
+ <para>以上是不錯的方式,但系統該如何控制裝置的權限? 實際上 FreeBSD
+ 對大多的硬碟裝置就如同檔案,程式可以開啟、讀取以及寫入資料如一般檔案。
+ 這些特殊裝置檔案 (Special device file) 都儲存於 <filename>/dev</filename>
+ 目錄中。</para>
+
+ <para>
+ 目錄也同如檔案,擁有讀取、寫入及執行的權限,
+ 但在執行權限上與檔案有明顯的差異。 當目錄被標示為可執行時,代表可以使用
+ <quote>cd</quote> (更改目錄) 進入該目錄。
+ 也代表能夠存取在此目錄之中的已知檔名的檔案
+ (當然,檔案仍擁有自己的權限)</para>
+
+ <para>尤其,要能夠列出目錄內容,必須擁有目錄的讀取權限。
+ 而當要刪除已知檔名的檔案時,也必須擁有檔案所在目錄的寫入
+ <emphasis>以及</emphasis> 執行的權限。</para>
+
+ <para>還有一些權限,但這些權限主要在特殊情況使用,如
+ setuid binaries 及 sticky directories。
+ 如果您還想知道更多檔案權限的資訊及使用方法,請務必參閱
+ &man.chmod.1; 說明文件。</para>
+
+ <sect2>
+ <info><title>權限符號</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>permissions</primary><secondary>symbolic</secondary></indexterm>
+
+ <para>權限符號可稱做符號表示,
+ 使用字元的方式來取代使用數值來設定檔案或目錄的權限。
+ 符號表示的格式依序為 (某人)(動作)(權限),可使用的符號如下:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>項目</entry>
+ <entry>字母</entry>
+ <entry>意義</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>(某人)</entry>
+ <entry>u</entry>
+ <entry>使用者</entry>
+ </row>
+
+ <row>
+ <entry>(某人)</entry>
+ <entry>g</entry>
+ <entry>群組所有者</entry>
+ </row>
+
+ <row>
+ <entry>(某人)</entry>
+ <entry>o</entry>
+ <entry>其他</entry>
+ </row>
+
+ <row>
+ <entry>(某人)</entry>
+ <entry>a</entry>
+ <entry>全部(<quote>world</quote>)</entry>
+ </row>
+
+ <row>
+ <entry>(動作)</entry>
+ <entry>+</entry>
+ <entry>增加權限</entry>
+ </row>
+
+ <row>
+ <entry>(動作)</entry>
+ <entry>-</entry>
+ <entry>移除權限</entry>
+ </row>
+
+ <row>
+ <entry>(動作)</entry>
+ <entry>=</entry>
+ <entry>指定權限</entry>
+ </row>
+
+ <row>
+ <entry>(權限)</entry>
+ <entry>r</entry>
+ <entry>讀取</entry>
+ </row>
+
+ <row>
+ <entry>(權限)</entry>
+ <entry>w</entry>
+ <entry>寫入</entry>
+ </row>
+
+ <row>
+ <entry>(權限)</entry>
+ <entry>x</entry>
+ <entry>執行</entry>
+ </row>
+
+ <row>
+ <entry>(權限)</entry>
+ <entry>t</entry>
+ <entry>Sticky bit</entry>
+ </row>
+
+ <row>
+ <entry>(權限)</entry>
+ <entry>s</entry>
+ <entry>Set UID 或 GID</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>如先前同樣使用 &man.chmod.1; 指令來設定,但使用的參數為這些字元。
+ 例如,您可以使用下列指令禁止其他使用者存取檔案
+ <replaceable>FILE</replaceable>:</para>
+
+ <screen>&prompt.user; <userinput>chmod go= FILE</userinput></screen>
+
+ <para>若有兩個以上的符號表示可以使用逗號 (,) 區隔。
+ 例如,下列指令將會移除群組及其他人對檔案
+ <replaceable>FILE</replaceable> 的寫入權限,
+ 並使全部人(<quote>world</quote>)對該檔有執行權限。</para>
+
+ <screen>&prompt.user; <userinput>chmod go-w,a+x FILE</userinput></screen>
+
+<!--
+ <para>Most users will not notice this, but it should be pointed out
+ that using the octal method will only set or assign permissions to
+ a file; it does not add or delete them.</para>
+-->
+ </sect2>
+
+ <sect2>
+ <info><title>&os; 檔案旗標(Flag)</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <para>除了前面提到的檔案權限外,&os; 支援使用 <quote>檔案旗標</quote>。
+ 這些旗標增加了檔案的安全性及管理性,但不包含目錄。</para>
+
+ <para>檔案旗標增加了管理性,確保在某些時候 <systemitem class="username">root</systemitem>
+ 不會意外將檔案修改或移除。</para>
+
+ <para>修改的檔案 flag 僅需要使用擁有簡易的介面的 &man.chflags.1; 工具。
+ 例如,標示系統禁止刪除的旗標於檔案
+ <filename>file1</filename>,使用下列指令:</para>
+
+ <screen>&prompt.root; <userinput>chflags sunlink file1</userinput></screen>
+
+ <para>若要移除系統禁止刪除的旗標,只需要簡單在 <option>sunlink</option>
+ 前加上 <quote>no</quote>,例如:</para>
+
+ <screen>&prompt.root; <userinput>chflags nosunlink file1</userinput></screen>
+
+ <para>使用 &man.ls.1; 及參數 <option>-lo</option>
+ 可檢視檔案目前的旗標:</para>
+
+ <screen>&prompt.root; <userinput>ls -lo file1
+ </userinput></screen>
+
+ <para>輸出的結果如下:</para>
+
+ <programlisting>-rw-r--r-- 1 trhodes trhodes sunlnk 0 Mar 1 05:54 file1</programlisting>
+
+ <para>多數的旗標僅能由 <systemitem class="username">root</systemitem>
+ 使用者來標示或移除,而部份旗標可由檔案所有者設定。
+ 我們建議系統管理者可閱讀 &man.chflags.1; 及 &man.chflags.2;
+ 說明以瞭解相關細節。</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="dirstructure">
+ <title>目錄結構</title>
+ <indexterm><primary>directory hierarchy</primary></indexterm>
+
+ <para>認識 FreeBSD 的目錄架構,就可對系統有概略的基礎理解。
+ 最重要的莫過於整個目錄的根目錄,就是 <quote>/</quote> 目錄,
+ 該目錄會在開機時最先掛載 (mount),裡面會有開機所會用到必備檔案。
+ 此外,根目錄還有紀錄其他檔案系統的掛載點相關設定。</para>
+
+ <para>「掛載點」就是讓新增的檔案系統,能接到上層的檔案系統
+ (通常就是「根目錄」檔案系統) 的目錄。
+ 在 <xref linkend="disk-organization"/> 這邊對此有更詳細介紹。
+ 標準的掛載點包括了 <filename>/usr</filename>、<filename>/var</filename>、
+ <filename>/tmp</filename>、<filename>/mnt</filename> 以及
+ <filename>/cdrom</filename>。 這些目錄通常會記錄在
+ <filename>/etc/fstab</filename> 設定檔內。
+ <filename>/etc/fstab</filename> 是記錄各檔案系統及相關掛載點的表格。
+ 大部分在 <filename>/etc/fstab</filename> 有記錄的檔案系統,會在開機時由
+ &man.rc.8; script 來自動掛載,除非它們有設定 <option>noauto</option>
+ 選項。 其中細節說明可參閱 <xref linkend="disks-fstab"/>。</para>
+
+ <para>有關檔案系統架構的完整說明可參閱 &man.hier.7;。
+ 現在呢,讓我們大致先一窺常見的目錄有哪些吧。</para>
+
+ <para>
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>目錄</entry>
+ <entry>說明</entry>
+ </row>
+ </thead>
+ <tbody valign="top">
+ <row>
+ <entry><filename>/</filename></entry>
+ <entry>檔案系統的根目錄。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/bin/</filename></entry>
+ <entry>single-user、multi-user 兩種模式皆可使用的基本工具
+ 。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/boot/</filename></entry>
+ <entry>作業系統開機過程會用到的程式、設定檔。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/boot/defaults/</filename></entry>
+ <entry>預設的開機啟動設定檔,詳情請參閱 &man.loader.conf.5;
+ 。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/dev/</filename></entry>
+ <entry>Device nodes,詳情請參閱 &man.intro.4;。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/etc/</filename></entry>
+ <entry>系統設定檔及一些 script 檔。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/etc/defaults/</filename></entry>
+ <entry>預設的系統設定檔,詳情請參閱 &man.rc.8;。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/etc/mail/</filename></entry>
+ <entry>MTA(Mail Transport Agent)的相關設定檔,像是
+ &man.sendmail.8;。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/etc/namedb/</filename></entry>
+ <entry><command>named</command> 設定檔,詳情請參閱
+ &man.named.8;。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/etc/periodic/</filename></entry>
+ <entry>每日、每週、每月透過 &man.cron.8;; 執行的定期排程 script,
+ 詳情請參閱 &man.periodic.8;。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/etc/ppp/</filename></entry>
+ <entry><command>ppp</command> 設定檔,詳情請參閱
+ &man.ppp.8;。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/mnt/</filename></entry>
+ <entry>系統管理者慣用充當臨時掛載點的空目錄。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/proc/</filename></entry>
+ <entry>Process 檔案系統,詳情請參閱 &man.procfs.5; 及
+ &man.mount.procfs.8;。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/rescue/</filename></entry>
+ <entry>緊急救援用途的一些 statically linked 程式,詳情請參閱
+ &man.rescue.8;。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/root/</filename></entry>
+ <entry><systemitem class="username">root</systemitem> 帳號的家目錄。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/sbin/</filename></entry>
+ <entry>供 single-user 及 multi-user 環境使用的系統程式及管理工具
+ 。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/tmp/</filename></entry>
+ <entry>臨時檔案。 一般而言,重開機之後
+ <filename>/tmp</filename> 內的東西會被清除掉。
+ 而通常會將 memory-based 檔案系統掛載在
+ <filename>/tmp</filename> 上。
+ 這些瑣事可透過 tmpmfs 相關的 &man.rc.conf.5; 環境變數來自動完成
+ 。(或是在 <filename>/etc/fstab</filename> 內做設定,
+ 詳情請參閱 &man.mdmfs.8;。)</entry>
+ </row>
+
+ <row>
+ <entry><filename>/usr/</filename></entry>
+ <entry>主要是使用者所安裝的工具程式、應用程式存放處。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/usr/bin/</filename></entry>
+ <entry>常用工具、開發工具、應用軟體。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/usr/include/</filename></entry>
+ <entry>標準 C include 的相關 header 檔案庫。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/usr/lib/</filename></entry>
+ <entry>函式庫存放處。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/usr/libdata/</filename></entry>
+ <entry>其他各式工具的資料檔。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/usr/libexec/</filename></entry>
+ <entry>系統 daemons 及系統工具程式(透過其他程式來執行)。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/usr/local/</filename></entry>
+
+ <entry>存放一些自行安裝的執行檔、函式庫等等。 同時,也是 FreeBSD
+ ports 架構的預設安裝目錄。 <filename>/usr/local</filename>
+ 內的目錄架構大致與 <filename>/usr</filename> 相同,詳情請參閱
+ &man.hier.7; 說明。 但 man 目錄例外,它們是直接放在
+ <filename>/usr/local</filename> 底下,而非
+ <filename>/usr/local/share</filename>,而 ports
+ 所安裝的說明文件則在
+ <filename>share/doc/port</filename>。
+ </entry>
+ </row>
+
+ <row>
+ <entry><filename>/usr/obj/</filename></entry>
+ <entry>在編譯 <filename>/usr/src</filename>
+ 目錄時所產生的相關架構 object 檔案。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/usr/ports</filename></entry>
+ <entry>FreeBSD Ports Collection (optional)。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/usr/sbin/</filename></entry>
+ <entry>系統 daemon 及系統工具(直接由使用者執行)。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/usr/share/</filename></entry>
+ <entry>各架構皆共通的檔案。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/usr/src/</filename></entry>
+ <entry>BSD 本身的原始碼(或自行新增的)。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/usr/X11R6/</filename></entry>
+ <entry>X11R6 相關套件的執行檔、函式庫等(optional)。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/var/</filename></entry>
+ <entry>存放各種用途的 log 檔、臨時或暫時存放、列印或郵件的
+ spool 檔案。有時候,memory-based 檔案系統也會掛載在
+ <filename>/var</filename>。
+ 這些瑣事可透過 varmfs 相關的 &man.rc.conf.5;
+ 環境變數來自動完成。(或是在
+ <filename>/etc/fstab</filename> 內做設定,相關細節請參閱
+ &man.mdmfs.8;。)</entry>
+ </row>
+
+
+ <row>
+ <entry><filename>/var/log/</filename></entry>
+ <entry>各項系統記錄的 log 檔案。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/var/mail/</filename></entry>
+ <entry>各使用者的 mailbox 檔案。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/var/spool/</filename></entry>
+ <entry>各種印表機、郵件系統的 spool 目錄。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/var/tmp/</filename></entry>
+ <entry>臨時檔案。
+ 這些檔案在重開機後通常仍會保留,除非
+ <filename>/var</filename>
+ 是屬於 memory-based 檔案系統。</entry>
+ </row>
+
+ <row>
+ <entry><filename>/var/yp</filename></entry>
+ <entry>記錄 NIS maps。</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+
+ </sect1>
+
+ <sect1 xml:id="disk-organization">
+ <title>磁碟組織</title>
+
+ <para>FreeBSD 用來尋找檔案的最小單位就是檔案的名稱了。
+ 檔案的名稱有大小寫之分,所以說 <filename>readme.txt</filename>
+ 和 <filename>README.TXT</filename> 是兩個不同的檔案。
+ FreeBSD 並不使用副檔名 (<filename>.txt</filename>)
+ 來判別這是一個程式檔、文件檔或是其他類型的檔案。</para>
+
+ <para>檔案存在目錄裡面。
+ 一個目錄中可能沒有任何檔案,也可能有好幾百個檔案。
+ 目錄之中也可以包含其他的目錄;
+ 您可以建立階層式的目錄以便資料的管理。</para>
+
+ <para>檔案或目錄的對應是藉由給定的檔案或目錄名稱,然後加上正斜線符號
+ (<literal>/</literal>);之後再視需要加上其他的目錄名稱。
+ 如果您有一個目錄 <filename>foo</filename> ,裡面有一個目錄叫作
+ <filename>bar</filename>,這個目錄中又包含了一個叫
+ <filename>readme.txt</filename>
+ 的檔案,那麼這個檔案的全名,或者說檔案的<firstterm>路徑</firstterm>就是
+ <filename>foo/bar/readme.txt</filename>。</para>
+
+ <para>目錄及檔案儲存在檔案系統之中。
+ 每個檔案系統都有唯一一個最上層的目錄,叫做<firstterm>根目錄
+ (root directory)</firstterm>。
+ 然後在這個根目錄下面才能有其他的目錄。</para>
+
+ <para>到目前為止大概和其他您用過的的作業系統都差不多。
+ 還是有些不一樣的地方就是了,例如 &ms-dos; 用 <literal>\</literal>
+ 當檔案和目錄名稱的分隔符號,而 &macos; 則是用 <literal>:</literal>
+ 符號。</para>
+
+ <para>FreeBSD 的路徑中並沒有使用磁碟機代號或其他的磁碟名稱。
+ 因此,您不可以使用像 <filename>c:/foo/bar/readme.txt</filename>
+ 這樣子的檔案名稱。</para>
+
+ <para>相對的,在 FreeBSD
+ 系統中有一個檔案系統被指定為<firstterm>根檔案系統</firstterm>。
+ 根檔案系統的根目錄由 <literal>/</literal> 表示。
+ 然後其他的檔案系統再<firstterm>掛載 (mount)</firstterm>
+ 在根檔案系統之下。因此無論您的 FreeBSD
+ 系統上有多少顆硬碟,每一個目錄看起來就像在同一個磁碟上。</para>
+
+ <para>假設您有三個檔案系統,分別叫作 <literal>A</literal>、
+ <literal>B</literal> 及 <literal>C</literal>。
+ 每個檔案系統都包含兩個目錄,叫做
+ <literal>A1</literal>、<literal>A2</literal> (依此類推得
+ <literal>B1</literal>、<literal>B2</literal> 及
+ <literal>C1</literal>、<literal>C2</literal>)。</para>
+
+ <para>稱 <literal>A</literal> 為主要的檔案系統;如果您用
+ <command>ls</command> 指令查看此目錄的內容,您會看到兩個子目錄:
+ <literal>A1</literal> 及 <literal>A2</literal>,如下所示:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/example-dir1"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced"> /
+ |
+ +--- A1
+ |
+ `--- A2</literallayout>
+ </textobject>
+ </mediaobject>
+
+ <para>一個檔案系統必須以目錄形式掛載於另一個檔案系統上。
+ 因此,假設您將 <literal>B</literal> 掛載於 <literal>A1</literal>
+ 之上,則 <literal>B</literal> 的根目錄就變成了
+ <literal>A1</literal>,而在 <literal>B</literal>
+ 之下的任何目錄的路徑也隨之改變:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/example-dir2"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced"> /
+ |
+ +--- A1
+ | |
+ | +--- B1
+ | |
+ | `--- B2
+ |
+ `--- A2</literallayout>
+ </textobject>
+ </mediaobject>
+
+ <para>在 <literal>B1</literal> 或 <literal>B2</literal>
+ 目錄中的任何檔案必須經由路徑 <filename>/A1/B1</filename>
+ 或 <filename>/A1/B2</filename> 才能達到。
+ 所有原來在 <filename>/A1</filename> 中的檔案會暫時被隱藏起來,直到
+ <literal>B</literal> 被「<firstterm>移除
+ (unmounted)</firstterm>」後才會再顯現出來。</para>
+
+ <para>如果 <literal>B</literal> 掛載在 <literal>A2</literal>
+ 之上,則會變成:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/example-dir3"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced"> /
+ |
+ +--- A1
+ |
+ `--- A2
+ |
+ +--- B1
+ |
+ `--- B2</literallayout>
+ </textobject>
+ </mediaobject>
+
+ <para>上面的路徑分別為 <filename>/A2/B1</filename> 及
+ <filename>/A2/B2</filename>。</para>
+
+ <para>檔案系統可以掛在其他檔案系統的目錄之上。
+ 延續之前的例子,<literal>C</literal> 檔案系統可以掛在檔案系統
+ <literal>B</literal> 的 <literal>B1</literal>
+ 目錄之上,如圖所示:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/example-dir4"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced"> /
+ |
+ +--- A1
+ |
+ `--- A2
+ |
+ +--- B1
+ | |
+ | +--- C1
+ | |
+ | `--- C2
+ |
+ `--- B2</literallayout>
+ </textobject>
+ </mediaobject>
+
+ <para>或者 <literal>C</literal> 直接掛載於 <literal>A</literal> 的
+ <literal>A1</literal> 目錄之上:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/example-dir5"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced"> /
+ |
+ +--- A1
+ | |
+ | +--- C1
+ | |
+ | `--- C2
+ |
+ `--- A2
+ |
+ +--- B1
+ |
+ `--- B2</literallayout>
+ </textobject>
+ </mediaobject>
+
+ <para>如果您熟悉 &ms-dos; 的話,這和 <command>join</command>
+ 指令很類似 (雖然不儘相同)。</para>
+
+ <para>一般情況下您不需要擔心這些東西。
+ 除非您要安裝新的磁碟,不然通常在您安裝 FreeBSD
+ 時建立好檔案系統並決定好要掛載在何處之後就不會再做任何更動了。</para>
+
+ <para>您完全可以使用單一的一個大的根檔案系統 (root file system)
+ 而不建立其他的檔案系統。 這樣有好處也有有壞處。</para>
+
+ <itemizedlist>
+ <title>使用多個檔案系統的好處</title>
+
+ <listitem>
+ <para>不同的檔案系統在掛上的時候可以有不同的
+ <firstterm>掛載參數</firstterm>。
+ 舉例來說,為求謹慎您可以將根檔案系統設成唯讀,
+ 以避免不小心刪除或修改掉重要的檔案。
+ 將使用者可寫入的檔案系統 (例如 <filename>/home</filename>)
+ 獨立出來也可以讓他們用 <firstterm>nosuid</firstterm>
+ 的參數掛載,此選項可以讓在這個檔案系統中執行檔的
+ <firstterm>suid</firstterm>/<firstterm>guid</firstterm>
+ bits 失效,也許可以讓系統更安全。</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD 會自動根據您檔案系統的使用方式來做最佳的檔案配置方式。
+ 因此,一個有很多小檔案、
+ 常常寫入的檔案系統跟只有幾個較大的檔案的檔案系統配置是不一樣的。
+ 如果您只有單一一個大的檔案系統,這部分就沒用了。</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD 的檔案系統在停電的時候很穩固。
+ 然而,在某些重要的時候停電仍然會對檔案系統結構造成損害。
+ 分割成許多個檔案系統的話在系統在停電後比較能夠正常啟動,
+ 以便您在需要的時候將備份資料回存回來。</para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <title>使用單一檔案系統的好處</title>
+
+ <listitem>
+ <para>檔案系統的大小是固定的。
+ 您當初安裝 FreeBSD
+ 的時候應該會給定一個大小,可是後來您可能會想把空間加大。
+ 如果沒有備份的話是很難達成的;
+ 您必須將檔案系統重新建立為您需要的大小,然後將備份回存回來。</para>
+
+ <important>
+ <para>FreeBSD 的 &man.growfs.8;
+ 指令可以突破此限制直接變更檔案系統的大小。</para>
+ </important>
+ </listitem>
+ </itemizedlist>
+
+ <para>檔案系統包含在分割區裡面。
+ 因為 &os; 承襲 &unix; 架構,這邊講的分割區和一般提到的分割區
+ (例如 &ms-dos; 分割區) 不同。 每一個分割區由一個代號(字母)表示,從
+ <literal>a</literal> 到 <literal>h</literal>。
+ 每個分割區只能包含一個檔案系統。
+ 因此除了說常見到用檔案系統同的掛載點來表示檔案系統外,
+ 也可以用包含他的分割區代號來表示。</para>
+
+ <para>FreeBSD 也會拿磁碟空間來當 <firstterm>swap space</firstterm>。
+ Swap space 給 FreeBSD 當作<firstterm>虛擬記憶體</firstterm>用。
+ 這讓您的電腦好像擁有比實際更多的記憶體。
+ 當 FreeBSD 的記憶體用完的時候,它會把一些目前沒用到的資料移到
+ swap space,然後在用到的時候移回去 (同時移出部份沒用到的)。</para>
+
+ <para>某些分割區有慣例的使用方式如下:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="5*"/>
+
+ <thead>
+ <row>
+ <entry>分割區</entry>
+
+ <entry>慣例</entry>
+ </row>
+ </thead>
+
+ <tbody valign="top">
+ <row>
+ <entry><literal>a</literal></entry>
+
+ <entry>通常包含根檔案系統 (root file system)</entry>
+ </row>
+
+ <row>
+ <entry><literal>b</literal></entry>
+
+ <entry>通常是 swap space</entry>
+ </row>
+
+ <row>
+ <entry><literal>c</literal></entry>
+
+ <entry>通常和整個 slice 的大小一樣,給一些會用到整個 slice
+ 的工具程式 (例如硬碟壞軌檢查工具) 來使用。
+ 一般來說您應該不會把檔案系統建立在這個分割區。</entry>
+ </row>
+
+ <row>
+ <entry><literal>d</literal></entry>
+
+ <entry>分割區 <literal>d</literal>
+ 曾經有代表特殊意義,但是已經不再使用。
+ 所以現在 <literal>d</literal>
+ 就和其他一般的分割區相同了。</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>每個包含有檔案系統的分割區是存在所謂的
+ <firstterm>slice</firstterm> 裡面。
+ FreeBSD 的 slice 就是指平常我們稱為分割區 (partition) 的東西。
+ 同樣地,會這樣子稱呼也是因為 FreeBSD 的 &unix; 色彩。
+ 而 slice 是有編號的,從 1 號編到 4 號。</para>
+
+ <indexterm><primary>slices</primary></indexterm>
+ <indexterm><primary>partitions</primary></indexterm>
+ <indexterm><primary>dangerously dedicated</primary></indexterm>
+
+ <para>slice 號碼跟在裝置名稱後面,先接一個字母
+ <literal>s</literal>,然後從 1 號開始編下去。
+ 因此 <quote>da0<emphasis>s1</emphasis></quote> 就是指第一個 SCSI
+ 硬碟的第一個 slice。 一個磁碟上只能有四個實體的 slice,但是在實體的
+ slice 中您可以塞進適當類型的邏輯 slice。 這些延伸的 slice 編號從 5
+ 開始,所以 <quote>ad0<emphasis>s5</emphasis></quote> 是第一個 IDE
+ 硬碟上的第一個延伸 slice。 檔案系統在裝置 (device) 裡就是在一個 slice
+ 之中。</para>
+
+ <para>Slices、<quote>dangerously dedicated</quote>
+ 模式的實體磁碟機,以及其他包含<firstterm>分割區(partition)</firstterm>
+ 的磁碟都是以字母 <literal>a</literal> 到 <literal>h</literal>
+ 的編號來表示。 編號是接在裝置名稱的後面的,因此
+ <quote>da0<emphasis>a</emphasis></quote> 是磁碟機 da 上的第一個
+ <quote>dangerously dedicated</quote>模式之分割區。
+ 而 <quote>ad1s3<emphasis>e</emphasis></quote>
+ 則是第二顆 IDE 硬碟上第三個 slice 的第五個分割區。</para>
+
+ <para>最後,我們就可以把系統上的每個磁碟都區分出來了。
+ 一個磁碟的名稱會有一個代碼來表示這個磁碟的類型,接著是一個數字,
+ 表示這是哪一個磁碟。 這邊跟 slice 每個磁碟編號從 0 開始不一樣。
+ 常見的代碼可以參考 <xref linkend="basics-dev-codes"/>。</para>
+
+ <para>當要參照一個分割區的時候,FreeBSD 會要您一併輸入包含這個分割區的
+ slice 及磁碟機名稱;當要參照一個 slice 的時候,也必須輸入包含這個
+ slice 的磁碟名稱。 怎麼做呢?首先先列出磁碟名稱,然後
+ <literal>s</literal> 加上 slice 編號,最後再輸入分割區字母代號。
+ 範例可以參考 <xref linkend="basics-disk-slice-part"/>.</para>
+
+ <para><xref linkend="basics-concept-disk-model"/>
+ 示範了一個基本的磁碟分布模式,相信對您有些幫助。</para>
+
+ <para>要安裝 FreeBSD,您必須先建置磁碟的 slice,接著於 slice 中建立要給
+ FreeBSD 用的分割區。 最後在這些分割區中建立檔案系統 (或 swap space)
+ 並決定要將這些檔案系統掛載於哪裡。</para>
+
+ <table frame="none" pgwide="1" xml:id="basics-dev-codes">
+ <title>磁碟機代號</title>
+
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="5*"/>
+
+ <thead>
+ <row>
+ <entry>代號</entry>
+
+ <entry>意義</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><filename>ad</filename></entry>
+
+ <entry>ATAPI(IDE) 磁碟機</entry>
+ </row>
+
+ <row>
+ <entry><filename>da</filename></entry>
+
+ <entry>SCSI 直接存取磁碟機</entry>
+ </row>
+
+ <row>
+ <entry><filename>acd</filename></entry>
+
+ <entry>ATAPI(IDE) 光碟機</entry>
+ </row>
+
+ <row>
+ <entry><filename>cd</filename></entry>
+
+ <entry>SCSI 光碟機</entry>
+ </row>
+
+ <row>
+ <entry><filename>fd</filename></entry>
+
+ <entry>軟碟機</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <example xml:id="basics-disk-slice-part">
+ <title>磁碟、slice 及分割區命名範例</title>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="5*"/>
+
+ <thead>
+ <row>
+ <entry>名稱</entry>
+
+ <entry>意義</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>ad0s1a</literal></entry>
+
+ <entry>第一個 IDE 硬碟 (<literal>ad0</literal>) 上第一個 slice
+ (<literal>s1</literal>)的第一個分割區(<literal>a</literal>)
+ 。</entry>
+ </row>
+
+ <row>
+ <entry><literal>da1s2e</literal></entry>
+ <entry>第二個 SCSI 硬碟 (<literal>da1</literal>) 上第二個 slice
+ (<literal>s2</literal>) 的第五個分割區 (<literal>e</literal>)
+ 。</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </example>
+
+ <example xml:id="basics-concept-disk-model">
+ <title>磁碟的概念模型</title>
+
+ <para>此圖顯示 FreeBSD 中接到系統的第一個 IDE 磁碟機內部配置圖。
+ 假設這個磁碟的容量是 4&nbsp;GB,並且包含了兩個 2&nbsp;GB 的
+ slice (&ms-dos; 的分割區)。 第一個 slice 是 DOS 的
+ <filename>C:</filename> 磁碟機,第二個則安裝了 FreeBSD。
+ 本範例的 FreeBSD 有三個分割區以及一個 swap 分割區。</para>
+
+ <para>這三個分割區每個都是一個檔案系統。
+ <literal>a</literal> 分割是根 (root) 檔案系統;分割
+ <literal>e</literal> 是 <filename>/var</filename>;而
+ <literal>f</literal> 分割是 <filename>/usr</filename>
+ 目錄結構。</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/disk-layout"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced">.-----------------. --.
+| | |
+| DOS / Windows | |
+: : &gt; First slice, ad0s1
+: : |
+| | |
+:=================: ==: --.
+| | | Partition a, mounted as / |
+| | &gt; referred to as ad0s2a |
+| | | |
+:-----------------: ==: |
+| | | Partition b, used as swap |
+| | &gt; referred to as ad0s2b |
+| | | |
+:-----------------: ==: | Partition c, no
+| | | Partition e, used as /var &gt; file system, all
+| | &gt; referred to as ad0s2e | of FreeBSD slice,
+| | | | ad0s2c
+:-----------------: ==: |
+| | | |
+: : | Partition f, used as /usr |
+: : &gt; referred to as ad0s2f |
+: : | |
+| | | |
+| | --' |
+`-----------------' --'</literallayout>
+ </textobject>
+ </mediaobject>
+ </example>
+ </sect1>
+
+
+
+ <sect1 xml:id="mount-unmount">
+ <title>掛載與卸載檔案系統</title>
+
+ <para>檔案系統就像一顆樹。<filename>/</filename>
+ 就像是樹根,而 <filename>/dev</filename>,<filename>/usr</filename>
+ 以及其他在根目錄下的目錄就像是樹枝,而這些樹枝上面又還有分支,像是
+ <filename>/usr/local</filename> 等。</para>
+
+ <indexterm><primary>根檔案系統</primary></indexterm>
+ <para>因為某些原因,我們會將一些目錄分別放在不同的檔案系統上。
+ 如 <filename>/var</filename> 包含了可能會滿出來的
+ <filename>log/</filename>,<filename>spool/</filename>
+ 等目錄以及各式各樣的暫存檔。
+ 把根檔案系統塞到滿出來顯然不是個好主意,所以我們往往會比較傾向把
+ <filename>/var</filename> 從 <filename>/</filename> 中拉出來。</para>
+
+ <para>另一個常見到把某些目錄放在不同檔案系統上的理由是:
+ 這些檔案在不同的實體或虛擬磁碟機上。
+ 像是<link linkend="network-nfs">網路檔案系統</link>
+ (Network File System) 或是光碟機。</para>
+
+ <sect2 xml:id="disks-fstab">
+ <title> <filename>fstab</filename> 檔</title>
+ <indexterm>
+ <primary>檔案系統 file systems</primary>
+ <secondary>由fstab掛載 mounted with fstab</secondary>
+ </indexterm>
+
+ <para>在 <filename>/etc/fstab</filename>
+ 裡面有設定的檔案系統會在<link linkend="boot">開機</link>
+ 的過程中自動地被掛載
+ (除非該檔案系統有被加上 <option>noauto</option> 參數)。</para>
+
+ <para><filename>/etc/fstab</filename> 檔案內容的格式如下:</para>
+
+ <programlisting><replaceable>device</replaceable> <replaceable>/mount-point</replaceable> <replaceable>fstype</replaceable> <replaceable>options</replaceable> <replaceable>dumpfreq</replaceable> <replaceable>passno</replaceable></programlisting>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>device</literal></term>
+ <listitem>
+ <para>裝置名稱 (該裝置必須真的存在)。 詳情請參閱
+ <xref linkend="disks-naming"/>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>mount-point</literal></term>
+
+ <listitem><para>檔案系統要掛載到的目錄 (該目錄必須真的存在)。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>fstype</literal></term>
+
+ <listitem>
+ <para>檔案系統類型,這是要傳給 &man.mount.8; 的參數。
+ FreeBSD 預設的檔案系統是 <literal>ufs</literal>。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>options</literal></term>
+
+ <listitem>
+ <para>可讀可寫的檔案系統用
+ <option>rw</option>,而唯讀的檔案系統則是用
+ <option>ro</option>,後面視需要還可以加其他選項。
+ 常見的選項如 <option>noauto</option>
+ 是用在不要於開機過程中自動的掛載的檔案系統。
+ 其他選項可參閱 &man.mount.8; 說明。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>dumpfreq</literal></term>
+
+ <listitem>
+ <para>&man.dump.8; 由此項目決定那些檔案系統需要傾印。
+ 如果這格空白則以零為預設值。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>passno</literal></term>
+
+ <listitem>
+ <para>這個項目決定檔案系統檢查的順序。
+ 對於要跳過檢查的檔案系統,它們的 <literal>passno</literal>
+ 值要設為零。 根檔案系統的 <literal>passno</literal> 值應設為一
+ (因為需要比所有其他的還要先檢查),而其他的檔案系統的
+ <literal>passno</literal> 值應該要設得比一大。
+ 若有多個檔案系統具有相同的 <literal>passno</literal> 值,則
+ &man.fsck.8; 會試著平行地(如果可能的話)檢查這些檔案系統。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>更多關於 <filename>/etc/fstab</filename>
+ 檔案格式及選項的資訊請參閱 &man.fstab.5; 說明文件。</para>
+ </sect2>
+
+ <sect2 xml:id="disks-mount">
+ <title><command>mount</command> 指令</title>
+ <indexterm>
+ <primary>檔案系統 file systems</primary>
+ <secondary>掛載 mounting</secondary>
+ </indexterm>
+
+ <para>&man.mount.8; 指令是拿來掛載檔案系統用的。</para>
+
+ <para>基本的操作指令格式如下:</para>
+
+ <informalexample>
+ <screen>&prompt.root; <userinput>mount device mountpoint</userinput></screen>
+ </informalexample>
+
+ <para>在 &man.mount.8;
+ 裡面有提到一大堆的選項,不過最常用的就是這些:</para>
+
+ <variablelist>
+ <title>掛載選項</title>
+
+ <varlistentry>
+ <term><option>-a</option></term>
+
+ <listitem>
+ <para>把 <filename>/etc/fstab</filename>
+ 裡面所有還沒有被掛載、沒有被標記成 <quote>noauto</quote>
+ 而且沒有用 <option>-t</option> 排除的檔案系統掛載起來。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-d</option></term>
+
+ <listitem>
+ <para>執行所有的動作,但是不真的去呼叫掛載的 system call。
+ 這個選項和 <option>-v</option> 搭配拿來推測 &man.mount.8;
+ 將要做什麼動作時很好用。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-f</option></term>
+
+ <listitem>
+ <para>強迫掛載不乾淨的檔案系統 (危險),或是用來強制取消寫入權限
+ (把檔案系統的掛載狀態從可存取變成唯讀)。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-r</option></term>
+
+ <listitem>
+ <para>用唯讀的方式掛載檔案系統。 這個選項和在 <option>-o</option>
+ 選項中指定 <option>ro</option> (在 &os; 5.2之前的版本是用
+ <option>rdonly</option>) 參數是一樣的。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t</option>
+ <replaceable>fstype</replaceable></term>
+
+ <listitem>
+ <para>用指定的檔案系統型態 (fstype)
+ 來掛載指定的檔案系統,或是在有 <option>-a</option>
+ 選項時只掛載指定型態的檔案系統。</para>
+
+ <para>預設的檔案系統是 <quote>ufs</quote>。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-u</option></term>
+
+ <listitem>
+ <para>更新檔案系統的掛載選項。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+
+ <listitem>
+ <para>顯示較詳細資訊。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+
+ <listitem>
+ <para>以可存取的模式掛載檔案系統。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para><option>-o</option> 選項後面會接著以逗號分隔的參數,例如:</para>
+ <variablelist>
+ <varlistentry>
+ <term>noexec</term>
+
+ <listitem>
+ <para>不允許在這個檔案系統上執行二進位程式碼,
+ 這也是一個蠻有用的安全選項。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>nosuid</term>
+
+ <listitem>
+ <para>不解析檔案系統上的 setuid 或 setgid 旗標,
+ 這也是一個蠻有用的安全選項。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 xml:id="disks-umount">
+ <title><command>umount</command> 指令</title>
+ <indexterm>
+ <primary>檔案系統 file systems</primary>
+ <secondary>卸載 unmounting</secondary>
+ </indexterm>
+
+ <para>&man.umount.8; 指令的參數可以是掛載點
+ (mountpoint),裝置名稱,以及 <option>-a</option> 或是
+ <option>-A</option> 等選項。</para>
+
+ <para>加上 <option>-f</option> 可以強制卸載,加上 <option>-v</option>
+ 則是會顯示詳細資訊。 要注意的是一般來說用 <option>-f</option>
+ 並不是個好主意,強制卸載檔案系統有可能會造成電腦當機,
+ 或者損壞檔案系統內的資料。</para>
+
+ <para><option>-a</option> 和 <option>-A</option>
+ 是用來卸載所有已掛載的檔案系統,另外還可以用 <option>-t</option>
+ 來指定要卸載的是哪些種類的檔案系統。 要注意的是 <option>-A</option>
+ 並不會試圖卸載根檔案系統。</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="basics-processes">
+ <title>程序</title>
+
+ <para>FreeBSD 是一個多工的作業系統,也就是說在同一時間內可以跑超過一個程式。
+ 每一個正在花時間跑的程式就叫做 <firstterm>程序 (process)</firstterm>。
+ 您下的每個指令都至少會開啟一個新的程序,
+ 而有些系統程序是一直在跑以維持系統正常運作的。</para>
+
+ <para>每一個程序都有一個不重覆的數字叫做 <firstterm>process ID
+ </firstterm>,或稱為 <firstterm>PID
+ </firstterm>,而且就像檔案一樣,每一個程序也有擁有者及群組。
+ 擁有者及群組的資訊是用來決定什麼檔案或裝置是這個程序可以開啟的
+ (前面有提到過檔案權限)。 大部份的程序都有父程序。
+ 父程序是開啟這個程序的程序,例如:您對 shell 輸入指令,shell
+ 本身就是一個程序,而您執行的指令也是程序。
+ 每一個您用這種方式跑的程序的父程序都是 shell。
+ 有一個特別的程序叫做 &man.init.8; 是個例外。<command>init</command>
+ 永遠是第一個程序,所以他的 PID 一直都會是 1。 在 FreeBSD 開機的時候
+ <command>init</command> 會自動地被 kernel 開啟。</para>
+
+ <para>要看系統執行中的程序,有兩個相當有用的指令可用:
+ &man.ps.1; 以及 &man.top.1;。<command>ps</command>
+ 指令是用來列出正在執行之程序,而且可以秀它們的
+ PID、用了多少記憶體、執行的指令名稱及其後之參數是什麼等等。
+ <command>top</command> 指令則是顯示所有正在執行的程序,
+ 並且數秒鐘更新一次。因此您可以互動式的觀看您的電腦正在做什麼。</para>
+
+ <para>在預設的情況下,<command>ps</command>
+ 指令只會顯示您所擁有的的程序。 例如:</para>
+
+ <screen>&prompt.user; <userinput>ps</userinput>
+ 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</screen>
+
+ <para>在這個範例裡可以看到 &man.ps.1; 的輸出分成好幾個欄位。
+ <literal>PID</literal> 就是前面有提到的 process ID。 PID 的分配是從
+ 1 開始一直到 99999,如果用完的話又會繞回來重頭開始分配
+ (若該 PID 已經在用了,則 PID 不會重新分配)。
+ <literal>TT</literal> 欄位是指這個程式在哪個 tty
+ 上執行,在這裡可以先忽略不管。<literal>STAT</literal>
+ 是程式的狀態,也可以先不要管。<literal>TIME</literal> 是這個程式在
+ CPU 上執行的時間&mdash;這通常不是程式總共花的時間,
+ 因為當您開始執行程式後,大部份的程式在 CPU 上執行前會先花上不少時間等待
+ 。 最後,<literal>COMMAND</literal> 是執行這個程式的命令列。</para>
+
+ <para>&man.ps.1;
+ 有幾個不同的選項組合可以用來變更顯示出來的資訊,其中一個最有用的組合是
+ <literal>auxww</literal>。
+ <option>a</option> 可以顯示所有正在跑的程序的指令,不只是您自已的。
+ <option>u</option> 則是顯示程序的擁有者名稱以及記憶體使用情況。
+ <option>x</option> 可以把 daemon 程序顯示出來,
+ 而 <option>ww</option> 可讓 &man.ps.1; 顯示出每個程序完整的內容,
+ 而不致因過長而被螢幕截掉了。</para>
+
+ <para>&man.top.1; 也有類似的輸出。 一般的情況看像是這樣:</para>
+
+ <screen>&prompt.user; <userinput>top</userinput>
+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
+...</screen>
+
+ <para>輸出的資訊分成兩個部份。開頭 (前五行) 秀出最近一個程序的
+ PID、系統平均負載 (系統有多忙錄的測試)、系統的開機時間
+ (從上次重開算起) 以及現在的時間等。
+ 在開頭裡面的其他數字分別是在講有多少程序正在執行
+ (在本例中為47)、有多少記憶體及 swap space
+ 被占用了,還有就是系統分別花了多少時間在不同的 CPU 狀態上。</para>
+
+ <para>接下來的部份是由好幾個欄位所構成,和 &man.ps.1; 輸出的資訊類似。
+ 就如同前例,您可以看到 PID、使用者名稱、CPU
+ 花費的時間以及正在執行的指令。 &man.top.1;
+ 在預設的情況下還會告訴您程序用掉了多少的記憶體空間。
+ 在這邊會分成兩欄,一個是總用量 (total size),另一個是實際用量
+ (resident size)&mdash;總用量是指這個應用程式需要的記憶體空間,
+ 而實際用量則是指實際上該程式的記憶體使用量。
+ 在這個例子裡面您可以看到 <application>&netscape;</application>
+ 要了幾乎到 30 MB 的 RAM,但是只有用到 9 MB。</para>
+
+ <para>&man.top.1; 每隔 2 秒鐘會自動更新顯示內容,可用 <option>s</option>
+ 選項來改變間隔的時間。</para>
+
+ </sect1>
+
+ <sect1 xml:id="basics-daemons">
+ <title>Daemon、信號及終止程序</title>
+
+ <para>當在執行文書編輯器時,您可以很容易地使用它,叫它讀取檔案或是什麼的。
+ 可以這樣做是因為編輯器有提供這些功能,
+ 還有就是編輯器依附在一個<firstterm>終端機 (Terminal) </firstterm>之上。
+ 有些程式並不是設計成一直在接收使用者的輸入的,
+ 所以它們在一開始執行的時候就從終端機斷開了。 例如說,
+ 網頁伺服器整天都在回應網頁方面的要求,它通常不需要您輸入任何東西。
+ 另外,像是把信從一個站傳送到另一個站的程式,也是這種類型的應用程式。
+ </para>
+
+ <para>我們把這種程式稱作 <firstterm>daemon</firstterm>。
+ Daemon (惡魔、守護神)
+ 是希臘神話中的角色:祂們不屬於善良陣營或邪惡陣營,是守護的小精靈。
+ 大致上來說祂們就是在替人類做一些有用的事情,
+ 跟今天的網頁伺服器或是郵件伺服器很像。 這也就是為何 BSD
+ 的吉祥物,長期以來都是一隻穿著帆布鞋拿著三叉耙的快樂小惡魔的原因。</para>
+
+ <para>通常來說 deamon 程式的名字後面都會加一個字母 <quote>d</quote>。
+ <application>BIND</application> 是 Berkeley Internet Name Domain
+ 的縮寫 (但實際上執行的程式名稱是 <command>named</command>)、Apache
+ 網頁伺服器的程式名稱是 <command>httpd</command>、印表機服務程式是
+ <command>lpd</command>,依此類推。
+ 這是習慣用法,並沒有硬性規定,例如 <application>Sendmail</application>
+ 主要的寄信 daemon 是叫做 <command>sendmail</command> 而不是
+ <command>maild</command>,跟您想像的不一樣。</para>
+
+ <para>有些時候會需要跟某個 daemon 程序溝通,
+ 這些溝通是透過所謂的<firstterm>信號(signal)</firstterm>來傳遞給該 daemon
+ 程序(或是其他執行中的程序)。
+ 藉由送出信號,您可以和一個 daemon (或是任何一個正在跑的程序) 溝通。
+ 信號有很多種&mdash;有些有特定的意義,有些則是會由應用程式來解讀。
+ 應用程式的說明文件會告訴您該程式是如何解讀信號的。
+ 您只能送信號給您擁有的程序,送 &man.kill.1; 或 &man.kill.2;
+ 的信號給別人的程序是不被允許的。 不過 <systemitem class="username"> root </systemitem>
+ 不受此限制,他可以送信號給任何人的程序。</para>
+
+ <para>FreeBSD 本身在某些情況也會送信號給應用程式。
+ 假設有個應用程式寫得很爛,然後企圖要存取它不該碰的記憶體的時候,FreeBSD
+ 會送一個 <firstterm>Segmentation Violation</firstterm> 信號
+ (<literal>SIGSEGV</literal>) 給這個程序。
+ 又如果有一個應用程式用了 &man.alarm.3; 的 system call
+ 要求系統在過一段時間之後叫他一下,時間到了的時候鬧鐘的信號
+ (<literal>SIGALRM</literal>) 就會被送出了,其他的依此類推。</para>
+
+ <para><literal>SIGTERM</literal> and <literal>SIGKILL</literal>
+ 這兩個信號可以拿來終止程序。 用 <literal>SIGTERM</literal>
+ 結束程序是比較有禮貌的方式,該程序會<emphasis>捕捉 (catch) </emphasis>
+ 這個信號而了解到您想要把他關掉。 接著下來它會把它自已開的記錄檔通通關掉,
+ 然後在關掉程序之前結束掉手邊的工作。 在某些情況下程序有可能會裝作沒看見
+ <literal>SIGTERM</literal>,假如它正在做一些不能中斷的工作的話。</para>
+
+ <para><literal>SIGKILL</literal> 就沒有辦法被程序忽略了。
+ 這是一個<quote>我管你正在幹嘛,現在就給我停下來</quote>的信號。
+ 如果您送了 <literal>SIGKILL</literal> 信號給某個程序,FreeBSD
+ 將會把它停掉<footnote>
+ <para>不完全正確&mdash;還是有少數東西不能被中斷。
+ 例如有個程序正在從網路上的別的電腦讀一個檔案,
+ 而那部電腦因為某些理由連不到 (機器被關掉,或是網路爛掉了),
+ 那這個程序我們就說他是一個<quote>不能中斷的</quote>程序。
+ 通常在經過兩分鐘左右之後這個程序會逾時。
+ 當發生逾時的時候這個程序就會被結束掉了。</para>
+ </footnote>。</para>
+
+ <para>這些是其他您有可能會要用到的信號:
+ <literal>SIGHUP</literal>,<literal>SIGUSR1</literal>,以及
+ <literal>SIGUSR2</literal>。
+ 這些是通用的信號,當送出時不同的應用程式會有不同的反應。</para>
+
+ <para>假設您更動了您的網頁伺服器的設定檔&mdash;
+ 您想要叫網頁伺服器去重新讀取設定值。 您可以關閉後再重新啟動
+ <command>httpd</command>,但是這麼做會造成網頁伺服器暫停服務一段時間,
+ 這樣子可能不太好。
+ 大部份的 daemon 都寫成會去回應 <literal>SIGHUP</literal>。
+ 當收到這個信號之後,它們會去重新讀取自已的設定檔。
+ 因此您可以用送 <literal>SIGHUP</literal> 信號來取代關掉重開。
+ 又因為沒有標準在規範如何回應這些信號,不同的 daemon
+ 可能會有不同的行為,所以有疑問的話請先確認並翻閱 deamon
+ 的說明文件。</para>
+
+ <para>信號是由 &man.kill.1; 指令送出的,如範例所示:</para>
+
+ <procedure>
+ <title>送信號給程序</title>
+
+ <para>這個範例將會示範如何送一個信號給 &man.inetd.8;。
+ <command>inetd</command> 的設定檔是
+ <filename>/etc/inetd.conf</filename>,而 <command>inetd</command>
+ 會在收到 <literal>SIGHUP</literal> 的時候重新讀取這個設定檔。</para>
+
+ <step>
+ <para>找出您想要送信號的那個程序的 ID。 您會用到 &man.ps.1; 以及
+ &man.grep.1; 這兩個指令。 &man.grep.1; 是用來在輸出中搜尋,
+ 找出您指定的字串。 這個指令是由一般使用者執行,而 &man.inetd.8;
+ 是由 <systemitem class="username">root</systemitem> 執行,所以在使用 &man.ps.1; 時需要加上
+ <option>ax</option> 選項。</para>
+
+ <screen>&prompt.user; <userinput>ps -ax | grep inetd</userinput>
+ 198 ?? IWs 0:00.00 inetd -wW</screen>
+
+ <para>因此可知 &man.inetd.8; 的 PID 為 198。 在某些情況下
+ <literal>grep inetd</literal> 這個指令本身也會出現在輸出裡。
+ 這是因為 &man.ps.1; 乃是找所有執行中的程序的方式造成的。</para>
+ </step>
+
+ <step>
+ <para>用 &man.kill.1; 來送信號。 又因為 &man.inetd.8; 是由
+ <systemitem class="username">root</systemitem> 執行的,您必須用 &man.su.1; 切換成
+ <systemitem class="username">root</systemitem>先。</para>
+
+ <screen>&prompt.user; <userinput>su</userinput>
+<prompt>Password:</prompt>
+&prompt.root; <userinput>/bin/kill -s HUP 198</userinput></screen>
+
+ <para>一般情況對大多數 &unix; 指令來講,當 &man.kill.1;
+ 執行成功時並不會輸出任何訊息。
+ 假設您送一個信號給某個不是您所擁有的程序,
+ 那麼您就會吃到這個錯誤訊息: <errorname>kill:
+ <replaceable>PID</replaceable>: Operation not permitted</errorname>。
+ 而如果您打錯 PID 的話,那就會把信號送給錯誤的程序。 這樣可能會很糟,
+ 不過如果您夠幸運的話,可能剛好就只是把信號送給一個非使用中的
+ PID,那您就只會看到 <errorname>kill:
+ <replaceable>PID</replaceable>: No such process</errorname> 而已。
+ </para>
+
+ <note>
+ <title>為什麼用 <command>/bin/kill</command>?</title>
+
+ <para>很多 shell 有提供內建的 <command>kill</command> 指令。
+ 也就是說這種 shell 會直接送信號,而不是執行
+ <filename>/bin/kill</filename>。
+ 這樣是蠻方便的沒錯啦,但是不同的 shell
+ 會有不同的語法來指定信號的名稱等。
+ 與其嘗試去把它們通通學會,不如就單純的直接用 <command>/bin/kill
+ ...</command> 吧。</para>
+ </note>
+ </step>
+ </procedure>
+
+ <para>要送其他的信號的話也是非常類似,就視需要把指令中的
+ <literal>TERM</literal> 或 <literal>KILL</literal>
+ 替換掉即可。</para>
+
+ <important>
+ <para>隨便抓一個系統中的程序然後把他砍掉並不是個好主意。
+ 特別是 &man.init.8;, process ID 1,一個非常特別的程序。
+ 執行 <command>/bin/kill -s KILL 1</command>
+ 的結果就是系統立刻關機。 因此在您按下 <keycap>Return</keycap>
+ 要執行 &man.kill.1;<emphasis>之前</emphasis>,
+ 請<emphasis>一定</emphasis>要記得再次確認您下的參數。</para>
+ </important>
+ </sect1>
+
+ <sect1 xml:id="shells">
+ <title>Shells</title>
+ <indexterm><primary>shells</primary></indexterm>
+ <indexterm><primary>命令列 command line</primary></indexterm>
+
+ <para>在 FreeBSD 中,很多日常的工作是在一個叫做 shell
+ 的文字介面中完成的。
+ Shell 的主要工作就是從輸入中收到命令並執行它們。
+ 許多 shell 也有內建一些有助於日常工作的指令,
+ 像是檔案管理、檔案比對、命令列編輯、指令巨集以及環境變數等。
+ FreeBSD 有內附了幾個 shell,像是 <command>sh</command>,
+ Bourne Shell,以及 <command>tcsh</command>,改良版的 C-shell。
+ 還有許多其他的 shell 可以從 FreeBSD Ports Collection
+ 中取得,像是 <command>zsh</command> 以及 <command>bash</command>
+ 等。</para>
+
+ <para>您用哪個 shell 呢? 其實每個人的喜好都不一樣。
+ 如果您是一個 C 程式設計師,那對於使用像是 <command>tcsh</command>
+ 這種 C-like 的 shell 可能會感到相當愉快。 如果你是從 Linux
+ 跳過來的,或者您是一個 &unix; 新手,那您也許會想要用
+ <command>bash</command> 來當作文字介面。
+ 每一個 shell 都有自已獨特之處,至於這些特點能不能配合您的工作環境?
+ 那就是您選擇 shell 的重點了。</para>
+
+ <para>檔名自動補齊就是常見的 shell 功能。
+ 首先輸入指令或檔案的前幾個字母,這時通常您只需要按下 <keycap>Tab</keycap>
+ 鍵,接下來 shell 就會自動把指令或是檔案名稱剩餘的部份補齊。
+ 假設您有兩個檔案分別叫作 <filename>foobar</filename> 及
+ <filename>foo.bar</filename>。 現在要刪掉
+ <filename>foo.bar</filename>,那麼可以輸入:
+ <command>rm fo[Tab].[Tab]</command>
+ </para>
+
+ <para>Shell 會印出這個: <command>rm foo[嗶].bar</command>。</para>
+
+ <para>[嗶] 是 console 的響鈴,這嗶的一聲是 shell
+ 在告訴我說它沒有辦法完全自動補齊檔名,因為有不只一個檔名符合條件。
+ <filename>foobar</filename> 和 <filename>foo.bar</filename> 都是
+ <literal>fo</literal> 開頭的檔名,不過它至少可以補齊到 <literal>foo</literal>。
+ 如果您接著輸入 <literal>.</literal> 然後再按 <keycap>Tab</keycap>
+ 一次,那 shell 就能夠替您把剩下的檔名填滿了。</para>
+
+ <indexterm><primary>environment variables</primary></indexterm>
+
+ <para>Shell 的另一項特點是使用了環境變數。
+ 環境變數是以變數與鍵值(variable/key)的對應關係儲存於 shell
+ 的環境空間中,任何由 shell 所產生的程序都可以讀取此空間,
+ 因此這個空間儲存了許多程序的設定組態。 在此附上
+ 一份常見環境變數與其涵義的列表:</para>
+ <indexterm><primary>environment variables</primary></indexterm>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>變數</entry>
+ <entry>詳細說明</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><envar>USER</envar></entry>
+ <entry>目前登入的使用者名稱。</entry>
+ </row>
+
+ <row>
+ <entry><envar>PATH</envar></entry>
+ <entry>以冒號(:)隔開的目錄列表,用以搜尋執行檔的路徑。</entry>
+ </row>
+
+ <row>
+ <entry><envar>DISPLAY</envar></entry>
+ <entry>若存在這個環境變數,則代表 X11 連結顯示器的網路名稱。</entry>
+ </row>
+
+ <row>
+ <entry><envar>SHELL</envar></entry>
+ <entry>目前使用的 shell。</entry>
+ </row>
+
+ <row>
+ <entry><envar>TERM</envar></entry>
+ <entry>使用者終端機的名稱,能藉由此變數判斷終端機的能力。</entry>
+ </row>
+
+ <row>
+ <entry><envar>TERMCAP</envar></entry>
+ <entry>Database entry of the terminal escape codes to perform
+ various terminal functions.</entry>
+ </row>
+
+ <row>
+ <entry><envar>OSTYPE</envar></entry>
+ <entry>作業系統的種類,如:FreeBSD。</entry>
+ </row>
+
+ <row>
+ <entry><envar>MACHTYPE</envar></entry>
+ <entry>目前系統所用的 CPU 架構。</entry>
+ </row>
+
+ <row>
+ <entry><envar>EDITOR</envar></entry>
+ <entry>使用者偏好的文字編輯器。</entry>
+ </row>
+
+ <row>
+ <entry><envar>PAGER</envar></entry>
+ <entry>使用者偏好的文字分頁器(text pager)。</entry>
+ </row>
+
+ <row>
+ <entry><envar>MANPATH</envar></entry>
+ <entry>以冒號(:)隔開的目錄列表,用以搜尋 manual pages 的路徑。</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <indexterm><primary>Bourne shells</primary></indexterm>
+ <para>在不同的 shell 底下設定環境變數的方式也有所不同。
+ 舉例來說,在 C-Style 的 shell 底下,像是
+ <command>tcsh</command> 和 <command>csh</command>,你必須使用
+ <command>setenv</command> 來設定環境變數。
+ 但在 Bourne shells 底下,像是 <command>sh</command> 和
+ <command>bash</command>,你則必須使用
+ <command>export</command> 來設定你所使用的環境變數。
+ 再舉個例子來說,若要設定或是修改
+ <envar>EDITOR</envar> 這個環境變數,在 <command>csh</command> 或
+ <command>tcsh</command> 下設定 <envar>EDITOR</envar> 這個環境變數為
+ <filename>/usr/local/bin/emacs</filename> 的指令是:</para>
+
+ <screen>&prompt.user; <userinput>setenv EDITOR /usr/local/bin/emacs</userinput></screen>
+
+ <para>在 Bourne shells 下則是:</para>
+
+ <screen>&prompt.user; <userinput>export EDITOR="/usr/local/bin/emacs"</userinput></screen>
+
+ <para>大多數的 shell 都支援使用者在命令列中將
+ <literal>$</literal> 字元放在變數之前,以取得環境變數的值。
+ 舉例來說,<command>echo $TERM</command> 會
+ 顯示出 <envar>$TERM</envar> 的設定值,這是因為 shell 取得了
+ <envar>$TERM</envar> 的設定值,
+ 並將其傳給 <command>echo</command> 顯示出來。</para>
+
+ <para>Shell 中有某些特別的字元是來表示特殊的資料,我們將其稱作
+ meta-characters。 其中最常見的是
+ <literal>*</literal> 字元,他代表了檔名中的任意字元。
+ 這些特殊字元可以用在檔名展開(filename globbing)上,舉例來說,輸入
+ <command>echo *</command> 會和輸入
+ <command>ls</command> 得到幾乎相同的結果,這是因為 shell 會將所有符合
+ <literal>*</literal> 字元的檔案傳到命令列上,再由
+ <command>echo</command> 顯示出來。</para>
+
+ <para>為了避免 shell 轉譯這些特殊字元,我們可以在這些特殊字元前放一個反斜線
+ (<literal>\</literal>) 字元使他們跳脫(escape) shell 的轉譯。舉例來說,
+ <command>echo $TERM</command> 會印出你目前設定的終端機格式,
+ <command>echo \$TERM</command> 則會直接印出 <envar>$TERM</envar>
+ 這幾個字。</para>
+
+ <sect2 xml:id="changing-shells">
+ <title>變更你的 Shell</title>
+
+ <para>變更 shell 最簡單的方法就是透過 <command>chsh</command> 命令。
+ 執行 <command>chsh</command> 將會呼叫環境變數中 <envar>EDITOR</envar>
+ 指定的文字編輯器。 如果沒有設定,則預設是 <command>vi</command>。
+ 請依照需求去修改 <quote>Shell:</quote> 的值。</para>
+
+ <para>你也可以透過 <command>chsh</command> 的參數 <option>-s</option>,
+ 這可以直接設定你的 shell 而不需要透過任何文字編輯器。 例如,
+ 假設想把所用的 shell 改為 <command>bash</command>,
+ 可以透過下列的方式:</para>
+
+ <screen>&prompt.user; <userinput>chsh -s /usr/local/bin/bash</userinput></screen>
+
+ <note>
+ <para>你所使用的 shell <emphasis>必須</emphasis> 列於
+ <filename>/etc/shells</filename> 裡頭。 如果是由
+ <link linkend="ports">Ports Collection</link> 來裝 shell,
+ 那這個步驟已經完成了。 但若是手動安裝了一個 shell,
+ 那麼就必須為新安裝的 shell 進行設定。</para>
+
+ <para>舉例來說,若手動安裝了 <command>bash</command> 並將它置於
+ <filename>/usr/local/bin</filename> 底下,你還得:</para>
+
+ <screen>&prompt.root; <userinput>echo &quot;/usr/local/bin/bash&quot; &gt;&gt; /etc/shells</userinput></screen>
+
+ <para>然後再重新執行 <command>chsh</command>。</para>
+ </note>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="editors">
+ <title>文字編輯器</title>
+ <indexterm><primary>text editors</primary></indexterm>
+ <indexterm><primary>editors</primary></indexterm>
+
+ <para>在 FreeBSD 中有許多設定必須透過編輯文字檔完成。
+ 因此,若能熟悉文字編輯器是再好不過的。
+ FreeBSD 本身(指 base system)就附有幾種文字編輯器,
+ 此外,你也可以透過 Ports Collection 來安裝其他的文字編輯器。</para>
+
+ <indexterm>
+ <primary><command>ee</command></primary>
+ </indexterm>
+ <indexterm>
+ <primary>editors</primary>
+ <secondary><command>ee</command></secondary>
+ </indexterm>
+ <para>最簡單易學的文字編輯器叫做 <application>ee</application>,
+ 代表了其全名 easy editor。 要開始使用 <application>ee</application>,
+ 必須在命令列上輸入
+ <command>ee filename</command>,
+ 這邊的 <replaceable>filename</replaceable> 代表你想要編輯的檔案名稱。
+ 舉例來說,要編輯 <filename>/etc/rc.conf</filename>,就要輸入
+ <command>ee /etc/rc.conf</command>。
+ 而在 <command>ee</command> 的操作介面下,
+ 所有編輯器的功能與操作都會顯示在螢幕的正上方。
+ 其中的插入符號(<literal>^</literal>)代表鍵盤上的 <keycap>Ctrl</keycap>
+ 鍵,所以 <literal>^e</literal> 就等同於
+ <keycombo action="simul"><keycap>Ctrl</keycap><keycap>e</keycap></keycombo>
+ 。 若要結束 <application>ee</application>,請按下 <keycap>Esc</keycap>
+ 鍵,接著選擇 leave editor 即可。
+ 此時如果該檔案有修改過,編輯器會提醒你是否要存檔。</para>
+
+ <indexterm>
+ <primary><command>vi</command></primary>
+ </indexterm>
+ <indexterm>
+ <primary>editors</primary>
+ <secondary><command>vi</command></secondary>
+ </indexterm>
+ <indexterm>
+ <primary><command>emacs</command></primary>
+ </indexterm>
+ <indexterm>
+ <primary>editors</primary>
+ <secondary><command>emacs</command></secondary>
+ </indexterm>
+
+ <para>此外,FreeBSD 也內附了幾個好用的文字編輯器,像是 base system 的
+ <application>vi</application> 及 FreeBSD Ports Collection 內的其他編輯器,
+ 比如 <application>Emacs</application> 及 <application>vim</application>
+ (<package>editors/emacs</package> 及
+ <package>editors/vim</package>)。
+ 這些文字編輯器提供更強的功能,但是也比較難學習。
+ 然而若要從事大量文字編輯工作,
+ 那麼花點時間來學習這些好用的編輯器,
+ 會在日後為您省下更多的時間。</para>
+ </sect1>
+
+ <sect1 xml:id="basics-devices">
+ <title>設備及設備節點</title>
+
+ <para>設備(device)主要是指跟硬體比較有關的術語,
+ 包括磁碟、印表機、顯示卡和鍵盤。 FreeBSD 開機過程當中,
+ 大多數硬體通常都能偵測到並顯示出來,也可以查閱
+ <filename>/var/run/dmesg.boot</filename> 內有開機的相關訊息。</para>
+
+ <para>舉例來說,<filename>acd0</filename>即為第一台 IDE 光碟機的代號,
+ 而 <filename>kbd0</filename> 則代表鍵盤。</para>
+
+ <para>在 &unix; 作業系統,
+ 大部分的設備都是透過叫做 device nodes(設備節點)的特殊檔案來作存取,
+ 而這些檔案都位於 <filename>/dev</filename> 目錄。</para>
+
+ <sect2>
+ <title>建立設備節點</title>
+ <para>若要在系統上建立新節點,或者是要編譯某些新硬體的支援軟體,
+ 那麼就要先新增設備節點。</para>
+
+ <sect3>
+ <title><literal>DEVFS</literal> (DEVice File System)</title>
+
+ <para>設備檔案系統(或稱為 <literal>DEVFS</literal>) 是指在整體檔案系統
+ namespace 提供 kernel 的設備 namespace。 <literal>DEVFS</literal>
+ 乃是維護這些檔案系統,而不能新增或修改這些設備節點。</para>
+
+ <para>細節請參閱 &man.devfs.5; 說明。</para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="binary-formats">
+ <title>Binary 的格式</title>
+
+ <para>若要知道為何 &os; 是採用 &man.elf.5; 格式,必先瞭解當前 &unix;
+ 系統中三種<quote>影響最為重大</quote>的可執行檔相關背景:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>&man.a.out.5;</para>
+
+ <para>最古老、<quote>經典</quote> 的 &unix; object 檔格式。
+ 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.</para>
+ </listitem>
+
+ <listitem>
+ <para><acronym>COFF</acronym></para>
+
+ <para>The SVR3 object format. The header now comprises a
+ section table, so you can have more than just .text, .data,
+ and .bss sections.</para>
+ </listitem>
+
+ <listitem>
+ <para>&man.elf.5;</para>
+
+ <para>The successor to <acronym>COFF</acronym>, featuring
+ multiple sections and 32-bit or 64-bit possible values. One
+ major drawback: <acronym>ELF</acronym> 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.</para>
+
+ <para>FreeBSD tries to work around this problem somewhat by
+ providing a utility for <emphasis>branding</emphasis> a
+ known <acronym>ELF</acronym> executable with information
+ about the ABI it is compliant with. See the manual page for
+ &man.brandelf.1; for more information.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>FreeBSD comes from the <quote>classic</quote> 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
+ <acronym>ELF</acronym> binaries (and kernels) on a FreeBSD
+ system for some time before that, FreeBSD initially resisted the
+ <quote>push</quote> to switch to <acronym>ELF</acronym> as the
+ default format. Why? Well, when the Linux camp made their
+ painful transition to <acronym>ELF</acronym>, it was not so much
+ to flee the <filename>a.out</filename> 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
+ <acronym>ELF</acronym> tools available offered a solution to the
+ shared library problem and were generally seen as <quote>the way
+ forward</quote> 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.</para>
+
+ <para>So, why are there so many different formats?</para>
+
+ <para>Back in the dim, dark past, there was simple hardware. This
+ simple hardware supported a simple, small system. <filename>a.out</filename> 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 <filename>a.out</filename> format because it was sufficient
+ for the early ports of &unix; to architectures like the Motorola
+ 68k, VAXen, etc.</para>
+
+ <para>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 <acronym>RISC</acronym>), <filename>a.out</filename>
+ was ill-suited for this hardware, so many formats were developed
+ to get to a better performance from this hardware than the
+ limited, simple <filename>a.out</filename> format could
+ offer. Things like <acronym>COFF</acronym>,
+ <acronym>ECOFF</acronym>, and a few obscure others were invented
+ and their limitations explored before things seemed to settle on
+ <acronym>ELF</acronym>.</para>
+
+ <para>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 <filename>a.out</filename> 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 <filename>a.out</filename> format to
+ allow all of these things to happen, and they basically worked
+ for a time. In time, <filename>a.out</filename> was not up to
+ handling all these problems without an ever increasing overhead
+ in code and complexity. While <acronym>ELF</acronym> solved many
+ of these problems, it would be painful to switch from the system
+ that basically worked. So <acronym>ELF</acronym> had to wait
+ until it was more painful to remain with
+ <filename>a.out</filename> than it was to migrate to
+ <acronym>ELF</acronym>.</para>
+
+ <para>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 <application>as</application> and <application>ld</application> were not up to the
+ task. The new GNU tools chain (<application>binutils</application>) does support cross
+ compiling, <acronym>ELF</acronym>, shared libraries, C++
+ extensions, etc. In addition, many vendors are releasing
+ <acronym>ELF</acronym> binaries, and it is a good thing for
+ FreeBSD to run them.</para>
+
+ <para><acronym>ELF</acronym> is more expressive than <filename>a.out</filename> and
+ allows more extensibility in the base system. The
+ <acronym>ELF</acronym> tools are better maintained, and offer
+ cross compilation support, which is important to many people.
+ <acronym>ELF</acronym> may be a little slower than <filename>a.out</filename>, 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
+ <filename>a.out</filename> will be moved out of the <filename>GENERIC</filename>
+ kernel, and eventually removed from the kernel once the need to
+ run legacy <filename>a.out</filename> programs is past.</para>
+ </sect1>
+
+ <sect1 xml:id="basics-more-information">
+ <title>更多資訊</title>
+
+ <sect2 xml:id="basics-man">
+ <title>Manual 線上說明</title>
+ <indexterm><primary>manual pages</primary></indexterm>
+
+ <para>在使用 FreeBSD 時,最詳細的使用說明莫過於 man 線上說明。
+ 幾乎各程式都會有附上簡短說明,以介紹該程式的基本功能跟相關參數用法。
+ 可以透過 <command>man</command> 指令來閱讀這些說明,而
+ <command>man</command> 指令的使用相當簡單易懂:</para>
+
+ <screen>&prompt.user; <userinput>man command</userinput></screen>
+
+ <para><literal>command</literal> 處就是想要知道的指令。 舉個例子,
+ 若要知道 <command>ls</command> 的詳細用法,就可以打:</para>
+
+ <screen>&prompt.user; <userinput>man ls</userinput></screen>
+
+ <para>而各線上說明因為性質不同,而區分為下列的數字章節:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>使用者指令。</para>
+ </listitem>
+
+ <listitem>
+ <para>系統呼叫(System call) 及錯誤代號。</para>
+ </listitem>
+
+ <listitem>
+ <para>C 語言函式庫。</para>
+ </listitem>
+
+ <listitem>
+ <para>各設備的驅動程式。</para>
+ </listitem>
+
+ <listitem>
+ <para>檔案格式。</para>
+ </listitem>
+
+ <listitem>
+ <para>小遊戲程式及其他娛樂程式。</para>
+ </listitem>
+
+ <listitem>
+ <para>雜項工具、其他資訊。</para>
+ </listitem>
+
+ <listitem>
+ <para>系統維護、操作的指令。</para>
+ </listitem>
+
+ <listitem>
+ <para>Kernel 開發用途。</para>
+ </listitem>
+ </orderedlist>
+
+ <para>有些情況會有同樣主題但不同章節。 舉個例子,系統內會有
+ <command>chmod</command> 指令,但也有 <function>chmod()</function>
+ 系統呼叫。 在這種情況,<command>man</command>
+ 應該要指定所要查詢的章節:</para>
+
+ <screen>&prompt.user; <userinput>man 1 chmod</userinput></screen>
+
+ <para>如此一來就會查 <command>chmod</command> 指令部分。
+ 通常在寫文件時會把有參考到某特定章節的 man 號碼也一併寫在括號內。
+ 所以 &man.chmod.1; 就是指 <command>chmod</command> 指令,而
+ &man.chmod.2; 則是指系統呼叫的部分。</para>
+
+ <para>如果您已經知道命令的名稱,只是不知道要怎樣使用的話,那就比較好辦。
+ 但若不知道要用哪個指令時,該怎麼辦呢? 這個時候,就可以利用
+ <command>man</command> 的搜尋關鍵字功能,
+ 以在各說明的介紹部分搜尋相關字眼。,它的選項是 <option>-k</option>:
+ </para>
+
+ <screen>&prompt.user; <userinput>man -k mail</userinput></screen>
+
+ <para>如此一來會看到一堆有 <quote>mail</quote> 關鍵字的說明,
+ 事實上該功能與 <command>apropos</command> 指令是一樣的。</para>
+
+ <para>而有時你會看到像是 <filename>/usr/bin</filename>
+ 有許多看起來頗炫的指令,但不知其用途? 只要簡單輸入:</para>
+
+ <screen>&prompt.user; <userinput>cd /usr/bin</userinput>
+&prompt.user; <userinput>man -f *</userinput></screen>
+
+ <para>或者是</para>
+
+ <screen>&prompt.user; <userinput>cd /usr/bin</userinput>
+&prompt.user; <userinput>whatis *</userinput></screen>
+
+ <para>這兩者的指令效果是一樣的。</para>
+ </sect2>
+
+ <sect2 xml:id="basics-info">
+ <title>GNU Info 檔案</title>
+ <indexterm><primary>Free Software Foundation</primary></indexterm>
+
+ <para>FreeBSD 有許多程式跟工具來自於自由軟體基金會(FSF)。 除了 man
+ 線上說明之外,這些程式提供了另外一種更具有彈性的 hypertext 格式文件,
+ 叫做 <literal>info</literal>。 可以用 <command>info</command>
+ 指令來閱讀,或者若有裝 <application>emacs</application> 亦可透過
+ <application>emacs</application> 的 info 模式閱讀。</para>
+
+ <para>要用 &man.info.1; 指令,只需打:</para>
+
+ <screen>&prompt.user; <userinput>info</userinput></screen>
+
+ <para>按 <literal>h</literal> 會有簡單說明,而若要快速查閱相關操作方式,
+ 則請按 <literal>?</literal>。</para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/basics/example-dir1.dot b/zh_TW.UTF-8/books/handbook/basics/example-dir1.dot
new file mode 100644
index 0000000000..f259e8377d
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/basics/example-dir1.dot
@@ -0,0 +1,7 @@
+// $FreeBSD$
+
+digraph directory {
+ root [label="Root\n/"];
+ root -> "A1/";
+ root -> "A2/";
+}
diff --git a/zh_TW.UTF-8/books/handbook/basics/example-dir2.dot b/zh_TW.UTF-8/books/handbook/basics/example-dir2.dot
new file mode 100644
index 0000000000..b846c82399
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/basics/example-dir2.dot
@@ -0,0 +1,8 @@
+// $FreeBSD$
+
+digraph directory {
+ root [label="Root\n/"];
+ root -> "A1/" -> "B1/";
+ "A1/" -> "B2/";
+ root -> "A2/";
+}
diff --git a/zh_TW.UTF-8/books/handbook/basics/example-dir3.dot b/zh_TW.UTF-8/books/handbook/basics/example-dir3.dot
new file mode 100644
index 0000000000..178a3a91bb
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/basics/example-dir3.dot
@@ -0,0 +1,8 @@
+// $FreeBSD$
+
+digraph directory {
+ root [label="Root\n/"];
+ root -> "A1/";
+ root -> "A2/" -> "B1/";
+ "A2/" -> "B2/";
+}
diff --git a/zh_TW.UTF-8/books/handbook/basics/example-dir4.dot b/zh_TW.UTF-8/books/handbook/basics/example-dir4.dot
new file mode 100644
index 0000000000..82d12b421a
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/basics/example-dir4.dot
@@ -0,0 +1,9 @@
+// $FreeBSD$
+
+digraph directory {
+ root [label="Root\n/"];
+ root -> "A1/";
+ root -> "A2/" -> "B1/" -> "C1/";
+ "B1/" -> "C2/";
+ "A2/" -> "B2/";
+}
diff --git a/zh_TW.UTF-8/books/handbook/basics/example-dir5.dot b/zh_TW.UTF-8/books/handbook/basics/example-dir5.dot
new file mode 100644
index 0000000000..f5aa6e01dc
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/basics/example-dir5.dot
@@ -0,0 +1,9 @@
+// $FreeBSD$
+
+digraph directory {
+ root [label="Root\n/"];
+ root -> "A1/" -> "C1/";
+ "A1/" -> "C2/";
+ root -> "A2/" -> "B1/";
+ "A2/" -> "B2/";
+}
diff --git a/zh_TW.UTF-8/books/handbook/bibliography/Makefile b/zh_TW.UTF-8/books/handbook/bibliography/Makefile
new file mode 100644
index 0000000000..e1ac7fd2e2
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/bibliography/Makefile
@@ -0,0 +1,16 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+# Original revision: 1.1
+#
+
+CHAPTERS= bibliography/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/bibliography/chapter.xml b/zh_TW.UTF-8/books/handbook/bibliography/chapter.xml
new file mode 100644
index 0000000000..2cbfa7068a
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/bibliography/chapter.xml
@@ -0,0 +1,630 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.85
+-->
+<appendix xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="bibliography">
+ <title>參考文獻</title>
+
+ <para>雖然線上說明(manual pages)有提供 &os; 各個特定部分明確的說明,
+ 但它們卻難免有「小學而大遺」之憾,像是如何讓整個系統運作順暢。 因此,
+ 身邊有 &unix; 系統管理的好書以及好的使用手冊是不可或缺的。</para>
+
+ <sect1 xml:id="bibliography-freebsd">
+ <title>FreeBSD 相關的書籍、雜誌</title>
+
+ <para><emphasis>非英語的書籍、雜誌:</emphasis></para>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="http://jdli.tw.FreeBSD.org/publication/book/freebsd2/index.htm">FreeBSD 入門與應用(光碟豪華版)</link> (繁體中文),
+ <link xlink:href="http://www.drmaster.com.tw/">博碩文化</link>
+ ,1997。 ISBN 9-578-39435-7</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD 技術內幕 (FreeBSD Unleashed 簡體中譯版),
+ <link xlink:href="http://www.hzbook.com/">機械工業出版社</link>
+ 。 ISBN 7-111-10201-0
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD 使用大全第一版 (簡體中文),
+ 機械工業出版社。 ISBN 7-111-07482-3
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD 使用大全第二版 (簡體中文),
+ 機械工業出版社。 ISBN 7-111-10286-X
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD Handbook 第二版 (簡體中譯版),
+ <link xlink:href="http://www.ptpress.com.cn/">人民郵電出版社</link>
+ 。 ISBN 7-115-10541-3
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD 3.x Internet 高級服務器的架設與管理 (簡體中文),
+ <link xlink:href="http://www.tup.tsinghua.edu.cn/">清華大學出版社</link>
+ 。 ISBN 7-900625-66-6</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD &amp; Windows 集成組網實務 (簡體中文),
+ <link xlink:href="http://www.tdpress.com/">中國鐵道出版社</link>
+ 。 ISBN 7-113-03845-X</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD 網站架設實務 (簡體中文),中國鐵道出版社
+ 。 ISBN 7-113-03423-3</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD for PC 98'ers (日文),SHUWA SystemCo, LTD
+ 。 ISBN 4-87966-468-5 C3055 定價 2900 日圓。</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD (日文),CUTT。 ISBN 4-906391-22-2
+ C3055 定價 2400 日圓。</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.shoeisha.com/book/Detail.asp?bid=650">Complete Introduction to FreeBSD</link> (日文),<link xlink:href="http://www.shoeisha.co.jp/">Shoeisha Co., Ltd</link>。 ISBN 4-88135-473-6 定價 3600 日圓。</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.ascii.co.jp/pb/book1/shinkan/detail/1322785.html">Personal UNIX Starter Kit FreeBSD</link> (日文), <link xlink:href="http://www.ascii.co.jp/">ASCII</link>。 ISBN 4-7561-1733-3 定價 3000 日圓。</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD Handbook (日文譯版), <link xlink:href="http://www.ascii.co.jp/">ASCII</link>。 ISBN 4-7561-1580-2
+ 定價 3800 日圓。</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD mit Methode (德文),<link xlink:href="http://www.cul.de">Computer und
+ Literatur Verlag</link>/Vertrieb Hanser,1998。 ISBN 3-932311-31-0</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.cul.de/freebsd.html">FreeBSD 4 - Installieren, Konfigurieren, Administrieren</link>
+ (德文),<link xlink:href="http://www.cul.de">Computer und Literatur Verlag</link>,2001。
+ ISBN 3-932311-88-4</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.cul.de/freebsd.html">FreeBSD 5 - Installieren, Konfigurieren, Administrieren</link>
+ (德文),<link xlink:href="http://www.cul.de">Computer und Literatur Verlag</link>,2003。
+ ISBN 3-936546-06-1</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.mitp.de/vmi/mitp/detail/pWert/1343/">
+ FreeBSD de Luxe</link> (德文),
+ <link xlink:href="http://www.mitp.de">Verlag Modere Industrie</link>,
+ 2003。 ISBN 3-8266-1343-0</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.pc.mycom.co.jp/FreeBSD/install-manual.html">FreeBSD
+ Install and Utilization Manual</link> (日文),<link xlink:href="http://www.pc.mycom.co.jp/">Mainichi Communications Inc.</link>
+ ,1998。 ISBN 4-8399-0112-0</para>
+ </listitem>
+
+ <listitem>
+ <para>Onno W Purbo, Dodi Maryanto, Syahrial Hubbany, Widjil Widodo
+ <emphasis><link xlink:href="http://maxwell.itb.ac.id/">
+ Building Internet Server with
+ FreeBSD</link></emphasis> (印尼文),<link xlink:href="http://www.elexmedia.co.id/">Elex Media Komputindo</link>。</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD 完全探索 (Absolute BSD: The Ultimate Guide to FreeBSD
+ 繁體中文譯版),<link xlink:href="http://www.grandtech.com.tw/">上奇</link>,2003。
+ ISBN 986-7944-92-5</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.twbsd.org/cht/book/">FreeBSD 6.0架設管理與應用</link>
+ (繁體中文),博碩,2006。ISBN 9-575-27878-X</para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para><emphasis>英文的書籍、雜誌:</emphasis></para>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="http://www.AbsoluteBSD.com/">Absolute
+ BSD: The Ultimate Guide to FreeBSD</link>,
+ <link xlink:href="http://www.nostarch.com/">No Starch Press</link>,2002。
+ ISBN: 1886411743</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.freebsdmall.com/cgi-bin/fm/bsdcomp">
+ The Complete FreeBSD</link>,
+ <link xlink:href="http://www.oreilly.com/">O'Reilly</link>,2003。
+ ISBN: 0596005164</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.freebsd-corp-net-guide.com/">The
+ FreeBSD Corporate Networker's Guide</link>,
+ <link xlink:href="http://www.awl.com/aw/">Addison-Wesley</link>,2000。
+ ISBN: 0201704811</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://andrsn.stanford.edu/FreeBSD/introbook/">
+ FreeBSD: An Open-Source Operating System for Your Personal
+ Computer</link>,The Bit Tree Press,2001。
+ ISBN: 0971204500</para>
+ </listitem>
+
+ <listitem>
+ <para>Teach Yourself FreeBSD in 24 Hours,
+ <link xlink:href="http://www.samspublishing.com/">Sams</link>,2002。
+ ISBN: 0672324245</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD 6 Unleashed,
+ <link xlink:href="http://www.samspublishing.com/">Sams</link>,2006。
+ ISBN: 0672328755</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD: The Complete Reference,
+ <link xlink:href="http://books.mcgraw-hill.com">McGrawHill</link>,2003。
+ ISBN: 0072224096 </para>
+ </listitem>
+
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="bibliography-userguides">
+ <title>使用說明手冊</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>Computer Systems Research Group, UC Berkeley. <emphasis>4.4BSD
+ User's Reference Manual</emphasis>. O'Reilly &amp; Associates,
+ Inc., 1994. ISBN 1-56592-075-9</para>
+ </listitem>
+
+ <listitem>
+ <para>Computer Systems Research Group, UC Berkeley. <emphasis>4.4BSD
+ User's Supplementary Documents</emphasis>. O'Reilly &amp;
+ Associates, Inc., 1994. ISBN 1-56592-076-7</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>UNIX in a Nutshell</emphasis>. O'Reilly &amp;
+ Associates, Inc., 1990. ISBN 093717520X</para>
+ </listitem>
+
+ <listitem>
+ <para>Mui, Linda. <emphasis>What You Need To Know When You Can't Find
+ Your UNIX System Administrator</emphasis>. O'Reilly &amp;
+ Associates, Inc., 1995. ISBN 1-56592-104-6</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.osu.edu/">Ohio State University</link>
+ 有撰寫 <link xlink:href="http://8help.osu.edu/wks/unix_course/index.html">UNIX
+ 介紹的課程</link>,並提供 HTML 或 PostScript 兩種格式供人瀏覽。
+ </para>
+
+ <para>UNIX 介紹的<link xlink:href="&url.doc.base;/it_IT.ISO8859-15/books/unix-introduction/index.html">義大利文翻譯版</link>
+ ,同時本文件也是 FreeBSD Italian Documentation Project 之一。</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.jp.FreeBSD.org/">Jpman Project, Japan
+ FreeBSD Users Group</link>. <link xlink:href="http://www.pc.mycom.co.jp/FreeBSD/urm.html">FreeBSD User's
+ Reference Manual</link> (日文翻譯)。 <link xlink:href="http://www.pc.mycom.co.jp/">Mainichi Communications
+ Inc.</link>, 1998. ISBN4-8399-0088-4 P3800E.</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.ed.ac.uk/">Edinburgh
+ University</link> 為 UNIX 新手所撰寫的 <link xlink:href="http://unixhelp.ed.ac.uk/">Online Guide</link> 指引說明。</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="bibliography-adminguides">
+ <title>系統管理指南</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>Albitz, Paul and Liu, Cricket. <emphasis>DNS and
+ BIND</emphasis>, 4th Ed. O'Reilly &amp; Associates, Inc., 2001.
+ ISBN 1-59600-158-4</para>
+ </listitem>
+
+ <listitem>
+ <para>Computer Systems Research Group, UC Berkeley. <emphasis>4.4BSD
+ System Manager's Manual</emphasis>. O'Reilly &amp; Associates,
+ Inc., 1994. ISBN 1-56592-080-5</para>
+ </listitem>
+
+ <listitem>
+ <para>Costales, Brian, et al. <emphasis>Sendmail</emphasis>, 2nd Ed.
+ O'Reilly &amp; Associates, Inc., 1997. ISBN 1-56592-222-0</para>
+ </listitem>
+
+ <listitem>
+ <para>Frisch, &AElig;leen. <emphasis>Essential System
+ Administration</emphasis>, 2nd Ed. O'Reilly &amp; Associates,
+ Inc., 1995. ISBN 1-56592-127-5</para>
+ </listitem>
+
+ <listitem>
+ <para>Hunt, Craig. <emphasis>TCP/IP Network
+ Administration</emphasis>, 2nd Ed. O'Reilly &amp; Associates, Inc.,
+ 1997. ISBN 1-56592-322-7</para>
+ </listitem>
+
+ <listitem>
+ <para>Nemeth, Evi. <emphasis>UNIX System Administration
+ Handbook</emphasis>. 3rd Ed. Prentice Hall, 2000. ISBN
+ 0-13-020601-6</para>
+ </listitem>
+
+ <listitem>
+ <para>Stern, Hal <emphasis>Managing NFS and NIS</emphasis> O'Reilly
+ &amp; Associates, Inc., 1991. ISBN 0-937175-75-7</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.jp.FreeBSD.org/">Jpman Project, Japan
+ FreeBSD Users Group</link>. <link xlink:href="http://www.pc.mycom.co.jp/FreeBSD/sam.html">FreeBSD System
+ Administrator's Manual</link> (日文翻譯)。 <link xlink:href="http://www.pc.mycom.co.jp/">Mainichi Communications
+ Inc.</link>, 1998. ISBN4-8399-0109-0 P3300E.</para>
+ </listitem>
+
+ <listitem>
+ <para>Dreyfus, Emmanuel. <link xlink:href="http://www.eyrolles.com/Informatique/Livre/9782212114638/">Cahiers
+ de l'Admin: BSD</link> 2nd Ed. (法文), Eyrolles, 2004.
+ ISBN 2-212-11463-X</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="bibliography-programmers">
+ <title>程式設計師指南</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>Asente, Paul, Converse, Diana, and Swick, Ralph.
+ <emphasis>X Window System Toolkit</emphasis>. Digital Press,
+ 1998. ISBN 1-55558-178-1</para>
+ </listitem>
+
+ <listitem>
+ <para>Computer Systems Research Group, UC Berkeley. <emphasis>4.4BSD
+ Programmer's Reference Manual</emphasis>. O'Reilly &amp;
+ Associates, Inc., 1994. ISBN 1-56592-078-3</para>
+ </listitem>
+
+ <listitem>
+ <para>Computer Systems Research Group, UC Berkeley. <emphasis>4.4BSD
+ Programmer's Supplementary Documents</emphasis>. O'Reilly &amp;
+ Associates, Inc., 1994. ISBN 1-56592-079-1</para>
+ </listitem>
+
+ <listitem>
+ <para>Harbison, Samuel P. and Steele, Guy L. Jr. <emphasis>C: A
+ Reference Manual</emphasis>. 4th ed. Prentice Hall, 1995.
+ ISBN 0-13-326224-3</para>
+ </listitem>
+
+ <listitem>
+ <para>Kernighan, Brian and Dennis M. Ritchie. <emphasis>The C
+ Programming Language</emphasis>. 2nd Ed. PTR Prentice Hall, 1988.
+ ISBN 0-13-110362-8</para>
+ </listitem>
+
+ <listitem>
+ <para>Lehey, Greg. <emphasis>Porting UNIX Software</emphasis>.
+ O'Reilly &amp; Associates, Inc., 1995. ISBN 1-56592-126-7</para>
+ </listitem>
+
+ <listitem>
+ <para>Plauger, P. J. <emphasis>The Standard C Library</emphasis>.
+ Prentice Hall, 1992. ISBN 0-13-131509-9</para>
+ </listitem>
+
+ <listitem>
+ <para>Spinellis, Diomidis. <link xlink:href="http://www.spinellis.gr/codereading/"><emphasis>Code
+ Reading: The Open Source Perspective</emphasis></link>.
+ Addison-Wesley, 2003. ISBN 0-201-79940-5</para>
+ </listitem>
+
+ <listitem>
+ <para>Spinellis, Diomidis. <link xlink:href="http://www.spinellis.gr/codequality/"><emphasis>Code
+ Quality: The Open Source Perspective</emphasis></link>.
+ Addison-Wesley, 2006. ISBN 0-321-16607-8</para>
+ </listitem>
+
+ <listitem>
+ <para>Stevens, W. Richard and Stephen A. Rago.
+ <emphasis>Advanced Programming in the UNIX
+ Environment</emphasis>. 2nd Ed.
+ Reading, Mass. : Addison-Wesley, 2005.
+ ISBN 0-201-43307-9</para>
+ </listitem>
+
+ <listitem>
+ <para>Stevens, W. Richard. <emphasis>UNIX Network
+ Programming</emphasis>. 2nd Ed, PTR Prentice Hall, 1998. ISBN
+ 0-13-490012-X</para>
+ </listitem>
+
+ <listitem>
+ <para>Wells, Bill. <quote>Writing Serial Drivers for UNIX</quote>.
+ <emphasis>Dr. Dobb's Journal</emphasis>. 19(15), December 1994.
+ pp68-71, 97-99.</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="bibliography-osinternals">
+ <title>深入作業系統</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>Andleigh, Prabhat K. <emphasis>UNIX System
+ Architecture</emphasis>. Prentice-Hall, Inc., 1990. ISBN
+ 0-13-949843-5</para>
+ </listitem>
+
+ <listitem>
+ <para>Jolitz, William. <quote>Porting UNIX to the 386</quote>.
+ <emphasis>Dr. Dobb's Journal</emphasis>. January 1991-July
+ 1992.</para>
+ </listitem>
+
+ <listitem>
+ <para>Leffler, Samuel J., Marshall Kirk McKusick, Michael J Karels and
+ John Quarterman <emphasis>The Design and Implementation of the
+ 4.3BSD UNIX Operating System</emphasis>. Reading, Mass. :
+ Addison-Wesley, 1989. ISBN 0-201-06196-1</para>
+ </listitem>
+
+ <listitem>
+ <para>Leffler, Samuel J., Marshall Kirk McKusick, <emphasis>The Design
+ and Implementation of the 4.3BSD UNIX Operating System: Answer
+ Book</emphasis>. Reading, Mass. : Addison-Wesley, 1991. ISBN
+ 0-201-54629-9</para>
+ </listitem>
+
+ <listitem>
+ <para>McKusick, Marshall Kirk, Keith Bostic, Michael J Karels, and
+ John Quarterman. <emphasis>The Design and Implementation of the
+ 4.4BSD Operating System</emphasis>. Reading, Mass. :
+ Addison-Wesley, 1996. ISBN 0-201-54979-4</para>
+
+ <para>(本書第二章的 <link xlink:href="&url.books.design-44bsd;/book.html">網路版</link> 是
+ FreeBSD 文件計劃的一部份,以及第九章的部分可以在 <link xlink:href="http://www.netapp.com/tech_library/nfsbook.html">
+ 這邊</link>找到)</para>
+ </listitem>
+
+ <listitem>
+ <para>Marshall Kirk McKusick, George V. Neville-Neil <emphasis>The
+ Design and Implementation of the FreeBSD Operating System</emphasis>.
+ Boston, Mass. : Addison-Wesley, 2004. ISBN 0-201-70245-2</para>
+ </listitem>
+
+ <listitem>
+ <para>Stevens, W. Richard. <emphasis>TCP/IP Illustrated, Volume 1:
+ The Protocols</emphasis>. Reading, Mass. : Addison-Wesley,
+ 1996. ISBN 0-201-63346-9</para>
+ </listitem>
+
+ <listitem>
+ <para>Schimmel, Curt. <emphasis>Unix Systems for Modern
+ Architectures</emphasis>. Reading, Mass. : Addison-Wesley, 1994.
+ ISBN 0-201-63338-8</para>
+ </listitem>
+
+ <listitem>
+ <para>Stevens, W. Richard. <emphasis>TCP/IP Illustrated, Volume 3:
+ TCP for Transactions, HTTP, NNTP and the UNIX Domain
+ Protocols</emphasis>. Reading, Mass. : Addison-Wesley, 1996.
+ ISBN 0-201-63495-3</para>
+ </listitem>
+
+ <listitem>
+ <para>Vahalia, Uresh. <emphasis>UNIX Internals -- The New
+ Frontiers</emphasis>. Prentice Hall, 1996. ISBN
+ 0-13-101908-2</para>
+ </listitem>
+
+ <listitem>
+ <para>Wright, Gary R. and W. Richard Stevens. <emphasis>TCP/IP
+ Illustrated, Volume 2: The Implementation</emphasis>. Reading,
+ Mass. : Addison-Wesley, 1995. ISBN 0-201-63354-X</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="bibliography-security">
+ <title>資安領域的參考文獻</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>Cheswick, William R. and Steven M. Bellovin. <emphasis>Firewalls
+ and Internet Security: Repelling the Wily Hacker</emphasis>.
+ Reading, Mass. : Addison-Wesley, 1995. ISBN
+ 0-201-63357-4</para>
+ </listitem>
+
+ <listitem>
+ <para>Garfinkel, Simson and Gene Spafford.
+ <emphasis>Practical UNIX &amp; Internet Security</emphasis>.
+ 2nd Ed. O'Reilly &amp; Associates, Inc., 1996. ISBN
+ 1-56592-148-8</para>
+ </listitem>
+
+ <listitem>
+ <para>Garfinkel, Simson. <emphasis>PGP Pretty Good
+ Privacy</emphasis> O'Reilly &amp; Associates, Inc., 1995. ISBN
+ 1-56592-098-8</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="bibliography-hardware">
+ <title>硬體方面的參考文獻</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>Anderson, Don and Tom Shanley. <emphasis>Pentium Processor
+ System Architecture</emphasis>. 2nd Ed. Reading, Mass. :
+ Addison-Wesley, 1995. ISBN 0-201-40992-5</para>
+ </listitem>
+
+ <listitem>
+ <para>Ferraro, Richard F. <emphasis>Programmer's Guide to the EGA,
+ VGA, and Super VGA Cards</emphasis>. 3rd ed. Reading, Mass. :
+ Addison-Wesley, 1995. ISBN 0-201-62490-7</para>
+ </listitem>
+
+ <listitem>
+ <para>Intel Corporation 通常會以 PDF 格式在 <link xlink:href="http://developer.intel.com/">developer web site</link>
+ 網站放他們的 CPU、晶片組、相關標準的規格書文件。</para>
+ </listitem>
+
+ <listitem>
+ <para>Shanley, Tom. <emphasis>80486 System Architecture</emphasis>.
+ 3rd ed. Reading, Mass. : Addison-Wesley, 1995. ISBN
+ 0-201-40994-1</para>
+ </listitem>
+
+ <listitem>
+ <para>Shanley, Tom. <emphasis>ISA System Architecture</emphasis>.
+ 3rd ed. Reading, Mass. : Addison-Wesley, 1995. ISBN
+ 0-201-40996-8</para>
+ </listitem>
+
+ <listitem>
+ <para>Shanley, Tom. <emphasis>PCI System Architecture</emphasis>.
+ 4th ed. Reading, Mass. : Addison-Wesley, 1999. ISBN
+ 0-201-30974-2</para>
+ </listitem>
+
+ <listitem>
+ <para>Van Gilluwe, Frank. <emphasis>The Undocumented PC</emphasis>,
+ 2nd Ed. Reading, Mass: Addison-Wesley Pub. Co., 1996. ISBN
+ 0-201-47950-8</para>
+ </listitem>
+
+ <listitem>
+ <para>Messmer, Hans-Peter. <emphasis>The Indispensable PC Hardware
+ Book</emphasis>, 4th Ed.
+ Reading, Mass: Addison-Wesley Pub. Co., 2002. ISBN
+ 0-201-59616-4</para>
+ </listitem>
+
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="bibliography-history">
+ <title>&unix; 歷史淵源</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>Lion, John <emphasis>Lion's Commentary on UNIX, 6th Ed. With
+ Source Code</emphasis>. ITP Media Group, 1996. ISBN
+ 1573980137</para>
+ </listitem>
+
+ <listitem>
+ <para>Raymond, Eric S. <emphasis>The New Hacker's Dictionary, 3rd
+ edition</emphasis>. MIT Press, 1996. ISBN
+ 0-262-68092-0. Also known as the <link xlink:href="http://www.catb.org/~esr/jargon/html/index.html">Jargon
+ File</link></para>
+ </listitem>
+
+ <listitem>
+ <para>Salus, Peter H. <emphasis>A quarter century of UNIX</emphasis>.
+ Addison-Wesley Publishing Company, Inc., 1994. ISBN
+ 0-201-54777-5</para>
+ </listitem>
+
+ <listitem>
+ <para>Simon Garfinkel, Daniel Weise, Steven Strassmann. <emphasis>The
+ UNIX-HATERS Handbook</emphasis>. IDG Books Worldwide, Inc.,
+ 1994. ISBN 1-56884-203-1. Out of print, but available <link xlink:href="http://research.microsoft.com/~daniel/unix-haters.html">
+ online</link>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Don Libes, Sandy Ressler <emphasis>Life with UNIX</emphasis>
+ &mdash; special edition. Prentice-Hall, Inc., 1989. ISBN
+ 0-13-536657-7</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>BSD 族譜</emphasis>:
+ <uri xlink:href="http://www.FreeBSD.org/cgi/cvsweb.cgi/src/share/misc/bsd-family-tree">http://www.FreeBSD.org/cgi/cvsweb.cgi/src/share/misc/bsd-family-tree</uri>
+ 或 FreeBSD 機器內的 <link xlink:href="file://localhost/usr/share/misc/bsd-family-tree"><filename>/usr/share/misc/bsd-family-tree</filename></link>
+ 。</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>The BSD Release Announcements collection</emphasis>.
+ 1997. <uri xlink:href="http://www.de.FreeBSD.org/de/ftp/releases/">http://www.de.FreeBSD.org/de/ftp/releases/</uri></para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Networked Computer Science Technical Reports
+ Library</emphasis>. <uri xlink:href="http://www.ncstrl.org/">http://www.ncstrl.org/</uri></para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Old BSD releases from the Computer Systems Research
+ group (CSRG)</emphasis>.
+ <uri xlink:href="http://www.mckusick.com/csrg/">http://www.mckusick.com/csrg/</uri>:
+ The 4CD set covers all BSD versions from 1BSD to 4.4BSD and
+ 4.4BSD-Lite2 (but not 2.11BSD, unfortunately). The last
+ disk also holds the final sources plus the SCCS files.</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="bibliography-journals">
+ <title>雜誌、期刊</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>The C/C++ Users Journal</emphasis>. R&amp;D
+ Publications Inc. ISSN 1075-2838</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Sys Admin &mdash; The Journal for UNIX System
+ Administrators</emphasis> Miller Freeman, Inc., ISSN
+ 1061-2688</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>freeX &mdash; Das Magazin f&uuml;r Linux - BSD - UNIX</emphasis>
+ (德文) Computer- und Literaturverlag GmbH, ISSN 1436-7033</para>
+ </listitem>
+
+ </itemizedlist>
+ </sect1>
+</appendix>
diff --git a/zh_TW.UTF-8/books/handbook/book.xml b/zh_TW.UTF-8/books/handbook/book.xml
new file mode 100644
index 0000000000..b6fa191bcf
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/book.xml
@@ -0,0 +1,274 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
+ "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd" [
+<!ENTITY % chapters SYSTEM "chapters.ent">
+%chapters;
+<!ENTITY % txtfiles SYSTEM "txtfiles.ent">
+%txtfiles;
+]>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.163
+-->
+<book xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="zh_TW">
+ <info><title>FreeBSD 使用手冊</title>
+
+
+ <author><orgname>FreeBSD 文件計畫</orgname></author>
+
+ <pubdate>February 1999</pubdate>
+
+ <releaseinfo>$FreeBSD$</releaseinfo>
+
+ <copyright>
+ <year>1995</year>
+ <year>1996</year>
+ <year>1997</year>
+ <year>1998</year>
+ <year>1999</year>
+ <year>2000</year>
+ <year>2001</year>
+ <year>2002</year>
+ <year>2003</year>
+ <year>2004</year>
+ <year>2005</year>
+ <year>2006</year>
+ <year>2007</year>
+ <year>2008</year>
+ <holder>FreeBSD 文件計畫</holder>
+ </copyright>
+
+ &legalnotice;
+
+ <legalnotice xml:id="trademarks" role="trademarks">
+ &tm-attrib.freebsd;
+ &tm-attrib.3com;
+ &tm-attrib.3ware;
+ &tm-attrib.arm;
+ &tm-attrib.adaptec;
+ &tm-attrib.adobe;
+ &tm-attrib.apple;
+ &tm-attrib.corel;
+ &tm-attrib.creative;
+ &tm-attrib.cvsup;
+ &tm-attrib.heidelberger;
+ &tm-attrib.ibm;
+ &tm-attrib.ieee;
+ &tm-attrib.intel;
+ &tm-attrib.intuit;
+ &tm-attrib.linux;
+ &tm-attrib.lsilogic;
+ &tm-attrib.m-systems;
+ &tm-attrib.macromedia;
+ &tm-attrib.microsoft;
+ &tm-attrib.netscape;
+ &tm-attrib.nexthop;
+ &tm-attrib.opengroup;
+ &tm-attrib.oracle;
+ &tm-attrib.powerquest;
+ &tm-attrib.realnetworks;
+ &tm-attrib.redhat;
+ &tm-attrib.sap;
+ &tm-attrib.sun;
+ &tm-attrib.symantec;
+ &tm-attrib.themathworks;
+ &tm-attrib.thomson;
+ &tm-attrib.usrobotics;
+ &tm-attrib.vmware;
+ &tm-attrib.waterloomaple;
+ &tm-attrib.wolframresearch;
+ &tm-attrib.xfree86;
+ &tm-attrib.xiph;
+ &tm-attrib.general;
+ </legalnotice>
+
+ <abstract>
+ <para>歡迎使用FreeBSD! 本使用手冊涵蓋範圍包括了
+ <emphasis>FreeBSD &rel2.current;-RELEASE</emphasis> 和
+ <emphasis>FreeBSD &rel.current;-RELEASE</emphasis> 的安裝和日常使用。
+ 這份使用手冊是很多人的集體創作,而且仍然『持續不斷』的進行中。
+ 許多章節仍未完成,已完成的部份也有些需要更新。
+ 如果您有興趣協助本計畫的話,請寄 e-mail 到 &a.doc;。
+ 在 <link xlink:href="http://www.FreeBSD.org/">FreeBSD 網站</link>
+ 可以找到這份文件的最新版本(舊版文件可從 <uri xlink:href="http://docs.FreeBSD.org/doc/">http://docs.FreeBSD.org/doc/</uri> 取得),也可以從 <link xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/">FreeBSD FTP 伺服器</link>
+ 或是眾多 <link linkend="mirrors-ftp">mirror 站臺</link>
+ 下載不同格式的資料。
+ 如果比較偏好實體書面資料,那可以在
+ <link xlink:href="http://www.freebsdmall.com/">FreeBSD Mall</link> 購買。
+ 此外,也可以在 <link xlink:href="&url.base;/search/index.html">使用手冊</link>
+ 中搜尋資料。
+ </para>
+ </abstract>
+ </info>
+
+ &chap.preface;
+
+ <part xml:id="getting-started">
+ <title>開始使用 FreeBSD </title>
+
+ <partintro>
+ <para>這部份是提供給初次使用 FreeBSD 的使用者和系統管理者。
+ 這些章節包括:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>介紹 FreeBSD 給您。 </para>
+ </listitem>
+
+ <listitem>
+ <para>在安裝過程給您指引。 </para>
+ </listitem>
+
+ <listitem>
+ <para>教您 &unix; 的基礎及原理。 </para>
+ </listitem>
+
+ <listitem>
+ <para>展示給您看如何安裝豐富的 FreeBSD 的應用軟體</para>
+ </listitem>
+
+ <listitem>
+ <para>向您介紹 X, &unix; 的視窗系統以及詳細的桌面環境設定,讓您更有生產力。
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>我們試著儘可能的讓這段文字的參考連結數目降到最低,讓您在讀使用手冊的這部份時可以不太需要常常前後翻頁。
+ </para>
+ </partintro>
+
+ &chap.introduction;
+ &chap.install;
+ &chap.basics;
+ &chap.ports;
+ &chap.x11;
+ </part>
+
+ <part xml:id="common-tasks">
+ <title>一般性工作</title>
+
+ <partintro>
+ <para>既然基礎的部分已經提過了,接下來的這個部分將會討論一些常會用到的 FreeBSD
+ 的特色,這些章節包括:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>介紹給您常見且實用的桌面應用軟體:網頁瀏覽器、生產力工具、文件檢視程式等。</para>
+ </listitem>
+
+ <listitem>
+ <para>介紹給您眾多 FreeBSD 上可用的多媒體工具。</para>
+ </listitem>
+
+ <listitem>
+ <para>解釋如何編譯自訂 FreeBSD 核心以增加額外系統功能的流程。</para>
+ </listitem>
+
+ <listitem>
+ <para>詳細描述列印系統,包含桌上型印表機及網路印表機的設定。</para>
+ </listitem>
+
+ <listitem>
+ <para>展示給您看如何在您的 FreeBSD 系統中執行 Linux 應用軟體。</para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>這些章節中有些需要您預先閱讀些相關文件,在各章節開頭的概要內會提及。</para>
+
+ </partintro>
+
+ &chap.desktop;
+ &chap.multimedia;
+ &chap.kernelconfig;
+ &chap.printing;
+ &chap.linuxemu;
+ </part>
+
+ <part xml:id="system-administration">
+ <title>系統管理</title>
+
+ <partintro>
+ <para>FreeBSD 使用手冊剩下的這些章節涵蓋了全方位的 FreeBSD 系統管理。
+ 每個章節的開頭會先描述在該您讀完該章節後您會學到什麼,也會詳述在您在看這些資料時應該要有的一些背景知識。
+ </para>
+
+ <para>這些章節是讓您在需要查資料的時候翻閱用的。
+ 您不需要依照特定的順序來讀,也不需要將這些章節全部過讀之後才開始用 FreeBSD。
+ </para>
+ </partintro>
+
+ &chap.config;
+ &chap.boot;
+ &chap.users;
+ &chap.security;
+ &chap.jails;
+ &chap.mac;
+ &chap.audit;
+ &chap.disks;
+ &chap.geom;
+ &chap.vinum;
+ &chap.virtualization;
+ &chap.l10n;
+ &chap.cutting-edge;
+ </part>
+
+ <part xml:id="network-communication">
+ <title>網路通訊</title>
+
+ <partintro>
+ <para>FreeBSD 是一種廣泛的被使用在高效能的網路伺服器中的作業系統,這些章節包含了:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>序列埠通訊</para>
+ </listitem>
+
+ <listitem>
+ <para>PPP 和 PPPoE</para>
+ </listitem>
+
+ <listitem>
+ <para>電子郵件</para>
+ </listitem>
+
+ <listitem>
+ <para>執行網路伺服程式</para>
+ </listitem>
+
+ <listitem>
+ <para>防火牆</para>
+ </listitem>
+
+ <listitem>
+ <para>其他的進階網路主題</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>這些章節是讓您在需要查資料的時候翻閱用的。
+ 您不需要依照特定的順序來讀,也不需要將這些章節全部讀過之後才將 FreeBSD 用在網路環境下。</para>
+ </partintro>
+
+ &chap.serialcomms;
+ &chap.ppp-and-slip;
+ &chap.mail;
+ &chap.network-servers;
+ &chap.firewalls;
+ &chap.advanced-networking;
+
+ </part>
+
+ <part xml:id="appendices">
+ <title>附錄</title>
+
+ &chap.mirrors;
+ &chap.bibliography;
+ &chap.eresources;
+ &chap.pgpkeys;
+ </part>
+ &chap.freebsd-glossary;
+ &chap.index;
+ &chap.colophon;
+</book>
diff --git a/zh_TW.UTF-8/books/handbook/boot/Makefile b/zh_TW.UTF-8/books/handbook/boot/Makefile
new file mode 100644
index 0000000000..c405bb50c6
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/boot/Makefile
@@ -0,0 +1,16 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+# Original revision: 1.1
+#
+
+CHAPTERS= boot/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/boot/chapter.xml b/zh_TW.UTF-8/books/handbook/boot/chapter.xml
new file mode 100644
index 0000000000..ae4ce38477
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/boot/chapter.xml
@@ -0,0 +1,802 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.62
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="boot">
+ <title>FreeBSD 開機流程篇</title>
+
+ <sect1 xml:id="boot-synopsis">
+ <title>概述</title>
+ <indexterm><primary>booting</primary></indexterm>
+ <indexterm><primary>bootstrap</primary></indexterm>
+
+ <para>The process of starting a computer and loading the operating system
+ is referred to as <quote>the bootstrap process</quote>, or simply
+ <quote>booting</quote>. FreeBSD's boot process provides a great deal of
+ flexibility in customizing what happens when you start the system,
+ allowing you to select from different operating systems installed on the
+ same computer, or even different versions of the same operating system
+ or installed kernel.</para>
+
+ <para>This chapter details the configuration options you can set and how
+ to customize the FreeBSD boot process. This includes everything that
+ happens until the FreeBSD kernel has started, probed for devices, and
+ started &man.init.8;. If you are not quite sure when this happens, it
+ occurs when the text color changes from bright white to grey.</para>
+
+ <para>讀完這章,您將了解:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>What the components of the FreeBSD bootstrap system are, and how
+ they interact.</para>
+ </listitem>
+
+ <listitem>
+ <para>The options you can give to the components in the FreeBSD
+ bootstrap to control the boot process.</para>
+ </listitem>
+
+ <listitem>
+ <para>&man.device.hints.5; 的基本概念。</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <title>x86 Only</title>
+
+ <para>This chapter only describes the boot process for FreeBSD running
+ on Intel x86 systems.</para>
+ </note>
+ </sect1>
+
+ <sect1 xml:id="boot-introduction">
+ <title>Booting 問題</title>
+
+ <para>Turning on a computer and starting the operating system poses an
+ interesting dilemma. By definition, the computer does not know how to
+ do anything until the operating system is started. This includes
+ running programs from the disk. So if the computer can not run a
+ program from the disk without the operating system, and the operating
+ system programs are on the disk, how is the operating system
+ started?</para>
+
+ <para>This problem parallels one in the book <citetitle>The Adventures of
+ Baron Munchausen</citetitle>. A character had fallen part way down a
+ manhole, and pulled himself out by grabbing his bootstraps, and
+ lifting. In the early days of computing the term
+ <firstterm>bootstrap</firstterm> was applied to the mechanism used to
+ load the operating system, which has become shortened to
+ <quote>booting</quote>.</para>
+
+ <indexterm><primary>BIOS</primary></indexterm>
+
+ <indexterm><primary>Basic Input/Output System</primary><see>BIOS</see></indexterm>
+
+ <para>On x86 hardware the Basic Input/Output System (BIOS) is responsible
+ for loading the operating system. To do this, the BIOS looks on the
+ hard disk for the Master Boot Record (MBR), which must be located on a
+ specific place on the disk. The BIOS has enough knowledge to load and
+ run the MBR, and assumes that the MBR can then carry out the rest of the
+ tasks involved in loading the operating system,
+ possibly with the help of the BIOS.</para>
+
+ <indexterm><primary>Master Boot Record (MBR)</primary></indexterm>
+
+ <indexterm><primary>Boot Manager</primary></indexterm>
+
+ <indexterm><primary>Boot Loader</primary></indexterm>
+
+ <para>The code within the MBR is usually referred to as a <emphasis>boot
+ manager</emphasis>, especially when it interacts with the user. In this case
+ the boot manager usually has more code in the first
+ <emphasis>track</emphasis> of the disk or within some OS's file system. (A
+ boot manager is sometimes also called a <emphasis>boot loader</emphasis>,
+ but FreeBSD uses that term for a later stage of booting.) Popular boot
+ managers include <application>boot0</application> (a.k.a. <application>Boot
+ Easy</application>, the standard &os; boot manager),
+ <application>Grub</application>, <application>GAG</application>, and
+ <application>LILO</application>.
+ (Only <application>boot0</application> fits within the MBR.)</para>
+
+ <para>If you have only one operating system installed on your disks then
+ a standard PC MBR will suffice. This MBR searches for the first bootable
+ (a.k.a. active) slice on the disk, and then runs the code on that slice to
+ load the remainder of the operating system. The MBR installed by
+ &man.fdisk.8;, by default, is such an MBR. It is based on
+ <filename>/boot/mbr</filename>.</para>
+
+ <para>If you have installed multiple operating systems on your disks then
+ you can install a different boot manager, one that can display a list of
+ different operating systems, and allows you to choose the one to boot
+ from. Two of these are discussed in the next subsection.</para>
+
+ <para>The remainder of the FreeBSD bootstrap system is divided into three
+ stages. The first stage is run by the MBR, which knows just enough to
+ get the computer into a specific state and run the second stage. The
+ second stage can do a little bit more, before running the third stage.
+ The third stage finishes the task of loading the operating system. The
+ work is split into these three stages because the PC standards put
+ limits on the size of the programs that can be run at stages one and
+ two. Chaining the tasks together allows FreeBSD to provide a more
+ flexible loader.</para>
+
+ <indexterm><primary>kernel</primary></indexterm>
+ <indexterm><primary><command>init</command></primary></indexterm>
+
+ <para>The kernel is then started and it begins to probe for devices
+ and initialize them for use. Once the kernel boot
+ process is finished, the kernel passes control to the user process
+ &man.init.8;, which then makes sure the disks are in a usable state.
+ &man.init.8; then starts the user-level resource configuration which
+ mounts file systems, sets up network cards to communicate on the
+ network, and generally starts all the processes that usually
+ are run on a FreeBSD system at startup.</para>
+ </sect1>
+
+ <sect1 xml:id="boot-blocks">
+ <title>The Boot Manager and Boot Stages</title>
+
+ <indexterm><primary>Boot Manager</primary></indexterm>
+
+ <sect2 xml:id="boot-boot0">
+ <title>The Boot Manager</title>
+ <indexterm><primary>Master Boot Record (MBR)</primary></indexterm>
+
+ <para>The code in the MBR or boot manager is sometimes referred to as
+ <emphasis>stage zero</emphasis> of the boot process. This subsection
+ discusses two of the boot managers previously mentioned:
+ <application>boot0</application> and <application>LILO</application>.</para>
+
+ <formalpara><title>The <application>boot0</application> Boot Manager:</title>
+ <para>The MBR installed by FreeBSD's installer or &man.boot0cfg.8;, by
+ default, is based on <filename>/boot/boot0</filename>.
+ (The <application>boot0</application> program is very simple, since the
+ program in the <abbrev>MBR</abbrev> can only be 446 bytes long because of the slice
+ table and 0x55AA identifier at the end of the MBR.)
+ If you have installed <application>boot0</application> and
+ multiple operating systems on your hard disks, then you will see a
+ display similar to this one at boot time:</para></formalpara>
+
+ <example xml:id="boot-boot0-example">
+ <title><filename>boot0</filename> Screenshot</title>
+
+ <screen>F1 DOS
+F2 FreeBSD
+F3 Linux
+F4 ??
+F5 Drive 1
+
+Default: F2</screen>
+ </example>
+
+ <para>Other operating systems, in particular &windows;, have been known
+ to overwrite an existing MBR with their own. If this happens to you,
+ or you want to replace your existing MBR with the FreeBSD MBR then use
+ the following command:</para>
+
+ <screen>&prompt.root; <userinput>fdisk -B -b /boot/boot0 device</userinput></screen>
+
+ <para>where <replaceable>device</replaceable> is the device that you
+ boot from, such as <filename>ad0</filename> for the first IDE
+ disk, <filename>ad2</filename> for the first IDE disk on a second
+ IDE controller, <filename>da0</filename> for the first SCSI disk,
+ and so on. Or, if you want a custom configuration of the MBR,
+ use &man.boot0cfg.8;.</para>
+
+ <formalpara><title>The LILO Boot Manager:</title>
+
+ <para>To install this boot manager so it will also boot FreeBSD, first
+ start Linux and add the following to your existing
+ <filename>/etc/lilo.conf</filename> configuration file:</para></formalpara>
+
+ <programlisting>other=/dev/hdXY
+table=/dev/hdX
+loader=/boot/chain.b
+label=FreeBSD</programlisting>
+
+ <para>In the above, specify FreeBSD's primary partition and drive using
+ Linux specifiers, replacing <replaceable>X</replaceable> with the Linux
+ drive letter and <replaceable>Y</replaceable> with the Linux primary
+ partition number. If you are using a <acronym>SCSI</acronym> drive, you
+ will need to change <replaceable>/dev/hd</replaceable> to read something
+ similar to <replaceable>/dev/sd</replaceable>. The
+ <option>loader=/boot/chain.b</option> line can be omitted if you have
+ both operating systems on the same drive. Now run
+ <command>/sbin/lilo&nbsp;-v</command> to commit your new changes to the
+ system; this should be verified by checking its screen messages.</para>
+ </sect2>
+
+ <sect2 xml:id="boot-boot1">
+ <title>Stage One, <filename>/boot/boot1</filename>, and Stage Two,
+ <filename>/boot/boot2</filename></title>
+
+ <para>Conceptually the first and second stages are part of the same
+ program, on the same area of the disk. Because of space constraints
+ they have been split into two, but you would always install them
+ together. They are copied from the combined file
+ <filename>/boot/boot</filename> by the installer or
+ <application>disklabel</application> (see below).</para>
+
+ <para>They are located outside file systems, in the first track of
+ the boot slice, starting with the first sector. This is where <link linkend="boot-boot0">boot0</link>, or any other boot manager,
+ expects to find a program to run which will
+ continue the boot process. The number of sectors used is easily
+ determined from the size of <filename>/boot/boot</filename>.</para>
+
+ <para><filename>boot1</filename> is very simple, since it
+ can only be 512 bytes
+ in size, and knows just enough about the FreeBSD
+ <firstterm>disklabel</firstterm>, which stores information
+ about the slice, to find and execute <filename>boot2</filename>.</para>
+
+ <para><filename>boot2</filename> is slightly more sophisticated, and understands
+ the FreeBSD file system enough to find files on it, and can
+ provide a simple interface to choose the kernel or loader to
+ run.</para>
+
+ <para>Since the <link linkend="boot-loader">loader</link> is
+ much more sophisticated, and provides a nice easy-to-use
+ boot configuration, <filename>boot2</filename> usually runs
+ it, but previously it
+ was tasked to run the kernel directly.</para>
+
+ <example xml:id="boot-boot2-example">
+ <title><filename>boot2</filename> Screenshot</title>
+
+ <screen>&gt;&gt; FreeBSD/i386 BOOT
+Default: 0:ad(0,a)/kernel
+boot:</screen>
+ </example>
+
+ <para>If you ever need to replace the installed
+ <filename>boot1</filename> and <filename>boot2</filename> use
+ &man.disklabel.8;:</para>
+
+ <screen>&prompt.root; <userinput>disklabel -B diskslice</userinput></screen>
+
+ <para>where <replaceable>diskslice</replaceable> is the disk and slice
+ you boot from, such as <filename>ad0s1</filename> for the first
+ slice on the first IDE disk.</para>
+
+ <warning>
+ <title>Dangerously Dedicated Mode</title>
+
+ <para>If you use just the disk name, such as
+ <filename>ad0</filename>, in the &man.disklabel.8; command you
+ will create a dangerously dedicated disk, without slices. This is
+ almost certainly not what you want to do, so make sure you double
+ check the &man.disklabel.8; command before you press
+ <keycap>Return</keycap>.</para>
+ </warning>
+ </sect2>
+
+ <sect2 xml:id="boot-loader">
+ <title>Stage Three, <filename>/boot/loader</filename></title>
+
+ <indexterm><primary>boot-loader</primary></indexterm>
+ <para>The loader is the final stage of the three-stage
+ bootstrap, and is located on the file system, usually as
+ <filename>/boot/loader</filename>.</para>
+
+ <para>The loader is intended as a user-friendly method for
+ configuration, using an easy-to-use built-in command set,
+ backed up by a more powerful interpreter, with a more complex
+ command set.</para>
+
+ <sect3 xml:id="boot-loader-flow">
+ <title>Loader Program Flow</title>
+
+ <para>During initialization, the loader will probe for a
+ console and for disks, and figure out what disk it is
+ booting from. It will set variables accordingly, and an
+ interpreter is started where user commands can be passed from
+ a script or interactively.</para>
+ <indexterm><primary>loader</primary></indexterm>
+ <indexterm><primary>loader configuration</primary></indexterm>
+
+ <para>The loader will then read
+ <filename>/boot/loader.rc</filename>, which by default reads
+ in <filename>/boot/defaults/loader.conf</filename> which
+ sets reasonable defaults for variables and reads
+ <filename>/boot/loader.conf</filename> for local changes to
+ those variables. <filename>loader.rc</filename> then acts
+ on these variables, loading whichever modules and kernel are
+ selected.</para>
+
+ <para>Finally, by default, the loader issues a 10 second wait
+ for key presses, and boots the kernel if it is not interrupted.
+ If interrupted, the user is presented with a prompt which
+ understands the easy-to-use command set, where the user may
+ adjust variables, unload all modules, load modules, and then
+ finally boot or reboot.</para>
+
+ </sect3>
+
+ <sect3 xml:id="boot-loader-commands">
+ <title>Loader Built-In Commands</title>
+
+ <para>These are the most commonly used loader commands. For a
+ complete discussion of all available commands, please see
+ &man.loader.8;.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>autoboot <replaceable>seconds</replaceable></term>
+
+ <listitem>
+ <para>Proceeds to boot the kernel if not interrupted
+ within the time span given, in seconds. It displays a
+ countdown, and the default time span is 10
+ seconds.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>boot
+ <optional>-options</optional>
+ <optional>kernelname</optional></term>
+
+ <listitem>
+ <para>Immediately proceeds to boot the kernel, with the
+ given options, if any, and with the kernel name given,
+ if it is.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>boot-conf</term>
+
+ <listitem>
+ <para>Goes through the same automatic configuration of
+ modules based on variables as what happens at boot.
+ This only makes sense if you use
+ <command>unload</command> first, and change some
+ variables, most commonly <envar>kernel</envar>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>help
+ <optional>topic</optional></term>
+
+ <listitem>
+ <para>Shows help messages read from
+ <filename>/boot/loader.help</filename>. If the topic
+ given is <literal>index</literal>, then the list of
+ available topics is given.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>include <replaceable>filename</replaceable>
+ &hellip;</term>
+
+ <listitem>
+ <para>Processes the file with the given filename. The
+ file is read in, and interpreted line by line. An
+ error immediately stops the include command.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>load <optional>-t
+ type</optional>
+ <replaceable>filename</replaceable></term>
+
+ <listitem>
+ <para>Loads the kernel, kernel module, or file of the
+ type given, with the filename given. Any arguments
+ after filename are passed to the file.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>ls <optional>-l</optional>
+ <optional>path</optional></term>
+
+ <listitem>
+ <para>Displays a listing of files in the given path, or
+ the root directory, if the path is not specified. If
+ <option>-l</option> is specified, file sizes will be
+ shown too.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>lsdev <optional>-v</optional></term>
+
+ <listitem>
+ <para>Lists all of the devices from which it may be
+ possible to load modules. If <option>-v</option> is
+ specified, more details are printed.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>lsmod <optional>-v</optional></term>
+
+ <listitem>
+ <para>Displays loaded modules. If <option>-v</option> is
+ specified, more details are shown.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>more <replaceable>filename</replaceable></term>
+
+ <listitem>
+ <para>Displays the files specified, with a pause at each
+ <varname>LINES</varname> displayed.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>reboot</term>
+
+ <listitem>
+ <para>Immediately reboots the system.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>set <replaceable>variable</replaceable></term>
+ <term>set
+ <replaceable>variable</replaceable>=<replaceable>value</replaceable></term>
+
+ <listitem>
+ <para>Sets the loader's environment variables.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>unload</term>
+
+ <listitem>
+ <para>Removes all loaded modules.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 xml:id="boot-loader-examples">
+ <title>Loader Examples</title>
+
+ <para>Here are some practical examples of loader usage:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>To simply boot your usual kernel, but in single-user
+ mode:<indexterm><primary>single-user mode</primary></indexterm></para>
+
+ <screen><userinput>boot -s</userinput></screen>
+ </listitem>
+
+ <listitem>
+ <para>To unload your usual kernel and modules, and then
+ load just your old (or another) kernel:</para>
+
+ <screen><userinput>unload</userinput>
+<userinput>load kernel.old</userinput></screen>
+
+ <para>You can use <filename>kernel.GENERIC</filename> to
+ refer to the generic kernel that comes on the install
+ disk, or <filename>kernel.old</filename><indexterm><primary><filename>kernel.old</filename></primary></indexterm> to refer to
+ your previously installed kernel (when you have upgraded
+ or configured your own kernel, for example).</para>
+
+ <note>
+ <para>Use the following to load your usual modules with
+ another kernel:</para>
+
+ <screen><userinput>unload</userinput>
+<userinput>set kernel="kernel.old"</userinput>
+<userinput>boot-conf</userinput></screen></note>
+ </listitem>
+
+ <listitem>
+ <para>To load a kernel configuration script (an automated
+ script which does the things you would normally do in the
+ kernel boot-time configurator):</para>
+
+ <screen><userinput>load -t userconfig_script /boot/kernel.conf</userinput></screen>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="boot-kernel">
+ <title>Kernel Interaction During Boot</title>
+ <indexterm>
+ <primary>kernel</primary>
+ <secondary>boot interaction</secondary>
+ </indexterm>
+
+ <para>Once the kernel is loaded by either <link linkend="boot-loader">loader</link> (as usual) or <link linkend="boot-boot1">boot2</link> (bypassing the loader), it
+ examines its boot flags, if any, and adjusts its behavior as
+ necessary.</para>
+
+ <sect2 xml:id="boot-kernel-bootflags">
+ <title>Kernel Boot Flags</title>
+
+ <indexterm>
+ <primary>kernel</primary>
+ <secondary>bootflags</secondary>
+ </indexterm>
+
+ <para>Here are the more common boot flags:</para>
+
+ <variablelist xml:id="boot-kernel-bootflags-list">
+ <varlistentry>
+ <term><option>-a</option></term>
+
+ <listitem>
+ <para>during kernel initialization, ask for the device
+ to mount as the root file system.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-C</option></term>
+
+ <listitem>
+ <para>boot from CDROM.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-c</option></term>
+
+ <listitem>
+ <para>run UserConfig, the boot-time kernel
+ configurator</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option></term>
+
+ <listitem>
+ <para>boot into single-user mode</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+
+ <listitem>
+ <para>be more verbose during kernel startup</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <note>
+ <para>There are other boot flags, read &man.boot.8; for more
+ information on them.</para></note>
+ </sect2>
+
+<!-- <sect2 id="boot-kernel-userconfig">
+ <title>UserConfig: the Boot-time Kernel Configurator</title>
+
+ <para> </para>
+ </sect2> -->
+ </sect1>
+
+ <sect1 xml:id="device-hints">
+ <info><title>Device Hints</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <indexterm>
+ <primary>device.hints</primary>
+ </indexterm>
+
+ <note><para>This is a FreeBSD&nbsp;5.0 and later feature which does not
+ exist in earlier versions.</para></note>
+
+ <para>During initial system startup, the boot &man.loader.8; will read the
+ &man.device.hints.5; file. This file stores kernel boot information
+ known as variables, sometimes referred to as <quote>device hints</quote>.
+ These <quote>device hints</quote> are used by device drivers for device
+ configuration.</para>
+
+ <para>Device hints may also be specified at the <link linkend="boot-loader">
+ Stage 3 boot loader</link> prompt. Variables can be added using
+ <command>set</command>, removed with <command>unset</command>, and viewed
+ with the <command>show</command> commands. Variables set in the
+ <filename>/boot/device.hints</filename> file can be overridden here also. Device hints entered at
+ the boot loader are not permanent and will be forgotten on the next
+ reboot.</para>
+
+ <para>Once the system is booted, the &man.kenv.1; command can be used to
+ dump all of the variables.</para>
+
+ <para>The syntax for the <filename>/boot/device.hints</filename> file is one variable per line, using
+ the standard hash <quote>#</quote> as comment markers. Lines are
+ constructed as follows:</para>
+
+ <screen><userinput>hint.driver.unit.keyword="value"</userinput></screen>
+
+ <para>The syntax for the Stage 3 boot loader is:</para>
+ <screen><userinput>set hint.driver.unit.keyword=value</userinput></screen>
+
+ <para><literal>driver</literal> is the device driver name, <literal>unit</literal>
+ is the device driver unit number, and <literal>keyword</literal> is the hint
+ keyword. The keyword may consist of the following options:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>at</literal>: specifies the bus which the device is attached to.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>port</literal>: specifies the start address of the <acronym>I/O</acronym>
+ to be used.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>irq</literal>: specifies the interrupt request number to be used.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>drq</literal>: specifies the DMA channel number.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>maddr</literal>: specifies the physical memory address occupied by the
+ device.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>flags</literal>: sets various flag bits for the device.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>disabled</literal>: if set to <literal>1</literal> the device is disabled.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Device drivers may accept (or require) more hints not listed here, viewing
+ their manual page is recommended. For more information, consult the
+ &man.device.hints.5;, &man.kenv.1;, &man.loader.conf.5;, and &man.loader.8;
+ manual pages.</para>
+ </sect1>
+
+ <sect1 xml:id="boot-init">
+ <title>Init: Process Control Initialization</title>
+
+ <indexterm>
+ <primary><command>init</command></primary>
+ </indexterm>
+
+ <para>Once the kernel has finished booting, it passes control to
+ the user process &man.init.8;, which is located at
+ <filename>/sbin/init</filename>, or the program path specified
+ in the <envar>init_path</envar> variable in
+ <command>loader</command>.</para>
+
+ <sect2 xml:id="boot-autoreboot">
+ <title>Automatic Reboot Sequence</title>
+
+ <para>The automatic reboot sequence makes sure that the
+ file systems available on the system are consistent. If they
+ are not, and &man.fsck.8; cannot fix the
+ inconsistencies, &man.init.8; drops the system
+ into <link linkend="boot-singleuser">single-user mode</link>
+ for the system administrator to take care of the problems
+ directly.</para>
+ </sect2>
+
+ <sect2 xml:id="boot-singleuser">
+ <title>Single-User Mode</title>
+ <indexterm><primary>single-user mode</primary></indexterm>
+ <indexterm><primary>console</primary></indexterm>
+
+ <para>This mode can be reached through the <link linkend="boot-autoreboot">automatic reboot
+ sequence</link>, or by the user booting with the
+ <option>-s</option> option or setting the
+ <envar>boot_single</envar> variable in
+ <command>loader</command>.</para>
+
+ <para>It can also be reached by calling
+ &man.shutdown.8; without the reboot
+ (<option>-r</option>) or halt (<option>-h</option>) options,
+ from <link linkend="boot-multiuser">multi-user
+ mode</link>.</para>
+
+ <para>If the system <literal>console</literal> is set
+ to <literal>insecure</literal> in <filename>/etc/ttys</filename>,
+ then the system prompts for the <systemitem class="username">root</systemitem> password
+ before initiating single-user mode.</para>
+
+ <example xml:id="boot-insecure-console">
+ <title>An Insecure Console in <filename>/etc/ttys</filename></title>
+
+ <programlisting># name getty type status comments
+#
+# If console is marked "insecure", then init will ask for the root password
+# when going to single-user mode.
+console none unknown off insecure</programlisting>
+ </example>
+
+ <note>
+ <para>An <literal>insecure</literal> console means that you
+ consider your physical security to the console to be
+ insecure, and want to make sure only someone who knows the
+ <systemitem class="username">root</systemitem> password may use single-user mode, and it
+ does not mean that you want to run your console insecurely. Thus,
+ if you want security, choose <literal>insecure</literal>,
+ not <literal>secure</literal>.</para>
+ </note>
+ </sect2>
+
+ <sect2 xml:id="boot-multiuser">
+ <title>Multi-User Mode</title>
+ <indexterm><primary>multi-user mode</primary></indexterm>
+
+ <para>If &man.init.8; finds your file systems to be
+ in order, or once the user has finished in <link linkend="boot-singleuser">single-user mode</link>, the
+ system enters multi-user mode, in which it starts the
+ resource configuration of the system.</para>
+
+ <sect3 xml:id="boot-rc">
+ <title>Resource Configuration (rc)</title>
+
+ <indexterm><primary>rc files</primary></indexterm>
+
+ <para>The resource configuration system reads in
+ configuration defaults from
+ <filename>/etc/defaults/rc.conf</filename>, and
+ system-specific details from
+ <filename>/etc/rc.conf</filename>, and then proceeds to
+ mount the system file systems mentioned in
+ <filename>/etc/fstab</filename>, start up networking
+ services, start up miscellaneous system daemons, and
+ finally runs the startup scripts of locally installed
+ packages.</para>
+
+ <para>The &man.rc.8; manual page is a good reference to the resource
+ configuration system, as is examining the scripts
+ themselves.</para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="boot-shutdown">
+ <title>Shutdown Sequence</title>
+ <indexterm>
+ <primary><command>shutdown</command></primary>
+ </indexterm>
+
+ <para>Upon controlled shutdown, via &man.shutdown.8;,
+ &man.init.8; will attempt to run the script
+ <filename>/etc/rc.shutdown</filename>, and then proceed to send
+ all processes the <literal>TERM</literal> signal, and subsequently
+ the <literal>KILL</literal> signal to any that do not terminate
+ timely.</para>
+
+ <para>To power down a FreeBSD machine on architectures and systems
+ that support power management, simply use the command
+ <command>shutdown -p now</command> to turn the power off
+ immediately. To just reboot a FreeBSD system, just use
+ <command>shutdown -r now</command>. You need to be
+ <systemitem class="username">root</systemitem> or a member of
+ <systemitem class="groupname">operator</systemitem> group to run &man.shutdown.8;.
+ The &man.halt.8; and &man.reboot.8; commands can also be used,
+ please refer to their manual pages and to &man.shutdown.8;'s one
+ for more information.</para>
+
+ <note>
+ <para>Power management requires &man.acpi.4; support in the kernel
+ or loaded as module for FreeBSD&nbsp;5.X and &man.apm.4;
+ support for FreeBSD&nbsp;4.X.</para>
+ </note>
+
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/chapters.ent b/zh_TW.UTF-8/books/handbook/chapters.ent
new file mode 100644
index 0000000000..fc0c4577d0
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/chapters.ent
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Creates entities for each chapter in the FreeBSD Handbook. Each entity
+ is named chap.foo, where foo is the value of the id attribute on that
+ chapter, and corresponds to the name of the directory in which that
+ chapter's .xml file is stored.
+
+ Chapters should be listed in the order in which they are referenced.
+
+ $FreeBSD$
+ Original revision: 1.33
+-->
+
+<!ENTITY chap.preface SYSTEM "preface/preface.xml">
+<!ENTITY % pgpkeys SYSTEM "../../../share/pgpkeys/pgpkeys.ent"> %pgpkeys;
+
+<!-- Part One -->
+ <!ENTITY chap.introduction SYSTEM "introduction/chapter.xml">
+ <!ENTITY chap.install SYSTEM "install/chapter.xml">
+ <!ENTITY chap.basics SYSTEM "basics/chapter.xml">
+ <!ENTITY chap.ports SYSTEM "ports/chapter.xml">
+ <!ENTITY chap.x11 SYSTEM "x11/chapter.xml">
+
+<!-- Part Two -->
+ <!ENTITY chap.desktop SYSTEM "desktop/chapter.xml">
+ <!ENTITY chap.multimedia SYSTEM "multimedia/chapter.xml">
+ <!ENTITY chap.kernelconfig SYSTEM "kernelconfig/chapter.xml">
+ <!ENTITY chap.printing SYSTEM "printing/chapter.xml">
+ <!ENTITY chap.linuxemu SYSTEM "linuxemu/chapter.xml">
+
+<!-- Part Three -->
+ <!ENTITY chap.config SYSTEM "config/chapter.xml">
+ <!ENTITY chap.boot SYSTEM "boot/chapter.xml">
+ <!ENTITY chap.users SYSTEM "users/chapter.xml">
+ <!ENTITY chap.security SYSTEM "security/chapter.xml">
+ <!ENTITY chap.jails SYSTEM "jails/chapter.xml">
+ <!ENTITY chap.mac SYSTEM "mac/chapter.xml">
+ <!ENTITY chap.audit SYSTEM "audit/chapter.xml">
+ <!ENTITY chap.disks SYSTEM "disks/chapter.xml">
+ <!ENTITY chap.geom SYSTEM "geom/chapter.xml">
+ <!ENTITY chap.filesystems SYSTEM "filesystems/chapter.xml">
+ <!ENTITY chap.vinum SYSTEM "vinum/chapter.xml">
+ <!ENTITY chap.virtualization SYSTEM "virtualization/chapter.xml">
+ <!ENTITY chap.l10n SYSTEM "l10n/chapter.xml">
+ <!ENTITY chap.cutting-edge SYSTEM "cutting-edge/chapter.xml">
+ <!ENTITY chap.dtrace SYSTEM "dtrace/chapter.xml">
+
+<!-- Part Four -->
+ <!ENTITY chap.serialcomms SYSTEM "serialcomms/chapter.xml">
+ <!ENTITY chap.ppp-and-slip SYSTEM "ppp-and-slip/chapter.xml">
+ <!ENTITY chap.mail SYSTEM "mail/chapter.xml">
+ <!ENTITY chap.network-servers SYSTEM "network-servers/chapter.xml">
+ <!ENTITY chap.firewalls SYSTEM "firewalls/chapter.xml">
+ <!ENTITY chap.advanced-networking SYSTEM "advanced-networking/chapter.xml">
+
+<!-- Part Five (appendices) -->
+ <!ENTITY chap.mirrors SYSTEM "mirrors/chapter.xml">
+ <!ENTITY chap.mirrors.lastmod.inc SYSTEM "mirrors.lastmod.inc">
+ <!ENTITY chap.mirrors.ftp.index.inc SYSTEM "mirrors.xml.ftp.index.inc">
+ <!ENTITY chap.mirrors.ftp.inc SYSTEM "mirrors.xml.ftp.inc">
+ <!ENTITY chap.mirrors.cvsup.index.inc SYSTEM "mirrors.xml.cvsup.index.inc">
+ <!ENTITY chap.mirrors.cvsup.inc SYSTEM "mirrors.xml.cvsup.inc">
+ <!ENTITY chap.bibliography SYSTEM "bibliography/chapter.xml">
+ <!ENTITY chap.eresources SYSTEM "eresources/chapter.xml">
+ <!ENTITY chap.eresources.www.index.inc SYSTEM "eresources.xml.www.index.inc">
+ <!ENTITY chap.eresources.www.inc SYSTEM "eresources.xml.www.inc">
+ <!ENTITY chap.pgpkeys SYSTEM "pgpkeys/chapter.xml">
+ <!ENTITY chap.freebsd-glossary SYSTEM "../../share/xml/glossary.ent">
+ <!ENTITY chap.index "<index xmlns='http://docbook.org/ns/docbook'/>">
+
+<!ENTITY chap.colophon SYSTEM "colophon.xml">
diff --git a/zh_TW.UTF-8/books/handbook/colophon.xml b/zh_TW.UTF-8/books/handbook/colophon.xml
new file mode 100644
index 0000000000..0ded28baa5
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/colophon.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+-->
+<colophon xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="colophon">
+ <para>This book is the combined work of hundreds of contributors to
+ <quote>The FreeBSD Documentation Project</quote>. The text is
+ authored in SGML
+ according to the DocBook DTD and is formatted from SGML into many
+ different presentation formats using <application>Jade</application>,
+ an open source DSSSL
+ engine. Norm Walsh's DSSSL stylesheets were used with an
+ additional customization layer to provide the presentation
+ instructions for <application>Jade</application>. The printed
+ version of this document would not be possible without Donald
+ Knuth's &tex; typesetting language,
+ Leslie Lamport's <application>LaTeX</application>, or Sebastian
+ Rahtz's <application>JadeTeX</application> macro package.</para>
+</colophon>
diff --git a/zh_TW.UTF-8/books/handbook/config/Makefile b/zh_TW.UTF-8/books/handbook/config/Makefile
new file mode 100644
index 0000000000..2d81feca5e
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/config/Makefile
@@ -0,0 +1,16 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+# Original revision: 1.1
+#
+
+CHAPTERS= config/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/config/chapter.xml b/zh_TW.UTF-8/books/handbook/config/chapter.xml
new file mode 100644
index 0000000000..07b0409d8b
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/config/chapter.xml
@@ -0,0 +1,3095 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.213
+ Chased revision: 1.221
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="config-tuning">
+ <info><title>設定與效能調校(Tuning)</title>
+ <authorgroup>
+ <author><personname><firstname>Chern</firstname><surname>Lee</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Mike</firstname><surname>Smith</surname></personname><contrib>Based on a tutorial written by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Matt</firstname><surname>Dillon</surname></personname><contrib>Also based on tuning(7) written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="config-synopsis">
+ <title>概述</title>
+
+ <indexterm><primary>system configuration</primary></indexterm>
+ <indexterm><primary>system optimization</primary></indexterm>
+
+ <para>在 &os; 使用過程中,相當重要的環節之一就是系統設定部分。
+ 正確的系統設定,可以讓你減輕日後升級的頭痛壓力。
+ 本章著重於介紹 &os; 的相關重要設定上,包括一些可以調整 &os; 效能的參數設定。
+ </para>
+
+ <para>讀完這章,您將了解:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>如何有效運用檔案系統以及 swap 分割區。</para>
+ </listitem>
+ <listitem>
+ <para><filename>rc.conf</filename> 的設定與 <filename>/usr/local/etc/rc.d</filename> 的啟動架構。</para>
+ </listitem>
+ <listitem>
+ <para>如何設定、測試網路卡。</para>
+ </listitem>
+ <listitem>
+ <para>如何設定 virtual hosts。</para>
+ </listitem>
+ <listitem>
+ <para>如何設定 <filename>/etc</filename> 內的各種設定檔。</para>
+ </listitem>
+ <listitem>
+ <para>如何以 <command>sysctl</command> 來調整 &os; 的系統效能。</para>
+ </listitem>
+ <listitem>
+ <para>如何調整硬碟效能,以及更改 kernel 限制。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>在開始閱讀這章之前,您需要︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>瞭解 &unix; 及 &os; 相關基本概念(<xref linkend="basics"/>)。</para>
+ </listitem>
+ <listitem>
+ <para>要有設定、編譯 kernel 的基礎概念(<xref linkend="kernelconfig"/>)。</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="configtuning-initial">
+ <title>一開始的規劃</title>
+
+ <sect2>
+ <title>規劃分割區(Partition)</title>
+
+ <indexterm><primary>partition layout</primary></indexterm>
+ <indexterm>
+ <primary><filename>/etc</filename></primary>
+ </indexterm>
+ <indexterm>
+ <primary><filename>/var</filename></primary>
+ </indexterm>
+ <indexterm>
+ <primary><filename>/usr</filename></primary>
+ </indexterm>
+
+ <sect3>
+ <title>Base Partitions</title>
+
+ <para>用 &man.bsdlabel.8; 或 &man.sysinstall.8; 來規劃檔案系統時,請記住:
+ 硬碟在傳輸資料方面,(由於結構為碟片因素)外圈會比內圈來得快些。
+ 因此,建議把較小、常會存取的分割區儘量放外圈,而較大的分割區像是
+ <filename>/usr</filename> 則應放在較內圈。
+ 建議建立分割區的順序,以像是:root, swap,
+ <filename>/var</filename>, <filename>/usr</filename> 這樣順序來建立會較妥。</para>
+
+ <para><filename>/var</filename> 的大小要視機器的用途而定。
+ <filename>/var</filename> 是用來放
+ 信箱、log 紀錄檔以及印表機佇列(spools)。 信箱以及記錄檔的成長幅度可能無法預估,
+ 因為這些成長幅度乃是取決於多少用戶、要放多久等管理原則而定。
+ 通常這些使用者並沒有用到 1 GB 以上,但請切記:至少要保留一定空間給 <filename>/var/tmp</filename>
+ 以便存放 packages。
+ </para>
+
+ <para>而 <filename>/usr</filename> 分割區主要是用來放系統運作時所需的檔案、工具程式等,例如:
+ &man.ports.7; collection(建議安裝)跟 source tree(optional)。
+ 在安裝 FreeBSD 時,這兩者都是可選擇裝與不裝的。
+ 不過,這個分割區建議至少要有 2 GB 空間以上才夠用。</para>
+
+ <para>規劃分割區大小時,記得多保留些成長空間。
+ 否則若某個分割區滿了,但另一個分割區卻還剩很多空間,就會相當困窘。</para>
+
+ <note><para>有些人可能會發現 &man.sysinstall.8; 的
+ <literal>Auto-defaults(自動預設值)</literal> 所做的分割區大小,
+ 有時候會把 <filename>/var</filename> 以及 <filename>/</filename> 分割區設太小了。
+ 我們建議是:請依使用情況以及需求,來手動調整相關分割區大小。</para></note>
+
+ </sect3>
+
+ <sect3 xml:id="swap-design">
+ <title>Swap 分割區</title>
+
+ <indexterm><primary>swap sizing</primary></indexterm>
+ <indexterm><primary>swap partition</primary></indexterm>
+
+ <para>根據經驗法則,通常 swap 分割區應該設為系統記憶體(RAM)大小的兩倍即可。
+ 舉例來說:若機器有 128&nbsp;MB RAM 的話,那麼
+ swap 則應該設為 256&nbsp;MB。 記憶體較少的機器,可以透過增加更多 swap 空間來提昇效能。
+ 我們建議 swap 空間不要設低於 256&nbsp;MB,而且該考慮增加記憶體才是良策。
+ 當 swap 最少為記憶體的兩倍大時,kernel 的 VM paging 演算法會把效能調整到最佳狀態。
+ 但若是機器記憶體很大,但 swap 卻劃分太少的話,會導致 VM page 掃瞄的效率過低,
+ 此外日後若增加更多記憶體時,也會導致一些異常狀況發生。</para>
+
+ <para>在較大型的機器內,通常會有多顆 SCSI 磁碟(或多顆 IDE 磁碟接在不同 IDE 匯流排上),
+ 建議在每顆磁碟上都建立 swap(最多到四顆)。
+ 而這些 swap 應該都大約一樣大小,
+ Kernel 可接受任意大小的 swap,但內部資料結構則是最大塊 swap 的 4 倍。
+ 若有保持 swap 為同樣大小的話,則可讓 kernel 最佳化運用各磁碟之中的 swap 空間。
+ 即使不太常會用到,分配大的 swap 也都還可接受,
+ 因為它可在強制重開機之前讓你更容易從當掉的程式中恢復正常。</para>
+ </sect3>
+
+ <sect3>
+ <title>為何要規劃 Partition?</title>
+
+ <para>有些人覺得把硬碟就直接劃分一個大分割區就好了,
+ 但是事實上有些原因會證明為何這是個爛點子,
+ 首先,每個分割區都有不同的運作特性,把它們分開的話可以讓檔案系統來調整。
+ 比如: <filename>/</filename> 以及 <filename>/usr</filename> 分割區大多只是讀取而已,
+ 比較少在寫入。 而讀寫都很頻繁的則是 <filename>/var</filename> 及
+ <filename>/var/tmp</filename>。</para>
+
+ <para>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
+ <filename>/var</filename> 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.</para>
+ </sect3>
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="configtuning-core-configuration">
+ <title>最主要的設定檔</title>
+
+ <indexterm>
+ <primary>rc files</primary>
+ <secondary><filename>rc.conf</filename></secondary>
+ </indexterm>
+
+ <para>The principal location for system configuration information
+ is within <filename>/etc/rc.conf</filename>. 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
+ <filename>rc*</filename> files.</para>
+
+ <para>An administrator should make entries in the
+ <filename>rc.conf</filename> file to
+ override the default settings from
+ <filename>/etc/defaults/rc.conf</filename>. The defaults file
+ should not be copied verbatim to <filename>/etc</filename> - it
+ contains default values, not examples. All system-specific
+ changes should be made in the <filename>rc.conf</filename>
+ file itself.</para>
+
+ <para>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 <filename>/etc/rc.conf.site</filename>, and then include
+ this file into <filename>/etc/rc.conf</filename>, which will
+ contain only system-specific information.</para>
+
+ <para>As <filename>rc.conf</filename> is read by &man.sh.1; it is
+ trivial to achieve this. For example:</para>
+
+ <itemizedlist>
+ <listitem><para>rc.conf:</para>
+<programlisting> . /etc/rc.conf.site
+ hostname="node15.example.com"
+ network_interfaces="fxp0 lo0"
+ ifconfig_fxp0="inet 10.1.1.1"</programlisting></listitem>
+ <listitem><para>rc.conf.site:</para>
+<programlisting> defaultrouter="10.1.1.254"
+ saver="daemon"
+ blanktime="100"</programlisting></listitem>
+ </itemizedlist>
+
+ <para>The <filename>rc.conf.site</filename> file can then be
+ distributed to every system using <command>rsync</command> or a
+ similar program, while the <filename>rc.conf</filename> file
+ remains unique.</para>
+
+ <para>Upgrading the system using &man.sysinstall.8;
+ or <command>make world</command> will not overwrite the
+ <filename>rc.conf</filename>
+ file, so system configuration information will not be lost.</para>
+
+ </sect1>
+
+ <sect1 xml:id="configtuning-appconfig">
+ <title>各式應用程式的設定檔</title>
+
+ <para>原則上,安裝的軟體都會有其自有的設定檔,也會有自己的格式及語法。
+ 因此,將其與系統分開獨立是件非常重要的事情。如此一來,套件管理工具將可以
+ 很輕易的找出這些設定檔並管理這些設定檔。</para>
+
+ <indexterm><primary>/usr/local/etc</primary></indexterm>
+
+ <para>原則上,設定檔會被放置在 <filename>/usr/local/etc</filename>。
+ 若某軟體的設定檔為數眾多,那將會其下建立一個目錄以供放置</para>
+
+ <para>通常,當一個 port 或 package 被安裝的同時,一些基本的設定範例
+ 也會一併被安裝至此。這些範例通常會被用 <filename>.default</filename> 做為副檔名。
+ 若安裝時沒有自行撰寫的軟體設定檔,那麼將會複製一份 <filename>.default</filename> 設定
+ 做為預設設定檔</para>
+
+ <para>舉個例子,我們來看看 <filename>/usr/local/etc/apache</filename>:</para>
+
+<literallayout class="monospaced">-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</literallayout>
+
+ <para><filename>srm.conf</filename> 的檔案被修改過了,爾後 <application>Apache</application> 的更新
+ 將不會對這個已修改過的設定檔做任何變動。</para>
+
+ </sect1>
+
+ <sect1 xml:id="configtuning-starting-services">
+ <info><title>各種 Services 的啟動方式</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm><primary>services</primary></indexterm>
+
+ <para>Many 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 <package>mail/postfix</package> or
+ <package>www/apache13</package> 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.</para>
+
+ <para>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.</para>
+
+ <para>Before the advent of <filename>rc.d</filename>, applications would drop a
+ simple start up script into the
+ <filename>/usr/local/etc/rc.d</filename>
+ directory which would be read by the system initialization
+ scripts. These scripts would then be executed during the latter
+ stages of system start up.</para>
+
+ <para>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 <filename>rc.d</filename> is being used. Prior
+ to &os;&nbsp;5.1 the old configuration style is used and in
+ almost all cases a new style script would do just fine.</para>
+
+ <para>While every script must meet some minimal requirements, most
+ of the time these requirements are &os; version
+ agnostic. Each script must have a <filename>.sh</filename>
+ extension appended to the end and every script must be
+ executable by the system. The latter may be achieved by using
+ the <command>chmod</command> command and setting the unique permissions
+ of <literal>755</literal>. There should also be, at minimal,
+ an option to <literal>start</literal> the application and an
+ option to <literal>stop</literal> the application.</para>
+
+ <para>The simplest start up script would probably look a little
+ bit like this one:</para>
+
+ <programlisting>#!/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}" &gt;&amp;2
+ exit 64
+ ;;
+esac
+
+exit 0</programlisting>
+
+ <para>This script provides for a <literal>stop</literal> and
+ <literal>start</literal> option for
+ the application hereto referred simply as
+ <literal>utility</literal>.</para>
+
+ <para>Could be started manually with:</para>
+
+ <screen>&prompt.root; <userinput>/usr/local/etc/rc.d/utility.sh start</userinput></screen>
+
+ <para>While not all third party software requires the line in
+ <filename>rc.conf</filename>, 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
+ <filename>rc.d</filename>; although, this will be discussed in the next section.</para>
+
+ <sect2>
+ <title>Extended Application Configuration</title>
+
+ <para>Now that &os; includes <filename>rc.d</filename>, configuration
+ of application startup has become easier, and more
+ featureful. Using the key words discussed in the
+ <link linkend="configtuning-rcd">rc.d</link> section,
+ applications may now be set to start after certain other
+ services for example <acronym>DNS</acronym>; may permit extra
+ flags to be passed through <filename>rc.conf</filename> in
+ place of hard coded flags in the start up script, etc. A
+ basic script may look similar to the following:</para>
+
+ <programlisting>#!/bin/sh
+#
+# PROVIDE: utility
+# REQUIRE: DAEMON
+# KEYWORD: shutdown
+
+. /etc/rc.subr
+
+name=utility
+rcvar=utility_pidfile
+
+command="/usr/local/sbin/utility"
+
+load_rc_config $name
+
+#
+# DO NOT CHANGE THESE DEFAULT VALUES HERE
+# SET THEM IN THE /etc/rc.conf FILE
+#
+utility_enable=${utility_enable-"NO"}
+pidfile=${utility_pidfile-"/var/run/utility.pid"}
+
+run_rc_command "$1"</programlisting>
+
+ <para>This script will ensure that the provided
+ <application>utility</application> will be started after the
+ <literal>daemon</literal> service. It also provides a method
+ for setting and tracking the <acronym>PID</acronym>, or process
+ <acronym>ID</acronym> file.</para>
+
+ <para>This application could then have the following line placed
+ in <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>utility_enable="YES"</programlisting>
+
+ <para>This new method also allows for easier manipulation of the
+ command line arguments, inclusion of the default functions
+ provided in <filename>/etc/rc.subr</filename>, compatibility
+ with the &man.rcorder.8; utility and provides for easier
+ configuration via the <filename>rc.conf</filename> file.</para>
+ </sect2>
+
+ <sect2>
+ <title>以 Services 來啟動各式 Services</title>
+
+ <para>Other services, such as <acronym>POP</acronym>3 server
+ daemons, <acronym>IMAP</acronym>, 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 <filename>/etc/inetd.conf</filename> file,
+ or uncommenting one of the current configuration lines. Working
+ with <application>inetd</application> and its configuration is
+ described in depth in the
+ <link linkend="network-inetd">inetd</link> section.</para>
+
+ <para>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 <command>cron</command> runs
+ these processes as the <filename>crontab</filename>'s file
+ owner. This allows regular users to start and maintain some
+ applications.</para>
+
+ <para>The <command>cron</command> utility provides a unique
+ feature, <literal>@reboot</literal>, 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.</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="configtuning-cron">
+ <info><title>設定 <command>cron</command></title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>cron</primary>
+ <secondary>configuration</secondary></indexterm>
+
+ <para>&os; 最好用的工具之一就是 &man.cron.8;。
+ <command>cron</command> 會在背景下運作,並不斷檢查
+ <filename>/etc/crontab</filename> 檔以及 <filename>/var/cron/tabs</filename> 目錄,來搜尋是否有新 <filename>crontab</filename> 檔案。
+ 這些 <filename>crontab</filename> 檔會存放一些排程工作的設定,來給 <command>cron</command> 執行。</para>
+
+ <para><command>cron</command> 程式,可同時採用兩種不同類型的設定檔:系統本身的 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.</para>
+
+ <note>
+ <para>User crontabs allow individual users to schedule tasks without the
+ need for <systemitem class="username">root</systemitem> privileges. Commands in a user's crontab run with the
+ permissions of the user who owns the crontab.</para>
+
+ <para>The <systemitem class="username">root</systemitem> user can have a user crontab just like
+ any other user. This one is different from
+ <filename>/etc/crontab</filename> (the system crontab). Because of the
+ system crontab, there is usually no need to create a user crontab
+ for <systemitem class="username">root</systemitem>.</para>
+ </note>
+
+ <para>Let us take a look at the <filename>/etc/crontab</filename> file
+ (the system crontab):</para>
+
+
+ <programlisting># /etc/crontab - root's crontab for &os;
+#
+# &dollar;&os;: src/etc/crontab,v 1.32 2002/11/22 16:13:39 tom Exp &dollar;
+# <co xml:id="co-comments"/>
+#
+SHELL=/bin/sh
+PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin <co xml:id="co-env"/>
+HOME=/var/log
+#
+#
+#minute hour mday month wday who command <co xml:id="co-field-descr"/>
+#
+#
+*/5 * * * * root /usr/libexec/atrun <co xml:id="co-main"/>
+</programlisting>
+
+ <calloutlist>
+ <callout arearefs="co-comments">
+ <para>Like most &os; configuration files, the <literal>#</literal>
+ 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.</para>
+ </callout>
+
+ <callout arearefs="co-env">
+ <para>First, the environment must be defined. The equals
+ (<literal>=</literal>) character is used to define any environment
+ settings, as with this example where it is used for the <envar>SHELL</envar>,
+ <envar>PATH</envar>, and <envar>HOME</envar> options. If the shell line is
+ omitted, <command>cron</command> will use the default, which is
+ <command>sh</command>. If the <envar>PATH</envar> variable is
+ omitted, no default will be used and file locations will need to
+ be absolute. If <envar>HOME</envar> is omitted, <command>cron</command>
+ will use the invoking users home directory.</para>
+ </callout>
+
+ <callout arearefs="co-field-descr">
+ <para>This line defines a total of seven fields. Listed here are the
+ values <literal>minute</literal>, <literal>hour</literal>,
+ <literal>mday</literal>, <literal>month</literal>, <literal>wday</literal>,
+ <literal>who</literal>, and <literal>command</literal>. These
+ are almost all self explanatory. <literal>minute</literal> is the time in minutes the
+ command will be run. <literal>hour</literal> is similar to the <literal>minute</literal> option, just in
+ hours. <literal>mday</literal> stands for day of the month. <literal>month</literal> is similar to <literal>hour</literal>
+ and <literal>minute</literal>, as it designates the month. The <literal>wday</literal> option stands for
+ day of the week. All these fields must be numeric values, and follow
+ the twenty-four hour clock. The <literal>who</literal> field is special,
+ and only exists in the <filename>/etc/crontab</filename> file.
+ This field specifies which user the command should be run as.
+ When a user installs his or her <filename>crontab</filename> file, they
+ will not have this option. Finally, the <literal>command</literal> option is listed.
+ This is the last field, so naturally it should designate the command
+ to be executed.</para>
+ </callout>
+
+ <callout arearefs="co-main">
+ <para>This last line will define the values discussed above. Notice here
+ we have a <literal>*/5</literal> listing, followed by several more
+ <literal>*</literal> characters. These <literal>*</literal> characters
+ mean <quote>first-last</quote>, and can be interpreted as
+ <emphasis>every</emphasis> time. So, judging by this line,
+ it is apparent that the <command>atrun</command> command is to be invoked by
+ <systemitem class="username">root</systemitem> every five minutes regardless of what
+ day or month it is. For more information on the <command>atrun</command> command,
+ see the &man.atrun.8; manual page.</para>
+
+ <para>Commands can have any number of flags passed to them; however,
+ commands which extend to multiple lines need to be broken with the backslash
+ <quote>\</quote> continuation character.</para>
+ </callout>
+ </calloutlist>
+
+ <para>This is the basic set up for every
+ <filename>crontab</filename> file, although there is one thing
+ different about this one. Field number six, where we specified
+ the username, only exists in the system
+ <filename>/etc/crontab</filename> file. This field should be
+ omitted for individual user <filename>crontab</filename>
+ files.</para>
+
+
+ <sect2 xml:id="configtuning-installcrontab">
+ <title>工作排程(Crontab)的排定與管理</title>
+
+ <important>
+ <para>You must not use the procedure described here to
+ edit/install the system crontab. Simply use your favorite
+ editor: the <command>cron</command> utility will notice that the file
+ has changed and immediately begin using the updated version.
+ See
+ <link xlink:href="&url.books.faq;/admin.html#ROOT-NOT-FOUND-CRON-ERRORS">
+ this FAQ entry </link> for more information.</para>
+ </important>
+
+ <para>To install a freshly written user
+ <filename>crontab</filename>, first use your favorite editor to create
+ a file in the proper format, and then use the
+ <command>crontab</command> utility. The most common usage
+ is:</para>
+
+ <screen>&prompt.user; <userinput>crontab crontab-file</userinput></screen>
+
+ <para>In this example, <filename>crontab-file</filename> is the filename
+ of a <filename>crontab</filename> that was previously created.</para>
+
+ <para>There is also an option to list installed
+ <filename>crontab</filename> files: just pass the
+ <option>-l</option> option to <command>crontab</command> and look
+ over the output.</para>
+
+ <para>For users who wish to begin their own crontab file from scratch,
+ without the use of a template, the <command>crontab -e</command>
+ 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 <command>crontab</command> command.
+ </para>
+
+ <para>If you later want to remove your user <filename>crontab</filename>
+ completely, use <command>crontab</command> with the <option>-r</option>
+ option.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="configtuning-rcd">
+ <info><title>在 &os; 使用 rc</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <para>從 2002 年起,&os; 整合了 NetBSD 的 <filename>rc.d</filename> 機制來作為系統服務啟動機制。
+ 可以到 <filename>/etc/rc.d</filename> 目錄下去看,很多檔案都是基本服務,可以用 <option>start</option>, <option>stop</option>
+ 及 <option>restart</option> 作為使用時的選項。
+ 舉個例子,可以用下列指令來重新啟動 &man.sshd.8;:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/sshd restart</userinput></screen>
+
+ <para>其他服務也是類似作法。當然,
+ 服務通常只要在 &man.rc.conf.5; 內有指定的話,都會在開機時就自動啟動。舉例來說,若要開機時啟動 NAT(Network Address
+ Translation) daemon 的話,只要在 <filename>/etc/rc.conf</filename> 內加上下列這行即可:</para>
+
+ <programlisting>natd_enable="YES"</programlisting>
+
+ <para>若原本寫的是 <option>natd_enable="NO"</option> 那麼只要把 <option>NO</option> 改為
+ <option>YES</option> 就好了。rc scripts 會在下次重開機時,自動載入相關(有相依)的服務,以下我們會講到這部分。</para>
+
+ <para>Since the <filename>rc.d</filename> system is primarily
+ intended to start/stop services at system startup/shutdown time,
+ the standard <option>start</option>,
+ <option>stop</option> and <option>restart</option> options will only
+ perform their action if the appropriate
+ <filename>/etc/rc.conf</filename> variables are set. For
+ instance the above <command>sshd restart</command> command will
+ only work if <varname>sshd_enable</varname> is set to
+ <option>YES</option> in <filename>/etc/rc.conf</filename>. To
+ <option>start</option>, <option>stop</option> or
+ <option>restart</option> a service regardless of the settings in
+ <filename>/etc/rc.conf</filename>, the commands should be
+ prefixed with <quote>force</quote>. For instance to restart
+ <command>sshd</command> regardless of the current
+ <filename>/etc/rc.conf</filename> setting, execute the following
+ command:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/sshd forcerestart</userinput></screen>
+
+ <para>It is easy to check if a service is enabled in
+ <filename>/etc/rc.conf</filename> by running the appropriate
+ <filename>rc.d</filename> script with the option
+ <option>rcvar</option>. Thus, an administrator can check that
+ <command>sshd</command> is in fact enabled in
+ <filename>/etc/rc.conf</filename> by running:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/sshd rcvar</userinput>
+# sshd
+$sshd_enable=YES</screen>
+
+ <note>
+ <para>The second line (<literal># sshd</literal>) is the output
+ from the <command>sshd</command> command, not a <systemitem class="username">root</systemitem>
+ console.</para>
+ </note>
+
+ <para>若要檢查服務是否有在運作,可以用 <option>status</option> 選項來查詢。比如:若要確認
+ <command>sshd</command> 是否真的有啟動的話,那麼打:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/sshd status</userinput>
+sshd is running as pid 433.</screen>
+
+ <para>In some cases it is also possible to <option>reload</option> 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 <literal>SIGHUP</literal>
+ signal. Support for this feature is not included for every service.</para>
+
+ <para>The <filename>rc.d</filename> system is not only used for network services, it also
+ contributes to most of the system initialization. For
+ instance, consider the <filename>bgfsck</filename> file. When
+ this script is executed, it will print out the following
+ message:</para>
+
+ <screen>Starting background file system checks in 60 seconds.</screen>
+
+ <para>Therefore this file is used for background file system
+ checks, which are done only during system initialization.</para>
+
+ <para>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 <command>rpcbind</command>
+ (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:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>PROVIDE</literal>: Specifies the services this file provides.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>REQUIRE</literal>: Lists services which are required for this
+ service. This file will run <emphasis>after</emphasis>
+ the specified services.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>BEFORE</literal>: Lists services which depend on this service.
+ This file will run <emphasis>before</emphasis>
+ the specified services.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>By using this method, an administrator can easily control system
+ services without the hassle of <quote>runlevels</quote> like
+ some other &unix; operating systems.</para>
+
+ <para>Additional information about the
+ <filename>rc.d</filename> system can be found in the &man.rc.8;
+ and &man.rc.subr.8; manual pages.</para>
+ </sect1>
+
+ <sect1 xml:id="config-network-setup">
+ <info><title>設定網路卡</title>
+ <authorgroup>
+ <author><personname><firstname>Marc</firstname><surname>Fonvieille</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm>
+ <primary>network cards</primary>
+ <secondary>configuration</secondary>
+ </indexterm>
+
+ <para>Nowadays 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.</para>
+
+ <sect2>
+ <title>選擇正確、可用的驅動程式(Driver)</title>
+
+ <indexterm>
+ <primary>network cards</primary>
+ <secondary>driver</secondary>
+ </indexterm>
+
+ <para>Before 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.</para>
+
+ <para>Once you are sure your card is supported, you need
+ to determine the proper driver for the card.
+ <filename>/usr/src/sys/conf/NOTES</filename> and
+ <filename>/usr/src/sys/arch/conf/NOTES</filename> 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.</para>
+
+ <para>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 <filename>GENERIC</filename>
+ kernel, so your card should show up during boot, like so:</para>
+
+<screen>dc0: &lt;82c169 PNIC 10/100BaseTX&gt; 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: &lt;MII bus&gt; on dc0
+ukphy0: &lt;Generic IEEE 802.3u media interface&gt; on miibus0
+ukphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
+dc1: &lt;82c169 PNIC 10/100BaseTX&gt; 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: &lt;MII bus&gt; on dc1
+ukphy1: &lt;Generic IEEE 802.3u media interface&gt; on miibus1
+ukphy1: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto</screen>
+
+ <para>In this example, we see that two cards using the &man.dc.4;
+ driver are present on the system.</para>
+
+ <para>If the driver for your NIC is not present in
+ <filename>GENERIC</filename>, you will need to load the proper
+ driver to use your NIC. This may be accomplished in one of
+ two ways:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The easiest way is to simply load a kernel module for
+ your network card with &man.kldload.8;, or automatically at boot time by adding the appropriate line to the file <filename>/boot/loader.conf</filename>. Not all NIC
+ drivers are available as modules; notable examples of
+ devices for which modules do not exist are ISA cards.</para>
+ </listitem>
+
+ <listitem>
+ <para>Alternatively, you may statically compile the support
+ for your card into your kernel. Check
+ <filename>/usr/src/sys/conf/NOTES</filename>,
+ <filename>/usr/src/sys/arch/conf/NOTES</filename>
+ 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 <xref linkend="kernelconfig"/>. If your card was detected at
+ boot by your kernel (<filename>GENERIC</filename>) you do
+ not have to build a new kernel.</para>
+ </listitem>
+ </itemizedlist>
+
+ <sect3 xml:id="config-network-ndis">
+ <title>Using &windows; NDIS Drivers</title>
+
+ <indexterm><primary>NDIS</primary></indexterm>
+ <indexterm><primary>NDISulator</primary></indexterm>
+ <indexterm><primary>&windows; drivers</primary></indexterm>
+ <indexterm><primary>Microsoft Windows</primary></indexterm>
+ <indexterm><primary>Microsoft Windows</primary>
+ <secondary>device drivers</secondary></indexterm>
+ <indexterm><primary>KLD (kernel loadable
+ object)</primary></indexterm>
+<!-- We should probably omit the expanded name, and add a <see> entry
+for it. Whatever is done must also be done to the same indexterm in
+linuxemu/chapter.xml -->
+
+ <para>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
+ &microsoft.windows; platforms. Most developers, including
+ those involved with &os;, have taken the latter
+ approach.</para>
+
+ <para>Thanks to the contributions of Bill Paul (wpaul), as of
+ &os;&nbsp;5.3-RELEASE there is <quote>native</quote> 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.</para>
+
+ <note>
+ <para>The &man.ndis.4; driver is designed to support mainly
+ PCI, CardBus and PCMCIA devices, USB devices are not yet
+ supported.</para>
+ </note>
+
+ <para>In order to use the NDISulator, you need three
+ things:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Kernel sources</para>
+ </listitem>
+ <listitem>
+ <para>&windowsxp; driver binary
+ (<filename>.SYS</filename> extension)</para>
+ </listitem>
+ <listitem>
+ <para>&windowsxp; driver configuration file
+ (<filename>.INF</filename> extension)</para>
+ </listitem>
+ </orderedlist>
+
+ <para>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
+ <filename>W32DRIVER.SYS</filename> and
+ <filename>W32DRIVER.INF</filename>.</para>
+
+ <note>
+ <para>You can not use a &windows;/i386 driver with
+ &os;/amd64, you must get a &windows;/amd64 driver to make it
+ work properly.</para>
+ </note>
+
+ <para>The next step is to compile the driver binary into a
+ loadable kernel module. To accomplish this, as
+ <systemitem class="username">root</systemitem>, use &man.ndisgen.8;:</para>
+
+ <screen>&prompt.root; <userinput>ndisgen /path/to/W32DRIVER.INF /path/to/W32DRIVER.SYS</userinput></screen>
+
+ <para>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:</para>
+
+ <screen>&prompt.root; <userinput>kldload ./W32DRIVER.ko</userinput></screen>
+
+ <para>In addition to the generated kernel module, you must
+ load the <filename>ndis.ko</filename> and
+ <filename>if_ndis.ko</filename> 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:</para>
+
+ <screen>&prompt.root; <userinput>kldload ndis</userinput>
+&prompt.root; <userinput>kldload if_ndis</userinput></screen>
+
+ <para>The first command loads the NDIS miniport driver
+ wrapper, the second loads the actual network
+ interface.</para>
+
+ <para>Now, check &man.dmesg.8; to see if there were any errors
+ loading. If all went well, you should get output resembling
+ the following:</para>
+
+ <screen>ndis0: &lt;Wireless-G PCI Adapter&gt; 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</screen>
+
+ <para>From here you can treat the
+ <filename>ndis0</filename> device like any other network
+ interface (e.g., <filename>dc0</filename>).</para>
+
+ <para>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,
+ <filename>W32DRIVER.ko</filename>, to the <filename>/boot/modules</filename> directory. Then,
+ add the following line to
+ <filename>/boot/loader.conf</filename>:</para>
+
+ <programlisting>W32DRIVER_load="YES"</programlisting>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>設定網路卡</title>
+
+ <indexterm>
+ <primary>network cards</primary>
+ <secondary>configuration</secondary>
+ </indexterm>
+
+ <para>Once 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
+ <application>sysinstall</application>.</para>
+
+ <para>To display the configuration for the network interfaces on
+ your system, enter the following command:</para>
+
+<screen>&prompt.user; <userinput>ifconfig</userinput>
+dc0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; 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 &lt;full-duplex&gt;)
+ status: active
+dc1: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; 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&lt;POINTOPOINT,SIMPLEX,MULTICAST&gt; mtu 1500
+lo0: flags=8049&lt;UP,LOOPBACK,RUNNING,MULTICAST&gt; mtu 16384
+ inet 127.0.0.1 netmask 0xff000000
+tun0: flags=8010&lt;POINTOPOINT,MULTICAST&gt; mtu 1500</screen>
+
+ <note>
+ <para>Old versions of &os; may require the <option>-a</option>
+ 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
+ (<literal>inet6</literal> etc.) were omitted in this
+ example.</para>
+ </note>
+
+ <para>In this example, the following devices were
+ displayed:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><filename>dc0</filename>: The first Ethernet
+ interface</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>dc1</filename>: The second Ethernet
+ interface</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>lp0</filename>: The parallel port
+ interface</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>lo0</filename>: The loopback device</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>tun0</filename>: The tunnel device used by
+ <application>ppp</application></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>&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 <filename>sis2</filename> would
+ be the third network card on the system using the &man.sis.4;
+ driver.</para>
+
+ <para>In this example, the <filename>dc0</filename> device is
+ up and running. The key indicators are:</para>
+
+ <orderedlist>
+ <listitem>
+ <para><literal>UP</literal> means that the card is configured
+ and ready.</para>
+ </listitem>
+
+ <listitem>
+ <para>The card has an Internet (<literal>inet</literal>)
+ address (in this case
+ <systemitem class="ipaddress">192.168.1.3</systemitem>).</para>
+ </listitem>
+
+ <listitem>
+ <para>It has a valid subnet mask (<literal>netmask</literal>;
+ <systemitem class="netmask">0xffffff00</systemitem> is the same as
+ <systemitem class="netmask">255.255.255.0</systemitem>).</para>
+ </listitem>
+
+ <listitem>
+ <para>It has a valid broadcast address (in this case,
+ <systemitem class="ipaddress">192.168.1.255</systemitem>).</para>
+ </listitem>
+
+ <listitem>
+ <para>The MAC address of the card (<literal>ether</literal>)
+ is <systemitem class="etheraddress">00:a0:cc:da:da:da</systemitem></para>
+ </listitem>
+
+ <listitem>
+ <para>The physical media selection is on autoselection mode
+ (<literal>media: Ethernet autoselect (100baseTX
+ &lt;full-duplex&gt;)</literal>). We see that
+ <filename>dc1</filename> was configured to run with
+ <literal>10baseT/UTP</literal> media. For more
+ information on available media types for a driver, please
+ refer to its manual page.</para>
+ </listitem>
+
+ <listitem>
+ <para>The status of the link (<literal>status</literal>)
+ is <literal>active</literal>, i.e. the carrier is detected.
+ For <filename>dc1</filename>, we see
+ <literal>status: no carrier</literal>. This is normal when
+ an Ethernet cable is not plugged into the card.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>If the &man.ifconfig.8; output had shown something similar
+ to:</para>
+
+<screen>dc0: flags=8843&lt;BROADCAST,SIMPLEX,MULTICAST&gt; mtu 1500
+ ether 00:a0:cc:da:da:da</screen>
+
+ <para>it would indicate the card has not been configured.</para>
+
+ <para>To configure your card, you need <systemitem class="username">root</systemitem>
+ 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
+ <filename>/etc/rc.conf</filename> is where to add the network
+ card's configuration.</para>
+
+ <para>Open <filename>/etc/rc.conf</filename> 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:</para>
+
+<programlisting>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"</programlisting>
+
+ <para>You have to replace <filename>dc0</filename>,
+ <filename>dc1</filename>, 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
+ <filename>/etc/rc.conf</filename>.</para>
+
+ <para>If you configured the network during installation, some
+ lines about the network card(s) may be already present. Double
+ check <filename>/etc/rc.conf</filename> before adding any
+ lines.</para>
+
+ <para>You will also have to edit the file
+ <filename>/etc/hosts</filename> 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 <filename>/usr/share/examples/etc/hosts</filename>.</para>
+ </sect2>
+
+ <sect2>
+ <title>測試與疑難排除</title>
+
+ <para>Once you have made the necessary changes in
+ <filename>/etc/rc.conf</filename>, 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.</para>
+
+ <para>Once the system has been rebooted, you should test the
+ network interfaces.</para>
+
+ <sect3>
+ <title>測試乙太網路卡(Ethernet Card)</title>
+
+ <indexterm>
+ <primary>network cards</primary>
+ <secondary>testing</secondary>
+ </indexterm>
+
+ <para>To 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.</para>
+
+ <para>First test the local interface:</para>
+
+<screen>&prompt.user; <userinput>ping -c5 192.168.1.3</userinput>
+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 ms</screen>
+
+ <para>Now we have to ping another machine on the LAN:</para>
+
+<screen>&prompt.user; <userinput>ping -c5 192.168.1.2</userinput>
+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 ms</screen>
+
+ <para>You could also use the machine name instead of
+ <systemitem class="ipaddress">192.168.1.2</systemitem> if you have set up the
+ <filename>/etc/hosts</filename> file.</para>
+ </sect3>
+
+ <sect3>
+ <title>疑難排除</title>
+
+ <indexterm>
+ <primary>network cards</primary>
+ <secondary>troubleshooting</secondary>
+ </indexterm>
+
+ <para>Troubleshooting 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.</para>
+
+ <para>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.</para>
+
+ <para>Some users experience one or two <errorname>device
+ timeout</errorname> 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.</para>
+
+ <para>At times, users see a few <errorname>watchdog timeout</errorname>
+ 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.</para>
+
+ <para><errorname>No route to host</errorname> 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 <command>netstat
+ -rn</command> and make sure there is a valid route to the host
+ you are trying to reach. If there is not, read on to <xref linkend="advanced-networking"/>.</para>
+
+ <para><errorname>ping: sendto: Permission denied</errorname> error
+ messages are often caused by a misconfigured firewall. If
+ <command>ipfw</command> 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 <xref linkend="firewalls"/> for more information.</para>
+
+ <para>Sometimes performance of the card is poor, or below average.
+ In these cases it is best to set the media selection mode
+ from <literal>autoselect</literal> 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.</para>
+
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="configtuning-virtual-hosts">
+ <title>虛擬主機(Virtual Hosts)</title>
+
+ <indexterm><primary>virtual hosts</primary></indexterm>
+ <indexterm><primary>IP aliases</primary></indexterm>
+
+ <para>A 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.</para>
+
+ <para>A given network interface has one <quote>real</quote> address,
+ and may have any number of <quote>alias</quote> addresses.
+ These aliases are
+ normally added by placing alias entries in
+ <filename>/etc/rc.conf</filename>.</para>
+
+ <para>An alias entry for the interface <filename>fxp0</filename>
+ looks like:</para>
+
+<programlisting>ifconfig_fxp0_alias0="inet xxx.xxx.xxx.xxx netmask xxx.xxx.xxx.xxx"</programlisting>
+
+ <para>Note that alias entries must start with <literal>alias0</literal> and proceed
+ upwards in order, (for example, <literal>_alias1</literal>, <literal>_alias2</literal>, and so on).
+ The configuration process will stop at the first missing number.
+ </para>
+
+ <para>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 <literal>1</literal>s (expressed as either
+ <systemitem class="netmask">255.255.255.255</systemitem> or <systemitem class="netmask">0xffffffff</systemitem>).
+ </para>
+
+ <para>For example, consider the case where the
+ <filename>fxp0</filename> interface is
+ connected to two networks, the <systemitem class="ipaddress">10.1.1.0</systemitem>
+ network with a netmask of <systemitem class="netmask">255.255.255.0</systemitem>
+ and the <systemitem class="ipaddress">202.0.75.16</systemitem> network with
+ a netmask of <systemitem class="netmask">255.255.255.240</systemitem>.
+ We want the system to appear at <systemitem class="ipaddress">10.1.1.1</systemitem>
+ through <systemitem class="ipaddress">10.1.1.5</systemitem> and at
+ <systemitem class="ipaddress">202.0.75.17</systemitem> through
+ <systemitem class="ipaddress">202.0.75.20</systemitem>. As noted above, only the
+ first address in a given network range (in this case,
+ <systemitem class="ipaddress">10.0.1.1</systemitem> and
+ <systemitem class="ipaddress">202.0.75.17</systemitem>) should have a real
+ netmask; all the rest (<systemitem class="ipaddress">10.1.1.2</systemitem>
+ through <systemitem class="ipaddress">10.1.1.5</systemitem> and
+ <systemitem class="ipaddress">202.0.75.18</systemitem> through
+ <systemitem class="ipaddress">202.0.75.20</systemitem>) must be configured with a
+ netmask of <systemitem class="netmask">255.255.255.255</systemitem>.</para>
+
+ <para>The following <filename>/etc/rc.conf</filename> entries
+ configure the adapter correctly for this arrangement:</para>
+
+ <programlisting>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"</programlisting>
+
+ </sect1>
+
+ <sect1 xml:id="configtuning-configfiles">
+ <title>還有哪些主要設定檔呢?</title>
+
+ <sect2>
+ <title><filename>/etc</filename> Layout</title>
+ <para>There are a number of directories in which configuration
+ information is kept. These include:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2*"/>
+
+ <tbody>
+ <row>
+ <entry><filename>/etc</filename></entry>
+ <entry>Generic system configuration information; data here is
+ system-specific.</entry>
+ </row>
+ <row>
+ <entry><filename>/etc/defaults</filename></entry>
+ <entry>Default versions of system configuration files.</entry>
+ </row>
+ <row>
+ <entry><filename>/etc/mail</filename></entry>
+ <entry>Extra &man.sendmail.8; configuration, other
+ MTA configuration files.
+ </entry>
+ </row>
+ <row>
+ <entry><filename>/etc/ppp</filename></entry>
+ <entry>Configuration for both user- and kernel-ppp programs.
+ </entry>
+ </row>
+ <row>
+ <entry><filename>/etc/namedb</filename></entry>
+ <entry>Default location for &man.named.8; data. Normally
+ <filename>named.conf</filename> and zone files are stored
+ here.</entry>
+ </row>
+ <row>
+ <entry><filename>/usr/local/etc</filename></entry>
+ <entry>Configuration files for installed applications.
+ May contain per-application subdirectories.</entry>
+ </row>
+ <row>
+ <entry><filename>/usr/local/etc/rc.d</filename></entry>
+ <entry>Start/stop scripts for installed applications.</entry>
+ </row>
+ <row>
+ <entry><filename>/var/db</filename></entry>
+ <entry>Automatically generated system-specific database files,
+ such as the package database, the locate database, and so
+ on</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Hostnames</title>
+
+ <indexterm><primary>hostname</primary></indexterm>
+ <indexterm><primary>DNS</primary></indexterm>
+
+ <sect3>
+ <title><filename>/etc/resolv.conf</filename></title>
+
+ <indexterm>
+ <primary><filename>resolv.conf</filename></primary>
+ </indexterm>
+
+ <para><filename>/etc/resolv.conf</filename> dictates how &os;'s
+ resolver accesses the Internet Domain Name System (DNS).</para>
+
+ <para>The most common entries to <filename>resolv.conf</filename> are:
+ </para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2*"/>
+
+ <tbody>
+ <row>
+ <entry><literal>nameserver</literal></entry>
+ <entry>The IP address of a name server the resolver
+ should query. The servers are queried in the order
+ listed with a maximum of three.</entry>
+ </row>
+ <row>
+ <entry><literal>search</literal></entry>
+ <entry>Search list for hostname lookup. This is normally
+ determined by the domain of the local hostname.</entry>
+ </row>
+ <row>
+ <entry><literal>domain</literal></entry>
+ <entry>The local domain name.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>A typical <filename>resolv.conf</filename>:</para>
+
+ <programlisting>search example.com
+nameserver 147.11.1.11
+nameserver 147.11.100.30</programlisting>
+
+ <note><para>Only one of the <literal>search</literal> and
+ <literal>domain</literal> options should be used.</para></note>
+
+ <para>If you are using DHCP, &man.dhclient.8; usually rewrites
+ <filename>resolv.conf</filename> with information received from the
+ DHCP server.</para>
+ </sect3>
+
+ <sect3>
+ <title><filename>/etc/hosts</filename></title>
+
+ <indexterm><primary>hosts</primary></indexterm>
+
+ <para><filename>/etc/hosts</filename> 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,
+ <filename>/etc/hosts</filename> can be used to provide a
+ local record of Internet names, reducing the need to query
+ externally for commonly accessed names.</para>
+
+ <programlisting># &dollar;&os;&dollar;
+#
+# 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').
+#</programlisting>
+
+ <para><filename>/etc/hosts</filename> takes on the simple format
+ of:</para>
+
+ <programlisting>[Internet address] [official hostname] [alias1] [alias2] ...</programlisting>
+
+ <para>For example:</para>
+
+ <programlisting>10.0.0.1 myRealHostname.example.com myRealHostname foobar1 foobar2</programlisting>
+
+ <para>Consult &man.hosts.5; for more information.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Log File Configuration</title>
+
+ <indexterm><primary>log files</primary></indexterm>
+
+ <sect3>
+ <title><filename>syslog.conf</filename></title>
+
+ <indexterm><primary>syslog.conf</primary></indexterm>
+
+ <para><filename>syslog.conf</filename> is the configuration file
+ for the &man.syslogd.8; program. It indicates which types
+ of <command>syslog</command> messages are logged to particular
+ log files.</para>
+
+ <programlisting># &dollar;&os;&dollar;
+#
+# 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.log</programlisting>
+
+ <para>Consult the &man.syslog.conf.5; manual page for more
+ information.</para>
+ </sect3>
+
+ <sect3>
+ <title><filename>newsyslog.conf</filename></title>
+
+ <indexterm><primary>newsyslog.conf</primary></indexterm>
+
+ <para><filename>newsyslog.conf</filename> 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.
+ <filename>logfile</filename> is moved to
+ <filename>logfile.0</filename>, <filename>logfile.0</filename>
+ is moved to <filename>logfile.1</filename>, and so on.
+ Alternatively, the log files may be archived in &man.gzip.1; format
+ causing them to be named: <filename>logfile.0.gz</filename>,
+ <filename>logfile.1.gz</filename>, and so on.</para>
+
+ <para><filename>newsyslog.conf</filename> 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.</para>
+
+ <programlisting># configuration file for newsyslog
+# &dollar;&os;&dollar;
+#
+# 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 * Z</programlisting>
+
+ <para>Consult the &man.newsyslog.8; manual page for more
+ information.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="configtuning-sysctlconf">
+ <title><filename>sysctl.conf</filename></title>
+
+ <indexterm><primary>sysctl.conf</primary></indexterm>
+ <indexterm><primary>sysctl</primary></indexterm>
+
+ <para><filename>sysctl.conf</filename> looks much like
+ <filename>rc.conf</filename>. Values are set in a
+ <literal>variable=value</literal>
+ form. The specified values are set after the system goes into
+ multi-user mode. Not all variables are settable in this mode.</para>
+
+ <para>A sample <filename>sysctl.conf</filename> turning off logging
+ of fatal signal exits and letting Linux programs know they are really
+ running under &os;:</para>
+
+ <programlisting>kern.logsigexit=0 # Do not log fatal signal exits (e.g. sig 11)
+compat.linux.osname=&os;
+compat.linux.osrelease=4.3-STABLE</programlisting>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="configtuning-sysctl">
+ <title>Tuning with sysctl</title>
+
+ <indexterm><primary>sysctl</primary></indexterm>
+ <indexterm>
+ <primary>tuning</primary>
+ <secondary>with sysctl</secondary>
+ </indexterm>
+
+ <para>&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;.</para>
+
+ <para>At its core, &man.sysctl.8; serves two functions: to read and
+ to modify system settings.</para>
+
+ <para>To view all readable variables:</para>
+
+ <screen>&prompt.user; <userinput>sysctl -a</userinput></screen>
+
+ <para>To read a particular variable, for example,
+ <varname>kern.maxproc</varname>:</para>
+
+ <screen>&prompt.user; <userinput>sysctl kern.maxproc</userinput>
+kern.maxproc: 1044</screen>
+
+ <para>To set a particular variable, use the intuitive
+ <replaceable>variable</replaceable>=<replaceable>value</replaceable>
+ syntax:</para>
+
+ <screen>&prompt.root; <userinput>sysctl kern.maxfiles=5000</userinput>
+kern.maxfiles: 2088 -&gt; 5000</screen>
+
+ <para>Settings of sysctl variables are usually either strings,
+ numbers, or booleans (a boolean being <literal>1</literal> for yes
+ or a <literal>0</literal> for no).</para>
+
+ <para>If you want to set automatically some variables each time
+ the machine boots, add them to the
+ <filename>/etc/sysctl.conf</filename> file. For more information
+ see the &man.sysctl.conf.5; manual page and the
+ <xref linkend="configtuning-sysctlconf"/>.</para>
+
+ <sect2 xml:id="sysctl-readonly">
+ <info><title>&man.sysctl.8; Read-only</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <para>In 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.</para>
+
+ <para>For instance on some laptop models the &man.cardbus.4; device will
+ not probe memory ranges, and fail with errors which look similar to:</para>
+
+ <screen>cbb0: Could not map register memory
+device_probe_and_attach: cbb0 attach returned 12</screen>
+
+ <para>Cases 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; <quote>OIDs</quote>
+ in their local <filename>/boot/loader.conf</filename>. Default
+ settings are located in the <filename>/boot/defaults/loader.conf</filename>
+ file.</para>
+
+ <para>Fixing the problem mentioned above would require a user to set
+ <option>hw.pci.allow_unsupported_io_range=1</option> in the aforementioned
+ file. Now &man.cardbus.4; will work properly.</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="configtuning-disk">
+ <title>Tuning Disks</title>
+
+ <sect2>
+ <title>Sysctl Variables</title>
+
+ <sect3>
+ <title><varname>vfs.vmiodirenable</varname></title>
+
+ <indexterm>
+ <primary><varname>vfs.vmiodirenable</varname></primary>
+ </indexterm>
+
+ <para>The <varname>vfs.vmiodirenable</varname> 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&nbsp;K) in the file system and less
+ (typically 512&nbsp;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&nbsp;K) rather than 512&nbsp;
+ 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.</para>
+ </sect3>
+
+ <sect3>
+ <title><varname>vfs.write_behind</varname></title>
+
+ <indexterm>
+ <primary><varname>vfs.write_behind</varname></primary>
+ </indexterm>
+
+ <para>The <varname>vfs.write_behind</varname> sysctl variable
+ defaults to <literal>1</literal> (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.</para>
+ </sect3>
+
+ <sect3>
+ <title><varname>vfs.hirunningspace</varname></title>
+
+ <indexterm>
+ <primary><varname>vfs.hirunningspace</varname></primary>
+ </indexterm>
+
+ <para>The <varname>vfs.hirunningspace</varname> 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 <emphasis>megabytes</emphasis>.
+ 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.
+ </para>
+
+ <para>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.</para>
+ </sect3>
+
+ <sect3>
+ <title><varname>vm.swap_idle_enabled</varname></title>
+
+ <indexterm>
+ <primary><varname>vm.swap_idle_enabled</varname></primary>
+ </indexterm>
+
+ <para>The <varname>vm.swap_idle_enabled</varname> 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
+ <varname>vm.swap_idle_threshold1</varname> and
+ <varname>vm.swap_idle_threshold2</varname> 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.</para>
+ </sect3>
+
+ <sect3>
+ <title><varname>hw.ata.wc</varname></title>
+
+ <indexterm>
+ <primary><varname>hw.ata.wc</varname></primary>
+ </indexterm>
+
+ <para>&os;&nbsp;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
+ <varname>hw.ata.wc</varname> 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.</para>
+
+ <para>For more information, please see &man.ata.4;.</para>
+ </sect3>
+
+ <sect3>
+ <title><literal>SCSI_DELAY</literal>
+ (<varname>kern.cam.scsi_delay</varname>)</title>
+
+ <indexterm>
+ <primary><varname>kern.cam.scsi_delay</varname></primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary><literal>SCSI_DELAY</literal></secondary>
+ </indexterm>
+
+ <para>The <literal>SCSI_DELAY</literal> kernel config may be used to
+ reduce system boot times. The defaults are fairly high and can be
+ responsible for <literal>15</literal> seconds of delay in the
+ boot process. Reducing it to <literal>5</literal> seconds usually
+ works (especially with modern drives). Newer versions of &os;
+ (5.0 and higher) should use the <varname>kern.cam.scsi_delay</varname>
+ boot time tunable. The tunable, and kernel config option accept
+ values in terms of <emphasis>milliseconds</emphasis> and
+ <emphasis>not</emphasis> <emphasis>seconds</emphasis>.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="soft-updates">
+ <title>Soft Updates</title>
+
+ <indexterm><primary>Soft Updates</primary></indexterm>
+ <indexterm><primary>tunefs</primary></indexterm>
+
+ <para>The &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:</para>
+
+ <screen>&prompt.root; <userinput>tunefs -n enable /filesystem</userinput>
+&prompt.root; <userinput>tunefs -n disable /filesystem</userinput></screen>
+
+ <para>A 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.</para>
+
+ <para>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
+ <command>make installworld</command>, can cause the filesystem to run
+ out of space and the update to fail.</para>
+
+ <sect3>
+ <title>More Details about Soft Updates</title>
+
+ <indexterm>
+ <primary>Soft Updates</primary>
+ <secondary>details</secondary>
+ </indexterm>
+
+ <para>There 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.)</para>
+
+ <para>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
+ <command>rm -r</command>, 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 (<command>tar -x</command>).</para>
+
+ <para>The second case is asynchronous meta-data updates. This
+ is the default for Linux/ext2fs and
+ <command>mount -o async</command> 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 <command>fsck</command> 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.
+ </para>
+
+ <para>The usual solution for this problem was to implement
+ <emphasis>dirty region logging</emphasis>, which is also
+ referred to as <emphasis>journaling</emphasis>, 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 <quote>pessimization</quote>
+ 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.</para>
+
+ <para>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 (<quote>ordered meta-data
+ updates</quote>). This has the effect that, in case of
+ heavy meta-data operations, later updates to an item
+ <quote>catch</quote> 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 <quote>log
+ rewind</quote>: 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 <quote>used</quote> which are actually <quote>free</quote>.
+ &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 <command>mount -f</command>. 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 <emphasis>background fsck</emphasis>: at system startup
+ time, only a <emphasis>snapshot</emphasis> of the
+ filesystem is recorded. The <command>fsck</command> can be
+ run later on. All file systems can then be mounted
+ <quote>dirty</quote>, so the system startup proceeds in
+ multiuser mode. Then, background <command>fsck</command>s
+ 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
+ <command>fsck</command> though.)</para>
+
+ <para>The advantage is that meta-data operations are nearly as
+ fast as asynchronous updates (i.e. faster than with
+ <emphasis>logging</emphasis>, 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 <quote>older</quote>. In situations where
+ the standard synchronous approach would have caused some
+ zero-length files to remain after the
+ <command>fsck</command>, 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 <command>rm</command>. 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.</para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="configtuning-kernel-limits">
+ <title>Tuning Kernel Limits</title>
+
+ <indexterm>
+ <primary>tuning</primary>
+ <secondary>kernel limits</secondary>
+ </indexterm>
+
+ <sect2 xml:id="file-process-limits">
+ <title>File/Process Limits</title>
+
+ <sect3 xml:id="kern-maxfiles">
+ <title><varname>kern.maxfiles</varname></title>
+
+ <indexterm>
+ <primary><varname>kern.maxfiles</varname></primary>
+ </indexterm>
+
+ <para><varname>kern.maxfiles</varname> 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,
+ <errorname>file: table is full</errorname> will show up repeatedly
+ in the system message buffer, which can be viewed with the
+ <command>dmesg</command> command.</para>
+
+ <para>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.</para>
+
+ <para>In older FreeBSD releases, <varname>kern.maxfile</varname>'s default
+ value is derived from the <option>maxusers</option> option in your
+ dictated by the <option>maxusers</option> option in your
+ kernel configuration file. <varname>kern.maxfiles</varname> grows
+ proportionally to the value of <option>maxusers</option>. 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.</para>
+
+ <para>As of FreeBSD 4.5, <varname>kern.maxusers</varname> 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 <varname>kern.maxusers</varname> sysctl.
+ Some sites will require larger or smaller values of
+ <varname>kern.maxusers</varname> 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
+ <varname>kern.maxusers</varname> may be individually overridden at
+ boot-time or run-time in <filename>/boot/loader.conf</filename> (see
+ the &man.loader.conf.5; man page or the
+ <filename>/boot/defaults/loader.conf</filename> file for some hints)
+ or as described elsewhere in this document. Systems older than
+ FreeBSD&nbsp;4.4 must set this value via the kernel &man.config.8;
+ option <option>maxusers</option> instead.</para>
+
+ <para>The system will auto-tune
+ <literal>maxusers</literal> for you if you explicitly set it to
+ <literal>0</literal><footnote>
+ <para>The auto-tuning algorithm sets
+ <literal>maxusers</literal> equal to the amount of memory in the
+ system, with a minimum of 32, and a maximum of 384.</para>
+ </footnote>. When setting this option, you will want to set
+ <literal>maxusers</literal> 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 <literal>maxusers</literal> is the
+ maximum number of processes, which is set to <literal>20 + 16 *
+ maxusers</literal>, so if you set <literal>maxusers</literal> 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
+ <literal>maxusers</literal> 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 <errortype>proc table
+ full</errortype> error when trying to start another program, or are
+ running a server with a large number of simultaneous users (like
+ <systemitem class="fqdomainname">ftp.FreeBSD.org</systemitem>), you can always
+ increase the number and rebuild.</para>
+
+ <note>
+ <para><literal>maxusers</literal> does <emphasis>not</emphasis>
+ 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 <emphasis>does</emphasis> limit the number of simultaneous
+ remote logins and X terminal windows is <link linkend="kernelconfig-ptys"><literal>pseudo-device pty
+ 16</literal></link>. With &os;&nbsp;5.X, you do not have to
+ worry about this number since the &man.pty.4; driver is
+ <quote>auto-cloning</quote>; you simply use the line
+ <literal>device pty</literal> in your configuration file.</para>
+ </note>
+
+ </sect3>
+
+ <sect3>
+ <title><varname>kern.ipc.somaxconn</varname></title>
+
+ <indexterm>
+ <primary><varname>kern.ipc.somaxconn</varname></primary>
+ </indexterm>
+
+ <para>The <varname>kern.ipc.somaxconn</varname> sysctl variable
+ limits the size of the listen queue for accepting new TCP
+ connections. The default value of <literal>128</literal> 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 <literal>1024</literal> or
+ higher. The service daemon may itself limit the listen queue size
+ (e.g. &man.sendmail.8;, or <application>Apache</application>) 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 (<abbrev>DoS</abbrev>) attacks.</para>
+ </sect3>
+
+ </sect2>
+ <sect2 xml:id="nmbclusters">
+ <title>Network Limits</title>
+
+ <para>The <literal>NMBCLUSTERS</literal> 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&nbsp;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&nbsp;K receive
+ and 16&nbsp;K send buffer, you need approximately 32&nbsp;MB worth of
+ network buffers to cover the web server. A good rule of thumb is
+ to multiply by 2, so 2x32&nbsp;MB&nbsp;/&nbsp;2&nbsp;KB&nbsp;=
+ 64&nbsp;MB&nbsp;/&nbsp;2&nbsp;kB&nbsp;= 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>-m</option> option to
+ &man.netstat.1; may be used to observe network cluster
+ use.</para>
+
+ <para><varname>kern.ipc.nmbclusters</varname> loader tunable should
+ be used to tune this at boot time. Only older versions of &os;
+ will require you to use the <literal>NMBCLUSTERS</literal> kernel
+ &man.config.8; option.</para>
+
+ <para>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
+ <literal>NSFBUFS</literal> kernel configuration option or by
+ setting its value in <filename>/boot/loader.conf</filename>
+ (see &man.loader.8; for details). A common indicator that
+ this parameter needs to be adjusted is when processes are seen
+ in the <literal>sfbufa</literal> state. The sysctl
+ variable <varname>kern.ipc.nsfbufs</varname> is a read-only
+ glimpse at the kernel configured variable. This parameter
+ nominally scales with <varname>kern.maxusers</varname>,
+ however it may be necessary to tune accordingly.</para>
+
+ <important>
+ <para>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
+ <literal>struct sf_buf</literal>'s are made
+ available.</para>
+ </important>
+
+ <sect3>
+ <title><varname>net.inet.ip.portrange.*</varname></title>
+
+ <indexterm>
+ <primary>net.inet.ip.portrange.*</primary>
+ </indexterm>
+
+ <para>The <varname>net.inet.ip.portrange.*</varname> 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
+ <varname>net.inet.ip.portrange.first</varname> and
+ <varname>net.inet.ip.portrange.last</varname>, 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 <varname>net.inet.ip.portrange.last</varname> modestly.
+ A value of <literal>10000</literal>, <literal>20000</literal> or
+ <literal>30000</literal> 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 &mdash; for this reason it is not recommended that
+ <varname>net.inet.ip.portrange.first</varname> be lowered.</para>
+ </sect3>
+
+ <sect3>
+ <title>TCP Bandwidth Delay Product</title>
+
+ <indexterm>
+ <primary>TCP Bandwidth Delay Product Limiting</primary>
+ <secondary><varname>net.inet.tcp.inflight.enable</varname></secondary>
+ </indexterm>
+
+ <para>The TCP Bandwidth Delay Product Limiting is similar to
+ TCP/Vegas in NetBSD. It can be
+ enabled by setting <varname>net.inet.tcp.inflight.enable</varname>
+ sysctl variable to <literal>1</literal>. 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.</para>
+
+ <para>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
+ <varname>net.inet.tcp.inflight.debug</varname> to
+ <literal>0</literal> (disable debugging), and for production use
+ setting <varname>net.inet.tcp.inflight.min</varname> to at least
+ <literal>6144</literal> 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 <emphasis>Round Trip Times</emphasis>. However,
+ note that this feature only effects data transmission (uploading
+ / server side). It has no effect on data reception (downloading).
+ </para>
+
+ <para>Adjusting <varname>net.inet.tcp.inflight.stab</varname> is
+ <emphasis>not</emphasis> 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
+ <varname>net.inet.tcp.inflight.min</varname> (for example, to
+ 3500) to get the desired effect. Reducing these parameters
+ should be done as a last resort only.</para>
+
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Virtual Memory</title>
+
+ <sect3>
+ <title><varname>kern.maxvnodes</varname></title>
+
+ <para>A 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.</para>
+
+ <para>To see the current number of vnodes in use:</para>
+
+ <programlisting>&prompt.root; sysctl vfs.numvnodes
+vfs.numvnodes: 91349</programlisting>
+
+ <para>To see the maximum vnodes:</para>
+
+ <programlisting>&prompt.root; sysctl kern.maxvnodes
+kern.maxvnodes: 100000</programlisting>
+
+ <para>If the current vnode usage is near the maximum, increasing
+ <varname>kern.maxvnodes</varname> by a value of 1,000 is
+ probably a good idea. Keep an eye on the number of
+ <varname>vfs.numvnodes</varname>. If it climbs up to the
+ maximum again, <varname>kern.maxvnodes</varname> 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.</para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="adding-swap-space">
+ <title>Adding Swap Space</title>
+
+ <para>No 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.</para>
+
+ <para>For information on how to encrypt swap space, what options
+ for this task exist and why it should be done, please refer to
+ <xref linkend="swap-encrypting"/> of the Handbook.</para>
+
+ <sect2 xml:id="new-drive-swap">
+ <title>Swap on a New Hard Drive</title>
+
+ <para>The 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 <xref linkend="configtuning-initial"/>
+ of the Handbook for some suggestions on how to best
+ arrange your swap.</para>
+ </sect2>
+
+ <sect2 xml:id="nfs-swap">
+ <title>Swapping over NFS</title>
+
+ <para>Swapping 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.</para>
+ </sect2>
+
+ <sect2 xml:id="create-swapfile">
+ <title>Swapfiles</title>
+
+ <para>You 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
+ <filename>/usr/swap0</filename>. You can use any name you
+ want, of course.</para>
+
+ <example>
+ <title>Creating a Swapfile on &os;</title>
+
+ <orderedlist>
+ <listitem>
+ <para>Be certain that your kernel configuration includes
+ the memory disk driver (&man.md.4;). It is default in
+ <filename>GENERIC</filename> kernel.</para>
+
+ <programlisting>device md # Memory "disks"</programlisting>
+ </listitem>
+
+ <listitem>
+ <para>Create a swapfile (<filename>/usr/swap0</filename>):</para>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/zero of=/usr/swap0 bs=1024k count=64</userinput></screen>
+ </listitem>
+
+ <listitem>
+ <para>Set proper permissions on (<filename>/usr/swap0</filename>):</para>
+
+ <screen>&prompt.root; <userinput>chmod 0600 /usr/swap0</userinput></screen>
+ </listitem>
+
+ <listitem>
+ <para>Enable the swap file in <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>swapfile="/usr/swap0" # Set to name of swapfile if aux swapfile desired.</programlisting>
+ </listitem>
+
+ <listitem>
+
+ <para>Reboot the machine or to enable the swap file immediately,
+ type:</para>
+
+ <screen>&prompt.root; <userinput>mdconfig -a -t vnode -f /usr/swap0 -u 0 &amp;&amp; swapon /dev/md0</userinput></screen>
+ </listitem>
+ </orderedlist>
+
+ </example>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="acpi-overview">
+ <info><title>Power and Resource Management</title>
+ <authorgroup>
+ <author><personname><firstname>Hiten</firstname><surname>Pandya</surname></personname><contrib>Written by </contrib></author>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname></author>
+ </authorgroup>
+ </info>
+
+
+
+ <para>It is very important to utilize hardware resources in an
+ efficient manner. Before <acronym>ACPI</acronym> 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 <acronym>BIOS</acronym> embedded
+ interface, such as <emphasis>Plug and Play BIOS (PNPBIOS)</emphasis>, or
+ <emphasis>Advanced Power Management (APM)</emphasis> 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.</para>
+
+ <para>In this section of the &os; Handbook, we will provide
+ comprehensive information about <acronym>ACPI</acronym>. References
+ will be provided for further reading at the end.</para>
+
+ <sect2 xml:id="acpi-intro">
+ <title>What Is ACPI?</title>
+
+ <indexterm>
+ <primary>ACPI</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>APM</primary>
+ </indexterm>
+
+ <para>Advanced Configuration and Power Interface
+ (<acronym>ACPI</acronym>) 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 <emphasis>Operating System-directed
+ configuration and Power Management</emphasis>, i.e.: it provides
+ more control and flexibility to the operating system
+ (<acronym>OS</acronym>).
+ Modern systems <quote>stretched</quote> the limits of the
+ current Plug and Play interfaces prior to the introduction of
+ <acronym>ACPI</acronym>. <acronym>ACPI</acronym> is the direct
+ successor to <acronym>APM</acronym>
+ (Advanced Power Management).</para>
+ </sect2>
+
+ <sect2 xml:id="acpi-old-spec">
+ <title>Shortcomings of Advanced Power Management (APM)</title>
+
+ <para>The <emphasis>Advanced Power Management (APM)</emphasis>
+ 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 <emphasis>APM Software Interface</emphasis>,
+ which allows management of power levels.</para>
+
+ <para>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.</para>
+
+ <para><emphasis>Plug and Play BIOS (PNPBIOS)</emphasis> was
+ unreliable in many situations. PNPBIOS is 16-bit technology,
+ so the OS has to use 16-bit emulation in order to
+ <quote>interface</quote> with PNPBIOS methods.</para>
+
+ <para>The &os; <acronym>APM</acronym> driver is documented in
+ the &man.apm.4; manual page.</para>
+ </sect2>
+
+ <sect2 xml:id="acpi-config">
+ <title>Configuring <acronym>ACPI</acronym></title>
+
+ <para>The <filename>acpi.ko</filename> driver is loaded by default
+ at start up by the &man.loader.8; and should <emphasis>not</emphasis>
+ be compiled into the kernel. The reasoning behind this is that modules
+ are easier to work with, say if switching to another <filename>acpi.ko</filename>
+ without doing a kernel rebuild. This has the advantage of making testing easier.
+ Another reason is that starting <acronym>ACPI</acronym> after a system has been
+ brought up is not too useful, and in some cases can be fatal. In doubt, just
+ disable <acronym>ACPI</acronym> all together. This driver should not and can not
+ be unloaded because the system bus uses it for various hardware interactions.
+ <acronym>ACPI</acronym> can be disabled with the &man.acpiconf.8; utility.
+ In fact most of the interaction with <acronym>ACPI</acronym> can be done via
+ &man.acpiconf.8;. Basically this means, if anything about <acronym>ACPI</acronym>
+ is in the &man.dmesg.8; output, then most likely it is already running.</para>
+
+ <note><para><acronym>ACPI</acronym> and <acronym>APM</acronym> cannot coexist and
+ should be used separately. The last one to load will terminate if the driver
+ notices the other running.</para></note>
+
+ <para>In the simplest form, <acronym>ACPI</acronym> can be used to put the
+ system into a sleep mode with &man.acpiconf.8;, the <option>-s</option>
+ flag, and a <literal>1-5</literal> option. Most users will only need
+ <literal>1</literal>. Option <literal>5</literal> will do a soft-off
+ which is the same action as:</para>
+
+ <screen>&prompt.root; <userinput>halt -p</userinput></screen>
+
+ <para>The other options are available. Check out the &man.acpiconf.8;
+ manual page for more information.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="ACPI-debug">
+ <info><title>Using and Debugging &os; <acronym>ACPI</acronym></title>
+ <authorgroup>
+ <author><personname><firstname>Nate</firstname><surname>Lawson</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Peter</firstname><surname>Schultz</surname></personname><contrib>With contributions from </contrib></author>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm>
+ <primary>ACPI</primary>
+ <secondary>problems</secondary>
+ </indexterm>
+
+ <para><acronym>ACPI</acronym> is a fundamentally new way of
+ discovering devices, managing power usage, and providing
+ standardized access to various hardware previously managed
+ by the <acronym>BIOS</acronym>. Progress is being made toward
+ <acronym>ACPI</acronym> working on all systems, but bugs in some
+ motherboards' <firstterm><acronym>ACPI</acronym> Machine
+ Language</firstterm> (<acronym>AML</acronym>) bytecode,
+ incompleteness in &os;'s kernel subsystems, and bugs in the &intel;
+ <acronym>ACPI-CA</acronym> interpreter continue to appear.</para>
+
+ <para>This document is intended to help you assist the &os;
+ <acronym>ACPI</acronym> 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.</para>
+
+ <sect2 xml:id="ACPI-submitdebug">
+ <title>Submitting Debugging Information</title>
+
+ <note>
+ <para>Before submitting a problem, be sure you are running the latest
+ <acronym>BIOS</acronym> version and, if available, embedded
+ controller firmware version.</para>
+ </note>
+
+ <para>For those of you that want to submit a problem right away,
+ please send the following information to
+ <link xlink:href="mailto:freebsd-acpi@FreeBSD.org">
+ freebsd-acpi@FreeBSD.org</link>:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>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.</para>
+ </listitem>
+
+ <listitem>
+ <para>The &man.dmesg.8; output after <command>boot
+ -v</command>, including any error messages
+ generated by you exercising the bug.</para>
+ </listitem>
+
+ <listitem>
+ <para>The &man.dmesg.8; output from <command>boot
+ -v</command> with <acronym>ACPI</acronym>
+ disabled, if disabling it helps fix the problem.</para>
+ </listitem>
+
+ <listitem>
+ <para>Output from <command>sysctl hw.acpi</command>. This is also
+ a good way of figuring out what features your system
+ offers.</para>
+ </listitem>
+
+ <listitem>
+ <para><acronym>URL</acronym> where your
+ <firstterm><acronym>ACPI</acronym> Source Language</firstterm>
+ (<acronym>ASL</acronym>)
+ can be found. Do <emphasis>not</emphasis> send the
+ <acronym>ASL</acronym> directly to the list as it can be
+ very large. Generate a copy of your <acronym>ASL</acronym>
+ by running this command:</para>
+
+ <screen>&prompt.root; <userinput>acpidump -t -d &gt; name-system.asl</userinput></screen>
+
+ <para>(Substitute your login name for
+ <replaceable>name</replaceable> and manufacturer/model for
+ <replaceable>system</replaceable>. Example:
+ <filename>njl-FooCo6000.asl</filename>)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>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 <acronym>PR</acronym> via
+ &man.send-pr.1;. When entering a <acronym>PR</acronym>, please
+ include the same information as requested above. This will help
+ us track the problem and resolve it. Do not send a
+ <acronym>PR</acronym> without emailing &a.acpi.name; first as we use
+ <acronym>PR</acronym>s as reminders of existing problems, not a
+ reporting mechanism. It is likely that your problem has been
+ reported by someone before.</para>
+ </sect2>
+
+ <sect2 xml:id="ACPI-background">
+ <title>Background</title>
+
+ <indexterm>
+ <primary>ACPI</primary>
+ </indexterm>
+
+ <para><acronym>ACPI</acronym> 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
+ <acronym>CPU</acronym> 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.</para>
+
+ <para>An <acronym>ACPI</acronym>-compliant system has various
+ components. The <acronym>BIOS</acronym> and chipset vendors
+ provide various fixed tables (e.g., <acronym>FADT</acronym>)
+ in memory that specify things like the <acronym>APIC</acronym>
+ map (used for <acronym>SMP</acronym>), config registers, and
+ simple configuration values. Additionally, a table of bytecode
+ (the <firstterm>Differentiated System Description Table</firstterm>
+ <acronym>DSDT</acronym>) is provided that specifies a
+ tree-like name space of devices and methods.</para>
+
+ <para>The <acronym>ACPI</acronym> driver must parse the fixed
+ tables, implement an interpreter for the bytecode, and modify
+ device drivers and the kernel to accept information from the
+ <acronym>ACPI</acronym> subsystem. For &os;, &intel; has
+ provided an interpreter (<acronym>ACPI-CA</acronym>) that is
+ shared with Linux and NetBSD. The path to the
+ <acronym>ACPI-CA</acronym> source code is
+ <filename>src/sys/contrib/dev/acpica</filename>.
+ The glue code that allows <acronym>ACPI-CA</acronym> to work on
+ &os; is in
+ <filename>src/sys/dev/acpica/Osd</filename>. Finally, drivers
+ that implement various <acronym>ACPI</acronym> devices are found
+ in
+ <filename>src/sys/dev/acpica</filename>.</para>
+ </sect2>
+
+ <sect2 xml:id="ACPI-comprob">
+ <title>Common Problems</title>
+
+ <indexterm>
+ <primary>ACPI</primary>
+ <secondary>problems</secondary>
+ </indexterm>
+
+ <para>For <acronym>ACPI</acronym> 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.</para>
+
+ <sect3>
+ <title>Mouse Issues</title>
+
+ <para>In some cases, resuming from a suspend operation will
+ cause the mouse to fail. A known work around is to add
+ <literal>hint.psm.0.flags="0x3000"</literal> to the
+ <filename>/boot/loader.conf</filename> file. If this
+ does not work then please consider sending a bug report
+ as described above.</para>
+ </sect3>
+
+ <sect3>
+ <title>Suspend/Resume</title>
+
+ <para><acronym>ACPI</acronym> has three suspend to
+ <acronym>RAM</acronym> (<acronym>STR</acronym>) states,
+ <literal>S1</literal>-<literal>S3</literal>, and one suspend
+ to disk state (<literal>STD</literal>), called
+ <literal>S4</literal>. <literal>S5</literal> is
+ <quote>soft off</quote> and is the normal state your system
+ is in when plugged in but not powered up.
+ <literal>S4</literal> can actually be implemented two separate
+ ways. <literal>S4</literal><acronym>BIOS</acronym> is a
+ <acronym>BIOS</acronym>-assisted suspend to disk.
+ <literal>S4</literal><acronym>OS</acronym> is implemented
+ entirely by the operating system.</para>
+
+ <para>Start by checking <command>sysctl hw.acpi</command>
+ for the suspend-related items. Here
+ are the results for a Thinkpad:</para>
+
+ <screen>hw.acpi.supported_sleep_state: S3 S4 S5
+hw.acpi.s4bios: 0</screen>
+
+ <para>This means that we can use <command>acpiconf -s</command>
+ to test <literal>S3</literal>,
+ <literal>S4</literal><acronym>OS</acronym>, and
+ <literal>S5</literal>. If <option>s4bios</option> was one
+ (<literal>1</literal>), we would have
+ <literal>S4</literal><acronym>BIOS</acronym>
+ support instead of <literal>S4</literal>
+ <acronym>OS</acronym>.</para>
+
+ <para>When testing suspend/resume, start with
+ <literal>S1</literal>, if supported. This state is most
+ likely to work since it does not require much driver support.
+ No one has implemented <literal>S2</literal> but if you have
+ it, it is similar to <literal>S1</literal>. The next thing
+ to try is <literal>S3</literal>. This is the deepest
+ <acronym>STR</acronym> 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.</para>
+
+ <para>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
+ <filename>nvidia.ko</filename>, X11
+ display drivers, and <acronym>USB</acronym> 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
+ <filename>/etc/rc.suspend</filename> and
+ <filename>/etc/rc.resume</filename>. There is a
+ commented-out example for unloading and loading a driver. Try
+ setting <option>hw.acpi.reset_video</option> to zero (<literal>0</literal>) if
+ your display is messed up after resume. Try setting longer or
+ shorter values for <option>hw.acpi.sleep_delay</option> to see
+ if that helps.</para>
+
+ <para>Another thing to try is load a recent Linux distribution
+ with <acronym>ACPI</acronym> 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 <acronym>ACPI</acronym> maintainers do not
+ usually maintain other drivers (e.g sound,
+ <acronym>ATA</acronym>, 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.</para>
+
+ <para>Finally, try disabling <acronym>ACPI</acronym> and
+ enabling <acronym>APM</acronym> instead. If suspend/resume
+ works with <acronym>APM</acronym>, you may be better off
+ sticking with <acronym>APM</acronym>, especially on older
+ hardware (pre-2000). It took vendors a while to get
+ <acronym>ACPI</acronym> support correct and older hardware is
+ more likely to have <acronym>BIOS</acronym> problems with
+ <acronym>ACPI</acronym>.</para>
+ </sect3>
+
+ <sect3>
+ <title>System Hangs (temporary or permanent)</title>
+
+ <para>Most system hangs are a result of lost interrupts or an
+ interrupt storm. Chipsets have a lot of problems based on how
+ the <acronym>BIOS</acronym> configures interrupts before boot,
+ correctness of the <acronym>APIC</acronym>
+ (<acronym>MADT</acronym>) table, and routing of the
+ <firstterm>System Control Interrupt</firstterm>
+ (<acronym>SCI</acronym>).</para>
+
+ <indexterm>
+ <primary>interrupt storms</primary>
+ </indexterm>
+
+ <para>Interrupt storms can be distinguished from lost interrupts
+ by checking the output of <command>vmstat -i</command>
+ and looking at the line that has
+ <literal>acpi0</literal>. 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 <acronym>DDB</acronym>
+ (<keycombo action="simul"><keycap>CTRL</keycap>
+ <keycap>ALT</keycap><keycap>ESC</keycap></keycombo> on
+ console) and type <literal>show interrupts</literal>.</para>
+
+ <indexterm>
+ <primary>APIC</primary>
+ <secondary>disabling</secondary>
+ </indexterm>
+
+ <para>Your best hope when dealing with interrupt problems is to
+ try disabling <acronym>APIC</acronym> support with
+ <literal>hint.apic.0.disabled="1"</literal> in
+ <filename>loader.conf</filename>.</para>
+ </sect3>
+
+ <sect3>
+ <title>Panics</title>
+
+ <para>Panics are relatively rare for <acronym>ACPI</acronym> 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
+ <literal>options DDB</literal> and setting up a serial console
+ (see <xref linkend="serialconsole-ddb"/>)
+ or setting up a &man.dump.8; partition. You can get a
+ backtrace in <acronym>DDB</acronym> with
+ <literal>tr</literal>. 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.</para>
+
+ <para>Then, try to isolate the problem by booting with
+ <acronym>ACPI</acronym> disabled. If that works, you can
+ isolate the <acronym>ACPI</acronym> subsystem by using various
+ values of <option>debug.acpi.disable</option>. See the
+ &man.acpi.4; manual page for some examples.</para>
+ </sect3>
+
+ <sect3>
+ <title>System Powers Up After Suspend or Shutdown</title>
+ <para>First, try setting
+ <literal>hw.acpi.disable_on_poweroff="0"</literal>
+ in &man.loader.conf.5;. This keeps <acronym>ACPI</acronym>
+ from disabling various events during the shutdown process.
+ Some systems need this value set to <literal>1</literal> (the
+ default) for the same reason. This usually fixes
+ the problem of a system powering up spontaneously after a
+ suspend or poweroff.</para>
+ </sect3>
+
+ <sect3>
+ <title>Other Problems</title>
+
+ <para>If you have other problems with <acronym>ACPI</acronym>
+ (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 <acronym>ACPI</acronym> subsystem so they might
+ take a while to be implemented. Please be patient and
+ prepared to test patches we may send you.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="ACPI-aslanddump">
+ <title><acronym>ASL</acronym>, <command>acpidump</command>, and
+ <acronym>IASL</acronym></title>
+
+ <indexterm>
+ <primary>ACPI</primary>
+ <secondary>ASL</secondary>
+ </indexterm>
+
+ <para>The most common problem is the <acronym>BIOS</acronym>
+ vendors providing incorrect (or outright buggy!) bytecode. This
+ is usually manifested by kernel console messages like
+ this:</para>
+
+ <screen>ACPI-1287: *** Error: Method execution failed [\\_SB_.PCI0.LPC0.FIGD._STA] \\
+(Node 0xc3f6d160), AE_NOT_FOUND</screen>
+
+ <para>Often, you can resolve these problems by updating your
+ <acronym>BIOS</acronym> 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 <acronym>AML</acronym>. The
+ bytecode, known as <acronym>AML</acronym>, is compiled from a
+ source language called <acronym>ASL</acronym>. The
+ <acronym>AML</acronym> is found in the table known as the
+ <acronym>DSDT</acronym>. To get a copy of your
+ <acronym>ASL</acronym>, use &man.acpidump.8;. You should use
+ both the <option>-t</option> (show contents of the fixed tables)
+ and <option>-d</option> (disassemble <acronym>AML</acronym> to
+ <acronym>ASL</acronym>) options. See the
+ <link linkend="ACPI-submitdebug">Submitting Debugging
+ Information</link> section for an example syntax.</para>
+
+ <para>The simplest first check you can do is to recompile your
+ <acronym>ASL</acronym> to check for errors. Warnings can
+ usually be ignored but errors are bugs that will usually prevent
+ <acronym>ACPI</acronym> from working correctly. To recompile
+ your <acronym>ASL</acronym>, issue the following command:</para>
+
+ <screen>&prompt.root; <userinput>iasl your.asl</userinput></screen>
+ </sect2>
+
+ <sect2 xml:id="ACPI-fixasl">
+ <title>Fixing Your <acronym>ASL</acronym></title>
+
+ <indexterm>
+ <primary>ACPI</primary>
+ <secondary>ASL</secondary>
+ </indexterm>
+
+ <para>In the long run, our goal is for almost everyone to have
+ <acronym>ACPI</acronym> work without any user intervention. At
+ this point, however, we are still developing workarounds for
+ common mistakes made by the <acronym>BIOS</acronym> vendors.
+ The &microsoft; interpreter (<filename>acpi.sys</filename> and
+ <filename>acpiec.sys</filename>) does not strictly check for
+ adherence to the standard, and thus many <acronym>BIOS</acronym>
+ vendors who only test <acronym>ACPI</acronym> under &windows;
+ never fix their <acronym>ASL</acronym>. We hope to continue to
+ identify and document exactly what non-standard behavior is
+ allowed by &microsoft;'s interpreter and replicate it so &os; can
+ work without forcing users to fix the <acronym>ASL</acronym>.
+ As a workaround and to help us identify behavior, you can fix
+ the <acronym>ASL</acronym> manually. If this works for you,
+ please send a &man.diff.1; of the old and new
+ <acronym>ASL</acronym> so we can possibly work around the buggy
+ behavior in <acronym>ACPI-CA</acronym> and thus make your fix
+ unnecessary.</para>
+
+ <indexterm>
+ <primary>ACPI</primary>
+ <secondary>error messages</secondary>
+ </indexterm>
+
+ <para>Here is a list of common error messages, their cause, and
+ how to fix them:</para>
+
+ <sect3>
+ <title>_OS dependencies</title>
+
+ <para>Some <acronym>AML</acronym> assumes the world consists of
+ various &windows; versions. You can tell &os; to claim it is
+ any <acronym>OS</acronym> to see if this fixes problems you
+ may have. An easy way to override this is to set
+ <literal>hw.acpi.osname="Windows 2001"</literal>
+ in <filename>/boot/loader.conf</filename> or other similar
+ strings you find in the <acronym>ASL</acronym>.</para>
+ </sect3>
+
+ <sect3>
+ <title>Missing Return statements</title>
+
+ <para>Some methods do not explicitly return a value as the
+ standard requires. While <acronym>ACPI-CA</acronym>
+ 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 <command>iasl</command> to compile the
+ <acronym>ASL</acronym>, use the <option>-f</option>
+ flag.</para>
+ </sect3>
+
+ <sect3>
+ <title>Overriding the Default <acronym>AML</acronym></title>
+
+ <para>After you customize <filename>your.asl</filename>, you
+ will want to compile it, run:</para>
+
+ <screen>&prompt.root; <userinput>iasl your.asl</userinput></screen>
+
+ <para>You can add the <option>-f</option> flag to force creation
+ of the <acronym>AML</acronym>, even if there are errors during
+ compilation. Remember that some errors (e.g., missing Return
+ statements) are automatically worked around by the
+ interpreter.</para>
+
+ <para><filename>DSDT.aml</filename> is the default output
+ filename for <command>iasl</command>. You can load this
+ instead of your <acronym>BIOS</acronym>'s buggy copy (which
+ is still present in flash memory) by editing
+ <filename>/boot/loader.conf</filename> as
+ follows:</para>
+
+ <programlisting>acpi_dsdt_load="YES"
+acpi_dsdt_name="/boot/DSDT.aml"</programlisting>
+
+ <para>Be sure to copy your <filename>DSDT.aml</filename> to the
+ <filename>/boot</filename> directory.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="ACPI-debugoutput">
+ <title>Getting Debugging Output From
+ <acronym>ACPI</acronym></title>
+
+ <indexterm>
+ <primary>ACPI</primary>
+ <secondary>problems</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>ACPI</primary>
+ <secondary>debugging</secondary>
+ </indexterm>
+
+ <para>The <acronym>ACPI</acronym> 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 <quote>layers</quote> and are broken down
+ into <acronym>ACPI-CA</acronym> components (ACPI_ALL_COMPONENTS)
+ and <acronym>ACPI</acronym> hardware support (ACPI_ALL_DRIVERS).
+ The verbosity of debugging output is specified as the
+ <quote>level</quote> and ranges from ACPI_LV_ERROR (just report
+ errors) to ACPI_LV_VERBOSE (everything). The
+ <quote>level</quote> 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.</para>
+
+ <para>Debugging output is not enabled by default. To enable it,
+ add <literal>options ACPI_DEBUG</literal> to your kernel configuration file
+ if <acronym>ACPI</acronym> is compiled into the kernel. You can
+ add <literal>ACPI_DEBUG=1</literal> to your
+ <filename>/etc/make.conf</filename> to enable it globally. If
+ it is a module, you can recompile just your
+ <filename>acpi.ko</filename> module as follows:</para>
+
+ <screen>&prompt.root; <userinput>cd /sys/modules/acpi/acpi
+&amp;&amp; make clean &amp;&amp;
+make ACPI_DEBUG=1</userinput></screen>
+
+ <para>Install <filename>acpi.ko</filename> in
+ <filename>/boot/kernel</filename> and add your
+ desired level and layer to <filename>loader.conf</filename>.
+ This example enables debug messages for all
+ <acronym>ACPI-CA</acronym> components and all
+ <acronym>ACPI</acronym> hardware drivers
+ (<acronym>CPU</acronym>, <acronym>LID</acronym>, etc.) It will
+ only output error messages, the least verbose level.</para>
+
+ <programlisting>debug.acpi.layer="ACPI_ALL_COMPONENTS ACPI_ALL_DRIVERS"
+debug.acpi.level="ACPI_LV_ERROR"</programlisting>
+
+ <para>If the information you want is triggered by a specific event
+ (say, a suspend and then resume), you can leave out changes to
+ <filename>loader.conf</filename> and instead use
+ <command>sysctl</command> to specify the layer and level after
+ booting and preparing your system for the specific event. The
+ <command>sysctl</command>s are named the same as the tunables
+ in <filename>loader.conf</filename>.</para>
+ </sect2>
+
+ <sect2 xml:id="ACPI-References">
+ <title>References</title>
+
+ <para>More information about <acronym>ACPI</acronym> may be found
+ in the following locations:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The &a.acpi;</para>
+ </listitem>
+
+ <listitem>
+ <para>The <acronym>ACPI</acronym> Mailing List Archives
+ <uri xlink:href="http://lists.freebsd.org/pipermail/freebsd-acpi/">http://lists.freebsd.org/pipermail/freebsd-acpi/</uri></para>
+ </listitem>
+
+ <listitem>
+ <para>The old <acronym>ACPI</acronym> Mailing List Archives
+ <uri xlink:href="http://home.jp.FreeBSD.org/mail-list/acpi-jp/">http://home.jp.FreeBSD.org/mail-list/acpi-jp/</uri></para>
+ </listitem>
+
+ <listitem>
+ <para>The <acronym>ACPI</acronym> 2.0 Specification
+ <uri xlink:href="http://acpi.info/spec.htm">http://acpi.info/spec.htm</uri></para>
+ </listitem>
+
+ <listitem>
+ <para>&os; Manual pages: &man.acpi.4;,
+ &man.acpi.thermal.4;, &man.acpidump.8;, &man.iasl.8;,
+ &man.acpidb.8;</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.cpqlinux.com/acpi-howto.html#fix_broken_dsdt">
+ <acronym>DSDT</acronym> debugging resource</link>.
+ (Uses Compaq as an example but generally useful.)</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/cutting-edge/Makefile b/zh_TW.UTF-8/books/handbook/cutting-edge/Makefile
new file mode 100644
index 0000000000..6ca842754f
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/cutting-edge/Makefile
@@ -0,0 +1,16 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+# Original revision: 1.1
+#
+
+CHAPTERS= cutting-edge/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/cutting-edge/chapter.xml b/zh_TW.UTF-8/books/handbook/cutting-edge/chapter.xml
new file mode 100644
index 0000000000..ef0d9a6c6d
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/cutting-edge/chapter.xml
@@ -0,0 +1,1535 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.225
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="cutting-edge">
+ <info><title>更新、升級 FreeBSD</title>
+ <authorgroup>
+ <author><personname><firstname>Jim</firstname><surname>Mock</surname></personname><contrib>Restructured, reorganized, and parts updated by </contrib></author>
+ <!-- Mar 2000 -->
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Jordan</firstname><surname>Hubbard</surname></personname><contrib>Original work by </contrib></author>
+ <author><personname><firstname>Poul-Henning</firstname><surname>Kamp</surname></personname></author>
+ <author><personname><firstname>John</firstname><surname>Polstra</surname></personname></author>
+ <author><personname><firstname>Nik</firstname><surname>Clayton</surname></personname></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <sect1 xml:id="cutting-edge-synopsis">
+ <title>概述</title>
+
+ <para>&os; 是個持續發展的作業系統。對於喜歡追求新鮮、刺激的使用者而言,
+ 有很多方法可以使您的系統輕鬆更新為最新版。
+ 注意:並非每個人都適合這麼做! 本章主要是協助您決定到底要跟開發版本,
+ 或是要使用較穩定的釋出版。
+ </para>
+
+ <para>讀完這章,您將了解︰</para>
+
+ <itemizedlist>
+ <listitem><para>&os.stable; 與 &os.current; 這兩分支的不同之處;</para>
+ </listitem>
+ <listitem><para>如何以
+ <application>CSup</application>,
+ <application>CVSup</application>,
+ <application>CVS</application> 或
+ <application>CTM</application> 來更新你的系統</para>
+ </listitem>
+ <listitem><para>如何以 <command>make buildworld</command>
+ 等指令來重新編譯、安裝整個 base system。</para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>在開始閱讀這章之前,您需要︰</para>
+
+ <itemizedlist>
+ <listitem><para>先設好你的網路(<xref linkend="advanced-networking"/>)。
+ </para>
+ </listitem>
+ <listitem><para>知道如何透過 port/package 安裝軟體(<xref linkend="ports"/>)。</para></listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="current-stable">
+ <title>&os.current; vs. &os.stable;</title>
+ <indexterm><primary>-CURRENT</primary></indexterm>
+ <indexterm><primary>-STABLE</primary></indexterm>
+
+ <para>FreeBSD 有兩個發展分支:&os.current; 及
+ &os.stable;。本節將會陸續介紹,並介紹它們分別又是如何更新。
+ 首先,先介紹 &os.current;,接著再介紹 &os.stable;。</para>
+
+ <sect2 xml:id="current">
+ <title>使用最新的 &os; CURRENT</title>
+
+ <para>這裡再次強調,&os.current; 是 &os; 開發的 <quote>最前線</quote>。
+ &os.current; 使用者須有較強的技術能力,
+ 而且應該要有能力自己解決困難的系統問題。 若您是 &os; 新手,
+ 那麼請在安裝前最好先三思。</para>
+
+ <sect3>
+ <title>什麼是 &os.current;?</title>
+ <indexterm><primary>snapshot</primary></indexterm>
+
+ <para>&os.current; 是 &os; 的最新版。它包含:
+ 仍在研發階段、實驗性質的修改、過渡時期的機制,
+ 這些東西在下一次正式 relase 的版本可能會有,也可能不會有的。
+ 儘管有許多 &os; 開發者每天都會編譯 &os.current; source code,
+ 但有時這些原始碼是無法編譯成功。 雖然,這些問題通常會儘快解決,
+ 但 &os.current; 到底是帶來浩劫或是多了想要用的新功能、改善,
+ 這點主要取決於您更新原始碼的時機為何而定!</para>
+ </sect3>
+
+ <sect3>
+ <title>誰需要 &os.current;?</title>
+
+ <para>&os.current; 適合下列這三類人:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>&os; 社群成員:積極專注於 source tree 的某一部份,
+ 以及認為保持為 <quote>current(最新狀態)</quote>
+ 為絕對需求的人。</para>
+ </listitem>
+
+ <listitem>
+ <para>&os; 社群成員:為了確保 &os.current;
+ 能夠儘可能地維持在最穩定的狀態,
+ 而主動花時間解決問題的測試者。 此外,還有對 &os;
+ 能提出具體建議以及改善方向,並提出 patch 修正檔的人。</para>
+ </listitem>
+
+ <listitem>
+ <para>只是關心或者想參考(比如,只是<emphasis>閱讀</emphasis>,
+ 而非執行)的人。
+ 這些人有時也會做些註解,或貢獻原始碼。</para>
+ </listitem>
+ </orderedlist>
+ </sect3>
+
+ <sect3>
+ <title>&os.current; <emphasis>並不是</emphasis> 什麼?</title>
+
+ <orderedlist>
+ <listitem>
+ <para>追求最新功能。 聽說裡面有些很酷的新功能,
+ 並希望成為您周圍的人中第一個嘗試的人,
+ 因此將 &os.current; 視為取得搶鮮版的捷徑。
+ 儘管,您能夠因此首先瞭解到最新的功能,
+ 但這也意味著若出現新的 bug 時,您也是首當其衝。</para>
+ </listitem>
+
+ <listitem>
+ <para>修復 bug 的速成法。 因為 &os.current;
+ 的任何版本在修復已知 bug 的同時,又可能會產生新的 bug。
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>無所不在的 <quote>officially supported</quote>。
+ 我們會盡力協助上述 &os.current; 的那三種類別的
+ <quote>legitimate</quote> 使用者,
+ 但我們<emphasis>沒時間</emphasis>為他們提供技術支援。
+ 這不代表我們很惡劣,或是不想幫助人(若是的話,
+ 我們也不會為 &os; 努力了)
+ ,實在是因為我們分身乏術,無法每天回答數百個問題,
+ <emphasis>而同時</emphasis>繼續開發 &os;。
+ 可以確定的一點就是,
+ 在改善 &os; 或是回答大量有關實驗碼的問題之間,
+ 若要做個選擇的話,開發者會選擇前者。</para>
+ </listitem>
+ </orderedlist>
+ </sect3>
+
+ <sect3>
+ <title>使用 &os.current;</title>
+
+ <orderedlist>
+ <listitem>
+ <para>加入 &a.current.name;<indexterm><primary>-CURRENT</primary><secondary>using</secondary></indexterm> 及 &a.cvsall.name; 論壇。
+ 這不單只是個建議,也是 <emphasis>必須</emphasis> 作的。
+ 若您沒訂閱 <emphasis>&a.current.name;</emphasis>
+ ,那麼就會錯過別人對目前系統狀態的說明,而枯耗在別人已解的問題。
+ 更重要的是,可能會錯失一些對己身所管系統安危相當重要的公告。
+ </para>
+
+ <para>在 &a.cvsall.name; 上則可以看到每個 commit 紀錄,
+ 因為這些記錄會連帶影響其他相關資訊。</para>
+
+ <para>要訂閱這些論壇或其他論壇,請參考 &a.mailman.lists.link;
+ 並點選想訂閱的部分即可。 至於其他後續步驟如何進行,
+ 在那裡會有說明。</para>
+ </listitem>
+
+ <listitem>
+ <para>從 &os; <link linkend="mirrors">mirror 站</link>
+ 取得原始碼。 有兩種方式可以達成:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>以 <link linkend="cvsup">csup</link><indexterm><primary><command>cvsup</command></primary></indexterm> 或
+ <link linkend="cvsup">cvsup</link> 程式搭配位於
+ <filename>/usr/share/examples/cvsup</filename> 檔名為
+ <filename>standard-supfile</filename> 的
+ <filename>supfile</filename>。
+ 這是大家最常推薦的方式,因為它可以讓您把整個 tree 都抓回來,
+ 之後就只取有更新的部分即可。
+ 此外,許多人會把 <command>csup</command> 或
+ <command>cvsup</command> 放到
+ <command>cron</command><indexterm><primary><command>cron</command></primary></indexterm> 以定期自動更新。
+ 您須要自訂前述的 <filename>supfile</filename> 範例檔,
+ 並針對自身網路環境以調整 <link linkend="cvsup">csup</link>
+ 或 <link linkend="cvsup">cvsup</link><indexterm><primary>-CURRENT</primary><secondary>Syncing with <application>CVSup</application></secondary></indexterm> 相關設定。</para>
+ </listitem>
+
+ <listitem>
+ <para>使用 <application>CTM</application><indexterm><primary>-CURRENT</primary><secondary>Syncing with CTM</secondary></indexterm> 工具。 若網路環境不佳
+ (上網費用貴,或只能用 email 而已)
+ <application>CTM</application> 會比較適合您的需求。
+ 然而,這也有一些爭議並且常抓到一些有問題的檔案。 因此,
+ 很少人會用它。 這也註定了不能長期依賴這個更新方式。
+ 若是使用 9600&nbsp;bps modem 或頻寬更大的上網者,建議使用
+ <application>CVSup</application>
+ 。</para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+
+ <listitem>
+ <para>若抓 source code 是要用來跑的,而不僅只是看看而已,
+ 那麼就抓 <emphasis>整個</emphasis> &os.current;,而不要只抓部分。
+ 因為大部分的 source code 都會相依到其他 source code 環節部分,
+ 若是您只編譯其中一部份,保證會很麻煩。</para>
+
+ <para>在編譯 &os.current;<indexterm><primary>-CURRENT</primary><secondary>compiling</secondary></indexterm> 之前,請仔細閱讀
+ <filename>/usr/src</filename> 內的 <filename>Makefile</filename>。
+ 儘管只是升級部分東西而已,您至少也要先 <link linkend="makeworld">
+ 裝新的 kernel 以及重新編譯 world</link>。 此外,多多閱讀
+ &a.current; 以及 <filename>/usr/src/UPDATING</filename>
+ 也是必須的,
+ 才能知道目前進度是怎樣以及下一版會有什麼新東西。</para>
+ </listitem>
+
+ <listitem>
+ <para>熱血!若您正在跑 &os.current;,
+ 我們很想知道您對於它的想法是什麼,尤其是加強哪些功能,
+ 或該修正哪些錯誤的建議。 如果您在建議時能附上相關程式碼的話,
+ 那真是太棒了!</para>
+ </listitem>
+ </orderedlist>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="stable">
+ <title>使用最新的 &os; STABLE</title>
+
+ <sect3>
+ <title>什麼是 &os.stable;?</title>
+ <indexterm><primary>-STABLE</primary></indexterm>
+
+ <para>&os.stable; 是我們的開發分支,主要的發行版就由此而來。
+ 這個分支會以不同速度作修改變化,並且假設這些是第一次進入 &os.current;
+ 進行測試。 然而,這 <emphasis>仍然</emphasis> 屬於開發中的分支,
+ 也就是說在某些時候,&os.stable; 可能會、也可能不會符合一些特殊需求。
+ 它只不過是另一個開發分支而已,可能不太適合一般使用者。</para>
+ </sect3>
+
+ <sect3>
+ <title>誰需要 &os.stable;?</title>
+
+ <para>若您有興趣去追蹤、貢獻 FreeBSD 開發過程或作些貢獻,
+ 尤其是會跟 FreeBSD 接下來的 <quote>關鍵性</quote> 發行有關,
+ 應該考慮採用 &os.stable;。</para>
+
+ <para>雖然安全漏洞的修補也會進入 &os.stable; 分支,
+ 但不必僅僅因此而 <emphasis>需要</emphasis> 去用 &os.stable;。
+ FreeBSD 每項 security advisory(安全公告)
+ 都會解說如何去修復有受到影響的版本
+ <footnote><para>然而,這也不一定是正確,我們不可能永遠支援 FreeBSD
+ 昔日的各種發行版本,儘管每個發行版發佈之後,都仍會持續支援數年之久。
+ 若欲瞭解 FreeBSD 目前對於舊版的支援政策細節,請參閱 <link xlink:href="&url.base;/security/">http://www.FreeBSD.org/security/</link>
+ 。</para>
+ </footnote>
+ ,若僅因為安全因素而去採用開發分支,雖然會解決現有已知問題,
+ 但也可能帶來一些潛藏的問題。</para>
+
+ <para>儘管我們盡力確保 &os.stable; 分支在任何時候均能正確編譯、運作,
+ 但沒人能夠擔保它隨時都可以符合上述目的。 此外,雖然原始碼在進入
+ &os.stable; 之前,都會先在 &os.current; 開發完畢,但使用 &os.current;
+ 的人畢竟遠比 &os.stable; 使用者來的少,所以通常有些問題,可能在
+ &os.current; 比較沒人注意到,隨著 &os.stable;
+ 使用者的廣泛使用才會浮現。</para>
+
+ <para>由於上述這些理由,我們<emphasis>並不推薦</emphasis> 盲目追隨
+ &os.stable;,而且更重要的是,別在原始碼尚未經完整測試之前,
+ 就衝動把 production server 轉移到 &os.stable; 環境。</para>
+
+ <para>若您沒有這些多的時間、精神的話,那推薦您使用最新的 FreeBSD
+ 發行版即可,並採用其所提供的 binary 更新機制來完成升級轉移。</para>
+ </sect3>
+
+ <sect3>
+ <title>使用 &os.stable;</title>
+
+ <orderedlist>
+ <listitem>
+ <para>訂閱 &a.stable.name;<indexterm><primary>-STABLE</primary><secondary>using</secondary></indexterm> list。 可以讓您隨時瞭解 &os.stable;
+ 的軟體編譯時的相依關係,以及其他需特別注意的問題。
+ 開發者在考慮一些有爭議的修正或更新時,就會先在這裡發信說明,
+ 給使用者有機會可以反應,
+ 看他們對所提的更改是否有什麼建議或問題。</para>
+
+ <para>而 &a.cvsall.name; list 這邊可以看到每個 commit log,
+ 其中包括了許多中肯的資訊,例如一些可能發生的邊際效應等等。</para>
+
+ <para>想要加入這些通信論壇的話,只要到 &a.mailman.lists.link;
+ 點下想訂閱的 list 即可。 其餘的步驟在網頁上會有說明。</para>
+ </listitem>
+
+ <listitem>
+ <para>若打算要安裝一個全新的系統,並且希望裝 &os.stable;
+ 每月定期的 snapshot,那麼請參閱 <link xlink:href="&url.base;/snapshots/">Snapshots</link> 網頁以瞭解相關細節。
+ 此外,也可從 <link linkend="mirrors">mirror 站</link>
+ 來安裝最新的 &os.stable; 發行版,並透過下列的的說明來更新到最新的
+ &os.stable; 原始碼。</para>
+
+ <para>若已裝的是 &os; 以前的版本,而想透過原始碼方式來升級,
+ 那麼也是可以利用 &os; <link linkend="mirrors">mirror 站</link>
+ 來完成。 以下介紹兩種方式:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>以 <link linkend="cvsup">csup</link><indexterm><primary><command>cvsup</command></primary></indexterm> 或
+ <link linkend="cvsup">cvsup</link> 程式搭配位於
+ <filename>/usr/share/examples/cvsup</filename> 檔名為
+ <filename>stable-supfile</filename> 的
+ <filename>supfile</filename>。 這是大家最常推薦的方式,
+ 因為它可以讓你把整個 tree 都抓回來,
+ 之後就只取有更新的部分即可。
+ 此外,許多人會把 <command>csup</command> 或
+ <command>cvsup</command> 放到 <command>cron</command><indexterm><primary><command>cron</command></primary></indexterm>
+ 以定期自動更新。 您須要自訂前述的
+ <filename>supfile</filename> 範例檔,並針對自身網路環境以調整
+ <link linkend="cvsup">csup</link> 或
+ <link linkend="cvsup">cvsup</link><indexterm><primary>-STABLE</primary><secondary>syncing with <application>CVSup</application></secondary></indexterm> 相關設定。</para>
+ </listitem>
+
+ <listitem>
+ <para>使用 <application>CTM</application><indexterm><primary>-STABLE</primary><secondary>syncing with CTM</secondary></indexterm> 更新工具。
+ 若網路不快或網路費用貴,那麼可以考慮採用。</para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+
+ <listitem>
+ <para>一般而言,若常需存取最新原始碼,而不計較網路頻寬的話,
+ 可以使用 <command>csup</command> 或 <command>cvsup</command>
+ 或 <command>ftp</command>。 否則,就考慮
+ <application>CTM</application>。</para>
+ </listitem>
+
+ <listitem>
+ <para>在編譯 &os.stable;<indexterm><primary>-STABLE</primary><secondary>compiling</secondary></indexterm> 之前,請先仔細閱讀
+ <filename>/usr/src</filename> 內的 <filename>Makefile</filename>
+ 檔。 儘管只是升級部分東西而已,您至少也要先 <link linkend="makeworld">裝新的 kernel 以及重新編譯 world</link>。
+ 此外,多多閱讀 &a.stable; 以及
+ <filename>/usr/src/UPDATING</filename> 也是必備的,
+ 這樣才能知道目前進度是怎樣,以及下一版會有哪些新東西。</para>
+ </listitem>
+ </orderedlist>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="synching">
+ <title>更新你的 Source</title>
+
+ <para>&os; 計劃原始碼有許多透過網路(或 email)的方式來更新,
+ 無論是更新那一塊領域,這些全由您自行決定。 我們主要提供的是 <link linkend="anoncvs">Anonymous CVS</link>、<link linkend="cvsup">CVSup</link>
+ 、<link linkend="ctm">CTM</link>。</para>
+
+ <warning>
+ <para>雖然可以只更新部分原始碼,但唯一支援的更新流程是更新整個 tree,
+ 並且重編 userland(比如:由使用者去執行的所有程式,像是
+ <filename>/bin</filename>、<filename>/sbin</filename> 內的程式)以及
+ kernel 原始碼。
+ 若只更新部分的 source tree、或只有 kernel 部分、或只有 userland
+ 部分,通常會造成一些錯誤,像是:編譯錯誤、kernel panic、資料毀損等
+ 。</para>
+ </warning>
+
+ <indexterm>
+ <primary>CVS</primary>
+ <secondary>anonymous</secondary>
+ </indexterm>
+
+ <para><application>Anonymous CVS</application> 及
+ <application>CVSup</application> 均是採 <emphasis>pull</emphasis>
+ 模式來更新原始碼。 以 <application>CVSup</application> 為例,
+ 使用者(或 <command>cron</command> script)會執行 <command>cvsup</command>
+ 程式,後者會與某一台 <command>cvsupd</command> 伺服器作些互動,
+ 以更新相關原始碼檔案。 您所收到更新會是當時最新的,
+ 而且只會收到需更新的部分。 此外,也可以很輕鬆去設定要更新的範圍。
+ 更新會由伺服器跟本機比對之後,丟出當時您所需要的更新檔案給你。
+ <application>Anonymous CVS</application> 的概念相對於
+ <application>CVSup</application> 來得更簡單些,因為它只是
+ <application>CVS</application> 的延伸而已,一樣讓你可從遠端的
+ CVS repository 取出最新原始碼。 然而 <application>CVSup</application>
+ 在這方面會更有效率,不過 <application>Anonymous CVS</application>
+ 對新手而言,是用起來比較簡單。</para>
+
+ <indexterm>
+ <primary><application>CTM</application></primary>
+ </indexterm>
+ <para>另一種方式則是 <application>CTM</application>。
+ 它並不是以交談式介面來比對您所擁有的 sources 和伺服器上的 sources
+ 或是您取得的更新部份。 相反的,會有一個 script
+ 檔專門用來辨識變更過的檔案,這個程式是由 CTM 伺服器來執行,
+ 每天會比對數次,並把兩次執行期間內變更過的檔案加以壓縮,
+ 並給它們一個序號,然後就加以編碼(只用 printable ASCII 字元),
+ 並以 email 的方式寄出。 當您收到它的時候,這些 <quote>CTM deltas</quote>
+ 就可以由 &man.ctm.rmail.1; 程式來處理,該程式會自動解碼、確認、
+ 套用這些變更。 這程序比 <application>CVSup</application> 來說是快得多了,
+ 而且,這個模式對我們的伺服器來說是比較輕鬆的,因為這是一個
+ <emphasis>push</emphasis> 的模式,而非 <emphasis>pull</emphasis>
+ 的模式。</para>
+
+ <para>當然,這樣做也會帶來一些不便。 若不小心把您部份的程式清除掉了,
+ <application>CVSup</application> 會偵測出來,並自動為您把不足的部份補齊。
+ <application>CTM</application> 並不會為您做這些動作。
+ 若清掉了您的部份 source (而且沒備份),您可以從頭開始(從最新的 CVS
+ <quote>base delta</quote>)並用 <application>CTM</application> 來重建它們
+ ,或是用 <application>Anonymous CVS</application> 來完成,
+ 只要把不正確的地方砍掉,再重新做同步的動作即可。</para>
+ </sect1>
+
+ <sect1 xml:id="makeworld">
+ <title>重新編譯 <quote>world</quote></title>
+
+ <indexterm>
+ <primary>Rebuilding <quote>world</quote></primary>
+ </indexterm>
+ <para>在更新 &os; 的 source tree 到最新之後(無論是 &os.stable;、
+ &os.current; 等等),接下來就可以用這些 source tree 來重新編譯系統
+ 。</para>
+
+ <warning>
+ <title>做好備份</title>
+
+ <para>在作任何大動作 <emphasis>之前</emphasis>
+ 要記得先把系統作備份的重要性無須強調。 儘管重新編譯 world 是
+ (只要有照文件指示去作的話)一件很簡單的事情,但出錯也是在所難免的。
+ 另外,別人在 source tree 不慎搞混的錯誤,也可能會造成系統無法開機
+ 。</para>
+
+ <para>請確認自己已作妥相關備份,並且手邊有 fixit 磁片或開機光碟。
+ 您可能永遠也用不到這些東西,
+ 但安全第一總比事後說抱歉來得好吧!</para>
+ </warning>
+
+ <warning>
+ <title>訂閱相關的 Mailing List</title>
+
+ <indexterm><primary>mailing list</primary></indexterm>
+ <para>&os.stable; 以及 &os.current; 分支,本質上就是屬於 <emphasis>
+ 開發階段</emphasis>。 為 &os; 作貢獻的也都是人,偶爾也會犯錯誤。</para>
+
+ <para>有時候這些錯誤並無大礙,只是會讓系統產生新的錯誤警告而已。
+ 有時則是災難,可能會導致不能開機或檔案系統的毀損(或更糟)。</para>
+
+ <para>若遇到類似問題,貼封標題為 <quote>heads up(注意)</quote>
+ 開頭的信到相關的 mailing list,並講清楚問題點以及會影響哪些系統。
+ 在問題獲解決後,再貼標題為 <quote>all clear(已解決)</quote>
+ 開頭的聲明信。</para>
+
+ <para>若用的是 &os.stable; 或 &os.current;,卻又不閱讀 &a.stable; 或
+ &a.current; 的討論,那麼會是自找麻煩而已。</para>
+ </warning>
+
+ <warning>
+ <title>不要用 <command>make world</command></title>
+
+ <para>一堆早期的舊文件都會建議說使用 <command>make world</command>。
+ 這樣做會跳過一些重要步驟,建議只有在你知道自己在作什麼,再這麼做。
+ 在絕大多數的情況下,請不要亂用 <command>make world</command>,
+ 而該改用下面介紹的方式。</para>
+ </warning>
+
+ <sect2>
+ <title>更新系統的標準方式</title>
+
+ <para>要升級系統前,一定要先查閱 <filename>/usr/src/UPDATING</filename>
+ 文件,以瞭解 buildworld 之前需要作哪些事情或注意事項,
+ 然後才用下列步驟:</para>
+
+ <screen>&prompt.root; <userinput>make buildworld</userinput>
+&prompt.root; <userinput>make buildkernel</userinput>
+&prompt.root; <userinput>make installkernel</userinput>
+&prompt.root; <userinput>reboot</userinput></screen>
+
+ <note>
+ <para>在少數狀況,可能需要先在 <buildtarget>buildworld</buildtarget>
+ 步驟之前先作 <command>mergemaster -p</command> 才能完成。
+ 至於何時需要或不需要,請參閱 <filename>UPDATING</filename> 內的說明。
+ 一般來說,只要不是進行跨版號(major)的 &os; 版本升級,
+ 就可略過這步驟。</para>
+ </note>
+
+ <para>完成 <buildtarget>installkernel</buildtarget> 之後,需要重開機並切到
+ single user 模式(舉例:也可以在 loader 提示符號後面加上
+ <command>boot -s</command>)。 接下來執行:</para>
+
+ <screen>&prompt.root; <userinput>mergemaster -p</userinput>
+&prompt.root; <userinput>make installworld</userinput>
+&prompt.root; <userinput>mergemaster</userinput>
+&prompt.root; <userinput>reboot</userinput></screen>
+
+ <warning>
+ <title>Read Further Explanations</title>
+
+ <para>上述步驟只是協助您升級的簡單說明而已,若要清楚瞭解每一步驟,
+ 尤其是若欲自行打造 kernel 設定,就更該閱讀下面的內容。</para>
+ </warning>
+ </sect2>
+
+ <sect2>
+ <title>閱讀 <filename>/usr/src/UPDATING</filename></title>
+
+ <para>在作任何事情之前,請務必先閱讀
+ <filename>/usr/src/UPDATING</filename> (或在 source code 內類似的文件)
+ 。 這份文件會寫到可能遭遇的問題,或指定那些會執行的指令順序為何。
+ 如果你機器現在的 <filename>UPDATING</filename>
+ 文件與這邊的描述有衝突、矛盾之處,那麼請以機器上的
+ <filename>UPDATING</filename> 為準。</para>
+
+ <important>
+ <para>然而,如同先前所述,單單只靠閱讀 <filename>UPDATING</filename>
+ 並不能完全取代 mailing list。 這兩者都是互補的,而不相排斥。</para>
+ </important>
+ </sect2>
+
+ <sect2>
+ <title>檢查 <filename>/etc/make.conf</filename></title>
+ <indexterm>
+ <primary><filename>make.conf</filename></primary>
+ </indexterm>
+
+ <para>檢查
+ <filename>/usr/share/examples/etc/make.conf</filename>
+ 以及
+ <filename>/etc/make.conf</filename>。 第一份文件乃是一些系統預設值
+ &ndash; 不過,大部分都被註解起來。 為了在重新編譯時能夠使用這些,
+ 請把這些設定加到 <filename>/etc/make.conf</filename>。 請注意在
+ <filename>/etc/make.conf</filename> 的任何設定也會影響到每次使用
+ <command>make</command> 的結果,
+ 因此設定一些適合自己系統的選項會是不錯的作法。</para>
+
+ <para>一般使用者通常會從
+ <filename>/usr/share/examples/etc/make.conf</filename> 複製
+ <varname>CFLAGS</varname> 以及 <varname>NO_PROFILE</varname>
+ 之類的設定到 <filename>/etc/make.conf</filename>,並解除相關註解印記
+ 。</para>
+
+ <para>此外,也可以試試看其他設定 (<varname>COPTFLAGS</varname>、
+ <varname>NOPORTDOCS</varname> 等等),是否符合自己所需。</para>
+ </sect2>
+
+ <sect2>
+ <title>更新 <filename>/etc</filename> 內的設定檔</title>
+
+ <para>在 <filename>/etc</filename> 目錄會有系統的相關設定檔,
+ 以及開機時的各項服務啟動 script。 有些 script 隨 FreeBSD
+ 版本的不同而有些差異。</para>
+
+ <para>其中有些設定檔會在每日運作的系統裡也會用到。 尤其是
+ <filename>/etc/group</filename>。</para>
+
+ <para>有時候在 <command>make installworld</command> 安裝過程中,
+ 會需要先建立某些特定帳號或群組。 在進行升級之前,它們可能並不存在,
+ 因此升級時就會造成問題。 有時候 <command>make buildworld</command>
+ 會先檢查這些所需的帳號或群組是否已有存在。</para>
+
+ <para>舉個這樣的例子,像是某次升級之後必須新增 <systemitem class="username">smmsp</systemitem>
+ 帳號。 若使用者尚未新增該帳號就要完成升級操作的話,
+ 會在 &man.mtree.8; 嘗試建立 <filename>/var/spool/clientmqueue</filename>
+ 時發生失敗。</para>
+
+ <para>解法是在 buildworld 階段之前,先執行 &man.mergemaster.8; 並搭配
+ <option>-p</option> 選項。 它會比對那些執行
+ <buildtarget>buildworld</buildtarget> 或
+ <buildtarget>installworld</buildtarget> 所需之關鍵設定檔。
+ 若你所用的是早期仍未支援 <option>-p</option> 的
+ <command>mergemaster</command> 版本,那麼直接使用 source tree
+ 內的新版即可:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src/usr.sbin/mergemaster</userinput>
+&prompt.root; <userinput>./mergemaster.sh -p</userinput></screen>
+
+ <tip>
+ <para>若您是偏執狂(paranoid),
+ 可以像下面這樣去試著檢查系統上有哪些檔案屬於已改名或被刪除的群組
+ :</para>
+
+ <screen>&prompt.root; <userinput>find / -group GID -print</userinput></screen>
+
+ <para>這會顯示所有符合要找的 <replaceable>GID</replaceable> 群組
+ (可以是群組名稱,或者是群組的數字代號)的所有檔案。</para>
+ </tip>
+ </sect2>
+
+ <sect2 xml:id="makeworld-singleuser">
+ <title>切換到 Single User 模式</title>
+ <indexterm><primary>single-user mode</primary></indexterm>
+
+ <para>您可能會想在 single user 模式下編譯系統。
+ 除了可以明顯更快完成之外,安裝過程中將會牽涉許多重要的系統檔案,
+ 包括所有系統 binaries、libraries、include 檔案等。
+ 若在運作中的系統(尤其有許多使用者在用的時候)內更改這些檔案,
+ 那簡直是自找麻煩的作法。</para>
+
+ <indexterm><primary>multi-user mode</primary></indexterm>
+ <para>另一種模式是先在 multi-user 模式下編譯好系統,然後再切到 single user
+ 模式去安裝。 若您比較喜歡這種方式,只需在 build(編譯過程) 完成之後,
+ 再去執行下面的步驟即可。 一直到可切換 single user 模式時,再去執行
+ <buildtarget>installkernel</buildtarget> 或
+ <buildtarget>installworld</buildtarget> 即可。</para>
+
+ <para>切換為 root 身份打:</para>
+
+ <screen>&prompt.root; <userinput>shutdown now</userinput></screen>
+
+ <para>這樣就會從原本的 multi-user 模式切換到 single user 模式。</para>
+
+ <para>除此之外也可以重開機,接著在開機選單處選擇
+ <quote>single user</quote> 選項。 如此一來就會進入 single user 模式,
+ 然後在 shell 提示符號處輸入:</para>
+
+ <screen>&prompt.root; <userinput>fsck -p</userinput>
+&prompt.root; <userinput>mount -u /</userinput>
+&prompt.root; <userinput>mount -a -t ufs</userinput>
+&prompt.root; <userinput>swapon -a</userinput></screen>
+
+ <para>這樣會先檢查檔案系統,並重新將 <filename>/</filename>
+ 改以可讀寫的模式掛載,以及 <filename>/etc/fstab</filename>
+ 內所設定的其他 UFS 檔案系統,最後啟用 swap 磁區。</para>
+
+
+ <note>
+ <para>若 CMOS 時鐘是設為當地時間,而非 GMT 時區(若 &man.date.1;
+ 指令沒顯示正確的時間、時區),那可能需要再輸入下列指令:</para>
+<screen>&prompt.root; <userinput>adjkerntz -i</userinput></screen>
+
+ <para>這步驟可以確認您的當地時區設定是否正確 &mdash;
+ 否則日後會造成一些問題。</para>
+ </note>
+
+ </sect2>
+
+ <sect2>
+ <title>移除 <filename>/usr/obj</filename></title>
+
+ <para>在重新編譯系統的過程中,編譯結果會放到(預設情況)
+ <filename>/usr/obj</filename> 內。 這裡面的目錄會對應到
+ <filename>/usr/src</filename> 的目錄結構。</para>
+
+ <para>砍掉這目錄,可以讓以後的 <command>make buildworld</command>
+ 過程更快一些,而且可避免以前編譯的東西跟現在的混淆在一起的相依錯亂
+ 。</para>
+
+ <para>而有些 <filename>/usr/obj</filename> 內的檔案可能會設定不可更動的
+ flag(細節請參閱 &man.chflags.1;),而必須先拿掉這些 flag 設定才行
+ 。</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/obj</userinput>
+&prompt.root; <userinput>chflags -R noschg *</userinput>
+&prompt.root; <userinput>rm -rf *</userinput></screen>
+ </sect2>
+
+ <sect2 xml:id="cutting-edge-compilebase">
+ <title>重新編譯 Base System</title>
+
+ <sect3>
+ <title>保留編譯的紀錄</title>
+
+ <para>建議養成好習慣,把執行 &man.make.1; 時產生的紀錄存起來。
+ 這樣若有哪邊出錯,就會有錯誤訊息的紀錄。 雖然單單這樣,
+ 你可能不知道如何分析是哪邊出了岔,但若把你問題記錄貼到 &os; 相關的
+ mailing list 就可以有人可以幫忙看是怎麼一回事情。</para>
+
+ <para>最簡單的方是就是用 &man.script.1; 指令,並加上參數
+ (你想存放記錄的檔案位置、檔名)即可。
+ 這步驟應該在重新編譯系統時就要作,然後在完成編譯後輸入
+ <userinput>exit</userinput> 即可離開。</para>
+
+ <screen>&prompt.root; <userinput>script /var/tmp/mw.out</userinput>
+Script started, output file is /var/tmp/mw.out
+&prompt.root; <userinput>make TARGET</userinput>
+<emphasis>&hellip; compile, compile, compile &hellip;</emphasis>
+&prompt.root; <userinput>exit</userinput>
+Script done, &hellip;</screen>
+
+ <para>對了,還有一點儘量<emphasis>別把</emphasis>檔案存到
+ <filename>/tmp</filename> 目錄內。 因為重開機之後,
+ 這目錄內的東西都會被清空。 比較妥善的地方是
+ <filename>/var/tmp</filename> (如上例所示) 或者是
+ <systemitem class="username">root</systemitem> 的家目錄。</para>
+ </sect3>
+
+ <sect3 xml:id="make-buildworld">
+ <title>編譯 Base System</title>
+
+ <para>首先請先切換到 <filename>/usr/src</filename> 目錄:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src</userinput></screen>
+
+ <para>(當然,除非你把 source code 放到其他地方,若真是這樣,
+ 就切換到那個目錄即可)。</para>
+ <indexterm><primary><command>make</command></primary></indexterm>
+
+ <para>使用 &man.make.1; 指令來重新編譯 world。
+ 這指令會從 <filename>Makefile</filename> 檔(這檔會寫 &os;
+ 的程式該如何重新編譯、以哪些順序來編譯等等)去讀取相關指令。</para>
+
+ <para>一般下指令的格式如下:</para>
+
+ <screen>&prompt.root; <userinput>make -x -DVARIABLE target</userinput></screen>
+
+ <para>在這個例子,<option>-<replaceable>x</replaceable></option>
+ 是你想傳給 &man.make.1; 的選項,細節說明請參閱 &man.make.1; 說明,
+ 裡面有相關範例說明。</para>
+
+ <para><option>-D<replaceable>VARIABLE</replaceable></option>
+ 則是把變數設定傳給 <filename>Makefile</filename>。 這些變數會控制
+ <filename>Makefile</filename> 的行為。 這些設定與
+ <filename>/etc/make.conf</filename> 的變數設定是一樣,
+ 只是另一種設定方式而已。</para>
+
+ <screen>&prompt.root; <userinput>make -DNO_PROFILE target</userinput></screen>
+
+ <para>上面的例子則是另一種設定方式,也就是哪些不要。
+ 這個例子中的意思是不去編譯 profiled libraries,效果就如同設定在
+ <filename>/etc/make.conf</filename> 的</para>
+
+ <programlisting>NO_PROFILE= true # Avoid compiling profiled libraries</programlisting>
+
+ <para><replaceable>target</replaceable> 則是告訴 &man.make.1;
+ 該去做哪些。 每個 <filename>Makefile</filename> 都會定義不同的
+ <quote>targets</quote>,然後依您所給的 target 就會決定會做哪些動作
+ 。</para>
+
+ <para>Some targets are listed in the
+ <filename>Makefile</filename>, but are not meant for you to run.
+ Instead, they are used by the build process to break out the
+ steps necessary to rebuild the system into a number of
+ sub-steps.</para>
+
+ <para>Most of the time you will not need to pass any parameters to
+ &man.make.1;, and so your command like will look like
+ this:</para>
+
+ <screen>&prompt.root; <userinput>make target</userinput></screen>
+
+ <para>Where <replaceable>target</replaceable> will be one of
+ many build options. The first target should always be
+ <varname>buildworld</varname>.</para>
+
+ <para>As the names imply, <buildtarget>buildworld</buildtarget>
+ builds a complete new tree under <filename>/usr/obj</filename>,
+ and <buildtarget>installworld</buildtarget>, another target, installs this tree on
+ the current machine.</para>
+
+ <para>Having separate options is very useful for two reasons. First, it allows you
+ to do the build safe in the knowledge that no components of
+ your running system will be affected. The build is
+ <quote>self hosted</quote>. Because of this, you can safely
+ run <buildtarget>buildworld</buildtarget> on a machine running
+ in multi-user mode with no fear of ill-effects. It is still
+ recommended that you run the
+ <buildtarget>installworld</buildtarget> part in single user
+ mode, though.</para>
+
+ <para>Secondly, it allows you to use NFS mounts to upgrade
+ multiple machines on your network. If you have three machines,
+ <systemitem>A</systemitem>, <systemitem>B</systemitem> and <systemitem>C</systemitem> that you want to upgrade, run <command>make
+ buildworld</command> and <command>make installworld</command> on
+ <systemitem>A</systemitem>. <systemitem>B</systemitem> and <systemitem>C</systemitem> should then NFS mount <filename>/usr/src</filename>
+ and <filename>/usr/obj</filename> from <systemitem>A</systemitem>, and you can then run
+ <command>make installworld</command> to install the results of
+ the build on <systemitem>B</systemitem> and <systemitem>C</systemitem>.</para>
+
+ <para>Although the <buildtarget>world</buildtarget> target still exists,
+ you are strongly encouraged not to use it.</para>
+
+ <para>Run</para>
+
+ <screen>&prompt.root; <userinput>make buildworld</userinput></screen>
+
+ <para>It is possible to specify a <option>-j</option> option to
+ <command>make</command> which will cause it to spawn several
+ simultaneous processes. This is most useful on multi-CPU machines.
+ However, since much of the compiling process is IO bound rather
+ than CPU bound it is also useful on single CPU machines.</para>
+
+ <para>On a typical single-CPU machine you would run:</para>
+
+ <screen>&prompt.root; <userinput>make -j4 buildworld</userinput></screen>
+
+ <para>&man.make.1; will then have up to 4 processes running at any one
+ time. Empirical evidence posted to the mailing lists shows this
+ generally gives the best performance benefit.</para>
+
+ <para>If you have a multi-CPU machine and you are using an SMP
+ configured kernel try values between 6 and 10 and see how they speed
+ things up.</para>
+ </sect3>
+
+ <sect3>
+ <title>Timings</title>
+ <indexterm>
+ <primary>rebuilding <quote>world</quote></primary>
+ <secondary>timings</secondary>
+ </indexterm>
+
+ <para>Many factors influence the build time, but fairly recent
+ machines may only take a one or two hours to build
+ the &os.stable; tree, with no tricks or shortcuts used during the
+ process. A &os.current; tree will take somewhat longer.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Compile and Install a New Kernel</title>
+ <indexterm>
+ <primary>kernel</primary>
+ <secondary>compiling</secondary>
+ </indexterm>
+
+ <para>To take full advantage of your new system you should recompile the
+ kernel. This is practically a necessity, as certain memory structures
+ may have changed, and programs like &man.ps.1; and &man.top.1; will
+ fail to work until the kernel and source code versions are the
+ same.</para>
+
+ <para>The simplest, safest way to do this is to build and install a
+ kernel based on <filename>GENERIC</filename>. While
+ <filename>GENERIC</filename> may not have all the necessary devices
+ for your system, it should contain everything necessary to boot your
+ system back to single user mode. This is a good test that the new
+ system works properly. After booting from
+ <filename>GENERIC</filename> and verifying that your system works you
+ can then build a new kernel based on your normal kernel configuration
+ file.</para>
+
+ <para>On &os; it is important to <link linkend="make-buildworld">build world</link> before building a
+ new kernel.</para>
+
+ <note><para>If you want to build a custom kernel, and already have a configuration
+ file, just use <literal>KERNCONF=MYKERNEL</literal>
+ like this:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src</userinput>
+&prompt.root; <userinput>make buildkernel KERNCONF=MYKERNEL</userinput>
+&prompt.root; <userinput>make installkernel KERNCONF=MYKERNEL</userinput></screen>
+ </note>
+
+ <para>Note that if you have raised <literal>kern.securelevel</literal>
+ above 1 <emphasis>and</emphasis> you have set either the
+ <literal>noschg</literal> or similar flags to your kernel binary, you
+ might find it necessary to drop into single user mode to use
+ <buildtarget>installkernel</buildtarget>. Otherwise you should be able
+ to run both these commands from multi user mode without
+ problems. See &man.init.8; for details about
+ <literal>kern.securelevel</literal> and &man.chflags.1; for details
+ about the various file flags.</para>
+ </sect2>
+
+ <sect2>
+ <title>Reboot into Single User Mode</title>
+ <indexterm><primary>single-user mode</primary></indexterm>
+
+ <para>You should reboot into single user mode to test the new kernel
+ works. Do this by following the instructions in
+ <xref linkend="makeworld-singleuser"/>.</para>
+ </sect2>
+
+ <sect2 xml:id="make-installworld">
+ <title>Install the New System Binaries</title>
+
+ <para>If you were building a version of &os; recent enough to have
+ used <command>make buildworld</command> then you should now use
+ <buildtarget>installworld</buildtarget> to install the new system
+ binaries.</para>
+
+ <para>Run</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src</userinput>
+&prompt.root; <userinput>make installworld</userinput></screen>
+
+ <note>
+ <para>If you specified variables on the <command>make
+ buildworld</command> command line, you must specify the same
+ variables in the <command>make installworld</command> command
+ line. This does not necessarily hold true for other options;
+ for example, <option>-j</option> must never be used with
+ <buildtarget>installworld</buildtarget>.</para>
+
+ <para>For example, if you ran:</para>
+
+ <screen>&prompt.root; <userinput>make -DNO_PROFILE buildworld</userinput></screen>
+
+ <para>you must install the results with:</para>
+
+ <screen>&prompt.root; <userinput>make -DNO_PROFILE installworld</userinput></screen>
+
+ <para>otherwise it would try to install profiled libraries that
+ had not been built during the <command>make buildworld</command>
+ phase.</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Update Files Not Updated by <command>make installworld</command></title>
+
+ <para>Remaking the world will not update certain directories (in
+ particular, <filename>/etc</filename>, <filename>/var</filename> and
+ <filename>/usr</filename>) with new or changed configuration files.</para>
+
+ <para>The simplest way to update these files is to use
+ &man.mergemaster.8;, though it is possible to do it manually
+ if you would prefer to do that. Regardless of which way you
+ choose, be sure to make a backup of <filename>/etc</filename> in
+ case anything goes wrong.</para>
+
+ <sect3 xml:id="mergemaster">
+ <info><title><command>mergemaster</command></title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+ <indexterm><primary><command>mergemaster</command></primary></indexterm>
+
+ <para>The &man.mergemaster.8; utility is a Bourne script that will
+ aid you in determining the differences between your configuration files
+ in <filename>/etc</filename>, and the configuration files in
+ the source tree <filename>/usr/src/etc</filename>. This is
+ the recommended solution for keeping the system configuration files up to date
+ with those located in the source tree.</para>
+
+ <para>To begin simply type <command>mergemaster</command> at your prompt, and
+ watch it start going. <command>mergemaster</command> will then build a
+ temporary root environment, from <filename>/</filename> down, and populate
+ it with various system configuration files. Those files are then compared
+ to the ones currently installed in your system. At this point, files that
+ differ will be shown in &man.diff.1; format, with the <option>+</option> sign
+ representing added or modified lines, and <option>-</option> representing
+ lines that will be either removed completely, or replaced with a new line.
+ See the &man.diff.1; manual page for more information about the &man.diff.1;
+ syntax and how file differences are shown.</para>
+
+ <para>&man.mergemaster.8; will then show you each file that displays variances,
+ and at this point you will have the option of either deleting the new file (referred
+ to as the temporary file), installing the temporary file in its unmodified state,
+ merging the temporary file with the currently installed file, or viewing the
+ &man.diff.1; results again.</para>
+
+ <para>Choosing to delete the temporary file will tell &man.mergemaster.8; that we
+ wish to keep our current file unchanged, and to delete the new version.
+ This option is not recommended, unless you see no
+ reason to change the current file. You can get help at any time by
+ typing <keycap>?</keycap> at the &man.mergemaster.8; prompt. If the user
+ chooses to skip a file, it will be presented again after all other files
+ have been dealt with.</para>
+
+ <para>Choosing to install the unmodified temporary file will replace the
+ current file with the new one. For most unmodified files, this is the best
+ option.</para>
+
+ <para>Choosing to merge the file will present you with a text editor,
+ and the contents of both files. You can now merge them by
+ reviewing both files side by side on the screen, and choosing parts from
+ both to create a finished product. When the files are compared side by side,
+ the <keycap>l</keycap> key will select the left contents and the
+ <keycap>r</keycap> key will select contents from your right.
+ The final output will be a file consisting of both parts, which can then be
+ installed. This option is customarily used for files where settings have been
+ modified by the user.</para>
+
+ <para>Choosing to view the &man.diff.1; results again will show you the file differences
+ just like &man.mergemaster.8; did before prompting you for an option.</para>
+
+ <para>After &man.mergemaster.8; is done with the system files you will be
+ prompted for other options. &man.mergemaster.8; may ask if you want to rebuild
+ the password file and will finish up with an option to
+ remove left-over temporary files.</para>
+ </sect3>
+
+ <sect3>
+ <title>Manual Update</title>
+
+ <para>If you wish to do the update manually, however,
+ you cannot just copy over the files from
+ <filename>/usr/src/etc</filename> to <filename>/etc</filename> and
+ have it work. Some of these files must be <quote>installed</quote>
+ first. This is because the <filename>/usr/src/etc</filename>
+ directory <emphasis>is not</emphasis> a copy of what your
+ <filename>/etc</filename> directory should look like. In addition,
+ there are files that should be in <filename>/etc</filename> that are
+ not in <filename>/usr/src/etc</filename>.</para>
+
+ <para>If you are using &man.mergemaster.8; (as recommended),
+ you can skip forward to the <link linkend="cutting-edge-rebooting">next
+ section</link>.</para>
+
+ <para>The simplest way to do this by hand is to install the
+ files into a new directory, and then work through them looking
+ for differences.</para>
+
+ <warning>
+ <title>Backup Your Existing <filename>/etc</filename></title>
+
+ <para>Although, in theory, nothing is going to touch this directory
+ automatically, it is always better to be sure. So copy your
+ existing <filename>/etc</filename> directory somewhere safe.
+ Something like:</para>
+
+ <screen>&prompt.root; <userinput>cp -Rp /etc /etc.old</userinput></screen>
+
+ <para><option>-R</option> does a recursive copy, <option>-p</option>
+ preserves times, ownerships on files and suchlike.</para>
+ </warning>
+
+ <para>You need to build a dummy set of directories to install the new
+ <filename>/etc</filename> and other files into.
+ <filename>/var/tmp/root</filename> is a reasonable choice, and
+ there are a number of subdirectories required under this as
+ well.</para>
+
+ <screen>&prompt.root; <userinput>mkdir /var/tmp/root</userinput>
+&prompt.root; <userinput>cd /usr/src/etc</userinput>
+&prompt.root; <userinput>make DESTDIR=/var/tmp/root distrib-dirs distribution</userinput></screen>
+
+ <para>This will build the necessary directory structure and install the
+ files. A lot of the subdirectories that have been created under
+ <filename>/var/tmp/root</filename> are empty and should be deleted.
+ The simplest way to do this is to:</para>
+
+ <screen>&prompt.root; <userinput>cd /var/tmp/root</userinput>
+&prompt.root; <userinput>find -d . -type d | xargs rmdir 2&gt;/dev/null</userinput></screen>
+
+ <para>This will remove all empty directories. (Standard error is
+ redirected to <filename>/dev/null</filename> to prevent the warnings
+ about the directories that are not empty.)</para>
+
+ <para><filename>/var/tmp/root</filename> now contains all the files that
+ should be placed in appropriate locations below
+ <filename>/</filename>. You now have to go through each of these
+ files, determining how they differ with your existing files.</para>
+
+ <para>Note that some of the files that will have been installed in
+ <filename>/var/tmp/root</filename> have a leading <quote>.</quote>. At the
+ time of writing the only files like this are shell startup files in
+ <filename>/var/tmp/root/</filename> and
+ <filename>/var/tmp/root/root/</filename>, although there may be others
+ (depending on when you are reading this). Make sure you use
+ <command>ls -a</command> to catch them.</para>
+
+ <para>The simplest way to do this is to use &man.diff.1; to compare the
+ two files:</para>
+
+ <screen>&prompt.root; <userinput>diff /etc/shells /var/tmp/root/etc/shells</userinput></screen>
+
+ <para>This will show you the differences between your
+ <filename>/etc/shells</filename> file and the new
+ <filename>/var/tmp/root/etc/shells</filename> file. Use these to decide whether to
+ merge in changes that you have made or whether to copy over your old
+ file.</para>
+
+ <tip>
+ <title>Name the New Root Directory
+ (<filename>/var/tmp/root</filename>) with a Time Stamp, so You Can
+ Easily Compare Differences Between Versions</title>
+
+ <para>Frequently rebuilding the world means that you have to update
+ <filename>/etc</filename> frequently as well, which can be a bit of
+ a chore.</para>
+
+ <para>You can speed this process up by keeping a copy of the last set
+ of changed files that you merged into <filename>/etc</filename>.
+ The following procedure gives one idea of how to do this.</para>
+
+ <procedure>
+ <step>
+ <para>Make the world as normal. When you want to update
+ <filename>/etc</filename> and the other directories, give the
+ target directory a name based on the current date. If you were
+ doing this on the 14th of February 1998 you could do the
+ following:</para>
+
+ <screen>&prompt.root; <userinput>mkdir /var/tmp/root-19980214</userinput>
+&prompt.root; <userinput>cd /usr/src/etc</userinput>
+&prompt.root; <userinput>make DESTDIR=/var/tmp/root-19980214 \
+ distrib-dirs distribution</userinput></screen>
+ </step>
+
+ <step>
+ <para>Merge in the changes from this directory as outlined
+ above.</para>
+
+ <para><emphasis>Do not</emphasis> remove the
+ <filename>/var/tmp/root-19980214</filename> directory when you
+ have finished.</para>
+ </step>
+
+ <step>
+ <para>When you have downloaded the latest version of the source
+ and remade it, follow step 1. This will give you a new
+ directory, which might be called
+ <filename>/var/tmp/root-19980221</filename> (if you wait a week
+ between doing updates).</para>
+ </step>
+
+ <step>
+ <para>You can now see the differences that have been made in the
+ intervening week using &man.diff.1; to create a recursive diff
+ between the two directories:</para>
+
+ <screen>&prompt.root; <userinput>cd /var/tmp</userinput>
+&prompt.root; <userinput>diff -r root-19980214 root-19980221</userinput></screen>
+
+ <para>Typically, this will be a much smaller set of differences
+ than those between
+ <filename>/var/tmp/root-19980221/etc</filename> and
+ <filename>/etc</filename>. Because the set of differences is
+ smaller, it is easier to migrate those changes across into your
+ <filename>/etc</filename> directory.</para>
+ </step>
+
+ <step>
+ <para>You can now remove the older of the two
+ <filename>/var/tmp/root-*</filename> directories:</para>
+
+ <screen>&prompt.root; <userinput>rm -rf /var/tmp/root-19980214</userinput></screen>
+ </step>
+
+ <step>
+ <para>Repeat this process every time you need to merge in changes
+ to <filename>/etc</filename>.</para>
+ </step>
+ </procedure>
+
+ <para>You can use &man.date.1; to automate the generation of the
+ directory names:</para>
+
+ <screen>&prompt.root; <userinput>mkdir /var/tmp/root-`date "+%Y%m%d"`</userinput></screen>
+ </tip>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="cutting-edge-rebooting">
+ <title>Rebooting</title>
+
+ <para>You are now done. After you have verified that everything appears
+ to be in the right place you can reboot the system. A simple
+ &man.shutdown.8; should do it:</para>
+
+ <screen>&prompt.root; <userinput>shutdown -r now</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Finished</title>
+
+ <para>You should now have successfully upgraded your &os; system.
+ Congratulations.</para>
+
+ <para>If things went slightly wrong, it is easy to rebuild a particular
+ piece of the system. For example, if you accidentally deleted
+ <filename>/etc/magic</filename> as part of the upgrade or merge of
+ <filename>/etc</filename>, the &man.file.1; command will stop working.
+ In this case, the fix would be to run:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src/usr.bin/file</userinput>
+&prompt.root; <userinput>make all install</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Questions</title>
+
+ <qandaset>
+ <qandaentry>
+ <question>
+ <para>Do I need to re-make the world for every change?</para>
+ </question>
+
+ <answer>
+ <para>There is no easy answer to this one, as it depends on the
+ nature of the change. For example, if you just ran <application>CVSup</application>, and
+ it has shown the following files as being updated:</para>
+
+ <screen><filename>src/games/cribbage/instr.c</filename>
+<filename>src/games/sail/pl_main.c</filename>
+<filename>src/release/sysinstall/config.c</filename>
+<filename>src/release/sysinstall/media.c</filename>
+<filename>src/share/mk/bsd.port.mk</filename></screen>
+
+ <para>it probably is not worth rebuilding the entire world.
+ You could just go to the appropriate sub-directories and
+ <command>make all install</command>, and that's about it. But
+ if something major changed, for example
+ <filename>src/lib/libc/stdlib</filename> then you should either
+ re-make the world, or at least those parts of it that are
+ statically linked (as well as anything else you might have added
+ that is statically linked).</para>
+
+ <para>At the end of the day, it is your call. You might be happy
+ re-making the world every fortnight say, and let changes
+ accumulate over that fortnight. Or you might want to re-make
+ just those things that have changed, and be confident you can
+ spot all the dependencies.</para>
+
+ <para>And, of course, this all depends on how often you want to
+ upgrade, and whether you are tracking &os.stable; or
+ &os.current;.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>My compile failed with lots of signal 11<indexterm>
+ <primary>signal 11</primary></indexterm> (or other signal
+ number) errors. What has happened?</para>
+ </question>
+
+ <answer>
+ <para>This is normally indicative of hardware problems.
+ (Re)making the world is an effective way to stress test your
+ hardware, and will frequently throw up memory problems. These
+ normally manifest themselves as the compiler mysteriously dying
+ on receipt of strange signals.</para>
+
+ <para>A sure indicator of this is if you can restart the make and
+ it dies at a different point in the process.</para>
+
+ <para>In this instance there is little you can do except start
+ swapping around the components in your machine to determine
+ which one is failing.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>Can I remove <filename>/usr/obj</filename> when I have
+ finished?</para>
+ </question>
+
+ <answer>
+ <para>The short answer is yes.</para>
+
+ <para><filename>/usr/obj</filename> contains all the object files
+ that were produced during the compilation phase. Normally, one
+ of the first steps in the <command>make buildworld</command> process is to
+ remove this directory and start afresh. In this case, keeping
+ <filename>/usr/obj</filename> around after you have finished
+ makes little sense, and will free up a large chunk of disk space
+ (currently about 340&nbsp;MB).</para>
+
+ <para>However, if you know what you are doing you can have
+ <command>make buildworld</command> skip this step. This will make subsequent
+ builds run much faster, since most of sources will not need to
+ be recompiled. The flip side of this is that subtle dependency
+ problems can creep in, causing your build to fail in odd ways.
+ This frequently generates noise on the &os; mailing lists,
+ when one person complains that their build has failed, not
+ realizing that it is because they have tried to cut
+ corners.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>Can interrupted builds be resumed?</para>
+ </question>
+
+ <answer>
+ <para>This depends on how far through the process you got before
+ you found a problem.</para>
+
+ <para><emphasis>In general</emphasis> (and this is not a hard and
+ fast rule) the <command>make buildworld</command> process builds new
+ copies of essential tools (such as &man.gcc.1;, and
+ &man.make.1;) and the system libraries. These tools and
+ libraries are then installed. The new tools and libraries are
+ then used to rebuild themselves, and are installed again. The
+ entire system (now including regular user programs, such as
+ &man.ls.1; or &man.grep.1;) is then rebuilt with the new
+ system files.</para>
+
+ <para>If you are at the last stage, and you know it (because you
+ have looked through the output that you were storing) then you
+ can (fairly safely) do:</para>
+
+ <screen><emphasis>&hellip; fix the problem &hellip;</emphasis>
+&prompt.root; <userinput>cd /usr/src</userinput>
+&prompt.root; <userinput>make -DNO_CLEAN all</userinput></screen>
+
+ <para>This will not undo the work of the previous
+ <command>make buildworld</command>.</para>
+
+ <para>If you see the message:</para>
+
+ <screen>--------------------------------------------------------------
+Building everything..
+--------------------------------------------------------------</screen>
+
+ <para>in the <command>make buildworld</command> output then it is
+ probably fairly safe to do so.</para>
+
+ <para>If you do not see that message, or you are not sure, then it
+ is always better to be safe than sorry, and restart the build
+ from scratch.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>How can I speed up making the world?</para>
+ </question>
+
+ <answer>
+ <itemizedlist>
+ <listitem>
+ <para>Run in single user mode.</para>
+ </listitem>
+
+ <listitem>
+ <para>Put the <filename>/usr/src</filename> and
+ <filename>/usr/obj</filename> directories on separate
+ file systems held on separate disks. If possible, put these
+ disks on separate disk controllers.</para>
+ </listitem>
+
+ <listitem>
+ <para>Better still, put these file systems across multiple
+ disks using the &man.ccd.4; (concatenated disk
+ driver) device.</para>
+ </listitem>
+
+ <listitem>
+ <para>Turn off profiling (set <quote>NO_PROFILE=true</quote> in
+ <filename>/etc/make.conf</filename>). You almost certainly
+ do not need it.</para>
+ </listitem>
+
+ <listitem>
+ <para>Also in <filename>/etc/make.conf</filename>, set
+ <varname>CFLAGS</varname> to something like <option>-O
+ -pipe</option>. The optimization <option>-O2</option> is much
+ slower, and the optimization difference between
+ <option>-O</option> and <option>-O2</option> is normally
+ negligible. <option>-pipe</option> lets the compiler use
+ pipes rather than temporary files for communication, which
+ saves disk access (at the expense of memory).</para>
+ </listitem>
+
+ <listitem>
+ <para>Pass the <option>-j<replaceable>n</replaceable></option> option to &man.make.1; to
+ run multiple processes in parallel. This usually helps
+ regardless of whether you have a single or a multi processor
+ machine.</para>
+ </listitem>
+
+ <listitem><para>The file system holding
+ <filename>/usr/src</filename> can be mounted (or remounted)
+ with the <option>noatime</option> option. This prevents the
+ file system from recording the file access time. You probably
+ do not need this information anyway.</para>
+
+ <screen>&prompt.root; <userinput>mount -u -o noatime /usr/src</userinput></screen>
+
+ <warning>
+ <para>The example assumes <filename>/usr/src</filename> is
+ on its own file system. If it is not (if it is a part of
+ <filename>/usr</filename> for example) then you will
+ need to use that file system mount point, and not
+ <filename>/usr/src</filename>.</para>
+ </warning>
+ </listitem>
+
+ <listitem>
+ <para>The file system holding <filename>/usr/obj</filename> can
+ be mounted (or remounted) with the <option>async</option>
+ option. This causes disk writes to happen asynchronously.
+ In other words, the write completes immediately, and the
+ data is written to the disk a few seconds later. This
+ allows writes to be clustered together, and can be a
+ dramatic performance boost.</para>
+
+ <warning>
+ <para>Keep in mind that this option makes your file system
+ more fragile. With this option there is an increased
+ chance that, should power fail, the file system will be in
+ an unrecoverable state when the machine restarts.</para>
+
+ <para>If <filename>/usr/obj</filename> is the only thing on
+ this file system then it is not a problem. If you have
+ other, valuable data on the same file system then ensure
+ your backups are fresh before you enable this
+ option.</para>
+ </warning>
+
+ <screen>&prompt.root; <userinput>mount -u -o async /usr/obj</userinput></screen>
+
+ <warning>
+ <para>As above, if <filename>/usr/obj</filename> is not on
+ its own file system, replace it in the example with the
+ name of the appropriate mount point.</para>
+ </warning>
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>What do I do if something goes wrong?</para>
+ </question>
+
+ <answer>
+ <para>Make absolutely sure your environment has no
+ extraneous cruft from earlier builds. This is simple
+ enough.</para>
+
+ <screen>&prompt.root; <userinput>chflags -R noschg /usr/obj/usr</userinput>
+&prompt.root; <userinput>rm -rf /usr/obj/usr</userinput>
+&prompt.root; <userinput>cd /usr/src</userinput>
+&prompt.root; <userinput>make cleandir</userinput>
+&prompt.root; <userinput>make cleandir</userinput></screen>
+
+ <para>Yes, <command>make cleandir</command> really should
+ be run twice.</para>
+
+ <para>Then restart the whole process, starting
+ with <command>make buildworld</command>.</para>
+
+ <para>If you still have problems, send the error and the
+ output of <command>uname -a</command> to &a.questions;.
+ Be prepared to answer other questions about your
+ setup!</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="small-lan">
+ <info><title>Tracking for Multiple Machines</title>
+ <authorgroup>
+ <author><personname><firstname>Mike</firstname><surname>Meyer</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+ <indexterm>
+ <primary>NFS</primary>
+ <secondary>installing multiple machines</secondary>
+ </indexterm>
+
+ <para>If you have multiple machines that you want to track the
+ same source tree, then having all of them download sources and
+ rebuild everything seems like a waste of resources: disk space,
+ network bandwidth, and CPU cycles. It is, and the solution is
+ to have one machine do most of the work, while the rest of the
+ machines mount that work via NFS. This section outlines a
+ method of doing so.</para>
+
+ <sect2 xml:id="small-lan-preliminaries">
+ <title>Preliminaries</title>
+
+ <para>First, identify a set of machines that is going to run
+ the same set of binaries, which we will call a
+ <emphasis>build set</emphasis>. Each machine can have a
+ custom kernel, but they will be running the same userland
+ binaries. From that set, choose a machine to be the
+ <emphasis>build machine</emphasis>. It is going to be the
+ machine that the world and kernel are built on. Ideally, it
+ should be a fast machine that has sufficient spare CPU to
+ run <command>make buildworld</command> and
+ <command>make buildkernel</command>. You will also want to
+ choose a machine to be the <emphasis>test
+ machine</emphasis>, which will test software updates before they
+ are put into production. This <emphasis>must</emphasis> be a
+ machine that you can afford to have down for an extended
+ period of time. It can be the build machine, but need not be.</para>
+
+ <para>All the machines in this build set need to mount
+ <filename>/usr/obj</filename> and
+ <filename>/usr/src</filename> from the same machine, and at
+ the same point. Ideally, those are on two different drives
+ on the build machine, but they can be NFS mounted on that machine
+ as well. If you have multiple build sets,
+ <filename>/usr/src</filename> should be on one build machine, and
+ NFS mounted on the rest.</para>
+
+ <para>Finally make sure that
+ <filename>/etc/make.conf</filename> on all the machines in
+ the build set agrees with the build machine. That means that
+ the build machine must build all the parts of the base
+ system that any machine in the build set is going to
+ install. Also, each build machine should have its kernel
+ name set with <varname>KERNCONF</varname> in
+ <filename>/etc/make.conf</filename>, and the build machine
+ should list them all in <varname>KERNCONF</varname>, listing
+ its own kernel first. The build machine must have the kernel
+ configuration files for each machine in
+ <filename>/usr/src/sys/arch/conf</filename>
+ if it is going to build their kernels.</para>
+ </sect2>
+
+ <sect2>
+ <title>The Base System</title>
+
+ <para>Now that all that is done, you are ready to build
+ everything. Build the kernel and world as described in <xref linkend="make-buildworld"/> on the build machine,
+ but do not install anything. After the build has finished, go
+ to the test machine, and install the kernel you just
+ built. If this machine mounts <filename>/usr/src</filename>
+ and <filename>/usr/obj</filename> via NFS, when you reboot
+ to single user you will need to enable the network and mount
+ them. The easiest way to do this is to boot to multi-user,
+ then run <command>shutdown now</command> to go to single user
+ mode. Once there, you can install the new kernel and world and run
+ <command>mergemaster</command> just as you normally would. When
+ done, reboot to return to normal multi-user operations for this
+ machine.</para>
+
+ <para>After you are certain that everything on the test
+ machine is working properly, use the same procedure to
+ install the new software on each of the other machines in
+ the build set.</para>
+ </sect2>
+
+ <sect2>
+ <title>Ports</title>
+
+ <para>The same ideas can be used for the ports tree. The first
+ critical step is mounting <filename>/usr/ports</filename> from
+ the same machine to all the machines in the build set. You can
+ then set up <filename>/etc/make.conf</filename> properly to share
+ distfiles. You should set <varname>DISTDIR</varname> to a
+ common shared directory that is writable by whichever user
+ <systemitem class="username">root</systemitem> is mapped to by your NFS mounts. Each
+ machine should set <varname>WRKDIRPREFIX</varname> to a
+ local build directory. Finally, if you are going to be
+ building and distributing packages, you should set
+ <varname>PACKAGES</varname> to a directory similar to
+ <varname>DISTDIR</varname>.</para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/desktop/Makefile b/zh_TW.UTF-8/books/handbook/desktop/Makefile
new file mode 100644
index 0000000000..192ca2b156
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/desktop/Makefile
@@ -0,0 +1,16 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+# Original revision: 1.1
+#
+
+CHAPTERS= desktop/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/desktop/chapter.xml b/zh_TW.UTF-8/books/handbook/desktop/chapter.xml
new file mode 100644
index 0000000000..e4169261ff
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/desktop/chapter.xml
@@ -0,0 +1,1037 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+ $FreeBSD$
+ Original revision: 1.72
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="desktop">
+ <info><title>桌面環境應用程式</title>
+ <authorgroup>
+ <author><personname><firstname>Christophe</firstname><surname>Juniet</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="desktop-synopsis">
+ <title>概述</title>
+
+ <para>在 FreeBSD 上面可以執行非常多種類的桌面應用程式,
+ 像是網頁瀏覽器和文字處理軟體等。
+ 這些程式大都可以透過套件來安裝或是從 Ports Collection 中自動編譯安裝。
+ 許多新的使用者會希望能在在他們的桌面系統中找到這些程式。
+ 這章將會告訴你如何不用費太多功夫去安裝一些熱門的桌面應用程式,
+ 不管是從套件或是從 Ports Collection 中安裝。</para>
+
+ <para>需要注意到的是:當從 ports 中安裝程式的時候,
+ 它們是從原始碼開始編譯的。依照你編譯的 ports 和電腦速度(硬體等級),
+ 有可能會花很長一段時間才能完成。
+ 如果從原始碼編譯對你來說會花太多時間的話,
+ 大部分的 ports 你都能找到事先編譯好的套件來安裝。</para>
+
+ <para>因為 FreeBSD 具有相容 Linux 二進制的特性,
+ 許多原先在 Linux 上開發的應用程式都能在你的 FreeBSD 桌面環境執行。
+ 在安裝任何 Linux 應用程式之前,強烈建議你先閱讀 <xref linkend="linuxemu"/>
+ Linux 執行相容模式這個章節。
+ 而許多用 Linux 二進制相容模式的軟體在 ports 裡頭通常都會用
+ <quote>linux-</quote> 開頭。
+ 當你在搜尋某個特定軟體時,記住這點,並且可以使用 &man.whereis.1;
+ 來找。 在下列的說明中,
+ 都假設你在安裝任何 Linux 應用軟體之前,
+ 已經事先啟用了 Linux 二進制相容模式。</para>
+
+ <para>下列目錄是這章中所涵蓋的應用程式:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>瀏覽器 (像是 <application>Mozilla</application>,
+ <application>Opera</application>,
+ <application>Firefox</application>,
+ <application>Konqueror</application>)</para>
+ </listitem>
+
+ <listitem>
+ <para>辦公軟體 (像是
+ <application>KOffice</application>,
+ <application>AbiWord</application>,
+ <application>The GIMP</application>,
+ <application>OpenOffice.org</application>)</para>
+ </listitem>
+
+ <listitem>
+ <para>文件瀏覽軟體 (像是 <application>&acrobat.reader;</application>,
+ <application>gv</application>,
+ <application>Xpdf</application>,
+ <application>GQview</application>)</para>
+ </listitem>
+
+ <listitem>
+ <para>財務處理軟體 (像是
+ <application>GnuCash</application>,
+ <application>Gnumeric</application>,
+ <application>Abacus</application>)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>在閱讀這章之前,你必須</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>知道如何安裝其他的軟體(third-party software)
+ (<xref linkend="ports"/>).</para>
+ </listitem>
+
+ <listitem>
+ <para>知道如何安裝 Linux 軟體
+ (<xref linkend="linuxemu"/>).</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>要知道更多關於多媒體環境的資訊,請先閱讀
+ <xref linkend="multimedia"/> 多媒體章節。
+ 如果你想要設定和使用電子郵件,也請你先看 <xref linkend="mail"/>郵件章節。</para>
+ </sect1>
+
+ <sect1 xml:id="desktop-browsers">
+ <title>瀏覽器</title>
+
+ <indexterm>
+ <primary>瀏覽器</primary>
+ <secondary>網路</secondary>
+ </indexterm>
+
+ <para>在 FreeBSD 中並沒有預先安裝好的特定瀏覽器。
+ 但在 Ports Collection 之中卻有許多瀏覽器可供你安裝使用。
+ 如果你沒有足夠時間去編譯所有的東西
+ (在某些情況下這可能會花上很長的一段時間),
+ 這些都有現成的套件可供直接安裝。</para>
+
+ <para><application>KDE</application> 和
+ <application>GNOME</application> 桌面環境都已提供 HTML 瀏覽器。
+ 請參考 <xref linkend="x11-wm"/> 來了解更多有關如何設定這些完整的桌面環境系統資訊。</para>
+
+ <para>如果你在尋找輕量化的瀏覽器,你可以從 Ports Collection 中找到下面的幾種:
+ <package>www/dillo</package>,
+ <package>www/links</package>, 或
+ <package>www/w3m</package>。</para>
+
+ <para>這節介紹這些瀏覽器:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>瀏覽器名稱</entry>
+ <entry>所需的系統資源</entry>
+ <entry>從 ports 安裝時間</entry>
+ <entry>主要相依的軟體</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><application>Mozilla</application></entry>
+ <entry>多</entry>
+ <entry>長</entry>
+ <entry><application>Gtk+</application></entry>
+ </row>
+
+ <row>
+ <entry><application>Opera</application></entry>
+ <entry>少</entry>
+ <entry>短</entry>
+ <entry>FreeBSD 和 Linux 的版本都有。
+ Linux 的版本需要 Linux 二進制相容模組以及
+ <application>linux-openmotif</application>.</entry>
+ </row>
+
+ <row>
+ <entry><application>Firefox</application></entry>
+ <entry>中度</entry>
+ <entry>長</entry>
+ <entry><application>Gtk+</application></entry>
+ </row>
+
+ <row>
+ <entry><application>Konqueror</application></entry>
+ <entry>中度</entry>
+ <entry>長</entry>
+ <entry><application>KDE</application> 函式庫</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <sect2>
+ <title>Mozilla</title>
+ <indexterm>
+ <primary><application>Mozilla</application></primary>
+ </indexterm>
+
+ <para><application>Mozilla</application>
+ 是相當現代化、穩定且完全移植至 FreeBSD 系統上。
+ 它也具備有十分符合 HTML 標準的顯示引擎,
+ 它更提供了郵件及新聞群組的閱讀功能。
+ 此外如果你打算要自己寫一些網頁的話,它還提供了 HTML 的編輯器。
+ 如果是 <application>&netscape;</application> 的使用者,
+ 你可能會認出這跟 <application>Communicator</application> 很像,
+ 它們其實同樣是使用相同基礎的瀏覽器。</para>
+
+ <para>在速度較慢,像是 CPU 速度少於 233MHz 或是小於 64MB 記憶體的機器上面,
+ 完全使用 <application>Mozilla</application> 會是件極度耗費資源的事。
+ 所以在這樣的機器上面,你可能會想要使用 <application>Opera</application>
+ 這樣輕量級的瀏覽器,而接下來後面會提到。</para>
+ <!--20060316: psilotum 譯著:多加一句話,試著讓此段比較通順一些。
+ 「所以在這樣的機器上面」-->
+
+ <para>如果你有什麼原因不能或是不想編譯
+ <application>Mozilla</application> 的話,FreeBSD
+ GNOME 團隊已經為你做好了這件事。
+ 只要用下面的指令透過網路安裝套件就行了:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r mozilla</userinput></screen>
+
+ <para>如果沒有找到套件可以使用,而你也有足夠的時間和磁碟空間來編譯
+ <application>Mozilla</application> 並安裝到你的系統中,
+ 你可以透過下列步驟來安裝:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/www/mozilla</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+
+
+ <para><application>Mozilla</application> 需要使用
+ <systemitem class="username">root</systemitem> 的權限來執行 chrome
+ 註冊來確保正確的初始化。
+ 另外,如果你需要抓一些額外的外掛程式像是 mouse gestures,
+ 你就必須要使用 <systemitem class="username">root</systemitem> 的權限來安裝,
+ 以適當的安裝這些外掛程式。</para>
+
+ <para>一旦你完成了 <application>Mozilla</application>
+ 的安裝,你就再也不需要 <systemitem class="username">root</systemitem> 的權限了。
+  你可以直接打下面的指令來啟動 <application>Mozilla</application>:</para>
+
+ <screen>&prompt.user; <userinput>mozilla</userinput></screen>
+
+ <para>也可以直接打下列指令,直接啟動郵件和新聞閱讀器:</para>
+
+ <screen>&prompt.user; <userinput>mozilla -mail</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Firefox</title>
+ <indexterm>
+ <primary><application>Firefox</application></primary>
+ </indexterm>
+
+ <para><application>Firefox</application> 是以
+ <application>Mozilla</application> 原始碼為基礎的新世代瀏覽器。
+ <application>Mozilla</application> 是一堆應用軟體的整合套裝,
+ 像是瀏覽器、郵件程式、聊天室軟體等所組成。
+ <application>Firefox</application> 則純粹是瀏覽器,
+ 這也是為何它能短小精悍之故。</para>
+
+ <para>可以打下列指令來安裝:</para>
+
+ <screen>&prompt.root;<userinput>pkg_add -r firefox</userinput></screen>
+
+ <para>也可以透過 Ports Collection,以編譯原始碼的方式來安裝:</para>
+
+ <screen>&prompt.root;<userinput>cd /usr/ports/www/firefox</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+ </sect2>
+
+ <sect2 xml:id="moz-java-plugin">
+ <title>Firefox, Mozilla 的 &java; plugin 程式</title>
+
+ <note>
+ <para>本節以及下一節,均假設您已裝好
+ <application>Firefox</application> 或
+ <application>Mozilla</application>。</para>
+ </note>
+
+ <para>&os; 基金會與 Sun Microsystems 有達成授權協議,
+ 可以散播 Java Runtime Environment(&jre;) 及
+ Java Developement Kit(&jdk;) 的 &os; 版 binary(執行檔)。
+ &os; 版的 binary 可以在 <link xlink:href="http://www.freebsdfoundation.org/downloads/java.shtml">&os;
+ 基金會</link> 網站下載。</para>
+
+ <para>要讓 <application>Firefox</application> 或
+ <application>Mozilla</application> 支援 &java; 的話,首先要先裝
+ <package>java/javavmwrapper</package> 這個 port。
+ 然後再去 <uri xlink:href="http://www.freebsdfoundation.org/downloads/java.shtml">http://www.freebsdfoundation.org/downloads/java.shtml</uri>
+ 下載 <application>Diablo &jre;</application>,並以 &man.pkg.add.1;
+ 指令來安裝之。</para>
+
+ <para>接著啟動瀏覽器,在網址列輸入 <literal>about:plugins</literal>
+ 然後按 <keycap>Enter</keycap> 鍵,就會顯示目前已裝的 plugins 清單,
+ 這時應該就可以看到 <application>&java;</application> 也有列出來。
+ 若仍未看到的話,那就切換為 <systemitem class="username">root</systemitem> 帳號,
+ 打下列指令:</para>
+
+ <screen>&prompt.root; <userinput>ln -s /usr/local/diablo-jre1.5.0/plugin/i386/ns7/libjavaplugin_oji.so \
+ /usr/local/lib/browser_plugins/</userinput></screen>
+
+ <para>最後,重啟瀏覽器即可。</para>
+ </sect2>
+
+ <sect2 xml:id="moz-flash-plugin">
+
+ <title>Firefox, Mozilla 的 &macromedia; &flash; plugin 程式</title>
+
+ <para>&macromedia; &flash; plugin 程式並沒有 &os; 版,
+ 然而可以透過軟體層(wrapper)來執行 Linux 版的 plugin 程式。
+ 這個 wrapper 同時也支援 &adobe; &acrobat; 以及 &realplayer; plugin
+ 等。</para>
+
+ <para>接下來去裝 <package>www/linuxpluginwrapper</package>。
+ linuxpluginwrapper 需要先裝一個很大的 <package>emulators/linux_base</package>port。
+ 然後根據 port 所指示的作法,
+ 去正確地設定你的 <filename>/etc/libmap.conf</filename>!
+ 設定的範例檔案位於
+ <filename>/usr/local/share/examples/linuxpluginwrapper/</filename>
+ 的目錄底下。</para>
+
+ <para>下一步,則是裝 <package>www/linux-flashplugin7</package>。
+ 裝好後,再啟動瀏覽器,在網址列輸入 <literal>about:plugins</literal>,
+ 然後按 <keycap>Enter</keycap> 鍵就會顯示目前已裝的 plugin 清單。</para>
+
+ <para>若 &flash; plugin 沒出現的話,大多可能是因為漏了做 symlink
+ 連結之故。 請切為 <systemitem class="username">root</systemitem> 帳號,打下列指令:</para>
+
+ <screen>&prompt.root; <userinput>ln -s /usr/local/lib/npapi/linux-flashplugin/libflashplayer.so \
+ /usr/local/lib/browser_plugins/</userinput>
+&prompt.root; <userinput>ln -s /usr/local/lib/npapi/linux-flashplugin/flashplayer.xpt \
+ /usr/local/lib/browser_plugins/</userinput></screen>
+
+ <para>最後,重啟瀏覽器應該就可看到了。</para>
+
+ <note>
+ <para><application>linuxpluginwrapper</application> 只能在
+ &i386; 的系統架構下運行。</para>
+ </note>
+
+ </sect2>
+
+ <sect2>
+ <title>Opera</title>
+ <indexterm>
+ <primary><application>Opera</application></primary>
+ </indexterm>
+
+ <para><application>Opera</application> 是個具備完整功能、符合標準的瀏覽器。
+ 它同時也具備了內建的郵件、新聞閱讀器、IRC、RSS/Atom feeds 閱讀器等。
+ 此外 <application>Opera</application> 更是個輕量級、
+ 執行速度又快的瀏覽器。
+ 它在 ports 中有兩種版本:「原生」的 FreeBSD 版本還有在 Linux
+ 模擬模式下的版本。</para>
+
+ <para>要用 <application>Opera</application> 的 FreeBSD 版本來瀏覽網頁的話,
+ 用下面的指令安裝:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r opera</userinput></screen>
+
+ <para>有些 FTP 站台並沒有全部的套件,
+ 但是打下面的指令就能從 Ports Collection 中安裝:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/www/opera</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+
+ <para>要安裝 <application>Opera</application> 的 Linux 版本的話,
+ 請將上面例子中的 <literal>opera</literal> 替換成
+ <literal>linux-opera</literal>。
+ 有些時候, Linux 的版本是十分有用的,
+ 像是只有 Linux 版本外掛程式的時候。
+ 但在其他方面來說, FreeBSD 和 Linux 的版本功能上是一樣的。</para>
+
+ </sect2>
+
+ <sect2>
+ <title>Konqueror</title>
+ <indexterm>
+ <primary><application>Konqueror</application></primary>
+ </indexterm>
+
+ <para><application>Konqueror</application> 是 <application>KDE</application>
+ 桌面系統的一部分,但是它也可以藉由安裝
+ <package>x11/kdebase3</package>
+ 在 KDE 環境以外使用。
+ <application>Konqueror</application> 不只是個網頁瀏覽器,
+ 他同時也是檔案管理器和多媒體瀏覽器。</para>
+
+ <para><application>Konqueror</application> 也有許多的外掛程式,
+ 這些外掛程式可以從 <package>misc/konq-plugins</package>
+ 中安裝。</para>
+
+ <para><application>Konqueror</application> 也支援 <application>&flash;</application> 的外掛程式。
+ 如何安裝的說明請參閱:<uri xlink:href="http://freebsd.kde.org/howto.php">http://freebsd.kde.org/howto.php</uri>。</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="desktop-productivity">
+ <title>辦公室軟體</title>
+
+ <para>當開始進行辦公,
+ 新的使用者通常會去找好用的辦公室軟體或是好上手的文字處理器。
+ 目前 有些<link linkend="x11-wm">桌面環境</link> 像是
+ <application>KDE</application>已經提供了辦公軟體組合的套件。
+ FreeBSD 提供了所需的所有辦公軟體,桌面環境也不例外。</para>
+
+ <para>這節涵蓋了下列的這些軟體:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>軟體名稱</entry>
+ <entry>所需系統資源</entry>
+ <entry>從 Ports 安裝的時間</entry>
+ <entry>主要相依套件</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><application>KOffice</application></entry>
+ <entry>少</entry>
+ <entry>長</entry>
+ <entry><application>KDE</application></entry>
+ </row>
+
+ <row>
+ <entry><application>AbiWord</application></entry>
+ <entry>少</entry>
+ <entry>短</entry>
+ <entry><application>Gtk+</application> 或是 <application>GNOME</application></entry>
+ </row>
+
+ <row>
+ <entry><application>The Gimp</application></entry>
+ <entry>少</entry>
+ <entry>長</entry>
+ <entry><application>Gtk+</application></entry>
+ </row>
+
+ <row>
+ <entry><application>OpenOffice.org</application></entry>
+ <entry>多</entry>
+ <entry>很久</entry>
+ <entry><application>&jdk; 1.4</application>, <application>Mozilla</application></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <sect2>
+ <title>KOffice</title>
+ <indexterm>
+ <primary><application>KOffice</application></primary>
+ </indexterm>
+ <indexterm>
+ <primary>辦公軟體套件</primary>
+ <secondary><application>KOffice</application></secondary>
+ </indexterm>
+
+ <para>KDE 社群在它的桌面環境裡頭提供了一個可以在 <application>KDE</application>
+ 外使用的辦公軟體組合。 它包含了四種模組:
+ <application>KWord</application> 是文字處理器,
+ <application>KSpread</application> 是試算表程式,
+ <application>KPresenter</application> 是簡報播放程式,
+ 另外 <application>Karbon14</application> 讓你可以產生圖形化的文件。
+ <footnote><para>譯註:Karbon14 是向量繪圖軟體,以前叫 Kontour,更早之前稱為 Killustrator。
+ </para></footnote>
+ </para>
+
+ <para>在安裝最新版的 <application>KOffice</application> 之前,
+ 請先確定你有最新版本的 <application>KDE</application>。</para>
+
+ <para>若要用套件來安裝 <application>KOffice</application>,
+ 請依照下面的指令:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r koffice</userinput></screen>
+
+ <para>如果套件不存在的話,你可以使用 ports
+ collection. 例如要安裝 <application>KDE3</application> 中的
+ <application>KOffice</application>,請使用下列指令安裝:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/koffice-kde3</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>AbiWord</title>
+ <indexterm>
+ <primary><application>AbiWord</application></primary>
+ </indexterm>
+
+ <para><application>AbiWord</application>
+ 是一個免費的文字處理軟體,外觀和感覺都近似於 <application>&microsoft; Word</application>。
+ 它適合處理文件、信件、報告、備忘錄等等。
+ 它也非常快速,包含了許多功能而且非常容易上手。</para>
+
+ <para><application>AbiWord</application> 可以輸入或輸出許多檔案格式,
+ 包括一些有專利的格式,例如微軟(Microsoft)公司的
+ <filename>.doc</filename> 格式。</para>
+
+ <para><application>AbiWord</application> 也能用套件安裝,
+ 你可以用下列指令來安裝:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r abiword</userinput></screen>
+
+ <para>如果找不到套件的話,它也可以從 Ports Collection 中編譯安裝。
+ 而 Ports Collection 應該要保持在最新的狀態。
+ <application>AbiWord</application> 可以透過下列方式編譯安裝:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/abiword</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>The GIMP</title>
+ <indexterm>
+ <primary><application>The GIMP</application></primary>
+ </indexterm>
+
+ <para>對於影像的編輯及修改來說,<application>GIMP</application>
+ 是非常精緻的影像處理軟體。
+ 它可以當作簡單的繪圖軟體或是高品質的相片處理軟體。
+ 它支援為數眾多的外掛程式及指令稿 (script-fu) 介面。
+ <application>GIMP</application> 可以讀寫許多檔案格式。
+ 它也支援掃描器
+ <footnote><para>
+ 譯註:你必須透過 sane-frontends 或 xsane 來掃描</para></footnote>
+ 和手寫板。</para>
+
+ <para>譯註:<application>GIMP</application> 在目前是 2.x 版,如果你想要安裝
+ 1.x 版的話,請用 Ports Collection 中的
+ <package>graphics/gimp1</package>。
+ 另外如果你已經使用習慣 Adobe Photoshop,而且不習慣
+ <application>GIMP</application> 介面的話,你也可以嘗試安裝
+ <package>graphics/gimpshop</package>,
+ 它的使用介面十分類似 Adobe Photoshop。</para>
+
+ <para>你可以使用下面指令安裝套件:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r gimp</userinput></screen>
+
+ <para>如果的你的 FTP 站台沒有這個套件,你可以使用
+ Ports Collection。 在 Ports Collection 的
+ <link xlink:href="http://www.FreeBSD.org/ports/graphics.html">graphics</link>
+ 目錄下也包含了
+ <application>The Gimp Manual</application>(GIMP 使用手冊)。
+ 下面示範如何安裝這些程式:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/graphics/gimp</userinput>
+&prompt.root; <userinput>make install clean</userinput>
+&prompt.root; <userinput>cd /usr/ports/graphics/gimp-manual-pdf</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+
+ <para>譯註:另外在 Ports Collection 中也有一些外掛程式可以使用,
+ 例如說可以處理數位相機 raw 檔案格式的 <package>gimp-ufraw</package>。
+ </para>
+
+ <note><para>GIMP 使用手冊也有 HTML 格式的,你可以在
+ <package>graphics/gimp-manual-html</package>
+ 中安裝。</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>OpenOffice.org</title>
+ <indexterm>
+ <primary><application>OpenOffice.org</application></primary>
+ </indexterm>
+ <indexterm>
+ <primary>office suite</primary>
+ <secondary><application>OpenOffice.org</application></secondary>
+ </indexterm>
+
+ <para><application>OpenOffice.org</application> 包含了所有完整的辦公軟體組合:
+ 文字處理器、試算表、簡報軟體還有繪圖軟體。
+ 除了它的使用者介面非常類似其他的辦公軟體,
+ 他還能夠輸入和輸出許多熱門的檔案格式。
+ 它也包含了不同語言的使用者介面、拼字檢查和字典。</para>
+
+ <para><application>OpenOffice.org</application>
+ 的文字處理器使用 XML 檔案格式來增加移植性及彈性。
+ 試算表程式支援巨集(macro)功能而且能夠使用外來的資料庫介面。
+ <application>OpenOffice.org</application> 已經十分穩定,
+ 並且能夠在 &windows;, &solaris;, Linux, FreeBSD 及
+ &macos;&nbsp;X 等作業系統上面執行。
+ 想知道更多關於 <application>OpenOffice.org</application>
+ 的資訊可以在
+ <link xlink:href="http://www.openoffice.org/">OpenOffice.org 網頁</link>
+ 上查詢。你也可以在 <link xlink:href="http://porting.openoffice.org/freebsd/">FreeBSD OpenOffice.org
+ 移植團隊</link>
+ 的網頁上查詢關於 FreeBSD 上 OpenOffice 特定的資訊或直接下載已編譯好的套件</para>
+
+ <para>要安裝 <application>OpenOffice.org</application>,
+ 請用以下方式來執行:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r openoffice.org</userinput></screen>
+
+ <note>
+ <para>當你在使用 &os; -RELEASE 版本的時候,上面的作法應該行得通。
+ 要是其他的版本,你應該看一下 &os; <application>OpenOffice.org</application>
+ 移植團隊的網站,並且用 &man.pkg.add.1; 安裝合適的套件。
+ 在這個站台都可以下載到穩定的釋出版(release)或開發中的版本。</para>
+ </note>
+
+ <para>當已經安裝完之後,你只要鍵入下面的指令就能執行
+ <application>OpenOffice.org</application>:</para>
+
+ <screen>&prompt.user; <userinput>openoffice.org</userinput></screen>
+
+ <para>譯註:端看你的版本,有時候需要輸入如 openoffice.org-2.0.1
+ 之類的指令,不過你也可以用 shell 中的 alias 或是用 symbolic link
+ 來處理。</para>
+
+ <note>
+ <para>在第一次啟動的時候,OpenOffice 會問到一些問題。
+ 而且在你的家目錄底下會自動建立 <filename>.openoffice.org2</filename>
+ 的資料夾。</para>
+ </note>
+
+ <para>如果無法取得 <application>OpenOffice.org</application>
+ 的套件,你仍然可以選擇從 port 編譯。
+ 不過你必須謹記在心:編譯的過程會需要大量的磁碟空間且相當耗時。</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/editors/openoffice.org-2</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+
+ <note>
+ <para>如果你想要安裝本地化的版本,把前面的指令代換成下面的:</para>
+
+ <screen>&prompt.root; <userinput>make LOCALIZED_LANG=你的語言 install clean</userinput></screen>
+
+ <para>你必須把<replaceable>你的語言</replaceable>
+ 換成正確的語言 ISO-code
+ <footnote>
+ <para>譯註:臺灣正體中文使用者為 zh-TW。</para>
+ </footnote>
+ 所支援的語言代碼清單可以在 port 目錄裡的
+ <filename>files/Makefile.localized</filename> 檔案中找到。</para>
+ </note>
+
+ <para>一旦完成了上述步驟,
+ <application>OpenOffice.org</application> 可用以下指令啟動:</para>
+
+ <screen>&prompt.user; <userinput>openoffice.org</userinput></screen>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="desktop-viewers">
+ <title>文件閱覽器</title>
+
+ <para>近年來有些文件格式變得愈來愈流行,
+ 基本的系統中也許不會有這些格式所需的標準閱覽器。
+ 在這一節,我們來看看怎麼安裝這些軟體。</para>
+
+ <para>這張涵蓋了下列的軟體</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>軟體名稱</entry>
+ <entry>所需系統資源</entry>
+ <entry>從 Ports 安裝時間</entry>
+ <entry>主要相依套件</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><application>&acrobat.reader;</application></entry>
+ <entry>少</entry>
+ <entry>短</entry>
+ <entry>Linux 二進制相容模組</entry>
+ </row>
+
+ <row>
+ <entry><application>gv</application></entry>
+ <entry>少</entry>
+ <entry>短</entry>
+ <entry><application>Xaw3d</application></entry>
+ </row>
+
+ <row>
+ <entry><application>Xpdf</application></entry>
+ <entry>少</entry>
+ <entry>短</entry>
+ <entry><application>FreeType</application></entry>
+ </row>
+
+ <row>
+ <entry><application>GQview</application></entry>
+ <entry>少</entry>
+ <entry>短</entry>
+ <entry><application>Gtk+</application> 或是 <application>GNOME</application></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <sect2>
+ <title>&acrobat.reader;</title>
+ <indexterm>
+ <primary><application>Acrobat Reader</application></primary>
+ </indexterm>
+ <indexterm>
+ <primary>PDF</primary>
+ <secondary>閱覽</secondary>
+ </indexterm>
+
+ <para>許多文件在散佈的時候都是用 PDF 的檔案格式,
+ 這個格式是基於 <quote>可攜式文件格式(Portable Document Format)</quote>。
+ 其中一個推薦的閱覽軟體就是<application>&acrobat.reader;</application>,
+ 它是由 Adobe 公司發行給 Linux 使用的版本。
+ 因為 FreeBSD 也可以執行 Linux 二進位檔案,
+ 所以它也能在 FreeBSD 上面執行。</para>
+
+ <para>要從 Ports Collection 中安裝
+ <application>&acrobat.reader; 7</application>
+ 只要:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/print/acroread7</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+
+ <para>因為授權的限制,所以不提供編譯好的套件。</para>
+
+ </sect2>
+
+ <sect2>
+ <title>gv</title>
+ <indexterm>
+ <primary><application>gv</application></primary>
+ </indexterm>
+ <indexterm>
+ <primary>PDF</primary>
+ <secondary>viewing</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>PostScript</primary>
+ <secondary>閱覽</secondary>
+ </indexterm>
+
+ <para><application>gv</application>是 &postscript; 和 PDF 的閱覽器。
+ 它建構於 <application>ghostview</application>的基礎上,
+ 不過因為使用 <application>Xaw3d</application> 函式庫,
+ 所以外觀看起來比較漂亮。 gv 速度快,介面簡潔並且有許多功能,
+ 比如說方向性、紙張大小、縮放比例、和反鋸齒(antialias)等。
+ 而且幾乎所有的使用都可以從鍵盤或滑鼠來完成。</para>
+
+ <para>用套件來安裝 <application>gv</application>,使用下列指令:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r gv</userinput></screen>
+
+ <para>如果你不能取得套件,你可以使用 Ports Collection:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/print/gv</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Xpdf</title>
+ <indexterm>
+ <primary><application>Xpdf</application></primary>
+ </indexterm>
+ <indexterm>
+ <primary>PDF</primary>
+ <secondary>閱覽</secondary>
+ </indexterm>
+
+ <para>如果你想要一個小型的 FreeBSD PDF 閱覽軟體,
+ <application>Xpdf</application>是個輕量級而且有效率的閱覽器。
+ 它只需要非常少的資源而且十分穩定。
+ 它只使用標準的 X 字型而不需要 <application>&motif;</application>
+ 或是其他的 X 工具組(toolkit)。</para>
+
+ <para>用套件來安裝 <application>Xpdf</application>,使用下列指令:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r xpdf</userinput></screen>
+
+ <para>如果套件不存在或是你偏好使用 Ports Collection,
+ 使用以下指令: </para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/graphics/xpdf</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+
+ <para>一旦完成了安裝,你可以啟動 <application>Xpdf</application>
+ 並且使用滑鼠右鍵去使用選單。</para>
+ </sect2>
+
+ <sect2>
+ <title>GQview</title>
+ <indexterm>
+ <primary><application>GQview</application></primary>
+ </indexterm>
+
+ <para><application>GQview</application> 是影像管理軟體。
+ 你可以用單鍵來閱覽檔案、啟動額外的編輯器、縮圖預覽等功能。
+ 它也有幻燈片播放(slideshow)及一些基本的檔案操作功能。
+ 你可用 GQview 管理影像集並能輕鬆地找出重複的檔案。
+ <application>GQview</application>
+ 能夠使用全螢幕觀看並支援國際化。</para>
+
+ <para>如果你想要安裝 <application>GQview</application>的套件,
+ 請使用下列指令:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r gqview</userinput></screen>
+
+ <para>如果套件無法取得,或是你比較喜歡使用 Ports Collection,只要:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/graphics/gqview</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="desktop-finance">
+ <title>財務</title>
+
+ <para>如果有任何理由你想要在你的 FreeBSD 桌面環境上管理你的個人財務,
+ 這裡有一些功能強大、使用簡單的應用程式可供安裝。
+ 這些財務管理軟體之中有些是相容於流行的
+ <application>Quicken</application> 或 <application>Excel</application> 文件。</para>
+
+ <para>這節涵蓋了下面這些軟體:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>軟體名稱</entry>
+ <entry>所需系統資源</entry>
+ <entry>從 Ports 安裝的時間</entry>
+ <entry>主要的相依套件</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><application>GnuCash</application></entry>
+ <entry>少</entry>
+ <entry>長</entry>
+ <entry><application>GNOME</application></entry>
+ </row>
+
+ <row>
+ <entry><application>Gnumeric</application></entry>
+ <entry>少</entry>
+ <entry>長</entry>
+ <entry><application>GNOME</application></entry>
+ </row>
+
+ <row>
+ <entry><application>Abacus</application></entry>
+ <entry>少</entry>
+ <entry>短</entry>
+ <entry><application>Tcl/Tk</application></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <sect2>
+ <title>GnuCash</title>
+ <indexterm>
+ <primary><application>GnuCash</application></primary>
+ </indexterm>
+
+ <para><application>GnuCash</application> 是
+ <application>GNOME</application> 團隊努力成果中的一部分,
+ 而 <application>GNOME</application> 主要是提供終端使用者(end-users)
+ 親切而強大的桌面應用程式。
+ 使用 <application>GnuCash</application>,
+ 你可以持續紀錄你的收入及花費、你的銀行帳戶、或是你的股票證券等。
+ 它的特性是介面直覺但功能仍非常專業。</para>
+
+ <para><application>GnuCash</application> 提供了一個智慧的註冊器、
+ 帳戶層級系統、許多快速鍵及自動完成(auto-completion)模式。
+ 它也能分開單一的報表至數個詳細的部份。
+ <application>GnuCash</application> 也能夠輸入及合併
+ <application>Quicken</application> QIF 檔案。
+ 它也能處理大部分國際的日期及通用貨幣之格式。</para>
+
+ <para>要安裝 <application>GnuCash</application> 到你的系統中,
+ 只要做下列步驟:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r gnucash</userinput></screen>
+
+ <para>如果不能取得套件,你可以使用 Ports Collection:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/finance/gnucash</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Gnumeric</title>
+ <indexterm>
+ <primary><application>Gnumeric</application></primary>
+ </indexterm>
+ <indexterm>
+ <primary>試算表</primary>
+ <secondary><application>Gnumeric</application></secondary>
+ </indexterm>
+
+ <para><application>Gnumeric</application> 是
+ <application>GNOME</application> 桌面環境中的試算表。
+ 它的特點是能夠根據儲存格格式(cell format)及自動補齊的系統,
+ 來方便自動地「猜出」使用者的輸入。
+ 它也能夠輸入許多熱門的檔案格式,像是
+ <application>Excel</application>, <application>Lotus 1-2-3</application>, 或是 <application>Quattro Pro</application>。
+
+ <application>Gnumeric</application> 支援使用
+ <package>math/guppi</package> 繪圖軟體來繪圖。
+ 它有許多內建的函數而且允許一般的儲存格格式,像是:
+ 數字、貨幣、日期、時間及其他格式等。</para>
+
+ <para>要用套件安裝 <application>Gnumeric</application>,只要打以下指令:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r gnumeric</userinput></screen>
+
+ <para>如果套件不存在,你可以做下面的步驟來使用 Ports Collection 編譯安裝:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/math/gnumeric</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Abacus</title>
+ <indexterm>
+ <primary><application>Abacus</application></primary>
+ </indexterm>
+ <indexterm>
+ <primary>試算表</primary>
+ <secondary><application>Abacus</application></secondary>
+ </indexterm>
+
+ <para><application>Abacus</application> 是個小巧又使用簡單的試算表。
+ 它包含了許多內建的函數,在相關的領域如統計學、財務、數學中很實用。
+ 它也可以輸出輸入 <application>Excel</application> 的檔案格式。
+ 另外 <application>Abacus</application>也能夠輸出 &postscript; 格式。</para>
+
+ <para>從套件安裝 <application>Abacus</application> 只要做:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r abacus</userinput></screen>
+
+ <para>如果套件不能取得的話,你可以使用 Ports Collection,
+ 並用以下指令:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/deskutils/abacus</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="desktop-summary">
+ <title>摘要</title>
+
+ <para>雖然 FreeBSD 是因為效能及穩定性而在 ISP 之間很流行,
+ 不過它也可以完全當作桌面環境(desktop)來使用,
+ 並不侷限於使用在伺服器上面。目前有數千種應用程式的
+ <link xlink:href="http://www.FreeBSD.org/where.html">套件(packages)</link>
+ 或
+ <link xlink:href="http://www.FreeBSD.org/ports/index.html">ports</link>,
+ 可供使用,你可以根據你的需求打造出一個完美的桌面環境。</para>
+
+ <para>下面是這章涵蓋的所有桌面應用軟體之快速回顧表:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>軟體名稱</entry>
+ <entry>套件名稱</entry>
+ <entry>Ports 名稱</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><application>Mozilla</application></entry>
+ <entry><literal>mozilla</literal></entry>
+ <entry><package>www/mozilla</package></entry>
+ </row>
+
+ <row>
+ <entry><application>Opera</application></entry>
+ <entry><literal>opera</literal></entry>
+ <entry><package>www/opera</package></entry>
+ </row>
+
+ <row>
+ <entry><application>Firefox</application></entry>
+ <entry><literal>firefox</literal></entry>
+ <entry><package>www/firefox</package></entry>
+ </row>
+
+ <row>
+ <entry><application>KOffice</application></entry>
+ <entry><literal>koffice-kde3</literal></entry>
+ <entry><package>editors/koffice-kde3</package></entry>
+ </row>
+
+ <row>
+ <entry><application>AbiWord</application></entry>
+ <entry><literal>abiword</literal></entry>
+ <entry><package>editors/abiword</package></entry>
+ </row>
+
+ <row>
+ <entry><application>The GIMP</application></entry>
+ <entry><literal>gimp</literal></entry>
+ <entry><package>graphics/gimp</package></entry>
+ </row>
+
+ <row>
+ <entry><application>OpenOffice.org</application></entry>
+ <entry><literal>openoffice</literal></entry>
+ <entry><package>editors/openoffice-1.1</package></entry>
+ </row>
+
+ <row>
+ <entry><application>&acrobat.reader;</application></entry>
+ <entry><literal>acroread</literal></entry>
+ <entry><package>print/acroread7</package></entry>
+ </row>
+
+ <row>
+ <entry><application>gv</application></entry>
+ <entry><literal>gv</literal></entry>
+ <entry><package>print/gv</package></entry>
+ </row>
+
+ <row>
+ <entry><application>Xpdf</application></entry>
+ <entry><literal>xpdf</literal></entry>
+ <entry><package>graphics/xpdf</package></entry>
+ </row>
+
+ <row>
+ <entry><application>GQview</application></entry>
+ <entry><literal>gqview</literal></entry>
+ <entry><package>graphics/gqview</package></entry>
+ </row>
+
+ <row>
+ <entry><application>GnuCash</application></entry>
+ <entry><literal>gnucash</literal></entry>
+ <entry><package>finance/gnucash</package></entry>
+ </row>
+
+ <row>
+ <entry><application>Gnumeric</application></entry>
+ <entry><literal>gnumeric</literal></entry>
+ <entry><package>math/gnumeric</package></entry>
+ </row>
+
+ <row>
+ <entry><application>Abacus</application></entry>
+ <entry><literal>abacus</literal></entry>
+ <entry><package>deskutils/abacus</package></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/disks/Makefile b/zh_TW.UTF-8/books/handbook/disks/Makefile
new file mode 100644
index 0000000000..c9ed4c9594
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/disks/Makefile
@@ -0,0 +1,16 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+# Original revision: 1.1
+#
+
+CHAPTERS= disks/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/disks/chapter.xml b/zh_TW.UTF-8/books/handbook/disks/chapter.xml
new file mode 100644
index 0000000000..f659610fd1
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/disks/chapter.xml
@@ -0,0 +1,3849 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.246
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="disks">
+ <title>儲存設備篇</title>
+
+ <sect1 xml:id="disks-synopsis">
+ <title>概述</title>
+
+
+ <para>本章涵蓋如何在 FreeBSD 下使用碟片裝置
+ <footnote>
+ <para>譯註:雖然有些設備沒有『碟片』,例如 USB 隨身碟,
+ 不過在此仍把 Disk 譯為『碟片裝置』。此外,為方便起見,
+ 後文所有的 Disk 都譯為『磁碟』。</para></footnote>
+ 包含 memory-backed disk (用記憶體作為磁碟使用)、跨網路使用的磁碟、
+ 標準 SCSI/IDE 磁碟、USB 介面的設備等。</para>
+
+ <para>閱讀本章後,您裝學會:</para>
+ <itemizedlist>
+ <listitem><para>FreeBSD 如何描述資料在磁碟上的劃分情形
+ (partition 和 slices)。</para>
+ </listitem>
+ <listitem><para>如何在系統上加入磁碟</para>
+ </listitem>
+ <listitem>
+ <para>如何設定 &os; 來使用 USB 裝置。</para>
+ </listitem>
+ <listitem><para>如何設定虛擬檔案系統 (virtual file systems),
+ 例如 memory disks (用記憶體作為磁碟使用)。</para></listitem>
+ <listitem>
+ <para>如何用 quota 來限制磁碟空間的使用。</para>
+ </listitem>
+ <listitem>
+ <para>如何對磁碟加密以應付攻擊。</para>
+ </listitem>
+ <listitem>
+ <para>如何在 FreeBSD 下建立、燒錄 CD 和 DVD。</para>
+ </listitem>
+ <listitem>
+ <para>各種不同的備份設備。</para>
+ </listitem>
+ <listitem>
+ <para>如何使用 FreeBSD 提供的備份工具。</para>
+ </listitem>
+ <listitem>
+ <para>如何備份到軟碟。</para>
+ </listitem>
+ <listitem>
+ <para>什麼是 snapshots ,且如何有效率地使用之。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>在閱讀之前,您應該:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>知道如何設定、安裝新的 FreeBSD kernel。
+ (<xref linkend="kernelconfig"/>).</para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 xml:id="disks-naming">
+ <title>裝置名稱</title>
+
+ <para>下面是 FreeBSD 支援的儲存媒體列表,及它們對應的裝置名稱。</para>
+
+ <table xml:id="disk-naming-physical-table" frame="none">
+ <title>命名規則</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>裝置類型</entry>
+ <entry>裝置名稱</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>IDE 磁碟機</entry>
+ <entry><literal>ad</literal></entry>
+ </row>
+ <row>
+ <entry>IDE 光碟機</entry>
+ <entry><literal>acd</literal></entry>
+ </row>
+ <row>
+ <entry>SCSI 磁碟機和 USB 碟</entry>
+ <entry><literal>da</literal></entry>
+ </row>
+ <row>
+ <entry>SCSI 光碟機</entry>
+ <entry><literal>cd</literal></entry>
+ </row>
+ <row>
+ <entry>非標準規格光碟機</entry>
+ <entry>Mitsumi 光碟機用 <literal>mcd</literal>,
+ Sony 光碟機用 <literal>scd</literal>。
+ </entry>
+ </row>
+ <row>
+ <entry>軟碟機</entry>
+ <entry><literal>fd</literal></entry>
+ </row>
+ <row>
+ <entry>SCSI 碟帶機</entry>
+ <entry><literal>sa</literal></entry>
+ </row>
+ <row>
+ <entry>IDE 碟帶機</entry>
+ <entry><literal>ast</literal></entry>
+ </row>
+ <row>
+ <entry>Flash 磁碟機</entry>
+ <entry>&diskonchip; Flash 磁碟機用 <literal>fla</literal></entry>
+ </row>
+ <row>
+ <entry>RAID 磁碟機</entry>
+ <entry>&adaptec; AdvancedRAID 用<literal>aacd</literal>,
+ &mylex; 用 <literal>mlxd</literal> 和 <literal>mlyd</literal>,
+ AMI &megaraid; 用 <literal>amrd</literal>,
+ Compaq Smart RAID 用 <literal>idad</literal>,
+ &tm.3ware; RAID 用 <literal>twed</literal>。</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 xml:id="disks-adding">
+ <info><title>新增磁碟</title>
+ <authorgroup>
+ <author><personname><firstname>David</firstname><surname>O'Brien</surname></personname><contrib>Originally contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <indexterm>
+ <primary>disk</primary>
+ <secondary>adding</secondary>
+ </indexterm>
+
+ <para>假設我們想新增 SCSI 磁碟到一臺原先只有一顆磁碟的機器上,
+ 首先將電腦關機,依製造商的指示將磁碟裝上去,
+ 詳細的操作方式請參考製造商的說明文件。</para>
+
+ <para>安裝好磁碟後,用 <systemitem class="username">root</systemitem> 登入系統,
+ 看一下 <filename>/var/run/dmesg.boot</filename> 以確認系統是否抓到新磁碟。
+ 繼續剛才的範例,新增的磁碟會是 <filename>da1</filename>,
+ 假設我們想將它掛載到 <filename>/1</filename> 這個位置
+ (如果您新增的是 IDE 磁碟的話,請用 <filename>ad1</filename>)。</para>
+
+ <indexterm><primary>partitions</primary></indexterm>
+ <indexterm><primary>slices</primary></indexterm>
+ <indexterm>
+ <primary><command>fdisk</command></primary>
+ </indexterm>
+
+ <para>FreeBSD 為了在 IBM-PC 相容電腦上執行,
+ 必須配合 PC BIOS partition,因此和傳統的 BSD partition 有很大的不同。
+ 在 PC 裡磁碟最多可以有四筆 BIOS partition 資訊(亦即最多可分割成四個
+ partition)。如果這個磁碟打算全部讓 FreeBSD 使用,可選擇
+ <emphasis>dedicated</emphasis> 模式,
+ 不然的話 FreeBSD 必須置身於其中一個 PC BIOS partition 中。
+ 在 FreeBSD 裡,PC BIOS partition 稱為 <emphasis>slice</emphasis>,
+ 這是為了不要和傳統的 BSD partition 搞混了。
+ <footnote><para>譯註:基於相同的理由,
+ 現在 BSD partition 常稱為 BSD label,或簡稱 label。</para></footnote>
+ 不論是完全由 FreeBSD 使用的磁碟,還是安裝了其它作業系統的磁碟,
+ 您都可以使用 slice。這樣的好處是,其它非 FreeBSD 作業系統的
+ <command>fdisk</command> 工具可以順利操作。</para>
+
+ <para>如果使用 slice,這個新增的磁碟會是
+ <filename>/dev/da1s1e</filename>。可以這樣來解讀它:SCSI 磁碟、
+ unit number 1(第二個 SCSI 磁碟)、slice 1(第一個 PC BIOS partition)、
+ 及 <filename>e</filename> BSD partition。在 dedicated 模式的話,
+ 新磁碟則是 <filename>/dev/da1e</filename>。</para>
+
+ <para>因為 &man.bsdlabel.8; 是用 32-bit 整數來儲存 sector(磁區) 數,
+ 因此限制一個磁碟最大只能有 2^32-1 個 sector,亦即 2TB 的空間。
+ 而 &man.fdisk.8; 的格式容許起始 sector 編號不超過 2^32-1,
+ 長度也不超過 2^32-1,因此 partition 最大空間是 2TB,而磁碟最大是 4TB。
+ &man.sunlabel.8; 則限制 partition 最大是 2TB,磁碟最多可有 8 個
+ partition,因此最大是 16TB。 如果要使用更大的磁碟,請使用
+ &man.gpt.8;。</para>
+
+ <sect2>
+ <title>使用 &man.sysinstall.8;</title>
+ <indexterm>
+ <primary><application>sysinstall</application></primary>
+ <secondary>新增磁碟</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>su</primary>
+ </indexterm>
+ <procedure>
+ <step>
+ <title>操作 <application>Sysinstall</application></title>
+
+ <para>透過 <command>sysinstall</command> 的選單介面,
+ 可以輕易為磁碟分割 BIOS partition(slice) 和 BSD patition。
+ 必須以 root 身份使用 <command>sysinstall</command>,
+ 要嘛用 root 登入,要嘛用 <command>su</command> 切換到 root。
+ 執行 <command>sysinstall</command> 後,選
+ <literal>Configure</literal>,在
+ <literal>FreeBSD Configuration Menu</literal> 裡移到
+ <literal>Fdisk</literal> 選項。</para>
+ </step>
+
+ <step>
+ <title><application>fdisk</application> Partition 編輯器</title>
+
+ <para>在 <application>fdisk</application> 裡,按下
+ <userinput>A</userinput> 表示整個磁碟都給 FreeBSD 使用。
+ 接著會提示您『是否要相容其它的作業系統』,回答
+ <literal>YES</literal>。 按 <userinput>W</userinput>
+ 會將這些改變立即寫入磁碟,再按 <userinput>q</userinput> 可以離開
+ FDISK 編輯器。 接下來會問您要將 <quote>Master Boot Record</quote>
+ 安裝於何處,由於現在是新增磁碟,表示作業系統已經裝在別的磁碟上了,
+ 所以可以選 <literal>None</literal> 就行了。</para>
+ </step>
+
+ <step>
+ <title>Disk Label Editor(磁碟 Label 編輯器)</title>
+ <indexterm><primary>BSD partitions</primary></indexterm>
+
+ <para>接著請關閉 <application>sysinstall</application>,再重開一次。
+ 照著上一節的指示,不過這次改選 <literal>Label</literal>
+ 進入 <literal>Disk Label Editor</literal>,在此您可以編輯傳統的
+ BSD partition。 一個磁碟(或著一個 slice) 最多可切分成 8 個
+ BSD partition,依序用 <literal>a-h</literal> 來表示。
+ 有些字母有特別的意義,<literal>a</literal> partition 表示這是
+ root partition(根分割區,<filename>/</filename>),
+ 因此只有安裝系統的磁碟(例如用來開機的磁碟) 有
+ <literal>a</literal> partition。 <literal>b</literal> partition
+ 表示這是 swap partitions(交換分割區),每個磁碟上都可以有 swap。
+ <literal>c</literal> partition 用來表示整個磁碟(如果使用 dedicated
+ mode 的話)或整個 slice。 其它的字母則用來表示普通的 BSD partition
+ 。</para>
+
+ <para><application>sysinstall</application> 的
+ Label editor(磁碟 Label 編輯器) 偏好用 <literal>e</literal>
+ 來表示非 root、也非 swap 的分割區
+ <footnote>
+ <para>譯註:老實說我看不懂這句指的是什麼?原文是
+ <application>sysinstall</application> Label editor
+ favors the <literal>e</literal> partition for non-root,
+ non-swap partitions. </para>
+ </footnote> 在 Label editor 裡,按 <userinput>C</userinput>
+ 可以新增一個檔案系統(BSD label),它會問您這是一個 FS(file system
+ ,檔案系統) 或是 swap(交換分割區),選擇 <literal>FS</literal>
+ 接著輸入要掛載的位置(例如 <filename>/mnt</filename>)。
+ 如果系統安裝完後才新增磁碟,<application>sysinstall</application>
+ 不會幫您把這筆掛載資料加入 <filename>/etc/fstab</filename>,
+ 所以掛載的位置不太重要。</para>
+
+ <para>當您準備好將新的 label 寫入磁碟、建立檔案系統,按
+ <userinput>W</userinput> 即可。如果出現在什麼錯誤,
+ <application>sysinstall</application> 可能無法幫您掛載這個新分割區。
+ 結束 Label Editor、結束 <application>sysinstall</application>
+ 就行了。</para>
+ </step>
+
+ <step>
+ <title>完成</title>
+
+ <para>最後要做的是編輯 <filename>/etc/fstab</filename>,
+ 加入您新增的分割區資訊。</para>
+ </step>
+ </procedure>
+ </sect2>
+
+ <sect2>
+ <title>使用命令列工具</title>
+
+ <sect3>
+ <title>使用 Slices(BIOS partitions)</title>
+
+ <para>這種模式能讓您的磁碟分割區與其它作業系統的
+ <command>fdisk</command> 工具和平共處,因此我們建議您使用 slice 模式。
+ 如果您一定要使用 <literal>dedicated</literal> 模式,
+ 您得有個好理由!
+ <footnote>
+ <para>譯註:如果您自始至終都不打算將這個磁碟用於 FreeBSD
+ 之外的作業系統,那可以算是個好理由。不過就算如此,
+ 用 slice 模式也沒什麼壞處就是了:-)。</para></footnote></para>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/zero of=/dev/da1 bs=1k count=1</userinput>
+&prompt.root; <userinput>fdisk -BI da1</userinput> # 初始您的磁碟。
+&prompt.root; <userinput>bsdlabel -B -w -r da1s1 auto</userinput> # 建立 bsdlabel。
+&prompt.root; <userinput>bsdlabel -e da1s1</userinput> # 編輯 bsdlabel 以新增 label。
+&prompt.root; <userinput>mkdir -p /1</userinput>
+&prompt.root; <userinput>newfs /dev/da1s1e</userinput> # 如果您新增了多個 label,對每個 label 重覆這個步驟。
+&prompt.root; <userinput>mount /dev/da1s1e /1</userinput> # 掛載這些新 label。
+&prompt.root; <userinput>vi /etc/fstab</userinput> # 在 <filename>/etc/fstab</filename> 加入適當的資訊。</screen>
+
+ <para>如果您新增的是 IDE 磁碟,將 <filename>da</filename>
+ 改成 <filename>ad</filename> 即可
+ <footnote>
+ <para>譯註:da 是 direct access (disk) 的縮寫;
+ ad 是 ata disk 的縮寫。</para></footnote>。</para>
+ </sect3>
+
+ <sect3>
+ <title>Dedicated</title>
+ <indexterm><primary>OS/2</primary></indexterm>
+
+ <para>如果您不打算將新磁碟用於其它的作業系統,
+ 您可以使用 <literal>dedicated</literal> 模式。注意:
+ Microsoft 的作業系統認不得這個模式,不過也不會去破壞它;
+ 然而 IBM 的 &os2; 就沒那麼好心了,它會去調整所有它不認得的分割區
+ <footnote>
+ <para>譯註:我對這句的意思沒什麼信心,原文是 IBM's &os2; however,
+ will <quote>appropriate</quote> any partition it finds which it
+ does not understand.</para></footnote>。</para>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/zero of=/dev/da1 bs=1k count=1</userinput>
+&prompt.root; <userinput>bsdlabel -Brw da1 auto</userinput>
+&prompt.root; <userinput>bsdlabel -e da1</userinput> # 建立 `e' partition。
+&prompt.root; <userinput>newfs -d0 /dev/da1e</userinput>
+&prompt.root; <userinput>mkdir -p /1</userinput>
+&prompt.root; <userinput>vi /etc/fstab</userinput> # 新增一筆 /dev/da1e 的資訊。
+&prompt.root; <userinput>mount /1</userinput></screen>
+
+ <para>另一種方法:</para>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/zero of=/dev/da1 count=2</userinput>
+&prompt.root; <userinput>bsdlabel /dev/da1 | bsdlabel -BrR da1 /dev/stdin</userinput>
+&prompt.root; <userinput>newfs /dev/da1e</userinput>
+&prompt.root; <userinput>mkdir -p /1</userinput>
+&prompt.root; <userinput>vi /etc/fstab</userinput> # 新增一筆 /dev/da1e 的資訊。
+&prompt.root; <userinput>mount /1</userinput></screen>
+
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="raid">
+ <title>RAID</title>
+
+ <sect2 xml:id="raid-soft">
+ <title>軟體 RAID</title>
+
+ <sect3 xml:id="ccd">
+ <info><title>連接式磁碟裝置驅動程式(CCD, Concatenated Disk Driver) 設定</title>
+ <authorgroup>
+ <author><personname><firstname>Christopher</firstname><surname>Shumway</surname></personname><contrib>Original work by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Jim</firstname><surname>Brown</surname></personname><contrib>Revised by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+<indexterm><primary>RAID</primary><secondary>software</secondary></indexterm>
+<indexterm>
+ <primary>RAID</primary><secondary>CCD</secondary>
+</indexterm>
+
+ <para>對大容量儲存設備而言,最關鍵的要素乃是速度、可靠性及價格。
+ 然而這三者往往難以兼顧:快速可靠的設備通常很貴;
+ 而降低成本通常也犧牲了速度或可靠性。</para>
+
+ <para>接下來要介紹的系統,價格是最重要的考量,接下來是速度,
+ 最後才是可靠性。 順序如此是因為資料傳輸的速度最終取決於網路,
+ 而儘管可靠性十分重要,卻有簡單的取代方案:
+ 將資料完整備份於 CD-R 中。</para>
+
+ <para>選擇大容量儲存設備方案時,首先要定義您的需求。
+ 如果您重視速度或可靠性甚於價格,接下來的介紹恐非您所需。</para>
+
+ <sect4 xml:id="ccd-installhw">
+ <title>安裝硬體</title>
+
+ <para>除了系統磁碟外,下面介紹的 CCD 磁碟陣列將使用到三顆 30GB、
+ 5400 RPM 的 Western Digital IDE 磁碟,以提供約 90GB 的儲存空間。
+ 最理想的情況是每個磁碟由獨立使用的排線連接獨立使用的 IDE 控制器,
+ 不過為了降低成本,利用 jumper 設定磁碟,使每個 IDE 控制器可連接
+ 一個主磁碟加一個副磁碟,如此可不必加裝額外的 IDE 控制器。</para>
+
+ <para>開機後,BIOS 應該設定成自重偵測磁碟。更重要的是 FreeBSD 應該
+ 要偵測到它們:</para>
+
+ <programlisting>ad0: 19574MB &lt;WDC WD205BA&gt; [39770/16/63] at ata0-master UDMA33
+ad1: 29333MB &lt;WDC WD307AA&gt; [59598/16/63] at ata0-slave UDMA33
+ad2: 29333MB &lt;WDC WD307AA&gt; [59598/16/63] at ata1-master UDMA33
+ad3: 29333MB &lt;WDC WD307AA&gt; [59598/16/63] at ata1-slave UDMA33</programlisting>
+
+ <note>
+ <para>如果 FreeBSD 沒有偵測到所有磁碟,請確認 jumper 都設定正確。
+ 許多 IDE 磁碟可以設定成 <quote>Cable Select</quote>
+ (根據排線位置決定),這<emphasis>並非</emphasis> master(主磁碟)
+ 或 slave(副磁碟)。 請參閱磁碟的說明文件以正確設定 jumper
+ 。</para></note>
+
+ <para>接下來,考慮如何將它們變成檔案系統的一部份。您可以參考
+ &man.vinum.8;(<xref linkend="vinum-vinum"/>) 及 &man.ccd.4;。
+ 在此我們選擇 &man.ccd.4;。</para>
+ </sect4>
+
+ <sect4 xml:id="ccd-setup">
+ <title>設定 CCD</title>
+
+ <para>&man.ccd.4; 可以將多個磁碟接起來成為一個大磁碟。要使用
+ &man.ccd.4;,您的 kernel 需要支援 &man.ccd.4;。將這行加入到
+ kernel 設定檔,並重編、重安裝 kernel:</para>
+
+ <programlisting>device ccd</programlisting>
+
+ <para>也可以載入 kernel 動態模組來支援 &man.ccd.4;。</para>
+
+ <para>使用 &man.ccd.4; 請先用 &man.bsdlabel.8; 來初始磁碟:</para>
+
+ <programlisting>bsdlabel -r -w ad1 auto
+bsdlabel -r -w ad2 auto
+bsdlabel -r -w ad3 auto</programlisting>
+
+ <para>上述指令會建立 <filename>ad1c</filename>,
+ <filename>ad2c</filename> 和 <filename>ad3c</filename>,
+ 這些 bsdlabel 都使用了整個磁碟。</para>
+
+ <para>下一步是修改 label type,同樣用 &man.bsdlabel.8; 來處理:</para>
+
+ <programlisting>bsdlabel -e ad1
+bsdlabel -e ad2
+bsdlabel -e ad3</programlisting>
+
+ <para>這個指令會打開一個編輯器(預設是 &man.vi.1;,可以用
+ <envar>EDITOR</envar> 環境變數來指定其它編輯器),並將目前磁碟的 label
+ 資訊顯示在該編輯器裡。</para>
+
+ <para>一個還未變動過的磁碟 label 資訊看起來會像這樣:</para>
+
+ <programlisting>8 partitions:
+# size offset fstype [fsize bsize bps/cpg]
+ c: 60074784 0 unused 0 0 0 # (Cyl. 0 - 59597)</programlisting>
+
+ <para>在此我們要新增一個 <literal>e</literal> partition 給
+ &man.ccd.4; 使用。 通常複製 <literal>c</literal> partition 那一行,
+ 再把 <option>fstype</option> 那一行改成
+ <userinput>4.2BSD</userinput> 就可以了。
+ 改完之後看起來應該會像這樣:</para>
+
+ <programlisting>8 partitions:
+# size offset fstype [fsize bsize bps/cpg]
+ c: 60074784 0 unused 0 0 0 # (Cyl. 0 - 59597)
+ e: 60074784 0 4.2BSD 0 0 0 # (Cyl. 0 - 59597)</programlisting>
+
+ </sect4>
+
+ <sect4 xml:id="ccd-buildingfs">
+ <title>建立檔案系統</title>
+
+ <para>現在所有的磁碟都已經建好 bsdlabel 了,可以開始建立 &man.ccd.4;。
+ 用 &man.ccdconfig.8; 來建立 &man.ccd.4;,參考下面的指令:</para>
+
+ <programlisting>ccdconfig ccd0<co xml:id="co-ccd-dev"/> 32<co xml:id="co-ccd-interleave"/> 0<co xml:id="co-ccd-flags"/> /dev/ad1e<co xml:id="co-ccd-devs"/> /dev/ad2e /dev/ad3e</programlisting>
+
+ <para>每個參數的作用如下:</para>
+
+ <calloutlist>
+ <callout arearefs="co-ccd-dev">
+ <para>第一個參數是要設定的裝置名稱,在這個例子裡是
+ <filename>/dev/ccd0c</filename>。其中 <filename>/dev/</filename>
+ 可有可無。</para>
+ </callout>
+
+ <callout arearefs="co-ccd-interleave">
+
+ <para>「interleave」的大小。所謂 interleave 是指一排磁碟區塊
+ (disk block)的大小,通常以 512 bytes 為單位,所以 interleave
+ 設為 32 即為 16,384 bytes。</para>
+ </callout>
+
+ <callout arearefs="co-ccd-flags">
+ <para>&man.ccdconfig.8; 設定模式的參數。如果您打算啟用磁碟鏡設
+ (drive mirroring),您可以在此指定參數。這個例子沒有使用鏡設,
+ 所以設成 0。</para>
+ </callout>
+
+ <callout arearefs="co-ccd-devs">
+ <para>&man.ccdconfig.8; 最後的參數是要加入到陣列的所有磁碟。
+ 請使用完整的路徑。</para>
+ </callout>
+ </calloutlist>
+
+
+ <para>執行 &man.ccdconfig.8; 之後,&man.ccd.4;
+ 已設定完成可供建立檔案系統。 請參考 &man.newfs.8; 或輸入:</para>
+
+ <programlisting>newfs /dev/ccd0c</programlisting>
+
+
+ </sect4>
+
+ <sect4 xml:id="ccd-auto">
+ <title>讓一切自動完成</title>
+
+ <para>通常您會希望每次開機時都能自動掛上(mount) &man.ccd.4;。
+ 用下面的指令將您目前的設定寫入 <filename>/etc/ccd.conf</filename>
+ :</para>
+
+ <programlisting>ccdconfig -g &gt; /etc/ccd.conf</programlisting>
+
+ <para>如果 <filename>/etc/ccd.conf</filename> 存在,每次開機時
+ <command>/etc/rc</command> 都會執行 <command>ccdconfig -C</command>
+ 。 如此便可自動設定 &man.ccd.4; 以便之後掛上(mount)檔案系統。
+ </para>
+
+ <note><para>如果您開機時選擇進入單人模式(single mode),在掛上
+ (&man.mount.8;) &man.ccd.4; 的檔案系統之前您得先執行設定的指令:
+ </para>
+
+ <programlisting>ccdconfig -C</programlisting>
+ </note>
+
+ <para>要在每次開機時自動掛上(mount) &man.ccd.4;,請在
+ <filename>/etc/fstab</filename> 加入 &man.ccd.4;:
+ </para>
+
+ <programlisting>/dev/ccd0c /media ufs rw 2 2</programlisting>
+ </sect4>
+ </sect3>
+
+ <sect3 xml:id="vinum">
+ <title>Vinum 容量管理系統</title>
+
+<indexterm><primary>RAID</primary><secondary>software</secondary></indexterm>
+<indexterm>
+ <primary>RAID</primary>
+ <secondary>Vinum</secondary>
+</indexterm>
+
+ <para>Vinum 容量管理系統(以下簡稱 Vinum) 可視為一種虛擬磁碟。
+ 它將區塊裝置(block device) 的介面與對應資料的方式切割開來,比起原本
+ slice 劃分的磁碟,Vinum 可增加了彈性、效能和穩定度
+ <footnote><para>譯註:原文這裡是用「和」,但要視實際使用方式而定。
+ 例如用 RAID-0 就不會增加穩定度 :)。</para></footnote>
+ &man.vinum.8; 實作了 RAID-0、RAID-1 和 RAID-5 等模組,
+ 它們都可以單獨使用,也可以互相搭配使用。</para>
+
+ <para>請見 <xref linkend="vinum-vinum"/> 以參考更多關於
+ &man.vinum.8; 的資訊。</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="raid-hard">
+ <title>硬體 RAID</title>
+
+ <indexterm>
+ <primary>RAID</primary>
+ <secondary>hardware</secondary>
+ </indexterm>
+
+ <para>FreeBSD 也支援許多硬體 <acronym>RAID</acronym> 控制器。
+ 這些控制器自行掌控一個小型的 <acronym>RAID</acronym> 系統,
+ 因此不需要特定軟體來管理。</para>
+
+ <para>透過控制器上的 <acronym>BIOS</acronym> 幾乎能控制所有的操作。
+ 接下來將簡單介紹如何設定 Promise <acronym>IDE</acronym>
+ <acronym>RAID</acronym> 控制卡。首先確認控制卡已安裝,接著開機。
+ 它應該會提示一些資訊<footnote><para>譯註:例如按 F1 可以進入控制卡
+ BIOS 之類的資訊。</para></footnote>。依指示進入控制卡的設定畫面,
+ 從這裡您可以將全部的硬體結合成一個大磁碟。完成之後,FreeBSD
+ 將只會看到這個大磁碟。當然您也可以使用其它的
+ <acronym>RAID</acronym> 模式。</para>
+ </sect2>
+
+ <sect2>
+ <title>重建(rebuild) ATA RAID1 陣列</title>
+
+ <para>FreeBSD 允許您熱插拔磁碟陣列裡壞掉的磁碟,
+ 當然在重開機前就得先發現。</para>
+
+ <para>也許您會在 <filename>/var/log/messages</filename>(或 &man.dmesg.8;
+ 的輸出) 看到類似下面的訊息:</para>
+
+ <programlisting>ad6 on monster1 suffered a hard error.
+ad6: READ command timeout tag=0 serv=0 - resetting
+ad6: trying fallback to PIO mode
+ata3: resetting devices .. done
+ad6: hard error reading fsbn 1116119 of 0-7 (ad6 bn 1116119; cn 1107 tn 4 sn 11)\\
+status=59 error=40
+ar0: WARNING - mirror lost</programlisting>
+
+ <para>請用 &man.atacontrol.8; 來得到更多資訊:</para>
+
+ <screen>&prompt.root; <userinput>atacontrol list</userinput>
+ATA channel 0:
+ Master: no device present
+ Slave: acd0 &lt;HL-DT-ST CD-ROM GCR-8520B/1.00&gt; ATA/ATAPI rev 0
+
+ATA channel 1:
+ Master: no device present
+ Slave: no device present
+
+ATA channel 2:
+ Master: ad4 &lt;MAXTOR 6L080J4/A93.0500&gt; ATA/ATAPI rev 5
+ Slave: no device present
+
+ATA channel 3:
+ Master: ad6 &lt;MAXTOR 6L080J4/A93.0500&gt; ATA/ATAPI rev 5
+ Slave: no device present
+
+&prompt.root; <userinput>atacontrol status ar0</userinput>
+ar0: ATA RAID1 subdisks: ad4 ad6 status: DEGRADED</screen>
+
+ <procedure>
+ <step>
+ <para>首先您得將損壞磁碟所在的 ata channel 卸載(detach),
+ 如此才能安全地移除:</para>
+
+ <screen>&prompt.root; <userinput>atacontrol detach ata3</userinput></screen>
+ </step>
+
+ <step>
+ <para>用好的磁碟換下損壞的。</para>
+ </step>
+
+ <step>
+ <para>重新載入(re-attach) ata channel:</para>
+
+ <screen>&prompt.root; <userinput>atacontrol attach ata3</userinput>
+Master: ad6 &lt;MAXTOR 6L080J4/A93.0500&gt; ATA/ATAPI rev 5
+Slave: no device present</screen>
+ </step>
+
+ <step>
+ <para>將新的磁碟加入原本的磁碟陣列成為備援(spare) 磁碟:</para>
+
+ <screen>&prompt.root; <userinput>atacontrol addspare ar0 ad6</userinput></screen>
+ </step>
+
+ <step>
+ <para>重建磁碟陣列:</para>
+
+ <screen>&prompt.root; <userinput>atacontrol rebuild ar0</userinput></screen>
+ </step>
+
+ <step>
+ <para>可以用下面指定來確認重建的進度:</para>
+
+ <screen>&prompt.root; <userinput>dmesg | tail -10</userinput>
+[output removed]
+ad6: removed from configuration
+ad6: deleted from ar0 disk1
+ad6: inserted into ar0 disk1 as spare
+
+&prompt.root; <userinput>atacontrol status ar0</userinput>
+ar0: ATA RAID1 subdisks: ad4 ad6 status: REBUILDING 0% completed</screen>
+ </step>
+
+ <step>
+ <para>等重建完就完成了。</para>
+ </step>
+ </procedure>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="usb-disks">
+ <info><title>USB 儲存裝置</title>
+ <authorgroup>
+ <author><personname><firstname>Marc</firstname><surname>Fonvieille</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+ <indexterm>
+ <primary>USB</primary>
+ <secondary>disks</secondary>
+ </indexterm>
+
+ <para>在現在,有許多外部儲存裝置採用 USB(Universal Serial Bus) 介面,
+ 例如硬碟、USB 拇指碟、CD-R 燒錄機等。 &os; 提供對這些裝置的支援。</para>
+
+ <sect2>
+ <title>設定</title>
+
+ <para>USB mass 儲存裝置驅動程式(&man.umass.4;)提供 USB 儲存裝置的支援。
+ 但如果是用 <filename>GENERIC</filename> kernel,就不需要做任何設定變動
+ 。 若是自訂 kernel,請確認 kernel 設定檔含有下面這幾行:</para>
+
+ <programlisting>device scbus
+device da
+device pass
+device uhci
+device ohci
+device usb
+device umass</programlisting>
+
+ <para>&man.umass.4; 驅動程式透過 SCSI 子系統存取 USB 儲存裝置,
+ 您的 USB 裝置會被系統辨識成 SCSI 裝置。 依照您主機板上 USB 晶片型號,
+ 您只需要 <literal>device uhci</literal> 或
+ <literal>device ohci</literal> 其中一個。
+ 然而,將兩者都編進 kernel 也無妨。 只要別忘了在修改 kernel
+ 設定後重新編譯及安裝新的 kernel 就行了。</para>
+
+ <note>
+ <para>如果您的 USB 裝置是 CD-R 或 DVD 燒錄機,則 SCSI 光碟機驅動程式
+ &man.cd.4; 必須寫入 kernel 設定檔,像這樣:</para>
+
+ <programlisting>device cd</programlisting>
+
+ <para>因為燒錄機會被當成 SCSI 裝置,所以 &man.atapicam.4;
+ 驅動程式不需要編入 kernel。</para>
+ </note>
+
+ <para>USB 2.0 控制器的支援由 &os;; 提供,然而必須在 kernel
+ 設定檔增加下面這行以提供 USB 2.0 支援:</para>
+
+ <programlisting>device ehci</programlisting>
+
+ <para>注意,如果您需要 USB 1.x 支援,您仍然需要將 &man.uhci.4; 及
+ &man.ohci.4; 驅動程式編入 kernel。</para>
+ </sect2>
+
+ <sect2>
+ <title>測試設定</title>
+
+ <para>The configuration is ready to be tested: plug in your USB
+ device, and in the system message buffer (&man.dmesg.8;), the
+ drive should appear as something like:</para>
+
+ <screen>umass0: USB Solid state disk, rev 1.10/1.00, addr 2
+GEOM: create disk da0 dp=0xc2d74850
+da0 at umass-sim0 bus 0 target 0 lun 0
+da0: &lt;Generic Traveling Disk 1.11&gt; Removable Direct Access SCSI-2 device
+da0: 1.000MB/s transfers
+da0: 126MB (258048 512 byte sectors: 64H 32S/T 126C)</screen>
+
+ <para>Of course, the brand, the device node
+ (<filename>da0</filename>) and other details can differ
+ according to your configuration.</para>
+
+ <para>Since the USB device is seen as a SCSI one, the
+ <command>camcontrol</command> command can be used to list the
+ USB storage devices attached to the system:</para>
+
+ <screen>&prompt.root; <userinput>camcontrol devlist</userinput>
+&lt;Generic Traveling Disk 1.11&gt; at scbus0 target 0 lun 0 (da0,pass0)</screen>
+
+ <para>If the drive comes with a file system, you should be able
+ to mount it. The <xref linkend="disks-adding"/> will help you
+ to format and create partitions on the USB drive if
+ needed.</para>
+
+ <para>If you unplug the device (the disk must be unmounted
+ before), you should see, in the system message buffer,
+ something like the following:</para>
+
+ <screen>umass0: at uhub0 port 1 (addr 2) disconnected
+(da0:umass-sim0:0:0:0): lost device
+(da0:umass-sim0:0:0:0): removing device entry
+GEOM: destroy disk da0 dp=0xc2d74850
+umass0: detached</screen>
+ </sect2>
+
+ <sect2>
+ <title>Further Reading</title>
+
+ <para>Beside the <link linkend="disks-adding">Adding
+ Disks</link> and <link linkend="mount-unmount">Mounting and
+ Unmounting File Systems</link> sections, reading various
+ manual pages may be also useful: &man.umass.4;,
+ &man.camcontrol.8;, and &man.usbdevs.8;.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="creating-cds">
+ <info><title>Creating and Using Optical Media (CDs)</title>
+ <authorgroup>
+ <author><personname><firstname>Mike</firstname><surname>Meyer</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+ <indexterm>
+ <primary>CDROMs</primary>
+ <secondary>creating</secondary>
+ </indexterm>
+
+ <sect2>
+ <title>Introduction</title>
+
+ <para>CDs have a number of features that differentiate them from
+ conventional disks. Initially, they were not writable by the
+ user. They are designed so that they can be read continuously without
+ delays to move the head between tracks. They are also much easier
+ to transport between systems than similarly sized media were at the
+ time.</para>
+
+ <para>CDs do have tracks, but this refers to a section of data to
+ be read continuously and not a physical property of the disk. To
+ produce a CD on FreeBSD, you prepare the data files that are going
+ to make up the tracks on the CD, then write the tracks to the
+ CD.</para>
+
+ <indexterm><primary>ISO 9660</primary></indexterm>
+ <indexterm>
+ <primary>file systems</primary>
+ <secondary>ISO 9660</secondary>
+ </indexterm>
+ <para>The ISO 9660 file system was designed to deal with these
+ differences. It unfortunately codifies file system limits that were
+ common then. Fortunately, it provides an extension mechanism that
+ allows properly written CDs to exceed those limits while still
+ working with systems that do not support those extensions.</para>
+
+ <indexterm>
+ <primary><package>sysutils/cdrtools</package></primary>
+ </indexterm>
+ <para>The <package>sysutils/cdrtools</package>
+ port includes &man.mkisofs.8;, a program that you can use to
+ produce a data file containing an ISO 9660 file
+ system. It has options that support various extensions, and is
+ described below.</para>
+
+ <indexterm>
+ <primary>CD burner</primary>
+ <secondary>ATAPI</secondary>
+ </indexterm>
+ <para>Which tool to use to burn the CD depends on whether your CD burner
+ is ATAPI or something else. ATAPI CD burners use the <command>burncd</command> program that is part of
+ the base system. SCSI and USB CD burners should use
+ <command>cdrecord</command> from
+ the <package>sysutils/cdrtools</package> port.</para>
+
+ <para><command>burncd</command> has a limited number of
+ supported drives. To find out if a drive is supported, see the
+ <link xlink:href="http://www.freebsd.dk/ata/">CD-R/RW supported
+ drives</link> list.</para>
+
+ <note>
+ <indexterm>
+ <primary>CD burner</primary>
+ <secondary>ATAPI/CAM driver</secondary>
+ </indexterm>
+ <para>If you run &os;&nbsp;5.X, &os;&nbsp;4.8-RELEASE version or
+ higher, it will be possible to use <command>cdrecord</command> and other tools
+ for SCSI drives on an ATAPI hardware with the <link linkend="atapicam">ATAPI/CAM module</link>.</para>
+ </note>
+
+ <para>If you want a CD burning software with a graphical user
+ interface, you should have a look to
+ <application>X-CD-Roast</application> or
+ <application>K3b</application>. These tools are available as
+ packages or from the <package>sysutils/xcdroast</package> and <package>sysutils/k3b</package> ports.
+ <application>X-CD-Roast</application> and
+ <application>K3b</application> require the <link linkend="atapicam">ATAPI/CAM module</link> with ATAPI
+ hardware.</para>
+ </sect2>
+
+ <sect2 xml:id="mkisofs">
+ <title>mkisofs</title>
+
+ <para>The &man.mkisofs.8; program, which is part of the
+ <package>sysutils/cdrtools</package> port,
+ produces an ISO 9660 file system
+ that is an image of a directory tree in the &unix; file system name
+ space. The simplest usage is:</para>
+
+ <screen>&prompt.root; <userinput>mkisofs -o imagefile.iso /path/to/tree</userinput></screen>
+
+ <indexterm>
+ <primary>file systems</primary>
+ <secondary>ISO 9660</secondary>
+ </indexterm>
+ <para>This command will create an <replaceable>imagefile.iso</replaceable>
+ containing an ISO 9660 file system that is a copy of the tree at
+ <replaceable>/path/to/tree</replaceable>. In the process, it will
+ map the file names to names that fit the limitations of the
+ standard ISO 9660 file system, and will exclude files that have
+ names uncharacteristic of ISO file systems.</para>
+
+ <indexterm>
+ <primary>file systems</primary>
+ <secondary>HFS</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>file systems</primary>
+ <secondary>Joliet</secondary>
+ </indexterm>
+ <para>A number of options are available to overcome those
+ restrictions. In particular, <option>-R</option> enables the
+ Rock Ridge extensions common to &unix; systems, <option>-J</option>
+ enables Joliet extensions used by Microsoft systems, and
+ <option>-hfs</option> can be used to create HFS file systems used
+ by &macos;.</para>
+
+ <para>For CDs that are going to be used only on FreeBSD systems,
+ <option>-U</option> can be used to disable all filename
+ restrictions. When used with <option>-R</option>, it produces a
+ file system image that is identical to the FreeBSD tree you started
+ from, though it may violate the ISO 9660 standard in a number of
+ ways.</para>
+
+ <indexterm>
+ <primary>CDROMs</primary>
+ <secondary>creating bootable</secondary>
+ </indexterm>
+ <para>The last option of general use is <option>-b</option>. This is
+ used to specify the location of the boot image for use in producing an
+ <quote>El Torito</quote> bootable CD. This option takes an
+ argument which is the path to a boot image from the top of the
+ tree being written to the CD. By default, &man.mkisofs.8; creates an
+ ISO image in the so-called <quote>floppy disk emulation</quote> mode,
+ and thus expects the boot image to be exactly 1200, 1440 or
+ 2880&nbsp;KB in size. Some boot loaders, like the one used by the
+ FreeBSD distribution disks, do not use emulation mode; in this case,
+ the <option>-no-emul-boot</option> option should be used. So, if
+ <filename>/tmp/myboot</filename> holds a bootable FreeBSD system
+ with the boot image in
+ <filename>/tmp/myboot/boot/cdboot</filename>, you could produce the
+ image of an ISO 9660 file system in
+ <filename>/tmp/bootable.iso</filename> like so:</para>
+
+ <screen>&prompt.root; <userinput>mkisofs -R -no-emul-boot -b boot/cdboot -o /tmp/bootable.iso /tmp/myboot</userinput></screen>
+
+ <para>Having done that, if you have <filename>md</filename>
+ configured in your kernel, you can mount the file system with:</para>
+
+ <screen>&prompt.root; <userinput>mdconfig -a -t vnode -f /tmp/bootable.iso -u 0</userinput>
+&prompt.root; <userinput>mount -t cd9660 /dev/md0 /mnt</userinput></screen>
+
+ <para>At which point you can verify that <filename>/mnt</filename>
+ and <filename>/tmp/myboot</filename> are identical.</para>
+
+ <para>There are many other options you can use with
+ &man.mkisofs.8; to fine-tune its behavior. In particular:
+ modifications to an ISO 9660 layout and the creation of Joliet
+ and HFS discs. See the &man.mkisofs.8; manual page for details.</para>
+ </sect2>
+
+ <sect2 xml:id="burncd">
+ <title>burncd</title>
+ <indexterm>
+ <primary>CDROMs</primary>
+ <secondary>burning</secondary>
+ </indexterm>
+ <para>If you have an ATAPI CD burner, you can use the
+ <command>burncd</command> command to burn an ISO image onto a
+ CD. <command>burncd</command> is part of the base system, installed
+ as <filename>/usr/sbin/burncd</filename>. Usage is very simple, as
+ it has few options:</para>
+
+ <screen>&prompt.root; <userinput>burncd -f cddevice data imagefile.iso fixate</userinput></screen>
+
+ <para>Will burn a copy of <replaceable>imagefile.iso</replaceable> on
+ <replaceable>cddevice</replaceable>. The default device is
+ <filename>/dev/acd0</filename>. See &man.burncd.8; for options to
+ set the write speed, eject the CD after burning, and write audio
+ data.</para>
+ </sect2>
+
+ <sect2 xml:id="cdrecord">
+ <title>cdrecord</title>
+
+ <para>If you do not have an ATAPI CD burner, you will have to use
+ <command>cdrecord</command> to burn your
+ CDs. <command>cdrecord</command> is not part of the base system;
+ you must install it from either the port at <package>sysutils/cdrtools</package>
+ or the appropriate
+ package. Changes to the base system can cause binary versions of
+ this program to fail, possibly resulting in a
+ <quote>coaster</quote>. You should therefore either upgrade the
+ port when you upgrade your system, or if you are <link linkend="stable">tracking -STABLE</link>, upgrade the port when a
+ new version becomes available.</para>
+
+ <para>While <command>cdrecord</command> has many options, basic usage
+ is even simpler than <command>burncd</command>. Burning an ISO 9660
+ image is done with:</para>
+
+ <screen>&prompt.root; <userinput>cdrecord dev=device imagefile.iso</userinput></screen>
+
+ <para>The tricky part of using <command>cdrecord</command> is finding
+ the <option>dev</option> to use. To find the proper setting, use
+ the <option>-scanbus</option> flag of <command>cdrecord</command>,
+ which might produce results like this:</para>
+ <indexterm>
+ <primary>CDROMs</primary>
+ <secondary>burning</secondary>
+ </indexterm>
+ <screen>&prompt.root; <userinput>cdrecord -scanbus</userinput>
+Cdrecord-Clone 2.01 (i386-unknown-freebsd7.0) Copyright (C) 1995-2004 J&ouml;rg Schilling
+Using libscg version 'schily-0.1'
+scsibus0:
+ 0,0,0 0) 'SEAGATE ' 'ST39236LW ' '0004' Disk
+ 0,1,0 1) 'SEAGATE ' 'ST39173W ' '5958' Disk
+ 0,2,0 2) *
+ 0,3,0 3) 'iomega ' 'jaz 1GB ' 'J.86' Removable Disk
+ 0,4,0 4) 'NEC ' 'CD-ROM DRIVE:466' '1.26' Removable CD-ROM
+ 0,5,0 5) *
+ 0,6,0 6) *
+ 0,7,0 7) *
+scsibus1:
+ 1,0,0 100) *
+ 1,1,0 101) *
+ 1,2,0 102) *
+ 1,3,0 103) *
+ 1,4,0 104) *
+ 1,5,0 105) 'YAMAHA ' 'CRW4260 ' '1.0q' Removable CD-ROM
+ 1,6,0 106) 'ARTEC ' 'AM12S ' '1.06' Scanner
+ 1,7,0 107) *</screen>
+
+ <para>This lists the appropriate <option>dev</option> value for the
+ devices on the list. Locate your CD burner, and use the three
+ numbers separated by commas as the value for
+ <option>dev</option>. In this case, the CRW device is 1,5,0, so the
+ appropriate input would be
+ <option>dev=1,5,0</option>. There are easier
+ ways to specify this value; see &man.cdrecord.1; for
+ details. That is also the place to look for information on writing
+ audio tracks, controlling the speed, and other things.</para>
+ </sect2>
+
+ <sect2 xml:id="duplicating-audiocds">
+ <title>Duplicating Audio CDs</title>
+
+ <para>You can duplicate an audio CD by extracting the audio data from
+ the CD to a series of files, and then writing these files to a blank
+ CD. The process is slightly different for ATAPI and SCSI
+ drives.</para>
+
+ <procedure>
+ <title>SCSI Drives</title>
+
+ <step>
+ <para>Use <command>cdda2wav</command> to extract the audio.</para>
+
+ <screen>&prompt.user; <userinput>cdda2wav -v255 -D2,0 -B -Owav</userinput></screen>
+ </step>
+
+ <step>
+ <para>Use <command>cdrecord</command> to write the
+ <filename>.wav</filename> files.</para>
+
+ <screen>&prompt.user; <userinput>cdrecord -v dev=2,0 -dao -useinfo *.wav</userinput></screen>
+
+ <para>Make sure that <replaceable>2,0</replaceable> is set
+ appropriately, as described in <xref linkend="cdrecord"/>.</para>
+ </step>
+ </procedure>
+
+ <procedure>
+ <title>ATAPI Drives</title>
+
+ <step>
+ <para>The ATAPI CD driver makes each track available as
+ <filename>/dev/acddtnn</filename>,
+ where <replaceable>d</replaceable> is the drive number, and
+ <replaceable>nn</replaceable> is the track number written with two
+ decimal digits, prefixed with zero as needed.
+ So the first track on the first disk is
+ <filename>/dev/acd0t01</filename>, the second is
+ <filename>/dev/acd0t02</filename>, the third is
+ <filename>/dev/acd0t03</filename>, and so on.</para>
+
+ <para>Make sure the appropriate files exist in
+ <filename>/dev</filename>. If the entries are missing,
+ force the system to retaste the media:</para>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/acd0 of=/dev/null count=1</userinput></screen>
+
+ </step>
+
+ <step>
+ <para>Extract each track using &man.dd.1;. You must also use a
+ specific block size when extracting the files.</para>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/acd0t01 of=track1.cdr bs=2352</userinput>
+&prompt.root; <userinput>dd if=/dev/acd0t02 of=track2.cdr bs=2352</userinput>
+...
+</screen>
+ </step>
+
+ <step>
+ <para>Burn the extracted files to disk using
+ <command>burncd</command>. You must specify that these are audio
+ files, and that <command>burncd</command> should fixate the disk
+ when finished.</para>
+
+ <screen>&prompt.root; <userinput>burncd -f /dev/acd0 audio track1.cdr track2.cdr ... fixate</userinput></screen>
+ </step>
+ </procedure>
+ </sect2>
+
+ <sect2 xml:id="imaging-cd">
+ <title>Duplicating Data CDs</title>
+
+ <para>You can copy a data CD to a image file that is
+ functionally equivalent to the image file created with
+ &man.mkisofs.8;, and you can use it to duplicate
+ any data CD. The example given here assumes that your CDROM
+ device is <filename>acd0</filename>. Substitute your
+ correct CDROM device.</para>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/acd0 of=file.iso bs=2048</userinput></screen>
+
+ <para>Now that you have an image, you can burn it to CD as
+ described above.</para>
+ </sect2>
+
+ <sect2 xml:id="mounting-cd">
+ <title>Using Data CDs</title>
+
+ <para>Now that you have created a standard data CDROM, you
+ probably want to mount it and read the data on it. By
+ default, &man.mount.8; assumes that a file system is of type
+ <literal>ufs</literal>. If you try something like:</para>
+
+ <screen>&prompt.root; <userinput>mount /dev/cd0 /mnt</userinput></screen>
+
+ <para>you will get a complaint about <errorname>Incorrect super
+ block</errorname>, and no mount. The CDROM is not a
+ <literal>UFS</literal> file system, so attempts to mount it
+ as such will fail. You just need to tell &man.mount.8; that
+ the file system is of type <literal>ISO9660</literal>, and
+ everything will work. You do this by specifying the
+ <option>-t cd9660</option> option &man.mount.8;. For
+ example, if you want to mount the CDROM device,
+ <filename>/dev/cd0</filename>, under
+ <filename>/mnt</filename>, you would execute:</para>
+
+ <screen>&prompt.root; <userinput>mount -t cd9660 /dev/cd0 /mnt</userinput></screen>
+
+ <para>Note that your device name
+ (<filename>/dev/cd0</filename> in this example) could be
+ different, depending on the interface your CDROM uses. Also,
+ the <option>-t cd9660</option> option just executes
+ &man.mount.cd9660.8;. The above example could be shortened
+ to:</para>
+
+<screen>&prompt.root; <userinput>mount_cd9660 /dev/cd0 /mnt</userinput></screen>
+
+ <para>You can generally use data CDROMs from any vendor in this
+ way. Disks with certain ISO 9660 extensions might behave
+ oddly, however. For example, Joliet disks store all filenames
+ in two-byte Unicode characters. The FreeBSD kernel does not
+ speak Unicode (yet!), so non-English characters show up as
+ question marks. (The FreeBSD
+ CD9660 driver includes hooks to load an appropriate Unicode
+ conversion table on the fly. Modules for some of the common
+ encodings are available via the
+ <package>sysutils/cd9660_unicode</package> port.)</para>
+
+ <para>Occasionally, you might get <errorname>Device not
+ configured</errorname> when trying to mount a CDROM. This
+ usually means that the CDROM drive thinks that there is no
+ disk in the tray, or that the drive is not visible on the bus.
+ It can take a couple of seconds for a CDROM drive to realize
+ that it has been fed, so be patient.</para>
+
+ <para>Sometimes, a SCSI CDROM may be missed because it did not
+ have enough time to answer the bus reset. If you have a SCSI
+ CDROM please add the following option to your kernel
+ configuration and <link linkend="kernelconfig-building">rebuild your kernel</link>.</para>
+
+ <programlisting>options SCSI_DELAY=15000</programlisting>
+
+ <para>This tells your SCSI bus to pause 15 seconds during boot,
+ to give your CDROM drive every possible chance to answer the
+ bus reset.</para>
+ </sect2>
+
+ <sect2 xml:id="rawdata-cd">
+ <title>Burning Raw Data CDs</title>
+
+ <para>You can choose to burn a file directly to CD, without
+ creating an ISO 9660 file system. Some people do this for
+ backup purposes. This runs more quickly than burning a
+ standard CD:</para>
+
+ <screen>&prompt.root; <userinput>burncd -f /dev/acd1 -s 12 data archive.tar.gz fixate</userinput></screen>
+
+ <para>In order to retrieve the data burned to such a CD, you
+ must read data from the raw device node:</para>
+
+ <screen>&prompt.root; <userinput>tar xzvf /dev/acd1</userinput></screen>
+
+ <para>You cannot mount this disk as you would a normal CDROM.
+ Such a CDROM cannot be read under any operating system
+ except FreeBSD. If you want to be able to mount the CD, or
+ share data with another operating system, you must use
+ &man.mkisofs.8; as described above.</para>
+ </sect2>
+
+ <sect2 xml:id="atapicam">
+ <info><title>Using the ATAPI/CAM Driver</title>
+ <authorgroup>
+ <author><personname><firstname>Marc</firstname><surname>Fonvieille</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm>
+ <primary>CD burner</primary>
+ <secondary>ATAPI/CAM driver</secondary>
+ </indexterm>
+
+ <para>This driver allows ATAPI devices (CD-ROM, CD-RW, DVD
+ drives etc...) to be accessed through the SCSI subsystem, and
+ so allows the use of applications like <package>sysutils/cdrdao</package> or
+ &man.cdrecord.1;.</para>
+
+ <para>To use this driver, you will need to add the following
+ line to your kernel configuration file:</para>
+
+ <programlisting>device atapicam</programlisting>
+
+ <para>You also need the following lines in your kernel
+ configuration file:</para>
+
+ <programlisting>device ata
+device scbus
+device cd
+device pass</programlisting>
+
+ <para>which should already be present.</para>
+
+ <para>Then rebuild, install your new kernel, and reboot your
+ machine. During the boot process, your burner should show up,
+ like so:</para>
+
+ <screen>acd0: CD-RW &lt;MATSHITA CD-RW/DVD-ROM UJDA740&gt; at ata1-master PIO4
+cd0 at ata1 bus 0 target 0 lun 0
+cd0: &lt;MATSHITA CDRW/DVD UJDA740 1.00&gt; Removable CD-ROM SCSI-0 device
+cd0: 16.000MB/s transfers
+cd0: Attempt to query device size failed: NOT READY, Medium not present - tray closed</screen>
+
+ <para>The drive could now be accessed via the
+ <filename>/dev/cd0</filename> device name, for example to
+ mount a CD-ROM on <filename>/mnt</filename>, just type the
+ following:</para>
+
+ <screen>&prompt.root; <userinput>mount -t cd9660 /dev/cd0 /mnt</userinput></screen>
+
+ <para>As <systemitem class="username">root</systemitem>, you can run the following
+ command to get the SCSI address of the burner:</para>
+
+ <screen>&prompt.root; <userinput>camcontrol devlist</userinput>
+&lt;MATSHITA CDRW/DVD UJDA740 1.00&gt; at scbus1 target 0 lun 0 (pass0,cd0)</screen>
+
+ <para>So <literal>1,0,0</literal> will be the SCSI address to
+ use with &man.cdrecord.1; and other SCSI application.</para>
+
+ <para>For more information about ATAPI/CAM and SCSI system,
+ refer to the &man.atapicam.4; and &man.cam.4; manual
+ pages.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="creating-dvds">
+ <info><title>Creating and Using Optical Media (DVDs)</title>
+ <authorgroup>
+ <author><personname><firstname>Marc</firstname><surname>Fonvieille</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Andy</firstname><surname>Polyakov</surname></personname><contrib>With inputs from </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+ <indexterm>
+ <primary>DVD</primary>
+ <secondary>burning</secondary>
+ </indexterm>
+
+ <sect2>
+ <title>Introduction</title>
+
+ <para>Compared to the CD, the DVD is the next generation of
+ optical media storage technology. The DVD can hold more data
+ than any CD and is nowadays the standard for video
+ publishing.</para>
+
+ <para>Five physical recordable formats can be defined for what
+ we will call a recordable DVD:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>DVD-R: This was the first DVD recordable format
+ available. The DVD-R standard is defined by the <link xlink:href="http://www.dvdforum.com/forum.shtml">DVD Forum</link>.
+ This format is write once.</para>
+ </listitem>
+
+ <listitem>
+ <para>DVD-RW: This is the rewriteable version of
+ the DVD-R standard. A DVD-RW can be rewritten about 1000
+ times.</para>
+ </listitem>
+
+ <listitem>
+ <para>DVD-RAM: This is also a rewriteable format
+ supported by the DVD Forum. A DVD-RAM can be seen as a
+ removable hard drive. However, this media is not
+ compatible with most DVD-ROM drives and DVD-Video players;
+ only a few DVD writers support the DVD-RAM format.</para>
+ </listitem>
+
+ <listitem>
+ <para>DVD+RW: This is a rewriteable format defined by
+ the <link xlink:href="http://www.dvdrw.com/">DVD+RW
+ Alliance</link>. A DVD+RW can be rewritten about 1000
+ times.</para>
+ </listitem>
+
+ <listitem>
+ <para>DVD+R: This format is the write once variation
+ of the DVD+RW format.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>A single layer recordable DVD can hold up to
+ 4,700,000,000&nbsp;bytes which is actually 4.38&nbsp;GB or
+ 4485&nbsp;MB (1 kilobyte is 1024 bytes).</para>
+
+ <note>
+ <para>A distinction must be made between the physical media and
+ the application. For example, a DVD-Video is a specific
+ file layout that can be written on any recordable DVD
+ physical media: DVD-R, DVD+R, DVD-RW etc. Before choosing
+ the type of media, you must be sure that both the burner and the
+ DVD-Video player (a standalone player or a DVD-ROM drive on
+ a computer) are compatible with the media under consideration.</para></note>
+ </sect2>
+
+ <sect2>
+ <title>Configuration</title>
+
+ <para>The program &man.growisofs.1; will be used to perform DVD
+ recording. This command is part of the
+ <application>dvd+rw-tools</application> utilities (<package>sysutils/dvd+rw-tools</package>). The
+ <application>dvd+rw-tools</application> support all DVD media
+ types.</para>
+
+ <para>These tools use the SCSI subsystem to access to the
+ devices, therefore the <link linkend="atapicam">ATAPI/CAM
+ support</link> must be added to your kernel. If your burner
+ uses the USB interface this addition is useless, and you should
+ read the <xref linkend="usb-disks"/> for more details on USB
+ devices configuration.</para>
+
+ <para>You also have to enable DMA access for ATAPI devices, this
+ can be done in adding the following line to the
+ <filename>/boot/loader.conf</filename> file:</para>
+
+ <programlisting>hw.ata.atapi_dma="1"</programlisting>
+
+ <para>Before attempting to use the
+ <application>dvd+rw-tools</application> you should consult the
+ <link xlink:href="http://fy.chalmers.se/~appro/linux/DVD+RW/hcn.html">dvd+rw-tools'
+ hardware compatibility notes</link> for any information
+ related to your DVD burner.</para>
+
+ <note>
+ <para>If you want a graphical user interface, you should have
+ a look to <application>K3b</application> (<package>sysutils/k3b</package>) which provides a
+ user friendly interface to &man.growisofs.1; and many others
+ burning tools.</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Burning Data DVDs</title>
+
+ <para>The &man.growisofs.1; command is a frontend to <link linkend="mkisofs">mkisofs</link>, it will invoke
+ &man.mkisofs.8; to create the file system layout and will
+ perform the write on the DVD. This means you do not need to
+ create an image of the data before the burning process.</para>
+
+ <para>To burn onto a DVD+R or a DVD-R the data from the <filename>/path/to/data</filename> directory, use the
+ following command:</para>
+
+ <screen>&prompt.root; <userinput>growisofs -dvd-compat -Z /dev/cd0 -J -R /path/to/data</userinput></screen>
+
+ <para>The options <option>-J -R</option> are passed to
+ &man.mkisofs.8; for the file system creation (in this case: an
+ ISO 9660 file system with Joliet and Rock Ridge extensions),
+ consult the &man.mkisofs.8; manual page for more
+ details.</para>
+
+ <para>The option <option>-Z</option> is used for the initial
+ session recording in any case: multiple sessions or not. The
+ DVD device, <replaceable>/dev/cd0</replaceable>, must be
+ changed according to your configuration. The
+ <option>-dvd-compat</option> parameter will close the disk,
+ the recording will be unappendable. In return this should provide better
+ media compatibility with DVD-ROM drives.</para>
+
+ <para>It is also possible to burn a pre-mastered image, for
+ example to burn the image
+ <replaceable>imagefile.iso</replaceable>, we will run:</para>
+
+ <screen>&prompt.root; <userinput>growisofs -dvd-compat -Z /dev/cd0=imagefile.iso</userinput></screen>
+
+ <para>The write speed should be detected and automatically set
+ according to the media and the drive being used. If you want
+ to force the write speed, use the <option>-speed=</option>
+ parameter. For more information, read the &man.growisofs.1;
+ manual page.</para>
+ </sect2>
+
+ <sect2>
+ <title>Burning a DVD-Video</title>
+
+ <indexterm>
+ <primary>DVD</primary>
+ <secondary>DVD-Video</secondary>
+ </indexterm>
+
+ <para>A DVD-Video is a specific file layout based on ISO 9660
+ and the micro-UDF (M-UDF) specifications. The DVD-Video also
+ presents a specific data structure hierarchy, it is the reason
+ why you need a particular program such as <package>multimedia/dvdauthor</package> to author the
+ DVD.</para>
+
+ <para>If you already have an image of the DVD-Video file system,
+ just burn it in the same way as for any image, see the
+ previous section for an example. If you have made the DVD
+ authoring and the result is in, for example, the directory
+ <filename>/path/to/video</filename>, the
+ following command should be used to burn the DVD-Video:</para>
+
+ <screen>&prompt.root; <userinput>growisofs -Z /dev/cd0 -dvd-video /path/to/video</userinput></screen>
+
+ <para>The <option>-dvd-video</option> option will be passed down to
+ &man.mkisofs.8; and will instruct it to create a DVD-Video file system
+ layout. Beside this, the <option>-dvd-video</option> option
+ implies <option>-dvd-compat</option> &man.growisofs.1;
+ option.</para>
+ </sect2>
+
+ <sect2>
+ <title>Using a DVD+RW</title>
+
+ <indexterm>
+ <primary>DVD</primary>
+ <secondary>DVD+RW</secondary>
+ </indexterm>
+
+ <para>Unlike CD-RW, a virgin DVD+RW needs to be formatted before
+ first use. The &man.growisofs.1; program will take care of it
+ automatically whenever appropriate, which is the
+ <emphasis>recommended</emphasis> way. However you can use the
+ <command>dvd+rw-format</command> command to format the
+ DVD+RW:</para>
+
+ <screen>&prompt.root; <userinput>dvd+rw-format /dev/cd0</userinput></screen>
+
+ <para>You need to perform this operation just once, keep in mind
+ that only virgin DVD+RW medias need to be formatted. Then you
+ can burn the DVD+RW in the way seen in previous
+ sections.</para>
+
+ <para>If you want to burn new data (burn a totally new file
+ system not append some data) onto a DVD+RW, you do not need to
+ blank it, you just have to write over the previous recording
+ (in performing a new initial session), like this:</para>
+
+ <screen>&prompt.root; <userinput>growisofs -Z /dev/cd0 -J -R /path/to/newdata</userinput></screen>
+
+ <para>DVD+RW format offers the possibility to easily append data
+ to a previous recording. The operation consists in merging a
+ new session to the existing one, it is not multisession
+ writing, &man.growisofs.1; will <emphasis>grow</emphasis> the
+ ISO 9660 file system present on the media.</para>
+
+ <para>For example, if we want to append data to our previous
+ DVD+RW, we have to use the following:</para>
+
+ <screen>&prompt.root; <userinput>growisofs -M /dev/cd0 -J -R /path/to/nextdata</userinput></screen>
+
+ <para>The same &man.mkisofs.8; options we used to burn the
+ initial session should be used during next writes.</para>
+
+ <note>
+ <para>You may want to use the <option>-dvd-compat</option>
+ option if you want better media compatibility with DVD-ROM
+ drives. In the DVD+RW case, this will not prevent you from
+ adding data.</para>
+ </note>
+
+ <para>If for any reason you really want to blank the media, do
+ the following:</para>
+
+ <screen>&prompt.root; <userinput>growisofs -Z /dev/cd0=/dev/zero</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Using a DVD-RW</title>
+
+ <indexterm>
+ <primary>DVD</primary>
+ <secondary>DVD-RW</secondary>
+ </indexterm>
+
+ <para>A DVD-RW accepts two disc formats: the incremental
+ sequential one and the restricted overwrite. By default
+ DVD-RW discs are in sequential format.</para>
+
+ <para>A virgin DVD-RW can be directly written without the need
+ of a formatting operation, however a non-virgin DVD-RW in
+ sequential format needs to be blanked before to be able to
+ write a new initial session.</para>
+
+ <para>To blank a DVD-RW in sequential mode, run:</para>
+
+ <screen>&prompt.root; <userinput>dvd+rw-format -blank=full /dev/cd0</userinput></screen>
+
+ <note>
+ <para>A full blanking (<option>-blank=full</option>) will take
+ about one hour on a 1x media. A fast blanking can be
+ performed using the <option>-blank</option> option if the
+ DVD-RW will be recorded in Disk-At-Once (DAO) mode. To burn
+ the DVD-RW in DAO mode, use the command:</para>
+
+ <screen>&prompt.root; <userinput>growisofs -use-the-force-luke=dao -Z /dev/cd0=imagefile.iso</userinput></screen>
+
+ <para>The <option>-use-the-force-luke=dao</option> option
+ should not be required since &man.growisofs.1; attempts to
+ detect minimally (fast blanked) media and engage DAO
+ write.</para>
+
+ <para>In fact one should use restricted overwrite mode with
+ any DVD-RW, this format is more flexible than the default
+ incremental sequential one.</para>
+ </note>
+
+ <para>To write data on a sequential DVD-RW, use the same
+ instructions as for the other DVD formats:</para>
+
+ <screen>&prompt.root; <userinput>growisofs -Z /dev/cd0 -J -R /path/to/data</userinput></screen>
+
+ <para>If you want to append some data to your previous
+ recording, you will have to use the &man.growisofs.1;
+ <option>-M</option> option. However, if you perform data
+ addition on a DVD-RW in incremental sequential mode, a new
+ session will be created on the disc and the result will be a
+ multi-session disc.</para>
+
+ <para>A DVD-RW in restricted overwrite format does not need to
+ be blanked before a new initial session, you just have to
+ overwrite the disc with the <option>-Z</option> option, this
+ is similar to the DVD+RW case. It is also possible to grow an
+ existing ISO 9660 file system written on the disc in a same
+ way as for a DVD+RW with the <option>-M</option> option. The
+ result will be a one-session DVD.</para>
+
+ <para>To put a DVD-RW in the restricted overwrite format, the
+ following command must be used:</para>
+
+ <screen>&prompt.root; <userinput>dvd+rw-format /dev/cd0</userinput></screen>
+
+ <para>To change back to the sequential format use:</para>
+
+ <screen>&prompt.root; <userinput>dvd+rw-format -blank=full /dev/cd0</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Multisession</title>
+
+ <para>Very few DVD-ROM drives support
+ multisession DVDs, they will most of time, hopefully, only read
+ the first session. DVD+R, DVD-R and DVD-RW in sequential
+ format can accept multiple sessions, the notion of multiple
+ sessions does not exist for the DVD+RW and the DVD-RW
+ restricted overwrite formats.</para>
+
+ <para>Using the following command after an initial (non-closed)
+ session on a DVD+R, DVD-R, or DVD-RW in sequential format,
+ will add a new session to the disc:</para>
+
+ <screen>&prompt.root; <userinput>growisofs -M /dev/cd0 -J -R /path/to/nextdata</userinput></screen>
+
+ <para>Using this command line with a DVD+RW or a DVD-RW in restricted
+ overwrite mode, will append data in merging the new session to
+ the existing one. The result will be a single-session disc.
+ This is the way used to add data after an initial write on these
+ medias.</para>
+
+ <note>
+ <para>Some space on the media is used between each session for
+ end and start of sessions. Therefore, one should add
+ sessions with large amount of data to optimize media space.
+ The number of sessions is limited to 154 for a DVD+R,
+ about 2000 for a DVD-R, and 127 for a DVD+R Double
+ Layer.</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>For More Information</title>
+
+ <para>To obtain more information about a DVD, the
+ <command>dvd+rw-mediainfo
+ /dev/cd0</command> command can be
+ ran with the disc in the drive.</para>
+
+ <para>More information about the
+ <application>dvd+rw-tools</application> can be found in
+ the &man.growisofs.1; manual page, on the <link xlink:href="http://fy.chalmers.se/~appro/linux/DVD+RW/">dvd+rw-tools
+ web site</link> and in the <link xlink:href="http://lists.debian.org/cdwrite/">cdwrite mailing
+ list</link> archives.</para>
+
+ <note>
+ <para>The <command>dvd+rw-mediainfo</command> output of the
+ resulting recording or the media with issues is mandatory
+ for any problem report. Without this output, it will be
+ quite impossible to help you.</para>
+ </note>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="floppies">
+ <info><title>Creating and Using Floppy Disks</title>
+ <authorgroup>
+ <author><personname><firstname>Julio</firstname><surname>Merino</surname></personname><contrib>Original work by </contrib></author>
+ </authorgroup>
+
+ <authorgroup>
+ <author><personname><firstname>Martin</firstname><surname>Karlsson</surname></personname><contrib>Rewritten by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <para>Storing data on floppy disks is sometimes useful, for
+ example when one does not have any other removable storage media
+ or when one needs to transfer small amounts of data to another
+ computer.</para>
+
+ <para>This section will explain how to use floppy disks in
+ FreeBSD. It will primarily cover formatting and usage of
+ 3.5inch DOS floppies, but the concepts are similar for other
+ floppy disk formats.</para>
+
+ <sect2>
+ <title>Formatting Floppies</title>
+
+ <sect3>
+ <title>The Device</title>
+
+ <para>Floppy disks are accessed through entries in
+ <filename>/dev</filename>, just like other devices. To
+ access the raw floppy disk, simply use
+ <filename>/dev/fdN</filename>.</para>
+
+ </sect3>
+
+ <sect3>
+ <title>Formatting</title>
+
+ <para>A floppy disk needs to be low-level formated before it
+ can be used. This is usually done by the vendor, but
+ formatting is a good way to check media integrity. Although
+ it is possible to force larger (or smaller) disk sizes,
+ 1440kB is what most floppy disks are designed for.</para>
+
+ <para>To low-level format the floppy disk you need to use
+ &man.fdformat.1;. This utility expects the device name as an
+ argument.</para>
+
+ <para>Make note of any error messages, as these can help
+ determine if the disk is good or bad.</para>
+
+ <sect4>
+ <title>Formatting Floppy Disks</title>
+
+ <para>Use the
+ <filename>/dev/fdN</filename>
+ devices to format the floppy. Insert a new 3.5inch floppy
+ disk in your drive and issue:</para>
+
+ <screen>&prompt.root; <userinput>/usr/sbin/fdformat -f 1440 /dev/fd0</userinput></screen>
+
+ </sect4>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>The Disk Label</title>
+
+ <para>After low-level formatting the disk, you will need to
+ place a disk label on it. This disk label will be destroyed
+ later, but it is needed by the system to determine the size of
+ the disk and its geometry later.</para>
+
+ <para>The new disk label will take over the whole disk, and will
+ contain all the proper information about the geometry of the
+ floppy. The geometry values for the disk label are listed in
+ <filename>/etc/disktab</filename>.</para>
+
+ <para>You can run now &man.bsdlabel.8; like so:</para>
+
+ <screen>&prompt.root; <userinput>/sbin/bsdlabel -B -r -w /dev/fd0 fd1440</userinput></screen>
+
+ <note><para>Since &os;&nbsp;5.1-RELEASE, the &man.bsdlabel.8;
+ utility replaces the old &man.bsdlabel.8; program. With
+ &man.bsdlabel.8; a number of obsolete options and parameters
+ have been retired; in the example above the option
+ <option>-r</option> should be removed. For more
+ information, please refer to the &man.bsdlabel.8;
+ manual page.</para></note>
+
+ </sect2>
+
+ <sect2>
+ <title>The File System</title>
+
+ <para>Now the floppy is ready to be high-level formated. This
+ will place a new file system on it, which will let FreeBSD read
+ and write to the disk. After creating the new file system, the
+ disk label is destroyed, so if you want to reformat the disk, you
+ will have to recreate the disk label.</para>
+
+ <para>The floppy's file system can be either UFS or FAT.
+ FAT is generally a better choice for floppies.</para>
+
+ <para>To put a new file system on the floppy, issue:</para>
+
+ <screen>&prompt.root; <userinput>/sbin/newfs_msdos /dev/fd0</userinput></screen>
+
+ <para>The disk is now ready for use.</para>
+ </sect2>
+
+
+ <sect2>
+ <title>Using the Floppy</title>
+
+ <para>To use the floppy, mount it with &man.mount.msdos.8;. One can also use
+ <package>emulators/mtools</package> from the ports
+ collection.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="backups-tapebackups">
+ <title>Creating and Using Data Tapes</title>
+
+ <indexterm><primary>tape media</primary></indexterm>
+ <para>The major tape media are the 4mm, 8mm, QIC, mini-cartridge and
+ DLT.</para>
+
+ <sect2 xml:id="backups-tapebackups-4mm">
+ <title>4mm (DDS: Digital Data Storage)</title>
+
+ <indexterm>
+ <primary>tape media</primary>
+ <secondary>DDS (4mm) tapes</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>tape media</primary>
+ <secondary>QIC tapes</secondary>
+ </indexterm>
+ <para>4mm tapes are replacing QIC as the workstation backup media of
+ choice. This trend accelerated greatly when Conner purchased Archive,
+ a leading manufacturer of QIC drives, and then stopped production of
+ QIC drives. 4mm drives are small and quiet but do not have the
+ reputation for reliability that is enjoyed by 8mm drives. The
+ cartridges are less expensive and smaller (3 x 2 x 0.5 inches, 76 x 51
+ x 12 mm) than 8mm cartridges. 4mm, like 8mm, has comparatively short
+ head life for the same reason, both use helical scan.</para>
+
+ <para>Data throughput on these drives starts ~150&nbsp;kB/s, peaking at ~500&nbsp;kB/s.
+ Data capacity starts at 1.3&nbsp;GB and ends at 2.0&nbsp;GB. Hardware
+ compression, available with most of these drives, approximately
+ doubles the capacity. Multi-drive tape library units can have 6
+ drives in a single cabinet with automatic tape changing. Library
+ capacities reach 240&nbsp;GB.</para>
+
+ <para>The DDS-3 standard now supports tape capacities up to 12&nbsp;GB (or
+ 24&nbsp;GB compressed).</para>
+
+ <para>4mm drives, like 8mm drives, use helical-scan. All the benefits
+ and drawbacks of helical-scan apply to both 4mm and 8mm drives.</para>
+
+ <para>Tapes should be retired from use after 2,000 passes or 100 full
+ backups.</para>
+ </sect2>
+
+ <sect2 xml:id="backups-tapebackups-8mm">
+ <title>8mm (Exabyte)</title>
+ <indexterm>
+ <primary>tape media</primary>
+ <secondary>Exabyte (8mm) tapes</secondary>
+ </indexterm>
+
+ <para>8mm tapes are the most common SCSI tape drives; they are the best
+ choice of exchanging tapes. Nearly every site has an Exabyte 2&nbsp;GB 8mm
+ tape drive. 8mm drives are reliable, convenient and quiet. Cartridges
+ are inexpensive and small (4.8 x 3.3 x 0.6 inches; 122 x 84 x 15 mm).
+ One downside of 8mm tape is relatively short head and tape life due to
+ the high rate of relative motion of the tape across the heads.</para>
+
+ <para>Data throughput ranges from ~250&nbsp;kB/s to ~500&nbsp;kB/s. Data sizes start
+ at 300&nbsp;MB and go up to 7&nbsp;GB. Hardware compression, available with
+ most of these drives, approximately doubles the capacity. These
+ drives are available as single units or multi-drive tape libraries
+ with 6 drives and 120 tapes in a single cabinet. Tapes are changed
+ automatically by the unit. Library capacities reach 840+&nbsp;GB.</para>
+
+ <para>The Exabyte <quote>Mammoth</quote> model supports 12&nbsp;GB on one tape
+ (24&nbsp;GB with compression) and costs approximately twice as much as
+ conventional tape drives.</para>
+
+ <para>Data is recorded onto the tape using helical-scan, the heads are
+ positioned at an angle to the media (approximately 6 degrees). The
+ tape wraps around 270 degrees of the spool that holds the heads. The
+ spool spins while the tape slides over the spool. The result is a
+ high density of data and closely packed tracks that angle across the
+ tape from one edge to the other.</para>
+ </sect2>
+
+ <sect2 xml:id="backups-tapebackups-qic">
+ <title>QIC</title>
+ <indexterm>
+ <primary>tape media</primary>
+ <secondary>QIC-150</secondary>
+ </indexterm>
+
+ <para>QIC-150 tapes and drives are, perhaps, the most common tape drive
+ and media around. QIC tape drives are the least expensive <quote>serious</quote>
+ backup drives. The downside is the cost of media. QIC tapes are
+ expensive compared to 8mm or 4mm tapes, up to 5 times the price per GB
+ data storage. But, if your needs can be satisfied with a half-dozen
+ tapes, QIC may be the correct choice. QIC is the
+ <emphasis>most</emphasis> common tape drive. Every site has a QIC
+ drive of some density or another. Therein lies the rub, QIC has a
+ large number of densities on physically similar (sometimes identical)
+ tapes. QIC drives are not quiet. These drives audibly seek before
+ they begin to record data and are clearly audible whenever reading,
+ writing or seeking. QIC tapes measure (6 x 4 x 0.7 inches; 152 x
+ 102 x 17 mm).</para>
+
+ <para>Data throughput ranges from ~150&nbsp;kB/s to ~500&nbsp;kB/s. Data capacity
+ ranges from 40&nbsp;MB to 15&nbsp;GB. Hardware compression is available on many
+ of the newer QIC drives. QIC drives are less frequently installed;
+ they are being supplanted by DAT drives.</para>
+
+ <para>Data is recorded onto the tape in tracks. The tracks run along
+ the long axis of the tape media from one end to the other. The number
+ of tracks, and therefore the width of a track, varies with the tape's
+ capacity. Most if not all newer drives provide backward-compatibility
+ at least for reading (but often also for writing). QIC has a good
+ reputation regarding the safety of the data (the mechanics are simpler
+ and more robust than for helical scan drives).</para>
+
+ <para>Tapes should be retired from use after 5,000 backups.</para>
+ </sect2>
+
+ <sect2 xml:id="backups-tapebackups-dlt">
+ <title>DLT</title>
+ <indexterm>
+ <primary>tape media</primary>
+ <secondary>DLT</secondary>
+ </indexterm>
+
+ <para>DLT has the fastest data transfer rate of all the drive types
+ listed here. The 1/2" (12.5mm) tape is contained in a single spool
+ cartridge (4 x 4 x 1 inches; 100 x 100 x 25 mm). The cartridge has a
+ swinging gate along one entire side of the cartridge. The drive
+ mechanism opens this gate to extract the tape leader. The tape leader
+ has an oval hole in it which the drive uses to <quote>hook</quote> the tape. The
+ take-up spool is located inside the tape drive. All the other tape
+ cartridges listed here (9 track tapes are the only exception) have
+ both the supply and take-up spools located inside the tape cartridge
+ itself.</para>
+
+ <para>Data throughput is approximately 1.5&nbsp;MB/s, three times the throughput of
+ 4mm, 8mm, or QIC tape drives. Data capacities range from 10&nbsp;GB to 20&nbsp;GB
+ for a single drive. Drives are available in both multi-tape changers
+ and multi-tape, multi-drive tape libraries containing from 5 to 900
+ tapes over 1 to 20 drives, providing from 50&nbsp;GB to 9&nbsp;TB of
+ storage.</para>
+
+ <para>With compression, DLT Type IV format supports up to 70&nbsp;GB
+ capacity.</para>
+
+ <para>Data is recorded onto the tape in tracks parallel to the direction
+ of travel (just like QIC tapes). Two tracks are written at once.
+ Read/write head lifetimes are relatively long; once the tape stops
+ moving, there is no relative motion between the heads and the
+ tape.</para>
+ </sect2>
+
+ <sect2>
+ <title xml:id="backups-tapebackups-ait">AIT</title>
+ <indexterm>
+ <primary>tape media</primary>
+ <secondary>AIT</secondary>
+ </indexterm>
+
+ <para>AIT is a new format from Sony, and can hold up to 50&nbsp;GB (with
+ compression) per tape. The tapes contain memory chips which retain an
+ index of the tape's contents. This index can be rapidly read by the
+ tape drive to determine the position of files on the tape, instead of
+ the several minutes that would be required for other tapes. Software
+ such as <application>SAMS:Alexandria</application> can operate forty or more AIT tape libraries,
+ communicating directly with the tape's memory chip to display the
+ contents on screen, determine what files were backed up to which
+ tape, locate the correct tape, load it, and restore the data from the
+ tape.</para>
+
+ <para>Libraries like this cost in the region of $20,000, pricing them a
+ little out of the hobbyist market.</para>
+ </sect2>
+
+ <sect2>
+ <title>Using a New Tape for the First Time</title>
+
+ <para>The first time that you try to read or write a new, completely
+ blank tape, the operation will fail. The console messages should be
+ similar to:</para>
+
+ <screen>sa0(ncr1:4:0): NOT READY asc:4,1
+sa0(ncr1:4:0): Logical unit is in process of becoming ready</screen>
+
+ <para>The tape does not contain an Identifier Block (block number 0).
+ All QIC tape drives since the adoption of QIC-525 standard write an
+ Identifier Block to the tape. There are two solutions:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><command>mt fsf 1</command> causes the tape drive to write an
+ Identifier Block to the tape.</para>
+ </listitem>
+
+ <listitem>
+ <para>Use the front panel button to eject the tape.</para>
+
+ <para>Re-insert the tape and <command>dump</command> data to
+ the tape.</para>
+
+ <para><command>dump</command> will report <errorname>DUMP: End of tape
+ detected</errorname> and the console will show: <errorname>HARDWARE
+ FAILURE info:280 asc:80,96</errorname>.</para>
+
+ <para>rewind the tape using: <command>mt rewind</command>.</para>
+
+ <para>Subsequent tape operations are successful.</para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="backups-floppybackups">
+ <title>Backups to Floppies</title>
+
+ <sect2 xml:id="floppies-using">
+ <title>Can I Use Floppies for Backing Up My Data?</title>
+ <indexterm><primary>backup floppies</primary></indexterm>
+ <indexterm><primary>floppy disks</primary></indexterm>
+
+ <para>Floppy disks are not really a suitable media for
+ making backups as:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The media is unreliable, especially over long periods of
+ time.</para>
+ </listitem>
+
+ <listitem>
+ <para>Backing up and restoring is very slow.</para>
+ </listitem>
+
+ <listitem>
+ <para>They have a very limited capacity (the days of backing up
+ an entire hard disk onto a dozen or so floppies has long since
+ passed).</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>However, if you have no other method of backing up your data then
+ floppy disks are better than no backup at all.</para>
+
+ <para>If you do have to use floppy disks then ensure that you use good
+ quality ones. Floppies that have been lying around the office for a
+ couple of years are a bad choice. Ideally use new ones from a
+ reputable manufacturer.</para>
+ </sect2>
+
+ <sect2 xml:id="floppies-creating">
+ <title>So How Do I Backup My Data to Floppies?</title>
+
+ <para>The best way to backup to floppy disk is to use
+ &man.tar.1; with the <option>-M</option> (multi
+ volume) option, which allows backups to span multiple
+ floppies.</para>
+
+ <para>To backup all the files in the current directory and sub-directory
+ use this (as <systemitem class="username">root</systemitem>):</para>
+
+ <screen>&prompt.root; <userinput>tar Mcvf /dev/fd0 *</userinput></screen>
+
+ <para>When the first floppy is full &man.tar.1; will prompt you to
+ insert the next volume (because &man.tar.1; is media independent it
+ refers to volumes; in this context it means floppy disk).</para>
+
+ <screen>Prepare volume #2 for /dev/fd0 and hit return:</screen>
+
+ <para>This is repeated (with the volume number incrementing) until all
+ the specified files have been archived.</para>
+ </sect2>
+
+ <sect2 xml:id="floppies-compress">
+ <title>Can I Compress My Backups?</title>
+ <indexterm>
+ <primary><command>tar</command></primary>
+ </indexterm>
+ <indexterm>
+ <primary><command>gzip</command></primary>
+ </indexterm>
+ <indexterm><primary>compression</primary></indexterm>
+
+ <para>Unfortunately, &man.tar.1; will not allow the
+ <option>-z</option> option to be used for multi-volume archives.
+ You could, of course, &man.gzip.1; all the files,
+ &man.tar.1; them to the floppies, then
+ &man.gunzip.1; the files again!</para>
+ </sect2>
+
+ <sect2 xml:id="floppies-restoring">
+ <title>How Do I Restore My Backups?</title>
+
+ <para>To restore the entire archive use:</para>
+
+ <screen>&prompt.root; <userinput>tar Mxvf /dev/fd0</userinput></screen>
+
+ <para>There are two ways that you can use to restore only
+ specific files. First, you can start with the first floppy
+ and use:</para>
+
+ <screen>&prompt.root; <userinput>tar Mxvf /dev/fd0 filename</userinput></screen>
+
+ <para>The utility &man.tar.1; will prompt you to insert subsequent floppies until it
+ finds the required file.</para>
+
+ <para>Alternatively, if you know which floppy the file is on then you
+ can simply insert that floppy and use the same command as above. Note
+ that if the first file on the floppy is a continuation from the
+ previous one then &man.tar.1; will warn you that it cannot
+ restore it, even if you have not asked it to!</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="backup-strategies">
+ <info><title>Backup Strategies</title>
+ <authorgroup>
+ <author><personname><firstname>Lowell</firstname><surname>Gilbert</surname></personname><contrib>Original work by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <para>The first requirement in devising a backup plan is to make sure that
+ all of the following problems are covered:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Disk failure</para>
+ </listitem>
+ <listitem>
+ <para>Accidental file deletion</para>
+ </listitem>
+ <listitem>
+ <para>Random file corruption</para>
+ </listitem>
+ <listitem>
+ <para>Complete machine destruction (e.g. fire), including destruction
+ of any on-site backups.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>It is perfectly possible that some systems will be best served by
+ having each of these problems covered by a completely different
+ technique. Except for strictly personal systems with very low-value
+ data, it is unlikely that one technique would cover all of them.</para>
+
+ <para>Some of the techniques in the toolbox are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Archives of the whole system, backed up onto permanent media
+ offsite. This actually provides protection against all of the
+ possible problems listed above, but is slow and inconvenient to
+ restore from. You can keep copies of the backups onsite and/or
+ online, but there will still be inconveniences in restoring files,
+ especially for non-privileged users.</para>
+ </listitem>
+
+ <listitem>
+ <para>Filesystem snapshots. This is really only helpful in the
+ accidental file deletion scenario, but it can be
+ <emphasis>very</emphasis> helpful in that case, and is quick and
+ easy to deal with.</para>
+ </listitem>
+
+ <listitem>
+ <para>Copies of whole filesystems and/or disks (e.g. periodic rsync of
+ the whole machine). This is generally most useful in networks with
+ unique requirements. For general protection against disk failure,
+ it is usually inferior to <acronym>RAID</acronym>. For restoring
+ accidentally deleted files, it can be comparable to
+ <acronym>UFS</acronym> snapshots, but that depends on your
+ preferences.</para>
+ </listitem>
+
+ <listitem>
+ <para><acronym>RAID</acronym>. Minimizes or avoids downtime when a
+ disk fails. At the expense of having to deal with disk failures
+ more often (because you have more disks), albeit at a much lower
+ urgency.</para>
+ </listitem>
+
+ <listitem>
+ <para>Checking fingerprints of files. The &man.mtree.8; utility is
+ very useful for this. Although it is not a backup technique, it
+ helps guarantee that you will notice when you need to resort to your
+ backups. This is particularly important for offline backups, and
+ should be checked periodically.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>It is quite easy to come up with even more techniques, many of them
+ variations on the ones listed above. Specialized requirements will
+ usually lead to specialized techniques (for example, backing up a live
+ database usually requires a method particular to the database software
+ as an intermediate step). The important thing is to know what dangers
+ you want to protect against, and how you will handle each.</para>
+ </sect1>
+
+ <sect1 xml:id="backup-basics">
+ <title>Backup Basics</title>
+
+ <para>The three major backup programs are
+ &man.dump.8;,
+ &man.tar.1;,
+ and
+ &man.cpio.1;.</para>
+
+ <sect2>
+ <title>Dump and Restore</title>
+ <indexterm>
+ <primary>backup software</primary>
+ <secondary>dump / restore</secondary>
+ </indexterm>
+ <indexterm><primary><command>dump</command></primary></indexterm>
+ <indexterm><primary><command>restore</command></primary></indexterm>
+
+ <para>The traditional &unix; backup programs are
+ <command>dump</command> and <command>restore</command>. They
+ operate on the drive as a collection of disk blocks, below the
+ abstractions of files, links and directories that are created by
+ the file systems. <command>dump</command> backs up an entire
+ file system on a device. It is unable to backup only part of a
+ file system or a directory tree that spans more than one
+ file system. <command>dump</command> does not write files and
+ directories to tape, but rather writes the raw data blocks that
+ comprise files and directories.</para>
+
+ <note><para>If you use <command>dump</command> on your root directory, you
+ would not back up <filename>/home</filename>,
+ <filename>/usr</filename> or many other directories since
+ these are typically mount points for other file systems or
+ symbolic links into those file systems.</para></note>
+
+ <para><command>dump</command> has quirks that remain from its early days in
+ Version 6 of AT&amp;T UNIX (circa 1975). The default
+ parameters are suitable for 9-track tapes (6250 bpi), not the
+ high-density media available today (up to 62,182 ftpi). These
+ defaults must be overridden on the command line to utilize the
+ capacity of current tape drives.</para>
+
+ <indexterm><primary><filename>.rhosts</filename></primary></indexterm>
+ <para>It is also possible to backup data across the network to a
+ tape drive attached to another computer with <command>rdump</command> and
+ <command>rrestore</command>. Both programs rely upon &man.rcmd.3; and
+ &man.ruserok.3; to access the remote tape drive. Therefore,
+ the user performing the backup must be listed in the
+ <filename>.rhosts</filename> file on the remote computer. The
+ arguments to <command>rdump</command> and <command>rrestore</command> must be suitable
+ to use on the remote computer. When
+ <command>rdump</command>ing from a FreeBSD computer to an
+ Exabyte tape drive connected to a Sun called
+ <systemitem>komodo</systemitem>, use:</para>
+
+ <screen>&prompt.root; <userinput>/sbin/rdump 0dsbfu 54000 13000 126 komodo:/dev/nsa8 /dev/da0a 2&gt;&amp;1</userinput></screen>
+
+ <para>Beware: there are security implications to
+ allowing <filename>.rhosts</filename> authentication. Evaluate your
+ situation carefully.</para>
+
+ <para>It is also possible to use <command>dump</command> and
+ <command>restore</command> in a more secure fashion over
+ <command>ssh</command>.</para>
+
+ <example>
+ <title>Using <command>dump</command> over <application>ssh</application></title>
+
+ <screen>&prompt.root; <userinput>/sbin/dump -0uan -f - /usr | gzip -2 | ssh -c blowfish \
+ targetuser@targetmachine.example.com dd of=/mybigfiles/dump-usr-l0.gz</userinput></screen>
+
+ </example>
+
+ <para>Or using <command>dump</command>'s built-in method,
+ setting the environment variable <envar>RSH</envar>:</para>
+
+ <example>
+ <title>Using <command>dump</command> over <application>ssh</application> with <envar>RSH</envar> set</title>
+
+ <screen>&prompt.root; <userinput>RSH=/usr/bin/ssh /sbin/dump -0uan -f targetuser@targetmachine.example.com:/dev/sa0 /usr</userinput></screen>
+
+ </example>
+
+ </sect2>
+
+ <sect2>
+ <title><command>tar</command></title>
+ <indexterm>
+ <primary>backup software</primary>
+ <secondary><command>tar</command></secondary>
+ </indexterm>
+
+ <para>&man.tar.1; also dates back to Version 6 of AT&amp;T UNIX
+ (circa 1975). <command>tar</command> operates in cooperation
+ with the file system; it writes files and
+ directories to tape. <command>tar</command> does not support the
+ full range of options that are available from &man.cpio.1;, but
+ it does not require the unusual command
+ pipeline that <command>cpio</command> uses.</para>
+
+ <indexterm><primary><command>tar</command></primary></indexterm>
+
+ <para>On FreeBSD 5.3 and later, both GNU <command>tar</command>
+ and the default <command>bsdtar</command> are available. The
+ GNU version can be invoked with <command>gtar</command>. It
+ supports remote devices using the same syntax as
+ <command>rdump</command>. To <command>tar</command> to an
+ Exabyte tape drive connected to a Sun called
+ <systemitem>komodo</systemitem>, use:</para>
+
+ <screen>&prompt.root; <userinput>/usr/bin/gtar cf komodo:/dev/nsa8 . 2&gt;&amp;1</userinput></screen>
+
+ <para>The same could be accomplished with
+ <command>bsdtar</command> by using a pipeline and
+ <command>rsh</command> to send the data to a remote tape
+ drive.</para>
+
+ <screen>&prompt.root; <userinput>tar cf - . | rsh hostname dd of=tape-device obs=20b</userinput></screen>
+
+ <para>If you are worried about the security of backing up over a
+ network you should use the <command>ssh</command> command
+ instead of <command>rsh</command>.</para>
+ </sect2>
+
+ <sect2>
+ <title><command>cpio</command></title>
+ <indexterm>
+ <primary>backup software</primary>
+ <secondary><command>cpio</command></secondary>
+ </indexterm>
+
+ <para>&man.cpio.1; is the original &unix; file interchange tape
+ program for magnetic media. <command>cpio</command> has options
+ (among many others) to perform byte-swapping, write a number of
+ different archive formats, and pipe the data to other programs.
+ This last feature makes <command>cpio</command> an excellent
+ choice for installation media. <command>cpio</command> does not
+ know how to walk the directory tree and a list of files must be
+ provided through <filename>stdin</filename>.</para>
+ <indexterm><primary><command>cpio</command></primary></indexterm>
+
+ <para><command>cpio</command> does not support backups across
+ the network. You can use a pipeline and <command>rsh</command>
+ to send the data to a remote tape drive.</para>
+
+ <screen>&prompt.root; <userinput>for f in directory_list; do</userinput>
+<userinput>find $f &gt;&gt; backup.list</userinput>
+<userinput>done</userinput>
+&prompt.root; <userinput>cpio -v -o --format=newc &lt; backup.list | ssh user@host "cat &gt; backup_device"</userinput></screen>
+
+ <para>Where <replaceable>directory_list</replaceable> is the list of
+ directories you want to back up,
+ <replaceable>user</replaceable>@<replaceable>host</replaceable> is the
+ user/hostname combination that will be performing the backups, and
+ <replaceable>backup_device</replaceable> is where the backups should
+ be written to (e.g., <filename>/dev/nsa0</filename>).</para>
+ </sect2>
+
+ <sect2>
+ <title><command>pax</command></title>
+ <indexterm>
+ <primary>backup software</primary>
+ <secondary><command>pax</command></secondary>
+ </indexterm>
+ <indexterm><primary><command>pax</command></primary></indexterm>
+ <indexterm><primary>POSIX</primary></indexterm>
+ <indexterm><primary>IEEE</primary></indexterm>
+
+ <para>&man.pax.1; is IEEE/&posix;'s answer to
+ <command>tar</command> and <command>cpio</command>. Over the
+ years the various versions of <command>tar</command> and
+ <command>cpio</command> have gotten slightly incompatible. So
+ rather than fight it out to fully standardize them, &posix;
+ created a new archive utility. <command>pax</command> attempts
+ to read and write many of the various <command>cpio</command>
+ and <command>tar</command> formats, plus new formats of its own.
+ Its command set more resembles <command>cpio</command> than
+ <command>tar</command>.</para>
+ </sect2>
+
+ <sect2 xml:id="backups-programs-amanda">
+ <title><application>Amanda</application></title>
+ <indexterm>
+ <primary>backup software</primary>
+ <secondary><application>Amanda</application></secondary>
+ </indexterm>
+ <indexterm><primary><application>Amanda</application></primary></indexterm>
+
+ <!-- Remove link until <port> tag is available -->
+ <para><application>Amanda</application> (Advanced Maryland
+ Network Disk Archiver) is a client/server backup system,
+ rather than a single program. An <application>Amanda</application> server will backup to
+ a single tape drive any number of computers that have <application>Amanda</application>
+ clients and a network connection to the <application>Amanda</application> server. A
+ common problem at sites with a number of large disks is
+ that the length of time required to backup to data directly to tape
+ exceeds the amount of time available for the task. <application>Amanda</application>
+ solves this problem. <application>Amanda</application> can use a <quote>holding disk</quote> to
+ backup several file systems at the same time. <application>Amanda</application> creates
+ <quote>archive sets</quote>: a group of tapes used over a period of time to
+ create full backups of all the file systems listed in <application>Amanda</application>'s
+ configuration file. The <quote>archive set</quote> also contains nightly
+ incremental (or differential) backups of all the file systems.
+ Restoring a damaged file system requires the most recent full
+ backup and the incremental backups.</para>
+
+ <para>The configuration file provides fine control of backups and the
+ network traffic that <application>Amanda</application> generates. <application>Amanda</application> will use any of the
+ above backup programs to write the data to tape. <application>Amanda</application> is available
+ as either a port or a package, it is not installed by default.</para>
+ </sect2>
+
+ <sect2>
+ <title>Do Nothing</title>
+
+ <para><quote>Do nothing</quote> is not a computer program, but it is the
+ most widely used backup strategy. There are no initial costs. There
+ is no backup schedule to follow. Just say no. If something happens
+ to your data, grin and bear it!</para>
+
+ <para>If your time and your data is worth little to nothing, then
+ <quote>Do nothing</quote> is the most suitable backup program for your
+ computer. But beware, &unix; is a useful tool, you may find that within
+ six months you have a collection of files that are valuable to
+ you.</para>
+
+ <para><quote>Do nothing</quote> is the correct backup method for
+ <filename>/usr/obj</filename> and other directory trees that can be
+ exactly recreated by your computer. An example is the files that
+ comprise the HTML or &postscript; version of this Handbook.
+ These document formats have been created from SGML input
+ files. Creating backups of the HTML or &postscript; files is
+ not necessary. The SGML files are backed up regularly.</para>
+ </sect2>
+
+ <sect2>
+ <title>Which Backup Program Is Best?</title>
+ <indexterm>
+ <primary>LISA</primary>
+ </indexterm>
+
+ <para>&man.dump.8; <emphasis>Period.</emphasis> Elizabeth D. Zwicky
+ torture tested all the backup programs discussed here. The clear
+ choice for preserving all your data and all the peculiarities of &unix;
+ file systems is <command>dump</command>. Elizabeth created file systems containing
+ a large variety of unusual conditions (and some not so unusual ones)
+ and tested each program by doing a backup and restore of those
+ file systems. The peculiarities included: files with holes, files with
+ holes and a block of nulls, files with funny characters in their
+ names, unreadable and unwritable files, devices, files that change
+ size during the backup, files that are created/deleted during the
+ backup and more. She presented the results at LISA V in Oct. 1991.
+ See <link xlink:href="http://berdmann.dyndns.org/zwicky/testdump.doc.html">torture-testing
+ Backup and Archive Programs</link>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Emergency Restore Procedure</title>
+
+ <sect3>
+ <title>Before the Disaster</title>
+
+ <para>There are only four steps that you need to perform in
+ preparation for any disaster that may occur.</para>
+ <indexterm>
+ <primary><command>bsdlabel</command></primary>
+ </indexterm>
+
+ <para>First, print the bsdlabel from each of your disks
+ (e.g. <command>bsdlabel da0 | lpr</command>), your file system table
+ (<filename>/etc/fstab</filename>) and all boot messages,
+ two copies of
+ each.</para>
+
+ <indexterm><primary>fix-it floppies</primary></indexterm>
+ <para>Second, determine that the boot and fix-it floppies
+ (<filename>boot.flp</filename> and <filename>fixit.flp</filename>)
+ have all your devices. The easiest way to check is to reboot your
+ machine with the boot floppy in the floppy drive and check the boot
+ messages. If all your devices are listed and functional, skip on to
+ step three.</para>
+
+ <para>Otherwise, you have to create two custom bootable
+ floppies which have a kernel that can mount all of your disks
+ and access your tape drive. These floppies must contain:
+ <command>fdisk</command>, <command>bsdlabel</command>,
+ <command>newfs</command>, <command>mount</command>, and
+ whichever backup program you use. These programs must be
+ statically linked. If you use <command>dump</command>, the
+ floppy must contain <command>restore</command>.</para>
+
+ <para>Third, create backup tapes regularly. Any changes that you make
+ after your last backup may be irretrievably lost. Write-protect the
+ backup tapes.</para>
+
+ <para>Fourth, test the floppies (either <filename>boot.flp</filename>
+ and <filename>fixit.flp</filename> or the two custom bootable
+ floppies you made in step two.) and backup tapes. Make notes of the
+ procedure. Store these notes with the bootable floppy, the
+ printouts and the backup tapes. You will be so distraught when
+ restoring that the notes may prevent you from destroying your backup
+ tapes (How? In place of <command>tar xvf /dev/sa0</command>, you
+ might accidentally type <command>tar cvf /dev/sa0</command> and
+ over-write your backup tape).</para>
+
+ <para>For an added measure of security, make bootable floppies and two
+ backup tapes each time. Store one of each at a remote location. A
+ remote location is NOT the basement of the same office building. A
+ number of firms in the World Trade Center learned this lesson the
+ hard way. A remote location should be physically separated from
+ your computers and disk drives by a significant distance.</para>
+
+ <example>
+ <title>A Script for Creating a Bootable Floppy</title>
+
+ <programlisting><![CDATA[#!/bin/sh
+#
+# create a restore floppy
+#
+# format the floppy
+#
+PATH=/bin:/sbin:/usr/sbin:/usr/bin
+
+fdformat -q fd0
+if [ $? -ne 0 ]
+then
+ echo "Bad floppy, please use a new one"
+ exit 1
+fi
+
+# place boot blocks on the floppy
+#
+bsdlabel -w -B /dev/fd0c fd1440
+
+#
+# newfs the one and only partition
+#
+newfs -t 2 -u 18 -l 1 -c 40 -i 5120 -m 5 -o space /dev/fd0a
+
+#
+# mount the new floppy
+#
+mount /dev/fd0a /mnt
+
+#
+# create required directories
+#
+mkdir /mnt/dev
+mkdir /mnt/bin
+mkdir /mnt/sbin
+mkdir /mnt/etc
+mkdir /mnt/root
+mkdir /mnt/mnt # for the root partition
+mkdir /mnt/tmp
+mkdir /mnt/var
+
+#
+# populate the directories
+#
+if [ ! -x /sys/compile/MINI/kernel ]
+then
+ cat &lt;&lt; EOM
+The MINI kernel does not exist, please create one.
+Here is an example config file:
+#
+# MINI - A kernel to get FreeBSD onto a disk.
+#
+machine "i386"
+cpu "I486_CPU"
+ident MINI
+maxusers 5
+
+options INET # needed for _tcp _icmpstat _ipstat
+ # _udpstat _tcpstat _udb
+options FFS #Berkeley Fast File System
+options FAT_CURSOR #block cursor in syscons or pccons
+options SCSI_DELAY=15 #Be pessimistic about Joe SCSI device
+options NCONS=2 #1 virtual consoles
+options USERCONFIG #Allow user configuration with -c XXX
+
+config kernel root on da0 swap on da0 and da1 dumps on da0
+
+device isa0
+device pci0
+
+device fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr
+device fd0 at fdc0 drive 0
+
+device ncr0
+
+device scbus0
+
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+device npx0 at isa? port "IO_NPX" irq 13 vector npxintr
+
+device da0
+device da1
+device da2
+
+device sa0
+
+pseudo-device loop # required by INET
+pseudo-device gzip # Exec gzipped a.out's
+EOM
+ exit 1
+fi
+
+cp -f /sys/compile/MINI/kernel /mnt
+
+gzip -c -best /sbin/init &gt; /mnt/sbin/init
+gzip -c -best /sbin/fsck &gt; /mnt/sbin/fsck
+gzip -c -best /sbin/mount &gt; /mnt/sbin/mount
+gzip -c -best /sbin/halt &gt; /mnt/sbin/halt
+gzip -c -best /sbin/restore &gt; /mnt/sbin/restore
+
+gzip -c -best /bin/sh &gt; /mnt/bin/sh
+gzip -c -best /bin/sync &gt; /mnt/bin/sync
+
+cp /root/.profile /mnt/root
+
+cp -f /dev/MAKEDEV /mnt/dev
+chmod 755 /mnt/dev/MAKEDEV
+
+chmod 500 /mnt/sbin/init
+chmod 555 /mnt/sbin/fsck /mnt/sbin/mount /mnt/sbin/halt
+chmod 555 /mnt/bin/sh /mnt/bin/sync
+chmod 6555 /mnt/sbin/restore
+
+#
+# create the devices nodes
+#
+cd /mnt/dev
+./MAKEDEV std
+./MAKEDEV da0
+./MAKEDEV da1
+./MAKEDEV da2
+./MAKEDEV sa0
+./MAKEDEV pty0
+cd /
+
+#
+# create minimum file system table
+#
+cat &gt; /mnt/etc/fstab &lt;&lt;EOM
+/dev/fd0a / ufs rw 1 1
+EOM
+
+#
+# create minimum passwd file
+#
+cat &gt; /mnt/etc/passwd &lt;&lt;EOM
+root:*:0:0:Charlie &:/root:/bin/sh
+EOM
+
+cat &gt; /mnt/etc/master.passwd &lt;&lt;EOM
+root::0:0::0:0:Charlie &:/root:/bin/sh
+EOM
+
+chmod 600 /mnt/etc/master.passwd
+chmod 644 /mnt/etc/passwd
+/usr/sbin/pwd_mkdb -d/mnt/etc /mnt/etc/master.passwd
+
+#
+# umount the floppy and inform the user
+#
+/sbin/umount /mnt
+echo "The floppy has been unmounted and is now ready."]]></programlisting>
+
+ </example>
+
+ </sect3>
+
+ <sect3>
+ <title>After the Disaster</title>
+
+ <para>The key question is: did your hardware survive? You have been
+ doing regular backups so there is no need to worry about the
+ software.</para>
+
+ <para>If the hardware has been damaged, the parts should be replaced
+ before attempting to use the computer.</para>
+
+ <para>If your hardware is okay, check your floppies. If you are using
+ a custom boot floppy, boot single-user (type <literal>-s</literal>
+ at the <prompt>boot:</prompt> prompt). Skip the following
+ paragraph.</para>
+
+ <para>If you are using the <filename>boot.flp</filename> and
+ <filename>fixit.flp</filename> floppies, keep reading. Insert the
+ <filename>boot.flp</filename> floppy in the first floppy drive and
+ boot the computer. The original install menu will be displayed on
+ the screen. Select the <literal>Fixit--Repair mode with CDROM or
+ floppy.</literal> option. Insert the
+ <filename>fixit.flp</filename> when prompted.
+ <command>restore</command> and the other programs that you need are
+ located in <filename>/mnt2/rescue</filename>
+ (<filename>/mnt2/stand</filename> for
+ &os; versions older than 5.2).</para>
+
+ <para>Recover each file system separately.</para>
+
+ <indexterm>
+ <primary><command>mount</command></primary>
+ </indexterm>
+ <indexterm><primary>root partition</primary></indexterm>
+ <indexterm>
+ <primary><command>bsdlabel</command></primary>
+ </indexterm>
+ <indexterm>
+ <primary><command>newfs</command></primary>
+ </indexterm>
+ <para>Try to <command>mount</command> (e.g. <command>mount /dev/da0a
+ /mnt</command>) the root partition of your first disk. If the
+ bsdlabel was damaged, use <command>bsdlabel</command> to re-partition and
+ label the disk to match the label that you printed and saved. Use
+ <command>newfs</command> to re-create the file systems. Re-mount the root
+ partition of the floppy read-write (<command>mount -u -o rw
+ /mnt</command>). Use your backup program and backup tapes to
+ recover the data for this file system (e.g. <command>restore vrf
+ /dev/sa0</command>). Unmount the file system (e.g. <command>umount
+ /mnt</command>). Repeat for each file system that was
+ damaged.</para>
+
+ <para>Once your system is running, backup your data onto new tapes.
+ Whatever caused the crash or data loss may strike again. Another
+ hour spent now may save you from further distress later.</para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="disks-virtual">
+ <info><title>Network, Memory, and File-Backed File Systems</title>
+ <authorgroup>
+ <author><personname><firstname>Marc</firstname><surname>Fonvieille</surname></personname><contrib>Reorganized and enhanced by </contrib></author>
+ </authorgroup>
+ </info>
+
+ <indexterm><primary>virtual disks</primary></indexterm>
+ <indexterm>
+ <primary>disks</primary>
+ <secondary>virtual</secondary>
+ </indexterm>
+
+ <para>Aside from the disks you physically insert into your computer:
+ floppies, CDs, hard drives, and so forth; other forms of disks
+ are understood by FreeBSD - the <firstterm>virtual
+ disks</firstterm>.</para>
+
+ <indexterm><primary>NFS</primary></indexterm>
+ <indexterm><primary>Coda</primary></indexterm>
+ <indexterm>
+ <primary>disks</primary>
+ <secondary>memory</secondary>
+ </indexterm>
+ <para>These include network file systems such as the <link linkend="network-nfs">Network File System</link> and Coda, memory-based
+ file systems and
+ file-backed file systems.</para>
+
+ <para>According to the FreeBSD version you run, you will have to use
+ different tools for creation and use of file-backed and
+ memory-based file systems.</para>
+
+ <note>
+ <para>Use &man.devfs.5; to allocate device nodes transparently for the
+ user.</para>
+ </note>
+
+ <sect2 xml:id="disks-mdconfig">
+ <title>File-Backed File System</title>
+ <indexterm>
+ <primary>disks</primary>
+ <secondary>file-backed</secondary>
+ </indexterm>
+
+ <para>The utility &man.mdconfig.8; is used to configure and enable
+ memory disks, &man.md.4;, under FreeBSD. To use
+ &man.mdconfig.8;, you have to load &man.md.4; module or to add
+ the support in your kernel configuration file:</para>
+
+ <programlisting>device md</programlisting>
+
+ <para>The &man.mdconfig.8; command supports three kinds of
+ memory backed virtual disks: memory disks allocated with
+ &man.malloc.9;, memory disks using a file or swap space as
+ backing. One possible use is the mounting of floppy
+ or CD images kept in files.</para>
+
+ <para>To mount an existing file system image:</para>
+
+ <example>
+ <title>Using <command>mdconfig</command> to Mount an Existing File System
+ Image</title>
+
+ <screen>&prompt.root; <userinput>mdconfig -a -t vnode -f diskimage -u 0</userinput>
+&prompt.root; <userinput>mount /dev/md0 /mnt</userinput></screen>
+ </example>
+
+ <para>To create a new file system image with &man.mdconfig.8;:</para>
+
+ <example>
+ <title>Creating a New File-Backed Disk with <command>mdconfig</command></title>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/zero of=newimage bs=1k count=5k</userinput>
+5120+0 records in
+5120+0 records out
+&prompt.root; <userinput>mdconfig -a -t vnode -f newimage -u 0</userinput>
+&prompt.root; <userinput>bsdlabel -w md0 auto</userinput>
+&prompt.root; <userinput>newfs md0a</userinput>
+/dev/md0a: 5.0MB (10224 sectors) block size 16384, fragment size 2048
+ using 4 cylinder groups of 1.25MB, 80 blks, 192 inodes.
+super-block backups (for fsck -b #) at:
+ 160, 2720, 5280, 7840
+&prompt.root; <userinput>mount /dev/md0a /mnt</userinput>
+&prompt.root; <userinput>df /mnt</userinput>
+Filesystem 1K-blocks Used Avail Capacity Mounted on
+/dev/md0a 4710 4 4330 0% /mnt</screen>
+ </example>
+
+ <para>If you do not specify the unit number with the
+ <option>-u</option> option, &man.mdconfig.8; will use the
+ &man.md.4; automatic allocation to select an unused device.
+ The name of the allocated unit will be output on stdout like
+ <filename>md4</filename>. For more details about
+ &man.mdconfig.8;, please refer to the manual page.</para>
+
+ <para>The utility &man.mdconfig.8; is very useful, however it
+ asks many command lines to create a file-backed file system.
+ FreeBSD also comes with a tool called &man.mdmfs.8;,
+ this program configures a &man.md.4; disk using
+ &man.mdconfig.8;, puts a UFS file system on it using
+ &man.newfs.8;, and mounts it using &man.mount.8;. For example,
+ if you want to create and mount the same file system image as
+ above, simply type the following:</para>
+
+ <example>
+ <title>Configure and Mount a File-Backed Disk with <command>mdmfs</command></title>
+ <screen>&prompt.root; <userinput>dd if=/dev/zero of=newimage bs=1k count=5k</userinput>
+5120+0 records in
+5120+0 records out
+&prompt.root; <userinput>mdmfs -F newimage -s 5m md0 /mnt</userinput>
+&prompt.root; <userinput>df /mnt</userinput>
+Filesystem 1K-blocks Used Avail Capacity Mounted on
+/dev/md0 4718 4 4338 0% /mnt</screen>
+ </example>
+
+ <para>If you use the option <option>md</option> without unit
+ number, &man.mdmfs.8; will use &man.md.4; auto-unit feature to
+ automatically select an unused device. For more details
+ about &man.mdmfs.8;, please refer to the manual page.</para>
+
+ </sect2>
+
+ <sect2 xml:id="disks-md-freebsd5">
+ <title>Memory-Based File System</title>
+ <indexterm>
+ <primary>disks</primary>
+ <secondary>memory file system</secondary>
+ </indexterm>
+
+ <para>For a
+ memory-based file system the <quote>swap backing</quote>
+ should normally be used. Using swap backing does not mean
+ that the memory disk will be swapped out to disk by default,
+ but merely that the memory disk will be allocated from a
+ memory pool which can be swapped out to disk if needed. It is
+ also possible to create memory-based disk which are
+ &man.malloc.9; backed, but using malloc backed memory disks,
+ especially large ones, can result in a system panic if the
+ kernel runs out of memory.</para>
+
+ <example>
+ <title>Creating a New Memory-Based Disk with
+ <command>mdconfig</command></title>
+
+ <screen>&prompt.root; <userinput>mdconfig -a -t malloc -s 5m -u 1</userinput>
+&prompt.root; <userinput>newfs -U md1</userinput>
+/dev/md1: 5.0MB (10240 sectors) block size 16384, fragment size 2048
+ using 4 cylinder groups of 1.27MB, 81 blks, 256 inodes.
+ with soft updates
+super-block backups (for fsck -b #) at:
+ 32, 2624, 5216, 7808
+&prompt.root; <userinput>mount /dev/md1 /mnt</userinput>
+&prompt.root; <userinput>df /mnt</userinput>
+Filesystem 1K-blocks Used Avail Capacity Mounted on
+/dev/md1 4846 2 4458 0% /mnt</screen>
+ </example>
+
+ <example>
+ <title>Creating a New Memory-Based Disk with
+ <command>mdmfs</command></title>
+ <screen>&prompt.root; <userinput>mdmfs -M -s 5m md2 /mnt</userinput>
+&prompt.root; <userinput>df /mnt</userinput>
+Filesystem 1K-blocks Used Avail Capacity Mounted on
+/dev/md2 4846 2 4458 0% /mnt</screen>
+ </example>
+
+ <para>Instead of using a &man.malloc.9; backed file system, it is
+ possible to use swap, for that just replace
+ <option>malloc</option> with <option>swap</option> in the
+ command line of &man.mdconfig.8;. The &man.mdmfs.8; utility
+ by default (without <option>-M</option>) creates a swap-based
+ disk. For more details, please refer to &man.mdconfig.8;
+ and &man.mdmfs.8; manual pages.</para>
+ </sect2>
+
+ <sect2>
+ <title>Detaching a Memory Disk from the System</title>
+ <indexterm>
+ <primary>disks</primary>
+ <secondary>detaching a memory disk</secondary>
+ </indexterm>
+
+ <para>When a memory-based or file-based file system
+ is not used, you should release all resources to the system.
+ The first thing to do is to unmount the file system, then use
+ &man.mdconfig.8; to detach the disk from the system and release
+ the resources.</para>
+
+ <para>For example to detach and free all resources used by
+ <filename>/dev/md4</filename>:</para>
+
+ <screen>&prompt.root; <userinput>mdconfig -d -u 4</userinput></screen>
+
+ <para>It is possible to list information about configured
+ &man.md.4; devices in using the command <command>mdconfig
+ -l</command>.</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="snapshots">
+ <info><title>File System Snapshots</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <indexterm>
+ <primary>file systems</primary>
+ <secondary>snapshots</secondary>
+ </indexterm>
+
+ <para>FreeBSD offers a feature in conjunction with
+ <link linkend="soft-updates">Soft Updates</link>: File system snapshots.</para>
+
+ <para>Snapshots allow a user to create images of specified file
+ systems, and treat them as a file.
+ Snapshot files must be created in the file system that the
+ action is performed on, and a user may create no more than 20
+ snapshots per file system. Active snapshots are recorded
+ in the superblock so they are persistent across unmount and
+ remount operations along with system reboots. When a snapshot
+ is no longer required, it can be removed with the standard &man.rm.1;
+ command. Snapshots may be removed in any order,
+ however all the used space may not be acquired because another snapshot will
+ possibly claim some of the released blocks.</para>
+
+ <para>The un-alterable <option>snapshot</option> file flag is set
+ by &man.mksnap.ffs.8; after initial creation of a snapshot file.
+ The &man.unlink.1; command makes an exception for snapshot files
+ since it allows them to be removed.</para>
+
+ <para>Snapshots are created with the &man.mount.8; command. To place
+ a snapshot of <filename>/var</filename> in the file
+ <filename>/var/snapshot/snap</filename> use the following
+ command:</para>
+
+<screen>&prompt.root; <userinput>mount -u -o snapshot /var/snapshot/snap /var</userinput></screen>
+
+ <para>Alternatively, you can use &man.mksnap.ffs.8; to create
+ a snapshot:</para>
+<screen>&prompt.root; <userinput>mksnap_ffs /var /var/snapshot/snap</userinput></screen>
+
+ <para>One can find snapshot files on a file system (e.g. <filename>/var</filename>)
+ by using the &man.find.1; command:</para>
+<screen>&prompt.root; <userinput>find /var -flags snapshot</userinput></screen>
+
+ <para>Once a snapshot has been created, it has several
+ uses:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Some administrators will use a snapshot file for backup purposes,
+ because the snapshot can be transfered to CDs or tape.</para>
+ </listitem>
+
+ <listitem>
+ <para>File integrity, &man.fsck.8; may be ran on the snapshot.
+ Assuming that the file system was clean when it was mounted, you
+ should always get a clean (and unchanging) result.
+ This is essentially what the
+ background &man.fsck.8; process does.</para>
+ </listitem>
+
+ <listitem>
+ <para>Run the &man.dump.8; utility on the snapshot.
+ A dump will be returned that is consistent with the
+ file system and the timestamp of the snapshot. &man.dump.8;
+ can also take a snapshot, create a dump image and then
+ remove the snapshot in one command using the
+ <option>-L</option> flag.</para>
+ </listitem>
+
+ <listitem>
+ <para>&man.mount.8; the snapshot as a frozen image of the file system.
+ To &man.mount.8; the snapshot
+ <filename>/var/snapshot/snap</filename> run:</para>
+
+<screen>&prompt.root; <userinput>mdconfig -a -t vnode -f /var/snapshot/snap -u 4</userinput>
+&prompt.root; <userinput>mount -r /dev/md4 /mnt</userinput></screen>
+
+ </listitem>
+ </itemizedlist>
+
+ <para>You can now walk the hierarchy of your frozen <filename>/var</filename>
+ file system mounted at <filename>/mnt</filename>. Everything will
+ initially be in the same state it was during the snapshot creation time.
+ The only exception is that any earlier snapshots will appear
+ as zero length files. When the use of a snapshot has delimited,
+ it can be unmounted with:</para>
+
+<screen>&prompt.root; <userinput>umount /mnt</userinput>
+&prompt.root; <userinput>mdconfig -d -u 4</userinput></screen>
+
+ <para>For more information about <option>softupdates</option> and
+ file system snapshots, including technical papers, you can visit
+ Marshall Kirk McKusick's website at
+ <uri xlink:href="http://www.mckusick.com/">http://www.mckusick.com/</uri>.</para>
+ </sect1>
+
+ <sect1 xml:id="quotas">
+ <title>磁碟空間配額(Quota)</title>
+ <indexterm>
+ <primary>accounting</primary>
+ <secondary>disk space</secondary>
+ </indexterm>
+ <indexterm><primary>disk quotas</primary></indexterm>
+
+ <para>磁碟配額(Quota)屬於作業系統上的選用功能,
+ 可以用來限制使用者或群組的可用空間大小,或者檔案的總數多寡。
+ 這功能通常用在多人共用的系統環境上,
+ 因為要限制各使用者或各群組所能運用的系統資源。
+ 如此一來,就可避免磁碟空間被某使用者或某群組全部耗盡。</para>
+
+ <sect2>
+ <title>啟用磁碟配額</title>
+
+ <para>在用磁碟配額之前,請先確認 kernel 已經有作相關設定,也就是
+ kernel 設定檔要有下面這行:</para>
+
+ <programlisting>options QUOTA</programlisting>
+
+ <para>預設的 <filename>GENERIC</filename> kernel 並不會加上這項,
+ 所以若要啟用就必需加上,並重新編譯、安裝 kernel。 kernel
+ 設定部分可參閱 <xref linkend="kernelconfig"/> 的說明。</para>
+
+ <para>接著就是在 <filename>/etc/rc.conf</filename> 設定啟動磁碟配額。
+ 請加上下列這行:</para>
+
+ <programlisting>enable_quotas="YES"</programlisting>
+ <indexterm>
+ <primary>disk quotas</primary>
+ <secondary>checking</secondary>
+ </indexterm>
+ <para>為了能更完善的控管磁碟配額的啟動,還有一個設定可以用。 通常開機時,
+ &man.quotacheck.8; 程式會檢查各檔案系統上的配額。
+ &man.quotacheck.8; 可以確保配額資料庫的資料與實際檔案系統的資料有符合。
+ 但這功能也會在開機時,會對啟動時間造成相當明顯的影響。
+ 若想跳過這步驟,則可以在 <filename>/etc/rc.conf</filename> 加上:</para>
+
+ <programlisting>check_quotas="NO"</programlisting>
+
+ <para>最後,要記得改 <filename>/etc/fstab</filename>
+ 來啟用以檔案系統為對象的磁碟配額功能。 也可以啟用針對使用者或群組,
+ 或者兩者皆有之的磁碟配額。</para>
+
+ <para>若要啟用針對使用者的配額,可以在 <filename>/etc/fstab</filename>
+ 內要設定的檔案系統加上 <option>userquota</option> 選項。 比如:</para>
+
+ <programlisting>/dev/da1s2g /home ufs rw,userquota 1 2</programlisting>
+
+ <para>同理若要啟用針對群組的配額,則把剛剛的 <option>userquota</option>
+ 換成 <option>groupquota</option> 即可。 而若要兩者同時啟用,
+ 那麼則是:</para>
+
+ <programlisting>/dev/da1s2g /home ufs rw,userquota,groupquota 1 2</programlisting>
+
+ <para>針對使用者以及群組的磁碟配額設定檔,預設分別會放在該檔案系統根目錄的
+ <filename>quota.user</filename> 以及 <filename>quota.group</filename>
+ 。 細節部分請參閱 &man.fstab.5;。
+ 雖然 &man.fstab.5; 提到可以為配額設定檔指定其他地方,但並不建議如此作,
+ 因為各種磁碟配額管理工具並不見得對這些預設值能隨之彈性變化。</para>
+
+ <para>接下來就可以用新 kernel 來重開機。 <filename>/etc/rc</filename>
+ 會自動執行相關指令以對 <filename>/etc/fstab</filename>
+ 有設定配額管理的部分,作初始設定。
+ 所以並不需要逐一手動產生相關空的配額設定檔。</para>
+
+ <para>正常操作過程中,並不需要手動執行 &man.quotacheck.8;、&man.quotaon.8;
+ 、&man.quotaoff.8; 這些指令。 不過,若要更熟悉相關操作方式的話,
+ 或許可以閱讀相關的 manual 線上說明。</para>
+ </sect2>
+
+ <sect2>
+ <title>設定配額限制</title>
+ <indexterm>
+ <primary>disk quotas</primary>
+ <secondary>limits</secondary>
+ </indexterm>
+
+ <para>一旦開始啟用配額管理之後,請記得確認是否有真的啟用。
+ 可以打下列指令來作簡單檢查:</para>
+
+ <screen>&prompt.root; <userinput>quota -v</userinput></screen>
+
+ <para>應該可以看到有關各檔案系統的配額限量,
+ 以及現在使用量的摘要訊息。</para>
+
+ <para>現在可以開始用 &man.edquota.8; 來設定各磁碟配額的限制。</para>
+
+ <para>有幾種選項可以用來限制使用者或群組所能運用的磁碟空間,
+ 以及所能建立的檔案數量多寡。 可以依磁碟空間(block 配額)或檔案數量
+ (inode 配額),或者搭配兩者一起設定。 而每種限制還可以細分為兩類:
+ hard(硬性)上限、soft(彈性)上限。</para>
+
+ <indexterm><primary>hard limit</primary></indexterm>
+ <para>硬性上限是不能超過的。 一旦使用者達到硬性上限時,
+ 就無法在該檔案系統上繼續使用更多的使用空間了。
+ 舉例來說,若有位使用者的硬性上限為 500 KB,而目前用了 490 KB,
+ 那麼他就只能再多用 10 KB 而已,若要新增的檔案有 11 KB 就會失敗。</para>
+
+ <indexterm><primary>soft limit</primary></indexterm>
+ <para>然而,彈性上限則可允許一定時間內的超額使用,這段期間稱為
+ grace period(寬限期),預設值是一週。 若使用者持續超額使用並超出
+ grace period 而逾期,則彈性上限就會轉為硬性上限,
+ 而不允許該使用者繼續新增空間。
+ 直到該使用者的空間已經清到低於彈性上限之後,才會重設
+ grace period。</para>
+
+ <para>下面則是使用 &man.edquota.8; 的例子。 在執行 &man.edquota.8;
+ 時,會進入設定磁碟配額上限的編輯器內,至於是哪一種編輯器則視您的
+ <envar>EDITOR</envar> 環境變數而定,若沒設定 <envar>EDITOR</envar>
+ 的話,則會用 <application>vi</application> 編輯器。</para>
+
+ <screen>&prompt.root; <userinput>edquota -u test</userinput></screen>
+
+ <programlisting>Quotas for user test:
+/usr: kbytes in use: 65, limits (soft = 50, hard = 75)
+ inodes in use: 7, limits (soft = 50, hard = 60)
+/usr/var: kbytes in use: 0, limits (soft = 50, hard = 75)
+ inodes in use: 0, limits (soft = 50, hard = 60)</programlisting>
+
+ <para>一般來說,每個啟動了磁碟配額的檔案系統都會有兩行設定。
+ 第一行是 block 上限,而另一行則是 inode 上限。
+ 若要更改磁碟配額上限,只需要修改後面的數值即可。 舉例來說,
+ 要增加這位使用者的 block 上限部分:把彈性上限 50 調為 500,
+ 硬性上限則由 75 調為 600 ,只需修改下面這行:</para>
+
+ <programlisting>/usr: kbytes in use: 65, limits (soft = 50, hard = 75)</programlisting>
+
+ <para>改為下列:</para>
+
+ <programlisting>/usr: kbytes in use: 65, limits (soft = 500, hard = 600)</programlisting>
+
+ <para>然後存檔離開後,新的配額設定就會立即生效。</para>
+
+ <para>有時候會想一次改大範圍 UID 的帳號設定,這時可以用 &man.edquota.8;
+ 的 <option>-p</option> 參數功能來完成。 首先,
+ 把某個帳號調為想要的相關配額,然後可以用
+ <command>edquota -p protouser startuid-enduid</command> 之類的方式來改。
+ 舉例來說,假設 <systemitem class="username">test</systemitem> 這帳號已經設定好相關配額,
+ 然後要改的對象為 UID 從 10,000 到 19,999 的帳號,
+ 那麼就可以下列指令來設定同樣的配額:</para>
+
+ <screen>&prompt.root; <userinput>edquota -p test 10000-19999</userinput></screen>
+
+ <para>細節說明請參閱 &man.edquota.8;。</para>
+ </sect2>
+
+ <sect2>
+ <title>檢查磁碟配額設定、磁碟使用量</title>
+ <indexterm>
+ <primary>disk quotas</primary>
+ <secondary>checking</secondary>
+ </indexterm>
+
+ <para>可以用 &man.quota.1; 或 &man.repquota.8; 來檢查磁碟配額設定,
+ 以及磁碟使用量。 &man.quota.1; 可用來檢查單一使用者或群組的磁碟配額、
+ 磁碟使用量。 不過一般帳號只能查自己的以及自己群組的磁碟配額、
+ 磁碟使用量,只有系統管理者帳號才能察看所有使用者、
+ 群組的配額設定與使用量。 而 &man.repquota.8;
+ 則可以看到所有已啟動磁碟配額的檔案系統設定、磁碟使用量摘要。</para>
+
+ <para>下面例子則是在兩個有配額設定的檔案系統上,打
+ <command>quota -v</command> 的顯示結果:</para>
+
+ <programlisting>Disk quotas for user test (uid 1002):
+ Filesystem usage quota limit grace files quota limit grace
+ /usr 65* 50 75 5days 7 50 60
+ /usr/var 0 50 75 0 50 60</programlisting>
+
+ <indexterm><primary>grace period</primary></indexterm>
+ <para>在上面這例中,該使用者在 <filename>/usr</filename> 的彈性配額是
+ 50 KB,實際上已經超額多用 15 KB,而 grace period 還有 5 天就逾期。
+ 請注意這個星號 <literal>*</literal>
+ 是表示目前該使用者已經超越其配額的彈性上限了。</para>
+
+ <para>一般來說,若使用者並沒有用到某個檔案系統,
+ 那麼就算該檔案有啟用磁碟配額,在 &man.quota.1; 也不會顯示出來。
+ 而 <option>-v</option> 參數則可以把這些檔案系統都全部列出來,
+ 比如上例中的 <filename>/usr/var</filename>。</para>
+ </sect2>
+
+ <sect2>
+ <title>透過 NFS 使用磁碟配額</title>
+ <indexterm><primary>NFS</primary></indexterm>
+
+ <para>NFS server 端可以強制以 quota subsystem(配額子系統)來用磁碟配額。
+ 而 NFS client 端則可以透過 &man.rpc.rquotad.8; daemon 來讓 &man.quota.1;
+ 指令抓到相關配額資料,也就可以讓 client
+ 端的使用者察看其配額的統計資料。</para>
+
+ <para>若要啟用 <command>rpc.rquotad</command>,可以在
+ <filename>/etc/inetd.conf</filename> 加上下列類似設定:</para>
+
+ <programlisting>rquotad/1 dgram rpc/udp wait root /usr/libexec/rpc.rquotad rpc.rquotad</programlisting>
+
+ <para>然後重啟 <command>inetd</command> 即可:</para>
+
+ <screen>&prompt.root; <userinput>kill -HUP `cat /var/run/inetd.pid`</userinput></screen>
+ </sect2>
+ </sect1>
+
+
+ <sect1 xml:id="disks-encrypting">
+ <info><title>Encrypting Disk Partitions</title>
+ <authorgroup>
+ <author><personname><firstname>Lucky</firstname><surname>Green</surname></personname><contrib>Contributed by </contrib><affiliation>
+ <address><email>shamrock@cypherpunks.to</email></address>
+ </affiliation></author>
+ </authorgroup>
+
+ </info>
+
+
+ <indexterm>
+ <primary>disks</primary>
+ <secondary>encrypting</secondary></indexterm>
+
+ <para>FreeBSD offers excellent online protections against
+ unauthorized data access. File permissions and Mandatory
+ Access Control (MAC) (see <xref linkend="mac"/>) help prevent
+ unauthorized third-parties from accessing data while the operating
+ system is active and the computer is powered up. However,
+ the permissions enforced by the operating system are irrelevant if an
+ attacker has physical access to a computer and can simply move
+ the computer's hard drive to another system to copy and analyze
+ the sensitive data.</para>
+
+ <para>Regardless of how an attacker may have come into possession of
+ a hard drive or powered-down computer, both <application>GEOM
+ Based Disk Encryption (gbde)</application> and
+ <command>geli</command> cryptographic subsystems in &os; are able
+ to protect the data on the computer's file systems against even
+ highly-motivated attackers with significant resources. Unlike
+ cumbersome encryption methods that encrypt only individual files,
+ <command>gbde</command> and <command>geli</command> transparently
+ encrypt entire file systems. No cleartext ever touches the hard
+ drive's platter.</para>
+
+ <sect2>
+ <title>Disk Encryption with <application>gbde</application></title>
+
+ <procedure>
+ <step>
+ <title>Become <systemitem class="username">root</systemitem></title>
+
+ <para>Configuring <application>gbde</application> requires
+ super-user privileges.</para>
+
+ <screen>&prompt.user; <userinput>su -</userinput>
+Password:</screen>
+ </step>
+
+ <step>
+ <title>Add &man.gbde.4; Support to the Kernel Configuration File</title>
+
+ <para>Add the following line to the kernel configuration
+ file:</para>
+
+ <para><literal>options GEOM_BDE</literal></para>
+
+ <para>Rebuild the kernel as described in <xref linkend="kernelconfig"/>.</para>
+
+ <para>Reboot into the new kernel.</para>
+ </step>
+ </procedure>
+
+ <sect3>
+ <title>Preparing the Encrypted Hard Drive</title>
+
+ <para>The following example assumes that you are adding a new hard
+ drive to your system that will hold a single encrypted partition.
+ This partition will be mounted as <filename>/private</filename>.
+ <application>gbde</application> can also be used to encrypt
+ <filename>/home</filename> and <filename>/var/mail</filename>, but
+ this requires more complex instructions which exceed the scope of
+ this introduction.</para>
+
+ <procedure>
+ <step>
+ <title>Add the New Hard Drive</title>
+
+ <para>Install the new drive to the system as explained in <xref linkend="disks-adding"/>. For the purposes of this example,
+ a new hard drive partition has been added as
+ <filename>/dev/ad4s1c</filename>. The
+ <filename>/dev/ad0s1*</filename>
+ devices represent existing standard FreeBSD partitions on
+ the example system.</para>
+
+ <screen>&prompt.root; <userinput>ls /dev/ad*</userinput>
+/dev/ad0 /dev/ad0s1b /dev/ad0s1e /dev/ad4s1
+/dev/ad0s1 /dev/ad0s1c /dev/ad0s1f /dev/ad4s1c
+/dev/ad0s1a /dev/ad0s1d /dev/ad4</screen>
+ </step>
+
+ <step>
+ <title>Create a Directory to Hold gbde Lock Files</title>
+
+ <screen>&prompt.root; <userinput>mkdir /etc/gbde</userinput></screen>
+
+ <para>The <application>gbde</application> lock file contains
+ information that <application>gbde</application> requires to
+ access encrypted partitions. Without access to the lock file,
+ <application>gbde</application> will not be able to decrypt
+ the data contained in the encrypted partition without
+ significant manual intervention which is not supported by the
+ software. Each encrypted partition uses a separate lock
+ file.</para>
+ </step>
+
+ <step>
+ <title>Initialize the gbde Partition</title>
+
+ <para>A <application>gbde</application> partition must be
+ initialized before it can be used. This initialization needs to
+ be performed only once:</para>
+
+ <screen>&prompt.root; <userinput>gbde init /dev/ad4s1c -i -L /etc/gbde/ad4s1c</userinput></screen>
+
+ <para>&man.gbde.8; will open your editor, permitting you to set
+ various configuration options in a template. For use with UFS1
+ or UFS2, set the sector_size to 2048:</para>
+
+ <programlisting>$<!-- This is not the space you are looking
+for-->FreeBSD: src/sbin/gbde/template.txt,v 1.1 2002/10/20 11:16:13 phk Exp $
+#
+# Sector size is the smallest unit of data which can be read or written.
+# Making it too small decreases performance and decreases available space.
+# Making it too large may prevent filesystems from working. 512 is the
+# minimum and always safe. For UFS, use the fragment size
+#
+sector_size = 2048
+[...]
+</programlisting>
+
+ <para>&man.gbde.8; will ask you twice to type the passphrase that
+ should be used to secure the data. The passphrase must be the
+ same both times. <application>gbde</application>'s ability to
+ protect your data depends entirely on the quality of the
+ passphrase that you choose.
+ <footnote>
+ <para>For tips on how to select a secure passphrase that is easy
+ to remember, see the <link xlink:href="http://world.std.com/~reinhold/diceware.html">Diceware
+ Passphrase</link> website.</para></footnote></para>
+
+ <para>The <command>gbde init</command> command creates a lock
+ file for your <application>gbde</application> partition that in
+ this example is stored as
+ <filename>/etc/gbde/ad4s1c</filename>.</para>
+
+ <caution>
+ <para><application>gbde</application> lock files
+ <emphasis>must</emphasis> be backed up together with the
+ contents of any encrypted partitions. While deleting a lock
+ file alone cannot prevent a determined attacker from
+ decrypting a <application>gbde</application> partition,
+ without the lock file, the legitimate owner will be unable
+ to access the data on the encrypted partition without a
+ significant amount of work that is totally unsupported by
+ &man.gbde.8; and its designer.</para>
+ </caution>
+ </step>
+
+ <step>
+ <title>Attach the Encrypted Partition to the Kernel</title>
+
+ <screen>&prompt.root; <userinput>gbde attach /dev/ad4s1c -l /etc/gbde/ad4s1c</userinput></screen>
+
+ <para> You will be asked to provide the passphrase that you
+ selected during the initialization of the encrypted partition.
+ The new encrypted device will show up in
+ <filename>/dev</filename> as
+ <filename>/dev/device_name.bde</filename>:</para>
+
+ <screen>&prompt.root; <userinput>ls /dev/ad*</userinput>
+/dev/ad0 /dev/ad0s1b /dev/ad0s1e /dev/ad4s1
+/dev/ad0s1 /dev/ad0s1c /dev/ad0s1f /dev/ad4s1c
+/dev/ad0s1a /dev/ad0s1d /dev/ad4 /dev/ad4s1c.bde</screen>
+ </step>
+
+ <step>
+ <title>Create a File System on the Encrypted Device</title>
+
+ <para>Once the encrypted device has been attached to the kernel,
+ you can create a file system on the device. To create a file
+ system on the encrypted device, use &man.newfs.8;. Since it is
+ much faster to initialize a new UFS2 file system than it is to
+ initialize the old UFS1 file system, using &man.newfs.8; with
+ the <option>-O2</option> option is recommended.</para>
+
+ <screen>&prompt.root; <userinput>newfs -U -O2 /dev/ad4s1c.bde</userinput></screen>
+
+ <note>
+ <para>The &man.newfs.8; command must be performed on an
+ attached <application>gbde</application> partition which
+ is identified by a
+ <filename>*.bde</filename>
+ extension to the device name.</para>
+ </note>
+ </step>
+
+ <step>
+ <title>Mount the Encrypted Partition</title>
+
+ <para>Create a mount point for the encrypted file system.</para>
+
+ <screen>&prompt.root; <userinput>mkdir /private</userinput></screen>
+
+ <para>Mount the encrypted file system.</para>
+
+ <screen>&prompt.root; <userinput>mount /dev/ad4s1c.bde /private</userinput></screen>
+ </step>
+
+ <step>
+ <title>Verify That the Encrypted File System is Available</title>
+
+ <para>The encrypted file system should now be visible to
+ &man.df.1; and be available for use.</para>
+
+ <screen>&prompt.user; <userinput>df -H</userinput>
+Filesystem Size Used Avail Capacity Mounted on
+/dev/ad0s1a 1037M 72M 883M 8% /
+/devfs 1.0K 1.0K 0B 100% /dev
+/dev/ad0s1f 8.1G 55K 7.5G 0% /home
+/dev/ad0s1e 1037M 1.1M 953M 0% /tmp
+/dev/ad0s1d 6.1G 1.9G 3.7G 35% /usr
+/dev/ad4s1c.bde 150G 4.1K 138G 0% /private</screen>
+ </step>
+ </procedure>
+ </sect3>
+
+ <sect3>
+ <title>Mounting Existing Encrypted File Systems</title>
+
+ <para>After each boot, any encrypted file systems must be
+ re-attached to the kernel, checked for errors, and mounted, before
+ the file systems can be used. The required commands must be
+ executed as user <systemitem class="username">root</systemitem>.</para>
+
+ <procedure>
+ <step>
+ <title>Attach the gbde Partition to the Kernel</title>
+
+ <screen>&prompt.root; <userinput>gbde attach /dev/ad4s1c -l /etc/gbde/ad4s1c</userinput></screen>
+
+ <para>You will be asked to provide the passphrase that you
+ selected during initialization of the encrypted
+ <application>gbde</application> partition.</para>
+ </step>
+
+ <step>
+ <title>Check the File System for Errors</title>
+
+ <para>Since encrypted file systems cannot yet be listed in
+ <filename>/etc/fstab</filename> for automatic mounting, the
+ file systems must be checked for errors by running &man.fsck.8;
+ manually before mounting.</para>
+
+ <screen>&prompt.root; <userinput>fsck -p -t ffs /dev/ad4s1c.bde</userinput></screen>
+ </step>
+
+ <step>
+ <title>Mount the Encrypted File System</title>
+
+ <screen>&prompt.root; <userinput>mount /dev/ad4s1c.bde /private</userinput></screen>
+
+ <para>The encrypted file system is now available for use.</para>
+ </step>
+ </procedure>
+
+ <sect4>
+ <title>Automatically Mounting Encrypted Partitions</title>
+
+ <para>It is possible to create a script to automatically attach,
+ check, and mount an encrypted partition, but for security reasons
+ the script should not contain the &man.gbde.8; password. Instead,
+ it is recommended that such scripts be run manually while
+ providing the password via the console or &man.ssh.1;.</para>
+
+ <para>As of &os; 5.2-RELEASE, there is a new <filename>rc.d</filename> script
+ provided. Arguments for this script can be passed via
+ &man.rc.conf.5;, for example:</para>
+
+ <screen>gbde_autoattach_all="YES"
+gbde_devices="ad4s1c"</screen>
+
+ <para>This will require that the <application>gbde</application>
+ passphrase be entered at boot time. After typing the correct
+ passphrase, the <application>gbde</application> encrypted
+ partition will be mounted automatically. This can be very
+ useful when using <application>gbde</application> on
+ notebooks.</para>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>Cryptographic Protections Employed by gbde</title>
+
+ <para>&man.gbde.8; encrypts the sector payload using 128-bit AES in
+ CBC mode. Each sector on the disk is encrypted with a different
+ AES key. For more information on <application>gbde</application>'s
+ cryptographic design, including how the sector keys are derived
+ from the user-supplied passphrase, see &man.gbde.4;.</para>
+ </sect3>
+
+ <sect3>
+ <title>Compatibility Issues</title>
+
+ <para>&man.sysinstall.8; is incompatible with
+ <application>gbde</application>-encrypted devices. All
+ <filename>*.bde</filename> devices must be detached from the
+ kernel before starting &man.sysinstall.8; or it will crash during
+ its initial probing for devices. To detach the encrypted device
+ used in our example, use the following command:</para>
+ <screen>&prompt.root; <userinput>gbde detach /dev/ad4s1c</userinput></screen>
+
+ <para>Also note that, as &man.vinum.4; does not use the
+ &man.geom.4; subsystem, you cannot use
+ <application>gbde</application> with
+ <application>vinum</application> volumes.</para>
+ </sect3>
+
+ </sect2>
+
+ <sect2>
+ <info><title>Disk Encryption with <command>geli</command></title>
+ <authorgroup>
+ <author><personname><firstname>Daniel</firstname><surname>Gerzo</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <para>A new cryptographic GEOM class is available as of &os; 6.0 -
+ <command>geli</command>. It is currently being developed by
+ &a.pjd;. <command>Geli</command> is different to
+ <command>gbde</command>; it offers different features and uses
+ a different scheme for doing cryptographic work.</para>
+
+ <para>The most important features of &man.geli.8; are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Utilizes the &man.crypto.9; framework &mdash; when
+ cryptographic hardware is available, <command>geli</command>
+ will use it automatically.</para>
+ </listitem>
+ <listitem>
+ <para>Supports multiple cryptographic algorithms (currently
+ AES, Blowfish, and 3DES).</para>
+ </listitem>
+ <listitem>
+ <para>Allows the root partition to be encrypted. The
+ passphrase used to access the encrypted root partition will
+ be requested during the system boot.</para>
+ </listitem>
+ <listitem>
+ <para>Allows the use of two independent keys (e.g. a
+ <quote>key</quote> and a <quote>company key</quote>).</para>
+ </listitem>
+ <listitem>
+ <para><command>geli</command> is fast - performs simple
+ sector-to-sector encryption.</para>
+ </listitem>
+ <listitem>
+ <para>Allows backup and restore of Master Keys. When a user
+ has to destroy his keys, it will be possible to get access
+ to the data again by restoring keys from the backup.</para>
+ </listitem>
+ <listitem>
+ <para>Allows to attach a disk with a random, one-time key
+ &mdash; useful for swap partitions and temporary file
+ systems.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>More <command>geli</command> features can be found in the
+ &man.geli.8; manual page.</para>
+
+ <para>The next steps will describe how to enable support for
+ <command>geli</command> in the &os; kernel and will explain how
+ to create a new <command>geli</command> encryption provider. At
+ the end it will be demonstrated how to create an encrypted swap
+ partition using features provided by <command>geli</command>.</para>
+
+ <para>In order to use <command>geli</command>, you must be running
+ &os; 6.0-RELEASE or later. Super-user privileges will be
+ required since modifications to the kernel are necessary.</para>
+
+ <procedure>
+ <step>
+ <title>Adding <command>geli</command> Support to the Kernel
+ Configuration File</title>
+
+ <para>Add the following lines to the kernel configuration
+ file:</para>
+
+ <screen>options GEOM_ELI
+device crypto</screen>
+
+ <para>Rebuild the kernel as described in <xref linkend="kernelconfig"/>.</para>
+
+ <para>Alternatively, the <command>geli</command> module can
+ be loaded at boot time. Add the following line to the
+ <filename>/boot/loader.conf</filename>:</para>
+
+ <para><literal>geom_eli_load="YES"</literal></para>
+
+ <para>&man.geli.8; should now be supported by the kernel.</para>
+ </step>
+
+ <step>
+ <title>Generating the Master Key</title>
+
+ <para>The following example will describe how to generate a
+ key file, which will be used as part of the Master Key for
+ the encrypted provider mounted under
+ <filename>/private</filename>. The key
+ file will provide some random data used to encrypt the
+ Master Key. The Master Key will be protected by a
+ passphrase as well. Provider's sector size will be 4kB big.
+ Furthermore, the discussion will describe how to attach the
+ <command>geli</command> provider, create a file system on
+ it, how to mount it, how to work with it, and finally how to
+ detach it.</para>
+
+ <para>It is recommended to use a bigger sector size (like 4kB) for
+ better performance.</para>
+
+ <para>The Master Key will be protected with a passphrase and
+ the data source for key file will be
+ <filename>/dev/random</filename>. The sector size of
+ <filename>/dev/da2.eli</filename>, which we call provider,
+ will be 4kB.</para>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/random of=/root/da2.key bs=64 count=1</userinput>
+&prompt.root; <userinput>geli init -s 4096 -K /root/da2.key /dev/da2</userinput>
+Enter new passphrase:
+Reenter new passphrase:</screen>
+
+ <para>It is not mandatory that both a passphrase and a key
+ file are used; either method of securing the Master Key can
+ be used in isolation.</para>
+
+ <para>If key file is given as <quote>-</quote>, standard
+ input will be used. This example shows how more than one
+ key file can be used.</para>
+
+ <screen>&prompt.root; <userinput>cat keyfile1 keyfile2 keyfile3 | geli init -K - /dev/da2</userinput></screen>
+ </step>
+
+ <step>
+ <title>Attaching the Provider with the generated Key</title>
+
+ <screen>&prompt.root; <userinput>geli attach -k /root/da2.key /dev/da2</userinput>
+Enter passphrase:</screen>
+
+ <para>The new plaintext device will be named
+ <filename>/dev/da2.eli</filename>.</para>
+
+ <screen>&prompt.root; <userinput>ls /dev/da2*</userinput>
+/dev/da2 /dev/da2.eli</screen>
+ </step>
+
+ <step>
+ <title>Creating the new File System</title>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/random of=/dev/da2.eli bs=1m</userinput>
+&prompt.root; <userinput>newfs /dev/da2.eli</userinput>
+&prompt.root; <userinput>mount /dev/da2.eli /private</userinput></screen>
+
+ <para>The encrypted file system should be visible to &man.df.1;
+ and be available for use now.</para>
+
+ <screen>&prompt.root; <userinput>df -H</userinput>
+Filesystem Size Used Avail Capacity Mounted on
+/dev/ad0s1a 248M 89M 139M 38% /
+/devfs 1.0K 1.0K 0B 100% /dev
+/dev/ad0s1f 7.7G 2.3G 4.9G 32% /usr
+/dev/ad0s1d 989M 1.5M 909M 0% /tmp
+/dev/ad0s1e 3.9G 1.3G 2.3G 35% /var
+/dev/da2.eli 150G 4.1K 138G 0% /private</screen>
+
+ </step>
+
+ <step>
+ <title>Unmounting and Detaching the Provider</title>
+
+ <para>Once the work on the encrypted partition is done, and
+ the <filename>/private</filename> partition
+ is no longer needed, it is prudent to consider unmounting
+ and detaching the <command>geli</command> encrypted
+ partition from the kernel.</para>
+
+ <screen>&prompt.root; <userinput>umount /private</userinput>
+&prompt.root; <userinput>geli detach da2.eli</userinput></screen>
+ </step>
+ </procedure>
+
+ <para>More information about the use of &man.geli.8; can be
+ found in the manual page.</para>
+
+ <sect3>
+ <title>Encrypting a Swap Partition</title>
+
+ <para>The following example demonstrates how to create a
+ <command>geli</command> encrypted swap partition.</para>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/random of=/dev/ad0s1b bs=1m</userinput>
+&prompt.root; <userinput>geli onetime -d -a 3des ad0s1b</userinput>
+&prompt.root; <userinput>swapon /dev/ad0s1b.eli</userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Using the <filename>geli</filename> <filename>rc.d</filename> Script</title>
+
+ <para><command>geli</command> comes with a <filename>rc.d</filename> script which
+ can be used to simplify the usage of <command>geli</command>.
+ An example of configuring <command>geli</command> through
+ &man.rc.conf.5; follows:</para>
+
+ <screen>geli_devices="da2"
+geli_da2_flags="-p -k /root/da2.key"</screen>
+
+ <para>This will configure <filename>/dev/da2</filename> as a
+ <command>geli</command> provider of which the Master Key file
+ is located in <filename>/root/da2.key</filename>, and
+ <command>geli</command> will not use a passphrase when
+ attaching the provider (note that this can only be used if -P
+ was given during the <command>geli</command> init phase). The
+ system will detach the <command>geli</command> provider from
+ the kernel before the system shuts down.</para>
+
+ <para>More information about configuring <filename>rc.d</filename> is provided in the
+ <link linkend="configtuning-rcd">rc.d</link> section of the
+ Handbook.</para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+
+ <sect1 xml:id="swap-encrypting">
+ <info><title>Encrypting Swap Space</title>
+ <authorgroup>
+ <author><personname><firstname>Christian</firstname><surname>Br&uuml;ffer</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm>
+ <primary>swap</primary>
+ <secondary>encrypting</secondary>
+ </indexterm>
+
+ <para>Swap encryption in &os; is easy to configure and has been
+ available since &os; 5.3-RELEASE. Depending on which version
+ of &os; is being used, different options are available
+ and configuration can vary slightly. From &os; 6.0-RELEASE onwards,
+ the &man.gbde.8; or &man.geli.8; encryption systems can be used
+ for swap encryption. With earlier versions, only &man.gbde.8; is
+ available. Both systems use the <filename>encswap</filename>
+ <link linkend="configtuning-rcd">rc.d</link> script.</para>
+
+ <para>The previous section, <link linkend="disks-encrypting">Encrypting
+ Disk Partitions</link>, includes a short discussion on the different
+ encryption systems.</para>
+
+ <sect2>
+ <title>Why should Swap be Encrypted?</title>
+
+ <para>Like the encryption of disk partitions, encryption of swap space
+ is done to protect sensitive information. Imagine an application
+ that e.g. deals with passwords. As long as these passwords stay in
+ physical memory, all is well. However, if the operating system starts
+ swapping out memory pages to free space for other applications, the
+ passwords may be written to the disk platters unencrypted and easy to
+ retrieve for an adversary. Encrypting swap space can be a solution for
+ this scenario.</para>
+ </sect2>
+
+ <sect2>
+ <title>Preparation</title>
+
+ <note>
+ <para>For the remainder of this section, <filename>ad0s1b</filename>
+ will be the swap partition.</para>
+ </note>
+
+ <para>Up to this point the swap has been unencrypted. It is possible that
+ there are already passwords or other sensitive data on the disk platters
+ in cleartext. To rectify this, the data on the swap partition should be
+ overwritten with random garbage:</para>
+
+ <screen>&prompt.root; <userinput>dd if=/dev/random of=/dev/ad0s1b bs=1m</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Swap Encryption with &man.gbde.8;</title>
+
+ <para>If &os; 6.0-RELEASE or newer is being used, the
+ <literal>.bde</literal> suffix should be added to the device in the
+ respective <filename>/etc/fstab</filename> swap line:</para>
+
+ <screen>
+# Device Mountpoint FStype Options Dump Pass#
+/dev/ad0s1b.bde none swap sw 0 0
+ </screen>
+
+ <para>For systems prior to &os; 6.0-RELEASE, the following line
+ in <filename>/etc/rc.conf</filename> is also needed:</para>
+
+ <programlisting>gbde_swap_enable="YES"</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Swap Encryption with &man.geli.8;</title>
+
+ <para>Alternatively, the procedure for using &man.geli.8; for swap
+ encryption is similar to that of using &man.gbde.8;. The
+ <literal>.eli</literal> suffix should be added to the device in the
+ respective <filename>/etc/fstab</filename> swap line:</para>
+
+ <screen>
+# Device Mountpoint FStype Options Dump Pass#
+/dev/ad0s1b.eli none swap sw 0 0
+ </screen>
+
+ <para>&man.geli.8; uses the <acronym>AES</acronym> algorithm with
+ a key length of 256 bit by default.</para>
+
+ <para>Optionally, these defaults can be altered using the
+ <literal>geli_swap_flags</literal> option in
+ <filename>/etc/rc.conf</filename>. The following line tells the
+ <filename>encswap</filename> rc.d script to create &man.geli.8; swap
+ partitions using the Blowfish algorithm with a key length of 128 bit,
+ a sectorsize of 4 kilobytes and the <quote>detach on last close</quote>
+ option set:</para>
+
+ <programlisting>geli_swap_flags="-a blowfish -l 128 -s 4096 -d"</programlisting>
+
+ <para>Please refer to the description of the <command>onetime</command> command
+ in the &man.geli.8; manual page for a list of possible options.</para>
+ </sect2>
+
+ <sect2>
+ <title>Verifying that it Works</title>
+
+ <para>Once the system has been rebooted, proper operation of the
+ encrypted swap can be verified using the
+ <command>swapinfo</command> command.</para>
+
+ <para>If &man.gbde.8; is being used:</para>
+
+ <screen>&prompt.user; <userinput>swapinfo</userinput>
+Device 1K-blocks Used Avail Capacity
+/dev/ad0s1b.bde 542720 0 542720 0%
+ </screen>
+
+ <para>If &man.geli.8; is being used:</para>
+
+ <screen>&prompt.user; <userinput>swapinfo</userinput>
+Device 1K-blocks Used Avail Capacity
+/dev/ad0s1b.eli 542720 0 542720 0%
+ </screen>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/eresources/Makefile b/zh_TW.UTF-8/books/handbook/eresources/Makefile
new file mode 100644
index 0000000000..7099b0c7d2
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/eresources/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+# $FreeBSD$
+# Original revision: 1.1
+#
+
+CHAPTERS= eresources/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/eresources/chapter.xml b/zh_TW.UTF-8/books/handbook/eresources/chapter.xml
new file mode 100644
index 0000000000..a55dab922b
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/eresources/chapter.xml
@@ -0,0 +1,1676 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Take translation from Kang-min Liu <gugod@gugod.org>
+ Original revision: 1.175
+-->
+<appendix xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="eresources">
+ <title>網際網路上的資源</title>
+
+ <para>進展飛快的 FreeBSD 使得現有的印刷、平面媒體跟不上它的最新進度!
+ 反而數位版本的資源,也許有時並不是最好,但通常是唯一一個跟上最新進展的方式。
+ 正由於 FreeBSD 是來自於許多志工的努力,所以廣大的使用者群也通常扮演著 <quote>IT技術支援部門</quote> 的角色。
+ 只要善用電子郵件和 USENET 新聞群組就可以很快速地聯繫這些社群了。</para>
+
+ <para>以下簡介與 FreeBSD 社群搭上線的主要方式。
+ 若你還知道其他這裡沒有列出的資源,請告知 &a.doc;,以便我們更新。</para>
+
+ <sect1 xml:id="eresources-mail">
+ <title>郵遞論壇(Mailing Lists)</title>
+
+ <para>雖然,大部份的 FreeBSD 開發人員都有看 USENET 新聞群組,
+ 我們也不能保證我們永遠可以及時得知您的問題。
+ 尤其是,若您只在
+ <literal>comp.unix.bsd.freebsd.*</literal> 其中群組內發問的話。
+ 建議您將問題發到適當的郵遞論壇(mailing list)上,不但可以同時讓 FreeBSD
+ 開發者和其他看倌們知道,通常也可以得到一個較好的(最起碼會比較快)的回應。</para>
+
+ <para>本文後面介紹的是各式不同的郵遞論壇、討論規則(charter)。
+ <emphasis>在訂閱任何 list 之前,請先閱讀討論規則。</emphasis>
+ 訂閱這些 list 的人們現在每天都會收到數百封 FreeBSD 相關信件。
+ 而討論規則的制訂,則有助於提升彼此討論品質。
+ 否則,這些討論 FreeBSD 的 list 終將陷入溝通不良,而失去其原本美意。</para>
+
+ <para>對於該在哪個 list 發問覺得很疑惑的時候,就來看看 <link xlink:href="&url.articles.freebsd-questions;">《如何在 FreeBSD-questions mailing list 上得到正解》
+ </link> 一文吧</para>
+
+ <para>在發表問題、回覆到 list 之前,請先讀過
+ <link xlink:href="&url.articles.mailing-list-faq;">
+ FreeBSD Mailing Lists 常見問答集(FAQ)</link> 一文以學會如何善用 mailing list
+ ,才能避免像是經常重複的月經文、戰文之類的事情發生。</para>
+
+ <para>全部的 mailing lists 討論記錄都可以在 <link xlink:href="&url.base;/search/index.html">
+ FreeBSD WWW主機</link> 上找到。它提供了很棒的關鍵字搜尋功能,可讓您找到常用問答集(FAQ)
+ 。而在 mailing lists 上發問之前,也請先搜尋是否已有解答。</para>
+
+ <sect2 xml:id="eresources-summary">
+ <title>List 一覽表</title>
+
+ <para><emphasis>一般論壇:</emphasis> 以下的 list 都是一般性質,而且大家可以自由地參與,
+ 我們也鼓勵大家訂閱:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>List 名稱</entry>
+ <entry>目的</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>&a.cvsall.name;</entry>
+ <entry>所有的 FreeBSD 提交(commit)記錄</entry>
+ </row>
+
+ <row>
+ <entry>&a.advocacy.name;</entry>
+ <entry>FreeBSD 惡魔福音電台</entry>
+ </row>
+
+ <row>
+ <entry>&a.announce.name;</entry>
+ <entry>公布重要事件、計劃里程碑</entry>
+ </row>
+
+ <row>
+ <entry>&a.arch.name;</entry>
+ <entry>架構研發討論</entry>
+ </row>
+
+ <row>
+ <entry>&a.bugbusters.name;</entry>
+ <entry>FreeBSD 問題回報(PR)資料庫的維護議題與工具</entry>
+ </row>
+
+ <row>
+ <entry>&a.bugs.name;</entry>
+ <entry>Bug 回報</entry>
+ </row>
+
+ <row>
+ <entry>&a.chat.name;</entry>
+ <entry>非技術交流的 FreeBSD 社群聊天區</entry>
+ </row>
+
+ <row>
+ <entry>&a.current.name;</entry>
+ <entry>討論 &os.current; 版本的 FreeBSD</entry>
+ </row>
+
+ <row>
+ <entry>&a.isp.name;</entry>
+ <entry>FreeBSD 的 ISP 業者技術交流區</entry>
+ </row>
+
+ <row>
+ <entry>&a.jobs.name;</entry>
+ <entry>FreeBSD 人力銀行</entry>
+ </row>
+
+ <row>
+ <entry>&a.policy.name;</entry>
+ <entry>FreeBSD Core team 的 policy 方針討論區。這裡文章不多,且只限 core team 才可發言。</entry>
+ </row>
+
+ <row>
+ <entry>&a.questions.name;</entry>
+ <entry>使用問題及技術支援</entry>
+ </row>
+
+ <row>
+ <entry>&a.security-notifications.name;</entry>
+ <entry>安全漏洞通知</entry>
+ </row>
+
+ <row>
+ <entry>&a.stable.name;</entry>
+ <entry>討論 &os.stable; 版本的 FreeBSD</entry>
+ </row>
+
+ <row>
+ <entry>&a.test.name;</entry>
+ <entry>論壇新手發表區,這裡可以讓你小試身手</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para><emphasis>技術論壇:</emphasis> 以下 list 主是要以探討技術問題為主,
+ 在加入訂閱及討論之前,請務必仔細閱讀每個 list 的版規(charter),
+ 因為它們的討論內容都有很嚴謹的限制。</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>List 名稱</entry>
+ <entry>目的</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>&a.acpi.name;</entry>
+ <entry>ACPI 以及電力管理議題</entry>
+ </row>
+
+ <row>
+ <entry>&a.afs.name;</entry>
+ <entry>移植 AFS 到 FreeBSD</entry>
+ </row>
+
+ <row>
+ <entry>&a.aic7xxx.name;</entry>
+ <entry>研發 &adaptec; AIC 7xxx 的驅動程式</entry>
+ </row>
+
+ <row>
+ <entry>&a.alpha.name;</entry>
+ <entry>移植 FreeBSD 到 Alpha 系統架構</entry>
+ </row>
+
+ <row>
+ <entry>&a.amd64.name;</entry>
+ <entry>移植 FreeBSD 到 AMD64 系統架構</entry>
+ </row>
+
+ <row>
+ <entry>&a.apache.name;</entry>
+ <entry>探討 <application>Apache</application> 相關的 ports 議題</entry>
+ </row>
+
+ <row>
+ <entry>&a.arm.name;</entry>
+ <entry>移植 FreeBSD 到 &arm; CPU 架構</entry>
+ </row>
+
+ <row>
+ <entry>&a.atm.name;</entry>
+ <entry>在 FreeBSD 上使用 ATM 網路</entry>
+ </row>
+
+ <row>
+ <entry>&a.audit.name;</entry>
+ <entry>Source code 的稽核(audit)計劃</entry>
+ </row>
+
+ <row>
+ <entry>&a.binup.name;</entry>
+ <entry>研發 binary 的升級方式</entry>
+ </row>
+
+ <row>
+ <entry>&a.bluetooth.name;</entry>
+ <entry>在 FreeBSD 中使用藍芽(&bluetooth;)技術</entry>
+ </row>
+
+ <row>
+ <entry>&a.cluster.name;</entry>
+ <entry>把 FreeBSD 在叢集架構環境(clustered environment)的運用</entry>
+ </row>
+
+ <row>
+ <entry>&a.cvsweb.name;</entry>
+ <entry>CVSweb 的維護</entry>
+ </row>
+
+ <row>
+ <entry>&a.database.name;</entry>
+ <entry>討論各式資料庫在 FreeBSD 的研發、運用</entry>
+ </row>
+
+ <row>
+ <entry>&a.doc.name;</entry>
+ <entry>撰寫 FreeBSD 相關文件</entry>
+ </row>
+
+ <row>
+ <entry>&a.drivers.name;</entry>
+ <entry>撰寫 &os; 用的驅動程式</entry>
+ </row>
+
+ <row>
+ <entry>&a.eclipse.name;</entry>
+ <entry>FreeBSD 的 Eclipse IDE 工具愛用者交流</entry>
+ </row>
+
+ <row>
+ <entry>&a.emulation.name;</entry>
+ <entry>在 FreeBSD 上模擬其他系統,如:Linux、&ms-dos;、&windows;</entry>
+ </row>
+
+ <row>
+ <entry>&a.firewire.name;</entry>
+ <entry>FreeBSD 的 &firewire; (iLink, IEEE 1394) 方面技術交流</entry>
+ </row>
+
+ <row>
+ <entry>&a.fs.name;</entry>
+ <entry>檔案系統的探討、研發</entry>
+ </row>
+
+ <row>
+ <entry>&a.geom.name;</entry>
+ <entry>GEOM 議題的探討、研發</entry>
+ </row>
+
+ <row>
+ <entry>&a.gnome.name;</entry>
+ <entry>移植 <application>GNOME</application> 及 <application>GNOME</application> 相關應用軟體</entry>
+ </row>
+
+ <row>
+ <entry>&a.hackers.name;</entry>
+ <entry>一般技術議題的探討</entry>
+ </row>
+
+ <row>
+ <entry>&a.hardware.name;</entry>
+ <entry>FreeBSD 上的各式硬體問題交流</entry>
+ </row>
+
+ <row>
+ <entry>&a.i18n.name;</entry>
+ <entry>FreeBSD 的多語化(Internationalization)</entry>
+ </row>
+
+ <row>
+ <entry>&a.ia32.name;</entry>
+ <entry>FreeBSD 在 IA-32 (&intel; x86) 平台上的使用探討</entry>
+ </row>
+
+ <row>
+ <entry>&a.ia64.name;</entry>
+ <entry>移植 FreeBSD 到 &intel; 的未來 IA64 平台架構</entry>
+ </row>
+
+ <row>
+ <entry>&a.ipfw.name;</entry>
+ <entry>對 ipfw(IP firewall) 的技術探討</entry>
+ </row>
+
+ <row>
+ <entry>&a.isdn.name;</entry>
+ <entry>ISDN 研發</entry>
+ </row>
+
+ <row>
+ <entry>&a.java.name;</entry>
+ <entry>&java; 程式開發者以及移植 &jdk;s 到 FreeBSD 上</entry>
+ </row>
+
+ <row>
+ <entry>&a.kde.name;</entry>
+ <entry>移植 <application>KDE</application> 以及 <application>KDE</application> 相關應用程式</entry>
+ </row>
+
+ <row>
+ <entry>&a.lfs.name;</entry>
+ <entry>移植 LFS 到 FreeBSD</entry>
+ </row>
+
+ <row>
+ <entry>&a.libh.name;</entry>
+ <entry>新世代的安裝、打包套件機制</entry>
+ </row>
+
+ <row>
+ <entry>&a.mips.name;</entry>
+ <entry>移植 FreeBSD 到 &mips;</entry>
+ </row>
+
+ <row>
+ <entry>&a.mobile.name;</entry>
+ <entry>關於各類 mobile computing(比如:筆記型電腦)的研討</entry>
+ </row>
+
+ <row>
+ <entry>&a.mozilla.name;</entry>
+ <entry>把 <application>Mozilla</application> 軟體移植到 FreeBSD</entry>
+ </row>
+
+ <row>
+ <entry>&a.multimedia.name;</entry>
+ <entry>各式影音運用、軟體</entry>
+ </row>
+
+ <row>
+ <entry>&a.newbus.name;</entry>
+ <entry>各式 bus 架構的技術探討</entry>
+ </row>
+
+ <row>
+ <entry>&a.net.name;</entry>
+ <entry>網路運用探討與 TCP/IP source code</entry>
+ </row>
+
+ <row>
+ <entry>&a.openoffice.name;</entry>
+ <entry>移植 <application>OpenOffice.org</application> 及
+ <application>&staroffice;</application> 到 FreeBSD</entry>
+ </row>
+
+ <row>
+ <entry>&a.performance.name;</entry>
+ <entry>在高效能/負荷環境下的效能調校(tuning)議題</entry>
+ </row>
+
+ <row>
+ <entry>&a.perl.name;</entry>
+ <entry>探討 Perl 相關 ports 的維護</entry>
+ </row>
+
+ <row>
+ <entry>&a.pf.name;</entry>
+ <entry>pf(packet filter) 防火牆機制的探討</entry>
+ </row>
+
+ <row>
+ <entry>&a.platforms.name;</entry>
+ <entry>討論著重於移植 port 到非 &intel; 架構平台的議題</entry>
+ </row>
+
+ <row>
+ <entry>&a.ports.name;</entry>
+ <entry>關於 Ports Collection 的運用、探討</entry>
+ </row>
+
+ <row>
+ <entry>&a.ports-bugs.name;</entry>
+ <entry>ports 相關的 bugs/PRs</entry>
+ </row>
+
+ <row>
+ <entry>&a.ppc.name;</entry>
+ <entry>移植 FreeBSD 到 &powerpc; 系統架構</entry>
+ </row>
+
+ <row>
+ <entry>&a.proliant.name;</entry>
+ <entry>FreeBSD 在 HP ProLiant 主機平台的使用交流</entry>
+ </row>
+
+ <row>
+ <entry>&a.python.name;</entry>
+ <entry>Python 在 FreeBSD 上使用的各式議題。</entry>
+ </row>
+
+ <row>
+ <entry>&a.qa.name;</entry>
+ <entry>QA(Quality Assurance)討論,通常會決定是否已經到達可以 release 的程度</entry>
+ </row>
+
+ <row>
+ <entry>&a.rc.name;</entry>
+ <entry><filename>rc.d</filename> 機制的討論、研發</entry>
+ </row>
+
+ <row>
+ <entry>&a.realtime.name;</entry>
+ <entry>FreeBSD 上 realtime extensions 的研發</entry>
+ </row>
+
+ <row>
+ <entry>&a.scsi.name;</entry>
+ <entry>SCSI 方面議題</entry>
+ </row>
+
+ <row>
+ <entry>&a.security.name;</entry>
+ <entry>FreeBSD 安全漏洞議題</entry>
+ </row>
+
+ <row>
+ <entry>&a.small.name;</entry>
+ <entry>在嵌入式硬體環境的應用、探討</entry>
+ </row>
+
+ <row>
+ <entry>&a.smp.name;</entry>
+ <entry>CPU 對稱多工處理(SMP, [A]Symmetric Multiprocessing)的應用、研討</entry>
+ </row>
+
+ <row>
+ <entry>&a.sparc.name;</entry>
+ <entry>移植 FreeBSD 到 &sparc; 平台架構</entry>
+ </row>
+
+ <row>
+ <entry>&a.standards.name;</entry>
+ <entry>FreeBSD 與 C99 及 &posix;標準的相容議題</entry>
+ </row>
+
+ <row>
+ <entry>&a.threads.name;</entry>
+ <entry>FreeBSD 上的 Threading 運用、探討</entry>
+ </row>
+
+ <row>
+ <entry>&a.testing.name;</entry>
+ <entry>FreeBSD 的效能與穩定性測試</entry>
+ </row>
+
+ <row>
+ <entry>&a.tokenring.name;</entry>
+ <entry>FreeBSD 的 Token Ring 支援的應用、探討</entry>
+ </row>
+
+ <row>
+ <entry>&a.usb.name;</entry>
+ <entry>&os; 的 USB 支援的應用、探討</entry>
+ </row>
+
+ <row>
+ <entry>&a.vuxml.name;</entry>
+ <entry>VuXML 漏洞通報架構的探討</entry>
+ </row>
+
+ <row>
+ <entry>&a.x11.name;</entry>
+ <entry>X11 在 FreeBSD 的運用</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para><emphasis>有訂閱限制的論壇:</emphasis> 以下的 lists 是針對一些特定要求的讀者而設,
+ 而且並不適合當成是一般的公開討論區。
+ 您最好先在某些技術討論區參與一段時間的討論後,再選擇訂閱這些有限制的論壇。
+ 因為如此一來,您可以了解到在這些討論區發言所須的禮儀。</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>List 名稱</entry>
+ <entry>目的</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>&a.hubs.name;</entry>
+ <entry>映射站台(mirror)的交流討論區</entry>
+ </row>
+
+ <row>
+ <entry>&a.usergroups.name;</entry>
+ <entry>社群間的協調</entry>
+ </row>
+
+ <row>
+ <entry>&a.vendors.name;</entry>
+ <entry>Vendors pre-release coordination</entry>
+ </row>
+
+ <row>
+ <entry>&a.www.name;</entry>
+ <entry><link xlink:href="&url.base;/index.html">www.FreeBSD.org</link> 的管理維護</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para><emphasis>論壇的摘要版:</emphasis> 上述的各 lists 都有摘要版(digest),
+ 在訂閱 list 之後,就可以先以自己帳號登入,然後個人訂閱選項那邊改為摘要版即可。</para>
+
+ <para><emphasis>CVS lists:</emphasis> 以下的 lists 是提供給想要看各個 tree 的提交(commit)紀錄,
+ 請注意:他們是 <emphasis>唯讀(Read-Only)</emphasis> 性質的 list
+ ,而且不能寄信給這。</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>List 名稱</entry>
+ <entry>Source 區域</entry>
+ <entry>本區簡介 (source for)</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>&a.cvsall.name;</entry>
+ <entry><filename>/usr/(CVSROOT|doc|ports|projects|src)</filename></entry>
+ <entry>全部的變更記錄(包括各類 CVS commit)</entry>
+ </row>
+
+ <row>
+ <entry>&a.cvs-doc.name;</entry>
+ <entry><filename>/usr/(doc|www)</filename></entry>
+ <entry>doc 及 www trees 的所有變更紀錄</entry>
+ </row>
+
+ <row>
+ <entry>&a.cvs-ports.name;</entry>
+ <entry><filename>/usr/ports</filename></entry>
+ <entry>ports tree 的所有變更紀錄</entry>
+ </row>
+
+ <row>
+ <entry>&a.cvs-projects.name;</entry>
+ <entry><filename>/usr/projects</filename></entry>
+ <entry>projects tree 的所有變更紀錄</entry>
+ </row>
+
+ <row>
+ <entry>&a.cvs-src.name;</entry>
+ <entry><filename>/usr/src</filename></entry>
+ <entry>src tree 的所有變更紀錄</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2 xml:id="eresources-subscribe">
+ <title>要如何訂閱</title>
+
+ <para>要訂閱 list 的話,請以滑鼠按下上述 list 名稱,
+ 或是到 &a.mailman.lists.link; 然後即可挑選有興趣的 list 來訂閱了,
+ 該網頁會指示你如何進行訂閱的步驟。</para>
+
+ <para>To actually post to a given list you simply send mail to
+ <email><replaceable>listname</replaceable>@FreeBSD.org</email>. It will then
+ be redistributed to mailing list members world-wide.</para>
+
+ <para>To unsubscribe yourself from a list, click on the URL
+ found at the bottom of every email received from the list. It
+ is also possible to send an email to
+ <email><replaceable>listname</replaceable>-unsubscribe@FreeBSD.org</email> to unsubscribe
+ yourself.</para>
+
+ <para>Again, we would like to request that you keep discussion in the
+ technical mailing lists on a technical track. If you are only
+ interested in important announcements then it is suggested that
+ you join the &a.announce;, which is intended only for infrequent
+ traffic.</para>
+ </sect2>
+
+ <sect2 xml:id="eresources-charters">
+ <title>List Charters</title>
+
+ <para><emphasis>All</emphasis> FreeBSD mailing lists have certain basic
+ rules which must be adhered to by anyone using them. Failure to comply
+ with these guidelines will result in two (2) written warnings from the
+ FreeBSD Postmaster <email>postmaster@FreeBSD.org</email>, after which,
+ on a third offense, the poster will removed from all FreeBSD mailing
+ lists and filtered from further posting to them. We regret that such
+ rules and measures are necessary at all, but today's Internet is a
+ pretty harsh environment, it would seem, and many fail to appreciate
+ just how fragile some of its mechanisms are.</para>
+
+ <para>Rules of the road:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The topic of any posting should adhere to the basic charter of
+ the list it is posted to, e.g. if the list is about technical
+ issues then your posting should contain technical discussion.
+ Ongoing irrelevant chatter or flaming only detracts from the value
+ of the mailing list for everyone on it and will not be tolerated.
+ For free-form discussion on no particular topic, the &a.chat;
+ is freely available and should be used instead.</para>
+ </listitem>
+
+ <listitem>
+ <para>No posting should be made to more than 2 mailing lists, and
+ only to 2 when a clear and obvious need to post to both lists
+ exists. For most lists, there is already a great deal of
+ subscriber overlap and except for the most esoteric mixes (say
+ <quote>-stable &amp; -scsi</quote>), there really is no reason to post to more
+ than one list at a time. If a message is sent to you in such a
+ way that multiple mailing lists appear on the
+ <literal>Cc</literal> line then the <literal>Cc</literal>
+ line should also be trimmed before sending it out again.
+ <emphasis>You are still responsible for your
+ own cross-postings, no matter who the originator might have
+ been.</emphasis></para>
+ </listitem>
+
+ <listitem>
+ <para>Personal attacks and profanity (in the context of an argument)
+ are not allowed, and that includes users and developers alike.
+ Gross breaches of netiquette, like excerpting or reposting private
+ mail when permission to do so was not and would not be
+ forthcoming, are frowned upon but not specifically enforced.
+ <emphasis>However</emphasis>, there are also very few cases where
+ such content would fit within the charter of a list and it would
+ therefore probably rate a warning (or ban) on that basis
+ alone.</para>
+ </listitem>
+
+ <listitem>
+ <para>Advertising of non-FreeBSD related products or services is
+ strictly prohibited and will result in an immediate ban if it is
+ clear that the offender is advertising by spam.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><emphasis>Individual list charters:</emphasis></para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>&a.acpi.name;</term>
+
+ <listitem>
+ <para><emphasis>ACPI and power management
+ development</emphasis></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.afs.name;</term>
+
+ <listitem>
+ <para><emphasis>Andrew File System</emphasis></para>
+
+ <para>This list is for discussion on porting and using AFS from
+ CMU/Transarc</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.announce.name;</term>
+
+ <listitem>
+ <para><emphasis>Important events / milestones</emphasis></para>
+
+ <para>This is the mailing list for people interested only in
+ occasional announcements of significant FreeBSD events. This
+ includes announcements about snapshots and other releases. It
+ contains announcements of new FreeBSD capabilities. It may
+ contain calls for volunteers etc. This is a low volume, strictly
+ moderated mailing list.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.arch.name;</term>
+
+ <listitem>
+ <para><emphasis>Architecture and design
+ discussions</emphasis></para>
+
+ <para>This list is for discussion of the FreeBSD
+ architecture. Messages will mostly be kept strictly
+ technical in nature. Examples of suitable topics
+ are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>How to re-vamp the build system to have several
+ customized builds running at the same time.</para>
+ </listitem>
+
+ <listitem>
+ <para>What needs to be fixed with VFS to make Heidemann layers
+ work.</para>
+ </listitem>
+
+ <listitem>
+ <para>How do we change the device driver interface to be able
+ to use the same drivers cleanly on many buses and
+ architectures.</para>
+ </listitem>
+
+ <listitem>
+ <para>How to write a network driver.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.audit.name;</term>
+
+ <listitem>
+ <para><emphasis>Source code audit project</emphasis></para>
+
+ <para>This is the mailing list for the FreeBSD source code
+ audit project. Although this was originally intended for
+ security-related changes, its charter has been expanded to
+ review any code changes.</para>
+
+ <para>This list is very heavy on patches, and is probably of no
+ interest to the average FreeBSD user. Security discussions
+ not related to a particular code change are held on
+ freebsd-security. Conversely, all developers are encouraged
+ to send their patches here for review, especially if they
+ touch a part of the system where a bug may adversely affect
+ the integrity of the system.</para>
+
+<!-- I can't actually find a charter for this, but there's this email: http://www.FreeBSD.org/cgi/getmsg.cgi?fetch=223347+225804+/usr/local/www/db/text/2000/cvs-all/20001210.cvs-all -->
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.binup.name;</term>
+
+ <listitem>
+ <para><emphasis>FreeBSD Binary Update Project</emphasis></para>
+
+ <para>This list exists to provide discussion for the binary
+ update system, or <application>binup</application>.
+ Design issues, implementation details,
+ patches, bug reports, status reports, feature requests, commit
+ logs, and all other things related to
+ <application>binup</application> are fair game.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.bluetooth.name;</term>
+
+ <listitem>
+ <para><emphasis>&bluetooth; in FreeBSD</emphasis></para>
+
+ <para>This is the forum where FreeBSD's &bluetooth; users
+ congregate. Design issues, implementation details,
+ patches, bug reports, status reports, feature requests,
+ and all matters related to &bluetooth; are fair
+ game.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.bugbusters.name;</term>
+
+ <listitem>
+ <para><emphasis>Coordination of the Problem Report handling effort</emphasis></para>
+
+ <para>The purpose of this list is to serve as a coordination and
+ discussion forum for the Bugmeister, his Bugbusters, and any other
+ parties who have a genuine interest in the PR database. This list
+ is not for discussions about specific bugs, patches or PRs.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.bugs.name;</term>
+
+ <listitem>
+ <para><emphasis>Bug reports</emphasis></para>
+
+ <para>This is the mailing list for reporting bugs in FreeBSD.
+ Whenever possible, bugs should be submitted using the
+ &man.send-pr.1;
+ command or the <link xlink:href="&url.base;/send-pr.html">WEB
+ interface</link> to it.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.chat.name;</term>
+
+ <listitem>
+ <para><emphasis>Non technical items related to the FreeBSD
+ community</emphasis></para>
+
+ <para>This list contains the overflow from the other lists about
+ non-technical, social information. It includes discussion about
+ whether Jordan looks like a toon ferret or not, whether or not
+ to type in capitals, who is drinking too much coffee, where the
+ best beer is brewed, who is brewing beer in their basement, and
+ so on. Occasional announcements of important events (such as
+ upcoming parties, weddings, births, new jobs, etc) can be made
+ to the technical lists, but the follow ups should be directed to
+ this -chat list.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.core.name;</term>
+
+ <listitem>
+ <para><emphasis>FreeBSD core team</emphasis></para>
+
+ <para>This is an internal mailing list for use by the core
+ members. Messages can be sent to it when a serious
+ FreeBSD-related matter requires arbitration or high-level
+ scrutiny.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.current.name;</term>
+
+ <listitem>
+ <para><emphasis>Discussions about the use of
+ &os.current;</emphasis></para>
+
+ <para>This is the mailing list for users of &os.current;. It
+ includes warnings about new features coming out in -CURRENT that
+ will affect the users, and instructions on steps that must be
+ taken to remain -CURRENT. Anyone running <quote>CURRENT</quote>
+ must subscribe to this list. This is a technical mailing list
+ for which strictly technical content is expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.cvsweb.name;</term>
+
+ <listitem>
+ <para><emphasis>FreeBSD CVSweb Project</emphasis></para>
+
+ <para>Technical discussions about use, development and maintenance
+ of FreeBSD-CVSweb.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.doc.name;</term>
+
+ <listitem>
+ <para><emphasis>Documentation project</emphasis></para>
+
+ <para>This mailing list is for the discussion of issues and
+ projects related to the creation of documentation for FreeBSD.
+ The members of this mailing list are collectively referred to as
+ <quote>The FreeBSD Documentation Project</quote>. It is an open
+ list; feel free to join and contribute!</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.drivers.name;</term>
+
+ <listitem>
+ <para><emphasis>Writing device drivers for &os;</emphasis></para>
+
+ <para>This is a forum for technical discussions related to
+ device drivers on &os;. It is primarily a place
+ for device driver writers to ask questions about
+ how to write device drivers using the APIs in the
+ &os; kernel.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.eclipse.name;</term>
+
+ <listitem>
+ <para><emphasis>&os; users of Eclipse IDE, tools, rich
+ client applications and ports.</emphasis></para>
+
+ <para>The intention of this list is to provide mutual
+ support for everything to do with choosing, installing,
+ using, developing and maintaining the Eclipse IDE,
+ tools, rich client applications on the &os; platform and
+ assisting with the porting of Eclipse IDE and plugins to
+ the &os; environment.</para>
+
+ <para>The intention is also to facilitate exchange of
+ information between the Eclipse community and the &os;
+ community to the mutual benefit of both.</para>
+
+ <para>Although this list is focused primarily on the needs
+ of Eclipse users it will also provide a forum for those
+ who would like to develop &os; specific applications
+ using the Eclipse framework.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.emulation.name;</term>
+
+ <listitem>
+ <para><emphasis>Emulation of other systems such as
+ Linux/&ms-dos;/&windows;</emphasis></para>
+
+ <para>This is a forum for technical discussions related to
+ running programs written for other operating systems on &os;.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.firewire.name;</term>
+
+ <listitem>
+ <para><emphasis>&firewire; (iLink, IEEE 1394)</emphasis></para>
+
+ <para>This is a mailing list for discussion of the design
+ and implementation of a &firewire; (aka IEEE 1394 aka
+ iLink) subsystem for FreeBSD. Relevant topics
+ specifically include the standards, bus devices and
+ their protocols, adapter boards/cards/chips sets, and
+ the architecture and implementation of code for their
+ proper support.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.fs.name;</term>
+
+ <listitem>
+ <para><emphasis>File systems</emphasis></para>
+
+ <para>Discussions concerning FreeBSD file systems. This is a
+ technical mailing list for which strictly technical content is
+ expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.geom.name;</term>
+
+ <listitem>
+ <para><emphasis>GEOM</emphasis></para>
+
+ <para>Discussions specific to GEOM and related implementations.
+ This is a technical mailing list for which strictly technical
+ content is expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.gnome.name;</term>
+
+ <listitem>
+ <para><emphasis>GNOME</emphasis></para>
+
+ <para>Discussions concerning The <application>GNOME</application> Desktop Environment for
+ FreeBSD systems. This is a technical mailing list for
+ which strictly technical content is expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.ipfw.name;</term>
+
+ <listitem>
+ <para><emphasis>IP Firewall</emphasis></para>
+
+ <para>This is the forum for technical discussions concerning the
+ redesign of the IP firewall code in FreeBSD. This is a
+ technical mailing list for which strictly technical content is
+ expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.ia64.name;</term>
+
+ <listitem>
+ <para><emphasis>Porting FreeBSD to IA64</emphasis></para>
+
+ <para>This is a technical mailing list for individuals
+ actively working on porting FreeBSD to the IA-64 platform
+ from &intel;, to bring up problems or discuss alternative
+ solutions. Individuals interested in following the
+ technical discussion are also welcome.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.isdn.name;</term>
+
+ <listitem>
+ <para><emphasis>ISDN Communications</emphasis></para>
+
+ <para>This is the mailing list for people discussing the
+ development of ISDN support for FreeBSD.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.java.name;</term>
+
+ <listitem>
+ <para><emphasis>&java; Development</emphasis></para>
+
+ <para>This is the mailing list for people discussing the
+ development of significant &java; applications for FreeBSD and the
+ porting and maintenance of &jdk;s.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry xml:id="eresources-charters-jobs">
+ <term>&a.jobs.name;</term>
+
+ <listitem>
+ <para><emphasis>Jobs offered and sought</emphasis></para>
+
+ <para>This is a forum for posting employment notices and
+ resumes specifically related to &os;, e.g. if you are
+ seeking &os;-related employment or have a job involving
+ &os; to advertise then this is the right place. This is
+ <emphasis>not</emphasis> a mailing list for general
+ employment issues since adequate forums for that
+ already exist elsewhere.</para>
+
+ <para>Note that this list, like other <systemitem class="fqdomainname">FreeBSD.org</systemitem> mailing
+ lists, is distributed worldwide. Thus, you need to be
+ clear about location and the extent to which
+ telecommuting or assistance with relocation is
+ available.</para>
+
+ <para>Email should use open formats only &mdash;
+ preferably plain text, but basic Portable Document
+ Format (<acronym>PDF</acronym>), HTML, and a few others
+ are acceptable to many readers. Closed formats such as
+ &microsoft; Word (<filename>.doc</filename>) will be
+ rejected by the mailing list server.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.kde.name;</term>
+
+ <listitem>
+ <para><emphasis>KDE</emphasis></para>
+
+ <para>Discussions concerning <application>KDE</application> on
+ FreeBSD systems. This is a technical mailing list for
+ which strictly technical content is expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.hackers.name;</term>
+
+ <listitem>
+ <para><emphasis>Technical discussions</emphasis></para>
+
+ <para>This is a forum for technical discussions related to
+ FreeBSD. This is the primary technical mailing list. It is for
+ individuals actively working on FreeBSD, to bring up problems or
+ discuss alternative solutions. Individuals interested in
+ following the technical discussion are also welcome. This is a
+ technical mailing list for which strictly technical content is
+ expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.hardware.name;</term>
+
+ <listitem>
+ <para><emphasis>General discussion of FreeBSD
+ hardware</emphasis></para>
+
+ <para>General discussion about the types of hardware that FreeBSD
+ runs on, various problems and suggestions concerning what to buy
+ or avoid.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.hubs.name;</term>
+
+ <listitem>
+ <para><emphasis>Mirror sites</emphasis></para>
+
+ <para>Announcements and discussion for people who run FreeBSD
+ mirror sites.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.isp.name;</term>
+
+ <listitem>
+ <para><emphasis>Issues for Internet Service
+ Providers</emphasis></para>
+
+ <para>This mailing list is for discussing topics relevant to
+ Internet Service Providers (ISPs) using FreeBSD. This is a
+ technical mailing list for which strictly technical content is
+ expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.openoffice.name;</term>
+
+ <listitem>
+ <para><emphasis>OpenOffice.org</emphasis></para>
+
+ <para>Discussions concerning the porting and maintenance
+ of <application>OpenOffice.org</application> and
+ <application>&staroffice;</application>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.performance.name;</term>
+
+ <listitem>
+ <para><emphasis>Discussions about tuning or speeding up FreeBSD</emphasis></para>
+
+ <para>This mailing list exists to provide a place for
+ hackers, administrators, and/or concerned parties to
+ discuss performance related topics pertaining to
+ FreeBSD. Acceptable topics includes talking about
+ FreeBSD installations that are either under high load,
+ are experiencing performance problems, or are pushing
+ the limits of FreeBSD. Concerned parties that are
+ willing to work toward improving the performance of
+ FreeBSD are highly encouraged to subscribe to this list.
+ This is a highly technical list ideally suited for
+ experienced FreeBSD users, hackers, or administrators
+ interested in keeping FreeBSD fast, robust, and
+ scalable. This list is not a question-and-answer list
+ that replaces reading through documentation, but it is a
+ place to make contributions or inquire about unanswered
+ performance related topics.</para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.pf.name;</term>
+
+ <listitem>
+ <para><emphasis>Discussion and questions about the packet filter
+ firewall system</emphasis></para>
+
+ <para>Discussion concerning the packet filter (pf) firewall
+ system in terms of FreeBSD. Technical discussion and user
+ questions are both welcome. This list is also a place to
+ discuss the ALTQ QoS framework.</para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.platforms.name;</term>
+
+ <listitem>
+ <para><emphasis>Porting to Non &intel; platforms</emphasis></para>
+
+ <para>Cross-platform FreeBSD issues, general discussion and
+ proposals for non &intel; FreeBSD ports. This is a technical
+ mailing list for which strictly technical content is
+ expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.policy.name;</term>
+
+ <listitem>
+ <para><emphasis>Core team policy decisions</emphasis></para>
+
+ <para>This is a low volume, read-only mailing list for FreeBSD
+ Core Team Policy decisions.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.ports.name;</term>
+
+ <listitem>
+ <para><emphasis>Discussion of
+ <quote>ports</quote></emphasis></para>
+
+ <para>Discussions concerning FreeBSD's <quote>ports
+ collection</quote> (<filename>/usr/ports</filename>), ports infrastructure, and
+ general ports coordination efforts. This is a technical mailing list
+ for which strictly technical content is expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.ports-bugs.name;</term>
+
+ <listitem>
+ <para><emphasis>Discussion of
+ <quote>ports</quote> bugs</emphasis></para>
+
+ <para>Discussions concerning problem reports for FreeBSD's <quote>ports
+ collection</quote> (<filename>/usr/ports</filename>), proposed
+ ports, or modifications to ports. This is a technical mailing list
+ for which strictly technical content is expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.proliant.name;</term>
+
+ <listitem>
+ <para><emphasis>Technical discussion of FreeBSD on HP
+ ProLiant server platforms</emphasis></para>
+
+ <para>This mailing list is to be used for the technical
+ discussion of the usage of FreeBSD on HP ProLiant servers,
+ including the discussion of ProLiant-specific drivers,
+ management software, configuration tools, and BIOS
+ updates. As such, this is the primary place to discuss
+ the hpasmd, hpasmcli, and hpacucli modules.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.python.name;</term>
+
+ <listitem>
+ <para><emphasis>Python on FreeBSD</emphasis></para>
+
+ <para>This is a list for discussions related to improving Python-support
+ on FreeBSD. This is a technical mailing list. It is for individuals
+ working on porting Python, its 3rd party modules and <application>Zope</application> stuff to
+ FreeBSD. Individuals interested in following the technical discussion
+ are also welcome.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.questions.name;</term>
+
+ <listitem>
+ <para><emphasis>User questions</emphasis></para>
+
+ <para>This is the mailing list for questions about FreeBSD. You
+ should not send <quote>how to</quote> questions to the technical
+ lists unless you consider the question to be pretty
+ technical.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.scsi.name;</term>
+
+ <listitem>
+ <para><emphasis>SCSI subsystem</emphasis></para>
+
+ <para>This is the mailing list for people working on the SCSI
+ subsystem for FreeBSD. This is a technical mailing list for
+ which strictly technical content is expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.security.name;</term>
+
+ <listitem>
+ <para><emphasis>Security issues</emphasis></para>
+
+ <para>FreeBSD computer security issues (DES, Kerberos, known
+ security holes and fixes, etc). This is a technical mailing
+ list for which strictly technical discussion is expected. Note
+ that this is not a question-and-answer list, but that
+ contributions (BOTH question AND answer) to the FAQ are
+ welcome.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.security-notifications.name;</term>
+
+ <listitem>
+ <para><emphasis>Security Notifications</emphasis></para>
+
+ <para>Notifications of FreeBSD security problems and
+ fixes. This is not a discussion list. The discussion
+ list is FreeBSD-security.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.small.name;</term>
+
+ <listitem>
+ <para><emphasis>Using FreeBSD in embedded
+ applications</emphasis></para>
+
+ <para>This list discusses topics related to unusually small and
+ embedded FreeBSD installations. This is a technical mailing
+ list for which strictly technical content is expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.stable.name;</term>
+
+ <listitem>
+ <para><emphasis>Discussions about the use of
+ &os.stable;</emphasis></para>
+
+ <para>This is the mailing list for users of &os.stable;. It
+ includes warnings about new features coming out in -STABLE that
+ will affect the users, and instructions on steps that must be
+ taken to remain -STABLE. Anyone running <quote>STABLE</quote>
+ should subscribe to this list. This is a technical mailing list
+ for which strictly technical content is expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.standards.name;</term>
+
+ <listitem>
+ <para><emphasis>C99 &amp; POSIX Conformance</emphasis></para>
+
+ <para>This is a forum for technical discussions related to
+ FreeBSD Conformance to the C99 and the POSIX standards.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.usb.name;</term>
+
+ <listitem>
+ <para><emphasis>Discussing &os; support for
+ USB</emphasis></para>
+
+ <para>This is a mailing list for technical discussions
+ related to &os; support for USB.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.usergroups.name;</term>
+
+ <listitem>
+ <para><emphasis>User Group Coordination List</emphasis></para>
+
+ <para>This is the mailing list for the coordinators from each of
+ the local area Users Groups to discuss matters with each other
+ and a designated individual from the Core Team. This mail list
+ should be limited to meeting synopsis and coordination of
+ projects that span User Groups.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&a.vendors.name;</term>
+
+ <listitem>
+ <para><emphasis>Vendors</emphasis></para>
+
+ <para>Coordination discussions between The FreeBSD Project and
+ Vendors of software and hardware for FreeBSD.</para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+ <sect2 xml:id="eresources-mailfiltering">
+ <title>Filtering on the Mailing Lists</title>
+
+ <para>The &os; mailing lists are filtered in multiple ways to
+ avoid the distribution of spam, viruses, and other unwanted emails.
+ The filtering actions described in this section do not include all
+ those used to protect the mailing lists.</para>
+
+ <para>Only certain types of attachments are allowed on the
+ mailing lists. All attachments with a MIME content type not
+ found in the list below will be stripped before an email is
+ distributed on the mailing lists.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>application/octet-stream</para>
+ </listitem>
+
+ <listitem>
+ <para>application/pdf</para>
+ </listitem>
+
+ <listitem>
+ <para>application/pgp-signature</para>
+ </listitem>
+
+ <listitem>
+ <para>application/x-pkcs7-signature</para>
+ </listitem>
+
+ <listitem>
+ <para>message/rfc822</para>
+ </listitem>
+
+ <listitem>
+ <para>multipart/alternative</para>
+ </listitem>
+
+ <listitem>
+ <para>multipart/related</para>
+ </listitem>
+
+ <listitem>
+ <para>multipart/signed</para>
+ </listitem>
+
+ <listitem>
+ <para>text/html</para>
+ </listitem>
+
+ <listitem>
+ <para>text/plain</para>
+ </listitem>
+
+ <listitem>
+ <para>text/x-diff</para>
+ </listitem>
+
+ <listitem>
+ <para>text/x-patch</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <para>Some of the mailing lists might allow attachments of
+ other MIME content types, but the above list should be
+ applicable for most of the mailing lists.</para>
+ </note>
+
+ <para>If an email contains both an HTML and a plain text version,
+ the HTML version will be removed. If an email contains only an
+ HTML version, it will be converted to plain text.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="eresources-news">
+ <title>Usenet Newsgroups</title>
+
+ <para>In addition to two FreeBSD specific newsgroups, there are many
+ others in which FreeBSD is discussed or are otherwise relevant to
+ FreeBSD users. <link xlink:href="http://minnie.tuhs.org/BSD-info/bsdnews_search.html">Keyword
+ searchable archives</link> are available for some of these newsgroups
+ from courtesy of Warren Toomey <email>wkt@cs.adfa.edu.au</email>.</para>
+
+ <sect2>
+ <title>BSD Specific Newsgroups</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="news:comp.unix.bsd.freebsd.announce">comp.unix.bsd.freebsd.announce</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.unix.bsd.freebsd.misc">comp.unix.bsd.freebsd.misc</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:de.comp.os.unix.bsd">de.comp.os.unix.bsd</link> (German)</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:fr.comp.os.bsd">fr.comp.os.bsd</link> (French)</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:it.comp.os.freebsd">it.comp.os.freebsd</link> (Italian)</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>Other &unix; Newsgroups of Interest</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="news:comp.unix">comp.unix</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.unix.questions">comp.unix.questions</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.unix.admin">comp.unix.admin</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.unix.programmer">comp.unix.programmer</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.unix.shell">comp.unix.shell</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.unix.user-friendly">comp.unix.user-friendly</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.security.unix">comp.security.unix</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.sources.unix">comp.sources.unix</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.unix.advocacy">comp.unix.advocacy</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.unix.misc">comp.unix.misc</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.bugs.4bsd">comp.bugs.4bsd</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.bugs.4bsd.ucb-fixes">comp.bugs.4bsd.ucb-fixes</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.unix.bsd">comp.unix.bsd</link></para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>X Window System</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="news:comp.windows.x.i386unix">comp.windows.x.i386unix</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.windows.x">comp.windows.x</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.windows.x.apps">comp.windows.x.apps</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.windows.x.announce">comp.windows.x.announce</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.windows.x.intrinsics">comp.windows.x.intrinsics</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.windows.x.motif">comp.windows.x.motif</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.windows.x.pex">comp.windows.x.pex</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="news:comp.emulators.ms-windows.wine">comp.emulators.ms-windows.wine</link></para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="eresources-web">
+ <title>World Wide Web Servers</title>
+
+ &chap.eresources.www.index.inc;
+
+ &chap.mirrors.lastmod.inc;
+
+ &chap.eresources.www.inc;
+ </sect1>
+
+ <sect1 xml:id="eresources-email">
+ <title>Email Addresses</title>
+
+ <para>The following user groups provide FreeBSD related email addresses
+ for their members. The listed administrator reserves the right to
+ revoke the address if it is abused in any way.</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Domain</entry>
+ <entry>Facilities</entry>
+ <entry>User Group</entry>
+ <entry>Administrator</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>ukug.uk.FreeBSD.org</entry>
+ <entry>Forwarding only</entry>
+ <entry><email>freebsd-users@uk.FreeBSD.org</email></entry>
+ <entry>Lee Johnston
+ <email>lee@uk.FreeBSD.org</email></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect1>
+
+ <sect1 xml:id="eresources-shell">
+ <title>Shell Accounts</title>
+
+ <para>The following user groups provide shell accounts for people who are
+ actively supporting the FreeBSD project. The listed administrator
+ reserves the right to cancel the account if it is abused in any
+ way.</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Host</entry>
+ <entry>Access</entry>
+ <entry>Facilities</entry>
+ <entry>Administrator</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>dogma.freebsd-uk.eu.org</entry>
+ <entry>Telnet/FTP/SSH</entry>
+ <entry>Email, Web space, Anonymous FTP</entry>
+ <entry>Lee Johnston
+ <email>lee@uk.FreeBSD.org</email></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect1>
+</appendix>
diff --git a/zh_TW.UTF-8/books/handbook/firewalls/Makefile b/zh_TW.UTF-8/books/handbook/firewalls/Makefile
new file mode 100644
index 0000000000..9320a51f68
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/firewalls/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= firewalls/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/firewalls/chapter.xml b/zh_TW.UTF-8/books/handbook/firewalls/chapter.xml
new file mode 100644
index 0000000000..159372890f
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/firewalls/chapter.xml
@@ -0,0 +1,3260 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.66
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="firewalls">
+ <info><title>防火牆</title>
+ <authorgroup>
+ <author><personname><firstname>Joseph J.</firstname><surname>Barbish</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Brad</firstname><surname>Davis</surname></personname><contrib>Converted to SGML and updated by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm><primary>防火牆</primary></indexterm>
+
+ <indexterm>
+ <primary>安全</primary>
+
+ <secondary>防火牆</secondary>
+ </indexterm>
+
+ <sect1 xml:id="firewalls-intro">
+ <title>概述</title>
+
+ <para>防火牆能夠過濾你的系統中進出的流量。
+ 防火牆也能藉由設置一或多組「規則(rules)」
+ 來檢查你的網路連結中進出的網路封包(network packets),
+ 並且能允許或阻擋其通過。
+ 這些防火牆的規則可以檢查封包中的特徵,
+ 這些特徵涵蓋,但不限於某些通訊協定類型、主機位址的來源或目的,
+ 以及連接埠(port)的來源及目的。</para>
+
+ <para>防火牆能夠大幅地增強主機或是網路的安全性。
+ 它也能夠用來執行下列事項:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>保護或隔離你內部網路的應用程式、服務以及機器,
+ 免於被來自 Internet 中你不想要的傳輸所影響</para>
+ </listitem>
+
+ <listitem>
+ <para>限制或禁止內部網路對 Internet 的存取服務</para>
+ </listitem>
+
+ <listitem>
+ <para>支援「網路位址轉換」(network address translation
+ , <acronym>NAT</acronym>),它可以允許你的內部網路使用 private
+ <acronym>IP</acronym> 位址並可以共同分享一個單一連線到網際網路上
+ (可同時用單一<acronym>IP</acronym>位址或是一組公共網址)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>讀完這章之後,你將會知道:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>如何適當地訂出封包過濾的規則。</para>
+ </listitem>
+
+ <listitem>
+ <para>&os; 中內建的防火牆之間的差異。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何使用及設定 OpenBSD 的
+ <application>PF</application> 防火牆。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何使用及設定
+ <application>IPFILTER</application>。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何使用及設定
+ <application>IPFW</application>。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>在閱讀這章之前,你必須:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>了解基本的 &os; 和 Internet 觀念</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="firewalls-concepts">
+ <title>淺談防火牆概念</title>
+
+ <indexterm>
+ <primary>防火牆</primary>
+
+ <secondary>規則</secondary>
+ </indexterm>
+
+ <para>基本上防火牆規則可分為兩種型態,分別為:「exclusive」以及
+ 「inclusive」。
+ <!-- inclusive/exclusive 參考 Mattlinuxer 的意見
+ 因為 exclusive 防火牆是先容許所有封包通過,再透過規則阻擋
+ 不想讓其通過的封包。而 inclusive 則是檔掉所有,後來再容許
+ 符合規則的封包通過。
+ -->
+ 「exclusive」類似「黑名單」,它先允許所有封包通過,
+ 然後違反規則的封包則禁止通過防火牆。
+ 相反的,「inclusive」類似「白名單」,它先擋住所有封包通過,
+ 然後只允許有符合規則的才可通過防火牆。</para>
+
+ <para>整體來說,「inclusive」式防火牆會比「exclusive」式防火牆安全些。
+ 因為「inclusive」明顯降低了不必要的風險。</para>
+
+ <para>此外,使用「stateful firewall」可讓安全性更嚴密。
+ 它會持續記錄通過防火牆開放的連線,
+ 並且只允許符合現存或開啟新的連線才能通過防火牆。
+ 狀態防火牆的缺點是如果在非常快的速度下開啟許多新連線,
+ 就可能會受到阻絕式服務攻擊(<acronym>DoS</acronym>, Denial of Service)。
+ 在大多數的防火牆方案中,也可以交叉運用「stateful 」及「non-stateful」
+ 防火牆的組合,讓該網站的防火牆達到最佳化。</para>
+ </sect1>
+
+ <sect1 xml:id="firewalls-apps">
+ <title>防火牆相關軟體</title>
+
+
+ <para>在 &os; 基本系統中內建有三種不同的防火牆軟體套件。
+ 它們分別是 <emphasis>IPFILTER</emphasis>
+ (也就是 <acronym>IPF</acronym>)、
+ <emphasis>IPFIREWALL</emphasis> (也就是 <acronym>IPFW</acronym>),
+ 以及<emphasis> OpenBSD 的 PacketFilter</emphasis> (即有名的
+ <acronym>PF</acronym>)。
+ &os; 也有兩個內建的流量控管套件(基本上是控制頻寬的使用):
+ &man.altq.4; 以及 &man.dummynet.4;。
+ 通常我們習慣把 Dummynet 與 <acronym>IPFW</acronym> 一併運用,
+ 而 <acronym>ALTQ</acronym> 則是搭配
+ <acronym>IPF</acronym>/<acronym>PF</acronym> 一同使用。
+ 雖然 IPF、IPFW 以及 PF 是使用不同的實做方式及規則語法,
+ 但是它們都使用規則來控制是否允許資料封包進出你的系統。</para>
+
+ <para>&os; 為何會內建許多不同的防火牆軟體套件,這是因為不同人會有不同的需求
+ 、偏好,很難說哪一個防火牆軟體套件是最好的。</para>
+
+ <para>而筆者偏好 IPFILTER 的原因,是因為運用在 <acronym>NAT</acronym>
+ 環境的時候,它的狀態規則是相對簡單許多的。
+ 而且它內建的 FTP 代理,也簡化了如何設定安全的對外 FTP 服務規則。</para>
+
+ <!-- psilotum: 20060309: 這段實在翻的有點怪,參考 zh_CN 翻譯 -->
+ <para>正由於所有的防火牆都是以「檢查、控制所選定之封包」的實作,所以,
+ 制定防火牆規則的人就更必須了解 <acronym>TCP</acronym>/IP 如何運作,
+ 以及如何控制封包在正常 session 的各種作用。
+ 更詳盡的說明,請參閱:
+ <uri xlink:href="http://www.ipprimer.com/overview.cfm">http://www.ipprimer.com/overview.cfm</uri>。</para>
+
+ </sect1>
+
+ <sect1 xml:id="firewalls-pf">
+ <title>OpenBSD 封包過濾器 (Packet Filter, PF)及
+ <acronym>ALTQ</acronym></title>
+
+ <indexterm>
+ <primary>防火牆</primary>
+
+ <secondary>PF</secondary>
+ </indexterm>
+
+ <para>在 2003 年 6 月份,OpenBSD 的防火牆軟體 <acronym>PF</acronym>
+ 被移植到 &os; 中,並且收錄於 Ports Collection 內。
+ 而 2004 年 11 月份所發行的 &os;&nbsp;5.3 版也是第一次將
+ <acronym>PF</acronym> 整合為基礎系統的一部分。
+ <acronym>PF</acronym>是個完備、全功能的防火牆,
+ 並且具有選擇性 <acronym>ALTQ</acronym>(交錯佇列,Alternate Queuing)
+ <!--psilotum: 20060309 alternative queuing 參考 zh_CN 的翻譯 -->
+ 的功能。
+ <acronym>ALTQ</acronym>提供了「<acronym>QoS</acronym>」
+ (Quality of Service)頻寬管制功能,
+ 它可以用過濾規則的方式來保障各種不同服務的頻寬。
+ 另外,OpenBSD 計劃中已經對 PF 的使用指南提供了詳盡的解說,
+ 因此在這本手冊中我們不會作重複的贅述,而只介紹概要。</para>
+ <!--20060309 psilotum:怎麼翻譯都覺得有點怪,所以最後一句重寫-->
+
+ <para>更多關於 PF 的資訊可於下列網址查詢:<uri xlink:href="http://pf4freebsd.love2party.net/">http://pf4freebsd.love2party.net/</uri>.</para>
+
+ <sect2>
+ <title>啟用 PF</title>
+
+ <para>PF 在 &os; 5.3 之後的系統中,就可以輕鬆使用 kernel 動態模組來載入。
+ 在 rc.conf 中加入 <literal>pf_enable="YES"</literal> 後,
+ 系統就會載入 PF 的 kernel 動態模組。這模組會在建立時也啟用 &man.pflog.4;
+ 記錄功能。</para>
+
+ <note>
+ <para>這個模組會假設 kernel 內已有 <literal>options INET</literal> 和
+ <literal>device bpf</literal>。
+ 除非編譯 kernel 時已在像是 &man.make.conf.5; 設定檔中加入
+ <literal>NOINET6</literal>(
+ &os; 6.0 以後的版本則是 <literal>NO_INET6</literal>)
+ 這樣才會避免不打開 IPv6 支援,
+ 否則 pf 模組同時也需要 <literal>options INET6</literal>,也就是 IPv6
+ 支援。</para>
+ </note>
+
+ <para>一旦載入 PF 的 kernel 模組或是靜態編譯入 kernel 內,
+ 就可以使用 <command>pfctl</command> 來啟動或關閉
+ <application>pf</application>。</para>
+
+ <para>下面這個例子示範如何啟動 <application>pf</application>:</para>
+
+ <screen>&prompt.root; <userinput>pfctl -e</userinput></screen>
+
+ <para><command>pfctl</command> 是使用 <application>pf</application>
+ 防火牆的指令。 若要了解更詳盡的 <command>pfctl</command> 運用,請查閱
+ &man.pfctl.8; 線上手冊。</para>
+ </sect2>
+
+ <sect2>
+ <title>kernel 選項</title>
+
+ <indexterm>
+ <primary>kernel 選項</primary>
+
+ <secondary>device pf</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>kernel 選項</primary>
+
+ <secondary>device pflog</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>kernel 選項</primary>
+
+ <secondary>device pfsync</secondary>
+ </indexterm>
+
+ <para>在編譯 &os; kernel 時,並不必完全加入下列的選項來啟用 PF。
+ 在這裡只是要列出給你參考的一些資訊而已。
+ 將 PF 編譯入 kernel 中,會導致無法使用 kernel 的動態載入模組。</para>
+
+ <para>設定 PF 的 kernel 選項範例在 kernel 原始碼中的
+ <filename>/usr/src/sys/conf/NOTES</filename>,轉貼內容如下:</para>
+
+ <programlisting>device pf
+device pflog
+device pfsync</programlisting>
+
+ <para><literal>device pf</literal> 是用來啟動「packet filter(封包過濾)」
+ 的防火牆支援。</para>
+
+ <para>而 <literal>device pflog</literal>,此功能要裝不裝皆可,它會啟動
+ &man.pflog.4;,以 &man.bpf.4; 格式來記錄網路流量。
+ &man.pflogd.8; daemon 則是用來紀錄這些訊息,並存在硬碟上。</para>
+ <!-- psilotum:20060311 參考 zh_CN 翻譯 -->
+
+ <para><literal>device pfsync</literal>,此功能要裝不裝皆可,它會啟動
+ &man.pfsync.4;,可以用來監控「狀態的改變」。 請注意:
+ <literal>device pfsync</literal>並不是 kernel 動態模組,要使用的話,
+ 必須要編入自訂的 kernel 中才行。</para>
+
+ <para>這些設定將會在你編譯及安裝好新 kernel 後才會生效。</para>
+ </sect2>
+
+ <sect2>
+ <title>rc.conf 其他相關的選項</title>
+
+ <para>你需要在 <filename>/etc/rc.conf</filename>
+ 中加入下列的設定,以便在系統啟動時啟用 PF:</para>
+
+ <programlisting>pf_enable="YES" # 啟用 PF (如果需要的話載入模組)
+pf_rules="/etc/pf.conf" # PF 防火牆規則設定檔
+pf_flags="" # pfctl 啟動時的附加選項
+pflog_enable="YES" # 啟動 pflogd(8)
+pflog_logfile="/var/log/pflog" # pflogd 儲存記錄檔案的地方
+pflog_flags="" # pflogd 啟動時附加的選項</programlisting>
+
+ <para>如果您的防火牆後面有個 LAN(區域網路),並要透過它來轉送封包,
+ 就必須要設定下列選項:</para>
+
+ <programlisting>gateway_enable="YES" # 啟用 LAN Gateway</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>啟用 <acronym>ALTQ</acronym></title>
+
+ <para><acronym>ALTQ</acronym> 只有在編入 &os; kernel 中才能生效。
+ 不是所有的網路卡驅動程式都支援 <acronym>ALTQ</acronym>。
+ 請看 &man.altq.4; 線上手冊來了解你使用的 &os; 版本中支援驅動程式的清單。
+ 下面所列的將會啟用 <acronym>ALTQ</acronym> 及其他附加功能:</para>
+
+ <programlisting>options ALTQ
+options ALTQ_CBQ # Class Bases Queuing (CBQ)
+options ALTQ_RED # Random Early Detection (RED)
+options ALTQ_RIO # RED In/Out
+options ALTQ_HFSC # Hierarchical Packet Scheduler (HFSC)
+options ALTQ_PRIQ # Priority Queuing (PRIQ)
+options ALTQ_NOPCC # Required for SMP build</programlisting>
+
+ <para><literal>options ALTQ</literal> 是啟用 <acronym>ALTQ</acronym> 主架構。</para>
+
+ <para><literal>options ALTQ_CBQ</literal> 會啟用「<acronym>CBQ</acronym>」
+ (Class Based Queuing)支援。
+ <acronym>CBQ</acronym> 允許你
+ divide a connection's bandwidth into different
+ classes or queues to prioritize traffic based on filter
+ rules.</para>
+
+ <para><literal>options ALTQ_RED</literal> enables Random Early
+ Detection (<acronym>RED</acronym>). <acronym>RED</acronym> is
+ used to avoid network congestion. <acronym>RED</acronym> does
+ this by measuring the length of the queue and comparing it to
+ the minimum and maximum thresholds for the queue. If the
+ queue is over the maximum all new packets will be dropped.
+ True to its name, <acronym>RED</acronym> drops packets from
+ different connections randomly.</para>
+
+ <para><literal>options ALTQ_RIO</literal> enables Random Early
+ Detection In and Out.</para>
+
+ <para><literal>options ALTQ_HFSC</literal> enables the
+ Hierarchical Fair Service Curve Packet Scheduler. For more
+ information about <acronym>HFSC</acronym> see: <uri xlink:href="http://www-2.cs.cmu.edu/~hzhang/HFSC/main.html">http://www-2.cs.cmu.edu/~hzhang/HFSC/main.html</uri>.</para>
+
+ <para><literal>options ALTQ_PRIQ</literal> enables Priority
+ Queuing (<acronym>PRIQ</acronym>). <acronym>PRIQ</acronym>
+ will always pass traffic that is in a higher queue
+ first.</para>
+
+ <para><literal>options ALTQ_NOPCC</literal> enables
+ <acronym>SMP</acronym> support for <acronym>ALTQ</acronym>.
+ This option is required on <acronym>SMP</acronym>
+ systems.</para>
+ </sect2>
+
+ <sect2>
+ <title>Creating Filtering Rules</title>
+
+ <para>The Packet Filter reads its configuration rules from the
+ &man.pf.conf.5; file and it modifies, drops or passes packets
+ according to the rules or definitions specified there. The &os;
+ installation comes with a default
+ <filename>/etc/pf.conf</filename> which contains useful examples
+ and explanations.</para>
+
+ <para>Although &os; has its own <filename>/etc/pf.conf</filename>
+ the syntax is the same as one used in OpenBSD. A great
+ resource for configuring the <application>pf</application>
+ firewall has been written by OpenBSD team and is available at
+ <uri xlink:href="http://www.openbsd.org/faq/pf/">http://www.openbsd.org/faq/pf/</uri>.</para>
+
+ <warning>
+ <para>When browsing the pf user's guide, please keep in mind that
+ different versions of &os; contain different versions of pf. The
+ <application>pf</application> firewall in &os; 5.X is at the level
+ of OpenBSD version 3.5 and in &os; 6.X is at the level of OpenBSD
+ version 3.7.</para>
+ </warning>
+
+ <para>The &a.pf; is a good place to ask questions about
+ configuring and running the <application>pf</application>
+ firewall. Do not forget to check the mailing list archives
+ before asking questions.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="firewalls-ipf">
+ <title>IPFILTER (IPF) 防火牆</title>
+
+ <indexterm>
+ <primary>防火牆</primary>
+
+ <secondary>IPFILTER</secondary>
+ </indexterm>
+
+ <note>
+ <para>此一節的內容仍在陸續補充、更新,所以本節內容可能並未完全符合現況。</para>
+ </note>
+
+ <para>IPFILTER 的作者為 Darren Reed。IPFILTER 並非得綁某特定作業系統才行:
+ 它是個跨 OS 平台的 open source 應用程式,且已被移植到
+ &os;、NetBSD、OpenBSD、&sunos;、HP/UX 以及
+ &solaris; 這些作業系統上。此外,IPFILTER 的支援、維護也相當積極,也有定期釋出的更新版。</para>
+
+ <para>IPFILTER is based on a kernel-side firewall and
+ <acronym>NAT</acronym> mechanism that can be controlled and
+ monitored by userland interface programs. The firewall rules can
+ be set or deleted with the &man.ipf.8; utility. The
+ <acronym>NAT</acronym> rules can be set or deleted with the
+ &man.ipnat.1; utility. The &man.ipfstat.8; utility can print
+ run-time statistics for the kernel parts of IPFILTER. The
+ &man.ipmon.8; program can log IPFILTER actions to the system log
+ files.</para>
+
+ <para>IPF was originally written using a rule processing logic of
+ 「the last matching rule wins」 and used only
+ stateless type of rules. Over time IPF has been enhanced to
+ include a 「quick」 option and a stateful 「keep
+ state」 option which drastically modernized the rules
+ processing logic. IPF's official documentation covers the legacy
+ rule coding parameters and the legacy rule file processing
+ logic. The modernized functions are only included as additional
+ options, completely understating their benefits in producing a
+ far superior secure firewall.</para>
+
+ <para>The instructions contained in this section are based on
+ using rules that contain the 「quick」 option and the
+ stateful 「keep state」 option. This is the basic
+ framework for coding an inclusive firewall rule set.</para>
+
+ <!-- XXX: something like this already in
+ <xref linkend="firewalls-concepts"/>
+ AND: the para below is repeated 3 times in this chapter-->
+
+ <para>An inclusive firewall only allows packets matching the rules
+ to pass through. This way you can control what services can
+ originate behind the firewall destined for the public Internet
+ and also control the services which can originate from the
+ public Internet accessing your private network. Everything else
+ is blocked and logged by default design. Inclusive firewalls are
+ much, much more secure than exclusive firewall rule sets and is
+ the only rule set type covered herein.</para>
+
+ <para>For detailed explanation of the legacy rules processing
+ method see: <uri xlink:href="http://www.obfuscation.org/ipf/ipf-howto.html#TOC_1">http://www.obfuscation.org/ipf/ipf-howto.html#TOC_1</uri>
+ and <uri xlink:href="http://coombs.anu.edu.au/~avalon/ip-filter.html">http://coombs.anu.edu.au/~avalon/ip-filter.html</uri>.</para>
+
+ <para>IPF 的 FAQ 位於 <uri xlink:href="http://www.phildev.net/ipf/index.html">http://www.phildev.net/ipf/index.html</uri>.</para>
+
+ <sect2>
+ <title>啟用 IPF</title>
+
+ <indexterm>
+ <primary>IPFILTER</primary>
+
+ <secondary>啟用</secondary>
+ </indexterm>
+
+ <para>IPF is included in the basic &os; install as a separate run
+ time loadable module. The system will dynamically load the IPF
+ kernel loadable module when the rc.conf statement
+ <literal>ipfilter_enable="YES"</literal> is used. The loadable
+ module was created with logging enabled and the
+ <literal>default pass all</literal> options. You do not need
+ to compile IPF into the &os; kernel just to change the default
+ to <literal>block all</literal>, you can do that by just coding
+ a block all rule at the end of your rule set.</para>
+ </sect2>
+
+ <sect2>
+ <title>kernel 選項</title>
+
+ <indexterm>
+ <primary>kernel options</primary>
+
+ <secondary>IPFILTER</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>kernel options</primary>
+
+ <secondary>IPFILTER_LOG</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>kernel options</primary>
+
+ <secondary>IPFILTER_DEFAULT_BLOCK</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>IPFILTER</primary>
+
+ <secondary>kernel options</secondary>
+ </indexterm>
+
+ <para>在編譯 &os; kernel 時,並不必完全加入下列的選項來啟用 IPF。
+ 在這裡只是要列出給你參考的一些資訊而已。
+ 將 IPF 編譯入 kernel 中,會導致無法使用 kernel 的動態載入模組。</para>
+
+ <para>Sample kernel config IPF option statements are in the
+ <filename>/usr/src/sys/conf/NOTES</filename> kernel source
+ (<filename>/usr/src/sys/arch/conf/LINT</filename>
+ for &os;&nbsp;4.X) and are reproduced here:</para>
+
+ <programlisting>options IPFILTER
+options IPFILTER_LOG
+options IPFILTER_DEFAULT_BLOCK</programlisting>
+
+ <para><literal>options IPFILTER</literal> enables support for the
+ 「IPFILTER」 firewall.</para>
+
+ <para><literal>options IPFILTER_LOG</literal> enables the option
+ to have IPF log traffic by writing to the
+ <filename>ipl</filename> packet logging pseudo&mdash;device
+ for every rule that has the <literal>log</literal>
+ keyword.</para>
+
+ <para><literal>options IPFILTER_DEFAULT_BLOCK</literal> changes
+ the default behavior so any packet not matching a firewall
+ <literal>pass</literal> rule gets blocked.</para>
+
+ <para>These settings will take effect only after you have built
+ and installed a kernel with them set.</para>
+ </sect2>
+
+ <sect2>
+ <title>可用的 rc.conf 選項</title>
+
+ <para>須在 <filename>/etc/rc.conf</filename> 內加入下列內容,以便在開機時就會啟用 IPF:</para>
+
+ <programlisting>ipfilter_enable="YES" # Start ipf firewall
+ipfilter_rules="/etc/ipf.rules" # IPF 防火牆規則設定檔
+ipmon_enable="YES" # 啟用 IP 監控記錄
+ipmon_flags="-Ds" # D = 使用服務程序 (daemon) 啟動
+ # s = 使用 syslog 記錄
+ # v = 記錄於 tcp window, ack, seq
+ # n = 將 IP 及 port 對應至名稱中</programlisting>
+
+ <para>If you have a LAN behind this firewall that uses the
+ reserved private IP address ranges, then you need to add the
+ following to enable <acronym>NAT</acronym>
+ functionality:</para>
+
+ <programlisting>gateway_enable="YES" # 啟用 LAN Gateway
+ipnat_enable="YES" # Start ipnat function
+ipnat_rules="/etc/ipnat.rules" # rules definition file for ipnat</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>IPF</title>
+
+ <indexterm><primary><command>ipf</command></primary></indexterm>
+
+ <para>The ipf command is used to load your rules file. Normally
+ you create a file containing your custom rules and use this
+ command to replace in mass the currently running firewall
+ internal rules:</para>
+
+ <screen>&prompt.root; <userinput>ipf -Fa -f /etc/ipf.rules</userinput></screen>
+
+ <para><option>-Fa</option> means flush all internal rules
+ tables.</para>
+
+ <para><option>-f</option> means this is the file to read for the
+ rules to load.</para>
+
+ <para>This gives you the ability to make changes to your custom
+ rules file, run the above IPF command, and thus update the
+ running firewall with a fresh copy of all the rules without
+ having to reboot the system. This method is very convenient
+ for testing new rules as the procedure can be executed as many
+ times as needed.</para>
+
+ <para>See the &man.ipf.8; manual page for details on the other
+ flags available with this command.</para>
+
+ <para>The &man.ipf.8; command expects the rules file to be a
+ standard text file. It will not accept a rules file written as
+ a script with symbolic substitution.</para>
+
+ <para>There is a way to build IPF rules that utilizes the power
+ of script symbolic substitution. For more information, see
+ <xref linkend="firewalls-ipf-rules-script"/>.</para>
+ </sect2>
+
+ <sect2>
+ <title>IPFSTAT</title>
+
+ <indexterm><primary><command>ipfstat</command></primary></indexterm>
+
+ <indexterm>
+ <primary>IPFILTER</primary>
+
+ <secondary>statistics</secondary>
+ </indexterm>
+
+ <para>The default behavior of &man.ipfstat.8; is to retrieve and
+ display the totals of the accumulated statistics gathered as a
+ result of applying the user coded rules against packets going
+ in and out of the firewall since it was last started, or since
+ the last time the accumulators were reset to zero by the
+ <command>ipf -Z</command> command.</para>
+
+ <para>See the &man.ipfstat.8; manual page for details.</para>
+
+ <para>The default &man.ipfstat.8; command output will look
+ something like this:</para>
+
+ <screen>input packets: blocked 99286 passed 1255609 nomatch 14686 counted 0
+ output packets: blocked 4200 passed 1284345 nomatch 14687 counted 0
+ input packets logged: blocked 99286 passed 0
+ output packets logged: blocked 0 passed 0
+ packets logged: input 0 output 0
+ log failures: input 3898 output 0
+ fragment state(in): kept 0 lost 0
+ fragment state(out): kept 0 lost 0
+ packet state(in): kept 169364 lost 0
+ packet state(out): kept 431395 lost 0
+ ICMP replies: 0 <acronym>TCP</acronym> RSTs sent: 0
+ Result cache hits(in): 1215208 (out): 1098963
+ IN Pullups succeeded: 2 failed: 0
+ OUT Pullups succeeded: 0 failed: 0
+ Fastroute successes: 0 failures: 0
+ <acronym>TCP</acronym> cksum fails(in): 0 (out): 0
+ Packet log flags set: (0)</screen>
+
+ <para>When supplied with either <option>-i</option> for inbound
+ or <option>-o</option> for outbound, it will retrieve and
+ display the appropriate list of filter rules currently
+ installed and in use by the kernel.</para>
+
+ <para><command>ipfstat -in</command> displays the inbound
+ internal rules table with rule number.</para>
+
+ <para><command>ipfstat -on</command> displays the outbound
+ internal rules table with the rule number.</para>
+
+ <para>The output will look something like this:</para>
+
+ <screen>@1 pass out on xl0 from any to any
+@2 block out on dc0 from any to any
+@3 pass out quick on dc0 proto tcp/udp from any to any keep state</screen>
+
+ <para><command>ipfstat -ih</command> displays the inbound
+ internal rules table, prefixing each rule with a count of how
+ many times the rule was matched.</para>
+
+ <para><command>ipfstat -oh</command> displays the outbound
+ internal rules table, prefixing each rule with a count of how
+ many times the rule was matched.</para>
+
+ <para>The output will look something like this:</para>
+
+ <screen>2451423 pass out on xl0 from any to any
+354727 block out on dc0 from any to any
+430918 pass out quick on dc0 proto tcp/udp from any to any keep state</screen>
+
+ <para>One of the most important functions of the
+ <command>ipfstat</command> command is the <option>-t</option>
+ flag which displays the state table in a way similar to the way
+ &man.top.1; shows the &os; running process table. When your
+ firewall is under attack this function gives you the ability to
+ identify, drill down to, and see the attacking packets. The
+ optional sub-flags give the ability to select the destination
+ or source IP, port, or protocol that you want to monitor in
+ real time. See the &man.ipfstat.8; manual page for
+ details.</para>
+ </sect2>
+
+ <sect2>
+ <title>IPMON</title>
+
+ <indexterm><primary><command>ipmon</command></primary></indexterm>
+
+ <indexterm>
+ <primary>IPFILTER</primary>
+
+ <secondary>logging</secondary>
+ </indexterm>
+
+ <para>In order for <command>ipmon</command> to work properly, the
+ kernel option IPFILTER_LOG must be turned on. This command has
+ two different modes that it can be used in. Native mode is the
+ default mode when you type the command on the command line
+ without the <option>-D</option> flag.</para>
+
+ <para>Daemon mode is for when you want to have a continuous
+ system log file available so that you can review logging of
+ past events. This is how &os; and IPFILTER are configured to
+ work together. &os; has a built in facility to automatically
+ rotate system logs. That is why outputting the log information
+ to syslogd is better than the default of outputting to a
+ regular file. In the default <filename>rc.conf</filename> file
+ you see the ipmon_flags statement uses the <option>-Ds</option>
+ flags:</para>
+
+ <programlisting>ipmon_flags="-Ds" # D = start as daemon
+ # s = log to syslog
+ # v = log tcp window, ack, seq
+ # n = map IP &amp; port to names</programlisting>
+
+ <para>The benefits of logging are obvious. It provides the
+ ability to review, after the fact, information such as which
+ packets had been dropped, what addresses they came from and
+ where they were going. These all give you a significant edge
+ in tracking down attackers.</para>
+
+ <para>Even with the logging facility enabled, IPF will not
+ generate any rule logging on its own. The firewall
+ administrator decides what rules in the rule set he wants to
+ log and adds the log keyword to those rules. Normally only
+ deny rules are logged.</para>
+
+ <para>It is very customary to include a default deny everything
+ rule with the log keyword included as your last rule in the
+ rule set. This way you get to see all the packets that did not
+ match any of the rules in the rule set.</para>
+ </sect2>
+
+ <sect2>
+ <title>IPMON Logging</title>
+
+ <para><application>Syslogd</application> uses its own special
+ method for segregation of log data. It uses special groupings
+ called 「facility」 and <quote>level</quote>. IPMON
+ in <option>-Ds</option> mode uses <literal>security</literal>
+ (<literal>local0</literal> in 4.X) as the 「facility」
+ name. All IPMON logged data goes to <literal>security</literal>
+ (<literal>local0</literal> in 4.X). The following levels can be
+ used to further segregate the logged data if desired:</para>
+
+ <screen>LOG_INFO - packets logged using the "log" keyword as the action rather than pass or block.
+LOG_NOTICE - packets logged which are also passed
+LOG_WARNING - packets logged which are also blocked
+LOG_ERR - packets which have been logged and which can be considered short</screen>
+
+ <!-- XXX: "can be considered short" == "with incomplete header" -->
+
+ <para>To setup IPFILTER to log all data to
+ <filename>/var/log/ipfilter.log</filename>, you will need to
+ create the file. The following command will do that:</para>
+
+ <screen>&prompt.root; <userinput>touch /var/log/ipfilter.log</userinput></screen>
+
+ <para>The syslog function is controlled by definition statements
+ in the <filename>/etc/syslog.conf</filename> file. The
+ <filename>syslog.conf</filename> file offers considerable
+ flexibility in how syslog will deal with system messages issued
+ by software applications like IPF.</para>
+
+ <para>Add the following statement to
+ <filename>/etc/syslog.conf</filename> for &os;&nbsp;5.X and
+ later:</para>
+
+ <programlisting>security.* /var/log/ipfilter.log</programlisting>
+
+ <para>Or add the following statement to
+ <filename>/etc/syslog.conf</filename> for &os;&nbsp;4.X:</para>
+
+ <programlisting>local0.* /var/log/ipfilter.log</programlisting>
+
+ <para>The <literal>security.*</literal> (<literal>local0</literal>
+ for 4.X) means to write all the logged messages to the coded
+ file location.</para>
+
+ <para>To activate the changes to <filename>/etc/syslog.conf
+ </filename> you can reboot or bump the syslog task into
+ re-reading <filename>/etc/syslog.conf</filename> by running
+ <command>/etc/rc.d/syslogd reload</command>
+ (<command>killall -HUP syslogd</command> in &os; 4.X).</para>
+
+ <para>Do not forget to change
+ <filename>/etc/newsyslog.conf</filename> to rotate the new log
+ you just created above.</para>
+ </sect2>
+
+ <sect2>
+ <title>The Format of Logged Messages</title>
+
+ <para>Messages generated by <command>ipmon</command> consist of
+ data fields separated by white space. Fields common to all
+ messages are:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>The date of packet receipt.</para>
+ </listitem>
+
+ <listitem>
+ <para>The time of packet receipt. This is in the form
+ HH:MM:SS.F, for hours, minutes, seconds, and fractions of a
+ second (which can be several digits long).</para>
+ </listitem>
+
+ <listitem>
+ <para>The name of the interface the packet was processed on,
+ e.g. <filename>dc0</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para>The group and rule number of the rule, e.g.
+ <literal>@0:17</literal>.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>These can be viewed with <command>ipfstat
+ -in</command>.</para>
+
+ <orderedlist>
+ <listitem>
+ <para>The action: p for passed, b for blocked, S for a short
+ packet, n did not match any rules, L for a log rule. The
+ order of precedence in showing flags is: S, p, b, n, L. A
+ capital P or B means that the packet has been logged due to
+ a global logging setting, not a particular rule.</para>
+ </listitem>
+
+ <listitem>
+ <para>The addresses. This is actually three fields: the
+ source address and port (separated by a comma), the -&gt;
+ symbol, and the destination address and port.
+ 209.53.17.22,80 -&gt; 198.73.220.17,1722.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>PR</literal> followed by the protocol name or
+ number, e.g. PR tcp.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>len</literal> followed by the header length
+ and total length of the packet, e.g. len 20 40.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>If the packet is a <acronym>TCP</acronym> packet, there
+ will be an additional field starting with a hyphen followed by
+ letters corresponding to any flags that were set. See the
+ &man.ipmon.8; manual page for a list of letters and their
+ flags.</para>
+
+ <para>If the packet is an ICMP packet, there will be two fields
+ at the end, the first always being 「ICMP」, and the
+ next being the ICMP message and sub-message type, separated by
+ a slash, e.g. ICMP 3/3 for a port unreachable message.</para>
+ </sect2>
+
+ <sect2 xml:id="firewalls-ipf-rules-script">
+ <title>Building the Rule Script with Symbolic
+ Substitution</title>
+
+ <para>Some experienced IPF users create a file containing the
+ rules and code them in a manner compatible with running them as
+ a script with symbolic substitution. The major benefit of
+ doing this is that you only have to change the value associated
+ with the symbolic name and when the script is run all the rules
+ containing the symbolic name will have the value substituted in
+ the rules. Being a script, you can use symbolic substitution
+ to code frequently used values and substitute them in multiple
+ rules. You will see this in the following example.</para>
+
+ <para>The script syntax used here is compatible with the sh, csh,
+ and tcsh shells.</para>
+
+ <para>Symbolic substitution fields are prefixed with a dollar
+ sign: <literal>&dollar;</literal>.</para>
+
+ <para>Symbolic fields do not have the &dollar; prefix.</para>
+
+ <para>The value to populate the symbolic field must be enclosed
+ with double quotes (<literal>"</literal>).</para>
+
+ <para>Start your rule file with something like this:</para>
+
+ <programlisting>############# IPF 規則命令稿的開始 ########################
+
+oif="dc0" # 對外網路裝置的名稱
+odns="192.0.2.11" # ISP 的 DNS 伺服器 IP 位址
+myip="192.0.2.7" # 從我的 ISP 提供的靜態 IP
+ks="keep state"
+fks="flags S keep state"
+
+# You can choose between building /etc/ipf.rules file
+# from this script or running this script "as is".
+#
+# Uncomment only one line and comment out another.
+#
+# 1) This can be used for building /etc/ipf.rules:
+#cat &gt; /etc/ipf.rules &lt;&lt; EOF
+#
+# 2) This can be used to run script "as is":
+/sbin/ipf -Fa -f - &lt;&lt; EOF
+
+# Allow out access to my ISP's Domain name server.
+pass out quick on &dollar;oif proto tcp from any to &dollar;odns port = 53 &dollar;fks
+pass out quick on &dollar;oif proto udp from any to &dollar;odns port = 53 &dollar;ks
+
+# Allow out non-secure standard www function
+pass out quick on &dollar;oif proto tcp from &dollar;myip to any port = 80 &dollar;fks
+
+# Allow out secure www function https over TLS SSL
+pass out quick on &dollar;oif proto tcp from &dollar;myip to any port = 443 &dollar;fks
+EOF
+################## End of IPF rules script ########################</programlisting>
+
+ <para>That is all there is to it. The rules are not important in
+ this example; how the symbolic substitution fields are
+ populated and used are. If the above example was in a file
+ named <filename>/etc/ipf.rules.script</filename>, you could
+ reload these rules by entering the following command:</para>
+
+ <screen>&prompt.root; <userinput>sh /etc/ipf.rules.script</userinput></screen>
+
+ <para>There is one problem with using a rules file with embedded
+ symbolics: IPF does not understand symbolic substitution, and
+ cannot read such scripts directly.</para>
+
+ <para>This script can be used in one of two ways:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Uncomment the line that begins with
+ <literal>cat</literal>, and comment out the line that
+ begins with <literal>/sbin/ipf</literal>. Place
+ <literal>ipfilter_enable="YES"</literal> into
+ <filename>/etc/rc.conf</filename> as usual, and run script
+ once after each modification to create or update
+ <filename>/etc/ipf.rules</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Disable IPFILTER in system startup scripts by adding
+ <literal>ipfilter_enable="NO"</literal> (this is default
+ value) into <filename>/etc/rc.conf</filename> file.</para>
+
+ <para>Add a script like the following to your
+ <filename>/usr/local/etc/rc.d/</filename> startup
+ directory. The script should have an obvious name like
+ <filename>ipf.loadrules.sh</filename>. The
+ <filename>.sh</filename> extension is mandatory.</para>
+
+ <programlisting>#!/bin/sh
+sh /etc/ipf.rules.script</programlisting>
+
+ <para>The permissions on this script file must be read,
+ write, execute for owner <systemitem class="username">root</systemitem>.</para>
+
+ <screen>&prompt.root; <userinput>chmod 700 /usr/local/etc/rc.d/ipf.loadrules.sh</userinput></screen>
+ </listitem>
+ </itemizedlist>
+
+ <para>從現在起,當系統開機時就會載入你所設的 IPF 規則。</para>
+ </sect2>
+
+ <sect2>
+ <title>IPF 規則</title>
+
+ <!-- XXX: looks incorrect (and duplicated 2 times in this chapter):
+ 1. Packet can be processed two times depend of firewall
+ firewall configuration, but "return trip back" is
+ another packet.
+ 2. "Each TCP/IP service ... is predefined by its protocol ..."
+ - this shold be about packet and it's parameters
+ (source/destination address and port). -->
+
+ <para>A rule set is a group of ipf rules coded to pass or block
+ packets based on the values contained in the packet. The
+ bi-directional exchange of packets between hosts comprises a
+ session conversation. The firewall rule set processes the
+ packet two times, once on its arrival from the public Internet
+ host and again as it leaves for its return trip back to the
+ public Internet host. Each TCP/IP service (i.e. telnet, www,
+ mail, etc.) is predefined by its protocol, source and
+ destination IP address, or the source and destination port
+ number. This is the basic selection criteria used to create
+ rules which will pass or block services.</para>
+
+ <indexterm>
+ <primary>IPFILTER</primary>
+
+ <secondary>rule processing order</secondary>
+ </indexterm>
+
+ <para>IPF was originally written using a rules processing logic
+ of 「the last matching rule wins」 and used only
+ stateless rules. Over time IPF has been enhanced to include a
+ 「quick」 option and a stateful 「keep
+ state」 option which drastically modernized the rule
+ processing logic.</para>
+
+ <para>The instructions contained in this section are based on
+ using rules that contain the 「quick」 option and
+ the stateful 「keep state」 option. This is the
+ basic framework for coding an inclusive firewall rule
+ set.</para>
+
+ <!-- XXX: something like this already in
+ <xref linkend="firewalls-concepts"/>
+ AND: the para below is repeated 3 times in this chapter-->
+
+ <para>An inclusive firewall only allows services matching the
+ rules through. This way you can control what services can
+ originate behind the firewall destined for the public Internet
+ and also control the services which can originate from the
+ public Internet accessing your private network. Everything
+ else is blocked and logged by default design. Inclusive
+ firewalls are much, much securer than exclusive firewall rule
+ sets and is the only rule set type covered herein.</para>
+
+ <warning>
+ <para>When working with the firewall rules, be <emphasis>very
+ careful</emphasis>. Some configurations <emphasis>will
+ lock you out</emphasis> of the server. To be on the safe
+ side, you may wish to consider performing the initial
+ firewall configuration from the local console rather than
+ doing it remotely e.g. via
+ <application>ssh</application>.</para>
+ </warning>
+ </sect2>
+
+ <sect2>
+ <title>Rule Syntax</title>
+
+ <indexterm>
+ <primary>IPFILTER</primary>
+
+ <secondary>rule syntax</secondary>
+ </indexterm>
+
+ <para>The rule syntax presented here has been simplified to only
+ address the modern stateful rule context and 「first
+ matching rule wins」 logic. For the complete legacy rule
+ syntax description see the &man.ipf.8; manual page.</para>
+
+ <para>A <literal>#</literal> character is used to mark the start
+ of a comment and may appear at the end of a rule line or on its
+ own line. Blank lines are ignored.</para>
+
+ <para>Rules contain keywords. These keywords have to be coded in
+ a specific order from left to right on the line. Keywords are
+ identified in bold type. Some keywords have sub-options which
+ may be keywords themselves and also include more sub-options.
+ Each of the headings in the below syntax has a bold section
+ header which expands on the content.</para>
+
+ <!-- This section is probably wrong. See the OpenBSD flag -->
+ <!-- What is the "OpenBSD flag"? Reference please -->
+
+ <para><replaceable>ACTION IN-OUT OPTIONS SELECTION STATEFUL PROTO
+ SRC_ADDR,DST_ADDR OBJECT PORT_NUM TCP_FLAG
+ STATEFUL</replaceable></para>
+
+ <para><replaceable>ACTION</replaceable> = block | pass</para>
+
+ <para><replaceable>IN-OUT</replaceable> = in | out</para>
+
+ <para><replaceable>OPTIONS</replaceable> = log | quick | on
+ interface-name</para>
+
+ <para><replaceable>SELECTION</replaceable> = proto value |
+ source/destination IP | port = number | flags
+ flag-value</para>
+
+ <para><replaceable>PROTO</replaceable> = tcp/udp | udp | tcp |
+ icmp</para>
+
+ <para><replaceable>SRC_ADD,DST_ADDR</replaceable> = all | from
+ object to object</para>
+
+ <para><replaceable>OBJECT</replaceable> = IP address | any</para>
+
+ <para><replaceable>PORT_NUM</replaceable> = port number</para>
+
+ <para><replaceable>TCP_FLAG</replaceable> = S</para>
+
+ <para><replaceable>STATEFUL</replaceable> = keep state</para>
+
+ <sect3>
+ <title>ACTION</title>
+
+ <para>The action indicates what to do with the packet if it
+ matches the rest of the filter rule. Each rule
+ <emphasis>must</emphasis> have a action. The following
+ actions are recognized:</para>
+
+ <para><literal>block</literal> indicates that the packet should
+ be dropped if the selection parameters match the
+ packet.</para>
+
+ <para><literal>pass</literal> indicates that the packet should
+ exit the firewall if the selection parameters match the
+ packet.</para>
+ </sect3>
+
+ <sect3>
+ <title>IN-OUT</title>
+
+ <para>A mandatory requirement is that each filter rule
+ explicitly state which side of the I/O it is to be used on.
+ The next keyword must be either in or out and one or the
+ other has to be coded or the rule will not pass syntax
+ checks.</para>
+
+ <para><literal>in</literal> means this rule is being applied
+ against an inbound packet which has just been received on the
+ interface facing the public Internet.</para>
+
+ <para><literal>out</literal> means this rule is being applied
+ against an outbound packet destined for the interface facing
+ the public Internet.</para>
+ </sect3>
+
+ <sect3>
+ <title>OPTIONS</title>
+
+ <note>
+ <para>These options must be used in the order shown
+ here.</para>
+ </note>
+
+ <para><literal>log</literal> indicates that the packet header
+ will be written to
+
+ <!-- XXX - xref here -->
+
+ the <filename>ipl</filename> log (as described in the
+ LOGGING section below) if the selection parameters match the
+ packet.</para>
+
+ <para><literal>quick</literal> indicates that if the selection
+ parameters match the packet, this rule will be the last rule
+ checked, allowing a 「short-circuit」 path to avoid processing
+ any following rules for this packet. This option is a
+ mandatory requirement for the modernized rules processing
+ logic.</para>
+
+ <para><literal>on</literal> indicates the interface name to be
+ incorporated into the selection parameters. Interface names
+ are as displayed by &man.ifconfig.8;. Using this option, the
+ rule will only match if the packet is going through that
+ interface in the specified direction (in/out). This option
+ is a mandatory requirement for the modernized rules
+ processing logic.</para>
+
+ <para>When a packet is logged, the headers of the packet are
+ written to the IPL packet logging pseudo-device.
+ Immediately following the log keyword, the following
+ qualifiers may be used (in this order):</para>
+
+ <para><literal>body</literal> indicates that the first 128
+ bytes of the packet contents will be logged after the
+ headers.</para>
+
+ <para><literal>first</literal> If the <literal>log</literal>
+ keyword is being used in conjunction with a 「keep
+ state」 option, it is recommended that this option is
+ also applied so that only the triggering packet is logged and
+ not every packet which thereafter matches the 「keep
+ state」 information.</para>
+ </sect3>
+
+ <sect3>
+ <title>SELECTION</title>
+
+ <para>The keywords described in this section are used to
+ describe attributes of the packet to be interrogated when
+ determining whether rules match or not. There is a
+ keyword subject, and it has sub-option keywords, one of
+ which has to be selected. The following general-purpose
+ attributes are provided for matching, and must be used in
+ this order:</para>
+ </sect3>
+
+ <sect3>
+ <title>PROTO</title>
+
+ <para><literal>proto</literal> is the subject keyword and must
+ be coded along with one of its corresponding keyword
+ sub-option values. The value allows a specific protocol to
+ be matched against. This option is a mandatory requirement
+ for the modernized rules processing logic.</para>
+
+ <para><literal>tcp/udp | udp | tcp | icmp</literal> or any
+ protocol names found in <filename>/etc/protocols</filename>
+ are recognized and may be used. The special protocol keyword
+ <literal>tcp/udp</literal> may be used to match either a
+ <acronym>TCP</acronym> or a UDP packet, and has been added as
+ a convenience to save duplication of otherwise identical
+ rules.</para>
+ </sect3>
+
+ <sect3>
+ <title>SRC_ADDR/DST_ADDR</title>
+
+ <para>The <literal>all</literal> keyword is essentially a
+ synonym for 「from any to any」 with no other
+ match parameters.</para>
+
+ <para><literal>from src to dst</literal>: the from and to
+ keywords are used to match against IP addresses. Rules must
+ specify BOTH source and destination parameters.
+ <literal>any</literal> is a special keyword that matches any
+ IP address. Examples of use: 「from any to any」
+ or 「from 0.0.0.0/0 to any」 or <quote>from any to
+ 0.0.0.0/0」 or 「from 0.0.0.0 to any</quote> or
+ 「from any to 0.0.0.0」.</para>
+
+ <!-- XXX: Needs rewording -->
+
+ <para>IP addresses may be specified as a dotted IP address
+ numeric form/mask-length, or as single dotted IP address
+ numeric form.</para>
+
+ <para>There is no way to match ranges of IP addresses which
+ do not express themselves easily as mask-length. See this
+ web page for help on writing mask-length: <uri xlink:href="http://jodies.de/ipcalc">http://jodies.de/ipcalc</uri>.</para>
+ </sect3>
+
+ <sect3>
+ <title>PORT</title>
+
+ <para>If a port match is included, for either or both of source
+ and destination, then it is only applied to
+ <acronym>TCP</acronym> and UDP packets. When composing port
+ comparisons, either the service name from
+ <filename>/etc/services</filename> or an integer port number
+ may be used. When the port appears as part of the from
+ object, it matches the source port number; when it appears
+ as part of the to object, it matches the destination port
+ number. The use of the port option with the
+ <literal>to</literal> object is a mandatory requirement for
+ the modernized rules processing logic. Example of use:
+ 「from any to any port = 80」</para>
+
+ <!-- XXX: Needs rewriting -->
+
+ <para>Port comparisons may be done in a number of forms, with
+ a number of comparison operators, or port ranges may be
+ specified.</para>
+
+ <para>port "=" | "!=" | "&lt;" | "&gt;" | "&lt;=" | "&gt;=" |
+ "eq" | "ne" | "lt" | "gt" | "le" | "ge".</para>
+
+ <para>To specify port ranges, port "&lt;&gt;" |
+ "&gt;&lt;"</para>
+
+ <warning>
+ <para>Following the source and destination matching
+ parameters, the following two parameters are mandatory
+ requirements for the modernized rules processing
+ logic.</para>
+ </warning>
+ </sect3>
+
+ <sect3>
+ <title><acronym>TCP</acronym>_FLAG</title>
+
+ <para>Flags are only effective for <acronym>TCP</acronym>
+ filtering. The letters represents one of the possible flags
+ that can be interrogated in the <acronym>TCP</acronym> packet
+ header.</para>
+
+ <para>The modernized rules processing logic uses the
+ <literal>flags S</literal> parameter to identify the tcp
+ session start request.</para>
+ </sect3>
+
+ <sect3>
+ <title>STATEFUL</title>
+
+ <para><literal>keep state</literal> indicates that on a pass
+ rule, any packets that match the rules selection parameters
+ should activate the stateful filtering facility.</para>
+
+ <note>
+ <para>This option is a mandatory requirement for the
+ modernized rules processing logic.</para>
+ </note>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Stateful Filtering</title>
+
+ <indexterm>
+ <primary>IPFILTER</primary>
+
+ <secondary>stateful filtering</secondary>
+ </indexterm>
+
+ <!-- XXX: duplicated -->
+
+ <para>Stateful filtering treats traffic as a bi-directional
+ exchange of packets comprising a session conversation. When
+ activated, keep-state dynamically generates internal rules for
+ each anticipated packet being exchanged during the
+ bi-directional session conversation. It has the interrogation
+ abilities to determine if the session conversation between the
+ originating sender and the destination are following the valid
+ procedure of bi-directional packet exchange. Any packets that
+ do not properly fit the session conversation template are
+ automatically rejected as impostors.</para>
+
+ <para>Keep state will also allow ICMP packets related to a
+ <acronym>TCP</acronym> or UDP session through. So if you get
+ ICMP type 3 code 4 in response to some web surfing allowed out
+ by a keep state rule, they will be automatically allowed in.
+ Any packet that IPF can be certain is part of an active
+ session, even if it is a different protocol, will be let
+ in.</para>
+
+ <para>What happens is:</para>
+
+ <para>Packets destined to go out the interface connected to the
+ public Internet are first checked against the dynamic state
+ table, if the packet matches the next expected packet
+ comprising in a active session conversation, then it exits the
+ firewall and the state of the session conversation flow is
+ updated in the dynamic state table, the remaining packets get
+ checked against the outbound rule set.</para>
+
+ <para>Packets coming in to the interface connected to the public
+ Internet are first checked against the dynamic state table, if
+ the packet matches the next expected packet comprising a
+ active session conversation, then it exits the firewall and
+ the state of the session conversation flow is updated in the
+ dynamic state table, the remaining packets get checked against
+ the inbound rule set.</para>
+
+ <para>When the conversation completes it is removed from the
+ dynamic state table.</para>
+
+ <para>Stateful filtering allows you to focus on blocking/passing
+ new sessions. If the new session is passed, all its subsequent
+ packets will be allowed through automatically and any impostors
+ automatically rejected. If a new session is blocked, none of
+ its subsequent packets will be allowed through. Stateful
+ filtering has technically advanced interrogation abilities
+ capable of defending against the flood of different attack
+ methods currently employed by attackers.</para>
+ </sect2>
+
+ <sect2>
+ <!-- XXX: This section needs a rewrite -->
+
+ <title>Inclusive Rule Set Example</title>
+
+ <para>The following rule set is an example of how to code a very
+ secure inclusive type of firewall. An inclusive firewall only
+ allows services matching pass rules through and blocks all
+ other by default. All firewalls have at the minimum two
+ interfaces which have to have rules to allow the firewall to
+ function.</para>
+
+ <para>All &unix; flavored systems including &os; are designed to
+ use interface <filename>lo0</filename> and IP address
+ <systemitem class="ipaddress">127.0.0.1</systemitem> for internal
+ communication within the operating system. The firewall rules
+ must contain rules to allow free unmolested movement of these
+ special internally used packets.</para>
+
+ <para>The interface which faces the public Internet is the one
+ where you place your rules to authorize and control access out
+ to the public Internet and access requests arriving from the
+ public Internet. This can be your user PPP
+ <filename>tun0</filename> interface or your NIC that is
+ connected to your DSL or cable modem.</para>
+
+ <para>In cases where one or more NICs are cabled to private LANs
+ behind the firewall, those interfaces must have a rule coded to
+ allow free unmolested movement of packets originating from
+ those LAN interfaces.</para>
+
+ <para>The rules should be first organized into three major
+ sections: all the free unmolested interfaces, the public
+ interface outbound, and the public interface inbound.</para>
+
+ <para>The rules in each of the public interface sections should
+ have the most frequently matched rules placed before less
+ commonly matched rules, with the last rule in the section
+ blocking and logging all packets on that interface and
+ direction.</para>
+
+ <para>The Outbound section in the following rule set only
+ contains 'pass' rules which contain selection values that
+ uniquely identify the service that is authorized for public
+ Internet access. All the rules have the 'quick', 'on',
+ 'proto', 'port', and 'keep state' option coded. The 'proto
+ tcp' rules have the 'flag' option included to identify the
+ session start request as the triggering packet to activate the
+ stateful facility.</para>
+
+ <para>The Inbound section has all the blocking of undesirable
+ packets first, for two different reasons. The first is that
+ these things being blocked may be part of an otherwise valid
+ packet which may be allowed in by the later authorized service
+ rules. The second reason is that by having a rule that
+ explicitly blocks selected packets that I receive on an
+ infrequent basis and that I do not want to see in the log, they
+ will not be caught by the last rule in the section which blocks
+ and logs all packets which have fallen through the rules. The
+ last rule in the section which blocks and logs all packets is
+ how you create the legal evidence needed to prosecute the
+ people who are attacking your system.</para>
+
+ <para>Another thing you should take note of, is there is no
+ response returned for any of the undesirable stuff, their
+ packets just get dropped and vanish. This way the attacker
+ has no knowledge if his packets have reached your system. The
+ less the attackers can learn about your system, the more
+ time they must invest before actually doing something bad.
+ The inbound 'nmap OS fingerprint' attempts rule I log
+
+ <!-- XXX: what? -->
+
+ the first occurrence because this is something a attacker
+ would do.</para>
+
+ <para>Any time you see log messages on a rule with 'log first'.
+ You should do an <command>ipfstat -hio</command> command to see
+ the number of times the rule has been matched so you know if
+ you are being flooded, i.e. under attack.</para>
+
+ <para>When you log packets with port numbers you do not
+ recognize, look it up in <filename>/etc/services</filename> or
+ go to <uri xlink:href="http://www.securitystats.com/tools/portsearch.php">http://www.securitystats.com/tools/portsearch.php</uri>
+ and do a port number lookup to find what the purpose of that
+ port number is.</para>
+
+ <para>Check out this link for port numbers used by Trojans <uri xlink:href="http://www.simovits.com/trojans/trojans.html">http://www.simovits.com/trojans/trojans.html</uri>.</para>
+
+ <para>The following rule set is a complete very secure
+ 'inclusive' type of firewall rule set that I have used on my
+ system. You can not go wrong using this rule set for your own.
+ Just comment out any pass rules for services that you do not
+ want to authorize.</para>
+
+ <para>If you see messages in your log that you want to stop
+ seeing just add a block rule in the inbound section.</para>
+
+ <para>You have to change the <filename>dc0</filename>
+ interface name in every rule to the interface name of the Nic
+ card that connects your system to the public Internet. For
+ user PPP it would be <filename>tun0</filename>.</para>
+
+ <para>Add the following statements to
+ <filename>/etc/ipf.rules</filename>:</para>
+
+ <programlisting>#################################################################
+# No restrictions on Inside LAN Interface for private network
+# Not needed unless you have LAN
+#################################################################
+
+#pass out quick on xl0 all
+#pass in quick on xl0 all
+
+#################################################################
+# No restrictions on Loopback Interface
+#################################################################
+pass in quick on lo0 all
+pass out quick on lo0 all
+
+#################################################################
+# Interface facing Public Internet (Outbound Section)
+# Interrogate session start requests originating from behind the
+# firewall on the private network
+# or from this gateway server destine for the public Internet.
+#################################################################
+
+# Allow out access to my ISP's Domain name server.
+# xxx must be the IP address of your ISP's DNS.
+# Dup these lines if your ISP has more than one DNS server
+# Get the IP addresses from /etc/resolv.conf file
+pass out quick on dc0 proto tcp from any to xxx port = 53 flags S keep state
+pass out quick on dc0 proto udp from any to xxx port = 53 keep state
+
+# Allow out access to my ISP's DHCP server for cable or DSL networks.
+# This rule is not needed for 'user ppp' type connection to the
+# public Internet, so you can delete this whole group.
+# Use the following rule and check log for IP address.
+# Then put IP address in commented out rule &amp; delete first rule
+pass out log quick on dc0 proto udp from any to any port = 67 keep state
+#pass out quick on dc0 proto udp from any to z.z.z.z port = 67 keep state
+
+
+# Allow out non-secure standard www function
+pass out quick on dc0 proto tcp from any to any port = 80 flags S keep state
+
+# Allow out secure www function https over TLS SSL
+pass out quick on dc0 proto tcp from any to any port = 443 flags S keep state
+
+# Allow out send &amp; get email function
+pass out quick on dc0 proto tcp from any to any port = 110 flags S keep state
+pass out quick on dc0 proto tcp from any to any port = 25 flags S keep state
+
+# Allow out Time
+pass out quick on dc0 proto tcp from any to any port = 37 flags S keep state
+
+# Allow out nntp news
+pass out quick on dc0 proto tcp from any to any port = 119 flags S keep state
+
+# Allow out gateway &amp; LAN users non-secure FTP ( both passive &amp; active modes)
+# This function uses the IP<acronym>NAT</acronym> built in FTP proxy function coded in
+# the nat rules file to make this single rule function correctly.
+# If you want to use the pkg_add command to install application packages
+# on your gateway system you need this rule.
+pass out quick on dc0 proto tcp from any to any port = 21 flags S keep state
+
+# Allow out secure FTP, Telnet, and SCP
+# This function is using SSH (secure shell)
+pass out quick on dc0 proto tcp from any to any port = 22 flags S keep state
+
+# Allow out non-secure Telnet
+pass out quick on dc0 proto tcp from any to any port = 23 flags S keep state
+
+# Allow out FBSD CVSUP function
+pass out quick on dc0 proto tcp from any to any port = 5999 flags S keep state
+
+# Allow out ping to public Internet
+pass out quick on dc0 proto icmp from any to any icmp-type 8 keep state
+
+# Allow out whois for LAN PC to public Internet
+pass out quick on dc0 proto tcp from any to any port = 43 flags S keep state
+
+# Block and log only the first occurrence of everything
+# else that's trying to get out.
+# This rule enforces the block all by default logic.
+block out log first quick on dc0 all
+
+#################################################################
+# Interface facing Public Internet (Inbound Section)
+# Interrogate packets originating from the public Internet
+# destine for this gateway server or the private network.
+#################################################################
+
+# Block all inbound traffic from non-routable or reserved address spaces
+block in quick on dc0 from 192.168.0.0/16 to any #RFC 1918 private IP
+block in quick on dc0 from 172.16.0.0/12 to any #RFC 1918 private IP
+block in quick on dc0 from 10.0.0.0/8 to any #RFC 1918 private IP
+block in quick on dc0 from 127.0.0.0/8 to any #loopback
+block in quick on dc0 from 0.0.0.0/8 to any #loopback
+block in quick on dc0 from 169.254.0.0/16 to any #DHCP auto-config
+block in quick on dc0 from 192.0.2.0/24 to any #reserved for docs
+block in quick on dc0 from 204.152.64.0/23 to any #Sun cluster interconnect
+block in quick on dc0 from 224.0.0.0/3 to any #Class D &amp; E multicast
+
+##### Block a bunch of different nasty things. ############
+# That I do not want to see in the log
+
+# Block frags
+block in quick on dc0 all with frags
+
+# Block short tcp packets
+block in quick on dc0 proto tcp all with short
+
+# block source routed packets
+block in quick on dc0 all with opt lsrr
+block in quick on dc0 all with opt ssrr
+
+# Block nmap OS fingerprint attempts
+# Log first occurrence of these so I can get their IP address
+block in log first quick on dc0 proto tcp from any to any flags FUP
+
+# Block anything with special options
+block in quick on dc0 all with ipopts
+
+# Block public pings
+block in quick on dc0 proto icmp all icmp-type 8
+
+# Block ident
+block in quick on dc0 proto tcp from any to any port = 113
+
+# Block all Netbios service. 137=name, 138=datagram, 139=session
+# Netbios is MS/Windows sharing services.
+# Block MS/Windows hosts2 name server requests 81
+block in log first quick on dc0 proto tcp/udp from any to any port = 137
+block in log first quick on dc0 proto tcp/udp from any to any port = 138
+block in log first quick on dc0 proto tcp/udp from any to any port = 139
+block in log first quick on dc0 proto tcp/udp from any to any port = 81
+
+# Allow traffic in from ISP's DHCP server. This rule must contain
+# the IP address of your ISP's DHCP server as it's the only
+# authorized source to send this packet type. Only necessary for
+# cable or DSL configurations. This rule is not needed for
+# 'user ppp' type connection to the public Internet.
+# This is the same IP address you captured and
+# used in the outbound section.
+pass in quick on dc0 proto udp from z.z.z.z to any port = 68 keep state
+
+# Allow in standard www function because I have apache server
+pass in quick on dc0 proto tcp from any to any port = 80 flags S keep state
+
+# Allow in non-secure Telnet session from public Internet
+# labeled non-secure because ID/PW passed over public Internet as clear text.
+# Delete this sample group if you do not have telnet server enabled.
+#pass in quick on dc0 proto tcp from any to any port = 23 flags S keep state
+
+# Allow in secure FTP, Telnet, and SCP from public Internet
+# This function is using SSH (secure shell)
+pass in quick on dc0 proto tcp from any to any port = 22 flags S keep state
+
+# Block and log only first occurrence of all remaining traffic
+# coming into the firewall. The logging of only the first
+# occurrence stops a .denial of service. attack targeted
+# at filling up your log file space.
+# This rule enforces the block all by default logic.
+block in log first quick on dc0 all
+################### End of rules file #####################################</programlisting>
+ </sect2>
+
+ <sect2>
+ <title><acronym>NAT</acronym></title>
+
+ <indexterm><primary>NAT</primary></indexterm>
+
+ <indexterm>
+ <primary>IP masquerading</primary>
+
+ <see>NAT</see>
+ </indexterm>
+
+ <indexterm>
+ <primary>network address translation</primary>
+
+ <see>NAT</see>
+ </indexterm>
+
+ <para><acronym>NAT</acronym> stands for Network Address
+ Translation. To those familiar with &linux;, this concept is
+ called IP Masquerading; <acronym>NAT</acronym> and IP
+ Masquerading are the same thing. One of the many things the
+ IPF <acronym>NAT</acronym> function enables is the ability to
+ have a private Local Area Network (LAN) behind the firewall
+ sharing a single ISP assigned IP address on the public
+ Internet.</para>
+
+ <para>You may ask why would someone want to do this. ISPs
+ normally assign a dynamic IP address to their non-commercial
+ users. Dynamic means that the IP address can be different each
+ time you dial in and log on to your ISP, or for cable and DSL
+ modem users when you power off and then power on your modems
+ you can get assigned a different IP address. This IP address
+ is how you are known to the public Internet.</para>
+
+ <para>Now lets say you have five PCs at home and each one needs
+ Internet access. You would have to pay your ISP for an
+ individual Internet account for each PC and have five phone
+ lines.</para>
+
+ <para>With <acronym>NAT</acronym> you only need a single account
+ with your ISP, then cable your other four PCs to a switch and
+ the switch to the NIC in your &os; system which is going to
+ service your LAN as a gateway. <acronym>NAT</acronym> will
+ automatically translate the private LAN IP address for each
+ separate PC on the LAN to the single public IP address as it
+ exits the firewall bound for the public Internet. It also does
+ the reverse translation for returning packets.</para>
+
+ <para><acronym>NAT</acronym> is most often accomplished without
+ the approval, or knowledge, of your ISP and in most cases is
+ grounds for your ISP terminating your account if found out.
+ Commercial users pay a lot more for their Internet connection
+ and usually get assigned a block of static IP address which
+ never change. The ISP also expects and consents to their
+ Commercial customers using <acronym>NAT</acronym> for their
+ internal private LANs.</para>
+
+ <para>There is a special range of IP addresses reserved for
+ <acronym>NAT</acronym>ed private LAN IP address. According to
+ RFC 1918, you can use the following IP ranges for private nets
+ which will never be routed directly to the public
+ Internet:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <colspec colwidth="1*"/>
+
+ <colspec colwidth="1*"/>
+
+ <colspec colwidth="1*"/>
+
+ <tbody>
+ <row>
+ <entry>Start IP <systemitem class="ipaddress">10.0.0.0</systemitem></entry>
+
+ <entry>-</entry>
+
+ <entry>Ending IP <systemitem class="ipaddress">10.255.255.255</systemitem></entry>
+ </row>
+
+ <row>
+ <entry>Start IP <systemitem class="ipaddress">172.16.0.0</systemitem></entry>
+
+ <entry>-</entry>
+
+ <entry>Ending IP <systemitem class="ipaddress">172.31.255.255</systemitem></entry>
+ </row>
+
+ <row>
+ <entry>Start IP <systemitem class="ipaddress">192.168.0.0</systemitem></entry>
+
+ <entry>-</entry>
+
+ <entry>Ending IP <systemitem class="ipaddress">192.168.255.255</systemitem></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>IP<acronym>NAT</acronym></title>
+
+ <indexterm>
+ <primary>NAT</primary>
+
+ <secondary>and IPFILTER</secondary>
+ </indexterm>
+
+ <indexterm><primary><command>ipnat</command></primary></indexterm>
+
+ <para><acronym>NAT</acronym> rules are loaded by using the
+ <command>ipnat</command> command. Typically the
+ <acronym>NAT</acronym> rules are stored in
+ <filename>/etc/ipnat.rules</filename>. See &man.ipnat.1; for
+ details.</para>
+
+ <para>When changing the <acronym>NAT</acronym> rules after
+ <acronym>NAT</acronym> has been started, make your changes to
+ the file containing the NAT rules, then run ipnat command with
+ the <option>-CF</option> flags to delete the internal in use
+ <acronym>NAT</acronym> rules and flush the contents of the
+ translation table of all active entries.</para>
+
+ <para>To reload the <acronym>NAT</acronym> rules issue a command
+ like this:</para>
+
+ <screen>&prompt.root; <userinput>ipnat -CF -f /etc/ipnat.rules</userinput></screen>
+
+ <para>To display some statistics about your
+ <acronym>NAT</acronym>, use this command:</para>
+
+ <screen>&prompt.root; <userinput>ipnat -s</userinput></screen>
+
+ <para>To list the <acronym>NAT</acronym> table's current
+ mappings, use this command:</para>
+
+ <screen>&prompt.root; <userinput>ipnat -l</userinput></screen>
+
+ <para>To turn verbose mode on, and display information relating
+ to rule processing and active rules/table entries:</para>
+
+ <screen>&prompt.root; <userinput>ipnat -v</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>IP<acronym>NAT</acronym> Rules</title>
+
+ <para><acronym>NAT</acronym> rules are very flexible and can
+ accomplish many different things to fit the needs of commercial
+ and home users.</para>
+
+ <para>The rule syntax presented here has been simplified to what
+ is most commonly used in a non-commercial environment. For a
+ complete rule syntax description see the &man.ipnat.5; manual
+ page.</para>
+
+ <para>The syntax for a <acronym>NAT</acronym> rule looks
+ something like this:</para>
+
+ <programlisting>map <replaceable>IF</replaceable> <replaceable>LAN_IP_RANGE</replaceable> -&gt; <replaceable>PUBLIC_ADDRESS</replaceable></programlisting>
+
+ <para>The keyword <literal>map</literal> starts the rule.</para>
+
+ <para>Replace <replaceable>IF</replaceable> with the external
+ interface.</para>
+
+ <para>The <replaceable>LAN_IP_RANGE</replaceable> is what your
+ internal clients use for IP Addressing, usually this is
+ something like <systemitem class="ipaddress">192.168.1.0/24</systemitem>.</para>
+
+ <para>The <replaceable>PUBLIC_ADDRESS</replaceable> can either
+ be the external IP address or the special keyword
+ <literal>0/32</literal>, which means to use the IP address
+ assigned to <replaceable>IF</replaceable>.</para>
+ </sect2>
+
+ <sect2>
+ <title>How <acronym>NAT</acronym> works</title>
+
+ <para>A packet arrives at the firewall from the LAN with a public
+ destination. It passes through the outbound filter rules,
+ <acronym>NAT</acronym> gets his turn at the packet and applies
+ its rules top down, first matching rule wins.
+ <acronym>NAT</acronym> tests each of its rules against the
+ packets interface name and source IP address. When a packets
+ interface name matches a <acronym>NAT</acronym> rule then the
+ [source IP address, i.e. private LAN IP address] of the packet
+ is checked to see if it falls within the IP address range
+ specified to the left of the arrow symbol on the
+ <acronym>NAT</acronym> rule. On a match the packet has its
+ source IP address rewritten with the public IP address
+ obtained by the <literal>0/32</literal> keyword.
+ <acronym>NAT</acronym> posts a entry in its internal
+ <acronym>NAT</acronym> table so when the packet returns from
+ the public Internet it can be mapped back to its original
+ private IP address and then passed to the filter rules for
+ processing.</para>
+ </sect2>
+
+ <sect2>
+ <title>Enabling IP<acronym>NAT</acronym></title>
+
+ <para>To enable IP<acronym>NAT</acronym> add these statements to
+ <filename>/etc/rc.conf</filename>.</para>
+
+ <para>To enable your machine to route traffic between
+ interfaces:</para>
+
+ <programlisting>gateway_enable="YES"</programlisting>
+
+ <para>To start IP<acronym>NAT</acronym> automatically each
+ time:</para>
+
+ <programlisting>ipnat_enable="YES"</programlisting>
+
+ <para>To specify where to load the IP<acronym>NAT</acronym> rules
+ from:</para>
+
+ <programlisting>ipnat_rules="/etc/ipnat.rules"</programlisting>
+ </sect2>
+
+ <sect2>
+ <title><acronym>NAT</acronym> for a very large LAN</title>
+
+ <para>For networks that have large numbers of PC's on the LAN or
+ networks with more than a single LAN, the process of funneling
+ all those private IP addresses into a single public IP address
+ becomes a resource problem that may cause problems with the
+ same port numbers being used many times across many
+ <acronym>NAT</acronym>ed LAN PC's, causing collisions. There
+ are two ways to relieve this resource problem.</para>
+
+ <sect3>
+ <title>Assigning Ports to Use</title>
+
+ <!-- What does it mean ? Is there something missing ?-->
+ <!-- XXXBLAH <- Apparently you can't start a sect
+ with a <programlisting> tag ?-->
+
+ <para>A normal NAT rule would look like:</para>
+
+ <programlisting>map dc0 192.168.1.0/24 -&gt; 0/32</programlisting>
+
+ <para>In the above rule the packet's source port is unchanged
+ as the packet passes through IP<acronym>NAT</acronym>. By
+ adding the portmap keyword you can tell
+ IP<acronym>NAT</acronym> to only use source ports in a range.
+ For example the following rule will tell
+ IP<acronym>NAT</acronym> to modify the source port to be
+ within that range:</para>
+
+ <programlisting>map dc0 192.168.1.0/24 -&gt; 0/32 portmap tcp/udp 20000:60000</programlisting>
+
+ <para>Additionally we can make things even easier by using the
+ <literal>auto</literal> keyword to tell
+ IP<acronym>NAT</acronym> to determine by itself which ports
+ are available to use:</para>
+
+ <programlisting>map dc0 192.168.1.0/24 -&gt; 0/32 portmap tcp/udp auto</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Using a pool of public addresses</title>
+
+ <para>In very large LANs there comes a point where there are
+ just too many LAN addresses to fit into a single public
+ address. By changing the following rule:</para>
+
+ <programlisting>map dc0 192.168.1.0/24 -&gt; 204.134.75.1</programlisting>
+
+ <para>Currently this rule maps all connections through <systemitem class="ipaddress">204.134.75.1</systemitem>. This can be changed
+ to specify a range:</para>
+
+ <programlisting>map dc0 192.168.1.0/24 -&gt; 204.134.75.1-10</programlisting>
+
+ <para>Or a subnet using CIDR notation such as:</para>
+
+ <programlisting>map dc0 192.168.1.0/24 -&gt; 204.134.75.0/24</programlisting>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Port Redirection</title>
+
+ <para>A very common practice is to have a web server, email
+ server, database server and DNS server each segregated to a
+ different PC on the LAN. In this case the traffic from these
+ servers still have to be <acronym>NAT</acronym>ed, but there
+ has to be some way to direct the inbound traffic to the
+ correct LAN PCs. IP<acronym>NAT</acronym> has the redirection
+ facilities of <acronym>NAT</acronym> to solve this problem.
+ Lets say you have your web server on LAN address <systemitem class="ipaddress">10.0.10.25</systemitem> and your single public IP
+ address is <systemitem class="ipaddress">20.20.20.5</systemitem> you would
+ code the rule like this:</para>
+
+ <programlisting>rdr dc0 20.20.20.5/32 port 80 -&gt; 10.0.10.25 port 80</programlisting>
+
+ <para>or:</para>
+
+ <programlisting>rdr dc0 0/32 port 80 -&gt; 10.0.10.25 port 80</programlisting>
+
+ <para>or for a LAN DNS Server on LAN address of <systemitem class="ipaddress">10.0.10.33</systemitem> that needs to receive
+ public DNS requests:</para>
+
+ <programlisting>rdr dc0 20.20.20.5/32 port 53 -&gt; 10.0.10.33 port 53 udp</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>FTP and <acronym>NAT</acronym></title>
+
+ <para>FTP is a dinosaur left over from the time before the
+ Internet as it is known today, when research universities were
+ leased lined together and FTP was used to share files among
+ research Scientists. This was a time when data security was
+ not a consideration. Over the years the FTP protocol became
+ buried into the backbone of the emerging Internet and its
+ username and password being sent in clear text was never
+ changed to address new security concerns. FTP has two flavors,
+ it can run in active mode or passive mode. The difference is
+ in how the data channel is acquired. Passive mode is more
+ secure as the data channel is acquired be the ordinal ftp
+ session requester. For a real good explanation of FTP and the
+ different modes see <uri xlink:href="http://www.slacksite.com/other/ftp.html">http://www.slacksite.com/other/ftp.html</uri>.</para>
+
+ <sect3>
+ <title>IP<acronym>NAT</acronym> Rules</title>
+
+ <para>IP<acronym>NAT</acronym> has a special built in FTP proxy
+ option which can be specified on the <acronym>NAT</acronym>
+ map rule. It can monitor all outbound packet traffic for FTP
+ active or passive start session requests and dynamically
+ create temporary filter rules containing only the port number
+ really in use for the data channel. This eliminates the
+ security risk FTP normally exposes the firewall to from
+ having large ranges of high order port numbers open.</para>
+
+ <para>This rule will handle all the traffic for the internal
+ LAN:</para>
+
+ <programlisting>map dc0 10.0.10.0/29 -&gt; 0/32 proxy port 21 ftp/tcp</programlisting>
+
+ <para>This rule handles the FTP traffic from the
+ gateway:</para>
+
+ <programlisting>map dc0 0.0.0.0/0 -&gt; 0/32 proxy port 21 ftp/tcp</programlisting>
+
+ <para>This rule handles all non-FTP traffic from the internal
+ LAN:</para>
+
+ <programlisting>map dc0 10.0.10.0/29 -&gt; 0/32</programlisting>
+
+ <para>The FTP map rule goes before our regular map rule. All
+ packets are tested against the first rule from the top.
+ Matches on interface name, then private LAN source IP
+ address, and then is it a FTP packet. If all that matches
+ then the special FTP proxy creates temp filter rules to let
+ the FTP session packets pass in and out, in addition to also
+ <acronym>NAT</acronym>ing the FTP packets. All LAN packets
+ that are not FTP do not match the first rule and fall
+ through to the third rule and are tested, matching on
+ interface and source IP, then are
+ <acronym>NAT</acronym>ed.</para>
+ </sect3>
+
+ <sect3>
+ <title>IP<acronym>NAT</acronym> FTP Filter Rules</title>
+
+ <para>Only one filter rule is needed for FTP if the
+ <acronym>NAT</acronym> FTP proxy is used.</para>
+
+ <para>Without the FTP Proxy you will need the following three
+ rules:</para>
+
+ <programlisting># Allow out LAN PC client FTP to public Internet
+# Active and passive modes
+pass out quick on rl0 proto tcp from any to any port = 21 flags S keep state
+
+# Allow out passive mode data channel high order port numbers
+pass out quick on rl0 proto tcp from any to any port &gt; 1024 flags S keep state
+
+# Active mode let data channel in from FTP server
+pass in quick on rl0 proto tcp from any to any port = 20 flags S keep state</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>FTP <acronym>NAT</acronym> Proxy Bug</title>
+
+ <para>As of &os; 4.9 which includes IPFILTER version 3.4.31
+ the FTP proxy works as documented during the FTP session
+ until the session is told to close. When the close happens
+ packets returning from the remote FTP server are blocked and
+ logged coming in on port 21. The <acronym>NAT</acronym>
+ FTP/proxy appears to remove its temp rules prematurely,
+ before receiving the response from the remote FTP server
+ acknowledging the close. A problem report was posted to the
+ IPF mailing list.</para>
+
+ <para>The solution is to add a filter rule to get rid of these
+ unwanted log messages or do nothing and ignore FTP inbound
+ error messages in your log. Most people do not use outbound
+ FTP too often.</para>
+
+ <programlisting>block in quick on rl0 proto tcp from any to any port = 21</programlisting>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="firewalls-ipfw">
+ <title>IPFW</title>
+
+ <indexterm>
+ <primary>firewall</primary>
+
+ <secondary>IPFW</secondary>
+ </indexterm>
+
+ <note>
+ <para>此一節的內容仍在陸續補充、更新,所以本節內容可能並未完全符合現況。.</para>
+ </note>
+
+ <para>The IPFIREWALL (IPFW) is a &os; sponsored firewall software
+ application authored and maintained by &os; volunteer staff
+ members. It uses the legacy stateless rules and a legacy rule
+ coding technique to achieve what is referred to as Simple
+ Stateful logic.</para>
+
+ <para>The IPFW sample rule set (found in
+ <filename>/etc/rc.firewall</filename>) in the standard &os;
+ install is rather simple and it is not expected that it used
+ directly without modifications. The example does not use
+ stateful filtering, which is beneficial in most setups, so it
+ will not be used as base for this section.</para>
+
+ <para>The IPFW stateless rule syntax is empowered with technically
+ sophisticated selection capabilities which far surpasses the
+ knowledge level of the customary firewall installer. IPFW is
+ targeted at the professional user or the advanced technical
+ computer hobbyist who have advanced packet selection
+ requirements. A high degree of detailed knowledge into how
+ different protocols use and create their unique packet header
+ information is necessary before the power of the IPFW rules can
+ be unleashed. Providing that level of explanation is out of the
+ scope of this section of the handbook.</para>
+
+ <para>IPFW is composed of seven components, the primary component
+ is the kernel firewall filter rule processor and its integrated
+ packet accounting facility, the logging facility, the 'divert'
+ rule which triggers the <acronym>NAT</acronym> facility, and the
+ advanced special purpose facilities, the dummynet traffic shaper
+ facilities, the 'fwd rule' forward facility, the bridge
+ facility, and the ipstealth facility.</para>
+
+ <sect2 xml:id="firewalls-ipfw-enable">
+ <title>Enabling IPFW</title>
+
+ <indexterm>
+ <primary>IPFW</primary>
+
+ <secondary>enabling</secondary>
+ </indexterm>
+
+ <para>IPFW is included in the basic &os; install as a separate
+ run time loadable module. The system will dynamically load the
+ kernel module when the <filename>rc.conf</filename> statement
+ <literal>firewall_enable="YES"</literal> is used. You do not
+ need to compile IPFW into the &os; kernel unless you want
+ <acronym>NAT</acronym> function enabled.</para>
+
+ <para>After rebooting your system with
+ <literal>firewall_enable="YES"</literal> in
+ <filename>rc.conf</filename> the following white highlighted
+ message is displayed on the screen as part of the boot
+ process:</para>
+
+ <screen>ipfw2 initialized, divert disabled, rule-based forwarding disabled, default to deny, logging disabled</screen>
+
+ <para>The loadable module does have logging ability
+ compiled in. To enable logging and set the verbose logging
+ limit, there is a knob you can set in
+ <filename>/etc/sysctl.conf</filename> by adding these
+ statements, logging will be enabled on future reboots:</para>
+
+ <programlisting>net.inet.ip.fw.verbose=1
+net.inet.ip.fw.verbose_limit=5</programlisting>
+ </sect2>
+
+ <sect2 xml:id="firewalls-ipfw-kernel">
+ <title>Kernel Options</title>
+
+ <indexterm>
+ <primary>kernel options</primary>
+
+ <secondary>IPFIREWALL</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>kernel options</primary>
+
+ <secondary>IPFIREWALL_VERBOSE</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>kernel options</primary>
+
+ <secondary>IPFIREWALL_VERBOSE_LIMIT</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>IPFW</primary>
+
+ <secondary>kernel options</secondary>
+ </indexterm>
+
+ <para>It is not a mandatory requirement that you enable IPFW by
+ compiling the following options into the &os; kernel unless
+ you need <acronym>NAT</acronym> function. It is presented here
+ as background information.</para>
+
+ <programlisting>options IPFIREWALL</programlisting>
+
+ <para>This option enables IPFW as part of the kernel</para>
+
+ <programlisting>options IPFIREWALL_VERBOSE</programlisting>
+
+ <para>Enables logging of packets that pass through IPFW and have
+ the 'log' keyword specified in the rule set.</para>
+
+ <programlisting>options IPFIREWALL_VERBOSE_LIMIT=5</programlisting>
+
+ <para>Limits the number of packets logged through &man.syslogd.8;
+ on a per entry basis. You may wish to use this option in
+ hostile environments which you want to log firewall activity.
+ This will close a possible denial of service attack via syslog
+ flooding.</para>
+
+ <indexterm>
+ <primary>kernel options</primary>
+
+ <secondary>IPFIREWALL_DEFAULT_TO_ACCEPT</secondary>
+ </indexterm>
+
+ <programlisting>options IPFIREWALL_DEFAULT_TO_ACCEPT</programlisting>
+
+ <para>This option will allow everything to pass through the
+ firewall by default, which is a good idea when you are first
+ setting up your firewall.</para>
+
+ <programlisting>options IPV6FIREWALL
+options IPV6FIREWALL_VERBOSE
+options IPV6FIREWALL_VERBOSE_LIMIT
+options IPV6FIREWALL_DEFAULT_TO_ACCEPT</programlisting>
+
+ <para>These options are exactly the same as the IPv4 options but
+ they are for IPv6. If you do not use IPv6 you might want to
+ use IPV6FIREWALL without any rules to block all IPv6</para>
+
+ <indexterm>
+ <primary>kernel options</primary>
+
+ <secondary>IPDIVERT</secondary>
+ </indexterm>
+
+ <programlisting>options IPDIVERT</programlisting>
+
+ <para>This enables the use of <acronym>NAT</acronym>
+ functionality.</para>
+
+ <note>
+ <para>If you do not include IPFIREWALL_DEFAULT_TO_ACCEPT or set
+ your rules to allow incoming packets you will block all
+ packets going to and from this machine.</para>
+ </note>
+ </sect2>
+
+ <sect2 xml:id="firewalls-ipfw-rc">
+ <title><filename>/etc/rc.conf</filename> Options</title>
+
+ <para>If you do not have IPFW compiled into your kernel you will
+ need to load it with the following statement in your
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>firewall_enable="YES"</programlisting>
+
+ <para>Set the script to run to activate your rules:</para>
+
+ <programlisting>firewall_script="/etc/ipfw.rules"</programlisting>
+
+ <para>Enable logging:</para>
+
+ <programlisting>firewall_logging="YES"</programlisting>
+
+ <warning>
+ <para>The only thing that the
+ <varname>firewall_logging</varname> variable will do is
+ setting the <varname>net.inet.ip.fw.verbose</varname> sysctl
+ variable to the value of <literal>1</literal> (see <xref linkend="firewalls-ipfw-enable"/>). There is no
+ <filename>rc.conf</filename> variable to set log limitations,
+ but it can be set via sysctl variable, manually or from the
+ <filename>/etc/sysctl.conf</filename> file:</para>
+
+ <programlisting>net.inet.ip.fw.verbose_limit=5</programlisting>
+ </warning>
+
+ <para>If your machine is acting as a gateway, i.e. providing
+ Network Address Translation (NAT) via &man.natd.8;, please
+ refer to <xref linkend="network-natd"/> for information
+ regarding the required <filename>/etc/rc.conf</filename>
+ options.</para>
+ </sect2>
+
+ <sect2 xml:id="firewalls-ipfw-cmd">
+ <title>The IPFW Command</title>
+
+ <indexterm><primary><command>ipfw</command></primary></indexterm>
+
+ <para>The ipfw command is the normal vehicle for making manual
+ single rule additions or deletions to the firewall active
+ internal rules while it is running. The problem with using
+ this method is once your system is shutdown or halted all the
+ rules you added or changed or deleted are lost. Writing all
+ your rules in a file and using that file to load the rules at
+ boot time, or to replace in mass the currently running firewall
+ rules with changes you made to the files content is the
+ recommended method used here.</para>
+
+ <para>The ipfw command is still a very useful to display the
+ running firewall rules to the console screen. The IPFW
+ accounting facility dynamically creates a counter for each
+ rule that counts each packet that matches the rule. During the
+ process of testing a rule, listing the rule with its counter
+ is the one of the ways of determining if the rule is
+ functioning.</para>
+
+ <para>To list all the rules in sequence:</para>
+
+ <screen>&prompt.root; <userinput>ipfw list</userinput></screen>
+
+ <para>To list all the rules with a time stamp of when the last
+ time the rule was matched:</para>
+
+ <screen>&prompt.root; <userinput>ipfw -t list</userinput></screen>
+
+ <para>To list the accounting information, packet count for
+ matched rules along with the rules themselves. The first
+ column is the rule number, followed by the number of outgoing
+ matched packets, followed by the number of incoming matched
+ packets, and then the rule itself.</para>
+
+ <screen>&prompt.root; <userinput>ipfw -a list</userinput></screen>
+
+ <para>List the dynamic rules in addition to the static
+ rules:</para>
+
+ <screen>&prompt.root; <userinput>ipfw -d list</userinput></screen>
+
+ <para>Also show the expired dynamic rules:</para>
+
+ <screen>&prompt.root; <userinput>ipfw -d -e list</userinput></screen>
+
+ <para>Zero the counters:</para>
+
+ <screen>&prompt.root; <userinput>ipfw zero</userinput></screen>
+
+ <para>Zero the counters for just rule
+ <replaceable>NUM</replaceable>:</para>
+
+ <screen>&prompt.root; <userinput>ipfw zero NUM</userinput></screen>
+ </sect2>
+
+ <sect2 xml:id="firewalls-ipfw-rules">
+ <title>IPFW Rule Sets</title>
+
+ <!-- XXX: looks incorrect (and duplicated 2 times in this chapter):
+ 1. Packet can be processed two times depend of firewall
+ firewall configuration, but "return trip back" is
+ another packet.
+ 2. "Each TCP/IP service ... is predefined by its protocol ..."
+ - this shold be about packet and it's parameters
+ (source/destination address and port). -->
+
+ <para>A rule set is a group of ipfw rules coded to allow or deny
+ packets based on the values contained in the packet. The
+ bi-directional exchange of packets between hosts comprises a
+ session conversation. The firewall rule set processes the
+ packet twice: once on its arrival from the public Internet host
+ and again as it leaves for its return trip back to the public
+ Internet host. Each tcp/ip service (i.e. telnet, www, mail,
+ etc.) is predefined by its protocol, and port number. This is
+ the basic selection criteria used to create rules which will
+ allow or deny services.</para>
+
+ <indexterm>
+ <primary>IPFW</primary>
+
+ <secondary>rule processing order</secondary>
+ </indexterm>
+
+ <!-- Needs rewording to include note below -->
+
+ <para>When a packet enters the firewall it is compared against
+ the first rule in the rule set and progress one rule at a time
+ moving from top to bottom of the set in ascending rule number
+ sequence order. When the packet matches a rule selection
+ parameters, the rules action field value is executed and the
+ search of the rule set terminates for that packet. This is
+ referred to as 「the first match wins」 search
+ method. If the packet does not match any of the rules, it gets
+ caught by the mandatory ipfw default rule, number 65535 which
+ denies all packets and discards them without any reply back to
+ the originating destination.</para>
+
+ <note>
+ <para>The search continues after <literal>count</literal>,
+ <literal>skipto</literal> and <literal>tee</literal>
+ rules.</para>
+ </note>
+
+ <para>The instructions contained here are based on using rules
+ that contain the stateful 'keep state', 'limit', 'in'/'out',
+ and via options. This is the basic framework for coding an
+ inclusive type firewall rule set.</para>
+
+ <!-- XXX: something like this already in
+ <xref linkend="firewalls-concepts"/>
+ AND: the para below is repeated 3 times in this chapter. -->
+
+ <para>An inclusive firewall only allows services matching the
+ rules through. This way you can control what services can
+ originate behind the firewall destine for the public Internet
+ and also control the services which can originate from the
+ public Internet accessing your private network. Everything
+ else is denied by default design. Inclusive firewalls are
+ much, much more secure than exclusive firewall rule sets and
+ is the only rule set type covered here in.</para>
+
+ <warning>
+ <para>When working with the firewall rules be careful, you can
+ end up locking your self out.</para>
+ </warning>
+
+ <sect3 xml:id="firewalls-ipfw-rules-syntax">
+ <title>Rule Syntax</title>
+
+ <indexterm>
+ <primary>IPFW</primary>
+
+ <secondary>rule syntax</secondary>
+ </indexterm>
+
+ <para>The rule syntax presented here has been simplified to
+ what is necessary to create a standard inclusive type
+ firewall rule set. For a complete rule syntax description
+ see the &man.ipfw.8; manual page.</para>
+
+ <para>Rules contain keywords: these keywords have to be coded
+ in a specific order from left to right on the line. Keywords
+ are identified in bold type. Some keywords have sub-options
+ which may be keywords them selves and also include more
+ sub-options.</para>
+
+ <para><literal>#</literal> is used to mark the start of a
+ comment and may appear at the end of a rule line or on its
+ own lines. Blank lines are ignored.</para>
+
+ <para><replaceable>CMD RULE_NUMBER ACTION LOGGING SELECTION
+ STATEFUL</replaceable></para>
+
+ <sect4>
+ <title>CMD</title>
+
+ <para>Each new rule has to be prefixed with
+ <parameter>add</parameter> to add the
+ rule to the internal table.</para>
+ </sect4>
+
+ <sect4>
+ <title>RULE_NUMBER</title>
+
+ <para>Each rule has to have a rule number to go with
+ it.</para>
+ </sect4>
+
+ <sect4>
+ <title>ACTION</title>
+
+ <para>A rule can be associated with one of the following
+ actions, which will be executed when the packet matches
+ the selection criterion of the rule.</para>
+
+ <para><parameter>allow | accept | pass |
+ permit</parameter></para>
+
+ <para>These all mean the same thing which is to allow packets
+ that match the rule to exit the firewall rule processing.
+ The search terminates at this rule.</para>
+
+ <para><parameter>check-state</parameter></para>
+
+ <para>Checks the packet against the dynamic rules table. If
+ a match is found, execute the action associated with the
+ rule which generated this dynamic rule, otherwise move to
+ the next rule. The check-state rule does not have
+ selection criterion. If no check-state rule is present in
+ the rule set, the dynamic rules table is checked at the
+ first keep-state or limit rule.</para>
+
+ <para><parameter>deny | drop</parameter></para>
+
+ <para>Both words mean the same thing which is to discard
+ packets that match this rule. The search
+ terminates.</para>
+ </sect4>
+
+ <sect4>
+ <title>Logging</title>
+
+ <para><parameter>log</parameter> or
+ <parameter>logamount</parameter></para>
+
+ <para>When a packet matches a rule with the log keyword, a
+ message will be logged to syslogd with a facility name of
+ SECURITY. The logging only occurs if the number of
+ packets logged so far for that particular rule does not
+ exceed the logamount parameter. If no logamount is
+ specified, the limit is taken from the sysctl variable
+ net.inet.ip.fw.verbose_limit. In both cases, a value of
+ zero removes the logging limit. Once the limit is
+ reached, logging can be re-enabled by clearing the
+ logging counter or the packet counter for that rule, see
+ the ipfw reset log command.</para>
+
+ <note>
+ <para>Logging is done after
+ all other packet matching conditions have been
+ successfully verified, and before performing the final
+ action (accept, deny) on the packet. It is up to you to
+ decide which rules you want to enable logging on.</para>
+ </note>
+ </sect4>
+
+ <sect4>
+ <title>Selection</title>
+
+ <para>The keywords described in this section are used to
+ describe attributes of the packet to be interrogated when
+ determining whether rules match the packet or not.
+ The following general-purpose attributes are provided for
+ matching, and must be used in this order:</para>
+
+ <para><parameter>udp | tcp | icmp</parameter></para>
+
+ <para>or any protocol names found in
+ <filename>/etc/protocols</filename> are recognized and may
+ be used. The value specified is protocol to be matched
+ against. This is a mandatory requirement.</para>
+
+ <para><parameter>from src to dst</parameter></para>
+
+ <para>The from and to keywords are used to match against IP
+ addresses. Rules must specify BOTH source and destination
+ parameters. <literal>any</literal> is a special keyword
+ that matches any IP address. <literal>me</literal> is a
+ special keyword that matches any IP address configured on
+ an interface in your &os; system to represent the PC the
+ firewall is running on (i.e. this box) as in 'from me to
+ any' or 'from any to me' or 'from 0.0.0.0/0 to any' or
+ 'from any to 0.0.0.0/0' or 'from 0.0.0.0 to any' or 'from
+ any to 0.0.0.0' or 'from me to 0.0.0.0'. IP addresses are
+ specified as a dotted IP address numeric form/mask-length,
+ or as single dotted IP address numeric form. This is a
+ mandatory requirement. See this link for help on writing
+ mask-lengths. <uri xlink:href="http://jodies.de/ipcalc">http://jodies.de/ipcalc</uri></para>
+
+ <para><parameter>port number</parameter></para>
+
+ <para>For protocols which support port numbers (such as
+ <acronym>TCP</acronym> and UDP). It is mandatory that you
+ code the port number of the service you want to match
+ on. Service names (from
+ <filename>/etc/services</filename>) may be used instead of
+ numeric port values.</para>
+
+ <para><parameter>in | out</parameter></para>
+
+ <para>Matches incoming or outgoing packets, respectively.
+ The in and out are keywords and it is mandatory that you
+ code one or the other as part of your rule matching
+ criterion.</para>
+
+ <para><parameter>via IF</parameter></para>
+
+ <para>Matches packets going through the interface specified
+ by exact name. The <literal>via</literal> keyword causes
+ the interface to always be checked as part of the match
+ process.</para>
+
+ <para><parameter>setup</parameter></para>
+
+ <para>This is a mandatory keyword that identifies the session
+ start request for <acronym>TCP</acronym> packets.</para>
+
+ <para><parameter>keep-state</parameter></para>
+
+ <para>This is a mandatory&gt; keyword. Upon a match, the
+ firewall will create a dynamic rule, whose default behavior
+ is to match bidirectional traffic between source and
+ destination IP/port using the same protocol.</para>
+
+ <para><parameter>limit {src-addr | src-port | dst-addr |
+ dst-port}</parameter></para>
+
+ <para>The firewall will only allow
+ <replaceable>N</replaceable> connections with the same set
+ of parameters as specified in the rule. One or more of
+ source and destination addresses and ports can be
+ specified. The 'limit' and 'keep-state' can not be used on
+ same rule. Limit provides the same stateful function as
+ 'keep-state' plus its own functions.</para>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>Stateful Rule Option</title>
+
+ <indexterm>
+ <primary>IPFW</primary>
+
+ <secondary>stateful filtering</secondary>
+ </indexterm>
+
+ <!-- XXX: duplicated -->
+
+ <para>Stateful filtering treats traffic as a bi-directional
+ exchange of packets comprising a session conversation. It
+ has the interrogation abilities to determine if the session
+ conversation between the originating sender and the
+ destination are following the valid procedure of
+ bi-directional packet exchange. Any packets that do not
+ properly fit the session conversation template are
+ automatically rejected as impostors.</para>
+
+ <para>'check-state' is used to identify where in the IPFW rules
+ set the packet is to be tested against the dynamic rules
+ facility. On a match the packet exits the firewall to
+ continue on its way and a new rule is dynamic created for
+ the next anticipated packet being exchanged during this
+ bi-directional session conversation. On a no match the
+ packet advances to the next rule in the rule set for
+ testing.</para>
+
+ <para>The dynamic rules facility is vulnerable to resource
+ depletion from a SYN-flood attack which would open a huge
+ number of dynamic rules. To counter this attack, &os;
+ version 4.5 added another new option named limit. This
+ option is used to limit the number of simultaneous session
+ conversations by interrogating the rules source or
+ destinations fields as directed by the limit option and
+ using the packet's IP address found there, in a search of
+ the open dynamic rules counting the number of times this
+ rule and IP address combination occurred, if this count is
+ greater that the value specified on the limit option, the
+ packet is discarded.</para>
+ </sect3>
+
+ <sect3>
+ <title>Logging Firewall Messages</title>
+
+ <indexterm>
+ <primary>IPFW</primary>
+
+ <secondary>logging</secondary>
+ </indexterm>
+
+ <para>The benefits of logging are obvious: it provides the
+ ability to review after the fact the rules you activated
+ logging on which provides information like, what packets had
+ been dropped, what addresses they came from, where they were
+ going, giving you a significant edge in tracking down
+ attackers.</para>
+
+ <para>Even with the logging facility enabled, IPFW will not
+ generate any rule logging on it's own. The firewall
+ administrator decides what rules in the rule set he wants
+ to log and adds the log verb to those rules. Normally only
+ deny rules are logged, like the deny rule for incoming
+ <acronym>ICMP</acronym> pings. It is very customary to
+ duplicate the ipfw default deny everything rule with the
+ log verb included as your last rule in the rule set. This
+ way you get to see all the packets that did not match any
+ of the rules in the rule set.</para>
+
+ <para>Logging is a two edged sword, if you are not careful, you
+ can lose yourself in the over abundance of log data and fill
+ your disk up with growing log files. DoS attacks that fill
+ up disk drives is one of the oldest attacks around. These
+ log message are not only written to syslogd, but also are
+ displayed on the root console screen and soon become very
+ annoying.</para>
+
+ <para>The <literal>IPFIREWALL_VERBOSE_LIMIT=5</literal>
+ kernel option limits the number of consecutive messages
+ sent to the system logger syslogd, concerning the packet
+ matching of a given rule. When this option is enabled in
+ the kernel, the number of consecutive messages concerning
+ a particular rule is capped at the number specified. There
+ is nothing to be gained from 200 log messages saying the
+ same identical thing. For instance, five consecutive
+ messages concerning a particular rule would be logged to
+ syslogd, the remainder identical consecutive messages would
+ be counted and posted to the syslogd with a phrase like
+ this:</para>
+
+ <programlisting>last message repeated 45 times</programlisting>
+
+ <para>All logged packets messages are written by default to
+ <filename>/var/log/security</filename> file, which is defined
+ in the <filename>/etc/syslog.conf</filename> file.</para>
+ </sect3>
+
+ <sect3 xml:id="firewalls-ipfw-rules-script">
+ <title>Building a Rule Script</title>
+
+ <para>Most experienced IPFW users create a file containing the
+ rules and code them in a manner compatible with running them
+ as a script. The major benefit of doing this is the firewall
+ rules can be refreshed in mass without the need of rebooting
+ the system to activate the new rules. This method is very
+ convenient in testing new rules as the procedure can be
+ executed as many times as needed. Being a script, you can
+ use symbolic substitution to code frequent used values and
+ substitution them in multiple rules. You will see this in
+ the following example.</para>
+
+ <para>The script syntax used here is compatible with the 'sh',
+ 'csh', 'tcsh' shells. Symbolic substitution fields are
+ prefixed with a dollar sign &dollar;. Symbolic fields do not
+ have the &dollar; prefix. The value to populate the Symbolic
+ field must be enclosed to "double quotes".</para>
+
+ <para>Start your rules file like this:</para>
+
+ <programlisting>############### start of example ipfw rules script #############
+#
+ipfw -q -f flush # Delete all rules
+# Set defaults
+oif="tun0" # out interface
+odns="192.0.2.11" # ISP's DNS server IP address
+cmd="ipfw -q add " # build rule prefix
+ks="keep-state" # just too lazy to key this each time
+&dollar;cmd 00500 check-state
+&dollar;cmd 00502 deny all from any to any frag
+&dollar;cmd 00501 deny tcp from any to any established
+&dollar;cmd 00600 allow tcp from any to any 80 out via &dollar;oif setup &dollar;ks
+&dollar;cmd 00610 allow tcp from any to &dollar;odns 53 out via &dollar;oif setup &dollar;ks
+&dollar;cmd 00611 allow udp from any to &dollar;odns 53 out via &dollar;oif &dollar;ks
+################### End of example ipfw rules script ############</programlisting>
+
+ <para>That is all there is to it. The rules are not important
+ in this example, how the Symbolic substitution field are
+ populated and used are.</para>
+
+ <para>If the above example was in
+ <filename>/etc/ipfw.rules</filename> file, you could reload
+ these rules by entering on the command line.</para>
+
+ <screen>&prompt.root; <userinput>sh /etc/ipfw.rules</userinput></screen>
+
+ <para>The <filename>/etc/ipfw.rules</filename> file could be
+ located anywhere you want and the file could be named any
+ thing you would like.</para>
+
+ <para>The same thing could also be accomplished by running
+ these commands by hand:</para>
+
+ <screen>&prompt.root; <userinput>ipfw -q -f flush</userinput>
+&prompt.root; <userinput>ipfw -q add check-state</userinput>
+&prompt.root; <userinput>ipfw -q add deny all from any to any frag</userinput>
+&prompt.root; <userinput>ipfw -q add deny tcp from any to any established</userinput>
+&prompt.root; <userinput>ipfw -q add allow tcp from any to any 80 out via tun0 setup keep-state</userinput>
+&prompt.root; <userinput>ipfw -q add allow tcp from any to 192.0.2.11 53 out via tun0 setup keep-state</userinput>
+&prompt.root; <userinput>ipfw -q add 00611 allow udp from any to 192.0.2.11 53 out via tun0 keep-state</userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Stateful Ruleset</title>
+
+ <para>The following non-<acronym>NAT</acronym>ed rule set is an
+ example of how to code a very secure 'inclusive' type of
+ firewall. An inclusive firewall only allows services
+ matching pass rules through and blocks all other by default.
+ All firewalls have at the minimum two interfaces which have
+ to have rules to allow the firewall to function.</para>
+
+ <para>All &unix; flavored operating systems, &os; included, are
+ designed to use interface <filename>lo0</filename> and IP
+ address <systemitem class="ipaddress">127.0.0.1</systemitem> for internal
+ communication with in the operating system. The firewall
+ rules must contain rules to allow free unmolested movement of
+ these special internally used packets.</para>
+
+ <para>The interface which faces the public Internet, is the one
+ which you code your rules to authorize and control access out
+ to the public Internet and access requests arriving from the
+ public Internet. This can be your ppp
+ <filename>tun0</filename> interface or your NIC that is
+ connected to your DSL or cable modem.</para>
+
+ <para>In cases where one or more than one NIC are connected to
+ a private LANs behind the firewall, those interfaces must
+ have rules coded to allow free unmolested movement of
+ packets originating from those LAN interfaces.</para>
+
+ <para>The rules should be first organized into three major
+ sections, all the free unmolested interfaces, public
+ interface outbound, and the public interface inbound.</para>
+
+ <para>The order of the rules in each of the public interface
+ sections should be in order of the most used rules being
+ placed before less often used rules with the last rule in
+ the section being a block log all packets on that interface
+ and direction.</para>
+
+ <para>The Outbound section in the following rule set only
+ contains 'allow' rules which contain selection values that
+ uniquely identify the service that is authorized for public
+ Internet access. All the rules have the, proto, port,
+ in/out, via and keep state option coded. The 'proto tcp'
+ rules have the 'setup' option included to identify the start
+ session request as the trigger packet to be posted to the
+ keep state stateful table.</para>
+
+ <para>The Inbound section has all the blocking of undesirable
+ packets first for two different reasons. First is these
+ things being blocked may be part of an otherwise valid packet
+ which may be allowed in by the later authorized service
+ rules. Second reason is that by having a rule that
+ explicitly blocks selected packets that I receive on an
+ infrequent bases and do not want to see in the log, this
+ keeps them from being caught by the last rule in the section
+ which blocks and logs all packets which have fallen through
+ the rules. The last rule in the section which blocks and
+ logs all packets is how you create the legal evidence needed
+ to prosecute the people who are attacking your system.</para>
+
+ <para>Another thing you should take note of, is there is no
+ response returned for any of the undesirable stuff, their
+ packets just get dropped and vanish. This way the attackers
+ has no knowledge if his packets have reached your system.
+ The less the attackers can learn about your system the more
+ secure it is. When you log packets with port numbers you do
+ not recognize, look the numbers up in
+ <filename>/etc/services/</filename> or go to <uri xlink:href="http://www.securitystats.com/tools/portsearch.php">http://www.securitystats.com/tools/portsearch.php</uri>
+ and do a port number lookup to find what the purpose of that
+ port number is. Check out this link for port numbers used by
+ Trojans: <uri xlink:href="http://www.simovits.com/trojans/trojans.html">http://www.simovits.com/trojans/trojans.html</uri>.</para>
+ </sect3>
+
+ <sect3>
+ <title>An Example Inclusive Ruleset</title>
+
+ <para>The following non-<acronym>NAT</acronym>ed rule set is a
+ complete inclusive type ruleset. You can not go wrong using
+ this rule set for you own. Just comment out any pass rules
+ for services you do not want. If you see messages in your
+ log that you want to stop seeing just add a deny rule in the
+ inbound section. You have to change the 'dc0' interface name
+ in every rule to the interface name of the NIC that connects
+ your system to the public Internet. For user ppp it would be
+ 'tun0'.</para>
+
+ <para>You will see a pattern in the usage of these
+ rules.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>All statements that are a request to start a session
+ to the public Internet use keep-state.</para>
+ </listitem>
+
+ <listitem>
+ <para>All the authorized services that originate from the
+ public Internet have the limit option to stop
+ flooding.</para>
+ </listitem>
+
+ <listitem>
+ <para>All rules use in or out to clarify direction.</para>
+ </listitem>
+
+ <listitem>
+ <para>All rules use via interface name to specify the
+ interface the packet is traveling over.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The following rules go into
+ <filename>/etc/ipfw.rules</filename>.</para>
+
+ <programlisting>################ Start of IPFW rules file ###############################
+# Flush out the list before we begin.
+ipfw -q -f flush
+
+# Set rules command prefix
+cmd="ipfw -q add"
+pif="dc0" # public interface name of NIC
+ # facing the public Internet
+
+#################################################################
+# No restrictions on Inside LAN Interface for private network
+# Not needed unless you have LAN.
+# Change xl0 to your LAN NIC interface name
+#################################################################
+#&dollar;cmd 00005 allow all from any to any via xl0
+
+#################################################################
+# No restrictions on Loopback Interface
+#################################################################
+&dollar;cmd 00010 allow all from any to any via lo0
+
+#################################################################
+# Allow the packet through if it has previous been added to the
+# the "dynamic" rules table by a allow keep-state statement.
+#################################################################
+&dollar;cmd 00015 check-state
+
+#################################################################
+# Interface facing Public Internet (Outbound Section)
+# Interrogate session start requests originating from behind the
+# firewall on the private network or from this gateway server
+# destine for the public Internet.
+#################################################################
+
+# Allow out access to my ISP's Domain name server.
+# x.x.x.x must be the IP address of your ISP.s DNS
+# Dup these lines if your ISP has more than one DNS server
+# Get the IP addresses from /etc/resolv.conf file
+&dollar;cmd 00110 allow tcp from any to x.x.x.x 53 out via &dollar;pif setup keep-state
+&dollar;cmd 00111 allow udp from any to x.x.x.x 53 out via &dollar;pif keep-state
+
+# Allow out access to my ISP's DHCP server for cable/DSL configurations.
+# This rule is not needed for .user ppp. connection to the public Internet.
+# so you can delete this whole group.
+# Use the following rule and check log for IP address.
+# Then put IP address in commented out rule &amp; delete first rule
+&dollar;cmd 00120 allow log udp from any to any 67 out via &dollar;pif keep-state
+#&dollar;cmd 00120 allow udp from any to x.x.x.x 67 out via &dollar;pif keep-state
+
+# Allow out non-secure standard www function
+&dollar;cmd 00200 allow tcp from any to any 80 out via &dollar;pif setup keep-state
+
+# Allow out secure www function https over TLS SSL
+&dollar;cmd 00220 allow tcp from any to any 443 out via &dollar;pif setup keep-state
+
+# Allow out send &amp; get email function
+&dollar;cmd 00230 allow tcp from any to any 25 out via &dollar;pif setup keep-state
+&dollar;cmd 00231 allow tcp from any to any 110 out via &dollar;pif setup keep-state
+
+# Allow out FBSD (make install &amp; CVSUP) functions
+# Basically give user root "GOD" privileges.
+&dollar;cmd 00240 allow tcp from me to any out via &dollar;pif setup keep-state uid root
+
+# Allow out ping
+&dollar;cmd 00250 allow icmp from any to any out via &dollar;pif keep-state
+
+# Allow out Time
+&dollar;cmd 00260 allow tcp from any to any 37 out via &dollar;pif setup keep-state
+
+# Allow out nntp news (i.e. news groups)
+&dollar;cmd 00270 allow tcp from any to any 119 out via &dollar;pif setup keep-state
+
+# Allow out secure FTP, Telnet, and SCP
+# This function is using SSH (secure shell)
+&dollar;cmd 00280 allow tcp from any to any 22 out via &dollar;pif setup keep-state
+
+# Allow out whois
+&dollar;cmd 00290 allow tcp from any to any 43 out via &dollar;pif setup keep-state
+
+# deny and log everything else that.s trying to get out.
+# This rule enforces the block all by default logic.
+&dollar;cmd 00299 deny log all from any to any out via &dollar;pif
+
+#################################################################
+# Interface facing Public Internet (Inbound Section)
+# Interrogate packets originating from the public Internet
+# destine for this gateway server or the private network.
+#################################################################
+
+# Deny all inbound traffic from non-routable reserved address spaces
+&dollar;cmd 00300 deny all from 192.168.0.0/16 to any in via &dollar;pif #RFC 1918 private IP
+&dollar;cmd 00301 deny all from 172.16.0.0/12 to any in via &dollar;pif #RFC 1918 private IP
+&dollar;cmd 00302 deny all from 10.0.0.0/8 to any in via &dollar;pif #RFC 1918 private IP
+&dollar;cmd 00303 deny all from 127.0.0.0/8 to any in via &dollar;pif #loopback
+&dollar;cmd 00304 deny all from 0.0.0.0/8 to any in via &dollar;pif #loopback
+&dollar;cmd 00305 deny all from 169.254.0.0/16 to any in via &dollar;pif #DHCP auto-config
+&dollar;cmd 00306 deny all from 192.0.2.0/24 to any in via &dollar;pif #reserved for docs
+&dollar;cmd 00307 deny all from 204.152.64.0/23 to any in via &dollar;pif #Sun cluster interconnect
+&dollar;cmd 00308 deny all from 224.0.0.0/3 to any in via &dollar;pif #Class D &amp; E multicast
+
+# Deny public pings
+&dollar;cmd 00310 deny icmp from any to any in via &dollar;pif
+
+# Deny ident
+&dollar;cmd 00315 deny tcp from any to any 113 in via &dollar;pif
+
+# Deny all Netbios service. 137=name, 138=datagram, 139=session
+# Netbios is MS/Windows sharing services.
+# Block MS/Windows hosts2 name server requests 81
+&dollar;cmd 00320 deny tcp from any to any 137 in via &dollar;pif
+&dollar;cmd 00321 deny tcp from any to any 138 in via &dollar;pif
+&dollar;cmd 00322 deny tcp from any to any 139 in via &dollar;pif
+&dollar;cmd 00323 deny tcp from any to any 81 in via &dollar;pif
+
+# Deny any late arriving packets
+&dollar;cmd 00330 deny all from any to any frag in via &dollar;pif
+
+# Deny ACK packets that did not match the dynamic rule table
+&dollar;cmd 00332 deny tcp from any to any established in via &dollar;pif
+
+# Allow traffic in from ISP's DHCP server. This rule must contain
+# the IP address of your ISP.s DHCP server as it.s the only
+# authorized source to send this packet type.
+# Only necessary for cable or DSL configurations.
+# This rule is not needed for .user ppp. type connection to
+# the public Internet. This is the same IP address you captured
+# and used in the outbound section.
+#&dollar;cmd 00360 allow udp from any to x.x.x.x 67 in via &dollar;pif keep-state
+
+# Allow in standard www function because I have apache server
+&dollar;cmd 00400 allow tcp from any to me 80 in via &dollar;pif setup limit src-addr 2
+
+# Allow in secure FTP, Telnet, and SCP from public Internet
+&dollar;cmd 00410 allow tcp from any to me 22 in via &dollar;pif setup limit src-addr 2
+
+# Allow in non-secure Telnet session from public Internet
+# labeled non-secure because ID &amp; PW are passed over public
+# Internet as clear text.
+# Delete this sample group if you do not have telnet server enabled.
+&dollar;cmd 00420 allow tcp from any to me 23 in via &dollar;pif setup limit src-addr 2
+
+# Reject &amp; Log all incoming connections from the outside
+&dollar;cmd 00499 deny log all from any to any in via &dollar;pif
+
+# Everything else is denied by default
+# deny and log all packets that fell through to see what they are
+&dollar;cmd 00999 deny log all from any to any
+################ End of IPFW rules file ###############################</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>An Example <acronym>NAT</acronym> and Stateful
+ Ruleset</title>
+
+ <indexterm>
+ <primary>NAT</primary>
+
+ <secondary>and IPFW</secondary>
+ </indexterm>
+
+ <para>There are some additional configuration statements that
+ need to be enabled to activate the <acronym>NAT</acronym>
+ function of IPFW. The kernel source needs 'option divert'
+ statement added to the other IPFIREWALL statements compiled
+ into a custom kernel.</para>
+
+ <para>In addition to the normal IPFW options in
+ <filename>/etc/rc.conf</filename>, the following are
+ needed.</para>
+
+ <programlisting>natd_enable="YES" # Enable <acronym>NAT</acronym>D function
+natd_interface="rl0" # interface name of public Internet NIC
+natd_flags="-dynamic -m" # -m = preserve port numbers if possible</programlisting>
+
+ <para>Utilizing stateful rules with divert natd rule (Network
+ Address Translation) greatly complicates the rule set coding
+ logic. The positioning of the check-state, and 'divert natd'
+ rules in the rule set becomes very critical. This is no
+ longer a simple fall-through logic flow. A new action type
+ is used, called 'skipto'. To use the skipto command it is
+ mandatory that you number each rule so you know exactly
+ where the skipto rule number is you are really jumping
+ to.</para>
+
+ <para>The following is an uncommented example of one coding
+ method, selected here to explain the sequence of the packet
+ flow through the rule sets.</para>
+
+ <para>The processing flow starts with the first rule from the
+ top of the rule file and progress one rule at a time deeper
+ into the file until the end is reach or the packet being
+ tested to the selection criteria matches and the packet is
+ released out of the firewall. It is important to take notice
+ of the location of rule numbers 100 101, 450, 500, and 510.
+ These rules control the translation of the outbound and
+ inbound packets so their entries in the keep-state dynamic
+ table always register the private LAN IP address. Next
+ notice that all the allow and deny rules specified the
+ direction the packet is going (IE outbound or inbound) and
+ the interface. Also notice that all the start outbound
+ session requests all skipto rule 500 for the network address
+ translation.</para>
+
+ <para>Lets say a LAN user uses their web browser to get a web
+ page. Web pages use port 80 to communicate over. So the
+ packet enters the firewall, It does not match 100 because it
+ is headed out not in. It passes rule 101 because this is the
+ first packet so it has not been posted to the keep-state
+ dynamic table yet. The packet finally comes to rule 125 a
+ matches. It is outbound through the NIC facing the public
+ Internet. The packet still has it's source IP address as a
+ private LAN IP address. On the match to this rule, two
+ actions take place. The keep-state option will post this
+ rule into the keep-state dynamic rules table and the
+ specified action is executed. The action is part of the info
+ posted to the dynamic table. In this case it is "skipto rule
+ 500". Rule 500 <acronym>NAT</acronym>s the packet IP address
+ and out it goes. Remember this, this is very important.
+ This packet makes its way to the destination and returns and
+ enters the top of the rule set. This time it does match rule
+ 100 and has it destination IP address mapped back to its
+ corresponding LAN IP address. It then is processed by the
+ check-state rule, it's found in the table as an existing
+ session conversation and released to the LAN. It goes to the
+ LAN PC that sent it and a new packet is sent requesting
+ another segment of the data from the remote server. This
+ time it gets checked by the check-state rule and its outbound
+ entry is found, the associated action, 'skipto 500', is
+ executed. The packet jumps to rule 500 gets
+ <acronym>NAT</acronym>ed and released on it's way out.</para>
+
+ <para>On the inbound side, everything coming in that is part
+ of an existing session conversation is being automatically
+ handled by the check-state rule and the properly placed
+ divert natd rules. All we have to address is denying all the
+ bad packets and only allowing in the authorized services.
+ Lets say there is a apache server running on the firewall box
+ and we want people on the public Internet to be able to
+ access the local web site. The new inbound start request
+ packet matches rule 100 and its IP address is mapped to LAN
+ IP for the firewall box. The packet is them matched against
+ all the nasty things we want to check for and finally matches
+ against rule 425. On a match two things occur. The packet
+ rule is posted to the keep-state dynamic table but this time
+ any new session requests originating from that source IP
+ address is limited to 2. This defends against DoS attacks of
+ service running on the specified port number. The action is
+ allow so the packet is released to the LAN. On return the
+ check-state rule recognizes the packet as belonging to an
+ existing session conversation sends it to rule 500 for
+ <acronym>NAT</acronym>ing and released to outbound
+ interface.</para>
+
+ <para>Example Ruleset #1:</para>
+
+ <programlisting>#!/bin/sh
+cmd="ipfw -q add"
+skip="skipto 500"
+pif=rl0
+ks="keep-state"
+good_tcpo="22,25,37,43,53,80,443,110,119"
+
+ipfw -q -f flush
+
+&dollar;cmd 002 allow all from any to any via xl0 # exclude LAN traffic
+&dollar;cmd 003 allow all from any to any via lo0 # exclude loopback traffic
+
+&dollar;cmd 100 divert natd ip from any to any in via &dollar;pif
+&dollar;cmd 101 check-state
+
+# Authorized outbound packets
+&dollar;cmd 120 &dollar;skip udp from any to xx.168.240.2 53 out via &dollar;pif &dollar;ks
+&dollar;cmd 121 &dollar;skip udp from any to xx.168.240.5 53 out via &dollar;pif &dollar;ks
+&dollar;cmd 125 &dollar;skip tcp from any to any &dollar;good_tcpo out via &dollar;pif setup &dollar;ks
+&dollar;cmd 130 &dollar;skip icmp from any to any out via &dollar;pif &dollar;ks
+&dollar;cmd 135 &dollar;skip udp from any to any 123 out via &dollar;pif &dollar;ks
+
+
+# Deny all inbound traffic from non-routable reserved address spaces
+&dollar;cmd 300 deny all from 192.168.0.0/16 to any in via &dollar;pif #RFC 1918 private IP
+&dollar;cmd 301 deny all from 172.16.0.0/12 to any in via &dollar;pif #RFC 1918 private IP
+&dollar;cmd 302 deny all from 10.0.0.0/8 to any in via &dollar;pif #RFC 1918 private IP
+&dollar;cmd 303 deny all from 127.0.0.0/8 to any in via &dollar;pif #loopback
+&dollar;cmd 304 deny all from 0.0.0.0/8 to any in via &dollar;pif #loopback
+&dollar;cmd 305 deny all from 169.254.0.0/16 to any in via &dollar;pif #DHCP auto-config
+&dollar;cmd 306 deny all from 192.0.2.0/24 to any in via &dollar;pif #reserved for docs
+&dollar;cmd 307 deny all from 204.152.64.0/23 to any in via &dollar;pif #Sun cluster
+&dollar;cmd 308 deny all from 224.0.0.0/3 to any in via &dollar;pif #Class D &amp; E multicast
+
+# Authorized inbound packets
+&dollar;cmd 400 allow udp from xx.70.207.54 to any 68 in &dollar;ks
+&dollar;cmd 420 allow tcp from any to me 80 in via &dollar;pif setup limit src-addr 1
+
+
+&dollar;cmd 450 deny log ip from any to any
+
+# This is skipto location for outbound stateful rules
+&dollar;cmd 500 divert natd ip from any to any out via &dollar;pif
+&dollar;cmd 510 allow ip from any to any
+
+######################## end of rules ##################</programlisting>
+
+ <para>The following is pretty much the same as above, but uses
+ a self documenting coding style full of description comments
+ to help the inexperienced IPFW rule writer to better
+ understand what the rules are doing.</para>
+
+ <para>Example Ruleset #2:</para>
+
+ <programlisting>#!/bin/sh
+################ Start of IPFW rules file ###############################
+# Flush out the list before we begin.
+ipfw -q -f flush
+
+# Set rules command prefix
+cmd="ipfw -q add"
+skip="skipto 800"
+pif="rl0" # public interface name of NIC
+ # facing the public Internet
+
+#################################################################
+# No restrictions on Inside LAN Interface for private network
+# Change xl0 to your LAN NIC interface name
+#################################################################
+&dollar;cmd 005 allow all from any to any via xl0
+
+#################################################################
+# No restrictions on Loopback Interface
+#################################################################
+&dollar;cmd 010 allow all from any to any via lo0
+
+#################################################################
+# check if packet is inbound and nat address if it is
+#################################################################
+&dollar;cmd 014 divert natd ip from any to any in via &dollar;pif
+
+#################################################################
+# Allow the packet through if it has previous been added to the
+# the "dynamic" rules table by a allow keep-state statement.
+#################################################################
+&dollar;cmd 015 check-state
+
+#################################################################
+# Interface facing Public Internet (Outbound Section)
+# Interrogate session start requests originating from behind the
+# firewall on the private network or from this gateway server
+# destine for the public Internet.
+#################################################################
+
+# Allow out access to my ISP's Domain name server.
+# x.x.x.x must be the IP address of your ISP's DNS
+# Dup these lines if your ISP has more than one DNS server
+# Get the IP addresses from /etc/resolv.conf file
+&dollar;cmd 020 &dollar;skip tcp from any to x.x.x.x 53 out via &dollar;pif setup keep-state
+
+
+# Allow out access to my ISP's DHCP server for cable/DSL configurations.
+&dollar;cmd 030 &dollar;skip udp from any to x.x.x.x 67 out via &dollar;pif keep-state
+
+# Allow out non-secure standard www function
+&dollar;cmd 040 &dollar;skip tcp from any to any 80 out via &dollar;pif setup keep-state
+
+# Allow out secure www function https over TLS SSL
+&dollar;cmd 050 &dollar;skip tcp from any to any 443 out via &dollar;pif setup keep-state
+
+# Allow out send &amp; get email function
+&dollar;cmd 060 &dollar;skip tcp from any to any 25 out via &dollar;pif setup keep-state
+&dollar;cmd 061 &dollar;skip tcp from any to any 110 out via &dollar;pif setup keep-state
+
+# Allow out FreeBSD (make install &amp; CVSUP) functions
+# Basically give user root "GOD" privileges.
+&dollar;cmd 070 &dollar;skip tcp from me to any out via &dollar;pif setup keep-state uid root
+
+# Allow out ping
+&dollar;cmd 080 &dollar;skip icmp from any to any out via &dollar;pif keep-state
+
+# Allow out Time
+&dollar;cmd 090 &dollar;skip tcp from any to any 37 out via &dollar;pif setup keep-state
+
+# Allow out nntp news (i.e. news groups)
+&dollar;cmd 100 &dollar;skip tcp from any to any 119 out via &dollar;pif setup keep-state
+
+# Allow out secure FTP, Telnet, and SCP
+# This function is using SSH (secure shell)
+&dollar;cmd 110 &dollar;skip tcp from any to any 22 out via &dollar;pif setup keep-state
+
+# Allow out whois
+&dollar;cmd 120 &dollar;skip tcp from any to any 43 out via &dollar;pif setup keep-state
+
+# Allow ntp time server
+&dollar;cmd 130 &dollar;skip udp from any to any 123 out via &dollar;pif keep-state
+
+#################################################################
+# Interface facing Public Internet (Inbound Section)
+# Interrogate packets originating from the public Internet
+# destine for this gateway server or the private network.
+#################################################################
+
+# Deny all inbound traffic from non-routable reserved address spaces
+&dollar;cmd 300 deny all from 192.168.0.0/16 to any in via &dollar;pif #RFC 1918 private IP
+&dollar;cmd 301 deny all from 172.16.0.0/12 to any in via &dollar;pif #RFC 1918 private IP
+&dollar;cmd 302 deny all from 10.0.0.0/8 to any in via &dollar;pif #RFC 1918 private IP
+&dollar;cmd 303 deny all from 127.0.0.0/8 to any in via &dollar;pif #loopback
+&dollar;cmd 304 deny all from 0.0.0.0/8 to any in via &dollar;pif #loopback
+&dollar;cmd 305 deny all from 169.254.0.0/16 to any in via &dollar;pif #DHCP auto-config
+&dollar;cmd 306 deny all from 192.0.2.0/24 to any in via &dollar;pif #reserved for docs
+&dollar;cmd 307 deny all from 204.152.64.0/23 to any in via &dollar;pif #Sun cluster
+&dollar;cmd 308 deny all from 224.0.0.0/3 to any in via &dollar;pif #Class D &amp; E multicast
+
+# 拒絕 ident
+&dollar;cmd 315 deny tcp from any to any 113 in via &dollar;pif
+
+# 拒絕所有的 Netbios 服務. 137=name, 138=datagram, 139=session
+# Netbios 是 MS/Windows 網路分享服務
+# 阻擋所有的 MS/Windows 主機名稱伺服器hosts2 name server requests 81
+&dollar;cmd 320 deny tcp from any to any 137 in via &dollar;pif
+&dollar;cmd 321 deny tcp from any to any 138 in via &dollar;pif
+&dollar;cmd 322 deny tcp from any to any 139 in via &dollar;pif
+&dollar;cmd 323 deny tcp from any to any 81 in via &dollar;pif
+
+# 拒絕任何的延遲到達之封包
+&dollar;cmd 330 deny all from any to any frag in via &dollar;pif
+
+# Deny ACK packets that did not match the dynamic rule table
+&dollar;cmd 332 deny tcp from any to any established in via &dollar;pif
+
+# Allow traffic in from ISP's DHCP server. This rule must contain
+# the IP address of your ISP's DHCP server as it's the only
+# authorized source to send this packet type.
+# Only necessary for cable or DSL configurations.
+# This rule is not needed for 'user ppp' type connection to
+# the public Internet. This is the same IP address you captured
+# and used in the outbound section.
+&dollar;cmd 360 allow udp from x.x.x.x to any 68 in via &dollar;pif keep-state
+
+# Allow in standard www function because I have Apache server
+&dollar;cmd 370 allow tcp from any to me 80 in via &dollar;pif setup limit src-addr 2
+
+# Allow in secure FTP, Telnet, and SCP from public Internet
+&dollar;cmd 380 allow tcp from any to me 22 in via &dollar;pif setup limit src-addr 2
+
+# Allow in non-secure Telnet session from public Internet
+# labeled non-secure because ID &amp; PW are passed over public
+# Internet as clear text.
+# Delete this sample group if you do not have telnet server enabled.
+&dollar;cmd 390 allow tcp from any to me 23 in via &dollar;pif setup limit src-addr 2
+
+# Reject &amp; Log all unauthorized incoming connections from the public Internet
+&dollar;cmd 400 deny log all from any to any in via &dollar;pif
+
+# Reject &amp; Log all unauthorized out going connections to the public Internet
+&dollar;cmd 450 deny log all from any to any out via &dollar;pif
+
+# This is skipto location for outbound stateful rules
+&dollar;cmd 800 divert natd ip from any to any out via &dollar;pif
+&dollar;cmd 801 allow ip from any to any
+
+# Everything else is denied by default
+# deny and log all packets that fell through to see what they are
+&dollar;cmd 999 deny log all from any to any
+################ End of IPFW rules file ###############################</programlisting>
+ </sect3>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/geom/Makefile b/zh_TW.UTF-8/books/handbook/geom/Makefile
new file mode 100644
index 0000000000..f574c00011
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/geom/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= geom/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/geom/chapter.xml b/zh_TW.UTF-8/books/handbook/geom/chapter.xml
new file mode 100644
index 0000000000..b8a44254ca
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/geom/chapter.xml
@@ -0,0 +1,356 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+ $FreeBSD$
+ Original revision: 1.21
+
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="GEOM">
+ <info><title>GEOM: Modular Disk Transformation Framework</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="GEOM-synopsis">
+ <title>概述</title>
+
+ <indexterm>
+ <primary>GEOM</primary>
+ </indexterm>
+ <indexterm>
+ <primary>GEOM Disk Framework</primary>
+ <see>GEOM</see>
+ </indexterm>
+
+ <para>本章涵蓋如何在 &os; 的 GEOM 架構下使用磁碟,
+ 包含用來設定幾種常用的 <acronym role="Redundant Array of Inexpensive Disks,磁碟陣列系統">RAID</acronym>
+ 的控制工具。本章不會深入探討 GEOM 如何處理底層的 I/O,這類資訊請參考
+ &man.geom.4; 及相關的 SEE ALSO 部份。本章也非 <acronym>RAID</acronym>
+ 設定指南,在這裡只會討論目前 GEOM 支援的 <acronym>RAID</acronym> 模式。
+ </para>
+
+ <para>讀完這章,您將了解︰</para>
+ <itemizedlist>
+ <listitem>
+ <para>透過 GEOM 可支援哪些模式的 <acronym>RAID</acronym>。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何使用基本工具來配置、操作、維護不同模式的
+ <acronym>RAID</acronym>。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何透過 GEOM 來完成鏡射(mirror)、分散連結(stripe)、加密(encrypt)
+ 、遠端連接磁碟等。</para>
+ </listitem>
+
+ <listitem>
+ <para>當 GEOM 架構下的磁碟發生問題,如何排除。</para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>在開始閱讀這章之前,您需要︰</para>
+
+
+ <itemizedlist>
+ <listitem>
+ <para>了解 &os; 如何看待磁碟(<xref linkend="disks"/>) 。</para>
+ </listitem>
+
+ <listitem>
+ <para>知道如何設定、安裝新的 &os; 核心
+ (<xref linkend="kernelconfig"/>) 。</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="GEOM-intro">
+ <title>GEOM 導論</title>
+
+ <para>GEOM 透過 privoder(即 <filename>/dev/</filename>
+ 下的特殊裝置檔案) 來操控 classes(如 Master Boot Records、
+ <acronym>BSD</acronym> labels 等) 。GEOM 支援多種軟體
+ <acronym>RAID</acronym> 配置,透過 GEOM 存取時,
+ 作業系統和應用程式不會意識到 GEOM 存在。</para>
+ </sect1>
+
+ <sect1 xml:id="GEOM-striping">
+ <info><title>RAID0 - 分散連結(striping)</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Written by </contrib></author>
+ <author><personname><firstname>Murray</firstname><surname>Stokely</surname></personname></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm>
+ <primary>GEOM</primary>
+ </indexterm>
+ <indexterm>
+ <primary>分散連結(Striping)</primary>
+ </indexterm>
+
+ <para>分散連結(striping) 可用來連結多個磁碟成為一大塊空間。
+ 很多時候硬體控制器可以完成這件事,不過 GEOM 也提供了軟體版本的
+ <acronym>RAID</acronym>0,也就是分散連結(striping)。</para>
+
+ <para>在 <acronym>RAID</acronym>0 裡,資料會被切分成很多塊,
+ 再分散寫入全部的磁碟。例如要寫入 256k 的資料到單一磁碟,在
+ 四個磁碟的 <acronym>RAID</acronym>0 中可同時寫入 64k 到四個磁碟裡,
+ 因此可大幅提升 I/O 效能。如果使用更多的磁碟控制器,
+ I/O 效能可再提升。</para>
+
+ <para>由於讀或寫時會同步交錯對許多磁碟進行 I/O 處理,因此
+ <acronym>RAID</acronym>0 的每個磁碟必須大小一樣。</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="geom/striping" align="center"/>
+ </imageobject>
+
+ <textobject>
+ <phrase>Disk Striping Illustration</phrase>
+ </textobject>
+ </mediaobject>
+
+ <procedure>
+ <title>用未格式化的 ATA 磁碟來建立分散連結(striping)</title>
+
+ <step><para>載入 <filename>geom_stripe</filename>
+ kernel module:</para>
+
+ <screen>&prompt.root; <userinput>kldload geom_stripe.ko</userinput></screen>
+ </step>
+
+ <step><para>確定掛載點(mount point)存在。
+ 如果想用分散連結(striping)的空間做為根目錄(root partition,即 <filename>/</filename> ),
+ 則先用個暫時的掛載點,如
+ <filename>/mnt</filename>:</para>
+
+ <screen>&prompt.root; <userinput>mkdir /mnt</userinput></screen>
+ </step>
+
+
+<step><para>確認要用來分散連結(striping)的裝置名稱,接著建立新的分散連結(striping)。
+ 例如下面的指令會分散連結(striping)兩個未使用、尚未分割區的 <acronym>ATA</acronym>
+ 磁碟(<filename>/dev/ad2</filename> 和
+ <filename>/dev/ad3</filename>) :</para>
+ <screen>&prompt.root; <userinput>
+ gstripe label -v st0 /dev/ad2 /dev/ad3</userinput></screen>
+
+ <screen>&prompt.root; <userinput>gstripe label -v st0 /dev/ad2 /dev/ad3</userinput></screen>
+
+<!--
+ <para>A message should be returned explaining that meta data has
+ been stored on the devices.
+XXX: What message? Put it inside the screen output above.
+-->
+ </step>
+
+ <step><para>用下面的指令來建立分割區表(partition table):</para>
+
+ <screen>&prompt.root; <userinput>bsdlabel -wB /dev/stripe/st0</userinput></screen>
+
+ </step>
+
+ <step><para>除了先前建立的 <filename>st0</filename> ,這個步驟還會在
+ <filename>/dev/stripe</filename> 下新增兩個裝置:
+ <filename>st0a</filename> 和 <filename>st0c</filename>。
+ 利用 <command>newfs</command> 指令可以在
+ <filename>st0a</filename> 建立檔案系統:</para>
+
+ <screen>&prompt.root; <userinput>newfs -U /dev/stripe/st0a</userinput></screen>
+
+ <para>螢幕上會有一堆數字傾瀉而過,幾秒鐘後就會完成。此時空間已建立,
+ 可用來掛載使用了。</para>
+ </step>
+ </procedure>
+
+ <para>下面指令可用來手動掛載分散連結(striping)空間:</para>
+
+ <screen>&prompt.root; <userinput>mount /dev/stripe/st0a /mnt</userinput></screen>
+
+ <para>如果要在開機時自動掛載,在 <filename>/etc/fstab</filename>
+ 加入這塊空間的資訊:</para>
+
+ <screen>&prompt.root; <userinput>echo "/dev/stripe/st0a /mnt ufs rw 2 2" \</userinput>
+ <userinput>&gt;&gt; /etc/fstab</userinput></screen>
+
+ <para>而 <filename>geom</filename> kernel module 必須在系統初始化時自動載入,
+ 因此在 <filename>/boot/lodaer.conf</filename> 加入一行:</para>
+
+ <screen>&prompt.root; <userinput>echo 'geom_stripe_load="YES"' &gt;&gt; /boot/loader.conf</userinput></screen>
+
+ </sect1>
+
+ <sect1 xml:id="GEOM-mirror">
+ <title>RAID1 - 鏡射(Mirroring)</title>
+
+ <indexterm>
+ <primary>GEOM</primary>
+ </indexterm>
+ <indexterm>
+ <primary>磁碟鏡射(Disk Mirroring)</primary>
+ </indexterm>
+
+ <para>許多企業或個人用戶用鏡射(mirroring) 來不中斷系統進行備份。
+ 鏡射簡單來說就是在 B 磁碟上重覆一份 A 磁碟的資料,
+ 或者 C+D 磁碟重覆 A+B 磁碟的資料。不論設定如何,
+ 最重要的是所有磁碟或分割區(partition) 上的資料都會被複製,
+ 之後可在不中斷服務的情況下復原、備份資料,使儲存的資料更安全。</para>
+
+ <para>開始之前,請先確定系統上有兩個容量相同的磁碟,
+ 後面的範例假設這兩顆磁碟是 direct access(&man.da.4;)
+ <acronym>SCSI</acronym> 磁碟。</para>
+
+ <para>首先我們假設 &os; 安裝在第一個磁碟上,且只有兩個分割區(partition)。
+ 其中一個是交換分割區(swap partition,大小為 <acronym>RAM</acronym>
+ 的兩倍),而剩下的全用於根目錄(即 <filename>/</filename>,
+ root file system)。當然要在不同掛載點(mount point) 切出更多分割區
+ (partition) 也可以,不過難度會大幅提升,因為必須手動操作 &man.bsdlabel.8;
+ 和 &man.fdisk.8; 工具。</para>
+
+ <para>重開機並等到系統完全初始化完畢,用 <systemitem class="username">root</systemitem>
+ 登入。</para>
+
+ <para>建立 <filename>/dev/mirror/gm</filename> 裝置並以
+ <filename>/dev/da1</filename> 連結:</para>
+
+ <screen>&prompt.root; <userinput>gmirror label -vnb round-robin gm0 /dev/da1</userinput></screen>
+
+ <para>這時系統應該會回應:</para>
+ <screen>
+Metadata value stored on /dev/da1.
+Done.</screen>
+
+ <para>初始化 GEOM,這動作會自動載入
+ <filename>/boot/kernel/geom_mirror.ko</filename> kernel module:</para>
+
+ <screen>&prompt.root; <userinput>gmirror load</userinput></screen>
+
+ <note>
+ <para>這動作應該會在 <filename>/dev/mirror</filename>
+ 下建立 <filename>gm0</filename> 裝置結點(device node)。</para>
+ </note>
+
+ <para>在這個新建的 <filename>gm0</filename> 裝置上安置一般的
+ <command>fdisk</command> label 和開機磁區:</para>
+
+ <screen>&prompt.root; <userinput>fdisk -vBI /dev/mirror/gm0</userinput></screen>
+
+ <para>接著安置 <command>bsdlabel</command> 資訊:</para>
+
+ <screen>&prompt.root; <userinput>bsdlabel -wB /dev/mirror/gm0s1</userinput></screen>
+
+ <note>
+ <para>如果存在多個 slice 和分割區(partition),
+ 記得修改上兩指令的參數,且另一個磁碟上的 slice 和分割區(partition)
+ 大小必須相同。</para>
+ </note>
+
+ <para>用 &man.newfs.8; 工具在 <filename>gm0s1a</filename>
+ 裝置結點建立預設的檔案系統:</para>
+
+ <screen>&prompt.root; <userinput>newfs -U /dev/mirror/gm0s1a</userinput></screen>
+
+ <para>系統會印出許多資訊和一大堆數字,這是正常的。
+ 確認是否有認何錯誤,接著就可以將這個裝置掛載到
+ <filename>/mnt</filename> 掛載點(mount mount):</para>
+
+ <screen>&prompt.root; <userinput>mount /dev/mirror/gm0s1a /mnt</userinput></screen>
+
+ <para>接著將原本開機磁碟的資料搬移到新的檔案系統
+ (<filename>/mnt</filename>)。範例是用
+ &man.dump.8; 和 &man.restore.8; ,不過用 &man.dd.1; 也可以。</para>
+
+ <screen>&prompt.root; <userinput>dump -L -0 -f- / |(cd /mnt &amp;&amp; restore -r -v -f-)</userinput></screen>
+
+ <para>執行上述指令時,只要將恰當的檔案系統掛在正確的位置,應該就能成功。
+ </para>
+
+ <para>接著編輯 <filename>/mnt/etc/fstab</filename>
+ 檔將 swap file 那行移除或註解起來。
+ <footnote>
+ <para>請注意,將 <filename>fstab</filename> 的 swap file
+ 那行註解起來,通常表示:您得用別的方法來重建 swap。詳情請參考
+ <xref linkend="adding-swap-space"/>。</para>
+ </footnote>請參考下面範例,並根據新磁碟修改其它的檔案系統資訊:</para>
+
+ <programlisting># Device Mountpoint FStype Options Dump Pass#
+#/dev/da0s2b none swap sw 0 0
+/dev/mirror/gm0s1a / ufs rw 1 1</programlisting>
+
+ <para>在目前的根目錄及新的根目錄建立 <filename>boot.conf</filename> 檔案,
+ 這個檔案可以『幫助』系統 <acronym>BIOS</acronym> 開機:</para>
+
+ <screen>&prompt.root; <userinput>echo "1:da(1,a)/boot/loader" &gt; /boot.config</userinput></screen>
+
+ <screen>&prompt.root; <userinput>echo "1:da(1,a)/boot/loader" &gt; /mnt/boot.config</userinput></screen>
+
+ <note>
+ <para>在兩個根目錄上都新增檔案是為了安全起見,
+ 如果因為某些原因新的根目錄無法開機,至少還可用原本的根目錄。</para>
+ </note>
+
+ <para>接著在 <filename>/boot/loader.conf</filename> 新增兩行:</para>
+
+ <screen>&prompt.root; <userinput>echo 'geom_mirror_load="YES"' &gt;&gt; /mnt/boot/loader.conf</userinput></screen>
+
+ <para>這會指示 &man.loader.8; 在開機時載入
+ <filename>geom_mirror.ko</filename> kernel module。</para>
+
+ <para>重開機:</para>
+
+ <screen>&prompt.root; <userinput>shutdown -r now</userinput></screen>
+
+ <para>如果一切順利,系統應該會從 <filename>gm0s1a</filename> 裝置開機,
+ 接下來出現 <command>login</command> 提示畫面。如果出錯了,
+ 請參閱下面 Troubleshooting 那一節。 現在可以將
+ <filename>da0</filename> 磁碟加入 <filename>gm0</filename>
+ 裝置:</para>
+
+ <screen>&prompt.root; <userinput>gmirror configure -a gm0</userinput>
+&prompt.root; <userinput>gmirror insert gm0 /dev/da0</userinput></screen>
+
+ <para>其中 <option>-a</option> 旗標告訴 &man.gmirror.8;
+ 使用「自動同步(automatic synchronization)」,例如自動同步寫入磁碟的動作。
+ manual 說明了如何重建、取代磁碟等,不過 manual 裡的範例是用
+ <filename>data</filename> 而不是 <filename>gm0</filename>。</para>
+
+ <sect2>
+ <title>Troubleshooting</title>
+
+ <sect3>
+ <title>系統無法開機</title>
+
+ <para>如果開機提示類似這樣:</para>
+
+ <programlisting>ffs_mountroot: can't find rootvp
+Root mount failed: 6
+mountroot&gt;</programlisting>
+
+ <para>請用機器面板上的 Power 按鈕或 reset 按鈕來重開機,並在開機選單選 (6),
+ 這樣子,系統就會進入 &man.loader.8;
+ 交談模式。這時候,請照下面指令來手動載入所需的 kernel module
+ ,也就是 <filename>geom_mirror.ko</filename>:</para>
+
+ <screen>OK? <userinput>load geom_mirror.ko</userinput>
+OK? <userinput>boot</userinput></screen>
+
+ <para>如果這樣成功了的話,表示因為某些原因無法自動載入 kernel module。
+ 請將:</para>
+
+ <programlisting>options GEOM_MIRROR</programlisting>
+
+ <para>加入到核心設定檔(kernel configuration file),重編並安裝核心。
+ 這應該能解決這個問題。</para>
+ </sect3>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/install/Makefile b/zh_TW.UTF-8/books/handbook/install/Makefile
new file mode 100644
index 0000000000..9ca79617b2
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/install/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= install/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/install/chapter.xml b/zh_TW.UTF-8/books/handbook/install/chapter.xml
new file mode 100644
index 0000000000..400158415e
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/install/chapter.xml
@@ -0,0 +1,4503 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.381
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="install">
+ <info><title>安裝 FreeBSD</title>
+ <authorgroup>
+ <author><personname><firstname>Jim</firstname><surname>Mock</surname></personname><contrib>Restructured, reorganized, and parts
+ rewritten by </contrib></author>
+ </authorgroup>
+
+ <authorgroup>
+ <author><personname><firstname>Randy</firstname><surname>Pratt</surname></personname><contrib>The sysinstall walkthrough, screenshots, and general
+ copy by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <sect1 xml:id="install-synopsis">
+ <title>概述</title>
+
+ <indexterm><primary>installation</primary></indexterm>
+
+ <para>FreeBSD 提供一個簡單好用的文字介面安裝程式,叫做
+ <application>sysinstall</application>。 這是 FreeBSD 預設使用的安裝程式
+ 。協力廠商若有意願的話,也可以改用自己的安裝程式。
+ 本章將說明如何使用 <application>sysinstall</application> 來安裝
+ FreeBSD。</para>
+
+ <para>讀完這章,您將了解︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>如何製作 FreeBSD 安裝片</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD 對硬碟的使用及配置。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何啟動 <application>sysinstall</application> 程式。</para>
+ </listitem>
+
+ <listitem>
+ <para>在執行 <application>sysinstall</application>
+ 時會問的相關問題有哪些、這些問題的意思為何、以及該如何回答。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>在開始閱讀這章之前,您需要︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>閱讀要安裝的 FreeBSD 版本所附之硬體支援表,
+ 以確定您的硬體有沒有被支援。</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <para>一般來說,此安裝說明是針對 &i386; (相容的 PC 機種)
+ 架構的電腦。 如果有其他架構(比如 Alpha)的安裝說明,我們會一併列出。
+ 雖然本文件會常常更新,但有可能與您安裝版本上所附的說明文件有些許出入。
+ 在此,我們建議您把本說明文章當作一般的安裝參考原則就好。</para>
+ </note>
+
+ </sect1>
+
+ <sect1 xml:id="install-hardware">
+ <title>硬體需求</title>
+
+ <sect2 xml:id="install-hardware-minimal">
+ <title>最低需求</title>
+
+ <para>安裝 &os; 的硬體方面最低需求,依各 &os;
+ 版本與硬體架構差別而有所不同。</para>
+
+ <para>關於安裝所需的最低需求,可在 &os; 網站的 <link xlink:href="http://www.FreeBSD.org/releases/index.html">Release
+ Information</link> 找相關的 Installation Notes 說明。
+ 接下來的章節會有相關說明整理。
+ 根據安裝 &os; 的方式不同,可能會需要軟碟機或光碟機,
+ 或某些情況則是要網路卡。 這些部份會在 <xref linkend="install-floppies"/> 有介紹。</para>
+
+ <sect3>
+ <title>&os;/&arch.i386; 及 &os;/&arch.pc98; 架構</title>
+
+ <para>&os;/&arch.i386; 及 &os;/&arch.pc98; 兩種版本均須 486 或更好的處理器,
+ 以及至少 24&nbsp;MB 的 RAM、至少 150&nbsp;MB 的硬碟空間,
+ 才能進行最小安裝。</para>
+
+ <note>
+ <para>對老舊硬體而言,在大部份情況裝更多的 RAM
+ 與更大的硬碟空間,會比使用更快的 CPU 更有用。</para>
+ </note>
+ </sect3>
+
+ <sect3>
+ <title>&os;/&arch.alpha; 架構</title>
+
+ <para>若要裝 &os;/&arch.alpha;,則需確認該機型是否有支援
+ (請參閱 <xref linkend="install-hardware-supported"/>)
+ 且必須整顆硬碟皆給 &os; 使用。
+ 目前無法同時與其他作業系統共存。 這硬碟須接到 SRM
+ 韌體有支援的 SCSI controller 上,或者 IDE 硬碟
+ (該機型的 SRM 有支援可從 IDE 硬碟開機)。</para>
+
+ <para>此外,還需該機型的 SRM console firmware。
+ 有些機型可以選擇 AlphaBIOS (or ARC) firmware 或 SRM 來用。
+ 若沒有的話,則需從硬體廠商的網站去下載新的韌體。</para>
+
+ <note>
+ <para>從 &os;&nbsp;7.0 就不再支援 Alpha。
+ &os;&nbsp;6.<replaceable>X</replaceable> 系列則是此架構的最後支援
+ 。</para>
+ </note>
+ </sect3>
+
+ <sect3>
+ <title>&os;/&arch.amd64; 架構</title>
+
+ <para>有兩種 CPU 能跑 &os;/&arch.amd64;。 第一種是包括 &amd.athlon;64
+ 、&amd.athlon;64-FX、&amd.opteron; 或更好的 CPU。</para>
+
+ <para>第二種則是 &intel; EM64T 架構的 CPU,這些也可以用
+ &os;/&arch.amd64;。 這些 CPU 包括了 &intel;&nbsp;&core;&nbsp;2 Duo
+ 、Quad、Extreme 系列以及 &intel;&nbsp;&xeon; 3000、5000、7000
+ 相關系列的 CPU。</para>
+
+ <para>若主機板晶片組為 nVidia nForce3 Pro-150,則
+ <emphasis>必須</emphasis> 調整 BIOS 設定,將 IO APIC 停用才行。
+ 若找不到這選項,那可能就是找 ACPI 停用。
+ 因為 Pro-150 晶片組有個 bug,目前我們尚無找到堪解之道。</para>
+ </sect3>
+
+ <sect3>
+ <title>&os;/&arch.sparc64; 架構</title>
+
+ <para>若要裝 &os;/&arch.sparc64;,則需確認該機型是否有支援
+ (請參閱 <xref linkend="install-hardware-supported"/>)。</para>
+
+ <para>&os;/&arch.sparc64; 必須使用整顆硬碟,
+ 因為無法同時與其他作業系統共存。</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="install-hardware-supported">
+ <title>有支援的硬體</title>
+
+ <para>&os; 每次 release 時都會有附上 &os; Hardware Notes
+ 來說明有支援的硬體列表。
+ 通常這份文件可在光碟或 FTP 的最上層目錄找到,也就是名為
+ <filename>HARDWARE.TXT</filename> 的檔案。
+ 此外,在 <application>sysinstall</application> 的 documentation
+ 選項內也可以看到。
+ 每次 &os; release 時該列表會依各不同架構,
+ 而列出相關已知有支援的硬體。 在 &os; 網站的 <link xlink:href="http://www.FreeBSD.org/releases/index.html">Release
+ Information</link> 頁可以找到各不同 release
+ 版本與各架構上的硬體支援列表。</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="install-pre">
+ <title>安裝前的準備工作</title>
+
+ <sect2 xml:id="install-inventory">
+ <title>列出您電腦的硬體清單</title>
+
+ <para>在安裝 FreeBSD 之前,您應該試著將您電腦中的硬體清單列出來。
+ FreeBSD 安裝程式會將這些硬體(硬碟、網路卡、光碟機等等)
+ 以型號及製造廠商列出來。
+ FreeBSD 也會嘗試為這些硬體找出最適當的 IRQ 及 IO port 的設定。
+ 但是因為 PC 的硬體種類實在太過複雜,這個步驟不一定保證絕對成功。
+ 這時,您就可能需要手動更改有問題的設定值哩。</para>
+
+ <para>如果您已裝了其它的作業系統,如:
+ &windows; 或 Linux,那麼可先由這些系統所提供的工具,
+ 來查看這些硬體設定值是怎麼設定的。
+ 若真的沒辦法確定某些卡用什麼設定值,
+ 那麼可以檢查看看卡上面所標示的東西,說不定它的設定已有標示在卡上。
+ 常用的 IRQ 號碼為 3、5 以及 7;而 IO 埠的值通常以 16 進位表示,
+ 例如 0x330。</para>
+
+ <para>建議您在安裝 FreeBSD 之前,把這些資料列印或抄錄下來做成表格,
+ 也許會較有用喔,例如:</para>
+
+ <table pgwide="1" frame="none">
+ <title>硬體清單(舉例)</title>
+
+ <tgroup cols="4">
+ <colspec colwidth="2*"/>
+ <colspec colwidth="1*"/>
+ <colspec colwidth="1*"/>
+ <colspec colwidth="4*"/>
+ <thead>
+ <row>
+ <entry>硬體名稱</entry>
+
+ <entry>IRQ</entry>
+
+ <entry>IO port(s)</entry>
+
+ <entry>備註</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>第一顆 IDE 硬碟</entry>
+
+ <entry>N/A</entry>
+
+ <entry>N/A</entry>
+
+ <entry>40&nbsp;GB,Seagate 製造,接在第一條 IDE 排線的 master
+ </entry>
+ </row>
+
+ <row>
+ <entry>CDROM</entry>
+
+ <entry>N/A</entry>
+
+ <entry>N/A</entry>
+
+ <entry>接在第一條 IDE 排線的 slave</entry>
+ </row>
+
+ <row>
+ <entry>第二顆硬碟</entry>
+
+ <entry>N/A</entry>
+
+ <entry>N/A</entry>
+
+ <entry>20&nbsp;GB,IBM 製造,接在第二條 IDE 排線的 master</entry>
+ </row>
+
+ <row>
+ <entry>第一個 IDE controller</entry>
+
+ <entry>14</entry>
+
+ <entry>0x1f0</entry>
+
+ <entry/>
+ </row>
+
+ <row>
+ <entry>網路卡</entry>
+
+ <entry>N/A</entry>
+
+ <entry>N/A</entry>
+
+ <entry>&intel; 10/100</entry>
+ </row>
+
+ <row>
+ <entry>數據機</entry>
+
+ <entry>N/A</entry>
+
+ <entry>N/A</entry>
+
+ <entry>&tm.3com; 56K faxmodem,接在 COM1</entry>
+ </row>
+
+ <row>
+ <entry>&hellip;</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>硬體清單完成之後,就需針對你所要裝的 &os; 版本之硬體需求,
+ 來檢查是否有支援。</para>
+ </sect2>
+
+ <sect2>
+ <title>備份您的資料</title>
+
+ <para>如果要裝的電腦上面存有重要資料,那麼在安裝 FreeBSD 前,
+ 請確定您已經將這些資料備份了,並且先測試過這些備份檔是否沒有問題。
+ FreeBSD 安裝程式在要寫入任何資料到您的硬碟前,都會先提醒您確認,
+ 一旦您確定要寫入,那麼之後就再也沒有反悔的機會囉。</para>
+ </sect2>
+
+ <sect2 xml:id="install-where">
+ <title>決定要將 FreeBSD 安裝到哪裡</title>
+
+ <para>如果您想讓 FreeBSD 直接使用整顆硬碟,那麼請直接跳到下一節。</para>
+
+ <para>然而,如果您想要 FreeBSD 跟既有的系統並存,那麼,
+ 您必須對硬碟的資料分佈方式有深入的了解,以及其所造成的影響。</para>
+
+ <sect3 xml:id="install-where-i386">
+ <title>&os;/&arch.i386; 架構的硬碟配置模式</title>
+
+ <para>PC 上的硬碟可以被細分為許多分散區(chunk)。這些區域叫做
+ <firstterm>分割區(Partitions)</firstterm>。
+ 由於 &os; 內部也有 partition,名稱可能很容易造成混淆,
+ 因此通常在 &os; 這邊會稱呼這些磁碟分散區為 disk slices 或簡稱
+ slices。 舉例來說,FreeBSD 的 <command>fdisk</command>
+ 的對象是針對 PC 硬碟的 slice 而非 partition。 因為
+ PC 本身先天設計,每個硬碟最多可以有 4 個分割區,而這些分割叫做
+ <firstterm>主要分割區(Primary Partitions)</firstterm>。
+ 為了突破這個限制,以便能使用更多的分割區,就有了新的分割區類型,叫作:
+ <firstterm>延伸分割區(Extended Partition)</firstterm>。
+ 每個硬碟就只能有一個延伸分割區。
+ 然而,在延伸分割區裡面可以建立許多個特殊分割區,叫作
+ <firstterm>邏輯分割區(Logical Partitions)</firstterm>。</para>
+
+ <para>每種分割區都有其 <firstterm>分割區代號(Partition ID)</firstterm>
+ 用以區別每種分割區的資料類型。
+ 而 FreeBSD 分割區代號是 <literal>165</literal>。</para>
+
+ <para>一般來講,每種作業系統都會有自己獨特的方式來區別分割區。
+ 舉例: DOS 及其之後的作業系統,比如 &windows;
+ 會分配給每個主要分割區及邏輯分割區 1 個
+ <firstterm>磁碟代號(drive letter)</firstterm>,從
+ <filename>C:</filename> 開始。</para>
+
+ <para>FreeBSD 必須安裝在主要分割區。
+ FreeBSD 可以在這個分割區上面存放資料或是您建立的任何檔案。
+ 然而,如果您有很多顆硬碟,也可以在這些(或部份)硬碟建立 FreeBSD 分割區。
+ 安裝 FreeBSD 的時候,必須至少要有 1 個分割區給 FreeBSD 使用,
+ 這個分割區可以是尚未使用的分割區,或是現存的分割區
+ (但上面的資料不打算繼續使用)。</para>
+
+ <para>如果已經用完了磁碟上所有的分割區,
+ 那麼您必須使用其他作業系統所提供的工具
+ (像是 DOS or &windows; 上的 <command>fdisk</command>)
+ 來騰出一個分割區給 FreeBSD 用。</para>
+
+ <para>如果有多餘的分割區,也可以使用它。
+ 但使用前,您可能需要先整理一下這些分割區。</para>
+
+ <para>FreeBSD最小安裝需要約 100&nbsp;MB 的空間,但是這只是『最小安裝』,
+ 幾乎沒剩下多少空間來存放您自己的檔案。
+ 較理想的(不含圖形介面)最小安裝是約
+ 250&nbsp;MB,或者是 350&nbsp;MB 左右(包含圖形介面)。
+ 還需要安裝其他的套件軟體,那麼將需要更多的硬碟空間。</para>
+
+ <para>您可以使用商業軟體像是
+ <application>&partitionmagic;</application> 或免費自由工具像是
+ <application>GParted</application> 來重新調整分割區空間,
+ 來給 FreeBSD 用的空間。FreeBSD 光碟、FTP 上面的
+ <filename>tools</filename> 目錄包含兩個免費的工具,
+ 也可以達成這個工作,叫作:<application>FIPS</application> 及
+ <application>PResizer</application>。
+ 這些工具的說明文件可以在同個目錄內找到。
+ <application>FIPS</application>、
+ <application>PResizer</application> 和
+ <application>&partitionmagic;</application> 可以重新調整在 &ms-dos; 到
+ &windows; ME 所使用的 <acronym>FAT16</acronym> 及
+ <acronym>FAT32</acronym> 分割區大小。 目前已知可更改
+ <acronym>NTFS</acronym> 分割區的有
+ <application>&partitionmagic;</application> 及
+ <application>GParted</application> 這兩種工具程式。
+ <application>GParted</application>在許多 Linux distributions 的 Live CD
+ 都有提供,像是 <link xlink:href="http://www.sysresccd.org/">SystemRescueCD</link>。</para>
+
+ <para>目前已知 &microsoft; Vista 分割區的重新調整大小會有問題。
+ 在做上述類似動作時,請記得手邊要有 Vista 安裝光碟以免萬一。
+ 此外,強烈建議先做磁碟維護,以及現有資料備份。</para>
+
+ <warning>
+ <para>不當的使用這些工具,可能會刪除所有硬碟上的資料。
+ 在使用這些工具前,請確定您已有先備份好資料。</para>
+ </warning>
+
+ <example>
+ <title>使用現有的分割區</title>
+
+ <para>假設您只有一個 4&nbsp;GB 的硬碟,而且已經裝了 &windows;
+ ,然後將這顆硬碟分成兩個磁碟代號:<filename>C:</filename> 及
+ <filename>D:</filename>,每個大小為 2&nbsp;GB 。
+ <filename>C:</filename> 槽上放了 1&nbsp;GB 的資料,
+ 而 <filename>D:</filename> 槽上放了 0.5&nbsp;GB 的資料。</para>
+
+ <para>這表示硬碟上有兩個分割區,每個磁碟代號槽都是分割區。
+ 您可以把所有放在 <filename>D:</filename> 的資料,都移動到
+ <filename>C:</filename>,這樣就空出了第二個分割區可以給
+ FreeBSD 使用。</para>
+ </example>
+
+ <example>
+ <title>縮減現有的分割區</title>
+
+ <para>假設您只有一個 4&nbsp;GB 硬碟,而且已經裝了 &windows;。
+ 在安裝 &windows; 時把 4&nbsp;GB 都給 <filename>C:</filename>
+ 槽,並且現在已經用了 1.5&nbsp;GB 空間,而你想將剩下空間的
+ 2&nbsp;GB 給 FreeBSD 使用。</para>
+
+ <para>如此一來,為了裝 FreeBSD,你必須在以下兩種方式二選一:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>備份 &windows; 資料,然後重裝 &windows;,
+ 並在安裝 &windows; 時給 2&nbsp;GB 的分割空間。</para>
+ </listitem>
+
+ <listitem>
+ <para>使用上述的工具,像是
+ <application>&partitionmagic;</application>,來重新調整 &windows;
+ 所用的分割區大小。</para>
+ </listitem>
+ </orderedlist>
+ </example>
+
+ </sect3>
+
+ <sect3>
+ <title>Alpha 架構的磁碟配置模式</title>
+
+ <para>在 Alpha 上,您必須使用一整顆硬碟給 FreeBSD,
+ 沒有辦法在同顆硬碟上跟其他作業系統共存。 依不同型號的 Alpha
+ 機器,您的硬碟可以是 SCSI 或 IDE 硬碟,
+ 只要您的機器可以從這些硬碟開機就可以。</para>
+
+ <para>按照 Digital / Compaq 使用手冊的編排風格,
+ 所有 SRM 輸入的部分都用大寫表示。 注意:SRM 大小寫有別。</para>
+
+ <para>要得知您磁碟的名稱以及型號,可以在 SRM console 提示下使用
+ <literal>SHOW DEVICE</literal> 命令:</para>
+
+ <screen>&gt;&gt;&gt;<userinput>SHOW DEVICE</userinput>
+dka0.0.0.4.0 DKA0 TOSHIBA CD-ROM XM-57 3476
+dkc0.0.0.1009.0 DKC0 RZ1BB-BS 0658
+dkc100.1.0.1009.0 DKC100 SEAGATE ST34501W 0015
+dva0.0.0.0.1 DVA0
+ewa0.0.0.3.0 EWA0 00-00-F8-75-6D-01
+pkc0.7.0.1009.0 PKC0 SCSI Bus ID 7 5.27
+pqa0.0.0.4.0 PQA0 PCI EIDE
+pqb0.0.1.4.0 PQB0 PCI EIDE</screen>
+
+ <para>例子中機器為 Digital Personal Workstation 433au,
+ 並且顯示出此機器有連接三個磁碟機。 第一個是 CDROM,叫做
+ <filename>DKA0</filename> ;另外兩個是磁碟機, 分別叫做:
+ <filename>DKC0</filename> 及 <filename>DKC100</filename>。
+ </para>
+
+ <para>磁碟機的名稱中有 <filename>DKx</filename>
+ 字樣的是 SCSI 硬碟。例如: <filename>DKA100</filename>
+ 表示是 SCSI 硬碟,其 SCSI ID 為 1, 位在第一個 SCSI 匯流排(A);
+ 而 <filename>DKC300</filename> 表示是 SCSI 硬碟,
+ 其 SCSI ID 為 3,位於第三個 SCSI 匯流排(C)。
+ 裝置名稱 <filename>PKx</filename> 則為 SCSI 控制卡。
+ 由上述 <literal>SHOW DEVICE</literal> 的結果看來,
+ SCSI 光碟機也被視為是 SCSI 硬碟的一種。</para>
+
+ <para>若為 IDE 硬碟的話,名稱會有 <filename>DQx</filename> 字樣,
+ 而 <filename>PQx</filename> 則表示相對應的 IDE 磁碟控制器。
+ </para>
+
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>整理你的網路設定資料</title>
+
+ <para>如果想透過網路( FTP 站或 NFS)安裝 FreeBSD,
+ 那麼就必須知道您的網路設定。
+ 在安裝 FreeBSD 的過程中將會提示您輸入這些資訊,以順利完成安裝過程。
+ </para>
+
+ <sect3>
+ <title>使用乙太網路(Ethernet)或 Cable/DSL 數據機上網</title>
+
+ <para>若使用乙太網路,或是要透過 Cable/DSL 數據機上網,
+ 那麼您必須準備下面的資訊:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>IP 位址</para>
+ </listitem>
+
+ <listitem>
+ <para>預設 Gateway(閘道) 的 IP 位址</para>
+ </listitem>
+
+ <listitem>
+ <para>Hostname(機器名稱)</para>
+ </listitem>
+
+ <listitem>
+ <para>DNS 伺服器的 IP 位址</para>
+ </listitem>
+
+ <listitem>
+ <para>Subnet Mask</para>
+ </listitem>
+ </orderedlist>
+
+ <para>若不知道這些資訊,您可以詢問系統管理者或是您的 ISP 業者。
+ 他們可能會說這些資訊會由 <firstterm>DHCP</firstterm> 自動指派;
+ 如果是這樣的話,請記住這一點就可以了。</para>
+ </sect3>
+
+ <sect3>
+ <title>使用數據機上網</title>
+
+ <para>若由一般的數據機撥接上網,您仍然可以安裝 FreeBSD,
+ 只是會需要很長的時間。</para>
+
+ <para>您必須知道:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>撥接到 ISP 的電話號碼。</para>
+ </listitem>
+
+ <listitem>
+ <para>您的數據機是連到哪個 COM 埠。</para>
+ </listitem>
+
+ <listitem>
+ <para>您撥接到 ISP 所用的帳號跟密碼。</para>
+ </listitem>
+ </orderedlist>
+ </sect3>
+ </sect2>
+ <sect2>
+ <title>查閱 FreeBSD 勘誤表(Errata)</title>
+
+ <para>雖然我們盡力使得每個 FreeBSD 發行版本都很穩定,
+ 但是過程中仍然不免有時會發生錯誤。
+ 在某些很罕見的情形下,這些錯誤會影響到安裝的過程。
+ 當發現這些錯誤且修正後,會將它們列在
+ <link xlink:href="http://www.FreeBSD.org/releases/&rel.current;R/errata.html">
+ FreeBSD 勘誤表(Errata)</link> 中。 在您安裝 FreeBSD
+ 前,應該先看看勘誤表中有沒有什麼問題會影響到您的安裝。</para>
+
+ <para>關於所有發行版本的資訊(包括勘誤表),可以在 <link xlink:href="&url.base;/index.html">FreeBSD 網站</link> 的
+ <link xlink:href="&url.base;/releases/index.html">發行情報(release information)
+ </link> 找到。</para>
+ </sect2>
+
+ <sect2>
+ <title>準備好 FreeBSD 安裝檔案</title>
+
+ <para>FreeBSD 可以透過下面任何一種安裝來源進行安裝︰</para>
+
+ <itemizedlist>
+ <title>Local Media</title>
+
+ <listitem>
+ <para>CDROM 或 DVD</para>
+ </listitem>
+
+ <listitem>
+ <para>現有的 DOS 分割區</para>
+ </listitem>
+
+ <listitem>
+ <para>SCSI 或 QIC 磁帶。</para>
+ </listitem>
+
+ <listitem>
+ <para>軟碟磁片</para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <title>Network</title>
+
+ <listitem>
+ <para>FTP 站、支援 Passvie 模式的 FTP 站(若您機器在 NAT 內)
+ 、甚至 HTTP proxy 都可以。</para>
+ </listitem>
+
+ <listitem>
+ <para>NFS 伺服器</para>
+ </listitem>
+
+ <listitem>
+ <para>專用(dedicated)的 parallel 或 serial 連線</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>若已經有 FreeBSD 的 CD 或 DVD,但機器不支援從光碟開機的話,
+ 那麼請直接進下一節 (<xref linkend="install-floppies"/>)。</para>
+
+ <para>若沒有 FreeBSD 安裝片的話,那麼請先看 <xref linkend="install-diff-media"/> 這裡會介紹如何準備所需要的安裝片,
+ 照該節步驟弄好後,就可以繼續下一步 <xref linkend="install-start"/>。
+ </para>
+ </sect2>
+
+ <sect2 xml:id="install-floppies">
+ <title>準備好開機磁片</title>
+
+ <para>FreeBSD 安裝流程是要從電腦開機後,進入 FreeBSD 安裝畫面 ——
+ 而不是在其他作業系統上執行程式。
+ 一般來講,電腦都是用裝在硬碟上的作業系統來開機,
+ 也可以用開機磁片來開機;
+ 此外,現在大多數電腦都可以從光碟開機。</para>
+
+ <tip>
+ <para>如果您有 FreeBSD 的 CDROM 或 DVD(無論是用買現成的或是自己燒錄的),
+ 且您的電腦可支援由光碟開機,(通常在 BIOS 中會有
+ <quote>Boot Order</quote> 或類似選項),那麼您就可以跳過此小節。
+ 因為 FreeBSD CDROM 或 DVD 都可以用來開機。</para>
+ </tip>
+
+ <para>請按照下面步驟,以製作開機片:</para>
+
+ <procedure>
+ <step>
+ <title>取得開機片的映像檔(images)</title>
+
+ <para>開機磁片用的映像檔(images)通常會放在光碟片上的
+ <filename>floppies/</filename> 目錄內,
+ 另外也可以從像是下面 FTP 站的 floppies 目錄下載:
+ <literal>ftp://ftp.FreeBSD.org/pub/FreeBSD/releases/&lt;arch&gt;/&lt;version&gt;-RELEASE/floppies/</literal>
+ 。請將『arch』、『version』替換為打算安裝的電腦架構、OS 版本。
+ 例如:想裝的是 &os;/&arch.i386;&nbsp;&rel.current;-RELEASE
+ ,那麼可以到 <uri xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/releases/i386/&rel.current;-RELEASE/floppies/">ftp://ftp.FreeBSD.org/pub/FreeBSD/releases/i386/&rel.current;-RELEASE/floppies/</uri> 下載。</para>
+
+ <para>映像檔(images)的附檔名都是 <filename>.flp</filename>。而
+ <filename>floppies/</filename> 目錄內包含一些不同用途的映像檔
+ (images),這取決於您要裝的 FreeBSD 版本、需求、硬體配備為何。
+ 通常要 4 個映像檔,也就是: <filename>boot.flp</filename>、
+ <filename>kern1.flp</filename>、<filename>kern2.flp</filename>、
+ <filename>kern3.flp</filename>。 若有疑問的話,請翻閱同一目錄下的
+ <filename>README.TXT</filename> 文件檔,以瞭解相關最新注意事項。
+ </para>
+
+ <important>
+ <para>在使用 FTP 下載時,必須使用 <emphasis>binary 模式</emphasis>
+ 進行傳輸。 有些瀏覽器預設是以 <emphasis>text</emphasis> (或
+ <emphasis>ASCII</emphasis>) 模式來傳輸資料,
+ 所以這些錯誤傳輸模式下載的映像檔所做成的磁片,會無法使用。</para>
+ </important>
+ </step>
+
+ <step>
+ <title>準備開機磁片</title>
+
+ <para>每個映像檔都需要一張磁片,並且請避免使用到壞的磁片。
+ 最簡單的檢測方式就是自己先把這些磁片再重新格式化(format)
+ 而不要相信所謂的已格式化的磁片,&windows; 內的 format
+ 在格式化時,並不會告訴你是否有壞軌,
+ 而只會直接將它們標示壞軌而不使用壞軌部分而已。
+ 此外,建議採用全新的磁片來製作安裝片比較保險。</para>
+
+ <important>
+ <para>若在安裝 FreeBSD 的過程中發生當機、
+ 畫面凍結或是其他怪異的現象,首先要懷疑的就是開機磁片是否壞掉。
+ 請用其他的磁片製作映像檔再試試看。</para>
+ </important>
+ </step>
+
+ <step>
+ <title>將映像檔(images)寫入到磁片內</title>
+
+ <para><filename>.flp</filename> 檔並非一般檔案,
+ 不能直接把它複製到磁片上。
+ 事實上它是包含整張磁片所有內容的映像檔(image)。
+ 也就是說,不能純粹複製檔案到磁片上,
+ 而必須使用特別的工具程式,來將映像檔直接寫到磁片上。</para>
+
+ <indexterm><primary>DOS</primary></indexterm>
+ <para>若要用 &ms-dos;/&windows; 來作安裝片的話,那麼可以用
+ <command>fdimage</command> 工具程式來將映像檔,寫到磁片上。</para>
+
+ <para>若您用的是 FreeBSD 光碟的話(假設光碟機代號為
+ <filename>E:</filename> ,那麼請執行類似下面的指令:</para>
+
+ <screen><prompt>E:\&gt;</prompt> <userinput>tools\fdimage floppies\boot.flp A:</userinput></screen>
+
+ <para>請針對每個需要用到的 <filename>.flp</filename> 映像檔,
+ 重複上述的指令(記得更改相關檔名),每次的映像檔完成後,
+ 都需要換另外一片來裝新的映像檔; 請記得:
+ 在作好的磁片上註明是使用哪個映像檔作的。
+ 若 <filename>.flp</filename> 映像檔放在不同地方,
+ 請自行修改上述指令。若沒有 FreeBSD 光碟的話,
+ 可以到 FTP 上面的 <link xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/tools/"><filename>tools</filename>
+ 目錄</link> 下載 <command>fdimage</command> 使用。</para>
+
+ <para>如果要用 &unix; 系統(比如其他台 FreeBSD 機器)
+ 來製作開機片的話,可以用 &man.dd.1; 指令來把映像檔直接寫入到磁片上。
+ 在 FreeBSD上的話,可以打類似下面的指令:</para>
+
+ <screen>&prompt.root; <userinput>dd if=boot.flp of=/dev/fd0</userinput></screen>
+
+ <para>在 FreeBSD 中,<filename>/dev/fd0</filename>
+ 就是指第一台軟碟機(即一般 &ms-dos;/&windows;
+ 上的 <filename>A:</filename> 磁碟機);
+ 而 <filename>/dev/fd1</filename> 指 <filename>B:</filename>
+ 磁碟機,其餘的依此類推。 不過其他的 &unix;
+ 系統可能會用不同的名稱,這時就要查閱該系統的說明文件了。</para>
+ </step>
+ </procedure>
+
+ <para>現在起,我們可以開始安裝 FreeBSD 囉!</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="install-start">
+ <title>開始安裝</title>
+
+ <important>
+ <para>預設的情況下,安裝過程並不會改變您磁碟機中的任何資料,
+ 除非您看到下面的訊息:</para>
+
+ <literallayout class="monospaced">Last Chance: Are you SURE you want continue the installation?
+
+If you're running this on a disk with data you wish to save then WE
+STRONGLY ENCOURAGE YOU TO MAKE PROPER BACKUPS before proceeding!
+
+We can take no responsibility for lost disk contents!</literallayout>
+
+ <para>在看到這最後的警告訊息前,
+ 您都可以隨時離開安裝程式而不會變更您的硬碟。
+ 如果您發現有任何設定錯誤,
+ 這時您可以直接將電源關掉而不會造成任何傷害。</para>
+ </important>
+
+ <sect2 xml:id="install-starting">
+ <title>開機啟動流程篇</title>
+
+ <sect3 xml:id="install-starting-i386">
+ <title>&i386; 平台的開機流程</title>
+
+ <procedure>
+ <step>
+ <para>在一開始,電腦電源開關是關閉的。</para>
+ </step>
+
+ <step>
+ <para>打開電腦電源開關。剛開始的時候,
+ 它應該會顯示進入系統設定選單或 BIOS 要按哪個鍵,
+ 常見的有: <keycap>F2</keycap>, <keycap>F10</keycap>,
+ <keycap>Del</keycap> 或 <keycombo action="simul">
+ <keycap>Alt</keycap> <keycap>S</keycap>
+ </keycombo>。(按鍵請依據實際情況決定) 不論是要按哪個鍵,
+ 請按它進入 BIOS 設定畫面。
+ 有時您的電腦可能會顯示一個圖形畫面,
+ 通常做法是按 <keycap>Esc</keycap> 鍵將離開這個圖形畫面,
+ 以使您能夠看到必要的設定訊息。</para>
+ </step>
+
+ <step>
+ <para>找出可以設定『開機順序(Boot Order)』的選項,
+ 通常該選項會列出一些設備讓您選擇,例如︰
+ <literal>Floppy</literal>, <literal>CDROM</literal>,
+ <literal>First Hard Disk</literal> 等等。</para>
+
+ <para>如果要用軟碟安裝,請確定 floppy disk 要列為開機順序的第一個;
+ 若要用光碟安裝,記得 CDROM 要列為開機順序的第一個。
+ 為了避免不必要的疑惑,請參考機器、主機板說明手冊。</para>
+
+ <para>儲存設定並離開,系統應該會重新啟動。</para>
+ </step>
+
+ <step>
+ <para>若要用磁片安裝,請把在
+ <xref linkend="install-floppies"/>一節中製作好的
+ <filename>boot.flp</filename> 那張安裝磁片放到第一台軟碟機中。
+ </para>
+
+ <para>如果是從光碟安裝,那麼開機後請將 FreeBSD 光碟放入光碟機中。
+ </para>
+
+ <para>如果,開機後如往常一樣而沒有從軟碟或光碟開機,請檢查︰</para>
+
+ <orderedlist>
+ <listitem>
+ <para>是不是磁片或光碟太晚放入而錯失開機時間。
+ 如果是,請將它們放入,然後重新開機。</para>
+ </listitem>
+
+ <listitem>
+ <para>BIOS 設定不對或忘了儲存設定,請重新檢查 BIOS 的設定。</para>
+ </listitem>
+
+ <listitem>
+ <para>您的電腦 BIOS 不支援從光碟開機。</para>
+ </listitem>
+ </orderedlist>
+ </step>
+
+ <step>
+ <para>此時,FreeBSD 就開始啟動了。
+ 如果是從光碟開機,會見到類似下面的畫面(版本部分省略):</para>
+
+ <screen>Booting from CD-Rom...
+CD Loader 1.2
+
+Building the boot loader arguments
+Looking up /BOOT/LOADER... Found
+Relocating the loader and the BTX
+Starting the BTX loader
+
+BTX loader 1.00 BTX version is 1.01
+Console: internal video/keyboard
+BIOS CD is cd0
+BIOS drive C: is disk0
+BIOS drive D: is disk1
+BIOS 639kB/261120kB available memory
+
+FreeBSD/i386 bootstrap loader, Revision 1.1
+
+Loading /boot/defaults/loader.conf
+/boot/kernel/kernel text=0x64daa0 data=0xa4e80+0xa9e40 syms=[0x4+0x6cac0+0x4+0x88e9d]
+\</screen>
+
+ <para>如果您從軟碟開機,會看到類似下面的畫面(版本部分省略):</para>
+
+ <screen>Booting from Floppy...
+Uncompressing ... done
+
+BTX loader 1.00 BTX version is 1.01
+Console: internal video/keyboard
+BIOS drive A: is disk0
+BIOS drive C: is disk1
+BIOS 639kB/261120kB available memory
+
+FreeBSD/i386 bootstrap loader, Revision 1.1
+
+Loading /boot/defaults/loader.conf
+/kernel text=0x277391 data=0x3268c+0x332a8 |
+
+Insert disk labelled "Kernel floppy 1" and press any key...</screen>
+
+ <para>請根據提示將 <filename>boot.flp</filename> 磁片取出,
+ 並放入 <filename>kern1.flp</filename> 這張磁片,
+ 然後按 <keycap>Enter</keycap> 鍵。
+ 總之,您只需從第一張磁片啟動,然後根據提示,再放入相關磁片即可。
+ </para>
+ </step>
+
+ <step>
+ <para>無論從軟碟或光碟開機,接下來會進入 &os; boot loader
+ 選單畫面:</para>
+
+ <figure xml:id="boot-loader-menu">
+ <title>&os; Boot Loader 選單</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/boot-loader-menu"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+
+ <para>您可以等待 10 秒,或是按 <keycap>Enter</keycap> 鍵。</para>
+ </step>
+ </procedure>
+
+ </sect3>
+ <sect3>
+ <title>Alpha 平台的開機流程</title>
+
+ <indexterm><primary>Alpha</primary></indexterm>
+
+ <procedure>
+ <step>
+ <para>在一開始,電腦電源開關是關閉的。</para>
+ </step>
+
+ <step>
+ <para>打開電腦電源開關,然後等開機畫面出現。</para>
+ </step>
+
+ <step>
+ <para>若要用磁片安裝,請把在
+ <xref linkend="install-floppies"/>一節中製作好的
+ <filename>boot.flp</filename> 那張安裝磁片放到第一台軟碟機中。
+ 然後,打下列指令來從磁片開機
+ (請把下列軟碟機代號改為你電腦的軟碟機代號):</para>
+
+ <screen>&gt;&gt;&gt;<userinput>BOOT DVA0 -FLAGS '' -FILE ''</userinput></screen>
+
+ <para>若要用光碟安裝,請把做好的安裝片放入光碟機,
+ 然後打下列指令來從光碟開機
+ (請把下列光碟機代號改為你電腦的光碟機代號):</para>
+
+ <screen>&gt;&gt;&gt;<userinput>BOOT DKA0 -FLAGS '' -FILE ''</userinput></screen>
+ </step>
+
+ <step>
+ <para>接著 FreeBSD 開機片就會開始了。若是由軟碟開機的話,
+ 這時會看到以下訊息:</para>
+
+ <screen>Insert disk labelled "Kernel floppy 1" and press any key...</screen>
+
+ <para>請照指示,拿走 <filename>boot.flp</filename> 片,改放
+ <filename>kern1.flp</filename> 片,
+ 然後按 <keycap>Enter</keycap>。</para>
+ </step>
+
+ <step>
+ <para>無論從軟碟或光碟開機,您都會看到下面這段訊息:</para>
+
+ <screen>Hit [Enter] to boot immediately, or any other key for command prompt.
+Booting [kernel] in 9 seconds... _</screen>
+
+ <para>您可以等待 10 秒,或是按 <keycap>Enter</keycap> 鍵。
+ 接下來就會進入kernel configuration 選單。</para>
+ </step>
+ </procedure>
+
+ </sect3>
+
+ <sect3>
+ <title>&sparc64; 平台的開機流程</title>
+
+ <para>大多數的 &sparc64; 機器預設會自動從硬碟開機。 因此要裝 &os;
+ 的話,則需要進入 PROM(OpenFirmware) 設定由網路或光碟開機才可。</para>
+
+ <para>請先重開機,然後等待直到開機訊息出現。 這部分可能會隨機器型號不同
+ ,而有所差異,但大概會出現像下列這樣:</para>
+
+ <screen>Sun Blade 100 (UltraSPARC-IIe), Keyboard Present
+Copyright 1998-2001 Sun Microsystems, Inc. All rights reserved.
+OpenBoot 4.2, 128 MB memory installed, Serial #51090132.
+Ethernet address 0:3:ba:b:92:d4, Host ID: 830b92d4.</screen>
+
+ <para>若您機器此時會先由硬碟開機,那麼需要按
+ <keycombo action="simul"><keycap>L1</keycap><keycap>A</keycap></keycombo>
+ 或
+ <keycombo action="simul"><keycap>Stop</keycap><keycap>A</keycap></keycombo>
+ 或者是透過 serial console (用法請參閱 &man.tip.1; 或 &man.cu.1;
+ 內有關 <command>~#</command> 的說明) 送出 <command>BREAK</command>
+ 指令來進入 PROM prompt。 大概會像下面:</para>
+
+ <screen><prompt>ok </prompt><co xml:id="prompt-single"/>
+<prompt>ok {0} </prompt><co xml:id="prompt-smp"/></screen>
+
+ <calloutlist>
+ <callout arearefs="prompt-single">
+ <para>這是適用於只有單一 CPU 的機器。</para>
+ </callout>
+
+ <callout arearefs="prompt-smp">
+ <para>這是適用於 SMP 機器,數字部分是指目前在使用中的 CPU
+ 編號。</para>
+ </callout>
+ </calloutlist>
+
+ <para>此時請把安裝光碟放入光碟機內,然後在 PROM prompt 打
+ <command>boot cdrom</command> 即可。</para>
+
+ </sect3>
+
+ </sect2>
+
+
+ <sect2 xml:id="view-probe">
+ <title>那要怎麼去翻閱偵測硬體的結果呢?</title>
+
+ <para>先前在螢幕上所顯示的最後幾百行字,會存在暫存區(buffer)
+ 以便您翻閱。</para>
+
+ <para>若要翻閱暫存區,請按 <keycap>Scroll Lock</keycap> 鍵,
+ 這會開啟捲動畫面功能。
+ 然後就可以使用方向鍵,或是 <keycap>PageUp</keycap>、
+ <keycap>PageDown</keycap> 鍵來上下翻閱。
+ 再按一次 <keycap>Scroll Lock</keycap> 鍵,就會停止畫面捲動。</para>
+
+ <para>現在就請試試看,翻閱一下偵測硬體的畫面吧,
+ 你應該會看到類似 <xref linkend="install-dev-probe"/> 的畫面,
+ 真正畫面會依你的電腦設備而有所不同。</para>
+
+ <figure xml:id="install-dev-probe">
+ <title>偵測硬體的例子</title>
+
+ <screen>avail memory = 253050880 (247120K bytes)
+Preloaded elf kernel "kernel" at 0xc0817000.
+Preloaded mfs_root "/mfsroot" at 0xc0817084.
+md0: Preloaded image &lt;/mfsroot&gt; 4423680 bytes at 0xc03ddcd4
+
+md1: Malloc disk
+Using $PIR table, 4 entries at 0xc00fde60
+npx0: &lt;math processor&gt; on motherboard
+npx0: INT 16 interface
+pcib0: &lt;Host to PCI bridge&gt; on motherboard
+pci0: &lt;PCI bus&gt; on pcib0
+pcib1:&lt;VIA 82C598MVP (Apollo MVP3) PCI-PCI (AGP) bridge&gt; at device 1.0 on pci0
+pci1: &lt;PCI bus&gt; on pcib1
+pci1: &lt;Matrox MGA G200 AGP graphics accelerator&gt; at 0.0 irq 11
+isab0: &lt;VIA 82C586 PCI-ISA bridge&gt; at device 7.0 on pci0
+isa0: &lt;iSA bus&gt; on isab0
+atapci0: &lt;VIA 82C586 ATA33 controller&gt; port 0xe000-0xe00f at device 7.1 on pci0
+ata0: at 0x1f0 irq 14 on atapci0
+ata1: at 0x170 irq 15 on atapci0
+uhci0 &lt;VIA 83C572 USB controller&gt; port 0xe400-0xe41f irq 10 at device 7.2 on pci
+0
+usb0: &lt;VIA 83572 USB controller&gt; on uhci0
+usb0: USB revision 1.0
+uhub0: VIA UHCI root hub, class 9/0, rev 1.00/1.00, addr1
+uhub0: 2 ports with 2 removable, self powered
+pci0: &lt;unknown card&gt; (vendor=0x1106, dev=0x3040) at 7.3
+dc0: &lt;ADMtek AN985 10/100BaseTX&gt; port 0xe800-0xe8ff mem 0xdb000000-0xeb0003ff ir
+q 11 at device 8.0 on pci0
+dc0: Ethernet address: 00:04:5a:74:6b:b5
+miibus0: &lt;MII bus&gt; on dc0
+ukphy0: &lt;Generic IEEE 802.3u media interface&gt; on miibus0
+ukphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
+ed0: &lt;NE2000 PCI Ethernet (RealTek 8029)&gt; port 0xec00-0xec1f irq 9 at device 10.
+0 on pci0
+ed0 address 52:54:05:de:73:1b, type NE2000 (16 bit)
+isa0: too many dependant configs (8)
+isa0: unexpected small tag 14
+orm0: &lt;Option ROM&gt; at iomem 0xc0000-0xc7fff on isa0
+fdc0: &lt;NEC 72065B or clone&gt; at port 0x3f0-0x3f5,0x3f7 irq 6 drq2 on isa0
+fdc0: FIFO enabled, 8 bytes threshold
+fd0: &lt;1440-KB 3.5" drive&gt; on fdc0 drive 0
+atkbdc0: &lt;Keyboard controller (i8042)&gt; at port 0x60,0x64 on isa0
+atkbd0: &lt;AT Keyboard&gt; flags 0x1 irq1 on atkbdc0
+kbd0 at atkbd0
+psm0: &lt;PS/2 Mouse&gt; irq 12 on atkbdc0
+psm0: model Generic PS/@ mouse, device ID 0
+vga0: &lt;Generic ISA VGA&gt; at port 0x3c0-0x3df iomem 0xa0000-0xbffff on isa0
+sc0: &lt;System console&gt; at flags 0x100 on isa0
+sc0: VGA &lt;16 virtual consoles, flags=0x300&gt;
+sio0 at port 0x3f8-0x3ff irq 4 flags 0x10 on isa0
+sio0: type 16550A
+sio1 at port 0x2f8-0x2ff irq 3 on isa0
+sio1: type 16550A
+ppc0: &lt;Parallel port&gt; at port 0x378-0x37f irq 7 on isa0
+pppc0: SMC-like chipset (ECP/EPP/PS2/NIBBLE) in COMPATIBLE mode
+ppc0: FIFO with 16/16/15 bytes threshold
+plip0: &lt;PLIP network interface&gt; on ppbus0
+ad0: 8063MB &lt;IBM-DHEA-38451&gt; [16383/16/63] at ata0-master UDMA33
+acd0: CD-RW &lt;LITE-ON LTR-1210B&gt; at ata1-slave PIO4
+Mounting root from ufs:/dev/md0c
+/stand/sysinstall running as init on vty0</screen>
+ </figure>
+
+ <para>請仔細檢查每項檢測結果,以確定 FreeBSD 有正確偵測到每項硬體。
+ 若沒偵測到硬體的話,那畫面就不會列出來了。 <link linkend="kernelconfig">自訂 kernel</link> 可以讓您加上原本預設的
+ <filename>GENERIC</filename> kernel 所不支援的硬體,像是音效卡之類。
+ </para>
+
+ <para>而 &os;&nbsp;6.2 起的版本,在偵測硬體後會看到 <xref linkend="config-country"/>,請用方向鍵選擇你的國別、地區或群組。
+ 然後按 <keycap>Enter</keycap> 鍵就會幫你設定相關國別、鍵盤對應。
+ 此外,要離開、重啟 <application>sysinstall</application>
+ 程式,也很簡單。</para>
+
+ <figure xml:id="config-country">
+ <title>選擇國別</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/config-country"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <figure xml:id="sysinstall-exit">
+ <title>離開 Sysinstall 程式</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/sysinstall-exit"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>在主畫面選擇 <guimenuitem>Exit Install</guimenuitem>,
+ 接下來應該會出現以下訊息:</para>
+
+
+ <screen> User Confirmation Requested
+ Are you sure you wish to exit? The system will reboot
+ (be sure to remove any floppies/CDs/DVDs from the drives).
+
+ [ Yes ] No</screen>
+
+ <para>若按下 &gui.yes; 之後,卻忘了把光碟退出來的話,
+ 那麼等下重開機後又會再次啟動安裝程式了。</para>
+
+ <para>若你是用磁片開機的話,那麼重開機之前,請記得先退出
+ <filename>boot.flp</filename> 片吧。</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="using-sysinstall">
+ <title>介紹 Sysinstall</title>
+
+ <para><application>sysinstall</application>
+ 是 FreeBSD 計劃所提供的安裝程式。
+ 它是以文字模式操作方式為主,分為幾層選單、畫面,以讓您進行安裝。</para>
+
+ <para><application>sysinstall</application> 選單主要由方向鍵、
+ <keycap>Enter</keycap>、<keycap>Tab</keycap>、<keycap>Space</keycap>
+ 以及其他按鍵來進行操作,
+ 在 <application>sysinstall</application> 主畫面的 Usage
+ 內有這些鍵盤操作上的說明。</para>
+
+ <para>要查閱這些說明,請將游標移到
+ <guimenuitem>Usage</guimenuitem>,然後選
+ <guibutton>[Select]</guibutton> ,這時你畫面應該會長像 <xref linkend="sysinstall-main3"/>,接著請按 <keycap>Enter</keycap> 鍵。</para>
+
+ <para>接下來,會出現安裝的使用說明,閱讀完畢請按
+ <keycap>Enter</keycap> 以跳回主畫面。</para>
+
+ <figure xml:id="sysinstall-main3">
+ <title>選擇 Sysinstall 主畫面的『Usage(快速說明)』</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/main1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <sect2 xml:id="select-doc">
+ <title>選擇『 Documentation(說明文件)』選單</title>
+
+ <para>在主畫面用方向鍵選擇 <guimenuitem>Doc</guimenuitem>,然後按
+ <keycap>Enter</keycap> 鍵。</para>
+
+ <figure xml:id="main-doc">
+ <title>選擇『Documentation(說明文件)』選單</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/main-doc"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>這時會出現說明文件的選單。</para>
+
+ <figure xml:id="docmenu1">
+ <title>Sysinstall 的說明文件(Documentation)選單</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/docmenu1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>閱讀這些說明文件很重要。</para>
+
+ <para>要閱讀文件的話,請用方向鍵選取要閱讀的文件然後按
+ <keycap>Enter</keycap> 鍵。讀完後,再按一次
+ <keycap>Enter</keycap> 鍵就會回到說明文件畫面了。</para>
+
+ <para>若要回到主畫面,用方向鍵選擇
+ <guimenuitem>Exit</guimenuitem> 然後按下
+ <keycap>Enter</keycap> 鍵即可。</para>
+ </sect2>
+
+ <sect2 xml:id="keymap">
+ <title>選擇『鍵盤對應』選單</title>
+
+ <para>如果要改變鍵盤按鍵的對應模式,請在主選單選取
+ <guimenuitem>Keymap</guimenuitem> 然後按
+ <keycap>Enter</keycap> 鍵即可。 一般情況下是不用去改,
+ 除非你用的鍵盤不是一般標準或非美式鍵盤。</para>
+
+ <figure xml:id="sysinstall-keymap">
+ <title>Sysinstall 主選單</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/main-keymap"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>您可以使用上下鍵移動到您想使用的鍵盤對應方式,然後按下
+ <keycap>Space</keycap> 鍵以選取它;再按一下
+ <keycap>Space</keycap> 鍵可以取消選取。當您完成後,請選擇
+ &gui.ok; 然後按
+ <keycap>Enter</keycap> 鍵即可。</para>
+
+ <para>在這個畫面顯示的只是其中一小部分;
+ 若只要用預設鍵盤對應方式就好的話,可以用 <keycap>Tab</keycap>
+ 來選 &gui.cancel; 這樣就會返回主畫面。</para>
+
+ <figure xml:id="sysinstall-keymap-menu">
+ <title>Sysinstall 鍵盤對應選單</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/keymap"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ </sect2>
+
+ <sect2 xml:id="viewsetoptions">
+ <title>安裝選項的設定畫面</title>
+
+ <para>請選 <guimenuitem>Options</guimenuitem> 然後按
+ <keycap>Enter</keycap> 鍵。</para>
+
+ <figure xml:id="sysinstall-options">
+ <title>Sysinstall 主選單</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/main-options"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <figure xml:id="options">
+ <title>Sysinstall 選項設定</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/options"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>通常,使用者大多用預設值就可以了,而不用修改它們。
+ 而 Release Name 的地方則依你所安裝的版本而有所不同。</para>
+
+ <para>而目前所選的的項目,會在畫面下方以藍底白字顯示說明。
+ 注意:其中右邊最後的選項是
+ <guimenuitem>Use Defaults(使用預設值)</guimenuitem>
+ ,您可以藉由此選項將所有的設定還原為預設值。</para>
+
+ <para>另外,可以按 <keycap>F1</keycap> 鍵來閱讀各選項的說明。</para>
+
+ <para>而按 <keycap>Q</keycap> 鍵則是可以回到主畫面。</para>
+ </sect2>
+
+ <sect2 xml:id="start-install">
+ <title>開始進行標準安裝</title>
+
+ <para><guimenuitem>Standard(標準)</guimenuitem>安裝適用於那些初探 &unix;
+ 或 FreeBSD 的使用者。用方向鍵選擇 <guimenuitem>Standard</guimenuitem>
+ 然後按 <keycap>Enter</keycap> 鍵即可開始進入標準安裝。</para>
+
+ <figure xml:id="sysinstall-standard">
+ <title>開始進行標準安裝</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/main-std"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="install-steps">
+ <title>硬碟空間的分配</title>
+
+ <para>您的第一個任務就是要決定分配給 FreeBSD 用的磁碟空間、label,
+ 以便 <application>sysinstall</application> 幫你做相關準備動作。
+ 因此,你必須先對 FreeBSD 是如何確認磁碟的流程有個概念。</para>
+
+ <sect2 xml:id="install-drive-bios-numbering">
+ <title>BIOS 磁碟機編號</title>
+
+ <para>在安裝、設定 FreeBSD 之前,有很重要的一點必須注意,
+ 尤其當您有許多顆硬碟的時候。</para>
+
+ <indexterm><primary>DOS</primary></indexterm>
+ <indexterm><primary>Microsoft Windows</primary></indexterm>
+ <para>在 PC 架構,當您跑像 &ms-dos; 或 &microsoft.windows;
+ 這種跟 BIOS 設定相關的作業系統,
+ BIOS 那邊可以調整正常的磁碟機順序,然後這些作業系統會跟著 BIOS 做改變。
+ 這讓使用者不一定非得要由所謂的 <quote>primary master</quote> 硬碟開機。
+ 有人發現最簡單、便宜的備份系統方式,就是再去買一顆一模一樣的硬碟,
+ 然後定期使用 <application>
+ Ghost</application> 或
+ <application>XCOPY</application>
+ 以將資料從第一顆硬碟複製到第二顆硬碟上面去。
+ 所以,當第一顆硬碟掛了(可能是病毒或壞軌造成的),
+ 就可以輕鬆透過調整 BIOS 中的開機順序,
+ 而直接用第二顆硬碟開機。
+ 這跟將機殼拆開,把第二顆硬碟跟第一顆對調(要調 jumper)有同樣的效果,
+ 差別就是:不用拆機殼。</para>
+
+ <indexterm><primary>SCSI</primary></indexterm>
+ <indexterm><primary>BIOS</primary></indexterm>
+ <para>此外,若裝有比較貴的 SCSI 卡系統,通常本身也有 BIOS 的功能來讓
+ SCSI 設備(最多可到 7 個)達到類似改變順序的功能。</para>
+
+ <para>習慣上述方式的使用者很可能會感到驚訝,因為在 FreeBSD 中並非如此,
+ FreeBSD 不會參考 BIOS 設定值,而且也不能偵測 <quote>logical BIOS
+ drive mapping</quote> 設定。 這會讓人感覺很疑惑,明明就是一樣的硬碟,
+ 而且資料也完全從另一顆複製過來,結果卻沒辦法像以前那樣用。</para>
+
+ <para>使用 FreeBSD 的時候,請將 BIOS 中的硬碟開機順序調回原本正常的順序,
+ 並且以後不要再改這設定。如果您需要切換硬碟順序的話,那請用硬體方式,
+ 直接打開機殼,調 jumper 及排線即可。</para>
+
+ <sidebar>
+ <title>一段小故事:Bill 及 Fred 的安裝歷險</title>
+
+ <para>比爾(Bill)打算幫佛列德(Fred)把舊的 Wintel 機器灌 FreeBSD。
+ 他在一顆 SCSI 硬碟(ID 是 0)裝上 FreeBSD。</para>
+
+ <para>於是佛列德開始用他新的 FreeBSD 系統;但是過了幾天,他發現這顆
+ SCSI 老硬碟發生許多小問題。 之後,他就跟比爾說起這件事。</para>
+
+ <para>此事經過幾天後,比爾決定是該解決問題的時候了,
+ 所以他從後面房間的硬碟 <quote>收藏區</quote>
+ 內拿出一個一模一樣的硬碟,並且經過初步 surface 掃瞄測試後,
+ 顯示這顆硬碟還可堪用,因此,比爾將它的 ID 調成 4,
+ 然後安裝到佛列德的機器,
+ 並且將資料從磁碟 0 複製到磁碟 4。
+ 現在新硬碟裝好了,而且看起來好像一切正常;
+ 所以,比爾認為現在應該可以開始用它了。
+ 於是到 SCSI BIOS 中設定 SCSI ID 4 為開機碟,
+ 用磁碟 4 重新開機後,FreeBSD 一切跑得很順利。</para>
+
+ <para>佛列德繼續用了幾天後,比爾跟佛列德決定要來玩點新的:
+ 試著升級 FreeBSD 看看。
+ 比爾將 ID 0 的硬碟移除(因為有問題)並且又從 <quote>收藏區</quote>
+ 中拿了一顆一樣的硬碟來。
+ 然後他用佛列德的開機磁片透過 FTP 方式將在這顆硬碟上裝了新版的
+ FreeBSD,安裝過程都很順利。</para>
+
+ <para>佛列德用了這新版本幾天後,覺得它很適合用在工程部門...
+ 是時候將以前放在舊系統的工作資料複製過來了。
+ 因此,佛列德將 ID 4 的 SCSI 硬碟
+ (裡面有放從舊系統中複製過來的最新資料)先 mount 起來,
+ 結果竟然發現在 ID 4 的硬碟上,他以前的所有資料都不見了!</para>
+
+ <para>奇怪,資料到底是跑到哪裡去了呢?</para>
+
+ <para>原來,當初比爾將 ID 0 硬碟的資料複製到 ID 4 硬碟的時候,
+ ID 4 就變成 <quote>新的複製品(new clone)</quote>。
+ 而當他調 SCSI BIOS 設定 ID 4 為開機碟,想讓系統從 ID 4 開機,
+ 這步驟其實只是他自己搞混了,
+ 因為大部分的作業系統可以藉由調 BIOS 設定以改變開機順序,
+ 但是 FreeBSD 卻會把開機順序還原成正常的模式,
+ 因此,佛列德的 FreeBSD 還是從最初的那顆 ID 0 硬碟開機的。
+ 事實上,所有的資料都還在故事最初的那顆硬碟上,
+ 而不是在他想像中的 ID 4 硬碟。</para>
+
+ <para>我們很高興在發現這件事時,那些資料都還在,
+ 我們把資料從最初的那顆 ID 0 硬碟取出來並交還給佛列德
+ (而且比爾也從此瞭解了 0 的重要....)。</para>
+
+ <para>雖然我們這邊的例子是用 SCSI 硬碟,
+ 但是相同的觀念也可以套用在 IDE 硬碟上。</para>
+ </sidebar>
+ </sect2>
+
+ <sect2 xml:id="main-fdisk">
+ <title>以 FDisk 來建立分割磁區(Slices)</title>
+
+ <note>
+ <para>在這時候您所做的變更都還不會真正寫入硬碟中。
+ 如果你發現弄錯了,想要重來一遍的話,
+ 可以用選單來離開 <application>sysinstall</application>,
+ 或是按 <keycap>U</keycap> 鍵來
+ <guimenuitem>Undo(回復)</guimenuitem> 所有設定。
+ 如果你弄亂了而且不知道怎麼離開,你可以直接將電腦電源關掉再重來。
+ </para>
+ </note>
+
+ <para>在 <application>sysinstall</application> 主畫面選擇使用標準安裝後,
+ 應該會看到下面的訊息:</para>
+
+ <screen> Message
+ In the next menu, you will need to set up a DOS-style ("fdisk")
+ partitioning scheme for your hard disk. If you simply wish to devote
+ all disk space to FreeBSD (overwriting anything else that might be on
+ the disk(s) selected) then use the (A)ll command to select the default
+ partitioning scheme followed by a (Q)uit. If you wish to allocate only
+ free space to FreeBSD, move to a partition marked "unused" and use the
+ (C)reate command.
+ [ OK ]
+
+ [ Press enter or space ]</screen>
+
+ <para>這時請依畫面說明,按 <keycap>Enter</keycap> 鍵。
+ 然後會看到一個列表,上面會列出所有在偵測硬體時所找到的硬碟。
+ <xref linkend="sysinstall-fdisk-drive1"/> 範例顯示的是有找到兩個
+ IDE 磁碟機的情形,這兩個磁碟機分別為:
+ <filename>ad0</filename> 與 <filename>ad2</filename>。</para>
+
+ <figure xml:id="sysinstall-fdisk-drive1">
+ <title>選擇 FDisk 要分割的硬碟</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/fdisk-drive1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>你可能會好奇,為何 <filename>ad1</filename> 沒列在這裡。
+ 為什麼會不見了呢?</para>
+
+ <para>試想,如果您有兩顆 IDE 硬碟,一個是 primary master,一個是 secondary
+ master,這樣會發生什麼事呢? 如果 FreeBSD 依照找到的順序來為他們命名,
+ 比如首先是 <filename>ad0</filename> 再來是
+ <filename>ad1</filename> 那麼就不會出現困擾。</para>
+
+ <para>但是,現在問題來了。如果您現在想在 primary slave 加裝第三顆硬碟,
+ 那麼這顆硬碟的名稱就會是 <filename>ad1</filename>,之前原本的
+ <filename>ad1</filename> 就會變成 <filename>ad2</filename>。
+ 這樣會造成什麼問題呢? 因為硬體設備的名稱(像是
+ <filename>ad1s1a</filename>)是用來尋找檔案系統的,
+ 因此您可能會突然發現,有些檔案系統從此無法正常顯示,
+ 必須修改 FreeBSD 設定(<filename>/etc/fstab</filename>)才可以正確顯示。
+ </para>
+
+ <para>為了解決這個問題,在設定 kernel 時可以採用 IDE
+ 硬碟所在的位置來命名,而非根據找到的順序。 使用這種方式的話,
+ 在 secondary master 的 IDE
+ 硬碟就<emphasis>永遠</emphasis>會是 <filename>ad2</filename>,
+ 即使系統中並沒有 <filename>ad0</filename> 或
+ <filename>ad1</filename> 也不受影響。</para>
+
+ <para>由於此為 FreeBSD kernel 預設設定,也就是為何上述畫面只顯示
+ <filename>ad0</filename> 及 <filename>ad2</filename> 之故。
+ 畫面上這台機器的兩顆硬碟是分別裝在 primary 以及 secondary 排線上的
+ master,這兩顆都沒有裝在 slave 上。</para>
+
+ <para>請選好想安裝 FreeBSD 的硬碟,然後按下 &gui.ok;。 接著就會開始
+ <application>FDisk</application>,然後會看到類似 <xref linkend="sysinstall-fdisk1"/> 的畫面。</para>
+
+ <para><application>FDisk</application> 的顯示畫面分為三個部分。</para>
+
+ <para>第一部份是畫面最上方的前兩行,這裡會顯示目前所選的硬碟資訊,
+ 包括它在 FreeBSD 的名稱、硬碟 geometry、硬碟總容量。</para>
+
+ <para>第二部分會顯示目前所選的硬碟上有哪些 slice 以及各 slice 的起末位置、
+ 所佔容量、FreeBSD 名稱、描述說明、子類別(sub-type)。 例子中顯示出有 2
+ 個小的並且尚未使用的 slice,這是受到 PC 的硬碟本身架構影響之故。 此外,
+ 還有一個大的 <acronym>FAT</acronym> slice(通常是 &ms-dos; /
+ &windows; 中的 <filename>C:</filename>),以及一個延伸磁碟分割區
+ (在 &ms-dos; / &windows; 內的其他磁碟代號)。</para>
+
+ <para>第三部分則顯示 <application>FDisk</application> 可用的指令。</para>
+
+ <figure xml:id="sysinstall-fdisk1">
+ <title>(舉例)未編輯前的 Fdisk 分割區(Partition)</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/fdisk-edit1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>接下來要做的事,跟您要怎麼分割硬碟有關。</para>
+
+ <para>若要讓 FreeBSD 使用整顆硬碟(稍後的安裝會再要您確認以
+ <application>sysinstall</application> 來繼續安裝,
+ 就會清除該硬碟內上的資料),那麼就可以按 <keycap>A</keycap> 鍵(
+ <guimenuitem>Use Entire Disk</guimenuitem>),以刪除所有既存的 slice,
+ 取而代之的是一個小的並標示為 <literal>unused</literal>(同樣的,這也是
+ PC 硬碟架構所造成)的 slice,以及一個大的 FreeBSD slice。 之後,
+ 請用方向鍵把光棒移至該 FreeBSD slice,然後按 <keycap>S</keycap>
+ 鍵以便將此 slice 標為開機 slice。
+ 此時的畫面應該類似 <xref linkend="sysinstall-fdisk2"/>。 請注意:
+ 在 <literal>Flags</literal> 欄位的 <literal>A</literal> 值表示該 slice
+ 屬於 <emphasis>active</emphasis>,也會由此 slice 來開機。</para>
+
+ <para>若要刪除現有 slice 以挪出空間給 FreeBSD 使用,可以把光棒移到要刪除的
+ slice 後按 <keycap>D</keycap> 鍵,然後再按 <keycap>C</keycap> 鍵,
+ 此時會出現對話框,請輸入要新增的 slice 大小為何,輸入合適大小之後按
+ <keycap>Enter</keycap> 鍵即可。 該預設值為可分配空間的最大值,
+ 可以是最大的或尚未分配的整顆硬碟大小。</para>
+
+ <para>若已建立完畢給 FreeBSD 的空間(透過類似
+ <application>&partitionmagic;</application> 之類的工具),那麼可以按
+ <keycap>C</keycap> 鍵以新增 slice。同樣也會有對話框出現,來問想要新增的
+ slice 大小為何。</para>
+
+ <figure xml:id="sysinstall-fdisk2">
+ <title>Fdisk 採用整顆硬碟作分割區(Partition)</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/fdisk-edit2"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>完畢後請按 <keycap>Q</keycap> 鍵。 這些更改會暫存給
+ <application>sysinstall</application> 使用,但還不會真正寫入到硬碟
+ 。</para>
+ </sect2>
+
+ <sect2 xml:id="bootmgr">
+ <title>安裝 Boot Manager</title>
+
+ <para>現在可以選擇是否要裝 boot manager。 一般而言,
+ 遇到下列情況才會需要裝 boot manager:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>有一個以上的硬碟,而 FreeBSD 並非裝在第一個硬碟上。</para>
+ </listitem>
+
+ <listitem>
+ <para>同一顆硬碟上除了有裝 FreeBSD 之外,還有裝其他作業系統,
+ 所以需要在開機時選擇要進入哪個作業系統。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>若只裝 FreeBSD,並且是裝在第一顆硬碟,那麼選
+ <guimenuitem>Standard</guimenuitem> 即可。 若已經有使用其他的
+ boot manager 可開機進入 FreeBSD 那麼請選 <guimenuitem>None</guimenuitem>
+ 即可。</para>
+
+ <para>請依自身需求與情況做抉擇,然後按 <keycap>Enter</keycap> 鍵。</para>
+
+ <figure xml:id="sysinstall-bootmgr">
+ <title>Sysinstall 的 Boot Manager 選單</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/boot-mgr"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>按 <keycap>F1</keycap> 會有不同作業系統共存時,
+ 有可能遇到的相關問題說明。</para>
+ </sect2>
+
+ <sect2>
+ <title>在其他硬碟上建立分割磁區(Slices)</title>
+
+ <para>若有一個以上的硬碟,那麼在選完 boot manager
+ 之後會再回到選擇硬碟的畫面。 若要把 FreeBSD 裝在多個硬碟上,
+ 那麼可以在此選擇其他硬碟,並重複使用 <application>FDisk</application>
+ 來建立 slice 。</para>
+
+ <important>
+ <para>若第一顆硬碟不是裝 FreeBSD 的話,那麼每一顆就要都裝 FreeBSD boot
+ manager 才可以。</para>
+ </important>
+
+ <figure xml:id="sysinstall-fdisk-drive2">
+ <title>離開『選擇硬碟』畫面</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/fdisk-drive2"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para><keycap>Tab</keycap> 鍵可以在最後選擇的硬碟以及 &gui.ok;、
+ &gui.cancel; 之間進行切換。</para>
+
+ <para>先按一次 <keycap>Tab</keycap> 會先移到 &gui.ok;,然後再按
+ <keycap>Enter</keycap> 鍵以繼續安裝。</para>
+ </sect2>
+
+ <sect2 xml:id="bsdlabeleditor">
+ <title>以 <application>Disklabel</application> 來建立分割區(Partitions)
+ </title>
+
+ <para>現在必須在剛建立好的 slice 規劃一些分割區。 請注意:
+ 每個分割區的代號是從 <literal>a</literal> 到 <literal>h</literal>,
+ 此外 <literal>b</literal>、<literal>c</literal>、<literal>d</literal>
+ 通常是特殊用途,不該隨意變動。</para>
+
+ <para>有些程式可以透過特殊的分割方式而達到更好的效果,
+ 尤其是分割區是分散在不同硬碟上的時候。 但是,現在是您第一次裝 FreeBSD,
+ 所以請不要去煩惱該如何分割硬碟才好。 最重要的是,裝好 FreeBSD
+ 然後學習如何善用之。 當對 FreeBSD 有一定程度的熟悉之後,可以隨時重裝
+ FreeBSD,並改變分割的方式。</para>
+
+ <para>下面例子有四個分割區 &mdash; 其中一個是 swap 空間,i
+ 其他三個是檔案系統。</para>
+
+ <table frame="none" pgwide="1">
+ <title>第一顆硬碟的分割區(Partition)配置</title>
+
+ <tgroup cols="4">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="1*"/>
+ <colspec colwidth="1*"/>
+ <colspec colwidth="4*"/>
+
+ <thead>
+ <row>
+ <entry>分割區</entry>
+
+ <entry>檔案系統</entry>
+
+ <entry>大小</entry>
+
+ <entry>介紹</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>a</literal></entry>
+
+ <entry><filename>/</filename></entry>
+
+ <entry>128&nbsp;MB</entry>
+
+ <entry>此為根目錄檔案系統(root filesystem)。
+ 其他的檔案系統都會掛載在根目錄之下。 128&nbsp;MB
+ 對於此檔案系統來說是相當合理的大小,
+ 因為通常這裡並不會放太多資料,而在 FreeBSD 裝完後會用到約
+ 40&nbsp;MB 的根目錄空間。 剩下的空間是放臨時資料用的,
+ 此外也應該要預留一些空間,因為日後的 FreeBSD
+ 版本可能會需要更多的 <filename>/</filename>(根目錄) 空間
+ 。</entry>
+ </row>
+
+ <row>
+ <entry><literal>b</literal></entry>
+
+ <entry>N/A</entry>
+
+ <entry>RAM 的 2~3 倍</entry>
+
+ <entry><para>系統的 swap 空間是放在 <literal>b</literal> 分割區。
+ 如何選擇適合的 swap 空間大小可是一門學問。 一般來說,
+ swap 空間應該是記憶體(RAM)大小的 2 或 3 倍。 此外,swap
+ 至少需要 64&nbsp;MB,因此若 RAM 小於 32&nbsp;MB 的話,請把
+ swap 大小設為 64&nbsp;MB。</para><para>
+
+ 若有一個以上的硬碟,則可以在每個硬碟都配置 swap 空間。
+ FreeBSD 會善用每個硬碟上的 swap 空間,如此一來便能有效提高
+ swap 的性能。 若您屬這類情況,請先算出總共需要的 swap 總大小
+ (比如:128&nbsp;MB),然後除以全部的硬碟數量(比如:兩顆硬碟),
+ 這樣算出來的結果就是每個硬碟上所需配置的 swap 大小,
+ 在這個例子中,則每個硬碟所需之 swap 空間為 64&nbsp;MB
+ 。</para></entry>
+ </row>
+
+ <row>
+ <entry><literal>e</literal></entry>
+
+ <entry><filename>/var</filename></entry>
+
+ <entry>256&nbsp;MB</entry>
+
+ <entry><filename>/var</filename> 目錄會放的檔案有很多種,像是 log
+ 檔案以及其他的系統管理檔案。 這些檔案大部分都是 FreeBSD
+ 每日運作所會讀、寫。 把這些檔案另外放到專門的檔案系統(即
+ <filename>/var</filename>) 則可以最佳化這些檔案的存取,
+ 而不致於影響其他目錄的存取。</entry>
+ </row>
+
+ <row>
+ <entry><literal>f</literal></entry>
+
+ <entry><filename>/usr</filename></entry>
+
+ <entry>剩餘的硬碟空間</entry>
+
+ <entry>所有其他檔案通常會存在 <filename>/usr</filename>
+ 及其子目錄內。</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>若要把 FreeBSD 裝在多個硬碟上,那麼必須在您所配置的其他 slice
+ 上新增分割區。 最簡單的方式,就是在每個硬碟上建立分割區,一個給 swap
+ 空間,另一個則是檔案系統。</para>
+
+ <table frame="none" pgwide="1">
+ <title>其他硬碟的分割區(Partition)配置</title>
+
+ <tgroup cols="4">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2*"/>
+ <colspec colwidth="3*"/>
+
+ <thead>
+ <row>
+ <entry>分割區</entry>
+
+ <entry>檔案系統</entry>
+
+ <entry>大小</entry>
+
+ <entry>介紹</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>b</literal></entry>
+
+ <entry>N/A</entry>
+
+ <entry>請參閱右側的介紹</entry>
+
+ <entry>前面有提過,swap 空間是可以跨各硬碟。 即使沒有使用
+ <literal>a</literal> 分割區,但習慣上還是會把 swap 空間設為
+ <literal>b</literal> 分割區。</entry>
+ </row>
+
+ <row>
+ <entry><literal>e</literal></entry>
+
+ <entry>/disk<replaceable>n</replaceable></entry>
+
+ <entry>剩餘的硬碟空間</entry>
+
+ <entry>剩下的空間是一個大的分割區,最簡單的做法是將之規劃為
+ <literal>a</literal> 分割區,而不是 <literal>e</literal>
+ 分割區。 然而,習慣上 <literal>a</literal> 分割區是保留給
+ 根目錄(<filename>/</filename>)所使用的。 當然,
+ 您不一定要遵循此習慣,但 <application>sysinstall</application>
+ 本身會,所以照它既有的方式會讓你安裝更加清爽、潔淨。
+ 你可以把這些檔案系統掛載在任何地方,本範例是建議把它們掛載於
+ <filename>/diskn</filename> 目錄,
+ 其中的 <replaceable>n</replaceable> 的數字,
+ 則依各硬碟的順序而有所變化。 但若您高興,
+ 也可以把它們掛載於其他地方。</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>完成分割區配置之後,就可以用 <application>sysinstall</application>
+ 來建立之。 您會看到如下訊息:</para>
+
+ <screen> Message
+ Now, you need to create BSD partitions inside of the fdisk
+ partition(s) just created. If you have a reasonable amount of disk
+ space (200MB or more) and don't have any special requirements, simply
+ use the (A)uto command to allocate space automatically. If you have
+ more specific needs or just don't care for the layout chosen by
+ (A)uto, press F1 for more information on manual layout.
+
+ [ OK ]
+ [ Press enter or space ]</screen>
+
+ <para>請按 <keycap>Enter</keycap> 鍵以進入 FreeBSD 分割區編輯器,叫做
+ <application>Disklabel</application>。</para>
+
+ <para><xref linkend="sysinstall-label"/> 顯示第一次執行
+ <application>Disklabel</application> 的畫面,
+ 這畫面可區分為三個區塊。</para>
+
+ <para>前幾行顯示的是正在編輯的硬碟,以及目前正在建立的 slice 位於哪個
+ 分割區上。(在此處,<application>Disklabel</application> 是使用
+ <literal>Partition name</literal>(分割區名稱),而非 slice 名稱)。
+ 此畫面也會顯示目前 slice 還有多少空間可供使用,
+ 換句話說就是尚未指定分割區的多餘空間。</para>
+
+ <para>在畫面中間,則顯示已建立的分割區、每個分割區的檔案系統名稱、
+ 所佔大小,以及一些參數。</para>
+
+ <para>在畫面下方,則顯示 <application>Disklabel</application>
+ 可用的按鍵。</para>
+
+ <figure xml:id="sysinstall-label">
+ <title>Sysinstall 的 Disklabel 編輯器</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/disklabel-ed1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para><application>Disklabel</application> 可自動分配分割區,
+ 並賦予預設值大小,按 <keycap>A</keycap> 即可自動完成。 您會看到類似
+ <xref linkend="sysinstall-label2"/> 的畫面。 不過,
+ 由於所用的硬碟大小不一,所以自動分配所設定的大小不一定合用,不要緊,
+ 您不一定得使用預設大小才可以。</para>
+
+ <note>
+ <para>預設會給 <filename>/tmp</filename> 目錄作為獨立分割區,
+ 而非附屬於 <filename>/</filename> 之下。 如此一來,
+ 可避免 <filename>/</filename> 會被一堆臨時檔案塞爆。</para>
+ </note>
+
+ <figure xml:id="sysinstall-label2">
+ <title>Sysinstall 的 Disklabel 編輯器 — 使用自動分配</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/disklabel-auto"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>如果您不想用自動分配分割區而希望自行設定,
+ 請用方向鍵選擇第一個分割區,並按下 <keycap>D</keycap> 刪除之。
+ 重複此動作直到刪除所有分割區。</para>
+
+ <para>建立第一個分割區(<literal>a</literal>,掛載為
+ <filename>/</filename> &mdash; 根目錄),
+ 請在畫面最上方選擇正確的磁碟分割磁區(slice)並按下
+ <keycap>C</keycap>。 接下來將出現對話框,
+ 會要求輸入新的分割區大小(如 <xref linkend="sysinstall-label-add"/> 所示)
+ 。 這邊可以直接輸入以 block 為單位,
+ 或者是以 <literal>M</literal>(MB)為單位、
+ 或以 <literal>G</literal>(GB)為單位,
+ 或者以 <literal>C</literal>(磁柱,cylinders) 為單位。</para>
+
+ <note><para>自 FreeBSD&nbsp;5.X 起,則可使用
+ <literal>Custom Newfs</literal> 選項來用 <acronym>UFS2</acronym>
+ (從 &os;&nbsp;5.1 起,此即為預設值)。 若是使用
+ <literal>Auto Defaults</literal> 自動預設的情況下,則可以再用
+ <literal>Custom Newfs</literal> 選項,或者在建立檔案系統時指定
+ <option>-O 2</option> 參數亦可。 若用 <literal>Custom Newfs</literal>
+ 選項的話,則別忘了要加上 <option>-U</option> 來啟用 SoftUpdates
+ 功能! </para></note>
+
+ <figure xml:id="sysinstall-label-add">
+ <title>根目錄的空間分配</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/disklabel-root1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>此處預設顯示的大小,會是整個 slice 的所有空間。
+ 若要採用先前例子所介紹的劃分大小,則按 <keycap>Backspace</keycap>
+ 鍵來消除這些數字,並輸入例子中的 <userinput>128M</userinput>,如
+ <xref linkend="sysinstall-label-add2"/> 所示。
+ 接著按下 &gui.ok;。</para>
+
+ <figure xml:id="sysinstall-label-add2">
+ <title>修改根目錄的空間分配</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/disklabel-root2"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>在輸入之後會問所要建立的是檔案系統(file system)或者是 swap 空間,
+ 如 <xref linkend="sysinstall-label-type"/> 所示。
+ 第一個選項為檔案系統,所以選擇 <guimenuitem>FS</guimenuitem>
+ 後按下<keycap>Enter</keycap>。</para>
+
+ <figure xml:id="sysinstall-label-type">
+ <title>選擇分割區的類型</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/disklabel-fs"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>最後,因為要新增的是檔案系統,所以必須告訴
+ <application>Disklabel</application> 要將其掛載至何處。 如 <xref linkend="sysinstall-label-mount"/> 所示。 根目錄檔案系統
+ 的掛載點為 <filename>/</filename>,所以請輸入 <userinput>/</userinput>
+ ,然後按下 <keycap>Enter</keycap>。</para>
+
+ <figure xml:id="sysinstall-label-mount">
+ <title>選擇根目錄的掛載點</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/disklabel-root3"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>剛所建立的分割區會顯示在畫面上,可以用上述類似動作來建立其他分割區。
+ 然而在建立 swap 分割區時,系統並不會問要掛載於哪邊,因為 swap
+ 空間是不必額外掛載的。 此外在建立最後分割區 <filename>/usr</filename>
+ 時,可以直接採用預設大小,也就是該 slice 剩餘的所有空間。</para>
+
+ <para>最後 FreeBSD 上的 DiskLabel 編輯器畫面會類似 <xref linkend="sysinstall-label4"/>,實際數字則依安裝選擇而有所不同。
+ 請按下 <keycap>Q</keycap> 即可完成分割區規劃。</para>
+
+ <figure xml:id="sysinstall-label4">
+ <title>Sysinstall Disklabel 編輯器</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/disklabel-ed2"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="install-choosing">
+ <title>選擇想要安裝的</title>
+
+ <sect2 xml:id="distset">
+ <title>選擇要安裝的套件集(Distribution Set)</title>
+
+ <para>要裝哪些套件,主要取決於該系統的用途為何及磁碟空間而定。
+ 預置的套件,從最小安裝到完整安裝都有。 若是 &unix; 或 FreeBSD
+ 新手,通常直接選其中之一即可。
+ 而自訂套件比較適合有經驗的人來用。</para>
+
+ <para>若要瞭解各套件的選項細節資訊,請按 <keycap>F1</keycap> 鍵。
+ 看完之後按 <keycap>Enter</keycap> 即會回到剛才的套件選擇畫面。</para>
+
+ <para>若需要 GUI 介面,那必需加選 <literal>X</literal>
+ 開頭的相關套件。 至於 X server 的設定及要用哪一類的桌面管理,必須在
+ &os; 裝好之後才能進行。 X server 設定細節部分請參閱 <xref linkend="x11"/>。</para>
+
+ <para>預設安裝的 X11 版本為 <application>&xorg;</application>。</para>
+
+ <para>若需要自訂 kernel,那麼需加選有含 source code 的選項。
+ 至於為何需自訂 kernel 及相關細節,請參閱
+ <xref linkend="kernelconfig"/>。</para>
+
+ <para>很明顯地,全部都裝就不用困擾需要裝什麼了。 若硬碟夠大,請以方向鍵選
+ <xref linkend="distribution-set1"/> 圖下的 <guimenuitem>All</guimenuitem>
+ 選項,並按下 <keycap>Enter</keycap> 即可。
+ 若硬碟空間不夠,請依自身需求選擇安裝。 當然在安裝完畢後,
+ 還是可以依需求再加裝其他套件。</para>
+
+ <figure xml:id="distribution-set1">
+ <title>選擇要裝的套件集(Distributions)</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/dist-set"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ </sect2>
+
+ <sect2 xml:id="portscol">
+ <title>安裝 Ports Collection</title>
+
+ <para>在裝完套件集之後,接著會問是否要裝 FreeBSD Ports 套件。 Ports
+ 套件可以讓您輕鬆安裝各種常見的軟體,它本身並不含那些軟體的原始碼,
+ 而是一個包含如何自動下載、編譯、安裝 third-party 軟體的檔案集合。
+ <xref linkend="ports"/> 會介紹如何使用 ports。</para>
+
+ <para>安裝程式並不會檢查是否有足夠空間來放 ports tree,
+ 所以請先確認有足夠空間。 目前 FreeBSD &rel.current; 的 FreeBSD
+ Ports Collection 大約需要 &ports.size; 的空間。 因此,
+ 可以推估更新版的 FreeBSD 會需要更多的空間來裝。</para>
+
+<screen> User Confirmation Requested
+ Would you like to install the FreeBSD ports collection?
+
+ This will give you ready access to over &os.numports; ported software packages,
+ at a cost of around &ports.size; of disk space when "clean" and possibly much
+ more than that if a lot of the distribution tarballs are loaded
+ (unless you have the extra CDs from a FreeBSD CD/DVD distribution
+ available and can mount it on /cdrom, in which case this is far less
+ of a problem).
+
+ The Ports Collection is a very valuable resource and well worth having
+ on your /usr partition, so it is advisable to say Yes to this option.
+
+ For more information on the Ports Collection &amp; the latest ports,
+ visit:
+ http://www.FreeBSD.org/ports
+
+ [ Yes ] No</screen>
+
+ <para>用方向鍵選 &gui.yes; 就會裝 Ports Collection,否則就選
+ &gui.no; 以略過。 選好後按 <keycap>Enter</keycap> 繼續,
+ 然後會再次回到選擇套件集的畫面。</para>
+
+ <figure xml:id="distribution-set2">
+ <title>確認要安裝的套件集</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/dist-set2"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>若要勾選的項目都確認沒問題的話,就以方向鍵選
+ <guimenuitem>Exit</guimenuitem> 退出並確認 &gui.ok; 有選到,然後按I
+ <keycap>Enter</keycap> 繼續。</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="install-media">
+ <title>選擇安裝來源</title>
+
+ <para>若要從 CDROM 或 DVD 安裝,用方向鍵將游標移到
+ <guimenuitem>Install from a FreeBSD CD/DVD</guimenuitem>,並確定
+ 選 &gui.ok; 後按下 <keycap>Enter</keycap> 就會開始裝了。</para>
+
+ <para>若是要用其他的方式安裝的話,請選擇適當的安裝來源,
+ 然後遵照螢幕指示進行安裝即可。</para>
+
+ <para>按 <keycap>F1</keycap> 可以顯示針對此部分(安裝來源)的線上說明。
+ 按一下 <keycap>Enter</keycap> 就會回到『選擇安裝來源』的畫面了。</para>
+
+ <figure xml:id="choose-media">
+ <title>選擇安裝來源</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/media"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <note>
+ <title>FTP 安裝模式</title>
+
+ <indexterm>
+ <primary>installation</primary>
+ <secondary>network</secondary>
+ <tertiary>FTP</tertiary>
+ </indexterm>
+
+ <para>使用 FTP 安裝的話,有分三種模式︰主動式(active)FTP、
+ 被動式(passive)FTP 或是透過 HTTP proxy server。</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>主動式 FTP:<guimenuitem>從 FTP server 安裝</guimenuitem></term>
+
+ <listitem>
+ <para>該選項會透過 <quote>Active</quote> 模式作 FTP 傳輸動作。
+ 這會無法穿過防火牆,但可用在那些較古早、不支援被動模式的 FTP
+ 站。 若 FTP 連線會卡住(預設為被動模式),
+ 那請改換主動模式看看!</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>被動式 FTP:<guimenuitem>透過防火牆,從 FTP server
+ 安裝</guimenuitem></term>
+
+ <listitem>
+ <indexterm>
+ <primary>FTP</primary>
+ <secondary>passive mode</secondary>
+ </indexterm>
+
+ <para>該選項會讓 <application>sysinstall</application> 全程使用
+ <quote>Passive(被動式)</quote> 來進行 FTP 連線,
+ 就可以穿過只允許使用固定 TCP port 連入的防火牆。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>透過 HTTP proxy 的 FTP:<guimenuitem>透過 http proxy 來從 FTP
+ 站安裝</guimenuitem></term>
+
+ <listitem>
+ <indexterm>
+ <primary>FTP</primary>
+ <secondary>via a HTTP proxy</secondary>
+ </indexterm>
+
+ <para>該選項會讓 <application>sysinstall</application> 的 FTP 連線,
+ 先透過 HTTP 協定(就像網頁瀏覽器一樣)連到 proxy server,而 proxy
+ server 會解譯送過來的的請求,然後轉送給 FTP server。
+ 這可以穿透只允許 HTTP 連線但不允許 FTP 連線的防火牆。
+ 但記得要用之時,必須指定 proxy server 的位址。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>對 proxy FTP server 而言,通常要在登入用的帳號名稱後面,
+ 加上 <quote>@</quote> 符號再加上要登入的 server 名稱。 然後,
+ proxy server 就會 <quote>fakes(偽裝)</quote> 為真的 server 樣子。
+ 舉個例子,若要到 <systemitem class="fqdomainname">ftp.FreeBSD.org</systemitem> 來裝,
+ 但中間透過 proxy FTP server 也就是
+ <systemitem class="fqdomainname">foo.example.com</systemitem> 並且使用 port 1234。</para>
+
+ <para>在此情況下,可以到 options 選單,將 FTP username 設為
+ <literal>ftp@ftp.FreeBSD.org</literal>,密碼則設為自己的 email 信箱。
+ 安裝來源部分,則使用 FTP (或 proxy 有支援的話,就用 passive FTP),
+ 而 URL 則用
+ <literal>ftp://foo.example.com:1234/pub/FreeBSD</literal>。</para>
+
+ <para>因為 <systemitem class="fqdomainname">ftp.FreeBSD.org</systemitem> 的
+ <filename>/pub/FreeBSD</filename> 會被 porxy 到
+ <systemitem class="fqdomainname">foo.example.com</systemitem>,所以就可以從
+ <systemitem class="fqdomainname">foo.example.com</systemitem> <emphasis>這台</emphasis>
+ 機器(這台會從 <systemitem class="fqdomainname">ftp.FreeBSD.org</systemitem> 抓檔回來給您)
+ 安裝。</para>
+ </note>
+ </sect1>
+
+ <sect1 xml:id="install-final-warning">
+ <title>開始進行安裝</title>
+
+
+ <para>到此為止,可以開始進行安裝了,
+ 這也是您避免更動到硬碟的最後機會。</para>
+
+ <screen> User Confirmation Requested
+ Last Chance! Are you SURE you want to continue the installation?
+
+ If you're running this on a disk with data you wish to save then WE
+ STRONGLY ENCOURAGE YOU TO MAKE PROPER BACKUPS before proceeding!
+
+ We can take no responsibility for lost disk contents!
+
+ [ Yes ] No</screen>
+
+ <para>選擇 &gui.yes; 並按下
+ <keycap>Enter</keycap>以確認真的要開始安裝</para>
+
+ <para>安裝所需時間會依據所選擇安裝的套件集(distribution)
+ 、安裝來源以及電腦速度而有所不同。
+ 在安裝的過程中,會有一些訊息顯示目前的安裝進度。</para>
+
+ <para>當您看到下面的訊息表示已經安裝完成了︰</para>
+
+ <screen> Message
+
+Congratulations! You now have FreeBSD installed on your system.
+
+We will now move on to the final configuration questions.
+For any option you do not wish to configure, simply select No.
+
+If you wish to re-enter this utility after the system is up, you may
+do so by typing: /usr/sbin/sysinstall.
+
+ [ OK ]
+
+ [ Press enter or space ]</screen>
+
+ <para>請按 <keycap>Enter</keycap> 鍵來進行相關的後續設定。</para>
+
+ <para>如果剛選的是 &gui.no; 並按下
+ <keycap>Enter</keycap> 鍵,那麼會中斷安裝(就不會動到你的原有系統)。
+ 接著,會出現以下訊息:</para>
+
+ <screen> Message
+Installation complete with some errors. You may wish to scroll
+through the debugging messages on VTY1 with the scroll-lock feature.
+You can also choose "No" at the next prompt and go back into the
+installation menus to retry whichever operations have failed.
+
+ [ OK ]</screen>
+
+ <para>這段訊息乃是因為都沒裝任何東西之故,請按 <keycap>Enter</keycap> 以跳回主畫面。</para>
+ </sect1>
+
+ <sect1 xml:id="install-post">
+ <title>後續安裝</title>
+
+ <para>安裝系統成功之後,可以在新裝好的 FreeBSD
+ 重開機之前,或者是事後再透過 <command>sysinstall</command>
+ (&os; 5.2 之前版本則是 <command>/stand/sysinstall</command>) 然後選擇
+ <guimenuitem>Configure</guimenuitem> 選項以進行後續設定。</para>
+
+ <sect2 xml:id="inst-network-dev">
+ <title>設定網路</title>
+
+ <para>如果您之前有設定用 PPP 連線透過 FTP 安裝,那麼這個畫面將不會出現;
+ 正如上面剛所說的,您可以稍後再做更改。</para>
+
+ <para>有關 LAN 或把 FreeBSD 設定為 gateway 或 router 請參閱使用手冊中有關
+ <link linkend="advanced-networking">網路進階運用</link> 的章節。</para>
+
+ <screen> User Confirmation Requested
+ Would you like to configure any Ethernet or SLIP/PPP network devices?
+
+ [ Yes ] No</screen>
+
+ <para>如果要設定網路卡,請選擇 &gui.yes; 然後按 <keycap>Enter</keycap>。
+ 否則請選 &gui.no; 以繼續。</para>
+
+ <figure xml:id="ed-config1">
+ <title>選擇網路卡</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/ed0-conf"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>用方向鍵選擇您要設定的網路卡,然後按 <keycap>Enter</keycap>。</para>
+
+ <screen> User Confirmation Requested
+ Do you want to try IPv6 configuration of the interface?
+
+ Yes [ No ]</screen>
+
+ <para>在私人區域網路的情況,由於目前的 Internet 協定
+ (<acronym>IPv4</acronym>)還算夠用,
+ 所以請選 &gui.no; 不設定 <acronym>IPv6</acronym>,然後按
+ <keycap>Enter</keycap>。</para>
+
+ <para>若是透過 <acronym>RA</acronym> server 連到既有的
+ <acronym>IPv6</acronym> 環境,那麼就選 &gui.yes; 並按
+ <keycap>Enter</keycap>,之後系統會花幾秒鐘去搜尋 RA server。</para>
+
+ <screen> User Confirmation Requested
+ Do you want to try DHCP configuration of the interface?
+
+ Yes [ No ]</screen>
+
+ <para>接下來,若不需要 DHCP (Dynamic Host Configuration Protocol)請選
+ &gui.no; 並按<keycap>Enter</keycap>。</para>
+
+ <para>選擇 &gui.yes; 的話,則會執行
+ <application>dhclient</application>,若成功要到 IP,
+ 則其會自動填上相關的環境設定,細節請參閱 <xref linkend="network-dhcp"/>。</para>
+
+ <para>下面的網路設定圖顯示如何在區域網路(LAN)中,
+ 將該機器設定為 gateway 的方式:</para>
+
+ <figure xml:id="ed-config2">
+ <title>設定 ed0 這張網路卡的網路設定</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/ed0-conf2"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>可用 <keycap>Tab</keycap> 鍵在各欄位間作切換,
+ 並填上適合的資料:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Host(機器名稱)</term>
+
+ <listitem>
+ <para>完整的機器名稱,例如本例中的
+ <systemitem class="fqdomainname">k6-2.example.com</systemitem>。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Domain(網域)</term>
+
+ <listitem>
+ <para>機器所屬的網域名稱,例如本例中的
+ <systemitem class="fqdomainname">example.com</systemitem>。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>IPv4 Gateway</term>
+
+ <listitem>
+ <para>這裡請輸入 Gateway 的 IP 位址,其可負責將封包轉遞到遠端網路。
+ 只有在該 gateway 屬於該網路其中節點之一時,才要輸入。
+ 若這機器本身要做為該區域網路的 gateway 的話,
+ <emphasis>請保持本欄為空白</emphasis>。 此外,
+ 通常 IPv4 Gateway 也會被認為是 default gateway 或
+ default route。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Name server(Name server 或 DNS server)</term>
+
+ <listitem>
+ <para>該網路所用的 DNS server 之 IP。 本例假設該機器所在的網路沒有
+ DNS,故填上的是該 ISP 所提供的 DNS server
+ (<systemitem class="ipaddress">208.163.10.2</systemitem>)。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>IPv4 address</term>
+
+ <listitem>
+ <para>The IP address to be used for this interface was
+ <systemitem class="ipaddress">192.168.0.1</systemitem></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Netmask</term>
+
+ <listitem>
+ <para>The address block being used for this local area
+ network is a Class C block
+ (<systemitem class="ipaddress">192.168.0.0</systemitem> -
+ <systemitem class="ipaddress">192.168.0.255</systemitem>).
+ The default netmask is for a Class C network
+ (<systemitem class="netmask">255.255.255.0</systemitem>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Extra options to ifconfig</term>
+
+ <listitem>
+ <para>Any interface-specific options to <command>ifconfig</command>
+ you would like to add. There were none in this case.</para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>Use <keycap>Tab</keycap> to select &gui.ok;
+ when finished and press <keycap>Enter</keycap>.</para>
+
+
+ <screen> User Confirmation Requested
+ Would you like to Bring Up the ed0 interface right now?
+
+ [ Yes ] No</screen>
+
+ <para>Choosing &gui.yes; and pressing
+ <keycap>Enter</keycap> will bring
+ the machine up on the network and be ready for use. However,
+ this does not accomplish much during installation, since
+ the machine still needs to be rebooted.</para>
+ </sect2>
+
+ <sect2 xml:id="gateway">
+ <title>Configure Gateway</title>
+
+ <screen> User Confirmation Requested
+ Do you want this machine to function as a network gateway?
+
+ [ Yes ] No</screen>
+
+ <para>If the machine will be acting as the gateway for a local area
+ network and forwarding packets between other machines then select
+ &gui.yes; and press <keycap>Enter</keycap>.
+ If the machine is a node on a network then
+ select &gui.no; and press
+ <keycap>Enter</keycap> to continue.</para>
+ </sect2>
+
+ <sect2 xml:id="inetd-services">
+ <title>Configure Internet Services</title>
+
+ <screen> User Confirmation Requested
+Do you want to configure inetd and the network services that it provides?
+
+ Yes [ No ]</screen>
+
+ <para>If &gui.no; is selected, various services
+ such <application>telnetd</application> will not be enabled. This
+ means that remote users will not be able to
+ <application>telnet</application> into this machine. Local users
+ will still be able to access remote machines with
+ <application>telnet</application>.</para>
+
+ <para>These services can be enabled after installation by editing
+ <filename>/etc/inetd.conf</filename> with your favorite text editor.
+ See <xref linkend="network-inetd-overview"/> for more information.</para>
+
+ <para>Select &gui.yes; if you wish to
+ configure these services during install. An additional
+ confirmation will display:</para>
+
+ <screen> User Confirmation Requested
+The Internet Super Server (inetd) allows a number of simple Internet
+services to be enabled, including finger, ftp and telnetd. Enabling
+these services may increase risk of security problems by increasing
+the exposure of your system.
+
+With this in mind, do you wish to enable inetd?
+
+ [ Yes ] No</screen>
+
+ <para>Select &gui.yes; to continue.</para>
+
+ <screen> User Confirmation Requested
+inetd(8) relies on its configuration file, /etc/inetd.conf, to determine
+which of its Internet services will be available. The default FreeBSD
+inetd.conf(5) leaves all services disabled by default, so they must be
+specifically enabled in the configuration file before they will
+function, even once inetd(8) is enabled. Note that services for
+IPv6 must be separately enabled from IPv4 services.
+
+Select [Yes] now to invoke an editor on /etc/inetd.conf, or [No] to
+use the current settings.
+
+ [ Yes ] No</screen>
+
+ <para>Selecting &gui.yes; will allow adding
+ services by deleting the <literal>#</literal> at the beginning
+ of a line.</para>
+
+ <figure xml:id="inetd-edit">
+ <title>Editing <filename>inetd.conf</filename></title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/edit-inetd-conf"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>After adding the desired services, pressing <keycap>Esc</keycap>
+ will display a menu which will allow exiting and saving
+ the changes.</para>
+
+ </sect2>
+
+ <sect2 xml:id="ssh-login">
+ <title>啟用 SSH 登入</title>
+
+ <indexterm>
+ <primary>SSH</primary>
+ <secondary>sshd</secondary>
+ </indexterm>
+
+ <screen> User Confirmation Requested
+ Would you like to enable SSH login?
+ Yes [ No ]</screen>
+
+ <para>選擇 &gui.yes; 就會啟用 &man.sshd.8;,也就是
+ <application>OpenSSH</application> 的 daemon 程式。
+ 這會允許該機器可從遠端安全登入。 關於
+ <application>OpenSSH</application> 請參閱 <xref linkend="openssh"/> 部分的說明。</para>
+ </sect2>
+
+ <sect2 xml:id="ftpanon">
+ <title>Anonymous FTP</title>
+
+ <indexterm>
+ <primary>FTP</primary>
+ <secondary>anonymous</secondary>
+ </indexterm>
+
+ <screen> User Confirmation Requested
+ Do you want to have anonymous FTP access to this machine?
+
+ Yes [ No ]</screen>
+
+ <sect3 xml:id="deny-anon">
+ <title>Deny Anonymous FTP</title>
+
+ <para>Selecting the default &gui.no; and pressing
+ <keycap>Enter</keycap> will still allow users who have accounts
+ with passwords to use FTP to access the machine.</para>
+ </sect3>
+
+ <sect3 xml:id="ftpallow">
+ <title>Allow Anonymous FTP</title>
+
+ <para>Anyone can access your machine if you elect to allow
+ anonymous FTP connections. The security implications should be
+ considered before enabling this option. For more information
+ about security see <xref linkend="security"/>.</para>
+
+ <para>To allow anonymous FTP, use the arrow keys to select
+ &gui.yes; and press <keycap>Enter</keycap>.
+ The following screen (or similar) will display:</para>
+
+ <figure xml:id="anon-ftp2">
+ <title>Default Anonymous FTP Configuration</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/ftp-anon1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Pressing <keycap>F1</keycap> will display the help:</para>
+
+ <screen>This screen allows you to configure the anonymous FTP user.
+
+The following configuration values are editable:
+
+UID: The user ID you wish to assign to the anonymous FTP user.
+ All files uploaded will be owned by this ID.
+
+Group: Which group you wish the anonymous FTP user to be in.
+
+Comment: String describing this user in /etc/passwd
+
+
+FTP Root Directory:
+
+ Where files available for anonymous FTP will be kept.
+
+Upload subdirectory:
+
+ Where files uploaded by anonymous FTP users will go.</screen>
+
+ <para>The ftp root directory will be put in <filename>/var</filename>
+ by default. If you do not have enough room there for the
+ anticipated FTP needs, the <filename>/usr</filename> directory
+ could be used by setting the FTP Root Directory to
+ <filename>/usr/ftp</filename>.</para>
+
+ <para>When you are satisfied with the values, press
+ <keycap>Enter</keycap> to continue.</para>
+
+ <screen> User Confirmation Requested
+ Create a welcome message file for anonymous FTP users?
+
+ [ Yes ] No</screen>
+
+ <para>If you select &gui.yes; and press
+ <keycap>Enter</keycap>, an editor will automatically start
+ allowing you to edit the message.</para>
+
+ <figure xml:id="anon-ftp4">
+ <title>Edit the FTP Welcome Message</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/ftp-anon2"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>This is a text editor called <command>ee</command>. Use the
+ instructions to change the message or change the message later
+ using a text editor of your choice. Note the file name/location
+ at the bottom of the editor screen.</para>
+
+ <para>Press <keycap>Esc</keycap> and a pop-up menu will default
+ to <guimenuitem>a) leave editor</guimenuitem>. Press
+ <keycap>Enter</keycap> to exit and continue. Press
+ <keycap>Enter</keycap> again to save changes if you made
+ any.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="nfsconf">
+ <title>Configure Network File System</title>
+
+ <para>Network File System (NFS) allows sharing of files across a
+ network. A machine can be configured as a server, a client, or
+ both. Refer to <xref linkend="network-nfs"/> for a more information.</para>
+
+ <sect3 xml:id="nsf-server-options">
+ <title>NFS Server</title>
+
+ <screen> User Confirmation Requested
+ Do you want to configure this machine as an NFS server?
+
+ Yes [ No ]</screen>
+
+ <para>If there is no need for a Network File System server,
+ select &gui.no; and press
+ <keycap>Enter</keycap>.</para>
+
+ <para>If &gui.yes; is chosen, a message will
+ pop-up indicating that the <filename>exports</filename> file must be
+ created.</para>
+
+ <screen> Message
+Operating as an NFS server means that you must first configure an
+/etc/exports file to indicate which hosts are allowed certain kinds of
+access to your local filesystems.
+Press [Enter] now to invoke an editor on /etc/exports
+ [ OK ]</screen>
+
+ <para>Press <keycap>Enter</keycap> to continue. A text editor will
+ start allowing the <filename>exports</filename> file to be created
+ and edited.</para>
+
+ <figure xml:id="nfs-server-edit">
+ <title>Editing <filename>exports</filename></title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/nfs-server-edit"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Use the instructions to add the actual exported filesystems
+ now or later using a text editor of your choice. Note the
+ file name/location at the bottom of the editor screen.</para>
+
+ <para>Press <keycap>Esc</keycap> and a pop-up menu will default to
+ <guimenuitem>a) leave editor</guimenuitem>. Press
+ <keycap>Enter</keycap> to exit and continue.</para>
+ </sect3>
+
+ <sect3 xml:id="nfs-client-options">
+ <title>NFS Client</title>
+
+ <para>The NFS client allows your machine to access NFS servers.</para>
+
+ <screen> User Confirmation Requested
+ Do you want to configure this machine as an NFS client?
+
+ Yes [ No ]</screen>
+
+ <para>With the arrow keys, select &gui.yes;
+ or &gui.no; as appropriate and
+ press <keycap>Enter</keycap>.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="console">
+ <title>System Console Settings</title>
+
+ <para>There are several options available to customize the system
+ console.</para>
+
+ <screen> User Confirmation Requested
+ Would you like to customize your system console settings?
+
+ [ Yes ] No</screen>
+
+ <para>To view and configure the options, select
+ &gui.yes; and press
+ <keycap>Enter</keycap>.</para>
+
+ <figure xml:id="saver-options">
+ <title>System Console Configuration Options</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/console-saver1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>A commonly used option is the screen saver. Use the arrow keys
+ to select <guimenuitem>Saver</guimenuitem> and then press
+ <keycap>Enter</keycap>.</para>
+
+ <figure xml:id="saver-select">
+ <title>Screen Saver Options</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/console-saver2"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Select the desired screen saver using the arrow keys
+ and then press <keycap>Enter</keycap>. The System Console
+ Configuration menu will redisplay.</para>
+
+ <para>The default time interval is 300 seconds. To change the time
+ interval, select <guimenuitem>Saver</guimenuitem> again. At the
+ Screen Saver Options menu, select <guimenuitem>Timeout</guimenuitem>
+ using the arrow keys and press <keycap>Enter</keycap>. A pop-up
+ menu will appear:</para>
+
+ <figure xml:id="saver-timeout">
+ <title>Screen Saver Timeout</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/console-saver3"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>The value can be changed, then select &gui.ok;
+ and press <keycap>Enter</keycap> to return to the System Console
+ Configuration menu.</para>
+
+ <figure xml:id="saver-exit">
+ <title>System Console Configuration Exit</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/console-saver4"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Selecting <guimenuitem>Exit</guimenuitem> and pressing
+ <keycap>Enter</keycap> will continue with the post-installation
+ configurations.</para>
+ </sect2>
+
+ <sect2 xml:id="timezone">
+ <title>Setting the Time Zone</title>
+
+ <para>Setting the time zone for your machine will allow it to
+ automatically correct for any regional time changes and perform
+ other time zone related functions properly.</para>
+
+ <para>The example shown is for a machine located in the Eastern
+ time zone of the United States. Your selections will vary according
+ to your geographical location.</para>
+
+ <screen> User Confirmation Requested
+ Would you like to set this machine's time zone now?
+
+ [ Yes ] No</screen>
+
+ <para>Select &gui.yes; and press
+ <keycap>Enter</keycap> to set the time zone.</para>
+
+ <screen> User Confirmation Requested
+ Is this machine's CMOS clock set to UTC? If it is set to local time
+ or you don't know, please choose NO here!
+
+ Yes [ No ]</screen>
+
+ <para>Select &gui.yes;
+ or &gui.no; according to how the machine's
+ clock is configured and press <keycap>Enter</keycap>.</para>
+
+ <figure xml:id="set-timezone-region">
+ <title>Select Your Region</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/timezone1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>The appropriate region is selected using the arrow keys
+ and then pressing <keycap>Enter</keycap>.</para>
+
+ <figure xml:id="set-timezone-country">
+ <title>Select Your Country</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/timezone2"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Select the appropriate country using the arrow keys
+ and press <keycap>Enter</keycap>.</para>
+
+ <figure xml:id="set-timezone-locality">
+ <title>Select Your Time Zone</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/timezone3"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>The appropriate time zone is selected using the arrow
+ keys and pressing <keycap>Enter</keycap>.</para>
+
+ <screen> Confirmation
+ Does the abbreviation 'EDT' look reasonable?
+
+ [ Yes ] No</screen>
+
+ <para>Confirm the abbreviation for the time zone is correct.
+ If it looks okay, press <keycap>Enter</keycap> to continue with
+ the post-installation configuration.</para>
+ </sect2>
+
+ <sect2 xml:id="linuxcomp">
+ <title>Linux Compatibility</title>
+
+ <screen> User Confirmation Requested
+ Would you like to enable Linux binary compatibility?
+
+ [ Yes ] No</screen>
+
+ <para>Selecting &gui.yes; and pressing
+ <keycap>Enter</keycap> will allow
+ running Linux software on FreeBSD. The install will add
+ the appropriate packages for Linux compatibility.</para>
+
+ <para>If installing by FTP, the machine will need to be connected to
+ the Internet. Sometimes a remote ftp site will not have all the
+ distributions like the Linux binary compatibility. This can
+ be installed later if necessary.</para>
+ </sect2>
+
+ <sect2 xml:id="mouse">
+ <title>Mouse Settings</title>
+
+ <para>This option will allow you to cut and paste text in the
+ console and user programs with a 3-button mouse. If using a 2-button
+ mouse, refer to manual page, &man.moused.8;, after installation for
+ details on emulating the 3-button style. This example depicts a
+ non-USB mouse configuration (such as a PS/2 or COM port mouse):</para>
+
+ <screen> User Confirmation Requested
+ Does this system have a PS/2, serial, or bus mouse?
+
+ [ Yes ] No </screen>
+
+ <para>Select &gui.yes; for a PS/2, serial, or bus mouse, or
+ &gui.no; for a USB mouse and press
+ <keycap>Enter</keycap>.</para>
+
+ <figure xml:id="mouse-protocol">
+ <title>Select Mouse Protocol Type</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/mouse1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Use the arrow keys to select <guimenuitem>Type</guimenuitem> and
+ press <keycap>Enter</keycap>.</para>
+
+ <figure xml:id="set-mouse-protocol">
+ <title>Set Mouse Protocol</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/mouse2"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>The mouse used in this example is a PS/2 type, so the default
+ <guimenuitem>Auto</guimenuitem> was appropriate. To change protocol,
+ use the arrow keys to select another option. Ensure that &gui.ok; is
+ highlighted and press <keycap>Enter</keycap> to exit this menu.</para>
+
+ <figure xml:id="config-mouse-port">
+ <title>Configure Mouse Port</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/mouse3"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Use the arrow keys to select <guimenuitem>Port</guimenuitem> and
+ press <keycap>Enter</keycap>.</para>
+
+ <figure xml:id="set-mouse-port">
+ <title>Setting the Mouse Port</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/mouse4"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>This system had a PS/2 mouse, so the default
+ <guimenuitem>PS/2</guimenuitem> was appropriate. To change the port,
+ use the arrow keys and then press <keycap>Enter</keycap>.</para>
+
+ <figure xml:id="test-daemon">
+ <title>Enable the Mouse Daemon</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/mouse5"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Last, use the arrow keys to select
+ <guimenuitem>Enable</guimenuitem>, and press
+ <keycap>Enter</keycap> to enable and test the mouse
+ daemon.</para>
+
+
+ <figure xml:id="test-mouse-daemon">
+ <title>Test the Mouse Daemon</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/mouse6"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Move the mouse around the screen and verify the cursor
+ shown responds properly. If it does, select
+ &gui.yes; and press <keycap>Enter</keycap>. If
+ not, the mouse has not been configured correctly &mdash; select
+ &gui.no; and try using different configuration
+ options.</para>
+
+ <para>Select <guimenuitem>Exit</guimenuitem> with the arrow keys
+ and press <keycap>Enter</keycap> to return to continue with the
+ post-installation configuration.</para>
+ </sect2>
+
+ <sect2 xml:id="packages">
+ <title>Install Packages</title>
+
+ <para>Packages are pre-compiled binaries and are a convenient
+ way to install software.</para>
+
+ <para>Installation of one package is shown for purposes of
+ illustration. Additional packages can also be added at this
+ time if desired. After installation
+ <command>sysinstall</command> can be used to add additional
+ packages.</para>
+
+ <screen> User Confirmation Requested
+ The FreeBSD package collection is a collection of hundreds of
+ ready-to-run applications, from text editors to games to WEB servers
+ and more. Would you like to browse the collection now?
+
+ [ Yes ] No</screen>
+
+ <para>Selecting &gui.yes; and pressing
+ <keycap>Enter</keycap> will be
+ followed by the Package Selection screens:</para>
+
+ <figure xml:id="package-category">
+ <title>Select Package Category</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/pkg-cat"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Only packages on the current installation media are
+ available for installation at any given time.</para>
+
+ <para>All packages available will be displayed if
+ <guimenuitem>All</guimenuitem> is selected or you can select a
+ particular category. Highlight your selection with the arrow
+ keys and press <keycap>Enter</keycap>.</para>
+
+ <para>A menu will display showing all the packages available for
+ the selection made:</para>
+
+ <figure xml:id="package-select">
+ <title>Select Packages</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/pkg-sel"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>The <application>bash</application> shell is shown selected.
+ Select as many as desired by highlighting the package and pressing the
+ <keycap>Space</keycap> key. A short description of each package will
+ appear in the lower left corner of the screen.</para>
+
+ <para>Pressing the <keycap>Tab</keycap> key will toggle between the last
+ selected package, &gui.ok;, and &gui.cancel;.</para>
+
+ <para>When you have finished marking the packages for installation,
+ press <keycap>Tab</keycap> once to toggle to the &gui.ok; and press
+ <keycap>Enter</keycap> to return to the Package Selection menu.</para>
+
+ <para>The left and right arrow keys will also toggle between &gui.ok;
+ and &gui.cancel;. This method can also be used to select &gui.ok; and
+ press <keycap>Enter</keycap> to return to the Package Selection
+ menu.</para>
+
+ <figure xml:id="package-install">
+ <title>Install Packages</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/pkg-install"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Use the <keycap>Tab</keycap> and arrow keys to select <guibutton>[&nbsp;Install&nbsp;]</guibutton>
+ and press <keycap>Enter</keycap>. You will then need to confirm
+ that you want to install the packages:</para>
+
+ <figure xml:id="package-install-confirm">
+ <title>Confirm Package Installation</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/pkg-confirm"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Selecting &gui.ok; and pressing <keycap>Enter</keycap> will start
+ the package installation. Installing messages will appear until
+ completed. Make note if there are any error messages.</para>
+
+ <para>The final configuration continues after packages are
+ installed. If you end up not selecting any packages, and wish
+ to return to the final configuration, select
+ <guibutton>Install</guibutton> anyways.</para>
+ </sect2>
+
+ <sect2 xml:id="addusers">
+ <title>Add Users/Groups</title>
+
+ <para>You should add at least one user during the installation so
+ that you can use the system without being logged in as
+ <systemitem class="username">root</systemitem>. The root partition is generally small
+ and running applications as <systemitem class="username">root</systemitem> can quickly
+ fill it. A bigger danger is noted below:</para>
+
+ <screen> User Confirmation Requested
+ Would you like to add any initial user accounts to the system? Adding
+ at least one account for yourself at this stage is suggested since
+ working as the "root" user is dangerous (it is easy to do things which
+ adversely affect the entire system).
+
+ [ Yes ] No</screen>
+
+ <para>Select &gui.yes; and press
+ <keycap>Enter</keycap> to continue with adding a user.</para>
+
+ <figure xml:id="add-user2">
+ <title>Select User</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/adduser1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Select <guimenuitem>User</guimenuitem> with the arrow keys
+ and press <keycap>Enter</keycap>.</para>
+
+ <figure xml:id="add-user3">
+ <title>Add User Information</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/adduser2"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>The following descriptions will appear in the lower part of
+ the screen as the items are selected with <keycap>Tab</keycap>
+ to assist with entering the required information:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Login ID</term>
+
+ <listitem>
+ <para>The login name of the new user (mandatory).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>UID</term>
+
+ <listitem>
+ <para>The numerical ID for this user (leave blank for
+ automatic choice).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Group</term>
+
+ <listitem>
+ <para>The login group name for this user (leave blank for
+ automatic choice).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Password</term>
+
+ <listitem>
+ <para>The password for this user (enter this field with
+ care!).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Full name</term>
+
+ <listitem>
+ <para>The user's full name (comment).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Member groups</term>
+
+ <listitem>
+ <para>The groups this user belongs to (i.e. gets access
+ rights for).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Home directory</term>
+
+ <listitem>
+ <para>The user's home directory (leave blank for
+ default).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Login shell</term>
+ <listitem>
+ <para>The user's login shell (leave blank for
+ default, e.g. <filename>/bin/sh</filename>).</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>The login shell was changed from <filename>/bin/sh</filename> to
+ <filename>/usr/local/bin/bash</filename> to use the
+ <application>bash</application> shell that was previously installed as
+ a package. Do not try to use a shell that does not exist or you will
+ not be able to login. The most common shell used in the
+ BSD-world is the C shell, which can be indicated as
+ <filename>/bin/tcsh</filename>.</para>
+
+ <para>The user was also added to the <systemitem class="groupname">wheel</systemitem> group
+ to be able to become a superuser with <systemitem class="username">root</systemitem>
+ privileges.</para>
+
+ <para>When you are satisfied, press &gui.ok; and
+ the User and Group Management menu will redisplay:</para>
+
+ <figure xml:id="add-user4">
+ <title>Exit User and Group Management</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/adduser3"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Groups can also be added at this time if specific needs
+ are known. Otherwise, this may be accessed through using
+ <command>sysinstall</command> (<command>/stand/sysinstall</command>
+ in &os; versions older than 5.2) after installation is
+ completed.</para>
+
+ <para>When you are finished adding users, select
+ <guimenuitem>Exit</guimenuitem> with the arrow keys and press
+ <keycap>Enter</keycap> to continue the installation.</para>
+ </sect2>
+
+ <sect2 xml:id="rootpass">
+ <title>Set the <systemitem class="username">root</systemitem> Password</title>
+
+ <screen> Message
+ Now you must set the system manager's password.
+ This is the password you'll use to log in as "root".
+
+ [ OK ]
+
+ [ Press enter or space ]</screen>
+
+ <para>Press <keycap>Enter</keycap> to set the <systemitem class="username">root</systemitem>
+ password.</para>
+
+ <para>The password will need to be typed in twice correctly. Needless to
+ say, make sure you have a way of finding the password if you
+ forget. Notice that the password you type in is not echoed, nor
+ are asterisks displayed.</para>
+
+ <screen>New password :
+Retype new password :</screen>
+
+ <para>The installation will continue after the password is
+ successfully entered.</para>
+ </sect2>
+
+ <sect2 xml:id="exit-inst">
+ <title>Exiting Install</title>
+
+ <para>If you need to configure <link linkend="network-services">additional network devices</link> or
+ any other configuration, you can do it at this point or
+ after installation with <command>sysinstall</command>
+ (<command>/stand/sysinstall</command> in &os; versions older
+ than 5.2).</para>
+
+ <screen> User Confirmation Requested
+ Visit the general configuration menu for a chance to set any last
+ options?
+
+ Yes [ No ]</screen>
+
+ <para>Select &gui.no; with the arrow keys
+ and press <keycap>Enter</keycap> to return to the Main
+ Installation Menu.</para>
+
+ <figure xml:id="final-main">
+ <title>Exit Install</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/mainexit"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Select <guibutton>[X Exit Install]</guibutton> with the arrow
+ keys and press <keycap>Enter</keycap>. You will be asked to
+ confirm exiting the installation:</para>
+
+ <screen> User Confirmation Requested
+ Are you sure you wish to exit? The system will reboot (be sure to
+ remove any floppies/CDs/DVDs from the drives).
+
+ [ Yes ] No</screen>
+
+ <para>Select &gui.yes; and remove the floppy if
+ booting from the floppy. The CDROM drive is locked until the machine
+ starts to reboot. The CDROM drive is then unlocked and the disk can
+ be removed from drive (quickly).</para>
+
+ <para>The system will reboot so watch for any error messages that
+ may appear, see <xref linkend="freebsdboot"/>
+ details.</para>
+ </sect2>
+
+ <sect2 xml:id="network-services">
+ <info><title>Configure Additional Network Services</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <para>Configuring network services can be a daunting
+ task for new users if they lack previous
+ knowledge in this area. Networking, including the Internet,
+ is critical to all modern operating systems including &os;;
+ as a result, it is very useful to have some understanding
+ &os;'s extensive networking capabilities. Doing this
+ during the installation will ensure users have some
+ understanding of the various services available to them.</para>
+
+ <para>Network services are programs that accept input from
+ anywhere on the network. Every effort is made to make sure
+ these programs will not do anything <quote>harmful</quote>.
+ Unfortunately, programmers are not perfect and through time
+ there have been cases where bugs in network services have been
+ exploited by attackers to do bad things. It is important that
+ you only enable the network services you know that you need. If
+ in doubt it is best if you do not enable a network service until
+ you find out that you do need it. You can always enable it
+ later by re-running <application>sysinstall</application> or by
+ using the features provided by the
+ <filename>/etc/rc.conf</filename> file.</para>
+
+ <para>Selecting the <guimenu>Networking</guimenu> option will display
+ a menu similar to the one below:</para>
+
+ <figure xml:id="network-configuration">
+ <title>Network Configuration Upper-level</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/net-config-menu1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>The first option, <guimenuitem>Interfaces</guimenuitem>, was previously covered during
+ the <xref linkend="inst-network-dev"/>, thus this option can
+ safely be ignored.</para>
+
+ <para>Selecting the <guimenuitem>AMD</guimenuitem> option adds
+ support for the <acronym>BSD</acronym> automatic mount utility.
+ This is usually used in conjunction with the
+ <acronym>NFS</acronym> protocol (see below)
+ for automatically mounting remote file systems.
+ No special configuration is required here.</para>
+
+ <para>Next in line is the <guimenuitem>AMD Flags</guimenuitem>
+ option. When selected, a menu will pop up for you
+ to enter specific <acronym>AMD</acronym> flags.
+ The menu already contains a set of default options:</para>
+
+ <screen>-a /.amd_mnt -l syslog /host /etc/amd.map /net /etc/amd.map</screen>
+
+ <para>The <option>-a</option> option sets the default mount
+ location which is specified here as
+ <filename>/.amd_mnt</filename>. The <option>-l</option>
+ option specifies the default <filename>log</filename> file;
+ however, when <literal>syslogd</literal> is used all log
+ activity will be sent to the system log daemon. The
+ <filename>/host</filename> directory is used
+ to mount an exported file system from a remote
+ host, while <filename>/net</filename>
+ directory is used to mount an exported file system from an
+ <acronym>IP</acronym> address. The
+ <filename>/etc/amd.map</filename> file defines the default
+ options for <acronym>AMD</acronym> exports.</para>
+
+ <indexterm>
+ <primary>FTP</primary>
+ <secondary>anonymous</secondary>
+ </indexterm>
+
+ <para>The <guimenuitem>Anon FTP</guimenuitem> option permits anonymous
+ <acronym>FTP</acronym> connections. Select this option to
+ make this machine an anonymous <acronym>FTP</acronym> server.
+ Be aware of the security risks involved with this option.
+ Another menu will be displayed to explain the security risks
+ and configuration in depth.</para>
+
+ <para>The <guimenuitem>Gateway</guimenuitem> configuration menu will set
+ the machine up to be a gateway as explained previously. This
+ can be used to unset the <guimenuitem>Gateway</guimenuitem> option if you accidentally
+ selected it during the installation process.</para>
+
+ <para>The <guimenuitem>Inetd</guimenuitem> option can be used to configure
+ or completely disable the &man.inetd.8; daemon as discussed
+ above.</para>
+
+ <para>The <guimenuitem>Mail</guimenuitem> option is used to configure the system's
+ default <acronym>MTA</acronym> or Mail Transfer Agent.
+ Selecting this option will bring up the following menu:</para>
+
+ <figure xml:id="mta-selection">
+ <title>Select a default MTA</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/mta-main"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>Here you are offered a choice as to which
+ <acronym>MTA</acronym> to install
+ and set as the default. An <acronym>MTA</acronym> is nothing
+ more than a mail server which delivers email to users on the
+ system or the Internet.</para>
+
+ <para>Selecting <guimenuitem>Sendmail</guimenuitem> will install
+ the popular <application>sendmail</application> server which
+ is the &os; default. The <guimenuitem>Sendmail local</guimenuitem> option
+ will set <application>sendmail</application> to be the default
+ <acronym>MTA</acronym>, but disable its ability to receive
+ incoming email from the Internet. The other options here,
+ <guimenuitem>Postfix</guimenuitem> and
+ <guimenuitem>Exim</guimenuitem> act similar to
+ <guimenuitem>Sendmail</guimenuitem>. They both deliver
+ email; however, some users prefer these alternatives to the
+ <application>sendmail</application>
+ <acronym>MTA</acronym>.</para>
+
+ <para>After selecting an <acronym>MTA</acronym>, or choosing
+ not to select an MTA, the network configuration menu will appear
+ with the next option being <guimenuitem>NFS client</guimenuitem>.</para>
+
+ <para>The <guimenuitem>NFS client</guimenuitem> option will
+ configure the system to communicate with a server via
+ <acronym>NFS</acronym>. An <acronym>NFS</acronym> server
+ makes file systems available to other machines on the
+ network via the <acronym>NFS</acronym> protocol. If this is
+ a stand-alone machine, this option can remain unselected.
+ The system may require more configuration later; see
+ <xref linkend="network-nfs"/> for more
+ information about client and server configuration.</para>
+
+ <para>Below that option is the <guimenuitem>NFS server</guimenuitem>
+ option, permitting you to set the system up as an
+ <acronym>NFS</acronym> server. This adds the required
+ information to start up the <acronym>RPC</acronym> remote
+ procedure call services. <acronym>RPC</acronym> is used to
+ coordinate connections between hosts and programs.</para>
+
+ <para>Next in line is the <guimenuitem>Ntpdate</guimenuitem> option,
+ which deals with time synchronization. When selected, a menu
+ like the one below shows up:</para>
+
+ <figure xml:id="Ntpdate-config">
+ <title>Ntpdate Configuration</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/ntp-config"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>From this menu, select the server which is the closest
+ to your location. Selecting a close one will make the time
+ synchronization more accurate as a server further from your
+ location may have more connection latency.</para>
+
+ <para>The next option is the <acronym>PCNFSD</acronym> selection.
+ This option will install the
+ <package>net/pcnfsd</package> package from
+ the Ports Collection. This is a useful utility which provides
+ <acronym>NFS</acronym> authentication services for systems which
+ are unable to provide their own, such as Microsoft's
+ &ms-dos; operating system.</para>
+
+ <para>Now you must scroll down a bit to see the other
+ options:</para>
+
+ <figure xml:id="Network-configuration-cont">
+ <title>Network Configuration Lower-level</title>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="install/net-config-menu2"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>The &man.rpcbind.8;, &man.rpc.statd.8;, and
+ &man.rpc.lockd.8; utilities are all used for Remote Procedure
+ Calls (<acronym>RPC</acronym>).
+ The <command>rpcbind</command> utility manages communication
+ between <acronym>NFS</acronym> servers and clients, and is
+ required for <acronym>NFS</acronym> servers to operate
+ correctly. The <application>rpc.statd</application> daemon interacts
+ with the <application>rpc.statd</application> daemon on other hosts to
+ provide status monitoring. The reported status is usually held
+ in the <filename>/var/db/statd.status</filename> file. The
+ next option listed here is the <guimenuitem>rpc.lockd</guimenuitem>
+ option, which, when selected, will provide file locking
+ services. This is usually used with
+ <application>rpc.statd</application> to monitor what hosts are
+ requesting locks and how frequently they request them.
+ While these last two options are marvelous for debugging, they
+ are not required for <acronym>NFS</acronym> servers and clients
+ to operate correctly.</para>
+
+ <para>As you progress down the list the next item here is
+ <guimenuitem>Routed</guimenuitem>, which is the routing daemon. The
+ &man.routed.8; utility manages network routing tables,
+ discovers multicast routers, and supplies a copy of the routing
+ tables to any physically connected host on the network upon
+ request. This is mainly used for machines which act as a
+ gateway for the local network. When selected, a menu will be
+ presented requesting the default location of the utility.
+ The default location is already defined for you and can be
+ selected with the <keycap>Enter</keycap> key. You will then
+ be presented with yet another menu, this time asking for the
+ flags you wish to pass on to <application>routed</application>. The
+ default is <option>-q</option> and it should already appear
+ on the screen.</para>
+
+ <para>Next in line is the <guimenuitem>Rwhod</guimenuitem> option which,
+ when selected, will start the &man.rwhod.8; daemon
+ during system initialization. The <command>rwhod</command>
+ utility broadcasts system messages across the network
+ periodically, or collects them when in <quote>consumer</quote>
+ mode. More information can be found in the &man.ruptime.1; and
+ &man.rwho.1; manual pages.</para>
+
+ <para>The next to the last option in the list is for the
+ &man.sshd.8; daemon. This is the secure shell server for
+ <application>OpenSSH</application> and it is highly recommended
+ over the standard <application>telnet</application> and
+ <acronym>FTP</acronym> servers. The <application>sshd</application>
+ server is used to create a secure connection from one host to
+ another by using encrypted connections.</para>
+
+ <para>Finally there is the <guimenuitem>TCP Extensions</guimenuitem>
+ option. This enables the <acronym>TCP</acronym> Extensions
+ defined in <acronym>RFC</acronym>&nbsp;1323 and
+ <acronym>RFC</acronym>&nbsp;1644. While on many hosts this can
+ speed up connections, it can also cause some connections to be
+ dropped. It is not recommended for servers, but may be
+ beneficial for stand alone machines.</para>
+
+ <para>Now that you have configured the network services, you can
+ scroll up to the very top item which is <guimenuitem>X Exit</guimenuitem>
+ and continue on to the next configuration item or simply exit
+ <application>sysinstall</application> in selecting
+ <guimenuitem>X Exit</guimenuitem> twice then <guibutton>[X
+ Exit Install]</guibutton>.</para>
+
+ </sect2>
+
+ <sect2 xml:id="freebsdboot">
+ <title>&os; 開機流程</title>
+
+ <sect3 xml:id="freebsdboot-i386">
+ <title>&os;/&arch.i386; 的開機流程</title>
+
+ <para>If everything went well, you will see messages scroll
+ off the screen and you will arrive at a login prompt. You can view
+ the content of the messages by pressing <keycap>Scroll-Lock</keycap>
+ and using <keycap>PgUp</keycap> and <keycap>PgDn</keycap>.
+ Pressing <keycap>Scroll-Lock</keycap> again will return
+ to the prompt.</para>
+
+ <para>The entire message may not display (buffer limitation) but
+ it can be viewed from the command line after logging in by typing
+ <command>dmesg</command> at the prompt.</para>
+
+ <para>Login using the username/password you set during installation
+ (<systemitem class="username">rpratt</systemitem>, in this example). Avoid logging in as
+ <systemitem class="username">root</systemitem> except when necessary.</para>
+
+ <para>Typical boot messages (version information omitted):</para>
+
+<screen>Copyright (c) 1992-2002 The FreeBSD Project.
+Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
+ The Regents of the University of California. All rights reserved.
+
+Timecounter "i8254" frequency 1193182 Hz
+CPU: AMD-K6(tm) 3D processor (300.68-MHz 586-class CPU)
+ Origin = "AuthenticAMD" Id = 0x580 Stepping = 0
+ Features=0x8001bf&lt;FPU,VME,DE,PSE,TSC,MSR,MCE,CX8,MMX&gt;
+ AMD Features=0x80000800&lt;SYSCALL,3DNow!&gt;
+real memory = 268435456 (262144K bytes)
+config&gt; di sn0
+config&gt; di lnc0
+config&gt; di le0
+config&gt; di ie0
+config&gt; di fe0
+config&gt; di cs0
+config&gt; di bt0
+config&gt; di aic0
+config&gt; di aha0
+config&gt; di adv0
+config&gt; q
+avail memory = 256311296 (250304K bytes)
+Preloaded elf kernel "kernel" at 0xc0491000.
+Preloaded userconfig_script "/boot/kernel.conf" at 0xc049109c.
+md0: Malloc disk
+Using $PIR table, 4 entries at 0xc00fde60
+npx0: &lt;math processor&gt; on motherboard
+npx0: INT 16 interface
+pcib0: &lt;Host to PCI bridge&gt; on motherboard
+pci0: &lt;PCI bus&gt; on pcib0
+pcib1: &lt;VIA 82C598MVP (Apollo MVP3) PCI-PCI (AGP) bridge&gt; at device 1.0 on pci0
+pci1: &lt;PCI bus&gt; on pcib1
+pci1: &lt;Matrox MGA G200 AGP graphics accelerator&gt; at 0.0 irq 11
+isab0: &lt;VIA 82C586 PCI-ISA bridge&gt; at device 7.0 on pci0
+isa0: &lt;ISA bus&gt; on isab0
+atapci0: &lt;VIA 82C586 ATA33 controller&gt; port 0xe000-0xe00f at device 7.1 on pci0
+ata0: at 0x1f0 irq 14 on atapci0
+ata1: at 0x170 irq 15 on atapci0
+uhci0: &lt;VIA 83C572 USB controller&gt; port 0xe400-0xe41f irq 10 at device 7.2 on pci0
+usb0: &lt;VIA 83C572 USB controller&gt; on uhci0
+usb0: USB revision 1.0
+uhub0: VIA UHCI root hub, class 9/0, rev 1.00/1.00, addr 1
+uhub0: 2 ports with 2 removable, self powered
+chip1: &lt;VIA 82C586B ACPI interface&gt; at device 7.3 on pci0
+ed0: &lt;NE2000 PCI Ethernet (RealTek 8029)&gt; port 0xe800-0xe81f irq 9 at
+device 10.0 on pci0
+ed0: address 52:54:05:de:73:1b, type NE2000 (16 bit)
+isa0: too many dependant configs (8)
+isa0: unexpected small tag 14
+fdc0: &lt;NEC 72065B or clone&gt; at port 0x3f0-0x3f5,0x3f7 irq 6 drq 2 on isa0
+fdc0: FIFO enabled, 8 bytes threshold
+fd0: &lt;1440-KB 3.5" drive&gt; on fdc0 drive 0
+atkbdc0: &lt;keyboard controller (i8042)&gt; at port 0x60-0x64 on isa0
+atkbd0: &lt;AT Keyboard&gt; flags 0x1 irq 1 on atkbdc0
+kbd0 at atkbd0
+psm0: &lt;PS/2 Mouse&gt; irq 12 on atkbdc0
+psm0: model Generic PS/2 mouse, device ID 0
+vga0: &lt;Generic ISA VGA&gt; at port 0x3c0-0x3df iomem 0xa0000-0xbffff on isa0
+sc0: &lt;System console&gt; at flags 0x1 on isa0
+sc0: VGA &lt;16 virtual consoles, flags=0x300&gt;
+sio0 at port 0x3f8-0x3ff irq 4 flags 0x10 on isa0
+sio0: type 16550A
+sio1 at port 0x2f8-0x2ff irq 3 on isa0
+sio1: type 16550A
+ppc0: &lt;Parallel port&gt; at port 0x378-0x37f irq 7 on isa0
+ppc0: SMC-like chipset (ECP/EPP/PS2/NIBBLE) in COMPATIBLE mode
+ppc0: FIFO with 16/16/15 bytes threshold
+ppbus0: IEEE1284 device found /NIBBLE
+Probing for PnP devices on ppbus0:
+plip0: &lt;PLIP network interface&gt; on ppbus0
+lpt0: &lt;Printer&gt; on ppbus0
+lpt0: Interrupt-driven port
+ppi0: &lt;Parallel I/O&gt; on ppbus0
+ad0: 8063MB &lt;IBM-DHEA-38451&gt; [16383/16/63] at ata0-master using UDMA33
+ad2: 8063MB &lt;IBM-DHEA-38451&gt; [16383/16/63] at ata1-master using UDMA33
+acd0: CDROM &lt;DELTA OTC-H101/ST3 F/W by OIPD&gt; at ata0-slave using PIO4
+Mounting root from ufs:/dev/ad0s1a
+swapon: adding /dev/ad0s1b as swap device
+Automatic boot in progress...
+/dev/ad0s1a: FILESYSTEM CLEAN; SKIPPING CHECKS
+/dev/ad0s1a: clean, 48752 free (552 frags, 6025 blocks, 0.9% fragmentation)
+/dev/ad0s1f: FILESYSTEM CLEAN; SKIPPING CHECKS
+/dev/ad0s1f: clean, 128997 free (21 frags, 16122 blocks, 0.0% fragmentation)
+/dev/ad0s1g: FILESYSTEM CLEAN; SKIPPING CHECKS
+/dev/ad0s1g: clean, 3036299 free (43175 frags, 374073 blocks, 1.3% fragmentation)
+/dev/ad0s1e: filesystem CLEAN; SKIPPING CHECKS
+/dev/ad0s1e: clean, 128193 free (17 frags, 16022 blocks, 0.0% fragmentation)
+Doing initial network setup: hostname.
+ed0: flags=8843&lt;UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet 192.168.0.1 netmask 0xffffff00 broadcast 192.168.0.255
+ inet6 fe80::5054::5ff::fede:731b%ed0 prefixlen 64 tentative scopeid 0x1
+ ether 52:54:05:de:73:1b
+lo0: flags=8049&lt;UP,LOOPBACK,RUNNING,MULTICAST&gt; mtu 16384
+ inet6 fe80::1%lo0 prefixlen 64 scopeid 0x8
+ inet6 ::1 prefixlen 128
+ inet 127.0.0.1 netmask 0xff000000
+Additional routing options: IP gateway=YES TCP keepalive=YES
+routing daemons:.
+additional daemons: syslogd.
+Doing additional network setup:.
+Starting final network daemons: creating ssh RSA host key
+Generating public/private rsa1 key pair.
+Your identification has been saved in /etc/ssh/ssh_host_key.
+Your public key has been saved in /etc/ssh/ssh_host_key.pub.
+The key fingerprint is:
+cd:76:89:16:69:0e:d0:6e:f8:66:d0:07:26:3c:7e:2d root@k6-2.example.com
+ creating ssh DSA host key
+Generating public/private dsa key pair.
+Your identification has been saved in /etc/ssh/ssh_host_dsa_key.
+Your public key has been saved in /etc/ssh/ssh_host_dsa_key.pub.
+The key fingerprint is:
+f9:a1:a9:47:c4:ad:f9:8d:52:b8:b8:ff:8c:ad:2d:e6 root@k6-2.example.com.
+setting ELF ldconfig path: /usr/lib /usr/lib/compat /usr/X11R6/lib
+/usr/local/lib
+a.out ldconfig path: /usr/lib/aout /usr/lib/compat/aout /usr/X11R6/lib/aout
+starting standard daemons: inetd cron sshd usbd sendmail.
+Initial rc.i386 initialization:.
+rc.i386 configuring syscons: blank_time screensaver moused.
+Additional ABI support: linux.
+Local package initialization:.
+Additional TCP options:.
+
+FreeBSD/i386 (k6-2.example.com) (ttyv0)
+
+login: rpratt
+Password:</screen>
+
+ <para>Generating the RSA and DSA keys may take some time on slower
+ machines. This happens only on the initial boot-up of a new
+ installation. Subsequent boots will be faster.</para>
+
+ <para>If the X server has been configured and a Default Desktop
+ chosen, it can be started by typing <command>startx</command> at
+ the command line.</para>
+
+ </sect3>
+
+ <sect3>
+ <title>&os;/&arch.alpha; 開機流程</title>
+
+ <indexterm><primary>Alpha</primary></indexterm>
+
+ <para>Once the install procedure has finished, you will be
+ able to start FreeBSD by typing something like this to the
+ SRM prompt:</para>
+
+ <screen>&gt;&gt;&gt;<userinput>BOOT DKC0</userinput></screen>
+
+ <para>This instructs the firmware to boot the specified
+ disk. To make FreeBSD boot automatically in the future, use
+ these commands:</para>
+
+ <screen><prompt>&gt;&gt;&gt;</prompt> <userinput>SET BOOT_OSFLAGS A</userinput>
+<prompt>&gt;&gt;&gt;</prompt> <userinput>SET BOOT_FILE ''</userinput>
+<prompt>&gt;&gt;&gt;</prompt> <userinput>SET BOOTDEF_DEV DKC0</userinput>
+<prompt>&gt;&gt;&gt;</prompt> <userinput>SET AUTO_ACTION BOOT</userinput></screen>
+
+ <para>The boot messages will be similar (but not identical) to
+ those produced by FreeBSD booting on the &i386;.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="shutdown">
+ <title>FreeBSD Shutdown</title>
+
+ <para>It is important to properly shutdown the operating
+ system. Do not just turn off power. First, become a superuser by
+ typing <command>su</command> at the command line and entering the
+ <systemitem class="username">root</systemitem> password. This will work only if the user
+ is a member of the <systemitem class="groupname">wheel</systemitem> group.
+ Otherwise, login as <systemitem class="username">root</systemitem> and use
+ <command>shutdown -h now</command>.</para>
+
+ <screen>The operating system has halted.
+Please press any key to reboot.</screen>
+
+ <para>It is safe to turn off the power after the shutdown command
+ has been issued and the message <quote>Please press any key to reboot</quote>
+ appears. If any key is pressed instead of turning off the power
+ switch, the system will reboot.</para>
+
+ <para>You could also use the
+ <keycombo action="simul">
+ <keycap>Ctrl</keycap>
+ <keycap>Alt</keycap>
+ <keycap>Del</keycap>
+ </keycombo>
+ key combination to reboot the system, however this is not recommended
+ during normal operation.</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="install-trouble">
+ <title>安裝的疑難雜症解決</title>
+
+ <indexterm>
+ <primary>installation</primary>
+ <secondary>troubleshooting</secondary>
+ </indexterm>
+ <para>The following section covers basic installation troubleshooting,
+ such as common problems people have reported. There are also a few
+ questions and answers for people wishing to dual-boot FreeBSD with
+ &ms-dos; or &windows;.</para>
+
+ <sect2>
+ <title>What to Do If Something Goes Wrong</title>
+
+ <para>Due to various limitations of the PC architecture, it is
+ impossible for probing to be 100% reliable, however, there are a
+ few things you can do if it fails.</para>
+
+ <para>Check the <link xlink:href="http://www.FreeBSD.org/releases/index.html">Hardware Notes
+ </link> document for your version of &os; to make sure
+ your hardware is supported.</para>
+
+ <para>若硬體有在支援清單內,但使用 <filename>GENERIC</filename> kernel
+ 仍有問題,那麼就可能需要 <link linkend="kernelconfig">自訂 kernel</link>,以加入有支援的硬體。
+ The kernel on the boot disks is configured
+ assuming that most hardware devices are in their factory default
+ configuration in terms of IRQs, IO addresses, and DMA channels. If
+ your hardware has been reconfigured, you will most likely need to
+ edit the kernel configuration and recompile to tell
+ &os; where to find things.</para>
+
+ <para>It is also possible that a probe for a device not present will
+ cause a later probe for another device that is present to fail. In
+ that case, the probes for the conflicting driver(s) should be
+ disabled.</para>
+
+ <note>
+ <para>Some installation problems can be avoided or alleviated
+ by updating the firmware on various hardware components, most notably
+ the motherboard. The motherboard firmware may also be referred to
+ as <acronym>BIOS</acronym> and most of the motherboard or computer
+ manufactures have a website where the upgrades and upgrade information
+ may be located.</para>
+
+ <para>Most manufacturers strongly advise against upgrading the motherboard
+ <acronym>BIOS</acronym> unless there is a good reason for doing so, which
+ could possibly be a critical update of sorts. The upgrade process
+ <emphasis>can</emphasis> go wrong, causing permanent damage to the
+ <acronym>BIOS</acronym> chip.</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Using &ms-dos; and &windows; File Systems</title>
+
+ <para>At this time, &os; does not support file systems compressed with the
+ <application>Double Space&trade;</application> application. Therefore the file
+ system will need to be uncompressed before &os; can access the data. This
+ can be done by running the <application>Compression Agent</application>
+ located in the <guimenuitem>Start</guimenuitem>&gt; <guimenuitem>Programs</guimenuitem> &gt;
+ <guimenuitem>System Tools</guimenuitem> menu.</para>
+
+ <para>&os; can support &ms-dos; based file systems(FAT16 and FAT32).
+ This requires you use the &man.mount.msdosfs.8; command
+ with the required parameters. The utility most common usage is:</para>
+
+ <screen>&prompt.root; <userinput>mount -t msdosfs /dev/ad0s1 /mnt</userinput></screen>
+
+ <para>In this example, the &ms-dos; file system is located on the first partition of
+ the primary hard disk. Your situation may be different, check the output from
+ the <command>dmesg</command>, and <command>mount</command> commands. They should
+ produce enough information to give an idea of the partition layout.</para>
+
+ <note><para>Extended &ms-dos; file systems are usually mapped after the &os;
+ partitions. In other words, the slice number may be higher than the ones
+ &os; is using. For instance, the first &ms-dos; partition may be
+ <filename>/dev/ad0s1</filename>, the &os; partition may be
+ <filename>/dev/ad0s2</filename>, with the extended &ms-dos; partition being
+ located on <filename>/dev/ad0s3</filename>. To some, this can be confusing
+ at first.</para></note>
+
+ <para>NTFS partitions can also be mounted in a similar manner
+ using the &man.mount.ntfs.8; command.</para>
+ </sect2>
+
+ <sect2>
+ <title>Troubleshooting Questions and Answers</title>
+
+ <qandaset>
+ <qandaentry>
+ <question>
+ <para>My system hangs while probing hardware during boot,
+ or it behaves strangely during install, or the floppy
+ drive isn't probed.</para>
+ </question>
+ <answer>
+ <para>&os; 5.0 and above makes extensive use of the system
+ ACPI service on the i386, amd64 and ia64 platforms to
+ aid in system configuration if it's detected during
+ boot. Unfortunately, some bugs still exist in both the
+ ACPI driver and within system motherboards and BIOS.
+ The use of ACPI can be disabled by setting
+ the <literal>hint.acpi.0.disabled</literal> hint in the
+ third stage boot loader:</para>
+
+ <screen>set hint.acpi.0.disabled="1"</screen>
+
+ <para>This is reset each time the system is booted, so it
+ is necessary to
+ add <literal>hint.acpi.0.disabled="1"</literal> to the
+ file
+ <filename>/boot/loader.conf</filename>. More
+ information about the boot loader can be found
+ in <xref linkend="boot-synopsis"/>.</para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question>
+ <para>I go to boot from the hard disk for the first time
+ after installing &os;, the kernel loads and probes my
+ hardware, but stops with messages like:</para>
+
+ <screen>changing root device to ad1s1a panic: cannot mount root</screen>
+
+ <para>What is wrong? What can I do?</para>
+
+ <para>What is this
+ <literal>bios_drive:interface(unit,partition)kernel_name</literal>
+ thing that is displayed with the boot help?</para>
+ </question>
+ <answer>
+ <para>There is a longstanding problem in the case where
+ the boot disk is not the first disk in the system. The
+ BIOS uses a different numbering scheme to &os;, and
+ working out which numbers correspond to which is
+ difficult to get right.</para>
+
+ <para>In the case where the boot disk is not the first
+ disk in the system, &os; can need some help finding it.
+ There are two common situations here, and in both of
+ these cases, you need to tell &os; where the root
+ filesystem is. You do this by specifying the BIOS disk
+ number, the disk type and the &os; disk number for that
+ type.</para>
+
+ <para>The first situation is where you have two IDE disks,
+ each configured as the master on their respective IDE
+ busses, and wish to boot &os; from the second disk. The
+ BIOS sees these as disk 0 and disk 1, while &os; sees
+ them as <filename>ad0</filename> and
+ <filename>ad2</filename>.</para>
+
+ <para>&os; is on BIOS disk 1, of type
+ <literal>ad</literal> and the &os; disk number is 2, so
+ you would say:</para>
+
+ <screen><userinput>1:ad(2,a)kernel</userinput></screen>
+
+ <para>Note that if you have a slave on the primary bus,
+ the above is not necessary (and is effectively
+ wrong).</para>
+
+ <para>The second situation involves booting from a SCSI
+ disk when you have one or more IDE disks in the system.
+ In this case, the &os; disk number is lower than the
+ BIOS disk number. If you have two IDE disks as well as
+ the SCSI disk, the SCSI disk is BIOS disk 2,
+ type <literal>da</literal> and &os; disk number 0, so
+ you would say:</para>
+
+ <screen><userinput>2:da(0,a)kernel</userinput></screen>
+
+ <para>To tell &os; that you want to boot from BIOS disk 2,
+ which is the first SCSI disk in the system. If you only
+ had one IDE disk, you would use '1:' instead.</para>
+
+ <para>Once you have determined the correct values to use,
+ you can put the command exactly as you would have typed
+ it in the <filename>/boot.config</filename> file using a
+ standard text editor. Unless instructed otherwise, &os;
+ will use the contents of this file as the default
+ response to the <literal>boot:</literal> prompt.</para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question>
+ <para>I go to boot from the hard disk for the first time
+ after installing &os;, but the Boot Manager prompt just
+ prints <literal>F?</literal> at the boot menu each time
+ but the boot won't go any further.</para>
+ </question>
+ <answer>
+ <para>The hard disk geometry was set incorrectly in the
+ Partition editor when you installed &os;. Go back into
+ the partition editor and specify the actual geometry of
+ your hard disk. You must reinstall &os; again from the
+ beginning with the correct geometry.</para>
+
+ <para>If you are failing entirely in figuring out the
+ correct geometry for your machine, here's a tip: Install
+ a small DOS partition at the beginning of the disk and
+ install &os; after that. The install program will see
+ the DOS partition and try to infer the correct geometry
+ from it, which usually works.</para>
+
+ <para>The following tip is no longer recommended, but is
+ left here for reference:</para>
+
+ <blockquote>
+ <para>If you are setting up a truly dedicated &os;
+ server or workstation where you don't care for
+ (future) compatibility with DOS, Linux or another
+ operating system, you've also got the option to use
+ the entire disk (`A' in the partition editor),
+ selecting the non-standard option where &os; occupies
+ the entire disk from the very first to the very last
+ sector. This will leave all geometry considerations
+ aside, but is somewhat limiting unless you're never
+ going to run anything other than &os; on a
+ disk.</para>
+ </blockquote>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question>
+ <para>The system finds my &man.ed.4; network card, but I
+ keep getting device timeout errors.</para>
+ </question>
+ <answer>
+ <para>Your card is probably on a different IRQ from what
+ is specified in
+ the <filename>/boot/device.hints</filename> file. The
+ ed driver does not use the `soft' configuration by
+ default (values entered using EZSETUP in DOS), but it
+ will use the software configuration if you
+ specify <literal>-1</literal> in the hints for the
+ interface.</para>
+
+ <para>Either move the jumper on the card to a hard
+ configuration setting (altering the kernel settings if
+ necessary), or specify the IRQ as <literal>-1</literal>
+ by setting the hint <quote>hint.ed.0.irq="-1"</quote>
+ This will tell the kernel to use the soft
+ configuration.</para>
+
+ <para>Another possibility is that your card is at IRQ 9,
+ which is shared by IRQ 2 and frequently a cause of
+ problems (especially when you have a VGA card using IRQ
+ 2!). You should not use IRQ 2 or 9 if at all
+ possible.</para>
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="install-advanced">
+ <info><title>進階安裝指南</title>
+ <authorgroup>
+ <author><personname><firstname>Valentino</firstname><surname>Vaschetto</surname></personname><contrib>Contributed by </contrib></author>
+ <!-- May 2001 -->
+ </authorgroup>
+ </info>
+
+
+
+ <para>This section describes how to install FreeBSD in exceptional
+ cases.</para>
+
+ <sect2 xml:id="headless-install">
+ <title>Installing FreeBSD on a System without a Monitor or
+ Keyboard</title>
+
+ <indexterm>
+ <primary>installation</primary>
+ <secondary>headless (serial console)</secondary>
+ </indexterm>
+ <indexterm><primary>serial console</primary></indexterm>
+ <para>This type of installation is called a <quote>headless
+ install</quote>, because the machine that you are trying to install
+ FreeBSD on either does not have a monitor attached to it, or does not
+ even have a VGA output. How is this possible you ask? Using a
+ serial console. A serial console is basically using another
+ machine to act as the main display and keyboard for a
+ system. To do this, just follow the steps to create
+ installation floppies, explained in <xref linkend="install-floppies"/>.</para>
+
+ <para>To modify these floppies to boot into a serial console, follow
+ these steps:</para>
+
+ <procedure>
+ <step>
+ <title>Enabling the Boot Floppies to Boot into a Serial Console</title>
+ <indexterm>
+ <primary><command>mount</command></primary>
+ </indexterm>
+ <para>If you were to boot into the floppies that you just
+ made, FreeBSD would boot into its normal install mode. We
+ want FreeBSD to boot into a serial console for our
+ install. To do this, you have to mount the
+ <filename>boot.flp</filename> floppy onto your FreeBSD
+ system using the &man.mount.8; command.</para>
+
+ <screen>&prompt.root; <userinput>mount /dev/fd0 /mnt</userinput></screen>
+
+ <para>Now that you have the floppy mounted, you must
+ change into the <filename>/mnt</filename> directory:</para>
+
+ <screen>&prompt.root; <userinput>cd /mnt</userinput></screen>
+
+ <para>Here is where you must set the floppy to boot into a
+ serial console. You have to make a file called
+ <filename>boot.config</filename> containing
+ <literal>/boot/loader -h</literal>. All this does is pass a flag to the bootloader to
+ boot into a serial console.</para>
+
+ <screen>&prompt.root; <userinput>echo "/boot/loader -h" &gt; boot.config</userinput></screen>
+
+ <para>Now that you have your floppy configured correctly,
+ you must unmount the floppy using the &man.umount.8;
+ command:</para>
+
+ <screen>&prompt.root; <userinput>cd /</userinput>
+&prompt.root; <userinput>umount /mnt</userinput></screen>
+
+ <para>Now you can remove the floppy from the floppy
+ drive.</para>
+ </step>
+
+ <step>
+ <title>Connecting Your Null-modem Cable</title>
+
+ <indexterm><primary>null-modem cable</primary></indexterm>
+ <para>You now need to connect a
+ <link linkend="term-cables-null">null-modem cable</link> between
+ the two machines. Just connect the cable to the serial
+ ports of the 2 machines. <emphasis>A normal serial cable
+ will not work here</emphasis>, you need a null-modem
+ cable because it has some of the wires inside crossed
+ over.</para>
+ </step>
+
+ <step>
+ <title>Booting Up for the Install</title>
+
+ <para>It is now time to go ahead and start the install. Put
+ the <filename>boot.flp</filename> floppy in the floppy
+ drive of the machine you are doing the headless install
+ on, and power on the machine.</para>
+ </step>
+
+ <step>
+ <title>Connecting to Your Headless Machine</title>
+ <indexterm>
+ <primary><command>cu</command></primary>
+ </indexterm>
+ <para>Now you have to connect to that machine with
+ &man.cu.1;:</para>
+
+ <screen>&prompt.root; <userinput>cu -l /dev/cuad0</userinput></screen>
+
+ <para>在 &os;&nbsp;5.X,請改用
+ <filename>/dev/cuaa0</filename> 而非
+ <filename>/dev/cuad0</filename>。</para>
+
+ </step>
+ </procedure>
+
+ <para>That's it! You should now be able to control the headless machine
+ through your <command>cu</command> session. It will ask you to
+ put in the <filename>kern1.flp</filename>, and then it will come up
+ with a selection of what kind of terminal to use. Select the
+ FreeBSD color console and proceed with your install!</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="install-diff-media">
+ <title>製作安裝片</title>
+
+ <note>
+ <para>為避免重覆說明,在文中所提到的「FreeBSD 光碟」,
+ 在這裡指的是您所購買或自行燒錄的 FreeBSD CDROM 或 DVD。</para>
+ </note>
+
+ <para>There may be some situations in which you need to create your own
+ FreeBSD installation media and/or source. This might be physical media,
+ such as a tape, or a source that <application>sysinstall</application>
+ can use to retrieve the files, such as a local FTP site, or an &ms-dos;
+ partition.</para>
+
+ <para>For example:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>You have many machines connected to your local network, and one
+ FreeBSD disc. You want to create a local FTP site using the
+ contents of the FreeBSD disc, and then have your machines use this
+ local FTP site instead of needing to connect to the Internet.</para>
+ </listitem>
+
+ <listitem>
+ <para>You have a FreeBSD disc, and FreeBSD does not recognize your CD/DVD
+ drive, but &ms-dos;/&windows; does. You want to copy the FreeBSD
+ installation files to a DOS partition on the same computer, and
+ then install FreeBSD using those files.</para>
+ </listitem>
+
+ <listitem>
+ <para>The computer you want to install on does not have a CD/DVD
+ drive or a network card, but you can connect a
+ <quote>Laplink-style</quote> serial or parallel cable to a computer
+ that does.</para>
+ </listitem>
+
+ <listitem>
+ <para>You want to create a tape that can be used to install
+ FreeBSD.</para>
+ </listitem>
+ </itemizedlist>
+
+ <sect2 xml:id="install-cdrom">
+ <title>Creating an Installation CDROM</title>
+
+ <para>As part of each release, the FreeBSD project makes available at least two
+ CDROM images (<quote>ISO images</quote>) per supported architecture. These images can be written
+ (<quote>burned</quote>) to CDs if you have a CD writer, and then used
+ to install FreeBSD. If you have a CD writer, and bandwidth is cheap,
+ then this is the easiest way to install FreeBSD.</para>
+
+ <procedure>
+ <step>
+ <title>Download the Correct ISO Images</title>
+
+ <para>The ISO images for each release can be downloaded from <filename>ftp://ftp.FreeBSD.org/pub/FreeBSD/ISO-IMAGES-arch/version</filename> or the closest mirror.
+ Substitute <replaceable>arch</replaceable> and
+ <replaceable>version</replaceable> as appropriate.</para>
+
+ <para>That directory will normally contain the following images:</para>
+
+ <table frame="none">
+ <title>FreeBSD 5.<replaceable>X</replaceable> and 6.<replaceable>X</replaceable>
+ ISO Image Names and Meanings</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>檔名</entry>
+
+ <entry>內容</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><filename>版本-RELEASE-架構-bootonly.iso</filename></entry>
+
+ <entry>Everything you need to boot into a FreeBSD
+ kernel and start the installation interface.
+ The installable files have to be pulled over FTP
+ or some other supported source.</entry>
+ </row>
+
+ <row>
+ <entry><filename>版本-RELEASE-架構-disc1.iso</filename></entry>
+
+ <entry>Everything you need to install &os; and a
+ <quote>live filesystem</quote>, which is used in
+ conjunction with the <quote>Repair</quote> facility
+ in <application>sysinstall</application>.</entry>
+ </row>
+
+ <row>
+ <entry><filename>版本-RELEASE-架構-disc2.iso</filename></entry>
+
+ <entry>&os; 文件(&os; 6.2 之前的),以及許多 third-party
+ packages。</entry>
+ </row>
+
+ <row>
+ <entry><filename>版本-RELEASE-架構-docs.iso</filename></entry>
+
+ <entry>&os; 文件(&os; 6.2 及之後)。</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>You <emphasis>must</emphasis> download one of either the bootonly
+ ISO image (if available), or the image of disc one. Do not download
+ both of them, since the disc one image contains everything that the
+ bootonly ISO image contains.</para>
+
+ <para>Use the bootonly ISO if Internet access is cheap for you. It will
+ let you install &os;, and you can then install third-party
+ packages by downloading them using the ports/packages system (see
+ <xref linkend="ports"/>) as
+ necessary.</para>
+
+ <para>Use the image of disc one if you want to install a &os;
+ release and want
+ a reasonable selection of third-party packages on the disc
+ as well.</para>
+
+ <para>The additional disc images are useful, but not essential,
+ especially if you have high-speed access to the Internet.</para>
+ </step>
+
+ <step>
+ <title>Write the CDs</title>
+
+ <para>You must then write the CD images to disc. If you will be
+ doing this on another FreeBSD system then see
+ <xref linkend="creating-cds"/> for more information (in
+ particular, <xref linkend="burncd"/> and
+ <xref linkend="cdrecord"/>).</para>
+
+ <para>If you will be doing this on another platform then you will
+ need to use whatever utilities exist to control your CD writer on
+ that platform. The images provided are in the standard ISO format,
+ which many CD writing applications support.</para>
+ </step>
+ </procedure>
+
+ <note><para>If you are interested in building a customized
+ release of FreeBSD, please see the <link xlink:href="&url.articles.releng;">Release Engineering
+ Article</link>.</para></note>
+
+ </sect2>
+
+ <sect2 xml:id="install-ftp">
+ <title>Creating a Local FTP Site with a FreeBSD Disc</title>
+
+ <indexterm>
+ <primary>installation</primary>
+ <secondary>network</secondary>
+ <tertiary>FTP</tertiary>
+ </indexterm>
+
+ <para>FreeBSD discs are laid out in the same way as the FTP site. This
+ makes it very easy for you to create a local FTP site that can be used
+ by other machines on your network when installing FreeBSD.</para>
+
+ <procedure>
+ <step>
+ <para>On the FreeBSD computer that will host the FTP site, ensure
+ that the CDROM is in the drive, and mounted on
+ <filename>/cdrom</filename>.</para>
+
+ <screen>&prompt.root; <userinput>mount /cdrom</userinput></screen>
+ </step>
+
+ <step>
+ <para>Create an account for anonymous FTP in
+ <filename>/etc/passwd</filename>. Do this by editing
+ <filename>/etc/passwd</filename> using &man.vipw.8; and adding
+ this line:</para>
+
+ <programlisting>ftp:*:99:99::0:0:FTP:/cdrom:/nonexistent</programlisting>
+ </step>
+
+ <step>
+ <para>Ensure that the FTP service is enabled in
+ <filename>/etc/inetd.conf</filename>.</para>
+ </step>
+ </procedure>
+
+ <para>Anyone with network connectivity to your machine can now
+ chose a media type of FTP and type in
+ <userinput>ftp://your machine</userinput>
+ after picking <quote>Other</quote> in the FTP sites menu during
+ the install.</para>
+
+ <note>
+ <para>If the boot media (floppy disks, usually) for your FTP
+ clients is not precisely the same version as that provided
+ by the local FTP site, then <application>sysinstall</application> will not let you
+ complete the installation. If the versions are not similar and
+ you want to override this, you must go into the <guimenu>Options</guimenu> menu
+ and change distribution name to
+ <guimenuitem>any</guimenuitem>.</para>
+ </note>
+
+ <warning>
+ <para>This approach is OK for a machine that is on your local network,
+ and that is protected by your firewall. Offering up FTP services to
+ other machines over the Internet (and not your local network)
+ exposes your computer to the attention of crackers and other
+ undesirables. We strongly recommend that you follow good security
+ practices if you do this.</para>
+ </warning>
+ </sect2>
+
+ <sect2>
+ <title>建立安裝用的磁片</title>
+
+ <indexterm>
+ <primary>installation</primary>
+ <secondary>floppies</secondary>
+ </indexterm>
+
+ <para>若您必須從磁片安裝(雖然我們<emphasis>不</emphasis>建議這樣做),
+ 不論是因為硬體不支援或是您堅持要用這麼刻苦的方式,
+ 您都必須先準備一些磁片以供安裝。</para>
+
+ <para>磁片至少得是 1.44&nbsp;MB
+ At a minimum, you will need as many 1.44&nbsp;MB floppies
+ as it takes to hold all the files in the
+ <filename>base</filename> (base distribution) directory. If
+ you are preparing the floppies from DOS, then they
+ <emphasis>must</emphasis> be formatted using the &ms-dos;
+ <command>FORMAT</command> command. If you are using &windows;,
+ use Explorer to format the disks (right-click on the
+ <filename>A:</filename> drive, and select <quote>Format</quote>).</para>
+
+ <para>Do <emphasis>not</emphasis> trust factory pre-formatted
+ floppies. Format them again yourself, just to be sure. Many
+ problems reported by our users in the past have resulted from
+ the use of improperly formatted media, which is why we are
+ making a point of it now.</para>
+
+ <para>If you are creating the floppies on another FreeBSD machine,
+ a format is still not a bad idea, though you do not need to put
+ a DOS filesystem on each floppy. You can use the
+ <command>disklabel</command> and <command>newfs</command>
+ commands to put a UFS filesystem on them instead, as the
+ following sequence of commands (for a 3.5" 1.44&nbsp;MB floppy)
+ illustrates:</para>
+
+ <screen>&prompt.root; <userinput>fdformat -f 1440 fd0.1440</userinput>
+&prompt.root; <userinput>bsdlabel -w fd0.1440 floppy3</userinput>
+&prompt.root; <userinput>newfs -t 2 -u 18 -l 1 -i 65536 /dev/fd0</userinput></screen>
+
+ <para>Then you can mount and write to them like any other
+ filesystem.</para>
+
+ <para>After you have formatted the floppies, you will need to copy
+ the files to them. The distribution files are split into chunks
+ conveniently sized so that five of them will fit on a conventional
+ 1.44&nbsp;MB floppy. Go through all your floppies, packing as many
+ files as will fit on each one, until you have all of the
+ distributions you want packed up in this fashion. Each
+ distribution should go into a subdirectory on the floppy, e.g.:
+ <filename>a:\base\base.aa</filename>,
+ <filename>a:\base\base.ab</filename>, and so on.</para>
+
+ <important>
+ <para>The <filename>base.inf</filename> file also needs to go on the
+ first floppy of the <filename>base</filename> set since it is read
+ by the installation program in order to figure out how many
+ additional pieces to look for when fetching and concatenating the
+ distribution.</para>
+ </important>
+
+ <para>Once you come to the Media screen during the install
+ process, select <guimenuitem>Floppy</guimenuitem> and you
+ will be prompted for the rest.</para>
+ </sect2>
+
+ <sect2 xml:id="install-msdos">
+ <title>從 &ms-dos; 分割區安裝</title>
+
+ <indexterm>
+ <primary>installation</primary>
+ <secondary>from MS-DOS</secondary>
+ </indexterm>
+ <para>若準備要從 &ms-dos; 分割區進行安裝,
+ 請把所有安裝檔都複製到該分割區根目錄內的 <filename>freebsd</filename>
+ 目錄。 比如:<filename>c:\freebsd</filename>。
+ 此目錄結構必須與光碟或 FTP 內的目錄結構一致,
+ 因此若是要從光碟複製檔案,建議使用 DOS 的 <command>xcopy</command>
+ 指令。 例如,要複製 &os; 最小安裝所需的檔案:</para>
+
+ <screen><prompt>C:\&gt;</prompt> <userinput>md c:\freebsd</userinput>
+<prompt>C:\&gt;</prompt> <userinput>xcopy e:\bin c:\freebsd\bin\ /s</userinput>
+<prompt>C:\&gt;</prompt> <userinput>xcopy e:\manpages c:\freebsd\manpages\ /s</userinput></screen>
+
+ <para>假設 <filename>C:</filename> 槽有多餘空間,可以放 &os;
+ 安裝檔;<filename>E:</filename>則是光碟機代號。</para>
+
+ <para>若沒有光碟機,可以到 <link xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/releases/i386/&rel.current;-RELEASE/">ftp.FreeBSD.org</link> 去下載安裝檔。
+ 每個安裝套件都有其相對應的目錄;比如 <emphasis>base</emphasis>
+ 是放在 <link xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/releases/i386/&rel.current;-RELEASE/base/">&rel.current;/base/</link>
+ 目錄內。</para>
+
+
+ <para>請將您要安裝的套件(當然空間要夠)放到 &ms-dos; 分割區的
+ <filename>c:\freebsd</filename> 裡 &mdash; 因為這個
+ <literal>BIN</literal> 安裝套件僅供最精簡安裝而已。</para>
+ </sect2>
+
+ <sect2>
+ <title>製作安裝用的磁帶</title>
+
+ <indexterm>
+ <primary>installation</primary>
+ <secondary>from QIC/SCSI Tape</secondary>
+ </indexterm>
+ <para>從磁帶上安裝也許是最簡單的方式,比用 FTP 或光碟安裝還快。
+ 安裝程式假設所有檔案都會壓縮放在磁帶上。 在取得所有要裝的安裝檔之後
+ ,可以用下列指令把它們壓縮放在磁帶上:</para>
+
+ <screen>&prompt.root; <userinput>cd /freebsd/distdir</userinput>
+&prompt.root; <userinput>tar cvf /dev/rwt0 dist1 ... dist2</userinput></screen>
+
+ <para>當要安裝時,必須先確認磁帶還有足夠空間,
+ 以便讓安裝過程暫存空間(可以自行選擇要放在哪個目錄),
+ 可以容納磁帶安裝時的<emphasis>全部</emphasis>檔案。
+ 由於磁帶本身並不能隨機存取,因此用磁帶安裝會需要很大的暫存空間。
+ </para>
+
+ <note>
+ <para>在使用安裝磁片開機<emphasis> 之前</emphasis>,
+ 磁帶一定要先放入磁帶機內,否則在偵測硬體時可能會無法偵測到磁帶機。
+ </para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Before Installing over a Network</title>
+
+ <indexterm>
+ <primary>installation</primary>
+ <secondary>network</secondary>
+ <tertiary>serial (SLIP or PPP)</tertiary>
+ </indexterm>
+ <indexterm>
+ <primary>installation</primary>
+ <secondary>network</secondary>
+ <tertiary>parallel (PLIP)</tertiary>
+ </indexterm>
+ <indexterm>
+ <primary>installation</primary>
+ <secondary>network</secondary>
+ <tertiary>Ethernet</tertiary>
+ </indexterm>
+ <para>有三種網路安裝方式:
+ Ethernet (標準 Ethernet 晶片)、Serial port(SLIP 或 PPP)、
+ Parallel port (PLIP (laplink cable))。</para>
+
+ <para>透過網路安裝的最快方式,就是使用 Ethernet 網路卡!
+ &os; 支援大多數常見的 Ethernet 網路卡;
+ 所有支援的網路卡(及其所需的設定)都有在各版本的 &os; 內的 Hardware
+ Note 說明文件內列出。 若您所用的是有支援的 PCMCIA 網路卡,
+ 請務必在開機<emphasis>之前</emphasis>,先把該網路卡插上。 因為 &os;
+ 的安裝過程,目前並不支援 PCMCIA 卡的熱插拔。</para>
+
+ <para>此外,還需要知道該用的 IP 位址以及相對應的 netmask 為何,
+ 以及機器名稱。 若所用的是 PPP 連線,而且沒有固定 IP,別擔心,
+ 因為您的 ISP 會自動分配 IP 給您。 關於這些網路的細部設定,
+ 可以洽詢您網路環境的系統管理者。
+ 若要能以機器名稱就能連到相對應的機器,而非直接使用 IP位址去連,
+ 那麼您還需要 DNS 以及 gateway 的位址(若用的是 PPP 連線,
+ gateway 位址就是 ISP 所分配給你的 IP 位址)。 若想透過 HTTP proxy
+ 來使用 FTP 安裝,那麼必須知道 proxy 的網址為何。
+ 若您對上述所需資訊不甚了解,那麼請在安裝<emphasis>之前</emphasis>,
+ 先詢問系統管理者或 ISP。</para>
+
+ <para>SLIP 的支援相當原始,並且主要受限於電腦之間的實體線路(hard-wired)
+ ,比如筆記型電腦與其他電腦之間的 serial 線。
+ 之所以得以電腦間以直接線路連結,乃是由於 SLIP
+ 安裝目前並不支援撥接功能。 PPP 才有提供撥接功能,
+ 所以請儘可能優先採用 PPP 而非 SLIP。</para>
+
+ <para>若要透過數據機(modem)來安裝,那 PPP 幾乎是您唯一選擇。
+ 請先準備好 ISP 所提供的相關資料,因為在安裝之初就會用到。</para>
+
+ <para>若使用 PAP 或 CHAP 來連到 ISP(換句話說,若在 &windows;
+ 可以不透過 script 就可以連線到 ISP),那麼您僅需在
+ <application>ppp</application> 提示符號下輸入 <command>dial</command>
+ 指令即可撥號。 否則,您必須知道如何以該數據機所採用的
+ <quote>AT 指令集</quote>來連到 ISP,因為 PPP 撥號程式僅提供非常陽春的
+ 終端模擬器(terminal emulator)而起。 請參閱 Handbook 中 <link linkend="userppp">user-ppp</link> 章節以及 <link xlink:href="&url.books.faq;/ppp.html">FAQ</link> 中的相關項目。
+ 若有操作上的疑問,可以打 <command>set log local ...</command>
+ 指令,以便在螢幕上顯示相關記錄。</para>
+
+ <para>若可直接以 hard-wired 方式連到另外的 &os;(2.0-R 及之後) 機器,
+ 那麼可以考慮透過 <quote>laplink</quote> 平行電纜來安裝。
+ 平行埠的傳輸速率比序列埠高很多(最高可達每秒 50&nbsp;kbytes/sec),
+ 所以安裝速度會更快一些。</para>
+
+ <sect3>
+ <title>Before Installing via NFS</title>
+
+ <indexterm>
+ <primary>installation</primary>
+ <secondary>network</secondary>
+ <tertiary>NFS</tertiary>
+ </indexterm>
+ <para>NFS 安裝方式相當簡便,只需將 FreeBSD 安裝檔案都放到某台 NFS
+ server 上,然後再指定使用這台 NFS 作為安裝來源即可。</para>
+
+ <para>若該 server 只允許 <quote>privileged port</quote>(通常這是 Sun
+ 工作站的預設值),那麼在安裝之前,必須先到 <guimenu>Options</guimenu>
+ 選單去指定 <literal>NFS Secure</literal> 設定值。</para>
+
+ <para>若網路卡的連線品質不佳,那可能需要調整一下
+ <literal>NFS Slow</literal> 設定。</para>
+
+ <para>為了讓 NFS 安裝能順利完成,NFS 主機必須要可以支援子目錄的掛載
+ (mount),例如:&os;&nbsp;&rel.current; 安裝目錄是在:
+ <filename>ziggy:/usr/archive/stuff/FreeBSD</filename>,那麼
+ <systemitem>ziggy</systemitem> 必須允許直接掛載在
+ <filename>/usr/archive/stuff/FreeBSD</filename>,而非僅
+ <filename>/usr</filename> 或是
+ <filename>/usr/archive/stuff</filename>。</para>
+
+ <para>在 &os; 的 <filename>/etc/exports</filename> 檔,上述功能是由
+ <option>-alldirs</option> 選項所設定。 其他的 NFS server
+ 可能會有不同的設定方式。 若看到
+ <errorname>permission denied</errorname> 錯誤訊息,
+ 則表示可能由於沒有啟用這選項所造成的。</para>
+ </sect3>
+
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/install/example-dir1.dot b/zh_TW.UTF-8/books/handbook/install/example-dir1.dot
new file mode 100644
index 0000000000..f259e8377d
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/install/example-dir1.dot
@@ -0,0 +1,7 @@
+// $FreeBSD$
+
+digraph directory {
+ root [label="Root\n/"];
+ root -> "A1/";
+ root -> "A2/";
+}
diff --git a/zh_TW.UTF-8/books/handbook/install/example-dir2.dot b/zh_TW.UTF-8/books/handbook/install/example-dir2.dot
new file mode 100644
index 0000000000..b846c82399
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/install/example-dir2.dot
@@ -0,0 +1,8 @@
+// $FreeBSD$
+
+digraph directory {
+ root [label="Root\n/"];
+ root -> "A1/" -> "B1/";
+ "A1/" -> "B2/";
+ root -> "A2/";
+}
diff --git a/zh_TW.UTF-8/books/handbook/install/example-dir3.dot b/zh_TW.UTF-8/books/handbook/install/example-dir3.dot
new file mode 100644
index 0000000000..178a3a91bb
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/install/example-dir3.dot
@@ -0,0 +1,8 @@
+// $FreeBSD$
+
+digraph directory {
+ root [label="Root\n/"];
+ root -> "A1/";
+ root -> "A2/" -> "B1/";
+ "A2/" -> "B2/";
+}
diff --git a/zh_TW.UTF-8/books/handbook/install/example-dir4.dot b/zh_TW.UTF-8/books/handbook/install/example-dir4.dot
new file mode 100644
index 0000000000..82d12b421a
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/install/example-dir4.dot
@@ -0,0 +1,9 @@
+// $FreeBSD$
+
+digraph directory {
+ root [label="Root\n/"];
+ root -> "A1/";
+ root -> "A2/" -> "B1/" -> "C1/";
+ "B1/" -> "C2/";
+ "A2/" -> "B2/";
+}
diff --git a/zh_TW.UTF-8/books/handbook/install/example-dir5.dot b/zh_TW.UTF-8/books/handbook/install/example-dir5.dot
new file mode 100644
index 0000000000..f5aa6e01dc
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/install/example-dir5.dot
@@ -0,0 +1,9 @@
+// $FreeBSD$
+
+digraph directory {
+ root [label="Root\n/"];
+ root -> "A1/" -> "C1/";
+ "A1/" -> "C2/";
+ root -> "A2/" -> "B1/";
+ "A2/" -> "B2/";
+}
diff --git a/zh_TW.UTF-8/books/handbook/introduction/Makefile b/zh_TW.UTF-8/books/handbook/introduction/Makefile
new file mode 100644
index 0000000000..db1a5173b2
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/introduction/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= introduction/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/introduction/chapter.xml b/zh_TW.UTF-8/books/handbook/introduction/chapter.xml
new file mode 100644
index 0000000000..8fd11b4032
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/introduction/chapter.xml
@@ -0,0 +1,842 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.125
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="introduction">
+ <info><title>簡介</title>
+ <authorgroup>
+ <author><personname><firstname>Jim</firstname><surname>Mock</surname></personname><contrib>Restructured, reorganized, and parts
+ rewritten by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="introduction-synopsis">
+ <title>概述</title>
+
+ <para>非常感謝您對 &os; 感興趣!以下章節涵蓋 &os;
+ 計劃的各方面:比如它的歷史、目標、開發模式等等。</para>
+
+ <para>讀完這章,您將了解︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>&os; 與其他 OS 之間的關係;</para>
+ </listitem>
+ <listitem>
+ <para>&os; 計劃的歷史源流;</para>
+ </listitem>
+ <listitem>
+ <para>&os; 計劃的目標;</para>
+ </listitem>
+ <listitem>
+ <para>&os; open-source 開發模式的基礎概念;</para>
+ </listitem>
+ <listitem>
+ <para>當然囉,還有 <quote>&os;</quote> 這名字的由來。</para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 xml:id="nutshell">
+ <title>Welcome to &os;!</title>
+ <indexterm><primary>4.4BSD-Lite</primary></indexterm>
+
+ <para>&os; 是一個從 4.4BSD-Lite 衍生出而能在以 Intel (x86 and &itanium;),
+ AMD64, <trademark>Alpha</trademark>, Sun &ultrasparc;
+ 為基礎的電腦上執行的作業系統。同時,移植到其他平台的工作也在進行中。
+ 對於本計劃歷史的介紹,請看 <link linkend="history">&os; 歷史源流</link>,
+ 對於 &os; 的最新版本介紹,請看 <link linkend="relnotes">current release
+ </link>。若打算對於 &os; 計劃有所貢獻的話(像是程式碼硬體設備、基金),
+ 請看 <link xlink:href="&url.articles.contributing;/index.html">如何對 &os;
+ 有貢獻</link>。</para>
+
+ <sect2 xml:id="os-overview">
+ <title>&os; 能做什麼?</title>
+
+ <para>&os; 提供給你許多先進功能。這些功能包括:</para>
+
+ <itemizedlist>
+ <listitem>
+ <indexterm><primary>先佔式多工(preemptive multitasking)</primary></indexterm>
+
+ <para>動態優先權調整的『先佔式多工』能夠確保,即使在系統負擔很重的情況下,
+ 程式執行平順並且應用程式與使用者公平地共享資源。</para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>支援多人共用</primary></indexterm>
+
+ <para>『多人共用(multi-user)』代表著許多人可以同時使用一個 &os; 系統來處理各自的事務。
+ 系統的硬體周邊(如印表機及磁帶機)也可以讓所有的使用者適當地分享。
+ 也可以針對各別使用者或一群使用者的系統資源,予以設限,
+ 以保護系統不致被過度使用。</para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>TCP/IP 網路功能</primary></indexterm>
+
+ <para>好用的『TCP/IP 網路功能』可支援許多業界標準,比如:
+ SCTP、DHCP、NFS、NIS、PPP、SLIP、IPSec、IPv6 的支援,也就是說 &os;
+ 可以容易地跟其他作業系統透過網路共同運作,或是當作企業的伺服器用途
+ ,例如提供遠端檔案共享(NFS)及電子郵件(email)等服務,
+ 或是讓您的企業連上網際網路(Internet)並提供 WWW、FTP、
+ 路由(routing)、及防火牆(firewall、security) 等必備服務。</para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>記憶體保護</primary></indexterm>
+
+ <para>『記憶體保護(Memory protection)』能確保程式(或是使用者)不會互相干擾,
+ 即使任何程式有不正常的運作,都不會影響其他程式的執行。</para>
+ </listitem>
+
+ <listitem>
+ <para>&os; 是『32位元(32-bit)』的作業系統
+ (在 Alpha、&itanium;、 AMD64 及 &ultrasparc; 上則是『64位元(64-bit)』)
+ — 打從一開始便是這樣設計的。</para>
+ </listitem>
+
+ <listitem>
+ <indexterm>
+ <primary>X Window System</primary>
+ <seealso>XFree86</seealso>
+ </indexterm>
+
+ <para>業界標準的『X Window 系統』(X11R7)可以在常見的便宜 VGA 顯示卡/螢幕,
+ 提供了圖形化的使用者介面(GUI),並且包括了完整的原始程式碼。</para>
+ </listitem>
+
+ <listitem>
+ <indexterm>
+ <primary>binary compatibility</primary>
+ <secondary>Linux</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>binary compatibility</primary>
+ <secondary>SCO</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>binary compatibility</primary>
+ <secondary>SVR4</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>binary compatibility</primary>
+ <secondary>BSD/OS</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>binary compatibility</primary>
+ <secondary>NetBSD</secondary>
+ </indexterm>
+ <para>能『直接執行』許多其他作業系統(比如: Linux、SCO、SVR4、BSDI 和 NetBSD)
+ 的可執行檔。</para>
+ </listitem>
+
+ <listitem>
+ <para>數以萬計的立即可以執行的應用程式,這些都可透過 &os;
+ 的『ports』及『packages』軟體管理機制來取得。
+ 不再需要費心到網路上到處搜尋所需要的軟體。</para>
+ </listitem>
+
+ <listitem>
+ <para>此外,網路上尚有可非常容易移植的數以萬計應用程式。
+ &os; 的原始程式碼與許多常見的商業版 &unix; 系統都相容,
+ 所以大部分的程式都只需要很少的修改(或根本不用修改)
+ ,就可以編譯執行。</para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>virtual memory</primary></indexterm>
+
+ <para>需要時才置換(demand paged) <emphasis>virtual memory</emphasis> 及
+ <quote>merged VM/buffer cache</quote> 的設計,
+ 這點在系統中有用去大量記憶體的程式執行時,仍然有不錯的效率表現。</para>
+ </listitem>
+
+ <listitem>
+ <indexterm>
+ <primary>Symmetric Multi-Processing (SMP)</primary>
+ </indexterm>
+
+ <para>支援 CPU 的對稱多工處理(SMP):可以支援多 CPU
+ 的電腦系統。</para>
+ </listitem>
+
+ <listitem>
+ <indexterm>
+ <primary>compilers</primary>
+ <secondary>C</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>compilers</primary>
+ <secondary>C++</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>compilers</primary>
+ <secondary>FORTRAN</secondary>
+ </indexterm>
+ <para>完全相容的 <emphasis>C</emphasis>、<emphasis>C++</emphasis> 以及
+ <emphasis>Fortran</emphasis> 的環境和其他開發工具。
+ 以及其他許多可供進階研發的程式語言也收集在 ports 和 packages。
+ </para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>source code</primary></indexterm>
+
+ <para>整個系統都有『原始程式碼』,
+ 這讓你對作業環境擁有最完全的掌握度。
+ 既然能擁有完全開放的系統,何苦被特定封閉軟體所約束,任廠商擺佈呢?
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>廣泛且豐富的『線上文件』。</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>當然囉,還不止如此!</emphasis></para>
+ </listitem>
+ </itemizedlist>
+
+ <indexterm><primary>4.4BSD-Lite</primary></indexterm>
+ <indexterm>
+ <primary>Computer Systems Research Group (CSRG)</primary>
+ </indexterm>
+ <indexterm><primary>U.C. Berkeley</primary></indexterm>
+ <para>&os; 系統乃是基於美國加州大學柏克萊分校的電腦系統研究群
+ (Computer Systems Research Group 也就是 CSRG) 所發行的
+ 4.4BSD-Lite,以及基於 BSD 系統開發的優良傳統。
+ 除了由 CSRG 所提供的高品質的成果,
+ 為了提供可處理真正具負荷的工作,
+ &os; 計劃也投入了數千小時以上的細部調整,
+ 以能獲得最好的執行效率以及系統的穩定度。
+ 正當許多商業上的巨人正努力地希望能提供效能及穩定時,
+ &os; 已經具備這樣的特質 -- <emphasis>就是現在</emphasis>!
+ </para>
+
+ <para>&os; 的運用範圍無限,其實完全限制在你的想像力上。
+ 從軟體的開發到工廠自動化,或是人造衛星上面的天線的方位角度的遠端控制;
+ 這些功能若可以用商用的 Unix 產品來達成,
+ 那麼極有可能使用 &os; 也能辦到!
+ &os; 也受益於來自於全球各研究中心及大學所開發的數千個高品質的軟體
+ ,這些通常只需要花費很少的費用或根本就是免費的。
+ 當然也有商業軟體,而且出現的數目是與日俱增。</para>
+
+ <para>由於每個人都可以取得 &os; 的原始程式碼,
+ 這個系統可以被調整而能執行任何原本完全無法想像的功能或計劃,
+ 而對於從各廠商取得的作業系統通常沒有辦法這樣地被修改。
+ 以下提供一些人們使用 &os; 的例子:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>網路服務:</emphasis> &os;
+ 內建強勁的網路功能使它成為網路服務(如下例)的理想平台:</para>
+
+ <itemizedlist>
+ <listitem>
+ <indexterm><primary>FTP servers</primary></indexterm>
+
+ <para>檔案伺服器(FTP servers)</para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>web servers</primary></indexterm>
+
+ <para>全球資訊網伺服器(WWW servers)
+ (標準的或更安全的 [SSL] 連線)</para>
+ </listitem>
+
+ <listitem>
+ <para>IPv4 及 IPv6 routing</para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>firewall</primary></indexterm>
+
+ <indexterm><primary>IP masquerading</primary></indexterm>
+
+ <para>防火牆以及 NAT (<quote>IP masquerading</quote>)
+ gateways。</para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>electronic mail</primary></indexterm>
+
+ <para>電子郵件伺服器(Electronic Mail servers)</para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>USENET</primary></indexterm>
+
+ <para>網路新聞伺服器(USENET News)
+ 或是電子佈告欄系統(BBS)</para>
+ </listitem>
+
+ <listitem>
+ <para>還有更多...</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>有了 &os;,您可以容易地先用便宜的 386 PC,
+ 再逐步升級您的機器到四個 CPU 的 Xeon
+ 並使用磁碟陣列(RAID)來滿足您企業運用上的需求。</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>教育:</emphasis>
+ 若您是資工相關領域的學生,再也沒有比使用 &os;
+ 能學到更多作業系統、計算機結構、及網路的方法了。
+ 另外如果你想利用電腦來處理一些<emphasis>其他的</emphasis>
+ 工作,還有一些如 CAD、
+ 數學運算以及圖形處理軟體等可以免費地取得使用。</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>研究:</emphasis>有了完整的原始程式碼,&os;
+ 是研究作業系統及電腦科學的極佳環境。
+ 具有免費且自由取得特性的 &os;
+ 也使得一個分置兩地的合作計劃,不必擔心版權及系統開放性的問題,
+ 而能自在的交流。</para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>router</primary></indexterm>
+
+ <indexterm><primary>DNS Server</primary></indexterm>
+
+ <para><emphasis>網路:</emphasis>
+ 你如果需要 router、Name Server (DNS) 或安全的防火牆(Firewall),
+ &os; 可以輕易的將你沒有用到的 386 或 486 PC
+ 變身成為絕佳的伺服器,甚至具有過濾封包(packet-filter) 的功能。
+ </para>
+ </listitem>
+
+ <listitem>
+ <indexterm>
+ <primary>X Window System</primary>
+ <secondary>XFree86</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>X Window System</primary>
+ <secondary>Accelerated-X</secondary>
+ </indexterm>
+ <para><emphasis>X 視窗工作站:</emphasis> &os; 是 X
+ 終端機的良策,你可以使用免費的 X11 Server。
+ &os; 不但可以充當遠端 X 程式終端機,
+ 也可以執行本地的 X 程式而減輕大型工作站的負荷。
+ 如果有一台中央伺服器的話,&os; 甚至可以經由網路開機
+ (不需硬碟,也就是<quote>diskless</quote>)
+ ,而變成更便宜且易於管理的工作站。</para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>GNU Compiler Collection</primary></indexterm>
+
+ <para><emphasis>軟體開發:</emphasis>
+ 基本安裝的 &os; 就包含了完整的程式開發工具,如 GNU C/C++
+ 編譯器及除錯器。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>你可以經由燒錄 CD-ROM、DVD 或是從 FTP 站上抓回 &os; --
+ 包括立即可執行的系統以及系統的完整程式碼。
+ 詳情請參閱 <xref linkend="mirrors"/> 取得 &os;。</para>
+ </sect2>
+
+ <sect2>
+ <title>誰在用 &os;?</title>
+
+ <indexterm>
+ <primary>users</primary>
+ <secondary>large sites running &os;</secondary>
+ </indexterm>
+ <para>許多 Internet 上的大型網站都是以 &os; 作為它的作業系統,例如:</para>
+
+ <itemizedlist>
+ <listitem>
+ <indexterm><primary>Yahoo!</primary></indexterm>
+
+ <para><link xlink:href="http://www.yahoo.com/">Yahoo!</link></para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>Apache</primary></indexterm>
+
+ <para><link xlink:href="http://www.apache.org/">Apache</link></para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>Blue Mountain Arts</primary></indexterm>
+
+ <para><link xlink:href="http://www.bluemountain.com/">Blue Mountain
+ Arts</link></para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>Pair Networks</primary></indexterm>
+
+ <para><link xlink:href="http://www.pair.com/">Pair
+ Networks</link></para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>Sony Japan</primary></indexterm>
+
+ <para><link xlink:href="http://www.sony.co.jp/">Sony
+ Japan</link></para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>Netcraft</primary></indexterm>
+
+ <para><link xlink:href="http://www.netcraft.com/">Netcraft</link>
+ </para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>Weathernews</primary></indexterm>
+
+ <para><link xlink:href="http://www.wni.com/">Weathernews</link>
+ </para></listitem>
+
+ <listitem>
+ <indexterm><primary>Supervalu</primary></indexterm>
+
+ <para><link xlink:href="http://www.supervalu.com/">Supervalu</link></para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>TELEHOUSE America</primary></indexterm>
+
+ <para><link xlink:href="http://www.telehouse.com/">TELEHOUSE
+ America</link></para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>Sophos Anti-Virus</primary></indexterm>
+
+ <para><link xlink:href="http://www.sophos.com/">Sophos
+ Anti-Virus</link></para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>JMA Wired</primary></indexterm>
+
+ <para><link xlink:href="http://www.jmawired.com/">JMA Wired</link></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>以及許多其他的網站。</para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="history">
+ <title>關於 &os; 計劃</title>
+
+ <para>接下來講的是 &os; 計劃的背景,包含歷史源流的簡介、計劃的目標,以及開發的模式。</para>
+
+ <sect2 xml:id="intro-history">
+ <info role="firstperson"><title>&os; 歷史源流的簡介</title>
+ <authorgroup>
+ <author><personname><firstname>Jordan</firstname><surname>Hubbard</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm><primary>386BSD Patchkit</primary></indexterm>
+ <indexterm><primary>Hubbard, Jordan</primary></indexterm>
+ <indexterm><primary>Williams, Nate</primary></indexterm>
+ <indexterm><primary>Grimes, Rod</primary></indexterm>
+ <indexterm>
+ <primary>&os; Project</primary>
+ <secondary>history</secondary>
+ </indexterm>
+ <para>&os; 計畫的想法是在 1993 年初所形成的,
+ 那是源自於維護一組 『非官方 386BSD 的 patchkit(修正工具)』計劃的三個協調維護人
+ Nate Williams,Rod Grimes 和我(Jordan Hubbard)。</para>
+
+ <indexterm><primary>386BSD</primary></indexterm>
+ <para>我們最初的目標是做出一份 386BSD 綜合修正的 snapshot 版,以便修正當時一堆
+ patchkit 都不容易解決的問題。有些人可能還記得早期的計劃名稱叫做
+ <quote>386BSD 0.5</quote> 或 <quote>386BSD Interim</quote> 就是這個原因。</para>
+
+ <indexterm><primary>Jolitz, Bill</primary></indexterm>
+ <para>386BSD 是 Bill Jolitz 的作業系統,在當時就已有約一年的分裂討論。
+ 當該修正工具 (patchkit) 日漸龐雜得令人不舒服,我們無異議地同意要作一些事了,
+ 並決定提供一份臨時性的 <quote>淨化版(cleanup)</quote> 來幫助 Bill。
+ 然而,由於 Bill Jolitz 忽然決定取消其對該計劃的認可,且沒有明確指出未來的打算,
+ 所以該計劃便突然面臨斷炊危機。</para>
+
+ <indexterm><primary>Greenman, David</primary></indexterm>
+ <indexterm><primary>Walnut Creek CD-ROM</primary></indexterm>
+ <para>不久我們便決定在即使沒有 Bill 的支持下,讓該計劃仍然繼續下去,
+ 最後我們採用 David Greenman 丟銅板決定的名字,也就是『&os;』。
+ 在詢問了當時的一些使用者意見之後,就開始決定了最初的目標,
+ 當該計劃開始實施一切就要成真時,一切就變得更清楚了。
+ 我跟 Walnut Creek CD-ROM 討論發行 CD-ROM
+ 這樣子不便上網的人就可以用比較簡單的方式取得 &os;。
+ Walnut Creek CD-ROM 不只贊成以 CD-ROM 來發行 &os;
+ 的想法,同時提供了一台機器以及快速的網際網路的頻寬。
+ 如果不是 Walnut Creek CD-ROM 幾乎是空前的信任這個剛開始還是完全默默無聞的計劃,
+ 那麼很可能 &os; 不會如此快速的成長到今日這樣的規模。</para>
+
+ <indexterm><primary>4.3BSD-Lite</primary></indexterm>
+ <indexterm><primary>Net/2</primary></indexterm>
+ <indexterm><primary>U.C. Berkeley</primary></indexterm>
+ <indexterm><primary>386BSD</primary></indexterm>
+ <indexterm><primary>Free Software Foundation</primary></indexterm>
+ <para>第一張以 CD-ROM (及網路)發行的 &os;&nbsp;1.0 是在 1993 年十二月。
+ 該版本是基於由 U.C. Berkeley 以磁帶方式發行的
+ 4.3BSD-Lite (<quote>Net/2</quote>)以及許多來自於 386BSD
+ 和自由軟體基金會的軟體。對於第一次發行而言還算成功,
+ 我們又接著於 1994 年 5 月發行了相當成功的 &os; 1.1。</para>
+
+ <indexterm><primary>Novell</primary></indexterm>
+ <indexterm><primary>U.C. Berkeley</primary></indexterm>
+ <indexterm><primary>Net/2</primary></indexterm>
+ <indexterm><primary>AT&amp;T</primary></indexterm>
+ <para>然而此後不久,另一個意外的風暴在 Novell 和 U.C. Berkeley 關於
+ Berkeley Net/2 磁帶之法律地位的訴訟確定之後形成。
+ U.C. Berkeley 接受大部份的 Net/2 的程式碼都是『侵佔來的』且是屬於 Novell 的財產
+ -- 事實上是當時不久前從 AT&amp;T 取得的。
+ Berkeley 得到的是 Novell 對於 4.4BSD-Lite 的『祝福』,最後當 4.4BSD-Lite
+ 終於發行之後,便不再是侵佔行為。
+ 而所有現有 Net/2 使用者都被強烈建議更換新版本,這包括了 &os;。
+ 於是,我們被要求於 1994 年 6 月底前停止散佈基於 Net/2
+ 的產品。在此前提之下,本計劃被允許在期限以前作最後一次發行,也就是
+ &os;&nbsp;1.1.5.1。</para>
+
+ <para>&os; 便開始了這宛如『重新發明輪子』的艱鉅工作 -- 從全新的且不完整的
+ 4.4BSD-Lite 重新整合。
+ 這個 <quote>Lite</quote> 版本是不完整的,因為
+ Berkeley 的 CSRG 已經刪除了大量在建立一個可以開機執行的系統所需要的程式碼
+ (基於若干法律上的要求),且該版本在 Intel 平台的移植是非常不完整的。
+ 直到 1994 年 11 月本計劃才完成了這個轉移,
+ 同時在該年 12 月底以 CD-ROM 以及網路的形式發行了 &os;&nbsp;2.0。
+ 雖然該份版本在當時有點匆促粗糙,但仍是富有意義的成功。
+ 隨之於 1995 年 6 月又發行了更容易安裝,更好的 &os;&nbsp;2.0.5。</para>
+
+ <para>我們在 1996 年 8 月發行了 &os;&nbsp;2.1.5,在 ISP 和商業團體中非常流行。
+ 隨後, 2.1-STABLE 分支的另一個版本應運而生,它就是在 1997 年 2 月發行 &os; 2.1.7.1
+ ,同時也是 2.1-STABLE 分支的最後版。之後此分支便進入維護狀態,
+ 僅僅提供安全性的加強和其他嚴重錯誤修補的維護(RELENG_2_1_0)。</para>
+
+ <para>1996 年 11 月 &os;&nbsp;2.2 從開發主軸分支 (<quote>-CURRENT</quote>)
+ 出來成為 RELENG_2_2 分支。它的第一個完整版(2.2.1)於 1997 年 4 月發行。
+ 2.2 分支的延續版本在 97 年夏秋之間發行的,其最後版是在 1998 年 11 月發行的 2.2.8 版。
+ 第一個正式的 3.0 版本在 1998 年 10 月發行,亦即宣告 2.2 分支的落幕。</para>
+
+ <para>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 分支最後一個發行版本。</para>
+
+ <para>在 2000/03/13 又有了一個新的分支, 也就是 4.X-STABLE
+ 。這個分支之後發佈了許多的發行版本︰ 4.0-RELEASE 在 2000 年 3 月發行,
+ 而最後的 4.11-RELEASE 則在 2005 年 1 月發行。4-STABLE 分支的支援會持續到 2007/01/31
+ ,但主要焦點在於安全方面的漏洞、臭蟲及其他嚴重問題的修補。</para>
+
+ <para>期待已久的 5.0-RELEASE 在 2003/01/19 正式發行。這是將近開發三年的巔峰之作,同時
+ 也開始加強多顆CPU(SMPng)的支援、kernel thread(KSE) 的支援、檔案系統採用 UFS2 以及支援 snapshot
+ 等, 並支援 &ultrasparc; 和
+ <literal>ia64</literal> 平台、支援藍芽、32 bit 的 PCMCIA 等。之後於 2003 年 6 月發行了 5.1。
+ 而 -CURRENT 這個發展主軸分支的最後 5.X 版本是在 2004 年 2 月正式發行的 5.2.1-RELEASE,在 5.X
+ 系列進入 -STABLE (RELENG_5分支)之後,-CURRENT 就轉移為 6.X 系列。</para>
+
+ <para>RELENG_5 分支於 2004 年 8 月正式開跑,之後是 5.3-RELEASE
+ ,它是 5-STABLE 分支的第一個發行版本。 最後的 5.5-RELEASE 是在
+ 2006 年 5 月發行的,在此之後 RELENG_5 分支不再繼續。</para>
+
+ <para>RELENG_6 分支於 2005 年 7 月開跑,而 6.X 分支的第一個
+ release(6.0-RELEASE) 是在 2005 年 11 月出的。
+ 最新的 &rel2.current;-RELEASE 是在 &rel2.current.date;
+ 發行。 當然囉,RELENG_6 分支還將有後續的發行版。</para>
+
+ <para>RELENG_7 分支於 2007 年 10 月開跑,最新的 &rel.current;-RELEASE
+ 是在 &rel.current.date; 發行。 RELENG_7
+ 分支還將有後續的發行版。</para>
+
+ <para>目前,長期的開發計畫繼續在 8.X-CURRENT (trunk) 分支中進行,而
+ 8.X 的 CD-ROM (當然,也可以用網路抓) snapshot 版本可以在 <link xlink:href="ftp://current.FreeBSD.org/pub/FreeBSD/snapshots/">FreeBSD snapshot server</link>
+ 取得。</para>
+ </sect2>
+
+ <sect2 xml:id="goals">
+ <info><title>&os; 計劃的目標</title>
+ <authorgroup>
+ <author><personname><firstname>Jordan</firstname><surname>Hubbard</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm>
+ <primary>&os; Project</primary>
+ <secondary>goals</secondary>
+ </indexterm>
+ <para>&os; 計劃的目標在於提供可作任意用途的軟體而不附帶任何限制條文。
+ 我們之中許多人對程式碼 (以及計畫本身) 都有非常大的投入,
+ 因此,當然不介意偶爾有一些資金上的補償,但我們並沒打算堅決地要求得到這類資助。
+ 我們認為我們的首要『使命(mission)』是為任何人提供程式碼,
+ 不管他們打算用這些程式碼做什麼, 因為這樣程式碼將能夠被更廣泛地使用,從而發揮其價值。
+ 我認為這是自由軟體最基本的,同時也是我們所倡導的一個目標。</para>
+
+ <indexterm>
+ <primary>GNU General Public License (GPL)</primary>
+ </indexterm>
+ <indexterm>
+ <primary>GNU Lesser General Public License (LGPL)</primary>
+ </indexterm>
+ <indexterm><primary>BSD Copyright</primary></indexterm>
+ <para>我們程式碼樹中,有若干是以 GNU GPL 或者 LGPL
+ 發佈的那些程式碼帶有少許的附加限制,還好只是強制性的要求開放程式碼而不是別的。
+ 由於使用 GPL 的軟體在商業用途上會增加若干複雜性,因此,如果可以選擇的話,
+ 我們會比較喜歡使用限制相對更寬鬆的 BSD 版權來發佈軟體。</para>
+ </sect2>
+
+ <sect2 xml:id="development">
+ <info><title>&os; 的開發模式</title>
+ <authorgroup>
+ <author><personname><firstname>Satoshi</firstname><surname>Asami</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm>
+ <primary>&os; Project</primary>
+ <secondary>development model</secondary>
+ </indexterm>
+ <para>&os; 的開發是一個非常開放且具彈性的過程,就像從 <link xlink:href="&url.articles.contributors;/article.html">貢獻者名單</link>
+ 所看到的,是由全世界成千上萬的貢獻者發展起來的。
+ &os; 的開發基礎架構允許數以百計的開發者透過網際網路協同工作。
+ 我們也經常關注著那些對我們的計畫感興趣的新開發者和新的創意,
+ 那些有興趣更進一步參與計劃的人只需要在 &a.hackers; 連繫我們。
+ &a.announce; 對那些希望了解我們進度的人也是相當有用的。</para>
+
+ <para>無論是單獨開發者或者封閉式的團隊合作,多瞭解 &os; 計劃和它的開發過程會是不錯的︰</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>The SVN and CVS repository<anchor xml:id="development-cvs-repository"/></term>
+
+ <listitem>
+ <indexterm>
+ <primary>CVS</primary>
+ <secondary>repository</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>Concurrent Versions System</primary>
+ <see>CVS</see>
+ </indexterm>
+ <indexterm>
+ <primary>SVN</primary>
+ <secondary>repository</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>Subversion</primary>
+ <see>SVN</see>
+ </indexterm>
+ <para>過去數年來 &os; 的中央 source tree 一直是以
+ <link xlink:href="http://ximbiot.com/cvs/wiki/">CVS</link>
+ (Concurrent Versions System) 來維護的,
+ 它是個自由軟體,可用來做為版本控制,一裝完 &os; 內就有附了。
+ 然而在 2008 年 6 月起, &os; 版本控制系統改用 <link xlink:href="http://subversion.tigris.org">SVN</link>(Subversion)。
+ 這切換動作我們認為是有必要,因為 <application>CVS</application>
+ 先天的技術限制,導致 source tree 以及歷史版本數量不斷快速擴張。
+ 因此,主要的 repository 目前是採用 <application>SVN</application>
+ ,而 client 端的工具像是 <application>CVSup</application>、
+ <application>csup</application> 都是以舊式的
+ <application>CVS</application> 架構為基礎,仍可以繼續正常運作
+ &mdash; 此乃因 <application>SVN</application> repository
+ 有 backport 回 <application>CVS</application> 才可以繼續讓 client
+ 端相容。 目前,就只有中央 source tree 是採
+ <application>SVN</application> 版本控制方式。 而文件、網頁、
+ Ports 這些 repository 仍持續使用 <application>CVS</application>
+ 版本控制方式。
+ 而主要的 <link xlink:href="http://www.FreeBSD.org/cgi/cvsweb.cgi">CVS
+ repository</link> 是位於美國加州 Santa Clara 的某台機器上,
+ 然後再 mirror 到世界上其他的許多機器上。
+ <application>SVN</application> tree 內有兩個主分支:
+ <link linkend="current">-CURRENT</link> 以及 <link linkend="stable">-STABLE</link> ,這些都可輕鬆複製到自己機器上。
+ 詳情請參閱 <link linkend="synching">更新你的 source tree</link>
+ 一節。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>The committers list<anchor xml:id="development-committers"/></term>
+
+ <listitem>
+ <indexterm><primary>committers</primary></indexterm>
+
+ <para>所謂的 <firstterm>committers</firstterm>
+ 指的是對 CVS tree 有 <emphasis>write</emphasis> 權限,
+ 並依不同授權部分,而有不同權限可修改 &os; source。
+ (<quote>committer</quote> 這詞源自 &man.cvs.1; 中的
+ <command>commit</command> 指令,該指令是用來把新的修改提交給
+ CVS repository。)
+ 而提交修改給 committer 們檢查的最好方式,就是用 &man.send-pr.1;
+ 指令。 若提交 PR 的流程系統上有壅塞現象的話,
+ 也可以改用寄信方式,寄信到 &a.committers; 即可。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>The &os; core team<anchor xml:id="development-core"/></term>
+
+ <listitem>
+ <indexterm><primary>core team</primary></indexterm>
+
+ <para>如果把 &os; 看成是一家公司的話,
+ <firstterm>&os; core team</firstterm>
+ 就相當於『董事會(board of directors)』。 core team
+ 的主要職責在於確保此計劃有良好的架構,以朝著正確的方向發展。
+ 此外,邀請熱血且負責的軟體開發者加入 committers 行列,
+ 以在若干成員離去時得以補充新血。
+ 目前的 core team 是在 2008 年 7 月 committers
+ 候選人中選出來的,每兩年會舉辦一次選舉。</para>
+
+ <para>有些 core team 成員還負責某些特定範圍,
+ 也就是說他們必須盡量確保一些子系統的穩定、效能。
+ 關於 &os; 開發者們以及各自責任範圍,請參閱 <link xlink:href="&url.articles.contributors;/article.html">貢獻者名單
+ </link>。</para>
+
+ <note>
+ <para>core team 大部分成員加入 &os; 開發都是志工性質而已,
+ 並未從本計劃中獲得任何薪酬,所以不該把
+ <quote>commitment</quote> 誤解為
+ <quote>guaranteed support</quote> 才對。
+ 剛前面所講的『董事會』可能是不恰當的類推,或許我們應該說:
+ 他們是一群自願放棄原本的優渥生活、個人其他領域成就,
+ 而選擇投入 &os; 開發的熱血有為者才對!</para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>其他的貢獻者</term>
+
+ <listitem>
+ <indexterm><primary>contributors</primary></indexterm>
+
+ <para>最後一點,但這點絕非最不重要的,
+ 最大的開發者團隊就是持續為我們提供回饋以及錯誤修正的使用者自己。
+ 與 &os; 非核心開發者互動的主要方式,便是透過訂閱 &a.hackers;
+ 來進行溝通,這方面可參考,請參閱 <xref linkend="eresources"/> 以瞭解各式不同的 &os;
+ 郵遞論壇(mailing lists)。</para>
+
+ <para><citetitle><link xlink:href="&url.articles.contributors;/article.html">&os; 貢獻者名單
+ </link></citetitle> 相當長且不斷成長中,
+ 只要有貢獻就會被列入其中,
+ 要不要立即考慮貢獻 &os; 一些回饋呢?</para>
+
+ <para>然而,提供原始碼並非為這個計劃做貢獻的唯一方式;
+ 還需要大家投入的完整工作列表、說明,請參閱 <link xlink:href="&url.base;/index.html">&os; 官網</link>。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>簡單的說,我們的開發模式就像是一組沒有拘束的同心圓。
+ 這種集中開發模式是以 <emphasis>給使用者方便</emphasis> 為主,
+ 同時讓他們能很容易地共同維護軟體,而不會把潛在的貢獻者排除在外!
+ 我們的目標是提供含有大量一致性的
+ <link linkend="ports">應用軟體(ports/packages)</link>
+ ,以便讓使用者輕鬆安裝、使用的作業系統 ——
+ 而這開發模式相當符合此一目標。</para>
+
+ <para>我們對於那些想要加入 &os; 開發者的期待是:
+ 請保持如同前人一樣的投入,以確保繼續成功!</para>
+ </sect2>
+
+ <sect2 xml:id="relnotes">
+ <title>最新的 &os; 發行版本</title>
+
+ <indexterm><primary>NetBSD</primary></indexterm>
+ <indexterm><primary>OpenBSD</primary></indexterm>
+ <indexterm><primary>386BSD</primary></indexterm>
+ <indexterm><primary>Free Software Foundation</primary></indexterm>
+ <indexterm><primary>U.C. Berkeley</primary></indexterm>
+ <indexterm>
+ <primary>Computer Systems Research Group (CSRG)</primary>
+ </indexterm>
+ <para>&os; 是免費使用且帶有完整原始程式碼的以 4.4BSD-Lite
+ 為基礎的系統,可以在
+ Intel &i386;, &i486;, &pentium;,
+ &pentium;&nbsp;Pro,
+ &celeron;,
+ &pentium;&nbsp;II,
+ &pentium;&nbsp;III,
+ &pentium;&nbsp;4 (或者相容型號),
+ &xeon;, DEC <trademark>Alpha</trademark>
+ 和 Sun &ultrasparc; 為基礎的電腦上執行的作業系統。
+ 它主要以加州大學巴爾克利分校 的 CSRG 研究小組的軟體為基礎,並加入了
+ NetBSD、OpenBSD、386BSD 以及自由軟體基金會的一些東西。</para>
+
+ <para>自從 1994 年末,我們發佈了 &os;&nbsp;2.0 之後,系統的執行效率、
+ 功能、穩定性都有了令人注目的提升。
+ <!-- XXX is the rest of this paragraph still true ? -->
+ 最大的改變就是我們將記憶體與檔案系統的 cache 機制結合在一起。
+ 這不只使得系統的表現變得更好, 並且使得 &os;
+ 系統最少的記憶體需求減少到 5&nbsp;MB。
+ 其它的改進包括完整的 NIS cilent and server 功能支援,
+ 支援 transaction TCP、PPP 撥接連線、整合的 DHCP 支援、
+ SCSI 子系統的改進、ISDN 的支援,ATM、FDDI 以及乙太網路 (Ethernet、包括
+ 100&nbsp;Mbit 和 Gigabit) 的支援,提升了最新的 Adaptec
+ 控制卡驅動程式的改善,以及數以千計的 bug 修正。</para>
+
+ <para>除了最基本的系統軟體,&os; 還提供了廣受歡迎的套件軟體管理機制:
+ Ports Collection。
+ 到本書付印時,已有超過 &os.numports; 個 ports,這範疇涵蓋從 http(WWW)
+ 伺服器到遊戲、程式語言、編輯器以及您能想到的幾乎所有的東西。
+ 完整的 Ports Collection 需要約 &ports.size; 的硬碟空間,除了
+ port 基本架構檔案外,都只儲存與該 port
+ 軟體的原始碼有『須要變更』的部份。
+ 如此一來,我們可以更容易更新這些 ports,也大量的減少如舊的 1.0 版
+ Ports Collection 對於硬碟空間的需求。
+ 要安裝一個 port 的話,只需要進入該 port 的目錄,輸入
+ <command>make install</command>,這樣子系統就會幫你裝好了。
+ 您要編譯的每個程式的完整原始程式,
+ 都可從 FTP 或 CD-ROM 中獲得,所以您只需準備足夠的硬碟空間來編譯你要的
+ port 軟體。
+ 幾乎每一個 port 都有已事先編譯好的 <quote>package</quote>以方便安裝,
+ 如果不想從編譯 port 的人,只要用個簡單指令
+ (<command>pkg_add</command>)就可以安裝。
+ 有關 packages 和 ports 的細節,可以參閱 <xref linkend="ports"/>。</para>
+
+ <para>&os; 主機的 <filename>/usr/share/doc</filename>
+ 目錄下找到許多有用的文件,
+ 來幫助您安裝、使用 &os;。
+ 也可以使用下面的網址,以瀏覽器來翻閱本機上安裝的手冊︰</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>&os; 使用手冊</term>
+
+ <listitem>
+ <para><link xlink:href="file://localhost/usr/share/doc/handbook/index.html"><filename>/usr/share/doc/handbook/index.html</filename></link></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&os; 常見問答集</term>
+
+ <listitem>
+ <para><link xlink:href="file://localhost/usr/share/doc/faq/index.html"><filename>/usr/share/doc/faq/index.html</filename></link></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>此外,可在下列網址找到最新版 (也是更新最頻繁的版本):<uri xlink:href="http://www.FreeBSD.org/">http://www.FreeBSD.org/</uri>。</para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/jails/chapter.xml b/zh_TW.UTF-8/books/handbook/jails/chapter.xml
new file mode 100644
index 0000000000..91c7ad185a
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/jails/chapter.xml
@@ -0,0 +1,793 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+
+ Original revision: 1.15
+
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="jails">
+ <info><title>Jails</title>
+ <authorgroup>
+ <author><personname><firstname>Matteo</firstname><surname>Riondato</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm><primary>jails</primary></indexterm>
+
+ <sect1 xml:id="jails-synopsis">
+ <title>概述</title>
+
+ <para>本章將介紹 &os; jail 為何,以及如何運用之法。
+ Jails 有時也常被認為是 <emphasis>chroot 環境</emphasis>
+ 的加強型替代品之一,它對系統管理者而言是非常好用的工具,
+ 此外,它的一些基本用法對進階使用者而言,也是相當有用。</para>
+
+ <para>讀完這章,您將了解︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>jail 是什麼,以及它在 &os; 上可以發揮的作用。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何編譯、啟動、停止 jail。</para>
+ </listitem>
+
+ <listitem>
+ <para>jail 管理的基本概念:包括從 jail 內部或主機本身。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>其他有用的 jail 相關資源還有:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>&man.jail.8; 線上說明。 這是有關 <command>jail</command>
+ 的完整說明 &mdash; &os; 內的啟動、停止、控制 &os; jail
+ 相關管理工具。</para>
+ </listitem>
+
+ <listitem>
+ <para>郵遞論壇(mailing lists)及舊信檔案館(archives)。
+ &a.mailman.lists; 所提供的 &a.questions; 及其他郵遞論壇的舊信
+ ,已有包括一堆 jail 的有用資料。 通常,搜尋舊信或者在
+ &a.questions.name; 上發問,也相當有效。</para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 xml:id="jails-terms">
+ <title>Jail 相關術語</title>
+
+ <para>為協助更容易理解 &os; 系統的 jail 相關部分,
+ 以及它們與 &os; 其他部分的相互作用關係,
+ 以下列出本章將使用的術語:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>&man.chroot.2; (指令)</term>
+ <listitem>
+ <para>&os; 的 system call 之一,其作用為改變 process
+ 及其衍生 process 所能運用的根目錄 (<filename>/</filename>
+ dir)。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&man.chroot.2; (環境)</term>
+ <listitem>
+ <para>指在 <quote>chroot</quote> 中運行的 process 環境。
+ 這包括了類似檔案系統的可見部分、可用的 UID、GID、網路卡及其他 IPC
+ 機制等資源。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&man.jail.8; (command)</term>
+ <listitem>
+ <para>允許程式在 jail 環境下執行的系統管理工具。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>host (系統、process、帳號等等)</term>
+ <listitem>
+ <para>jail 環境的控制系統。 host 系統可以使用全部可用的硬體資源,
+ 並能控制 jail 環境內外的 process。 host 系統與 jail 最大的差別在於
+ :在 host 系統中的 superuser processes 並不像在 jail
+ 環境那樣處處受到一堆限制。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>hosted (系統、process、帳號等等)</term>
+ <listitem>
+ <para>可用資源受到 &os; jail 限制的 process、帳號、或其他設備資源
+ 。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1 xml:id="jails-intro">
+ <title>背景故事</title>
+
+ <para>由於系統管理是困難又繁瑣的工作,因此人們開發許多好用工具,
+ 以讓管理工作更加簡單輕鬆。 這些改善通常是讓系統能夠以更簡單的方式安裝、
+ 設定、維護,而有些改善目標則是系統安全的正確設定,使其能真正發揮原本用途,
+ 而非陷入安全風險之中。</para>
+
+ <para>&os; 系統所提供的一種用於強化安全的工具就是 <emphasis>jail</emphasis>
+ 。 Jail 是由 &a.phk; 於 &os;&nbsp;4.X 開始導入,而在 &os;&nbsp;5.X
+ 受到許多重大改良而集大成,成為強大而靈活的子系統,目前仍在持續開發、
+ 以提高其可用性、效能與安全。</para>
+
+ <sect2 xml:id="jails-what">
+ <title>何為 Jail</title>
+
+ <para>BSD-like 作業系統自 4.2BSD 起即提供 &man.chroot.2;。
+ &man.chroot.8; 可用來變更一組 process 的根目錄位置,
+ 藉此建立與實體系統中相隔離的安全環境。 處於 chrooted 環境的
+ process 會無法不能存取世外的檔案或資源。 由於此因素,
+ 故即使攻擊者攻破某個處於 chroot 環境的 service,也不能攻破整個系統。
+ &man.chroot.8; 對於那些不太需要彈性或複雜又高級的簡單應用而言相當好用。
+ 另外,在引入 chroot 概念的過程中,曾經發現許多可脫逃 chroot 環境的方式,
+ 儘管這些問題在較新版本的 &os; kernel 均已修正,但很明顯地 &man.chroot.2;
+ 絕非用於強化安全的理想解決方案。 因此,
+ 勢必得實作新的子系統來解決這些問題。</para>
+
+ <para>這就是為何要開發 <emphasis>jail</emphasis> 的最主要原因。</para>
+
+ <para>Jail 在各種方式分進合擊,改進傳統 &man.chroot.2; 環境的概念。
+ 在傳統的 &man.chroot.2; 環境中,只限制 process 對於檔案系統的存取部分,
+ 而系統資源的其他部分(例如系統帳號、執行中的 process、網路子系統)則是由
+ chroot process 與 host 系統的其他 process 一起共享。
+ Jail 以『虛擬化』來擴展這模型,不單只有檔案系統的存取,還延伸到
+ 系統帳號、&os; kernel 的網路子系統及其他系統資源的虛擬化。
+ 關於這些 jail 環境存取的細微調控,請參閱 <xref linkend="jails-tuning"/>。</para>
+
+ <para>jail 具有下列四項特色:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>目錄子樹(directory subtree) &mdash; 也就是進入 jail 的起點。
+ 一旦進入 jail 之後,process 就不再被允許跳到 subtree 以外。
+ &amp;傳統會影響到 &man.chroot.2; 最初設計的安全問題,就不會再影響
+ &os; jail。</para>
+ </listitem>
+
+ <listitem>
+ <para>主機名稱(hostname) &mdash; 用於 jail 的 hostname。 由於
+ jail 主要用於網路服務,因此若各 jail 皆有名稱,
+ 對於系統管理工作的簡化會相當有效。</para>
+ </listitem>
+
+ <listitem>
+ <para><acronym>IP</acronym> address &mdash; 是用來給 jail 使用,
+ 並且在 jail 生命週期內都無法變更。 通常 jail 的 IP address
+ 是現有網卡的 alias address,但這並不是必須的。</para>
+ </listitem>
+
+ <listitem>
+ <para>指令(Command) &mdash; 準備在 jail 內執行的完整路徑。 這指令是相對於
+ jail 環境的根目錄,視 jail 環境的類型不同,而有所差異。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>除了上述之外,jail 也可擁有自己的帳號及 <systemitem class="username">root</systemitem>
+ 帳號。 當然,這裡的<systemitem class="username">root</systemitem> 權力會受制於 jail 環境內。
+ 並且從 host 系統的角度來看,jail 的 <systemitem class="username">root</systemitem>
+ 並非無所不能的帳號。 此外 jail 的 <systemitem class="username">root</systemitem>
+ 並不能執行其對於 &man.jail.8; 環境以外的一些關鍵性操作。
+ 關於 <systemitem class="username">root</systemitem> 的能力與限制,將於稍後的
+ <xref linkend="jails-tuning"/> 介紹之。</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="jails-build">
+ <title>建立和控制 Jail</title>
+
+ <para>有些系統管理者把 jail 分為下列兩種:<quote>complete(完全)</quote>
+ jail &mdash; 通常包括完整的 &os; 系統;另一種則為
+ <quote>service(服務)</quote> jail &mdash;
+ 專門只跑某單一可能要用特殊權限的程式或 service。 這只是一種概念上的區分
+ ,並不影響如何建立 jail 的過程。 至於如何建立 jail 在 &man.jail.8;
+ 內有更詳細的說明:</para>
+
+ <screen>&prompt.root; <userinput>setenv D /here/is/the/jail</userinput>
+&prompt.root; <userinput>mkdir -p $D</userinput> <co xml:id="jailpath"/>
+&prompt.root; <userinput>cd /usr/src</userinput>
+&prompt.root; <userinput>make world DESTDIR=$D</userinput> <co xml:id="jailworld"/>
+&prompt.root; <userinput>cd etc/</userinput> <footnote><para>&os; 6.0(含)
+之後就不需這步驟。</para></footnote>
+&prompt.root; <userinput>make distribution DESTDIR=$D</userinput> <co xml:id="jaildistrib"/>
+&prompt.root; <userinput>mount -t devfs $D/dev</userinput> <co xml:id="jaildevfs"/></screen>
+
+ <calloutlist>
+ <callout arearefs="jailpath">
+ <para>首先就是先為 jail 找個家。 該路徑是在 host 系統中的 jail
+ 實體位置。 習慣是放在 <filename>/usr/jail/jailname</filename>,
+ <replaceable>jailname</replaceable> 請替換為該 jail 的 hostname
+ 以便辨別。 通常 <filename>/usr</filename>
+ 會有足夠空間來存放 jail 檔案系統,對於 <quote>complete</quote> jail
+ 而言,它通常包括了 &os; 預設安裝 base system 所有檔案的拷貝檔。</para>
+ </callout>
+
+ <callout arearefs="jailworld">
+ <para>該指令將會在 jail 目錄中安裝所需的 binary、library、manual 說明等
+ 。 這些是以傳統的 &os; 方式完成 &mdash; 即首先先編譯所有檔案,
+ 接著再裝到目的地。</para>
+ </callout>
+
+ <callout arearefs="jaildistrib">
+ <para>使用 <buildtarget>distribution</buildtarget> 這個
+ <application>make</application> target 來裝所有會用到的設定檔。
+ 簡單來說該動作就是把 <filename>/usr/src/etc/</filename> 複製到 jail 環境內的
+ <filename>/etc</filename>,也就是
+ <filename>$D/etc/</filename>。</para>
+ </callout>
+
+ <callout arearefs="jaildevfs">
+ <para>對於 jail 環境而言,&man.devfs.8; 檔案系統的掛載並非必須,
+ 但另一方面,幾乎所有應用程式都會需要存取至少一個設備(device),
+ 這主要取決於該程式目的而定。 控制 jail 所能存取的設備非常重要,
+ 因為不正確的設定,會讓攻擊者對 jail 有機可趁。 至於如何透過
+ &man.devfs.8; 來控制的規則,可以參閱 &man.devfs.8; 及
+ &man.devfs.conf.5; 說明。</para>
+ </callout>
+ </calloutlist>
+
+ <para>裝好 jail 之後,就可以用 &man.jail.8; 工具。 &man.jail.8;
+ 需要四項必填參數,這些參數在 <xref linkend="jails-what"/> 有介紹過。
+ 除了這四個參數之外,還可以指定其他參數,像是以特定帳號在 jail 中執行
+ process。 <option><replaceable>command</replaceable></option>
+ 參數取決於 jail 類型而定;對於 <emphasis>virtual system(虛擬系統)
+ </emphasis>,那麼就選擇 <filename>/etc/rc</filename>,
+ 因為它會完成真正 &os; 系統啟動所需的操作。 對於 <emphasis>service(服務)
+ </emphasis> jail 而言,執行的指令取決於將在 jail 內執行的 service
+ 或應用程式而定。</para>
+
+ <para>Jail 通常要在系統開機時啟動,因此 &os; 的 <filename>rc</filename>
+ 機制提供一些便利的方式來簡化這些工作:</para>
+
+ <procedure>
+ <step>
+ <para>開機時要啟動的 jail 清單要加到 &man.rc.conf.5; 設定檔:</para>
+
+ <programlisting>jail_enable="YES" # 若設為 NO 則表示不自動啟動 jail
+jail_list="<replaceable>www</replaceable>" # 若有許多 jail 則請以空白隔開來寫</programlisting>
+ </step>
+
+ <step>
+ <para>對於每一筆在 <varname>jail_list</varname> 所列出的 jail,
+ 也要在 &man.rc.conf.5; 做出相對應的設定:</para>
+
+ <programlisting>jail_<replaceable>www</replaceable>_rootdir="/usr/jail/www" # jail 的根目錄
+jail_<replaceable>www</replaceable>_hostname="<replaceable>www</replaceable>.example.org" # jail 的 hostname
+jail_<replaceable>www</replaceable>_ip="192.168.0.10" # jail 的 IP address
+jail_<replaceable>www</replaceable>_devfs_enable="YES" # 在 jail 內 mount devfs
+jail_<replaceable>www</replaceable>_devfs_ruleset="<replaceable>www_ruleset</replaceable>" # jail 內所用的 devfs 規則表</programlisting>
+
+ <para>在 &man.rc.conf.5; 所預設的 jail 啟動設定會跑
+ <filename>/etc/rc</filename> 內的 jail script,也就是說會假設 jail
+ 是完整的虛擬系統。 若要用 service jail 類型,則要另外指定啟動指令,
+ 方法是設定對應的
+ <varname>jail_<replaceable>jailname</replaceable>_exec_start</varname>
+ 設定。</para>
+
+ <note>
+ <para>若欲知道所有可用的選項清單,請參閱 &man.rc.conf.5; 說明。</para>
+ </note>
+ </step>
+ </procedure>
+
+ <para>也可以透過手動執行 <filename>/etc/rc.d/jail</filename> script
+ 來啟動或停止 <filename>rc.conf</filename> 所設定的 jail:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/jail start www</userinput>
+&prompt.root; <userinput>/etc/rc.d/jail stop www</userinput></screen>
+
+ <para>目前尚無任何方法來很乾淨地關閉 &man.jail.8;。
+ 此乃因為正常用來關閉系統的指令,目前尚不能在 jail 中使用。 目前關閉 jail
+ 最佳的方式,是在 jail 內執行下列指令,或者 jail 外面透過 &man.jexec.8;
+ 執行下列指令:</para>
+
+ <screen>&prompt.root; <userinput>sh /etc/rc.shutdown</userinput></screen>
+
+ <para>詳情請參閱 &man.jail.8; 說明。</para>
+ </sect1>
+
+ <sect1 xml:id="jails-tuning">
+ <title>微調與管理</title>
+
+ <para>可以為 jail 設定許多不同選項,並讓 &os; 的 host 系統與 jail
+ 以各種不同方式組合搭配,以符合更多的應用用途。 本節要介紹的是:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>用以微調 jail 行為與安全限制的選項。</para>
+ </listitem>
+
+ <listitem>
+ <para>可透過 &os; Ports Collection 安裝的高階 jail 管理程式,
+ 搭配這些程式可以達到一些 jail-based 解決方案。</para>
+ </listitem>
+ </itemizedlist>
+
+ <sect2 xml:id="jails-tuning-utilities">
+ <title>&os; 所提供的 jail tuning 工具</title>
+
+ <para>對於 jail 設定的微調,基本上都是透過設定 &man.sysctl.8; 變數來完成。
+ 系統提供一組 sysctl 的特殊子樹,全部相關的選項都在該子樹內,也就是
+ &os; kernel 中的 <varname>security.jail.*</varname> 子樹。
+ 下面則是與 jail 相關的主要 sysctl 設定及預設值,這些名稱都相當容易理解,
+ 如欲更進一步的資訊,請參閱 &man.jail.8; 與 &man.sysctl.8; 說明:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><varname>security.jail.set_hostname_allowed:
+ 1</varname></para>
+ </listitem>
+
+ <listitem>
+ <para><varname>security.jail.socket_unixiproute_only:
+ 1</varname></para>
+ </listitem>
+
+ <listitem>
+ <para><varname>security.jail.sysvipc_allowed:
+ 0</varname></para>
+ </listitem>
+
+ <listitem>
+ <para><varname>security.jail.enforce_statfs:
+ 2</varname></para>
+ </listitem>
+
+ <listitem>
+ <para><varname>security.jail.allow_raw_sockets:
+ 0</varname></para>
+ </listitem>
+
+ <listitem>
+ <para><varname>security.jail.chflags_allowed:
+ 0</varname></para>
+ </listitem>
+
+ <listitem>
+ <para><varname>security.jail.jailed: 0</varname></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>系統管理者可在 <emphasis>host system</emphasis>
+ 透過修改這些設定值來增加、取消 Jail 內 <systemitem class="username">root</systemitem>
+ 帳號的預設限制。 請注意:有些限制是不能取消,在 &man.jail.8; 環境的
+ <systemitem class="username">root</systemitem> 不能掛載或卸載檔案系統。 此外亦不能載入、
+ 卸載 &man.devfs.8; 規則、設定防火牆規則,或執行其他需修改 kernel
+ 資料的管理作業,例如設定 kernel 的 <varname>securelevel</varname>
+ 值。</para>
+
+ <para>&os; base system 內附一些基本工具,可用來查閱目前使用中的 jail、
+ 並接上(attach) jail 以執行管理指令。 &man.jls.8; 及 &man.jexec.8;
+ 均屬於 &os; base system 之一,可用來執行一些簡單工作:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>列出有在使用的 jail 及其相對應的 jail identifier
+ (<acronym>JID</acronym>)、<acronym>IP</acronym> address、
+ hostname、路徑。</para>
+ </listitem>
+
+ <listitem>
+ <para>接上(Attach)正在運作中的 jail,並在其中執行指令以進行管理工作。
+ 這點在當 <systemitem class="username">root</systemitem> 想乾淨關閉 jail 時相當有用,
+ &man.jexec.8; 也可用在 jail 中啟動 shell 以便對其進行管理,
+ 比如:</para>
+
+ <screen>&prompt.root; <userinput>jexec 1 tcsh</userinput></screen>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2 xml:id="jails-tuning-admintools">
+ <title>&os; Ports Collection 所提供的高階管理工具</title>
+
+ <para>在諸多 third-party 所提供的 jail 管理工具當中,<package>sysutils/jailutils</package> 是最完整也最好用的。
+ 該套件是由一系列 &man.jail.8; 管理小工具所組成的。 詳情請參閱其網站介紹
+ 。</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="jails-application">
+ <title>Jail 的應用</title>
+
+ <sect2 xml:id="jails-service-jails">
+ <info><title>Service Jails</title>
+ <authorgroup>
+ <author><personname><firstname>Daniel</firstname><surname>Gerzo</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <para>本節主要以 &a.simon; 寫的 <uri xlink:href="http://simon.nitro.dk/service-jails.html">http://simon.nitro.dk/service-jails.html</uri> 為主,加上
+ Ken Tom <email>locals@gmail.com</email> 所更新的文章。
+ 本節介紹如何設定 &os; 以 &man.jail.8; 功能來增加額外的安全層面。
+ 這部分假設您系統跑的是 RELENG_6_0 或更新的版本,
+ 並且對本章先前部分均能理解。</para>
+
+ <sect3 xml:id="jails-service-jails-design">
+ <title>Design</title>
+
+ <para>Jail 的主要問題之一在於如何對其進行更新、升級和管理。
+ 由於每個 jail 都是從頭重新編譯,對於單一 jail 而言,
+ 升級也許還不是很嚴重的問題,因為更新、升級並不會太麻煩。
+ 但對於一堆 jail 而言,升級不僅會耗費太多時間,並相當枯燥乏味。</para>
+
+ <warning>
+ <para>這些設定的前提是您對 &os; 使用、功能運用上有相當的經驗,
+ 若下面的設定對您來說太過複雜,建議您該考慮用較簡易的系統,像是
+ <package>sysutils/ezjail</package>,其提供更簡單的
+ &os; jail 管理方式。</para>
+ </warning>
+
+ <para>基本的想法是在不同的 jail 中儘量以安全的方式來共用資源
+ &mdash; 採用唯讀的 &man.mount.nullfs.8; 掛載,來讓升級更簡單,
+ 並把各個 service 放到不同的 jail 的作法會更加可行。 此外,
+ 其也提供對於如何增加、刪除、升級 jail 的簡便方式。</para>
+
+ <note>
+ <para>service 常見的例子包括:
+ <acronym>HTTP</acronym> server、<acronym>DNS</acronym>
+ server、<acronym>SMTP</acronym> server 等等。</para>
+ </note>
+
+ <para>本節介紹的設定目的在於:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>建立簡易且容易理解的 jail 架構。 也就是說
+ <emphasis>不必</emphasis>為每個 jail 都執行完整的 installworld
+ 。</para>
+ </listitem>
+ <listitem>
+ <para>讓 jail 的新增、移除更簡單。</para>
+ </listitem>
+ <listitem>
+ <para>讓 jail 的更新、升級更輕鬆。</para>
+ </listitem>
+ <listitem>
+ <para>可以跑自行打造的 &os; 分支。</para>
+ </listitem>
+ <listitem>
+ <para>對安全有更偏執狂的追求,儘可能降低被攻陷的可能。</para>
+ </listitem>
+ <listitem>
+ <para>儘量節省空間與 inode。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>如同先前所提到的,這設計主要是靠把唯讀的主要模版
+ (也就是大家所熟知的 <application>nullfs</application>)掛載到每個
+ jail,並且讓每個 jail 有個可讀、寫的設備,這設備可以是獨立實體硬碟、
+ 、分割區、或以 vnode 為後端的 &man.md.4; 設備。 在本例當中,
+ 我們採用可讀寫的 <application>nullfs</application> 掛載。</para>
+
+ <para>下面的表則介紹檔案系統的配置:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>每個 jail 都會掛載到 <filename>/home/j</filename> 底下的其中一個目錄。</para>
+ </listitem>
+ <listitem>
+ <para><filename>/home/j/mroot</filename> 則是每個
+ jail 共用的模版,並對於所有 jail 而言都是唯讀。</para>
+ </listitem>
+ <listitem>
+ <para>每個 jail 在 <filename>/home/j</filename>
+ 底下都有一個相對應的空目錄。</para>
+ </listitem>
+ <listitem>
+ <para>每個 jail 都會有 <filename>/s</filename> 目錄,
+ 該目錄會連到系統的可讀寫部分。</para>
+ </listitem>
+ <listitem>
+ <para>每個 jail 都會在 <filename>/home/j/skel</filename> 目錄建立自屬的可讀寫空間
+ 。</para>
+ </listitem>
+ <listitem>
+ <para>每個 jailspace (各 jail 可讀寫的部分) 都建在 <filename>/home/js</filename>&gt;。</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <para>這邊假設所有 jail 都放在
+ <filename>/home</filename> 分割區。 當然,
+ 也可以依自身需求更改,但接下來的例子中,
+ 也要記得修改相對應的地方。</para>
+ </note>
+ <!-- Insert an image or drawing here to illustrate the example. -->
+ </sect3>
+
+ <sect3 xml:id="jails-service-jails-template">
+ <title>建立模版</title>
+
+ <para>本節將逐步介紹如何建立 jail 要用的唯讀主模版。</para>
+
+ <para>建議先把 &os; 系統升級到最新的 -RELEASE 分支,至於如何做請參閱
+ Handbook 的
+ <link xlink:href="&url.books.handbook;/makeworld.html">相關章節</link>。
+ 當更新完成之後,就要進行 buildworld 程序,此外還要裝 <package>sysutils/cpdup</package> 套件。
+ 我們將用 &man.portsnap.8; 來下載 &os; Ports Collection,
+ 在 Handbook 中對 <link xlink:href="&url.books.handbook;/portsnap.html">Portsnap 章節</link>
+ 中有相關介紹,初學者可以看看。</para>
+
+ <procedure>
+ <step>
+ <para>首先,先建立唯讀的目錄結構給 jail 放 &os; binary,
+ 接著到 &os; source tree 目錄,並安裝 jail 模版:</para>
+
+ <screen>&prompt.root; <userinput>mkdir -p /home/j/mroot</userinput>
+&prompt.root; <userinput>cd /usr/src</userinput>
+&prompt.root; <userinput>make installworld DESTDIR=/home/j/mroot</userinput></screen>
+ </step>
+ <step>
+ <para>接著跟 &os; source tree 一樣,也把 &os; Ports Collection
+ 放一份供 jail 使用,以備 <application>mergemaster</application>
+ :</para>
+
+ <screen>&prompt.root; <userinput>cd /home/j/mroot</userinput>
+&prompt.root; <userinput>mkdir usr/ports</userinput>
+&prompt.root; <userinput>portsnap -p /home/j/mroot/usr/ports fetch extract</userinput>
+&prompt.root; <userinput>cpdup /usr/src /home/j/mroot/usr/src</userinput></screen>
+ </step>
+ <step>
+ <para>建立可讀寫部分的骨架:</para>
+
+ <screen>&prompt.root; <userinput>mkdir /home/j/skel /home/j/skel/home /home/j/skel/usr-X11R6 /home/j/skel/distfiles</userinput>
+&prompt.root; <userinput>mv etc /home/j/skel</userinput>
+&prompt.root; <userinput>mv usr/local /home/j/skel/usr-local</userinput>
+&prompt.root; <userinput>mv tmp /home/j/skel</userinput>
+&prompt.root; <userinput>mv var /home/j/skel</userinput>
+&prompt.root; <userinput>mv root /home/j/skel</userinput></screen>
+ </step>
+ <step>
+ <para>用 <application>mergemaster</application> 來裝漏掉的設定檔。
+ 接下來刪除 <application>mergemaster</application>
+ 所建立的多餘目錄:</para>
+
+ <screen>&prompt.root; <userinput>mergemaster -t /home/j/skel/var/tmp/temproot -D /home/j/skel -i</userinput>
+&prompt.root; <userinput>cd /home/j/skel</userinput>
+&prompt.root; <userinput>rm -R bin boot lib libexec mnt proc rescue sbin sys usr dev</userinput></screen>
+ </step>
+ <step>
+ <para>現在把可讀寫的檔案系統以 symlink 方式連到唯讀的檔案系統。
+ 請確認 symbolic link 是否有正確連到 <filename>s/</filename> 目錄,若目錄建立方式不對,
+ 或指向位置不對,可能會導致安裝失敗。</para>
+
+ <screen>&prompt.root; <userinput>cd /home/j/mroot</userinput>
+&prompt.root; <userinput>mkdir s</userinput>
+&prompt.root; <userinput>ln -s s/etc etc</userinput>
+&prompt.root; <userinput>ln -s s/home home</userinput>
+&prompt.root; <userinput>ln -s s/root root</userinput>
+&prompt.root; <userinput>ln -s ../s/usr-local usr/local</userinput>
+&prompt.root; <userinput>ln -s ../s/usr-X11R6 usr/X11R6</userinput>
+&prompt.root; <userinput>ln -s ../../s/distfiles usr/ports/distfiles</userinput>
+&prompt.root; <userinput>ln -s s/tmp tmp</userinput>
+&prompt.root; <userinput>ln -s s/var var</userinput></screen>
+ </step>
+ <step>
+ <para>最後則是新增 <filename>/home/j/skel/etc/make.conf</filename>
+ ,並填入以下內容:</para>
+
+ <programlisting>WRKDIRPREFIX?= /s/portbuild</programlisting>
+
+
+ <para>要設定 <literal>WRKDIRPREFIX</literal> 才可以讓各 jail
+ 得以順利編譯 &os; ports。請記住 ports 目錄是屬唯讀檔案系統。
+ 而搭配自訂的 <literal>WRKDIRPREFIX</literal> 才可以讓各 jail
+ 在可讀寫空間進行編譯。</para>
+ </step>
+ </procedure>
+ </sect3>
+
+ <sect3 xml:id="jails-service-jails-creating">
+ <title>建立 Jail</title>
+
+ <para>現在已經有完整的 &os; jail 模版,可以在
+ <filename>/etc/rc.conf</filename> 內做相關設定。
+ 下面這例子則示範如何建立 3 個 jail:<quote>NS</quote>、
+ <quote>MAIL</quote>、<quote>WWW</quote>。</para>
+
+ <procedure>
+ <step>
+ <para>在 <filename>/etc/fstab</filename> 加上下列設定,
+ 以便讓系統自動掛載各 jail 所需的唯讀模版與讀寫空間:</para>
+
+ <programlisting>/home/j/mroot /home/j/ns nullfs ro 0 0
+/home/j/mroot /home/j/mail nullfs ro 0 0
+/home/j/mroot /home/j/www nullfs ro 0 0
+/home/js/ns /home/j/ns/s nullfs rw 0 0
+/home/js/mail /home/j/mail/s nullfs rw 0 0
+/home/js/www /home/j/www/s nullfs rw 0 0</programlisting>
+
+ <note>
+ <para>分割區的 pass number 標示為 0 就不會在開機時做 &man.fsck.8;
+ 檢查;而分割區的 dump number 標示為 0 則不會被 &man.dump.8;
+ 所備份。
+ 我們並不希望
+ <application>fsck</application> 檢查
+ <application>nullfs</application> 的掛載,或者讓
+ <application>dump</application> 備份 jail 內唯讀的 nullfs 掛載。
+ 這也就是為何上述 <filename>fstab</filename>
+ 每行設定後面都有兩欄為 <quote>0&nbsp;0</quote>。</para>
+ </note>
+ </step>
+ <step>
+ <para>在 <filename>/etc/rc.conf</filename> 內設定 jail:</para>
+
+ <programlisting>jail_enable="YES"
+jail_set_hostname_allow="NO"
+jail_list="ns mail www"
+jail_ns_hostname="ns.example.org"
+jail_ns_ip="192.168.3.17"
+jail_ns_rootdir="/usr/home/j/ns"
+jail_ns_devfs_enable="YES"
+jail_mail_hostname="mail.example.org"
+jail_mail_ip="192.168.3.18"
+jail_mail_rootdir="/usr/home/j/mail"
+jail_mail_devfs_enable="YES"
+jail_www_hostname="www.example.org"
+jail_www_ip="62.123.43.14"
+jail_www_rootdir="/usr/home/j/www"
+jail_www_devfs_enable="YES"</programlisting>
+
+ <warning>
+ <para>之所以要把
+ <varname>jail_<replaceable>name</replaceable>_rootdir</varname>
+ 從 <filename>/home</filename> 改為 <filename>/usr/home</filename> 的原因在於 &os;
+ 預設安裝的 <filename>/home</filename> 目錄其實只是指向 <filename>/usr/home</filename> 的 symbolic link。 而
+ <varname>jail_<replaceable>name</replaceable>_rootdir</varname>
+ 變數須為 <emphasis>實體目錄</emphasis> 而非 symbolic link,
+ 否則 jail 會拒絕啟動。 可以用 &man.realpath.1;
+ 來決定該變數。 詳情請參閱 &os;-SA-07:01.jail 安全通告。</para>
+ </warning>
+ </step>
+ <step>
+ <para>替每個 jail 建立必須的唯讀檔案系統掛載點:</para>
+
+ <screen>&prompt.root; <userinput>mkdir /home/j/ns /home/j/mail /home/j/www</userinput></screen>
+ </step>
+ <step>
+ <para>為每個 jail 安裝可讀寫的模版。 請注意這時要用 <package>sysutils/cpdup</package>
+ ,它能確保每個目錄都有正確複製。</para>
+ <!-- keramida: Why is cpdup required here? Doesn't cpio(1)
+ already include adequate functionality for performing this
+ job *and* have the advantage of being part of the base
+ system of FreeBSD? -->
+
+ <screen>&prompt.root; <userinput>mkdir /home/js</userinput>
+&prompt.root; <userinput>cpdup /home/j/skel /home/js/ns</userinput>
+&prompt.root; <userinput>cpdup /home/j/skel /home/js/mail</userinput>
+&prompt.root; <userinput>cpdup /home/j/skel /home/js/www</userinput></screen>
+ </step>
+ <step>
+ <para>如此一來就已完成 jail 環境建立,可以準備好要用了。
+ 請先為各 jail 掛載所須的檔案系統,再用
+ <filename>/etc/rc.d/jail</filename> script 來啟動:</para>
+
+ <screen>&prompt.root; <userinput>mount -a</userinput>
+&prompt.root; <userinput>/etc/rc.d/jail start</userinput></screen>
+ </step>
+ </procedure>
+
+ <para>現在 jail 應該就會啟動了。 若要檢查是否有正常啟動,可以用
+ &man.jls.8; 指令來看,該指令的執行結果應該類似下面:</para>
+
+ <screen>&prompt.root; <userinput>jls</userinput>
+ JID IP Address Hostname Path
+ 3 192.168.3.17 ns.example.org /home/j/ns
+ 2 192.168.3.18 mail.example.org /home/j/mail
+ 1 62.123.43.14 www.example.org /home/j/www</screen>
+
+ <para>此時就可以登入各 jail 並新增帳號與設定相關 service 要用的 daemon
+ 。 上面的 <literal>JID</literal> 欄代表正在運作中的 jail 編號。
+ 可用下列指令以在 <literal>JID</literal> 編號 3 的 jail
+ 執行管理工作:</para>
+
+ <screen>&prompt.root; <userinput>jexec 3 tcsh</userinput></screen>
+ </sect3>
+
+ <sect3 xml:id="jails-service-jails-upgrading">
+ <title>升級</title>
+
+ <para>有時由於安全問題或者 jail 內要用新功能,而需要把 &os;
+ 系統升級到更新。 這種安裝設計方式讓既有的 jail 升級變得更加容易。
+ jail 也可以把 service 停機時間(downtime)降到最低,因為 jail
+ 只需在最後關鍵才需要重開。 此外,萬一新版有問題的話,
+ 它也提供輕鬆回溯到舊版的功能。</para>
+
+ <procedure>
+ <step>
+ <para>首先是照一般方式來升級 host system,再新增臨時的唯讀模版
+ <filename>/home/j/mroot2</filename>:</para>
+
+ <screen>&prompt.root; <userinput>mkdir /home/j/mroot2</userinput>
+&prompt.root; <userinput>cd /usr/src</userinput>
+&prompt.root; <userinput>make installworld DESTDIR=/home/j/mroot2</userinput>
+&prompt.root; <userinput>cd /home/j/mroot2</userinput>
+&prompt.root; <userinput>cpdup /usr/src usr/src</userinput>
+&prompt.root; <userinput>mkdir s</userinput></screen>
+
+ <para>同樣地,在執行 <buildtarget>installworld</buildtarget>
+ 時會建立一些用不著的目錄,請把這些砍掉:</para>
+
+ <screen>&prompt.root; <userinput>chflags -R 0 var</userinput>
+&prompt.root; <userinput>rm -R etc var root usr/local tmp</userinput></screen>
+ </step>
+ <step>
+ <para>重新建立到主系統的可讀寫空間 symlink:</para>
+
+ <screen>&prompt.root; <userinput>ln -s s/etc etc</userinput>
+&prompt.root; <userinput>ln -s s/root root</userinput>
+&prompt.root; <userinput>ln -s s/home home</userinput>
+&prompt.root; <userinput>ln -s ../s/usr-local usr/local</userinput>
+&prompt.root; <userinput>ln -s ../s/usr-X11R6 usr/X11R6</userinput>
+&prompt.root; <userinput>ln -s s/tmp tmp</userinput>
+&prompt.root; <userinput>ln -s s/var var</userinput></screen>
+ </step>
+ <step>
+ <para>現在可以關閉 jail:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/jail stop</userinput></screen>
+ </step>
+ <step>
+ <para>卸載原先的檔案系統:</para>
+ <!-- keramida: Shouldn't we suggest a short script-based
+ loop here, instead of tediously copying the same commands
+ multiple times? -->
+
+ <screen>&prompt.root; <userinput>umount /home/j/ns/s</userinput>
+&prompt.root; <userinput>umount /home/j/ns</userinput>
+&prompt.root; <userinput>umount /home/j/mail/s</userinput>
+&prompt.root; <userinput>umount /home/j/mail</userinput>
+&prompt.root; <userinput>umount /home/j/www/s</userinput>
+&prompt.root; <userinput>umount /home/j/www</userinput></screen>
+
+ <note>
+ <para>可讀寫空間(<filename>/s</filename>)
+ 是掛載在唯讀檔案系統底下,故要先卸載。</para>
+ </note>
+ </step>
+ <step>
+ <para>把舊的唯讀系統搬走,換成新的。 如此一來,
+ 可同時保留先前系統的備份,以備萬一升級後有問題可回復。
+ 這邊的命名方式採新唯讀檔案系統的建立時間,此外原先 &os;
+ Ports Collection 直接搬到新的檔案系統,以節省硬碟空間與 inode
+ :</para>
+
+ <screen>&prompt.root; <userinput>cd /home/j</userinput>
+&prompt.root; <userinput>mv mroot mroot.20060601</userinput>
+&prompt.root; <userinput>mv mroot2 mroot</userinput>
+&prompt.root; <userinput>mv mroot.20060601/usr/ports mroot/usr</userinput></screen>
+ </step>
+ <step>
+ <para>現在新的唯讀模版準備好了,只剩下重新掛載以及啟動 jail:</para>
+
+ <screen>&prompt.root; <userinput>mount -a</userinput>
+&prompt.root; <userinput>/etc/rc.d/jail start</userinput></screen>
+ </step>
+ </procedure>
+
+ <para>最後以 &man.jls.8; 來檢查 jail 是否均正常啟動。
+ 別忘了要在各 jail 內執行 mergemaster,還有相關設定檔以及
+ rc.d scripts 均要更新。</para>
+ </sect3>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/kernelconfig/Makefile b/zh_TW.UTF-8/books/handbook/kernelconfig/Makefile
new file mode 100644
index 0000000000..e2c2e5cdf0
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/kernelconfig/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= kernelconfig/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/kernelconfig/chapter.xml b/zh_TW.UTF-8/books/handbook/kernelconfig/chapter.xml
new file mode 100644
index 0000000000..1ed22cf6e4
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/kernelconfig/chapter.xml
@@ -0,0 +1,1387 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.180
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="kernelconfig">
+ <info><title>設定 FreeBSD Kernel</title>
+ <authorgroup>
+ <author><personname><firstname>Jim</firstname><surname>Mock</surname></personname><contrib>更新、重排:</contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Jake</firstname><surname>Hamby</surname></personname><contrib> 原作為:</contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="kernelconfig-synopsis">
+ <title>概述</title>
+
+ <indexterm>
+ <primary>kernel</primary>
+ <secondary>building a custom kernel</secondary>
+ </indexterm>
+
+ <para>kernel 是整個 &os; 作業系統的核心。
+ 它控制了系統的整體運作,包含和記憶體管理、安全控管、網路、硬碟存取等等。
+ 儘管目前 &os; 大多可以用動態 module 來載入、卸載所需功能,
+ 但有時候仍有必要學會重新調配 kernel。</para>
+
+ <para>讀完這章,您將了解︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>為何需要重新調配、編譯 kernel?</para>
+ </listitem>
+
+ <listitem>
+ <para>要怎麼修改 kernel 設定檔?</para>
+ </listitem>
+
+ <listitem>
+ <para>如何以 kernel 設定檔來建立、編譯新的 kernel 呢?</para>
+ </listitem>
+
+ <listitem>
+ <para>如何安裝新的 kernel。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何處理 kernel 錯誤無法開機的情形。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>本章所舉例的相關指令都是以 <systemitem class="username">root</systemitem> 權限來進行。</para>
+ </sect1>
+
+ <sect1 xml:id="kernelconfig-custom-kernel">
+ <title>為何需要重新調配、編譯 kernel?</title>
+
+ <para>早期的 &os; 的 kernel 被戲稱為 <quote>monolithic</quote> kernel。
+ 這意思是說當時的 kernel 是個大塊頭程式,且只支援固定的硬體而已。
+ 如果您想改變 kernel 的設定,那麼必須編譯一個新的並重新開機,才能啟用。</para>
+
+ <para>現在的 &os; 已快速成長到新型態的管理模式,其重要特色是:
+ kernel 功能可以隨時依據需求,
+ 而以動態載入或卸載相關的 kernel module。
+ 這使得 kernel 能夠快速因應新的環境而作調整
+ (有點像是:筆記型電腦上的 PCMCIA 卡一樣即插即用)
+ ,或是增加其他原本的預設 kernel(<filename>GENERIC</filename>)所沒有的功能。
+ 這種模式,就叫做 modular kernel(核心模組)。</para>
+
+ <para>儘管如此,還是有一些功能仍須編譯在 kernel 內才行。因為有時候是因為這些功能與 kernel
+ 結合的相當複雜緊密,而無法將它們弄成可動態載入的 module
+ ;而有時候,則是因為沒有人有空來弄那些 kernel module 的實作。</para>
+
+ <para>重新調配、編譯 kernel 幾乎是每位 BSD 使用者所必須經歷的過程。
+ 儘管這項工作可能比較耗時,但在 &os; 的使用上會有許多好處。
+ 跟必須支援大多數各式硬體的 <filename>GENERIC</filename> kernel 相比的話,
+ 自行調配 kernel 不同處在於:可以更『體貼』,只支援『自己硬體』的部分就好。
+ 好處在於,譬如︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>開機速度更快:因為自行調配的 kernel 只需要偵測您系統上的硬體,
+ 所以讓啟動所花的過程更流暢快速。</para>
+ </listitem>
+
+ <listitem>
+ <para>佔用的記憶體更少:自行調配的 kernel 通常會比
+ <filename>GENERIC</filename> 核心使用更少的記憶體,由於 kernel
+ 必須一直存放在記憶體內,因此這就顯得更加重要。因此,
+ 對於記憶體較小的系統來說,
+ 自行調配的 kernel 就可發揮更多的作用、揮灑空間。</para>
+ </listitem>
+
+ <listitem>
+ <para>可支援更多硬體:您可在自行調配的 kernel 增加一些原本
+ <filename>GENERIC</filename> 核心沒有提供的硬體支援,像是音效卡之類的。</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="kernelconfig-devices">
+ <info><title>探測系統硬體</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <para>在進行 kernel 設定的探索之旅前,
+ 先把該機器各項硬體資訊作點調查會是明智之舉。
+ 若 &os; 並非主要的作業系統,那麼也可以輕鬆透過目前所使用的作業系統,
+ 來查看相關硬體資訊表。 舉例來說,&microsoft; 的
+ <application>裝置管理員(Device Manager)</application>
+ 內通常會有目前有裝的硬體資訊。 而 <application>裝置管理員</application>
+ 是在控制台。</para>
+
+ <note>
+ <para>&microsoft.windows; 某些版本則是先透過
+ <application>系統(System)</application> 再進入
+ <application>裝置管理員</application>。</para>
+ </note>
+
+ <para>若該機器尚未安裝任何作業系統,那麼就要親自找出相關硬體資訊。
+ 其中一種方式是透過 &man.dmesg.8; 以及 &man.man.1;。 &os;
+ 上大多硬體都會有相關的 man 說明有支援的規格型號,
+ 並且開機的偵測過程中,也會列出有找到的硬體。 舉個例子,
+ 下面這幾行是說有偵測到滑鼠,並且是以 <filename>psm</filename>
+ 驅動程式:</para>
+
+ <programlisting>psm0: &lt;PS/2 Mouse&gt; irq 12 on atkbdc0
+psm0: [GIANT-LOCKED]
+psm0: [ITHREAD]
+psm0: model Generic PS/2 mouse, device ID 0</programlisting>
+
+ <para>驅動程式必須要在自訂的 kernel 設定檔內加入,或者是用
+ &man.loader.conf.5;。</para>
+
+ <para><command>dmesg</command> 有時只顯示系統訊息而沒有開機偵測的部份,
+ 遇到這種情況請查閱 <filename>/var/run/dmesg.boot</filename> 檔。</para>
+
+ <para>另外也可以透過 &man.pciconf.8; 來列出更詳細的相關資訊。
+ 舉例說明:</para>
+
+ <programlisting>ath0@pci0:3:0:0: class=0x020000 card=0x058a1014 chip=0x1014168c rev=0x01 hdr=0x00
+ vendor = 'Atheros Communications Inc.'
+ device = 'AR5212 Atheros AR5212 802.11abg wireless'
+ class = network
+ subclass = ethernet</programlisting>
+
+ <para>上面顯示是透過 <command>pciconf -lv</command>
+ 所看到的 <filename>ath</filename> 無線網卡驅動程式。 可以用
+ <command>man ath</command> 來查看
+ &man.ath.4; 的相關說明。</para>
+
+ <para>在使用 &man.man.1; 時,加上 <option>-k</option>
+ 參數也可以提供比較精準的資訊。 以上述例子而言,可以改為打:</para>
+
+ <screen>&prompt.root; man -k <replaceable>Atheros</replaceable></screen>
+
+ <para>就會列出有含上述關鍵字的相關 man 說明:</para>
+
+ <programlisting>ath(4) - Atheros IEEE 802.11 wireless network driver
+ath_hal(4) - Atheros Hardware Access Layer (HAL)</programlisting>
+
+ <para>知己知彼,先瞭解相關硬體環境,才能讓接下來的自訂 kernel
+ 打造過程更為順利。</para>
+ </sect1>
+
+ <sect1 xml:id="kernelconfig-building">
+ <title>重新調配、編譯 kernel</title>
+ <indexterm>
+ <primary>kernel</primary>
+ <secondary>building / installing</secondary>
+ </indexterm>
+
+ <para>首先對 kernel 相關目錄作快速介紹。
+ 這裡所提到的所有目錄都在 <filename>/usr/src/sys</filename> 內,
+ 也可以用 <filename>/sys</filename> 這個 symbolic link 來連到這。
+ 這裡的許多子目錄分別擺放 kernel 的各組成部分,但對打造 kernel
+ 影響最重要的目錄是
+ <filename>arch/conf</filename>,
+ 這裡是可以針對需求來修改自訂 kernel 相關設定。
+ 此外,還有在編譯 kernel 過程中會暫時擺放的 <filename>compile</filename>
+ 目錄。
+ 剛講到的 <replaceable>arch</replaceable> 可以是右列架構之一:
+ <filename>i386</filename>、<filename>alpha</filename>、
+ <filename>amd64</filename>、<filename>ia64</filename>、
+ <filename>powerpc</filename>、<filename>sparc64</filename>、
+ <filename>pc98</filename>(在日本較流行的另一種 PC 硬體架構)。
+ 在各特定硬體架構目錄的東西,只搭配相對應的硬體架構而已。
+ 而其餘的原始碼則是與硬體架構無關,可以在所有 &os; 可裝的平台上共用。
+ 整體目錄架構都是有邏輯可循,像是各項有支援的硬體設備、檔案系統,
+ 以及相關選項通常都會擺在它們自己的子目錄內。</para>
+
+ <para>本章所用到的例子,都是你使用 i386 架構的機器。
+ 請依實際情況,對相關目錄作調整即可。</para>
+
+ <note>
+ <para>若您系統上 <emphasis>沒裝</emphasis>
+ <filename>/usr/src/sys</filename> 目錄,
+ 也就是說沒裝 kernel source code 的話,那麼最簡單安裝方式就是以
+ <systemitem class="username">root</systemitem> 權限來執行 <command>sysinstall</command>,
+ 接著請選 <guimenuitem>Configure</guimenuitem>,然後選
+ <guimenuitem>Distributions</guimenuitem> 接著為
+ <guimenuitem>src</guimenuitem> 再選
+ <guimenuitem>base</guimenuitem> 最後選
+ <guimenuitem>sys</guimenuitem>。 若不喜歡用
+ <application>sysinstall</application> 而且手邊有
+ <quote>正式的</quote> &os; 光碟可以用的話,
+ 那麼也可以用以下指令來安裝:</para>
+
+ <screen>&prompt.root; <userinput>mount /cdrom</userinput>
+&prompt.root; <userinput>mkdir -p /usr/src/sys</userinput>
+&prompt.root; <userinput>ln -s /usr/src/sys /sys</userinput>
+&prompt.root; <userinput>cat /cdrom/src/ssys.[a-d]* | tar -xzvf -</userinput>
+&prompt.root; <userinput>cat /cdrom/src/sbase.[a-d]* | tar -xzvf -</userinput></screen>
+ </note>
+
+ <para>接下來,切換到
+ <filename>arch/conf</filename> 目錄,
+ 複製 <filename>GENERIC</filename> 設定檔為你想稱呼的新 kernel 名稱。
+ 例如:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src/sys/i386/conf</userinput>
+&prompt.root; <userinput>cp GENERIC MYKERNEL</userinput></screen>
+
+ <para>通常,命名方式都是大寫。如果你負責維護許多不同硬體架構的 &os;
+ 機器的話,那麼照該機器名稱(hostname)來命名會是比較明智。
+ 上面例子中之所以命名為 <filename>MYKERNEL</filename>
+ 就是因為這緣故。</para>
+
+ <tip>
+ <para>建議不要把改過的 kernel 設定檔直接放在
+ <filename>/usr/src</filename>。 因為若編譯遇到其他問題時,
+ 直接砍掉 <filename>/usr/src</filename> 再重練,
+ 可能會是比較乾脆的選擇之一。
+ 一旦真的砍了之後,你可能幾秒之後才會醒悟到:
+ 你同時也砍掉自己改的 kernel 設定檔。
+ 此外,也不要直接修改 <filename>GENERIC</filename>,因為下次你
+ <link linkend="cutting-edge">更新 source tree</link>時,
+ 它會被新版覆蓋,而相關修改也將隨之而逝。</para>
+
+ <para>你也可考慮把 kernel 設定檔改放到其他地方,然後再到
+ <filename>i386</filename>
+ 目錄內建個指向它的 symbolic link。</para>
+
+ <para>舉例:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src/sys/i386/conf</userinput>
+&prompt.root; <userinput>mkdir /root/kernels</userinput>
+&prompt.root; <userinput>cp GENERIC /root/kernels/MYKERNEL</userinput>
+&prompt.root; <userinput>ln -s /root/kernels/MYKERNEL</userinput></screen>
+ </tip>
+
+ <para>現在,就開始用自己喜歡的編輯器來修改 <filename>MYKERNEL</filename>。
+ 若才剛裝好 FreeBSD 而已,唯一可用的編輯器很可能是
+ <application>vi</application> 了,由於它的用法很多種,礙於篇幅將不詳細介紹,
+ 你可在 <link linkend="bibliography">參考書目</link> 內找到相關書籍。
+ 不過,&os; 也提供另一個更好用的編輯器,它叫做
+ <application>ee</application>,對新手而言,這可能是蠻好的選擇。
+ 你可以任意修改檔案內的相關註解以說明相關設定為何,
+ 或者其他想改的 <filename>GENERIC</filename> 設定內容。</para>
+ <indexterm><primary>SunOS</primary></indexterm>
+
+ <para>若你有在 &sunos; 或者其他種 BSD 作業系統下進行編譯 kernel 的經驗,
+ 那麼應該已經很熟悉本篇所介紹的大部分步驟。
+ 換句話說,若您之前用的是 DOS 這類作業系統,那麼
+ <filename>GENERIC</filename> 設定檔的內容就可能比較難懂些,沒關係,
+ 我們將在下面的 <link linkend="kernelconfig-config">kernel 設定</link>
+ 會循序漸進地介紹。</para>
+
+ <note>
+ <para>若有從 &os; 計劃去 <link linkend="cutting-edge">更新你的 source tree</link> 的話,
+ 則切記在進行任何升級之前,務必要察看
+ <filename>/usr/src/UPDATING</filename>。
+ 這檔會介紹在更新過程中的重大議題或要注意的事項。
+ 由於 <filename>/usr/src/UPDATING</filename> 是對應於你機器上目前的
+ &os; source code 版本,因此會提供比本手冊更新的內容。</para>
+ </note>
+
+ <para>現在開始來編譯 kernel 吧。</para>
+
+ <procedure>
+ <title>編譯 Kernel</title>
+
+ <step>
+ <para>請切換至 <filename>/usr/src</filename> 目錄:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src</userinput></screen>
+ </step>
+
+ <step>
+ <para>編譯 kernel:</para>
+
+ <screen>&prompt.root; <userinput>make buildkernel KERNCONF=MYKERNEL</userinput></screen>
+ </step>
+
+ <step>
+ <para>安裝新 kernel:</para>
+
+ <screen>&prompt.root; <userinput>make installkernel KERNCONF=MYKERNEL</userinput></screen>
+ </step>
+ </procedure>
+
+ <note>
+ <para>要有完整的 &os; source tree 才能編譯 kernel。</para>
+ </note>
+
+ <tip>
+ <para>預設情況下,在編譯自訂 kernel 時,<emphasis>全部的</emphasis>
+ kernel modules 也會一起重編。 若要快速升級 kernel,
+ 或是只想重編所需的 kernel module,那麼在編譯 kernel 前要先改一下
+ <filename>/etc/make.conf</filename>,比如:</para>
+
+ <programlisting>MODULES_OVERRIDE = linux acpi sound/sound sound/driver/ds1 ntfs</programlisting>
+
+ <para>上面該設定值為所希望重編的 kernel module 列表。</para>
+
+ <programlisting>WITHOUT_MODULES = linux acpi sound/sound sound/driver/ds1 ntfs</programlisting>
+
+ <para>而上面這設定值則為不要編入的 kernel module 列表。 若想更瞭解其他
+ kernel 編譯的相關變數,請參閱 &man.make.conf.5; 說明。</para>
+ </tip>
+
+ <indexterm>
+ <primary><filename>/boot/kernel.old</filename></primary>
+ </indexterm>
+
+ <para>新的 kernel 會複製到 <filename>/boot/kernel</filename> 目錄內的
+ <filename>/boot/kernel/kernel</filename>,而舊的則移至
+ <filename>/boot/kernel.old/kernel</filename>。
+ 現在呢,先關機,然後就會以新 kernel 重開機
+ 若有問題的話,本章後面會介紹一些<link linkend="kernelconfig-trouble">疑難雜症</link>來協助你。
+ 若新 kernel 無法開機的話,請參閱 <link linkend="kernelconfig-noboot">這裡</link> 以恢復系統運作。</para>
+
+ <note>
+ <para>至於開機過程的其他相關檔案、設定,比如 &man.loader.8;
+ 及其設定,則放在 <filename>/boot</filename>。
+ Third party 或自訂的 kernel modules 則會放在
+ <filename>/boot/kernel</filename>,不過,
+ 應注意要保持 kernel module 與 kernel 是否有同步,
+ 這點很重要,否則會導致不穩或出問題。</para>
+ </note>
+ </sect1>
+
+ <sect1 xml:id="kernelconfig-config">
+ <info><title>kernel 設定檔解說</title>
+ <authorgroup>
+ <author><personname><firstname>Joel</firstname><surname>Dahl</surname></personname><contrib>Updated for &os; 6.X by </contrib></author>
+ </authorgroup>
+ </info>
+
+ <indexterm>
+ <primary>kernel</primary>
+ <secondary>NOTES</secondary>
+ </indexterm>
+ <indexterm><primary>NOTES</primary></indexterm>
+ <indexterm>
+ <primary>kernel</primary>
+ <secondary>configuration file</secondary>
+ </indexterm>
+
+ <para>kernel 設定檔的內容格式相當簡單。
+ 每一行都包括一個關鍵字,以及一個或多個參數。事實上,
+ 很多行大多只有一個參數。任何以 <literal>#</literal>
+ 開頭的敘述都將被視為註解而被忽略。
+ 接下來將以在 <filename>GENERIC</filename> 所出現的順序一一介紹之。
+ <anchor xml:id="kernelconfig-options"/>若要看與該平台架構有關的各選項、設備列表,
+ 請參閱與 <filename>GENERIC</filename> 檔同目錄的 <filename>NOTES</filename>
+ 檔。 而與平台架構差異較無關的通用部份,則可參閱
+ <filename>/usr/src/sys/conf/NOTES</filename>。</para>
+
+ <note>
+ <para>若為了測試,而需要一份含有所有可用設定的設定檔,那麼請以
+ <systemitem class="username">root</systemitem> 身份下:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src/sys/i386/conf &amp;&amp; make LINT</userinput></screen>
+ </note>
+
+ <indexterm>
+ <primary>kernel</primary>
+ <secondary>configuration file</secondary>
+ </indexterm>
+
+ <para>下面為 <filename>GENERIC</filename> 設定檔的範例,
+ 其中包括說明用的註釋。 這例子應該與您機器上的
+ <filename>/usr/src/sys/i386/conf/GENERIC</filename>
+ 相當接近。</para>
+
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>machine</secondary>
+ </indexterm>
+
+ <programlisting>machine i386</programlisting>
+
+ <para>此處是指機器架構,必須為
+ <literal>alpha</literal>、<literal>amd64</literal>、
+ <literal>i386</literal>、<literal>ia64</literal>、
+ <literal>pc98</literal>、<literal>powerpc</literal>、
+ <literal>sparc64</literal> 其中之一。</para>
+
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>cpu</secondary>
+ </indexterm>
+ <programlisting>cpu I486_CPU
+cpu I586_CPU
+cpu I686_CPU</programlisting>
+
+ <para>上面設定是指定要用哪一種 CPU 型號。 也可以同時加上多組 CPU 型號
+ (比如說萬一不確定是否要用 <literal>I586_CPU</literal> 或
+ <literal>I686_CPU</literal>)。 然而自訂 kernel 的話,建議先確認自己的
+ CPU 型號,然後只用最適合的那組就好了。 若不確定 CPU 到底是用哪一種,
+ 可以查閱 <filename>/var/run/dmesg.boot</filename>
+ 的開機訊息以確定。</para>
+
+ <indexterm>
+ <primary>kernel options</primary>
+
+ <secondary>ident</secondary>
+ </indexterm>
+
+ <programlisting>ident GENERIC</programlisting>
+
+ <para>這是設定該 kernel 名稱為何,可以隨意命名之,像是取名為
+ <literal>MYKERNEL</literal>,若是有照先前說明來作大概會取這樣名字。
+ <literal>ident</literal> 後面的字串會在開機時顯示,因此若要辨認新 kernel
+ 與常用 kernel 的話,就設定不同組名稱即可(比如在自訂實驗用的
+ kernel)。</para>
+
+ <programlisting>#To statically compile in device wiring instead of /boot/device.hints
+#hints "GENERIC.hints" # Default places to look for devices.</programlisting>
+
+ <para>&man.device.hints.5; 可用來設定各項驅動程式的選項。
+ 開機時 &man.loader.8; 會檢查預設的 <filename>/boot/device.hints</filename>
+ 設定檔。 使用 <literal>hints</literal> 選項,就可以把這些 hints
+ 靜態編入 kernel 內。 如此一來就不必在 <filename>/boot</filename>
+ 內建立 <filename>device.hints</filename> 檔。</para>
+
+ <!-- XXX: Add a comment here that explains when compiling hints into
+ the kernel is a good idea and why. -->
+
+ <programlisting>makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols</programlisting>
+
+ <para>加上 <option>-g</option> 選項的話,&os; 會在編譯過程加上 debug
+ 用的資訊,透過這選項會讓 &man.gcc.1; 啟用 debug
+ 所會用到的相關資訊。</para>
+
+ <programlisting>options SCHED_4BSD # 4BSD scheduler</programlisting>
+
+ <para>&os;. 傳統所用(並且是預設)的系統 CPU scheduler。 若您不清楚要如何設定
+ ,請保留這設定。</para>
+
+ <programlisting>options PREEMPTION # Enable kernel thread preemption</programlisting>
+
+ <para>Allows threads that are in the kernel to be preempted
+ by higher priority threads. It helps with interactivity and
+ allows interrupt threads to run sooner rather than waiting.</para>
+
+ <programlisting>options INET # InterNETworking</programlisting>
+
+ <para>Networking support. Leave this in, even if you do not plan to
+ be connected to a network. Most programs require at least loopback
+ networking (i.e., making network connections within your PC), so
+ this is essentially mandatory.</para>
+
+ <programlisting>options INET6 # IPv6 communications protocols</programlisting>
+
+ <para>This enables the IPv6 communication protocols.</para>
+
+ <programlisting>options FFS # Berkeley Fast Filesystem</programlisting>
+
+ <para>This is the basic hard drive file system. Leave it in if you
+ boot from the hard disk.</para>
+
+ <programlisting>options SOFTUPDATES # Enable FFS Soft Updates support</programlisting>
+
+ <para>This option enables Soft Updates in the kernel, this will
+ help speed up write access on the disks. Even when this
+ functionality is provided by the kernel, it must be turned on
+ for specific disks. Review the output from &man.mount.8; to see
+ if Soft Updates is enabled for your system disks. If you do not
+ see the <literal>soft-updates</literal> option then you will
+ need to activate it using the &man.tunefs.8; (for existing
+ file systems) or &man.newfs.8; (for new file systems)
+ commands.</para>
+
+ <programlisting>options UFS_ACL # Support for access control lists</programlisting>
+
+ <para>This option enables kernel support
+ for access control lists. This relies on the use of extended
+ attributes and <acronym>UFS2</acronym>, and the feature is described
+ in detail in <xref linkend="fs-acl"/>. <acronym>ACL</acronym>s are
+ enabled by default and should not be
+ disabled in the kernel if they have been used previously on a file
+ system, as this will remove the access control lists, changing the
+ way files are protected in unpredictable ways.</para>
+
+ <programlisting>options UFS_DIRHASH # Improve performance on big directories</programlisting>
+
+ <para>This option includes functionality to speed up disk
+ operations on large directories, at the expense of using
+ additional memory. You would normally keep this for a large
+ server, or interactive workstation, and remove it if you are
+ using &os; on a smaller system where memory is at a premium and
+ disk access speed is less important, such as a firewall.</para>
+
+ <programlisting>options MD_ROOT # MD is a potential root device</programlisting>
+
+ <para>This option enables support for a memory backed virtual disk
+ used as a root device.</para>
+
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>NFS</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>NFS_ROOT</secondary>
+ </indexterm>
+ <programlisting>options NFSCLIENT # Network Filesystem Client
+options NFSSERVER # Network Filesystem Server
+options NFS_ROOT # NFS usable as /, requires NFSCLIENT</programlisting>
+
+ <para>The network file system. Unless you plan to mount partitions
+ from a &unix; file server over TCP/IP, you can comment these
+ out.</para>
+
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>MSDOSFS</secondary>
+ </indexterm>
+ <programlisting>options MSDOSFS # MSDOS Filesystem</programlisting>
+
+ <para>The &ms-dos; file system. Unless you plan to mount a DOS formatted
+ hard drive partition at boot time, you can safely comment this out.
+ It will be automatically loaded the first time you mount a DOS
+ partition, as described above. Also, the excellent
+ <package>emulators/mtools</package> software
+ allows you to access DOS floppies without having to mount and
+ unmount them (and does not require <literal>MSDOSFS</literal> at
+ all).</para>
+
+ <programlisting>options CD9660 # ISO 9660 Filesystem</programlisting>
+
+ <para>The ISO 9660 file system for CDROMs. Comment it out if you do
+ not have a CDROM drive or only mount data CDs occasionally (since it
+ will be dynamically loaded the first time you mount a data CD).
+ Audio CDs do not need this file system.</para>
+
+ <programlisting>options PROCFS # Process filesystem(requires PSEUDOFS)</programlisting>
+
+ <para>The process file system. This is a <quote>pretend</quote>
+ file system mounted on <filename>/proc</filename> which allows
+ programs like &man.ps.1; to give you more information on what
+ processes are running. Use of <literal>PROCFS</literal>
+ is not required under most circumstances, as most
+ debugging and monitoring tools have been adapted to run without
+ <literal>PROCFS</literal>: installs will not mount this file
+ system by default.</para>
+
+ <programlisting>options PSEUDOFS # Pseudo-filesystem framework</programlisting>
+
+ <para>6.X kernels making use of <literal>PROCFS</literal> must also
+ include support for <literal>PSEUDOFS</literal>.</para>
+
+ <programlisting>options GEOM_GPT # GUID Partition Tables.</programlisting>
+
+ <para>This option brings the ability to have a large number of
+ partitions on a single disk.</para>
+
+ <programlisting>options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]</programlisting>
+
+ <para>Compatibility with 4.3BSD. Leave this in; some programs will
+ act strangely if you comment this out.</para>
+
+ <programlisting>options COMPAT_FREEBSD4 # Compatible with &os;4</programlisting>
+
+ <para>This option is required on &os;&nbsp;5.X &i386; and Alpha systems
+ to support applications compiled on older versions of &os;
+ that use older system call interfaces. It is recommended that
+ this option be used on all &i386; and Alpha systems that may
+ run older applications; platforms that gained support only in
+ 5.X, such as ia64 and &sparc64;, do not require this option.</para>
+
+ <programlisting>options COMPAT_FREEBSD5 # 與 &os;5 相容</programlisting>
+
+ <para>此行是 &os;&nbsp;6.X 及更新的版本若需支援 &os;&nbsp;5.X
+ 系統呼叫才需要設定。</para>
+
+ <programlisting>options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI</programlisting>
+
+ <para>This causes the kernel to pause for 5 seconds before probing
+ each SCSI device in your system. If you only have IDE hard drives,
+ you can ignore this, otherwise you can try to lower this
+ number, to speed up booting. Of course, if
+ you do this and &os; has trouble recognizing your SCSI devices,
+ you will have to raise it again.</para>
+
+ <programlisting>options KTRACE # ktrace(1) support</programlisting>
+
+ <para>This enables kernel process tracing, which is useful in
+ debugging.</para>
+
+ <programlisting>options SYSVSHM # SYSV-style shared memory</programlisting>
+
+ <para>This option provides for System&nbsp;V shared memory. The most
+ common use of this is the XSHM extension in X, which many
+ graphics-intensive programs will automatically take advantage of for
+ extra speed. If you use X, you will definitely want to include
+ this.</para>
+
+ <programlisting>options SYSVMSG # SYSV-style message queues</programlisting>
+
+ <para>Support for System&nbsp;V messages. This option only adds
+ a few hundred bytes to the kernel.</para>
+
+ <programlisting>options SYSVSEM # SYSV-style semaphores</programlisting>
+
+ <para>Support for System&nbsp;V semaphores. Less commonly used but only
+ adds a few hundred bytes to the kernel.</para>
+
+ <note>
+ <para>The <option>-p</option> option of the &man.ipcs.1; command will
+ list any processes using each of these System&nbsp;V facilities.</para>
+ </note>
+
+ <programlisting>options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions</programlisting>
+
+ <para>Real-time extensions added in the 1993 &posix;. Certain
+ applications in the Ports Collection use these
+ (such as <application>&staroffice;</application>).</para>
+
+ <programlisting>options KBD_INSTALL_CDEV # install a CDEV entry in /dev</programlisting>
+
+ <para>This option is required to allow the creation of keyboard device
+ nodes in <filename>/dev</filename>.</para>
+
+ <programlisting>options ADAPTIVE_GIANT # Giant mutex is adaptive.</programlisting>
+
+ <para>Giant is the name of a mutual exclusion mechanism (a sleep mutex)
+ that protects a large set of kernel resources. Today, this is an
+ unacceptable performance bottleneck which is actively being replaced
+ with locks that protect individual resources. The
+ <literal>ADAPTIVE_GIANT</literal> option causes Giant to be included
+ in the set of mutexes adaptively spun on. That is, when a thread
+ wants to lock the Giant mutex, but it is already locked by a thread
+ on another CPU, the first thread will keep running and wait for the
+ lock to be released. Normally, the thread would instead go back to
+ sleep and wait for its next chance to run. If you are not sure,
+ leave this in.</para>
+
+ <note>
+ <para>Note that on &os; 8.0-CURRENT and later versions, all mutexes are
+ adaptive by default, unless explicitly set to non-adaptive by
+ compiling with the <literal>NO_ADAPTIVE_MUTEXES</literal> option. As
+ a result, Giant is adaptive by default now, and the
+ <literal>ADAPTIVE_GIANT</literal> option has been removed from the
+ kernel configuration.</para>
+ </note>
+
+
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>SMP</secondary>
+ </indexterm>
+ <programlisting>device apic # I/O APIC</programlisting>
+
+ <para>The apic device enables the use of the I/O APIC for interrupt
+ delivery. The apic device can be used in both UP and SMP kernels, but
+ is required for SMP kernels. Add <literal>options SMP</literal> to
+ include support for multiple processors.</para>
+
+ <note>
+ <para>apic 只限 i386 架構才有,其他架構則不必加上這行。</para>
+ </note>
+
+ <programlisting>device eisa</programlisting>
+
+ <para>Include this if you have an EISA motherboard. This enables
+ auto-detection and configuration support for all devices on the EISA
+ bus.</para>
+
+ <programlisting>device pci</programlisting>
+
+ <para>Include this if you have a PCI motherboard. This enables
+ auto-detection of PCI cards and gatewaying from the PCI to ISA
+ bus.</para>
+
+ <programlisting># Floppy drives
+device fdc</programlisting>
+
+ <para>This is the floppy drive controller.</para>
+
+ <programlisting># ATA and ATAPI devices
+device ata</programlisting>
+
+ <para>This driver supports all ATA and ATAPI devices. You only need
+ one <literal>device ata</literal> line for the kernel to detect all
+ PCI ATA/ATAPI devices on modern machines.</para>
+
+ <programlisting>device atadisk # ATA disk drives</programlisting>
+
+ <para>This is needed along with <literal>device ata</literal> for
+ ATA disk drives.</para>
+
+ <programlisting>device ataraid # ATA RAID drives</programlisting>
+
+ <para>This is needed along with <literal>device ata</literal> for ATA
+ RAID drives.</para>
+
+ <programlisting><anchor xml:id="kernelconfig-atapi"/>
+device atapicd # ATAPI CDROM drives</programlisting>
+
+ <para>This is needed along with <literal>device ata</literal> for
+ ATAPI CDROM drives.</para>
+
+ <programlisting>device atapifd # ATAPI floppy drives</programlisting>
+
+ <para>This is needed along with <literal>device ata</literal> for
+ ATAPI floppy drives.</para>
+
+ <programlisting>device atapist # ATAPI tape drives</programlisting>
+
+ <para>This is needed along with <literal>device ata</literal> for
+ ATAPI tape drives.</para>
+
+ <programlisting>options ATA_STATIC_ID # Static device numbering</programlisting>
+
+ <para>This makes the controller number static; without this,
+ the device numbers are dynamically allocated.</para>
+
+ <programlisting># SCSI Controllers
+device ahb # EISA AHA1742 family
+device ahc # AHA2940 and onboard AIC7xxx devices
+options AHC_REG_PRETTY_PRINT # Print register bitfields in debug
+ # output. Adds ~128k to driver.
+device ahd # AHA39320/29320 and onboard AIC79xx devices
+options AHD_REG_PRETTY_PRINT # Print register bitfields in debug
+ # output. Adds ~215k to driver.
+device amd # AMD 53C974 (Teckram DC-390(T))
+device isp # Qlogic family
+device ispfw # Firmware for QLogic HBAs- normally a module
+device mpt # LSI-Logic MPT-Fusion
+#device ncr # NCR/Symbios Logic
+device sym # NCR/Symbios Logic (newer chipsets + those of `ncr')
+device trm # Tekram DC395U/UW/F DC315U adapters
+
+device adv # Advansys SCSI adapters
+device adw # Advansys wide SCSI adapters
+device aha # Adaptec 154x SCSI adapters
+device aic # Adaptec 15[012]x SCSI adapters, AIC-6[23]60.
+device bt # Buslogic/Mylex MultiMaster SCSI adapters
+
+device ncv # NCR 53C500
+device nsp # Workbit Ninja SCSI-3
+device stg # TMC 18C30/18C50</programlisting>
+
+ <para>SCSI controllers. Comment out any you do not have in your
+ system. If you have an IDE only system, you can remove these
+ altogether. The <literal>*_REG_PRETTY_PRINT</literal> lines are
+ debugging options for their respective drivers.</para>
+
+ <programlisting># SCSI peripherals
+device scbus # SCSI bus (required for SCSI)
+device ch # SCSI media changers
+device da # Direct Access (disks)
+device sa # Sequential Access (tape etc)
+device cd # CD
+device pass # Passthrough device (direct SCSI access)
+device ses # SCSI Environmental Services (and SAF-TE)</programlisting>
+
+ <para>SCSI peripherals. Again, comment out any you do not have, or if
+ you have only IDE hardware, you can remove them completely.</para>
+
+ <note>
+ <para>The USB &man.umass.4; driver and a few other drivers use
+ the SCSI subsystem even though they are not real SCSI devices.
+ Therefore make sure not to remove SCSI support, if any such
+ drivers are included in the kernel configuration.</para>
+ </note>
+
+ <programlisting># RAID controllers interfaced to the SCSI subsystem
+device amr # AMI MegaRAID
+device arcmsr # Areca SATA II RAID
+device asr # DPT SmartRAID V, VI and Adaptec SCSI RAID
+device ciss # Compaq Smart RAID 5*
+device dpt # DPT Smartcache III, IV - See NOTES for options
+device hptmv # Highpoint RocketRAID 182x
+device rr232x # Highpoint RocketRAID 232x
+device iir # Intel Integrated RAID
+device ips # IBM (Adaptec) ServeRAID
+device mly # Mylex AcceleRAID/eXtremeRAID
+device twa # 3ware 9000 series PATA/SATA RAID
+
+# RAID controllers
+device aac # Adaptec FSA RAID
+device aacp # SCSI passthrough for aac (requires CAM)
+device ida # Compaq Smart RAID
+device mfi # LSI MegaRAID SAS
+device mlx # Mylex DAC960 family
+device pst # Promise Supertrak SX6000
+device twe # 3ware ATA RAID</programlisting>
+
+ <para>Supported RAID controllers. If you do not have any of these,
+ you can comment them out or remove them.</para>
+
+ <programlisting># atkbdc0 controls both the keyboard and the PS/2 mouse
+device atkbdc # AT keyboard controller</programlisting>
+
+ <para>The keyboard controller (<literal>atkbdc</literal>) provides I/O
+ services for the AT keyboard and PS/2 style pointing devices. This
+ controller is required by the keyboard driver
+ (<literal>atkbd</literal>) and the PS/2 pointing device driver
+ (<literal>psm</literal>).</para>
+
+ <programlisting>device atkbd # AT keyboard</programlisting>
+
+ <para>The <literal>atkbd</literal> driver, together with
+ <literal>atkbdc</literal> controller, provides access to the AT 84
+ keyboard or the AT enhanced keyboard which is connected to the AT
+ keyboard controller.</para>
+
+ <programlisting>device psm # PS/2 mouse</programlisting>
+
+ <para>Use this device if your mouse plugs into the PS/2 mouse
+ port.</para>
+
+ <programlisting>device kbdmux # keyboard multiplexer</programlisting>
+
+ <para>多重鍵盤的支援。 若不打算同時接多組鍵盤的話,
+ 那麼若要移除該行也沒關係。</para>
+
+ <programlisting>device vga # VGA video card driver</programlisting>
+
+ <para>The video card driver.</para>
+
+ <programlisting>
+device splash # Splash screen and screen saver support</programlisting>
+
+ <para>Splash screen at start up! Screen savers require this
+ too.</para>
+
+ <programlisting># syscons is the default console driver, resembling an SCO console
+device sc</programlisting>
+
+ <para><literal>sc</literal> is the default console driver and
+ resembles a SCO console. Since most full-screen programs access the
+ console through a terminal database library like
+ <filename>termcap</filename>, it should not matter whether you use
+ this or <literal>vt</literal>, the <literal>VT220</literal>
+ compatible console driver. When you log in, set your
+ <envar>TERM</envar> variable to <literal>scoansi</literal> if
+ full-screen programs have trouble running under this console.</para>
+
+ <programlisting># Enable this for the pcvt (VT220 compatible) console driver
+#device vt
+#options XSERVER # support for X server on a vt console
+#options FAT_CURSOR # start with block cursor</programlisting>
+
+ <para>This is a VT220-compatible console driver, backward compatible to
+ VT100/102. It works well on some laptops which have hardware
+ incompatibilities with <literal>sc</literal>. Also set your
+ <envar>TERM</envar> variable to <literal>vt100</literal> or
+ <literal>vt220</literal> when you log in. This driver might also
+ prove useful when connecting to a large number of different machines
+ over the network, where <filename>termcap</filename> or
+ <filename>terminfo</filename> entries for the <literal>sc</literal>
+ device are often not available &mdash; <literal>vt100</literal>
+ should be available on virtually any platform.</para>
+
+ <programlisting>device agp</programlisting>
+
+ <para>Include this if you have an AGP card in the system. This
+ will enable support for AGP, and AGP GART for boards which
+ have these features.</para>
+
+ <indexterm>
+ <primary>APM</primary>
+ </indexterm>
+
+ <programlisting># Power management support (see NOTES for more options)
+#device apm</programlisting>
+
+ <para>Advanced Power Management support. Useful for laptops,
+ although in &os; 5.X and above this is disabled in
+ <filename>GENERIC</filename> by default.</para>
+
+ <programlisting># Add suspend/resume support for the i8254.
+device pmtimer</programlisting>
+
+ <para>Timer device driver for power management events, such as APM and
+ ACPI.</para>
+
+ <programlisting># PCCARD (PCMCIA) support
+# PCMCIA and cardbus bridge support
+device cbb # cardbus (yenta) bridge
+device pccard # PC Card (16-bit) bus
+device cardbus # CardBus (32-bit) bus</programlisting>
+
+ <para>PCMCIA support. You want this if you are using a
+ laptop.</para>
+
+ <programlisting># Serial (COM) ports
+device sio # 8250, 16[45]50 based serial ports</programlisting>
+
+ <para>These are the serial ports referred to as
+ <filename>COM</filename> ports in the &ms-dos;/&windows;
+ world.</para>
+
+ <note>
+ <para>If you have an internal modem on <filename>COM4</filename>
+ and a serial port at <filename>COM2</filename>, you will have
+ to change the IRQ of the modem to 2 (for obscure technical reasons,
+ IRQ2 = IRQ 9) in order to access it
+ from &os;. If you have a multiport serial card, check the
+ manual page for &man.sio.4; for more information on the proper
+ values to add to your <filename>/boot/device.hints</filename>.
+ Some video cards (notably those based on
+ S3 chips) use IO addresses in the form of
+ <literal>0x*2e8</literal>, and since many cheap serial cards do
+ not fully decode the 16-bit IO address space, they clash with
+ these cards making the <filename>COM4</filename> port
+ practically unavailable.</para>
+
+ <para>Each serial port is required to have a unique IRQ (unless you
+ are using one of the multiport cards where shared interrupts are
+ supported), so the default IRQs for <filename>COM3</filename>
+ and <filename>COM4</filename> cannot be used.</para>
+ </note>
+
+ <programlisting># Parallel port
+device ppc</programlisting>
+
+ <para>This is the ISA-bus parallel port interface.</para>
+
+ <programlisting>device ppbus # Parallel port bus (required)</programlisting>
+
+ <para>Provides support for the parallel port bus.</para>
+
+ <programlisting>device lpt # Printer</programlisting>
+
+ <para>Support for parallel port printers.</para>
+
+ <note>
+ <para>All three of the above are required to enable parallel printer
+ support.</para>
+ </note>
+
+ <programlisting>device plip # TCP/IP over parallel</programlisting>
+
+ <para>This is the driver for the parallel network interface.</para>
+
+ <programlisting>device ppi # Parallel port interface device</programlisting>
+
+ <para>The general-purpose I/O (<quote>geek port</quote>) + IEEE1284
+ I/O.</para>
+
+ <programlisting>#device vpo # Requires scbus and da</programlisting>
+
+ <indexterm><primary>zip drive</primary></indexterm>
+ <para>This is for an Iomega Zip drive. It requires
+ <literal>scbus</literal> and <literal>da</literal> support. Best
+ performance is achieved with ports in EPP 1.9 mode.</para>
+
+ <programlisting>#device puc</programlisting>
+
+ <para>Uncomment this device if you have a <quote>dumb</quote> serial
+ or parallel PCI card that is supported by the &man.puc.4; glue
+ driver.</para>
+
+ <programlisting># PCI Ethernet NICs.
+device de # DEC/Intel DC21x4x (<quote>Tulip</quote>)
+device em # Intel PRO/1000 adapter Gigabit Ethernet Card
+device ixgb # Intel PRO/10GbE Ethernet Card
+device txp # 3Com 3cR990 (<quote>Typhoon</quote>)
+device vx # 3Com 3c590, 3c595 (<quote>Vortex</quote>)</programlisting>
+
+ <para>Various PCI network card drivers. Comment out or remove any of
+ these not present in your system.</para>
+
+ <programlisting># PCI Ethernet NICs that use the common MII bus controller code.
+# NOTE: Be sure to keep the 'device miibus' line in order to use these NICs!
+device miibus # MII bus support</programlisting>
+
+ <para>MII bus support is required for some PCI 10/100 Ethernet NICs,
+ namely those which use MII-compliant transceivers or implement
+ transceiver control interfaces that operate like an MII. Adding
+ <literal>device miibus</literal> to the kernel config pulls in
+ support for the generic miibus API and all of the PHY drivers,
+ including a generic one for PHYs that are not specifically handled
+ by an individual driver.</para>
+
+ <programlisting>device bce # Broadcom BCM5706/BCM5708 Gigabit Ethernet
+device bfe # Broadcom BCM440x 10/100 Ethernet
+device bge # Broadcom BCM570xx Gigabit Ethernet
+device dc # DEC/Intel 21143 and various workalikes
+device fxp # Intel EtherExpress PRO/100B (82557, 82558)
+device lge # Level 1 LXT1001 gigabit ethernet
+device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet
+device nge # NatSemi DP83820 gigabit ethernet
+device nve # nVidia nForce MCP on-board Ethernet Networking
+device pcn # AMD Am79C97x PCI 10/100 (precedence over 'lnc')
+device re # RealTek 8139C+/8169/8169S/8110S
+device rl # RealTek 8129/8139
+device sf # Adaptec AIC-6915 (<quote>Starfire</quote>)
+device sis # Silicon Integrated Systems SiS 900/SiS 7016
+device sk # SysKonnect SK-984x &amp; SK-982x gigabit Ethernet
+device ste # Sundance ST201 (D-Link DFE-550TX)
+device stge # Sundance/Tamarack TC9021 gigabit Ethernet
+device ti # Alteon Networks Tigon I/II gigabit Ethernet
+device tl # Texas Instruments ThunderLAN
+device tx # SMC EtherPower II (83c170 <quote>EPIC</quote>)
+device vge # VIA VT612x gigabit ethernet
+device vr # VIA Rhine, Rhine II
+device wb # Winbond W89C840F
+device xl # 3Com 3c90x (<quote>Boomerang</quote>, <quote>Cyclone</quote>)</programlisting>
+
+ <para>Drivers that use the MII bus controller code.</para>
+
+ <programlisting># ISA Ethernet NICs. pccard NICs included.
+device cs # Crystal Semiconductor CS89x0 NIC
+# 'device ed' requires 'device miibus'
+device ed # NE[12]000, SMC Ultra, 3c503, DS8390 cards
+device ex # Intel EtherExpress Pro/10 and Pro/10+
+device ep # Etherlink III based cards
+device fe # Fujitsu MB8696x based cards
+device ie # EtherExpress 8/16, 3C507, StarLAN 10 etc.
+device lnc # NE2100, NE32-VL Lance Ethernet cards
+device sn # SMC's 9000 series of Ethernet chips
+device xe # Xircom pccard Ethernet
+
+# ISA devices that use the old ISA shims
+#device le</programlisting>
+
+ <para>ISA Ethernet drivers. See
+ <filename>/usr/src/sys/i386/conf/NOTES</filename> for details
+of which cards are
+ supported by which driver.</para>
+
+ <programlisting># Wireless NIC cards
+device wlan # 802.11 support</programlisting>
+
+ <para>對 802.11 標準的支援。 若要無線上網,則需加上這行。</para>
+
+ <programlisting>device wlan_wep # 802.11 WEP support
+device wlan_ccmp # 802.11 CCMP support
+device wlan_tkip # 802.11 TKIP support</programlisting>
+
+ <para>對 802.11 加密設備的支援。 若要安全加密以及 802.11i 安全協定,
+ 則需加上這行。</para>
+
+ <programlisting>device an # Aironet 4500/4800 802.11 wireless NICs.
+device ath # Atheros pci/cardbus NIC's
+device ath_hal # Atheros HAL (Hardware Access Layer)
+device ath_rate_sample # SampleRate tx rate control for ath
+device an # Aironet 4500/4800 802.11 wireless NICs.
+device awi # BayStack 660 and others
+device ral # Ralink Technology RT2500 wireless NICs.
+device wi # WaveLAN/Intersil/Symbol 802.11 wireless NICs.
+#device wl # Older non 802.11 Wavelan wireless NIC.</programlisting>
+
+ <para>Support for various wireless cards.</para>
+
+ <programlisting># Pseudo devices
+device loop # Network loopback</programlisting>
+
+ <para>This is the generic loopback device for TCP/IP. If you telnet
+ or FTP to <systemitem>localhost</systemitem> (a.k.a. <systemitem class="ipaddress">127.0.0.1</systemitem>) it will come back at you through
+ this device. This is <emphasis>mandatory</emphasis>.</para>
+
+ <programlisting>device random # Entropy device</programlisting>
+
+ <para>Cryptographically secure random number generator.</para>
+
+ <programlisting>device ether # Ethernet support</programlisting>
+
+ <para><literal>ether</literal> is only needed if you have an Ethernet
+ card. It includes generic Ethernet protocol code.</para>
+
+ <programlisting>device sl # Kernel SLIP</programlisting>
+
+ <para><literal>sl</literal> is for SLIP support. This has been almost
+ entirely supplanted by PPP, which is easier to set up, better suited
+ for modem-to-modem connection, and more powerful.</para>
+
+ <programlisting>device ppp # Kernel PPP</programlisting>
+
+ <para>This is for kernel PPP support for dial-up connections. There
+ is also a version of PPP implemented as a userland application that
+ uses <literal>tun</literal> and offers more flexibility and features
+ such as demand dialing.</para>
+
+ <programlisting>device tun # Packet tunnel.</programlisting>
+
+ <para>This is used by the userland PPP software.
+ See
+ the <link linkend="userppp">PPP</link> section of this book for more
+ information.</para>
+
+ <programlisting><anchor xml:id="kernelconfig-ptys"/>
+device pty # Pseudo-ttys (telnet etc)</programlisting>
+
+ <para>This is a <quote>pseudo-terminal</quote> or simulated login port.
+ It is used by incoming <command>telnet</command> and
+ <command>rlogin</command> sessions,
+ <application>xterm</application>, and some other applications such
+ as <application>Emacs</application>.</para>
+
+ <programlisting>device md # Memory <quote>disks</quote></programlisting>
+
+ <para>Memory disk pseudo-devices.</para>
+
+ <programlisting>device gif # IPv6 and IPv4 tunneling</programlisting>
+
+ <para>This implements IPv6 over IPv4 tunneling, IPv4 over IPv6 tunneling,
+ IPv4 over IPv4 tunneling, and IPv6 over IPv6 tunneling. The
+ <literal>gif</literal> device is
+ <quote>auto-cloning</quote>, and will create device nodes as
+ needed.</para>
+
+ <programlisting>device faith # IPv6-to-IPv4 relaying (translation)</programlisting>
+
+ <para>This pseudo-device captures packets that are sent to it and
+ diverts them to the IPv4/IPv6 translation daemon.</para>
+
+ <programlisting># The `bpf' device enables the Berkeley Packet Filter.
+# Be aware of the administrative consequences of enabling this!
+# Note that 'bpf' is required for DHCP.
+device bpf # Berkeley packet filter</programlisting>
+
+ <para>This is the Berkeley Packet Filter. This pseudo-device allows
+ network interfaces to be placed in promiscuous mode, capturing every
+ packet on a broadcast network (e.g., an Ethernet). These packets
+ can be captured to disk and or examined with the &man.tcpdump.1;
+ program.</para>
+
+ <note>
+ <para>The &man.bpf.4; device is also used by
+ &man.dhclient.8; to obtain the IP address of the default router
+ (gateway) and so on. If you use DHCP, leave this
+ uncommented.</para>
+ </note>
+
+ <programlisting># USB support
+device uhci # UHCI PCI-&gt;USB interface
+device ohci # OHCI PCI-&gt;USB interface
+device ehci # EHCI PCI-&gt;USB interface (USB 2.0)
+device usb # USB Bus (required)
+#device udbp # USB Double Bulk Pipe devices
+device ugen # Generic
+device uhid # <quote>Human Interface Devices</quote>
+device ukbd # Keyboard
+device ulpt # Printer
+device umass # Disks/Mass storage - Requires scbus and da
+device ums # Mouse
+device ural # Ralink Technology RT2500USB wireless NICs
+device urio # Diamond Rio 500 MP3 player
+device uscanner # Scanners
+# USB Ethernet, requires mii
+device aue # ADMtek USB Ethernet
+device axe # ASIX Electronics USB Ethernet
+device cdce # Generic USB over Ethernet
+device cue # CATC USB Ethernet
+device kue # Kawasaki LSI USB Ethernet
+device rue # RealTek RTL8150 USB Ethernet</programlisting>
+
+ <para>Support for various USB devices.</para>
+
+ <programlisting># FireWire support
+device firewire # FireWire bus code
+device sbp # SCSI over FireWire (Requires scbus and da)
+device fwe # Ethernet over FireWire (non-standard!)</programlisting>
+
+ <para>Support for various Firewire devices.</para>
+
+ <para>For more information and additional devices supported by
+ &os;, see
+ <filename>/usr/src/sys/i386/conf/NOTES</filename>.</para>
+
+ <sect2>
+ <title>Large Memory Configurations (<acronym>PAE</acronym>)</title>
+ <indexterm>
+ <primary>Physical Address Extensions
+ (<acronym>PAE</acronym>)</primary>
+ <secondary>large memory</secondary>
+ </indexterm>
+
+ <para>Large memory configuration machines require access to
+ more than the 4 gigabyte limit on User+Kernel Virtual
+ Address (<acronym>KVA</acronym>) space. Due to this
+ limitation, Intel added support for 36-bit physical address
+ space access in the &pentium; Pro and later line of CPUs.</para>
+
+ <para>The Physical Address Extension (<acronym>PAE</acronym>)
+ capability of the &intel; &pentium; Pro and later CPUs
+ allows memory configurations of up to 64 gigabytes.
+ &os; provides support for this capability via the
+ <option>PAE</option> kernel configuration option, available
+ in all current release versions of &os;. Due to
+ the limitations of the Intel memory architecture, no distinction
+ is made for memory above or below 4 gigabytes. Memory allocated
+ above 4 gigabytes is simply added to the pool of available
+ memory.</para>
+
+ <para>To enable <acronym>PAE</acronym> support in the kernel,
+ simply add the following line to your kernel configuration
+ file:</para>
+
+ <programlisting>options PAE</programlisting>
+
+ <note>
+ <para>The <acronym>PAE</acronym> support in &os; is only
+ available for &intel; IA-32 processors. It should also be
+ noted, that the <acronym>PAE</acronym> support in &os; has
+ not received wide testing, and should be considered beta
+ quality compared to other stable features of &os;.</para>
+ </note>
+
+ <para><acronym>PAE</acronym> support in &os; has a few limitations:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>A process is not able to access more than 4
+ gigabytes of VM space.</para>
+ </listitem>
+
+ <listitem>
+ <para><acronym>KLD</acronym> modules cannot be loaded into
+ a <acronym>PAE</acronym> enabled kernel, due to the
+ differences in the build framework of a module and the
+ kernel.</para>
+ </listitem>
+
+ <listitem>
+ <para>Device drivers that do not use the &man.bus.dma.9;
+ interface will cause data corruption in a
+ <acronym>PAE</acronym> enabled kernel and are not
+ recommended for use. For this reason, a
+ <filename>PAE</filename> kernel
+ configuration file is provided in &os; which
+ excludes all drivers not known to work in a <acronym>PAE</acronym> enabled
+ kernel.</para>
+ </listitem>
+
+ <listitem>
+ <para>Some system tunables determine memory resource usage
+ by the amount of available physical memory. Such
+ tunables can unnecessarily over-allocate due to the
+ large memory nature of a <acronym>PAE</acronym> system.
+ One such example is the <option>kern.maxvnodes</option>
+ sysctl, which controls the maximum number of vnodes allowed
+ in the kernel. It is advised to adjust this and other
+ such tunables to a reasonable value.</para>
+ </listitem>
+
+ <listitem>
+ <para>It might be necessary to increase the kernel virtual
+ address (<acronym>KVA</acronym>) space or to reduce the
+ amount of specific kernel resource that is heavily used
+ (see above) in order to avoid <acronym>KVA</acronym>
+ exhaustion. The <option>KVA_PAGES</option> kernel option
+ can be used for increasing the
+ <acronym>KVA</acronym> space.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>For performance and stability concerns, it is advised to
+ consult the &man.tuning.7; manual page. The &man.pae.4;
+ manual page contains up-to-date information on &os;'s
+ <acronym>PAE</acronym> support.</para>
+ </sect2>
+ </sect1>
+
+
+ <sect1 xml:id="kernelconfig-trouble">
+ <title>If Something Goes Wrong</title>
+
+ <para>There are five categories of trouble that can occur when
+ building a custom kernel. They are:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><command>config</command> fails:</term>
+
+ <listitem>
+ <para>If the &man.config.8; command fails when you
+ give it your kernel description, you have probably made a
+ simple error somewhere. Fortunately,
+ &man.config.8; will print the line number that it
+ had trouble with, so that you can quickly locate the line
+ containing the error. For example, if you see:</para>
+
+ <screen>config: line 17: syntax error</screen>
+
+ <para>Make sure the
+ keyword is typed correctly by comparing it to the
+ <filename>GENERIC</filename> kernel or another
+ reference.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>make</command> fails:</term>
+
+ <listitem>
+ <para>If the <command>make</command> command fails, it usually
+ signals an error in your kernel description which is not severe
+ enough for &man.config.8; to catch. Again, look
+ over your configuration, and if you still cannot resolve the
+ problem, send mail to the &a.questions; with your kernel
+ configuration, and it should be diagnosed quickly.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>The kernel does not boot:<anchor xml:id="kernelconfig-noboot"/></term>
+
+ <listitem>
+ <para>If your new kernel does not boot, or fails to
+ recognize your devices, do not panic! Fortunately, &os; has
+ an excellent mechanism for recovering from incompatible
+ kernels. Simply choose the kernel you want to boot from at
+ the &os; boot loader. You can access this when the system
+ boot menu appears. Select the <quote>Escape to a loader
+ prompt</quote> option, number six. At the prompt, type
+ <command>unload kernel</command>
+ and then type
+ <command>boot /boot/kernel.old/kernel</command>,
+ or the filename of any other kernel that will boot properly.
+ When reconfiguring a kernel, it is always a good idea to keep
+ a kernel that is known to work on hand.</para>
+
+ <para>After booting with a good kernel you can check over your
+ configuration file and try to build it again. One helpful
+ resource is the <filename>/var/log/messages</filename> file
+ which records, among other things, all of the kernel messages
+ from every successful boot. Also, the &man.dmesg.8; command
+ will print the kernel messages from the current boot.</para>
+
+ <note>
+ <para>If you are having trouble building a kernel, make sure
+ to keep a <filename>GENERIC</filename>, or some other kernel
+ that is known to work on hand as a different name that will
+ not get erased on the next build. You cannot rely on
+ <filename>kernel.old</filename> because when installing a
+ new kernel, <filename>kernel.old</filename> is overwritten
+ with the last installed kernel which may be non-functional.
+ Also, as soon as possible, move the working kernel to the
+ proper <filename>/boot/kernel</filename>
+ location or commands such
+ as &man.ps.1; may not work properly. To do this, simply
+ rename the directory containing the good kernel:</para>
+
+ <screen>&prompt.root; <userinput>mv /boot/kernel /boot/kernel.bad</userinput>
+&prompt.root; <userinput>mv /boot/kernel.good /boot/kernel</userinput></screen>
+
+
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>The kernel works, but &man.ps.1; does not work
+ any more:</term>
+
+ <listitem>
+ <para>If you have installed a different version of the kernel
+ from the one that the system utilities have been built with,
+ for example, a -CURRENT kernel on a -RELEASE, many system-status
+ commands like &man.ps.1; and &man.vmstat.8; will not work any
+ more. You should <link linkend="makeworld">recompile and install
+ a world</link> built with the same version of the source tree as
+ your kernel. This is one reason it is
+ not normally a good idea to use a different version of the
+ kernel from the rest of the operating system.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/l10n/Makefile b/zh_TW.UTF-8/books/handbook/l10n/Makefile
new file mode 100644
index 0000000000..45d3429ab1
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/l10n/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= l10n/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/l10n/chapter.xml b/zh_TW.UTF-8/books/handbook/l10n/chapter.xml
new file mode 100644
index 0000000000..2ea4f83ad6
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/l10n/chapter.xml
@@ -0,0 +1,884 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.119
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="l10n">
+ <info><title>語系設定 - I18N/L10N 用法與設定</title>
+ <authorgroup>
+ <author><personname><firstname>Andrey</firstname><surname>Chernov</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Michael C.</firstname><surname>Wu</surname></personname><contrib>Rewritten by </contrib></author>
+ <!-- 30 Nv 2000 -->
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="l10n-synopsis">
+ <title>概述</title>
+
+ <para>由於 FreeBSD 是分佈全世界的使用者及志工所支持的計畫,本章主要探討的是
+ FreeBSD 的國際化、本土化議題,以便讓母語不是英語系的人也能順利完成各項工作。
+ 在作業系統、應用程式兩種層面,主要都是透過 i18n 標準來實作的,所以,
+ 這裡我們將會介紹大致運作方式。</para>
+
+ <para>讀完這章,您將了解︰</para>
+ <itemizedlist>
+ <listitem><para>各種不同的語言與地區設定如何在作業系統上進行編碼。</para></listitem>
+ <listitem><para>如何設定登入用的 shell 語系環境。</para></listitem>
+ <listitem><para>如何將你的 console 設為英語以外的語系設定。</para></listitem>
+ <listitem><para>如何使用不同語系的設定,來讓 X Window 運作更親切。</para></listitem>
+ <listitem><para>哪邊可以找到更多與 i18n 規格相容的應用程式規格資料。</para></listitem>
+ </itemizedlist>
+
+ <para>在開始閱讀這章之前,您需要︰</para>
+
+ <itemizedlist>
+ <listitem><para>知道如何以 ports/packages 來安裝應用程式(<xref linkend="ports"/>)。</para></listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="l10n-basics">
+ <title>L10N 基礎概念</title>
+
+ <sect2>
+ <title>什麼是 I18N/L10N?</title>
+ <indexterm>
+ <primary>internationalization</primary>
+ <see>localization</see>
+ </indexterm>
+ <indexterm><primary>localization</primary></indexterm>
+
+ <para>程式開發人員習慣把 internationalization 縮寫為 I18N,中間的數字 18 乃是最前與最後面字母之間的字母個數總和,
+ 而 L10N 也是以一樣的方式,是 <quote>localization</quote> 的縮寫。
+ 只要有符合 I18N/L10N 規格、協定的應用程式,就可以讓使用者依各自語系而作設定。</para>
+
+ <para>I18N 應用程式是以 I18N 開發工具來進行開發的,
+ 它可以讓程式開發人員透過寫簡單的文字檔,就可以把執行畫面上的選單、訊息翻譯為各語系的版本。
+ 我們強烈建議程式開發人員遵循這個遊戲規則。</para>
+ </sect2>
+
+ <sect2>
+ <title>為何該使用 I18N/L10N?</title>
+
+ <para>只要有符合 I18N/L10N 標準,就可以輕鬆地看、輸入、處理非英文的資料。</para>
+ </sect2>
+
+ <sect2>
+ <title>I18N 支援哪些語系?</title>
+
+ <para>I18N 和 L10N 並非 FreeBSD 所特有的,目前這世界上的幾乎任一主要語系都有支援,
+ 像是:中文、德文、日文、韓文、法文、俄文、越南文等等。</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="using-localization">
+ <title>使用語系設定(Localization)</title>
+
+ <para>I18N 和 L10N 並非 FreeBSD 所特有的,而是共通的遊戲規則。
+ 我們鼓勵你在 FreeBSD 世界中同樣遵守這項遊戲規則。</para>
+ <indexterm><primary>locale</primary></indexterm>
+
+ <para>Locale 設定由三個部分所組成:語言代碼(Language Code)、國碼(Country Code)、編碼(Encoding)。
+ 所以,Locale 的設定名稱就是由這三個一起組成:</para>
+
+ <programlisting><replaceable>語言代碼</replaceable>_<replaceable>國碼</replaceable>.<replaceable>編碼</replaceable></programlisting>
+
+ <sect2>
+ <title>語言、國碼</title>
+ <indexterm><primary>language codes</primary></indexterm>
+ <indexterm><primary>country codes</primary></indexterm>
+
+ <para>使用者必須要先知道這些特定的國碼、語言代碼(國碼會告訴應用程式該使用哪一種語言),
+ 才能讓 FreeBSD 或其他支援 I18N 的 &unix; 類系統作 locale 相關設定。
+ 此外,網頁瀏覽器(borwser)、SMTP/POP 主機、Web 主機等也都以這架構為主。
+ 下面是如何使用『語言代碼、國碼』的例子:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>語言代碼/國碼</entry>
+ <entry>簡介</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>en_US</entry>
+ <entry>英文(美國)</entry>
+ </row>
+
+ <row>
+ <entry>ru_RU</entry>
+ <entry>俄文(俄國)</entry>
+ </row>
+
+ <row>
+ <entry>zh_TW</entry>
+ <entry>正體中文(台灣)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ </sect2>
+
+ <sect2>
+ <title>編碼</title>
+ <indexterm><primary>encodings</primary></indexterm>
+ <indexterm><primary>ASCII</primary></indexterm>
+
+ <para>有些語言並非採用 ASCII 編碼,可能是: 8-bit、wide
+ 或 multibyte 字元,詳情請參閱 &man.multibyte.3;。
+ 較古早的程式可能無法正確判別、或誤判為特殊控制字元。而較新的程式都可以辨認
+ 8-bit 字元。 由於各程式的作法不一,使用者可能需要在編譯程式時,加上
+ wide 或 multibyte 字元的支援設定,或是正確調整才行。
+ 要輸入、處理 wide 或 multibyte 字元的話,可多多利用 <link xlink:href="&url.base;/ports/index.html">FreeBSD Ports Collection</link> 內有各國語言版本的程式。
+ 詳情請參閱 FreeBSD 各 port 中的 I18N 相關文件。</para>
+
+ <para>Specifically, the user needs to look at the application
+ documentation to decide on how to configure it correctly or to
+ pass correct values into the configure/Makefile/compiler.</para>
+
+ <para>Some things to keep in mind are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Language specific single C chars character sets
+ (see &man.multibyte.3;), e.g.
+ ISO8859-1, ISO8859-15, KOI8-R, CP437.</para>
+ </listitem>
+
+ <listitem>
+ <para>Wide or multibyte encodings, e.g. EUC, Big5.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>You can check the active list of character sets at the
+ <link xlink:href="http://www.iana.org/assignments/character-sets">IANA Registry</link>.</para>
+
+ <note>
+ <para>&os; use X11-compatible locale encodings instead.</para>
+ </note>
+
+ </sect2>
+
+ <sect2>
+ <title>I18N Applications</title>
+
+ <para>In the FreeBSD Ports and Package system, I18N applications
+ have been named with <literal>I18N</literal> in their names for
+ easy identification. However, they do not always support the
+ language needed.</para>
+ </sect2>
+
+ <sect2 xml:id="setting-locale">
+ <title>Setting Locale</title>
+
+ <para>Usually it is sufficient to export the value of the locale name
+ as <envar>LANG</envar> in the login shell. This could be done in
+ the user's <filename>~/.login_conf</filename> file or in the
+ startup file of the user's shell (<filename>~/.profile</filename>,
+ <filename>~/.bashrc</filename>, <filename>~/.cshrc</filename>).
+ There is no need to set the locale subsets such as
+ <envar>LC_CTYPE</envar>, <envar>LC_CTIME</envar>. Please
+ refer to language-specific FreeBSD documentation for more
+ information.</para>
+
+ <para>You should set the following two environment variables in your configuration
+ files:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><envar>LANG</envar> for &posix;<indexterm><primary>POSIX</primary></indexterm> &man.setlocale.3; family
+ functions</para>
+ </listitem>
+
+ <listitem>
+ <para><envar>MM_CHARSET</envar> for applications' MIME<indexterm><primary>MIME</primary></indexterm> character
+ set</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>This includes the user shell configuration, the specific application
+ configuration, and the X11 configuration.</para>
+
+ <sect3>
+ <title>Setting Locale Methods</title>
+ <indexterm><primary>locale</primary></indexterm>
+ <indexterm><primary>login class</primary></indexterm>
+
+ <para>There are two methods for setting locale, and both are
+ described below. The first (recommended one) is by assigning
+ the environment variables in <link linkend="login-class">login
+ class</link>, and the second is by adding the environment
+ variable assignments to the system's shell <link linkend="startup-file">startup file</link>.</para>
+
+ <sect4 xml:id="login-class">
+ <title>Login Classes Method</title>
+
+ <para>This method allows environment variables needed for locale
+ name and MIME character sets to be assigned once for every
+ possible shell instead of adding specific shell assignments to
+ each shell's startup file. <link linkend="usr-setup">User
+ Level Setup</link> can be done by an user himself and <link linkend="adm-setup">Administrator Level Setup</link> require
+ superuser privileges.</para>
+
+ <sect5 xml:id="usr-setup">
+ <title>User Level Setup</title>
+
+ <para>Here is a minimal example of a
+ <filename>.login_conf</filename> file in user's home
+ directory which has both variables set for Latin-1
+ encoding:</para>
+
+ <programlisting>me:\
+ :charset=ISO-8859-1:\
+ :lang=de_DE.ISO8859-1:</programlisting>
+
+ <indexterm><primary>Traditional Chinese</primary><secondary>BIG-5 encoding</secondary></indexterm>
+ <para>Here is an example of a
+ <filename>.login_conf</filename> that sets the variables
+ for Traditional Chinese in BIG-5 encoding. Notice the many
+ more variables set because some software does not respect
+ locale variables correctly for Chinese, Japanese, and Korean.</para>
+
+ <programlisting>#Users who do not wish to use monetary units or time formats
+#of Taiwan can manually change each variable
+me:\
+ :lang=zh_TW.Big5:\
+ :lc_all=zh_TW.Big:\
+ :lc_collate=zh_TW.Big5:\
+ :lc_ctype=zh_TW.Big5:\
+ :lc_messages=zh_TW.Big5:\
+ :lc_monetary=zh_TW.Big5:\
+ :lc_numeric=zh_TW.Big5:\
+ :lc_time=zh_TW.Big5:\
+ :charset=big5:\
+ :xmodifiers="@im=xcin": #Setting the XIM Input Server</programlisting>
+
+ <para>See <link linkend="adm-setup">Administrator Level
+ Setup</link> and &man.login.conf.5; for more details.</para>
+ </sect5>
+
+ <sect5 xml:id="adm-setup">
+ <title>Administrator Level Setup</title>
+
+ <para>Verify that the user's login class in
+ <filename>/etc/login.conf</filename> sets the correct
+ language. Make sure these settings
+ appear in <filename>/etc/login.conf</filename>:</para>
+
+ <programlisting><replaceable>language_name</replaceable>:<replaceable>accounts_title</replaceable>:\
+ :charset=<replaceable>MIME_charset</replaceable>:\
+ :lang=<replaceable>locale_name</replaceable>:\
+ :tc=default:</programlisting>
+
+ <para>So sticking with our previous example using Latin-1, it
+ would look like this:</para>
+
+ <programlisting>german:German Users Accounts:\
+ :charset=ISO-8859-1:\
+ :lang=de_DE.ISO8859-1:\
+ :tc=default:</programlisting>
+
+ <para>Before changing users Login Classes execute
+ the following command</para>
+
+ <screen>&prompt.root; <userinput>cap_mkdb /etc/login.conf</userinput></screen>
+
+ <para>to make new configuration in
+ <filename>/etc/login.conf</filename> visible to the system.</para>
+
+ <bridgehead renderas="sect4">Changing Login Classes with &man.vipw.8;</bridgehead>
+
+ <indexterm>
+ <primary><command>vipw</command></primary>
+ </indexterm>
+ <para>Use <command>vipw</command> to add new users, and make
+ the entry look like this:</para>
+
+ <programlisting>user:password:1111:11:<replaceable>language</replaceable>:0:0:User Name:/home/user:/bin/sh</programlisting>
+
+ <bridgehead renderas="sect4">Changing Login Classes with &man.adduser.8;</bridgehead>
+
+ <indexterm>
+ <primary><command>adduser</command></primary>
+ </indexterm>
+ <indexterm><primary>login class</primary></indexterm>
+ <para>Use <command>adduser</command> to add new users, and do
+ the following:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Set <literal>defaultclass =
+ language</literal> in
+ <filename>/etc/adduser.conf</filename>. Keep in mind
+ you must enter a <literal>default</literal> class for
+ all users of other languages in this case.</para>
+ </listitem>
+
+ <listitem>
+ <para>An alternative variant is answering the specified
+ language each time that
+<screen><prompt>Enter login class: default []: </prompt></screen>
+ appears from &man.adduser.8;.</para>
+ </listitem>
+
+ <listitem>
+ <para>Another alternative is to use the following for each
+ user of a different language that you wish to
+ add:</para>
+
+ <screen>&prompt.root; <userinput>adduser -class language</userinput></screen>
+ </listitem>
+ </itemizedlist>
+
+ <bridgehead renderas="sect4">Changing Login Classes with &man.pw.8;</bridgehead>
+ <indexterm>
+ <primary><command>pw</command></primary>
+ </indexterm>
+ <para>If you use &man.pw.8; for adding new users, call it in
+ this form:</para>
+
+ <screen>&prompt.root; <userinput>pw useradd user_name -L language</userinput></screen>
+ </sect5>
+ </sect4>
+
+ <sect4 xml:id="startup-file">
+ <title>Shell Startup File Method</title>
+
+ <note>
+ <para>This method is not recommended because it requires a
+ different setup for each possible shell program chosen. Use
+ the <link linkend="login-class">Login Class Method</link>
+ instead.</para>
+ </note>
+
+ <indexterm><primary>MIME</primary></indexterm>
+ <indexterm><primary>locale</primary></indexterm>
+ <para>To add the locale name and MIME character set, just set
+ the two environment variables shown below in the
+ <filename>/etc/profile</filename> and/or
+ <filename>/etc/csh.login</filename> shell startup files. We
+ will use the German language as an example below:</para>
+
+ <para>In <filename>/etc/profile</filename>:</para>
+
+ <programlisting><envar>LANG=de_DE.ISO8859-1; export LANG</envar>
+<envar>MM_CHARSET=ISO-8859-1; export MM_CHARSET</envar></programlisting>
+
+ <para>Or in <filename>/etc/csh.login</filename>:</para>
+
+ <programlisting><envar>setenv LANG de_DE.ISO8859-1</envar>
+<envar>setenv MM_CHARSET ISO-8859-1</envar></programlisting>
+
+ <para>Alternatively, you can add the above instructions to
+ <filename>/usr/share/skel/dot.profile</filename> (similar to
+ what was used in <filename>/etc/profile</filename> above), or
+ <filename>/usr/share/skel/dot.login</filename> (similar to
+ what was used in <filename>/etc/csh.login</filename>
+ above).</para>
+
+ <para>For X11:</para>
+
+ <para>In <filename>$HOME/.xinitrc</filename>:</para>
+
+ <programlisting><envar>LANG=de_DE.ISO8859-1; export LANG</envar></programlisting>
+
+ <para>Or:</para>
+
+ <programlisting><envar>setenv LANG de_DE.ISO8859-1</envar></programlisting>
+
+ <para>Depending on your shell (see above).</para>
+
+ </sect4>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="setting-console">
+ <title>Console Setup</title>
+
+ <para>For all single C chars character sets, set the correct
+ console fonts in <filename>/etc/rc.conf</filename> for the
+ language in question with:</para>
+
+ <programlisting>font8x16=<replaceable>font_name</replaceable>
+font8x14=<replaceable>font_name</replaceable>
+font8x8=<replaceable>font_name</replaceable></programlisting>
+
+ <para>The <replaceable>font_name</replaceable> here is taken from
+ the <filename>/usr/share/syscons/fonts</filename> directory,
+ without the <filename>.fnt</filename> suffix.</para>
+
+ <indexterm>
+ <primary><application>sysinstall</application></primary>
+ </indexterm>
+ <indexterm><primary>keymap</primary></indexterm>
+ <indexterm><primary>screenmap</primary></indexterm>
+ <para>Also be sure to set the correct keymap and screenmap for your
+ single C chars character set through
+ <command>sysinstall</command> (<command>/stand/sysinstall</command>
+ in &os; versions older than 5.2).
+ Once inside <application>sysinstall</application>, choose <guimenuitem>Configure</guimenuitem>, then
+ <guimenuitem>Console</guimenuitem>. Alternatively, you can add the
+ following to <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>scrnmap=<replaceable>screenmap_name</replaceable>
+keymap=<replaceable>keymap_name</replaceable>
+keychange="<replaceable>fkey_number sequence</replaceable>"</programlisting>
+
+ <para>The <replaceable>screenmap_name</replaceable> here is taken
+ from the <filename>/usr/share/syscons/scrnmaps</filename>
+ directory, without the <filename>.scm</filename> suffix. A
+ screenmap with a corresponding mapped font is usually needed as a
+ workaround for expanding bit 8 to bit 9 on a VGA adapter's font
+ character matrix in pseudographics area, i.e., to move letters out
+ of that area if screen font uses a bit 8 column.</para>
+
+ <para>If you have the <application>moused</application> daemon
+ enabled by setting the following
+ in your <filename>/etc/rc.conf</filename>:</para>
+
+<programlisting>moused_enable="YES"</programlisting>
+
+ <para>then examine the mouse cursor information in the next
+ paragraph.</para>
+
+ <indexterm>
+ <primary><application>moused</application></primary>
+ </indexterm>
+ <para>By default the mouse cursor of the &man.syscons.4; driver occupies the
+ 0xd0-0xd3 range in the character set. If your language uses this
+ range, you need to move the cursor's range outside of it. To enable
+ the workaround for &os;, add the following line to
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>mousechar_start=3</programlisting>
+
+ <para>The <replaceable>keymap_name</replaceable> here is taken from
+ the <filename>/usr/share/syscons/keymaps</filename> directory,
+ without the <filename>.kbd</filename> suffix. If you are
+ uncertain which keymap to use, you use can &man.kbdmap.1; to test
+ keymaps without rebooting.</para>
+
+ <para>The <literal>keychange</literal> is usually needed to program
+ function keys to match the selected terminal type because
+ function key sequences cannot be defined in the key map.</para>
+
+ <para>Also be sure to set the correct console terminal type in
+ <filename>/etc/ttys</filename> for all <literal>ttyv*</literal>
+ entries. Current pre-defined correspondences are:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Character Set</entry>
+ <entry>Terminal Type</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>ISO8859-1 or ISO8859-15</entry>
+ <entry><literal>cons25l1</literal></entry>
+ </row>
+
+ <row>
+ <entry>ISO8859-2</entry>
+ <entry><literal>cons25l2</literal></entry>
+ </row>
+
+ <row>
+ <entry>ISO8859-7</entry>
+ <entry><literal>cons25l7</literal></entry>
+ </row>
+
+ <row>
+ <entry>KOI8-R</entry>
+ <entry><literal>cons25r</literal></entry>
+ </row>
+
+ <row>
+ <entry>KOI8-U</entry>
+ <entry><literal>cons25u</literal></entry>
+ </row>
+
+ <row>
+ <entry>CP437 (VGA default)</entry>
+ <entry><literal>cons25</literal></entry>
+ </row>
+
+ <row>
+ <entry>US-ASCII</entry>
+ <entry><literal>cons25w</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>For wide or multibyte characters languages, use the correct
+ FreeBSD port in your
+ <filename>/usr/ports/language</filename>
+ directory. Some ports appear as console while the system sees it
+ as serial vtty's, hence you must reserve enough vtty's for both
+ X11 and the pseudo-serial console. Here is a partial list of
+ applications for using other languages in console:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Language</entry>
+ <entry>Location</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>Traditional Chinese (BIG-5)</entry>
+ <entry><package>chinese/big5con</package></entry>
+ </row>
+
+ <row>
+ <entry>Japanese</entry>
+ <entry><package>japanese/kon2-16dot</package> or
+ <package>japanese/mule-freewnn</package></entry>
+ </row>
+
+ <row>
+ <entry>Korean</entry>
+ <entry><package>korean/han</package></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>X11 Setup</title>
+
+ <para>Although X11 is not part of the FreeBSD Project, we have
+ included some information here for FreeBSD users. For more
+ details, refer to the <link xlink:href="http://www.x.org/">&xorg;
+ web site</link> or whichever X11 Server you use.</para>
+
+ <para>In <filename>~/.Xresources</filename>, you can additionally
+ tune application specific I18N settings (e.g., fonts, menus,
+ etc.).</para>
+
+ <sect3>
+ <title>Displaying Fonts</title>
+ <indexterm><primary>X11 True Type font server</primary></indexterm>
+ <para>Install <application>&xorg;</application> server
+ (<package>x11-servers/xorg-server</package>)
+ or <application>&xfree86;</application> server
+ (<package>x11-servers/XFree86-4-Server</package>),
+ then install the language &truetype; fonts. Setting the correct
+ locale should allow you to view your selected language in menus
+ and such.</para>
+ </sect3>
+
+ <sect3>
+ <title>Inputting Non-English Characters</title>
+ <indexterm><primary>X11 Input Method (XIM)</primary></indexterm>
+ <para>The X11 Input Method (XIM) Protocol is a new standard for
+ all X11 clients. All X11 applications should be written as XIM
+ clients that take input from XIM Input servers. There are
+ several XIM servers available for different languages.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Printer Setup</title>
+
+ <para>Some single C chars character sets are usually hardware
+ coded into printers. Wide or multibyte
+ character sets require special setup and we recommend using
+ <application>apsfilter</application>. You may also convert the
+ document to &postscript; or PDF formats using language specific
+ converters.</para>
+ </sect2>
+
+ <sect2>
+ <title>Kernel and File Systems</title>
+
+ <para>The FreeBSD fast filesystem (FFS) is 8-bit clean, so it can be used
+ with any single C chars character set (see &man.multibyte.3;),
+ but there is no character set
+ name stored in the filesystem; i.e., it is raw 8-bit and does not
+ know anything about encoding order. Officially, FFS does not
+ support any form of wide or multibyte character sets yet. However, some
+ wide or multibyte character sets have independent patches for FFS
+ enabling such support. They are only temporary unportable
+ solutions or hacks and we have decided to not include them in the
+ source tree. Refer to respective languages' web sites for more
+ information and the patch files.</para>
+
+ <indexterm><primary>DOS</primary></indexterm>
+ <indexterm><primary>Unicode</primary></indexterm>
+ <para>The FreeBSD &ms-dos; filesystem has the configurable ability to
+ convert between &ms-dos;, Unicode character sets and chosen
+ FreeBSD filesystem character sets. See &man.mount.msdos.8; for
+ details.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="l10n-compiling">
+ <title>Compiling I18N Programs</title>
+
+ <para>Many FreeBSD Ports have been ported with I18N support. Some
+ of them are marked with -I18N in the port name. These and many
+ other programs have built in support for I18N and need no special
+ consideration.</para>
+
+ <indexterm>
+ <primary><application>MySQL</application></primary>
+ </indexterm>
+ <para>However, some applications such as
+ <application>MySQL</application> need to be have the
+ <filename>Makefile</filename> configured with the specific
+ charset. This is usually done in the
+ <filename>Makefile</filename> or done by passing a value to
+ <application>configure</application> in the source.</para>
+ </sect1>
+
+ <sect1 xml:id="lang-setup">
+ <title>Localizing FreeBSD to Specific Languages</title>
+
+ <sect2 xml:id="ru-localize">
+ <info><title>Russian Language (KOI8-R Encoding)</title>
+ <authorgroup>
+ <author><personname><firstname>Andrey</firstname><surname>Chernov</surname></personname><contrib>Originally contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+ <indexterm>
+ <primary>localization</primary>
+ <secondary>Russian</secondary>
+ </indexterm>
+
+ <para>For more information about KOI8-R encoding, see the <link xlink:href="http://koi8.pp.ru/">KOI8-R References
+ (Russian Net Character Set)</link>.</para>
+
+ <sect3>
+ <title>Locale Setup</title>
+
+ <para>Put the following lines into your
+ <filename>~/.login_conf</filename> file:</para>
+
+ <programlisting>me:My Account:\
+ :charset=KOI8-R:\
+ :lang=ru_RU.KOI8-R:</programlisting>
+
+ <para>See earlier in this chapter for examples of setting up the
+ <link linkend="setting-locale">locale</link>.</para>
+ </sect3>
+
+ <sect3>
+ <title>Console Setup</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>Add the following line
+ to your <filename>/etc/rc.conf</filename> file:</para>
+
+ <programlisting>mousechar_start=3</programlisting>
+ </listitem>
+
+ <listitem>
+ <para>Also, use following settings in
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>keymap="ru.koi8-r"
+scrnmap="koi8-r2cp866"
+font8x16="cp866b-8x16"
+font8x14="cp866-8x14"
+font8x8="cp866-8x8"</programlisting>
+
+ </listitem>
+
+ <listitem>
+ <para>For each <literal>ttyv*</literal> entry in
+ <filename>/etc/ttys</filename>, use
+ <literal>cons25r</literal> as the terminal type.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>See earlier in this chapter for examples of setting up the
+ <link linkend="setting-console">console</link>.</para>
+ </sect3>
+
+ <sect3>
+ <title>Printer Setup</title>
+ <indexterm><primary>printers</primary></indexterm>
+ <para>Since most printers with Russian characters come with
+ hardware code page CP866, a special output filter is needed
+ to convert from KOI8-R to CP866. Such a filter is installed by
+ default as <filename>/usr/libexec/lpr/ru/koi2alt</filename>.
+ A Russian printer <filename>/etc/printcap</filename> entry
+ should look like:</para>
+
+ <programlisting>lp|Russian local line printer:\
+ :sh:of=/usr/libexec/lpr/ru/koi2alt:\
+ :lp=/dev/lpt0:sd=/var/spool/output/lpd:lf=/var/log/lpd-errs:</programlisting>
+
+ <para>See &man.printcap.5; for a detailed description.</para>
+ </sect3>
+
+ <sect3>
+ <title>&ms-dos; FS and Russian Filenames</title>
+
+ <para>The following example &man.fstab.5; entry enables support
+ for Russian filenames in mounted &ms-dos; filesystems:</para>
+
+ <programlisting>/dev/ad0s2 /dos/c msdos rw,-Wkoi2dos,-Lru_RU.KOI8-R 0 0</programlisting>
+
+ <para>The option <option>-L</option> selects the locale name
+ used, and <option>-W</option> sets the character conversion
+ table. To use the <option>-W</option> option, be sure to
+ mount <filename>/usr</filename> before the &ms-dos; partition
+ because the conversion tables are located in
+ <filename>/usr/libdata/msdosfs</filename>. For more
+ information, see the &man.mount.msdos.8; manual
+ page.</para>
+ </sect3>
+
+ <sect3>
+ <title>X11 Setup</title>
+
+ <orderedlist>
+ <listitem>
+ <para>Do <link linkend="setting-locale">non-X locale
+ setup</link> first as described.</para>
+ </listitem>
+
+ <listitem>
+ <para>If you use <application>&xorg;</application>,
+ install
+ <package>x11-fonts/xorg-fonts-cyrillic</package>
+ package.</para>
+
+ <para>Check the <literal>"Files"</literal> section
+ in your <filename>/etc/X11/xorg.conf</filename> file.
+ The following
+ lines must be added <emphasis>before</emphasis> any other
+ <literal>FontPath</literal> entries:</para>
+
+ <programlisting>FontPath "/usr/X11R6/lib/X11/fonts/cyrillic/misc"
+FontPath "/usr/X11R6/lib/X11/fonts/cyrillic/75dpi"
+FontPath "/usr/X11R6/lib/X11/fonts/cyrillic/100dpi"</programlisting>
+
+ <para>If you use a high resolution video mode, swap the 75 dpi
+ and 100 dpi lines.</para>
+ </listitem>
+
+ <listitem>
+ <para>To activate a Russian keyboard, add the following to the
+ <literal>"Keyboard"</literal> section of your
+ <filename>xorg.conf</filename> file.</para>
+
+ <programlisting>Option "XkbLayout" "us,ru"
+Option "XkbOptions" "grp:toggle"</programlisting>
+
+ <para>Also make sure that <literal>XkbDisable</literal> is
+ turned off (commented out) there.</para>
+
+ <para>For <literal>grp:caps_toggle</literal>
+ the RUS/LAT switch will be <keycap>CapsLock</keycap>.
+ The old <keycap>CapsLock</keycap> function is still
+ available via <keycombo action="simul"><keycap>Shift</keycap><keycap>CapsLock</keycap></keycombo> (in LAT mode
+ only). For <literal>grp:toggle</literal>
+ the RUS/LAT switch will be <keycap>Right Alt</keycap>.
+ <literal>grp:caps_toggle</literal> does not work in
+ <application>&xorg;</application> for unknown reason.</para>
+
+ <para>If you have <quote>&windows;</quote> keys on your keyboard,
+ and notice that some non-alphabetical keys are mapped
+ incorrectly in RUS mode, add the following line in your
+ <filename>xorg.conf</filename> file.</para>
+
+ <programlisting>Option "XkbVariant" ",winkeys"</programlisting>
+
+ <note>
+ <para>The Russian XKB keyboard may not work with non-localized
+ applications.</para>
+ </note>
+ </listitem>
+ </orderedlist>
+ <note>
+ <para>Minimally localized applications
+ should call a <function>XtSetLanguageProc (NULL, NULL,
+ NULL);</function> function early in the program.</para>
+ <para>See <link xlink:href="http://koi8.pp.ru/xwin.html">
+ KOI8-R for X Window</link> for more instructions on
+ localizing X11 applications.</para>
+ </note>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Traditional Chinese Localization for Taiwan</title>
+ <indexterm>
+ <primary>localization</primary>
+ <secondary>Traditional Chinese</secondary>
+ </indexterm>
+ <para>The FreeBSD-Taiwan Project has an Chinese HOWTO for
+ FreeBSD at <uri xlink:href="http://netlab.cse.yzu.edu.tw/~statue/freebsd/zh-tut/">http://netlab.cse.yzu.edu.tw/~statue/freebsd/zh-tut/</uri>
+ using many Chinese ports.
+ Current editor for the <literal>FreeBSD Chinese HOWTO</literal> is
+ Shen Chuan-Hsing <email>statue@freebsd.sinica.edu.tw</email>.
+ </para>
+
+ <para>Chuan-Hsing Shen <email>statue@freebsd.sinica.edu.tw</email> has
+ created the <link xlink:href="http://netlab.cse.yzu.edu.tw/~statue/cfc/">
+ Chinese FreeBSD Collection (CFC)</link> using FreeBSD-Taiwan's
+ <literal>zh-L10N-tut</literal>. The packages and the script files
+ are available at <uri xlink:href="ftp://freebsd.csie.nctu.edu.tw/pub/taiwan/CFC/">ftp://freebsd.csie.nctu.edu.tw/pub/taiwan/CFC/</uri>.</para>
+ </sect2>
+
+ <sect2>
+ <title>German Language Localization (for All ISO 8859-1
+ Languages)</title>
+ <indexterm>
+ <primary>localization</primary>
+ <secondary>German</secondary>
+ </indexterm>
+
+ <para>Slaven Rezic <email>eserte@cs.tu-berlin.de</email> wrote a
+ tutorial how to use umlauts on a FreeBSD machine. The tutorial
+ is written in German and available at
+ <uri xlink:href="http://www.de.FreeBSD.org/de/umlaute/">http://www.de.FreeBSD.org/de/umlaute/</uri>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Japanese and Korean Language Localization</title>
+ <indexterm>
+ <primary>localization</primary>
+ <secondary>Japanese</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>localization</primary>
+ <secondary>Korean</secondary>
+ </indexterm>
+ <para>For Japanese, refer to
+ <uri xlink:href="http://www.jp.FreeBSD.org/">http://www.jp.FreeBSD.org/</uri>,
+ and for Korean, refer to
+ <uri xlink:href="http://www.kr.FreeBSD.org/">http://www.kr.FreeBSD.org/</uri>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Non-English FreeBSD Documentation</title>
+
+ <para>Some FreeBSD contributors have translated parts of FreeBSD to
+ other languages. They are available through links on the <link xlink:href="&url.base;/index.html">main site</link> or in
+ <filename>/usr/share/doc</filename>.</para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/linuxemu/Makefile b/zh_TW.UTF-8/books/handbook/linuxemu/Makefile
new file mode 100644
index 0000000000..a477216e72
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/linuxemu/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= linuxemu/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/linuxemu/chapter.xml b/zh_TW.UTF-8/books/handbook/linuxemu/chapter.xml
new file mode 100644
index 0000000000..47d61c8ba1
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/linuxemu/chapter.xml
@@ -0,0 +1,3281 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.132
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="linuxemu">
+ <info><title>與 Linux Binary 的相容方面</title>
+ <authorgroup>
+ <author><personname><firstname>Jim</firstname><surname>Mock</surname></personname><contrib>Restructured and parts updated by </contrib></author>
+ <!-- 22 Mar 2000 -->
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Brian N.</firstname><surname>Handy</surname></personname><contrib>Originally contributed by </contrib></author>
+ <author><personname><firstname>Rich</firstname><surname>Murphey</surname></personname></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="linuxemu-synopsis">
+ <title>概述</title>
+ <indexterm><primary>Linux binary compatibility</primary></indexterm>
+ <indexterm>
+ <primary>binary compatibility</primary>
+ <secondary>Linux</secondary>
+ </indexterm>
+
+ <para>FreeBSD 有提供其他幾種 &unix; like 作業系統的 binary 相容性,其中包括了 Linux。
+ 你可能會納悶:為什麼 FreeBSD 需要能夠執行 Linux 專用執行檔(binary)呢?答案很簡單,
+ 許多公司、開發者只會 Linux 開發程式,因為這是目前資訊界 <quote>最熱門</quote> 的玩意。
+ 這逼得許多 FreeBSD 使用者不得不去勸說這些人是否提供可直接在 FreeBSD 上執行的版本。
+ 但問題是,大多數公司並不瞭解會有多少人會用 FreeBSD 版,因此他們仍只開發 Linux 版。
+ 那麼 FreeBSD 使用者該怎麼辦呢?答案就是用 FreeBSD 所提供的 Linux binary 相容。</para>
+
+ <para>簡單來講,這種相容性可讓 FreeBSD 使用者直接執行約 90% 的 Linux 程式,而不必做任何修改。
+ 這些包括了: <application>&staroffice;</application>、
+ <application>&netscape;</application> 的 Linux 版、
+ <application>&adobe;&nbsp;&acrobat;</application>、
+ <application>RealPlayer</application>、
+ <application>VMware</application>、
+ <application>&oracle;</application>、
+ <application>WordPerfect</application>、<application>Doom</application>、
+ <application>Quake</application> 等等。此外,也有人回報說在某些情況下,
+ 這些在 FreeBSD 上執行的 Linux 程式,甚至比原本在 Linux 執行得更好。</para>
+
+ <para>然而呢,還是有些只限 Linux 特定的作業系統功能,在 FreeBSD 上並未支援。
+ 如果 Linux 程式過於濫用只有 &i386; 架構上才能用的功能,比如:虛擬 8086 模式,
+ 則可能無法在 FreeBSD 運作正常。</para>
+
+ <para>讀完這章,您將了解:</para>
+ <itemizedlist>
+ <listitem>
+ <para>如何啟用 Linux 相容模式。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何安裝額外的 Linux share libraries。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何在 FreeBSD 上安裝 Linux 程式。</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD 上的 Linux 相容模式的實作細節。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>在閱讀這章之前,您應當了解:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>知道如何透過 port 機制來安裝軟體(<xref linkend="ports"/>)。</para>
+ </listitem>
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 xml:id="linuxemu-lbc-install">
+ <title>安裝</title>
+
+ <indexterm><primary>KLD (kernel loadable object)</primary></indexterm>
+
+ <para>預設並不會打開 Linux 相容模式,最簡單的啟用方式,就是載入
+ <literal>linux</literal> KLD object (<quote>Kernel LoaDable
+ object</quote>)。 載入方式,請切為 <systemitem class="username">root</systemitem>
+ 權限,然後打下列指令:</para>
+
+ <screen>&prompt.root; <userinput>kldload linux</userinput></screen>
+
+ <para>若要每次開機都啟用的話,請把下列內容加到
+ <filename>/etc/rc.conf</filename> 檔:</para>
+
+ <programlisting>linux_enable="YES"</programlisting>
+
+ <para>另外可以用 &man.kldstat.8; 指令,來確認有哪些 KLD 有載入:</para>
+
+ <screen>&prompt.user; <userinput>kldstat</userinput>
+Id Refs Address Size Name
+ 1 2 0xc0100000 16bdb8 kernel
+ 7 1 0xc24db000 d000 linux.ko</screen>
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>COMPAT_LINUX</secondary>
+ </indexterm>
+
+ <para>If for some reason you do not want to or cannot load the KLD,
+ then you may statically link Linux binary compatibility into the kernel
+ by adding <literal>options COMPAT_LINUX</literal> to your kernel
+ configuration file. Then install your new kernel as described in
+ <xref linkend="kernelconfig"/>.</para>
+
+ <sect2>
+ <title>Installing Linux Runtime Libraries</title>
+ <indexterm>
+ <primary>Linux</primary>
+ <secondary>installing Linux libraries</secondary>
+ </indexterm>
+
+ <para>This can be done one of two ways, either by using the
+ <link linkend="linuxemu-libs-port">linux_base</link> port, or
+ by installing them <link linkend="linuxemu-libs-manually">manually</link>.</para>
+
+ <sect3 xml:id="linuxemu-libs-port">
+ <title>Installing Using the linux_base Port</title>
+ <indexterm><primary>Ports Collection</primary></indexterm>
+
+ <para>This is by far the easiest method to use when installing the
+ runtime libraries. It is just like installing any other port
+ from the <link xlink:href="file://localhost/usr/ports/">Ports Collection</link>.
+ Simply do the following:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/emulators/linux_base-fc4</userinput>
+&prompt.root; <userinput>make install distclean</userinput></screen>
+
+ <para>You should now have working Linux binary compatibility.
+ Some programs may complain about incorrect minor versions of the
+ system libraries. In general, however, this does not seem to be
+ a problem.</para>
+
+ <note><para>There may be multiple versions of the <package>emulators/linux_base</package> port available,
+ corresponding to different versions of various Linux distributions.
+ You should install the port most closely resembling the
+ requirements of the Linux applications you would like to
+ install.</para></note>
+
+ </sect3>
+
+ <sect3 xml:id="linuxemu-libs-manually">
+ <title>Installing Libraries Manually</title>
+
+ <para>If you do not have the <quote>ports</quote> collection
+ installed, you can install the libraries by hand instead. You
+ will need the Linux shared libraries that the program depends on
+ and the runtime linker. Also, you will need to create a
+ <quote>shadow root</quote> directory,
+ <filename>/compat/linux</filename>, for Linux libraries on your
+ FreeBSD system. Any shared libraries opened by Linux programs
+ run under FreeBSD will look in this tree first. So, if a Linux
+ program loads, for example, <filename>/lib/libc.so</filename>,
+ FreeBSD will first try to open
+ <filename>/compat/linux/lib/libc.so</filename>, and if that does
+ not exist, it will then try <filename>/lib/libc.so</filename>.
+ Shared libraries should be installed in the shadow tree
+ <filename>/compat/linux/lib</filename> rather than the paths
+ that the Linux <command>ld.so</command> reports.</para>
+
+ <para>Generally, you will need to look for the shared libraries
+ that Linux binaries depend on only the first few times that you
+ install a Linux program on your FreeBSD system. After a while,
+ you will have a sufficient set of Linux shared libraries on your
+ system to be able to run newly imported Linux binaries without
+ any extra work.</para>
+ </sect3>
+
+ <sect3>
+ <title>How to Install Additional Shared Libraries</title>
+ <indexterm><primary>shared libraries</primary></indexterm>
+
+ <para>What if you install the <filename>linux_base</filename> port
+ and your application still complains about missing shared
+ libraries? How do you know which shared libraries Linux
+ binaries need, and where to get them? Basically, there are 2
+ possibilities (when following these instructions you will need
+ to be <systemitem class="username">root</systemitem> on your FreeBSD system).</para>
+
+ <para>If you have access to a Linux system, see what shared
+ libraries the application needs, and copy them to your FreeBSD
+ system. Look at the following example:</para>
+
+ <informalexample>
+ <para>Let us assume you used FTP to get the Linux binary of
+ <application>Doom</application>, and put it on a Linux system you have access to. You
+ then can check which shared libraries it needs by running
+ <command>ldd linuxdoom</command>, like so:</para>
+
+ <screen>&prompt.user; <userinput>ldd linuxdoom</userinput>
+libXt.so.3 (DLL Jump 3.1) =&gt; /usr/X11/lib/libXt.so.3.1.0
+libX11.so.3 (DLL Jump 3.1) =&gt; /usr/X11/lib/libX11.so.3.1.0
+libc.so.4 (DLL Jump 4.5pl26) =&gt; /lib/libc.so.4.6.29</screen>
+
+ <indexterm><primary>symbolic links</primary></indexterm>
+ <para>You would need to get all the files from the last column,
+ and put them under <filename>/compat/linux</filename>, with
+ the names in the first column as symbolic links pointing to
+ them. This means you eventually have these files on your
+ FreeBSD system:</para>
+
+ <screen>/compat/linux/usr/X11/lib/libXt.so.3.1.0
+/compat/linux/usr/X11/lib/libXt.so.3 -&gt; libXt.so.3.1.0
+/compat/linux/usr/X11/lib/libX11.so.3.1.0
+/compat/linux/usr/X11/lib/libX11.so.3 -&gt; libX11.so.3.1.0
+/compat/linux/lib/libc.so.4.6.29
+/compat/linux/lib/libc.so.4 -&gt; libc.so.4.6.29</screen>
+
+ <blockquote>
+ <note>
+ <para>Note that if you already have a Linux shared library
+ with a matching major revision number to the first column
+ of the <command>ldd</command> output, you will not need to
+ copy the file named in the last column to your system, the
+ one you already have should work. It is advisable to copy
+ the shared library anyway if it is a newer version,
+ though. You can remove the old one, as long as you make
+ the symbolic link point to the new one. So, if you have
+ these libraries on your system:</para>
+
+ <screen>/compat/linux/lib/libc.so.4.6.27
+/compat/linux/lib/libc.so.4 -&gt; libc.so.4.6.27</screen>
+
+ <para>and you find a new binary that claims to require a
+ later version according to the output of
+ <command>ldd</command>:</para>
+
+ <screen>libc.so.4 (DLL Jump 4.5pl26) -&gt; libc.so.4.6.29</screen>
+
+ <para>If it is only one or two versions out of date in the
+ in the trailing digit then do not worry about copying
+ <filename>/lib/libc.so.4.6.29</filename> too, because the
+ program should work fine with the slightly older version.
+ However, if you like, you can decide to replace the
+ <filename>libc.so</filename> anyway, and that should leave
+ you with:</para>
+
+ <screen>/compat/linux/lib/libc.so.4.6.29
+/compat/linux/lib/libc.so.4 -&gt; libc.so.4.6.29</screen>
+ </note>
+ </blockquote>
+
+ <blockquote>
+ <note>
+ <para>The symbolic link mechanism is
+ <emphasis>only</emphasis> needed for Linux binaries. The
+ FreeBSD runtime linker takes care of looking for matching
+ major revision numbers itself and you do not need to worry
+ about it.</para>
+ </note>
+ </blockquote>
+ </informalexample>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Installing Linux ELF Binaries</title>
+ <indexterm>
+ <primary>Linux</primary>
+ <secondary>ELF binaries</secondary>
+ </indexterm>
+
+ <para>ELF binaries sometimes require an extra step of
+ <quote>branding</quote>. If you attempt to run an unbranded ELF
+ binary, you will get an error message like the following:</para>
+
+ <screen>&prompt.user; <userinput>./my-linux-elf-binary</userinput>
+ELF binary type not known
+Abort</screen>
+
+ <para>To help the FreeBSD kernel distinguish between a FreeBSD ELF
+ binary from a Linux binary, use the &man.brandelf.1;
+ utility.</para>
+
+ <screen>&prompt.user; <userinput>brandelf -t Linux my-linux-elf-binary</userinput></screen>
+
+ <indexterm><primary>GNU toolchain</primary></indexterm>
+ <para>The GNU toolchain now places the appropriate branding
+ information into ELF binaries automatically, so this step
+ should become increasingly unnecessary in the future.</para>
+ </sect2>
+
+ <sect2>
+ <title>Configuring the Hostname Resolver</title>
+
+ <para>If DNS does not work or you get this message:</para>
+
+ <screen>resolv+: "bind" is an invalid keyword resolv+:
+"hosts" is an invalid keyword</screen>
+
+ <para>You will need to configure a
+ <filename>/compat/linux/etc/host.conf</filename> file
+ containing:</para>
+
+ <programlisting>order hosts, bind
+multi on</programlisting>
+
+ <para>The order here specifies that <filename>/etc/hosts</filename>
+ is searched first and DNS is searched second. When
+ <filename>/compat/linux/etc/host.conf</filename> is not
+ installed, Linux applications find FreeBSD's
+ <filename>/etc/host.conf</filename> and complain about the
+ incompatible FreeBSD syntax. You should remove
+ <literal>bind</literal> if you have not configured a name server
+ using the <filename>/etc/resolv.conf</filename> file.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="linuxemu-mathematica">
+ <info><title>Installing &mathematica;</title>
+ <authorgroup>
+ <author><personname><firstname>Boris</firstname><surname>Hollas</surname></personname><contrib>Updated for Mathematica 5.X by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm>
+ <primary>applications</primary>
+ <secondary><application>Mathematica</application></secondary>
+ </indexterm>
+
+ <para>This document describes the process of installing the Linux
+ version of <application>&mathematica; 5.X</application> onto
+ a FreeBSD system.</para>
+
+ <para>The Linux version of <application>&mathematica;</application>
+ or <application>&mathematica; for Students</application> can
+ be ordered directly from Wolfram at
+ <uri xlink:href="http://www.wolfram.com/">http://www.wolfram.com/</uri>.</para>
+
+ <sect2>
+ <title>Running the &mathematica; Installer</title>
+
+ <para>First, you have to tell &os; that
+ <application>&mathematica;</application>'s Linux
+ binaries use the Linux ABI. The easiest way to do so is to
+ set the default ELF brand
+ to Linux for all unbranded binaries with the command:</para>
+
+ <screen>&prompt.root; <userinput>sysctl kern.fallback_elf_brand=3</userinput></screen>
+
+ <para>This will make &os; assume that unbranded ELF binaries
+ use the Linux ABI and so you should be able to run the
+ installer straight from the CDROM.</para>
+
+ <para>Now, copy the file <filename>MathInstaller</filename> to
+ your hard drive:</para>
+
+ <screen>&prompt.root; <userinput>mount /cdrom</userinput>
+&prompt.root; <userinput>cp /cdrom/Unix/Installers/Linux/MathInstaller /localdir/</userinput></screen>
+
+ <para>and in this file, replace <literal>/bin/sh</literal> in
+ the first line by <literal>/compat/linux/bin/sh</literal>.
+ This makes sure that the installer is executed by the Linux
+ version of &man.sh.1;. Next, replace all occurrences of
+ <literal>Linux)</literal> by <literal>FreeBSD)</literal> with
+ a text editor or the script below in the next section. This
+ tells the <application>&mathematica;</application> installer,
+ who calls <command>uname -s</command> to determine the
+ operating system, to treat &os; as a Linux-like operating
+ system. Invoking <command>MathInstaller</command> will now
+ install <application>&mathematica;</application>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Modifying the &mathematica; Executables</title>
+
+ <para>The shell scripts that
+ <application>&mathematica;</application> created during
+ installation have to be modified before you can use them. If
+ you chose <filename>/usr/local/bin</filename>
+ as the directory to place the
+ <application>&mathematica;</application> executables in, you
+ will find symlinks in this directory to files called
+ <filename>math</filename>, <filename>mathematica</filename>,
+ <filename>Mathematica</filename>, and
+ <filename>MathKernel</filename>. In each of these, replace
+ <literal>Linux)</literal> by <literal>FreeBSD)</literal> with
+ a text editor or the following shell script:</para>
+
+ <programlisting>#!/bin/sh
+cd /usr/local/bin
+for i in math mathematica Mathematica MathKernel
+ do sed 's/Linux)/FreeBSD)/g' $i &gt; $i.tmp
+ sed 's/\/bin\/sh/\/compat\/linux\/bin\/sh/g' $i.tmp &gt; $i
+ rm $i.tmp
+ chmod a+x $i
+done</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Obtaining Your &mathematica; Password</title>
+
+ <indexterm>
+ <primary>Ethernet</primary>
+ <secondary>MAC address</secondary>
+ </indexterm>
+
+ <para>When you start <application>&mathematica;</application>
+ for the first time, you will be asked for a password. If you
+ have not yet obtained a password from Wolfram, run the program
+ <command>mathinfo</command> in the installation directory to
+ obtain your <quote>machine ID</quote>. This machine ID is
+ based solely on the MAC address of your first Ethernet card,
+ so you cannot run your copy of
+ <application>&mathematica;</application> on different
+ machines.</para>
+
+ <para>When you register with Wolfram, either by email, phone or fax,
+ you will give them the <quote>machine ID</quote> and they will
+ respond with a corresponding password consisting of groups of
+ numbers.</para>
+ </sect2>
+
+ <sect2>
+ <title>Running the &mathematica; Frontend over a Network</title>
+
+ <para><application>&mathematica;</application> uses some special
+ fonts to display characters not
+ present in any of the standard font sets (integrals, sums, Greek
+ letters, etc.). The X protocol requires these fonts to be install
+ <emphasis>locally</emphasis>. This means you will have to copy
+ these fonts from the CDROM or from a host with
+ <application>&mathematica;</application>
+ installed to your local machine. These fonts are normally stored
+ in <filename>/cdrom/Unix/Files/SystemFiles/Fonts</filename> on the
+ CDROM, or
+ <filename>/usr/local/mathematica/SystemFiles/Fonts</filename> on
+ your hard drive. The actual fonts are in the subdirectories
+ <filename>Type1</filename> and <filename>X</filename>. There are
+ several ways to use them, as described below.</para>
+
+ <para>The first way is to copy them into one of the existing font
+ directories in <filename>/usr/X11R6/lib/X11/fonts</filename>.
+ This will require editing the <filename>fonts.dir</filename> file,
+ adding the font names to it, and changing the number of fonts on
+ the first line. Alternatively, you should also just be able to
+ run &man.mkfontdir.1; in the directory you have copied
+ them to.</para>
+
+ <para>The second way to do this is to copy the directories to
+ <filename>/usr/X11R6/lib/X11/fonts</filename>:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/X11R6/lib/X11/fonts</userinput>
+&prompt.root; <userinput>mkdir X</userinput>
+&prompt.root; <userinput>mkdir MathType1</userinput>
+&prompt.root; <userinput>cd /cdrom/Unix/Files/SystemFiles/Fonts</userinput>
+&prompt.root; <userinput>cp X/* /usr/X11R6/lib/X11/fonts/X</userinput>
+&prompt.root; <userinput>cp Type1/* /usr/X11R6/lib/X11/fonts/MathType1</userinput>
+&prompt.root; <userinput>cd /usr/X11R6/lib/X11/fonts/X</userinput>
+&prompt.root; <userinput>mkfontdir</userinput>
+&prompt.root; <userinput>cd ../MathType1</userinput>
+&prompt.root; <userinput>mkfontdir</userinput></screen>
+
+ <para>Now add the new font directories to your font path:</para>
+
+ <screen>&prompt.root; <userinput>xset fp+ /usr/X11R6/lib/X11/fonts/X</userinput>
+&prompt.root; <userinput>xset fp+ /usr/X11R6/lib/X11/fonts/MathType1</userinput>
+&prompt.root; <userinput>xset fp rehash</userinput></screen>
+
+ <para>If you are using the <application>&xorg;</application> server, you can have these font
+ directories loaded automatically by adding them to your
+ <filename>xorg.conf</filename> file.</para>
+
+ <note><para>For <application>&xfree86;</application> servers,
+ the configuration file is <filename>XF86Config</filename>.</para></note>
+ <indexterm><primary>fonts</primary></indexterm>
+
+ <para>If you <emphasis>do not</emphasis> already have a directory
+ called <filename>/usr/X11R6/lib/X11/fonts/Type1</filename>, you
+ can change the name of the <filename>MathType1</filename>
+ directory in the example above to
+ <filename>Type1</filename>.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="linuxemu-maple">
+ <info><title>Installing &maple;</title>
+ <authorgroup>
+ <author><personname><firstname>Aaron</firstname><surname>Kaplan</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Robert</firstname><surname>Getschmann</surname></personname><contrib>Thanks to </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm>
+ <primary>applications</primary>
+ <secondary><application>Maple</application></secondary>
+ </indexterm>
+
+ <para><application>&maple;</application> is a commercial mathematics program similar to
+ <application>&mathematica;</application>. You must purchase this software from <uri xlink:href="http://www.maplesoft.com/">http://www.maplesoft.com/</uri> and then register there
+ for a license file. To install this software on FreeBSD, please
+ follow these simple steps.</para>
+
+ <procedure>
+ <step><para>Execute the <filename>INSTALL</filename> shell
+ script from the product distribution. Choose the
+ <quote>RedHat</quote> option when prompted by the
+ installation program. A typical installation directory
+ might be <filename>/usr/local/maple</filename>.</para></step>
+
+ <step><para>If you have not done so, order a license for <application>&maple;</application>
+ from Maple Waterloo Software (<uri xlink:href="http://register.maplesoft.com/">http://register.maplesoft.com/</uri>)
+ and copy it to
+ <filename>/usr/local/maple/license/license.dat</filename>.</para></step>
+
+ <step><para>Install the <application>FLEXlm</application>
+ license manager by running the
+ <filename>INSTALL_LIC</filename> install shell script that
+ comes with <application>&maple;</application>. Specify the
+ primary hostname for your machine for the license
+ server.</para></step>
+
+ <step><para>Patch the
+ <filename>/usr/local/maple/bin/maple.system.type</filename>
+ file with the following:</para>
+<programlisting> ----- snip ------------------
+*** maple.system.type.orig Sun Jul 8 16:35:33 2001
+--- maple.system.type Sun Jul 8 16:35:51 2001
+***************
+*** 72,77 ****
+--- 72,78 ----
+ # the IBM RS/6000 AIX case
+ MAPLE_BIN="bin.IBM_RISC_UNIX"
+ ;;
++ "FreeBSD"|\
+ "Linux")
+ # the Linux/x86 case
+ # We have two Linux implementations, one for Red Hat and
+ ----- snip end of patch -----</programlisting>
+
+ <para>Please note that after the <literal>"FreeBSD"|\</literal> no other
+ whitespace should be present.</para>
+
+ <para>This patch instructs <application>&maple;</application> to
+ recognize <quote>FreeBSD</quote> as a type of Linux system.
+ The <filename>bin/maple</filename> shell script calls the
+ <filename>bin/maple.system.type</filename> shell script
+ which in turn calls <command>uname -a</command> to find out the operating
+ system name. Depending on the OS name it will find out which
+ binaries to use.</para></step>
+
+ <step><para>Start the license server.</para>
+
+ <para>The following script, installed as
+ <filename>/usr/local/etc/rc.d/lmgrd.sh</filename> is a
+ convenient way to start up <command>lmgrd</command>:</para>
+
+ <programlisting> ----- snip ------------
+
+#! /bin/sh
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin
+PATH=${PATH}:/usr/local/maple/bin:/usr/local/maple/FLEXlm/UNIX/LINUX
+export PATH
+
+LICENSE_FILE=/usr/local/maple/license/license.dat
+LOG=/var/log/lmgrd.log
+
+case "$1" in
+start)
+ lmgrd -c ${LICENSE_FILE} 2&gt;&gt; ${LOG} 1&gt;&amp;2
+ echo -n " lmgrd"
+ ;;
+stop)
+ lmgrd -c ${LICENSE_FILE} -x lmdown 2&gt;&gt; ${LOG} 1&gt;&amp;2
+ ;;
+*)
+ echo "Usage: `basename $0` {start|stop}" 1&gt;&amp;2
+ exit 64
+ ;;
+esac
+
+exit 0
+ ----- snip ------------</programlisting></step>
+
+
+ <step><para>Test-start <application>&maple;</application>:</para>
+ <screen>&prompt.user; <userinput>cd /usr/local/maple/bin</userinput>
+&prompt.user; <userinput>./xmaple</userinput></screen>
+
+ <para>You should be up and running. Make sure to write
+ Maplesoft to let them know you would like a native FreeBSD
+ version!</para></step>
+ </procedure>
+
+ <sect2>
+ <title>Common Pitfalls</title>
+
+ <itemizedlist>
+ <listitem><para>The <application>FLEXlm</application> license manager can be a difficult
+ tool to work with. Additional documentation on the subject
+ can be found at <uri xlink:href="http://www.globetrotter.com/">http://www.globetrotter.com/</uri>.</para></listitem>
+
+ <listitem><para><command>lmgrd</command> is known to be very picky
+ about the license file and to core dump if there are any
+ problems. A correct license file should look like this:</para>
+
+<programlisting># =======================================================
+# License File for UNIX Installations ("Pointer File")
+# =======================================================
+SERVER chillig ANY
+#USE_SERVER
+VENDOR maplelmg
+
+FEATURE Maple maplelmg 2000.0831 permanent 1 XXXXXXXXXXXX \
+ PLATFORMS=i86_r ISSUER="Waterloo Maple Inc." \
+ ISSUED=11-may-2000 NOTICE=" Technische Universitat Wien" \
+ SN=XXXXXXXXX</programlisting>
+
+ <note><para>Serial number and key 'X''ed out. <systemitem>chillig</systemitem> is a
+ hostname.</para></note>
+
+ <para>Editing the license file works as long as you do not
+ touch the <quote>FEATURE</quote> line (which is protected by the
+ license key).</para></listitem>
+ </itemizedlist>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="linuxemu-matlab">
+ <info><title>Installing &matlab;</title>
+ <authorgroup>
+ <author><personname><firstname>Dan</firstname><surname>Pelleg</surname></personname><contrib>Contributed by </contrib></author>
+ <!-- daniel+handbook@pelleg.org -->
+ </authorgroup>
+ </info>
+
+
+ <indexterm>
+ <primary>applications</primary>
+ <secondary><application>MATLAB</application></secondary>
+ </indexterm>
+
+ <para>This document describes the process of installing the Linux
+ version of <application>&matlab; version 6.5</application> onto
+ a &os; system. It works quite well, with the exception of the
+ <application>&java.virtual.machine;</application> (see
+ <xref linkend="matlab-jre"/>).</para>
+
+ <para>The Linux version of <application>&matlab;</application> can be
+ ordered directly from The MathWorks at <uri xlink:href="http://www.mathworks.com">http://www.mathworks.com</uri>. Make sure you also get
+ the license file or instructions how to create it. While you
+ are there, let them know you would like a native &os;
+ version of their software.</para>
+
+ <sect2>
+ <title>Installing &matlab;</title>
+
+ <para>To install <application>&matlab;</application>, do the
+ following:</para>
+
+ <procedure>
+ <step>
+ <para>Insert the installation CD and mount it.
+ Become <systemitem class="username">root</systemitem>, as recommended by the
+ installation script. To start the installation script
+ type:</para>
+
+ <screen>&prompt.root; <userinput>/compat/linux/bin/sh /cdrom/install</userinput></screen>
+
+ <tip>
+ <para>The installer is graphical. If you get errors about
+ not being able to open a display, type
+ <command>setenv HOME ~USER</command>,
+ where <replaceable>USER</replaceable> is the user you did a
+ &man.su.1; as.</para>
+ </tip>
+ </step>
+
+ <step>
+ <para>
+ When asked for the <application>&matlab;</application> root
+ directory, type:
+ <userinput>/compat/linux/usr/local/matlab</userinput>.</para>
+
+ <tip>
+ <para>For easier typing on the rest of the installation
+ process, type this at your shell prompt:
+ <command>set MATLAB=/compat/linux/usr/local/matlab</command></para>
+ </tip>
+ </step>
+
+ <step>
+ <para>Edit the license file as instructed when
+ obtaining the <application>&matlab;</application> license.</para>
+
+ <tip>
+ <para>You can prepare this file in advance using your
+ favorite editor, and copy it to
+ <filename>$MATLAB/license.dat</filename> before the
+ installer asks you to edit it.</para>
+ </tip>
+ </step>
+
+ <step>
+ <para>Complete the installation process.</para>
+ </step>
+ </procedure>
+
+ <para>At this point your <application>&matlab;</application>
+ installation is complete. The following steps apply
+ <quote>glue</quote> to connect it to your &os; system.</para>
+ </sect2>
+
+ <sect2>
+ <title>License Manager Startup</title>
+ <procedure>
+ <step>
+ <para>Create symlinks for the license manager scripts:</para>
+
+ <screen>&prompt.root; <userinput>ln -s $MATLAB/etc/lmboot /usr/local/etc/lmboot_TMW</userinput>
+&prompt.root; <userinput>ln -s $MATLAB/etc/lmdown /usr/local/etc/lmdown_TMW</userinput></screen>
+ </step>
+
+ <step>
+ <para>Create a startup file at
+ <filename>/usr/local/etc/rc.d/flexlm.sh</filename>. The
+ example below is a modified version of the distributed
+ <filename>$MATLAB/etc/rc.lm.glnx86</filename>. The changes
+ are file locations, and startup of the license manager
+ under Linux emulation.</para>
+
+ <programlisting>#!/bin/sh
+case "$1" in
+ start)
+ if [ -f /usr/local/etc/lmboot_TMW ]; then
+ /compat/linux/bin/sh /usr/local/etc/lmboot_TMW -u <replaceable>username</replaceable> &amp;&amp; echo 'MATLAB_lmgrd'
+ fi
+ ;;
+ stop)
+ if [ -f /usr/local/etc/lmdown_TMW ]; then
+ /compat/linux/bin/sh /usr/local/etc/lmdown_TMW &gt; /dev/null 2&gt;&amp;1
+ fi
+ ;;
+ *)
+ echo "Usage: $0 {start|stop}"
+ exit 1
+ ;;
+esac
+
+exit 0</programlisting>
+
+ <important>
+ <para>The file must be made executable:</para>
+
+ <screen>&prompt.root; <userinput>chmod +x /usr/local/etc/rc.d/flexlm.sh</userinput></screen>
+
+ <para>You must also replace
+ <replaceable>username</replaceable> above with the name
+ of a valid user on your system (and not
+ <systemitem class="username">root</systemitem>).</para>
+ </important>
+ </step>
+
+ <step>
+ <para>Start the license manager with the command:</para>
+
+ <screen>&prompt.root; <userinput>/usr/local/etc/rc.d/flexlm.sh start</userinput></screen>
+ </step>
+ </procedure>
+ </sect2>
+
+ <sect2 xml:id="matlab-jre">
+ <title>Linking the &java; Runtime Environment</title>
+
+ <para>Change the <application>&java;</application> Runtime
+ Environment (JRE) link to one working under &os;:</para>
+
+ <screen>&prompt.root; <userinput>cd $MATLAB/sys/java/jre/glnx86/</userinput>
+&prompt.root; <userinput>unlink jre; ln -s ./jre1.1.8 ./jre</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Creating a &matlab; Startup Script</title>
+
+ <procedure>
+ <step>
+ <para>Place the following startup script in
+ <filename>/usr/local/bin/matlab</filename>:
+ </para>
+
+ <programlisting>#!/bin/sh
+/compat/linux/bin/sh /compat/linux/usr/local/matlab/bin/matlab "$@"</programlisting>
+ </step>
+
+ <step>
+ <para>Then type the command
+ <command>chmod +x /usr/local/bin/matlab</command>.</para>
+ </step>
+ </procedure>
+
+ <tip>
+ <para>Depending on your version of
+ <package>emulators/linux_base</package>, you
+ may run into errors when running this script. To avoid that,
+ edit the file
+ <filename>/compat/linux/usr/local/matlab/bin/matlab</filename>,
+ and change the line that says:</para>
+
+ <programlisting>if [ `expr "$lscmd" : '.*-&gt;.*'` -ne 0 ]; then</programlisting>
+
+ <para>(in version 13.0.1 it is on line 410) to this
+ line:</para>
+
+ <programlisting>if test -L $newbase; then</programlisting>
+ </tip>
+ </sect2>
+
+ <sect2>
+ <title>Creating a &matlab; Shutdown Script</title>
+
+ <para>The following is needed to solve a problem with &matlab;
+ not exiting correctly.</para>
+
+ <procedure>
+ <step>
+ <para>Create a file
+ <filename>$MATLAB/toolbox/local/finish.m</filename>, and
+ in it put the single line:</para>
+
+ <programlisting>! $MATLAB/bin/finish.sh</programlisting>
+
+ <note><para>The <literal>$MATLAB</literal> is
+ literal.</para></note>
+
+ <tip>
+ <para>In the same directory, you will find the files
+ <filename>finishsav.m</filename> and
+ <filename>finishdlg.m</filename>, which let you save
+ your workspace before quitting. If you use either of
+ them, insert the line above immediately after the
+ <literal>save</literal> command.</para></tip>
+ </step>
+
+ <step>
+ <para>Create a file
+ <filename>$MATLAB/bin/finish.sh</filename>, which will
+ contain the following:</para>
+
+ <programlisting>#!/usr/compat/linux/bin/sh
+(sleep 5; killall -1 matlab_helper) &amp;
+exit 0</programlisting>
+ </step>
+
+ <step>
+ <para>Make the file executable:</para>
+
+ <screen>&prompt.root; <userinput>chmod +x $MATLAB/bin/finish.sh</userinput></screen>
+ </step>
+ </procedure>
+ </sect2>
+
+ <sect2 xml:id="matlab-using">
+ <title>Using &matlab;</title>
+
+ <para>At this point you are ready to type
+ <command>matlab</command> and start using it.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="linuxemu-oracle">
+ <info><title>Installing &oracle;</title>
+ <authorgroup>
+ <author><personname><firstname>Marcel</firstname><surname>Moolenaar</surname></personname><contrib>Contributed by </contrib></author>
+ <!-- marcel@cup.hp.com -->
+ </authorgroup>
+ </info>
+
+
+ <indexterm>
+ <primary>applications</primary>
+ <secondary><application>Oracle</application></secondary>
+ </indexterm>
+
+ <sect2>
+ <title>Preface</title>
+ <para>This document describes the process of installing <application>&oracle; 8.0.5</application> and
+ <application>&oracle; 8.0.5.1 Enterprise Edition</application> for Linux onto a FreeBSD
+ machine.</para>
+ </sect2>
+
+ <sect2>
+ <title>Installing the Linux Environment</title>
+
+ <para>Make sure you have both <package>emulators/linux_base</package> and
+ <package>devel/linux_devtools</package> from the Ports Collection
+ installed. If you run into difficulties with these ports,
+ you may have to use
+ the packages or older versions available in the Ports Collection.</para>
+
+ <para>If you want to run the intelligent agent, you will
+ also need to install the Red Hat Tcl package:
+ <filename>tcl-8.0.3-20.i386.rpm</filename>. The general command
+ for installing packages with the official <application>RPM</application> port (<package>archivers/rpm</package>) is:</para>
+
+ <screen>&prompt.root; <userinput>rpm -i --ignoreos --root /compat/linux --dbpath /var/lib/rpm package</userinput></screen>
+
+ <para>Installation of the <replaceable>package</replaceable> should not generate any errors.</para>
+ </sect2>
+
+ <sect2>
+ <title>Creating the &oracle; Environment</title>
+
+ <para>Before you can install <application>&oracle;</application>, you need to set up a proper
+ environment. This document only describes what to do
+ <emphasis>specially</emphasis> to run <application>&oracle;</application> for Linux on FreeBSD, not
+ what has been described in the <application>&oracle;</application> installation guide.</para>
+
+ <sect3 xml:id="linuxemu-kernel-tuning">
+ <title>Kernel Tuning</title>
+ <indexterm><primary>kernel tuning</primary></indexterm>
+
+ <para>As described in the <application>&oracle;</application> installation guide, you need to set
+ the maximum size of shared memory. Do not use
+ <literal>SHMMAX</literal> under FreeBSD. <literal>SHMMAX</literal>
+ is merely calculated out of <literal>SHMMAXPGS</literal> and
+ <literal>PGSIZE</literal>. Therefore define
+ <literal>SHMMAXPGS</literal>. All other options can be used as
+ described in the guide. For example:</para>
+
+ <programlisting>options SHMMAXPGS=10000
+options SHMMNI=100
+options SHMSEG=10
+options SEMMNS=200
+options SEMMNI=70
+options SEMMSL=61</programlisting>
+
+ <para>Set these options to suit your intended use of <application>&oracle;</application>.</para>
+
+ <para>Also, make sure you have the following options in your kernel
+ configuration file:</para>
+
+<programlisting>options SYSVSHM #SysV shared memory
+options SYSVSEM #SysV semaphores
+options SYSVMSG #SysV interprocess communication</programlisting>
+ </sect3>
+
+ <sect3 xml:id="linuxemu-oracle-account">
+
+ <title>&oracle; Account</title>
+
+ <para>Create an <systemitem class="username">oracle</systemitem> account just as you would create any other
+ account. The <systemitem class="username">oracle</systemitem> account is special only that you need to give
+ it a Linux shell. Add <literal>/compat/linux/bin/bash</literal> to
+ <filename>/etc/shells</filename> and set the shell for the <systemitem class="username">oracle</systemitem>
+ account to <filename>/compat/linux/bin/bash</filename>.</para>
+ </sect3>
+
+ <sect3 xml:id="linuxemu-environment">
+ <title>Environment</title>
+
+ <para>Besides the normal <application>&oracle;</application> variables, such as
+ <envar>ORACLE_HOME</envar> and <envar>ORACLE_SID</envar> you must
+ set the following environment variables:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Variable</entry>
+
+ <entry>Value</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><envar>LD_LIBRARY_PATH</envar></entry>
+
+ <entry><literal>$ORACLE_HOME/lib</literal></entry>
+ </row>
+
+ <row>
+ <entry><envar>CLASSPATH</envar></entry>
+
+ <entry><literal>$ORACLE_HOME/jdbc/lib/classes111.zip</literal></entry>
+ </row>
+
+ <row>
+ <entry><envar>PATH</envar></entry>
+
+ <entry><literal>/compat/linux/bin
+/compat/linux/sbin
+/compat/linux/usr/bin
+/compat/linux/usr/sbin
+/bin
+/sbin
+/usr/bin
+/usr/sbin
+/usr/local/bin
+$ORACLE_HOME/bin</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>It is advised to set all the environment variables in
+ <filename>.profile</filename>. A complete example is:</para>
+
+<programlisting>ORACLE_BASE=/oracle; export ORACLE_BASE
+ORACLE_HOME=/oracle; export ORACLE_HOME
+LD_LIBRARY_PATH=$ORACLE_HOME/lib
+export LD_LIBRARY_PATH
+ORACLE_SID=ORCL; export ORACLE_SID
+ORACLE_TERM=386x; export ORACLE_TERM
+CLASSPATH=$ORACLE_HOME/jdbc/lib/classes111.zip
+export CLASSPATH
+PATH=/compat/linux/bin:/compat/linux/sbin:/compat/linux/usr/bin
+PATH=$PATH:/compat/linux/usr/sbin:/bin:/sbin:/usr/bin:/usr/sbin
+PATH=$PATH:/usr/local/bin:$ORACLE_HOME/bin
+export PATH</programlisting>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Installing &oracle;</title>
+
+ <para>Due to a slight inconsistency in the Linux emulator, you need to
+ create a directory named <filename>.oracle</filename> in
+ <filename>/var/tmp</filename> before you start the installer.
+ Let it be owned by the <systemitem class="username">oracle</systemitem> user. You
+ should be able to install <application>&oracle;</application> without any problems. If you have
+ problems, check your <application>&oracle;</application> distribution and/or configuration first!
+ After you have installed <application>&oracle;</application>, apply the patches described in the
+ next two subsections.</para>
+
+ <para>A frequent problem is that the TCP protocol adapter is not
+ installed right. As a consequence, you cannot start any TCP listeners.
+ The following actions help solve this problem:</para>
+
+ <screen>&prompt.root; <userinput>cd $ORACLE_HOME/network/lib</userinput>
+&prompt.root; <userinput>make -f ins_network.mk ntcontab.o</userinput>
+&prompt.root; <userinput>cd $ORACLE_HOME/lib</userinput>
+&prompt.root; <userinput>ar r libnetwork.a ntcontab.o</userinput>
+&prompt.root; <userinput>cd $ORACLE_HOME/network/lib</userinput>
+&prompt.root; <userinput>make -f ins_network.mk install</userinput></screen>
+
+ <para>Do not forget to run <filename>root.sh</filename> again!</para>
+
+ <sect3 xml:id="linuxemu-patch-root">
+ <title>Patching root.sh</title>
+
+ <para>When installing <application>&oracle;</application>, some actions, which need to be performed
+ as <systemitem class="username">root</systemitem>, are recorded in a shell script called
+ <filename>root.sh</filename>. This script is
+ written in the <filename>orainst</filename> directory. Apply the
+ following patch to <filename>root.sh</filename>, to have it use to proper location of
+ <command>chown</command> or alternatively run the script under a
+ Linux native shell.</para>
+
+ <programlisting>*** orainst/root.sh.orig Tue Oct 6 21:57:33 1998
+--- orainst/root.sh Mon Dec 28 15:58:53 1998
+***************
+*** 31,37 ****
+# This is the default value for CHOWN
+# It will redefined later in this script for those ports
+# which have it conditionally defined in ss_install.h
+! CHOWN=/bin/chown
+#
+# Define variables to be used in this script
+--- 31,37 ----
+# This is the default value for CHOWN
+# It will redefined later in this script for those ports
+# which have it conditionally defined in ss_install.h
+! CHOWN=/usr/sbin/chown
+#
+# Define variables to be used in this script</programlisting>
+
+ <para>When you do not install <application>&oracle;</application> from CD, you can patch the source
+ for <filename>root.sh</filename>. It is called
+ <filename>rthd.sh</filename> and is located in the
+ <filename>orainst</filename> directory in the source tree.</para>
+ </sect3>
+
+ <sect3 xml:id="linuxemu-patch-tcl">
+ <title>Patching genclntsh</title>
+
+ <para>The script <command>genclntsh</command> is used to create
+ a single shared client
+ library. It is used when building the demos. Apply the following
+ patch to comment out the definition of <envar>PATH</envar>:</para>
+
+ <programlisting>*** bin/genclntsh.orig Wed Sep 30 07:37:19 1998
+--- bin/genclntsh Tue Dec 22 15:36:49 1998
+***************
+*** 32,38 ****
+#
+# Explicit path to ensure that we're using the correct commands
+#PATH=/usr/bin:/usr/ccs/bin export PATH
+! PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin export PATH
+#
+# each product MUST provide a $PRODUCT/admin/shrept.lst
+--- 32,38 ----
+#
+# Explicit path to ensure that we're using the correct commands
+#PATH=/usr/bin:/usr/ccs/bin export PATH
+! #PATH=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin export PATH
+#
+# each product MUST provide a $PRODUCT/admin/shrept.lst</programlisting>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Running &oracle;</title>
+
+ <para>When you have followed the instructions, you should be able to run
+ <application>&oracle;</application> as if it was run on Linux
+ itself.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="sapr3">
+ <info><title>Installing &sap.r3;</title>
+ <authorgroup>
+ <author><personname><firstname>Holger</firstname><surname>Kipp</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ <authorgroup>
+ <author><personname><firstname>Valentino</firstname><surname>Vaschetto</surname></personname><contrib>Original version converted to SGML by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm>
+ <primary>applications</primary>
+ <secondary><application>SAP R/3</application></secondary>
+ </indexterm>
+
+ <para>Installations of <application>&sap;</application> Systems using FreeBSD will not be
+ supported by the &sap; support team &mdash; they only offer support
+ for certified platforms.</para>
+
+ <sect2 xml:id="preface">
+ <title>Preface</title>
+
+ <para>This document describes a possible way of installing a
+ <application>&sap.r3; System</application>
+ with <application>&oracle; Database</application>
+ for Linux onto a FreeBSD machine, including the installation
+ of FreeBSD and <application>&oracle;</application>. Two different
+ configurations will be described:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><application>&sap.r3; 4.6B (IDES)</application> with
+ <application>&oracle; 8.0.5</application> on FreeBSD 4.3-STABLE</para>
+ </listitem>
+
+ <listitem>
+ <para><application>&sap.r3; 4.6C</application> with
+ <application>&oracle; 8.1.7</application> on FreeBSD 4.5-STABLE</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Even though this document tries to describe all important
+ steps in a greater detail, it is not intended as a replacement
+ for the <application>&oracle;</application> and
+ <application>&sap.r3;</application> installation guides.</para>
+
+ <para>Please see the documentation that comes with the
+ <application>&sap.r3;</application>
+ Linux edition for <application>&sap;</application> and
+ <application>&oracle;</application> specific questions, as well
+ as resources from <application>&oracle;</application> and
+ <application>&sap; OSS</application>.</para>
+ </sect2>
+
+ <sect2 xml:id="software">
+ <title>Software</title>
+
+ <para>The following CD-ROMs have been used for <application>&sap;</application> installations:</para>
+
+ <sect3 xml:id="software-46b">
+ <title>&sap.r3; 4.6B, &oracle; 8.0.5</title>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry> <entry>Number</entry> <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>KERNEL</entry> <entry>51009113</entry> <entry>SAP Kernel Oracle /
+ Installation / AIX, Linux, Solaris</entry>
+ </row>
+
+ <row>
+ <entry>RDBMS</entry> <entry>51007558</entry> <entry>Oracle / RDBMS 8.0.5.X /
+ Linux</entry>
+ </row>
+
+ <row>
+ <entry>EXPORT1</entry> <entry>51010208</entry> <entry>IDES / DB-Export /
+ Disc 1 of 6</entry>
+ </row>
+
+ <row>
+ <entry>EXPORT2</entry> <entry>51010209</entry> <entry>IDES / DB-Export /
+ Disc 2 of 6</entry>
+ </row>
+
+ <row>
+ <entry>EXPORT3</entry> <entry>51010210</entry> <entry>IDES / DB-Export /
+ Disc 3 of 6</entry>
+ </row>
+
+ <row>
+ <entry>EXPORT4</entry> <entry>51010211</entry> <entry>IDES / DB-Export /
+ Disc 4 of 6</entry>
+ </row>
+
+ <row>
+ <entry>EXPORT5</entry> <entry>51010212</entry> <entry>IDES / DB-Export /
+ Disc 5 of 6</entry>
+ </row>
+
+ <row>
+ <entry>EXPORT6</entry> <entry>51010213</entry> <entry>IDES / DB-Export /
+ Disc 6 of 6</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>Additionally, we used the <application>&oracle; 8
+ Server</application> (Pre-production version 8.0.5 for Linux,
+ Kernel Version 2.0.33) CD which is not really necessary, and
+ FreeBSD 4.3-STABLE (it was only a few days past 4.3
+ RELEASE).</para>
+
+ </sect3>
+ <sect3 xml:id="software-46c">
+ <title>&sap.r3; 4.6C SR2, &oracle; 8.1.7</title>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry> <entry>Number</entry> <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>KERNEL</entry> <entry>51014004</entry> <entry>SAP Kernel Oracle /
+ SAP Kernel Version 4.6D / DEC, Linux</entry>
+ </row>
+
+ <row>
+ <entry>RDBMS</entry> <entry>51012930</entry> <entry>Oracle 8.1.7/ RDBMS /
+ Linux</entry>
+ </row>
+
+ <row>
+ <entry>EXPORT1</entry> <entry>51013953</entry> <entry>Release 4.6C SR2 / Export
+ / Disc 1 of 4</entry>
+ </row>
+
+ <row>
+ <entry>EXPORT1</entry> <entry>51013953</entry> <entry>Release 4.6C SR2 / Export
+ / Disc 2 of 4</entry>
+ </row>
+
+ <row>
+ <entry>EXPORT1</entry> <entry>51013953</entry> <entry>Release 4.6C SR2 / Export
+ / Disc 3 of 4</entry>
+ </row>
+
+ <row>
+ <entry>EXPORT1</entry> <entry>51013953</entry> <entry>Release 4.6C SR2 / Export
+ / Disc 4 of 4</entry>
+ </row>
+
+ <row>
+ <entry>LANG1</entry> <entry>51013954</entry> <entry>Release 4.6C SR2 /
+ Language / DE, EN, FR / Disc 1 of 3</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>Depending on the languages you would like to install, additional
+ language CDs might be necessary. Here we are just using DE and EN, so
+ the first language CD is the only one needed. As a little note, the
+ numbers for all four EXPORT CDs are identical. All three language CDs
+ also have the same number (this is different from the 4.6B IDES
+ release CD numbering). At the time of writing this installation is
+ running on FreeBSD 4.5-STABLE (20.03.2002).</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="sap-notes">
+ <title>&sap; Notes</title>
+
+ <para>The following notes should be read before installing
+ <application>&sap.r3;</application> and proved to be useful
+ during installation:</para>
+
+ <sect3 xml:id="sap-notes-46b">
+ <title>&sap.r3; 4.6B, &oracle; 8.0.5</title>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Number</entry>
+ <entry>Title</entry>
+ </row>
+ </thead>
+ <tbody>
+
+ <row>
+ <entry>0171356</entry> <entry>SAP Software on Linux: Essential
+ Comments</entry>
+ </row>
+
+ <row>
+ <entry>0201147</entry> <entry>INST: 4.6C R/3 Inst. on UNIX -
+ Oracle</entry>
+ </row>
+
+ <row>
+ <entry>0373203</entry> <entry>Update / Migration Oracle 8.0.5 --&gt;
+ 8.0.6/8.1.6 LINUX</entry>
+ </row>
+
+ <row>
+ <entry>0072984</entry> <entry>Release of Digital UNIX 4.0B for
+ Oracle</entry>
+ </row>
+
+ <row>
+ <entry>0130581</entry> <entry>R3SETUP step DIPGNTAB terminates</entry>
+ </row>
+
+ <row>
+ <entry>0144978</entry> <entry>Your system has not been installed
+ correctly</entry>
+ </row>
+
+ <row>
+ <entry>0162266</entry> <entry>Questions and tips for R3SETUP on Windows
+ NT / W2K</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+
+ <sect3 xml:id="sap-notes-46c">
+ <title>&sap.r3; 4.6C, &oracle; 8.1.7</title>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Number</entry>
+ <entry>Title</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>0015023</entry> <entry>Initializing table TCPDB (RSXP0004)
+ (EBCDIC)</entry>
+ </row>
+
+ <row>
+ <entry>0045619</entry> <entry>R/3 with several languages or
+ typefaces</entry>
+ </row>
+
+ <row>
+ <entry>0171356</entry> <entry>SAP Software on Linux: Essential
+ Comments</entry>
+ </row>
+
+ <row>
+ <entry>0195603</entry> <entry>RedHat 6.1 Enterprise version:
+ Known problems</entry>
+ </row>
+
+ <row>
+ <entry>0212876</entry> <entry>The new archiving tool SAPCAR</entry>
+ </row>
+
+ <row>
+ <entry>0300900</entry> <entry>Linux: Released DELL Hardware</entry>
+ </row>
+
+ <row>
+ <entry>0377187</entry> <entry>RedHat 6.2: important remarks</entry>
+ </row>
+
+ <row>
+ <entry>0387074</entry> <entry>INST: R/3 4.6C SR2 Installation on
+ UNIX</entry>
+ </row>
+
+ <row>
+ <entry>0387077</entry> <entry>INST: R/3 4.6C SR2 Inst. on UNIX -
+ Oracle</entry>
+ </row>
+
+ <row>
+ <entry>0387078</entry> <entry>SAP Software on UNIX: OS Dependencies
+ 4.6C SR2</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="hardware-requirements">
+ <title>Hardware Requirements</title>
+
+ <para>The following equipment is sufficient for the installation
+ of a <application>&sap.r3; System</application>. For production
+ use, a more exact sizing is of course needed:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Component</entry>
+ <entry>4.6B</entry>
+ <entry>4.6C</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Processor</entry>
+ <entry>2 x 800MHz &pentium; III</entry>
+ <entry>2 x 800MHz &pentium; III</entry>
+ </row>
+
+ <row>
+ <entry>Memory</entry>
+ <entry>1GB ECC</entry>
+ <entry>2GB ECC</entry>
+ </row>
+
+ <row>
+ <entry>Hard Disk Space</entry>
+ <entry>50-60GB (IDES)</entry>
+ <entry>50-60GB (IDES)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>For use in production, &xeon; Processors with large cache,
+ high-speed disk access (SCSI, RAID hardware controller), USV
+ and ECC-RAM is recommended. The large amount of hard disk
+ space is due to the preconfigured IDES System, which creates
+ 27&nbsp;GB of database files during installation. This space is
+ also sufficient for initial production systems and application
+ data.</para>
+
+ <sect3 xml:id="hardware-46b">
+ <title>&sap.r3; 4.6B, &oracle; 8.0.5</title>
+
+ <para>The following off-the-shelf hardware was used: a dual processor
+ board with 2 800&nbsp;MHz &pentium;&nbsp;III processors, &adaptec; 29160 Ultra160
+ SCSI adapter (for accessing a 40/80&nbsp;GB DLT tape drive and CDROM),
+ &mylex; &acceleraid; (2 channels, firmware 6.00-1-00 with 32&nbsp;MB RAM).
+ To the &mylex; RAID controller are attached two 17&nbsp;GB hard disks
+ (mirrored) and four 36&nbsp;GB hard disks (RAID level 5).</para>
+ </sect3>
+
+ <sect3 xml:id="hardware-46c">
+ <title>&sap.r3; 4.6C, &oracle; 8.1.7</title>
+
+ <para>For this installation a &dell; &poweredge; 2500 was used: a
+ dual processor board with two 1000&nbsp;MHz &pentium;&nbsp;III processors
+ (256&nbsp;kB Cache), 2&nbsp;GB PC133 ECC SDRAM, PERC/3 DC PCI RAID Controller
+ with 128&nbsp;MB, and an EIDE DVD-ROM drive. To the RAID controller are
+ attached two 18&nbsp;GB hard disks (mirrored) and four 36&nbsp;GB hard disks
+ (RAID level 5).</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="installation">
+ <title>Installation of FreeBSD</title>
+
+ <para>First you have to install FreeBSD. There are several ways to do
+ this, for more information read the <xref linkend="install-diff-media"/>.</para>
+
+ <sect3 xml:id="disk-layout">
+ <title>Disk Layout</title>
+
+ <para>To keep it simple, the same disk layout both for the
+ <application>&sap.r3; 46B</application> and <application>&sap.r3; 46C
+ SR2</application> installation was used. Only the device names
+ changed, as the installations were on different hardware (<filename>/dev/da</filename>
+ and <filename>/dev/amr</filename> respectively, so if using an AMI &megaraid;, one will see
+ <filename>/dev/amr0s1a</filename> instead of <filename>/dev/da0s1a</filename>):</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>File system</entry>
+ <entry>Size (1k-blocks)</entry>
+ <entry>Size (GB)</entry>
+ <entry>Mounted on</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><filename>/dev/da0s1a</filename></entry>
+ <entry>1.016.303</entry>
+ <entry>1</entry>
+ <entry><filename>/</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>/dev/da0s1b</filename></entry>
+ <entry> </entry>
+ <entry>6</entry>
+ <entry>swap</entry>
+ </row>
+
+ <row>
+ <entry><filename>/dev/da0s1e</filename></entry>
+ <entry>2.032.623</entry>
+ <entry>2</entry>
+ <entry><filename>/var</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>/dev/da0s1f</filename></entry>
+ <entry>8.205.339</entry>
+ <entry>8</entry>
+ <entry><filename>/usr</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>/dev/da1s1e</filename></entry>
+ <entry>45.734.361</entry>
+ <entry>45</entry>
+ <entry><filename>/compat/linux/oracle</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>/dev/da1s1f</filename></entry>
+ <entry>2.032.623</entry>
+ <entry>2</entry>
+ <entry><filename>/compat/linux/sapmnt</filename></entry>
+ </row>
+
+ <row>
+ <entry><filename>/dev/da1s1g</filename></entry>
+ <entry>2.032.623</entry>
+ <entry>2</entry>
+ <entry><filename>/compat/linux/usr/sap</filename></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>Configure and initialize the two logical drives
+ with the &mylex; or PERC/3 RAID software beforehand.
+ The software can be started during the
+ <acronym>BIOS</acronym> boot phase.</para>
+
+ <para> Please note that this disk layout differs slightly from
+ the &sap; recommendations, as &sap; suggests mounting the
+ <application>&oracle;</application> subdirectories (and some others) separately &mdash; we
+ decided to just create them as real subdirectories for
+ simplicity.</para>
+ </sect3>
+
+ <sect3 xml:id="makeworldandnewkernel">
+ <title><command>make world</command> and a New Kernel</title>
+
+ <para>Download the latest -STABLE sources. Rebuild world and your
+ custom kernel after configuring your kernel configuration file.
+ Here you should also include the
+ <link linkend="kerneltuning">kernel parameters</link>
+ which are required for both <application>&sap.r3;</application>
+ and <application>&oracle;</application>.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="installingthelinuxenviornment">
+ <title>Installing the Linux Environment</title>
+
+ <sect3 xml:id="installinglinuxbase-system">
+ <title>Installing the Linux Base System</title>
+
+ <para>First the <link linkend="linuxemu-libs-port">linux_base</link>
+ port needs to be installed (as <systemitem class="username">root</systemitem>):</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/emulators/linux_base</userinput>
+&prompt.root; <userinput>make install distclean</userinput></screen>
+
+ </sect3>
+
+
+ <sect3 xml:id="installinglinuxdevelopment">
+ <title>Installing Linux Development Environment</title>
+
+ <para>The Linux development environment is needed, if you want to install
+ <application>&oracle;</application> on FreeBSD according to the
+ <xref linkend="linuxemu-oracle"/>:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/devel/linux_devtools</userinput>
+&prompt.root; <userinput>make install distclean</userinput></screen>
+
+ <para>The Linux development environment has only been installed for the <application>&sap.r3;
+ 46B IDES</application> installation. It is not needed, if
+ the <application>&oracle; DB</application> is not relinked on the
+ FreeBSD system. This is the case if you are using the
+ <application>&oracle;</application> tarball from a Linux system.</para>
+
+ </sect3>
+
+
+ <sect3 xml:id="installingnecessaryrpms">
+ <title>Installing the Necessary RPMs</title>
+ <indexterm><primary>RPMs</primary></indexterm>
+
+ <para>To start the <command>R3SETUP</command> program, PAM support is needed.
+ During the first <application>&sap;</application> Installation on FreeBSD 4.3-STABLE we
+ tried to install PAM with all the required packages and
+ finally forced the installation of the PAM package, which
+ worked. For <application>&sap.r3; 4.6C SR2</application> we
+ directly forced the installation of the PAM RPM, which also
+ works, so it seems the dependent packages are not needed:</para>
+
+
+<screen>&prompt.root; <userinput>rpm -i --ignoreos --nodeps --root /compat/linux --dbpath /var/lib/rpm \
+pam-0.68-7.i386.rpm</userinput></screen>
+
+ <para>For <application>&oracle; 8.0.5</application> to run the
+ intelligent agent, we also had to install the RedHat Tcl package
+ <filename>tcl-8.0.5-30.i386.rpm</filename> (otherwise the
+ relinking during <application>&oracle;</application> installation
+ will not work). There are some other issues regarding
+ relinking of <application>&oracle;</application>, but that is
+ a <application>&oracle;</application> Linux issue, not FreeBSD specific.</para>
+
+ </sect3>
+
+ <sect3 xml:id="linuxprocandfallbackelfbrand">
+ <title>Some Additional Hints</title>
+
+ <para>It might also be a good idea to add <literal>linprocfs</literal>
+ to <filename>/etc/fstab</filename>, for more information, see the &man.linprocfs.5; manual page.
+ Another parameter to set is <literal>kern.fallback_elf_brand=3</literal>
+ which is done in the file <filename>/etc/sysctl.conf</filename>.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="creatingsapr3env">
+ <title>Creating the &sap.r3; Environment</title>
+
+ <sect3 xml:id="filesystemsandmountpoints">
+ <title>Creating the Necessary File Systems and Mountpoints</title>
+
+ <para>For a simple installation, it is sufficient to create the
+ following file systems:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>mount point</entry>
+ <entry>size in GB</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><filename>/compat/linux/oracle</filename></entry>
+ <entry>45 GB</entry>
+ </row>
+
+ <row>
+ <entry><filename>/compat/linux/sapmnt</filename></entry>
+ <entry>2 GB</entry>
+ </row>
+
+ <row>
+ <entry><filename>/compat/linux/usr/sap</filename></entry>
+ <entry>2 GB</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>It is also necessary to created some links. Otherwise
+ the <application>&sap;</application> Installer will complain, as it is checking the
+ created links:</para>
+
+ <screen>&prompt.root; <userinput>ln -s /compat/linux/oracle /oracle</userinput>
+&prompt.root; <userinput>ln -s /compat/linux/sapmnt /sapmnt</userinput>
+&prompt.root; <userinput>ln -s /compat/linux/usr/sap /usr/sap</userinput></screen>
+
+ <para>Possible error message during installation (here with
+ System <emphasis>PRD</emphasis> and the
+ <application>&sap.r3; 4.6C SR2</application>
+ installation):</para>
+
+ <screen>INFO 2002-03-19 16:45:36 R3LINKS_IND_IND SyLinkCreate:200
+ Checking existence of symbolic link /usr/sap/PRD/SYS/exe/dbg to
+ /sapmnt/PRD/exe. Creating if it does not exist...
+
+WARNING 2002-03-19 16:45:36 R3LINKS_IND_IND SyLinkCreate:400
+ Link /usr/sap/PRD/SYS/exe/dbg exists but it points to file
+ /compat/linux/sapmnt/PRD/exe instead of /sapmnt/PRD/exe. The
+ program cannot go on as long as this link exists at this
+ location. Move the link to another location.
+
+ERROR 2002-03-19 16:45:36 R3LINKS_IND_IND Ins_SetupLinks:0
+ can not setup link '/usr/sap/PRD/SYS/exe/dbg' with content
+ '/sapmnt/PRD/exe'</screen>
+ </sect3>
+
+ <sect3 xml:id="creatingusersanddirectories">
+ <title>Creating Users and Directories</title>
+
+ <para><application>&sap.r3;</application> needs two users and
+ three groups. The user names depend on the
+ <application>&sap;</application> system ID (SID) which consists
+ of three letters. Some of these SIDs are reserved
+ by <application>&sap;</application> (for example
+ <literal>SAP</literal> and <literal>NIX</literal>. For a
+ complete list please see the <application>&sap;</application> documentation). For the IDES
+ installation we used <literal>IDS</literal>, for the
+ 4.6C SR2 installation <literal>PRD</literal>, as that system
+ is intended for production use. We have
+ therefore the following groups (group IDs might differ, these
+ are just the values we used with our installation):</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>group ID</entry>
+ <entry>group name</entry>
+ <entry>description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>100</entry>
+ <entry>dba</entry>
+ <entry>Data Base Administrator</entry>
+ </row>
+ <row>
+ <entry>101</entry>
+ <entry>sapsys</entry>
+ <entry>&sap; System</entry>
+ </row>
+ <row>
+ <entry>102</entry>
+ <entry>oper</entry>
+ <entry>Data Base Operator</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>For a default <application>&oracle;</application> installation, only group
+ <systemitem class="groupname">dba</systemitem> is used. As
+ <systemitem class="groupname">oper</systemitem> group, one also uses group
+ <systemitem class="groupname">dba</systemitem> (see <application>&oracle;</application> and
+ <application>&sap;</application> documentation for further information).</para>
+
+ <para>We also need the following users:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="6">
+ <thead>
+ <row>
+ <entry>user ID</entry>
+ <entry>user name</entry>
+ <entry>generic name</entry>
+ <entry>group</entry>
+ <entry>additional groups</entry>
+ <entry>description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>1000</entry>
+ <entry>idsadm/prdadm</entry>
+ <entry><replaceable>sid</replaceable>adm</entry>
+ <entry>sapsys</entry>
+ <entry>oper</entry>
+ <entry>&sap; Administrator</entry>
+ </row>
+ <row>
+ <entry>1002</entry>
+ <entry>oraids/oraprd</entry>
+ <entry>ora<replaceable>sid</replaceable></entry>
+ <entry>dba</entry>
+ <entry>oper</entry>
+ <entry>&oracle; Administrator</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>Adding the users with &man.adduser.8;
+ requires the following (please note shell and home
+ directory) entries for <quote>&sap; Administrator</quote>:</para>
+
+ <programlisting>Name: <replaceable>sid</replaceable>adm
+Password: ******
+Fullname: SAP Administrator <replaceable>SID</replaceable>
+Uid: 1000
+Gid: 101 (sapsys)
+Class:
+Groups: sapsys dba
+HOME: /home/<replaceable>sid</replaceable>adm
+Shell: bash (/compat/linux/bin/bash)</programlisting>
+
+ <para>and for <quote>&oracle; Administrator</quote>:</para>
+
+ <programlisting>Name: ora<replaceable>sid</replaceable>
+Password: ******
+Fullname: Oracle Administrator <replaceable>SID</replaceable>
+Uid: 1002
+Gid: 100 (dba)
+Class:
+Groups: dba
+HOME: /oracle/<replaceable>sid</replaceable>
+Shell: bash (/compat/linux/bin/bash)</programlisting>
+
+ <para>This should also include group
+ <systemitem class="groupname">oper</systemitem> in case you are using both
+ groups <systemitem class="groupname">dba</systemitem> and
+ <systemitem class="groupname">oper</systemitem>.</para>
+
+ </sect3>
+
+ <sect3 xml:id="creatingdirectories">
+ <title>Creating Directories</title>
+
+ <para>These directories are usually created as separate
+ file systems. This depends entirely on your requirements. We
+ choose to create them as simple directories, as they are all
+ located on the same RAID 5 anyway:</para>
+
+ <para>First we will set owners and rights of some directories (as
+ user <systemitem class="username">root</systemitem>):</para>
+
+ <screen>&prompt.root; <userinput>chmod 775 /oracle</userinput>
+&prompt.root; <userinput>chmod 777 /sapmnt</userinput>
+&prompt.root; <userinput>chown root:dba /oracle</userinput>
+&prompt.root; <userinput>chown sidadm:sapsys /compat/linux/usr/sap</userinput>
+&prompt.root; <userinput>chmod 775 /compat/linux/usr/sap</userinput></screen>
+
+ <para>Second we will create directories as user
+ <systemitem class="username">ora<replaceable>sid</replaceable></systemitem>. These
+ will all be subdirectories of
+ <filename>/oracle/SID</filename>:</para>
+
+ <screen>&prompt.root; <userinput>su - orasid</userinput>
+&prompt.root; <userinput>cd /oracle/SID</userinput>
+&prompt.root; <userinput>mkdir mirrlogA mirrlogB origlogA origlogB</userinput>
+&prompt.root; <userinput>mkdir sapdata1 sapdata2 sapdata3 sapdata4 sapdata5 sapdata6</userinput>
+&prompt.root; <userinput>mkdir saparch sapreorg</userinput>
+&prompt.root; <userinput>exit</userinput></screen>
+
+ <para>For the <application>&oracle; 8.1.7</application> installation
+ some additional directories are needed:</para>
+
+ <screen>&prompt.root; <userinput>su - orasid</userinput>
+&prompt.root; <userinput>cd /oracle</userinput>
+&prompt.root; <userinput>mkdir 805_32</userinput>
+&prompt.root; <userinput>mkdir client stage</userinput>
+&prompt.root; <userinput>mkdir client/80x_32</userinput>
+&prompt.root; <userinput>mkdir stage/817_32</userinput>
+&prompt.root; <userinput>cd /oracle/SID</userinput>
+&prompt.root; <userinput>mkdir 817_32</userinput></screen>
+
+ <note><para>The directory <filename>client/80x_32</filename> is used
+ with exactly this name. Do not replace the <emphasis>x</emphasis>
+ with some number or anything.</para></note>
+
+ <para>In the third step we create directories as user
+ <systemitem class="username"><replaceable>sid</replaceable>adm</systemitem>:</para>
+
+ <screen>&prompt.root; <userinput>su - sidadm</userinput>
+&prompt.root; <userinput>cd /usr/sap</userinput>
+&prompt.root; <userinput>mkdir SID</userinput>
+&prompt.root; <userinput>mkdir trans</userinput>
+&prompt.root; <userinput>exit</userinput></screen>
+ </sect3>
+
+ <sect3 xml:id="entriesinslashetcslashservices">
+ <title>Entries in <filename>/etc/services</filename></title>
+
+ <para><application>&sap.r3;</application> requires some entries in file
+ <filename>/etc/services</filename>, which will not be set
+ correctly during installation under FreeBSD. Please add the
+ following entries (you need at least those entries
+ corresponding to the instance number &mdash; in this case,
+ <literal>00</literal>. It will do no harm adding all
+ entries from <literal>00</literal> to
+ <literal>99</literal> for <literal>dp</literal>,
+ <literal>gw</literal>, <literal>sp</literal> and
+ <literal>ms</literal>). If you are going to use a <application>SAProuter</application>
+ or need to access <application>&sap;</application> OSS, you also need <literal>99</literal>,
+ as port 3299 is usually used for the <application>SAProuter</application> process on the
+ target system:</para>
+
+ <programlisting>
+sapdp00 3200/tcp # SAP Dispatcher. 3200 + Instance-Number
+sapgw00 3300/tcp # SAP Gateway. 3300 + Instance-Number
+sapsp00 3400/tcp # 3400 + Instance-Number
+sapms00 3500/tcp # 3500 + Instance-Number
+sapms<replaceable>SID</replaceable> 3600/tcp # SAP Message Server. 3600 + Instance-Number
+sapgw00s 4800/tcp # SAP Secure Gateway 4800 + Instance-Number</programlisting>
+ </sect3>
+
+ <sect3 xml:id="necessarylocales">
+ <title>Necessary Locales</title>
+ <indexterm><primary>locale</primary></indexterm>
+
+ <para><application>&sap;</application> requires at least two locales that are not part of
+ the default RedHat installation. &sap; offers the required
+ RPMs as download from their FTP server (which is only
+ accessible if you are a customer with OSS access). See note
+ 0171356 for a list of RPMs you need.</para>
+
+ <para>It is also possible to just create appropriate links
+ (for example from <emphasis>de_DE</emphasis> and
+ <emphasis>en_US</emphasis> ), but we would not recommend this
+ for a production system (so far it worked with the IDES
+ system without any problems, though). The following locales
+ are needed:</para>
+
+ <programlisting>de_DE.ISO-8859-1
+en_US.ISO-8859-1</programlisting>
+
+ <para>Create the links like this:</para>
+
+ <screen>&prompt.root; <userinput>cd /compat/linux/usr/share/locale</userinput>
+&prompt.root; <userinput>ln -s de_DE de_DE.ISO-8859-1</userinput>
+&prompt.root; <userinput>ln -s en_US en_US.ISO-8859-1</userinput></screen>
+
+ <para>If they are not present, there will be some problems
+ during the installation. If these are then subsequently
+ ignored (by setting the <literal>STATUS</literal> of the offending steps to
+ <literal>OK</literal> in file <filename>CENTRDB.R3S</filename>), it will be impossible to log onto
+ the <application>&sap;</application> system without some additional effort.</para>
+ </sect3>
+
+ <sect3 xml:id="kerneltuning">
+ <title>Kernel Tuning</title>
+ <indexterm><primary>kernel tuning</primary></indexterm>
+
+ <para><application>&sap.r3;</application> systems need a lot of resources. We therefore
+ added the following parameters to the kernel configuration file:</para>
+
+ <programlisting># Set these for memory pigs (SAP and Oracle):
+options MAXDSIZ="(1024*1024*1024)"
+options DFLDSIZ="(1024*1024*1024)"
+# System V options needed.
+options SYSVSHM #SYSV-style shared memory
+options SHMMAXPGS=262144 #max amount of shared mem. pages
+#options SHMMAXPGS=393216 #use this for the 46C inst.parameters
+options SHMMNI=256 #max number of shared memory ident if.
+options SHMSEG=100 #max shared mem.segs per process
+options SYSVMSG #SYSV-style message queues
+options MSGSEG=32767 #max num. of mes.segments in system
+options MSGSSZ=32 #size of msg-seg. MUST be power of 2
+options MSGMNB=65535 #max char. per message queue
+options MSGTQL=2046 #max amount of msgs in system
+options SYSVSEM #SYSV-style semaphores
+options SEMMNU=256 #number of semaphore UNDO structures
+options SEMMNS=1024 #number of semaphores in system
+options SEMMNI=520 #number of semaphore identifiers
+options SEMUME=100 #number of UNDO keys</programlisting>
+
+ <para>The minimum values are specified in the documentation that
+ comes from &sap;. As there is no description for Linux, see the
+ HP-UX section (32-bit) for further information. As the system
+ for the 4.6C SR2 installation has more main memory, the shared
+ segments can be larger both for <application>&sap;</application>
+ and <application>&oracle;</application>, therefore choose a larger
+ number of shared memory pages.</para>
+
+ <note><para>With the default installation of FreeBSD on &i386;,
+ leave <literal>MAXDSIZ</literal> and <literal>DFLDSIZ</literal> at 1&nbsp;GB maximum. Otherwise, strange
+ errors like <errorname>ORA-27102: out of memory</errorname> and
+ <errorname>Linux Error: 12: Cannot allocate memory</errorname>
+ might happen.</para></note>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="installingsapr3">
+ <title>Installing &sap.r3;</title>
+
+ <sect3 xml:id="preparingsapcdroms">
+ <title>Preparing &sap; CDROMs</title>
+
+ <para>There are many CDROMs to mount and unmount during the
+ installation. Assuming you have enough CDROM drives, you
+ can just mount them all. We decided to copy the CDROMs
+ contents to corresponding directories:</para>
+
+ <programlisting>/oracle/<replaceable>SID</replaceable>/sapreorg/<replaceable>cd-name</replaceable></programlisting>
+
+ <para>where <replaceable>cd-name</replaceable> was one of <filename>KERNEL</filename>,
+ <filename>RDBMS</filename>, <filename>EXPORT1</filename>,
+ <filename>EXPORT2</filename>, <filename>EXPORT3</filename>,
+ <filename>EXPORT4</filename>, <filename>EXPORT5</filename> and
+ <filename>EXPORT6</filename> for the 4.6B/IDES installation, and
+ <filename>KERNEL</filename>, <filename>RDBMS</filename>,
+ <filename>DISK1</filename>, <filename>DISK2</filename>,
+ <filename>DISK3</filename>, <filename>DISK4</filename> and
+ <filename>LANG</filename> for the 4.6C SR2 installation. All the
+ filenames on the mounted CDs should be in capital letters,
+ otherwise use the <option>-g</option> option for mounting. So use the following
+ commands:</para>
+
+ <screen>&prompt.root; <userinput>mount_cd9660 -g /dev/cd0a /mnt</userinput>
+&prompt.root; <userinput>cp -R /mnt/* /oracle/SID/sapreorg/cd-name</userinput>
+&prompt.root; <userinput>umount /mnt</userinput></screen>
+ </sect3>
+
+ <sect3 xml:id="runningtheinstall-script">
+ <title>Running the Installation Script</title>
+
+ <para>First you have to prepare an <filename>install</filename> directory:</para>
+
+ <screen>&prompt.root; <userinput>cd /oracle/SID/sapreorg</userinput>
+&prompt.root; <userinput>mkdir install</userinput>
+&prompt.root; <userinput>cd install</userinput></screen>
+
+ <para>Then the installation script is started, which will copy nearly
+ all the relevant files into the <filename>install</filename> directory:</para>
+
+ <screen>&prompt.root; <userinput>/oracle/SID/sapreorg/KERNEL/UNIX/INSTTOOL.SH</userinput></screen>
+
+ <para>The IDES installation (4.6B) comes with a fully customized
+ &sap.r3; demonstration system, so there are six instead of just three
+ EXPORT CDs. At this point the installation template
+ <filename>CENTRDB.R3S</filename> is for installing a standard
+ central instance (<application>&r3;</application> and database), not the IDES central
+ instance, so one needs to copy the corresponding <filename>CENTRDB.R3S</filename>
+ from the <filename>EXPORT1</filename> directory, otherwise <command>R3SETUP</command> will only ask
+ for three EXPORT CDs.</para>
+
+ <para>The newer <application>&sap; 4.6C SR2</application> release
+ comes with four EXPORT CDs. The parameter file that controls
+ the installation steps is <filename>CENTRAL.R3S</filename>.
+ Contrary to earlier releases there are no separate installation
+ templates for a central instance with or without database.
+ <application>&sap;</application> is using a separate template for database installation. To restart
+ the installation later it is however sufficient to restart with
+ the original file.</para>
+
+ <para>During and after installation, <application>&sap;</application> requires
+ <command>hostname</command> to return the computer name
+ only, not the fully qualified domain name. So either
+ set the hostname accordingly, or set an alias with
+ <command>alias hostname='hostname -s'</command> for
+ both <systemitem class="username">ora<replaceable>sid</replaceable></systemitem> and
+ <systemitem class="username"><replaceable>sid</replaceable>adm</systemitem> (and for
+ <systemitem class="username">root</systemitem> at least during installation
+ steps performed as <systemitem class="username">root</systemitem>). It is also
+ possible to adjust the installed <filename>.profile</filename> and <filename>.login</filename> files of
+ both users that are installed during
+ <application>&sap;</application> installation.</para>
+ </sect3>
+
+ <sect3 xml:id="startr3setup-46B">
+ <title>Start <command>R3SETUP</command> 4.6B</title>
+
+ <para>Make sure <envar>LD_LIBRARY_PATH</envar> is set correctly:</para>
+
+ <screen>&prompt.root; <userinput>export LD_LIBRARY_PATH=/oracle/IDS/lib:/sapmnt/IDS/exe:/oracle/805_32/lib</userinput></screen>
+
+ <para>Start <command>R3SETUP</command> as <systemitem class="username">root</systemitem> from
+ installation directory:</para>
+
+ <screen>&prompt.root; <userinput>cd /oracle/IDS/sapreorg/install</userinput>
+&prompt.root; <userinput>./R3SETUP -f CENTRDB.R3S</userinput></screen>
+
+ <para>The script then asks some questions (defaults in brackets,
+ followed by actual input):</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Question</entry>
+ <entry>Default</entry>
+ <entry>Input</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Enter SAP System ID</entry>
+ <entry>[C11]</entry>
+ <entry>IDS<keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter SAP Instance Number</entry>
+ <entry>[00]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter SAPMOUNT Directory</entry>
+ <entry>[/sapmnt]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter name of SAP central host</entry>
+ <entry>[troubadix.domain.de]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter name of SAP db host</entry>
+ <entry>[troubadix]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Select character set</entry>
+ <entry>[1] (WE8DEC)</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter Oracle server version (1) Oracle 8.0.5, (2) Oracle 8.0.6, (3) Oracle 8.1.5, (4) Oracle 8.1.6</entry>
+ <entry> </entry>
+ <entry>1<keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Extract Oracle Client archive</entry>
+ <entry>[1] (Yes, extract)</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter path to KERNEL CD</entry>
+ <entry>[/sapcd]</entry>
+ <entry>/oracle/IDS/sapreorg/KERNEL</entry>
+ </row>
+ <row>
+ <entry>Enter path to RDBMS CD</entry>
+ <entry>[/sapcd]</entry>
+ <entry>/oracle/IDS/sapreorg/RDBMS</entry>
+ </row>
+ <row>
+ <entry>Enter path to EXPORT1 CD</entry>
+ <entry>[/sapcd]</entry>
+ <entry>/oracle/IDS/sapreorg/EXPORT1</entry>
+ </row>
+ <row>
+ <entry>Directory to copy EXPORT1 CD</entry>
+ <entry>[/oracle/IDS/sapreorg/CD4_DIR]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter path to EXPORT2 CD</entry>
+ <entry>[/sapcd]</entry>
+ <entry>/oracle/IDS/sapreorg/EXPORT2</entry>
+ </row>
+ <row>
+ <entry>Directory to copy EXPORT2 CD</entry>
+ <entry>[/oracle/IDS/sapreorg/CD5_DIR]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter path to EXPORT3 CD</entry>
+ <entry>[/sapcd]</entry>
+ <entry>/oracle/IDS/sapreorg/EXPORT3</entry>
+ </row>
+ <row>
+ <entry>Directory to copy EXPORT3 CD</entry>
+ <entry>[/oracle/IDS/sapreorg/CD6_DIR]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter path to EXPORT4 CD</entry>
+ <entry>[/sapcd]</entry>
+ <entry>/oracle/IDS/sapreorg/EXPORT4</entry>
+ </row>
+ <row>
+ <entry>Directory to copy EXPORT4 CD</entry>
+ <entry>[/oracle/IDS/sapreorg/CD7_DIR]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter path to EXPORT5 CD</entry>
+ <entry>[/sapcd]</entry>
+ <entry>/oracle/IDS/sapreorg/EXPORT5</entry>
+ </row>
+ <row>
+ <entry>Directory to copy EXPORT5 CD</entry>
+ <entry>[/oracle/IDS/sapreorg/CD8_DIR]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter path to EXPORT6 CD</entry>
+ <entry>[/sapcd]</entry>
+ <entry>/oracle/IDS/sapreorg/EXPORT6</entry>
+ </row>
+ <row>
+ <entry>Directory to copy EXPORT6 CD</entry>
+ <entry>[/oracle/IDS/sapreorg/CD9_DIR]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter amount of RAM for SAP + DB</entry>
+ <entry> </entry>
+ <entry>850<keycap>Enter</keycap> (in Megabytes)</entry>
+ </row>
+ <row>
+ <entry>Service Entry Message Server</entry>
+ <entry>[3600]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter Group-ID of sapsys</entry>
+ <entry>[101]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter Group-ID of oper</entry>
+ <entry>[102]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter Group-ID of dba</entry>
+ <entry>[100]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter User-ID of <replaceable>sid</replaceable>adm</entry>
+ <entry>[1000]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter User-ID of ora<replaceable>sid</replaceable></entry>
+ <entry>[1002]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Number of parallel procs</entry>
+ <entry>[2]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>If you had not copied the CDs to the different locations,
+ then the <application>&sap;</application> installer cannot find the CD needed (identified
+ by the <filename>LABEL.ASC</filename> file on the CD) and would
+ then ask you to insert and mount the CD and confirm or enter
+ the mount path.</para>
+
+ <para>The <filename>CENTRDB.R3S</filename> might not be
+ error free. In our case, it requested EXPORT4 CD again but
+ indicated the correct key (6_LOCATION, then 7_LOCATION
+ etc.), so one can just continue with entering the correct
+ values.</para>
+
+ <para>Apart from some problems mentioned below, everything
+ should go straight through up to the point where the &oracle;
+ database software needs to be installed.</para>
+ </sect3>
+
+ <sect3 xml:id="startr3setup-46C">
+ <title>Start <command>R3SETUP</command> 4.6C SR2</title>
+
+ <para>Make sure <envar>LD_LIBRARY_PATH</envar> is set correctly. This is a
+ different value from the 4.6B installation with
+ <application>&oracle; 8.0.5</application>:</para>
+
+ <screen>&prompt.root; <userinput>export LD_LIBRARY_PATH=/sapmnt/PRD/exe:/oracle/PRD/817_32/lib</userinput></screen>
+
+ <para>Start <command>R3SETUP</command> as user <systemitem class="username">root</systemitem> from installation directory:</para>
+
+ <screen>&prompt.root; <userinput>cd /oracle/PRD/sapreorg/install</userinput>
+&prompt.root; <userinput>./R3SETUP -f CENTRAL.R3S</userinput></screen>
+
+ <para>The script then asks some questions (defaults in brackets,
+ followed by actual input):</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Question</entry>
+ <entry>Default</entry>
+ <entry>Input</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Enter SAP System ID</entry>
+ <entry>[C11]</entry>
+ <entry>PRD<keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter SAP Instance Number</entry>
+ <entry>[00]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter SAPMOUNT Directory</entry>
+ <entry>[/sapmnt]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter name of SAP central host</entry>
+ <entry>[majestix]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter Database System ID</entry>
+ <entry>[PRD]</entry>
+ <entry>PRD<keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter name of SAP db host</entry>
+ <entry>[majestix]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Select character set</entry>
+ <entry>[1] (WE8DEC)</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter Oracle server version (2) Oracle 8.1.7</entry>
+ <entry> </entry>
+ <entry>2<keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Extract Oracle Client archive</entry>
+ <entry>[1] (Yes, extract)</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter path to KERNEL CD</entry>
+ <entry>[/sapcd]</entry>
+ <entry>/oracle/PRD/sapreorg/KERNEL</entry>
+ </row>
+ <row>
+ <entry>Enter amount of RAM for SAP + DB</entry>
+ <entry>2044</entry>
+ <entry>1800<keycap>Enter</keycap> (in Megabytes)</entry>
+ </row>
+ <row>
+ <entry>Service Entry Message Server</entry>
+ <entry>[3600]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter Group-ID of sapsys</entry>
+ <entry>[100]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter Group-ID of oper</entry>
+ <entry>[101]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter Group-ID of dba</entry>
+ <entry>[102]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter User-ID of <systemitem class="username">oraprd</systemitem></entry>
+ <entry>[1002]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter User-ID of <systemitem class="username">prdadm</systemitem></entry>
+ <entry>[1000]</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>LDAP support</entry>
+ <entry> </entry>
+ <entry>3<keycap>Enter</keycap> (no support)</entry>
+ </row>
+ <row>
+ <entry>Installation step completed</entry>
+ <entry>[1] (continue)</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Choose installation service</entry>
+ <entry>[1] (DB inst,file)</entry>
+ <entry><keycap>Enter</keycap></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>So far, creation of users gives an error during
+ installation in phases OSUSERDBSID_IND_ORA (for creating
+ user <systemitem class="username">ora<replaceable>sid</replaceable></systemitem>) and
+ OSUSERSIDADM_IND_ORA (creating user
+ <systemitem class="username"><replaceable>sid</replaceable>adm</systemitem>).</para>
+
+ <para>Apart from some problems mentioned below, everything
+ should go straight through up to the point where the &oracle;
+ database software needs to be installed.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="installingoracle805">
+ <title>Installing &oracle; 8.0.5</title>
+
+ <para>Please see the corresponding &sap; Notes and &oracle; <filename>Readme</filename>s
+ regarding Linux and <application>&oracle; DB</application> for possible problems. Most if
+ not all problems stem from incompatible libraries.</para>
+
+ <para>For more information on installing <application>&oracle;</application>, refer to <link linkend="linuxemu-oracle">the Installing &oracle;
+ chapter.</link></para>
+
+
+ <sect3 xml:id="installingtheoracle805withorainst">
+ <title>Installing the &oracle; 8.0.5 with <command>orainst</command></title>
+
+ <para>If <application>&oracle; 8.0.5</application> is to be
+ used, some additional libraries are needed for successfully
+ relinking, as <application>&oracle; 8.0.5</application> was linked with an old glibc
+ (RedHat 6.0), but RedHat 6.1 already uses a new glibc. So
+ you have to install the following additional packages to
+ ensure that linking will work:</para>
+
+ <para><filename>compat-libs-5.2-2.i386.rpm</filename></para>
+ <para><filename>compat-glibc-5.2-2.0.7.2.i386.rpm</filename></para>
+ <para><filename>compat-egcs-5.2-1.0.3a.1.i386.rpm</filename></para>
+ <para><filename>compat-egcs-c++-5.2-1.0.3a.1.i386.rpm</filename></para>
+ <para><filename>compat-binutils-5.2-2.9.1.0.23.1.i386.rpm</filename></para>
+
+ <para>See the corresponding &sap; Notes or &oracle; <filename>Readme</filename>s for
+ further information. If this is no option (at the time of
+ installation we did not have enough time to check this), one
+ could use the original binaries, or use the relinked
+ binaries from an original RedHat system.</para>
+
+ <para>For compiling the intelligent agent, the RedHat Tcl
+ package must be installed. If you cannot get
+ <filename>tcl-8.0.3-20.i386.rpm</filename>, a newer one like
+ <filename>tcl-8.0.5-30.i386.rpm</filename> for RedHat 6.1
+ should also do.</para>
+
+ <para>Apart from relinking, the installation is
+ straightforward:</para>
+
+ <screen>&prompt.root; <userinput>su - oraids</userinput>
+&prompt.root; <userinput>export TERM=xterm</userinput>
+&prompt.root; <userinput>export ORACLE_TERM=xterm</userinput>
+&prompt.root; <userinput>export ORACLE_HOME=/oracle/IDS</userinput>
+&prompt.root; <userinput>cd $ORACLE_HOME/orainst_sap</userinput>
+&prompt.root; <userinput>./orainst</userinput></screen>
+
+ <para>Confirm all screens with <keycap>Enter</keycap> until the software is
+ installed, except that one has to deselect the
+ <emphasis>&oracle; On-Line Text Viewer</emphasis>, as this is
+ not currently available for Linux. <application>&oracle;</application> then wants to
+ relink with <command>i386-glibc20-linux-gcc</command>
+ instead of the available <command>gcc</command>,
+ <command>egcs</command> or <command>i386-redhat-linux-gcc
+ </command>.</para>
+
+ <para>Due to time constrains we decided to use the binaries
+ from an <application>&oracle; 8.0.5 PreProduction</application>
+ release, after the first
+ attempt at getting the version from the RDBMS CD working,
+ failed, and finding and accessing the correct RPMs was a
+ nightmare at that time.</para>
+
+ </sect3>
+
+ <sect3 xml:id="installingtheoracle805preproduction">
+ <title>Installing the &oracle; 8.0.5 Pre-production Release for
+ Linux (Kernel 2.0.33)</title>
+
+ <para>This installation is quite easy. Mount the CD, start the
+ installer. It will then ask for the location of the &oracle;
+ home directory, and copy all binaries there. We did not
+ delete the remains of our previous RDBMS installation tries,
+ though.</para>
+
+ <para>Afterwards, <application>&oracle;</application> Database could be started with no
+ problems.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="installingoracle817">
+ <title>Installing the &oracle; 8.1.7 Linux Tarball</title>
+ <para>Take the tarball <filename>oracle81732.tgz</filename> you
+ produced from the installation directory on a Linux system
+ and untar it to <filename>/oracle/SID/817_32/</filename>.</para>
+ </sect2>
+
+ <sect2 xml:id="continuewithsapr4installation">
+ <title>Continue with &sap.r3; Installation</title>
+
+ <para>First check the environment settings of users
+ <systemitem class="username">idsamd</systemitem>
+ (<replaceable>sid</replaceable>adm) and
+ <systemitem class="username">oraids</systemitem> (ora<replaceable>sid</replaceable>). They should now
+ both have the files <filename>.profile</filename>,
+ <filename>.login</filename> and <filename>.cshrc</filename>
+ which are all using <command>hostname</command>. In case the
+ system's hostname is the fully qualified name, you need to
+ change <command>hostname</command> to <command>hostname
+ -s</command> within all three files.</para>
+
+ <sect3 xml:id="databaseload">
+ <title>Database Load</title>
+
+ <para>Afterwards, <command>R3SETUP</command> can either be restarted or continued
+ (depending on whether exit was chosen or not). <command>R3SETUP</command> then
+ creates the tablespaces and loads the data (for 46B IDES, from
+ EXPORT1 to EXPORT6, for 46C from DISK1 to DISK4) with <command>R3load</command>
+ into the database.</para>
+
+ <para>When the database load is finished (might take a few
+ hours), some passwords are requested. For test
+ installations, one can use the well known default passwords
+ (use different ones if security is an issue!):</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Question</entry>
+ <entry>Input</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Enter Password for sapr3</entry>
+ <entry>sap<keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Confirum Password for sapr3</entry>
+ <entry>sap<keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter Password for sys</entry>
+ <entry>change_on_install<keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Confirm Password for sys</entry>
+ <entry>change_on_install<keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Enter Password for system</entry>
+ <entry>manager<keycap>Enter</keycap></entry>
+ </row>
+ <row>
+ <entry>Confirm Password for system</entry>
+ <entry>manager<keycap>Enter</keycap></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>At this point We had a few problems with
+ <command>dipgntab</command> during the 4.6B
+ installation.</para>
+ </sect3>
+
+ <sect3 xml:id="listener">
+ <title>Listener</title>
+
+ <para>Start the <application>&oracle;</application> Listener as user
+ <systemitem class="username">ora<replaceable>sid</replaceable></systemitem> as follows:</para>
+
+ <screen>&prompt.user; <userinput>umask 0; lsnrctl start</userinput></screen>
+
+ <para>Otherwise you might get the error <errorcode>ORA-12546</errorcode> as the sockets will not
+ have the correct permissions. See &sap; Note 072984.</para>
+ </sect3>
+
+ <sect3 xml:id="mnlstables">
+ <title>Updating MNLS Tables</title>
+ <para>If you plan to import non-Latin-1 languages into the <application>&sap;</application> system,
+ you have to update the Multi National Language Support tables.
+ This is described in the &sap; OSS Notes 15023 and 45619. Otherwise,
+ you can skip this question during <application>&sap;</application> installation.</para>
+ <note><para>If you do not need MNLS, it is still necessary to check
+ the table TCPDB and initializing it if this has not been done. See
+ &sap; note 0015023 and 0045619 for further information.</para></note>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="postinstallationsteps">
+ <title>Post-installation Steps</title>
+
+ <sect3 xml:id="requestsapr3licensekey">
+ <title>Request &sap.r3; License Key</title>
+
+ <para>You have to request your <application>&sap.r3;</application> License Key. This is needed,
+ as the temporary license that was installed during installation
+ is only valid for four weeks. First get the hardware key. Log
+ on as user <systemitem class="username">idsadm</systemitem> and call
+ <command>saplicense</command>:</para>
+
+ <screen>&prompt.root; <userinput>/sapmnt/IDS/exe/saplicense -get</userinput></screen>
+
+ <para>Calling <command>saplicense</command> without parameters gives
+ a list of options. Upon receiving the license key, it can be
+ installed using:</para>
+
+ <screen>&prompt.root; <userinput>/sapmnt/IDS/exe/saplicense -install</userinput></screen>
+
+ <para>You are then required to enter the following values:</para>
+
+ <programlisting>SAP SYSTEM ID = <replaceable>SID, 3 chars</replaceable>
+CUSTOMER KEY = <replaceable>hardware key, 11 chars</replaceable>
+INSTALLATION NO = <replaceable>installation, 10 digits</replaceable>
+EXPIRATION DATE = <replaceable>yyyymmdd, usually "99991231"</replaceable>
+LICENSE KEY = <replaceable>license key, 24 chars</replaceable></programlisting>
+ </sect3>
+
+ <sect3 xml:id="creatingusers">
+ <title>Creating Users</title>
+
+ <para>Create a user within client 000 (for some tasks required
+ to be done within client 000, but with a user different from
+ users <systemitem class="username">sap*</systemitem> and
+ <systemitem class="username">ddic</systemitem>). As a user name, We usually choose
+ <systemitem class="username">wartung</systemitem> (or
+ <systemitem class="username">service</systemitem> in English). Profiles
+ required are <literal>sap_new</literal> and
+ <literal>sap_all</literal>. For additional safety the
+ passwords of default users within all clients should be
+ changed (this includes users <systemitem class="username">sap*</systemitem> and
+ <systemitem class="username">ddic</systemitem>).</para>
+ </sect3>
+
+ <sect3 xml:id="configtranssysprofileopermodesetc">
+ <title>Configure Transport System, Profile, Operation Modes, Etc.</title>
+
+ <para>Within client 000, user different from <systemitem class="username">ddic</systemitem>
+ and <systemitem class="username">sap*</systemitem>, do at least the following:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Task</entry>
+ <entry>Transaction</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Configure Transport System, e.g. as <emphasis>Stand-Alone
+ Transport Domain Entity</emphasis></entry>
+ <entry>STMS</entry>
+ </row>
+ <row>
+ <entry>Create / Edit Profile for System</entry>
+ <entry>RZ10</entry>
+ </row>
+ <row>
+ <entry>Maintain Operation Modes and Instances</entry>
+ <entry>RZ04</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>These and all the other post-installation steps are
+ thoroughly described in <application>&sap;</application> installation guides.</para>
+ </sect3>
+
+ <sect3 xml:id="editintsidsap">
+ <title>Edit <filename>initsid.sap</filename> (<filename>initIDS.sap</filename>)</title>
+
+ <para>The file <filename>/oracle/IDS/dbs/initIDS.sap</filename>
+ contains the <application>&sap;</application> backup profile. Here the size of the tape to
+ be used, type of compression and so on need to be defined. To
+ get this running with <command>sapdba</command> /
+ <command>brbackup</command>, we changed the following values:</para>
+
+ <programlisting>compress = hardware
+archive_function = copy_delete_save
+cpio_flags = "-ov --format=newc --block-size=128 --quiet"
+cpio_in_flags = "-iuv --block-size=128 --quiet"
+tape_size = 38000M
+tape_address = /dev/nsa0
+tape_address_rew = /dev/sa0</programlisting>
+
+ <para>Explanations:</para>
+
+ <para><varname>compress</varname>: The tape we use is a HP DLT1
+ which does hardware compression.</para>
+
+ <para><varname>archive_function</varname>: This defines the
+ default behavior for saving &oracle; archive logs: new logfiles
+ are saved to tape, already saved logfiles are saved again and
+ are then deleted. This prevents lots of trouble if you need to
+ recover the database, and one of the archive-tapes has gone
+ bad.</para>
+
+ <para><varname>cpio_flags</varname>: Default is to use <option>-B</option> which
+ sets block size to 5120&nbsp;Bytes. For DLT Tapes, HP recommends at
+ least 32&nbsp;K block size, so we used <option>--block-size=128</option> for
+ 64&nbsp;K. <option>--format=newc</option> is needed because we have inode numbers greater than
+ 65535. The last option <option>--quiet</option> is needed as otherwise
+ <command>brbackup</command>
+ complains as soon as <command>cpio</command> outputs the
+ numbers of blocks saved.</para>
+
+ <para><varname>cpio_in_flags</varname>: Flags needed for
+ loading data back from tape. Format is recognized
+ automatically.</para>
+
+ <para><varname>tape_size</varname>: This usually gives the raw
+ storage capability of the tape. For security reason (we use
+ hardware compression), the value is slightly lower than the
+ actual value.</para>
+
+ <para><varname>tape_address</varname>: The non-rewindable
+ device to be used with <command>cpio</command>.</para>
+
+ <para><varname>tape_address_rew</varname>: The rewindable device to be
+ used with <command>cpio</command>.</para>
+ </sect3>
+
+ <sect3>
+ <title>Configuration Issues after Installation</title>
+
+ <para>The following <application>&sap;</application> parameters should be tuned after
+ installation (examples for IDES 46B, 1&nbsp;GB memory):</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Value</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>ztta/roll_extension</entry>
+ <entry>250000000</entry>
+ </row>
+ <row>
+ <entry>abap/heap_area_dia</entry>
+ <entry>300000000</entry>
+ </row>
+ <row>
+ <entry>abap/heap_area_nondia</entry>
+ <entry>400000000</entry>
+ </row>
+ <row>
+ <entry>em/initial_size_MB</entry>
+ <entry>256</entry>
+ </row>
+ <row>
+ <entry>em/blocksize_kB</entry>
+ <entry>1024</entry>
+ </row>
+ <row>
+ <entry>ipc/shm_psize_40</entry>
+ <entry>70000000</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>&sap; Note 0013026:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Value</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>ztta/dynpro_area</entry>
+ <entry>2500000</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>&sap; Note 0157246:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Value</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>rdisp/ROLL_MAXFS</entry>
+ <entry>16000</entry>
+ </row>
+ <row>
+ <entry>rdisp/PG_MAXFS</entry>
+ <entry>30000</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <note>
+ <para>With the above parameters, on a system with 1&nbsp;gigabyte
+ of memory, one may find memory consumption similar to:</para>
+
+ <programlisting>Mem: 547M Active, 305M Inact, 109M Wired, 40M Cache, 112M Buf, 3492K Free</programlisting>
+ </note>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="problemsduringinstallation">
+ <title>Problems during Installation</title>
+
+ <sect3 xml:id="restartr3setup">
+ <title>Restart <command>R3SETUP</command> after Fixing a Problem</title>
+
+ <para><command>R3SETUP</command> stops if it encounters an error. If you have
+ looked at the corresponding logfiles and fixed the error,
+ you have to start <command>R3SETUP</command> again, usually selecting REPEAT
+ as option for the last step <command>R3SETUP</command> complained about.</para>
+
+ <para>To restart <command>R3SETUP</command>, just start it with the corresponding
+ <filename>R3S</filename> file:</para>
+
+ <screen>&prompt.root; <userinput>./R3SETUP -f CENTRDB.R3S</userinput></screen>
+
+ <para>for 4.6B, or with</para>
+
+ <screen>&prompt.root; <userinput>./R3SETUP -f CENTRAL.R3S</userinput></screen>
+
+ <para>for 4.6C, no matter whether the error occurred
+ with <filename>CENTRAL.R3S</filename> or
+ <filename>DATABASE.R3S</filename>.</para>
+
+ <note><para>At some stages, <command>R3SETUP</command> assumes that both database
+ and <application>&sap;</application> processes are up and running (as those were steps it
+ already completed). Should errors occur and for example the
+ database could not be started, you have to start both database
+ and <application>&sap;</application> by hand after you fixed the errors and before starting
+ <command>R3SETUP</command> again.</para>
+ <para>Do not forget to also start the <application>&oracle;</application> listener again (as
+ <systemitem class="username">ora<replaceable>sid</replaceable></systemitem> with
+ <command>umask 0; lsnrctl start</command>) if it was also
+ stopped (for example due to a necessary reboot of the
+ system).</para>
+ </note>
+ </sect3>
+
+ <sect3 xml:id="indoraduringduringr3setup">
+ <title>OSUSERSIDADM_IND_ORA during <command>R3SETUP</command></title>
+
+ <para>If <command>R3SETUP</command> complains at this stage, edit the
+ template file <command>R3SETUP</command> used at that time
+ (<filename>CENTRDB.R3S</filename> (4.6B) or either
+ <filename>CENTRAL.R3S</filename> or
+ <filename>DATABASE.R3S</filename> (4.6C)).
+ Locate <literal>[OSUSERSIDADM_IND_ORA]</literal> or search for the
+ only <literal>STATUS=ERROR</literal> entry
+ and edit the following values:</para>
+
+ <programlisting>HOME=/home/<replaceable>sid</replaceable>adm (was empty)
+STATUS=OK (had status ERROR)
+ </programlisting>
+
+ <para>Then you can restart <command>R3SETUP</command> again.</para>
+ </sect3>
+
+ <sect3 xml:id="indoraduringr3setup">
+ <title>OSUSERDBSID_IND_ORA during <command>R3SETUP</command></title>
+
+ <para>Possibly <command>R3SETUP</command> also complains at this stage. The error
+ here is similar to the one in phase OSUSERSIDADM_IND_ORA.
+ Just edit
+ the template file <command>R3SETUP</command> used at that time
+ (<filename>CENTRDB.R3S</filename> (4.6B) or either
+ <filename>CENTRAL.R3S</filename> or
+ <filename>DATABASE.R3S</filename> (4.6C)).
+ Locate <literal>[OSUSERDBSID_IND_ORA]</literal> or search for the
+ only <literal>STATUS=ERROR</literal> entry
+ and edit the following value in that section:</para>
+
+ <programlisting>STATUS=OK</programlisting>
+
+ <para>Then restart <command>R3SETUP</command>.</para>
+ </sect3>
+
+ <sect3 xml:id="oraviewvrffilenotfound">
+ <title><errorname>oraview.vrf FILE NOT FOUND</errorname> during &oracle; Installation</title>
+
+ <para>You have not deselected <emphasis>&oracle; On-Line Text Viewer</emphasis>
+ before starting the installation. This is marked for installation even
+ though this option is currently not available for Linux. Deselect this
+ product inside the <application>&oracle;</application> installation menu and restart installation.</para>
+ </sect3>
+
+ <sect3 xml:id="textenvincalid">
+ <title><errorname>TEXTENV_INVALID</errorname> during <command>R3SETUP</command>, RFC or SAPgui Start</title>
+
+ <para>If this error is encountered, the correct locale is
+ missing. &sap; Note 0171356 lists the necessary RPMs that need
+ be installed (e.g. <filename>saplocales-1.0-3</filename>,
+ <filename>saposcheck-1.0-1</filename> for RedHat 6.1). In case
+ you ignored all the related errors and set the corresponding
+ <literal>STATUS</literal> from <literal>ERROR</literal> to <literal>OK</literal> (in <filename>CENTRDB.R3S</filename>) every time <command>R3SETUP</command>
+ complained and just restarted <command>R3SETUP</command>, the <application>&sap;</application> system will not
+ be properly configured and you will then not be able to
+ connect to the system with a
+ <application>SAPgui</application>, even though the system
+ can be started. Trying to connect with the old Linux
+ <application>SAPgui</application> gave the following
+ messages:</para>
+
+ <programlisting>Sat May 5 14:23:14 2001
+*** ERROR =&gt; no valid userarea given [trgmsgo. 0401]
+Sat May 5 14:23:22 2001
+*** ERROR =&gt; ERROR NR 24 occured [trgmsgi. 0410]
+*** ERROR =&gt; Error when generating text environment. [trgmsgi. 0435]
+*** ERROR =&gt; function failed [trgmsgi. 0447]
+*** ERROR =&gt; no socket operation allowed [trxio.c 3363]
+Speicherzugriffsfehler</programlisting>
+
+ <para>This behavior is due to <application>&sap.r3;</application> being unable to correctly
+ assign a locale and also not being properly configured itself
+ (missing entries in some database tables). To be able to connect
+ to <application>&sap;</application>, add the following entries to file
+ <filename>DEFAULT.PFL</filename> (see Note 0043288):</para>
+
+ <programlisting>abap/set_etct_env_at_new_mode = 0
+install/collate/active = 0
+rscp/TCP0B = TCP0B</programlisting>
+
+ <para>Restart the <application>&sap;</application> system. Now you can connect to the
+ system, even though country-specific language settings might
+ not work as expected. After correcting country settings
+ (and providing the correct locales), these entries can be
+ removed from <filename>DEFAULT.PFL</filename> and the <application>&sap;</application>
+ system can be restarted.</para>
+
+ </sect3>
+
+ <sect3 xml:id="ora-00001">
+ <title><errorcode>ORA-00001</errorcode></title>
+ <para>This error only happened with
+ <application>&oracle; 8.1.7</application> on FreeBSD.
+ The reason was that the <application>&oracle;</application> database could not initialize itself
+ properly and crashed, leaving semaphores and shared memory on the
+ system. The next try to start the database then returned
+ <errorcode>ORA-00001</errorcode>.</para>
+
+ <para>Find them with <command>ipcs -a</command> and remove them
+ with <command>ipcrm</command>.</para>
+ </sect3>
+
+ <sect3 xml:id="ora-00445pmon">
+ <title><errorcode>ORA-00445</errorcode> (Background Process PMON Did Not Start)</title>
+ <para>This error happened with <application>&oracle; 8.1.7</application>.
+ This error is reported if the database is started with
+ the usual <command>startsap</command> script (for example
+ <command>startsap_majestix_00</command>) as user
+ <systemitem class="username">prdadm</systemitem>.</para>
+
+ <para>A possible workaround is to start the database as user
+ <systemitem class="username">oraprd</systemitem> instead
+ with <command>svrmgrl</command>:</para>
+
+ <screen>&prompt.user; <userinput>svrmgrl</userinput>
+SVRMGR&gt; <userinput>connect internal;</userinput>
+SVRMGR&gt; <userinput>startup</userinput>;
+SVRMGR&gt; <userinput>exit</userinput></screen>
+
+ </sect3>
+
+ <sect3 xml:id="ora-12546">
+ <title><errorcode>ORA-12546</errorcode> (Start Listener with Correct Permissions)</title>
+
+ <para>Start the <application>&oracle;</application> listener as user
+ <systemitem class="username">oraids</systemitem> with the following commands:</para>
+
+ <screen>&prompt.root; <userinput>umask 0; lsnrctl start</userinput></screen>
+
+ <para>Otherwise you might get <errorcode>ORA-12546</errorcode> as the sockets will not
+ have the correct permissions. See &sap; Note 0072984.</para>
+ </sect3>
+
+ <sect3 xml:id="ora-27102">
+ <title><errorcode>ORA-27102</errorcode> (Out of Memory)</title>
+
+ <para>This error happened whilst trying to use values for
+ <literal>MAXDSIZ</literal> and <literal>DFLDSIZ</literal>
+ greater than 1&nbsp;GB (1024x1024x1024). Additionally, we got
+ <errorname>Linux Error 12: Cannot allocate memory</errorname>.</para>
+ </sect3>
+
+ <sect3 xml:id="dipgntabindind">
+ <title>[DIPGNTAB_IND_IND] during <command>R3SETUP</command></title>
+
+ <para>In general, see &sap; Note 0130581 (<command>R3SETUP</command> step
+ <literal>DIPGNTAB</literal> terminates). During the
+ IDES-specific installation, for some reason the installation
+ process was not using the proper <application>&sap;</application> system name <quote>IDS</quote>, but
+ the empty string <literal>""</literal> instead. This leads to some minor problems
+ with accessing directories, as the paths are generated
+ dynamically using <replaceable>SID</replaceable> (in this case IDS). So instead
+ of accessing:</para>
+
+ <programlisting>/usr/sap/IDS/SYS/...
+/usr/sap/IDS/DVMGS00</programlisting>
+
+ <para>the following paths were used:</para>
+
+ <programlisting>/usr/sap//SYS/...
+/usr/sap/D00</programlisting>
+
+ <para>To continue with the installation, we created a link and an
+ additional directory:</para>
+
+ <screen>&prompt.root; <userinput>pwd</userinput>
+/compat/linux/usr/sap
+&prompt.root; <userinput>ls -l</userinput>
+total 4
+drwxr-xr-x 3 idsadm sapsys 512 May 5 11:20 D00
+drwxr-x--x 5 idsadm sapsys 512 May 5 11:35 IDS
+lrwxr-xr-x 1 root sapsys 7 May 5 11:35 SYS -&gt; IDS/SYS
+drwxrwxr-x 2 idsadm sapsys 512 May 5 13:00 tmp
+drwxrwxr-x 11 idsadm sapsys 512 May 4 14:20 trans</screen>
+
+ <para>We also found &sap; Notes (0029227 and 0008401) describing
+ this behavior. We did not encounter any of these problems with
+ the <application>&sap; 4.6C</application> installation.</para>
+ </sect3>
+
+ <sect3 xml:id="rfcrswboiniindind">
+ <title>[RFCRSWBOINI_IND_IND] during <command>R3SETUP</command></title>
+
+ <para>During installation of <application>&sap; 4.6C</application>,
+ this error was just the result of another error happening
+ earlier during installation. In this case, you have to look
+ through the corresponding logfiles and correct the real
+ problem.</para>
+
+ <para>If after looking through the logfiles this error is
+ indeed the correct one (check the &sap; Notes), you can set
+ <literal>STATUS</literal> of the offending step from <literal>ERROR</literal> to <literal>OK</literal> (file
+ <filename>CENTRDB.R3S</filename>) and restart <command>R3SETUP</command>. After
+ installation, you have to execute the report
+ <literal>RSWBOINS</literal> from transaction SE38. See &sap;
+ Note 0162266 for additional information about phase
+ <literal>RFCRSWBOINI</literal> and
+ <literal>RFCRADDBDIF</literal>.</para>
+ </sect3>
+
+ <sect3 xml:id="rfcraddbdifindind">
+ <title>[RFCRADDBDIF_IND_IND] during <command>R3SETUP</command></title>
+ <para>Here the same restrictions apply: make sure by looking
+ through the logfiles, that this error is not caused by some
+ previous problems.</para>
+
+ <para>If you can confirm that &sap; Note 0162266 applies, just
+ set <literal>STATUS</literal> of the offending step from <literal>ERROR</literal> to <literal>OK</literal> (file
+ <filename>CENTRDB.R3S</filename>) and restart <command>R3SETUP</command>. After
+ installation, you have to execute the report
+ <literal>RADDBDIF</literal> from transaction SE38.</para>
+ </sect3>
+
+ <sect3 xml:id="sigactionsig31">
+ <title><errorcode>sigaction sig31: File size limit exceeded</errorcode></title>
+
+ <para>This error occurred during start of <application>&sap;</application> processes
+ <emphasis>disp+work</emphasis>. If starting <application>&sap;</application> with the
+ <command>startsap</command> script, subprocesses are then started which
+ detach and do the dirty work of starting all other <application>&sap;</application>
+ processes. As a result, the script itself will not notice
+ if something goes wrong.</para>
+
+ <para>To check whether the <application>&sap;</application> processes did start properly,
+ have a look at the process status with
+ <command>ps ax | grep SID</command>, which will give
+ you a list of all <application>&oracle;</application> and <application>&sap;</application> processes. If it looks like
+ some processes are missing or if you cannot connect to the <application>&sap;</application> system,
+ look at the corresponding logfiles which can be found
+ at <filename>/usr/sap/SID/DVEBMGSnr/work/</filename>.
+ The files to look at are <filename>dev_ms</filename> and
+ <filename>dev_disp</filename>.</para>
+
+ <para>Signal 31 happens here if the amount of shared memory used by
+ <application>&oracle;</application> and <application>&sap;</application> exceed the one defined within the kernel configuration
+ file and could be resolved by using a larger value:</para>
+
+ <programlisting># larger value for 46C production systems:
+options SHMMAXPGS=393216
+# smaller value sufficient for 46B:
+#options SHMMAXPGS=262144</programlisting>
+
+ </sect3>
+
+ <sect3 xml:id="saposcolfails">
+ <title>Start of <command>saposcol</command> Failed</title>
+ <para>There are some problems with the program <command>saposcol</command> (version 4.6D).
+ The <application>&sap;</application> system is using <command>saposcol</command> to collect data about the
+ system performance. This program is not needed to use the <application>&sap;</application> system,
+ so this problem can be considered a minor one. The older versions
+ (4.6B) does work, but does not collect all the data (many calls will
+ just return 0, for example for CPU usage).</para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="linuxemu-advanced">
+ <title>Advanced Topics</title>
+
+ <para>If you are curious as to how the Linux binary compatibility
+ works, this is the section you want to read. Most of what follows
+ is based heavily on an email written to &a.chat; by Terry Lambert
+ <email>tlambert@primenet.com</email> (Message ID:
+ <literal>&lt;199906020108.SAA07001@usr09.primenet.com&gt;</literal>).</para>
+
+ <sect2>
+ <title>How Does It Work?</title>
+ <indexterm><primary>execution class loader</primary></indexterm>
+
+ <para>FreeBSD has an abstraction called an <quote>execution class
+ loader</quote>. This is a wedge into the &man.execve.2; system
+ call.</para>
+
+ <para>What happens is that FreeBSD has a list of loaders, instead of
+ a single loader with a fallback to the <literal>#!</literal>
+ loader for running any shell interpreters or shell scripts.</para>
+
+ <para>Historically, the only loader on the &unix; platform examined
+ the magic number (generally the first 4 or 8 bytes of the file) to
+ see if it was a binary known to the system, and if so, invoked the
+ binary loader.</para>
+
+ <para>If it was not the binary type for the system, the
+ &man.execve.2; call returned a failure, and the shell attempted to
+ start executing it as shell commands.</para>
+
+ <para>The assumption was a default of <quote>whatever the current
+ shell is</quote>.</para>
+
+ <para>Later, a hack was made for &man.sh.1; to examine the first two
+ characters, and if they were <literal>:\n</literal>, then it
+ invoked the &man.csh.1; shell instead (we believe SCO first made
+ this hack).</para>
+
+ <para>What FreeBSD does now is go through a list of loaders, with a
+ generic <literal>#!</literal> loader that knows about interpreters
+ as the characters which follow to the next whitespace next to
+ last, followed by a fallback to
+ <filename>/bin/sh</filename>.</para>
+ <indexterm><primary>ELF</primary></indexterm>
+
+ <para>For the Linux ABI support, FreeBSD sees the magic number as an
+ ELF binary (it makes no distinction between FreeBSD, &solaris;,
+ Linux, or any other OS which has an ELF image type, at this
+ point).</para>
+ <indexterm><primary>Solaris</primary></indexterm>
+
+ <para>The ELF loader looks for a specialized
+ <emphasis>brand</emphasis>, which is a comment section in the ELF
+ image, and which is not present on SVR4/&solaris; ELF
+ binaries.</para>
+
+ <para>For Linux binaries to function, they must be
+ <emphasis>branded</emphasis> as type <literal>Linux</literal>
+ from &man.brandelf.1;:</para>
+
+ <screen>&prompt.root; <userinput>brandelf -t Linux file</userinput></screen>
+
+ <para>When this is done, the ELF loader will see the
+ <literal>Linux</literal> brand on the file.</para>
+ <indexterm>
+ <primary>ELF</primary>
+ <secondary>branding</secondary>
+ </indexterm>
+
+ <para>When the ELF loader sees the <literal>Linux</literal> brand,
+ the loader replaces a pointer in the <literal>proc</literal>
+ structure. All system calls are indexed through this pointer (in
+ a traditional &unix; system, this would be the
+ <literal>sysent[]</literal> structure array, containing the system
+ calls). In addition, the process is flagged for special handling of
+ the trap vector for the signal trampoline code, and several other
+ (minor) fix-ups that are handled by the Linux kernel
+ module.</para>
+
+ <para>The Linux system call vector contains, among other things, a
+ list of <literal>sysent[]</literal> entries whose addresses reside
+ in the kernel module.</para>
+
+ <para>When a system call is called by the Linux binary, the trap
+ code dereferences the system call function pointer off the
+ <literal>proc</literal> structure, and gets the Linux, not the
+ FreeBSD, system call entry points.</para>
+
+ <para>In addition, the Linux mode dynamically
+ <emphasis>reroots</emphasis> lookups; this is, in effect, what the
+ <option>union</option> option to file system mounts
+ (<emphasis>not</emphasis> the <literal>unionfs</literal> file system type!) does. First, an attempt
+ is made to lookup the file in the
+ <filename>/compat/linux/original-path</filename>
+ directory, <emphasis>then</emphasis> only if that fails, the
+ lookup is done in the
+ <filename>/original-path</filename>
+ directory. This makes sure that binaries that require other
+ binaries can run (e.g., the Linux toolchain can all run under
+ Linux ABI support). It also means that the Linux binaries can
+ load and execute FreeBSD binaries, if there are no corresponding
+ Linux binaries present, and that you could place a &man.uname.1;
+ command in the <filename>/compat/linux</filename> directory tree
+ to ensure that the Linux binaries could not tell they were not
+ running on Linux.</para>
+
+ <para>In effect, there is a Linux kernel in the FreeBSD kernel; the
+ various underlying functions that implement all of the services
+ provided by the kernel are identical to both the FreeBSD system
+ call table entries, and the Linux system call table entries: file
+ system operations, virtual memory operations, signal delivery,
+ System V IPC, etc&hellip; The only difference is that FreeBSD
+ binaries get the FreeBSD <emphasis>glue</emphasis> functions, and
+ Linux binaries get the Linux <emphasis>glue</emphasis> functions
+ (most older OS's only had their own <emphasis>glue</emphasis>
+ functions: addresses of functions in a static global
+ <literal>sysent[]</literal> structure array, instead of addresses
+ of functions dereferenced off a dynamically initialized pointer in
+ the <literal>proc</literal> structure of the process making the
+ call).</para>
+
+ <para>Which one is the native FreeBSD ABI? It does not matter.
+ Basically the only difference is that (currently; this could
+ easily be changed in a future release, and probably will be after
+ this) the FreeBSD <emphasis>glue</emphasis> functions are
+ statically linked into the kernel, and the Linux <emphasis>glue</emphasis> functions
+ can be statically linked, or they can be accessed via a kernel
+ module.</para>
+
+ <para>Yeah, but is this really emulation? No. It is an ABI
+ implementation, not an emulation. There is no emulator (or
+ simulator, to cut off the next question) involved.</para>
+
+ <para>So why is it sometimes called <quote>Linux emulation</quote>?
+ To make it hard to sell FreeBSD! Really, it
+ is because the historical implementation was done at a time when
+ there was really no word other than that to describe what was
+ going on; saying that FreeBSD ran Linux binaries was not true, if
+ you did not compile the code in or load a module, and there needed
+ to be a word to describe what was being loaded&mdash;hence
+ <quote>the Linux emulator</quote>.</para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/mac/Makefile b/zh_TW.UTF-8/books/handbook/mac/Makefile
new file mode 100644
index 0000000000..ecd40cd7e2
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/mac/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= mac/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/mac/chapter.xml b/zh_TW.UTF-8/books/handbook/mac/chapter.xml
new file mode 100644
index 0000000000..3d2579c75e
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/mac/chapter.xml
@@ -0,0 +1,2274 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+ $FreeBSD$
+ Original revision: 1.48
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="mac">
+ <info><title>Mandatory Access Control</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="mac-synopsis">
+ <title>Synopsis</title>
+
+ <indexterm><primary>MAC</primary></indexterm>
+ <indexterm>
+ <primary>Mandatory Access Control</primary>
+ <see>MAC</see>
+ </indexterm>
+
+ <para>&os;&nbsp;5.X introduced new security extensions from the
+ TrustedBSD project based on the &posix;.1e draft. Two of the most
+ significant new security mechanisms are file system Access Control
+ Lists (<acronym>ACLs</acronym>) and Mandatory Access Control
+ (<acronym>MAC</acronym>) facilities. Mandatory Access Control allows
+ new access control modules to be loaded, implementing new security
+ policies. Some provide protections of a narrow subset of the
+ system, hardening a particular service, while others provide
+ comprehensive labeled security across all subjects and objects.
+ The mandatory part
+ of the definition comes from the fact that the enforcement of
+ the controls is done by administrators and the system, and is
+ not left up to the discretion of users as is done with
+ discretionary access control (<acronym>DAC</acronym>, the standard
+ file and System V <acronym>IPC</acronym> permissions on &os;).</para>
+
+ <para>This chapter will focus on the
+ Mandatory Access Control Framework (MAC Framework), and a set
+ of pluggable security policy modules enabling various security
+ mechanisms.</para>
+
+ <para>After reading this chapter, you will know:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>What <acronym>MAC</acronym> security policy modules are currently
+ included in &os; and their associated mechanisms.</para>
+ </listitem>
+
+ <listitem>
+ <para>What <acronym>MAC</acronym> security policy modules implement as
+ well as the difference between a labeled and non-labeled
+ policy.</para>
+ </listitem>
+
+ <listitem>
+ <para>How to efficiently configure a system to use
+ the <acronym>MAC</acronym> framework.</para>
+ </listitem>
+
+ <listitem>
+ <para>How to configure the different security policy modules included with the
+ <acronym>MAC</acronym> framework.</para>
+ </listitem>
+
+ <listitem>
+ <para>How to implement a more secure environment using the
+ <acronym>MAC</acronym> framework and the examples
+ shown.</para>
+ </listitem>
+
+ <listitem>
+ <para>How to test the <acronym>MAC</acronym> configuration
+ to ensure the framework has been properly implemented.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Before reading this chapter, you should:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Understand &unix; and &os; basics
+ (<xref linkend="basics"/>).</para>
+ </listitem>
+
+ <listitem>
+ <para>Be familiar with
+ the basics of kernel configuration/compilation
+ (<xref linkend="kernelconfig"/>).</para>
+ </listitem>
+
+ <listitem>
+ <para>Have some familiarity with security and how it
+ pertains to &os; (<xref linkend="security"/>).</para>
+ </listitem>
+ </itemizedlist>
+
+ <warning>
+ <para>The improper use of the
+ information in this chapter may cause loss of system access,
+ aggravation of users, or inability to access the features
+ provided by X11. More importantly, <acronym>MAC</acronym> should not
+ be relied upon to completely secure a system. The
+ <acronym>MAC</acronym> framework only augments
+ existing security policy; without sound security practices and
+ regular security checks, the system will never be completely
+ secure.</para>
+
+ <para>It should also be noted that the examples contained
+ within this chapter are just that, examples. It is not
+ recommended that these particular settings be rolled out
+ on a production system. Implementing the various security policy modules takes
+ a good deal of thought. One who does not fully understand
+ exactly how everything works may find him or herself going
+ back through the entire system and reconfiguring many files
+ or directories.</para>
+ </warning>
+
+ <sect2>
+ <title>What Will Not Be Covered</title>
+
+ <para>This chapter covers a broad range of security issues relating
+ to the <acronym>MAC</acronym> framework; however, the
+ development of new <acronym>MAC</acronym> security policy modules
+ will not be covered. A number of security policy modules included with the
+ <acronym>MAC</acronym> framework have specific characteristics
+ which are provided for both testing and new module
+ development. These include the &man.mac.test.4;,
+ &man.mac.stub.4; and &man.mac.none.4;.
+ For more information on these security policy modules and the various
+ mechanisms they provide, please review the manual pages.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="mac-inline-glossary">
+ <title>Key Terms in this Chapter</title>
+
+ <para>Before reading this chapter, a few key terms must be
+ explained. This will hopefully clear up any confusion that
+ may occur and avoid the abrupt introduction of new terms
+ and information.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>compartment</emphasis>: A compartment is a
+ set of programs and data to be partitioned or separated,
+ where users are given explicit access to specific components
+ of a system. Also, a compartment represents a grouping,
+ such as a work group, department, project, or topic. Using
+ compartments, it is possible to implement a need-to-know
+ security policy.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>integrity</emphasis>: Integrity, as a key
+ concept, is the level of trust which can be placed on data.
+ As the integrity of the data is elevated, so does the ability
+ to trust that data.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>label</emphasis>: A label is a security
+ attribute which can be applied to files, directories, or
+ other items in the system. It could be considered
+ a confidentiality stamp; when a label is placed on
+ a file it describes the security properties for that specific
+ file and will only permit access by files, users, resources,
+ etc. with a similar security setting. The meaning and
+ interpretation of label values depends on the policy configuration: while
+ some policies might treat a label as representing the
+ integrity or secrecy of an object, other policies might use
+ labels to hold rules for access.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>level</emphasis>: The increased or decreased
+ setting of a security attribute. As the level increases,
+ its security is considered to elevate as well.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>multilabel</emphasis>: The
+ <option>multilabel</option> property is a file system option
+ which can be set in single user mode using the
+ &man.tunefs.8; utility, during the boot operation
+ using the &man.fstab.5; file, or during the creation of
+ a new file system. This option will permit an administrator
+ to apply different <acronym>MAC</acronym> labels on different
+ objects. This option
+ only applies to security policy modules which support labeling.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>object</emphasis>: An object or system
+ object is an entity through which information flows
+ under the direction of a <emphasis>subject</emphasis>.
+ This includes directories, files, fields, screens, keyboards,
+ memory, magnetic storage, printers or any other data
+ storage/moving device. Basically, an object is a data container or
+ a system resource; access to an <emphasis>object</emphasis>
+ effectively means access to the data.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>policy</emphasis>: A collection of rules
+ which defines how objectives are to be achieved. A
+ <emphasis>policy</emphasis> usually documents how certain
+ items are to be handled. This chapter will
+ consider the term <emphasis>policy</emphasis> in this
+ context as a <emphasis>security policy</emphasis>; i.e.
+ a collection of rules which will control the flow of data
+ and information and define whom will have access to that
+ data and information.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>sensitivity</emphasis>: Usually used when
+ discussing <acronym>MLS</acronym>. A sensitivity level is
+ a term used to describe how important or secret the data
+ should be. As the sensitivity level increases, so does the
+ importance of the secrecy, or confidentiality of the data.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>single label</emphasis>: A single label is
+ when the entire file system uses one label to
+ enforce access control over the flow of data. When a file
+ system has this set, which is any time when the
+ <option>multilabel</option> option is not set, all
+ files will conform to the same label setting.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>subject</emphasis>: a subject is any
+ active entity that causes information to flow between
+ <emphasis>objects</emphasis>; e.g. a user, user processor,
+ system process, etc. On &os;, this is almost always a thread
+ acting in a process on behalf of a user.</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="mac-initial">
+ <title>Explanation of MAC</title>
+
+ <para>With all of these new terms in mind, consider how the
+ <acronym>MAC</acronym> framework augments the security of
+ the system as a whole. The various security policy modules provided by
+ the <acronym>MAC</acronym> framework could be used to
+ protect the network and file systems, block users from
+ accessing certain ports and sockets, and more. Perhaps
+ the best use of the policy modules is to blend them together, by loading
+ several security policy modules at a time for a multi-layered
+ security environment. In a multi-layered security environment,
+ multiple policy modules are in effect to keep security in check. This
+ is different to a hardening policy, which typically hardens
+ elements of a system that is used only for specific purposes.
+ The only downside is administrative overhead in cases of
+ multiple file system labels, setting network access control
+ user by user, etc.</para>
+
+ <para>These downsides are minimal when compared to the lasting
+ effect of the framework; for instance, the ability to pick and choose
+ which policies are required for a specific configuration keeps
+ performance overhead down. The reduction of support for unneeded
+ policies can increase the overall performance of the system as well as
+ offer flexibility of choice. A good implementation would
+ consider the overall security requirements and effectively implement
+ the various security policy modules offered by the framework.</para>
+
+ <para>Thus a system utilizing <acronym>MAC</acronym> features
+ should at least guarantee that a user will not be permitted
+ to change security attributes at will; all user utilities,
+ programs and scripts must work within the constraints of
+ the access rules provided by the selected security policy modules; and
+ that total control of the <acronym>MAC</acronym> access
+ rules are in the hands of the system administrator.</para>
+
+ <para>It is the sole duty of the system administrator to
+ carefully select the correct security policy modules. Some environments
+ may need to limit access control over the network; in these
+ cases, the &man.mac.portacl.4;, &man.mac.ifoff.4; and even
+ &man.mac.biba.4; policy modules might make good starting points. In other
+ cases, strict confidentiality of file system objects might
+ be required. Policy modules such as &man.mac.bsdextended.4;
+ and &man.mac.mls.4; exist for this purpose.</para>
+
+ <para>Policy decisions could be made based on network
+ configuration. Perhaps only certain users should be permitted
+ access to facilities provided by &man.ssh.1; to access the
+ network or the Internet. The &man.mac.portacl.4; would be
+ the policy module of choice for these situations. But what should be
+ done in the case of file systems? Should all access to certain
+ directories be severed from other groups or specific
+ users? Or should we limit user or utility access to specific
+ files by setting certain objects as classified?</para>
+
+ <para>In the file system case, access to objects might be
+ considered confidential to some users, but not to others.
+ For an example, a large development team might be broken
+ off into smaller groups of individuals. Developers in
+ project A might not be permitted to access objects written
+ by developers in project B. Yet they might need to access
+ objects created by developers in project C; that is quite a
+ situation indeed. Using the different security policy modules provided by
+ the <acronym>MAC</acronym> framework; users could
+ be divided into these groups and then given access to the
+ appropriate areas without fear of information
+ leakage.</para>
+
+ <para>Thus, each security policy module has a unique way of dealing with
+ the overall security of a system. Module selection should be based
+ on a well thought out security policy. In many cases, the
+ overall policy may need to be revised and reimplemented on
+ the system. Understanding the different security policy modules offered by
+ the <acronym>MAC</acronym> framework will help administrators
+ choose the best policies for their situations.</para>
+
+ <para>The default &os; kernel does not include the option for
+ the <acronym>MAC</acronym> framework; thus the following
+ kernel option must be added before trying any of the examples or
+ information in this chapter:</para>
+
+ <programlisting>options MAC</programlisting>
+
+ <para>And the kernel will require a rebuild and a reinstall.</para>
+
+ <caution>
+ <para>While the various manual pages for <acronym>MAC</acronym>
+ policy modules state that they may be built into the kernel,
+ it is possible to lock the system out of
+ the network and more. Implementing <acronym>MAC</acronym>
+ is much like implementing a firewall, care must be taken
+ to prevent being completely locked out of the system. The
+ ability to revert back to a previous configuration should be
+ considered while the implementation of <acronym>MAC</acronym>
+ remotely should be done with extreme caution.</para>
+ </caution>
+ </sect1>
+
+ <sect1 xml:id="mac-understandlabel">
+ <title>Understanding MAC Labels</title>
+
+ <para>A <acronym>MAC</acronym> label is a security attribute
+ which may be applied to subjects and objects throughout
+ the system.</para>
+
+ <para>When setting a label, the user must be able to comprehend
+ what it is, exactly, that is being done. The attributes
+ available on an object depend on the policy module loaded, and that
+ policy modules interpret their attributes in different
+ ways. If improperly configured due to lack of comprehension, or
+ the inability to understand the implications, the result will
+ be the unexpected and perhaps, undesired, behavior of the
+ system.</para>
+
+ <para>The security label on an object is used as a part of a
+ security access control decision by a policy. With some
+ policies, the label by itself contains all information necessary
+ to make a decision; in other models, the labels may be processed
+ as part of a larger rule set, etc.</para>
+
+ <para>For instance, setting the label of <literal>biba/low</literal>
+ on a file will represent a label maintained by the Biba security policy module,
+ with a value of <quote>low</quote>.</para>
+
+ <para>A few policy modules which support the labeling feature in
+ &os; offer three specific predefined labels. These
+ are the low, high, and equal labels. Although they enforce
+ access control in a different manner with each policy module, you
+ can be sure that the low label will be the lowest setting,
+ the equal label will set the subject or object to be disabled
+ or unaffected, and the high label will enforce the highest
+ setting available in the Biba and <acronym>MLS</acronym>
+ policy modules.</para>
+
+ <para>Within single label file system environments, only one label may be
+ used on objects. This will enforce one set of
+ access permissions across the entire system and in many
+ environments may be all that is required. There are a few
+ cases where multiple labels may be set on objects
+ or subjects in the file system. For those cases, the
+ <option>multilabel</option> option may be passed to
+ &man.tunefs.8;.</para>
+
+ <para>In the case of Biba and <acronym>MLS</acronym>, a numeric
+ label may be set to indicate the precise level of hierarchical
+ control. This numeric level is used to partition or sort
+ information into different groups of say, classification only
+ permitting access to that group or a higher group level.</para>
+
+ <para>In most cases the administrator will only be setting up a
+ single label to use throughout the file system.</para>
+
+ <para><emphasis>Hey wait, this is similar to <acronym>DAC</acronym>!
+ I thought <acronym>MAC</acronym> gave control strictly to the
+ administrator.</emphasis> That statement still holds true, to some
+ extent as <systemitem class="username">root</systemitem> is the one in control and who
+ configures the policies so that users are placed in the
+ appropriate categories/access levels. Alas, many policy modules can
+ restrict the <systemitem class="username">root</systemitem> user as well. Basic
+ control over objects will then be released to the group, but
+ <systemitem class="username">root</systemitem> may revoke or modify the settings
+ at any time. This is the hierarchal/clearance model covered
+ by policies such as Biba and <acronym>MLS</acronym>.</para>
+
+ <sect2>
+ <title>Label Configuration</title>
+
+ <para>Virtually all aspects of label policy module configuration
+ will be performed using the base system utilities. These
+ commands provide a simple interface for object or subject
+ configuration or the manipulation and verification of
+ the configuration.</para>
+
+ <para>All configuration may be done by use of the
+ &man.setfmac.8; and &man.setpmac.8; utilities.
+ The <command>setfmac</command> command is used to set
+ <acronym>MAC</acronym> labels on system objects while the
+ <command>setpmac</command> command is used to set the labels
+ on system subjects. Observe:</para>
+
+ <screen>&prompt.root; <userinput>setfmac biba/high test</userinput></screen>
+
+ <para>If no errors occurred with the command above, a prompt
+ will be returned. The only time these commands are not
+ quiescent is when an error occurred; similarly to the
+ &man.chmod.1; and &man.chown.8; commands. In some cases this
+ error may be a <errorname>Permission denied</errorname> and
+ is usually obtained when the label is being set or modified
+ on an object which is restricted.<footnote><para>Other conditions
+ may produce different failures. For instance, the file may not
+ be owned by the user attempting to relabel the object, the
+ object may not exist or may be read only. A mandatory policy
+ will not allow the process to relabel the file, maybe because
+ of a property of the file, a property of the process, or a
+ property of the proposed new label value. For example: a user
+ running at low integrity tries to change the label of a high
+ integrity file. Or perhaps a user running at low integrity
+ tries to change the label of a low integrity file to a high
+ integrity label.</para></footnote> The system administrator
+ may use the following commands to overcome this:</para>
+
+ <screen>&prompt.root; <userinput>setfmac biba/high test</userinput>
+<errorname>Permission denied</errorname>
+&prompt.root; <userinput>setpmac biba/low setfmac biba/high test</userinput>
+&prompt.root; <userinput>getfmac test</userinput>
+test: biba/high</screen>
+
+ <para>As we see above, <command>setpmac</command>
+ can be used to override the policy module's settings by assigning
+ a different label to the invoked process. The
+ <command>getpmac</command> utility is usually used with currently
+ running processes, such as <application>sendmail</application>:
+ although it takes a process ID in place of
+ a command the logic is extremely similar. If users
+ attempt to manipulate a file not in their access, subject to the
+ rules of the loaded policy modules, the
+ <errorname>Operation not permitted</errorname> error
+ will be displayed by the <function>mac_set_link</function>
+ function.</para>
+
+ <sect3>
+ <title>Common Label Types</title>
+
+ <para>For the &man.mac.biba.4;, &man.mac.mls.4; and
+ &man.mac.lomac.4; policy modules, the ability to assign
+ simple labels is provided. These take the form of high,
+ equal and low, what follows is a brief description of
+ what these labels provide:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The <literal>low</literal> label is considered the
+ lowest label setting an object or subject may have.
+ Setting this on objects or subjects will block their
+ access to objects or subjects marked high.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <literal>equal</literal> label should only be
+ placed on objects considered to be exempt from the
+ policy.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <literal>high</literal> label grants an object or
+ subject the highest possible setting.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>With respect to each policy module, each of those settings
+ will instate a different information flow directive. Reading
+ the proper manual pages will further explain the traits of
+ these generic label configurations.</para>
+
+ <sect4>
+ <title>Advanced Label Configuration</title>
+
+ <para>Numeric grade numbers used for
+ <literal>comparison:compartment+compartment</literal>; thus
+ the following:</para>
+
+ <programlisting>biba/10:2+3+6(5:2+3-20:2+3+4+5+6)</programlisting>
+
+ <para>May be interpreted as:</para>
+
+ <para><quote>Biba Policy Label</quote>/<quote>Grade 10</quote>
+ :<quote>Compartments 2, 3 and 6</quote>:
+ (<quote>grade 5 ...</quote>)</para>
+
+ <para>In this example, the first grade would be considered
+ the <quote>effective grade</quote> with
+ <quote>effective compartments</quote>, the second grade
+ is the low grade and the last one is the high grade.
+ In most configurations these settings will not be used;
+ indeed, they offered for more advanced
+ configurations.</para>
+
+ <para>When applied to system objects, they will only have a
+ current grade/compartments as opposed to system subjects
+ as they reflect the range of available rights in the system,
+ and network interfaces, where they are used for access
+ control.</para>
+
+ <para>The grade and compartments in a subject and object pair
+ are used to construct a relationship referred to as
+ <quote>dominance</quote>, in which a subject dominates an
+ object, the object dominates the subject, neither dominates
+ the other, or both dominate each other. The
+ <quote>both dominate</quote> case occurs when the two labels
+ are equal. Due to the information flow nature of Biba, you
+ have rights to a set of compartments,
+ <quote>need to know</quote>, that might correspond to
+ projects, but objects also have a set of compartments.
+ Users may have to subset their rights using
+ <command>su</command> or <command>setpmac</command> in order
+ to access objects in a compartment from which they are not
+ restricted.</para>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>Users and Label Settings</title>
+
+ <para>Users themselves are required to have labels so that
+ their files and processes may properly interact with the
+ security policy defined on the system. This is
+ configured through the <filename>login.conf</filename> file
+ by use of login classes. Every policy module that uses labels
+ will implement the user class setting.</para>
+
+ <para>An example entry containing every policy module setting is displayed
+ below:</para>
+
+ <programlisting>default:\
+ :copyright=/etc/COPYRIGHT:\
+ :welcome=/etc/motd:\
+ :setenv=MAIL=/var/mail/$,BLOCKSIZE=K:\
+ :path=~/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:\
+ :manpath=/usr/share/man /usr/local/man:\
+ :nologin=/usr/sbin/nologin:\
+ :cputime=1h30m:\
+ :datasize=8M:\
+ :vmemoryuse=100M:\
+ :stacksize=2M:\
+ :memorylocked=4M:\
+ :memoryuse=8M:\
+ :filesize=8M:\
+ :coredumpsize=8M:\
+ :openfiles=24:\
+ :maxproc=32:\
+ :priority=0:\
+ :requirehome:\
+ :passwordtime=91d:\
+ :umask=022:\
+ :ignoretime@:\
+ :label=partition/13,mls/5,biba/10(5-15),lomac10[2]:</programlisting>
+
+ <para>The <literal>label</literal> option is used to set the
+ user class default label which will be enforced by
+ <acronym>MAC</acronym>. Users will never be permitted to
+ modify this value, thus it can be considered not optional
+ in the user case. In a real configuration, however, the
+ administrator will never wish to enable every policy module.
+ It is recommended that the rest of this chapter be reviewed
+ before any of this configuration is implemented.</para>
+
+ <note>
+ <para>Users may change their label after the initial login;
+ however, this change is subject constraints of the policy.
+ The example above tells the Biba policy that a process's
+ minimum integrity is 5, its maximum is 15, but the default
+ effective label is 10. The process will run at 10 until
+ it chooses to change label, perhaps due to the user using
+ the setpmac command, which will be constrained by Biba to
+ the range set at login.</para>
+ </note>
+
+ <para>In all cases, after a change to
+ <filename>login.conf</filename>, the login class capability
+ database must be rebuilt using <command>cap_mkdb</command>
+ and this will be reflected throughout every forthcoming
+ example or discussion.</para>
+
+ <para>It is useful to note that many sites may have a
+ particularly large number of users requiring several
+ different user classes. In depth planning is required
+ as this may get extremely difficult to manage.</para>
+
+ <para>Future versions of &os; will include a new way to
+ deal with mapping users to labels; however, this will
+ not be available until some time after &os;&nbsp;5.3.</para>
+ </sect3>
+
+ <sect3>
+ <title>Network Interfaces and Label Settings</title>
+
+ <para>Labels may also be set on network interfaces to help
+ control the flow of data across the network. In all cases
+ they function in the same way the policies function with
+ respect to objects. Users at high settings in
+ <literal>biba</literal>, for example, will not be permitted
+ to access network interfaces with a label of low.</para>
+
+ <para>The <option>maclabel</option> may be passed to
+ <command>ifconfig</command> when setting the
+ <acronym>MAC</acronym> label on network interfaces. For
+ example:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig bge0 maclabel biba/equal</userinput></screen>
+
+ <para>will set the <acronym>MAC</acronym> label of
+ <literal>biba/equal</literal> on the &man.bge.4; interface.
+ When using a setting similar to
+ <literal>biba/high(low-high)</literal> the entire label should
+ be quoted; otherwise an error will be returned.</para>
+
+ <para>Each policy module which supports labeling has a tunable
+ which may be used to disable the <acronym>MAC</acronym>
+ label on network interfaces. Setting the label to
+ <option>equal</option> will have a similar effect. Review
+ the output from <command>sysctl</command>, the policy manual
+ pages, or even the information found later in this chapter
+ for those tunables.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Singlelabel or Multilabel?</title>
+<!-- Stopped here with my edits -->
+ <para>By default the system will use the
+ <option>singlelabel</option> option. But what does this
+ mean to the administrator? There are several differences
+ which, in their own right, offer pros and cons to the
+ flexibility in the systems security model.</para>
+
+ <para>The <option>singlelabel</option> only permits for one
+ label, for instance <literal>biba/high</literal> to be used
+ for each subject or object. It provides for lower
+ administration overhead but decreases the flexibility of
+ policies which support labeling. Many administrators may
+ want to use the <option>multilabel</option> option in
+ their security policy.</para>
+
+ <para>The <option>multilabel</option> option will permit each
+ subject or object to have its own independent
+ <acronym>MAC</acronym> label in
+ place of the standard <option>singlelabel</option> option
+ which will allow only one label throughout the partition.
+ The <option>multilabel</option> and <option>single</option>
+ label options are only required for the policies which
+ implement the labeling feature, including the Biba, Lomac,
+ <acronym>MLS</acronym> and <acronym>SEBSD</acronym>
+ policies.</para>
+
+ <para>In many cases, the <option>multilabel</option> may not need
+ to be set at all. Consider the following situation and
+ security model:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>&os; web-server using the <acronym>MAC</acronym>
+ framework and a mix of the various policies.</para>
+ </listitem>
+
+ <listitem>
+ <para>This machine only requires one label,
+ <literal>biba/high</literal>, for everything in the system.
+ Here the file system would not require the
+ <option>multilabel</option> option as a single label
+ will always be in effect.</para>
+ </listitem>
+
+ <listitem>
+ <para>But, this machine will be a web server and should have
+ the web server run at <literal>biba/low</literal> to prevent
+ write up capabilities. The Biba policy and how it works
+ will be discussed later, so if the previous comment was
+ difficult to interpret just continue reading and return.
+ The server could use a separate partition set at
+ <literal>biba/low</literal> for most if not all of its
+ runtime state. Much is lacking from this example, for
+ instance the restrictions on data, configuration and user
+ settings; however, this is just a quick example to prove the
+ aforementioned point.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>If any of the non-labeling policies are to be used,
+ then the <option>multilabel</option> option would never
+ be required. These include the <literal>seeotheruids</literal>,
+ <literal>portacl</literal> and <literal>partition</literal>
+ policies.</para>
+
+ <para>It should also be noted that using
+ <option>multilabel</option> with a partition and establishing
+ a security model based on <option>multilabel</option>
+ functionality could open the doors for higher administrative
+ overhead as everything in the file system would have a label.
+ This includes directories, files, and even device
+ nodes.</para>
+
+ <para>The following command will set <option>multilabel</option>
+ on the file systems to have multiple labels. This may only be
+ done in single user mode:</para>
+
+ <screen>&prompt.root; <userinput>tunefs -l enable /</userinput></screen>
+
+ <para>This is not a requirement for the swap file
+ system.</para>
+
+ <note>
+ <para>Some users have experienced problems with setting the
+ <option>multilabel</option> flag on the root partition.
+ If this is the case, please review the
+ <xref linkend="mac-troubleshoot"/> of this chapter.</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Controlling MAC with Tunables</title>
+
+ <para>Without any modules loaded, there are still some parts
+ of <acronym>MAC</acronym> which may be configured using
+ the <command>sysctl</command> interface. These tunables
+ are described below and in all cases the number one (1)
+ means enabled while the number zero (0) means
+ disabled:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>security.mac.enforce_fs</literal> defaults to
+ one (1) and enforces <acronym>MAC</acronym> file system
+ policies on the file systems.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.enforce_kld</literal> defaults to
+ one (1) and enforces <acronym>MAC</acronym> kernel linking
+ policies on the dynamic kernel linker (see
+ &man.kld.4;).</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.enforce_network</literal> defaults
+ to one (1) and enforces <acronym>MAC</acronym> network
+ policies.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.enforce_pipe</literal> defaults
+ to one (1) and enforces <acronym>MAC</acronym> policies
+ on pipes.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.enforce_process</literal> defaults
+ to one (1) and enforces <acronym>MAC</acronym> policies
+ on processes which utilize inter-process
+ communication.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.enforce_socket</literal> defaults
+ to one (1) and enforces <acronym>MAC</acronym> policies
+ on sockets (see the &man.socket.2; manual page).</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.enforce_system</literal> defaults
+ to one (1) and enforces <acronym>MAC</acronym> policies
+ on system activities such as accounting and
+ rebooting.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.enforce_vm</literal> defaults
+ to one (1) and enforces <acronym>MAC</acronym> policies
+ on the virtual memory system.</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <para>Every policy or <acronym>MAC</acronym> option supports
+ tunables. These usually hang off of the
+ <literal>security.mac.&lt;policyname&gt;</literal> tree.
+ To view all of the tunables from <acronym>MAC</acronym>
+ use the following command:</para>
+
+ <screen>&prompt.root; <userinput>sysctl -da | grep mac</userinput></screen>
+ </note>
+
+ <para>This should be interpreted as all of the basic
+ <acronym>MAC</acronym> policies are enforced by default.
+ If the modules were built into the kernel the system
+ would be extremely locked down and most likely unable to
+ communicate with the local network or connect to the Internet,
+ etc. This is why building the modules into the kernel is not
+ completely recommended. Not because it limits the ability to
+ disable features on the fly with <command>sysctl</command>,
+ but it permits the administrator to instantly switch the
+ policies of a system without the requirement of rebuilding
+ and reinstalling a new system.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="mac-modules">
+ <title>Module Configuration</title>
+
+ <para>Every module included with the <acronym>MAC</acronym>
+ framework may be either compiled into the kernel as noted above
+ or loaded as a run-time kernel module.
+ The recommended method is to add the module name to the
+ <filename>/boot/loader.conf</filename> file so that it will load
+ during the initial boot operation.</para>
+
+ <para>The following sections will discuss the various
+ <acronym>MAC</acronym> modules and cover their features.
+ Implementing them into a specific environment will also
+ be a consideration of this chapter. Some modules support
+ the use of labeling, which is controlling access by enforcing
+ a label such as <quote>this is allowed and this is not</quote>.
+ A label configuration file may control how files may be accessed,
+ network communication can be exchanged, and more. The previous
+ section showed how the <option>multilabel</option> flag could
+ be set on file systems to enable per-file or per-partition
+ access control.</para>
+
+ <para>A single label configuration would enforce only one label
+ across the system, that is why the <command>tunefs</command>
+ option is called <option>multilabel</option>.</para>
+
+ <sect2 xml:id="mac-seeotheruids">
+ <title>The MAC seeotheruids Module</title>
+
+ <indexterm>
+ <primary>MAC See Other UIDs Policy</primary>
+ </indexterm>
+ <para>Module name: <filename>mac_seeotheruids.ko</filename></para>
+
+ <para>Kernel configuration line:
+ <literal>options MAC_SEEOTHERUIDS</literal></para>
+
+ <para>Boot option:
+ <literal>mac_seeotheruids_load="YES"</literal></para>
+
+ <para>The &man.mac.seeotheruids.4; module mimics and extends
+ the <literal>security.bsd.see_other_uids</literal> and
+ <literal>security.bsd.see_other_gids</literal>
+ <command>sysctl</command> tunables. This option does
+ not require any labels to be set before configuration and
+ can operate transparently with the other modules.</para>
+
+ <para>After loading the module, the following
+ <command>sysctl</command> tunables may be used to control
+ the features:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>security.mac.seeotheruids.enabled</literal>
+ will enable the module's features and use the default
+ settings. These default settings will deny users the
+ ability to view processes and sockets owned by other
+ users.</para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>security.mac.seeotheruids.specificgid_enabled</literal>
+ will allow a certain group to be exempt from this policy.
+ To exempt specific groups from this policy, use the
+ <literal>security.mac.seeotheruids.specificgid=XXX</literal>
+ <command>sysctl</command> tunable. In the above example,
+ the <replaceable>XXX</replaceable> should be replaced with the
+ numeric group ID to be exempted.</para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>security.mac.seeotheruids.primarygroup_enabled</literal>
+ is used to exempt specific primary groups from this policy.
+ When using this tunable, the
+ <literal>security.mac.seeotheruids.specificgid_enabled</literal>
+ may not be set.</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="mac-bsdextended">
+ <title>The MAC bsdextended Module</title>
+
+ <indexterm>
+ <primary>MAC</primary>
+ <secondary>File System Firewall Policy</secondary>
+ </indexterm>
+ <para>Module name: <filename>mac_bsdextended.ko</filename></para>
+
+ <para>Kernel configuration line:
+ <literal>options MAC_BSDEXTENDED</literal></para>
+
+ <para>Boot option:
+ <literal>mac_bsdextended_load="YES"</literal></para>
+
+ <para>The &man.mac.bsdextended.4; module enforces the file system
+ firewall. This module's policy provides an extension to the
+ standard file system permissions model, permitting an
+ administrator to create a firewall-like ruleset to protect files,
+ utilities, and directories in the file system hierarchy.</para>
+
+ <para>The policy may be created using a utility, &man.ugidfw.8;,
+ that has a syntax similar to that of &man.ipfw.8;. More tools
+ can be written by using the functions in the
+ &man.libugidfw.3; library.</para>
+
+ <para>Extreme caution should be taken when working with this
+ module; incorrect use could block access to certain parts of
+ the file system.</para>
+
+ <sect2>
+ <title>Examples</title>
+
+ <para>After the &man.mac.bsdextended.4; module has
+ been loaded, the following command may be used to list the
+ current rule configuration:</para>
+
+ <screen>&prompt.root; <userinput>ugidfw list</userinput>
+0 slots, 0 rules</screen>
+
+ <para>As expected, there are no rules defined. This means that
+ everything is still completely accessible. To create a rule
+ which will block all access by users but leave
+ <systemitem class="username">root</systemitem> unaffected, simply run the
+ following command:</para>
+
+ <screen>&prompt.root; <userinput>ugidfw add subject not uid root new object not uid root mode n</userinput></screen>
+
+ <note>
+ <para>In releases prior to &os;&nbsp;5.3, the
+ <parameter>add</parameter> parameter did not exist. In those
+ cases the <parameter>set</parameter> should be used
+ instead. See below for a command example.</para></note>
+
+ <para>This is a very bad idea as it will block all users from
+ issuing even the most simple commands, such as
+ <command>ls</command>. A more patriotic list of rules
+ might be:</para>
+
+ <screen>&prompt.root; <userinput>ugidfw set 2 subject uid user1 object uid user2 mode n</userinput>
+&prompt.root; <userinput>ugidfw set 3 subject uid user1 object gid user2 mode n</userinput></screen>
+
+ <para>This will block any and all access, including directory
+ listings, to <systemitem class="username"><replaceable>user2</replaceable></systemitem>'s home
+ directory from the username <systemitem class="username">user1</systemitem>.</para>
+
+ <para>In place of <systemitem class="username">user1</systemitem>, the
+ <option>not uid <replaceable>user2</replaceable></option> could
+ be passed. This will enforce the same access restrictions
+ above for all users in place of just one user.</para>
+
+ <note>
+ <para>The <systemitem class="username">root</systemitem> user will be unaffected
+ by these changes.</para>
+ </note>
+
+ <para>This should give a general idea of how the
+ &man.mac.bsdextended.4; module may be used to help fortify
+ a file system. For more information, see the
+ &man.mac.bsdextended.4; and the &man.ugidfw.8; manual
+ pages.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="mac-ifoff">
+ <title>The MAC ifoff Module</title>
+
+ <indexterm>
+ <primary>MAC Interface Silencing Policy</primary>
+ </indexterm>
+ <para>Module name: <filename>mac_ifoff.ko</filename></para>
+
+ <para>Kernel configuration line:
+ <literal>options MAC_IFOFF</literal></para>
+
+ <para>Boot option: <literal>mac_ifoff_load="YES"</literal></para>
+
+ <para>The &man.mac.ifoff.4; module exists solely to disable network
+ interfaces on the fly and keep network interfaces from being
+ brought up during the initial system boot. It does not require
+ any labels to be set up on the system, nor does it have a
+ dependency on other <acronym>MAC</acronym> modules.</para>
+
+ <para>Most of the control is done through the
+ <command>sysctl</command> tunables listed below.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>security.mac.ifoff.lo_enabled</literal> will
+ enable/disable all traffic on the loopback (&man.lo.4;)
+ interface.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.ifoff.bpfrecv_enabled</literal> will
+ enable/disable all traffic on the Berkeley Packet Filter
+ interface (&man.bpf.4;)</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.ifoff.other_enabled</literal> will
+ enable/disable traffic on all other interfaces.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>One of the most common uses of &man.mac.ifoff.4; is network
+ monitoring in an environment where network traffic should not
+ be permitted during the boot sequence. Another suggested use
+ would be to write a script which uses
+ <package>security/aide</package> to automatically
+ block network traffic if it finds new or altered files in
+ protected directories.</para>
+ </sect1>
+
+ <sect1 xml:id="mac-portacl">
+ <title>The MAC portacl Module</title>
+
+ <indexterm>
+ <primary>MAC Port Access Control List Policy</primary>
+ </indexterm>
+ <para>Module name: <filename>mac_portacl.ko</filename></para>
+
+ <para>Kernel configuration line:
+ <literal>MAC_PORTACL</literal></para>
+
+ <para>Boot option: <literal>mac_portacl_load="YES"</literal></para>
+
+ <para>The &man.mac.portacl.4; module is used to limit binding to
+ local <acronym>TCP</acronym> and <acronym>UDP</acronym> ports
+ using a variety of <command>sysctl</command> variables. In
+ essence &man.mac.portacl.4; makes it possible to allow
+ non-<systemitem class="username">root</systemitem> users to bind to specified
+ privileged ports, i.e. ports fewer than 1024.</para>
+
+ <para>Once loaded, this module will enable the
+ <acronym>MAC</acronym> policy on all sockets. The following
+ tunables are available:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>security.mac.portacl.enabled</literal> will
+ enable/disable the policy completely.<footnote><para>Due to
+ a bug the <literal>security.mac.portacl.enabled</literal>
+ <command>sysctl</command> variable will not work on
+ &os;&nbsp;5.2.1 or previous releases.</para></footnote></para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.portacl.port_high</literal> will set
+ the highest port number that &man.mac.portacl.4;
+ will enable protection for.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.portacl.suser_exempt</literal> will,
+ when set to a non-zero value, exempt the
+ <systemitem class="username">root</systemitem> user from this policy.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.portacl.rules</literal> will
+ specify the actual mac_portacl policy; see below.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The actual <literal>mac_portacl</literal> policy, as
+ specified in the <literal>security.mac.portacl.rules</literal>
+ sysctl, is a text string of the form:
+ <literal>rule[,rule,...]</literal> with as many rules as
+ needed. Each rule is of the form:
+ <literal>idtype:id:protocol:port</literal>. The
+ <parameter>idtype</parameter> parameter can be
+ <literal>uid</literal> or <literal>gid</literal> and used to
+ interpret the <parameter>id</parameter> parameter as either a
+ user id or group id, respectively. The
+ <parameter>protocol</parameter> parameter is used to determine if
+ the rule should apply to <acronym>TCP</acronym> or
+ <acronym>UDP</acronym> by setting the parameter to
+ <literal>tcp</literal> or <literal>udp</literal>. The final
+ <parameter>port</parameter> parameter is the port number to allow
+ the specified user or group to bind to.</para>
+
+ <note>
+ <para>Since the ruleset is interpreted directly by the kernel
+ only numeric values can be used for the user ID, group ID, and
+ port parameters. I.e. user, group, and port service names
+ cannot be used.</para>
+ </note>
+
+ <para>By default, on &unix;-like systems, ports fewer than 1024
+ can only be used by/bound to privileged processes,
+ i.e. those run as <systemitem class="username">root</systemitem>. For
+ &man.mac.portacl.4; to allow non-privileged processes to bind
+ to ports below 1024 this standard &unix; restriction has to be
+ disabled. This can be accomplished by setting the &man.sysctl.8;
+ variables <literal>net.inet.ip.portrange.reservedlow</literal> and
+ <literal>net.inet.ip.portrange.reservedhigh</literal>
+ to zero.</para>
+
+ <para>See the examples below or review the &man.mac.portacl.4;
+ manual page for further information.</para>
+
+ <sect2>
+ <title>Examples</title>
+
+ <para>The following examples should illuminate the above
+ discussion a little better:</para>
+
+ <screen>&prompt.root; <userinput>sysctl security.mac.portacl.port_high=1023</userinput>
+&prompt.root; <userinput>sysctl net.inet.ip.portrange.reservedlow=0 net.inet.ip.portrange.reservedhigh=0</userinput></screen>
+
+ <para>First we set &man.mac.portacl.4; to cover the standard
+ privileged ports and disable the normal &unix; bind
+ restrictions.</para>
+
+ <screen>&prompt.root; <userinput>sysctl security.mac.portacl.suser_exempt=1</userinput></screen>
+
+ <para>The <systemitem class="username">root</systemitem> user should not be crippled
+ by this policy, thus set the
+ <literal>security.mac.portacl.suser_exempt</literal> to a
+ non-zero value. The &man.mac.portacl.4; module
+ has now been set up to behave the same way &unix;-like systems
+ behave by default.</para>
+
+ <screen>&prompt.root; <userinput>sysctl security.mac.portacl.rules=uid:80:tcp:80</userinput></screen>
+
+ <para>Allow the user with <acronym>UID</acronym> 80 (normally
+ the <systemitem class="username">www</systemitem> user) to bind to port 80.
+ This can be used to allow the <systemitem class="username">www</systemitem>
+ user to run a web server without ever having
+ <systemitem class="username">root</systemitem> privilege.</para>
+
+ <screen>&prompt.root; <userinput>sysctl security.mac.portacl.rules=uid:1001:tcp:110,uid:1001:tcp:995</userinput></screen>
+
+ <para>Permit the user with the <acronym>UID</acronym> of
+ 1001 to bind to the <acronym>TCP</acronym> ports 110
+ (<quote>pop3</quote>) and 995 (<quote>pop3s</quote>).
+ This will permit this user to start a server that accepts
+ connections on ports 110 and 995.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="mac-labelingpolicies">
+ <title>MAC Policies with Labeling Features</title>
+
+ <para>The next few sections will discuss <acronym>MAC</acronym>
+ policies which use labels.</para>
+
+ <para>From here on this chapter will focus on the features
+ of &man.mac.biba.4;, &man.mac.lomac.4;,
+ &man.mac.partition.4;, and &man.mac.mls.4;.</para>
+
+ <note>
+ <para>This is an example configuration only and should not be
+ considered for a production implementation. The goal is
+ to document and show the syntax as well as examples for
+ implementation and testing.</para>
+ </note>
+
+ <para>For these policies to work correctly several
+ preparations must be made.</para>
+
+ <sect2 xml:id="mac-prep">
+ <title>Preparation for Labeling Policies</title>
+
+ <para>The following changes are required in the
+ <filename>login.conf</filename> file:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>An <literal>insecure</literal> class, or another
+ class of similar type, must be
+ added. The login class of <literal>insecure</literal>
+ is not required and just used as an example here; different
+ configurations may use another class name.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <literal>insecure</literal> class should have
+ the following settings and definitions. Several of these
+ can be altered but the line which defines the default
+ label is a requirement and must remain.</para>
+
+ <programlisting>insecure:\
+ :copyright=/etc/COPYRIGHT:\
+ :welcome=/etc/motd:\
+ :setenv=MAIL=/var/mail/$,BLOCKSIZE=K:\
+ :path=~/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:\
+ :manpath=/usr/share/man /usr/local/man:\
+ :nologin=/usr/sbin/nologin:\
+ :cputime=1h30m:\
+ :datasize=8M:\
+ :vmemoryuse=100M:\
+ :stacksize=2M:\
+ :memorylocked=4M:\
+ :memoryuse=8M:\
+ :filesize=8M:\
+ :coredumpsize=8M:\
+ :openfiles=24:\
+ :maxproc=32:\
+ :priority=0:\
+ :requirehome:\
+ :passwordtime=91d:\
+ :umask=022:\
+ :ignoretime@:\
+ :label=partition/13,mls/5,biba/low:</programlisting>
+
+ <para>The &man.cap.mkdb.1; command needs to be ran on
+ &man.login.conf.5; before any of the
+ users can be switched over to the new class.</para>
+
+ <para>The <systemitem class="username">root</systemitem> username should also be placed
+ into a login class; otherwise, almost every command
+ executed by <systemitem class="username">root</systemitem> will require the
+ use of <command>setpmac</command>.</para>
+
+ <warning>
+ <para>Rebuilding the <filename>login.conf</filename>
+ database may cause some errors later with the daemon
+ class. Simply uncommenting the daemon account and
+ rebuilding the database should alleviate these
+ issues.</para>
+ </warning>
+ </listitem>
+
+ <listitem>
+ <para>Ensure that all partitions on which
+ <acronym>MAC</acronym> labeling will be implemented support
+ the <option>multilabel</option>. We must do this because
+ many of the examples here contain different labels for
+ testing purposes. Review the output from the
+ <command>mount</command> command as a precautionary
+ measure.</para>
+ </listitem>
+
+ <listitem>
+ <para>Switch any users who will have the higher security
+ mechanisms enforced over to the new user class. A quick
+ run of &man.pw.8; or &man.vipw.8; should do the
+ trick.</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="mac-partition">
+ <title>The MAC partition Module</title>
+
+ <indexterm>
+ <primary>MAC Process Partition Policy</primary>
+ </indexterm>
+ <para>Module name: <filename>mac_partition.ko</filename></para>
+
+ <para>Kernel configuration line:
+ <literal>options MAC_PARTITION</literal></para>
+
+ <para>Boot option:
+ <literal>mac_partition_load="YES"</literal></para>
+
+ <para>The &man.mac.partition.4; policy will drop processes into
+ specific <quote>partitions</quote> based on their
+ <acronym>MAC</acronym> label. Think of it as a special
+ type of &man.jail.8;, though that is hardly a worthy
+ comparison.</para>
+
+ <para>This is one module that should be added to the
+ &man.loader.conf.5; file so that it loads
+ and enables the policy during the boot process.</para>
+
+ <para>Most configuration for this policy is done using
+ the &man.setpmac.8; utility which will be explained below.
+ The following <command>sysctl</command> tunable is
+ available for this policy:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>security.mac.partition.enabled</literal> will
+ enable the enforcement of <acronym>MAC</acronym> process
+ partitions.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>When this policy is enabled, users will only be permitted
+ to see their processes but will not be permitted to work with
+ certain utilities. For instance, a user in the
+ <literal>insecure</literal> class above will not be permitted
+ to access the <command>top</command> command as well as many
+ other commands that must spawn a process.</para>
+
+ <para>To set or drop utilities into a partition label, use the
+ <command>setpmac</command> utility:</para>
+
+ <screen>&prompt.root; <userinput>setpmac partition/13 top</userinput></screen>
+
+ <para>This will add the <command>top</command> command to the
+ label set on users in the <literal>insecure</literal> class.
+ Note that all processes spawned by users
+ in the <literal>insecure</literal> class will stay in the
+ <literal>partition/13</literal> label.</para>
+
+ <sect2>
+ <title>Examples</title>
+
+ <para>The following command will show you the partition label
+ and the process list:</para>
+
+ <screen>&prompt.root; <userinput>ps Zax</userinput></screen>
+
+ <para>This next command will allow the viewing of another
+ user's process partition label and that user's currently
+ running processes:</para>
+
+ <screen>&prompt.root; <userinput>ps -ZU trhodes</userinput></screen>
+
+ <note>
+ <para>Users can see processes in <systemitem class="username">root</systemitem>'s
+ label unless the &man.mac.seeotheruids.4; policy is
+ loaded.</para>
+ </note>
+
+ <para>A really crafty implementation could have all of the
+ services disabled in <filename>/etc/rc.conf</filename> and
+ started by a script that starts them with the proper
+ labeling set.</para>
+
+ <note>
+ <para>The following policies support integer settings
+ in place of the three default labels offered. These options,
+ including their limitations, are further explained in
+ the module manual pages.</para>
+ </note>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="mac-mls">
+ <title>The MAC Multi-Level Security Module</title>
+
+ <indexterm>
+ <primary>MAC Multi-Level Security Policy</primary>
+ </indexterm>
+ <para>Module name: <filename>mac_mls.ko</filename></para>
+
+ <para>Kernel configuration line:
+ <literal>options MAC_MLS</literal></para>
+
+ <para>Boot option: <literal>mac_mls_load="YES"</literal></para>
+
+ <para>The &man.mac.mls.4; policy controls access between subjects
+ and objects in the system by enforcing a strict information
+ flow policy.</para>
+
+ <para>In <acronym>MLS</acronym> environments, a
+ <quote>clearance</quote> level is set in each subject or objects
+ label, along with compartments. Since these clearance or
+ sensibility levels can reach numbers greater than six thousand;
+ it would be a daunting task for any system administrator to
+ thoroughly configure each subject or object. Thankfully, three
+ <quote>instant</quote> labels are already included in this
+ policy.</para>
+
+ <para>These labels are <literal>mls/low</literal>,
+ <literal>mls/equal</literal> and <literal>mls/high</literal>.
+ Since these labels are described in depth in the manual page,
+ they will only get a brief description here:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The <literal>mls/low</literal> label contains a low
+ configuration which permits it to be dominated by all other
+ objects. Anything labeled with <literal>mls/low</literal>
+ will have a low clearance level and not be permitted to access
+ information of a higher level. In addition, this label will
+ prevent objects of a higher clearance level from writing or
+ passing information on to them.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <literal>mls/equal</literal> label should be
+ placed on objects considered to be exempt from the
+ policy.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <literal>mls/high</literal> label is the highest level
+ of clearance possible. Objects assigned this label will
+ hold dominance over all other objects in the system; however,
+ they will not permit the leaking of information to objects
+ of a lower class.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><acronym>MLS</acronym> provides for:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>A hierarchical security level with a set of non
+ hierarchical categories;</para>
+ </listitem>
+
+ <listitem>
+ <para>Fixed rules: no read up, no write down (a subject can
+ have read access to objects on its own level or below, but
+ not above. Similarly, a subject can have write access to
+ objects on its own level or above but not beneath.);</para>
+ </listitem>
+
+ <listitem>
+ <para>Secrecy (preventing inappropriate disclosure
+ of data);</para>
+ </listitem>
+
+ <listitem>
+ <para>Basis for the design of systems that concurrently handle
+ data at multiple sensitivity levels (without leaking
+ information between secret and confidential).</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The following <command>sysctl</command> tunables are
+ available for the configuration of special services and
+ interfaces:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>security.mac.mls.enabled</literal> is used to
+ enable/disable the <acronym>MLS</acronym> policy.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.mls.ptys_equal</literal> will label
+ all &man.pty.4; devices as <literal>mls/equal</literal> during
+ creation.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.mls.revocation_enabled</literal> is
+ used to revoke access to objects after their label changes
+ to a label of a lower grade.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.mls.max_compartments</literal> is
+ used to set the maximum number of compartment levels with
+ objects; basically the maximum compartment number allowed
+ on a system.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>To manipulate the <acronym>MLS</acronym> labels, the
+ &man.setfmac.8; command has been provided. To assign a label
+ to an object, issue the following command:</para>
+
+ <screen>&prompt.root; <userinput>setfmac mls/5 test</userinput></screen>
+
+ <para>To get the <acronym>MLS</acronym> label for the file
+ <filename>test</filename> issue the following command:</para>
+
+ <screen>&prompt.root; <userinput>getfmac test</userinput></screen>
+
+ <para>This is a summary of the <acronym>MLS</acronym>
+ policy's features. Another approach is to create a master policy
+ file in <filename>/etc</filename> which
+ specifies the <acronym>MLS</acronym> policy information and to
+ feed that file into the <command>setfmac</command> command. This
+ method will be explained after all policies are covered.</para>
+
+ <para>Observations: an object with lower clearance is unable to
+ observe higher clearance processes. A basic policy would be
+ to enforce <literal>mls/high</literal> on everything not to be
+ read, even if it needs to be written. Enforce
+ <literal>mls/low</literal> on everything not to be written, even
+ if it needs to be read. And finally enforce
+ <literal>mls/equal</literal> on the rest. All users marked
+ <literal>insecure</literal> should be set at
+ <literal>mls/low</literal>.</para>
+ </sect1>
+
+ <sect1 xml:id="mac-biba">
+ <title>The MAC Biba Module</title>
+
+ <indexterm>
+ <primary>MAC Biba Integrity Policy</primary>
+ </indexterm>
+ <para>Module name: <filename>mac_biba.ko</filename></para>
+
+ <para>Kernel configuration line: <literal>options MAC_BIBA</literal></para>
+
+ <para>Boot option: <literal>mac_biba_load="YES"</literal></para>
+
+ <para>The &man.mac.biba.4; module loads the <acronym>MAC</acronym>
+ Biba policy. This policy works much like that of the
+ <acronym>MLS</acronym> policy with the exception that the rules
+ for information flow
+ are slightly reversed. This is said to prevent the downward
+ flow of sensitive information whereas the <acronym>MLS</acronym>
+ policy prevents the upward flow of sensitive information; thus,
+ much of this section can apply to both policies.</para>
+
+ <para>In Biba environments, an <quote>integrity</quote> label is
+ set on each subject or object. These labels are made up of
+ hierarchal grades, and non-hierarchal components. As an object's
+ or subject's grade ascends, so does its integrity.</para>
+
+ <para>Supported labels are <literal>biba/low</literal>,
+ <literal>biba/equal</literal>, and <literal>biba/high</literal>;
+ as explained below:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The <literal>biba/low</literal> label is considered the
+ lowest integrity an object or subject may have. Setting
+ this on objects or subjects will block their write access
+ to objects or subjects marked high. They still have read
+ access though.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <literal>biba/equal</literal> label should only be
+ placed on objects considered to be exempt from the
+ policy.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <literal>biba/high</literal> label will permit
+ writing to objects set at a lower label, but not
+ permit reading that object. It is recommended that this
+ label be placed on objects that affect the integrity of
+ the entire system.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Biba provides for:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Hierarchical integrity level with a set of non
+ hierarchical integrity categories;</para>
+ </listitem>
+
+ <listitem>
+ <para>Fixed rules: no write up, no read down (opposite of
+ <acronym>MLS</acronym>). A subject can have write access
+ to objects on its own level or below, but not above. Similarly, a
+ subject can have read access to objects on its own level
+ or above, but not below;</para>
+ </listitem>
+
+ <listitem>
+ <para>Integrity (preventing inappropriate modification of
+ data);</para>
+ </listitem>
+
+ <listitem>
+ <para>Integrity levels (instead of MLS sensitivity
+ levels).</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The following <command>sysctl</command> tunables can
+ be used to manipulate the Biba policy.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>security.mac.biba.enabled</literal> may be used
+ to enable/disable enforcement of the Biba policy on the
+ target machine.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.biba.ptys_equal</literal> may be
+ used to disable the Biba policy on &man.pty.4;
+ devices.</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>security.mac.biba.revocation_enabled</literal>
+ will force the revocation of access to objects if the label
+ is changed to dominate the subject.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>To access the Biba policy setting on system objects, use
+ the <command>setfmac</command> and <command>getfmac</command>
+ commands:</para>
+
+ <screen>&prompt.root; <userinput>setfmac biba/low test</userinput>
+&prompt.root; <userinput>getfmac test</userinput>
+test: biba/low</screen>
+
+ <para>Observations: a lower integrity subject is unable to write
+ to a higher integrity subject; a higher integrity subject cannot
+ observe or read a lower integrity object.</para>
+ </sect1>
+
+ <sect1 xml:id="mac-lomac">
+ <title>The MAC LOMAC Module</title>
+
+ <indexterm>
+ <primary>MAC LOMAC</primary>
+ </indexterm>
+ <para>Module name: <filename>mac_lomac.ko</filename></para>
+
+ <para>Kernel configuration line: <literal>options MAC_LOMAC</literal></para>
+ <para>Boot option: <literal>mac_lomac_load="YES"</literal></para>
+
+ <para>Unlike the <acronym>MAC</acronym> Biba policy, the
+ &man.mac.lomac.4; policy permits access to lower integrity
+ objects only after decreasing the integrity level to not disrupt
+ any integrity rules.</para>
+
+ <para>The <acronym>MAC</acronym> version of the Low-watermark
+ integrity policy, not to be confused with the older &man.lomac.4;
+ implementation, works almost identically to Biba, but with the
+ exception of using floating labels to support subject
+ demotion via an auxiliary grade compartment. This secondary
+ compartment takes the form of <literal>[auxgrade]</literal>.
+ When assigning a lomac policy with an auxiliary grade, it
+ should look a little bit like: <literal>lomac/10[2]</literal>
+ where the number two (2) is the auxiliary grade.</para>
+
+ <para>The <acronym>MAC</acronym> LOMAC policy relies on the
+ ubiquitous labeling of all system objects with integrity labels,
+ permitting subjects to read from low integrity objects and then
+ downgrading the label on the subject to prevent future writes to
+ high integrity objects. This is the
+ <literal>[auxgrade]</literal> option discussed above, thus the
+ policy may provide for greater compatibility and require less
+ initial configuration than Biba.</para>
+
+ <sect2>
+ <title>Examples</title>
+
+ <para>Like the Biba and <acronym>MLS</acronym> policies;
+ the <command>setfmac</command> and <command>setpmac</command>
+ utilities may be used to place labels on system objects:</para>
+
+ <screen>&prompt.root; <userinput>setfmac /usr/home/trhodes lomac/high[low]</userinput>
+&prompt.root; <userinput>getfmac /usr/home/trhodes</userinput> lomac/high[low]</screen>
+
+ <para>Notice the auxiliary grade here is <literal>low</literal>,
+ this is a feature provided only by the <acronym>MAC</acronym>
+ LOMAC policy.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="mac-implementing">
+ <title>Implementing a Secure Environment with MAC</title>
+
+ <indexterm>
+ <primary>MAC Example Implementation</primary>
+ </indexterm>
+
+ <para>The following demonstration will implement a secure
+ environment using various <acronym>MAC</acronym> modules
+ with properly configured policies. This is only a test and
+ should not be considered the complete answer to everyone's
+ security woes. Just implementing a policy and ignoring it
+ never works and could be disastrous in a production
+ environment.</para>
+
+ <para>Before beginning this process, the
+ <literal>multilabel</literal> option must be set on each file
+ system as stated at the beginning of this chapter. Not doing
+ so will result in errors.</para>
+
+ <sect2>
+ <title>Create an insecure User Class</title>
+
+ <para>Begin the procedure by adding the following user class
+ to the <filename>/etc/login.conf</filename> file:</para>
+
+ <programlisting>insecure:\
+:copyright=/etc/COPYRIGHT:\
+:welcome=/etc/motd:\
+:setenv=MAIL=/var/mail/$,BLOCKSIZE=K:\
+:path=~/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
+:manpath=/usr/share/man /usr/local/man:\
+:nologin=/usr/sbin/nologin:\
+:cputime=1h30m:\
+:datasize=8M:\
+:vmemoryuse=100M:\
+:stacksize=2M:\
+:memorylocked=4M:\
+:memoryuse=8M:\
+:filesize=8M:\
+:coredumpsize=8M:\
+:openfiles=24:\
+:maxproc=32:\
+:priority=0:\
+:requirehome:\
+:passwordtime=91d:\
+:umask=022:\
+:ignoretime@:\
+:label=partition/13,mls/5:</programlisting>
+
+ <para>And adding the following line to the default user
+ class:</para>
+
+ <programlisting>:label=mls/equal,biba/equal,partition/15:</programlisting>
+
+ <para>Once this is completed, the following command must be
+ issued to rebuild the database:</para>
+
+ <screen>&prompt.root; <userinput>cap_mkdb /etc/login.conf</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Boot with the Correct Modules</title>
+
+ <para>Add the following lines to
+ <filename>/boot/loader.conf</filename> so the required
+ modules will load during system initialization:</para>
+
+ <programlisting>mac_biba_load="YES"
+mac_mls_load="YES"
+mac_seeotheruids_load="YES"
+mac_partition_load="YES"</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Set All Users to Insecure</title>
+
+ <para>All user accounts that are not <systemitem class="username">root</systemitem>
+ or system users will now require a login class. The login
+ class is required otherwise users will be refused access
+ to common commands such as &man.vi.1;.
+ The following <command>sh</command> script should do the
+ trick:</para>
+
+ <screen>&prompt.root; <userinput>for x in `awk -F: '($3 &gt;= 1001) &amp;&amp; ($3 != 65534) { print $1 }' \</userinput>
+ <userinput>/etc/passwd`; do pw usermod $x -L insecure; done;</userinput></screen>
+
+ <para>The <command>cap_mkdb</command> command will need to be
+ run on <filename>/etc/master.passwd</filename> after this
+ change.</para>
+ </sect2>
+
+ <sect2>
+ <title>Complete the Configuration</title>
+
+ <para>A contexts file should now be created; the following
+ example was taken from Robert Watson's example policy and
+ should be placed in
+ <filename>/etc/policy.contexts</filename>.</para>
+
+ <programlisting># This is the default BIBA/MLS policy for this system.
+
+.* biba/high,mls/high
+/sbin/dhclient biba/high(low),mls/high(low)
+/dev(/.*)? biba/equal,mls/equal
+# This is not an exhaustive list of all "privileged" devices.
+/dev/mdctl biba/high,mls/high
+/dev/pci biba/high,mls/high
+/dev/k?mem biba/high,mls/high
+/dev/io biba/high,mls/high
+/dev/agp.* biba/high,mls/high
+(/var)?/tmp(/.*)? biba/equal,mls/equal
+/tmp/\.X11-unix biba/high(equal),mls/high(equal)
+/tmp/\.X11-unix/.* biba/equal,mls/equal
+/proc(/.*)? biba/equal,mls/equal
+/mnt.* biba/low,mls/low
+(/usr)?/home biba/high(low),mls/high(low)
+(/usr)?/home/.* biba/low,mls/low
+/var/mail(/.*)? biba/low,mls/low
+/var/spool/mqueue(/.*)? biba/low,mls/low
+(/mnt)?/cdrom(/.*)? biba/high,mls/high
+(/usr)?/home/(ftp|samba)(/.*)? biba/high,mls/high
+/var/log/sendmail\.st biba/low,mls/low
+/var/run/utmp biba/equal,mls/equal
+/var/log/(lastlog|wtmp) biba/equal,mls/equal</programlisting>
+
+ <para>This policy will enforce security by setting restrictions
+ on both the downward and upward flow of information with
+ regards to the directories and utilities listed on the
+ left.</para>
+
+ <para>This can now be read into our system by issuing the
+ following command:</para>
+
+ <screen>&prompt.root; <userinput>setfsmac -ef /etc/policy.contexts /</userinput>
+&prompt.root; <userinput>setfsmac -ef /etc/policy.contexts /usr</userinput></screen>
+
+ <note>
+ <para>The above file system layout may be different depending
+ on environment.</para>
+ </note>
+
+ <para>The <filename>/etc/mac.conf</filename> file requires
+ the following modifications in the main section:</para>
+
+ <programlisting>default_labels file ?biba,?mls
+default_labels ifnet ?biba,?mls
+default_labels process ?biba,?mls,?partition
+default_labels socket ?biba,?mls</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Testing the Configuration</title>
+
+ <indexterm>
+ <primary>MAC Configuration Testing</primary>
+ </indexterm>
+
+ <para>Add a user with the <command>adduser</command> command
+ and place that user in the <literal>insecure</literal>
+ class for these tests.</para>
+
+ <para>The examples below will show a mix of
+ <systemitem class="username">root</systemitem> and regular user tests; use the
+ prompt to distinguish between the two.</para>
+
+ <sect3>
+ <title>Basic Labeling Tests</title>
+
+ <screen>&prompt.user; <userinput>getpmac</userinput>
+biba/15(15-15),mls/15(15-15),partition/15
+&prompt.root; <userinput>setpmac partition/15,mls/equal top</userinput></screen>
+
+ <note>
+ <para>The top process will be killed before we start
+ another top process.</para>
+ </note>
+ </sect3>
+
+ <sect3>
+ <title>MAC Seeotheruids Tests</title>
+
+ <screen>&prompt.user; <userinput>ps Zax</userinput>
+biba/15(15-15),mls/15(15-15),partition/15 1096 #C: S 0:00.03 -su (bash)
+biba/15(15-15),mls/15(15-15),partition/15 1101 #C: R+ 0:00.01 ps Zax</screen>
+
+ <para>We should not be permitted to see any processes
+ owned by other users.</para>
+ </sect3>
+
+ <sect3>
+ <title>MAC Partition Test</title>
+
+ <para>Disable the <acronym>MAC</acronym>
+ <literal>seeotheruids</literal> policy for the rest of these
+ tests:</para>
+
+ <screen>&prompt.root; <userinput>sysctl security.mac.seeotheruids.enabled=0</userinput>
+&prompt.user; <userinput>ps Zax</userinput>
+LABEL PID TT STAT TIME COMMAND
+ biba/equal(low-high),mls/equal(low-high),partition/15 1122 #C: S+ 0:00.02 top
+ biba/15(15-15),mls/15(15-15),partition/15 1096 #C: S 0:00.05 -su (bash)
+ biba/15(15-15),mls/15(15-15),partition/15 1123 #C: R+ 0:00.01 ps Zax</screen>
+
+ <para>All users should be permitted to see every process in
+ their partition.</para>
+ </sect3>
+
+ <sect3>
+ <title>Testing Biba and MLS Labels</title>
+
+ <screen>&prompt.root; <userinput>setpmac partition/15,mls/equal,biba/high\(high-high\) top</userinput>
+&prompt.user; <userinput>ps Zax</userinput>
+LABEL PID TT STAT TIME COMMAND
+ biba/high(high-high),mls/equal(low-high),partition/15 1251 #C: S+ 0:00.02 top
+ biba/15(15-15),mls/15(15-15),partition/15 1096 #C: S 0:00.06 -su (bash)
+ biba/15(15-15),mls/15(15-15),partition/15 1157 #C: R+ 0:00.00 ps Zax</screen>
+
+ <para>The Biba policy allows us to read higher-labeled
+ objects.</para>
+
+ <screen>&prompt.root; <userinput>setpmac partition/15,mls/equal,biba/low top</userinput>
+&prompt.user; <userinput>ps Zax</userinput>
+LABEL PID TT STAT TIME COMMAND
+ biba/15(15-15),mls/15(15-15),partition/15 1096 #C: S 0:00.07 -su (bash)
+ biba/15(15-15),mls/15(15-15),partition/15 1226 #C: R+ 0:00.01 ps Zax</screen>
+
+ <para>The Biba policy does not allow lower-labeled objects
+ to be read; however, <acronym>MLS</acronym> does.</para>
+
+ <screen>&prompt.user; <userinput>ifconfig bge0 | grep maclabel</userinput>
+maclabel biba/low(low-low),mls/low(low-low)
+&prompt.user; <userinput>ping -c 1 192.0.34.166</userinput>
+PING 192.0.34.166 (192.0.34.166): 56 data bytes
+ping: sendto: Permission denied</screen>
+
+ <para>Users are unable to ping
+ <systemitem class="fqdomainname">example.com</systemitem>, or any domain
+ for that matter.</para>
+
+ <para>To prevent this error from occurring, run the following
+ command:</para>
+
+ <screen>&prompt.root; <userinput>sysctl security.mac.biba.trust_all_interfaces=1</userinput></screen>
+
+ <para>This sets the default interface label to insecure mode,
+ so the default Biba policy label will not be enforced.</para>
+
+ <screen>&prompt.root; <userinput>ifconfig bge0 maclabel biba/equal\(low-high\),mls/equal\(low-high\)</userinput>
+&prompt.user; <userinput>ping -c 1 192.0.34.166</userinput>
+PING 192.0.34.166 (192.0.34.166): 56 data bytes
+64 bytes from 192.0.34.166: icmp_seq=0 ttl=50 time=204.455 ms
+--- 192.0.34.166 ping statistics ---
+1 packets transmitted, 1 packets received, 0% packet loss
+round-trip min/avg/max/stddev = 204.455/204.455/204.455/0.000 ms</screen>
+
+ <para>By setting a more correct label, we can issue
+ <command>ping</command> requests.</para>
+
+ <para>Now to create a few files for some read and write
+ testing procedures:</para>
+
+ <screen>&prompt.root; <userinput>touch test1 test2 test3 test4 test5</userinput>
+&prompt.root; <userinput>getfmac test1</userinput>
+test1: biba/equal,mls/equal
+&prompt.root; <userinput>setfmac biba/low test1 test2; setfmac biba/high test4 test5; \
+ setfmac mls/low test1 test3; setfmac mls/high test2 test4</userinput>
+&prompt.root; <userinput>setfmac mls/equal,biba/equal test3 &amp;&amp; getfmac test?</userinput>
+test1: biba/low,mls/low
+test2: biba/low,mls/high
+test3: biba/equal,mls/equal
+test4: biba/high,mls/high
+test5: biba/high,mls/equal
+&prompt.root; <userinput>chown testuser:testuser test?</userinput></screen>
+
+ <para>All of these files should now be owned by our
+ <systemitem class="username">testuser</systemitem> user. And now for some read
+ tests:</para>
+
+ <screen>&prompt.user; <userinput>ls</userinput>
+test1 test2 test3 test4 test5
+&prompt.user; <userinput>ls test?</userinput>
+ls: test1: Permission denied
+ls: test2: Permission denied
+ls: test4: Permission denied
+test3 test5</screen>
+
+ <para>We should not be permitted to observe pairs; e.g.:
+ <literal>(biba/low,mls/low)</literal>,
+ <literal>(biba/low,mls/high)</literal> and
+ <literal>(biba/high,mls/high)</literal>. And of course,
+ read access should be denied. Now for some write
+ tests:</para>
+
+ <screen>&prompt.user; <userinput>for i in `echo test*`; do echo 1 &gt; $i; done</userinput>
+-su: test1: Permission denied
+-su: test4: Permission denied
+-su: test5: Permission denied</screen>
+
+ <para>Like with the read tests, write access should not be
+ permitted to write pairs; e.g.:
+ <literal>(biba/low,mls/high)</literal> and
+ <literal>(biba/equal,mls/equal)</literal>.</para>
+
+ <screen>&prompt.user; <userinput>cat test?</userinput>
+cat: test1: Permission denied
+cat: test2: Permission denied
+1
+cat: test4: Permission denied</screen>
+
+ <para>And now as <systemitem class="username">root</systemitem>:</para>
+
+ <screen>&prompt.root; <userinput>cat test2</userinput>
+1</screen>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="MAC-examplehttpd">
+ <title>Another Example: Using MAC to Constrain a Web Server</title>
+
+ <para>A separate location for the web data which users
+ must be capable of accessing will be appointed. This
+ will permit <literal>biba/high</literal> processes access
+ rights to the web data.</para>
+
+ <para>Begin by creating a directory to store the web
+ data in:</para>
+
+ <screen>&prompt.root; <userinput>mkdir /usr/home/cvs</userinput></screen>
+
+ <para>Now initialize it with <command>cvs</command>:</para>
+
+ <screen>&prompt.root; <userinput>cvs -d /usr/home/cvs init</userinput></screen>
+
+ <para>The first goal is to enable the <literal>biba</literal>
+ policy, thus the <literal>mac_biba_enable="YES"</literal>
+ should be placed in
+ <filename>/boot/loader.conf</filename>. This assumes
+ that support for <acronym>MAC</acronym> has been enabled
+ in the kernel.</para>
+
+ <para>From this point on everything in the system should
+ be set at <literal>biba/high</literal> by default.</para>
+
+ <para>The following modification must be made to the
+ <filename>login.conf</filename> file, under the default
+ user class:</para>
+
+ <programlisting>:ignoretime@:\
+ :umask=022:\
+ :label=biba/high:</programlisting>
+
+ <para>Every user should now be placed in the default class;
+ a command such as:</para>
+
+ <screen>&prompt.root; <userinput>for x in `awk -F: '($3 &gt;= 1001) &amp;&amp; ($3 != 65534) { print $1 }' \</userinput>
+ <userinput>/etc/passwd`; do pw usermod $x -L default; done;</userinput></screen>
+
+ <para>will accomplish this task in a few moments.</para>
+
+ <para>Now create another class, web, a copy of default,
+ with the label setting of <literal>biba/low</literal>.</para>
+
+ <para>Create a user who will be used to work with the
+ main web data stored in a <application>cvs</application>
+ repository. This user must be placed in our new login
+ class, <systemitem class="username">web</systemitem>.</para>
+
+ <para>Since the default is <literal>biba/high</literal>
+ everywhere, the repository will be the same. The web data must
+ also be the same for users to have read/write access to it;
+ however, since our web server will be serving data that
+ <literal>biba/high</literal> users must access, we will need to
+ downgrade the data as a whole.</para>
+
+ <para>The perfect tools for this are &man.sh.1; and
+ &man.cron.8; and are already provided in &os;. The following
+ script should do everything we want:</para>
+
+ <programlisting>PATH=/bin:/usr/bin:/usr/local/bin; export PATH;
+CVSROOT=/home/repo; export CVSROOT;
+cd /home/web;
+cvs -qR checkout -P htdocs;
+exit;</programlisting>
+
+ <note>
+ <para>In many cases the <command>cvs</command>
+ Id tags must be placed into the web
+ site data files.</para>
+ </note>
+
+ <para>This script may now be placed into
+ <systemitem class="username">web</systemitem>'s home directory and the following
+ &man.crontab.1; entry added:</para>
+
+ <programlisting># Check out the web data as biba/low every twelve hours:
+0 */12 * * * web /home/web/checkout.sh</programlisting>
+
+ <para>This will check out the <acronym>HTML</acronym> sources
+ every twelve hours on the machine.</para>
+
+ <para>The default startup method for the web server must also be
+ modified to start the process as <literal>biba/low</literal>.
+ This can be done by making the following modification to the
+ <filename>/usr/local/etc/rc.d/apache.sh</filename>
+ script:</para>
+
+ <programlisting>command="setpmac biba/low /usr/local/sbin/httpd"</programlisting>
+
+ <para>The <application>Apache</application> configuration must be
+ altered to work with the <literal>biba/low</literal> policy. In
+ this case the software must be configured to append to the
+ log files in a directory set at <literal>biba/low</literal>
+ or else <errorname>access denied</errorname> errors will be
+ returned.</para>
+
+ <note>
+ <para>Following this example requires that the
+ <literal>docroot</literal> directive be set to
+ <filename>/home/web/htdocs</filename>; otherwise,
+ <application>Apache</application> will fail when trying
+ to locate the directory to serve documents from.</para>
+ </note>
+
+ <para>Other configuration variables must be altered as well,
+ including the <acronym>PID</acronym> file,
+ <literal>Scoreboardfile</literal>,
+ <literal>DocumentRoot</literal>, log file locations, or any
+ other variable which requires write access.
+ When using <literal>biba</literal>, all write access will be
+ denied to the server in areas <emphasis>not</emphasis> set at
+ <literal>biba/low</literal>.</para>
+<!--
+PROBLEM: CAN THIS WORK? OR SHOULD IT BE start_precmd? More testing need here.
+-->
+ </sect1>
+
+<!--
+XXX
+
+ <sect1 id="mac-examplesandbox">
+ <title>An Example of a MAC Sandbox</title>
+
+ <para>An example of placing users in a sandbox using
+ <acronym>MAC</acronym> should go here.</para>
+ </sect1>
+-->
+
+ <sect1 xml:id="mac-troubleshoot">
+ <title>Troubleshooting the MAC Framework</title>
+
+ <indexterm>
+ <primary>MAC Troubleshooting</primary>
+ </indexterm>
+
+ <para>During the development stage, a few users reported problems
+ with normal configuration. Some of these problems
+ are listed below:</para>
+
+ <sect2>
+ <title>The <option>multilabel</option> option cannot be enabled on
+ <filename>/</filename></title>
+
+ <para>The <option>multilabel</option> flag does not stay
+ enabled on my root (<filename>/</filename>) partition!</para>
+
+
+ <para>It seems that one out of every fifty users has this
+ problem, indeed, we had this problem during our initial
+ configuration. Further observation of this so called
+ <quote>bug</quote> has lead me to believe that it is a
+ result of either incorrect documentation or misinterpretation
+ of the documentation. Regardless of why it happened, the
+ following steps may be taken to resolve it:</para>
+
+ <procedure>
+ <step>
+ <para>Edit <filename>/etc/fstab</filename> and set the root
+ partition at <option>ro</option> for read-only.</para>
+ </step>
+
+ <step>
+ <para>Reboot into single user mode.</para>
+ </step>
+
+ <step>
+ <para>Run <command>tunefs</command> <option>-l enable</option>
+ on <filename>/</filename>.</para>
+ </step>
+
+ <step>
+ <para>Reboot the system into normal mode.</para>
+ </step>
+
+ <step>
+ <para>Run <command>mount</command> <option>-urw</option>
+ <filename>/</filename> and change the <option>ro</option>
+ back to <option>rw</option> in <filename>/etc/fstab</filename>
+ and reboot the system again.</para>
+ </step>
+
+ <step>
+ <para>Double-check the output from the
+ <command>mount</command> to ensure that
+ <option>multilabel</option> has been properly set on the
+ root file system.</para>
+ </step>
+ </procedure>
+ </sect2>
+
+ <sect2>
+ <title>Cannot start a X11 server after <acronym>MAC</acronym></title>
+
+ <para>After establishing a secure environment with
+ <acronym>MAC</acronym>, I am no longer able to start
+ X!</para>
+
+ <para>This could be caused by the <acronym>MAC</acronym>
+ <literal>partition</literal> policy or by a mislabeling in
+ one of the <acronym>MAC</acronym> labeling policies. To
+ debug, try the following:</para>
+
+ <procedure>
+ <step>
+ <para>Check the error message; if the user is in the
+ <literal>insecure</literal> class, the
+ <literal>partition</literal> policy may be the culprit.
+ Try setting the user's class back to the
+ <literal>default</literal> class and rebuild the database
+ with the <command>cap_mkdb</command> command. If this
+ does not alleviate the problem, go to step two.</para>
+ </step>
+
+ <step>
+ <para>Double-check the label policies. Ensure that the
+ policies are set correctly for the user in question, the
+ X11 application, and
+ the <filename>/dev</filename>
+ entries.</para>
+ </step>
+
+ <step>
+ <para>If neither of these resolve the problem, send the
+ error message and a description of your environment to
+ the TrustedBSD discussion lists located at the
+ <link xlink:href="http://www.TrustedBSD.org">TrustedBSD</link>
+ website or to the &a.questions;
+ mailing list.</para>
+ </step>
+ </procedure>
+ </sect2>
+
+ <sect2>
+ <title>Error: &man..secure.path.3; cannot stat <filename>.login_conf</filename></title>
+
+ <para>When I attempt to switch from the <systemitem class="username">root</systemitem>
+ to another user in the system, the error message
+ <errorname>_secure_path: unable to state .login_conf</errorname>.</para>
+
+ <para>This message is usually shown when the user has a higher
+ label setting then that of the user whom they are attempting to
+ become. For instance a user on the system,
+ <systemitem class="username">joe</systemitem>, has a default label of
+ <option>biba/low</option>. The <systemitem class="username">root</systemitem> user,
+ who has a label of <option>biba/high</option>, cannot view
+ <systemitem class="username">joe</systemitem>'s home directory. This will happen
+ regardless if <systemitem class="username">root</systemitem> has used the
+ <command>su</command> command to become <systemitem class="username">joe</systemitem>,
+ or not. In this scenario, the Biba integrity model will not
+ permit <systemitem class="username">root</systemitem> to view objects set at a lower
+ integrity level.</para>
+ </sect2>
+
+ <sect2>
+ <title>The <systemitem class="username">root</systemitem> username is broken!</title>
+
+ <para>In normal or even single user mode, the
+ <systemitem class="username">root</systemitem> is not recognized. The
+ <command>whoami</command> command returns 0 (zero) and
+ <command>su</command> returns <errorname>who are you?</errorname>.
+ What could be going on?</para>
+
+ <para>This can happen if a labeling policy has been disabled,
+ either by a &man.sysctl.8; or the policy module was unloaded.
+ If the policy is being disabled or has been temporarily
+ disabled, then the login capabilities database needs to be
+ reconfigured with the <option>label</option> option being
+ removed. Double check the <filename>login.conf</filename>
+ file to ensure that all <option>label</option> options have
+ been removed and rebuild the database with the
+ <command>cap_mkdb</command> command.</para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/mail/Makefile b/zh_TW.UTF-8/books/handbook/mail/Makefile
new file mode 100644
index 0000000000..6138758090
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/mail/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= mail/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/mail/chapter.xml b/zh_TW.UTF-8/books/handbook/mail/chapter.xml
new file mode 100644
index 0000000000..e3d907ff0f
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/mail/chapter.xml
@@ -0,0 +1,2227 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.136
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="mail">
+ <info><title>電子郵件</title>
+ <authorgroup>
+ <author><personname><firstname>Bill</firstname><surname>Lloyd</surname></personname><contrib>Original work by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Jim</firstname><surname>Mock</surname></personname><contrib>Rewritten by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="mail-synopsis">
+ <title>概述</title>
+ <indexterm><primary>email</primary></indexterm>
+
+ <para><quote>電子郵件</quote>或者俗稱的 email,
+ 乃是現今使用最廣泛的溝通方式之一。 本章主要介紹如何在 &os; 上安裝、
+ 設定 email 服務,以及如何在 &os; 收發信件; 然而這並不是完整的參考手冊,
+ 實際上許多需考量的重要事項並未提及,若欲瞭解細節請參閱 <xref linkend="bibliography"/> 內的參考書籍。</para>
+
+ <para>讀完這章,您將了解︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>哪些軟體元件與收發電子郵件有關。</para>
+ </listitem>
+
+ <listitem>
+ <para>FreeBSD 內的 <application>sendmail</application>
+ 基本設定檔在哪。</para>
+ </listitem>
+
+ <listitem>
+ <para>遠端信箱與本機信箱的區別。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何阻擋 spammer(垃圾郵件製造者)非法運用您的郵件伺服器作為
+ relay(轉發中繼點)。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何安裝、設定其他 Mail Transfer Agent(MTA) 來取代
+ <application>sendmail</application>。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何處理常見的郵件伺服器問題。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何使用 UUCP 來進行 SMTP。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何設定系統,使其只能發送郵件。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何在撥接上網環境中,收發郵件。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何設定 SMTP 驗證,以加強安全性。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何安裝、使用 Mail User Agent(MUA) 程式,比如
+ <application>mutt</application> 來收發郵件。</para>
+ </listitem>
+
+ <listitem>
+
+ <para>如何從遠端 <acronym>POP</acronym> 或 <acronym>IMAP</acronym>
+ 主機去下載郵件。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何在收信方面,自動套用郵件過濾。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>在開始閱讀這章之前,您需要︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>先設好你的網路
+ (<xref linkend="advanced-networking"/>)。</para>
+ </listitem>
+
+ <listitem>
+ <para>能正確為郵件伺服器設定 DNS
+ (<xref linkend="network-servers"/>)。</para>
+ </listitem>
+
+ <listitem>
+ <para>知道如何透過 port/package 安裝軟體
+ (<xref linkend="ports"/>)。</para></listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="mail-using">
+ <title>使用電子郵件</title>
+ <indexterm><primary>POP</primary></indexterm>
+ <indexterm><primary>IMAP</primary></indexterm>
+ <indexterm><primary>DNS</primary></indexterm>
+
+ <para>在 email 交換的過程中有 5 個主要部分,分別是:<link linkend="mail-mua">MUA</link>、<link linkend="mail-mta">MTA</link>、
+ <link linkend="mail-dns">DNS</link>、<link linkend="mail-receive">
+ 遠端或本機的信箱</link>,當然還有 <link linkend="mail-host">郵件主機本身
+ </link>。</para>
+
+ <sect2 xml:id="mail-mua">
+ <title>MUA 程式</title>
+
+ <para>包括一些文字介面的程式,像是
+ <application>mutt</application>、
+ <application>pine</application>、<application>elm</application>、
+ and <command>mail</command>,以及 <acronym>GUI</acronym> 介面的程式,
+ 像是 <application>balsa</application>、
+ <application>xfmail</application> 等等。 此外,還有更
+ <quote>複雜的</quote> 像是 WWW 瀏覽器。
+ 這些程式會郵件處理交給 <link linkend="mail-host"><quote>郵件主機</quote></link>,或者透過呼叫
+ <link linkend="mail-mta">MTA</link>(若有的話)或者是透過
+ <acronym>TCP</acronym> 來傳遞郵件。</para>
+ </sect2>
+
+ <sect2 xml:id="mail-mta">
+ <title>Mailhost Server Daemon</title>
+ <indexterm>
+ <primary>mail server daemons</primary>
+ <secondary><application>sendmail</application></secondary>
+ </indexterm>
+ <indexterm>
+ <primary>mail server daemons</primary>
+ <secondary><application>postfix</application></secondary>
+ </indexterm>
+ <indexterm>
+ <primary>mail server daemons</primary>
+ <secondary><application>qmail</application></secondary>
+ </indexterm>
+ <indexterm>
+ <primary>mail server daemons</primary>
+ <secondary><application>exim</application></secondary>
+ </indexterm>
+
+ <para>&os; ships with <application>sendmail</application> by
+ default, but also support numerous other mail server daemons,
+ just some of which include:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><application>exim</application>;</para>
+ </listitem>
+
+ <listitem>
+ <para><application>postfix</application>;</para>
+ </listitem>
+
+ <listitem>
+ <para><application>qmail</application>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The server daemon usually has two functions&mdash;it is responsible
+ for receiving incoming mail as well as delivering outgoing mail. It is
+ <emphasis>not</emphasis> responsible for the collection of mail using protocols
+ such as <acronym>POP</acronym> or <acronym>IMAP</acronym> to
+ read your email, nor does it allow connecting to local
+ <filename>mbox</filename> or Maildir mailboxes. You may require
+ an additional <link linkend="mail-receive">daemon</link> for
+ that.</para>
+
+ <warning>
+ <para>Older versions of <application>sendmail</application>
+ 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
+ <acronym>MTA</acronym> from the <link linkend="ports">&os;
+ Ports Collection</link>.</para>
+ </warning>
+ </sect2>
+
+ <sect2 xml:id="mail-dns">
+ <title>Email and DNS</title>
+
+ <para>The Domain Name System (DNS) and its daemon
+ <command>named</command> 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.</para>
+
+ <indexterm>
+ <primary>MX record</primary>
+ </indexterm>
+
+ <para><acronym>DNS</acronym> 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.</para>
+
+ <para>You may view the MX records for any domain by using the
+ &man.host.1; command, as seen in the example below:</para>
+
+ <screen>&prompt.user; <userinput>host -t mx FreeBSD.org</userinput>
+FreeBSD.org mail is handled (pri=10) by mx1.FreeBSD.org</screen>
+ </sect2>
+
+ <sect2 xml:id="mail-receive">
+ <title>Receiving Mail</title>
+ <indexterm>
+ <primary>email</primary>
+ <secondary>receiving</secondary>
+ </indexterm>
+
+ <para>Receiving mail for your domain is done by the mail host. It
+ will collect all mail sent to your domain and store it
+ either in <filename>mbox</filename> (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
+ <application>mutt</application>, or remotely accessed and
+ collected using protocols such as
+ <acronym>POP</acronym> or <acronym>IMAP</acronym>.
+ This means that should you only
+ wish to read mail locally, you are not required to install a
+ <acronym>POP</acronym> or <acronym>IMAP</acronym> server.</para>
+
+ <sect3 xml:id="pop-and-imap">
+ <title>Accessing remote mailboxes using <acronym>POP</acronym> and <acronym>IMAP</acronym></title>
+
+ <indexterm><primary>POP</primary></indexterm>
+ <indexterm><primary>IMAP</primary></indexterm>
+ <para>In order to access mailboxes remotely, you are required to
+ have access to a <acronym>POP</acronym> or <acronym>IMAP</acronym>
+ server. These protocols allow users to connect to their mailboxes from
+ remote locations with ease. Though both
+ <acronym>POP</acronym> and <acronym>IMAP</acronym> allow users
+ to remotely access mailboxes, <acronym>IMAP</acronym> offers
+ many advantages, some of which are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><acronym>IMAP</acronym> can store messages on a remote
+ server as well as fetch them.</para>
+ </listitem>
+
+ <listitem>
+ <para><acronym>IMAP</acronym> supports concurrent updates.</para>
+ </listitem>
+
+ <listitem>
+ <para><acronym>IMAP</acronym> 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.</para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>In order to install a <acronym>POP</acronym> or
+ <acronym>IMAP</acronym> server, the following steps should be
+ performed:</para>
+
+ <procedure>
+ <step>
+ <para>Choose an <acronym>IMAP</acronym> or
+ <acronym>POP</acronym> server that best suits your needs.
+ The following <acronym>POP</acronym> and
+ <acronym>IMAP</acronym> servers are well known and serve
+ as some good examples:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><application>qpopper</application>;</para>
+ </listitem>
+
+ <listitem>
+ <para><application>teapop</application>;</para>
+ </listitem>
+
+ <listitem>
+ <para><application>imap-uw</application>;</para>
+ </listitem>
+
+ <listitem>
+ <para><application>courier-imap</application>;</para>
+ </listitem>
+ </itemizedlist>
+
+ </step>
+
+ <step>
+ <para>Install the <acronym>POP</acronym> or
+ <acronym>IMAP</acronym> daemon of your choosing from the
+ ports
+ collection.</para>
+ </step>
+
+ <step>
+ <para>Where required, modify <filename>/etc/inetd.conf</filename>
+ to load the <acronym>POP</acronym> or
+ <acronym>IMAP</acronym> server.</para>
+ </step>
+ </procedure>
+
+ <warning>
+ <para>It should be noted that both <acronym>POP</acronym> and
+ <acronym>IMAP</acronym> 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 <xref linkend="security-ssh-tunneling"/>.</para>
+ </warning>
+ </sect3>
+
+ <sect3 xml:id="local">
+ <title>Accessing local mailboxes</title>
+
+ <para>Mailboxes may be accessed locally by directly utilizing
+ <acronym>MUA</acronym>s on the server on which the mailbox
+ resides. This can be done using applications such as
+ <application>mutt</application> or &man.mail.1;.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="mail-host">
+ <title>The Mail Host</title>
+ <indexterm><primary>mail host</primary></indexterm>
+
+ <para>The mail host is the name given to a server that is
+ responsible for delivering and receiving mail for your host, and
+ possibly your network.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="sendmail">
+ <info><title><application>sendmail</application> Configuration</title>
+ <authorgroup>
+ <author><personname><firstname>Christopher</firstname><surname>Shumway</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm>
+ <primary><application>sendmail</application></primary>
+ </indexterm>
+
+ <para>&man.sendmail.8; is the default Mail Transfer Agent (MTA) in
+ FreeBSD. <application>sendmail</application>'s job is to accept
+ mail from Mail User Agents (<acronym>MUA</acronym>) and deliver it
+ to the appropriate mailer as defined by its configuration file.
+ <application>sendmail</application> can also accept network
+ connections and deliver mail to local mailboxes or deliver it to
+ another program.</para>
+
+ <para><application>sendmail</application> uses the following
+ configuration files:</para>
+
+ <indexterm>
+ <primary><filename>/etc/mail/access</filename></primary>
+ </indexterm>
+ <indexterm>
+ <primary><filename>/etc/mail/aliases</filename></primary>
+ </indexterm>
+ <indexterm>
+ <primary><filename>/etc/mail/local-host-names</filename></primary>
+ </indexterm>
+ <indexterm>
+ <primary><filename>/etc/mail/mailer.conf</filename></primary>
+ </indexterm>
+ <indexterm>
+ <primary><filename>/etc/mail/mailertable</filename></primary>
+ </indexterm>
+ <indexterm>
+ <primary><filename>/etc/mail/sendmail.cf</filename></primary>
+ </indexterm>
+ <indexterm>
+ <primary><filename>/etc/mail/virtusertable</filename></primary>
+ </indexterm>
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Filename</entry>
+ <entry>Function</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <filename>/etc/mail/access</filename>
+ </entry>
+ <entry><application>sendmail</application> access database
+ file</entry>
+ </row>
+ <row>
+ <entry>
+ <filename>/etc/mail/aliases</filename>
+ </entry>
+ <entry>Mailbox aliases</entry>
+ </row>
+ <row>
+ <entry>
+ <filename>/etc/mail/local-host-names</filename>
+ </entry>
+ <entry>Lists of hosts <application>sendmail</application>
+ accepts mail for</entry>
+ </row>
+ <row>
+ <entry>
+ <filename>/etc/mail/mailer.conf</filename>
+ </entry>
+ <entry>Mailer program configuration</entry>
+ </row>
+ <row>
+ <entry>
+ <filename>/etc/mail/mailertable</filename>
+ </entry>
+ <entry>Mailer delivery table</entry>
+ </row>
+ <row>
+ <entry>
+ <filename>/etc/mail/sendmail.cf</filename>
+ </entry>
+ <entry><application>sendmail</application> master
+ configuration file</entry>
+ </row>
+ <row>
+ <entry>
+ <filename>/etc/mail/virtusertable</filename>
+ </entry>
+ <entry>Virtual users and domain tables</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <sect2>
+ <title><filename>/etc/mail/access</filename></title>
+
+ <para>The 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 <option>OK</option>,
+ <option>REJECT</option>, <option>RELAY</option> or simply passed
+ to <application>sendmail</application>'s error handling routine with a given mailer error.
+ Hosts that are listed as <option>OK</option>, 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 <option>REJECT</option> are rejected for all mail
+ connections. Hosts that have the <option>RELAY</option> option
+ for their hostname are allowed to send mail for any destination
+ through this mail server.</para>
+
+ <example>
+ <title>Configuring the <application>sendmail</application>
+ Access Database</title>
+
+ <programlisting>cyberspammer.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 RELAY</programlisting>
+ </example>
+
+ <para>In 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 <application>sendmail</application>'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,
+ <systemitem>another.source.of.spam</systemitem>. The next entry accepts
+ mail connections from a host
+ <systemitem class="fqdomainname">okay.cyberspammer.com</systemitem>, which is more exact than
+ the <systemitem class="fqdomainname">cyberspammer.com</systemitem> 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 <systemitem>128.32</systemitem>. These hosts would be able
+ to send mail through this mail server that are destined for other
+ mail servers.</para>
+
+ <para>When this file is updated, you need to run
+ <command>make</command> in <filename>/etc/mail/</filename> to
+ update the database.</para>
+
+ </sect2>
+ <sect2>
+ <title><filename>/etc/mail/aliases</filename></title>
+
+ <para>The 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
+ <filename>/etc/mail/aliases</filename>:</para>
+
+ <example>
+ <title>Mail Aliases</title>
+ <programlisting>root: localuser
+ftp-bugs: joe,eric,paul
+bit.bucket: /dev/null
+procmail: "|/usr/local/bin/procmail"</programlisting>
+ </example>
+
+ <para>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 <systemitem class="username">root</systemitem>
+ to the mailbox <systemitem class="username">localuser</systemitem>, which is then
+ looked up again in the aliases database. If no match is found,
+ then the message is delivered to the local user
+ <systemitem class="username">localuser</systemitem>. The next example shows a mail
+ list. Mail to the mailbox <systemitem class="username">ftp-bugs</systemitem> is
+ expanded to the three local mailboxes <systemitem class="username">joe</systemitem>,
+ <systemitem class="username">eric</systemitem>, and <systemitem class="username">paul</systemitem>. Note
+ that a remote mailbox could be specified as <email>user@example.com</email>. The
+ next example shows writing mail to a file, in this case
+ <filename>/dev/null</filename>. The last example shows sending
+ mail to a program, in this case the mail message is written to the
+ standard input of <filename>/usr/local/bin/procmail</filename>
+ through a &unix; pipe.</para>
+
+ <para>When this file is updated, you need to run
+ <command>make</command> in <filename>/etc/mail/</filename> to
+ update the database.</para>
+ </sect2>
+ <sect2>
+ <title><filename>/etc/mail/local-host-names</filename></title>
+
+ <para>This is a list of hostnames &man.sendmail.8; is to accept as
+ the local host name. Place any domains or hosts that
+ <application>sendmail</application> is to be receiving mail for.
+ For example, if this mail server was to accept mail for the
+ domain <systemitem class="fqdomainname">example.com</systemitem> and the host
+ <systemitem class="fqdomainname">mail.example.com</systemitem>, its
+ <filename>local-host-names</filename> might look something like
+ this:</para>
+
+ <programlisting>example.com
+mail.example.com</programlisting>
+
+ <para>When this file is updated, &man.sendmail.8; needs to be
+ restarted to read the changes.</para>
+
+ </sect2>
+
+ <sect2>
+ <title><filename>/etc/mail/sendmail.cf</filename></title>
+
+ <para><application>sendmail</application>'s master configuration
+ file, <filename>sendmail.cf</filename> controls the overall
+ behavior of <application>sendmail</application>, 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.</para>
+
+ <para>The master <application>sendmail</application> configuration
+ file can be built from &man.m4.1; macros that define the features
+ and behavior of <application>sendmail</application>. Please see
+ <filename>/usr/src/contrib/sendmail/cf/README</filename> for
+ some of the details.</para>
+
+ <para>When changes to this file are made,
+ <application>sendmail</application> needs to be restarted for
+ the changes to take effect.</para>
+
+ </sect2>
+ <sect2>
+ <title><filename>/etc/mail/virtusertable</filename></title>
+
+ <para>The <filename>virtusertable</filename> maps mail addresses for
+ virtual domains and
+ mailboxes to real mailboxes. These mailboxes can be local,
+ remote, aliases defined in
+ <filename>/etc/mail/aliases</filename> or files.</para>
+
+ <example>
+ <title>Example Virtual Domain Mail Map</title>
+
+ <programlisting>root@example.com root
+postmaster@example.com postmaster@noc.example.net
+@example.com joe</programlisting>
+ </example>
+
+ <para>In the above example, we have a mapping for a domain
+ <systemitem class="fqdomainname">example.com</systemitem>. This file is processed in a
+ first match order down the file. The first item maps
+ <email>root@example.com</email> to the local mailbox <systemitem class="username">root</systemitem>. The next entry maps
+ <email>postmaster@example.com</email> to the mailbox <systemitem class="username">postmaster</systemitem> on the host
+ <systemitem class="fqdomainname">noc.example.net</systemitem>. Finally, if nothing from <systemitem class="fqdomainname">example.com</systemitem> has
+ matched so far, it will match the last mapping, which matches
+ every other mail message addressed to someone at
+ <systemitem class="fqdomainname">example.com</systemitem>.
+ This will be mapped to the local mailbox <systemitem class="username">joe</systemitem>.</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="mail-changingmta">
+ <info><title>Changing Your Mail Transfer Agent</title>
+ <authorgroup>
+ <author><personname><firstname>Andrew</firstname><surname>Boothman</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Gregory</firstname><surname>Neil Shapiro</surname></personname><contrib>Information taken from e-mails written by </contrib></author>
+ </authorgroup>
+ </info>
+
+ <indexterm>
+ <primary>email</primary>
+ <secondary>change mta</secondary>
+ </indexterm>
+
+ <para>As already mentioned, FreeBSD comes with
+ <application>sendmail</application> already installed as your
+ MTA (Mail Transfer Agent). Therefore by default it is
+ in charge of your outgoing and incoming mail.</para>
+
+ <para>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.</para>
+
+ <sect2>
+ <title>Install a New MTA</title>
+
+ <para>You have a wide choice of MTAs available. A good
+ starting point is the
+ <link linkend="ports">FreeBSD Ports Collection</link> 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.</para>
+
+ <para>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
+ <application>sendmail</application>. When doing this, you
+ should be sure that installing the new software will not attempt
+ to overwrite system binaries such as
+ <filename>/usr/bin/sendmail</filename>. Otherwise, your new
+ mail software has essentially been put into service before
+ you have configured it.</para>
+
+ <para>Please refer to your chosen MTA's documentation for
+ information on how to configure the software you have
+ chosen.</para>
+ </sect2>
+
+ <sect2 xml:id="mail-disable-sendmail">
+ <title>Disable <application>sendmail</application></title>
+
+ <para>The procedure used to start
+ <application>sendmail</application> changed significantly
+ between 4.5-RELEASE, 4.6-RELEASE, and later releases.
+ Therefore, the procedure used to disable it is subtly
+ different.</para>
+
+ <warning>
+ <para>If you disable <application>sendmail</application>'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
+ <application>sendmail</application>-compatible system. If
+ applications continue to use
+ <application>sendmail</application>'s binaries to try to send
+ e-mail after you have disabled them, mail could go into an
+ inactive <application>sendmail</application> queue, and
+ never be delivered.</para>
+ </warning>
+
+ <sect3>
+ <title>FreeBSD 4.5-STABLE before 2002/4/4 and Earlier
+ (Including 4.5-RELEASE and Earlier)</title>
+
+ <para>Enter:</para>
+
+ <programlisting>sendmail_enable="NO"</programlisting>
+
+ <para>into <filename>/etc/rc.conf</filename>. This will disable
+ <application>sendmail</application>'s incoming mail service,
+ but if <filename>/etc/mail/mailer.conf</filename> (see below)
+ is not changed, <application>sendmail</application> will
+ still be used to send e-mail.</para>
+ </sect3>
+
+ <sect3>
+ <title>FreeBSD 4.5-STABLE after 2002/4/4
+ (Including 4.6-RELEASE and Later)</title>
+
+ <para>In order to completely disable
+ <application>sendmail</application>, including the outgoing
+ mail service, you must use</para>
+
+ <programlisting>sendmail_enable="NONE"</programlisting>
+
+ <para>in <filename>/etc/rc.conf.</filename></para>
+
+ <para>If you only want to disable
+ <application>sendmail</application>'s incoming mail service,
+ you should set</para>
+
+ <programlisting>sendmail_enable="NO"</programlisting>
+
+ <para>in <filename>/etc/rc.conf</filename>. However, if
+ incoming mail is disabled, local delivery will still
+ function. More information on
+ <application>sendmail</application>'s startup options is
+ available from the &man.rc.sendmail.8; manual page.</para>
+ </sect3>
+
+ <sect3>
+ <title>FreeBSD 5.0-STABLE and Later</title>
+
+ <para>In order to completely disable
+ <application>sendmail</application>, including the outgoing
+ mail service, you must use</para>
+
+ <programlisting>sendmail_enable="NO"
+sendmail_submit_enable="NO"
+sendmail_outbound_enable="NO"
+sendmail_msp_queue_enable="NO"</programlisting>
+
+ <para>in <filename>/etc/rc.conf.</filename></para>
+
+ <para>If you only want to disable
+ <application>sendmail</application>'s incoming mail service,
+ you should set</para>
+
+ <programlisting>sendmail_enable="NO"</programlisting>
+
+ <para>in <filename>/etc/rc.conf</filename>. More information on
+ <application>sendmail</application>'s startup options is
+ available from the &man.rc.sendmail.8; manual page.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Running Your New MTA on Boot</title>
+
+ <para>You may have a choice of two methods for running your
+ new MTA on boot, again depending on what version of FreeBSD
+ you are running.</para>
+
+ <sect3>
+ <title>FreeBSD 4.5-STABLE before 2002/4/11
+ (Including 4.5-RELEASE and Earlier)</title>
+
+ <para>Add a script to
+ <filename>/usr/local/etc/rc.d/</filename> that
+ ends in <filename>.sh</filename> and is executable by
+ <systemitem class="username">root</systemitem>. The script should accept <literal>start</literal> and
+ <literal>stop</literal> parameters. At startup time the
+ system scripts will execute the command</para>
+
+ <programlisting>/usr/local/etc/rc.d/supermailer.sh start</programlisting>
+
+ <para>which you can also use to manually start the server. At
+ shutdown time, the system scripts will use the
+ <literal>stop</literal> option, running the command</para>
+
+ <programlisting>/usr/local/etc/rc.d/supermailer.sh stop</programlisting>
+
+ <para>which you can also use to manually stop the server
+ while the system is running.</para>
+
+ </sect3>
+
+ <sect3>
+ <title>FreeBSD 4.5-STABLE after 2002/4/11
+ (Including 4.6-RELEASE and Later)</title>
+
+ <para>With later versions of FreeBSD, you can use the
+ above method or you can set</para>
+
+ <programlisting>mta_start_script="filename"</programlisting>
+
+ <para>in <filename>/etc/rc.conf</filename>, where
+ <replaceable>filename</replaceable> is the name of some
+ script that you want executed at boot to start your
+ MTA.</para>
+ </sect3>
+
+ </sect2>
+
+ <sect2>
+ <title>Replacing <application>sendmail</application> as
+ the System's Default Mailer</title>
+
+ <para>The program <application>sendmail</application> 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 <application>sendmail</application>
+ command-line interface; this facilitates using them as
+ <quote>drop-in</quote> replacements for <application>sendmail</application>.</para>
+
+ <para>Therefore, if you are using an alternative mailer,
+ you will need to make sure that software trying to execute
+ standard <application>sendmail</application> binaries such as
+ <filename>/usr/bin/sendmail</filename> actually executes
+ your chosen mailer instead. Fortunately, FreeBSD provides
+ a system called &man.mailwrapper.8; that does this job for
+ you.</para>
+
+ <para>When <application>sendmail</application> is operating as installed, you will
+ find something like the following
+ in <filename>/etc/mail/mailer.conf</filename>:</para>
+
+<programlisting>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/sendmail</programlisting>
+
+ <para>This means that when any of these common commands
+ (such as <filename>sendmail</filename> itself) are run,
+ the system actually invokes a copy of mailwrapper named <filename>sendmail</filename>, which
+ checks <filename>mailer.conf</filename> and
+ executes <filename>/usr/libexec/sendmail/sendmail</filename>
+ instead. This system makes it easy to change what binaries
+ are actually executed when these default <filename>sendmail</filename> functions
+ are invoked.</para>
+
+ <para>Therefore if you wanted
+ <filename>/usr/local/supermailer/bin/sendmail-compat</filename>
+ to be run instead of <application>sendmail</application>, you could change
+ <filename>/etc/mail/mailer.conf</filename> to read:</para>
+
+<programlisting>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-compat</programlisting>
+
+ </sect2>
+
+ <sect2>
+ <title>Finishing</title>
+
+ <para>Once you have everything configured the way you want it, you should
+ either kill the <application>sendmail</application> 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.</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="mail-trouble">
+ <title>Troubleshooting</title>
+ <indexterm>
+ <primary>email</primary>
+ <secondary>troubleshooting</secondary>
+ </indexterm>
+
+ <qandaset>
+ <qandaentry>
+ <question>
+ <para>Why do I have to use the FQDN for hosts on my site?</para>
+ </question>
+
+ <answer>
+ <para>You will probably find that the host is actually in a
+ different domain; for example, if you are in
+ <systemitem class="fqdomainname">foo.bar.edu</systemitem> and you wish to reach
+ a host called <systemitem>mumble</systemitem> in the <systemitem class="fqdomainname">bar.edu</systemitem> domain, you will have to
+ refer to it by the fully-qualified domain name, <systemitem class="fqdomainname">mumble.bar.edu</systemitem>, instead of just
+ <systemitem>mumble</systemitem>.</para>
+
+ <para>Traditionally, this was allowed by BSD BIND<indexterm>
+ <primary>BIND</primary></indexterm> resolvers.
+ However the current version of <application>BIND</application>
+ 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 <systemitem>mumble</systemitem> must
+ either be found as <systemitem class="fqdomainname">mumble.foo.bar.edu</systemitem>, or it will be searched
+ for in the root domain.</para>
+
+ <para>This is different from the previous behavior, where the
+ search continued across <systemitem class="fqdomainname">mumble.bar.edu</systemitem>, and <systemitem class="fqdomainname">mumble.edu</systemitem>. Have a look at RFC 1535
+ for why this was considered bad practice, or even a security
+ hole.</para>
+
+ <para>As a good workaround, you can place the line:
+
+ <programlisting>search foo.bar.edu bar.edu</programlisting>
+
+ instead of the previous:
+
+ <programlisting>domain foo.bar.edu</programlisting>
+
+ into your <filename>/etc/resolv.conf</filename>. However, make
+ sure that the search order does not go beyond the
+ <quote>boundary between local and public administration</quote>,
+ as RFC 1535 calls it.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+
+ <para><application>sendmail</application> says <errorname>mail
+ loops back to myself</errorname></para>
+ </question>
+
+ <answer>
+ <para>This is answered in the
+ <application>sendmail</application> FAQ as follows:</para>
+
+ <programlisting>I'm getting these error messages:
+
+553 MX list for domain.net points back to relay.domain.net
+554 &lt;user@domain.net&gt;... 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<indexterm><primary>MX record</primary></indexterm>
+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 <quote>Cw domain.net</quote>
+to /etc/mail/sendmail.cf.</programlisting>
+
+ <para>The <application>sendmail</application> FAQ can be found at
+ <uri xlink:href="http://www.sendmail.org/faq/">http://www.sendmail.org/faq/</uri> and is
+ recommended reading if you want to do any
+ <quote>tweaking</quote> of your mail setup.</para>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>How can I run a mail server on a dial-up PPP<indexterm>
+ <primary>PPP</primary></indexterm> host?</para>
+ </question>
+
+ <answer>
+ <para>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.</para>
+
+ <para>There are at least two ways to do this. One way is to use
+ UUCP<indexterm><primary>UUCP</primary></indexterm>.</para>
+
+ <para>Another way is to get a full-time Internet server to provide secondary
+ MX<indexterm><primary>MX record</primary></indexterm>
+ services for your domain. For example, if your company's domain is
+ <systemitem class="fqdomainname">example.com</systemitem> and your Internet service provider has
+ set <systemitem class="fqdomainname">example.net</systemitem> up to provide secondary MX services
+ to your domain:</para>
+
+ <programlisting>example.com. MX 10 example.com.
+ MX 20 example.net.</programlisting>
+
+ <para>Only one host should be specified as the final recipient
+ (add <literal>Cw example.com</literal> in
+ <filename>/etc/mail/sendmail.cf</filename> on <systemitem class="fqdomainname">example.com</systemitem>).</para>
+
+ <para>When the sending <command>sendmail</command> is trying to
+ deliver the mail it will try to connect to you (<systemitem class="fqdomainname">example.com</systemitem>) over the modem
+ link. It will most likely time out because you are not online.
+ The program <application>sendmail</application> will automatically deliver it to the
+ secondary MX site, i.e. your Internet provider (<systemitem class="fqdomainname">example.net</systemitem>). The secondary MX
+ site will then periodically try to connect to
+ your host and deliver the mail to the primary MX host (<systemitem class="fqdomainname">example.com</systemitem>).</para>
+
+ <para>You might want to use something like this as a login
+ script:</para>
+
+ <programlisting>#!/bin/sh
+# Put me in /usr/local/bin/pppmyisp
+( sleep 60 ; /usr/sbin/sendmail -q ) &amp;
+/usr/sbin/ppp -direct pppmyisp</programlisting>
+
+ <para>If you are going to create a separate login script for a
+ user you could use <command>sendmail -qRexample.com</command>
+ instead in the script above. This will force all mail in your
+ queue for <systemitem class="fqdomainname">example.com</systemitem> to be processed immediately.</para>
+
+ <para>A further refinement of the situation is as follows:</para>
+
+ <para>Message stolen from the &a.isp;.</para>
+
+ <programlisting>&gt; we provide the secondary MX for a customer. The customer connects to
+&gt; our services several times a day automatically to get the mails to
+&gt; his primary MX (We do not call his site when a mail for his domains
+&gt; arrived). Our sendmail sends the mailqueue every 30 minutes. At the
+&gt; moment he has to stay 30 minutes online to be sure that all mail is
+&gt; gone to the primary MX.
+&gt;
+&gt; Is there a command that would initiate sendmail to send all the mails
+&gt; now? The user has not root-privileges on our machine of course.
+
+In the <quote>privacy flags</quote> 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
+<quote>hosts</quote>, so you need to get your customer to name their mail
+machine <quote>customer.com</quote> as well as
+<quote>hostname.customer.com</quote> in the DNS. Just put an A record in
+the DNS for <quote>customer.com</quote>.</programlisting>
+ </answer>
+ </qandaentry>
+
+ <qandaentry>
+ <question>
+ <para>Why do I keep getting <errorname>Relaying
+ Denied</errorname> errors when sending mail from other
+ hosts?</para>
+ </question>
+
+ <answer>
+ <para>In default FreeBSD installations,
+ <application>sendmail</application> is configured to only
+ send mail from the host it is running on. For example, if
+ a <acronym>POP</acronym> 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
+ <application>MAILER-DAEMON</application> with a
+ <errorname>5.7 Relaying Denied</errorname> error
+ message.</para>
+
+ <para>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
+ <filename>/etc/mail/relay-domains</filename>. A quick way
+ to do this would be:</para>
+
+ <screen>&prompt.root; <userinput>echo "your.isp.example.com" &gt; /etc/mail/relay-domains</userinput></screen>
+
+ <para>After creating or editing this file you must restart
+ <application>sendmail</application>. 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:</para>
+
+ <programlisting>your.isp.example.com
+other.isp.example.net
+users-isp.example.org
+www.example.org</programlisting>
+
+ <para>Now 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.</para>
+
+ </answer>
+ </qandaentry>
+ </qandaset>
+ </sect1>
+
+ <sect1 xml:id="mail-advanced">
+ <title>Advanced Topics</title>
+
+ <para>The following section covers more involved topics such as mail
+ configuration and setting up mail for your entire domain.</para>
+
+ <sect2 xml:id="mail-config">
+ <title>Basic Configuration</title>
+ <indexterm>
+ <primary>email</primary>
+ <secondary>configuration</secondary>
+ </indexterm>
+
+ <para>Out of the box, you should be able to send email to external
+ hosts as long as you have set up
+ <filename>/etc/resolv.conf</filename> or are running your own
+ name server. If you would like to have mail for your host
+ delivered to the MTA (e.g., <application>sendmail</application>) on your own FreeBSD host, there are two methods:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Run your own name server and have your own domain. For
+ example, <systemitem class="fqdomainname">FreeBSD.org</systemitem></para>
+ </listitem>
+
+ <listitem>
+ <para>Get mail delivered directly to your host. This is done by
+ delivering mail directly to the current DNS name for your
+ machine. For example, <systemitem class="fqdomainname">example.FreeBSD.org</systemitem>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <indexterm><primary>SMTP</primary></indexterm>
+ <para>Regardless 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:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Make sure that the (lowest-numbered) MX record<indexterm><primary>MX record</primary></indexterm> in your DNS points to your
+ host's IP address.</para>
+ </listitem>
+
+ <listitem>
+ <para>Make sure there is no MX entry in your DNS for your
+ host.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Either of the above will allow you to receive mail directly at
+ your host.</para>
+
+ <para>Try this:</para>
+
+ <screen>&prompt.root; <userinput>hostname</userinput>
+example.FreeBSD.org
+&prompt.root; <userinput>host example.FreeBSD.org</userinput>
+example.FreeBSD.org has address 204.216.27.XX</screen>
+
+ <para>If that is what you see, mail directly to
+ <email role="nolink">yourlogin@example.FreeBSD.org</email> should work without
+ problems (assuming <application>sendmail</application> is
+ running correctly on <systemitem class="fqdomainname">example.FreeBSD.org</systemitem>).</para>
+
+ <para>If instead you see something like this:</para>
+
+ <screen>&prompt.root; <userinput>host example.FreeBSD.org</userinput>
+example.FreeBSD.org has address 204.216.27.XX
+example.FreeBSD.org mail is handled (pri=10) by hub.FreeBSD.org</screen>
+
+ <para>All mail sent to your host (<systemitem class="fqdomainname">example.FreeBSD.org</systemitem>) will end up being
+ collected on <systemitem>hub</systemitem> under the same username instead
+ of being sent directly to your host.</para>
+
+ <para>The above information is handled by your DNS server. The DNS
+ record that carries mail routing information is the
+ <emphasis>M</emphasis>ail e<emphasis>X</emphasis>change entry. If
+ no MX record exists, mail will be delivered directly to the host by
+ way of its IP address.</para>
+
+ <para>The MX entry for <systemitem class="fqdomainname">freefall.FreeBSD.org</systemitem> at one time looked like
+ this:</para>
+
+ <programlisting>freefall MX 30 mail.crl.net
+freefall MX 40 agora.rdrop.com
+freefall MX 10 freefall.FreeBSD.org
+freefall MX 20 who.cdrom.com</programlisting>
+
+ <para>As you can see, <systemitem>freefall</systemitem> 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 <quote>backup MXes</quote>) accept messages
+ temporarily, and pass it along when a lower-numbered host becomes
+ available, eventually to the lowest-numbered host.</para>
+
+ <para>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.</para>
+ </sect2>
+
+ <sect2 xml:id="mail-domain">
+ <title>Mail for Your Domain</title>
+
+ <para>In order to set up a <quote>mailhost</quote> (a.k.a. mail
+ server) you need to have any mail sent to various workstations
+ directed to it. Basically, you want to <quote>claim</quote> any
+ mail for any hostname in your domain (in this case <systemitem class="fqdomainname">*.FreeBSD.org</systemitem>) and divert it to your mail
+ server so your users can receive their mail on
+ the master mail server.</para>
+
+ <indexterm><primary>DNS</primary></indexterm>
+ <para>To make life easiest, a user account with the same
+ <emphasis>username</emphasis> should exist on both machines. Use
+ &man.adduser.8; to do this.</para>
+
+ <para>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:</para>
+
+ <programlisting>example.FreeBSD.org A 204.216.27.XX ; Workstation
+ MX 10 hub.FreeBSD.org ; Mailhost</programlisting>
+
+ <para>This will redirect mail for the workstation to the mailhost no
+ matter where the A record points. The mail is sent to the MX
+ host.</para>
+
+ <para>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.</para>
+
+ <para>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 <systemitem class="fqdomainname">customer1.org</systemitem>, and you want
+ all the mail for <systemitem class="fqdomainname">customer1.org</systemitem>
+ sent to your mailhost, <systemitem class="fqdomainname">mail.myhost.com</systemitem>. The entry in your DNS
+ should look like this:</para>
+
+ <programlisting>customer1.org MX 10 mail.myhost.com</programlisting>
+
+ <para>You do <emphasis>not</emphasis> need an A record for <systemitem class="fqdomainname">customer1.org</systemitem> if you only
+ want to handle email for that domain.</para>
+
+ <note>
+ <para>Be aware that pinging <systemitem class="fqdomainname">customer1.org</systemitem> will not work unless
+ an A record exists for it.</para>
+ </note>
+
+ <para>The last thing that you must do is tell
+ <application>sendmail</application> 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:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Add the hosts to your
+ <filename>/etc/mail/local-host-names</filename> file if you are using the
+ <literal>FEATURE(use_cw_file)</literal>. If you are using
+ a version of <application>sendmail</application> earlier than 8.10, the file is
+ <filename>/etc/sendmail.cw</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Add a <literal>Cwyour.host.com</literal> line to your
+ <filename>/etc/sendmail.cf</filename> or
+ <filename>/etc/mail/sendmail.cf</filename> if you are using
+ <application>sendmail</application> 8.10 or higher.</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="SMTP-UUCP">
+ <title>SMTP with UUCP</title>
+
+ <para>The <application>sendmail</application> 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
+ <application>sendmail</application> configuration file.</para>
+
+ <para>Tweaking <filename>/etc/mail/sendmail.cf</filename> manually
+ is an advanced topic. <application>sendmail</application> 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
+ <filename>/usr/share/sendmail/cf</filename>. The file
+ <filename>README</filename> in the <filename>cf</filename>
+ directory can serve as a basic introduction to &man.m4.1;
+ configuration.</para>
+
+ <para>The best way to support UUCP delivery is to use the
+ <literal>mailertable</literal> feature. This creates a database
+ that <application>sendmail</application> can use to make routing decisions.</para>
+
+ <para>First, you have to create your <filename>.mc</filename>
+ file. The directory
+ <filename>/usr/share/sendmail/cf/cf</filename> contains a
+ few examples. Assuming you have named your file
+ <filename>foo.mc</filename>, all you need to do in order to
+ convert it into a valid <filename>sendmail.cf</filename>
+ is:</para>
+
+ <screen>&prompt.root; <userinput>cd /etc/mail</userinput>
+&prompt.root; <userinput>make foo.cf</userinput>
+&prompt.root; <userinput>cp foo.cf /etc/mail/sendmail.cf</userinput></screen>
+
+ <para>A typical <filename>.mc</filename> file might look
+ like:</para>
+
+ <programlisting>VERSIONID(`<replaceable>Your version number</replaceable>') OSTYPE(bsd4.4)
+
+FEATURE(accept_unresolvable_domains)
+FEATURE(nocanonify)
+FEATURE(mailertable, `hash -o /etc/mail/mailertable')
+
+define(`UUCP_RELAY', <replaceable>your.uucp.relay</replaceable>)
+define(`UUCP_MAX_SIZE', 200000)
+define(`confDONT_PROBE_INTERFACES')
+
+MAILER(local)
+MAILER(smtp)
+MAILER(uucp)
+
+Cw <replaceable>your.alias.host.name</replaceable>
+Cw <replaceable>youruucpnodename.UUCP</replaceable></programlisting>
+
+ <para>The lines containing
+ <literal>accept_unresolvable_domains</literal>,
+ <literal>nocanonify</literal>, and
+ <literal>confDONT_PROBE_INTERFACES</literal> features will
+ prevent any usage of the DNS during mail delivery. The
+ <literal>UUCP_RELAY</literal> 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.</para>
+
+ <para>Once you have this, you need an
+ <filename>/etc/mail/mailertable</filename> file. If you have
+ only one link to the outside that is used for all your mails,
+ the following file will suffice:</para>
+
+ <programlisting>#
+# makemap hash /etc/mail/mailertable.db &lt; /etc/mail/mailertable
+. uucp-dom:<replaceable>your.uucp.relay</replaceable></programlisting>
+
+ <para>A more complex example might look like this:</para>
+
+ <programlisting>#
+# makemap hash /etc/mail/mailertable.db &lt; /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:</programlisting>
+
+
+ <para>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
+ <quote>shortcut</quote> 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
+ <literal>uucp-neighbor
+ !recipient</literal>
+ 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
+ <literal>uucp-dom:</literal> keyword must be valid UUCP
+ neighbors, as you can verify using the command
+ <literal>uuname</literal>.</para>
+
+ <para>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 <filename>mailertable</filename> file.
+ You always have to execute this command each time you change
+ your <filename>mailertable</filename> file.</para>
+
+ <para>Final hint: if you are uncertain whether some particular
+ mail routing would work, remember the <option>-bt</option>
+ option to <application>sendmail</application>. It starts <application>sendmail</application> in <emphasis>address test
+ mode</emphasis>; simply enter <literal>3,0</literal>, 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 <keycombo action="simul"><keycap>Ctrl</keycap><keycap>D</keycap></keycombo>.</para>
+
+ <screen>&prompt.user; <userinput>sendmail -bt</userinput>
+ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
+Enter &lt;ruleset&gt; &lt;address&gt;
+<prompt>&gt;</prompt> <userinput>3,0 foo@example.com</userinput>
+canonify input: foo @ example . com
+...
+parse returns: $# uucp-dom $@ <replaceable>your.uucp.relay</replaceable> $: foo &lt; @ example . com . &gt;
+<prompt>&gt;</prompt> <userinput>^D</userinput></screen>
+ </sect1>
+
+ <sect1 xml:id="outgoing-only">
+ <info><title>Setting Up to Send Only</title>
+ <authorgroup>
+ <author><personname><firstname>Bill</firstname><surname>Moran</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <para>There are many instances where you may only want to send
+ mail through a relay. Some examples are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>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.</para>
+ </listitem>
+
+ <listitem>
+ <para>The computer is a server that does not handle mail
+ locally, but needs to pass off all mail to a relay for
+ processing.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Just about any <acronym>MTA</acronym> is capable of filling
+ this particular niche. Unfortunately, it can be very difficult
+ to properly configure a full-featured <acronym>MTA</acronym>
+ just to handle offloading mail. Programs such as
+ <application>sendmail</application> and
+ <application>postfix</application> are largely overkill for
+ this use.</para>
+
+ <para>Additionally, if you are using a typical Internet access
+ service, your agreement may forbid you from running a
+ <quote>mail server</quote>.</para>
+
+ <para>The easiest way to fulfill those needs is to install the
+ <package>mail/ssmtp</package> port. Execute
+ the following commands as <systemitem class="username">root</systemitem>:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/mail/ssmtp</userinput>
+&prompt.root; <userinput>make install replace clean</userinput></screen>
+
+ <para>Once installed,
+ <package>mail/ssmtp</package> can be configured
+ with a four-line file located at
+ <filename>/usr/local/etc/ssmtp/ssmtp.conf</filename>:</para>
+
+ <programlisting>root=yourrealemail@example.com
+mailhub=mail.example.com
+rewriteDomain=example.com
+hostname=_HOSTNAME_</programlisting>
+
+ <para>Make sure you use your real email address for
+ <systemitem class="username">root</systemitem>. Enter your ISP's outgoing mail relay
+ in place of <systemitem class="fqdomainname">mail.example.com</systemitem> (some ISPs call
+ this the <quote>outgoing mail server</quote> or
+ <quote>SMTP server</quote>).</para>
+
+ <para>Make sure you disable <application>sendmail</application>,
+ including the outgoing mail service. See
+ <xref linkend="mail-disable-sendmail"/> for details.</para>
+
+ <para><package>mail/ssmtp</package> has some
+ other options available. See the example configuration file in
+ <filename>/usr/local/etc/ssmtp</filename> or the manual page of
+ <application>ssmtp</application> for some examples and more
+ information.</para>
+
+ <para>Setting up <application>ssmtp</application> 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.</para>
+ </sect1>
+
+ <sect1 xml:id="SMTP-dialup">
+ <title>Using Mail with a Dialup Connection</title>
+
+ <para>If 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 <application>sendmail</application> will do the rest.</para>
+
+ <para>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 <systemitem class="fqdomainname">example.net</systemitem>, and that your
+ user name is <systemitem class="username">user</systemitem>, you have called your
+ machine <systemitem class="fqdomainname">bsd.home</systemitem>, and your ISP has
+ told you that you may use <systemitem class="fqdomainname">relay.example.net</systemitem> as a mail relay.</para>
+
+ <para>In order to retrieve mail from your mailbox, you must
+ install a retrieval agent. The
+ <application>fetchmail</application> utility is a good choice as
+ it supports many different protocols. This program is available
+ as a package or from the Ports Collection (<package>mail/fetchmail</package>). Usually, your <acronym>ISP</acronym> will
+ provide <acronym>POP</acronym>. If you are using user <acronym>PPP</acronym>, you can
+ automatically fetch your mail when an Internet connection is
+ established with the following entry in
+ <filename>/etc/ppp/ppp.linkup</filename>:</para>
+
+ <programlisting>MYADDR:
+!bg su user -c fetchmail</programlisting>
+
+ <para>If you are using <application>sendmail</application> (as
+ shown below) to deliver mail to non-local accounts, you probably
+ want to have <application>sendmail</application> process your
+ mailqueue as soon as your Internet connection is established.
+ To do this, put this command after the
+ <command>fetchmail</command> command in
+ <filename>/etc/ppp/ppp.linkup</filename>:</para>
+
+ <programlisting> !bg su user -c "sendmail -q"</programlisting>
+
+ <para>Assume that you have an account for
+ <systemitem class="username">user</systemitem> on <systemitem class="fqdomainname">bsd.home</systemitem>. In the home directory of
+ <systemitem class="username">user</systemitem> on <systemitem class="fqdomainname">bsd.home</systemitem>, create a
+ <filename>.fetchmailrc</filename> file:</para>
+
+ <programlisting>poll example.net protocol pop3 fetchall pass MySecret</programlisting>
+
+ <para>This file should not be readable by anyone except
+ <systemitem class="username">user</systemitem> as it contains the password
+ <literal>MySecret</literal>.</para>
+
+ <para>In order to send mail with the correct
+ <literal>from:</literal> header, you must tell
+ <application>sendmail</application> to use
+ <email>user@example.net</email> rather than
+ <email role="nolink">user@bsd.home</email>. You may also wish to tell
+ <application>sendmail</application> to send all mail via <systemitem class="fqdomainname">relay.example.net</systemitem>, allowing quicker mail
+ transmission.</para>
+
+ <para>The following <filename>.mc</filename> file should
+ suffice:</para>
+
+ <programlisting>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')dnl</programlisting>
+
+ <para>Refer to the previous section for details of how to turn
+ this <filename>.mc</filename> file into a
+ <filename>sendmail.cf</filename> file. Also, do not forget to
+ restart <application>sendmail</application> after updating
+ <filename>sendmail.cf</filename>.</para>
+ </sect1>
+
+ <sect1 xml:id="SMTP-Auth">
+ <info><title>SMTP Authentication</title>
+ <authorgroup>
+ <author><personname><firstname>James</firstname><surname>Gorham</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <para>Having <acronym>SMTP</acronym> Authentication in place on
+ your mail server has a number of benefits.
+ <acronym>SMTP</acronym> Authentication can add another layer
+ of security to <application>sendmail</application>, 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.</para>
+
+ <procedure>
+ <step>
+ <para>Install <package>security/cyrus-sasl2</package>
+ from the ports. You can find this port in
+ <package>security/cyrus-sasl2</package>. The
+ <package>security/cyrus-sasl2</package> port
+ supports a number of compile-time options. For the SMTP
+ Authentication method we will be using here, make sure that
+ the <option>LOGIN</option> option is not disabled.</para>
+ </step>
+
+
+ <step>
+ <para>After installing <package>security/cyrus-sasl2</package>,
+ edit <filename>/usr/local/lib/sasl2/Sendmail.conf</filename>
+ (or create it if it does not exist) and add the following
+ line:</para>
+
+ <programlisting>pwcheck_method: saslauthd</programlisting>
+ </step>
+
+ <step>
+ <para>Next, install <package>security/cyrus-sasl2-saslauthd</package>,
+ edit <filename>/etc/rc.conf</filename> to add the following
+ line:</para>
+
+ <programlisting>saslauthd_enable="YES"</programlisting>
+
+ <para>and finally start the saslauthd daemon:</para>
+
+ <screen>&prompt.root; <userinput>/usr/local/etc/rc.d/saslauthd start</userinput></screen>
+
+ <para>This daemon serves as a broker for <application>sendmail</application> to
+ authenticate against your FreeBSD <filename>passwd</filename>
+ database. This saves the trouble of creating a new set of usernames
+ and passwords for each user that needs to use
+ <acronym>SMTP</acronym> authentication, and keeps the login
+ and mail password the same.</para>
+ </step>
+
+ <step>
+ <para>Now edit <filename>/etc/make.conf</filename> and add the
+ following lines:</para>
+
+ <programlisting>SENDMAIL_CFLAGS=-I/usr/local/include/sasl -DSASL
+SENDMAIL_LDFLAGS=-L/usr/local/lib
+SENDMAIL_LDADD=-lsasl2</programlisting>
+
+ <para>These lines will give <application>sendmail</application>
+ the proper configuration options for linking
+ to <package>cyrus-sasl2</package> at compile time.
+ Make sure that <package>cyrus-sasl2</package>
+ has been installed before recompiling
+ <application>sendmail</application>.</para>
+ </step>
+
+ <step>
+ <para>Recompile <application>sendmail</application> by executing the following commands:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src/lib/libsmutil</userinput>
+&prompt.root; <userinput>make cleandir &amp;&amp; make obj &amp;&amp; make</userinput>
+&prompt.root; <userinput>cd /usr/src/lib/libsm</userinput>
+&prompt.root; <userinput>make cleandir &amp;&amp; make obj &amp;&amp; make</userinput>
+&prompt.root; <userinput>cd /usr/src/usr.sbin/sendmail</userinput>
+&prompt.root; <userinput>make cleandir &amp;&amp; make obj &amp;&amp; make &amp;&amp; make install</userinput></screen>
+
+ <para>The compile of <application>sendmail</application> should not have any problems
+ if <filename>/usr/src</filename> has not been changed extensively
+ and the shared libraries it needs are available.</para>
+ </step>
+
+ <step>
+ <para>After <application>sendmail</application> has been compiled
+ and reinstalled, edit your <filename>/etc/mail/freebsd.mc</filename>
+ file (or whichever file you use as your <filename>.mc</filename> file. Many administrators
+ choose to use the output from &man.hostname.1; as the <filename>.mc</filename> file for
+ uniqueness). Add these lines to it:</para>
+
+ <programlisting>dnl set SASL options
+TRUST_AUTH_MECH(`GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN')dnl
+define(`confAUTH_MECHANISMS', `GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN')dnl</programlisting>
+
+ <para>These options configure the different methods available to
+ <application>sendmail</application> for authenticating users.
+ If you would like to use a method other than
+ <application>pwcheck</application>, please see the
+ included documentation.</para>
+ </step>
+
+ <step>
+ <para>Finally, run &man.make.1; while in <filename>/etc/mail</filename>.
+ That will run your new <filename>.mc</filename> file and create a <filename>.cf</filename> file named
+ <filename>freebsd.cf</filename> (or whatever name you have used
+ for your <filename>.mc</filename> file). Then use the
+ command <command>make install restart</command>, which will
+ copy the file to <filename>sendmail.cf</filename>, and will
+ properly restart <application>sendmail</application>.
+ For more information about this process, you should refer
+ to <filename>/etc/mail/Makefile</filename>.</para>
+ </step>
+ </procedure>
+
+ <para>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 <option>LogLevel</option> of
+ <application>sendmail</application> to 13 and watch
+ <filename>/var/log/maillog</filename> for any errors.</para>
+
+ <para>For more information, please see the <application>sendmail</application>
+ page regarding
+ <link xlink:href="http://www.sendmail.org/~ca/email/auth.html">
+ <acronym>SMTP</acronym> authentication</link>.</para>
+
+ </sect1>
+
+ <sect1 xml:id="mail-agents">
+ <info><title>Mail User Agents</title>
+ <authorgroup>
+ <author><personname><firstname>Marc</firstname><surname>Silver</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm>
+ <primary>Mail User Agents</primary>
+ </indexterm>
+
+ <para>A Mail User Agent (<acronym>MUA</acronym>) is an application
+ that is used to send and receive email. Furthermore, as email
+ <quote>evolves</quote> and becomes more complex,
+ <acronym>MUA</acronym>'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 <link linkend="ports">FreeBSD Ports Collection</link>.
+ Users may choose between graphical email clients such as
+ <application>evolution</application> or
+ <application>balsa</application>, console based clients such as
+ <application>mutt</application>, <application>pine</application>
+ or <command>mail</command>, or the web interfaces used by some
+ large organizations.</para>
+
+ <sect2 xml:id="mail-command">
+ <title>mail</title>
+
+ <para>&man.mail.1; is the default Mail User Agent
+ (<acronym>MUA</acronym>) in &os;. It is a
+ console based <acronym>MUA</acronym> 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.</para>
+
+ <para>Although <command>mail</command> does not natively support
+ interaction with <acronym>POP</acronym> or
+ <acronym>IMAP</acronym> servers, these mailboxes may be
+ downloaded to a local <filename>mbox</filename> file using an
+ application such as <application>fetchmail</application>, which
+ will be discussed later in this chapter (<xref linkend="mail-fetchmail"/>).</para>
+
+ <para>In order to send and receive email, simply invoke the
+ <command>mail</command> command as per the following
+ example:</para>
+
+ <screen>&prompt.user; <userinput>mail</userinput></screen>
+
+ <para>The contents of the user mailbox in
+ <filename>/var/mail</filename> are
+ automatically read by the <command>mail</command> 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:</para>
+
+ <screen>Mail version 8.1 6/6/93. Type ? for help.
+"/var/mail/marcs": 3 messages 3 new
+&gt;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"</screen>
+
+ <para>Messages can now be read by using the <keycap>t</keycap>
+ <command>mail</command> command, suffixed by the message number
+ that should be displayed. In this example, we will read the
+ first email:</para>
+
+ <screen>&amp; <userinput>t 1</userinput>
+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.</screen>
+
+ <para>As can be seen in the example above, the <keycap>t</keycap>
+ key will cause the message to be displayed with full headers.
+ To display the list of messages again, the <keycap>h</keycap>
+ key should be used.</para>
+
+ <para>If the email requires a response, you may use
+ <command>mail</command> to reply, by using either the
+ <keycap>R</keycap> or <keycap>r</keycap> <command>mail</command>
+ keys. The <keycap>R</keycap> key instructs
+ <command>mail</command> to reply only to the sender of the
+ email, while <keycap>r</keycap> 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 <keycap>.</keycap> on a new line. An example can be seen
+ below:</para>
+
+ <screen>&amp; <userinput>R 1</userinput>
+To: root@localhost
+Subject: Re: test
+
+<userinput>Thank you, I did get your email.
+.</userinput>
+EOT</screen>
+
+ <para>In order to send new email, the <keycap>m</keycap>
+ key should be used, followed by the
+ recipient email address. Multiple recipients may also be
+ specified by separating each address with the <keycap>,</keycap>
+ 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 <keycap>.</keycap> on a new
+ line.</para>
+
+ <screen>&amp; <userinput>mail root@localhost</userinput>
+Subject: <userinput>I mastered mail
+
+Now I can send and receive email using mail ... :)
+.</userinput>
+EOT</screen>
+
+ <para>While inside the <command>mail</command> utility, the
+ <keycap>?</keycap> command may be used to display help at any
+ time, the &man.mail.1; manual page should also be consulted for
+ more help with <command>mail</command>.</para>
+
+ <note>
+ <para>As previously mentioned, the &man.mail.1; command was not
+ originally designed to handle attachments, and thus deals with
+ them very poorly. Newer <acronym>MUA</acronym>s such as
+ <application>mutt</application> handle attachments in a much
+ more intelligent way. But should you still wish to use the
+ <command>mail</command> command, the <package>converters/mpack</package> port may be of
+ considerable use.</para>
+ </note>
+ </sect2>
+
+ <sect2 xml:id="mutt-command">
+ <title>mutt</title>
+
+ <para><application>mutt</application> is a small yet very
+ powerful Mail User Agent, with excellent features,
+ just some of which include:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The ability to thread messages;</para>
+ </listitem>
+
+ <listitem>
+ <para>PGP support for digital signing and encryption of
+ email;</para>
+ </listitem>
+
+ <listitem>
+ <para>MIME Support;</para>
+ </listitem>
+
+ <listitem>
+ <para>Maildir Support;</para>
+ </listitem>
+
+ <listitem>
+ <para>Highly customizable.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>All of these features help to make
+ <application>mutt</application> one of the most advanced mail
+ user agents available. See <uri xlink:href="http://www.mutt.org">http://www.mutt.org</uri> for more
+ information on <application>mutt</application>.</para>
+
+ <para>The stable version of <application>mutt</application> may be
+ installed using the <package>mail/mutt</package> port, while the current
+ development version may be installed via the <package>mail/mutt-devel</package> port. After the port
+ has been installed, <application>mutt</application> can be
+ started by issuing the following command:</para>
+
+ <screen>&prompt.user; <userinput>mutt</userinput></screen>
+
+ <para><application>mutt</application> will automatically read the
+ contents of the user mailbox in <filename>/var/mail</filename> and display the contents
+ if applicable. If no mails are found in the user mailbox, then
+ <application>mutt</application> will wait for commands from the
+ user. The example below shows <application>mutt</application>
+ displaying a list of messages:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="mail/mutt1"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>In order to read an email, simply select it using the cursor
+ keys, and press the <keycap>Enter</keycap> key. An example of
+ <application>mutt</application> displaying email can be seen
+ below:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="mail/mutt2"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>As with the &man.mail.1; command,
+ <application>mutt</application> 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
+ <keycap>r</keycap> keyboard shortcut. To send a group reply,
+ which will be sent to the original sender as well as all the
+ message recipients, use the <keycap>g</keycap> shortcut.</para>
+
+ <note>
+ <para><application>mutt</application> 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 <filename>.muttrc</filename> file in their home directory and setting the
+ <literal>editor</literal> variable or by setting the
+ <envar>EDITOR</envar> environment variable. See
+ <uri xlink:href="http://www.mutt.org/">http://www.mutt.org/</uri> for more
+ information about configuring
+ <application>mutt</application>.</para>
+ </note>
+
+ <para>In order to compose a new mail message, press
+ <keycap>m</keycap>. After a valid subject has been given,
+ <application>mutt</application> will start &man.vi.1; and the
+ mail can be written. Once the contents of the mail are
+ complete, save and quit from <command>vi</command> and
+ <application>mutt</application> will resume, displaying a
+ summary screen of the mail that is to be delivered. In order to
+ send the mail, press <keycap>y</keycap>. An example of the
+ summary screen can be seen below:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="mail/mutt3"/>
+ </imageobject>
+ </mediaobject>
+
+ <para><application>mutt</application> also contains extensive
+ help, which can be accessed from most of the menus by pressing
+ the <keycap>?</keycap> key. The top line also displays the
+ keyboard shortcuts where appropriate.</para>
+
+ </sect2>
+
+ <sect2 xml:id="pine-command">
+ <title>pine</title>
+
+ <para><application>pine</application> is aimed at a beginner
+ user, but also includes some advanced features.</para>
+
+ <warning>
+ <para>The <application>pine</application> 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
+ <emphasis>known</emphasis> problems have been fixed, but the
+ <application>pine</application> code is written in a very insecure style and the &os;
+ Security Officer believes there are likely to be other
+ undiscovered vulnerabilities. You install
+ <application>pine</application> at your own risk.</para>
+ </warning>
+
+ <para>The current version of <application>pine</application> may
+ be installed using the <package>mail/pine4</package> port. Once the port has
+ installed, <application>pine</application> can be started by
+ issuing the following command:</para>
+
+ <screen>&prompt.user; <userinput>pine</userinput></screen>
+
+ <para>The first time that <application>pine</application> is run
+ it displays a greeting page with a brief introduction, as well
+ as a request from the <application>pine</application>
+ 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 <keycap>Enter</keycap>, or
+ alternatively press <keycap>E</keycap> to exit the greeting
+ without sending an anonymous message. An example of the
+ greeting page can be seen below:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="mail/pine1"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>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.</para>
+
+ <para>The default directory opened by <application>pine</application>
+ is the <filename>inbox</filename>. To view the message index, press
+ <keycap>I</keycap>, or select the <guimenuitem>MESSAGE INDEX</guimenuitem>
+ option as seen below:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="mail/pine2"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>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
+ <keycap>Enter</keycap> key.</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="mail/pine3"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>In the screenshot below, a sample message is displayed by
+ <application>pine</application>. Keyboard shortcuts are
+ displayed as a reference at the bottom of the screen. An
+ example of one of these shortcuts is the <keycap>r</keycap> key,
+ which tells the <acronym>MUA</acronym> to reply to the current
+ message being displayed.</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="mail/pine4"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>Replying to an email in <application>pine</application> is
+ done using the <application>pico</application> editor, which is
+ installed by default with <application>pine</application>.
+ The <application>pico</application> 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
+ <keycombo action="simul"><keycap>Ctrl</keycap><keycap>X</keycap>
+ </keycombo>. The <application>pine</application> application
+ will ask for confirmation.</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="mail/pine5"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>The <application>pine</application> application can be
+ customized using the <guimenuitem>SETUP</guimenuitem> option from the main
+ menu. Consult <uri xlink:href="http://www.washington.edu/pine/">http://www.washington.edu/pine/</uri>
+ for more information.</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="mail-fetchmail">
+ <info><title>Using fetchmail</title>
+ <authorgroup>
+ <author><personname><firstname>Marc</firstname><surname>Silver</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm>
+ <primary>fetchmail</primary>
+ </indexterm>
+
+ <para><application>fetchmail</application> is a full-featured
+ <acronym>IMAP</acronym> and <acronym>POP</acronym> client which
+ allows users to automatically download mail from remote
+ <acronym>IMAP</acronym> and <acronym>POP</acronym> servers and
+ save it into local mailboxes; there it can be accessed more easily.
+ <application>fetchmail</application> can be installed using the
+ <package>mail/fetchmail</package> port, and
+ offers various features, some of which include:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Support of <acronym>POP3</acronym>,
+ <acronym>APOP</acronym>, <acronym>KPOP</acronym>,
+ <acronym>IMAP</acronym>, <acronym>ETRN</acronym> and
+ <acronym>ODMR</acronym> protocols.</para>
+ </listitem>
+
+ <listitem>
+ <para>Ability to forward mail using <acronym>SMTP</acronym>, which
+ allows filtering, forwarding, and aliasing to function
+ normally.</para>
+ </listitem>
+
+ <listitem>
+ <para>May be run in daemon mode to check periodically for new
+ messages.</para>
+ </listitem>
+
+ <listitem>
+ <para>Can retrieve multiple mailboxes and forward them based
+ on configuration, to different local users.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>While it is outside the scope of this document to explain
+ all of <application>fetchmail</application>'s features, some
+ basic features will be explained. The
+ <application>fetchmail</application> utility requires a
+ configuration file known as <filename>.fetchmailrc</filename>,
+ 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:</para>
+
+ <screen>&prompt.user; <userinput>chmod 600 .fetchmailrc</userinput></screen>
+
+ <para>The following <filename>.fetchmailrc</filename> serves as an
+ example for downloading a single user mailbox using
+ <acronym>POP</acronym>. It tells
+ <application>fetchmail</application> to connect to <systemitem class="fqdomainname">example.com</systemitem> using a username of
+ <systemitem class="username">joesoap</systemitem> and a password of
+ <literal>XXX</literal>. This example assumes that the user
+ <systemitem class="username">joesoap</systemitem> is also a user on the local
+ system.</para>
+
+ <programlisting>poll example.com protocol pop3 username "joesoap" password "XXX"</programlisting>
+
+ <para>The next example connects to multiple <acronym>POP</acronym>
+ and <acronym>IMAP</acronym> servers and redirects to different
+ local usernames where applicable:</para>
+
+ <programlisting>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;</programlisting>
+
+ <para>The <application>fetchmail</application> utility can be run in daemon
+ mode by running it with the <option>-d</option> flag, followed
+ by the interval (in seconds) that
+ <application>fetchmail</application> should poll servers listed
+ in the <filename>.fetchmailrc</filename> file. The following
+ example would cause <application>fetchmail</application> to poll
+ every 600 seconds:</para>
+
+ <screen>&prompt.user; <userinput>fetchmail -d 600</userinput></screen>
+
+ <para>More information on <application>fetchmail</application> can
+ be found at <uri xlink:href="http://fetchmail.berlios.de/">http://fetchmail.berlios.de/</uri>.</para>
+ </sect1>
+
+ <sect1 xml:id="mail-procmail">
+ <info><title>Using procmail</title>
+ <authorgroup>
+ <author><personname><firstname>Marc</firstname><surname>Silver</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm>
+ <primary>procmail</primary>
+ </indexterm>
+
+ <para>The <application>procmail</application> utility is an
+ incredibly powerful application used to filter incoming mail.
+ It allows users to define <quote>rules</quote> which can be
+ matched to incoming mails to perform specific functions or to
+ reroute mail to alternative mailboxes and/or email addresses.
+ <application>procmail</application> can be installed using the
+ <package>mail/procmail</package> port. Once
+ installed, it can be directly integrated into most
+ <acronym>MTA</acronym>s; consult your <acronym>MTA</acronym>
+ documentation for more information. Alternatively,
+ <application>procmail</application> can be integrated by adding
+ the following line to a <filename>.forward</filename> in the home
+ directory of the user utilizing
+ <application>procmail</application> features:</para>
+
+ <programlisting>"|exec /usr/local/bin/procmail || exit 75"</programlisting>
+
+ <para>The following section will display some basic
+ <application>procmail</application> rules, as well as brief
+ descriptions on what they do. These rules, and others must be
+ inserted into a <filename>.procmailrc</filename> file, which
+ must reside in the user's home directory.</para>
+
+ <para>The majority of these rules can also be found in the
+ &man.procmailex.5; manual page.</para>
+
+ <para>Forward all mail from <email>user@example.com</email> to an
+ external address of <email role="nolink">goodmail@example2.com</email>:</para>
+
+ <programlisting>:0
+* ^From.*user@example.com
+! goodmail@example2.com</programlisting>
+
+ <para>Forward all mails shorter than 1000 bytes to an external
+ address of <email role="nolink">goodmail@example2.com</email>:</para>
+
+ <programlisting>:0
+* &lt; 1000
+! goodmail@example2.com</programlisting>
+
+ <para>Send all mail sent to <email>alternate@example.com</email>
+ into a mailbox called <filename>alternate</filename>:</para>
+
+ <programlisting>:0
+* ^TOalternate@example.com
+alternate</programlisting>
+
+ <para>Send all mail with a subject of <quote>Spam</quote> to
+ <filename>/dev/null</filename>:</para>
+
+ <programlisting>:0
+^Subject:.*Spam
+/dev/null</programlisting>
+
+ <para>A useful recipe that parses incoming <systemitem class="fqdomainname">&os;.org</systemitem> mailing lists
+ and places each list in its own mailbox:</para>
+
+ <programlisting>:0
+* ^Sender:.owner-freebsd-\/[^@]+@FreeBSD.ORG
+{
+ LISTNAME=${MATCH}
+ :0
+ * LISTNAME??^\/[^@]+
+ FreeBSD-${MATCH}
+}</programlisting>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/mirrors/Makefile b/zh_TW.UTF-8/books/handbook/mirrors/Makefile
new file mode 100644
index 0000000000..9197ba315d
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/mirrors/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= mirrors/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/mirrors/chapter.xml b/zh_TW.UTF-8/books/handbook/mirrors/chapter.xml
new file mode 100644
index 0000000000..4373bb3521
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/mirrors/chapter.xml
@@ -0,0 +1,3190 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.420
+-->
+<appendix xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="mirrors">
+ <title>取得 FreeBSD 的方式</title>
+
+ <sect1 xml:id="mirrors-cdrom">
+ <title>CDROM 及 DVD 發行商</title>
+
+ <sect2>
+ <title>盒裝產品的零售處:</title>
+
+ <para>FreeBSD 盒裝產品(含 FreeBSD 光碟及其他一些軟體、書面文件)的零售業者:</para>
+
+ <itemizedlist>
+ <listitem>
+ <address>
+ CompUSA
+ WWW: <otheraddr xlink:href="http://www.compusa.com/">http://www.compusa.com/</otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ Frys Electronics
+ WWW: <otheraddr xlink:href="http://www.frys.com/">http://www.frys.com/</otheraddr>
+ </address>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>CD 及 DVD 合集</title>
+
+ <para>FreeBSD 光碟(CD 及 DVD)的網路零售業者:</para>
+
+ <itemizedlist>
+ <listitem>
+ <address>
+ BSD Mall by Daemon News
+ <street>PO Box 161</street>
+ <city>Nauvoo</city>, <state>IL</state> <postcode>62354</postcode>
+ <country>USA</country>
+ Phone: <phone>+1 866 273-6255</phone>
+ Fax: <fax>+1 217 453-9956</fax>
+ Email: <email>sales@bsdmall.com</email>
+ WWW: <otheraddr xlink:href="http://www.bsdmall.com/freebsd1.html">http://www.bsdmall.com/freebsd1.html</otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ BSD-Systems
+ Email: <email>info@bsd-systems.co.uk</email>
+ WWW: <otheraddr xlink:href="http://www.bsd-systems.co.uk">http://www.bsd-systems.co.uk</otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ FreeBSD Mall, Inc.
+ <street>3623 Sanford Street</street>
+ <city>Concord</city>, <state>CA</state> <postcode>94520-1405</postcode>
+ <country>USA</country>
+ Phone: <phone>+1 925 674-0783</phone>
+ Fax: <fax>+1 925 674-0821</fax>
+ Email: <email>info@freebsdmall.com</email>
+ WWW: <otheraddr xlink:href="http://www.freebsdmall.com/">http://www.freebsdmall.com/</otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ Hinner EDV
+ <street>St. Augustinus-Str. 10</street>
+ <postcode>D-81825</postcode> <city>M&uuml;nchen</city>
+ <country>Germany</country>
+ Phone: <phone>(089) 428 419</phone>
+ WWW: <otheraddr xlink:href="http://www.hinner.de/linux/freebsd.html">http://www.hinner.de/linux/freebsd.html</otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ Ikarios
+ <street>22-24 rue Voltaire</street>
+ <postcode>92000</postcode> <city>Nanterre</city>
+ <country>France</country>
+ WWW: <otheraddr xlink:href="http://ikarios.com/form/#freebsd">http://ikarios.com/form/#freebsd</otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ JMC Software
+ <country>Ireland</country>
+ Phone: <phone>353 1 6291282</phone>
+ WWW: <otheraddr xlink:href="http://www.thelinuxmall.com">http://www.thelinuxmall.com</otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ Linux CD Mall
+ <street>Private Bag MBE N348</street>
+ <city>Auckland 1030</city>
+ <country>New Zealand</country>
+ Phone: <phone>+64 21 866529</phone>
+ WWW: <otheraddr xlink:href="http://www.linuxcdmall.co.nz/">http://www.linuxcdmall.co.nz/</otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ The Linux Emporium
+ <street>Hilliard House, Lester Way</street>
+ <city>Wallingford</city>
+ <postcode>OX10 9TA</postcode>
+ <country>United Kingdom</country>
+ Phone: <phone>+44 1491 837010</phone>
+ Fax: <fax>+44 1491 837016</fax>
+ WWW: <otheraddr xlink:href="http://www.linuxemporium.co.uk/products/freebsd/">http://www.linuxemporium.co.uk/products/freebsd/</otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ Linux+ DVD Magazine
+ <street>Lewartowskiego 6</street>
+ <city>Warsaw</city>
+ <postcode>00-190</postcode>
+ <country>Poland</country>
+ Phone: <phone>+48 22 860 18 18</phone>
+ Email: <email>editors@lpmagazine.org</email>
+ WWW: <otheraddr xlink:href="http://www.lpmagazine.org/">http://www.lpmagazine.org/</otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ Linux System Labs Australia
+ <street>21 Ray Drive</street>
+ <city>Balwyn North</city>
+ <postcode>VIC - 3104</postcode>
+ <country>Australia</country>
+ Phone: <phone>+61 3 9857 5918</phone>
+ Fax: <fax>+61 3 9857 8974</fax>
+ WWW: <otheraddr xlink:href="http://www.lsl.com.au">http://www.lsl.com.au</otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ LinuxCenter.Ru
+ <street>Galernaya Street, 55</street>
+ <city>Saint-Petersburg</city>
+ <postcode>190000</postcode>
+ <country>Russia</country>
+ Phone: <phone>+7-812-3125208</phone>
+ Email: <email>info@linuxcenter.ru</email>
+ WWW: <otheraddr xlink:href="http://linuxcenter.ru/freebsd">http://linuxcenter.ru/freebsd</otheraddr>
+ </address>
+ </listitem>
+
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>經銷商(Distributors)</title>
+
+ <para>若你是區域經銷商,並想代理經銷 FreeBSD 光碟產品的話,請與下列的代理商聯繫:</para>
+
+ <itemizedlist>
+ <listitem>
+ <address>
+ Cylogistics
+ <street>809B Cuesta Dr., #2149</street>
+ <city>Mountain View</city>, <state>CA</state> <postcode>94040</postcode>
+ <country>USA</country>
+ Phone: <phone>+1 650 694-4949</phone>
+ Fax: <fax>+1 650 694-4953</fax>
+ Email: <email>sales@cylogistics.com</email>
+ WWW: <otheraddr xlink:href="http://www.cylogistics.com/">http://www.cylogistics.com/</otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ Ingram Micro
+ <street>1600 E. St. Andrew Place</street>
+ <city>Santa Ana</city>, <state>CA</state> <postcode>92705-4926</postcode>
+ <country>USA</country>
+ Phone: <phone>1 (800) 456-8000</phone>
+ WWW: <otheraddr xlink:href="http://www.ingrammicro.com/">http://www.ingrammicro.com/</otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ Kudzu, LLC
+ <street>7375 Washington Ave. S.</street>
+ <city>Edina</city>, <state>MN</state> <postcode>55439</postcode>
+ <country>USA</country>
+ Phone: <phone>+1 952 947-0822</phone>
+ Fax: <fax>+1 952 947-0876</fax>
+ Email: <email>sales@kudzuenterprises.com</email>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ LinuxCenter.Ru
+ <street>Galernaya Street, 55</street>
+ <city>Saint-Petersburg</city>
+ <postcode>190000</postcode>
+ <country>Russia</country>
+ Phone: <phone>+7-812-3125208</phone>
+ Email: <email>info@linuxcenter.ru</email>
+ WWW: <otheraddr xlink:href="http://linuxcenter.ru/freebsd">http://linuxcenter.ru/freebsd</otheraddr>
+ </address>
+ </listitem>
+
+ <listitem>
+ <address>
+ Navarre Corp
+ <street>7400 49th Ave South</street>
+ <city>New Hope</city>, <state>MN</state> <postcode>55428</postcode>
+ <country>USA</country>
+ Phone: <phone>+1 763 535-8333</phone>
+ Fax: <fax>+1 763 535-0341</fax>
+ WWW: <otheraddr xlink:href="http://www.navarre.com/">http://www.navarre.com/</otheraddr>
+ </address>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="mirrors-ftp">
+ <title>FTP 站</title>
+
+ <para>The official sources for FreeBSD are available via anonymous FTP
+ from a worldwide set of mirror sites. The site
+ <uri xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/">ftp://ftp.FreeBSD.org/pub/FreeBSD/</uri> is well
+ connected and allows a large number of connections to it, but
+ you are probably better off finding a <quote>closer</quote>
+ mirror site (especially if you decide to set up some sort of
+ mirror site).</para>
+
+ <para>The <link xlink:href="http://mirrorlist.FreeBSD.org/">FreeBSD mirror
+ sites database</link> is more accurate than the mirror listing in the
+ Handbook, as it gets its information from the DNS rather than relying on
+ static lists of hosts.</para>
+
+ <para>Additionally, FreeBSD is available via anonymous FTP from the
+ following mirror sites. If you choose to obtain FreeBSD via anonymous
+ FTP, please try to use a site near you. The mirror sites listed as
+ <quote>Primary Mirror Sites</quote> typically have the entire FreeBSD archive (all
+ the currently available versions for each of the architectures) but
+ you will probably have faster download times from a site that is
+ in your country or region. The regional sites carry the most recent
+ versions for the most popular architecture(s) but might not carry
+ the entire FreeBSD archive. All sites provide access via anonymous
+ FTP but some sites also provide access via other methods. The access
+ methods available for each site are provided in parentheses
+ after the hostname.</para>
+
+ &chap.mirrors.ftp.index.inc;
+
+ &chap.mirrors.lastmod.inc;
+
+ &chap.mirrors.ftp.inc;
+ </sect1>
+
+ <sect1 xml:id="anoncvs">
+ <title>Anonymous CVS</title>
+
+ <sect2 xml:id="anoncvs-intro">
+ <title>anoncvs 簡介</title>
+
+ <indexterm>
+ <primary>CVS</primary>
+ <secondary>anonymous</secondary>
+ </indexterm>
+
+ <para>Anonymous CVS (or, as it is otherwise known,
+ <emphasis>anoncvs</emphasis>) is a feature provided by the CVS
+ utilities bundled with FreeBSD for synchronizing with a remote
+ CVS repository. Among other things, it allows users of FreeBSD
+ to perform, with no special privileges, read-only CVS operations
+ against one of the FreeBSD project's official anoncvs servers.
+ To use it, one simply sets the <envar>CVSROOT</envar>
+ environment variable to point at the appropriate anoncvs server,
+ provides the well-known password <quote>anoncvs</quote> with the
+ <command>cvs login</command> command, and then uses the
+ &man.cvs.1; command to access it like any local
+ repository.</para>
+
+ <note>
+ <para>The <command>cvs login</command> command, stores the passwords
+ that are used for authenticating to the CVS server in a file
+ called <filename>.cvspass</filename> in your
+ <envar>HOME</envar> directory. If this file does not exist,
+ you might get an error when trying to use <command>cvs
+ login</command> for the first time. Just make an empty
+ <filename>.cvspass</filename> file, and retry to login.</para>
+ </note>
+
+ <para>While it can also be said that the <link linkend="cvsup">CVSup</link> and <emphasis>anoncvs</emphasis>
+ services both perform essentially the same function, there are
+ various trade-offs which can influence the user's choice of
+ synchronization methods. In a nutshell,
+ <application>CVSup</application> is much more efficient in its
+ usage of network resources and is by far the most technically
+ sophisticated of the two, but at a price. To use
+ <application>CVSup</application>, a special client must first be
+ installed and configured before any bits can be grabbed, and
+ then only in the fairly large chunks which
+ <application>CVSup</application> calls
+ <emphasis>collections</emphasis>.</para>
+
+ <para><application>Anoncvs</application>, by contrast, can be used
+ to examine anything from an individual file to a specific
+ program (like <command>ls</command> or <command>grep</command>)
+ by referencing the CVS module name. Of course,
+ <application>anoncvs</application> is also only good for
+ read-only operations on the CVS repository, so if it is your
+ intention to support local development in one repository shared
+ with the FreeBSD project bits then
+ <application>CVSup</application> is really your only
+ option.</para>
+ </sect2>
+
+ <sect2 xml:id="anoncvs-usage">
+ <title>Using Anonymous CVS</title>
+
+ <para>Configuring &man.cvs.1; to use an Anonymous CVS repository
+ is a simple matter of setting the <envar>CVSROOT</envar>
+ environment variable to point to one of the FreeBSD project's
+ <emphasis>anoncvs</emphasis> servers. At the time of this
+ writing, the following servers are available:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>Austria(奧地利)</emphasis>:
+ :pserver:anoncvs@anoncvs.at.FreeBSD.org:/home/ncvs
+ (Use <command>cvs login</command> and enter any
+ password when prompted.)</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>France(法國)</emphasis>:
+ :pserver:anoncvs@anoncvs.fr.FreeBSD.org:/home/ncvs
+ (pserver (password <quote>anoncvs</quote>), ssh (no password))
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>Germany(德國)</emphasis>:
+ :pserver:anoncvs@anoncvs.de.FreeBSD.org:/home/ncvs
+ (Use <command>cvs login</command> and enter the password
+ <quote>anoncvs</quote> when prompted.)</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>Germany(德國)</emphasis>:
+ :pserver:anoncvs@anoncvs2.de.FreeBSD.org:/home/ncvs
+ (rsh, pserver, ssh, ssh/2022)
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>Japan(日本)</emphasis>:
+ :pserver:anoncvs@anoncvs.jp.FreeBSD.org:/home/ncvs
+ (Use <command>cvs login</command> and enter the password
+ <quote>anoncvs</quote> when prompted.)</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>USA(美國)</emphasis>:
+ freebsdanoncvs@anoncvs.FreeBSD.org:/home/ncvs
+ (ssh only - no password)</para>
+
+ <programlisting>SSH HostKey: 1024 a1:e7:46:de:fb:56:ef:05:bc:73:aa:91:09:da:f7:f4 root@sanmateo.ecn.purdue.edu
+SSH2 HostKey: 1024 52:02:38:1a:2f:a8:71:d3:f5:83:93:8d:aa:00:6f:65 ssh_host_dsa_key.pub</programlisting>
+
+ </listitem>
+ <listitem>
+ <para><emphasis>USA(美國)</emphasis>:
+ anoncvs@anoncvs1.FreeBSD.org:/home/ncvs (ssh only - no
+ password)</para>
+
+ <programlisting>SSH HostKey: 1024 8b:c4:6f:9a:7e:65:8a:eb:50:50:29:7c:a1:47:03:bc root@ender.liquidneon.com
+SSH2 HostKey: 2048 4d:59:19:7b:ea:9b:76:0b:ca:ee:da:26:e2:3a:83:b8 ssh_host_dsa_key.pub</programlisting>
+
+ </listitem>
+ </itemizedlist>
+
+ <para>Since CVS allows one to <quote>check out</quote> virtually
+ any version of the FreeBSD sources that ever existed (or, in
+ some cases, will exist), you need to be
+ familiar with the revision (<option>-r</option>) flag to
+ &man.cvs.1; and what some of the permissible values for it in
+ the FreeBSD Project repository are.</para>
+
+ <para>There are two kinds of tags, revision tags and branch tags.
+ A revision tag refers to a specific revision. Its meaning stays
+ the same from day to day. A branch tag, on the other hand,
+ refers to the latest revision on a given line of development, at
+ any given time. Because a branch tag does not refer to a
+ specific revision, it may mean something different tomorrow than
+ it means today.</para>
+
+ <para><xref linkend="cvs-tags"/> contains revision tags that users
+ might be interested
+ in. Again, none of these are valid for the Ports Collection
+ since the Ports Collection does not have multiple
+ revisions.</para>
+
+ <para>When you specify a branch tag, you normally receive the
+ latest versions of the files on that line of development. If
+ you wish to receive some past version, you can do so by
+ specifying a date with the <option>-D date</option> flag.
+ See the &man.cvs.1; manual page for more details.</para>
+ </sect2>
+
+ <sect2>
+ <title>Examples</title>
+
+ <para>While it really is recommended that you read the manual page
+ for &man.cvs.1; thoroughly before doing anything, here are some
+ quick examples which essentially show how to use Anonymous
+ CVS:</para>
+
+ <example>
+ <title>Checking Out Something from -CURRENT (&man.ls.1;):</title>
+
+ <screen>&prompt.user; <userinput>setenv CVSROOT :pserver:anoncvs@anoncvs.jp.FreeBSD.org:/home/ncvs</userinput>
+&prompt.user; <userinput>cvs login</userinput>
+<emphasis>At the prompt, enter the password</emphasis> <quote>anoncvs</quote>.
+&prompt.user; <userinput>cvs co ls</userinput>
+ </screen>
+ </example>
+
+ <example>
+ <title>Using SSH to check out the <filename>src/</filename>
+ tree:</title>
+ <screen>&prompt.user; <userinput>cvs -d freebsdanoncvs@anoncvs.FreeBSD.org:/home/ncvs co src</userinput>
+The authenticity of host 'anoncvs.freebsd.org (128.46.156.46)' can't be established.
+DSA key fingerprint is 52:02:38:1a:2f:a8:71:d3:f5:83:93:8d:aa:00:6f:65.
+Are you sure you want to continue connecting (yes/no)? <userinput>yes</userinput>
+Warning: Permanently added 'anoncvs.freebsd.org' (DSA) to the list of known hosts.</screen>
+ </example>
+
+ <example>
+ <title>Checking Out the Version of &man.ls.1; in the 6-STABLE
+ Branch:</title>
+
+ <screen>&prompt.user; <userinput>setenv CVSROOT :pserver:anoncvs@anoncvs.jp.FreeBSD.org:/home/ncvs</userinput>
+&prompt.user; <userinput>cvs login</userinput>
+<emphasis>At the prompt, enter the password</emphasis> <quote>anoncvs</quote>.
+&prompt.user; <userinput>cvs co -rRELENG_6 ls</userinput>
+ </screen>
+ </example>
+
+ <example>
+ <title>Creating a List of Changes (as Unified Diffs) to &man.ls.1;</title>
+
+ <screen>&prompt.user; <userinput>setenv CVSROOT :pserver:anoncvs@anoncvs.jp.FreeBSD.org:/home/ncvs</userinput>
+&prompt.user; <userinput>cvs login</userinput>
+<emphasis>At the prompt, enter the password</emphasis> <quote>anoncvs</quote>.
+&prompt.user; <userinput>cvs rdiff -u -rRELENG_5_3_0_RELEASE -rRELENG_5_4_0_RELEASE ls</userinput>
+ </screen>
+ </example>
+
+ <example>
+ <title>Finding Out What Other Module Names Can Be Used:</title>
+
+ <screen>&prompt.user; <userinput>setenv CVSROOT :pserver:anoncvs@anoncvs.jp.FreeBSD.org:/home/ncvs</userinput>
+&prompt.user; <userinput>cvs login</userinput>
+<emphasis>At the prompt, enter the password</emphasis> <quote>anoncvs</quote>.
+&prompt.user; <userinput>cvs co modules</userinput>
+&prompt.user; <userinput>more modules/modules</userinput>
+ </screen>
+ </example>
+ </sect2>
+
+ <sect2>
+ <title>Other Resources</title>
+
+ <para>The following additional resources may be helpful in learning
+ CVS:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="http://www.csc.calpoly.edu/~dbutler/tutorials/winter96/cvs/">CVS Tutorial</link> from Cal Poly.</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://ximbiot.com/cvs/wiki/">CVS Home</link>,
+ the CVS development and support community.</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.FreeBSD.org/cgi/cvsweb.cgi">CVSweb</link> is
+ the FreeBSD Project web interface for CVS.</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ </sect1>
+
+
+ <sect1 xml:id="ctm">
+ <title>Using CTM</title>
+
+ <indexterm>
+ <primary>CTM</primary>
+ </indexterm>
+
+ <para><application>CTM</application> is a method for keeping a
+ remote directory tree in sync with a central one. It has been
+ developed for usage with FreeBSD's source trees, though other
+ people may find it useful for other purposes as time goes by.
+ Little, if any, documentation currently exists at this time on the
+ process of creating deltas, so contact the &a.ctm-users.name; mailing list for more
+ information and if you wish to use <application>CTM</application>
+ for other things.</para>
+
+ <sect2>
+ <title>Why Should I Use <application>CTM</application>?</title>
+
+ <para><application>CTM</application> will give you a local copy of
+ the FreeBSD source trees. There are a number of
+ <quote>flavors</quote> of the tree available. Whether you wish
+ to track the entire CVS tree or just one of the branches,
+ <application>CTM</application> can provide you the information.
+ If you are an active developer on FreeBSD, but have lousy or
+ non-existent TCP/IP connectivity, or simply wish to have the
+ changes automatically sent to you,
+ <application>CTM</application> was made for you. You will need
+ to obtain up to three deltas per day for the most active
+ branches. However, you should consider having them sent by
+ automatic email. The sizes of the updates are always kept as
+ small as possible. This is typically less than 5K, with an
+ occasional (one in ten) being 10-50K and every now and then a
+ large 100K+ or more coming around.</para>
+
+ <para>You will also need to make yourself aware of the various
+ caveats related to working directly from the development sources
+ rather than a pre-packaged release. This is particularly true
+ if you choose the <quote>current</quote> sources. It is
+ recommended that you read <link linkend="current">Staying
+ current with FreeBSD</link>.</para>
+ </sect2>
+
+ <sect2>
+ <title>What Do I Need to Use
+ <application>CTM</application>?</title>
+
+ <para>You will need two things: The <application>CTM</application>
+ program, and the initial deltas to feed it (to get up to
+ <quote>current</quote> levels).</para>
+
+ <para>The <application>CTM</application> program has been part of
+ FreeBSD ever since version 2.0 was released, and lives in
+ <filename>/usr/src/usr.sbin/ctm</filename> if you have a copy
+ of the source available.</para>
+
+ <para>The <quote>deltas</quote> you feed
+ <application>CTM</application> can be had two ways, FTP or
+ email. If you have general FTP access to the Internet then the
+ following FTP sites support access to
+ <application>CTM</application>:</para>
+
+ <para><uri xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/CTM/">ftp://ftp.FreeBSD.org/pub/FreeBSD/CTM/</uri></para>
+
+ <para>or see section <link linkend="mirrors-ctm">mirrors</link>.</para>
+
+ <para>FTP the relevant directory and fetch the
+ <filename>README</filename> file, starting from there.</para>
+
+ <para>If you wish to get your deltas via email:</para>
+
+ <para>Subscribe to one of the
+ <application>CTM</application> distribution lists.
+ &a.ctm-cvs-cur.name; supports the entire CVS tree.
+ &a.ctm-src-cur.name; supports the head of the development
+ branch. &a.ctm-src-4.name; supports the 4.X release
+ branch, etc.. (If you do not know how to subscribe yourself
+ to a list, click on the list name above or go to
+ &a.mailman.lists.link; and click on the list that you
+ wish to subscribe to. The list page should contain all of
+ the necessary subscription instructions.)</para>
+
+ <para>When you begin receiving your <application>CTM</application>
+ updates in the mail, you may use the
+ <command>ctm_rmail</command> program to unpack and apply them.
+ You can actually use the <command>ctm_rmail</command> program
+ directly from a entry in <filename>/etc/aliases</filename> if
+ you want to have the process run in a fully automated fashion.
+ Check the <command>ctm_rmail</command> manual page for more
+ details.</para>
+
+ <note>
+ <para>No matter what method you use to get the
+ <application>CTM</application> deltas, you should subscribe to
+ the &a.ctm-announce.name; mailing list. In
+ the future, this will be the only place where announcements
+ concerning the operations of the
+ <application>CTM</application> system will be posted. Click
+ on the list name above and follow the instructions
+ to subscribe to the
+ list.</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Using <application>CTM</application> for the First
+ Time</title>
+
+ <para>Before you can start using <application>CTM</application>
+ deltas, you will need to get to a starting point for the deltas
+ produced subsequently to it.</para>
+
+ <para>First you should determine what you already have. Everyone
+ can start from an <quote>empty</quote> directory. You must use
+ an initial <quote>Empty</quote> delta to start off your
+ <application>CTM</application> supported tree. At some point it
+ is intended that one of these <quote>started</quote> deltas be
+ distributed on the CD for your convenience, however, this does
+ not currently happen.</para>
+
+ <para>Since the trees are many tens of megabytes, you should
+ prefer to start from something already at hand. If you have a
+ -RELEASE CD, you can copy or extract an initial source from it.
+ This will save a significant transfer of data.</para>
+
+ <para>You can recognize these <quote>starter</quote> deltas by the
+ <literal>X</literal> appended to the number
+ (<filename>src-cur.3210XEmpty.gz</filename> for instance). The
+ designation following the <literal>X</literal> corresponds to
+ the origin of your initial <quote>seed</quote>.
+ <filename>Empty</filename> is an empty directory. As a rule a
+ base transition from <literal>Empty</literal> is produced
+ every 100 deltas. By the way, they are large! 70 to 80
+ Megabytes of <command>gzip</command>'d data is common for the
+ <filename>XEmpty</filename> deltas.</para>
+
+ <para>Once you have picked a base delta to start from, you will also
+ need all deltas with higher numbers following it.</para>
+ </sect2>
+
+ <sect2>
+ <title>Using <application>CTM</application> in Your Daily
+ Life</title>
+
+ <para>To apply the deltas, simply say:</para>
+
+ <screen>&prompt.root; <userinput>cd /where/ever/you/want/the/stuff</userinput>
+&prompt.root; <userinput>ctm -v -v /where/you/store/your/deltas/src-xxx.*</userinput></screen>
+
+ <para><application>CTM</application> understands deltas which have
+ been put through <command>gzip</command>, so you do not need to
+ <command>gunzip</command> them first, this saves disk space.</para>
+
+ <para>Unless it feels very secure about the entire process,
+ <application>CTM</application> will not touch your tree. To
+ verify a delta you can also use the <option>-c</option> flag and
+ <application>CTM</application> will not actually touch your
+ tree; it will merely verify the integrity of the delta and see
+ if it would apply cleanly to your current tree.</para>
+
+ <para>There are other options to <application>CTM</application>
+ as well, see the manual pages or look in the sources for more
+ information.</para>
+
+ <para>That is really all there is to it. Every time you get a new
+ delta, just run it through <application>CTM</application> to
+ keep your sources up to date.</para>
+
+ <para>Do not remove the deltas if they are hard to download again.
+ You just might want to keep them around in case something bad
+ happens. Even if you only have floppy disks, consider using
+ <command>fdwrite</command> to make a copy.</para>
+ </sect2>
+
+ <sect2>
+ <title>Keeping Your Local Changes</title>
+
+ <para>As a developer one would like to experiment with and change
+ files in the source tree. <application>CTM</application>
+ supports local modifications in a limited way: before checking
+ for the presence of a file <filename>foo</filename>, it first
+ looks for <filename>foo.ctm</filename>. If this file exists,
+ <application>CTM</application> will operate on it instead of
+ <filename>foo</filename>.</para>
+
+ <para>This behavior gives us a simple way to maintain local
+ changes: simply copy the files you plan to modify to the
+ corresponding file names with a <filename>.ctm</filename>
+ suffix. Then you can freely hack the code, while <application>CTM</application> keeps the
+ <filename>.ctm</filename> file up-to-date.</para>
+ </sect2>
+
+ <sect2>
+ <title>Other Interesting <application>CTM</application> Options</title>
+
+ <sect3>
+ <title>Finding Out Exactly What Would Be Touched by an
+ Update</title>
+
+ <para>You can determine the list of changes that
+ <application>CTM</application> will make on your source
+ repository using the <option>-l</option> option to
+ <application>CTM</application>.</para>
+
+ <para>This is useful if you would like to keep logs of the
+ changes, pre- or post- process the modified files in any
+ manner, or just are feeling a tad paranoid.</para>
+ </sect3>
+
+ <sect3>
+ <title>Making Backups Before Updating</title>
+
+ <para>Sometimes you may want to backup all the files that would
+ be changed by a <application>CTM</application> update.</para>
+
+ <para>Specifying the <option>-B backup-file</option> option
+ causes <application>CTM</application> to backup all files that
+ would be touched by a given <application>CTM</application>
+ delta to <filename>backup-file</filename>.</para>
+ </sect3>
+
+ <sect3>
+ <title>Restricting the Files Touched by an Update</title>
+
+ <para>Sometimes you would be interested in restricting the scope
+ of a given <application>CTM</application> update, or may be
+ interested in extracting just a few files from a sequence of
+ deltas.</para>
+
+ <para>You can control the list of files that
+ <application>CTM</application> would operate on by specifying
+ filtering regular expressions using the <option>-e</option>
+ and <option>-x</option> options.</para>
+
+ <para>For example, to extract an up-to-date copy of
+ <filename>lib/libc/Makefile</filename> from your collection of
+ saved <application>CTM</application> deltas, run the commands:</para>
+
+ <screen>&prompt.root; <userinput>cd /where/ever/you/want/to/extract/it/</userinput>
+&prompt.root; <userinput>ctm -e '^lib/libc/Makefile' ~ctm/src-xxx.*</userinput></screen>
+
+ <para>For every file specified in a
+ <application>CTM</application> delta, the <option>-e</option>
+ and <option>-x</option> options are applied in the order given
+ on the command line. The file is processed by
+ <application>CTM</application> only if it is marked as
+ eligible after all the <option>-e</option> and
+ <option>-x</option> options are applied to it.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Future Plans for <application>CTM</application></title>
+
+ <para>Tons of them:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Use some kind of authentication into the <application>CTM</application> system, so
+ as to allow detection of spoofed <application>CTM</application> updates.</para>
+ </listitem>
+
+ <listitem>
+ <para>Clean up the options to <application>CTM</application>,
+ they became confusing and counter intuitive.</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>Miscellaneous Stuff</title>
+
+ <para>There is a sequence of deltas for the
+ <literal>ports</literal> collection too, but interest has not
+ been all that high yet.</para>
+ </sect2>
+
+ <sect2 xml:id="mirrors-ctm">
+ <title>CTM Mirrors</title>
+
+ <para><link linkend="ctm">CTM</link>/FreeBSD is available via anonymous
+ FTP from the following mirror sites. If you choose to obtain <application>CTM</application> via
+ anonymous FTP, please try to use a site near you.</para>
+
+ <para>In case of problems, please contact the &a.ctm-users.name;
+ mailing list.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>California, Bay Area, official source</term>
+
+ <listitem>
+ <itemizedlist>
+ <listitem>
+ <para><uri xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/development/CTM/">ftp://ftp.FreeBSD.org/pub/FreeBSD/development/CTM/</uri></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>South Africa, backup server for old deltas</term>
+
+ <listitem>
+ <itemizedlist>
+ <listitem>
+ <para><uri xlink:href="ftp://ftp.za.FreeBSD.org/pub/FreeBSD/CTM/">ftp://ftp.za.FreeBSD.org/pub/FreeBSD/CTM/</uri></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Taiwan/R.O.C.(台灣/中華民國)</term>
+
+ <listitem>
+ <itemizedlist>
+ <listitem>
+ <para><uri xlink:href="ftp://ctm.tw.FreeBSD.org/pub/FreeBSD/development/CTM/">ftp://ctm.tw.FreeBSD.org/pub/FreeBSD/development/CTM/</uri></para>
+ </listitem>
+
+ <listitem>
+ <para><uri xlink:href="ftp://ctm2.tw.FreeBSD.org/pub/FreeBSD/development/CTM/">ftp://ctm2.tw.FreeBSD.org/pub/FreeBSD/development/CTM/</uri></para>
+ </listitem>
+
+ <listitem>
+ <para><uri xlink:href="ftp://ctm3.tw.FreeBSD.org/pub/FreeBSD/development/CTM/">ftp://ctm3.tw.FreeBSD.org/pub/FreeBSD/development/CTM/</uri></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>If you did not find a mirror near to you or the mirror is
+ incomplete, try to use a search engine such as
+ <link xlink:href="http://www.alltheweb.com/">alltheweb</link>.</para>
+ </sect2></sect1>
+
+ <sect1 xml:id="cvsup">
+ <title>Using CVSup</title>
+
+ <sect2 xml:id="cvsup-intro">
+ <title>CVSup 簡介</title>
+
+ <para><application>CVSup</application> is a software package for
+ distributing and updating source trees from a master CVS
+ repository on a remote server host. The FreeBSD sources are
+ maintained in a CVS repository on a central development machine
+ in California. With <application>CVSup</application>, FreeBSD
+ users can easily keep their own source trees up to date.</para>
+
+ <para><application>CVSup</application> uses the so-called
+ <emphasis>pull</emphasis> model of updating. Under the pull
+ model, each client asks the server for updates, if and when they
+ are wanted. The server waits passively for update requests from
+ its clients. Thus all updates are instigated by the client.
+ The server never sends unsolicited updates. Users must either
+ run the <application>CVSup</application> client manually to get
+ an update, or they must set up a <command>cron</command> job to
+ run it automatically on a regular basis.</para>
+
+ <para>The term <application>CVSup</application>, capitalized just
+ so, refers to the entire software package. Its main components
+ are the client <command>cvsup</command> which runs on each
+ user's machine, and the server <command>cvsupd</command> which
+ runs at each of the FreeBSD mirror sites.</para>
+
+ <para>As you read the FreeBSD documentation and mailing lists, you
+ may see references to <application>sup</application>.
+ <application>Sup</application> was the predecessor of
+ <application>CVSup</application>, and it served a similar
+ purpose. <application>CVSup</application> is used much in the
+ same way as sup and, in fact, uses configuration files which are
+ backward-compatible with <command>sup</command>'s.
+ <application>Sup</application> is no longer used in the FreeBSD
+ project, because <application>CVSup</application> is both faster
+ and more flexible.</para>
+ </sect2>
+
+ <sect2 xml:id="cvsup-install">
+ <title>Installation</title>
+
+ <para>The easiest way to install <application>CVSup</application>
+ is to use the precompiled <package>net/cvsup</package> package
+ from the FreeBSD <link linkend="ports">packages collection</link>.
+ If you prefer to build <application>CVSup</application> from
+ source, you can use the <package>net/cvsup</package>
+ port instead. But be forewarned: the
+ <package>net/cvsup</package> port depends on the Modula-3
+ system, which takes a substantial amount of time and
+ disk space to download and build.</para>
+
+ <note>
+ <para>If you are going to be using
+ <application>CVSup</application> on a machine which will not have
+ <application>&xfree86;</application> or <application>&xorg;</application> installed, such as a server, be
+ sure to use the port which does not include the
+ <application>CVSup</application> <acronym>GUI</acronym>,
+ <package>net/cvsup-without-gui</package>.</para>
+ </note>
+ </sect2>
+
+ <sect2 xml:id="cvsup-config">
+ <title>CVSup Configuration</title>
+
+ <para><application>CVSup</application>'s operation is controlled
+ by a configuration file called the <filename>supfile</filename>.
+ There are some sample <filename>supfiles</filename> in the
+ directory <link xlink:href="file://localhost/usr/share/examples/cvsup/"><filename>/usr/share/examples/cvsup/</filename></link>.</para>
+
+ <para>The information in a <filename>supfile</filename> answers
+ the following questions for <application>CVSup</application>:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="cvsup-config-files">Which files do you
+ want to receive?</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="cvsup-config-vers">Which versions of them
+ do you want?</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="cvsup-config-where">Where do you want to
+ get them from?</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="cvsup-config-dest">Where do you want to
+ put them on your own machine?</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="cvsup-config-status">Where do you want to
+ put your status files?</link></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>In the following sections, we will construct a typical
+ <filename>supfile</filename> by answering each of these
+ questions in turn. First, we describe the overall structure of
+ a <filename>supfile</filename>.</para>
+
+ <para>A <filename>supfile</filename> is a text file. Comments
+ begin with <literal>#</literal> and extend to the end of the
+ line. Lines that are blank and lines that contain only
+ comments are ignored.</para>
+
+ <para>Each remaining line describes a set of files that the user
+ wishes to receive. The line begins with the name of a
+ <quote>collection</quote>, a logical grouping of files defined by
+ the server. The name of the collection tells the server which
+ files you want. After the collection name come zero or more
+ fields, separated by white space. These fields answer the
+ questions listed above. There are two types of fields: flag
+ fields and value fields. A flag field consists of a keyword
+ standing alone, e.g., <literal>delete</literal> or
+ <literal>compress</literal>. A value field also begins with a
+ keyword, but the keyword is followed without intervening white
+ space by <literal>=</literal> and a second word. For example,
+ <literal>release=cvs</literal> is a value field.</para>
+
+ <para>A <filename>supfile</filename> typically specifies more than
+ one collection to receive. One way to structure a
+ <filename>supfile</filename> is to specify all of the relevant
+ fields explicitly for each collection. However, that tends to
+ make the <filename>supfile</filename> lines quite long, and it
+ is inconvenient because most fields are the same for all of the
+ collections in a <filename>supfile</filename>.
+ <application>CVSup</application> provides a defaulting mechanism
+ to avoid these problems. Lines beginning with the special
+ pseudo-collection name <literal>*default</literal> can be used
+ to set flags and values which will be used as defaults for the
+ subsequent collections in the <filename>supfile</filename>. A
+ default value can be overridden for an individual collection, by
+ specifying a different value with the collection itself.
+ Defaults can also be changed or augmented in mid-supfile by
+ additional <literal>*default</literal> lines.</para>
+
+ <para>With this background, we will now proceed to construct a
+ <filename>supfile</filename> for receiving and updating the main
+ source tree of <link linkend="current">FreeBSD-CURRENT</link>.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><anchor xml:id="cvsup-config-files"/>Which files do you want
+ to receive?</para>
+
+ <para>The files available via <application>CVSup</application>
+ are organized into named groups called
+ <quote>collections</quote>. The collections that are
+ available are described in the <link linkend="cvsup-collec">following section</link>. In this
+ example, we
+ wish to receive the entire main source tree for the FreeBSD
+ system. There is a single large collection
+ <literal>src-all</literal> which will give us all of that.
+ As a first step toward constructing our
+ <filename>supfile</filename>, we
+ simply list the collections, one per line (in this case,
+ only one line):</para>
+
+ <programlisting>src-all</programlisting>
+ </listitem>
+
+ <listitem>
+ <para><anchor xml:id="cvsup-config-vers"/>Which version(s) of them
+ do you want?</para>
+
+ <para>With <application>CVSup</application>, you can receive
+ virtually any version of the sources that ever existed.
+ That is possible because the
+ <application>cvsupd</application> server works directly from
+ the CVS repository, which contains all of the versions. You
+ specify which one of them you want using the
+ <literal>tag=</literal> and <option>date=</option> value
+ fields.</para>
+
+ <warning>
+ <para>Be very careful to specify any <literal>tag=</literal>
+ fields correctly. Some tags are valid only for certain
+ collections of files. If you specify an incorrect or
+ misspelled tag, <application>CVSup</application>
+ will delete files which you probably
+ do not want deleted. In particular, use <emphasis>only
+ </emphasis> <literal>tag=.</literal> for the
+ <literal>ports-*</literal> collections.</para>
+ </warning>
+
+ <para>The <literal>tag=</literal> field names a symbolic tag
+ in the repository. There are two kinds of tags, revision
+ tags and branch tags. A revision tag refers to a specific
+ revision. Its meaning stays the same from day to day. A
+ branch tag, on the other hand, refers to the latest revision
+ on a given line of development, at any given time. Because
+ a branch tag does not refer to a specific revision, it may
+ mean something different tomorrow than it means
+ today.</para>
+
+ <para><xref linkend="cvs-tags"/> contains branch tags that
+ users might be interested in. When specifying a tag in
+ <application>CVSup</application>'s configuration file, it
+ must be preceded with <literal>tag=</literal>
+ (<literal>RELENG_4</literal> will become
+ <literal>tag=RELENG_4</literal>).
+ Keep in mind that only the <literal>tag=.</literal> is
+ relevant for the Ports Collection.</para>
+
+ <warning>
+ <para>Be very careful to type the tag name exactly as shown.
+ <application>CVSup</application> cannot distinguish
+ between valid and invalid tags. If you misspell the tag,
+ <application>CVSup</application> will behave as though you
+ had specified a valid tag which happens to refer to no
+ files at all. It will delete your existing sources in
+ that case.</para>
+ </warning>
+
+ <para>When you specify a branch tag, you normally receive the
+ latest versions of the files on that line of development.
+ If you wish to receive some past version, you can do so by
+ specifying a date with the <option>date=</option> value
+ field. The &man.cvsup.1; manual page explains how to do
+ that.</para>
+
+ <para>For our example, we wish to receive FreeBSD-CURRENT. We
+ add this line at the beginning of our
+ <filename>supfile</filename>:</para>
+
+ <programlisting>*default tag=.</programlisting>
+
+ <para>There is an important special case that comes into play
+ if you specify neither a <literal>tag=</literal> field nor a
+ <literal>date=</literal> field. In that case, you receive
+ the actual RCS files directly from the server's CVS
+ repository, rather than receiving a particular version.
+ Developers generally prefer this mode of operation. By
+ maintaining a copy of the repository itself on their
+ systems, they gain the ability to browse the revision
+ histories and examine past versions of files. This gain is
+ achieved at a large cost in terms of disk space,
+ however.</para>
+ </listitem>
+
+ <listitem>
+ <para><anchor xml:id="cvsup-config-where"/>Where do you want to get
+ them from?</para>
+
+ <para>We use the <literal>host=</literal> field to tell
+ <command>cvsup</command> where to obtain its updates. Any
+ of the <link linkend="cvsup-mirrors">CVSup mirror
+ sites</link> will do, though you should try to select one
+ that is close to you in cyberspace. In this example we will
+ use a fictional FreeBSD distribution site,
+ <systemitem class="fqdomainname">cvsup99.FreeBSD.org</systemitem>:</para>
+
+ <programlisting>*default host=cvsup99.FreeBSD.org</programlisting>
+
+ <para>You will need to change the host to one that actually
+ exists before running <application>CVSup</application>.
+ On any particular run of
+ <command>cvsup</command>, you can override the host setting
+ on the command line, with <option>-h
+ <replaceable>hostname</replaceable></option>.</para>
+ </listitem>
+
+ <listitem>
+ <para><anchor xml:id="cvsup-config-dest"/>Where do you want to put
+ them on your own machine?</para>
+
+ <para>The <literal>prefix=</literal> field tells
+ <command>cvsup</command> where to put the files it receives.
+ In this example, we will put the source files directly into
+ our main source tree, <filename>/usr/src</filename>. The
+ <filename>src</filename> directory is already implicit in
+ the collections we have chosen to receive, so this is the
+ correct specification:</para>
+
+ <programlisting>*default prefix=/usr</programlisting>
+ </listitem>
+
+ <listitem>
+ <para><anchor xml:id="cvsup-config-status"/>Where should
+ <command>cvsup</command> maintain its status files?</para>
+
+ <para>The <application>CVSup</application> client maintains
+ certain status files in what
+ is called the <quote>base</quote> directory. These files
+ help <application>CVSup</application> to work more
+ efficiently, by keeping track of which updates you have
+ already received. We will use the standard base directory,
+ <filename>/var/db</filename>:</para>
+
+ <programlisting>*default base=/var/db</programlisting>
+
+ <para>If your base directory does not already exist, now would
+ be a good time to create it. The <command>cvsup</command>
+ client will refuse to run if the base directory does not
+ exist.</para>
+ </listitem>
+
+ <listitem>
+ <para>Miscellaneous <filename>supfile</filename>
+ settings:</para>
+
+ <para>There is one more line of boiler plate that normally
+ needs to be present in the
+ <filename>supfile</filename>:</para>
+
+ <programlisting>*default release=cvs delete use-rel-suffix compress</programlisting>
+
+ <para><literal>release=cvs</literal> indicates that the server
+ should get its information out of the main FreeBSD CVS
+ repository. This is virtually always the case, but there
+ are other possibilities which are beyond the scope of this
+ discussion.</para>
+
+ <para><literal>delete</literal> gives
+ <application>CVSup</application> permission to delete files.
+ You should always specify this, so that
+ <application>CVSup</application> can keep your source tree
+ fully up-to-date. <application>CVSup</application> is
+ careful to delete only those files for which it is
+ responsible. Any extra files you happen to have will be
+ left strictly alone.</para>
+
+ <para><literal>use-rel-suffix</literal> is ... arcane. If you
+ really want to know about it, see the &man.cvsup.1; manual
+ page. Otherwise, just specify it and do not worry about
+ it.</para>
+
+ <para><literal>compress</literal> enables the use of
+ gzip-style compression on the communication channel. If
+ your network link is T1 speed or faster, you probably should
+ not use compression. Otherwise, it helps
+ substantially.</para>
+ </listitem>
+
+ <listitem>
+ <para>Putting it all together:</para>
+
+ <para>Here is the entire <filename>supfile</filename> for our
+ example:</para>
+
+ <programlisting>*default tag=.
+*default host=cvsup99.FreeBSD.org
+*default prefix=/usr
+*default base=/var/db
+*default release=cvs delete use-rel-suffix compress
+
+src-all</programlisting>
+ </listitem>
+ </itemizedlist>
+ <sect3 xml:id="cvsup-refuse-file">
+ <title>The <filename>refuse</filename> File</title>
+
+ <para>As mentioned above, <application>CVSup</application> uses
+ a <emphasis>pull method</emphasis>. Basically, this means that
+ you connect to the <application>CVSup</application> server, and
+ it says, <quote>Here is what you can download from
+ me...</quote>, and your client responds <quote>OK, I will take
+ this, this, this, and this.</quote> In the default
+ configuration, the <application>CVSup</application> client will
+ take every file associated with the collection and tag you
+ chose in the configuration file. However, this is not always
+ what you want, especially if you are synching the <filename>doc</filename>, <filename>ports</filename>, or
+ <filename>www</filename> trees &mdash; most people cannot read four or five
+ languages, and therefore they do not need to download the
+ language-specific files. If you are
+ <application>CVSup</application>ing the Ports Collection, you
+ can get around this by specifying each collection individually
+ (e.g., <emphasis>ports-astrology</emphasis>,
+ <emphasis>ports-biology</emphasis>, etc instead of simply
+ saying <emphasis>ports-all</emphasis>). However, since the <filename>doc</filename>
+ and <filename>www</filename> trees do not have language-specific collections, you
+ must use one of <application>CVSup</application>'s many nifty
+ features: the <filename>refuse</filename> file.</para>
+
+ <para>The <filename>refuse</filename> file essentially tells
+ <application>CVSup</application> that it should not take every
+ single file from a collection; in other words, it tells the
+ client to <emphasis>refuse</emphasis> certain files from the
+ server. The <filename>refuse</filename> file can be found (or, if you do not yet
+ have one, should be placed) in
+ <filename>base/sup/</filename>.
+ <replaceable>base</replaceable> is defined in your <filename>supfile</filename>;
+ our defined <replaceable>base</replaceable> is
+ <filename>/var/db</filename>,
+ which means that by default the <filename>refuse</filename> file is
+ <filename>/var/db/sup/refuse</filename>.</para>
+
+ <para>The <filename>refuse</filename> file has a very simple format; it simply
+ contains the names of files or directories that you do not wish
+ to download. For example, if you cannot speak any languages other
+ than English and some German, and you do not feel the need to read
+ the German translation of documentation, you can put the following in your
+ <filename>refuse</filename> file:</para>
+
+ <screen>doc/bn_*
+doc/da_*
+doc/de_*
+doc/el_*
+doc/es_*
+doc/fr_*
+doc/it_*
+doc/ja_*
+doc/nl_*
+doc/no_*
+doc/pl_*
+doc/pt_*
+doc/ru_*
+doc/sr_*
+doc/tr_*
+doc/zh_*</screen>
+
+ <para>and so forth for the other languages (you can find the
+ full list by browsing the <link xlink:href="http://www.FreeBSD.org/cgi/cvsweb.cgi/">FreeBSD
+ CVS repository</link>).</para>
+
+ <para>With this very useful feature, those users who are on
+ slow links or pay by the minute for their Internet connection
+ will be able to save valuable time as they will no longer need
+ to download files that they will never use. For more
+ information on <filename>refuse</filename> files and other neat
+ features of <application>CVSup</application>, please view its
+ manual page.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Running <application>CVSup</application></title>
+
+ <para>You are now ready to try an update. The command line for
+ doing this is quite simple:</para>
+
+ <screen>&prompt.root; <userinput>cvsup supfile</userinput></screen>
+
+ <para>where <filename>supfile</filename>
+ is of course the name of the <filename>supfile</filename> you have just created.
+ Assuming you are running under X11, <command>cvsup</command>
+ will display a GUI window with some buttons to do the usual
+ things. Press the <guibutton>go</guibutton> button, and watch it
+ run.</para>
+
+ <para>Since you are updating your actual
+ <filename>/usr/src</filename> tree in this example, you will
+ need to run the program as <systemitem class="username">root</systemitem> so that
+ <command>cvsup</command> has the permissions it needs to update
+ your files. Having just created your configuration file, and
+ having never used this program before, that might
+ understandably make you nervous. There is an easy way to do a
+ trial run without touching your precious files. Just create an
+ empty directory somewhere convenient, and name it as an extra
+ argument on the command line:</para>
+
+ <screen>&prompt.root; <userinput>mkdir /var/tmp/dest</userinput>
+&prompt.root; <userinput>cvsup supfile /var/tmp/dest</userinput></screen>
+
+ <para>The directory you specify will be used as the destination
+ directory for all file updates.
+ <application>CVSup</application> will examine your usual files
+ in <filename>/usr/src</filename>, but it will not modify or
+ delete any of them. Any file updates will instead land in
+ <filename>/var/tmp/dest/usr/src</filename>.
+ <application>CVSup</application> will also leave its base
+ directory status files untouched when run this way. The new
+ versions of those files will be written into the specified
+ directory. As long as you have read access to
+ <filename>/usr/src</filename>, you do not even need to be
+ <systemitem class="username">root</systemitem> to perform this kind of trial run.</para>
+
+ <para>If you are not running X11 or if you just do not like GUIs,
+ you should add a couple of options to the command line when you
+ run <command>cvsup</command>:</para>
+
+ <screen>&prompt.root; <userinput>cvsup -g -L 2 supfile</userinput></screen>
+
+ <para>The <option>-g</option> tells
+ <application>CVSup</application> not to use its GUI. This is
+ automatic if you are not running X11, but otherwise you have to
+ specify it.</para>
+
+ <para>The <option>-L 2</option> tells
+ <application>CVSup</application> to print out the
+ details of all the file updates it is doing. There are three
+ levels of verbosity, from <option>-L 0</option> to
+ <option>-L 2</option>. The default is 0, which means total
+ silence except for error messages.</para>
+
+ <para>There are plenty of other options available. For a brief
+ list of them, type <command>cvsup -H</command>. For more
+ detailed descriptions, see the manual page.</para>
+
+ <para>Once you are satisfied with the way updates are working, you
+ can arrange for regular runs of <application>CVSup</application>
+ using &man.cron.8;.
+ Obviously, you should not let <application>CVSup</application>
+ use its GUI when running it from &man.cron.8;.</para>
+ </sect2>
+
+ <sect2 xml:id="cvsup-collec">
+ <title><application>CVSup</application> File Collections</title>
+
+ <para>The file collections available via
+ <application>CVSup</application> are organized hierarchically.
+ There are a few large collections, and they are divided into
+ smaller sub-collections. Receiving a large collection is
+ equivalent to receiving each of its sub-collections. The
+ hierarchical relationships among collections are reflected by
+ the use of indentation in the list below.</para>
+
+ <para>The most commonly used collections are
+ <literal>src-all</literal>, and
+ <literal>ports-all</literal>. The other collections are used
+ only by small groups of people for specialized purposes, and
+ some mirror sites may not carry all of them.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>cvs-all release=cvs</literal></term>
+
+ <listitem>
+ <para>The main FreeBSD CVS repository, including the
+ cryptography code.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>distrib release=cvs</literal></term>
+
+ <listitem>
+ <para>Files related to the distribution and mirroring
+ of FreeBSD.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>doc-all release=cvs</literal></term>
+ <listitem>
+ <para>Sources for the FreeBSD Handbook and other
+ documentation. This does not include files for
+ the FreeBSD web site.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-all release=cvs</literal></term>
+
+ <listitem>
+ <para>The FreeBSD Ports Collection.</para>
+
+ <important xml:id="cvsup-collec-pbase-warn">
+ <para>If you do not want to update the whole of
+ <literal>ports-all</literal> (the whole ports tree),
+ but use one of the subcollections listed below,
+ make sure that you <emphasis>always</emphasis> update
+ the <literal>ports-base</literal> subcollection!
+ Whenever something changes in the ports build
+ infrastructure represented by
+ <literal>ports-base</literal>, it is virtually certain
+ that those changes will be used by <quote>real</quote>
+ ports real soon. Thus, if you only update the
+ <quote>real</quote> ports and they use some of the new
+ features, there is a very high chance that their build
+ will fail with some mysterious error message. The
+ <emphasis>very first</emphasis> thing to do in this
+ case is to make sure that your
+ <literal>ports-base</literal> subcollection is up to
+ date.</para>
+ </important>
+
+ <important xml:id="cvsup-collec-index-warn">
+ <para>If you are going to be building your own local
+ copy of <filename>ports/INDEX</filename>, you
+ <emphasis>must</emphasis> accept
+ <literal>ports-all</literal> (the whole ports tree).
+ Building <filename>ports/INDEX</filename> with
+ a partial tree is not supported. See the
+ <link xlink:href="&url.books.faq;/applications.html#MAKE-INDEX">
+ FAQ</link>.</para>
+ </important>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>ports-accessibility
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Software to help disabled users.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-arabic
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Arabic language support.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-archivers
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Archiving tools.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-astro
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Astronomical ports.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-audio
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Sound support.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-base
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>The Ports Collection build infrastructure -
+ various files located in the
+ <filename>Mk/</filename> and
+ <filename>Tools/</filename> subdirectories of
+ <filename>/usr/ports</filename>.</para>
+
+ <note>
+ <para>Please see the <link linkend="cvsup-collec-pbase-warn">important
+ warning above</link>: you should
+ <emphasis>always</emphasis> update this
+ subcollection, whenever you update any part of
+ the FreeBSD Ports Collection!</para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-benchmarks
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Benchmarks.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-biology
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Biology.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-cad
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Computer aided design tools.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-chinese
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Chinese language support.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-comms
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Communication software.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-converters
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>character code converters.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-databases
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Databases.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-deskutils
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Things that used to be on the desktop
+ before computers were invented.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-devel
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Development utilities.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-dns
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>DNS related software.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-editors
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Editors.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-emulators
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Emulators for other operating
+ systems.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-finance
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Monetary, financial and related applications.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-ftp
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>FTP client and server utilities.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-games
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Games.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-german
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>German language support.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-graphics
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Graphics utilities.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-hebrew
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Hebrew language support.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-hungarian
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Hungarian language support.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-irc
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Internet Relay Chat utilities.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-japanese
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Japanese language support.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-java
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>&java; utilities.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-korean
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Korean language support.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-lang
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Programming languages.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-mail
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Mail software.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-math
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Numerical computation software.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-mbone
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>MBone applications.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-misc
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Miscellaneous utilities.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-multimedia
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Multimedia software.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-net
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Networking software.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-net-im
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Instant messaging software.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-net-mgmt
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Network management software.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-net-p2p
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Peer to peer networking.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-news
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>USENET news software.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-palm
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Software support for <trademark class="trade">Palm</trademark>
+ series.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-polish
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Polish language support.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-portuguese
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Portuguese language support.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-print
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Printing software.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-russian
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Russian language support.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-science
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Science.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-security
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Security utilities.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-shells
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Command line shells.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-sysutils
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>System utilities.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-textproc
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>text processing utilities (does not
+ include desktop publishing).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-ukrainian
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Ukrainian language support.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-vietnamese
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Vietnamese language support.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-www
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Software related to the World Wide
+ Web.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-x11
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Ports to support the X window
+ system.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-x11-clocks
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>X11 clocks.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-x11-fm
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>X11 file managers.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-x11-fonts
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>X11 fonts and font utilities.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-x11-toolkits
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>X11 toolkits.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-x11-servers
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>X11 servers.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-x11-themes
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>X11 themes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ports-x11-wm
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>X11 window managers.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>projects-all release=cvs</literal></term>
+ <listitem>
+ <para>Sources for the FreeBSD projects repository.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-all release=cvs</literal></term>
+
+ <listitem>
+ <para>The main FreeBSD sources, including the
+ cryptography code.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>src-base
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Miscellaneous files at the top of
+ <filename>/usr/src</filename>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-bin
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>User utilities that may be needed in
+ single-user mode
+ (<filename>/usr/src/bin</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-contrib
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Utilities and libraries from outside the
+ FreeBSD project, used relatively unmodified
+ (<filename>/usr/src/contrib</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-crypto release=cvs</literal></term>
+
+ <listitem>
+ <para>Cryptography utilities and libraries from
+ outside the FreeBSD project, used relatively
+ unmodified
+ (<filename>/usr/src/crypto</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-eBones release=cvs</literal></term>
+
+ <listitem>
+ <para>Kerberos and DES
+ (<filename>/usr/src/eBones</filename>). Not
+ used in current releases of FreeBSD.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-etc
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>System configuration files
+ (<filename>/usr/src/etc</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-games
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Games
+ (<filename>/usr/src/games</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-gnu
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Utilities covered by the GNU Public
+ License (<filename>/usr/src/gnu</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-include
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Header files
+ (<filename>/usr/src/include</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-kerberos5
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Kerberos5 security package
+ (<filename>/usr/src/kerberos5</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-kerberosIV
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>KerberosIV security package
+ (<filename>/usr/src/kerberosIV</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-lib
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Libraries
+ (<filename>/usr/src/lib</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-libexec
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>System programs normally executed by other
+ programs
+ (<filename>/usr/src/libexec</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-release
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Files required to produce a FreeBSD
+ release
+ (<filename>/usr/src/release</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-sbin release=cvs</literal></term>
+
+ <listitem>
+ <para>System utilities for single-user mode
+ (<filename>/usr/src/sbin</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-secure
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Cryptographic libraries and commands
+ (<filename>/usr/src/secure</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-share
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Files that can be shared across multiple
+ systems
+ (<filename>/usr/src/share</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-sys
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>The kernel
+ (<filename>/usr/src/sys</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-sys-crypto
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Kernel cryptography code
+ (<filename>/usr/src/sys/crypto</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-tools
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>Various tools for the maintenance of
+ FreeBSD
+ (<filename>/usr/src/tools</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-usrbin
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>User utilities
+ (<filename>/usr/src/usr.bin</filename>).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>src-usrsbin
+ release=cvs</literal></term>
+
+ <listitem>
+ <para>System utilities
+ (<filename>/usr/src/usr.sbin</filename>).</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>www release=cvs</literal></term>
+
+ <listitem>
+ <para>The sources for the FreeBSD WWW site.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>distrib release=self</literal></term>
+
+ <listitem>
+ <para>The <application>CVSup</application> server's own
+ configuration files. Used by <application>CVSup</application>
+ mirror sites.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>gnats release=current</literal></term>
+
+ <listitem>
+ <para>The GNATS bug-tracking database.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>mail-archive release=current</literal></term>
+
+ <listitem>
+ <para>FreeBSD mailing list archive.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>www release=current</literal></term>
+
+ <listitem>
+ <para>The pre-processed FreeBSD WWW site files (not the
+ source files). Used by WWW mirror sites.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>For More Information</title>
+
+ <para>For the <application>CVSup</application> FAQ and other
+ information about <application>CVSup</application>, see
+ <link xlink:href="http://www.polstra.com/projects/freeware/CVSup/">The
+ CVSup Home Page</link>.</para>
+
+ <para>Most FreeBSD-related discussion of
+ <application>CVSup</application> takes place on the
+ &a.hackers;. New versions of the software are announced there,
+ as well as on the &a.announce;.</para>
+
+ <para>Questions and bug reports should be addressed to the author
+ of the program at <email>cvsup-bugs@polstra.com</email>.</para>
+ </sect2>
+
+ <sect2 xml:id="cvsup-mirrors">
+ <title>CVSup Sites</title>
+
+ <para><link linkend="cvsup">CVSup</link> servers for FreeBSD are running
+ at the following sites:</para>
+
+ &chap.mirrors.cvsup.index.inc;
+
+ &chap.mirrors.lastmod.inc;
+
+ &chap.mirrors.cvsup.inc;
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="portsnap">
+ <title>Using Portsnap</title>
+
+ <sect2 xml:id="portsnap-intro">
+ <title>Portsnap 簡介</title>
+
+ <para><application>Portsnap</application> is a system for securely
+ distributing the &os; ports tree. Approximately once an hour,
+ a <quote>snapshot</quote> of the ports tree is generated,
+ repackaged, and cryptographically signed. The resulting files
+ are then distributed via HTTP.</para>
+
+ <para>Like <application>CVSup</application>,
+ <application>Portsnap</application> uses a
+ <emphasis>pull</emphasis> model of updating: The packaged and
+ signed ports trees are placed on a web server which waits
+ passively for clients to request files. Users must either run
+ &man.portsnap.8; manually to download updates
+ or set up a &man.cron.8; job to download updates
+ automatically on a regular basis.</para>
+
+ <para>For technical reasons, <application>Portsnap</application>
+ does not update the <quote>live</quote> ports tree in
+ <filename>/usr/ports/</filename> directly; instead, it works
+ via a compressed copy of the ports tree stored in
+ <filename>/var/db/portsnap/</filename> by default. This
+ compressed copy is then used to update the live ports tree.</para>
+
+ <note>
+ <para>If <application>Portsnap</application> is installed from
+ the &os; Ports Collection, then the default location for its
+ compressed snapshot will be <filename>/usr/local/portsnap/</filename>
+ instead of <filename>/var/db/portsnap/</filename>.</para>
+ </note>
+ </sect2>
+
+ <sect2 xml:id="portsnap-install">
+ <title>Installation</title>
+
+ <para>On &os; 6.0 and more recent versions,
+ <application>Portsnap</application> is contained in the &os;
+ base system. On older versions of &os;, it can be installed
+ using the <package>sysutils/portsnap</package>
+ port.</para>
+ </sect2>
+
+ <sect2 xml:id="portsnap-config">
+ <title>Portsnap Configuration</title>
+
+ <para><application>Portsnap</application>'s operation is controlled
+ by the <filename>/etc/portsnap.conf</filename> configuration
+ file. For most users, the default configuration file will
+ suffice; for more details, consult the &man.portsnap.conf.5;
+ manual page.</para>
+
+ <note>
+ <para>If <application>Portsnap</application> is installed from
+ the &os; Ports Collection, it will use the configuration file
+ <filename>/usr/local/etc/portsnap.conf</filename> instead of
+ <filename>/etc/portsnap.conf</filename>. This configuration
+ file is not created when the port is installed, but a sample
+ configuration file is distributed; to copy it into place, run
+ the following command:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/local/etc &amp;&amp; cp portsnap.conf.sample portsnap.conf</userinput></screen>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Running <application>Portsnap</application> for the First
+ Time</title>
+
+ <para>The first time &man.portsnap.8; is run,
+ it will need to download a compressed snapshot of the entire
+ ports tree into <filename>/var/db/portsnap/</filename> (or
+ <filename>/usr/local/portsnap/</filename> if
+ <application>Portsnap</application> was installed from the
+ Ports Collection). For the beginning of 2006 this is approximately a 41&nbsp;MB
+ download.</para>
+
+ <screen>&prompt.root; <userinput>portsnap fetch</userinput></screen>
+
+ <para>Once the compressed snapshot has been downloaded, a
+ <quote>live</quote> copy of the ports tree can be extracted into
+ <filename>/usr/ports/</filename>. This is necessary even if a
+ ports tree has already been created in that directory (e.g., by
+ using <application>CVSup</application>), since it establishes a
+ baseline from which <command>portsnap</command> can
+ determine which parts of the ports tree need to be updated
+ later.</para>
+
+ <screen>&prompt.root; <userinput>portsnap extract</userinput></screen>
+
+ <note>
+ <para>In the default installation
+ <filename>/usr/ports</filename> is not
+ created. If you run &os;&nbsp;6.0-RELEASE, it should be created before
+ <command>portsnap</command> is used. On more recent
+ versions of &os; or <application>Portsnap</application>,
+ this operation will be done automatically at first use
+ of the <command>portsnap</command> command.</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Updating the Ports Tree</title>
+
+ <para>After an initial compressed snapshot of the ports tree has
+ been downloaded and extracted into <filename>/usr/ports/</filename>,
+ updating the ports tree consists of two steps:
+ <emphasis>fetch</emphasis>ing updates to the compressed
+ snapshot, and using them to <emphasis>update</emphasis> the
+ live ports tree. These two steps can be specified to
+ <command>portsnap</command> as a single command:</para>
+
+ <screen>&prompt.root; <userinput>portsnap fetch update</userinput></screen>
+
+ <note>
+ <para>Some older versions of <command>portsnap</command>
+ do not support this syntax; if it fails, try instead the
+ following:</para>
+
+ <screen>&prompt.root; <userinput>portsnap fetch</userinput>
+&prompt.root; <userinput>portsnap update</userinput></screen>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Running Portsnap from cron</title>
+
+ <para>In order to avoid problems with <quote>flash crowds</quote>
+ accessing the <application>Portsnap</application> servers,
+ <command>portsnap fetch</command> will not run from
+ a &man.cron.8; job. Instead, a special
+ <command>portsnap cron</command> command exists, which
+ waits for a random duration up to 3600 seconds before fetching
+ updates.</para>
+
+ <para>In addition, it is strongly recommended that
+ <command>portsnap update</command> not be run from a
+ <command>cron</command> job, since it is liable to cause
+ major problems if it happens to run at the same time as a port
+ is being built or installed. However, it is safe to update
+ the ports' <filename>INDEX</filename> files, and this can be done by passing the
+ <option>-I</option> flag to
+ <command>portsnap</command>. (Obviously, if
+ <command>portsnap -I update</command> is run from
+ <command>cron</command>, then it will be necessary to run
+ <command>portsnap update</command> without the <option>-I</option>
+ flag at a later time in order to update the rest of the tree.)</para>
+
+ <para>Adding the following line to <filename>/etc/crontab</filename>
+ will cause <command>portsnap</command> to update its
+ compressed snapshot and the <filename>INDEX</filename> files in
+ <filename>/usr/ports/</filename>, and will send an email if any
+ installed ports are out of date:</para>
+
+ <programlisting>0 3 * * * root portsnap -I cron update &amp;&amp; pkg_version -vIL=</programlisting>
+
+ <note>
+ <para>If the system clock is not set to the local time zone,
+ please replace <literal>3</literal> with a random
+ value between 0 and 23, in order to spread the load on the
+ <application>Portsnap</application> servers more evenly.</para>
+ </note>
+ <note>
+ <para>Some older versions of <command>portsnap</command>
+ do not support listing multiple commands (e.g., <literal>cron update</literal>)
+ in the same invocation of <command>portsnap</command>. If
+ the line above fails, try replacing
+ <command>portsnap -I cron update</command> with
+ <command>portsnap cron &amp;&amp; portsnap -I update</command>.</para>
+ </note>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="cvs-tags">
+ <title>CVS Tags</title>
+
+ <para>When obtaining or updating sources using
+ <application>cvs</application> or
+ <application>CVSup</application>, a revision tag must be specified.
+ A revision tag refers to either a particular line of &os;
+ development, or a specific point in time. The first type are called
+ <quote>branch tags</quote>, and the second type are called
+ <quote>release tags</quote>.</para>
+
+ <sect2>
+ <title>Branch Tags</title>
+
+ <para>All of these, with the exception of <literal>HEAD</literal> (which
+ is always a valid tag), only apply to the <filename>src/</filename>
+ tree. The <filename>ports/</filename>, <filename>doc/</filename>, and
+ <filename>www/</filename> trees are not branched.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>HEAD</term>
+
+ <listitem>
+ <para>Symbolic name for the main line, or FreeBSD-CURRENT.
+ Also the default when no revision is specified.</para>
+
+ <para>In <application>CVSup</application>, this tag is represented
+ by a <literal>.</literal> (not punctuation, but a literal
+ <literal>.</literal> character).</para>
+
+ <note>
+ <para>In CVS, this is the default when no revision tag is
+ specified. It is usually <emphasis>not</emphasis>
+ a good idea to checkout or update to CURRENT sources
+ on a STABLE machine, unless that is your intent.</para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_6</term>
+
+ <listitem>
+ <para>The line of development for FreeBSD-6.X, also known
+ as FreeBSD 6-STABLE</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_6_1</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-6.1, used only for
+ security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_6_0</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-6.0, used only for
+ security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_5</term>
+
+ <listitem>
+ <para>The line of development for FreeBSD-5.X, also known
+ as FreeBSD 5-STABLE.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_5_5</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-5.5, used only
+ for security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_5_4</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-5.4, used only
+ for security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_5_3</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-5.3, used only
+ for security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_5_2</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-5.2 and FreeBSD-5.2.1, used only
+ for security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_5_1</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-5.1, used only
+ for security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_5_0</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-5.0, used only
+ for security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4</term>
+
+ <listitem>
+ <para>The line of development for FreeBSD-4.X, also known
+ as FreeBSD 4-STABLE.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_11</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-4.11, used only
+ for security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_10</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-4.10, used only
+ for security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_9</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-4.9, used only
+ for security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_8</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-4.8, used only
+ for security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_7</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-4.7, used only
+ for security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_6</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-4.6 and FreeBSD-4.6.2,
+ used only for security advisories and other
+ critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_5</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-4.5, used only
+ for security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_4</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-4.4, used only
+ for security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_3</term>
+
+ <listitem>
+ <para>The release branch for FreeBSD-4.3, used only
+ for security advisories and other critical fixes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_3</term>
+
+ <listitem>
+ <para>The line of development for FreeBSD-3.X, also known
+ as 3.X-STABLE.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_2_2</term>
+
+ <listitem>
+ <para>The line of development for FreeBSD-2.2.X, also known
+ as 2.2-STABLE. This branch is mostly obsolete.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Release Tags</title>
+
+ <para>These tags refer to a specific point in time when a particular
+ version of &os; was released. The release engineering process is
+ documented in more detail by the
+ <link xlink:href="&url.base;/releng/">Release Engineering
+ Information</link> and
+ <link xlink:href="&url.articles.releng;/release-proc.html">Release
+ Process</link> documents.
+ The <filename>src</filename> tree uses tag names that
+ start with <literal>RELENG_</literal> tags.
+ The <filename>ports</filename> and
+ <filename>doc</filename> trees use tags whose names
+ begin with <literal>RELEASE</literal> tags.
+ Finally, the <filename>www</filename> tree is not
+ tagged with any special name for releases.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>RELENG_6_1_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 6.1</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_6_0_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 6.0</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_5_5_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 5.5</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_5_4_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 5.4</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_11_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.11</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_5_3_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 5.3</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_10_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.10</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_5_2_1_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 5.2.1</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_5_2_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 5.2</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_9_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.9</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_5_1_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 5.1</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_8_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.8</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_5_0_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 5.0</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_7_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.7</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_6_2_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.6.2</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_6_1_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.6.1</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_6_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.6</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_5_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.5</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_4_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.4</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_3_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.3</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_2_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.2</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_1_1_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.1.1</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_1_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.1</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_4_0_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD 4.0</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_3_5_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD-3.5</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_3_4_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD-3.4</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_3_3_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD-3.3</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_3_2_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD-3.2</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_3_1_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD-3.1</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_3_0_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD-3.0</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_2_2_8_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD-2.2.8</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_2_2_7_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD-2.2.7</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_2_2_6_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD-2.2.6</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_2_2_5_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD-2.2.5</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_2_2_2_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD-2.2.2</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_2_2_1_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD-2.2.1</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RELENG_2_2_0_RELEASE</term>
+
+ <listitem>
+ <para>FreeBSD-2.2.0</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="mirrors-afs">
+ <title>AFS Sites</title>
+
+ <para>AFS servers for FreeBSD are running at the following sites:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Sweden</term>
+
+ <listitem>
+ <para>The path to the files are:
+ <filename>/afs/stacken.kth.se/ftp/pub/FreeBSD/</filename></para>
+
+ <programlisting>stacken.kth.se # Stacken Computer Club, KTH, Sweden
+130.237.234.43 #hot.stacken.kth.se
+130.237.237.230 #fishburger.stacken.kth.se
+130.237.234.3 #milko.stacken.kth.se</programlisting>
+
+ <para>Maintainer <email>ftp@stacken.kth.se</email></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1 xml:id="mirrors-rsync">
+ <title>rsync Sites</title>
+
+ <para>The following sites make FreeBSD available through the rsync
+ protocol. The <application>rsync</application> utility works in
+ much the same way as the &man.rcp.1; command,
+ but has more options and uses the rsync remote-update protocol
+ which transfers only the differences between two sets of files,
+ thus greatly speeding up the synchronization over the network.
+ This is most useful if you are a mirror site for the
+ FreeBSD FTP server, or the CVS repository. The
+ <application>rsync</application> suite is available for many
+ operating systems, on FreeBSD, see the
+ <package>net/rsync</package>
+ port or use the package.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Czech Republic</term>
+
+ <listitem>
+ <para>rsync://ftp.cz.FreeBSD.org/</para>
+
+ <para>Available collections:</para>
+ <itemizedlist>
+ <listitem><para>ftp: A partial mirror of the FreeBSD FTP
+ server.</para></listitem>
+ <listitem><para>FreeBSD: A full mirror of the FreeBSD FTP
+ server.</para></listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Germany</term>
+
+ <listitem>
+ <para>rsync://grappa.unix-ag.uni-kl.de/</para>
+
+ <para>Available collections:</para>
+ <itemizedlist>
+ <listitem><para>freebsd-cvs: The full FreeBSD CVS
+ repository.</para></listitem>
+ </itemizedlist>
+ <para>This machine also mirrors the CVS repositories of the
+ NetBSD and the OpenBSD projects, among others.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Netherlands</term>
+
+ <listitem>
+ <para>rsync://ftp.nl.FreeBSD.org/</para>
+
+ <para>Available collections:</para>
+ <itemizedlist>
+ <listitem><para>vol/4/freebsd-core: A full mirror of the
+ FreeBSD FTP server.</para></listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>United Kingdom</term>
+
+ <listitem>
+ <para>rsync://rsync.mirror.ac.uk/</para>
+
+ <para>Available collections:</para>
+ <itemizedlist>
+ <listitem><para>ftp.FreeBSD.org: A full mirror of the
+ FreeBSD FTP server.</para></listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>United States of America</term>
+
+ <listitem>
+ <para>rsync://ftp-master.FreeBSD.org/</para>
+
+ <para>This server may only be used by FreeBSD primary mirror
+ sites.</para>
+ <para>Available collections:</para>
+ <itemizedlist>
+ <listitem><para>FreeBSD: The master archive of the FreeBSD
+ FTP server.</para></listitem>
+ <listitem><para>acl: The FreeBSD master ACL
+ list.</para></listitem>
+ </itemizedlist>
+
+ <para>rsync://ftp13.FreeBSD.org/</para>
+
+ <para>Available collections:</para>
+ <itemizedlist>
+ <listitem><para>FreeBSD: A full mirror of the FreeBSD FTP
+ server.</para></listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+</appendix>
diff --git a/zh_TW.UTF-8/books/handbook/multimedia/Makefile b/zh_TW.UTF-8/books/handbook/multimedia/Makefile
new file mode 100644
index 0000000000..d645e14d83
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/multimedia/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= multimedia/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/multimedia/chapter.xml b/zh_TW.UTF-8/books/handbook/multimedia/chapter.xml
new file mode 100644
index 0000000000..b20cb3a8ea
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/multimedia/chapter.xml
@@ -0,0 +1,1741 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.113
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="multimedia">
+ <info><title>多媒體影音娛樂(Multimedia)</title>
+ <authorgroup>
+ <author><personname><firstname>Ross</firstname><surname>Lippert</surname></personname><contrib>Edited by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <sect1 xml:id="multimedia-synopsis">
+ <title>概述</title>
+
+ <para>FreeBSD 廣泛地支援各種音效卡, 讓您可以享受來自電腦上的高傳真音質(Hi-Fi),
+ 此外還包括了錄製和播放 MPEG Audio Layer 3 (MP3)、 WAV、 以及 Ogg Vorbis
+ 等許多種格式聲音的能力。同時 FreeBSD Ports Collection 也包括了許多的應用程式,
+ 讓您可以錄音、編修音效以及控制 MIDI 配備。</para>
+
+ <para>要是喜歡動手嘗試不同的體驗, FreeBSD 也能播放一般的視訊檔和 DVD。
+ 編碼、轉換和播放視訊的程式比起處理聲音的程式略少一些。例如, 在撰寫這章時,
+ FreeBSD Ports Collection 中還沒有類似 <package>audio/sox</package> 那樣好用的編碼工具,能夠用來轉換不同的格式。
+ 不過,這個領域的軟體研發進展是相當迅速的。</para>
+
+ <para>本章將介紹設定音效卡的必要步驟。先前介紹到的 X11
+ (<xref linkend="x11"/>) 安裝和設定裡,已經講到了顯示卡的部份,
+ 但要想有更好的播放效果, 仍需要一些細部調整。</para>
+
+ <para>讀完這章,您將了解:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>如何設定系統,以正確識別音效卡。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何運用樣本程式,以測試音效卡是否正常運作。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何解決音效卡的設定問題。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何播放、錄製 MP3 及其他聲音檔案格式。</para>
+ </listitem>
+
+ <listitem>
+ <para>X server 是如何支援顯示卡。</para>
+ </listitem>
+
+ <listitem>
+ <para>Ports Collections 內有哪些好用的影像播放、錄製軟體。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何播放 DVD 的 <filename>.mpg</filename> 及
+ <filename>.avi</filename> 檔</para>
+ </listitem>
+
+ <listitem>
+ <para>如何從 CD 和 DVD 中擷取(rip)檔案。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何設定電視卡</para>
+ </listitem>
+
+ <listitem>
+ <para>如何設定掃描器</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>在閱讀這章之前,您應當了解:</para>
+
+ <itemizedlist>
+ <listitem><para>知道如何設定、安裝新的 kernel (<xref linkend="kernelconfig"/>)。</para></listitem>
+ </itemizedlist>
+
+ <warning>
+ <para>如果要用 &man.mount.8; 指令來 mount 音樂光碟的話,通常會發生錯誤,
+ 甚至導致 <emphasis>kernel panic</emphasis>。 這是因為音樂光碟是特殊編碼,而非一般的 ISO 檔案系統之故。</para>
+ </warning>
+
+ </sect1>
+
+ <sect1 xml:id="sound-setup">
+ <info><title>設定音效卡</title>
+ <authorgroup>
+ <author><personname><firstname>Moses</firstname><surname>Moore</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Marc</firstname><surname>Fonvieille</surname></personname><contrib>加強 &os;&nbsp;5.X 的內容:</contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect2 xml:id="sound-device">
+ <title>設定系統</title>
+
+ <indexterm><primary>PCI</primary></indexterm>
+ <indexterm><primary>ISA</primary></indexterm>
+ <indexterm><primary>sound cards</primary></indexterm>
+ <para>開始設定之前,必須先知道你的音效卡型號、晶片為何,以及是 PCI 或 ISA 規格。
+ FreeBSD 有支援許多種的 PCI、ISA 音效卡,請檢查支援的音效硬體表 <link xlink:href="&rel.current.hardware;">Hardware Notes</link>,以確認你的音效卡是否支援。
+ 本文也會提到相對應該卡的驅動程式。</para>
+
+ <indexterm>
+ <primary>kernel</primary>
+ <secondary>configuration</secondary>
+ </indexterm>
+
+ <para>要使用音效卡,必須要載入正確的驅動程式才行。有兩種方式都可以完成這動作,
+ 最簡單方式就是以 &man.kldload.8; 來輕鬆載入 kernel 動態模組(module),
+ 像是下列指令:</para>
+
+ <screen>&prompt.root; <userinput>kldload snd_emu10k1</userinput></screen>
+
+ <para>或者把相關驅動程式加到
+ <filename>/boot/loader.conf</filename> 檔,像是:</para>
+
+ <programlisting>snd_emu10k1_load="YES"</programlisting>
+
+ <para>上面例子是給 Creative &soundblaster; Live! 音效卡使用的。
+ 其他可用的音效卡驅動程式模組,可參考
+ <filename>/boot/defaults/loader.conf</filename> 範例。
+ 若不確定到底該用哪一種驅動程式,那麼可以試試載入 <filename>snd_driver</filename>
+ 模組看看:</para>
+
+ <screen>&prompt.root; <userinput>kldload snd_driver</userinput></screen>
+
+ <para>This is a metadriver loading the most common device drivers
+ at once. This speeds up the search for the correct driver. It
+ is also possible to load all sound drivers via the
+ <filename>/boot/loader.conf</filename> facility.</para>
+
+ <para>If you wish to find out the driver selected for your
+ soundcard after loading the <filename>snd_driver</filename>
+ metadriver, you may check the <filename>/dev/sndstat</filename>
+ file with the <command>cat /dev/sndstat</command>
+ command.</para>
+
+ <note>
+ <para>Under &os;&nbsp;4.X, to load all sound drivers, you have
+ to load the <filename>snd</filename> module instead of
+ <filename>snd_driver</filename>.</para>
+ </note>
+
+ <para>A second method is to statically
+ compile in support for your sound card in your kernel. The
+ section below provides the information you need to add support
+ for your hardware in this manner. For more information about
+ recompiling your kernel, please see <xref linkend="kernelconfig"/>.</para>
+
+ <sect3>
+ <title>Configuring a Custom Kernel with Sound Support</title>
+
+ <para>The first thing to do is adding the generic audio driver
+ &man.sound.4; to the kernel, for that you will need to
+ add the following line to the kernel configuration file:</para>
+
+ <programlisting>device sound</programlisting>
+
+ <para>Under &os;&nbsp;4.X, you would use the following
+ line:</para>
+
+ <programlisting>device pcm</programlisting>
+
+ <para>Then we have to add the support for our sound card.
+ Therefore, we need to know which driver supports the card.
+ Check the supported audio devices list of the <link xlink:href="&rel.current.hardware;">Hardware Notes</link>, to
+ determine the correct driver for your sound card. For
+ example, a Creative &soundblaster; Live! sound card is
+ supported by the &man.snd.emu10k1.4; driver. To add the support
+ for this card, use the following:</para>
+
+ <programlisting>device snd_emu10k1</programlisting>
+
+ <para>Be sure to read the manual page of the driver for the
+ syntax to use. Information regarding the syntax of sound
+ drivers in the kernel configuration can also be found in the
+ <filename>/usr/src/sys/conf/NOTES</filename> file
+ (<filename>/usr/src/sys/i386/conf/LINT</filename> for
+ &os;&nbsp;4.X).</para>
+
+ <para>Non-PnP ISA cards may require you to provide the kernel
+ with information on the sound card settings (IRQ, I/O port,
+ etc). This is done via the
+ <filename>/boot/device.hints</filename> file. At system boot,
+ the &man.loader.8; will read this file and pass the settings
+ to the kernel. For example, an old
+ Creative &soundblaster; 16 ISA non-PnP card will use the
+ &man.snd.sbc.4; driver in conjunction with snd_sb16(4). For this card the following lines have to be added to
+ the kernel configuration file:</para>
+
+ <programlisting>device snd_sbc
+device snd_sb16</programlisting>
+
+ <para>as well as the following in
+ <filename>/boot/device.hints</filename>:</para>
+
+ <programlisting>hint.sbc.0.at="isa"
+hint.sbc.0.port="0x220"
+hint.sbc.0.irq="5"
+hint.sbc.0.drq="1"
+hint.sbc.0.flags="0x15"</programlisting>
+
+ <para>In this case, the card uses the <literal>0x220</literal>
+ I/O port and the IRQ <literal>5</literal>.</para>
+
+ <para>The syntax used in the
+ <filename>/boot/device.hints</filename> file is covered in the
+ sound driver manual page. On &os;&nbsp;4.X, these settings
+ are directly written in the kernel configuration file. In the
+ case of our ISA card, we would only use this line:</para>
+
+ <programlisting>device sbc0 at isa? port 0x220 irq 5 drq 1 flags 0x15</programlisting>
+
+ <para>The settings shown above are the defaults. In some
+ cases, you may need to change the IRQ or the other settings to
+ match your card. See the &man.snd.sbc.4; manual page for more
+ information.</para>
+
+ <note>
+ <para>Under &os;&nbsp;4.X, some systems with built-in
+ motherboard sound devices may require the following option in
+ the kernel configuration:</para>
+
+ <programlisting>options PNPBIOS</programlisting>
+ </note>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="sound-testing">
+ <title>Testing the Sound Card</title>
+
+ <para>After rebooting with the modified kernel, or after loading
+ the required module, the sound card should appear in your system
+ message buffer (&man.dmesg.8;) as something like:</para>
+
+ <screen>pcm0: &lt;Intel ICH3 (82801CA)&gt; port 0xdc80-0xdcbf,0xd800-0xd8ff irq 5 at device 31.5 on pci0
+pcm0: [GIANT-LOCKED]
+pcm0: &lt;Cirrus Logic CS4205 AC97 Codec&gt;</screen>
+
+ <para>The status of the sound card may be checked via the
+ <filename>/dev/sndstat</filename> file:</para>
+
+ <screen>&prompt.root; <userinput>cat /dev/sndstat</userinput>
+FreeBSD Audio Driver (newpcm)
+Installed devices:
+pcm0: &lt;Intel ICH3 (82801CA)&gt; at io 0xd800, 0xdc80 irq 5 bufsz 16384
+kld snd_ich (1p/2r/0v channels duplex default)</screen>
+
+ <para>The output from your system may vary. If no
+ <filename>pcm</filename> devices show up, go back and review
+ what was done earlier. Go through your kernel
+ configuration file again and make sure the correct
+ device is chosen. Common problems are listed in <xref linkend="troubleshooting"/>.</para>
+
+ <para>If all goes well, you should now have a functioning sound
+ card. If your CD-ROM or DVD-ROM drive is properly coupled to
+ your sound card, you can put a CD in the drive and play it
+ with &man.cdcontrol.1;:</para>
+
+ <screen>&prompt.user; <userinput>cdcontrol -f /dev/acd0 play 1</userinput></screen>
+
+ <para>Various applications, such as <package>audio/workman</package> can provide a friendlier
+ interface. You may want to install an application such as
+ <package>audio/mpg123</package> to listen to
+ MP3 audio files. A quick way to test the card is sending data
+ to the <filename>/dev/dsp</filename>, like this:</para>
+
+ <screen>&prompt.user; <userinput>cat filename &gt; /dev/dsp</userinput></screen>
+
+ <para>where <replaceable>filename</replaceable> can be any file.
+ This command line should produce some noise, confirming the
+ sound card is actually working.</para>
+
+ <note>
+ <para>&os;&nbsp;4.X users need to create the sound card device
+ nodes before being able to use it. If the card showed up in
+ message buffer as <filename>pcm0</filename>, you will have
+ to run the following as <systemitem class="username">root</systemitem>:</para>
+
+ <screen>&prompt.root; <userinput>cd /dev</userinput>
+&prompt.root; <userinput>sh MAKEDEV snd0</userinput></screen>
+
+ <para>If the card detection returned <filename>pcm1</filename>,
+ follow the same steps as shown above, replacing
+ <filename>snd0</filename> with
+ <filename>snd1</filename>.</para>
+
+ <para><command>MAKEDEV</command> will create a group of device
+ nodes that will be used by the different sound related
+ applications.</para>
+ </note>
+
+ <para>Sound card mixer levels can be changed via the &man.mixer.8;
+ command. More details can be found in the &man.mixer.8; manual
+ page.</para>
+
+ <sect3 xml:id="troubleshooting">
+ <title>Common Problems</title>
+
+ <indexterm><primary>device nodes</primary></indexterm>
+ <indexterm><primary>I/O port</primary></indexterm>
+ <indexterm><primary>IRQ</primary></indexterm>
+ <indexterm><primary>DSP</primary></indexterm>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Error</entry>
+ <entry>Solution</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><errorname>unsupported subdevice XX</errorname></entry>
+ <entry><para>One or more of the device nodes was not created
+ correctly. Repeat the steps above.</para></entry>
+ </row>
+
+ <row>
+ <entry><errorname>sb_dspwr(XX) timed out</errorname></entry>
+ <entry><para>The I/O port is not set correctly.</para></entry>
+ </row>
+
+ <row>
+ <entry><errorname>bad irq XX</errorname></entry>
+ <entry><para>The IRQ is set incorrectly. Make sure that
+ the set IRQ and the sound IRQ are the same.</para></entry>
+ </row>
+
+ <row>
+ <entry><errorname>xxx: gus pcm not attached, out of memory</errorname></entry>
+ <entry><para>There is not enough available memory to use
+ the device.</para></entry>
+ </row>
+
+ <row>
+ <entry><errorname>xxx: can't open /dev/dsp!</errorname></entry>
+ <entry><para>Check with <command>fstat | grep dsp</command>
+ if another application is holding the device open.
+ Noteworthy troublemakers are <application>esound</application> and <application>KDE</application>'s sound
+ support.</para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="sound-multiple-sources">
+ <info><title>Utilizing Multiple Sound Sources</title>
+ <authorgroup>
+ <author><personname><firstname>Munish</firstname><surname>Chopra</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <para>It is often desirable to have multiple sources of sound that
+ are able to play simultaneously, such as when
+ <application>esound</application> or
+ <application>artsd</application> do not support sharing of the
+ sound device with a certain application.</para>
+
+ <para>FreeBSD lets you do this through <emphasis>Virtual Sound
+ Channels</emphasis>, which can be set with the &man.sysctl.8;
+ facility. Virtual channels allow you to multiplex your sound
+ card's playback channels by mixing sound in the kernel.</para>
+
+ <para>To set the number of virtual channels, there are two sysctl
+ knobs which, if you are the <systemitem class="username">root</systemitem> user, can
+ be set like this:</para>
+ <screen>&prompt.root; <userinput>sysctl hw.snd.pcm0.vchans=4</userinput>
+&prompt.root; <userinput>sysctl hw.snd.maxautovchans=4</userinput></screen>
+
+ <para>The above example allocates four virtual channels, which is a
+ practical number for everyday use. <varname>hw.snd.pcm0.vchans</varname>
+ is the number of virtual channels <filename>pcm0</filename> has, and is configurable
+ once a device has been attached.
+ <literal>hw.snd.maxautovchans</literal> is the number of virtual channels
+ a new audio device is given when it is attached using
+ &man.kldload.8;. Since the <filename>pcm</filename> module
+ can be loaded independently of the hardware drivers,
+ <varname>hw.snd.maxautovchans</varname> can store how many
+ virtual channels any devices which are attached later will be
+ given.</para>
+
+ <note>
+ <para>You cannot change the number of virtual channels for a
+ device while it is in use. First close any programs using the
+ device, such as music players or sound daemons.</para>
+ </note>
+
+ <para>If you are not using &man.devfs.5;, you will have to point
+ your applications at
+ <filename>/dev/dsp0</filename>.<replaceable>x</replaceable>,
+ where <replaceable>x</replaceable> is 0 to 3 if
+ <varname>hw.snd.pcm.0.vchans</varname> is set to 4 as in the
+ above example. On a system using &man.devfs.5;, the above will
+ automatically be allocated transparently to the user.</para>
+ </sect2>
+
+ <sect2>
+ <info><title>設定預設(Mixer Channel)的音量大小</title>
+ <authorgroup>
+ <author><personname><firstname>Josef</firstname><surname>El-Rayes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <note>
+ <para>本功能只有在 &os; 5.3-RELEASE 及之後版本才有支援。</para>
+ </note>
+
+ <para>The default values for the different mixer channels are
+ hardcoded in the sourcecode of the &man.pcm.4; driver. There are
+ a lot of different applications and daemons that allow
+ you to set values for the mixer they remember and set
+ each time they are started, but this is not a clean
+ solution, we want to have default values at the driver
+ level. This is accomplished by defining the appropriate
+ values in <filename>/boot/device.hints</filename>. E.g.:</para>
+<programlisting>hint.pcm.0.vol="100"</programlisting>
+
+ <para>This will set the volume channel to a default value of
+ 100, when the &man.pcm.4; module is loaded.</para>
+ </sect2>
+</sect1>
+
+ <sect1 xml:id="sound-mp3">
+ <info><title>MP3 音樂</title>
+ <authorgroup>
+ <author><personname><firstname>Chern</firstname><surname>Lee</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <para>MP3 (MPEG Layer 3 Audio) accomplishes near CD-quality sound,
+ leaving no reason to let your FreeBSD workstation fall short of
+ its offerings.</para>
+
+ <sect2 xml:id="mp3-players">
+ <title>MP3 Players</title>
+
+ <para>By far, the most popular X11 MP3 player is
+ <application>XMMS</application> (X Multimedia System).
+ <application>Winamp</application>
+ skins can be used with <application>XMMS</application> since the
+ GUI is almost identical to that of Nullsoft's
+ <application>Winamp</application>.
+ <application>XMMS</application> also has native plug-in
+ support.</para>
+
+ <para><application>XMMS</application> can be installed from the
+ <package>multimedia/xmms</package> port or package.</para>
+
+ <para><application>XMMS'</application> interface is intuitive,
+ with a playlist, graphic equalizer, and more. Those familiar
+ with <application>Winamp</application> will find
+ <application>XMMS</application> simple to use.</para>
+
+ <para>The <package>audio/mpg123</package> port is an alternative,
+ command-line MP3 player.</para>
+
+ <para><application>mpg123</application> can be run by specifying
+ the sound device and the MP3 file on the command line, as
+ shown below:</para>
+
+ <screen>&prompt.root; <userinput>mpg123 -a /dev/dsp1.0 Foobar-GreatestHits.mp3</userinput>
+High Performance MPEG 1.0/2.0/2.5 Audio Player for Layer 1, 2 and 3.
+Version 0.59r (1999/Jun/15). Written and copyrights by Michael Hipp.
+Uses code from various people. See 'README' for more!
+THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN RISK!
+
+
+
+
+
+Playing MPEG stream from Foobar-GreatestHits.mp3 ...
+MPEG 1.0 layer III, 128 kbit/s, 44100 Hz joint-stereo
+</screen>
+
+ <para><literal>/dev/dsp1.0</literal> should be replaced with the
+ <filename>dsp</filename> device entry on your system.</para>
+
+ </sect2>
+
+ <sect2 xml:id="rip-cd">
+ <title>Ripping CD Audio Tracks</title>
+
+ <para>Before encoding a CD or CD track to MP3, the audio data on
+ the CD must be ripped onto the hard drive. This is done by
+ copying the raw CDDA (CD Digital Audio) data to WAV
+ files.</para>
+
+ <para>The <command>cdda2wav</command> tool, which is a part of
+ the <package>sysutils/cdrtools</package>
+ suite, is used for ripping audio information from CDs and the
+ information associated with them.</para>
+
+ <para>With the audio CD in the drive, the following command can
+ be issued (as <systemitem class="username">root</systemitem>) to rip an entire CD
+ into individual (per track) WAV files:</para>
+
+ <screen>&prompt.root; <userinput>cdda2wav -D 0,1,0 -B</userinput></screen>
+
+ <para><application>cdda2wav</application> will support
+ ATAPI (IDE) CDROM drives. To rip from an IDE drive, specify
+ the device name in place of the SCSI unit numbers. For
+ example, to rip track 7 from an IDE drive:</para>
+
+ <screen>&prompt.root; <userinput>cdda2wav -D /dev/acd0a -t 7</userinput></screen>
+
+ <para>The <option>-D <replaceable>0,1,0</replaceable></option>
+ indicates the SCSI device <filename>0,1,0</filename>,
+ which corresponds to the output of <command>cdrecord
+ -scanbus</command>.</para>
+
+ <para>To rip individual tracks, make use of the
+ <option>-t</option> option as shown:</para>
+
+ <screen>&prompt.root; <userinput>cdda2wav -D 0,1,0 -t 7</userinput></screen>
+
+ <para>This example rips track seven of the audio CDROM. To rip
+ a range of tracks, for example, track one to seven, specify a
+ range:</para>
+
+ <screen>&prompt.root; <userinput>cdda2wav -D 0,1,0 -t 1+7</userinput></screen>
+
+ <para>The utility &man.dd.1; can also be used to extract audio tracks
+ on ATAPI drives, read <xref linkend="duplicating-audiocds"/>
+ for more information on that possibility.</para>
+
+ </sect2>
+
+ <sect2 xml:id="mp3-encoding">
+ <title>Encoding MP3s</title>
+
+ <para>Nowadays, the mp3 encoder of choice is
+ <application>lame</application>.
+ <application>Lame</application> can be found at
+ <package>audio/lame</package> in the ports tree.</para>
+
+ <para>Using the ripped WAV files, the following command will
+ convert <filename>audio01.wav</filename> to
+ <filename>audio01.mp3</filename>:</para>
+
+ <screen>&prompt.root; <userinput>lame -h -b 128 \
+--tt "Foo Song Title" \
+--ta "FooBar Artist" \
+--tl "FooBar Album" \
+--ty "2001" \
+--tc "Ripped and encoded by Foo" \
+--tg "Genre" \
+audio01.wav audio01.mp3</userinput></screen>
+
+ <para>128&nbsp;kbits seems to be the standard MP3 bitrate in use.
+ Many enjoy the higher quality 160, or 192. The higher the
+ bitrate, the more disk space the resulting MP3 will
+ consume--but the quality will be higher. The
+ <option>-h</option> option turns on the <quote>higher quality
+ but a little slower</quote> mode. The options beginning with
+ <option>--t</option> indicate ID3 tags, which usually contain
+ song information, to be embedded within the MP3 file.
+ Additional encoding options can be found by consulting the
+ lame man page.</para>
+ </sect2>
+
+ <sect2 xml:id="mp3-decoding">
+ <title>Decoding MP3s</title>
+
+ <para>In order to burn an audio CD from MP3s, they must be
+ converted to a non-compressed WAV format. Both
+ <application>XMMS</application> and
+ <application>mpg123</application> support the output of MP3 to
+ an uncompressed file format.</para>
+
+ <para>Writing to Disk in <application>XMMS</application>:</para>
+
+ <procedure>
+ <step>
+ <para>Launch <application>XMMS</application>.</para>
+ </step>
+
+ <step>
+ <para>Right-click on the window to bring up the
+ <application>XMMS</application> menu.</para>
+ </step>
+
+ <step>
+ <para>Select <literal>Preference</literal> under
+ <literal>Options</literal>.</para>
+ </step>
+
+ <step>
+ <para>Change the Output Plugin to <quote>Disk Writer
+ Plugin</quote>.</para>
+ </step>
+
+ <step>
+ <para>Press <literal>Configure</literal>.</para>
+ </step>
+
+ <step>
+ <para>Enter (or choose browse) a directory to write the
+ uncompressed files to.</para>
+ </step>
+
+ <step>
+ <para>Load the MP3 file into <application>XMMS</application>
+ as usual, with volume at 100% and EQ settings turned
+ off.</para>
+ </step>
+
+ <step>
+ <para>Press <literal>Play</literal> &mdash;
+ <application>XMMS</application> will appear as if it is
+ playing the MP3, but no music will be heard. It is
+ actually playing the MP3 to a file.</para>
+ </step>
+
+ <step>
+ <para>Be sure to set the default Output Plugin back to what
+ it was before in order to listen to MP3s again.</para>
+ </step>
+ </procedure>
+
+ <para>Writing to stdout in <application>mpg123</application>:</para>
+
+ <procedure>
+ <step>
+ <para>Run <command>mpg123 -s audio01.mp3
+ &gt; audio01.pcm</command></para>
+ </step>
+ </procedure>
+
+ <para><application>XMMS</application> writes a file in the WAV
+ format, while <application>mpg123</application> converts the
+ MP3 into raw PCM audio data. Both of these formats can be
+ used with <application>cdrecord</application> to create audio CDs.
+ You have to use raw PCM with &man.burncd.8;.
+ If you use WAV files, you will notice a small tick sound at the
+ beginning of each track, this sound is the header of the WAV
+ file. You can simply remove the header of a WAV file with the
+ utility <application>SoX</application> (it can be installed from
+ the <package>audio/sox</package> port or
+ package):</para>
+
+ <screen>&prompt.user; <userinput>sox -t wav -r 44100 -s -w -c 2 track.wav track.raw</userinput></screen>
+
+ <para>Read <xref linkend="creating-cds"/> for more information on using a
+ CD burner in FreeBSD.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="video-playback">
+ <info><title>播放影片</title>
+ <authorgroup>
+ <author><personname><firstname>Ross</firstname><surname>Lippert</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <para>Video playback is a very new and rapidly developing application
+ area. Be patient. Not everything is going to work as smoothly as
+ it did with sound.</para>
+
+ <para>Before you begin, you should know the model of the video
+ card you have and the chip it uses. While <application>&xorg;</application> and <application>&xfree86;</application> support a
+ wide variety of video cards, fewer give good playback
+ performance. To obtain a list of extensions supported by the
+ X server using your card use the command &man.xdpyinfo.1; while
+ X11 is running.</para>
+
+ <para>It is a good idea to have a short MPEG file which can be
+ treated as a test file for evaluating various players and
+ options. Since some DVD players will look for DVD media in
+ <filename>/dev/dvd</filename> by default, or have this device
+ name hardcoded in them, you might find it useful to make
+ symbolic links to the proper devices:</para>
+
+ <screen>&prompt.root; <userinput>ln -sf /dev/acd0c /dev/dvd</userinput>
+&prompt.root; <userinput>ln -sf /dev/racd0c /dev/rdvd</userinput></screen>
+
+ <para>On FreeBSD&nbsp;5.X, which uses &man.devfs.5; there
+ is a slightly different set of recommended links:</para>
+
+ <screen>&prompt.root; <userinput>ln -sf /dev/acd0 /dev/dvd</userinput>
+&prompt.root; <userinput>ln -sf /dev/acd0 /dev/rdvd</userinput></screen>
+
+ <para>Note that due to the nature of &man.devfs.5;,
+ manually created links like these will not persist if you reboot
+ your system. In order to create the symbolic links
+ automatically whenever you boot your system, add the following
+ lines to <filename>/etc/devfs.conf</filename>:</para>
+
+ <programlisting>link acd0 dvd
+link acd0 rdvd</programlisting>
+
+ <para>Additionally, DVD decryption, which requires invoking
+ special DVD-ROM functions, requires write permission on the DVD
+ devices.</para>
+
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>CPU_ENABLE_SSE</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>USER_LDT</secondary>
+ </indexterm>
+
+ <para>Some of the ports discussed rely on the following kernel
+ options to build correctly. Before attempting to build, add
+ this option to the kernel configuration file, build a new kernel, and reboot:</para>
+
+ <programlisting>options CPU_ENABLE_SSE</programlisting>
+
+ <note>
+ <para>On &os;&nbsp;4.X <literal>options USER_LDT</literal> should
+ be added to the kernel configuration file. This option is not
+ available on &os;&nbsp;5.X and later version.</para>
+ </note>
+
+ <para>To enhance the shared memory X11 interface, it is
+ recommended that the values of some &man.sysctl.8; variables
+ should be increased:</para>
+
+ <programlisting>kern.ipc.shmmax=67108864
+kern.ipc.shmall=32768</programlisting>
+
+ <sect2 xml:id="video-interface">
+ <title>Determining Video Capabilities</title>
+
+ <indexterm><primary>XVideo</primary></indexterm>
+ <indexterm><primary>SDL</primary></indexterm>
+ <indexterm><primary>DGA</primary></indexterm>
+
+ <para>There are several possible ways to display video under X11.
+ What will really work is largely hardware dependent. Each
+ method described below will have varying quality across
+ different hardware. Secondly, the rendering of video in X11 is
+ a topic receiving a lot of attention lately, and with each
+ version of <application>&xorg;</application>, or of <application>&xfree86;</application>, there may be significant improvement.</para>
+
+ <para>A list of common video interfaces:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>X11: normal X11 output using shared memory.</para>
+ </listitem>
+ <listitem>
+ <para>XVideo: an extension to the X11
+ interface which supports video in any X11 drawable.</para>
+ </listitem>
+ <listitem>
+ <para>SDL: the Simple Directmedia Layer.</para>
+ </listitem>
+ <listitem>
+ <para>DGA: the Direct Graphics Access.</para>
+ </listitem>
+ <listitem>
+ <para>SVGAlib: low level console graphics layer.</para>
+ </listitem>
+ </orderedlist>
+
+ <sect3 xml:id="video-interface-xvideo">
+ <title>XVideo</title>
+
+ <para><application>&xorg;</application> and <application>&xfree86; 4.X</application> have an extension called
+ <emphasis>XVideo</emphasis> (aka Xvideo, aka Xv, aka xv) which
+ allows video to be directly displayed in drawable objects
+ through a special acceleration. This extension provides very
+ good quality playback even on low-end machines.</para>
+
+ <para>To check whether the extension is running,
+ use <command>xvinfo</command>:</para>
+
+ <screen>&prompt.user; <userinput>xvinfo</userinput></screen>
+
+ <para>XVideo is supported for your card if the result looks like:</para>
+<screen>X-Video Extension version 2.2
+screen #0
+ Adaptor #0: "Savage Streams Engine"
+ number of ports: 1
+ port base: 43
+ operations supported: PutImage
+ supported visuals:
+ depth 16, visualID 0x22
+ depth 16, visualID 0x23
+ number of attributes: 5
+ "XV_COLORKEY" (range 0 to 16777215)
+ client settable attribute
+ client gettable attribute (current value is 2110)
+ "XV_BRIGHTNESS" (range -128 to 127)
+ client settable attribute
+ client gettable attribute (current value is 0)
+ "XV_CONTRAST" (range 0 to 255)
+ client settable attribute
+ client gettable attribute (current value is 128)
+ "XV_SATURATION" (range 0 to 255)
+ client settable attribute
+ client gettable attribute (current value is 128)
+ "XV_HUE" (range -180 to 180)
+ client settable attribute
+ client gettable attribute (current value is 0)
+ maximum XvImage size: 1024 x 1024
+ Number of image formats: 7
+ id: 0x32595559 (YUY2)
+ guid: 59555932-0000-0010-8000-00aa00389b71
+ bits per pixel: 16
+ number of planes: 1
+ type: YUV (packed)
+ id: 0x32315659 (YV12)
+ guid: 59563132-0000-0010-8000-00aa00389b71
+ bits per pixel: 12
+ number of planes: 3
+ type: YUV (planar)
+ id: 0x30323449 (I420)
+ guid: 49343230-0000-0010-8000-00aa00389b71
+ bits per pixel: 12
+ number of planes: 3
+ type: YUV (planar)
+ id: 0x36315652 (RV16)
+ guid: 52563135-0000-0000-0000-000000000000
+ bits per pixel: 16
+ number of planes: 1
+ type: RGB (packed)
+ depth: 0
+ red, green, blue masks: 0x1f, 0x3e0, 0x7c00
+ id: 0x35315652 (RV15)
+ guid: 52563136-0000-0000-0000-000000000000
+ bits per pixel: 16
+ number of planes: 1
+ type: RGB (packed)
+ depth: 0
+ red, green, blue masks: 0x1f, 0x7e0, 0xf800
+ id: 0x31313259 (Y211)
+ guid: 59323131-0000-0010-8000-00aa00389b71
+ bits per pixel: 6
+ number of planes: 3
+ type: YUV (packed)
+ id: 0x0
+ guid: 00000000-0000-0000-0000-000000000000
+ bits per pixel: 0
+ number of planes: 0
+ type: RGB (packed)
+ depth: 1
+ red, green, blue masks: 0x0, 0x0, 0x0</screen>
+
+ <para>Also note that the formats listed (YUV2, YUV12, etc) are not
+ present with every implementation of XVideo and their absence may
+ hinder some players.</para>
+
+ <para>If the result looks like:</para>
+<screen>X-Video Extension version 2.2
+screen #0
+no adaptors present</screen>
+
+ <para>Then XVideo is probably not supported for your card.</para>
+
+ <para>If XVideo is not supported for your card, this only means
+ that it will be more difficult for your display to meet the
+ computational demands of rendering video. Depending on your
+ video card and processor, though, you might still be able to
+ have a satisfying experience. You should probably read about
+ ways of improving performance in the advanced reading <xref linkend="video-further-reading"/>.</para>
+
+ </sect3>
+
+ <sect3 xml:id="video-interface-SDL">
+ <title>Simple Directmedia Layer</title>
+
+ <para>The Simple Directmedia Layer, SDL, was intended to be a
+ porting layer between &microsoft.windows;, BeOS, and &unix;,
+ allowing cross-platform applications to be developed which made
+ efficient use of sound and graphics. The SDL layer provides a
+ low-level abstraction to the hardware which can sometimes be
+ more efficient than the X11 interface.</para>
+
+ <para>The SDL can be found at <package>devel/sdl12</package>.</para>
+
+ </sect3>
+
+ <sect3 xml:id="video-interface-DGA">
+ <title>Direct Graphics Access</title>
+
+ <para>Direct Graphics Access is an X11 extension which allows
+ a program to bypass the X server and directly alter the
+ framebuffer. Because it relies on a low level memory mapping to
+ effect this sharing, programs using it must be run as
+ <systemitem class="username">root</systemitem>.</para>
+
+ <para>The DGA extension can be tested and benchmarked by
+ &man.dga.1;. When <command>dga</command> is running, it
+ changes the colors of the display whenever a key is pressed. To
+ quit, use <keycap>q</keycap>.</para>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 xml:id="video-ports">
+ <title>Ports and Packages Dealing with Video</title>
+
+ <indexterm><primary>video ports</primary></indexterm>
+ <indexterm><primary>video packages</primary></indexterm>
+
+ <para>This section discusses the software available from the
+ FreeBSD Ports Collection which can be used for video playback.
+ Video playback is a very active area of software development,
+ and the capabilities of various applications are bound to
+ diverge somewhat from the descriptions given here.</para>
+
+ <para>Firstly, it is important to know that many of the video
+ applications which run on FreeBSD were developed as Linux
+ applications. Many of these applications are still
+ beta-quality. Some of the problems that you may encounter with
+ video packages on FreeBSD include:</para>
+
+ <orderedlist>
+
+ <listitem>
+ <para>An application cannot playback a file which another
+ application produced.</para>
+ </listitem>
+
+ <listitem>
+ <para>An application cannot playback a file which the
+ application itself produced.</para>
+ </listitem>
+
+ <listitem>
+ <para>The same application on two different machines,
+ rebuilt on each machine for that machine, plays back the same
+ file differently.</para>
+ </listitem>
+
+ <listitem>
+ <para>A seemingly trivial filter like rescaling of the image
+ size results in very bad artifacts from a buggy rescaling
+ routine.</para>
+ </listitem>
+
+ <listitem>
+ <para>An application frequently dumps core.</para>
+ </listitem>
+
+ <listitem>
+ <para>Documentation is not installed with the port and can be
+ found either on the web or under the port's <filename>work</filename>
+ directory.</para>
+ </listitem>
+
+ </orderedlist>
+
+ <para>Many of these applications may also exhibit
+ <quote>Linux-isms</quote>. That is, there may be
+ issues resulting from the way some standard libraries are
+ implemented in the Linux distributions, or some features of the
+ Linux kernel which have been assumed by the authors of the
+ applications. These issues are not always noticed and worked around
+ by the port maintainers, which can lead to problems like
+ these:</para>
+
+ <orderedlist>
+
+ <listitem>
+ <para>The use of <filename>/proc/cpuinfo</filename> to detect
+ processor characteristics.</para>
+ </listitem>
+
+ <listitem>
+ <para>A misuse of threads which causes a program to hang upon
+ completion instead of truly terminating.</para>
+ </listitem>
+
+ <listitem>
+ <para>Software not yet in the FreeBSD Ports Collection
+ which is commonly used in conjunction with the application.</para>
+ </listitem>
+
+ </orderedlist>
+
+ <para>So far, these application developers have been cooperative with
+ port maintainers to minimize the work-arounds needed for
+ port-ing.</para>
+
+ <sect3 xml:id="video-mplayer">
+ <title>MPlayer</title>
+
+ <para><application>MPlayer</application> is a recently developed and rapidly developing
+ video player. The goals of the <application>MPlayer</application> team are speed and
+ flexibility on Linux and other Unices. The project was
+ started when the team founder got fed up with bad playback
+ performance on then available players. Some would say that
+ the graphical interface has been sacrificed for a streamlined
+ design. However, once
+ you get used to the command line options and the key-stroke
+ controls, it works very well.</para>
+
+ <sect4 xml:id="video-mplayer-building">
+ <title>Building MPlayer</title>
+ <indexterm><primary>MPlayer</primary>
+ <secondary>making</secondary></indexterm>
+
+ <para><application>MPlayer</application> resides in <package>multimedia/mplayer</package>.
+ <application>MPlayer</application> performs a variety of
+ hardware checks during the build process, resulting in a
+ binary which will not be portable from one system to
+ another. Therefore, it is important to build it from
+ ports and not to use a binary package. Additionally, a
+ number of options can be specified in the <command>make</command>
+ command line, as described in the <filename>Makefile</filename> and at the start of the build:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/multimedia/mplayer</userinput>
+&prompt.root; <userinput>make</userinput>
+N - O - T - E
+
+Take a careful look into the Makefile in order
+to learn how to tune mplayer towards you personal preferences!
+For example,
+make WITH_GTK1
+builds MPlayer with GTK1-GUI support.
+If you want to use the GUI, you can either install
+/usr/ports/multimedia/mplayer-skins
+or download official skin collections from
+http://www.mplayerhq.hu/homepage/dload.html
+</screen>
+
+ <para>The default port options should be sufficient for most
+ users. However, if you need the XviD codec, you have to
+ specify the <varname>WITH_XVID</varname> option in the
+ command line. The default DVD device can also be defined
+ with the <varname>WITH_DVD_DEVICE</varname> option, by
+ default <filename>/dev/acd0</filename> will be used.</para>
+
+ <para>As of this writing, the <application>MPlayer</application> port will build its HTML
+ documentation and two executables,
+ <command>mplayer</command>, and
+ <command>mencoder</command>, which is a tool for
+ re-encoding video.</para>
+
+ <para>The HTML documentation for <application>MPlayer</application> is very informative.
+ If the reader finds the information on video hardware and
+ interfaces in this chapter lacking, the <application>MPlayer</application> documentation
+ is a very thorough supplement. You should definitely take
+ the time to read the <application>MPlayer</application>
+ documentation if you are looking for information about video
+ support in &unix;.</para>
+
+ </sect4>
+
+ <sect4 xml:id="video-mplayer-using">
+ <title>Using MPlayer</title>
+ <indexterm><primary>MPlayer</primary>
+ <secondary>use</secondary></indexterm>
+
+ <para>Any user of <application>MPlayer</application> must set up a
+ <filename>.mplayer</filename> subdirectory of her
+ home directory. To create this necessary subdirectory,
+ you can type the following:</para>
+
+<screen>&prompt.user; <userinput>cd /usr/ports/multimedia/mplayer</userinput>
+&prompt.user; <userinput>make install-user</userinput></screen>
+
+ <para>The command options for <command>mplayer</command> are
+ listed in the manual page. For even more detail there is HTML
+ documentation. In this section, we will describe only a few
+ common uses.</para>
+
+ <para>To play a file, such as
+ <filename>testfile.avi</filename>,
+ through one of the various video interfaces set the
+ <option>-vo</option> option:</para>
+
+ <screen>&prompt.user; <userinput>mplayer -vo xv testfile.avi</userinput></screen>
+ <screen>&prompt.user; <userinput>mplayer -vo sdl testfile.avi</userinput></screen>
+ <screen>&prompt.user; <userinput>mplayer -vo x11 testfile.avi</userinput></screen>
+ <screen>&prompt.root; <userinput>mplayer -vo dga testfile.avi</userinput></screen>
+ <screen>&prompt.root; <userinput>mplayer -vo 'sdl:dga' testfile.avi</userinput></screen>
+
+ <para>It is worth trying all of these options, as their relative
+ performance depends on many factors and will vary significantly
+ with hardware.</para>
+
+ <para>To play from a DVD, replace the
+ <filename>testfile.avi</filename> with <option>dvd://<replaceable>N</replaceable> -dvd-device
+ <replaceable>DEVICE</replaceable></option> where <replaceable>N</replaceable> is
+ the title number to play and
+ <filename>DEVICE</filename> is the
+ device node for the DVD-ROM. For example, to play title 3
+ from <filename>/dev/dvd</filename>:</para>
+
+ <screen>&prompt.root; <userinput>mplayer -vo xv dvd://3 -dvd-device /dev/dvd</userinput></screen>
+
+ <note>
+ <para>The default DVD device can be defined during the build
+ of the <application>MPlayer</application> port via the
+ <varname>WITH_DVD_DEVICE</varname> option. By default,
+ this device is <filename>/dev/acd0</filename>. More
+ details can be found in the port
+ <filename>Makefile</filename>.</para>
+ </note>
+
+ <para>To stop, pause, advance and so on, consult the
+ keybindings, which are output by running <command>mplayer
+ -h</command> or read the manual page.</para>
+
+ <para>Additional important options for playback are:
+ <option>-fs -zoom</option> which engages the fullscreen mode
+ and <option>-framedrop</option> which helps performance.</para>
+
+ <para>In order for the mplayer command line to not become too
+ large, the user can create a file
+ <filename>.mplayer/config</filename> and set default options
+ there:</para>
+<programlisting>vo=xv
+fs=yes
+zoom=yes</programlisting>
+
+ <para>Finally, <command>mplayer</command> can be used to rip a
+ DVD title into a <filename>.vob</filename> file. To dump
+ out the second title from a DVD, type this:</para>
+
+ <screen>&prompt.root; <userinput>mplayer -dumpstream -dumpfile out.vob dvd://2 -dvd-device /dev/dvd</userinput></screen>
+
+ <para>The output file, <filename>out.vob</filename>, will be
+ MPEG and can be manipulated by the other packages described
+ in this section.</para>
+
+ </sect4>
+ <sect4 xml:id="video-mencoder">
+ <title>mencoder</title>
+ <indexterm>
+ <primary>mencoder</primary>
+ </indexterm>
+
+ <para>Before using
+ <command>mencoder</command> it is a good idea to
+ familiarize yourself with the options from the HTML
+ documentation. There is a manual page, but it is not very
+ useful without the HTML documentation. There are innumerable ways to
+ improve quality, lower bitrate, and change formats, and some
+ of these tricks may make the difference between good
+ or bad performance. Here are a couple of examples to get
+ you going. First a simple copy:</para>
+
+ <screen>&prompt.user; <userinput>mencoder input.avi -oac copy -ovc copy -o output.avi</userinput></screen>
+
+ <para>Improper combinations of command line options can yield
+ output files that are
+ unplayable even by <command>mplayer</command>. Thus, if you
+ just want to rip to a file, stick to the <option>-dumpfile</option>
+ in <command>mplayer</command>.</para>
+
+ <para>To convert <filename>input.avi</filename> to the MPEG4
+ codec with MPEG3 audio encoding (<package>audio/lame</package> is required):</para>
+
+ <screen>&prompt.user; <userinput>mencoder input.avi -oac mp3lame -lameopts br=192 \
+ -ovc lavc -lavcopts vcodec=mpeg4:vhq -o output.avi</userinput></screen>
+
+ <para>This has produced output playable by <command>mplayer</command>
+ and <command>xine</command>.</para>
+
+ <para><filename>input.avi</filename> can be replaced with
+ <option>dvd://1 -dvd-device /dev/dvd</option> and run as
+ <systemitem class="username">root</systemitem> to re-encode a DVD title
+ directly. Since you are likely to be dissatisfied with
+ your results the first time around, it is recommended you
+ dump the title to a file and work on the file.</para>
+ </sect4>
+
+ </sect3>
+
+ <sect3 xml:id="video-xine">
+ <title>The xine Video Player</title>
+
+ <para>The <application>xine</application> video player is a project of wide scope aiming not only at being an
+ all in one video solution, but also in producing a reusable base
+ library and a modular executable which can be extended with
+ plugins. It comes both as a package and as a port, <package>multimedia/xine</package>.</para>
+
+ <para>The <application>xine</application> player
+ is still very rough around the edges, but it is clearly off to a
+ good start. In practice, <application>xine</application> requires either a fast CPU with a
+ fast video card, or support for the XVideo extension. The GUI is
+ usable, but a bit clumsy.</para>
+
+ <para>As of this writing, there is no input module shipped with
+ <application>xine</application> which will play CSS encoded DVD's. There are third party
+ builds which do have modules for this built in them, but none
+ of these are in the FreeBSD Ports Collection.</para>
+
+ <para>Compared to <application>MPlayer</application>, <application>xine</application> does more for the user, but at the
+ same time, takes some of the more fine-grained control away from
+ the user. The <application>xine</application> video player
+ performs best on XVideo interfaces.</para>
+
+ <para>By default, <application>xine</application> player will
+ start up in a graphical user interface. The menus can then be
+ used to open a specific file:</para>
+
+ <screen>&prompt.user; <userinput>xine</userinput></screen>
+
+ <para>Alternatively, it may be invoked to play a file immediately
+ without the GUI with the command:</para>
+
+ <screen>&prompt.user; <userinput>xine -g -p mymovie.avi</userinput></screen>
+
+ </sect3>
+
+ <sect3 xml:id="video-ports-transcode">
+ <title>The transcode Utilities</title>
+
+ <para>The software <application>transcode</application> is not a player, but a suite of tools for
+ re-encoding video and audio files. With <application>transcode</application>, one has the
+ ability to merge video files, repair broken files, using command
+ line tools with <filename>stdin/stdout</filename> stream
+ interfaces.</para>
+
+ <para>A great number of options can be specified during
+ the build from the <package>multimedia/transcode</package> port, we recommend the
+ following command line to build
+ <application>transcode</application>:</para>
+
+ <screen>&prompt.root; <userinput>make WITH_OPTIMIZED_CFLAGS=yes WITH_LIBA52=yes WITH_LAME=yes WITH_OGG=yes \
+WITH_MJPEG=yes -DWITH_XVID=yes</userinput></screen>
+
+ <para>The proposed settings should be sufficient for most users.</para>
+
+ <para>To illustrate <command>transcode</command> capacities, one
+ example to show how to convert a DivX file into a PAL MPEG-1
+ file (PAL VCD):</para>
+
+ <screen>&prompt.user; <userinput>transcode -i input.avi -V --export_prof vcd-pal -o output_vcd</userinput>
+&prompt.user; <userinput>mplex -f 1 -o output_vcd.mpg output_vcd.m1v output_vcd.mpa</userinput></screen>
+
+ <para>The resulting MPEG file,
+ <filename>output_vcd.mpg</filename>, is ready to be played with
+ <application>MPlayer</application>. You could even burn the
+ file on a CD-R media to create a Video CD, in this case you will
+ need to install and use both <package>multimedia/vcdimager</package> and <package>sysutils/cdrdao</package> programs.</para>
+
+ <para>There is a manual page for <command>transcode</command>, but
+ you should also consult the <link xlink:href="http://www.transcoding.org/cgi-bin/transcode">transcode
+ wiki</link> for further information and examples.</para>
+ </sect3>
+
+ </sect2>
+
+ <sect2 xml:id="video-further-reading">
+ <title>Further Reading</title>
+
+ <para>The various video software packages for FreeBSD are
+ developing rapidly. It is quite possible that in the near
+ future many of the problems discussed here will have been
+ resolved. In the mean time, those who
+ want to get the very most out of FreeBSD's A/V capabilities will
+ have to cobble together knowledge from several FAQs and tutorials
+ and use a few different applications. This section exists to
+ give the reader pointers to such additional information.</para>
+
+ <para>The
+ <link xlink:href="http://www.mplayerhq.hu/DOCS/">MPlayer documentation</link>
+ is very technically informative.
+ These documents should probably be consulted by anyone wishing
+ to obtain a high level of expertise with &unix; video. The
+ <application>MPlayer</application> mailing list is hostile to anyone who has not bothered
+ to read the documentation, so if you plan on making bug reports
+ to them, RTFM.</para>
+
+ <para>The
+ <link xlink:href="http://dvd.sourceforge.net/xine-howto/en_GB/html/howto.html"> xine HOWTO</link>
+ contains a chapter on performance improvement
+ which is general to all players.</para>
+
+ <para>Finally, there are some other promising applications which
+ the reader may try:</para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para><link xlink:href="http://avifile.sourceforge.net/">Avifile</link> which
+ is also a port <package>multimedia/avifile</package>.</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.dtek.chalmers.se/groups/dvd/">Ogle</link>
+ which is also a port <package>multimedia/ogle</package>.</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://xtheater.sourceforge.net/">Xtheater</link></para>
+ </listitem>
+
+ <listitem>
+ <para><package>multimedia/dvdauthor</package>, an open
+ source package for authoring DVD content.</para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="tvcard">
+ <info><title>設定電視卡(TV Cards)</title>
+ <authorgroup>
+ <author><personname><firstname>Josef</firstname><surname>El-Rayes</surname></personname><contrib>Original contribution by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Marc</firstname><surname>Fonvieille</surname></personname><contrib>Enhanced and adapted by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm>
+ <primary>TV cards</primary>
+ </indexterm>
+
+ <sect2>
+ <title>介紹</title>
+
+ <para>電視卡(TV card)可以讓您用電腦來看無線、有線電視節目。許多卡都是透過 RCA 或 S-video
+ 輸入端子來接收視訊,而且有些卡還可接收 FM 廣播的功能。</para>
+
+ <para>&os; 可透過 &man.bktr.4; 驅動程式,來支援 PCI 介面的電視卡,只要這些卡使用的是 Brooktree Bt848/849/878/879
+ 或 Conexant CN-878/Fusion 878a 視訊擷取晶片。此外,要再確認哪些卡上所附的選台功能是否有支援,可以參考 &man.bktr.4;
+ 說明,以查看所支援的硬體清單。</para>
+ </sect2>
+
+ <sect2>
+ <title>設定相關驅動程式</title>
+
+ <para>要用電視卡的話,就要載入 &man.bktr.4; 驅動程式,這個可以透過在 <filename>/boot/loader.conf</filename>
+ 檔加上下面這一行就可以了:</para>
+
+ <programlisting>bktr_load="YES"</programlisting>
+
+ <para>此外,也可以把該 kernel module 直接與 kernel 編譯在一起,作法就是在你的 kernel 設定檔內,加上下面這幾行:</para>
+
+ <programlisting>device bktr
+device iicbus
+device iicbb
+device smbus</programlisting>
+
+ <para>之所以要加上這些額外的驅動程式,是因為卡的各組成部分都是透過 I2C 匯流排而相互連接的。接下來,請重新編譯、安裝新的 kernel 。</para>
+
+ <para>安裝好新的 kernel 之後,要重開機才會生效。開機時,應該會看到類似下面的正確偵測到 TV card 訊息:</para>
+
+ <programlisting>bktr0: &lt;BrookTree 848A&gt; mem 0xd7000000-0xd7000fff irq 10 at device 10.0 on pci0
+iicbb0: &lt;I2C bit-banging driver&gt; on bti2c0
+iicbus0: &lt;Philips I2C bus&gt; on iicbb0 master-only
+iicbus1: &lt;Philips I2C bus&gt; on iicbb0 master-only
+smbus0: &lt;System Management Bus&gt; on bti2c0
+bktr0: Pinnacle/Miro TV, Philips SECAM tuner.</programlisting>
+
+ <para>當然,這些訊息可能因您的硬體不同而有所不同。However you should check if the tuner is correctly
+ detected; it is still possible to override some of the
+ detected parameters with &man.sysctl.8; MIBs and kernel
+ configuration file options. For example, if you want to force
+ the tuner to a Philips SECAM tuner, you should add the
+ following line to your kernel configuration file:</para>
+
+ <programlisting>options OVERRIDE_TUNER=6</programlisting>
+
+ <para>or you can directly use &man.sysctl.8;:</para>
+
+ <screen>&prompt.root; <userinput>sysctl hw.bt848.tuner=6</userinput></screen>
+
+ <para>See the &man.bktr.4; manual page and the
+ <filename>/usr/src/sys/conf/NOTES</filename> file for more
+ details on the available options. (If you are under
+ &os;&nbsp;4.X, <filename>/usr/src/sys/conf/NOTES</filename> is
+ replaced with
+ <filename>/usr/src/sys/i386/conf/LINT</filename>.)</para>
+ </sect2>
+
+ <sect2>
+ <title>好用的程式</title>
+
+ <para>要用電視卡,可以視需要安裝下列應用程式之一︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><package>multimedia/fxtv</package>
+ provides TV-in-a-window and image/audio/video capture
+ capabilities.</para>
+ </listitem>
+ <listitem>
+ <para><package>multimedia/xawtv</package>
+ is also a TV application, with the same features as
+ <application>fxtv</application>.</para>
+ </listitem>
+ <listitem>
+ <para><package>misc/alevt</package> decodes
+ and displays Videotext/Teletext.</para>
+ </listitem>
+ <listitem>
+ <para><package>audio/xmradio</package>, an
+ application to use the FM radio tuner coming with some
+ TV cards.</para>
+ </listitem>
+ <listitem>
+ <para><package>audio/wmtune</package>, a handy
+ desktop application for radio tuners.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>More applications are available in the &os; Ports
+ Collection.</para>
+ </sect2>
+
+ <sect2>
+ <title>Troubleshooting</title>
+
+ <para>If you encounter any problem with your TV card, you should
+ check at first if the video capture chip and the tuner are
+ really supported by the &man.bktr.4; driver and if you used the right
+ configuration options. For more support and various questions
+ about your TV card you may want to contact and use the
+ archives of the &a.multimedia.name; mailing list.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="scanners">
+ <info><title>掃描器</title>
+ <authorgroup>
+ <author><personname><firstname>Marc</firstname><surname>Fonvieille</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm>
+ <primary>image scanners</primary>
+ </indexterm>
+
+ <sect2>
+ <title>介紹</title>
+
+ <para>&os; 就像任何現代作業系統一樣,都可以使用掃描器。
+ 在 &os; 是透過 Ports Collection 內的 <application>SANE</application>(Scanner Access Now Easy)
+ 所提供的 <acronym role="Application Programming Interface">API</acronym> 來操作掃描器。
+ <application>SANE</application> 也會使用一些 &os; 的驅動程式來控制掃描器硬體。</para>
+
+ <para>&os; 同時支援 SCSI 和 USB 兩種介面的掃描器。在做任何設定之前,請確保
+ <application>SANE</application> 有支援您的掃描器。
+ <application>SANE</application> 有張 <link xlink:href="http://sane-project.org/sane-supported-devices.html">支援硬體</link>
+ 的清單,這裡有介紹掃描器的支援情況和狀態訊息。
+ 在 &man.uscanner.4; 內也有提供一份 USB 掃描器的支援列表。</para>
+ </sect2>
+
+ <sect2>
+ <title>Kernel 的設定</title>
+
+ <para>如同上述所提的 SCSI 和 USB 界面都有支援。這要取決於您的掃描器界面,而需要不同的設備驅動程式。</para>
+
+ <sect3 xml:id="scanners-kernel-usb">
+ <title>USB 介面</title>
+
+ <para>The <filename>GENERIC</filename> kernel by default
+ includes the device drivers needed to support USB scanners.
+ Should you decide to use a custom kernel, be sure that the
+ following lines are present in your kernel configuration
+ file:</para>
+
+ <programlisting>device usb
+device uhci
+device ohci
+device uscanner</programlisting>
+
+ <para>Depending upon the USB chipset on your motherboard, you
+ will only need either <literal>device uhci</literal> or
+ <literal>device ohci</literal>, however having both in the
+ kernel configuration file is harmless.</para>
+
+ <para>If you do not want to rebuild your kernel and your
+ kernel is not the <filename>GENERIC</filename> one, you can
+ directly load the &man.uscanner.4; device driver module with
+ the &man.kldload.8; command:</para>
+
+ <screen>&prompt.root; <userinput>kldload uscanner</userinput></screen>
+
+ <para>To load this module at each system startup, add the
+ following line to
+ <filename>/boot/loader.conf</filename>:</para>
+
+ <programlisting>uscanner_load="YES"</programlisting>
+
+ <para>After rebooting with the correct kernel, or after
+ loading the required module, plug in your USB scanner. The
+ scanner should appear in your system message buffer
+ (&man.dmesg.8;) as something like:</para>
+
+ <screen>uscanner0: EPSON EPSON Scanner, rev 1.10/3.02, addr 2</screen>
+
+ <para>This shows that our scanner is using the
+ <filename>/dev/uscanner0</filename> device node.</para>
+
+ <note>
+ <para>On &os;&nbsp;4.X, the USB daemon (&man.usbd.8;) must
+ be running to be able to see some USB devices. To enable
+ this, add <literal>usbd_enable="YES"</literal> to your
+ <filename>/etc/rc.conf</filename> file and reboot the
+ machine.</para>
+ </note>
+ </sect3>
+
+ <sect3>
+ <title>SCSI 介面</title>
+
+ <para>If your scanner comes with a SCSI interface, it is
+ important to know which SCSI controller board you will use.
+ According to the SCSI chipset used, you will have to tune
+ your kernel configuration file. The
+ <filename>GENERIC</filename> kernel supports the most common
+ SCSI controllers. Be sure to read the
+ <filename>NOTES</filename> file (<filename>LINT</filename>
+ under &os;&nbsp;4.X) and add the correct line to your kernel
+ configuration file. In addition to the SCSI adapter driver,
+ you need to have the following lines in your kernel
+ configuration file:</para>
+
+ <programlisting>device scbus
+device pass</programlisting>
+
+ <para>Once your kernel has been properly compiled, you should
+ be able to see the devices in your system message buffer,
+ when booting:</para>
+
+ <screen>pass2 at aic0 bus 0 target 2 lun 0
+pass2: &lt;AGFA SNAPSCAN 600 1.10&gt; Fixed Scanner SCSI-2 device
+pass2: 3.300MB/s transfers</screen>
+
+ <para>If your scanner was not powered-on at system boot, it is
+ still possible to manually force the detection by performing
+ a SCSI bus scan with the &man.camcontrol.8; command:</para>
+
+ <screen>&prompt.root; <userinput>camcontrol rescan all</userinput>
+Re-scan of bus 0 was successful
+Re-scan of bus 1 was successful
+Re-scan of bus 2 was successful
+Re-scan of bus 3 was successful</screen>
+
+ <para>Then the scanner will appear in the SCSI devices
+ list:</para>
+
+ <screen>&prompt.root; <userinput>camcontrol devlist</userinput>
+&lt;IBM DDRS-34560 S97B&gt; at scbus0 target 5 lun 0 (pass0,da0)
+&lt;IBM DDRS-34560 S97B&gt; at scbus0 target 6 lun 0 (pass1,da1)
+&lt;AGFA SNAPSCAN 600 1.10&gt; at scbus1 target 2 lun 0 (pass3)
+&lt;PHILIPS CDD3610 CD-R/RW 1.00&gt; at scbus2 target 0 lun 0 (pass2,cd0)</screen>
+
+ <para>More details about SCSI devices, are available in the
+ &man.scsi.4; and &man.camcontrol.8; manual pages.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>設定 SANE</title>
+
+ <para>The <application>SANE</application> system has been
+ splitted in two parts: the backends (<package>graphics/sane-backends</package>) and the
+ frontends (<package>graphics/sane-frontends</package>). The
+ backends part provides access to the scanner itself. The
+ <application>SANE</application>'s <link xlink:href="http://sane-project.org/sane-supported-devices.html">supported
+ devices</link> list specifies which backend will support your
+ image scanner. It is mandatory to determine the correct
+ backend for your scanner if you want to be able to use your
+ device. The frontends part provides the graphical scanning
+ interface (<application>xscanimage</application>).</para>
+
+ <para>The first thing to do is install the <package>graphics/sane-backends</package> port or
+ package. Then, use the <command>sane-find-scanner</command>
+ command to check the scanner detection by the
+ <application>SANE</application> system:</para>
+
+ <screen>&prompt.root; <userinput>sane-find-scanner -q</userinput>
+found SCSI scanner "AGFA SNAPSCAN 600 1.10" at /dev/pass3</screen>
+
+ <para>The output will show the interface type of the scanner and
+ the device node used to attach the scanner to the system. The
+ vendor and the product model may not appear, it is not
+ important.</para>
+
+ <note>
+ <para>Some USB scanners require you to load a firmware, this
+ is explained in the backend manual page. You should also read
+ &man.sane-find-scanner.1; and &man.sane.7; manual
+ pages.</para>
+ </note>
+
+ <para>Now we have to check if the scanner will be identified by
+ a scanning frontend. By default, the
+ <application>SANE</application> backends comes with a command
+ line tool called &man.scanimage.1;. This command allows you
+ to list the devices and to perform an image acquisition from
+ the command line. The <option>-L</option> option is used to
+ list the scanner device:</para>
+
+ <screen>&prompt.root; <userinput>scanimage -L</userinput>
+device `snapscan:/dev/pass3' is a AGFA SNAPSCAN 600 flatbed scanner</screen>
+
+ <para>No output or a message saying that no scanners were
+ identified indicates that &man.scanimage.1; is unable to
+ identify the scanner. If this happens, you will need to edit
+ the backend configuration file and define the scanner device
+ used. The <filename>/usr/local/etc/sane.d/</filename> directory
+ contains all backends configuration files. This
+ identification problem does appear with certain USB
+ scanners.</para>
+
+ <para>For example, with the USB scanner used in the <xref linkend="scanners-kernel-usb"/>,
+ <command>sane-find-scanner</command> gives us the following
+ information:</para>
+
+ <screen>&prompt.root; <userinput>sane-find-scanner -q</userinput>
+found USB scanner (UNKNOWN vendor and product) at device /dev/uscanner0</screen>
+ <para>The scanner is correctly detected, it uses the USB
+ interface and is attached to the
+ <filename>/dev/uscanner0</filename> device node. We can now
+ check if the scanner is correctly identified:</para>
+
+ <screen>&prompt.root; <userinput>scanimage -L</userinput>
+
+No scanners were identified. If you were expecting something different,
+check that the scanner is plugged in, turned on and detected by the
+sane-find-scanner tool (if appropriate). Please read the documentation
+which came with this software (README, FAQ, manpages).</screen>
+
+ <para>Since the scanner is not identified, we will need to edit
+ the <filename>/usr/local/etc/sane.d/epson.conf</filename>
+ file. The scanner model used was the &epson.perfection; 1650,
+ so we know the scanner will use the <literal>epson</literal>
+ backend. Be sure to read the help comments in the backends
+ configuration files. Line changes are quite simple: comment
+ out all lines that have the wrong interface for your scanner
+ (in our case, we will comment out all lines starting with the
+ word <literal>scsi</literal> as our scanner uses the USB
+ interface), then add at the end of the file a line specifying
+ the interface and the device node used. In this case, we add
+ the following line:</para>
+
+ <programlisting>usb /dev/uscanner0</programlisting>
+
+ <para>Please be sure to read the comments provided in the
+ backend configuration file as well as the backend manual page
+ for more details and correct syntax to use. We can now verify
+ if the scanner is identified:</para>
+
+ <screen>&prompt.root; <userinput>scanimage -L</userinput>
+device `epson:/dev/uscanner0' is a Epson GT-8200 flatbed scanner</screen>
+
+ <para>Our USB scanner has been identified. It is not important
+ if the brand and the model do not match. The key item to be
+ concerned with is the
+ <literal>`epson:/dev/uscanner0'</literal> field, which give us
+ the right backend name and the right device node.</para>
+
+ <para>Once the <command>scanimage -L</command> command is able
+ to see the scanner, the configuration is complete. The device
+ is now ready to scan.</para>
+
+ <para>While &man.scanimage.1; does allow us to perform an
+ image acquisition from the command line, it is preferable to
+ use a graphical user interface to perform image scanning.
+ <application>SANE</application> offers a simple but efficient
+ graphical interface: <application>xscanimage</application>
+ (<package>graphics/sane-frontends</package>).</para>
+
+ <para><application>Xsane</application> (<package>graphics/xsane</package>) is another popular
+ graphical scanning frontend. This frontend offers advanced
+ features such as various scanning mode (photocopy, fax, etc.),
+ color correction, batch scans, etc. Both of these applications
+ are useable as a <application>GIMP</application>
+ plugin.</para>
+ </sect2>
+
+ <sect2>
+ <title>Allowing Scanner Access to Other Users</title>
+
+ <para>All previous operations have been done with
+ <systemitem class="username">root</systemitem> privileges. You may however, need
+ other users to have access
+ to the scanner. The user will need read and write
+ permissions to the device node used by the scanner. As an
+ example, our USB scanner uses the device node
+ <filename>/dev/uscanner0</filename> which is owned by the
+ <systemitem class="groupname">operator</systemitem> group. Adding the user
+ <systemitem class="username">joe</systemitem> to the
+ <systemitem class="groupname">operator</systemitem> group will allow him to use
+ the scanner:</para>
+
+ <screen>&prompt.root; <userinput>pw groupmod operator -m joe</userinput></screen>
+
+ <para>For more details read the &man.pw.8; manual page. You
+ also have to set the correct write permissions (0660 or 0664)
+ on the <filename>/dev/uscanner0</filename> device node, by
+ default the <systemitem class="groupname">operator</systemitem> group can only
+ read the device node. This is done by adding the following
+ lines to the <filename>/etc/devfs.rules</filename> file:</para>
+
+ <programlisting>[system=5]
+add path uscanner0 mode 660</programlisting>
+
+ <para>Then add the following to
+ <filename>/etc/rc.conf</filename> and reboot the
+ machine:</para>
+
+ <programlisting>devfs_system_ruleset="system"</programlisting>
+
+ <para>More information regarding these lines can be found in the
+ &man.devfs.8; manual page. Under &os;&nbsp;4.X, the
+ <systemitem class="groupname">operator</systemitem> group has, by default, read
+ and write permissions to
+ <filename>/dev/uscanner0</filename>.</para>
+
+ <note>
+ <para>Of course, for security reasons, you should think twice
+ before adding a user to any group, especially the
+ <systemitem class="groupname">operator</systemitem> group.</para>
+ </note>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/network-servers/Makefile b/zh_TW.UTF-8/books/handbook/network-servers/Makefile
new file mode 100644
index 0000000000..8f39ebad57
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/network-servers/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= network-servers/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/network-servers/chapter.xml b/zh_TW.UTF-8/books/handbook/network-servers/chapter.xml
new file mode 100644
index 0000000000..bb09a704cd
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/network-servers/chapter.xml
@@ -0,0 +1,5074 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.75
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="network-servers">
+ <info><title>Network Servers</title>
+ <authorgroup>
+ <author><personname><firstname>Murray</firstname><surname>Stokely</surname></personname><contrib>Reorganized by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <sect1 xml:id="network-servers-synopsis">
+ <title>概述</title>
+
+ <para>This chapter will cover some of the more frequently used
+ network services on &unix; systems. We will cover how to
+ install, configure, test, and maintain many different types of
+ network services. Example configuration files are included
+ throughout this chapter for you to benefit from.</para>
+
+ <para>After reading this chapter, you will know:</para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>How to manage the <application>inetd</application>
+ daemon.</para>
+ </listitem>
+
+ <listitem>
+ <para>How to set up a network file system.</para>
+ </listitem>
+
+ <listitem>
+ <para>How to set up a network information server for sharing
+ user accounts.</para>
+ </listitem>
+
+ <listitem>
+ <para>How to set up automatic network settings using DHCP.</para>
+ </listitem>
+
+ <listitem>
+ <para>How to set up a domain name server.</para>
+ </listitem>
+
+ <listitem>
+ <para>How to set up the <application>Apache</application> HTTP Server.</para>
+ </listitem>
+
+ <listitem>
+ <para>How to set up a File Transfer Protocol (FTP) Server.</para>
+ </listitem>
+
+ <listitem>
+ <para>How to set up a file and print server for &windows;
+ clients using <application>Samba</application>.</para>
+ </listitem>
+
+ <listitem>
+ <para>How to synchronize the time and date, and set up a
+ time server, with the NTP protocol.</para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>Before reading this chapter, you should:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Understand the basics of the
+ <filename>/etc/rc</filename> scripts.</para>
+ </listitem>
+
+ <listitem>
+ <para>Be familiar with basic network terminology.</para>
+ </listitem>
+
+ <listitem>
+ <para>Know how to install additional third-party
+ software (<xref linkend="ports"/>).</para>
+ </listitem>
+
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="network-inetd">
+ <info><title>The <application>inetd</application> <quote>Super-Server</quote></title>
+ <authorgroup>
+ <author><personname><firstname>Chern</firstname><surname>Lee</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect2 xml:id="network-inetd-overview">
+ <title>Overview</title>
+
+ <para>&man.inetd.8; is referred to as the <quote>Internet
+ Super-Server</quote> because it manages connections for
+ several services. When a
+ connection is received by <application>inetd</application>, it
+ determines which program the connection is destined for, spawns
+ the particular process and delegates the socket to it (the program
+ is invoked with the service socket as its standard input, output
+ and error descriptors). Running
+ one instance of <application>inetd</application> reduces the
+ overall system load as compared to running each daemon
+ individually in stand-alone mode.</para>
+
+ <para>Primarily, <application>inetd</application> is used to
+ spawn other daemons, but several trivial protocols are handled
+ directly, such as <application>chargen</application>,
+ <application>auth</application>, and
+ <application>daytime</application>.</para>
+
+ <para>This section will cover the basics in configuring
+ <application>inetd</application> through its command-line
+ options and its configuration file,
+ <filename>/etc/inetd.conf</filename>.</para>
+ </sect2>
+
+ <sect2 xml:id="network-inetd-settings">
+ <title>Settings</title>
+
+ <para><application>inetd</application> is initialized through
+ the <filename>/etc/rc.conf</filename> system. The
+ <literal>inetd_enable</literal> option is set to
+ <literal>NO</literal> by default, but is often times turned on
+ by <application>sysinstall</application> with the medium
+ security profile. Placing:
+ <programlisting>inetd_enable="YES"</programlisting> or
+ <programlisting>inetd_enable="NO"</programlisting> into
+ <filename>/etc/rc.conf</filename> can enable or disable
+ <application>inetd</application> starting at boot time.</para>
+
+ <para>Additionally, different command-line options can be passed
+ to <application>inetd</application> via the
+ <literal>inetd_flags</literal> option.</para>
+ </sect2>
+
+ <sect2 xml:id="network-inetd-cmdline">
+ <title>Command-Line Options</title>
+
+ <para><application>inetd</application> synopsis:</para>
+
+ <para><option> inetd [-d] [-l] [-w] [-W] [-c maximum] [-C rate] [-a address | hostname]
+ [-p filename] [-R rate] [configuration file]</option></para>
+
+ <variablelist>
+ <varlistentry>
+ <term>-d</term>
+
+ <listitem>
+ <para>Turn on debugging.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-l</term>
+
+ <listitem>
+ <para>Turn on logging of successful connections.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-w</term>
+
+ <listitem>
+ <para>Turn on TCP Wrapping for external services (on by
+ default).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-W</term>
+
+ <listitem>
+ <para>Turn on TCP Wrapping for internal services which are
+ built into <application>inetd</application> (on by
+ default).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-c maximum</term>
+
+ <listitem>
+ <para>Specify the default maximum number of simultaneous
+ invocations of each service; the default is unlimited.
+ May be overridden on a per-service basis with the
+ <option>max-child</option> parameter.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-C rate</term>
+
+ <listitem>
+ <para>Specify the default maximum number of times a
+ service can be invoked from a single IP address in one
+ minute; the default is unlimited. May be overridden on a
+ per-service basis with the
+ <option>max-connections-per-ip-per-minute</option>
+ parameter.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-R rate</term>
+
+ <listitem>
+ <para>Specify the maximum number of times a service can be
+ invoked in one minute; the default is 256. A rate of 0
+ allows an unlimited number of invocations.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-a</term>
+
+ <listitem>
+ <para>Specify one specific IP address to bind to.
+ Alternatively, a hostname can be specified, in which case
+ the IPv4 or IPv6 address which corresponds to that
+ hostname is used. Usually a hostname is specified when
+ <application>inetd</application> is run inside a
+ &man.jail.8;, in which case the hostname corresponds to
+ the &man.jail.8; environment.</para>
+
+ <para>When hostname specification is used and both IPv4
+ and IPv6 bindings are desired, one entry with the
+ appropriate protocol type for each binding is required
+ for each service in
+ <filename>/etc/inetd.conf</filename>. For example, a
+ TCP-based service would need two entries, one using
+ <literal>tcp4</literal> for the protocol and the other
+ using <literal>tcp6</literal>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-p</term>
+
+ <listitem>
+ <para>Specify an alternate file in which to store the
+ process ID.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>These options can be passed to
+ <application>inetd</application> using the
+ <literal>inetd_flags</literal> option in
+ <filename>/etc/rc.conf</filename>. By default,
+ <literal>inetd_flags</literal> is set to
+ <literal>-wW</literal>, which turns on TCP wrapping for
+ <application>inetd</application>'s internal and external
+ services. For novice users, these parameters usually do not
+ need to be modified or even entered in
+ <filename>/etc/rc.conf</filename>.</para>
+
+ <note>
+ <para>An external service is a daemon outside of
+ <application>inetd</application>, which is invoked when a
+ connection is received for it. On the other hand, an
+ internal service is one that
+ <application>inetd</application> has the facility of
+ offering within itself.</para>
+ </note>
+
+ </sect2>
+
+ <sect2 xml:id="network-inetd-conf">
+ <title><filename>inetd.conf</filename></title>
+
+ <para>Configuration of <application>inetd</application> is
+ controlled through the <filename>/etc/inetd.conf</filename>
+ file.</para>
+
+ <para>When a modification is made to
+ <filename>/etc/inetd.conf</filename>,
+ <application>inetd</application> can be forced to re-read its
+ configuration file by sending a HangUP signal to the
+ <application>inetd</application> process as shown:</para>
+
+ <example xml:id="network-inetd-hangup">
+ <title>Sending <application>inetd</application> a HangUP Signal</title>
+
+ <screen>&prompt.root; <userinput>kill -HUP `cat /var/run/inetd.pid`</userinput></screen>
+ </example>
+
+ <para>Each line of the configuration file specifies an
+ individual daemon. Comments in the file are preceded by a
+ <quote>#</quote>. The format of
+ <filename>/etc/inetd.conf</filename> is as follows:</para>
+
+ <programlisting>service-name
+socket-type
+protocol
+{wait|nowait}[/max-child[/max-connections-per-ip-per-minute]]
+user[:group][/login-class]
+server-program
+server-program-arguments</programlisting>
+
+ <para>An example entry for the <application>ftpd</application> daemon
+ using IPv4:</para>
+
+ <programlisting>ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l</programlisting>
+
+ <variablelist>
+ <varlistentry>
+ <term>service-name</term>
+
+ <listitem>
+ <para>This is the service name of the particular daemon.
+ It must correspond to a service listed in
+ <filename>/etc/services</filename>. This determines
+ which port <application>inetd</application> must listen
+ to. If a new service is being created, it must be
+ placed in <filename>/etc/services</filename>
+ first.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>socket-type</term>
+
+ <listitem>
+ <para>Either <literal>stream</literal>,
+ <literal>dgram</literal>, <literal>raw</literal>, or
+ <literal>seqpacket</literal>. <literal>stream</literal>
+ must be used for connection-based, TCP daemons, while
+ <literal>dgram</literal> is used for daemons utilizing
+ the <acronym>UDP</acronym> transport protocol.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>protocol</term>
+
+ <listitem>
+ <para>One of the following:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Protocol</entry>
+ <entry>Explanation</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>tcp, tcp4</entry>
+ <entry>TCP IPv4</entry>
+ </row>
+ <row>
+ <entry>udp, udp4</entry>
+ <entry>UDP IPv4</entry>
+ </row>
+ <row>
+ <entry>tcp6</entry>
+ <entry>TCP IPv6</entry>
+ </row>
+ <row>
+ <entry>udp6</entry>
+ <entry>UDP IPv6</entry>
+ </row>
+ <row>
+ <entry>tcp46</entry>
+ <entry>Both TCP IPv4 and v6</entry>
+ </row>
+ <row>
+ <entry>udp46</entry>
+ <entry>Both UDP IPv4 and v6</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>{wait|nowait}[/max-child[/max-connections-per-ip-per-minute]]</term>
+
+ <listitem>
+ <para><option>wait|nowait</option> indicates whether the
+ daemon invoked from <application>inetd</application> is
+ able to handle its own socket or not.
+ <option>dgram</option> socket types must use the
+ <option>wait</option> option, while stream socket
+ daemons, which are usually multi-threaded, should use
+ <option>nowait</option>. <option>wait</option> usually
+ hands off multiple sockets to a single daemon, while
+ <option>nowait</option> spawns a child daemon for each
+ new socket.</para>
+
+ <para>The maximum number of child daemons
+ <application>inetd</application> may spawn can be set
+ using the <option>max-child</option> option. If a limit
+ of ten instances of a particular daemon is needed, a
+ <literal>/10</literal> would be placed after
+ <option>nowait</option>.</para>
+
+ <para>In addition to <option>max-child</option>, another
+ option limiting the maximum connections from a single
+ place to a particular daemon can be enabled.
+ <option>max-connections-per-ip-per-minute</option> does
+ just this. A value of ten here would limit any particular
+ IP address connecting to a particular service to ten
+ attempts per minute. This is useful to prevent
+ intentional or unintentional resource consumption and
+ Denial of Service (DoS) attacks to a machine.</para>
+
+ <para>In this field, <option>wait</option> or
+ <option>nowait</option> is mandatory.
+ <option>max-child</option> and
+ <option>max-connections-per-ip-per-minute</option> are
+ optional.</para>
+
+ <para>A stream-type multi-threaded daemon without any
+ <option>max-child</option> or
+ <option>max-connections-per-ip-per-minute</option> limits
+ would simply be: <literal>nowait</literal>.</para>
+
+ <para>The same daemon with a maximum limit of ten daemons
+ would read: <literal>nowait/10</literal>.</para>
+
+ <para>Additionally, the same setup with a limit of twenty
+ connections per IP address per minute and a maximum
+ total limit of ten child daemons would read:
+ <literal>nowait/10/20</literal>.</para>
+
+ <para>These options are all utilized by the default
+ settings of the <application>fingerd</application> daemon,
+ as seen here:</para>
+
+ <programlisting>finger stream tcp nowait/3/10 nobody /usr/libexec/fingerd fingerd -s</programlisting>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>user</term>
+
+ <listitem>
+ <para>This is the username that the particular daemon
+ should run as. Most commonly, daemons run as the
+ <systemitem class="username">root</systemitem> user. For security purposes, it is
+ common to find some servers running as the
+ <systemitem class="username">daemon</systemitem> user, or the least privileged
+ <systemitem class="username">nobody</systemitem> user.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>server-program</term>
+
+ <listitem>
+ <para>The full path of the daemon to be executed when a
+ connection is received. If the daemon is a service
+ provided by <application>inetd</application> internally,
+ then <option>internal</option> should be
+ used.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>server-program-arguments</term>
+
+ <listitem>
+ <para>This works in conjunction with
+ <option>server-program</option> by specifying the
+ arguments, starting with <literal>argv[0]</literal>,
+ passed to the daemon on invocation. If
+ <command>mydaemon -d</command> is the command line,
+ <literal>mydaemon -d</literal> would be the value of
+ <option>server-program-arguments</option>. Again, if
+ the daemon is an internal service, use
+ <option>internal</option> here.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 xml:id="network-inetd-security">
+ <title>Security</title>
+
+ <para>Depending on the security profile chosen at install, many
+ of <application>inetd</application>'s daemons may be enabled
+ by default. If there is no apparent need for a particular
+ daemon, disable it! Place a <quote>#</quote> in front of the
+ daemon in question in <filename>/etc/inetd.conf</filename>,
+ and then send a <link linkend="network-inetd-hangup">hangup
+ signal to inetd</link>. Some daemons, such as
+ <application>fingerd</application>, may not be desired at all
+ because they provide an attacker with too much
+ information.</para>
+
+ <para>Some daemons are not security-conscious and have long, or
+ non-existent timeouts for connection attempts. This allows an
+ attacker to slowly send connections to a particular daemon,
+ thus saturating available resources. It may be a good idea to
+ place <option>max-connections-per-ip-per-minute</option> and
+ <option>max-child</option> limitations on certain
+ daemons.</para>
+
+ <para>By default, TCP wrapping is turned on. Consult the
+ &man.hosts.access.5; manual page for more information on placing
+ TCP restrictions on various <application>inetd</application>
+ invoked daemons.</para>
+ </sect2>
+
+ <sect2 xml:id="network-inetd-misc">
+ <title>Miscellaneous</title>
+
+ <para><application>daytime</application>,
+ <application>time</application>,
+ <application>echo</application>,
+ <application>discard</application>,
+ <application>chargen</application>, and
+ <application>auth</application> are all internally provided
+ services of <application>inetd</application>.</para>
+
+ <para>The <application>auth</application> service provides
+ identity (<application>ident</application>,
+ <application>identd</application>) network services, and is
+ configurable to a certain degree.</para>
+
+ <para>Consult the &man.inetd.8; manual page for more in-depth
+ information.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-nfs">
+ <info><title>Network File System (NFS)</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Reorganized and enhanced by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Bill</firstname><surname>Swingle</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>NFS</primary></indexterm>
+ <para>Among the many different file systems that FreeBSD supports
+ is the Network File System, also known as <acronym role="Network File System">NFS</acronym>. <acronym role="Network File System">NFS</acronym> allows a system to share directories and
+ files with others over a network. By using <acronym role="Network File System">NFS</acronym>, users and programs can
+ access files on remote systems almost as if they were local
+ files.</para>
+
+ <para>Some of the most notable benefits that
+ <acronym>NFS</acronym> can provide are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Local workstations use less disk space because commonly
+ used data can be stored on a single machine and still remain
+ accessible to others over the network.</para>
+ </listitem>
+
+ <listitem>
+ <para>There is no need for users to have separate home
+ directories on every network machine. Home directories
+ could be set up on the <acronym>NFS</acronym> server and
+ made available throughout the network.</para>
+ </listitem>
+
+ <listitem>
+ <para>Storage devices such as floppy disks, CDROM drives, and
+ &iomegazip; drives can be used by other machines on the network.
+ This may reduce the number of removable media drives
+ throughout the network.</para>
+ </listitem>
+ </itemizedlist>
+
+ <sect2>
+ <title>How <acronym>NFS</acronym> Works</title>
+
+ <para><acronym>NFS</acronym> consists of at least two main
+ parts: a server and one or more clients. The client remotely
+ accesses the data that is stored on the server machine. In
+ order for this to function properly a few processes have to be
+ configured and running.</para>
+
+ <note><para>Under &os;&nbsp;4.X, the <application>portmap</application>
+ utility is used in place of the
+ <application>rpcbind</application> utility. Thus, in &os;&nbsp;4.X
+ the user is required to replace every instance of
+ <application>rpcbind</application> with
+ <application>portmap</application> in the forthcoming
+ examples.</para></note>
+
+ <para>The server has to be running the following daemons:</para>
+ <indexterm>
+ <primary>NFS</primary>
+ <secondary>server</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>file server</primary>
+ <secondary>UNIX clients</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary><application>rpcbind</application></primary>
+ </indexterm>
+ <indexterm>
+ <primary><application>portmap</application></primary>
+ </indexterm>
+ <indexterm>
+ <primary><application>mountd</application></primary>
+ </indexterm>
+ <indexterm>
+ <primary><application>nfsd</application></primary>
+ </indexterm>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="3*"/>
+
+ <thead>
+ <row>
+ <entry>Daemon</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><application>nfsd</application></entry>
+ <entry>The <acronym>NFS</acronym> daemon which services
+ requests from the <acronym>NFS</acronym>
+ clients.</entry>
+ </row>
+ <row>
+ <entry><application>mountd</application></entry>
+ <entry>The <acronym>NFS</acronym> mount daemon which carries out
+ the requests that &man.nfsd.8; passes on to it.</entry>
+ </row>
+ <row>
+ <entry><application>rpcbind</application></entry>
+ <entry> This daemon allows
+ <acronym>NFS</acronym> clients to discover which port
+ the <acronym>NFS</acronym> server is using.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>The client can also run a daemon, known as
+ <application>nfsiod</application>. The
+ <application>nfsiod</application> daemon services the requests
+ from the <acronym>NFS</acronym> server. This is optional, and
+ improves performance, but is not required for normal and
+ correct operation. See the &man.nfsiod.8; manual page for
+ more information.
+ </para>
+ </sect2>
+
+ <sect2 xml:id="network-configuring-nfs">
+ <title>Configuring <acronym>NFS</acronym></title>
+ <indexterm>
+ <primary>NFS</primary>
+ <secondary>configuration</secondary>
+ </indexterm>
+
+ <para><acronym>NFS</acronym> configuration is a relatively
+ straightforward process. The processes that need to be
+ running can all start at boot time with a few modifications to
+ your <filename>/etc/rc.conf</filename> file.</para>
+
+ <para>On the <acronym>NFS</acronym> server, make sure that the
+ following options are configured in the
+ <filename>/etc/rc.conf</filename> file:</para>
+
+ <programlisting>rpcbind_enable="YES"
+nfs_server_enable="YES"
+mountd_flags="-r"</programlisting>
+
+ <para><application>mountd</application> runs automatically
+ whenever the <acronym>NFS</acronym> server is enabled.</para>
+
+ <para>On the client, make sure this option is present in
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>nfs_client_enable="YES"</programlisting>
+
+ <para>The <filename>/etc/exports</filename> file specifies which
+ file systems <acronym>NFS</acronym> should export (sometimes
+ referred to as <quote>share</quote>). Each line in
+ <filename>/etc/exports</filename> specifies a file system to be
+ exported and which machines have access to that file system.
+ Along with what machines have access to that file system,
+ access options may also be specified. There are many such
+ options that can be used in this file but only a few will be
+ mentioned here. You can easily discover other options by
+ reading over the &man.exports.5; manual page.</para>
+
+ <para>Here are a few example <filename>/etc/exports</filename>
+ entries:</para>
+
+ <indexterm>
+ <primary>NFS</primary>
+ <secondary>export examples</secondary>
+ </indexterm>
+
+ <para>The following examples give an idea of how to export
+ file systems, although the settings may be different depending
+ on your environment and network configuration. For instance,
+ to export the <filename>/cdrom</filename> directory to three
+ example machines that have the same domain name as the server
+ (hence the lack of a domain name for each) or have entries in
+ your <filename>/etc/hosts</filename> file. The
+ <option>-ro</option> flag makes the exported file system
+ read-only. With this flag, the remote system will not be able
+ to write any changes to the exported file system.</para>
+
+ <programlisting>/cdrom -ro host1 host2 host3</programlisting>
+
+ <para>The following line exports <filename>/home</filename> to
+ three hosts by IP address. This is a useful setup if you have
+ a private network without a <acronym>DNS</acronym> server
+ configured. Optionally the <filename>/etc/hosts</filename>
+ file could be configured for internal hostnames; please review
+ &man.hosts.5; for more information. The
+ <option>-alldirs</option> flag allows the subdirectories to be
+ mount points. In other words, it will not mount the
+ subdirectories but permit the client to mount only the
+ directories that are required or needed.</para>
+
+ <programlisting>/home -alldirs 10.0.0.2 10.0.0.3 10.0.0.4</programlisting>
+
+ <para>The following line exports <filename>/a</filename> so that
+ two clients from different domains may access the file system.
+ The <option>-maproot=root</option> flag allows the
+ <systemitem class="username">root</systemitem> user on the remote system to write
+ data on the exported file system as <systemitem class="username">root</systemitem>.
+ If the <literal>-maproot=root</literal> flag is not specified,
+ then even if a user has <systemitem class="username">root</systemitem> access on
+ the remote system, he will not be able to modify files on
+ the exported file system.</para>
+
+ <programlisting>/a -maproot=root host.example.com box.example.org</programlisting>
+
+ <para>In order for a client to access an exported file system,
+ the client must have permission to do so. Make sure the
+ client is listed in your <filename>/etc/exports</filename>
+ file.</para>
+
+ <para>In <filename>/etc/exports</filename>, each line represents
+ the export information for one file system to one host. A
+ remote host can only be specified once per file system, and may
+ only have one default entry. For example, assume that
+ <filename>/usr</filename> is a single file system. The
+ following <filename>/etc/exports</filename> would be
+ invalid:</para>
+
+ <programlisting># Invalid when /usr is one file system
+/usr/src client
+/usr/ports client</programlisting>
+
+ <para>One file system, <filename>/usr</filename>, has two lines
+ specifying exports to the same host, <systemitem>client</systemitem>.
+ The correct format for this situation is:</para>
+
+ <programlisting>/usr/src /usr/ports client</programlisting>
+
+ <para>The properties of one file system exported to a given host
+ must all occur on one line. Lines without a client specified
+ are treated as a single host. This limits how you can export
+ file systems, but for most people this is not an issue.</para>
+
+ <para>The following is an example of a valid export list, where
+ <filename>/usr</filename> and <filename>/exports</filename>
+ are local file systems:</para>
+
+ <programlisting># Export src and ports to client01 and client02, but only
+# client01 has root privileges on it
+/usr/src /usr/ports -maproot=root client01
+/usr/src /usr/ports client02
+# The client machines have root and can mount anywhere
+# on /exports. Anyone in the world can mount /exports/obj read-only
+/exports -alldirs -maproot=root client01 client02
+/exports/obj -ro</programlisting>
+
+ <para>You must restart
+ <application>mountd</application> whenever you modify
+ <filename>/etc/exports</filename> so the changes can take effect.
+ This can be accomplished by sending the HUP signal
+ to the <command>mountd</command> process:</para>
+
+ <screen>&prompt.root; <userinput>kill -HUP `cat /var/run/mountd.pid`</userinput></screen>
+
+ <para>Alternatively, a reboot will make FreeBSD set everything
+ up properly. A reboot is not necessary though.
+ Executing the following commands as <systemitem class="username">root</systemitem>
+ should start everything up.</para>
+
+ <para>On the <acronym>NFS</acronym> server:</para>
+
+ <screen>&prompt.root; <userinput>rpcbind</userinput>
+&prompt.root; <userinput>nfsd -u -t -n 4</userinput>
+&prompt.root; <userinput>mountd -r</userinput></screen>
+
+ <para>On the <acronym>NFS</acronym> client:</para>
+
+ <screen>&prompt.root; <userinput>nfsiod -n 4</userinput></screen>
+
+ <para>Now everything should be ready to actually mount a remote file
+ system. In these examples the
+ server's name will be <systemitem>server</systemitem> and the client's
+ name will be <systemitem>client</systemitem>. If you only want to
+ temporarily mount a remote file system or would rather test the
+ configuration, just execute a command like this as <systemitem class="username">root</systemitem> on the
+ client:</para>
+ <indexterm>
+ <primary>NFS</primary>
+ <secondary>mounting</secondary>
+ </indexterm>
+ <screen>&prompt.root; <userinput>mount server:/home /mnt</userinput></screen>
+
+ <para>This will mount the <filename>/home</filename> directory
+ on the server at <filename>/mnt</filename> on the client. If
+ everything is set up correctly you should be able to enter
+ <filename>/mnt</filename> on the client and see all the files
+ that are on the server.</para>
+
+ <para>If you want to automatically mount a remote file system
+ each time the computer boots, add the file system to the
+ <filename>/etc/fstab</filename> file. Here is an example:</para>
+
+ <programlisting>server:/home /mnt nfs rw 0 0</programlisting>
+
+ <para>The &man.fstab.5; manual page lists all the available
+ options.</para>
+ </sect2>
+
+ <sect2>
+ <title>Practical Uses</title>
+
+ <para><acronym>NFS</acronym> has many practical uses. Some of
+ the more common ones are listed below:</para>
+
+ <indexterm>
+ <primary>NFS</primary>
+ <secondary>uses</secondary>
+ </indexterm>
+ <itemizedlist>
+ <listitem>
+ <para>Set several machines to share a CDROM or other media
+ among them. This is cheaper and often a more convenient
+ method to install software on multiple machines.</para>
+ </listitem>
+
+ <listitem>
+ <para>On large networks, it might be more convenient to
+ configure a central <acronym>NFS</acronym> server in which
+ to store all the user home directories. These home
+ directories can then be exported to the network so that
+ users would always have the same home directory,
+ regardless of which workstation they log in to.</para>
+ </listitem>
+
+ <listitem>
+ <para>Several machines could have a common
+ <filename>/usr/ports/distfiles</filename> directory. That
+ way, when you need to install a port on several machines,
+ you can quickly access the source without downloading it
+ on each machine.</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2 xml:id="network-amd">
+ <info><title>Automatic Mounts with <application>amd</application></title>
+ <authorgroup>
+ <author><personname><firstname>Wylie</firstname><surname>Stilwell</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Chern</firstname><surname>Lee</surname></personname><contrib>Rewritten by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>amd</primary></indexterm>
+ <indexterm><primary>automatic mounter daemon</primary></indexterm>
+
+ <para>&man.amd.8; (the automatic mounter daemon)
+ automatically mounts a
+ remote file system whenever a file or directory within that
+ file system is accessed. Filesystems that are inactive for a
+ period of time will also be automatically unmounted by
+ <application>amd</application>. Using
+ <application>amd</application> provides a simple alternative
+ to permanent mounts, as permanent mounts are usually listed in
+ <filename>/etc/fstab</filename>.</para>
+
+ <para><application>amd</application> operates by attaching
+ itself as an NFS server to the <filename>/host</filename> and
+ <filename>/net</filename> directories. When a file is accessed
+ within one of these directories, <application>amd</application>
+ looks up the corresponding remote mount and automatically mounts
+ it. <filename>/net</filename> is used to mount an exported
+ file system from an IP address, while <filename>/host</filename>
+ is used to mount an export from a remote hostname.</para>
+
+ <para>An access to a file within
+ <filename>/host/foobar/usr</filename> would tell
+ <application>amd</application> to attempt to mount the
+ <filename>/usr</filename> export on the host
+ <systemitem>foobar</systemitem>.</para>
+
+ <example>
+ <title>Mounting an Export with <application>amd</application></title>
+
+ <para>You can view the available mounts of a remote host with
+ the <command>showmount</command> command. For example, to
+ view the mounts of a host named <systemitem>foobar</systemitem>, you
+ can use:</para>
+
+ <screen>&prompt.user; <userinput>showmount -e foobar</userinput>
+Exports list on foobar:
+/usr 10.10.10.0
+/a 10.10.10.0
+&prompt.user; <userinput>cd /host/foobar/usr</userinput></screen>
+ </example>
+
+ <para>As seen in the example, the <command>showmount</command> shows
+ <filename>/usr</filename> as an export. When changing directories to
+ <filename>/host/foobar/usr</filename>, <application>amd</application>
+ attempts to resolve the hostname <systemitem>foobar</systemitem> and
+ automatically mount the desired export.</para>
+
+ <para><application>amd</application> can be started by the
+ startup scripts by placing the following lines in
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>amd_enable="YES"</programlisting>
+
+ <para>Additionally, custom flags can be passed to
+ <application>amd</application> from the
+ <varname>amd_flags</varname> option. By default,
+ <varname>amd_flags</varname> is set to:</para>
+
+ <programlisting>amd_flags="-a /.amd_mnt -l syslog /host /etc/amd.map /net /etc/amd.map"</programlisting>
+
+ <para>The <filename>/etc/amd.map</filename> file defines the
+ default options that exports are mounted with. The
+ <filename>/etc/amd.conf</filename> file defines some of the more
+ advanced features of <application>amd</application>.</para>
+
+ <para>Consult the &man.amd.8; and &man.amd.conf.5; manual pages for more
+ information.</para>
+ </sect2>
+
+ <sect2 xml:id="network-nfs-integration">
+ <info><title>Problems Integrating with Other Systems</title>
+ <authorgroup>
+ <author><personname><firstname>John</firstname><surname>Lind</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <para>Certain Ethernet adapters for ISA PC systems have limitations
+ which can lead to serious network problems, particularly with NFS.
+ This difficulty is not specific to FreeBSD, but FreeBSD systems
+ are affected by it.</para>
+
+ <para>The problem nearly always occurs when (FreeBSD) PC systems are
+ networked with high-performance workstations, such as those made
+ by Silicon Graphics, Inc., and Sun Microsystems, Inc. The NFS
+ mount will work fine, and some operations may succeed, but
+ suddenly the server will seem to become unresponsive to the
+ client, even though requests to and from other systems continue to
+ be processed. This happens to the client system, whether the
+ client is the FreeBSD system or the workstation. On many systems,
+ there is no way to shut down the client gracefully once this
+ problem has manifested itself. The only solution is often to
+ reset the client, because the NFS situation cannot be
+ resolved.</para>
+
+ <para>Though the <quote>correct</quote> solution is to get a
+ higher performance and capacity Ethernet adapter for the
+ FreeBSD system, there is a simple workaround that will allow
+ satisfactory operation. If the FreeBSD system is the
+ <emphasis>server</emphasis>, include the option
+ <option>-w=1024</option> on the mount from the client. If the
+ FreeBSD system is the <emphasis>client</emphasis>, then mount
+ the NFS file system with the option <option>-r=1024</option>.
+ These options may be specified using the fourth field of the
+ <filename>fstab</filename> entry on the client for automatic
+ mounts, or by using the <option>-o</option> parameter of the
+ &man.mount.8; command for manual mounts.</para>
+
+ <para>It should be noted that there is a different problem,
+ sometimes mistaken for this one, when the NFS servers and
+ clients are on different networks. If that is the case, make
+ <emphasis>certain</emphasis> that your routers are routing the
+ necessary <acronym>UDP</acronym> information, or you will not get anywhere, no
+ matter what else you are doing.</para>
+
+ <para>In the following examples, <systemitem>fastws</systemitem> is the host
+ (interface) name of a high-performance workstation, and
+ <systemitem>freebox</systemitem> is the host (interface) name of a FreeBSD
+ system with a lower-performance Ethernet adapter. Also,
+ <filename>/sharedfs</filename> will be the exported NFS
+ file system (see &man.exports.5;), and
+ <filename>/project</filename> will be the mount point on the
+ client for the exported file system. In all cases, note that
+ additional options, such as <option>hard</option> or
+ <option>soft</option> and <option>bg</option> may be desirable in
+ your application.</para>
+
+ <para>Examples for the FreeBSD system (<systemitem>freebox</systemitem>)
+ as the client in <filename>/etc/fstab</filename> on
+ <systemitem>freebox</systemitem>:</para>
+
+ <programlisting>fastws:/sharedfs /project nfs rw,-r=1024 0 0</programlisting>
+
+ <para>As a manual mount command on <systemitem>freebox</systemitem>:</para>
+
+ <screen>&prompt.root; <userinput>mount -t nfs -o -r=1024 fastws:/sharedfs /project</userinput></screen>
+
+ <para>Examples for the FreeBSD system as the server in
+ <filename>/etc/fstab</filename> on
+ <systemitem>fastws</systemitem>:</para>
+
+ <programlisting>freebox:/sharedfs /project nfs rw,-w=1024 0 0</programlisting>
+
+ <para>As a manual mount command on <systemitem>fastws</systemitem>:</para>
+
+ <screen>&prompt.root; <userinput>mount -t nfs -o -w=1024 freebox:/sharedfs /project</userinput></screen>
+
+ <para>Nearly any 16-bit Ethernet adapter will allow operation
+ without the above restrictions on the read or write size.</para>
+
+ <para>For anyone who cares, here is what happens when the
+ failure occurs, which also explains why it is unrecoverable.
+ NFS typically works with a <quote>block</quote> size of
+ 8&nbsp;K (though it may do fragments of smaller sizes). Since
+ the maximum Ethernet packet is around 1500&nbsp;bytes, the NFS
+ <quote>block</quote> gets split into multiple Ethernet
+ packets, even though it is still a single unit to the
+ upper-level code, and must be received, assembled, and
+ <emphasis>acknowledged</emphasis> as a unit. The
+ high-performance workstations can pump out the packets which
+ comprise the NFS unit one right after the other, just as close
+ together as the standard allows. On the smaller, lower
+ capacity cards, the later packets overrun the earlier packets
+ of the same unit before they can be transferred to the host
+ and the unit as a whole cannot be reconstructed or
+ acknowledged. As a result, the workstation will time out and
+ try again, but it will try again with the entire 8&nbsp;K
+ unit, and the process will be repeated, ad infinitum.</para>
+
+ <para>By keeping the unit size below the Ethernet packet size
+ limitation, we ensure that any complete Ethernet packet
+ received can be acknowledged individually, avoiding the
+ deadlock situation.</para>
+
+ <para>Overruns may still occur when a high-performance
+ workstations is slamming data out to a PC system, but with the
+ better cards, such overruns are not guaranteed on NFS
+ <quote>units</quote>. When an overrun occurs, the units
+ affected will be retransmitted, and there will be a fair
+ chance that they will be received, assembled, and
+ acknowledged.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-nis">
+ <info><title>Network Information System (NIS/YP)</title>
+ <authorgroup>
+ <author><personname><firstname>Bill</firstname><surname>Swingle</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Eric</firstname><surname>Ogren</surname></personname><contrib>Enhanced by </contrib></author>
+ <author><personname><firstname>Udo</firstname><surname>Erdelhoff</surname></personname></author>
+ </authorgroup>
+ </info>
+
+
+ <sect2>
+ <title>What Is It?</title>
+ <indexterm><primary>NIS</primary></indexterm>
+ <indexterm><primary>Solaris</primary></indexterm>
+ <indexterm><primary>HP-UX</primary></indexterm>
+ <indexterm><primary>AIX</primary></indexterm>
+ <indexterm><primary>Linux</primary></indexterm>
+ <indexterm><primary>NetBSD</primary></indexterm>
+ <indexterm><primary>OpenBSD</primary></indexterm>
+
+ <para><acronym role="Network Information System">NIS</acronym>,
+ which stands for Network Information Services, was developed
+ by Sun Microsystems to centralize administration of &unix;
+ (originally &sunos;) systems. It has now essentially become
+ an industry standard; all major &unix; like systems
+ (&solaris;, HP-UX, &aix;, Linux, NetBSD, OpenBSD, FreeBSD,
+ etc) support <acronym role="Network Information System">NIS</acronym>.</para>
+
+ <indexterm><primary>yellow pages</primary><see>NIS</see></indexterm>
+
+ <para><acronym role="Network Information System">NIS</acronym>
+ was formerly known as Yellow Pages, but because of trademark
+ issues, Sun changed the name. The old term (and yp) is still
+ often seen and used.</para>
+
+ <indexterm>
+ <primary>NIS</primary>
+ <secondary>domains</secondary>
+ </indexterm>
+
+ <para>It is a RPC-based client/server system that allows a group
+ of machines within an NIS domain to share a common set of
+ configuration files. This permits a system administrator to
+ set up NIS client systems with only minimal configuration data
+ and add, remove or modify configuration data from a single
+ location.</para>
+
+ <indexterm><primary>Windows NT</primary></indexterm>
+
+ <para>It is similar to the &windowsnt; domain system; although
+ the internal implementation of the two are not at all similar,
+ the basic functionality can be compared.</para>
+ </sect2>
+
+ <sect2>
+ <title>Terms/Processes You Should Know</title>
+
+ <para>There are several terms and several important user
+ processes that you will come across when attempting to
+ implement NIS on FreeBSD, whether you are trying to create an
+ NIS server or act as an NIS client:</para>
+
+ <indexterm>
+ <primary><application>rpcbind</application></primary>
+ </indexterm>
+ <indexterm>
+ <primary><application>portmap</application></primary>
+ </indexterm>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="3*"/>
+
+ <thead>
+ <row>
+ <entry>Term</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>NIS domainname</entry>
+
+ <entry>An NIS master server and all of its clients
+ (including its slave servers) have a NIS domainname.
+ Similar to an &windowsnt; domain name, the NIS
+ domainname does not have anything to do with
+ <acronym>DNS</acronym>.</entry>
+ </row>
+ <row>
+ <entry><application>rpcbind</application></entry>
+
+ <entry>Must be running in order to enable
+ <acronym>RPC</acronym> (Remote Procedure Call, a
+ network protocol used by NIS). If
+ <application>rpcbind</application> is not running, it
+ will be impossible to run an NIS server, or to act as
+ an NIS client (Under &os;&nbsp;4.X
+ <application>portmap</application> is used in place of
+ <application>rpcbind</application>).</entry>
+ </row>
+ <row>
+ <entry><application>ypbind</application></entry>
+
+ <entry><quote>Binds</quote> an NIS client to its NIS
+ server. It will take the NIS domainname from the
+ system, and using <acronym>RPC</acronym>, connect to
+ the server. <application>ypbind</application> is the
+ core of client-server communication in an NIS
+ environment; if <application>ypbind</application> dies
+ on a client machine, it will not be able to access the
+ NIS server.</entry>
+ </row>
+ <row>
+ <entry><application>ypserv</application></entry>
+ <entry>Should only be running on NIS servers; this is
+ the NIS server process itself. If &man.ypserv.8;
+ dies, then the server will no longer be able to
+ respond to NIS requests (hopefully, there is a slave
+ server to take over for it). There are some
+ implementations of NIS (but not the FreeBSD one), that
+ do not try to reconnect to another server if the
+ server it used before dies. Often, the only thing
+ that helps in this case is to restart the server
+ process (or even the whole server) or the
+ <application>ypbind</application> process on the
+ client.
+ </entry>
+ </row>
+ <row>
+ <entry><application>rpc.yppasswdd</application></entry>
+ <entry>Another process that should only be running on
+ NIS master servers; this is a daemon that will allow NIS
+ clients to change their NIS passwords. If this daemon
+ is not running, users will have to login to the NIS
+ master server and change their passwords there.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ <!-- XXX Missing: rpc.ypxfrd (not important, though) May only run
+ on the master -->
+
+ </sect2>
+
+ <sect2>
+ <title>How Does It Work?</title>
+
+ <para>There are three types of hosts in an NIS environment:
+ master servers, slave servers, and clients. Servers act as a
+ central repository for host configuration information. Master
+ servers hold the authoritative copy of this information, while
+ slave servers mirror this information for redundancy. Clients
+ rely on the servers to provide this information to
+ them.</para>
+
+ <para>Information in many files can be shared in this manner.
+ The <filename>master.passwd</filename>,
+ <filename>group</filename>, and <filename>hosts</filename>
+ files are commonly shared via NIS. Whenever a process on a
+ client needs information that would normally be found in these
+ files locally, it makes a query to the NIS server that it is
+ bound to instead.</para>
+
+ <sect3>
+ <title>Machine Types</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>A <emphasis>NIS master server</emphasis><indexterm><primary>NIS</primary><secondary>master server</secondary></indexterm>. This
+ server, analogous to a &windowsnt; primary domain
+ controller, maintains the files used by all of the NIS
+ clients. The <filename>passwd</filename>,
+ <filename>group</filename>, and other various files used
+ by the NIS clients live on the master server.</para>
+
+ <note><para>It is possible for one machine to be an NIS
+ master server for more than one NIS domain. However,
+ this will not be covered in this introduction, which
+ assumes a relatively small-scale NIS
+ environment.</para></note>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>NIS slave servers</emphasis><indexterm><primary>NIS</primary><secondary>slave server</secondary></indexterm>. Similar to
+ the &windowsnt; backup domain controllers, NIS slave
+ servers maintain copies of the NIS master's data files.
+ NIS slave servers provide the redundancy, which is
+ needed in important environments. They also help to
+ balance the load of the master server: NIS Clients
+ always attach to the NIS server whose response they get
+ first, and this includes slave-server-replies.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>NIS clients</emphasis><indexterm><primary>NIS</primary><secondary>client</secondary></indexterm>. NIS clients, like
+ most &windowsnt; workstations, authenticate against the
+ NIS server (or the &windowsnt; domain controller in the
+ &windowsnt; workstations case) to log on.</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Using NIS/YP</title>
+
+ <para>This section will deal with setting up a sample NIS
+ environment.</para>
+
+ <note><para>This section assumes that you are running
+ FreeBSD&nbsp;3.3 or later. The instructions given here will
+ <emphasis>probably</emphasis> work for any version of FreeBSD
+ greater than 3.0, but there are no guarantees that this is
+ true.</para></note>
+
+
+ <sect3>
+ <title>Planning</title>
+
+ <para>Let us assume that you are the administrator of a small
+ university lab. This lab, which consists of 15 FreeBSD
+ machines, currently has no centralized point of
+ administration; each machine has its own
+ <filename>/etc/passwd</filename> and
+ <filename>/etc/master.passwd</filename>. These files are
+ kept in sync with each other only through manual
+ intervention; currently, when you add a user to the lab, you
+ must run <command>adduser</command> on all 15 machines.
+ Clearly, this has to change, so you have decided to convert
+ the lab to use NIS, using two of the machines as
+ servers.</para>
+
+ <para>Therefore, the configuration of the lab now looks something
+ like:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Machine name</entry>
+ <entry>IP address</entry>
+ <entry>Machine role</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><systemitem>ellington</systemitem></entry>
+ <entry><systemitem class="ipaddress">10.0.0.2</systemitem></entry>
+ <entry>NIS master</entry>
+ </row>
+ <row>
+ <entry><systemitem>coltrane</systemitem></entry>
+ <entry><systemitem class="ipaddress">10.0.0.3</systemitem></entry>
+ <entry>NIS slave</entry>
+ </row>
+ <row>
+ <entry><systemitem>basie</systemitem></entry>
+ <entry><systemitem class="ipaddress">10.0.0.4</systemitem></entry>
+ <entry>Faculty workstation</entry>
+ </row>
+ <row>
+ <entry><systemitem>bird</systemitem></entry>
+ <entry><systemitem class="ipaddress">10.0.0.5</systemitem></entry>
+ <entry>Client machine</entry>
+ </row>
+ <row>
+ <entry><systemitem>cli[1-11]</systemitem></entry>
+ <entry><systemitem class="ipaddress">10.0.0.[6-17]</systemitem></entry>
+ <entry>Other client machines</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>If you are setting up a NIS scheme for the first time, it
+ is a good idea to think through how you want to go about it. No
+ matter what the size of your network, there are a few decisions
+ that need to be made.</para>
+
+ <sect4>
+ <title>Choosing a NIS Domain Name</title>
+
+ <indexterm>
+ <primary>NIS</primary>
+ <secondary>domainname</secondary>
+ </indexterm>
+ <para>This might not be the <quote>domainname</quote> that
+ you are used to. It is more accurately called the
+ <quote>NIS domainname</quote>. When a client broadcasts
+ its requests for info, it includes the name of the NIS
+ domain that it is part of. This is how multiple servers
+ on one network can tell which server should answer which
+ request. Think of the NIS domainname as the name for a
+ group of hosts that are related in some way.</para>
+
+ <para>Some organizations choose to use their Internet
+ domainname for their NIS domainname. This is not
+ recommended as it can cause confusion when trying to debug
+ network problems. The NIS domainname should be unique
+ within your network and it is helpful if it describes the
+ group of machines it represents. For example, the Art
+ department at Acme Inc. might be in the
+ <quote>acme-art</quote> NIS domain. For this example,
+ assume you have chosen the name
+ <literal>test-domain</literal>.</para>
+
+ <indexterm><primary>SunOS</primary></indexterm>
+ <para>However, some operating systems (notably &sunos;) use
+ their NIS domain name as their Internet domain name. If one
+ or more machines on your network have this restriction, you
+ <emphasis>must</emphasis> use the Internet domain name as
+ your NIS domain name.</para>
+ </sect4>
+
+ <sect4>
+ <title>Physical Server Requirements</title>
+
+ <para>There are several things to keep in mind when choosing
+ a machine to use as a NIS server. One of the unfortunate
+ things about NIS is the level of dependency the clients
+ have on the server. If a client cannot contact the server
+ for its NIS domain, very often the machine becomes
+ unusable. The lack of user and group information causes
+ most systems to temporarily freeze up. With this in mind
+ you should make sure to choose a machine that will not be
+ prone to being rebooted regularly, or one that might be
+ used for development. The NIS server should ideally be a
+ stand alone machine whose sole purpose in life is to be an
+ NIS server. If you have a network that is not very
+ heavily used, it is acceptable to put the NIS server on a
+ machine running other services, just keep in mind that if
+ the NIS server becomes unavailable, it will affect
+ <emphasis>all</emphasis> of your NIS clients
+ adversely.</para>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>NIS Servers</title>
+
+ <para> The canonical copies of all NIS information are stored
+ on a single machine called the NIS master server. The
+ databases used to store the information are called NIS maps.
+ In FreeBSD, these maps are stored in
+ <filename>/var/yp/[domainname]</filename> where
+ <filename>[domainname]</filename> is the name of the NIS
+ domain being served. A single NIS server can support
+ several domains at once, therefore it is possible to have
+ several such directories, one for each supported domain.
+ Each domain will have its own independent set of
+ maps.</para>
+
+ <para>NIS master and slave servers handle all NIS requests
+ with the <command>ypserv</command> daemon.
+ <command>ypserv</command> is responsible for receiving
+ incoming requests from NIS clients, translating the
+ requested domain and map name to a path to the corresponding
+ database file and transmitting data from the database back
+ to the client.</para>
+
+ <sect4>
+ <title>Setting Up a NIS Master Server</title>
+ <indexterm>
+ <primary>NIS</primary>
+ <secondary>server configuration</secondary>
+ </indexterm>
+ <para>Setting up a master NIS server can be relatively
+ straight forward, depending on your needs. FreeBSD comes
+ with support for NIS out-of-the-box. All you need is to
+ add the following lines to
+ <filename>/etc/rc.conf</filename>, and FreeBSD will do the
+ rest for you.</para>
+
+ <procedure>
+ <step>
+ <para><programlisting>nisdomainname="test-domain"</programlisting>
+ This line will set the NIS domainname to
+ <literal>test-domain</literal>
+ upon network setup (e.g. after reboot).</para>
+ </step>
+ <step>
+ <para><programlisting>nis_server_enable="YES"</programlisting>
+ This will tell FreeBSD to start up the NIS server processes
+ when the networking is next brought up.</para>
+ </step>
+ <step>
+ <para><programlisting>nis_yppasswdd_enable="YES"</programlisting>
+ This will enable the <command>rpc.yppasswdd</command>
+ daemon which, as mentioned above, will allow users to
+ change their NIS password from a client machine.</para>
+ </step>
+ </procedure>
+
+ <note>
+ <para>Depending on your NIS setup, you may need to add
+ further entries. See the <link linkend="network-nis-server-is-client">section about NIS
+ servers that are also NIS clients</link>, below, for
+ details.</para>
+ </note>
+
+ <para>Now, all you have to do is to run the command
+ <command>/etc/netstart</command> as superuser. It will
+ set up everything for you, using the values you defined in
+ <filename>/etc/rc.conf</filename>.</para>
+ </sect4>
+
+ <sect4>
+ <title>Initializing the NIS Maps</title>
+ <indexterm>
+ <primary>NIS</primary>
+ <secondary>maps</secondary>
+ </indexterm>
+ <para>The <emphasis>NIS maps</emphasis> are database files,
+ that are kept in the <filename>/var/yp</filename>
+ directory. They are generated from configuration files in
+ the <filename>/etc</filename> directory of the NIS master,
+ with one exception: the
+ <filename>/etc/master.passwd</filename> file. This is for
+ a good reason, you do not want to propagate passwords to
+ your <systemitem class="username">root</systemitem> and other administrative
+ accounts to all the servers in the NIS domain. Therefore,
+ before we initialize the NIS maps, you should:</para>
+
+ <screen>&prompt.root; <userinput>cp /etc/master.passwd /var/yp/master.passwd</userinput>
+&prompt.root; <userinput>cd /var/yp</userinput>
+&prompt.root; <userinput>vi master.passwd</userinput></screen>
+
+ <para>You should remove all entries regarding system
+ accounts (<systemitem class="username">bin</systemitem>,
+ <systemitem class="username">tty</systemitem>, <systemitem class="username">kmem</systemitem>,
+ <systemitem class="username">games</systemitem>, etc), as well as any accounts
+ that you do not want to be propagated to the NIS clients
+ (for example <systemitem class="username">root</systemitem> and any other UID 0
+ (superuser) accounts).</para>
+
+ <note><para>Make sure the
+ <filename>/var/yp/master.passwd</filename> is neither group
+ nor world readable (mode 600)! Use the
+ <command>chmod</command> command, if appropriate.</para></note>
+
+ <indexterm><primary>Tru64 UNIX</primary></indexterm>
+
+ <para>When you have finished, it is time to initialize the
+ NIS maps! FreeBSD includes a script named
+ <command>ypinit</command> to do this for you (see its
+ manual page for more information). Note that this script
+ is available on most &unix; Operating Systems, but not on
+ all. On Digital UNIX/Compaq Tru64 UNIX it is called
+ <command>ypsetup</command>. Because we are generating
+ maps for an NIS master, we are going to pass the
+ <option>-m</option> option to <command>ypinit</command>.
+ To generate the NIS maps, assuming you already performed
+ the steps above, run:</para>
+
+ <screen>ellington&prompt.root; <userinput>ypinit -m test-domain</userinput>
+Server Type: MASTER Domain: test-domain
+Creating an YP server will require that you answer a few questions.
+Questions will all be asked at the beginning of the procedure.
+Do you want this procedure to quit on non-fatal errors? [y/n: n] <userinput>n</userinput>
+Ok, please remember to go back and redo manually whatever fails.
+If you don't, something might not work.
+At this point, we have to construct a list of this domains YP servers.
+rod.darktech.org is already known as master server.
+Please continue to add any slave servers, one per line. When you are
+done with the list, type a &lt;control D&gt;.
+master server : ellington
+next host to add: <userinput>coltrane</userinput>
+next host to add: <userinput>^D</userinput>
+The current list of NIS servers looks like this:
+ellington
+coltrane
+Is this correct? [y/n: y] <userinput>y</userinput>
+
+[..output from map generation..]
+
+NIS Map update completed.
+ellington has been setup as an YP master server without any errors.</screen>
+
+ <para><command>ypinit</command> should have created
+ <filename>/var/yp/Makefile</filename> from
+ <filename>/var/yp/Makefile.dist</filename>.
+ When created, this file assumes that you are operating
+ in a single server NIS environment with only FreeBSD
+ machines. Since <literal>test-domain</literal> has
+ a slave server as well, you must edit
+ <filename>/var/yp/Makefile</filename>:</para>
+
+ <screen>ellington&prompt.root; <userinput>vi /var/yp/Makefile</userinput></screen>
+
+ <para>You should comment out the line that says</para>
+
+ <programlisting>NOPUSH = "True"</programlisting>
+
+ <para>(if it is not commented out already).</para>
+ </sect4>
+
+ <sect4>
+ <title>Setting up a NIS Slave Server</title>
+ <indexterm>
+ <primary>NIS</primary>
+ <secondary>slave server</secondary>
+ </indexterm>
+ <para>Setting up an NIS slave server is even more simple than
+ setting up the master. Log on to the slave server and edit the
+ file <filename>/etc/rc.conf</filename> as you did before.
+ The only difference is that we now must use the
+ <option>-s</option> option when running <command>ypinit</command>.
+ The <option>-s</option> option requires the name of the NIS
+ master be passed to it as well, so our command line looks
+ like:</para>
+
+ <screen>coltrane&prompt.root; <userinput>ypinit -s ellington test-domain</userinput>
+
+Server Type: SLAVE Domain: test-domain Master: ellington
+
+Creating an YP server will require that you answer a few questions.
+Questions will all be asked at the beginning of the procedure.
+
+Do you want this procedure to quit on non-fatal errors? [y/n: n] <userinput>n</userinput>
+
+Ok, please remember to go back and redo manually whatever fails.
+If you don't, something might not work.
+There will be no further questions. The remainder of the procedure
+should take a few minutes, to copy the databases from ellington.
+Transferring netgroup...
+ypxfr: Exiting: Map successfully transferred
+Transferring netgroup.byuser...
+ypxfr: Exiting: Map successfully transferred
+Transferring netgroup.byhost...
+ypxfr: Exiting: Map successfully transferred
+Transferring master.passwd.byuid...
+ypxfr: Exiting: Map successfully transferred
+Transferring passwd.byuid...
+ypxfr: Exiting: Map successfully transferred
+Transferring passwd.byname...
+ypxfr: Exiting: Map successfully transferred
+Transferring group.bygid...
+ypxfr: Exiting: Map successfully transferred
+Transferring group.byname...
+ypxfr: Exiting: Map successfully transferred
+Transferring services.byname...
+ypxfr: Exiting: Map successfully transferred
+Transferring rpc.bynumber...
+ypxfr: Exiting: Map successfully transferred
+Transferring rpc.byname...
+ypxfr: Exiting: Map successfully transferred
+Transferring protocols.byname...
+ypxfr: Exiting: Map successfully transferred
+Transferring master.passwd.byname...
+ypxfr: Exiting: Map successfully transferred
+Transferring networks.byname...
+ypxfr: Exiting: Map successfully transferred
+Transferring networks.byaddr...
+ypxfr: Exiting: Map successfully transferred
+Transferring netid.byname...
+ypxfr: Exiting: Map successfully transferred
+Transferring hosts.byaddr...
+ypxfr: Exiting: Map successfully transferred
+Transferring protocols.bynumber...
+ypxfr: Exiting: Map successfully transferred
+Transferring ypservers...
+ypxfr: Exiting: Map successfully transferred
+Transferring hosts.byname...
+ypxfr: Exiting: Map successfully transferred
+
+coltrane has been setup as an YP slave server without any errors.
+Don't forget to update map ypservers on ellington.</screen>
+
+ <para>You should now have a directory called
+ <filename>/var/yp/test-domain</filename>. Copies of the NIS
+ master server's maps should be in this directory. You will
+ need to make sure that these stay updated. The following
+ <filename>/etc/crontab</filename> entries on your slave
+ servers should do the job:</para>
+
+ <programlisting>20 * * * * root /usr/libexec/ypxfr passwd.byname
+21 * * * * root /usr/libexec/ypxfr passwd.byuid</programlisting>
+
+ <para>These two lines force the slave to sync its maps with
+ the maps on the master server. Although these entries are
+ not mandatory, since the master server attempts to ensure
+ any changes to its NIS maps are communicated to its slaves
+ and because password information is vital to systems
+ depending on the server, it is a good idea to force the
+ updates. This is more important on busy networks where map
+ updates might not always complete.</para>
+
+ <para>Now, run the command <command>/etc/netstart</command> on the
+ slave server as well, which again starts the NIS server.</para>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>NIS Clients</title>
+
+ <para> An NIS client establishes what is called a binding to a
+ particular NIS server using the
+ <command>ypbind</command> daemon.
+ <command>ypbind</command> checks the system's default
+ domain (as set by the <command>domainname</command> command),
+ and begins broadcasting RPC requests on the local network.
+ These requests specify the name of the domain for which
+ <command>ypbind</command> is attempting to establish a binding.
+ If a server that has been configured to serve the requested
+ domain receives one of the broadcasts, it will respond to
+ <command>ypbind</command>, which will record the server's
+ address. If there are several servers available (a master and
+ several slaves, for example), <command>ypbind</command> will
+ use the address of the first one to respond. From that point
+ on, the client system will direct all of its NIS requests to
+ that server. <command>ypbind</command> will
+ occasionally <quote>ping</quote> the server to make sure it is
+ still up and running. If it fails to receive a reply to one of
+ its pings within a reasonable amount of time,
+ <command>ypbind</command> will mark the domain as unbound and
+ begin broadcasting again in the hopes of locating another
+ server.</para>
+
+ <sect4>
+ <title>Setting Up a NIS Client</title>
+ <indexterm>
+ <primary>NIS</primary>
+ <secondary>client configuration</secondary>
+ </indexterm>
+ <para>Setting up a FreeBSD machine to be a NIS client is fairly
+ straightforward.</para>
+
+ <procedure>
+ <step>
+ <para>Edit the file <filename>/etc/rc.conf</filename> and
+ add the following lines in order to set the NIS domainname
+ and start <command>ypbind</command> upon network
+ startup:</para>
+
+ <programlisting>nisdomainname="test-domain"
+nis_client_enable="YES"</programlisting>
+ </step>
+
+ <step>
+ <para>To import all possible password entries from the NIS
+ server, remove all user accounts from your
+ <filename>/etc/master.passwd</filename> file and use
+ <command>vipw</command> to add the following line to
+ the end of the file:</para>
+
+ <programlisting>+:::::::::</programlisting>
+
+ <note>
+ <para>This line will afford anyone with a valid account in
+ the NIS server's password maps an account. There are
+ many ways to configure your NIS client by changing this
+ line. See the <link linkend="network-netgroups">netgroups
+ section</link> below for more information.
+ For more detailed reading see O'Reilly's book on
+ <literal>Managing NFS and NIS</literal>.</para>
+ </note>
+
+ <note>
+ <para>You should keep at least one local account (i.e.
+ not imported via NIS) in your
+ <filename>/etc/master.passwd</filename> and this
+ account should also be a member of the group
+ <systemitem class="groupname">wheel</systemitem>. If there is something
+ wrong with NIS, this account can be used to log in
+ remotely, become <systemitem class="username">root</systemitem>, and fix things.</para>
+ </note>
+ </step>
+
+ <step>
+ <para>To import all possible group entries from the NIS
+ server, add this line to your
+ <filename>/etc/group</filename> file:</para>
+
+ <programlisting>+:*::</programlisting>
+ </step>
+ </procedure>
+
+ <para>After completing these steps, you should be able to run
+ <command>ypcat passwd</command> and see the NIS server's
+ passwd map.</para>
+ </sect4>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>NIS Security</title>
+
+ <para>In general, any remote user can issue an RPC to
+ &man.ypserv.8; and retrieve the contents of your NIS maps,
+ provided the remote user knows your domainname. To prevent
+ such unauthorized transactions, &man.ypserv.8; supports a
+ feature called <quote>securenets</quote> which can be used to
+ restrict access to a given set of hosts. At startup,
+ &man.ypserv.8; will attempt to load the securenets information
+ from a file called
+ <filename>/var/yp/securenets</filename>.</para>
+
+ <note>
+ <para>This path varies depending on the path specified with the
+ <option>-p</option> option. This file contains entries that
+ consist of a network specification and a network mask separated
+ by white space. Lines starting with <quote>#</quote> are
+ considered to be comments. A sample securenets file might look
+ like this:</para>
+ </note>
+
+ <programlisting># allow connections from local host -- mandatory
+127.0.0.1 255.255.255.255
+# allow connections from any host
+# on the 192.168.128.0 network
+192.168.128.0 255.255.255.0
+# allow connections from any host
+# between 10.0.0.0 to 10.0.15.255
+# this includes the machines in the testlab
+10.0.0.0 255.255.240.0</programlisting>
+
+ <para>If &man.ypserv.8; receives a request from an address that
+ matches one of these rules, it will process the request
+ normally. If the address fails to match a rule, the request
+ will be ignored and a warning message will be logged. If the
+ <filename>/var/yp/securenets</filename> file does not exist,
+ <command>ypserv</command> will allow connections from any
+ host.</para>
+
+ <para>The <command>ypserv</command> program also has support for
+ Wietse Venema's <application>TCP Wrapper</application> package.
+ This allows the administrator to use the
+ <application>TCP Wrapper</application> configuration files for
+ access control instead of
+ <filename>/var/yp/securenets</filename>.</para>
+
+ <note>
+ <para>While both of these access control mechanisms provide some
+ security, they, like the privileged port test, are
+ vulnerable to <quote>IP spoofing</quote> attacks. All
+ NIS-related traffic should be blocked at your firewall.</para>
+
+ <para>Servers using <filename>/var/yp/securenets</filename>
+ may fail to serve legitimate NIS clients with archaic TCP/IP
+ implementations. Some of these implementations set all
+ host bits to zero when doing broadcasts and/or fail to
+ observe the subnet mask when calculating the broadcast
+ address. While some of these problems can be fixed by
+ changing the client configuration, other problems may force
+ the retirement of the client systems in question or the
+ abandonment of <filename>/var/yp/securenets</filename>.</para>
+
+ <para>Using <filename>/var/yp/securenets</filename> on a
+ server with such an archaic implementation of TCP/IP is a
+ really bad idea and will lead to loss of NIS functionality
+ for large parts of your network.</para>
+
+ <indexterm><primary>TCP Wrappers</primary></indexterm>
+ <para>The use of the <application>TCP Wrapper</application>
+ package increases the latency of your NIS server. The
+ additional delay may be long enough to cause timeouts in
+ client programs, especially in busy networks or with slow
+ NIS servers. If one or more of your client systems
+ suffers from these symptoms, you should convert the client
+ systems in question into NIS slave servers and force them
+ to bind to themselves.</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Barring Some Users from Logging On</title>
+
+ <para>In our lab, there is a machine <systemitem>basie</systemitem> that
+ is supposed to be a faculty only workstation. We do not want
+ to take this machine out of the NIS domain, yet the
+ <filename>passwd</filename> file on the master NIS server
+ contains accounts for both faculty and students. What can we
+ do?</para>
+
+ <para>There is a way to bar specific users from logging on to a
+ machine, even if they are present in the NIS database. To do
+ this, all you must do is add
+ <literal>-username</literal> to the
+ end of the <filename>/etc/master.passwd</filename> file on the
+ client machine, where <replaceable>username</replaceable> is
+ the username of the user you wish to bar from logging in.
+ This should preferably be done using <command>vipw</command>,
+ since <command>vipw</command> will sanity check your changes
+ to <filename>/etc/master.passwd</filename>, as well as
+ automatically rebuild the password database when you finish
+ editing. For example, if we wanted to bar user
+ <systemitem class="username">bill</systemitem> from logging on to
+ <systemitem>basie</systemitem> we would:</para>
+
+ <screen>basie&prompt.root; <userinput>vipw</userinput>
+<userinput>[add -bill to the end, exit]</userinput>
+vipw: rebuilding the database...
+vipw: done
+
+basie&prompt.root; <userinput>cat /etc/master.passwd</userinput>
+
+root:[password]:0:0::0:0:The super-user:/root:/bin/csh
+toor:[password]:0:0::0:0:The other super-user:/root:/bin/sh
+daemon:*:1:1::0:0:Owner of many system processes:/root:/sbin/nologin
+operator:*:2:5::0:0:System &amp;:/:/sbin/nologin
+bin:*:3:7::0:0:Binaries Commands and Source,,,:/:/sbin/nologin
+tty:*:4:65533::0:0:Tty Sandbox:/:/sbin/nologin
+kmem:*:5:65533::0:0:KMem Sandbox:/:/sbin/nologin
+games:*:7:13::0:0:Games pseudo-user:/usr/games:/sbin/nologin
+news:*:8:8::0:0:News Subsystem:/:/sbin/nologin
+man:*:9:9::0:0:Mister Man Pages:/usr/share/man:/sbin/nologin
+bind:*:53:53::0:0:Bind Sandbox:/:/sbin/nologin
+uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/libexec/uucp/uucico
+xten:*:67:67::0:0:X-10 daemon:/usr/local/xten:/sbin/nologin
+pop:*:68:6::0:0:Post Office Owner:/nonexistent:/sbin/nologin
+nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/sbin/nologin
++:::::::::
+-bill
+
+basie&prompt.root;</screen>
+ </sect2>
+
+ <sect2 xml:id="network-netgroups">
+ <info><title>Using Netgroups</title>
+ <authorgroup>
+ <author><personname><firstname>Udo</firstname><surname>Erdelhoff</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>netgroups</primary></indexterm>
+
+ <para>The method shown in the previous section works reasonably
+ well if you need special rules for a very small number of
+ users and/or machines. On larger networks, you
+ <emphasis>will</emphasis> forget to bar some users from logging
+ onto sensitive machines, or you may even have to modify each
+ machine separately, thus losing the main benefit of NIS:
+ <emphasis>centralized</emphasis> administration.</para>
+
+ <para>The NIS developers' solution for this problem is called
+ <emphasis>netgroups</emphasis>. Their purpose and semantics
+ can be compared to the normal groups used by &unix; file
+ systems. The main differences are the lack of a numeric ID
+ and the ability to define a netgroup by including both user
+ accounts and other netgroups.</para>
+
+ <para>Netgroups were developed to handle large, complex networks
+ with hundreds of users and machines. On one hand, this is
+ a Good Thing if you are forced to deal with such a situation.
+ On the other hand, this complexity makes it almost impossible to
+ explain netgroups with really simple examples. The example
+ used in the remainder of this section demonstrates this
+ problem.</para>
+
+ <para>Let us assume that your successful introduction of NIS in
+ your laboratory caught your superiors' interest. Your next
+ job is to extend your NIS domain to cover some of the other
+ machines on campus. The two tables contain the names of the
+ new users and new machines as well as brief descriptions of
+ them.</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>User Name(s)</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><systemitem class="username">alpha</systemitem>, <systemitem class="username">beta</systemitem></entry>
+ <entry>Normal employees of the IT department</entry>
+ </row>
+
+ <row>
+ <entry><systemitem class="username">charlie</systemitem>, <systemitem class="username">delta</systemitem></entry>
+ <entry>The new apprentices of the IT department</entry>
+ </row>
+
+ <row>
+ <entry><systemitem class="username">echo</systemitem>, <systemitem class="username">foxtrott</systemitem>, <systemitem class="username">golf</systemitem>, ...</entry>
+ <entry>Ordinary employees</entry>
+ </row>
+
+ <row>
+ <entry><systemitem class="username">able</systemitem>, <systemitem class="username">baker</systemitem>, ...</entry>
+ <entry>The current interns</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Machine Name(s)</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <!-- Names taken from "Good Omens" by Neil Gaiman and Terry
+ Pratchett. Many thanks for a brilliant book. -->
+
+ <entry><systemitem>war</systemitem>, <systemitem>death</systemitem>,
+ <systemitem>famine</systemitem>,
+ <systemitem>pollution</systemitem></entry>
+ <entry>Your most important servers. Only the IT
+ employees are allowed to log onto these
+ machines.</entry>
+ </row>
+ <row>
+ <!-- gluttony was omitted because it was too fat -->
+
+ <entry><systemitem>pride</systemitem>, <systemitem>greed</systemitem>,
+ <systemitem>envy</systemitem>, <systemitem>wrath</systemitem>,
+ <systemitem>lust</systemitem>, <systemitem>sloth</systemitem></entry>
+ <entry>Less important servers. All members of the IT
+ department are allowed to login onto these
+ machines.</entry>
+ </row>
+
+ <row>
+ <entry><systemitem>one</systemitem>, <systemitem>two</systemitem>,
+ <systemitem>three</systemitem>, <systemitem>four</systemitem>,
+ ...</entry>
+
+ <entry>Ordinary workstations. Only the
+ <emphasis>real</emphasis> employees are allowed to use
+ these machines.</entry>
+ </row>
+
+ <row>
+ <entry><systemitem>trashcan</systemitem></entry>
+ <entry>A very old machine without any critical data.
+ Even the intern is allowed to use this box.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>If you tried to implement these restrictions by separately
+ blocking each user, you would have to add one
+ <literal>-user</literal> line to
+ each system's <filename>passwd</filename> for each user who is
+ not allowed to login onto that system. If you forget just one
+ entry, you could be in trouble. It may be feasible to do this
+ correctly during the initial setup, however you
+ <emphasis>will</emphasis> eventually forget to add the lines
+ for new users during day-to-day operations. After all, Murphy
+ was an optimist.</para>
+
+ <para>Handling this situation with netgroups offers several
+ advantages. Each user need not be handled separately; you
+ assign a user to one or more netgroups and allow or forbid
+ logins for all members of the netgroup. If you add a new
+ machine, you will only have to define login restrictions for
+ netgroups. If a new user is added, you will only have to add
+ the user to one or more netgroups. Those changes are
+ independent of each other: no more <quote>for each combination
+ of user and machine do...</quote> If your NIS setup is planned
+ carefully, you will only have to modify exactly one central
+ configuration file to grant or deny access to machines.</para>
+
+ <para>The first step is the initialization of the NIS map
+ netgroup. FreeBSD's &man.ypinit.8; does not create this map by
+ default, but its NIS implementation will support it once it has
+ been created. To create an empty map, simply type</para>
+
+ <screen>ellington&prompt.root; <userinput>vi /var/yp/netgroup</userinput></screen>
+
+ <para>and start adding content. For our example, we need at
+ least four netgroups: IT employees, IT apprentices, normal
+ employees and interns.</para>
+
+ <programlisting>IT_EMP (,alpha,test-domain) (,beta,test-domain)
+IT_APP (,charlie,test-domain) (,delta,test-domain)
+USERS (,echo,test-domain) (,foxtrott,test-domain) \
+ (,golf,test-domain)
+INTERNS (,able,test-domain) (,baker,test-domain)</programlisting>
+
+ <para><literal>IT_EMP</literal>, <literal>IT_APP</literal> etc.
+ are the names of the netgroups. Each bracketed group adds
+ one or more user accounts to it. The three fields inside a
+ group are:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>The name of the host(s) where the following items are
+ valid. If you do not specify a hostname, the entry is
+ valid on all hosts. If you do specify a hostname, you
+ will enter a realm of darkness, horror and utter confusion.</para>
+ </listitem>
+
+ <listitem>
+ <para>The name of the account that belongs to this
+ netgroup.</para>
+ </listitem>
+
+ <listitem>
+ <para>The NIS domain for the account. You can import
+ accounts from other NIS domains into your netgroup if you
+ are one of the unlucky fellows with more than one NIS
+ domain.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>Each of these fields can contain wildcards. See
+ &man.netgroup.5; for details.</para>
+
+ <note>
+ <indexterm><primary>netgroups</primary></indexterm>
+ <para>Netgroup names longer than 8 characters should not be
+ used, especially if you have machines running other
+ operating systems within your NIS domain. The names are
+ case sensitive; using capital letters for your netgroup
+ names is an easy way to distinguish between user, machine
+ and netgroup names.</para>
+
+ <para>Some NIS clients (other than FreeBSD) cannot handle
+ netgroups with a large number of entries. For example, some
+ older versions of &sunos; start to cause trouble if a netgroup
+ contains more than 15 <emphasis>entries</emphasis>. You can
+ circumvent this limit by creating several sub-netgroups with
+ 15 users or less and a real netgroup that consists of the
+ sub-netgroups:</para>
+
+ <programlisting>BIGGRP1 (,joe1,domain) (,joe2,domain) (,joe3,domain) [...]
+BIGGRP2 (,joe16,domain) (,joe17,domain) [...]
+BIGGRP3 (,joe31,domain) (,joe32,domain)
+BIGGROUP BIGGRP1 BIGGRP2 BIGGRP3</programlisting>
+
+ <para>You can repeat this process if you need more than 225
+ users within a single netgroup.</para>
+ </note>
+
+ <para>Activating and distributing your new NIS map is
+ easy:</para>
+
+ <screen>ellington&prompt.root; <userinput>cd /var/yp</userinput>
+ellington&prompt.root; <userinput>make</userinput></screen>
+
+ <para>This will generate the three NIS maps
+ <filename>netgroup</filename>,
+ <filename>netgroup.byhost</filename> and
+ <filename>netgroup.byuser</filename>. Use &man.ypcat.1; to
+ check if your new NIS maps are available:</para>
+
+ <screen>ellington&prompt.user; <userinput>ypcat -k netgroup</userinput>
+ellington&prompt.user; <userinput>ypcat -k netgroup.byhost</userinput>
+ellington&prompt.user; <userinput>ypcat -k netgroup.byuser</userinput></screen>
+
+ <para>The output of the first command should resemble the
+ contents of <filename>/var/yp/netgroup</filename>. The second
+ command will not produce output if you have not specified
+ host-specific netgroups. The third command can be used to
+ get the list of netgroups for a user.</para>
+
+ <para>The client setup is quite simple. To configure the server
+ <systemitem>war</systemitem>, you only have to start
+ &man.vipw.8; and replace the line</para>
+
+ <programlisting>+:::::::::</programlisting>
+
+ <para>with</para>
+
+ <programlisting>+@IT_EMP:::::::::</programlisting>
+
+ <para>Now, only the data for the users defined in the netgroup
+ <literal>IT_EMP</literal> is imported into
+ <systemitem>war</systemitem>'s password database and only
+ these users are allowed to login.</para>
+
+ <para>Unfortunately, this limitation also applies to the
+ <literal>~</literal> function of the shell and all routines
+ converting between user names and numerical user IDs. In
+ other words, <command>cd
+ ~user</command> will not work,
+ <command>ls -l</command> will show the numerical ID instead of
+ the username and <command>find . -user joe -print</command>
+ will fail with <errorname>No such user</errorname>. To fix
+ this, you will have to import all user entries
+ <emphasis>without allowing them to login onto your
+ servers</emphasis>.</para>
+
+ <para>This can be achieved by adding another line to
+ <filename>/etc/master.passwd</filename>. This line should
+ contain:</para>
+
+ <para><literal>+:::::::::/sbin/nologin</literal>, meaning
+ <quote>Import all entries but replace the shell with
+ <filename>/sbin/nologin</filename> in the imported
+ entries</quote>. You can replace any field in the
+ <literal>passwd</literal> entry by placing a default value in
+ your <filename>/etc/master.passwd</filename>.</para>
+
+ <!-- Been there, done that, got the scars to prove it - ue -->
+ <warning>
+ <para>Make sure that the line
+ <literal>+:::::::::/sbin/nologin</literal> is placed after
+ <literal>+@IT_EMP:::::::::</literal>. Otherwise, all user
+ accounts imported from NIS will have <filename>/sbin/nologin</filename> as their
+ login shell.</para>
+ </warning>
+
+ <para>After this change, you will only have to change one NIS
+ map if a new employee joins the IT department. You could use
+ a similar approach for the less important servers by replacing
+ the old <literal>+:::::::::</literal> in their local version
+ of <filename>/etc/master.passwd</filename> with something like
+ this:</para>
+
+ <programlisting>+@IT_EMP:::::::::
++@IT_APP:::::::::
++:::::::::/sbin/nologin</programlisting>
+
+ <para>The corresponding lines for the normal workstations
+ could be:</para>
+
+ <programlisting>+@IT_EMP:::::::::
++@USERS:::::::::
++:::::::::/sbin/nologin</programlisting>
+
+ <para>And everything would be fine until there is a policy
+ change a few weeks later: The IT department starts hiring
+ interns. The IT interns are allowed to use the normal
+ workstations and the less important servers; and the IT
+ apprentices are allowed to login onto the main servers. You
+ add a new netgroup <literal>IT_INTERN</literal>, add the new
+ IT interns to this netgroup and start to change the
+ configuration on each and every machine... As the old saying
+ goes: <quote>Errors in centralized planning lead to global
+ mess</quote>.</para>
+
+ <para>NIS' ability to create netgroups from other netgroups can
+ be used to prevent situations like these. One possibility
+ is the creation of role-based netgroups. For example, you
+ could create a netgroup called
+ <literal>BIGSRV</literal> to define the login
+ restrictions for the important servers, another netgroup
+ called <literal>SMALLSRV</literal> for the less
+ important servers and a third netgroup called
+ <literal>USERBOX</literal> for the normal
+ workstations. Each of these netgroups contains the netgroups
+ that are allowed to login onto these machines. The new
+ entries for your NIS map netgroup should look like this:</para>
+
+ <programlisting>BIGSRV IT_EMP IT_APP
+SMALLSRV IT_EMP IT_APP ITINTERN
+USERBOX IT_EMP ITINTERN USERS</programlisting>
+
+ <para>This method of defining login restrictions works
+ reasonably well if you can define groups of machines with
+ identical restrictions. Unfortunately, this is the exception
+ and not the rule. Most of the time, you will need the ability
+ to define login restrictions on a per-machine basis.</para>
+
+ <para>Machine-specific netgroup definitions are the other
+ possibility to deal with the policy change outlined above. In
+ this scenario, the <filename>/etc/master.passwd</filename> of
+ each box contains two lines starting with <quote>+</quote>.
+ The first of them adds a netgroup with the accounts allowed to
+ login onto this machine, the second one adds all other
+ accounts with <filename>/sbin/nologin</filename> as shell. It
+ is a good idea to use the <quote>ALL-CAPS</quote> version of
+ the machine name as the name of the netgroup. In other words,
+ the lines should look like this:</para>
+
+ <programlisting>+@<replaceable>BOXNAME</replaceable>:::::::::
++:::::::::/sbin/nologin</programlisting>
+
+ <para>Once you have completed this task for all your machines,
+ you will not have to modify the local versions of
+ <filename>/etc/master.passwd</filename> ever again. All
+ further changes can be handled by modifying the NIS map. Here
+ is an example of a possible netgroup map for this
+ scenario with some additional goodies:</para>
+
+ <programlisting># Define groups of users first
+IT_EMP (,alpha,test-domain) (,beta,test-domain)
+IT_APP (,charlie,test-domain) (,delta,test-domain)
+DEPT1 (,echo,test-domain) (,foxtrott,test-domain)
+DEPT2 (,golf,test-domain) (,hotel,test-domain)
+DEPT3 (,india,test-domain) (,juliet,test-domain)
+ITINTERN (,kilo,test-domain) (,lima,test-domain)
+D_INTERNS (,able,test-domain) (,baker,test-domain)
+#
+# Now, define some groups based on roles
+USERS DEPT1 DEPT2 DEPT3
+BIGSRV IT_EMP IT_APP
+SMALLSRV IT_EMP IT_APP ITINTERN
+USERBOX IT_EMP ITINTERN USERS
+#
+# And a groups for a special tasks
+# Allow echo and golf to access our anti-virus-machine
+SECURITY IT_EMP (,echo,test-domain) (,golf,test-domain)
+#
+# machine-based netgroups
+# Our main servers
+WAR BIGSRV
+FAMINE BIGSRV
+# User india needs access to this server
+POLLUTION BIGSRV (,india,test-domain)
+#
+# This one is really important and needs more access restrictions
+DEATH IT_EMP
+#
+# The anti-virus-machine mentioned above
+ONE SECURITY
+#
+# Restrict a machine to a single user
+TWO (,hotel,test-domain)
+# [...more groups to follow]</programlisting>
+
+ <para>If you are using some kind of database to manage your user
+ accounts, you should be able to create the first part of the
+ map with your database's report tools. This way, new users
+ will automatically have access to the boxes.</para>
+
+ <para>One last word of caution: It may not always be advisable
+ to use machine-based netgroups. If you are deploying a couple of
+ dozen or even hundreds of identical machines for student labs,
+ you should use role-based netgroups instead of machine-based
+ netgroups to keep the size of the NIS map within reasonable
+ limits.</para>
+ </sect2>
+
+ <sect2>
+ <title>Important Things to Remember</title>
+
+ <para>There are still a couple of things that you will need to do
+ differently now that you are in an NIS environment.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Every time you wish to add a user to the lab, you
+ must add it to the master NIS server <emphasis>only</emphasis>,
+ and <emphasis>you must remember to rebuild the NIS
+ maps</emphasis>. If you forget to do this, the new user will
+ not be able to login anywhere except on the NIS master.
+ For example, if we needed to add a new user
+ <systemitem class="username">jsmith</systemitem> to the lab, we would:</para>
+
+ <screen>&prompt.root; <userinput>pw useradd jsmith</userinput>
+&prompt.root; <userinput>cd /var/yp</userinput>
+&prompt.root; <userinput>make test-domain</userinput></screen>
+
+ <para>You could also run <command>adduser jsmith</command> instead
+ of <command>pw useradd jsmith</command>.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>Keep the administration accounts out of the
+ NIS maps</emphasis>. You do not want to be propagating
+ administrative accounts and passwords to machines that
+ will have users that should not have access to those
+ accounts.</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>Keep the NIS master and slave secure, and
+ minimize their downtime</emphasis>. If somebody either
+ hacks or simply turns off these machines, they have
+ effectively rendered many people without the ability to
+ login to the lab.</para>
+
+ <para>This is the chief weakness of any centralized administration
+ system. If you do
+ not protect your NIS servers, you will have a lot of angry
+ users!</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>NIS v1 Compatibility</title>
+
+ <para> FreeBSD's <application>ypserv</application> has some
+ support for serving NIS v1 clients. FreeBSD's NIS
+ implementation only uses the NIS v2 protocol, however other
+ implementations include support for the v1 protocol for
+ backwards compatibility with older systems. The
+ <application>ypbind</application> daemons supplied with these
+ systems will try to establish a binding to an NIS v1 server
+ even though they may never actually need it (and they may
+ persist in broadcasting in search of one even after they
+ receive a response from a v2 server). Note that while support
+ for normal client calls is provided, this version of
+ <application>ypserv</application> does not handle v1 map
+ transfer requests; consequently, it cannot be used as a master
+ or slave in conjunction with older NIS servers that only
+ support the v1 protocol. Fortunately, there probably are not
+ any such servers still in use today.</para>
+ </sect2>
+
+ <sect2 xml:id="network-nis-server-is-client">
+ <title>NIS Servers That Are Also NIS Clients</title>
+
+ <para> Care must be taken when running
+ <application>ypserv</application> in a multi-server domain
+ where the server machines are also NIS clients. It is
+ generally a good idea to force the servers to bind to
+ themselves rather than allowing them to broadcast bind
+ requests and possibly become bound to each other. Strange
+ failure modes can result if one server goes down and others
+ are dependent upon it. Eventually all the clients will time
+ out and attempt to bind to other servers, but the delay
+ involved can be considerable and the failure mode is still
+ present since the servers might bind to each other all over
+ again.</para>
+
+ <para>You can force a host to bind to a particular server by running
+ <command>ypbind</command> with the <option>-S</option>
+ flag. If you do not want to do this manually each time you
+ reboot your NIS server, you can add the following lines to
+ your <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>nis_client_enable="YES" # run client stuff as well
+nis_client_flags="-S <replaceable>NIS domain</replaceable>,<replaceable>server</replaceable>"</programlisting>
+
+ <para>See &man.ypbind.8; for further information.</para>
+ </sect2>
+
+ <sect2>
+ <title>Password Formats</title>
+ <indexterm>
+ <primary>NIS</primary>
+ <secondary>password formats</secondary>
+ </indexterm>
+ <para>One of the most common issues that people run into when trying
+ to implement NIS is password format compatibility. If your NIS
+ server is using DES encrypted passwords, it will only support
+ clients that are also using DES. For example, if you have
+ &solaris; NIS clients in your network, then you will almost certainly
+ need to use DES encrypted passwords.</para>
+
+ <para>To check which format your servers
+ and clients are using, look at <filename>/etc/login.conf</filename>.
+ If the host is configured to use DES encrypted passwords, then the
+ <literal>default</literal> class will contain an entry like this:</para>
+
+ <programlisting>default:\
+ :passwd_format=des:\
+ :copyright=/etc/COPYRIGHT:\
+ [Further entries elided]</programlisting>
+
+ <para>Other possible values for the <literal>passwd_format</literal>
+ capability include <literal>blf</literal> and <literal>md5</literal>
+ (for Blowfish and MD5 encrypted passwords, respectively).</para>
+
+ <para>If you have made changes to
+ <filename>/etc/login.conf</filename>, you will also need to
+ rebuild the login capability database, which is achieved by
+ running the following command as
+ <systemitem class="username">root</systemitem>:</para>
+
+ <screen>&prompt.root; <userinput>cap_mkdb /etc/login.conf</userinput></screen>
+
+ <note><para>The format of passwords already in
+ <filename>/etc/master.passwd</filename> will not be updated
+ until a user changes his password for the first time
+ <emphasis>after</emphasis> the login capability database is
+ rebuilt.</para></note>
+
+ <para>Next, in order to ensure that passwords are encrypted with
+ the format that you have chosen, you should also check that
+ the <literal>crypt_default</literal> in
+ <filename>/etc/auth.conf</filename> gives precedence to your
+ chosen password format. To do this, place the format that you
+ have chosen first in the list. For example, when using DES
+ encrypted passwords, the entry would be:</para>
+
+ <programlisting>crypt_default = des blf md5</programlisting>
+
+ <para>Having followed the above steps on each of the &os; based
+ NIS servers and clients, you can be sure that they all agree
+ on which password format is used within your network. If you
+ have trouble authenticating on an NIS client, this is a pretty
+ good place to start looking for possible problems. Remember:
+ if you want to deploy an NIS server for a heterogenous
+ network, you will probably have to use DES on all systems
+ because it is the lowest common standard.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-dhcp">
+ <info><title>Automatic Network Configuration (DHCP)</title>
+ <authorgroup>
+ <author><personname><firstname>Greg</firstname><surname>Sutter</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <sect2>
+ <title>What Is DHCP?</title>
+ <indexterm>
+ <primary>Dynamic Host Configuration Protocol</primary>
+ <see>DHCP</see>
+ </indexterm>
+ <indexterm>
+ <primary>Internet Software Consortium (ISC)</primary>
+ </indexterm>
+
+ <para>DHCP, the Dynamic Host Configuration Protocol, describes
+ the means by which a system can connect to a network and obtain the
+ necessary information for communication upon that network. FreeBSD
+ versions prior to 6.0 use the ISC (Internet Software
+ Consortium) DHCP client (&man.dhclient.8;) implementation.
+ Later versions use the OpenBSD <command>dhclient</command>
+ taken from OpenBSD&nbsp;3.7. All
+ information here regarding <command>dhclient</command> is for
+ use with either of the ISC or OpenBSD DHCP clients. The DHCP
+ server is the one included in the ISC distribution.</para>
+ </sect2>
+
+ <sect2>
+ <title>What This Section Covers</title>
+
+ <para>This section describes both the client-side components of the ISC and OpenBSD DHCP client and
+ server-side components of the ISC DHCP system. The
+ client-side program, <command>dhclient</command>, comes
+ integrated within FreeBSD, and the server-side portion is
+ available from the <package>net/isc-dhcp3-server</package> port. The
+ &man.dhclient.8;, &man.dhcp-options.5;, and
+ &man.dhclient.conf.5; manual pages, in addition to the
+ references below, are useful resources.</para>
+ </sect2>
+
+ <sect2>
+ <title>How It Works</title>
+ <indexterm><primary>UDP</primary></indexterm>
+ <para>When <command>dhclient</command>, the DHCP client, is
+ executed on the client machine, it begins broadcasting
+ requests for configuration information. By default, these
+ requests are on UDP port 68. The server replies on UDP 67,
+ giving the client an IP address and other relevant network
+ information such as netmask, router, and DNS servers. All of
+ this information comes in the form of a DHCP
+ <quote>lease</quote> and is only valid for a certain time
+ (configured by the DHCP server maintainer). In this manner,
+ stale IP addresses for clients no longer connected to the
+ network can be automatically reclaimed.</para>
+
+ <para>DHCP clients can obtain a great deal of information from
+ the server. An exhaustive list may be found in
+ &man.dhcp-options.5;.</para>
+ </sect2>
+
+ <sect2>
+ <title>FreeBSD Integration</title>
+
+ <para>&os; fully integrates the ISC or OpenBSD DHCP client,
+ <command>dhclient</command> (according to the &os; version you run). DHCP client support is provided
+ within both the installer and the base system, obviating the need
+ for detailed knowledge of network configurations on any network
+ that runs a DHCP server. <command>dhclient</command> has been
+ included in all FreeBSD distributions since 3.2.</para>
+ <indexterm>
+ <primary><application>sysinstall</application></primary>
+ </indexterm>
+
+ <para>DHCP is supported by
+ <application>sysinstall</application>. When configuring a
+ network interface within
+ <application>sysinstall</application>, the second question
+ asked is: <quote>Do you want to try DHCP configuration of
+ the interface?</quote>. Answering affirmatively will
+ execute <command>dhclient</command>, and if successful, will
+ fill in the network configuration information
+ automatically.</para>
+
+ <para>There are two things you must do to have your system use
+ DHCP upon startup:</para>
+ <indexterm>
+ <primary>DHCP</primary>
+ <secondary>requirements</secondary>
+ </indexterm>
+ <itemizedlist>
+ <listitem>
+ <para>Make sure that the <filename>bpf</filename>
+ device is compiled into your kernel. To do this, add
+ <literal>device bpf</literal> (<literal>pseudo-device
+ bpf</literal> under &os;&nbsp;4.X) to your kernel
+ configuration file, and rebuild the kernel. For more
+ information about building kernels, see <xref linkend="kernelconfig"/>.</para> <para>The
+ <filename>bpf</filename> device is already part of
+ the <filename>GENERIC</filename> kernel that is supplied
+ with FreeBSD, so if you do not have a custom kernel, you
+ should not need to create one in order to get DHCP
+ working.</para>
+ <note>
+ <para>For those who are particularly security conscious,
+ you should be warned that <filename>bpf</filename>
+ is also the device that allows packet sniffers to work
+ correctly (although they still have to be run as
+ <systemitem class="username">root</systemitem>). <filename>bpf</filename>
+ <emphasis>is</emphasis> required to use DHCP, but if
+ you are very sensitive about security, you probably
+ should not add <filename>bpf</filename> to your
+ kernel in the expectation that at some point in the
+ future you will be using DHCP.</para>
+ </note>
+ </listitem>
+ <listitem>
+ <para>Edit your <filename>/etc/rc.conf</filename> to
+ include the following:</para>
+
+ <programlisting>ifconfig_fxp0="DHCP"</programlisting>
+
+ <note>
+ <para>Be sure to replace <literal>fxp0</literal> with the
+ designation for the interface that you wish to dynamically
+ configure, as described in
+ <xref linkend="config-network-setup"/>.</para>
+ </note>
+
+ <para>If you are using a different location for
+ <command>dhclient</command>, or if you wish to pass additional
+ flags to <command>dhclient</command>, also include the
+ following (editing as necessary):</para>
+
+ <programlisting>dhcp_program="/sbin/dhclient"
+dhcp_flags=""</programlisting>
+ </listitem>
+ </itemizedlist>
+
+ <indexterm>
+ <primary>DHCP</primary>
+ <secondary>server</secondary>
+ </indexterm>
+ <para>The DHCP server, <application>dhcpd</application>, is included
+ as part of the <package>net/isc-dhcp3-server</package> port in the ports
+ collection. This port contains the ISC DHCP server and
+ documentation.</para>
+ </sect2>
+
+ <sect2>
+ <title>Files</title>
+ <indexterm>
+ <primary>DHCP</primary>
+ <secondary>configuration files</secondary>
+ </indexterm>
+ <itemizedlist>
+ <listitem><para><filename>/etc/dhclient.conf</filename></para>
+ <para><command>dhclient</command> requires a configuration file,
+ <filename>/etc/dhclient.conf</filename>. Typically the file
+ contains only comments, the defaults being reasonably sane. This
+ configuration file is described by the &man.dhclient.conf.5;
+ manual page.</para>
+ </listitem>
+
+ <listitem><para><filename>/sbin/dhclient</filename></para>
+ <para><command>dhclient</command> is statically linked and
+ resides in <filename>/sbin</filename>. The &man.dhclient.8;
+ manual page gives more information about
+ <command>dhclient</command>.</para>
+ </listitem>
+
+ <listitem><para><filename>/sbin/dhclient-script</filename></para>
+ <para><command>dhclient-script</command> is the FreeBSD-specific
+ DHCP client configuration script. It is described in
+ &man.dhclient-script.8;, but should not need any user
+ modification to function properly.</para>
+ </listitem>
+
+ <listitem><para><filename>/var/db/dhclient.leases</filename></para>
+ <para>The DHCP client keeps a database of valid leases in this
+ file, which is written as a log. &man.dhclient.leases.5;
+ gives a slightly longer description.</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>Further Reading</title>
+
+ <para>The DHCP protocol is fully described in
+ <link xlink:href="http://www.freesoft.org/CIE/RFC/2131/">RFC 2131</link>.
+ An informational resource has also been set up at
+ <uri xlink:href="http://www.dhcp.org/">http://www.dhcp.org/</uri>.</para>
+ </sect2>
+
+ <sect2 xml:id="network-dhcp-server">
+ <title>Installing and Configuring a DHCP Server</title>
+
+ <sect3>
+ <title>What This Section Covers</title>
+
+ <para>This section provides information on how to configure
+ a FreeBSD system to act as a DHCP server using the ISC
+ (Internet Software Consortium) implementation of the DHCP
+ suite.</para>
+
+ <para>The server portion of the suite is not provided as part of
+ FreeBSD, and so you will need to install the
+ <package>net/isc-dhcp3-server</package>
+ port to provide this service. See <xref linkend="ports"/> for
+ more information on using the Ports Collection.</para>
+ </sect3>
+
+ <sect3>
+ <title>DHCP Server Installation</title>
+ <indexterm>
+ <primary>DHCP</primary>
+ <secondary>installation</secondary>
+ </indexterm>
+ <para>In order to configure your FreeBSD system as a DHCP
+ server, you will need to ensure that the &man.bpf.4;
+ device is compiled into your kernel. To do this, add
+ <literal>device bpf</literal> (<literal>pseudo-device
+ bpf</literal> under &os;&nbsp;4.X) to your kernel
+ configuration file, and rebuild the kernel. For more
+ information about building kernels, see <xref linkend="kernelconfig"/>.</para>
+
+ <para>The <filename>bpf</filename> device is already
+ part of the <filename>GENERIC</filename> kernel that is
+ supplied with FreeBSD, so you do not need to create a custom
+ kernel in order to get DHCP working.</para>
+
+ <note>
+ <para>Those who are particularly security conscious
+ should note that <filename>bpf</filename>
+ is also the device that allows packet sniffers to work
+ correctly (although such programs still need privileged
+ access). <filename>bpf</filename>
+ <emphasis>is</emphasis> required to use DHCP, but if
+ you are very sensitive about security, you probably
+ should not include <filename>bpf</filename> in your
+ kernel purely because you expect to use DHCP at some
+ point in the future.</para>
+ </note>
+
+ <para>The next thing that you will need to do is edit the sample
+ <filename>dhcpd.conf</filename> which was installed by the
+ <package>net/isc-dhcp3-server</package> port.
+ By default, this will be
+ <filename>/usr/local/etc/dhcpd.conf.sample</filename>, and you
+ should copy this to
+ <filename>/usr/local/etc/dhcpd.conf</filename> before proceeding
+ to make changes.</para>
+ </sect3>
+
+ <sect3>
+ <title>Configuring the DHCP Server</title>
+ <indexterm>
+ <primary>DHCP</primary>
+ <secondary>dhcpd.conf</secondary>
+ </indexterm>
+ <para><filename>dhcpd.conf</filename> is
+ comprised of declarations regarding subnets and hosts, and is
+ perhaps most easily explained using an example :</para>
+
+ <programlisting>option domain-name "example.com";<co xml:id="domain-name"/>
+option domain-name-servers 192.168.4.100;<co xml:id="domain-name-servers"/>
+option subnet-mask 255.255.255.0;<co xml:id="subnet-mask"/>
+
+default-lease-time 3600;<co xml:id="default-lease-time"/>
+max-lease-time 86400;<co xml:id="max-lease-time"/>
+ddns-update-style none;<co xml:id="ddns-update-style"/>
+
+subnet 192.168.4.0 netmask 255.255.255.0 {
+ range 192.168.4.129 192.168.4.254;<co xml:id="range"/>
+ option routers 192.168.4.1;<co xml:id="routers"/>
+}
+
+host mailhost {
+ hardware ethernet 02:03:04:05:06:07;<co xml:id="hardware"/>
+ fixed-address mailhost.example.com;<co xml:id="fixed-address"/>
+}</programlisting>
+
+ <calloutlist>
+ <callout arearefs="domain-name">
+ <para>This option specifies the domain that will be provided
+ to clients as the default search domain. See
+ &man.resolv.conf.5; for more information on what this
+ means.</para>
+ </callout>
+
+ <callout arearefs="domain-name-servers">
+ <para>This option specifies a comma separated list of DNS
+ servers that the client should use.</para>
+ </callout>
+
+ <callout arearefs="subnet-mask">
+ <para>The netmask that will be provided to clients.</para>
+ </callout>
+
+ <callout arearefs="default-lease-time">
+ <para>A client may request a specific length of time that a
+ lease will be valid. Otherwise the server will assign
+ a lease with this expiry value (in seconds).</para>
+ </callout>
+
+ <callout arearefs="max-lease-time">
+ <para>This is the maximum length of time that the server will
+ lease for. Should a client request a longer lease, a lease
+ will be issued, although it will only be valid for
+ <literal>max-lease-time</literal> seconds.</para>
+ </callout>
+
+ <callout arearefs="ddns-update-style">
+ <para>This option specifies whether the DHCP server should
+ attempt to update DNS when a lease is accepted or released.
+ In the ISC implementation, this option is
+ <emphasis>required</emphasis>.</para>
+ </callout>
+
+ <callout arearefs="range">
+ <para>This denotes which IP addresses should be used in
+ the pool reserved for allocating to clients. IP
+ addresses between, and including, the ones stated are
+ handed out to clients.</para>
+ </callout>
+
+ <callout arearefs="routers">
+ <para>Declares the default gateway that will be provided to
+ clients.</para>
+ </callout>
+
+ <callout arearefs="hardware">
+ <para>The hardware MAC address of a host (so that the DHCP server
+ can recognize a host when it makes a request).</para>
+ </callout>
+
+ <callout arearefs="fixed-address">
+ <para>Specifies that the host should always be given the
+ same IP address. Note that using a hostname is
+ correct here, since the DHCP server will resolve the
+ hostname itself before returning the lease
+ information.</para>
+ </callout>
+ </calloutlist>
+
+ <para>Once you have finished writing your
+ <filename>dhcpd.conf</filename>, you can proceed to start the
+ server by issuing the following command:</para>
+
+ <screen>&prompt.root; <userinput>/usr/local/etc/rc.d/isc-dhcpd.sh start</userinput></screen>
+
+ <para>Should you need to make changes to the configuration of your
+ server in the future, it is important to note that sending a
+ <literal>SIGHUP</literal> signal to
+ <application>dhcpd</application> does <emphasis>not</emphasis>
+ result in the configuration being reloaded, as it does with most
+ daemons. You will need to send a <literal>SIGTERM</literal>
+ signal to stop the process, and then restart it using the command
+ above.</para>
+ </sect3>
+
+ <sect3>
+ <title>Files</title>
+ <indexterm>
+ <primary>DHCP</primary>
+ <secondary>configuration files</secondary>
+ </indexterm>
+ <itemizedlist>
+ <listitem><para><filename>/usr/local/sbin/dhcpd</filename></para>
+ <para><application>dhcpd</application> is statically linked and
+ resides in <filename>/usr/local/sbin</filename>. The
+ &man.dhcpd.8; manual page installed with the
+ port gives more information about
+ <application>dhcpd</application>.</para>
+ </listitem>
+
+ <listitem><para><filename>/usr/local/etc/dhcpd.conf</filename></para>
+ <para><application>dhcpd</application> requires a configuration
+ file, <filename>/usr/local/etc/dhcpd.conf</filename> before it
+ will start providing service to clients. This file needs to
+ contain all the information that should be provided to clients
+ that are being serviced, along with information regarding the
+ operation of the server. This configuration file is described
+ by the &man.dhcpd.conf.5; manual page installed
+ by the port.</para>
+ </listitem>
+
+ <listitem><para><filename>/var/db/dhcpd.leases</filename></para>
+ <para>The DHCP server keeps a database of leases it has issued
+ in this file, which is written as a log. The manual page
+ &man.dhcpd.leases.5;, installed by the port
+ gives a slightly longer description.</para>
+ </listitem>
+
+ <listitem><para><filename>/usr/local/sbin/dhcrelay</filename></para>
+ <para><application>dhcrelay</application> is used in advanced
+ environments where one DHCP server forwards a request from a
+ client to another DHCP server on a separate network. If you
+ require this functionality, then install the <package>net/isc-dhcp3-relay</package> port. The
+ &man.dhcrelay.8; manual page provided with the
+ port contains more detail.</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="network-dns">
+ <info><title>Domain Name System (DNS)</title>
+ <authorgroup>
+ <author><personname><firstname>Chern</firstname><surname>Lee</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <sect2>
+ <title>Overview</title>
+ <indexterm><primary>BIND</primary></indexterm>
+
+ <para>FreeBSD utilizes, by default, a version of BIND (Berkeley
+ Internet Name Domain), which is the most common implementation
+ of the DNS protocol. DNS is the protocol through which names
+ are mapped to IP addresses, and vice versa. For example, a
+ query for <systemitem class="fqdomainname">www.FreeBSD.org</systemitem> will
+ receive a reply with the IP address of The FreeBSD Project's
+ web server, whereas, a query for <systemitem class="fqdomainname">ftp.FreeBSD.org</systemitem> will return the IP
+ address of the corresponding FTP machine. Likewise, the
+ opposite can happen. A query for an IP address can resolve
+ its hostname. It is not necessary to run a name server to
+ perform DNS lookups on a system.
+ </para>
+
+ <indexterm><primary>DNS</primary></indexterm>
+ <para>DNS is coordinated across the Internet through a somewhat
+ complex system of authoritative root name servers, and other
+ smaller-scale name servers who host and cache individual domain
+ information.
+ </para>
+
+ <para>
+ This document refers to BIND 8.x, as it is the stable version
+ used in &os;. Versions of &os;&nbsp;5.3 and beyond include
+ <acronym>BIND</acronym>9 and the configuration instructions
+ may be found later in this chapter. Users of &os;&nbsp;5.2
+ and other previous versions may install <acronym>BIND</acronym>9
+ from the <package>net/bind9</package> port.</para>
+
+ <para>
+ RFC1034 and RFC1035 dictate the DNS protocol.
+ </para>
+
+ <para>
+ Currently, BIND is maintained by the
+ Internet Software Consortium <uri xlink:href="http://www.isc.org/">http://www.isc.org/</uri>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Terminology</title>
+
+ <para>To understand this document, some terms related to DNS must be
+ understood.</para>
+
+ <indexterm><primary>resolver</primary></indexterm>
+ <indexterm><primary>reverse DNS</primary></indexterm>
+ <indexterm><primary>root zone</primary></indexterm>
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="3*"/>
+
+ <thead>
+ <row>
+ <entry>Term</entry>
+ <entry>Definition</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>Forward DNS</entry>
+ <entry>Mapping of hostnames to IP addresses</entry>
+ </row>
+
+ <row>
+ <entry>Origin</entry>
+ <entry>Refers to the domain covered in a particular zone
+ file</entry>
+ </row>
+
+ <row>
+ <entry><application>named</application>, BIND, name server</entry>
+ <entry>Common names for the BIND name server package within
+ FreeBSD</entry>
+ </row>
+
+ <row>
+ <entry>Resolver</entry>
+ <entry>A system process through which a
+ machine queries a name server for zone information</entry>
+ </row>
+
+ <row>
+ <entry>Reverse DNS</entry>
+ <entry>The opposite of forward DNS; mapping of IP addresses to
+ hostnames</entry>
+ </row>
+
+ <row>
+ <entry>Root zone</entry>
+
+ <entry>The beginning of the Internet zone hierarchy.
+ All zones fall under the root zone, similar to how
+ all files in a file system fall under the root directory.</entry>
+ </row>
+
+ <row>
+ <entry>Zone</entry>
+ <entry>An individual domain, subdomain, or portion of the DNS administered by
+ the same authority</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <indexterm>
+ <primary>zones</primary>
+ <secondary>examples</secondary>
+ </indexterm>
+
+ <para>Examples of zones:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para><systemitem>.</systemitem> is the root zone</para>
+ </listitem>
+ <listitem>
+ <para><systemitem>org.</systemitem> is a zone under the root zone</para>
+ </listitem>
+ <listitem>
+ <para><systemitem class="fqdomainname">example.org.</systemitem> is a
+ zone under the <systemitem>org.</systemitem> zone</para>
+ </listitem>
+ <listitem>
+ <para><systemitem class="fqdomainname">foo.example.org.</systemitem> is
+ a subdomain, a zone under the <systemitem class="fqdomainname">example.org.</systemitem> zone</para>
+ </listitem>
+ <listitem>
+ <para>
+ <systemitem>1.2.3.in-addr.arpa</systemitem> is a zone referencing
+ all IP addresses which fall under the <systemitem class="ipaddress">3.2.1.*</systemitem> IP space.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>As one can see, the more specific part of a hostname
+ appears to its left. For example, <systemitem class="fqdomainname">example.org.</systemitem> is more specific than
+ <systemitem>org.</systemitem>, as <systemitem>org.</systemitem> is more
+ specific than the root zone. The layout of each part of a
+ hostname is much like a file system: the
+ <filename>/dev</filename> directory falls within the root, and
+ so on.</para>
+
+
+ </sect2>
+
+ <sect2>
+ <title>Reasons to Run a Name Server</title>
+
+ <para>Name servers usually come in two forms: an authoritative
+ name server, and a caching name server.</para>
+
+ <para>An authoritative name server is needed when:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>one wants to serve DNS information to the
+ world, replying authoritatively to queries.</para>
+ </listitem>
+ <listitem>
+ <para>a domain, such as <systemitem class="fqdomainname">example.org</systemitem>, is
+ registered and IP addresses need to be assigned to hostnames
+ under it.</para>
+ </listitem>
+ <listitem>
+ <para>an IP address block requires reverse DNS entries (IP to
+ hostname).</para>
+ </listitem>
+ <listitem>
+ <para>a backup name server, called a slave, must reply to queries
+ when the primary is down or inaccessible.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>A caching name server is needed when:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>a local DNS server may cache and respond more quickly
+ than querying an outside name server.</para>
+ </listitem>
+ <listitem>
+ <para>a reduction in overall network traffic is desired (DNS
+ traffic has been measured to account for 5% or more of total
+ Internet traffic).</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>When one queries for <systemitem class="fqdomainname">www.FreeBSD.org</systemitem>, the resolver usually
+ queries the uplink ISP's name server, and retrieves the reply.
+ With a local, caching DNS server, the query only has to be
+ made once to the outside world by the caching DNS server.
+ Every additional query will not have to look to the outside of
+ the local network, since the information is cached
+ locally.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>How It Works</title>
+ <para>In FreeBSD, the BIND daemon is called
+ <application>named</application> for obvious reasons.</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>File</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><application>named</application></entry>
+ <entry>the BIND daemon</entry>
+ </row>
+
+ <row>
+ <entry><command>ndc</command></entry>
+ <entry>name daemon control program</entry>
+ </row>
+
+ <row>
+ <entry><filename>/etc/namedb</filename></entry>
+ <entry>directory where BIND zone information resides</entry>
+ </row>
+
+ <row>
+ <entry><filename>/etc/namedb/named.conf</filename></entry>
+ <entry>daemon configuration file</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>
+ Zone files are usually contained within the
+ <filename>/etc/namedb</filename>
+ directory, and contain the DNS zone information
+ served by the name server.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Starting BIND</title>
+ <indexterm>
+ <primary>BIND</primary>
+ <secondary>starting</secondary>
+ </indexterm>
+ <para>
+ Since BIND is installed by default, configuring it all is
+ relatively simple.
+ </para>
+ <para>
+ To ensure the <application>named</application> daemon is
+ started at boot, put the following line in
+ <filename>/etc/rc.conf</filename>:
+ </para>
+ <programlisting>named_enable="YES"</programlisting>
+ <para>To start the daemon manually (after configuring it):</para>
+ <screen>&prompt.root; <userinput>ndc start</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Configuration Files</title>
+ <indexterm>
+ <primary>BIND</primary>
+ <secondary>configuration files</secondary>
+ </indexterm>
+ <sect3>
+ <title>Using <command>make-localhost</command></title>
+ <para>Be sure to:
+ </para>
+ <screen>&prompt.root; <userinput>cd /etc/namedb</userinput>
+&prompt.root; <userinput>sh make-localhost</userinput></screen>
+ <para>to properly create the local reverse DNS zone file in
+ <filename>/etc/namedb/master/localhost.rev</filename>.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><filename>/etc/namedb/named.conf</filename></title>
+
+ <programlisting>// &dollar;FreeBSD$
+//
+// Refer to the named(8) manual page for details. If you are ever going
+// to setup a primary server, make sure you've understood the hairy
+// details of how DNS is working. Even with simple mistakes, you can
+// break connectivity for affected parties, or cause huge amount of
+// useless Internet traffic.
+
+options {
+ directory "/etc/namedb";
+
+// In addition to the "forwarders" clause, you can force your name
+// server to never initiate queries of its own, but always ask its
+// forwarders only, by enabling the following line:
+//
+// forward only;
+
+// If you've got a DNS server around at your upstream provider, enter
+// its IP address here, and enable the line below. This will make you
+// benefit from its cache, thus reduce overall DNS traffic in the
+Internet.
+/*
+ forwarders {
+ 127.0.0.1;
+ };
+*/</programlisting>
+
+ <para>
+ Just as the comment says, to benefit from an uplink's cache,
+ <literal>forwarders</literal> can be enabled here. Under normal
+ circumstances, a name server will recursively query the Internet
+ looking at certain name servers until it finds the answer it is
+ looking for. Having this enabled will have it query the uplink's
+ name server (or name server provided) first, taking advantage of
+ its cache. If the uplink name server in question is a heavily
+ trafficked, fast name server, enabling this may be worthwhile.
+ </para>
+
+ <warning><para><systemitem class="ipaddress">127.0.0.1</systemitem>
+ will <emphasis>not</emphasis> work here.
+ Change this IP address to a name server at your uplink.</para>
+ </warning>
+
+ <programlisting> /*
+ * If there is a firewall between you and name servers you want
+ * to talk to, you might need to uncomment the query-source
+ * directive below. Previous versions of BIND always asked
+ * questions using port 53, but BIND 8.1 uses an unprivileged
+ * port by default.
+ */
+ // query-source address * port 53;
+
+ /*
+ * If running in a sandbox, you may have to specify a different
+ * location for the dumpfile.
+ */
+ // dump-file "s/named_dump.db";
+};
+
+// Note: the following will be supported in a future release.
+/*
+host { any; } {
+ topology {
+ 127.0.0.0/8;
+ };
+};
+*/
+
+// Setting up secondaries is way easier and the rough picture for this
+// is explained below.
+//
+// If you enable a local name server, don't forget to enter 127.0.0.1
+// into your /etc/resolv.conf so this server will be queried first.
+// Also, make sure to enable it in /etc/rc.conf.
+
+zone "." {
+ type hint;
+ file "named.root";
+};
+
+zone "0.0.127.IN-ADDR.ARPA" {
+ type master;
+ file "localhost.rev";
+};
+
+// NB: Do not use the IP addresses below, they are faked, and only
+// serve demonstration/documentation purposes!
+//
+// Example secondary config entries. It can be convenient to become
+// a secondary at least for the zone where your own domain is in. Ask
+// your network administrator for the IP address of the responsible
+// primary.
+//
+// Never forget to include the reverse lookup (IN-ADDR.ARPA) zone!
+// (This is the first bytes of the respective IP address, in reverse
+// order, with ".IN-ADDR.ARPA" appended.)
+//
+// Before starting to setup a primary zone, better make sure you fully
+// understand how DNS and BIND works, however. There are sometimes
+// unobvious pitfalls. Setting up a secondary is comparably simpler.
+//
+// NB: Don't blindly enable the examples below. :-) Use actual names
+// and addresses instead.
+//
+// NOTE!!! FreeBSD runs BIND in a sandbox (see named_flags in rc.conf).
+// The directory containing the secondary zones must be write accessible
+// to BIND. The following sequence is suggested:
+//
+// mkdir /etc/namedb/s
+// chown bind:bind /etc/namedb/s
+// chmod 750 /etc/namedb/s</programlisting>
+
+ <para>For more information on running BIND in a sandbox, see
+ <link linkend="network-named-sandbox">Running named in a sandbox</link>.
+ </para>
+
+ <programlisting>/*
+zone "example.com" {
+ type slave;
+ file "s/example.com.bak";
+ masters {
+ 192.168.1.1;
+ };
+};
+
+zone "0.168.192.in-addr.arpa" {
+ type slave;
+ file "s/0.168.192.in-addr.arpa.bak";
+ masters {
+ 192.168.1.1;
+ };
+};
+*/</programlisting>
+ <para>In <filename>named.conf</filename>, these are examples of slave
+ entries for a forward and reverse zone.</para>
+
+ <para>For each new zone served, a new zone entry must be added to
+ <filename>named.conf</filename>.</para>
+
+ <para>For example, the simplest zone entry for
+ <systemitem class="fqdomainname">example.org</systemitem> can look like:</para>
+
+ <programlisting>zone "example.org" {
+ type master;
+ file "example.org";
+};</programlisting>
+
+ <para>The zone is a master, as indicated by the <option>type</option>
+ statement, holding its zone information in
+ <filename>/etc/namedb/example.org</filename> indicated by
+ the <option>file</option> statement.</para>
+
+ <programlisting>zone "example.org" {
+ type slave;
+ file "example.org";
+};</programlisting>
+
+ <para>In the slave case, the zone information is transferred from
+ the master name server for the particular zone, and saved in the
+ file specified. If and when the master server dies or is
+ unreachable, the slave name server will have the transferred
+ zone information and will be able to serve it.</para>
+ </sect3>
+
+ <sect3>
+ <title>Zone Files</title>
+ <para>
+ An example master zone file for <systemitem class="fqdomainname">example.org</systemitem> (existing within
+ <filename>/etc/namedb/example.org</filename>) is as follows:
+ </para>
+
+ <programlisting>$TTL 3600
+
+example.org. IN SOA ns1.example.org. admin.example.org. (
+ 5 ; Serial
+ 10800 ; Refresh
+ 3600 ; Retry
+ 604800 ; Expire
+ 86400 ) ; Minimum TTL
+
+; DNS Servers
+@ IN NS ns1.example.org.
+@ IN NS ns2.example.org.
+
+; Machine Names
+localhost IN A 127.0.0.1
+ns1 IN A 3.2.1.2
+ns2 IN A 3.2.1.3
+mail IN A 3.2.1.10
+@ IN A 3.2.1.30
+
+; Aliases
+www IN CNAME @
+
+; MX Record
+@ IN MX 10 mail.example.org.</programlisting>
+
+ <para>
+ Note that every hostname ending in a <quote>.</quote> is an
+ exact hostname, whereas everything without a trailing
+ <quote>.</quote> is referenced to the origin. For example,
+ <literal>www</literal> is translated into
+ <literal>www.origin</literal>.
+ In our fictitious zone file, our origin is
+ <systemitem>example.org.</systemitem>, so <literal>www</literal>
+ would translate to <systemitem>www.example.org.</systemitem>
+ </para>
+
+ <para>
+ The format of a zone file follows:
+ </para>
+ <programlisting>recordname IN recordtype value</programlisting>
+
+ <indexterm>
+ <primary>DNS</primary>
+ <secondary>records</secondary>
+ </indexterm>
+ <para>
+ The most commonly used DNS records:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>SOA</term>
+
+ <listitem><para>start of zone authority</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>NS</term>
+
+ <listitem><para>an authoritative name server</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>A</term>
+
+ <listitem><para>a host address</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>CNAME</term>
+
+ <listitem><para>the canonical name for an alias</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>MX</term>
+
+ <listitem><para>mail exchanger</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PTR</term>
+
+ <listitem><para>a domain name pointer (used in reverse DNS)
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <programlisting>
+example.org. IN SOA ns1.example.org. admin.example.org. (
+ 5 ; Serial
+ 10800 ; Refresh after 3 hours
+ 3600 ; Retry after 1 hour
+ 604800 ; Expire after 1 week
+ 86400 ) ; Minimum TTL of 1 day</programlisting>
+
+
+
+ <variablelist>
+ <varlistentry>
+ <term><systemitem class="fqdomainname">example.org.</systemitem></term>
+
+ <listitem><para>the domain name, also the origin for this
+ zone file.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><systemitem class="fqdomainname">ns1.example.org.</systemitem></term>
+
+ <listitem><para>the primary/authoritative name server for this
+ zone.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>admin.example.org.</literal></term>
+
+ <listitem><para>the responsible person for this zone,
+ email address with <quote>@</quote>
+ replaced. (<email>admin@example.org</email> becomes
+ <literal>admin.example.org</literal>)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>5</literal></term>
+
+ <listitem><para>the serial number of the file. This
+ must be incremented each time the zone file is
+ modified. Nowadays, many admins prefer a
+ <literal>yyyymmddrr</literal> format for the serial
+ number. <literal>2001041002</literal> would mean
+ last modified 04/10/2001, the latter
+ <literal>02</literal> being the second time the zone
+ file has been modified this day. The serial number
+ is important as it alerts slave name servers for a
+ zone when it is updated.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <programlisting>
+@ IN NS ns1.example.org.</programlisting>
+
+ <para>
+ This is an NS entry. Every name server that is going to reply
+ authoritatively for the zone must have one of these entries.
+ The <literal>@</literal> as seen here could have been
+ <systemitem class="fqdomainname">example.org.</systemitem>
+ The <literal>@</literal> translates to the origin.
+ </para>
+
+ <programlisting>
+localhost IN A 127.0.0.1
+ns1 IN A 3.2.1.2
+ns2 IN A 3.2.1.3
+mail IN A 3.2.1.10
+@ IN A 3.2.1.30</programlisting>
+
+ <para>
+ The A record indicates machine names. As seen above,
+ <systemitem class="fqdomainname">ns1.example.org</systemitem> would resolve
+ to <systemitem class="ipaddress">3.2.1.2</systemitem>. Again, the
+ origin symbol, <literal>@</literal>, is used here, thus
+ meaning <systemitem class="fqdomainname">example.org</systemitem> would
+ resolve to <systemitem class="ipaddress">3.2.1.30</systemitem>.
+ </para>
+
+ <programlisting>
+www IN CNAME @</programlisting>
+
+ <para>
+ The canonical name record is usually used for giving aliases
+ to a machine. In the example, <systemitem>www</systemitem> is
+ aliased to the machine addressed to the origin, or
+ <systemitem class="fqdomainname">example.org</systemitem>
+ (<systemitem class="ipaddress">3.2.1.30</systemitem>).
+ CNAMEs can be used to provide alias
+ hostnames, or round robin one hostname among multiple
+ machines.
+ </para>
+
+ <indexterm>
+ <primary>MX record</primary>
+ </indexterm>
+
+ <programlisting>
+@ IN MX 10 mail.example.org.</programlisting>
+
+ <para>
+ The MX record indicates which mail
+ servers are responsible for handling incoming mail for the
+ zone. <systemitem class="fqdomainname">mail.example.org</systemitem> is the
+ hostname of the mail server, and 10 being the priority of
+ that mail server.
+ </para>
+
+ <para>
+ One can have several mail servers, with priorities of 3, 2,
+ 1. A mail server attempting to deliver to <systemitem class="fqdomainname">example.org</systemitem> would first try the
+ highest priority MX, then the second highest, etc, until the
+ mail can be properly delivered.
+ </para>
+
+ <para>
+ For in-addr.arpa zone files (reverse DNS), the same format is
+ used, except with PTR entries instead of
+ A or CNAME.
+ </para>
+
+ <programlisting>$TTL 3600
+
+1.2.3.in-addr.arpa. IN SOA ns1.example.org. admin.example.org. (
+ 5 ; Serial
+ 10800 ; Refresh
+ 3600 ; Retry
+ 604800 ; Expire
+ 3600 ) ; Minimum
+
+@ IN NS ns1.example.org.
+@ IN NS ns2.example.org.
+
+2 IN PTR ns1.example.org.
+3 IN PTR ns2.example.org.
+10 IN PTR mail.example.org.
+30 IN PTR example.org.</programlisting>
+
+ <para>This file gives the proper IP address to hostname
+ mappings of our above fictitious domain.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Caching Name Server</title>
+ <indexterm>
+ <primary>BIND</primary>
+ <secondary>caching name server</secondary>
+ </indexterm>
+
+ <para>A caching name server is a name server that is not
+ authoritative for any zones. It simply asks queries of its
+ own, and remembers them for later use. To set one up, just
+ configure the name server as usual, omitting any inclusions of
+ zones.</para>
+ </sect2>
+
+ <sect2 xml:id="network-named-sandbox">
+ <title>Running <application>named</application> in a Sandbox</title>
+ <indexterm>
+ <primary>BIND</primary>
+ <secondary>running in a sandbox</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary><command>chroot</command></primary>
+ </indexterm>
+ <para>For added security you may want to run &man.named.8; as an
+ unprivileged user, and configure it to &man.chroot.8; into a
+ sandbox directory. This makes everything outside of the
+ sandbox inaccessible to the <application>named</application>
+ daemon. Should <application>named</application> be
+ compromised, this will help to reduce the damage that can be
+ caused. By default, FreeBSD has a user and a group called
+ <systemitem class="groupname">bind</systemitem>, intended for this use.</para>
+
+ <note><para>Various people would recommend that instead of configuring
+ <application>named</application> to <command>chroot</command>, you
+ should run <application>named</application> inside a &man.jail.8;.
+ This section does not attempt to cover this situation.</para>
+ </note>
+
+ <para>Since <application>named</application> will not be able to
+ access anything outside of the sandbox (such as shared
+ libraries, log sockets, and so on), there are a number of steps
+ that need to be followed in order to allow
+ <application>named</application> to function correctly. In the
+ following checklist, it is assumed that the path to the sandbox
+ is <filename>/etc/namedb</filename> and that you have made no
+ prior modifications to the contents of this directory. Perform
+ the following steps as <systemitem class="username">root</systemitem>:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Create all directories that <application>named</application>
+ expects to see:</para>
+
+ <screen>&prompt.root; <userinput>cd /etc/namedb</userinput>
+&prompt.root; <userinput>mkdir -p bin dev etc var/tmp var/run master slave</userinput>
+&prompt.root; <userinput>chown bind:bind slave var/*</userinput><co xml:id="chown-slave"/></screen>
+
+
+
+ <calloutlist>
+ <callout arearefs="chown-slave">
+ <para><application>named</application> only needs write access to
+ these directories, so that is all we give it.</para>
+ </callout>
+ </calloutlist>
+ </listitem>
+
+ <listitem>
+ <para>Rearrange and create basic zone and configuration files:</para>
+ <screen>&prompt.root; <userinput>cp /etc/localtime etc</userinput><co xml:id="localtime"/>
+&prompt.root; <userinput>mv named.conf etc &amp;&amp; ln -sf etc/named.conf</userinput>
+&prompt.root; <userinput>mv named.root master</userinput>
+<!-- I don't like this next bit -->
+&prompt.root; <userinput>sh make-localhost</userinput>
+&prompt.root; <userinput>cat &gt; master/named.localhost
+$ORIGIN localhost.
+$TTL 6h
+@ IN SOA localhost. postmaster.localhost. (
+ 1 ; serial
+ 3600 ; refresh
+ 1800 ; retry
+ 604800 ; expiration
+ 3600 ) ; minimum
+ IN NS localhost.
+ IN A 127.0.0.1
+^D</userinput></screen>
+
+ <calloutlist>
+ <callout arearefs="localtime">
+ <para>This allows <application>named</application> to log the
+ correct time to &man.syslogd.8;.</para>
+ </callout>
+ </calloutlist>
+ </listitem>
+
+ <listitem>
+
+ <indexterm><primary>syslog</primary></indexterm>
+ <indexterm><primary>log files</primary>
+ <secondary>named</secondary></indexterm>
+
+ <para>If you are running a version of &os; prior to 4.9-RELEASE, build a statically linked copy of
+ <application>named-xfer</application>, and copy it into the sandbox:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src/lib/libisc</userinput>
+&prompt.root; <userinput>make cleandir &amp;&amp; make cleandir &amp;&amp; make depend &amp;&amp; make all</userinput>
+&prompt.root; <userinput>cd /usr/src/lib/libbind</userinput>
+&prompt.root; <userinput>make cleandir &amp;&amp; make cleandir &amp;&amp; make depend &amp;&amp; make all</userinput>
+&prompt.root; <userinput>cd /usr/src/libexec/named-xfer</userinput>
+&prompt.root; <userinput>make cleandir &amp;&amp; make cleandir &amp;&amp; make depend &amp;&amp; make NOSHARED=yes all</userinput>
+&prompt.root; <userinput>cp named-xfer /etc/namedb/bin &amp;&amp; chmod 555 /etc/namedb/bin/named-xfer</userinput><co xml:id="clean-cruft"/></screen>
+
+ <para>After your statically linked
+ <command>named-xfer</command> is installed some cleaning up
+ is required, to avoid leaving stale copies of libraries or
+ programs in your source tree:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src/lib/libisc</userinput>
+&prompt.root; <userinput>make cleandir</userinput>
+&prompt.root; <userinput>cd /usr/src/lib/libbind</userinput>
+&prompt.root; <userinput>make cleandir</userinput>
+&prompt.root; <userinput>cd /usr/src/libexec/named-xfer</userinput>
+&prompt.root; <userinput>make cleandir</userinput></screen>
+
+ <calloutlist>
+ <callout arearefs="clean-cruft">
+ <para>This step has been reported to fail occasionally. If this
+ happens to you, then issue the command:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/src &amp;&amp; make cleandir &amp;&amp; make cleandir</userinput></screen>
+
+ <para>and delete your <filename>/usr/obj</filename> tree:</para>
+
+ <screen>&prompt.root; <userinput>rm -fr /usr/obj &amp;&amp; mkdir /usr/obj</userinput></screen>
+
+ <para>This will clean out any <quote>cruft</quote> from your
+ source tree, and retrying the steps above should then work.</para>
+ </callout>
+ </calloutlist>
+
+ <para>If you are running &os; version 4.9-RELEASE or later,
+ then the copy of <command>named-xfer</command> in
+ <filename>/usr/libexec</filename> is statically linked by
+ default, and you can simply use &man.cp.1; to copy it into
+ your sandbox.</para>
+ </listitem>
+
+ <listitem>
+ <para>Make a <filename>dev/null</filename> that
+ <application>named</application> can see and write to:</para>
+
+ <screen>&prompt.root; <userinput>cd /etc/namedb/dev &amp;&amp; mknod null c 2 2</userinput>
+&prompt.root; <userinput>chmod 666 null</userinput></screen>
+ </listitem>
+
+ <listitem>
+ <para>Symlink <filename> /var/run/ndc</filename> to
+ <filename>/etc/namedb/var/run/ndc</filename>:</para>
+
+ <screen>&prompt.root; <userinput>ln -sf /etc/namedb/var/run/ndc /var/run/ndc</userinput></screen>
+
+ <note>
+ <para>This simply avoids having to specify the
+ <option>-c</option> option to &man.ndc.8; every time you
+ run it. Since the contents of
+ <filename>/var/run</filename> are deleted on boot, it may
+ be useful to add this command to
+ <systemitem class="username">root</systemitem>'s &man.crontab.5;, using the
+ <option>@reboot</option> option.</para>
+ </note>
+
+ </listitem>
+
+ <listitem>
+
+ <indexterm><primary>syslog</primary></indexterm>
+ <indexterm><primary>log files</primary>
+ <secondary>named</secondary></indexterm>
+
+ <para>Configure &man.syslogd.8; to create an extra
+ <filename>log</filename> socket that
+ <application>named</application> can write to. To do this,
+ add <literal>-l /etc/namedb/dev/log</literal> to the
+ <varname>syslogd_flags</varname> variable in
+ <filename>/etc/rc.conf</filename>.</para>
+ </listitem>
+
+ <listitem>
+
+ <indexterm><primary><command>chroot</command></primary></indexterm>
+
+ <para>Arrange to have <application>named</application> start
+ and <command>chroot</command> itself to the sandbox by
+ adding the following to
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>named_enable="YES"
+named_flags="-u bind -g bind -t /etc/namedb /etc/named.conf"</programlisting>
+
+ <note>
+ <para>Note that the configuration file
+ <replaceable>/etc/named.conf</replaceable> is denoted by a full
+ pathname <emphasis>relative to the sandbox</emphasis>, i.e. in
+ the line above, the file referred to is actually
+ <filename>/etc/namedb/etc/named.conf</filename>.</para>
+ </note>
+ </listitem>
+ </itemizedlist>
+
+ <para>The next step is to edit
+ <filename>/etc/namedb/etc/named.conf</filename> so that
+ <application>named</application> knows which zones to load and
+ where to find them on the disk. There follows a commented
+ example (anything not specifically commented here is no
+ different from the setup for a DNS server not running in a
+ sandbox):</para>
+
+ <programlisting>options {
+ directory "/";<co xml:id="directory"/>
+ named-xfer "/bin/named-xfer";<co xml:id="named-xfer"/>
+ version ""; // Don't reveal BIND version
+ query-source address * port 53;
+};
+// ndc control socket
+controls {
+ unix "/var/run/ndc" perm 0600 owner 0 group 0;
+};
+// Zones follow:
+zone "localhost" IN {
+ type master;
+ file "master/named.localhost";<co xml:id="master"/>
+ allow-transfer { localhost; };
+ notify no;
+};
+zone "0.0.127.in-addr.arpa" IN {
+ type master;
+ file "master/localhost.rev";
+ allow-transfer { localhost; };
+ notify no;
+};
+zone "." IN {
+ type hint;
+ file "master/named.root";
+};
+zone "private.example.net" in {
+ type master;
+ file "master/private.example.net.db";
+ allow-transfer { 192.168.10.0/24; };
+};
+zone "10.168.192.in-addr.arpa" in {
+ type slave;
+ masters { 192.168.10.2; };
+ file "slave/192.168.10.db";<co xml:id="slave"/>
+};</programlisting>
+
+ <calloutlist>
+ <callout arearefs="directory">
+ <para>The
+ <literal>directory</literal> statement is specified as
+ <filename>/</filename>, since all files that
+ <application>named</application> needs are within this
+ directory (recall that this is equivalent to a
+ <quote>normal</quote> user's
+ <filename>/etc/namedb</filename>).</para>
+ </callout>
+
+ <callout arearefs="named-xfer">
+ <para>Specifies the full path
+ to the <command>named-xfer</command> binary (from
+ <application>named</application>'s frame of reference). This
+ is necessary since <application>named</application> is
+ compiled to look for <command>named-xfer</command> in
+ <filename>/usr/libexec</filename> by default.</para>
+ </callout>
+ <callout arearefs="master"><para>Specifies the filename (relative
+ to the <literal>directory</literal> statement above) where
+ <application>named</application> can find the zone file for this
+ zone.</para>
+ </callout>
+ <callout arearefs="slave"><para>Specifies the filename
+ (relative to the <literal>directory</literal> statement above)
+ where <application>named</application> should write a copy of
+ the zone file for this zone after successfully transferring it
+ from the master server. This is why we needed to change the
+ ownership of the directory <filename>slave</filename> to
+ <systemitem class="groupname">bind</systemitem> in the setup stages above.</para>
+ </callout>
+ </calloutlist>
+
+ <para>After completing the steps above, either reboot your
+ server or restart &man.syslogd.8; and start &man.named.8;, making
+ sure to use the new options specified in
+ <varname>syslogd_flags</varname> and
+ <varname>named_flags</varname>. You should now be running a
+ sandboxed copy of <application>named</application>!</para>
+
+ </sect2>
+
+ <sect2>
+ <title>Security</title>
+
+ <para>Although BIND is the most common implementation of DNS,
+ there is always the issue of security. Possible and
+ exploitable security holes are sometimes found.
+ </para>
+
+ <para>
+ It is a good idea to read <link xlink:href="http://www.cert.org/">CERT</link>'s security advisories and
+ to subscribe to the &a.security-notifications;
+ to stay up to date with the current Internet and FreeBSD security
+ issues.
+ </para>
+
+ <tip><para>If a problem arises, keeping sources up to date and
+ having a fresh build of <application>named</application> would
+ not hurt.</para></tip>
+ </sect2>
+
+ <sect2>
+ <title>Further Reading</title>
+
+ <para>BIND/<application>named</application> manual pages:
+ &man.ndc.8; &man.named.8; &man.named.conf.5;</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="http://www.isc.org/products/BIND/">Official ISC BIND
+ Page</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.nominum.com/getOpenSourceResource.php?id=6">
+ BIND FAQ</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.oreilly.com/catalog/dns4/">O'Reilly
+ DNS and BIND 4th Edition</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="ftp://ftp.isi.edu/in-notes/rfc1034.txt">RFC1034
+ - Domain Names - Concepts and Facilities</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="ftp://ftp.isi.edu/in-notes/rfc1035.txt">RFC1035
+ - Domain Names - Implementation and Specification</link></para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-bind9">
+ <info><title><acronym>BIND</acronym>9 and &os;</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+<!-- This section is here to get users up with BIND9 configurations! It
+ does not cover the terminology, theoretical discussion (why run a name
+ server) or the further reading which is still in the previous section.
+ I did things this way to avoid repetition of content and obviously we
+ cannot just remove the previous section since other supported releases
+ use it. When the previous section is removed then those comments
+ should be moved here. // Tom Rhodes -->
+
+ <indexterm><primary>bind9</primary>
+ <secondary>setting up</secondary></indexterm>
+
+ <para>The release of &os;&nbsp;5.3 brought the
+ <acronym>BIND</acronym>9 <acronym>DNS</acronym> server software
+ into the distribution. New security features, a new file system
+ layout and automated &man.chroot.8; configuration came with the
+ import. This section has been written in two parts, the first
+ will discuss new features and their configuration; the latter
+ will cover upgrades to aid in move to &os;&nbsp;5.3. From this
+ moment on, the server will be referred to simply as
+ &man.named.8; in place of <acronym>BIND</acronym>. This section
+ skips over the terminology described in the previous section as
+ well as some of the theoretical discussions; thus, it is
+ recommended that the previous section be consulted before reading
+ any further here.</para>
+
+ <para>Configuration files for <application>named</application> currently
+ reside in
+ <filename>/var/named/etc/namedb/</filename> and
+ will need modification before use. This is where most of the
+ configuration will be performed.</para>
+
+ <sect2>
+ <title>Configuration of a Master Zone</title>
+
+ <para>To configure a master zone visit
+ <filename>/var/named/etc/namedb/</filename>
+ and run the following command:</para>
+
+ <screen>&prompt.root; <userinput>sh make-localhost</userinput></screen>
+
+ <para>If all went well a new file should exist in the
+ <filename>master</filename> directory. The
+ filenames should be <filename>localhost.rev</filename> for
+ the local domain name and <filename>localhost-v6.rev</filename>
+ for <acronym>IPv6</acronym> configurations. As the default
+ configuration file, configuration for its use will already
+ be present in the <filename>named.conf</filename> file.</para>
+ </sect2>
+
+ <sect2>
+ <title>Configuration of a Slave Zone</title>
+
+ <para>Configuration for extra domains or sub domains may be
+ done properly by setting them as a slave zone. In most cases,
+ the <filename>master/localhost.rev</filename> file could just be
+ copied over into the <filename>slave</filename>
+ directory and modified. Once completed, the files need
+ to be properly added in <filename>named.conf</filename> such
+ as in the following configuration for
+ <systemitem class="fqdomainname">example.com</systemitem>:</para>
+
+ <programlisting>zone "example.com" {
+ type slave;
+ file "slave/example.com";
+ masters {
+ 10.0.0.1;
+ };
+};
+
+zone "0.168.192.in-addr.arpa" {
+ type slave;
+ file "slave/0.168.192.in-addr.arpa";
+ masters {
+ 10.0.0.1;
+ };
+};</programlisting>
+
+ <para>Note well that in this example, the master
+ <acronym>IP</acronym> address is the primary domain server
+ from which the zones are transferred; it does not necessary serve
+ as <acronym>DNS</acronym> server itself.</para>
+ </sect2>
+
+ <sect2>
+ <title>System Initialization Configuration</title>
+
+ <para>In order for the <application>named</application> daemon to start
+ when the system is booted, the following option must be present
+ in the <filename>rc.conf</filename> file:</para>
+
+ <programlisting>named_enable="YES"</programlisting>
+
+ <para>While other options exist, this is the bare minimal
+ requirement. Consult the &man.rc.conf.5; manual page for
+ a list of the other options. If nothing is entered in the
+ <filename>rc.conf</filename> file then <application>named</application>
+ may be started on the command line by invoking:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/named start</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title><acronym>BIND</acronym>9 Security</title>
+
+ <para>While &os; automatically drops <application>named</application>
+ into a &man.chroot.8; environment; there are several other
+ security mechanisms in place which could help to lure off
+ possible <acronym>DNS</acronym> service attacks.</para>
+
+ <sect3>
+ <title>Query Access Control Lists</title>
+
+ <para>A query access control list can be used to restrict
+ queries against the zones. The configuration works by
+ defining the network inside of the <literal>acl</literal>
+ token and then listing <acronym>IP</acronym> addresses in
+ the zone configuration. To permit domains to query the
+ example host, just define it like this:</para>
+
+ <programlisting>acl "example.com" {
+ 192.168.0.0/24;
+};
+
+zone "example.com" {
+ type slave;
+ file "slave/example.com";
+ masters {
+ 10.0.0.1;
+ };
+ allow-query { example.com; };
+};
+
+zone "0.168.192.in-addr.arpa" {
+ type slave;
+ file "slave/0.168.192.in-addr.arpa";
+ masters {
+ 10.0.0.1;
+ };
+ allow-query { example.com; };
+};</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Restrict Version</title>
+
+ <para>Permitting version lookups on the <acronym>DNS</acronym>
+ server could be opening the doors for an attacker. A
+ malicious user may use this information to hunt up known
+ exploits or bugs to utilize against the host.</para>
+
+ <warning>
+ <para>Setting a false version will not protect the server
+ from exploits. Only upgrading to a version that is not
+ vulnerable will protect your server.</para>
+ </warning>
+
+ <para>A false version string can be placed the
+ <literal>options</literal> section of
+ <filename>named.conf</filename>:</para>
+
+ <programlisting>options {
+ directory "/etc/namedb";
+ pid-file "/var/run/named/pid";
+ dump-file "/var/dump/named_dump.db";
+ statistics-file "/var/stats/named.stats";
+ version "None of your business";
+};</programlisting>
+ </sect3>
+
+<!-- Here is where I stopped for now
+ <sect3>
+ <title>Authentication</title>
+
+ <para> ... </para>
+
+-->
+ </sect2>
+ </sect1>
+
+
+ <sect1 xml:id="network-apache">
+ <info><title>Apache HTTP Server</title>
+ <authorgroup>
+ <author><personname><firstname>Murray</firstname><surname>Stokely</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>web servers</primary>
+ <secondary>setting up</secondary></indexterm>
+ <indexterm><primary>Apache</primary></indexterm>
+
+ <sect2>
+ <title>Overview</title>
+
+ <para>&os; is used to run some of the busiest web sites in the
+ world. The majority of web servers on the Internet are using
+ the <application>Apache HTTP Server</application>.
+ <application>Apache</application> software packages should be
+ included on your FreeBSD installation media. If you did not
+ install <application>Apache</application> when you first
+ installed FreeBSD, then you can install it from the <package>www/apache13</package> or <package>www/apache20</package> port.</para>
+
+ <para>Once <application>Apache</application> has been installed
+ successfully, it must be configured.</para>
+
+ <note><para>This section covers version 1.3.X of the
+ <application>Apache HTTP Server</application> as that is the
+ most widely used version for &os;. <application>Apache</application>&nbsp;2.X introduces many
+ new technologies but they are not discussed here. For more
+ information about <application>Apache</application>&nbsp;2.X, please see <uri xlink:href="http://httpd.apache.org/">http://httpd.apache.org/</uri>.</para></note>
+
+ </sect2>
+
+ <sect2>
+ <title>Configuration</title>
+
+ <indexterm><primary>Apache</primary>
+ <secondary>configuration file</secondary></indexterm>
+
+ <para>The main <application>Apache HTTP Server</application> configuration file is
+ installed as
+ <filename>/usr/local/etc/apache/httpd.conf</filename> on &os;.
+ This file is a typical &unix; text configuration file with
+ comment lines beginning with the <literal>#</literal>
+ character. A comprehensive description of all possible
+ configuration options is outside the scope of this book, so
+ only the most frequently modified directives will be described
+ here.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>ServerRoot "/usr/local"</literal></term>
+
+ <listitem>
+ <para>This specifies the default directory hierarchy for
+ the <application>Apache</application> installation. Binaries are stored in the
+ <filename>bin</filename> and
+ <filename>sbin</filename> subdirectories
+ of the server root, and configuration files are stored in
+ <filename>etc/apache</filename>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ServerAdmin you@your.address</literal></term>
+
+ <listitem>
+ <para>The address to which problems with the server should
+ be emailed. This address appears on some
+ server-generated pages, such as error documents.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ServerName www.example.com</literal></term>
+
+ <listitem>
+ <para><literal>ServerName</literal> allows you to set a host name which is
+ sent back to clients for your server if it is different
+ to the one that the host is configured with (i.e., use <systemitem>www</systemitem>
+ instead of the host's real name).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DocumentRoot "/usr/local/www/data"</literal></term>
+
+ <listitem>
+ <para><literal>DocumentRoot</literal>: The directory out of which you will
+ serve your documents. By default, all requests are taken
+ from this directory, but symbolic links and aliases may
+ be used to point to other locations.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>It is always a good idea to make backup copies of your
+ <application>Apache</application> configuration file before making changes. Once you are
+ satisfied with your initial configuration you are ready to
+ start running <application>Apache</application>.</para>
+
+<!-- sect3 for performance tuning directives? maxservers minservers -->
+<!-- etc..?? -->
+
+<!-- Advanced configuration section.
+
+Performance tuning directives.
+
+Log file format -->
+
+ </sect2>
+
+ <sect2>
+ <title>Running <application>Apache</application></title>
+
+ <indexterm><primary>Apache</primary>
+ <secondary>starting or stopping</secondary></indexterm>
+
+ <para><application>Apache</application> does not run from the
+ <application>inetd</application> super server as many other
+ network servers do. It is configured to run standalone for
+ better performance for incoming HTTP requests from client web
+ browsers. A shell script wrapper is included to make
+ starting, stopping, and restarting the server as simple as
+ possible. To start up <application>Apache</application> for
+ the first time, just run:</para>
+
+ <screen>&prompt.root; <userinput>/usr/local/sbin/apachectl start</userinput></screen>
+
+ <para>You can stop the server at any time by typing:</para>
+
+ <screen>&prompt.root; <userinput>/usr/local/sbin/apachectl stop</userinput></screen>
+
+ <para>After making changes to the configuration file for any
+ reason, you will need to restart the server:</para>
+
+ <screen>&prompt.root; <userinput>/usr/local/sbin/apachectl restart</userinput></screen>
+
+ <para>To restart <application>Apache</application> without
+ aborting current connections, run:</para>
+
+ <screen>&prompt.root; <userinput>/usr/local/sbin/apachectl graceful</userinput></screen>
+
+ <para>Additional information available at
+ &man.apachectl.8; manual page.</para>
+
+ <para>To launch <application>Apache</application> at system
+ startup, add the following line to
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>apache_enable="YES"</programlisting>
+
+ <para>If you would like to supply additional command line
+ options for the <application>Apache</application>
+ <command>httpd</command> program started at system boot, you
+ may specify them with an additional line in
+ <filename>rc.conf</filename>:</para>
+
+ <programlisting>apache_flags=""</programlisting>
+
+ <para>Now that the web server is running, you can view your web
+ site by pointing a web browser to
+ <literal>http://localhost/</literal>. The default web page
+ that is displayed is
+ <filename>/usr/local/www/data/index.html</filename>.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>Virtual Hosting</title>
+
+ <para><application>Apache</application> supports two different
+ types of Virtual Hosting. The first method is Name-based
+ Virtual Hosting. Name-based virtual hosting uses the clients
+ HTTP/1.1 headers to figure out the hostname. This allows many
+ different domains to share the same IP address.</para>
+
+ <para>To setup <application>Apache</application> to use
+ Name-based Virtual Hosting add an entry like the following to
+ your <filename>httpd.conf</filename>:</para>
+
+ <programlisting>NameVirtualHost *</programlisting>
+
+ <para>If your webserver was named <systemitem class="fqdomainname">www.domain.tld</systemitem> and
+ you wanted to setup a virtual domain for
+ <systemitem class="fqdomainname">www.someotherdomain.tld</systemitem> then you would add
+ the following entries to
+ <filename>httpd.conf</filename>:</para>
+
+ <screen>&lt;VirtualHost *&gt;
+ServerName www.domain.tld
+DocumentRoot /www/domain.tld
+&lt;/VirtualHost&gt;
+
+&lt;VirtualHost *&gt;
+ServerName www.someotherdomain.tld
+DocumentRoot /www/someotherdomain.tld
+&lt;/VirtualHost&gt;</screen>
+
+ <para>Replace the addresses with the addresses you want to use
+ and the path to the documents with what you are using.</para>
+
+ <para>For more information about setting up virtual hosts,
+ please consult the official <application>Apache</application>
+ documentation at: <uri xlink:href="http://httpd.apache.org/docs/vhosts/">http://httpd.apache.org/docs/vhosts/</uri>.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>Apache Modules</title>
+
+ <indexterm><primary>Apache</primary>
+ <secondary>modules</secondary></indexterm>
+
+ <para>There are many different <application>Apache</application> modules available to add
+ functionality to the basic server. The FreeBSD Ports
+ Collection provides an easy way to install
+ <application>Apache</application> together with some of the
+ more popular add-on modules.</para>
+
+ <sect3>
+ <title>mod_ssl</title>
+
+ <indexterm><primary>web servers</primary>
+ <secondary>secure</secondary></indexterm>
+ <indexterm><primary>SSL</primary></indexterm>
+ <indexterm><primary>cryptography</primary></indexterm>
+
+ <para>The <application>mod_ssl</application> module uses the OpenSSL library to provide
+ strong cryptography via the Secure Sockets Layer (SSL v2/v3)
+ and Transport Layer Security (TLS v1) protocols. This
+ module provides everything necessary to request a signed
+ certificate from a trusted certificate signing authority so
+ that you can run a secure web server on &os;.</para>
+
+ <para>If you have not yet installed
+ <application>Apache</application>, then a version of <application>Apache</application>
+ 1.3.X that includes <application>mod_ssl</application> may be installed with the <package>www/apache13-modssl</package> port. SSL
+ support is also available for <application>Apache</application>&nbsp;2.X in the
+ <package>www/apache20</package> port,
+ where it is enabled by default.</para>
+
+<!-- XXX add more information about configuring mod_ssl here. -->
+<!-- Generating keys, getting the key signed, setting up your secure -->
+<!-- web server! -->
+ </sect3>
+
+ <sect3>
+ <title>Dynamic Websites with Perl &amp; PHP</title>
+ <para>In the past few years, more businesses have turned to the
+ Internet in order to enhance their revenue and increase
+ exposure. This has also increased the need for interactive
+ web content. While some companies, such as &microsoft;, have
+ introduced solutions into their proprietary products, the
+ open source community answered the call. Two options for
+ dynamic web content include mod_perl &amp; mod_php.</para>
+
+ <sect4>
+ <title>mod_perl</title>
+
+ <indexterm>
+ <primary>mod_perl</primary>
+ <secondary>Perl</secondary>
+ </indexterm>
+
+ <para>The <application>Apache</application>/Perl integration project brings together the
+ full power of the Perl programming language and the <application>Apache
+ HTTP Server</application>. With the <application>mod_perl</application> module it is possible to
+ write <application>Apache</application> modules entirely in Perl. In addition, the
+ persistent interpreter embedded in the server avoids the
+ overhead of starting an external interpreter and the penalty
+ of Perl start-up time.</para>
+
+ <para><application>mod_perl</application> is available a few
+ different ways. To use <application>mod_perl</application>
+ remember that <application>mod_perl</application> 1.0 only
+ works with <application>Apache</application> 1.3 and
+ <application>mod_perl</application> 2.0 only works with
+ <application>Apache</application> 2.
+ <application>mod_perl</application> 1.0 is available in
+ <package>www/mod_perl</package> and a
+ statically compiled version is available in
+ <package>www/apache13-modperl</package>.
+ <application>mod_perl</application> 2.0 is avaliable in
+ <package>www/mod_perl2</package>.</para>
+ </sect4>
+
+ <sect4>
+ <info><title>mod_php</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm>
+ <primary>mod_php</primary>
+ <secondary>PHP</secondary>
+ </indexterm>
+
+ <para><acronym>PHP</acronym>, also known as <quote>PHP:
+ Hypertext Preprocessor</quote> is a general-purpose scripting
+ language that is especially suited for Web development.
+ Capable of being embedded into <acronym>HTML</acronym> its
+ syntax draws upon C, &java;, and Perl with the intention of
+ allowing web developers to write dynamically generated
+ webpages quickly.</para>
+
+ <para>To gain support for <acronym>PHP</acronym>5 for the
+ <application>Apache</application> web server, begin by
+ installing the
+ <package>www/mod_php5</package>
+ port.</para>
+
+ <para>This will install and configure the modules required
+ to support dynamic <acronym>PHP</acronym> applications. Check
+ to ensure the following lines have been added to
+ <filename>/usr/local/etc/apache/httpd.conf</filename>:</para>
+
+ <programlisting>LoadModule php5_module libexec/apache/libphp5.so
+AddModule mod_php5.c
+ &lt;IfModule mod_php5.c&gt;
+ DirectoryIndex index.php index.html
+ &lt;/IfModule&gt;
+
+ &lt;IfModule mod_php5.c&gt;
+ AddType application/x-httpd-php .php
+ AddType application/x-httpd-php-source .phps
+ &lt;/IfModule&gt;</programlisting>
+
+ <para>Once completed, a simple call to the
+ <command>apachectl</command> command for a graceful
+ restart is needed to load the <acronym>PHP</acronym>
+ module:</para>
+
+ <screen>&prompt.root; <userinput>apachectl graceful</userinput></screen>
+
+ <para>The <acronym>PHP</acronym> support in &os; is extremely
+ modular so the base install is very limited. It is very easy
+ to add support using the
+ <package>lang/php5-extensions</package> port.
+ This port provides a menu driven interface to
+ <acronym>PHP</acronym> extension installation.
+ Alternatively, individual extensions can be installed using
+ the appropriate port.</para>
+
+ <para>For instance, to add support for the
+ <application>MySQL</application> database server to
+ <acronym>PHP</acronym>5, simply install the
+ <package>databases/php5-mysql</package>
+ port.</para>
+
+ <para>After installing an extension, the
+ <application>Apache</application> server must be reloaded to
+ pick up the new configuration changes.</para>
+
+ <screen>&prompt.root; <userinput>apachectl graceful</userinput></screen>
+ </sect4>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-ftp">
+ <info><title>File Transfer Protocol (FTP)</title>
+ <authorgroup>
+ <author><personname><firstname>Murray</firstname><surname>Stokely</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>FTP servers</primary></indexterm>
+
+ <sect2>
+ <title>Overview</title>
+
+ <para>The File Transfer Protocol (FTP) provides users with a
+ simple way to transfer files to and from an <acronym role="File Transfer Protocol">FTP</acronym> server. &os;
+ includes <acronym role="File Transfer Protocol">FTP</acronym>
+ server software, <application>ftpd</application>, in the base
+ system. This makes setting up and administering an <acronym role="File Transfer Protocol">FTP</acronym> server on FreeBSD
+ very straightforward.</para>
+ </sect2>
+
+ <sect2>
+ <title>Configuration</title>
+
+ <para>The most important configuration step is deciding which
+ accounts will be allowed access to the FTP server. A normal
+ FreeBSD system has a number of system accounts used for
+ various daemons, but unknown users should not be allowed to
+ log in with these accounts. The
+ <filename>/etc/ftpusers</filename> file is a list of users
+ disallowed any FTP access. By default, it includes the
+ aforementioned system accounts, but it is possible to add
+ specific users here that should not be allowed access to
+ FTP.</para>
+
+ <para>You may want to restrict the access of some users without
+ preventing them completely from using FTP. This can be
+ accomplished with the <filename>/etc/ftpchroot</filename>
+ file. This file lists users and groups subject to FTP access
+ restrictions. The &man.ftpchroot.5; manual page has all of
+ the details so it will not be described in detail here.</para>
+
+ <indexterm>
+ <primary>FTP</primary>
+ <secondary>anonymous</secondary>
+ </indexterm>
+
+ <para>If you would like to enable anonymous FTP access to your
+ server, then you must create a user named
+ <systemitem class="username">ftp</systemitem> on your &os; system. Users will then
+ be able to log on to your FTP server with a username of
+ <systemitem class="username">ftp</systemitem> or <systemitem class="username">anonymous</systemitem> and
+ with any password (by convention an email address for the user
+ should be used as the password). The FTP server will call
+ &man.chroot.2; when an anonymous user logs in, to restrict
+ access to only the home directory of the
+ <systemitem class="username">ftp</systemitem> user.</para>
+
+ <para>There are two text files that specify welcome messages to
+ be displayed to FTP clients. The contents of the file
+ <filename>/etc/ftpwelcome</filename> will be displayed to
+ users before they reach the login prompt. After a successful
+ login, the contents of the file
+ <filename>/etc/ftpmotd</filename> will be displayed. Note
+ that the path to this file is relative to the login environment, so the
+ file <filename>~ftp/etc/ftpmotd</filename> would be displayed
+ for anonymous users.</para>
+
+ <para>Once the FTP server has been configured properly, it must
+ be enabled in <filename>/etc/inetd.conf</filename>. All that
+ is required here is to remove the comment symbol
+ <quote>#</quote> from in front of the existing
+ <application>ftpd</application> line :</para>
+
+ <programlisting>ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l</programlisting>
+
+ <para>As explained in <xref linkend="network-inetd-hangup"/>, a
+ HangUP Signal must be sent to <application>inetd</application>
+ after this configuration file is changed.</para>
+
+ <para>You can now log on to your FTP server by typing:</para>
+
+ <screen>&prompt.user; <userinput>ftp localhost</userinput></screen>
+
+ </sect2>
+
+ <sect2>
+ <title>Maintaining</title>
+
+ <indexterm><primary>syslog</primary></indexterm>
+ <indexterm><primary>log files</primary>
+ <secondary>FTP</secondary></indexterm>
+
+ <para>The <application>ftpd</application> daemon uses
+ &man.syslog.3; to log messages. By default, the system log
+ daemon will put messages related to FTP in the
+ <filename>/var/log/xferlog</filename> file. The location of
+ the FTP log can be modified by changing the following line in
+ <filename>/etc/syslog.conf</filename>:</para>
+
+ <programlisting>ftp.info /var/log/xferlog</programlisting>
+
+ <indexterm>
+ <primary>FTP</primary>
+ <secondary>anonymous</secondary>
+ </indexterm>
+
+ <para>Be aware of the potential problems involved with running
+ an anonymous FTP server. In particular, you should think
+ twice about allowing anonymous users to upload files. You may
+ find that your FTP site becomes a forum for the trade of
+ unlicensed commercial software or worse. If you do need to
+ allow anonymous FTP uploads, then you should set up the
+ permissions so that these files can not be read by other
+ anonymous users until they have been reviewed.</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="network-samba">
+ <info><title>File and Print Services for &microsoft.windows; clients (Samba)</title>
+ <authorgroup>
+ <author><personname><firstname>Murray</firstname><surname>Stokely</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>Samba server</primary></indexterm>
+ <indexterm><primary>Microsoft Windows</primary></indexterm>
+ <indexterm>
+ <primary>file server</primary>
+ <secondary>Windows clients</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>print server</primary>
+ <secondary>Windows clients</secondary>
+ </indexterm>
+
+ <sect2>
+ <title>Overview</title>
+
+ <para><application>Samba</application> is a popular open source
+ software package that provides file and print services for
+ &microsoft.windows; clients. Such clients can connect to and
+ use FreeBSD filespace as if it was a local disk drive, or
+ FreeBSD printers as if they were local printers.</para>
+
+ <para><application>Samba</application> software packages should
+ be included on your FreeBSD installation media. If you did
+ not install <application>Samba</application> when you first
+ installed FreeBSD, then you can install it from the <package>net/samba3</package> port or package.</para>
+
+<!-- mention LDAP, Active Directory, WinBIND, ACL, Quotas, PAM, .. -->
+
+ </sect2>
+
+ <sect2>
+ <title>Configuration</title>
+
+ <para>A default <application>Samba</application> configuration
+ file is installed as
+ <filename>/usr/local/etc/smb.conf.default</filename>. This
+ file must be copied to
+ <filename>/usr/local/etc/smb.conf</filename> and customized
+ before <application>Samba</application> can be used.</para>
+
+ <para>The <filename>smb.conf</filename> file contains runtime
+ configuration information for
+ <application>Samba</application>, such as definitions of the
+ printers and <quote>file system shares</quote> that you would
+ like to share with &windows; clients. The
+ <application>Samba</application> package includes a web based
+ tool called <application>swat</application> which provides a
+ simple way of configuring the <filename>smb.conf</filename>
+ file.</para>
+
+ <sect3>
+ <title>Using the Samba Web Administration Tool (SWAT)</title>
+
+ <para>The Samba Web Administration Tool (SWAT) runs as a
+ daemon from <application>inetd</application>. Therefore, the
+ following line in <filename>/etc/inetd.conf</filename>
+ should be uncommented before <application>swat</application> can be
+ used to configure <application>Samba</application>:</para>
+
+ <programlisting>swat stream tcp nowait/400 root /usr/local/sbin/swat</programlisting>
+ <para>As explained in <xref linkend="network-inetd-hangup"/>, a
+ HangUP Signal must be sent to
+ <application>inetd</application> after this configuration
+ file is changed.</para>
+
+ <para>Once <application>swat</application> has been enabled in
+ <filename>inetd.conf</filename>, you can use a browser to
+ connect to <uri xlink:href="http://localhost:901">http://localhost:901</uri>. You will
+ first have to log on with the system <systemitem class="username">root</systemitem> account.</para>
+
+<!-- XXX screenshots go here, loader is creating them -->
+
+ <para>Once you have successfully logged on to the main
+ <application>Samba</application> configuration page, you can
+ browse the system documentation, or begin by clicking on the
+ <guimenu>Globals</guimenu> tab. The <guimenu>Globals</guimenu> section corresponds to the
+ variables that are set in the <literal>[global]</literal>
+ section of
+ <filename>/usr/local/etc/smb.conf</filename>.</para>
+ </sect3>
+
+ <sect3>
+ <title>Global Settings</title>
+
+ <para>Whether you are using <application>swat</application> or
+ editing <filename>/usr/local/etc/smb.conf</filename>
+ directly, the first directives you are likely to encounter
+ when configuring <application>Samba</application>
+ are:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>workgroup</literal></term>
+
+ <listitem>
+ <para>NT Domain-Name or Workgroup-Name for the computers
+ that will be accessing this server.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>netbios name</literal></term>
+
+ <listitem>
+ <indexterm><primary>NetBIOS</primary></indexterm>
+
+ <para>This sets the NetBIOS name by which a <application>Samba</application> server
+ is known. By default it is the same as the first
+ component of the host's DNS name.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>server string</literal></term>
+
+ <listitem>
+ <para>This sets the string that will be displayed with
+ the <command>net view</command> command and some other
+ networking tools that seek to display descriptive text
+ about the server.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3>
+ <title>Security Settings</title>
+
+ <para>Two of the most important settings in
+ <filename>/usr/local/etc/smb.conf</filename> are the
+ security model chosen, and the backend password format for
+ client users. The following directives control these
+ options:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>security</literal></term>
+
+ <listitem>
+ <para>The two most common options here are
+ <literal>security = share</literal> and <literal>security
+ = user</literal>. If your clients use usernames that
+ are the same as their usernames on your &os; machine
+ then you will want to use user level security. This
+ is the default security policy and it requires clients
+ to first log on before they can access shared
+ resources.</para>
+
+ <para>In share level security, client do not need to log
+ onto the server with a valid username and password
+ before attempting to connect to a shared resource.
+ This was the default security model for older versions
+ of <application>Samba</application>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>passdb backend</literal></term>
+
+ <listitem>
+ <para><application>Samba</application> has several
+ different backend authentication models. You can
+ authenticate clients with LDAP<indexterm><primary>LDAP</primary></indexterm>,
+ NIS+<indexterm><primary>NIS+</primary></indexterm>, a SQL database<indexterm><primary>SQL database</primary></indexterm>,
+ or a modified password file. The default
+ authentication method is <literal>smbpasswd</literal>,
+ and that is all that will be covered here.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>Assuming that the default <literal>smbpasswd</literal>
+ backend is used, the
+ <filename>/usr/local/private/smbpasswd</filename> file must
+ be created to allow <application>Samba</application> to
+ authenticate clients. If you would like to give all of
+ your &unix; user accounts access from &windows; clients, use the
+ following command:</para>
+
+ <screen>&prompt.root; <userinput>grep -v "^#" /etc/passwd | make_smbpasswd &gt; /usr/local/private/smbpasswd</userinput>
+&prompt.root; <userinput>chmod 600 /usr/local/private/smbpasswd</userinput></screen>
+
+ <para>Please see the <application>Samba</application>
+ documentation for additional information about configuration
+ options. With the basics outlined here, you should have
+ everything you need to start running
+ <application>Samba</application>.</para>
+ </sect3>
+
+ </sect2>
+ <sect2>
+ <title>Starting <application>Samba</application></title>
+
+ <para>To enable <application>Samba</application> when your
+ system boots, add the following line to
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>samba_enable="YES"</programlisting>
+
+ <para>You can then start <application>Samba</application> at any
+ time by typing:</para>
+
+ <screen>&prompt.root; <userinput>/usr/local/etc/rc.d/samba.sh start</userinput>
+Starting SAMBA: removing stale tdbs :
+Starting nmbd.
+Starting smbd.</screen>
+
+ <para><application>Samba</application> actually consists of
+ three separate daemons. You should see that both the
+ <application>nmbd</application> and <application>smbd</application> daemons
+ are started by the <filename>samba.sh</filename> script. If
+ you enabled winbind name resolution services in
+ <filename>smb.conf</filename>, then you will also see that
+ the <application>winbindd</application> daemon is started.</para>
+
+ <para>You can stop <application>Samba</application> at any time
+ by typing :</para>
+
+ <screen>&prompt.root; <userinput>/usr/local/etc/rc.d/samba.sh stop</userinput></screen>
+
+ <para><application>Samba</application> is a complex software
+ suite with functionality that allows broad integration with
+ &microsoft.windows; networks. For more information about
+ functionality beyond the basic installation described here,
+ please see <uri xlink:href="http://www.samba.org">http://www.samba.org</uri>.</para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="network-ntp">
+ <info><title>Clock Synchronization with NTP</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Hukins</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>NTP</primary></indexterm>
+
+ <sect2>
+ <title>Overview</title>
+
+ <para>Over time, a computer's clock is prone to drift. The
+ Network Time Protocol (NTP) is one way to ensure your clock stays
+ accurate.</para>
+
+ <para>Many Internet services rely on, or greatly benefit from,
+ computers' clocks being accurate. For example, a web server
+ may receive requests to send a file if it has been modified since a
+ certain time. In a local area network environment, it is
+ essential that computers sharing files from the same file
+ server have synchronized clocks so that file timestamps stay
+ consistent. Services such as &man.cron.8; also rely on
+ an accurate system clock to run commands at the specified
+ times.</para>
+
+ <indexterm>
+ <primary>NTP</primary>
+ <secondary>ntpd</secondary>
+ </indexterm>
+ <para>FreeBSD ships with the &man.ntpd.8; <acronym role="Network Time Protocol">NTP</acronym> server which can be used to query
+ other <acronym role="Network Time Protocol">NTP</acronym>
+ servers to set the clock on your machine or provide time
+ services to others.</para>
+ </sect2>
+
+ <sect2>
+ <title>Choosing Appropriate NTP Servers</title>
+
+ <indexterm>
+ <primary>NTP</primary>
+ <secondary>choosing servers</secondary>
+ </indexterm>
+
+ <para>In order to synchronize your clock, you will need to find
+ one or more <acronym role="Network Time Protocol">NTP</acronym> servers to use. Your network
+ administrator or ISP may have set up an NTP server for this
+ purpose&mdash;check their documentation to see if this is the
+ case. There is an <link xlink:href="http://ntp.isc.org/bin/view/Servers/WebHome">online
+ list of publicly accessible NTP servers</link> which you can
+ use to find an NTP server near to you. Make sure you are
+ aware of the policy for any servers you choose, and ask for
+ permission if required.</para>
+
+ <para>Choosing several unconnected NTP servers is a good idea in
+ case one of the servers you are using becomes unreachable or
+ its clock is unreliable. &man.ntpd.8; uses the responses it
+ receives from other servers intelligently&mdash;it will favor
+ unreliable servers less than reliable ones.</para>
+ </sect2>
+
+ <sect2>
+ <title>Configuring Your Machine</title>
+
+ <indexterm>
+ <primary>NTP</primary>
+ <secondary>configuration</secondary>
+ </indexterm>
+
+ <sect3>
+ <title>Basic Configuration</title>
+ <indexterm><primary>ntpdate</primary></indexterm>
+
+ <para>If you only wish to synchronize your clock when the
+ machine boots up, you can use &man.ntpdate.8;. This may be
+ appropriate for some desktop machines which are frequently
+ rebooted and only require infrequent synchronization, but
+ most machines should run &man.ntpd.8;.</para>
+
+ <para>Using &man.ntpdate.8; at boot time is also a good idea
+ for machines that run &man.ntpd.8;. The &man.ntpd.8;
+ program changes the clock gradually, whereas &man.ntpdate.8;
+ sets the clock, no matter how great the difference between a
+ machine's current clock setting and the correct time.</para>
+
+ <para>To enable &man.ntpdate.8; at boot time, add
+ <literal>ntpdate_enable="YES"</literal> to
+ <filename>/etc/rc.conf</filename>. You will also need to
+ specify all servers you wish to synchronize with and any
+ flags to be passed to &man.ntpdate.8; in
+ <varname>ntpdate_flags</varname>.</para>
+ </sect3>
+
+ <sect3>
+ <title>General Configuration</title>
+
+ <indexterm>
+ <primary>NTP</primary>
+ <secondary>ntp.conf</secondary>
+ </indexterm>
+
+ <para>NTP is configured by the
+ <filename>/etc/ntp.conf</filename> file in the format
+ described in &man.ntp.conf.5;. Here is a simple
+ example:</para>
+
+ <programlisting>server ntplocal.example.com prefer
+server timeserver.example.org
+server ntp2a.example.net
+
+driftfile /var/db/ntp.drift</programlisting>
+
+ <para>The <literal>server</literal> option specifies which
+ servers are to be used, with one server listed on each line.
+ If a server is specified with the <literal>prefer</literal>
+ argument, as with <systemitem class="fqdomainname">ntplocal.example.com</systemitem>, that server is
+ preferred over other servers. A response from a preferred
+ server will be discarded if it differs significantly from
+ other servers' responses, otherwise it will be used without
+ any consideration to other responses. The
+ <literal>prefer</literal> argument is normally used for NTP
+ servers that are known to be highly accurate, such as those
+ with special time monitoring hardware.</para>
+
+ <para>The <literal>driftfile</literal> option specifies which
+ file is used to store the system clock's frequency offset.
+ The &man.ntpd.8; program uses this to automatically
+ compensate for the clock's natural drift, allowing it to
+ maintain a reasonably correct setting even if it is cut off
+ from all external time sources for a period of time.</para>
+
+ <para>The <literal>driftfile</literal> option specifies which
+ file is used to store information about previous responses
+ from the NTP servers you are using. This file contains
+ internal information for NTP. It should not be modified by
+ any other process.</para>
+ </sect3>
+
+ <sect3>
+ <title>Controlling Access to Your Server</title>
+
+ <para>By default, your NTP server will be accessible to all
+ hosts on the Internet. The <literal>restrict</literal>
+ option in <filename>/etc/ntp.conf</filename> allows you to
+ control which machines can access your server.</para>
+
+ <para>If you want to deny all machines from accessing your NTP
+ server, add the following line to
+ <filename>/etc/ntp.conf</filename>:</para>
+
+ <programlisting>restrict default ignore</programlisting>
+
+ <para>If you only want to allow machines within your own
+ network to synchronize their clocks with your server, but
+ ensure they are not allowed to configure the server or used
+ as peers to synchronize against, add</para>
+
+ <programlisting>restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap</programlisting>
+
+ <para>instead, where <systemitem class="ipaddress">192.168.1.0</systemitem> is
+ an IP address on your network and <systemitem class="netmask">255.255.255.0</systemitem> is your network's
+ netmask.</para>
+
+ <para><filename>/etc/ntp.conf</filename> can contain multiple
+ <literal>restrict</literal> options. For more details, see
+ the <literal>Access Control Support</literal> subsection of
+ &man.ntp.conf.5;.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Running the NTP Server</title>
+
+ <para>To ensure the NTP server is started at boot time, add the
+ line <literal>ntpd_enable="YES"</literal> to
+ <filename>/etc/rc.conf</filename>. If you wish to pass
+ additional flags to &man.ntpd.8;, edit the
+ <varname>ntpd_flags</varname> parameter in
+ <filename>/etc/rc.conf</filename>.</para>
+
+ <para>To start the server without rebooting your machine, run
+ <command>ntpd</command> being sure to specify any additional
+ parameters from <varname>ntpd_flags</varname> in
+ <filename>/etc/rc.conf</filename>. For example:</para>
+
+ <screen>&prompt.root; <userinput>ntpd -p /var/run/ntpd.pid</userinput></screen>
+
+ <note>
+ <para>Under &os;&nbsp;4.X,
+ you have to replace every instance of <literal>ntpd</literal>
+ with <literal>xntpd</literal> in the options above.</para></note>
+ </sect2>
+
+ <sect2>
+ <title>Using ntpd with a Temporary Internet
+ Connection</title>
+
+ <para>The &man.ntpd.8; program does not need a permanent
+ connection to the Internet to function properly. However, if
+ you have a temporary connection that is configured to dial out
+ on demand, it is a good idea to prevent NTP traffic from
+ triggering a dial out or keeping the connection alive. If you
+ are using user PPP, you can use <literal>filter</literal>
+ directives in <filename>/etc/ppp/ppp.conf</filename>. For
+ example:</para>
+
+ <programlisting> set filter dial 0 deny udp src eq 123
+ # Prevent NTP traffic from initiating dial out
+ set filter dial 1 permit 0 0
+ set filter alive 0 deny udp src eq 123
+ # Prevent incoming NTP traffic from keeping the connection open
+ set filter alive 1 deny udp dst eq 123
+ # Prevent outgoing NTP traffic from keeping the connection open
+ set filter alive 2 permit 0/0 0/0</programlisting>
+
+ <para>For more details see the <literal>PACKET
+ FILTERING</literal> section in &man.ppp.8; and the examples in
+ <filename>/usr/share/examples/ppp/</filename>.</para>
+
+ <note>
+ <para>Some Internet access providers block low-numbered ports,
+ preventing NTP from functioning since replies never
+ reach your machine.</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Further Information</title>
+
+ <para>Documentation for the NTP server can be found in
+ <filename>/usr/share/doc/ntp/</filename> in HTML
+ format.</para>
+ </sect2>
+ </sect1>
+
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/pgpkeys/Makefile b/zh_TW.UTF-8/books/handbook/pgpkeys/Makefile
new file mode 100644
index 0000000000..cd4e52bafd
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/pgpkeys/Makefile
@@ -0,0 +1,18 @@
+#
+# Build the Handbook with just the content from this chapter.
+# $FreeBSD$
+#
+
+CHAPTERS= pgpkeys/chapter.xml
+
+PGPKEYS!= perl -ne 'm/\"([\w-]+.key)\"/ && print "$$1\n"' \
+ ${DOC_PREFIX}/share/pgpkeys/pgpkeys.ent
+SRCS+= ${PGPKEYS}
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/pgpkeys/chapter.xml b/zh_TW.UTF-8/books/handbook/pgpkeys/chapter.xml
new file mode 100644
index 0000000000..6c324fdd72
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/pgpkeys/chapter.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.285
+-->
+<!--
+
+ Do not edit this file except as instructed by the addkey.sh script.
+
+ See the README file in doc/share/pgpkeys for instructions.
+
+-->
+<appendix xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="pgpkeys">
+ <title>PGP Keys</title>
+
+ <indexterm><primary>pgp keys</primary></indexterm>
+ <para>In case you need to verify a signature or send encrypted email
+ to one of the officers or developers a number of keys are provided
+ here for your convenience. A complete keyring of <systemitem class="fqdomainname">FreeBSD.org</systemitem>
+ users is available for download from <link xlink:href="&url.base;/doc/pgpkeyring.txt">http://www.FreeBSD.org/doc/pgpkeyring.txt</link>.</para>
+
+ <sect1 xml:id="pgpkeys-officers">
+ <title>Officers</title>
+
+ &section.pgpkeys-officers;
+ </sect1>
+
+ <sect1 xml:id="pgpkeys-core">
+ <title>Core Team Members</title>
+
+ &section.pgpkeys-core;
+ </sect1>
+
+ <sect1 xml:id="pgpkeys-developers">
+ <title>Developers</title>
+
+ &section.pgpkeys-developers;
+ </sect1>
+</appendix>
diff --git a/zh_TW.UTF-8/books/handbook/ports/Makefile b/zh_TW.UTF-8/books/handbook/ports/Makefile
new file mode 100644
index 0000000000..f5ebfe0a14
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/ports/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= ports/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/ports/chapter.xml b/zh_TW.UTF-8/books/handbook/ports/chapter.xml
new file mode 100644
index 0000000000..5101cdf34b
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/ports/chapter.xml
@@ -0,0 +1,1300 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.273
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="ports">
+ <title>軟體套件管理篇:Packages 及 Ports 機制</title>
+
+ <sect1 xml:id="ports-synopsis">
+ <title>概述</title>
+
+ <indexterm><primary>ports</primary></indexterm>
+ <indexterm><primary>packages</primary></indexterm>
+ <para>儘管 FreeBSD 在 base system 已加了很多系統工具。
+ 然而,在實務運用上,您可能仍需要安裝額外的軟體。
+ FreeBSD 提供了 2 種安裝應用程式的套件管理系統︰Ports Collection
+ (以 soucre 來編譯、安裝) 和 package(預先編譯好的 binary 檔)。
+ 上述的方式,無論要用哪一種,都可以由像是 CDROM
+ 等或網路上來安裝想裝的最新版軟體。</para>
+
+ <para>讀完這章,您將了解:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>如何以 packages 來安裝軟體。</para>
+ </listitem>
+ <listitem>
+ <para>如何以 ports 來安裝軟體。</para>
+ </listitem>
+ <listitem>
+ <para>已安裝的 packages 或 ports 要如何移除。</para>
+ </listitem>
+ <listitem>
+ <para>如何更改(override) ports collection 所使用的預設值。</para>
+ </listitem>
+ <listitem>
+ <para>如何在套件管理系統中,找出想裝的軟體。</para>
+ </listitem>
+ <listitem>
+ <para>如何升級已安裝的軟體。</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="ports-overview">
+ <title>安裝軟體的各種方式介紹</title>
+
+ <para>通常要在 &unix; 系統上安裝軟體時,有幾個步驟要作:</para>
+
+ <procedure>
+ <step>
+ <para>先下載該軟體壓縮檔(tarball),有可能是原始碼或是 binary 執行檔。
+ </para>
+ </step>
+
+ <step>
+ <para>解開該壓縮檔。(通常是以
+ &man.compress.1; , &man.gzip.1; 或 &man.bzip2.1; 壓縮的)</para>
+ </step>
+
+ <step>
+ <para>閱讀相關文件檔,以了解如何安裝。(通常檔名是
+ <filename>INSTALL</filename> 或 <filename>README</filename>
+ ,或在 <filename>doc/</filename> 目錄下的一些文件)</para>
+ </step>
+
+ <step>
+ <para>如果所下載的是原始碼,可能要先修改
+ <filename>Makefile</filename> 或是執行
+ <command>./configure</command> 之類的 script
+ ,接著再編譯該軟體。</para>
+ </step>
+
+ <step>
+ <para>最後測試再測試與安裝。</para>
+ </step>
+ </procedure>
+
+ <para>如果一切順利的話,就這麼簡單。
+ 如果在安裝非專門設計(移植)給 FreeBSD 的軟體時出問題,
+ 那可能需要修改一下它的程式碼,才能正常使用。</para>
+
+ <para>當然,我們可以在 FreeBSD 上使用上述的傳統方式來安裝軟體,
+ 但是,我們還有更簡單的選擇。
+ FreeBSD 提供了兩種省事的軟體管理機制: packages 和 ports。
+ 就在寫這篇文章的時候,
+ 已經有超過 &os.numports; 個 port 軟體可以使用。</para>
+
+ <para>所謂的 FreeBSD package 就是別人把該應用程式編譯、打包完畢。
+ 該 package 會包括該應用程式的所有執行檔、設定檔、文件等。
+ 而下載到硬碟上的 package 都可透過 FreeBSD 套件管理指令來進行管理,比如:
+ &man.pkg.add.1;、&man.pkg.delete.1;、&man.pkg.info.1; 等指令。
+ 所以,只需簡單打個指令就可輕鬆安裝新的應用程式了。</para>
+
+ <para>而 FreeBSD port 則是用一些檔案,來自動處理應用程式的安裝流程。</para>
+
+ <para>請記住:如果打算自己來編譯的話,需要執行很多操作步驟
+ (下載、解壓、patch、編譯、安裝)。
+ 而 port 呢,則是涵蓋所有需要完成這些工作的必備步驟,
+ 所以只需打一些簡單的指令,那些原始程式碼就會自動下載、解壓、
+ patch、編譯,直至安裝完畢。</para>
+
+ <para>事實上,ports 機制還可以用來產生 packages,以便他人可以用
+ <command>pkg_add</command> 來安裝,
+ 或是稍後會介紹到的其他套件管理指令。</para>
+
+ <para>而 packages 以及 ports 它們都是一樣會認
+ <emphasis>dependencies(軟體相依關係)</emphasis>。
+ 假設:您想安裝某程式,但它有相依另一個已裝的函式庫(library),
+ 而在 FreeBSD 的 port 以及 package 都有這程式以及該函式庫了。
+ 所以無論是用 <command>pkg_add</command> 指令或者 port 方式來裝該程式,
+ 這兩者(package、port)都會先檢查有沒有裝該函式庫,
+ 若沒有就會自動先裝該函式庫了。</para>
+
+ <para>這兩種技術都很相似,您可能會好奇為什麼 FreeBSD 會弄出這兩種技術來呢。
+ 其實,packages 和 ports 都有它們各自的長處,
+ 使用哪一種完全取決於您自己的喜好。</para>
+
+ <itemizedlist>
+ <title>Package 好處在於:</title>
+
+ <listitem>
+ <para>同樣是壓縮過的 package 與原始碼 tarball 相比,
+ 前者通常會比後者小多了。</para>
+ </listitem>
+
+ <listitem>
+ <para>package 並不需再進行編譯。
+ 對大型應用程式如 <application>Mozilla</application>、
+ <application>KDE</application>、
+ <application>GNOME</application> 而言,這點顯得相當重要,
+ 尤其是使用速度緩慢的機器。</para>
+ </listitem>
+
+ <listitem>
+ <para>不需要瞭解如何在 FreeBSD 上編譯軟體的相關細節過程,
+ 即可使用 package。</para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <title>Ports 好處在於:</title>
+
+ <listitem>
+ <para>為了讓 package 能在大多數系統上順利執行,
+ 通常在編譯時會使用比較保守的選項。 然而,
+ 透過 port 安裝的話,則可針對特定環境(比如: Pentium 4 或 Athlon CPU)
+ 來調整選項,以符合需求。</para>
+ </listitem>
+
+ <listitem>
+ <para>有些程式在編譯時,會有一些選項可以選擇。
+ 舉例來說,<application>Apache</application>
+ 可以設定一大堆的編譯選項。 若透過 port 來安裝的話,
+ 會比較彈性多了,可以自己選而不必使用預設的編譯選項。</para>
+
+ <para>在某些情況,同樣的程式但不同編譯選項,則會分成不同的 package。
+ 比如:
+ <application>Ghostscript</application> 會因為是否要裝 X11 server,
+ 而劃分為 <filename>ghostscript</filename> 以及
+ <filename>ghostscript-nox11</filename> 這兩種 package。
+ 如此的調整對 package 算是可成立的,
+ 但若該程式有一個以上或兩種不同的編譯選項時,
+ 這對 package 就沒辦法了。</para>
+ </listitem>
+
+ <listitem>
+ <para>某些軟體的禁止以 binary 方式散佈,
+ 或者說必須以原始碼方式散佈才可。</para>
+ </listitem>
+
+ <listitem>
+ <para>有些人並不信任 binary 套件機制,因為他們覺得至少有原始碼,
+ (理論上)就可以自己檢閱,並尋找是否有潛在的問題。</para>
+ </listitem>
+
+ <listitem>
+ <para>若要對軟體加上自己改過的 patch,
+ 那麼就必須要先有原始碼才能去上相關 patch 修正。</para>
+ </listitem>
+
+ <listitem>
+ <para>有些人喜歡有原始碼在手邊,
+ 所以他們無聊時就可以自己閱讀、鑽研、借用
+ (當然要符合原始碼本身的授權規定)原始碼等等。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>若想注意 port 更新動態的話,可以訂閱
+ &a.ports; 以及 &a.ports-bugs;。</para>
+
+ <warning>
+ <para>在安裝軟體前,最好先看 <uri xlink:href="http://vuxml.freebsd.org/">http://vuxml.freebsd.org/</uri> 內是否有該軟體的安全漏洞通報。
+ </para>
+
+ <para>此外,也可以裝 <package>ports-mgmt/portaudit</package>,它會自動檢查所有已裝的
+ 的軟體是否有已知的安全漏洞,另外,它還會在裝軟體的編譯過程前先行檢查。
+ 也可以在裝了某些軟體之後,用 <command>portaudit -F -a</command>
+ 來作全面強制安檢。</para>
+ </warning>
+
+ <para>本章接下來將介紹如何在 FreeBSD 使用 package 及 port 來安裝、管理
+ third-party 軟體。</para>
+ </sect1>
+
+ <sect1 xml:id="ports-finding-applications">
+ <title>尋找想裝的軟體</title>
+
+ <para>在安裝任何軟體之前,你必須先了解你想要什麼的軟體,
+ 以及該軟體叫做什麼名稱。</para>
+
+ <para>FreeBSD 上可裝的軟體清單不斷在增加中,
+ 不過,我們很慶幸有幾種方式可以來找你想裝的軟體:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>FreeBSD 網站上有更新頻繁的軟體清單,在
+ <link xlink:href="&url.base;/ports/index.html">http://www.FreeBSD.org/ports/
+ </link>。
+ 各 ports 皆依其性質而分門別類,既可以透過軟體名稱來搜尋
+ (如果知道名字的話),
+ 也可以在分類中列出所有可用的軟體。</para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>FreshPorts</primary></indexterm>
+
+ <para>由 Dan Langille 所維護 FreshPorts 網站,網址在 <uri xlink:href="http://www.FreshPorts.org/">http://www.FreshPorts.org/</uri>。
+ FreshPorts 會不斷追蹤 port tree 中的各種變化,
+ 也可以針對某些 port 以列入 <quote>追蹤名單(watch)</quote> 內,
+ 當有任何軟體升級時,就會發 email 提醒。</para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>FreshMeat</primary></indexterm>
+
+ <para>如果不知道想裝的軟體名稱,那麼可透過像是 FreshMeat (<uri xlink:href="http://www.freshmeat.net/">http://www.freshmeat.net/</uri>) 這類的網站來找,
+ 如果找到了,可以回 FreeBSD 網站去看一下這個應用程式是否已經被
+ port 進去了。</para>
+ </listitem>
+
+ <listitem>
+ <para>若知道該 port 的正確名稱,但不知道放在哪個分類目錄,可以用
+ &man.whereis.1; 指令來找出來。 只要打 <command>whereis
+ file</command> 即可,而
+ <replaceable>file</replaceable> 的地方請改為想裝的軟體名稱。
+ 若找到該軟體,就會告訴你,就像下面這樣:</para>
+
+ <screen>&prompt.root; <userinput>whereis lsof</userinput>
+lsof: /usr/ports/sysutils/lsof</screen>
+
+ <para>如此一來,就會知道 <command>lsof</command> (系統工具程式) 是放在
+ <filename>/usr/ports/sysutils/lsof</filename> 目錄。</para></listitem>
+
+ <listitem>
+ <para>此外,也可以用 &man.echo.1; 輕鬆找出該 port 是位於 porte tree
+ 的何處。 舉例來說:</para>
+
+ <screen>&prompt.root; <userinput>echo /usr/ports/*/*lsof*</userinput>
+/usr/ports/sysutils/lsof</screen>
+
+ <para>請注意,這也會顯示 <filename>/usr/ports/distfiles</filename> 目錄內有符合檔名的檔案。</para>
+ </listitem>
+
+ <listitem>
+ <para>還有另一招,就是用 Ports Collection 本身內建的搜尋機制。
+ 要用的時候,請先切換到 <filename>/usr/ports</filename> 目錄。
+ 然後,打 <command>make search name=程式名稱</command>
+ ,其中 <replaceable>程式名稱</replaceable> 請改為想找的軟體名稱。
+ 舉例來說,若要找的是 <command>lsof</command> 的話,那麼就是:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports</userinput>
+&prompt.root; <userinput>make search name=lsof</userinput>
+Port: lsof-4.56.4
+Path: /usr/ports/sysutils/lsof
+Info: Lists information about open files (similar to fstat(1))
+Maint: obrien@FreeBSD.org
+Index: sysutils
+B-deps:
+R-deps: </screen>
+
+ <para>這些搜尋結果中,要注意的是 <quote>Path:</quote> 這行,
+ 因為這行會告訴你可以在哪邊找到該 port。
+ 而搜尋結果的其他部分,因為與 port 安裝較無關係,所以這裡就不講了。</para>
+
+ <para>若要更徹底的搜尋,那麼可以改用 <command>make
+ search key=string</command>,其中
+ <replaceable>string</replaceable> 請改為想搜尋的關鍵字。
+ 如此一來會找 port 名稱、軟體簡介(comments)、軟體敘述檔(descriptions)
+ 以及軟體相依關係(dependencies)裡面是否有符合關鍵字,
+ 此外,不清楚軟體名稱的話,也可以拿來找有符合關鍵字主題的 port。</para>
+
+ <para>剛講的這兩種方式,搜尋字眼都是 case-insensitive(不必區分大小寫)。
+ 比如,搜尋 <quote>LSOF</quote> 與 <quote>lsof</quote>
+ 兩者結果都會是一樣的。</para>
+ </listitem>
+
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="packages-using">
+ <info><title>使用 Packages 管理機制</title>
+ <authorgroup>
+ <author><personname><firstname>Chern</firstname><surname>Lee</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <sect2>
+ <title>Package 的安裝方式</title>
+ <indexterm>
+ <primary>packages</primary>
+ <secondary>installing</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary><command>pkg_add</command></primary>
+ </indexterm>
+ <para>可以用 &man.pkg.add.1; 從本機上或者透過網路來安裝任一
+ FreeBSD package。</para>
+
+ <example>
+ <title>手動下載、安裝 Package</title>
+
+ <screen>&prompt.root; <userinput>ftp -a ftp2.FreeBSD.org</userinput>
+Connected to ftp2.FreeBSD.org.
+220 ftp2.FreeBSD.org FTP server (Version 6.00LS) ready.
+331 Guest login ok, send your email address as password.
+230-
+230- This machine is in Vienna, VA, USA, hosted by Verio.
+230- Questions? E-mail freebsd@vienna.verio.net.
+230-
+230-
+230 Guest login ok, access restrictions apply.
+Remote system type is UNIX.
+Using binary mode to transfer files.
+<prompt>ftp&gt;</prompt> <userinput>cd /pub/FreeBSD/ports/packages/sysutils/</userinput>
+250 CWD command successful.
+<prompt>ftp&gt;</prompt> <userinput>get lsof-4.56.4.tgz</userinput>
+local: lsof-4.56.4.tgz remote: lsof-4.56.4.tgz
+200 PORT command successful.
+150 Opening BINARY mode data connection for 'lsof-4.56.4.tgz' (92375 bytes).
+100% |**************************************************| 92375 00:00 ETA
+226 Transfer complete.
+92375 bytes received in 5.60 seconds (16.11 KB/s)
+<prompt>ftp&gt;</prompt> <userinput>exit</userinput>
+&prompt.root; <userinput>pkg_add lsof-4.56.4.tgz</userinput></screen>
+ </example>
+
+ <para>若手邊沒有 package 來源(像是 FreeBSD 光碟)的話,
+ 那麼建議使用 &man.pkg.add.1; 時,加上 <option>-r</option>
+ 選項來更輕鬆安裝 package。如此一來,就會自動判斷正確的 package 格式、
+ 以及所搭配的作業系統 release 版本,
+ 然後會自己從 FTP 站抓回、安裝相對應的 package。
+ </para>
+
+ <indexterm>
+ <primary><command>pkg_add</command></primary></indexterm>
+ <screen>&prompt.root; <userinput>pkg_add -r lsof</userinput></screen>
+
+ <para>上面這例子會自動下載正確的 package 並安裝。
+ 若想改換用其他 &os; Packages Mirror 站,那麼就要設定
+ <envar>PACKAGESITE</envar> 環境變數,
+ 如此一來才會取代預設設定。 &man.pkg.add.1;
+ 會用 &man.fetch.3; 指令來下載檔案,而 &man.fetch.3;
+ 本身則會使用相關環境變數的設定,
+ 像是:
+ <envar>FTP_PASSIVE_MODE</envar>、<envar>FTP_PROXY</envar> 以及
+ <envar>FTP_PASSWORD</envar>。 如果你網路環境處於 firewall
+ 後面,或者需要用 FTP/HTTP proxy 的話,那麼就需要設定。
+ 設定細節請參閱 &man.fetch.3;。
+ 請注意:上面所說的例子是寫 <literal>lsof</literal> 而非
+ <literal>lsof-4.56.4</literal>。 當使用遠端抓取功能時,該
+ package 版號就不必加上去了。
+ &man.pkg.add.1; 會自動下載該軟體的最新版回來安裝。</para>
+
+ <note>
+ <para>若用的是 &os.current; 或 &os.stable; 的話,&man.pkg.add.1;
+ 會自動下載該軟體最新版回來。
+ 若用的是屬於 -RELEASE 版本,那麼他會抓回屬於該 release 上所編譯的
+ package。
+ 也可以更改 <envar>PACKAGESITE</envar> 環境變數,以改變下載方式。
+ 舉例來說,如果是 &os;&nbsp;5.4-RELEASE 的話,那麼 &man.pkg.add.1;
+ 預設會從
+ <literal>ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-5.4-release/Latest/</literal>
+ 來抓 package。若要強制 &man.pkg.add.1; 下載 &os;&nbsp;5-STABLE
+ 所用的 package,那麼就把 <envar>PACKAGESITE</envar> 改設為
+ <literal>ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-5-stable/Latest/</literal>
+ 即可。
+ </para>
+ </note>
+
+ <para>Package 檔有 <filename>.tgz</filename> 以及
+ <filename>.tbz</filename> 兩種格式。
+ 這些都可透過 <uri xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/packages/">ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/packages/</uri>
+ ,或者 FreeBSD 光碟內取得。
+ 每張 4 片裝的 FreeBSD 光碟(以及 PowerPak 包等等)內都會在
+ <filename>/packages</filename> 目錄內放 package。
+ 裡面的目錄架構類似 <filename>/usr/ports</filename> 的目錄架構。
+ 每個分類都各自有專屬目錄,且每份 package 都會放在
+ <filename>All</filename> 目錄內。
+ </para>
+
+ <para>package 目錄架構與 port 的都一致;它們共同構成整個 package/port
+ 系統機制。</para>
+
+ </sect2>
+
+ <sect2>
+ <title>管理 Packages</title>
+
+ <indexterm>
+ <primary>packages</primary>
+ <secondary>managing</secondary>
+ </indexterm>
+ <para>&man.pkg.info.1; 可用來列出所有已安裝的軟體、軟體簡介。</para>
+
+ <indexterm>
+ <primary><command>pkg_info</command></primary>
+ </indexterm>
+ <screen>&prompt.root; <userinput>pkg_info</userinput>
+cvsup-16.1 A general network file distribution system optimized for CV
+docbook-1.2 Meta-port for the different versions of the DocBook DTD
+...</screen>
+ <para>&man.pkg.version.1; 則是列出所有已安裝的軟體版本。
+ 它會顯示已裝版本以及目前機器上 port tree 的版本差異。
+ </para>
+ <indexterm>
+ <primary><command>pkg_version</command></primary>
+ </indexterm>
+ <screen>&prompt.root; <userinput>pkg_version</userinput>
+cvsup =
+docbook =
+...</screen>
+
+ <para>第二欄的符號表示:已安裝的軟體版本與目前機器上 port tree
+ 的版本差異。</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>符號</entry>
+ <entry>代表意義</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>=</entry> <entry>已裝的版本與目前機器上 port tree
+ 的版本是同一版的。
+ </entry>
+ </row>
+
+ <row><entry>&lt;</entry>
+ <entry>與目前機器上 port tree 版本相比起來,已裝的版本較舊。</entry>
+ </row>
+
+ <row><entry>&gt;</entry><entry>與目前機器上 port tree 版本相比起來,
+ 已裝的版本較新。(可能是目前機器上 port tree 尚未更新。)</entry></row>
+
+ <row><entry>?</entry><entry>已裝的軟體在 ports 索引內找無相關資料。
+ (通常可能是,舉例來說:已安裝的該 port 已從 Ports Collection
+ 中移除或改名了。)
+ </entry></row>
+
+ <row><entry>*</entry><entry>該軟體同時有許多版本。</entry></row>
+
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>移除已安裝的 Package</title>
+ <indexterm>
+ <primary><command>pkg_delete</command></primary>
+ </indexterm>
+ <indexterm>
+ <primary>packages</primary>
+ <secondary>deleting</secondary>
+ </indexterm>
+ <para>若要移除已裝的軟體,那麼請多利用 &man.pkg.delete.1; 工具,比如:
+ </para>
+
+ <screen>&prompt.root; <userinput>pkg_delete xchat-1.7.1</userinput></screen>
+
+ <para>請注意 &man.pkg.delete.1; 須要放上完整的軟體名稱以及版本,
+ 若只輸入 <replaceable>xchat</replaceable> 就不行,必須換成
+ <replaceable>xchat-1.7.1</replaceable> 才可。 然而,我們可以用
+ &man.pkg.version.1; 輕鬆找出已裝的所有軟體版本,或者以 wildcard
+ (萬用字元) 的方式:</para>
+
+ <screen>&prompt.root; <userinput>pkg_delete xchat\*</userinput></screen>
+
+ <para>以上面例子而言,將會移除所有以 <literal>xchat</literal>
+ 開頭的軟體。</para>
+ </sect2>
+
+ <sect2>
+ <title>其他細節部份</title>
+ <para>所有已裝的 package 資訊都會存到 <filename>/var/db/pkg</filename>
+ 目錄內,在該目錄下可以找到記載已裝的軟體檔案清單及該軟體簡介的檔案。
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="ports-using">
+ <title>使用 Ports 管理機制</title>
+
+ <para>下面我們會介紹如何使用 Ports Collection 來安裝、移除軟體的基本用法。
+ 至於其他可用的 <command>make</command> 詳細用法與環境設定,可參閱
+ &man.ports.7;。</para>
+
+ <sect2 xml:id="ports-tree">
+ <title>記得安裝 Ports Collection</title>
+
+ <para>在安裝任一 ports 之前,必須先裝上
+ Ports Collection —— 它主要是由 <filename>/usr/ports</filename> 內一堆
+ <filename>Makefiles</filename>, patches 以及一些軟體簡介檔所組成的。
+ </para>
+
+ <para>在裝 FreeBSD 時,若忘了在 <application>sysinstall</application>
+ 內勾選要裝 Ports Collection 的話,
+ 沒關係,可以照下列方式來安裝 ports collection:</para>
+
+ <procedure>
+ <title>CVSup 方式</title>
+
+ <para>使用 <application>CVSup</application> 是安裝、更新 Ports
+ Collection 的快速方法之一。
+ 若想更瞭解 <application>CVSup</application> 用法的話,請參閱 <link linkend="cvsup">使用 CVSup</link>。</para>
+
+ <note>
+ <para><application>csup</application> 是以 C 語言對
+ <application>CVSup</application> 軟體的重寫,在 &os; 6.2
+ 及之後版本即有附在系統內。 可以直接用系統所附的
+ <application>csup</application> 即可跳過步驟一的動作,
+ 並將本文相關提到 <command>cvsup</command> 之處,
+ 都改為 <command>csup</command> 即可。 此外, &os; 6.2
+ 之前的版本,則可裝 <package>net/csup</package>
+ 或者 package 來使用 <application>csup</application>。</para>
+ </note>
+
+ <para>第一次跑 <application>CVSup</application> 之前,請先確認
+ <filename>/usr/ports</filename>
+ 是乾淨的! 若你已經裝了 Ports Collection ,但又自行加上其他 patch
+ 檔,那麼 <application>CVSup</application>
+ 並不會刪除你自行加上的 patch 檔,這樣可能會導致要安裝某些軟體時,
+ 發生 patch 失敗或編譯失敗。</para>
+
+ <step>
+ <para>安裝 <package>net/cvsup-without-gui</package>
+ package:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r cvsup-without-gui</userinput></screen>
+
+ <para>細節用法請參閱 <link linkend="cvsup-install">安裝 CVSup</link>(<xref linkend="cvsup-install"/>)。</para>
+ </step>
+
+ <step>
+ <para>執行 <command>cvsup</command>:</para>
+
+ <screen>&prompt.root; <userinput>cvsup -L 2 -h cvsup.tw.FreeBSD.org /usr/share/examples/cvsup/ports-supfile</userinput></screen>
+
+ <para>請把
+ <replaceable>cvsup.tw.FreeBSD.org</replaceable> 請改成離你比較近
+ (快)的 <application>CVSup</application> 主機。
+ 這部分可以參閱完整的 <link linkend="cvsup-mirrors">CVSup mirror
+ </link> 站列表(<xref linkend="cvsup-mirrors"/>)。</para>
+
+ <note>
+ <para>若想改用自己設的
+ <filename>ports-supfile</filename>,比如說,
+ 不想每次都得打指令來指定所使用的
+ <application>CVSup</application> 主機。</para>
+
+ <procedure>
+ <step>
+ <para>這種情況下,請以 <systemitem class="username">root</systemitem> 權限把
+ <filename>/usr/share/examples/cvsup/ports-supfile</filename>
+ 複製到其他位置,比如
+ <filename>/root</filename> 或者自己帳號的家目錄。</para>
+ </step>
+
+ <step>
+ <para>修改新的 <filename>ports-supfile</filename> 檔。</para>
+ </step>
+
+ <step>
+ <para>把
+ <replaceable>CHANGE_THIS.FreeBSD.org</replaceable>
+ 改為離你比較近(快)的 <application>CVSup</application> 主機。
+ 這部分可以參閱完整的 <link linkend="cvsup-mirrors">CVSup
+ Mirrors</link> (<xref linkend="cvsup-mirrors"/>) 站列表</para>
+ </step>
+
+ <step>
+ <para>然後就開始以類似下列指令跑 <command>cvsup</command>:
+ </para>
+
+ <screen>&prompt.root; <userinput>cvsup -L 2 /root/ports-supfile</userinput></screen>
+ </step>
+ </procedure>
+ </note>
+ </step>
+
+ <step>
+ <para>執行 &man.cvsup.1; 之後,就會開始更新 Ports Collection。
+ 不過這動作只是『更新』並不是『升級』,不會把已裝的軟體重新編譯、升級。</para>
+ </step>
+ </procedure>
+
+ <procedure>
+ <title>Portsnap 方式</title>
+
+ <para>&man.portsnap.8; 也是更新 Ports Collection 的方式之一。
+ &os;&nbsp;6.0 起開始內建 Portsnap 機制,而較舊的系統,則可透過
+ <package>ports-mgmt/portsnap</package> port 來安裝:
+ </para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r portsnap</userinput></screen>
+
+ <para><application>Portsnap</application> 細節功能,請參閱
+ <link linkend="portsnap">Portsnap 使用篇</link>。</para>
+
+ <step>
+ <para>若 <filename>/usr/ports</filename> 目錄不存在的話,
+ 就建立一下吧:</para>
+
+ <screen>&prompt.root; <userinput>mkdir /usr/ports</userinput></screen>
+ </step>
+
+ <step>
+ <para>接下來,下載壓縮的 Ports Collection 定期更新檔到
+ <filename>/var/db/portsnap</filename> 目錄。
+ 完成下載後,要斷線與否都可以。</para>
+
+ <screen>&prompt.root; <userinput>portsnap fetch</userinput></screen>
+ </step>
+
+ <step>
+ <para>若是第一次跑 <application>Portsnap</application> 的話,
+ 則需要先解壓到 <filename>/usr/ports</filename>:
+ </para>
+
+ <screen>&prompt.root; <userinput>portsnap extract</userinput></screen>
+
+ <para>若已有 <filename>/usr/ports</filename> 而且只是想更新而已,
+ 那麼就照下面作:</para>
+
+ <screen>&prompt.root; <userinput>portsnap update</userinput></screen>
+ </step>
+
+ </procedure>
+
+ <procedure>
+ <title>Sysinstall 方式</title>
+
+ <para>這方式要用 <application>sysinstall</application>
+ 透過安裝來源來裝 Ports Collection。
+ 請注意:所安裝的 Ports Collection 版本只是該 release
+ 發佈時的版本而已,而非最新。
+ 若能上網(Internet)的話,請使用上述方式之一會比較好。</para>
+
+ <step>
+ <para>以 <systemitem class="username">root</systemitem> 權限執行
+ <command>sysinstall</command>
+ (在 &os; 5.2 之前版本則是 <command>/stand/sysinstall</command>)
+ ,方式如下:</para>
+
+ <screen>&prompt.root; <userinput>sysinstall</userinput></screen>
+ </step>
+
+ <step>
+ <para>請以方向鍵移動選擇項目,選擇
+ <guimenuitem>Configure</guimenuitem>,然後按
+ <keycap>Enter</keycap> 鍵。</para>
+ </step>
+
+ <step>
+ <para>選擇
+ <guimenuitem>Distributions</guimenuitem>,然後按
+ <keycap>Enter</keycap> 鍵。</para>
+ </step>
+
+ <step>
+ <para>選擇 <guimenuitem>ports</guimenuitem>,然後按
+ <keycap>Space</keycap> 鍵。</para>
+ </step>
+
+ <step>
+ <para>選 <guimenuitem>Exit</guimenuitem>,然後按
+ <keycap>Enter</keycap> 鍵。</para>
+ </step>
+
+ <step>
+ <para>選擇要用的安裝來源,比如:CDROM(光碟)、FTP 等方式。</para>
+ </step>
+
+ <step>
+ <para>選 <guimenuitem>Exit</guimenuitem>,然後按
+ <keycap>Enter</keycap> 鍵。</para>
+ </step>
+
+ <step>
+ <para>按下 <keycap>X</keycap> 鍵就可離開
+ <application>sysinstall</application> 程式。</para>
+ </step>
+ </procedure>
+ </sect2>
+
+ <sect2 xml:id="ports-skeleton">
+ <title>Ports 的安裝方式</title>
+
+ <indexterm>
+ <primary>ports</primary>
+ <secondary>installing</secondary>
+ </indexterm>
+ <para>提到 Ports Collection,首先要先說明的是:何謂
+ <quote>skeleton</quote>。
+ 簡單來講,port skeleton 就是讓軟體如何在 FreeBSD
+ 順利編譯、安裝的最基本檔案組合。
+ 每份 port skeleton 基本上會有:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><filename>Makefile</filename> 檔。
+ 這個 <filename>Makefile</filename> 內容有分許多部分,
+ 是用來指定要如何編譯,以及該裝在系統的何處。</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>distinfo</filename> 檔。
+ 編譯該軟體所需下載的檔案、checksum(使用 &man.md5.1; 及
+ &man.sha256.1; 來檢驗檔案)都會記錄在這檔,
+ 以確保所下載的檔案是正確無誤的。</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>files</filename> 目錄。 這目錄放的是讓軟體正常編譯、
+ 安裝的 patch 檔。
+ Patches 檔基本上是一些小檔案,並針對特定檔案來做修改,
+ 而且是純文字檔格式,
+ 基本上內容通常會像是 <quote>Remove line 10(刪除第 10 行)</quote>
+ 或
+ <quote>Change line 26 to this ...(把第 26 行改為...)</quote>
+ 之類的。
+ 這些 Patches 通常也稱為 <quote>diffs</quote>
+ ,因為都是由 &man.diff.1; 程式所產生的。</para>
+
+ <para>此外,本目錄也可能會放一些協助編譯該 port 的檔案。</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>pkg-descr</filename> 檔,內容是比較詳細的軟體介紹,
+ 通常會寫得比較多行。</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>pkg-plist</filename> 檔,該 port
+ 會安裝的所有檔案清單。
+ 也是告訴系統在移除該 port 時,需要刪除哪些檔案。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>有些 port 還會有其他檔案,像是 <filename>pkg-message</filename> 檔。
+ port 系統在一些情況時,會用這些檔案。
+ 如果想知道這些檔案的更多細節用途,以及 port 一般用法,請參閱 <link xlink:href="&url.books.porters-handbook;/index.html">FreeBSD Porter's
+ Handbook</link>。</para>
+
+ <para>port 內寫的是告訴系統如何編譯 source code 的相關指令,
+ 但並不是真正的 source code。
+ 而 source code 可以從光碟或網路(Internet)來取得,
+ 該軟體開發者可能會把 source code 以各種格式來發佈。
+ 通常是以 tar 以及 gzip 這兩者工具一起壓縮的檔案,
+ 也有可能是以其他工具壓縮,或根本沒壓縮。
+ 而軟體的 source code 無論是以哪一種壓縮檔型態,我們都稱之為
+ <quote>distfile</quote>。
+ 下面將介紹兩種安裝 &os; port 的方式。</para>
+
+ <note>
+ <para>要安裝 port 的話,請務必切為 <systemitem class="username">root</systemitem> 身份。
+ </para>
+ </note>
+
+ <warning>
+ <para>在安裝任何 port 之前,請務必確認有更新 Ports Collection 到最新版,
+ 此外請檢閱 <uri xlink:href="http://vuxml.freebsd.org/">http://vuxml.freebsd.org/</uri> 來檢查所要裝的 port
+ 是否有相關安全漏洞議題需要注意的。</para>
+
+ <para><application>portaudit</application> 會在安裝任何 port 之前,
+ 先自動檢查是否有相關已知的安全漏洞。這個工具在 Ports Collection 內有
+ (<package>ports-mgmt/portaudit</package>)。
+ 在安裝 port 之前,可以先跑 <command>portaudit -F</command> 指令,
+ 如此一來就會抓最新的資安漏洞資料庫回來核對。
+ 每天的系統定期安檢會自動更新資料庫,並作安全稽核。
+ 詳情請參閱 &man.portaudit.1; 以及 &man.periodic.8; 的線上說明。</para>
+ </warning>
+
+ <para>Ports Collection 會假設你的網路是可正常連線的。
+ 如果沒有的話,那麼需手動把所需的 distfile 檔複製到
+ <filename>/usr/ports/distfiles</filename> 才行。</para>
+
+ <para>開始操作之前,要先進入打算安裝的 port 目錄內:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/sysutils/lsof</userinput></screen>
+
+ <para>一旦進入 <filename>lsof</filename> 目錄後,就可以看到這個 port
+ 的 skeleton 結構。
+ 接下來,就是編譯,也就是 <quote>build</quote> 這個 port。
+ 只需簡單輸入 <command>make</command> 指令,就可輕鬆完成編譯。
+ 完成後,應該可以看到類似下面訊息:</para>
+
+ <screen>&prompt.root; <userinput>make</userinput>
+&gt;&gt; lsof_4.57D.freebsd.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
+&gt;&gt; Attempting to fetch from ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/.
+===&gt; Extracting for lsof-4.57
+...
+[extraction output snipped]
+...
+&gt;&gt; Checksum OK for lsof_4.57D.freebsd.tar.gz.
+===&gt; Patching for lsof-4.57
+===&gt; Applying FreeBSD patches for lsof-4.57
+===&gt; Configuring for lsof-4.57
+...
+[configure output snipped]
+...
+===&gt; Building for lsof-4.57
+...
+[compilation output snipped]
+...
+&prompt.root;</screen>
+
+ <para>請注意:編譯完成後,就會回到提示列(prompt)。接下來就是安裝該
+ port 了,要裝的話,只需在原本的 <command>make</command>
+ 指令後面再加上一個字即可,
+ 那個字就是 <command>install</command>:</para>
+
+ <screen>&prompt.root; <userinput>make install</userinput>
+===&gt; Installing for lsof-4.57
+...
+[installation output snipped]
+...
+===&gt; Generating temporary packing list
+===&gt; Compressing manual pages for lsof-4.57
+===&gt; Registering installation for lsof-4.57
+===&gt; SECURITY NOTE:
+ This port has installed the following binaries which execute with
+ increased privileges.
+&prompt.root;</screen>
+
+ <para>一旦回到提示列(prompt),就可以執行剛裝的程式了。
+ 另外,因為 <command>lsof</command> 這程式執行時會有額外權限,
+ 所以會出現安全警告。在編譯、安裝 port 的時候,
+ 請留意任何出現的警告。</para>
+
+ <para>此外,建議刪除編譯用的工作目錄(預設是 <filename>work</filename>),
+ 這目錄內為在編譯過程中所用到的一些臨時檔案,
+ 這些檔案不只佔硬碟空間,而且也可能會在該 port 升級新版時,
+ 造成不必要的困擾。</para>
+
+ <screen>&prompt.root; <userinput>make clean</userinput>
+===&gt; Cleaning for lsof-4.57
+&prompt.root;</screen>
+
+ <note>
+ <para>用 <command>make install clean</command> 就可以一口氣完成剛所說
+ <command>make</command>、<command>make install</command>、
+ <command>make clean</command> 這三個步驟了。</para>
+ </note>
+
+ <note>
+ <para>有些 shell 會依據 <envar>PATH</envar> 環境變數的路徑,
+ 把那些路徑的執行檔 cache 起來,來加速搜尋執行檔。
+ 如果你用的是這類的 shell,那麼在裝完 port 後需要打
+ <command>rehash</command> 指令,才能執行新裝的執行檔,而
+ <command>rehash</command> 指令可以在 <command>tcsh</command>
+ 之類的 shell 上使用,若是 <command>sh</command> 的話,則是
+ <command>hash -r</command>。
+ 詳情請參閱你所使用的 shell 相關文件。</para>
+ </note>
+
+ <para>有些由所謂 third-party 所發行的 DVD-ROM 產品,像是
+ <link xlink:href="http://www.freebsdmall.com/">FreeBSD
+ Mall</link> 所發行的 FreeBSD Toolkit 會包括 distfiles 檔案,
+ 這些檔案可用來搭配 Ports Collection。
+ 把 DVD-ROM 掛載在 <filename>/cdrom</filename>。
+ 若使用其他掛載點的話,要記得設定 <varname>CD_MOUNTPTS</varname>
+ 環境變數為相對應的掛載點。 如此一來,光碟上若有所需的 distfiles
+ 就會自動使用光碟的檔案。</para>
+
+ <note>
+ <para>請注意,有少數 port 並不允許透過光碟來發佈檔案。
+ 可能的原因有:需先填註冊單才能下載或散佈檔案,或其他原因。
+ 如果想安裝在光碟上沒附上的 port,就需連上網路才能繼續進行安裝。
+ </para>
+ </note>
+
+ <para>ports 系統採用 &man.fetch.1; 來下載檔案,
+ 它有許多可調整的環境變數,包括:
+ <envar>FTP_PASSIVE_MODE</envar>、<envar>FTP_PROXY</envar>、
+ <envar>FTP_PASSWORD</envar>。 如果是處於有防火牆的環境,
+ 或者需要使用 FTP/HTTP proxy,那麼就需要設定這些變數。
+ 使用細節請參閱 &man.fetch.3; 說明。</para>
+
+ <para>若無法隨時一直上網的話,那麼可以利用
+ <command>make fetch</command>。
+ 只要在 port 的最上層路徑(<filename>/usr/ports</filename>)
+ 打這指令,那麼所有需要用到的檔案都會下載。
+ 這指令也可以在下層目錄使用,例如:
+ <filename>/usr/ports/net</filename>。
+ 請注意,若該 port 有相依的 library 或者其他 port 的話,
+ 那麼它<emphasis>並不會</emphasis>跟著一起下載其他所相依的檔案。
+ 若想一次下載所有相依的 port 所有檔案,那麼指令參數請改用
+ <buildtarget>fetch-recursive</buildtarget> 而非
+ <buildtarget>fetch</buildtarget>。</para>
+
+ <note><para>可以在某類別或最上層路徑打 <command>make</command>
+ 指令來編譯所有的 port,或者以上述的 <command>make
+ fetch</command> 指令來下載所有檔案。
+ 然而,這樣是相當危險,因為有些 port 不能並存。
+ 也有另一種情況,有些 port 可能會以相同檔名,
+ 但是實際上卻是不同內容的檔案。</para></note>
+
+ <para>在某些罕見情況,可能需加上 <varname>MASTER_SITES</varname>
+ (檔案的原始下載處)之外的下載點,以下載所需的檔案。
+ 可以用下列指令,來更改預設的 <varname>MASTER_SITES</varname>
+ 下載點:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/directory</userinput>
+&prompt.root; <userinput>make MASTER_SITE_OVERRIDE= \
+ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/ fetch</userinput></screen>
+
+ <para>上面這例子,是把 <varname>MASTER_SITES</varname> 改設
+ <systemitem class="fqdomainname">ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/</systemitem>
+ 為下載點。</para>
+
+ <note><para>有些 port 允許(或要求)您得指定編譯選項,
+ 以啟用、停用該軟體中非必須的功能、安全選項以及其他可自訂的選項。
+ 具有代表性的包括了
+ <package>www/mozilla</package>、<package>security/gpgme</package>、<package>mail/sylpheed-claws</package>。
+ 若有這類選項時,通常在編譯時會出現相關提示訊息。</para></note>
+
+ <sect3>
+ <title>更改(Override)預設的 Ports 目錄</title>
+
+ <para>有時候,會發現到使用其他目錄作為 port、distfiles
+ 目錄可能相當有用(甚至是必須),可以設定
+ <varname>PORTSDIR</varname> 及 <varname>PREFIX</varname>
+ 環境變數以修改預設的 port 目錄。舉例:</para>
+
+ <screen>&prompt.root; <userinput>make PORTSDIR=/usr/home/example/ports install</userinput></screen>
+
+ <para>以上會在
+ <filename>/usr/home/example/ports</filename> 內進行編譯,
+ 並把所有檔案安裝到 <filename>/usr/local</filename> 內。</para>
+
+ <screen>&prompt.root; <userinput>make PREFIX=/usr/home/example/local install</userinput></screen>
+
+ <para>則會在 <filename>/usr/ports</filename> 目錄內編譯,
+ 並把所有檔案安裝到
+ <filename>/usr/home/example/local</filename> 內。</para>
+
+ <para>當然囉,</para>
+
+ <screen>&prompt.root; <userinput>make PORTSDIR=../ports PREFIX=../local install</userinput></screen>
+
+ <para>則會同時包含兩種設定(還有很多變化以致無法在本頁全部都有寫到,
+ 但您應該已經有抓到大概概念了吧)。</para>
+
+ <para>此外,這些變數也以作為環境變數來設定。
+ 請依您所使用的 shell 去參閱相關說明,以瞭解如何設定。</para>
+ </sect3>
+
+ <sect3>
+ <title>處理 <command>imake</command></title>
+
+ <para>有些 port 會使用 <command>imake</command>(X Window 系統的一部份)
+ 無法正常運用 <varname>PREFIX</varname> 變數,
+ 它們會堅持把檔案都安裝到 <filename>/usr/X11R6</filename> 目錄。
+ 同樣地,也有一些 Perl port 會忽略 <varname>PREFIX</varname>
+ 並把檔案安裝到 Perl 目錄架構內。 讓這些 ports respect
+ <varname>PREFIX</varname> 是相當困難,甚至是不可能的事。</para>
+
+ </sect3>
+
+ <sect3>
+ <title>重新設定 Ports 選項</title>
+
+ <para>在編譯某些 port 時會出現選單畫面(ncurses-based),
+ 可以用來選擇安裝選項。 通常裝好該 port 之後,便不太會需要重加、
+ 移除、更改一些當初安裝的選項。 但日後若有需要的話,
+ 也有許多方式可以調整這些選項。 其中一種方式便是切到該 port 目錄,
+ 並打 <command>make</command> <buildtarget>config</buildtarget>
+ 即可再次回到選項畫面去作調整。 另外還可用 <command>make</command>
+ <buildtarget>showconfig</buildtarget> 以顯示該 port 安裝時所用的選項。
+ 也可以用 <command>make</command> <buildtarget>rmconfig</buildtarget>
+ 來把所有選項回到初始設定。 這些選項跟其他動作都可參閱 &man.ports.7;
+ 內的詳細說明。</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="ports-removing">
+ <title>移除已安裝的 Ports</title>
+
+ <indexterm>
+ <primary>ports</primary>
+ <secondary>removing</secondary>
+ </indexterm>
+ <para>現在您已經知道如何安裝 port,而開始想瞭解如何移除。
+ 比如裝了一個 port 後才意識到裝錯 port 了。
+ 在此,我們將移除前面例子所裝的那個 port
+ (沒仔細注意的話,我們再提醒一下就是 <command>lsof</command>)。
+ 跟移除 package 時相當類似(在 <link linkend="packages-using">Packages section</link> 有介紹),都是使用
+ &man.pkg.delete.1; 指令:</para>
+
+ <screen>&prompt.root; <userinput>pkg_delete lsof-4.57</userinput></screen>
+
+ </sect2>
+
+ <sect2 xml:id="ports-upgrading">
+ <title>升級已安裝的 Ports</title>
+
+ <indexterm>
+ <primary>ports</primary>
+ <secondary>upgrading</secondary>
+ </indexterm>
+ <para>首先,用 &man.pkg.version.1; 指令來列出目前 Ports Collection
+ 中提供了那些可升級的 port 版本:</para>
+
+ <screen>&prompt.root; <userinput>pkg_version -v</userinput></screen>
+
+ <sect3 xml:id="ports-file-updating">
+ <title><filename>/usr/ports/UPDATING</filename></title>
+
+ <para>每次更新完 Ports Collection 之後,請務必記得在升級 port 前,
+ 先看看 <filename>/usr/ports/UPDATING</filename>,
+ 這裡會寫升級方面的各式問題,比如:檔案格式改變、變更設定檔位置、
+ 與舊版不相容的問題等,以及怎麼解決的完整步驟。</para>
+
+ <para>若 <filename>UPDATING</filename> 內容與你看到的其他文件有些不同
+ 、相衝的話,
+ 那麼請以 <filename>UPDATING</filename> 為準。</para>
+ </sect3>
+
+ <sect3 xml:id="portupgrade">
+ <title>以 Portupgrade 來升級已安裝的 Ports</title>
+
+ <indexterm>
+ <primary>portupgrade</primary>
+ </indexterm>
+
+ <para><application>portupgrade</application> 可以輕鬆升級已裝的軟體。
+ 該工具可從 <package>ports-mgmt/portupgrade</package>
+ port 安裝,
+ 安裝方式就如同其他 port 一樣,用 <command>make install clean
+ </command> 指令就可以了:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/ports-mgmt/portupgrade</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+
+ <para>首先最好先以 <command>pkgdb -F</command> 來掃瞄已裝的 ports
+ 資料庫是否有誤,並修正有問題的地方。
+ 在每次做升級之前,最好定期做一下 <command>pkgdb -F</command>
+ 動作會較為妥當。</para>
+
+ <para>跑 <command>portupgrade -a</command> 的話,
+ <application>portupgrade</application> 會升級系統上所有已裝的過舊
+ ports。 若用 <option>-i</option> 則在升級每個 port 過程當中,
+ 會要求確認相關動作是否符合所需。</para>
+
+ <screen>&prompt.root; <userinput>portupgrade -ai</userinput></screen>
+
+ <para>若只想升級某特定程式而非全部,那麼可以用
+ <command>portupgrade pkgname</command>
+ 來做指定。 若想要 <application>portupgrade</application>
+ 優先升級某 port 所相依的相關套件,則請用 <option>-R</option>
+ 參數即可。</para>
+
+ <screen>&prompt.root; <userinput>portupgrade -R firefox</userinput></screen>
+
+ <para>若要用 package 而非 port 來安裝,則需指定
+ <option>-P</option> 才可以。 若有指定這選項,則
+ <application>portupgrade</application> 會搜尋
+ <envar>PKG_PATH</envar> 變數所指定的本機目錄,
+ 若找不到則透過網路來下載安裝。
+ 若本機跟網路都沒有可用的 package 的話,則
+ <application>portupgrade</application> 會使用 port 方式安裝。
+ 若不想如此又變成使用 port 方式安裝,則用 <option>-PP</option>
+ 即可強制避免使用 port 方式安裝。</para>
+
+ <screen>&prompt.root; <userinput>portupgrade -PP gnome2</userinput></screen>
+
+ <para>若只想下載 distfiles(或者若指定 <option>-P</option> 的話,則是
+ package)而不想編譯或安裝檔案,可以使用 <option>-F</option>。
+ 詳情請參閱 &man.portupgrade.1; 的說明。</para>
+ </sect3>
+
+ <sect3 xml:id="portmanager">
+ <title>以 Portmanager 來升級已安裝的 Ports</title>
+
+ <indexterm>
+ <primary>portmanager</primary>
+ </indexterm>
+
+ <para><application>Portmanager</application>
+ 也可以用來輕鬆升級已裝的軟體。 該工具可從 <package>ports-mgmt/portmanager</package> port 安裝:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/ports-mgmt/portmanager</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+
+ <para>所有已裝的軟體,都可以輕鬆用類似下列指令來升級:</para>
+
+ <screen>&prompt.root; <userinput>portmanager -u</userinput></screen>
+
+ <para>此外,使用參數可以改為 <option>-ui</option>,如此一來
+ <application>Portmanager</application> 在升級一些有特殊選項的軟體時
+ ,就會詢問該如何升級。 <application>Portmanager</application>
+ 也可以用來裝新 port。與以往常用的
+ <command>make install clean</command> 指令不同之處在於:
+ 它會先升級你要裝的 port 所相依的所有 ports,然後才開始編譯、
+ 安裝要裝的 port。</para>
+
+ <screen>&prompt.root; <userinput>portmanager x11/gnome2</userinput></screen>
+
+ <para>若要裝的 port 之軟體相依關係有問題時,也可以用
+ <application>Portmanager</application> 使它們重歸正軌。 而
+ <application>Portmanager</application> 解決相依問題完畢之後,該 port
+ 也會重新編譯,以因應正確的相依關係。</para>
+
+ <screen>&prompt.root; <userinput>portmanager graphics/gimp -f</userinput></screen>
+
+ <para>其餘運用法門,請參閱 &man.portmanager.1; 說明。</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="ports-disk-space">
+ <title>Ports 與硬碟空間</title>
+
+ <indexterm>
+ <primary>ports</primary>
+ <secondary>disk-space</secondary>
+ </indexterm>
+ <para>因為使用 Ports Collection 遲早可能會用光硬碟空間,
+ 所以在裝完軟體後,記得要以 <command>make clean
+ </command> 指令來清除臨時的 <filename>work
+ </filename> 目錄。
+ 此外,可以用下列指令來清除整個 Ports Collection 內的臨時目錄:</para>
+
+ <screen>&prompt.root; <userinput>portsclean -C</userinput></screen>
+
+ <para>ports 用久了,您可能會在
+ <filename>distfiles</filename>
+ 目錄內會累積著許多的原始碼檔案。 可以手動刪除這些檔案,
+ 或者用下列指令來清除所有 port 都不使用的舊檔:</para>
+
+ <screen>&prompt.root; <userinput>portsclean -D</userinput></screen>
+
+ <para>或者要清除所有已裝的 port 都不再使用的舊檔:</para>
+
+ <screen>&prompt.root; <userinput>portsclean -DD</userinput></screen>
+
+ <note>
+ <para><command>portsclean</command> 這工具乃是
+ <application>portupgrade</application> 套件的一部分。</para>
+ </note>
+
+ <para>不要忘了移除那些已經安裝,但不再需要用到的 ports。
+ 有個 <package>ports-mgmt/pkg_cutleaves</package>
+ port,正是可自動完成這功能的好工具。</para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="ports-nextsteps">
+ <title>安裝之後,有什麼後續注意事項嗎?</title>
+
+ <para>通常,安裝完軟體後,我們可以閱讀所附的一些文件,或需要編輯設定檔,
+ 來確保這個軟體能順利運作,或在機器開機的時候啟動(如果是 daemon 的話)
+ 等等。</para>
+
+ <para>不同的軟體會有不同的設定步驟。不管怎樣,如果裝好了軟體,
+ 但是不知道下一步怎麼辦的時候, 可以試試看這些小技巧:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>善用 &man.pkg.info.1; ,這指令可以顯示:透過套件管理系統
+ (Packages/Ports)裝了哪些軟體、檔案裝在哪邊。舉例來說,若剛裝了
+ FooPackage (版本 1.0.0),那麼下面這指令:</para>
+
+ <screen>&prompt.root; <userinput>pkg_info -L foopackage-1.0.0 | less</userinput></screen>
+
+ <para>就會顯示這軟體所安裝的檔案清單。 請特別注意在
+ <filename>man/</filename> 目錄內是說明檔、
+ <filename>etc/</filename> 目錄內是設定檔、
+ <filename>doc/</filename> 目錄內是完整文件。</para>
+
+ <para>若不確定已裝的套件版本為何,可以用類似下列指令來查:</para>
+
+ <screen>&prompt.root; <userinput>pkg_info | grep -i foopackage</userinput></screen>
+
+ <para>以上將會搜尋所有已裝的套件,列出有符合
+ <replaceable>foopackage</replaceable> 的套件名稱。
+ 請自行依需求,修改 <replaceable>foopackage</replaceable>
+ 為想找的套件名稱。</para>
+ </listitem>
+
+ <listitem>
+ <para>一旦確認該程式的線上說明有安裝,就可以用 &man.man.1; 來翻閱。
+ 同樣地,若該程式有提供的話,也可以參考設定檔樣本,以及其他文件。
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>若該程式有官網的話,還可以透過網站來找文件、常見問答集(FAQ)等。
+ 若不知道網址,請用下列指令:</para>
+
+ <screen>&prompt.root; <userinput>pkg_info foopackage-1.0.0</userinput></screen>
+
+ <para>若該程式有官網的話,則會有一行 <literal>WWW:</literal>
+ 開頭的出現,這行會列出該程式的官網網址(URL)。</para>
+ </listitem>
+
+ <listitem>
+ <para>Port 若須在開機時就會啟動(就像 Internet
+ 主機),通常都會安裝 script 到
+ <filename>/usr/local/etc/rc.d</filename> 目錄。
+ 您可以檢閱這 script 的正確與否,或若有需要,也可以修改、改名。
+ 詳情請參閱 <link linkend="configtuning-starting-services">啟動 Services</link>。
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="ports-broken">
+ <title>如何處理爛掉(Broken)的 Ports?</title>
+
+ <para>如果發現某個 port 無法順利安裝、運作, 有幾種方法可以試試看:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>從 <link xlink:href="&url.base;/support.html#gnats">Problem Report
+ 資料庫</link> 中挖寶看看,說不定已經有人送可用的 patch 上去囉,
+ 那麼或許就可以順利解決問題哩。</para>
+ </listitem>
+
+ <listitem>
+ <para>向該 port 的 maintainer 尋求協助:請打
+ <command>make maintainer</command> 或翻閱
+ <filename>Makefile</filename> 以查詢 maintainer 的
+ email address。記得寄信給 maintainer 時,要附註該 port
+ 的名稱、版本(或是把 <filename>Makefile</filename> 內的
+ <literal>&dollar;FreeBSD:</literal> 那一整行附上)
+ 以及相關錯誤訊息。</para>
+
+ <note>
+ <para>有些 port 不是由專門的單一 maintainer 負責,而是透過 <link xlink:href="&url.articles.mailing-list-faq;/article.html">mailing
+ list</link> 的專題討論。許多(但非全部)的聯絡 email 格式通常是
+ <email role="nolink">freebsd-list名稱@FreeBSD.org</email>
+ 。發問時,請記得把『freebsd-list名稱』改為相關討論的
+ mailing list 名稱。</para>
+
+ <para>尤其當 port 的 maintainer 欄位是
+ <email role="nolink">freebsd-ports@FreeBSD.org</email>
+ 時,事實上已經沒人當該 port maintainer 了。
+ 因此若該 port 仍有修正或其他技術支援的話,相關討論都會在
+ freebsd-ports 郵遞論壇上出現。
+ 喔,對了,如果有熟悉該軟體者,志願當該 port maintainer
+ 的話,我們也都很歡迎您的加入喔。</para>
+ </note>
+
+ <para>若 port maintainer 沒有回覆您的信件, 則可以用 &man.send-pr.1;
+ 來提交問題報告 PR。(請參閱 <link xlink:href="&url.articles.problem-reports;/article.html">Writing
+ FreeBSD Problem Reports</link>)。</para>
+ </listitem>
+
+ <listitem>
+ <para>試試看修正它吧! <link xlink:href="&url.books.porters-handbook;/index.html">Porter's
+ Handbook</link> 包括了 <quote>Ports</quote>
+ 架構的細節部份,這些書中內容有助您修好有問題的 port
+ 甚至提交自己的 port﹗</para>
+ </listitem>
+
+ <listitem>
+ <para>從較近的 FTP 站點下載編譯好的 package。
+ package collection 的最上游站是在 <systemitem class="fqdomainname">ftp.FreeBSD.org</systemitem> 上的 <link xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/packages/">packages
+ 目錄</link>內,但請記得先檢查是否已有 <link xlink:href="http://mirrorlist.FreeBSD.org/">local mirror</link>
+ 站! 通常情況下這些 package 都可以直接使用,
+ 而且應該比自行編譯快一些。
+ 用 &man.pkg.add.1; 即可順利安裝 package 。</para>
+ </listitem>
+ </orderedlist>
+ </sect1>
+
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/ppp-and-slip/Makefile b/zh_TW.UTF-8/books/handbook/ppp-and-slip/Makefile
new file mode 100644
index 0000000000..4026603f90
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/ppp-and-slip/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= ppp-and-slip/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/ppp-and-slip/chapter.xml b/zh_TW.UTF-8/books/handbook/ppp-and-slip/chapter.xml
new file mode 100644
index 0000000000..d7360f74c2
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/ppp-and-slip/chapter.xml
@@ -0,0 +1,3116 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.170
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="ppp-and-slip">
+ <info><title>PPP and SLIP</title>
+ <authorgroup>
+ <author><personname><firstname>Jim</firstname><surname>Mock</surname></personname><contrib>Restructured, reorganized, and updated by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="ppp-and-slip-synopsis">
+ <title>Synopsis</title>
+ <indexterm xml:id="ppp-ppp">
+ <primary>PPP</primary>
+ </indexterm>
+ <indexterm xml:id="ppp-slip">
+ <primary>SLIP</primary>
+ </indexterm>
+
+ <para>FreeBSD has a number of ways to link one computer to
+ another. To establish a network or Internet connection through a
+ dial-up modem, or to allow others to do so through you, requires
+ the use of PPP or SLIP. This chapter describes setting up
+ these modem-based communication services in detail.</para>
+
+ <para>After reading this chapter, you will know:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>How to set up user PPP.</para>
+ </listitem>
+ <listitem>
+ <para>How to set up kernel PPP.</para>
+ </listitem>
+ <listitem>
+ <para>How to set up <acronym>PPPoE</acronym> (PPP over
+ Ethernet).</para>
+ </listitem>
+ <listitem>
+ <para>How to set up <acronym>PPPoA</acronym> (PPP over
+ ATM).</para>
+ </listitem>
+ <listitem>
+ <para>How to configure and set up a SLIP client and
+ server.</para>
+ </listitem>
+ </itemizedlist>
+
+ <indexterm xml:id="ppp-ppp-user">
+ <primary>PPP</primary>
+ <secondary>user PPP</secondary>
+ </indexterm>
+ <indexterm xml:id="ppp-ppp-kernel">
+ <primary>PPP</primary>
+ <secondary>kernel PPP</secondary>
+ </indexterm>
+ <indexterm xml:id="ppp-ppp-ethernet">
+ <primary>PPP</primary>
+ <secondary>over Ethernet</secondary>
+ </indexterm>
+
+ <para>Before reading this chapter, you should:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Be familiar with basic network terminology.</para>
+ </listitem>
+ <listitem>
+ <para>Understand the basics and purpose of a dialup connection
+ and PPP and/or SLIP.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>You may be wondering what the main difference is between user
+ PPP and kernel PPP. The answer is simple: user PPP processes the
+ inbound and outbound data in userland rather than in the kernel.
+ This is expensive in terms of copying the data between the kernel
+ and userland, but allows a far more feature-rich PPP implementation.
+ User PPP uses the <filename>tun</filename> device to communicate
+ with the outside world whereas kernel PPP uses the
+ <filename>ppp</filename> device.</para>
+
+ <note>
+ <para>Throughout in this chapter, user PPP will simply be
+ referred to as <application>ppp</application> unless a distinction needs to be made between it
+ and any other PPP software such as <application>pppd</application>.
+ Unless otherwise stated, all of the commands explained in this
+ chapter should be executed as <systemitem class="username">root</systemitem>.</para>
+ </note>
+ </sect1>
+
+ <sect1 xml:id="userppp">
+ <info><title>Using User PPP</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Updated and enhanced by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Brian</firstname><surname>Somers</surname></personname><contrib>Originally contributed by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Nik</firstname><surname>Clayton</surname></personname><contrib>With input from </contrib></author>
+ <author><personname><firstname>Dirk</firstname><surname>Fr&ouml;mberg</surname></personname></author>
+ <author><personname><firstname>Peter</firstname><surname>Childs</surname></personname></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect2>
+ <title>User PPP</title>
+
+ <sect3>
+ <title>Assumptions</title>
+
+ <para>This document assumes you have the following:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>An account with an Internet Service Provider (ISP)<indexterm xml:id="ppp-isp"><primary>ISP</primary></indexterm> which
+ you connect to using PPP<indexterm xml:id="ppp-ppp2"><primary>PPP</primary></indexterm>.</para>
+ </listitem>
+
+ <listitem>
+ <para>You have a modem or
+ other device connected to your system and configured
+ correctly which allows you to connect to your ISP.</para>
+ </listitem>
+
+ <listitem>
+ <para>The dial-up number(s) of your ISP.</para>
+ </listitem>
+
+ <listitem>
+ <para>Your login name<indexterm xml:id="ppp-login"><primary>login name</primary></indexterm> and password<indexterm xml:id="ppp-password"><primary>password</primary></indexterm>. (Either a
+ regular &unix;<indexterm xml:id="ppp-unix"><primary>UNIX</primary></indexterm> style login and password pair, or a
+ PAP<indexterm xml:id="ppp-pap"><primary>PAP</primary></indexterm> or CHAP<indexterm xml:id="ppp-chap"><primary>CHAP</primary></indexterm>
+ login and password pair.)</para>
+ </listitem>
+
+ <listitem>
+ <para>The IP address of one or more name servers<indexterm xml:id="ppp-nameserver"><primary>nameserver</primary></indexterm>.
+ Normally, you will be given two IP addresses by your ISP to
+ use for this. If they have not given you at least one, then
+ you can use the <command>enable dns</command> command in
+ <filename>ppp.conf</filename> and
+ <application>ppp</application> will set the name servers for
+ you. This feature depends on your ISPs PPP implementation
+ supporting DNS negotiation.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The following information may be supplied by your ISP, but
+ is not completely necessary:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The IP address of your ISP's gateway. The gateway is
+ the machine to which you will connect and will be set up as
+ your <emphasis>default route</emphasis>. If you do not have
+ this information, we can make one up and your ISP's PPP
+ server will tell us the correct value when we connect.</para>
+
+ <para>This IP number is referred to as
+ <literal>HISADDR</literal> by
+ <application>ppp</application>.</para>
+ </listitem>
+
+ <listitem>
+ <para>The netmask you should use. If your ISP has not
+ provided you with one, you can safely use <systemitem class="netmask">255.255.255.255</systemitem>.</para>
+ </listitem>
+
+ <listitem>
+ <para>If your ISP provides you with a static IP address<indexterm xml:id="ppp-static-ip"><primary>static IP address</primary></indexterm> and
+ hostname, you can enter it. Otherwise, we simply let the
+ peer assign whatever IP address it sees fit.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>If you do not have any of the required information, contact
+ your ISP.</para>
+
+ <note>
+ <para>Throughout this section, many of the examples showing
+ the contents of configuration files are numbered by line.
+ These numbers serve to aid in the presentation and
+ discussion only and are not meant to be placed in the actual
+ file. Proper indentation with tab and space characters is
+ also important.</para>
+ </note>
+
+ </sect3>
+
+ <sect3>
+ <title>Creating PPP Device Nodes</title>
+ <indexterm><primary>PPP</primary><secondary>creating device nodes</secondary></indexterm>
+
+ <para>Under normal circumstances, most users will only need
+ one <filename>tun</filename> device
+ (<filename>/dev/tun0</filename>). References to
+ <filename>tun0</filename> below may be changed to
+ <filename>tunN</filename>
+ where <replaceable>N</replaceable> is any unit number
+ corresponding to your system.</para>
+
+ <para>For FreeBSD installations that do not have &man.devfs.5; enabled
+ (FreeBSD&nbsp;4.X and earlier), the existence of the
+ <filename>tun0</filename> device should be verified (this is not
+ necessary if &man.devfs.5; is enabled as device nodes will be created
+ on demand).</para>
+
+ <para>The easiest way to make sure that the
+ <filename>tun0</filename> device is configured correctly
+ is to remake the device. To remake the device, do the
+ following:</para>
+
+ <screen>&prompt.root; <userinput>cd /dev</userinput>
+&prompt.root; <userinput>sh MAKEDEV tun0</userinput></screen>
+
+ <para>If you need 16 tunnel devices in your kernel, you will need
+ to create them. This can be done by executing the following
+ commands:</para>
+
+ <screen>&prompt.root; <userinput>cd /dev</userinput>
+&prompt.root; <userinput>sh MAKEDEV tun15</userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Automatic <application>PPP</application> Configuration</title>
+
+ <indexterm><primary>PPP</primary><secondary>configuration</secondary></indexterm>
+ <para>Both <command>ppp</command> and <command>pppd</command>
+ (the kernel level implementation of PPP) use the configuration
+ files located in the <filename>/etc/ppp</filename> directory.
+ Examples for user ppp can be found in
+ <filename>/usr/share/examples/ppp/</filename>.</para>
+
+ <para>Configuring <command>ppp</command> requires that you edit a
+ number of files, depending on your requirements. What you put
+ in them depends to some extent on whether your ISP allocates IP
+ addresses statically (i.e., you get given one IP address, and
+ always use that one) or dynamically (i.e., your IP address
+ changes each time you connect to your ISP).</para>
+
+ <sect4 xml:id="userppp-staticIP">
+ <title>PPP and Static IP Addresses</title>
+
+ <indexterm><primary>PPP</primary><secondary>with static IP addresses</secondary></indexterm>
+ <para>You will need to edit the
+ <filename>/etc/ppp/ppp.conf</filename> configuration file. It
+ should look similar to the example below.</para>
+
+ <note>
+ <para>Lines that end in a <literal>:</literal> start in
+ the first column (beginning of the line)&mdash; all other
+ lines should be indented as shown using spaces or
+ tabs.</para>
+ </note>
+
+ <programlisting>1 default:
+2 set log Phase Chat LCP IPCP CCP tun command
+3 ident user-ppp VERSION (built COMPILATIONDATE)
+4 set device /dev/cuaa0
+5 set speed 115200
+6 set dial "ABORT BUSY ABORT NO\\sCARRIER TIMEOUT 5 \
+7 \"\" AT OK-AT-OK ATE1Q0 OK \\dATDT\\T TIMEOUT 40 CONNECT"
+8 set timeout 180
+9 enable dns
+10
+11 provider:
+12 set phone "(123) 456 7890"
+13 set authname foo
+14 set authkey bar
+15 set login "TIMEOUT 10 \"\" \"\" gin:--gin: \\U word: \\P col: ppp"
+16 set timeout 300
+17 set ifaddr <replaceable>x.x.x.x</replaceable> <replaceable>y.y.y.y</replaceable> 255.255.255.255 0.0.0.0
+18 add default HISADDR</programlisting>
+
+ <variablelist>
+ <varlistentry>
+ <term>Line 1:</term>
+
+ <listitem>
+ <para>Identifies the default entry. Commands in this
+ entry are executed automatically when ppp is run.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 2:</term>
+
+ <listitem>
+ <para>Enables logging parameters. When the configuration
+ is working satisfactorily, this line should be reduced
+ to saying
+
+ <programlisting>set log phase tun</programlisting>
+
+ in order to avoid excessive log file sizes.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 3:</term>
+
+ <listitem>
+ <para>Tells PPP how to identify itself to the peer.
+ PPP identifies itself to the peer if it has any trouble
+ negotiating and setting up the link, providing information
+ that the peers administrator may find useful when
+ investigating such problems.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 4:</term>
+
+ <listitem>
+ <para>Identifies the device to which the modem is
+ connected. <filename>COM1</filename> is
+ <filename>/dev/cuaa0</filename> and
+ <filename>COM2</filename> is
+ <filename>/dev/cuaa1</filename>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 5:</term>
+
+ <listitem>
+ <para>Sets the speed you want to connect at. If 115200
+ does not work (it should with any reasonably new modem),
+ try 38400 instead.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 6 &amp; 7:</term>
+
+ <listitem>
+ <para>The dial string. User PPP<indexterm><primary>PPP</primary><secondary>user PPP</secondary></indexterm> uses an expect-send
+ syntax similar to the &man.chat.8; program. Refer to
+ the manual page for information on the features of this
+ language.</para>
+
+ <para>Note that this command continues onto the next line
+ for readability. Any command in
+ <filename>ppp.conf</filename> may do this if the last
+ character on the line is a ``\'' character.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 8:</term>
+
+ <listitem>
+ <para>Sets the idle timeout for the link. 180 seconds
+ is the default, so this line is purely cosmetic.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 9:</term>
+
+ <listitem>
+ <para>Tells PPP to ask the peer to confirm the local
+ resolver settings. If you run a local name server, this
+ line should be commented out or removed.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 10:</term>
+
+ <listitem>
+ <para>A blank line for readability. Blank lines are ignored
+ by PPP.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 11:</term>
+
+ <listitem>
+ <para>Identifies an entry for a provider called
+ <quote>provider</quote>. This could be changed
+ to the name of your <acronym>ISP</acronym> so
+ that later you can use the <option>load ISP</option>
+ to start the connection.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 12:</term>
+
+ <listitem>
+ <para>Sets the phone number for this provider. Multiple
+ phone numbers may be specified using the colon
+ (<literal>:</literal>) or pipe character
+ (<literal>|</literal>)as a separator. The difference
+ between the two separators is described in &man.ppp.8;.
+ To summarize, if you want to rotate through the numbers,
+ use a colon. If you want to always attempt to dial the
+ first number first and only use the other numbers if the
+ first number fails, use the pipe character. Always
+ quote the entire set of phone numbers as shown.</para>
+
+ <para>You must enclose the phone number in quotation marks
+ (<literal>"</literal>) if there is any intention on using
+ spaces in the phone number. This can cause a simple, yet
+ subtle error.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 13 &amp; 14:</term>
+
+ <listitem>
+ <para>Identifies the user name and password. When
+ connecting using a &unix; style login prompt, these
+ values are referred to by the <command>set
+ login</command> command using the \U and \P
+ variables. When connecting using PAP or CHAP, these
+ values are used at authentication time.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 15:</term>
+
+ <listitem>
+ <para>If you are using PAP or CHAP, there will be no login
+ at this point, and this line should be commented out or
+ removed. See <link linkend="userppp-PAPnCHAP">PAP<indexterm><primary>PAP</primary></indexterm> and CHAP<indexterm><primary>CHAP</primary></indexterm>
+ authentication</link> for further details.</para>
+
+ <para>The login string is of the same chat-like syntax as
+ the dial string. In this example, the string works for
+ a service whose login session looks like this:</para>
+
+ <screen>J. Random Provider
+login: <replaceable>foo</replaceable>
+password: <replaceable>bar</replaceable>
+protocol: ppp</screen>
+
+ <para>You will need to alter this script to suit your
+ own needs. When you write this script for the first
+ time, you should ensure that you have enabled
+ <quote>chat</quote> logging so you can determine if
+ the conversation is going as expected.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 16:</term>
+
+ <listitem>
+ <para>Sets the default idle timeout<indexterm><primary>timeout</primary></indexterm> (in seconds) for the
+ connection. Here, the connection will be closed
+ automatically after 300 seconds of inactivity. If you
+ never want to timeout, set this value to zero or use
+ the <option>-ddial</option> command line switch.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 17:</term>
+ <listitem>
+ <para>Sets the interface addresses. The string
+ <replaceable>x.x.x.x</replaceable> should be
+ replaced by the IP address that your provider has
+ allocated to you. The string
+ <replaceable>y.y.y.y</replaceable> should be
+ replaced by the IP address that your ISP indicated
+ for their gateway (the machine to which you
+ connect). If your ISP<indexterm><primary>ISP</primary></indexterm> has not given you a gateway
+ address, use <systemitem class="netmask">10.0.0.2/0</systemitem>. If you need to
+ use a <quote>guessed</quote> address, make sure that
+ you create an entry in
+ <filename>/etc/ppp/ppp.linkup</filename> as per the
+ instructions for <link linkend="userppp-dynamicIP">PPP and Dynamic IP
+ addresses</link>. If this line is omitted,
+ <command>ppp</command> cannot run in
+ <option>-auto</option> mode.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 18:</term>
+
+ <listitem>
+ <para>Adds a default route to your ISP's gateway. The
+ special word <literal>HISADDR</literal> is replaced with
+ the gateway address specified on line 17. It is
+ important that this line appears after line 17,
+ otherwise <literal>HISADDR</literal> will not yet be
+ initialized.</para>
+
+ <para>If you do not wish to run ppp in <option>-auto</option>,
+ this line should be moved to the
+ <filename>ppp.linkup</filename> file.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>It is not necessary to add an entry to
+ <filename>ppp.linkup</filename> when you have a static IP
+ address and are running ppp in <option>-auto</option> mode as your
+ routing table entries are already correct before you connect.
+ You may however wish to create an entry to invoke programs after
+ connection. This is explained later with the sendmail
+ example.</para>
+
+ <para>Example configuration files can be found in the
+ <filename>/usr/share/examples/ppp/</filename> directory.</para>
+ </sect4>
+
+ <sect4 xml:id="userppp-dynamicIP">
+ <title>PPP and Dynamic IP Addresses</title>
+ <indexterm><primary>PPP</primary><secondary>with dynamic IP addresses</secondary></indexterm>
+ <indexterm><primary>IPCP</primary></indexterm>
+ <para>If your service provider does not assign static IP
+ addresses, <command>ppp</command> can be configured to
+ negotiate the local and remote addresses. This is done by
+ <quote>guessing</quote> an IP address and allowing
+ <command>ppp</command> to set it up correctly using the IP
+ Configuration Protocol (IPCP) after connecting. The
+ <filename>ppp.conf</filename> configuration is the same as
+ <link linkend="userppp-staticIP">PPP and Static IP
+ Addresses</link>, with the following change:</para>
+
+ <programlisting>17 set ifaddr 10.0.0.1/0 10.0.0.2/0 255.255.255.255</programlisting>
+
+ <para>Again, do not include the line number, it is just for
+ reference. Indentation of at least one space is
+ required.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Line 17:</term>
+
+ <listitem>
+ <para>The number after the <literal>/</literal> character
+ is the number of bits of the address that ppp will
+ insist on. You may wish to use IP numbers more
+ appropriate to your circumstances, but the above example
+ will always work.</para>
+
+ <para>The last argument (<literal>0.0.0.0</literal>) tells
+ PPP to start negotiations using address <systemitem class="ipaddress">0.0.0.0</systemitem> rather than <systemitem class="ipaddress">10.0.0.1</systemitem> and is necessary for some
+ ISPs. Do not use <literal>0.0.0.0</literal> as the first
+ argument to <command>set ifaddr</command> as it prevents
+ PPP from setting up an initial route in
+ <option>-auto</option> mode.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>If you are not running in <option>-auto</option> mode, you
+ will need to create an entry in
+ <filename>/etc/ppp/ppp.linkup</filename>.
+ <filename>ppp.linkup</filename> is used after a connection has
+ been established. At this point, <command>ppp</command> will
+ have assigned the interface addresses and it will now be
+ possible to add the routing table entries:</para>
+
+ <programlisting>1 provider:
+2 add default HISADDR</programlisting>
+
+ <variablelist>
+ <varlistentry>
+ <term>Line 1:</term>
+
+ <listitem>
+ <para>On establishing a connection,
+ <command>ppp</command> will look for an entry in
+ <filename>ppp.linkup</filename> according to the
+ following rules: First, try to match the same label
+ as we used in <filename>ppp.conf</filename>. If
+ that fails, look for an entry for the IP address of
+ our gateway. This entry is a four-octet IP style
+ label. If we still have not found an entry, look
+ for the <literal>MYADDR</literal> entry.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 2:</term>
+
+ <listitem>
+ <para>This line tells <command>ppp</command> to add a
+ default route that points to
+ <literal>HISADDR</literal>.
+ <literal>HISADDR</literal> will be replaced with the
+ IP number of the gateway as negotiated by the
+ IPCP.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>See the <literal>pmdemand</literal> entry in the files
+ <filename>/usr/share/examples/ppp/ppp.conf.sample</filename>
+ and
+ <filename>/usr/share/examples/ppp/ppp.linkup.sample</filename>
+ for a detailed example.</para>
+ </sect4>
+
+ <sect4>
+ <title>Receiving Incoming Calls</title>
+ <indexterm><primary>PPP</primary><secondary>receiving
+ incoming calls</secondary></indexterm>
+ <para>When you configure <application>ppp</application> to
+ receive incoming calls on a machine connected to a LAN, you
+ must decide if you wish to forward packets to the LAN. If you
+ do, you should allocate the peer an IP number from your LAN's
+ subnet, and use the command <command>enable proxy</command> in
+ your <filename>/etc/ppp/ppp.conf</filename> file. You should
+ also confirm that the <filename>/etc/rc.conf</filename> file
+ contains the following:</para>
+
+ <programlisting>gateway_enable="YES"</programlisting>
+ </sect4>
+
+ <sect4>
+ <title>Which getty?</title>
+
+ <para><link linkend="dialup">Configuring FreeBSD for Dial-up
+ Services</link> provides a good description on enabling
+ dial-up services using &man.getty.8;.</para>
+
+ <para>An alternative to <command>getty</command> is <link xlink:href="http://www.leo.org/~doering/mgetty/index.html">mgetty</link>,
+ a smarter version of <command>getty</command> designed
+ with dial-up lines in mind.</para>
+
+ <para>The advantages of using <command>mgetty</command> is
+ that it actively <emphasis>talks</emphasis> to modems,
+ meaning if port is turned off in
+ <filename>/etc/ttys</filename> then your modem will not answer
+ the phone.</para>
+
+ <para>Later versions of <command>mgetty</command> (from
+ 0.99beta onwards) also support the automatic detection of
+ PPP streams, allowing your clients script-less access to
+ your server.</para>
+
+ <para>Refer to <link linkend="userppp-mgetty">Mgetty and
+ AutoPPP</link> for more information on
+ <command>mgetty</command>.</para>
+ </sect4>
+
+ <sect4>
+ <title><application>PPP</application> Permissions</title>
+
+ <para>The <command>ppp</command> command must normally be
+ run as the <systemitem class="username">root</systemitem> user. If however,
+ you wish to allow <command>ppp</command> to run in
+ server mode as a normal user by executing
+ <command>ppp</command> as described below, that user
+ must be given permission to run <command>ppp</command>
+ by adding them to the <systemitem class="username">network</systemitem> group
+ in <filename>/etc/group</filename>.</para>
+
+ <para>You will also need to give them access to one or more
+ sections of the configuration file using the
+ <command>allow</command> command:</para>
+
+ <programlisting>allow users fred mary</programlisting>
+
+ <para>If this command is used in the <literal>default</literal>
+ section, it gives the specified users access to
+ everything.</para>
+ </sect4>
+
+ <sect4>
+ <title>PPP Shells for Dynamic-IP Users</title>
+ <indexterm><primary>PPP shells</primary></indexterm>
+
+ <para>Create a file called
+ <filename>/etc/ppp/ppp-shell</filename> containing the
+ following:</para>
+
+ <programlisting>#!/bin/sh
+IDENT=`echo $0 | sed -e 's/^.*-\(.*\)$/\1/'`
+CALLEDAS="$IDENT"
+TTY=`tty`
+
+if [ x$IDENT = xdialup ]; then
+ IDENT=`basename $TTY`
+fi
+
+echo "PPP for $CALLEDAS on $TTY"
+echo "Starting PPP for $IDENT"
+
+exec /usr/sbin/ppp -direct $IDENT</programlisting>
+
+ <para>This script should be executable. Now make a symbolic
+ link called <filename>ppp-dialup</filename> to this script
+ using the following commands:</para>
+
+ <screen>&prompt.root; <userinput>ln -s ppp-shell /etc/ppp/ppp-dialup</userinput></screen>
+
+ <para>You should use this script as the
+ <emphasis>shell</emphasis> for all of your dialup users.
+ This is an example from <filename>/etc/passwd</filename>
+ for a dialup PPP user with username
+ <systemitem class="username">pchilds</systemitem> (remember do not directly edit
+ the password file, use &man.vipw.8;).</para>
+
+ <programlisting>pchilds:*:1011:300:Peter Childs PPP:/home/ppp:/etc/ppp/ppp-dialup</programlisting>
+
+ <para>Create a <filename>/home/ppp</filename> directory that
+ is world readable containing the following 0 byte
+ files:</para>
+
+ <screen>-r--r--r-- 1 root wheel 0 May 27 02:23 .hushlogin
+-r--r--r-- 1 root wheel 0 May 27 02:22 .rhosts</screen>
+
+ <para>which prevents <filename>/etc/motd</filename> from being
+ displayed.</para>
+ </sect4>
+
+ <sect4>
+ <title>PPP Shells for Static-IP Users</title>
+ <indexterm><primary>PPP shells</primary></indexterm>
+
+ <para>Create the <filename>ppp-shell</filename> file as above,
+ and for each account with statically assigned IPs create a
+ symbolic link to <filename>ppp-shell</filename>.</para>
+
+ <para>For example, if you have three dialup customers,
+ <systemitem class="username">fred</systemitem>, <systemitem class="username">sam</systemitem>, and
+ <systemitem class="username">mary</systemitem>, that you route class C networks
+ for, you would type the following:</para>
+
+ <screen>&prompt.root; <userinput>ln -s /etc/ppp/ppp-shell /etc/ppp/ppp-fred</userinput>
+&prompt.root; <userinput>ln -s /etc/ppp/ppp-shell /etc/ppp/ppp-sam</userinput>
+&prompt.root; <userinput>ln -s /etc/ppp/ppp-shell /etc/ppp/ppp-mary</userinput></screen>
+
+ <para>Each of these users dialup accounts should have their
+ shell set to the symbolic link created above (for example,
+ <systemitem class="username">mary</systemitem>'s shell should be
+ <filename>/etc/ppp/ppp-mary</filename>).</para>
+ </sect4>
+
+ <sect4>
+ <title>Setting Up <filename>ppp.conf</filename> for Dynamic-IP Users</title>
+
+ <para>The <filename>/etc/ppp/ppp.conf</filename> file should
+ contain something along the lines of:</para>
+
+ <programlisting>default:
+ set debug phase lcp chat
+ set timeout 0
+
+ttyd0:
+ set ifaddr 203.14.100.1 203.14.100.20 255.255.255.255
+ enable proxy
+
+ttyd1:
+ set ifaddr 203.14.100.1 203.14.100.21 255.255.255.255
+ enable proxy</programlisting>
+
+ <note>
+ <para>The indenting is important.</para>
+ </note>
+
+ <para>The <literal>default:</literal> section is loaded for
+ each session. For each dialup line enabled in
+ <filename>/etc/ttys</filename> create an entry similar to
+ the one for <literal>ttyd0:</literal> above. Each line
+ should get a unique IP address from your pool of IP
+ addresses for dynamic users.</para>
+ </sect4>
+
+ <sect4>
+ <title>Setting Up <filename>ppp.conf</filename> for Static-IP
+ Users</title>
+
+ <para>Along with the contents of the sample
+ <filename>/usr/share/examples/ppp/ppp.conf</filename>
+ above you should add a section for each of the
+ statically assigned dialup users. We will continue with
+ our <systemitem class="username">fred</systemitem>, <systemitem class="username">sam</systemitem>,
+ and <systemitem class="username">mary</systemitem> example.</para>
+
+ <programlisting>fred:
+ set ifaddr 203.14.100.1 203.14.101.1 255.255.255.255
+
+sam:
+ set ifaddr 203.14.100.1 203.14.102.1 255.255.255.255
+
+mary:
+ set ifaddr 203.14.100.1 203.14.103.1 255.255.255.255</programlisting>
+
+ <para>The file <filename>/etc/ppp/ppp.linkup</filename>
+ should also contain routing information for each static
+ IP user if required. The line below would add a route
+ for the <systemitem class="ipaddress">203.14.101.0</systemitem>
+ class C via the client's ppp link.</para>
+
+ <programlisting>fred:
+ add 203.14.101.0 netmask 255.255.255.0 HISADDR
+
+sam:
+ add 203.14.102.0 netmask 255.255.255.0 HISADDR
+
+mary:
+ add 203.14.103.0 netmask 255.255.255.0 HISADDR</programlisting>
+ </sect4>
+
+ <sect4 xml:id="userppp-mgetty">
+ <title><command>mgetty</command> and AutoPPP</title>
+ <indexterm>
+ <primary><command>mgetty</command></primary>
+ </indexterm>
+ <indexterm><primary>AutoPPP</primary></indexterm>
+ <indexterm><primary>LCP</primary></indexterm>
+
+ <para>Configuring and compiling <command>mgetty</command>
+ with the <literal>AUTO_PPP</literal> option enabled
+ allows <command>mgetty</command> to detect the LCP phase
+ of PPP connections and automatically spawn off a ppp
+ shell. However, since the default login/password
+ sequence does not occur it is necessary to authenticate
+ users using either PAP or CHAP.</para>
+
+ <para>This section assumes the user has successfully
+ configured, compiled, and installed a version of
+ <command>mgetty</command> with the
+ <literal>AUTO_PPP</literal> option (v0.99beta or
+ later).</para>
+
+ <para>Make sure your
+ <filename>/usr/local/etc/mgetty+sendfax/login.config</filename>
+ file has the following in it:</para>
+
+ <programlisting>/AutoPPP/ - - /etc/ppp/ppp-pap-dialup</programlisting>
+
+ <para>This will tell <command>mgetty</command> to run the
+ <filename>ppp-pap-dialup</filename> script for detected
+ PPP connections.</para>
+
+ <para>Create a file called
+ <filename>/etc/ppp/ppp-pap-dialup</filename> containing the
+ following (the file should be executable):</para>
+
+ <programlisting>#!/bin/sh
+exec /usr/sbin/ppp -direct pap$IDENT</programlisting>
+
+ <para>For each dialup line enabled in
+ <filename>/etc/ttys</filename>, create a corresponding entry
+ in <filename>/etc/ppp/ppp.conf</filename>. This will
+ happily co-exist with the definitions we created
+ above.</para>
+
+ <programlisting>pap:
+ enable pap
+ set ifaddr 203.14.100.1 203.14.100.20-203.14.100.40
+ enable proxy</programlisting>
+
+ <para>Each user logging in with this method will need to have
+ a username/password in
+ <filename>/etc/ppp/ppp.secret</filename> file, or
+ alternatively add the following option to authenticate users
+ via PAP from the <filename>/etc/passwd</filename> file.</para>
+
+ <programlisting>enable passwdauth</programlisting>
+
+ <para>If you wish to assign some users a static IP number,
+ you can specify the number as the third argument in
+ <filename>/etc/ppp/ppp.secret</filename>. See
+ <filename>/usr/share/examples/ppp/ppp.secret.sample</filename>
+ for examples.</para>
+ </sect4>
+
+ <sect4>
+ <title>MS Extensions</title>
+ <indexterm><primary>DNS</primary></indexterm>
+ <indexterm><primary>NetBIOS</primary></indexterm>
+ <indexterm><primary>PPP</primary><secondary>Microsoft extensions</secondary></indexterm>
+ <para>It is possible to configure PPP to supply DNS and
+ NetBIOS nameserver addresses on demand.</para>
+
+ <para>To enable these extensions with PPP version 1.x, the
+ following lines might be added to the relevant section of
+ <filename>/etc/ppp/ppp.conf</filename>.</para>
+
+ <programlisting>enable msext
+set ns 203.14.100.1 203.14.100.2
+set nbns 203.14.100.5</programlisting>
+
+ <para>And for PPP version 2 and above:</para>
+
+ <programlisting>accept dns
+set dns 203.14.100.1 203.14.100.2
+set nbns 203.14.100.5</programlisting>
+
+ <para>This will tell the clients the primary and secondary
+ name server addresses, and a NetBIOS nameserver host.</para>
+
+ <para>In version 2 and above, if the
+ <literal>set dns</literal> line is omitted, PPP will use the
+ values found in <filename>/etc/resolv.conf</filename>.</para>
+ </sect4>
+
+ <sect4 xml:id="userppp-PAPnCHAP">
+ <title>PAP and CHAP Authentication</title>
+ <indexterm><primary>PAP</primary></indexterm>
+ <indexterm><primary>CHAP</primary></indexterm>
+ <para>Some ISPs set their system up so that the authentication
+ part of your connection is done using either of the PAP or
+ CHAP authentication mechanisms. If this is the case, your ISP
+ will not give a <prompt>login:</prompt> prompt when you
+ connect, but will start talking PPP immediately.</para>
+
+ <para>PAP is less secure than CHAP, but security is not normally
+ an issue here as passwords, although being sent as plain text
+ with PAP, are being transmitted down a serial line only.
+ There is not much room for crackers to
+ <quote>eavesdrop</quote>.</para>
+
+ <para>Referring back to the <link linkend="userppp-staticIP">PPP
+ and Static IP addresses</link> or <link linkend="userppp-dynamicIP">PPP and Dynamic IP addresses</link>
+ sections, the following alterations must be made:</para>
+
+ <programlisting>13 set authname <replaceable>MyUserName</replaceable>
+14 set authkey <replaceable>MyPassword</replaceable>
+15 set login</programlisting>
+
+ <variablelist>
+ <varlistentry>
+ <term>Line 13:</term>
+
+ <listitem>
+ <para>This line specifies your PAP/CHAP user name. You
+ will need to insert the correct value for
+ <replaceable>MyUserName</replaceable>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 14:</term>
+ <listitem>
+ <para>This line specifies your PAP/CHAP password<indexterm><primary>password</primary></indexterm>. You
+ will need to insert the correct value for
+ <replaceable>MyPassword</replaceable>. You may want to
+ add an additional line, such as:</para>
+
+ <programlisting>16 accept PAP</programlisting>
+
+ <para>or</para>
+
+ <programlisting>16 accept CHAP</programlisting>
+
+ <para>to make it obvious that this is the intention, but
+ PAP and CHAP are both accepted by default.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Line 15:</term>
+
+ <listitem>
+ <para>Your ISP will not normally require that you log into
+ the server if you are using PAP or CHAP. You must
+ therefore disable your <quote>set login</quote>
+ string.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect4>
+
+ <sect4>
+ <title>Changing Your <command>ppp</command> Configuration on the
+ Fly</title>
+
+ <para>It is possible to talk to the <command>ppp</command>
+ program while it is running in the background, but only if a
+ suitable diagnostic port has been set up. To do this, add the
+ following line to your configuration:</para>
+
+ <programlisting>set server /var/run/ppp-tun<replaceable>%d</replaceable> DiagnosticPassword 0177</programlisting>
+
+ <para>This will tell PPP to listen to the specified
+ &unix; domain socket, asking clients for the specified
+ password before allowing access. The
+ <literal>%d</literal> in the name is replaced with the
+ <filename>tun</filename> device number that is in
+ use.</para>
+
+ <para>Once a socket has been set up, the &man.pppctl.8;
+ program may be used in scripts that wish to manipulate the
+ running program.</para>
+ </sect4>
+ </sect3>
+
+ <sect3 xml:id="userppp-nat">
+ <title>Using PPP Network Address Translation Capability</title>
+ <indexterm><primary>PPP</primary><secondary>NAT</secondary></indexterm>
+
+ <para>PPP has ability to use internal NAT without kernel diverting
+ capabilities. This functionality may be enabled by the following
+ line in <filename>/etc/ppp/ppp.conf</filename>:</para>
+
+ <programlisting>nat enable yes</programlisting>
+
+ <para>Alternatively, PPP NAT may be enabled by command-line
+ option <literal>-nat</literal>. There is also
+ <filename>/etc/rc.conf</filename> knob named
+ <literal>ppp_nat</literal>, which is enabled by default.</para>
+
+ <para>If you use this feature, you may also find useful
+ the following <filename>/etc/ppp/ppp.conf</filename> options
+ to enable incoming connections forwarding:</para>
+
+ <programlisting>nat port tcp 10.0.0.2:ftp ftp
+nat port tcp 10.0.0.2:http http</programlisting>
+
+ <para>or do not trust the outside at all</para>
+
+ <programlisting>nat deny_incoming yes</programlisting>
+ </sect3>
+
+ <sect3 xml:id="userppp-final">
+ <title>Final System Configuration</title>
+ <indexterm><primary>PPP</primary><secondary>configuration</secondary></indexterm>
+
+ <para>You now have <command>ppp</command> configured, but there
+ are a few more things to do before it is ready to work. They
+ all involve editing the <filename>/etc/rc.conf</filename>
+ file.</para>
+
+ <para>Working from the top down in this file, make sure the
+ <literal>hostname=</literal> line is set, e.g.:</para>
+
+ <programlisting>hostname="foo.example.com"</programlisting>
+
+ <para>If your ISP has supplied you with a static IP address and
+ name, it is probably best that you use this name as your host
+ name.</para>
+
+ <para>Look for the <literal>network_interfaces</literal> variable.
+ If you want to configure your system to dial your ISP on demand,
+ make sure the <filename>tun0</filename> device is added to
+ the list, otherwise remove it.</para>
+
+ <programlisting>network_interfaces="lo0 tun0"
+ifconfig_tun0=</programlisting>
+
+ <note>
+ <para>The <literal>ifconfig_tun0</literal> variable should be
+ empty, and a file called
+ <filename>/etc/start_if.tun0</filename> should be created.
+ This file should contain the line:</para>
+
+ <programlisting>ppp -auto mysystem</programlisting>
+
+ <para>This script is executed at network configuration time,
+ starting your ppp daemon in automatic mode. If you have a LAN
+ for which this machine is a gateway, you may also wish to use
+ the <option>-alias</option> switch. Refer to the manual page
+ for further details.</para>
+ </note>
+
+ <para>Make sure that the router program is set to <literal>NO</literal> with
+ the following line in your
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>router_enable="NO"</programlisting>
+
+ <indexterm>
+ <primary><application>routed</application></primary>
+ </indexterm>
+ <para>It is important that the <command>routed</command> daemon is
+ not started, as
+ <command>routed</command> tends to delete the default routing
+ table entries created by <command>ppp</command>.</para>
+
+ <para>It is probably worth your while ensuring that the
+ <literal>sendmail_flags</literal> line does not include the
+ <option>-q</option> option, otherwise
+ <command>sendmail</command> will attempt to do a network lookup
+ every now and then, possibly causing your machine to dial out.
+ You may try:</para>
+
+ <programlisting>sendmail_flags="-bd"</programlisting>
+
+ <indexterm>
+ <primary><application>sendmail</application></primary>
+ </indexterm>
+ <para>The downside of this is that you must force
+ <command>sendmail</command> to re-examine the mail queue
+ whenever the ppp link is up by typing:</para>
+
+ <screen>&prompt.root; <userinput>/usr/sbin/sendmail -q</userinput></screen>
+
+ <para>You may wish to use the <command>!bg</command> command in
+ <filename>ppp.linkup</filename> to do this automatically:</para>
+
+ <programlisting>1 provider:
+2 delete ALL
+3 add 0 0 HISADDR
+4 !bg sendmail -bd -q30m</programlisting>
+
+ <indexterm><primary>SMTP</primary></indexterm>
+ <para>If you do not like this, it is possible to set up a
+ <quote>dfilter</quote> to block SMTP traffic. Refer to the
+ sample files for further details.</para>
+
+ <para>All that is left is to reboot the machine. After rebooting,
+ you can now either type:</para>
+
+ <screen>&prompt.root; <userinput>ppp</userinput></screen>
+
+ <para>and then <command>dial provider</command> to start the PPP
+ session, or, if you want <command>ppp</command> to establish
+ sessions automatically when there is outbound traffic (and
+ you have not created the <filename>start_if.tun0</filename>
+ script), type:</para>
+
+ <screen>&prompt.root; <userinput>ppp -auto provider</userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Summary</title>
+
+ <para>To recap, the following steps are necessary when setting up
+ ppp for the first time:</para>
+
+ <para>Client side:</para>
+
+ <procedure>
+ <step>
+ <para>Ensure that the <filename>tun</filename> device is
+ built into your kernel.</para>
+ </step>
+
+ <step>
+ <para>Ensure that the
+ <filename>tunN</filename> device
+ file is available in the <filename>/dev</filename>
+ directory.</para>
+ </step>
+
+ <step>
+ <para>Create an entry in
+ <filename>/etc/ppp/ppp.conf</filename>. The
+ <filename>pmdemand</filename> example should suffice for
+ most ISPs.</para>
+ </step>
+
+ <step>
+ <para>If you have a dynamic IP address, create an entry in
+ <filename>/etc/ppp/ppp.linkup</filename>.</para>
+ </step>
+
+ <step>
+ <para>Update your <filename>/etc/rc.conf</filename>
+ file.</para>
+ </step>
+
+ <step>
+ <para>Create a <filename>start_if.tun0</filename> script if
+ you require demand dialing.</para>
+ </step>
+ </procedure>
+
+ <para>Server side:</para>
+
+ <procedure>
+ <step>
+ <para>Ensure that the <filename>tun</filename> device is
+ built into your kernel.</para>
+ </step>
+
+ <step>
+ <para>Ensure that the
+ <filename>tunN</filename> device
+ file is available in the <filename>/dev</filename>
+ directory.</para>
+ </step>
+
+ <step>
+ <para>Create an entry in <filename>/etc/passwd</filename>
+ (using the &man.vipw.8; program).</para>
+ </step>
+
+ <step>
+ <para>Create a profile in this users home directory that runs
+ <command>ppp -direct direct-server</command> or
+ similar.</para>
+ </step>
+
+ <step>
+ <para>Create an entry in
+ <filename>/etc/ppp/ppp.conf</filename>. The
+ <filename>direct-server</filename> example should
+ suffice.</para>
+ </step>
+
+ <step>
+ <para>Create an entry in
+ <filename>/etc/ppp/ppp.linkup</filename>.</para>
+ </step>
+
+ <step>
+ <para>Update your <filename>/etc/rc.conf</filename>
+ file.</para>
+ </step>
+ </procedure>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="ppp">
+ <info><title>Using Kernel PPP</title>
+ <authorgroup>
+ <author><personname><firstname>Gennady B.</firstname><surname>Sorokopud</surname></personname><contrib>Parts originally contributed by </contrib></author>
+ <author><personname><firstname>Robert</firstname><surname>Huff</surname></personname></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect2>
+ <title>Setting Up Kernel PPP</title>
+ <indexterm><primary>PPP</primary><secondary>kernel PPP</secondary></indexterm>
+
+ <para>Before you start setting up PPP on your machine, make sure
+ that <command>pppd</command> is located in
+ <filename>/usr/sbin</filename> and the directory
+ <filename>/etc/ppp</filename> exists.</para>
+
+ <para><command>pppd</command> can work in two modes:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>As a <quote>client</quote> &mdash; you want to connect your
+ machine to the outside world via a PPP serial connection or
+ modem line.</para>
+ </listitem>
+
+ <listitem>
+ <para>As a <quote>server</quote><indexterm><primary>PPP</primary><secondary>server</secondary></indexterm> &mdash; your machine is located on
+ the network, and is used to connect other computers using
+ PPP.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>In both cases you will need to set up an options file
+ (<filename>/etc/ppp/options</filename> or
+ <filename>~/.ppprc</filename> if you have more than one user on
+ your machine that uses PPP).</para>
+
+ <para>You will also need some modem/serial software (preferably
+ <package>comms/kermit</package>), so you can dial and
+ establish a connection with the remote host.</para>
+ </sect2>
+
+ <sect2>
+ <info><title>Using <command>pppd</command> as a Client</title>
+ <authorgroup>
+ <author><personname><firstname>Trev</firstname><surname>Roydhouse</surname></personname><contrib>Based on information provided by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>PPP</primary><secondary>client</secondary></indexterm>
+ <indexterm><primary>Cisco</primary></indexterm>
+ <para>The following <filename>/etc/ppp/options</filename> might be
+ used to connect to a Cisco terminal server PPP line.</para>
+
+ <programlisting>crtscts # enable hardware flow control
+modem # modem control line
+noipdefault # remote PPP server must supply your IP address
+ # if the remote host does not send your IP during IPCP
+ # negotiation, remove this option
+passive # wait for LCP packets
+domain ppp.foo.com # put your domain name here
+
+:&lt;remote_ip&gt; # put the IP of remote PPP host here
+ # it will be used to route packets via PPP link
+ # if you didn't specified the noipdefault option
+ # change this line to &lt;local_ip&gt;:&lt;remote_ip&gt;
+
+defaultroute # put this if you want that PPP server will be your
+ # default router</programlisting>
+
+ <para>To connect:</para>
+
+ <indexterm><primary>Kermit</primary></indexterm>
+ <indexterm><primary>modem</primary></indexterm>
+ <procedure>
+ <step>
+ <para>Dial to the remote host using <application>Kermit</application> (or some other modem
+ program), and enter your user name and password (or whatever
+ is needed to enable PPP on the remote host).</para>
+ </step>
+
+ <step>
+ <para>Exit <application>Kermit</application> (without
+ hanging up the line).</para>
+ </step>
+
+ <step>
+ <para>Enter the following:</para>
+
+ <screen>&prompt.root; <userinput>/usr/src/usr.sbin/pppd.new/pppd /dev/tty01 19200</userinput></screen>
+
+ <para>Be sure to use the appropriate speed and device name.</para>
+ </step>
+ </procedure>
+
+ <para>Now your computer is connected with PPP. If the connection
+ fails, you can add the <option>debug</option> option to the
+ <filename>/etc/ppp/options</filename> file, and check console messages
+ to track the problem.</para>
+
+ <para>Following <filename>/etc/ppp/pppup</filename> script will make
+ all 3 stages automatic:</para>
+
+ <programlisting>#!/bin/sh
+ps ax |grep pppd |grep -v grep
+pid=`ps ax |grep pppd |grep -v grep|awk '{print $1;}'`
+if [ "X${pid}" != "X" ] ; then
+ echo 'killing pppd, PID=' ${pid}
+ kill ${pid}
+fi
+ps ax |grep kermit |grep -v grep
+pid=`ps ax |grep kermit |grep -v grep|awk '{print $1;}'`
+if [ "X${pid}" != "X" ] ; then
+ echo 'killing kermit, PID=' ${pid}
+ kill -9 ${pid}
+fi
+
+ifconfig ppp0 down
+ifconfig ppp0 delete
+
+kermit -y /etc/ppp/kermit.dial
+pppd /dev/tty01 19200</programlisting>
+
+ <indexterm><primary>Kermit</primary></indexterm>
+ <para><filename>/etc/ppp/kermit.dial</filename> is a <application>Kermit</application>
+ script that dials and makes all necessary authorization on the
+ remote host (an example of such a script is attached to the end
+ of this document).</para>
+
+ <para>Use the following <filename>/etc/ppp/pppdown</filename> script
+ to disconnect the PPP line:</para>
+
+ <programlisting>#!/bin/sh
+pid=`ps ax |grep pppd |grep -v grep|awk '{print $1;}'`
+if [ X${pid} != "X" ] ; then
+ echo 'killing pppd, PID=' ${pid}
+ kill -TERM ${pid}
+fi
+
+ps ax |grep kermit |grep -v grep
+pid=`ps ax |grep kermit |grep -v grep|awk '{print $1;}'`
+if [ "X${pid}" != "X" ] ; then
+ echo 'killing kermit, PID=' ${pid}
+ kill -9 ${pid}
+fi
+
+/sbin/ifconfig ppp0 down
+/sbin/ifconfig ppp0 delete
+kermit -y /etc/ppp/kermit.hup
+/etc/ppp/ppptest</programlisting>
+
+ <para>Check to see if <command>pppd</command> is still running by executing
+ <filename>/usr/etc/ppp/ppptest</filename>, which should look like
+ this:</para>
+
+ <programlisting>#!/bin/sh
+pid=`ps ax| grep pppd |grep -v grep|awk '{print $1;}'`
+if [ X${pid} != "X" ] ; then
+ echo 'pppd running: PID=' ${pid-NONE}
+else
+ echo 'No pppd running.'
+fi
+set -x
+netstat -n -I ppp0
+ifconfig ppp0</programlisting>
+
+ <para>To hang up the modem, execute
+ <filename>/etc/ppp/kermit.hup</filename>, which should
+ contain:</para>
+
+ <programlisting>set line /dev/tty01 ; put your modem device here
+set speed 19200
+set file type binary
+set file names literal
+set win 8
+set rec pack 1024
+set send pack 1024
+set block 3
+set term bytesize 8
+set command bytesize 8
+set flow none
+
+pau 1
+out +++
+inp 5 OK
+out ATH0\13
+echo \13
+exit</programlisting>
+
+ <para>Here is an alternate method using <command>chat</command>
+ instead of <command>kermit</command>:</para>
+
+ <para>The following two files are sufficient to accomplish a
+ <command>pppd</command> connection.</para>
+
+ <para><filename>/etc/ppp/options</filename>:</para>
+
+ <programlisting>/dev/cuaa1 115200
+
+crtscts # enable hardware flow control
+modem # modem control line
+connect "/usr/bin/chat -f /etc/ppp/login.chat.script"
+noipdefault # remote PPP serve must supply your IP address
+ # if the remote host doesn't send your IP during
+ # IPCP negotiation, remove this option
+passive # wait for LCP packets
+domain &lt;your.domain&gt; # put your domain name here
+
+: # put the IP of remote PPP host here
+ # it will be used to route packets via PPP link
+ # if you didn't specified the noipdefault option
+ # change this line to &lt;local_ip&gt;:&lt;remote_ip&gt;
+
+defaultroute # put this if you want that PPP server will be
+ # your default router</programlisting>
+
+ <para><filename>/etc/ppp/login.chat.script</filename>:</para>
+
+ <note>
+ <para>The following should go on a single line.</para>
+ </note>
+
+ <programlisting>ABORT BUSY ABORT 'NO CARRIER' "" AT OK ATDT&lt;phone.number&gt;
+ CONNECT "" TIMEOUT 10 ogin:-\\r-ogin: &lt;login-id&gt;
+ TIMEOUT 5 sword: &lt;password&gt;</programlisting>
+
+ <para>Once these are installed and modified correctly, all you need
+ to do is run <command>pppd</command>, like so:</para>
+
+ <screen>&prompt.root; <userinput>pppd</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Using <command>pppd</command> as a Server</title>
+
+ <para><filename>/etc/ppp/options</filename> should contain something
+ similar to the following:</para>
+
+ <programlisting>crtscts # Hardware flow control
+netmask 255.255.255.0 # netmask (not required)
+192.114.208.20:192.114.208.165 # IP's of local and remote hosts
+ # local ip must be different from one
+ # you assigned to the Ethernet (or other)
+ # interface on your machine.
+ # remote IP is IP address that will be
+ # assigned to the remote machine
+domain ppp.foo.com # your domain
+passive # wait for LCP
+modem # modem line</programlisting>
+
+ <para>The following <filename>/etc/ppp/pppserv</filename> script
+ will tell <application>pppd</application> to behave as a
+ server:</para>
+
+ <programlisting>#!/bin/sh
+ps ax |grep pppd |grep -v grep
+pid=`ps ax |grep pppd |grep -v grep|awk '{print $1;}'`
+if [ "X${pid}" != "X" ] ; then
+ echo 'killing pppd, PID=' ${pid}
+ kill ${pid}
+fi
+ps ax |grep kermit |grep -v grep
+pid=`ps ax |grep kermit |grep -v grep|awk '{print $1;}'`
+if [ "X${pid}" != "X" ] ; then
+ echo 'killing kermit, PID=' ${pid}
+ kill -9 ${pid}
+fi
+
+# reset ppp interface
+ifconfig ppp0 down
+ifconfig ppp0 delete
+
+# enable autoanswer mode
+kermit -y /etc/ppp/kermit.ans
+
+# run ppp
+pppd /dev/tty01 19200</programlisting>
+
+ <para>Use this <filename>/etc/ppp/pppservdown</filename> script to
+ stop the server:</para>
+
+ <programlisting>#!/bin/sh
+ps ax |grep pppd |grep -v grep
+pid=`ps ax |grep pppd |grep -v grep|awk '{print $1;}'`
+if [ "X${pid}" != "X" ] ; then
+ echo 'killing pppd, PID=' ${pid}
+ kill ${pid}
+fi
+ps ax |grep kermit |grep -v grep
+pid=`ps ax |grep kermit |grep -v grep|awk '{print $1;}'`
+if [ "X${pid}" != "X" ] ; then
+ echo 'killing kermit, PID=' ${pid}
+ kill -9 ${pid}
+fi
+ifconfig ppp0 down
+ifconfig ppp0 delete
+
+kermit -y /etc/ppp/kermit.noans</programlisting>
+
+ <para>The following <application>Kermit</application> script
+ (<filename>/etc/ppp/kermit.ans</filename>) will enable/disable
+ autoanswer mode on your modem. It should look like this:</para>
+
+ <programlisting>set line /dev/tty01
+set speed 19200
+set file type binary
+set file names literal
+set win 8
+set rec pack 1024
+set send pack 1024
+set block 3
+set term bytesize 8
+set command bytesize 8
+set flow none
+
+pau 1
+out +++
+inp 5 OK
+out ATH0\13
+inp 5 OK
+echo \13
+out ATS0=1\13 ; change this to out ATS0=0\13 if you want to disable
+ ; autoanswer mode
+inp 5 OK
+echo \13
+exit</programlisting>
+
+ <para>A script named <filename>/etc/ppp/kermit.dial</filename> is
+ used for dialing and authenticating on the remote host. You will
+ need to customize it for your needs. Put your login and password
+ in this script; you will also need to change the input statement
+ depending on responses from your modem and remote host.</para>
+
+ <programlisting>;
+; put the com line attached to the modem here:
+;
+set line /dev/tty01
+;
+; put the modem speed here:
+;
+set speed 19200
+set file type binary ; full 8 bit file xfer
+set file names literal
+set win 8
+set rec pack 1024
+set send pack 1024
+set block 3
+set term bytesize 8
+set command bytesize 8
+set flow none
+set modem hayes
+set dial hangup off
+set carrier auto ; Then SET CARRIER if necessary,
+set dial display on ; Then SET DIAL if necessary,
+set input echo on
+set input timeout proceed
+set input case ignore
+def \%x 0 ; login prompt counter
+goto slhup
+
+:slcmd ; put the modem in command mode
+echo Put the modem in command mode.
+clear ; Clear unread characters from input buffer
+pause 1
+output +++ ; hayes escape sequence
+input 1 OK\13\10 ; wait for OK
+if success goto slhup
+output \13
+pause 1
+output at\13
+input 1 OK\13\10
+if fail goto slcmd ; if modem doesn't answer OK, try again
+
+:slhup ; hang up the phone
+clear ; Clear unread characters from input buffer
+pause 1
+echo Hanging up the phone.
+output ath0\13 ; hayes command for on hook
+input 2 OK\13\10
+if fail goto slcmd ; if no OK answer, put modem in command mode
+
+:sldial ; dial the number
+pause 1
+echo Dialing.
+output atdt9,550311\13\10 ; put phone number here
+assign \%x 0 ; zero the time counter
+
+:look
+clear ; Clear unread characters from input buffer
+increment \%x ; Count the seconds
+input 1 {CONNECT }
+if success goto sllogin
+reinput 1 {NO CARRIER\13\10}
+if success goto sldial
+reinput 1 {NO DIALTONE\13\10}
+if success goto slnodial
+reinput 1 {\255}
+if success goto slhup
+reinput 1 {\127}
+if success goto slhup
+if &lt; \%x 60 goto look
+else goto slhup
+
+:sllogin ; login
+assign \%x 0 ; zero the time counter
+pause 1
+echo Looking for login prompt.
+
+:slloop
+increment \%x ; Count the seconds
+clear ; Clear unread characters from input buffer
+output \13
+;
+; put your expected login prompt here:
+;
+input 1 {Username: }
+if success goto sluid
+reinput 1 {\255}
+if success goto slhup
+reinput 1 {\127}
+if success goto slhup
+if &lt; \%x 10 goto slloop ; try 10 times to get a login prompt
+else goto slhup ; hang up and start again if 10 failures
+
+:sluid
+;
+; put your userid here:
+;
+output ppp-login\13
+input 1 {Password: }
+;
+; put your password here:
+;
+output ppp-password\13
+input 1 {Entering SLIP mode.}
+echo
+quit
+
+:slnodial
+echo \7No dialtone. Check the telephone line!\7
+exit 1
+
+; local variables:
+; mode: csh
+; comment-start: "; "
+; comment-start-skip: "; "
+; end:</programlisting>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="ppp-troubleshoot">
+ <info><title>Troubleshooting <acronym>PPP</acronym> Connections</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+ <indexterm><primary>PPP</primary><secondary>troubleshooting</secondary></indexterm>
+
+ <para>This section covers a few issues which may arise when
+ using PPP over a modem connection. For instance, perhaps you
+ need to know exactly what prompts the system you are dialing
+ into will present. Some <acronym>ISP</acronym>s present the
+ <literal>ssword</literal> prompt, and others will present
+ <literal>password</literal>; if the <command>ppp</command>
+ script is not written accordingly, the login attempt will
+ fail. The most common way to debug <command>ppp</command>
+ connections is by connecting manually. The following
+ information will walk you through a manual connection step by
+ step.</para>
+
+ <sect2>
+ <title>Check the Device Nodes</title>
+
+ <para>If you reconfigured your kernel then you recall the
+ <filename>sio</filename> device. If you did not
+ configure your kernel, there is no reason to worry. Just
+ check the <command>dmesg</command> output for the modem
+ device with:</para>
+
+ <screen>&prompt.root; <userinput>dmesg | grep sio</userinput></screen>
+
+ <para>You should get some pertinent output about the
+ <filename>sio</filename> devices. These are the COM
+ ports we need. If your modem acts like a standard serial
+ port then you should see it listed on
+ <filename>sio1</filename>, or <filename>COM2</filename>. If so, you are not
+ required to rebuild the kernel, you just need to make the
+ serial device. You can do this by changing your directory
+ to <filename>/dev</filename> and running the
+ <filename>MAKEDEV</filename> script like above. Now make
+ the serial devices with:</para>
+
+ <screen>&prompt.root; <userinput>sh MAKEDEV cuaa0 cuaa1 cuaa2 cuaa3</userinput></screen>
+
+ <para>which will create the serial devices for your system.
+ When matching up sio modem is on <filename>sio1</filename> or
+ <filename>COM2</filename> if you are in DOS, then your
+ modem device would be <filename>/dev/cuaa1</filename>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Connecting Manually</title>
+
+ <para>Connecting to the Internet by manually controlling
+ <command>ppp</command> is quick, easy, and a great way to
+ debug a connection or just get information on how your
+ <acronym>ISP</acronym> treats <command>ppp</command> client
+ connections. Lets start <application>PPP</application> from
+ the command line. Note that in all of our examples we will
+ use <emphasis>example</emphasis> as the hostname of the
+ machine running <application>PPP</application>. You start
+ <command>ppp</command> by just typing
+ <command>ppp</command>:</para>
+
+ <screen>&prompt.root; <userinput>ppp</userinput></screen>
+
+ <para>We have now started <command>ppp</command>.</para>
+
+ <screen>ppp ON example&gt; <userinput>set device /dev/cuaa1</userinput></screen>
+
+ <para>We set our modem device, in this case it is
+ <filename>cuaa1</filename>.</para>
+
+ <screen>ppp ON example&gt; <userinput>set speed 115200</userinput></screen>
+
+ <para>Set the connection speed, in this case we
+ are using 115,200 <acronym>kbps</acronym>.</para>
+
+ <screen>ppp ON example&gt; <userinput>enable dns</userinput></screen>
+
+ <para>Tell <command>ppp</command> to configure our
+ resolver and add the nameserver lines to
+ <filename>/etc/resolv.conf</filename>. If <command>ppp</command>
+ cannot determine our hostname, we can set one manually later.</para>
+
+ <screen>ppp ON example&gt; <userinput>term</userinput></screen>
+
+ <para>Switch to <quote>terminal</quote> mode so that we can manually
+ control the modem.</para>
+
+ <programlisting>deflink: Entering terminal mode on <filename>/dev/cuaa1</filename>
+type '~h' for help</programlisting>
+
+ <screen><userinput>at</userinput>
+OK
+<userinput>atdt123456789</userinput></screen>
+
+ <para>Use <command>at</command> to initialize the modem,
+ then use <command>atdt</command> and the number for your
+ <acronym>ISP</acronym> to begin the dial in process.</para>
+
+ <screen>CONNECT</screen>
+
+ <para>Confirmation of the connection, if we are going to have
+ any connection problems, unrelated to hardware, here is where
+ we will attempt to resolve them.</para>
+
+ <screen>ISP Login:<userinput>myusername</userinput></screen>
+
+ <para>Here you are prompted for a username, return the
+ prompt with the username that was provided by the
+ <acronym>ISP</acronym>.</para>
+
+ <screen>ISP Pass:<userinput>mypassword</userinput></screen>
+
+ <para>This time we are prompted for a password, just
+ reply with the password that was provided by the
+ <acronym>ISP</acronym>. Just like logging into
+ &os;, the password will not echo.</para>
+
+ <screen>Shell or PPP:<userinput>ppp</userinput></screen>
+
+ <para>Depending on your <acronym>ISP</acronym> this prompt
+ may never appear. Here we are being asked if we wish to
+ use a shell on the provider, or to start
+ <command>ppp</command>. In this example, we have chosen
+ to use <command>ppp</command> as we want an Internet
+ connection.</para>
+
+ <screen>Ppp ON example&gt;</screen>
+
+ <para>Notice that in this example the first <option>p</option>
+ has been capitalized. This shows that we have successfully
+ connected to the <acronym>ISP</acronym>.</para>
+
+ <screen>PPp ON example&gt;</screen>
+
+ <para>We have successfully authenticated with our
+ <acronym>ISP</acronym> and are waiting for the
+ assigned <acronym>IP</acronym> address.</para>
+
+ <screen>PPP ON example&gt;</screen>
+
+ <para>We have made an agreement on an <acronym>IP</acronym>
+ address and successfully completed our connection.</para>
+
+ <screen>PPP ON example&gt;<userinput>add default HISADDR</userinput></screen>
+
+ <para>Here we add our default route, we need to do this before
+ we can talk to the outside world as currently the only
+ established connection is with the peer. If this fails due to
+ existing routes you can put a bang character
+ <literal>!</literal> in front of the <option>add</option>.
+ Alternatively, you can set this before making the actual
+ connection and it will negotiate a new route
+ accordingly.</para>
+
+ <para>If everything went good we should now have an active
+ connection to the Internet, which could be thrown into the
+ background using <keycombo action="simul"><keycap>CTRL</keycap>
+ <keycap>z</keycap></keycombo> If you notice the
+ <command>PPP</command> return to <command>ppp</command> then
+ we have lost our connection. This is good to know because it
+ shows our connection status. Capital P's show that we have a
+ connection to the <acronym>ISP</acronym> and lowercase p's
+ show that the connection has been lost for whatever reason.
+ <command>ppp</command> only has these 2 states.</para>
+
+ <sect3>
+ <title>Debugging</title>
+
+ <para>If you have a direct line and cannot seem to make a
+ connection, then turn hardware flow
+ <acronym>CTS/RTS</acronym> to off with the <option>set
+ ctsrts off</option>. This is mainly the case if you are
+ connected to some <application>PPP</application> capable
+ terminal servers, where <application>PPP</application> hangs
+ when it tries to write data to your communication link, so
+ it would be waiting for a <acronym>CTS</acronym>, or Clear
+ To Send signal which may never come. If you use this option
+ however, you should also use the <option>set accmap</option>
+ option, which may be required to defeat hardware dependent
+ on passing certain characters from end to end, most of the
+ time XON/XOFF. See the &man.ppp.8; manual page for more
+ information on this option, and how it is used.</para>
+
+ <para>If you have an older modem, you may need to use the
+ <option>set parity even</option>. Parity is set at none
+ be default, but is used for error checking (with a large
+ increase in traffic) on older modems and some
+ <acronym>ISP</acronym>s. You may need this option for
+ the Compuserve <acronym>ISP</acronym>.</para>
+
+ <para><application>PPP</application> may not return to the
+ command mode, which is usually a negotiation error where
+ the <acronym>ISP</acronym> is waiting for your side to start
+ negotiating. At this point, using the <command>~p</command>
+ command will force ppp to start sending the configuration
+ information.</para>
+
+ <para>If you never obtain a login prompt, then most likely you
+ need to use <acronym>PAP</acronym> or
+ <acronym>CHAP</acronym> authentication instead of the
+ &unix; style in the example above. To use
+ <acronym>PAP</acronym> or <acronym>CHAP</acronym> just add
+ the following options to <application>PPP</application>
+ before going into terminal mode:</para>
+
+ <screen>ppp ON example&gt; <userinput>set authname myusername</userinput></screen>
+
+ <para>Where <replaceable>myusername</replaceable> should be
+ replaced with the username that was assigned by the
+ <acronym>ISP</acronym>.</para>
+
+ <screen>ppp ON example&gt; <userinput>set authkey mypassword</userinput></screen>
+
+ <para>Where <replaceable>mypassword</replaceable> should be
+ replaced with the password that was assigned by the
+ <acronym>ISP</acronym>.</para>
+
+ <para>If you connect fine, but cannot seem to find any domain
+ name, try to use &man.ping.8; with an <acronym>IP</acronym>
+ address and see if you can get any return information. If
+ you experience 100 percent (100%) packet loss, then it is most
+ likely that you were not assigned a default route. Double
+ check that the option <option>add default HISADDR</option>
+ was set during the connection. If you can connect to a
+ remote <acronym>IP</acronym> address then it is possible
+ that a resolver address has not been added to the
+ <filename>/etc/resolv.conf</filename>. This file should
+ look like:</para>
+
+ <programlisting>domain <replaceable>example.com</replaceable>
+nameserver <replaceable>x.x.x.x</replaceable>
+nameserver <replaceable>y.y.y.y</replaceable></programlisting>
+
+ <para>Where <replaceable>x.x.x.x</replaceable> and
+ <replaceable>y.y.y.y</replaceable> should be replaced with
+ the <acronym>IP</acronym> address of your
+ <acronym>ISP</acronym>'s DNS servers. This information may
+ or may not have been provided when you signed up, but a
+ quick call to your <acronym>ISP</acronym> should remedy
+ that.</para>
+
+ <para>You could also have &man.syslog.3; provide a logging
+ function for your <application>PPP</application> connection.
+ Just add:</para>
+
+ <programlisting>!ppp
+*.* /var/log/ppp.log</programlisting>
+
+ <para>to <filename>/etc/syslog.conf</filename>. In most cases, this
+ functionality already exists.</para>
+
+ </sect3>
+ </sect2>
+ </sect1>
+
+
+
+
+ <sect1 xml:id="pppoe">
+ <info><title>Using PPP over Ethernet (PPPoE)</title>
+ <authorgroup>
+ <author><personname><firstname>Jim</firstname><surname>Mock</surname></personname><contrib>Contributed (from http://node.to/freebsd/how-tos/how-to-freebsd-pppoe.html) by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+ <indexterm><primary>PPP</primary><secondary>over Ethernet</secondary></indexterm>
+ <indexterm>
+ <primary>PPPoE</primary>
+ <see>PPP, over Ethernet</see>
+ </indexterm>
+
+ <para>This section describes how to set up PPP over Ethernet
+ (<acronym>PPPoE</acronym>).</para>
+
+ <sect2>
+ <title>Configuring the Kernel</title>
+
+ <para>No kernel configuration is necessary for PPPoE any longer. If
+ the necessary netgraph support is not built into the kernel, it will
+ be dynamically loaded by <application>ppp</application>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Setting Up <filename>ppp.conf</filename></title>
+
+ <para>Here is an example of a working
+ <filename>ppp.conf</filename>:</para>
+
+ <programlisting>default:
+ set log Phase tun command # you can add more detailed logging if you wish
+ set ifaddr 10.0.0.1/0 10.0.0.2/0
+
+name_of_service_provider:
+ set device PPPoE:<replaceable>xl1</replaceable> # replace xl1 with your Ethernet device
+ set authname YOURLOGINNAME
+ set authkey YOURPASSWORD
+ set dial
+ set login
+ add default HISADDR</programlisting>
+
+ </sect2>
+
+ <sect2>
+ <title>Running <application>ppp</application></title>
+
+ <para>As <systemitem class="username">root</systemitem>, you can run:</para>
+
+ <screen>&prompt.root; <userinput>ppp -ddial name_of_service_provider</userinput></screen>
+
+ </sect2>
+
+ <sect2>
+ <title>Starting <application>ppp</application> at Boot</title>
+
+ <para>Add the following to your <filename>/etc/rc.conf</filename>
+ file:</para>
+
+ <programlisting>ppp_enable="YES"
+ppp_mode="ddial"
+ppp_nat="YES" # if you want to enable nat for your local network, otherwise NO
+ppp_profile="name_of_service_provider"</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Using a PPPoE Service Tag</title>
+
+ <para>Sometimes it will be necessary to use a service tag to establish
+ your connection. Service tags are used to distinguish between
+ different PPPoE servers attached to a given network.</para>
+
+ <para>You should have been given any required service tag information
+ in the documentation provided by your ISP. If you cannot locate
+ it there, ask your ISP's tech support personnel.</para>
+
+ <para>As a last resort, you could try the method suggested by the
+ <link xlink:href="http://www.roaringpenguin.com/pppoe/">Roaring Penguin
+ PPPoE</link> program which can be found in the <link linkend="ports">Ports Collection</link>. Bear in mind however,
+ this may de-program your modem and render it useless, so
+ think twice before doing it. Simply install the program shipped
+ with the modem by your provider. Then, access the
+ <guimenu>System</guimenu> menu from the program. The name of your
+ profile should be listed there. It is usually
+ <emphasis>ISP</emphasis>.</para>
+
+ <para>The profile name (service tag) will be used in the PPPoE
+ configuration entry in <filename>ppp.conf</filename> as the provider
+ part of the <command>set device</command> command (see the &man.ppp.8;
+ manual page for full details). It should look like this:</para>
+
+ <programlisting>set device PPPoE:<replaceable>xl1</replaceable>:<replaceable>ISP</replaceable></programlisting>
+
+ <para>Do not forget to change <replaceable>xl1</replaceable>
+ to the proper device for your Ethernet card.</para>
+ <para>Do not forget to change <replaceable>ISP</replaceable>
+ to the profile you have just found above.</para>
+
+ <para>For additional information, see:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="http://renaud.waldura.com/doc/freebsd/pppoe/">Cheaper
+ Broadband with FreeBSD on DSL</link> by Renaud
+ Waldura.</para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.ruhr.de/home/nathan/FreeBSD/tdsl-freebsd.html">
+ Nutzung von T-DSL und T-Online mit FreeBSD</link>
+ by Udo Erdelhoff (in German).</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2 xml:id="ppp-3com">
+
+ <title>PPPoE with a &tm.3com; <trademark class="registered">HomeConnect</trademark> ADSL Modem Dual Link</title>
+
+ <para>This modem does not follow <link xlink:href="http://www.faqs.org/rfcs/rfc2516.html">RFC 2516</link>
+ (<emphasis>A Method for transmitting PPP over Ethernet
+ (PPPoE)</emphasis>, written by L. Mamakos, K. Lidl, J. Evarts,
+ D. Carrel, D. Simone, and R. Wheeler). Instead, different packet
+ type codes have been used for the Ethernet frames. Please complain
+ to <link xlink:href="http://www.3com.com/">3Com</link> if you think it
+ should comply with the PPPoE specification.</para>
+
+ <para>In order to make FreeBSD capable of communicating with this
+ device, a sysctl must be set. This can be done automatically at
+ boot time by updating <filename>/etc/sysctl.conf</filename>:</para>
+
+ <programlisting>net.graph.nonstandard_pppoe=1</programlisting>
+
+ <para>or can be done immediately with the command:</para>
+
+ <screen>&prompt.root; <userinput>sysctl net.graph.nonstandard_pppoe=1</userinput></screen>
+
+ <para>Unfortunately, because this is a system-wide setting, it is
+ not possible to talk to a normal PPPoE client or server and a
+ &tm.3com; <trademark class="registered">HomeConnect</trademark> ADSL Modem at the same time.</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="pppoa">
+ <title>Using <application>PPP</application> over ATM (PPPoA)</title>
+ <indexterm><primary>PPP</primary><secondary>over ATM</secondary></indexterm>
+ <indexterm>
+ <primary>PPPoA</primary>
+ <see>PPP, over ATM</see>
+ </indexterm>
+
+ <para>The following describes how to set up PPP over ATM (PPPoA).
+ PPPoA is a popular choice among European DSL providers.</para>
+
+ <sect2>
+ <title>Using PPPoA with the Alcatel &speedtouch; USB</title>
+
+ <para>PPPoA support for this device is supplied as a port in
+ FreeBSD because the firmware is distributed under <link xlink:href="http://www.speedtouchdsl.com/disclaimer_lx.htm">Alcatel's
+ license agreement</link> and can not be redistributed freely
+ with the base system of FreeBSD.</para>
+
+ <para>To install the software, simply use the <link linkend="ports">Ports Collection</link>. Install the
+ <package>net/pppoa</package> port and follow the
+ instructions provided with it.</para>
+
+ <para>Like many USB devices, the Alcatel &speedtouch; USB needs to
+ download firmware from the host computer to operate properly.
+ It is possible to automate this process in &os; so that this
+ transfer takes place whenever the device is plugged into a USB
+ port. The following information can be added to the
+ <filename>/etc/usbd.conf</filename> file to enable this
+ automatic firmware transfer. This file must be edited as the
+ <systemitem class="username">root</systemitem> user.</para>
+
+ <programlisting>device "Alcatel SpeedTouch USB"
+ devname "ugen[0-9]+"
+ vendor 0x06b9
+ product 0x4061
+ attach "/usr/local/sbin/modem_run -f /usr/local/libdata/mgmt.o"</programlisting>
+
+ <para>To enable the USB daemon, <application>usbd</application>,
+ put the following the line into
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>usbd_enable="YES"</programlisting>
+
+ <para>It is also possible to set up
+ <application>ppp</application> to dial up at startup. To do
+ this add the following lines to
+ <filename>/etc/rc.conf</filename>. Again, for this procedure
+ you will need to be logged in as the <systemitem class="username">root</systemitem>
+ user.</para>
+
+ <programlisting>ppp_enable="YES"
+ppp_mode="ddial"
+ppp_profile="adsl"</programlisting>
+
+ <para>For this to work correctly you will need to have used the
+ sample <filename>ppp.conf</filename> which is supplied with the
+ <package>net/pppoa</package> port.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>Using mpd</title>
+
+ <para>You can use <application>mpd</application> to connect to a
+ variety of services, in particular PPTP services. You can find
+ <application>mpd</application> in the Ports Collection,
+ <package>net/mpd</package>. Many ADSL modems
+ require that a PPTP tunnel is created between the modem and
+ computer, one such modem is the Alcatel &speedtouch;
+ Home.</para>
+
+ <para>First you must install the port, and then you can
+ configure <application>mpd</application> to suit your
+ requirements and provider settings. The port places a set of
+ sample configuration files which are well documented in
+ <filename>PREFIX/etc/mpd/</filename>.
+ Note here that <replaceable>PREFIX</replaceable> means the directory
+ into which your ports are installed, this defaults to
+ <filename>/usr/local/</filename>. A complete guide to
+ configure <application>mpd</application> is available in
+ HTML format once the port has been installed. It is placed in
+ <filename>PREFIX/share/doc/mpd/</filename>.
+ Here is a sample configuration for connecting to an ADSL
+ service with <application>mpd</application>. The configuration
+ is spread over two files, first the
+ <filename>mpd.conf</filename>:</para>
+
+ <programlisting>default:
+ load adsl
+
+adsl:
+ new -i ng0 adsl adsl
+ set bundle authname <replaceable>username</replaceable> <co xml:id="co-mpd-ex-user"/>
+ set bundle password <replaceable>password</replaceable> <co xml:id="co-mpd-ex-pass"/>
+ set bundle disable multilink
+
+ set link no pap acfcomp protocomp
+ set link disable chap
+ set link accept chap
+ set link keep-alive 30 10
+
+ set ipcp no vjcomp
+ set ipcp ranges 0.0.0.0/0 0.0.0.0/0
+
+ set iface route default
+ set iface disable on-demand
+ set iface enable proxy-arp
+ set iface idle 0
+
+ open</programlisting>
+
+ <calloutlist>
+ <callout arearefs="co-mpd-ex-user">
+ <para>The username used to authenticate with your ISP.</para>
+ </callout>
+ <callout arearefs="co-mpd-ex-pass">
+ <para>The password used to authenticate with your ISP.</para>
+ </callout>
+ </calloutlist>
+
+ <para>The <filename>mpd.links</filename> file contains information about
+ the link, or links, you wish to establish. An example
+ <filename>mpd.links</filename> to accompany the above example is given
+ beneath:</para>
+
+ <programlisting>adsl:
+ set link type pptp
+ set pptp mode active
+ set pptp enable originate outcall
+ set pptp self <replaceable>10.0.0.1</replaceable> <co xml:id="co-mpd-ex-self"/>
+ set pptp peer <replaceable>10.0.0.138</replaceable> <co xml:id="co-mpd-ex-peer"/></programlisting>
+
+ <calloutlist>
+ <callout arearefs="co-mpd-ex-self">
+ <para>The IP address of your &os; computer which you will be
+ using <application>mpd</application> from.</para>
+ </callout>
+ <callout arearefs="co-mpd-ex-peer">
+ <para>The IP address of your ADSL modem. For the Alcatel
+ &speedtouch; Home this address defaults to <systemitem class="ipaddress">10.0.0.138</systemitem>.</para>
+ </callout>
+ </calloutlist>
+
+ <para>It is possible to initialize the connection easily by issuing the
+ following command as <systemitem class="username">root</systemitem>:</para>
+
+ <screen>&prompt.root; <userinput>mpd -b adsl</userinput></screen>
+
+ <para>You can see the status of the connection with the following
+ command:</para>
+
+ <screen>&prompt.user; <userinput>ifconfig ng0</userinput>
+ng0: flags=88d1&lt;UP,POINTOPOINT,RUNNING,NOARP,SIMPLEX,MULTICAST&gt; mtu 1500
+ inet 216.136.204.117 --&gt; 204.152.186.171 netmask 0xffffffff</screen>
+
+ <para>Using <application>mpd</application> is the recommended way to
+ connect to an ADSL service with &os;.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>Using pptpclient</title>
+
+ <para>It is also possible to use FreeBSD to connect to other PPPoA
+ services using
+ <package>net/pptpclient</package>.</para>
+
+ <para>To use <package>net/pptpclient</package> to
+ connect to a DSL service, install the port or package and edit your
+ <filename>/etc/ppp/ppp.conf</filename>. You will need to be
+ <systemitem class="username">root</systemitem> to perform both of these operations. An
+ example section of <filename>ppp.conf</filename> is given
+ below. For further information on <filename>ppp.conf</filename>
+ options consult the <application>ppp</application> manual page,
+ &man.ppp.8;.</para>
+
+ <programlisting>adsl:
+ set log phase chat lcp ipcp ccp tun command
+ set timeout 0
+ enable dns
+ set authname <replaceable>username</replaceable> <co xml:id="co-pptp-ex-user"/>
+ set authkey <replaceable>password</replaceable> <co xml:id="co-pptp-ex-pass"/>
+ set ifaddr 0 0
+ add default HISADDR</programlisting>
+
+ <calloutlist>
+ <callout arearefs="co-pptp-ex-user">
+ <para>The username of your account with the DSL provider.</para>
+ </callout>
+ <callout arearefs="co-pptp-ex-pass">
+ <para>The password for your account.</para>
+ </callout>
+ </calloutlist>
+
+ <warning>
+ <para>Because you must put your account's password in the
+ <filename>ppp.conf</filename> file in plain text form you should
+ make sure than nobody can read the contents of this file. The
+ following series of commands will make sure the file is only
+ readable by the <systemitem class="username">root</systemitem> account. Refer to the
+ manual pages for &man.chmod.1; and &man.chown.8; for further
+ information.</para>
+ <screen>&prompt.root; <userinput>chown root:wheel /etc/ppp/ppp.conf</userinput>
+&prompt.root; <userinput>chmod 600 /etc/ppp/ppp.conf</userinput></screen>
+ </warning>
+
+ <para>This will open a tunnel for a PPP session to your DSL router.
+ Ethernet DSL modems have a preconfigured LAN IP address which you
+ connect to. In the case of the Alcatel &speedtouch; Home this address is
+ <systemitem class="ipaddress">10.0.0.138</systemitem>. Your router documentation
+ should tell you which address your device uses. To open the tunnel and
+ start a PPP session execute the following
+ command:</para>
+
+ <screen>&prompt.root; <userinput>pptp address adsl</userinput></screen>
+
+ <tip>
+ <para>You may wish to add an ampersand (<quote>&amp;</quote>) to the
+ end of the previous command because <application>pptp</application>
+ will not return your prompt to you otherwise.</para>
+ </tip>
+
+ <para>A <filename>tun</filename> virtual tunnel device will be
+ created for interaction between the <application>pptp</application>
+ and <application>ppp</application> processes. Once you have been
+ returned to your prompt, or the <application>pptp</application>
+ process has confirmed a connection you can examine the tunnel like
+ so:</para>
+
+ <screen>&prompt.user; <userinput>ifconfig tun0</userinput>
+tun0: flags=8051&lt;UP,POINTOPOINT,RUNNING,MULTICAST&gt; mtu 1500
+ inet 216.136.204.21 --&gt; 204.152.186.171 netmask 0xffffff00
+ Opened by PID 918</screen>
+
+ <para>If you are unable to connect, check the configuration of
+ your router, which is usually accessible via
+ <application>telnet</application> or with a web browser. If you still
+ cannot connect you should examine the output of the
+ <command>pptp</command> command and the contents of the
+ <application>ppp</application> log file,
+ <filename>/var/log/ppp.log</filename> for clues.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="slip">
+ <info><title>Using SLIP</title>
+ <authorgroup>
+ <author><personname><firstname>Satoshi</firstname><surname>Asami</surname></personname><contrib>Originally contributed by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Guy</firstname><surname>Helmer</surname></personname><contrib>With input from </contrib></author>
+ <author><personname><firstname>Piero</firstname><surname>Serini</surname></personname></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>SLIP</primary></indexterm>
+
+ <sect2 xml:id="slipc">
+ <title>Setting Up a SLIP Client</title>
+ <indexterm><primary>SLIP</primary><secondary>client</secondary></indexterm>
+ <para>The following is one way to set up a FreeBSD machine for SLIP
+ on a static host network. For dynamic hostname assignments (your
+ address changes each time you dial up), you probably need to
+ have a more complex setup.</para>
+
+ <para>First, determine which serial port your modem is connected to.
+ Many people set up a symbolic link, such as
+ <filename>/dev/modem</filename>, to point to the real device name,
+ <filename>/dev/cuaaN</filename> (or <filename>/dev/cuadN</filename> under &os;&nbsp;6.X). This allows you to
+ abstract the actual device name should you ever need to move
+ the modem to a different port. It can become quite cumbersome when you
+ need to fix a bunch of files in <filename>/etc</filename> and
+ <filename>.kermrc</filename> files all over the system!</para>
+
+ <note>
+ <para><filename>/dev/cuaa0</filename> (or <filename>/dev/cuad0</filename> under &os;&nbsp;6.X) is
+ <filename>COM1</filename>, <filename>cuaa1</filename> (or <filename>/dev/cuad1</filename>) is
+ <filename>COM2</filename>, etc.</para>
+ </note>
+
+ <para>Make sure you have the following in your kernel configuration
+ file:</para>
+
+ <programlisting>device sl</programlisting>
+
+ <para>Under &os;&nbsp;4.X, use instead the following
+ line:</para>
+
+ <programlisting>pseudo-device sl 1</programlisting>
+
+ <para>It is included in the <filename>GENERIC</filename> kernel, so
+ this should not be a problem unless you have deleted it.</para>
+
+ <sect3>
+ <title>Things You Have to Do Only Once</title>
+
+ <procedure>
+ <step>
+ <para>Add your home machine, the gateway and nameservers to
+ your <filename>/etc/hosts</filename> file. Ours looks like
+ this:</para>
+
+ <programlisting>127.0.0.1 localhost loghost
+136.152.64.181 water.CS.Example.EDU water.CS water
+136.152.64.1 inr-3.CS.Example.EDU inr-3 slip-gateway
+128.32.136.9 ns1.Example.EDU ns1
+128.32.136.12 ns2.Example.EDU ns2</programlisting>
+ </step>
+
+ <step>
+ <para>Make sure you have <literal>hosts</literal> before
+ <literal>bind</literal> in your
+ <filename>/etc/host.conf</filename> on FreeBSD versions
+ prior to 5.0. Since FreeBSD&nbsp;5.0, the system uses
+ the file <filename>/etc/nsswitch.conf</filename> instead,
+ make sure you have <literal>files</literal> before
+ <literal>dns</literal> in the <option>hosts</option> line
+ of this file. Without these parameters funny
+ things may happen.</para>
+ </step>
+
+ <step>
+ <para>Edit the <filename>/etc/rc.conf</filename> file.</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Set your hostname by editing the line that
+ says:</para>
+
+ <programlisting>hostname="myname.my.domain"</programlisting>
+
+ <para>Your machine's full Internet hostname should be
+ placed here.</para>
+ </listitem>
+
+ <listitem>
+ <indexterm><primary>default route</primary></indexterm>
+
+ <para>Designate the default router<indexterm><primary>default route</primary></indexterm> by changing the
+ line:</para>
+
+ <programlisting>defaultrouter="NO"</programlisting>
+
+ <para>to:</para>
+
+ <programlisting>defaultrouter="slip-gateway"</programlisting>
+ </listitem>
+ </orderedlist>
+ </step>
+
+ <step>
+ <para>Make a file <filename>/etc/resolv.conf</filename> which
+ contains:</para>
+
+ <programlisting>domain CS.Example.EDU
+nameserver 128.32.136.9
+nameserver 128.32.136.12</programlisting>
+
+ <indexterm><primary>nameserver</primary></indexterm>
+ <indexterm><primary>domain name</primary></indexterm>
+ <para>As you can see, these set up the nameserver hosts. Of
+ course, the actual domain names and addresses depend on your
+ environment.</para>
+ </step>
+
+ <step>
+ <para>Set the password for <systemitem class="username">root</systemitem> and
+ <systemitem class="username">toor</systemitem> (and any other
+ accounts that do not have a password).</para>
+ </step>
+
+ <step>
+ <para>Reboot your machine and make sure it comes up with the
+ correct hostname.</para>
+ </step>
+ </procedure>
+ </sect3>
+
+ <sect3>
+ <title>Making a SLIP Connection</title>
+ <indexterm><primary>SLIP</primary><secondary>connecting with</secondary></indexterm>
+ <procedure>
+ <step>
+ <para>Dial up, type <command>slip</command> at the prompt,
+ enter your machine name and password. What is required to
+ be entered depends on your environment. If you use
+ <application>Kermit</application>, you can try a script like this:</para>
+
+ <programlisting># kermit setup
+set modem hayes
+set line /dev/modem
+set speed 115200
+set parity none
+set flow rts/cts
+set terminal bytesize 8
+set file type binary
+# The next macro will dial up and login
+define slip dial 643-9600, input 10 =&gt;, if failure stop, -
+output slip\x0d, input 10 Username:, if failure stop, -
+output silvia\x0d, input 10 Password:, if failure stop, -
+output ***\x0d, echo \x0aCONNECTED\x0a</programlisting>
+
+ <para>Of course, you have to change the username and password
+ to fit yours. After doing so, you can just type
+ <command>slip</command> from the <application>Kermit</application> prompt to
+ connect.</para>
+
+ <note>
+ <para>Leaving your password in plain text anywhere in the
+ filesystem is generally a <emphasis>bad</emphasis> idea.
+ Do it at your own risk.</para>
+ </note>
+ </step>
+
+ <step>
+ <para>Leave the <application>Kermit</application> there (you can suspend it by
+ <keycombo>
+ <keycap>Ctrl</keycap>
+ <keycap>z</keycap>
+ </keycombo>) and as <systemitem class="username">root</systemitem>, type:</para>
+
+ <screen>&prompt.root; <userinput>slattach -h -c -s 115200 /dev/modem</userinput></screen>
+
+ <para>If you are able to <command>ping</command> hosts on the
+ other side of the router, you are connected! If it does not
+ work, you might want to try <option>-a</option> instead of
+ <option>-c</option> as an argument to
+ <command>slattach</command>.</para>
+ </step>
+ </procedure>
+ </sect3>
+
+ <sect3>
+ <title>How to Shutdown the Connection</title>
+
+ <para>Do the following:</para>
+
+ <screen>&prompt.root; <userinput>kill -INT `cat /var/run/slattach.modem.pid`</userinput></screen>
+
+ <para>to kill <command>slattach</command>. Keep in mind you must be
+ <systemitem class="username">root</systemitem> to do the above. Then go back to
+ <command>kermit</command> (by running <command>fg</command> if you suspended it) and
+ exit from
+ it (<keycap>q</keycap>).</para>
+
+ <para>The &man.slattach.8; manual page says you have
+ to use <command>ifconfig sl0 down</command>
+ to mark the interface down, but this does not
+ seem to make any difference.
+ (<command>ifconfig sl0</command> reports the same thing.)</para>
+
+ <para>Some times, your modem might refuse to drop the carrier.
+ In that case, simply start <command>kermit</command> and quit
+ it again. It usually goes out on the second try.</para>
+ </sect3>
+
+ <sect3>
+ <title>Troubleshooting</title>
+
+ <para>If it does not work, feel free to ask on &a.net.name; mailing list. The things that
+ people tripped over so far:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Not using <option>-c</option> or <option>-a</option> in
+ <command>slattach</command> (This should not be fatal,
+ but some users have reported that this solves their
+ problems.)</para>
+ </listitem>
+
+ <listitem>
+ <para>Using <option>s10</option> instead of
+ <option>sl0</option> (might be hard to see the difference on
+ some fonts).</para>
+ </listitem>
+
+ <listitem>
+ <para>Try <command>ifconfig sl0</command> to see your
+ interface status. For example, you might get:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig sl0</userinput>
+sl0: flags=10&lt;POINTOPOINT&gt;
+ inet 136.152.64.181 --&gt; 136.152.64.1 netmask ffffff00</screen>
+ </listitem>
+
+ <listitem>
+ <para>If you get <errorname>no route to host</errorname>
+ messages from &man.ping.8;, there may be a problem with your
+ routing table. You can use the <command>netstat -r</command>
+ command to display the current routes :</para>
+
+ <screen>&prompt.root; <userinput>netstat -r</userinput>
+Routing tables
+Destination Gateway Flags Refs Use IfaceMTU Rtt Netmasks:
+
+(root node)
+(root node)
+
+Route Tree for Protocol Family inet:
+(root node) =&gt;
+default inr-3.Example.EDU UG 8 224515 sl0 - -
+localhost.Exampl localhost.Example. UH 5 42127 lo0 - 0.438
+inr-3.Example.ED water.CS.Example.E UH 1 0 sl0 - -
+water.CS.Example localhost.Example. UGH 34 47641234 lo0 - 0.438
+(root node)</screen>
+
+ <para>The preceding examples are from a relatively busy system.
+ The numbers on your system will vary depending on
+ network activity.</para>
+
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="slips">
+ <title>Setting Up a SLIP Server</title>
+ <indexterm><primary>SLIP</primary><secondary>server</secondary></indexterm>
+
+ <para>This document provides suggestions for setting up SLIP Server
+ services on a FreeBSD system, which typically means configuring
+ your system to automatically startup connections upon login for
+ remote SLIP clients.</para>
+
+ <!-- Disclaimer is not necessarily relevant
+ <para> The author has written this document based
+ on his experience; however, as your system and needs may be
+ different, this document may not answer all of your questions, and
+ the author cannot be responsible if you damage your system or lose
+ data due to attempting to follow the suggestions here.</para>
+ -->
+
+ <sect3 xml:id="slips-prereqs">
+ <title>Prerequisites</title>
+ <indexterm><primary>TCP/IP networking</primary></indexterm>
+ <para>This section is very technical in nature, so background
+ knowledge is required. It is assumed that you are familiar with
+ the TCP/IP network protocol, and in particular, network and node
+ addressing, network address masks, subnetting, routing, and
+ routing protocols, such as RIP. Configuring SLIP services on a
+ dial-up server requires a knowledge of these concepts, and if
+ you are not familiar with them, please read a copy of either
+ Craig Hunt's <emphasis>TCP/IP Network Administration</emphasis>
+ published by O'Reilly &amp; Associates, Inc. (ISBN Number
+ 0-937175-82-X), or Douglas Comer's books on the TCP/IP
+ protocol.</para>
+
+ <indexterm><primary>modem</primary></indexterm>
+ <para>It is further assumed that you have already set up your
+ modem(s) and configured the appropriate system files to allow
+ logins through your modems. If you have not prepared your
+ system for this yet, please see <xref linkend="dialup"/> for details on dialup services
+ configuration.
+ You may also want to check the manual pages for &man.sio.4; for
+ information on the serial port device driver and &man.ttys.5;,
+ &man.gettytab.5;, &man.getty.8;, &amp; &man.init.8; for
+ information relevant to configuring the system to accept logins
+ on modems, and perhaps &man.stty.1; for information on setting
+ serial port parameters (such as <literal>clocal</literal> for
+ directly-connected serial interfaces).</para>
+ </sect3>
+
+ <sect3>
+ <title>Quick Overview</title>
+
+ <para>In its typical configuration, using FreeBSD as a SLIP server
+ works as follows: a SLIP user dials up your FreeBSD SLIP Server
+ system and logs in with a special SLIP login ID that uses
+ <filename>/usr/sbin/sliplogin</filename> as the special user's
+ shell. The <command>sliplogin</command> program browses the
+ file <filename>/etc/sliphome/slip.hosts</filename> to find a
+ matching line for the special user, and if it finds a match,
+ connects the serial line to an available SLIP interface and then
+ runs the shell script
+ <filename>/etc/sliphome/slip.login</filename> to configure the
+ SLIP interface.</para>
+
+ <sect4>
+ <title>An Example of a SLIP Server Login</title>
+
+ <para>For example, if a SLIP user ID were
+ <systemitem class="username">Shelmerg</systemitem>, <systemitem class="username">Shelmerg</systemitem>'s
+ entry in <filename>/etc/master.passwd</filename> would look
+ something like this:</para>
+
+ <programlisting>Shelmerg:password:1964:89::0:0:Guy Helmer - SLIP:/usr/users/Shelmerg:/usr/sbin/sliplogin</programlisting>
+
+ <para>When <systemitem class="username">Shelmerg</systemitem> logs in,
+ <command>sliplogin</command> will search
+ <filename>/etc/sliphome/slip.hosts</filename> for a line that
+ had a matching user ID; for example, there may be a line in
+ <filename>/etc/sliphome/slip.hosts</filename> that
+ reads:</para>
+
+ <programlisting>Shelmerg dc-slip sl-helmer 0xfffffc00 autocomp</programlisting>
+
+ <para><command>sliplogin</command> will find that matching line,
+ hook the serial line into the next available SLIP interface,
+ and then execute <filename>/etc/sliphome/slip.login</filename>
+ like this:</para>
+
+ <programlisting>/etc/sliphome/slip.login 0 19200 Shelmerg dc-slip sl-helmer 0xfffffc00 autocomp</programlisting>
+
+ <para>If all goes well,
+ <filename>/etc/sliphome/slip.login</filename> will issue an
+ <command>ifconfig</command> for the SLIP interface to which
+ <command>sliplogin</command> attached itself (SLIP interface
+ 0, in the above example, which was the first parameter in the
+ list given to <filename>slip.login</filename>) to set the
+ local IP address (<systemitem>dc-slip</systemitem>), remote IP address
+ (<systemitem>sl-helmer</systemitem>), network mask for the SLIP
+ interface (<systemitem class="netmask">0xfffffc00</systemitem>), and
+ any additional flags (<literal>autocomp</literal>). If
+ something goes wrong, <command>sliplogin</command> usually
+ logs good informational messages via the
+ <application>syslogd</application> daemon facility, which usually logs
+ to <filename>/var/log/messages</filename> (see the manual
+ pages for &man.syslogd.8; and &man.syslog.conf.5; and perhaps
+ check <filename>/etc/syslog.conf</filename> to see to what
+ <application>syslogd</application> is logging and where it is
+ logging to).</para>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>Kernel Configuration</title>
+ <indexterm><primary>kernel</primary><secondary>configuration</secondary></indexterm>
+ <indexterm><primary>SLIP</primary></indexterm>
+
+ <para>&os;'s default kernel (<filename>GENERIC</filename>)
+ comes with SLIP (&man.sl.4;) support; in case of a custom
+ kernel, you have to add the following line to your kernel
+ configuration file:</para>
+
+ <programlisting>device sl</programlisting>
+
+ <para>Under &os;&nbsp;4.X, use instead the following
+ line:</para>
+
+ <programlisting>pseudo-device sl 2</programlisting>
+
+ <note>
+ <para>The number at the end of the line is the maximum
+ number of SLIP connections that may be operating
+ simultaneously. Since &os;&nbsp;5.0, the &man.sl.4;
+ driver is <quote>auto-cloning</quote>.</para>
+ </note>
+
+ <para>By default, your &os; machine will not forward packets.
+ If you want your FreeBSD SLIP Server to act as a router, you
+ will have to edit the <filename>/etc/rc.conf</filename> file and
+ change the setting of the <literal>gateway_enable</literal> variable to
+ <option>YES</option>.</para>
+
+ <para>You will then need to reboot for the new settings to take
+ effect.</para>
+
+ <para>Please refer to <xref linkend="kernelconfig"/> on
+ Configuring the FreeBSD Kernel for help in
+ reconfiguring your kernel.</para>
+ </sect3>
+
+ <sect3>
+ <title>Sliplogin Configuration</title>
+
+ <para>As mentioned earlier, there are three files in the
+ <filename>/etc/sliphome</filename> directory that are part of
+ the configuration for <filename>/usr/sbin/sliplogin</filename>
+ (see &man.sliplogin.8; for the actual manual page for
+ <command>sliplogin</command>): <filename>slip.hosts</filename>,
+ which defines the SLIP users and their associated IP
+ addresses; <filename>slip.login</filename>, which usually just
+ configures the SLIP interface; and (optionally)
+ <filename>slip.logout</filename>, which undoes
+ <filename>slip.login</filename>'s effects when the serial
+ connection is terminated.</para>
+
+ <sect4>
+ <title><filename>slip.hosts</filename> Configuration</title>
+
+ <para><filename>/etc/sliphome/slip.hosts</filename> contains
+ lines which have at least four items separated by
+ whitespace:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>SLIP user's login ID</para>
+ </listitem>
+
+ <listitem>
+ <para>Local address (local to the SLIP server) of the SLIP
+ link</para>
+ </listitem>
+
+ <listitem>
+ <para>Remote address of the SLIP link</para>
+ </listitem>
+
+ <listitem>
+ <para>Network mask</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The local and remote addresses may be host names
+ (resolved to IP addresses by
+ <filename>/etc/hosts</filename> or by the domain name
+ service, depending on your specifications in the file
+ <filename>/etc/nsswitch.conf</filename>,
+ or in <filename>/etc/host.conf</filename>
+ if you use FreeBSD&nbsp;4.X), and the network mask may be
+ a name that can be resolved by a lookup into
+ <filename>/etc/networks</filename>. On a sample system,
+ <filename>/etc/sliphome/slip.hosts</filename> looks like
+ this:</para>
+
+ <programlisting>#
+# login local-addr remote-addr mask opt1 opt2
+# (normal,compress,noicmp)
+#
+Shelmerg dc-slip sl-helmerg 0xfffffc00 autocomp</programlisting>
+
+ <para>At the end of the line is one or more of the
+ options:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><option>normal</option> &mdash; no header
+ compression</para>
+ </listitem>
+
+ <listitem>
+ <para><option>compress</option> &mdash; compress
+ headers</para>
+ </listitem>
+
+ <listitem>
+ <para><option>autocomp</option> &mdash; compress headers if
+ the remote end allows it</para>
+ </listitem>
+
+ <listitem>
+ <para><option>noicmp</option> &mdash; disable ICMP packets
+ (so any <quote>ping</quote> packets will be dropped instead
+ of using up your bandwidth)</para>
+ </listitem>
+ </itemizedlist>
+
+ <indexterm><primary>SLIP</primary></indexterm>
+ <indexterm><primary>TCP/IP networking</primary></indexterm>
+ <para>Your choice of local and remote addresses for your SLIP
+ links depends on whether you are going to dedicate a TCP/IP
+ subnet or if you are going to use <quote>proxy ARP</quote> on
+ your SLIP server (it is not <quote>true</quote> proxy ARP, but
+ that is the terminology used in this section to describe it).
+ If you are not sure which method to select or how to assign IP
+ addresses, please refer to the TCP/IP books referenced in
+ the SLIP Prerequisites (<xref linkend="slips-prereqs"/>)
+ and/or consult your IP network manager.</para>
+
+ <para>If you are going to use a separate subnet for your SLIP
+ clients, you will need to allocate the subnet number out of
+ your assigned IP network number and assign each of your SLIP
+ client's IP numbers out of that subnet. Then, you will
+ probably need to configure a static route to the SLIP
+ subnet via your SLIP server on your nearest IP router.</para>
+
+ <indexterm><primary>Ethernet</primary></indexterm>
+ <para>Otherwise, if you will use the <quote>proxy ARP</quote>
+ method, you will need to assign your SLIP client's IP
+ addresses out of your SLIP server's Ethernet subnet, and you
+ will also need to adjust your
+ <filename>/etc/sliphome/slip.login</filename> and
+ <filename>/etc/sliphome/slip.logout</filename> scripts to use
+ &man.arp.8; to manage the proxy-ARP entries in the SLIP
+ server's ARP table.</para>
+ </sect4>
+
+ <sect4>
+ <title><filename>slip.login</filename> Configuration</title>
+
+ <para>The typical <filename>/etc/sliphome/slip.login</filename>
+ file looks like this:</para>
+
+ <programlisting>#!/bin/sh -
+#
+# @(#)slip.login 5.1 (Berkeley) 7/1/90
+
+#
+# generic login file for a slip line. sliplogin invokes this with
+# the parameters:
+# 1 2 3 4 5 6 7-n
+# slipunit ttyspeed loginname local-addr remote-addr mask opt-args
+#
+/sbin/ifconfig sl$1 inet $4 $5 netmask $6</programlisting>
+
+ <para>This <filename>slip.login</filename> file merely runs
+ <command>ifconfig</command> for the appropriate SLIP interface
+ with the local and remote addresses and network mask of the
+ SLIP interface.</para>
+
+ <para>If you have decided to use the <quote>proxy ARP</quote>
+ method (instead of using a separate subnet for your SLIP
+ clients), your <filename>/etc/sliphome/slip.login</filename>
+ file will need to look something like this:</para>
+
+ <programlisting>#!/bin/sh -
+#
+# @(#)slip.login 5.1 (Berkeley) 7/1/90
+
+#
+# generic login file for a slip line. sliplogin invokes this with
+# the parameters:
+# 1 2 3 4 5 6 7-n
+# slipunit ttyspeed loginname local-addr remote-addr mask opt-args
+#
+/sbin/ifconfig sl$1 inet $4 $5 netmask $6
+# Answer ARP requests for the SLIP client with our Ethernet addr
+/usr/sbin/arp -s $5 00:11:22:33:44:55 pub</programlisting>
+
+ <para>The additional line in this
+ <filename>slip.login</filename>, <command>arp -s
+ &#36;5 00:11:22:33:44:55 pub</command>, creates an ARP entry
+ in the SLIP server's ARP table. This ARP entry causes the
+ SLIP server to respond with the SLIP server's Ethernet MAC
+ address whenever another IP node on the Ethernet asks to
+ speak to the SLIP client's IP address.</para>
+
+ <indexterm><primary>Ethernet</primary><secondary>MAC address</secondary></indexterm>
+ <para>When using the example above, be sure to replace the
+ Ethernet MAC address (<systemitem class="etheraddress">00:11:22:33:44:55</systemitem>) with the MAC address of
+ your system's Ethernet card, or your <quote>proxy ARP</quote>
+ will definitely not work! You can discover your SLIP server's
+ Ethernet MAC address by looking at the results of running
+ <command>netstat -i</command>; the second line of the output
+ should look something like:</para>
+
+ <screen>ed0 1500 &lt;Link&gt;0.2.c1.28.5f.4a 191923 0 129457 0 116</screen>
+
+ <para>This indicates that this particular system's Ethernet MAC
+ address is <systemitem class="etheraddress">00:02:c1:28:5f:4a</systemitem>
+ &mdash; the periods in the Ethernet MAC address given by
+ <command>netstat -i</command> must be changed to colons and
+ leading zeros should be added to each single-digit hexadecimal
+ number to convert the address into the form that &man.arp.8;
+ desires; see the manual page on &man.arp.8; for complete
+ information on usage.</para>
+
+ <note>
+ <para>When you create
+ <filename>/etc/sliphome/slip.login</filename> and
+ <filename>/etc/sliphome/slip.logout</filename>, the
+ <quote>execute</quote> bit (i.e., <command>chmod 755
+ /etc/sliphome/slip.login /etc/sliphome/slip.logout</command>)
+ must be set, or <command>sliplogin</command> will be unable
+ to execute it.</para>
+ </note>
+ </sect4>
+
+ <sect4>
+ <title><filename>slip.logout</filename> Configuration</title>
+
+ <para><filename>/etc/sliphome/slip.logout</filename> is not
+ strictly needed (unless you are implementing <quote>proxy
+ ARP</quote>), but if you decide to create it, this is an
+ example of a basic
+ <filename>slip.logout</filename> script:</para>
+
+ <programlisting>#!/bin/sh -
+#
+# slip.logout
+
+#
+# logout file for a slip line. sliplogin invokes this with
+# the parameters:
+# 1 2 3 4 5 6 7-n
+# slipunit ttyspeed loginname local-addr remote-addr mask opt-args
+#
+/sbin/ifconfig sl$1 down</programlisting>
+
+ <para>If you are using <quote>proxy ARP</quote>, you will want to
+ have <filename>/etc/sliphome/slip.logout</filename> remove the
+ ARP entry for the SLIP client:</para>
+
+ <programlisting>#!/bin/sh -
+#
+# @(#)slip.logout
+
+#
+# logout file for a slip line. sliplogin invokes this with
+# the parameters:
+# 1 2 3 4 5 6 7-n
+# slipunit ttyspeed loginname local-addr remote-addr mask opt-args
+#
+/sbin/ifconfig sl$1 down
+# Quit answering ARP requests for the SLIP client
+/usr/sbin/arp -d $5</programlisting>
+
+ <para>The <command>arp -d &#36;5</command> removes the ARP entry
+ that the <quote>proxy ARP</quote>
+ <filename>slip.login</filename> added when the SLIP client
+ logged in.</para>
+
+ <para>It bears repeating: make sure
+ <filename>/etc/sliphome/slip.logout</filename> has the execute
+ bit set after you create it (i.e., <command>chmod 755
+ /etc/sliphome/slip.logout</command>).</para>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>Routing Considerations</title>
+ <indexterm>
+ <primary>SLIP</primary>
+ <secondary>routing</secondary>
+ </indexterm>
+ <para>If you are not using the <quote>proxy ARP</quote> method for
+ routing packets between your SLIP clients and the rest of your
+ network (and perhaps the Internet), you will probably
+ have to add static routes to your closest default router(s) to
+ route your SLIP clients subnet via your SLIP server.</para>
+
+ <sect4>
+ <title>Static Routes</title>
+ <indexterm><primary>static routes</primary></indexterm>
+
+ <para>Adding static routes to your nearest default routers
+ can be troublesome (or impossible if you do not have
+ authority to do so...). If you have a multiple-router
+ network in your organization, some routers, such as those
+ made by Cisco and Proteon, may not only need to be
+ configured with the static route to the SLIP subnet, but
+ also need to be told which static routes to tell other
+ routers about, so some expertise and
+ troubleshooting/tweaking may be necessary to get
+ static-route-based routing to work.</para>
+ </sect4>
+
+ <sect4>
+ <title>Running <application>&gated;</application></title>
+ <indexterm>
+ <primary><application>&gated;</application></primary>
+ </indexterm>
+
+ <note>
+ <para><application>&gated;</application> is proprietary software now and
+ will not be available as source code to the public anymore
+ (more info on the <link xlink:href="http://www.gated.org/">&gated;</link> website). This
+ section only exists to ensure backwards compatibility for
+ those that are still using an older version.</para>
+ </note>
+
+ <para>An alternative to the headaches of static routes is to
+ install <application>&gated;</application> on your FreeBSD SLIP server
+ and configure it to use the appropriate routing protocols
+ (RIP/OSPF/BGP/EGP) to tell other routers about your SLIP
+ subnet.
+ You will need to write a <filename>/etc/gated.conf</filename>
+ file to configure your <application>&gated;</application>; here is a sample, similar to
+ what the author used on a FreeBSD SLIP server:</para>
+
+ <programlisting>#
+# gated configuration file for dc.dsu.edu; for gated version 3.5alpha5
+# Only broadcast RIP information for xxx.xxx.yy out the ed Ethernet interface
+#
+#
+# tracing options
+#
+traceoptions "/var/tmp/gated.output" replace size 100k files 2 general ;
+
+rip yes {
+ interface sl noripout noripin ;
+ interface ed ripin ripout version 1 ;
+ traceoptions route ;
+} ;
+
+#
+# Turn on a bunch of tracing info for the interface to the kernel:
+kernel {
+ traceoptions remnants request routes info interface ;
+} ;
+
+#
+# Propagate the route to xxx.xxx.yy out the Ethernet interface via RIP
+#
+
+export proto rip interface ed {
+ proto direct {
+ <replaceable>xxx.xxx.yy</replaceable> mask 255.255.252.0 metric 1; # SLIP connections
+ } ;
+} ;
+
+#
+# Accept routes from RIP via ed Ethernet interfaces
+
+import proto rip interface ed {
+ all ;
+} ;</programlisting>
+
+ <indexterm><primary>RIP</primary></indexterm>
+ <para>The above sample <filename>gated.conf</filename> file
+ broadcasts routing information regarding the SLIP subnet
+ <replaceable>xxx.xxx.yy</replaceable> via RIP onto the
+ Ethernet; if you are using a different Ethernet driver than
+ the <filename>ed</filename> driver, you will need to
+ change the references to the <filename>ed</filename>
+ interface appropriately. This sample file also sets up
+ tracing to <filename>/var/tmp/gated.output</filename> for
+ debugging <application>&gated;</application>'s activity; you can
+ certainly turn off the tracing options if
+ <application>&gated;</application> works correctly for you. You will need to
+ change the <replaceable>xxx.xxx.yy</replaceable>'s into the
+ network address of your own SLIP subnet (be sure to change the
+ net mask in the <literal>proto direct</literal> clause as
+ well).</para>
+
+ <para>Once you have installed and configured
+ <application>&gated;</application> on your system, you will need to
+ tell the FreeBSD startup scripts to run
+ <application>&gated;</application> in place of
+ <application>routed</application>. The easiest way to accomplish
+ this is to set the <varname>router</varname> and
+ <varname>router_flags</varname> variables in
+ <filename>/etc/rc.conf</filename>. Please see the manual
+ page for <application>&gated;</application> for information on
+ command-line parameters.</para>
+ </sect4>
+ </sect3>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/preface/preface.xml b/zh_TW.UTF-8/books/handbook/preface/preface.xml
new file mode 100644
index 0000000000..56bdc59069
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/preface/preface.xml
@@ -0,0 +1,510 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ $FreeBSD$
+ Original revision: 1.30
+-->
+<preface xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="book-preface">
+ <title>序</title>
+
+ <bridgehead xml:id="preface-audience" renderas="sect1">給讀者的話</bridgehead>
+
+ <para>若您是第一次接觸 FreeBSD 的新手,可以在本書第一部分找到 FreeBSD 的安裝方法,同時會逐步介紹 &unix;
+ 的基礎概念與一些常用、共通的東西。而閱讀這部分並不難,只需要您有探索的精神和接受新概念。</para>
+
+ <para>讀完這些之後,手冊中的第二部分花很長篇幅介紹的各種廣泛主題,相當值得系統管理者去注意。
+ 在閱讀這些章節的內容時所需要的背景知識,都註釋在該章的大綱裡面,若不熟的話,可在閱讀前先預習一番。</para>
+
+ <para>延伸閱讀方面,可參閱 <xref linkend="bibliography"/>。</para>
+
+ <bridgehead xml:id="preface-changes-from2" renderas="sect1">第三版的主要修訂</bridgehead>
+
+ <para>您目前看到的這本手冊第三版是 FreeBSD 文件計劃的成員歷時兩年完成的心血之作。
+ 新版的主要修訂部分,如下:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><xref linkend="config-tuning"/>, 設定與效能調校(Tuning),該章節針對新內容作更新,比如:
+ ACPI 電源管理、cron、以及其他更多的 kernel tuning 選項說明內容。</para>
+ </listitem>
+
+ <listitem>
+ <para><xref linkend="security"/>, 系統安全篇,該章節增加了虛擬私人網路(VPN)、檔案系統的存取控制(ACL),以及安全公告(Security
+ Advisories)的內容。</para>
+ </listitem>
+
+ <listitem>
+ <para><xref linkend="mac"/>, 集權式存取控制(MAC)是本版所增加的章節。本章介紹:什麼是 MAC 機制?以及如何運用它來使您的 FreeBSD 系統更安全。</para>
+ </listitem>
+
+ <listitem>
+ <para><xref linkend="disks"/>, 儲存設備篇,新增了像是:USB 隨身碟、檔案系統快照(snapshot)、檔案系統配額(quota)
+ 、檔案及網路的備援檔案系統、以及如何對硬碟分割區作加密等詳解。</para>
+ </listitem>
+
+ <listitem>
+ <para><xref linkend="vinum-vinum"/>Vinum是本版所新增的章節。本章介紹:如何運用 Vinum 這種邏輯磁碟(device-independent)
+ ,以及軟體 RAID-0, RAID-1 和 RAID-5 。</para>
+ </listitem>
+
+ <listitem>
+ <para><xref linkend="ppp-and-slip"/>PPP 及 SLIP 一章中增加了故障排除的說明。</para>
+ </listitem>
+
+ <listitem>
+ <para><xref linkend="mail"/>電子郵件一章中新增有關如何使用其它的 MTA 程式、SMTP 認証、UUCP、fecthmail、procmail 的運用以及其它進階專題。</para>
+ </listitem>
+
+ <listitem>
+ <para><xref linkend="network-servers"/>, 網路伺服器篇,是新版中全新的一章。這一章介紹了如何架設 Apache HTTP 伺服器、FTPd,以及用於支援
+ Microsoft Windows client 的 Samba 伺服器。其中有些段落來自原先的<xref linkend="advanced-networking"/>進階網路應用一章。</para>
+ </listitem>
+
+ <listitem>
+ <para><xref linkend="advanced-networking"/>進階網路應用一章新增有關在 FreeBSD 中使用藍芽設備、安裝無線網路以及使用 ATM(Asynchronous Transfer Mode)
+ 網路的介紹。</para>
+ </listitem>
+
+ <listitem>
+ <para>增加了一份詞彙表(Glossary),用以說明全書中出現的術語。</para>
+ </listitem>
+
+ <listitem>
+ <para>重新美編書中所列的圖表。</para>
+ </listitem>
+ </itemizedlist>
+
+ <bridgehead xml:id="preface-changes" renderas="sect1">第二版的主要修訂</bridgehead>
+
+ <para>本手冊的第二版是 FreeBSD 文件計劃的成員歷時兩年完成的心血之作。第二版包含了如下的主要變動︰</para>
+
+<!-- Talk a little about justification and other stylesheet changes? -->
+
+ <itemizedlist>
+ <listitem>
+ <para>增加完整的目錄索引。</para>
+ </listitem>
+ <listitem>
+ <para>所有的 ASCII 圖表均改成圖檔格式的圖表。</para>
+ </listitem>
+ <listitem>
+ <para>每個章節均加入概述,以便快速的瀏覽該章節內容摘要、讀者所欲了解的部分。</para>
+ </listitem>
+ <listitem>
+ <para>內容架構重新組織成三大部分: <quote>開始使用 FreeBSD</quote>, <quote>系統管理</quote>, and
+ <quote>附錄</quote>。</para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="install"/> (<quote>安裝 FreeBSD</quote>) 已經重新改寫,並加入許多說明圖片,
+ 讓第一次接觸 FreeBSD 的人,直接看圖就很清楚明瞭重點(一圖抵千字的效果)。</para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="basics"/>(<quote>&unix; 基礎概念篇</quote>)新增了 processes, daemons
+ 和 signals 的介紹。</para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="ports"/> (<quote>軟體套件管理篇</quote>)新增了介紹如何管理 binary package 套件的資訊。</para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="x11"/> (<quote>X Window 視窗系統篇</quote>) 經過全面改寫,著重於在 &xfree86; 4.X 上的流行 x11-wm,像是:
+ <application>KDE</application> 和 <application>GNOME</application> 。</para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="boot"/> (<quote>FreeBSD 開機流程篇</quote>)更新相關內容。</para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="disks"/> (<quote>儲存設備篇(Storage)</quote>) 分別以兩個章節 <quote>Disks</quote>
+ 與 <quote>Backups</quote> 來撰寫。我們認為這樣子會比單一章節來得容易瞭解。還有關於 RAID(包含硬體、軟體RAID) 的段落也新增上去了。</para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="serialcomms"/>(<quote>Serial 通訊篇</quote>)架構重新改寫,並更新至 FreeBSD 4.X/5.X 的內容。</para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="ppp-and-slip"/> (<quote>PPP 及 SLIP</quote>)有相當程度的更新。</para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="advanced-networking"/>(<quote>進階網路應用篇</quote>)加入許多新內容。</para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="mail"/> (<quote>電子郵件篇</quote>)大量新增了設定 <application>sendmail</application> 的介紹。</para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="linuxemu"/> (<quote>&linux; 相容篇</quote>) 增加許多有關安裝
+ <application>&oracle;</application> 及
+ <application>&sap.r3;</application> 的介紹。</para>
+ </listitem>
+ <listitem>
+ <para>此外,第二版還新加章節,以介紹下列專題:</para>
+ <itemizedlist>
+ <listitem>
+ <para><xref linkend="config-tuning"/>, 設定與效能調校(Tuning)。</para>
+ </listitem>
+ <listitem>
+ <para><xref linkend="multimedia"/>, 多媒體影音娛樂(Multimedia)。</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+
+ <bridgehead xml:id="preface-overview" renderas="sect1">本書架構</bridgehead>
+
+ <para>本書主要分為五大部分,第一部份『開始使用』:介紹 FreeBSD 的安裝、基本操作。
+ 讀者可根據自己的程度,循序或者跳過一些熟悉的主題來閱讀;
+ 第二部分『常用操作』:介紹 FreeBSD 常用功能,這部分可以不按順序來讀。
+ 每章前面都會有概述,概述會描述本章節涵蓋的內容和讀者應該已知的,
+ 這主要是讓讀者可以挑喜歡的章節閱讀;
+ 第三部分『系統管理』:介紹 FreeBSD 老手所感興趣的各種專題部分;
+ 第四部分『網路通訊』:則包括網路和各式 Server 專題;而第五部分『附錄』:是各種有關 FreeBSD 的資源。</para>
+
+ <variablelist>
+
+<!-- Part I - Introduction -->
+
+ <varlistentry>
+ <term><emphasis><xref linkend="introduction"/>, 簡介篇</emphasis></term>
+ <listitem>
+ <para>向新手介紹 FreeBSD。該篇說明了 FreeBSD 計劃的歷史、目標和開發模式。</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="install"/>, 安裝篇</emphasis></term>
+ <listitem>
+ <para>介紹安裝程序。其中還有介紹一些進階的安裝主題,包括像是如何透過 serial console 來安裝。</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="basics"/>, &unix; 基礎概念篇</emphasis></term>
+ <listitem>
+ <para>Covers the basic commands and functionality of the
+ FreeBSD operating system. If you are familiar with &linux; or
+ another flavor of &unix; then you can probably skip this
+ chapter.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="ports"/>, 軟體套件管理篇</emphasis></term>
+ <listitem>
+ <para>Covers the installation of third-party software with
+ both FreeBSD's innovative <quote>Ports Collection</quote> and standard
+ binary packages.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="x11"/>, X Window 視窗系統篇</emphasis></term>
+ <listitem>
+ <para>Describes the X Window System in general and using
+ X11 on FreeBSD in particular. Also describes common
+ desktop environments such as <application>KDE</application> and <application>GNOME</application>.</para>
+ </listitem>
+ </varlistentry>
+
+<!-- Part II Common Tasks -->
+
+ <varlistentry>
+ <term><emphasis><xref linkend="desktop"/>, Desktop Applications</emphasis></term>
+ <listitem>
+ <para>Lists some common desktop applications, such as web browsers
+ and productivity suites, and describes how to install them on
+ FreeBSD.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="multimedia"/>, Multimedia</emphasis></term>
+ <listitem>
+ <para>Shows how to set up sound and video playback support for your
+ system. Also describes some sample audio and video applications.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="kernelconfig"/>, Configuring the FreeBSD
+ Kernel</emphasis></term>
+ <listitem>
+ <para>Explains why you might need to configure a new kernel
+ and provides detailed instructions for configuring, building,
+ and installing a custom kernel.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="printing"/>, 列印篇</emphasis></term>
+ <listitem>
+ <para>Describes managing printers on FreeBSD, including
+ information about banner pages, printer accounting, and
+ initial setup.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="linuxemu"/>, &linux; Binary Compatibility</emphasis></term>
+ <listitem>
+ <para>Describes the &linux; compatibility features of FreeBSD.
+ Also provides detailed installation instructions for many
+ popular &linux; applications such as <application>&oracle;</application>, <application>&sap.r3;</application>, and
+ <application>&mathematica;</application>.</para>
+ </listitem>
+ </varlistentry>
+
+<!-- Part III - System Administration -->
+
+ <varlistentry>
+ <term><emphasis><xref linkend="config-tuning"/>, Configuration and Tuning</emphasis></term>
+ <listitem>
+ <para>Describes the parameters available for system
+ administrators to tune a FreeBSD system for optimum
+ performance. Also describes the various configuration files
+ used in FreeBSD and where to find them.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="boot"/>, Booting Process</emphasis></term>
+ <listitem>
+ <para>Describes the FreeBSD boot process and explains
+ how to control this process with configuration options.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="users"/>, Users and Basic Account
+ Management</emphasis></term>
+ <listitem>
+ <para>Describes the creation and manipulation of user
+ accounts. Also discusses resource limitations that can be
+ set on users and other account management tasks.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="security"/>, Security</emphasis></term>
+ <listitem>
+ <para>Describes many different tools available to help keep your
+ FreeBSD system secure, including Kerberos, IPsec and OpenSSH.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="mac"/>, Mandatory Access Control</emphasis></term>
+ <listitem>
+ <para>Explains what Mandatory Access Control (MAC) is and how this
+ mechanism can be used to secure a FreeBSD system.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="disks"/>, Storage</emphasis></term>
+ <listitem>
+ <para>Describes how to manage storage media and filesystems
+ with FreeBSD. This includes physical disks, RAID arrays,
+ optical and tape media, memory-backed disks, and network
+ filesystems.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="GEOM"/>, GEOM</emphasis></term>
+ <listitem>
+ <para>Describes what the GEOM framework in FreeBSD is and how
+ to configure various supported RAID levels.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="vinum-vinum"/>, Vinum</emphasis></term>
+ <listitem>
+ <para>Describes how to use Vinum, a logical volume manager
+ which provides device-independent logical disks, and
+ software RAID-0, RAID-1 and RAID-5.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="l10n"/>, Localization</emphasis></term>
+ <listitem>
+ <para>Describes how to use FreeBSD in languages other than
+ English. Covers both system and application level
+ localization.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="cutting-edge"/>, The Cutting Edge</emphasis></term>
+ <listitem>
+ <para>Explains the differences between FreeBSD-STABLE,
+ FreeBSD-CURRENT, and FreeBSD releases. Describes which users
+ would benefit from tracking a development system and outlines
+ that process.</para>
+ </listitem>
+ </varlistentry>
+
+<!-- Part IV - Network Communications -->
+
+ <varlistentry>
+ <term><emphasis><xref linkend="serialcomms"/>, Serial Communications</emphasis></term>
+ <listitem>
+ <para>Explains how to connect terminals and modems to your
+ FreeBSD system for both dial in and dial out connections.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="ppp-and-slip"/>, PPP and SLIP</emphasis></term>
+ <listitem>
+ <para>Describes how to use PPP, SLIP, or PPP over Ethernet to
+ connect to remote systems with FreeBSD.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="mail"/>, Electronic Mail</emphasis></term>
+ <listitem>
+ <para>Explains the different components of an email server and
+ dives into simple configuration topics for the most popular
+ mail server software:
+ <application>sendmail</application>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="network-servers"/>, Network Servers</emphasis></term>
+ <listitem>
+ <para>Provides detailed instructions and example configuration
+ files to set up your FreeBSD machine as a network filesystem
+ server, domain name server, network information system
+ server, or time synchronization server.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="firewalls"/>, Firewalls</emphasis></term>
+ <listitem>
+ <para>Explains the philosophy behind software-based firewalls and
+ provides detailed information about the configuration of the
+ different firewalls available for FreeBSD.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="advanced-networking"/>, Advanced Networking</emphasis></term>
+ <listitem>
+ <para>Describes many networking topics, including sharing an
+ Internet connection with other computers on your LAN, advanced
+ routing topics, wireless networking, bluetooth, ATM, IPv6, and
+ much more.</para>
+ </listitem>
+ </varlistentry>
+
+<!-- Part V - Appendices -->
+
+ <varlistentry>
+ <term><emphasis><xref linkend="mirrors"/>, Obtaining FreeBSD </emphasis></term>
+ <listitem>
+ <para>Lists different sources for obtaining FreeBSD media on CDROM
+ or DVD as well as different sites on the Internet that allow
+ you to download and install FreeBSD.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="bibliography"/>, Bibliography </emphasis></term>
+ <listitem>
+ <para>This book touches on many different subjects that may
+ leave you hungry for a more detailed explanation. The
+ bibliography lists many excellent books that are referenced in
+ the text.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="eresources"/>, Resources on the Internet</emphasis></term>
+ <listitem>
+ <para>Describes the many forums available for FreeBSD users to
+ post questions and engage in technical conversations about
+ FreeBSD.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis><xref linkend="pgpkeys"/>, PGP Keys</emphasis></term>
+ <listitem>
+ <para>Lists the PGP fingerprints of several FreeBSD Developers.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <bridgehead xml:id="preface-conv" renderas="sect1">本書的編排體裁</bridgehead>
+
+ <para>為方便閱讀本書,以下是一些本書所遵循的編排體裁:</para>
+
+ <bridgehead xml:id="preface-conv-typographic" renderas="sect2">文字編排體裁</bridgehead>
+
+ <variablelist>
+ <varlistentry>
+ <term><emphasis>斜體字(Italic)</emphasis></term>
+ <listitem>
+ <para><emphasis>斜體字型(Italic)</emphasis> 用於:檔名、目錄、網址(URL)、
+ 強調語氣、以及第一次提及的技術詞彙。</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>定寬字(Monospace)</literal></term>
+ <listitem>
+ <para><literal>定寬字(Monospace)</literal> 用於:
+ 錯誤訊息、指令、環境變數、port 名稱、主機名稱(hostname)、帳號、群組、設備(device)名稱、變數、
+ 程式碼等。</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><application>粗體字型(Bold)</application></term>
+ <listitem>
+ <para>以<application>粗體字</application>表示:應用程式、命令、按鍵。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+<!-- Var list -->
+ <bridgehead xml:id="preface-conv-commands" renderas="sect2">使用者輸入</bridgehead>
+
+ <para>鍵盤輸入以 <keycap>粗體字(Bold)</keycap> 表示,以便與一般文字做區隔。
+ 組合鍵是指同時按下一些按鍵,我們以 `<literal>+</literal>' 來表示連接,像是:</para>
+
+ <para>
+ <keycombo action="simul">
+ <keycap>Ctrl</keycap>
+ <keycap>Alt</keycap>
+ <keycap>Del</keycap>
+ </keycombo>
+ </para>
+
+ <para>也就是說,一起按 <keycap>Ctrl</keycap> 鍵、
+ <keycap>Alt</keycap> 鍵,以及 <keycap>Del</keycap> 鍵。</para>
+
+ <para>若要逐一按鍵,那麼會以逗號(,)來表示,像是:</para>
+
+ <para>
+ <keycombo action="simul">
+ <keycap>Ctrl</keycap>
+ <keycap>X</keycap>
+ </keycombo>,
+ <keycombo action="simul">
+ <keycap>Ctrl</keycap>
+ <keycap>S</keycap>
+ </keycombo>
+ </para>
+
+ <para>也就是說:先同時按下 <keycap>Ctrl</keycap> 與 <keycap>X</keycap> 鍵,
+ 然後放開後再同時按 <keycap>Ctrl</keycap> 與 <keycap>S</keycap> 鍵。</para>
+
+<!-- How to type in key stokes, etc.. -->
+ <bridgehead xml:id="preface-conv-examples" renderas="sect2">舉個實例</bridgehead>
+
+ <para>下面例子以 <filename>E:\&gt;</filename>
+ 為開頭的代表 &ms-dos; 指令部分。 若沒有特殊情況的話,這些指令應該是在 &microsoft.windows; 環境的
+ <quote>命令提示字元(Command Prompt)</quote> 內執行。</para>
+
+ <screen><prompt>E:\&gt;</prompt> <userinput>tools\fdimage floppies\kern.flp A:</userinput></screen>
+
+ <para>例子若是先以 &prompt.root; 為開頭再接指令的話,就是指在 FreeBSD 中以 root 權限來下命令。
+ 你可以先以 <systemitem class="username">root</systemitem>登入系統並下指令,或是以你自己的帳號登入,並使用
+ &man.su.1; 來取得 root 權限。</para>
+
+ <screen>&prompt.root; <userinput>dd if=kern.flp of=/dev/fd0</userinput></screen>
+
+ <para>例子若是先以 &prompt.user; 為開頭再接指令的話,就是指在 FreeBSD 中以一般帳號來下命令即可。
+ 除非有提到其他用法,否則都是預設為 C-shell(csh/tcsh) 語法,用來設定環境變數以及下其他指令的意思。</para>
+
+ <screen>&prompt.user; <userinput>top</userinput></screen>
+
+ <bridgehead xml:id="preface-acknowledgements" renderas="sect1">致謝</bridgehead>
+
+ <para>您所看到的這本書是經過數百個分散在世界各地的人所努力而來的結果。
+ 無論他們只是糾正一些錯誤或提交完整的章節,所有的點滴貢獻都是非常寶貴有用的。</para>
+
+ <para>也有一些公司透過提供資金讓作者專注於撰稿、提供出版資金等模式來支持文件的寫作。
+ 其中,BSDi (之後併入 <link xlink:href="http://www.windriver.com">Wind River Systems</link>)
+ 資助 FreeBSD 文件計劃成員來專職改善這本書直到 2000 年 3 月第一版的出版。(ISBN 1-57176-241-8)
+ Wind River Systems 同時資助其他作者來對輸出架構做很多改進,以及給文章增加一些附加章節。這項工作結束於
+ 2001 年 11 月第二版。(ISBN 1-57176-303-1)
+ 在 2003-2004 兩年中,<link xlink:href="http://www.freebsdmall.com">FreeBSD Mall</link> 把報酬支付給改進這本手冊以使第三版印刷版本能夠出版的志工。
+</para>
+
+</preface>
diff --git a/zh_TW.UTF-8/books/handbook/printing/Makefile b/zh_TW.UTF-8/books/handbook/printing/Makefile
new file mode 100644
index 0000000000..cbf5a174cc
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/printing/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= printing/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/printing/chapter.xml b/zh_TW.UTF-8/books/handbook/printing/chapter.xml
new file mode 100644
index 0000000000..f98dbbca8c
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/printing/chapter.xml
@@ -0,0 +1,4737 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Traditional Chinese Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.96
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="printing">
+ <info><title>列印</title>
+ <authorgroup>
+ <author><personname><firstname>Sean</firstname><surname>Kelly</surname></personname><contrib>Contributed by </contrib></author>
+ <!-- 30 Sept 1995 -->
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Jim</firstname><surname>Mock</surname></personname><contrib>Restructured and updated by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="printing-synopsis">
+ <title>概述</title>
+ <indexterm><primary>LPD spooling system</primary></indexterm>
+ <indexterm><primary>LPD 緩衝系統</primary></indexterm>
+ <indexterm><primary>printing</primary></indexterm>
+ <indexterm><primary>列印</primary></indexterm>
+
+ <para>FreeBSD 可以和各式各樣的印表機搭配列印,
+ 從最老的撞針式印表機到最新的雷射印表機都沒問題,
+ 讓您的應用程式可以產生出高品質的文件列印輸出。</para>
+
+ <para>也可以把 FreeBSD 設定成一台網路列印伺服器;這時候的 FreeBSD
+ 能接收其他電腦送來的列印工作,包括其他 FreeBSD 的電腦、&windows;
+ 的電腦以及 &macos; 的電腦。 FreeBSD
+ 會確保同時只有一件文件正在列印,而且可以統計哪個使用者及機器印得最多,
+ 還有就是印出接下來是誰的文件這類的<quote>標題</quote>頁等。</para>
+
+ <para>讀完這章,您將了解:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>如何設定 FreeBSD 的列印多工緩衝處理器。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何安裝列印過濾器以分別處理特殊的列印工作,
+ 包括把收到的文件轉換成您的印表機看得懂的列印格式等。</para>
+ </listitem>
+
+ <listitem>
+ <para>了解如何在您列印時順便印出頁首或標題。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何利用別台電腦上的印表機列印。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何利用直接接在網路上的印表機列印。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何控制印表機的權限,包括限制列印工作的檔案大小,
+ 以及不允許特定使用者列印等。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何記下印表機的統計資料,以及各帳號的印表機使用量。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何解決列印時遇到的問題。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>在開始閱讀這章之前,您需要︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>要有設定、編譯 kernel 的基礎概念
+ (<xref linkend="kernelconfig"/>)。</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="printing-intro-spooler">
+ <title>介紹</title>
+
+ <para>要在 FreeBSD 上使用印表機,您需要設定好 Berkeley
+ 行列式印表機列印緩衝系統,又稱為 <application>LPD</application>
+ 列印緩衝系統,或者就叫他 <application>LPD</application> 吧。
+ 這是 FreeBSD 標準的印表機控制系統,本章會介紹並教您如何設定
+ <application>LPD</application>。</para>
+
+ <para>如果您已經對 <application>LPD</application>
+ 或是其他列印緩衝系統很熟悉了,
+ 您可以直接跳到<link linkend="printing-intro-setup">基本設定</link>。
+ </para>
+
+ <para><application>LPD</application> 控制著主機上印表機的一切。
+ 它負責這些工作:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>控制本機及網路印表機的使用。</para>
+ </listitem>
+
+ <listitem>
+ <para>讓使用者可以列印文件,送出的文件稱為<emphasis>工作</emphasis>。<indexterm><primary>print jobs</primary></indexterm>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>為每台印表機準備一個<emphasis>佇列</emphasis>,
+ 避免多個使用者同時使用同一台印表機。</para>
+ </listitem>
+
+ <listitem>
+ <para>列印 <emphasis>header pages</emphasis> (又稱為
+ <emphasis>banner</emphasis> or <emphasis>burst</emphasis>
+ pages),方便使用者在出紙閘中找到自已列印的文件。</para>
+ </listitem>
+
+ <listitem>
+ <para>把接在串列埠上的印表機的通訊參數設定好。</para>
+ </listitem>
+
+ <listitem>
+ <para>利用網路傳送列印工作給別台主機上的
+ <application>LPD</application>。</para>
+ </listitem>
+
+ <listitem>
+ <para>執行特別的過濾程式將列印工作格式化以配合不同的列印語言或印表機。
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>統計印表機的使用情況。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>藉由設定檔 (<filename>/etc/printcap</filename>) 以及過濾程式的幫助,
+ 您可以讓大多數的印表機配合 <application>LPD</application>
+ 達成上述全部或部份的功能。</para>
+
+ <sect2 xml:id="printing-intro-why">
+ <title>為什麼需要使用多工緩衝處理器</title>
+
+ <para>如果您的系統是個人使用,
+ 不需要控制存取權限、列印標題頁或者統計使用情況等功能時,
+ 您可能會覺得很奇怪為什麼還需要去管這個多工緩衝處理器。
+ 當然要直接控制印表機可行的,
+ 不過無論如何您還是需要多工緩衝處理器,因為:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><application>LPD</application> 可以在背景 (background)
+ 列印,您不需要在那邊等文件送到印表機。</para>
+ </listitem>
+
+ <listitem>
+ <para><application>LPD</application> 可以很輕鬆地用過濾器增加日期 /
+ 時間於頁首或是把特別的檔案格式 (像是 &tex;<indexterm><primary>&tex;</primary></indexterm> DVI 檔)
+ 轉換成印表機看得懂的的格式,您不需要手動去做這些步驟。</para>
+ </listitem>
+
+ <listitem>
+ <para>許多免費或商業軟體提供的列印功能通常都是和多工緩衝處理器溝通。
+ 透過設定緩衝系統,支援您現有或是即將要安裝的其他軟體將變得更容易。
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="printing-intro-setup">
+ <title>基礎設定</title>
+
+ <para>要用印表機搭配 <application>LPD</application>
+ 多工緩衝系統,您需要有印表機這個硬體以及
+ <application>LPD</application> 這套軟體。
+ 本手冊提供了兩階段的設定說明:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>閱讀 <link linkend="printing-simple">簡易印表機設定</link>
+ 來學習如何連接印表機、讓印表機和 <application>LPD</application>
+ 溝通以及列印純文字文件。</para>
+ </listitem>
+
+ <listitem>
+ <para>閱讀 <link linkend="printing-advanced">進階印表機設定</link>
+ 來學習如何列印各種特殊格式文件、列印首頁、網路列印、
+ 控制印表機權限以及統計使用狀況等。</para>
+ </listitem>
+ </itemizedlist>
+
+ <sect2 xml:id="printing-simple">
+ <title>簡易印表機設定</title>
+
+ <para>本章節會告訴您如何設定印表機設備和
+ <application>LPD</application> 軟體以使用印表機,
+ 基本教學內容:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="printing-hardware">硬體設定</link>
+ 會提示如何將印表機接上電腦的連接埠。</para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="printing-software">軟體設定</link>
+ 會示範如何寫 <application>LPD</application> 緩衝器設定檔
+ (<filename>/etc/printcap</filename>)。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>如果您要把印表機設定接收網路列印資料而不是本機端的話,請參考
+ <link linkend="printing-advanced-network-net-if">
+ 印表機及網路資料傳輸介面</link>。</para>
+
+ <para>這個章節雖然叫做<quote>簡易印表機設定</quote>,
+ 實際上還是有點複雜的。 最困難的部份是讓你的印表機和電腦上的
+ <application>LPD</application> 緩衝器能夠正常運作。
+ 一旦印表機可以正常工作之後,
+ 像是印首頁或是做列印統計這些進階的功能就不難做到了。
+ </para>
+
+ <sect3 xml:id="printing-hardware">
+ <title>硬體設定</title>
+
+ <para>本章節討論各種連接印表機到 PC 的方式。
+ 這裡會提到不同種類的連接埠和連接線,
+ 以及為了讓 FreeBSD 能和印表機溝通您可能會需要開啟的核心參數等。
+ </para>
+
+ <para>如果您已經把印表機接上電腦,
+ 而且在其他作業系統上有成功列印過的話,可以直接跳至
+ <link linkend="printing-software">軟體設定</link>。</para>
+
+ <sect4 xml:id="printing-ports">
+ <title>連接埠和排線</title>
+
+ <para>市售個人電腦印表機一般來說不出這三種界面:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>序列 (Serial)</emphasis><indexterm><primary>printers</primary><secondary>serial</secondary></indexterm>
+ 界面,又稱為 RS-232 或 COM 埠,
+ 用您電腦上的序列埠傳送資料到印表機。
+ 序列界面廣泛的為電腦業界所採用,
+ 所以排線容易取得,要設定連線並不困難。
+ 然而序列介面有時候會需要使用較特別的排線,
+ 這時候就有可能需要設定一些較為複雜的通訊參數了。
+ 大部份 PC 序列埠的傳輸速度最高只到 115200&nbsp;bps,
+ 因此想要用序列埠來列印大圖是不切實際的。</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>並列 (Parallel)</emphasis><indexterm><primary>printers</primary><secondary>parallel</secondary></indexterm>
+ 界面利用電腦的並列埠將資料送到印表機。
+ 並列埠比 RS-232 序列埠還快,也是一種電腦業界常用的界面。
+ 這種界面的排線非常容易取得,但是較難用手工打造。
+ 通常來說並列界面並沒有什麼通訊參數需要指定,
+ 所以設定起來超級容易。</para>
+
+ <para>並列埠界面有時候也會被稱為 <quote>Centronics</quote><indexterm><primary>centronics</primary><see>parallel printers</see></indexterm>
+ 界面,這是印表機的接頭的名稱。</para>
+ </listitem>
+
+ <listitem>
+ <para>USB<indexterm><primary>printers</primary><secondary>USB</secondary></indexterm> 界面,也就是通用序列匯流排,傳輸速率比並列界面或是
+ RS-232 序列界面都來得快,而且 USB 排線單純又便宜。
+ 對列印工作而言,USB 比 RS-232
+ 序列埠或是並列埠都來得好,但是在
+ &unix; 系統上的支援度較差。 購買同時具有 USB
+ 及並列埠兩種界面的印表機可以避免掉這種問題。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>一般而言,並列界面只能提供單向傳輸
+ (電腦至印表機),而要用 USB 才能提供雙向。 然而在 FreeBSD
+ 下,使用較新的並列埠 (EPP 和 ECP) 以及印表機,再配合使用
+ IEEE-1284 相容排線也可以做到雙向溝通。</para>
+
+ <indexterm><primary>PostScript</primary></indexterm>
+
+ <para>電腦和印表機之間藉由並列埠行進雙向溝通的方式有兩種。
+ 第一種是使用特製的、能和特定印表機溝通的 FreeBSD 印表機驅動程式。
+ 這種方式在噴墨印表機上很常見,用來回報墨水存量以及其他狀態資訊等。
+ 第二種方法是用 &postscript;,如果印表機有支援的話。</para>
+
+ <para>&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.</para>
+ </sect4>
+
+ <sect4 xml:id="printing-parallel">
+ <title>Parallel Ports</title>
+
+ <para>To 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.</para>
+
+ <para>Remember which parallel port you used on the computer.
+ The first parallel port is <filename>ppc0</filename> to
+ FreeBSD; the second is <filename>ppc1</filename>, and so
+ on. The printer device name uses the same scheme:
+ <filename>/dev/lpt0</filename> for the printer on the first
+ parallel ports etc.</para>
+ </sect4>
+
+ <sect4 xml:id="printing-serial">
+ <title>Serial Ports</title>
+
+ <para>To 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.</para>
+
+ <para>If you are unsure what the <quote>proper serial
+ cable</quote> is, you may wish to try one of the following
+ alternatives:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>A <emphasis>modem</emphasis> 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
+ <quote>DTE-to-DCE</quote> cable.</para>
+ </listitem>
+
+ <listitem>
+ <para>A <emphasis>null-modem</emphasis><indexterm><primary>null-modem cable</primary></indexterm> 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
+ <quote>DTE-to-DTE</quote> cable.</para>
+ </listitem>
+
+ <listitem>
+ <para>A <emphasis>serial printer</emphasis> cable, required
+ for some unusual printers, is like the null-modem cable,
+ but sends some signals to their counterparts instead of
+ being internally shorted.</para>
+ </listitem>
+ </itemizedlist>
+
+ <indexterm><primary>baud rate</primary></indexterm>
+ <indexterm><primary>parity</primary></indexterm>
+ <indexterm><primary>flow control protocol</primary></indexterm>
+ <para>You should also set up the communications parameters for
+ the printer, usually through front-panel controls or DIP
+ switches on the printer. Choose the highest
+ <literal>bps</literal> (bits per second, sometimes
+ <emphasis>baud rate</emphasis>) 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
+ <quote>in-band</quote> or <quote>software</quote>) flow control.
+ Remember these settings for the software configuration that
+ follows.</para>
+ </sect4>
+ </sect3>
+
+ <sect3 xml:id="printing-software">
+ <title>Software Setup</title>
+
+ <para>This section describes the software setup necessary to print
+ with the <application>LPD</application> spooling system in FreeBSD.
+ </para>
+
+ <para>Here is an outline of the steps involved:</para>
+
+ <procedure>
+ <step>
+ <para>Configure your kernel, if necessary, for the port you
+ are using for the printer; section <link linkend="printing-kernel">Kernel Configuration</link> tells
+ you what you need to do.</para>
+ </step>
+
+ <step>
+ <para>Set the communications mode for the parallel port, if
+ you are using a parallel port; section <link linkend="printing-parallel-port-mode">Setting the
+ Communication Mode for the Parallel Port</link> gives
+ details.</para>
+ </step>
+
+ <step>
+ <para>Test if the operating system can send data to the printer.
+ Section <link linkend="printing-testing">Checking Printer
+ Communications</link> gives some suggestions on how to do
+ this.</para>
+ </step>
+
+ <step>
+ <para>Set up <application>LPD</application> for the printer by
+ modifying the file
+ <filename>/etc/printcap</filename>. You will find out how
+ to do this later in this chapter.</para>
+ </step>
+ </procedure>
+
+ <sect4 xml:id="printing-kernel">
+ <title>Kernel Configuration</title>
+
+ <para>The 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.</para>
+
+ <para>To find out if the kernel you are currently using supports
+ a serial interface, type:</para>
+
+ <screen>&prompt.root; <userinput>grep sioN /var/run/dmesg.boot</userinput></screen>
+
+ <para>Where <replaceable>N</replaceable> is the number of the
+ serial port, starting from zero. If you see output similar to
+ the following:</para>
+
+ <screen>sio2 at port 0x3e8-0x3ef irq 5 on isa
+sio2: type 16550A</screen>
+
+ <para>then the kernel supports the port.</para>
+
+ <para>To find out if the kernel supports a parallel interface,
+ type:</para>
+
+ <screen>&prompt.root; <userinput>grep ppcN /var/run/dmesg.boot</userinput></screen>
+
+ <para>Where <replaceable>N</replaceable> is the number of the
+ parallel port, starting from zero. If you see output similar
+ to the following:</para>
+
+ <screen>ppc0: &lt;Parallel port&gt; 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 threshold</screen>
+
+ <para>then the kernel supports the port.</para>
+
+ <para>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.</para>
+
+ <para>To add support for a serial port, see the section on
+ kernel configuration. To add support for a parallel port, see
+ that section <emphasis>and</emphasis> the section that
+ follows.</para>
+ </sect4>
+ </sect3>
+ <sect3 xml:id="printing-parallel-port-mode">
+ <title>Setting the Communication Mode for the Parallel
+ Port</title>
+
+ <para>When 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
+ uses the &man.ppbus.4; system, which controls the port
+ chipset with the &man.ppc.4; driver.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The <emphasis>interrupt-driven</emphasis> 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.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <emphasis>polled</emphasis> 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.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>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.</para>
+
+ <para>You can set the communications mode in two ways: by
+ configuring the kernel or by using the &man.lptcontrol.8;
+ program.</para>
+
+ <para><emphasis>To set the communications mode by configuring
+ the kernel:</emphasis></para>
+
+ <procedure>
+ <step>
+ <para>Edit your kernel configuration file. Look for
+ an <literal>ppc0</literal> entry. If you are setting up
+ the second parallel port, use <literal>ppc1</literal>
+ instead. Use <literal>ppc2</literal> for the third port,
+ and so on.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>If you want interrupt-driven mode, edit the following line:</para>
+
+ <programlisting>hint.ppc.0.irq="<replaceable>N</replaceable>"</programlisting>
+
+ <para>in the <filename>/boot/device.hints</filename> file
+ and replace <replaceable>N</replaceable> with the right
+ IRQ number. The kernel configuration file must
+ also contain the &man.ppc.4; driver:</para>
+
+ <screen>device ppc</screen>
+
+ </listitem>
+
+ <listitem>
+ <para>If you want polled mode, remove in your
+ <filename>/boot/device.hints</filename> file, the
+ following line:</para>
+
+ <programlisting>hint.ppc.0.irq="<replaceable>N</replaceable>"</programlisting>
+
+ <para>In some cases, this is not enough to put the
+ 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.</para>
+ </listitem>
+ </itemizedlist>
+ </step>
+
+ <step>
+ <para>Save the file. Then configure, build, and install the
+ kernel, then reboot. See <link linkend="kernelconfig">kernel configuration</link> for
+ more details.</para>
+ </step>
+ </procedure>
+
+ <para><emphasis>To set the communications mode with</emphasis>
+ &man.lptcontrol.8;:</para>
+
+ <procedure>
+ <step>
+ <para>Type:</para>
+
+ <screen>&prompt.root; <userinput>lptcontrol -i -d /dev/lptN</userinput></screen>
+
+ <para>to set interrupt-driven mode for
+ <literal>lptN</literal>.</para>
+ </step>
+
+ <step>
+ <para>Type:</para>
+
+ <screen>&prompt.root; <userinput>lptcontrol -p -d /dev/lptN</userinput></screen>
+
+ <para>to set polled-mode for
+ <literal>lptN</literal>.</para>
+ </step>
+ </procedure>
+
+ <para>You could put these commands in your
+ <filename>/etc/rc.local</filename> file to set the mode each
+ time your system boots. See &man.lptcontrol.8; for more
+ information.</para>
+ </sect3>
+
+ <sect3 xml:id="printing-testing">
+ <title>Checking Printer Communications</title>
+
+ <para>Before 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.</para>
+
+ <para>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.</para>
+
+ <indexterm><primary>PostScript</primary></indexterm>
+ <para>For a &postscript; (or other language-based) printer, we
+ will need a more sophisticated test. A small &postscript;
+ program, such as the following, will suffice:</para>
+
+ <programlisting>%!PS
+100 100 moveto 300 300 lineto stroke
+310 310 moveto /Helvetica findfont 12 scalefont setfont
+(Is this thing working?) show
+showpage</programlisting>
+
+ <para>The above &postscript; code can be placed into a file and
+ used as shown in the examples appearing in the following
+ sections.</para>
+
+ <indexterm><primary>PCL</primary></indexterm>
+ <note>
+ <para>When 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.</para>
+ </note>
+
+ <sect4 xml:id="printing-checking-parallel">
+ <title>Checking a Parallel Printer</title>
+
+ <indexterm>
+ <primary>printers</primary>
+ <secondary>parallel</secondary>
+ </indexterm>
+ <para>This section tells you how to check if FreeBSD can
+ communicate with a printer connected to a parallel
+ port.</para>
+
+ <para><emphasis>To test a printer on a parallel
+ port:</emphasis></para>
+
+ <procedure>
+ <step>
+ <para>Become <systemitem class="username">root</systemitem> with &man.su.1;.</para>
+ </step>
+
+ <step>
+ <para>Send data to the printer.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>If the printer can print plain text, then use
+ &man.lptest.1;. Type:</para>
+
+ <screen>&prompt.root; <userinput>lptest &gt; /dev/lptN</userinput></screen>
+
+ <para>Where <replaceable>N</replaceable> is the number
+ of the parallel port, starting from zero.</para>
+ </listitem>
+
+ <listitem>
+ <para>If the printer understands &postscript; or other
+ printer language, then send a small program to the
+ printer. Type:</para>
+
+ <screen>&prompt.root; <userinput>cat &gt; /dev/lptN</userinput></screen>
+
+ <para>Then, line by line, type the program
+ <emphasis>carefully</emphasis> as you cannot edit a
+ line once you have pressed <literal>RETURN</literal>
+ or <literal>ENTER</literal>. When you have finished
+ entering the program, press
+ <literal>CONTROL+D</literal>, or whatever your end
+ of file key is.</para>
+
+ <para>Alternatively, you can put the program in a file
+ and type:</para>
+
+ <screen>&prompt.root; <userinput>cat file &gt; /dev/lptN</userinput></screen>
+
+ <para>Where <replaceable>file</replaceable> is the
+ name of the file containing the program you want to
+ send to the printer.</para>
+ </listitem>
+ </itemizedlist>
+ </step>
+ </procedure>
+
+ <para>You should see something print. Do not worry if the
+ text does not look right; we will fix such things
+ later.</para>
+ </sect4>
+
+ <sect4 xml:id="printing-checking-serial">
+ <title>Checking a Serial Printer</title>
+
+ <indexterm>
+ <primary>printers</primary>
+ <secondary>serial</secondary>
+ </indexterm>
+ <para>This section tells you how to check if FreeBSD can
+ communicate with a printer on a serial port.</para>
+
+ <para><emphasis>To test a printer on a serial
+ port:</emphasis></para>
+
+ <procedure>
+ <step>
+ <para>Become <systemitem class="username">root</systemitem> with &man.su.1;.</para>
+ </step>
+
+ <step>
+ <para>Edit the file <filename>/etc/remote</filename>. Add
+ the following entry:</para>
+
+ <programlisting>printer:dv=/dev/<replaceable>port</replaceable>:br#<replaceable>bps-rate</replaceable>:pa=<replaceable>parity</replaceable></programlisting>
+
+ <indexterm><primary>bits-per-second</primary></indexterm>
+ <indexterm><primary>serial port</primary></indexterm>
+ <indexterm><primary>parity</primary></indexterm>
+ <para>Where <replaceable>port</replaceable> is the device
+ entry for the serial port (<literal>ttyd0</literal>,
+ <literal>ttyd1</literal>, etc.),
+ <replaceable>bps-rate</replaceable> is the
+ bits-per-second rate at which the printer communicates,
+ and <replaceable>parity</replaceable> is the parity
+ required by the printer (either <literal>even</literal>,
+ <literal>odd</literal>, <literal>none</literal>, or
+ <literal>zero</literal>).</para>
+
+ <para>Here is a sample entry for a printer connected via
+ a serial line to the third serial port at 19200&nbsp;bps with
+ no parity:</para>
+
+ <programlisting>printer:dv=/dev/ttyd2:br#19200:pa=none</programlisting>
+ </step>
+
+ <step>
+ <para>Connect to the printer with &man.tip.1;.
+ Type:</para>
+
+ <screen>&prompt.root; <userinput>tip printer</userinput></screen>
+
+ <para>If this step does not work, edit the file
+ <filename>/etc/remote</filename> again and try using
+ <filename>/dev/cuaaN</filename>
+ instead of
+ <filename>/dev/ttydN</filename>.</para>
+ </step>
+
+ <step>
+ <para>Send data to the printer.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>If the printer can print plain text, then use
+ &man.lptest.1;. Type:</para>
+
+ <screen>&prompt.user; <userinput>$lptest</userinput></screen>
+ </listitem>
+
+ <listitem>
+ <para>If the printer understands &postscript; or other
+ printer language, then send a small program to the
+ printer. Type the program, line by line,
+ <emphasis>very carefully</emphasis> 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 <literal>CONTROL+D</literal>.</para>
+
+ <para>Alternatively, you can put the program in a file
+ and type:</para>
+
+ <screen>&prompt.user; <userinput>&gt;file</userinput></screen>
+
+ <para>Where <replaceable>file</replaceable> is the
+ name of the file containing the program. After
+ &man.tip.1; sends the file, press any required
+ end-of-file key.</para>
+ </listitem>
+ </itemizedlist>
+ </step>
+ </procedure>
+
+ <para>You should see something print. Do not worry if the
+ text does not look right; we will fix that later.</para>
+ </sect4>
+ </sect3>
+
+ <sect3 xml:id="printing-printcap">
+ <title>Enabling the Spooler: the <filename>/etc/printcap</filename>
+ File</title>
+
+ <para>At 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 <application>LPD</application> to control access
+ to your printer.</para>
+
+ <para>You configure <application>LPD</application> by editing the file
+ <filename>/etc/printcap</filename>. The
+ <application>LPD</application> spooling system
+ reads this file each time the spooler is used, so updates to the
+ file take immediate effect.</para>
+
+ <indexterm>
+ <primary>printers</primary>
+ <secondary>capabilities</secondary>
+ </indexterm>
+ <para>The format of the &man.printcap.5; file is straightforward.
+ Use your favorite text editor to make changes to
+ <filename>/etc/printcap</filename>. The format is identical to
+ other capability files like
+ <filename>/usr/share/misc/termcap</filename> and
+ <filename>/etc/remote</filename>. For complete information
+ about the format, see the &man.cgetent.3;.</para>
+
+ <para>The simple spooler configuration consists of the following
+ steps:</para>
+
+ <procedure>
+ <step>
+ <para>Pick a name (and a few convenient aliases) for the
+ printer, and put them in the
+ <filename>/etc/printcap</filename> file; see the
+ <link linkend="printing-naming">Naming the Printer</link>
+ section for more information on naming.</para>
+ </step>
+
+ <step>
+ <para>Turn off header pages<indexterm><primary>header pages</primary></indexterm> (which are on by default) by
+ inserting the <literal>sh</literal> capability; see the
+ <link linkend="printing-no-header-pages">Suppressing Header
+ Pages</link> section for more information.</para>
+ </step>
+
+ <step>
+ <para>Make a spooling directory, and specify its location with
+ the <literal>sd</literal> capability; see the <link linkend="printing-spooldir">Making the Spooling
+ Directory</link> section for more information.</para>
+ </step>
+
+ <step>
+ <para>Set the <filename>/dev</filename> entry to use for the
+ printer, and note it in <filename>/etc/printcap</filename>
+ with the <literal>lp</literal> capability; see the <link linkend="printing-device">Identifying the Printer
+ Device</link> for more information. Also, if the printer is
+ on a serial port, set up the communication parameters with
+ the <literal>ms#</literal> capability which is discussed in the <link linkend="printing-commparam">Configuring Spooler
+ Communications Parameters</link> section.</para>
+ </step>
+
+ <step>
+ <para>Install a plain text input filter; see the <link linkend="printing-textfilter">Installing the Text
+ Filter</link> section for details.</para>
+ </step>
+
+ <step>
+ <para>Test the setup by printing something with the
+ &man.lpr.1; command. More details are available in the
+ <link linkend="printing-trying">Trying It Out</link> and
+ <link linkend="printing-troubleshooting">Troubleshooting</link>
+ sections.</para>
+ </step>
+ </procedure>
+
+ <note>
+ <para>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.</para>
+ </note>
+
+ <para>Users often expect that they can print plain text to any of
+ the printers installed on your system. Programs that interface
+ to <application>LPD</application> 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 <emphasis>and</emphasis>
+ 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 <link linkend="printing-advanced-if-conversion">Accommodating Plain
+ Text Jobs on &postscript; Printers</link> tells how to do
+ this.</para>
+
+ <sect4 xml:id="printing-naming">
+ <title>Naming the Printer</title>
+
+ <para>The 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.</para>
+
+ <para>At least one of the printers specified in the
+ <filename>/etc/printcap</filename> should have the alias
+ <literal>lp</literal>. This is the default printer's name.
+ If users do not have the <envar>PRINTER</envar> environment
+ variable nor specify a printer name on the command line of any
+ of the <application>LPD</application> commands,
+ then <literal>lp</literal> will be the
+ default printer they get to use.</para>
+
+ <para>Also, it is common practice to make the last alias for a
+ printer be a full description of the printer, including make
+ and model.</para>
+
+ <para>Once you have picked a name and some common aliases, put
+ them in the <filename>/etc/printcap</filename> 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.</para>
+
+ <para>In the following example, we start with a skeletal
+ <filename>/etc/printcap</filename> that defines two printers
+ (a Diablo 630 line printer and a Panasonic KX-P4455 &postscript;
+ laser printer):</para>
+
+ <programlisting>#
+# /etc/printcap for host rose
+#
+rattan|line|diablo|lp|Diablo 630 Line Printer:
+
+bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:</programlisting>
+
+ <para>In this example, the first printer is named
+ <literal>rattan</literal> and has as aliases
+ <literal>line</literal>, <literal>diablo</literal>,
+ <literal>lp</literal>, and <literal>Diablo 630 Line
+ Printer</literal>. Since it has the alias
+ <literal>lp</literal>, it is also the default printer. The
+ second is named <literal>bamboo</literal>, and has as aliases
+ <literal>ps</literal>, <literal>PS</literal>,
+ <literal>S</literal>, <literal>panasonic</literal>, and
+ <literal>Panasonic KX-P4455 PostScript v51.4</literal>.</para>
+ </sect4>
+
+ <sect4 xml:id="printing-no-header-pages">
+ <title>Suppressing Header Pages</title>
+ <indexterm>
+ <primary>printing</primary>
+ <secondary>header pages</secondary>
+ </indexterm>
+
+ <para>The <application>LPD</application> spooling system will
+ by default print a
+ <emphasis>header page</emphasis> 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.</para>
+
+ <para>To suppress header pages, add the <literal>sh</literal>
+ capability to the entry for the printer in
+ <filename>/etc/printcap</filename>. Here is an example
+ <filename>/etc/printcap</filename> with <literal>sh</literal>
+ added:</para>
+
+ <programlisting>#
+# /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:</programlisting>
+
+ <para>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.</para>
+ </sect4>
+
+ <sect4 xml:id="printing-spooldir">
+ <title>Making the Spooling Directory</title>
+ <indexterm><primary>printer spool</primary></indexterm>
+ <indexterm><primary>print jobs</primary></indexterm>
+
+ <para>The next step in the simple spooler setup is to make a
+ <emphasis>spooling directory</emphasis>, a directory where
+ print jobs reside until they are printed, and where a number
+ of other spooler support files live.</para>
+
+ <para>Because of the variable nature of spooling directories, it
+ is customary to put these directories under
+ <filename>/var/spool</filename>. It is not necessary to
+ backup the contents of spooling directories, either.
+ Recreating them is as simple as running &man.mkdir.1;.</para>
+
+ <para>It is also customary to make the directory with a name
+ that is identical to the name of the printer, as shown
+ below:</para>
+
+ <screen>&prompt.root; <userinput>mkdir /var/spool/printer-name</userinput></screen>
+
+ <para>However, 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
+ <application>LPD</application>. We
+ will do this for our two example printers
+ <literal>rattan</literal> and
+ <literal>bamboo</literal>:</para>
+
+ <screen>&prompt.root; <userinput>mkdir /var/spool/lpd</userinput>
+&prompt.root; <userinput>mkdir /var/spool/lpd/rattan</userinput>
+&prompt.root; <userinput>mkdir /var/spool/lpd/bamboo</userinput></screen>
+
+ <note>
+ <para>If 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:</para>
+
+ <screen>&prompt.root; <userinput>chown daemon:daemon /var/spool/lpd/rattan</userinput>
+&prompt.root; <userinput>chown daemon:daemon /var/spool/lpd/bamboo</userinput>
+&prompt.root; <userinput>chmod 770 /var/spool/lpd/rattan</userinput>
+&prompt.root; <userinput>chmod 770 /var/spool/lpd/bamboo</userinput></screen>
+ </note>
+
+ <para>Finally, you need to tell <application>LPD</application>
+ about these directories
+ using the <filename>/etc/printcap</filename> file. You
+ specify the pathname of the spooling directory with the
+ <literal>sd</literal> capability:</para>
+
+ <programlisting>#
+# /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:</programlisting>
+
+ <para>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.</para>
+
+ <para>If you do not specify a spooling directory with
+ <literal>sd</literal>, the spooling system will use
+ <filename>/var/spool/lpd</filename> as a default.</para>
+ </sect4>
+
+ <sect4 xml:id="printing-device">
+ <title>Identifying the Printer Device</title>
+
+ <para>In the
+ Entries for the Ports
+ section, we identified which entry in the
+ <filename>/dev</filename> directory FreeBSD will use to
+ communicate with the printer. Now, we tell
+ <application>LPD</application> 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).</para>
+
+ <para>List the <filename>/dev</filename> entry pathname in the
+ <filename>/etc/printcap</filename> file using the
+ <literal>lp</literal> capability.</para>
+
+ <para>In our running example, let us assume that
+ <literal>rattan</literal> is on the first parallel port, and
+ <literal>bamboo</literal> is on a sixth serial port; here are
+ the additions to <filename>/etc/printcap</filename>:</para>
+
+ <programlisting>#
+# /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:</programlisting>
+
+ <para>If you do not specify the <literal>lp</literal> capability
+ for a printer in your <filename>/etc/printcap</filename> file,
+ <application>LPD</application> uses <filename>/dev/lp</filename>
+ as a default.
+ <filename>/dev/lp</filename> currently does not exist in
+ FreeBSD.</para>
+
+ <para>If the printer you are installing is connected to a
+ parallel port, skip to the section entitled, <link linkend="printing-textfilter">Installing the Text
+ Filter</link>. Otherwise, be sure to follow the instructions
+ in the next section.</para>
+ </sect4>
+
+ <sect4 xml:id="printing-commparam">
+ <title>Configuring Spooler Communication Parameters</title>
+ <indexterm>
+ <primary>printers</primary>
+ <secondary>serial</secondary>
+ </indexterm>
+
+ <para>For printers on serial ports, <application>LPD</application>
+ 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:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>It lets you try different communication parameters by
+ simply editing the <filename>/etc/printcap</filename>
+ file; you do not have to recompile the filter
+ program.</para>
+ </listitem>
+
+ <listitem>
+ <para>It enables the spooling system to use the same filter
+ program for multiple printers which may have different
+ serial communication settings.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The following <filename>/etc/printcap</filename>
+ capabilities control serial communication parameters of the
+ device listed in the <literal>lp</literal> capability:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>br#bps-rate</literal></term>
+
+ <listitem>
+ <para>Sets the communications speed of the device to
+ <replaceable>bps-rate</replaceable>, where
+ <replaceable>bps-rate</replaceable> can be 50, 75, 110,
+ 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600,
+ 19200, 38400, 57600, or 115200 bits-per-second.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ms#stty-mode</literal></term>
+
+ <listitem>
+ <para>Sets the options for the terminal device after
+ opening the device. &man.stty.1; explains the
+ available options.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>When <application>LPD</application> opens the device
+ specified by the <literal>lp</literal> capability, it sets
+ the characteristics of the device to those specified with
+ the <literal>ms#</literal> capability. Of particular
+ interest will be the <literal>parenb</literal>,
+ <literal>parodd</literal>, <literal>cs5</literal>,
+ <literal>cs6</literal>, <literal>cs7</literal>,
+ <literal>cs8</literal>, <literal>cstopb</literal>,
+ <literal>crtscts</literal>, and <literal>ixon</literal>
+ modes, which are explained in the &man.stty.1;
+ manual page.</para>
+
+ <para>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 <literal>-parenb</literal>,
+ 8-bit characters with <literal>cs8</literal>,
+ no modem control with <literal>clocal</literal> and
+ hardware flow control with <literal>crtscts</literal>:</para>
+
+ <programlisting>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:</programlisting>
+ </sect4>
+
+ <sect4 xml:id="printing-textfilter">
+ <title>Installing the Text Filter</title>
+ <indexterm>
+ <primary>printing</primary>
+ <secondary>filters</secondary>
+ </indexterm>
+
+ <para>We are now ready to tell <application>LPD</application>
+ what text filter to use to
+ send jobs to the printer. A <emphasis>text filter</emphasis>,
+ also known as an <emphasis>input filter</emphasis>, is a
+ program that <application>LPD</application> runs when it
+ has a job to print. When <application>LPD</application>
+ 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 <literal>lp</literal>
+ 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 <link linkend="printing-advanced-filters">Filters</link>
+ section.</para>
+
+ <para>For our simple printer setup, the text filter can be a
+ small shell script that just executes
+ <command>/bin/cat</command> to send the job to the printer.
+ FreeBSD comes with another filter called
+ <filename>lpf</filename> 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 <command>lpf</command> is
+ described in detail in section entitled <link linkend="printing-advanced-lpf">lpf: a Text
+ Filter</link>.</para>
+
+ <para>First, let us make the shell script
+ <filename>/usr/local/libexec/if-simple</filename> be a simple
+ text filter. Put the following text into that file with your
+ favorite text editor:</para>
+
+ <programlisting>#!/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 &amp;&amp; exit 0
+exit 2</programlisting>
+
+ <para>Make the file executable:</para>
+
+ <screen>&prompt.root; <userinput>chmod 555 /usr/local/libexec/if-simple</userinput></screen>
+
+ <para>And then tell LPD to use it by specifying it with the
+ <literal>if</literal> capability in
+ <filename>/etc/printcap</filename>. We will add it to the two
+ printers we have so far in the example
+ <filename>/etc/printcap</filename>:</para>
+
+ <programlisting>#
+# /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:</programlisting>
+
+ <note>
+ <para>A copy of the <filename>if-simple</filename> script
+ can be found in the <filename>/usr/share/examples/printing</filename>
+ directory.</para>
+ </note>
+ </sect4>
+
+ <sect4>
+ <title>Turn on <application>LPD</application></title>
+
+ <para>&man.lpd.8; is run from <filename>/etc/rc</filename>,
+ controlled by the <literal>lpd_enable</literal> variable. This
+ variable defaults to <literal>NO</literal>. If you have not done
+ so already, add the line:</para>
+
+ <programlisting>lpd_enable="YES"</programlisting>
+
+ <para>to <filename>/etc/rc.conf</filename>, and then either restart
+ your machine, or just run &man.lpd.8;.</para>
+
+ <screen>&prompt.root; <userinput>lpd</userinput></screen>
+ </sect4>
+
+ <sect4 xml:id="printing-trying">
+ <title>Trying It Out</title>
+
+ <para>You have reached the end of the simple
+ <application>LPD</application> 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 <application>LPD</application> system, you
+ use the command &man.lpr.1;,
+ which submits a job for printing.</para>
+
+ <para>You can combine &man.lpr.1; with the &man.lptest.1;
+ program, introduced in section <link linkend="printing-testing">Checking Printer
+ Communications</link> to generate some test text.</para>
+
+ <para><emphasis>To test the simple <application>LPD</application>
+ setup:</emphasis></para>
+
+ <para>Type:</para>
+
+ <screen>&prompt.root; <userinput>lptest 20 5 | lpr -Pprinter-name</userinput></screen>
+
+ <para>Where <replaceable>printer-name</replaceable> is a the
+ name of a printer (or an alias) specified in
+ <filename>/etc/printcap</filename>. To test the default
+ printer, type &man.lpr.1; without any <option>-P</option>
+ 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 <command>lpr
+ file</command>.</para>
+
+ <para>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:</para>
+
+ <programlisting>!"#$%&amp;'()*+,-./01234
+"#$%&amp;'()*+,-./012345
+#$%&amp;'()*+,-./0123456
+$%&amp;'()*+,-./01234567
+%&amp;'()*+,-./012345678</programlisting>
+
+ <para>To further test the printer, try downloading larger
+ programs (for language-based printers) or running
+ &man.lptest.1; with different arguments. For example,
+ <command>lptest 80 60</command> will produce 60 lines of 80
+ characters each.</para>
+
+ <para>If the printer did not work, see the <link linkend="printing-troubleshooting">Troubleshooting</link>
+ section.</para>
+ </sect4>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="printing-advanced">
+ <title>Advanced Printer Setup</title>
+
+ <para>This section describes filters for printing specially formatted
+ files, header pages, printing across networks, and restricting and
+ accounting for printer usage.</para>
+
+ <sect2 xml:id="printing-advanced-filter-intro">
+ <title>Filters</title>
+ <indexterm>
+ <primary>printing</primary>
+ <secondary>filters</secondary>
+ </indexterm>
+
+ <para>Although <application>LPD</application> handles network protocols,
+ queuing, access control,
+ and other aspects of printing, most of the <emphasis>real</emphasis>
+ work happens in the <emphasis>filters</emphasis>. 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&mdash;an extremely simple one that
+ should work with most printers (section <link linkend="printing-textfilter">Installing the Text
+ Filter</link>).</para>
+
+ <para>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
+ <emphasis>you</emphasis> have to provide filters yourself. The good
+ news is that many are generally available; when they are not, they are
+ usually easy to write.</para>
+
+ <para>Also, FreeBSD comes with one,
+ <filename>/usr/libexec/lpr/lpf</filename>, 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.</para>
+
+ <para>Here is what you will find in this section:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Section <link linkend="printing-advanced-filters">How Filters
+ Work</link>, 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 <quote>under the hood</quote>
+ when <application>LPD</application> 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.</para>
+ </listitem>
+
+ <listitem>
+ <para><application>LPD</application> 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 <link linkend="printing-advanced-if-conversion">Accommodating
+ Plain Text Jobs on &postscript; Printers</link> tells you what you
+ should do to overcome this problem. You should read this
+ section if you have a &postscript; printer.</para>
+ </listitem>
+
+ <listitem>
+ <para>&postscript; is a popular output format for many programs.
+ Some people even write &postscript; code directly. Unfortunately,
+ &postscript; printers are expensive. Section <link linkend="printing-advanced-ps">Simulating &postscript; on
+ Non &postscript; Printers</link> tells how you can further modify
+ a printer's text filter to accept and print &postscript; data on a
+ <emphasis>non &postscript;</emphasis> printer. You should read
+ this section if you do not have a &postscript; printer.</para>
+ </listitem>
+
+ <listitem>
+ <para>Section <link linkend="printing-advanced-convfilters">Conversion
+ Filters</link> 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 <command>lpr -t</command> to print troff data, or
+ <command>lpr -d</command> to print &tex; DVI data, or <command>lpr
+ -v</command> to print raster image data, and so forth. I
+ recommend reading this section.</para>
+ </listitem>
+
+ <listitem>
+ <para>Section <link linkend="printing-advanced-of">Output
+ Filters</link> tells all about a not often used feature of
+ <application>LPD</application>:
+ output filters. Unless you are printing header pages (see <link linkend="printing-advanced-header-pages">Header Pages</link>),
+ you can probably skip that section altogether.</para>
+ </listitem>
+
+ <listitem>
+ <para>Section <link linkend="printing-advanced-lpf">lpf: a Text
+ Filter</link> describes <command>lpf</command>, 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
+ <command>lpf</command>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <para>A copy of the various scripts described below can be
+ found in the <filename>/usr/share/examples/printing</filename>
+ directory.</para>
+ </note>
+
+ <sect3 xml:id="printing-advanced-filters">
+ <title>How Filters Work</title>
+
+ <para>As mentioned before, a filter is an executable program started
+ by <application>LPD</application> to handle the device-dependent part of
+ communicating with the printer.</para>
+
+ <para>When <application>LPD</application> 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 <literal>lf</literal>
+ capability in <filename>/etc/printcap</filename>, or
+ <filename>/dev/console</filename> by default).</para>
+
+ <indexterm>
+ <primary><command>troff</command></primary>
+ </indexterm>
+ <para>Which filter <application>LPD</application> starts and the
+ filter's arguments depend on
+ what is listed in the <filename>/etc/printcap</filename> file and
+ what arguments the user specified for the job on the
+ &man.lpr.1; command line. For example, if the user typed
+ <command>lpr -t</command>, <application>LPD</application> would
+ start the troff filter, listed
+ in the <literal>tf</literal> capability for the destination printer.
+ If the user wanted to print plain text, it would start the
+ <literal>if</literal> filter (this is mostly true: see <link linkend="printing-advanced-of">Output Filters</link> for
+ details).</para>
+
+ <para>There are three kinds of filters you can specify in
+ <filename>/etc/printcap</filename>:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The <emphasis>text filter</emphasis>, confusingly called the
+ <emphasis>input filter</emphasis> in
+ <application>LPD</application> documentation, handles
+ regular text printing. Think of it as the default filter.
+ <application>LPD</application>
+ 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:
+
+ <cmdsynopsis>
+ <command>filter-name</command>
+ <arg>-c</arg>
+ <arg choice="plain">-w<replaceable>width</replaceable></arg>
+ <arg choice="plain">-l<replaceable>length</replaceable></arg>
+ <arg choice="plain">-i<replaceable>indent</replaceable></arg>
+ <arg choice="plain">-n <replaceable>login</replaceable></arg>
+ <arg choice="plain">-h <replaceable>host</replaceable></arg>
+ <arg choice="plain"><replaceable>acct-file</replaceable></arg>
+ </cmdsynopsis>
+
+ where
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-c</option></term>
+
+ <listitem>
+ <para>appears if the job is submitted with <command>lpr
+ -l</command></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>width</replaceable></term>
+
+ <listitem>
+ <para>is the value from the <literal>pw</literal> (page
+ width) capability specified in
+ <filename>/etc/printcap</filename>, default 132</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>length</replaceable></term>
+
+ <listitem>
+ <para>is the value from the <literal>pl</literal> (page
+ length) capability, default 66</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>indent</replaceable></term>
+
+ <listitem>
+ <para>is the amount of the indentation from <command>lpr
+ -i</command>, default 0</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>login</replaceable></term>
+
+ <listitem>
+ <para>is the account name of the user printing the
+ file</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>host</replaceable></term>
+
+ <listitem>
+ <para>is the host name from which the job was
+ submitted</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>acct-file</replaceable></term>
+
+ <listitem>
+ <para>is the name of the accounting file from the
+ <literal>af</literal> capability.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>A <emphasis>conversion filter</emphasis><indexterm><primary>printing</primary><secondary>filters</secondary></indexterm> 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 <link linkend="printing-advanced-convfilters">Conversion
+ Filters</link> tells all about them. Conversion filters also
+ need to do accounting, if you need printer accounting.
+ Conversion filters are started with the following arguments:
+
+ <cmdsynopsis>
+ <command>filter-name</command>
+ <arg choice="plain">-x<replaceable>pixel-width</replaceable></arg>
+ <arg choice="plain">-y<replaceable>pixel-height</replaceable></arg>
+ <arg choice="plain">-n <replaceable>login</replaceable></arg>
+ <arg choice="plain">-h <replaceable>host</replaceable></arg>
+ <arg choice="plain"><replaceable>acct-file</replaceable></arg>
+ </cmdsynopsis>
+
+ where <replaceable>pixel-width</replaceable> is the value
+ from the px capability (default 0) and
+ <replaceable>pixel-height</replaceable> is the value from the
+ py capability (default 0).</para>
+ </listitem>
+
+ <listitem>
+ <para>The <emphasis>output filter</emphasis> is used only if there
+ is no text filter, or if header pages are enabled. In my
+ experience, output filters are rarely used. Section <link linkend="printing-advanced-of">Output Filters</link> describe
+ them. There are only two arguments to an output filter:
+
+ <cmdsynopsis>
+ <command>filter-name</command>
+ <arg choice="plain">-w<replaceable>width</replaceable></arg>
+ <arg choice="plain">-l<replaceable>length</replaceable></arg>
+ </cmdsynopsis>
+
+ which are identical to the text filters <option>-w</option> and
+ <option>-l</option> arguments.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Filters should also <emphasis>exit</emphasis> with the
+ following exit status:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>exit 0</term>
+
+ <listitem>
+ <para>If the filter printed the file successfully.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>exit 1</term>
+
+ <listitem>
+ <para>If the filter failed to print the file but wants
+ <application>LPD</application> to
+ try to print the file again. <application>LPD</application>
+ will restart a filter if it exits with this status.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>exit 2</term>
+
+ <listitem>
+ <para>If the filter failed to print the file and does not want
+ <application>LPD</application> to try again.
+ <application>LPD</application> will throw out the file.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>The text filter that comes with the FreeBSD release,
+ <filename>/usr/libexec/lpr/lpf</filename>, 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.</para>
+
+ <para>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.</para>
+ </sect3>
+
+ <sect3 xml:id="printing-advanced-if-conversion">
+ <title>Accommodating Plain Text Jobs on &postscript; Printers</title>
+ <indexterm><primary>print jobs</primary></indexterm>
+
+ <para>If 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.</para>
+
+ <para>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
+ <literal>%!</literal> (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.</para>
+
+ <para>How do we do this?</para>
+
+ <indexterm>
+ <primary>printers</primary>
+ <secondary>serial</secondary>
+ </indexterm>
+ <para>If you have got a serial printer, a great way to do it is to
+ install <command>lprps</command>. <command>lprps</command> 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 <errorname>toner
+ low</errorname> or <errorname>paper jam</errorname>). But more
+ importantly, it includes a program called <command>psif</command>
+ which detects whether the incoming job is plain text and calls
+ <command>textps</command> (another program that comes with
+ <command>lprps</command>) to convert it to &postscript;. It then uses
+ <command>lprps</command> to send the job to the printer.</para>
+
+ <para><command>lprps</command> is part of the FreeBSD Ports Collection
+ (see <link linkend="ports">The Ports Collection</link>). You can
+ fetch, build and install it yourself, of course. After installing
+ <command>lprps</command>, just specify the pathname to the
+ <command>psif</command> program that is part of
+ <command>lprps</command>. If you installed <command>lprps</command>
+ from the Ports Collection, use the following in the serial
+ &postscript; printer's entry in
+ <filename>/etc/printcap</filename>:</para>
+
+ <programlisting>:if=/usr/local/libexec/psif:</programlisting>
+
+ <para>You should also specify the <literal>rw</literal> capability;
+ that tells <application>LPD</application> to open the printer in
+ read-write mode.</para>
+
+ <para>If you have a parallel &postscript; printer (and therefore cannot
+ use two-way communication with the printer, which
+ <command>lprps</command> needs), you can use the following shell
+ script as the text filter:</para>
+
+ <programlisting>#!/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" &amp;&amp; cat &amp;&amp; printf "\004" &amp;&amp; exit 0
+ exit 2
+else
+ #
+ # Plain text, convert it, then print it.
+ #
+ ( echo "$first_line"; cat ) | /usr/local/bin/textps &amp;&amp; printf "\004" &amp;&amp; exit 0
+ exit 2
+fi</programlisting>
+
+ <para>In the above script, <command>textps</command> 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 <link linkend="ports">The Ports Collection</link>)
+ includes a full featured text-to-&postscript; program called
+ <literal>a2ps</literal> that you might want to investigate.</para>
+ </sect3>
+
+ <sect3 xml:id="printing-advanced-ps">
+ <title>Simulating &postscript; on Non &postscript; Printers</title>
+ <indexterm>
+ <primary>PostScript</primary>
+ <secondary>emulating</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>Ghostscript</primary></indexterm>
+ <para>&postscript; is the <emphasis>de facto</emphasis> standard for
+ high quality typesetting and printing. &postscript; is, however, an
+ <emphasis>expensive</emphasis> standard. Thankfully, Aladdin
+ Enterprises has a free &postscript; work-alike called
+ <application>Ghostscript</application> 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.</para>
+
+ <para>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.</para>
+
+ <para>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.</para>
+
+ <para>Here is an example: the following script is a text filter
+ for Hewlett Packard DeskJet 500 printers. For other printers,
+ substitute the <option>-sDEVICE</option> argument to the
+ <command>gs</command> (Ghostscript) command. (Type <command>gs
+ -h</command> to get a list of devices the current installation of
+ Ghostscript supports.)</para>
+
+ <programlisting>#!/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&amp;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=- - &amp;&amp; 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" &amp;&amp; cat &amp;&amp; printf "\033&amp;l0H" &amp;&amp;
+exit 0
+fi
+
+exit 2</programlisting>
+
+ <para>Finally, you need to notify <application>LPD</application> of
+ the filter via the <literal>if</literal> capability:</para>
+
+ <programlisting>:if=/usr/local/libexec/ifhp:</programlisting>
+
+ <para>That is it. You can type <command>lpr plain.text</command> and
+ <filename>lpr whatever.ps</filename> and both should print
+ successfully.</para>
+ </sect3>
+
+ <sect3 xml:id="printing-advanced-convfilters">
+ <title>Conversion Filters</title>
+
+ <para>After completing the simple setup described in <link linkend="printing-simple">Simple Printer Setup</link>, the first
+ thing you will probably want to do is install conversion filters for
+ your favorite file formats (besides plain ASCII text).</para>
+
+ <sect4>
+ <title>Why Install Conversion Filters?</title>
+ <indexterm>
+ <primary>&tex;</primary>
+ <secondary>printing DVI files</secondary>
+ </indexterm>
+
+ <para>Conversion 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:</para>
+
+ <screen>&prompt.user; <userinput>dvips seaweed-analysis.dvi</userinput>
+&prompt.user; <userinput>lpr seaweed-analysis.ps</userinput></screen>
+
+ <para>By installing a conversion filter for DVI files, we can skip
+ the hand conversion step each time by having
+ <application>LPD</application> do it for us.
+ Now, each time we get a DVI file, we are just one step away from
+ printing it:</para>
+
+ <screen>&prompt.user; <userinput>lpr -d seaweed-analysis.dvi</userinput></screen>
+
+ <para>We got <application>LPD</application> to do the DVI file
+ conversion for us by specifying
+ the <option>-d</option> option. Section <link linkend="printing-lpr-options-format">Formatting and Conversion
+ Options</link> lists the conversion options.</para>
+
+ <para>For each of the conversion options you want a printer to
+ support, install a <emphasis>conversion filter</emphasis> and
+ specify its pathname in <filename>/etc/printcap</filename>. A
+ conversion filter is like the text filter for the simple printer
+ setup (see section <link linkend="printing-textfilter">Installing
+ the Text Filter</link>) except that instead of printing plain
+ text, the filter converts the file into a format the printer can
+ understand.</para>
+ </sect4>
+
+ <sect4>
+ <title>Which Conversion Filters Should I Install?</title>
+
+ <para>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.</para>
+
+ <para>The following table summarizes the filters that
+ <application>LPD</application> works
+ with, their capability entries for the
+ <filename>/etc/printcap</filename> file, and how to invoke them
+ with the <command>lpr</command> command:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>File type</entry>
+ <entry><filename>/etc/printcap</filename> capability</entry>
+ <entry><command>lpr</command> option</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>cifplot</entry>
+ <entry><literal>cf</literal></entry>
+ <entry><option>-c</option></entry>
+ </row>
+
+ <row>
+ <entry>DVI</entry>
+ <entry><literal>df</literal></entry>
+ <entry><option>-d</option></entry>
+ </row>
+
+ <row>
+ <entry>plot</entry>
+ <entry><literal>gf</literal></entry>
+ <entry><option>-g</option></entry>
+ </row>
+
+ <row>
+ <entry>ditroff</entry>
+ <entry><literal>nf</literal></entry>
+ <entry><option>-n</option></entry>
+ </row>
+
+ <row>
+ <entry>FORTRAN text</entry>
+ <entry><literal>rf</literal></entry>
+ <entry><option>-f</option></entry>
+ </row>
+
+ <row>
+ <entry>troff</entry>
+ <entry><literal>tf</literal></entry>
+ <entry><option>-f</option></entry>
+ </row>
+
+ <row>
+ <entry>raster</entry>
+ <entry><literal>vf</literal></entry>
+ <entry><option>-v</option></entry>
+ </row>
+
+ <row>
+ <entry>plain text</entry>
+ <entry><literal>if</literal></entry>
+ <entry>none, <option>-p</option>, or
+ <option>-l</option></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>In our example, using <command>lpr -d</command> means the
+ printer needs a <literal>df</literal> capability in its entry in
+ <filename>/etc/printcap</filename>.</para>
+
+ <indexterm><primary>FORTRAN</primary></indexterm>
+ <para>Despite 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
+ <literal>gf</literal> capability and then educate your users that
+ <command>lpr -g</command> mean <quote>print Printerleaf
+ files.</quote></para>
+ </sect4>
+
+ <sect4>
+ <title>Installing Conversion Filters</title>
+
+ <para>Since conversion filters are programs you install outside of
+ the base FreeBSD installation, they should probably go under
+ <filename>/usr/local</filename>. The directory
+ <filename>/usr/local/libexec</filename> is a popular location,
+ since they are specialized programs that only
+ <application>LPD</application> will run;
+ regular users should not ever need to run them.</para>
+
+ <para>To enable a conversion filter, specify its pathname under the
+ appropriate capability for the destination printer in
+ <filename>/etc/printcap</filename>.</para>
+
+ <para>In our example, we will add the DVI conversion filter to the
+ entry for the printer named <literal>bamboo</literal>. Here is
+ the example <filename>/etc/printcap</filename> file again, with
+ the new <literal>df</literal> capability for the printer
+ <literal>bamboo</literal>.</para>
+
+ <programlisting>#
+# /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:</programlisting>
+
+ <para>The DVI filter is a shell script named
+ <filename>/usr/local/libexec/psdf</filename>. Here is that
+ script:</para>
+
+ <programlisting>#!/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 "$@"</programlisting>
+
+ <para>This script runs <command>dvips</command> in filter mode (the
+ <option>-f</option> argument) on standard input, which is the job
+ to print. It then starts the &postscript; printer filter
+ <command>lprps</command> (see section <link linkend="printing-advanced-if-conversion">Accommodating Plain
+ Text Jobs on &postscript; Printers</link>) with the arguments
+ <application>LPD</application>
+ passed to this script. <command>lprps</command> will use those
+ arguments to account for the pages printed.</para>
+ </sect4>
+
+ <sect4>
+ <title>More Conversion Filter Examples</title>
+
+ <para>Since 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.</para>
+
+ <para>This example script is a raster (well, GIF file, actually)
+ conversion filter for a Hewlett Packard LaserJet III-Si
+ printer:</para>
+
+ <programlisting>#!/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 \
+ &amp;&amp; exit 0 \
+ || exit 2</programlisting>
+
+ <para>It 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.</para>
+
+ <para>Here is the <filename>/etc/printcap</filename> file with an
+ entry for a printer using the above filter:</para>
+
+ <programlisting>#
+# /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:</programlisting>
+
+ <para>The following script is a conversion filter for troff data
+ from the groff typesetting system for the &postscript; printer named
+ <literal>bamboo</literal>:</para>
+
+ <programlisting>#!/bin/sh
+#
+# pstf - Convert groff's troff data into PS, then print.
+# Installed in /usr/local/libexec/pstf
+#
+exec grops | /usr/local/libexec/lprps "$@"</programlisting>
+
+ <para>The above script makes use of <command>lprps</command> again
+ to handle the communication with the printer. If the printer were
+ on a parallel port, we would use this script instead:</para>
+
+ <programlisting>#!/bin/sh
+#
+# pstf - Convert groff's troff data into PS, then print.
+# Installed in /usr/local/libexec/pstf
+#
+exec grops</programlisting>
+
+ <para>That is it. Here is the entry we need to add to
+ <filename>/etc/printcap</filename> to enable the filter:</para>
+
+ <programlisting>:tf=/usr/local/libexec/pstf:</programlisting>
+
+ <para>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
+ <literal>teak</literal>:</para>
+
+ <programlisting>#!/bin/sh
+#
+# hprf - FORTRAN text filter for LaserJet 3si:
+# Installed in /usr/local/libexec/hprf
+#
+
+printf "\033&amp;k2G" &amp;&amp; fpr &amp;&amp; printf "\033&amp;l0H" &amp;&amp;
+ exit 0
+exit 2</programlisting>
+
+ <para>And we will add this line to the
+ <filename>/etc/printcap</filename> for the printer
+ <literal>teak</literal> to enable this filter:</para>
+
+ <programlisting>:rf=/usr/local/libexec/hprf:</programlisting>
+
+ <para>Here is one final, somewhat complex example. We will add a
+ DVI filter to the LaserJet printer <literal>teak</literal>
+ introduced earlier. First, the easy part: updating
+ <filename>/etc/printcap</filename> with the location of the DVI
+ filter:</para>
+
+ <programlisting>:df=/usr/local/libexec/hpdf:</programlisting>
+
+ <para>Now, for the hard part: making the filter. For that, we need
+ a DVI-to-LaserJet/PCL conversion program. The FreeBSD Ports
+ Collection (see <link linkend="ports">The Ports Collection</link>)
+ has one: <command>dvi2xx</command> is the name of the package.
+ Installing this package gives us the program we need,
+ <command>dvilj2p</command>, which converts DVI into LaserJet IIp,
+ LaserJet III, and LaserJet 2000 compatible codes.</para>
+
+ <para><command>dvilj2p</command> makes the filter
+ <command>hpdf</command> quite complex since
+ <command>dvilj2p</command> cannot read from standard input. It
+ wants to work with a filename. What is worse, the filename has to
+ end in <filename>.dvi</filename> so using
+ <filename>/dev/fd/0</filename> for standard input is problematic.
+ We can get around that problem by linking (symbolically) a
+ temporary file name (one that ends in <filename>.dvi</filename>)
+ to <filename>/dev/fd/0</filename>, thereby forcing
+ <command>dvilj2p</command> to read from standard input.</para>
+
+ <para>The only other fly in the ointment is the fact that we cannot
+ use <filename>/tmp</filename> for the temporary link. Symbolic
+ links are owned by user and group <systemitem class="username">bin</systemitem>. The
+ filter runs as user <systemitem class="username">daemon</systemitem>. And the
+ <filename>/tmp</filename> 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.</para>
+
+ <para>Instead, the filter will make the symbolic link in the current
+ working directory, which is the spooling directory (specified by
+ the <literal>sd</literal> capability in
+ <filename>/etc/printcap</filename>). 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
+ <filename>/tmp</filename>.</para>
+
+ <para>Here, finally, is the filter:</para>
+
+ <programlisting>#!/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&gt;&amp;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&amp;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 0</programlisting>
+ </sect4>
+
+ <sect4 xml:id="printing-advanced-autoconv">
+ <title>Automated Conversion: an Alternative to Conversion
+ Filters</title>
+
+ <para>All 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.</para>
+
+ <para>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
+ <command>file</command> can be of help here. Of course, it will
+ be hard to determine the differences between
+ <emphasis>some</emphasis> file types&mdash;and, of course, you can
+ still provide conversion filters just for them.</para>
+
+ <indexterm><primary>apsfilter</primary></indexterm>
+ <indexterm>
+ <primary>printing</primary>
+ <secondary>filters</secondary>
+ <tertiary>apsfilter</tertiary>
+ </indexterm>
+ <para>The FreeBSD Ports Collection has a text filter that performs
+ automatic conversion called <command>apsfilter</command>. It can
+ detect plain text, &postscript;, and DVI files, run the proper
+ conversions, and print.</para>
+ </sect4>
+ </sect3>
+
+ <sect3 xml:id="printing-advanced-of">
+ <title>Output Filters</title>
+
+ <para>The <application>LPD</application> 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:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><application>LPD</application> starts an output filter once
+ for the entire job instead
+ of once for each file in the job.</para>
+ </listitem>
+
+ <listitem>
+ <para><application>LPD</application> does not make any provision
+ to identify the start or the
+ end of files within the job for the output filter.</para>
+ </listitem>
+
+ <listitem>
+ <para><application>LPD</application> 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:</para>
+
+ <cmdsynopsis>
+ <command>filter-name</command>
+ <arg choice="plain">-w<replaceable>width</replaceable></arg>
+ <arg choice="plain">-l<replaceable>length</replaceable></arg>
+ </cmdsynopsis>
+
+ <para>Where <replaceable>width</replaceable> is from the
+ <literal>pw</literal> capability and
+ <replaceable>length</replaceable> is from the
+ <literal>pl</literal> capability for the printer in
+ question.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>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 <emphasis>will not work</emphasis>. Use a text filter (also
+ known as an input filter); see section <link linkend="printing-textfilter">Installing the Text Filter</link>.
+ Furthermore, an output filter is actually <emphasis>more
+ complex</emphasis> 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 <application>LPD</application>.</para>
+
+ <para>However, an output filter is <emphasis>necessary</emphasis> 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 <emphasis>futile</emphasis> if you want to charge header
+ pages to the requesting user's account, since
+ <application>LPD</application> does not give any
+ user or host information to the output filter.)</para>
+
+ <para>On a single printer, <application>LPD</application>
+ allows both an output filter and text or other filters. In
+ such cases, <application>LPD</application> will start the
+ output filter
+ to print the header page (see section <link linkend="printing-advanced-header-pages">Header Pages</link>)
+ only. <application>LPD</application> then expects the
+ output filter to <emphasis>stop
+ itself</emphasis> 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 <literal>SIGSTOP</literal>
+ to itself. When
+ <application>LPD</application>'s
+ done running other filters, it will restart the output filter by
+ sending <literal>SIGCONT</literal> to it.</para>
+
+ <para>If there is an output filter but <emphasis>no</emphasis> text
+ filter and <application>LPD</application> is working on a plain
+ text job, <application>LPD</application> 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
+ <emphasis>not</emphasis> what you want. In almost all cases, you
+ need a text filter.</para>
+
+ <para>The program <command>lpf</command>, 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 <command>lpf</command>. You
+ can also wrap <command>lpf</command> in a shell script to handle any
+ initialization codes the printer might require.</para>
+ </sect3>
+
+ <sect3 xml:id="printing-advanced-lpf">
+ <title><command>lpf</command>: a Text Filter</title>
+
+ <para>The program <filename>/usr/libexec/lpr/lpf</filename> that comes
+ with FreeBSD binary distribution is a text filter (input filter)
+ that can indent output (job submitted with <command>lpr
+ -i</command>), allow literal characters to pass (job submitted
+ with <command>lpr -l</command>), adjust the printing position for
+ backspaces and tabs in the job, and account for pages printed. It
+ can also act like an output filter.</para>
+
+ <para><command>lpf</command> 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
+ <command>lpf</command>.</para>
+
+ <indexterm><primary>page accounting</primary></indexterm>
+ <indexterm>
+ <primary>accounting</primary>
+ <secondary>printer</secondary>
+ </indexterm>
+ <para>In order for <command>lpf</command> to do page accounting
+ correctly, it needs correct values filled in for the
+ <literal>pw</literal> and <literal>pl</literal> capabilities in the
+ <filename>/etc/printcap</filename> 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 <link linkend="printing-advanced-acct">Accounting for Printer
+ Usage</link>.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="printing-advanced-header-pages">
+ <title>Header Pages</title>
+
+ <para>If you have <emphasis>lots</emphasis> of users, all of them using
+ various printers, then you probably want to consider <emphasis>header
+ pages</emphasis> as a necessary evil.</para>
+
+ <indexterm>
+ <primary>banner pages</primary>
+ <see>header pages</see>
+ </indexterm>
+ <indexterm><primary>header pages</primary></indexterm>
+ <para>Header pages, also known as <emphasis>banner</emphasis> or
+ <emphasis>burst pages</emphasis> 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.)</para>
+
+ <para>The <application>LPD</application> system can provide header
+ pages automatically for your
+ printouts <emphasis>if</emphasis> 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 <link linkend="printing-advanced-header-pages-ps">Header Pages on
+ &postscript; Printers</link>.</para>
+
+ <sect3 xml:id="printing-advanced-header-pages-enabling">
+ <title>Enabling Header Pages</title>
+
+ <para>In the <link linkend="printing-simple">Simple Printer
+ Setup</link> section, we turned off header pages by specifying
+ <literal>sh</literal> (meaning <quote>suppress header</quote>) in the
+ <filename>/etc/printcap</filename> file. To enable header pages for
+ a printer, just remove the <literal>sh</literal> capability.</para>
+
+ <para>Sounds too easy, right?</para>
+
+ <para>You are right. You <emphasis>might</emphasis> 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:</para>
+
+ <programlisting>#!/bin/sh
+#
+# hpof - Output filter for Hewlett Packard PCL-compatible printers
+# Installed in /usr/local/libexec/hpof
+
+printf "\033&amp;k2G" || exit 2
+exec /usr/libexec/lpr/lpf</programlisting>
+
+ <para>Specify the path to the output filter in the
+ <literal>of</literal> capability. See the <link linkend="printing-advanced-of">Output Filters</link> section for more
+ information.</para>
+
+ <para>Here is an example <filename>/etc/printcap</filename> file for
+ the printer <literal>teak</literal> that we introduced earlier; we
+ enabled header pages and added the above output filter:</para>
+
+ <programlisting>#
+# /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:</programlisting>
+
+ <para>Now, when users print jobs to <literal>teak</literal>, 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 <command>lpr -h</command>; see the <link linkend="printing-lpr-options-misc">Header Page Options</link> section for
+ more &man.lpr.1; options.</para>
+
+ <note>
+ <para><application>LPD</application> 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 <literal>ff</literal>
+ capability in <filename>/etc/printcap</filename>.</para>
+ </note>
+ </sect3>
+
+ <sect3 xml:id="printing-advanced-header-pages-controlling">
+ <title>Controlling Header Pages</title>
+
+ <para>By enabling header pages, <application>LPD</application> will
+ produce a <emphasis>long
+ header</emphasis>, a full page of large letters identifying the
+ user, host, and job. Here is an example (kelly printed the job
+ named outline from host <systemitem>rose</systemitem>):</para>
+
+ <programlisting> 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 1995</programlisting>
+
+ <para><application>LPD</application> appends a form feed after this
+ text so the job starts on a
+ new page (unless you have <literal>sf</literal> (suppress form
+ feeds) in the destination printer's entry in
+ <filename>/etc/printcap</filename>).</para>
+
+ <para>If you prefer, <application>LPD</application> can make a
+ <emphasis>short header</emphasis>;
+ specify <literal>sb</literal> (short banner) in the
+ <filename>/etc/printcap</filename> file. The header page will look
+ like this:</para>
+
+ <programlisting>rose:kelly Job: outline Date: Sun Sep 17 11:07:51 1995</programlisting>
+
+ <para>Also by default, <application>LPD</application> prints the
+ header page first, then the job.
+ To reverse that, specify <literal>hl</literal> (header last) in
+ <filename>/etc/printcap</filename>.</para>
+ </sect3>
+
+ <sect3 xml:id="printing-advanced-header-pages-accounting">
+ <title>Accounting for Header Pages</title>
+
+ <para>Using <application>LPD</application>'s built-in header pages
+ enforces a particular paradigm
+ when it comes to printer accounting: header pages must be
+ <emphasis>free of charge</emphasis>.</para>
+
+ <para>Why?</para>
+
+ <para>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 <emphasis>user or
+ host</emphasis> information or an accounting file, so it has no
+ idea whom to charge for printer use. It is also not enough to just
+ <quote>add one page</quote> to the text filter or any of the
+ conversion filters (which do have user and host information) since
+ users can suppress header pages with <command>lpr -h</command>.
+ They could still be charged for header pages they did not print.
+ Basically, <command>lpr -h</command> will be the preferred option of
+ environmentally-minded users, but you cannot offer any incentive to
+ use it.</para>
+
+ <para>It is <emphasis>still not enough</emphasis> 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 <command>lpr -h</command>, they will still get
+ them and be charged for them since <application>LPD</application>
+ does not pass any knowledge
+ of the <option>-h</option> option to any of the filters.</para>
+
+ <para>So, what are your options?</para>
+
+ <para>You can:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Accept <application>LPD</application>'s paradigm and make
+ header pages free.</para>
+ </listitem>
+
+ <listitem>
+ <para>Install an alternative to <application>LPD</application>,
+ such as
+ <application>LPRng</application>. Section
+ <link linkend="printing-lpd-alternatives">Alternatives to the
+ Standard Spooler</link> tells more about other spooling
+ software you can substitute for <application>LPD</application>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>Write a <emphasis>smart</emphasis> 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 <application>LPD</application> will start
+ the output filter only for
+ the header pages. And the output filter can parse the header
+ page text that <application>LPD</application> 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 <literal>af</literal> 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
+ <literal>sh</literal> (short header) capability in
+ <filename>/etc/printcap</filename>. Then again, all that might
+ be too much trouble, and users will certainly appreciate the
+ more generous system administrator who makes header pages
+ free.</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+
+ <sect3 xml:id="printing-advanced-header-pages-ps">
+ <title>Header Pages on &postscript; Printers</title>
+
+ <para>As described above, <application>LPD</application> 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
+ <application>LPD</application> is
+ useless&mdash;or mostly so.</para>
+
+ <para>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 <command>lpr
+ -h</command>.</para>
+
+ <para>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:</para>
+
+ <programlisting>#!/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` &lt;user&gt; &lt;host&gt; &lt;job&gt;" 1&gt;&amp;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 &lt;&lt;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
+EOF</programlisting>
+
+ <para>Now, 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:</para>
+
+ <programlisting>#!/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&gt;&amp;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&gt;&amp;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_args</programlisting>
+
+ <para>Notice 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 <link linkend="printing-advanced-filters">How Filters
+ Work</link>).</para>
+
+ <para>As we have mentioned before, the above scheme, though fairly
+ simple, disables the <quote>suppress header page</quote> option (the
+ <option>-h</option> option) to <command>lpr</command>. 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.</para>
+
+ <para>To allow users to shut off header pages on a per-job basis, you
+ will need to use the trick introduced in section <link linkend="printing-advanced-header-pages-accounting">Accounting for
+ Header Pages</link>: write an output filter that parses the
+ LPD-generated header page and produces a &postscript; version. If the
+ user submits the job with <command>lpr -h</command>, then
+ <application>LPD</application> will
+ not generate a header page, and neither will your output filter.
+ Otherwise, your output filter will read the text from
+ <application>LPD</application> and send
+ the appropriate header page &postscript; code to the printer.</para>
+
+ <para>If you have a &postscript; printer on a serial line, you can make
+ use of <command>lprps</command>, which comes with an output filter,
+ <command>psof</command>, which does the above. Note that
+ <command>psof</command> does not charge for header pages.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="printing-advanced-network-printers">
+ <title>Networked Printing</title>
+
+ <indexterm>
+ <primary>printers</primary>
+ <secondary>network</secondary>
+ </indexterm>
+ <indexterm><primary>network printing</primary></indexterm>
+ <para>FreeBSD supports networked printing: sending jobs to remote
+ printers. Networked printing generally refers to two different
+ things:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>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 <application>LPD</application> to
+ enable access to the printer
+ from other hosts on the network. Section <link linkend="printing-advanced-network-rm">Printers Installed on
+ Remote Hosts</link> tells how to do this.</para>
+ </listitem>
+
+ <listitem>
+ <para>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:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>It might understand the <application>LPD</application>
+ protocol and can even queue
+ jobs from remote hosts. In this case, it acts just like a
+ regular host running <application>LPD</application>. Follow
+ the same procedure in
+ section <link linkend="printing-advanced-network-rm">Printers
+ Installed on Remote Hosts</link> to set up such a
+ printer.</para>
+ </listitem>
+
+ <listitem>
+ <para>It might support a data stream network connection. In this
+ case, you <quote>attach</quote> the printer to one host on the
+ network by making that host responsible for spooling jobs and
+ sending them to the printer. Section <link linkend="printing-advanced-network-net-if">Printers with
+ Networked Data Stream Interfaces</link> gives some
+ suggestions on installing such printers.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+
+ <sect3 xml:id="printing-advanced-network-rm">
+ <title>Printers Installed on Remote Hosts</title>
+
+ <para>The <application>LPD</application> spooling system has built-in
+ support for sending jobs to
+ other hosts also running <application>LPD</application> (or are
+ compatible with <application>LPD</application>). 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
+ <application>LPD</application> protocol.</para>
+
+ <para>To enable this kind of remote printing, first install a printer
+ on one host, the <emphasis>printer host</emphasis>, using the simple
+ printer setup described in the <link linkend="printing-simple">Simple
+ Printer Setup</link> section. Do any advanced setup in <link linkend="printing-advanced">Advanced Printer Setup</link> that you
+ need. Make sure to test the printer and see if it works with the
+ features of <application>LPD</application> you have enabled.
+ Also ensure that the
+ <emphasis>local host</emphasis> has authorization to use the
+ <application>LPD</application>
+ service in the <emphasis>remote host</emphasis> (see <link linkend="printing-advanced-restricting-remote">Restricting Jobs
+ from Remote Printers</link>).</para>
+
+ <indexterm>
+ <primary>printers</primary>
+ <secondary>network</secondary>
+ </indexterm>
+ <indexterm><primary>network printing</primary></indexterm>
+ <para>If you are using a printer with a network interface that is
+ compatible with <application>LPD</application>, then the
+ <emphasis>printer host</emphasis> in
+ the discussion below is the printer itself, and the
+ <emphasis>printer name</emphasis> is the name you configured for the
+ printer. See the documentation that accompanied your printer and/or
+ printer-network interface.</para>
+
+ <tip>
+ <para>If you are using a Hewlett Packard Laserjet then the printer
+ name <literal>text</literal> will automatically perform the LF to
+ CRLF conversion for you, so you will not require the
+ <filename>hpif</filename> script.</para>
+ </tip>
+
+ <para>Then, on the other hosts you want to have access to the printer,
+ make an entry in their <filename>/etc/printcap</filename> files with
+ the following:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Name the entry anything you want. For simplicity, though,
+ you probably want to use the same name and aliases as on the
+ printer host.</para>
+ </listitem>
+
+ <listitem>
+ <para>Leave the <literal>lp</literal> capability blank, explicitly
+ (<literal>:lp=:</literal>).</para>
+ </listitem>
+
+ <listitem>
+ <para>Make a spooling directory and specify its location in the
+ <literal>sd</literal> capability. <application>LPD</application>
+ will store jobs here
+ before they get sent to the printer host.</para>
+ </listitem>
+
+ <listitem>
+ <para>Place the name of the printer host in the
+ <literal>rm</literal> capability.</para>
+ </listitem>
+
+ <listitem>
+ <para>Place the printer name on the <emphasis>printer
+ host</emphasis> in the <literal>rp</literal>
+ capability.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>That is it. You do not need to list conversion filters, page
+ dimensions, or anything else in the
+ <filename>/etc/printcap</filename> file.</para>
+
+ <para>Here is an example. The host <systemitem>rose</systemitem> has two
+ printers, <literal>bamboo</literal> and <literal>rattan</literal>.
+ We will enable users on the host <systemitem>orchid</systemitem> to print
+ to those printers.
+ Here is the <filename>/etc/printcap</filename> file for
+ <systemitem>orchid</systemitem> (back from section <link linkend="printing-advanced-header-pages-enabling">Enabling Header
+ Pages</link>). It already had the entry for the printer
+ <literal>teak</literal>; we have added entries for the two printers
+ on the host <systemitem>rose</systemitem>:</para>
+
+ <programlisting>#
+# /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:</programlisting>
+
+ <para>Then, we just need to make spooling directories on
+ <systemitem>orchid</systemitem>:</para>
+
+ <screen>&prompt.root; <userinput>mkdir -p /var/spool/lpd/rattan /var/spool/lpd/bamboo</userinput>
+&prompt.root; <userinput>chmod 770 /var/spool/lpd/rattan /var/spool/lpd/bamboo</userinput>
+&prompt.root; <userinput>chown daemon:daemon /var/spool/lpd/rattan /var/spool/lpd/bamboo</userinput></screen>
+
+ <para>Now, users on <systemitem>orchid</systemitem> can print to
+ <literal>rattan</literal> and <literal>bamboo</literal>. If, for
+ example, a user on <systemitem>orchid</systemitem> typed
+
+ <screen>&prompt.user; <userinput>lpr -P bamboo -d sushi-review.dvi</userinput></screen>
+
+ the <application>LPD</application> system on <systemitem>orchid</systemitem>
+ would copy the job to the spooling
+ directory <filename>/var/spool/lpd/bamboo</filename> and note that it was a
+ DVI job. As soon as the host <systemitem>rose</systemitem> has room in its
+ <literal>bamboo</literal> spooling directory, the two
+ <application>LPDs</application> would transfer the
+ file to <systemitem>rose</systemitem>. The file would wait in <systemitem>rose</systemitem>'s
+ queue until it was finally printed. It would be converted from DVI to
+ &postscript; (since <literal>bamboo</literal> is a &postscript; printer) on
+ <systemitem>rose</systemitem>.</para>
+ </sect3>
+
+ <sect3 xml:id="printing-advanced-network-net-if">
+ <title>Printers with Networked Data Stream Interfaces</title>
+
+ <para>Often, 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 <link linkend="printing-advanced-network-rm">Printers Installed on
+ Remote Hosts</link>.</para>
+
+ <para>The format of the <filename>/etc/printcap</filename> 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.</para>
+
+ <para>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
+ <command>netprint</command> 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 <command>netprint</command>. 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.).</para>
+
+ <programlisting>#!/usr/bin/perl
+#
+# netprint - Text filter for printer attached to network
+# Installed in /usr/local/libexec/netprint
+#
+$#ARGV eq 1 || die "Usage: $0 &lt;printer-hostname&gt; &lt;port-number&gt;";
+
+$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', &amp;AF_INET, $printer_port, $address);
+
+socket(PRINTER, &amp;PF_INET, &amp;SOCK_STREAM, $protocol)
+ || die "Can't create TCP/IP stream socket: $!";
+connect(PRINTER, $sockaddr) || die "Can't contact $printer_host: $!";
+while (&lt;STDIN&gt;) { print PRINTER; }
+exit 0;</programlisting>
+
+ <para>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:</para>
+
+ <programlisting>#!/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 5100</programlisting>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="printing-advanced-restricting">
+ <title>Restricting Printer Usage</title>
+
+ <indexterm>
+ <primary>printers</primary>
+ <secondary>restricting access to</secondary>
+ </indexterm>
+ <para>This section gives information on restricting printer usage. The
+ <application>LPD</application> 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.</para>
+
+ <sect3 xml:id="printing-advanced-restricting-copies">
+ <title>Restricting Multiple Copies</title>
+
+ <para>The <application>LPD</application> system makes it easy for
+ users to print multiple copies
+ of a file. Users can print jobs with <command>lpr -#5</command>
+ (for example) and get five copies of each file in the job. Whether
+ this is a good thing is up to you.</para>
+
+ <para>If you feel multiple copies cause unnecessary wear and tear on
+ your printers, you can disable the <option>-#</option> option to
+ &man.lpr.1; by adding the <literal>sc</literal> capability to the
+ <filename>/etc/printcap</filename> file. When users submit jobs
+ with the <option>-#</option> option, they will see:</para>
+
+ <screen>lpr: multiple copies are not allowed</screen>
+
+
+ <para>Note that if you have set up access to a printer remotely (see
+ section <link linkend="printing-advanced-network-rm">Printers
+ Installed on Remote Hosts</link>), you need the
+ <literal>sc</literal> capability on the remote
+ <filename>/etc/printcap</filename> files as well, or else users will
+ still be able to submit multiple-copy jobs by using another
+ host.</para>
+
+ <para>Here is an example. This is the
+ <filename>/etc/printcap</filename> file for the host
+ <systemitem>rose</systemitem>. The printer <literal>rattan</literal> is
+ quite hearty, so we will allow multiple copies, but the laser
+ printer <literal>bamboo</literal> is a bit more delicate, so we will
+ disable multiple copies by adding the <literal>sc</literal>
+ capability:</para>
+
+ <programlisting>#
+# /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:</programlisting>
+
+ <para>Now, we also need to add the <literal>sc</literal> capability on
+ the host <systemitem>orchid</systemitem>'s
+ <filename>/etc/printcap</filename> (and while we are at it, let us
+ disable multiple copies for the printer
+ <literal>teak</literal>):</para>
+
+ <programlisting>#
+# /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:</programlisting>
+
+ <para>By using the <literal>sc</literal> capability, we prevent the
+ use of <command>lpr -#</command>, 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:</para>
+
+ <screen>&prompt.user; <userinput>lpr forsale.sign forsale.sign forsale.sign forsale.sign forsale.sign</userinput></screen>
+
+ <para>There are many ways to prevent this abuse (including ignoring
+ it) which you are free to explore.</para>
+ </sect3>
+
+ <sect3 xml:id="printing-advanced-restricting-access">
+ <title>Restricting Access to Printers</title>
+
+ <para>You can control who can print to what printers by using the &unix;
+ group mechanism and the <literal>rg</literal> capability in
+ <filename>/etc/printcap</filename>. Just place the users you want
+ to have access to a printer in a certain group, and then name that
+ group in the <literal>rg</literal> capability.</para>
+
+ <para>Users outside the group (including <systemitem class="username">root</systemitem>)
+ will be greeted with
+
+ <errorname>lpr: Not a member of the restricted group</errorname>
+
+ if they try to print to the controlled printer.</para>
+
+ <para>As with the <literal>sc</literal> (suppress multiple copies)
+ capability, you need to specify <literal>rg</literal> on remote
+ hosts that also have access to your printers, if you feel it is
+ appropriate (see section <link linkend="printing-advanced-network-rm">Printers Installed on
+ Remote Hosts</link>).</para>
+
+ <para>For example, we will let anyone access the printer
+ <literal>rattan</literal>, but only those in group
+ <literal>artists</literal> can use <literal>bamboo</literal>. Here
+ is the familiar <filename>/etc/printcap</filename> for host
+ <systemitem>rose</systemitem>:</para>
+
+ <programlisting>#
+# /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:</programlisting>
+
+ <para>Let us leave the other example
+ <filename>/etc/printcap</filename> file (for the host
+ <systemitem>orchid</systemitem>) alone. Of course, anyone on
+ <systemitem>orchid</systemitem> can print to <literal>bamboo</literal>. It
+ might be the case that we only allow certain logins on
+ <systemitem>orchid</systemitem> anyway, and want them to have access to the
+ printer. Or not.</para>
+
+ <note>
+ <para>There can be only one restricted group per printer.</para>
+ </note>
+ </sect3>
+
+ <sect3 xml:id="printing-advanced-restricting-sizes">
+ <title>Controlling Sizes of Jobs Submitted</title>
+
+ <indexterm><primary>print jobs</primary></indexterm>
+ <para>If 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.</para>
+
+ <indexterm>
+ <primary>print jobs</primary>
+ <secondary>controlling</secondary>
+ </indexterm>
+ <para><application>LPD</application> enables you to limit the maximum
+ byte size a file in a job
+ can be with the <literal>mx</literal> capability. The units are in
+ <literal>BUFSIZ</literal> blocks, which are 1024 bytes. If you put
+ a zero for this
+ capability, there will be no limit on file size; however, if no
+ <literal>mx</literal> capability is specified, then a default limit
+ of 1000 blocks will be used.</para>
+
+ <note>
+ <para>The limit applies to <emphasis>files</emphasis> in a job, and
+ <emphasis>not</emphasis> the total job size.</para>
+ </note>
+
+ <para><application>LPD</application> 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.</para>
+
+ <para>Let us add limits to our example printers
+ <literal>rattan</literal> and <literal>bamboo</literal>. 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:</para>
+
+ <programlisting>#
+# /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:</programlisting>
+
+ <para>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 <literal>mx</literal>
+ capability in the remote <filename>/etc/printcap</filename> files as
+ well. See section <link linkend="printing-advanced-network-rm">Printers Installed on
+ Remote Hosts</link> for more information on remote
+ printing.</para>
+
+ <para>There is another specialized way to limit job sizes from remote
+ printers; see section <link linkend="printing-advanced-restricting-remote">Restricting Jobs
+ from Remote Printers</link>.</para>
+ </sect3>
+
+ <sect3 xml:id="printing-advanced-restricting-remote">
+ <title>Restricting Jobs from Remote Printers</title>
+
+ <para>The <application>LPD</application> spooling system provides
+ several ways to restrict print
+ jobs submitted from remote hosts:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Host restrictions</term>
+
+ <listitem>
+ <para>You can control from which remote hosts a local
+ <application>LPD</application> accepts requests with the files
+ <filename>/etc/hosts.equiv</filename> and
+ <filename>/etc/hosts.lpd</filename>.
+ <application>LPD</application> checks to see if an
+ incoming request is from a host listed in either one of these
+ files. If not, <application>LPD</application> refuses the
+ request.</para>
+
+ <para>The format of these files is simple: one host name per
+ line. Note that the file
+ <filename>/etc/hosts.equiv</filename> is also used by the
+ &man.ruserok.3; protocol, and affects programs like
+ &man.rsh.1; and &man.rcp.1;, so be careful.</para>
+
+ <para>For example, here is the
+ <filename>/etc/hosts.lpd</filename> file on the host
+ <systemitem>rose</systemitem>:</para>
+
+ <programlisting>orchid
+violet
+madrigal.fishbaum.de</programlisting>
+
+ <para>This means <systemitem>rose</systemitem> will accept requests from
+ the hosts <systemitem>orchid</systemitem>, <systemitem>violet</systemitem>,
+ and <systemitem class="fqdomainname">madrigal.fishbaum.de</systemitem>. If any
+ other host tries to access <systemitem>rose</systemitem>'s
+ <application>LPD</application>, the job will be refused.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Size restrictions</term>
+
+ <listitem>
+ <para>You can control how much free space there needs to remain
+ on the filesystem where a spooling directory resides. Make a
+ file called <filename>minfree</filename> 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.</para>
+
+ <para>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
+ <filename>minfree</filename> file.</para>
+
+ <para>For example, let us add a <filename>minfree</filename>
+ file for the printer <literal>bamboo</literal>. We examine
+ <filename>/etc/printcap</filename> to find the spooling
+ directory for this printer; here is <literal>bamboo</literal>'s
+ entry:</para>
+
+ <programlisting>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:</programlisting>
+
+ <para>The spooling directory is given in the <literal>sd</literal>
+ capability. We will make three megabytes (which is 6144 disk blocks)
+ the amount of free disk space that must exist on the filesystem for
+ <application>LPD</application> to accept remote jobs:</para>
+
+ <screen>&prompt.root; <userinput>echo 6144 &gt; /var/spool/lpd/bamboo/minfree
+ </userinput></screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>User restrictions</term>
+
+ <listitem>
+ <para>You can control which remote users can print to local
+ printers by specifying the <literal>rs</literal> capability in
+ <filename>/etc/printcap</filename>. When
+ <literal>rs</literal> appears in the entry for a
+ locally-attached printer, <application>LPD</application> will
+ accept jobs from remote
+ hosts <emphasis>if</emphasis> the user submitting the job also
+ has an account of the same login name on the local host.
+ Otherwise, <application>LPD</application> refuses the job.</para>
+
+ <para>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 <emphasis>only</emphasis> your
+ printers and not your computer resources, you can give them
+ <quote>token</quote> accounts, with no home directory and a
+ useless shell like <filename>/usr/bin/false</filename>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="printing-advanced-acct">
+ <title>Accounting for Printer Usage</title>
+
+ <indexterm>
+ <primary>accounting</primary>
+ <secondary>printer</secondary>
+ </indexterm>
+ <para>So, you need to charge for printouts. And why not? Paper and ink
+ cost money. And then there are maintenance costs&mdash;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?</para>
+
+ <para>Well, the bad news is the <application>LPD</application> 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
+ <emphasis>your</emphasis> requirements in charging for printer
+ usage.</para>
+
+ <para>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 <link linkend="printing-advanced-filter-intro">Filters</link>.</para>
+
+ <para>Generally, there are two ways to do accounting:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>Periodic accounting</emphasis> 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.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Timely accounting</emphasis> 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
+ <quote>print quotas.</quote> But this method requires some database
+ code to track users and their quotas.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The <application>LPD</application> 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.</para>
+
+ <sect3>
+ <title>Quick and Dirty Printer Accounting</title>
+
+ <para>FreeBSD comes with two programs that can get you set up with
+ simple periodic accounting right away. They are the text filter
+ <command>lpf</command>, described in section <link linkend="printing-advanced-lpf">lpf: a Text Filter</link>, and
+ &man.pac.8;, a program to gather and total
+ entries from printer accounting files.</para>
+
+ <para>As mentioned in the section on filters (<link linkend="printing-advanced-filters">Filters</link>),
+ <application>LPD</application> 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 <literal>af</literal> capability in
+ <filename>/etc/printcap</filename>, and if not specified as an
+ absolute path, is relative to the spooling directory.</para>
+
+ <para><application>LPD</application> starts <command>lpf</command>
+ with page width and length
+ arguments (from the <literal>pw</literal> and <literal>pl</literal>
+ capabilities). <command>lpf</command> 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:</para>
+
+ <programlisting>2.00 rose:andy
+3.00 rose:kelly
+3.00 orchid:mary
+5.00 orchid:mary
+2.00 orchid:zhang</programlisting>
+
+ <para>You should use a separate accounting file for each printer, as
+ <command>lpf</command> has no file locking logic built into it, and
+ two <command>lpf</command>s 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
+ <literal>af=acct</literal> in <filename>/etc/printcap</filename>.
+ Then, each accounting file will be in the spooling directory for a
+ printer, in a file named <filename>acct</filename>.</para>
+
+ <para>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 <literal>pac</literal>.
+ You will get a dollar-centric summary like the following:</para>
+
+ <screen> 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.74</screen>
+
+ <para>These are the arguments &man.pac.8; expects:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-P<replaceable>printer</replaceable></option></term>
+
+ <listitem>
+ <para>Which <replaceable>printer</replaceable> to summarize.
+ This option works only if there is an absolute path in the
+ <literal>af</literal> capability in
+ <filename>/etc/printcap</filename>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-c</option></term>
+
+ <listitem>
+ <para>Sort the output by cost instead of alphabetically by user
+ name.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-m</option></term>
+
+ <listitem>
+ <para>Ignore host name in the accounting files. With this
+ option, user <systemitem class="username">smith</systemitem> on host
+ <systemitem>alpha</systemitem> is the same user
+ <systemitem class="username">smith</systemitem> on host <systemitem>gamma</systemitem>.
+ Without, they are different users.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p<replaceable>price</replaceable></option></term>
+
+ <listitem>
+ <para>Compute charges with <replaceable>price</replaceable>
+ dollars per page or per foot instead of the price from the
+ <literal>pc</literal> capability in
+ <filename>/etc/printcap</filename>, or two cents (the
+ default). You can specify <replaceable>price</replaceable> as
+ a floating point number.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-r</option></term>
+
+ <listitem>
+ <para>Reverse the sort order.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option></term>
+
+ <listitem>
+ <para>Make an accounting summary file and truncate the
+ accounting file.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>name</replaceable>
+ <replaceable>&hellip;</replaceable></term>
+
+ <listitem>
+ <para>Print accounting information for the given user
+ <replaceable>names</replaceable> only.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>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 <command>pac -m</command>, to produce the following
+ summary:</para>
+
+ <screen> 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.74</screen>
+
+
+ <para>To compute the dollar amount due,
+ &man.pac.8; uses the <literal>pc</literal> capability in the
+ <filename>/etc/printcap</filename> 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>-p</option> option. The units for the <option>-p</option>
+ option are in dollars, though, not hundredths of cents. For
+ example,
+
+ <screen>&prompt.root; <userinput>pac -p1.50</userinput></screen>
+
+ makes each page cost one dollar and fifty cents. You can really
+ rake in the profits by using this option.</para>
+
+ <para>Finally, running <command>pac -s</command> will save the summary
+ information in a summary accounting file, which is named the same as
+ the printer's accounting file, but with <literal>_sum</literal>
+ 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.</para>
+ </sect3>
+
+ <sect3>
+ <title>How Can You Count Pages Printed?</title>
+
+ <para>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.</para>
+
+ <para>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.</para>
+
+ <para>The text filter <command>lpf</command> (introduced in <link linkend="printing-advanced-lpf">lpf: a Text Filter</link>) 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 <command>lpf</command>'s source code.</para>
+
+ <para>How do you handle other file formats, though?</para>
+
+ <para>Well, for DVI-to-LaserJet or DVI-to-&postscript; conversion, you
+ can have your filter parse the diagnostic output of
+ <command>dvilj</command> or <command>dvips</command> and look to see
+ how many pages were converted. You might be able to do similar
+ things with other file formats and conversion programs.</para>
+
+ <para>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&mdash;and the user would still get
+ charged.</para>
+
+ <para>So, what can you do?</para>
+
+ <para>There is only one <emphasis>sure</emphasis> way to do
+ <emphasis>accurate</emphasis> 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
+ <emphasis>only</emphasis>. There is no line counting nor
+ error-prone file examination required.</para>
+
+ <para>Of course, you can always be generous and make all printouts
+ free.</para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="printing-using">
+ <title>Using Printers</title>
+
+ <indexterm>
+ <primary>printers</primary>
+ <secondary>usage</secondary>
+ </indexterm>
+ <para>This section tells you how to use printers you have set up with
+ FreeBSD. Here is an overview of the user-level commands:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>&man.lpr.1;</term>
+
+ <listitem>
+ <para>Print jobs</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&man.lpq.1;</term>
+
+ <listitem>
+ <para>Check printer queues</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>&man.lprm.1;</term>
+
+ <listitem>
+ <para>Remove jobs from a printer's queue</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>There is also an administrative command, &man.lpc.8;,
+ described in the section <link linkend="printing-lpc">Administering Printers</link>, used to
+ control printers and their queues.</para>
+
+ <para>All three of the commands &man.lpr.1;, &man.lprm.1;, and &man.lpq.1;
+ accept an option <option>-P
+ <replaceable>printer-name</replaceable></option> to specify on which
+ printer/queue to operate, as listed in the
+ <filename>/etc/printcap</filename> file. This enables you to submit,
+ remove, and check on jobs for various printers. If you do not use the
+ <option>-P</option> option, then these commands use the printer
+ specified in the <envar>PRINTER</envar> environment variable. Finally,
+ if you do not have a <envar>PRINTER</envar> environment variable, these
+ commands default to the printer named <literal>lp</literal>.</para>
+
+ <para>Hereafter, the terminology <emphasis>default printer</emphasis>
+ means the printer named in the <envar>PRINTER</envar> environment
+ variable, or the printer named <literal>lp</literal> when there is no
+ <envar>PRINTER</envar> environment variable.</para>
+
+ <sect2 xml:id="printing-lpr">
+ <title>Printing Jobs</title>
+
+ <para>To print files, type:</para>
+
+ <screen>&prompt.user; <userinput>lpr filename ...</userinput></screen>
+
+ <indexterm><primary>printing</primary></indexterm>
+ <para>This 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:</para>
+
+ <screen>&prompt.user; <userinput>lpr /etc/host.conf /etc/hosts.equiv</userinput></screen>
+
+ <para>To select a specific printer, type:</para>
+
+ <screen>&prompt.user; <userinput>lpr -P printer-name filename ...</userinput></screen>
+
+ <para>This example prints a long listing of the current directory to the
+ printer named <literal>rattan</literal>:</para>
+
+ <screen>&prompt.user; <userinput>ls -l | lpr -P rattan</userinput></screen>
+
+ <para>Because no files were listed for the
+ &man.lpr.1; command, <command>lpr</command> read the data to print
+ from standard input, which was the output of the <command>ls
+ -l</command> command.</para>
+
+ <para>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 <link linkend="printing-lpr-options">Printing Options</link>.</para>
+ </sect2>
+
+ <sect2 xml:id="printing-lpq">
+ <title>Checking Jobs</title>
+
+ <indexterm><primary>print jobs</primary></indexterm>
+ <para>When you print with &man.lpr.1;, the data you wish to print is put
+ together in a package called a <quote>print job</quote>, which is sent
+ to the <application>LPD</application> 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.</para>
+
+ <para>To display the queue for the default printer, type &man.lpq.1;.
+ For a specific printer, use the <option>-P</option> option. For
+ example, the command
+
+ <screen>&prompt.user; <userinput>lpq -P bamboo</userinput></screen>
+
+ shows the queue for the printer named <literal>bamboo</literal>. Here
+ is an example of the output of the <command>lpq</command>
+ command:</para>
+
+ <screen>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 bytes</screen>
+
+ <para>This shows three jobs in the queue for <literal>bamboo</literal>.
+ The first job, submitted by user kelly, got assigned <quote>job
+ number</quote> 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 <link linkend="printing-lprm">Removing Jobs</link> for details.</para>
+
+ <para>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 <literal>active</literal>
+ under the <quote>Rank</quote> 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 <systemitem class="username">mary</systemitem>; 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.</para>
+
+ <para>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
+ <application>LPD</application> thinks the printer is doing).</para>
+
+ <para>The &man.lpq.1; command also support a <option>-l</option> option
+ to generate a detailed long listing. Here is an example of
+ <command>lpq -l</command>:</para>
+
+ <screen>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 bytes</screen>
+ </sect2>
+
+ <sect2 xml:id="printing-lprm">
+ <title>Removing Jobs</title>
+
+ <para>If 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.</para>
+
+ <para>To remove a job from the default printer, first use
+ &man.lpq.1; to find the job number. Then type:</para>
+
+ <screen>&prompt.user; <userinput>lprm job-number</userinput></screen>
+
+ <para>To remove the job from a specific printer, add the
+ <option>-P</option> option. The following command removes job number
+ 10 from the queue for the printer <literal>bamboo</literal>:</para>
+
+ <screen>&prompt.user; <userinput>lprm -P bamboo 10</userinput></screen>
+
+ <para>The &man.lprm.1; command has a few shortcuts:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>lprm -</term>
+
+ <listitem>
+ <para>Removes all jobs (for the default printer) belonging to
+ you.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>lprm <replaceable>user</replaceable></term>
+
+ <listitem>
+ <para>Removes all jobs (for the default printer) belonging to
+ <replaceable>user</replaceable>. The superuser can remove other
+ users' jobs; you can remove only your own jobs.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>lprm</term>
+
+ <listitem>
+ <para>With no job number, user name, or <option>-</option>
+ 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.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>Just use the <option>-P</option> 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 <literal>rattan</literal>:</para>
+
+ <screen>&prompt.user; <userinput>lprm -P rattan -</userinput></screen>
+
+ <note>
+ <para>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:</para>
+
+ <screen>&prompt.user; <userinput>lpr -P rattan myfile</userinput>
+&prompt.user; <userinput>rlogin orchid</userinput>
+&prompt.user; <userinput>lpq -P rattan</userinput>
+Rank Owner Job Files Total Size
+active seeyan 12 ... 49123 bytes
+2nd kelly 13 myfile 12 bytes
+&prompt.user; <userinput>lprm -P rattan 13</userinput>
+rose: Permission denied
+&prompt.user; <userinput>logout</userinput>
+&prompt.user; <userinput>lprm -P rattan 13</userinput>
+dfA013rose dequeued
+cfA013rose dequeued
+ </screen>
+ </note>
+ </sect2>
+
+ <sect2 xml:id="printing-lpr-options">
+ <title>Beyond Plain Text: Printing Options</title>
+
+ <para>The &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.</para>
+
+ <sect3 xml:id="printing-lpr-options-format">
+ <title>Formatting and Conversion Options</title>
+
+ <para>The 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.</para>
+
+ <indexterm><primary>&tex;</primary></indexterm>
+ <para>For example, the following command prints a DVI file (from the
+ &tex; typesetting system) named <filename>fish-report.dvi</filename>
+ to the printer named <literal>bamboo</literal>:</para>
+
+ <screen>&prompt.user; <userinput>lpr -P bamboo -d fish-report.dvi</userinput></screen>
+
+ <para>These 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.</para>
+
+ <note>
+ <para>All of these options except <option>-p</option> and
+ <option>-T</option> require conversion filters installed for the
+ destination printer. For example, the <option>-d</option> option
+ requires the DVI conversion filter. Section <link linkend="printing-advanced-convfilters">Conversion
+ Filters</link> gives details.</para>
+ </note>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-c</option></term>
+
+ <listitem>
+ <para>Print cifplot files.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-d</option></term>
+
+ <listitem>
+ <para>Print DVI files.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-f</option></term>
+
+ <listitem>
+ <para>Print FORTRAN text files.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-g</option></term>
+
+ <listitem>
+ <para>Print plot data.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-i <replaceable>number</replaceable></option></term>
+
+ <listitem>
+ <para>Indent the output by <replaceable>number</replaceable>
+ columns; if you omit <replaceable>number</replaceable>, indent
+ by 8 columns. This option works only with certain conversion
+ filters.</para>
+
+ <note>
+ <para>Do not put any space between the <option>-i</option> and
+ the number.</para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-l</option></term>
+
+ <listitem>
+ <para>Print literal text data, including control
+ characters.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+
+ <listitem>
+ <para>Print ditroff (device independent troff) data.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-p</term>
+
+ <listitem>
+ <para>Format plain text with &man.pr.1; before printing. See
+ &man.pr.1; for more information.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-T <replaceable>title</replaceable></option></term>
+
+ <listitem>
+ <para>Use <replaceable>title</replaceable> on the
+ &man.pr.1; header instead of the file name. This option has
+ effect only when used with the <option>-p</option>
+ option.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t</option></term>
+
+ <listitem>
+ <para>Print troff data.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+
+ <listitem>
+ <para>Print raster data.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>Here is an example: this command prints a nicely formatted
+ version of the &man.ls.1; manual page on the default printer:</para>
+
+ <screen>&prompt.user; <userinput>zcat /usr/share/man/man1/ls.1.gz | troff -t -man | lpr -t</userinput></screen>
+
+ <para>The &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 <application>LPD</application> spooler. Because we
+ used the <option>-t</option>
+ 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.</para>
+ </sect3>
+
+ <sect3 xml:id="printing-lpr-options-job-handling">
+ <title>Job Handling Options</title>
+
+ <para>The following options to &man.lpr.1; tell
+ <application>LPD</application> to handle the job
+ specially:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>-# <replaceable>copies</replaceable></term>
+
+ <listitem>
+ <para>Produce a number of <replaceable>copies</replaceable> 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
+ <link linkend="printing-advanced-restricting-copies">Restricting
+ Multiple Copies</link>.</para>
+
+ <para>This example prints three copies of
+ <filename>parser.c</filename> followed by three copies of
+ <filename>parser.h</filename> to the default printer:</para>
+
+ <screen>&prompt.user; <userinput>lpr -#3 parser.c parser.h</userinput></screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-m</term>
+
+ <listitem>
+ <para>Send mail after completing the print job. With this
+ option, the <application>LPD</application> 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.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-s</term>
+
+ <listitem>
+ <para>Do not copy the files to the spooling directory, but make
+ symbolic links to them instead.</para>
+
+ <para>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
+ <application>LPD</application>
+ will not have to copy each and every byte of your job to the
+ spooling directory.</para>
+
+ <para>There is a drawback, though: since
+ <application>LPD</application> will refer to the
+ original files directly, you cannot modify or remove them
+ until they have been printed.</para>
+
+ <note>
+ <para>If you are printing to a remote printer,
+ <application>LPD</application> will
+ eventually have to copy files from the local host to the
+ remote host, so the <option>-s</option> option will save
+ space only on the local spooling directory, not the remote.
+ It is still useful, though.</para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-r</term>
+
+ <listitem>
+ <para>Remove the files in the job after copying them to the
+ spooling directory, or after printing them with the
+ <option>-s</option> option. Be careful with this
+ option!</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3 xml:id="printing-lpr-options-misc">
+ <title>Header Page Options</title>
+
+ <para>These 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
+ <link linkend="printing-advanced-header-pages">Header Pages</link>
+ for information about setting up header pages.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>-C <replaceable>text</replaceable></term>
+
+ <listitem>
+ <para>Replace the hostname on the header page with
+ <replaceable>text</replaceable>. The hostname is normally the
+ name of the host from which the job was submitted.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-J <replaceable>text</replaceable></term>
+
+ <listitem>
+ <para>Replace the job name on the header page with
+ <replaceable>text</replaceable>. The job name is normally the
+ name of the first file of the job, or
+ <filename>stdin</filename> if you are printing standard
+ input.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-h</term>
+
+ <listitem>
+ <para>Do not print any header page.</para>
+
+ <note>
+ <para>At some sites, this option may have no effect due to the
+ way header pages are generated. See <link linkend="printing-advanced-header-pages">Header
+ Pages</link> for details.</para>
+ </note>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="printing-lpc">
+ <title>Administering Printers</title>
+
+ <para>As 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 can</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Start and stop the printers</para>
+ </listitem>
+
+ <listitem>
+ <para>Enable and disable their queues</para>
+ </listitem>
+
+ <listitem>
+ <para>Rearrange the order of the jobs in each queue.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>First, a note about terminology: if a printer is
+ <emphasis>stopped</emphasis>, it will not print anything in its queue.
+ Users can still submit jobs, which will wait in the queue until the
+ printer is <emphasis>started</emphasis> or the queue is
+ cleared.</para>
+
+ <para>If a queue is <emphasis>disabled</emphasis>, no user (except
+ <systemitem class="username">root</systemitem>) can submit jobs for the printer. An
+ <emphasis>enabled</emphasis> queue allows jobs to be submitted. A
+ printer can be <emphasis>started</emphasis> for a disabled queue, in
+ which case it will continue to print jobs in the queue until the queue
+ is empty.</para>
+
+ <para>In general, you have to have <systemitem class="username">root</systemitem> 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.</para>
+
+ <para>Here is a summary of the &man.lpc.8; commands. Most of the
+ commands take a <replaceable>printer-name</replaceable> argument to
+ tell on which printer to operate. You can use <literal>all</literal>
+ for the <replaceable>printer-name</replaceable> to mean all printers
+ listed in <filename>/etc/printcap</filename>.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><command>abort
+ printer-name</command></term>
+
+ <listitem>
+ <para>Cancel the current job and stop the printer. Users can
+ still submit jobs if the queue is enabled.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>clean
+ printer-name</command></term>
+
+ <listitem>
+ <para>Remove old files from the printer's spooling directory.
+ Occasionally, the files that make up a job are not properly
+ removed by <application>LPD</application>, 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.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>disable
+ printer-name</command></term>
+
+ <listitem>
+ <para>Disable queuing of new jobs. If the printer is running, it
+ will continue to print any jobs remaining in the queue. The
+ superuser (<systemitem class="username">root</systemitem>) can always submit jobs,
+ even to a disabled queue.</para>
+
+ <para>This command is useful while you are testing a new printer
+ or filter installation: disable the queue and submit jobs as
+ <systemitem class="username">root</systemitem>. Other users will not be able to submit
+ jobs until you complete your testing and re-enable the queue with
+ the <command>enable</command> command.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>down printer-name
+ message</command></term>
+
+ <listitem>
+ <para>Take a printer down. Equivalent to
+ <command>disable</command> followed by <command>stop</command>.
+ The <replaceable>message</replaceable> appears as the printer's
+ status whenever a user checks the printer's queue with
+ &man.lpq.1; or status with <command>lpc
+ status</command>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>enable
+ printer-name</command></term>
+
+ <listitem>
+ <para>Enable the queue for a printer. Users can submit jobs but
+ the printer will not print anything until it is started.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>help
+ command-name</command></term>
+
+ <listitem>
+ <para>Print help on the command
+ <replaceable>command-name</replaceable>. With no
+ <replaceable>command-name</replaceable>, print a summary of the
+ commands available.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>restart
+ printer-name</command></term>
+
+ <listitem>
+ <para>Start the printer. Ordinary users can use this command if
+ some extraordinary circumstance hangs
+ <application>LPD</application>, but they cannot start
+ a printer stopped with either the <command>stop</command> or
+ <command>down</command> commands. The
+ <command>restart</command> command is equivalent to
+ <command>abort</command> followed by
+ <command>start</command>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>start
+ printer-name</command></term>
+
+ <listitem>
+ <para>Start the printer. The printer will print jobs in its
+ queue.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>stop
+ printer-name</command></term>
+
+ <listitem>
+ <para>Stop 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.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>topq printer-name
+ job-or-username</command></term>
+
+ <listitem>
+ <para>Rearrange the queue for
+ <replaceable>printer-name</replaceable> by placing the jobs with
+ the listed <replaceable>job</replaceable> numbers or the jobs
+ belonging to <replaceable>username</replaceable> at the top of
+ the queue. For this command, you cannot use
+ <literal>all</literal> as the
+ <replaceable>printer-name</replaceable>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><command>up
+ printer-name</command></term>
+
+ <listitem>
+ <para>Bring a printer up; the opposite of the
+ <command>down</command> command. Equivalent to
+ <command>start</command> followed by
+ <command>enable</command>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>&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 <command>exit</command>,
+ <command>quit</command>, or end-of-file.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="printing-lpd-alternatives">
+ <title>Alternatives to the Standard Spooler</title>
+
+ <para>If you have been reading straight through this manual, by now you
+ have learned just about everything there is to know about the
+ <application>LPD</application>
+ spooling system that comes with FreeBSD. You can probably appreciate
+ many of its shortcomings, which naturally leads to the question:
+ <quote>What other spooling systems are out there (and work with
+ FreeBSD)?</quote></para>
+
+ <variablelist>
+ <varlistentry>
+ <term>LPRng</term>
+
+ <listitem>
+ <indexterm><primary>LPRng</primary></indexterm>
+
+ <para><application>LPRng</application>, which purportedly means
+ <quote>LPR: the Next
+ Generation</quote> is a complete rewrite of PLP. Patrick Powell
+ and Justin Mason (the principal maintainer of PLP) collaborated to
+ make <application>LPRng</application>. The main site for
+ <application>LPRng</application> is <uri xlink:href="http://www.lprng.org/">http://www.lprng.org/</uri>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>CUPS</term>
+
+ <listitem>
+ <indexterm><primary>CUPS</primary></indexterm>
+
+ <para><application>CUPS</application>, 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.</para>
+
+ <para><application>CUPS</application> uses the Internet Printing
+ Protocol (<acronym>IPP</acronym>) as the basis for managing
+ print jobs and queues. The Line Printer Daemon
+ (<acronym>LPD</acronym>), Server Message Block
+ (<acronym>SMB</acronym>), and AppSocket (a.k.a. JetDirect)
+ protocols are also supported with reduced functionality. CUPS
+ adds network printer browsing and PostScript Printer Description
+ (<acronym>PPD</acronym>) based printing options to support
+ real-world printing under &unix;.</para>
+
+ <para>The main site for <application>CUPS</application> is <uri xlink:href="http://www.cups.org/">http://www.cups.org/</uri>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1 xml:id="printing-troubleshooting">
+ <title>Troubleshooting</title>
+
+ <para>After performing the simple test with &man.lptest.1;, you might
+ have gotten one of the following results instead of the correct
+ printout:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>It worked, after awhile; or, it did not eject a full
+ sheet.</term>
+
+ <listitem>
+ <para>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.</para>
+
+ <para>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.</para>
+
+ <para>The following replacement for the shell script
+ <filename>/usr/local/libexec/if-simple</filename> prints a
+ form feed after it sends the job to the printer:</para>
+
+ <programlisting>#!/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 &amp;&amp; printf "\f" &amp;&amp; exit 0
+exit 2</programlisting>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>It produced the <quote>staircase effect.</quote></term>
+
+ <listitem>
+ <para>You got the following on paper:</para>
+
+ <programlisting>!"#$%&amp;'()*+,-./01234
+ "#$%&amp;'()*+,-./012345
+ #$%&amp;'()*+,-./0123456</programlisting>
+
+ <indexterm><primary>MS-DOS</primary></indexterm>
+ <indexterm><primary>OS/2</primary></indexterm>
+ <indexterm><primary>ASCII</primary></indexterm>
+ <para>You have become another victim of the <emphasis>staircase
+ effect</emphasis>, 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 <emphasis>and</emphasis> ASCII code
+ 13 (the carriage return or CR). Many printers use the &ms-dos;
+ convention for representing new-lines.</para>
+
+ <para>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.</para>
+
+ <para>Here is what FreeBSD wants your printer to do:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>Printer received CR</entry>
+ <entry>Printer prints CR</entry>
+ </row>
+
+ <row>
+ <entry>Printer received LF</entry>
+ <entry>Printer prints CR + LF</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>Here are some ways to achieve this:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>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.</para>
+
+ <note>
+ <para>If you boot your system into other operating systems
+ besides FreeBSD, you may have to
+ <emphasis>reconfigure</emphasis> 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.</para>
+ </note>
+ </listitem>
+
+ <listitem>
+ <para>Have FreeBSD's serial line driver automatically
+ convert LF to CR+LF. Of course, this works with printers
+ on serial ports <emphasis>only</emphasis>. To enable this
+ feature, use the <literal>ms#</literal> capability and
+ set the <literal>onlcr</literal> mode
+ in the <filename>/etc/printcap</filename> file
+ for the printer.</para>
+ </listitem>
+
+ <listitem>
+ <para>Send an <emphasis>escape code</emphasis> 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.</para>
+
+ <indexterm><primary>PCL</primary></indexterm>
+ <para>Here 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.</para>
+
+ <programlisting>#!/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&amp;k2G" &amp;&amp; cat &amp;&amp; printf "\033&amp;l0H" &amp;&amp; exit 0
+exit 2</programlisting>
+
+ <para>Here is an example <filename>/etc/printcap</filename>
+ from a host called <systemitem>orchid</systemitem>. It has a single printer
+ attached to its first parallel port, a Hewlett Packard
+ LaserJet 3Si named <literal>teak</literal>. It is using the
+ above script as its text filter:</para>
+
+ <programlisting>#
+# /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:</programlisting>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>It overprinted each line.</term>
+
+ <listitem>
+ <para>The printer never advanced a line. All of the lines of
+ text were printed on top of each other on one line.</para>
+
+ <para>This problem is the <quote>opposite</quote> 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.</para>
+
+ <para>Use the printer's configuration switches or control panel
+ to enforce the following interpretation of LF and CR
+ characters:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Printer receives</entry>
+ <entry>Printer prints</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>CR</entry>
+ <entry>CR</entry>
+ </row>
+
+ <row>
+ <entry>LF</entry>
+ <entry>CR + LF</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>The printer lost characters.</term>
+
+ <listitem>
+ <para>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.</para>
+
+ <para>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:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>If the printer supports XON/XOFF flow control, have
+ FreeBSD use it by specifying the <literal>ixon</literal> mode
+ in the <literal>ms#</literal> capability.</para>
+ </listitem>
+
+ <listitem>
+ <para>If the printer supports carrier flow control, specify
+ the <literal>crtscts</literal> mode in the
+ <literal>ms#</literal> capability.
+ Make sure the cable connecting the printer to the computer
+ is correctly wired for carrier flow control.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>It printed garbage.</term>
+
+ <listitem>
+ <para>The printer printed what appeared to be random garbage,
+ but not the desired text.</para>
+
+ <para>This is usually another symptom of incorrect
+ communications parameters with a serial printer. Double-check
+ the bps rate in the <literal>br</literal> capability, and the
+ parity setting in the
+ <literal>ms#</literal> capability; make sure the printer is
+ using the same settings as specified in the
+ <filename>/etc/printcap</filename> file.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Nothing happened.</term>
+
+ <listitem>
+ <para>If nothing happened, the problem is probably within
+ FreeBSD and not the hardware. Add the log file
+ (<literal>lf</literal>) capability to the entry for the
+ printer you are debugging in the
+ <filename>/etc/printcap</filename> file. For example, here is
+ the entry for <literal>rattan</literal>, with the
+ <literal>lf</literal> capability:</para>
+
+ <programlisting>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.log</programlisting>
+
+ <para>Then, try printing again. Check the log file (in our
+ example, <filename>/var/log/rattan.log</filename>) to see any
+ error messages that might appear. Based on the messages you
+ see, try to correct the problem.</para>
+
+ <para>If you do not specify a <literal>lf</literal> capability,
+ <application>LPD</application> uses
+ <filename>/dev/console</filename> as a default.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/security/Makefile b/zh_TW.UTF-8/books/handbook/security/Makefile
new file mode 100644
index 0000000000..3524819d48
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/security/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= security/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/security/chapter.xml b/zh_TW.UTF-8/books/handbook/security/chapter.xml
new file mode 100644
index 0000000000..a75dfaf83c
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/security/chapter.xml
@@ -0,0 +1,4992 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.285
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="security">
+ <info><title>系統安全</title>
+ <authorgroup>
+ <author><personname><firstname>Matthew</firstname><surname>Dillon</surname></personname><contrib>Much of this chapter has been taken from the
+ security(7) manual page by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>security</primary></indexterm>
+
+ <sect1 xml:id="security-synopsis">
+ <title>概述</title>
+
+ <para>這一章將對系統安全的基本概念進行介紹,除此之外,還將介紹一些好的習慣,以及
+ &os; 下的一些更深入的話題。這章的許多內容對於一般的系統和 Internet
+ 安全也適用。如今,Internet 已經不再像以前那樣是個人人都願意與您作好鄰居的『友善場所』。
+ 必須讓系統更安全,才能去保護您的資料、智慧財產、寶貴時間以及其他很多東西,
+ 而不至於被入侵者或心存惡意的人所竊取。</para>
+
+ <para>&os; 提供了一系列工具和相關機制,來確保系統和網路的完整、安全。</para>
+
+ <para>讀完這章,您將了解︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para> &os; 系統的基本安全概念。</para>
+ </listitem>
+
+ <listitem>
+ <para>&os; 中許多可用的加密機制,例如 <acronym>DES</acronym> 及
+ <acronym>MD5</acronym>。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何建立一次性(one-time)密碼驗證機制。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何設定 <acronym>TCP</acronym> Wrappers
+ 以便與 <command>inetd</command> 配合使用。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何在 &os; 5.0. 之前的版本上設定 <application>KerberosIV</application>。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何在 &os; 5.0 (含之後版本)上設定 <application>Kerberos5</application>。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何設定 IPsec 以及在 &os;/&windows; 上建立 <acronym>VPN</acronym> 網路。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何設定、運用 <application>OpenSSH</application>,以及 &os; 的
+ <acronym>SSH</acronym> 實作方式(implementation)</para>
+ </listitem>
+
+ <listitem>
+ <para>了解檔案系統的 <acronym>ACL</acronym>s 機制為何,以及如何運用。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何使用 <application>Portaudit</application>
+ 工具來檢驗(audit) 從 Ports Collection 安裝的軟體安全性。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何善用 &os; 安全公告(Security Advisories),並採取相應措施。</para>
+ </listitem>
+
+ <listitem>
+ <para>瞭解 Process Accounting 機制及如何在 &os; 上啟動。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>在開始閱讀這章之前,您需要︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>瞭解 &os; 及 Internet 的基本概念。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>本書中其他章節,也有介紹安全方面的其他話題。例如:
+ 在 <xref linkend="mac"/> 有談到 Mandatory Access Control, Internet Firewalls 則在 <xref linkend="firewalls"/>。</para>
+ </sect1>
+
+ <sect1 xml:id="security-intro">
+ <title>介紹</title>
+
+ <para>安全,對系統管理者而言,是至始至終最基本的要求。由於所有的 BSD &unix; multi-user
+ 系統都提供了與生俱來的基本安全,所以建立、維護額外的安全機制,以確保使用者的『可靠』,
+ 可能也就是系統管理員最需要慎思的艱巨任務了。機器的安全性取決於您所建立的安全措施,
+ 而許多安全方面的考量,則會與人們使用電腦時的便利相矛盾。一般來說, &unix;
+ 系統可同時執行許多數目的程式 process ,並且其中許多 process 也同時以 Server 端來運作。
+ ── 這意味著,外部實體機器能夠與它們互相連接,並產生互動。現在的一般桌機,
+ 已經能夠達到以前小型主機甚至大型主機的性能,而隨著這些電腦的網路連接和在更大範圍內互相連接
+ ,安全也成為了一個日益嚴峻的課題。</para>
+
+ <para>安全最好的方式,是能夠透過像『洋蔥』那樣的層層防護模式。
+ 簡單講,應該儘可能的建立多層次安全防護,並小心地監視各類針對系統的入侵疑點。
+ You do not want to
+ overbuild your security or you will interfere with the detection
+ side, and detection is one of the single most important aspects of
+ any security mechanism. For example, it makes little sense to set
+ the <literal>schg</literal> flag (see &man.chflags.1;) on every
+ system binary because
+ while this may temporarily protect the binaries, it prevents an
+ attacker who has broken in from making an easily detectable change
+ that may result in your security mechanisms not detecting the attacker
+ at all.</para>
+
+ <para>System security also pertains to dealing with various forms of
+ attack, including attacks that attempt to crash, or otherwise make a
+ system unusable, but do not attempt to compromise the
+ <systemitem class="username">root</systemitem> account (<quote>break root</quote>).
+ Security concerns
+ can be split up into several categories:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>服務阻斷攻擊(DoS)</para>
+ </listitem>
+
+ <listitem>
+ <para>竊取其他使用者的帳號。</para>
+ </listitem>
+
+ <listitem>
+ <para>透過各式 Server 上所提供的 Service 來竊取 root 帳號。</para>
+ </listitem>
+
+ <listitem>
+ <para>透過使用者帳號竊取 root 帳號。</para>
+ </listitem>
+
+ <listitem>
+ <para>開後門。</para>
+ </listitem>
+ </orderedlist>
+
+ <indexterm>
+ <primary>DoS attacks</primary>
+ <see>Denial of Service (DoS)</see>
+ </indexterm>
+ <indexterm>
+ <primary>security</primary>
+ <secondary>DoS attacks</secondary>
+ <see>Denial of Service (DoS)</see>
+ </indexterm>
+ <indexterm><primary>Denial of Service (DoS)</primary></indexterm>
+
+ <para>A denial of service attack is an action that deprives the
+ machine of needed resources. Typically, DoS attacks are
+ brute-force mechanisms that attempt to crash or otherwise make a
+ machine unusable by overwhelming its servers or network stack. Some
+ DoS attacks try to take advantage of bugs in the networking
+ stack to crash a machine with a single packet. The latter can only
+ be fixed by applying a bug fix to the kernel. Attacks on servers
+ can often be fixed by properly specifying options to limit the load
+ the servers incur on the system under adverse conditions.
+ Brute-force network attacks are harder to deal with. A
+ spoofed-packet attack, for example, is nearly impossible to stop,
+ short of cutting your system off from the Internet. It may not be
+ able to take your machine down, but it can saturate your
+ Internet connection.</para>
+
+ <indexterm>
+ <primary>security</primary>
+ <secondary>account compromises</secondary>
+ </indexterm>
+
+ <para>A user account compromise is even more common than a DoS
+ attack. Many sysadmins still run standard
+ <application>telnetd</application>, <application>rlogind</application>,
+ <application>rshd</application>,
+ and <application>ftpd</application> servers on their machines.
+ These servers, by default, do
+ not operate over encrypted connections. The result is that if you
+ have any moderate-sized user base, one or more of your users logging
+ into your system from a remote location (which is the most common
+ and convenient way to login to a system) will have his or her
+ password sniffed. The attentive system admin will analyze his
+ remote access logs looking for suspicious source addresses even for
+ successful logins.</para>
+
+ <para>One must always assume that once an attacker has access to a
+ user account, the attacker can break <systemitem class="username">root</systemitem>.
+ However, the reality is that in a well secured and maintained system,
+ access to a user account does not necessarily give the attacker
+ access to <systemitem class="username">root</systemitem>. The distinction is important
+ because without access to <systemitem class="username">root</systemitem> the attacker
+ cannot generally hide his tracks and may, at best, be able to do
+ nothing more than mess with the user's files, or crash the machine.
+ User account compromises are very common because users tend not to
+ take the precautions that sysadmins take.</para>
+
+ <indexterm>
+ <primary>security</primary>
+ <secondary>backdoors</secondary>
+ </indexterm>
+
+ <para>System administrators must keep in mind that there are
+ potentially many ways to break <systemitem class="username">root</systemitem> on a machine.
+ The attacker may know the <systemitem class="username">root</systemitem> password,
+ the attacker may find a bug in a root-run server and be able
+ to break <systemitem class="username">root</systemitem> over a network
+ connection to that server, or the attacker may know of a bug in
+ a suid-root program that allows the attacker to break
+ <systemitem class="username">root</systemitem> once he has broken into a user's account.
+ If an attacker has found a way to break <systemitem class="username">root</systemitem>
+ on a machine, the attacker may not have a need
+ to install a backdoor. Many of the <systemitem class="username">root</systemitem> holes
+ found and closed to date involve a considerable amount of work
+ by the attacker to cleanup after himself, so most attackers install
+ backdoors. A backdoor provides the attacker with a way to easily
+ regain <systemitem class="username">root</systemitem> access to the system, but it
+ also gives the smart system administrator a convenient way
+ to detect the intrusion.
+ Making it impossible for an attacker to install a backdoor may
+ actually be detrimental to your security, because it will not
+ close off the hole the attacker found to break in the first
+ place.</para>
+
+
+ <para>Security remedies should always be implemented with a
+ multi-layered <quote>onion peel</quote> approach and can be
+ categorized as follows:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Securing <systemitem class="username">root</systemitem> and staff accounts.</para>
+ </listitem>
+
+ <listitem>
+ <para>Securing <systemitem class="username">root</systemitem>&ndash;run servers
+ and suid/sgid binaries.</para>
+ </listitem>
+
+ <listitem>
+ <para>Securing user accounts.</para>
+ </listitem>
+
+ <listitem>
+ <para>Securing the password file.</para>
+ </listitem>
+
+ <listitem>
+ <para>Securing the kernel core, raw devices, and
+ file systems.</para>
+ </listitem>
+
+ <listitem>
+ <para>Quick detection of inappropriate changes made to the
+ system.</para>
+ </listitem>
+
+ <listitem>
+ <para>Paranoia.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>The next section of this chapter will cover the above bullet
+ items in greater depth.</para>
+ </sect1>
+
+ <sect1 xml:id="securing-freebsd">
+ <title>&os; 的系統安全</title>
+ <indexterm>
+ <primary>security</primary>
+ <secondary>securing &os;</secondary>
+ </indexterm>
+
+ <note>
+ <title>Command vs. Protocol</title>
+ <para>Throughout this document, we will use
+ <application>bold</application> text to refer to an
+ application, and a <command>monospaced</command> font to refer
+ to specific commands. Protocols will use a normal font. This
+ typographical distinction is useful for instances such as ssh,
+ since it is
+ a protocol as well as command.</para>
+ </note>
+
+ <para>The sections that follow will cover the methods of securing your
+ &os; system that were mentioned in the <link linkend="security-intro">last section</link> of this chapter.</para>
+
+ <sect2 xml:id="securing-root-and-staff">
+ <title>Securing the <systemitem class="username">root</systemitem> Account and
+ Staff Accounts</title>
+ <indexterm>
+ <primary><command>su</command></primary>
+ </indexterm>
+
+ <para>First off, do not bother securing staff accounts if you have
+ not secured the <systemitem class="username">root</systemitem> account.
+ Most systems have a password assigned to the <systemitem class="username">root</systemitem>
+ account. The first thing you do is assume
+ that the password is <emphasis>always</emphasis> compromised.
+ This does not mean that you should remove the password. The
+ password is almost always necessary for console access to the
+ machine. What it does mean is that you should not make it
+ possible to use the password outside of the console or possibly
+ even with the &man.su.1; command. For example, make sure that
+ your ptys are specified as being insecure in the
+ <filename>/etc/ttys</filename> file so that direct
+ <systemitem class="username">root</systemitem> logins
+ via <command>telnet</command> or <command>rlogin</command> are
+ disallowed. If using other login services such as
+ <application>sshd</application>, make sure that direct
+ <systemitem class="username">root</systemitem> logins are disabled there as well.
+ You can do this by editing
+ your <filename>/etc/ssh/sshd_config</filename> file, and making
+ sure that <literal>PermitRootLogin</literal> is set to
+ <literal>NO</literal>. Consider every access method &mdash;
+ services such as FTP often fall through the cracks.
+ Direct <systemitem class="username">root</systemitem> logins should only be allowed
+ via the system console.</para>
+ <indexterm>
+ <primary><systemitem class="groupname">wheel</systemitem></primary>
+ </indexterm>
+
+ <para>Of course, as a sysadmin you have to be able to get to
+ <systemitem class="username">root</systemitem>, so we open up a few holes.
+ But we make sure these holes require additional password
+ verification to operate. One way to make <systemitem class="username">root</systemitem>
+ accessible is to add appropriate staff accounts to the
+ <systemitem class="groupname">wheel</systemitem> group (in
+ <filename>/etc/group</filename>). The staff members placed in the
+ <systemitem class="groupname">wheel</systemitem> group are allowed to
+ <command>su</command> to <systemitem class="username">root</systemitem>.
+ You should never give staff
+ members native <systemitem class="groupname">wheel</systemitem> access by putting them in the
+ <systemitem class="groupname">wheel</systemitem> group in their password entry. Staff
+ accounts should be placed in a <systemitem class="groupname">staff</systemitem> group, and
+ then added to the <systemitem class="groupname">wheel</systemitem> group via the
+ <filename>/etc/group</filename> file. Only those staff members
+ who actually need to have <systemitem class="username">root</systemitem> access
+ should be placed in the
+ <systemitem class="groupname">wheel</systemitem> group. It is also possible, when using
+ an authentication method such as Kerberos, to use Kerberos'
+ <filename>.k5login</filename> file in the <systemitem class="username">root</systemitem>
+ account to allow a &man.ksu.1; to <systemitem class="username">root</systemitem>
+ without having to place anyone at all in the
+ <systemitem class="groupname">wheel</systemitem> group. This may be the better solution
+ since the <systemitem class="groupname">wheel</systemitem> mechanism still allows an
+ intruder to break <systemitem class="username">root</systemitem> if the intruder
+ has gotten hold of your
+ password file and can break into a staff account. While having
+ the <systemitem class="groupname">wheel</systemitem> mechanism is better than having
+ nothing at all, it is not necessarily the safest option.</para>
+
+ <!-- XXX:
+ This will need updating depending on the outcome of PR bin/71147.
+ Personally I know what I'd like to see, which puts this in definite
+ need of a rewrite, but we'll have to wait and see. ceri@
+ -->
+
+ <para>An indirect way to secure staff accounts, and ultimately
+ <systemitem class="username">root</systemitem> access is to use an alternative
+ login access method and
+ do what is known as <quote>starring</quote> out the encrypted
+ password for the staff accounts. Using the &man.vipw.8;
+ command, one can replace each instance of an encrypted password
+ with a single <quote><literal>*</literal></quote> character.
+ This command will update the <filename>/etc/master.passwd</filename>
+ file and user/password database to disable password-authenticated
+ logins.</para>
+
+ <para>A staff account entry such as:</para>
+
+ <programlisting>foobar:R9DT/Fa1/LV9U:1000:1000::0:0:Foo Bar:/home/foobar:/usr/local/bin/tcsh</programlisting>
+
+ <para>Should be changed to this:</para>
+
+ <programlisting>foobar:*:1000:1000::0:0:Foo Bar:/home/foobar:/usr/local/bin/tcsh</programlisting>
+
+ <para>This change will prevent normal logins from occurring,
+ since the encrypted password will never match
+ <quote><literal>*</literal></quote>. With this done,
+ staff members must use
+ another mechanism to authenticate themselves such as
+ &man.kerberos.1; or &man.ssh.1; using a public/private key
+ pair. When using something like Kerberos, one generally must
+ secure the machines which run the Kerberos servers and your
+ desktop workstation. When using a public/private key pair
+ with ssh, one must generally secure
+ the machine used to login <emphasis>from</emphasis> (typically
+ one's workstation). An additional layer of protection can be
+ added to the key pair by password protecting the key pair when
+ creating it with &man.ssh-keygen.1;. Being able to
+ <quote>star</quote> out the passwords for staff accounts also
+ guarantees that staff members can only login through secure
+ access methods that you have set up. This forces all staff
+ members to use secure, encrypted connections for all of their
+ sessions, which closes an important hole used by many
+ intruders: sniffing the network from an unrelated,
+ less secure machine.</para>
+
+ <para>The more indirect security mechanisms also assume that you are
+ logging in from a more restrictive server to a less restrictive
+ server. For example, if your main box is running all sorts of
+ servers, your workstation should not be running any. In order for
+ your workstation to be reasonably secure you should run as few
+ servers as possible, up to and including no servers at all, and
+ you should run a password-protected screen blanker. Of course,
+ given physical access to a workstation an attacker can break any
+ sort of security you put on it. This is definitely a problem that
+ you should consider, but you should also consider the fact that the
+ vast majority of break-ins occur remotely, over a network, from
+ people who do not have physical access to your workstation or
+ servers.</para>
+ <indexterm><primary>KerberosIV</primary></indexterm>
+
+ <para>Using something like Kerberos also gives you the ability to
+ disable or change the password for a staff account in one place,
+ and have it immediately affect all the machines on which the staff
+ member may have an account. If a staff member's account gets
+ compromised, the ability to instantly change his password on all
+ machines should not be underrated. With discrete passwords,
+ changing a password on N machines can be a mess. You can also
+ impose re-passwording restrictions with Kerberos: not only can a
+ Kerberos ticket be made to timeout after a while, but the Kerberos
+ system can require that the user choose a new password after a
+ certain period of time (say, once a month).</para>
+ </sect2>
+
+ <sect2>
+ <title>Securing Root-run Servers and SUID/SGID Binaries</title>
+
+ <indexterm>
+ <primary><command>ntalk</command></primary>
+ </indexterm>
+ <indexterm>
+ <primary><command>comsat</command></primary>
+ </indexterm>
+ <indexterm>
+ <primary><command>finger</command></primary>
+ </indexterm>
+ <indexterm>
+ <primary>sandboxes</primary>
+ </indexterm>
+ <indexterm>
+ <primary><application>sshd</application></primary>
+ </indexterm>
+ <indexterm>
+ <primary><application>telnetd</application></primary>
+ </indexterm>
+ <indexterm>
+ <primary><application>rshd</application></primary>
+ </indexterm>
+ <indexterm>
+ <primary><application>rlogind</application></primary>
+ </indexterm>
+
+ <para>The prudent sysadmin only runs the servers he needs to, no
+ more, no less. Be aware that third party servers are often the
+ most bug-prone. For example, running an old version of
+ <application>imapd</application> or
+ <application>popper</application> is like giving a universal
+ <systemitem class="username">root</systemitem> ticket out to the entire world.
+ Never run a server that you have not checked out carefully.
+ Many servers do not need to be run as <systemitem class="username">root</systemitem>.
+ For example, the <application>ntalk</application>,
+ <application>comsat</application>, and
+ <application>finger</application> daemons can be run in special
+ user <firstterm>sandboxes</firstterm>. A sandbox is not perfect,
+ unless you go through a large amount of trouble, but the onion
+ approach to security still stands: If someone is able to break
+ in through a server running in a sandbox, they still have to
+ break out of the sandbox. The more layers the attacker must
+ break through, the lower the likelihood of his success. Root
+ holes have historically been found in virtually every server
+ ever run as <systemitem class="username">root</systemitem>, including basic system servers.
+ If you are running a machine through which people only login via
+ <application>sshd</application> and never login via
+ <application>telnetd</application> or
+ <application>rshd</application> or
+ <application>rlogind</application>, then turn off those
+ services!</para>
+
+ <para>&os; now defaults to running
+ <application>ntalkd</application>,
+ <application>comsat</application>, and
+ <application>finger</application> in a sandbox. Another program
+ which may be a candidate for running in a sandbox is &man.named.8;.
+ <filename>/etc/defaults/rc.conf</filename> includes the arguments
+ necessary to run <application>named</application> in a sandbox in a
+ commented-out form. Depending on whether you are installing a new
+ system or upgrading an existing system, the special user accounts
+ used by these sandboxes may not be installed. The prudent
+ sysadmin would research and implement sandboxes for servers
+ whenever possible.</para>
+ <indexterm>
+ <primary><application>sendmail</application></primary>
+ </indexterm>
+
+ <para>There are a number of other servers that typically do not run
+ in sandboxes: <application>sendmail</application>,
+ <application>popper</application>,
+ <application>imapd</application>, <application>ftpd</application>,
+ and others. There are alternatives to some of these, but
+ installing them may require more work than you are willing to
+ perform (the convenience factor strikes again). You may have to
+ run these servers as <systemitem class="username">root</systemitem> and rely on other
+ mechanisms to detect break-ins that might occur through them.</para>
+
+ <para>The other big potential <systemitem class="username">root</systemitem> holes in a
+ system are the
+ suid-root and sgid binaries installed on the system. Most of
+ these binaries, such as <application>rlogin</application>, reside
+ in <filename>/bin</filename>, <filename>/sbin</filename>,
+ <filename>/usr/bin</filename>, or <filename>/usr/sbin</filename>.
+ While nothing is 100% safe, the system-default suid and sgid
+ binaries can be considered reasonably safe. Still,
+ <systemitem class="username">root</systemitem> holes are occasionally found in these
+ binaries. A <systemitem class="username">root</systemitem> hole was found in
+ <literal>Xlib</literal> in 1998 that made
+ <application>xterm</application> (which is typically suid)
+ vulnerable. It is better to be safe than sorry and the prudent
+ sysadmin will restrict suid binaries, that only staff should run,
+ to a special group that only staff can access, and get rid of
+ (<command>chmod 000</command>) any suid binaries that nobody uses.
+ A server with no display generally does not need an
+ <application>xterm</application> binary. Sgid binaries can be
+ almost as dangerous. If an intruder can break an sgid-kmem binary,
+ the intruder might be able to read <filename>/dev/kmem</filename>
+ and thus read the encrypted password file, potentially compromising
+ any passworded account. Alternatively an intruder who breaks
+ group <literal>kmem</literal> can monitor keystrokes sent through
+ ptys, including ptys used by users who login through secure
+ methods. An intruder that breaks the <systemitem class="groupname">tty</systemitem>
+ group can write to
+ almost any user's tty. If a user is running a terminal program or
+ emulator with a keyboard-simulation feature, the intruder can
+ potentially generate a data stream that causes the user's terminal
+ to echo a command, which is then run as that user.</para>
+ </sect2>
+
+ <sect2 xml:id="secure-users">
+ <title>Securing User Accounts</title>
+
+ <para>User accounts are usually the most difficult to secure. While
+ you can impose Draconian access restrictions on your staff and
+ <quote>star</quote> out their passwords, you may not be able to
+ do so with any general user accounts you might have. If you do
+ have sufficient control, then you may win out and be able to secure
+ the user accounts properly. If not, you simply have to be more
+ vigilant in your monitoring of those accounts. Use of
+ ssh and Kerberos for user accounts is
+ more problematic, due to the extra administration and technical
+ support required, but still a very good solution compared to a
+ crypted password file.</para>
+ </sect2>
+
+ <sect2>
+ <title>Securing the Password File</title>
+
+ <para>The only sure fire way is to <literal>*</literal> out as many
+ passwords as you can and use ssh or
+ Kerberos for access to those accounts. Even though the encrypted
+ password file (<filename>/etc/spwd.db</filename>) can only be read
+ by <systemitem class="username">root</systemitem>, it may be possible for an intruder
+ to obtain read access to that file even if the attacker cannot
+ obtain root-write access.</para>
+
+ <para>Your security scripts should always check for and report
+ changes to the password file (see the <link linkend="security-integrity">Checking file integrity</link> section
+ below).</para>
+ </sect2>
+
+ <sect2>
+ <title>Securing the Kernel Core, Raw Devices, and
+ File systems</title>
+
+ <para>If an attacker breaks <systemitem class="username">root</systemitem> he can do
+ just about anything, but
+ there are certain conveniences. For example, most modern kernels
+ have a packet sniffing device driver built in. Under &os; it
+ is called the <filename>bpf</filename> device. An intruder
+ will commonly attempt to run a packet sniffer on a compromised
+ machine. You do not need to give the intruder the capability and
+ most systems do not have the need for the
+ <filename>bpf</filename> device compiled in.</para>
+
+ <indexterm>
+ <primary><command>sysctl</command></primary>
+ </indexterm>
+ <para>But even if you turn off the <filename>bpf</filename>
+ device, you still have
+ <filename>/dev/mem</filename> and
+ <filename>/dev/kmem</filename>
+ to worry about. For that matter, the intruder can still write to
+ raw disk devices. Also, there is another kernel feature called
+ the module loader, &man.kldload.8;. An enterprising intruder can
+ use a KLD module to install his own <filename>bpf</filename>
+ device, or other sniffing
+ device, on a running kernel. To avoid these problems you have to
+ run the kernel at a higher secure level, at least securelevel 1.
+ The securelevel can be set with a <command>sysctl</command> on
+ the <varname>kern.securelevel</varname> variable. Once you have
+ set the securelevel to 1, write access to raw devices will be
+ denied and special <command>chflags</command> flags,
+ such as <literal>schg</literal>,
+ will be enforced. You must also ensure that the
+ <literal>schg</literal> flag is set on critical startup binaries,
+ directories, and script files &mdash; everything that gets run up
+ to the point where the securelevel is set. This might be overdoing
+ it, and upgrading the system is much more difficult when you
+ operate at a higher secure level. You may compromise and run the
+ system at a higher secure level but not set the
+ <literal>schg</literal> flag for every system file and directory
+ under the sun. Another possibility is to simply mount
+ <filename>/</filename> and <filename>/usr</filename> read-only.
+ It should be noted that being too Draconian in what you attempt to
+ protect may prevent the all-important detection of an
+ intrusion.</para>
+ </sect2>
+
+ <sect2 xml:id="security-integrity">
+ <title>Checking File Integrity: Binaries, Configuration Files,
+ Etc.</title>
+
+ <para>When it comes right down to it, you can only protect your core
+ system configuration and control files so much before the
+ convenience factor rears its ugly head. For example, using
+ <command>chflags</command> to set the <literal>schg</literal> bit
+ on most of the files in <filename>/</filename> and
+ <filename>/usr</filename> is probably counterproductive, because
+ while it may protect the files, it also closes a detection window.
+ The last layer of your security onion is perhaps the most
+ important &mdash; detection. The rest of your security is pretty
+ much useless (or, worse, presents you with a false sense of
+ safety) if you cannot detect potential incursions. Half the job
+ of the onion is to slow down the attacker, rather than stop him, in
+ order to give the detection side of the equation a chance to catch
+ him in the act.</para>
+
+ <para>The best way to detect an incursion is to look for modified,
+ missing, or unexpected files. The best way to look for modified
+ files is from another (often centralized) limited-access system.
+ Writing your security scripts on the extra-secure limited-access
+ system makes them mostly invisible to potential attackers, and this
+ is important. In order to take maximum advantage you generally
+ have to give the limited-access box significant access to the
+ other machines in the business, usually either by doing a
+ read-only NFS export of the other machines to the limited-access
+ box, or by setting up ssh key-pairs to
+ allow the limited-access box to ssh to
+ the other machines. Except for its network traffic, NFS is the
+ least visible method &mdash; allowing you to monitor the
+ file systems on each client box virtually undetected. If your
+ limited-access server is connected to the client boxes through a
+ switch, the NFS method is often the better choice. If your
+ limited-access server is connected to the client boxes through a
+ hub, or through several layers of routing, the NFS method may be
+ too insecure (network-wise) and using
+ ssh may be the better choice even with
+ the audit-trail tracks that ssh
+ lays.</para>
+
+ <para>Once you give a limited-access box, at least read access to the
+ client systems it is supposed to monitor, you must write scripts
+ to do the actual monitoring. Given an NFS mount, you can write
+ scripts out of simple system utilities such as &man.find.1; and
+ &man.md5.1;. It is best to physically md5 the client-box files
+ at least once a day, and to test control files such as those
+ found in <filename>/etc</filename> and
+ <filename>/usr/local/etc</filename> even more often. When
+ mismatches are found, relative to the base md5 information the
+ limited-access machine knows is valid, it should scream at a
+ sysadmin to go check it out. A good security script will also
+ check for inappropriate suid binaries and for new or deleted files
+ on system partitions such as <filename>/</filename> and
+ <filename>/usr</filename>.</para>
+
+ <para>When using ssh rather than NFS,
+ writing the security script is much more difficult. You
+ essentially have to <command>scp</command> the scripts to the client
+ box in order to
+ run them, making them visible, and for safety you also need to
+ <command>scp</command> the binaries (such as find) that those
+ scripts use. The <application>ssh</application> client on the
+ client box may already be compromised. All in all, using
+ ssh may be necessary when running over
+ insecure links, but it is also a lot harder to deal with.</para>
+
+ <para>A good security script will also check for changes to user and
+ staff members access configuration files:
+ <filename>.rhosts</filename>, <filename>.shosts</filename>,
+ <filename>.ssh/authorized_keys</filename> and so forth&hellip;
+ files that might fall outside the purview of the
+ <literal>MD5</literal> check.</para>
+
+ <para>If you have a huge amount of user disk space, it may take too
+ long to run through every file on those partitions. In this case,
+ setting mount flags to disallow suid binaries and devices on those
+ partitions is a good idea. The <literal>nodev</literal> and
+ <literal>nosuid</literal> options (see &man.mount.8;) are what you
+ want to look into. You should probably scan them anyway, at least
+ once a week, since the object of this layer is to detect a break-in
+ whether or not the break-in is effective.</para>
+
+ <para>Process accounting (see &man.accton.8;) is a relatively
+ low-overhead feature of the operating system which might help
+ as a post-break-in evaluation mechanism. It is especially
+ useful in tracking down how an intruder has actually broken into
+ a system, assuming the file is still intact after the break-in
+ occurs.</para>
+
+ <para>Finally, security scripts should process the log files, and the
+ logs themselves should be generated in as secure a manner as
+ possible &mdash; remote syslog can be very useful. An intruder
+ tries to cover his tracks, and log files are critical to the
+ sysadmin trying to track down the time and method of the initial
+ break-in. One way to keep a permanent record of the log files is
+ to run the system console to a serial port and collect the
+ information on a continuing basis through a secure machine
+ monitoring the consoles.</para>
+ </sect2>
+
+ <sect2>
+ <title>Paranoia</title>
+
+ <para>A little paranoia never hurts. As a rule, a sysadmin can add
+ any number of security features, as long as they do not affect
+ convenience, and can add security features that
+ <emphasis>do</emphasis> affect convenience with some added thought.
+ Even more importantly, a security administrator should mix it up a
+ bit &mdash; if you use recommendations such as those given by this
+ document verbatim, you give away your methodologies to the
+ prospective attacker who also has access to this document.</para>
+ </sect2>
+
+ <sect2>
+ <title>DoS(Denial of Service)服務阻斷攻擊</title>
+ <indexterm><primary>Denial of Service (DoS)</primary></indexterm>
+
+ <para>這一節將介紹服務阻斷攻擊。 DoS 攻擊通常是以封包的方式進行攻擊,
+ 儘管幾乎沒有任何辦法來阻止大量的偽造封包耗盡網路資源,
+ 但通常可以透過一些方式來降低這類攻擊的損害,使它們無法擊垮伺服器。</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Limiting server forks.</para>
+ </listitem>
+
+ <listitem>
+ <para>Limiting springboard attacks (ICMP response 攻擊,ping
+ broadcast等等)</para>
+ </listitem>
+
+ <listitem>
+ <para>Kernel Route Cache.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>A common DoS attack is against a forking server that attempts
+ to cause the server to eat processes, file descriptors, and memory,
+ until the machine dies. <application>inetd</application>
+ (see &man.inetd.8;) has several
+ options to limit this sort of attack. It should be noted that
+ while it is possible to prevent a machine from going down, it is
+ not generally possible to prevent a service from being disrupted
+ by the attack. Read the <application>inetd</application> manual
+ page carefully and pay
+ specific attention to the <option>-c</option>, <option>-C</option>,
+ and <option>-R</option> options. Note that spoofed-IP attacks
+ will circumvent the <option>-C</option> option to
+ <application>inetd</application>, so
+ typically a combination of options must be used. Some standalone
+ servers have self-fork-limitation parameters.</para>
+
+ <para><application>Sendmail</application> has its
+ <option>-OMaxDaemonChildren</option> option, which tends to work
+ much better than trying to use sendmail's load limiting options
+ due to the load lag. You should specify a
+ <literal>MaxDaemonChildren</literal> parameter, when you start
+ <application>sendmail</application>, high enough to handle your
+ expected load, but not so high that the computer cannot handle that
+ number of <application>sendmails</application> without falling on
+ its face. It is also prudent to run sendmail in queued mode
+ (<option>-ODeliveryMode=queued</option>) and to run the daemon
+ (<command>sendmail -bd</command>) separate from the queue-runs
+ (<command>sendmail -q15m</command>). If you still want real-time
+ delivery you can run the queue at a much lower interval, such as
+ <option>-q1m</option>, but be sure to specify a reasonable
+ <literal>MaxDaemonChildren</literal> option for
+ <emphasis>that</emphasis> sendmail to prevent cascade failures.</para>
+
+ <para><application>Syslogd</application> can be attacked directly
+ and it is strongly recommended that you use the <option>-s</option>
+ option whenever possible, and the <option>-a</option> option
+ otherwise.</para>
+
+ <para>You should also be fairly careful with connect-back services
+ such as <application>TCP Wrapper</application>'s reverse-identd,
+ which can be attacked directly. You generally do not want to use
+ the reverse-ident feature of
+ <application>TCP Wrapper</application> for this reason.</para>
+
+ <para>It is a very good idea to protect internal services from
+ external access by firewalling them off at your border routers.
+ The idea here is to prevent saturation attacks from outside your
+ LAN, not so much to protect internal services from network-based
+ <systemitem class="username">root</systemitem> compromise.
+ Always configure an exclusive firewall, i.e.,
+ <quote>firewall everything <emphasis>except</emphasis> ports A, B,
+ C, D, and M-Z</quote>. This way you can firewall off all of your
+ low ports except for certain specific services such as
+ <application>named</application> (if you are primary for a zone),
+ <application>ntalkd</application>,
+ <application>sendmail</application>, and other Internet-accessible
+ services. If you try to configure the firewall the other way
+ &mdash; as an inclusive or permissive firewall, there is a good
+ chance that you will forget to <quote>close</quote> a couple of
+ services, or that you will add a new internal service and forget
+ to update the firewall. You can still open up the high-numbered
+ port range on the firewall, to allow permissive-like operation,
+ without compromising your low ports. Also take note that &os;
+ allows you to control the range of port numbers used for dynamic
+ binding, via the various <varname>net.inet.ip.portrange</varname>
+ <command>sysctl</command>'s (<command>sysctl -a | fgrep
+ portrange</command>), which can also ease the complexity of your
+ firewall's configuration. For example, you might use a normal
+ first/last range of 4000 to 5000, and a hiport range of 49152 to
+ 65535, then block off everything under 4000 in your firewall
+ (except for certain specific Internet-accessible ports, of
+ course).</para>
+
+ <para>Another common DoS attack is called a springboard attack
+ &mdash; to attack a server in a manner that causes the server to
+ generate responses which overloads the server, the local
+ network, or some other machine. The most common attack of this
+ nature is the <emphasis>ICMP ping broadcast attack</emphasis>.
+ The attacker spoofs ping packets sent to your LAN's broadcast
+ address with the source IP address set to the actual machine they
+ wish to attack. If your border routers are not configured to
+ stomp on ping's to broadcast addresses, your LAN winds up
+ generating sufficient responses to the spoofed source address to
+ saturate the victim, especially when the attacker uses the same
+ trick on several dozen broadcast addresses over several dozen
+ different networks at once. Broadcast attacks of over a hundred
+ and twenty megabits have been measured. A second common
+ springboard attack is against the ICMP error reporting system.
+ By constructing packets that generate ICMP error responses, an
+ attacker can saturate a server's incoming network and cause the
+ server to saturate its outgoing network with ICMP responses. This
+ type of attack can also crash the server by running it out of
+ mbuf's, especially if the server cannot drain the ICMP responses
+ it generates fast enough. &os; 4.X kernels have a kernel
+ compile option called <option>ICMP_BANDLIM</option>
+ which limits the effectiveness
+ of these sorts of attacks.
+ Later kernels use the <application>sysctl</application>
+ variable <literal>net.inet.icmp.icmplim</literal>.
+ The last major class of springboard
+ attacks is related to certain internal
+ <application>inetd</application> services such as the
+ udp echo service. An attacker simply spoofs a UDP packet with the
+ source address being server A's echo port, and the destination
+ address being server B's echo port, where server A and B are both
+ on your LAN. The two servers then bounce this one packet back and
+ forth between each other. The attacker can overload both servers
+ and their LANs simply by injecting a few packets in this manner.
+ Similar problems exist with the internal
+ <application>chargen</application> port. A
+ competent sysadmin will turn off all of these inetd-internal test
+ services.</para>
+
+ <para>Spoofed packet attacks may also be used to overload the kernel
+ route cache. Refer to the <varname>net.inet.ip.rtexpire</varname>,
+ <varname>rtminexpire</varname>, and <varname>rtmaxcache</varname>
+ <command>sysctl</command> parameters. A spoofed packet attack
+ that uses a random source IP will cause the kernel to generate a
+ temporary cached route in the route table, viewable with
+ <command>netstat -rna | fgrep W3</command>. These routes
+ typically timeout in 1600 seconds or so. If the kernel detects
+ that the cached route table has gotten too big it will dynamically
+ reduce the <varname>rtexpire</varname> but will never decrease it
+ to less than <varname>rtminexpire</varname>. There are two
+ problems:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>The kernel does not react quickly enough when a lightly
+ loaded server is suddenly attacked.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <varname>rtminexpire</varname> is not low enough for
+ the kernel to survive a sustained attack.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>If your servers are connected to the Internet via a T3 or
+ better, it may be prudent to manually override both
+ <varname>rtexpire</varname> and <varname>rtminexpire</varname>
+ via &man.sysctl.8;. Never set either parameter to zero (unless
+ you want to crash the machine). Setting both
+ parameters to 2 seconds should be sufficient to protect the route
+ table from attack.</para>
+ </sect2>
+
+ <sect2>
+ <title>Access Issues with Kerberos and SSH</title>
+ <indexterm><primary><command>ssh</command></primary></indexterm>
+ <indexterm><primary>KerberosIV</primary></indexterm>
+
+ <para>There are a few issues with both Kerberos and
+ ssh that need to be addressed if
+ you intend to use them. Kerberos V is an excellent
+ authentication protocol, but there are bugs in the kerberized
+ <application>telnet</application> and
+ <application>rlogin</application> applications that make them
+ unsuitable for dealing with binary streams. Also, by default
+ Kerberos does not encrypt a session unless you use the
+ <option>-x</option> option. <application>ssh</application>
+ encrypts everything by default.</para>
+
+ <para>ssh works quite well in every
+ respect except that it forwards encryption keys by default. What
+ this means is that if you have a secure workstation holding keys
+ that give you access to the rest of the system, and you
+ ssh to an insecure machine, your keys
+ are usable. The actual keys themselves are not exposed, but
+ ssh installs a forwarding port for the
+ duration of your login, and if an attacker has broken
+ <systemitem class="username">root</systemitem> on the
+ insecure machine he can utilize that port to use your keys to gain
+ access to any other machine that your keys unlock.</para>
+
+ <para>We recommend that you use ssh in
+ combination with Kerberos whenever possible for staff logins.
+ <application>ssh</application> can be compiled with Kerberos
+ support. This reduces your reliance on potentially exposed
+ ssh keys while at the same time
+ protecting passwords via Kerberos. ssh
+ keys should only be used for automated tasks from secure machines
+ (something that Kerberos is unsuited to do). We also recommend that
+ you either turn off key-forwarding in the
+ ssh configuration, or that you make use
+ of the <literal>from=IP/DOMAIN</literal> option that
+ ssh allows in its
+ <filename>authorized_keys</filename> file to make the key only
+ usable to entities logging in from specific machines.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="crypt">
+ <info><title>DES, MD5, and Crypt</title>
+ <authorgroup>
+ <author><personname><firstname>Bill</firstname><surname>Swingle</surname></personname><contrib>Parts rewritten and updated by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+ <indexterm>
+ <primary>security</primary>
+ <secondary>crypt</secondary>
+ </indexterm>
+
+ <indexterm><primary>crypt</primary></indexterm>
+ <indexterm><primary>DES</primary></indexterm>
+ <indexterm><primary>MD5</primary></indexterm>
+
+ <para>Every user on a &unix; system has a password associated with
+ their account. It seems obvious that these passwords need to be
+ known only to the user and the actual operating system. In
+ order to keep these passwords secret, they are encrypted with
+ what is known as a <quote>one-way hash</quote>, that is, they can
+ only be easily encrypted but not decrypted. In other words, what
+ we told you a moment ago was obvious is not even true: the
+ operating system itself does not <emphasis>really</emphasis> know
+ the password. It only knows the <emphasis>encrypted</emphasis>
+ form of the password. The only way to get the
+ <quote>plain-text</quote> password is by a brute force search of the
+ space of possible passwords.</para>
+
+ <para>Unfortunately the only secure way to encrypt passwords when
+ &unix; came into being was based on DES, the Data Encryption
+ Standard. This was not such a problem for users resident in
+ the US, but since the source code for DES could not be exported
+ outside the US, &os; had to find a way to both comply with
+ US law and retain compatibility with all the other &unix;
+ variants that still used DES.</para>
+
+ <para>The solution was to divide up the encryption libraries
+ so that US users could install the DES libraries and use
+ DES but international users still had an encryption method
+ that could be exported abroad. This is how &os; came to
+ use MD5 as its default encryption method. MD5 is believed to
+ be more secure than DES, so installing DES is offered primarily
+ for compatibility reasons.</para>
+
+ <sect2>
+ <title>Recognizing Your Crypt Mechanism</title>
+
+ <para>Before &os;&nbsp;4.4 <filename>libcrypt.a</filename> was a
+ symbolic link pointing to the library which was used for
+ encryption. &os;&nbsp;4.4 changed <filename>libcrypt.a</filename> to
+ provide a configurable password authentication hash library.
+ Currently the library supports DES, MD5 and Blowfish hash
+ functions. By default &os; uses MD5 to encrypt
+ passwords.</para>
+
+ <para>It is pretty easy to identify which encryption method
+ &os; is set up to use. Examining the encrypted passwords in
+ the <filename>/etc/master.passwd</filename> file is one way.
+ Passwords encrypted with the MD5 hash are longer than those
+ encrypted with the DES hash and also begin with the characters
+ <literal>&dollar;1&dollar;</literal>. Passwords starting with
+ <literal>&dollar;2a&dollar;</literal> are encrypted with the
+ Blowfish hash function. DES password strings do not
+ have any particular identifying characteristics, but they are
+ shorter than MD5 passwords, and are coded in a 64-character
+ alphabet which does not include the <literal>&dollar;</literal>
+ character, so a relatively short string which does not begin with
+ a dollar sign is very likely a DES password.</para>
+
+ <para>The password format used for new passwords is controlled
+ by the <literal>passwd_format</literal> login capability in
+ <filename>/etc/login.conf</filename>, which takes values of
+ <literal>des</literal>, <literal>md5</literal> or
+ <literal>blf</literal>. See the &man.login.conf.5; manual page
+ for more information about login capabilities.</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="one-time-passwords">
+ <title>One-time Passwords</title>
+ <indexterm><primary>one-time passwords</primary></indexterm>
+ <indexterm>
+ <primary>security</primary>
+ <secondary>one-time passwords</secondary>
+ </indexterm>
+
+ <para>S/Key is a one-time password scheme based on a one-way hash
+ function. &os; uses the MD4 hash for compatibility but other
+ systems have used MD5 and DES-MAC. S/Key has been part of the
+ &os; base system since version 1.1.5 and is also used on a
+ growing number of other operating systems. S/Key is a registered
+ trademark of Bell Communications Research, Inc.</para>
+
+ <para>From version 5.0 of &os;, S/Key has been replaced with
+ the functionally equivalent OPIE (One-time Passwords In
+ Everything). OPIE uses the MD5 hash by default.</para>
+
+ <para>There are three different sorts of passwords which we will discuss
+ below. The first is your usual &unix; style or
+ Kerberos password; we will call this a <quote>&unix; password</quote>.
+ The second sort is the one-time password which is generated by the
+ S/Key <command>key</command> program or the OPIE
+ &man.opiekey.1; program and accepted by the
+ <command>keyinit</command> or &man.opiepasswd.1; programs
+ and the login prompt; we will
+ call this a <quote>one-time password</quote>. The final sort of
+ password is the secret password which you give to the
+ <command>key</command>/<command>opiekey</command> programs (and
+ sometimes the
+ <command>keyinit</command>/<command>opiepasswd</command> programs)
+ which it uses to generate
+ one-time passwords; we will call it a <quote>secret password</quote>
+ or just unqualified <quote>password</quote>.</para>
+
+ <para>The secret password does not have anything to do with your &unix;
+ password; they can be the same but this is not recommended. S/Key
+ and OPIE secret passwords are not limited to 8 characters like old
+ &unix; passwords<footnote><para>Under &os; the standard login
+ password may be up to 128 characters in length.</para></footnote>,
+ they can be as long as you like. Passwords of six or
+ seven word long phrases are fairly common. For the most part, the
+ S/Key or OPIE system operates completely independently of the &unix;
+ password system.</para>
+
+ <para>Besides the password, there are two other pieces of data that
+ are important to S/Key and OPIE. One is what is known as the
+ <quote>seed</quote> or <quote>key</quote>, consisting of two letters
+ and five digits. The other is what is called the <quote>iteration
+ count</quote>, a number between 1 and 100. S/Key creates the
+ one-time password by concatenating the seed and the secret password,
+ then applying the MD4/MD5 hash as many times as specified by the
+ iteration count and turning the result into six short English words.
+ These six English words are your one-time password. The
+ authentication system (primarily PAM) keeps
+ track of the last one-time password used, and the user is
+ authenticated if the hash of the user-provided password is equal to
+ the previous password. Because a one-way hash is used it is
+ impossible to generate future one-time passwords if a successfully
+ used password is captured; the iteration count is decremented after
+ each successful login to keep the user and the login program in
+ sync. When the iteration count gets down to 1, S/Key and OPIE must be
+ reinitialized.</para>
+
+ <para>There are three programs involved in each system
+ which we will discuss below. The <command>key</command> and
+ <command>opiekey</command> programs accept an iteration
+ count, a seed, and a secret password, and generate a one-time
+ password or a consecutive list of one-time passwords. The
+ <command>keyinit</command> and <command>opiepasswd</command>
+ programs are used to initialize S/Key and OPIE respectively,
+ and to change passwords, iteration counts, or seeds; they
+ take either a secret passphrase, or an iteration count,
+ seed, and one-time password. The <command>keyinfo</command>
+ and <command>opieinfo</command> programs examine the
+ relevant credentials files (<filename>/etc/skeykeys</filename> or
+ <filename>/etc/opiekeys</filename>) and print out the invoking user's
+ current iteration count and seed.</para>
+
+ <para>There are four different sorts of operations we will cover. The
+ first is using <command>keyinit</command> or
+ <command>opiepasswd</command> over a secure connection to set up
+ one-time-passwords for the first time, or to change your password
+ or seed. The second operation is using <command>keyinit</command>
+ or <command>opiepasswd</command> over an insecure connection, in
+ conjunction with <command>key</command> or <command>opiekey</command>
+ over a secure connection, to do the same. The third is using
+ <command>key</command>/<command>opiekey</command> to log in over
+ an insecure connection. The fourth is using <command>key</command>
+ or <command>opiekey</command> to generate a number of keys which
+ can be written down or printed out to carry with you when going to
+ some location without secure connections to anywhere.</para>
+
+ <sect2>
+ <title>Secure Connection Initialization</title>
+
+ <para>To initialize S/Key for the first time, change your password,
+ or change your seed while logged in over a secure connection
+ (e.g. on the console of a machine or via <application>ssh</application>), use the
+ <command>keyinit</command> command without any parameters while
+ logged in as yourself:</para>
+
+ <screen>&prompt.user; <userinput>keyinit</userinput>
+Adding unfurl:
+Reminder - Only use this method if you are directly connected.
+If you are using telnet or rlogin exit with no password and use keyinit -s.
+Enter secret password:
+Again secret password:
+
+ID unfurl s/key is 99 to17757
+DEFY CLUB PRO NASH LACE SOFT</screen>
+
+ <para>For OPIE, <command>opiepasswd</command> is used instead:</para>
+
+ <screen>&prompt.user; <userinput>opiepasswd -c</userinput>
+[grimreaper] ~ $ opiepasswd -f -c
+Adding unfurl:
+Only use this method from the console; NEVER from remote. If you are using
+telnet, xterm, or a dial-in, type ^C now or exit with no password.
+Then run opiepasswd without the -c parameter.
+Using MD5 to compute responses.
+Enter new secret pass phrase:
+Again new secret pass phrase:
+ID unfurl OTP key is 499 to4268
+MOS MALL GOAT ARM AVID COED
+</screen>
+
+ <para>At the <prompt>Enter new secret pass phrase:</prompt> or
+ <prompt>Enter secret password:</prompt> prompts, you
+ should enter a password or phrase. Remember, this is not the
+ password that you will use to login with, this is used to generate
+ your one-time login keys. The <quote>ID</quote> line gives the
+ parameters of your particular instance: your login name, the
+ iteration count, and seed. When logging in the system
+ will remember these parameters and present them back to you so you
+ do not have to remember them. The last line gives the particular
+ one-time password which corresponds to those parameters and your
+ secret password; if you were to re-login immediately, this
+ one-time password is the one you would use.</para>
+ </sect2>
+
+ <sect2>
+ <title>Insecure Connection Initialization</title>
+
+ <para>To initialize or change your secret password over an
+ insecure connection, you will need to already have a secure
+ connection to some place where you can run <command>key</command>
+ or <command>opiekey</command>; this might be in the form of a
+ desk accessory on a &macintosh;, or a shell prompt on a machine you
+ trust. You will also need to make up an iteration count (100 is
+ probably a good value), and you may make up your own seed or use a
+ randomly-generated one. Over on the insecure connection (to the
+ machine you are initializing), use the <command>keyinit
+ -s</command> command:</para>
+
+ <screen>&prompt.user; <userinput>keyinit -s</userinput>
+Updating unfurl:
+Old key: to17758
+Reminder you need the 6 English words from the key command.
+Enter sequence count from 1 to 9999: <userinput>100</userinput>
+Enter new key [default to17759]:
+s/key 100 to 17759
+s/key access password:
+s/key access password:<userinput>CURE MIKE BANE HIM RACY GORE</userinput>
+</screen>
+
+ <para>For OPIE, you need to use <command>opiepasswd</command>:</para>
+
+ <screen>&prompt.user; <userinput>opiepasswd</userinput>
+
+Updating unfurl:
+You need the response from an OTP generator.
+Old secret pass phrase:
+ otp-md5 498 to4268 ext
+ Response: GAME GAG WELT OUT DOWN CHAT
+New secret pass phrase:
+ otp-md5 499 to4269
+ Response: LINE PAP MILK NELL BUOY TROY
+
+ID mark OTP key is 499 gr4269
+LINE PAP MILK NELL BUOY TROY
+</screen>
+
+ <para>To accept the default seed (which the
+ <command>keyinit</command> program confusingly calls a
+ <literal>key</literal>), press <keycap>Return</keycap>.
+ Then before entering an
+ access password, move over to your secure connection or S/Key desk
+ accessory, and give it the same parameters:</para>
+
+ <screen>&prompt.user; <userinput>key 100 to17759</userinput>
+Reminder - Do not use this program while logged in via telnet or rlogin.
+Enter secret password: <userinput>&lt;secret password&gt;</userinput>
+CURE MIKE BANE HIM RACY GORE</screen>
+
+ <para>Or for OPIE:</para>
+
+ <screen>&prompt.user; <userinput>opiekey 498 to4268</userinput>
+Using the MD5 algorithm to compute response.
+Reminder: Don't use opiekey from telnet or dial-in sessions.
+Enter secret pass phrase:
+GAME GAG WELT OUT DOWN CHAT
+</screen>
+
+ <para>Now switch back over to the insecure connection, and copy the
+ one-time password generated over to the relevant program.</para>
+ </sect2>
+
+ <sect2>
+ <title>Generating a Single One-time Password</title>
+
+ <para>Once you have initialized S/Key or OPIE, when you login you will be
+ presented with a prompt like this:</para>
+
+<screen>&prompt.user; <userinput>telnet example.com</userinput>
+Trying 10.0.0.1...
+Connected to example.com
+Escape character is '^]'.
+
+FreeBSD/i386 (example.com) (ttypa)
+
+login: <userinput>&lt;username&gt;</userinput>
+s/key 97 fw13894
+Password: </screen>
+
+ <para>Or for OPIE:</para>
+
+<screen>&prompt.user; <userinput>telnet example.com</userinput>
+Trying 10.0.0.1...
+Connected to example.com
+Escape character is '^]'.
+
+FreeBSD/i386 (example.com) (ttypa)
+
+login: <userinput>&lt;username&gt;</userinput>
+otp-md5 498 gr4269 ext
+Password: </screen>
+
+ <para>As a side note, the S/Key and OPIE prompts have a useful feature
+ (not shown here): if you press <keycap>Return</keycap>
+ at the password prompt, the
+ prompter will turn echo on, so you can see what you are
+ typing. This can be extremely useful if you are attempting to
+ type in a password by hand, such as from a printout.</para>
+
+ <indexterm><primary>MS-DOS</primary></indexterm>
+ <indexterm><primary>Windows</primary></indexterm>
+ <indexterm><primary>MacOS</primary></indexterm>
+
+ <para>At this point you need to generate your one-time password to
+ answer this login prompt. This must be done on a trusted system
+ that you can run <command>key</command> or
+ <command>opiekey</command> on. (There are versions of these for DOS,
+ &windows; and &macos; as well.) They need both the iteration count and
+ the seed as command line options. You can cut-and-paste these
+ right from the login prompt on the machine that you are logging
+ in to.</para>
+
+ <para>On the trusted system:</para>
+
+ <screen>&prompt.user; <userinput>key 97 fw13894</userinput>
+Reminder - Do not use this program while logged in via telnet or rlogin.
+Enter secret password:
+WELD LIP ACTS ENDS ME HAAG</screen>
+
+ <para>For OPIE:</para>
+
+ <screen>&prompt.user; <userinput>opiekey 498 to4268</userinput>
+Using the MD5 algorithm to compute response.
+Reminder: Don't use opiekey from telnet or dial-in sessions.
+Enter secret pass phrase:
+GAME GAG WELT OUT DOWN CHAT</screen>
+
+ <para>Now that you have your one-time password you can continue
+ logging in:</para>
+
+ <screen>login: <userinput>&lt;username&gt;</userinput>
+s/key 97 fw13894
+Password: <userinput>&lt;return to enable echo&gt;</userinput>
+s/key 97 fw13894
+Password [echo on]: WELD LIP ACTS ENDS ME HAAG
+Last login: Tue Mar 21 11:56:41 from 10.0.0.2 ... </screen>
+
+ </sect2>
+
+ <sect2>
+ <title>Generating Multiple One-time Passwords</title>
+
+ <para>Sometimes you have to go places where you do not have
+ access to a trusted machine or secure connection. In this case,
+ it is possible to use the <command>key</command> and
+ <command>opiekey</command> commands to
+ generate a number of one-time passwords beforehand to be printed
+ out and taken with you. For example:</para>
+
+ <screen>&prompt.user; <userinput>key -n 5 30 zz99999</userinput>
+Reminder - Do not use this program while logged in via telnet or rlogin.
+Enter secret password: <userinput>&lt;secret password&gt;</userinput>
+26: SODA RUDE LEA LIND BUDD SILT
+27: JILT SPY DUTY GLOW COWL ROT
+28: THEM OW COLA RUNT BONG SCOT
+29: COT MASH BARR BRIM NAN FLAG
+30: CAN KNEE CAST NAME FOLK BILK</screen>
+
+ <para>Or for OPIE:</para>
+
+ <screen>&prompt.user; <userinput>opiekey -n 5 30 zz99999</userinput>
+Using the MD5 algorithm to compute response.
+Reminder: Don't use opiekey from telnet or dial-in sessions.
+Enter secret pass phrase: <userinput>&lt;secret password&gt;</userinput>
+26: JOAN BORE FOSS DES NAY QUIT
+27: LATE BIAS SLAY FOLK MUCH TRIG
+28: SALT TIN ANTI LOON NEAL USE
+29: RIO ODIN GO BYE FURY TIC
+30: GREW JIVE SAN GIRD BOIL PHI</screen>
+
+ <para>The <option>-n 5</option> requests five keys in sequence, the
+ <option>30</option> specifies what the last iteration number
+ should be. Note that these are printed out in
+ <emphasis>reverse</emphasis> order of eventual use. If you are
+ really paranoid, you might want to write the results down by hand;
+ otherwise you can cut-and-paste into <command>lpr</command>. Note
+ that each line shows both the iteration count and the one-time
+ password; you may still find it handy to scratch off passwords as
+ you use them.</para>
+ </sect2>
+
+ <sect2>
+ <title>Restricting Use of &unix; Passwords</title>
+
+ <para>S/Key can place restrictions on the use of &unix; passwords based
+ on the host name, user name, terminal port, or IP address of a
+ login session. These restrictions can be found in the
+ configuration file <filename>/etc/skey.access</filename>. The
+ &man.skey.access.5; manual page has more information on the complete
+ format of the file and also details some security cautions to be
+ aware of before depending on this file for security.</para>
+
+ <para>If there is no <filename>/etc/skey.access</filename> file
+ (this is the default on &os;&nbsp;4.X systems), then all users will
+ be allowed to use &unix; passwords. If the file exists, however,
+ then all users will be required to use S/Key unless explicitly
+ permitted to do otherwise by configuration statements in the
+ <filename>skey.access</filename> file. In all cases, &unix;
+ passwords are permitted on the console.</para>
+
+ <para>Here is a sample <filename>skey.access</filename> configuration
+ file which illustrates the three most common sorts of configuration
+ statements:</para>
+
+ <programlisting>permit internet 192.168.0.0 255.255.0.0
+permit user fnord
+permit port ttyd0</programlisting>
+
+ <para>The first line (<literal>permit internet</literal>) allows
+ users whose IP source address (which is vulnerable to spoofing)
+ matches the specified value and mask, to use &unix; passwords. This
+ should not be considered a security mechanism, but rather, a means
+ to remind authorized users that they are using an insecure network
+ and need to use S/Key for authentication.</para>
+
+ <para>The second line (<literal>permit user</literal>) allows the
+ specified username, in this case <systemitem class="username">fnord</systemitem>, to use
+ &unix; passwords at any time. Generally speaking, this should only
+ be used for people who are either unable to use the
+ <command>key</command> program, like those with dumb terminals, or
+ those who are ineducable.</para>
+
+ <para>The third line (<literal>permit port</literal>) allows all
+ users logging in on the specified terminal line to use &unix;
+ passwords; this would be used for dial-ups.</para>
+
+ <para>OPIE can restrict the use of &unix; passwords based on the IP
+ address of a login session just like S/Key does. The relevant file
+ is <filename>/etc/opieaccess</filename>, which is present by default
+ on &os;&nbsp;5.0 and newer systems. Please check &man.opieaccess.5;
+ for more information on this file and which security considerations
+ you should be aware of when using it.</para>
+
+ <para>Here is a sample <filename>opieaccess</filename> file:</para>
+
+ <programlisting>permit 192.168.0.0 255.255.0.0</programlisting>
+
+ <para>This line allows users whose IP source address (which is
+ vulnerable to spoofing) matches the specified value and mask,
+ to use &unix; passwords at any time.</para>
+
+ <para>If no rules in <filename>opieaccess</filename> are matched,
+ the default is to deny non-OPIE logins.</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="tcpwrappers">
+ <info><title>TCP Wrappers</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Written by: </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm><primary>TCP Wrappers</primary></indexterm>
+
+ <para>每個熟 &man.inetd.8; 的人幾乎都會聽過 <acronym>TCP</acronym>
+ Wrappers 這個東西,但很少人能完全瞭解它在網路環境上的好用在哪。
+ 大多數的人都會裝防火牆來保護網路,雖然,防火牆用途非常廣泛,但並非萬能。
+ 例如:若打算回傳一段文字給連線來源者等之類的。而 <acronym>TCP</acronym>
+ 軟體卻可以做到這點,還有其他更多事情。在以下段落內,我們將繼續介紹
+ <acronym>TCP</acronym> Wrappers 提供的功能,以及一些實際運用的例子。</para>
+
+ <para><acronym>TCP</acronym> Wrappers 可以讓 <command>inetd</command>
+ 所管理的每個 server daemon ,都會在 <acronym>TCP</acronym> Wrappers
+ 的掌握之下。透過 <acronym>TCP</acronym> Wrappers 這種方式可以支援連線紀錄(logging)
+ 、回傳一段文字給連線來源者、可以讓 daemon 只接受內部連線等等。
+ 雖然其中部份功能用防火牆也可以做到,但 <acronym>TCP</acronym> Wrappers
+ 不只是增加了一層保護,還提供了防火牆所辦不到的事情。</para>
+
+ <para>然而, 由 <acronym>TCP</acronym> Wrappers 所提供的這些額外安全功能,
+ 不應該視為優秀防火牆的替代方案。應該結合 <acronym>TCP</acronym> Wrappers
+ 及防火牆、其他加強安全措施來一併運用才對,這樣才可以為系統提供多層安全防護。</para>
+
+ <para>由於這些設定是主要針對
+ <command>inetd</command> 所提供的,所以我們建議您先參閱 <link linkend="network-inetd">inetd 設定</link> 一節。</para>
+
+ <note>
+ <para>雖然 &man.inetd.8; 所啟動的程式並非全部都是真正的
+ 『daemons』,但一般來講,我們都還是會稱呼為『daemons』,
+ 下面我們仍將使用這字眼來表達。</para>
+ </note>
+
+ <sect2>
+ <title>Initial Configuration</title>
+
+ <para>若要在 &os; 中使用 <acronym>TCP</acronym>
+ Wrappers 的話,只要確定 <command>inetd</command>
+ 在啟動時,有在 <filename>/etc/rc.conf</filename> 加上
+ <option>-Ww</option> 的參數即可,這個設定在系統預設就有了。
+ 當然還需要適當修改 <filename>/etc/hosts.allow</filename> 設定檔,但
+ &man.syslogd.8; 仍會在系統 log 檔內,紀錄相關資料下來。</para>
+
+ <note>
+ <para>FreeBSD 的 <acronym>TCP</acronym> Wrappers 實作方式與其他作業系統上的
+ <acronym>TCP</acronym> Wrappers 不太一樣,目前 FreeBSD 已經廢棄不用
+ <filename>/etc/hosts.deny</filename> ,而一律改用
+ <filename>/etc/hosts.allow</filename>。</para>
+ </note>
+
+ <para>最簡單的設定方式是,每個對 daemon 的連線都由
+ <filename>/etc/hosts.allow</filename> 來決定是否允許或拒絕。 The default
+ configuration in &os; is to allow a connection to every daemon
+ started with <command>inetd</command>. Changing this will be
+ discussed only after the basic configuration is covered.</para>
+
+ <para>Basic configuration usually takes the form of
+ <literal>daemon : address : action</literal>. Where
+ <literal>daemon</literal> is the daemon name which
+ <command>inetd</command> started. The
+ <literal>address</literal> can be a valid hostname, an
+ <acronym>IP</acronym> address or an IPv6 address enclosed in
+ brackets ([&nbsp;]). The action field can be either allow
+ or deny to grant or deny access appropriately. Keep in mind
+ that configuration works off a first rule match semantic,
+ meaning that the configuration file is scanned in ascending
+ order for a matching rule. When a match is found the rule
+ is applied and the search process will halt.</para>
+
+ <para>Several other options exist but they will be explained
+ in a later section. A simple configuration line may easily be
+ constructed from that information alone. For example, to
+ allow <acronym>POP</acronym>3 connections via the
+ <package>mail/qpopper</package> daemon,
+ the following lines should be appended to
+ <filename>hosts.allow</filename>:</para>
+
+ <programlisting># This line is required for POP3 connections:
+qpopper : ALL : allow</programlisting>
+
+ <para>加上上面這行之後,必須重新啟動 <command>inetd</command>。重新啟動的方式可以用
+ &man.kill.1; 指令,或打『 <filename>/etc/rc.d/inetd</filename> <parameter>restart</parameter>
+ 』 來完成。</para>
+ </sect2>
+
+ <sect2>
+ <title>Advanced Configuration</title>
+
+ <para><acronym>TCP</acronym> Wrappers has advanced
+ options too; they will allow for more control over the
+ way connections are handled. In some cases it may be
+ a good idea to return a comment to certain hosts or
+ daemon connections. In other cases, perhaps a log file
+ should be recorded or an email sent to the administrator.
+ Other situations may require the use of a service for local
+ connections only. This is all possible through the use of
+ configuration options known as <literal>wildcards</literal>,
+ expansion characters and external command execution. The
+ next two sections are written to cover these situations.</para>
+
+ <sect3>
+ <title>External Commands</title>
+
+ <para>Suppose that a situation occurs where a connection
+ should be denied yet a reason should be sent to the
+ individual who attempted to establish that connection. How
+ could it be done? That action can be made possible by
+ using the <option>twist</option> option. When a connection
+ attempt is made, <option>twist</option> will be called to
+ execute a shell command or script. An example already exists
+ in the <filename>hosts.allow</filename> file:</para>
+
+ <programlisting># The rest of the daemons are protected.
+ALL : ALL \
+ : severity auth.info \
+ : twist /bin/echo "You are not welcome to use %d from %h."</programlisting>
+
+ <para>This example shows that the message,
+ <quote>You are not allowed to use <literal>daemon</literal>
+ from <literal>hostname</literal>.</quote> will be returned
+ for any daemon not previously configured in the access file.
+ This is extremely useful for sending a reply back to the
+ connection initiator right after the established connection
+ is dropped. Note that any message returned
+ <emphasis>must</emphasis> be wrapped in quote
+ <literal>"</literal> characters; there are no exceptions to
+ this rule.</para>
+
+ <warning>
+ <para>It may be possible to launch a denial of service attack
+ on the server if an attacker, or group of attackers could
+ flood these daemons with connection requests.</para>
+ </warning>
+
+ <para>Another possibility is to use the <option>spawn</option>
+ option in these cases. Like <option>twist</option>, the
+ <option>spawn</option> implicitly denies the connection and
+ may be used to run external shell commands or scripts.
+ Unlike <option>twist</option>, <option>spawn</option> will
+ not send a reply back to the individual who established the
+ connection. For an example, consider the following
+ configuration line:</para>
+
+ <programlisting># We do not allow connections from example.com:
+ALL : .example.com \
+ : spawn (/bin/echo %a from %h attempted to access %d &gt;&gt; \
+ /var/log/connections.log) \
+ : deny</programlisting>
+
+ <para>This will deny all connection attempts from the
+ <systemitem class="fqdomainname">*.example.com</systemitem> domain;
+ simultaneously logging the hostname, <acronym>IP</acronym>
+ address and the daemon which they attempted to access in the
+ <filename>/var/log/connections.log</filename> file.</para>
+
+ <para>Aside from the already explained substitution characters
+ above, e.g. %a, a few others exist. See the
+ &man.hosts.access.5; manual page for the complete list.</para>
+ </sect3>
+
+ <sect3>
+ <title>Wildcard Options</title>
+
+ <para>Thus far the <literal>ALL</literal> example has been used
+ continuously throughout the examples. Other options exist
+ which could extend the functionality a bit further. For
+ instance, <literal>ALL</literal> may be used to match every
+ instance of either a daemon, domain or an
+ <acronym>IP</acronym> address. Another wildcard available is
+ <literal>PARANOID</literal> which may be used to match any
+ host which provides an <acronym>IP</acronym> address that may
+ be forged. In other words, <literal>paranoid</literal> may
+ be used to define an action to be taken whenever a connection
+ is made from an <acronym>IP</acronym> address that differs
+ from its hostname. The following example may shed some more
+ light on this discussion:</para>
+
+ <programlisting># Block possibly spoofed requests to sendmail:
+sendmail : PARANOID : deny</programlisting>
+
+ <para>In that example all connection requests to
+ <command>sendmail</command> which have an
+ <acronym>IP</acronym> address that varies from its hostname
+ will be denied.</para>
+
+ <caution>
+ <para>Using the <literal>PARANOID</literal> may severely
+ cripple servers if the client or server has a broken
+ <acronym>DNS</acronym> setup. Administrator discretion
+ is advised.</para>
+ </caution>
+
+ <para>To learn more about wildcards and their associated
+ functionality, see the &man.hosts.access.5; manual
+ page.</para>
+
+ <para>Before any of the specific configuration lines above will
+ work, the first configuration line should be commented out
+ in <filename>hosts.allow</filename>. This was noted at the
+ beginning of this section.</para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="kerberosIV">
+ <info><title><application>KerberosIV</application></title>
+ <authorgroup>
+ <author><personname><firstname>Mark</firstname><surname>Murray</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Mark</firstname><surname>Dapoz</surname></personname><contrib>Based on a contribution by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <para>Kerberos is a network add-on system/protocol that allows users to
+ authenticate themselves through the services of a secure server.
+ Services such as remote login, remote copy, secure inter-system file
+ copying and other high-risk tasks are made considerably safer and more
+ controllable.</para>
+
+ <para>The following instructions can be used as a guide on how to set up
+ Kerberos as distributed for &os;. However, you should refer to the
+ relevant manual pages for a complete description.</para>
+
+ <sect2>
+ <title>Installing <application>KerberosIV</application></title>
+
+ <indexterm><primary>MIT</primary></indexterm>
+ <indexterm>
+ <primary>KerberosIV</primary>
+ <secondary>installing</secondary>
+ </indexterm>
+ <para>Kerberos is an optional component of &os;. The easiest
+ way to install this software is by selecting the <literal>krb4</literal> or
+ <literal>krb5</literal> distribution in <application>sysinstall</application>
+ during the initial installation of &os;. This will install
+ the <quote>eBones</quote> (KerberosIV) or <quote>Heimdal</quote> (Kerberos5)
+ implementation of Kerberos. These implementations are
+ included because they are developed outside the USA/Canada and
+ were thus available to system owners outside those countries
+ during the era of restrictive export controls on cryptographic
+ code from the USA.</para>
+
+ <para>Alternatively, the MIT implementation of Kerberos is
+ available from the Ports Collection as
+ <package>security/krb5</package>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Creating the Initial Database</title>
+
+ <para>This is done on the Kerberos server only. First make sure that
+ you do not have any old Kerberos databases around. You should change
+ to the directory <filename>/etc/kerberosIV</filename> and check that
+ only the following files are present:</para>
+
+ <screen>&prompt.root; <userinput>cd /etc/kerberosIV</userinput>
+&prompt.root; <userinput>ls</userinput>
+README krb.conf krb.realms</screen>
+
+ <para>If any additional files (such as <filename>principal.*</filename>
+ or <filename>master_key</filename>) exist, then use the
+ <command>kdb_destroy</command> command to destroy the old Kerberos
+ database, or if Kerberos is not running, simply delete the extra
+ files.</para>
+
+ <para>You should now edit the <filename>krb.conf</filename> and
+ <filename>krb.realms</filename> files to define your Kerberos realm.
+ In this case the realm will be <literal>EXAMPLE.COM</literal> and the
+ server is <systemitem class="fqdomainname">grunt.example.com</systemitem>. We edit
+ or create the <filename>krb.conf</filename> file:</para>
+
+ <screen>&prompt.root; <userinput>cat krb.conf</userinput>
+EXAMPLE.COM
+EXAMPLE.COM grunt.example.com admin server
+CS.BERKELEY.EDU okeeffe.berkeley.edu
+ATHENA.MIT.EDU kerberos.mit.edu
+ATHENA.MIT.EDU kerberos-1.mit.edu
+ATHENA.MIT.EDU kerberos-2.mit.edu
+ATHENA.MIT.EDU kerberos-3.mit.edu
+LCS.MIT.EDU kerberos.lcs.mit.edu
+TELECOM.MIT.EDU bitsy.mit.edu
+ARC.NASA.GOV trident.arc.nasa.gov</screen>
+
+ <para>In this case, the other realms do not need to be there. They are
+ here as an example of how a machine may be made aware of multiple
+ realms. You may wish to not include them for simplicity.</para>
+
+ <para>The first line names the realm in which this system works. The
+ other lines contain realm/host entries. The first item on a line is a
+ realm, and the second is a host in that realm that is acting as a
+ <quote>key distribution center</quote>. The words <literal>admin
+ server</literal> following a host's name means that host also
+ provides an administrative database server. For further explanation
+ of these terms, please consult the Kerberos manual pages.</para>
+
+ <para>Now we have to add <systemitem class="fqdomainname">grunt.example.com</systemitem>
+ to the <literal>EXAMPLE.COM</literal> realm and also add an entry to
+ put all hosts in the <systemitem class="fqdomainname">.example.com</systemitem>
+ domain in the <literal>EXAMPLE.COM</literal> realm. The
+ <filename>krb.realms</filename> file would be updated as
+ follows:</para>
+
+ <screen>&prompt.root; <userinput>cat krb.realms</userinput>
+grunt.example.com EXAMPLE.COM
+.example.com EXAMPLE.COM
+.berkeley.edu CS.BERKELEY.EDU
+.MIT.EDU ATHENA.MIT.EDU
+.mit.edu ATHENA.MIT.EDU</screen>
+
+ <para>Again, the other realms do not need to be there. They are here as
+ an example of how a machine may be made aware of multiple realms. You
+ may wish to remove them to simplify things.</para>
+
+ <para>The first line puts the <emphasis>specific</emphasis> system into
+ the named realm. The rest of the lines show how to default systems of
+ a particular subdomain to a named realm.</para>
+
+ <para>Now we are ready to create the database. This only needs to run
+ on the Kerberos server (or Key Distribution Center). Issue the
+ <command>kdb_init</command> command to do this:</para>
+
+ <screen>&prompt.root; <userinput>kdb_init</userinput>
+<prompt>Realm name [default ATHENA.MIT.EDU ]:</prompt> <userinput>EXAMPLE.COM</userinput>
+You will be prompted for the database Master Password.
+It is important that you NOT FORGET this password.
+
+<prompt>Enter Kerberos master key:</prompt> </screen>
+
+ <para>Now we have to save the key so that servers on the local machine
+ can pick it up. Use the <command>kstash</command> command to do
+ this:</para>
+
+ <screen>&prompt.root; <userinput>kstash</userinput>
+
+<prompt>Enter Kerberos master key:</prompt>
+
+Current Kerberos master key version is 1.
+
+Master key entered. BEWARE!</screen>
+
+ <para>This saves the encrypted master password in
+ <filename>/etc/kerberosIV/master_key</filename>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Making It All Run</title>
+
+ <indexterm>
+ <primary>KerberosIV</primary>
+ <secondary>initial startup</secondary>
+ </indexterm>
+
+ <para>Two principals need to be added to the database for
+ <emphasis>each</emphasis> system that will be secured with Kerberos.
+ Their names are <literal>kpasswd</literal> and <literal>rcmd</literal>.
+ These two principals are made for each system, with the instance being
+ the name of the individual system.</para>
+
+ <para>These daemons, <application>kpasswd</application> and
+ <application>rcmd</application> allow other systems to change Kerberos
+ passwords and run commands like &man.rcp.1;,
+ &man.rlogin.1; and &man.rsh.1;.</para>
+
+ <para>Now let us add these entries:</para>
+
+ <screen>&prompt.root; <userinput>kdb_edit</userinput>
+Opening database...
+
+<prompt>Enter Kerberos master key:</prompt>
+
+Current Kerberos master key version is 1.
+
+Master key entered. BEWARE!
+Previous or default values are in [brackets] ,
+enter return to leave the same, or new value.
+
+<prompt>Principal name:</prompt> <userinput>passwd</userinput>
+<prompt>Instance:</prompt> <userinput>grunt</userinput>
+
+&lt;Not found&gt;, <prompt>Create [y] ?</prompt> <userinput>y</userinput>
+
+Principal: passwd, Instance: grunt, kdc_key_ver: 1
+<prompt>New Password:</prompt> &lt;---- enter RANDOM here
+Verifying password
+
+<prompt>New Password:</prompt> &lt;---- enter RANDOM here
+
+<prompt>Random password [y] ?</prompt> <userinput>y</userinput>
+
+Principal's new key version = 1
+<prompt>Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?</prompt>
+<prompt>Max ticket lifetime (*5 minutes) [ 255 ] ?</prompt>
+<prompt>Attributes [ 0 ] ?</prompt>
+Edit O.K.
+<prompt>Principal name:</prompt> <userinput>rcmd</userinput>
+<prompt>Instance:</prompt> <userinput>grunt</userinput>
+
+&lt;Not found&gt;, <prompt>Create [y] ?</prompt>
+
+Principal: rcmd, Instance: grunt, kdc_key_ver: 1
+<prompt>New Password:</prompt> &lt;---- enter RANDOM here
+Verifying password
+
+<prompt>New Password:</prompt> &lt;---- enter RANDOM here
+
+<prompt>Random password [y] ?</prompt>
+
+Principal's new key version = 1
+<prompt>Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?</prompt>
+<prompt>Max ticket lifetime (*5 minutes) [ 255 ] ?</prompt>
+<prompt>Attributes [ 0 ] ?</prompt>
+Edit O.K.
+<prompt>Principal name:</prompt> &lt;---- null entry here will cause an exit</screen>
+ </sect2>
+
+ <sect2>
+ <title>Creating the Server File</title>
+
+ <para>We now have to extract all the instances which define the
+ services on each machine. For this we use the
+ <command>ext_srvtab</command> command. This will create a file
+ which must be copied or moved <emphasis>by secure
+ means</emphasis> to each Kerberos client's
+ <filename>/etc/kerberosIV</filename> directory. This file must
+ be present on each server and client, and is crucial to the
+ operation of Kerberos.</para>
+
+
+ <screen>&prompt.root; <userinput>ext_srvtab grunt</userinput>
+<prompt>Enter Kerberos master key:</prompt>
+
+Current Kerberos master key version is 1.
+
+Master key entered. BEWARE!
+Generating 'grunt-new-srvtab'....</screen>
+
+ <para>Now, this command only generates a temporary file which must be
+ renamed to <filename>srvtab</filename> so that all the servers can pick
+ it up. Use the &man.mv.1; command to move it into place on
+ the original system:</para>
+
+ <screen>&prompt.root; <userinput>mv grunt-new-srvtab srvtab</userinput></screen>
+
+ <para>If the file is for a client system, and the network is not deemed
+ safe, then copy the
+ <filename>client-new-srvtab</filename> to
+ removable media and transport it by secure physical means. Be sure to
+ rename it to <filename>srvtab</filename> in the client's
+ <filename>/etc/kerberosIV</filename> directory, and make sure it is
+ mode 600:</para>
+
+ <screen>&prompt.root; <userinput>mv grumble-new-srvtab srvtab</userinput>
+&prompt.root; <userinput>chmod 600 srvtab</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Populating the Database</title>
+
+ <para>We now have to add some user entries into the database. First
+ let us create an entry for the user <systemitem class="username">jane</systemitem>. Use the
+ <command>kdb_edit</command> command to do this:</para>
+
+ <screen>&prompt.root; <userinput>kdb_edit</userinput>
+Opening database...
+
+<prompt>Enter Kerberos master key:</prompt>
+
+Current Kerberos master key version is 1.
+
+Master key entered. BEWARE!
+Previous or default values are in [brackets] ,
+enter return to leave the same, or new value.
+
+<prompt>Principal name:</prompt> <userinput>jane</userinput>
+<prompt>Instance:</prompt>
+
+&lt;Not found&gt;, <prompt>Create [y] ?</prompt> <userinput>y</userinput>
+
+Principal: jane, Instance: , kdc_key_ver: 1
+<prompt>New Password:</prompt> &lt;---- enter a secure password here
+Verifying password
+
+<prompt>New Password:</prompt> &lt;---- re-enter the password here
+Principal's new key version = 1
+<prompt>Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?</prompt>
+<prompt>Max ticket lifetime (*5 minutes) [ 255 ] ?</prompt>
+<prompt>Attributes [ 0 ] ?</prompt>
+Edit O.K.
+<prompt>Principal name:</prompt> &lt;---- null entry here will cause an exit</screen>
+ </sect2>
+
+ <sect2>
+ <title>Testing It All Out</title>
+
+ <para>First we have to start the Kerberos daemons. Note that if you
+ have correctly edited your <filename>/etc/rc.conf</filename> then this
+ will happen automatically when you reboot. This is only necessary on
+ the Kerberos server. Kerberos clients will automatically get what
+ they need from the <filename>/etc/kerberosIV</filename>
+ directory.</para>
+
+ <screen>&prompt.root; <userinput>kerberos &amp;</userinput>
+Kerberos server starting
+Sleep forever on error
+Log file is /var/log/kerberos.log
+Current Kerberos master key version is 1.
+
+Master key entered. BEWARE!
+
+Current Kerberos master key version is 1
+Local realm: EXAMPLE.COM
+&prompt.root; <userinput>kadmind -n &amp;</userinput>
+KADM Server KADM0.0A initializing
+Please do not use 'kill -9' to kill this job, use a
+regular kill instead
+
+Current Kerberos master key version is 1.
+
+Master key entered. BEWARE!</screen>
+
+ <para>Now we can try using the <command>kinit</command> command to get a
+ ticket for the ID <systemitem class="username">jane</systemitem> that we created
+ above:</para>
+
+ <screen>&prompt.user; <userinput>kinit jane</userinput>
+MIT Project Athena (grunt.example.com)
+Kerberos Initialization for "jane"
+<prompt>Password:</prompt> </screen>
+
+ <para>Try listing the tokens using <command>klist</command> to see if we
+ really have them:</para>
+
+ <screen>&prompt.user; <userinput>klist</userinput>
+Ticket file: /tmp/tkt245
+Principal: jane@EXAMPLE.COM
+
+ Issued Expires Principal
+Apr 30 11:23:22 Apr 30 19:23:22 krbtgt.EXAMPLE.COM@EXAMPLE.COM</screen>
+
+ <para>Now try changing the password using &man.passwd.1; to
+ check if the <application>kpasswd</application> daemon can get
+ authorization to the Kerberos database:</para>
+
+ <screen>&prompt.user; <userinput>passwd</userinput>
+realm EXAMPLE.COM
+<prompt>Old password for jane:</prompt>
+<prompt>New Password for jane:</prompt>
+Verifying password
+<prompt>New Password for jane:</prompt>
+Password changed.</screen>
+ </sect2>
+
+ <sect2>
+ <title>Adding <command>su</command> Privileges</title>
+
+ <para>Kerberos allows us to give <emphasis>each</emphasis> user
+ who needs <systemitem class="username">root</systemitem> privileges their own
+ <emphasis>separate</emphasis> &man.su.1; password.
+ We could now add an ID which is authorized to
+ &man.su.1; to <systemitem class="username">root</systemitem>. This is
+ controlled by having an instance of <systemitem class="username">root</systemitem>
+ associated with a principal. Using <command>kdb_edit</command>
+ we can create the entry <literal>jane.root</literal> in the
+ Kerberos database:</para>
+
+ <screen>&prompt.root; <userinput>kdb_edit</userinput>
+Opening database...
+
+<prompt>Enter Kerberos master key:</prompt>
+
+Current Kerberos master key version is 1.
+
+Master key entered. BEWARE!
+Previous or default values are in [brackets] ,
+enter return to leave the same, or new value.
+
+<prompt>Principal name:</prompt> <userinput>jane</userinput>
+<prompt>Instance:</prompt> <userinput>root</userinput>
+
+&lt;Not found&gt;, Create [y] ? y
+
+Principal: jane, Instance: root, kdc_key_ver: 1
+<prompt>New Password:</prompt> &lt;---- enter a SECURE password here
+Verifying password
+
+<prompt>New Password:</prompt> &lt;---- re-enter the password here
+
+Principal's new key version = 1
+<prompt>Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ?</prompt>
+<prompt>Max ticket lifetime (*5 minutes) [ 255 ] ?</prompt> <userinput>12</userinput> &lt;--- Keep this short!
+<prompt>Attributes [ 0 ] ?</prompt>
+Edit O.K.
+<prompt>Principal name:</prompt> &lt;---- null entry here will cause an exit</screen>
+
+ <para>Now try getting tokens for it to make sure it works:</para>
+
+ <screen>&prompt.root; <userinput>kinit jane.root</userinput>
+MIT Project Athena (grunt.example.com)
+Kerberos Initialization for "jane.root"
+<prompt>Password:</prompt></screen>
+
+ <para>Now we need to add the user to <systemitem class="username">root</systemitem>'s
+ <filename>.klogin</filename> file:</para>
+
+ <screen>&prompt.root; <userinput>cat /root/.klogin</userinput>
+jane.root@EXAMPLE.COM</screen>
+
+ <para>Now try doing the &man.su.1;:</para>
+
+ <screen>&prompt.user; <userinput>su</userinput>
+<prompt>Password:</prompt></screen>
+
+ <para>and take a look at what tokens we have:</para>
+
+ <screen>&prompt.root; <userinput>klist</userinput>
+Ticket file: /tmp/tkt_root_245
+Principal: jane.root@EXAMPLE.COM
+
+ Issued Expires Principal
+May 2 20:43:12 May 3 04:43:12 krbtgt.EXAMPLE.COM@EXAMPLE.COM</screen>
+ </sect2>
+
+ <sect2>
+ <title>Using Other Commands</title>
+
+ <para>In an earlier example, we created a principal called
+ <literal>jane</literal> with an instance <literal>root</literal>.
+ This was based on a user with the same name as the principal, and this
+ is a Kerberos default; that a
+ <literal>&lt;principal&gt;.&lt;instance&gt;</literal> of the form
+ <literal>&lt;username&gt;.</literal><systemitem class="username">root</systemitem> will allow
+ that <literal>&lt;username&gt;</literal> to &man.su.1; to
+ <systemitem class="username">root</systemitem> if the necessary entries are in the
+ <filename>.klogin</filename> file in <systemitem class="username">root</systemitem>'s
+ home directory:</para>
+
+ <screen>&prompt.root; <userinput>cat /root/.klogin</userinput>
+jane.root@EXAMPLE.COM</screen>
+
+ <para>Likewise, if a user has in their own home directory lines of the
+ form:</para>
+
+ <screen>&prompt.user; <userinput>cat ~/.klogin</userinput>
+jane@EXAMPLE.COM
+jack@EXAMPLE.COM</screen>
+
+ <para>This allows anyone in the <literal>EXAMPLE.COM</literal> realm
+ who has authenticated themselves as <systemitem class="username">jane</systemitem> or
+ <systemitem class="username">jack</systemitem> (via <command>kinit</command>, see above)
+ to access to <systemitem class="username">jane</systemitem>'s
+ account or files on this system (<systemitem>grunt</systemitem>) via
+ &man.rlogin.1;, &man.rsh.1; or
+ &man.rcp.1;.</para>
+
+ <para>For example, <systemitem class="username">jane</systemitem> now logs into another system using
+ Kerberos:</para>
+
+ <screen>&prompt.user; <userinput>kinit</userinput>
+MIT Project Athena (grunt.example.com)
+<prompt>Password:</prompt>
+&prompt.user; <userinput>rlogin grunt</userinput>
+Last login: Mon May 1 21:14:47 from grumble
+Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
+ The Regents of the University of California. All rights reserved.
+
+FreeBSD BUILT-19950429 (GR386) #0: Sat Apr 29 17:50:09 SAT 1995</screen>
+
+ <para>Or <systemitem class="username">jack</systemitem> logs into <systemitem class="username">jane</systemitem>'s account on the same machine
+ (<systemitem class="username">jane</systemitem> having
+ set up the <filename>.klogin</filename> file as above, and the person
+ in charge of Kerberos having set up principal
+ <emphasis>jack</emphasis> with a null instance):</para>
+
+ <screen>&prompt.user; <userinput>kinit</userinput>
+&prompt.user; <userinput>rlogin grunt -l jane</userinput>
+MIT Project Athena (grunt.example.com)
+<prompt>Password:</prompt>
+Last login: Mon May 1 21:16:55 from grumble
+Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
+ The Regents of the University of California. All rights reserved.
+FreeBSD BUILT-19950429 (GR386) #0: Sat Apr 29 17:50:09 SAT 1995</screen>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="kerberos5">
+ <info><title><application>Kerberos5</application></title>
+ <authorgroup>
+ <author><personname><firstname>Tillman</firstname><surname>Hodgson</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Mark</firstname><surname>Murray</surname></personname><contrib>Based on a contribution by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <para>Every &os; release beyond &os;-5.1 includes support
+ only for <application>Kerberos5</application>. Hence
+ <application>Kerberos5</application> is the only version
+ included, and its configuration is similar in many aspects
+ to that of <application>KerberosIV</application>. The following
+ information only applies to
+ <application>Kerberos5</application> in post &os;-5.0
+ releases. Users who wish to use the
+ <application>KerberosIV</application> package may install the
+ <package>security/krb4</package> port.</para>
+
+ <para><application>Kerberos</application> is a network add-on
+ system/protocol that allows users to authenticate themselves
+ through the services of a secure server. Services such as remote
+ login, remote copy, secure inter-system file copying and other
+ high-risk tasks are made considerably safer and more
+ controllable.</para>
+
+ <para><application>Kerberos</application> can be described as an
+ identity-verifying proxy system. It can also be described as a
+ trusted third-party authentication system.
+ <application>Kerberos</application> provides only one
+ function &mdash; the secure authentication of users on the network.
+ It does not provide authorization functions (what users are
+ allowed to do) or auditing functions (what those users did).
+ After a client and server have used
+ <application>Kerberos</application> to prove their identity, they
+ can also encrypt all of their communications to assure privacy
+ and data integrity as they go about their business.</para>
+
+ <para>Therefore it is highly recommended that
+ <application>Kerberos</application> be used with other security
+ methods which provide authorization and audit services.</para>
+
+ <para>The following instructions can be used as a guide on how to set
+ up <application>Kerberos</application> as distributed for &os;.
+ However, you should refer to the relevant manual pages for a complete
+ description.</para>
+
+ <para>For purposes of demonstrating a <application>Kerberos</application>
+ installation, the various name spaces will be handled as follows:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The <acronym>DNS</acronym> domain (<quote>zone</quote>)
+ will be example.org.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <application>Kerberos</application> realm will be
+ EXAMPLE.ORG.</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <para>Please use real domain names when setting up
+ <application>Kerberos</application> even if you intend to run
+ it internally. This avoids <acronym>DNS</acronym> problems
+ and assures inter-operation with other
+ <application>Kerberos</application> realms.</para>
+ </note>
+
+ <sect2>
+ <title>History</title>
+ <indexterm>
+ <primary>Kerberos5</primary>
+ <secondary>history</secondary>
+ </indexterm>
+
+ <para><application>Kerberos</application> was created by
+ <acronym>MIT</acronym> as a solution to network security problems.
+ The <application>Kerberos</application> protocol uses strong
+ cryptography so that a client can prove its identity to a server
+ (and vice versa) across an insecure network connection.</para>
+
+ <para><application>Kerberos</application> is both the name of a
+ network authentication protocol and an adjective to describe
+ programs that implement the program
+ (<application>Kerberos</application> telnet, for example). The
+ current version of the protocol is version 5, described in
+ <acronym>RFC</acronym>&nbsp;1510.</para>
+
+ <para>Several free implementations of this protocol are available,
+ covering a wide range of operating systems. The Massachusetts
+ Institute of Technology (<acronym>MIT</acronym>), where
+ <application>Kerberos</application> was originally developed,
+ continues to develop their <application>Kerberos</application>
+ package. It is commonly used in the <acronym>US</acronym>
+ as a cryptography product, as such it
+ has historically been affected by <acronym>US</acronym> export
+ regulations. The <acronym>MIT</acronym>
+ <application>Kerberos</application> is available as a port
+ (<package>security/krb5</package>). Heimdal
+ <application>Kerberos</application> is another version 5
+ implementation, and was explicitly developed outside of the
+ <acronym>US</acronym> to avoid export
+ regulations (and is thus often included in non-commercial &unix;
+ variants). The Heimdal <application>Kerberos</application>
+ distribution is available as a port
+ (<package>security/heimdal</package>), and a
+ minimal installation of it is included in the base &os;
+ install.</para>
+
+ <para>In order to reach the widest audience, these instructions assume
+ the use of the Heimdal distribution included in &os;.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>Setting up a Heimdal <acronym>KDC</acronym></title>
+ <indexterm>
+ <primary>Kerberos5</primary>
+ <secondary>Key Distribution Center</secondary>
+ </indexterm>
+
+ <para>The Key Distribution Center (<acronym>KDC</acronym>) is the
+ centralized authentication service that
+ <application>Kerberos</application> provides &mdash; it is the
+ computer that issues <application>Kerberos</application> tickets.
+ The <acronym>KDC</acronym> is considered <quote>trusted</quote> by
+ all other computers in the <application>Kerberos</application>
+ realm, and thus has heightened security concerns.</para>
+
+ <para>Note that while running the <application>Kerberos</application>
+ server requires very few computing resources, a dedicated machine
+ acting only as a <acronym>KDC</acronym> is recommended for security
+ reasons.</para>
+
+ <para>To begin setting up a <acronym>KDC</acronym>, ensure that your
+ <filename>/etc/rc.conf</filename> file contains the correct
+ settings to act as a <acronym>KDC</acronym> (you may need to adjust
+ paths to reflect your own system):</para>
+
+ <programlisting>kerberos5_server_enable="YES"
+kadmind5_server_enable="YES"
+kerberos_stash="YES"</programlisting>
+
+ <note>
+ <para>The <option>kerberos_stash</option> is only available in
+ &os;&nbsp;4.X.</para>
+ </note>
+
+ <para>Next we will set up your <application>Kerberos</application>
+ config file, <filename>/etc/krb5.conf</filename>:</para>
+
+ <programlisting>[libdefaults]
+ default_realm = EXAMPLE.ORG
+[realms]
+ EXAMPLE.ORG = {
+ kdc = kerberos.example.org
+ admin_server = kerberos.example.org
+ }
+[domain_realm]
+ .example.org = EXAMPLE.ORG</programlisting>
+
+ <para>Note that this <filename>/etc/krb5.conf</filename> file implies
+ that your <acronym>KDC</acronym> will have the fully-qualified
+ hostname of <systemitem class="fqdomainname">kerberos.example.org</systemitem>.
+ You will need to add a CNAME (alias) entry to your zone file to
+ accomplish this if your <acronym>KDC</acronym> has a different
+ hostname.</para>
+
+ <note>
+ <para>For large networks with a properly configured
+ <acronym>BIND</acronym> <acronym>DNS</acronym> server, the
+ above example could be trimmed to:</para>
+
+ <programlisting>[libdefaults]
+ default_realm = EXAMPLE.ORG</programlisting>
+
+ <para>With the following lines being appended to the
+ <systemitem class="fqdomainname">example.org</systemitem> zonefile:</para>
+
+ <programlisting>_kerberos._udp IN SRV 01 00 88 kerberos.example.org.
+_kerberos._tcp IN SRV 01 00 88 kerberos.example.org.
+_kpasswd._udp IN SRV 01 00 464 kerberos.example.org.
+_kerberos-adm._tcp IN SRV 01 00 749 kerberos.example.org.
+_kerberos IN TXT EXAMPLE.ORG</programlisting></note>
+
+ <note>
+ <para>For clients to be able to find the
+ <application>Kerberos</application> services, you
+ <emphasis>must</emphasis> have either a fully configured
+ <filename>/etc/krb5.conf</filename> or a miminally configured
+ <filename>/etc/krb5.conf</filename> <emphasis>and</emphasis> a
+ properly configured DNS server.</para>
+ </note>
+
+ <para>Next we will create the <application>Kerberos</application>
+ database. This database contains the keys of all principals encrypted
+ with a master password. You are not
+ required to remember this password, it will be stored in a file
+ (<filename>/var/heimdal/m-key</filename>). To create the master
+ key, run <command>kstash</command> and enter a password.</para>
+
+ <para>Once the master key has been created, you can initialize the
+ database using the <command>kadmin</command> program with the
+ <literal>-l</literal> option (standing for <quote>local</quote>).
+ This option instructs <command>kadmin</command> to modify the
+ database files directly rather than going through the
+ <command>kadmind</command> network service. This handles the
+ chicken-and-egg problem of trying to connect to the database
+ before it is created. Once you have the <command>kadmin</command>
+ prompt, use the <command>init</command> command to create your
+ realms initial database.</para>
+
+ <para>Lastly, while still in <command>kadmin</command>, create your
+ first principal using the <command>add</command> command. Stick
+ to the defaults options for the principal for now, you can always
+ change them later with the <command>modify</command> command.
+ Note that you can use the <literal>?</literal> command at any
+ prompt to see the available options.</para>
+
+ <para>A sample database creation session is shown below:</para>
+
+ <screen>&prompt.root; <userinput>kstash</userinput>
+Master key: <userinput>xxxxxxxx</userinput>
+Verifying password - Master key: <userinput>xxxxxxxx</userinput>
+
+&prompt.root; <userinput>kadmin -l</userinput>
+kadmin&gt; <userinput>init EXAMPLE.ORG</userinput>
+Realm max ticket life [unlimited]:
+kadmin&gt; <userinput>add tillman</userinput>
+Max ticket life [unlimited]:
+Max renewable life [unlimited]:
+Attributes []:
+Password: <userinput>xxxxxxxx</userinput>
+Verifying password - Password: <userinput>xxxxxxxx</userinput></screen>
+
+ <para>Now it is time to start up the <acronym>KDC</acronym> services.
+ Run <command>/etc/rc.d/kerberos start</command> and
+ <command>/etc/rc.d/kadmind start</command> to bring up the
+ services. Note that you will not have any kerberized daemons running
+ at this point but you should be able to confirm the that the
+ <acronym>KDC</acronym> is functioning by obtaining and listing a
+ ticket for the principal (user) that you just created from the
+ command-line of the <acronym>KDC</acronym> itself:</para>
+
+ <screen>&prompt.user; <userinput>k5init tillman</userinput>
+tillman@EXAMPLE.ORG's Password:
+
+&prompt.user; <userinput>k5list</userinput>
+Credentials cache: FILE:<filename>/tmp/krb5cc_500</filename>
+ Principal: tillman@EXAMPLE.ORG
+
+ Issued Expires Principal
+Aug 27 15:37:58 Aug 28 01:37:58 krbtgt/EXAMPLE.ORG@EXAMPLE.ORG</screen>
+
+ </sect2>
+
+ <sect2>
+ <title><application>Kerberos</application> enabling a server with
+ Heimdal services</title>
+
+ <indexterm>
+ <primary>Kerberos5</primary>
+ <secondary>enabling services</secondary>
+ </indexterm>
+
+ <para>First, we need a copy of the <application>Kerberos</application>
+ configuration file, <filename>/etc/krb5.conf</filename>. To do
+ so, simply copy it over to the client computer from the
+ <acronym>KDC</acronym> in a secure fashion (using network utilities,
+ such as &man.scp.1;, or physically via a
+ floppy disk).</para>
+
+ <para>Next you need a <filename>/etc/krb5.keytab</filename> file.
+ This is the major difference between a server providing
+ <application>Kerberos</application> enabled daemons and a
+ workstation &mdash; the server must have a
+ <filename>keytab</filename> file. This file
+ contains the servers host key, which allows it and the
+ <acronym>KDC</acronym> to verify each others identity. It
+ must be transmitted to the server in a secure fashion, as the
+ security of the server can be broken if the key is made public.
+ This explicitly means that transferring it via a clear text
+ channel, such as <acronym>FTP</acronym>, is a very bad idea.</para>
+
+ <para>Typically, you transfer to the <filename>keytab</filename>
+ to the server using the <command>kadmin</command> program.
+ This is handy because you also need to create the host principal
+ (the <acronym>KDC</acronym> end of the
+ <filename>krb5.keytab</filename>) using
+ <command>kadmin</command>.</para>
+
+ <para>Note that you must have already obtained a ticket and that this
+ ticket must be allowed to use the <command>kadmin</command>
+ interface in the <filename>kadmind.acl</filename>. See the section
+ titled <quote>Remote administration</quote> in the Heimdal info
+ pages (<command>info heimdal</command>) for details on designing
+ access control lists. If you do not want to enable remote
+ <command>kadmin</command> access, you can simply securely connect
+ to the <acronym>KDC</acronym> (via local console,
+ &man.ssh.1; or <application>Kerberos</application>
+ &man.telnet.1;) and perform administration locally
+ using <command>kadmin -l</command>.</para>
+
+ <para>After installing the <filename>/etc/krb5.conf</filename> file,
+ you can use <command>kadmin</command> from the
+ <application>Kerberos</application> server. The
+ <command>add --random-key</command> command will let you add the
+ servers host principal, and the <command>ext</command> command
+ will allow you to extract the servers host principal to its own
+ keytab. For example:</para>
+
+ <screen>&prompt.root; <userinput>kadmin</userinput>
+kadmin&gt;<userinput> add --random-key host/myserver.example.org</userinput>
+Max ticket life [unlimited]:
+Max renewable life [unlimited]:
+Attributes []:
+kadmin&gt;<userinput> ext host/myserver.example.org</userinput>
+kadmin&gt;<userinput> exit</userinput></screen>
+
+ <para>Note that the <command>ext</command> command (short for
+ <quote>extract</quote>) stores the extracted key in
+ <filename>/etc/krb5.keytab</filename> by default.</para>
+
+ <para>If you do not have <command>kadmind</command> running on the
+ <acronym>KDC</acronym> (possibly for security reasons) and thus
+ do not have access to <command>kadmin</command> remotely, you
+ can add the host principal
+ (<systemitem class="username">host/myserver.EXAMPLE.ORG</systemitem>) directly on the
+ <acronym>KDC</acronym> and then extract it to a temporary file
+ (to avoid over-writing the <filename>/etc/krb5.keytab</filename>
+ on the <acronym>KDC</acronym>) using something like this:</para>
+
+ <screen>&prompt.root; <userinput>kadmin</userinput>
+kadmin&gt;<userinput> ext --keytab=/tmp/example.keytab host/myserver.example.org</userinput>
+kadmin&gt;<userinput> exit</userinput></screen>
+
+ <para>You can then securely copy the keytab to the server
+ computer (using <command>scp</command> or a floppy, for
+ example). Be sure to specify a non-default keytab name
+ to avoid over-writing the keytab on the
+ <acronym>KDC</acronym>.</para>
+
+ <para>At this point your server can communicate with the
+ <acronym>KDC</acronym> (due to its <filename>krb5.conf</filename>
+ file) and it can prove its own identity (due to the
+ <filename>krb5.keytab</filename> file). It is now ready for
+ you to enable some <application>Kerberos</application> services.
+ For this example we will enable the <command>telnet</command>
+ service by putting a line like this into your
+ <filename>/etc/inetd.conf</filename> and then restarting the
+ &man.inetd.8; service with
+ <command>/etc/rc.d/inetd restart</command>:</para>
+
+ <programlisting>telnet stream tcp nowait root /usr/libexec/telnetd telnetd -a user</programlisting>
+
+ <para>The critical bit is that the <command>-a</command>
+ (for authentication) type is set to user. Consult the
+ &man.telnetd.8; manual page for more details.</para>
+
+ </sect2>
+
+ <sect2>
+ <title><application>Kerberos</application> enabling a client with Heimdal</title>
+
+ <indexterm>
+ <primary>Kerberos5</primary>
+ <secondary>configure clients</secondary>
+ </indexterm>
+
+ <para>Setting up a client computer is almost trivially easy. As
+ far as <application>Kerberos</application> configuration goes,
+ you only need the <application>Kerberos</application>
+ configuration file, located at <filename>/etc/krb5.conf</filename>.
+ Simply securely copy it over to the client computer from the
+ <acronym>KDC</acronym>.</para>
+
+ <para>Test your client computer by attempting to use
+ <command>kinit</command>, <command>klist</command>, and
+ <command>kdestroy</command> from the client to obtain, show, and
+ then delete a ticket for the principal you created above. You
+ should also be able to use <application>Kerberos</application>
+ applications to connect to <application>Kerberos</application>
+ enabled servers, though if that does not work and obtaining a
+ ticket does the problem is likely with the server and not with
+ the client or the <acronym>KDC</acronym>.</para>
+
+ <para>When testing an application like <command>telnet</command>,
+ try using a packet sniffer (such as &man.tcpdump.1;)
+ to confirm that your password is not sent in the clear. Try
+ using <command>telnet</command> with the <literal>-x</literal>
+ option, which encrypts the entire data stream (similar to
+ <command>ssh</command>).</para>
+
+ <para>The core <application>Kerberos</application> client applications
+ (traditionally named <command>kinit</command>,
+ <command>klist</command>, <command>kdestroy</command>, and
+ <command>kpasswd</command>) are installed in
+ the base &os; install. Note that &os; versions prior to 5.0
+ renamed them to <command>k5init</command>,
+ <command>k5list</command>, <command>k5destroy</command>,
+ <command>k5passwd</command>, and <command>k5stash</command>
+ (though it is typically only used once).</para>
+
+ <para>Various non-core <application>Kerberos</application> client
+ applications are also installed by default. This is where the
+ <quote>minimal</quote> nature of the base Heimdal installation is
+ felt: <command>telnet</command> is the only
+ <application>Kerberos</application> enabled service.</para>
+
+ <para>The Heimdal port adds some of the missing client applications:
+ <application>Kerberos</application> enabled versions of
+ <command>ftp</command>, <command>rsh</command>,
+ <command>rcp</command>, <command>rlogin</command>, and a few
+ other less common programs. The <acronym>MIT</acronym> port also
+ contains a full suite of <application>Kerberos</application>
+ client applications.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>User configuration files: <filename>.k5login</filename> and <filename>.k5users</filename></title>
+
+ <indexterm>
+ <primary><filename>.k5login</filename></primary>
+ </indexterm>
+
+ <indexterm>
+ <primary><filename>.k5users</filename></primary>
+ </indexterm>
+
+ <para>Users within a realm typically have their
+ <application>Kerberos</application> principal (such as
+ <systemitem class="username">tillman@EXAMPLE.ORG</systemitem>) mapped to a local
+ user account (such as a local account named
+ <systemitem class="username">tillman</systemitem>). Client applications such as
+ <command>telnet</command> usually do not require a user name
+ or a principal.</para>
+
+ <para>Occasionally, however, you want to grant access to a local
+ user account to someone who does not have a matching
+ <application>Kerberos</application> principal. For example,
+ <systemitem class="username">tillman@EXAMPLE.ORG</systemitem> may need access to the
+ local user account <systemitem class="username">webdevelopers</systemitem>. Other
+ principals may also need access to that local account.</para>
+
+ <para>The <filename>.k5login</filename> and
+ <filename>.k5users</filename> files, placed in a users home
+ directory, can be used similar to a powerful combination of
+ <filename>.hosts</filename> and <filename>.rhosts</filename>,
+ solving this problem. For example, if a
+ <filename>.k5login</filename> with the following
+ contents:</para>
+
+ <screen>tillman@example.org
+jdoe@example.org</screen>
+
+ <para>Were to be placed into the home directory of the local user
+ <systemitem class="username">webdevelopers</systemitem> then both principals listed
+ would have access to that account without requiring a shared
+ password.</para>
+
+ <para>Reading the manual pages for these commands is recommended.
+ Note that the <command>ksu</command> manual page covers
+ <filename>.k5users</filename>.</para>
+
+ </sect2>
+
+ <sect2>
+ <title><application>Kerberos</application> Tips, Tricks, and Troubleshooting</title>
+
+ <indexterm>
+ <primary>Kerberos5</primary>
+ <secondary>troubleshooting</secondary>
+ </indexterm>
+
+ <itemizedlist>
+ <listitem>
+ <para>When using either the Heimdal or <acronym>MIT</acronym>
+ <application>Kerberos</application> ports ensure that your
+ <envar>PATH</envar> environment variable lists the
+ <application>Kerberos</application> versions of the client
+ applications before the system versions.</para>
+ </listitem>
+
+ <listitem>
+ <para>Do all the computers in your realm have synchronized
+ time settings? If not, authentication may fail.
+ <xref linkend="network-ntp"/> describes how to synchronize
+ clocks using <acronym>NTP</acronym>.</para>
+ </listitem>
+
+ <listitem>
+ <para><acronym>MIT</acronym> and Heimdal inter-operate nicely.
+ Except for <command>kadmin</command>, the protocol for
+ which is not standardized.</para>
+ </listitem>
+
+ <listitem>
+ <para>If you change your hostname, you also need to change your
+ <systemitem class="username">host/</systemitem> principal and update your keytab.
+ This also applies to special keytab entries like the
+ <systemitem class="username">www/</systemitem> principal used for Apache's
+ <package>www/mod_auth_kerb</package>.</para>
+ </listitem>
+
+ <listitem>
+ <para>All hosts in your realm must be resolvable (both forwards
+ and reverse) in <acronym>DNS</acronym> (or
+ <filename>/etc/hosts</filename> as a minimum). CNAMEs
+ will work, but the A and PTR records must be correct and in
+ place. The error message is not very intuitive:
+ <errorname>Kerberos5 refuses authentication because Read req
+ failed: Key table entry not found</errorname>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Some operating systems that may being acting as clients
+ to your <acronym>KDC</acronym> do not set the permissions
+ for <command>ksu</command> to be setuid
+ <systemitem class="username">root</systemitem>. This means that
+ <command>ksu</command> does not work, which is a good
+ security idea but annoying. This is not a
+ <acronym>KDC</acronym> error.</para>
+ </listitem>
+
+ <listitem>
+ <para>With <acronym>MIT</acronym>
+ <application>Kerberos</application>, if you want to allow a
+ principal to have a ticket life longer than the default ten
+ hours, you must use <command>modify_principal</command> in
+ <command>kadmin</command> to change the maxlife of both the
+ principal in question and the <systemitem class="username">krbtgt</systemitem>
+ principal. Then the principal can use the
+ <literal>-l</literal> option with <command>kinit</command>
+ to request a ticket with a longer lifetime.</para>
+ </listitem>
+
+ <listitem>
+ <note><para>If you run a packet sniffer on your
+ <acronym>KDC</acronym> to add in troubleshooting and then
+ run <command>kinit</command> from a workstation, you will
+ notice that your <acronym>TGT</acronym> is sent
+ immediately upon running <command>kinit</command> &mdash;
+ even before you type your password! The explanation is
+ that the <application>Kerberos</application> server freely
+ transmits a <acronym>TGT</acronym> (Ticket Granting
+ Ticket) to any unauthorized request; however, every
+ <acronym>TGT</acronym> is encrypted in a key derived from
+ the user's password. Therefore, when a user types their
+ password it is not being sent to the <acronym>KDC</acronym>,
+ it is being used to decrypt the <acronym>TGT</acronym> that
+ <command>kinit</command> already obtained. If the decryption
+ process results in a valid ticket with a valid time stamp,
+ the user has valid <application>Kerberos</application>
+ credentials. These credentials include a session key for
+ establishing secure communications with the
+ <application>Kerberos</application> server in the future, as
+ well as the actual ticket-granting ticket, which is actually
+ encrypted with the <application>Kerberos</application>
+ server's own key. This second layer of encryption is
+ unknown to the user, but it is what allows the
+ <application>Kerberos</application> server to verify
+ the authenticity of each <acronym>TGT</acronym>.</para></note>
+ </listitem>
+
+ <listitem>
+ <para>If you want to use long ticket lifetimes (a week, for
+ example) and you are using <application>OpenSSH</application>
+ to connect to the machine where your ticket is stored, make
+ sure that <application>Kerberos</application>
+ <option>TicketCleanup</option> is set to <literal>no</literal>
+ in your <filename>sshd_config</filename> or else your tickets
+ will be deleted when you log out.</para>
+ </listitem>
+
+ <listitem>
+ <para>Remember that host principals can have a longer ticket
+ lifetime as well. If your user principal has a lifetime of a
+ week but the host you are connecting to has a lifetime of nine
+ hours, you will have an expired host principal in your cache
+ and the ticket cache will not work as expected.</para>
+ </listitem>
+
+ <listitem>
+ <para>When setting up a <filename>krb5.dict</filename> file to
+ prevent specific bad passwords from being used (the manual page
+ for <command>kadmind</command> covers this briefly), remember
+ that it only applies to principals that have a password policy
+ assigned to them. The <filename>krb5.dict</filename> files
+ format is simple: one string per line. Creating a symbolic
+ link to <filename>/usr/share/dict/words</filename> might be
+ useful.</para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ <sect2>
+ <title>Differences with the <acronym>MIT</acronym> port</title>
+
+ <para>The major difference between the <acronym>MIT</acronym>
+ and Heimdal installs relates to the <command>kadmin</command>
+ program which has a different (but equivalent) set of commands
+ and uses a different protocol. This has a large implications
+ if your <acronym>KDC</acronym> is <acronym>MIT</acronym> as you
+ will not be able to use the Heimdal <command>kadmin</command>
+ program to administer your <acronym>KDC</acronym> remotely
+ (or vice versa, for that matter).</para>
+
+ <para>The client applications may also take slightly different
+ command line options to accomplish the same tasks. Following
+ the instructions on the <acronym>MIT</acronym>
+ <application>Kerberos</application> web site
+ (<uri xlink:href="http://web.mit.edu/Kerberos/www/">http://web.mit.edu/Kerberos/www/</uri>)
+ is recommended. Be careful of path issues: the
+ <acronym>MIT</acronym> port installs into
+ <filename>/usr/local/</filename> by default, and the
+ <quote>normal</quote> system applications may be run instead
+ of <acronym>MIT</acronym> if your <envar>PATH</envar>
+ environment variable lists the system directories first.</para>
+
+ <note><para>With the <acronym>MIT</acronym>
+ <package>security/krb5</package> port
+ that is provided by &os;, be sure to read the
+ <filename>/usr/local/share/doc/krb5/README.FreeBSD</filename>
+ file installed by the port if you want to understand why logins
+ via <command>telnetd</command> and <command>klogind</command>
+ behave somewhat oddly. Most importantly, correcting the
+ <quote>incorrect permissions on cache file</quote> behavior
+ requires that the <command>login.krb5</command> binary be used
+ for authentication so that it can properly change ownership for
+ the forwarded credentials.</para></note>
+
+ </sect2>
+
+ <sect2>
+ <title>Mitigating limitations found in <application>Kerberos</application></title>
+
+ <indexterm>
+ <primary>Kerberos5</primary>
+ <secondary>limitations and shortcomings</secondary>
+ </indexterm>
+
+ <sect3>
+ <title><application>Kerberos</application> is an all-or-nothing approach</title>
+
+ <para>Every service enabled on the network must be modified to
+ work with <application>Kerberos</application> (or be otherwise
+ secured against network attacks) or else the users credentials
+ could be stolen and re-used. An example of this would be
+ <application>Kerberos</application> enabling all remote shells
+ (via <command>rsh</command> and <command>telnet</command>, for
+ example) but not converting the <acronym>POP3</acronym> mail
+ server which sends passwords in plain text.</para>
+
+ </sect3>
+
+ <sect3>
+ <title><application>Kerberos</application> is intended for single-user workstations</title>
+
+ <para>In a multi-user environment,
+ <application>Kerberos</application> is less secure.
+ This is because it stores the tickets in the
+ <filename>/tmp</filename> directory, which is readable by all
+ users. If a user is sharing a computer with several other
+ people simultaneously (i.e. multi-user), it is possible that
+ the user's tickets can be stolen (copied) by another
+ user.</para>
+
+ <para>This can be overcome with the <literal>-c</literal>
+ filename command-line option or (preferably) the
+ <envar>KRB5CCNAME</envar> environment variable, but this
+ is rarely done. In principal, storing the ticket in the users
+ home directory and using simple file permissions can mitigate
+ this problem.</para>
+
+ </sect3>
+
+ <sect3>
+ <title>The KDC is a single point of failure</title>
+
+ <para>By design, the <acronym>KDC</acronym> must be as secure as
+ the master password database is contained on it. The
+ <acronym>KDC</acronym> should have absolutely no other
+ services running on it and should be physically secured. The
+ danger is high because <application>Kerberos</application>
+ stores all passwords encrypted with the same key (the
+ <quote>master</quote> key), which in turn is stored as a file
+ on the <acronym>KDC</acronym>.</para>
+
+ <para>As a side note, a compromised master key is not quite as
+ bad as one might normally fear. The master key is only used
+ to encrypt the <application>Kerberos</application> database
+ and as a seed for the random number generator. As long as
+ access to your <acronym>KDC</acronym> is secure, an attacker
+ cannot do much with the master key.</para>
+
+ <para>Additionally, if the <acronym>KDC</acronym> is unavailable
+ (perhaps due to a denial of service attack or network problems)
+ the network services are unusable as authentication can not be
+ performed, a recipe for a denial-of-service attack. This can
+ alleviated with multiple <acronym>KDC</acronym>s (a single
+ master and one or more slaves) and with careful implementation
+ of secondary or fall-back authentication
+ (<acronym>PAM</acronym> is excellent for this).</para>
+
+ </sect3>
+
+ <sect3>
+ <title><application>Kerberos</application> Shortcomings</title>
+
+ <para><application>Kerberos</application> allows users, hosts
+ and services to authenticate between themselves. It does not
+ have a mechanism to authenticate the <acronym>KDC</acronym>
+ to the users, hosts or services. This means that a trojanned
+ <command>kinit</command> (for example) could record all user
+ names and passwords. Something like
+ <package>security/tripwire</package> or
+ other file system integrity checking tools can alleviate
+ this.</para>
+
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Resources and further information</title>
+
+ <indexterm>
+ <primary>Kerberos5</primary>
+ <secondary>external resources</secondary>
+ </indexterm>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="http://www.faqs.org/faqs/Kerberos-faq/general/preamble.html">
+ The <application>Kerberos</application> FAQ</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://web.mit.edu/Kerberos/www/dialogue.html">Designing
+ an Authentication System: a Dialog in Four Scenes</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.ietf.org/rfc/rfc1510.txt?number=1510">RFC 1510,
+ The <application>Kerberos</application> Network Authentication Service
+ (V5)</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://web.mit.edu/Kerberos/www/"><acronym>MIT</acronym>
+ <application>Kerberos</application> home page</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.pdc.kth.se/heimdal/">Heimdal
+ <application>Kerberos</application> home page</link></para>
+ </listitem>
+
+ </itemizedlist>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="openssl">
+ <info><title>OpenSSL</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Written by: </contrib></author>
+ </authorgroup>
+ </info>
+
+ <indexterm>
+ <primary>security</primary>
+ <secondary>OpenSSL</secondary>
+ </indexterm>
+
+ <para>One feature that many users overlook is the
+ <application>OpenSSL</application> toolkit included
+ in &os;. <application>OpenSSL</application> provides an
+ encryption transport layer on top of the normal communications
+ layer; thus allowing it to be intertwined with many network
+ applications and services.</para>
+
+ <para>Some uses of <application>OpenSSL</application> may include
+ encrypted authentication of mail clients, web based transactions
+ such as credit card payments and more. Many ports such as
+ <package>www/apache13-ssl</package>, and
+ <package>mail/sylpheed-claws</package>
+ will offer compilation support for building with
+ <application>OpenSSL</application>.</para>
+
+ <note>
+ <para>In most cases the Ports Collection will attempt to build
+ the <package>security/openssl</package> port
+ unless the <varname>WITH_OPENSSL_BASE</varname> make variable
+ is explicitly set to <quote>yes</quote>.</para>
+ </note>
+
+ <para>The version of <application>OpenSSL</application> included
+ in &os; supports Secure Sockets Layer v2/v3 (SSLv2/SSLv3),
+ Transport Layer Security v1 (TLSv1) network security protocols
+ and can be used as a general cryptographic library.</para>
+
+ <note>
+ <para>While <application>OpenSSL</application> supports the
+ <acronym>IDEA</acronym> algorithm, it is disabled by default
+ due to United States patents. To use it, the license should
+ be reviewed and, if the restrictions are acceptable, the
+ <varname>MAKE_IDEA</varname> variable must be set in
+ <filename>make.conf</filename>.</para>
+ </note>
+
+ <para>One of the most common uses of
+ <application>OpenSSL</application> is to provide certificates for
+ use with software applications. These certificates ensure
+ that the credentials of the company or individual are valid
+ and not fraudulent. If the certificate in question has
+ not been verified by one of the several <quote>Certificate Authorities</quote>,
+ or <acronym>CA</acronym>s, a warning is usually produced. A
+ Certificate Authority is a company, such as <link xlink:href="http://www.verisign.com">VeriSign</link>, which will
+ sign certificates in order to validate credentials of individuals
+ or companies. This process has a cost associated with it and
+ is definitely not a requirement for using certificates; however,
+ it can put some of the more paranoid users at ease.</para>
+
+ <sect2>
+ <title>Generating Certificates</title>
+
+ <indexterm>
+ <primary>OpenSSL</primary>
+ <secondary>certificate generation</secondary>
+ </indexterm>
+
+ <para>To generate a certificate, the following command is
+ available:</para>
+
+ <screen>&prompt.root; <userinput>openssl req -new -nodes -out req.pem -keyout cert.pem</userinput>
+Generating a 1024 bit RSA private key
+................++++++
+.......................................++++++
+writing new private key to 'cert.pem'
+-----
+You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+Country Name (2 letter code) [AU]:<userinput>US</userinput>
+State or Province Name (full name) [Some-State]:<userinput>PA</userinput>
+Locality Name (eg, city) []:<userinput>Pittsburgh</userinput>
+Organization Name (eg, company) [Internet Widgits Pty Ltd]:<userinput>My Company</userinput>
+Organizational Unit Name (eg, section) []:<userinput>Systems Administrator</userinput>
+Common Name (eg, YOUR name) []:<userinput>localhost.example.org</userinput>
+Email Address []:<userinput>trhodes@FreeBSD.org</userinput>
+
+Please enter the following 'extra' attributes
+to be sent with your certificate request
+A challenge password []:<userinput>SOME PASSWORD</userinput>
+An optional company name []:<userinput>Another Name</userinput></screen>
+
+ <para>Notice the response directly after the
+ <quote>Common Name</quote> prompt shows a domain name.
+ This prompt requires a server name to be entered for
+ verification purposes; placing anything but a domain name
+ would yield a useless certificate. Other options, for
+ instance expire time, alternate encryption algorithms, etc.
+ are available. A complete list may be obtained by viewing
+ the &man.openssl.1; manual page.</para>
+
+ <para>Two files should now exist in
+ the directory in which the aforementioned command was issued.
+ The certificate request, <filename>req.pem</filename>, may be
+ sent to a certificate authority who will validate the credentials
+ that you entered, sign the request and return the certificate to
+ you. The second file created will be named <filename>cert.pem</filename>
+ and is the private key for the certificate and should be
+ protected at all costs; if this falls in the hands of others it
+ can be used to impersonate you (or your server).</para>
+
+ <para>In cases where a signature from a <acronym>CA</acronym> is
+ not required, a self signed certificate can be created. First,
+ generate the <acronym>RSA</acronym> key:</para>
+
+ <screen>&prompt.root; <userinput>openssl dsaparam -rand -genkey -out myRSA.key 1024</userinput></screen>
+
+ <para>Next, generate the <acronym>CA</acronym> key:</para>
+
+ <screen>&prompt.root; <userinput>openssl gendsa -des3 -out myca.key myRSA.key</userinput></screen>
+
+ <para>Use this key to create the certificate:</para>
+
+ <screen>&prompt.root; <userinput>openssl req -new -x509 -days 365 -key myca.key -out new.crt</userinput></screen>
+
+ <para>Two new files should appear in the directory: a certificate
+ authority signature file, <filename>myca.key</filename> and the
+ certificate itself, <filename>new.crt</filename>. These should
+ be placed in a directory, preferably under
+ <filename>/etc</filename>, which is readable
+ only by <systemitem class="username">root</systemitem>. Permissions of 0700 should be fine for this and
+ they can be set with the <command>chmod</command>
+ utility.</para>
+ </sect2>
+
+ <sect2>
+ <title>Using Certificates, an Example</title>
+
+ <para>So what can these files do? A good use would be to
+ encrypt connections to the <application>Sendmail</application>
+ <acronym>MTA</acronym>. This would dissolve the use of clear
+ text authentication for users who send mail via the local
+ <acronym>MTA</acronym>.</para>
+
+ <note>
+ <para>This is not the best use in the world as some
+ <acronym>MUA</acronym>s will present the user with an
+ error if they have not installed the certificate locally.
+ Refer to the documentation included with the software for
+ more information on certificate installation.</para>
+ </note>
+
+ <para>The following lines should be placed inside the
+ local <filename>.mc</filename> file:</para>
+
+ <programlisting>dnl SSL Options
+define(`confCACERT_PATH',`/etc/certs')dnl
+define(`confCACERT',`/etc/certs/new.crt')dnl
+define(`confSERVER_CERT',`/etc/certs/new.crt')dnl
+define(`confSERVER_KEY',`/etc/certs/myca.key')dnl
+define(`confTLS_SRV_OPTIONS', `V')dnl</programlisting>
+
+ <para>Where <filename>/etc/certs/</filename>
+ is the directory to be used for storing the certificate
+ and key files locally. The last few requirements are a rebuild
+ of the local <filename>.cf</filename> file. This is easily
+ achieved by typing <command>make</command>
+ <parameter>install</parameter> within the
+ <filename>/etc/mail</filename>
+ directory. Follow that up with <command>make</command>
+ <parameter>restart</parameter> which should start the
+ <application>Sendmail</application> daemon.</para>
+
+ <para>If all went well there will be no error messages in the
+ <filename>/var/log/maillog</filename> file and
+ <application>Sendmail</application> will show up in the process
+ list.</para>
+
+ <para>For a simple test, simply connect to the mail server
+ using the &man.telnet.1; utility:</para>
+
+ <screen>&prompt.root; <userinput>telnet example.com 25</userinput>
+Trying 192.0.34.166...
+Connected to <systemitem class="fqdomainname">example.com</systemitem>.
+Escape character is '^]'.
+220 <systemitem class="fqdomainname">example.com</systemitem> ESMTP Sendmail 8.12.10/8.12.10; Tue, 31 Aug 2004 03:41:22 -0400 (EDT)
+<userinput>ehlo example.com</userinput>
+250-example.com Hello example.com [192.0.34.166], pleased to meet you
+250-ENHANCEDSTATUSCODES
+250-PIPELINING
+250-8BITMIME
+250-SIZE
+250-DSN
+250-ETRN
+250-AUTH LOGIN PLAIN
+250-STARTTLS
+250-DELIVERBY
+250 HELP
+<userinput>quit</userinput>
+221 2.0.0 <systemitem class="fqdomainname">example.com</systemitem> closing connection
+Connection closed by foreign host.</screen>
+
+ <para>If the <quote>STARTTLS</quote> line appears in the output
+ then everything is working correctly.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="ipsec">
+ <info><title>VPN over IPsec</title>
+ <authorgroup>
+ <author><personname><firstname>Nik</firstname><surname>Clayton</surname></personname><affiliation>
+ <address><email>nik@FreeBSD.org</email></address>
+ </affiliation><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm>
+ <primary>IPsec</primary>
+ </indexterm>
+
+ <para>Creating a VPN between two networks, separated by the
+ Internet, using FreeBSD gateways.</para>
+
+ <sect2>
+ <info><title>Understanding IPsec</title>
+ <authorgroup>
+ <author><personname><firstname>Hiten M.</firstname><surname>Pandya</surname></personname><affiliation>
+ <address><email>hmp@FreeBSD.org</email></address>
+ </affiliation><contrib>Written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <para>This section will guide you through the process of setting
+ up IPsec, and to use it in an environment which consists of
+ FreeBSD and <application>&microsoft.windows; 2000/XP</application>
+ machines, to make them communicate securely. In order to set up
+ IPsec, it is necessary that you are familiar with the concepts
+ of building a custom kernel (see
+ <xref linkend="kernelconfig"/>).</para>
+
+ <para><emphasis>IPsec</emphasis> is a protocol which sits on top
+ of the Internet Protocol (IP) layer. It allows two or more
+ hosts to communicate in a secure manner (hence the name). The
+ FreeBSD IPsec <quote>network stack</quote> is based on the
+ <link xlink:href="http://www.kame.net/">KAME</link> implementation,
+ which has support for both protocol families, IPv4 and
+ IPv6.</para>
+
+ <note>
+ <para>FreeBSD 5.X contains a <quote>hardware
+ accelerated</quote> IPsec stack, known as <quote>Fast
+ IPsec</quote>, that was obtained from OpenBSD. It employs
+ cryptographic hardware (whenever possible) via the
+ &man.crypto.4; subsystem to optimize the performance of IPsec.
+ This subsystem is new, and does not support all the features
+ that are available in the KAME version of IPsec. However, in
+ order to enable hardware-accelerated IPsec, the following
+ kernel option has to be added to your kernel configuration
+ file:</para>
+
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>FAST_IPSEC</secondary>
+ </indexterm>
+
+ <screen>
+options FAST_IPSEC # new IPsec (cannot define w/ IPSEC)
+ </screen>
+
+ <para> Note, that it is not currently possible to use the
+ <quote>Fast IPsec</quote> subsystem in lue with the KAME
+ implementation of IPsec. Consult the &man.fast.ipsec.4;
+ manual page for more information.</para>
+
+ </note>
+
+ <indexterm>
+ <primary>IPsec</primary>
+ <secondary>ESP</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>IPsec</primary>
+ <secondary>AH</secondary>
+ </indexterm>
+
+ <para>IPsec consists of two sub-protocols:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>Encapsulated Security Payload
+ (ESP)</emphasis>, protects the IP packet data from third
+ party interference, by encrypting the contents using
+ symmetric cryptography algorithms (like Blowfish,
+ 3DES).</para>
+ </listitem>
+ <listitem>
+ <para><emphasis>Authentication Header (AH)</emphasis>,
+ protects the IP packet header from third party interference
+ and spoofing, by computing a cryptographic checksum and
+ hashing the IP packet header fields with a secure hashing
+ function. This is then followed by an additional header
+ that contains the hash, to allow the information in the
+ packet to be authenticated.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><acronym>ESP</acronym> and <acronym>AH</acronym> can
+ either be used together or separately, depending on the
+ environment.</para>
+
+ <indexterm>
+ <primary>VPN</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>virtual private network</primary>
+ <see>VPN</see>
+ </indexterm>
+
+ <para>IPsec can either be used to directly encrypt the traffic
+ between two hosts (known as <emphasis>Transport
+ Mode</emphasis>); or to build <quote>virtual tunnels</quote>
+ between two subnets, which could be used for secure
+ communication between two corporate networks (known as
+ <emphasis>Tunnel Mode</emphasis>). The latter is more commonly
+ known as a <emphasis>Virtual Private Network (VPN)</emphasis>.
+ The &man.ipsec.4; manual page should be consulted for detailed
+ information on the IPsec subsystem in FreeBSD.</para>
+
+ <para>To add IPsec support to your kernel, add the following
+ options to your kernel configuration file:</para>
+
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>IPSEC</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>IPSEC_ESP</secondary>
+ </indexterm>
+
+ <screen>
+options IPSEC #IP security
+options IPSEC_ESP #IP security (crypto; define w/ IPSEC)
+ </screen>
+
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>IPSEC_DEBUG</secondary>
+ </indexterm>
+
+ <para>If IPsec debugging support is desired, the following
+ kernel option should also be added:</para>
+
+ <screen>
+options IPSEC_DEBUG #debug for IP security
+ </screen>
+ </sect2>
+
+ <sect2>
+ <title>The Problem</title>
+
+ <para>There is no standard for what constitutes a VPN. VPNs can
+ be implemented using a number of different technologies, each of
+ which have their own strengths and weaknesses. This section
+ presents a scenario, and the strategies used for implementing a
+ VPN for this scenario.</para>
+ </sect2>
+
+ <sect2>
+ <title>The Scenario: Two networks, connected to the Internet, to
+ behave as one</title>
+
+ <indexterm>
+ <primary>VPN</primary>
+ <secondary>creating</secondary>
+ </indexterm>
+
+ <para>The premise is as follows:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>You have at least two sites</para>
+ </listitem>
+ <listitem>
+ <para>Both sites are using IP internally</para>
+ </listitem>
+ <listitem>
+ <para>Both sites are connected to the Internet, through a
+ gateway that is running FreeBSD.</para>
+ </listitem>
+ <listitem>
+ <para>The gateway on each network has at least one public IP
+ address.</para>
+ </listitem>
+ <listitem>
+ <para>The internal addresses of the two networks can be
+ public or private IP addresses, it does not matter. You can
+ be running NAT on the gateway machine if necessary.</para>
+ </listitem>
+ <listitem>
+ <para>The internal IP addresses of the two networks
+ <emphasis>do not collide</emphasis>. While I expect it is
+ theoretically possible to use a combination of VPN
+ technology and NAT to get this to work, I expect it to be a
+ configuration nightmare.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>If you find that you are trying to connect two networks,
+ both of which, internally, use the same private IP address range
+ (e.g. both of them use <systemitem class="ipaddress">192.168.1.x</systemitem>), then one of the networks will
+ have to be renumbered.</para>
+
+ <para>The network topology might look something like this:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="security/ipsec-network" align="center"/>
+ </imageobject>
+
+ <textobject>
+<literallayout class="monospaced">Network #1 [ Internal Hosts ] Private Net, 192.168.1.2-254
+ [ Win9x/NT/2K ]
+ [ UNIX ]
+ |
+ |
+ .---[fxp1]---. Private IP, 192.168.1.1
+ | FreeBSD |
+ `---[fxp0]---' Public IP, A.B.C.D
+ |
+ |
+ -=-=- Internet -=-=-
+ |
+ |
+ .---[fxp0]---. Public IP, W.X.Y.Z
+ | FreeBSD |
+ `---[fxp1]---' Private IP, 192.168.2.1
+ |
+ |
+Network #2 [ Internal Hosts ]
+ [ Win9x/NT/2K ] Private Net, 192.168.2.2-254
+ [ UNIX ]</literallayout>
+ </textobject>
+ </mediaobject>
+
+ <para>Notice the two public IP addresses. I will use the letters to
+ refer to them in the rest of this article. Anywhere you see those
+ letters in this article, replace them with your own public IP
+ addresses. Note also that internally, the two gateway
+ machines have .1 IP addresses, and that the two networks have
+ different private IP addresses (<systemitem class="ipaddress">192.168.1.x</systemitem> and <systemitem class="ipaddress">192.168.2.x</systemitem> respectively). All the
+ machines on the private networks have been configured to use the
+ <systemitem class="ipaddress">.1</systemitem> machine as their default
+ gateway.</para>
+
+ <para>The intention is that, from a network point of view, each
+ network should view the machines on the other network as though
+ they were directly attached the same router -- albeit a slightly
+ slow router with an occasional tendency to drop packets.</para>
+
+ <para>This means that (for example), machine <systemitem class="ipaddress">192.168.1.20</systemitem> should be able to run</para>
+
+ <programlisting>ping 192.168.2.34</programlisting>
+
+ <para>and have it work, transparently. &windows; machines should
+ be able to see the machines on the other network, browse file
+ shares, and so on, in exactly the same way that they can browse
+ machines on the local network.</para>
+
+ <para>And the whole thing has to be secure. This means that
+ traffic between the two networks has to be encrypted.</para>
+
+ <para>Creating a VPN between these two networks is a multi-step
+ process. The stages are as follows:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Create a <quote>virtual</quote> network link between the two
+ networks, across the Internet. Test it, using tools like
+ &man.ping.8;, to make sure it works.</para>
+ </listitem>
+
+ <listitem>
+ <para>Apply security policies to ensure that traffic between
+ the two networks is transparently encrypted and decrypted as
+ necessary. Test this, using tools like &man.tcpdump.1;, to
+ ensure that traffic is encrypted.</para>
+ </listitem>
+
+ <listitem>
+ <para>Configure additional software on the FreeBSD gateways,
+ to allow &windows; machines to see one another across the
+ VPN.</para>
+ </listitem>
+ </orderedlist>
+
+ <sect3>
+ <title>Step 1: Creating and testing a <quote>virtual</quote>
+ network link</title>
+
+ <para>Suppose that you were logged in to the gateway machine on
+ network #1 (with public IP address <systemitem class="ipaddress">A.B.C.D</systemitem>, private IP address <systemitem class="ipaddress">192.168.1.1</systemitem>), and you ran <command>ping
+ 192.168.2.1</command>, which is the private address of the machine
+ with IP address <systemitem class="ipaddress">W.X.Y.Z</systemitem>. What
+ needs to happen in order for this to work?</para>
+
+ <orderedlist>
+ <listitem>
+ <para>The gateway machine needs to know how to reach <systemitem class="ipaddress">192.168.2.1</systemitem>. In other words, it needs
+ to have a route to <systemitem class="ipaddress">192.168.2.1</systemitem>.</para>
+ </listitem>
+ <listitem>
+ <para>Private IP addresses, such as those in the <systemitem class="ipaddress">192.168.x</systemitem> range are not supposed to
+ appear on the Internet at large. Instead, each packet you
+ send to <systemitem class="ipaddress">192.168.2.1</systemitem> will need
+ to be wrapped up inside another packet. This packet will need
+ to appear to be from <systemitem class="ipaddress">A.B.C.D</systemitem>,
+ and it will have to be sent to <systemitem class="ipaddress">W.X.Y.Z</systemitem>. This process is called
+ <firstterm>encapsulation</firstterm>.</para>
+ </listitem>
+ <listitem>
+ <para>Once this packet arrives at <systemitem class="ipaddress">W.X.Y.Z</systemitem> it will need to
+ <quote>unencapsulated</quote>, and delivered to <systemitem class="ipaddress">192.168.2.1</systemitem>.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>You can think of this as requiring a <quote>tunnel</quote>
+ between the two networks. The two <quote>tunnel mouths</quote> are the IP
+ addresses <systemitem class="ipaddress">A.B.C.D</systemitem> and <systemitem class="ipaddress">W.X.Y.Z</systemitem>, and the tunnel must be told the
+ addresses of the private IP addresses that will be allowed to pass
+ through it. The tunnel is used to transfer traffic with private
+ IP addresses across the public Internet.</para>
+
+ <para>This tunnel is created by using the generic interface, or
+ <filename>gif</filename> devices on FreeBSD. As you can
+ imagine, the <filename>gif</filename> interface on each
+ gateway host must be configured with four IP addresses; two for
+ the public IP addresses, and two for the private IP
+ addresses.</para>
+
+ <para>Support for the gif device must be compiled in to the
+ &os; kernel on both machines. You can do this by adding the
+ line:</para>
+
+ <programlisting>device gif</programlisting>
+
+ <para>to the kernel configuration files on both machines, and
+ then compile, install, and reboot as normal.</para>
+
+ <para>Configuring the tunnel is a two step process. First the
+ tunnel must be told what the outside (or public) IP addresses
+ are, using &man.gifconfig.8;. Then the private IP addresses must be
+ configured using &man.ifconfig.8;.</para>
+
+ <note>
+ <para>In &os;&nbsp;5.X, the functionality provided by the
+ &man.gifconfig.8; utility has been merged into
+ &man.ifconfig.8;.</para></note>
+
+ <para>On the gateway machine on network #1 you would run the
+ following two commands to configure the tunnel.</para>
+
+ <programlisting>gifconfig gif0 A.B.C.D W.X.Y.Z
+ifconfig gif0 inet 192.168.1.1 192.168.2.1 netmask 0xffffffff
+ </programlisting>
+
+ <para>On the other gateway machine you run the same commands,
+ but with the order of the IP addresses reversed.</para>
+
+ <programlisting>gifconfig gif0 W.X.Y.Z A.B.C.D
+ifconfig gif0 inet 192.168.2.1 192.168.1.1 netmask 0xffffffff
+ </programlisting>
+
+ <para>You can then run:</para>
+
+ <programlisting>gifconfig gif0</programlisting>
+
+ <para>to see the configuration. For example, on the network #1
+ gateway, you would see this:</para>
+
+ <screen>&prompt.root; <userinput>gifconfig gif0</userinput>
+gif0: flags=8011&lt;UP,POINTTOPOINT,MULTICAST&gt; mtu 1280
+inet 192.168.1.1 --&gt; 192.168.2.1 netmask 0xffffffff
+physical address inet A.B.C.D --&gt; W.X.Y.Z
+ </screen>
+
+ <para>As you can see, a tunnel has been created between the
+ physical addresses <systemitem class="ipaddress">A.B.C.D</systemitem> and
+ <systemitem class="ipaddress">W.X.Y.Z</systemitem>, and the traffic allowed
+ through the tunnel is that between <systemitem class="ipaddress">192.168.1.1</systemitem> and <systemitem class="ipaddress">192.168.2.1</systemitem>.</para>
+
+ <para>This will also have added an entry to the routing table
+ on both machines, which you can examine with the command <command>netstat -rn</command>.
+ This output is from the gateway host on network #1.</para>
+
+ <screen>&prompt.root; <userinput>netstat -rn</userinput>
+Routing tables
+
+Internet:
+Destination Gateway Flags Refs Use Netif Expire
+...
+192.168.2.1 192.168.1.1 UH 0 0 gif0
+...
+ </screen>
+
+ <para>As the <quote>Flags</quote> value indicates, this is a
+ host route, which means that each gateway knows how to reach the
+ other gateway, but they do not know how to reach the rest of
+ their respective networks. That problem will be fixed
+ shortly.</para>
+
+ <para>It is likely that you are running a firewall on both
+ machines. This will need to be circumvented for your VPN
+ traffic. You might want to allow all traffic between both
+ networks, or you might want to include firewall rules that
+ protect both ends of the VPN from one another.</para>
+
+ <para>It greatly simplifies testing if you configure the
+ firewall to allow all traffic through the VPN. You can always
+ tighten things up later. If you are using &man.ipfw.8; on the
+ gateway machines then a command like</para>
+
+ <programlisting>ipfw add 1 allow ip from any to any via gif0</programlisting>
+
+ <para>will allow all traffic between the two end points of the
+ VPN, without affecting your other firewall rules. Obviously
+ you will need to run this command on both gateway hosts.</para>
+
+ <para>This is sufficient to allow each gateway machine to ping
+ the other. On <systemitem class="ipaddress">192.168.1.1</systemitem>, you
+ should be able to run</para>
+
+ <programlisting>ping 192.168.2.1</programlisting>
+
+ <para>and get a response, and you should be able to do the same
+ thing on the other gateway machine.</para>
+
+ <para>However, you will not be able to reach internal machines
+ on either network yet. This is because of the routing --
+ although the gateway machines know how to reach one another,
+ they do not know how to reach the network behind each one.</para>
+
+ <para>To solve this problem you must add a static route on each
+ gateway machine. The command to do this on the first gateway
+ would be:</para>
+
+ <programlisting>route add 192.168.2.0 192.168.2.1 netmask 0xffffff00
+ </programlisting>
+
+ <para>This says <quote>In order to reach the hosts on the
+ network <systemitem class="ipaddress">192.168.2.0</systemitem>, send the
+ packets to the host <systemitem class="ipaddress">192.168.2.1</systemitem></quote>. You will need to
+ run a similar command on the other gateway, but with the
+ <systemitem class="ipaddress">192.168.1.x</systemitem> addresses
+ instead.</para>
+
+ <para>IP traffic from hosts on one network will now be able to
+ reach hosts on the other network.</para>
+
+ <para>That has now created two thirds of a VPN between the two
+ networks, in as much as it is <quote>virtual</quote> and it is a
+ <quote>network</quote>. It is not private yet. You can test
+ this using &man.ping.8; and &man.tcpdump.1;. Log in to the
+ gateway host and run</para>
+
+ <programlisting>tcpdump dst host 192.168.2.1</programlisting>
+
+ <para>In another log in session on the same host run</para>
+
+ <programlisting>ping 192.168.2.1</programlisting>
+
+ <para>You will see output that looks something like this:</para>
+
+ <programlisting>
+16:10:24.018080 192.168.1.1 &gt; 192.168.2.1: icmp: echo request
+16:10:24.018109 192.168.1.1 &gt; 192.168.2.1: icmp: echo reply
+16:10:25.018814 192.168.1.1 &gt; 192.168.2.1: icmp: echo request
+16:10:25.018847 192.168.1.1 &gt; 192.168.2.1: icmp: echo reply
+16:10:26.028896 192.168.1.1 &gt; 192.168.2.1: icmp: echo request
+16:10:26.029112 192.168.1.1 &gt; 192.168.2.1: icmp: echo reply
+ </programlisting>
+
+ <para>As you can see, the ICMP messages are going back and forth
+ unencrypted. If you had used the <option>-s</option> parameter to
+ &man.tcpdump.1; to grab more bytes of data from the packets you
+ would see more information.</para>
+
+ <para>Obviously this is unacceptable. The next section will
+ discuss securing the link between the two networks so that it
+ all traffic is automatically encrypted.</para>
+
+ <itemizedlist>
+ <title>Summary:</title>
+ <listitem>
+ <para>Configure both kernels with <quote>pseudo-device
+ gif</quote>.</para>
+ </listitem>
+ <listitem>
+ <para>Edit <filename>/etc/rc.conf</filename> on gateway host
+ #1 and add the following lines (replacing IP addresses as
+ necessary).</para>
+ <programlisting>gifconfig_gif0="A.B.C.D W.X.Y.Z"
+ifconfig_gif0="inet 192.168.1.1 192.168.2.1 netmask 0xffffffff"
+static_routes="vpn"
+route_vpn="192.168.2.0 192.168.2.1 netmask 0xffffff00"
+ </programlisting>
+ </listitem>
+
+ <listitem>
+ <para>Edit your firewall script
+ (<filename>/etc/rc.firewall</filename>, or similar) on both
+ hosts, and add</para>
+
+ <programlisting>ipfw add 1 allow ip from any to any via gif0</programlisting>
+ </listitem>
+ <listitem>
+ <para>Make similar changes to
+ <filename>/etc/rc.conf</filename> on gateway host #2,
+ reversing the order of IP addresses.</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+
+ <sect3>
+ <title>Step 2: Securing the link</title>
+
+ <para>To secure the link we will be using IPsec. IPsec provides
+ a mechanism for two hosts to agree on an encryption key, and to
+ then use this key in order to encrypt data between the two
+ hosts.</para>
+
+ <para>The are two areas of configuration to be considered here.</para>
+
+ <orderedlist>
+ <listitem>
+ <para>There must be a mechanism for two hosts to agree on the
+ encryption mechanism to use. Once two hosts have agreed on
+ this mechanism there is said to be a <quote>security association</quote>
+ between them.</para>
+ </listitem>
+ <listitem>
+ <para>There must be a mechanism for specifying which traffic
+ should be encrypted. Obviously, you do not want to encrypt
+ all your outgoing traffic -- you only want to encrypt the
+ traffic that is part of the VPN. The rules that you put in
+ place to determine what traffic will be encrypted are called
+ <quote>security policies</quote>.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>Security associations and security policies are both
+ maintained by the kernel, and can be modified by userland
+ programs. However, before you can do this you must configure the
+ kernel to support IPsec and the Encapsulated Security Payload
+ (ESP) protocol. This is done by configuring a kernel with:</para>
+
+ <indexterm>
+ <primary>kernel options</primary>
+ <secondary>IPSEC</secondary>
+ </indexterm>
+
+ <programlisting>options IPSEC
+options IPSEC_ESP
+ </programlisting>
+
+ <para>and recompiling, reinstalling, and rebooting. As before
+ you will need to do this to the kernels on both of the gateway
+ hosts.</para>
+
+ <indexterm>
+ <primary>IKE</primary>
+ </indexterm>
+
+ <para>You have two choices when it comes to setting up security
+ associations. You can configure them by hand between two hosts,
+ which entails choosing the encryption algorithm, encryption keys,
+ and so forth, or you can use daemons that implement the Internet
+ Key Exchange protocol (IKE) to do this for you.</para>
+
+ <para>I recommend the latter. Apart from anything else, it is
+ easier to set up.</para>
+
+ <indexterm>
+ <primary>IPsec</primary>
+ <secondary>security policies</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary><command>setkey</command></primary>
+ </indexterm>
+
+ <para>Editing and displaying security policies is carried out
+ using &man.setkey.8;. By analogy, <command>setkey</command> is
+ to the kernel's security policy tables as &man.route.8; is to
+ the kernel's routing tables. <command>setkey</command> can
+ also display the current security associations, and to continue
+ the analogy further, is akin to <command>netstat -r</command>
+ in that respect.</para>
+
+ <para>There are a number of choices for daemons to manage
+ security associations with FreeBSD. This article will describe
+ how to use one of these, racoon&nbsp;&mdash; which is available from
+ <package>security/ipsec-tools</package> in the &os; Ports
+ collection.</para>
+
+ <indexterm>
+ <primary>racoon</primary>
+ </indexterm>
+
+ <para>The <application>racoon</application> software must be run on both gateway hosts. On each host it
+ is configured with the IP address of the other end of the VPN,
+ and a secret key (which you choose, and must be the same on both
+ gateways).</para>
+
+ <para>The two daemons then contact one another, confirm that they
+ are who they say they are (by using the secret key that you
+ configured). The daemons then generate a new secret key, and use
+ this to encrypt the traffic over the VPN. They periodically
+ change this secret, so that even if an attacker were to crack one
+ of the keys (which is as theoretically close to unfeasible as it
+ gets) it will not do them much good -- by the time they have cracked
+ the key the two daemons have chosen another one.</para>
+
+ <para>The configuration file for racoon is stored in
+ <filename>${PREFIX}/etc/racoon</filename>. You should find a
+ configuration file there, which should not need to be changed
+ too much. The other component of racoon's configuration,
+ which you will need to change, is the <quote>pre-shared
+ key</quote>.</para>
+
+ <para>The default racoon configuration expects to find this in
+ the file <filename>${PREFIX}/etc/racoon/psk.txt</filename>. It is important to note
+ that the pre-shared key is <emphasis>not</emphasis> the key that will be used to
+ encrypt your traffic across the VPN link, it is simply a token
+ that allows the key management daemons to trust one another.</para>
+
+ <para><filename>psk.txt</filename> contains a line for each
+ remote site you are dealing with. In this example, where there
+ are two sites, each <filename>psk.txt</filename> file will contain one line (because
+ each end of the VPN is only dealing with one other end).</para>
+
+ <para>On gateway host #1 this line should look like this:</para>
+
+ <programlisting>W.X.Y.Z secret</programlisting>
+
+ <para>That is, the <emphasis>public</emphasis> IP address of the remote end,
+ whitespace, and a text string that provides the secret.
+ Obviously, you should not use <quote>secret</quote> as your key -- the normal
+ rules for choosing a password apply.</para>
+
+ <para>On gateway host #2 the line would look like this</para>
+
+ <programlisting>A.B.C.D secret</programlisting>
+
+ <para>That is, the public IP address of the remote end, and the
+ same secret key. <filename>psk.txt</filename> must be mode
+ <literal>0600</literal> (i.e., only read/write to
+ <systemitem class="username">root</systemitem>) before racoon will run.</para>
+
+ <para>You must run racoon on both gateway machines. You will
+ also need to add some firewall rules to allow the IKE traffic,
+ which is carried over UDP to the ISAKMP (Internet Security Association
+ Key Management Protocol) port. Again, this should be fairly early in
+ your firewall ruleset.</para>
+
+ <programlisting>ipfw add 1 allow udp from A.B.C.D to W.X.Y.Z isakmp
+ipfw add 1 allow udp from W.X.Y.Z to A.B.C.D isakmp
+ </programlisting>
+
+ <para>Once racoon is running you can try pinging one gateway host
+ from the other. The connection is still not encrypted, but
+ racoon will then set up the security associations between the two
+ hosts -- this might take a moment, and you may see this as a
+ short delay before the ping commands start responding.</para>
+
+ <para>Once the security association has been set up you can
+ view it using &man.setkey.8;. Run</para>
+
+ <programlisting>setkey -D</programlisting>
+
+ <para>on either host to view the security association information.</para>
+
+ <para>That's one half of the problem. They other half is setting
+ your security policies.</para>
+
+ <para>To create a sensible security policy, let's review what's
+ been set up so far. This discussions hold for both ends of the
+ link.</para>
+
+ <para>Each IP packet that you send out has a header that contains
+ data about the packet. The header includes the IP addresses of
+ both the source and destination. As we already know, private IP
+ addresses, such as the <systemitem class="ipaddress">192.168.x.y</systemitem>
+ range are not supposed to appear on the public Internet.
+ Instead, they must first be encapsulated inside another packet.
+ This packet must have the public source and destination IP
+ addresses substituted for the private addresses.</para>
+
+ <para>So if your outgoing packet started looking like this:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="security/ipsec-out-pkt" align="center"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced">
+ .----------------------.
+ | Src: 192.168.1.1 |
+ | Dst: 192.168.2.1 |
+ | &lt;other header info&gt; |
+ +----------------------+
+ | &lt;packet data&gt; |
+ `----------------------'</literallayout>
+ </textobject>
+ </mediaobject>
+
+ <para>Then it will be encapsulated inside another packet, looking
+ something like this:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="security/ipsec-encap-pkt" align="center"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced">
+ .--------------------------.
+ | Src: A.B.C.D |
+ | Dst: W.X.Y.Z |
+ | &lt;other header info&gt; |
+ +--------------------------+
+ | .----------------------. |
+ | | Src: 192.168.1.1 | |
+ | | Dst: 192.168.2.1 | |
+ | | &lt;other header info&gt; | |
+ | +----------------------+ |
+ | | &lt;packet data&gt; | |
+ | `----------------------' |
+ `--------------------------'</literallayout>
+ </textobject>
+ </mediaobject>
+
+ <para>This encapsulation is carried out by the
+ <filename>gif</filename> device. As
+ you can see, the packet now has real IP addresses on the outside,
+ and our original packet has been wrapped up as data inside the
+ packet that will be put out on the Internet.</para>
+
+ <para>Obviously, we want all traffic between the VPNs to be
+ encrypted. You might try putting this in to words, as:</para>
+
+ <para><quote>If a packet leaves from <systemitem class="ipaddress">A.B.C.D</systemitem>, and it is destined for <systemitem class="ipaddress">W.X.Y.Z</systemitem>, then encrypt it, using the
+ necessary security associations.</quote></para>
+
+ <para><quote>If a packet arrives from <systemitem class="ipaddress">W.X.Y.Z</systemitem>, and it is destined for <systemitem class="ipaddress">A.B.C.D</systemitem>, then decrypt it, using the
+ necessary security associations.</quote></para>
+
+ <para>That's close, but not quite right. If you did this, all
+ traffic to and from <systemitem class="ipaddress">W.X.Y.Z</systemitem>, even
+ traffic that was not part of the VPN, would be encrypted. That's
+ not quite what you want. The correct policy is as follows</para>
+
+ <para><quote>If a packet leaves from <systemitem class="ipaddress">A.B.C.D</systemitem>, and that packet is encapsulating
+ another packet, and it is destined for <systemitem class="ipaddress">W.X.Y.Z</systemitem>, then encrypt it, using the
+ necessary security associations.</quote></para>
+
+ <para><quote>If a packet arrives from <systemitem class="ipaddress">W.X.Y.Z</systemitem>, and that packet is encapsulating
+ another packet, and it is destined for <systemitem class="ipaddress">A.B.C.D</systemitem>, then decrypt it, using the
+ necessary security associations.</quote></para>
+
+ <para>A subtle change, but a necessary one.</para>
+
+ <para>Security policies are also set using &man.setkey.8;.
+ &man.setkey.8; features a configuration language for defining the
+ policy. You can either enter configuration instructions via
+ stdin, or you can use the <option>-f</option> option to specify a
+ filename that contains configuration instructions.</para>
+
+ <para>The configuration on gateway host #1 (which has the public
+ IP address <systemitem class="ipaddress">A.B.C.D</systemitem>) to force all
+ outbound traffic to <systemitem class="ipaddress">W.X.Y.Z</systemitem> to be
+ encrypted is:</para>
+
+ <programlisting>
+spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P out ipsec esp/tunnel/A.B.C.D-W.X.Y.Z/require;
+ </programlisting>
+
+ <para>Put these commands in a file (e.g.
+ <filename>/etc/ipsec.conf</filename>) and then run</para>
+
+ <screen>&prompt.root; <userinput>setkey -f /etc/ipsec.conf</userinput></screen>
+
+ <para><option>spdadd</option> tells &man.setkey.8; that we want
+ to add a rule to the secure policy database. The rest of this
+ line specifies which packets will match this policy. <systemitem class="ipaddress">A.B.C.D/32</systemitem> and <systemitem class="ipaddress">W.X.Y.Z/32</systemitem> are the IP addresses and
+ netmasks that identify the network or hosts that this policy will
+ apply to. In this case, we want it to apply to traffic between
+ these two hosts. <option>ipencap</option> tells the kernel that
+ this policy should only apply to packets that encapsulate other
+ packets. <option>-P out</option> says that this policy applies
+ to outgoing packets, and <option>ipsec</option> says that the
+ packet will be secured.</para>
+
+ <para>The second line specifies how this packet will be
+ encrypted. <option>esp</option> is the protocol that will be
+ used, while <option>tunnel</option> indicates that the packet
+ will be further encapsulated in an IPsec packet. The repeated
+ use of <systemitem class="ipaddress">A.B.C.D</systemitem> and <systemitem class="ipaddress">W.X.Y.Z</systemitem> is used to select the security
+ association to use, and the final <option>require</option>
+ mandates that packets must be encrypted if they match this
+ rule.</para>
+
+ <para>This rule only matches outgoing packets. You will need a
+ similar rule to match incoming packets.</para>
+
+ <programlisting>spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P in ipsec esp/tunnel/W.X.Y.Z-A.B.C.D/require;</programlisting>
+
+ <para>Note the <option>in</option> instead of
+ <option>out</option> in this case, and the necessary reversal of
+ the IP addresses.</para>
+
+ <para>The other gateway host (which has the public IP address
+ <systemitem class="ipaddress">W.X.Y.Z</systemitem>) will need similar rules.</para>
+
+ <programlisting>spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P out ipsec esp/tunnel/W.X.Y.Z-A.B.C.D/require;
+spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P in ipsec esp/tunnel/A.B.C.D-W.X.Y.Z/require;</programlisting>
+
+ <para>Finally, you need to add firewall rules to allow ESP and
+ IPENCAP packets back and forth. These rules will need to be
+ added to both hosts.</para>
+
+ <programlisting>ipfw add 1 allow esp from A.B.C.D to W.X.Y.Z
+ipfw add 1 allow esp from W.X.Y.Z to A.B.C.D
+ipfw add 1 allow ipencap from A.B.C.D to W.X.Y.Z
+ipfw add 1 allow ipencap from W.X.Y.Z to A.B.C.D
+ </programlisting>
+
+ <para>Because the rules are symmetric you can use the same rules
+ on each gateway host.</para>
+
+ <para>Outgoing packets will now look something like this:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="security/ipsec-crypt-pkt" align="center"/>
+ </imageobject>
+
+ <textobject>
+ <literallayout class="monospaced">
+ .------------------------------. --------------------------.
+ | Src: A.B.C.D | |
+ | Dst: W.X.Y.Z | |
+ | &lt;other header info&gt; | | Encrypted
+ +------------------------------+ | packet.
+ | .--------------------------. | -------------. | contents
+ | | Src: A.B.C.D | | | | are
+ | | Dst: W.X.Y.Z | | | | completely
+ | | &lt;other header info&gt; | | | |- secure
+ | +--------------------------+ | | Encap'd | from third
+ | | .----------------------. | | -. | packet | party
+ | | | Src: 192.168.1.1 | | | | Original |- with real | snooping
+ | | | Dst: 192.168.2.1 | | | | packet, | IP addr |
+ | | | &lt;other header info&gt; | | | |- private | |
+ | | +----------------------+ | | | IP addr | |
+ | | | &lt;packet data&gt; | | | | | |
+ | | `----------------------' | | -' | |
+ | `--------------------------' | -------------' |
+ `------------------------------' --------------------------'
+ </literallayout>
+ </textobject>
+ </mediaobject>
+
+ <para>When they are received by the far end of the VPN they will
+ first be decrypted (using the security associations that have
+ been negotiated by racoon). Then they will enter the
+ <filename>gif</filename> interface, which will unwrap
+ the second layer, until you are left with the innermost
+ packet, which can then travel in to the inner network.</para>
+
+ <para>You can check the security using the same &man.ping.8; test from
+ earlier. First, log in to the
+ <systemitem class="ipaddress">A.B.C.D</systemitem> gateway machine, and
+ run:</para>
+
+ <programlisting>tcpdump dst host 192.168.2.1</programlisting>
+
+ <para>In another log in session on the same host run</para>
+
+ <programlisting>ping 192.168.2.1</programlisting>
+
+ <para>This time you should see output like the following:</para>
+
+ <programlisting>XXX tcpdump output</programlisting>
+
+ <para>Now, as you can see, &man.tcpdump.1; shows the ESP packets. If
+ you try to examine them with the <option>-s</option> option you will see
+ (apparently) gibberish, because of the encryption.</para>
+
+ <para>Congratulations. You have just set up a VPN between two
+ remote sites.</para>
+
+ <itemizedlist>
+ <title>Summary</title>
+ <listitem>
+ <para>Configure both kernels with:</para>
+
+ <programlisting>options IPSEC
+options IPSEC_ESP
+ </programlisting>
+ </listitem>
+ <listitem>
+ <para>Install <package>security/ipsec-tools</package>. Edit
+ <filename>${PREFIX}/etc/racoon/psk.txt</filename> on both
+ gateway hosts, adding an entry for the remote host's IP
+ address and a secret key that they both know. Make sure
+ this file is mode 0600.</para>
+ </listitem>
+ <listitem>
+ <para>Add the following lines to
+ <filename>/etc/rc.conf</filename> on each host:</para>
+
+ <programlisting>ipsec_enable="YES"
+ipsec_file="/etc/ipsec.conf"
+ </programlisting>
+ </listitem>
+ <listitem>
+ <para>Create an <filename>/etc/ipsec.conf</filename> on each
+ host that contains the necessary spdadd lines. On gateway
+ host #1 this would be:</para>
+
+ <programlisting>
+spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P out ipsec
+ esp/tunnel/A.B.C.D-W.X.Y.Z/require;
+spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P in ipsec
+ esp/tunnel/W.X.Y.Z-A.B.C.D/require;
+</programlisting>
+
+ <para>On gateway host #2 this would be:</para>
+
+<programlisting>
+spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P out ipsec
+ esp/tunnel/W.X.Y.Z-A.B.C.D/require;
+spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P in ipsec
+ esp/tunnel/A.B.C.D-W.X.Y.Z/require;
+</programlisting>
+ </listitem>
+ <listitem>
+ <para>Add firewall rules to allow IKE, ESP, and IPENCAP
+ traffic to both hosts:</para>
+
+ <programlisting>
+ipfw add 1 allow udp from A.B.C.D to W.X.Y.Z isakmp
+ipfw add 1 allow udp from W.X.Y.Z to A.B.C.D isakmp
+ipfw add 1 allow esp from A.B.C.D to W.X.Y.Z
+ipfw add 1 allow esp from W.X.Y.Z to A.B.C.D
+ipfw add 1 allow ipencap from A.B.C.D to W.X.Y.Z
+ipfw add 1 allow ipencap from W.X.Y.Z to A.B.C.D
+ </programlisting>
+ </listitem>
+ </itemizedlist>
+
+ <para>The previous two steps should suffice to get the VPN up and
+ running. Machines on each network will be able to refer to one
+ another using IP addresses, and all traffic across the link will
+ be automatically and securely encrypted.</para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="openssh">
+ <info><title>OpenSSH</title>
+ <authorgroup>
+ <author><personname><firstname>Chern</firstname><surname>Lee</surname></personname><contrib>Contributed by </contrib></author>
+ <!-- 21 April 2001 -->
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>OpenSSH</primary></indexterm>
+ <indexterm>
+ <primary>security</primary>
+ <secondary>OpenSSH</secondary>
+ </indexterm>
+
+ <para><application>OpenSSH</application> is a set of network connectivity tools used to
+ access remote machines securely. It can be used as a direct
+ replacement for <command>rlogin</command>,
+ <command>rsh</command>, <command>rcp</command>, and
+ <command>telnet</command>. Additionally, TCP/IP
+ connections can be tunneled/forwarded securely through SSH.
+ <application>OpenSSH</application> encrypts all traffic to effectively eliminate eavesdropping,
+ connection hijacking, and other network-level attacks.</para>
+
+ <para><application>OpenSSH</application> is maintained by the OpenBSD project, and is based
+ upon SSH v1.2.12 with all the recent bug fixes and updates. It
+ is compatible with both SSH protocols 1 and 2. <application>OpenSSH</application> has been
+ in the base system since FreeBSD&nbsp;4.0.</para>
+
+ <sect2>
+ <title>Advantages of Using OpenSSH</title>
+
+ <para>Normally, when using &man.telnet.1; or &man.rlogin.1;,
+ data is sent over the network in an clear, un-encrypted form.
+ Network sniffers anywhere in between the client and server can
+ steal your user/password information or data transferred in
+ your session. <application>OpenSSH</application> offers a variety of authentication and
+ encryption methods to prevent this from happening.</para>
+ </sect2>
+
+ <sect2>
+ <title>Enabling sshd</title>
+ <indexterm>
+ <primary>OpenSSH</primary>
+ <secondary>enabling</secondary>
+ </indexterm>
+
+ <para>The <application>sshd</application> daemon is enabled by
+ default on &os;&nbsp;4.X. In &os; 5.X and later enabling
+ <application>sshd</application> is an option presented during
+ a <literal>Standard</literal> install of &os;. To see if
+ <application>sshd</application> is enabled, check the
+ <filename>rc.conf</filename> file for:</para>
+ <screen>sshd_enable="YES"</screen>
+ <para>This will load &man.sshd.8;, the daemon program for <application>OpenSSH</application>,
+ the next time your system initializes. Alternatively, you can
+ simply run directly the <application>sshd</application> daemon by typing <command>sshd</command> on the command line.</para>
+ </sect2>
+
+ <sect2>
+ <title>SSH Client</title>
+ <indexterm>
+ <primary>OpenSSH</primary>
+ <secondary>client</secondary>
+ </indexterm>
+
+ <para>The &man.ssh.1; utility works similarly to
+ &man.rlogin.1;.</para>
+
+ <screen>&prompt.root; <userinput>ssh user@example.com</userinput>
+Host key not found from the list of known hosts.
+Are you sure you want to continue connecting (yes/no)? <userinput>yes</userinput>
+Host 'example.com' added to the list of known hosts.
+user@example.com's password: <userinput>*******</userinput></screen>
+
+ <para>The login will continue just as it would have if a session was
+ created using <command>rlogin</command> or
+ <command>telnet</command>. SSH utilizes a key fingerprint
+ system for verifying the authenticity of the server when the
+ client connects. The user is prompted to enter
+ <literal>yes</literal> only when
+ connecting for the first time. Future attempts to login are all
+ verified against the saved fingerprint key. The SSH client
+ will alert you if the saved fingerprint differs from the
+ received fingerprint on future login attempts. The fingerprints
+ are saved in <filename>~/.ssh/known_hosts</filename>, or
+ <filename>~/.ssh/known_hosts2</filename> for SSH v2
+ fingerprints.</para>
+
+ <para>By default, recent versions of the
+ <application>OpenSSH</application> servers only accept SSH v2
+ connections. The client will use version 2 if possible and
+ will fall back to version 1. The client can also be forced to
+ use one or the other by passing it the <option>-1</option> or
+ <option>-2</option> for version 1 or version 2, respectively.
+ The version 1 compatability is maintained in the client for
+ backwards compatability with older versions.</para>
+ </sect2>
+
+ <sect2>
+ <title>Secure Copy</title>
+ <indexterm>
+ <primary>OpenSSH</primary>
+ <secondary>secure copy</secondary>
+ </indexterm>
+ <indexterm><primary><command>scp</command></primary></indexterm>
+
+ <para>The &man.scp.1; command works similarly to
+ &man.rcp.1;; it copies a file to or from a remote machine,
+ except in a secure fashion.</para>
+
+ <screen>&prompt.root; <userinput> scp user@example.com:/COPYRIGHT COPYRIGHT</userinput>
+user@example.com's password: <userinput>*******</userinput>
+COPYRIGHT 100% |*****************************| 4735
+00:00
+&prompt.root;</screen>
+ <para>Since the fingerprint was already saved for this host in the
+ previous example, it is verified when using &man.scp.1;
+ here.</para>
+
+ <para>The arguments passed to &man.scp.1; are similar
+ to &man.cp.1;, with the file or files in the first
+ argument, and the destination in the second. Since the file is
+ fetched over the network, through SSH, one or more of the file
+ arguments takes on the form
+ <option>user@host:&lt;path_to_remote_file&gt;</option>.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>Configuration</title>
+ <indexterm>
+ <primary>OpenSSH</primary>
+ <secondary>configuration</secondary>
+ </indexterm>
+
+ <para>The system-wide configuration files for both the
+ <application>OpenSSH</application> daemon and client reside
+ within the <filename>/etc/ssh</filename> directory.</para>
+
+ <para><filename>ssh_config</filename> configures the client
+ settings, while <filename>sshd_config</filename> configures the
+ daemon.</para>
+
+ <para>Additionally, the <option>sshd_program</option>
+ (<filename>/usr/sbin/sshd</filename> by default), and
+ <option>sshd_flags</option> <filename>rc.conf</filename>
+ options can provide more levels of configuration.</para>
+ </sect2>
+
+ <sect2 xml:id="security-ssh-keygen">
+ <title>ssh-keygen</title>
+
+ <para>Instead of using passwords, &man.ssh-keygen.1; can
+ be used to generate DSA or RSA keys to authenticate a user:</para>
+
+ <screen>&prompt.user; <userinput>ssh-keygen -t dsa</userinput>
+Generating public/private dsa key pair.
+Enter file in which to save the key (/home/user/.ssh/id_dsa):
+Created directory '/home/user/.ssh'.
+Enter passphrase (empty for no passphrase):
+Enter same passphrase again:
+Your identification has been saved in /home/user/.ssh/id_dsa.
+Your public key has been saved in /home/user/.ssh/id_dsa.pub.
+The key fingerprint is:
+bb:48:db:f2:93:57:80:b6:aa:bc:f5:d5:ba:8f:79:17 user@host.example.com
+</screen>
+
+ <para>&man.ssh-keygen.1; will create a public and private
+ key pair for use in authentication. The private key is stored in
+ <filename>~/.ssh/id_dsa</filename> or
+ <filename>~/.ssh/id_rsa</filename>, whereas the public key is
+ stored in <filename>~/.ssh/id_dsa.pub</filename> or
+ <filename>~/.ssh/id_rsa.pub</filename>, respectively for DSA and
+ RSA key types. The public key must be placed in
+ <filename>~/.ssh/authorized_keys</filename> of the remote
+ machine in order for the setup to work. Similarly, RSA version
+ 1 public keys should be placed in
+ <filename>~/.ssh/authorized_keys</filename>.</para>
+
+ <para>This will allow connection to the remote machine based upon
+ SSH keys instead of passwords.</para>
+
+ <para>If a passphrase is used in &man.ssh-keygen.1;, the user
+ will be prompted for a password each time in order to use the
+ private key. &man.ssh-agent.1; can alleviate the strain of
+ repeatedly entering long passphrases, and is explored in the
+ <xref linkend="security-ssh-agent"/> section below.</para>
+
+ <warning><para>The various options and files can be different
+ according to the <application>OpenSSH</application> version
+ you have on your system; to avoid problems you should consult
+ the &man.ssh-keygen.1; manual page.</para></warning>
+ </sect2>
+
+ <sect2 xml:id="security-ssh-agent">
+ <title>ssh-agent and ssh-add</title>
+
+ <para>The &man.ssh-agent.1; and &man.ssh-add.1; utilities provide
+ methods for <application>SSH</application> keys to be loaded
+ into memory for use, without needing to type the passphrase
+ each time.</para>
+
+ <para>The &man.ssh-agent.1; utility will handle the authentication
+ using the private key(s) that are loaded into it.
+ &man.ssh-agent.1; should be used to launch another application.
+ At the most basic level, it could spawn a shell or at a more
+ advanced level, a window manager.</para>
+
+ <para>To use &man.ssh-agent.1; in a shell, first it will need to
+ be spawned with a shell as an argument. Secondly, the
+ identity needs to be added by running &man.ssh-add.1; and
+ providing it the passphrase for the private key. Once these
+ steps have been completed the user will be able to &man.ssh.1;
+ to any host that has the corresponding public key installed.
+ For example:</para>
+
+ <screen>&prompt.user; ssh-agent <replaceable>csh</replaceable>
+&prompt.user; ssh-add
+Enter passphrase for /home/user/.ssh/id_dsa:
+Identity added: /home/user/.ssh/id_dsa (/home/user/.ssh/id_dsa)
+&prompt.user;</screen>
+
+ <para>To use &man.ssh-agent.1; in X11, a call to
+ &man.ssh-agent.1; will need to be placed in
+ <filename>~/.xinitrc</filename>. This will provide the
+ &man.ssh-agent.1; services to all programs launched in X11.
+ An example <filename>~/.xinitrc</filename> file might look
+ like this:</para>
+
+ <programlisting>exec ssh-agent <replaceable>startxfce4</replaceable></programlisting>
+
+ <para>This would launch &man.ssh-agent.1;, which would in turn
+ launch <application>XFCE</application>, every time X11 starts.
+ Then once that is done and X11 has been restarted so that the
+ changes can take effect, simply run &man.ssh-add.1; to load
+ all of your SSH keys.</para>
+ </sect2>
+
+ <sect2 xml:id="security-ssh-tunneling">
+ <title>SSH Tunneling</title>
+ <indexterm>
+ <primary>OpenSSH</primary>
+ <secondary>tunneling</secondary>
+ </indexterm>
+
+ <para><application>OpenSSH</application> has the ability to create a tunnel to encapsulate
+ another protocol in an encrypted session.</para>
+
+ <para>The following command tells &man.ssh.1; to create a tunnel
+ for <application>telnet</application>:</para>
+
+ <screen>&prompt.user; <userinput>ssh -2 -N -f -L 5023:localhost:23 user@foo.example.com</userinput>
+&prompt.user;</screen>
+
+ <para>The <command>ssh</command> command is used with the
+ following options:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-2</option></term>
+
+ <listitem>
+ <para>Forces <command>ssh</command> to use version 2 of
+ the protocol. (Do not use if you are working with older
+ SSH servers)</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-N</option></term>
+
+ <listitem>
+ <para>Indicates no command, or tunnel only. If omitted,
+ <command>ssh</command> would initiate a normal
+ session.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-f</option></term>
+
+ <listitem>
+ <para>Forces <command>ssh</command> to run in the
+ background.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-L</option></term>
+
+ <listitem>
+ <para>Indicates a local tunnel in
+ <replaceable>localport:remotehost:remoteport</replaceable>
+ fashion.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>user@foo.example.com</option></term>
+
+ <listitem>
+ <para>The remote SSH server.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+
+ <para>An SSH tunnel works by creating a listen socket on
+ <systemitem>localhost</systemitem> on the specified port.
+ It then forwards any connection received
+ on the local host/port via the SSH connection to the specified
+ remote host and port.</para>
+
+ <para>In the example, port <replaceable>5023</replaceable> on
+ <systemitem>localhost</systemitem> is being forwarded to port
+ <replaceable>23</replaceable> on <systemitem>localhost</systemitem>
+ of the remote machine. Since <replaceable>23</replaceable> is <application>telnet</application>,
+ this would create a secure <application>telnet</application> session through an SSH tunnel.</para>
+
+ <para>This can be used to wrap any number of insecure TCP
+ protocols such as SMTP, POP3, FTP, etc.</para>
+
+ <example>
+ <title>Using SSH to Create a Secure Tunnel for SMTP</title>
+
+ <screen>&prompt.user; <userinput>ssh -2 -N -f -L 5025:localhost:25 user@mailserver.example.com</userinput>
+user@mailserver.example.com's password: <userinput>*****</userinput>
+&prompt.user; <userinput>telnet localhost 5025</userinput>
+Trying 127.0.0.1...
+Connected to localhost.
+Escape character is '^]'.
+220 mailserver.example.com ESMTP</screen>
+
+ <para>This can be used in conjunction with an
+ &man.ssh-keygen.1; and additional user accounts to create a
+ more seamless/hassle-free SSH tunneling environment. Keys
+ can be used in place of typing a password, and the tunnels
+ can be run as a separate user.</para>
+ </example>
+
+ <sect3>
+ <title>Practical SSH Tunneling Examples</title>
+
+ <sect4>
+ <title>Secure Access of a POP3 Server</title>
+
+ <para>At work, there is an SSH server that accepts
+ connections from the outside. On the same office network
+ resides a mail server running a POP3 server. The network,
+ or network path between your home and office may or may not
+ be completely trustable. Because of this, you need to check
+ your e-mail in a secure manner. The solution is to create
+ an SSH connection to your office's SSH server, and tunnel
+ through to the mail server.</para>
+
+ <screen>&prompt.user; <userinput>ssh -2 -N -f -L 2110:mail.example.com:110 user@ssh-server.example.com</userinput>
+user@ssh-server.example.com's password: <userinput>******</userinput></screen>
+
+ <para>When the tunnel is up and running, you can point your
+ mail client to send POP3 requests to <systemitem>localhost</systemitem>
+ port 2110. A connection here will be forwarded securely across
+ the tunnel to <systemitem>mail.example.com</systemitem>.</para>
+ </sect4>
+
+ <sect4>
+ <title>Bypassing a Draconian Firewall</title>
+
+ <para>Some network administrators impose extremely draconian
+ firewall rules, filtering not only incoming connections,
+ but outgoing connections. You may be only given access
+ to contact remote machines on ports 22 and 80 for SSH
+ and web surfing.</para>
+
+ <para>You may wish to access another (perhaps non-work
+ related) service, such as an Ogg Vorbis server to stream
+ music. If this Ogg Vorbis server is streaming on some other
+ port than 22 or 80, you will not be able to access it.</para>
+
+ <para>The solution is to create an SSH connection to a machine
+ outside of your network's firewall, and use it to tunnel to
+ the Ogg Vorbis server.</para>
+
+ <screen>&prompt.user; <userinput>ssh -2 -N -f -L 8888:music.example.com:8000 user@unfirewalled-system.example.org</userinput>
+user@unfirewalled-system.example.org's password: <userinput>*******</userinput></screen>
+
+ <para>Your streaming client can now be pointed to
+ <systemitem>localhost</systemitem> port 8888, which will be
+ forwarded over to <systemitem>music.example.com</systemitem> port
+ 8000, successfully evading the firewall.</para>
+ </sect4>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>The <varname>AllowUsers</varname> Users Option</title>
+
+ <para>It is often a good idea to limit which users can log in and
+ from where. The <literal>AllowUsers</literal> option is a good
+ way to accomplish this. For example, to only allow the
+ <systemitem class="username">root</systemitem> user to log in from
+ <systemitem class="ipaddress">192.168.1.32</systemitem>, something like this
+ would be appropriate in the
+ <filename>/etc/ssh/sshd_config</filename> file:</para>
+
+ <programlisting>AllowUsers root@192.168.1.32</programlisting>
+
+ <para>To allow the user <systemitem class="username">admin</systemitem> to log in from
+ anywhere, just list the username by itself:</para>
+
+ <programlisting>AllowUsers admin</programlisting>
+
+ <para>Multiple users should be listed on the same line, like so:</para>
+
+ <programlisting>AllowUsers root@192.168.1.32 admin</programlisting>
+
+ <note>
+ <para>It is important that you list each user that needs to
+ log in to this machine; otherwise they will be locked out.</para>
+ </note>
+
+ <para>After making changes to
+ <filename>/etc/ssh/sshd_config</filename> you must tell
+ &man.sshd.8; to reload its config files, by running:</para>
+
+ <screen>&prompt.root; <userinput>/etc/rc.d/sshd reload</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Further Reading</title>
+ <para><link xlink:href="http://www.openssh.com/">OpenSSH</link></para>
+ <para>&man.ssh.1; &man.scp.1; &man.ssh-keygen.1;
+ &man.ssh-agent.1; &man.ssh-add.1; &man.ssh.config.5;</para>
+ <para>&man.sshd.8; &man.sftp-server.8; &man.sshd.config.5;</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="fs-acl">
+ <info><title>File System Access Control Lists</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm>
+ <primary>ACL</primary>
+ </indexterm>
+
+ <para>In conjunction with file system enhancements like snapshots, FreeBSD 5.0
+ and later offers the security of File System Access Control Lists
+ (<acronym>ACLs</acronym>).</para>
+
+ <para>Access Control Lists extend the standard &unix;
+ permission model in a highly compatible (&posix;.1e) way. This feature
+ permits an administrator to make use of and take advantage of a
+ more sophisticated security model.</para>
+
+ <para>To enable <acronym>ACL</acronym> support for <acronym>UFS</acronym>
+ file systems, the following:</para>
+
+ <programlisting>options UFS_ACL</programlisting>
+
+ <para>must be compiled into the kernel. If this option has
+ not been compiled in, a warning message will be displayed
+ when attempting to mount a file system supporting <acronym>ACLs</acronym>.
+ This option is included in the <filename>GENERIC</filename> kernel.
+ <acronym>ACLs</acronym> rely on extended attributes being enabled on
+ the file system. Extended attributes are natively supported in the next generation
+ &unix; file system, <acronym>UFS2</acronym>.</para>
+
+ <note><para>A higher level of administrative overhead is required to
+ configure extended attributes on <acronym>UFS1</acronym> than on
+ <acronym>UFS2</acronym>. The performance of extended attributes
+ on <acronym>UFS2</acronym> is also substantially higher. As a
+ result, <acronym>UFS2</acronym> is generally recommended in preference
+ to <acronym>UFS1</acronym> for use with access control lists.</para></note>
+
+ <para><acronym>ACLs</acronym> are enabled by the mount-time administrative
+ flag, <option>acls</option>, which may be added to <filename>/etc/fstab</filename>.
+ The mount-time flag can also be automatically set in a persistent manner using
+ &man.tunefs.8; to modify a superblock <acronym>ACLs</acronym> flag in the
+ file system header. In general, it is preferred to use the superblock flag
+ for several reasons:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The mount-time <acronym>ACLs</acronym> flag cannot be changed by a
+ remount (&man.mount.8; <option>-u</option>), only by means of a complete
+ &man.umount.8; and fresh &man.mount.8;. This means that
+ <acronym>ACLs</acronym> cannot be enabled on the root file system after boot.
+ It also means that you cannot change the disposition of a file system once
+ it is in use.</para>
+ </listitem>
+
+ <listitem>
+ <para>Setting the superblock flag will cause the file system to always be
+ mounted with <acronym>ACLs</acronym> enabled even if there is not an
+ <filename>fstab</filename> entry or if the devices re-order. This prevents
+ accidental mounting of the file system without <acronym>ACLs</acronym>
+ enabled, which can result in <acronym>ACLs</acronym> being improperly enforced,
+ and hence security problems.</para>
+ </listitem>
+ </itemizedlist>
+
+ <note><para>We may change the <acronym>ACLs</acronym> behavior to allow the flag to
+ be enabled without a complete fresh &man.mount.8;, but we consider it desirable to
+ discourage accidental mounting without <acronym>ACLs</acronym> enabled, because you
+ can shoot your feet quite nastily if you enable <acronym>ACLs</acronym>, then disable
+ them, then re-enable them without flushing the extended attributes. In general, once
+ you have enabled <acronym>ACLs</acronym> on a file system, they should not be disabled,
+ as the resulting file protections may not be compatible with those intended by the
+ users of the system, and re-enabling <acronym>ACLs</acronym> may re-attach the previous
+ <acronym>ACLs</acronym> to files that have since had their permissions changed,
+ resulting in other unpredictable behavior.</para></note>
+
+ <para>File systems with <acronym>ACLs</acronym> enabled will show a <literal>+</literal>
+ (plus) sign in their permission settings when viewed. For example:</para>
+
+ <programlisting>drwx------ 2 robert robert 512 Dec 27 11:54 private
+drwxrwx---+ 2 robert robert 512 Dec 23 10:57 directory1
+drwxrwx---+ 2 robert robert 512 Dec 22 10:20 directory2
+drwxrwx---+ 2 robert robert 512 Dec 27 11:57 directory3
+drwxr-xr-x 2 robert robert 512 Nov 10 11:54 public_html</programlisting>
+
+ <para>Here we see that the <filename>directory1</filename>,
+ <filename>directory2</filename>, and <filename>directory3</filename>
+ directories are all taking advantage of <acronym>ACLs</acronym>. The
+ <filename>public_html</filename> directory is not.</para>
+
+ <sect2>
+ <title>Making Use of <acronym>ACL</acronym>s</title>
+
+ <para>The file system <acronym>ACL</acronym>s can be viewed by the
+ &man.getfacl.1; utility. For instance, to view the
+ <acronym>ACL</acronym> settings on the <filename>test</filename>
+ file, one would use the command:</para>
+
+ <screen>&prompt.user; <userinput>getfacl test</userinput>
+ #file:test
+ #owner:1001
+ #group:1001
+ user::rw-
+ group::r--
+ other::r--</screen>
+
+ <para>To change the <acronym>ACL</acronym> settings on this file,
+ invoke the &man.setfacl.1; utility. Observe:</para>
+
+ <screen>&prompt.user; <userinput>setfacl -k test</userinput></screen>
+
+ <para>The <option>-k</option> flag will remove all of the
+ currently defined <acronym>ACL</acronym>s from a file or file
+ system. The more preferable method would be to use
+ <option>-b</option> as it leaves the basic fields required for
+ <acronym>ACL</acronym>s to work.</para>
+
+ <screen>&prompt.user; <userinput>setfacl -m u:trhodes:rwx,group:web:r--,o::--- test</userinput></screen>
+
+ <para>In the aforementioned command, the <option>-m</option>
+ option was used to modify the default <acronym>ACL</acronym>
+ entries. Since there were no pre-defined entries, as they were
+ removed by the previous command, this will restore the default
+ options and assign the options listed. Take care to notice that
+ if you add a user or group which does not exist on the system,
+ an <errorname>Invalid argument</errorname> error will be printed
+ to <filename>stdout</filename>.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="security-portaudit">
+ <info><title>Monitoring Third Party Security Issues</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm>
+ <primary>Portaudit</primary>
+ </indexterm>
+
+ <para>In recent years, the security world has made many improvements
+ to how vulnerability assessment is handled. The threat of system
+ intrusion increases as third party utilities are installed and
+ configured for virtually any operating system available
+ today.</para>
+
+ <para>Vulnerability assessment is a key factor in security, and
+ while &os; releases advisories for the base system, doing so
+ for every third party utility is beyond the &os; Project's
+ capability. There is a way to mitigate third party
+ vulnerabilities and warn administrators of known security
+ issues. A &os; add on utility known as
+ <application>Portaudit</application> exists solely for this
+ purpose.</para>
+
+ <para>The <package role="port">security/portaudit</package> port
+ polls a database, updated and maintained by the &os; Security
+ Team and ports developers, for known security issues.</para>
+
+ <para>To begin using <application>Portaudit</application>, one
+ must install it from the Ports Collection:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/security/portaudit &amp;&amp; make install clean</userinput></screen>
+
+ <para>During the install process, the configuration files for
+ &man.periodic.8; will be updated, permitting
+ <application>Portaudit</application> output in the daily security
+ runs. Ensure the daily security run emails, which are sent to
+ <systemitem class="username">root</systemitem>'s email account, are being read. No
+ more configuration will be required here.</para>
+
+ <para>After installation, an administrator can update the database
+ and view known vulnerabilities in installed packages by invoking
+ the following command:</para>
+
+ <screen>&prompt.root; <userinput>portaudit -Fda</userinput></screen>
+
+ <note>
+ <para>The database will automatically be updated during the
+ &man.periodic.8; run; thus, the previous command is completely
+ optional. It is only required for the following
+ examples.</para>
+ </note>
+
+ <para>To audit the third party utilities installed as part of
+ the Ports Collection at anytime, an administrator need only run
+ the following command:</para>
+
+ <screen>&prompt.root; <userinput>portaudit -a</userinput></screen>
+
+ <para><application>Portaudit</application> will produce something
+ like this for vulnerable packages:</para>
+
+ <programlisting>Affected package: cups-base-1.1.22.0_1
+Type of problem: cups-base -- HPGL buffer overflow vulnerability.
+Reference: &lt;http://www.FreeBSD.org/ports/portaudit/40a3bca2-6809-11d9-a9e7-0001020eed82.html&gt;
+
+1 problem(s) in your installed packages found.
+
+You are advised to update or deinstall the affected package(s) immediately.</programlisting>
+
+ <para>By pointing a web browser to the <acronym>URL</acronym> shown,
+ an administrator may obtain more information about the
+ vulnerability in question. This will include versions affected,
+ by &os; Port version, along with other web sites which may contain
+ security advisories.</para>
+
+ <para>In short, <application>Portaudit</application> is a powerful
+ utility and extremely useful when coupled with the
+ <application>Portupgrade</application> port.</para>
+ </sect1>
+
+ <sect1 xml:id="security-advisories">
+ <info><title>&os; Security Advisories</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm>
+ <primary>FreeBSD Security Advisories</primary>
+ </indexterm>
+
+ <para>Like many production quality operating systems, &os; publishes
+ <quote>Security Advisories</quote>. These advisories are usually
+ mailed to the security lists and noted in the Errata only
+ after the appropriate releases have been patched. This section
+ will work to explain what an advisory is, how to understand it,
+ and what measures to take in order to patch a system.</para>
+
+ <sect2>
+ <title>What does an advisory look like?</title>
+
+ <para>The &os; security advisories look similar to the one below,
+ taken from the &a.security-notifications.name; mailing list.</para>
+
+ <programlisting>=============================================================================
+&os;-SA-XX:XX.UTIL Security Advisory
+ The &os; Project
+
+Topic: denial of service due to some problem<co xml:id="co-topic"/>
+
+Category: core<co xml:id="co-category"/>
+Module: sys<co xml:id="co-module"/>
+Announced: 2003-09-23<co xml:id="co-announce"/>
+Credits: Person@EMAIL-ADDRESS<co xml:id="co-credit"/>
+Affects: All releases of &os;<co xml:id="co-affects"/>
+ &os; 4-STABLE prior to the correction date
+Corrected: 2003-09-23 16:42:59 UTC (RELENG_4, 4.9-PRERELEASE)
+ 2003-09-23 20:08:42 UTC (RELENG_5_1, 5.1-RELEASE-p6)
+ 2003-09-23 20:07:06 UTC (RELENG_5_0, 5.0-RELEASE-p15)
+ 2003-09-23 16:44:58 UTC (RELENG_4_8, 4.8-RELEASE-p8)
+ 2003-09-23 16:47:34 UTC (RELENG_4_7, 4.7-RELEASE-p18)
+ 2003-09-23 16:49:46 UTC (RELENG_4_6, 4.6-RELEASE-p21)
+ 2003-09-23 16:51:24 UTC (RELENG_4_5, 4.5-RELEASE-p33)
+ 2003-09-23 16:52:45 UTC (RELENG_4_4, 4.4-RELEASE-p43)
+ 2003-09-23 16:54:39 UTC (RELENG_4_3, 4.3-RELEASE-p39)<co xml:id="co-corrected"/>
+&os; only: NO<co xml:id="co-only"/>
+
+For general information regarding FreeBSD Security Advisories,
+including descriptions of the fields above, security branches, and the
+following sections, please visit
+http://www.FreeBSD.org/security/.
+
+I. Background<co xml:id="co-backround"/>
+
+
+II. Problem Description<co xml:id="co-descript"/>
+
+
+III. Impact<co xml:id="co-impact"/>
+
+
+IV. Workaround<co xml:id="co-workaround"/>
+
+
+V. Solution<co xml:id="co-solution"/>
+
+
+VI. Correction details<co xml:id="co-details"/>
+
+
+VII. References<co xml:id="co-ref"/></programlisting>
+
+
+ <calloutlist>
+ <callout arearefs="co-topic">
+ <para>The <literal>Topic</literal> field indicates exactly what the problem is.
+ It is basically an introduction to the current security
+ advisory and notes the utility with the
+ vulnerability.</para>
+ </callout>
+
+ <callout arearefs="co-category">
+ <para>The <literal>Category</literal> refers to the affected part of the system
+ which may be one of <literal>core</literal>, <literal>contrib</literal>, or <literal>ports</literal>. The <literal>core</literal>
+ category means that the vulnerability affects a core
+ component of the &os; operating system. The <literal>contrib</literal>
+ category means that the vulnerability affects software
+ contributed to the &os; Project, such as
+ <application>sendmail</application>. Finally the <literal>ports</literal>
+ category indicates that the vulnerability affects add on
+ software available as part of the Ports Collection.</para>
+ </callout>
+
+ <callout arearefs="co-module">
+ <para>The <literal>Module</literal> field refers to the component location, for
+ instance <literal>sys</literal>. In this example, we see that the module,
+ <literal>sys</literal>, is affected; therefore, this vulnerability
+ affects a component used within the kernel.</para>
+ </callout>
+
+ <callout arearefs="co-announce">
+ <para>The <literal>Announced</literal> field reflects the date said security
+ advisory was published, or announced to the world. This
+ means that the security team has verified that the problem
+ does exist and that a patch has been committed to the &os;
+ source code repository.</para>
+ </callout>
+
+ <callout arearefs="co-credit">
+ <para>The <literal>Credits</literal> field gives credit to the individual or
+ organization who noticed the vulnerability and reported
+ it.</para>
+ </callout>
+
+ <callout arearefs="co-affects">
+ <para>The <literal>Affects</literal> field explains which releases of &os; are
+ affected by this vulnerability. For the kernel, a quick
+ look over the output from <command>ident</command> on the
+ affected files will help in determining the revision.
+ For ports, the version number is listed after the port name
+ in <filename>/var/db/pkg</filename>. If the system does not
+ sync with the &os; <acronym>CVS</acronym> repository and rebuild
+ daily, chances are that it is affected.</para>
+ </callout>
+
+ <callout arearefs="co-corrected">
+ <para>The <literal>Corrected</literal> field indicates the date, time, time
+ offset, and release that was corrected.</para>
+ </callout>
+
+ <callout arearefs="co-only">
+ <para>The <literal>&os; only</literal> field indicates whether this vulnerability
+ affects just &os;, or if it affects other operating systems
+ as well.</para>
+ </callout>
+
+ <callout arearefs="co-backround">
+ <para>The <literal>Background</literal> field gives information on exactly what
+ the affected utility is. Most of the time this is why
+ the utility exists in &os;, what it is used for, and a bit
+ of information on how the utility came to be.</para>
+ </callout>
+
+ <callout arearefs="co-descript">
+ <para>The <literal>Problem Description</literal> field explains the security hole
+ in depth. This can include information on flawed code, or
+ even how the utility could be maliciously used to open
+ a security hole.</para>
+ </callout>
+
+ <callout arearefs="co-impact">
+ <para>The <literal>Impact</literal> field describes what type of impact the
+ problem could have on a system. For example, this could
+ be anything from a denial of service attack, to extra
+ privileges available to users, or even giving the attacker
+ superuser access.</para>
+ </callout>
+
+ <callout arearefs="co-workaround">
+ <para>The <literal>Workaround</literal> field offers a feasible workaround to
+ system administrators who may be incapable of upgrading
+ the system. This may be due to time constraints, network
+ availability, or a slew of other reasons. Regardless,
+ security should not be taken lightly, and an affected system
+ should either be patched or the security hole workaround
+ should be implemented.</para>
+ </callout>
+
+ <callout arearefs="co-solution">
+ <para>The <literal>Solution</literal> field offers instructions on patching the
+ affected system. This is a step by step tested and verified
+ method for getting a system patched and working
+ securely.</para>
+ </callout>
+
+ <callout arearefs="co-details">
+ <para>The <literal>Correction Details</literal> field displays the
+ <acronym>CVS</acronym> branch or release name with the
+ periods changed to underscore characters. It also shows
+ the revision number of the affected files within each
+ branch.</para>
+ </callout>
+
+ <callout arearefs="co-ref">
+ <para>The <literal>References</literal> field usually offers sources of other
+ information. This can included web <acronym>URL</acronym>s,
+ books, mailing lists, and newsgroups.</para>
+ </callout>
+ </calloutlist>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="security-accounting">
+ <info><title>Process Accounting</title>
+ <authorgroup>
+ <author><personname><firstname>Tom</firstname><surname>Rhodes</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm>
+ <primary>Process Accounting</primary>
+ </indexterm>
+
+ <para>Process accounting is a security method in which an
+ administrator may keep track of system resources used,
+ their allocation among users, provide for system monitoring,
+ and minimally track a user's commands.</para>
+
+ <para>This indeed has its own positive and negative points. One of
+ the positives is that an intrusion may be narrowed down
+ to the point of entry. A negative is the amount of logs
+ generated by process accounting, and the disk space they may
+ require. This section will walk an administrator through
+ the basics of process accounting.</para>
+
+ <sect2>
+ <title>Enable and Utilizing Process Accounting</title>
+ <para>Before making use of process accounting, it
+ must be enabled. To do this, execute the following
+ commands:</para>
+
+ <screen>&prompt.root; <userinput>touch /var/account/acct</userinput>
+
+&prompt.root; <userinput>accton /var/account/acct</userinput>
+
+&prompt.root; <userinput>echo 'accounting_enable="YES"' &gt;&gt; /etc/rc.conf</userinput></screen>
+
+ <para>Once enabled, accounting will begin to track
+ <acronym>CPU</acronym> stats, commands, etc. All accounting
+ logs are in a non-human readable format and may be viewed
+ using the &man.sa.8; utility. If issued without any options,
+ <command>sa</command> will print information relating to the
+ number of per user calls, the total elapsed time in minutes,
+ total <acronym>CPU</acronym> and user time in minutes, average
+ number of I/O operations, etc.</para>
+
+ <para>To view information about commands being issued, one
+ would use the &man.lastcomm.1; utility. The
+ <command>lastcomm</command> may be used to print out commands
+ issued by users on specific &man.ttys.5;, for example:</para>
+
+ <screen>&prompt.root; <userinput>lastcomm ls
+ trhodes ttyp1</userinput></screen>
+
+ <para>Would print out all known usage of the <command>ls</command>
+ by <systemitem class="username">trhodes</systemitem> on the ttyp1 terminal.</para>
+
+ <para>Many other useful options exist and are explained in the
+ &man.lastcomm.1;, &man.acct.5; and &man.sa.8; manual
+ pages.</para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/serialcomms/Makefile b/zh_TW.UTF-8/books/handbook/serialcomms/Makefile
new file mode 100644
index 0000000000..3dbd97ce6d
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/serialcomms/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= serialcomms/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/serialcomms/chapter.xml b/zh_TW.UTF-8/books/handbook/serialcomms/chapter.xml
new file mode 100644
index 0000000000..48fd4b3b86
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/serialcomms/chapter.xml
@@ -0,0 +1,2856 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.108
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="serialcomms">
+ <title>Serial Communications</title>
+
+ <sect1 xml:id="serial-synopsis">
+ <title>Synopsis</title>
+
+ <indexterm><primary>serial communications</primary></indexterm>
+ <para>&unix; has always had support for serial communications. In fact,
+ the very first &unix; machines relied on serial lines for user input
+ and output. Things have changed a lot from the days when the average
+ <quote>terminal</quote> consisted of a 10-character-per-second serial
+ printer and a keyboard. This chapter will cover some of the ways in
+ which FreeBSD uses serial communications.</para>
+
+ <para>After reading this chapter, you will know:</para>
+ <itemizedlist>
+ <listitem><para>How to connect terminals to your FreeBSD
+ system.</para></listitem>
+ <listitem><para>How to use a modem to dial out to remote
+ hosts.</para></listitem>
+ <listitem><para>How to allow remote users to login to your
+ system with a modem.</para></listitem>
+ <listitem><para>How to boot your system from a serial
+ console.</para></listitem>
+ </itemizedlist>
+
+ <para>Before reading this chapter, you should:</para>
+ <itemizedlist>
+ <listitem><para>Know how to configure and install a new kernel (<xref linkend="kernelconfig"/>).</para></listitem>
+ <listitem><para>Understand &unix; permissions and processes (<xref linkend="basics"/>).</para></listitem>
+ <listitem><para>Have access to the technical manual for the
+ serial hardware (modem or multi-port card) that you would like
+ to use with FreeBSD.</para></listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="serial">
+ <title>Introduction</title>
+
+ <!-- XXX Write me! -->
+
+ <sect2 xml:id="serial-terminology">
+ <title>Terminology</title>
+
+ <variablelist>
+ <indexterm><primary>bits-per-second</primary></indexterm>
+ <varlistentry>
+ <term>bps</term>
+ <listitem>
+ <para>Bits per Second &mdash; the rate at which data is
+ transmitted</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>DTE</term>
+ <listitem>
+ <indexterm><primary>DTE</primary></indexterm>
+
+ <para>Data Terminal Equipment &mdash; for example, your
+ computer</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>DCE</term>
+ <listitem>
+ <indexterm><primary>DCE</primary></indexterm>
+
+ <para>Data Communications Equipment &mdash; your modem</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RS-232</term>
+ <listitem>
+ <indexterm><primary>RS-232C cables</primary></indexterm>
+
+ <para>EIA standard for hardware serial communications</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>When talking about communications data rates, this section
+ does not use the term <quote>baud</quote>. Baud refers to the
+ number of electrical state transitions that may be made in a
+ period of time, while <quote>bps</quote> (bits per second) is
+ the <emphasis>correct</emphasis> term to use (at least it does not
+ seem to bother the curmudgeons quite as much).</para>
+ </sect2>
+
+ <sect2 xml:id="serial-cables-ports">
+ <title>Cables and Ports</title>
+
+ <para>To connect a modem or terminal to your FreeBSD system, you
+ will need a serial port on your computer and the proper cable to connect
+ to your serial device. If you are already familiar with your
+ hardware and the cable it requires, you can safely skip this
+ section.</para>
+
+ <sect3 xml:id="term-cables">
+ <title>Cables</title>
+
+ <para>There are several different kinds of serial cables. The
+ two most common types for our purposes are null-modem cables
+ and standard (<quote>straight</quote>) RS-232 cables. The documentation
+ for your hardware should describe the type of cable
+ required.</para>
+
+ <sect4 xml:id="term-cables-null">
+ <title>Null-modem Cables</title>
+
+ <indexterm>
+ <primary>null-modem cable</primary>
+ </indexterm>
+ <para>A null-modem cable passes some signals, such as <quote>Signal
+ Ground</quote>, straight through, but switches other signals. For
+ example, the <quote>Transmitted Data</quote> pin on one end goes to the
+ <quote>Received Data</quote> pin on the other end.</para>
+
+ <para>You can also construct your own null-modem cable for use with
+ terminals (e.g., for quality purposes). This table shows the RS-232C
+ <link linkend="serialcomms-signal-names">signals</link> and the pin
+ numbers on a DB-25 connector. Note that the standard also calls for a
+ straight-through pin 1 to pin 1 <emphasis>Protective Ground</emphasis>
+ line, but it is often omitted. Some terminals work OK using only
+ pins 2, 3 and 7, while others require different configurations than
+ the examples shown below.</para>
+
+ <table frame="none" pgwide="1">
+ <title>DB-25 to DB-25 Null-Modem Cable</title>
+
+ <tgroup cols="5">
+ <thead>
+ <row>
+ <entry align="left">Signal</entry>
+ <entry align="left">Pin #</entry>
+ <entry/>
+ <entry align="left">Pin #</entry>
+ <entry align="left">Signal</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>SG</entry>
+ <entry>7</entry>
+ <entry>connects to</entry>
+ <entry>7</entry>
+ <entry>SG</entry>
+ </row>
+
+ <row>
+ <entry>TD</entry>
+ <entry>2</entry>
+ <entry>connects to</entry>
+ <entry>3</entry>
+ <entry>RD</entry>
+ </row>
+
+ <row>
+ <entry>RD</entry>
+ <entry>3</entry>
+ <entry>connects to</entry>
+ <entry>2</entry>
+ <entry>TD</entry>
+ </row>
+
+ <row>
+ <entry>RTS</entry>
+ <entry>4</entry>
+ <entry>connects to</entry>
+ <entry>5</entry>
+ <entry>CTS</entry>
+ </row>
+
+ <row>
+ <entry>CTS</entry>
+ <entry>5</entry>
+ <entry>connects to</entry>
+ <entry>4</entry>
+ <entry>RTS</entry>
+ </row>
+
+ <row>
+ <entry>DTR</entry>
+ <entry>20</entry>
+ <entry>connects to</entry>
+ <entry>6</entry>
+ <entry>DSR</entry>
+ </row>
+
+ <row>
+ <entry>DTR</entry>
+ <entry>20</entry>
+ <entry>connects to</entry>
+ <entry>8</entry>
+ <entry>DCD</entry>
+ </row>
+
+ <row>
+ <entry>DSR</entry>
+ <entry>6</entry>
+ <entry>connects to</entry>
+ <entry>20</entry>
+ <entry>DTR</entry>
+ </row>
+
+ <row>
+ <entry>DCD</entry>
+ <entry>8</entry>
+ <entry>connects to</entry>
+ <entry>20</entry>
+ <entry>DTR</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>Here are two other schemes more common nowadays.</para>
+
+ <table frame="none" pgwide="1">
+ <title>DB-9 to DB-9 Null-Modem Cable</title>
+
+ <tgroup cols="5">
+ <thead>
+ <row>
+ <entry align="left">Signal</entry>
+ <entry align="left">Pin #</entry>
+ <entry/>
+ <entry align="left">Pin #</entry>
+ <entry align="left">Signal</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>RD</entry>
+ <entry>2</entry>
+ <entry>connects to</entry>
+ <entry>3</entry>
+ <entry>TD</entry>
+ </row>
+
+ <row>
+ <entry>TD</entry>
+ <entry>3</entry>
+ <entry>connects to</entry>
+ <entry>2</entry>
+ <entry>RD</entry>
+ </row>
+
+ <row>
+ <entry>DTR</entry>
+ <entry>4</entry>
+ <entry>connects to</entry>
+ <entry>6</entry>
+ <entry>DSR</entry>
+ </row>
+
+ <row>
+ <entry>DTR</entry>
+ <entry>4</entry>
+ <entry>connects to</entry>
+ <entry>1</entry>
+ <entry>DCD</entry>
+ </row>
+
+ <row>
+ <entry>SG</entry>
+ <entry>5</entry>
+ <entry>connects to</entry>
+ <entry>5</entry>
+ <entry>SG</entry>
+ </row>
+
+ <row>
+ <entry>DSR</entry>
+ <entry>6</entry>
+ <entry>connects to</entry>
+ <entry>4</entry>
+ <entry>DTR</entry>
+ </row>
+
+ <row>
+ <entry>DCD</entry>
+ <entry>1</entry>
+ <entry>connects to</entry>
+ <entry>4</entry>
+ <entry>DTR</entry>
+ </row>
+
+ <row>
+ <entry>RTS</entry>
+ <entry>7</entry>
+ <entry>connects to</entry>
+ <entry>8</entry>
+ <entry>CTS</entry>
+ </row>
+
+ <row>
+ <entry>CTS</entry>
+ <entry>8</entry>
+ <entry>connects to</entry>
+ <entry>7</entry>
+ <entry>RTS</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none" pgwide="1">
+ <title>DB-9 to DB-25 Null-Modem Cable</title>
+
+ <tgroup cols="5">
+ <thead>
+ <row>
+ <entry align="left">Signal</entry>
+ <entry align="left">Pin #</entry>
+ <entry/>
+ <entry align="left">Pin #</entry>
+ <entry align="left">Signal</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>RD</entry>
+ <entry>2</entry>
+ <entry>connects to</entry>
+ <entry>2</entry>
+ <entry>TD</entry>
+ </row>
+
+ <row>
+ <entry>TD</entry>
+ <entry>3</entry>
+ <entry>connects to</entry>
+ <entry>3</entry>
+ <entry>RD</entry>
+ </row>
+
+ <row>
+ <entry>DTR</entry>
+ <entry>4</entry>
+ <entry>connects to</entry>
+ <entry>6</entry>
+ <entry>DSR</entry>
+ </row>
+
+ <row>
+ <entry>DTR</entry>
+ <entry>4</entry>
+ <entry>connects to</entry>
+ <entry>8</entry>
+ <entry>DCD</entry>
+ </row>
+
+ <row>
+ <entry>SG</entry>
+ <entry>5</entry>
+ <entry>connects to</entry>
+ <entry>7</entry>
+ <entry>SG</entry>
+ </row>
+
+ <row>
+ <entry>DSR</entry>
+ <entry>6</entry>
+ <entry>connects to</entry>
+ <entry>20</entry>
+ <entry>DTR</entry>
+ </row>
+
+ <row>
+ <entry>DCD</entry>
+ <entry>1</entry>
+ <entry>connects to</entry>
+ <entry>20</entry>
+ <entry>DTR</entry>
+ </row>
+
+ <row>
+ <entry>RTS</entry>
+ <entry>7</entry>
+ <entry>connects to</entry>
+ <entry>5</entry>
+ <entry>CTS</entry>
+ </row>
+
+ <row>
+ <entry>CTS</entry>
+ <entry>8</entry>
+ <entry>connects to</entry>
+ <entry>4</entry>
+ <entry>RTS</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>When one pin at one end connects to a pair of pins
+ at the other end, it is usually implemented with one short
+ wire between the pair of pins in their connector and a
+ long wire to the other single pin.</para>
+ </note>
+
+ <para>The above designs seems to be the most popular. In another
+ variation (explained in the book <emphasis>RS-232 Made
+ Easy</emphasis>) SG connects to SG, TD connects to RD, RTS and
+ CTS connect to DCD, DTR connects to DSR, and vice-versa.</para>
+ </sect4>
+
+ <sect4 xml:id="term-cables-std">
+ <title>Standard RS-232C Cables</title>
+ <indexterm><primary>RS-232C cables</primary></indexterm>
+
+ <para>A standard serial cable passes all of the RS-232C signals
+ straight through. That is, the <quote>Transmitted Data</quote> pin on one
+ end of the cable goes to the <quote>Transmitted Data</quote> pin on the
+ other end. This is the type of cable to use to connect a modem to your
+ FreeBSD system, and is also appropriate for some
+ terminals.</para>
+ </sect4>
+ </sect3>
+
+ <sect3 xml:id="term-ports">
+ <title>Ports</title>
+
+ <para>Serial ports are the devices through which data is transferred
+ between the FreeBSD host computer and the terminal. This section
+ describes the kinds of ports that exist and how they are addressed
+ in FreeBSD.</para>
+
+ <sect4 xml:id="term-portkinds">
+ <title>Kinds of Ports</title>
+
+ <para>Several kinds of serial ports exist. Before you purchase or
+ construct a cable, you need to make sure it will fit the ports on
+ your terminal and on the FreeBSD system.</para>
+
+ <para>Most terminals will have DB-25 ports. Personal computers,
+ including PCs running FreeBSD, will have DB-25 or DB-9 ports. If you
+ have a multiport serial card for your PC, you may have RJ-12 or
+ RJ-45 ports.</para>
+
+ <para>See the documentation that accompanied the hardware for
+ specifications on the kind of port in use. A visual inspection of
+ the port often works too.</para>
+ </sect4>
+
+ <sect4 xml:id="term-portnames">
+ <title>Port Names</title>
+
+ <para>In FreeBSD, you access each serial port through an entry in
+ the <filename>/dev</filename> directory. There are two different
+ kinds of entries:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Call-in ports are named
+ <filename>/dev/ttydN</filename>
+ where <replaceable>N</replaceable> is the port number,
+ starting from zero. Generally, you use the call-in port for
+ terminals. Call-in ports require that the serial line assert
+ the data carrier detect (DCD) signal to work correctly.</para>
+ </listitem>
+
+ <listitem>
+ <para>Call-out ports are named
+ <filename>/dev/cuadN</filename>.
+ You usually do not use the call-out port for terminals, just
+ for modems. You may use the call-out port if the serial cable
+ or the terminal does not support the carrier detect
+ signal.</para>
+
+ <note><para>Call-out ports are named
+ <filename>/dev/cuaaN</filename> in
+ &os;&nbsp;5.X and older.</para></note>
+ </listitem>
+ </itemizedlist>
+
+ <para>If you have connected a terminal to the first serial port
+ (<filename>COM1</filename> in &ms-dos;), then you will
+ use <filename>/dev/ttyd0</filename> to refer to the terminal. If
+ the terminal is on the second serial port (also known as
+ <filename>COM2</filename>), use
+ <filename>/dev/ttyd1</filename>, and so forth.</para>
+
+ </sect4>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Kernel Configuration</title>
+
+ <para>FreeBSD supports four serial ports by default. In the
+ &ms-dos; world, these are known as
+ <filename>COM1</filename>,
+ <filename>COM2</filename>,
+ <filename>COM3</filename>, and
+ <filename>COM4</filename>. FreeBSD currently supports
+ <quote>dumb</quote> multiport serial interface cards, such as
+ the BocaBoard 1008 and 2016, as well as more
+ intelligent multi-port cards such as those made by Digiboard
+ and Stallion Technologies. However, the default kernel only looks
+ for the standard COM ports.</para>
+
+ <para>To see if your kernel recognizes any of your serial ports, watch
+ for messages while the kernel is booting, or use the
+ <command>/sbin/dmesg</command> command to replay the kernel's boot
+ messages. In particular, look for messages that start with the
+ characters <literal>sio</literal>.</para>
+
+ <tip><para>To view just the messages that have the word
+ <literal>sio</literal>, use the command:</para>
+
+ <screen>&prompt.root; <userinput>/sbin/dmesg | grep 'sio'</userinput></screen>
+ </tip>
+
+ <para>For example, on a system with four serial ports, these are the
+ serial-port specific kernel boot messages:</para>
+
+ <screen>sio0 at 0x3f8-0x3ff irq 4 on isa
+sio0: type 16550A
+sio1 at 0x2f8-0x2ff irq 3 on isa
+sio1: type 16550A
+sio2 at 0x3e8-0x3ef irq 5 on isa
+sio2: type 16550A
+sio3 at 0x2e8-0x2ef irq 9 on isa
+sio3: type 16550A</screen>
+
+ <para>If your kernel does not recognize all of your serial
+ ports, you will probably need to configure your kernel
+ in the <filename>/boot/device.hints</filename> file. You can
+ also comment-out or completely remove lines for devices you do not
+ have.</para>
+
+ <para>On &os;&nbsp;4.X you have to edit your kernel configuration file.
+ For detailed information on configuring your kernel, please see <xref linkend="kernelconfig"/>. The relevant device lines would look like
+ this:</para>
+
+ <programlisting>device sio0 at isa? port IO_COM1 irq 4
+device sio1 at isa? port IO_COM2 irq 3
+device sio2 at isa? port IO_COM3 irq 5
+device sio3 at isa? port IO_COM4 irq 9</programlisting>
+
+ <para>Please refer to the &man.sio.4; manual page for
+ more information on serial ports and multiport boards configuration.
+ Be careful if you are using a configuration
+ file that was previously used for a different version of
+ FreeBSD because the device flags and the syntax have changed between
+ versions.</para>
+
+ <note>
+ <para><literal>port IO_COM1</literal> is a substitution for
+ <literal>port 0x3f8</literal>, <literal>IO_COM2</literal> is
+ <literal>0x2f8</literal>, <literal>IO_COM3</literal> is
+ <literal>0x3e8</literal>, and <literal>IO_COM4</literal> is
+ <literal>0x2e8</literal>, which are fairly common port addresses for
+ their respective serial ports; interrupts 4, 3, 5, and 9 are fairly
+ common interrupt request lines. Also note that regular serial ports
+ <emphasis>cannot</emphasis> share interrupts on ISA-bus PCs
+ (multiport boards have on-board electronics that allow all the
+ 16550A's on the board to share one or two interrupt request
+ lines).</para>
+ </note>
+
+ </sect2>
+
+ <sect2>
+ <title>Device Special Files</title>
+
+ <para>Most devices in the kernel are accessed through <quote>device
+ special files</quote>, which are located in the
+ <filename>/dev</filename> directory. The <filename>sio</filename>
+ devices are accessed through the
+ <filename>/dev/ttydN</filename> (dial-in)
+ and <filename>/dev/cuadN</filename>
+ (call-out) devices. FreeBSD also provides initialization devices
+ (<filename>/dev/ttydN.init</filename> and
+ <filename>/dev/cuadN.init</filename> on
+ &os;&nbsp;6.X,
+ <filename>/dev/ttyidN</filename> and
+ <filename>/dev/cuaidN</filename> on
+ &os;&nbsp;5.X and older) and
+ locking devices
+ (<filename>/dev/ttydN.lock</filename> and
+ <filename>/dev/cuadN.lock</filename> on
+ &os;&nbsp;6.X,
+ <filename>/dev/ttyldN</filename> and
+ <filename>/dev/cualdN</filename> on
+ &os;&nbsp;5.X and older). The
+ initialization devices are used to initialize communications port
+ parameters each time a port is opened, such as
+ <literal>crtscts</literal> for modems which use
+ <literal>RTS/CTS</literal> signaling for flow control. The locking
+ devices are used to lock flags on ports to prevent users or programs
+ changing certain parameters; see the manual pages &man.termios.4;,
+ &man.sio.4;, and &man.stty.1; for
+ information on the terminal settings, locking and initializing
+ devices, and setting terminal options, respectively.</para>
+
+ <sect3>
+ <title>Making Device Special Files</title>
+
+ <note><para>FreeBSD&nbsp;5.0 includes the &man.devfs.5;
+ filesystem which automatically creates device nodes as
+ needed. If you are running a version of FreeBSD with
+ <literal>devfs</literal> enabled then you can safely skip
+ this section.</para></note>
+
+ <para>A shell script called <command>MAKEDEV</command> in the
+ <filename>/dev</filename> directory manages the device special
+ files. To use <command>MAKEDEV</command> to make dial-up device
+ special files for <filename>COM1</filename> (port 0),
+ <command>cd</command> to <filename>/dev</filename> and issue the
+ command <command>MAKEDEV ttyd0</command>. Likewise, to make dial-up
+ device special files for <filename>COM2</filename> (port 1),
+ use <command>MAKEDEV ttyd1</command>.</para>
+
+ <para><command>MAKEDEV</command> not only creates the
+ <filename>/dev/ttydN</filename> device
+ special files, but also the
+ <filename>/dev/cuaaN</filename>,
+ <filename>/dev/cuaiaN</filename>,
+ <filename>/dev/cualaN</filename>,
+ <filename>/dev/ttyldN</filename>,
+ and
+ <filename>/dev/ttyidN</filename>
+ nodes.</para>
+
+ <para>After making new device special files, be sure to check the
+ permissions on the files (especially the
+ <filename>/dev/cua*</filename> files) to make sure that only users
+ who should have access to those device special files can read and
+ write on them &mdash; you probably do not want to allow your average
+ user to use your modems to dial-out. The default permissions on the
+ <filename>/dev/cua*</filename> files should be sufficient:</para>
+
+ <screen>crw-rw---- 1 uucp dialer 28, 129 Feb 15 14:38 /dev/cuaa1
+crw-rw---- 1 uucp dialer 28, 161 Feb 15 14:38 /dev/cuaia1
+crw-rw---- 1 uucp dialer 28, 193 Feb 15 14:38 /dev/cuala1</screen>
+
+ <para>These permissions allow the user <systemitem class="username">uucp</systemitem> and
+ users in the group <systemitem class="username">dialer</systemitem> to use the call-out
+ devices.</para>
+ </sect3>
+ </sect2>
+
+
+ <sect2 xml:id="serial-hw-config">
+ <title>Serial Port Configuration</title>
+
+ <indexterm><primary><filename>ttyd</filename></primary></indexterm>
+ <indexterm><primary><filename>cuad</filename></primary></indexterm>
+
+ <para>The <filename>ttydN</filename> (or
+ <filename>cuadN</filename>) device is the
+ regular device you will want to open for your applications. When a
+ process opens the device, it will have a default set of terminal I/O
+ settings. You can see these settings with the command</para>
+
+ <screen>&prompt.root; <userinput>stty -a -f /dev/ttyd1</userinput></screen>
+
+ <para>When you change the settings to this device, the settings are in
+ effect until the device is closed. When it is reopened, it goes back to
+ the default set. To make changes to the default set, you can open and
+ adjust the settings of the <quote>initial state</quote> device. For
+ example, to turn on <option>CLOCAL</option> mode, 8 bit communication,
+ and <option>XON/XOFF</option> flow control by default for
+ <filename>ttyd5</filename>, type:</para>
+
+ <screen>&prompt.root; <userinput>stty -f /dev/ttyd5.init clocal cs8 ixon ixoff</userinput></screen>
+
+ <indexterm>
+ <primary>rc files</primary>
+ <secondary><filename>rc.serial</filename></secondary>
+ </indexterm>
+
+ <para>System-wide initialization of the serial devices is
+ controlled in <filename>/etc/rc.d/serial</filename>. This file
+ affects the default settings of serial devices.</para>
+
+ <note>
+ <para>On &os;&nbsp;4.X, system-wide initialization of the serial devices
+ is controlled in <filename>/etc/rc.serial</filename>.</para>
+ </note>
+
+ <para>To prevent certain settings from being changed by an
+ application, make adjustments to the <quote>lock state</quote>
+ device. For example, to lock the speed of
+ <filename>ttyd5</filename> to 57600&nbsp;bps, type:</para>
+
+ <screen>&prompt.root; <userinput>stty -f /dev/ttyd5.lock 57600</userinput></screen>
+
+ <para>Now, an application that opens
+ <filename>ttyd5</filename> and tries to change the speed of
+ the port will be stuck with 57600&nbsp;bps.</para>
+
+ <indexterm>
+ <primary><command>MAKEDEV</command></primary>
+ </indexterm>
+ <para>Naturally, you should make the initial state and lock state devices
+ writable only by the <systemitem class="username">root</systemitem> account.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="term">
+ <info><title>Terminals</title>
+ <authorgroup>
+ <author><personname><firstname>Sean</firstname><surname>Kelly</surname></personname><contrib>Contributed by </contrib></author>
+ <!-- 28 July 1996 -->
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>terminals</primary></indexterm>
+
+ <para>Terminals provide a convenient and low-cost way to access
+ your FreeBSD system when you are not at the computer's console or on
+ a connected network. This section describes how to use terminals with
+ FreeBSD.</para>
+
+ <sect2 xml:id="term-uses">
+ <title>Uses and Types of Terminals</title>
+
+ <para>The original &unix; systems did not have consoles. Instead, people
+ logged in and ran programs through terminals that were connected to
+ the computer's serial ports. It is quite similar to using a modem and
+ terminal software to dial into a remote system to do text-only
+ work.</para>
+
+ <para>Today's PCs have consoles capable of high quality graphics, but
+ the ability to establish a login session on a serial port still exists
+ in nearly every &unix; style operating system today; FreeBSD is no
+ exception. By using a terminal attached to an unused serial port, you
+ can log in and run any text program that you would normally run on the
+ console or in an <command>xterm</command> window in the X Window
+ System.</para>
+
+ <para>For the business user, you can attach many terminals to a FreeBSD
+ system and place them on your employees' desktops. For a home user, a
+ spare computer such as an older IBM PC or a &macintosh; can be a
+ terminal wired into a more powerful computer running FreeBSD. You can
+ turn what might otherwise be a single-user computer into a powerful
+ multiple user system.</para>
+
+ <para>For FreeBSD, there are three kinds of terminals:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><link linkend="term-dumb">Dumb terminals</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="term-pcs">PCs acting as terminals</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link linkend="term-x">X terminals</link></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The remaining subsections describe each kind.</para>
+
+ <sect3 xml:id="term-dumb">
+ <title>Dumb Terminals</title>
+
+ <para>Dumb terminals are specialized pieces of hardware that let you
+ connect to computers over serial lines. They are called
+ <quote>dumb</quote> because they have only enough computational power
+ to display, send, and receive text. You cannot run any programs on
+ them. It is the computer to which you connect them that has all the
+ power to run text editors, compilers, email, games, and so
+ forth.</para>
+
+ <para>There are hundreds of kinds of dumb terminals made by many
+ manufacturers, including Digital Equipment Corporation's VT-100 and
+ Wyse's WY-75. Just about any kind will work with FreeBSD. Some
+ high-end terminals can even display graphics, but only certain
+ software packages can take advantage of these advanced
+ features.</para>
+
+ <para>Dumb terminals are popular in work environments where workers do
+ not need access to graphical applications such as those provided by
+ the X Window System.</para>
+ </sect3>
+
+ <sect3 xml:id="term-pcs">
+ <title>PCs Acting as Terminals</title>
+
+ <para>If a <link linkend="term-dumb">dumb terminal</link> has just
+ enough ability to display, send, and receive text, then certainly
+ any spare personal computer can be a dumb terminal. All you need is
+ the proper cable and some <emphasis>terminal emulation</emphasis>
+ software to run on the computer.</para>
+
+ <para>Such a configuration is popular in homes. For example, if your
+ spouse is busy working on your FreeBSD system's console, you can do
+ some text-only work at the same time from a less powerful personal
+ computer hooked up as a terminal to the FreeBSD system.</para>
+ </sect3>
+
+ <sect3 xml:id="term-x">
+ <title>X Terminals</title>
+
+ <para>X terminals are the most sophisticated kind of terminal
+ available. Instead of connecting to a serial port, they usually
+ connect to a network like Ethernet. Instead of being relegated to
+ text-only applications, they can display any X application.</para>
+
+ <para>We introduce X terminals just for the sake of completeness.
+ However, this chapter does <emphasis>not</emphasis> cover setup,
+ configuration, or use of X terminals.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="term-config">
+ <title>Configuration</title>
+
+ <para>This section describes what you need to configure on your FreeBSD
+ system to enable a login session on a terminal. It assumes you have
+ already configured your kernel to support the serial port to which the
+ terminal is connected&mdash;and that you have connected it.</para>
+
+ <para>Recall from <xref linkend="boot"/> that the
+ <command>init</command> process is responsible for all process
+ control and initialization at system startup. One of the
+ tasks performed by <command>init</command> is to read the
+ <filename>/etc/ttys</filename> file and start a
+ <command>getty</command> process on the available terminals.
+ The <command>getty</command> process is responsible for
+ reading a login name and starting the <command>login</command>
+ program.</para>
+
+ <para>Thus, to configure terminals for your FreeBSD system the
+ following steps should be taken as <systemitem class="username">root</systemitem>:</para>
+
+ <procedure>
+ <step>
+ <para>Add a line to <filename>/etc/ttys</filename> for the entry in
+ the <filename>/dev</filename> directory for the serial port if it
+ is not already there.</para>
+ </step>
+
+ <step>
+ <para>Specify that <command>/usr/libexec/getty</command> be run on
+ the port, and specify the appropriate
+ <replaceable>getty</replaceable> type from the
+ <filename>/etc/gettytab</filename> file.</para>
+ </step>
+
+ <step>
+ <para>Specify the default terminal type.</para>
+ </step>
+
+ <step>
+ <para>Set the port to <quote>on.</quote></para>
+ </step>
+
+ <step>
+ <para>Specify whether the port should be
+ <quote>secure.</quote></para>
+ </step>
+
+ <step>
+ <para>Force <command>init</command> to reread the
+ <filename>/etc/ttys</filename> file.</para>
+ </step>
+ </procedure>
+
+ <para>As an optional step, you may wish to create a custom
+ <replaceable>getty</replaceable> type for use in step 2 by making an
+ entry in <filename>/etc/gettytab</filename>. This chapter does
+ not explain how to do so; you are encouraged to see the
+ &man.gettytab.5; and the &man.getty.8; manual pages for more
+ information.</para>
+
+ <sect3 xml:id="term-etcttys">
+ <title>Adding an Entry to <filename>/etc/ttys</filename></title>
+
+ <para>The <filename>/etc/ttys</filename> file lists all of the ports
+ on your FreeBSD system where you want to allow logins. For example,
+ the first virtual console <filename>ttyv0</filename> has an entry in
+ this file. You can log in on the console using this entry. This
+ file also contains entries for the other virtual consoles, serial ports,
+ and pseudo-ttys. For a hardwired terminal, just list the serial
+ port's <filename>/dev</filename> entry without the
+ <filename>/dev</filename> part (for example,
+ <filename>/dev/ttyv0</filename> would be listed as
+ <filename>ttyv0</filename>).</para>
+
+ <para>A default FreeBSD install includes an
+ <filename>/etc/ttys</filename> file with support for the first
+ four serial ports: <filename>ttyd0</filename> through
+ <filename>ttyd3</filename>. If you are attaching a terminal
+ to one of those ports, you do not need to add another entry.</para>
+
+ <example xml:id="ex-etc-ttys">
+ <title>Adding Terminal Entries to
+ <filename>/etc/ttys</filename></title>
+
+ <para>Suppose we would like to connect two terminals to the
+ system: a Wyse-50 and an old 286 IBM PC running
+ <application>Procomm</application> terminal software
+ emulating a VT-100 terminal. We connect the Wyse to the
+ second serial port and the 286 to the sixth serial port (a
+ port on a multiport serial card). The corresponding
+ entries in the <filename>/etc/ttys</filename> file would
+ look like this:</para>
+
+ <programlisting>ttyd1<co xml:id="co-ttys-line1col1"/> "/usr/libexec/getty std.38400"<co xml:id="co-ttys-line1col2"/> wy50<co xml:id="co-ttys-line1col3"/> on<co xml:id="co-ttys-line1col4"/> insecure<co xml:id="co-ttys-line1col5"/>
+ttyd5 "/usr/libexec/getty std.19200" vt100 on insecure
+ </programlisting>
+
+ <calloutlist>
+ <callout arearefs="co-ttys-line1col1">
+ <para>The first field normally specifies the name of
+ the terminal special file as it is found in
+ <filename>/dev</filename>.</para>
+ </callout>
+ <callout arearefs="co-ttys-line1col2">
+
+ <para>The second field is the command to execute for
+ this line, which is usually &man.getty.8;.
+ <command>getty</command> initializes and opens the
+ line, sets the speed, prompts for a user name and then
+ executes the &man.login.1; program.</para>
+
+ <para>The <command>getty</command> program accepts one
+ (optional) parameter on its command line, the
+ <replaceable>getty</replaceable> type. A
+ <replaceable>getty</replaceable> type configures
+ characteristics on the terminal line, like bps rate
+ and parity. The <command>getty</command> program reads
+ these characteristics from the file
+ <filename>/etc/gettytab</filename>.</para>
+
+ <para>The file <filename>/etc/gettytab</filename>
+ contains lots of entries for terminal lines both old
+ and new. In almost all cases, the entries that start
+ with the text <literal>std</literal> will work for
+ hardwired terminals. These entries ignore parity.
+ There is a <literal>std</literal> entry for each bps
+ rate from 110 to 115200. Of course, you can add your
+ own entries to this file. The &man.gettytab.5; manual
+ page provides more information.</para>
+
+ <para>When setting the <replaceable>getty</replaceable>
+ type in the <filename>/etc/ttys</filename> file, make
+ sure that the communications settings on the terminal
+ match.</para>
+
+ <para>For our example, the Wyse-50 uses no parity and
+ connects at 38400&nbsp;bps. The 286&nbsp;PC uses no parity and
+ connects at 19200&nbsp;bps.</para>
+
+ </callout>
+
+ <callout arearefs="co-ttys-line1col3">
+
+ <para>The third field is the type of terminal usually
+ connected to that tty line. For dial-up ports,
+ <literal>unknown</literal> or
+ <literal>dialup</literal> is typically used in this
+ field since users may dial up with practically any
+ type of terminal or software. For hardwired
+ terminals, the terminal type does not change, so you
+ can put a real terminal type from the &man.termcap.5;
+ database file in this field.</para>
+
+ <para>For our example, the Wyse-50 uses the real
+ terminal type while the 286 PC running
+ <application>Procomm</application> will be set to
+ emulate at VT-100. </para>
+
+ </callout>
+
+ <callout arearefs="co-ttys-line1col4">
+ <para>The fourth field specifies if the port should be
+ enabled. Putting <literal>on</literal> here will have
+ the <command>init</command> process start the program
+ in the second field, <command>getty</command>. If you
+ put <literal>off</literal> in this field, there will
+ be no <command>getty</command>, and hence no logins on
+ the port.</para>
+ </callout>
+
+ <callout arearefs="co-ttys-line1col5">
+ <para>The final field is used to specify whether the
+ port is secure. Marking a port as secure means that
+ you trust it enough to allow the
+ <systemitem class="username">root</systemitem> account (or any account with
+ a user ID of 0) to login from that port. Insecure
+ ports do not allow <systemitem class="username">root</systemitem> logins.
+ On an insecure port, users must login from
+ unprivileged accounts and then use &man.su.1; or a
+ similar mechanism to gain superuser privileges.</para>
+
+ <para>It is highly recommended that you use
+ <quote>insecure</quote>
+ even for terminals that are behind locked doors. It
+ is quite easy to login and use <command>su</command>
+ if you need superuser privileges.</para>
+ </callout>
+ </calloutlist>
+ </example>
+ </sect3>
+
+ <sect3 xml:id="term-hup">
+ <title>Force <command>init</command> to Reread
+ <filename>/etc/ttys</filename></title>
+
+ <para>After making the necessary changes to the
+ <filename>/etc/ttys</filename> file you should send a SIGHUP
+ (hangup) signal to the <command>init</command> process to
+ force it to re-read its configuration file. For example:</para>
+
+ <screen>&prompt.root; <userinput>kill -HUP 1</userinput></screen>
+
+ <note>
+ <para><command>init</command> is always the first process run
+ on a system, therefore it will always have PID 1.</para>
+ </note>
+
+ <para>If everything is set up correctly, all cables are in
+ place, and the terminals are powered up, then a
+ <command>getty</command> process should be running on each
+ terminal and you should see login prompts on your terminals
+ at this point.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="term-debug">
+ <title>Troubleshooting Your Connection</title>
+
+ <para>Even with the most meticulous attention to detail, something could
+ still go wrong while setting up a terminal. Here is a list of
+ symptoms and some suggested fixes.</para>
+
+ <sect3>
+ <title>No Login Prompt Appears</title>
+
+ <para>Make sure the terminal is plugged in and powered up. If it
+ is a personal computer acting as a terminal, make sure it is
+ running terminal emulation software on the correct serial
+ port.</para>
+
+ <para>Make sure the cable is connected firmly to both the terminal
+ and the FreeBSD computer. Make sure it is the right kind of
+ cable.</para>
+
+ <para>Make sure the terminal and FreeBSD agree on the bps rate and
+ parity settings. If you have a video display terminal, make
+ sure the contrast and brightness controls are turned up. If it
+ is a printing terminal, make sure paper and ink are in good
+ supply.</para>
+
+ <para>Make sure that a <command>getty</command> process is running
+ and serving the terminal. For example, to get a list of
+ running <command>getty</command> processes with
+ <command>ps</command>, type:</para>
+
+ <screen>&prompt.root; <userinput>ps -axww|grep getty</userinput></screen>
+
+ <para>You should see an entry for the terminal. For
+ example, the following display shows that a
+ <command>getty</command> is running on the second serial
+ port <literal>ttyd1</literal> and is using the
+ <literal>std.38400</literal> entry in
+ <filename>/etc/gettytab</filename>:</para>
+
+ <screen>22189 d1 Is+ 0:00.03 /usr/libexec/getty std.38400 ttyd1</screen>
+
+ <para>If no <command>getty</command> process is running, make sure
+ you have enabled the port in <filename>/etc/ttys</filename>.
+ Also remember to run <command>kill -HUP 1</command>
+ after modifying the <filename>ttys</filename> file.</para>
+
+ <para>If the <command>getty</command> process is running
+ but the terminal still does not display a login prompt,
+ or if it displays a prompt but will not allow you to
+ type, your terminal or cable may not support hardware
+ handshaking. Try changing the entry in
+ <filename>/etc/ttys</filename> from
+ <literal>std.38400</literal> to
+ <literal>3wire.38400</literal> remember to run
+ <command>kill -HUP 1</command> after modifying
+ <filename>/etc/ttys</filename>). The
+ <literal>3wire</literal> entry is similar to
+ <literal>std</literal>, but ignores hardware
+ handshaking. You may need to reduce the baud rate or
+ enable software flow control when using
+ <literal>3wire</literal> to prevent buffer
+ overflows.</para>
+
+ </sect3>
+
+ <sect3>
+ <title>If Garbage Appears Instead of a Login Prompt</title>
+
+ <para>Make sure the terminal and FreeBSD agree on the bps rate and
+ parity settings. Check the <command>getty</command> processes
+ to make sure the
+ correct <replaceable>getty</replaceable> type is in use. If
+ not, edit <filename>/etc/ttys</filename> and run <command>kill
+ -HUP 1</command>.</para>
+
+ </sect3>
+
+ <sect3>
+ <title>Characters Appear Doubled; the Password Appears When Typed</title>
+
+ <para>Switch the terminal (or the terminal emulation software)
+ from <quote>half duplex</quote> or <quote>local echo</quote> to
+ <quote>full duplex.</quote></para>
+
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="dialup">
+ <info><title>Dial-in Service</title>
+ <authorgroup>
+ <author><personname><firstname>Guy</firstname><surname>Helmer</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Sean</firstname><surname>Kelly</surname></personname><contrib>Additions by </contrib></author>
+ </authorgroup>
+ </info>
+
+ <indexterm><primary>dial-in service</primary></indexterm>
+
+ <para>Configuring your FreeBSD system for dial-in service is very
+ similar to connecting terminals except that you are dealing with
+ modems instead of terminals.</para>
+
+ <sect2>
+ <title>External vs. Internal Modems</title>
+
+ <para>External modems seem to be more convenient for dial-up, because
+ external modems often can be semi-permanently configured via
+ parameters stored in non-volatile RAM and they usually provide
+ lighted indicators that display the state of important RS-232
+ signals. Blinking lights impress visitors, but lights are also very
+ useful to see whether a modem is operating properly.</para>
+
+ <para>Internal modems usually lack non-volatile RAM, so their
+ configuration may be limited only to setting DIP switches. If your
+ internal modem has any signal indicator lights, it is probably
+ difficult to view the lights when the system's cover is in
+ place.</para>
+
+ <sect3>
+ <title>Modems and Cables</title>
+ <indexterm><primary>modem</primary></indexterm>
+
+ <para>If you are using an external modem, then you will of
+ course need the proper cable. A standard RS-232C serial
+ cable should suffice as long as all of the normal signals
+ are wired:</para>
+
+ <table frame="none" pgwide="1" xml:id="serialcomms-signal-names">
+ <title>Signal Names</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry align="left">Acronyms</entry>
+ <entry align="left">Names</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><acronym>RD</acronym></entry>
+ <entry>Received Data</entry>
+ </row>
+
+ <row>
+ <entry><acronym>TD</acronym></entry>
+ <entry>Transmitted Data</entry>
+ </row>
+
+ <row>
+ <entry><acronym>DTR</acronym></entry>
+ <entry>Data Terminal Ready</entry>
+ </row>
+
+ <row>
+ <entry><acronym>DSR</acronym></entry>
+ <entry>Data Set Ready</entry>
+ </row>
+
+ <row>
+ <entry><acronym>DCD</acronym></entry>
+ <entry>Data Carrier Detect (RS-232's Received Line
+ Signal Detector)</entry>
+ </row>
+
+ <row>
+ <entry><acronym>SG</acronym></entry>
+ <entry>Signal Ground</entry>
+ </row>
+
+ <row>
+ <entry><acronym>RTS</acronym></entry>
+ <entry>Request to Send</entry>
+ </row>
+
+ <row>
+ <entry><acronym>CTS</acronym></entry>
+ <entry>Clear to Send</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>FreeBSD needs the <acronym>RTS</acronym> and
+ <acronym>CTS</acronym> signals for flow control at speeds above
+ 2400&nbsp;bps, the <acronym>CD</acronym> signal to detect when a call has
+ been answered or the line has been hung up, and the
+ <acronym>DTR</acronym> signal to reset the modem after a session is
+ complete. Some cables are wired without all of the needed signals,
+ so if you have problems, such as a login session not going away when
+ the line hangs up, you may have a problem with your cable.</para>
+
+ <para>Like other &unix; like operating systems, FreeBSD uses the
+ hardware signals to find out when a call has been answered
+ or a line has been hung up and to hangup and reset the modem
+ after a call. FreeBSD avoids sending commands to the modem
+ or watching for status reports from the modem. If you are
+ familiar with connecting modems to PC-based bulletin board
+ systems, this may seem awkward.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Serial Interface Considerations</title>
+
+ <para>FreeBSD supports NS8250-, NS16450-, NS16550-, and NS16550A-based
+ EIA RS-232C (CCITT V.24) communications interfaces. The 8250 and
+ 16450 devices have single-character buffers. The 16550 device
+ provides a 16-character buffer, which allows for better system
+ performance. (Bugs in plain 16550's prevent the use of the
+ 16-character buffer, so use 16550A's if possible). Because
+ single-character-buffer devices require more work by the operating
+ system than the 16-character-buffer devices, 16550A-based serial
+ interface cards are much preferred. If the system has many active
+ serial ports or will have a heavy load, 16550A-based cards are
+ better for low-error-rate communications.</para>
+ </sect2>
+
+ <sect2>
+ <title>Quick Overview</title>
+
+ <indexterm><primary>getty</primary></indexterm>
+ <para>As with terminals, <command>init</command> spawns a
+ <command>getty</command> process for each configured serial
+ port for dial-in connections. For example, if a modem is
+ attached to <filename>/dev/ttyd0</filename>, the command
+ <command>ps ax</command> might show this:</para>
+
+ <screen> 4850 ?? I 0:00.09 /usr/libexec/getty V19200 ttyd0</screen>
+
+ <para>When a user dials the modem's line and the modems connect, the
+ <acronym>CD</acronym> (Carrier Detect) line is reported by the modem.
+ The kernel
+ notices that carrier has been detected and completes
+ <command>getty</command>'s open of the port. <command>getty</command>
+ sends a <prompt>login:</prompt> prompt at the specified initial line
+ speed. <command>getty</command> watches to see if legitimate
+ characters are received, and, in a typical configuration, if it finds
+ junk (probably due to the modem's connection speed being different
+ than <command>getty</command>'s speed), <command>getty</command> tries
+ adjusting the line speeds until it receives reasonable
+ characters.</para>
+
+ <indexterm>
+ <primary><command>/usr/bin/login</command></primary>
+ </indexterm>
+ <para>After the user enters his/her login name,
+ <command>getty</command> executes
+ <filename>/usr/bin/login</filename>, which completes the login
+ by asking for the user's password and then starting the user's
+ shell.</para>
+ </sect2>
+
+
+ <sect2>
+ <title>Configuration Files</title>
+
+ <para>There are three system configuration files in the
+ <filename>/etc</filename> directory that you will probably need to
+ edit to allow dial-up access to your FreeBSD system. The first,
+ <filename>/etc/gettytab</filename>, contains configuration information
+ for the <filename>/usr/libexec/getty</filename> daemon. Second,
+ <filename>/etc/ttys</filename> holds information that tells
+ <filename>/sbin/init</filename> what <filename>tty</filename> devices
+ should have <command>getty</command> processes running on them.
+ Lastly, you can place port initialization commands in the
+ <filename>/etc/rc.d/serial</filename> script.</para>
+
+ <para>There are two schools of thought regarding dial-up modems on &unix;.
+ One group likes to configure their modems and systems so that no matter
+ at what speed a remote user dials in, the local computer-to-modem
+ RS-232 interface runs at a locked speed. The benefit of this
+ configuration is that the remote user always sees a system login
+ prompt immediately. The downside is that the system does not know
+ what a user's true data rate is, so full-screen programs like Emacs
+ will not adjust their screen-painting methods to make their response
+ better for slower connections.</para>
+
+ <para>The other school configures their modems' RS-232 interface to vary
+ its speed based on the remote user's connection speed. For example,
+ V.32bis (14.4&nbsp;Kbps) connections to the modem might make the modem run
+ its RS-232 interface at 19.2&nbsp;Kbps, while 2400&nbsp;bps connections make the
+ modem's RS-232 interface run at 2400&nbsp;bps. Because
+ <command>getty</command> does not understand any particular modem's
+ connection speed reporting, <command>getty</command> gives a
+ <prompt>login:</prompt> message at an initial speed and watches the
+ characters that come back in response. If the user sees junk, it is
+ assumed that they know they should press the
+ <keycode>Enter</keycode> key until they see a recognizable
+ prompt. If the data rates do not match, <command>getty</command> sees
+ anything the user types as <quote>junk</quote>, tries going to the next
+ speed and gives the <prompt>login:</prompt> prompt again. This
+ procedure can continue ad nauseam, but normally only takes a keystroke
+ or two before the user sees a good prompt. Obviously, this login
+ sequence does not look as clean as the former
+ <quote>locked-speed</quote> method, but a user on a low-speed
+ connection should receive better interactive response from full-screen
+ programs.</para>
+
+ <para>This section will try to give balanced configuration information,
+ but is biased towards having the modem's data rate follow the
+ connection rate.</para>
+
+ <sect3>
+ <title><filename>/etc/gettytab</filename></title>
+
+ <indexterm>
+ <primary><filename>/etc/gettytab</filename></primary>
+ </indexterm>
+ <para><filename>/etc/gettytab</filename> is a &man.termcap.5;-style
+ file of configuration information for &man.getty.8;. Please see the
+ &man.gettytab.5; manual page for complete information on the
+ format of the file and the list of capabilities.</para>
+
+ <sect4>
+ <title>Locked-speed Config</title>
+
+ <para>If you are locking your modem's data communications rate at a
+ particular speed, you probably will not need to make any changes
+ to <filename>/etc/gettytab</filename>.</para>
+ </sect4>
+
+ <sect4>
+ <title>Matching-speed Config</title>
+
+ <para>You will need to set up an entry in
+ <filename>/etc/gettytab</filename> to give
+ <command>getty</command> information about the speeds you wish to
+ use for your modem. If you have a 2400&nbsp;bps modem, you can
+ probably use the existing <literal>D2400</literal> entry.</para>
+
+ <programlisting>#
+# Fast dialup terminals, 2400/1200/300 rotary (can start either way)
+#
+D2400|d2400|Fast-Dial-2400:\
+ :nx=D1200:tc=2400-baud:
+3|D1200|Fast-Dial-1200:\
+ :nx=D300:tc=1200-baud:
+5|D300|Fast-Dial-300:\
+ :nx=D2400:tc=300-baud:</programlisting>
+
+ <para>If you have a higher speed modem, you will probably need to
+ add an entry in <filename>/etc/gettytab</filename>; here is an
+ entry you could use for a 14.4&nbsp;Kbps modem with a top interface
+ speed of 19.2&nbsp;Kbps:</para>
+
+ <programlisting>#
+# Additions for a V.32bis Modem
+#
+um|V300|High Speed Modem at 300,8-bit:\
+ :nx=V19200:tc=std.300:
+un|V1200|High Speed Modem at 1200,8-bit:\
+ :nx=V300:tc=std.1200:
+uo|V2400|High Speed Modem at 2400,8-bit:\
+ :nx=V1200:tc=std.2400:
+up|V9600|High Speed Modem at 9600,8-bit:\
+ :nx=V2400:tc=std.9600:
+uq|V19200|High Speed Modem at 19200,8-bit:\
+ :nx=V9600:tc=std.19200:</programlisting>
+
+ <para>This will result in 8-bit, no parity connections.</para>
+
+ <para>The example above starts the communications rate at 19.2&nbsp;Kbps
+ (for a V.32bis connection), then cycles through 9600&nbsp;bps (for
+ V.32), 2400&nbsp;bps, 1200&nbsp;bps, 300&nbsp;bps, and back to 19.2&nbsp;Kbps.
+ Communications rate cycling is implemented with the
+ <literal>nx=</literal> (<quote>next table</quote>) capability.
+ Each of the lines uses a <literal>tc=</literal> (<quote>table
+ continuation</quote>) entry to pick up the rest of the
+ <quote>standard</quote> settings for a particular data rate.</para>
+
+ <para>If you have a 28.8&nbsp;Kbps modem and/or you want to take
+ advantage of compression on a 14.4&nbsp;Kbps modem, you need to use a
+ higher communications rate than 19.2&nbsp;Kbps. Here is an example of
+ a <filename>gettytab</filename> entry starting a 57.6&nbsp;Kbps:</para>
+
+ <programlisting>#
+# Additions for a V.32bis or V.34 Modem
+# Starting at 57.6 Kbps
+#
+vm|VH300|Very High Speed Modem at 300,8-bit:\
+ :nx=VH57600:tc=std.300:
+vn|VH1200|Very High Speed Modem at 1200,8-bit:\
+ :nx=VH300:tc=std.1200:
+vo|VH2400|Very High Speed Modem at 2400,8-bit:\
+ :nx=VH1200:tc=std.2400:
+vp|VH9600|Very High Speed Modem at 9600,8-bit:\
+ :nx=VH2400:tc=std.9600:
+vq|VH57600|Very High Speed Modem at 57600,8-bit:\
+ :nx=VH9600:tc=std.57600:</programlisting>
+
+ <para>If you have a slow CPU or a heavily loaded system and do
+ not have 16550A-based serial ports, you may receive
+ <errorname>sio</errorname>
+ <quote>silo</quote> errors at 57.6&nbsp;Kbps.</para>
+ </sect4>
+ </sect3>
+
+ <sect3 xml:id="dialup-ttys">
+ <title><filename>/etc/ttys</filename></title>
+ <indexterm>
+ <primary><filename>/etc/ttys</filename></primary>
+ </indexterm>
+
+ <para>Configuration of the <filename>/etc/ttys</filename> file
+ was covered in <xref linkend="ex-etc-ttys"/>.
+ Configuration for modems is similar but we must pass a
+ different argument to <command>getty</command> and specify a
+ different terminal type. The general format for both
+ locked-speed and matching-speed configurations is:</para>
+
+ <programlisting>ttyd0 "/usr/libexec/getty <replaceable>xxx</replaceable>" dialup on</programlisting>
+
+ <para>The first item in the above line is the device special file for
+ this entry &mdash; <literal>ttyd0</literal> means
+ <filename>/dev/ttyd0</filename> is the file that this
+ <command>getty</command> will be watching. The second item,
+ <literal>"/usr/libexec/getty
+ xxx"</literal>
+ (<replaceable>xxx</replaceable> will be replaced by the initial
+ <filename>gettytab</filename> capability) is the process
+ <command>init</command> will run on the device. The third item,
+ <literal>dialup</literal>, is the default terminal type. The fourth
+ parameter, <literal>on</literal>, indicates to
+ <command>init</command> that the line is operational. There can be
+ a fifth parameter, <literal>secure</literal>, but it should only be
+ used for terminals which are physically secure (such as the system
+ console).</para>
+
+ <para>The default terminal type (<literal>dialup</literal> in the
+ example above) may depend on local preferences.
+ <literal>dialup</literal> is the traditional default terminal type
+ on dial-up lines so that users may customize their login scripts to
+ notice when the terminal is <literal>dialup</literal> and
+ automatically adjust their terminal type. However, the author finds
+ it easier at his site to specify <literal>vt102</literal> as the
+ default terminal type, since the users just use VT102 emulation on
+ their remote systems.</para>
+
+ <para>After you have made changes to <filename>/etc/ttys</filename>,
+ you may send the <command>init</command> process a
+ <acronym>HUP</acronym> signal to re-read the file. You can use the
+ command
+
+ <screen>&prompt.root; <userinput>kill -HUP 1</userinput></screen>
+
+ to send the signal. If this is your first time setting up the
+ system, you may want to wait until your modem(s) are properly
+ configured and connected before signaling <command>init</command>.
+ </para>
+
+ <sect4>
+ <title>Locked-speed Config</title>
+
+ <para>For a locked-speed configuration, your
+ <filename>ttys</filename> entry needs to have a fixed-speed entry
+ provided to <command>getty</command>. For a modem whose port
+ speed is locked at 19.2&nbsp;Kbps, the <filename>ttys</filename> entry
+ might look like this:</para>
+
+ <programlisting>ttyd0 "/usr/libexec/getty std.19200" dialup on</programlisting>
+
+ <para>If your modem is locked at a different data rate,
+ substitute the appropriate value for
+ <literal>std.speed</literal>
+ instead of <literal>std.19200</literal>. Make sure that
+ you use a valid type listed in
+ <filename>/etc/gettytab</filename>.</para>
+ </sect4>
+
+ <sect4>
+ <title>Matching-speed Config</title>
+
+ <para>In a matching-speed configuration, your
+ <filename>ttys</filename> entry needs to reference the appropriate
+ beginning <quote>auto-baud</quote> (sic) entry in
+ <filename>/etc/gettytab</filename>. For example, if you added the
+ above suggested entry for a matching-speed modem that starts at
+ 19.2&nbsp;Kbps (the <filename>gettytab</filename> entry containing the
+ <literal>V19200</literal> starting point), your
+ <filename>ttys</filename> entry might look like this:</para>
+
+ <programlisting>ttyd0 "/usr/libexec/getty V19200" dialup on</programlisting>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title><filename>/etc/rc.d/serial</filename></title>
+ <indexterm>
+ <primary>rc files</primary>
+ <secondary><filename>rc.serial</filename></secondary>
+ </indexterm>
+
+ <para>High-speed modems, like V.32, V.32bis, and V.34 modems,
+ need to use hardware (<literal>RTS/CTS</literal>) flow
+ control. You can add <command>stty</command> commands to
+ <filename>/etc/rc.d/serial</filename> to set the hardware flow
+ control flag in the FreeBSD kernel for the modem
+ ports.</para>
+
+ <para>For example to set the <literal>termios</literal> flag
+ <varname>crtscts</varname> on serial port #1's
+ (<filename>COM2</filename>) dial-in and dial-out initialization
+ devices, the following lines could be added to
+ <filename>/etc/rc.d/serial</filename>:</para>
+ <programlisting># Serial port initial configuration
+stty -f /dev/ttyd1.init crtscts
+stty -f /dev/cuad1.init crtscts</programlisting>
+
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Modem Settings</title>
+
+ <para>If you have a modem whose parameters may be permanently set in
+ non-volatile RAM, you will need to use a terminal program (such as
+ Telix under &ms-dos; or <command>tip</command> under FreeBSD) to set the
+ parameters. Connect to the modem using the same communications speed
+ as the initial speed <command>getty</command> will use and configure
+ the modem's non-volatile RAM to match these requirements:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><acronym>CD</acronym> asserted when connected</para>
+ </listitem>
+
+ <listitem>
+ <para><acronym>DTR</acronym> asserted for operation; dropping DTR
+ hangs up line and resets modem</para>
+ </listitem>
+
+ <listitem>
+ <para><acronym>CTS</acronym> transmitted data flow control</para>
+ </listitem>
+
+ <listitem>
+ <para>Disable <acronym>XON/XOFF</acronym> flow control</para>
+ </listitem>
+
+ <listitem>
+ <para><acronym>RTS</acronym> received data flow control</para>
+ </listitem>
+
+ <listitem>
+ <para>Quiet mode (no result codes)</para>
+ </listitem>
+
+ <listitem>
+ <para>No command echo</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Please read the documentation for your modem to find out what
+ commands and/or DIP switch settings you need to give it.</para>
+
+ <para>For example, to set the above parameters on a &usrobotics;
+ &sportster; 14,400 external modem, one could give these commands to
+ the modem:</para>
+
+ <programlisting>ATZ
+AT&amp;C1&amp;D2&amp;H1&amp;I0&amp;R2&amp;W</programlisting>
+
+ <para>You might also want to take this opportunity to adjust other
+ settings in the modem, such as whether it will use V.42bis and/or MNP5
+ compression.</para>
+
+ <para>The &usrobotics; &sportster; 14,400 external modem also has some DIP switches
+ that need to be set; for other modems, perhaps you can use these
+ settings as an example:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Switch 1: UP &mdash; DTR Normal</para>
+ </listitem>
+
+ <listitem>
+ <para>Switch 2: N/A (Verbal Result Codes/Numeric Result
+ Codes)</para>
+ </listitem>
+
+ <listitem>
+ <para>Switch 3: UP &mdash; Suppress Result Codes</para>
+ </listitem>
+
+ <listitem>
+ <para>Switch 4: DOWN &mdash; No echo, offline commands</para>
+ </listitem>
+
+ <listitem>
+ <para>Switch 5: UP &mdash; Auto Answer</para>
+ </listitem>
+
+ <listitem>
+ <para>Switch 6: UP &mdash; Carrier Detect Normal</para>
+ </listitem>
+
+ <listitem>
+ <para>Switch 7: UP &mdash; Load NVRAM Defaults</para>
+ </listitem>
+
+ <listitem>
+ <para>Switch 8: N/A (Smart Mode/Dumb Mode)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Result codes should be disabled/suppressed for dial-up modems to
+ avoid problems that can occur if <command>getty</command> mistakenly
+ gives a <prompt>login:</prompt> prompt to a modem that is in command
+ mode and the modem echoes the command or returns a result
+ code. This sequence can result in a extended, silly conversation
+ between <command>getty</command> and the modem.</para>
+
+ <sect3>
+ <title>Locked-speed Config</title>
+
+ <para>For a locked-speed configuration, you will need to configure the
+ modem to maintain a constant modem-to-computer data rate independent
+ of the communications rate. On a &usrobotics; &sportster; 14,400 external
+ modem, these commands will lock the modem-to-computer data rate at
+ the speed used to issue the commands:</para>
+
+ <programlisting>ATZ
+AT&amp;B1&amp;W</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Matching-speed Config</title>
+
+ <para>For a variable-speed configuration, you will need to configure
+ your modem to adjust its serial port data rate to match the incoming
+ call rate. On a &usrobotics; &sportster; 14,400 external modem, these commands
+ will lock the modem's error-corrected data rate to the speed used to
+ issue the commands, but allow the serial port rate to vary for
+ non-error-corrected connections:</para>
+
+ <programlisting>ATZ
+AT&amp;B2&amp;W</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Checking the Modem's Configuration</title>
+
+ <para>Most high-speed modems provide commands to view the modem's
+ current operating parameters in a somewhat human-readable fashion.
+ On the &usrobotics; &sportster; 14,400 external modems, the command
+ <command>ATI5</command> displays the settings that are stored in the
+ non-volatile RAM. To see the true operating parameters of the modem
+ (as influenced by the modem's DIP switch settings), use the commands
+ <command>ATZ</command> and then <command>ATI4</command>.</para>
+
+ <para>If you have a different brand of modem, check your modem's
+ manual to see how to double-check your modem's configuration
+ parameters.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Troubleshooting</title>
+
+ <para>Here are a few steps you can follow to check out the dial-up modem
+ on your system.</para>
+
+ <sect3>
+ <title>Checking Out the FreeBSD System</title>
+
+ <para>Hook up your modem to your FreeBSD system, boot the system, and,
+ if your modem has status indication lights, watch to see whether the
+ modem's <acronym>DTR</acronym> indicator lights when the
+ <prompt>login:</prompt> prompt appears on the system's console
+ &mdash; if it lights up, that should mean that FreeBSD has started a
+ <command>getty</command> process on the appropriate communications
+ port and is waiting for the modem to accept a call.</para>
+
+ <para>If the <acronym>DTR</acronym> indicator does not light, login to
+ the FreeBSD system through the console and issue a <command>ps
+ ax</command> to see if FreeBSD is trying to run a
+ <command>getty</command> process on the correct port. You should see
+ lines like these among the processes displayed:</para>
+
+ <screen> 114 ?? I 0:00.10 /usr/libexec/getty V19200 ttyd0
+ 115 ?? I 0:00.10 /usr/libexec/getty V19200 ttyd1</screen>
+
+ <para>If you see something different, like this:</para>
+
+ <screen> 114 d0 I 0:00.10 /usr/libexec/getty V19200 ttyd0</screen>
+
+ <para>and the modem has not accepted a call yet, this means that
+ <command>getty</command> has completed its open on the
+ communications port. This could indicate a problem with the cabling
+ or a mis-configured modem, because <command>getty</command> should
+ not be able to open the communications port until
+ <acronym>CD</acronym> (carrier detect) has been asserted by the
+ modem.</para>
+
+ <para>If you do not see any <command>getty</command> processes waiting
+ to open the desired
+ <filename>ttydN</filename> port,
+ double-check your entries in <filename>/etc/ttys</filename> to see
+ if there are any mistakes there. Also, check the log file
+ <filename>/var/log/messages</filename> to see if there are any log
+ messages from <command>init</command> or <command>getty</command>
+ regarding any problems. If there are any messages, triple-check the
+ configuration files <filename>/etc/ttys</filename> and
+ <filename>/etc/gettytab</filename>, as well as the appropriate
+ device special files <filename>/dev/ttydN</filename>, for any
+ mistakes, missing entries, or missing device special files.</para>
+ </sect3>
+
+ <sect3>
+ <title>Try Dialing In</title>
+
+ <para>Try dialing into the system; be sure to use 8 bits, no parity,
+ and 1
+ stop bit on the remote system. If you do not get a prompt right
+ away, or get garbage, try pressing <keycode>Enter</keycode>
+ about once per second. If you still do not see a
+ <prompt>login:</prompt> prompt after a while, try sending a
+ <command>BREAK</command>. If you are using a high-speed modem to do
+ the dialing, try dialing again after locking the dialing modem's
+ interface speed (via <command>AT&amp;B1</command> on a &usrobotics;
+ &sportster; modem, for example).</para>
+
+ <para>If you still cannot get a <prompt>login:</prompt> prompt, check
+ <filename>/etc/gettytab</filename> again and double-check
+ that</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The initial capability name specified in
+ <filename>/etc/ttys</filename> for the line matches a name of a
+ capability in <filename>/etc/gettytab</filename></para>
+ </listitem>
+
+ <listitem>
+ <para>Each <literal>nx=</literal> entry matches another
+ <filename>gettytab</filename> capability name</para>
+ </listitem>
+
+ <listitem>
+ <para>Each <literal>tc=</literal> entry matches another
+ <filename>gettytab</filename> capability name</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>If you dial but the modem on the FreeBSD system will not answer,
+ make sure that the modem is configured to answer the phone when
+ <acronym>DTR</acronym> is asserted. If the modem seems to be
+ configured correctly, verify that the <acronym>DTR</acronym> line is
+ asserted by checking the modem's indicator lights (if it has
+ any).</para>
+
+ <para>If you have gone over everything several times and it still does
+ not work, take a break and come back to it later. If it still does
+ not work, perhaps you can send an electronic mail message to the
+ &a.questions; describing your modem and your problem, and the good
+ folks on the list will try to help.</para>
+ </sect3>
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="dialout">
+ <title>Dial-out Service</title>
+ <indexterm><primary>dial-out service</primary></indexterm>
+
+ <para>The following are tips for getting your host to be able to connect
+ over the modem to another computer. This is appropriate for
+ establishing a terminal session with a remote host.</para>
+
+ <para>This is useful to log onto a BBS.</para>
+
+ <para>This kind of connection can be extremely helpful to get a file on
+ the Internet if you have problems with PPP. If you need to FTP
+ something and PPP is broken, use the terminal session to FTP it. Then
+ use zmodem to transfer it to your machine.</para>
+
+ <sect2>
+ <title>My Stock Hayes Modem Is Not Supported, What Can I Do?</title>
+
+ <para>Actually, the manual page for <command>tip</command> is out of date.
+ There is a generic Hayes dialer already built in. Just use
+ <literal>at=hayes</literal> in your <filename>/etc/remote</filename>
+ file.</para>
+
+ <para>The Hayes driver is not smart enough to recognize some of the
+ advanced features of newer modems&mdash;messages like
+ <literal>BUSY</literal>, <literal>NO DIALTONE</literal>, or
+ <literal>CONNECT 115200</literal> will just confuse it. You should
+ turn those messages off when you use <command>tip</command> (using
+ <command>ATX0&amp;W</command>).</para>
+
+ <para>Also, the dial timeout for <command>tip</command> is 60 seconds.
+ Your modem should use something less, or else tip will think there is
+ a communication problem. Try <command>ATS7=45&amp;W</command>.</para>
+
+ <note>
+ <para>As shipped, <command>tip</command> does not yet support
+ Hayes modems fully. The solution is to edit the file
+ <filename>tipconf.h</filename> in the directory
+ <filename>/usr/src/usr.bin/tip/tip</filename>. Obviously you need the
+ source distribution to do this.</para>
+
+ <para>Edit the line <literal>#define HAYES 0</literal> to
+ <literal>#define HAYES 1</literal>. Then <command>make</command> and
+ <command>make install</command>. Everything works nicely after
+ that.</para>
+ </note>
+ </sect2>
+
+ <sect2 xml:id="direct-at">
+ <title>How Am I Expected to Enter These AT Commands?</title>
+
+ <indexterm>
+ <primary><filename>/etc/remote</filename></primary>
+ </indexterm>
+ <para>Make what is called a <quote>direct</quote> entry in your
+ <filename>/etc/remote</filename> file. For example, if your modem is
+ hooked up to the first serial port, <filename>/dev/cuad0</filename>,
+ then put in the following line:</para>
+
+ <programlisting>cuad0:dv=/dev/cuad0:br#19200:pa=none</programlisting>
+
+ <para>Use the highest bps rate your modem supports in the br capability.
+ Then, type <command>tip cuad0</command> and you will be connected to
+ your modem.</para>
+
+ <para>Or use <command>cu</command> as <systemitem class="username">root</systemitem> with the
+ following command:</para>
+
+ <screen>&prompt.root; <userinput>cu -lline -sspeed</userinput></screen>
+
+ <para><replaceable>line</replaceable> is the serial port
+ (e.g.<filename>/dev/cuad0</filename>) and
+ <replaceable>speed</replaceable> is the speed
+ (e.g.<literal>57600</literal>). When you are done entering the AT
+ commands hit <keycap>~.</keycap> to exit.</para>
+ </sect2>
+
+ <sect2>
+ <title>The <literal>@</literal> Sign for the pn Capability Does Not
+ Work!</title>
+
+ <para>The <literal>@</literal> sign in the phone number capability tells
+ tip to look in <filename>/etc/phones</filename> for a phone number.
+ But the <literal>@</literal> sign is also a special character in
+ capability files like <filename>/etc/remote</filename>. Escape it
+ with a backslash:</para>
+
+ <programlisting>pn=\@</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>How Can I Dial a Phone Number on the Command Line?</title>
+
+ <para>Put what is called a <quote>generic</quote> entry in your
+ <filename>/etc/remote</filename> file. For example:</para>
+
+ <programlisting>tip115200|Dial any phone number at 115200 bps:\
+ :dv=/dev/cuad0:br#115200:at=hayes:pa=none:du:
+tip57600|Dial any phone number at 57600 bps:\
+ :dv=/dev/cuad0:br#57600:at=hayes:pa=none:du:</programlisting>
+
+ <para>Then you can do things like:</para>
+
+ <screen>&prompt.root; <userinput>tip -115200 5551234</userinput></screen>
+
+ <para>If you prefer <command>cu</command> over <command>tip</command>,
+ use a generic <literal>cu</literal> entry:</para>
+
+ <programlisting>cu115200|Use cu to dial any number at 115200bps:\
+ :dv=/dev/cuad1:br#57600:at=hayes:pa=none:du:</programlisting>
+
+ <para>and type:</para>
+
+ <screen>&prompt.root; <userinput>cu 5551234 -s 115200</userinput></screen>
+ </sect2>
+
+ <sect2>
+ <title>Do I Have to Type in the bps Rate Every Time I Do That?</title>
+
+ <para>Put in an entry for <literal>tip1200</literal> or
+ <literal>cu1200</literal>, but go ahead and use whatever bps rate is
+ appropriate with the br capability. <command>tip</command> thinks a
+ good default is 1200&nbsp;bps which is why it looks for a
+ <literal>tip1200</literal> entry. You do not have to use 1200&nbsp;bps,
+ though.</para>
+ </sect2>
+
+ <sect2>
+ <title>I Access a Number of Hosts Through a Terminal Server</title>
+
+ <para>Rather than waiting until you are connected and typing
+ <command>CONNECT &lt;host&gt;</command> each time, use tip's
+ <literal>cm</literal> capability. For example, these entries in
+ <filename>/etc/remote</filename>:</para>
+
+ <programlisting>pain|pain.deep13.com|Forrester's machine:\
+ :cm=CONNECT pain\n:tc=deep13:
+muffin|muffin.deep13.com|Frank's machine:\
+ :cm=CONNECT muffin\n:tc=deep13:
+deep13:Gizmonics Institute terminal server:\
+ :dv=/dev/cuad2:br#38400:at=hayes:du:pa=none:pn=5551234:</programlisting>
+
+ <para>will let you type <command>tip pain</command> or <command>tip
+ muffin</command> to connect to the hosts pain or muffin, and
+ <command>tip deep13</command> to get to the terminal server.</para>
+ </sect2>
+
+ <sect2>
+ <title>Can Tip Try More Than One Line for Each Site?</title>
+
+ <para>This is often a problem where a university has several modem lines
+ and several thousand students trying to use them.</para>
+
+ <para>Make an entry for your university in
+ <filename>/etc/remote</filename> and use <literal>@</literal> for the
+ <literal>pn</literal> capability:</para>
+
+ <programlisting>big-university:\
+ :pn=\@:tc=dialout
+dialout:\
+ :dv=/dev/cuad3:br#9600:at=courier:du:pa=none:</programlisting>
+
+ <para>Then, list the phone numbers for the university in
+ <filename>/etc/phones</filename>:</para>
+
+ <programlisting>big-university 5551111
+big-university 5551112
+big-university 5551113
+big-university 5551114</programlisting>
+
+ <para><command>tip</command> will try each one in the listed order, then
+ give up. If you want to keep retrying, run <command>tip</command> in
+ a while loop.</para>
+ </sect2>
+
+ <sect2>
+ <title>Why Do I Have to Hit
+ <keycombo action="simul">
+ <keycap>Ctrl</keycap>
+ <keycap>P</keycap>
+ </keycombo>
+ Twice to Send
+ <keycombo action="simul">
+ <keycap>Ctrl</keycap>
+ <keycap>P</keycap>
+ </keycombo>
+ Once?</title>
+
+ <para><keycombo action="simul"><keycap>Ctrl</keycap><keycap>P</keycap></keycombo> is the default <quote>force</quote> character, used to tell
+ <command>tip</command> that the next character is literal data. You
+ can set the force character to any other character with the
+ <command>~s</command> escape, which means <quote>set a
+ variable.</quote></para>
+
+ <para>Type
+ <command>~sforce=single-char</command>
+ followed by a newline. <replaceable>single-char</replaceable> is any
+ single character. If you leave out
+ <replaceable>single-char</replaceable>, then the force character is
+ the nul character, which you can get by typing
+ <keycombo action="simul">
+ <keycap>Ctrl</keycap><keycap>2</keycap>
+ </keycombo>
+ or
+ <keycombo action="simul">
+ <keycap>Ctrl</keycap><keycap>Space</keycap>
+ </keycombo>.
+ A pretty good value for <replaceable>single-char</replaceable> is
+ <keycombo action="simul">
+ <keycap>Shift</keycap>
+ <keycap>Ctrl</keycap>
+ <keycap>6</keycap>
+ </keycombo>, which is only used on some terminal
+ servers.</para>
+
+ <para>You can have the force character be whatever you want by
+ specifying the following in your <filename>&#36;HOME/.tiprc</filename>
+ file:</para>
+
+ <programlisting>force=&lt;single-char&gt;</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Suddenly Everything I Type Is in Upper Case??</title>
+
+ <para>You must have pressed
+ <keycombo action="simul">
+ <keycap>Ctrl</keycap>
+ <keycap>A</keycap>
+ </keycombo>, <command>tip</command>'s
+ <quote>raise character,</quote> specially designed for people with
+ broken caps-lock keys. Use <command>~s</command> as above and set the
+ variable <literal>raisechar</literal> to something reasonable. In
+ fact, you can set it to the same as the force character, if you never
+ expect to use either of these features.</para>
+
+ <para>Here is a sample .tiprc file perfect for
+ <application>Emacs</application> users who need to type
+ <keycombo action="simul">
+ <keycap>Ctrl</keycap><keycap>2</keycap>
+ </keycombo>
+ and
+ <keycombo action="simul">
+ <keycap>Ctrl</keycap><keycap>A</keycap>
+ </keycombo>
+ a lot:</para>
+
+ <programlisting>force=^^
+raisechar=^^</programlisting>
+
+ <para>The ^^ is
+ <keycombo action="simul">
+ <keycap>Shift</keycap><keycap>Ctrl</keycap><keycap>6</keycap>
+ </keycombo>.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>How Can I Do File Transfers with <command>tip</command>?</title>
+
+ <para>If you are talking to another &unix; system, you can send and
+ receive files with <command>~p</command> (put) and
+ <command>~t</command> (take). These commands run
+ <command>cat</command> and <command>echo</command> on the remote
+ system to accept and send files. The syntax is:</para>
+
+ <cmdsynopsis>
+ <command>~p</command>
+ <arg choice="plain">local-file</arg>
+ <arg choice="opt">remote-file</arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>~t</command>
+ <arg choice="plain">remote-file</arg>
+ <arg choice="opt">local-file</arg>
+ </cmdsynopsis>
+
+ <para>There is no error checking, so you probably should use another
+ protocol, like zmodem.</para>
+ </sect2>
+
+ <sect2>
+ <title>How Can I Run zmodem with <command>tip</command>?</title>
+
+ <para>To receive files, start the sending program on the remote end.
+ Then, type <command>~C rz</command> to begin receiving them
+ locally.</para>
+
+ <para>To send files, start the receiving program on the remote end.
+ Then, type <command>~C sz files</command>
+ to send them to the remote system.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="serialconsole-setup">
+ <info><title>Setting Up the Serial Console</title>
+ <authorgroup>
+ <author><personname><firstname>Kazutaka</firstname><surname>YOKOTA</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ <authorgroup>
+ <author><personname><firstname>Bill</firstname><surname>Paul</surname></personname><contrib>Based on a document by </contrib></author>
+ </authorgroup>
+ </info>
+
+ <indexterm><primary>serial console</primary></indexterm>
+
+ <sect2 xml:id="serialconsole-intro">
+ <title>Introduction</title>
+
+ <para>FreeBSD has the ability to boot on a system with only
+ a dumb terminal on a serial port as a console. Such a configuration
+ should be useful for two classes of people: system administrators who
+ wish to install FreeBSD on machines that have no keyboard or monitor
+ attached, and developers who want to debug the kernel or device
+ drivers.</para>
+
+ <para>As described in <xref linkend="boot"/>, FreeBSD employs a three stage
+ bootstrap. The first two stages are in the boot block code which is
+ stored at the beginning of the FreeBSD slice on the boot disk. The
+ boot block will then load and run the boot loader
+ (<filename>/boot/loader</filename>) as the third stage code.</para>
+
+ <para>In order to set up the serial console you must configure the boot
+ block code, the boot loader code and the kernel.</para>
+
+ </sect2>
+
+ <sect2 xml:id="serialconsole-howto-fast">
+ <title>Serial Console Configuration, Terse Version</title>
+
+ <para>This section assumes that you are using the default setup
+ and just want a fast overview of setting up the serial
+ console.</para>
+
+ <procedure>
+
+ <step>
+ <para>Connect the serial cable to COM1 and the controlling
+ terminal.</para>
+ </step>
+
+ <step>
+ <para>To see all boot messages on the serial console, issue
+ the following command while logged in as the superuser:</para>
+ <screen>&prompt.root; echo 'console="comconsole"' &gt;&gt; /boot/loader.conf</screen>
+ </step>
+
+ <step>
+ <para>Edit <filename>/etc/ttys</filename> and change
+ <literal>off</literal> to <literal>on</literal> and
+ <literal>dialup</literal> to <literal>vt100</literal> for the
+ <literal>ttyd0</literal> entry. Otherwise a password will not be
+ required to connect via the serial console, resulting in a
+ potential security hole.</para>
+ </step>
+
+ <step>
+ <para>Reboot the system to see if the changes took effect.</para>
+ </step>
+
+ </procedure>
+
+ <para>If a different configuration is required, a more in depth
+ configuration explanation exists in
+ <xref linkend="serialconsole-howto"/>.</para>
+ </sect2>
+
+ <sect2 xml:id="serialconsole-howto">
+ <title>Serial Console Configuration</title>
+
+ <procedure>
+ <step>
+ <para>Prepare a serial cable.</para>
+
+ <indexterm><primary>null-modem cable</primary></indexterm>
+ <para>You will need either a null-modem cable or a standard serial
+ cable and a null-modem adapter. See <xref linkend="serial-cables-ports"/> for
+ a discussion on serial cables.</para>
+ </step>
+
+ <step>
+ <para>Unplug your keyboard.</para>
+
+ <para>Most PC systems probe for the keyboard during the Power-On
+ Self-Test (POST) and will generate an error if the keyboard is not
+ detected. Some machines complain loudly about the lack of a
+ keyboard and will not continue to boot until it is plugged
+ in.</para>
+
+ <para>If your computer complains about the error, but boots anyway,
+ then you do not have to do anything special. (Some machines with
+ Phoenix BIOS installed merely say <errorname>Keyboard
+ failed</errorname> and continue to boot normally.)</para>
+
+ <para>If your computer refuses to boot without a keyboard attached
+ then you will have to configure the BIOS so that it ignores this
+ error (if it can). Consult your motherboard's manual for details
+ on how to do this.</para>
+
+ <tip>
+ <para>Set the keyboard to <quote>Not installed</quote> in the
+ BIOS setup. You will still
+ be able to use your keyboard. All this does is tell the BIOS
+ not to probe for a keyboard at power-on. Your BIOS should not
+ complain if the keyboard is absent. You can leave the
+ keyboard plugged in even with this flag set to <quote>Not
+ installed</quote> and the keyboard will still work.</para>
+ </tip>
+
+ <note>
+ <para>If your system has a &ps2; mouse, chances are very good that
+ you may have to unplug your mouse as well as your keyboard.
+ This is because &ps2; mice share some hardware with the keyboard
+ and leaving the mouse plugged in can fool the keyboard probe
+ into thinking the keyboard is still there. It is said that a
+ Gateway 2000 Pentium 90&nbsp;MHz system with an AMI BIOS that behaves
+ this way. In general, this is not a problem since the mouse is
+ not much good without the keyboard anyway.</para>
+ </note>
+ </step>
+
+ <step>
+ <para>Plug a dumb terminal into <filename>COM1</filename>
+ (<filename>sio0</filename>).</para>
+
+ <para>If you do not have a dumb terminal, you can use an old PC/XT
+ with a modem program, or the serial port on another &unix; box. If
+ you do not have a <filename>COM1</filename>
+ (<filename>sio0</filename>), get one. At this time, there is
+ no way to select a port other than <filename>COM1</filename>
+ for the boot blocks without recompiling the boot blocks. If you
+ are already using <filename>COM1</filename> for another
+ device, you will have to temporarily remove that device and
+ install a new boot block and kernel once you get FreeBSD up and
+ running. (It is assumed that <filename>COM1</filename> will
+ be available on a file/compute/terminal server anyway; if you
+ really need <filename>COM1</filename> for something else
+ (and you cannot switch that something else to
+ <filename>COM2</filename> (<filename>sio1</filename>)),
+ then you probably should not even be bothering with all this in
+ the first place.)</para>
+ </step>
+
+ <step>
+ <para>Make sure the configuration file of your kernel has
+ appropriate flags set for <filename>COM1</filename>
+ (<filename>sio0</filename>).</para>
+
+ <para>Relevant flags are:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>0x10</literal></term>
+
+ <listitem>
+ <para>Enables console support for this unit. The other
+ console flags are ignored unless this is set. Currently, at
+ most one unit can have console support; the first one (in
+ config file order) with this flag set is preferred. This
+ option alone will not make the serial port the console. Set
+ the following flag or use the <option>-h</option> option
+ described below, together with this flag.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>0x20</literal></term>
+
+ <listitem>
+ <para>Forces this unit to be the console (unless there is
+ another higher priority console), regardless of the
+ <option>-h</option> option discussed below.
+ The flag <literal>0x20</literal> must be used
+ together with the <option>0x10</option> flag.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>0x40</literal></term>
+
+ <listitem>
+ <para>Reserves this unit (in conjunction with
+ <literal>0x10</literal>) and makes the unit
+ unavailable for normal access. You should not set
+ this flag to the serial port unit which you want to
+ use as the serial console. The only use of this
+ flag is to designate the unit for kernel remote
+ debugging. See <link xlink:href="&url.books.developers-handbook;/index.html">The
+ Developer's Handbook</link> for more information on
+ remote debugging.</para>
+
+ <note>
+ <para>In FreeBSD&nbsp;4.0 or later the semantics of the
+ flag <literal>0x40</literal> are slightly different and
+ there is another flag to specify a serial port for remote
+ debugging.</para>
+ </note>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>Example:</para>
+
+ <programlisting>device sio0 at isa? port IO_COM1 flags 0x10 irq 4</programlisting>
+
+ <para>See the &man.sio.4; manual page for more details.</para>
+
+ <para>If the flags were not set, you need to run UserConfig (on a
+ different console) or recompile the kernel.</para>
+ </step>
+
+ <step>
+ <para>Create <filename>boot.config</filename> in the root directory
+ of the <literal>a</literal> partition on the boot drive.</para>
+
+ <para>This file will instruct the boot block code how you would like
+ to boot the system. In order to activate the serial console, you
+ need one or more of the following options&mdash;if you want
+ multiple options, include them all on the same line:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-h</option></term>
+
+ <listitem>
+ <para>Toggles internal and serial consoles. You can use this
+ to switch console devices. For instance, if you boot from
+ the internal (video) console, you can use
+ <option>-h</option> to direct the boot loader and the kernel
+ to use the serial port as its console device. Alternatively,
+ if you boot from the serial port, you can use the
+ <option>-h</option> to tell the boot loader and the kernel
+ to use the video display as the console instead.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-D</option></term>
+
+ <listitem>
+ <para>Toggles single and dual console configurations. In the
+ single configuration the console will be either the internal
+ console (video display) or the serial port, depending on the
+ state of the <option>-h</option> option above. In the dual
+ console configuration, both the video display and the
+ serial port will become the console at the same time,
+ regardless of the state of the <option>-h</option> option.
+ However, note that the dual console configuration takes effect
+ only during the boot block is running. Once the boot loader
+ gets control, the console specified by the
+ <option>-h</option> option becomes the only console.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-P</option></term>
+
+ <listitem>
+ <para>Makes the boot block probe the keyboard. If no keyboard
+ is found, the <option>-D</option> and <option>-h</option>
+ options are automatically set.</para>
+
+ <note>
+ <para>Due to space constraints in the current version of the
+ boot blocks, the <option>-P</option> option is capable of
+ detecting extended keyboards only. Keyboards with less
+ than 101 keys (and without F11 and F12 keys) may not be
+ detected. Keyboards on some laptop computers may not be
+ properly found because of this limitation. If this is
+ the case with your system, you have to abandon using
+ the <option>-P</option> option. Unfortunately there is no
+ workaround for this problem.</para>
+ </note>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>Use either the <option>-P</option> option to select the
+ console automatically, or the <option>-h</option> option to
+ activate the serial console.</para>
+
+ <para>You may include other options described in &man.boot.8; as
+ well.</para>
+
+ <para>The options, except for <option>-P</option>, will be passed to
+ the boot loader (<filename>/boot/loader</filename>). The boot
+ loader will determine which of the internal video or the serial
+ port should become the console by examining the state of the
+ <option>-h</option> option alone. This means that if you specify
+ the <option>-D</option> option but not the <option>-h</option>
+ option in <filename>/boot.config</filename>, you can use the
+ serial port as the console only during the boot block; the boot
+ loader will use the internal video display as the console.</para>
+ </step>
+
+ <step>
+ <para>Boot the machine.</para>
+
+ <para>When you start your FreeBSD box, the boot blocks will echo the
+ contents of <filename>/boot.config</filename> to the console. For
+ example:</para>
+
+ <screen>/boot.config: -P
+Keyboard: no</screen>
+
+ <para>The second line appears only if you put <option>-P</option> in
+ <filename>/boot.config</filename> and indicates presence/absence
+ of the keyboard. These messages go to either serial or internal
+ console, or both, depending on the option in
+ <filename>/boot.config</filename>.</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry align="left">Options</entry>
+ <entry align="left">Message goes to</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>none</entry>
+ <entry>internal console</entry>
+ </row>
+
+ <row>
+ <entry><option>-h</option></entry>
+ <entry>serial console</entry>
+ </row>
+
+ <row>
+ <entry><option>-D</option></entry>
+ <entry>serial and internal consoles</entry>
+ </row>
+
+ <row>
+ <entry><option>-Dh</option></entry>
+ <entry>serial and internal consoles</entry>
+ </row>
+
+ <row>
+ <entry><option>-P</option>, keyboard present</entry>
+ <entry>internal console</entry>
+ </row>
+
+ <row>
+ <entry><option>-P</option>, keyboard absent</entry>
+ <entry>serial console</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>After the above messages, there will be a small pause before
+ the boot blocks continue loading the boot loader and before any
+ further messages printed to the console. Under normal
+ circumstances, you do not need to interrupt the boot blocks, but
+ you may want to do so in order to make sure things are set up
+ correctly.</para>
+
+ <para>Hit any key, other than <keycode>Enter</keycode>, at the console to
+ interrupt the boot process. The boot blocks will then prompt you
+ for further action. You should now see something like:</para>
+
+ <screen>&gt;&gt; FreeBSD/i386 BOOT
+Default: 0:ad(0,a)/boot/loader
+boot:</screen>
+
+ <para>Verify the above message appears on either the serial or
+ internal console or both, according to the options you put in
+ <filename>/boot.config</filename>. If the message appears in the
+ correct console, hit <keycode>Enter</keycode> to continue the boot
+ process.</para>
+
+ <para>If you want the serial console but you do not see the prompt
+ on the serial terminal, something is wrong with your settings. In
+ the meantime, you enter <option>-h</option> and hit Enter/Return
+ (if possible) to tell the boot block (and then the boot loader and
+ the kernel) to choose the serial port for the console. Once the
+ system is up, go back and check what went wrong.</para>
+ </step>
+ </procedure>
+
+ <para>After the boot loader is loaded and you are in the third stage of
+ the boot process you can still switch between the internal console and
+ the serial console by setting appropriate environment variables in the
+ boot loader. See <xref linkend="serialconsole-loader"/>.</para>
+ </sect2>
+
+ <sect2 xml:id="serialconsole-summary">
+ <title>Summary</title>
+
+ <para>Here is the summary of various settings discussed in this section
+ and the console eventually selected.</para>
+
+ <sect3>
+ <title>Case 1: You Set the Flags to 0x10 for
+ <filename>sio0</filename></title>
+
+ <programlisting>device sio0 at isa? port IO_COM1 flags 0x10 irq 4</programlisting>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry align="left">Options in /boot.config</entry>
+ <entry align="left">Console during boot blocks</entry>
+ <entry align="left">Console during boot loader</entry>
+ <entry align="left">Console in kernel</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>nothing</entry>
+ <entry>internal</entry>
+ <entry>internal</entry>
+ <entry>internal</entry>
+ </row>
+
+ <row>
+ <entry><option>-h</option></entry>
+ <entry>serial</entry>
+ <entry>serial</entry>
+ <entry>serial</entry>
+ </row>
+
+ <row>
+ <entry><option>-D</option></entry>
+ <entry>serial and internal</entry>
+ <entry>internal</entry>
+ <entry>internal</entry>
+ </row>
+
+ <row>
+ <entry><option>-Dh</option></entry>
+ <entry>serial and internal</entry>
+ <entry>serial</entry>
+ <entry>serial</entry>
+ </row>
+
+ <row>
+ <entry><option>-P</option>, keyboard present</entry>
+ <entry>internal</entry>
+ <entry>internal</entry>
+ <entry>internal</entry>
+ </row>
+
+ <row>
+ <entry><option>-P</option>, keyboard absent</entry>
+ <entry>serial and internal</entry>
+ <entry>serial</entry>
+ <entry>serial</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+
+ <sect3>
+ <title>Case 2: You Set the Flags to 0x30 for sio0</title>
+
+ <programlisting>device sio0 at isa? port IO_COM1 flags 0x30 irq 4</programlisting>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry align="left">Options in /boot.config</entry>
+ <entry align="left">Console during boot blocks</entry>
+ <entry align="left">Console during boot loader</entry>
+ <entry align="left">Console in kernel</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>nothing</entry>
+ <entry>internal</entry>
+ <entry>internal</entry>
+ <entry>serial</entry>
+ </row>
+
+ <row>
+ <entry><option>-h</option></entry>
+ <entry>serial</entry>
+ <entry>serial</entry>
+ <entry>serial</entry>
+ </row>
+
+ <row>
+ <entry><option>-D</option></entry>
+ <entry>serial and internal</entry>
+ <entry>internal</entry>
+ <entry>serial</entry>
+ </row>
+
+ <row>
+ <entry><option>-Dh</option></entry>
+ <entry>serial and internal</entry>
+ <entry>serial</entry>
+ <entry>serial</entry>
+ </row>
+
+ <row>
+ <entry><option>-P</option>, keyboard present</entry>
+ <entry>internal</entry>
+ <entry>internal</entry>
+ <entry>serial</entry>
+ </row>
+
+ <row>
+ <entry><option>-P</option>, keyboard absent</entry>
+ <entry>serial and internal</entry>
+ <entry>serial</entry>
+ <entry>serial</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="serialconsole-tips">
+ <title>Tips for the Serial Console</title>
+
+ <sect3>
+ <title>Setting a Faster Serial Port Speed</title>
+
+ <para>By default, the serial port settings are: 9600 baud, 8
+ bits, no parity, and 1 stop bit. If you wish to change the speed, you
+ need to recompile at least the boot blocks. Add the following line
+ to <filename>/etc/make.conf</filename> and compile new boot
+ blocks:</para>
+
+ <programlisting>BOOT_COMCONSOLE_SPEED=19200</programlisting>
+
+ <para>See <xref linkend="serialconsole-com2"/> for detailed
+ instructions about building and installing new boot blocks.</para>
+
+ <para>If the serial console is configured in some other way than by
+ booting with <option>-h</option>, or if the serial console used by
+ the kernel is different from the one used by the boot blocks, then
+ you must also add the following option to the kernel configuration
+ file and compile a new kernel:</para>
+
+ <programlisting>options CONSPEED=19200</programlisting>
+ </sect3>
+
+ <sect3 xml:id="serialconsole-com2">
+ <title>Using Serial Port Other Than <filename>sio0</filename> for
+ the Console</title>
+
+ <para>Using a port other than <filename>sio0</filename> as the
+ console requires some recompiling. If you want to use another
+ serial port for whatever reasons, recompile the boot blocks, the
+ boot loader and the kernel as follows.</para>
+
+ <procedure>
+ <step>
+ <para>Get the kernel source. (See <xref linkend="cutting-edge"/>)</para>
+ </step>
+
+ <step>
+ <para>Edit <filename>/etc/make.conf</filename> and set
+ <literal>BOOT_COMCONSOLE_PORT</literal> to the address of the
+ port you want to use (0x3F8, 0x2F8, 0x3E8 or 0x2E8). Only
+ <filename>sio0</filename> through
+ <filename>sio3</filename> (<filename>COM1</filename>
+ through <filename>COM4</filename>) can be used; multiport
+ serial cards will not work. No interrupt setting is
+ needed.</para>
+ </step>
+
+ <step>
+ <para>Create a custom kernel configuration file and add
+ appropriate flags for the serial port you want to use. For
+ example, if you want to make <filename>sio1</filename>
+ (<filename>COM2</filename>) the console:</para>
+
+ <programlisting>device sio1 at isa? port IO_COM2 flags 0x10 irq 3</programlisting>
+
+ <para>or</para>
+
+ <programlisting>device sio1 at isa? port IO_COM2 flags 0x30 irq 3</programlisting>
+
+ <para>The console flags for the other serial ports should not be
+ set.</para>
+ </step>
+
+ <step>
+ <para>Recompile and install the boot blocks and the boot loader:</para>
+
+ <screen>&prompt.root; <userinput>cd /sys/boot</userinput>
+&prompt.root; <userinput>make clean</userinput>
+&prompt.root; <userinput>make</userinput>
+&prompt.root; <userinput>make install</userinput></screen>
+ </step>
+
+ <step>
+ <para>Rebuild and install the kernel.</para>
+ </step>
+
+ <step>
+ <para>Write the boot blocks to the boot disk with
+ &man.disklabel.8; and boot from the new kernel.</para>
+ </step>
+ </procedure>
+ </sect3>
+
+ <sect3 xml:id="serialconsole-ddb">
+ <title>Entering the DDB Debugger from the Serial Line</title>
+
+ <para>If you wish to drop into the kernel debugger from the serial
+ console (useful for remote diagnostics, but also dangerous if you
+ generate a spurious BREAK on the serial port!) then you should
+ compile your kernel with the following options:</para>
+
+ <programlisting>options BREAK_TO_DEBUGGER
+options DDB</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Getting a Login Prompt on the Serial Console</title>
+
+ <para>While this is not required, you may wish to get a
+ <emphasis>login</emphasis> prompt over the serial line, now that you
+ can see boot messages and can enter the kernel debugging session
+ through the serial console. Here is how to do it.</para>
+
+ <para>Open the file <filename>/etc/ttys</filename> with an editor
+ and locate the lines:</para>
+
+ <programlisting>ttyd0 "/usr/libexec/getty std.9600" unknown off secure
+ttyd1 "/usr/libexec/getty std.9600" unknown off secure
+ttyd2 "/usr/libexec/getty std.9600" unknown off secure
+ttyd3 "/usr/libexec/getty std.9600" unknown off secure</programlisting>
+
+ <para><literal>ttyd0</literal> through <literal>ttyd3</literal>
+ corresponds to <filename>COM1</filename> through
+ <filename>COM4</filename>. Change <literal>off</literal> to
+ <literal>on</literal> for the desired port. If you have changed the
+ speed of the serial port, you need to change
+ <literal>std.9600</literal> to match the current setting, e.g.
+ <literal>std.19200</literal>.</para>
+
+ <para>You may also want to change the terminal type from
+ <literal>unknown</literal> to the actual type of your serial
+ terminal.</para>
+
+ <para>After editing the file, you must <command>kill -HUP 1</command>
+ to make this change take effect.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="serialconsole-loader">
+ <title>Changing Console from the Boot Loader</title>
+
+ <para>Previous sections described how to set up the serial console by
+ tweaking the boot block. This section shows that you can specify the
+ console by entering some commands and environment variables in the
+ boot loader. As the boot loader is invoked at the third stage of the
+ boot process, after the boot block, the settings in the boot loader
+ will override the settings in the boot block.</para>
+
+ <sect3>
+ <title>Setting Up the Serial Console</title>
+
+ <para>You can easily specify the boot loader and the kernel to use the
+ serial console by writing just one line in
+ <filename>/boot/loader.rc</filename>:</para>
+
+ <programlisting>set console="comconsole"</programlisting>
+
+ <para>This will take effect regardless of the settings in the boot
+ block discussed in the previous section.</para>
+
+ <para>You had better put the above line as the first line of
+ <filename>/boot/loader.rc</filename> so as to see boot messages on
+ the serial console as early as possible.</para>
+
+ <para>Likewise, you can specify the internal console as:</para>
+
+ <programlisting>set console="vidconsole"</programlisting>
+
+ <para>If you do not set the boot loader environment variable
+ <envar>console</envar>, the boot loader, and subsequently the
+ kernel, will use whichever console indicated by the
+ <option>-h</option> option in the boot block.</para>
+
+ <para>In versions 3.2 or later, you may specify the console in
+ <filename>/boot/loader.conf.local</filename> or
+ <filename>/boot/loader.conf</filename>, rather than in
+ <filename>/boot/loader.rc</filename>. In this method your
+ <filename>/boot/loader.rc</filename> should look like:</para>
+
+ <programlisting>include /boot/loader.4th
+start</programlisting>
+
+ <para>Then, create <filename>/boot/loader.conf.local</filename> and
+ put the following line there.</para>
+
+ <programlisting>console=comconsole</programlisting>
+
+ <para>or</para>
+
+ <programlisting>console=vidconsole</programlisting>
+
+ <para>See &man.loader.conf.5; for more information.</para>
+
+ <note>
+ <para>At the moment, the boot loader has no option equivalent to the
+ <option>-P</option> option in the boot block, and there is no
+ provision to automatically select the internal console and the
+ serial console based on the presence of the keyboard.</para>
+ </note>
+ </sect3>
+
+ <sect3>
+ <title>Using a Serial Port Other Than <filename>sio0</filename> for
+ the Console</title>
+
+ <para>You need to recompile the boot loader to use a serial port other
+ than <filename>sio0</filename> for the serial console. Follow the
+ procedure described in <xref linkend="serialconsole-com2"/>.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="serialconsole-caveats">
+ <title>Caveats</title>
+
+ <para>The idea here is to allow people to set up dedicated servers that
+ require no graphics hardware or attached keyboards. Unfortunately,
+ while most systems will let you boot without a keyboard, there
+ are quite a few that will not let you boot without a graphics adapter.
+ Machines with AMI BIOSes can be configured to boot with no graphics
+ adapter installed simply by changing the <quote>graphics adapter</quote> setting in
+ the CMOS configuration to <quote>Not installed.</quote></para>
+
+ <para>However, many machines do not support this option and will refuse
+ to boot if you have no display hardware in the system. With these
+ machines, you will have to leave some kind of graphics card plugged in,
+ (even if it is just a junky mono board) although you will not have to
+ attach a monitor. You might also try installing an AMI
+ BIOS.</para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/txtfiles.ent b/zh_TW.UTF-8/books/handbook/txtfiles.ent
new file mode 100644
index 0000000000..e45198fa0e
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/txtfiles.ent
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Creates entities for each .txt screenshot that is included in the
+ Handbook.
+
+ Each entity is named txt.dir.foo, where dir is the directory in
+ which it is stored, and foo is its filename, without the '.txt'
+ extension.
+
+ Entities should be listed in alphabetical order.
+
+ $FreeBSD$
+ Original revision: 1.4
+-->
+
+<!ENTITY txt.install.adduser1 SYSTEM "install/adduser1.txt">
+<!ENTITY txt.install.adduser2 SYSTEM "install/adduser2.txt">
+<!ENTITY txt.install.adduser3 SYSTEM "install/adduser3.txt">
+<!ENTITY txt.install.boot-mgr SYSTEM "install/boot-mgr.txt">
+<!ENTITY txt.install.config-country SYSTEM "install/config-country.txt">
+<!ENTITY txt.install.console-saver1 SYSTEM "install/console-saver1.txt">
+<!ENTITY txt.install.console-saver2 SYSTEM "install/console-saver2.txt">
+<!ENTITY txt.install.console-saver3 SYSTEM "install/console-saver3.txt">
+<!ENTITY txt.install.console-saver4 SYSTEM "install/console-saver4.txt">
+<!ENTITY txt.install.disklabel-auto SYSTEM "install/disklabel-auto.txt">
+<!ENTITY txt.install.disklabel-ed1 SYSTEM "install/disklabel-ed1.txt">
+<!ENTITY txt.install.disklabel-ed2 SYSTEM "install/disklabel-ed2.txt">
+<!ENTITY txt.install.disklabel-fs SYSTEM "install/disklabel-fs.txt">
+<!ENTITY txt.install.disklabel-root1 SYSTEM "install/disklabel-root1.txt">
+<!ENTITY txt.install.disklabel-root2 SYSTEM "install/disklabel-root2.txt">
+<!ENTITY txt.install.disklabel-root3 SYSTEM "install/disklabel-root3.txt">
+<!ENTITY txt.install.dist-set SYSTEM "install/dist-set.txt">
+<!ENTITY txt.install.dist-set2 SYSTEM "install/dist-set2.txt">
+<!ENTITY txt.install.docmenu1 SYSTEM "install/docmenu1.txt">
+<!ENTITY txt.install.ed0-conf SYSTEM "install/ed0-conf.txt">
+<!ENTITY txt.install.ed0-conf2 SYSTEM "install/ed0-conf2.txt">
+<!ENTITY txt.install.edit-inetd-conf SYSTEM "install/edit-inetd-conf.txt">
+<!ENTITY txt.install.fdisk-drive1 SYSTEM "install/fdisk-drive1.txt">
+<!ENTITY txt.install.fdisk-drive2 SYSTEM "install/fdisk-drive2.txt">
+<!ENTITY txt.install.fdisk-edit1 SYSTEM "install/fdisk-edit1.txt">
+<!ENTITY txt.install.fdisk-edit2 SYSTEM "install/fdisk-edit2.txt">
+<!ENTITY txt.install.ftp-anon1 SYSTEM "install/ftp-anon1.txt">
+<!ENTITY txt.install.ftp-anon2 SYSTEM "install/ftp-anon2.txt">
+<!ENTITY txt.install.hdwrconf SYSTEM "install/hdwrconf.txt">
+<!ENTITY txt.install.keymap SYSTEM "install/keymap.txt">
+<!ENTITY txt.install.main-doc SYSTEM "install/main-doc.txt">
+<!ENTITY txt.install.main-keymap SYSTEM "install/main-keymap.txt">
+<!ENTITY txt.install.main-options SYSTEM "install/main-options.txt">
+<!ENTITY txt.install.main-std SYSTEM "install/main-std.txt">
+<!ENTITY txt.install.main1 SYSTEM "install/main1.txt">
+<!ENTITY txt.install.mainexit SYSTEM "install/mainexit.txt">
+<!ENTITY txt.install.media SYSTEM "install/media.txt">
+<!ENTITY txt.install.mouse1 SYSTEM "install/mouse1.txt">
+<!ENTITY txt.install.mouse2 SYSTEM "install/mouse2.txt">
+<!ENTITY txt.install.mouse3 SYSTEM "install/mouse3.txt">
+<!ENTITY txt.install.mouse4 SYSTEM "install/mouse4.txt">
+<!ENTITY txt.install.mouse5 SYSTEM "install/mouse5.txt">
+<!ENTITY txt.install.mouse6 SYSTEM "install/mouse6.txt">
+<!ENTITY txt.install.nfs-server-edit SYSTEM "install/nfs-server-edit.txt">
+<!ENTITY txt.install.options SYSTEM "install/options.txt">
+<!ENTITY txt.install.pkg-cat SYSTEM "install/pkg-cat.txt">
+<!ENTITY txt.install.pkg-confirm SYSTEM "install/pkg-confirm.txt">
+<!ENTITY txt.install.pkg-install SYSTEM "install/pkg-install.txt">
+<!ENTITY txt.install.pkg-sel SYSTEM "install/pkg-sel.txt">
+<!ENTITY txt.install.probstart SYSTEM "install/probstart.txt">
+<!ENTITY txt.install.security SYSTEM "install/security.txt">
+<!ENTITY txt.install.sysinstall-exit SYSTEM "install/sysinstall-exit.txt">
+<!ENTITY txt.install.timezone1 SYSTEM "install/timezone1.txt">
+<!ENTITY txt.install.timezone2 SYSTEM "install/timezone2.txt">
+<!ENTITY txt.install.timezone3 SYSTEM "install/timezone3.txt">
+<!ENTITY txt.install.userconfig SYSTEM "../../../share/images/books/handbook/install/userconfig.txt">
+<!ENTITY txt.install.userconfig2 SYSTEM "../../../share/images/books/handbook/install/userconfig2.txt">
diff --git a/zh_TW.UTF-8/books/handbook/users/Makefile b/zh_TW.UTF-8/books/handbook/users/Makefile
new file mode 100644
index 0000000000..b44bd80628
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/users/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= users/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/users/chapter.xml b/zh_TW.UTF-8/books/handbook/users/chapter.xml
new file mode 100644
index 0000000000..2cc93f289a
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/users/chapter.xml
@@ -0,0 +1,940 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.58
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="users">
+ <info><title>使用者與基本帳號管理</title>
+ <authorgroup>
+ <author><personname><firstname>Neil</firstname><surname>Blakey-Milner</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <sect1 xml:id="users-synopsis">
+ <title>概述</title>
+
+ <para>FreeBSD 允許多個使用者同時使用電腦。 當然,
+ 這並不是很多人同時坐在同一台電腦前
+ <footnote>
+ <para>Well..除非您連接 multiple terminals,這種情況我們會在 <xref linkend="serialcomms"/> 講到。</para>
+ </footnote>,而是其他使用者可以透過網路來使用同一台電腦以完成他們的工作。
+ 要使用系統的話,那麼每個人都得有一個帳號。</para>
+
+ <para>讀完這章,您將了解:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>在 FreeBSD 系統上不同帳號之間的區別。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何增加帳號。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何刪除帳號。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何更改帳號的基本資料,像是帳號全名,或是使用的 shell
+ 種類。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何針對帳號、群組來設限,比如:允許存取記憶體或 CPU
+ 資源多寡等。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何運用群組,來更容易地管理帳號。</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>在開始閱讀這章之前,您需要:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>瞭解 &unix; 及 FreeBSD (<xref linkend="basics"/>)的基礎概念。</para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="users-introduction">
+ <title>介紹</title>
+
+ <para>系統的所有存取是經由帳號來進行,而所有的程式 process
+ 是由使用者來進行,所以使用者及帳號的管理,乃是 FreeBSD
+ 系統上不可或缺的重點。</para>
+
+ <para>所有於 FreeBSD 系統中的帳號皆包含下列相關資訊用來辨識身份。</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>使用者名稱</term>
+
+ <listitem>
+ <para>使用者名稱要輸入在 <prompt>login:</prompt> 提示出現後。
+ 使用者名稱必須是獨一無二,
+ 不能有重複的使用者名稱。
+ 至於如何建立有效使用者名稱的規則,請參閱 &man.passwd.5; 說明,
+ 通常使用者名稱是以八個以內的小寫字母所組成。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>密碼</term>
+
+ <listitem>
+ <para>每個帳號都可擁有一組密碼。 密碼也可以不設,
+ 如此就不需密碼即可登入系統,但通常這並非妙策,
+ 每個帳號都應設定一組密碼。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>使用者代號 (User ID, UID)</term>
+
+ <listitem>
+ <para>UID 是系統用來辨識使用者的數字,通常範圍是從 0 到 65535 <footnote xml:id="users-largeuidgid">
+ <para>UID/GID 最大可使用至 4294967295,但這樣的 ID
+ 可能會對已假設範圍的軟體造成嚴重問題。</para>
+ </footnote>。 FreeBSD 內部是使用 UID 來辨識使用者 &mdash;
+ FreeBSD 在執行任何指定使用者的指令之前,都會先把使用者名稱轉換為
+ UID。 也就是說,比如可以有數個不同的使用者名稱,
+ 但是都使用同一個 UID,對 FreeBSD 來說,這些帳號都只代表同一使用者。
+ 不過,實際上需要這樣做的可能性不大。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>群組代號 (Group ID, GID)</term>
+
+ <listitem>
+ <para>GID 是系統用來辨識使用者所屬群組的數字,通常範圍是從 0 到 65535<footnoteref linkend="users-largeuidgid"/>
+ 。 用群組來控制資源存取,可有效減少一些設定檔的大小。
+ 此外,使用者還可以同時屬於多個不同的群組。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>登入分類(Login classes)</term>
+
+ <listitem>
+ <para>
+ 登入分類是群組的延伸機制,
+ 提供了不同的使用者更彈性的。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>密碼變更期限</term>
+
+ <listitem>
+ <para>FreeBSD 預設並不要求使用者週期性的更改密碼。您可以強制某些或
+ 全部的使用者在指定的期間過後必須更改密碼。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>帳號期限</term>
+
+
+ <listitem>
+ <para>FreeBSD 的帳號沒有預設的期限,如果您已知道帳號的使用期限,
+ 例如,學校中提供學生使用的帳號,可在建立帳號時指定帳號的期限。
+ 當帳號過期後會無法登入系統,但該帳號的目錄及檔案則會保留。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>使用者全名</term>
+
+ <listitem>
+ <para>FreeBSD 的帳號使用使用者名稱用來辨識,但使用者名稱並不一定代表
+ 真實使用者的姓名。為帳號所需的相關資訊。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>家目錄</term>
+
+ <listitem>
+ <para>家目錄為使用者登入系統時的所在目錄的完整路徑。
+ 通常會將所有使用者的家目錄放置於
+ <filename>/home/使用者名稱</filename>
+ 或 <filename>/usr/home/使用者名稱</filename>。
+ 使用者可以將其個人的資料放置於其家目錄之中,並可以在此目錄底下
+ 建立新的目錄</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>使用者 Shell</term>
+
+ <listitem>
+ <para>Shell 提供預設的環境讓使用者與系統互動。
+ Shell 擁有數種不同的種類, 可供進階使用者依使用習慣選擇。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <!--
+ Superuser: 系統管理者帳號
+ System users: 系統帳號
+ user accounts: 使用者帳號
+ -->
+ <para>帳號主要分為下列三類: <link linkend="users-superuser">系統管理者帳號</link>, <link linkend="users-system">系統帳號</link>,及 <link linkend="users-user">使用者帳號</link>。 系統管理者帳號的帳號
+ 通常為 <systemitem class="username">root</systemitem>,擁有最大的權限來管理系統。
+ 系統帳號用來執行伺服器服務。最後,使用者帳號供真正的使用者使用,
+ 可登入、讀信等等。</para>
+ </sect1>
+
+ <sect1 xml:id="users-superuser">
+ <title>系統管理者帳號</title>
+
+ <indexterm>
+ <primary>accounts</primary>
+ <secondary>superuser (root)</secondary>
+ </indexterm>
+ <para>The superuser account, usually called
+ <systemitem class="username">root</systemitem>, 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.</para>
+
+ <para>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.</para>
+
+ <para>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.</para>
+
+ <para>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.</para>
+ </sect1>
+
+ <sect1 xml:id="users-system">
+ <title>系統帳號</title>
+
+ <indexterm>
+ <primary>accounts</primary>
+ <secondary>system</secondary>
+ </indexterm>
+ <para>System 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.</para>
+
+ <indexterm>
+ <primary>accounts</primary>
+ <secondary><systemitem class="username">daemon</systemitem></secondary>
+ </indexterm>
+ <indexterm>
+ <primary>accounts</primary>
+ <secondary><systemitem class="username">operator</systemitem></secondary>
+ </indexterm>
+ <para>Examples of system users are <systemitem class="username">daemon</systemitem>,
+ <systemitem class="username">operator</systemitem>, <systemitem class="username">bind</systemitem> (for
+ the Domain Name Service), <systemitem class="username">news</systemitem>, and
+ <systemitem class="username">www</systemitem>.</para>
+
+ <indexterm>
+ <primary>accounts</primary>
+ <secondary><systemitem class="username">nobody</systemitem></secondary>
+ </indexterm>
+ <para><systemitem class="username">nobody</systemitem> is the generic unprivileged
+ system user. However, it is important to keep in mind that the
+ more services that use <systemitem class="username">nobody</systemitem>, the more
+ files and processes that user will become associated with, and
+ hence the more privileged that user becomes.</para>
+ </sect1>
+
+ <sect1 xml:id="users-user">
+ <title>使用者帳號</title>
+
+ <indexterm>
+ <primary>accounts</primary>
+ <secondary>user</secondary>
+ </indexterm>
+ <para>User 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.</para>
+
+ <para>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.</para>
+
+ <para>Each user can set up their own environment to accommodate
+ their use of the system, by using alternate shells, editors, key
+ bindings, and language.</para>
+ </sect1>
+
+ <sect1 xml:id="users-modifying">
+ <title>更改帳號</title>
+
+ <indexterm>
+ <primary>accounts</primary>
+ <secondary>modifying</secondary>
+ </indexterm>
+
+ <para>在 &unix; 的環境之中提供了各式不同的指令管理使用者帳號,
+ 以下為較常使用的指令摘要及更詳細的使用範例。
+ </para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <colspec colwidth="1*"/>
+ <colspec colwidth="2*"/>
+
+ <thead>
+ <row>
+ <entry>指令</entry>
+ <entry>摘要</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>&man.adduser.8;</entry>
+ <entry>新增使用者。</entry>
+ </row>
+ <row>
+ <entry>&man.rmuser.8;</entry>
+ <entry>移除使用者。</entry>
+ </row>
+ <row>
+ <entry>&man.chpass.1;</entry>
+ <entry>更改使用者資料。</entry>
+ </row>
+ <row>
+ <entry>&man.passwd.1;</entry>
+ <entry>更改使用者密碼。</entry>
+ </row>
+ <row>
+ <entry>&man.pw.8;</entry>
+ <entry>修改使用者的各種資料。</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <sect2 xml:id="users-adduser">
+ <title><command>adduser</command></title>
+
+ <indexterm>
+ <primary>accounts</primary>
+ <secondary>adding</secondary>
+ </indexterm>
+ <indexterm>
+ <primary><command>adduser</command></primary>
+ </indexterm>
+ <indexterm>
+ <primary><filename>/usr/share/skel</filename></primary>
+ </indexterm>
+ <indexterm><primary>skeleton directory</primary></indexterm>
+ <para>&man.adduser.8; 是一支新增使用者的簡單程式。
+ 它會建立資料於系統的 <filename>passwd</filename> 與
+ <filename>group</filename>
+ 檔案之中。 同時也會建立使用者的家目錄,從 <filename>
+ /usr/share/skel</filename> 複製預設的組態檔(<quote>dotfiles</quote>),
+ 並可以選擇性的郵件通知新使用者歡迎訊息。</para>
+
+ <example>
+ <title>在 &os; 內新增使用者</title>
+
+ <screen>&prompt.root; <userinput>adduser</userinput>
+Username: <userinput>jru</userinput>
+Full name: <userinput>J. Random User</userinput>
+Uid (Leave empty for default):
+Login group [jru]:
+Login group is jru. Invite jru into other groups? []: <userinput>wheel</userinput>
+Login class [default]:
+Shell (sh csh tcsh zsh nologin) [sh]: <userinput>zsh</userinput>
+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): <userinput>yes</userinput>
+adduser: INFO: Successfully added (jru) to the user database.
+Add another user? (yes/no): <userinput>no</userinput>
+Goodbye!
+&prompt.root;</screen>
+ </example>
+
+ <note>
+ <para>您輸入的密碼並不會回應到螢幕,所以不會以星號顯示
+ 。 請確定您所輸入的密碼無誤。</para>
+ </note>
+ </sect2>
+
+ <sect2 xml:id="users-rmuser">
+ <title><command>rmuser</command></title>
+
+ <indexterm><primary><command>rmuser</command></primary></indexterm>
+ <indexterm>
+ <primary>accounts</primary>
+ <secondary>removing</secondary>
+ </indexterm>
+
+ <para>您可以使用 &man.rmuser.8; 來將使用者從系統之中完全移除
+ &man.rmuser.8; 會執行以下動作:</para>
+
+ <procedure>
+ <step>
+ <para>移除該使用者的 &man.crontab.1; 資料 (如果存在)。</para>
+ </step>
+ <step>
+ <para>移除所有屬於該使用者的 &man.at.1; 工作。</para>
+ </step>
+ <step>
+ <para>中止所有該使用者擁有的程序。</para>
+ </step>
+ <step>
+ <para>移除系統本機密碼檔中該使用者的資料。</para>
+ </step>
+ <step>
+ <para>移除該使用者的家目錄 (如果為該使用者所有)。</para>
+ </step>
+ <step>
+ <para>移除 <filename>/var/mail</filename> 中屬於該使用者的郵件。</para>
+ </step>
+ <step>
+ <para>移除暫存空間 (如: <filename>/tmp</filename>) 中所有屬於該使用者的檔案。</para>
+ </step>
+ <step>
+ <para>最後,在 <filename>/etc/group</filename> 檔內移除該使用者帳號。
+ </para>
+
+ <note>
+ <para>若該群組已無成員,或者是群組名稱與該使用者名稱相同時,
+ 則群組將會被移除; 此操作會與 &man.adduser.8;
+ 所建立的帳號群組相對應。</para>
+ </note>
+ </step>
+ </procedure>
+
+ <para>&man.rmuser.8; 無法移除系統管理者帳號帳號,
+ 因為這即代表嚴重的破壞行為。</para>
+
+ <para>為了確認您的操作,預設採互動模式。</para>
+
+ <example>
+ <title><command>rmuser</command> 帳號移除</title>
+
+ <screen>&prompt.root; <userinput>rmuser jru</userinput>
+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? <userinput>y</userinput>
+Remove user's home directory (/home/jru)? <userinput>y</userinput>
+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;</screen>
+ </example>
+ </sect2>
+
+ <sect2 xml:id="users-chpass">
+ <title><command>chpass</command></title>
+
+ <indexterm><primary><command>chpass</command></primary></indexterm>
+ <para>&man.chpass.1; 可更改使用者資料如: 密碼、Shell及個人資訊。</para>
+
+ <para>僅系統管理者即系統管理者帳號可利用 &man.chpass.1; 更改其他使用者的資訊及密碼</para>
+
+ <para>除了指定使用者名稱,當不加參數時,&man.chpass.1; 會將使用者資訊顯示於編輯器當中。
+ 並於使用者離開編輯器時更新使用者資訊。</para>
+
+ <note>
+ <para>若您並非系統管理者帳號,在離開編輯器前會詢問您的密碼。</para>
+ </note>
+
+ <example>
+ <title>系統管理者帳號 <command>chpass</command></title>
+
+ <screen>#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:</screen>
+ </example>
+
+ <para>一般使用者僅可更改自己的少部份資訊。</para>
+
+ <example>
+ <title>一般使用者 <command>chpass</command></title>
+
+ <screen>#Changing user database information for jru.
+Shell: /usr/local/bin/zsh
+Full Name: J. Random User
+Office Location:
+Office Phone:
+Home Phone:
+Other information:</screen>
+ </example>
+
+ <note>
+ <para>&man.chfn.1; 與 &man.chsh.1; 即為 &man.chpass.1;,也同
+ &man.ypchpass.1;、&man.ypchfn.1; 與 &man.ypchsh.1;。
+ NIS 支援是自動的,所以無需在指令前加上 <literal>yp</literal>。
+ 若這會困擾您,請不必擔心,<xref linkend="network-servers"/> 將函蓋 NIS 的部份的說明。</para>
+ </note>
+ </sect2>
+ <sect2 xml:id="users-passwd">
+ <title><command>passwd</command></title>
+
+ <indexterm><primary><command>passwd</command></primary></indexterm>
+ <indexterm>
+ <primary>accounts</primary>
+ <secondary>changing password</secondary>
+ </indexterm>
+ <para>&man.passwd.1; 是更改密碼常用的方式,除了超級管理者可更改其他使用者的密碼外
+ 使用者僅能更改自己的密碼。</para>
+
+ <note>
+ <para>為了避免意外或未經同意的修改,在更新密碼前需輸入原密碼。</para>
+ </note>
+
+ <example>
+ <title>更改您的密碼</title>
+
+ <screen>&prompt.user; <userinput>passwd</userinput>
+Changing local password for jru.
+Old password:
+New password:
+Retype new password:
+passwd: updating the database...
+passwd: done</screen>
+ </example>
+
+ <example>
+ <title>以系統管理者帳號去更改其他使用者的密碼</title>
+
+ <screen>&prompt.root; <userinput>passwd jru</userinput>
+Changing local password for jru.
+New password:
+Retype new password:
+passwd: updating the database...
+passwd: done</screen>
+ </example>
+
+ <note>
+ <para>&man.chpass.1;、
+ &man.yppasswd.1; 即為 &man.passwd.1;,皆支援 NIS。</para>
+ </note>
+ </sect2>
+
+
+ <sect2 xml:id="users-pw">
+ <title><command>pw</command></title>
+ <indexterm><primary><command>pw</command></primary></indexterm>
+
+ <para>&man.pw.8; 用來建立、移除、修改及查詢使用者及群組。
+ 其功能即為系統使用者及群組檔案的前端。&man.pw.8; 擁有大量的指令參數
+ 較適合使用於 shell script 中,對新手來說會此指令較其他指令複雜許多。
+ </para>
+ </sect2>
+
+
+ </sect1>
+
+ <sect1 xml:id="users-limiting">
+ <title>使用者資源限制</title>
+
+ <indexterm><primary>limiting users</primary></indexterm>
+ <indexterm>
+ <primary>accounts</primary>
+ <secondary>limiting</secondary>
+ </indexterm>
+ <!--
+ login class: 登入分級
+ login capability: 登入容量
+ -->
+ <para>
+ 若您擁有許多使用者,接下會想到該如何限制使用的資源。
+ FreeBSD 提供管理者許多方法來限制系統的資源給每個人使用。
+ 這些限制分為兩個部份: 磁碟限額,以及其他資源限制。
+ </para>
+
+ <indexterm><primary>quotas</primary></indexterm>
+ <indexterm>
+ <primary>limiting users</primary>
+ <secondary>quotas</secondary>
+ </indexterm>
+ <indexterm><primary>disk quotas</primary></indexterm>
+ <para>磁碟限額可以限制使用者的磁碟用量,
+ 它提供了一種方法可以快速的檢查並計算用量
+ 而不需每次重新計算,
+ 關於磁碟限額將於 <xref linkend="quotas"/> 會討論。</para>
+
+ <para>其他資源限制包含了 CPU、記憶體、以及其他每個使用者可使用
+ 的資源做限制,這些限制可使用 Login class 來定義並於在本章討論。</para>
+
+ <indexterm>
+ <primary><filename>/etc/login.conf</filename></primary>
+ </indexterm>
+ <para>Login class 定義於
+ <filename>/etc/login.conf</filename>。 明確語意不會在本節說明
+ 但詳細的描述會在 &man.login.conf.5; 文件中。 每使用者預設被
+ 分配到一個 Login class 中 (預設為 <literal>default</literal>),
+ 而每個 Login class 都有其資源的限制(Login capabilitiy)。
+ Login capabilitiy 以 <literal>名稱=值</literal> 成對,
+ <replaceable>名稱</replaceable> 代表資源的種類,而 <replaceable>值</replaceable>
+ 為任意的字串,為對應名稱的參數。 設定 Login class 及 Login capability 相當簡單,並同樣在
+ &man.login.conf.5; 中詳細說明。</para>
+
+ <note>
+ <para>系統不會直接讀取 <filename>/etc/login.conf</filename> 的組態
+ 而是讀取提供查詢較快的 <filename>/etc/login.conf.db</filename> 資料庫檔。
+ 要從 <filename>/etc/login.conf</filename> 產生 <filename>/etc/login.conf.db</filename>
+ 需要執行以下指令:</para>
+
+ <screen>&prompt.root; <userinput>cap_mkdb /etc/login.conf</userinput></screen>
+ </note>
+
+ <para>資源限制於一般的 Login capability 有兩點不同。
+ 第一,每種限制分為軟性限制及硬性限制。
+ 軟性限制可由使用者或應用程式調整,但不能高於硬性限制。
+ 後者限制可被使用者降低,但無法再提高。
+ 第二,多數資源限制是針對每個使用者的個別行程限制,而不是使用者的所有行程。
+ 注意,這些差異是由指定的限制程式托管,並非實作於 Login capability 的架構
+ (例如,這些不是 <emphasis>真正</emphasis> 登入容量的特例)。</para>
+
+ <para>另外,為了避免麻煩,以下為幾個常用的資源限制
+ (剩下及其他的 Login capability 可在 &man.login.conf.5; 中找到說明)。</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>coredumpsize</literal></term>
+
+ <listitem>
+ <indexterm><primary>coredumpsize</primary></indexterm>
+ <indexterm>
+ <primary>limiting users</primary>
+ <secondary>coredumpsize</secondary>
+ </indexterm>
+ <para>The 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., <literal>filesize</literal>, 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., <application>emacs</application>) crash.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>cputime</literal></term>
+
+ <listitem>
+ <indexterm><primary>cputime</primary></indexterm>
+ <indexterm>
+ <primary>limiting users</primary>
+ <secondary>cputime</secondary>
+ </indexterm>
+ <para>This is the maximum amount of CPU time a user's process may
+ consume. Offending processes will be killed by the kernel.</para>
+
+ <note>
+ <para>This is a limit on CPU <emphasis>time</emphasis>
+ 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&mdash;probably a
+ legitimate task&mdash;can easily use almost 100% of a CPU
+ for some time.</para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>filesize</literal></term>
+
+ <listitem>
+ <indexterm><primary>filesize</primary></indexterm>
+ <indexterm>
+ <primary>limiting users</primary>
+ <secondary>filesize</secondary>
+ </indexterm>
+ <para>This is the maximum size of a file the user may possess.
+ Unlike <link linkend="quotas">disk quotas</link>, this limit is
+ enforced on individual files, not the set of all files a user
+ owns.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>maxproc</literal></term>
+
+ <listitem>
+ <indexterm><primary>maxproc</primary></indexterm>
+ <indexterm>
+ <primary>limiting users</primary>
+ <secondary>maxproc</secondary>
+ </indexterm>
+ <para>This 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 <varname>kern.maxproc</varname>
+ &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).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>memorylocked</literal></term>
+
+ <listitem>
+ <indexterm><primary>memorylocked</primary></indexterm>
+ <indexterm>
+ <primary>limiting users</primary>
+ <secondary>memorylocked</secondary>
+ </indexterm>
+ <para>This 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.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>memoryuse</literal></term>
+
+ <listitem>
+ <indexterm><primary>memoryuse</primary></indexterm>
+ <indexterm>
+ <primary>limiting users</primary>
+ <secondary>memoryuse</secondary>
+ </indexterm>
+ <para>This 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.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>openfiles</literal></term>
+
+ <listitem>
+ <indexterm><primary>openfiles</primary></indexterm>
+ <indexterm>
+ <primary>limiting users</primary>
+ <secondary>openfiles</secondary>
+ </indexterm>
+ <para>This 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
+ <varname>kern.maxfiles</varname> &man.sysctl.8;.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sbsize</literal></term>
+
+ <listitem>
+ <indexterm><primary>sbsize</primary></indexterm>
+ <indexterm>
+ <primary>limiting users</primary>
+ <secondary>sbsize</secondary>
+ </indexterm>
+ <para>This 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.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>stacksize</literal></term>
+
+ <listitem>
+ <indexterm><primary>stacksize</primary></indexterm>
+ <indexterm>
+ <primary>limiting users</primary>
+ <secondary>stacksize</secondary>
+ </indexterm>
+ <para>This 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.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>There are a few other things to remember when setting resource
+ limits. Following are some general tips, suggestions, and
+ miscellaneous comments.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Processes started at system startup by
+ <filename>/etc/rc</filename> are assigned to the
+ <literal>daemon</literal> login class.</para>
+ </listitem>
+
+ <listitem>
+ <para>Although the <filename>/etc/login.conf</filename> 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.</para>
+ </listitem>
+
+ <listitem>
+ <para>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.</para>
+ </listitem>
+
+ <listitem>
+ <para>Remember that many limits apply to individual processes, not
+ the user as a whole. For example, setting
+ <varname>openfiles</varname> 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
+ <literal>openfiles</literal> multiplied by the value of
+ <literal>maxproc</literal>. This also applies to memory
+ consumption.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>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;.</para>
+ </sect1>
+
+ <sect1 xml:id="users-groups">
+ <title>群組</title>
+
+ <indexterm><primary>groups</primary></indexterm>
+ <indexterm>
+ <primary><filename>/etc/groups</filename></primary>
+ </indexterm>
+ <indexterm>
+ <primary>accounts</primary>
+ <secondary>groups</secondary>
+ </indexterm>
+ <para>A 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 <quote>group ID</quote>
+ of a user or process; most of the time, this just means the first
+ group in the list.</para>
+
+ <para>The group name to group ID map is in
+ <filename>/etc/group</filename>. 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.</para>
+
+ <para>If you do not want to edit <filename>/etc/group</filename>
+ manually, you can use the &man.pw.8; command to add and edit groups.
+ For example, to add a group called <systemitem class="groupname">teamtwo</systemitem> and
+ then confirm that it exists you can use:</para>
+
+ <example>
+ <title>Adding a Group Using &man.pw.8;</title>
+
+ <screen>&prompt.root; <userinput>pw groupadd teamtwo</userinput>
+&prompt.root; <userinput>pw groupshow teamtwo</userinput>
+teamtwo:*:1100:</screen>
+ </example>
+
+ <para>The number <literal>1100</literal> above is the group ID of the
+ group <systemitem class="groupname">teamtwo</systemitem>. Right now,
+ <systemitem class="groupname">teamtwo</systemitem> has no members, and is thus rather
+ useless. Let's change that by inviting <systemitem class="username">jru</systemitem> to
+ the <systemitem class="groupname">teamtwo</systemitem> group.</para>
+
+ <example>
+ <title>Adding Somebody to a Group Using &man.pw.8;</title>
+
+ <screen>&prompt.root; <userinput>pw groupmod teamtwo -M jru</userinput>
+&prompt.root; <userinput>pw groupshow teamtwo</userinput>
+teamtwo:*:1100:jru</screen>
+ </example>
+
+ <para>The argument to the <option>-M</option> 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 <option>groupshow</option> 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
+ <filename>/etc/group</filename> file; it will never attempt to read
+ additionally data from <filename>/etc/passwd</filename>.</para>
+
+ <example>
+ <title>Using &man.id.1; to Determine Group Membership</title>
+
+ <screen>&prompt.user; <userinput>id jru</userinput>
+uid=1001(jru) gid=1001(jru) groups=1001(jru), 1100(teamtwo)</screen>
+ </example>
+
+ <para>As you can see, <systemitem class="username">jru</systemitem> is a member of the
+ groups <systemitem class="groupname">jru</systemitem> and
+ <systemitem class="groupname">teamtwo</systemitem>.</para>
+
+ <para>For more information about &man.pw.8;, see its manual page, and
+ for more information on the format of
+ <filename>/etc/group</filename>, consult the &man.group.5; manual
+ page.</para>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/vinum/Makefile b/zh_TW.UTF-8/books/handbook/vinum/Makefile
new file mode 100644
index 0000000000..b970524581
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/vinum/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= vinum/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/vinum/chapter.xml b/zh_TW.UTF-8/books/handbook/vinum/chapter.xml
new file mode 100644
index 0000000000..534d9b67b0
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/vinum/chapter.xml
@@ -0,0 +1,1458 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The Vinum Volume Manager
+ By Greg Lehey (grog at lemis dot com)
+
+ Added to the Handbook by Hiten Pandya <hmp@FreeBSD.org>
+ and Tom Rhodes <trhodes@FreeBSD.org>
+
+ For the FreeBSD Documentation Project
+ $FreeBSD$
+ Original revision: 1.37
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="vinum-vinum">
+ <info><title>The Vinum Volume Manager</title>
+ <authorgroup>
+ <author><personname><firstname>Greg</firstname><surname>Lehey</surname></personname><contrib>Originally written by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="vinum-synopsis">
+ <title>Synopsis</title>
+
+
+<para>No matter what disks you have, there are always potential problems:</para>
+ <itemizedlist>
+ <listitem>
+ <para>They can be too small.</para>
+ </listitem>
+
+ <listitem>
+ <para>They can be too slow.</para>
+ </listitem>
+
+ <listitem>
+ <para>They can be too unreliable.</para>
+ </listitem>
+ </itemizedlist>
+
+<para>One way some users safeguard themselves against such issues is
+through the use of multiple, and sometimes redundant, disks.</para>
+
+<para>In addition to supporting various cards and controllers for hardware
+RAID systems, the base FreeBSD system includes the Vinum Volume Manager,
+a block device driver that implements virtual disk drives.</para>
+
+<para>Vinum provides more flexibility, performance, and reliability than
+traditional disk storage, and implements RAID-0, RAID-1, and RAID-5
+models both individually and in combination.</para>
+
+<para>This chapter provides an overview of potential problems with traditional
+disk storage, and an introduction to the Vinum Volume Manager.</para>
+
+ </sect1>
+
+ <sect1 xml:id="vinum-intro">
+ <title>Disks Are Too Small</title>
+
+ <indexterm><primary>Vinum</primary></indexterm>
+ <indexterm><primary>RAID</primary>
+ <secondary>software</secondary></indexterm>
+
+ <para><emphasis>Vinum</emphasis> is a so-called <emphasis>Volume
+ Manager</emphasis>, a virtual disk driver that addresses these
+ three problems. Let us look at them in more detail. Various
+ solutions to these problems have been proposed and
+ implemented:</para>
+
+
+ <para>Disks are getting bigger, but so are data storage
+ requirements. Often you will find you want a file system that
+ is bigger than the disks you have available. Admittedly, this
+ problem is not as acute as it was ten years ago, but it still
+ exists. Some systems have solved this by creating an abstract
+ device which stores its data on a number of disks.</para>
+ </sect1>
+
+ <sect1 xml:id="vinum-access-bottlenecks">
+ <title>Access Bottlenecks</title>
+
+ <para>Modern systems frequently need to access data in a highly
+ concurrent manner. For example, large FTP or HTTP servers can
+ maintain thousands of concurrent sessions and have multiple
+ 100&nbsp;Mbit/s connections to the outside world, well beyond
+ the sustained transfer rate of most disks.</para>
+
+ <para>Current disk drives can transfer data sequentially at up to
+ 70&nbsp;MB/s, but this value is of little importance in an
+ environment where many independent processes access a drive,
+ where they may achieve only a fraction of these values. In such
+ cases it is more interesting to view the problem from the
+ viewpoint of the disk subsystem: the important parameter is the
+ load that a transfer places on the subsystem, in other words the
+ time for which a transfer occupies the drives involved in the
+ transfer.</para>
+
+ <para>In any disk transfer, the drive must first position the
+ heads, wait for the first sector to pass under the read head,
+ and then perform the transfer. These actions can be considered
+ to be atomic: it does not make any sense to interrupt
+ them.</para>
+
+ <para><anchor xml:id="vinum-latency"/> Consider a typical transfer of
+ about 10&nbsp;kB: the current generation of high-performance
+ disks can position the heads in an average of 3.5&nbsp;ms. The
+ fastest drives spin at 15,000&nbsp;rpm, so the average
+ rotational latency (half a revolution) is 2&nbsp;ms. At
+ 70&nbsp;MB/s, the transfer itself takes about 150&nbsp;&mu;s,
+ almost nothing compared to the positioning time. In such a
+ case, the effective transfer rate drops to a little over
+ 1&nbsp;MB/s and is clearly highly dependent on the transfer
+ size.</para>
+
+ <para>The traditional and obvious solution to this bottleneck is
+ <quote>more spindles</quote>: rather than using one large disk,
+ it uses several smaller disks with the same aggregate storage
+ space. Each disk is capable of positioning and transferring
+ independently, so the effective throughput increases by a factor
+ close to the number of disks used.
+ </para>
+
+ <para>The exact throughput improvement is, of course, smaller than
+ the number of disks involved: although each drive is capable of
+ transferring in parallel, there is no way to ensure that the
+ requests are evenly distributed across the drives. Inevitably
+ the load on one drive will be higher than on another.</para>
+
+ <indexterm>
+ <primary>disk concatenation</primary>
+ </indexterm>
+ <indexterm>
+ <primary>Vinum</primary>
+ <secondary>concatenation</secondary>
+ </indexterm>
+
+ <para>The evenness of the load on the disks is strongly dependent
+ on the way the data is shared across the drives. In the
+ following discussion, it is convenient to think of the disk
+ storage as a large number of data sectors which are addressable
+ by number, rather like the pages in a book. The most obvious
+ method is to divide the virtual disk into groups of consecutive
+ sectors the size of the individual physical disks and store them
+ in this manner, rather like taking a large book and tearing it
+ into smaller sections. This method is called
+ <emphasis>concatenation</emphasis> and has the advantage that
+ the disks are not required to have any specific size
+ relationships. It works well when the access to the virtual
+ disk is spread evenly about its address space. When access is
+ concentrated on a smaller area, the improvement is less marked.
+ <xref linkend="vinum-concat"/> illustrates the sequence in which
+ storage units are allocated in a concatenated
+ organization.</para>
+
+ <para>
+ <figure xml:id="vinum-concat">
+ <title>Concatenated Organization</title>
+ <mediaobject><imageobject><imagedata fileref="vinum/vinum-concat"/></imageobject></mediaobject>
+ </figure>
+ </para>
+
+ <indexterm>
+ <primary>disk striping</primary>
+ </indexterm>
+ <indexterm>
+ <primary>Vinum</primary>
+ <secondary>striping</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>RAID</primary>
+ </indexterm>
+
+ <para>An alternative mapping is to divide the address space into
+ smaller, equal-sized components and store them sequentially on
+ different devices. For example, the first 256 sectors may be
+ stored on the first disk, the next 256 sectors on the next disk
+ and so on. After filling the last disk, the process repeats
+ until the disks are full. This mapping is called
+ <emphasis>striping</emphasis> or <acronym>RAID-0</acronym>
+
+ <footnote>
+ <para><acronym>RAID</acronym> stands for <emphasis>Redundant
+ Array of Inexpensive Disks</emphasis> and offers various forms
+ of fault tolerance, though the latter term is somewhat
+ misleading: it provides no redundancy.</para> </footnote>.
+
+ Striping requires somewhat more effort to locate the data, and it
+ can cause additional I/O load where a transfer is spread over
+ multiple disks, but it can also provide a more constant load
+ across the disks. <xref linkend="vinum-striped"/> illustrates the
+ sequence in which storage units are allocated in a striped
+ organization.</para>
+
+ <para>
+ <figure xml:id="vinum-striped">
+ <title>Striped Organization</title>
+ <mediaobject><imageobject><imagedata fileref="vinum/vinum-striped"/></imageobject></mediaobject>
+ </figure>
+ </para>
+ </sect1>
+
+ <sect1 xml:id="vinum-data-integrity">
+ <title>Data Integrity</title>
+
+ <para>The final problem with current disks is that they are
+ unreliable. Although disk drive reliability has increased
+ tremendously over the last few years, they are still the most
+ likely core component of a server to fail. When they do, the
+ results can be catastrophic: replacing a failed disk drive and
+ restoring data to it can take days.</para>
+
+ <indexterm>
+ <primary>disk mirroring</primary>
+ </indexterm>
+ <indexterm>
+ <primary>Vinum</primary>
+ <secondary>mirroring</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>RAID-1</primary>
+ </indexterm>
+
+ <para>The traditional way to approach this problem has been
+ <emphasis>mirroring</emphasis>, keeping two copies of the data
+ on different physical hardware. Since the advent of the
+ <acronym>RAID</acronym> levels, this technique has also been
+ called <acronym>RAID level 1</acronym> or
+ <acronym>RAID-1</acronym>. Any write to the volume writes to
+ both locations; a read can be satisfied from either, so if one
+ drive fails, the data is still available on the other
+ drive.</para>
+
+ <para>Mirroring has two problems:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The price. It requires twice as much disk storage as
+ a non-redundant solution.</para>
+ </listitem>
+
+ <listitem>
+ <para>The performance impact. Writes must be performed to
+ both drives, so they take up twice the bandwidth of a
+ non-mirrored volume. Reads do not suffer from a
+ performance penalty: it even looks as if they are
+ faster.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><indexterm><primary>RAID-5</primary></indexterm>An
+ alternative solution is <emphasis>parity</emphasis>,
+ implemented in the <acronym>RAID</acronym> levels 2, 3, 4 and
+ 5. Of these, <acronym>RAID-5</acronym> is the most
+ interesting. As implemented in Vinum, it is a variant on a
+ striped organization which dedicates one block of each stripe
+ to parity of the other blocks. As implemented by Vinum, a
+ <acronym>RAID-5</acronym> plex is similar to a striped plex,
+ except that it implements <acronym>RAID-5</acronym> by
+ including a parity block in each stripe. As required by
+ <acronym>RAID-5</acronym>, the location of this parity block
+ changes from one stripe to the next. The numbers in the data
+ blocks indicate the relative block numbers.</para>
+
+ <para>
+ <figure xml:id="vinum-raid5-org">
+ <title>RAID-5 Organization</title>
+ <mediaobject><imageobject><imagedata fileref="vinum/vinum-raid5-org"/></imageobject></mediaobject>
+ </figure>
+ </para>
+
+ <para>Compared to mirroring, <acronym>RAID-5</acronym> has the
+ advantage of requiring significantly less storage space. Read
+ access is similar to that of striped organizations, but write
+ access is significantly slower, approximately 25% of the read
+ performance. If one drive fails, the array can continue to
+ operate in degraded mode: a read from one of the remaining
+ accessible drives continues normally, but a read from the
+ failed drive is recalculated from the corresponding block from
+ all the remaining drives.
+ </para>
+ </sect1>
+
+ <sect1 xml:id="vinum-objects">
+ <title>Vinum Objects</title>
+ <para>In order to address these problems, Vinum implements a four-level
+ hierarchy of objects:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The most visible object is the virtual disk, called a
+ <emphasis>volume</emphasis>. Volumes have essentially the same
+ properties as a &unix; disk drive, though there are some minor
+ differences. They have no size limitations.</para>
+ </listitem>
+
+ <listitem>
+ <para>Volumes are composed of <emphasis>plexes</emphasis>,
+ each of which represent the total address space of a
+ volume. This level in the hierarchy thus provides
+ redundancy. Think of plexes as individual disks in a
+ mirrored array, each containing the same data.</para>
+ </listitem>
+
+ <listitem>
+ <para>Since Vinum exists within the &unix; disk storage
+ framework, it would be possible to use &unix;
+ partitions as the building block for multi-disk plexes,
+ but in fact this turns out to be too inflexible:
+ &unix; disks can have only a limited number of
+ partitions. Instead, Vinum subdivides a single
+ &unix; partition (the <emphasis>drive</emphasis>)
+ into contiguous areas called
+ <emphasis>subdisks</emphasis>, which it uses as building
+ blocks for plexes.</para>
+ </listitem>
+
+ <listitem>
+ <para>Subdisks reside on Vinum <emphasis>drives</emphasis>,
+ currently &unix; partitions. Vinum drives can
+ contain any number of subdisks. With the exception of a
+ small area at the beginning of the drive, which is used
+ for storing configuration and state information, the
+ entire drive is available for data storage.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>The following sections describe the way these objects provide the
+ functionality required of Vinum.</para>
+
+ <sect2>
+ <title>Volume Size Considerations</title>
+
+ <para>Plexes can include multiple subdisks spread over all
+ drives in the Vinum configuration. As a result, the size of
+ an individual drive does not limit the size of a plex, and
+ thus of a volume.</para>
+ </sect2>
+
+ <sect2>
+ <title>Redundant Data Storage</title>
+ <para>Vinum implements mirroring by attaching multiple plexes to
+ a volume. Each plex is a representation of the data in a
+ volume. A volume may contain between one and eight
+ plexes.</para>
+
+ <para>Although a plex represents the complete data of a volume,
+ it is possible for parts of the representation to be
+ physically missing, either by design (by not defining a
+ subdisk for parts of the plex) or by accident (as a result of
+ the failure of a drive). As long as at least one plex can
+ provide the data for the complete address range of the volume,
+ the volume is fully functional.</para>
+ </sect2>
+
+ <sect2>
+ <title>Performance Issues</title>
+
+ <para>Vinum implements both concatenation and striping at the
+ plex level:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>A <emphasis>concatenated plex</emphasis> uses the
+ address space of each subdisk in turn.</para>
+ </listitem>
+
+ <listitem>
+ <para>A <emphasis>striped plex</emphasis> stripes the data
+ across each subdisk. The subdisks must all have the same
+ size, and there must be at least two subdisks in order to
+ distinguish it from a concatenated plex.</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>Which Plex Organization?</title>
+ <para>The version of Vinum supplied with FreeBSD &rel.current; implements
+ two kinds of plex:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Concatenated plexes are the most flexible: they can
+ contain any number of subdisks, and the subdisks may be of
+ different length. The plex may be extended by adding
+ additional subdisks. They require less
+ <acronym>CPU</acronym> time than striped plexes, though
+ the difference in <acronym>CPU</acronym> overhead is not
+ measurable. On the other hand, they are most susceptible
+ to hot spots, where one disk is very active and others are
+ idle.</para>
+ </listitem>
+
+ <listitem>
+ <para>The greatest advantage of striped
+ (<acronym>RAID-0</acronym>) plexes is that they reduce hot
+ spots: by choosing an optimum sized stripe (about
+ 256&nbsp;kB), you can even out the load on the component
+ drives. The disadvantages of this approach are
+ (fractionally) more complex code and restrictions on
+ subdisks: they must be all the same size, and extending a
+ plex by adding new subdisks is so complicated that Vinum
+ currently does not implement it. Vinum imposes an
+ additional, trivial restriction: a striped plex must have
+ at least two subdisks, since otherwise it is
+ indistinguishable from a concatenated plex.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><xref linkend="vinum-comparison"/> summarizes the advantages
+ and disadvantages of each plex organization.</para>
+
+ <table xml:id="vinum-comparison" frame="none">
+ <title>Vinum Plex Organizations</title>
+ <tgroup cols="5">
+ <thead>
+ <row>
+ <entry>Plex type</entry>
+ <entry>Minimum subdisks</entry>
+ <entry>Can add subdisks</entry>
+ <entry>Must be equal size</entry>
+ <entry>Application</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>concatenated</entry>
+ <entry>1</entry>
+ <entry>yes</entry>
+ <entry>no</entry>
+ <entry>Large data storage with maximum placement flexibility
+ and moderate performance</entry>
+ </row>
+
+ <row>
+ <entry>striped</entry>
+ <entry>2</entry>
+ <entry>no</entry>
+ <entry>yes</entry>
+ <entry>High performance in combination with highly concurrent
+ access</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="vinum-examples">
+ <title>Some Examples</title>
+
+ <para>Vinum maintains a <emphasis>configuration
+ database</emphasis> which describes the objects known to an
+ individual system. Initially, the user creates the
+ configuration database from one or more configuration files with
+ the aid of the &man.vinum.8; utility program. Vinum stores a
+ copy of its configuration database on each disk slice (which
+ Vinum calls a <emphasis>device</emphasis>) under its control.
+ This database is updated on each state change, so that a restart
+ accurately restores the state of each Vinum object.</para>
+
+ <sect2>
+ <title>The Configuration File</title>
+ <para>The configuration file describes individual Vinum objects. The
+ definition of a simple volume might be:</para>
+
+ <programlisting>
+ drive a device /dev/da3h
+ volume myvol
+ plex org concat
+ sd length 512m drive a</programlisting>
+
+ <para>This file describes four Vinum objects:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The <emphasis>drive</emphasis> line describes a disk
+ partition (<emphasis>drive</emphasis>) and its location
+ relative to the underlying hardware. It is given the
+ symbolic name <emphasis>a</emphasis>. This separation of
+ the symbolic names from the device names allows disks to
+ be moved from one location to another without
+ confusion.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <emphasis>volume</emphasis> line describes a volume.
+ The only required attribute is the name, in this case
+ <emphasis>myvol</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <emphasis>plex</emphasis> line defines a plex.
+ The only required parameter is the organization, in this
+ case <emphasis>concat</emphasis>. No name is necessary:
+ the system automatically generates a name from the volume
+ name by adding the suffix
+ <emphasis>.p</emphasis><emphasis>x</emphasis>, where
+ <emphasis>x</emphasis> is the number of the plex in the
+ volume. Thus this plex will be called
+ <emphasis>myvol.p0</emphasis>.</para>
+ </listitem>
+
+ <listitem>
+ <para>The <emphasis>sd</emphasis> line describes a subdisk.
+ The minimum specifications are the name of a drive on
+ which to store it, and the length of the subdisk. As with
+ plexes, no name is necessary: the system automatically
+ assigns names derived from the plex name by adding the
+ suffix <emphasis>.s</emphasis><emphasis>x</emphasis>,
+ where <emphasis>x</emphasis> is the number of the subdisk
+ in the plex. Thus Vinum gives this subdisk the name
+ <emphasis>myvol.p0.s0</emphasis>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>After processing this file, &man.vinum.8; produces the following
+ output:</para>
+
+ <programlisting width="97">
+ &prompt.root; vinum -&gt; <userinput>create config1</userinput>
+ Configuration summary
+ Drives: 1 (4 configured)
+ Volumes: 1 (4 configured)
+ Plexes: 1 (8 configured)
+ Subdisks: 1 (16 configured)
+
+ D a State: up Device /dev/da3h Avail: 2061/2573 MB (80%)
+
+ V myvol State: up Plexes: 1 Size: 512 MB
+
+ P myvol.p0 C State: up Subdisks: 1 Size: 512 MB
+
+ S myvol.p0.s0 State: up PO: 0 B Size: 512 MB</programlisting>
+
+ <para>This output shows the brief listing format of &man.vinum.8;. It
+ is represented graphically in <xref linkend="vinum-simple-vol"/>.</para>
+
+ <para>
+ <figure xml:id="vinum-simple-vol">
+ <title>A Simple Vinum Volume</title>
+ <mediaobject><imageobject><imagedata fileref="vinum/vinum-simple-vol"/></imageobject></mediaobject>
+ </figure>
+ </para>
+
+ <para>This figure, and the ones which follow, represent a
+ volume, which contains the plexes, which in turn contain the
+ subdisks. In this trivial example, the volume contains one
+ plex, and the plex contains one subdisk.</para>
+
+ <para>This particular volume has no specific advantage over a
+ conventional disk partition. It contains a single plex, so it
+ is not redundant. The plex contains a single subdisk, so
+ there is no difference in storage allocation from a
+ conventional disk partition. The following sections
+ illustrate various more interesting configuration
+ methods.</para>
+ </sect2>
+
+ <sect2>
+ <title>Increased Resilience: Mirroring</title>
+
+ <para>The resilience of a volume can be increased by mirroring.
+ When laying out a mirrored volume, it is important to ensure
+ that the subdisks of each plex are on different drives, so
+ that a drive failure will not take down both plexes. The
+ following configuration mirrors a volume:</para>
+
+ <programlisting>
+ drive b device /dev/da4h
+ volume mirror
+ plex org concat
+ sd length 512m drive a
+ plex org concat
+ sd length 512m drive b</programlisting>
+
+ <para>In this example, it was not necessary to specify a
+ definition of drive <emphasis>a</emphasis> again, since Vinum
+ keeps track of all objects in its configuration database.
+ After processing this definition, the configuration looks
+ like:</para>
+
+
+ <programlisting width="97">
+ Drives: 2 (4 configured)
+ Volumes: 2 (4 configured)
+ Plexes: 3 (8 configured)
+ Subdisks: 3 (16 configured)
+
+ D a State: up Device /dev/da3h Avail: 1549/2573 MB (60%)
+ D b State: up Device /dev/da4h Avail: 2061/2573 MB (80%)
+
+ V myvol State: up Plexes: 1 Size: 512 MB
+ V mirror State: up Plexes: 2 Size: 512 MB
+
+ P myvol.p0 C State: up Subdisks: 1 Size: 512 MB
+ P mirror.p0 C State: up Subdisks: 1 Size: 512 MB
+ P mirror.p1 C State: initializing Subdisks: 1 Size: 512 MB
+
+ S myvol.p0.s0 State: up PO: 0 B Size: 512 MB
+ S mirror.p0.s0 State: up PO: 0 B Size: 512 MB
+ S mirror.p1.s0 State: empty PO: 0 B Size: 512 MB</programlisting>
+
+ <para><xref linkend="vinum-mirrored-vol"/> shows the structure
+ graphically.</para>
+
+ <para>
+ <figure xml:id="vinum-mirrored-vol">
+ <title>A Mirrored Vinum Volume</title>
+ <mediaobject><imageobject><imagedata fileref="vinum/vinum-mirrored-vol"/></imageobject></mediaobject>
+ </figure>
+ </para>
+
+ <para>In this example, each plex contains the full 512&nbsp;MB
+ of address space. As in the previous example, each plex
+ contains only a single subdisk.</para>
+ </sect2>
+
+ <sect2>
+ <title>Optimizing Performance</title>
+
+ <para>The mirrored volume in the previous example is more
+ resistant to failure than an unmirrored volume, but its
+ performance is less: each write to the volume requires a write
+ to both drives, using up a greater proportion of the total
+ disk bandwidth. Performance considerations demand a different
+ approach: instead of mirroring, the data is striped across as
+ many disk drives as possible. The following configuration
+ shows a volume with a plex striped across four disk
+ drives:</para>
+
+ <programlisting>
+ drive c device /dev/da5h
+ drive d device /dev/da6h
+ volume stripe
+ plex org striped 512k
+ sd length 128m drive a
+ sd length 128m drive b
+ sd length 128m drive c
+ sd length 128m drive d</programlisting>
+
+ <para>As before, it is not necessary to define the drives which are
+ already known to Vinum. After processing this definition, the
+ configuration looks like:</para>
+
+ <programlisting width="92">
+ Drives: 4 (4 configured)
+ Volumes: 3 (4 configured)
+ Plexes: 4 (8 configured)
+ Subdisks: 7 (16 configured)
+
+ D a State: up Device /dev/da3h Avail: 1421/2573 MB (55%)
+ D b State: up Device /dev/da4h Avail: 1933/2573 MB (75%)
+ D c State: up Device /dev/da5h Avail: 2445/2573 MB (95%)
+ D d State: up Device /dev/da6h Avail: 2445/2573 MB (95%)
+
+ V myvol State: up Plexes: 1 Size: 512 MB
+ V mirror State: up Plexes: 2 Size: 512 MB
+ V striped State: up Plexes: 1 Size: 512 MB
+
+ P myvol.p0 C State: up Subdisks: 1 Size: 512 MB
+ P mirror.p0 C State: up Subdisks: 1 Size: 512 MB
+ P mirror.p1 C State: initializing Subdisks: 1 Size: 512 MB
+ P striped.p1 State: up Subdisks: 1 Size: 512 MB
+
+ S myvol.p0.s0 State: up PO: 0 B Size: 512 MB
+ S mirror.p0.s0 State: up PO: 0 B Size: 512 MB
+ S mirror.p1.s0 State: empty PO: 0 B Size: 512 MB
+ S striped.p0.s0 State: up PO: 0 B Size: 128 MB
+ S striped.p0.s1 State: up PO: 512 kB Size: 128 MB
+ S striped.p0.s2 State: up PO: 1024 kB Size: 128 MB
+ S striped.p0.s3 State: up PO: 1536 kB Size: 128 MB</programlisting>
+
+ <para>
+ <figure xml:id="vinum-striped-vol">
+ <title>A Striped Vinum Volume</title>
+ <mediaobject><imageobject><imagedata fileref="vinum/vinum-striped-vol"/></imageobject></mediaobject>
+ </figure>
+ </para>
+
+ <para>This volume is represented in
+ <xref linkend="vinum-striped-vol"/>. The darkness of the stripes
+ indicates the position within the plex address space: the lightest stripes
+ come first, the darkest last.</para>
+ </sect2>
+
+ <sect2>
+ <title>Resilience and Performance</title>
+
+ <para><anchor xml:id="vinum-resilience"/>With sufficient hardware, it
+ is possible to build volumes which show both increased
+ resilience and increased performance compared to standard
+ &unix; partitions. A typical configuration file might
+ be:</para>
+
+ <programlisting>
+ volume raid10
+ plex org striped 512k
+ sd length 102480k drive a
+ sd length 102480k drive b
+ sd length 102480k drive c
+ sd length 102480k drive d
+ sd length 102480k drive e
+ plex org striped 512k
+ sd length 102480k drive c
+ sd length 102480k drive d
+ sd length 102480k drive e
+ sd length 102480k drive a
+ sd length 102480k drive b</programlisting>
+
+ <para>The subdisks of the second plex are offset by two drives from those
+ of the first plex: this helps ensure that writes do not go to the same
+ subdisks even if a transfer goes over two drives.</para>
+
+ <para><xref linkend="vinum-raid10-vol"/> represents the structure
+ of this volume.</para>
+
+ <para>
+ <figure xml:id="vinum-raid10-vol">
+ <title>A Mirrored, Striped Vinum Volume</title>
+ <mediaobject><imageobject><imagedata fileref="vinum/vinum-raid10-vol"/></imageobject></mediaobject>
+ </figure>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="vinum-object-naming">
+ <title>Object Naming</title>
+
+ <para>As described above, Vinum assigns default names to plexes
+ and subdisks, although they may be overridden. Overriding the
+ default names is not recommended: experience with the VERITAS
+ volume manager, which allows arbitrary naming of objects, has
+ shown that this flexibility does not bring a significant
+ advantage, and it can cause confusion.</para>
+
+ <para>Names may contain any non-blank character, but it is
+ recommended to restrict them to letters, digits and the
+ underscore characters. The names of volumes, plexes and
+ subdisks may be up to 64 characters long, and the names of
+ drives may be up to 32 characters long.</para>
+
+ <para>Vinum objects are assigned device nodes in the hierarchy
+ <filename>/dev/vinum</filename>. The configuration shown above
+ would cause Vinum to create the following device nodes:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The control devices
+ <filename>/dev/vinum/control</filename> and
+ <filename>/dev/vinum/controld</filename>, which are used
+ by &man.vinum.8; and the Vinum daemon respectively.</para>
+ </listitem>
+
+ <listitem>
+ <para>Block and character device entries for each volume.
+ These are the main devices used by Vinum. The block device
+ names are the name of the volume, while the character device
+ names follow the BSD tradition of prepending the letter
+ <emphasis>r</emphasis> to the name. Thus the configuration
+ above would include the block devices
+ <filename>/dev/vinum/myvol</filename>,
+ <filename>/dev/vinum/mirror</filename>,
+ <filename>/dev/vinum/striped</filename>,
+ <filename>/dev/vinum/raid5</filename> and
+ <filename>/dev/vinum/raid10</filename>, and the
+ character devices
+ <filename>/dev/vinum/rmyvol</filename>,
+ <filename>/dev/vinum/rmirror</filename>,
+ <filename>/dev/vinum/rstriped</filename>,
+ <filename>/dev/vinum/rraid5</filename> and
+ <filename>/dev/vinum/rraid10</filename>. There is
+ obviously a problem here: it is possible to have two volumes
+ called <emphasis>r</emphasis> and <emphasis>rr</emphasis>,
+ but there will be a conflict creating the device node
+ <filename>/dev/vinum/rr</filename>: is it a character
+ device for volume <emphasis>r</emphasis> or a block device
+ for volume <emphasis>rr</emphasis>? Currently Vinum does
+ not address this conflict: the first-defined volume will get
+ the name.</para>
+ </listitem>
+
+ <listitem>
+ <para>A directory <filename>/dev/vinum/drive</filename>
+ with entries for each drive. These entries are in fact
+ symbolic links to the corresponding disk nodes.</para>
+ </listitem>
+
+ <listitem>
+ <para>A directory <filename>/dev/vinum/volume</filename> with
+ entries for each volume. It contains subdirectories for
+ each plex, which in turn contain subdirectories for their
+ component subdisks.</para>
+ </listitem>
+
+ <listitem>
+ <para>The directories
+ <filename>/dev/vinum/plex</filename>,
+ <filename>/dev/vinum/sd</filename>, and
+ <filename>/dev/vinum/rsd</filename>, which contain block
+ device nodes for each plex and block and character device
+ nodes respectively for each subdisk.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>For example, consider the following configuration file:</para>
+ <programlisting>
+ drive drive1 device /dev/sd1h
+ drive drive2 device /dev/sd2h
+ drive drive3 device /dev/sd3h
+ drive drive4 device /dev/sd4h
+ volume s64 setupstate
+ plex org striped 64k
+ sd length 100m drive drive1
+ sd length 100m drive drive2
+ sd length 100m drive drive3
+ sd length 100m drive drive4</programlisting>
+
+ <para>After processing this file, &man.vinum.8; creates the following
+ structure in <filename>/dev/vinum</filename>:</para>
+
+ <programlisting>
+ brwx------ 1 root wheel 25, 0x40000001 Apr 13 16:46 Control
+ brwx------ 1 root wheel 25, 0x40000002 Apr 13 16:46 control
+ brwx------ 1 root wheel 25, 0x40000000 Apr 13 16:46 controld
+ drwxr-xr-x 2 root wheel 512 Apr 13 16:46 drive
+ drwxr-xr-x 2 root wheel 512 Apr 13 16:46 plex
+ crwxr-xr-- 1 root wheel 91, 2 Apr 13 16:46 rs64
+ drwxr-xr-x 2 root wheel 512 Apr 13 16:46 rsd
+ drwxr-xr-x 2 root wheel 512 Apr 13 16:46 rvol
+ brwxr-xr-- 1 root wheel 25, 2 Apr 13 16:46 s64
+ drwxr-xr-x 2 root wheel 512 Apr 13 16:46 sd
+ drwxr-xr-x 3 root wheel 512 Apr 13 16:46 vol
+
+ /dev/vinum/drive:
+ total 0
+ lrwxr-xr-x 1 root wheel 9 Apr 13 16:46 drive1 -&gt; /dev/sd1h
+ lrwxr-xr-x 1 root wheel 9 Apr 13 16:46 drive2 -&gt; /dev/sd2h
+ lrwxr-xr-x 1 root wheel 9 Apr 13 16:46 drive3 -&gt; /dev/sd3h
+ lrwxr-xr-x 1 root wheel 9 Apr 13 16:46 drive4 -&gt; /dev/sd4h
+
+ /dev/vinum/plex:
+ total 0
+ brwxr-xr-- 1 root wheel 25, 0x10000002 Apr 13 16:46 s64.p0
+
+ /dev/vinum/rsd:
+ total 0
+ crwxr-xr-- 1 root wheel 91, 0x20000002 Apr 13 16:46 s64.p0.s0
+ crwxr-xr-- 1 root wheel 91, 0x20100002 Apr 13 16:46 s64.p0.s1
+ crwxr-xr-- 1 root wheel 91, 0x20200002 Apr 13 16:46 s64.p0.s2
+ crwxr-xr-- 1 root wheel 91, 0x20300002 Apr 13 16:46 s64.p0.s3
+
+ /dev/vinum/rvol:
+ total 0
+ crwxr-xr-- 1 root wheel 91, 2 Apr 13 16:46 s64
+
+ /dev/vinum/sd:
+ total 0
+ brwxr-xr-- 1 root wheel 25, 0x20000002 Apr 13 16:46 s64.p0.s0
+ brwxr-xr-- 1 root wheel 25, 0x20100002 Apr 13 16:46 s64.p0.s1
+ brwxr-xr-- 1 root wheel 25, 0x20200002 Apr 13 16:46 s64.p0.s2
+ brwxr-xr-- 1 root wheel 25, 0x20300002 Apr 13 16:46 s64.p0.s3
+
+ /dev/vinum/vol:
+ total 1
+ brwxr-xr-- 1 root wheel 25, 2 Apr 13 16:46 s64
+ drwxr-xr-x 3 root wheel 512 Apr 13 16:46 s64.plex
+
+ /dev/vinum/vol/s64.plex:
+ total 1
+ brwxr-xr-- 1 root wheel 25, 0x10000002 Apr 13 16:46 s64.p0
+ drwxr-xr-x 2 root wheel 512 Apr 13 16:46 s64.p0.sd
+
+ /dev/vinum/vol/s64.plex/s64.p0.sd:
+ total 0
+ brwxr-xr-- 1 root wheel 25, 0x20000002 Apr 13 16:46 s64.p0.s0
+ brwxr-xr-- 1 root wheel 25, 0x20100002 Apr 13 16:46 s64.p0.s1
+ brwxr-xr-- 1 root wheel 25, 0x20200002 Apr 13 16:46 s64.p0.s2
+ brwxr-xr-- 1 root wheel 25, 0x20300002 Apr 13 16:46 s64.p0.s3</programlisting>
+
+ <para>Although it is recommended that plexes and subdisks should
+ not be allocated specific names, Vinum drives must be named.
+ This makes it possible to move a drive to a different location
+ and still recognize it automatically. Drive names may be up to
+ 32 characters long.</para>
+
+ <sect2>
+ <title>Creating File Systems</title>
+
+ <para>Volumes appear to the system to be identical to disks,
+ with one exception. Unlike &unix; drives, Vinum does
+ not partition volumes, which thus do not contain a partition
+ table. This has required modification to some disk
+ utilities, notably &man.newfs.8;, which previously tried to
+ interpret the last letter of a Vinum volume name as a
+ partition identifier. For example, a disk drive may have a
+ name like <filename>/dev/ad0a</filename> or
+ <filename>/dev/da2h</filename>. These names represent
+ the first partition (<filename>a</filename>) on the
+ first (0) IDE disk (<filename>ad</filename>) and the
+ eighth partition (<filename>h</filename>) on the third
+ (2) SCSI disk (<filename>da</filename>) respectively.
+ By contrast, a Vinum volume might be called
+ <filename>/dev/vinum/concat</filename>, a name which has
+ no relationship with a partition name.</para>
+
+ <para>Normally, &man.newfs.8; interprets the name of the disk and
+ complains if it cannot understand it. For example:</para>
+
+ <screen>&prompt.root; <userinput>newfs /dev/vinum/concat</userinput>
+newfs: /dev/vinum/concat: can't figure out file system partition</screen>
+
+ <note><para>The following is only valid for FreeBSD versions
+ prior to 5.0:</para></note>
+
+ <para>In order to create a file system on this volume, use the
+ <option>-v</option> option to &man.newfs.8;:</para>
+
+ <screen>&prompt.root; <userinput>newfs -v /dev/vinum/concat</userinput></screen>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="vinum-config">
+ <title>Configuring Vinum</title>
+
+ <para>The <filename>GENERIC</filename> kernel does not contain
+ Vinum. It is possible to build a special kernel which includes
+ Vinum, but this is not recommended. The standard way to start
+ Vinum is as a kernel module (<acronym>kld</acronym>). You do
+ not even need to use &man.kldload.8; for Vinum: when you start
+ &man.vinum.8;, it checks whether the module has been loaded, and
+ if it is not, it loads it automatically.</para>
+
+
+ <sect2>
+ <title>Startup</title>
+
+ <para>Vinum stores configuration information on the disk slices
+ in essentially the same form as in the configuration files.
+ When reading from the configuration database, Vinum recognizes
+ a number of keywords which are not allowed in the
+ configuration files. For example, a disk configuration might
+ contain the following text:</para>
+
+ <programlisting width="119">volume myvol state up
+volume bigraid state down
+plex name myvol.p0 state up org concat vol myvol
+plex name myvol.p1 state up org concat vol myvol
+plex name myvol.p2 state init org striped 512b vol myvol
+plex name bigraid.p0 state initializing org raid5 512b vol bigraid
+sd name myvol.p0.s0 drive a plex myvol.p0 state up len 1048576b driveoffset 265b plexoffset 0b
+sd name myvol.p0.s1 drive b plex myvol.p0 state up len 1048576b driveoffset 265b plexoffset 1048576b
+sd name myvol.p1.s0 drive c plex myvol.p1 state up len 1048576b driveoffset 265b plexoffset 0b
+sd name myvol.p1.s1 drive d plex myvol.p1 state up len 1048576b driveoffset 265b plexoffset 1048576b
+sd name myvol.p2.s0 drive a plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 0b
+sd name myvol.p2.s1 drive b plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 524288b
+sd name myvol.p2.s2 drive c plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 1048576b
+sd name myvol.p2.s3 drive d plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 1572864b
+sd name bigraid.p0.s0 drive a plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 0b
+sd name bigraid.p0.s1 drive b plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 4194304b
+sd name bigraid.p0.s2 drive c plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 8388608b
+sd name bigraid.p0.s3 drive d plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 12582912b
+sd name bigraid.p0.s4 drive e plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 16777216b</programlisting>
+
+ <para>The obvious differences here are the presence of
+ explicit location information and naming (both of which are
+ also allowed, but discouraged, for use by the user) and the
+ information on the states (which are not available to the
+ user). Vinum does not store information about drives in the
+ configuration information: it finds the drives by scanning
+ the configured disk drives for partitions with a Vinum
+ label. This enables Vinum to identify drives correctly even
+ if they have been assigned different &unix; drive
+ IDs.</para>
+
+ <sect3 xml:id="vinum-rc-startup">
+ <title>Automatic Startup</title>
+
+ <para>In order to start Vinum automatically when you boot the
+ system, ensure that you have the following line in your
+ <filename>/etc/rc.conf</filename>:</para>
+
+ <programlisting>start_vinum="YES" # set to YES to start vinum</programlisting>
+
+ <para>If you do not have a file
+ <filename>/etc/rc.conf</filename>, create one with this
+ content. This will cause the system to load the Vinum
+ <acronym>kld</acronym> at startup, and to start any objects
+ mentioned in the configuration. This is done before
+ mounting file systems, so it is possible to automatically
+ &man.fsck.8; and mount file systems on Vinum volumes.</para>
+
+ <para>When you start Vinum with the <command>vinum
+ start</command> command, Vinum reads the configuration
+ database from one of the Vinum drives. Under normal
+ circumstances, each drive contains an identical copy of the
+ configuration database, so it does not matter which drive is
+ read. After a crash, however, Vinum must determine which
+ drive was updated most recently and read the configuration
+ from this drive. It then updates the configuration if
+ necessary from progressively older drives.</para>
+
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="vinum-root">
+ <title>Using Vinum for the Root Filesystem</title>
+
+ <para>For a machine that has fully-mirrored filesystems using
+ Vinum, it is desirable to also mirror the root filesystem.
+ Setting up such a configuration is less trivial than mirroring
+ an arbitrary filesystem because:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The root filesystem must be available very early during
+ the boot process, so the Vinum infrastructure must already be
+ available at this time.</para>
+ </listitem>
+ <listitem>
+ <para>The volume containing the root filesystem also contains
+ the system bootstrap and the kernel, which must be read
+ using the host system's native utilities (e. g. the BIOS on
+ PC-class machines) which often cannot be taught about the
+ details of Vinum.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>In the following sections, the term <quote>root
+ volume</quote> is generally used to describe the Vinum volume
+ that contains the root filesystem. It is probably a good idea
+ to use the name <literal>"root"</literal> for this volume, but
+ this is not technically required in any way. All command
+ examples in the following sections assume this name though.</para>
+
+ <sect2>
+ <title>Starting up Vinum Early Enough for the Root
+ Filesystem</title>
+
+ <para>There are several measures to take for this to
+ happen:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Vinum must be available in the kernel at boot-time.
+ Thus, the method to start Vinum automatically described in
+ <xref linkend="vinum-rc-startup"/> is not applicable to
+ accomplish this task, and the
+ <literal>start_vinum</literal> parameter must actually
+ <emphasis>not</emphasis> be set when the following setup
+ is being arranged. The first option would be to compile
+ Vinum statically into the kernel, so it is available all
+ the time, but this is usually not desirable. There is
+ another option as well, to have
+ <filename>/boot/loader</filename> (<xref linkend="boot-loader"/>) load the vinum kernel module
+ early, before starting the kernel. This can be
+ accomplished by putting the line:</para>
+
+ <programlisting>vinum_load="YES"</programlisting>
+
+ <para>into the file
+ <filename>/boot/loader.conf</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Vinum must be initialized early since it needs to
+ supply the volume for the root filesystem. By default,
+ the Vinum kernel part is not looking for drives that might
+ contain Vinum volume information until the administrator
+ (or one of the startup scripts) issues a <command>vinum
+ start</command> command.</para>
+
+ <note><para>The following paragraphs are outlining the steps
+ needed for FreeBSD 5.X and above. The setup required for
+ FreeBSD 4.X differs, and is described below in <xref linkend="vinum-root-4x"/>.</para></note>
+
+ <para>By placing the line:</para>
+
+ <programlisting>vinum.autostart="YES"</programlisting>
+
+ <para>into <filename>/boot/loader.conf</filename>, Vinum is
+ instructed to automatically scan all drives for Vinum
+ information as part of the kernel startup.</para>
+
+ <para>Note that it is not necessary to instruct the kernel
+ where to look for the root filesystem.
+ <filename>/boot/loader</filename> looks up the name of the
+ root device in <filename>/etc/fstab</filename>, and passes
+ this information on to the kernel. When it comes to mount
+ the root filesystem, the kernel figures out from the
+ device name provided which driver to ask to translate this
+ into the internal device ID (major/minor number).</para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>Making a Vinum-based Root Volume Accessible to the
+ Bootstrap</title>
+
+ <para>Since the current FreeBSD bootstrap is only 7.5 KB of
+ code, and already has the burden of reading files (like
+ <filename>/boot/loader</filename>) from the UFS filesystem, it
+ is sheer impossible to also teach it about internal Vinum
+ structures so it could parse the Vinum configuration data, and
+ figure out about the elements of a boot volume itself. Thus,
+ some tricks are necessary to provide the bootstrap code with
+ the illusion of a standard <literal>"a"</literal> partition
+ that contains the root filesystem.</para>
+
+ <para>For this to be possible at all, the following requirements
+ must be met for the root volume:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The root volume must not be striped or RAID-5.</para>
+ </listitem>
+
+ <listitem>
+ <para>The root volume must not contain more than one
+ concatenated subdisk per plex.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Note that it is desirable and possible that there are
+ multiple plexes, each containing one replica of the root
+ filesystem. The bootstrap process will, however, only use one
+ of these replica for finding the bootstrap and all the files,
+ until the kernel will eventually mount the root filesystem
+ itself. Each single subdisk within these plexes will then
+ need its own <literal>"a"</literal> partition illusion, for
+ the respective device to become bootable. It is not strictly
+ needed that each of these faked <literal>"a"</literal>
+ partitions is located at the same offset within its device,
+ compared with other devices containing plexes of the root
+ volume. However, it is probably a good idea to create the
+ Vinum volumes that way so the resulting mirrored devices are
+ symmetric, to avoid confusion.</para>
+
+ <para>In order to set up these <literal>"a"</literal> partitions,
+ for each device containing part of the root volume, the
+ following needs to be done:</para>
+
+ <procedure>
+ <step>
+ <para>The location (offset from the beginning of the device)
+ and size of this device's subdisk that is part of the root
+ volume need to be examined, using the command:</para>
+
+ <screen>&prompt.root; <userinput>vinum l -rv root</userinput></screen>
+
+ <para>Note that Vinum offsets and sizes are measured in
+ bytes. They must be divided by 512 in order to obtain the
+ block numbers that are to be used in the
+ <command>disklabel</command> command.</para>
+ </step>
+
+ <step>
+ <para>Run the command:</para>
+
+ <screen>&prompt.root; <userinput>disklabel -e devname</userinput></screen>
+
+ <para>for each device that participates in the root volume.
+ <replaceable>devname</replaceable> must be either the name
+ of the disk (like <filename>da0</filename>) for disks
+ without a slice (aka. fdisk) table, or the name of the
+ slice (like <filename>ad0s1</filename>).</para>
+
+ <para>If there is already an <literal>"a"</literal>
+ partition on the device (presumably, containing a
+ pre-Vinum root filesystem), it should be renamed to
+ something else, so it remains accessible (just in case),
+ but will no longer be used by default to bootstrap the
+ system. Note that active partitions (like a root
+ filesystem currently mounted) cannot be renamed, so this
+ must be executed either when being booted from a
+ <quote>Fixit</quote> medium, or in a two-step process,
+ where (in a mirrored situation) the disk that has not been
+ currently booted is being manipulated first.</para>
+
+ <para>Then, the offset the Vinum partition on this
+ device (if any) must be added to the offset of the
+ respective root volume subdisk on this device. The
+ resulting value will become the
+ <literal>"offset"</literal> value for the new
+ <literal>"a"</literal> partition. The
+ <literal>"size"</literal> value for this partition can be
+ taken verbatim from the calculation above. The
+ <literal>"fstype"</literal> should be
+ <literal>4.2BSD</literal>. The
+ <literal>"fsize"</literal>, <literal>"bsize"</literal>,
+ and <literal>"cpg"</literal> values should best be chosen
+ to match the actual filesystem, though they are fairly
+ unimportant within this context.</para>
+
+ <para>That way, a new <literal>"a"</literal> partition will
+ be established that overlaps the Vinum partition on this
+ device. Note that the <command>disklabel</command> will
+ only allow for this overlap if the Vinum partition has
+ properly been marked using the <literal>"vinum"</literal>
+ fstype.</para>
+ </step>
+
+ <step>
+ <para>That's all! A faked <literal>"a"</literal> partition
+ does exist now on each device that has one replica of the
+ root volume. It is highly recommendable to verify the
+ result again, using a command like:</para>
+
+ <screen>&prompt.root; <userinput>fsck -n /dev/devnamea</userinput></screen>
+ </step>
+ </procedure>
+
+ <para>It should be remembered that all files containing control
+ information must be relative to the root filesystem in the
+ Vinum volume which, when setting up a new Vinum root volume,
+ might not match the root filesystem that is currently active.
+ So in particular, the files <filename>/etc/fstab</filename>
+ and <filename>/boot/loader.conf</filename> need to be taken
+ care of.</para>
+
+ <para>At next reboot, the bootstrap should figure out the
+ appropriate control information from the new Vinum-based root
+ filesystem, and act accordingly. At the end of the kernel
+ initialization process, after all devices have been announced,
+ the prominent notice that shows the success of this setup is a
+ message like:</para>
+
+ <screen>Mounting root from ufs:/dev/vinum/root</screen>
+ </sect2>
+
+ <sect2>
+ <title>Example of a Vinum-based Root Setup</title>
+
+ <para>After the Vinum root volume has been set up, the output of
+ <command>vinum l -rv root</command> could look like:</para>
+
+ <screen>
+...
+Subdisk root.p0.s0:
+ Size: 125829120 bytes (120 MB)
+ State: up
+ Plex root.p0 at offset 0 (0 B)
+ Drive disk0 (/dev/da0h) at offset 135680 (132 kB)
+
+Subdisk root.p1.s0:
+ Size: 125829120 bytes (120 MB)
+ State: up
+ Plex root.p1 at offset 0 (0 B)
+ Drive disk1 (/dev/da1h) at offset 135680 (132 kB)
+ </screen>
+
+ <para>The values to note are <literal>135680</literal> for the
+ offset (relative to partition
+ <filename>/dev/da0h</filename>). This translates to 265
+ 512-byte disk blocks in <command>disklabel</command>'s terms.
+ Likewise, the size of this root volume is 245760 512-byte
+ blocks. <filename>/dev/da1h</filename>, containing the
+ second replica of this root volume, has a symmetric
+ setup.</para>
+
+ <para>The disklabel for these devices might look like:</para>
+
+ <screen>
+...
+8 partitions:
+# size offset fstype [fsize bsize bps/cpg]
+ a: 245760 281 4.2BSD 2048 16384 0 # (Cyl. 0*- 15*)
+ c: 71771688 0 unused 0 0 # (Cyl. 0 - 4467*)
+ h: 71771672 16 vinum # (Cyl. 0*- 4467*)
+ </screen>
+
+ <para>It can be observed that the <literal>"size"</literal>
+ parameter for the faked <literal>"a"</literal> partition
+ matches the value outlined above, while the
+ <literal>"offset"</literal> parameter is the sum of the offset
+ within the Vinum partition <literal>"h"</literal>, and the
+ offset of this partition within the device (or slice). This
+ is a typical setup that is necessary to avoid the problem
+ described in <xref linkend="vinum-root-panic"/>. It can also
+ be seen that the entire <literal>"a"</literal> partition is
+ completely within the <literal>"h"</literal> partition
+ containing all the Vinum data for this device.</para>
+
+ <para>Note that in the above example, the entire device is
+ dedicated to Vinum, and there is no leftover pre-Vinum root
+ partition, since this has been a newly set-up disk that was
+ only meant to be part of a Vinum configuration, ever.</para>
+ </sect2>
+
+ <sect2>
+ <title>Troubleshooting</title>
+
+ <para>If something goes wrong, a way is needed to recover from
+ the situation. The following list contains few known pitfalls
+ and solutions.</para>
+
+ <sect3>
+ <title>System Bootstrap Loads, but System Does Not Boot</title>
+
+ <para>If for any reason the system does not continue to boot,
+ the bootstrap can be interrupted with by pressing the
+ <keycap>space</keycap> key at the 10-seconds warning. The
+ loader variables (like <literal>vinum.autostart</literal>)
+ can be examined using the <command>show</command>, and
+ manipulated using <command>set</command> or
+ <command>unset</command> commands.</para>
+
+ <para>If the only problem was that the Vinum kernel module was
+ not yet in the list of modules to load automatically, a
+ simple <command>load vinum</command> will help.</para>
+
+ <para>When ready, the boot process can be continued with a
+ <command>boot -as</command>. The options
+ <option>-as</option> will request the kernel to ask for the
+ root filesystem to mount (<option>-a</option>), and make the
+ boot process stop in single-user mode (<option>-s</option>),
+ where the root filesystem is mounted read-only. That way,
+ even if only one plex of a multi-plex volume has been
+ mounted, no data inconsistency between plexes is being
+ risked.</para>
+
+ <para>At the prompt asking for a root filesystem to mount, any
+ device that contains a valid root filesystem can be entered.
+ If <filename>/etc/fstab</filename> had been set up
+ correctly, the default should be something like
+ <literal>ufs:/dev/vinum/root</literal>. A typical alternate
+ choice would be something like
+ <literal>ufs:da0d</literal> which could be a
+ hypothetical partition that contains the pre-Vinum root
+ filesystem. Care should be taken if one of the alias
+ <literal>"a"</literal> partitions are entered here that are
+ actually reference to the subdisks of the Vinum root device,
+ because in a mirrored setup, this would only mount one piece
+ of a mirrored root device. If this filesystem is to be
+ mounted read-write later on, it is necessary to remove the
+ other plex(es) of the Vinum root volume since these plexes
+ would otherwise carry inconsistent data.</para>
+ </sect3>
+
+ <sect3>
+ <title>Only Primary Bootstrap Loads</title>
+
+ <para>If <filename>/boot/loader</filename> fails to load, but
+ the primary bootstrap still loads (visible by a single dash
+ in the left column of the screen right after the boot
+ process starts), an attempt can be made to interrupt the
+ primary bootstrap at this point, using the
+ <keycap>space</keycap> key. This will make the bootstrap
+ stop in stage two, see <xref linkend="boot-boot1"/>. An
+ attempt can be made here to boot off an alternate partition,
+ like the partition containing the previous root filesystem
+ that has been moved away from <literal>"a"</literal>
+ above.</para>
+ </sect3>
+
+ <sect3 xml:id="vinum-root-panic">
+ <title>Nothing Boots, the Bootstrap
+ Panics</title>
+
+ <para>This situation will happen if the bootstrap had been
+ destroyed by the Vinum installation. Unfortunately, Vinum
+ accidentally currently leaves only 4 KB at the beginning of
+ its partition free before starting to write its Vinum header
+ information. However, the stage one and two bootstraps plus
+ the disklabel embedded between them currently require 8 KB.
+ So if a Vinum partition was started at offset 0 within a
+ slice or disk that was meant to be bootable, the Vinum setup
+ will trash the bootstrap.</para>
+
+ <para>Similarly, if the above situation has been recovered,
+ for example by booting from a <quote>Fixit</quote> medium,
+ and the bootstrap has been re-installed using
+ <command>disklabel -B</command> as described in <xref linkend="boot-boot1"/>, the bootstrap will trash the Vinum
+ header, and Vinum will no longer find its disk(s). Though
+ no actual Vinum configuration data or data in Vinum volumes
+ will be trashed by this, and it would be possible to recover
+ all the data by entering exact the same Vinum configuration
+ data again, the situation is hard to fix at all. It would
+ be necessary to move the entire Vinum partition by at least
+ 4 KB off, in order to have the Vinum header and the system
+ bootstrap no longer collide.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="vinum-root-4x">
+ <title>Differences for FreeBSD 4.X</title>
+
+ <para>Under FreeBSD 4.X, some internal functions required to
+ make Vinum automatically scan all disks are missing, and the
+ code that figures out the internal ID of the root device is
+ not smart enough to handle a name like
+ <filename>/dev/vinum/root</filename> automatically.
+ Therefore, things are a little different here.</para>
+
+ <para>Vinum must explicitly be told which disks to scan, using a
+ line like the following one in
+ <filename>/boot/loader.conf</filename>:</para>
+
+ <programlisting>vinum.drives="/dev/<replaceable>da0</replaceable> /dev/<replaceable>da1</replaceable>"</programlisting>
+
+ <para>It is important that all drives are mentioned that could
+ possibly contain Vinum data. It does not harm if
+ <emphasis>more</emphasis> drives are listed, nor is it
+ necessary to add each slice and/or partition explicitly, since
+ Vinum will scan all slices and partitions of the named drives
+ for valid Vinum headers.</para>
+
+ <para>Since the routines used to parse the name of the root
+ filesystem, and derive the device ID (major/minor number) are
+ only prepared to handle <quote>classical</quote> device names
+ like <filename>/dev/ad0s1a</filename>, they cannot make
+ any sense out of a root volume name like
+ <filename>/dev/vinum/root</filename>. For that reason,
+ Vinum itself needs to pre-setup the internal kernel parameter
+ that holds the ID of the root device during its own
+ initialization. This is requested by passing the name of the
+ root volume in the loader variable
+ <literal>vinum.root</literal>. The entry in
+ <filename>/boot/loader.conf</filename> to accomplish this
+ looks like:</para>
+
+ <programlisting>vinum.root="root"</programlisting>
+
+ <para>Now, when the kernel initialization tries to find out the
+ root device to mount, it sees whether some kernel module has
+ already pre-initialized the kernel parameter for it. If that
+ is the case, <emphasis>and</emphasis> the device claiming the
+ root device matches the major number of the driver as figured
+ out from the name of the root device string being passed (that
+ is, <literal>"vinum"</literal> in our case), it will use the
+ pre-allocated device ID, instead of trying to figure out one
+ itself. That way, during the usual automatic startup, it can
+ continue to mount the Vinum root volume for the root
+ filesystem.</para>
+
+ <para>However, when <command>boot -a</command> has been
+ requesting to ask for entering the name of the root device
+ manually, it must be noted that this routine still cannot
+ actually parse a name entered there that refers to a Vinum
+ volume. If any device name is entered that does not refer to
+ a Vinum device, the mismatch between the major numbers of the
+ pre-allocated root parameter and the driver as figured out
+ from the given name will make this routine enter its normal
+ parser, so entering a string like
+ <literal>ufs:da0d</literal> will work as expected. Note
+ that if this fails, it is however no longer possible to
+ re-enter a string like <literal>ufs:vinum/root</literal>
+ again, since it cannot be parsed. The only way out is to
+ reboot again, and start over then. (At the
+ <quote>askroot</quote> prompt, the initial
+ <filename>/dev/</filename> can always be omitted.)</para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/virtualization/Makefile b/zh_TW.UTF-8/books/handbook/virtualization/Makefile
new file mode 100644
index 0000000000..7f5a1fd58b
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/virtualization/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= virtualization/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/virtualization/chapter.xml b/zh_TW.UTF-8/books/handbook/virtualization/chapter.xml
new file mode 100644
index 0000000000..1eea7a6c59
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/virtualization/chapter.xml
@@ -0,0 +1,886 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+ The FreeBSD Traditional Chinese Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.16
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="virtualization">
+ <info><title>Virtualization(虛擬機器)</title>
+ <authorgroup>
+ <author><personname><firstname>Murray</firstname><surname>Stokely</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <sect1 xml:id="virtualization-synopsis">
+ <title>Synopsis</title>
+
+ <para>虛擬機器軟體可以讓同一台機器得以同時執行多種作業系統。 在 PC 上,
+ 通常這類系統都是在宿主(host)機器上裝虛擬機器軟體,來跑一堆 guest OS
+ 。</para>
+
+ <para>讀完這章,您將了解︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>host OS 以及 guest OS 的區別。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何在搭載 &intel; CPU 的 &apple; &macintosh; 電腦上安裝 FreeBSD
+ 。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何在 Linux 上以 <application>&xen;</application> 來安裝
+ FreeBSD。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何在 &microsoft.windows; 上以 <application>Virtual PC</application>
+ 安裝 FreeBSD。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何在虛擬機器對 FreeBSD 系統作性能調校,以取得最佳效能。</para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>在開始閱讀這章之前,您需要︰</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>瞭解 &unix; 及 FreeBSD 相關基本概念
+ (<xref linkend="basics"/>)。</para>
+ </listitem>
+
+ <listitem><para>知道如何安裝 FreeBSD(<xref linkend="install"/>)。</para></listitem>
+
+ <listitem><para>知道如何設定網路(<xref linkend="advanced-networking"/>)。</para></listitem>
+
+ <listitem><para>知道如何以 ports/packages 來安裝應用程式
+ (<xref linkend="ports"/>)。</para></listitem>
+ </itemizedlist>
+
+ </sect1>
+
+
+
+ <sect1 xml:id="virtualization-guest">
+ <title>安裝 FreeBSD 為 Guest OS</title>
+
+ <sect2 xml:id="virtualization-guest-parallels">
+ <title>MacOS 上的 Parallels</title>
+
+ <para>&mac; 版的 <application>Parallels Desktop</application>
+ 乃是可用於搭配 &intel; CPU 以及 &macos; 10.4.6 以上的 &apple; &mac;
+ 電腦的商業軟體。 FreeBSD 是其有完整支援的 guest OS 之一。 在
+ &macos; X 裝好 <application>Parallels</application> 後,
+ 必須針對所欲安裝的 guest OS 來作相關的虛擬機器設定。</para>
+
+ <sect3 xml:id="virtualization-guest-parallels-install">
+ <title>在 Parallels/&macos; X 上安裝 FreeBSD</title>
+
+ <para>在 &macos; X/<application>Parallels</application> 上安裝 FreeBSD
+ 的第一步是新增虛擬機器。 如下所示,在提示視窗內請將
+ <guimenu>Guest OS Type</guimenu> 勾選為
+ <guimenuitem>FreeBSD</guimenuitem>:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/parallels-freebsd1"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>並依據自身需求來規劃硬碟容量跟記憶體的分配。 對大多數在
+ <application>Parallels</application> 使用的情況而言,大約 4GB
+ 硬碟以及 512MB RAM 就夠用了:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/parallels-freebsd2"/>
+ </imageobject>
+ </mediaobject>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/parallels-freebsd3"/>
+ </imageobject>
+ </mediaobject>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/parallels-freebsd4"/>
+ </imageobject>
+ </mediaobject>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/parallels-freebsd5"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>接下來,選擇網路種類以及網路卡:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/parallels-freebsd6"/>
+ </imageobject>
+ </mediaobject>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/parallels-freebsd7"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>最後,儲存設定檔就完成設定了:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/parallels-freebsd8"/>
+ </imageobject>
+ </mediaobject>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/parallels-freebsd9"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>在 FreeBSD 虛擬機器新增後,就可以繼續以其安裝 FreeBSD。
+ 安裝方面,比較好的作法是使用官方的 FreeBSD 光碟或者從官方 FTP
+ 站下載 ISO image 檔。 若您的 &mac; 本機已經有該 ISO 檔,
+ 或者 &mac; 的光碟機內有放安裝片,那麼就可以在 FreeBSD 的
+ <application>Parallels</application> 視窗右下角按下光碟片圖示。
+ 接著會出現一個視窗,可以把虛擬機器內的光碟機設定到該 ISO 檔,
+ 或者是實體光碟機。</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/parallels-freebsd11"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>設好光碟片來源之後,就可以按下重開機圖示以重開 FreeBSD
+ 虛擬機器。 <application>Parallels</application> 會以特殊 BIOS
+ 開機,並與普通的 BIOS 一樣會先檢查是否有光碟機。</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/parallels-freebsd10"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>此時,它就會找到 FreeBSD 安裝片,並開始在 <xref linkend="install"/> 內所介紹到的
+ <application>sysinstall</application> 安裝過程。 這時候也可順便裝
+ X11,但先不要進行相關設定。</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/parallels-freebsd12"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>完成安裝過程之後,就可以重開剛裝的 FreeBSD 虛擬機器。</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/parallels-freebsd13"/>
+ </imageobject>
+ </mediaobject>
+ </sect3>
+
+ <sect3 xml:id="virtualization-guest-parallels-configure">
+ <title>在 &macos; X/Parallels 上設定 FreeBSD</title>
+
+ <para>把 FreeBSD 成功裝到 &macos; X 的
+ <application>Parallels</application> 之後,還需要作一些設定步驟,
+ 以便將虛擬機器內的 FreeBSD 最佳化。</para>
+
+ <procedure>
+ <step>
+ <title>設定 boot loader 參數</title>
+
+ <para>最重要的步驟乃是藉由調降 <option>kern.hz</option> 來降低
+ <application>Parallels</application> 環境內 FreeBSD 的 CPU
+ 佔用率。 可以在 <filename>/boot/loader.conf</filename>
+ 內加上下列設定即可:</para>
+
+ <programlisting>kern.hz=100</programlisting>
+
+ <para>若不作這設定,那麼光是 idle 狀態的 FreeBSD
+ (<application>Parallels</application> guest OS)
+ 就會在僅單一處理器的 &imac; 上佔了大約 15% 的 CPU 佔用率。
+ 作上述修改之後,佔用率就會降至大約 5%。</para>
+ </step>
+
+ <step>
+ <title>設定新的 kernel 設定檔</title>
+
+ <para>可以放心把所有 SCSI、FireWire、USB
+ 相關設備都移除。 <application>Parallels</application>
+ 有提供 &man.ed.4; 的虛擬網卡,因此,除了 &man.ed.4; 以及
+ &man.miibus.4; 以外的其他網路卡也都可以從 kernel 中移除。</para>
+ </step>
+
+ <step>
+ <title>設定網路</title>
+
+ <para>可以替虛擬機器簡單用 DHCP 來設定與 &mac; 相同的 LAN
+ 網路環境,只要在 <filename>/etc/rc.conf</filename>
+ 內加上 <literal>ifconfig_ed0="DHCP"</literal> 即可完成。
+ 其他進階的網路設定方式,請參考 <xref linkend="advanced-networking"/>。</para>
+ </step>
+ </procedure>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 xml:id="virtualization-guest-xen">
+ <info><title>在 Linux 透過 &xen; 跑 FreeBSD</title>
+ <authorgroup>
+ <author><personname><firstname>Fukang</firstname><surname>Chen (Loader)</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+
+ </info>
+
+
+
+ <para><application>&xen;</application> hypervisor 乃是開放源碼的
+ paravirtualization 產品,並由商業公司(XenSource)提供支援。
+ Guest OS 通常被稱為 domU domains,而 host OS 則是被稱為 dom0。
+ 在 Linux 上建立 FreeBSD 虛擬機器的第一步,則是安裝 Linux dom0 的
+ <application>&xen;</application>。 在本例中, host OS 乃是 Slackware
+ Linux。</para>
+
+ <sect3 xml:id="xen-slackware-dom0">
+ <title>在 Linux dom0 上設定 &xen; 3</title>
+
+ <procedure>
+ <step>
+ <title>從 XenSource 網站下載 &xen; 3.0</title>
+
+ <para>從 <uri xlink:href="http://www.xensource.com/">http://www.xensource.com/</uri> 下載
+ <link xlink:href="http://bits.xensource.com/oss-xen/release/3.0.4-1/src.tgz/xen-3.0.4_1-src.tgz">xen-3.0.4_1-src.tgz</link>。</para>
+
+ </step>
+
+ <step>
+ <title>解壓縮</title>
+
+ <screen>&prompt.root; <userinput>cd xen-3.0.4_1-src</userinput>
+&prompt.root; <userinput>KERNELS="linux-2.6-xen0 linux-2.6-xenU" make world</userinput>
+&prompt.root; <userinput>make install</userinput></screen>
+
+ <note>
+ <para>為 dom0 重新編譯 kernel:</para>
+
+ <screen>&prompt.root; <userinput>cd xen-3.0.4_1-src/linux-2.6.16.33-xen0</userinput>
+&prompt.root; <userinput>make menuconfig</userinput>
+&prompt.root; <userinput>make</userinput>
+&prompt.root; <userinput>make install</userinput></screen>
+
+ <para>舊版的 <application>&xen;</application> 可能需要用
+ <command>make ARCH=xen menuconfig</command></para>
+ </note>
+ </step>
+
+ <step>
+ <title>增加選項到 Grub 的 menu.lst 選單</title>
+
+ <para>修改 <filename>/boot/grub/menu.lst</filename>
+ 加上下列設定:</para>
+
+ <programlisting>title Xen-3.0.4
+root (hd0,0)
+kernel /boot/xen-3.0.4-1.gz dom0_mem=262144
+module /boot/vmlinuz-2.6.16.33-xen0 root=/dev/hda1 ro</programlisting>
+ </step>
+
+ <step>
+ <title>重開機並進入 &xen;</title>
+
+ <para>首先,修改
+ <filename>/etc/xen/xend-config.sxp</filename>
+ 加上下列設定:</para>
+
+ <programlisting>(network-script 'network-bridge netdev=eth0')</programlisting>
+
+ <para>接下來,就可以啟動 <application>&xen;</application>:</para>
+
+ <screen>&prompt.root; <userinput>/etc/init.d/xend start</userinput>
+&prompt.root; <userinput>/etc/init.d/xendomains start</userinput></screen>
+
+ <para>現在 dom0 已經開始運作:</para>
+
+ <screen>&prompt.root; <userinput>xm list</userinput>
+Name ID Mem VCPUs State Time(s)
+Domain-0 0 256 1 r----- 54452.9</screen>
+ </step>
+ </procedure>
+ </sect3>
+
+ <sect3>
+ <title>FreeBSD 7-CURRENT domU</title>
+
+ <para>從 <link xlink:href="http://www.fsmware.com/">http://www.fsmware.com/</link>
+ 下載搭配 <application>&xen; 3.0</application> 的 FreeBSD domU
+ kernel 相關檔案</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><link xlink:href="http://www.fsmware.com/xenofreebsd/7.0/download/kernel-current">kernel-current</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.fsmware.com/xenofreebsd/7.0/download/mdroot-7.0.bz2">mdroot-7.0.bz2</link></para>
+ </listitem>
+
+ <listitem>
+ <para><link xlink:href="http://www.fsmware.com/xenofreebsd/7.0/download/config/xmexample1.bsd">xmexample1.bsd</link></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>把 <filename>xmexample1.bsd</filename> 設定檔放到
+ <filename>/etc/xen/</filename>,並修改 kernel 及 disk image 相關位置。
+ 以下是示範的例子:</para>
+
+ <programlisting>kernel = "/opt/kernel-current"
+memory = 256
+name = "freebsd"
+vif = [ '' ]
+disk = [ 'file:/opt/mdroot-7.0,hda1,w' ]
+#on_crash = 'preserve'
+extra = "boot_verbose"
+extra += ",boot_single"
+extra += ",kern.hz=100"
+extra += ",vfs.root.mountfrom=ufs:/dev/xbd769a"</programlisting>
+
+ <para>其中 <filename>mdroot-7.0.bz2</filename> 檔要記得解壓縮之。</para>
+
+ <para>接下來,要修改 <filename>kernel-current</filename> 設定檔的
+ __xen_guest 小節,並加上 <application>&xen; 3.0.3</application> 所需的
+ VIRT_BASE:</para>
+
+ <screen>&prompt.root; <userinput>objcopy kernel-current -R __xen_guest</userinput>
+&prompt.root; <userinput>perl -e 'print "LOADER=generic,GUEST_OS=freebsd,GUEST_VER=7.0,XEN_VER=xen-3.0,BSD_SYMTAB,VIRT_BASE=0xC0000000\x00"' &gt; tmp</userinput>
+&prompt.root; <userinput>objcopy kernel-current --add-section __xen_guest=tmp</userinput></screen>
+
+ <screen>&prompt.root; <userinput>objdump -j __xen_guest -s kernel-current</userinput>
+
+kernel-current: file format elf32-i386
+
+Contents of section __xen_guest:
+ 0000 4c4f4144 45523d67 656e6572 69632c47 LOADER=generic,G
+ 0010 55455354 5f4f533d 66726565 6273642c UEST_OS=freebsd,
+ 0020 47554553 545f5645 523d372e 302c5845 GUEST_VER=7.0,XE
+ 0030 4e5f5645 523d7865 6e2d332e 302c4253 N_VER=xen-3.0,BS
+ 0040 445f5359 4d544142 2c564952 545f4241 D_SYMTAB,VIRT_BA
+ 0050 53453d30 78433030 30303030 3000 SE=0xC0000000. </screen>
+
+ <para>現在可以新增並啟動 domU 囉:</para>
+
+ <screen>&prompt.root; <userinput>xm create /etc/xen/xmexample1.bsd -c</userinput>
+Using config file "/etc/xen/xmexample1.bsd".
+Started domain freebsd
+WARNING: loader(8) metadata is missing!
+Copyright (c) 1992-2006 The FreeBSD Project.
+Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
+The Regents of the University of California. All rights reserved.
+FreeBSD 7.0-CURRENT #113: Wed Jan 4 06:25:43 UTC 2006
+ kmacy@freebsd7.gateway.2wire.net:/usr/home/kmacy/p4/freebsd7_xen3/src/sys/i386-xen/compile/XENCONF
+WARNING: DIAGNOSTIC option enabled, expect reduced performance.
+Xen reported: 1796.927 MHz processor.
+Timecounter "ixen" frequency 1796927000 Hz quality 0
+CPU: Intel(R) Pentium(R) 4 CPU 1.80GHz (1796.93-MHz 686-class CPU)
+ Origin = "GenuineIntel" Id = 0xf29 Stepping = 9
+ Features=0xbfebfbff&lt;FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,
+ DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE&gt;
+ Features2=0x4400&lt;CNTX-ID,&lt;b14&gt;&gt;
+real memory = 265244672 (252 MB)
+avail memory = 255963136 (244 MB)
+xc0: &lt;Xen Console&gt; on motherboard
+cpu0 on motherboard
+Timecounters tick every 10.000 msec
+[XEN] Initialising virtual ethernet driver.
+xn0: Ethernet address: 00:16:3e:6b:de:3a
+[XEN]
+Trying to mount root from ufs:/dev/xbd769a
+WARNING: / was not properly dismounted
+Loading configuration files.
+No suitable dump device was found.
+Entropy harvesting: interrupts ethernet point_to_point kickstart.
+Starting file system checks:
+/dev/xbd769a: 18859 files, 140370 used, 113473 free (10769 frags, 12838 blocks, 4.2% fragmentation)
+Setting hostname: demo.freebsd.org.
+lo0: flags=8049&lt;UP,LOOPBACK,RUNNING,MULTICAST&gt; mtu 16384
+ inet6 ::1 prefixlen 128
+ inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
+ inet 127.0.0.1 netmask 0xff000000
+Additional routing options:.
+Mounting NFS file systems:.
+Starting syslogd.
+/etc/rc: WARNING: Dump device does not exist. Savecore not run.
+ELF ldconfig path: /lib /usr/lib /usr/lib/compat /usr/X11R6/lib /usr/local/lib
+a.out ldconfig path: /usr/lib/aout /usr/lib/compat/aout /usr/X11R6/lib/aout
+Starting usbd.
+usb: Kernel module not available: No such file or directory
+Starting local daemons:.
+Updating motd.
+Starting sshd.
+Initial i386 initialization:.
+Additional ABI support: linux.
+Starting cron.
+Local package initialization:.
+Additional TCP options:.
+Starting background file system checks in 60 seconds.
+
+Sun Apr 1 02:11:43 UTC 2007
+
+FreeBSD/i386 (demo.freebsd.org) (xc0)
+
+login: </screen>
+
+ <para>現在 domU 應該可以跑 &os;&nbsp;7.0-CURRENT kernel:</para>
+
+ <screen>&prompt.root; <userinput>uname -a</userinput>
+FreeBSD demo.freebsd.org 7.0-CURRENT FreeBSD 7.0-CURRENT #113: Wed Jan 4 06:25:43 UTC 2006
+kmacy@freebsd7.gateway.2wire.net:/usr/home/kmacy/p4/freebsd7_xen3/src/sys/i386-xen/compile/XENCONF i386</screen>
+
+ <para>接下來是設定 domU 的網路,&os; domU 會用代號為
+ <filename>xn0</filename> 的特殊網路卡:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig xn0 10.10.10.200 netmask 255.0.0.0</userinput>
+&prompt.root; <userinput>ifconfig</userinput>
+xn0: flags=843&lt;UP,BROADCAST,RUNNING,SIMPLEX&gt; mtu 1500
+ inet 10.10.10.200 netmask 0xff000000 broadcast 10.255.255.255
+ ether 00:16:3e:6b:de:3a
+lo0: flags=8049&lt;UP,LOOPBACK,RUNNING,MULTICAST&gt; mtu 16384
+ inet6 ::1 prefixlen 128
+ inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
+ inet 127.0.0.1 netmask 0xff000000 </screen>
+
+ <para>在 dom0 Slackware 上應該會出現一些 <application>&xen;</application>
+ 專用的網路卡:</para>
+
+ <screen>&prompt.root; <userinput>ifconfig</userinput>
+eth0 Link encap:Ethernet HWaddr 00:07:E9:A0:02:C2
+ inet addr:10.10.10.130 Bcast:0.0.0.0 Mask:255.0.0.0
+ UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
+ RX packets:815 errors:0 dropped:0 overruns:0 frame:0
+ TX packets:1400 errors:0 dropped:0 overruns:0 carrier:0
+ collisions:0 txqueuelen:0
+ RX bytes:204857 (200.0 KiB) TX bytes:129915 (126.8 KiB)
+
+lo Link encap:Local Loopback
+ inet addr:127.0.0.1 Mask:255.0.0.0
+ UP LOOPBACK RUNNING MTU:16436 Metric:1
+ RX packets:99 errors:0 dropped:0 overruns:0 frame:0
+ TX packets:99 errors:0 dropped:0 overruns:0 carrier:0
+ collisions:0 txqueuelen:0
+ RX bytes:9744 (9.5 KiB) TX bytes:9744 (9.5 KiB)
+
+peth0 Link encap:Ethernet HWaddr FE:FF:FF:FF:FF:FF
+ UP BROADCAST RUNNING NOARP MTU:1500 Metric:1
+ RX packets:1853349 errors:0 dropped:0 overruns:0 frame:0
+ TX packets:952923 errors:0 dropped:0 overruns:0 carrier:0
+ collisions:0 txqueuelen:1000
+ RX bytes:2432115831 (2.2 GiB) TX bytes:86528526 (82.5 MiB)
+ Base address:0xc000 Memory:ef020000-ef040000
+
+vif0.1 Link encap:Ethernet HWaddr FE:FF:FF:FF:FF:FF
+ UP BROADCAST RUNNING NOARP MTU:1500 Metric:1
+ RX packets:1400 errors:0 dropped:0 overruns:0 frame:0
+ TX packets:815 errors:0 dropped:0 overruns:0 carrier:0
+ collisions:0 txqueuelen:0
+ RX bytes:129915 (126.8 KiB) TX bytes:204857 (200.0 KiB)
+
+vif1.0 Link encap:Ethernet HWaddr FE:FF:FF:FF:FF:FF
+ UP BROADCAST RUNNING NOARP MTU:1500 Metric:1
+ RX packets:3 errors:0 dropped:0 overruns:0 frame:0
+ TX packets:2 errors:0 dropped:157 overruns:0 carrier:0
+ collisions:0 txqueuelen:1
+ RX bytes:140 (140.0 b) TX bytes:158 (158.0 b)
+
+xenbr1 Link encap:Ethernet HWaddr FE:FF:FF:FF:FF:FF
+ UP BROADCAST RUNNING NOARP MTU:1500 Metric:1
+ RX packets:4 errors:0 dropped:0 overruns:0 frame:0
+ TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
+ collisions:0 txqueuelen:0
+ RX bytes:112 (112.0 b) TX bytes:0 (0.0 b)</screen>
+
+ <screen>&prompt.root; <userinput>brctl show</userinput>
+bridge name bridge id STP enabled interfaces
+xenbr1 8000.feffffffffff no vif0.1
+ peth0
+ vif1.0</screen>
+ </sect3>
+
+ </sect2>
+
+ <sect2 xml:id="virtualization-guest-virtualpc">
+ <title>&windows; 上的 Virtual PC</title>
+
+ <para><application>Virtual PC</application> 是 &microsoft; 的
+ &windows; 軟體產品,可以免費下載使用。 相關系統需求,請參閱 <link xlink:href="http://www.microsoft.com/windows/downloads/virtualpc/sysreq.mspx">
+ system requirements</link> 說明。 在 &microsoft.windows; 裝完
+ <application>Virtual PC</application> 之後,
+ 必須針對所欲安裝的虛擬機器來作相關設定。</para>
+
+ <sect3 xml:id="virtualization-guest-virtualpc-install">
+ <title>在 Virtual PC/&microsoft.windows; 上安裝 FreeBSD</title>
+
+ <para>在 &microsoft.windows;/<application>Virtual PC</application>
+ 上安裝 FreeBSD 的第一步是新增虛擬機器。 如下所示,
+ 在提示視窗內請選擇 <guimenuitem>Create a virtual
+ machine</guimenuitem>:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/virtualpc-freebsd1"/>
+ </imageobject>
+ </mediaobject>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/virtualpc-freebsd2"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>然後在 <guimenuitem>Operating system</guimenuitem> 處選
+ <guimenuitem>Other</guimenuitem>:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/virtualpc-freebsd3"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>並依據自身需求來規劃硬碟容量跟記憶體的分配。
+ 對大多數在 <application>Virtual PC</application> 使用 FreeBSD
+ 的情況而言,大約 4GB 硬碟空間以及 512MB RAM 就夠用了:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/virtualpc-freebsd4"/>
+ </imageobject>
+ </mediaobject>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/virtualpc-freebsd5"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>儲存設定檔:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/virtualpc-freebsd6"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>接下來選剛剛所新增的 FreeBSD 虛擬機器,並按下
+ <guimenu>Settings</guimenu>,以設定網路種類以及網路卡:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/virtualpc-freebsd7"/>
+ </imageobject>
+ </mediaobject>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/virtualpc-freebsd8"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>在 FreeBSD 虛擬機器新增後,就可以繼續以其安裝 FreeBSD。
+ 安裝方面,比較好的作法是使用官方的 FreeBSD 光碟或者從官方 FTP
+ 站下載 ISO image 檔。 若您的 &windows; 檔案系統內已經有該 ISO
+ 檔, 或者光碟機內有放安裝片,那麼就可以在 FreeBSD
+ 虛擬機器上連按兩下,以開始啟動。 接著在
+ <application>Virtual PC</application> 視窗內按
+ <guimenu>CD</guimenu> 再按 <guimenu>Capture ISO Image...</guimenu>
+ 。 接著會出現一個視窗,可以把虛擬機器內的光碟機設定到該 ISO 檔,
+ 或者是實體光碟機。</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/virtualpc-freebsd9"/>
+ </imageobject>
+ </mediaobject>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/virtualpc-freebsd10"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>設好光碟片來源之後,就可以重開機,也就是先按
+ <guimenu>Action</guimenu> 再按 <guimenu>Reset</guimenu> 即可。
+ <application>Virtual PC</application> 會以特殊 BIOS 開機,並與普通
+ BIOS 一樣會先檢查是否有光碟機。</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/virtualpc-freebsd11"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>此時,它就會找到 FreeBSD 安裝片,並開始在 <xref linkend="install"/> 內所介紹到的 <application>sysinstall</application>
+ 安裝過程。 這時候也可順便裝 X11,但先不要進行相關設定。</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/virtualpc-freebsd12"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>完成安裝之後,記得把光碟片退出或者 ISO image 退片。 最後,
+ 把裝好的 FreeBSD 虛擬機器重開機即可。</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/virtualpc-freebsd13"/>
+ </imageobject>
+ </mediaobject>
+ </sect3>
+
+ <sect3 xml:id="virtualization-guest-virtualpc-configure">
+ <title>調整 &microsoft.windows;/Virtual PC 上的 FreeBSD</title>
+
+ <para>在 &microsoft.windows; 上以 <application>Virtual
+ PC</application> 裝好 FreeBSD 後,還需要作一些設定步驟,
+ 以便將虛擬機器內的 FreeBSD 最佳化。</para>
+
+ <procedure>
+ <step>
+ <title>設定 boot loader 參數</title>
+
+ <para>最重要的步驟乃是藉由調降 <option>kern.hz</option> 來降低
+ <application>Virtual PC</application> 環境內 FreeBSD 的 CPU
+ 佔用率。 可以在 <filename>/boot/loader.conf</filename>
+ 內加上下列設定即可:</para>
+
+ <programlisting>kern.hz=100</programlisting>
+
+ <para>若不作這設定,那麼光是 idle 狀態的 FreeBSD
+ <application>Virtual PC</application> guest OS
+ 就會在僅單一處理器的電腦上佔了大約 40% 的 CPU 佔用率。
+ 作上述修改之後,佔用率就會降至大約 3%。</para>
+ </step>
+
+ <step>
+ <title>設定新的 kernel 設定檔</title>
+
+ <para>可以放心把所有 SCSI、FireWire、USB 相關設備都移除。
+ <application>Virtual PC</application> 有提供 &man.de.4;
+ 的虛擬網卡,因此除了 &man.de.4; 以及 &man.miibus.4;
+ 以外的其他網路卡也都可以從 kernel 中移除。</para>
+ </step>
+
+ <step>
+ <title>設定網路</title>
+
+ <para>可以替虛擬機器簡單用 DHCP 來設定與 host(&microsoft.windows;)
+ 相同的 LAN 網路環境,只要在 <filename>/etc/rc.conf</filename>
+ 加上 <literal>ifconfig_de0="DHCP"</literal> 即可完成。
+ 其他進階的網路設定方式,請參閱 <xref linkend="advanced-networking"/>。</para>
+ </step>
+ </procedure>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 xml:id="virtualization-guest-vmware">
+ <title>在 MacOS 上的 VMware</title>
+
+ <para>&mac; 上的 <application>VMWare Fusion</application> 乃是可用於搭配
+ &intel; CPU 以及 &macos; 10.4.9 之 &apple; &mac; 以上的 &apple; &mac;
+ 電腦之商業軟體。 FreeBSD 是其有完整支援的 guest OS 之一。 在 &macos;
+ X 上裝完 <application>VMWare Fusion</application> 之後,
+ 必須針對所欲安裝的 guest OS 來作相關的虛擬機器設定。</para>
+
+ <sect3 xml:id="virtualization-guest-vmware-install">
+ <title>在 VMWare/&macos; X 上安裝 FreeBSD</title>
+
+ <para>首先執行 VMWare Fusion,而其 Virtual Machine Library
+ 也會隨之一併載入,這時請按 "New" 來建立 VM(虛擬機器):</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/vmware-freebsd01"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>接著會有 New Virtual Machine Assistant 來協助您建立 VM,請按
+ Continue 繼續:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/vmware-freebsd02"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>在 <guimenuitem>Operating System</guimenuitem> 選
+ <guimenuitem>Other</guimenuitem>,以及 <guimenu>Version</guimenu>
+ 處請選擇是否要
+ <guimenuitem>FreeBSD</guimenuitem> 或
+ <guimenuitem>FreeBSD 64-bit</guimenuitem>,這部份請依自身需求是否有要
+ 64-bit 支援而定:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/vmware-freebsd03"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>接著設定 VM image 檔要存到何處,以及決定名稱:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/vmware-freebsd04"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>決定該 VM 的虛擬硬碟要用多大:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/vmware-freebsd05"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>選擇要裝 VM 的方式為何,要用 ISO image 檔或者光碟機:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/vmware-freebsd06"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>按 Finish 以完畢,接著就會啟動該 VM:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/vmware-freebsd07"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>接著就照以往安裝 &os; 的方式來裝,若不熟的話請參閱
+ <xref linkend="install"/>:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/vmware-freebsd08"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>裝完之後,就可以修改一些 VM 設定,像是記憶體大小:</para>
+
+ <note>
+ <para>VM 在運作之時,不能修改 VM 的硬體設定。</para>
+ </note>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/vmware-freebsd09"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>調整 VM 的 CPU 數量:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/vmware-freebsd10"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>光碟機狀態,通常不再需要用的時候,就可以切斷其與 VM 的連接:</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/vmware-freebsd11"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>最後要改的則是 VM 的網路設定。 若除了 Host OS 之外的機器也能連到
+ VM,那麼請選 <guimenuitem>Connect directly to the physical network
+ (Bridged)</guimenuitem>,否則就選 <guimenuitem>Share the host's
+ internet connection (NAT)</guimenuitem> 即可讓 VM 連到 Internet,
+ 但外面則無法連入該 VM。</para>
+
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="virtualization/vmware-freebsd12"/>
+ </imageobject>
+ </mediaobject>
+
+ <para>改完上述設定之後,就可以啟動新裝妥的 FreeBSD 虛擬機器。</para>
+ </sect3>
+
+ <sect3 xml:id="virtualization-guest-vmware-configure">
+ <title>調整 &macos; X/VMWare 上的 FreeBSD</title>
+
+ <para>把 FreeBSD 成功裝到 &macos; X 的 <application>VMWare</application>
+ 之後,還需要作一些設定步驟, 以便將虛擬機器內的 FreeBSD 最佳化。</para>
+
+ <procedure>
+ <step>
+ <title>設定 boot loader 參數</title>
+
+ <para>最重要的步驟乃是藉由調降 <option>kern.hz</option> 來降低
+ <application>VMWare</application> 環境內 FreeBSD 的 CPU 佔用率。
+ 可以在 <filename>/boot/loader.conf</filename>
+ 內加上下列設定即可:</para>
+
+ <programlisting>kern.hz=100</programlisting>
+
+ <para>若不作這設定,那麼光是 idle 狀態的 FreeBSD
+ (<application>VMWare</application> guest OS) 就會在僅單一處理器的
+ &imac; 上佔了大約 15% 的 CPU 佔用率。 作上述修改之後,
+ 佔用率就會降至大約 5%。</para>
+ </step>
+
+ <step>
+ <title>設定新的 kernel 設定檔</title>
+
+ <para>可以放心把所有 FireWire、USB 相關設備都移除。
+ <application>VMWare</application> 有提供 &man.em.4; 的虛擬網卡,
+ 因此,除了 &man.em.4; 以及 &man.miibus.4; 以外的其他網路卡,
+ 也都可以從 kernel 中移除。</para>
+ </step>
+
+ <step>
+ <title>設定網路</title>
+
+ <para>可以替虛擬機器簡單用 DHCP 來設定與 host &mac; 相同的 LAN
+ 網路環境,只要在 <filename>/etc/rc.conf</filename> 加上
+ <literal>ifconfig_em0="DHCP"</literal> 即可。
+ 其他進階的網路設定方式,請參考 <xref linkend="advanced-networking"/>。</para>
+ </step>
+ </procedure>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="virtualization-host">
+ <title>以 FreeBSD 為 Host OS</title>
+
+ <para>目前,尚未有任何虛擬機器軟體有官方支援 FreeBSD 作為 host OS,
+ 但蠻多人都有在用舊版 <application>VMware</application> 所提供的這項功能。
+ 不過,目前已經有人為讓 <application>&xen;</application> 能夠以 FreeBSD
+ 為 host OS 為目標,而進行相關工作。</para>
+
+ </sect1>
+
+</chapter>
diff --git a/zh_TW.UTF-8/books/handbook/x11/Makefile b/zh_TW.UTF-8/books/handbook/x11/Makefile
new file mode 100644
index 0000000000..040a7ae2b2
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/x11/Makefile
@@ -0,0 +1,15 @@
+#
+# Build the Handbook with just the content from this chapter.
+#
+# $FreeBSD$
+#
+
+CHAPTERS= x11/chapter.xml
+
+VPATH= ..
+
+MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX}
+
+DOC_PREFIX?= ${.CURDIR}/../../../..
+
+.include "../Makefile"
diff --git a/zh_TW.UTF-8/books/handbook/x11/chapter.xml b/zh_TW.UTF-8/books/handbook/x11/chapter.xml
new file mode 100644
index 0000000000..8a03630116
--- /dev/null
+++ b/zh_TW.UTF-8/books/handbook/x11/chapter.xml
@@ -0,0 +1,1516 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original revision: 1.186
+-->
+<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="x11">
+ <info><title>X Window 視窗系統</title>
+ <authorgroup>
+ <author><personname><firstname>Ken</firstname><surname>Tom</surname></personname><contrib>Updated for X.Org's X11 server by </contrib></author>
+ <author><personname><firstname>Marc</firstname><surname>Fonvieille</surname></personname></author>
+ </authorgroup>
+ </info>
+
+
+
+ <sect1 xml:id="x11-synopsis">
+ <title>概述</title>
+
+ <para>FreeBSD 使用 X11 來提供使用者相當好用的 GUI 介面。
+ X11 是 X Window 系統,包括 <application>&xorg;</application>
+ 以及 <application>&xfree86;</application> 實作的自由軟體版本
+ (以及其他未在本章有介紹的軟體)。 &os; 一直到 &os;&nbsp;5.2.1-RELEASE
+ 都仍可在預設的安裝程式內去裝 <application>&xfree86;</application>
+ (由 The &xfree86; Project, Inc 發行的 X11 server)。
+ 而 &os;&nbsp;5.3-RELEASE 起,預設的 X11 改為
+ <application>&xorg;</application>(由 X.Org 基金會所開發的
+ X11 server,並採用與 &os; 相當類似的 license)。 此外,當然也有商業
+ X servers 的 &os; 版。</para>
+
+ <para>本章主要是介紹 X11 (主要著重於 <application>&xorg;</application>
+ &xorg.version; 版部分)的安裝與設定。 若欲瞭解
+ <application>&xfree86;</application> 的詳細資料(早期的 &os; 內,
+ <application>&xfree86;</application> 乃是預設的 X11 套件),請參閱舊版的
+ &os; Handbook,網址為 <uri xlink:href="http://docs.FreeBSD.org/doc/">http://docs.FreeBSD.org/doc/</uri>
+ 。</para>
+
+ <para>欲知 X11 對於顯示方面硬體的支援情況,請參閱 <link xlink:href="http://www.x.org/">&xorg;</link> 網站。</para>
+
+ <para>讀完這章,您將了解:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>X Window 系統的各組成部份,以及它們是如何相互運作。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何安裝、設定 X11。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何安裝並使用不同的 window managers。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何在 X11 上使用 &truetype; 字型。</para>
+ </listitem>
+
+ <listitem>
+ <para>如何設定系統以使用圖形登入介面。
+ (<application>XDM</application>)</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>在開始閱讀這章之前,您需要︰</para>
+
+ <itemizedlist>
+ <listitem><para>知道如何運用 ports、packages 來安裝軟體。
+ (<xref linkend="ports"/>)</para></listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 xml:id="x-understanding">
+ <title>瞭解 X 的世界</title>
+
+ <para>第一次接觸 X 的人,大概都會有些震撼,尤其是熟悉其他 GUI 介面(像是
+ &microsoft.windows; 或 &macos;)的使用者。</para>
+
+ <para>雖然 X 各元件的所有細節及運作方式,並不是必須要知道的。
+ 但對它們有些基本概念會更容易上手。</para>
+
+ <sect2>
+ <title>為何叫做 X?</title>
+
+ <para>X 並非 &unix; 上第一套視窗系統,但它卻是最廣為流傳運用。
+ 原本的 X 研發團隊在研發 X 之前有開發另一套視窗系統。 那套系統叫做
+ <quote>W</quote>(取 <quote>Window</quote> 的第一個字)。
+ 而 X 則是 W 之後的下一個羅馬字母。</para>
+
+ <para>X 亦被稱之為 <quote>X</quote>、<quote>X Window System</quote>、
+ <quote>X11</quote>,以及其他一些詞彙。 使用 <quote>X Windows</quote>
+ 這字眼來稱呼 X11,可能會讓有些人不爽;這部分細節可參閱 &man.X.7;
+ 說明。</para>
+ </sect2>
+
+ <sect2>
+ <title>X 的 Client/Server 架構</title>
+
+ <para>X 一開始是設計為網路架構環境,並採用
+ <quote>client-server</quote> 架構。</para>
+
+ <para>在 X 架構下,
+ <quote>X server</quote> 是在有鍵盤、螢幕、滑鼠的電腦上運作。
+ 而 server 部份則是負責像是顯示部份的管理、
+ 處理來自鍵盤、滑鼠及其他設備(比方像是以繪圖板來輸入、
+ 或者是顯示到投影機)的輸入等等,
+ 每個 X 程式(像是 <application>XTerm</application>,或
+ <application>&netscape;</application>)都是 <quote>client</quote>。
+ client 會傳訊息到 server 上,比如:<quote>Please draw a
+ window at these coordinates</quote>,接著 server 會傳回訊息,比如:
+ <quote>The user just clicked on the OK button</quote>。</para>
+
+ <para>在家庭或小辦公室環境,通常 X server 跟 X client
+ 都是在同一台電腦上執行的。 然而,也可以在比較爛的桌機上執行 X server,
+ 並在比較強、比較貴的電腦上跑 X 程式(client)來做事情。
+ 在這種場景,X client 與 server 之間的溝通就需透過網路來進行。</para>
+
+ <para>這點可能會讓有些人產生困惑,因為 X 術語與他們原本的認知剛好相反。
+ 他們原本以為 <quote>X server</quote> 是要在最強悍的機器上跑才行,而
+ <quote>X client</quote> 則是在他們桌機上面跑。 實際上卻不是這樣。</para>
+
+ <para>有點相當重要,請記住 X server 是在有接螢幕、鍵盤的機器上運作,
+ 而 X client 則是顯示這些視窗的程式。</para>
+
+ <para>協定(protocol)內並無強制規定 client 以及 server
+ 兩邊機器都得是同一作業系統,或者得是同型機器才可以。
+ 換句話說,也可以在 &microsoft.windows; 或蘋果電腦(Apple)的 &macos;
+ 上跑 X server,而且可以透過許多免費或商業軟體完成這些安裝、設定。
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>The Window Manager</title>
+
+ <para>X 設計哲學與 &unix; 設計哲學相當類似,都是
+ <quote>tools, not policy</quote>。 也就是說,X
+ 不會試圖強制規定某任務應該要如何完成,而是只提供使用者一些工具,
+ 至於如何運用這些工具,則是使用者本身的事了。</para>
+
+ <para>X 延續這哲學,它並不規定:螢幕上的視窗該長什麼樣、要如何移動滑鼠指標、
+ 該用什麼組合鍵來切換各視窗(比如:在 &microsoft.windows; 的
+ <keycombo action="simul">
+ <keycap>Alt</keycap>
+ <keycap>Tab</keycap>
+ </keycombo>鍵)、各視窗的標題列長相,以及是否該有關閉鈕等等。</para>
+
+ <para>事實上,X 把這部分交給所謂的 <quote>Window Manager</quote> 來管理。
+ 有一堆 window manager 程式,像是: <application>AfterStep</application>
+ 、<application>Blackbox</application>、<application>ctwm</application>
+ 、<application>Enlightenment</application>、
+ <application>fvwm</application>、<application>Sawfish</application>、
+ <application>twm</application>、
+ <application>Window Maker</application> 等等。每一種 window manager
+ 都提供不同的使用經驗; 有些還可使用 <quote>virtual desktops(虛擬桌面)
+ </quote>;有些則可自訂組合鍵來管理桌面;有些會有 <quote>Start(開始)
+ </quote>鈕或其他類似設計;有些則是 <quote>可更換佈景主題</quote>,
+ 可自行安裝新的佈景主題以更換外觀。 這些跟其他的
+ window manager 在 Ports Collection 內的
+ <filename>x11-wm</filename> 目錄內都有。</para>
+
+ <para>此外,<application>KDE</application> 及
+ <application>GNOME</application> 桌面環境則有其自屬並整合完整的
+ window manager。</para>
+
+ <para>每個 window manager 也各有其不同的設定機制;有些需手動寫設定檔,
+ 而有的則可透過 GUI 工具來完成大部分的設定。舉個例子:
+ <application>Sawfish</application> 就有以 Lisp 語言寫的設定檔。
+ </para>
+
+ <note>
+ <title>Focus Policy</title>
+
+ <para>window manager 的另一特色就是負責滑鼠指標的
+ <quote>focus policy</quote>。 每一種視窗系統都需要選擇作用視窗的方式
+ ,以接受鍵盤輸入,以及決定目前哪個視窗是處於使用中的狀態。</para>
+
+ <para>通常較為人熟悉的 focus policy 叫做 <quote>click-to-focus</quote>,
+ 這是 &microsoft.windows; 所採用的模式,也就是指標在該視窗按一下的話,
+ 該視窗就會處於使用中的狀態。</para>
+
+ <para>X 並不支援一些特殊的 focus policy。 換句話說,window manager
+ 會控制哪個視窗在何時是作用中。 不同的 window manager
+ 有不同的支援方式。 但它們都支援 click-to-focus,
+ 而且大多數都有支援多種方式。</para>
+
+ <para>以下是目前最流行的 focus policy:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term>focus-follows-mouse</term>
+
+ <listitem>
+ <para>滑鼠移到哪個視窗就是使用該視窗。
+ 該視窗不一定位於其他視窗上面,
+ 但只要把滑鼠移到該視窗就可以改變作用中的視窗,
+ 而不需在它上面點擊。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>sloppy-focus</term>
+
+ <listitem>
+ <para>該 policy 是針對 focus-follows-mouse 的小小延伸。
+ 對於 focus-follows-mouse 而言,若把游標移到最初的視窗(或桌面),
+ 那所有其他視窗都會處於非作用中,而且所有鍵盤輸入也會失效。
+ 若是選用 sloppy-focus,則只有在游標移到新視窗時,
+ 作用中的視窗才會變成新的,
+ 而只離開目前作用中的視窗仍不會改變作用狀態。</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>click-to-focus</term>
+
+ <listitem>
+ <para>由游標點擊才會決定作用中的視窗。 並且該視窗會被
+ <quote>raised(凸顯)</quote> 到所有其他視窗之前,
+ 即使游標移到其他視窗,所有的鍵盤輸入仍會由該視窗所接收。</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>許多 window manager 也支援其他 policy,與這些相比起來又有些不同,
+ 細節部分請參閱該 window manager 的文件說明。</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Widgets</title>
+
+ <para>The X approach of providing tools and not policy extends to the
+ widgets seen on screen in each application.</para>
+
+ <para><quote>Widget</quote> is a term for all the items in the user
+ interface that can be clicked or manipulated in some way; buttons,
+ check boxes, radio buttons, icons, lists, and so on. &microsoft.windows;
+ calls these <quote>controls</quote>.</para>
+
+ <para>&microsoft.windows; and Apple's &macos; both have a very rigid widget
+ policy. Application developers are supposed to ensure that their
+ applications share a common look and feel. With X, it was not
+ considered sensible to mandate a particular graphical style, or set
+ of widgets to adhere to.</para>
+
+ <para>As a result, do not expect X applications to have a common
+ look and feel. There are several popular widget sets and
+ variations, including the original Athena widget set from MIT,
+ <application>&motif;</application> (on which the widget set in
+ &microsoft.windows; was modeled, all bevelled edges and three shades of
+ grey), <application>OpenLook</application>, and others.</para>
+
+ <para>Most newer X applications today will use a modern-looking widget
+ set, either Qt, used by <application>KDE</application>, or
+ GTK+, used by the
+ <application>GNOME</application>
+ project. In this respect, there is some convergence in
+ look-and-feel of the &unix; desktop, which certainly makes things
+ easier for the novice user.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="x-install">
+ <title>安裝 X11</title>
+
+ <para><application>&xorg;</application> 是 &os; 預設的 X11 實作。
+ <application>&xorg;</application> 是由 X.Org 基金會所發行之開放源碼軟體
+ X Window 系統實作的 X server。 <application>&xorg;</application>
+ 乃是以 <application>&xfree86;&nbsp;4.4RC2</application> 以及 X11R6.6
+ 為基礎所產生的。 目前 &os; Ports Collection 內的
+ <application>&xorg;</application> 版本為 &xorg.version;。</para>
+
+ <para>從 Ports Collection 來安裝 <application>&xorg;</application>
+ 的安裝方式:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/x11/xorg</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+
+ <note>
+ <para>若要編譯完整的 <application>&xorg;</application>,
+ 請先確認至少有 4&nbsp;GB 的磁碟空間。</para>
+ </note>
+
+ <para>此外 X11 也可直接透過 package 方式來安裝,可使用 &man.pkg.add.1;
+ 來安裝編譯好的 X11 套件,記得在透過網路安裝時不要指定版本即可,
+ &man.pkg.add.1; 會自動抓該套件最新版的套件回來。</para>
+
+ <para>若要自動透過 package 方式來裝 <application>&xorg;</application>
+ ,直接打下面這行即可:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r xorg</userinput></screen>
+
+ <note><para>上面的例子會裝完整的 X11 套件,包括 server、client、字型等。
+ 此外,還有其他的 X11 子套件可透過 package 或 port
+ 方式來單獨安裝。</para></note>
+
+ <para>本章其餘部分將介紹如何設定 X11,
+ 以及如何打造高生產力的桌面環境。</para>
+ </sect1>
+
+ <sect1 xml:id="x-config">
+ <info><title>設定 X11</title>
+ <authorgroup>
+ <author><personname><firstname>Christopher</firstname><surname>Shumway</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+
+ <indexterm><primary>&xorg;</primary></indexterm>
+ <indexterm><primary>X11</primary></indexterm>
+
+ <sect2>
+ <title>在開始之前</title>
+
+ <para>在開始設定 X11 之前,要先瞭解所要裝的機器資料為何:</para>
+
+ <itemizedlist>
+ <listitem><para>螢幕規格</para></listitem>
+ <listitem><para>顯示卡的晶片規格</para></listitem>
+ <listitem><para>顯示卡的記憶體容量</para></listitem>
+ </itemizedlist>
+
+ <indexterm><primary>horizontal scan rate</primary></indexterm>
+ <indexterm><primary>vertical scan rate</primary></indexterm>
+
+ <para>X11 會依螢幕規格來決定解析度以及更新頻率。
+ 這些規格通常可從螢幕所附的文件或廠商網站上取得。
+ 最重要的是要知道水平、垂直更新頻率為何。</para>
+
+ <para>而顯示卡晶片則決定 X11 要用哪一種驅動程式模組。
+ 大多數的晶片都可以自動偵測,但最好還是要知道是何種晶片,
+ 以免萬一自動偵測失敗。</para>
+
+ <para>Video memory on the graphic adapter determines the
+ resolution and color depth which the system can run at. This is
+ important to know so the user knows the limitations of the
+ system.</para>
+ </sect2>
+
+ <sect2>
+ <title>設定 X11</title>
+
+ <para><application>&xorg;</application> 自 7.3
+ 版起不再需任何設定檔,只要打下列即可:</para>
+
+ <screen>&prompt.user; <userinput>startx</userinput></screen>
+
+ <para>若這指令不行或預設設定無法使用,那麼就需要手動設定 X11。
+ 設定 X11 需要幾個步驟,首先是以系統管理者帳號來建立初始設定檔:</para>
+
+ <screen>&prompt.root; <userinput>Xorg -configure</userinput></screen>
+
+ <para>這會在 <filename>/root</filename> 目錄內產生
+ <filename>xorg.conf.new</filename> 設定檔(無論是用 &man.su.1;
+ 或直接登入為 root,都會改變 root 預設的 <envar>$HOME</envar> 環境變數)。
+ X11 程式接著會偵測系統的顯示卡相關硬體,並將偵測到硬體訊息寫入設定檔,
+ 以便載入正確的驅動程式。</para>
+
+ <para>下一步是測試現有的設定檔,以便確認 <application>&xorg;</application>
+ 可以與顯示卡、螢幕相關硬體正確運作:</para>
+
+ <screen>&prompt.root; <userinput>Xorg -config xorg.conf.new</userinput></screen>
+
+ <para>若看得到一堆黑灰夾雜的網格畫面,以及 X 形的滑鼠游標,
+ 那麼設定檔就是成功的。 要退出測試,只要同時按下
+ <keycombo action="simul">
+ <keycap>Ctrl</keycap>
+ <keycap>Alt</keycap>
+ <keycap>Backspace</keycap>
+ </keycombo> 即可。</para>
+
+ <note><para>若滑鼠不正確運作,那麼需要先對其作設定。 請參閱
+ &os; 安裝一章中的 <xref linkend="mouse"/> 說明。</para></note>
+
+ <indexterm><primary>X11 tuning</primary></indexterm>
+
+ <para>Next, tune the <filename>xorg.conf.new</filename>
+ configuration file to taste. Open the file in a text editor such
+ as &man.emacs.1; or &man.ee.1;. First, add the
+ frequencies for the target system's monitor. These are usually
+ expressed as a horizontal and vertical synchronization rate. These
+ values are added to the <filename>xorg.conf.new</filename> file
+ under the <literal>"Monitor"</literal> section:</para>
+
+ <programlisting>Section "Monitor"
+ Identifier "Monitor0"
+ VendorName "Monitor Vendor"
+ ModelName "Monitor Model"
+ HorizSync 30-107
+ VertRefresh 48-120
+EndSection</programlisting>
+
+ <para>The <literal>HorizSync</literal> and
+ <literal>VertRefresh</literal> keywords may be missing in the
+ configuration file. If they are, they need to be added, with
+ the correct horizontal synchronization rate placed after the
+ <literal>HorizSync</literal> keyword and the vertical
+ synchronization rate after the <literal>VertRefresh</literal>
+ keyword. In the example above the target monitor's rates were
+ entered.</para>
+
+ <para>X allows DPMS (Energy Star) features to be used with capable
+ monitors. The &man.xset.1; program controls the time-outs and can force
+ standby, suspend, or off modes. If you wish to enable DPMS features
+ for your monitor, you must add the following line to the monitor
+ section:</para>
+
+ <programlisting>
+ Option "DPMS"</programlisting>
+
+ <indexterm>
+ <primary><filename>xorg.conf</filename></primary>
+ </indexterm>
+
+ <para>While the <filename>xorg.conf.new</filename>
+ configuration file is still open in an editor, select
+ the default resolution and color depth desired. This is
+ defined in the <literal>"Screen"</literal> section:</para>
+
+ <programlisting>Section "Screen"
+ Identifier "Screen0"
+ Device "Card0"
+ Monitor "Monitor0"
+ DefaultDepth 24
+ SubSection "Display"
+ Viewport 0 0
+ Depth 24
+ Modes "1024x768"
+ EndSubSection
+EndSection</programlisting>
+
+ <para>The <literal>DefaultDepth</literal> keyword describes
+ the color depth to run at by default. This can be overridden
+ with the <option>-depth</option> command line switch to
+ &man.Xorg.1;.
+ The <literal>Modes</literal> keyword
+ describes the resolution to run at for the given color depth.
+ Note that only VESA standard modes are supported as defined by
+ the target system's graphics hardware.
+ In the example above, the default color depth is twenty-four
+ bits per pixel. At this color depth, the accepted resolution is
+ 1024 by 768
+ pixels.</para>
+
+ <para>Finally, write the configuration file and test it using
+ the test mode given above.</para>
+
+ <note>
+ <para>One of the tools available to assist you during
+ troubleshooting process are the X11 log files, which contain
+ information on each device that the X11 server attaches to.
+ <application>&xorg;</application> log file names are in the format
+ of <filename>/var/log/Xorg.0.log</filename>. The exact name
+ of the log can vary from <filename>Xorg.0.log</filename> to
+ <filename>Xorg.8.log</filename> and so forth.</para>
+ </note>
+
+ <para>If all is well, the configuration
+ file needs to be installed in a common location where
+ &man.Xorg.1; can find it.
+ This is typically <filename>/etc/X11/xorg.conf</filename> or
+ <filename>/usr/local/etc/X11/xorg.conf</filename>.</para>
+
+ <screen>&prompt.root; <userinput>cp xorg.conf.new /etc/X11/xorg.conf</userinput></screen>
+
+ <para>The X11 configuration process is now
+ complete. <application>&xorg;</application> 目前可透過 &man.startx.1;
+ 來啟動之。
+ The X11 server may also be started with the use of
+ &man.xdm.1;.</para>
+
+ <note><para>There is also a graphical configuration tool,
+ &man.xorgcfg.1;, which comes with the
+ X11 distribution. It
+ allows you to interactively define your configuration by choosing
+ the appropriate drivers and settings. This program can be invoked from the console, by typing the command <command>xorgcfg -textmode</command>. For more details,
+ refer to the &man.xorgcfg.1; manual pages.</para>
+
+ <para>Alternatively, there is also a tool called &man.xorgconfig.1;.
+ This program is a console utility that is less user friendly,
+ but it may work in situations where the other tools do
+ not.</para></note>
+
+ </sect2>
+
+ <sect2>
+ <title>進階設定專欄</title>
+
+ <sect3>
+ <title>設定 &intel; i810 繪圖晶片組</title>
+
+ <indexterm><primary>Intel i810 graphic chipset</primary></indexterm>
+
+ <para>Configuration with &intel; i810 integrated chipsets
+ requires the <filename>agpgart</filename>
+ AGP programming interface for X11
+ to drive the card. 詳情請參閱 &man.agp.4; 說明。</para>
+
+ <para>This will allow configuration of the hardware as any other
+ graphics board. Note on systems without the &man.agp.4;
+ driver compiled in the kernel, trying to load the module
+ with &man.kldload.8; will not work. This driver has to be
+ in the kernel at boot time through being compiled in or
+ using <filename>/boot/loader.conf</filename>.</para>
+ </sect3>
+
+ <sect3>
+ <title>為寬螢幕打造更舒適環境</title>
+
+ <indexterm><primary>widescreen flatpanel configuration</primary></indexterm>
+
+ <para>本節假設各位已經有些微進階設定的功力。
+ 如果試著使用上述設定工具會有問題的話,請多利用相關 log 檔
+ (會記錄相關訊息)以便找出解法。
+ 找尋解法過程中,可能會需要用到文字編輯器作為輔助。</para>
+
+ <para>目前的寬螢幕 (WSXGA, WSXGA+, WUXGA, WXGA, WXGA+ 等)
+ 都有支援 16:10 及 10:9 比例,以及一些可能有問題的比例。
+ 以下是一些常見的 16:10 螢幕解析度:</para>
+
+ <itemizedlist>
+ <listitem><para>2560x1600</para></listitem>
+ <listitem><para>1920x1200</para></listitem>
+ <listitem><para>1680x1050</para></listitem>
+ <listitem><para>1440x900</para></listitem>
+ <listitem><para>1280x800</para></listitem>
+ </itemizedlist>
+
+ <para>某方面而言,要增加這些解析度設定也是相當容易的,
+ 只要在 <literal>Section "Screen"</literal> 內的
+ <literal>Mode</literal> 加上去就好,比如:</para>
+
+ <programlisting>Section "Screen"
+Identifier "Screen0"
+Device "Card0"
+Monitor "Monitor0"
+DefaultDepth 24
+SubSection "Display"
+ Viewport 0 0
+ Depth 24
+ Modes "1680x1050"
+EndSubSection
+EndSection</programlisting>
+
+ <para><application>&xorg;</application> 可以透過 I2C/DDC
+ 來得知該寬螢幕所支援的解析度等相關資訊,
+ 因此就能正確偵測出該螢幕所能支援的頻率、解析度。</para>
+
+ <para>若驅動程式並未包括 <literal>ModeLine</literal> 訊息的話,
+ 那麼就要為 <application>&xorg;</application> 做些設定才行。
+ 我們可以透過 <filename>/var/log/Xorg.0.log</filename> 檔來取得
+ <literal>ModeLine</literal> 相關設定資料,即可讓螢幕正常顯示。
+ 應該可以看到類似下面的訊息:</para>
+
+ <programlisting>(II) MGA(0): Supported additional Video Mode:
+(II) MGA(0): clock: 146.2 MHz Image Size: 433 x 271 mm
+(II) MGA(0): h_active: 1680 h_sync: 1784 h_sync_end 1960 h_blank_end 2240 h_border: 0
+(II) MGA(0): v_active: 1050 v_sync: 1053 v_sync_end 1059 v_blanking: 1089 v_border: 0
+(II) MGA(0): Ranges: V min: 48 V max: 85 Hz, H min: 30 H max: 94 kHz, PixClock max 170 MHz</programlisting>
+
+ <para>這些訊息被稱為 EDID 訊息。 可以藉由這些資料,
+ 搭配下列的正確順序來產生 <literal>ModeLine</literal> 設定:</para>
+
+ <programlisting> ModeLine &lt;name&gt; &lt;clock&gt; &lt;4 horiz. timings&gt; &lt;4 vert. timings&gt;</programlisting>
+
+ <para>所以這個案例 <literal>Section "Monitor"</literal> 的
+ <literal>ModeLine</literal> 就會是像下面這樣:</para>
+
+ <programlisting>Section "Monitor"
+Identifier "Monitor1"
+VendorName "Bigname"
+ModelName "BestModel"
+ModeLine "1680x1050" 146.2 1680 1784 1960 2240 1050 1053 1059 1089
+Option "DPMS"
+EndSection</programlisting>
+
+ <para>這樣子就簡單完成了,X 視窗就可以打造為新的寬螢幕環境囉。</para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="x-fonts">
+ <info><title>在 X11 中使用字型</title>
+ <authorgroup>
+ <author><personname><firstname>Murray</firstname><surname>Stokely</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <sect2 xml:id="type1">
+ <title>Type1 規格的字型</title>
+ <para>The default fonts that ship with
+ X11 are less than ideal for typical
+ desktop publishing applications. Large presentation fonts show up
+ jagged and unprofessional looking, and small fonts in
+ <application>&netscape;</application> are almost completely unintelligible.
+ However, there are several free, high quality Type1 (&postscript;) fonts
+ available which can be readily used
+ with X11. For instance, the URW font collection
+ (<package>x11-fonts/urwfonts</package>) includes
+ high quality versions of standard type1 fonts (<trademark class="registered">Times Roman</trademark>,
+ <trademark class="registered">Helvetica</trademark>, <trademark class="registered">Palatino</trademark> and others). The Freefonts collection
+ (<package>x11-fonts/freefonts</package>) includes
+ many more fonts, but most of them are intended for use in
+ graphics software such as the <application>Gimp</application>, and are not
+ complete enough to serve as screen fonts. In addition,
+ X11 can be configured to use
+ &truetype; fonts with a minimum of effort. For more details on
+ this, see the &man.X.7; manual page or the
+ <link linkend="truetype">section on &truetype; fonts</link>.</para>
+
+ <para>To install the above Type1 font collections from the ports
+ collection, run the following commands:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/x11-fonts/urwfonts</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+
+ <para>And likewise with the freefont or other collections. To have the X
+ server detect these fonts, add an appropriate line to the
+ X server configuration file (<filename>/etc/X11/xorg.conf</filename>),
+ which reads:</para>
+
+ <programlisting>FontPath "/usr/local/lib/X11/fonts/URW/"</programlisting>
+
+ <para>Alternatively, at the command line in the X session
+ run:</para>
+
+ <screen>&prompt.user; <userinput>xset fp+ /usr/local/lib/X11/fonts/URW</userinput>
+&prompt.user; <userinput>xset fp rehash</userinput></screen>
+
+ <para>This will work but will be lost when the X session is closed,
+ unless it is added to the startup file (<filename>~/.xinitrc</filename>
+ for a normal <command>startx</command> session,
+ or <filename>~/.xsession</filename> when logging in through a
+ graphical login manager like <application>XDM</application>).
+ A third way is to use the new
+ <filename>/usr/local/etc/fonts/local.conf</filename> file: see the
+ section on <link linkend="antialias">anti-aliasing</link>.
+ </para>
+ </sect2>
+
+ <sect2 xml:id="truetype">
+ <title>&truetype; 規格的字型</title>
+
+ <indexterm><primary>TrueType Fonts</primary></indexterm>
+ <indexterm><primary>fonts</primary>
+ <secondary>TrueType</secondary>
+ </indexterm>
+
+ <para><application>&xorg;</application> has built in support
+ for rendering &truetype; fonts. There are two different modules
+ that can enable this functionality. The freetype module is used
+ in this example because it is more consistent with the other font
+ rendering back-ends. To enable the freetype module just add the
+ following line to the <literal>"Module"</literal> section of the
+ <filename>/etc/X11/xorg.conf</filename> file.</para>
+
+ <programlisting>Load "freetype"</programlisting>
+
+ <para>Now make a directory for the &truetype; fonts (for example,
+ <filename>/usr/local/lib/X11/fonts/TrueType</filename>)
+ and copy all of the &truetype; fonts into this directory. Keep in
+ mind that &truetype; fonts cannot be directly taken from a
+ &macintosh;; they must be in &unix;/&ms-dos;/&windows; format for use by
+ X11. Once the files have been
+ copied into this directory, use
+ <application>ttmkfdir</application> to create a
+ <filename>fonts.dir</filename> file, so that the X font renderer
+ knows that these new files have been installed.
+ <command>ttmkfdir</command> is available from the FreeBSD
+ Ports Collection as
+ <package>x11-fonts/ttmkfdir</package>.</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/local/lib/X11/fonts/TrueType</userinput>
+&prompt.root; <userinput>ttmkfdir -o fonts.dir</userinput></screen>
+
+ <para>Now add the &truetype; directory to the font
+ path. This is just the same as described above for <link linkend="type1">Type1</link> fonts, that is, use</para>
+
+ <screen>&prompt.user; <userinput>xset fp+ /usr/local/lib/X11/fonts/TrueType</userinput>
+&prompt.user; <userinput>xset fp rehash</userinput></screen>
+
+ <para>or add a <literal>FontPath</literal> line to the
+ <filename>xorg.conf</filename> file.</para>
+
+ <para>That's it. Now <application>&netscape;</application>,
+ <application>Gimp</application>,
+ <application>&staroffice;</application>, and all of the other X
+ applications should now recognize the installed &truetype;
+ fonts. Extremely small fonts (as with text in a high resolution
+ display on a web page) and extremely large fonts (within
+ <application>&staroffice;</application>) will look much better
+ now.</para>
+ </sect2>
+
+ <sect2 xml:id="antialias">
+ <info><title>Anti-Aliased 規格的字型</title>
+ <authorgroup>
+ <author><personname><firstname>Joe Marcus</firstname><surname>Clarke</surname></personname><contrib>Updated by </contrib></author>
+ </authorgroup>
+ </info>
+
+
+ <indexterm><primary>anti-aliased fonts</primary></indexterm>
+ <indexterm><primary>fonts</primary>
+ <secondary>anti-aliased</secondary></indexterm>
+
+ <para>Anti-aliasing has been available in X11 since
+ <application>&xfree86;</application> 4.0.2. However, font
+ configuration was cumbersome before the introduction of
+ <application>&xfree86;</application> 4.3.0.
+ Beginning with
+ <application>&xfree86;</application> 4.3.0, all fonts in X11
+ that are found
+ in <filename>/usr/local/lib/X11/fonts/</filename> and
+ <filename>~/.fonts/</filename> are automatically
+ made available for anti-aliasing to Xft-aware applications. Not
+ all applications are Xft-aware, but many have received Xft support.
+ Examples of Xft-aware applications include Qt 2.3 and higher (the
+ toolkit for the <application>KDE</application> desktop),
+ GTK+ 2.0 and higher (the toolkit for the
+ <application>GNOME</application> desktop), and
+ <application>Mozilla</application> 1.2 and higher.
+ </para>
+
+ <para>In order to control which fonts are anti-aliased, or to
+ configure anti-aliasing properties, create (or edit, if it
+ already exists) the file
+ <filename>/usr/local/etc/fonts/local.conf</filename>. Several
+ advanced features of the Xft font system can be tuned using
+ this file; this section describes only some simple
+ possibilities. For more details, please see
+ &man.fonts-conf.5;.</para>
+
+ <indexterm><primary>XML</primary></indexterm>
+
+ <para>This file must be in XML format. Pay careful attention to
+ case, and make sure all tags are properly closed. The file
+ begins with the usual XML header followed by a DOCTYPE
+ definition, and then the <literal>&lt;fontconfig&gt;</literal> tag:</para>
+
+ <programlisting>
+ &lt;?xml version="1.0"?&gt;
+ &lt;!DOCTYPE fontconfig SYSTEM "fonts.dtd"&gt;
+ &lt;fontconfig&gt;
+ </programlisting>
+
+ <para>As previously stated, all fonts in
+ <filename>/usr/local/lib/X11/fonts/</filename> as well as
+ <filename>~/.fonts/</filename> are already made available to
+ Xft-aware applications. If you wish to add another directory
+ outside of these two directory trees, add a line similar to the
+ following to
+ <filename>/usr/local/etc/fonts/local.conf</filename>:</para>
+
+ <programlisting>&lt;dir&gt;/path/to/my/fonts&lt;/dir&gt;</programlisting>
+
+ <para>After adding new fonts, and especially new font directories,
+ you should run the following command to rebuild the font
+ caches:</para>
+
+ <screen>&prompt.root; <userinput>fc-cache -f</userinput></screen>
+
+ <para>Anti-aliasing makes borders slightly fuzzy, which makes very
+ small text more readable and removes <quote>staircases</quote> from
+ large text, but can cause eyestrain if applied to normal text. To
+ exclude font sizes smaller than 14 point from anti-aliasing, include
+ these lines:</para>
+
+ <programlisting> &lt;match target="font"&gt;
+ &lt;test name="size" compare="less"&gt;
+ &lt;double&gt;14&lt;/double&gt;
+ &lt;/test&gt;
+ &lt;edit name="antialias" mode="assign"&gt;
+ &lt;bool&gt;false&lt;/bool&gt;
+ &lt;/edit&gt;
+ &lt;/match&gt;
+ &lt;match target="font"&gt;
+ &lt;test name="pixelsize" compare="less" qual="any"&gt;
+ &lt;double&gt;14&lt;/double&gt;
+ &lt;/test&gt;
+ &lt;edit mode="assign" name="antialias"&gt;
+ &lt;bool&gt;false&lt;/bool&gt;
+ &lt;/edit&gt;
+ &lt;/match&gt;</programlisting>
+
+ <indexterm><primary>fonts</primary>
+ <secondary>spacing</secondary></indexterm>
+
+ <para>Spacing for some monospaced fonts may also be inappropriate
+ with anti-aliasing. This seems to be an issue with
+ <application>KDE</application>, in particular. One possible fix for
+ this is to force the spacing for such fonts to be 100. Add the
+ following lines:</para>
+
+ <programlisting> &lt;match target="pattern" name="family"&gt;
+ &lt;test qual="any" name="family"&gt;
+ &lt;string&gt;fixed&lt;/string&gt;
+ &lt;/test&gt;
+ &lt;edit name="family" mode="assign"&gt;
+ &lt;string&gt;mono&lt;/string&gt;
+ &lt;/edit&gt;
+ &lt;/match&gt;
+ &lt;match target="pattern" name="family"&gt;
+ &lt;test qual="any" name="family"&gt;
+ &lt;string&gt;console&lt;/string&gt;
+ &lt;/test&gt;
+ &lt;edit name="family" mode="assign"&gt;
+ &lt;string&gt;mono&lt;/string&gt;
+ &lt;/edit&gt;
+ &lt;/match&gt;</programlisting>
+
+ <para>(this aliases the other common names for fixed fonts as
+ <literal>"mono"</literal>), and then add:</para>
+
+ <programlisting> &lt;match target="pattern" name="family"&gt;
+ &lt;test qual="any" name="family"&gt;
+ &lt;string&gt;mono&lt;/string&gt;
+ &lt;/test&gt;
+ &lt;edit name="spacing" mode="assign"&gt;
+ &lt;int&gt;100&lt;/int&gt;
+ &lt;/edit&gt;
+ &lt;/match&gt; </programlisting>
+
+ <para>Certain fonts, such as Helvetica, may have a problem when
+ anti-aliased. Usually this manifests itself as a font that
+ seems cut in half vertically. At worst, it may cause
+ applications such as <application>Mozilla</application> to
+ crash. To avoid this, consider adding the following to
+ <filename>local.conf</filename>:</para>
+
+ <programlisting> &lt;match target="pattern" name="family"&gt;
+ &lt;test qual="any" name="family"&gt;
+ &lt;string&gt;Helvetica&lt;/string&gt;
+ &lt;/test&gt;
+ &lt;edit name="family" mode="assign"&gt;
+ &lt;string&gt;sans-serif&lt;/string&gt;
+ &lt;/edit&gt;
+ &lt;/match&gt; </programlisting>
+
+ <para>Once you have finished editing
+ <filename>local.conf</filename> make sure you end the file
+ with the <literal>&lt;/fontconfig&gt;</literal> tag. Not doing this will cause
+ your changes to be ignored.</para>
+
+ <para>The default font set that comes with
+ X11 is not very
+ desirable when it comes to anti-aliasing. A much better
+ set of default fonts can be found in the
+ <package>x11-fonts/bitstream-vera</package>
+ port. This port will install a
+ <filename>/usr/local/etc/fonts/local.conf</filename> file
+ if one does not exist already. If the file does exist,
+ the port will create a <filename>/usr/local/etc/fonts/local.conf-vera
+ </filename> file. Merge the contents of this file into
+ <filename>/usr/local/etc/fonts/local.conf</filename>, and the
+ Bitstream fonts will automatically replace the default
+ X11 Serif, Sans Serif, and Monospaced
+ fonts.</para>
+
+ <para>Finally, users can add their own settings via their personal
+ <filename>.fonts.conf</filename> files. To do this, each user should
+ simply create a <filename>~/.fonts.conf</filename>. This file must
+ also be in XML format.</para>
+
+ <indexterm><primary>LCD screen</primary></indexterm>
+ <indexterm><primary>Fonts</primary>
+ <secondary>LCD screen</secondary></indexterm>
+
+ <para>One last point: with an LCD screen, sub-pixel sampling may be
+ desired. This basically treats the (horizontally separated)
+ red, green and blue components separately to improve the horizontal
+ resolution; the results can be dramatic. To enable this, add the
+ line somewhere in the <filename>local.conf</filename> file:</para>
+
+ <programlisting>
+ &lt;match target="font"&gt;
+ &lt;test qual="all" name="rgba"&gt;
+ &lt;const&gt;unknown&lt;/const&gt;
+ &lt;/test&gt;
+ &lt;edit name="rgba" mode="assign"&gt;
+ &lt;const&gt;rgb&lt;/const&gt;
+ &lt;/edit&gt;
+ &lt;/match&gt;
+ </programlisting>
+
+ <note><para>Depending on the sort of display,
+ <literal>rgb</literal> may need to be changed to <literal>bgr</literal>,
+ <literal>vrgb</literal> or <literal>vbgr</literal>: experiment and
+ see which works best.</para></note>
+
+ <indexterm>
+ <primary>Mozilla</primary>
+ <secondary>disabling anti-aliased fonts</secondary>
+ </indexterm>
+
+ <para>Anti-aliasing should be enabled the next time the X
+ server is started. However, programs must know how to take
+ advantage of it. At present, the Qt toolkit does,
+ so the entire <application>KDE</application> environment can
+ use anti-aliased fonts.
+ GTK+ and
+ <application>GNOME</application> can also be made to use
+ anti-aliasing via the <quote>Font</quote> capplet (see <xref linkend="x11-wm-gnome-antialias"/> for details). By default,
+ <application>Mozilla</application> 1.2 and greater will
+ automatically use anti-aliasing. To disable this, rebuild
+ <application>Mozilla</application> with the
+ <varname>-DWITHOUT_XFT</varname> flag.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="x-xdm">
+ <info><title>The X Display Manager</title>
+ <authorgroup>
+ <author><personname><firstname>Seth</firstname><surname>Kingsley</surname></personname><contrib>Contributed by </contrib></author>
+ </authorgroup>
+ </info>
+
+ <sect2>
+ <title>Overview</title>
+
+ <indexterm><primary>X Display Manager</primary></indexterm>
+ <para>The X Display Manager (<application>XDM</application>) is
+ an optional part of the X Window System that is used for login
+ session management. This is useful for several types of
+ situations, including minimal <quote>X Terminals</quote>,
+ desktops, and large network display
+ servers. Since the X Window System is network and protocol
+ independent, there are a wide variety of possible configurations
+ for running X clients and servers on different machines
+ connected by a network. <application>XDM</application> provides
+ a graphical interface for choosing which display server to
+ connect to, and entering authorization information such as a
+ login and password combination.</para>
+
+ <para>Think of <application>XDM</application> as
+ providing the same functionality to the user as the
+ &man.getty.8; utility (see <xref linkend="term-config"/> for
+ details). That is, it performs system logins to the display
+ being connected to and then runs a session manager on behalf of
+ the user (usually an X window
+ manager). <application>XDM</application> then waits for this
+ program to exit, signaling that the user is done and should be
+ logged out of the display. At this point,
+ <application>XDM</application> can display the login and display
+ chooser screens for the next user to login.</para>
+ </sect2>
+
+ <sect2>
+ <title>Using XDM</title>
+
+ <para>The <application>XDM</application> daemon program is
+ located in <filename>/usr/local/bin/xdm</filename>. This program
+ can be run at any time as <systemitem class="username">root</systemitem> and it will
+ start managing the X display on the local machine. If
+ <application>XDM</application> is to be run every
+ time the machine boots up, a convenient way to do this is by
+ adding an entry to <filename>/etc/ttys</filename>. For more
+ information about the format and usage of this file, see <xref linkend="term-etcttys"/>. There is a line in the default
+ <filename>/etc/ttys</filename> file for running the
+ <application>XDM</application> daemon on a virtual terminal:</para>
+
+ <screen>ttyv8 "/usr/local/bin/xdm -nodaemon" xterm off secure</screen>
+
+ <para>By default this entry is disabled; in order to enable it
+ change field 5 from <literal>off</literal> to
+ <literal>on</literal> and restart &man.init.8; using the
+ directions in <xref linkend="term-hup"/>. The first field, the
+ name of the terminal this program will manage, is
+ <literal>ttyv8</literal>. This means that
+ <application>XDM</application> will start running on the 9th
+ virtual terminal.</para>
+ </sect2>
+
+ <sect2>
+ <title>Configuring XDM</title>
+
+ <para>The <application>XDM</application> configuration directory
+ is located in <filename>/usr/local/lib/X11/xdm</filename>. In
+ this directory there are several files used to change the
+ behavior and appearance of
+ <application>XDM</application>. Typically these files will
+ be found:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>File</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><filename>Xaccess</filename></entry>
+ <entry>Client authorization ruleset.</entry>
+ </row>
+
+ <row>
+ <entry><filename>Xresources</filename></entry>
+ <entry>Default X resource values.</entry>
+ </row>
+
+ <row>
+ <entry><filename>Xservers</filename></entry>
+ <entry>List of remote and local displays to manage.</entry>
+ </row>
+
+ <row>
+ <entry><filename>Xsession</filename></entry>
+ <entry>Default session script for logins.</entry>
+ </row>
+
+ <row>
+ <entry><filename>Xsetup_</filename>*</entry>
+ <entry>Script to launch applications before the login
+ interface.</entry>
+ </row>
+
+ <row>
+ <entry><filename>xdm-config</filename></entry>
+ <entry>Global configuration for all displays running on
+ this machine.</entry>
+ </row>
+
+ <row>
+ <entry><filename>xdm-errors</filename></entry>
+ <entry>Errors generated by the server program.</entry>
+ </row>
+
+ <row>
+ <entry><filename>xdm-pid</filename></entry>
+ <entry>The process ID of the currently running XDM.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>Also in this directory are a few scripts and programs used
+ to set up the desktop when <application>XDM</application> is
+ running. The purpose of each of these files will be briefly
+ described. The exact syntax and usage of all of these files is
+ described in &man.xdm.1;.</para>
+
+ <para>The default configuration is a simple rectangular login
+ window with the hostname of the machine displayed at the top in
+ a large font and <quote>Login:</quote> and
+ <quote>Password:</quote> prompts below. This is a good starting
+ point for changing the look and feel of
+ <application>XDM</application> screens.</para>
+
+ <sect3>
+ <title>Xaccess</title>
+
+ <para>The protocol for connecting to
+ <application>XDM</application>-controlled displays is called
+ the X Display Manager Connection Protocol (XDMCP). This file
+ is a ruleset for controlling XDMCP connections from remote
+ machines. It is ignored unless the <filename>xdm-config</filename>
+ is changed to listen for remote connections. By default, it does
+ not allow any clients to connect.</para>
+ </sect3>
+
+ <sect3>
+ <title>Xresources</title>
+ <para>This is an application-defaults file for the display
+ chooser and login screens. In it, the appearance
+ of the login program can be modified. The format is identical
+ to the app-defaults file described in the
+ X11 documentation.</para>
+ </sect3>
+
+ <sect3>
+ <title>Xservers</title>
+ <para>This is a list of the remote displays the chooser should
+ provide as choices.</para>
+ </sect3>
+
+ <sect3>
+ <title>Xsession</title>
+ <para>This is the default session script for
+ <application>XDM</application> to run after a user has logged
+ in. Normally each user will have a customized session script
+ in <filename>~/.xsession</filename> that overrides this
+ script.</para>
+ </sect3>
+
+ <sect3>
+ <title>Xsetup_*</title>
+ <para>These will be run automatically before displaying the
+ chooser or login interfaces. There is a script for each
+ display being used, named <filename>Xsetup_</filename> followed
+ by the local display number (for instance
+ <filename>Xsetup_0</filename>). Typically these scripts will
+ run one or two programs in the background such as
+ <command>xconsole</command>.</para>
+ </sect3>
+
+ <sect3>
+ <title>xdm-config</title>
+ <para>This contains settings in the form of app-defaults
+ that are applicable to every display that this installation
+ manages.</para>
+ </sect3>
+
+ <sect3>
+ <title>xdm-errors</title>
+ <para>This contains the output of the X servers that
+ <application>XDM</application> is trying to run. If a display
+ that <application>XDM</application> is trying to start hangs
+ for some reason, this is a good place to look for error
+ messages. These messages are also written to the user's
+ <filename>~/.xsession-errors</filename> file on a per-session
+ basis.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Running a Network Display Server</title>
+
+ <para>In order for other clients to connect to the display
+ server, you must edit the access control rules, and enable the connection
+ listener. By default these are set to conservative values.
+ To make <application>XDM</application> listen for connections,
+ first comment out a line in the <filename>xdm-config</filename>
+ file:</para>
+
+ <screen>! SECURITY: do not listen for XDMCP or Chooser requests
+! Comment out this line if you want to manage X terminals with xdm
+DisplayManager.requestPort: 0</screen>
+
+ <para>and then restart <application>XDM</application>. Remember that
+ comments in app-defaults files begin with a <quote>!</quote>
+ character, not the usual <quote>#</quote>. More strict
+ access controls may be desired &mdash; look at the example
+ entries in <filename>Xaccess</filename>, and refer to the
+ &man.xdm.1; manual page for further infomation.</para>
+ </sect2>
+
+ <sect2>
+ <title>Replacements for XDM</title>
+
+ <para>Several replacements for the default
+ <application>XDM</application> program exist. One of them,
+ <application>kdm</application> (bundled with
+ <application>KDE</application>) is described later in this
+ chapter. The <application>kdm</application> display manager offers many visual
+ improvements and cosmetic frills, as well as the
+ functionality to allow users to choose their window manager
+ of choice at login time.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="x11-wm">
+ <info><title>桌面環境</title>
+ <authorgroup>
+ <author><personname><firstname>Valentino</firstname><surname>Vaschetto</surname></personname><contrib>Contributed by </contrib></author>
+ <!-- June 2001 -->
+ </authorgroup>
+ </info>
+
+
+
+ <para>本章會介紹在 FreeBSD 中的 X 裡頭,有哪些不同的桌面環境。
+ <quote>桌面環境</quote>範圍很廣,從簡單的 window manager 到
+ 完整的桌面應用程式,例如 <application>KDE</application> 或 <application>GNOME</application>。
+ </para>
+
+ <sect2 xml:id="x11-wm-gnome">
+ <title>GNOME</title>
+
+ <sect3 xml:id="x11-wm-gnome-about">
+ <title>關於 GNOME</title>
+
+ <indexterm><primary>GNOME</primary></indexterm>
+ <para><application>GNOME</application> is a user-friendly
+ desktop environment that enables users to easily use and
+ configure their computers. <application>GNOME</application>
+ includes a panel (for starting applications and displaying
+ status), a desktop (where data and applications can be
+ placed), a set of standard desktop tools and applications, and
+ a set of conventions that make it easy for applications to
+ cooperate and be consistent with each other. Users of other
+ operating systems or environments should feel right at home
+ using the powerful graphics-driven environment that
+ <application>GNOME</application> provides. More
+ information regarding <application>GNOME</application> on
+ FreeBSD can be found on the <link xlink:href="http://www.FreeBSD.org/gnome">FreeBSD GNOME
+ Project</link>'s web site. The web site also contains fairly
+ comprehensive FAQs about installing, configuring, and managing
+ <application>GNOME</application>.</para>
+ </sect3>
+
+ <sect3 xml:id="x11-wm-gnome-install">
+ <title>Installing GNOME</title>
+
+ <para>可透過 package 或 Ports Collection 的方式來輕鬆安裝:</para>
+
+ <para>透過網路利用 package 安裝 <application>GNOME</application>:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r gnome2</userinput></screen>
+
+ <para>從 ports tree 透過原始碼編譯安裝 <application>GNOME</application>:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/x11/gnome2</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+
+ <para>當 <application>GNOME</application> 安裝完成後,
+ 必須告訴 X server 啟動 <application>GNOME</application> 而非原本的 window manager。</para>
+
+ <para>啟動 <application>GNOME</application> 最簡單的方法是利
+ 用 <application>GDM</application>(GNOME Display Manager)。
+ <application>GDM</application>, which is installed as a part
+ of the <application>GNOME</application> desktop (but is
+ disabled by default), can be enabled by adding
+ <literal>gdm_enable="YES"</literal> to
+ <filename>/etc/rc.conf</filename>. Once you have rebooted,
+ <application>GNOME</application> will start automatically
+ once you log in &mdash; no further configuration is
+ necessary.</para>
+
+ <para><application>GNOME</application> may also be started
+ from the command-line by properly configuring a file named
+ <filename>.xinitrc</filename>.
+ If a custom <filename>.xinitrc</filename> is already in
+ place, simply replace the line that starts the current window
+ manager with one that starts
+ <application>/usr/local/bin/gnome-session</application> instead.
+ If nothing special has been done to the configuration file,
+ then it is enough simply to type:</para>
+
+ <screen>&prompt.user; <userinput>echo "/usr/local/bin/gnome-session" &gt; ~/.xinitrc</userinput></screen>
+
+ <para>Next, type <command>startx</command>, and the
+ <application>GNOME</application> desktop environment will be
+ started.</para>
+
+ <note><para>If an older display manager, like
+ <application>XDM</application>, is being used, this will not work.
+ Instead, create an executable <filename>.xsession</filename>
+ file with the same command in it. To do this, edit the file
+ and replace the existing window manager command with
+ <application>/usr/local/bin/gnome-session</application>:
+ </para></note>
+
+ <screen>&prompt.user; <userinput>echo "#!/bin/sh" &gt; ~/.xsession</userinput>
+&prompt.user; <userinput>echo "/usr/local/bin/gnome-session" &gt;&gt; ~/.xsession</userinput>
+&prompt.user; <userinput>chmod +x ~/.xsession</userinput></screen>
+
+ <para>Yet another option is to configure the display manager to
+ allow choosing the window manager at login time; the section on
+ <link linkend="x11-wm-kde-details">KDE details</link>
+ explains how to do this for <application>kdm</application>, the
+ display manager of <application>KDE</application>.</para>
+ </sect3>
+
+ <sect3 xml:id="x11-wm-gnome-antialias">
+ <title>Anti-aliased Fonts with GNOME</title>
+
+ <indexterm><primary>GNOME</primary>
+ <secondary>anti-aliased fonts</secondary></indexterm>
+ <para>X11
+ supports anti-aliasing via its <quote>RENDER</quote> extension.
+ GTK+ 2.0 and greater (the toolkit used by
+ <application>GNOME</application>) can make use of this
+ functionality. Configuring anti-aliasing is described in
+ <xref linkend="antialias"/>. So, with up-to-date software,
+ anti-aliasing is possible within the
+ <application>GNOME</application> desktop. Just go to
+ <menuchoice>
+ <guimenu>Applications</guimenu>
+ <guisubmenu>Desktop Preferences</guisubmenu>
+ <guimenuitem>Font</guimenuitem></menuchoice>, and select either
+ <guibutton>Best shapes</guibutton>,
+ <guibutton>Best contrast</guibutton>, or
+ <guibutton>Subpixel smoothing (LCDs)</guibutton>. For a
+ GTK+ application that is not part of the
+ <application>GNOME</application> desktop, set the
+ environment variable <varname>GDK_USE_XFT</varname> to
+ <literal>1</literal> before launching the program.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="x11-wm-kde">
+ <title>KDE</title>
+
+ <indexterm><primary>KDE</primary></indexterm>
+ <sect3 xml:id="x11-wm-kde-about">
+ <title>About KDE</title>
+
+ <para><application>KDE</application> is an easy to use
+ contemporary desktop environment. Some of the things that
+ <application>KDE</application> brings to the user are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>A beautiful contemporary desktop</para>
+ </listitem>
+
+ <listitem>
+ <para>A desktop exhibiting complete network transparency</para>
+ </listitem>
+
+ <listitem>
+ <para>An integrated help system allowing for convenient,
+ consistent access to help on the use of the
+ <application>KDE</application> desktop and its
+ applications</para>
+ </listitem>
+
+ <listitem>
+ <para>Consistent look and feel of all
+ <application>KDE</application> applications</para>
+ </listitem>
+
+ <listitem>
+ <para>Standardized menu and toolbars, keybindings, color-schemes,
+ etc.</para>
+ </listitem>
+
+ <listitem>
+ <para>Internationalization: <application>KDE</application>
+ is available in more than 40 languages</para>
+ </listitem>
+
+ <listitem>
+ <para>Centralized, consistent, dialog-driven desktop
+ configuration</para>
+ </listitem>
+
+ <listitem>
+ <para>A great number of useful
+ <application>KDE</application> applications</para>
+ </listitem>
+ </itemizedlist>
+
+ <para><application>KDE</application> comes with a web browser called
+ <application>Konqueror</application>, which is
+ a solid competitor to other existing web browsers on &unix;
+ systems. More information on <application>KDE</application>
+ can be found on the <link xlink:href="http://www.kde.org/">KDE
+ website</link>. For FreeBSD specific information and
+ resources on <application>KDE</application>, consult
+ the <link xlink:href="http://freebsd.kde.org/">KDE on FreeBSD
+ team</link>'s website.</para>
+ </sect3>
+
+ <sect3 xml:id="x11-wm-kde-install">
+ <title>安裝 KDE</title>
+
+ <para>如同 <application>GNOME</application> 或其他桌面管理軟體一樣,
+ 也可以輕鬆透過 package 或 Ports Collection 來安裝:</para>
+
+ <para>To install the <application>KDE</application> package
+ from the network, simply type:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r kde</userinput></screen>
+
+ <para>&man.pkg.add.1; will automatically fetch the latest version
+ of the application.</para>
+
+ <para>To build <application>KDE</application> from source,
+ use the ports tree:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/x11/kde3</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+
+ <para>After <application>KDE</application> has been installed,
+ the X server must be told to launch this application
+ instead of the default window manager. This is accomplished
+ by editing the <filename>.xinitrc</filename> file:</para>
+
+ <screen>&prompt.user; <userinput>echo "exec startkde" &gt; ~/.xinitrc</userinput></screen>
+
+ <para>Now, whenever the X Window System is invoked with
+ <command>startx</command>,
+ <application>KDE</application> will be the desktop.</para>
+
+ <para>If a display manager such as
+ <application>XDM</application> is being used, the
+ configuration is slightly different. Edit the
+ <filename>.xsession</filename> file instead. Instructions
+ for <application>kdm</application> are described later in
+ this chapter.</para>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="x11-wm-kde-details">
+ <title>More Details on KDE</title>
+
+ <para>Now that <application>KDE</application> is installed on
+ the system, most things can be discovered through the
+ help pages, or just by pointing and clicking at various menus.
+ &windows; or &mac; users will feel quite at home.</para>
+
+ <para>The best reference for <application>KDE</application> is
+ the on-line documentation. <application>KDE</application>
+ comes with its own web browser,
+ <application>Konqueror</application>, dozens of useful
+ applications, and extensive documentation. The remainder of
+ this section discusses the technical items that are
+ difficult to learn by random exploration.</para>
+
+ <sect3 xml:id="x11-wm-kde-kdm">
+ <title>The KDE Display Manager</title>
+
+ <indexterm><primary>KDE</primary>
+ <secondary>display manager</secondary></indexterm>
+ <para>An administrator of a multi-user system may wish to have
+ a graphical login screen to welcome users.
+ <link linkend="x-xdm">XDM</link> can be
+ used, as described earlier. However,
+ <application>KDE</application> includes an
+ alternative, <application>kdm</application>, which is designed
+ to look more attractive and include more login-time options.
+ In particular, users can easily choose (via a menu) which
+ desktop environment (<application>KDE</application>,
+ <application>GNOME</application>, or something else) to run
+ after logging on.</para>
+
+ <para>To enable <application>kdm</application>, the
+ <literal>ttyv8</literal> entry in <filename>/etc/ttys</filename>
+ has to be adapted. The line should look as follows:</para>
+
+ <programlisting>ttyv8 "/usr/local/bin/kdm -nodaemon" xterm on secure</programlisting>
+ </sect3>
+ </sect2>
+
+ <sect2 xml:id="x11-wm-xfce">
+ <title>XFce</title>
+ <sect3 xml:id="x11-wm-xfce-about">
+ <title>About XFce</title>
+
+ <para><application>XFce</application> is a desktop environment
+ based on the GTK+
+ toolkit used by <application>GNOME</application>, but is much
+ more lightweight and meant for those who want a simple,
+ efficient desktop which is nevertheless easy to use and
+ configure. Visually, it looks very much like
+ <application>CDE</application>, found on commercial &unix;
+ systems. Some of <application>XFce</application>'s features
+ are:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>A simple, easy-to-handle desktop</para>
+ </listitem>
+
+ <listitem>
+ <para>Fully configurable via mouse, with drag and
+ drop, etc. </para>
+ </listitem>
+
+ <listitem>
+ <para>Main panel similar to <application>CDE</application>, with
+ menus, applets and applications launchers</para>
+ </listitem>
+
+ <listitem>
+ <para>Integrated window manager, file manager, sound manager,
+ <application>GNOME</application> compliance module, and more</para>
+ </listitem>
+
+ <listitem>
+ <para>Themeable (since it uses GTK+)</para>
+ </listitem>
+
+ <listitem>
+ <para>Fast, light and efficient: ideal for older/slower machines
+ or machines with memory limitations</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>More information on <application>XFce</application>
+ can be found on the <link xlink:href="http://www.xfce.org/">XFce
+ website</link>.</para>
+ </sect3>
+
+ <sect3 xml:id="x11-wm-xfce-install">
+ <title>Installing XFce</title>
+
+ <para>A binary package for <application>XFce</application>
+ exists (at the time of writing). To install, simply type:</para>
+
+ <screen>&prompt.root; <userinput>pkg_add -r xfce4</userinput></screen>
+
+ <para>Alternatively, to build from source, use the ports
+ collection:</para>
+
+ <screen>&prompt.root; <userinput>cd /usr/ports/x11-wm/xfce4</userinput>
+&prompt.root; <userinput>make install clean</userinput></screen>
+
+ <para>Now, tell the X server to launch
+ <application>XFce</application> the next time X is started.
+ Simply type this:</para>
+
+ <screen>&prompt.user; <userinput>echo "/usr/local/bin/startxfce4" &gt; ~/.xinitrc</userinput></screen>
+
+ <para>The next time X is started,
+ <application>XFce</application> will be the desktop.
+ As before, if a display manager like
+ <application>XDM</application> is being used, create an
+ <filename>.xsession</filename>, as described in the
+ section on <link linkend="x11-wm-gnome">GNOME</link>, but
+ with the <filename>/usr/local/bin/startxfce4</filename>
+ command; or, configure the display manager to allow
+ choosing a desktop at login time, as explained in
+ the section on <link linkend="x11-wm-kde-kdm">kdm</link>.</para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+</chapter>
diff --git a/zh_TW.UTF-8/books/porters-handbook/Makefile b/zh_TW.UTF-8/books/porters-handbook/Makefile
new file mode 100644
index 0000000000..50b8633a0b
--- /dev/null
+++ b/zh_TW.UTF-8/books/porters-handbook/Makefile
@@ -0,0 +1,39 @@
+#
+# $FreeBSD$
+#
+# Build the FreeBSD Porter's Handbook.
+#
+
+MAINTAINER=doc@FreeBSD.org
+
+DOC?= book
+
+FORMATS?= html-split html
+
+INSTALL_COMPRESSED?= gz
+INSTALL_ONLY_COMPRESSED?=
+
+#
+# SRCS lists the individual XML files that make up the document. Changes
+# to any of these files will force a rebuild
+#
+
+# XML content
+SRCS= book.xml
+
+# Images from the cross-document image library
+IMAGES_LIB+= callouts/1.png
+IMAGES_LIB+= callouts/2.png
+IMAGES_LIB+= callouts/3.png
+IMAGES_LIB+= callouts/4.png
+IMAGES_LIB+= callouts/5.png
+IMAGES_LIB+= callouts/6.png
+IMAGES_LIB+= callouts/7.png
+IMAGES_LIB+= callouts/8.png
+IMAGES_LIB+= callouts/9.png
+IMAGES_LIB+= callouts/10.png
+
+URL_RELPREFIX?= ../../../..
+DOC_PREFIX?= ${.CURDIR}/../../..
+
+.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/books/porters-handbook/book.xml b/zh_TW.UTF-8/books/porters-handbook/book.xml
new file mode 100644
index 0000000000..6daa695a85
--- /dev/null
+++ b/zh_TW.UTF-8/books/porters-handbook/book.xml
@@ -0,0 +1,12963 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE book PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
+ "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd">
+<!--
+ The FreeBSD Documentation Project
+
+ $FreeBSD$
+ Original Revision: 1.954
+-->
+<book xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="zh_tw">
+ <info><title>FreeBSD Porter's Handbook</title>
+
+
+ <authorgroup>
+ <author><orgname>FreeBSD 文件計劃</orgname></author>
+ </authorgroup>
+
+ <pubdate>April 2000</pubdate>
+
+ <copyright>
+ <year>2000</year>
+ <year>2001</year>
+ <year>2002</year>
+ <year>2003</year>
+ <year>2004</year>
+ <year>2005</year>
+ <year>2006</year>
+ <year>2007</year>
+ <year>2008</year>
+ <holder role="mailto:doc@FreeBSD.org">FreeBSD 文件計劃</holder>
+ </copyright>
+
+ &trademarks;
+
+ &legalnotice;
+
+ <releaseinfo>$FreeBSD$</releaseinfo>
+ </info>
+
+ <chapter xml:id="why-port">
+ <title>楔子</title>
+
+ <para>幾乎每個 FreeBSD 愛用者都是透過 FreeBSD Ports Collection
+ 來裝各式應用程式("ports")。如同 FreeBSD 的其他部分一樣,
+ 這些 ports 都主要來自許多志工的努力成果,所以在閱讀這份文件時,
+ 請務必感恩在心。</para>
+
+ <para>在 FreeBSD 上面,每個人都可以提交新的 port,
+ 或假如該 port 並沒有人維護的話,可以自願維護 &mdash;
+ 這點並不需要任何 commit 的權限,就可以來做這件事情。</para>
+
+ </chapter>
+
+ <chapter xml:id="own-port">
+ <title>自行打造 port</title>
+
+ <para>那麼,開始對自行製作 port 或更新有一些興趣了嗎?太好囉!</para>
+
+ <para>下面將介紹一些建立 port 時該注意的事項。如果是想升級現有的 port
+ ,那麼也請參閱 <xref linkend="port-upgrading"/> 說明。</para>
+
+ <para>因為這份文件可能講得不是十分詳細,可能需要參考
+ <filename>/usr/ports/Mk/bsd.port.mk</filename> 這檔是所有 port 的
+ Makefile 檔都會用到的。 就算你不是每天不斷 hacking Makefiles
+ ,也都可以藉由它來對整個 port 機制、Makefile 更瞭解,
+ 裡面的註釋相當詳細。 此外,若有其他特定 port 的問題,也可以到
+ &a.ports; 來獲得答案。</para>
+
+ <note>
+ <para>本文內所提及的環境變數
+ (<varname><replaceable>VAR</replaceable></varname>)部份,
+ 只有一些可以替換(overridden)。大部份的環境變數(非全部)通常都會寫在
+ <filename>/usr/ports/Mk/bsd.port.mk</filename> 內,其他的也是差不多。
+ 請注意:該檔並非使用一般的 tab 設定值,而是採用 1 個 tab 等於 4 個
+ space。 <application>Emacs</application> 與
+ <application>Vim</application> 應該都會在載入該檔時順便讀取相關設定值。
+ &man.vi.1; 及 &man.ex.1; 這兩個程式也都可以打
+ <command>:set tabstop=4</command> 以修改設定值。</para>
+ </note>
+ </chapter>
+
+ <chapter xml:id="quick-porting">
+ <title>打造 Port 快速上手篇</title>
+
+ <para>本節主要介紹如何來快速打造 port,然而,
+ 很多時候這些內容並不是很夠用,建議閱讀本文件中更深奧的地方。</para>
+
+ <para>首先取得該應用程式的原始程式碼壓縮檔(tarball),並把它放到
+ <varname>DISTDIR</varname>,預設路徑應該是
+ <filename>/usr/ports/distfiles</filename>。</para>
+
+ <note>
+ <para>下面的例子,是假設並不需要再修改該應用程式的原始碼,就可以在
+ FreeBSD 上編譯成功的;假如還需要另外修改才能成功編譯的話,
+ 那麼請參考下一章的說明。</para>
+ </note>
+
+ <sect1 xml:id="porting-makefile">
+ <title>編寫 <filename>Makefile</filename></title>
+
+ <para>最簡單的 <filename>Makefile</filename> 大概是像這樣:</para>
+
+ <programlisting># New ports collection makefile for: oneko
+# Date created: 5 December 1994
+# Whom: asami
+#
+# &dollar;FreeBSD&dollar;
+#
+
+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 &lt;bsd.port.mk&gt;</programlisting>
+
+ <para>嗯,大致就是這樣,看看你已經領略多少了呢?
+ 看到 <literal>&dollar;FreeBSD&dollar;</literal> 這一行的話,別想太多
+ ,它是 RCS ID 用途,當該 port 正式進入 port tree 時,
+ CVS 就會自動轉換為相關字串囉。 有關這點的細節部份,可以參閱 <link linkend="porting-samplem">sample Makefile</link> 章節。</para>
+ </sect1>
+
+ <sect1 xml:id="porting-desc">
+ <title>撰寫該軟體的說明檔</title>
+
+ <para>無論是否打算再加工做成 package,有 2 個檔案是任何實體 port (Slave
+ port則不一定)都必須要具備的。 這 2 個檔分別是
+ <filename>pkg-descr</filename> 檔及 <filename>pkg-plist</filename>
+ 檔。 這兩個檔案檔名前面都有 <filename>pkg-</filename>
+ 以跟其他檔案做區別。</para>
+
+ <sect2>
+ <title><filename>pkg-descr</filename></title>
+
+ <para>這是此 port 的詳細說明檔,請用一段或幾段文字來說明該 port
+ 的作用,並附上 WWW 網址(若有的話)。</para>
+
+ <note>
+ <para>請注意,這檔絕非「該軟體的說明手冊」或是「如何編譯、使用該
+ port 的說明」。 若是從該軟體的 <filename>README</filename>
+ 或 manpage 直接複製過來的話,請注意,因為它們通常都寫得太詳細、
+ 格式較特別(比如 manpage 會自動調整空白),
+ 請儘量避免這些冗長贅詞或採用特殊格式。若該軟體有官方版首頁的話,
+ 請在此列出來。 每個網址請用 <literal>WWW:</literal> 作為開頭,
+ 這樣子相關工具程式就會自動處理完畢。</para>
+ </note>
+
+ <para>該 port 的 <filename>pkg-descr</filename> 內容,大致如下面例子
+ :</para>
+
+ <programlisting>This is a port of oneko, in which a cat chases a poor mouse all over
+the screen.
+ :
+(etc.)
+
+WWW: http://www.oneko.org/</programlisting>
+ </sect2>
+
+ <sect2>
+ <title><filename>pkg-plist</filename></title>
+
+ <para>這是該 port 所會裝的所有檔案清單,另外因為 package
+ 會由這清單所產生,因此也被稱為『packing list
+ (打包清單)』。 以 <literal>${PREFIX}</literal> 為基準點,
+ 而用相對路徑表示。(<literal>${PREFIX}</literal> 通常是
+ <filename>/usr/local</filename> 或 <filename>/usr/X11R6</filename>)
+ 但是如果該程式有安裝 man page 的話,則要以類似
+ <varname>MAN<replaceable>n</replaceable>=</varname> 的方式寫在
+ <filename>Makefile</filename> 內,不能列在
+ <filename>pkg-plist</filename> 哦。
+ 除了列出檔案以外,也要把該 port 所會建立的目錄也列進去,
+ 方式有兩種:一種是寫在 <filename>pkg-plist</filename> 內的方式,
+ 比如:<literal>@dirrm</literal>。 至於另外一種方式,則是寫在
+ <filename>Makefile</filename> 內,比如:
+ <literal>PLIST_FILES=</literal> 之類的方式。</para>
+
+ <para>該 port 的 <filename>pkg-plist</filename> 內容,
+ 大致如下面例子:</para>
+
+ <programlisting>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</programlisting>
+
+ <para>關於 packing list 方面,可以參閱 &man.pkg.create.1; 會有詳解
+ 。</para>
+
+ <note>
+ <para>建議清單內的檔名,依照字母順序作排序,那麼下次要升級時,
+ 會比較清楚、方便來更新這份清單。 </para>
+ </note>
+
+ <note>
+ <para>手動生這份清單實在太苦了。尤其若該 port 會裝一大堆檔案的話,
+ 請多善用 <link linkend="plist-autoplist">自動產生 packing
+ list</link> 會比較省時省力唷。</para>
+ </note>
+
+ <para>只有在一種情況下可以省略不用生 <filename>pkg-plist</filename>
+ 檔: 若安裝的 port 相當單純,只有裝一些檔案,
+ 以及都在同一目錄下的話,那麼可以在 <filename>Makefile</filename>
+ 內改用 <varname>PLIST_FILES</varname> 及
+ <varname>PLIST_DIRS</varname> 來取代。
+ 比如,可以在上述的 <filename>oneko</filename> port 內不必附上
+ <filename>pkg-plist</filename> ,而只需在
+ <filename>Makefile</filename> 內加入下列幾行:</para>
+
+ <programlisting>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</programlisting>
+
+ <para>當然,若該 port 並無安裝自屬的目錄的話,就不必設
+ <varname>PLIST_DIRS</varname> 囉。</para>
+
+ <para>然而,使用 <varname>PLIST_FILES</varname>、
+ <varname>PLIST_DIRS</varname> 是必須付出代價:
+ 不能使用 &man.pkg.create.1; 內所說的 command sequences。
+ 因此,這招僅適用於較簡單的 port ,以及簡化該 port 的作法。
+ 此外,這招還有一個好處:可以減少 ports collection 的整體檔案總數。
+ 所以,在考慮是否一定要用 <filename>pkg-plist</filename> 之前,
+ 可以先斟酌這個替代方案看看。</para>
+
+ <para>後面會介紹到如何運用 <filename>pkg-plist</filename>、
+ <varname>PLIST_FILES</varname> 這些技巧以因應 <link linkend="plist">更複雜的狀況</link>。</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="porting-checksum">
+ <title>產生 checksum 用途的 distinfo 檔</title>
+
+ <para>只要打『<command>make makesum</command>』就好了,
+ 接下來就會自動產生相對應的 <filename>distinfo</filename> 檔了唷
+ 。</para>
+
+ <para>若抓下來的檔案,它的 checksum 會經常變更,
+ 而你也很確認所抓的來源是正確無誤的話,
+ (比如:來源是光碟或是每天自動產生的文件),那麼可以設定那些檔案為
+ <varname>IGNOREFILES</varname> 。 如此一來,在打
+ <command>make makesum</command> 的時候就不會計算那些檔案的 checksum
+ ,而自動改為 <literal>IGNORE</literal> 囉。</para>
+ </sect1>
+
+ <sect1 xml:id="porting-testing">
+ <title>檢驗 port 是否完整、可行</title>
+
+ <para>接下來,必須檢驗是否有符合 port 的遊戲規則,包括打包該 port
+ 為 package。 以下有幾個需要確認的重要地方:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>若該 port 沒裝的東西,不要列在 <filename>pkg-plist</filename>
+ 內。</para>
+ </listitem>
+
+ <listitem>
+ <para>若該 port 有裝的東西,請務必列在
+ <filename>pkg-plist</filename> 內。</para>
+ </listitem>
+
+ <listitem>
+ <para>該 port 可以用 <command>reinstall</command> 來重新安裝
+ 。</para>
+ </listitem>
+
+ <listitem>
+ <para>該 port 在移除之後,確定都可 <link linkend="plist-cleaning">cleans up</link>。</para>
+ </listitem>
+ </itemizedlist>
+
+ <procedure>
+ <title>建議的測試步驟順序:</title>
+
+ <step>
+ <para><command>make install</command></para>
+ </step>
+
+ <step>
+ <para><command>make package</command></para>
+ </step>
+
+ <step>
+ <para><command>make deinstall</command></para>
+ </step>
+
+ <step>
+ <para><command>pkg_add package-name
+ </command></para>
+ </step>
+
+ <step>
+ <para><command>make deinstall</command></para>
+ </step>
+
+ <step>
+ <para><command>make reinstall</command></para>
+ </step>
+
+ <step>
+ <para><command>make package</command></para>
+ </step>
+ </procedure>
+
+ <para>確認在 <buildtarget>package</buildtarget> 和
+ <buildtarget>deinstall</buildtarget> 這兩個階段都沒有任何錯誤訊息出現。
+ 完成第三步驟之後,檢查一下是否所裝的檔案、目錄都有移除完畢。 此外,
+ 第四步驟完成後,也檢查一下以 package 裝的該軟體,是否都能正常運作
+ 。</para>
+
+ <para>最周密的自動方式就是透過裝
+ <application>ports tinderbox</application>。 它會建立
+ <literal>jails</literal> 並管理之,以便您可以測試上述所有步驟,
+ 而不會真正影響您本身的作業系統。 詳情請參考
+ <filename>ports/ports-mgmt/tinderbox</filename>。</para>
+ </sect1>
+
+ <sect1 xml:id="porting-portlint">
+ <title>以 <command>portlint</command> 來作檢驗</title>
+
+ <para>請用 <command>portlint</command> 來檢查該 port
+ 是否有遵循上述遊戲規則。 說到這
+ <package>ports-mgmt/portlint</package>,它是
+ ports collection 的其中一個套件。 它主要可以用來檢驗 <link linkend="porting-samplem">Makefile</link> 內容是否正確以及 <link linkend="porting-pkgname">package</link> 是否有正確命名。</para>
+ </sect1>
+
+ <sect1 xml:id="porting-submitting">
+ <title>提交(Submit) port</title>
+
+ <para>首先,請確認是否有瞭解 <link linkend="porting-dads">DOs and DON'Ts</link> 該章部分。</para>
+
+ <para>現在你很高興終於打造出 port 來囉,唯一剩下要做的就是把它正式放到
+ FreeBSD ports tree 內,才能讓每個人都能分享使用這個 port。 請先拿掉
+ <filename>work</filename> 目錄或檔名像是
+ <filename>pkgname.tgz</filename> 的 package 可以砍掉。 接著,
+ 只要用 <command>shar `find port_dir`</command> 來產生 shar 格式,
+ 並配合 &man.send-pr.1; 程式以提交出去。(&man.send-pr.1;
+ 的部分可以參閱 <link xlink:href="&url.articles.contributing;/contrib-how.html#CONTRIB-GENERAL">
+ 錯誤報告和意見發表</link>)</para>
+
+ <para>記得在填寫 PR 時『分類(Category)』選 <literal>ports</literal>,
+ 還有『種類(Class)』填 <literal>change-request</literal>
+ (千萬別傻傻地把該 PR 的『Confidential(機密)』設為 yes!),
+ 此外在『描述(<quote>Description</quote>)』
+ 那邊寫上該程式的簡潔說明,而 shar 檔則附在『修正(<quote>Fix</quote>)
+ 』欄位內。</para>
+
+ <note>
+ <para>若 Synopsis 欄清楚描述該 PR 重點的話,那麼會讓整個流程更為順暢。
+ new ports 的話,我們習慣用:
+ <quote>New port: &lt;category&gt;/&lt;portname&gt;
+ &lt;該 port 的簡介&gt;</quote> ,而更新 port 的話,則是
+ <quote>Update port: &lt;category&gt;/&lt;portname&gt;
+ &lt;本次 update 的簡介&gt;</quote>。
+ 若你也採用這樣的格式的話,那麼會被受理的機會就會越高囉。</para>
+ </note>
+
+ <para>再次強調一點:<emphasis>不必附上原始 source 的 distfile
+ ,也就是 <filename>work</filename> 目錄。 同時,也不必附上
+ <command>make package</command> 時產生的 package</emphasis>。</para>
+
+ <para>送出 port 之後,請耐心等候佳音。
+ 有時候可能需要等個幾天或幾個月時間,才會在 FreeBSD ports tree
+ 上正式出現。 此外,隨時可以查閱 <link xlink:href="http://www.FreeBSD.org/cgi/query-pr-summary.cgi?category=ports">
+ 等待 committed to FreeBSD 的 port</link> 列表。</para>
+
+ <para>一旦我們開始處理你送來的 port 之後,如果有一些意見需要溝通的話,
+ 那麼會先 feedback 給你,
+ 之後確定都沒問題,就會放到 port tree 內囉!
+ 你的大名會被記在 <link xlink:href="&url.articles.contributors;/contrib-additional.html">Additional FreeBSD Contributors</link>
+ 列表上,以及其他檔案。聽起來,挺不賴的不是嗎!? <!-- smiley
+ -->:-)</para>
+ </sect1>
+ </chapter>
+
+ <chapter xml:id="slow">
+ <title>Slow Porting</title>
+
+ <para>Ok...事實上並不太可能這麼簡單,port
+ 方面可能需要作些修改才能正常使用。 因此,
+ 本節將一步一步來介紹如何修改上一章的樣本以正常使用。</para>
+
+ <sect1 xml:id="slow-work">
+ <title>How things work</title>
+
+ <para>首先,先介紹一下在你所作的 port 目錄內打 <command>make</command>
+ 時,所會作哪些事情的順序吧。
+ 你可以另開一窗來看 <filename>bsd.port.mk</filename>
+ 內容,以便瞭解我們下面在講什麼。</para>
+
+ <para>但別太擔心是否完全看懂
+ <filename>bsd.port.mk</filename> 在做啥,很多人都還沒完全看完...
+ <!-- smiley --><emphasis>:-&gt;</emphasis></para>
+
+ <procedure>
+
+ <step>
+ <para>首先,進行 <buildtarget>fetch</buildtarget> 階段。
+ <buildtarget>fetch</buildtarget> 是確認 tarball 檔有沒有已在
+ <varname>DISTDIR</varname> 內了?若 <buildtarget>fetch</buildtarget>
+ 在 <varname>DISTDIR</varname> 找不到的話,它會搜尋 Makefile
+ 內的 <varname>MASTER_SITES</varname> URL
+ ,或者是主 FTP 站專門放備份 distfiles 的目錄 <uri xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/">ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/</uri>
+ 。 假設都找不到的話,但是網路有接上 Internet 的話,它會試著用
+ <varname>FETCH</varname> 來抓所指定的檔案。
+ 抓到之後,它會把檔案存到 <varname>DISTDIR</varname>
+ 以便開始使用或日後運用。</para>
+ </step>
+
+ <step>
+ <para>其次,進行 <buildtarget>extract</buildtarget> 階段,它會從
+ <varname>DISTDIR</varname> 內找出該 port 所需的檔案(通常是 gzip
+ 格式的 tarball),然後解壓縮到 <varname>WRKDIR</varname>
+ 所設定的臨時目錄名稱(預設是 <filename>work</filename> 目錄)內
+ 。</para>
+ </step>
+
+ <step>
+ <para>之後,進行 <buildtarget>patch</buildtarget> 階段,
+ 一開始會先套用 <varname>PATCHFILES</varname> 所指定的任何 patch
+ 檔。 接著是 <varname>PATCHDIR</varname>(預設是
+ <filename>files</filename> 子目錄) 內的檔名為
+ <filename>patch-*</filename>
+ 之類的檔案,會以字母順序而逐一套用 patch。</para>
+ </step>
+
+ <step>
+ <para>接著是 <buildtarget>configure</buildtarget> 階段,可以照 port
+ 的類型來作各種不同設定以調整,比如:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>若有放 <filename>scripts/configure</filename> 的話,
+ 那麼就會跑裡面的設定。</para>
+ </listitem>
+
+ <listitem>
+ <para>若有設 <varname>HAS_CONFIGURE</varname> 或是
+ <varname>GNU_CONFIGURE</varname> 的話,那麼就會跑
+ <filename>WRKSRC/configure</filename></para>
+ </listitem>
+
+ <listitem>
+ <para>若有設 <varname>USE_IMAKE</varname> 的話,那麼就會跑
+ <varname>XMKMF</varname> (預設是 <command>xmkmf
+ -a</command>) 。</para>
+ </listitem>
+ </orderedlist>
+ </step>
+
+ <step>
+ <para>最後是 <buildtarget>build</buildtarget> 階段,它會在該
+ port 的 working directory(由 <varname>WRKSRC</varname> 所設定)
+ 內開始編譯。 若有設 <varname>USE_GMAKE</varname> 的話,
+ 那麼就會改用 GNU <command>make</command> 來編譯,
+ 否則就用系統本身的 <command>make</command> 來編譯。</para>
+ </step>
+ </procedure>
+
+ <para>上面講的都是打 <command>make</command> 時的預設階段。
+ 此外,還可以設定各階段之前、之後要作的事情:透過定義
+ <buildtarget>pre-<replaceable>something</replaceable></buildtarget> 或
+ <buildtarget>post-<replaceable>something</replaceable></buildtarget>,
+ 或者把這些檔名的 script 丟到 <filename>scripts</filename> 子目錄去,
+ 這樣子它們就會在各預設階段的之前、之後進行囉。</para>
+
+ <para>舉例來說,若在 <filename>Makefile</filename> 內設定
+ <buildtarget>post-extract</buildtarget>,而且在
+ <filename>scripts</filename> 子目錄內又有
+ <filename>pre-build</filename> 檔的話,那麼在作解壓縮之後,就會開始
+ <buildtarget>post-extract</buildtarget> 階段以進行解壓縮後的後續動作,
+ 而在跑 build 階段之前,就會先執行 <filename>pre-build</filename>
+ 這隻 script 作先期準備。 通常較簡單的修改動作,建議直接放在
+ <filename>Makefile</filename> 內就好了,
+ 因為這樣會比較方便加上這些原本沒有的階段,同時也方便他人協助除錯
+ 。</para>
+
+ <para>預設的各階段動作都是照 <filename>bsd.port.mk</filename> 內的
+ <buildtarget>do-<replaceable>something</replaceable></buildtarget>
+ 之類所定義的。 舉例:<buildtarget>do-extract</buildtarget>
+ 就是定義怎麼把檔案解壓縮的。
+ 若對預設方式覺得不妥的話,都可以在該 port 的
+ <filename>Makefile</filename> 重新定義。</para>
+
+ <note>
+ <para>The <quote>main</quote> targets (e.g.,
+ <buildtarget>extract</buildtarget>,
+ <buildtarget>configure</buildtarget>, 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
+ <buildtarget>do-extract</buildtarget>, but never ever change
+ the way <buildtarget>extract</buildtarget> operates!</para>
+ </note>
+
+ <para>現在,你已經知道打 <command>make</command> 到底會作些什麼事囉,
+ 接下來會教你如何作更完美的 port。</para>
+ </sect1>
+
+ <sect1 xml:id="slow-sources">
+ <title>取得原始的 source 檔</title>
+
+ <para>取得原始的 source 檔(通常檔名是
+ <filename>foo.tar.gz</filename>
+ 或 <filename>foo.tar.Z</filename>
+ 之類的壓縮檔),然後會把抓下來的檔案放在 <varname>DISTDIR</varname>
+ 內。 記得:抓的時候,儘量使用『該軟體主要的正式網站』上面的來源檔
+ ,以確保檔案有效、可信。</para>
+
+ <para>需要設 <varname>MASTER_SITES</varname> 以指定原始檔案是放在何處。
+ 相關網址在 <filename>bsd.sites.mk</filename>
+ 內有一些方便的速記表可以使用。 請盡可能多用對應這些網址的變數,
+ 以避免同樣的一堆網址有重複很多次出現在 port tree 內。
+ 否則,這些網址只要一有改變的話,那麼就會成為維護 port 的夢魘。</para>
+
+ <para>如果該檔並沒有放在公開的 FTP 站或網站(HTTP)上,
+ 或者該檔並非一般標準格式的話,
+ 那麼可以考慮複製該檔,然後放到你可掌握、可信任的 FTP 站或網站(HTTP)
+ 上,比如:你自己的網頁空間。</para>
+
+ <para>若找不到地方(方便、可信任)來放檔案的話,
+ 那麼可以 <quote>house(暫放)</quote> 在
+ <systemitem>ftp.FreeBSD.org</systemitem> 上的 committer 自屬空間內;
+ 然而,這是最不理想的解法。
+ 檔案要放到該 committer 的 <systemitem>freefall</systemitem> 上的
+ <filename>~/public_distfiles/</filename> 目錄內才可以。
+ 請與協助 commit 你的 port 的那位 committer 聯繫,
+ 以便把檔案放到他的目錄內。
+ 那位 committer 同時也會把 <varname>MASTER_SITES</varname> 設為
+ <varname>MASTER_SITE_LOCAL</varname>,並且把
+ <varname>MASTER_SITE_SUBDIR</varname> 設為他自己的
+ <systemitem>freefall</systemitem> 帳號名稱。</para>
+
+ <para>若該 port 的原始檔打包會經常重包,但原作者卻沒更新版號的話,
+ 請考慮把該檔改放到自己的網頁空間,並且把自己網頁空間列為
+ <varname>MASTER_SITES</varname> 的第一順位。
+ 或者請與原作者聯繫:請他不要這樣做(不斷重包同樣的檔案);如此一來,
+ 才有助於建立一定程度的 source code 版本控制。
+ 把檔案另外複製一份放到自屬網頁空間的話,不但可有效防止使用者會發生
+ <errorname>checksum mismatch(檔案經檢查有問題)</errorname>
+ 的錯誤訊息,也可降低我們 FTP 站維護者的工作量。此外,若該 port
+ 的檔案僅有一個主要網址,
+ 那麼建議:請在自屬網站上放上備份檔,並修改
+ <varname>MASTER_SITES</varname> 把你的網址列為第二順位。</para>
+
+ <para>若該 port 需要一些額外 `patches'(可透過 Internet 下載),並放在
+ <varname>DISTDIR</varname> 內,不必擔心這些 patch
+ 檔是否得都跟原始檔一樣來自同一網站,
+ 這些情況有另外的解法(請看下面的 <link linkend="porting-patchfiles">PATCHFILES</link> 介紹部分)。</para>
+ </sect1>
+
+ <sect1 xml:id="slow-modifying">
+ <title>量身打造 port</title>
+
+ <para>解開壓縮檔,然後開始逐一修改,使該 port 在目前所用的 FreeBSD
+ 版本上得以順利編譯。
+ 所做的每個動作請都 <emphasis>仔細記錄</emphasis>,
+ 如此一來才能迅速自動套用這些修改。
+ 在完成 port 之後,每項動作包括:對於檔案的刪除、增加、修改,
+ 要記得存為自動化的 script 或者 patch 檔形式,以利他人直接套用。</para>
+
+ <para>若該 port 需要使用者的互動、自訂功能來編譯、安裝的話,
+ 那麼建議揣摩看看 Larry Wall 的經典之作
+ <application>Configure</application> scripts 來完成類似效果。
+ Ports collection 的目的之一,就是讓每個 port 儘量用最小空間,
+ 來做出軟體的 <quote>plug-and-play(即插即用)</quote>。</para>
+
+ <note>
+ <para>除非有明確聲明,否則你所提交給 FreeBSD ports collection 的
+ patch 檔、相關 script 檔及其他檔案,都會假設是以標準的 BSD
+ 版權形式來發佈。</para>
+ </note>
+ </sect1>
+
+ <sect1 xml:id="slow-patch">
+ <title>Patching</title>
+
+ <para>在 port 的準備過程中,新增或變更過的檔案,
+ 可以利用 &man.diff.1; 將這些變動列出,
+ 以便後續讓 &man.patch.1; 使用。
+ 所有你想套用的 patch 都應該命名為
+ <filename>patch-*</filename>,其中
+ <replaceable>*</replaceable> 表示要 patch 檔案的路徑及檔名名稱,
+ 例如 <filename>patch-Imakefile</filename> 或
+ <filename>patch-src-config.h</filename>。
+ 這些檔案都應該儲存在 <varname>PATCHDIR</varname>
+ (通常是 <filename>files/</filename>,放在其內的檔案都會自動被套用。
+ 所有 patch 檔路徑都是相對於
+ <varname>WRKSRC</varname> (通常會將 port 的 tarball 解壓到裡面,
+ port 的建置也會在這裡完成)。
+ 為了能讓修正和更新更順利,你應該避免多個 patch 修正同一個檔案
+ (舉例來說,<filename>patch-file</filename> 和
+ <filename>patch-file2</filename> 同時更動
+ <filename>WRKSRC/foobar.c</filename>)。</para>
+
+ <para>請只使用 <literal>[-+._a-zA-Z0-9]</literal> 這些字元來命名
+ patch 檔,不要使用這些字元以外的字元。
+ 千萬不要將你的 patch 檔命名成 <filename>patch-aa</filename> 或是
+ <filename>patch-ab</filename> 等名稱,
+ 請使用路徑和名稱相關的命名。</para>
+
+ <para>不要將 RCS 字串放進你的 patch 檔。CVS 會在這些檔案送入
+ ports tree 的時候弄亂檔案內容,而且在將它們重新 check out
+ 出來後,會因檔案內容的差異造成 patch 失敗。
+ RCS 字串是以錢字號 (<literal>&dollar;</literal>) 括起來的,
+ 通常以 <literal>&dollar;Id</literal> 或
+ <literal>&dollar;RCS</literal> 為開頭。</para>
+
+ <para>你可以使用 &man.diff.1; 搭配 recurse (<option>-r</option>) 選項
+ 來產生 patch 檔,但請再次檢視產生出的 patch 檔,確保你沒有產生
+ 任何不必要的垃圾資訊在裡面。特別是對那些經由
+ <command>Imake</command> 或 GNU <command>configure</command>
+ 所產生的 <filename>Makefile</filename> 檔產生 patch,
+ 都是不必要的,這類的 patch 檔都應該被刪除。假如你必須透過修改
+ <command>configure.in</command> 再執行
+ <command>autoconf</command> 來重新產生
+ <command>configure</command>,不要對
+ <command>configure</command> 產生 patch 檔 (這往往會長成數千行!);
+ 請定義 <literal>USE_AUTOTOOLS=autoconf:261</literal> 並對
+ <filename>configure.in</filename> 產生 patch 檔。</para>
+
+ <para>請儘量不要對無用的 whitespace 作修改,因為在 Open Source 界各個
+ project 都會使用很多相同的 code base,這些可能卻是採用不同的編排方式
+ 、coding style。 若要試圖改變這些編排風格的話,請小心:
+ 這些只會是徒勞無功的更改。 此外不僅會造成 CVS repository 空間浪費,
+ 也會讓人難以找出真正問題癥結所在,以及分辨不出這段 patch 到底在作什麼
+ 。</para>
+
+ <para>假如你必須刪除一個檔案,那麼你可以在
+ <buildtarget>post-extract</buildtarget> 階段做這件事,
+ 而不是在 patch 階段。</para>
+
+ <para>你可以直接在 port 的
+ <filename>Makefile</filename> 中完成簡單的置換工作,只需使用
+ &man.sed.1; 的 in-place mode 即可。這在只需 patch 一個變數的值時相當有用。
+ 例如:</para>
+
+ <programlisting>post-patch:
+ @${REINPLACE_CMD} -e 's|for Linux|for FreeBSD|g' ${WRKSRC}/README
+ @${REINPLACE_CMD} -e 's|-pthread|${PTHREAD_LIBS}|' ${WRKSRC}/configure</programlisting>
+
+ <para>在移植軟體時,特別是那些在 &windows; 平台開發的軟體,
+ 時常會遇到一種情況,就是在大部份的 source file 中,
+ 使用 CR/LF 做為斷行。這會影響往後的 patching、compiler warnings、以及
+ scripts execution (找不到 <command>/bin/sh^M</command> 的情況) 等。
+ 為了快速轉換 CR/LF 為 LF,可以把
+ <literal>USE_DOS2UNIX=yes</literal> 加到 port 的
+ <filename>Makefile</filename> 檔中。
+ 你也可以設定成只針對指定的檔案做轉換:</para>
+
+ <programlisting>USE_DOS2UNIX= util.c util.h</programlisting>
+
+ <para>若想要轉換所有子目錄內的某類別檔案,可以使用
+ <varname>DOS2UNIX_REGEX</varname>。 它的參數是
+ <command>find</command> 相容的正規表達式。 相關格式可參閱
+ &man.re.format.7;。 對於所指定副檔名的檔案之轉換而言,這相當好用,
+ 舉例來說,只動所有原始碼部分而不改 binary 檔案:</para>
+
+ <programlisting>USE_DOS2UNIX= yes
+DOS2UNIX_REGEX= .*\.(c|cpp|h)</programlisting>
+ </sect1>
+
+ <sect1 xml:id="slow-configure">
+ <title>設定</title>
+
+ <para>將任何額外的自訂指令包含進你的
+ <filename>configure</filename> script 中,且將它儲存在
+ <filename>scripts</filename> 的子資料夾裡。 如同上面提到的,
+ 你也可以在 <filename>Makefile</filename> 或者是在
+ 名稱為 <filename>pre-configure</filename> 或
+ <filename>post-configure</filename> 的 script 檔中做同樣的事。</para>
+ </sect1>
+
+ <sect1 xml:id="slow-user-input">
+ <title>處理使用者輸入</title>
+
+ <para>如果該 port 需要使用者作出選擇才能安裝的話,
+ 則必須在 <filename>Makefile</filename> 加上
+ <varname>IS_INTERACTIVE</varname> 變數。 如此一來若使用者有設定
+ <envar>BATCH</envar> 環境變數的話,就會略過該 port 而繼續
+ <quote>overnight builds</quote>(若使用者把該環境變數值設為
+ <envar>BATCH</envar> 的話,那麼 <emphasis>只有</emphasis>
+ 那些需要與使用者互動的 port 才會編譯。)。
+ 這使得那些需要不停編譯 port 的機器會省下許多時間(後面會說明這點)
+ 。</para>
+
+ <para>此外建議,若是這些互動問題有合適的預設選項的話,
+ 那應確認一下 <varname>PACKAGE_BUILDING</varname> 變數該如何設,
+ 才能配合該變數而決定是否停止互動。 如此一來才可以自動編譯出
+ CDROM 與 FTP 上的套件。</para>
+ </sect1>
+ </chapter>
+
+ <chapter xml:id="makefile">
+ <title>設定 Makefile</title>
+
+ <para>設定 <filename>Makefile</filename> 是件非常簡單的事,
+ 建議您在開始前,先看看範例。Also, there is a
+ <link linkend="porting-samplem">sample Makefile</link> 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.</para>
+
+ <para>Now, consider the following problems in sequence as you design
+ your new <filename>Makefile</filename>:</para>
+
+ <sect1 xml:id="makefile-source">
+ <title>The original source</title>
+
+ <para>Does it live in <varname>DISTDIR</varname> as a standard
+ gzip'd tarball named something like
+ <filename>foozolix-1.2.tar.gz</filename>? If so, you can go on
+ to the next step. If not, you should look at overriding any of
+ the <varname>DISTVERSION</varname>, <varname>DISTNAME</varname>,
+ <varname>EXTRACT_CMD</varname>,
+ <varname>EXTRACT_BEFORE_ARGS</varname>,
+ <varname>EXTRACT_AFTER_ARGS</varname>,
+ <varname>EXTRACT_SUFX</varname>, or <varname>DISTFILES</varname>
+ variables, depending on how alien a format your port's
+ distribution file is. (The most common case is
+ <literal>EXTRACT_SUFX=.tar.Z</literal>, when the tarball is
+ condensed by regular <command>compress</command>, not
+ <command>gzip</command>.)</para>
+
+ <para>In the worst case, you can simply create your own
+ <buildtarget>do-extract</buildtarget> target to override the
+ default, though this should be rarely, if ever,
+ necessary.</para>
+ </sect1>
+
+ <sect1 xml:id="makefile-naming">
+ <title>Naming</title>
+
+ <para>The first part of the port's <filename>Makefile</filename> names
+ the port, describes its version number, and lists it in the correct
+ category.</para>
+
+ <sect2>
+ <title><varname>PORTNAME</varname> and <varname>PORTVERSION</varname></title>
+
+ <para>You should set <varname>PORTNAME</varname> to the
+ base name of your port, and <varname>PORTVERSION</varname>
+ to the version number of the port.</para>
+ </sect2>
+
+ <sect2 xml:id="makefile-naming-revepoch">
+ <title><varname>PORTREVISION</varname> and
+ <varname>PORTEPOCH</varname></title>
+
+ <sect3>
+ <title><varname>PORTREVISION</varname></title>
+
+ <para>The <varname>PORTREVISION</varname> variable is a
+ monotonically increasing value which is reset to 0 with
+ every increase of <varname>PORTVERSION</varname> (i.e.
+ every time a new official vendor release is made), and
+ appended to the package name if non-zero.
+ Changes to <varname>PORTREVISION</varname> are
+ used by automated tools (e.g. &man.pkg.version.1;)
+ to highlight the fact that a new package is
+ available.</para>
+
+ <para><varname>PORTREVISION</varname> should be increased
+ each time a change is made to the port which significantly
+ affects the content or structure of the derived
+ package.</para>
+
+ <para>Examples of when <varname>PORTREVISION</varname>
+ should be bumped:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Addition of patches to correct security
+ vulnerabilities, bugs, or to add new functionality to
+ the port.</para>
+ </listitem>
+
+ <listitem>
+ <para>Changes to the port <filename>Makefile</filename> to enable or disable
+ compile-time options in the package.</para>
+ </listitem>
+
+ <listitem>
+ <para>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).</para>
+ </listitem>
+
+ <listitem>
+ <para>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)).</para>
+ </listitem>
+
+ <listitem>
+ <para>Silent changes to the port distfile which have
+ significant functional differences, i.e. changes to
+ the distfile requiring a correction to
+ <filename>distinfo</filename> with no corresponding change to
+ <varname>PORTVERSION</varname>, where a <command>diff
+ -ru</command> of the old and new versions shows
+ non-trivial changes to the code.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Examples of changes which do not require a
+ <varname>PORTREVISION</varname> bump:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Style changes to the port skeleton with no
+ functional change to what appears in the resulting
+ package.</para>
+ </listitem>
+
+ <listitem>
+ <para>Changes to <varname>MASTER_SITES</varname> or
+ other functional changes to the port which do not
+ affect the resulting package.</para>
+ </listitem>
+
+ <listitem>
+ <para>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.</para>
+ </listitem>
+
+ <listitem>
+ <para>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 <varname>PORTREVISION</varname> reflects
+ the content of the package, if the package was not
+ previously buildable then there is no need to increase
+ <varname>PORTREVISION</varname> to mark a
+ change.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>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
+ <varname>PORTREVISION</varname> should be bumped.</para>
+ </sect3>
+
+ <sect3>
+ <title><varname>PORTEPOCH</varname></title>
+
+ <para>From 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).</para>
+
+ <para>In situations such as this, the
+ <varname>PORTEPOCH</varname> version should be increased.
+ If <varname>PORTEPOCH</varname> is nonzero it is appended
+ to the package name as described in section 0 above.
+ <varname>PORTEPOCH</varname> 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.
+ <literal>1.0,1</literal> in the above example) is still
+ numerically less than the previous version (20000801), but
+ the <literal>,1</literal> suffix is treated specially by
+ automated tools and found to be greater than the implied
+ suffix <literal>,0</literal> on the earlier package.</para>
+
+ <para>Dropping or resetting <varname>PORTEPOCH</varname>
+ 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.</para>
+
+ <para>It is expected that <varname>PORTEPOCH</varname> will
+ not be used for the majority of ports, and that sensible
+ use of <varname>PORTVERSION</varname> 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 &mdash; such as a code
+ <quote>snapshot</quote> release. The temptation is to label the
+ release with the release date, which will cause problems
+ as in the example above when a new <quote>official</quote> release is
+ made.</para>
+
+ <para>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
+ <varname>PORTVERSION</varname> of 1.2.20000917 or similar,
+ not 20000917, so that the succeeding release, say 1.3, is
+ still a numerically greater value.</para>
+ </sect3>
+
+ <sect3>
+ <title>Example of <varname>PORTREVISION</varname> and
+ <varname>PORTEPOCH</varname> usage</title>
+
+ <para>The <literal>gtkmumble</literal> port, version
+ <literal>0.10</literal>, is committed to the ports
+ collection:</para>
+
+ <programlisting>PORTNAME= gtkmumble
+PORTVERSION= 0.10</programlisting>
+
+ <para><varname>PKGNAME</varname> becomes
+ <literal>gtkmumble-0.10</literal>.</para>
+
+ <para>A security hole is discovered which requires a local
+ FreeBSD patch. <varname>PORTREVISION</varname> is bumped
+ accordingly.</para>
+
+ <programlisting>PORTNAME= gtkmumble
+PORTVERSION= 0.10
+PORTREVISION= 1</programlisting>
+
+ <para><varname>PKGNAME</varname> becomes
+ <literal>gtkmumble-0.10_1</literal></para>
+
+ <para>A new version is released by the vendor, numbered <literal>0.2</literal>
+ (it turns out the author actually intended
+ <literal>0.10</literal> to actually mean
+ <literal>0.1.0</literal>, not <quote>what comes after
+ 0.9</quote> - oops, too late now). Since the new minor
+ version <literal>2</literal> is numerically less than the
+ previous version <literal>10</literal>, the
+ <varname>PORTEPOCH</varname> must be bumped to manually
+ force the new package to be detected as <quote>newer</quote>. Since it
+ is a new vendor release of the code,
+ <varname>PORTREVISION</varname> is reset to 0 (or removed
+ from the <filename>Makefile</filename>).</para>
+
+ <programlisting>PORTNAME= gtkmumble
+PORTVERSION= 0.2
+PORTEPOCH= 1</programlisting>
+
+ <para><varname>PKGNAME</varname> becomes
+ <literal>gtkmumble-0.2,1</literal></para>
+
+ <para>The next release is 0.3. Since
+ <varname>PORTEPOCH</varname> never decreases, the version
+ variables are now:</para>
+
+ <programlisting>PORTNAME= gtkmumble
+PORTVERSION= 0.3
+PORTEPOCH= 1</programlisting>
+
+ <para><varname>PKGNAME</varname> becomes
+ <literal>gtkmumble-0.3,1</literal></para>
+
+ <note>
+ <para>If <varname>PORTEPOCH</varname> were reset
+ to <literal>0</literal> with this upgrade, someone who had
+ installed the <literal>gtkmumble-0.10_1</literal> package would not detect
+ the <literal>gtkmumble-0.3</literal> package as newer, since
+ <literal>3</literal> is still numerically less than
+ <literal>10</literal>. Remember, this is the whole point of
+ <varname>PORTEPOCH</varname> in the first place.</para>
+ </note>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title><varname>PKGNAMEPREFIX</varname> and <varname>PKGNAMESUFFIX</varname></title>
+
+ <para>Two optional variables, <varname>PKGNAMEPREFIX</varname> and
+ <varname>PKGNAMESUFFIX</varname>, are combined with
+ <varname>PORTNAME</varname> and
+ <varname>PORTVERSION</varname> to
+ form <varname>PKGNAME</varname> as
+ <literal>${PKGNAMEPREFIX}${PORTNAME}${PKGNAMESUFFIX}-${PORTVERSION}</literal>.
+ Make sure this conforms to our <link linkend="porting-pkgname">guidelines for a good package
+ name</link>. In particular, you are <emphasis>not</emphasis> allowed to use a
+ hyphen (<literal>-</literal>) in
+ <varname>PORTVERSION</varname>. Also, if the package name
+ has the <replaceable>language-</replaceable> or the
+ <replaceable>-compiled.specifics</replaceable> part (see below), use
+ <varname>PKGNAMEPREFIX</varname> and
+ <varname>PKGNAMESUFFIX</varname>, respectively. Do not make
+ them part of <varname>PORTNAME</varname>.</para>
+ </sect2>
+
+ <sect2>
+ <title><varname>LATEST_LINK</varname></title>
+
+ <para>在某些情況,可能會同時存在有不同版本的同一程式。
+ 由於它們可能會有同樣的 <varname>PORTNAME</varname>、
+ <varname>PKGNAMEPREFIX</varname>,甚至
+ <varname>PKGNAMESUFFIX</varname> 也相同,所以得讓這些程式有所不同,
+ 才能讓 port 的 index 以及 package 能順利產生。 遇到這類情況,
+ the optional <varname>LATEST_LINK</varname> variable should be set to
+ a different value for all ports except the <quote>main</quote>
+ one &mdash; see the <filename>editors/vim5</filename> and
+ <filename>editors/vim</filename> ports, and the
+ <filename>www/apache*</filename> family for examples of its use.
+ Note that how to choose a <quote>main</quote> version &mdash;
+ <quote>most popular</quote>, <quote>best supported</quote>,
+ <quote>least patched</quote>, and so on &mdash; 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
+ <quote>main</quote> one.</para>
+ </sect2>
+
+ <sect2 xml:id="porting-pkgname">
+ <title>Package Naming Conventions</title>
+
+ <para>The 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!</para>
+
+ <para>The package name should look like
+ <filename>language_region-name-compiled.specifics-version.numbers</filename>.</para>
+
+ <para>The package name is defined as
+ <literal>${PKGNAMEPREFIX}${PORTNAME}${PKGNAMESUFFIX}-${PORTVERSION}</literal>.
+ Make sure to set the variables to conform to that format.</para>
+
+ <orderedlist>
+ <listitem>
+ <para>FreeBSD strives to support the native language of its users.
+ The <replaceable>language-</replaceable> 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
+ <literal>ja</literal> for Japanese, <literal>ru</literal> for
+ Russian, <literal>vi</literal> for Vietnamese,
+ <literal>zh</literal> for Chinese, <literal>ko</literal> for
+ Korean and <literal>de</literal> for German.</para>
+
+ <para>If the port is specific to a certain region within the
+ language area, add the two letter country code as well.
+ Examples are <literal>en_US</literal> for US English and
+ <literal>fr_CH</literal> for Swiss French.</para>
+
+ <para>The <replaceable>language-</replaceable> part should
+ be set in the <varname>PKGNAMEPREFIX</varname> variable.</para>
+ </listitem>
+
+ <listitem>
+ <para>The first letter of the <filename>name</filename> 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 <literal>Perl 5</literal> modules by
+ prepending <literal>p5-</literal> and converting the double-colon
+ separator to a hyphen; for example, the
+ <literal>Data::Dumper</literal> module becomes
+ <literal>p5-Data-Dumper</literal>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Make sure that the port's name and version are clearly
+ separated and placed into the <varname>PORTNAME</varname> and
+ <varname>PORTVERSION</varname> variables. The only reason for
+ <varname>PORTNAME</varname> to contain a version part is if
+ the upstream distribution is really named that way, as in
+ the <filename>textproc/libxml2</filename> or
+ <filename>japanese/kinput2-freewnn</filename> ports. Otherwise,
+ the <varname>PORTNAME</varname> should not contain any
+ version-specific information. It is quite normal for several
+ ports to have the same <varname>PORTNAME</varname>, as the
+ <filename>www/apache*</filename> ports do; in that case,
+ different versions (and different index entries) are
+ distinguished by the <varname>PKGNAMEPREFIX</varname>,
+ <varname>PKGNAMESUFFIX</varname>, and
+ <varname>LATEST_LINK</varname> values.</para>
+ </listitem>
+
+ <listitem>
+ <para>If the port can be built with different <link linkend="makefile-masterdir">hardcoded defaults</link> (usually
+ part of the directory name in a family of ports), the
+ <replaceable>-compiled.specifics</replaceable> part should state
+ the compiled-in defaults (the hyphen is optional). Examples are
+ papersize and font units.</para>
+
+ <para>The <replaceable>-compiled.specifics</replaceable> part
+ should be set in the <varname>PKGNAMESUFFIX</varname>
+ variable.</para>
+ </listitem>
+
+ <listitem>
+ <para>The version string should follow a dash
+ (<literal>-</literal>) 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
+ <literal>pl</literal> (meaning <quote>patchlevel</quote>), which can be
+ used <emphasis>only</emphasis> when there are no major and
+ minor version numbers in the software. If the software
+ version has strings like <quote>alpha</quote>, <quote>beta</quote>, <quote>rc</quote>, or <quote>pre</quote>, 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.</para>
+
+ <para>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
+ <literal>yyyy.mm.dd</literal>
+ format, not
+ <literal>dd.mm.yyyy</literal>
+ or the non-Y2K compliant
+ <literal>yy.mm.dd</literal>
+ format.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>Here are some (real) examples on how to convert the name
+ as called by the software authors to a suitable package
+ name:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="6">
+ <thead>
+ <row>
+ <entry>Distribution Name</entry>
+ <entry><varname>PKGNAMEPREFIX</varname></entry>
+ <entry><varname>PORTNAME</varname></entry>
+ <entry><varname>PKGNAMESUFFIX</varname></entry>
+ <entry><varname>PORTVERSION</varname></entry>
+ <entry>Reason</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>mule-2.2.2</entry>
+ <entry>(empty)</entry>
+ <entry>mule</entry>
+ <entry>(empty)</entry>
+ <entry>2.2.2</entry>
+ <entry>No changes required</entry>
+ </row>
+
+ <row>
+ <entry>EmiClock-1.0.2</entry>
+ <entry>(empty)</entry>
+ <entry>emiclock</entry>
+ <entry>(empty)</entry>
+ <entry>1.0.2</entry>
+ <entry>No uppercase names for single programs</entry>
+ </row>
+
+ <row>
+ <entry>rdist-1.3alpha</entry>
+ <entry>(empty)</entry>
+ <entry>rdist</entry>
+ <entry>(empty)</entry>
+ <entry>1.3.a</entry>
+ <entry>No strings like <literal>alpha</literal>
+ allowed</entry>
+ </row>
+
+ <row>
+ <entry>es-0.9-beta1</entry>
+ <entry>(empty)</entry>
+ <entry>es</entry>
+ <entry>(empty)</entry>
+ <entry>0.9.b1</entry>
+ <entry>No strings like <literal>beta</literal>
+ allowed</entry>
+ </row>
+
+ <row>
+ <entry>mailman-2.0rc3</entry>
+ <entry>(empty)</entry>
+ <entry>mailman</entry>
+ <entry>(empty)</entry>
+ <entry>2.0.r3</entry>
+ <entry>No strings like <literal>rc</literal>
+ allowed</entry>
+ </row>
+
+ <row>
+ <entry>v3.3beta021.src</entry>
+ <entry>(empty)</entry>
+ <entry>tiff</entry>
+ <entry>(empty)</entry>
+ <entry>3.3</entry>
+ <entry>What the heck was that anyway?</entry>
+ </row>
+
+ <row>
+ <entry>tvtwm</entry>
+ <entry>(empty)</entry>
+ <entry>tvtwm</entry>
+ <entry>(empty)</entry>
+ <entry>pl11</entry>
+ <entry>Version string always required</entry>
+ </row>
+
+ <row>
+ <entry>piewm</entry>
+ <entry>(empty)</entry>
+ <entry>piewm</entry>
+ <entry>(empty)</entry>
+ <entry>1.0</entry>
+ <entry>Version string always required</entry>
+ </row>
+
+ <row>
+ <entry>xvgr-2.10pl1</entry>
+ <entry>(empty)</entry>
+ <entry>xvgr</entry>
+ <entry>(empty)</entry>
+ <entry>2.10.1</entry>
+ <entry><literal>pl</literal> allowed only when no
+ major/minor version numbers</entry>
+ </row>
+
+ <row>
+ <entry>gawk-2.15.6</entry>
+ <entry>ja-</entry>
+ <entry>gawk</entry>
+ <entry>(empty)</entry>
+ <entry>2.15.6</entry>
+ <entry>Japanese language version</entry>
+ </row>
+
+ <row>
+ <entry>psutils-1.13</entry>
+ <entry>(empty)</entry>
+ <entry>psutils</entry>
+ <entry>-letter</entry>
+ <entry>1.13</entry>
+ <entry>Papersize hardcoded at package build time</entry>
+ </row>
+
+ <row>
+ <entry>pkfonts</entry>
+ <entry>(empty)</entry>
+ <entry>pkfonts</entry>
+ <entry>300</entry>
+ <entry>1.0</entry>
+ <entry>Package for 300dpi fonts</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>If 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
+ <literal>1.0</literal> (like the <literal>piewm</literal> example above). Otherwise, ask
+ the original author or use the date string
+ (<literal>yyyy.mm.dd</literal>)
+ as the version.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="makefile-categories">
+ <title>Categorization</title>
+
+ <sect2>
+ <title><varname>CATEGORIES</varname></title>
+
+ <para>When a package is created, it is put under
+ <filename>/usr/ports/packages/All</filename> and links are made from
+ one or more subdirectories of
+ <filename>/usr/ports/packages</filename>. The names of these
+ subdirectories are specified by the variable
+ <varname>CATEGORIES</varname>. 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 <link linkend="porting-categories">current list of categories</link> and pick the ones
+ that are suitable for your port.</para>
+
+ <para>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 <link linkend="choosing-categories">below</link> for more
+ discussion about how to pick the right categories.</para>
+ </sect2>
+
+ <sect2 xml:id="porting-categories">
+ <title>Current list of categories</title>
+
+ <para>Here is the current list of port categories. Those
+ marked with an asterisk (<literal>*</literal>) are
+ <emphasis>virtual</emphasis> categories&mdash;those that do not have
+ a corresponding subdirectory in the ports tree. They are only
+ used as secondary categories, and only for search purposes.</para>
+
+ <note>
+ <para>For non-virtual categories, you will find a one-line
+ description in the <varname>COMMENT</varname> in that
+ subdirectory's <filename>Makefile</filename>.</para>
+ </note>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Category</entry>
+ <entry>Description</entry>
+ <entry>Notes</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><filename>accessibility</filename></entry>
+ <entry>Ports to help disabled users.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>afterstep*</filename></entry>
+ <entry>Ports to support the
+ <link xlink:href="http://www.afterstep.org">AfterStep</link>
+ window manager.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>arabic</filename></entry>
+ <entry>Arabic language support.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>archivers</filename></entry>
+ <entry>Archiving tools.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>astro</filename></entry>
+ <entry>Astronomical ports.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>audio</filename></entry>
+ <entry>Sound support.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>benchmarks</filename></entry>
+ <entry>Benchmarking utilities.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>biology</filename></entry>
+ <entry>Biology-related software.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>cad</filename></entry>
+ <entry>Computer aided design tools.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>chinese</filename></entry>
+ <entry>Chinese language support.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>comms</filename></entry>
+ <entry>Communication software.</entry>
+ <entry>Mostly software to talk to your serial port.</entry>
+ </row>
+
+ <row>
+ <entry><filename>converters</filename></entry>
+ <entry>Character code converters.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>databases</filename></entry>
+ <entry>Databases.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>deskutils</filename></entry>
+ <entry>Things that used to be on the desktop before
+ computers were invented.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>devel</filename></entry>
+ <entry>Development utilities.</entry>
+ <entry>Do not put libraries here just because they are
+ libraries&mdash;unless they truly do not belong anywhere
+ else, they should not be in this category.</entry>
+ </row>
+
+ <row>
+ <entry><filename>dns</filename></entry>
+ <entry>DNS-related software.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>editors</filename></entry>
+ <entry>General editors.</entry>
+ <entry>Specialized editors go in the section for those
+ tools (e.g., a mathematical-formula editor will go
+ in <filename>math</filename>).</entry>
+ </row>
+
+ <row>
+ <entry><filename>elisp*</filename></entry>
+ <entry>Emacs-lisp ports.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>emulators</filename></entry>
+ <entry>Emulators for other operating systems.</entry>
+ <entry>Terminal emulators do <emphasis>not</emphasis> belong
+ here&mdash;X-based ones should go to
+ <filename>x11</filename> and text-based ones to either
+ <filename>comms</filename> or <filename>misc</filename>,
+ depending on the exact functionality.</entry>
+ </row>
+
+ <row>
+ <entry><filename>finance</filename></entry>
+ <entry>Monetary, financial and related applications.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>french</filename></entry>
+ <entry>French language support.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>ftp</filename></entry>
+ <entry>FTP client and server utilities.</entry>
+ <entry>If your port speaks both FTP and HTTP, put it in
+ <filename>ftp</filename> with a secondary
+ category of <filename>www</filename>.</entry>
+ </row>
+
+ <row>
+ <entry><filename>games</filename></entry>
+ <entry>遊戲。</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>geography*</filename></entry>
+ <entry>地理圖資相關的軟體。</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>german</filename></entry>
+ <entry>德文相關支援。</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>gnome*</filename></entry>
+ <entry>Ports from the <link xlink:href="http://www.gnome.org">GNOME</link>
+ Project.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>gnustep*</filename></entry>
+ <entry>GNUstep 桌面環境相關的軟體。</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>graphics</filename></entry>
+ <entry>圖形處理的工具軟體。</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>hamradio*</filename></entry>
+ <entry>Software for amateur radio.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>haskell*</filename></entry>
+ <entry>Software related to the Haskell language.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>hebrew</filename></entry>
+ <entry>Hebrew language support.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>hungarian</filename></entry>
+ <entry>Hungarian language support.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>ipv6*</filename></entry>
+ <entry>IPv6 related software.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>irc</filename></entry>
+ <entry>Internet Relay Chat utilities.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>japanese</filename></entry>
+ <entry>Japanese language support.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>java</filename></entry>
+ <entry>Software related to the Java language.</entry>
+ <entry>The <filename>java</filename> 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 <filename>java</filename> as the main category of a
+ port.</entry>
+ </row>
+
+ <row>
+ <entry><filename>kde*</filename></entry>
+ <entry>Ports from the <link xlink:href="http://www.kde.org">K Desktop Environment (KDE)</link>
+ Project.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>kld*</filename></entry>
+ <entry>Kernel loadable modules。</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>korean</filename></entry>
+ <entry>Korean language support.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>lang</filename></entry>
+ <entry>Programming languages.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>linux*</filename></entry>
+ <entry>Linux applications and support utilities.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>lisp*</filename></entry>
+ <entry>Software related to the Lisp language.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>mail</filename></entry>
+ <entry>Mail software.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>math</filename></entry>
+ <entry>Numerical computation software and other utilities
+ for mathematics.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>mbone</filename></entry>
+ <entry>MBone applications.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>misc</filename></entry>
+ <entry>Miscellaneous utilities</entry>
+ <entry>Basically things that
+ do not belong anywhere else.
+ If at all possible, try to
+ find a better category for your port than
+ <literal>misc</literal>, as ports tend to get overlooked
+ in here.</entry>
+ </row>
+
+ <row>
+ <entry><filename>multimedia</filename></entry>
+ <entry>Multimedia software.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>net</filename></entry>
+ <entry>Miscellaneous networking software.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>net-im</filename></entry>
+ <entry>Instant messaging software.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>net-mgmt</filename></entry>
+ <entry>Networking management software.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>net-p2p</filename></entry>
+ <entry>Peer to peer network applications.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>news</filename></entry>
+ <entry>USENET news software.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>palm</filename></entry>
+ <entry>Software support for the <link xlink:href="http://www.palm.com/">Palm&trade;</link> series.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>parallel*</filename></entry>
+ <entry>Applications dealing with parallelism in computing.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>pear*</filename></entry>
+ <entry>Ports related to the Pear PHP framework.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>perl5*</filename></entry>
+ <entry>Ports that require <application>Perl</application> version 5 to run.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>plan9*</filename></entry>
+ <entry>Various programs from <link xlink:href="http://www.cs.bell-labs.com/plan9dist/">Plan9</link>.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>polish</filename></entry>
+ <entry>Polish language support.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>ports-mgmt</filename></entry>
+ <entry>FreeBSD ports 及 packages 的管理、安裝、開發。</entry>
+ </row>
+
+ <row>
+ <entry><filename>portuguese</filename></entry>
+ <entry>Portuguese language support.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>print</filename></entry>
+ <entry>Printing software.</entry>
+ <entry>Desktop publishing tools
+ (previewers, etc.) belong here too.</entry>
+ </row>
+
+ <row>
+ <entry><filename>python*</filename></entry>
+ <entry>Software related to the <link xlink:href="http://www.python.org/">Python</link> language.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>ruby*</filename></entry>
+ <entry>Software related to the <link xlink:href="http://www.ruby-lang.org/">Ruby</link> language.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>rubygems*</filename></entry>
+ <entry>Ports of <link xlink:href="http://www.rubygems.org/">RubyGems</link> packages.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>russian</filename></entry>
+ <entry>Russian language support.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>scheme*</filename></entry>
+ <entry>Software related to the Scheme language.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>science</filename></entry>
+ <entry>Scientific ports that do not fit into other
+ categories such as <filename>astro</filename>,
+ <filename>biology</filename> and
+ <filename>math</filename>.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>security</filename></entry>
+ <entry>Security utilities.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>shells</filename></entry>
+ <entry>Command line shells.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>spanish*</filename></entry>
+ <entry>西班牙文的相關支援。</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>sysutils</filename></entry>
+ <entry>System utilities.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>tcl*</filename></entry>
+ <entry>使用 Tcl 語言的軟體。</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>textproc</filename></entry>
+ <entry>Text processing utilities.</entry>
+ <entry>It does not include
+ desktop publishing tools, which go to <filename>print</filename>.</entry>
+ </row>
+
+ <row>
+ <entry><filename>tk*</filename></entry>
+ <entry>使用 Tk 語言的程式。</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>ukrainian</filename></entry>
+ <entry>Ukrainian language support.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>vietnamese</filename></entry>
+ <entry>Vietnamese language support.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>windowmaker*</filename></entry>
+ <entry>Ports to support the WindowMaker window
+ manager.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>www</filename></entry>
+ <entry>Software related to the World Wide Web.</entry>
+ <entry>HTML language
+ support belongs here too.</entry>
+ </row>
+
+ <row>
+ <entry><filename>x11</filename></entry>
+ <entry>The X Window System and friends.</entry>
+ <entry>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 <filename>x11-*</filename> categories (see below).
+ If your port <emphasis>is</emphasis> an X
+ application, define <varname>USE_XLIB</varname> (implied by
+ <varname>USE_IMAKE</varname>) and put it in the appropriate
+ category.</entry>
+ </row>
+
+ <row>
+ <entry><filename>x11-clocks</filename></entry>
+ <entry>X11 clocks.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>x11-drivers</filename></entry>
+ <entry>X11 驅動程式。</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>x11-fm</filename></entry>
+ <entry>X11 file managers.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>x11-fonts</filename></entry>
+ <entry>X11 fonts and font utilities.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>x11-servers</filename></entry>
+ <entry>X11 servers.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>x11-themes</filename></entry>
+ <entry>X11 themes.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>x11-toolkits</filename></entry>
+ <entry>X11 toolkits.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>x11-wm</filename></entry>
+ <entry>X11 window managers.</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>xfce*</filename></entry>
+ <entry><link xlink:href="http://www.xfce.org/">Xfce</link>
+ 桌面環境的相關軟體。</entry>
+ <entry/>
+ </row>
+
+ <row>
+ <entry><filename>zope*</filename></entry>
+ <entry><link xlink:href="http://www.zope.org/">Zope</link> support.</entry>
+ <entry/>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2 xml:id="choosing-categories">
+ <title>Choosing the right category</title>
+
+ <para>As 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:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>The first category must be a physical category (see
+ <link linkend="porting-categories">above</link>). This is
+ necessary to make the packaging work. Virtual categories and
+ physical categories may be intermixed after that.</para>
+ </listitem>
+
+ <listitem>
+ <para>Language specific categories always come first. For
+ example, if your port installs Japanese X11 fonts, then your
+ <varname>CATEGORIES</varname> line would read <filename>japanese
+ x11-fonts</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para>Specific categories are listed before less-specific ones. For
+ instance, an HTML editor should be listed as <filename>www
+ editors</filename>, not the other way around. Also, you should not
+ list <filename>net</filename> when the port belongs to
+ any of <filename>irc</filename>, <filename>mail</filename>,
+ <filename>mbone</filename>, <filename>news</filename>,
+ <filename>security</filename>, or <filename>www</filename>, as
+ <filename>net</filename> is included implicitly.</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>x11</filename> is used as a secondary category only
+ when the primary category is a natural language. In particular,
+ you should not put <filename>x11</filename> in the category line
+ for X applications.</para>
+ </listitem>
+
+ <listitem>
+ <para><application>Emacs</application> modes should be
+ placed in the same ports category as the application
+ supported by the mode, not in
+ <filename>editors</filename>. For example, an
+ <application>Emacs</application> mode to edit source
+ files of some programming language should go into
+ <filename>lang</filename>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>會安裝 kernel loadable modules 的 port 請在
+ <varname>CATEGORIES</varname> 內加上 <filename>kld</filename>
+ 這個虛擬目錄。</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>misc</filename>
+ should not appear with any other non-virtual category.
+ If you have <literal>misc</literal> with something else in
+ your <varname>CATEGORIES</varname> line, that means you can
+ safely delete <literal>misc</literal> and just put the port
+ in that other subdirectory!</para>
+ </listitem>
+
+ <listitem>
+ <para>If your port truly does not belong anywhere else, put it in
+ <filename>misc</filename>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>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.</para>
+ </sect2>
+
+ <sect2 xml:id="proposing-categories">
+ <title>Proposing a new category</title>
+
+ <para>As the Ports Collection has grown over time, various new
+ categories have been introduced. New categories can either
+ be <emphasis>virtual</emphasis> categories&mdash;those that do
+ not have a corresponding subdirectory in the ports tree&mdash;
+ or <emphasis>physical</emphasis> categories&mdash;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.</para>
+
+ <para>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.</para>
+
+ <para>The rationale for this is that such a change creates a
+ <link xlink:href="&url.articles.committers-guide;/#ports">
+ fair amount of work</link> 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 <quote>too big</quote>,
+ nor whether categories should lend themselves to browsing (and
+ thus what number of categories would be an ideal number), and
+ so forth.)</para>
+
+ <para>Here is the procedure:</para>
+
+ <procedure>
+ <step>
+ <para>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
+ <application>GNATS</application> 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.</para>
+ </step>
+
+ <step>
+ <para>Participate in the discussion.</para>
+ </step>
+
+ <step>
+ <para>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:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><filename>Makefile</filename>s for the
+ new ports once they are repocopied</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>Makefile</filename> for the
+ new category</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>Makefile</filename> for the
+ old ports' categories</para>
+ </listitem>
+
+ <listitem>
+ <para><filename>Makefile</filename>s for ports
+ that depend on the old ports</para>
+ </listitem>
+
+ <listitem>
+ <para>(for extra credit, you can include the other
+ files that have to change, as per the procedure
+ in the Committer's Guide.)</para>
+ </listitem>
+ </itemizedlist>
+ </step>
+
+ <step>
+ <para>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;.</para>
+ </step>
+
+ <step>
+ <para>If that PR is approved, a committer will need to follow
+ the rest of the procedure that is
+ <link xlink:href="&url.articles.committers-guide;/#ports">
+ outlined in the Committer's Guide</link>.</para>
+ </step>
+ </procedure>
+
+ <para>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
+ <varname>CATEGORIES</varname> of the affected ports.</para>
+ </sect2>
+
+ <sect2 xml:id="proposing-reorg">
+ <title>Proposing reorganizing all the categories</title>
+
+ <para>Occasionally 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.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="makefile-distfiles">
+ <title>The distribution files</title>
+
+ <para>The second part of the <filename>Makefile</filename> describes the
+ files that must be downloaded in order to build the port, and where
+ they can be downloaded from.</para>
+
+ <sect2>
+ <title><varname>DISTVERSION/DISTNAME</varname></title>
+
+ <para><varname>DISTNAME</varname> is the name of the port as
+ called by the authors of the software.
+ <varname>DISTNAME</varname> defaults to
+ <literal>${PORTNAME}-${PORTVERSION}</literal>, so override it only if necessary.
+ <varname>DISTNAME</varname> is only used in two places.
+ First, the distribution file list
+ (<varname>DISTFILES</varname>) defaults to
+ <varname>${DISTNAME}</varname><varname>${EXTRACT_SUFX}</varname>.
+ Second, the distribution file is expected to extract into a
+ subdirectory named <varname>WRKSRC</varname>, which defaults
+ to <filename>work/${DISTNAME}</filename>.</para>
+
+ <para>Some vendor's distribution names which do not fit into the
+ <literal>${PORTNAME}-${PORTVERSION}</literal>-scheme can be handled
+ automatically by setting <varname>DISTVERSION</varname>.
+ <varname>PORTVERSION</varname> and <varname>DISTNAME</varname> will be
+ derived automatically, but can of course be overridden. The following
+ table lists some examples:</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry><varname>DISTVERSION</varname></entry>
+ <entry><varname>PORTVERSION</varname></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>0.7.1d</entry>
+ <entry>0.7.1.d</entry>
+ </row>
+
+ <row>
+ <entry>10Alpha3</entry>
+ <entry>10.a3</entry>
+ </row>
+
+ <row>
+ <entry>3Beta7-pre2</entry>
+ <entry>3.b7.p2</entry>
+ </row>
+
+ <row>
+ <entry>8:f_17</entry>
+ <entry>8f.17</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <note>
+ <para><varname>PKGNAMEPREFIX</varname> and
+ <varname>PKGNAMESUFFIX</varname> do not affect
+ <varname>DISTNAME</varname>. Also note that if
+ <varname>WRKSRC</varname> is equal to
+ <filename>work/${PORTNAME}-${PORTVERSION}</filename>
+ while the original source archive is named something other than
+ <varname>${PORTNAME}-${PORTVERSION}${EXTRACT_SUFX}</varname>,
+ you should probably leave <varname>DISTNAME</varname>
+ alone&mdash; you are better off defining
+ <varname>DISTFILES</varname> than having to set both
+ <varname>DISTNAME</varname> and <varname>WRKSRC</varname>
+ (and possibly <varname>EXTRACT_SUFX</varname>).</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title><varname>MASTER_SITES</varname></title>
+
+ <para>Record the directory part of the FTP/HTTP-URL pointing at the
+ original tarball in <varname>MASTER_SITES</varname>. Do not forget
+ the trailing slash (<filename>/</filename>)!</para>
+
+ <para>The <command>make</command> macros will try to use this
+ specification for grabbing the distribution file with
+ <varname>FETCH</varname> if they cannot find it already on the
+ system.</para>
+
+ <para>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.</para>
+
+ <para>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
+ <varname>MASTER_SITE_<replaceable>*</replaceable></varname>
+ (比如:<varname>MASTER_SITE_XCONTRIB</varname>、
+ <varname>MASTER_SITE_GNU</varname>、
+ <varname>MASTER_SITE_PERL_CPAN</varname>)。 Simply set
+ <varname>MASTER_SITES</varname> to one of these variables and
+ <varname>MASTER_SITE_SUBDIR</varname> to the path within the
+ archive. Here is an example:</para>
+
+ <programlisting>MASTER_SITES= ${MASTER_SITE_XCONTRIB}
+MASTER_SITE_SUBDIR= applications</programlisting>
+
+ <para>These variables are defined in
+ <filename>/usr/ports/Mk/bsd.sites.mk</filename>. There are
+ new entries added all the time, so make sure to check the
+ latest version of this file before submitting a port.</para>
+
+ <para>The user can also set the <varname>MASTER_SITE_*</varname>
+ variables in <filename>/etc/make.conf</filename> to override our
+ choices, and use their favorite mirrors of these popular archives
+ instead.</para>
+ </sect2>
+
+ <sect2>
+ <title><varname>EXTRACT_SUFX</varname></title>
+
+ <para>If you have one distribution file, and it uses an odd suffix to
+ indicate the compression mechanism, set
+ <varname>EXTRACT_SUFX</varname>.</para>
+
+ <para>For example, if the distribution file was named
+ <filename>foo.tgz</filename> instead of the more normal
+ <filename>foo.tar.gz</filename>, you would write:</para>
+
+ <programlisting>DISTNAME= foo
+EXTRACT_SUFX= .tgz</programlisting>
+
+ <para>The <varname>USE_BZIP2</varname> and <varname>USE_ZIP</varname>
+ variables automatically set <varname>EXTRACT_SUFX</varname> to
+ <literal>.tar.bz2</literal> or <literal>.zip</literal> as necessary. If
+ neither of these are set then <varname>EXTRACT_SUFX</varname>
+ defaults to <literal>.tar.gz</literal>.</para>
+
+ <note>
+ <para>You never need to set both <varname>EXTRACT_SUFX</varname> and
+ <varname>DISTFILES</varname>.</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title><varname>DISTFILES</varname></title>
+
+ <para>Sometimes the names of the files to be downloaded have no
+ resemblance to the name of the port. For example, it might be
+ called <filename>source.tar.gz</filename> or similar. In other
+ cases the application's source code might be in several different
+ archives, all of which must be downloaded.</para>
+
+ <para>If this is the case, set <varname>DISTFILES</varname> to be a
+ space separated list of all the files that must be
+ downloaded.</para>
+
+ <programlisting>DISTFILES= source1.tar.gz source2.tar.gz</programlisting>
+
+ <para>If not explicitly set, <varname>DISTFILES</varname> defaults to
+ <literal>${DISTNAME}${EXTRACT_SUFX}</literal>.</para>
+ </sect2>
+
+ <sect2>
+ <title><varname>EXTRACT_ONLY</varname></title>
+
+ <para>If only some of the <varname>DISTFILES</varname> must be
+ extracted&mdash;for example, one of them is the source code, while
+ another is an uncompressed document&mdash;list the filenames that
+ must be extracted in <varname>EXTRACT_ONLY</varname>.</para>
+
+ <programlisting>DISTFILES= source.tar.gz manual.html
+EXTRACT_ONLY= source.tar.gz</programlisting>
+
+ <para>If <emphasis>none</emphasis> of the <varname>DISTFILES</varname>
+ should be uncompressed then set <varname>EXTRACT_ONLY</varname> to
+ the empty string.</para>
+
+ <programlisting>EXTRACT_ONLY=</programlisting>
+ </sect2>
+
+ <sect2 xml:id="porting-patchfiles">
+ <title><varname>PATCHFILES</varname></title>
+
+ <para>If your port requires some additional patches that are available
+ by FTP or HTTP, set <varname>PATCHFILES</varname> to the names of
+ the files and <varname>PATCH_SITES</varname> to the URL of the
+ directory that contains them (the format is the same as
+ <varname>MASTER_SITES</varname>).</para>
+
+ <para>If the patch is not relative to the top of the source tree
+ (i.e., <varname>WRKSRC</varname>) because it contains some extra
+ pathnames, set <varname>PATCH_DIST_STRIP</varname> accordingly. For
+ instance, if all the pathnames in the patch have an extra
+ <literal>foozolix-1.0/</literal> in front of the filenames, then set
+ <literal>PATCH_DIST_STRIP=-p1</literal>.</para>
+
+ <para>Do not worry if the patches are compressed; they will be
+ decompressed automatically if the filenames end with
+ <filename>.gz</filename> or <filename>.Z</filename>.</para>
+
+ <para>If the patch is distributed with some other files, such as
+ documentation, in a gzip'd tarball, you cannot just use
+ <varname>PATCHFILES</varname>. If that is the case, add the name
+ and the location of the patch tarball to
+ <varname>DISTFILES</varname> and <varname>MASTER_SITES</varname>.
+ Then, use the <varname>EXTRA_PATCHES</varname> variable to
+ point to those files and <filename>bsd.port.mk</filename>
+ will automatically apply them for you. In particular, do
+ <emphasis>not</emphasis> copy patch files into the
+ <varname>PATCHDIR</varname> directory&mdash;that directory may
+ not be writable.</para>
+
+ <note>
+ <para>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 <buildtarget>pre-clean</buildtarget>
+ target.</para>
+ </note>
+ </sect2>
+
+ <sect2 xml:id="porting-master-sites-n">
+ <title>Multiple distribution files or patches from different
+ sites and subdirectories
+ (<literal>MASTER_SITES:n</literal>)</title>
+
+ <para>(Consider this to be a somewhat <quote>advanced topic</quote>;
+ those new to this document may wish to skip this section at first).
+ </para>
+
+ <para>This section has information on the fetching mechanism
+ known as both <literal>MASTER_SITES:n</literal> and
+ <literal>MASTER_SITES_NN</literal>. We will refer to this
+ mechanism as <literal>MASTER_SITES:n</literal>
+ hereon.</para>
+
+ <para>A little background first. OpenBSD has a neat feature
+ inside both <varname>DISTFILES</varname> and
+ <varname>PATCHFILES</varname> variables, both files and
+ patches can be postfixed with <literal>:n</literal>
+ identifiers where <literal>n</literal> both can be
+ <literal>[0-9]</literal> and denote a group designation.
+ For example:</para>
+
+ <programlisting>DISTFILES= alpha:0 beta:1</programlisting>
+
+ <para>In OpenBSD, distribution file <filename>alpha</filename>
+ will be associated with variable
+ <varname>MASTER_SITES0</varname> instead of our common
+ <varname>MASTER_SITES</varname> and
+ <filename>beta</filename> with
+ <varname>MASTER_SITES1</varname>.</para>
+
+ <para>This is a very interesting feature which can decrease
+ that endless search for the correct download site.</para>
+
+ <para>Just picture 2 files in <varname>DISTFILES</varname> and
+ 20 sites in <varname>MASTER_SITES</varname>, the sites slow
+ as hell where <filename>beta</filename> is carried by all
+ sites in <varname>MASTER_SITES</varname>, and
+ <filename>alpha</filename> 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!</para>
+
+ <para>Now that you have the idea, just imagine more
+ <varname>DISTFILES</varname> and more
+ <varname>MASTER_SITES</varname>. Surely our
+ <quote>distfiles survey meister</quote> would appreciate the
+ relief to network strain that this would bring.</para>
+
+ <para>In the next sections, information will follow on the
+ FreeBSD implementation of this idea. We improved a bit on
+ OpenBSD's concept.</para>
+
+ <sect3>
+ <title>Simplified information</title>
+
+ <para>This 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
+ <literal>MASTER_SITES:n</literal> usage. This will be
+ sufficient for most scenarios. However, if you need
+ further information, you will have to refer to the next
+ section.</para>
+
+ <para>Some applications consist of multiple distribution
+ files that must be downloaded from a number of different
+ sites. For example,
+ <application>Ghostscript</application> 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.</para>
+
+ <para>To support this, each entry in
+ <varname>DISTFILES</varname> may be followed by a colon
+ and a <quote>tag name</quote>. Each site listed in
+ <varname>MASTER_SITES</varname> is then followed by a
+ colon, and the tag that indicates which distribution files
+ should be downloaded from this site.</para>
+
+ <para>For example, consider an application with the source
+ split in two parts, <filename>source1.tar.gz</filename>
+ and <filename>source2.tar.gz</filename>, which must be
+ downloaded from two different sites. The port's
+ <filename>Makefile</filename> would include lines like
+ <xref linkend="ports-master-sites-n-example-simple-use-one-file-per-site"/>.</para>
+
+ <example xml:id="ports-master-sites-n-example-simple-use-one-file-per-site">
+ <title>Simplified use of <literal>MASTER_SITES:n</literal>
+ with 1 file per site</title>
+
+ <programlisting>MASTER_SITES= ftp://ftp.example1.com/:source1 \
+ ftp://ftp.example2.com/:source2
+DISTFILES= source1.tar.gz:source1 \
+ source2.tar.gz:source2</programlisting>
+ </example>
+
+ <para>Multiple distribution files can have the same tag.
+ Continuing the previous example, suppose that there was a
+ third distfile, <filename>source3.tar.gz</filename>, that
+ should be downloaded from
+ <systemitem>ftp.example2.com</systemitem>. The
+ <filename>Makefile</filename> would then be written like
+ <xref linkend="ports-master-sites-n-example-simple-use-more-than-one-file-per-site"/>.</para>
+
+ <example xml:id="ports-master-sites-n-example-simple-use-more-than-one-file-per-site">
+ <title>Simplified use of <literal>MASTER_SITES:n</literal>
+ with more than 1 file per site</title>
+
+ <programlisting>MASTER_SITES= ftp://ftp.example1.com/:source1 \
+ ftp://ftp.example2.com/:source2
+DISTFILES= source1.tar.gz:source1 \
+ source2.tar.gz:source2 \
+ source3.tar.gz:source2</programlisting>
+ </example>
+ </sect3>
+
+ <sect3>
+ <title>Detailed information</title>
+
+ <para>Okay, so the previous section example did not reflect
+ your needs? In this section we will explain in detail how
+ the fine grained fetching mechanism
+ <literal>MASTER_SITES:n</literal> works and how you can
+ modify your ports to use it.</para>
+
+ <orderedlist>
+ <listitem>
+ <para>Elements can be postfixed with
+ <literal>:n</literal> where
+ <replaceable>n</replaceable> is
+ <literal>[^:,]+</literal>, i.e.,
+ <replaceable>n</replaceable> could conceptually be any
+ alphanumeric string but we will limit it to
+ <literal>[a-zA-Z_][0-9a-zA-Z_]+</literal> for
+ now.</para>
+
+ <para>Moreover, string matching is case sensitive;
+ i.e., <literal>n</literal> is different from
+ <literal>N</literal>.</para>
+
+ <para>However, the following words cannot be used for
+ postfixing purposes since they yield special meaning:
+ <literal>default</literal>, <literal>all</literal> and
+ <literal>ALL</literal> (they are used internally in
+ item <xref linkend="porting-master-sites-n-what-changes-in-port-targets"/>).
+ Furthermore, <literal>DEFAULT</literal> is a special
+ purpose word (check item <xref linkend="porting-master-sites-n-DEFAULT-group"/>).</para>
+ </listitem>
+
+ <listitem>
+ <para>Elements postfixed with <literal>:n</literal>
+ belong to the group <literal>n</literal>,
+ <literal>:m</literal> belong to group
+ <literal>m</literal> and so forth.</para>
+ </listitem>
+
+ <listitem xml:id="porting-master-sites-n-DEFAULT-group">
+ <para>Elements without a postfix are groupless, i.e.,
+ they all belong to the special group
+ <literal>DEFAULT</literal>. If you postfix any
+ elements with <literal>DEFAULT</literal>, you are just
+ being redundant unless you want to have an element
+ belonging to both <literal>DEFAULT</literal> and other
+ groups at the same time (check item <xref linkend="porting-master-sites-n-comma-operator"/>).</para>
+
+ <para>The following examples are equivalent but the
+ first one is preferred:</para>
+
+ <programlisting>MASTER_SITES= alpha
+
+MASTER_SITES= alpha:DEFAULT</programlisting>
+ </listitem>
+
+ <listitem>
+ <para>Groups 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.</para>
+ </listitem>
+
+ <listitem xml:id="porting-master-sites-n-comma-operator">
+ <para>When you want an element to belong to several
+ groups at the same time, you can use the comma
+ operator (<literal>,</literal>).</para>
+
+ <para>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,
+ <literal>:m,n,o</literal> marks an element that
+ belongs to group <literal>m</literal>,
+ <literal>n</literal> and <literal>o</literal>.</para>
+
+ <para>All the following examples are equivalent but the
+ last one is preferred:</para>
+
+ <programlisting>MASTER_SITES= alpha alpha:SOME_SITE
+
+MASTER_SITES= alpha:DEFAULT alpha:SOME_SITE
+
+MASTER_SITES= alpha:SOME_SITE,DEFAULT
+
+MASTER_SITES= alpha:DEFAULT,SOME_SITE</programlisting>
+ </listitem>
+
+ <listitem>
+ <para>All sites within a given group are sorted
+ according to <varname>MASTER_SORT_AWK</varname>. All
+ groups within <varname>MASTER_SITES</varname> and
+ <varname>PATCH_SITES</varname> are sorted as
+ well.</para>
+ </listitem>
+
+ <listitem xml:id="porting-master-sites-n-group-semantics">
+ <para>Group semantics can be used in any of the
+ following variables <varname>MASTER_SITES</varname>,
+ <varname>PATCH_SITES</varname>,
+ <varname>MASTER_SITE_SUBDIR</varname>,
+ <varname>PATCH_SITE_SUBDIR</varname>,
+ <varname>DISTFILES</varname>, and
+ <varname>PATCHFILES</varname> according to the
+ following syntax:</para>
+
+ <orderedlist>
+ <listitem>
+ <para>All <varname>MASTER_SITES</varname>,
+ <varname>PATCH_SITES</varname>,
+ <varname>MASTER_SITE_SUBDIR</varname> and
+ <varname>PATCH_SITE_SUBDIR</varname> elements must
+ be terminated with the forward slash
+ <literal>/</literal> character. If any elements
+ belong to any groups, the group postfix
+ <literal>:n</literal>
+ must come right after the terminator
+ <literal>/</literal>. The
+ <literal>MASTER_SITES:n</literal> mechanism relies
+ on the existence of the terminator
+ <literal>/</literal> to avoid confusing elements
+ where a <literal>:n</literal> is a valid part of
+ the element with occurrences where
+ <literal>:n</literal> denotes group
+ <literal>n</literal>. For compatibility purposes,
+ since the <literal>/</literal> terminator was not
+ required before in both
+ <varname>MASTER_SITE_SUBDIR</varname> and
+ <varname>PATCH_SITE_SUBDIR</varname> elements, if
+ the postfix immediate preceding character is not
+ a <literal>/</literal> then <literal>:n</literal>
+ will be considered a valid part of the element
+ instead of a group postfix even if an element is
+ postfixed with <literal>:n</literal>. See both
+ <xref linkend="ports-master-sites-n-example-detailed-use-master-site-subdir"/>
+ and <xref linkend="ports-master-sites-n-example-detailed-use-complete-example-master-sites"/>.</para>
+
+ <example xml:id="ports-master-sites-n-example-detailed-use-master-site-subdir">
+ <title>Detailed use of
+ <literal>MASTER_SITES:n</literal> in
+ <varname>MASTER_SITE_SUBDIR</varname></title>
+
+ <programlisting>MASTER_SITE_SUBDIR= old:n new/:NEW</programlisting>
+
+ <itemizedlist>
+ <listitem>
+ <para>Directories within group
+ <literal>DEFAULT</literal> -&gt; old:n</para>
+ </listitem>
+
+ <listitem>
+ <para>Directories within group
+ <literal>NEW</literal> -&gt; new</para>
+ </listitem>
+ </itemizedlist>
+ </example>
+
+ <example xml:id="ports-master-sites-n-example-detailed-use-complete-example-master-sites">
+ <title>Detailed use of
+ <literal>MASTER_SITES:n</literal> with comma
+ operator, multiple files, multiple sites and
+ multiple subdirectories</title>
+
+ <programlisting>MASTER_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 \
+ directory</programlisting>
+
+ <para>The previous example results in the
+ following fine grained fetching. Sites are
+ listed in the exact order they will be
+ used.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><filename>file1</filename> will be
+ fetched from</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><varname>MASTER_SITE_OVERRIDE</varname></para>
+ </listitem>
+
+ <listitem>
+ <para>http://site1/directory-trial:1/</para>
+ </listitem>
+
+ <listitem>
+ <para>http://site1/directory-one/</para>
+ </listitem>
+
+ <listitem>
+ <para>http://site1/directory/</para>
+ </listitem>
+
+ <listitem>
+ <para>http://site2/</para>
+ </listitem>
+
+ <listitem>
+ <para>http://site7/</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>MASTER_SITE_BACKUP</varname></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para><filename>file2</filename> will be
+ fetched exactly as
+ <filename>file1</filename> since they
+ both belong to the same group</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><varname>MASTER_SITE_OVERRIDE</varname></para>
+ </listitem>
+
+ <listitem>
+ <para>http://site1/directory-trial:1/</para>
+ </listitem>
+
+ <listitem>
+ <para>http://site1/directory-one/</para>
+ </listitem>
+
+ <listitem>
+ <para>http://site1/directory/</para>
+ </listitem>
+
+ <listitem>
+ <para>http://site2/</para>
+ </listitem>
+
+ <listitem>
+ <para>http://site7/</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>MASTER_SITE_BACKUP</varname></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para><filename>file3</filename> will be
+ fetched from</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><varname>MASTER_SITE_OVERRIDE</varname></para>
+ </listitem>
+
+ <listitem>
+ <para>http://site3/</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>MASTER_SITE_BACKUP</varname></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para><filename>file4</filename> will be
+ fetched from</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><varname>MASTER_SITE_OVERRIDE</varname></para>
+ </listitem>
+
+ <listitem>
+ <para>http://site4/</para>
+ </listitem>
+
+ <listitem>
+ <para>http://site5/</para>
+ </listitem>
+
+ <listitem>
+ <para>http://site6/</para>
+ </listitem>
+
+ <listitem>
+ <para>http://site7/</para>
+ </listitem>
+
+ <listitem>
+ <para>http://site8/directory-one/</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>MASTER_SITE_BACKUP</varname></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para><filename>file5</filename> will be
+ fetched from</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><varname>MASTER_SITE_OVERRIDE</varname></para>
+ </listitem>
+
+ <listitem>
+ <para><varname>MASTER_SITE_BACKUP</varname></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para><filename>file6</filename> will be
+ fetched from</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><varname>MASTER_SITE_OVERRIDE</varname></para>
+ </listitem>
+
+ <listitem>
+ <para>http://site8/</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>MASTER_SITE_BACKUP</varname></para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </example>
+ </listitem>
+ </orderedlist>
+ </listitem>
+
+ <listitem>
+ <para>How do I group one of the special variables from
+ <filename>bsd.sites.mk</filename>, e.g.,
+ <varname>MASTER_SITE_SOURCEFORGE</varname>?</para>
+
+ <para>See <xref linkend="ports-master-sites-n-example-detailed-use-master-site-sourceforge"/>.</para>
+
+ <example xml:id="ports-master-sites-n-example-detailed-use-master-site-sourceforge">
+ <title>Detailed use of
+ <literal>MASTER_SITES:n</literal> with
+ <varname>MASTER_SITE_SOURCEFORGE</varname></title>
+
+ <programlisting>MASTER_SITES= http://site1/ ${MASTER_SITE_SOURCEFORGE:S/$/:sourceforge,TEST/}
+DISTFILES= something.tar.gz:sourceforge</programlisting>
+ </example>
+
+ <para><filename>something.tar.gz</filename> will be
+ fetched from all sites within
+ <varname>MASTER_SITE_SOURCEFORGE</varname>.</para>
+ </listitem>
+
+ <listitem>
+ <para>How do I use this with <varname>PATCH*</varname>
+ variables?</para>
+
+ <para>All examples were done with
+ <varname>MASTER*</varname> variables but they work
+ exactly the same for <varname>PATCH*</varname> ones as
+ can be seen in <xref linkend="ports-master-sites-n-example-detailed-use-patch-sites"/>.</para>
+
+ <example xml:id="ports-master-sites-n-example-detailed-use-patch-sites">
+ <title>Simplified use of
+ <literal>MASTER_SITES:n</literal> with
+ <varname>PATCH_SITES</varname>.</title>
+
+ <programlisting>PATCH_SITES= http://site1/ http://site2/:test
+PATCHFILES= patch1:test</programlisting>
+ </example>
+ </listitem>
+ </orderedlist>
+ </sect3>
+
+ <sect3>
+ <title>What does change for ports? What does not?</title>
+
+ <orderedlist numeration="lowerroman">
+ <listitem>
+ <para>All current ports remain the same. The
+ <literal>MASTER_SITES:n</literal> feature code is only
+ activated if there are elements postfixed with
+ <literal>:n</literal> like
+ elements according to the aforementioned syntax rules,
+ especially as shown in item <xref linkend="porting-master-sites-n-group-semantics"/>.</para>
+ </listitem>
+
+ <listitem xml:id="porting-master-sites-n-what-changes-in-port-targets">
+ <para>The port targets remain the same:
+ <buildtarget>checksum</buildtarget>,
+ <buildtarget>makesum</buildtarget>,
+ <buildtarget>patch</buildtarget>,
+ <buildtarget>configure</buildtarget>,
+ <buildtarget>build</buildtarget>, etc. With the obvious
+ exceptions of <buildtarget>do-fetch</buildtarget>,
+ <buildtarget>fetch-list</buildtarget>,
+ <buildtarget>master-sites</buildtarget> and
+ <buildtarget>patch-sites</buildtarget>.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><buildtarget>do-fetch</buildtarget>: deploys the
+ new grouping postfixed
+ <varname>DISTFILES</varname> and
+ <varname>PATCHFILES</varname> with their matching
+ group elements within both
+ <varname>MASTER_SITES</varname> and
+ <varname>PATCH_SITES</varname> which use matching
+ group elements within both
+ <varname>MASTER_SITE_SUBDIR</varname> and
+ <varname>PATCH_SITE_SUBDIR</varname>. Check <xref linkend="ports-master-sites-n-example-detailed-use-complete-example-master-sites"/>.</para>
+ </listitem>
+
+ <listitem>
+ <para><buildtarget>fetch-list</buildtarget>: works
+ like old <buildtarget>fetch-list</buildtarget> with
+ the exception that it groups just like
+ <buildtarget>do-fetch</buildtarget>.</para>
+ </listitem>
+
+ <listitem>
+ <para><buildtarget>master-sites</buildtarget> and
+ <buildtarget>patch-sites</buildtarget>:
+ (incompatible with older versions) only return the
+ elements of group <literal>DEFAULT</literal>; in
+ fact, they execute targets
+ <buildtarget>master-sites-default</buildtarget> and
+ <buildtarget>patch-sites-default</buildtarget>
+ respectively.</para>
+
+ <para>Furthermore, using target either
+ <buildtarget>master-sites-all</buildtarget> or
+ <buildtarget>patch-sites-all</buildtarget> is
+ preferred to directly checking either
+ <buildtarget>MASTER_SITES</buildtarget> or
+ <buildtarget>PATCH_SITES</buildtarget>. Also,
+ directly checking is not guaranteed to work in any
+ future versions. Check item <xref linkend="porting-master-sites-n-new-port-targets-master-sites-all"/>
+ for more information on these new port
+ targets.</para>
+ </listitem>
+
+ </itemizedlist>
+ </listitem>
+
+ <listitem>
+ <para>New port targets</para>
+
+ <orderedlist>
+ <listitem>
+ <para>There are
+ <buildtarget>master-sites-<replaceable>n</replaceable></buildtarget>
+ and
+ <buildtarget>patch-sites-<replaceable>n</replaceable></buildtarget>
+ targets which will list the elements of the
+ respective group <replaceable>n</replaceable>
+ within <varname>MASTER_SITES</varname> and
+ <varname>PATCH_SITES</varname> respectively. For
+ instance, both
+ <buildtarget>master-sites-DEFAULT</buildtarget> and
+ <buildtarget>patch-sites-DEFAULT</buildtarget> will
+ return the elements of group
+ <literal>DEFAULT</literal>,
+ <buildtarget>master-sites-test</buildtarget> and
+ <buildtarget>patch-sites-test</buildtarget> of group
+ <literal>test</literal>, and thereon.</para>
+ </listitem>
+
+ <listitem xml:id="porting-master-sites-n-new-port-targets-master-sites-all">
+ <para>There are new targets
+ <buildtarget>master-sites-all</buildtarget> and
+ <buildtarget>patch-sites-all</buildtarget> which do
+ the work of the old
+ <buildtarget>master-sites</buildtarget> and
+ <buildtarget>patch-sites</buildtarget> 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
+ <varname>MASTER_SITE_BACKUP</varname> and
+ <varname>MASTER_SITE_OVERRIDE</varname> as there
+ are groups defined within either
+ <varname>DISTFILES</varname> or
+ <varname>PATCHFILES</varname>; respectively for
+ <buildtarget>master-sites-all</buildtarget> and
+ <buildtarget>patch-sites-all</buildtarget>.</para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+ </orderedlist>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title><varname>DIST_SUBDIR</varname></title>
+
+ <para>Do not let your port clutter
+ <filename>/usr/ports/distfiles</filename>. 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.,
+ <filename>Makefile</filename>), set <varname>DIST_SUBDIR</varname>
+ to the name of the port (<literal>${PORTNAME}</literal> or
+ <literal>${PKGNAMEPREFIX}${PORTNAME}</literal>
+ should work fine). This will change
+ <varname>DISTDIR</varname> from the default
+ <filename>/usr/ports/distfiles</filename> to
+ <filename>/usr/ports/distfiles/DIST_SUBDIR</filename>,
+ and in effect puts everything that is required for your port into
+ that subdirectory.</para>
+
+ <para>It will also look at the subdirectory with the same name on the
+ backup master site at <filename>ftp.FreeBSD.org</filename>.
+ (Setting <varname>DISTDIR</varname> explicitly in your
+ <varname>Makefile</varname> will not accomplish this, so please use
+ <varname>DIST_SUBDIR</varname>.)</para>
+
+ <note>
+ <para>This does not affect the <varname>MASTER_SITES</varname> you
+ define in your <filename>Makefile</filename>.</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title><varname>ALWAYS_KEEP_DISTFILES</varname></title>
+
+ <para>If 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, <varname>ALWAYS_KEEP_DISTFILES</varname>
+ will instruct the &os; build cluster to keep a copy of the files
+ specified in <varname>DISTFILES</varname>. Users of these ports
+ will generally not need these files, so it is a good idea to only
+ add the source distfiles to <varname>DISTFILES</varname> when
+ <varname>PACKAGE_BUILDING</varname> is defined.
+ </para>
+
+ <example xml:id="ports-master-sites-n-example-always-keep-distfiles">
+ <title>Use of <varname>ALWAYS_KEEP_DISTFILES</varname>.</title>
+ <programlisting>.if defined(PACKAGE_BUILDING)
+DISTFILES+= <replaceable>foo.tar.gz</replaceable>
+ALWAYS_KEEP_DISTFILES= yes
+.endif</programlisting>
+ </example>
+
+ <para>When adding extra files to <varname>DISTFILES</varname>,
+ make sure you also add them to <filename>distinfo</filename>.
+ Also, the additional files will normally be extracted into
+ <varname>WRKDIR</varname> as well, which for some ports may
+ lead to undesirable sideeffects and require special handling.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="makefile-maintainer">
+ <title><varname>MAINTAINER</varname></title>
+
+ <para>Set your mail-address here. Please. <!-- smiley
+ --><emphasis>:-)</emphasis></para>
+
+ <para>Note that only a single address without the comment part is
+ allowed as a <varname>MAINTAINER</varname> value.
+ The format used should be <literal>user@hostname.domain</literal>.
+ Please do not include any descriptive text such as your real
+ name in this entry&mdash;that merely confuses
+ <filename>bsd.port.mk</filename>.</para>
+
+ <para>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 <link xlink:href="&url.articles.contributing-ports;/maintain-port.html">The
+ challenge for port maintainers</link> section.</para>
+
+ <para>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.</para>
+
+ <para>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.</para>
+
+ <para>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.</para>
+ </sect1>
+
+ <sect1 xml:id="makefile-comment">
+ <title><varname>COMMENT</varname></title>
+
+ <para>This is a one-line description of the port.
+ <emphasis>Please</emphasis> 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:</para>
+
+ <programlisting>COMMENT= A cat chasing a mouse all over the screen</programlisting>
+
+ <para>The COMMENT variable should immediately follow the MAINTAINER
+ variable in the <filename>Makefile</filename>.</para>
+
+ <para>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.</para>
+ </sect1>
+
+ <sect1 xml:id="makefile-depend">
+ <title>Dependencies</title>
+
+ <para>Many 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.</para>
+
+ <sect2>
+ <title><varname>LIB_DEPENDS</varname></title>
+
+ <para>This variable specifies the shared libraries this port depends
+ on. It is a list of
+ <replaceable>lib</replaceable>:<replaceable>dir</replaceable><optional>:target</optional>
+ tuples where <replaceable>lib</replaceable> is the name of the
+ shared library, <replaceable>dir</replaceable> is the
+ directory in which to find it in case it is not available, and
+ <replaceable>target</replaceable> is the target to call in that
+ directory. For example,
+ <programlisting>LIB_DEPENDS= jpeg.9:${PORTSDIR}/graphics/jpeg</programlisting>
+ will check for a shared jpeg library with major version 9, and
+ descend into the <filename>graphics/jpeg</filename> subdirectory
+ of your ports tree to build and install it if it is not found.
+ The <replaceable>target</replaceable> part can be omitted if it is
+ equal to <varname>DEPENDS_TARGET</varname> (which defaults to
+ <literal>install</literal>).</para>
+
+ <note>
+ <para>The <replaceable>lib</replaceable> part is a regular
+ expression which is being looked up in the
+ <command>ldconfig -r</command> output. Values such as
+ <literal>intl.[5-7]</literal> and <literal>intl</literal> are
+ allowed. The first pattern,
+ <literal>intl.[5-7]</literal>, will match any of:
+ <literal>intl.5</literal>, <literal>intl.6</literal> or
+ <literal>intl.7</literal>. The second pattern,
+ <literal>intl</literal>, will match any version of the
+ <literal>intl</literal> library.</para>
+ </note>
+
+ <para>The dependency is checked twice, once from within the
+ <buildtarget>extract</buildtarget> target and then from within the
+ <buildtarget>install</buildtarget> 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.</para>
+ </sect2>
+
+ <sect2>
+ <title><varname>RUN_DEPENDS</varname></title>
+
+ <para>This variable specifies executables or files this port depends
+ on during run-time. It is a list of
+ <replaceable>path</replaceable>:<replaceable>dir</replaceable><optional>:target</optional>
+ tuples where <replaceable>path</replaceable> is the name of the
+ executable or file, <replaceable>dir</replaceable> is the
+ directory in which to find it in case it is not available, and
+ <replaceable>target</replaceable> is the target to call in that
+ directory. If <replaceable>path</replaceable> starts with a slash
+ (<literal>/</literal>), it is treated as a file and its existence
+ is tested with <command>test -e</command>; otherwise, it is
+ assumed to be an executable, and <command>which -s</command> is
+ used to determine if the program exists in the search path.</para>
+
+ <para>For example,</para>
+
+ <programlisting>RUN_DEPENDS= ${LOCALBASE}/etc/innd:${PORTSDIR}/news/inn \
+ xmlcatmgr:${PORTSDIR}/textproc/xmlcatmgr</programlisting>
+
+ <para>will check if the file or directory
+ <filename>/usr/local/etc/innd</filename> exists, and build and
+ install it from the <filename>news/inn</filename> subdirectory of
+ the ports tree if it is not found. It will also see if an
+ executable called <command>xmlcatmgr</command> is in the search
+ path, and descend into the <filename>textproc/xmlcatmgr</filename>
+ subdirectory of your ports tree to build and install it if it is
+ not found.</para>
+
+ <note>
+ <para>In this case, <command>innd</command> 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.</para>
+ </note>
+
+ <note>
+ <para>The official search <envar>PATH</envar> used on the ports
+ build cluster is</para>
+
+ <programlisting>/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin</programlisting>
+ </note>
+
+ <para>The dependency is checked from within the
+ <buildtarget>install</buildtarget> 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 <replaceable>target</replaceable>
+ part can be omitted if it is the same as
+ <varname>DEPENDS_TARGET</varname>.</para>
+ </sect2>
+
+ <sect2>
+ <title><varname>BUILD_DEPENDS</varname></title>
+
+ <para>This variable specifies executables or files this port
+ requires to build. Like <varname>RUN_DEPENDS</varname>, it is a
+ list of
+ <replaceable>path</replaceable>:<replaceable>dir</replaceable><optional>:target</optional>
+ tuples. For example, <programlisting> BUILD_DEPENDS=
+ unzip:${PORTSDIR}/archivers/unzip</programlisting> will check
+ for an executable called <command>unzip</command>, and descend
+ into the <filename>archivers/unzip</filename> subdirectory of your
+ ports tree to build and install it if it is not found.</para>
+
+ <note>
+ <para><quote>build</quote> here means everything from extraction to
+ compilation. The dependency is checked from within the
+ <buildtarget>extract</buildtarget> target. The
+ <replaceable>target</replaceable> part can be omitted if it is
+ the same as <varname>DEPENDS_TARGET</varname></para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title><varname>FETCH_DEPENDS</varname></title>
+
+ <para>This variable specifies executables or files this port
+ requires to fetch. Like the previous two, it is a list of
+ <replaceable>path</replaceable>:<replaceable>dir</replaceable><optional>:target</optional>
+ tuples. For example, <programlisting> FETCH_DEPENDS=
+ ncftp2:${PORTSDIR}/net/ncftp2</programlisting> will check for an
+ executable called <command>ncftp2</command>, and descend into the
+ <filename>net/ncftp2</filename> subdirectory of your ports tree to
+ build and install it if it is not found.</para>
+
+ <para>The dependency is checked from within the
+ <buildtarget>fetch</buildtarget> target. The
+ <replaceable>target</replaceable> part can be omitted if it is the
+ same as <varname>DEPENDS_TARGET</varname>.</para>
+ </sect2>
+
+ <sect2>
+ <title><varname>EXTRACT_DEPENDS</varname></title>
+
+ <para>This variable specifies executables or files this port
+ requires for extraction. Like the previous, it is a list of
+ <replaceable>path</replaceable>:<replaceable>dir</replaceable><optional>:target</optional>
+ tuples. For example, <programlisting>EXTRACT_DEPENDS=
+ unzip:${PORTSDIR}/archivers/unzip</programlisting> will check
+ for an executable called <command>unzip</command>, and descend
+ into the <filename>archivers/unzip</filename> subdirectory of
+ your ports tree to build and install it if it is not found.</para>
+
+ <para>The dependency is checked from within the
+ <buildtarget>extract</buildtarget> target. The
+ <replaceable>target</replaceable> part can be omitted if it is the
+ same as <varname>DEPENDS_TARGET</varname>.</para>
+
+ <note>
+ <para>Use this variable only if the extraction does not already
+ work (the default assumes <command>gzip</command>) and cannot
+ be made to work using <varname>USE_ZIP</varname> or
+ <varname>USE_BZIP2</varname> described in <xref linkend="use-vars"/>.</para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title><varname>PATCH_DEPENDS</varname></title>
+
+ <para>This variable specifies executables or files this port
+ requires to patch. Like the previous, it is a list of
+ <replaceable>path</replaceable>:<replaceable>dir</replaceable><optional>:target</optional>
+ tuples. For example, <programlisting> PATCH_DEPENDS=
+ ${NONEXISTENT}:${PORTSDIR}/java/jfc:extract
+ </programlisting>will descend into the
+ <filename>java/jfc</filename> subdirectory of your ports tree to
+ extract it.</para>
+
+ <para>The dependency is checked from within the
+ <buildtarget>patch</buildtarget> target. The
+ <replaceable>target</replaceable> part can be omitted if it is the
+ same as <varname>DEPENDS_TARGET</varname>.</para>
+ </sect2>
+
+ <sect2 xml:id="use-vars">
+ <title><varname>USE_<replaceable>*</replaceable></varname></title>
+
+ <para>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
+ <filename>Makefile</filename>s. Each of them is styled
+ as <varname>USE_<replaceable>*</replaceable></varname>. The
+ usage of these variables is restricted to the port
+ <filename>Makefile</filename>s and
+ <filename>ports/Mk/bsd.*.mk</filename> and is not designed
+ to encapsulate user-settable options &mdash; use
+ <varname>WITH_<replaceable>*</replaceable></varname> and
+ <varname>WITHOUT_<replaceable>*</replaceable></varname>
+ for that purpose.</para>
+
+ <note>
+ <para>It is <emphasis>always</emphasis> incorrect to set
+ any <varname>USE_<replaceable>*</replaceable></varname>
+ in <filename>/etc/make.conf</filename>. For instance,
+ setting <programlisting>USE_GCC=3.2</programlisting>
+ would adds a dependency on gcc32 for every port,
+ including gcc32 itself!</para>
+ </note>
+
+ <table frame="none">
+ <title>The <varname>USE_<replaceable>*</replaceable></varname>
+ variables</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+
+ <entry>Means</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>USE_BZIP2</varname></entry>
+
+ <entry>The port's tarballs are compressed with
+ <command>bzip2</command>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_ZIP</varname></entry>
+
+ <entry>The port's tarballs are compressed with
+ <command>zip</command>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_BISON</varname></entry>
+
+ <entry>The port uses <command>bison</command> for
+ building.</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_CDRTOOLS</varname></entry>
+
+ <entry>該 port 需要 <application>cdrecord</application>,
+ 無論是 <package>sysutils/cdrtools</package> 或 <package>sysutils/cdrtools-cjk</package> 哪一種的
+ <application>cdrecord</application> 皆可,視使用者偏好而定
+ 。</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_GCC</varname></entry>
+
+ <entry>The port requires a specific version of
+ <command>gcc</command> to build. The exact version can be
+ specified with value such as <literal>3.2</literal>.
+ The minimal required version can be specified as
+ <literal>3.2+</literal>. The <command>gcc</command> from
+ the base system is used when it satisfies the requested
+ version, otherwise an appropriate <command>gcc</command> is
+ compiled from ports and the <varname>CC</varname> and
+ <varname>CXX</varname> variables are adjusted.</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>Variables related to <application>gmake</application> and
+ the <filename>configure</filename> script are described in
+ <xref linkend="building"/>, while
+ <application>autoconf</application>,
+ <application>automake</application> and
+ <application>libtool</application> are described in
+ <xref linkend="using-autotools"/>. <application>Perl</application>
+ related variables are described in <xref linkend="using-perl"/>.
+ X11 variables are listed in <xref linkend="using-x11"/>. <xref linkend="using-gnome"/> deals with GNOME and <xref linkend="using-kde"/> with KDE related variables. <xref linkend="using-java"/> documents Java variables, while <xref linkend="using-php"/> contains information on
+ <application>Apache</application>, <application>PHP</application>
+ and PEAR modules. <application>Python</application> is discussed
+ in <xref linkend="using-python"/>, while
+ <application>Ruby</application> in <xref linkend="using-ruby"/>.
+ <xref linkend="using-sdl"/> provides variables used for
+ <application>SDL</application> applications and finally,
+ <xref linkend="using-xfce"/> contains information on
+ <application>Xfce</application>.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>Minimal version of a dependency</title>
+
+ <para>A minimal version of a dependency can be specified in any
+ <varname>*_DEPENDS</varname> variable except
+ <varname>LIB_DEPENDS</varname> using the following
+ syntax:</para>
+
+ <programlisting>p5-Spiffy&gt;=0.26:${PORTSDIR}/devel/p5-Spiffy</programlisting>
+
+ <para>The 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.</para>
+ </sect2>
+
+ <sect2>
+ <title>Notes on dependencies</title>
+
+ <para>As mentioned above, the default target to call when a
+ dependency is required is <buildtarget>DEPENDS_TARGET</buildtarget>.
+ It defaults to <literal>install</literal>. This is a user
+ variable; it is never defined in a port's
+ <filename>Makefile</filename>. If your port needs a special way
+ to handle a dependency, use the <literal>:target</literal> part of
+ the <varname>*_DEPENDS</varname> variables instead of redefining
+ <varname>DEPENDS_TARGET</varname>.</para>
+
+ <para>When you type <command>make clean</command>, its dependencies
+ are automatically cleaned too. If you do not wish this to happen,
+ define the variable <varname>NOCLEANDEPENDS</varname> 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.</para>
+
+ <para>To depend on another port unconditionally, use the
+ variable <varname>${NONEXISTENT}</varname> as the first field
+ of <varname>BUILD_DEPENDS</varname> or
+ <varname>RUN_DEPENDS</varname>. 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
+
+ <programlisting>BUILD_DEPENDS= ${NONEXISTENT}:${PORTSDIR}/graphics/jpeg:extract</programlisting>
+
+ will always descend to the <literal>jpeg</literal> port and extract it.</para>
+ </sect2>
+
+ <sect2>
+ <title>Circular dependencies are fatal</title>
+
+ <important>
+ <para>Do not introduce any circular dependencies into the
+ ports tree!</para>
+ </important>
+
+ <para>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:
+ <command>cd /usr/ports; make index</command>. That process
+ can be quite slow on older machines, but you may be able to
+ save a large number of people&mdash;including yourself&mdash;
+ a lot of grief in the process.</para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="makefile-masterdir">
+ <title><varname>MASTERDIR</varname></title>
+
+ <para>If 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
+ <filename>Makefile</filename> in all but one of the directories if you
+ use variables cleverly. In the sole <filename>Makefile</filename>,
+ you can use <varname>MASTERDIR</varname> to specify the directory
+ where the rest of the files are. Also, use a variable as part of
+ <link linkend="porting-pkgname"><varname>PKGNAMESUFFIX</varname></link> so
+ the packages will have different names.</para>
+
+ <para>This will be best demonstrated by an example. This is part of
+ <filename>japanese/xdvi300/Makefile</filename>;</para>
+
+ <programlisting>PORTNAME= xdvi
+PORTVERSION= 17
+PKGNAMEPREFIX= ja-
+PKGNAMESUFFIX= ${RESOLUTION}
+ :
+# default
+RESOLUTION?= 300
+.if ${RESOLUTION} != 118 &amp;&amp; ${RESOLUTION} != 240 &amp;&amp; \
+ ${RESOLUTION} != 300 &amp;&amp; ${RESOLUTION} != 400
+ @${ECHO_MSG} "Error: invalid value for RESOLUTION: \"${RESOLUTION}\""
+ @${ECHO_MSG} "Possible values are: 118, 240, 300 (default) and 400."
+ @${FALSE}
+.endif</programlisting>
+
+ <para><package>japanese/xdvi300</package> also has all the regular
+ patches, package files, etc. If you type <command>make</command>
+ there, it will take the default value for the resolution (300) and
+ build the port normally.</para>
+
+ <para>As for other resolutions, this is the <emphasis>entire</emphasis>
+ <filename>xdvi118/Makefile</filename>:</para>
+
+ <programlisting>RESOLUTION= 118
+MASTERDIR= ${.CURDIR}/../xdvi300
+
+.include "${MASTERDIR}/Makefile"</programlisting>
+
+ <para>(<filename>xdvi240/Makefile</filename> and
+ <filename>xdvi400/Makefile</filename> are similar). The
+ <varname>MASTERDIR</varname> definition tells
+ <filename>bsd.port.mk</filename> that the regular set of
+ subdirectories like <varname>FILESDIR</varname> and
+ <varname>SCRIPTDIR</varname> are to be found under
+ <filename>xdvi300</filename>. The <literal>RESOLUTION=118</literal>
+ line will override the <literal>RESOLUTION=300</literal> line in
+ <filename>xdvi300/Makefile</filename> and the port will be built with
+ resolution set to 118.</para>
+ </sect1>
+
+ <sect1 xml:id="makefile-manpages">
+ <title>Manpages</title>
+
+ <para>The <varname>MAN[1-9LN]</varname> variables will automatically add
+ any manpages to <filename>pkg-plist</filename> (this means you must
+ <emphasis>not</emphasis> list manpages in the
+ <filename>pkg-plist</filename>&mdash;see <link linkend="plist-sub">generating PLIST</link> for more). It also
+ makes the install stage automatically compress or uncompress manpages
+ depending on the setting of <varname>NOMANCOMPRESS</varname> in
+ <filename>/etc/make.conf</filename>.</para>
+
+ <para>If your port tries to install multiple names for manpages using
+ symlinks or hardlinks, you must use the <varname>MLINKS</varname>
+ variable to identify these. The link installed by your port will
+ be destroyed and recreated by <filename>bsd.port.mk</filename>
+ to make sure it points to the correct file. Any manpages
+ listed in MLINKS must not be listed in the
+ <filename>pkg-plist</filename>.</para>
+
+ <para>To specify whether the manpages are compressed upon installation,
+ use the <varname>MANCOMPRESSED</varname> variable. This variable can
+ take three values, <literal>yes</literal>, <literal>no</literal> and
+ <literal>maybe</literal>. <literal>yes</literal> means manpages are
+ already installed compressed, <literal>no</literal> means they are
+ not, and <literal>maybe</literal> means the software already respects
+ the value of <varname>NOMANCOMPRESS</varname> so
+ <filename>bsd.port.mk</filename> does not have to do anything
+ special.</para>
+
+ <para><varname>MANCOMPRESSED</varname> is automatically set to
+ <literal>yes</literal> if <varname>USE_IMAKE</varname> is set and
+ <varname>NO_INSTALL_MANPAGES</varname> is not set, and to
+ <literal>no</literal> otherwise. You do not have to explicitly define
+ it unless the default is not suitable for your port.</para>
+
+ <para>If your port anchors its man tree somewhere other than
+ <varname>MANPREFIX</varname>, you can use the
+ <varname>MANPREFIX</varname> to set it. Also, if only manpages in
+ certain sections go in a non-standard place, such as some <literal>perl</literal> modules
+ ports, you can set individual man paths using
+ <varname>MAN<replaceable>sect</replaceable>PREFIX</varname> (where
+ <replaceable>sect</replaceable> is one of <literal>1-9</literal>,
+ <literal>L</literal> or <literal>N</literal>).</para>
+
+ <para>If your manpages go to language-specific subdirectories, set the
+ name of the languages to <varname>MANLANG</varname>. The value of
+ this variable defaults to <literal>""</literal> (i.e., English
+ only).</para>
+
+ <para>Here is an example that puts it all together.</para>
+
+ <programlisting>MAN1= foo.1
+MAN3= bar.3
+MAN4= baz.4
+MLINKS= foo.1 alt-name.8
+MANLANG= "" ja
+MAN3PREFIX= ${PREFIX}/share/foobar
+MANCOMPRESSED= yes</programlisting>
+
+ <para>This states that six files are installed by this port;</para>
+
+ <programlisting>${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.gz</programlisting>
+
+ <para>Additionally <filename>${MANPREFIX}/man/man8/alt-name.8.gz</filename>
+ 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.</para>
+
+ <para>If only some manpages are translated, you can use several variables
+ dynamically created from <varname>MANLANG</varname> content:</para>
+
+ <programlisting>MANLANG= "" de ja
+MAN1= foo.1
+MAN1_EN= bar.1
+MAN3_DE= baz.3</programlisting>
+
+ <para>This translates into this list of files:</para>
+
+ <programlisting>${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.gz</programlisting>
+ </sect1>
+
+ <sect1 xml:id="makefile-info">
+ <title>Info files</title>
+
+ <para>If your package needs to install GNU info files, they should be
+ listed in the <varname>INFO</varname> variable (without the trailing
+ <literal>.info</literal>), one entry per document. These files
+ are assumed to be installed to
+ <filename>PREFIX/INFO_PATH</filename>.
+ You can change <varname>INFO_PATH</varname> if your package uses
+ a different location. However, this is not recommended. These entries
+ contain just the path relative to
+ <filename>PREFIX/INFO_PATH</filename>.
+ For example, <package>lang/gcc33</package> installs
+ info files to
+ <filename>PREFIX/INFO_PATH/gcc33</filename>,
+ and <varname>INFO</varname> will be something like this:
+ <programlisting>INFO= gcc33/cpp gcc33/cppinternals gcc33/g77 ...
+</programlisting>
+ Appropriate installation/de-installation code will be automatically
+ added to the temporary <filename>pkg-plist</filename> before package
+ registration.</para>
+ </sect1>
+
+ <sect1 xml:id="makefile-options">
+ <title>Makefile Options</title>
+
+ <para>Some 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.</para>
+
+ <sect2>
+ <title>Knobs</title>
+
+ <sect3>
+ <title><varname>WITH_<replaceable>*</replaceable></varname> and
+ <varname>WITHOUT_<replaceable>*</replaceable></varname></title>
+
+ <para>These variables are designed to be set by the system
+ administrator. There are many that are standardized in
+ <link xlink:href="http://www.freebsd.org/cgi/cvsweb.cgi/ports/KNOBS?rev=HEAD&amp;content-type=text/x-cvsweb-markup"><filename>ports/KNOBS</filename></link>
+ file.</para>
+
+ <para>When creating a port, do not make knob names specific to a
+ given application. For example in Avahi port, use
+ <varname>WITHOUT_MDNS</varname> instead of
+ <varname>WITHOUT_AVAHI_MDNS</varname>.</para>
+
+ <note>
+ <para>You should not assume that a
+ <varname>WITH_<replaceable>*</replaceable></varname>
+ necessarily has a corresponding
+ <varname>WITHOUT_<replaceable>*</replaceable></varname>
+ variable and vice versa. In general, the default is
+ simply assumed.</para>
+ </note>
+
+ <note>
+ <para>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 <literal>YES</literal> or
+ <literal>NO</literal>.</para>
+ </note>
+
+ <table frame="none">
+ <title>Common <varname>WITH_<replaceable>*</replaceable></varname>
+ and <varname>WITHOUT_<replaceable>*</replaceable></varname>
+ variables</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+
+ <entry>Means</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row xml:id="knobs-without-nls">
+ <entry><varname>WITHOUT_NLS</varname></entry>
+
+ <entry>If set, says that internationalization is not
+ needed, which can save compile time. By default,
+ internationalization is used.</entry>
+ </row>
+
+ <row>
+ <entry><varname>WITH_OPENSSL_BASE</varname></entry>
+
+ <entry>Use the version of OpenSSL in the base system.</entry>
+ </row>
+
+ <row>
+ <entry><varname>WITH_OPENSSL_PORT</varname></entry>
+
+ <entry>Installs the version of OpenSSL from
+ <package>security/openssl</package>,
+ even if the base is up to date.</entry>
+ </row>
+
+ <row>
+ <entry><varname>WITHOUT_X11</varname></entry>
+
+ <entry>If 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.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect3>
+
+ <sect3>
+ <title>Knob naming</title>
+ <para>It 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
+ <link xlink:href="http://www.freebsd.org/cgi/cvsweb.cgi/ports/KNOBS?rev=HEAD&amp;content-type=text/x-cvsweb-markup">KNOBS</link>
+ file.</para>
+
+ <para>Knob names should reflect what the knob is and does.
+ When a port has a lib-prefix in the <varname>PORTNAME</varname>
+ the lib-prefix should be dropped in knob naming.</para>
+
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title><varname>OPTIONS</varname></title>
+
+ <sect3>
+ <title>Background</title>
+ <para>The <varname>OPTIONS</varname> variable gives the user who
+ installs the port a dialog with the available options and saves
+ them to <filename>/var/db/ports/portname/options</filename>.
+ Next time when the port has to be rebuild, the options are reused.
+ Never again you will have to remember all the twenty
+ <varname>WITH_<replaceable>*</replaceable></varname> and
+ <varname>WITHOUT_<replaceable>*</replaceable></varname> options you
+ used to build this port!</para>
+
+ <para>When the user runs <command>make config</command> (or runs
+ <command>make build</command> for the first time), the framework will
+ check for
+ <filename>/var/db/ports/portname/options</filename>.
+ If that file does not exist, it will use the values of
+ <varname>OPTIONS</varname> to create a dialogbox where the options
+ can be enabled or disabled. Then the
+ <filename>options</filename> file is saved and the selected
+ variables will be used when building the port.</para>
+
+ <para>If a new version of the port adds new
+ <varname>OPTIONS</varname>, the dialog will be presented to the
+ user, with the saved values of old <varname>OPTIONS</varname>
+ prefilled.</para>
+
+ <para>Use <command>make showconfig</command> to see the saved
+ configuration. Use <command>make rmconfig</command> to remove the
+ saved configuration.</para>
+ </sect3>
+
+ <sect3>
+ <title>Syntax</title>
+ <para>The syntax for the <varname>OPTIONS</varname> variable is:
+
+<programlisting>OPTIONS= OPTION "descriptive text" default ...
+</programlisting>
+
+ The value for default is either <literal>ON</literal> or
+ <literal>OFF</literal>. Multiple repetitions of these three fields
+ are allowed.</para>
+
+ <para><varname>OPTIONS</varname> definition must appear before
+ the inclusion of <filename>bsd.port.pre.mk</filename>.
+ The <varname>WITH_*</varname> and <varname>WITHOUT_*</varname>
+ variables can only be tested after the inclusion of
+ <filename>bsd.port.pre.mk</filename>.</para>
+ </sect3>
+
+ <sect3>
+ <title>Example</title>
+ <example xml:id="ports-options-simple-use">
+ <title>Simple use of <varname>OPTIONS</varname></title>
+ <para><programlisting>OPTIONS= FOO "Enable option foo" On \
+ BAR "Support feature bar" Off
+
+.include &lt;bsd.port.pre.mk&gt;
+
+.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 &lt;bsd.port.post.mk&gt;</programlisting></para>
+ </example>
+ </sect3>
+
+ </sect2>
+
+ <sect2>
+ <title>Feature auto-activation</title>
+
+ <para>When 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
+ <literal>--without-xxx</literal> or <literal>--disable-xxx</literal>
+ in <varname>CONFIGURE_ARGS</varname>.</para>
+
+ <example>
+ <title>Wrong handling of an option</title>
+ <programlisting>.if defined(WITH_FOO)
+LIB_DEPENDS+= foo.0:${PORTSDIR}/devel/foo
+CONFIGURE_ARGS+= --enable-foo
+.endif</programlisting>
+ </example>
+
+ <para>In 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 <literal>make config</literal> 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.</para>
+
+ <example>
+ <title>Correct handling of an option</title>
+ <programlisting>.if defined(WITH_FOO)
+LIB_DEPENDS+= foo.0:${PORTSDIR}/devel/foo
+CONFIGURE_ARGS+= --enable-foo
+.else
+CONFIGURE_ARGS+= --disable-foo
+.endif</programlisting>
+ </example>
+
+ <para>In 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.</para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="makefile-wrkdir">
+ <title>Specifying the working directory</title>
+
+ <para>Each port is extracted in to a working directory, which must be
+ writable. The ports system defaults to having the
+ <varname>DISTFILES</varname> unpack in to a directory called
+ <literal>${DISTNAME}</literal>. In other words, if you have
+ set:</para>
+
+ <programlisting>PORTNAME= foo
+PORTVERSION= 1.0</programlisting>
+
+ <para>then the port's distribution files contain a top-level directory,
+ <filename>foo-1.0</filename>, and the rest of the files are located
+ under that directory.</para>
+
+ <para>There are a number of variables you can override if that is not the
+ case.</para>
+
+ <sect2>
+ <title><varname>WRKSRC</varname></title>
+
+ <para>The 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 <filename>foo</filename> (and not
+ <filename>foo-1.0</filename>) you would write:</para>
+
+ <programlisting>WRKSRC= ${WRKDIR}/foo</programlisting>
+
+ <para>or possibly</para>
+
+ <programlisting>WRKSRC= ${WRKDIR}/${PORTNAME}</programlisting>
+ </sect2>
+
+ <sect2>
+ <title><varname>NO_WRKSUBDIR</varname></title>
+
+ <para>If the port does not extract in to a subdirectory at all then
+ you should set <varname>NO_WRKSUBDIR</varname> to indicate
+ that.</para>
+
+ <programlisting>NO_WRKSUBDIR= yes</programlisting>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="conflicts">
+ <title><varname>CONFLICTS</varname></title>
+
+ <para>If your package cannot coexist with other packages
+ (because of file conflicts, runtime incompatibility, etc.),
+ list the other package names in the <varname>CONFLICTS</varname>
+ variable. You can use shell globs like <literal>*</literal> and
+ <literal>?</literal> here. Packages names should be
+ enumerated the same way they appear in
+ <filename>/var/db/pkg</filename>. Please make sure that
+ <varname>CONFLICTS</varname> does not match this port's
+ package itself, or else forcing its installation with
+ <varname>FORCE_PKG_REGISTER</varname> will no longer work.
+ </para>
+
+ <note>
+ <para><varname>CONFLICTS</varname> automatically sets
+ <varname>IGNORE</varname>, which is more fully documented
+ in <xref linkend="dads-noinstall"/>.</para>
+ </note>
+
+ <para>When removing one of several conflicting ports, it is advisable to
+ retain the <varname>CONFLICTS</varname> entries in those other ports
+ for a few months to cater for users who only update once in a
+ while.</para>
+ </sect1>
+
+ <sect1 xml:id="install">
+ <title>Installing files</title>
+
+ <sect2 xml:id="install-macros">
+ <title>INSTALL_* macros</title>
+
+ <para>Do use the macros provided in <filename>bsd.port.mk</filename>
+ to ensure correct modes and ownership of files in your own
+ <buildtarget>*-install</buildtarget> targets.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><varname>INSTALL_PROGRAM</varname> is a command to install
+ binary executables.</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>INSTALL_SCRIPT</varname> is a command to install
+ executable scripts.</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>INSTALL_KLD</varname> 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 <varname>INSTALL_PROGRAM</varname>.</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>INSTALL_DATA</varname> is a command to install
+ sharable data.</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>INSTALL_MAN</varname> is a command to install
+ manpages and other documentation (it does not compress
+ anything).</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>These are basically the <command>install</command> command with
+ all the appropriate flags.</para>
+ </sect2>
+
+ <sect2 xml:id="install-strip">
+ <title>Stripping Binaries</title>
+
+ <para>Do not strip binaries manually unless you have to. All binaries
+ should be stripped, but the <buildtarget>INSTALL_PROGRAM</buildtarget>
+ macro will install and strip a binary at the same time (see the next
+ section).</para>
+
+ <para>If you need to strip a file, but do not wish to use the
+ <varname>INSTALL_PROGRAM</varname> macro,
+ <varname>${STRIP_CMD}</varname> will strip your program. This is
+ typically done within the <literal>post-install</literal>
+ target. For example:</para>
+
+ <programlisting>post-install:
+ ${STRIP_CMD} ${PREFIX}/bin/xdl</programlisting>
+
+ <para>Use the &man.file.1; command on the installed executable to
+ check whether the binary is stripped or not. If it does not say
+ <literal>not stripped</literal>, it is stripped. Additionally,
+ &man.strip.1; will not strip a previously stripped program; it
+ will instead exit cleanly.</para>
+ </sect2>
+
+ <sect2 xml:id="install-copytree">
+ <title>Installing a whole tree of files</title>
+
+ <para>Sometimes, there is a need to install a big number of files,
+ preserving their hierarchical organization, ie. copying over a whole
+ directory tree from <varname>WRKSRC</varname> to a target directory
+ under <varname>PREFIX</varname>.</para>
+
+ <para>Two macros exists for this situation. The advantage of using
+ these macros instead of <command>cp</command> is that they guarantee
+ proper file ownership and permissions on target files. First macro,
+ <varname>COPYTREE_BIN</varname>, will set all the installed files to
+ be executable, thus being suitable for installing into
+ <filename>PREFIX/bin</filename>. The second
+ macro, <varname>COPYTREE_SHARE</varname>, does not set executable
+ permissions on files, and is therefore suitable for installing files
+ under <filename>PREFIX/share</filename>
+ target.</para>
+
+ <programlisting>post-install:
+ ${MKDIR} ${EXAMPLESDIR}
+ (cd ${WRKSRC}/examples/ &amp;&amp; ${COPYTREE_SHARE} \* ${EXAMPLESDIR})</programlisting>
+
+ <para>This example will install the contents of
+ <filename>examples</filename> directory in the vendor distfile to the
+ proper examples location of your port.</para>
+
+ <programlisting>post-install:
+ ${MKDIR} ${DATADIR}/summer
+ (cd ${WRKSRC}/temperatures/ &amp;&amp; ${COPYTREE_SHARE} "June July August" ${DATADIR}/summer/)</programlisting>
+
+ <para>And this example will install the data of summer months to the
+ <filename>summer</filename> subdirectory of a
+ <filename>DATADIR</filename>.</para>
+
+ <para>Additional <command>find</command> arguments can be passed via
+ the third argument to the <varname>COPYTREE_*</varname> macros.
+ For example, to install all files from the first example except
+ Makefiles, one can use the following command.</para>
+
+ <programlisting>post-install:
+ ${MKDIR} ${EXAMPLESDIR}
+ (cd ${WRKSRC}/examples/ &amp;&amp; \
+ ${COPYTREE_SHARE} \* ${EXAMPLESDIR} "! -name Makefile")</programlisting>
+
+ <para>Note that these macros does not add the installed files to
+ <filename>pkg-plist</filename>. You still need to list them.</para>
+ </sect2>
+
+ <sect2 xml:id="install-documentation">
+ <title>Install additional documentation</title>
+
+ <para>If your software has some documentation other than the standard
+ man and info pages that you think is useful for the user, install it
+ under <filename>PREFIX/share/doc</filename>.
+ This can be done, like the previous item, in the
+ <buildtarget>post-install</buildtarget> target.</para>
+
+ <para>Create a new directory for your port. The directory name should
+ reflect what the port is. This usually means
+ <varname>PORTNAME</varname>. 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
+ <varname>PKGNAME</varname>.</para>
+
+ <para>Make the installation dependent on the variable
+ <varname>NOPORTDOCS</varname> so that users can disable it in
+ <filename>/etc/make.conf</filename>, like this:</para>
+
+ <programlisting>post-install:
+.if !defined(NOPORTDOCS)
+ ${MKDIR} ${DOCSDIR}
+ ${INSTALL_MAN} ${WRKSRC}/docs/xvdocs.ps ${DOCSDIR}
+.endif</programlisting>
+
+ <para>Here are some handy variables and how they are expanded
+ by default when used
+ in the <filename>Makefile</filename>:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><varname>DATADIR</varname> gets expanded to
+ <filename>PREFIX/share/PORTNAME</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>DATADIR_REL</varname> gets expanded to
+ <filename>share/PORTNAME</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>DOCSDIR</varname> gets expanded to
+ <filename>PREFIX/share/doc/PORTNAME</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>DOCSDIR_REL</varname> gets expanded to
+ <filename>share/doc/PORTNAME</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>EXAMPLESDIR</varname> gets expanded to
+ <filename>PREFIX/share/examples/PORTNAME</filename>.</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>EXAMPLESDIR_REL</varname> gets expanded to
+ <filename>share/examples/PORTNAME</filename>.</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <para><varname>NOPORTDOCS</varname> only controls additional
+ documentation installed in <varname>DOCSDIR</varname>. It does not
+ apply to standard man pages and info pages. Things installed in
+ <varname>DATADIR</varname> and <varname>EXAMPLESDIR</varname>
+ are controlled by <varname>NOPORTDATA</varname> and
+ <varname>NOPORTEXAMPLES</varname>, respectively.</para>
+ </note>
+
+ <para>These variables are exported to <varname>PLIST_SUB</varname>.
+ Their values will appear there as pathnames relative to
+ <filename>PREFIX</filename> if possible.
+ That is, <filename>share/doc/PORTNAME</filename>
+ will be substituted for <literal>%%DOCSDIR%%</literal>
+ in the packing list by default, and so on.
+ (See more on <filename>pkg-plist</filename> substitution
+ <link linkend="plist-sub">here</link>.)</para>
+
+ <para>All conditionally installed documentation files and directories should
+ be included in <filename>pkg-plist</filename> with the
+ <literal>%%PORTDOCS%%</literal> prefix, for example:</para>
+
+ <programlisting>%%PORTDOCS%%%%DOCSDIR%%/AUTHORS
+%%PORTDOCS%%%%DOCSDIR%%/CONTACT
+%%PORTDOCS%%@dirrm %%DOCSDIR%%</programlisting>
+
+ <para>As an alternative to enumerating the documentation files
+ in <filename>pkg-plist</filename>, a port can set the variable
+ <varname>PORTDOCS</varname> to a list of file names and shell
+ glob patterns to add to the final packing list.
+ The names will be relative to <varname>DOCSDIR</varname>.
+ Therefore, a port that utilizes <varname>PORTDOCS</varname> and
+ uses a non-default location for its documentation should set
+ <varname>DOCSDIR</varname> accordingly.
+ If a directory is listed in <varname>PORTDOCS</varname>
+ 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 <varname>NOPORTDOCS</varname>
+ is defined then files and directories listed in
+ <varname>PORTDOCS</varname> would not be installed and neither
+ would be added to port packing list.
+ Installing the documentation at <varname>PORTDOCS</varname>
+ as shown above remains up to the port itself.
+ A typical example of utilizing <varname>PORTDOCS</varname>
+ looks as follows:</para>
+
+ <programlisting>PORTDOCS= README.* ChangeLog docs/*</programlisting>
+
+ <note>
+ <para>The equivalents of <varname>PORTDOCS</varname> for files
+ installed under <varname>DATADIR</varname> and
+ <varname>EXAMPLESDIR</varname> are <varname>PORTDATA</varname>
+ and <varname>PORTEXAMPLES</varname>, respectively.</para>
+
+ <para>You can also use the <filename>pkg-message</filename> file to
+ display messages upon installation. See <link linkend="porting-message">the section on using
+ <filename>pkg-message</filename></link> for details.
+ The <filename>pkg-message</filename> file does not need to be
+ added to <filename>pkg-plist</filename>.</para>
+ </note>
+ </sect2>
+
+ <sect2 xml:id="install-subdirs">
+ <title>Subdirectories under PREFIX</title>
+
+ <para>Try to let the port put things in the right subdirectories of
+ <varname>PREFIX</varname>. 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 <filename>lib</filename>, which does
+ not work well with the BSD paradigm. Many of the files should be
+ moved to one of the following: <filename>etc</filename>
+ (setup/configuration files), <filename>libexec</filename>
+ (executables started internally), <filename>sbin</filename>
+ (executables for superusers/managers), <filename>info</filename>
+ (documentation for info browser) or <filename>share</filename>
+ (architecture independent files). See &man.hier.7; for details;
+ the rules governing
+ <filename>/usr</filename> pretty much apply to
+ <filename>/usr/local</filename> too. The exception are ports
+ dealing with USENET <quote>news</quote>. They may use
+ <filename>PREFIX/news</filename> as a destination
+ for their files.</para>
+ </sect2>
+
+ </sect1>
+
+ </chapter>
+
+ <chapter xml:id="special">
+ <title>Special considerations</title>
+
+ <para>There are some more things you have to take into account when you
+ create a port. This section explains the most common of those.</para>
+
+ <sect1 xml:id="porting-shlibs">
+ <title>Shared Libraries</title>
+
+ <para>If your port installs one or more shared libraries, define a
+ <varname>USE_LDCONFIG</varname> make variable, which will instruct
+ a <filename>bsd.port.mk</filename> to run
+ <literal>&dollar;{LDCONFIG} -m</literal> on the directory where the
+ new library is installed (usually
+ <filename>PREFIX/lib</filename>) during
+ <buildtarget>post-install</buildtarget> target to register it into the
+ shared library cache. This variable, when defined, will also
+ facilitate addition of an appropriate
+ <literal>@exec /sbin/ldconfig -m</literal> and
+ <literal>@unexec /sbin/ldconfig -R</literal> pair into your
+ <filename>pkg-plist</filename> 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.</para>
+
+ <programlisting>USE_LDCONFIG= yes</programlisting>
+
+ <para>If you need, you can override the default directory
+ by setting the <varname>USE_LDCONFIG</varname>
+ value to a list of directories into which
+ shared libraries are to be installed. For example if your port
+ installs shared libraries into
+ <filename>PREFIX/lib/foo</filename> and
+ <filename>PREFIX/lib/bar</filename> directories
+ you could use the following in your
+ <filename>Makefile</filename>:</para>
+
+ <programlisting>USE_LDCONFIG= ${PREFIX}/lib/foo ${PREFIX}/lib/bar</programlisting>
+
+ <para>Please
+ double-check, often this is not necessary at all or can be avoided
+ through <literal>-rpath</literal> or setting <envar>LD_RUN_PATH</envar>
+ during linking (see <package>lang/moscow_ml</package>
+ for an example), or through a shell-wrapper which sets
+ <varname>LD_LIBRARY_PATH</varname> before invoking the binary, like
+ <package>www/mozilla</package> does.</para>
+
+ <para>When installing 32-bit libraries on 64-bit system, use
+ <varname>USE_LDCONFIG32</varname> instead.</para>
+
+ <para>Try to keep shared library version numbers in the
+ <filename>libfoo.so.0</filename> format. Our runtime linker only
+ cares for the major (first) number.</para>
+
+ <para>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 <varname>PORTREVISION</varname> incremented,
+ to force recompilation with the new library version.</para>
+
+ </sect1>
+
+ <sect1 xml:id="porting-restrictions">
+ <title>Ports with distribution restrictions</title>
+
+ <para>Licenses vary, and some of them place restrictions on how the
+ application can be packaged, whether it can be sold for profit, and so
+ on.</para>
+
+ <important>
+ <para>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;.</para>
+ </important>
+
+ <para>In situations like this, the variables described in the following
+ sections can be set.</para>
+
+ <sect2>
+ <title><varname>NO_PACKAGE</varname></title>
+
+ <para>This 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.</para>
+
+ <para>However, the port's <varname>DISTFILES</varname> may be
+ freely mirrored on FTP/HTTP. They may also be distributed on
+ a CD-ROM (or similar media) unless <varname>NO_CDROM</varname>
+ is set as well.</para>
+
+ <para><varname>NO_PACKAGE</varname> 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 <varname>NO_PACKAGE</varname>.</para>
+
+ <para><varname>NO_PACKAGE</varname> should be set to a string
+ describing the reason why the package should not be
+ generated.</para>
+ </sect2>
+
+ <sect2>
+ <title><varname>NO_CDROM</varname></title>
+
+ <para>This variable alone indicates that, although we are allowed
+ to generate binary packages, we may put neither those packages
+ nor the port's <varname>DISTFILES</varname> onto a CD-ROM (or
+ similar media) for resale. However, the binary packages and
+ the port's <varname>DISTFILES</varname> will still be available
+ via FTP/HTTP.</para>
+
+ <para>If this variable is set along with
+ <varname>NO_PACKAGE</varname>, then only the port's
+ <varname>DISTFILES</varname> will be available, and only via
+ FTP/HTTP.</para>
+
+ <para><varname>NO_CDROM</varname> 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 <quote>non-commercial</quote> use only.</para>
+ </sect2>
+
+ <sect2>
+ <title><varname>NOFETCHFILES</varname></title>
+
+ <para>Files defined in the <varname>NOFETCHFILES</varname>
+ variable are not fetchable from any of the
+ <varname>MASTER_SITES</varname>. An example of such a
+ file is when the file is supplied on CD-ROM by the
+ vendor.</para>
+
+ <para>Tools which check for the availability of these files
+ on the <varname>MASTER_SITES</varname> should ignore these
+ files and not report about them.</para>
+ </sect2>
+
+ <sect2>
+ <title><varname>RESTRICTED</varname></title>
+
+ <para>Set this variable alone if the application's license permits
+ neither mirroring the application's <varname>DISTFILES</varname>
+ nor distributing the binary package in any way.</para>
+
+ <para><varname>NO_CDROM</varname> or <varname>NO_PACKAGE</varname>
+ should not be set along with <varname>RESTRICTED</varname>
+ since the latter variable implies the former ones.</para>
+
+ <para><varname>RESTRICTED</varname> 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
+ <varname>DISTFILES</varname>, possibly after registering for the
+ software or agreeing to accept the terms of an
+ <acronym>EULA</acronym>.</para>
+ </sect2>
+
+ <sect2>
+ <title><varname>RESTRICTED_FILES</varname></title>
+
+ <para>When <varname>RESTRICTED</varname> or <varname>NO_CDROM</varname>
+ is set, this variable defaults to <literal>${DISTFILES}
+ ${PATCHFILES}</literal>, otherwise it is empty. If only some of the
+ distribution files are restricted, then set this variable to list
+ them.</para>
+
+ <para>Note that the port committer should add an entry to
+ <filename>/usr/ports/LEGAL</filename> for every listed distribution
+ file, describing exactly what the restriction entails.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="building">
+ <title>Building mechanisms</title>
+
+ <sect2 xml:id="using-make">
+ <title><command>make</command>, <command>gmake</command>, and
+ <command>imake</command></title>
+
+ <para>If your port uses <application>GNU make</application>, set
+ <literal>USE_GMAKE=yes</literal>.</para>
+
+ <table frame="none">
+ <title>Variables for ports related to gmake</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+
+ <entry>Means</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>USE_GMAKE</varname></entry>
+
+ <entry>The port requires <command>gmake</command> to
+ build.</entry>
+ </row>
+
+ <row>
+ <entry><varname>GMAKE</varname></entry>
+
+ <entry>The full path for <command>gmake</command> if it is not
+ in the <envar>PATH</envar>.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>If your port is an X application that creates
+ <filename>Makefile</filename> files from
+ <filename>Imakefile</filename> files using
+ <application>imake</application>, then set
+ <literal>USE_IMAKE=yes</literal>. This will cause the
+ configure stage to automatically do an <command>xmkmf -a</command>.
+ If the <option>-a</option> flag is a problem for your port, set
+ <literal>XMKMF=xmkmf</literal>. If the port uses
+ <application>imake</application> but does not understand the
+ <buildtarget>install.man</buildtarget> target,
+ <literal>NO_INSTALL_MANPAGES=yes</literal> should be set.</para>
+
+ <para>If your port's source <filename>Makefile</filename> has
+ something else than <buildtarget>all</buildtarget> as the main build
+ target, set <varname>ALL_TARGET</varname> accordingly. Same goes
+ for <buildtarget>install</buildtarget> and
+ <varname>INSTALL_TARGET</varname>.</para>
+
+ </sect2>
+
+ <sect2 xml:id="using-configure">
+ <title><command>configure</command> script</title>
+
+ <para>If your port uses the <command>configure</command> script to
+ generate <filename>Makefile</filename> files from
+ <filename>Makefile.in</filename> files, set
+ <literal>GNU_CONFIGURE=yes</literal>. If you want to give extra
+ arguments to the <command>configure</command> script (the default
+ argument is <literal>--prefix=&dollar;{PREFIX}
+ --infodir=&dollar;{PREFIX}/&dollar;{INFO_PATH}
+ --mandir=&dollar;{MANPREFIX}/man
+ --build=&dollar;{CONFIGURE_TARGET}</literal>), set those
+ extra arguments in <varname>CONFIGURE_ARGS</varname>. Extra
+ environment variables can be passed using
+ <varname>CONFIGURE_ENV</varname> variable.</para>
+
+ <table frame="none">
+ <title>Variables for ports that use configure</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+
+ <entry>Means</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>GNU_CONFIGURE</varname></entry>
+
+ <entry>The port uses <command>configure</command> script to
+ prepare build.</entry>
+ </row>
+
+ <row>
+ <entry><varname>HAS_CONFIGURE</varname></entry>
+
+ <entry>Same as <varname>GNU_CONFIGURE</varname>, except
+ default configure target is not added to
+ <varname>CONFIGURE_ARGS</varname>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>CONFIGURE_ARGS</varname></entry>
+
+ <entry>Additional arguments passed to
+ <command>configure</command> script.</entry>
+ </row>
+
+ <row>
+ <entry><varname>CONFIGURE_ENV</varname></entry>
+
+ <entry>Additional environment variables to be set
+ for <command>configure</command> script run.</entry>
+ </row>
+
+ <row>
+ <entry><varname>CONFIGURE_TARGET</varname></entry>
+
+ <entry>Override default configure target. Default value is
+ <literal>&dollar;{MACHINE_ARCH}-portbld-freebsd&dollar;{OSREL}</literal>.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 xml:id="using-scons">
+ <title>Using <command>scons</command></title>
+
+ <para>If your port uses <application>SCons</application>, define
+ <literal>USE_SCONS=yes</literal>.</para>
+
+ <table frame="none">
+ <title>Variables for ports that use <command>scons</command></title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+
+ <entry>Means</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>SCONS_ARGS</varname></entry>
+
+ <entry>Port specific SCons flags passed to the SCons
+ environment.</entry>
+ </row>
+
+ <row>
+ <entry><varname>SCONS_BUILDENV</varname></entry>
+
+ <entry>Variables to be set in system environment.</entry>
+ </row>
+
+ <row>
+ <entry><varname>SCONS_ENV</varname></entry>
+
+ <entry>Variables to be set in SCons environment.</entry>
+ </row>
+
+ <row>
+ <entry><varname>SCONS_TARGET</varname></entry>
+
+ <entry>Last argument passed to SCons, similar to
+ <varname>MAKE_TARGET</varname>.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="using-autotools">
+ <title>Using GNU autotools</title>
+
+ <sect2 xml:id="using-autotools-introduction">
+ <title>Introduction</title>
+
+ <para>The 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:</para>
+
+ <programlisting>USE_AUTOTOOLS= <replaceable>tool</replaceable>:<replaceable>version</replaceable>[:<replaceable>operation</replaceable>] ...</programlisting>
+
+ <para>At the time of writing, <replaceable>tool</replaceable> can be
+ one of <literal>libtool</literal>, <literal>libltdl</literal>,
+ <literal>autoconf</literal>, <literal>autoheader</literal>,
+ <literal>automake</literal> or <literal>aclocal</literal>.</para>
+
+ <para><replaceable>version</replaceable> specifies the particular
+ tool revision to be used (see
+ <literal>devel/{automake,autoconf,libtool}[0-9]+</literal> for
+ valid versions).</para>
+
+ <para><replaceable>operation</replaceable> is an optional extension
+ to modify how the tool is used.</para>
+
+ <para>Multiple tools can be specified at once, either by including
+ them all on a single line, or using the <literal>+=</literal>
+ Makefile construct.</para>
+
+ <para>Finally, there is the special tool, called
+ <literal>autotools</literal>, 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 <literal>devel/autotools</literal> port.</para>
+
+ </sect2>
+
+ <sect2 xml:id="using-libtool">
+ <title><command>libtool</command></title>
+
+ <para>Shared libraries using the GNU building framework usually use
+ <command>libtool</command> 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
+ <command>libtool</command> bundled with the application. In case
+ you need to use external <command>libtool</command>, you can use
+ the version provided by The Ports Collection:</para>
+
+ <programlisting>USE_AUTOTOOLS= libtool:<replaceable>version</replaceable>[:env]</programlisting>
+
+ <para>With no additional operations,
+ <literal>libtool:version</literal> tells
+ the building framework to patch the configure script with the
+ system-installed copy of <command>libtool</command>.
+ The <varname>GNU_CONFIGURE</varname> is implied.
+ Further, a number of make and shell
+ variables will be assigned for onward use by the port. See
+ <filename>bsd.autotools.mk</filename> for details.</para>
+
+ <para>With the <literal>:env</literal> operation, only the
+ environment will be set up.</para>
+
+ <para>Finally, <varname>LIBTOOLFLAGS</varname> and
+ <varname>LIBTOOLFILES</varname> can be optionally set to override
+ the most likely arguments to, and files patched by,
+ <command>libtool</command>. Most ports are unlikely to need this.
+ See <filename>bsd.autotools.mk</filename> for further
+ details.</para>
+
+ </sect2>
+
+ <sect2 xml:id="using-libltdl">
+ <title><command>libltdl</command></title>
+
+ <para>Some ports make use of the <command>libltdl</command> library
+ package, which is part of the <command>libtool</command> suite.
+ Use of this library does not automatically necessitate the use of
+ <command>libtool</command> itself, so a separate construct is
+ provided.</para>
+
+ <programlisting>USE_AUTOTOOLS= libltdl:<replaceable>version</replaceable></programlisting>
+
+ <para>Currently, all this does is to bring in a
+ <varname>LIB_DEPENDS</varname> on the appropriate
+ <command>libltdl</command> port, and is provided as a convenience
+ function to help eliminate any dependencies on the autotools ports
+ outside of the <varname>USE_AUTOTOOLS</varname> framework. There
+ are no optional operations for this tool.</para>
+
+ </sect2>
+
+ <sect2 xml:id="using-autoconf">
+ <title><command>autoconf</command> and
+ <command>autoheader</command></title>
+
+ <para>Some ports do not contain a configure script, but do contain an
+ autoconf template in the <filename>configure.ac</filename> file.
+ You can use the following assignments to let
+ <command>autoconf</command> create the configure script, and also
+ have <command>autoheader</command> create template headers for use
+ by the configure script.</para>
+
+ <programlisting>USE_AUTOTOOLS= autoconf:<replaceable>version</replaceable>[:env]</programlisting>
+
+ <para>and</para>
+
+ <programlisting>USE_AUTOTOOLS= autoheader:<replaceable>version</replaceable></programlisting>
+
+ <para>which also implies the use of
+ <literal>autoconf:version</literal>.</para>
+
+ <para>Similarly to <command>libtool</command>, the inclusion of the
+ optional <literal>:env</literal> operation simply sets up the
+ environment for further use. Without it, patching and
+ reconfiguration of the port is carried out.</para>
+
+ <para>The additional optional variables
+ <varname>AUTOCONF_ARGS</varname> and
+ <varname>AUTOHEADER_ARGS</varname> can be overridden by the port
+ <filename>Makefile</filename> if specifically requested. As with
+ the <command>libtool</command> equivalents, most ports are unlikely
+ to need this.</para>
+
+ </sect2>
+
+ <sect2 xml:id="using-automake">
+ <title><command>automake</command> and
+ <command>aclocal</command></title>
+
+ <para>Some packages only contain <filename>Makefile.am</filename>
+ files. These have to be converted into
+ <filename>Makefile.in</filename> files using
+ <command>automake</command>, and the further processed by
+ <command>configure</command> to generate an actual
+ <filename>Makefile</filename>.</para>
+
+ <para>Similarly, packages occasionally do not ship with included
+ <filename>aclocal.m4</filename> files, again required to build the
+ software. This can be achieved with <command>aclocal</command>,
+ which scans <filename>configure.ac</filename> or
+ <filename>configure.in</filename>.</para>
+
+ <para><command>aclocal</command> has a similar relationship to
+ <command>automake</command> as <command>autoheader</command> does
+ to <command>autoconf</command>, described in the previous section.
+ <command>aclocal</command> implies the use of
+ <command>automake</command>, thus we have:</para>
+
+ <programlisting>USE_AUTOTOOLS= automake:<replaceable>version</replaceable>[:<replaceable>env</replaceable>]</programlisting>
+
+ <para>and</para>
+
+ <programlisting>USE_AUTOTOOLS= aclocal:<replaceable>version</replaceable></programlisting>
+
+ <para>which also implies the use of
+ <literal>automake:version</literal>.</para>
+
+ <para>Similarly to <command>libtool</command> and
+ <command>autoconf</command>, the inclusion of the optional
+ <literal>:env</literal> operation simply sets up the environment
+ for further use. Without it, reconfiguration of the port is
+ carried out.</para>
+
+ <para>As with
+ <command>autoconf</command> and <command>autoheader</command>, both
+ <command>automake</command> and <command>aclocal</command> have
+ optional argument variables, <varname>AUTOMAKE_ARGS</varname> and
+ <varname>ACLOCAL_ARGS</varname> respectively, which may be
+ overriden by the port <filename>Makefile</filename> if
+ required.</para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="using-gettext">
+ <title>Using GNU <literal>gettext</literal></title>
+
+ <sect2>
+ <title>Basic usage</title>
+
+ <para>If your port requires <literal>gettext</literal>,
+ just set <varname>USE_GETTEXT</varname> to <literal>yes</literal>,
+ and your port will grow the dependency on <package>devel/gettext</package>. The value of
+ <varname>USE_GETTEXT</varname> can also specify the required
+ version of the <literal>libintl</literal> library, the basic
+ part of <literal>gettext</literal>, but using this
+ feature is <emphasis>strongly discouraged</emphasis>:
+ Your port should work with just the current version of
+ <package>devel/gettext</package>.</para>
+
+ <para>A rather common case is a port using
+ <literal>gettext</literal> and <command>configure</command>.
+ Generally, GNU <command>configure</command> should be
+ able to locate <literal>gettext</literal> automatically.
+ If it ever fails to, hints at the location of
+ <literal>gettext</literal> can be passed in
+ <envar>CPPFLAGS</envar> and <envar>LDFLAGS</envar> as
+ follows:</para>
+
+ <programlisting>USE_GETTEXT= yes
+CPPFLAGS+= -I${LOCALBASE}/include
+LDFLAGS+= -L${LOCALBASE}/lib
+
+GNU_CONFIGURE= yes
+CONFIGURE_ENV= CPPFLAGS="${CPPFLAGS}" \
+ LDFLAGS="${LDFLAGS}"</programlisting>
+
+ <para>Of course, the code can be more compact if there are no
+ more flags to pass to <command>configure</command>:</para>
+
+ <programlisting>USE_GETTEXT= yes
+GNU_CONFIGURE= yes
+CONFIGURE_ENV= CPPFLAGS="-I${LOCALBASE}/include" \
+ LDFLAGS="-L${LOCALBASE}/lib"</programlisting>
+
+ </sect2>
+
+ <sect2>
+ <title>Optional usage</title>
+
+ <para>Some software products allow for disabling NLS,
+ e.g., through passing <option>--disable-nls</option> to
+ <command>configure</command>. In that case, your port
+ should use <literal>gettext</literal> conditionally,
+ depending on the status of <link linkend="knobs-without-nls"><varname>WITHOUT_NLS</varname></link>.
+ For ports of low to medium complexity, you can rely on the
+ following idiom:</para>
+
+ <programlisting>GNU_CONFIGURE= yes
+
+.if !defined(WITHOUT_NLS)
+USE_GETTEXT= yes
+PLIST_SUB+= NLS=""
+.else
+CONFIGURE_ARGS+= --disable-nls
+PLIST_SUB+= NLS="@comment "
+.endif</programlisting>
+
+ <para>The next item on your to-do list is to arrange so that
+ the message catalog files are included in the packing list
+ conditionally. The <filename>Makefile</filename> part of
+ this task is already provided by the idiom. It is explained
+ in the section on <link linkend="plist-sub">advanced
+ <filename>pkg-plist</filename> practices</link>. In a
+ nutshell, each occurrence of <literal>%%NLS%%</literal> in
+ <filename>pkg-plist</filename> will be replaced by
+ <quote><literal>@comment&nbsp;</literal></quote> if NLS is
+ disabled, or by a null string if NLS is enabled. Consequently,
+ the lines prefixed by <literal>%%NLS%%</literal> 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 <literal>%%NLS%%</literal> before each
+ path to a message catalog file in <filename>pkg-plist</filename>.
+ For example:</para>
+
+ <programlisting>%%NLS%%share/locale/fr/LC_MESSAGES/foobar.mo
+%%NLS%%share/locale/no/LC_MESSAGES/foobar.mo</programlisting>
+
+ <para>In high complexity cases, you may need to use more advanced
+ techniques than the recipe given here, such as <link linkend="plist-dynamic">dynamic packing list generation</link>.</para>
+ </sect2>
+
+ <sect2>
+ <title>Handling message catalog directories</title>
+
+ <para>There is a point to note about installing message catalog
+ files. The target directories for them, which reside under
+ <filename>LOCALBASE/share/locale</filename>,
+ should rarely be created and removed by your port. The
+ most popular languages have their respective directories
+ listed in <filename>/etc/mtree/BSD.local.dist</filename>;
+ that is, they are a part of the base system. The directories
+ for many other languages are governed by the <package>devel/gettext</package> port. You may want
+ to consult its <filename>pkg-plist</filename> and see whether
+ your port is going to install a message catalog file for a
+ unique language.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="using-perl">
+ <title>Using <literal>perl</literal></title>
+
+ <para>If <varname>MASTER_SITES</varname> is set to
+ <varname>MASTER_SITE_PERL_CPAN</varname>, then preferred value of
+ <varname>MASTER_SITE_SUBDIR</varname> is top-level hierarchy name.
+ For example, the recommend value for <literal>p5-Module-Name</literal>
+ is <literal>Module</literal>. The top-level hierarchy can be examined
+ at <link xlink:href="http://cpan.org/modules/by-module/">cpan.org</link>.
+ This keeps the port working when the author of the module
+ changes.</para>
+
+ <para>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 <varname>MASTER_SITE_SUBDIR</varname> is allowed.</para>
+
+ <para>All of the tunable knobs below accept both <literal>YES</literal>
+ and a version string, like <literal>5.8.0+</literal>. Using
+ <literal>YES</literal> means that the port can be used with all
+ of the supported <application>Perl</application> versions. If a port
+ only works with specific versions of <application>Perl</application>,
+ it can be indicated with a version string, specifying a minimal version
+ (e.g. <literal>5.7.3+</literal>), a maximal version (e.g.
+ <literal>5.8.0-</literal>) or an exact version (e.g.
+ <literal>5.8.3</literal>).</para>
+
+ <table frame="none">
+ <title>Variables for ports that use <literal>perl</literal></title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+
+ <entry>Means</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>USE_PERL5</varname></entry>
+
+ <entry>Says that the port uses <literal>perl 5</literal> to build and run.</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_PERL5_BUILD</varname></entry>
+
+ <entry>Says that the port uses <literal>perl 5</literal> to build.</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_PERL5_RUN</varname></entry>
+
+ <entry>Says that the port uses <literal>perl 5</literal> to run.</entry>
+ </row>
+
+ <row>
+ <entry><varname>PERL</varname></entry>
+
+ <entry>The full path of <literal>perl 5</literal>, either in the
+ system or installed from a port, but without the version
+ number. Use this if you need to replace
+ <quote><literal>#!</literal></quote>lines in scripts.</entry>
+ </row>
+
+ <row>
+ <entry><varname>PERL_CONFIGURE</varname></entry>
+
+ <entry>Configure using Perl's MakeMaker. It implies
+ <varname>USE_PERL5</varname>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>PERL_MODBUILD</varname></entry>
+
+ <entry>Configure, build and install using Module::Build. It
+ implies <varname>PERL_CONFIGURE</varname>.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Read only variables</entry>
+
+ <entry>Means</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>PERL_VERSION</varname></entry>
+
+ <entry>The full version of <literal>perl</literal> installed (e.g.,
+ <literal>5.00503</literal>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>PERL_VER</varname></entry>
+
+ <entry>The short version of <literal>perl</literal> installed (e.g.,
+ <literal>5.005</literal>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>PERL_LEVEL</varname></entry>
+
+ <entry>The installed <literal>perl</literal> version as an integer of the form <literal>MNNNPP</literal>
+ (e.g., <literal>500503</literal>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>PERL_ARCH</varname></entry>
+
+ <entry>Where <literal>perl</literal> stores architecture dependent libraries.
+ Defaults to <literal>${ARCH}-freebsd</literal>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>PERL_PORT</varname></entry>
+
+ <entry>Name of the <literal>perl</literal> port that is
+ installed (e.g., <literal>perl5</literal>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>SITE_PERL</varname></entry>
+
+ <entry>Directory name where site specific
+ <literal>perl</literal> packages go.
+ This value is added to PLIST_SUB.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>Perl 模組的 port,由於沒有正式的網站,所以
+ <filename>pkg-descr</filename> 內的 WWW 應該指向至
+ <systemitem>cpan.org</systemitem>。 比較好的 URL 格式是
+ <literal>http://search.cpan.org/dist/Module-Name/</literal>
+ (包括結尾的 / 斜線符號)。</para>
+ </note>
+
+ </sect1>
+
+ <sect1 xml:id="using-x11">
+ <title>Using X11</title>
+
+ <sect2 xml:id="x11-variables">
+ <title>X.Org components</title>
+
+ <para>The X11 implementation available in The Ports Collection is X.Org.
+ If your application depends on X components, set
+ <varname>USE_XORG</varname> to the list of required components.
+ Available components, at the time of writing, are:</para>
+
+ <para><literal>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</literal>.</para>
+
+ <para>Always up-to-date list can be found in
+ <filename>/usr/ports/Mk/bsd.xorg.mk</filename>.</para>
+
+ <para>The Mesa Project is an effort to provide free OpenGL
+ implementation. You can specify a dependency on various components
+ of this project with <varname>USE_GL</varname> variable.
+ Valid options are: <literal>glut, glu, glw, gl</literal> and
+ <literal>linux</literal>. For backwards compatibility, the value
+ of <literal>yes</literal> maps to <literal>glu</literal>.</para>
+
+ <example xml:id="use-xorg-example">
+ <title>USE_XORG example</title>
+ <programlisting>USE_XORG= xrender xft xkbfile xt xaw
+USE_GL= glu</programlisting>
+ </example>
+
+ <para>Many ports define <varname>USE_XLIB</varname>, 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.</para>
+
+ <table frame="none">
+ <title>Variables for ports that use X</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry><varname>USE_XLIB</varname></entry>
+
+ <entry>The port uses the X libraries. Deprecated - use a list of
+ X.Org components in <varname>USE_XORG</varname> variable
+ instead.</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_IMAKE</varname></entry>
+
+ <entry>會用到 <command>imake</command> 的 port。</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_X_PREFIX</varname></entry>
+
+ <entry>Deprecated. Today it is equivalent to
+ <varname>USE_XLIB</varname> and can be replaced by it
+ freely.</entry>
+ </row>
+
+ <row>
+ <entry><varname>XMKMF</varname></entry>
+
+ <entry>Set to the path of <command>xmkmf</command> if not in the
+ <envar>PATH</envar>. Defaults to <literal>xmkmf
+ -a</literal>.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none">
+ <title>Variables for depending on individual parts of X11</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry><varname>X_IMAKE_PORT</varname></entry>
+
+ <entry>Port providing <command>imake</command> and several
+ other utilities used to build X11.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_LIBRARIES_PORT</varname></entry>
+
+ <entry>Port providing X11 libraries.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_CLIENTS_PORT</varname></entry>
+
+ <entry>Port providing X clients.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_SERVER_PORT</varname></entry>
+
+ <entry>Port providing X server.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_FONTSERVER_PORT</varname></entry>
+
+ <entry>Port providing font server.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_PRINTSERVER_PORT</varname></entry>
+
+ <entry>Port providing print server.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_VFBSERVER_PORT</varname></entry>
+
+ <entry>Port providing virtual framebuffer server.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_NESTSERVER_PORT</varname></entry>
+
+ <entry>Port providing a nested X server.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_FONTS_ENCODINGS_PORT</varname></entry>
+
+ <entry>Port providing encodings for fonts.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_FONTS_MISC_PORT</varname></entry>
+
+ <entry>Port providing miscellaneous bitmap fonts.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_FONTS_100DPI_PORT</varname></entry>
+
+ <entry>Port providing 100dpi bitmap fonts.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_FONTS_75DPI_PORT</varname></entry>
+
+ <entry>Port providing 75dpi bitmap fonts.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_FONTS_CYRILLIC_PORT</varname></entry>
+
+ <entry>Port providing cyrillic bitmap fonts.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_FONTS_TTF_PORT</varname></entry>
+
+ <entry>Port providing &truetype; fonts.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_FONTS_TYPE1_PORT</varname></entry>
+
+ <entry>Port providing Type1 fonts.</entry>
+ </row>
+
+ <row>
+ <entry><varname>X_MANUALS_PORT</varname></entry>
+
+ <entry>Port providing developer oriented manual pages</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <example xml:id="using-x11-vars">
+ <title>Using some X11 related variables in port</title>
+ <programlisting># Use X11 libraries and depend on
+# font server as well as cyrillic fonts.
+RUN_DEPENDS= ${LOCALBASE}/bin/xfs:${X_FONTSERVER_PORT} \
+ ${LOCALBASE}/lib/X11/fonts/cyrillic/crox1c.pcf.gz:${X_FONTS_CYRILLIC_PORT}
+
+USE_XORG= yes</programlisting>
+ </example>
+
+ </sect2>
+
+ <sect2 xml:id="x11-motif">
+ <title>Ports that require Motif</title>
+
+ <para>If your port requires a Motif library, define
+ <varname>USE_MOTIF</varname> in the <filename>Makefile</filename>.
+ Default Motif implementation is
+ <package>x11-toolkits/open-motif</package>.
+ Users can choose
+ <package>x11-toolkits/lesstif</package> instead
+ by setting <varname>WANT_LESSTIF</varname> variable.</para>
+
+ <para>The <varname>MOTIFLIB</varname> variable will be set by
+ <filename>bsd.port.mk</filename> to reference the appropriate
+ Motif library. Please patch the source of your port to
+ use <literal>&dollar;{MOTIFLIB}</literal> wherever the Motif library is referenced in the original
+ <filename>Makefile</filename> or
+ <filename>Imakefile</filename>.</para>
+
+ <para>There are two common cases:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>If the port refers to the Motif library as
+ <literal>-lXm</literal> in its <filename>Makefile</filename> or
+ <filename>Imakefile</filename>, simply substitute
+ <literal>&dollar;{MOTIFLIB}</literal> for it.</para>
+ </listitem>
+
+ <listitem>
+ <para>If the port uses <literal>XmClientLibs</literal> in its
+ <filename>Imakefile</filename>, change it to
+ <literal>&dollar;{MOTIFLIB} &dollar;{XTOOLLIB}
+ &dollar;{XLIB}</literal>.</para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>Note that <varname>MOTIFLIB</varname> (usually) expands to
+ <literal>-L/usr/X11R6/lib -lXm</literal> or
+ <literal>/usr/X11R6/lib/libXm.a</literal>, so there is no need to
+ add <literal>-L</literal> or <literal>-l</literal> in front.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>X11 fonts</title>
+
+ <para>If your port installs fonts for the X Window System, put them in
+ <filename>LOCALBASE/lib/X11/fonts/local</filename>.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>Getting fake <envar>DISPLAY</envar> using Xvfb</title>
+
+ <para>Some applications require a working X11 display for compilation to
+ succeed. This pose a problem for machines which operates headless.
+ When the following variable is used, the build infrastructure will
+ start the virtual framebuffer
+ X server. The working <envar>DISPLAY</envar> is then passed
+ to the build.</para>
+
+ <programlisting>USE_DISPLAY= yes</programlisting>
+
+ </sect2>
+
+ <sect2 xml:id="desktop-entries">
+ <title>Desktop entries</title>
+
+ <para>可藉由設定
+ <varname>DESKTOP_ENTRIES</varname> 變數,以輕鬆設定 port 的 X 選單項目
+ (Desktop Entries,請參閱 <link xlink:href="http://standards.freedesktop.org/desktop-entry-spec/latest/">
+ Freedesktop standard</link>)。 這些項目會在相應的桌面環境如 GNOME
+ 或 KDE 的應用程式選單中出現。 <filename>.desktop</filename> 檔案
+ 將會被建立、安裝以及自動加入 <filename>pkg-plist</filename>
+ 中。語法為:</para>
+
+ <programlisting>DESKTOP_ENTRIES= "NAME" "COMMENT" "ICON" "COMMAND" "CATEGORY" StartupNotify</programlisting>
+
+ <para>可供使用的分類可參考 <link xlink:href="http://standards.freedesktop.org/menu-spec/latest/apa.html">
+ Freedesktop 網站</link>。 而 <varname>StartupNotify</varname>
+ 變數會決定程式,是否支援 startup noficication 的環境。
+ </para>
+
+ <para>範例:</para>
+
+ <programlisting>DESKTOP_ENTRIES= "ToME" "Roguelike game based on JRR Tolkien's work" \
+ "${DATADIR}/xtra/graf/tome-128.png" \
+ "tome -v -g" "Application;Game;RolePlaying" \
+ false</programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="using-gnome">
+ <title>Using GNOME</title>
+
+ <para>The FreeBSD/GNOME project uses its own set of variables
+ to define which GNOME components a
+ particular port uses. A
+ <link xlink:href="http://www.FreeBSD.org/gnome/docs/porting.html">comprehensive
+ list of these variables</link> exists within the FreeBSD/GNOME
+ project's homepage.</para>
+
+ </sect1>
+
+ <sect1 xml:id="using-kde">
+ <title>Using KDE</title>
+
+ <sect2 xml:id="kde-variables">
+ <title>Variable definitions</title>
+
+ <table frame="none">
+ <title>Variables for ports that use KDE</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry><varname>USE_KDELIBS_VER</varname></entry>
+
+ <entry>The port uses KDE libraries. It specifies the
+ major version of KDE to use and implies
+ <varname>USE_QT_VER</varname> of the appropriate
+ version. The only possible value is
+ <literal>3</literal>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_KDEBASE_VER</varname></entry>
+
+ <entry>The port uses KDE base. It specifies the major
+ version of KDE to use and implies
+ <varname>USE_QT_VER</varname> of the appropriate version.
+ The only possible value is <literal>3</literal>.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 xml:id="kde-qt">
+ <title>Ports that require Qt</title>
+
+ <table frame="none">
+ <title>Variables for ports that use Qt</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry><varname>USE_QT_VER</varname></entry>
+
+ <entry>The port uses the Qt toolkit. Possible values
+ are <literal>3</literal> and <literal>4</literal>;
+ each specify the major version of Qt to use. Appropriate
+ parameters are passed to <command>configure</command>
+ script and <command>make</command>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>QT_PREFIX</varname></entry>
+
+ <entry>Set to the path where Qt installed to (read-only
+ variable).</entry>
+ </row>
+
+ <row>
+ <entry><varname>MOC</varname></entry>
+
+ <entry>Set to the path of <command>moc</command>
+ (read-only variable). Default set according to
+ <varname>USE_QT_VER</varname> value.</entry>
+ </row>
+
+ <row>
+ <entry><varname>QTCPPFLAGS</varname></entry>
+
+ <entry>Additional compiler flags passed via
+ <varname>CONFIGURE_ENV</varname> for Qt toolkit.
+ Default set according to
+ <varname>USE_QT_VER</varname>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>QTCFGLIBS</varname></entry>
+
+ <entry>Additional libraries for linking passed via
+ <varname>CONFIGURE_ENV</varname> for Qt toolkit.
+ Default set according to
+ <varname>USE_QT_VER</varname>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>QTNONSTANDARD</varname></entry>
+
+ <entry>Suppress modification of
+ <varname>CONFIGURE_ENV</varname>,
+ <varname>CONFIGURE_ARGS</varname>, and
+ <varname>MAKE_ENV</varname>.</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none">
+ <title>Additional variables for ports that use Qt 4.x</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry><varname>QT_COMPONENTS</varname></entry>
+
+ <entry>Specify tool and library dependencies for Qt4.
+ See below for details.</entry>
+ </row>
+
+ <row>
+ <entry><varname>UIC</varname></entry>
+
+ <entry>Set to the path of <command>uic</command> (read-only
+ variable). Default set according to
+ <varname>USE_QT_VER</varname> value.</entry>
+ </row>
+
+ <row>
+ <entry><varname>QMAKE</varname></entry>
+
+ <entry>Set to the path of <command>qmake</command>
+ (read-only variable). Default set according to
+ <varname>USE_QT_VER</varname> value.</entry>
+ </row>
+
+ <row>
+ <entry><varname>QMAKESPEC</varname></entry>
+
+ <entry>Set to the path of configuration file for
+ <command>qmake</command> (read-only variable). Default
+ set according to <varname>USE_QT_VER</varname>
+ value.</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>When <varname>USE_QT_VER</varname> is set, some useful
+ settings are passed to <command>configure</command> script:</para>
+
+ <programlisting>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}"</programlisting>
+
+ <para>If <varname>USE_QT_VER</varname> is set to <literal>4</literal>,
+ the following settings are also deployed:</para>
+
+ <programlisting>CONFIGURE_ENV+= UIC="${UIC}" QMAKE="${QMAKE}" QMAKESPEC="${QMAKESPEC}"
+MAKE_ENV+= QMAKESPEC="${QMAKESPEC}"</programlisting>
+
+ </sect2>
+
+ <sect2 xml:id="qt4-components">
+ <title>Component selection (Qt 4.x only)</title>
+
+ <para>When <varname>USE_QT_VER</varname> is set to 4, individual
+ Qt4 tool and library dependencies can be specified in the
+ <varname>QT_COMPONENTS</varname> variable. Every component
+ can be suffixed by either <literal>_build</literal> or <literal>_run</literal>,
+ 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 <literal>_build</literal> suffix and plugin components
+ should be specified with the <literal>_run</literal> suffix. The most commonly
+ used components are listed below (all available components are
+ listed in <varname>_QT_COMPONENTS_ALL</varname> in
+ <filename>/usr/ports/Mk/bsd.qt.mk</filename>):</para>
+
+ <table frame="none">
+ <title>Available Qt4 library components</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>corelib</literal></entry>
+ <entry>core library (can be omitted unless the port
+ uses nothing but <literal>corelib</literal>)</entry>
+ </row>
+
+ <row>
+ <entry><literal>gui</literal></entry>
+ <entry>graphical user interface library</entry>
+ </row>
+
+ <row>
+ <entry><literal>network</literal></entry>
+ <entry>network library</entry>
+ </row>
+
+ <row>
+ <entry><literal>opengl</literal></entry>
+ <entry>OpenGL library</entry>
+ </row>
+
+ <row>
+ <entry><literal>qt3support</literal></entry>
+ <entry>Qt3 compatibility library</entry>
+ </row>
+
+ <row>
+ <entry><literal>qtestlib</literal></entry>
+ <entry>unit testing library</entry>
+ </row>
+
+ <row>
+ <entry><literal>script</literal></entry>
+ <entry>script library</entry>
+ </row>
+
+ <row>
+ <entry><literal>sql</literal></entry>
+ <entry>SQL library</entry>
+ </row>
+
+ <row>
+ <entry><literal>xml</literal></entry>
+ <entry>XML library</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>You can determine which libraries the application depends
+ on, by running <command>ldd</command> on the main executable
+ after a successful compilation.</para>
+
+ <table frame="none">
+ <title>Available Qt4 tool components</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>moc</literal></entry>
+ <entry>meta object compiler (needed for almost
+ every Qt application at buildtime)</entry>
+ </row>
+
+ <row>
+ <entry><literal>qmake</literal></entry>
+ <entry>Makefile generator / build utility</entry>
+ </row>
+
+ <row>
+ <entry><literal>rcc</literal></entry>
+ <entry>resource compiler (need if the application comes
+ with <filename>*.rc</filename> or <filename>*.qrc</filename>
+ files)</entry>
+ </row>
+
+ <row>
+ <entry><literal>uic</literal></entry>
+ <entry>user interface compiler (needed if the application
+ comes with <filename>*.ui</filename> files created by Qt Designer
+ - in practice, every Qt application with a GUI)</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none">
+ <title>Available Qt4 plugin components</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>iconengines</literal></entry>
+ <entry>SVG icon engine plugin (if the application
+ ships SVG icons)</entry>
+ </row>
+
+ <row>
+ <entry><literal>imageformats</literal></entry>
+ <entry>imageformat plugins for GIF, JPEG, MNG and
+ SVG (if the application ships image files)</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <example xml:id="qt4-components-example">
+ <title>Selecting Qt4 components</title>
+
+ <para>In 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 <literal>_build</literal> suffix:</para>
+
+ <programlisting>USE_QT_VER= 4
+QT_COMPONENTS= gui moc_build qmake_build rcc_build uic_build</programlisting>
+ </example>
+ </sect2>
+
+ <sect2 xml:id="qt-additional">
+ <title>Additional considerations</title>
+
+ <para>If the application does not provide a
+ <filename>configure</filename> file but a <filename>.pro</filename>
+ file, you can use the following:</para>
+
+ <programlisting>HAS_CONFIGURE= yes
+
+do-configure:
+ @cd ${WRKSRC} &amp;&amp; ${SETENV} ${CONFIGURE_ENV} \
+ ${QMAKE} -unix PREFIX=${PREFIX} texmaker.pro</programlisting>
+
+ <para>Note the similarity to the <command>qmake</command> line
+ from the provided <filename>BUILD.sh</filename> script. Passing
+ <varname>CONFIGURE_ENV</varname> ensures <command>qmake</command>
+ will see the <varname>QMAKESPEC</varname> variable, without which
+ it cannot work. <command>qmake</command> generates standard
+ Makefiles, so it is not necessary to write our own
+ <buildtarget>build</buildtarget> target.</para>
+
+ <para>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:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>Missing additional includepaths.</emphasis>
+ Many applications come with system tray icon support, but
+ neglect to look for includes and/or libraries in the X11
+ directories. You can tell <command>qmake</command> to
+ add directories to the include and library searchpaths
+ via the commandline, for example:</para>
+
+ <programlisting>${QMAKE} -unix PREFIX=${PREFIX} INCLUDEPATH+=${LOCALBASE}/include \
+ LIBS+=-L${LOCALBASE}/lib sillyapp.pro</programlisting>
+
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Bogus installation paths.</emphasis>
+ Sometimes data such as icons or .desktop files are by
+ default installed into directories which aren't scanned by
+ XDG-compatible applications. <package>editors/texmaker</package>
+ is an example for this - look at <filename>patch-texmaker.pro</filename>
+ in the <filename>files</filename> directory of that port
+ for a template on how to remedy this directly in the Qmake
+ project file.</para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="using-java">
+ <title>Using Java</title>
+
+ <sect2 xml:id="java-variables">
+ <title>Variable definitions</title>
+
+ <para>If your port needs a Java&trade; Development Kit (JDK) to
+ either build, run or even extract the distfile, then it should
+ define <varname>USE_JAVA</varname>.</para>
+
+ <para>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 <package>java/jdk15</package>.</para>
+
+ <table frame="none">
+ <title>Variables that may be set by ports that use Java</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+ <entry>Means</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><varname>USE_JAVA</varname></entry>
+ <entry>Should be defined for the remaining variables to have any
+ effect.</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_VERSION</varname></entry>
+ <entry>List of space-separated suitable Java versions for
+ the port. An optional <literal>"+"</literal> allows you to
+ specify a range of versions (allowed values:
+ <literal>1.1[+] 1.2[+] 1.3[+] 1.4[+]</literal>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_OS</varname></entry>
+ <entry>List of space-separated suitable JDK port operating
+ systems for the port (allowed values: <literal>native
+ linux</literal>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_VENDOR</varname></entry>
+ <entry>List of space-separated suitable JDK port vendors for
+ the port (allowed values: <literal>freebsd bsdjava sun ibm
+ blackdown</literal>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_BUILD</varname></entry>
+ <entry>When set, it means that the selected JDK port should
+ be added to the build dependencies of the port.</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_RUN</varname></entry>
+ <entry>When set, it means that the selected JDK port should
+ be added to the run dependencies of the port.</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_EXTRACT</varname></entry>
+ <entry>When set, it means that the selected JDK port should
+ be added to the extract dependencies of the port.</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_JIKES</varname></entry>
+ <entry>Whether the port should or should not use the
+ <command>jikes</command> bytecode compiler to build. When
+ no value is set for this variable, the port will use
+ <command>jikes</command> to build if available. You may
+ also explicitly forbid or enforce the use of
+ <command>jikes</command> (by setting <literal>'no'</literal>
+ or <literal>'yes'</literal>). In the later case, <package>devel/jikes</package> will be added to build
+ dependencies of the port. In any case that <command>jikes</command>
+ is actually used in place of <command>javac</command>, then the
+ <varname>HAVE_JIKES</varname> variable is defined by
+ <filename>bsd.java.mk</filename>.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>Below is the list of all settings a port will receive after
+ setting <varname>USE_JAVA</varname>:</para>
+
+ <table frame="none">
+ <title>Variables provided to ports that use Java</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+ <entry>Value</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><varname>JAVA_PORT</varname></entry>
+ <entry>The name of the JDK port (e.g.
+ <literal>'java/jdk14'</literal>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_PORT_VERSION</varname></entry>
+ <entry>The full version of the JDK port (e.g.
+ <literal>'1.4.2'</literal>). If you only need the first
+ two digits of this version number, use
+ <varname>${JAVA_PORT_VERSION:C/^([0-9])\.([0-9])(.*)$/\1.\2/}</varname>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_PORT_OS</varname></entry>
+ <entry>The operating system used by the JDK port (e.g.
+ <literal>'linux'</literal>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_PORT_VENDOR</varname></entry>
+ <entry>The vendor of the JDK port (e.g.
+ <literal>'sun'</literal>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_PORT_OS_DESCRIPTION</varname></entry>
+ <entry>Description of the operating system used by the JDK port
+ (e.g. <literal>'Linux'</literal>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_PORT_VENDOR_DESCRIPTION</varname></entry>
+ <entry>Description of the vendor of the JDK port (e.g.
+ <literal>'FreeBSD Foundation'</literal>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_HOME</varname></entry>
+ <entry>Path to the installation directory of the JDK (e.g.
+ <filename>'/usr/local/jdk1.3.1'</filename>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVAC</varname></entry>
+ <entry>Path to the Java compiler to use (e.g.
+ <filename>'/usr/local/jdk1.1.8/bin/javac'</filename> or
+ <filename>'/usr/local/bin/jikes'</filename>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAR</varname></entry>
+ <entry>Path to the <command>jar</command> tool to use (e.g.
+ <filename>'/usr/local/jdk1.2.2/bin/jar'</filename> or
+ <filename>'/usr/local/bin/fastjar'</filename>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>APPLETVIEWER</varname></entry>
+ <entry>Path to the <command>appletviewer</command> utility (e.g.
+ <filename>'/usr/local/linux-jdk1.2.2/bin/appletviewer'</filename>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA</varname></entry>
+ <entry>Path to the <command>java</command> executable. Use
+ this for executing Java programs (e.g.
+ <filename>'/usr/local/jdk1.3.1/bin/java'</filename>).</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVADOC</varname></entry>
+ <entry>Path to the <command>javadoc</command> utility
+ program.</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVAH</varname></entry>
+ <entry>Path to the <command>javah</command> program.</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVAP</varname></entry>
+ <entry>Path to the <command>javap</command> program.</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_KEYTOOL</varname></entry>
+ <entry>Path to the <command>keytool</command> utility program.
+ This variable is available only if the JDK is Java 1.2 or
+ higher.</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_N2A</varname></entry>
+ <entry>Path to the <command>native2ascii</command> tool.</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_POLICYTOOL</varname></entry>
+ <entry>Path to the <command>policytool</command> program.
+ This variable is available only if the JDK is Java 1.2 or
+ higher.</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_SERIALVER</varname></entry>
+ <entry>Path to the <command>serialver</command> utility
+ program.</entry>
+ </row>
+
+ <row>
+ <entry><varname>RMIC</varname></entry>
+ <entry>Path to the RMI stub/skeleton generator,
+ <command>rmic</command>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>RMIREGISTRY</varname></entry>
+ <entry>Path to the RMI registry program,
+ <command>rmiregistry</command>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>RMID</varname></entry>
+ <entry>Path to the RMI daemon program <command>rmid</command>.
+ This variable is only available if the JDK is Java 1.2
+ or higher.</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVA_CLASSES</varname></entry>
+ <entry>Path to the archive that contains the JDK class
+ files. On JDK 1.2 or later, this is
+ <filename>${JAVA_HOME}/jre/lib/rt.jar</filename>. Earlier
+ JDKs used
+ <filename>${JAVA_HOME}/lib/classes.zip</filename>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>HAVE_JIKES</varname></entry>
+ <entry>Defined whenever <command>jikes</command> is used by
+ the port (see <varname>USE_JIKES</varname> above).</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>You may use the <literal>java-debug</literal> make target
+ to get information for debugging your port. It will display the
+ value of many of the forecited variables.</para>
+
+ <para>Additionally, the following constants are defined so all
+ Java ports may be installed in a consistent way:</para>
+
+ <table frame="none">
+ <title>Constants defined for ports that use Java</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Constant</entry>
+ <entry>Value</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><varname>JAVASHAREDIR</varname></entry>
+ <entry>The base directory for everything related to Java.
+ Default: <filename>${PREFIX}/share/java</filename>.
+ </entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVAJARDIR</varname></entry>
+ <entry>The directory where JAR files should be installed.
+ Default:
+ <filename>${JAVASHAREDIR}/classes</filename>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>JAVALIBDIR</varname></entry>
+ <entry>The directory where JAR files installed by other
+ ports are located. Default:
+ <filename>${LOCALBASE}/share/java/classes</filename>.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>The related entries are defined in both
+ <varname>PLIST_SUB</varname> (documented in
+ <xref linkend="plist-sub"/>) and
+ <varname>SUB_LIST</varname>.</para>
+
+ </sect2>
+
+ <sect2 xml:id="java-building-with-ant">
+ <title>Building with Ant</title>
+
+ <para>When the port is to be built using Apache Ant, it has to
+ define <varname>USE_ANT</varname>. Ant is thus considered to be
+ the sub-make command. When no <literal>do-build</literal> target
+ is defined by the port, a default one will be set that simply
+ runs Ant according to <varname>MAKE_ENV</varname>,
+ <varname>MAKE_ARGS</varname> and <varname>ALL_TARGETS</varname>.
+ This is similar to the <varname>USE_GMAKE</varname> mechanism,
+ which is documented in <xref linkend="building"/>.</para>
+
+ <para>If <command>jikes</command> is used in place of
+ <command>javac</command> (see <varname>USE_JIKES</varname> in
+ <xref linkend="java-variables"/>), then Ant will automatically
+ use it to build the port.</para>
+
+ </sect2>
+
+ <sect2 xml:id="java-best-practices">
+ <title>Best practices</title>
+
+ <para>When porting a Java library, your port should install the
+ JAR file(s) in <filename>${JAVAJARDIR}</filename>, and everything
+ else under <filename>${JAVASHAREDIR}/${PORTNAME}</filename>
+ (except for the documentation, see below). In order to reduce
+ the packing file size, you may reference the JAR file(s) directly
+ in the <filename>Makefile</filename>. Just use the following
+ statement (where <filename>myport.jar</filename> is the name
+ of the JAR file installed as part of the port):</para>
+
+ <programlisting>PLIST_FILES+= %%JAVAJARDIR%%/myport.jar</programlisting>
+
+ <para>When porting a Java application, the port usually installs
+ everything under a single directory (including its JAR
+ dependencies). The use of
+ <filename>${JAVASHAREDIR}/${PORTNAME}</filename> 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 <filename>${JAVAJARDIR}</filename>).</para>
+
+ <para>Regardless of the type of your port (library or application),
+ the additional documentation should be installed in the
+ <link linkend="install-documentation">same location</link> 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
+ (<filename>pkg-plist</filename>). This is one reason why
+ porters are strongly encouraged to use the
+ <varname>PORTDOCS</varname> macro. Moreover, even if you can
+ predict the set of files that will be generated by
+ <command>javadoc</command>, the size of the resulting
+ <filename>pkg-plist</filename> advocates for the use of
+ <varname>PORTDOCS</varname>.</para>
+
+ <para>The default value for <varname>DATADIR</varname> is
+ <filename>${PREFIX}/share/${PORTNAME}</filename>. It is a good
+ idea to override <varname>DATADIR</varname> to
+ <filename>${JAVASHAREDIR}/${PORTNAME}</filename> for Java ports.
+ Indeed, <varname>DATADIR</varname> is automatically added to
+ <varname>PLIST_SUB</varname> (documented in <xref linkend="plist-sub"/>) so you may use
+ <literal>%%DATADIR%%</literal> directly in
+ <filename>pkg-plist</filename>.</para>
+
+ <para>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 <link xlink:href="http://www.freebsd.org/java/">&os; Java Project</link>
+ encourage porters to have their ports built from source whenever
+ it is a trivial task.</para>
+
+ <para>All the features that have been presented in this section
+ are implemented in <filename>bsd.java.mk</filename>. If you
+ ever think that your port needs more sophisticated Java support,
+ please first have a look at the <link xlink:href="http://www.freebsd.org/cgi/cvsweb.cgi/ports/Mk/bsd.java.mk">
+ bsd.java.mk CVS log</link> 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;.</para>
+
+ <para>Although there is a <literal>java</literal> category for
+ PRs, it refers to the JDK porting effort from the &os; Java
+ project. Therefore, you should submit your Java port in the
+ <literal>ports</literal> category as for any other port, unless
+ the issue you are trying to resolve is related to either a JDK
+ implementation or <filename>bsd.java.mk</filename>.</para>
+
+ <para>Similarly, there is a defined policy regarding the
+ <varname>CATEGORIES</varname> of a Java port, which is detailed
+ in <xref linkend="makefile-categories"/>.</para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="using-php">
+ <title>Web applications, Apache and PHP</title>
+
+ <sect2 xml:id="using-apache">
+ <title>Apache</title>
+
+ <table frame="none">
+ <title>Variables for ports that use Apache</title>
+
+ <tgroup cols="2">
+ <tbody>
+
+ <row>
+ <entry><varname>USE_APACHE</varname></entry>
+
+ <entry>The port requires Apache. Possible values:
+ <literal>yes</literal> (gets any version),
+ <literal>1.3</literal>, <literal>2.0</literal>,
+ <literal>2.2</literal>, <literal>2.0+</literal>,
+ etc. Default dependency is on version
+ <literal>1.3</literal>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>WITH_APACHE2</varname></entry>
+
+ <entry>The 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.</entry>
+ </row>
+
+ <row>
+ <entry><varname>APXS</varname></entry>
+
+ <entry>Full path to the <command>apxs</command> binary.
+ Can be overriden in your port.</entry>
+ </row>
+
+ <row>
+ <entry><varname>HTTPD</varname></entry>
+
+ <entry>Full path to the <command>httpd</command> binary.
+ Can be overriden in your port.</entry>
+ </row>
+
+ <row>
+ <entry><varname>APACHE_VERSION</varname></entry>
+
+ <entry>The version of present Apache installation (read-only
+ variable). This variable is only available after inclusion
+ of <filename>bsd.port.pre.mk</filename>. Possible values:
+ <literal>13</literal>, <literal>20</literal>,
+ <literal>22</literal>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>APACHEMODDIR</varname></entry>
+
+ <entry>Directory for Apache modules. This variable is
+ automatically expanded in pkg-plist.</entry>
+ </row>
+
+ <row>
+ <entry><varname>APACHEINCLUDEDIR</varname></entry>
+
+ <entry>Directory for Apache headers. This variable is
+ automatically expanded in pkg-plist.</entry>
+ </row>
+
+ <row>
+ <entry><varname>APACHEETCDIR</varname></entry>
+
+ <entry>Directory for Apache configuration files. This
+ variable is automatically expanded in pkg-plist.</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="none">
+ <title>port Apache 模組時好用的變數</title>
+
+ <tgroup cols="2">
+ <tbody>
+
+ <row>
+ <entry><varname>MODULENAME</varname></entry>
+
+ <entry>模組名稱。 預設值為
+ <varname>PORTNAME</varname>. 範例:
+ <literal>mod_hello</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>SHORTMODNAME</varname></entry>
+
+ <entry>簡化的模組名稱。 自動地由變數
+ <varname>MODULENAME</varname> 產生,不過可以覆蓋它。
+ 範例: <literal>hello</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>AP_FAST_BUILD</varname></entry>
+
+ <entry>使用 <command>apxs</command>
+ 來編譯及安裝這個模組。</entry>
+ </row>
+
+ <row>
+ <entry><varname>AP_GENPLIST</varname></entry>
+
+ <entry>同樣地,也是自動產生
+ <filename>pkg-plist</filename>。</entry>
+ </row>
+
+ <row>
+ <entry><varname>AP_INC</varname></entry>
+
+ <entry>在編譯時間加入一個目錄到標頭檔搜尋路徑。</entry>
+ </row>
+
+ <row>
+ <entry><varname>AP_LIB</varname></entry>
+
+ <entry>在編譯時間加入一個目錄到函式庫搜尋路徑。</entry>
+ </row>
+
+ <row>
+ <entry><varname>AP_EXTRAS</varname></entry>
+
+ <entry>傳給
+ <command>apxs</command> 額外的 flags。</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 xml:id="web-apps">
+ <title>Web 應用程式</title>
+
+ <para>Web 應用程式應該安裝到
+ <filename>PREFIX/www/appname</filename>
+ 。 For your convenience, this path is available both in
+ <filename>Makefile</filename> and in <filename>pkg-plist</filename>
+ as <varname>WWWDIR</varname>, and the path relative to
+ <varname>PREFIX</varname> is available in
+ <filename>Makefile</filename> as
+ <varname>WWWDIR_REL</varname>.</para>
+
+ <para>The user and group of web server process are available as
+ <varname>WWWOWN</varname> and <varname>WWWGRP</varname>, in case you
+ need to change the ownership of some files. The default values of
+ both are <literal>www</literal>. If you want different values for
+ your port, use <literal>WWWOWN?= myuser</literal> notation, to allow
+ user to override it easily.</para>
+
+ <para>請別過於相依 Apache,除非這些程式有明確需要,而得相依 Apache
+ 。也許有些使用者,會想在其他非 Apache 的 Web 伺服器上執行這些網頁程式。</para>
+
+ </sect2>
+
+ <sect2 xml:id="php-variables">
+ <title>PHP</title>
+
+ <table frame="none">
+ <title>Variables for ports that use PHP</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry><varname>USE_PHP</varname></entry>
+
+ <entry>The port requires PHP. The value <literal>yes</literal>
+ adds a dependency on PHP. The list of required PHP extensions
+ can be specified instead. Example: <literal>pcre xml
+ gettext</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>DEFAULT_PHP_VER</varname></entry>
+
+ <entry>Selects which major version of PHP will be installed as
+ a dependency when no PHP is installed yet. Default is
+ <literal>4</literal>. Possible values: <literal>4</literal>,
+ <literal>5</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>IGNORE_WITH_PHP</varname></entry>
+
+ <entry>The port does not work with PHP of the given version.
+ Possible values: <literal>4</literal>,
+ <literal>5</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_PHPIZE</varname></entry>
+
+ <entry>The port will be built as a PHP extension.</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_PHPEXT</varname></entry>
+
+ <entry>The port will be treated as a PHP extension, including
+ installation and registration in the extension registry.</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_PHP_BUILD</varname></entry>
+
+ <entry>Set PHP as a build dependency.</entry>
+ </row>
+
+ <row>
+ <entry><varname>WANT_PHP_CLI</varname></entry>
+
+ <entry>Want the CLI (command line) version of PHP.</entry>
+ </row>
+
+ <row>
+ <entry><varname>WANT_PHP_CGI</varname></entry>
+
+ <entry>Want the CGI version of PHP.</entry>
+ </row>
+
+ <row>
+ <entry><varname>WANT_PHP_MOD</varname></entry>
+
+ <entry>Want the Apache module version of PHP.</entry>
+ </row>
+
+ <row>
+ <entry><varname>WANT_PHP_SCR</varname></entry>
+
+ <entry>Want the CLI or the CGI version of PHP.</entry>
+ </row>
+
+ <row>
+ <entry><varname>WANT_PHP_WEB</varname></entry>
+
+ <entry>Want the Apache module or the CGI version of PHP.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2>
+ <title>PEAR modules</title>
+
+ <para>Porting PEAR modules is a very simple process.</para>
+
+ <para>Use the variables <varname>FILES</varname>,
+ <varname>TESTS</varname>, <varname>DATA</varname>,
+ <varname>SQLS</varname>, <varname>SCRIPTFILES</varname>,
+ <varname>DOCS</varname> and <varname>EXAMPLES</varname> to list the
+ files you want to install. All listed files will be automatically
+ installed into the appropriate locations and added to
+ <filename>pkg-plist</filename>.</para>
+
+ <para>Include
+ <filename>&dollar;{PORTSDIR}/devel/pear/bsd.pear.mk</filename>
+ on the last line of the <filename>Makefile</filename>.</para>
+
+ <example xml:id="pear-makefile">
+ <title>Example Makefile for PEAR class</title>
+ <programlisting>PORTNAME= 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 &lt;bsd.port.pre.mk&gt;
+.include "&dollar;{PORTSDIR}/devel/pear/bsd.pear.mk"
+.include &lt;bsd.port.post.mk&gt;</programlisting>
+
+ </example>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="using-python">
+ <title>Using Python</title>
+
+ <para>The Ports Collection supports parallel installation of multiple
+ Python versions. Ports should make sure to use a correct
+ <command>python</command> interpreter, according to the user-settable
+ <varname>PYTHON_VERSION</varname> variable. Most prominently, this
+ means replacing the path to <command>python</command> executable in
+ scripts with the value of <varname>PYTHON_CMD</varname>
+ variable.</para>
+
+ <para>Ports that install files under <varname>PYTHON_SITELIBDIR</varname>
+ should use the <literal>pyXY-</literal> package name prefix, so their
+ package name embeds the version of Python they are installed
+ into.</para>
+
+ <programlisting>PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX}</programlisting>
+
+ <table frame="none">
+ <title>Most useful variables for ports that use Python</title>
+
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry><varname>USE_PYTHON</varname></entry>
+
+ <entry>The port needs Python. Minimal required version can be
+ specified with values such as <literal>2.3+</literal>.
+ Version ranges can also be specified, by separating two version
+ numbers with a dash, e.g.: <literal>2.1-2.3</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_PYDISTUTILS</varname></entry>
+
+ <entry>Use Python distutils for configuring, compiling and
+ installing. This is required when the port comes with
+ <filename>setup.py</filename>. This overrides the
+ <buildtarget>do-build</buildtarget> and
+ <buildtarget>do-install</buildtarget> targets
+ and may also override <buildtarget>do-configure</buildtarget> if
+ <varname>GNU_CONFIGURE</varname> is not defined.</entry>
+ </row>
+
+ <row>
+ <entry><varname>PYTHON_PKGNAMEPREFIX</varname></entry>
+
+ <entry>Used as a <varname>PKGNAMEPREFIX</varname> to distinguish
+ packages for different Python versions.
+ Example: <literal>py24-</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>PYTHON_SITELIBDIR</varname></entry>
+
+ <entry>Location of the site-packages tree, that contains
+ installation path of Python (usually <varname>LOCALBASE</varname>).
+ The <varname>PYTHON_SITELIBDIR</varname> variable can be very
+ useful when installing Python modules.</entry>
+ </row>
+
+ <row>
+ <entry><varname>PYTHONPREFIX_SITELIBDIR</varname></entry>
+
+ <entry>The PREFIX-clean variant of PYTHON_SITELIBDIR.
+ Always use
+ <literal>%%PYTHON_SITELIBDIR%%</literal> in
+ <filename>pkg-plist</filename> when possible. The default value of
+ <literal>%%PYTHON_SITELIBDIR%%</literal> is
+ <literal>lib/python%%PYTHON_VERSION%%/site-packages</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>PYTHON_CMD</varname></entry>
+
+ <entry>Python interpreter command line, including version
+ number.</entry>
+ </row>
+
+ <row>
+ <entry><varname>PYNUMERIC</varname></entry>
+
+ <entry>Dependency line for numeric extension.</entry>
+ </row>
+
+ <row>
+ <entry><varname>PYNUMPY</varname></entry>
+ <entry>Dependency line for the new numeric extension, numpy.
+ (PYNUMERIC is deprecated by upstream vendor).</entry>
+ </row>
+
+ <row>
+ <entry><varname>PYXML</varname></entry>
+
+ <entry>Dependency line for XML extension (not needed for
+ Python 2.0 and higher as it is also in base distribution).</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_TWISTED</varname></entry>
+
+ <entry>Add dependency on twistedCore. The list of required
+ components can be specified as a value of this
+ variable. Example: <literal>web lore pair
+ flow</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_ZOPE</varname></entry>
+
+ <entry>Add dependency on Zope, a web application platform.
+ Change Python dependency to Python 2.3. Set
+ <varname>ZOPEBASEDIR</varname> containing a directory with
+ Zope installation.</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>A complete list of available variables can be found in
+ <filename>/usr/ports/Mk/bsd.python.mk</filename>.</para>
+
+ </sect1>
+
+ <sect1 xml:id="using-emacs">
+ <title>Using Emacs</title>
+
+ <para>This section is yet to be written.</para>
+ </sect1>
+
+ <sect1 xml:id="using-ruby">
+ <title>Using Ruby</title>
+
+ <table frame="none">
+ <title>Useful variables for ports that use Ruby</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><varname>USE_RUBY</varname></entry>
+
+ <entry>The port requires Ruby.</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_RUBY_EXTCONF</varname></entry>
+
+ <entry>The port uses <filename>extconf.rb</filename> to
+ configure.</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_RUBY_SETUP</varname></entry>
+
+ <entry>The port uses <filename>setup.rb</filename> to
+ configure.</entry>
+ </row>
+
+ <row>
+ <entry><varname>RUBY_SETUP</varname></entry>
+
+ <entry>Set to the alternative name of
+ <filename>setup.rb</filename>. Common value is
+ <filename>install.rb</filename>.</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>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
+ <filename>pkg-plist</filename> as much as possible. These variables
+ should not be redefined in the port.</para>
+
+ <table frame="none">
+ <title>Selected read-only variables for ports that use Ruby</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+ <entry>Description</entry>
+ <entry>Example value</entry>
+ </row>
+ </thead>
+ <tbody>
+
+ <row>
+ <entry><varname>RUBY_PKGNAMEPREFIX</varname></entry>
+
+ <entry>Used as a <varname>PKGNAMEPREFIX</varname> to distinguish
+ packages for different Ruby versions.</entry>
+
+ <entry><literal>ruby18-</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>RUBY_VERSION</varname></entry>
+
+ <entry>Full version of Ruby in the form of
+ <literal>x.y.z</literal>.</entry>
+
+ <entry><literal>1.8.2</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>RUBY_SITELIBDIR</varname></entry>
+
+ <entry>Architecture independent libraries installation
+ path.</entry>
+
+ <entry><literal>/usr/local/lib/ruby/site_ruby/1.8</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>RUBY_SITEARCHLIBDIR</varname></entry>
+
+ <entry>Architecture dependent libraries installation
+ path.</entry>
+
+ <entry><literal>/usr/local/lib/ruby/site_ruby/1.8/amd64-freebsd6</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>RUBY_MODDOCDIR</varname></entry>
+
+ <entry>Module documentation installation path.</entry>
+
+ <entry><literal>/usr/local/share/doc/ruby18/patsy</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>RUBY_MODEXAMPLESDIR</varname></entry>
+
+ <entry>Module examples installation path.</entry>
+
+ <entry><literal>/usr/local/share/examples/ruby18/patsy</literal></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>A complete list of available variables can be found in
+ <filename>/usr/ports/Mk/bsd.ruby.mk</filename>.</para>
+
+ </sect1>
+
+ <sect1 xml:id="using-sdl">
+ <title>Using SDL</title>
+
+ <para>The <varname>USE_SDL</varname> variable is used to autoconfigure
+ the dependencies for ports which use an SDL based library like
+ <package>devel/sdl12</package> and
+ <package>x11-toolkits/sdl_gui</package>.</para>
+
+ <para>The following SDL libraries are recognized at the moment:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>sdl: <package>devel/sdl12</package></para>
+ </listitem>
+
+ <listitem>
+ <para>gfx: <package>graphics/sdl_gfx</package></para>
+ </listitem>
+
+ <listitem>
+ <para>gui: <package>x11-toolkits/sdl_gui</package></para>
+ </listitem>
+
+ <listitem>
+ <para>image: <package>graphics/sdl_image</package></para>
+ </listitem>
+
+ <listitem>
+ <para>ldbad: <package>devel/sdl_ldbad</package></para>
+ </listitem>
+
+ <listitem>
+ <para>mixer: <package>audio/sdl_mixer</package></para>
+ </listitem>
+
+ <listitem>
+ <para>mm: <package>devel/sdlmm</package></para>
+ </listitem>
+
+ <listitem>
+ <para>net: <package>net/sdl_net</package></para>
+ </listitem>
+
+ <listitem>
+ <para>sound: <package>audio/sdl_sound</package></para>
+ </listitem>
+
+ <listitem>
+ <para>ttf: <package>graphics/sdl_ttf</package></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Therefore, if a port has a dependency on
+ <package>net/sdl_net</package> and
+ <package>audio/sdl_mixer</package>,
+ the syntax will be:</para>
+
+ <programlisting>USE_SDL= net mixer</programlisting>
+
+ <para>The dependency <package>devel/sdl12</package>,
+ which is required by <package>net/sdl_net</package> and
+ <package>audio/sdl_mixer</package>, is automatically
+ added as well.</para>
+
+ <para>If you use <varname>USE_SDL</varname>, it will automatically:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Add a dependency on <application>sdl12-config</application> to
+ <varname>BUILD_DEPENDS</varname></para>
+ </listitem>
+
+ <listitem>
+ <para>Add the variable <varname>SDL_CONFIG</varname> to
+ <varname>CONFIGURE_ENV</varname></para>
+ </listitem>
+
+ <listitem>
+ <para>Add the dependencies of the selected libraries to the
+ <varname>LIB_DEPENDS</varname></para>
+ </listitem>
+ </itemizedlist>
+
+ <para>To check whether an SDL library is available, you can do it
+ with the <varname>WANT_SDL</varname> variable:</para>
+
+ <programlisting>WANT_SDL=yes
+
+.include &lt;bsd.port.pre.mk&gt;
+
+.if ${HAVE_SDL:Mmixer}!=""
+USE_SDL+= mixer
+.endif
+
+.include &lt;bsd.port.post.mk&gt;</programlisting>
+
+ </sect1>
+
+ <sect1 xml:id="using-wx">
+ <title>Using <application>wxWidgets</application></title>
+
+ <para>This section describes the status of the
+ <application>wxWidgets</application> libraries in the ports tree and
+ its integration with the ports system.</para>
+
+ <sect2 xml:id="wx-introduction">
+ <title>Introduction</title>
+
+ <para>There are many versions of the
+ <application>wxWidgets</application> 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.</para>
+
+ <para>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 <command>wx-config</command> 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 <command>wx-config</command> script to
+ call. Otherwise they have to be patched.</para>
+ </sect2>
+
+ <sect2 xml:id="wx-version">
+ <title>Version selection</title>
+
+ <para>To make your port use a specific version of
+ <application>wxWidgets</application> there are two variables
+ available for defining (if only one is defined the other will be set
+ to a default value):</para>
+
+ <table xml:id="wx-ver-sel-table" frame="none">
+ <title>Variables to select <application>wxWidgets</application>
+ versions</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+
+ <entry>Description</entry>
+
+ <entry>Default value</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>USE_WX</varname></entry>
+
+ <entry>List of versions the port can use</entry>
+
+ <entry>All available versions</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_WX_NOT</varname></entry>
+
+ <entry>List of versions the port can not use</entry>
+
+ <entry>None</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>The following is a list of available
+ <application>wxWidgets</application> versions and the corresponding
+ ports in the tree:</para>
+
+ <table frame="none">
+ <title>Available <application>wxWidgets</application>
+ versions</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Version</entry>
+
+ <entry>Port</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>2.4</literal></entry>
+
+ <entry><package>x11-toolkits/wxgtk24</package></entry>
+ </row>
+
+ <row>
+ <entry><literal>2.6</literal></entry>
+
+ <entry><package>x11-toolkits/wxgtk26</package></entry>
+ </row>
+ <row>
+ <entry><literal>2.8</literal></entry>
+
+ <entry><package>x11-toolkits/wxgtk28</package></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>The versions starting from <literal>2.5</literal> also come in
+ Unicode version and are installed by a slave port named like the
+ normal one plus a <literal>-unicode</literal> suffix, but this can
+ be handled with variables (see <xref linkend="wx-unicode"/>).</para>
+ </note>
+
+ <para>The variables in <xref linkend="wx-ver-sel-table"/> can be set
+ to one or more of the following combinations separated by
+ spaces:</para>
+
+ <table frame="none">
+ <title><application>wxWidgets</application> version
+ specifications</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Description</entry>
+
+ <entry>Example</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>Single version</entry>
+
+ <entry><literal>2.4</literal></entry>
+ </row>
+
+ <row>
+ <entry>Ascending range</entry>
+
+ <entry><literal>2.4+</literal></entry>
+ </row>
+
+ <row>
+ <entry>Descending range</entry>
+
+ <entry><literal>2.6-</literal></entry>
+ </row>
+
+ <row>
+ <entry>Full range (must be ascending)</entry>
+
+ <entry><literal>2.4-2.6</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>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.</para>
+
+ <table frame="none">
+ <title>Variables to select preferred
+ <application>wxWidgets</application> versions</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+
+ <entry>Designed for</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>WANT_WX_VER</varname></entry>
+
+ <entry>the port</entry>
+ </row>
+
+ <row>
+ <entry><varname>WITH_WX_VER</varname></entry>
+
+ <entry>the user</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 xml:id="wx-components">
+ <title>Component selection</title>
+
+ <para>There are other applications that, while not being
+ <application>wxWidgets</application> libraries, are related to them.
+ These applications can be specified in the
+ <varname>WX_COMPS</varname> variable. The following components are
+ available:</para>
+
+ <table frame="none">
+ <title>Available <application>wxWidgets</application>
+ components</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry>
+
+ <entry>Description</entry>
+
+ <entry>Version restriction</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>wx</literal></entry>
+
+ <entry>main library</entry>
+
+ <entry>none</entry>
+ </row>
+
+ <row>
+ <entry><literal>contrib</literal></entry>
+
+ <entry>contributed libraries</entry>
+
+ <entry><literal>none</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>python</literal></entry>
+
+ <entry><application>wxPython</application>
+ (<application>Python</application> bindings)</entry>
+
+ <entry><literal>2.4-2.6</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>mozilla</literal></entry>
+
+ <entry><application>wxMozilla</application></entry>
+
+ <entry><literal>2.4</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>svg</literal></entry>
+
+ <entry><application>wxSVG</application></entry>
+
+ <entry><literal>2.6</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>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 <xref linkend="wx-def-dep-types"/>). The
+ following types are available:</para>
+
+ <table frame="none">
+ <title>Available <application>wxWidgets</application> dependency
+ types</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>build</literal></entry>
+
+ <entry>Component is required for building, equivalent to
+ <varname>BUILD_DEPENDS</varname></entry>
+ </row>
+
+ <row>
+ <entry><literal>run</literal></entry>
+
+ <entry>Component is required for running, equivalent to
+ <varname>RUN_DEPENDS</varname></entry>
+ </row>
+
+ <row>
+ <entry><literal>lib</literal></entry>
+
+ <entry>Component is required for building and running,
+ equivalent to <varname>LIB_DEPENDS</varname></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>The default values for the components are detailed in the
+ following table:</para>
+
+ <table xml:id="wx-def-dep-types" frame="none">
+ <title>Default <application>wxWidgets</application> dependency
+ types</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Component</entry>
+
+ <entry>Dependency type</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>wx</literal></entry>
+
+ <entry><literal>lib</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>contrib</literal></entry>
+
+ <entry><literal>lib</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>python</literal></entry>
+
+ <entry><literal>run</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>mozilla</literal></entry>
+
+ <entry><literal>lib</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>svg</literal></entry>
+
+ <entry><literal>lib</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <example xml:id="wx-components-example">
+ <title>Selecting <application>wxWidgets</application>
+ components</title>
+
+ <para>The following fragment corresponds to a port which uses
+ <application>wxWidgets</application> version
+ <literal>2.4</literal> and its contributed libraries.</para>
+
+ <programlisting>USE_WX= 2.4
+WX_COMPS= wx contrib</programlisting>
+ </example>
+ </sect2>
+ <sect2 xml:id="wx-unicode">
+ <title>Unicode</title>
+
+ <para>The <application>wxWidgets</application> library supports
+ Unicode since version <literal>2.5</literal>. In the ports tree
+ both versions are available and can be selected with the following
+ variables:</para>
+
+ <table xml:id="wx-unicode-var-table" frame="none">
+ <title>Variables to select Unicode in
+ <application>wxWidgets</application>
+ versions</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+
+ <entry>Description</entry>
+
+ <entry>Designed for</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>WX_UNICODE</varname></entry>
+
+ <entry>The port works <emphasis>only</emphasis> with the
+ Unicode version</entry>
+
+ <entry>the port</entry>
+ </row>
+
+ <row>
+ <entry><varname>WANT_UNICODE</varname></entry>
+
+ <entry>The port works with both versions but prefers the
+ Unicode one</entry>
+
+ <entry>the port</entry>
+ </row>
+
+ <row>
+ <entry><varname>WITH_UNICODE</varname></entry>
+
+ <entry>The port will use the Unicode version</entry>
+
+ <entry>the user</entry>
+ </row>
+
+ <row>
+ <entry><varname>WITHOUT_UNICODE</varname></entry>
+
+ <entry>The port will use the normal version if
+ supported (when <varname>WX_UNICODE</varname> is not
+ defined)</entry>
+
+ <entry>the user</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <warning>
+ <para>Do not use <varname>WX_UNICODE</varname> for ports that can
+ use both Unicode and normal versions. If you want the port to use
+ Unicode by default define <varname>WANT_UNICODE</varname>
+ instead.</para>
+ </warning>
+ </sect2>
+
+ <sect2 xml:id="wx-version-detection">
+ <title>Detecting installed versions</title>
+
+ <para>To detect an installed version you have to define
+ <varname>WANT_WX</varname>. If you do not set it to a specific
+ version then the components will have a version suffix. The
+ <varname>HAVE_WX</varname> variable will be filled after
+ detection.</para>
+
+ <example xml:id="wx-ver-det-example">
+ <title>Detecting installed <application>wxWidgets</application>
+ versions and components</title>
+
+ <para>The following fragment can be used in a port that uses
+ <application>wxWidgets</application> if it is installed, or an
+ option is selected.</para>
+
+ <programlisting>WANT_WX= yes
+
+.include &lt;bsd.port.pre.mk&gt;
+
+.if defined(WITH_WX) || ${HAVE_WX:Mwx-2.4} != ""
+USE_WX= 2.4
+CONFIGURE_ARGS+=--enable-wx
+.endif</programlisting>
+
+ <para>The following fragment can be used in a port that enables
+ <application>wxPython</application> support if it is installed or
+ if an option is selected, in addition to
+ <application>wxWidgets</application>, both version
+ <literal>2.6</literal>.</para>
+
+ <programlisting>USE_WX= 2.6
+WX_COMPS= wx
+WANT_WX= 2.6
+
+.include &lt;bsd.port.pre.mk&gt;
+
+.if defined(WITH_WXPYTHON) || ${HAVE_WX:Mpython} != ""
+WX_COMPS+= python
+CONFIGURE_ARGS+=--enable-wxpython
+.endif</programlisting>
+ </example>
+ </sect2>
+
+ <sect2 xml:id="wx-defined-variables">
+ <title>Defined variables</title>
+
+ <para>The following variables are available in the port (after
+ defining one from <xref linkend="wx-ver-sel-table"/>).</para>
+
+ <table frame="none">
+ <title>Variables defined for ports that use
+ <application>wxWidgets</application></title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>WX_CONFIG</varname></entry>
+
+ <entry>The path to the <application>wxWidgets</application>
+ <command>wx-config</command> script (with different
+ name)</entry>
+ </row>
+ <row>
+ <entry><varname>WXRC_CMD</varname></entry>
+
+ <entry>The path to the <application>wxWidgets</application>
+ <command>wxrc</command> program (with different
+ name)</entry>
+ </row>
+ <row>
+ <entry><varname>WX_VERSION</varname></entry>
+
+ <entry>The <application>wxWidgets</application> version that
+ is going to be used (e.g., <literal>2.6</literal>)</entry>
+ </row>
+
+ <row>
+ <entry><varname>WX_UNICODE</varname></entry>
+
+ <entry>If not defined but Unicode is going to be used then it
+ will be defined</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 xml:id="wx-premk">
+ <title>Processing in <filename>bsd.port.pre.mk</filename></title>
+
+ <para>If you need to use the variables for running commands right
+ after including <filename>bsd.port.pre.mk</filename> you need to
+ define <varname>WX_PREMK</varname>.</para>
+
+ <important>
+ <para>If you define <varname>WX_PREMK</varname>, then the version,
+ dependencies, components and defined variables will not change if
+ you modify the <application>wxWidgets</application> port variables
+ <emphasis>after</emphasis> including
+ <filename>bsd.port.pre.mk</filename>.</para>
+ </important>
+
+ <example xml:id="wx-premk-example">
+ <title>Using <application>wxWidgets</application> variables in
+ commands</title>
+
+ <para>The following fragment illustrates the use of
+ <varname>WX_PREMK</varname> by running the
+ <command>wx-config</command> script to obtain the full version
+ string, assign it to a variable and pass it to the program.</para>
+
+ <programlisting>USE_WX= 2.4
+WX_PREMK= yes
+
+.include &lt;bsd.port.pre.mk&gt;
+
+.if exists(${WX_CONFIG})
+VER_STR!= ${WX_CONFIG} --release
+
+PLIST_SUB+= VERSION="${VER_STR}"
+.endif</programlisting>
+ </example>
+
+ <note>
+ <para>The <application>wxWidgets</application> variables can be
+ safely used in commands when they are inside targets without the
+ need of <varname>WX_PREMK</varname>.</para>
+ </note>
+ </sect2>
+
+ <sect2 xml:id="wx-additional-config-args">
+ <title>Additional <command>configure</command> arguments</title>
+
+ <para>Some GNU <command>configure</command> scripts can not find
+ <application>wxWidgets</application> with just the
+ <literal>WX_CONFIG</literal> environment variable set, requiring
+ additional arguments. The <varname>WX_CONF_ARGS</varname> variable
+ can be used for provide them.</para>
+
+ <table frame="none">
+ <title>Legal values for <varname>WX_CONF_ARGS</varname></title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Possible value</entry>
+
+ <entry>Resulting argument</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>absolute</literal></entry>
+
+ <entry><literal>--with-wx-config=${WX_CONFIG}</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>relative</literal></entry>
+
+ <entry><literal>--with-wx=${LOCALBASE}
+ --with-wx-config=${WX_CONFIG:T}</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="using-lua">
+ <title>Using <application>Lua</application></title>
+
+ <para>This section describes the status of the
+ <application>Lua</application> libraries in the ports tree and its
+ integration with the ports system.</para>
+
+ <sect2 xml:id="lua-introduction">
+ <title>Introduction</title>
+
+ <para>There are many versions of the <application>Lua</application>
+ 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.</para>
+
+ <para>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.</para>
+ </sect2>
+
+ <sect2 xml:id="lua-version">
+ <title>Version selection</title>
+
+ <para>To make your port use a specific version of
+ <application>Lua</application> there are two variables available
+ for defining (if only one is defined the other will be set to a
+ default value):</para>
+
+ <table xml:id="lua-ver-sel-table" frame="none">
+ <title>Variables to select <application>Lua</application>
+ versions</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+
+ <entry>Description</entry>
+
+ <entry>Default value</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>USE_LUA</varname></entry>
+
+ <entry>List of versions the port can use</entry>
+
+ <entry>All available versions</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_LUA_NOT</varname></entry>
+
+ <entry>List of versions the port can not use</entry>
+
+ <entry>None</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>The following is a list of available
+ <application>Lua</application> versions and the corresponding ports
+ in the tree:</para>
+
+ <table frame="none">
+ <title>Available <application>Lua</application> versions</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Version</entry>
+
+ <entry>Port</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>4.0</literal></entry>
+
+ <entry><package>lang/lua4</package></entry>
+ </row>
+
+ <row>
+ <entry><literal>5.0</literal></entry>
+
+ <entry><package>lang/lua50</package></entry>
+ </row>
+
+ <row>
+ <entry><literal>5.1</literal></entry>
+
+ <entry><package>lang/lua</package></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>The variables in <xref linkend="lua-ver-sel-table"/> can be set
+ to one or more of the following combinations separated by
+ spaces:</para>
+
+ <table frame="none">
+ <title><application>Lua</application> version specifications</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Description</entry>
+
+ <entry>Example</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>Single version</entry>
+
+ <entry><literal>4.0</literal></entry>
+ </row>
+
+ <row>
+ <entry>Ascending range</entry>
+
+ <entry><literal>5.0+</literal></entry>
+ </row>
+
+ <row>
+ <entry>Descending range</entry>
+
+ <entry><literal>5.0-</literal></entry>
+ </row>
+
+ <row>
+ <entry>Full range (must be ascending)</entry>
+
+ <entry><literal>5.0-5.1</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>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.</para>
+
+ <table frame="none">
+ <title>Variables to select preferred <application>Lua</application>
+ versions</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+
+ <entry>Designed for</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>WANT_LUA_VER</varname></entry>
+
+ <entry>the port</entry>
+ </row>
+
+ <row>
+ <entry><varname>WITH_LUA_VER</varname></entry>
+
+ <entry>the user</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <example xml:id="lua-version-example">
+ <title>Selecting the <application>Lua</application> version</title>
+
+ <para>The following fragment is from a port which can use
+ <application>Lua</application> version <literal>5.0</literal> or
+ <literal>5.1</literal>, and uses <literal>5.0</literal> by
+ default. It can be overriden by the user using
+ <varname>WITH_LUA_VER</varname>.</para>
+
+ <programlisting>USE_LUA= 5.0-5.1
+WANT_LUA_VER= 5.0</programlisting>
+ </example>
+ </sect2>
+
+ <sect2 xml:id="lua-components">
+ <title>Component selection</title>
+
+ <para>There are other applications that, while not being
+ <application>Lua</application> libraries, are related to them.
+ These applications can be specified in the
+ <varname>LUA_COMPS</varname> variable. The following components are
+ available:</para>
+
+ <table frame="none">
+ <title>Available <application>Lua</application> components</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry>
+
+ <entry>Description</entry>
+
+ <entry>Version restriction</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>lua</literal></entry>
+
+ <entry>main library</entry>
+
+ <entry>none</entry>
+ </row>
+
+ <row>
+ <entry><literal>tolua</literal></entry>
+
+ <entry>Library for accesing C/C++ code</entry>
+
+ <entry><literal>4.0-5.0</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>ruby</literal></entry>
+
+ <entry>Ruby bindings</entry>
+
+ <entry><literal>4.0-5.0</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>There are more components but they are modules for the
+ interpreter, not used by applications (only by other
+ modules).</para>
+ </note>
+
+ <para>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 <xref linkend="lua-def-dep-types"/>). The
+ following types are available:</para>
+
+ <table frame="none">
+ <title>Available <application>Lua</application> dependency
+ types</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>build</literal></entry>
+
+ <entry>Component is required for building, equivalent to
+ <varname>BUILD_DEPENDS</varname></entry>
+ </row>
+
+ <row>
+ <entry><literal>run</literal></entry>
+
+ <entry>Component is required for running, equivalent to
+ <varname>RUN_DEPENDS</varname></entry>
+ </row>
+
+ <row>
+ <entry><literal>lib</literal></entry>
+
+ <entry>Component is required for building and running,
+ equivalent to <varname>LIB_DEPENDS</varname></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>The default values for the components are detailed in the
+ following table:</para>
+
+ <table xml:id="lua-def-dep-types" frame="none">
+ <title>Default <application>Lua</application> dependency
+ types</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Component</entry>
+
+ <entry>Dependency type</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>lua</literal></entry>
+
+ <entry><literal>lib</literal> for <literal>4.0-5.0</literal>
+ (shared) and <literal>build</literal> for
+ <literal>5.1</literal> (static)</entry>
+ </row>
+
+ <row>
+ <entry><literal>tolua</literal></entry>
+
+ <entry><literal>build</literal> (static)</entry>
+ </row>
+
+ <row>
+ <entry><literal>ruby</literal></entry>
+
+ <entry><literal>lib</literal> (shared)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <example xml:id="lua-components-example">
+ <title>Selecting <application>Lua</application> components</title>
+
+ <para>The following fragment corresponds to a port which uses
+ <application>Lua</application> version <literal>4.0</literal> and
+ its <application>Ruby</application> bindings.</para>
+
+ <programlisting>USE_LUA= 4.0
+LUA_COMPS= lua ruby</programlisting>
+ </example>
+ </sect2>
+
+ <sect2 xml:id="lua-version-detection">
+ <title>Detecting installed versions</title>
+
+ <para>To detect an installed version you have to define
+ <varname>WANT_LUA</varname>. If you do not set it to a specific
+ version then the components will have a version suffix. The
+ <varname>HAVE_LUA</varname> variable will be filled after
+ detection.</para>
+
+ <example xml:id="lua-ver-det-example">
+ <title>Detecting installed <application>Lua</application> versions
+ and components</title>
+
+ <para>The following fragment can be used in a port that uses
+ <application>Lua</application> if it is installed, or an option is
+ selected.</para>
+
+ <programlisting>WANT_LUA= yes
+
+.include &lt;bsd.port.pre.mk&gt;
+
+.if defined(WITH_LUA5) || ${HAVE_LUA:Mlua-5.[01]} != ""
+USE_LUA= 5.0-5.1
+CONFIGURE_ARGS+=--enable-lua5
+.endif</programlisting>
+
+ <para>The following fragment can be used in a port that enables
+ <application>tolua</application> support if it is installed or if
+ an option is selected, in addition to
+ <application>Lua</application>, both version
+ <literal>4.0</literal>.</para>
+
+ <programlisting>USE_LUA= 4.0
+LUA_COMPS= lua
+WANT_LUA= 4.0
+
+.include &lt;bsd.port.pre.mk&gt;
+
+.if defined(WITH_TOLUA) || ${HAVE_LUA:Mtolua} != ""
+LUA_COMPS+= tolua
+CONFIGURE_ARGS+=--enable-tolua
+.endif</programlisting>
+ </example>
+ </sect2>
+
+ <sect2 xml:id="lua-defined-variables">
+ <title>Defined variables</title>
+
+ <para>The following variables are available in the port (after
+ defining one from <xref linkend="lua-ver-sel-table"/>).</para>
+
+ <table frame="none">
+ <title>Variables defined for ports that use
+ <application>Lua</application></title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>LUA_VER</varname></entry>
+
+ <entry>The <application>Lua</application> version that is
+ going to be used (e.g., <literal>5.1</literal>)</entry>
+ </row>
+
+ <row>
+ <entry><varname>LUA_VER_SH</varname></entry>
+ <entry>The <application>Lua</application> shared library major
+ version (e.g., <literal>1</literal>)</entry>
+ </row>
+
+ <row>
+ <entry><varname>LUA_VER_STR</varname></entry>
+
+ <entry>The <application>Lua</application> version without the
+ dots (e.g., <literal>51</literal>)</entry>
+ </row>
+
+ <row>
+ <entry><varname>LUA_PREFIX</varname></entry>
+
+ <entry>The prefix where <application>Lua</application> (and
+ components) is installed</entry>
+ </row>
+
+ <row>
+ <entry><varname>LUA_SUBDIR</varname></entry>
+
+ <entry>The directory under <filename>${PREFIX}/bin</filename>,
+ <filename>${PREFIX}/share</filename> and
+ <filename>${PREFIX}/lib</filename> where
+ <application>Lua</application> is installed</entry>
+ </row>
+
+ <row>
+ <entry><varname>LUA_INCDIR</varname></entry>
+
+ <entry>The directory where <application>Lua</application> and
+ <application>tolua</application> header files are
+ installed</entry>
+ </row>
+
+ <row>
+ <entry><varname>LUA_LIBDIR</varname></entry>
+
+ <entry>The directory where <application>Lua</application> and
+ <application>tolua</application> libraries are
+ installed</entry>
+ </row>
+
+ <row>
+ <entry><varname>LUA_MODLIBDIR</varname></entry>
+
+ <entry>The directory where <application>Lua</application>
+ module libraries (<filename>.so</filename>) are
+ installed</entry>
+ </row>
+
+ <row>
+ <entry><varname>LUA_MODSHAREDIR</varname></entry>
+
+ <entry>The directory where <application>Lua</application>
+ modules (<filename>.lua</filename>) are installed</entry>
+ </row>
+
+ <row>
+ <entry><varname>LUA_PKGNAMEPREFIX</varname></entry>
+
+ <entry>The package name prefix used by
+ <application>Lua</application> modules</entry>
+ </row>
+ <row>
+ <entry><varname>LUA_CMD</varname></entry>
+
+ <entry>The path to the <application>Lua</application>
+ interpreter</entry>
+ </row>
+ <row>
+ <entry><varname>LUAC_CMD</varname></entry>
+
+ <entry>The path to the <application>Lua</application>
+ compiler</entry>
+ </row>
+ <row>
+ <entry><varname>TOLUA_CMD</varname></entry>
+
+ <entry>The path to the <application>tolua</application>
+ program</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <example xml:id="lua-variables-example">
+ <title>Telling the port where to find
+ <application>Lua</application></title>
+
+ <para>The following fragment shows how to tell a port that uses a
+ configure script where the <application>Lua</application> header
+ files and libraries are.</para>
+
+ <programlisting>
+USE_LUA= 4.0
+GNU_CONFIGURE= yes
+CONFIGURE_ENV= CPPFLAGS="-I${LUA_INCDIR}" LDFLAGS="-L${LUA_LIBDIR}"</programlisting>
+ </example>
+ </sect2>
+
+ <sect2 xml:id="lua-premk">
+ <title>Processing in <filename>bsd.port.pre.mk</filename></title>
+
+ <para>If you need to use the variables for running commands right
+ after including <filename>bsd.port.pre.mk</filename> you need to
+ define <varname>LUA_PREMK</varname>.</para>
+
+ <important>
+ <para>If you define <varname>LUA_PREMK</varname>, then the version,
+ dependencies, components and defined variables will not change if
+ you modify the <application>Lua</application> port variables
+ <emphasis>after</emphasis> including
+ <filename>bsd.port.pre.mk</filename>.</para>
+ </important>
+
+ <example xml:id="lua-premk-example">
+ <title>Using <application>Lua</application> variables in
+ commands</title>
+
+ <para>The following fragment illustrates the use of
+ <varname>LUA_PREMK</varname> by running the
+ <application>Lua</application> interpreter to obtain the full
+ version string, assign it to a variable and pass it to the
+ program.</para>
+
+ <programlisting>USE_LUA= 5.0
+LUA_PREMK= yes
+
+.include &lt;bsd.port.pre.mk&gt;
+
+.if exists(${LUA_CMD})
+VER_STR!= ${LUA_CMD} -v
+
+CFLAGS+= -DLUA_VERSION_STRING="${VER_STR}"
+.endif</programlisting>
+ </example>
+
+ <note>
+ <para>The <application>Lua</application> variables can be safely
+ used in commands when they are inside targets without the need of
+ <varname>LUA_PREMK</varname>.</para>
+ </note>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="using-xfce">
+ <title>Using Xfce</title>
+
+ <para>The <varname>USE_XFCE</varname> variable is used to autoconfigure
+ the dependencies for ports which use an Xfce based library or application
+ like
+ <package>x11-toolkits/libxfce4gui</package> and
+ <package>x11-wm/xfce4-panel</package>.</para>
+
+ <para>The following Xfce libraries and applications are recognized at
+ the moment:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>libexo: <package>x11/libexo</package></para>
+ </listitem>
+
+ <listitem>
+ <para>libgui: <package>x11-toolkits/libxfce4gui</package></para>
+ </listitem>
+
+ <listitem>
+ <para>libutil: <package>x11/libxfce4util</package></para>
+ </listitem>
+
+ <listitem>
+ <para>libmcs: <package>x11/libxfce4mcs</package></para>
+ </listitem>
+
+ <listitem>
+ <para>mcsmanager: <package>sysutils/xfce4-mcs-manager</package></para>
+ </listitem>
+
+ <listitem>
+ <para>panel: <package>x11-wm/xfce4-panel</package></para>
+ </listitem>
+
+ <listitem>
+ <para>thunar: <package>x11-fm/thunar</package></para>
+ </listitem>
+
+ <listitem>
+ <para>wm: <package>x11-wm/xfce4-wm</package></para>
+ </listitem>
+
+ <listitem>
+ <para>xfdev: <package>dev/xfce4-dev-tools</package></para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>The following additional parameters are recognized:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>configenv: Use this if your port requires a special modified
+ <varname>CONFIGURE_ENV</varname> to find it's required libraries.
+ <programlisting>-I&dollar;{LOCALBASE}/include -L&dollar;{LOCALBASE}/lib</programlisting>
+ gets added to CPPFLAGS to <varname>CONFIGURE_ENV</varname>.</para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>Therefore, if a port has a dependency on
+ <package>sysutils/xfce4-mcs-manager</package> and
+ requires the special CPPFLAGS in its configure environment,
+ the syntax will be:</para>
+
+ <programlisting>USE_XFCE= mcsmanager configenv</programlisting>
+ </sect1>
+
+ <sect1 xml:id="using-databases">
+ <title>Using databases</title>
+
+ <table frame="none">
+ <title>Variables for ports using databases</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+
+ <entry>Means</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>USE_BDB</varname></entry>
+
+ <entry>If variable is set to <literal>yes</literal>,
+ add dependency on <package>databases/db41</package>
+ port. The variable may also be set to values: 2, 3, 40, 41,
+ 42, 43, 44, 45 46, or 47. You can declare a range of
+ acceptable values, <varname>USE_BDB</varname>=42+ will find
+ the highest installed version, and fall back to 42 if nothing
+ else is installed.</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_MYSQL</varname></entry>
+
+ <entry>If variable is set to <literal>yes</literal>, add
+ dependency on <package>databases/mysql50-server</package>
+ port. An associated variable,
+ <varname>WANT_MYSQL_VER</varname>, may be
+ set to values such as 323, 40, 41, 50, 51 or 60.</entry>
+ </row>
+
+ <row>
+ <entry><varname>USE_PGSQL</varname></entry>
+
+ <entry>If set to <literal>yes</literal>, add dependency on
+ <package>databases/postgresql82</package>
+ port. An associated variable,
+ <varname>WANT_PGSQL_VER</varname>, may be set to values such
+ as 73, 74, 80, 81, 82, or 83.</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 xml:id="rc-scripts">
+ <title>Starting and stopping services (rc scripts)</title>
+
+ <para><filename>rc.d</filename> 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 <filename>rc.d</filename> framework. Details on its usage
+ can be found in
+ <link xlink:href="&url.books.handbook;/configtuning-rcd.html">the rc.d Handbook
+ chapter</link>. Detailed explanation of available commands is
+ provided in
+ &man.rc.8; and &man.rc.subr.8;. Finally, there is
+ <link xlink:href="&url.articles.rc-scripting.en;">an article</link>
+ on practical aspects of <filename>rc.d</filename> scripting.</para>
+
+ <para>One or more rc scripts can be installed:</para>
+
+ <programlisting>USE_RC_SUBR= doormand</programlisting>
+
+ <para>Scripts must be placed in the <filename>files</filename>
+ subdirectory and a <literal>.in</literal> suffix must be added to their
+ filename. The only difference from a base system <filename>rc.d</filename> script is that the
+ <literal>.&nbsp;/etc/rc.subr</literal> line must be replaced with the
+ <literal>.&nbsp;%%RC_SUBR%%</literal>, because older versions of &os;
+ do not have an <filename>/etc/rc.subr</filename> file. Standard
+ <varname>SUB_LIST</varname> expansions are used too.
+ Use of the <literal>%%PREFIX%%</literal> and
+ <literal>%%LOCALBASE%%</literal> expansions is strongly encouraged as well.
+ More on
+ <varname>SUB_LIST</varname> in <link linkend="using-sub-files">the relevant section</link>.</para>
+
+ <para>Prior to &os;&nbsp;6.1-RELEASE, integration with &man.rcorder.8; is available by using
+ <varname>USE_RCORDER</varname> instead of
+ <varname>USE_RC_SUBR</varname>.
+ However, use of this method is deprecated.</para>
+
+ <para>As of &os;&nbsp;6.1-RELEASE, local <filename>rc.d</filename>
+ scripts (including those installed by ports) are included in
+ the overall &man.rcorder.8; of the base system.</para>
+
+ <para>Example simple <filename>rc.d</filename> script:</para>
+
+ <programlisting>#!/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"</programlisting>
+
+ <para>The &quot;=&quot; style of default variable assignment
+ is preferable to the &quot;:=&quot; 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
+ <emphasis>or</emphasis> null.
+ A user might very well include something like
+ <programlisting>doormand_flags=""</programlisting> in their
+ <filename>rc.conf.local</filename> file, and a variable
+ substitution using &quot;:=&quot; would inappropriately
+ override the user's intention.</para>
+
+ <para>The suffix of the rc script is provided in
+ <varname>RC_SUBR_SUFFIX</varname> for further use in the port's
+ <filename>Makefile</filename>. Current versions of &os; do not add
+ any suffix to the script name, but older versions used to add
+ <filename>.sh</filename> suffix.</para>
+
+ <note>
+ <para>No new scripts should be added with the <filename>.sh</filename>
+ suffix. At some point there will be a mass repocopy of all the
+ scripts that still have that suffix.</para>
+ </note>
+
+ <sect2>
+ <title>Stopping services at deinstall</title>
+
+ <para>It 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.</para>
+
+ <para>Line like this goes to the <filename>pkg-plist</filename>:</para>
+
+ <programlisting>@stopdaemon doormand</programlisting>
+
+ <para>The argument must match the content of
+ <varname>USE_RC_SUBR</varname> variable.</para>
+ </sect2>
+ </sect1>
+ </chapter>
+
+
+ <chapter xml:id="plist">
+ <title>Advanced <filename>pkg-plist</filename> practices</title>
+
+ <sect1 xml:id="plist-sub">
+ <title>Changing <filename>pkg-plist</filename> based on make
+ variables</title>
+
+ <para>Some ports, particularly the <literal>p5-</literal> ports,
+ need to change their <filename>pkg-plist</filename> depending on
+ what options they are configured with (or version of
+ <literal>perl</literal>, in the case of <literal>p5-</literal>
+ ports). To make this easy, any instances in the
+ <filename>pkg-plist</filename> of <literal>%%OSREL%%</literal>,
+ <literal>%%PERL_VER%%</literal>, and
+ <literal>%%PERL_VERSION%%</literal> will be substituted for
+ appropriately. The value of <literal>%%OSREL%%</literal> is the
+ numeric revision of the operating system (e.g.,
+ <literal>4.9</literal>). <literal>%%PERL_VERSION%%</literal> is
+ the full version number of <command>perl</command> (e.g.,
+ <literal>5.00502</literal>) and <literal>%%PERL_VER%%</literal>
+ is the <command>perl</command> version number minus
+ the patchlevel (e.g., <literal>5.005</literal>). Several other
+ <literal>%%VARS%%</literal> related to
+ port's documentation files are described in <link linkend="install-documentation">the relevant section</link>.</para>
+
+ <para>If you need to make other substitutions, you can set the
+ <varname>PLIST_SUB</varname> variable with a list of
+ <literal>VAR=VALUE</literal>
+ pairs and instances of
+ <literal>%%VAR%%</literal> will be
+ substituted with <replaceable>VALUE</replaceable> in the
+ <filename>pkg-plist</filename>.</para>
+
+ <para>For instance, if you have a port that installs many files in a
+ version-specific subdirectory, you can put something like</para>
+
+ <programlisting>OCTAVE_VERSION= 2.0.13
+PLIST_SUB= OCTAVE_VERSION=${OCTAVE_VERSION}</programlisting>
+
+ <para>in the <filename>Makefile</filename> and use
+ <literal>%%OCTAVE_VERSION%%</literal> wherever the version shows up
+ in <filename>pkg-plist</filename>. That way, when you upgrade the port,
+ you will not have to change dozens (or in some cases, hundreds) of
+ lines in the <filename>pkg-plist</filename>.</para>
+
+ <para>This substitution (as well as addition of any <link linkend="makefile-manpages">manual pages</link>) will be done between
+ the <buildtarget>pre-install</buildtarget> and
+ <buildtarget>do-install</buildtarget> targets, by reading from
+ <filename>PLIST</filename> and writing to
+ <filename>TMPPLIST</filename>
+ (default:
+ <filename>WRKDIR/.PLIST.mktmp</filename>). So if
+ your port builds <filename>PLIST</filename>
+ on the fly, do so in or
+ before <buildtarget>pre-install</buildtarget>. Also, if your port
+ needs to edit the resulting file, do so in
+ <buildtarget>post-install</buildtarget> to a file named
+ <filename>TMPPLIST</filename>.</para>
+
+ <para>Another possibility to modify port's packing list is based
+ on setting the variables <varname>PLIST_FILES</varname> and
+ <varname>PLIST_DIRS</varname>. The value of each variable
+ is regarded as a list of pathnames to
+ write to <filename>TMPPLIST</filename>
+ along with <filename>PLIST</filename>
+ contents. Names listed in <varname>PLIST_FILES</varname>
+ and <varname>PLIST_DIRS</varname> are subject to
+ <literal>%%VAR%%</literal>
+ substitution, as described above.
+ Except for that, names from <varname>PLIST_FILES</varname>
+ will appear in the final packing list unchanged,
+ while <literal>@dirrm</literal> will be
+ prepended to names from <varname>PLIST_DIRS</varname>.
+ To take effect, <varname>PLIST_FILES</varname> and
+ <varname>PLIST_DIRS</varname> must be set before
+ <filename>TMPPLIST</filename> is written,
+ i.e. in <buildtarget>pre-install</buildtarget> or earlier.</para>
+ </sect1>
+
+ <sect1 xml:id="plist-cleaning">
+ <title>Empty directories</title>
+
+ <sect2 xml:id="plist-dir-cleaning">
+ <title>Cleaning up empty directories</title>
+
+ <para>Do make your ports remove empty directories when they are
+ de-installed. This is usually accomplished by adding
+ <literal>@dirrm</literal> lines for all directories that are
+ specifically created by the port. You need to delete subdirectories
+ before you can delete parent directories.</para>
+
+ <programlisting> :
+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/oneko</programlisting>
+
+ <para>However, sometimes <literal>@dirrm</literal> will give you
+ errors because other ports share the same directory. You
+ can use <literal>@dirrmtry</literal> to
+ remove only empty directories without warning.</para>
+
+ <programlisting>@dirrmtry share/doc/gimp</programlisting>
+
+ <para>This will neither print any error messages nor cause
+ &man.pkg.delete.1; to exit abnormally even if
+ <filename>${PREFIX}/share/doc/gimp</filename> is not
+ empty due to other ports installing some files in there.</para>
+ </sect2>
+
+ <sect2 xml:id="plist-dir-empty">
+ <title>Creating empty directories</title>
+
+ <para>Empty 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
+ <filename>pkg-plist</filename> above the corresponding
+ <literal>@dirrm</literal> line:</para>
+
+ <programlisting>@exec mkdir -p %D/share/foo/templates</programlisting>
+ </sect2>
+
+ </sect1>
+
+ <sect1 xml:id="plist-config">
+ <title>Configuration files</title>
+
+ <para>If your port requires some configuration files in
+ <filename>PREFIX/etc</filename>, do
+ <emphasis>not</emphasis> just install them and list them in
+ <filename>pkg-plist</filename>. That will cause
+ &man.pkg.delete.1; to delete files carefully edited by
+ the user and a new installation to wipe them out.</para>
+
+ <para>Instead, install sample files with a suffix
+ (<filename>filename.sample</filename>
+ 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 <filename>Makefile</filename>, and in
+ the <filename>pkg-plist</filename> (for installation from
+ the package).</para>
+
+ <para>Example of the <filename>Makefile</filename> part:</para>
+
+ <programlisting>post-install:
+ @if [ ! -f ${PREFIX}/etc/orbit.conf ]; then \
+ ${CP} -p ${PREFIX}/etc/orbit.conf.sample ${PREFIX}/etc/orbit.conf ; \
+ fi</programlisting>
+
+ <para>Example of the <filename>pkg-plist</filename> part:</para>
+
+ <programlisting>@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; fi</programlisting>
+
+ <para>Alternatively, print out a <link linkend="porting-message">message</link> pointing out that the
+ user has to copy and edit the file before the software can be made
+ to work.</para>
+ </sect1>
+
+ <sect1 xml:id="plist-dynamic">
+ <title>Dynamic vs. static package list</title>
+
+ <para>A <emphasis>static package list</emphasis> is a package list
+ which is available in the Ports Collection either as a
+ <filename>pkg-plist</filename> file (with or without variable
+ substitution), or embedded into the <filename>Makefile</filename>
+ via <varname>PLIST_FILES</varname> and <varname>PLIST_DIRS</varname>.
+ Even if the contents are auto-generated by a tool or a target
+ in the Makefile <emphasis>before</emphasis> 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.</para>
+
+ <para>A <emphasis>dynamic package list</emphasis> 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 <literal>make
+ clean</literal>.</para>
+
+ <para>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
+ <application>Javadoc</application>).</para>
+
+ <para>Maintainers who prefer dynamic package lists are encouraged to
+ add a new target to their port which generates the
+ <filename>pkg-plist</filename> file so that users may examine
+ the contents.</para>
+
+ </sect1>
+
+ <sect1 xml:id="plist-autoplist">
+ <title>自動產生 package list</title>
+
+ <para>首先,先確認您的 port 除了 <filename>pkg-plist</filename>
+ 尚未搞定之外,其他都完成了。</para>
+
+ <para>接著,建立臨時目錄以供該 port 安裝,並且把所有相依套件都裝好
+ 。</para>
+
+ <screen>&prompt.root; <userinput>mkdir /var/tmp/$(make -V PORTNAME)</userinput>
+&prompt.root; <userinput>mtree -U -f $(make -V MTREE_FILE) -d -e -p /var/tmp/$(make -V PORTNAME)</userinput>
+&prompt.root; <userinput>make depends PREFIX=/var/tmp/$(make -V PORTNAME)</userinput></screen>
+
+ <para>把這目錄架構存到新檔案。</para>
+
+ <screen>&prompt.root; <userinput>(cd /var/tmp/$(make -V PORTNAME) &amp;&amp; find -d * -type d) | sort &gt; OLD-DIRS</userinput></screen>
+
+ <para>新增空的 <filename>pkg-plist</filename> 檔案:</para>
+
+ <screen>&prompt.root; <userinput>:&gt;pkg-plist</userinput></screen>
+
+ <para>若該 port 有遵循 <varname>PREFIX</varname>(也應該要遵循),
+ 接著就可以安裝該 port 並產生檔案清單。</para>
+
+ <screen>&prompt.root; <userinput>make install PREFIX=/var/tmp/$(make -V PORTNAME)</userinput>
+&prompt.root; <userinput>(cd /var/tmp/$(make -V PORTNAME) &amp;&amp; find -d * \! -type d) | sort &gt; pkg-plist</userinput></screen>
+
+ <para>這時要記得把新建的目錄,也加到檔案清單內。</para>
+
+ <screen>&prompt.root; <userinput>(cd /var/tmp/$(make -V PORTNAME) &amp;&amp; find -d * -type d) | sort | comm -13 OLD-DIRS - | sort -r | sed -e 's#^#@dirrm #' &gt;&gt; pkg-plist</userinput></screen>
+
+ <para>最後,您應該手動整理檔案清單(這不是全部自動化處理的)。Man page 則應該利用 <varname>MAN<replaceable>n</replaceable></varname> 的方式
+ 寫在 port 的 <filename>Makefile</filename> 而不是寫在檔案清單中。
+ 使用者設定檔應該移除,或更名為<filename>filename.sample</filename>。
+ The <filename>info/dir</filename> file should not be listed
+ and appropriate <filename>install-info</filename> lines should
+ be added as noted in the <link linkend="makefile-info">info
+ files</link> section. Any
+ libraries installed by the port should be listed as specified in the
+ <link linkend="porting-shlibs">shared libraries</link> section.</para>
+
+ <para>Alternatively, use the <command>plist</command> script in
+ <filename>/usr/ports/Tools/scripts/</filename> to build the
+ package list automatically. The first step is the same as
+ above: take the first three lines, that is,
+ <command>mkdir</command>, <command>mtree</command> and
+ <command>make depends</command>. Then build and install the
+ port:</para>
+
+ <screen>&prompt.root; <userinput>make install PREFIX=/var/tmp/port-name</userinput></screen>
+
+ <para>And let <command>plist</command> create the
+ <filename>pkg-plist</filename> file:</para>
+
+ <screen>&prompt.root; <userinput>/usr/ports/Tools/scripts/plist -Md -m /etc/mtree/BSD.port-type.dist /var/tmp/port-name &gt; pkg-plist</userinput></screen>
+
+ <para>The packing list still has to be tidied up by hand as
+ stated above.</para>
+
+ </sect1>
+
+ </chapter>
+
+ <chapter xml:id="pkg-files">
+ <title>The <filename>pkg-*</filename> files</title>
+
+ <para>There are some tricks we have not mentioned yet about the
+ <filename>pkg-*</filename> files
+ that come in handy sometimes.</para>
+
+ <sect1 xml:id="porting-message">
+ <title><filename>pkg-message</filename></title>
+
+ <para>If you need to display a message to the installer, you may place
+ the message in <filename>pkg-message</filename>. This capability is
+ often useful to display additional installation steps to be taken
+ after a &man.pkg.add.1; or to display licensing
+ information.</para>
+
+ <para>When some lines about the build-time knobs or warnings
+ have to be displayed, use <varname>ECHO_MSG</varname>. The
+ <filename>pkg-message</filename> file is only for
+ post-installation steps. Likewise, the distinction between
+ <varname>ECHO_MSG</varname> and <varname>ECHO_CMD</varname>
+ should be kept in mind. The former is for printing
+ informational text to the screen, while the latter is for
+ command pipelining.</para>
+
+ <para>A good example for both can be found in
+ <filename>shells/bash2/Makefile</filename>:</para>
+
+ <programlisting>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) &gt;/etc/shells
+ @${RM} /etc/shells.bak</programlisting>
+
+ <note>
+ <para>The <filename>pkg-message</filename> file does not need to be
+ added to <filename>pkg-plist</filename>. 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
+ <buildtarget>post-install</buildtarget> target yourself.</para>
+ </note>
+ </sect1>
+
+ <sect1 xml:id="pkg-install">
+ <title><filename>pkg-install</filename></title>
+
+ <para>If your port needs to execute commands when the binary package
+ is installed with &man.pkg.add.1; you can do this via the
+ <filename>pkg-install</filename> script. This script will
+ automatically be added to the package, and will be run twice by
+ &man.pkg.add.1;: the first time as
+ <literal>&dollar;{SH} pkg-install &dollar;{PKGNAME}
+ PRE-INSTALL</literal> and the second time as
+ <literal>&dollar;{SH} pkg-install &dollar;{PKGNAME} POST-INSTALL</literal>.
+ <literal>&dollar;2</literal> can be tested to determine which mode
+ the script is being run in. The <envar>PKG_PREFIX</envar>
+ environmental variable will be set to the package installation
+ directory. See &man.pkg.add.1; for
+ additional information.</para>
+
+ <note>
+ <para>This script is not run automatically if you install the port
+ with <command>make install</command>. If you are depending on it
+ being run, you will have to explicitly call it from your port's
+ <filename>Makefile</filename>, with a line like
+ <literal>PKG_PREFIX=&dollar;{PREFIX} &dollar;{SH} &dollar;{PKGINSTALL}
+ &dollar;{PKGNAME} PRE-INSTALL</literal>.</para>
+ </note>
+ </sect1>
+
+ <sect1 xml:id="pkg-deinstall">
+ <title><filename>pkg-deinstall</filename></title>
+
+ <para>This script executes when a package is removed.</para>
+
+ <para>
+ This script will be run twice by &man.pkg.delete.1;.
+ The first time as <literal>&dollar;{SH} pkg-deinstall &dollar;{PKGNAME}
+ DEINSTALL</literal> and the second time as
+ <literal>&dollar;{SH} pkg-deinstall &dollar;{PKGNAME} POST-DEINSTALL</literal>.
+ </para>
+ </sect1>
+
+ <sect1 xml:id="pkg-req">
+ <title><filename>pkg-req</filename></title>
+
+ <para>If your port needs to determine if it should install or not, you
+ can create a <filename>pkg-req</filename> <quote>requirements</quote>
+ script. It will be invoked automatically at
+ installation/de-installation time to determine whether or not
+ installation/de-installation should proceed.</para>
+
+ <para>The script will be run at installation time by
+ &man.pkg.add.1; as
+ <literal>pkg-req &dollar;{PKGNAME} INSTALL</literal>.
+ At de-installation time it will be run by
+ &man.pkg.delete.1; as
+ <literal>pkg-req &dollar;{PKGNAME} DEINSTALL</literal>.</para>
+ </sect1>
+
+ <sect1 xml:id="pkg-names">
+ <title xml:id="porting-pkgfiles">Changing the names of
+ <filename>pkg-*</filename> files</title>
+
+ <para>All the names of <filename>pkg-*</filename> files
+ are defined using variables so you can change them in your
+ <filename>Makefile</filename> if need be. This is especially useful
+ when you are sharing the same <filename>pkg-*</filename> files
+ among several ports or have to write to one of the above files (see
+ <link linkend="porting-wrkdir">writing to places other than
+ <varname>WRKDIR</varname></link> for why it is a bad idea to write
+ directly into the <filename>pkg-*</filename> subdirectory).</para>
+
+ <para>Here is a list of variable names and their default
+ values. (<varname>PKGDIR</varname> defaults to
+ <varname>${MASTERDIR}</varname>.)</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+ <entry>Default value</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>DESCR</varname></entry>
+ <entry><literal>${PKGDIR}/pkg-descr</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>PLIST</varname></entry>
+ <entry><literal>${PKGDIR}/pkg-plist</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>PKGINSTALL</varname></entry>
+ <entry><literal>${PKGDIR}/pkg-install</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>PKGDEINSTALL</varname></entry>
+ <entry><literal>${PKGDIR}/pkg-deinstall</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>PKGREQ</varname></entry>
+ <entry><literal>${PKGDIR}/pkg-req</literal></entry>
+ </row>
+
+ <row>
+ <entry><varname>PKGMESSAGE</varname></entry>
+ <entry><literal>${PKGDIR}/pkg-message</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>Please change these variables rather than overriding
+ <varname>PKG_ARGS</varname>. If you change
+ <varname>PKG_ARGS</varname>, those files will not correctly be
+ installed in <filename>/var/db/pkg</filename> upon install from a
+ port.</para>
+ </sect1>
+
+ <sect1 xml:id="using-sub-files">
+ <title>Making use of <varname>SUB_FILES</varname> and
+ <varname>SUB_LIST</varname></title>
+
+ <para>The <varname>SUB_FILES</varname> and <varname>SUB_LIST</varname>
+ variables are useful for dynamic values in port files, such as the
+ installation <varname>PREFIX</varname> in
+ <filename>pkg-message</filename>.</para>
+
+ <para>The <varname>SUB_FILES</varname> variable specifies a list
+ of files to be automatically modified. Each
+ <replaceable>file</replaceable> in the
+ <varname>SUB_FILES</varname> list must have a corresponding
+ <filename>file.in</filename> present
+ in <varname>FILESDIR</varname>. A modified version will
+ be created in <varname>WRKDIR</varname>. Files defined as a
+ value of <varname>USE_RC_SUBR</varname> (or the deprecated
+ <varname>USE_RCORDER</varname>)
+ are automatically added to the
+ <varname>SUB_FILES</varname>. For the files
+ <filename>pkg-message</filename>,
+ <filename>pkg-install</filename>, <filename>pkg-deinstall</filename>
+ and <filename>pkg-reg</filename>, the corresponding Makefile variable
+ is automatically set to point to the processed version.</para>
+
+ <para>The <varname>SUB_LIST</varname> variable is a list of
+ <literal>VAR=VALUE</literal> pairs. For each pair
+ <literal>%%VAR%%</literal> will get replaced
+ with <literal>VALUE</literal> in each file listed in
+ <varname>SUB_FILES</varname>. Several common pairs are
+ automatically defined: <varname>PREFIX</varname>,
+ <varname>LOCALBASE</varname>,
+ <varname>DATADIR</varname>, <varname>DOCSDIR</varname>,
+ <varname>EXAMPLESDIR</varname>. Any line beginning with
+ <literal>@comment</literal> will be deleted from resulting files
+ after a variable substitution.</para>
+
+ <para>The following example will replace <literal>%%ARCH%%</literal>
+ with the system architecture
+ in a <filename>pkg-message</filename>:</para>
+
+ <programlisting>SUB_FILES= pkg-message
+SUB_LIST= ARCH=${ARCH}</programlisting>
+
+ <para>Note that for this example, the
+ <filename>pkg-message.in</filename> file must exist in
+ <varname>FILESDIR</varname>.</para>
+
+ <para>Example of a good <filename>pkg-message.in</filename>:</para>
+
+ <programlisting>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.</programlisting>
+
+ </sect1>
+ </chapter>
+
+ <chapter xml:id="testing">
+ <title>Testing your port</title>
+
+ <sect1 xml:id="make-describe">
+ <title>Running <command>make describe</command></title>
+
+ <para>Several of the &os; port maintenance tools, such as
+ &man.portupgrade.1;, rely on a database called
+ <filename>/usr/ports/INDEX</filename> which keeps track of such
+ items as port dependencies. <filename>INDEX</filename> is created
+ by the top-level <filename>ports/Makefile</filename> via
+ <command>make index</command>, which descends into each
+ port subdirectory and executes <command>make describe</command>
+ there. Thus, if <command>make describe</command> fails in any
+ port, no one can generate <filename>INDEX</filename>, and many
+ people will quickly become unhappy.</para>
+
+ <note>
+ <para>It is important to be able to generate this file no
+ matter what options are present in <filename>make.conf</filename>,
+ so please avoid doing things such as using <literal>.error</literal>
+ statements when (for instance) a dependency is not satisfied.
+ (See <xref linkend="dads-dot-error"/>.)</para>
+ </note>
+
+ <para>If <command>make describe</command> produces a string
+ rather than an error message, you are probably safe. See
+ <filename>bsd.port.mk</filename> for the meaning of the
+ string produced.</para>
+
+ <para>Also note that running a recent version of
+ <command>portlint</command> (as specified in the next section)
+ will cause <command>make describe</command> to be run
+ automatically.</para>
+ </sect1>
+
+ <sect1 xml:id="testing-portlint">
+ <title>Portlint</title>
+
+ <para>Do check your work with <link linkend="porting-portlint"><command>portlint</command></link>
+ before you submit or commit it. <command>portlint</command>
+ warns you about many common errors, both functional and
+ stylistic. For a new (or repocopied) port,
+ <command>portlint -A</command> is the most thorough; for an
+ existing port, <command>portlint -C</command> is sufficient.</para>
+
+ <para>Since <command>portlint</command> 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;.</para>
+ </sect1>
+
+ <sect1 xml:id="testing-porttools">
+ <title>Port Tools</title>
+
+ <para>The <package>ports-mgmt/porttools</package>
+ program is part of the Ports Collection.</para>
+
+ <para><command>port</command> 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
+ <command>port test</command> to test your port, including the
+ <link linkend="testing-portlint"><command>portlint</command></link>
+ checking. This command also detects and lists any files that
+ are not listed in <filename>pkg-plist</filename>. See the
+ following example:</para>
+
+ <screen>&prompt.root; <userinput>port test /usr/ports/net/csup</userinput></screen>
+ </sect1>
+
+ <sect1 xml:id="porting-prefix">
+ <title><varname>PREFIX</varname> 以及 <varname>DESTDIR</varname></title>
+
+ <para><varname>PREFIX</varname> 變數會決定該 port 所會安裝的位置,
+ 通常是 <filename>/usr/local</filename> 或 <filename>/opt</filename>
+ 。 使用者可以藉由設定 <varname>PREFIX</varname> 決定要裝在哪邊,
+ 而你所維護的 port 必須遵循該規則。</para>
+
+ <para>若使用者有設定 <varname>DESTDIR</varname> 變數,
+ 那麼它會採用所設定的環境,通常可能是 jail 環境或者是並非掛載於
+ <filename>/</filename> 上的系統。 通常 port 會裝在
+ <varname>DESTDIR</varname>/<varname>PREFIX</varname> 底下,
+ 並且會紀錄在 <varname>DESTDIR</varname>/var/db/pkg 內的套件資料庫。
+ 由於事實上 <varname>DESTDIR</varname> 會由 ports 架構透過
+ &man.chroot.8; 來自動處理,所以您不需去作相關修改或刻意維護
+ <varname>DESTDIR</varname> 相容的 ports。</para>
+
+ <para><varname>PREFIX</varname> 變數若無特別設定,會與
+ <varname>LOCALBASE</varname> 相同 (預設為
+ <filename>/usr/local</filename>)。 若有設定
+ <varname>USE_LINUX_PREFIX</varname>,
+ 那麼 <varname>PREFIX</varname> 則為 <varname>LINUXBASE</varname> (
+ 預設為 <filename>/compat/linux</filename>)。</para>
+
+ <para>Avoiding the hard-coding of <filename>/usr/local</filename> or
+ <filename>/usr/X11R6</filename> 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 <command>imake</command>, this is
+ automatic; otherwise, this can often be done by simply replacing the
+ occurrences of <filename>/usr/local</filename> (or
+ <filename>/usr/X11R6</filename> for X ports that do not use imake)
+ in the various <filename>Makefile</filename>s in the port to read
+ <varname>${PREFIX}</varname>, as this variable is automatically passed
+ down to every stage of the build and install processes.</para>
+
+ <para>Make sure your application is not installing things in
+ <filename>/usr/local</filename> instead of <varname>PREFIX</varname>.
+ A quick test for this is to do this is:</para>
+
+ <screen>&prompt.root; <userinput>make clean; make package PREFIX=/var/tmp/port-name</userinput></screen>
+
+ <para>If anything is installed outside of <varname>PREFIX</varname>,
+ the package creation process will complain that it
+ cannot find the files.</para>
+
+ <!-- XXX This paragraph is confusing and poorly indented. -->
+ <para>This does not test for the existence of internal references,
+ or correct use of <varname>LOCALBASE</varname> for references to
+ files from other ports. Testing the installation in
+ <filename>/var/tmp/port-name</filename>
+ to do that while you have it installed would do that.</para>
+
+ <para>The variable <varname>PREFIX</varname> can be reassigned in your
+ <filename>Makefile</filename> or in the user's environment.
+ However, it is strongly discouraged for individual ports to set this
+ variable explicitly in the <filename>Makefile</filename>s.</para>
+
+ <para>Also, refer to programs/files from other ports with the
+ variables mentioned above, not explicit pathnames. For instance, if
+ your port requires a macro <literal>PAGER</literal> to be the full
+ pathname of <command>less</command>, use the compiler flag:
+
+ <programlisting>-DPAGER=\"&dollar;{LOCALBASE}/bin/less\"</programlisting>
+
+ instead of
+ <literal>-DPAGER=\"/usr/local/bin/less\"</literal>. This way it will
+ have a better chance of working if the system administrator has
+ moved the whole <filename>/usr/local</filename> tree somewhere else.</para>
+ </sect1>
+
+ <sect1 xml:id="testing-tinderbox">
+ <title>Tinderbox</title>
+
+ <para>If you're an avid ports contributor, you might want to take a
+ look at <application>Tinderbox</application>. It is a powerful
+ system for building and testing ports based on the scripts used on
+ <link linkend="build-cluster">Pointyhat</link>. You can install
+ <application>Tinderbox</application> using
+ <package>ports-mgmt/tinderbox</package> port. Be sure
+ to read supplied documentation since the configuration is not
+ trivial.</para>
+
+ <para>Visit the <link xlink:href="http://tinderbox.marcuscom.com/">Tinderbox website</link>
+ for more details.</para>
+
+ </sect1>
+ </chapter>
+
+ <chapter xml:id="port-upgrading">
+ <title>Upgrading</title>
+
+ <para>When 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
+ <filename>ports/ports-current</filename> 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
+ <application>CVSup</application> to keep your whole ports collection
+ up-to-date, as described in the
+ <link xlink:href="&url.books.handbook;/synching.html#CVSUP-CONFIG">Handbook</link>.
+ This will have the added benefit of tracking all the ports'
+ dependencies.</para>
+
+ <para>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
+ <link xlink:href="http://www.FreeBSD.org/cgi/query-pr-summary.cgi?query">
+ FreeBSD Problem Report (PR) database</link> (also known as
+ <literal>GNATS</literal>). Select <literal>ports</literal> in the
+ dropdown, and enter the name of the port.</para>
+
+ <para>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 <link linkend="portsmon">
+ FreeBSD Ports Monitoring System</link> (also known as
+ <literal>portsmon</literal>). This system attempts to classify
+ port PRs by portname. To search for PRs about a particular port,
+ use the <link xlink:href="http://portsmon.FreeBSD.org/portoverview.py">
+ Overview of One Port</link>.</para>
+
+ <para>If there is no pending PR, the next step is to send an email
+ to the port's maintainer, as shown by
+ <command>make maintainer</command>. 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
+ <literal>ports@FreeBSD.org</literal>, which is just the general
+ ports mailing list, so sending mail there
+ probably will not help in this case.</para>
+
+ <para>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 <command>diff</command> output
+ of the new and old
+ ports directories (e.g., if your modified port directory is
+ called <filename>superedit</filename> and the original is in our tree
+ as <filename>superedit.bak</filename>, then save the result of
+ <command>diff -ruN superedit.bak superedit</command>). Either
+ unified or context diff is fine, but port committers generally
+ prefer unified diffs. Note the use of the <literal>-N</literal>
+ option&mdash;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
+ <filename>/usr/ports/Tools/scripts/patchtool.py</filename>.
+ Before using it, please read
+ <filename>/usr/ports/Tools/scripts/README.patchtool</filename>.</para>
+
+ <para>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
+ <link xlink:href="&url.books.developers-handbook;/policies.html#POLICIES-MAINTAINER">
+ Developer's Handbook</link>.)</para>
+
+ <para>最好的方式是使用 &man.send-pr.1; 並附上 diff 一併回報(類別請選
+ <literal>ports</literal>)。 若你是該 port 的維護者,請記得在 synopsis
+ 那行的開頭註明 <literal>[maintainer update]</literal>,並且在 PR 的
+ <quote>Class</quote> 分類填上 <literal>maintainer-update</literal>。
+ 否則,該 PR 的 <quote>Class</quote> 處就是填
+ <literal>change-request</literal>。
+ 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.</para>
+
+ <para>Before you &man.send-pr.1;, you should review the
+ <link xlink:href="&url.articles.problem-reports;/pr-writing.html">
+ Writing the problem report</link> section in the Problem
+ Reports article; it contains far more information about how to write
+ useful problem reports.</para>
+
+ <important>
+ <para>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 <command>pkg_add -r</command> for several
+ weeks.</para>
+ </important>
+
+ <note>
+ <para>Once again, please use &man.diff.1; and not &man.shar.1; to send
+ updates to existing ports!</para>
+ </note>
+
+ <para>Now that you have done all that, you will want to read about
+ how to keep up-to-date in <xref linkend="keeping-up"/>.</para>
+
+ </chapter>
+
+ <chapter xml:id="security">
+ <title>Ports security</title>
+
+ <sect1 xml:id="security-intro">
+ <title>Why security is so important</title>
+
+ <para>Bugs 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.</para>
+
+ <para>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.</para>
+
+ <para>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.</para>
+ </sect1>
+
+ <sect1 xml:id="security-fix">
+ <title>Fixing security vulnerabilities</title>
+
+ <para>While 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 <link linkend="dads-noinstall">mark the port as
+ <varname>FORBIDDEN</varname></link>
+ 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, <link linkend="port-upgrading">the
+ standard procedure for submitting your change</link> should
+ be followed unless you have rights to commit it directly
+ to the ports tree.</para>
+
+ <important>
+ <para>Being a ports committer is not enough to commit to
+ an arbitrary port. Remember that ports usually have
+ maintainers, whom you should respect.</para>
+ </important>
+
+ <para>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.
+ <varname>PORTREVISION</varname> should be bumped unless
+ <varname>PORTVERSION</varname> has changed in the course
+ of correcting the vulnerability. That is you should
+ bump <varname>PORTREVISION</varname> 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 <varname>PORTVERSION</varname>. Please refer to the
+ <link linkend="makefile-naming-revepoch">corresponding section</link>
+ for more information.</para>
+ </sect1>
+
+ <sect1 xml:id="security-notify">
+ <title>Keeping the community informed</title>
+
+ <sect2 xml:id="security-notify-vuxml-db">
+ <title>The VuXML database</title>
+
+ <para>A 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 <emphasis>must</emphasis> update the package
+ without delay as soon as a corrected version is available.</para>
+
+ <para>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 <link xlink:href="http://vuxml.freebsd.org/">the FreeBSD VuXML
+ database</link>. The Security Officer Team members
+ are monitoring it for issues requiring their
+ intervention.</para>
+
+ <para>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 <link xlink:href="http://www.freebsd.org/security/#how">FreeBSD
+ Security Information</link> page.</para>
+
+ <para>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 <filename>vuln.xml</filename>
+ is kept right inside the port <package>security/vuxml</package>. Therefore
+ the file's full pathname will be
+ <filename>PORTSDIR/security/vuxml/vuln.xml</filename>.
+ 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.</para>
+ </sect2>
+
+ <sect2 xml:id="security-notify-vuxml-intro">
+ <title>A short introduction to VuXML</title>
+
+ <para>The 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
+ &lt;tag&gt; must have a matching closing &lt;/tag&gt;.
+ 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 e<emphasis>X</emphasis>tensible, 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.</para>
+
+ <para>Now let's consider a realistic VuXML entry:</para>
+
+ <programlisting>&lt;vuln vid="f4bc80f4-da62-11d8-90ea-0004ac98a7b9"&gt; <co xml:id="co-vx-vid"/>
+ &lt;topic&gt;Several vulnerabilities found in Foo&lt;/topic&gt; <co xml:id="co-vx-top"/>
+ &lt;affects&gt;
+ &lt;package&gt;
+ &lt;name&gt;foo&lt;/name&gt; <co xml:id="co-vx-nam"/>
+ &lt;name&gt;foo-devel&lt;/name&gt;
+ &lt;name&gt;ja-foo&lt;/name&gt;
+ &lt;range&gt;&lt;ge&gt;1.6&lt;/ge&gt;&lt;lt&gt;1.9&lt;/lt&gt;&lt;/range&gt; <co xml:id="co-vx-rng"/>
+ &lt;range&gt;&lt;ge&gt;2.*&lt;/ge&gt;&lt;lt&gt;2.4_1&lt;/lt&gt;&lt;/range&gt;
+ &lt;range&gt;&lt;eq&gt;3.0b1&lt;/eq&gt;&lt;/range&gt;
+ &lt;/package&gt;
+ &lt;package&gt;
+ &lt;name&gt;openfoo&lt;/name&gt; <co xml:id="co-vx-nm2"/>
+ &lt;range&gt;&lt;lt&gt;1.10_7&lt;/lt&gt;&lt;/range&gt; <co xml:id="co-vx-epo"/>
+ &lt;range&gt;&lt;ge&gt;1.2,1&lt;/ge&gt;&lt;lt&gt;1.3_1,1&lt;/lt&gt;&lt;/range&gt;
+ &lt;/package&gt;
+ &lt;/affects&gt;
+ &lt;description&gt;
+ &lt;body xmlns="http://www.w3.org/1999/xhtml"&gt;
+ &lt;p&gt;J. Random Hacker reports:&lt;/p&gt; <co xml:id="co-vx-bdy"/>
+ &lt;blockquote
+ cite="http://j.r.hacker.com/advisories/1"&gt;
+ &lt;p&gt;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.&lt;/p&gt;
+ &lt;/blockquote&gt;
+ &lt;/body&gt;
+ &lt;/description&gt;
+ &lt;references&gt; <co xml:id="co-vx-ref"/>
+ &lt;freebsdsa&gt;SA-10:75.foo&lt;/freebsdsa&gt; <co xml:id="co-vx-fsa"/>
+ &lt;freebsdpr&gt;ports/987654&lt;/freebsdpr&gt; <co xml:id="co-vx-fpr"/>
+ &lt;cvename&gt;CAN-2010-0201&lt;/cvename&gt; <co xml:id="co-vx-cve"/>
+ &lt;cvename&gt;CAN-2010-0466&lt;/cvename&gt;
+ &lt;bid&gt;96298&lt;/bid&gt; <co xml:id="co-vx-bid"/>
+ &lt;certsa&gt;CA-2010-99&lt;/certsa&gt; <co xml:id="co-vx-cts"/>
+ &lt;certvu&gt;740169&lt;/certvu&gt; <co xml:id="co-vx-ctv"/>
+ &lt;uscertsa&gt;SA10-99A&lt;/uscertsa&gt; <co xml:id="co-vx-ucs"/>
+ &lt;uscertta&gt;SA10-99A&lt;/uscertta&gt; <co xml:id="co-vx-uct"/>
+ &lt;mlist msgid="201075606@hacker.com"&gt;http://marc.theaimsgroup.com/?l=bugtraq&amp;amp;m=203886607825605&lt;/mlist&gt; <co xml:id="co-vx-mls"/>
+ &lt;url&gt;http://j.r.hacker.com/advisories/1&lt;/url&gt; <co xml:id="co-vx-url"/>
+ &lt;/references&gt;
+ &lt;dates&gt;
+ &lt;discovery&gt;2010-05-25&lt;/discovery&gt; <co xml:id="co-vx-dsc"/>
+ &lt;entry&gt;2010-07-13&lt;/entry&gt; <co xml:id="co-vx-ent"/>
+ &lt;modified&gt;2010-09-17&lt;/entry&gt; <co xml:id="co-vx-mod"/>
+ &lt;/dates&gt;
+&lt;/vuln&gt;</programlisting>
+
+ <para>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:</para>
+
+ <calloutlist>
+ <callout arearefs="co-vx-vid">
+ <para>This is the top-level tag of a VuXML entry. It has
+ a mandatory attribute, <literal>vid</literal>,
+ 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 <package>devel/p5-Data-UUID</package> and issue
+ the following command:</para>
+
+ <programlisting>perl -MData::UUID -le 'print lc new Data::UUID-&gt;create_str'</programlisting>
+ </callout>
+
+ <callout arearefs="co-vx-top">
+ <para>This is a one-line description of the issue found.</para>
+ </callout>
+
+ <callout arearefs="co-vx-nam">
+ <para>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.</para>
+
+ <important>
+ <para>It is your responsibility to find all such related
+ packages when writing a VuXML entry. Keep in mind that
+ <literal>make search name=foo</literal> is your friend.
+ The primary points to look for are as follows:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>the <filename>foo-devel</filename> variant
+ for a <filename>foo</filename> port;</para>
+ </listitem>
+
+ <listitem>
+ <para>other variants with a suffix like
+ <literal>-a4</literal> (for print-related packages),
+ <literal>-without-gui</literal> (for packages with X
+ support disabled), or similar;</para>
+ </listitem>
+
+ <listitem>
+ <para><literal>jp-</literal>, <literal>ru-</literal>,
+ <literal>zh-</literal>, and other possible localized
+ variants in the corresponding national categories of
+ the ports collection.</para>
+ </listitem>
+ </itemizedlist>
+ </important>
+ </callout>
+
+ <callout arearefs="co-vx-rng">
+ <para>Affected versions of the package(s) are specified
+ there as one or more ranges using a combination of
+ <literal>&lt;lt&gt;</literal>, <literal>&lt;le&gt;</literal>,
+ <literal>&lt;eq&gt;</literal>, <literal>&lt;ge&gt;</literal>,
+ and <literal>&lt;gt&gt;</literal> elements. The
+ version ranges given should not overlap.</para>
+
+ <para>In a range specification, <literal>*</literal> (asterisk)
+ denotes the smallest version number. In particular,
+ <literal>2.*</literal> is less than <literal>2.a</literal>.
+ Therefore an asterisk may be used for a range to match all
+ possible <literal>alpha</literal>, <literal>beta</literal>,
+ and <literal>RC</literal> versions. For instance,
+ <literal>&lt;ge&gt;2.*&lt;/ge&gt;&lt;lt&gt;3.*&lt;/lt&gt;</literal>
+ will selectively match every <literal>2.x</literal> version while
+ <literal>&lt;ge&gt;2.0&lt;/ge&gt;&lt;lt&gt;3.0&lt;/lt&gt;</literal>
+ will obviously not since the latter misses
+ <literal>2.r3</literal> and matches
+ <literal>3.b</literal>.</para>
+
+ <para>The above example
+ specifies that affected are versions from <literal>1.6</literal>
+ to <literal>1.9</literal> inclusive, versions
+ <literal>2.x</literal> before <literal>2.4_1</literal>,
+ and version <literal>3.0b1</literal>.</para>
+ </callout>
+
+ <callout arearefs="co-vx-nm2">
+ <para>Several related package groups (essentially, ports)
+ can be listed in the <literal>&lt;affected&gt;</literal>
+ 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
+ &lt;package&gt; section.</para>
+ </callout>
+
+ <callout arearefs="co-vx-epo">
+ <para>The version ranges should allow for
+ <varname>PORTEPOCH</varname> and
+ <varname>PORTREVISION</varname> if applicable.
+ Please remember that according to the collation rules,
+ a version with a non-zero <varname>PORTEPOCH</varname> is
+ greater than any version without
+ <varname>PORTEPOCH</varname>, e.g., <literal>3.0,1</literal>
+ is greater than <literal>3.1</literal> or even than
+ <literal>8.9</literal>.</para>
+ </callout>
+
+ <callout arearefs="co-vx-bdy">
+ <para>This is a summary of the issue.
+ XHTML is used in this field. At least enclosing
+ <literal>&lt;p&gt;</literal> and <literal>&lt;/p&gt;</literal>
+ should appear. More complex mark-up may be used, but only for
+ the sake of accuracy and clarity: No eye candy please.</para>
+ </callout>
+
+ <callout arearefs="co-vx-ref">
+ <para>This section contains references to relevant documents.
+ As many references as apply are encouraged.</para>
+ </callout>
+
+ <callout arearefs="co-vx-fsa">
+ <para>This is a
+ <link xlink:href="http://www.freebsd.org/security/#adv">FreeBSD
+ security advisory</link>.</para>
+ </callout>
+
+ <callout arearefs="co-vx-fpr">
+ <para>This is a
+ <link xlink:href="http://www.freebsd.org/support.html#gnats">FreeBSD
+ problem report</link>.</para>
+ </callout>
+
+ <callout arearefs="co-vx-cve">
+ <para>This is a <link xlink:href="http://www.cve.mitre.org/">Mitre
+ CVE</link> identifier.</para>
+ </callout>
+
+ <callout arearefs="co-vx-bid">
+ <para>This is a
+ <link xlink:href="http://www.securityfocus.com/bid">SecurityFocus
+ Bug ID</link>.</para>
+ </callout>
+
+ <callout arearefs="co-vx-cts">
+ <para>This is a
+ <link xlink:href="http://www.cert.org/">US-CERT</link>
+ security advisory.</para>
+ </callout>
+
+ <callout arearefs="co-vx-ctv">
+ <para>This is a
+ <link xlink:href="http://www.cert.org/">US-CERT</link>
+ vulnerability note.</para>
+ </callout>
+
+ <callout arearefs="co-vx-ucs">
+ <para>This is a
+ <link xlink:href="http://www.cert.org/">US-CERT</link>
+ Cyber Security Alert.</para>
+ </callout>
+
+ <callout arearefs="co-vx-uct">
+ <para>This is a
+ <link xlink:href="http://www.cert.org/">US-CERT</link>
+ Technical Cyber Security Alert.</para>
+ </callout>
+
+ <callout arearefs="co-vx-mls">
+ <para>This is a URL to an archived posting in a mailing list.
+ The attribute <literal>msgid</literal> is optional and
+ may specify the message ID of the posting.</para>
+ </callout>
+
+ <callout arearefs="co-vx-url">
+ <para>This is a generic URL. It should be used only if none of
+ the other reference categories apply.</para>
+ </callout>
+
+ <callout arearefs="co-vx-dsc">
+ <para>This is the date when the issue was disclosed
+ (<replaceable>YYYY-MM-DD</replaceable>).</para>
+ </callout>
+
+ <callout arearefs="co-vx-ent">
+ <para>This is the date when the entry was added
+ (<replaceable>YYYY-MM-DD</replaceable>).</para>
+ </callout>
+
+ <callout arearefs="co-vx-mod">
+ <para>This is the date when any information in the entry
+ was last modified (<replaceable>YYYY-MM-DD</replaceable>).
+ New entries must not include this field. It should be added
+ upon editing an existing entry.</para>
+ </callout>
+ </calloutlist>
+ </sect2>
+
+ <sect2 xml:id="security-notify-vuxml-testing">
+ <title>Testing your changes to the VuXML database</title>
+
+ <para>Assume you just wrote or filled in an entry for a
+ vulnerability in the package <literal>clamav</literal>
+ that has been fixed in version <literal>0.65_7</literal>.</para>
+
+ <para>As a prerequisite, you need to install fresh versions of the
+ ports <package>ports-mgmt/portaudit</package> and
+ <package>ports-mgmt/portaudit-db</package>.</para>
+
+ <para>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,
+ <literal>0.65_6</literal>:</para>
+
+ <screen>&prompt.user; <userinput>packaudit</userinput>
+&prompt.user; <userinput>portaudit clamav-0.65_6</userinput></screen>
+
+ <note>
+ <para>To run <command>packaudit</command>, you must have
+ permission to write to its
+ <filename>DATABASEDIR</filename>,
+ typically <filename>/var/db/portaudit</filename>.</para>
+ </note>
+
+ <para>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
+ <literal>74a9541d-5d6c-11d8-80e3-0020ed76ef5a</literal>) and
+ add your new entry to the VuXML database. Please verify
+ its syntax after that as follows:</para>
+
+ <screen>&prompt.user; <userinput>cd ${PORTSDIR}/security/vuxml &amp;&amp; make validate</userinput></screen>
+
+ <note>
+ <para>You will need at least one of the following packages
+ installed: <package>textproc/libxml2</package>,
+ <package>textproc/jade</package>.</para>
+ </note>
+
+ <para>Now rebuild the <command>portaudit</command> database
+ from the VuXML file:</para>
+
+ <screen>&prompt.user; <userinput>packaudit</userinput></screen>
+
+ <para>To verify that the <literal>&lt;affected&gt;</literal>
+ section of your entry will match correct package(s), issue
+ the following command:</para>
+
+ <screen>&prompt.user; <userinput>portaudit -f /usr/ports/INDEX -r 74a9541d-5d6c-11d8-80e3-0020ed76ef5a</userinput></screen>
+
+ <note>
+ <para>Please refer to &man.portaudit.1; for better understanding
+ of the command syntax.</para>
+ </note>
+
+ <para>Make sure that your entry produces no spurious matches
+ in the output.</para>
+
+ <para>Now check whether the right package versions are matched
+ by your entry:</para>
+
+ <screen>&prompt.user; <userinput>portaudit clamav-0.65_6 clamav-0.65_7</userinput>
+Affected package: clamav-0.65_6 (matched by clamav&lt;0.65_7)
+Type of problem: clamav remote denial-of-service.
+Reference: &lt;http://www.freebsd.org/ports/portaudit/74a9541d-5d6c-11d8-80e3-0020ed76ef5a.html&gt;
+
+1 problem(s) found.</screen>
+
+ <para>Obviously, the former version should match while the
+ latter one should not.</para>
+
+ <para>Finally, verify whether the web page generated from the
+ VuXML database looks like expected:</para>
+
+ <screen>&prompt.user; <userinput>mkdir -p ~/public_html/portaudit</userinput>
+&prompt.user; <userinput>packaudit</userinput>
+&prompt.user; <userinput>lynx ~/public_html/portaudit/74a9541d-5d6c-11d8-80e3-0020ed76ef5a.html</userinput></screen>
+ </sect2>
+
+ </sect1>
+ </chapter>
+
+ <chapter xml:id="porting-dads">
+ <title>Dos and Don'ts</title>
+
+ <sect1 xml:id="dads-intro">
+ <title>Introduction</title>
+
+ <para>Here 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 <link xlink:href="http://www.FreeBSD.org/cgi/query-pr-summary.cgi?query">PR database</link> that others have
+ submitted. Submit any comments on ports you check as described in
+ <link xlink:href="&url.articles.contributing;/contrib-how.html#CONTRIB-GENERAL">Bug Reports and General
+ Commentary</link>. 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.</para>
+ </sect1>
+
+ <sect1 xml:id="porting-wrkdir">
+ <title><varname>WRKDIR</varname></title>
+
+ <para>Do not write anything to files outside
+ <varname>WRKDIR</varname>. <varname>WRKDIR</varname> is the only
+ place that is guaranteed to be writable during the port build (see
+ <link xlink:href="&url.books.handbook;/ports-using.html#PORTS-CD">
+ installing ports from a CDROM</link> for an
+ example of building ports from a read-only tree). If you need to
+ modify one of the <filename>pkg-*</filename>
+ files, do so by <link linkend="porting-pkgfiles">redefining a variable</link>, not by
+ writing over it.</para>
+ </sect1>
+
+ <sect1 xml:id="porting-wrkdirprefix">
+ <title><varname>WRKDIRPREFIX</varname></title>
+
+ <para>Make sure your port honors <varname>WRKDIRPREFIX</varname>.
+ Most ports do not have to worry about this. In particular, if you
+ are referring to a <varname>WRKDIR</varname> of another port, note
+ that the correct location is
+ <filename>WRKDIRPREFIXPORTSDIR/subdir/name/work</filename> not <filename>PORTSDIR/subdir/name/work</filename> or <filename>.CURDIR/../../subdir/name/work</filename> or some such.</para>
+
+ <para>Also, if you are defining <varname>WRKDIR</varname> yourself,
+ make sure you prepend
+ <literal>&dollar;{WRKDIRPREFIX}&dollar;{.CURDIR}</literal> in the
+ front.</para>
+ </sect1>
+
+ <sect1 xml:id="porting-versions">
+ <title>Differentiating operating systems and OS versions</title>
+
+ <para>You 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.</para>
+
+ <para>The preferred way to tell 4.3BSD/Reno (1990) and newer versions
+ of the BSD code apart is by using the <literal>BSD</literal> macro
+ defined in
+ <link xlink:href="http://cvsweb.freebsd.org/src/sys/sys/param.h">sys/param.h</link>.
+ Hopefully that
+ file is already included; if not, add the code:</para>
+
+ <programlisting>#if (defined(__unix__) || defined(unix)) &amp;&amp; !defined(USG)
+#include &lt;sys/param.h&gt;
+#endif</programlisting>
+
+ <para>to the proper place in the <filename>.c</filename> file. We
+ believe that every system that defines these two symbols has
+ <filename>sys/param.h</filename>. If you find a system that
+ does not, we would like to know. Please send mail to the
+ &a.ports;.</para>
+
+ <para>Another way is to use the GNU Autoconf style of doing
+ this:</para>
+
+ <programlisting>#ifdef HAVE_SYS_PARAM_H
+#include &lt;sys/param.h&gt;
+#endif</programlisting>
+
+ <para>Do not forget to add <literal>-DHAVE_SYS_PARAM_H</literal> to the
+ <varname>CFLAGS</varname> in the <filename>Makefile</filename> for
+ this method.</para>
+
+ <para>Once you have <filename>sys/param.h</filename> included, you may
+ use:</para>
+
+ <programlisting>#if (defined(BSD) &amp;&amp; (BSD &gt;= 199103))</programlisting>
+
+ <para>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).</para>
+
+ <para>Use:</para>
+
+ <programlisting>#if (defined(BSD) &amp;&amp; (BSD &gt;= 199306))</programlisting>
+
+ <para>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).</para>
+
+ <para>The value of the <literal>BSD</literal> macro is
+ <literal>199506</literal> 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
+ <literal>__FreeBSD__</literal> macro should be used instead.</para>
+
+ <para>Use sparingly:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para><literal>__FreeBSD__</literal> is defined in all versions of
+ FreeBSD. Use it if the change you are making
+ <emphasis>only</emphasis> affects FreeBSD. Porting gotchas like
+ the use of <literal>sys_errlist[]</literal> vs
+ <function>strerror()</function> are Berkeley-isms, not FreeBSD
+ changes.</para>
+ </listitem>
+
+ <listitem>
+ <para>In FreeBSD 2.x, <literal>__FreeBSD__</literal> is defined to
+ be <literal>2</literal>. In earlier versions, it is
+ <literal>1</literal>. Later versions always bump it to match
+ their major version number.</para>
+ </listitem>
+
+ <listitem>
+ <para>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 <literal>BSD</literal> macros described above. If
+ there actually is a FreeBSD specific change (such as special
+ shared library options when using <command>ld</command>) then it
+ is OK to use <literal>__FreeBSD__</literal> and <literal>#if
+ __FreeBSD__ &gt; 1</literal> 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:</para>
+
+ <programlisting>#if __FreeBSD__ &gt;= 2
+#include &lt;osreldate.h&gt;
+# if __FreeBSD_version &gt;= 199504
+ /* 2.0.5+ release specific code here */
+# endif
+#endif</programlisting>
+ </listitem>
+ </itemizedlist>
+
+ <para>In the hundreds of ports that have been done, there have only
+ been one or two cases where <literal>__FreeBSD__</literal> 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.</para>
+ </sect1>
+
+ <sect1 xml:id="freebsd-versions">
+ <title>FreeBSD 版本速查表(__FreeBSD_version)</title>
+
+ <para>以下是 <link xlink:href="http://cvsweb.freebsd.org/src/sys/sys/param.h">sys/param.h</link> 內的 <literal>__FreeBSD_version</literal> 版本速查表:</para>
+
+ <table frame="none">
+ <title>__FreeBSD_version values</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Release</entry>
+ <entry><literal>__FreeBSD_version</literal></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>2.0-RELEASE</entry>
+ <entry>119411</entry>
+ </row>
+
+ <row>
+ <entry>2.1-CURRENT</entry>
+ <entry>199501, 199503</entry>
+ </row>
+
+ <row>
+ <entry>2.0.5-RELEASE</entry>
+ <entry>199504</entry>
+ </row>
+
+ <row>
+ <entry>2.2-CURRENT before 2.1</entry>
+ <entry>199508</entry>
+ </row>
+
+ <row>
+ <entry>2.1.0-RELEASE</entry>
+ <entry>199511</entry>
+ </row>
+
+ <row>
+ <entry>2.2-CURRENT before 2.1.5</entry>
+ <entry>199512</entry>
+ </row>
+
+ <row>
+ <entry>2.1.5-RELEASE</entry>
+ <entry>199607</entry>
+ </row>
+
+ <row>
+ <entry>2.2-CURRENT before 2.1.6</entry>
+ <entry>199608</entry>
+ </row>
+
+ <row>
+ <entry>2.1.6-RELEASE</entry>
+ <entry>199612</entry>
+ </row>
+
+ <row>
+ <entry>2.1.7-RELEASE</entry>
+ <entry>199612</entry>
+ </row>
+
+ <row>
+ <entry>2.2-RELEASE</entry>
+ <entry>220000</entry>
+ </row>
+
+ <row>
+ <entry>2.2.1-RELEASE</entry>
+ <entry>220000 (no change)</entry>
+ </row>
+
+ <row>
+ <entry>2.2-STABLE after 2.2.1-RELEASE</entry>
+ <entry>220000 (no change)</entry>
+ </row>
+
+ <row>
+ <entry>2.2-STABLE after texinfo-3.9</entry>
+ <entry>221001</entry>
+ </row>
+
+ <row>
+ <entry>2.2-STABLE after top</entry>
+ <entry>221002</entry>
+ </row>
+
+ <row>
+ <entry>2.2.2-RELEASE</entry>
+ <entry>222000</entry>
+ </row>
+
+ <row>
+ <entry>2.2-STABLE after 2.2.2-RELEASE</entry>
+ <entry>222001</entry>
+ </row>
+
+ <row>
+ <entry>2.2.5-RELEASE</entry>
+ <entry>225000</entry>
+ </row>
+
+ <row>
+ <entry>2.2-STABLE after 2.2.5-RELEASE</entry>
+ <entry>225001</entry>
+ </row>
+
+ <row>
+ <entry>2.2-STABLE after ldconfig -R merge</entry>
+ <entry>225002</entry>
+ </row>
+
+ <row>
+ <entry>2.2.6-RELEASE</entry>
+ <entry>226000</entry>
+ </row>
+
+ <row>
+ <entry>2.2.7-RELEASE</entry>
+ <entry>227000</entry>
+ </row>
+
+ <row>
+ <entry>2.2-STABLE after 2.2.7-RELEASE</entry>
+ <entry>227001</entry>
+ </row>
+
+ <row>
+ <entry>2.2-STABLE after &man.semctl.2; change</entry>
+ <entry>227002</entry>
+ </row>
+
+ <row>
+ <entry>2.2.8-RELEASE</entry>
+ <entry>228000</entry>
+ </row>
+
+ <row>
+ <entry>2.2-STABLE after 2.2.8-RELEASE</entry>
+ <entry>228001</entry>
+ </row>
+
+ <row>
+ <entry>3.0-CURRENT before &man.mount.2; change</entry>
+ <entry>300000</entry>
+ </row>
+
+ <row>
+ <entry>3.0-CURRENT after &man.mount.2; change</entry>
+ <entry>300001</entry>
+ </row>
+
+ <row>
+ <entry>3.0-CURRENT after &man.semctl.2; change</entry>
+ <entry>300002</entry>
+ </row>
+
+ <row>
+ <entry>3.0-CURRENT after ioctl arg changes</entry>
+ <entry>300003</entry>
+ </row>
+
+ <row>
+ <entry>3.0-CURRENT after ELF conversion</entry>
+ <entry>300004</entry>
+ </row>
+
+ <row>
+ <entry>3.0-RELEASE</entry>
+ <entry>300005</entry>
+ </row>
+
+ <row>
+ <entry>3.0-CURRENT after 3.0-RELEASE</entry>
+ <entry>300006</entry>
+ </row>
+
+ <row>
+ <entry>3.0-STABLE after 3/4 branch</entry>
+ <entry>300007</entry>
+ </row>
+
+ <row>
+ <entry>3.1-RELEASE</entry>
+ <entry>310000</entry>
+ </row>
+
+ <row>
+ <entry>3.1-STABLE after 3.1-RELEASE</entry>
+ <entry>310001</entry>
+ </row>
+
+ <row>
+ <entry>3.1-STABLE after C++ constructor/destructor order
+ change</entry>
+ <entry>310002</entry>
+ </row>
+
+ <row>
+ <entry>3.2-RELEASE</entry>
+ <entry>320000</entry>
+ </row>
+
+ <row>
+ <entry>3.2-STABLE</entry>
+ <entry>320001</entry>
+ </row>
+
+ <row>
+ <entry>3.2-STABLE after binary-incompatible IPFW and
+ socket changes</entry>
+ <entry>320002</entry>
+ </row>
+
+ <row>
+ <entry>3.3-RELEASE</entry>
+ <entry>330000</entry>
+ </row>
+
+ <row>
+ <entry>3.3-STABLE</entry>
+ <entry>330001</entry>
+ </row>
+
+ <row>
+ <entry>3.3-STABLE after adding &man.mkstemp.3;
+ to libc</entry>
+ <entry>330002</entry>
+ </row>
+
+ <row>
+ <entry>3.4-RELEASE</entry>
+ <entry>340000</entry>
+ </row>
+
+ <row>
+ <entry>3.4-STABLE</entry>
+ <entry>340001</entry>
+ </row>
+
+ <row>
+ <entry>3.5-RELEASE</entry>
+ <entry>350000</entry>
+ </row>
+
+ <row>
+ <entry>3.5-STABLE</entry>
+ <entry>350001</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after 3.4 branch</entry>
+ <entry>400000</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after change in dynamic linker
+ handling</entry>
+ <entry>400001</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after C++ constructor/destructor
+ order change</entry>
+ <entry>400002</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after functioning &man.dladdr.3;</entry>
+ <entry>400003</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after __deregister_frame_info dynamic
+ linker bug fix (also 4.0-CURRENT after EGCS 1.1.2
+ integration)
+ </entry>
+ <entry>400004</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after &man.suser.9; API change
+ (also 4.0-CURRENT after newbus)</entry>
+ <entry>400005</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after cdevsw registration change</entry>
+ <entry>400006</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after the addition of so_cred for
+ socket level credentials</entry>
+ <entry>400007</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after the addition of a poll syscall
+ wrapper to libc_r</entry>
+ <entry>400008</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after the change of the kernel's
+ <literal>dev_t</literal> type to <literal>struct
+ specinfo</literal> pointer</entry>
+ <entry>400009</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after fixing a hole
+ in &man.jail.2;</entry>
+ <entry>400010</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after the <literal>sigset_t</literal>
+ datatype change</entry>
+ <entry>400011</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after the cutover to the GCC 2.95.2
+ compiler</entry>
+ <entry>400012</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after adding pluggable linux-mode
+ ioctl handlers</entry>
+ <entry>400013</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after importing OpenSSL</entry>
+ <entry>400014</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after the C++ ABI change in GCC 2.95.2
+ from -fvtable-thunks to -fno-vtable-thunks by
+ default</entry>
+ <entry>400015</entry>
+ </row>
+
+ <row>
+ <entry>4.0-CURRENT after importing OpenSSH</entry>
+ <entry>400016</entry>
+ </row>
+
+ <row>
+ <entry>4.0-RELEASE</entry>
+ <entry>400017</entry>
+ </row>
+
+ <row>
+ <entry>4.0-STABLE after 4.0-RELEASE</entry>
+ <entry>400018</entry>
+ </row>
+
+ <row>
+ <entry>4.0-STABLE after the introduction of delayed
+ checksums.</entry>
+ <entry>400019</entry>
+ </row>
+
+ <row>
+ <entry>4.0-STABLE after merging libxpg4 code into
+ libc.</entry>
+ <entry>400020</entry>
+ </row>
+
+ <row>
+ <entry>4.0-STABLE after upgrading Binutils to 2.10.0, ELF
+ branding changes, and tcsh in the base system.</entry>
+ <entry>400021</entry>
+ </row>
+
+ <row>
+ <entry>4.1-RELEASE</entry>
+ <entry>410000</entry>
+ </row>
+
+ <row>
+ <entry>4.1-STABLE after 4.1-RELEASE</entry>
+ <entry>410001</entry>
+ </row>
+
+ <row>
+ <entry>4.1-STABLE after &man.setproctitle.3; moved from
+ libutil to libc.</entry>
+ <entry>410002</entry>
+ </row>
+
+ <row>
+ <entry>4.1.1-RELEASE</entry>
+ <entry>411000</entry>
+ </row>
+
+ <row>
+ <entry>4.1.1-STABLE after 4.1.1-RELEASE</entry>
+ <entry>411001</entry>
+ </row>
+
+ <row>
+ <entry>4.2-RELEASE</entry>
+ <entry>420000</entry>
+ </row>
+
+ <row>
+ <entry>4.2-STABLE after combining libgcc.a and
+ libgcc_r.a, and associated GCC linkage changes.</entry>
+ <entry>420001</entry>
+ </row>
+
+ <row>
+ <entry>4.3-RELEASE</entry>
+ <entry>430000</entry>
+ </row>
+
+ <row>
+ <entry>4.3-STABLE after wint_t introduction.</entry>
+ <entry>430001</entry>
+ </row>
+
+ <row>
+ <entry>4.3-STABLE after PCI powerstate API merge.</entry>
+ <entry>430002</entry>
+ </row>
+
+ <row>
+ <entry>4.4-RELEASE</entry>
+ <entry>440000</entry>
+ </row>
+
+ <row>
+ <entry>4.4-STABLE after d_thread_t introduction.</entry>
+ <entry>440001</entry>
+ </row>
+
+ <row>
+ <entry>4.4-STABLE after mount structure changes (affects
+ filesystem klds).</entry>
+ <entry>440002</entry>
+ </row>
+
+ <row>
+ <entry>4.4-STABLE after the userland components of smbfs
+ were imported.</entry>
+ <entry>440003</entry>
+ </row>
+
+ <row>
+ <entry>4.5-RELEASE</entry>
+ <entry>450000</entry>
+ </row>
+
+ <row>
+ <entry>4.5-STABLE after the usb structure element rename.</entry>
+ <entry>450001</entry>
+ </row>
+
+ <row>
+ <entry>4.5-STABLE after the
+ <literal>sendmail_enable</literal> &man.rc.conf.5;
+ variable was made to take the value
+ <literal>NONE</literal>.</entry>
+ <entry>450004</entry>
+ </row>
+
+ <row>
+ <entry>4.5-STABLE after moving to XFree86 4 by default
+ for package builds.</entry>
+ <entry>450005</entry>
+ </row>
+
+ <row>
+ <entry>4.5-STABLE after accept filtering was fixed so
+ that is no longer susceptible to an easy DoS.</entry>
+ <entry>450006</entry>
+ </row>
+
+ <row>
+ <entry>4.6-RELEASE</entry>
+ <entry>460000</entry>
+ </row>
+
+ <row>
+ <entry>4.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.</entry>
+ <entry>460001</entry>
+ </row>
+
+ <row>
+ <entry>4.6.2-RELEASE</entry>
+ <entry>460002</entry>
+ </row>
+
+ <row>
+ <entry>4.6-STABLE</entry>
+ <entry>460100</entry>
+ </row>
+
+ <row>
+ <entry>4.6-STABLE after MFC of `sed -i'.</entry>
+ <entry>460101</entry>
+ </row>
+
+ <row>
+ <entry>4.6-STABLE after MFC of many new pkg_install
+ features from the HEAD.</entry>
+ <entry>460102</entry>
+ </row>
+
+ <row>
+ <entry>4.7-RELEASE</entry>
+ <entry>470000</entry>
+ </row>
+
+ <row>
+ <entry>4.7-STABLE</entry>
+ <entry>470100</entry>
+ </row>
+
+ <row>
+ <entry>Start 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.</entry>
+ <entry>470101</entry>
+ </row>
+
+ <row>
+ <entry>4.7-STABLE after MFC of mbuf changes to replace
+ m_aux mbufs by m_tag's</entry>
+ <entry>470102</entry>
+ </row>
+
+ <row>
+ <entry>4.7-STABLE gets OpenSSL 0.9.7</entry>
+ <entry>470103</entry>
+ </row>
+
+ <row>
+ <entry>4.8-RELEASE</entry>
+ <entry>480000</entry>
+ </row>
+
+ <row>
+ <entry>4.8-STABLE</entry>
+ <entry>480100</entry>
+ </row>
+
+ <row>
+ <entry>4.8-STABLE after &man.realpath.3; has been made
+ thread-safe</entry>
+ <entry>480101</entry>
+ </row>
+
+ <row>
+ <entry>4.8-STABLE 3ware API changes to twe.</entry>
+ <entry>480102</entry>
+ </row>
+
+ <row>
+ <entry>4.9-RELEASE</entry>
+ <entry>490000</entry>
+ </row>
+
+ <row>
+ <entry>4.9-STABLE</entry>
+ <entry>490100</entry>
+ </row>
+
+ <row>
+ <entry>4.9-STABLE after e_sid was added to struct
+ kinfo_eproc.</entry>
+ <entry>490101</entry>
+ </row>
+
+ <row>
+ <entry>4.9-STABLE after MFC of libmap functionality
+ for rtld.</entry>
+ <entry>490102</entry>
+ </row>
+
+ <row>
+ <entry>4.10-RELEASE</entry>
+ <entry>491000</entry>
+ </row>
+
+ <row>
+ <entry>4.10-STABLE</entry>
+ <entry>491100</entry>
+ </row>
+
+ <row>
+ <entry>4.10-STABLE after MFC of revision 20040629 of
+ the package tools</entry>
+ <entry>491101</entry>
+ </row>
+
+ <row>
+ <entry>4.10-STABLE after VM fix dealing with unwiring
+ of fictitious pages</entry>
+ <entry>491102</entry>
+ </row>
+
+ <row>
+ <entry>4.11-RELEASE</entry>
+ <entry>492000</entry>
+ </row>
+
+ <row>
+ <entry>4.11-STABLE</entry>
+ <entry>492100</entry>
+ </row>
+
+ <row>
+ <entry>4.11-STABLE after adding libdata/ldconfig directories
+ to mtree files.</entry>
+ <entry>492101</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT</entry>
+ <entry>500000</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after adding addition ELF header fields,
+ and changing our ELF binary branding method.</entry>
+ <entry>500001</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after kld metadata changes.</entry>
+ <entry>500002</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after buf/bio changes.</entry>
+ <entry>500003</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after binutils upgrade.</entry>
+ <entry>500004</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after merging libxpg4 code into
+ libc and after TASKQ interface introduction.</entry>
+ <entry>500005</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after the addition of AGP
+ interfaces.</entry>
+ <entry>500006</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after Perl upgrade to 5.6.0</entry>
+ <entry>500007</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after the update of KAME code to
+ 2000/07 sources.</entry>
+ <entry>500008</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after ether_ifattach() and
+ ether_ifdetach() changes.</entry>
+ <entry>500009</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after changing mtree defaults
+ back to original variant, adding -L to follow
+ symlinks.</entry>
+ <entry>500010</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after kqueue API changed.</entry>
+ <entry>500011</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after &man.setproctitle.3; moved from
+ libutil to libc.</entry>
+ <entry>500012</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after the first SMPng commit.</entry>
+ <entry>500013</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after &lt;sys/select.h&gt; moved to
+ &lt;sys/selinfo.h&gt;.</entry>
+ <entry>500014</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after combining libgcc.a and
+ libgcc_r.a, and associated GCC linkage changes.</entry>
+ <entry>500015</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after change allowing libc and libc_r
+ to be linked together, deprecating -pthread
+ option.</entry>
+ <entry>500016</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after switch from struct ucred to
+ struct xucred to stabilize kernel-exported API for
+ mountd et al.</entry>
+ <entry>500017</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after addition of CPUTYPE make variable
+ for controlling CPU-specific optimizations.</entry>
+ <entry>500018</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after moving machine/ioctl_fd.h to
+ sys/fdcio.h</entry>
+ <entry>500019</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after locale names renaming.</entry>
+ <entry>500020</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after Bzip2 import.
+ Also signifies removal of S/Key.</entry>
+ <entry>500021</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after SSE support.</entry>
+ <entry>500022</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after KSE Milestone 2.</entry>
+ <entry>500023</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after d_thread_t,
+ and moving UUCP to ports.</entry>
+ <entry>500024</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after ABI change for descriptor
+ and creds passing on 64 bit platforms.</entry>
+ <entry>500025</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after moving to XFree86 4 by default for
+ package builds, and after the new libc strnstr() function
+ was added.</entry>
+ <entry>500026</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after the new libc strcasestr() function
+ was added.</entry>
+ <entry>500027</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after the userland components of smbfs
+ were imported.</entry>
+ <entry>500028</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after the new C99 specific-width
+ integer types were added.</entry>
+ <entry>(Not incremented.)</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after a change was made in the return
+ value of &man.sendfile.2;.</entry>
+ <entry>500029</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after the introduction of the
+ type <literal>fflags_t</literal>, which is the
+ appropriate size for file flags.</entry>
+ <entry>500030</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after the usb structure element rename.</entry>
+ <entry>500031</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after the introduction of
+ Perl 5.6.1.</entry>
+ <entry>500032</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after the
+ <literal>sendmail_enable</literal> &man.rc.conf.5;
+ variable was made to take the value
+ <literal>NONE</literal>.</entry>
+ <entry>500033</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after mtx_init() grew a third argument.</entry>
+ <entry>500034</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT with Gcc 3.1.</entry>
+ <entry>500035</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT without Perl in /usr/src</entry>
+ <entry>500036</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after the addition of &man.dlfunc.3;</entry>
+ <entry>500037</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after the types of some struct
+ sockbuf members were changed and the structure was
+ reordered.</entry>
+ <entry>500038</entry>
+ </row>
+
+ <row>
+ <entry>5.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.</entry>
+ <entry>500039</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after various changes to disk functions
+ were made in the name of removing dependency on disklabel
+ structure internals.</entry>
+ <entry>500040</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after the addition of &man.getopt.long.3;
+ to libc.</entry>
+ <entry>500041</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after Binutils 2.13 upgrade, which
+ included new FreeBSD emulation, vec, and output format.
+ </entry>
+ <entry>500042</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after adding weak pthread_XXX stubs
+ to libc, obsoleting libXThrStub.so. 5.0-RELEASE.</entry>
+ <entry>500043</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after branching for RELENG_5_0</entry>
+ <entry>500100</entry>
+ </row>
+
+ <row>
+ <entry>&lt;sys/dkstat.h&gt; is empty and should
+ not be included.</entry>
+ <entry>500101</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after the d_mmap_t interface
+ change.</entry>
+ <entry>500102</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after taskqueue_swi changed to run
+ without Giant, and taskqueue_swi_giant added to run
+ with Giant.</entry>
+ <entry>500103</entry>
+ </row>
+
+ <row>
+ <entry>cdevsw_add() and cdevsw_remove() no
+ longer exists.
+ Appearance of MAJOR_AUTO allocation facility.</entry>
+ <entry>500104</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after new cdevsw initialization method.</entry>
+ <entry>500105</entry>
+ </row>
+
+ <row>
+ <entry>devstat_add_entry() has been replaced by
+ devstat_new_entry()</entry>
+ <entry>500106</entry>
+ </row>
+
+ <row>
+ <entry>Devstat interface change; see sys/sys/param.h 1.149</entry>
+ <entry>500107</entry>
+ </row>
+
+ <row>
+ <entry>Token-Ring interface changes.</entry>
+ <entry>500108</entry>
+ </row>
+
+ <row>
+ <entry>Addition of vm_paddr_t.</entry>
+ <entry>500109</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after &man.realpath.3; has been made
+ thread-safe</entry>
+ <entry>500110</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after &man.usbhid.3; has been synced with
+ NetBSD</entry>
+ <entry>500111</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after new NSS implementation
+ and addition of POSIX.1 getpw*_r, getgr*_r
+ functions</entry>
+ <entry>500112</entry>
+ </row>
+
+ <row>
+ <entry>5.0-CURRENT after removal of the old rc system.</entry>
+ <entry>500113</entry>
+ </row>
+
+ <row>
+ <entry>5.1-RELEASE.</entry>
+ <entry>501000</entry>
+ </row>
+
+ <row>
+ <entry>5.1-CURRENT after branching for RELENG_5_1.</entry>
+ <entry>501100</entry>
+ </row>
+
+ <row>
+ <entry>5.1-CURRENT after correcting the semantics of
+ sigtimedwait(2) and sigwaitinfo(2).</entry>
+ <entry>501101</entry>
+ </row>
+
+ <row>
+ <entry>5.1-CURRENT after adding the lockfunc and lockfuncarg
+ fields to &man.bus.dma.tag.create.9;.</entry>
+ <entry>501102</entry>
+ </row>
+
+ <row>
+ <entry>5.1-CURRENT after GCC 3.3.1-pre 20030711 snapshot
+ integration.</entry>
+ <entry>501103</entry>
+ </row>
+
+ <row>
+ <entry>5.1-CURRENT 3ware API changes to twe.</entry>
+ <entry>501104</entry>
+ </row>
+
+ <row>
+ <entry>5.1-CURRENT dynamically-linked /bin and /sbin
+ support and movement of libraries to /lib.</entry>
+ <entry>501105</entry>
+ </row>
+
+ <row>
+ <entry>5.1-CURRENT after adding kernel support for
+ Coda 6.x.</entry>
+ <entry>501106</entry>
+ </row>
+
+ <row>
+ <entry>5.1-CURRENT after 16550 UART constants moved from
+ <filename>&lt;dev/sio/sioreg.h&gt;</filename> to
+ <filename>&lt;dev/ic/ns16550.h&gt;</filename>.
+ Also when libmap functionality was unconditionally
+ supported by rtld.</entry>
+ <entry>501107</entry>
+ </row>
+
+ <row>
+ <entry>5.1-CURRENT after PFIL_HOOKS API update</entry>
+ <entry>501108</entry>
+ </row>
+
+ <row>
+ <entry>5.1-CURRENT after adding kiconv(3)</entry>
+ <entry>501109</entry>
+ </row>
+
+ <row>
+ <entry>5.1-CURRENT after changing default operations
+ for open and close in cdevsw</entry>
+ <entry>501110</entry>
+ </row>
+
+ <row>
+ <entry>5.1-CURRENT after changed layout of cdevsw</entry>
+ <entry>501111</entry>
+ </row>
+
+ <row>
+ <entry> 5.1-CURRENT after adding kobj multiple inheritance
+ </entry>
+ <entry>501112</entry>
+ </row>
+
+ <row>
+ <entry> 5.1-CURRENT after the if_xname change in
+ struct ifnet</entry>
+ <entry>501113</entry>
+ </row>
+
+ <row>
+ <entry> 5.1-CURRENT after changing /bin and /sbin to
+ be dynamically linked</entry>
+ <entry>501114</entry>
+ </row>
+
+ <row>
+ <entry>5.2-RELEASE</entry>
+ <entry>502000</entry>
+ </row>
+
+ <row>
+ <entry>5.2.1-RELEASE</entry>
+ <entry>502010</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after branching for RELENG_5_2</entry>
+ <entry>502100</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after __cxa_atexit/__cxa_finalize
+ functions were added to libc.</entry>
+ <entry>502101</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after change of default thread library
+ from libc_r to libpthread.</entry>
+ <entry>502102</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after device driver API megapatch.
+ </entry>
+ <entry>502103</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after getopt_long_only() addition.
+ </entry>
+ <entry>502104</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after NULL is made into ((void *)0)
+ for C, creating more warnings.
+ </entry>
+ <entry>502105</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after pf is linked to the build and
+ install.
+ </entry>
+ <entry>502106</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after time_t is changed to a
+ 64-bit value on sparc64.
+ </entry>
+ <entry>502107</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after Intel C/C++ compiler support in some headers and execve(2) changes to be more strictly conforming to POSIX.
+ </entry>
+ <entry>502108</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after the introduction of the
+ bus_alloc_resource_any API
+ </entry>
+ <entry>502109</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after the addition of UTF-8 locales
+ </entry>
+ <entry>502110</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after the removal of the getvfsent(3)
+ API
+ </entry>
+ <entry>502111</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after the addition of the .warning
+ directive for make.</entry>
+ <entry>502112</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after ttyioctl() was made mandatory
+ for serial drivers.</entry>
+ <entry>502113</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after import of the ALTQ framework.
+ </entry>
+ <entry>502114</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after changing sema_timedwait(9) to
+ return 0 on success and a non-zero error code on
+ failure.
+ </entry>
+ <entry>502115</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after changing kernel dev_t to
+ be pointer to struct cdev *.
+ </entry>
+ <entry>502116</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after changing kernel udev_t to dev_t.
+ </entry>
+ <entry>502117</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after adding support for CLOCK_VIRTUAL
+ and CLOCK_PROF to clock_gettime(2) and clock_getres(2).
+ </entry>
+ <entry>502118</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after changing network interface
+ cloning overhaul.
+ </entry>
+ <entry>502119</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after the update of the package tools
+ to revision 20040629.
+ </entry>
+ <entry>502120</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after marking Bluetooth code as
+ non-i386 specific.
+ </entry>
+ <entry>502121</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after the introduction of the KDB
+ debugger framework, the conversion of DDB into a
+ backend and the introduction of the GDB backend.
+ </entry>
+ <entry>502122</entry>
+ </row>
+
+ <row>
+ <entry>5.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
+ <literal>xorg</literal> was also made at this time.
+ </entry>
+ <entry>502123</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after the change to separate the way
+ ports rc.d and legacy scripts are started.
+ </entry>
+ <entry>502124</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after the backout of the
+ previous change.
+ </entry>
+ <entry>502125</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after the removal of
+ kmem_alloc_pageable() and the import of gcc 3.4.2.
+ </entry>
+ <entry>502126</entry>
+ </row>
+
+ <row>
+ <entry>5.2-CURRENT after changing the UMA kernel
+ API to allow ctors/inits to fail.
+ </entry>
+ <entry>502127</entry>
+ </row>
+
+ <row>
+ <entry>5.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.
+ </entry>
+ <entry>502128</entry>
+ </row>
+
+ <row>
+ <entry>5.3-BETA/RC before the pfil API change</entry>
+ <entry>503000</entry>
+ </row>
+
+ <row>
+ <entry>5.3-RELEASE</entry>
+ <entry>503001</entry>
+ </row>
+
+ <row>
+ <entry>5.3-STABLE after branching for RELENG_5_3</entry>
+ <entry>503100</entry>
+ </row>
+
+ <row>
+ <entry>5.3-STABLE after addition of glibc style
+ &man.strftime.3; padding options.</entry>
+ <entry>503101</entry>
+ </row>
+
+ <row>
+ <entry>5.3-STABLE after OpenBSD's nc(1) import MFC.</entry>
+ <entry>503102</entry>
+ </row>
+
+ <row>
+ <entry>5.4-PRERELEASE after the MFC of the fixes in
+ <filename>&lt;src/include/stdbool.h&gt;</filename> and
+ <filename>&lt;src/sys/i386/include/_types.h&gt;</filename>
+ for using the GCC-compatibility of the Intel C/C++ compiler.</entry>
+ <entry>503103</entry>
+ </row>
+
+ <row>
+ <entry>5.4-PRERELEASE after the MFC of the change of
+ ifi_epoch from wall clock time to uptime.</entry>
+ <entry>503104</entry>
+ </row>
+
+ <row>
+ <entry>5.4-PRERELEASE after the MFC of the fix of EOVERFLOW check in vswprintf(3).</entry>
+ <entry>503105</entry>
+ </row>
+
+ <row>
+ <entry>5.4-RELEASE.</entry>
+ <entry>504000</entry>
+ </row>
+
+ <row>
+ <entry>5.4-STABLE after branching for RELENG_5_4</entry>
+ <entry>504100</entry>
+ </row>
+
+ <row>
+ <entry>5.4-STABLE after increasing the default
+ thread stacksizes</entry>
+ <entry>504101</entry>
+ </row>
+
+ <row>
+ <entry>5.4-STABLE after the addition of sha256</entry>
+ <entry>504102</entry>
+ </row>
+
+ <row>
+ <entry>5.4-STABLE after the MFC of if_bridge</entry>
+ <entry>504103</entry>
+ </row>
+
+ <row>
+ <entry>5.4-STABLE after the MFC of bsdiff and portsnap</entry>
+ <entry>504104</entry>
+ </row>
+
+ <row>
+ <entry>5.4-STABLE after MFC of ldconfig_local_dirs
+ change.</entry>
+ <entry>504105</entry>
+ </row>
+
+ <row>
+ <entry>5.5-RELEASE.</entry>
+ <entry>505000</entry>
+ </row>
+
+ <row>
+ <entry>5.5-STABLE after branching for RELENG_5_5</entry>
+ <entry>505100</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT</entry>
+ <entry>600000</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after permanently enabling PFIL_HOOKS
+ in the kernel.
+ </entry>
+ <entry>600001</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after initial addition of
+ ifi_epoch to struct if_data. Backed out after a
+ few days. Do not use this value.
+ </entry>
+ <entry>600002</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after the re-addition of the
+ ifi_epoch member of struct if_data.
+ </entry>
+ <entry>600003</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after addition of the struct inpcb
+ argument to the pfil API.
+ </entry>
+ <entry>600004</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after addition of the "-d
+ DESTDIR" argument to newsyslog.
+ </entry>
+ <entry>600005</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after addition of glibc style
+ &man.strftime.3; padding options.
+ </entry>
+ <entry>600006</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after addition of 802.11 framework
+ updates.
+ </entry>
+ <entry>600007</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after changes to VOP_*VOBJECT() functions
+ and introduction of MNTK_MPSAFE flag for Giantfree filesystems.
+ </entry>
+ <entry>600008</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after addition of the cpufreq framework
+ and drivers.
+ </entry>
+ <entry>600009</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after importing OpenBSD's nc(1).</entry>
+ <entry>600010</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after removing semblance of SVID2
+ <literal>matherr()</literal> support.</entry>
+ <entry>600011</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after increase of default thread stacks'
+ size.</entry>
+ <entry>600012</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after fixes in
+ <filename>&lt;src/include/stdbool.h&gt;</filename> and
+ <filename>&lt;src/sys/i386/include/_types.h&gt;</filename>
+ for using the GCC-compatibility of the Intel C/C++ compiler.</entry>
+ <entry>600013</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after EOVERFLOW checks in vswprintf(3) fixed.</entry>
+ <entry>600014</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after changing the struct if_data
+ member, ifi_epoch, from wall clock time to uptime.</entry>
+ <entry>600015</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after LC_CTYPE disk format changed.</entry>
+ <entry>600016</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after NLS catalogs disk format changed.</entry>
+ <entry>600017</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after LC_COLLATE disk format changed.</entry>
+ <entry>600018</entry>
+ </row>
+
+ <row>
+ <entry>Installation of acpica includes into /usr/include.</entry>
+ <entry>600019</entry>
+ </row>
+
+ <row>
+ <entry>Addition of MSG_NOSIGNAL flag to send(2) API.</entry>
+ <entry>600020</entry>
+ </row>
+
+ <row>
+ <entry>Addition of fields to cdevsw</entry>
+ <entry>600021</entry>
+ </row>
+
+ <row>
+ <entry>Removed gtar from base system.</entry>
+ <entry>600022</entry>
+ </row>
+
+ <row>
+ <entry>LOCAL_CREDS, LOCAL_CONNWAIT socket options added to unix(4).</entry>
+ <entry>600023</entry>
+ </row>
+
+ <row>
+ <entry>&man.hwpmc.4; and related tools added to 6.0-CURRENT.</entry>
+ <entry>600024</entry>
+ </row>
+
+ <row>
+ <entry>struct icmphdr added to 6.0-CURRENT.</entry>
+ <entry>600025</entry>
+ </row>
+
+ <row>
+ <entry>pf updated to 3.7.</entry>
+ <entry>600026</entry>
+ </row>
+
+ <row>
+ <entry>Kernel libalias and ng_nat introduced.</entry>
+ <entry>600027</entry>
+ </row>
+
+ <row>
+ <entry>POSIX ttyname_r(3) made available through unistd.h and libc.</entry>
+ <entry>600028</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after libpcap updated to v0.9.1 alpha 096.</entry>
+ <entry>600029</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after importing NetBSD's if_bridge(4).</entry>
+ <entry>600030</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after struct ifnet was broken out
+ of the driver softcs.</entry>
+ <entry>600031</entry>
+ </row>
+
+ <row>
+ <entry>6.0-CURRENT after the import of libpcap v0.9.1.</entry>
+ <entry>600032</entry>
+ </row>
+
+ <row>
+ <entry>6.0-STABLE after bump of all shared library
+ versions that had not been changed since
+ RELENG_5.</entry>
+ <entry>600033</entry>
+ </row>
+
+ <row>
+ <entry>6.0-STABLE after credential argument is added to
+ dev_clone event handler. 6.0-RELEASE.</entry>
+ <entry>600034</entry>
+ </row>
+
+ <row>
+ <entry>6.0-STABLE after 6.0-RELEASE</entry>
+ <entry>600100</entry>
+ </row>
+
+ <row>
+ <entry>6.0-STABLE after incorporating scripts from the
+ local_startup directories into the base &man.rcorder.8;.</entry>
+ <entry>600101</entry>
+ </row>
+
+ <row>
+ <entry>6.0-STABLE after updating the ELF types and
+ constants.</entry>
+ <entry>600102</entry>
+ </row>
+
+ <row>
+ <entry>6.0-STABLE after MFC of pidfile(3) API.</entry>
+ <entry>600103</entry>
+ </row>
+
+ <row>
+ <entry>6.0-STABLE after MFC of ldconfig_local_dirs
+ change.</entry>
+ <entry>600104</entry>
+ </row>
+
+ <row>
+ <entry>6.0-STABLE after NLS catalog support of
+ csh(1).</entry>
+ <entry>600105</entry>
+ </row>
+
+ <row>
+ <entry>6.1-RELEASE</entry>
+ <entry>601000</entry>
+ </row>
+
+ <row>
+ <entry>6.1-STABLE after 6.1-RELEASE.</entry>
+ <entry>601100</entry>
+ </row>
+
+ <row>
+ <entry>6.1-STABLE after the import of csup.</entry>
+ <entry>601101</entry>
+ </row>
+
+ <row>
+ <entry>6.1-STABLE after the iwi(4) update.</entry>
+ <entry>601102</entry>
+ </row>
+
+ <row>
+ <entry>6.1-STABLE after the resolver update to
+ BIND9, and exposure of reentrant version of
+ netdb functions.</entry>
+ <entry>601103</entry>
+ </row>
+
+ <row>
+ <entry>6.1-STABLE after DSO (dynamic shared
+ objects) support has been enabled in
+ OpenSSL.</entry>
+ <entry>601104</entry>
+ </row>
+
+ <row>
+ <entry>6.1-STABLE after 802.11 fixups changed the
+ api for the IEEE80211_IOC_STA_INFO ioctl.</entry>
+ <entry>601105</entry>
+ </row>
+
+ <row>
+ <entry>6.2-RELEASE</entry>
+ <entry>602000</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after 6.2-RELEASE.</entry>
+ <entry>602100</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after the addition of Wi-Spy
+ quirk.</entry>
+ <entry>602101</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after pci_find_extcap() addition.</entry>
+ <entry>602102</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after MFC of dlsym change to look
+ for a requested symbol both
+ in specified dso and its implicit dependencies.</entry>
+ <entry>602103</entry>
+ </row>
+
+ <row>
+ <entry>6.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.</entry>
+ <entry>602104</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after MFC of BSD licensed version of &man.gzip.1;
+ ported from NetBSD.</entry>
+ <entry>602105</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after MFC of PCI MSI and MSI-X
+ support.</entry>
+ <entry>602106</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after MFC of ncurses 5.6 and wide
+ character support.</entry>
+ <entry>602107</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after MFC of CAM 'SG' peripheral device,
+ which implements a subset of Linux SCSI SG passthrough device API.</entry>
+ <entry>602108</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after MFC of readline 5.2 patchset 002.</entry>
+ <entry>602109</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after MFC of pmap_invalidate_cache(),
+ pmap_change_attr(), pmap_mapbios(), pmap_mapdev_attr(),
+ and pmap_unmapbios() for amd64 and i386.</entry>
+ <entry>602110</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after MFC of BOP_BDFLUSH and caused
+ breakage of the filesystem modules KBI.</entry>
+ <entry>602111</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after libutil(3) MFC's.</entry>
+ <entry>602112</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after MFC of wide and single byte
+ ctype separation. Newly compiled binary that references
+ to ctype.h may require a new symbol, __mb_sb_limit,
+ which is not available on older systems.</entry>
+ <entry>602113</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after ctype ABI forward compatibility
+ restored.</entry>
+ <entry>602114</entry>
+ </row>
+
+ <row>
+ <entry>6.2-STABLE after back out of wide and single byte
+ ctype separation.</entry>
+ <entry>602115</entry>
+ </row>
+
+ <row>
+ <entry>6.3-RELEASE</entry>
+ <entry>603000</entry>
+ </row>
+
+ <row>
+ <entry>6.3-STABLE after 6.3-RELEASE.</entry>
+ <entry>603100</entry>
+ </row>
+
+ <row>
+ <entry>6.3-STABLE after fixing
+ multibyte type support in bit macro.</entry>
+ <entry>603101</entry>
+ </row>
+
+ <row>
+ <entry>6.3-STABLE after adding l_sysid to struct flock.</entry>
+ <entry>603102</entry>
+ </row>
+
+ <row>
+ <entry>6.3-STABLE after MFC of the
+ <function>memrchr</function> function.</entry>
+ <entry>603103</entry>
+ </row>
+
+ <row>
+ <entry>6.3-STABLE after MFC of support for
+ <literal>:u</literal> variable modifier in make(1).</entry>
+ <entry>603104</entry>
+ </row>
+
+ <row>
+ <entry>6.4-RELEASE</entry>
+ <entry>604000</entry>
+ </row>
+
+ <row>
+ <entry>6.4-STABLE after 6.4-RELEASE.</entry>
+ <entry>604100</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT.</entry>
+ <entry>700000</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after bump of all shared library
+ versions that had not been changed since
+ RELENG_5.</entry>
+ <entry>700001</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after credential argument is added to
+ dev_clone event handler.</entry>
+ <entry>700002</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after memmem(3) is added to libc.</entry>
+ <entry>700003</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after solisten(9) kernel arguments
+ are modified to accept a backlog parameter.</entry>
+ <entry>700004</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after IFP2ENADDR() was changed to return
+ a pointer to IF_LLADDR().</entry>
+ <entry>700005</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after addition of <literal>if_addr</literal>
+ member to <literal>struct ifnet</literal> and IFP2ENADDR()
+ removal.</entry>
+ <entry>700006</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after incorporating scripts from the
+ local_startup directories into the base &man.rcorder.8;.</entry>
+ <entry>700007</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after removal of MNT_NODEV mount
+ option.</entry>
+ <entry>700008</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after ELF-64 type changes and symbol
+ versioning.</entry>
+ <entry>700009</entry>
+ </row>
+
+ <row>
+ <entry>7.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.</entry>
+ <entry>700010</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after tv_sec was made time_t on
+ all platforms but Alpha.</entry>
+ <entry>700011</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after ldconfig_local_dirs change.</entry>
+ <entry>700012</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after changes to
+ <filename>/etc/rc.d/abi</filename> to support
+ <filename>/compat/linux/etc/ld.so.cache</filename>
+ being a symlink in a readonly filesystem.</entry>
+ <entry>700013</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after pts import.</entry>
+ <entry>700014</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after the introduction of version 2
+ of &man.hwpmc.4;'s ABI.</entry>
+ <entry>700015</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after addition of &man.fcloseall.3;
+ to libc.</entry>
+ <entry>700016</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after removal of ip6fw.</entry>
+ <entry>700017</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after import of snd_emu10kx.</entry>
+ <entry>700018</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after import of OpenSSL 0.9.8b.</entry>
+ <entry>700019</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after addition of bus_dma_get_tag
+ function</entry>
+ <entry>700020</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after libpcap 0.9.4 and
+ tcpdump 3.9.4 import.</entry>
+ <entry>700021</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after dlsym change to look
+ for a requested symbol both
+ in specified dso and its implicit dependencies.</entry>
+ <entry>700022</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after adding new sound IOCTLs.</entry>
+ <entry>700023</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after import of OpenSSL 0.9.8d.</entry>
+ <entry>700024</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after the addition of libelf.</entry>
+ <entry>700025</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after major changes on sound
+ sysctls.</entry>
+ <entry>700026</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after the addition of Wi-Spy
+ quirk.</entry>
+ <entry>700027</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after the addition of sctp calls to libc
+ </entry>
+ <entry>700028</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after the GNU &man.gzip.1; implementation was
+ replaced with a BSD licensed version ported from NetBSD.</entry>
+ <entry>700029</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after the removal of IPIP tunnel encapsulation (VIFF_TUNNEL) from the IPv4 multicast forwarding code.
+ </entry>
+ <entry>700030</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after the modification of bus_setup_intr() (newbus).
+ </entry>
+ <entry>700031</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after the inclusion of ipw(4) and iwi(4) firmwares.
+ </entry>
+ <entry>700032</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after the inclusion of ncurses wide character support.
+ </entry>
+ <entry>700033</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after changes to how insmntque(),
+ getnewvnode(), and vfs_hash_insert() work.
+ </entry>
+ <entry>700034</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after addition of a notify mechanism
+ for CPU frequency changes.
+ </entry>
+ <entry>700035</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after import of the ZFS filesystem.</entry>
+ <entry>700036</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after addition of CAM 'SG' peripheral device,
+ which implements a subset of Linux SCSI SG passthrough device API.</entry>
+ <entry>700037</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after changing &man.getenv.3;, &man.putenv.3;,
+ &man.setenv.3; and &man.unsetenv.3; to be POSIX
+ conformant.</entry>
+ <entry>700038</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after the changes in 700038 were
+ backed out.</entry>
+ <entry>700039</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after the addition of &man.flopen.3;
+ to libutil.</entry>
+ <entry>700040</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after enabling symbol versioning, and changing
+ the default thread library to libthr.</entry>
+ <entry>700041</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after the import of gcc 4.2.0.</entry>
+ <entry>700042</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after bump of all shared library
+ versions that had not been changed since
+ RELENG_6.</entry>
+ <entry>700043</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after changing the argument for
+ vn_open()/VOP_OPEN() from filedescriptor index to the
+ struct file *.</entry>
+ <entry>700044</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after changing &man.pam.nologin.8; to
+ provide an account management function instead of an
+ authentication function to the PAM framework.</entry>
+ <entry>700045</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after updated 802.11 wireless
+ support.</entry>
+ <entry>700046</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after adding TCP LRO interface
+ capabilities.</entry>
+ <entry>700047</entry>
+ </row>
+
+ <row>
+ <entry>7.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.</entry>
+ <entry>700048</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after importing pf from OpenBSD
+ 4.1</entry>
+ <entry>700049</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after adding IPv6 support for
+ FAST_IPSEC, deleting KAME IPSEC, and renaming
+ FAST_IPSEC to IPSEC.</entry>
+ <entry>(not changed)</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after converting setenv/putenv/etc.
+ calls from traditional BSD to POSIX.</entry>
+ <entry>700050</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after adding new mmap/lseek/etc
+ syscalls.</entry>
+ <entry>700051</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after moving I4B headers to
+ include/i4b.</entry>
+ <entry>700052</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after the addition of support for
+ PCI domains</entry>
+ <entry>700053</entry>
+ </row>
+
+ <row>
+ <entry>7.0-CURRENT after MFC of wide and single byte
+ ctype separation.</entry>
+ <entry>700054</entry>
+ </row>
+
+ <row>
+ <entry>7.0-RELEASE, and 7.0-CURRENT after ABI backwards compatibility
+ to the FreeBSD 4/5/6 versions of the PCIOCGETCONF,
+ PCIOCREAD and PCIOCWRITE IOCTLs was MFC'ed, which
+ required the ABI of the PCIOCGETCONF IOCTL to be
+ broken again</entry>
+ <entry>700055</entry>
+ </row>
+
+ <row>
+ <entry>7.0-STABLE after 7.0-RELEASE</entry>
+ <entry>700100</entry>
+ </row>
+
+ <row>
+ <entry>7.0-STABLE after the MFC of m_collapse().</entry>
+ <entry>700101</entry>
+ </row>
+
+ <row>
+ <entry>7.0-STABLE after the MFC of kdb_enter_why().</entry>
+ <entry>700102</entry>
+ </row>
+
+ <row>
+ <entry>7.0-STABLE after adding l_sysid to struct flock.</entry>
+ <entry>700103</entry>
+ </row>
+
+ <row>
+ <entry>7.0-STABLE after the MFC of procstat(1).</entry>
+ <entry>700104</entry>
+ </row>
+
+ <row>
+ <entry>7.0-STABLE after the MFC of umtx features. </entry>
+ <entry>700105</entry>
+ </row>
+
+ <row>
+ <entry>7.0-STABLE after the MFC of &man.write.2; support
+ to &man.psm.4;.</entry>
+ <entry>700106</entry>
+ </row>
+
+ <row>
+ <entry>7.0-STABLE after the MFC of F_DUP2FD command
+ to &man.fcntl.2;.</entry>
+ <entry>700107</entry>
+ </row>
+
+ <row>
+ <entry>7.0-STABLE after some &man.lockmgr.9; changes, which
+ makes it necessary to include
+ <filename>sys/lock.h</filename> in order to use
+ &man.lockmgr.9;.</entry>
+ <entry>700108</entry>
+ </row>
+
+ <row>
+ <entry>7.0-STABLE after MFC of the
+ <function>memrchr</function> function.</entry>
+ <entry>700109</entry>
+ </row>
+
+ <row>
+ <entry>7.0-STABLE after MFC of kernel NFS lockd client.
+ </entry>
+ <entry>700110</entry>
+ </row>
+
+ <row>
+ <entry>7.0-STABLE after addition of physically contiguous
+ jumbo frame support.</entry>
+ <entry>700111</entry>
+ </row>
+
+ <row>
+ <entry>7.0-STABLE after MFC of kernel DTrace support.
+ </entry>
+ <entry>700112</entry>
+ </row>
+
+ <row>
+ <entry>7.1-RELEASE</entry>
+ <entry>701000</entry>
+ </row>
+
+ <row>
+ <entry>7.1-STABLE after 7.1-RELEASE.</entry>
+ <entry>701100</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT. Separating wide and single byte
+ ctype.</entry>
+ <entry>800000</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after libpcap 0.9.8 and tcpdump 3.9.8
+ import.</entry>
+ <entry>800001</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after renaming kthread_create()
+ and friends to kproc_create() etc.</entry>
+ <entry>800002</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after ABI backwards compatibility
+ to the FreeBSD 4/5/6 versions of the PCIOCGETCONF,
+ PCIOCREAD and PCIOCWRITE IOCTLs was added, which
+ required the ABI of the PCIOCGETCONF IOCTL to be
+ broken again</entry>
+ <entry>800003</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after agp(4) driver moved from
+ src/sys/pci to src/sys/dev/agp</entry>
+ <entry>800004</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after
+ <link xlink:href="http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/kern/kern_mbuf.c#rev1.35">changes
+ to the jumbo frame allocator</link>.</entry>
+ <entry>800005</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after the addition of callgraph
+ capture functionality to &man.hwpmc.4;.</entry>
+ <entry>800006</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after kdb_enter() gains a "why"
+ argument.</entry>
+ <entry>800007</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after LK_EXCLUPGRADE option
+ removal.</entry>
+ <entry>800008</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after introduction of
+ &man.lockmgr.disown.9;</entry>
+ <entry>800009</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after the &man.vn.lock.9; prototype
+ change.</entry>
+ <entry>800010</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after the &man.VOP.LOCK.9; and
+ &man.VOP.UNLOCK.9; prototype changes.</entry>
+ <entry>800011</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after introduction of
+ &man.lockmgr.recursed.9;, &man.BUF.RECURSED.9; and
+ &man.BUF.ISLOCKED.9; and the removal of
+ <function>BUF_REFCNT()</function>.</entry>
+ <entry>800012</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after introduction of the
+ <quote>ASCII</quote> encoding.</entry>
+ <entry>800013</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after changing the prototype of
+ &man.lockmgr.9; and removal of
+ <function>lockcount()</function> and
+ <function>LOCKMGR_ASSERT()</function>.</entry>
+ <entry>800014</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after extending the types
+ of the &man.fts.3; structures.</entry>
+ <entry>800015</entry>
+ </row>
+
+ <row>
+ <entry>8.0-CURRENT after adding an argumentt to MEXTADD(9)
+ </entry>
+ <entry>800016</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after the introduction of
+ LK_NODUP and LK_NOWITNESS options in the
+ &man.lockmgr.9; space.</entry>
+ <entry>800017</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after the addition of
+ m_collapse.</entry>
+ <entry>800018</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after the addition of current
+ working directory, root directory, and jail
+ directory support to the kern.proc.filedesc
+ sysctl.</entry>
+ <entry>800019</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after introduction of
+ &man.lockmgr.assert.9; and
+ <function>BUF_ASSERT</function> functions.</entry>
+ <entry>800020</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after introduction of
+ &man.lockmgr.args.9; and LK_INTERNAL flag
+ removal.</entry>
+ <entry>800021</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after changing the default system ar
+ to BSD &man.ar.1;.</entry>
+ <entry>800022</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after changing the prototypes of
+ &man.lockstatus.9; and &man.VOP.ISLOCKED.9;, more
+ specifically retiring the
+ <literal>struct thread</literal> argument.</entry>
+ <entry>800023</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after axing out the
+ <function>lockwaiters</function> and
+ <function>BUF_LOCKWAITERS</function> functions,
+ changing the return value fo <function>brelvp</function>
+ from void to int and introducing new flags for
+ &man.lockinit.9;.</entry>
+ <entry>800024</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after adding F_DUP2FD command
+ to &man.fcntl.2;.</entry>
+ <entry>800025</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after changing the priority parameter
+ to cv_broadcastpri such that 0 means no priority.
+ </entry>
+ <entry>800026</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after changing the bpf monitoring ABI
+ when zerocopy bpf buffers were added.
+ </entry>
+ <entry>800027</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after adding l_sysid to struct flock.
+ </entry>
+ <entry>800028</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after reintegration of the
+ <function>BUF_LOCKWAITERS</function> function and the
+ addition of &man.lockmgr.waiters.9;.</entry>
+ <entry>800029</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after the introduction of the
+ &man.rw.try.rlock.9; and &man.rw.try.wlock.9; functions.
+ </entry>
+ <entry>800030</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after the introduction of the
+ <function>lockmgr_rw</function> and
+ <function>lockmgr_args_rw</function> functions.</entry>
+ <entry>800031</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after the implementation of the
+ openat and related syscalls, introduction of the O_EXEC
+ flag for the &man.open.2;, and providing the
+ corresponding linux compatibility syscalls.</entry>
+ <entry>800032</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after added &man.write.2; support for
+ &man.psm.4; in native operation level. Now arbitrary
+ commands can be written to <filename>/dev/psm%d</filename>
+ and status can be read back from it.</entry>
+ <entry>800033</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after introduction of the
+ <function>memrchr</function> function.</entry>
+ <entry>800034</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after introduction of the
+ <function>fdopendir</function> function.</entry>
+ <entry>800035</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after switchover of 802.11 wireless
+ to multi-bss support (aka vaps).</entry>
+ <entry>800036</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after addition of multi routing
+ table support (a.k.a. setfib(1), setfib(2)).</entry>
+ <entry>800037</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after removal of netatm and
+ ISDN4BSD.</entry>
+ <entry>800038</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after removal of sgtty.</entry>
+ <entry>800039</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT with kernel NFS lockd client.</entry>
+ <entry>800040</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after addition of arc4random_buf(3)
+ and arc4random_uniform(3).</entry>
+ <entry>800041</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after addition of cpuctl(4).</entry>
+ <entry>800042</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after changing bpf(4) to use a
+ single device node, instead of device cloning.</entry>
+ <entry>800043</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after the commit of the first step of
+ the vimage project renaming global variables to be
+ virtualized with a V_ prefix with macros to map them
+ back to their global names.</entry>
+ <entry>800044</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after the integration of the
+ MPSAFE TTY layer, including changes to various
+ drivers and utilities that interact with it.</entry>
+ <entry>800045</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after the separation of the GDT
+ per CPU on amd64 architecture.</entry>
+ <entry>800046</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after removal of VSVTX, VSGID
+ and VSUID.</entry>
+ <entry>800047</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after converting the kernel NFS mount
+ code to accept individual mount options in the
+ nmount() iovec, not just one big
+ struct nfs_args.</entry>
+ <entry>800048</entry>
+ </row>
+ <row>
+ <entry>8.0-CURRENT after the removal of &man.suser.9; and
+ &man.suser.cred.9;.</entry>
+ <entry>800049</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>Note that 2.2-STABLE sometimes identifies itself as
+ <quote>2.2.5-STABLE</quote> 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.</para>
+ </note>
+ </sect1>
+
+ <sect1 xml:id="dads-after-port-mk">
+ <title>Writing something after
+ <filename>bsd.port.mk</filename></title>
+
+ <para>Do not write anything after the <literal>.include
+ &lt;bsd.port.mk&gt;</literal> line. It usually can be avoided by
+ including <filename>bsd.port.pre.mk</filename> somewhere in the
+ middle of your <filename>Makefile</filename> and
+ <filename>bsd.port.post.mk</filename> at the end.</para>
+
+ <note>
+ <para>You need to include either the
+ <filename>bsd.port.pre.mk</filename>/<filename>bsd.port.post.mk</filename> pair or
+ <filename>bsd.port.mk</filename> only; do not mix these two usages.</para>
+ </note>
+
+ <para><filename>bsd.port.pre.mk</filename> only defines a few
+ variables, which can be used in tests in the
+ <filename>Makefile</filename>, <filename>bsd.port.post.mk</filename>
+ defines the rest.</para>
+
+ <para>Here are some important variables defined in
+ <filename>bsd.port.pre.mk</filename> (this is not the complete list,
+ please read <filename>bsd.port.mk</filename> for the complete
+ list).</para>
+
+ <informaltable frame="none" pgwide="1">
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>ARCH</varname></entry>
+ <entry>The architecture as returned by <command>uname
+ -m</command> (e.g., <literal>i386</literal>)</entry>
+ </row>
+
+ <row>
+ <entry><varname>OPSYS</varname></entry>
+ <entry>The operating system type, as returned by
+ <command>uname -s</command> (e.g.,
+ <literal>FreeBSD</literal>)</entry>
+ </row>
+
+ <row>
+ <entry><varname>OSREL</varname></entry>
+ <entry>The release version of the operating system (e.g.,
+ <literal>2.1.5</literal> or
+ <literal>2.2.7</literal>)</entry>
+ </row>
+
+ <row>
+ <entry><varname>OSVERSION</varname></entry>
+ <entry>The numeric version of the operating system; the same as
+ <link linkend="freebsd-versions"><literal>__FreeBSD_version</literal></link>.</entry>
+ </row>
+
+ <row>
+ <entry><varname>PORTOBJFORMAT</varname></entry>
+ <entry>The object format of the system
+ (<literal>elf</literal> or <literal>aout</literal>;
+ note that for <quote>modern</quote> versions of FreeBSD,
+ <literal>aout</literal> is deprecated.)</entry>
+ </row>
+
+ <row>
+ <entry><varname>LOCALBASE</varname></entry>
+ <entry>The base of the <quote>local</quote> tree (e.g.,
+ <literal>/usr/local/</literal>)</entry>
+ </row>
+
+ <row>
+ <entry><varname>PREFIX</varname></entry>
+ <entry>Where the port installs itself (see <link linkend="porting-prefix">more on
+ <varname>PREFIX</varname></link>).</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <note>
+ <para>If you have to define the variables
+ <varname>USE_IMAKE</varname>, <varname>USE_X_PREFIX</varname>, or
+ <varname>MASTERDIR</varname>, do so before including
+ <filename>bsd.port.pre.mk</filename>.</para>
+ </note>
+
+ <para>Here are some examples of things you can write after
+ <filename>bsd.port.pre.mk</filename>:</para>
+
+ <programlisting># no need to compile lang/perl5 if perl5 is already in system
+.if ${OSVERSION} &gt; 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
+.endif</programlisting>
+
+ <para>You did remember to use tab instead of spaces after
+ <literal>BROKEN=</literal> and
+ <literal>TCL_LIB_FILE=</literal>, did you not?
+ <!-- smiley -->:-).</para>
+ </sect1>
+
+ <sect1 xml:id="dads-sh-exec">
+ <title>在 wrapper scripts 中使用 <function>exec</function> 述句</title>
+
+ <para>若某 port 為了執行其他程式而安裝了一個 shell script,
+ 而該程式同時也是該 script 最後一個動作,那麼需要確定該 script
+ 是用 <function>exec</function> 述句(statement),舉例而言:</para>
+
+ <programlisting>#!/bin/sh
+exec %%LOCALBASE%%/bin/java -jar %%DATADIR%%/foo.jar "$@"</programlisting>
+
+ <para><function>exec</function> 述句以所指定的程式取代了該 shell
+ 的程序。 若省略 <function>exec</function> ,那麼該 shell 程序
+ 將會在程式執行中一直存在於記憶體,這無疑地浪費了系統資源。</para>
+
+ </sect1>
+
+ <sect1 xml:id="dads-uid-and-gids">
+ <title>UIDs 及 GIDs</title>
+
+ <para>The current list of reserved UIDs and GIDs can be found
+ in <filename>ports/UIDs</filename> and
+ <filename>ports/GIDs</filename>.</para>
+
+ <para>If your port requires a certain user to be on the installed
+ system, let the <filename>pkg-install</filename> script call
+ <command>pw</command> to create it automatically. Look at
+ <package>net/cvsup-mirror</package> for an example.
+ Please note that this is strongly discouraged, please register
+ user/group ID numbers as stated below.</para>
+
+ <para>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
+ <filename>ports/UIDs</filename> (for users) or in
+ <filename>ports/GIDs</filename> (for groups). Look at
+ <package>japanese/Wnn6</package> for an example.</para>
+
+ <para>Make sure you do not use a UID already used by the system or
+ other ports.</para>
+
+ <para>Please include a patch against these two files when you
+ require a new user or group to be created for your
+ port.</para>
+ </sect1>
+
+ <sect1 xml:id="dads-rational">
+ <title>Do things rationally</title>
+
+ <para>The <filename>Makefile</filename> 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
+ <literal>.if</literal> construct instead of a shell
+ <literal>if</literal> construct, not redefining
+ <buildtarget>do-extract</buildtarget> if you can redefine
+ <varname>EXTRACT*</varname> instead, and using
+ <varname>GNU_CONFIGURE</varname> instead of <literal>CONFIGURE_ARGS
+ += --prefix=&dollar;{PREFIX}</literal>.</para>
+
+ <para>If you find yourself having to write a lot
+ of new code to try to do something, please go back and review
+ <filename>bsd.port.mk</filename> 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 <filename>bsd.port.mk</filename> already provides a
+ shorthand solution.</para>
+ </sect1>
+
+ <sect1 xml:id="dads-cc">
+ <title>Respect both <varname>CC</varname> and
+ <varname>CXX</varname></title>
+
+ <para>The port should respect both <varname>CC</varname>
+ and <varname>CXX</varname> 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.</para>
+
+ <para>If the port does not respect these variables,
+ please add <literal>NO_PACKAGE=ignores either cc or
+ cxx</literal> to the <filename>Makefile</filename>.</para>
+
+ <para>An example of a <filename>Makefile</filename> respecting
+ both <varname>CC</varname> and <varname>CXX</varname>
+ variables follows. Note the <varname>?=</varname>:</para>
+
+ <programlisting>CC?= gcc</programlisting>
+ <programlisting>CXX?= g++</programlisting>
+
+ <para>Here is an example which respects neither
+ <varname>CC</varname> nor <varname>CXX</varname>
+ variables:</para>
+
+ <programlisting>CC= gcc</programlisting>
+ <programlisting>CXX= g++</programlisting>
+
+ <para>Both <varname>CC</varname> and <varname>CXX</varname>
+ variables can be defined on FreeBSD systems in
+ <filename>/etc/make.conf</filename>. The first example
+ defines a value if it was not previously set in
+ <filename>/etc/make.conf</filename>, preserving any
+ system-wide definitions. The second example clobbers
+ anything previously defined.</para>
+ </sect1>
+
+ <sect1 xml:id="dads-cflags">
+ <title>Respect <varname>CFLAGS</varname></title>
+
+ <para>The port should respect the <varname>CFLAGS</varname> 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.</para>
+
+ <para>If it does not, please add <literal>NO_PACKAGE=ignores
+ cflags</literal> to the <filename>Makefile</filename>.</para>
+
+ <para>An example of a <filename>Makefile</filename> respecting
+ the <varname>CFLAGS</varname> variable follows. Note the
+ <varname>+=</varname>:</para>
+
+ <programlisting>CFLAGS+= -Wall -Werror</programlisting>
+
+ <para>Here is an example which does not respect the
+ <varname>CFLAGS</varname> variable:</para>
+
+ <programlisting>CFLAGS= -Wall -Werror</programlisting>
+
+ <para>The <varname>CFLAGS</varname> variable is defined on
+ FreeBSD systems in <filename>/etc/make.conf</filename>. The
+ first example appends additional flags to the
+ <varname>CFLAGS</varname> variable, preserving any system-wide
+ definitions. The second example clobbers anything previously
+ defined.</para>
+
+ <para>You should remove optimization flags from the third party
+ <filename>Makefile</filename>s. System <varname>CFLAGS</varname>
+ contains system-wide optimization flags. An example from
+ an unmodified <filename>Makefile</filename>:</para>
+
+ <programlisting>CFLAGS= -O3 -funroll-loops -DHAVE_SOUND</programlisting>
+
+ <para>Using system optimization flags, the
+ <filename>Makefile</filename> would look similar to the
+ following example:</para>
+
+ <programlisting>CFLAGS+= -DHAVE_SOUND</programlisting>
+
+ </sect1>
+
+ <sect1 xml:id="dads-pthread">
+ <title>Threading libraries</title>
+
+ <para>The threading library must be linked to the binaries
+ using a special linker flag <literal>-pthread</literal> on
+ &os;. If a port insists on linking
+ <literal>-lpthread</literal> or <literal>-lc_r</literal>
+ directly, patch it to use <varname>PTHREAD_LIBS</varname>
+ variable provided by the ports framework. This variable
+ usually has the value of <literal>-pthread</literal>, but
+ on certain architectures and &os; versions it can have
+ different values, so do not just hardcode
+ <literal>-pthread</literal> into patches and always use
+ <varname>PTHREAD_LIBS</varname>.</para>
+
+ <note>
+ <para>If building the port errors out with <literal>unrecognized
+ option '-pthread'</literal> when setting
+ <varname>PTHREAD_LIBS</varname>, it may be desirable to use
+ <command>gcc</command> as linker by setting
+ <varname>CONFIGURE_ENV</varname> to <literal>LD=${CC}</literal>.
+ The <literal>-pthread</literal> option is not supported by
+ <command>ld</command> directly.</para>
+ </note>
+
+ </sect1>
+
+ <sect1 xml:id="dads-freedback">
+ <title>Feedback</title>
+
+ <para>Do 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.</para>
+ </sect1>
+
+ <sect1 xml:id="dads-readme">
+ <title><filename>README.html</filename></title>
+
+ <para>Do not include the <filename>README.html</filename> file. This
+ file is not part of the cvs collection but is generated using the
+ <command>make readme</command> command.
+ </para>
+ </sect1>
+
+ <sect1 xml:id="dads-noinstall">
+ <title>Marking a port not installable with <varname>BROKEN</varname>,
+ <varname>FORBIDDEN</varname>, or <varname>IGNORE</varname></title>
+
+ <para>In certain cases users should be prevented from installing
+ a port. To tell a user that
+ a port should not be installed, there are several
+ <command>make</command> variables that can be used in a port's
+ <filename>Makefile</filename>. The value of the following
+ <command>make</command> variables will be the reason that is
+ given back to users for why the port refuses to install itself.
+ Please use the correct <command>make</command> variable as
+ each make variable conveys radically different meanings to
+ both users, and to automated systems that depend on the
+ <filename>Makefile</filename>s, such as
+ <link linkend="build-cluster">the ports build cluster</link>,
+ <link linkend="freshports">FreshPorts</link>, and
+ <link linkend="portsmon">portsmon</link>.</para>
+
+ <sect2 xml:id="dads-noinstall-variables">
+ <title>Variables</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><varname>BROKEN</varname> 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.</para>
+
+ <para>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.)</para>
+
+ <para>For instance, use
+ <varname>BROKEN</varname> when a port:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>does not compile</para>
+ </listitem>
+
+ <listitem>
+ <para>fails its configuration or installation process</para>
+ </listitem>
+
+ <listitem>
+ <para>installs files outside of
+ <filename>${LOCALBASE}</filename></para>
+ </listitem>
+
+ <listitem>
+ <para>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)</para>
+ </listitem>
+ </itemizedlist>
+
+ </listitem>
+
+ <listitem>
+ <para><varname>FORBIDDEN</varname> 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 <varname>FORBIDDEN</varname>
+ 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
+ <varname>FORBIDDEN</varname> for any reason other than
+ security.</para>
+ </listitem>
+
+ <listitem>
+ <para><varname>IGNORE</varname> 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
+ <varname>IGNORE</varname>. For instance, use
+ <varname>IGNORE</varname> when a port:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>compiles but does not run properly</para>
+ </listitem>
+
+ <listitem>
+ <para>does not work on the installed version of &os;</para>
+ </listitem>
+
+ <listitem>
+ <para>requires &os; kernel sources to build, but the
+ user does not have them installed</para>
+ </listitem>
+
+ <listitem>
+ <para>has a distfile which may not be automatically
+ fetched due to licensing restrictions</para>
+ </listitem>
+
+ <listitem>
+ <para>does not work with some other currently installed
+ port (for instance, the port depends on
+ <package>www/apache21</package> but
+ <package>www/apache13</package>
+ is installed)</para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <para>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),
+ <link linkend="conflicts">use
+ <varname>CONFLICTS</varname> instead</link>.
+ <varname>CONFLICTS</varname> will set
+ <varname>IGNORE</varname> by itself.</para>
+ </note>
+ </listitem>
+
+ <listitem>
+ <para>If a port should be marked <varname>IGNORE</varname>
+ only on certain architectures, there are two other
+ convenience variables that will automatically set
+ <varname>IGNORE</varname> for you:
+ <varname>ONLY_FOR_ARCHS</varname> and
+ <varname>NOT_FOR_ARCHS</varname>. Examples:</para>
+
+ <programlisting>ONLY_FOR_ARCHS= i386 amd64</programlisting>
+
+ <programlisting>NOT_FOR_ARCHS= alpha ia64 sparc64</programlisting>
+
+ <para>A custom <varname>IGNORE</varname> message can be set
+ using <varname>ONLY_FOR_ARCHS_REASON</varname> and
+ <varname>NOT_FOR_ARCHS_REASON</varname>. Per architecture
+ entries are possible with
+ <varname>ONLY_FOR_ARCHS_REASON_<replaceable>ARCH</replaceable></varname>
+ and
+ <varname>NOT_FOR_ARCHS_REASON_<replaceable>ARCH</replaceable></varname>.</para>
+ </listitem>
+
+ <listitem>
+ <para>If a port fetches i386 binaries and installs them,
+ <varname>IA32_BINARY_PORT</varname> should be set. If this
+ variable is set, it will be checked whether the
+ <filename>/usr/lib32</filename> 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, <varname>IGNORE</varname> will
+ be set automatically.</para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect2>
+ <sect2 xml:id="dads-noinstall-notes">
+ <title>Implementation Notes</title>
+
+ <para>The 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:</para>
+
+ <programlisting>BROKEN= this port is unsupported on FreeBSD 5.x</programlisting>
+
+ <programlisting>IGNORE= is unsupported on FreeBSD 5.x</programlisting>
+
+ <para>resulting in the following output from
+ <command>make describe</command>:</para>
+
+ <programlisting>===&gt; foobar-0.1 is marked as broken: this port is unsupported on FreeBSD 5.x.</programlisting>
+
+ <programlisting>===&gt; foobar-0.1 is unsupported on FreeBSD 5.x.</programlisting>
+ </sect2>
+ </sect1>
+
+ <sect1 xml:id="dads-deprecated">
+ <title>Marking a port for removal with <varname>DEPRECATED</varname>
+ or <varname>EXPIRATION_DATE</varname></title>
+
+ <para>Do remember that <varname>BROKEN</varname> and
+ <varname>FORBIDDEN</varname> are to be used as a
+ temporary resort if a port is not working. Permanently
+ broken ports should be removed from the tree
+ entirely.</para>
+
+ <para>When it makes sense to do so, users can be warned about
+ a pending port removal with <varname>DEPRECATED</varname>
+ and <varname>EXPIRATION_DATE</varname>. 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.</para>
+
+ <para>It is possible to set <varname>DEPRECATED</varname>
+ without an <varname>EXPIRATION_DATE</varname> (for
+ instance, recommending a newer version of the port), but
+ the converse does not make any sense.</para>
+
+ <para>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.</para>
+ </sect1>
+
+ <sect1 xml:id="dads-dot-error">
+ <title>Avoid use of the <literal>.error</literal> construct</title>
+
+ <para>The correct way for a <filename>Makefile</filename> 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
+ <varname>IGNORE</varname>. This value will be formatted and
+ shown to the user by <command>make install</command>.</para>
+
+ <para>It is a common mistake to use <literal>.error</literal>
+ 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 <filename>/usr/ports/INDEX</filename>
+ (see <xref linkend="make-describe"/>). However, even more
+ trivial commands such as <command>make -V maintainer</command>
+ also fail in this scenario. This is not acceptable.</para>
+
+ <example xml:id="dot-error-breaks-index">
+ <title>How to avoid using <literal>.error</literal></title>
+ <para>Assume that someone has the line
+ <programlisting>USE_POINTYHAT=yes</programlisting>
+ in <filename>make.conf</filename>. The first of
+ the next two <filename>Makefile</filename> snippets will
+ cause <command>make index</command> to fail, while the
+ second one will not:</para>
+ <programlisting>.if USE_POINTYHAT
+.error "POINTYHAT is not supported"
+.endif</programlisting>
+ <programlisting>.if USE_POINTYHAT
+IGNORE=POINTYHAT is not supported
+.endif</programlisting>
+ </example>
+
+ </sect1>
+
+ <sect1 xml:id="dads-sysctl">
+ <title><filename>sysctl</filename> 使用時機</title>
+
+ <para><filename>sysctl</filename> 除了在 targets 之外,都不鼓勵使用。
+ 這是因為任何 <literal>makevar</literal>
+ 的評估都有可能會使得程序執行速度變慢。例如在
+ <command>make index</command> 的過程中就會需要用到
+ <filename>sysctl</filename>。</para>
+
+ <para>若要使用 &man.sysctl.8; 則必須透過 <varname>SYSCTL</varname>
+ 此一變數才可,因為這樣才會包含完整路徑,
+ 同時也可以隨時因應使用者需求而替換為其他路徑。</para>
+ </sect1>
+
+ <sect1 xml:id="dads-rerolling-distfiles">
+ <title>Rerolling distfiles</title>
+
+ <para>Sometimes 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.</para>
+
+ <para>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 <filename>distinfo</filename>.
+ 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.</para>
+
+ <para>You might also want to contact the authors of the software
+ and confirm the changes with them.</para>
+ </sect1>
+
+ <sect1 xml:id="dads-workarounds">
+ <title>Necessary workarounds</title>
+
+ <para>Sometimes it is necessary to work around bugs in
+ software included with older versions of &os;.</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Some versions of &man.make.1; were broken
+ on at least 4.8 and 5.0 with respect to handling
+ comparisons based on <varname>OSVERSION</varname>.
+ This would often lead to failures during
+ <command>make describe</command> (and thus, the overall
+ ports <command>make index</command>). The workaround is
+ to enclose the conditional comparison in spaces, e.g.:
+ <programlisting>if ( ${OSVERSION} &gt; 500023 )</programlisting>
+ Be aware that test-installing a port on 4.9 or 5.2
+ will <emphasis>not</emphasis> detect this problem.</para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect1>
+
+ <sect1 xml:id="dads-misc">
+ <title>Miscellanea</title>
+
+ <para>The files
+ <filename>pkg-descr</filename> and <filename>pkg-plist</filename>
+ should each be double-checked. If you are reviewing a port and feel
+ they can be worded better, do so.</para>
+
+ <para>Do not copy more copies of the GNU General Public License into
+ our system, please.</para>
+
+ <para>Please be careful to note any legal issues! Do not let us
+ illegally distribute software!</para>
+ </sect1>
+
+ </chapter>
+
+ <chapter xml:id="porting-samplem">
+ <title>A Sample <filename>Makefile</filename></title>
+
+ <para>Here is a sample <filename>Makefile</filename> that you can use to
+ create a new port. Make sure you remove all the extra comments (ones
+ between brackets)!</para>
+
+ <para>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 <link linkend="porting-portlint">portlint</link> to check the
+ <filename>Makefile</filename>.</para>
+
+ <programlisting>[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 &lt;asami@FreeBSD.org&gt;
+#
+# &dollar;FreeBSD&dollar;
+[ ^^^^^^^^^ 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 "&dollar;FreeBSD&dollar;". 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 &lt;bsd.port.mk&gt;</programlisting>
+ </chapter>
+
+ <chapter xml:id="keeping-up">
+ <title>Keeping Up</title>
+
+ <para>The &os; Ports Collection is constantly changing. Here is
+ some information on how to keep up.</para>
+
+ <sect1 xml:id="freshports">
+ <title>FreshPorts</title>
+
+ <para>One of the easiest ways to learn about updates that have
+ already been committed is by subscribing to
+ <link xlink:href="http://www.FreshPorts.org/">FreshPorts</link>.
+ 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&mdash;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.)</para>
+
+ <para>If you wish to use FreshPorts, all you need is an
+ account. If your registered email address is
+ <literal>@FreeBSD.org</literal>, 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 <literal>@FreeBSD.org</literal> email address,
+ just change your email to <literal>@FreeBSD.org</literal>, subscribe,
+ then change it back again.</para>
+
+ <para>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.</para>
+ </sect1>
+
+ <sect1 xml:id="cvsweb">
+ <title>The Web Interface to the Source Repository</title>
+
+ <para>It 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
+ <link xlink:href="http://cvsweb.FreeBSD.org/ports/CHANGES">
+ CHANGES</link> file. Changes that affect individual ports
+ are now documented in the
+ <link xlink:href="http://cvsweb.FreeBSD.org/ports/UPDATING">
+ UPDATING</link> file. However, the definitive answer to any
+ question is undoubtedly to read the source code of <link xlink:href="http://cvsweb.FreeBSD.org/ports/Mk/bsd.port.mk">
+ bsd.port.mk</link>, and associated files.</para>
+
+ </sect1>
+
+ <sect1 xml:id="ports-mailling-list">
+ <title>The &os; Ports Mailing List</title>
+
+ <para>If 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 <filename>CHANGES</filename>.</para>
+
+ </sect1>
+
+ <sect1 xml:id="build-cluster">
+ <title>The &os; Port Building Cluster on
+ <systemitem class="fqdomainname">pointyhat.FreeBSD.org</systemitem></title>
+
+ <para>One 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
+ <link xlink:href="http://pointyhat.FreeBSD.org/">package building logs
+ and errors</link>.</para>
+
+ <para>Individual ports are built unless they are specifically
+ marked with <varname>IGNORE</varname>. Ports that are
+ marked with <varname>BROKEN</varname> will still be attempted,
+ to see if the underlying problem has been resolved. (This
+ is done by passing <varname>TRYBROKEN</varname> to the
+ port's <filename>Makefile</filename>.)</para>
+
+ </sect1>
+
+ <sect1 xml:id="distfile-survey">
+ <title>The &os; Port Distfile Survey</title>
+
+ <para>The 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 <link xlink:href="http://people.FreeBSD.org/~fenner/portsurvey/">FreeBSD
+ Ports distfiles survey</link> 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.</para>
+
+ </sect1>
+
+ <sect1 xml:id="portsmon">
+
+ <title>The &os; Ports Monitoring System</title>
+
+ <para>Another handy resource is the
+ <link xlink:href="http://portsmon.FreeBSD.org">
+ FreeBSD Ports Monitoring System</link> (also known as
+ <literal>portsmon</literal>). 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.</para>
+
+ <para>To get started, you can view all information about a
+ particular port by using the
+ <link xlink:href="http://portsmon.FreeBSD.org/portoverview.py">
+ Overview of One Port</link>.</para>
+
+ <para>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, <literal>portsmon</literal>
+ 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.</para>
+ </sect1>
+
+ </chapter>
+</book>