aboutsummaryrefslogtreecommitdiff
path: root/zh_TW.UTF-8
diff options
context:
space:
mode:
authorSergio Carlavilla Delgado <carlavilla@FreeBSD.org>2021-01-25 23:31:29 +0000
committerSergio Carlavilla Delgado <carlavilla@FreeBSD.org>2021-01-25 23:31:29 +0000
commit989d921f5d4ac8d8b7c831c13b8954ad1901be24 (patch)
treea5d768f9af4b55422fdf5b17064879ae1c7ce032 /zh_TW.UTF-8
parent0cff342f42461c5081b98bce7581f43df319e4f4 (diff)
downloaddoc-989d921f5d4ac8d8b7c831c13b8954ad1901be24.tar.gz
doc-989d921f5d4ac8d8b7c831c13b8954ad1901be24.zip
Migrate doc to Hugo/AsciiDoctor
I'm very pleased to announce the release of our new website and documentation using the new toolchain with Hugo and AsciiDoctor. To get more information about the new toolchain please read the FreeBSD Documentation Project Primer[1], Hugo docs[2] and AsciiDoctor docs[3]. Acknowledgment: Benedict Reuschling <bcr@> Glen Barber <gjb@> Hiroki Sato <hrs@> Li-Wen Hsu <lwhsu@> Sean Chittenden <seanc@> The FreeBSD Foundation [1] https://docs.FreeBSD.org/en/books/fdp-primer/ [2] https://gohugo.io/documentation/ [3] https://docs.asciidoctor.org/home/ Approved by: doceng, core
Diffstat (limited to 'zh_TW.UTF-8')
-rw-r--r--zh_TW.UTF-8/Makefile9
-rw-r--r--zh_TW.UTF-8/Makefile.inc3
-rw-r--r--zh_TW.UTF-8/articles/Makefile15
-rw-r--r--zh_TW.UTF-8/articles/Makefile.inc5
-rw-r--r--zh_TW.UTF-8/articles/contributing/Makefile22
-rw-r--r--zh_TW.UTF-8/articles/contributing/article.xml465
-rw-r--r--zh_TW.UTF-8/articles/freebsd-questions/Makefile22
-rw-r--r--zh_TW.UTF-8/articles/freebsd-questions/article.xml610
-rw-r--r--zh_TW.UTF-8/articles/hubs/Makefile17
-rw-r--r--zh_TW.UTF-8/articles/hubs/article.xml520
-rw-r--r--zh_TW.UTF-8/articles/hubs/zh_TW.po665
-rw-r--r--zh_TW.UTF-8/articles/leap-seconds/Makefile19
-rw-r--r--zh_TW.UTF-8/articles/leap-seconds/article.xml64
-rw-r--r--zh_TW.UTF-8/articles/leap-seconds/zh_TW.po239
-rw-r--r--zh_TW.UTF-8/articles/mailing-list-faq/Makefile26
-rw-r--r--zh_TW.UTF-8/articles/mailing-list-faq/article.xml416
-rw-r--r--zh_TW.UTF-8/articles/nanobsd/Makefile28
-rw-r--r--zh_TW.UTF-8/articles/nanobsd/article.xml434
-rw-r--r--zh_TW.UTF-8/articles/pr-guidelines/Makefile19
-rw-r--r--zh_TW.UTF-8/articles/pr-guidelines/article.xml875
-rw-r--r--zh_TW.UTF-8/articles/problem-reports/Makefile19
-rw-r--r--zh_TW.UTF-8/articles/problem-reports/article.xml1103
-rw-r--r--zh_TW.UTF-8/articles/remote-install/Makefile30
-rw-r--r--zh_TW.UTF-8/articles/remote-install/article.xml475
-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/Makefile28
-rw-r--r--zh_TW.UTF-8/books/faq/book.xml6910
-rw-r--r--zh_TW.UTF-8/books/faq/zh_TW.po7846
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/Makefile37
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/book.xml8465
-rw-r--r--zh_TW.UTF-8/books/fdp-primer/zh_TW.po12718
-rw-r--r--zh_TW.UTF-8/books/handbook/Makefile167
-rw-r--r--zh_TW.UTF-8/books/handbook/book.xml61783
-rw-r--r--zh_TW.UTF-8/books/handbook/zh_TW.po106292
-rw-r--r--zh_TW.UTF-8/books/porters-handbook/Makefile45
-rw-r--r--zh_TW.UTF-8/books/porters-handbook/book.xml23101
-rw-r--r--zh_TW.UTF-8/books/porters-handbook/zh_TW.po37193
-rw-r--r--zh_TW.UTF-8/htdocs/Makefile52
-rw-r--r--zh_TW.UTF-8/htdocs/Makefile.inc5
-rw-r--r--zh_TW.UTF-8/htdocs/about.xml98
-rw-r--r--zh_TW.UTF-8/htdocs/applications.xml129
-rw-r--r--zh_TW.UTF-8/htdocs/art.xml127
-rw-r--r--zh_TW.UTF-8/htdocs/availability.xml27
-rw-r--r--zh_TW.UTF-8/htdocs/community.xsl148
-rw-r--r--zh_TW.UTF-8/htdocs/developers.xml566
-rw-r--r--zh_TW.UTF-8/htdocs/doc/Makefile47
-rw-r--r--zh_TW.UTF-8/htdocs/docs.xml24
-rw-r--r--zh_TW.UTF-8/htdocs/docs/Makefile16
-rw-r--r--zh_TW.UTF-8/htdocs/docs/books.xml364
-rw-r--r--zh_TW.UTF-8/htdocs/docs/webresources.xml111
-rw-r--r--zh_TW.UTF-8/htdocs/index.xsl322
-rw-r--r--zh_TW.UTF-8/htdocs/logo.xml118
-rw-r--r--zh_TW.UTF-8/htdocs/news/Makefile59
-rw-r--r--zh_TW.UTF-8/htdocs/platforms/Makefile12
-rw-r--r--zh_TW.UTF-8/htdocs/platforms/Makefile.inc4
-rw-r--r--zh_TW.UTF-8/htdocs/platforms/index.xml112
-rw-r--r--zh_TW.UTF-8/htdocs/send-pr.xml163
-rw-r--r--zh_TW.UTF-8/htdocs/support.xml40
-rw-r--r--zh_TW.UTF-8/htdocs/where.xml622
-rw-r--r--zh_TW.UTF-8/share/xml/authors.ent94
-rw-r--r--zh_TW.UTF-8/share/xml/catalog.xml34
-rw-r--r--zh_TW.UTF-8/share/xml/entities.ent26
-rw-r--r--zh_TW.UTF-8/share/xml/freebsd-dblatex.xsl17
-rw-r--r--zh_TW.UTF-8/share/xml/freebsd-fo.xsl69
-rw-r--r--zh_TW.UTF-8/share/xml/freebsd-xhtml.xsl20
-rw-r--r--zh_TW.UTF-8/share/xml/glossary.ent1920
-rw-r--r--zh_TW.UTF-8/share/xml/header.l10n.ent121
-rw-r--r--zh_TW.UTF-8/share/xml/l10n.ent124
-rw-r--r--zh_TW.UTF-8/share/xml/libcommon.xsl105
-rw-r--r--zh_TW.UTF-8/share/xml/mailing-lists.ent645
-rw-r--r--zh_TW.UTF-8/share/xml/navibar.l10n.ent171
-rw-r--r--zh_TW.UTF-8/share/xml/news.xml4976
-rw-r--r--zh_TW.UTF-8/share/xml/press.xml528
-rw-r--r--zh_TW.UTF-8/share/xml/release.l10n.ent137
-rw-r--r--zh_TW.UTF-8/share/xml/trademarks.ent310
-rw-r--r--zh_TW.UTF-8/share/xml/urls.ent125
92 files changed, 0 insertions, 297796 deletions
diff --git a/zh_TW.UTF-8/Makefile b/zh_TW.UTF-8/Makefile
deleted file mode 100644
index 55b5374fdf..0000000000
--- a/zh_TW.UTF-8/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# $FreeBSD$
-
-SUBDIR = articles
-SUBDIR += books
-
-COMPAT_SYMLINK= zh_TW
-
-DOC_PREFIX = ${.CURDIR}/..
-.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/Makefile.inc b/zh_TW.UTF-8/Makefile.inc
deleted file mode 100644
index 453700a49b..0000000000
--- a/zh_TW.UTF-8/Makefile.inc
+++ /dev/null
@@ -1,3 +0,0 @@
-# $FreeBSD$
-
-DOC_PREFIX?= ${.CURDIR}/../..
diff --git a/zh_TW.UTF-8/articles/Makefile b/zh_TW.UTF-8/articles/Makefile
deleted file mode 100644
index 24ccfc0219..0000000000
--- a/zh_TW.UTF-8/articles/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-# $FreeBSD$
-
-SUBDIR =
-SUBDIR+= contributing
-SUBDIR+= freebsd-questions
-SUBDIR+= hubs
-SUBDIR+= leap-seconds
-SUBDIR+= mailing-list-faq
-SUBDIR+= nanobsd
-SUBDIR+= pr-guidelines
-SUBDIR+= problem-reports
-SUBDIR+= remote-install
-
-DOC_PREFIX?= ${.CURDIR}/../..
-.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/articles/Makefile.inc b/zh_TW.UTF-8/articles/Makefile.inc
deleted file mode 100644
index e9ca57f579..0000000000
--- a/zh_TW.UTF-8/articles/Makefile.inc
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# $FreeBSD$
-#
-
-DESTDIR?= ${DOCDIR}/zh_TW.UTF-8/articles/${.CURDIR:T}
diff --git a/zh_TW.UTF-8/articles/contributing/Makefile b/zh_TW.UTF-8/articles/contributing/Makefile
deleted file mode 100644
index 72cfc4b491..0000000000
--- a/zh_TW.UTF-8/articles/contributing/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# The FreeBSD Traditional Chinese Project
-#
-# Original Revision: 1.6
-# $FreeBSD$
-#
-# Article: Contributing to FreeBSD
-
-DOC?= article
-
-FORMATS?= html
-WITH_ARTICLE_TOC?= YES
-
-INSTALL_COMPRESSED?=gz
-INSTALL_ONLY_COMPRESSED?=
-
-SRCS= article.xml
-
-URL_RELPREFIX?= ../../../..
-DOC_PREFIX?= ${.CURDIR}/../../..
-
-.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/articles/contributing/article.xml b/zh_TW.UTF-8/articles/contributing/article.xml
deleted file mode 100644
index 56ff1a66e0..0000000000
--- a/zh_TW.UTF-8/articles/contributing/article.xml
+++ /dev/null
@@ -1,465 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
- "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd">
-<!--
- The FreeBSD Documentation Project
- The FreeBSD Chinese (Traditional) Documentation Project
-
- Original Revision: 1.506
- Chased Revision: 1.508
--->
-<article 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>
-
-
- <abstract>
- <para>無論是個人或是各種組織,如果希望為 FreeBSD 提供幫助,都可以在本文中找到合適的方法。</para>
- </abstract>
-
- <authorgroup>
- <author><personname><firstname>Jordan</firstname><surname>Hubbard</surname></personname><contrib>原著: </contrib></author>
- </authorgroup>
-
- <legalnotice xml:id="trademarks" role="trademarks">
- &tm-attrib.freebsd;
- &tm-attrib.ieee;
- &tm-attrib.general;
- </legalnotice>
-
- <pubdate>$FreeBSD$</pubdate>
-
- <releaseinfo>$FreeBSD$</releaseinfo>
-
- </info>
-
- <indexterm><primary>貢獻</primary></indexterm>
-
- <para>你希望替 FreeBSD 做點什麼嗎?太好了,我們歡迎你。FreeBSD
- 正是有賴於廣大使用者的貢獻才得以發展壯大的。我們不僅非常感謝您所做的貢獻,而且,這些工作對於 FreeBSD 的持續發展也至關重要。</para>
-
-
- <para>也許與您想像的不同,您既不必得是一名出色的 Programmer,也無須和
- FreeBSD core team 成員有很好的私交,我們會一視同仁的對待您的工作。
- FreeBSD 的開發人員遍布全球,大家技術專長各異,年齡分布也非常廣泛。
- 然而,每天我們都在面對持續增加的工作,而苦於沒有足夠的人手,因此我們隨時歡迎您的幫助。</para>
-
- <para>FreeBSD 計劃所處理的是一個完整的作業系統環境,而不只是一個 kernel 或是一些零散的工具包。
- 因此,我們的 <filename>TODO</filename> 待辦任務列表裡包含各式各樣的工作:
- 從文件、使用者測試、demo,到系統安裝程式和更專業的 kernel 開發。
- 因此無論您的技術水準如何,從事何種領域,都可以幫助這個計劃。</para>
-
- <para>我們鼓勵從事和 FreeBSD 相關工作的企業和我們聯繫。
- 您需要一些特殊的擴展來使您的產品運轉起來嗎?
- 您會發現我們很樂意答應您的請求,除非是特別稀奇古怪的。
- 您是否正從事相關的增值業務? 讓我們來幫助您吧,
- 我們也許可以在某些方面相互合作。
- 自由軟體界正在努力打破舊有的框框(像是關於軟體開發、銷售和維護),
- 我們希望懇請您至少能給它一次機會。</para>
-
- <sect1 xml:id="contrib-what">
- <title>我們的需求</title>
-
- <para>下面列出了一些需要完成的任務和子計劃,
- 它們代表 <filename>TODO</filename>(待辦任務列表)
- 列表的意思,以及使用者的要求。</para>
-
- <sect2 xml:id="non-programmer-tasks">
- <title>正在進行中的任務(非程式開發人員)</title>
-
- <para>很多參加 FreeBSD 計劃的人不是 Programmer。
- 這個計劃裡有文件撰寫者、網頁設計師、以及技術支援人員。
- 對於這些義工來說,他們只需要貢獻一些時間,並且具有學習的意願。</para>
-
- <orderedlist>
- <listitem>
- <para>您可以時常翻閱 FAQ 和手冊(Handbook)
- ,如果發現有解釋不清楚的地方,或是不合時宜的文件,甚至完全不正確的地方,
- 都請告訴我們。當然,若能順手把他們修正,並把勘誤寄給我們,那就更好了。:)
- (SGML 其實並不難學,但我們也不反對您直接提交一般 ASCII 的純文字版本)。</para>
- </listitem>
-
- <listitem>
- <para>幫助我們把 FreeBSD 文件翻譯成你的母語。
- 如果你的母語版本已經存在了,
- 也可以翻譯一些額外的文件,或者檢查那些已有的文件是否為最新版。
- 您可以先簡單看看 FreeBSD 文件計劃中有關 <link xlink:href="&url.books.fdp-primer;/translations.html">翻譯時的常見問題</link>。
- 參加翻譯工作,並不是說您要孤軍奮戰翻譯所有 FreeBSD 文件。
- 身為義工,要做多少工作完全取決於您的意願。一旦某個人開始翻譯了,
- 之後幾乎一定會有其他人參與到這些工作中來。
- 如果時間有限,或者精力不夠去翻譯整份文件,那可以首先去翻譯安裝指南。</para>
- </listitem>
-
- <listitem>
- <para>閱讀 &a.questions; 並偶爾翻閱(甚至有規律地這樣做) &ng.misc;
- 。與別人分享您的專業知識,
- 並幫助他們解決問題,是件令人愉悅的事情;
- 有時候,您甚至可以在這個過程中學到一些新東西!
- 這些論壇有時也會為您激發出一些不錯的想法。</para>
- </listitem>
- </orderedlist>
- </sect2>
-
- <sect2 xml:id="ongoing-programmer-tasks">
- <title>正在進行中的任務(程式開發人員)</title>
- <para>列在這裡的大部分任務都需要您投入可觀的時間,或者需要您在 FreeBSD kernel
- 方面有豐富的知識,或者兩者都要。當然這裡也有很多重要的任務,適合像是
- <quote>weekend hackers</quote> 這類只用週末就可以搞定的 Hacker。</para>
-
- <orderedlist>
- <listitem>
- <para>如果您正在跑的是 FreeBSD -CURRENT 版本,並且網路速度還不錯,
- 那麼可以到 <systemitem class="fqdomainname">current.FreeBSD.org</systemitem>,
- 這台每天會有一個新版本 &mdash; 如果您有空,
- 您可以三不五時下載並安裝,
- 其間如果出了什麼問題,請告訴我們。</para>
- </listitem>
-
- <listitem>
- <para>閱讀 &a.bugs;。這些問題,或許您能提供有建設性意義的意見,
- 或者幫忙測試一些 patch 。此外,甚至可以嘗試修正其中的一些問題。</para>
- </listitem>
-
- <listitem>
- <para>如果您知道有一些修正已經在 -CURRENT 上成功地使用,
- 但在經過一段時間(通常是 2 週左右)之後,仍未合併到 -STABLE
- (這步驟就是 MFC -- Merged From Current),那麼可以給相關的 committer 人員發封禮貌的提醒信。</para>
- </listitem>
-
- <listitem>
- <para>將第三方(3rd party)軟體加入到原始碼中的
- <filename>src/contrib</filename> 目錄。</para>
- </listitem>
-
- <listitem>
- <para>確保 <filename>src/contrib</filename> 中的原始碼是最新的。</para>
- </listitem>
-
- <listitem>
- <para>編譯原始碼(或是部分原始碼)時,請改用更高的警告等級(warning level)
- 以便偵錯(debug)用,並在完成測試、確認正常完畢之後,清除這些編譯的警告等級。</para>
- </listitem>
-
- <listitem>
- <para>更新那些在 ports 中使用過時的東西,
- 例如 <function>gets()</function> 或包含
- <filename>malloc.h</filename> 所產生的警告。</para>
- </listitem>
-
- <listitem>
- <para>如果有為 ports 作了任何修正,
- 請記得將您的 patch 發給原作者 (這樣下次升級時,您的工作會變得輕鬆一些)。</para>
- </listitem>
-
- <listitem>
- <para>先取得正式的標準,如 &posix; 的副本。
- 在 <link xlink:href="&url.base;/projects/c99/index.html">FreeBSD
- C99 &amp; POSIX 標準相容計劃</link> 網站上,可以得到相關鏈接。
- 請將 FreeBSD 的行為與上述的標準進行比較,若所得結果與 C99 &amp; POSIX 標準不同的話,
- 特別是那些細節地方的微小差異,請發一個關於它的 PR (問題報告)。
- 如果可能,請指出如何修正它,並隨 PR 提交 patch 。
- 如果您認為標準有問題,請向這些規格標準的相關團體,請求對其進行重新的考慮。</para>
- </listitem>
-
- <listitem>
- <para>為這份列表提供更多建議!</para>
- </listitem>
- </orderedlist>
- </sect2>
-
- <sect2>
- <title>查閱整個 PR 資料庫</title>
-
- <indexterm><primary>問題報告資料庫</primary></indexterm>
-
- <para><link xlink:href="http://www.FreeBSD.org/cgi/query-pr-summary.cgi">FreeBSD
- PR 列表</link> 這裡會顯示目前所有 PR 的問題狀態,以及由
- FreeBSD 使用者提交的改進建議。
- PR 資料庫同時包括了開發人員和非開發人員的任務。
- 查看那些尚未解決的 PR,並看看是否有您感興趣的任務。
- 這其中可能有一些是非常簡單的問題,只需要看一看並確認 PR 是正確的。
- 另外一些可能會非常複雜,或者完全未附任何修正。</para>
-
- <para>首先看一看那些還沒有人接手的 PR。
- 如果 PR 已經分配給了其它人,但看起來是您能夠處理的,
- 您可以寄信給那個人,並詢問您是否可以提供幫助 &mdash;
- 他們可能已經有可供測試的 patch ,或有一些可供討論的意見。</para>
- </sect2>
-
- <sect2>
- <title>由 <quote>Ideas</quote> 中選一項</title>
-
- <para><link xlink:href="&url.base;/projects/ideas/">&os; list of
- projects and ideas for volunteers</link> 同樣地開放給有意願參與
- &os; 計劃的人。
- 這份清單將持續地更新,同時提供各個項目的資訊給所有人
- (不論是否為程式設計人員)。</para>
- </sect2>
- </sect1>
-
- <sect1 xml:id="contrib-how">
- <title>如何提供幫助</title>
-
- <para>基本上可以分為以下 5 種方式:</para>
-
- <sect2 xml:id="contrib-general">
- <title>錯誤報告和意見發表</title>
-
- <para>通常,<emphasis>一般</emphasis>
- 的技術想法和建議應該發到 &a.hackers;。
- 同樣地,對於這些東西有興趣的人 (當然,
- 他們同時還要能夠容忍 <emphasis>大量的</emphasis> 郵件!)
- 可以考慮訂閱 &a.hackers;。
- 請參閱 <link xlink:href="&url.books.handbook;/eresources.html#ERESOURCES-MAIL">FreeBSD
- 使用手冊</link> 以了解關於這個郵遞論壇,
- 以及其它郵遞論壇的詳細情況。</para>
-
- <para>如果您發現了 bug 或者想要提交某些修改,
- 請透過 &man.send-pr.1; 程式或使用
- <link xlink:href="&url.base;/send-pr.html">網頁介面
- 的回報</link> 來提交。請試著填寫 PR 的每個項目。
- 一般來說,除非 patch 檔超過 65 KB,我們建議在 PR 中直接附上 patch 就可以了。
- 若可直接套用 patch 到原始碼的話,那麼建議在 PR 的
- Synopsis 欄位註明 <literal>[PATCH]</literal>。
- 對了,在附上 patch 時,請 <emphasis>不要</emphasis>
- 透過滑鼠的『複製、貼上』來進行,因為這樣做會把 Tab 變成空格,
- 會導致 patch 就不能用了。如果 patch 超過 20KB,
- 請考慮壓縮它並使用 &man.uuencode.1; 來進行編碼。</para>
-
- <para>在寫完 PR 之後,您會收到一封確認郵件以及事件追蹤編號。
- 請保留這個編號,因為事後可以用這編號發信到 &a.bugfollowup;
- 來回覆、提供關於該事件的後續資料。您需要做的是將編號放到郵件的標題中,
- 例如 <literal>"Re:
- kern/3377"</literal>。
- 若是同一問題的回覆方面,應該透過這種方式來進行。</para>
-
- <para>如果您在一段時間 (超過 3 天甚至 1 週,這取決於您的郵件服務)之後仍然沒有收到確認信
- 或者由於一些原因無法使用 &man.send-pr.1; 程式,
- 則可以發信到 &a.bugs; 來請別人幫你代寄。</para>
-
- <para>請參閱 <link xlink:href="&url.articles.problem-reports;/article.html">這篇文章</link>
- 了解如何撰寫好的問題報告。</para>
- </sect2>
-
- <sect2>
- <title>對於文件的修訂</title>
-
- <indexterm><primary>提交文件</primary></indexterm>
-
- <para>文件的修改方面,是由 &a.doc; 來審查。
- 請參閱 <link xlink:href="&url.books.fdp-primer;/index.html">FreeBSD Documentation Project Primer</link>
- 來獲得完整的教學細節。
- 請按照 <xref linkend="contrib-general"/> 中介紹的方法使用 &man.send-pr.1;
- 來提交新的文件,或者改善現有的文件 (哪怕是很小的改進也是歡迎的!)。</para>
- </sect2>
-
- <sect2>
- <title>對於現有原始碼的修改</title>
-
- <indexterm><primary>FreeBSD-CURRENT</primary></indexterm>
-
- <para>在現有原始碼上進行修改或增加功能,在某種程度上是需要更多技巧的事,
- 並且還跟您對於目前 FreeBSD 的開發現狀了解程度有關。
- 有多種方式可以得到被稱作 <quote>FreeBSD-CURRENT</quote>
- 的 FreeBSD 開發版本。
- 請參閱 FreeBSD 使用手冊的 <link xlink:href=" &url.books.handbook;/current-stable.html">相關部份</link> ,來了解使用 FreeBSD-CURRENT 的詳情。</para>
-
- <para>在舊的原始碼上進行修改,則通常可能原始碼已過時,
- 或與新的版本差異太大而無法被重新整合到 FreeBSD 中。
- 如果您有訂 &a.announce; 以及 &a.current; 的話,
- 則可以透過它們來大致了解目前的開發狀態。</para>
-
- <para>若您能夠儘量以最新的原始碼來進行您的修改,
- 則下一步要做的事情就是產生您所修改的 diff 檔,
- 並將它發給 FreeBSD 的維護人員。這項工作可以透過 &man.diff.1;
- 命令來完成。</para>
-
- <para>提交 patch 時,建議 &man.diff.1; 格式採用 unified diff (可以用 <command>diff
- -u</command> 來產生)。不過,如果您修改了大量的原始碼,
- 則使用 <command>diff -c</command> 來生成的 context diff
- 的 diff 可能更容易閱讀,因而推薦使用。一般而言,大都是採用 <command>diff -ruN</command> 即可。</para>
-
- <indexterm>
- <primary><command>diff</command></primary>
- </indexterm>
-
- <para>例如:</para>
-
- <para>
- <screen>&prompt.user; <userinput>diff -c oldfile newfile</userinput></screen>
-
- 或
-
- <screen>&prompt.user; <userinput>diff -c -r olddir newdir</userinput></screen>
-
- 將會對特定目錄,產生 context 的 diff 檔。</para>
-
- <para>或者像是...
- <screen>&prompt.user; <userinput>diff -u oldfile newfile</userinput></screen>
- 或
- <screen>&prompt.user; <userinput>diff -u -r olddir newdir</userinput></screen>
-
- 將產生一樣的 diff ,但是格式為 unified 。</para>
-
- <para>更多的細節部份,請參閱 &man.diff.1;。</para>
-
- <para>一旦您使用 &man.diff.1; 來產生 diff 檔 (可以使用
- &man.patch.1; 命令來測試一下),就可以提交它們,以便被 FreeBSD 收錄。
- 透過使用 <xref linkend="contrib-general"/>
- 中所介紹的 &man.send-pr.1; 程式就可以完成這項工作。
- 請注意:不要只把 diff 檔發到 &a.hackers;,
- 否則它們可能會被遺忘! 我們會非常感激您提交的修改
- (這是一個義工計劃!); 因為我們都很忙,
- 因此有時不一定能夠立即修正問題,但 PR 資料庫將一直保持著這些記錄,
- 因此只要有人有了時間它們就能被改正了。
- 如果您的問題報告中包括 patch ,不要忘了在標題加上
- <literal>[PATCH]</literal> 來強調一下。</para>
-
- <indexterm>
- <primary><command>uuencode</command></primary>
- </indexterm>
-
- <para>如果您認為合適 (例如增、刪檔案或更改檔名),
- 還可以考慮使用
- <command>tar</command> 來將檔案打包,然後用 &man.uuencode.1;
- 來編碼。此外,也可以用 &man.shar.1; 產生的方式。</para>
-
- <para>如果您的修改可能存在潛在的爭議,例如,
- 您不確定相關的版權問題,或者感覺需要經過更嚴格的復審才可以發佈它們,
- 則應直接發給 &a.core;,而不是透過 &man.send-pr.1; 來發送。
- &a.core; 這小組成員大多從事 FreeBSD 的日常工作。
- 需要注意的是,這個小組也因此十分忙碌,
- 因此只有在非常必要的時候,才應寫信給他們。</para>
-
- <para>請參考 &man.intro.9; 和 &man.style.9; 以了解關於撰寫程式碼的風格偏好。
- 若能在送出相關程式碼之前,先了解這些,那對大家來說將是極大的幫助。</para>
- </sect2>
-
- <sect2>
- <title>新原始碼或重要的加值軟體包</title>
-
- <para>如果您打算提供規模較大的原始碼,或者為 FreeBSD 增加重要的新功能,
- 則可能必須將它們透過 uuencode 進行編碼,或傳到某個 Web 或
- FTP 站點,以便更多的人能夠得到它。如果您沒有這樣的主機,
- 請到相關的 FreeBSD 郵遞論壇提出,看看是否有人願意幫您放置它們。</para>
-
- <para>對於大量的原始碼而言,關於版權的問題肯定會被提出。
- FreeBSD 基本系統中能夠使用的版權聲明包括:</para>
-
- <orderedlist>
- <listitem>
- <para>BSD<indexterm><primary>BSD 版權聲明</primary></indexterm> 版權。我們傾向於使用這類授權的原始碼,
- 因為它『不附加多餘的條件』,因而更能夠吸引商業企業使用。
- FreeBSD 並不反對商業公司使用它的原始碼,相反,
- 我們積極地鼓勵商業公司使用我們的原始碼,
- 當然,如果它們若最終能把部分原始碼,重新捐贈給 FreeBSD 就更好了。</para>
- </listitem>
-
- <listitem>
- <para>GNU General Public License,或簡稱 <quote>GPL</quote>。<indexterm><primary>GPL</primary><see>GNU General Public License</see></indexterm><indexterm><primary>GNU General Public License</primary></indexterm>
- 我們並不很歡迎使用這樣授權的原始碼,
- 因為商業公司使用它需要做更多的工作。不過,由於很多使用
- GPL 授權的原始碼目前是無法避免的 (compiler, assembler, text formatter等等)
- ,拒絕使用所有採用這樣授權的軟體是很不明智的。
- 採用 GPL 授權的原始碼會被放到原始碼的一些特定的位置,例如
- <filename>/sys/gnu</filename> 或
- <filename>/usr/src/gnu</filename>,以便那些認為 GPL
- 可能會造成麻煩的人能夠作出適當的判斷。</para>
- </listitem>
- </orderedlist>
-
- <para>使用其它授權的原始碼在進入 FreeBSD 之前必須經過慎重的復審和考慮。
- 採用包含嚴厲限制的商業授權的原始碼,一般來說會被拒絕,
- 但我們鼓勵這些原始碼的作者,透過自己的管道來發布它們。</para>
-
- <para>若要在您的成果上加入 <quote>BSD-based</quote> 版權的話,
- 請把下列文字放到每份原始碼的最開始部分,
- 並用適當的文字替換 <literal>%%</literal> 之間的文字。</para>
-
- <programlisting>Copyright (c) %%proper_years_here%%
- %%your_name_here%%, %%your_state%% %%your_zip%%.
- 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 as
- the first lines of this file unmodified.
-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 %%your_name_here%% ``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 %%your_name_here%% 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.
-
- &#36;Id&#36;</programlisting>
-
- <para>為了方便您的使用,在
- <filename>/usr/share/examples/etc/bsd-style-copyright</filename>
- 也可以找到此授權的副本。</para>
- </sect2>
-
- <sect2>
- <title>贊助資金、硬體或 Internet mirror</title>
-
- <para>我們非常願意接受各種形式的捐贈,以進一步拓展 FreeBSD 計劃
- ,因為有您的支持,像我們這樣的義工努力才能夠有更大的成就!
- 捐贈硬體也非常重要,因為這樣能夠幫助我們增加可支援的硬體種類,
- 而我們中的很多人並沒有足夠的資金來購置這些硬體。</para>
-
- <sect3 xml:id="donations">
- <title>捐款</title>
-
- <para>FreeBSD 基金會是一個非營利的、有課稅豁免權的基金會,
- 之所以會建立這個基金會,是為了讓 FreeBSD 計劃能夠可長可久。
- 因為該基金會屬 501(c)3 實體,一般而言捐款給基金會的話,可以免繳美國聯邦收入稅,
- 以及科羅拉多州收入稅。通常對於有課稅豁免權的實體進行捐贈的話,
- 可以折抵聯邦收入中應課稅部分的金額。</para>
-
- <para>您可以把支票寄往:
- <address>
- The FreeBSD Foundation
- <street>7321 Brockway Dr.</street>
- <city>Boulder</city>, <state>CO</state> <postcode>80303</postcode>
- <country>USA</country>
- </address>
- </para>
-
- <para>FreeBSD 基金會現在可以透過 PayPal 從網上接受捐款。
- 如果您想向基金會捐款,請參閱 <link xlink:href="http://www.freebsdfoundation.org">FreeBSD 基金會</link> 網站。</para>
-
- <para>關於 FreeBSD 基金會的更多詳情,可以在 <link xlink:href="http://people.FreeBSD.org/~jdp/foundation/announcement.html">FreeBSD
- 基金會 -- 介紹</link> 找到。要聯絡基金會,
- 請發送電子郵件到
- <email>bod@FreeBSDFoundation.org</email>。</para>
- </sect3>
-
- <sect3>
- <title>捐贈硬體</title>
- <indexterm><primary>捐贈</primary></indexterm>
-
- <para>FreeBSD 計劃歡迎任何人捐贈可以使用的硬體。
- 如果您有興趣捐贈硬體,請聯繫 <link xlink:href="&url.base;/donations/">捐贈聯絡人辦公室</link>。</para>
- </sect3>
-
- <sect3>
- <title>成為 FreeBSD mirror 的網站</title>
-
- <para>我們歡迎新的 FTP、WWW 或
- <command>cvsup</command> mirror 站。如果您希望成為這樣的 mirror 站,
- 請參閱 <link xlink:href="&url.articles.hubs;/index.html">如何架設 FreeBSD mirror</link>
- 一文,以了解進一步的情況。</para>
- </sect3>
- </sect2>
- </sect1>
-
- <index/>
-</article>
diff --git a/zh_TW.UTF-8/articles/freebsd-questions/Makefile b/zh_TW.UTF-8/articles/freebsd-questions/Makefile
deleted file mode 100644
index e0524136c2..0000000000
--- a/zh_TW.UTF-8/articles/freebsd-questions/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# $FreeBSD$
-# Original revision: 1.6
-#
-# Article: How to get best results from the FreeBSD-questions mailing list
-
-MAINTAINER=chinsan.tw@gmail.com
-
-DOC?= article
-
-FORMATS?= html
-WITH_ARTICLE_TOC?= YES
-
-INSTALL_COMPRESSED?= gz
-INSTALL_ONLY_COMPRESSED?=
-
-SRCS= article.xml
-
-URL_RELPREFIX?= ../../../..
-DOC_PREFIX?= ${.CURDIR}/../../..
-
-.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/articles/freebsd-questions/article.xml b/zh_TW.UTF-8/articles/freebsd-questions/article.xml
deleted file mode 100644
index ad017406e0..0000000000
--- a/zh_TW.UTF-8/articles/freebsd-questions/article.xml
+++ /dev/null
@@ -1,610 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
- "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd">
-<!--
- Original revision: 1.24
--->
-<article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="zh_tw">
- <info><title>如何在 FreeBSD-questions mailing list 上得到正解</title>
-
-
- <author><personname><firstname>Greg</firstname><surname>Lehey</surname></personname><affiliation>
- <address><email>grog@FreeBSD.org</email></address>
- </affiliation></author>
-
- <legalnotice xml:id="trademarks" role="trademarks">
- &tm-attrib.freebsd;
- &tm-attrib.microsoft;
- &tm-attrib.netscape;
- &tm-attrib.opengroup;
- &tm-attrib.qualcomm;
- &tm-attrib.general;
- </legalnotice>
-
- <pubdate>$FreeBSD$</pubdate>
-
- <releaseinfo>$FreeBSD$</releaseinfo>
-
- <abstract>
- <para>本文主要是給準備寫信到 FreeBSD-questions mailing list 的人提供一些參考。
- 我們會給你一些發問的技巧與建議,以便讓你的答案得到更有用的答覆。</para>
-
- <para>本文會定期發到 FreeBSD-questions mailing list 上。</para>
- </abstract>
- </info>
-
- <sect1>
- <title xml:id="Introduction">簡介</title>
-
- <para><literal>FreeBSD-questions</literal> is a mailing list maintained by
- the FreeBSD project to help people who have questions about the normal
- use of FreeBSD. Another group, <literal>FreeBSD-hackers</literal>,
- discusses more advanced questions such as future development
- work.</para>
-
- <note>
- <para>The term <quote>hacker</quote> has nothing to do with breaking
- into other people's computers. The correct term for the latter
- activity is <quote>cracker</quote>, but the popular press has not found
- out yet. The FreeBSD hackers disapprove strongly of cracking
- security, and have nothing to do with it. For a longer description of
- hackers, see Eric Raymond's <link xlink:href="http://www.catb.org/~esr/faqs/hacker-howto.html">How To Become
- A Hacker</link></para>
- </note>
-
- <para>This is a regular posting aimed to help both those seeking advice
- from FreeBSD-questions (the <quote>newcomers</quote>), and also those
- who answer the questions (the <quote>hackers</quote>).</para>
-
- <para>Inevitably there is some friction, which stems from the different
- viewpoints of the two groups. The newcomers accuse the hackers of being
- arrogant, stuck-up, and unhelpful, while the hackers accuse the
- newcomers of being stupid, unable to read plain English, and expecting
- everything to be handed to them on a silver platter. Of course, there is
- an element of truth in both these claims, but for the most part these
- viewpoints come from a sense of frustration.</para>
-
- <para>In this document, I would like to do something to relieve this
- frustration and help everybody get better results from
- FreeBSD-questions. In the following section, I recommend how to submit
- a question; after that, we will look at how to answer one.</para>
- </sect1>
-
- <sect1>
- <title xml:id="subscribe">How to subscribe to FreeBSD-questions</title>
-
- <para>FreeBSD-questions is a mailing list, so you need mail access. Point
- your WWW browser to the <link xlink:href="&a.questions.url;">information page of the FreeBSD-questions mailing list</link>.
- In the section titled <quote>Subscribing to freebsd-questions</quote> fill
- in the <quote>Your email address</quote> field; the other fields are optional.
- </para>
-
- <note>
- <para>The password fields in the subscription form provide only mild
- security, but should prevent others from messing with your
- subscription. <emphasis>Do not use a valuable password</emphasis> as
- it will occasionally be emailed back to you in cleartext.</para>
- </note>
-
- <para>You will receive a confirmation message from
- <application>mailman</application>; follow the included instructions
- to complete your subscription.</para>
-
- <para>Finally, when you get the <quote>Welcome</quote> message from
- <application>mailman</application> telling you the details of the list
- and subscription area password, <emphasis>please save it</emphasis>.
- If you ever should want to leave the list, you will need the information
- there. See the next section for more details.</para>
- </sect1>
-
- <sect1>
- <title xml:id="unsubscribe">How to unsubscribe from FreeBSD-questions</title>
-
- <para>When you subscribed to FreeBSD-questions, you got a welcome message
- from <application>mailman</application>. In this message, amongst
- other things, it told you how to unsubscribe. Here is a typical
- message:</para>
-
- <literallayout class="monospaced">Welcome to the freebsd-questions@freebsd.org mailing list!
-
-To post to this list, send your email to:
-
- freebsd-questions@freebsd.org
-
-General information about the mailing list is at:
-
- http://lists.freebsd.org/mailman/listinfo/freebsd-questions
-
-If you ever want to unsubscribe or change your options (e.g., switch to
-or from digest mode, change your password, etc.), visit your
-subscription page at:
-
-http://lists.freebsd.org/mailman/options/freebsd-questions/grog%40lemsi.de
-
-You can also make such adjustments via email by sending a message to:
-
- freebsd-questions-request@freebsd.org
-
-with the word `help' in the subject or body (don't include the
-quotes), and you will get back a message with instructions.
-
-You must know your password to change your options (including changing
-the password, itself) or to unsubscribe. It is:
-
- 12345
-
-Normally, Mailman will remind you of your freebsd.org mailing list
-passwords once every month, although you can disable this if you
-prefer. This reminder will also include instructions on how to
-unsubscribe or change your account options. There is also a button on
-your options page that will email your current password to you.</literallayout>
-
- <para>From the URL specified in your <quote>Welcome</quote> message you
- may visit the <quote>Account management page</quote> and enter a request
- to <quote>Unsubscribe</quote> you from FreeBSD-questions mailing
- list.</para>
-
- <para>A confirmation message will be sent to you from
- <application>mailman</application>; follow the included instructions
- to finish unsubscribing.</para>
-
- <para>If you have done this, and you still can not figure out what
- is going on, send a message to
- <email>freebsd-questions-request@FreeBSD.org</email>, and they will
- sort things out for you. <emphasis>Do not</emphasis> send a message to
- FreeBSD-questions: they can not help you.</para>
- </sect1>
-
- <sect1>
- <title xml:id="askwho">Should I ask <literal>-questions</literal> or
- <literal>-hackers</literal>?</title>
-
- <para>Two mailing lists handle general questions about FreeBSD,
- <literal>FreeBSD-questions</literal> and
- <literal>FreeBSD-hackers</literal>. In some cases, it is not really
- clear which group you should ask. The following criteria should help
- for 99% of all questions, however:</para>
-
- <orderedlist>
- <listitem>
- <para>If the question is of a general nature, ask
- <literal>FreeBSD-questions</literal>. Examples might be questions
- about installing FreeBSD or the use of a particular &unix;
- utility.</para>
- </listitem>
-
- <listitem>
- <para>If you think the question relates to a bug, but you are not sure,
- or you do not know how to look for it, send the message to
- <literal>FreeBSD-questions</literal>.</para>
- </listitem>
-
- <listitem>
- <para>If the question relates to a bug, and you are
- <emphasis>sure</emphasis> that it is a bug (for example, you can
- pinpoint the place in the code where it happens, and you maybe have
- a fix), then send the message to
- <literal>FreeBSD-hackers</literal>.</para>
- </listitem>
-
- <listitem>
- <para>If the question relates to enhancements to FreeBSD, and you
- can make suggestions about how to implement them, then send the
- message to <literal>FreeBSD-hackers</literal>.</para>
- </listitem>
- </orderedlist>
-
- <para>There are also a number of other specialized mailing lists, for
- example <literal>FreeBSD-isp</literal>, which caters to the interests of
- ISPs (Internet Service Providers) who run FreeBSD. If you happen to be
- an ISP, this does not mean you should automatically send your questions
- to <literal>FreeBSD-isp</literal>. The criteria above still apply, and
- it is in your interest to stick to them, since you are more likely to get
- good results that way.</para>
- </sect1>
-
- <sect1>
- <title xml:id="before">Before submitting a question</title>
-
- <para>You can (and should) do some things yourself before asking a question
- on one of the mailing lists:</para>
-
- <itemizedlist>
- <listitem>
- <para>Try solving the problem on your own. If you post a question which
- shows that you have tried to solve the problem, your question will
- generally attract more positive attention from people reading it.
- Trying to solve the problem yourself will also enhance your understanding
- of FreeBSD, and will eventually let you use your knowledge to help others
- by answering questions posted to the mailing lists.
- </para>
- </listitem>
-
- <listitem>
- <para>Read the manual pages, and the FreeBSD documentation (either
- installed in <filename>/usr/doc</filename> or accessible via WWW at
- <uri xlink:href="http://www.FreeBSD.org">http://www.FreeBSD.org</uri>), especially the
- <link xlink:href="&url.books.handbook;/index.html">handbook</link>
- and the <link xlink:href="&url.books.faq;/index.html">FAQ</link>.
- </para>
- </listitem>
-
- <listitem>
- <para>Browse and/or search the archives for the mailing list, to see if your
- question or a similar one has been asked (and possibly answered) on the
- list. You can browse and/or search the mailing list archives
- at <uri xlink:href="http://www.FreeBSD.org/mail">http://www.FreeBSD.org/mail</uri>
- and <uri xlink:href="http://www.FreeBSD.org/search/search.html#mailinglists">http://www.FreeBSD.org/search/search.html#mailinglists</uri>
- respectively. This can be done at other WWW sites as well, for example
- at <uri xlink:href="http://marc.theaimsgroup.com">http://marc.theaimsgroup.com</uri>.
- </para>
- </listitem>
-
- <listitem>
- <para>Use a search engine such as <link xlink:href="http://www.google.com">Google</link>
- or <link xlink:href="http://www.yahoo.com">Yahoo</link> to find answers to your question.
- Google even has a <link xlink:href="http://www.google.com/bsd">BSD-specific search interface</link>.
- </para>
- </listitem>
- </itemizedlist>
- </sect1>
-
- <sect1>
- <title xml:id="submit">How to submit a question</title>
-
- <para>When submitting a question to FreeBSD-questions, consider the
- following points:</para>
-
- <itemizedlist>
- <listitem>
- <para>Remember that nobody gets paid for answering a FreeBSD
- question. They do it of their own free will. You can influence this
- free will positively by submitting a well-formulated question
- supplying as much relevant information as possible. You can
- influence this free will negatively by submitting an incomplete,
- illegible, or rude question. It is perfectly possible to send a
- message to FreeBSD-questions and not get an answer even if you
- follow these rules. It is much more possible to not get an answer if
- you do not. In the rest of this document, we will look at how to get
- the most out of your question to FreeBSD-questions.</para>
- </listitem>
-
- <listitem>
- <para>Not everybody who answers FreeBSD questions reads every message:
- they look at the subject line and decide whether it interests them.
- Clearly, it is in your interest to specify a subject. <quote>FreeBSD
- problem</quote> or <quote>Help</quote> are not enough. If you provide no subject at
- all, many people will not bother reading it. If your subject is not
- specific enough, the people who can answer it may not read
- it.</para>
- </listitem>
-
- <listitem>
- <para>Format your message so that it is legible, and
- PLEASE DO NOT SHOUT!!!!!. We appreciate that a lot of people do not
- speak English as their first language, and we try to make
- allowances for that, but it is really painful to try to read a
- message written full of typos or without any line breaks.</para>
-
- <para>Do not underestimate the effect that a poorly formatted mail
- message has, not just on the FreeBSD-questions mailing list.
- Your mail message is all people see of you, and if it is poorly
- formatted, one line per paragraph, badly spelt, or full of
- errors, it will give people a poor impression of you.</para>
-
- <para>A lot of badly formatted messages come from
- <link xlink:href="http://www.lemis.com/email.html">bad mailers or badly
- configured mailers</link>. The following mailers are known to
- send out badly formatted messages without you finding out about
- them:</para>
-
- <itemizedlist>
- <listitem>
- <para>cc:Mail</para>
- </listitem>
-
- <listitem>
- <para>&eudora;</para>
- </listitem>
-
- <listitem>
- <para>exmh</para>
- </listitem>
-
- <listitem>
- <para>&microsoft; Exchange</para>
- </listitem>
-
- <listitem>
- <para>&microsoft; Internet Mail</para>
- </listitem>
-
- <listitem>
- <para>&microsoft; &outlook;</para>
- </listitem>
-
- <listitem>
- <para>&netscape;</para>
- </listitem>
- </itemizedlist>
-
- <para>As you can see, the mailers in the Microsoft world are frequent
- offenders. If at all possible, use a &unix; mailer. If you must use a
- mailer under Microsoft environments, make sure it is set up
- correctly. Try not to use <acronym>MIME</acronym>: a lot of people
- use mailers which do not get on very well with
- <acronym>MIME</acronym>.</para>
- </listitem>
-
- <listitem>
- <para>Make sure your time and time zone are set correctly. This may
- seem a little silly, since your message still gets there, but many
- of the people you are trying to reach get several hundred messages a
- day. They frequently sort the incoming messages by subject and by
- date, and if your message does not come before the first answer, they
- may assume they missed it and not bother to look.</para>
- </listitem>
-
- <listitem>
- <para>Do not include unrelated questions in the same message. Firstly,
- a long message tends to scare people off, and secondly, it is more
- difficult to get all the people who can answer all the questions to
- read the message.</para>
- </listitem>
-
- <listitem>
- <para>Specify as much information as possible. This is a difficult
- area, and we need to expand on what information you need to submit,
- but here is a start:</para>
-
- <itemizedlist>
- <listitem>
- <para>In nearly every case, it is important to know the version of
- FreeBSD you are running. This is particularly the case for
- FreeBSD-CURRENT, where you should also specify the date of the
- sources, though of course you should not be sending questions
- about -CURRENT to FreeBSD-questions.</para>
- </listitem>
-
- <listitem><para>With any problem which <emphasis>could</emphasis> be
- hardware related, tell us about your hardware. In case of
- doubt, assume it is possible that it is hardware. What kind of
- CPU are you using? How fast? What motherboard? How much
- memory? What peripherals?</para>
-
- <para>There is a judgement call here, of course, but the output of
- the &man.dmesg.8; command can frequently be very useful, since it
- tells not just what hardware you are running, but what version of
- FreeBSD as well.</para>
- </listitem>
-
- <listitem>
- <para>If you get error messages, do not say <quote>I get error
- messages</quote>, say (for example) <quote>I get the error
- message 'No route to host'</quote>.</para>
- </listitem>
-
- <listitem>
- <para>If your system panics, do not say <quote>My system
- panicked</quote>, say (for example) <quote>my system panicked
- with the message 'free vnode isn't'</quote>.</para>
- </listitem>
-
- <listitem>
- <para>If you have difficulty installing FreeBSD, please tell us
- what hardware you have. In particular, it is important to know
- the IRQs and I/O addresses of the boards installed in your
- machine.</para>
- </listitem>
-
- <listitem>
- <para>If you have difficulty getting PPP to run, describe the
- configuration. Which version of PPP do you use? What kind of
- authentication do you have? Do you have a static or dynamic IP
- address? What kind of messages do you get in the log
- file?</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para>A lot of the information you need to supply is the output of
- programs, such as &man.dmesg.8;, or console messages, which usually
- appear in <filename>/var/log/messages</filename>. Do not try to copy
- this information by typing it in again; it is a real pain, and you are
- bound to make a mistake. To send log file contents, either make a
- copy of the file and use an editor to trim the information to what
- is relevant, or cut and paste into your message. For the output of
- programs like &man.dmesg.8;, redirect the output to a file and
- include that. For example,</para>
-
- <screen>&prompt.user; <userinput>dmesg &gt; /tmp/dmesg.out</userinput></screen>
-
- <para>This redirects the information to the file
- <filename>/tmp/dmesg.out</filename>.</para>
- </listitem>
-
- <listitem>
- <para>If you do all this, and you still do not get an answer, there
- could be other reasons. For example, the problem is so complicated
- that nobody knows the answer, or the person who does know the answer
- was offline. If you do not get an answer after, say, a week, it
- might help to re-send the message. If you do not get an answer to
- your second message, though, you are probably not going to get one
- from this forum. Resending the same message again and again will
- only make you unpopular.</para>
- </listitem>
- </itemizedlist>
-
- <para>To summarize, let's assume you know the answer to the following
- question (yes, it is the same one in each case).
- You choose which of these two questions you would be more prepared to
- answer:</para>
-
- <example>
- <title>Message 1</title>
-
- <literallayout class="monospaced">Subject: HELP!!?!??
-I just can't get hits damn silly FereBSD system to
-workd, and Im really good at this tsuff, but I have never seen
-anythign sho difficult to install, it jst wont work whatever I try
-so why don't you guys tell me what I doing wrong.</literallayout>
- </example>
-
- <example>
- <title>Message 2</title>
-
- <literallayout class="monospaced">Subject: Problems installing FreeBSD
-
-I've just got the FreeBSD 2.1.5 CDROM from Walnut Creek, and I'm having a lot
-of difficulty installing it. I have a 66 MHz 486 with 16 MB of
-memory and an Adaptec 1540A SCSI board, a 1.2GB Quantum Fireball
-disk and a Toshiba 3501XA CDROM drive. The installation works just
-fine, but when I try to reboot the system, I get the message
-<quote>Missing Operating System</quote>.</literallayout>
- </example>
- </sect1>
-
- <sect1>
- <title xml:id="followup">How to follow up to a question</title>
-
- <para>Often you will want to send in additional information to a question
- you have already sent. The best way to do this is to reply to your
- original message. This has three advantages:</para>
-
- <orderedlist>
- <listitem>
- <para>You include the original message text, so people will know what
- you are talking about. Do not forget to trim unnecessary text out,
- though.</para>
- </listitem>
-
- <listitem>
- <para>The text in the subject line stays the same (you did remember to
- put one in, did you not?). Many mailers will sort messages by
- subject. This helps group messages together.</para>
- </listitem>
-
- <listitem>
- <para>The message reference numbers in the header will refer to the
- previous message. Some mailers, such as
- <link xlink:href="http://www.mutt.org/">mutt</link>, can
- <emphasis>thread</emphasis> messages, showing the exact
- relationships between the messages.</para>
- </listitem>
- </orderedlist>
- </sect1>
-
- <sect1>
- <title xml:id="answer">How to answer a question</title>
-
-
- <para>Before you answer a question to FreeBSD-questions, consider:</para>
-
- <orderedlist>
- <listitem>
- <para>A lot of the points on submitting questions also apply to
- answering questions. Read them.</para>
- </listitem>
-
- <listitem>
- <para>Has somebody already answered the question? The easiest way to
- check this is to sort your incoming mail by subject: then
- (hopefully) you will see the question followed by any answers, all
- together.</para>
-
- <para>If somebody has already answered it, it does not automatically
- mean that you should not send another answer. But it makes sense to
- read all the other answers first.</para>
- </listitem>
-
- <listitem>
- <para>Do you have something to contribute beyond what has already been
- said? In general, <quote>Yeah, me too</quote> answers do not help
- much, although there are exceptions, like when somebody is
- describing a problem he is having, and he does not know whether it is
- his fault or whether there is something wrong with the hardware or
- software. If you do send a <quote>me too</quote> answer, you should
- also include any further relevant information.</para>
- </listitem>
-
- <listitem>
- <para>Are you sure you understand the question? Very frequently, the
- person who asks the question is confused or does not express himself
- very well. Even with the best understanding of the system, it is
- easy to send a reply which does not answer the question. This
- does not help: you will leave the person who submitted the question
- more frustrated or confused than ever. If nobody else answers, and
- you are not too sure either, you can always ask for more
- information.</para>
- </listitem>
-
- <listitem>
- <para>Are you sure your answer is correct?
- If not, wait a day or so. If nobody else comes up with a
- better answer, you can still reply and say, for example, <quote>I
- do not know if this is correct, but since nobody else has
- replied, why don't you try replacing your ATAPI CDROM with
- a frog?</quote>.</para>
- </listitem>
-
- <listitem>
- <para>Unless there is a good reason to do otherwise, reply to the
- sender and to FreeBSD-questions. Many people on the
- FreeBSD-questions are <quote>lurkers</quote>: they learn by reading
- messages sent and replied to by others. If you take a message which
- is of general interest off the list, you are depriving these people
- of their information. Be careful with group replies; lots of people
- send messages with hundreds of CCs. If this is the case, be sure to
- trim the Cc: lines appropriately.</para>
- </listitem>
-
- <listitem>
- <para>Include relevant text from the original message. Trim it to the
- minimum, but do not overdo it. It should still be possible for
- somebody who did not read the original message to understand what
- you are talking about.</para>
- </listitem>
-
- <listitem>
- <para>Use some technique to identify which text came from the original
- message, and which text you add. I personally find that prepending
- <quote><literal>&gt; </literal></quote> to the original message
- works best. Leaving white space after the
- <quote><literal>&gt; </literal></quote> and leave empty lines
- between your text and the original text both make the result more
- readable.</para>
- </listitem>
-
- <listitem>
- <para>Put your response in the correct place (after the text to which
- it replies). It is very difficult to read a thread of responses
- where each reply comes before the text to which it replies.</para>
- </listitem>
-
- <listitem>
- <para>Most mailers change the subject line on a reply by prepending a
- text such as <quote>Re: </quote>. If your mailer does not do it
- automatically, you should do it manually.</para>
- </listitem>
-
- <listitem>
- <para>If the submitter did not abide by format conventions (lines too
- long, inappropriate subject line), <emphasis>please</emphasis> fix
- it. In the case of an incorrect subject line (such as
- <quote>HELP!!??</quote>), change the subject line to (say)
- <quote>Re: Difficulties with sync PPP (was: HELP!!??)</quote>. That
- way other people trying to follow the thread will have less
- difficulty following it.</para>
-
- <para>In such cases, it is appropriate to say what you did and why you
- did it, but try not to be rude. If you find you can not answer
- without being rude, do not answer.</para>
-
- <para>If you just want to reply to a message because of its bad
- format, just reply to the submitter, not to the list. You can just
- send him this message in reply, if you like.</para>
- </listitem>
- </orderedlist>
- </sect1>
-</article>
diff --git a/zh_TW.UTF-8/articles/hubs/Makefile b/zh_TW.UTF-8/articles/hubs/Makefile
deleted file mode 100644
index f04f8a971f..0000000000
--- a/zh_TW.UTF-8/articles/hubs/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# $FreeBSD$
-#
-# Article: Mirroring FreeBSD
-
-DOC?= article
-
-FORMATS?= html
-WITH_ARTICLE_TOC?= YES
-
-INSTALL_COMPRESSED?=gz
-INSTALL_ONLY_COMPRESSED?=
-
-SRCS= article.xml
-
-DOC_PREFIX?= ${.CURDIR}/../../..
-.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/articles/hubs/article.xml b/zh_TW.UTF-8/articles/hubs/article.xml
deleted file mode 100644
index 5d87a92f21..0000000000
--- a/zh_TW.UTF-8/articles/hubs/article.xml
+++ /dev/null
@@ -1,520 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN" "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd">
-<article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:its="http://www.w3.org/2005/11/its" version="5.0" xml:lang="zh_TW">
- <info><title>Mirroring FreeBSD</title>
-
- <authorgroup>
- <author><personname><firstname>Jun</firstname><surname>Kuriyama</surname></personname><affiliation> <address><email>kuriyama@FreeBSD.org</email></address> </affiliation></author>
- <author><personname><firstname>Valentino</firstname><surname>Vaschetto</surname></personname><affiliation> <address><email>logo@FreeBSD.org</email></address> </affiliation></author>
- <author><personname><firstname>Daniel</firstname><surname>Lang</surname></personname><affiliation> <address><email>dl@leo.org</email></address> </affiliation></author>
- <author><personname><firstname>Daniel</firstname><surname>Lang</surname></personname><affiliation> <address><email>kensmith@FreeBSD.org</email></address> </affiliation></author>
- </authorgroup>
-
- <legalnotice xml:id="trademarks" role="trademarks">
- <para>FreeBSD 是 FreeBSD基金會的註冊商標.</para>
- <para>許多製造商和經銷商使用一些稱為商標的圖案或文字設計來彰顯自己的產品.本文中出現的眾多商標,以及 FreeBSD Project 本身廣所人知的商標,後面將以 <quote>™</quote> 或 <quote>®</quote> 符號來標註.</para>
- </legalnotice>
-
- <pubdate xml:lang="en">$FreeBSD$</pubdate>
-
- <releaseinfo xml:lang="en">$FreeBSD$</releaseinfo>
-
- <abstract>
- <para>這是份介紹如何 mirror FreeBSD,主要是針對網路中心管理者或託管於大型資料中心的管理者.</para>
- </abstract>
- </info>
-
- <note>
- <para>我們目前不接受新Mirror站點的申請.</para>
- </note>
-
- <sect1 xml:id="mirror-contact">
- <title>聯繫方式</title>
-
- <para xml:lang="en">The Mirror System Coordinators can be reached through email
- at <email>mirror-admin@FreeBSD.org</email>. There is also
- a <link xlink:href="http://lists.FreeBSD.org/mailman/listinfo/freebsd-hubs">FreeBSD mirror sites mailing lists</link>.</para>
- </sect1>
-
- <sect1 xml:id="mirror-requirements">
- <title>FreeBSD mirrors 的需求</title>
- <sect2 xml:id="mirror-diskspace">
- <title>磁碟空間</title>
- <para>磁碟空間是最為需要. 根據你想要 mirror 的發行版、CPU架構 ,可能會消耗大量的磁碟空間.另外請注意 <emphasis>官方</emphasis> 鏡像站需要完整 mirror。網站內容亦需要完整鏡像。且這裡所述的數字是反應目前版本狀態 (如 10.4-RELEASE/11.1-RELEASE )。而不斷的開發與發行將會增加所需空間。並請務必保留一些 ( 約10-20% ) 額外空間。這裡大約估計如下:</para>
- <itemizedlist>
- <listitem><para>完整的作業系統套件 FTP 站所需:1.4 TB</para></listitem>
- <listitem><para>CTM deltas: 10 GB</para></listitem>
- <listitem><para>網站: 1GB</para></listitem>
- </itemizedlist>
- <para>目前 FTP Distribution 的磁碟使用可在 <link xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/dir.sizes">ftp://ftp.FreeBSD.org/pub/FreeBSD/dir.sizes</link> 找到。</para>
- </sect2>
- <sect2 xml:id="mirror-bandwidth">
- <title>網路連線/頻寬</title>
- <para>當然,你一定要能連上 Internet。 頻寬需求多少,這要看你所想要的 mirror 程度而定。 若只想要 mirror 一部份的 FreeBSD 檔案以作為網站或 intranet 的局部用途, 那麼頻寬需求會明顯比成為公共服務用途的小一些。 若想成為 official mirror 之一的話,那麼頻寬就勢必得增加才夠用。以下,我們僅列出一些估計值以做為參考: </para>
- <itemizedlist>
- <listitem><para>本地站台,沒有要公共存取: 基本上沒有最低需求,但是 &lt; 2Mbps 同步將會非常緩慢</para></listitem>
- <listitem><para>非官方公共站台: 34Mbps 是不錯的開始.</para></listitem>
- <listitem><para>官方站台: &gt; 100Mbps 是建議值,並且你的主機必須盡可能連接靠近邊界路由器.</para></listitem>
- </itemizedlist>
- </sect2>
- <sect2 xml:id="mirror-system">
- <title>系統需求,CPU,RAM</title>
- <para>這取決於預期的客戶端數量,這是由伺服器的策略決定的。也會受到您提供的服務類型而影響.普通的 FTP 或 HTTP 服務可能不需要大量的資源。注意如果您提供rsync. 這可能會對 CPU 和記憶體的需求產生巨大的影響,因為會消耗大量記憶體。 以下只是給你一個非常粗略的的例子。</para>
- <para>針對一個較常被瀏覽的網站 <application>rsync</application>,您須考量處理器大約 800Mhz 至 1Ghz,並且安裝最少 512MB RAM,這或許是成為一個 <emphasis>官方</emphasis> 站台的最小需求.</para>
- <para>為了一個經常使用的網站你絕對需要更多 RAM (2GB是不錯的開始) 並且儘可能有更多 CPU , 這也表示你需要一個 SMP 系統。</para>
- <para>您也會需要考慮有一個較快的磁碟系統。在管理 SVN repository 需要一個快速的磁碟系統 ( 強烈建議 RAID)。有自己的快取記憶體的 SCSI 控制器也可以加快速度,因為大多數這些服務會對磁碟進行大量的小幅修改。</para>
- </sect2>
- <sect2 xml:id="mirror-services">
- <title>提供的服務</title>
- <para>每個鏡像站都需要一有一組可用的核心服務。除了這些所需的服務之外,還有許多伺服器管理員可以選擇提供的選用服務。本節將說明您可以提供哪些服務以及如何實作這些服務。</para>
- <sect3 xml:id="mirror-serv-ftp">
- <title>FTP (需要提供給FTP檔案集)</title>
- <para>這是最基本的服務之一。需要為每個鏡像站提供公共的 FTP distributions 。 FTP 存取必須是匿名的, 不允許上傳/下載比率 (這是一件荒謬的事),上傳功能不是必需的 (且<emphasis>必須 </emphasis>絕不允許 FreeBSD 檔案空間)。另外,FreeBSD archive 應該在路徑<filename>/pub/FreeBSD</filename>下。</para>
- <para>這裡有很多可用的軟體可以架設允許匿名的 FTP 服務 (按字母順序)。</para>
- <itemizedlist>
- <listitem><para><command>/usr/libexec/ftpd</command>: FreeBSD 內建的 ftpd 可以使用。請您參閱 <citerefentry><refentrytitle>ftpd</refentrytitle><manvolnum>8</manvolnum></citerefentry>。</para>
- </listitem>
- <listitem>
- <para><package>ftp/ncftpd</package>。一個商業軟體套件,免費供教育使用。</para>
- </listitem>
- <listitem>
- <para><package>ftp/oftpd</package>:一個以安全性作為主要考量的 ftpd。</para>
- </listitem>
- <listitem>
- <para><package>ftp/proftpd</package>:一個模組化且非常有彈性的 ftpd。</para>
- </listitem>
- <listitem>
- <para><package>ftp/pure-ftpd</package>: 另一個為安全所設計的 ftpd。</para>
- </listitem>
- <listitem><para><package>ftp/twoftpd</package>:如上。</para></listitem>
- <listitem><para><package>ftp/vsftpd</package>:<quote>非常安全的</quote> ftpd。</para></listitem>
- </itemizedlist>
- <para>FreeBSD 的 <application>ftpd</application>、<application>proftpd</application> 和也許 <application>ncftpd</application> 是最常使用的 FTP 軟體。其他的在鏡像站並沒有大量用戶基礎。需要考慮的一件事情是,您可能需要性地來限制允許同時連線數,從而限制消耗多少網路頻寬和系統資源。</para>
- </sect3>
- <sect3 xml:id="mirror-serv-rsync">
- <title>Rsync (給FTP檔案集選用)</title>
- <para><application>Rsync</application> 通常是用在存取 FreeBSD 系統中的FTP內容,其他的鏡像站可以使用你的系統當作他們的來源。這個協定和 FTP 有很多不同,它比較不那麼消耗頻寬,只有當比對檔案間有變動才傳輸檔案,而不是整個檔案傳完。<application>Rsync</application> 需要較多的記憶體。大小取決於檔案與目錄的數目及同步模組大小。<application>Rsync</application> 可以使用 <command>rsh</command> 和 <command>ssh</command> (現在為預設)來傳輸, 或使用自己的協定單獨存取(這是公共rsync伺服器的首選方法)。可以用認證、連接限制和其他限制。只有一個軟體套件可以用:</para>
- <itemizedlist>
- <listitem><para><package>net/rsync</package></para></listitem>
- </itemizedlist>
- </sect3>
- <sect3 xml:id="mirror-serv-http">
- <title>HTTP(網頁需要,FTP 檔案集則是選用)</title>
- <para>如果您想提供 FreeBSD 的網頁,您需要安裝一個網頁伺服器。您可以選擇利用 HTTP 提供 FTP 檔案集。網頁伺服器軟體的選擇留給鏡像站管理員選擇。一些最受歡迎的選擇是:</para>
-
- <itemizedlist>
- <listitem>
- <para><package>www/apache22</package>:<application>Apache</application> 是網際網路上最廣泛使用的網頁伺服器。 它被 FreeBSD 計畫廣泛使用。</para>
- </listitem>
-
- <listitem>
- <para><package>www/thttpd</package>:如果您要提供大量的靜態內容,您可能會發現使用諸如 thttpd 之類的應用程式會比 <application>Apache</application> 更有效率。它針對 FreeBSD 的優秀性能進行了最佳化。</para>
- </listitem>
-
- <listitem>
- <para><package>www/boa</package>:<application>Boa</application> 是 <application>thttpd</application> 和 <application>Apache</application> 外的另一個選擇。對於純粹的靜態網頁,它應該會提供比 <application>Apache</application> 更好的性能。在寫這篇文章的時候,它並不包含像在 <application>thttpd</application> 中一樣針對FreeBSD 做最佳化。</para>
- </listitem>
-
- <listitem>
- <para><package>www/nginx</package>:<application>Nginx</application> 是一款高性能的最新網頁服務器,具有低記憶體佔用量和關鍵特色,可以構建現代高效率網頁基礎架構,功能包括 HTTP 伺服器,HTTP 和郵件反向代理,快取,負載平衡,壓縮,請求限制(request throtting),連接多工與再利用,SSL 卸載和 HTTP 媒體串流。</para>
- </listitem>
- </itemizedlist>
- </sect3>
- </sect2>
- </sect1>
- <sect1 xml:id="mirror-howto">
- <title>如何Mirror FreeBSD 站台</title>
- <para>好,現在你知道硬體需求和如何提供服務,但不知道如何做。:-) 這節將解釋如何實際 mirror FreeBSD 的不同部分,使用哪些工具以及從哪裡 mirror。</para>
- <sect2 xml:id="mirror-ftp-rsync">
- <title>鏡像 FTP 站</title>
- <para>FTP 部份有最大量的資料需要被 mirror。它包括網路安裝所需的<emphasis>發布集</emphasis>,實際上是原始碼樹快照的<emphasis>分支</emphasis>,可燒錄光碟供安裝系統的<emphasis>ISO映像檔</emphasis> ,一個可 live 開機的檔案系統,以及一個 port tree 的快照。當然,全都有各種 FreeBSD 版本和各種CPU架構。</para>
- <para xml:lang="en">
- The best way to mirror the FTP area is <application>rsync</application>.
- You can install the port <package>net/rsync</package> and then use
- rsync to sync with your upstream host.
- <application>rsync</application> is already mentioned
- in <xref linkend="mirror-serv-rsync"/>.
- Since <application>rsync</application> access is not
- required, your preferred upstream site may not allow it.
- You may need to hunt around a little bit to find a site
- that allows <application>rsync</application> access.</para>
- <note>
- <para>由於 <application>rsync</application> 客戶端的數量將對伺服器主機產生重大影響,因此大多數管理員會對伺服器負荷加以限制。對於 mirror 站台,您應該詢問您要 mirror 站台的管理人員他們的管理政策,也許需要對您的主機開放例外(因為您是一個 mirror 站)。</para>
- </note>
- <para>一個需要mirror FreeBSD官網的指令如下:</para>
- <screen><prompt>%</prompt> <userinput>rsync -vaHz --delete rsync://ftp4.de.FreeBSD.org/FreeBSD/ /pub/FreeBSD/</userinput></screen>
- <para xml:lang="en">Consult the documentation for <application>rsync</application>,
- which is also available at
- <link xlink:href="http://rsync.samba.org/">http://rsync.samba.org/</link>,
- about the various options to be used with rsync.
- If you sync the whole module (unlike subdirectories),
- be aware that the module-directory (here "FreeBSD")
- will not be created, so you cannot omit the target directory.
- Also you might
- want to set up a script framework that calls such a command
- via <citerefentry><refentrytitle>cron</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
- </para>
- </sect2>
- <sect2 xml:id="mirror-www">
- <title>Mirroring 網頁</title>
- <para>FreeBSD 網站應只能透過<application>rsync</application>指令來mirror.</para>
- <para>一個 mirror FreeBSD 網站的指令應該看起像這樣:</para>
- <screen><prompt>%</prompt> <userinput>rsync -vaHz --delete rsync://bit0.us-west.freebsd.org/FreeBSD-www-data/ /usr/local/www/</userinput></screen>
- </sect2>
- <sect2 xml:id="mirror-pkgs">
- <title>Mirroring 套件</title>
- <para>由於對頻寬,儲存空間和管理的要求非常高,FreeBSD 計畫決定不允許公眾 mirror 套件. 對於擁有大量伺服主機的網站,建議為 <citerefentry><refentrytitle>pkg</refentrytitle><manvolnum>8</manvolnum></citerefentry> 使用 HTTP proxy 快取可能會有所幫助。或者,您可以使用以下指令獲得套件與相依套件:</para>
-
- <screen><prompt>%</prompt> <userinput>pkg fetch -d -o <replaceable>/usr/local/mirror</replaceable> <replaceable>vim</replaceable></userinput></screen>
-
- <para>一旦這些套件包被下載,就必須執行以下命令來產生套件庫數據:</para>
-
- <screen><prompt>%</prompt> <userinput>pkg repo <replaceable>/usr/local/mirror</replaceable></userinput></screen>
-
- <para>一旦套件被下載並且已經生成了套件庫的數據,就可以透過 HTTP 協定將套件提供給客戶端機器。有關更多訊息,請參閱 <citerefentry><refentrytitle>pkg</refentrytitle><manvolnum>8</manvolnum></citerefentry> 的 man pages,特別是<citerefentry><refentrytitle>pkg-repo</refentrytitle><manvolnum>8</manvolnum></citerefentry> 頁面。</para>
- </sect2>
- <sect2 xml:id="mirror-how-often">
- <title>我多久應該mirror?</title>
- <para xml:lang="en">
- Every mirror should be updated at a minimum of once per day.
- Certainly a script with locking to prevent multiple runs
- happening at the same time will be needed to run from
- <citerefentry><refentrytitle>cron</refentrytitle><manvolnum>8</manvolnum></citerefentry>. Since nearly every admin does this in their own
- way, specific instructions cannot be provided. It could work
- something like this:
- </para>
- <procedure>
- <step>
- <para xml:lang="en">
- Put the command to run your mirroring application
- in a script. Use of a plain <command>/bin/sh</command>
- script is recommended.
- </para>
- </step>
- <step>
- <para xml:lang="en">
- Add some output redirections so diagnostic
- messages are logged to a file.
- </para>
- </step>
- <step>
- <para xml:lang="en">
- Test if your script works. Check the logs.
- </para>
- </step>
- <step>
- <para xml:lang="en">
- Use <citerefentry><refentrytitle>crontab</refentrytitle><manvolnum>1</manvolnum></citerefentry> to add the script to the
- appropriate user's <citerefentry><refentrytitle>crontab</refentrytitle><manvolnum>5</manvolnum></citerefentry>. This should be a
- different user than what your FTP daemon runs as so that
- if file permissions inside your FTP area are not
- world-readable those files can not be accessed by anonymous
- FTP. This is used to <quote>stage</quote> releases —
- making sure all of the official mirror sites have all of the
- necessary release files on release day.
- </para>
- </step>
- </procedure>
- <para xml:lang="en">
- Here are some recommended schedules:</para>
- <itemizedlist>
- <listitem><para xml:lang="en">FTP fileset: daily</para></listitem>
- <listitem><para xml:lang="en">WWW pages: daily</para></listitem>
- </itemizedlist>
- </sect2>
- </sect1>
- <sect1 xml:id="mirror-where">
- <title xml:lang="en">Where to mirror from</title>
- <para xml:lang="en">
- This is an important issue. So this section will
- spend some effort to explain the backgrounds. We will say this
- several times: under no circumstances should you mirror from
- <systemitem class="fqdomainname">ftp.FreeBSD.org</systemitem>.
- </para>
- <sect2 xml:id="mirror-where-organization">
- <title xml:lang="en">A few words about the organization</title>
- <para xml:lang="en">
- Mirrors are organized by country. All
- official mirrors have a DNS entry of the form
- <systemitem class="fqdomainname">ftpN.CC.FreeBSD.org</systemitem>.
- <emphasis>CC</emphasis> (i.e. country code) is the
- <emphasis>top level domain</emphasis> (TLD)
- of the country where this mirror is located.
- <emphasis>N</emphasis> is a number,
- telling that the host would be the <emphasis>Nth</emphasis>
- mirror in that country.
- (Same applies to
- <systemitem>wwwN.CC.FreeBSD.org</systemitem>, etc.)
- There are mirrors with no <emphasis>CC</emphasis> part.
- These are the mirror sites that are very well connected and
- allow a large number of concurrent users.
- <systemitem class="fqdomainname">ftp.FreeBSD.org</systemitem> is actually two machines, one currently
- located in Denmark and the other in the United States.
- It is <emphasis>NOT</emphasis> a master site and should never be
- used to mirror from. Lots of online documentation leads
- <quote>interactive</quote>users to
- <systemitem class="fqdomainname">ftp.FreeBSD.org</systemitem> so automated mirroring
- systems should find a different machine to mirror from.
- </para>
- <para xml:lang="en">
- Additionally there exists a hierarchy of mirrors, which
- is described in terms of <emphasis>tiers</emphasis>.
- The master sites are not referred to but can be
- described as <emphasis>Tier-0</emphasis>. Mirrors
- that mirror from these sites can be considered
- <emphasis>Tier-1</emphasis>, mirrors of <emphasis>Tier-1</emphasis>-mirrors,
- are <emphasis>Tier-2</emphasis>, etc.
- Official sites are encouraged to be of a low <emphasis>tier</emphasis>,
- but the lower the tier the higher the requirements in
- terms as described in <xref linkend="mirror-requirements"/>.
- Also access to low-tier-mirrors may be restricted, and
- access to master sites is definitely restricted.
- The <emphasis>tier</emphasis>-hierarchy is not reflected
- by DNS and generally not documented anywhere except
- for the master sites. However, official mirrors with low numbers
- like 1-4, are usually <emphasis>Tier-1</emphasis>
- (this is just a rough hint, and there is no rule).
- </para>
- </sect2>
- <sect2 xml:id="mirror-where-where">
- <title xml:lang="en">Ok, but where should I get the stuff now?</title>
- <para xml:lang="en">
- Under no circumstances should you mirror from <systemitem class="fqdomainname">ftp.FreeBSD.org</systemitem>.
- The short answer is: from the
- site that is closest to you in Internet terms, or gives you
- the fastest access.
- </para>
- <sect3 xml:id="mirror-where-simple">
- <title xml:lang="en">I just want to mirror from somewhere!</title>
- <para xml:lang="en">
- If you have no special intentions or
- requirements, the statement in <xref linkend="mirror-where-where"/>
- applies. This means:
- </para>
- <procedure>
- <step>
- <para xml:lang="en">
- Check for those which provide fastest access
- (number of hops, round-trip-times)
- and offer the services you intend to
- use (like <application>rsync</application>).
- </para>
- </step>
- <step>
- <para xml:lang="en">
- Contact the administrators of your chosen site stating your
- request, and asking about their terms and
- policies.
- </para>
- </step>
- <step>
- <para xml:lang="en">
- Set up your mirror as described above.
- </para>
- </step>
- </procedure>
- </sect3>
- <sect3 xml:id="mirror-where-official">
- <title xml:lang="en">I am an official mirror, what is the right site for me?</title>
- <para xml:lang="en">
- In general the description in <xref linkend="mirror-where-simple"/>
- still applies. Of course you may want to put some
- weight on the fact that your upstream should be of
- a low tier.
- There are some other considerations about <emphasis>official</emphasis>
- mirrors that are described in <xref linkend="mirror-official"/>.
- </para>
- </sect3>
- <sect3 xml:id="mirror-where-master">
- <title xml:lang="en">I want to access the master sites!</title>
- <para xml:lang="en">
- If you have good reasons and good prerequisites,
- you may want and get access to one of the
- master sites. Access to these sites is
- generally restricted, and there are special policies
- for access. If you are already an <emphasis>official</emphasis>
- mirror, this certainly helps you getting access.
- In any other case make sure your country really needs another mirror.
- If it already has three or more, ask the <quote>zone administrator</quote> (<email>hostmaster@CC.FreeBSD.org</email>) or <link xlink:href="http://lists.FreeBSD.org/mailman/listinfo/freebsd-hubs">FreeBSD mirror sites mailing lists</link> first.</para>
-
- <para xml:lang="en">
- Whoever helped you become, an <emphasis>official</emphasis>
- should have helped you gain access to an appropriate upstream
- host, either one of the master sites or a suitable Tier-1
- site. If not, you can send email to
- <email>mirror-admin@FreeBSD.org</email> to request help with
- that.
- </para>
- <para xml:lang="en">
- There is one master site for the FTP fileset.
- </para>
- <sect4 xml:id="mirror-where-master-ftp">
- <title xml:lang="en">ftp-master.FreeBSD.org</title>
- <para xml:lang="en">
- This is the master site for the FTP fileset.
- </para>
- <para xml:lang="en">
- <systemitem>ftp-master.FreeBSD.org</systemitem> provides
- <application>rsync</application>
- access, in addition to FTP.
- Refer to <xref linkend="mirror-ftp-rsync"/>.
- </para>
- <para xml:lang="en">
- Mirrors are also encouraged to allow <application>rsync</application>
- access for the FTP contents, since they are
- <emphasis>Tier-1</emphasis>-mirrors.
- </para>
- </sect4>
- </sect3>
- </sect2>
- </sect1>
- <sect1 xml:id="mirror-official">
- <title xml:lang="en">Official Mirrors</title>
- <para xml:lang="en">
- Official mirrors are mirrors that</para>
- <itemizedlist>
- <listitem>
- <para xml:lang="en">
- a) have a <systemitem>FreeBSD.org</systemitem> DNS entry
- (usually a CNAME).
- </para>
- </listitem>
- <listitem>
- <para xml:lang="en">
- b) are listed as an official mirror in the FreeBSD
- documentation (like handbook).
- </para>
- </listitem>
- </itemizedlist>
-
- <para xml:lang="en">So far to distinguish official mirrors.
- Official mirrors are not necessarily <emphasis>Tier-1</emphasis>-mirrors.
- However you probably will not find a <emphasis>Tier-1</emphasis>-mirror,
- that is not also official.
- </para>
- <sect2 xml:id="mirror-official-requirements">
- <title xml:lang="en">Special Requirements for official (tier-1) mirrors</title>
- <para xml:lang="en">
- It is not so easy to state requirements for all
- official mirrors, since the project is sort of
- tolerant here. It is more easy to say,
- what <emphasis>official tier-1 mirrors</emphasis>
- are required to. All other official mirrors
- can consider this a big <emphasis>should</emphasis>.</para>
- <para xml:lang="en">
- Tier-1 mirrors are required to:</para>
- <itemizedlist>
- <listitem><para xml:lang="en">carry the complete fileset</para></listitem>
- <listitem><para xml:lang="en">allow access to other mirror sites</para></listitem>
- <listitem><para xml:lang="en">provide <application>FTP</application> and
- <application>rsync</application> access</para></listitem>
- </itemizedlist>
-
- <para xml:lang="en">Furthermore, admins should be subscribed to the <link xlink:href="http://lists.FreeBSD.org/mailman/listinfo/freebsd-hubs">FreeBSD mirror sites mailing lists</link>.
- See <link xlink:href="https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/eresources.html#ERESOURCES-MAIL">this link</link> for details, how to subscribe.
- </para>
- <important>
- <para xml:lang="en">It is <emphasis>very</emphasis> important for a hub administrator, especially
- Tier-1 hub admins, to check the
- <link xlink:href="https://www.FreeBSD.org/releng/">release schedule</link>
- for the next FreeBSD release. This is important because it will tell you when the
- next release is scheduled
- to come out, and thus giving you time to prepare for the big spike of traffic which follows it.
- </para>
- <para xml:lang="en">
- It is also important that hub administrators try to keep their mirrors as up-to-date as
- possible (again, even more crucial for Tier-1 mirrors). If Mirror1 does not update for a
- while, lower tier mirrors will begin to mirror old data from Mirror1 and thus begins
- a downward spiral... Keep your mirrors up to date!
- </para>
- </important>
- </sect2>
- <sect2 xml:id="mirror-official-become">
- <title xml:lang="en">How to become official then?</title>
- <!--
- <para>
- An interesting question, especially, since the state
- of being official comes with some benefits, like a much
- higher bill from your ISP as more people will be using
- your site. Also it may be a key requirement to get access
- to a master site.
- </para>
- <para>
- Before applying, please consider (again) if
- another official mirror is really needed for
- your region. Check first with your zone administrator (<email>hostmaster@CC.FreeBSD.org</email>) or, if that fails, ask on the &a.hubs;.
- </para>
- <para>Ok, here is how to do it:</para>
- <procedure>
- <step>
- <para>
- Get the mirror running in first place (maybe not
- using a master site, yet).
- </para>
- </step>
- <step>
- <para>
- <ulink url="https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/eresources.html#ERESOURCES-MAIL">Subscribe</ulink> to the &a.hubs;.
- </para>
- </step>
- <step>
- <para>
- If everything works so far, contact the DNS administrator responsible
- for your region/country, and ask for a DNS entry for your
- site. The admin should able to be contacted via
- <email>hostmaster@CC.FreeBSD.org</email>, where
- <emphasis>CC</emphasis> is your country code/TLD.
- Your DNS entry will be as described
- in <xref linkend="mirror-where-organization"/>.
- </para>
- <para>
- If there is no subdomain set up for your
- country yet, you should contact
- <email>mirror-admin@FreeBSD.org</email>,
- or you can try the &a.hubs; first.
- </para>
- </step>
- <step>
- <para>
- Whoever helps you get an official name should send email
- to <email>mirror-admin@FreeBSD.org</email> so your site will be
- added to the mirror list in the
- <ulink url="https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook">FreeBSD
- Handbook</ulink>.
- </para>
- </step>
- </procedure>
- <para>That is it.</para>
- -->
- <para xml:lang="en">
- We are not accepting any new mirrors at this time.
- </para>
- </sect2>
- </sect1>
- <sect1 xml:id="mirror-statpages">
- <title xml:lang="en">Some statistics from mirror sites</title>
- <para xml:lang="en">
- Here are links to the stat pages of your favorite mirrors
- (a.k.a. the only ones who feel like providing stats).
- </para>
- <sect2 xml:id="mirror-statpagesftp">
- <title xml:lang="en">FTP site statistics</title>
- <itemizedlist>
- <listitem>
- <para xml:lang="en">ftp.is.FreeBSD.org - <email>hostmaster@is.FreeBSD.org</email> -
- <link xlink:href="http://www.rhnet.is/status/draupnir/draupnir.html">
- (Bandwidth)</link> <link xlink:href="http://www.rhnet.is/status/ftp/ftp-notendur.html">(FTP
- processes)</link> <link xlink:href="http://www.rhnet.is/status/ftp/http-notendur.html">(HTTP processes)
- </link>
- </para>
- </listitem>
- <listitem>
- <para xml:lang="en">ftp2.ru.FreeBSD.org - <email>mirror@macomnet.ru</email> -
- <link xlink:href="http://mirror.macomnet.net/mrtg/mirror.macomnet.net_195.128.64.25.html">(Bandwidth)</link>
- <link xlink:href="http://mirror.macomnet.net/mrtg/mirror.macomnet.net_proc.html">(HTTP and FTP users)</link>
- </para>
- </listitem>
- </itemizedlist>
- </sect2>
- </sect1>
-</article>
diff --git a/zh_TW.UTF-8/articles/hubs/zh_TW.po b/zh_TW.UTF-8/articles/hubs/zh_TW.po
deleted file mode 100644
index b7b2ad4f05..0000000000
--- a/zh_TW.UTF-8/articles/hubs/zh_TW.po
+++ /dev/null
@@ -1,665 +0,0 @@
-# $FreeBSD$
-msgid ""
-msgstr ""
-"Project-Id-Version: \n"
-"POT-Creation-Date: 2017-12-15 03:12+0800\n"
-"PO-Revision-Date: 2018-02-03 13:43+0800\n"
-"Language: zh_TW\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Last-Translator: \n"
-"Language-Team: \n"
-"X-Generator: Poedit 1.8.11\n"
-
-#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
-msgctxt "_"
-msgid "translator-credits"
-msgstr "translator-credits"
-
-#. (itstool) path: info/title
-#: article.translate.xml:4
-msgid "Mirroring FreeBSD"
-msgstr "Mirroring FreeBSD"
-
-#. (itstool) path: affiliation/address
-#: article.translate.xml:8
-#, no-wrap
-msgid "<email>kuriyama@FreeBSD.org</email>"
-msgstr "<email>kuriyama@FreeBSD.org</email>"
-
-#. (itstool) path: authorgroup/author
-#: article.translate.xml:7
-msgid "<personname><firstname>Jun</firstname><surname>Kuriyama</surname></personname><affiliation> <_:address-1/> </affiliation>"
-msgstr "<personname><firstname>Jun</firstname><surname>Kuriyama</surname></personname><affiliation> <_:address-1/> </affiliation>"
-
-#. (itstool) path: affiliation/address
-#: article.translate.xml:11
-#, no-wrap
-msgid "<email>logo@FreeBSD.org</email>"
-msgstr "<email>logo@FreeBSD.org</email>"
-
-#. (itstool) path: authorgroup/author
-#: article.translate.xml:10
-msgid "<personname><firstname>Valentino</firstname><surname>Vaschetto</surname></personname><affiliation> <_:address-1/> </affiliation>"
-msgstr "<personname><firstname>Valentino</firstname><surname>Vaschetto</surname></personname><affiliation> <_:address-1/> </affiliation>"
-
-#. (itstool) path: affiliation/address
-#: article.translate.xml:14
-#, no-wrap
-msgid "<email>dl@leo.org</email>"
-msgstr "<email>dl@leo.org</email>"
-
-#. (itstool) path: authorgroup/author
-#: article.translate.xml:13
-msgid "<personname><firstname>Daniel</firstname><surname>Lang</surname></personname><affiliation> <_:address-1/> </affiliation>"
-msgstr "<personname><firstname>Daniel</firstname><surname>Lang</surname></personname><affiliation> <_:address-1/> </affiliation>"
-
-#. (itstool) path: affiliation/address
-#: article.translate.xml:17
-#, no-wrap
-msgid "<email>kensmith@FreeBSD.org</email>"
-msgstr "<email>kensmith@FreeBSD.org</email>"
-
-#. (itstool) path: authorgroup/author
-#: article.translate.xml:16
-msgid "<personname><firstname>Ken</firstname><surname>Smith</surname></personname><affiliation> <_:address-1/> </affiliation>"
-msgstr "<personname><firstname>Daniel</firstname><surname>Lang</surname></personname><affiliation> <_:address-1/> </affiliation>"
-
-#. (itstool) path: legalnotice/para
-#: article.translate.xml:22
-msgid "FreeBSD is a registered trademark of the FreeBSD Foundation."
-msgstr "FreeBSD 是 FreeBSD基金會的註冊商標."
-
-#. (itstool) path: legalnotice/para
-#: article.translate.xml:24
-msgid "Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this document, and the FreeBSD Project was aware of the trademark claim, the designations have been followed by the <quote>™</quote> or the <quote>®</quote> symbol."
-msgstr "許多製造商和經銷商使用一些稱為商標的圖案或文字設計來彰顯自己的產品.本文中出現的眾多商標,以及 FreeBSD Project 本身廣所人知的商標,後面將以 <quote>™</quote> 或 <quote>®</quote> 符號來標註."
-
-#. (itstool) path: info/pubdate
-#. (itstool) path: info/releaseinfo
-#: article.translate.xml:32 article.translate.xml:34
-msgid "$FreeBSD$"
-msgstr "$FreeBSD$"
-
-#. (itstool) path: abstract/para
-#: article.translate.xml:37
-msgid "An in-progress article on how to mirror FreeBSD, aimed at hub administrators."
-msgstr "這是份介紹如何 mirror FreeBSD,主要是針對網路中心管理者或託管於大型資料中心的管理者."
-
-#. (itstool) path: note/para
-#: article.translate.xml:43
-msgid "We are not accepting new mirrors at this time."
-msgstr "我們目前不接受新Mirror站點的申請."
-
-# 聯絡方式
-#. (itstool) path: sect1/title
-#: article.translate.xml:47
-msgid "Contact Information"
-msgstr "聯繫方式"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:49
-msgid "The Mirror System Coordinators can be reached through email at <email>mirror-admin@FreeBSD.org</email>. There is also a <link xlink:href=\"http://lists.FreeBSD.org/mailman/listinfo/freebsd-hubs\">FreeBSD mirror sites mailing lists</link>."
-msgstr ""
-
-#. (itstool) path: sect1/title
-#: article.translate.xml:55
-msgid "Requirements for FreeBSD mirrors"
-msgstr "FreeBSD mirrors 的需求"
-
-#. (itstool) path: sect2/title
-#: article.translate.xml:57
-msgid "Disk Space"
-msgstr "磁碟空間"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:58
-msgid "Disk space is one of the most important requirements. Depending on the set of releases, architectures, and degree of completeness you want to mirror, a huge amount of disk space may be consumed. Also keep in mind that <emphasis>official</emphasis> mirrors are probably required to be complete. The web pages should always be mirrored completely. Also note that the numbers stated here are reflecting the current state (at 10.4-RELEASE/11.1-RELEASE). Further development and releases will only increase the required amount. Also make sure to keep some (ca. 10-20%) extra space around just to be sure. Here are some approximate figures:"
-msgstr "磁碟空間是最為需要. 根據你想要 mirror 的發行版、CPU架構 ,可能會消耗大量的磁碟空間.另外請注意 <emphasis>官方</emphasis> 鏡像站需要完整 mirror。網站內容亦需要完整鏡像。且這裡所述的數字是反應目前版本狀態 (如 10.4-RELEASE/11.1-RELEASE )。而不斷的開發與發行將會增加所需空間。並請務必保留一些 ( 約10-20% ) 額外空間。這裡大約估計如下:"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:74
-msgid "Full FTP Distribution: 1.4 TB"
-msgstr "完整的作業系統套件 FTP 站所需:1.4 TB"
-
-# CTM deltas: 10GB
-#. (itstool) path: listitem/para
-#: article.translate.xml:75
-msgid "CTM deltas: 10 GB"
-msgstr "CTM deltas: 10 GB"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:76
-msgid "Web pages: 1GB"
-msgstr "網站: 1GB"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:78
-msgid "The current disk usage of FTP Distribution can be found at <link xlink:href=\"ftp://ftp.FreeBSD.org/pub/FreeBSD/dir.sizes\">ftp://ftp.FreeBSD.org/pub/FreeBSD/dir.sizes</link>."
-msgstr "目前 FTP Distribution 的磁碟使用可在 <link xlink:href=\"ftp://ftp.FreeBSD.org/pub/FreeBSD/dir.sizes\">ftp://ftp.FreeBSD.org/pub/FreeBSD/dir.sizes</link> 找到。"
-
-#. (itstool) path: sect2/title
-#: article.translate.xml:84
-msgid "Network Connection/Bandwidth"
-msgstr "網路連線/頻寬"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:85
-msgid "Of course, you need to be connected to the Internet. The required bandwidth depends on your intended use of the mirror. If you just want to mirror some parts of FreeBSD for local use at your site/intranet, the demand may be much smaller than if you want to make the files publicly available. If you intend to become an official mirror, the bandwidth required will be even higher. We can only give rough estimates here:"
-msgstr "當然,你一定要能連上 Internet。 頻寬需求多少,這要看你所想要的 mirror 程度而定。 若只想要 mirror 一部份的 FreeBSD 檔案以作為網站或 intranet 的局部用途, 那麼頻寬需求會明顯比成為公共服務用途的小一些。 若想成為 official mirror 之一的話,那麼頻寬就勢必得增加才夠用。以下,我們僅列出一些估計值以做為參考: "
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:96
-msgid "Local site, no public access: basically no minimum, but &lt; 2 Mbps could make syncing too slow."
-msgstr "本地站台,沒有要公共存取: 基本上沒有最低需求,但是 &lt; 2Mbps 同步將會非常緩慢"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:98
-msgid "Unofficial public site: 34 Mbps is probably a good start."
-msgstr "非官方公共站台: 34Mbps 是不錯的開始."
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:99
-msgid "Official site: &gt; 100 Mbps is recommended, and your host should be connected as close as possible to your border router."
-msgstr "官方站台: &gt; 100Mbps 是建議值,並且你的主機必須盡可能連接靠近邊界路由器."
-
-#. (itstool) path: sect2/title
-#: article.translate.xml:104
-msgid "System Requirements, CPU, RAM"
-msgstr "系統需求,CPU,RAM"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:105
-msgid "One thing this depends on the expected number of clients, which is determined by the server's policy. It is also affected by the types of services you want to offer. Plain FTP or HTTP services may not require a huge amount of resources. Watch out if you provide rsync. This can have a huge impact on CPU and memory requirements as it is considered a memory hog. The following are just examples to give you a very rough hint."
-msgstr "這取決於預期的客戶端數量,這是由伺服器的策略決定的。也會受到您提供的服務類型而影響.普通的 FTP 或 HTTP 服務可能不需要大量的資源。注意如果您提供rsync. 這可能會對 CPU 和記憶體的需求產生巨大的影響,因為會消耗大量記憶體。 以下只是給你一個非常粗略的的例子。"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:117
-msgid "For a moderately visited site that offers <application>rsync</application>, you might consider a current CPU with around 800MHz - 1 GHz, and at least 512MB RAM. This is probably the minimum you want for an <emphasis>official</emphasis> site."
-msgstr "針對一個較常被瀏覽的網站 <application>rsync</application>,您須考量處理器大約 800Mhz 至 1Ghz,並且安裝最少 512MB RAM,這或許是成為一個 <emphasis>官方</emphasis> 站台的最小需求."
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:125
-msgid "For a frequently used site you definitely need more RAM (consider 2GB as a good start) and possibly more CPU, which could also mean that you need to go for a SMP system."
-msgstr "為了一個經常使用的網站你絕對需要更多 RAM (2GB是不錯的開始) 並且儘可能有更多 CPU , 這也表示你需要一個 SMP 系統。"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:131
-msgid "You also want to consider a fast disk subsystem. Operations on the SVN repository require a fast disk subsystem (RAID is highly advised). A SCSI controller that has a cache of its own can also speed up things since most of these services incur a large number of small modifications to the disk."
-msgstr "您也會需要考慮有一個較快的磁碟系統。在管理 SVN repository 需要一個快速的磁碟系統 ( 強烈建議 RAID)。有自己的快取記憶體的 SCSI 控制器也可以加快速度,因為大多數這些服務會對磁碟進行大量的小幅修改。"
-
-#. (itstool) path: sect2/title
-#: article.translate.xml:141
-msgid "Services to offer"
-msgstr "提供的服務"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:142
-msgid "Every mirror site is required to have a set of core services available. In addition to these required services, there are a number of optional services that server administrators may choose to offer. This section explains which services you can provide and how to go about implementing them."
-msgstr "每個鏡像站都需要一有一組可用的核心服務。除了這些所需的服務之外,還有許多伺服器管理員可以選擇提供的選用服務。本節將說明您可以提供哪些服務以及如何實作這些服務。"
-
-#. (itstool) path: sect3/title
-#: article.translate.xml:150
-msgid "FTP (required for FTP fileset)"
-msgstr "FTP (需要提供給FTP檔案集)"
-
-#. (itstool) path: sect3/para
-#: article.translate.xml:151
-msgid "This is one of the most basic services, and it is required for each mirror offering public FTP distributions. FTP access must be anonymous, and no upload/download ratios are allowed (a ridiculous thing anyway). Upload capability is not required (and <emphasis>must</emphasis> never be allowed for the FreeBSD file space). Also the FreeBSD archive should be available under the path <filename>/pub/FreeBSD</filename>."
-msgstr "這是最基本的服務之一。需要為每個鏡像站提供公共的 FTP distributions 。 FTP 存取必須是匿名的, 不允許上傳/下載比率 (這是一件荒謬的事),上傳功能不是必需的 (且<emphasis>必須 </emphasis>絕不允許 FreeBSD 檔案空間)。另外,FreeBSD archive 應該在路徑<filename>/pub/FreeBSD</filename>下。"
-
-#. (itstool) path: sect3/para
-#: article.translate.xml:162
-msgid "There is a lot of software available which can be set up to allow anonymous FTP (in alphabetical order)."
-msgstr "這裡有很多可用的軟體可以架設允許匿名的 FTP 服務 (按字母順序)。"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:167
-msgid "<command>/usr/libexec/ftpd</command>: FreeBSD's own ftpd can be used. Be sure to read <citerefentry><refentrytitle>ftpd</refentrytitle><manvolnum>8</manvolnum></citerefentry>."
-msgstr "<command>/usr/libexec/ftpd</command>: FreeBSD 內建的 ftpd 可以使用。請您參閱 <citerefentry><refentrytitle>ftpd</refentrytitle><manvolnum>8</manvolnum></citerefentry>。"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:171
-msgid "<package>ftp/ncftpd</package>: A commercial package, free for educational use."
-msgstr "<package>ftp/ncftpd</package>。一個商業軟體套件,免費供教育使用。"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:175
-msgid "<package>ftp/oftpd</package>: An ftpd designed with security as a main focus."
-msgstr "<package>ftp/oftpd</package>:一個以安全性作為主要考量的 ftpd。"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:179
-msgid "<package>ftp/proftpd</package>: A modular and very flexible ftpd."
-msgstr "<package>ftp/proftpd</package>:一個模組化且非常有彈性的 ftpd。"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:182
-msgid "<package>ftp/pure-ftpd</package>: Another ftpd developed with security in mind."
-msgstr "<package>ftp/pure-ftpd</package>: 另一個為安全所設計的 ftpd。"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:185
-msgid "<package>ftp/twoftpd</package>: As above."
-msgstr "<package>ftp/twoftpd</package>:如上。"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:186
-msgid "<package>ftp/vsftpd</package>: The <quote>very secure</quote> ftpd."
-msgstr "<package>ftp/vsftpd</package>:<quote>非常安全的</quote> ftpd。"
-
-#. (itstool) path: sect3/para
-#: article.translate.xml:188
-msgid "FreeBSD's <application>ftpd</application>, <application>proftpd</application> and maybe <application>ncftpd</application> are among the most commonly used FTPds. The others do not have a large userbase among mirror sites. One thing to consider is that you may need flexibility in limiting how many simultaneous connections are allowed, thus limiting how much network bandwidth and system resources are consumed."
-msgstr "FreeBSD 的 <application>ftpd</application>、<application>proftpd</application> 和也許 <application>ncftpd</application> 是最常使用的 FTP 軟體。其他的在鏡像站並沒有大量用戶基礎。需要考慮的一件事情是,您可能需要性地來限制允許同時連線數,從而限制消耗多少網路頻寬和系統資源。"
-
-#. (itstool) path: sect3/title
-#: article.translate.xml:198
-msgid "Rsync (optional for FTP fileset)"
-msgstr "Rsync (給FTP檔案集選用)"
-
-#. (itstool) path: sect3/para
-#: article.translate.xml:199
-msgid "<application>Rsync</application> is often offered for access to the contents of the FTP area of FreeBSD, so other mirror sites can use your system as their source. The protocol is different from FTP in many ways. It is much more bandwidth friendly, as only differences between files are transferred instead of whole files when they change. <application>Rsync</application> does require a significant amount of memory for each instance. The size depends on the size of the synced module in terms of the number of directories and files. <application>Rsync</application> can use <command>rsh</command> and <command>ssh</command> (now default) as a transport, or use its own protocol for stand-alone access (this is the preferred method for public rsync servers). Authentication, connection limits, and other restrictions may be applied. There is just one software package available:"
-msgstr "<application>Rsync</application> 通常是用在存取 FreeBSD 系統中的FTP內容,其他的鏡像站可以使用你的系統當作他們的來源。這個協定和 FTP 有很多不同,它比較不那麼消耗頻寬,只有當比對檔案間有變動才傳輸檔案,而不是整個檔案傳完。<application>Rsync</application> 需要較多的記憶體。大小取決於檔案與目錄的數目及同步模組大小。<application>Rsync</application> 可以使用 <command>rsh</command> 和 <command>ssh</command> (現在為預設)來傳輸, 或使用自己的協定單獨存取(這是公共rsync伺服器的首選方法)。可以用認證、連接限制和其他限制。只有一個軟體套件可以用:"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:217
-msgid "<package>net/rsync</package>"
-msgstr "<package>net/rsync</package>"
-
-#. (itstool) path: sect3/title
-#: article.translate.xml:221
-msgid "HTTP (required for web pages, optional for FTP fileset)"
-msgstr "HTTP(網頁需要,FTP 檔案集則是選用)"
-
-#. (itstool) path: sect3/para
-#: article.translate.xml:222
-msgid "If you want to offer the FreeBSD web pages, you will need to install a web server. You may optionally offer the FTP fileset via HTTP. The choice of web server software is left up to the mirror administrator. Some of the most popular choices are:"
-msgstr "如果您想提供 FreeBSD 的網頁,您需要安裝一個網頁伺服器。您可以選擇利用 HTTP 提供 FTP 檔案集。網頁伺服器軟體的選擇留給鏡像站管理員選擇。一些最受歡迎的選擇是:"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:231
-msgid "<package>www/apache22</package>: <application>Apache</application> is the most widely deployed web server on the Internet. It is used extensively by the FreeBSD Project."
-msgstr "<package>www/apache22</package>:<application>Apache</application> 是網際網路上最廣泛使用的網頁伺服器。 它被 FreeBSD 計畫廣泛使用。"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:238
-msgid "<package>www/thttpd</package>: If you are going to be serving a large amount of static content you may find that using an application such as thttpd is more efficient than <application>Apache</application>. It is optimized for excellent performance on FreeBSD."
-msgstr "<package>www/thttpd</package>:如果您要提供大量的靜態內容,您可能會發現使用諸如 thttpd 之類的應用程式會比 <application>Apache</application> 更有效率。它針對 FreeBSD 的優秀性能進行了最佳化。"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:246
-msgid "<package>www/boa</package>: <application>Boa</application> is another alternative to <application>thttpd</application> and <application>Apache</application>. It should provide considerably better performance than <application>Apache</application> for purely static content. It does not, at the time of this writing, contain the same set of optimizations for FreeBSD that are found in <application>thttpd</application>."
-msgstr "<package>www/boa</package>:<application>Boa</application> 是 <application>thttpd</application> 和 <application>Apache</application> 外的另一個選擇。對於純粹的靜態網頁,它應該會提供比 <application>Apache</application> 更好的性能。在寫這篇文章的時候,它並不包含像在 <application>thttpd</application> 中一樣針對FreeBSD 做最佳化。"
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:258
-msgid "<package>www/nginx</package>: <application>Nginx</application> is a high performance edge web server with a low memory footprint and key features to build a modern and efficient web infrastructure. Features include a HTTP server, HTTP and mail reverse proxy, caching, load balancing, compression, request throttling, connection multiplexing and reuse, SSL offload and HTTP media streaming."
-msgstr "<package>www/nginx</package>:<application>Nginx</application> 是一款高性能的最新網頁服務器,具有低記憶體佔用量和關鍵特色,可以構建現代高效率網頁基礎架構,功能包括 HTTP 伺服器,HTTP 和郵件反向代理,快取,負載平衡,壓縮,請求限制(request throtting),連接多工與再利用,SSL 卸載和 HTTP 媒體串流。"
-
-#. (itstool) path: sect1/title
-#: article.translate.xml:272
-msgid "How to Mirror FreeBSD"
-msgstr "如何Mirror FreeBSD 站台"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:273
-msgid "Ok, now you know the requirements and how to offer the services, but not how to get it. :-) This section explains how to actually mirror the various parts of FreeBSD, what tools to use, and where to mirror from."
-msgstr "好,現在你知道硬體需求和如何提供服務,但不知道如何做。:-) 這節將解釋如何實際 mirror FreeBSD 的不同部分,使用哪些工具以及從哪裡 mirror。"
-
-#. (itstool) path: sect2/title
-#: article.translate.xml:281
-msgid "Mirroring the FTP site"
-msgstr "鏡像 FTP 站"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:282
-msgid "The FTP area is the largest amount of data that needs to be mirrored. It includes the <emphasis>distribution sets</emphasis> required for network installation, the <emphasis>branches</emphasis> which are actually snapshots of checked-out source trees, the <emphasis>ISO Images</emphasis> to write CD-ROMs with the installation distribution, a live file system, and a snapshot of the ports tree. All of course for various FreeBSD versions, and various architectures."
-msgstr "FTP 部份有最大量的資料需要被 mirror。它包括網路安裝所需的<emphasis>發布集</emphasis>,實際上是原始碼樹快照的<emphasis>分支</emphasis>,可燒錄光碟供安裝系統的<emphasis>ISO映像檔</emphasis> ,一個可 live 開機的檔案系統,以及一個 port tree 的快照。當然,全都有各種 FreeBSD 版本和各種CPU架構。"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:292
-msgid "The best way to mirror the FTP area is <application>rsync</application>. You can install the port <package>net/rsync</package> and then use rsync to sync with your upstream host. <application>rsync</application> is already mentioned in <xref linkend=\"mirror-serv-rsync\"/>. Since <application>rsync</application> access is not required, your preferred upstream site may not allow it. You may need to hunt around a little bit to find a site that allows <application>rsync</application> access."
-msgstr ""
-
-#. (itstool) path: note/para
-#: article.translate.xml:303
-msgid "Since the number of <application>rsync</application> clients will have a significant impact on the server machine, most admins impose limitations on their server. For a mirror, you should ask the site maintainer you are syncing from about their policy, and maybe an exception for your host (since you are a mirror)."
-msgstr "由於 <application>rsync</application> 客戶端的數量將對伺服器主機產生重大影響,因此大多數管理員會對伺服器負荷加以限制。對於 mirror 站台,您應該詢問您要 mirror 站台的管理人員他們的管理政策,也許需要對您的主機開放例外(因為您是一個 mirror 站)。"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:312
-msgid "A command line to mirror FreeBSD might look like:"
-msgstr "一個需要mirror FreeBSD官網的指令如下:"
-
-#. (itstool) path: sect2/screen
-#: article.translate.xml:313
-#, no-wrap
-msgid "<prompt>%</prompt> <userinput>rsync -vaHz --delete rsync://ftp4.de.FreeBSD.org/FreeBSD/ /pub/FreeBSD/</userinput>"
-msgstr "<prompt>%</prompt> <userinput>rsync -vaHz --delete rsync://ftp4.de.FreeBSD.org/FreeBSD/ /pub/FreeBSD/</userinput>"
-
-# source text少了一個<link>的標籤,多了一個</link>不知道重不重要?
-#. (itstool) path: sect2/para
-#: article.translate.xml:314
-msgid "Consult the documentation for <application>rsync</application>, which is also available at <link xlink:href=\"http://rsync.samba.org/\">http://rsync.samba.org/</link>, about the various options to be used with rsync. If you sync the whole module (unlike subdirectories), be aware that the module-directory (here \"FreeBSD\") will not be created, so you cannot omit the target directory. Also you might want to set up a script framework that calls such a command via <citerefentry><refentrytitle>cron</refentrytitle><manvolnum>8</manvolnum></citerefentry>."
-msgstr ""
-
-#. (itstool) path: sect2/title
-#: article.translate.xml:327
-msgid "Mirroring the WWW pages"
-msgstr "Mirroring 網頁"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:328
-msgid "The FreeBSD website should only be mirrored via <application>rsync</application>."
-msgstr "FreeBSD 網站應只能透過<application>rsync</application>指令來mirror."
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:331
-msgid "A command line to mirror the FreeBSD web site might look like:"
-msgstr "一個 mirror FreeBSD 網站的指令應該看起像這樣:"
-
-#. (itstool) path: sect2/screen
-#: article.translate.xml:332
-#, no-wrap
-msgid "<prompt>%</prompt> <userinput>rsync -vaHz --delete rsync://bit0.us-west.freebsd.org/FreeBSD-www-data/ /usr/local/www/</userinput>"
-msgstr "<prompt>%</prompt> <userinput>rsync -vaHz --delete rsync://bit0.us-west.freebsd.org/FreeBSD-www-data/ /usr/local/www/</userinput>"
-
-#. (itstool) path: sect2/title
-#: article.translate.xml:335
-msgid "Mirroring Packages"
-msgstr "Mirroring 套件"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:336
-msgid "Due to very high requirements of bandwidth, storage and adminstration the FreeBSD Project has decided not to allow public mirrors of packages. For sites with lots of machines, it might be advantagous to run a caching HTTP proxy for the <citerefentry><refentrytitle>pkg</refentrytitle><manvolnum>8</manvolnum></citerefentry> process. Alternatively specific packages and their dependencies can be fetched by running something like the following:"
-msgstr "由於對頻寬,儲存空間和管理的要求非常高,FreeBSD 計畫決定不允許公眾 mirror 套件. 對於擁有大量伺服主機的網站,建議為 <citerefentry><refentrytitle>pkg</refentrytitle><manvolnum>8</manvolnum></citerefentry> 使用 HTTP proxy 快取可能會有所幫助。或者,您可以使用以下指令獲得套件與相依套件:"
-
-#. (itstool) path: sect2/screen
-#: article.translate.xml:343
-#, no-wrap
-msgid "<prompt>%</prompt> <userinput>pkg fetch -d -o <replaceable>/usr/local/mirror</replaceable> <replaceable>vim</replaceable></userinput>"
-msgstr "<prompt>%</prompt> <userinput>pkg fetch -d -o <replaceable>/usr/local/mirror</replaceable> <replaceable>vim</replaceable></userinput>"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:345
-msgid "Once those packages have been fetched, the repository metadata must be generated by running:"
-msgstr "一旦這些套件包被下載,就必須執行以下命令來產生套件庫數據:"
-
-#. (itstool) path: sect2/screen
-#: article.translate.xml:347
-#, no-wrap
-msgid "<prompt>%</prompt> <userinput>pkg repo <replaceable>/usr/local/mirror</replaceable></userinput>"
-msgstr "<prompt>%</prompt> <userinput>pkg repo <replaceable>/usr/local/mirror</replaceable></userinput>"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:349
-msgid "Once the packages have been fetched and the metadata for the repository has been generated, serve the packages up to the client machines via HTTP. For additional information see the man pages for <citerefentry><refentrytitle>pkg</refentrytitle><manvolnum>8</manvolnum></citerefentry>, specifically the <citerefentry><refentrytitle>pkg-repo</refentrytitle><manvolnum>8</manvolnum></citerefentry> page."
-msgstr "一旦套件被下載並且已經生成了套件庫的數據,就可以透過 HTTP 協定將套件提供給客戶端機器。有關更多訊息,請參閱 <citerefentry><refentrytitle>pkg</refentrytitle><manvolnum>8</manvolnum></citerefentry> 的 man pages,特別是<citerefentry><refentrytitle>pkg-repo</refentrytitle><manvolnum>8</manvolnum></citerefentry> 頁面。"
-
-#. (itstool) path: sect2/title
-#: article.translate.xml:356
-msgid "How often should I mirror?"
-msgstr "我多久應該mirror?"
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:357
-msgid "Every mirror should be updated at a minimum of once per day. Certainly a script with locking to prevent multiple runs happening at the same time will be needed to run from <citerefentry><refentrytitle>cron</refentrytitle><manvolnum>8</manvolnum></citerefentry>. Since nearly every admin does this in their own way, specific instructions cannot be provided. It could work something like this:"
-msgstr ""
-
-#. (itstool) path: step/para
-#: article.translate.xml:367
-msgid "Put the command to run your mirroring application in a script. Use of a plain <command>/bin/sh</command> script is recommended."
-msgstr ""
-
-#. (itstool) path: step/para
-#: article.translate.xml:374
-msgid "Add some output redirections so diagnostic messages are logged to a file."
-msgstr ""
-
-#. (itstool) path: step/para
-#: article.translate.xml:380
-msgid "Test if your script works. Check the logs."
-msgstr ""
-
-#. (itstool) path: step/para
-#: article.translate.xml:385
-msgid "Use <citerefentry><refentrytitle>crontab</refentrytitle><manvolnum>1</manvolnum></citerefentry> to add the script to the appropriate user's <citerefentry><refentrytitle>crontab</refentrytitle><manvolnum>5</manvolnum></citerefentry>. This should be a different user than what your FTP daemon runs as so that if file permissions inside your FTP area are not world-readable those files can not be accessed by anonymous FTP. This is used to <quote>stage</quote> releases — making sure all of the official mirror sites have all of the necessary release files on release day."
-msgstr ""
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:397
-msgid "Here are some recommended schedules:"
-msgstr ""
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:400
-msgid "FTP fileset: daily"
-msgstr ""
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:401
-msgid "WWW pages: daily"
-msgstr ""
-
-#. (itstool) path: sect1/title
-#: article.translate.xml:406
-msgid "Where to mirror from"
-msgstr ""
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:407
-msgid "This is an important issue. So this section will spend some effort to explain the backgrounds. We will say this several times: under no circumstances should you mirror from <systemitem class=\"fqdomainname\">ftp.FreeBSD.org</systemitem>."
-msgstr ""
-
-#. (itstool) path: sect2/title
-#: article.translate.xml:414
-msgid "A few words about the organization"
-msgstr ""
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:415
-msgid "Mirrors are organized by country. All official mirrors have a DNS entry of the form <systemitem class=\"fqdomainname\">ftpN.CC.FreeBSD.org</systemitem>. <emphasis>CC</emphasis> (i.e. country code) is the <emphasis>top level domain</emphasis> (TLD) of the country where this mirror is located. <emphasis>N</emphasis> is a number, telling that the host would be the <emphasis>Nth</emphasis> mirror in that country. (Same applies to <systemitem>wwwN.CC.FreeBSD.org</systemitem>, etc.) There are mirrors with no <emphasis>CC</emphasis> part. These are the mirror sites that are very well connected and allow a large number of concurrent users. <systemitem class=\"fqdomainname\">ftp.FreeBSD.org</systemitem> is actually two machines, one currently located in Denmark and the other in the United States. It is <emphasis>NOT</emphasis> a master site and should never be used to mirror from. Lots of online documentation leads <quote>interactive</quote>users to <systemitem class=\"fqdomainname\">ftp.FreeBSD.org</systemitem> so automated mirroring systems should find a different machine to mirror from."
-msgstr ""
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:438
-msgid "Additionally there exists a hierarchy of mirrors, which is described in terms of <emphasis>tiers</emphasis>. The master sites are not referred to but can be described as <emphasis>Tier-0</emphasis>. Mirrors that mirror from these sites can be considered <emphasis>Tier-1</emphasis>, mirrors of <emphasis>Tier-1</emphasis>-mirrors, are <emphasis>Tier-2</emphasis>, etc. Official sites are encouraged to be of a low <emphasis>tier</emphasis>, but the lower the tier the higher the requirements in terms as described in <xref linkend=\"mirror-requirements\"/>. Also access to low-tier-mirrors may be restricted, and access to master sites is definitely restricted. The <emphasis>tier</emphasis>-hierarchy is not reflected by DNS and generally not documented anywhere except for the master sites. However, official mirrors with low numbers like 1-4, are usually <emphasis>Tier-1</emphasis> (this is just a rough hint, and there is no rule)."
-msgstr ""
-
-#. (itstool) path: sect2/title
-#: article.translate.xml:459
-msgid "Ok, but where should I get the stuff now?"
-msgstr ""
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:460
-msgid "Under no circumstances should you mirror from <systemitem class=\"fqdomainname\">ftp.FreeBSD.org</systemitem>. The short answer is: from the site that is closest to you in Internet terms, or gives you the fastest access."
-msgstr ""
-
-#. (itstool) path: sect3/title
-#: article.translate.xml:467
-msgid "I just want to mirror from somewhere!"
-msgstr ""
-
-#. (itstool) path: sect3/para
-#: article.translate.xml:468
-msgid "If you have no special intentions or requirements, the statement in <xref linkend=\"mirror-where-where\"/> applies. This means:"
-msgstr ""
-
-#. (itstool) path: step/para
-#: article.translate.xml:475
-msgid "Check for those which provide fastest access (number of hops, round-trip-times) and offer the services you intend to use (like <application>rsync</application>)."
-msgstr ""
-
-#. (itstool) path: step/para
-#: article.translate.xml:483
-msgid "Contact the administrators of your chosen site stating your request, and asking about their terms and policies."
-msgstr ""
-
-#. (itstool) path: step/para
-#: article.translate.xml:490
-msgid "Set up your mirror as described above."
-msgstr ""
-
-#. (itstool) path: sect3/title
-#: article.translate.xml:497
-msgid "I am an official mirror, what is the right site for me?"
-msgstr ""
-
-#. (itstool) path: sect3/para
-#: article.translate.xml:498
-msgid "In general the description in <xref linkend=\"mirror-where-simple\"/> still applies. Of course you may want to put some weight on the fact that your upstream should be of a low tier. There are some other considerations about <emphasis>official</emphasis> mirrors that are described in <xref linkend=\"mirror-official\"/>."
-msgstr ""
-
-#. (itstool) path: sect3/title
-#: article.translate.xml:508
-msgid "I want to access the master sites!"
-msgstr ""
-
-#. (itstool) path: sect3/para
-#: article.translate.xml:509
-msgid "If you have good reasons and good prerequisites, you may want and get access to one of the master sites. Access to these sites is generally restricted, and there are special policies for access. If you are already an <emphasis>official</emphasis> mirror, this certainly helps you getting access. In any other case make sure your country really needs another mirror. If it already has three or more, ask the <quote>zone administrator</quote> (<email>hostmaster@CC.FreeBSD.org</email>) or <link xlink:href=\"http://lists.FreeBSD.org/mailman/listinfo/freebsd-hubs\">FreeBSD mirror sites mailing lists</link> first."
-msgstr ""
-
-#. (itstool) path: sect3/para
-#: article.translate.xml:519
-msgid "Whoever helped you become, an <emphasis>official</emphasis> should have helped you gain access to an appropriate upstream host, either one of the master sites or a suitable Tier-1 site. If not, you can send email to <email>mirror-admin@FreeBSD.org</email> to request help with that."
-msgstr ""
-
-#. (itstool) path: sect3/para
-#: article.translate.xml:527
-msgid "There is one master site for the FTP fileset."
-msgstr ""
-
-# ftp-master.FreeBSD.org
-#. (itstool) path: sect4/title
-#: article.translate.xml:531
-msgid "ftp-master.FreeBSD.org"
-msgstr ""
-
-#. (itstool) path: sect4/para
-#: article.translate.xml:532
-msgid "This is the master site for the FTP fileset."
-msgstr ""
-
-# <systemitem>ftp-master.FreeBSD.org</systemitem> 提供 <application>rsync</application> 存取, 針對 FTP站點提供rsync
-# . 請參閱 <xref linkend="mirror-ftp-rsync"/>.
-#. (itstool) path: sect4/para
-#: article.translate.xml:535
-msgid "<systemitem>ftp-master.FreeBSD.org</systemitem> provides <application>rsync</application> access, in addition to FTP. Refer to <xref linkend=\"mirror-ftp-rsync\"/>."
-msgstr ""
-
-#. (itstool) path: sect4/para
-#: article.translate.xml:541
-msgid "Mirrors are also encouraged to allow <application>rsync</application> access for the FTP contents, since they are <emphasis>Tier-1</emphasis>-mirrors."
-msgstr ""
-
-#. (itstool) path: sect1/title
-#: article.translate.xml:551
-msgid "Official Mirrors"
-msgstr ""
-
-# 官方mirror站具有以下條件
-#. (itstool) path: sect1/para
-#: article.translate.xml:552
-msgid "Official mirrors are mirrors that"
-msgstr ""
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:556
-msgid "a) have a <systemitem>FreeBSD.org</systemitem> DNS entry (usually a CNAME)."
-msgstr ""
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:562
-msgid "b) are listed as an official mirror in the FreeBSD documentation (like handbook)."
-msgstr ""
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:569
-msgid "So far to distinguish official mirrors. Official mirrors are not necessarily <emphasis>Tier-1</emphasis>-mirrors. However you probably will not find a <emphasis>Tier-1</emphasis>-mirror, that is not also official."
-msgstr ""
-
-#. (itstool) path: sect2/title
-#: article.translate.xml:575
-msgid "Special Requirements for official (tier-1) mirrors"
-msgstr ""
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:576
-msgid "It is not so easy to state requirements for all official mirrors, since the project is sort of tolerant here. It is more easy to say, what <emphasis>official tier-1 mirrors</emphasis> are required to. All other official mirrors can consider this a big <emphasis>should</emphasis>."
-msgstr ""
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:583
-msgid "Tier-1 mirrors are required to:"
-msgstr ""
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:586
-msgid "carry the complete fileset"
-msgstr ""
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:587
-msgid "allow access to other mirror sites"
-msgstr ""
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:588
-msgid "provide <application>FTP</application> and <application>rsync</application> access"
-msgstr ""
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:592
-msgid "Furthermore, admins should be subscribed to the <link xlink:href=\"http://lists.FreeBSD.org/mailman/listinfo/freebsd-hubs\">FreeBSD mirror sites mailing lists</link>. See <link xlink:href=\"https://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/eresources.html#ERESOURCES-MAIL\">this link</link> for details, how to subscribe."
-msgstr ""
-
-#. (itstool) path: important/para
-#: article.translate.xml:596
-msgid "It is <emphasis>very</emphasis> important for a hub administrator, especially Tier-1 hub admins, to check the <link xlink:href=\"https://www.FreeBSD.org/releng/\">release schedule</link> for the next FreeBSD release. This is important because it will tell you when the next release is scheduled to come out, and thus giving you time to prepare for the big spike of traffic which follows it."
-msgstr ""
-
-#. (itstool) path: important/para
-#: article.translate.xml:603
-msgid "It is also important that hub administrators try to keep their mirrors as up-to-date as possible (again, even more crucial for Tier-1 mirrors). If Mirror1 does not update for a while, lower tier mirrors will begin to mirror old data from Mirror1 and thus begins a downward spiral... Keep your mirrors up to date!"
-msgstr ""
-
-#. (itstool) path: sect2/title
-#: article.translate.xml:612
-msgid "How to become official then?"
-msgstr ""
-
-#. (itstool) path: sect2/para
-#: article.translate.xml:668
-msgid "We are not accepting any new mirrors at this time."
-msgstr ""
-
-#. (itstool) path: sect1/title
-#: article.translate.xml:674
-msgid "Some statistics from mirror sites"
-msgstr ""
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:675
-msgid "Here are links to the stat pages of your favorite mirrors (a.k.a. the only ones who feel like providing stats)."
-msgstr ""
-
-#. (itstool) path: sect2/title
-#: article.translate.xml:680
-msgid "FTP site statistics"
-msgstr ""
-
-#. (itstool) path: listitem/para
-#: article.translate.xml:683
-msgid "ftp.is.FreeBSD.org - <email>hostmaster@is.FreeBSD.org</email> - <link xlink:href=\"http://www.rhnet.is/status/draupnir/draupnir.html\"> (Bandwidth)</link> <link xlink:href=\"http://www.rhnet.is/status/ftp/ftp-notendur.html\">(FTP processes)</link> <link xlink:href=\"http://www.rhnet.is/status/ftp/http-notendur.html\">(HTTP processes) </link>"
-msgstr ""
-
-# ftp2.ru.FreeBSD.org - <email>mirror@macomnet.ru</email> - <link xlink:href="http://mirror.macomnet.net/mrtg/mirror.macomnet.net_195.128.64.25.html">(Bandwidth)</link> <link xlink:href="http://mirror.macomnet.net/mrtg/mirror.macomnet.net_proc.html">(HTTP and FTP users)</link>
-#. (itstool) path: listitem/para
-#: article.translate.xml:691
-msgid "ftp2.ru.FreeBSD.org - <email>mirror@macomnet.ru</email> - <link xlink:href=\"http://mirror.macomnet.net/mrtg/mirror.macomnet.net_195.128.64.25.html\">(Bandwidth)</link> <link xlink:href=\"http://mirror.macomnet.net/mrtg/mirror.macomnet.net_proc.html\">(HTTP and FTP users)</link>"
-msgstr ""
diff --git a/zh_TW.UTF-8/articles/leap-seconds/Makefile b/zh_TW.UTF-8/articles/leap-seconds/Makefile
deleted file mode 100644
index 890b94f26e..0000000000
--- a/zh_TW.UTF-8/articles/leap-seconds/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# $FreeBSD$
-#
-# Article: Leap Seconds
-
-DOC?= article
-
-FORMATS?= html
-WITH_ARTICLE_TOC?= YES
-
-INSTALL_COMPRESSED?= gz
-INSTALL_ONLY_COMPRESSED?=
-
-SRCS= article.xml
-
-URL_RELPREFIX?= ../../../..
-DOC_PREFIX?= ${.CURDIR}/../../..
-
-.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/articles/leap-seconds/article.xml b/zh_TW.UTF-8/articles/leap-seconds/article.xml
deleted file mode 100644
index 6ad9fd2e30..0000000000
--- a/zh_TW.UTF-8/articles/leap-seconds/article.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN" "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd">
-<article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="leapseconds" xml:lang="zh_TW">
-
- <info>
- <title>FreeBSD 對潤秒的支援</title>
-
- <pubdate>$FreeBSD$</pubdate>
- </info>
-
- <sect1 xml:id="leapseconds-definition">
- <title>說明</title>
-
- <para><emphasis>潤秒</emphasis>是為了同步地球自轉,與原子鐘所做的特定一秒的修正。本文描述FreeBSD 如何處理潤秒。</para>
-
- <para>本文寫作時,下一個潤秒會發生在2015年6月30日23:59:60 CST。下一次潤秒會發生在南北美洲和亞太地區的工作日。</para>
-
- <para>潤秒是由 <link xlink:href="http://datacenter.iers.org/"><acronym>IERS</acronym></link> 在 <link xlink:href="http://datacenter.iers.org/web/guest/bulletins/-/somos/5Rgv/product/16">Bulletin C</link>所發表。</para>
-
- <para>標準的潤秒行為描述在<link xlink:href="https://tools.ietf.org/html/rfc7164#section-3">RFC 7164</link>.。也可見 <citerefentry><refentrytitle>time2posix</refentrytitle><manvolnum>3</manvolnum></citerefentry>。</para>
- </sect1>
-
- <sect1 xml:id="leapseconds-posix">
- <title>FreeBSD預設的潤秒處理</title>
-
- <para>最簡單的處理潤秒方法使用FreeBSD預設的 <acronym>POSIX</acronym> 時間規則,並使用 <link xlink:href="../../../../doc/zh_TW.UTF-8/books/handbook/network-ntp.html"><acronym>NTP</acronym></link>。如果 <citerefentry><refentrytitle>ntpd</refentrytitle><manvolnum>8</manvolnum></citerefentry> 在執行,而且時間和上游正確處理潤秒的 <acronym>NTP</acronym> 伺服器同步,潤秒會使系統時間自動重複當天的最後一秒。不需要其他調整。</para>
-
- <para>如果上游的 <acronym>NTP</acronym> 伺服器無法正確地處理潤秒, <citerefentry><refentrytitle>ntpd</refentrytitle><manvolnum>8</manvolnum></citerefentry> 會在錯誤的上游伺服器發現錯誤並跳一秒後,跟著把時間跳一秒。</para>
-
- <para>如果未使用 <acronym>NTP</acronym> ,將需要在潤秒過後,手動調整系統時鐘。</para>
- </sect1>
-
- <sect1 xml:id="leapseconds-cautions">
- <title>警告</title>
-
- <para>潤秒的插入在全世界是在同一個瞬間: <acronym>UTC</acronym> 午夜。在日本,是在上午九點,在太平洋,是正午,在美洲,是傍晚,在歐洲,是晚上。</para>
-
- <para>我們相信和預期,如果提供正確和穩定的<acronym>NTP</acronym> 服務,FreeBSD會如設計地在這次潤秒正確運作,就像在之前遇到潤秒時一樣。</para>
-
- <para>然而我們要警告,實務上沒有應用程式曾經要求核心關於潤秒的事。我們的經驗是,如同設計,潤秒本質上是潤秒前一秒的重播,這對大部份應用程式設計師來說是意想不到的事。</para>
-
- <para>其他作業系統或電腦可能會或可能不會像FreeBSD用同樣方法處理潤秒,沒有正確和穩定<acronym>NTP</acronym> 服務的系統一點也不會知道潤秒的發生。</para>
-
- <para>電腦因為潤秒而當機並不是沒有聽聞,經驗上也顯示,有大量公用的<acronym>NTP</acronym> 伺服器沒有正確地處理和公告潤秒。</para>
-
- <para>請試著確定不會因為潤秒而發生任何可怕的事情。</para>
- </sect1>
-
- <sect1 xml:id="leapseconds-testing">
- <title>測試</title>
-
- <para>測試是否有使用潤秒是有可能的。由於 <acronym>NTP</acronym>的性質,測試可能要運作到潤秒前24小時。有些主要的參考時鐘來源只在潤秒前一個小時公告。詢問<acronym>NTP</acronym>行程:</para>
-
- <screen><prompt>%</prompt> <userinput>ntpq -c 'rv 0 leap'</userinput></screen>
-
- <para>包含<literal>leap_add_sec</literal> 的輸出指出對於潤秒的支援。潤秒前24小時,或是潤秒已經過了,會顯示<literal>leap_none</literal>。</para>
- </sect1>
-
- <sect1 xml:id="leapseconds-conclusion">
- <title>結論</title>
-
- <para>實務上,FreeBSD 的潤秒通常不是個問題。我們希望這篇概述能幫助釐清預期會遇到什麼狀況,如何使潤秒事件進行的更順利。</para>
- </sect1>
-</article>
diff --git a/zh_TW.UTF-8/articles/leap-seconds/zh_TW.po b/zh_TW.UTF-8/articles/leap-seconds/zh_TW.po
deleted file mode 100644
index 6be72337a7..0000000000
--- a/zh_TW.UTF-8/articles/leap-seconds/zh_TW.po
+++ /dev/null
@@ -1,239 +0,0 @@
-# $FreeBSD$
-msgid ""
-msgstr ""
-"Project-Id-Version: \n"
-"POT-Creation-Date: 2015-11-10 08:43-0700\n"
-"PO-Revision-Date: 2015-11-06 22:51+0800\n"
-"Last-Translator: \n"
-"Language-Team: \n"
-"Language: zh_TW\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 1.7.5\n"
-
-#. Put one translator per line, in the form NAME <EMAIL>, YEAR1, YEAR2
-msgctxt "_"
-msgid "translator-credits"
-msgstr "translator-credits"
-
-#. (itstool) path: info/title
-#: article.translate.xml:6
-msgid "FreeBSD Support for Leap Seconds"
-msgstr "FreeBSD 對潤秒的支援"
-
-#. (itstool) path: info/pubdate
-#: article.translate.xml:8
-msgid ""
-"$FreeBSD: head/en_US.ISO8859-1/articles/leap-seconds/article.xml 46895 "
-"2015-06-29 16:41:41Z wblock $"
-msgstr ""
-"$FreeBSD: head/en_US.ISO8859-1/articles/leap-seconds/article.xml 46895 "
-"2015-06-29 16:41:41Z wblock $"
-
-#. (itstool) path: sect1/title
-#: article.translate.xml:12
-msgid "Introduction"
-msgstr "說明"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:14
-msgid ""
-"A <emphasis>leap second</emphasis> is an ad-hoc one-second correction to "
-"synchronize atomic timescales with Earth rotation. This article describes "
-"how FreeBSD interacts with leap seconds."
-msgstr ""
-"<emphasis>潤秒</emphasis>是為了同步地球自轉,與原子鐘所做的特定一秒的修正。本"
-"文描述FreeBSD 如何處理潤秒。"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:19
-msgid ""
-"As of this writing, the next leap second will occur at 2015-Jun-30 23:59:60 "
-"UTC. This leap second will occur during a business day for North and South "
-"America and the Asia/Pacific region."
-msgstr ""
-"本文寫作時,下一個潤秒會發生在2015年6月30日23:59:60 CST。下一次潤秒會發生在南"
-"北美洲和亞太地區的工作日。"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:24
-msgid ""
-"Leap seconds are announced by <link xlink:href=\"http://datacenter.iers.org/"
-"\"><acronym>IERS</acronym></link> on <link xlink:href=\"http://datacenter."
-"iers.org/web/guest/bulletins/-/somos/5Rgv/product/16\">Bulletin C</link>."
-msgstr ""
-"潤秒是由 <link xlink:href=\"http://datacenter.iers.org/\"><acronym>IERS</"
-"acronym></link> 在 <link xlink:href=\"http://datacenter.iers.org/web/guest/"
-"bulletins/-/somos/5Rgv/product/16\">Bulletin C</link>所發表。"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:28
-msgid ""
-"Standard leap second behavior is described in <link xlink:href=\"https://"
-"tools.ietf.org/html/rfc7164#section-3\">RFC 7164</link>. Also see "
-"<citerefentry><refentrytitle>time2posix</refentrytitle><manvolnum>3</"
-"manvolnum></citerefentry>."
-msgstr ""
-"標準的潤秒行為描述在<link xlink:href=\"https://tools.ietf.org/html/"
-"rfc7164#section-3\">RFC 7164</link>.。也可見 "
-"<citerefentry><refentrytitle>time2posix</refentrytitle><manvolnum>3</"
-"manvolnum></citerefentry>。"
-
-#. (itstool) path: sect1/title
-#: article.translate.xml:33
-msgid "Default Leap Second Handling on FreeBSD"
-msgstr "FreeBSD預設的潤秒處理"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:35
-msgid ""
-"The easiest way to handle leap seconds is with the <acronym>POSIX</acronym> "
-"time rules FreeBSD uses by default, combined with <link xlink:href="
-"\"@@URL_RELPREFIX@@/doc/en_US.ISO8859-1/books/handbook/network-ntp.html"
-"\"><acronym>NTP</acronym></link>. When <citerefentry><refentrytitle>ntpd</"
-"refentrytitle><manvolnum>8</manvolnum></citerefentry> is running and the "
-"time is synchronized with upstream <acronym>NTP</acronym> servers that "
-"handle leap seconds correctly, the leap second will cause the system time to "
-"automatically repeat the last second of the day. No other adjustments are "
-"necessary."
-msgstr ""
-"最簡單的處理潤秒方法使用FreeBSD預設的 <acronym>POSIX</acronym> 時間規則,並使"
-"用 <link xlink:href=\"../../../../doc/zh_TW.UTF-8/books/handbook/network-ntp."
-"html\"><acronym>NTP</acronym></link>。如果 "
-"<citerefentry><refentrytitle>ntpd</refentrytitle><manvolnum>8</manvolnum></"
-"citerefentry> 在執行,而且時間和上游正確處理潤秒的 <acronym>NTP</acronym> 伺"
-"服器同步,潤秒會使系統時間自動重複當天的最後一秒。不需要其他調整。"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:44
-msgid ""
-"If the upstream <acronym>NTP</acronym> servers do not handle leap seconds "
-"correctly, <citerefentry><refentrytitle>ntpd</refentrytitle><manvolnum>8</"
-"manvolnum></citerefentry> will step the time by one second after the errant "
-"upstream server has noticed and stepped itself."
-msgstr ""
-"如果上游的 <acronym>NTP</acronym> 伺服器無法正確地處理潤秒, "
-"<citerefentry><refentrytitle>ntpd</refentrytitle><manvolnum>8</manvolnum></"
-"citerefentry> 會在錯誤的上游伺服器發現錯誤並跳一秒後,跟著把時間跳一秒。"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:49
-msgid ""
-"If <acronym>NTP</acronym> is not being used, manual adjustment of the system "
-"clock will be required after the leap second has passed."
-msgstr ""
-"如果未使用 <acronym>NTP</acronym> ,將需要在潤秒過後,手動調整系統時鐘。"
-
-#. (itstool) path: sect1/title
-#: article.translate.xml:55
-msgid "Cautions"
-msgstr "警告"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:57
-msgid ""
-"Leap seconds are inserted at the same instant all over the world: "
-"<acronym>UTC</acronym> midnight. In Japan that is mid-morning, in the "
-"Pacific mid-day, in the Americas late afternoon, and in Europe at night."
-msgstr ""
-"潤秒的插入在全世界是在同一個瞬間: <acronym>UTC</acronym> 午夜。在日本,是在"
-"上午九點,在太平洋,是正午,在美洲,是傍晚,在歐洲,是晚上。"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:62
-msgid ""
-"We believe and expect that FreeBSD, if provided correct and stable "
-"<acronym>NTP</acronym> service, will work as designed during this leap "
-"second, as it did during the previous ones."
-msgstr ""
-"我們相信和預期,如果提供正確和穩定的<acronym>NTP</acronym> 服務,FreeBSD會如"
-"設計地在這次潤秒正確運作,就像在之前遇到潤秒時一樣。"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:67
-msgid ""
-"However, we caution that practically no applications have ever asked the "
-"kernel about leap seconds. Our experience is that, as designed, leap seconds "
-"are essentially a replay of the second before the leap second, and this is a "
-"surprise to most application programmers."
-msgstr ""
-"然而我們要警告,實務上沒有應用程式曾經要求核心關於潤秒的事。我們的經驗是,如"
-"同設計,潤秒本質上是潤秒前一秒的重播,這對大部份應用程式設計師來說是意想不到"
-"的事。"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:73
-msgid ""
-"Other operating systems and other computers may or may not handle the leap-"
-"second the same way as FreeBSD, and systems without correct and stable "
-"<acronym>NTP</acronym> service will not know anything about leap seconds at "
-"all."
-msgstr ""
-"其他作業系統或電腦可能會或可能不會像FreeBSD用同樣方法處理潤秒,沒有正確和穩定"
-"<acronym>NTP</acronym> 服務的系統一點也不會知道潤秒的發生。"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:78
-msgid ""
-"It is not unheard of for computers to crash because of leap seconds, and "
-"experience has shown that a large fraction of all public <acronym>NTP</"
-"acronym> servers might handle and announce the leap second incorrectly."
-msgstr ""
-"電腦因為潤秒而當機並不是沒有聽聞,經驗上也顯示,有大量公用的<acronym>NTP</"
-"acronym> 伺服器沒有正確地處理和公告潤秒。"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:83
-msgid ""
-"Please try to make sure nothing horrible happens because of the leap second."
-msgstr "請試著確定不會因為潤秒而發生任何可怕的事情。"
-
-#. (itstool) path: sect1/title
-#: article.translate.xml:88
-msgid "Testing"
-msgstr "測試"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:90
-msgid ""
-"It is possible to test whether a leap second will be used. Due to the nature "
-"of <acronym>NTP</acronym>, the test might work up to 24 hours before the "
-"leap second. Some major reference clock sources only announce leap seconds "
-"one hour ahead of the event. Query the <acronym>NTP</acronym> daemon:"
-msgstr ""
-"測試是否有使用潤秒是有可能的。由於 <acronym>NTP</acronym>的性質,測試可能要運"
-"作到潤秒前24小時。有些主要的參考時鐘來源只在潤秒前一個小時公告。詢問"
-"<acronym>NTP</acronym>行程:"
-
-#. (itstool) path: sect1/screen
-#: article.translate.xml:96
-#, no-wrap
-msgid "<prompt>%</prompt> <userinput>ntpq -c 'rv 0 leap'</userinput>"
-msgstr "<prompt>%</prompt> <userinput>ntpq -c 'rv 0 leap'</userinput>"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:98
-msgid ""
-"Output that includes <literal>leap_add_sec</literal> indicates proper "
-"support of the leap second. Before the 24 hours leading up to the leap "
-"second, or after the leap second has passed, <literal>leap_none</literal> "
-"will be shown."
-msgstr ""
-"包含<literal>leap_add_sec</literal> 的輸出指出對於潤秒的支援。潤秒前24小時,"
-"或是潤秒已經過了,會顯示<literal>leap_none</literal>。"
-
-#. (itstool) path: sect1/title
-#: article.translate.xml:105
-msgid "Conclusion"
-msgstr "結論"
-
-#. (itstool) path: sect1/para
-#: article.translate.xml:107
-msgid ""
-"In practice, leap seconds are usually not a problem on FreeBSD. We hope that "
-"this overview helps clarify what to expect and how to make the leap second "
-"event proceed more smoothly."
-msgstr ""
-"實務上,FreeBSD 的潤秒通常不是個問題。我們希望這篇概述能幫助釐清預期會遇到什"
-"麼狀況,如何使潤秒事件進行的更順利。"
diff --git a/zh_TW.UTF-8/articles/mailing-list-faq/Makefile b/zh_TW.UTF-8/articles/mailing-list-faq/Makefile
deleted file mode 100644
index 53a873470a..0000000000
--- a/zh_TW.UTF-8/articles/mailing-list-faq/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# $FreeBSD$
-#
-# Article: Frequently Asked Questions About The FreeBSD Mailing Lists
-
-DOC?= article
-
-FORMATS?= html
-
-INSTALL_COMPRESSED?=gz
-INSTALL_ONLY_COMPRESSED?=
-
-WITH_ARTICLE_TOC?=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= article.xml
-
-URL_RELPREFIX?= ../../../..
-DOC_PREFIX?= ${.CURDIR}/../../..
-
-.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/articles/mailing-list-faq/article.xml b/zh_TW.UTF-8/articles/mailing-list-faq/article.xml
deleted file mode 100644
index d85000e6e7..0000000000
--- a/zh_TW.UTF-8/articles/mailing-list-faq/article.xml
+++ /dev/null
@@ -1,416 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
- "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd">
-<!-- $FreeBSD$ -->
-<!-- The FreeBSD Documentation Project -->
-<!-- FreeBSD Mailing Lists 常見問答集 -->
-<!-- Translate into Chinese by chinsan.tw@gmail.com -->
-<!-- English Version: 1.7 -->
-<article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="zh_tw">
- <info><title>&os; Mailing Lists 常見問答集</title>
-
-
- <authorgroup>
- <author><personname><surname>The &os; Documentation Project</surname></personname></author>
- </authorgroup>
-
- <copyright>
- <year>2004</year>
- <year>2005</year>
- <year>2006</year>
- <holder>&os; 文件計畫</holder>
- </copyright>
-
- <pubdate>$FreeBSD$</pubdate>
-
- <releaseinfo>$FreeBSD$</releaseinfo>
-
- <abstract>
- <para>這是有關 &os; mailing lists 的 FAQ。如果您對協助本文件/翻譯計畫
- 的進行有興趣的話,請寄 e-mail 到
- &a.doc;。此外,隨時可從 <link xlink:href="http://www.FreeBSD.org/doc/en_US.ISO8859-1/articles/mailing-list-faq/index.html">
- FreeBSD 網站</link> 拿到這份文件的最新版本。
- 也可以利用 HTTP 來下載 <link xlink:href="article.html">HTML</link>
- 文件,或是經由 <link xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/">
- FreeBSD FTP 站</link> 下載純文字、&postscript;、或 PDF 版本的檔案。
- 您也可以在這裡使用
- <link xlink:href="&url.base;/search/search.html">搜尋 FAQ 資料</link>
- 的功能。</para>
- </abstract>
- </info>
-
- <sect1 xml:id="introduction">
- <title>前言</title>
-
- <para>如同其他 FAQs 一樣,本文主要目的是希望涵蓋在 &os; mailing
- lists 上面的常見問題(當然,包括答案)。
- 雖然,原本構想是希望能降低這些重複問題的網路流量,但如今已被公認 FAQs 也是相當好用的資源之一。</para>
-
- <para>本文主要是描述社群之間所培養的一些禮儀(或默契),但本文本身並非『聖旨』般的權威。
- 若發現本文內有任何技術瑕疵,或者是想建議可以增加哪些部分的話,請送 PR,或是 email 到 &a.doc;。謝囉!</para>
-
- <qandaset>
- <qandaentry>
- <question xml:id="purpose">
- <para>&os; mailing lists 的目的為何?</para>
- </question>
-
- <answer>
- <para>&os; mailing lists 主要是提供 &os; 社群間的溝通管道,這裡有各式專題領域的探討,以及興趣交流。</para>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question xml:id="audience">
- <para>&os; mailing lists 的參與者有哪些?</para>
- </question>
-
- <answer>
- <para>這個問題,要看各個 list 的『版規(charter)』定位而有所不同。有些 lists 主要是 developers 在參與討論的;
- 而有些則主要是幾乎整體 &os; 社群都可以隨意參與討論的。請看 <link xlink:href="http://lists.FreeBSD.org/mailman/listinfo">這份清單</link> 上面有目前所有 list 的摘要說明。</para>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question xml:id="participation-who">
- <para>&os; mailing lists 對任何人都是開放參與的嗎?</para>
- </question>
-
- <answer>
- <para>再重複一次,這要看各個 list 的『版規(charter)』定位而有所不同。
- 請在發文前,先注意閱讀該 list 的『版規(charter)』,並遵守相關原則。
- 如此一來,才會讓大家都能溝通更無礙。</para>
-
- <para>如果看了上一個問答內的清單之後,還是不清楚要到哪個 list 去發問的話,
- 那麼可以試著把問題丟到 freebsd-questions 看看(但請先看下面講的補充)。</para>
-
- <para>請注意:習慣上所有 mailing lists 都是開放發表討論的,也不必得先成為訂閱會員才行。
- 這是相當審慎的選擇,來讓參與 &os; 社群更輕鬆容易,並鼓勵互相分享彼此的想法。
- 然而,由於過去有些人的濫用,有些 lists 現在開始限制參與討論的部分,以避免不必要的困擾。</para>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question xml:id="subscribe">
- <para>要怎麼訂閱呢?</para>
- </question>
-
- <answer>
- <para>可以用 <link xlink:href="http://lists.FreeBSD.org/mailman/listinfo">
- Mailman 網頁介面</link> 來訂閱任何公開的 lists。</para>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question xml:id="unsubscribe">
- <para>要怎麼退訂?</para>
- </question>
-
- <answer>
- <para>一樣請用剛上面說的網頁介面,或者 mailing list 上面每封信結尾處都會有相關 URL 連結的指示說明。</para>
-
- <para>千萬請不要直接寫信到這些公開的 mailing lists 說你要退訂。
- 首先呢..因為本來就不是這樣退訂的,其次你會惹來眾怒而招來圍剿、筆戰。
- 這是很典型的退訂錯誤示範,請不要這樣做。</para>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question xml:id="archives">
- <para>可以找到舊信的資料庫嗎?</para>
- </question>
-
- <answer>
- <para>嗯,有!可以在 <link xlink:href="http://docs.FreeBSD.org/mail/">這邊</link>
- 找到相關的舊信資料庫(archive)。</para>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question xml:id="digest">
- <para>mailing lists 可有摘要版呢?</para>
- </question>
-
- <answer>
- <para>當然也有,請看 <link xlink:href="http://lists.FreeBSD.org/mailman/listinfo">
- Mailman 網頁介面</link>。</para>
- </answer>
- </qandaentry>
- </qandaset>
- </sect1>
-
- <sect1 xml:id="etiquette">
- <title>Mailing List 的參與禮儀</title>
-
- <para>在 mailing lists 上參與討論,就像在其他社群一樣,我們都需要一些溝通上的共識。
- 發言請注重禮儀(或默契),切勿無的放矢。</para>
-
- <qandaset>
- <qandaentry>
- <question xml:id="before-posting">
- <para>在發文之前,有什麼注意事項呢?</para>
- </question>
-
- <answer>
- <para>最重要的是你已經看了這篇文章,然而,若您對 &os; 不熟的話,
- 可能需要先廣泛閱讀
- <link xlink:href="&url.base;/docs/books.html">相關書籍及文章</link>
- 來先熟悉這套作業系統和一些典故,尤其是其中的 <link xlink:href="&url.books.faq;/index.html">
- &os; 常見問答集 (FAQ)</link> 文件,
- <link xlink:href="&url.books.handbook;/index.html">
- &os; 使用手冊(Handbook)</link>,
- 以及相關文章:<link xlink:href="&url.articles.freebsd-questions;/article.html">
- How to get best results from the FreeBSD-questions mailing list</link>、
- <link xlink:href="&url.articles.explaining-bsd;/article.html">
- Explaining BSD</link>、以及 <link xlink:href="&url.articles.new-users;/article.html">
- &os; First Steps</link>。</para>
-
- <para>此外,對上述文件內已有解答的部份又提出來問的話,會被認為是相當不禮貌的。
- 這並不是因為這群志工是相當吝於回答的,而是一再被相同的問題不斷疲勞轟炸之後,所產生的挫折感很重。
- 尤其是現成答案明明就在眼前,卻仍同樣問題滿天飛,這實在是...。
- 請注意:這些 &os; 相關文件幾乎都是由一群無薪志工的好心成果,而他們也是人。</para>
- </answer>
-
- </qandaentry>
-
- <qandaentry>
- <question xml:id="inappropriate">
- <para>如何避免不當發文呢?</para>
- </question>
-
- <answer>
- <itemizedlist>
- <listitem>
- <para>發文時,請務必遵守該 mailing list 的遊戲規則。</para>
- </listitem>
-
- <listitem>
- <para>不要作人身攻擊。好的網路公民,應該要有更高的言行標準。</para>
- </listitem>
-
- <listitem>
- <para>請不要試圖作 Spam 行為(廣告、轉貼多處等不請自來行為)。
- 所有 mailing lists 都會積極禁止這些違規者,一旦有的話,那麼後果請自行負責。</para>
- </listitem>
- </itemizedlist>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question xml:id="etiquette-posting">
- <para>發文時,有什麼該注意的嗎?</para>
- </question>
-
- <answer>
- <itemizedlist>
- <listitem>
- <para>發文時,請保持一行約 75 個字元就自動斷行,因為並不是每個看的人都有很炫的圖形介面(GUI)看信軟體。</para>
- </listitem>
-
- <listitem>
- <para>請注意:事實上,網路頻寬並不是無限的。
- 並非每個讀者的頻寬都很大,所以若想貼一些像是 <filename>config.log</filename>
- 之類的設定檔內容,或是大量的 stack trace 紀錄,那麼請把它放在自己網站上,然後貼出該網址 URL 就行了。
- 還有一件事,請記住,這些信件都會被舊信資料庫保存下來,所以這樣作會造成保存的資料庫會很快被塞到很大,
- 甚至可能塞爆 Server 的硬碟空間。</para>
- </listitem>
-
- <listitem>
- <para>文章是要讓人看得懂,所以請注意版面編排的可讀性,還有..
- 千 萬 不 要 大 聲 嚷 叫!!!!! 這點可不只 &os; mailing lists 才需如此注意,
- 請勿低估文章『基本編排』的重要性、連鎖效應。
- 信中的表達方式通常就代表著別人眼中的你,若文章讓人看了很吃力(霧煞煞)、拼字錯誤百出、
- 充滿語意或邏輯錯誤、或是文內充滿一堆驚嘆號,這會讓人對你印象觀感極差。</para>
- </listitem>
-
- <listitem>
- <para>在一些特定的 list 場合,請用適當的語言來溝通。許多非英語系的mailing
- lists 可以到
- <link xlink:href="&url.base;/community/mailinglists.html">
- 這邊</link> 查看看。</para>
-
- <para>對於許多母語不是英語的人,我們都能諒解他們的苦楚,並且試著儘量多多包涵。
- 英文非母語的人,我們會儘量不惡意批評拼字或文法錯誤之處。
- &os; 在這方面,一直有相當優秀的紀錄,請讓我們繼續保持這傳統吧。</para>
- </listitem>
-
- <listitem>
- <para>寫信時,請用相容標準的 Mail User Agent (MUA)程式。
- <link xlink:href="http://www.lemis.com/email.html">不良的(或設定錯誤的)寄信程式</link>
- 這裡列有許多信件格式的錯誤示範。以下是一些已知的寄信程式的不良示範:</para>
-
- <itemizedlist>
- <listitem>
- <para>cc:Mail</para>
- </listitem>
-
- <listitem>
- <para>(舊版的)&eudora;</para>
- </listitem>
-
- <listitem>
- <para>exmh</para>
- </listitem>
-
- <listitem>
- <para>&microsoft; Exchange</para>
- </listitem>
-
- <listitem>
- <para>&microsoft; Internet Mail</para>
- </listitem>
-
- <listitem>
- <para>&microsoft; &outlook;</para>
- </listitem>
-
- <listitem>
- <para>(舊版的)&netscape;</para>
- </listitem>
- </itemizedlist>
-
- <para>如同上述所見,Microsoft 出的一堆寄信程式通常都是不相容標準格式的。
- 請儘量改用 &unix; 上的寄信程式。若必須在 Microsoft 環境下使用寄信程式的話,
- 請記得確認設定是否正確。請儘量不要用 <acronym>MIME</acronym> 格式:
- 因為有一堆人都在濫用 <acronym>MIME</acronym> 信件格式。</para>
- </listitem>
-
- <listitem>
- <para>請確認:時間與時區設定是否正確。
- 這問題看起來有點蠢,因為你寄出的信還是會到達 mailing list 上,
- 但是呢,每位 mailing lists 上的訂戶每天都會看數百封的信,
- 他們通常會把信件以標題跟時間作為排序依據。
- 若你的信沒有在第一篇正解之前就先出現的話,他們就會假設可能是漏收你這封信,
- 然後就沒再去看你那封信了。</para>
- </listitem>
-
- <listitem>
- <para>請提供程式出現的相關訊息,像是 &man.dmesg.8; 或者 console
- messages 也就是通常會出現在 <filename>/var/log/messages</filename> 出現的。
- 請不要用手打,因為這不僅很苦,而且也可能打錯字或亂掉原有格式。請直接把相關的 log 檔丟出來,
- 或是用編輯器來剪裁、或是用滑鼠複製/貼上來完成。舉個例子,如果是要把像是 <command>dmesg</command>
- 的程式訊息倒入到某個檔案去的話,那麼作法如下:</para>
-
- <screen>&prompt.user; <userinput>dmesg &gt; /tmp/dmesg.out</userinput></screen>
-
- <para>這樣子會把訊息送到 <filename>/tmp/dmesg.out</filename> 檔內。</para>
- </listitem>
-
- <listitem>
- <para>在用滑鼠剪貼時,請注意是否有犯一些細節的剪貼壞習慣。
- 尤其是像貼 <filename>Makefiles</filename> 之類檔案時,由於 <literal>tab</literal>
- 鍵所打出來的分格,是屬於特殊字元。因此,在 <link xlink:href="&url.base;/support.html#gnats">
- GNATS PR 資料庫</link> 上很常看到這類很常見的惱人問題:
- <filename>Makefiles</filename> 內的 tab 經過剪貼後,變成『空白(white space)』
- 或是困擾的 <literal>=3B</literal> escape sequence,這些會讓 committers 們十分不爽。</para>
- </listitem>
- </itemizedlist>
- </answer>
- </qandaentry>
-
- <qandaentry>
- <question xml:id="etiquette-replying">
- <para>在 mailing lists 上回文的話,有什麼要特別注意的嗎?</para>
- </question>
-
- <answer>
- <itemizedlist>
- <listitem>
- <para>請適當調整文章引言長度。回文時,引言部份請引『有談到的』部分為主,但請不要過與不及。
- 應該保留涉及討論範圍的原文,這樣子才能讓沒看過前面文章的人知道是在講什麼,而非一頭霧水。</para>
-
- <para>還有一點也很重要,原文若是幅度相當長的話,記得註明 "yes, I see this too"。</para>
- </listitem>
-
- <listitem>
- <para>善用技巧來確認原文與自己寫的部份:
- 通常會在原文的每行前面加上 <quote><literal>&gt; </literal></quote> 以作記號。
- 請記得保留 <quote><literal>&gt; </literal></quote> 符號後面的空白,並且在原文以及你所寫的段落之間加上空行,
- 以便閱讀。</para>
- </listitem>
-
- <listitem>
- <para>請不要斷章取義、穿鑿附會:通常對原始文章『斷章取義』、『穿鑿附會』會讓大家很不爽,因為他們原意並非如此,卻被曲解。</para>
- </listitem>
-
- <listitem>
- <para>回文時,不要寫在原文上面(<literal>top post</literal>)。
- 這個意思是:若要回文時,請寫在原文下方,不要寫在原文上面,以免讓人有時空錯置的錯亂混淆。</para>
- <!-- 注意:下面這是故意幽默效果的問答 -->
- <itemizedlist>
- <listitem>
- <para>答: Because it reverses the logical flow of
- conversation.</para>
- </listitem>
- <listitem>
- <para>問: Why is top posting frowned upon?</para>
- </listitem>
- </itemizedlist>
- <para>(感謝 Randy Bush 提供笑話)</para>
- </listitem>
- </itemizedlist>
- </answer>
- </qandaentry>
- </qandaset>
- </sect1>
-
- <sect1 xml:id="recurring">
- <title>Mailing Lists 上的重複性問題</title>
-
- <para>在 mailing lists 上參與討論,就像在其他社群一樣,我們都需要一些溝通上的共識。
- 許多 mailing lists 都會假設參與討論者都大致知道 FreeBSD 計劃的一些歷史淵源。
- 尤其是社群的新手總是定期會不斷重複問類似問題。
- 每個發文的人,都有責任來避免掉入這樣的惡性循環輪迴內。
- 因此,應儘可能讓 mailing list 上能正常討論,而避免讓自己陷入筆戰泥沼。</para>
-
- <para>要怎麼避免呢?最好的方法就是善用這些 <link xlink:href="http://docs.FreeBSD.org/mail/">
- mailing list 舊信資料庫(archives)</link>,來瞭解相關背景。
- 正由於這原因,所以 <link xlink:href="http://www.FreeBSD.org/search/search.html#mailinglists">
- mailing list 搜尋介面</link> 就顯得非常好用。
- (若這方法仍無法找到有用的答案,那麼請改用自己愛用的搜尋引擎吧)</para>
-
- <para>透過這些舊信資料庫,不只可瞭解先前討論過哪些話題,也可以知道:是怎麼討論的、
- 哪些人參與討論過、主要看的人又是哪些人。
- 入境隨俗這些原則不只是 &os; mailing list 上才這樣,一樣可以適合其他地方。</para>
-
- <para>archives 的內容無疑地相當廣泛,而且會有些問題不斷反覆出現,
- 有時討論到後面總會離題。無論如何,在發問前的義務就是先做好功課,
- 以避免這類的月經文惡性循環,尤其是令人反感的 <literal>bikeshed(打嘴砲)</literal>。</para>
- </sect1>
-
- <sect1 xml:id="bikeshed">
- <title>什麼是 "Bikeshed" 呀?</title>
- <para>單就字面上意思解釋的話,<literal>bikeshed</literal> 是指專門給腳踏車、機車之類的兩輪交通工具使用的遮雨棚,
- 然而呢,在 &os; 這邊的說法卻有其他意思(帶有貶抑)指的是:
- 某些特定話題的重複討論,尤其是指在 &os; 社群內絕不會有共識,且有爭議的話題。
- (這字彙的起源在 <link xlink:href="&url.books.faq;/misc.html#BIKESHED-PAINTING">
- 這份文件</link> 內有更多說明)。你只要在發信到任一 &os; mailing lists 之前,知道這個基本概念就行了。</para>
-
- <para>一般來講,『bikeshed』是很容易產生許多波的筆戰與額外討論的爭議話題,如果事先不知道這些背景的話。</para>
-
- <para>拜託,請幫個忙讓討論回歸正常,而不要只是到處打嘴砲而已。感恩!</para>
- </sect1>
-
- <sect1 xml:id="acknowledgments">
- <title>致謝</title>
-
- <variablelist>
- <varlistentry>
- <term>&a.grog;</term>
- <listitem>
- <para><link xlink:href="&url.articles.freebsd-questions;/article.html">
- How to get best results from the FreeBSD-questions mailing list</link> 一文的原作者,
- 我們從他這文內獲得許多 mailing list 上的禮儀(或默契)寫作題材。</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>&a.linimon;</term>
- <listitem>
- <para>本 FAQ 雛形的原作</para>
- </listitem>
- </varlistentry>
- </variablelist>
- </sect1>
-
-</article>
diff --git a/zh_TW.UTF-8/articles/nanobsd/Makefile b/zh_TW.UTF-8/articles/nanobsd/Makefile
deleted file mode 100644
index 38de994f6c..0000000000
--- a/zh_TW.UTF-8/articles/nanobsd/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# The FreeBSD Traditional Chinese Project
-#
-# Original Revision: 1.2
-# $FreeBSD$
-#
-# Article: Introduction to NanoBSD
-
-DOC?= article
-
-FORMATS?= html
-WITH_ARTICLE_TOC?= YES
-
-INSTALL_COMPRESSED?= gz
-INSTALL_ONLY_COMPRESSED?=
-
-# 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
-
-SRCS= article.xml
-
-URL_RELPREFIX?= ../../../..
-DOC_PREFIX?= ${.CURDIR}/../../..
-
-.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/articles/nanobsd/article.xml b/zh_TW.UTF-8/articles/nanobsd/article.xml
deleted file mode 100644
index 44702eb5df..0000000000
--- a/zh_TW.UTF-8/articles/nanobsd/article.xml
+++ /dev/null
@@ -1,434 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
- "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd">
-<!--
- The FreeBSD Documentation Project
- The FreeBSD Chinese (Traditional) Documentation Project
-
- Original Revision: 1.1
--->
-<article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="zh_tw">
- <info><title>NanoBSD 簡介</title>
-
-
- <authorgroup>
- <author><personname><firstname>Daniel</firstname><surname>Gerzo</surname></personname></author>
- </authorgroup>
-
- <copyright>
- <year>2006</year>
- <holder>The FreeBSD Documentation Project</holder>
- </copyright>
-
- <pubdate>$FreeBSD$</pubdate>
-
- <releaseinfo>$FreeBSD$</releaseinfo>
-
- <legalnotice xml:id="trademarks" role="trademarks">
- &tm-attrib.freebsd;
- &tm-attrib.general;
- </legalnotice>
-
- <abstract>
- <para>這篇文件提供了關於 <application>NanoBSD</application> 工具的情報介紹,
- 這工具可用來建立用於嵌入式環境應用程式的 &os; 系統映像檔,
- 以便存放到 Compact Flash 卡(或隨身碟)。</para>
- </abstract>
- </info>
-
- <sect1 xml:id="intro">
- <title>NanoBSD 簡介</title>
-
- <indexterm><primary>NanoBSD</primary></indexterm>
-
- <para><application>NanoBSD</application> 是 &a.phk; 目前正在開發的一項工具。
- 它可用來建立用於嵌入式環境應用程式的 &os; 系統映像檔,
- 以便存放到 Compact Flash 卡(或隨身碟,mass storage medium)。</para>
-
- <para>這一工具也可以用來自製安裝映像檔,
- 以簡化俗稱為 <quote>嵌入式系統(computer appliances)</quote> 的系統安裝、維護工作。
- 通常,每個嵌入式系統產品都有限定硬體和軟體,
- 或者換言之,所有的應用程式都是預先裝好的。
- 這些設備可以直接放到現有的網路中,而且(幾乎是)立即使用。</para>
-
- <para><application>NanoBSD</application> 提供的功能包括:</para>
-
- <itemizedlist>
- <listitem>
- <para>可以和 &os; 一樣使用 Ports 和 Packages &mdash;
- 所有的應用程序都可以在 <application>NanoBSD</application> 中直接使用,
- 而方式與 &os; 完全一樣。</para>
- </listitem>
-
- <listitem>
- <para>功能絲毫未損 &mdash; 在 &os; 做的任何工作,都可以在
- <application>NanoBSD</application> 中使用,
- 除非您在建立 <application>NanoBSD</application> 映像檔時,
- 有指定要拿掉它們。</para>
- </listitem>
-
- <listitem>
- <para>所有東西在運行時都是唯讀的 &mdash; 可以安全地拔掉電源插頭。
- 系統不正常關機的話,不用再跑 &man.fsck.8; 了。</para>
- </listitem>
-
- <listitem>
- <para>可輕鬆編譯、自行打造 &mdash; 只需使用一個 shell script 和一個設定檔,
- 您可以輕鬆依需求來量身訂做適用的映像檔。</para>
- </listitem>
- </itemizedlist>
- </sect1>
-
- <sect1 xml:id="howto">
- <title>如何使用 NanoBSD</title>
-
- <sect2 xml:id="design">
- <title>NanoBSD 的設計</title>
-
- <para>一旦將映像檔存入嵌入式硬體,就可以用它來引導 <application>NanoBSD</application>
- 了。 預設情況下,隨身碟會劃分為三部分:</para>
-
- <itemizedlist>
- <listitem>
- <para>兩個映像檔分割區: <literal>code#1</literal>
- 和 <literal>code#2</literal>。</para>
- </listitem>
-
- <listitem>
- <para>一個設定檔分割區,在運行環境中,
- 可以將其掛載(mount)到 <filename>/cfg</filename> 目錄下。</para>
- </listitem>
- </itemizedlist>
-
- <para>這些分割區,在預設情況下是以唯讀方式掛載。</para>
-
- <para><filename>/etc</filename> 和
- <filename>/var</filename> 目錄均為
- &man.md.4;(malloc)磁碟。</para>
-
- <para>設定檔的分割區則是在
- <filename>/cfg</filename> 目錄。
- 它包含了用於 <filename>/etc</filename>
- 目錄的檔案,在啟動之後暫時以唯讀方式掛載。 因此,若想要重開機保留新的設定,
- 那麼要記得從 <filename>/etc</filename> 把改過的檔案複製回
- <filename>/cfg</filename> 目錄才行。</para>
-
- <example>
- <title>把修改過 <filename>/etc/resolv.conf</filename> 設定保存起來</title>
-
- <screen>&prompt.root; <userinput>vi /etc/resolv.conf</userinput>
-[...]
-&prompt.root; <userinput>mount /cfg</userinput>
-&prompt.root; <userinput>cp /etc/resolv.conf /cfg</userinput>
-&prompt.root; <userinput>umount /cfg</userinput></screen>
- </example>
-
- <note>
- <para>只有在系統啟動過程中,以及需要修改設定檔的時候,才需要掛載含有
- <filename>/cfg</filename> 的那個分割區。</para>
-
- <para>一直都掛載 <filename>/cfg</filename>
- 不是一個好主意,特別是當您把 <application>NanoBSD</application>
- 放在不適合進行大量寫入動作的分割區時
- (比如:由於檔案系統的同步化會定期在系統碟內寫入資料)。</para>
- </note>
- </sect2>
-
- <sect2>
- <title>打造 NanoBSD 映像檔</title>
-
- <para><application>NanoBSD</application> 映像檔是透過使用非常簡單的
- <filename>nanobsd.sh</filename> shell script 來打造的,這個 script 可以在
- <filename>/usr/src/tools/tools/nanobsd</filename>
- 目錄中找到。 這個 script 建立的映像檔,可以用 &man.dd.1; 工具來複製到隨身碟上。</para>
-
- <para>打造
- <application>NanoBSD</application> 映像檔所需的指令是:</para>
-
- <screen>&prompt.root; <userinput>cd /usr/src/tools/tools/nanobsd</userinput> <co xml:id="nbsd-cd"/>
-&prompt.root; <userinput>sh nanobsd.sh</userinput> <co xml:id="nbsd-sh"/>
-&prompt.root; <userinput>cd /usr/obj/nanobsd.full</userinput> <co xml:id="nbsd-cd2"/>
-&prompt.root; <userinput>dd if=_.disk.full of=/dev/da0 bs=64k</userinput> <co xml:id="nbsd-dd"/></screen>
-
- <calloutlist>
- <callout arearefs="nbsd-cd">
- <para>進入 <application>NanoBSD</application> 打造 script 的主目錄。</para>
- </callout>
-
- <callout arearefs="nbsd-sh">
- <para>開始打造過程。</para>
- </callout>
-
- <callout arearefs="nbsd-cd2">
- <para>進入打造好的映像檔所在的目錄。</para>
- </callout>
-
- <callout arearefs="nbsd-dd">
- <para>在隨身碟上安裝 <application>NanoBSD</application>。</para>
- </callout>
- </calloutlist>
- </sect2>
-
- <sect2>
- <title>自行打造 NanoBSD 映像檔</title>
-
- <para>這可能是 <application>NanoBSD</application> 最為重要,
- 同時也是您最感興趣的功能。 同時,在開發
- <application>NanoBSD</application> 應用程式時,這也是相當耗時的過程。</para>
-
- <para>執行下面的指令將會
- <filename>nanobsd.sh</filename> 讀取目前所在目錄的
- <filename>myconf.nano</filename> 檔的設定:</para>
-
- <screen>&prompt.root; <userinput>sh nanobsd.sh -c myconf.nano</userinput></screen>
-
- <para>自行打造的流程,只需兩個步驟:</para>
-
- <itemizedlist>
- <listitem>
- <para>自訂選項</para>
- </listitem>
-
- <listitem>
- <para>自訂功能</para>
- </listitem>
- </itemizedlist>
-
- <sect3>
- <title>自訂選項</title>
-
- <para>透過修改設定,可以設定用於
- <application>NanoBSD</application> 打造過程中 <literal>buildworld</literal>
- 和 <literal>installworld</literal> 階段的編譯、安裝選項,以及
- <application>NanoBSD</application> 主要打造過程中的選項。
- 透過使用這些選項可以削減系統的尺寸,使之能夠放入
- 64 MB 的隨身碟。 您還可以進一步透過這些選項來削減 &os;,
- 直到它只包含 kernel 以及兩三個 userland 檔案為止。</para>
-
- <para>設定檔案中包含用以代替預設值的設定選項。簡介最重要的幾項設定如下:</para>
-
- <itemizedlist>
- <listitem>
- <para><literal>NANO_NAME</literal> &mdash; 本次打造的名稱(所建立工作目錄的名稱)。</para>
- </listitem>
-
- <listitem>
- <para><literal>NANO_SRC</literal> &mdash; 用以編譯、打造映像檔的 source tree 的位置。</para>
- </listitem>
-
- <listitem>
- <para><literal>NANO_KERNEL</literal> &mdash; 設定用來編譯的 kernel 設定檔檔名。</para>
- </listitem>
-
- <listitem>
- <para><literal>CONF_BUILD</literal> &mdash; 用於
- <literal>buildworld</literal> 打造階段的選項。</para>
- </listitem>
-
- <listitem>
- <para><literal>CONF_INSTALL</literal> &mdash; 用於
- <literal>installworld</literal> 打造階段的選項。</para>
- </listitem>
-
- <listitem>
- <para><literal>CONF_WORLD</literal> &mdash; 用於
- <literal>buildworld</literal> 和
- <literal>installworld</literal> 這兩個打造階段的選項。</para>
- </listitem>
-
- <listitem>
- <para><literal>FlashDevice</literal> &mdash; 定義所用的嵌入式硬體類型。
- 詳情請參考 <filename>FlashDevice.sub</filename> 檔。</para>
- </listitem>
- </itemizedlist>
- </sect3>
-
- <sect3>
- <title>自訂功能</title>
-
- <para>透過在設定檔案中使用 shell 函數,可以進一步微調
- <application>NanoBSD</application>。 舉例說明一下自行打造函數的基本方式:</para>
-
- <programlisting>cust_foo()(
- echo "bar=topless" &gt; \
- &dollar;{NANO_WORLDDIR}/etc/foo
-)
-customize_cmd cust_foo</programlisting>
-
- <para>下面舉更實際點的例子,它會把預設的
- <filename>/etc</filename> 目錄大小,從 5MB 調整為 30MB:</para>
-
- <programlisting>cust_etc_size()(
- cd &dollar;{NANO_WORLDDIR}/conf
- echo 30000 &gt; default/etc/md_size
-)
-customize_cmd cust_etc_size</programlisting>
-
- <para>除此之外,還有幾個預設的功能定義可以用來自訂:</para>
-
- <itemizedlist>
- <listitem>
- <para><literal>cust_comconsole</literal> &mdash; 在預設 VGA 顯示卡上停用 &man.getty.8;
- (<filename>/dev/ttyv*</filename>)並啟用 serial port 的 COM1 以作為系統 console。</para>
- </listitem>
-
- <listitem>
- <para><literal>cust_allow_ssh_root</literal> &mdash; 允許 &man.sshd.8;
- 可以用 <systemitem class="username">root</systemitem> 帳號登入。</para>
- </listitem>
-
- <listitem>
- <para><literal>cust_install_files</literal> &mdash;
- 從 <filename>nanobsd/Files</filename>
- 目錄中安裝檔案,這包含一些實用的系統管理 script 。</para>
- </listitem>
- </itemizedlist>
- </sect3>
-
- <sect3>
- <title>設定檔案舉例</title>
-
- <para>下面是用於自行打造的 <application>NanoBSD</application> 映像檔的完整例子:</para>
-
- <programlisting>NANO_NAME=custom
-NANO_SRC=/usr/src
-NANO_KERNEL=MYKERNEL
-NANO_IMAGES=2
-
-CONF_BUILD='
-NO_KLDLOAD=YES
-NO_NETGRAPH=YES
-NO_PAM=YES
-'
-
-CONF_INSTALL='
-NO_ACPI=YES
-NO_BLUETOOTH=YES
-NO_CVS=YES
-NO_FORTRAN=YES
-NO_HTML=YES
-NO_LPR=YES
-NO_MAN=YES
-NO_SENDMAIL=YES
-NO_SHAREDOCS=YES
-NO_EXAMPLES=YES
-NO_INSTALLLIB=YES
-NO_CALENDAR=YES
-NO_MISC=YES
-NO_SHARE=YES
-'
-
-CONF_WORLD='
-NO_BIND=YES
-NO_MODULES=YES
-NO_KERBEROS=YES
-NO_GAMES=YES
-NO_RESCUE=YES
-NO_LOCALES=YES
-NO_SYSCONS=YES
-NO_INFO=YES
-'
-
-FlashDevice SanDisk 1G
-
-cust_nobeastie()(
- touch &dollar;{NANO_WORLDDIR}/boot/loader.conf
- echo "beastie_disable=\"YES\"" &gt;&gt; &dollar;{NANO_WORLDDIR}/boot/loader.conf
-)
-
-customize_cmd cust_comconsole
-customize_cmd cust_install_files
-customize_cmd cust_allow_ssh_root
-customize_cmd cust_nobeastie</programlisting>
- </sect3>
- </sect2>
-
- <sect2>
- <title>更新 NanoBSD</title>
-
- <para>更新 <application>NanoBSD</application> 相對 &os; 而言較為簡單:</para>
-
- <procedure>
- <step>
- <para>和之前一樣打造新的 <application>NanoBSD</application> 映像檔。</para>
- </step>
-
- <step>
- <para>將新的映像檔放入正運行的
- <application>NanoBSD</application> 中未用的分割區之一。</para>
-
- <para>與之前最初安裝 <application>NanoBSD</application> 的步驟相比,
- 這一步驟最重要的區別在於:這次不用 <filename>_.disk.full</filename> 檔(它包含整個磁碟的映像檔),
- 而應安裝 <filename>_.disk.image</filename> 映像檔(這個檔案中,只包含一個系統分割區)。</para>
- </step>
-
- <step>
- <para>重新啟動,並從新安裝的分割區中啟動系統。</para>
- </step>
-
- <step>
- <para>如果一切順利的話,升級工作就完成了。</para>
- </step>
-
- <step>
- <para>如果發生了任何問題,則可以從先前的分割區啟動
- (其中包含了舊的、 可用的映像檔),來盡快恢復系統功能。
- 接下來可以修正新編譯的版本中存在的問題,並重複前述步驟。</para>
- </step>
- </procedure>
-
- <para>要在正在運行的
- <application>NanoBSD</application> 系統中安裝新的映像檔,可以使用位於
- <filename>/root</filename> 目錄的
- <filename>updatep1</filename> 或
- <filename>updatep2</filename> script ,
- 實際上要用哪一個 script,則取決於正在運行的系統是位於哪個分割區而定。</para>
-
- <para>隨時提供新 <application>NanoBSD</application> 映像檔所提供的服務,
- 以及採用的傳輸方法的不同,您可以參考並使用下列三種方式之一:</para>
-
- <sect3>
- <title>使用 &man.ftp.1;</title>
-
- <para>如果傳輸速度是第一要求的話,請採用下面例子:</para>
-
- <screen>&prompt.root; <userinput>ftp myhost
-get _.disk.image "| sh updatep1"</userinput></screen>
- </sect3>
-
- <sect3>
- <title>使用 &man.ssh.1;</title>
-
- <para>如果想更安全的話,應參考下面例子:</para>
-
- <screen>&prompt.root; <userinput>ssh myhost cat _.disk.image.gz | zcat | sh updatep1</userinput></screen>
- </sect3>
-
- <sect3>
- <title>使用 &man.nc.1;</title>
-
- <para>如果遠程主機既不提供 &man.ftp.1; 服務,也不提供 &man.sshd.8; 服務的話:</para>
-
- <procedure>
- <step>
- <para>首先,在提供映像檔的主機上開啟 TCP listen,並讓它把映像檔傳給 client:</para>
-
- <screen>myhost&prompt.root; <userinput>nc -l 2222 &lt; _.disk.image</userinput></screen>
-
- <note>
- <para>請確認您所使用的 port 沒有被防火牆阻止來自
- <application>NanoBSD</application> client 的連線請求。</para>
- </note>
- </step>
- <step>
- <para>連到提供新映像檔服務的主機,並執行 <filename>updatep1</filename> 這支 script:</para>
-
- <screen>&prompt.root; <userinput>nc myhost 2222 | sh updatep1</userinput></screen>
- </step>
- </procedure>
- </sect3>
- </sect2>
- </sect1>
-
- <index/>
-</article>
diff --git a/zh_TW.UTF-8/articles/pr-guidelines/Makefile b/zh_TW.UTF-8/articles/pr-guidelines/Makefile
deleted file mode 100644
index 17e369ff2c..0000000000
--- a/zh_TW.UTF-8/articles/pr-guidelines/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# $FreeBSD$
-#
-# Article: Problem Report Handling Guidelines
-
-DOC?= article
-
-FORMATS?= html
-WITH_ARTICLE_TOC?= YES
-
-INSTALL_COMPRESSED?=gz
-INSTALL_ONLY_COMPRESSED?=
-
-SRCS= article.xml
-
-URL_RELPREFIX?= ../../../..
-DOC_PREFIX?= ${.CURDIR}/../../..
-
-.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/articles/pr-guidelines/article.xml b/zh_TW.UTF-8/articles/pr-guidelines/article.xml
deleted file mode 100644
index 9a2bebcc23..0000000000
--- a/zh_TW.UTF-8/articles/pr-guidelines/article.xml
+++ /dev/null
@@ -1,875 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
- "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd">
-<!-- $FreeBSD$ -->
-<!-- The FreeBSD Documentation Project -->
-<!-- Translate into Chinese by chinsan.tw@gmail.com -->
-<!-- English Version: 1.24 -->
-<!--
- 問題回報(PR)的處理原則
- The FreeBSD Project - http://www.FreeBSD.org
--->
-<article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="zh_tw">
- <!-- :START of Article Metadata -->
- <info><title>問題回報(PR)的處理原則</title>
-
-
- <pubdate>$FreeBSD$</pubdate>
-
- <legalnotice xml:id="trademarks" role="trademarks">
- &tm-attrib.freebsd;
- &tm-attrib.opengroup;
- &tm-attrib.general;
- </legalnotice>
-
- <abstract>
- <para>這篇文章主要在講:由 FreeBSD PR 維護小組所提出的一些 FreeBSD 問題回報(PR)
- 建議,希望大家在弄 PR 時都能遵守。</para>
- </abstract>
-
- <authorgroup>
- <author><personname><firstname>Dag-Erling</firstname><surname>Sm&oslash;rgrav</surname></personname></author>
-
- <author><personname><firstname>Hiten</firstname><surname>Pandya</surname></personname></author>
- </authorgroup>
-
- <releaseinfo>$FreeBSD$</releaseinfo>
- </info>
- <!-- :END of Article Metadata-->
-
- <section xml:id="intro">
- <title>前言</title>
-
- <para>GNATS 是 FReeBSD 計劃所採用的一套專門管理錯誤(回報bug) 系統。
- 由於對 FreeBSD 品質保證而言,是否能準確掌握各項錯誤回報與進度是十分重要的,
- 因此,如何正確有效使用 GNATS 也就必須注意。</para>
-
- <para>Access to GNATS is available to FreeBSD developers, as well as
- to the wider community. 為了讓 GNATS 資料庫使用上儘量一致,於是就產生了怎麼處理像是:followup(回文)、關閉PR等的參考原則。</para>
- </section>
-
- <section xml:id="pr-lifecycle">
- <title>問題回報(PR)的生命週期</title>
-
- <itemizedlist>
- <listitem>
- <para>首先,回報者(originator)以 &man.send-pr.1; 送出 PR,然後會收到一封確認信。</para>
- </listitem>
-
- <listitem>
- <para>然後,committer 們就會有人(假設叫做 Joe)發掘有興趣的 PR 並將該 PR 指派給自己來處理。
- 或者 bugbuster 會有人(假設叫做 Jane) 就會下決定:她覺得 Joe 比較適合處理,就將該 PR 指派(assign)給他</para>
- </listitem>
-
- <listitem>
- <para>Joe 會先與有問題的回報者作些意見交流(以確定這問題有進入 audit 追蹤流程內)
- 以及判斷問題點。
- 然後再確定問題點有寫入 audit 追蹤流程之後,然後把該 PR 狀態設為
- <quote>analyzed(已分析)</quote>。</para>
- </listitem>
-
- <listitem>
- <para>Joe 開始徹夜找出問題解法,然後將 patch 送到 follow-up(回文用),並請回報者協助測試是否正常。
- 然後,他就會將 PR 狀態設為 <quote>feedback</quote> 囉。</para>
- </listitem>
-
- <listitem>
- <para>如此重複 analyzed、feedback 幾趟之後,直到 Joe 與回報者雙方都相當滿意 patch 結果,
- 於是就會將 patch 給 commits 進入 <literal>-CURRENT</literal> (或者若 <literal>-CURRENT</literal>
- 上面沒這問題的話,就直接送到 <literal>-STABLE</literal>),在 commit log 內要把相關 PR 寫上去
- (同時回報者若有送完整或部分 patch 的話,就順便記載),然後,若沒什麼事的話,就開始準備 MFC 哩。
- (譯註:MFC意指 Merged From CURRENT ,也就是把 <literal>-CURRENT</literal> 上的東西併入 <literal>-STABLE</literal>。</para>
- </listitem>
-
- <listitem>
- <para>若該 patch 不需要 MFC 的話,Joe 就會關掉(close)該 PR 了。</para>
- </listitem>
-
- <listitem>
- <para>若該 patch 需要 MFC 的話,Joe 會把 PR 狀態改為 <quote>patched(已修正)</quote>,
- 直到已經 MFC 完畢,才會 close(關掉)。</para>
- </listitem>
- </itemizedlist>
-
- <note>
- <para>很多送出來的 PR 都很少附上問題的相關訊息,而有些則是相當複雜難搞,
- 或只是提到部分表面問題而已;
- 遇到這種情況時,是非常需要得到所有相關訊息以便解決問題。
- 若遇到這種無解的問題或再次發生的話,就必須要 re-open(重新開啟) 該 PR,以待解決。</para>
- </note>
- <note>
- <para>PR 上所附的 <quote>email address</quote> 可能因某些原因而無法收信時,遇到這種狀況,通常就是
- followup 該 PR ,並(在 followup 時)請回報者重新提供可正常收信的 email address。
- 當系統上的 mail 系統關閉或沒裝的時候,這通常是在使用 &man.send-pr.1; 的替代方案。</para>
- </note>
- </section>
-
- <section xml:id="pr-states">
- <title>問題回報(PR)的狀態</title>
-
- <para>若 PR 有任何變化的話,請務必記得更新 PR 的『狀態(state)』。
- 『狀態』應該要能正確反映該 PR 的目前進度才是。</para>
-
- <example>
- <title>以下是更改 PR 狀態的小例子:</title>
-
- <para>當有可以修正問題的 PR 出現,而相關負責的 developer(s)
- 也覺得這樣的修正可以接受,他們會 followup 該 PR,並將其狀態改為
- <quote>feedback</quote>。同時,回報者應重新評估最終的修正結果,並回應:所回報的錯誤是否已成功修正。</para>
- </example>
-
- <para>每份 PR 通常會有下面這幾種狀態之一:</para>
-
- <glosslist>
- <glossentry>
- <glossterm>open</glossterm>
- <glossdef>
- <para>PR 最初的狀態:這個問題被提出來,並在等待處理中。</para>
- </glossdef>
- </glossentry>
-
- <glossentry>
- <glossterm>analyzed</glossterm>
- <glossdef>
- <para>已經開始處理這問題,並且有找到疑似解決的方法。</para>
- </glossdef>
- </glossentry>
-
- <glossentry>
- <glossterm>feedback</glossterm>
- <glossdef>
- <para>需要回報者提供更詳細的相關資料,正如教學要因材施教,治病也要因人下藥,越多相關訊息,才能有最佳效果。</para>
- </glossdef>
- </glossentry>
-
- <glossentry>
- <glossterm>patched</glossterm>
- <glossdef>
- <para>已經送相關 patch 了,但仍因某些原因(MFC,或來自回報者的確認結果異常)因此尚未完畢。</para>
- </glossdef>
- </glossentry>
-
- <glossentry>
- <glossterm>suspended(暫緩)</glossterm>
- <glossdef>
- <para>因為沒附上相關訊息或參考資料,所以還沒辦法處理這問題。
- This is a prime candidate for
- somebody who is looking for a project to take on. If the
- problem cannot be solved at all, it will be closed, rather
- than suspended. The documentation project uses
- <quote>suspended</quote> for <quote>wish-list</quote>
- items that entail a significant amount of work which no one
- currently has time for.</para>
- </glossdef>
- </glossentry>
-
- <glossentry>
- <glossterm>closed</glossterm>
- <glossdef>
- <para>A problem report is closed when any changes have been
- integrated, documented, and tested, or when fixing the
- problem is abandoned.</para>
- </glossdef>
- </glossentry>
- </glosslist>
-
- <note>
- <para>The <quote>patched</quote> state is directly related to
- feedback, so you may go directly to <quote>closed</quote> state if
- the originator cannot test the patch, and it works in your own testing.</para>
- </note>
- </section>
-
- <section xml:id="pr-types">
- <title>問題回報(PR)的種類</title>
-
- <para>While handling problem reports, either as a developer who has
- direct access to the GNATS database or as a contributor who
- browses the database and submits followups with patches, comments,
- suggestions or change requests, you will come across several
- different types of PRs.</para>
-
- <itemizedlist>
- <listitem>
- <para><link linkend="pr-unassigned">PRs not yet assigned to anyone.</link></para>
- </listitem>
- <listitem>
- <para><link linkend="pr-assigned">PRs already assigned to someone.</link></para>
- </listitem>
- <listitem>
- <para><link linkend="pr-dups">重複的 PR</link></para>
- </listitem>
- <listitem>
- <para><link linkend="pr-stale">Stale PRs</link></para>
- </listitem>
- <listitem>
- <para><link linkend="pr-misfiled">Misfiled PRs</link></para>
- </listitem>
- </itemizedlist>
-
- <para>The following sections describe what each different type of
- PRs is used for, when a PR belongs to one of these types, and what
- treatment each different type receives.</para>
-
- <section xml:id="pr-unassigned">
- <title>Unassigned PRs</title>
-
- <para>When PRs arrive, they are initially assigned to a generic
- (placeholder) assignee. These are always prepended with
- <literal>freebsd-</literal>. The exact value for this default
- depends on the category; in most cases, it corresponds to a
- specific &os; mailing list. Here is the current list, with
- the most common ones listed first:</para>
-
- <table xml:id="default-assignees-common">
- <title>Default Assignees &mdash; most common</title>
- <tgroup cols="3">
- <thead>
- <row>
- <entry>Type</entry>
- <entry>Categories</entry>
- <entry>Default Assignee</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry>base system</entry>
- <entry>bin, conf, gnu, kern, misc</entry>
- <entry>freebsd-bugs</entry>
- </row>
-
- <row>
- <entry>architecture-specific</entry>
- <entry>alpha, i386, ia64, powerpc, sparc64</entry>
- <entry>freebsd-<replaceable>arch</replaceable></entry>
- </row>
-
- <row>
- <entry>ports collection</entry>
- <entry>ports</entry>
- <entry>freebsd-ports-bugs</entry>
- </row>
-
- <row>
- <entry>documentation shipped with the system</entry>
- <entry>docs</entry>
- <entry>freebsd-doc</entry>
- </row>
-
- <row>
- <entry>&os; web pages (not including docs)</entry>
- <entry>www</entry>
- <entry>freebsd-www</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <table xml:id="default-assignees-other">
- <title>Default Assignees &mdash; other</title>
- <tgroup cols="3">
- <thead>
- <row>
- <entry>Type</entry>
- <entry>Categories</entry>
- <entry>Default Assignee</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry>advocacy efforts</entry>
- <entry>advocacy</entry>
- <entry>freebsd-advocacy</entry>
- </row>
-
- <row>
- <entry>&java.virtual.machine; problems</entry>
- <entry>java</entry>
- <entry>freebsd-java</entry>
- </row>
-
- <row>
- <entry>standards compliance</entry>
- <entry>standards</entry>
- <entry>freebsd-standards</entry>
- </row>
-
- <row>
- <entry>threading libraries</entry>
- <entry>threads</entry>
- <entry>freebsd-threads</entry>
- </row>
-
- <row>
- <entry>&man.usb.4; subsystem</entry>
- <entry>usb</entry>
- <entry>freebsd-usb</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>Do not be surprised to find that the submitter of the
- PR has assigned it to the wrong category. If you fix the
- category, do not forget to fix the assignment as well.
- (In particular, our submitters seem to have a hard time
- understanding that just because their problem manifested
- on an i386 system, that it might be generic to all of &os;,
- and thus be more appropriate for <literal>kern</literal>.
- The converse is also true, of course.)</para>
-
- <para>Certain PRs may be reassigned away from these generic
- assignees by anyone. For assignees which are mailing lists,
- please use the long form when making the assignment (e.g.,
- <literal>freebsd-foo</literal> instead of <literal>foo</literal>);
- this will avoid duplicate emails sent to the mailing list.</para>
-
- <note>
- <para>Here is a sample list of such entities; it is probably
- not complete. In some cases, entries that have the short form are
- <emphasis>aliases</emphasis>, not mailing lists.</para>
- </note>
-
- <table xml:id="common-assignees-base">
- <title>Common Assignees &mdash; base system</title>
- <tgroup cols="3">
- <thead>
- <row>
- <entry>Type</entry>
- <entry>Suggested Category</entry>
- <entry>Suggested Assignee</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry>problem specific to the &arm; architecture</entry>
- <entry>kern</entry>
- <entry>freebsd-arm</entry>
- </row>
-
- <row>
- <entry>problem specific to the &mips; architecture</entry>
- <entry>kern</entry>
- <entry>freebsd-mips</entry>
- </row>
-
- <row>
- <entry>problem specific to the &powerpc; architecture</entry>
- <entry>kern</entry>
- <entry>freebsd-ppc</entry>
- </row>
-
- <row>
- <entry>problem with Advanced Configuration and Power
- Management (&man.acpi.4;)</entry>
- <entry>kern</entry>
- <entry>freebsd-acpi</entry>
- </row>
-
- <row>
- <entry>problem with Asynchronous Transfer Mode (ATM)
- drivers</entry>
- <entry>kern</entry>
- <entry>freebsd-atm</entry>
- </row>
-
- <row>
- <entry>problem with &firewire; drivers</entry>
- <entry>kern</entry>
- <entry>freebsd-firewire</entry>
- </row>
-
- <row>
- <entry>problem with the filesystem code</entry>
- <entry>kern</entry>
- <entry>freebsd-fs</entry>
- </row>
-
- <row>
- <entry>problem with the &man.geom.4; subsystem</entry>
- <entry>kern</entry>
- <entry>freebsd-geom</entry>
- </row>
-
- <row>
- <entry>problem with the &man.ipfw.4; subsystem</entry>
- <entry>kern</entry>
- <entry>freebsd-ipfw</entry>
- </row>
-
- <row>
- <entry>problem with Integrated Services Digital Network
- (ISDN) drivers</entry>
- <entry>kern</entry>
- <entry>freebsd-isdn</entry>
- </row>
-
- <row>
- <entry>problem with &linux; or SVR4 emulation</entry>
- <entry>kern</entry>
- <entry>freebsd-emulation</entry>
- </row>
-
- <row>
- <entry>problem with the networking stack</entry>
- <entry>kern</entry>
- <entry>freebsd-net</entry>
- </row>
-
- <row>
- <entry>problem with PicoBSD</entry>
- <entry>kern</entry>
- <entry>freebsd-small</entry>
- </row>
-
- <row>
- <entry>problem with the &man.pf.4; subsystem</entry>
- <entry>kern</entry>
- <entry>freebsd-pf</entry>
- </row>
-
- <row>
- <entry>problem with the &man.scsi.4; subsystem</entry>
- <entry>kern</entry>
- <entry>freebsd-scsi</entry>
- </row>
-
- <row>
- <entry>problem with the &man.sound.4; subsystem</entry>
- <entry>kern</entry>
- <entry>freebsd-multimedia</entry>
- </row>
-
- <row>
- <entry>problem with &man.sysinstall.8;</entry>
- <entry>bin</entry>
- <entry>freebsd-qa</entry>
- </row>
-
- <row>
- <entry>problem with the system startup scripts
- (&man.rc.8;)</entry>
- <entry>kern</entry>
- <entry>freebsd-rc</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <table xml:id="common-assignees-ports">
- <title>Common Assignees &mdash; Ports Collection</title>
- <tgroup cols="3">
- <thead>
- <row>
- <entry>Type</entry>
- <entry>Suggested Category</entry>
- <entry>Suggested Assignee</entry>
- </row>
- </thead>
-
- <tbody>
- <row>
- <entry>problem with the ports framework
- (<emphasis>not</emphasis> with an individual port!)</entry>
- <entry>ports</entry>
- <entry>portmgr</entry>
- </row>
-
- <row>
- <entry>port which is maintained by apache@FreeBSD.org</entry>
- <entry>ports</entry>
- <entry>apache</entry>
- </row>
-
- <row>
- <entry>port which is maintained by eclipse@FreeBSD.org</entry>
- <entry>ports</entry>
- <entry>freebsd-eclipse</entry>
- </row>
-
- <row>
- <entry>port which is maintained by gnome@FreeBSD.org</entry>
- <entry>ports</entry>
- <entry>gnome</entry>
- </row>
-
- <row>
- <entry>port which is maintained by haskell@FreeBSD.org</entry>
- <entry>ports</entry>
- <entry>haskell</entry>
- </row>
-
- <row>
- <entry>port which is maintained by java@FreeBSD.org</entry>
- <entry>ports</entry>
- <entry>freebsd-java</entry>
- </row>
-
- <row>
- <entry>port which is maintained by kde@FreeBSD.org</entry>
- <entry>ports</entry>
- <entry>kde</entry>
- </row>
-
- <row>
- <entry>port which is maintained by
- openoffice@FreeBSD.org</entry>
- <entry>ports</entry>
- <entry>freebsd-openoffice</entry>
- </row>
-
- <row>
- <entry>port which is maintained by perl@FreeBSD.org</entry>
- <entry>ports</entry>
- <entry>perl</entry>
- </row>
-
- <row>
- <entry>port which is maintained by python@FreeBSD.org</entry>
- <entry>ports</entry>
- <entry>freebsd-python</entry>
- </row>
-
- <row>
- <entry>port which is maintained by x11@FreeBSD.org</entry>
- <entry>ports</entry>
- <entry>freebsd-x11</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>Ports PRs which have a maintainer who is a ports committer
- may be reassigned by anyone (but note that not every &os;
- committer is necessarily a ports committer, so you cannot
- simply go by the email address alone.)
- </para>
-
- <para>For other PRs, please do not reassign them to individuals
- (other than yourself) unless you are certain that the assignee
- really wants to track the PR. This will help to avoid the
- case where no one looks at fixing a particular problem
- because everyone assumes that the assignee is already working
- on it.</para>
-
- </section>
-
- <section xml:id="pr-assigned">
- <title>Assigned PRs</title>
-
- <para>If a PR has the <literal>responsible</literal> field set
- to the username of a FreeBSD developer, it means that the PR
- has been handed over to that particular person for further
- work.</para>
-
- <para>Assigned PRs should not be touched by anyone but the
- assignee. If you have comments, submit a followup. If for
- some reason you think the PR should change state or be
- reassigned, send a message to the assignee. If the assignee
- does not respond within two weeks, unassign the PR and do as
- you please.</para>
- </section>
-
- <section xml:id="pr-dups">
- <title>重複的 PR</title>
-
- <para>If you find more than one PR that describe the same issue,
- choose the one that contains the largest amount of useful
- information and close the others, stating clearly the number
- of the superseding PR. If several PRs contain non-overlapping
- useful information, submit all the missing information to one
- in a followup, including references to the others; then close
- the other PRs (which are now completely superseded).</para>
- </section>
-
- <section xml:id="pr-stale">
- <title>Stale PRs</title>
-
- <para>A PR is considered stale if it has not been modified in more
- than six months. Apply the following procedure to deal with
- stale PRs:</para>
-
- <itemizedlist>
- <listitem>
- <para>If the PR contains sufficient detail, try to reproduce
- the problem in <literal>-CURRENT</literal> and
- <literal>-STABLE</literal>. If you succeed, submit a
- followup detailing your findings and try to find someone
- to assign it to. Set the state to <quote>analyzed</quote>
- if appropriate.</para>
- </listitem>
-
- <listitem>
- <para>If the PR describes an issue which you know is the
- result of a usage error (incorrect configuration or
- otherwise), submit a followup explaining what the
- originator did wrong, then close the PR with the reason
- <quote>User error</quote> or <quote>Configuration
- error</quote>.</para>
- </listitem>
-
- <listitem>
- <para>If the PR describes an error which you know has been
- corrected in both <literal>-CURRENT</literal> and
- <literal>-STABLE</literal>, close it with a message
- stating when it was fixed in each branch.</para>
- </listitem>
-
- <listitem>
- <para>If the PR describes an error which you know has been
- corrected in <literal>-CURRENT</literal>, but not in
- <literal>-STABLE</literal>, try to find out when the person
- who corrected it is planning to MFC it, or try to find
- someone else (maybe yourself?) to do it. Set the state to
- <quote>feedback</quote> and assign it to whomever will do
- the MFC.</para>
- </listitem>
-
- <listitem>
- <para>In other cases, ask the originator to confirm if
- the problem still exists in newer versions. If the
- originator does not reply within a month, close the PR
- with the notation <quote>Feedback timeout</quote>.</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section xml:id="pr-misfiled">
- <title>Misfiled PRs</title>
-
- <para>GNATS is picky about the format of a submitted bug report.
- This is why a lot of PRs end up being <quote>misfiled</quote> if
- the submitter forgets to fill in a field or puts the wrong sort of
- data in some of the PR fields. This section aims to provide most
- of the necessary details for FreeBSD developers that can help them to
- close or refile these PRs.</para>
-
- <para>When GNATS cannot deduce what to do with a problem report
- that reaches the database, it sets the responsible of the PR to
- <literal>gnats-admin</literal> and files it under the
- <literal>pending</literal> category. This is now a
- <quote>misfiled</quote> PR and will not appear in bug report
- listings, unless someone explicitly asks for a list of all the
- misfiled PRs. If you have access to the FreeBSD cluster
- machines, you can use <command>query-pr</command> to view a
- listing of PRs that have been misfiled:</para>
-
- <screen>&prompt.user; <userinput>query-pr -x -q -r gnats-admin</userinput>
- 52458 gnats-ad open serious medium Re: declaration clash f
- 52510 gnats-ad open serious medium Re: lots of sockets in
- 52557 gnats-ad open serious medium
- 52570 gnats-ad open serious medium Jigdo maintainer update</screen>
-
- <para>Commonly PRs like the ones shown above are misfiled for one
- of the following reasons:</para>
-
- <itemizedlist>
- <listitem>
- <para>A followup to an existing PR, sent through email, has
- the wrong format on its <literal>Subject:</literal>
- header.</para>
- </listitem>
-
- <listitem>
- <para>A submitter sent a Cc: to a mailing list and someone
- followed up to that post instead of the email issued by
- GNATS after processing. The email to the list will not
- have the category/PRnumber tracking tag. (This is why we
- discourage submitters from doing this exact thing.)</para>
- </listitem>
-
- <listitem>
- <para>When completing the &man.send-pr.1; template, the submitter
- forgot to set the category or class of the PR to a proper
- value.</para>
- </listitem>
-
- <listitem>
- <para>When completing the &man.send-pr.1; template, the submitter
- set Confidential to <literal>yes</literal>. (Since we allow
- anyone to mirror GNATS via <application>cvsup</application>,
- our PRs are public information. Security alerts should
- therefore not be sent via GNATS but instead via email to
- the Security Team.)</para>
- </listitem>
-
- <listitem>
- <para>It is not a real PR, but some random message sent to
- <email>bug-followup@FreeBSD.org</email> or
- <email>freebsd-gnats-submit@FreeBSD.org</email>.</para>
- </listitem>
- </itemizedlist>
-
- <section xml:id="pr-misfiled-followups">
- <title>Followups misfiled as new PRs</title>
-
- <para>The first category of misfiled PRs, the one with the wrong
- subject header, is actually the one that requires the greatest
- amount of work from developers. These are not real PRs,
- describing separate problem reports. When a reply is received
- for an existing PR at one of the addresses that GNATS
- <quote>listens</quote> to for incoming messages, the subject
- of the reply should always be of the form:</para>
-
- <programlisting>Subject: Re: category/number: old synopsis text</programlisting>
-
- <para>Most mailers will add the
- <quote><literal>Re:&nbsp;</literal></quote> part when you
- reply to the original mail message of a PR. The
- <quote><literal>category/number:&nbsp;</literal></quote> part
- is a GNATS-specific convention that you have to manually
- insert to the subject of your followup reports.</para>
-
- <para>Any FreeBSD developer, who has direct access to the GNATS
- database, can periodically check for PRs of this sort and move
- interesting bits of the misfiled PR into the audit trail of
- the original PR (by posting a proper followup to a bug report
- to the address &a.bugfollowup;). Then
- the misfiled PR can be closed with a message similar
- to:</para>
-
- <programlisting>Your problem report was misfiled. Please use the format
-"Subject: category/number: original text" when following
-up to older, existing PRs. I've added the relevant bits
-from the body of this PR to kern/12345</programlisting>
-
- <para>Searching with <command>query-pr</command> for the
- original PR, of which a misfiled followup is a reply, is as
- easy as running:</para>
-
- <screen>&prompt.user; query-pr -q -y "some text"</screen>
-
- <para>After you locate the original PR and the misfiled
- followups, use the <option>-F</option> option of
- <command>query-pr</command> to save the full text of all the
- relevant PRs in a &unix; mailbox file, i.e.:</para>
-
- <screen>&prompt.user; <userinput>query-pr -F 52458 52474 &gt; mbox</userinput></screen>
-
- <para>Now you can use any mail user agent to view all the PRs
- you saved in <filename>mbox</filename>. Copy the text of all
- the misfiled PRs in a followup to the original PR and make
- sure you include the proper <literal>Subject:</literal>
- header. Then close the misfiled PRs. When you close the misfiled
- PRs remember that the submitter receives a mail notification that
- his PR changed state to <quote>closed</quote>. Make sure you
- provide enough details in the log about the reason of this state
- change. Typically something like the following is ok:</para>
-
- <programlisting>Followup to ports/45364 misfiled as a new PR.
-This was misfiled because the subject did not have the format:
-
- Re: ports/45364: ...</programlisting>
-
- <para>This way the submitter of the misfiled PR will know what to
- avoid the next time a followup to an existing PR is sent.</para>
- </section>
-
- <section xml:id="pr-misfiled-format">
- <title>PRs misfiled because of missing fields</title>
-
- <para>The second type of misfiled PRs is usually the result of a
- submitter forgetting to fill all the necessary fields when
- writing the original PR.</para>
-
- <para>Missing or bogus <quote>category</quote> or
- <quote>class</quote> fields can result in a misfiled report.
- Developers can use &man.edit-pr.1; to change the category or
- class of these misfiled PRs to a more appropriate value and
- save the PR.</para>
-
- <para>Another common cause of misfiled PRs because of formatting
- issues is quoting, changes or removal of the
- <command>send-pr</command> template, either by the user who
- edits the template or by mailers which do strange things to
- plain text messages. This does not happen a lot of the time,
- but it can be fixed with <command>edit-pr</command> too; it
- does require a bit of work from the developer who refiles the
- PR, but it is relatively easy to do most of the time.</para>
- </section>
-
- <section xml:id="pr-misfiled-notpr">
- <title>Misfiled PRs that are not really problem reports</title>
-
- <para>Sometimes a user wants to submit a report for a problem
- and sends a simple email message to GNATS. The GNATS scripts
- will recognize bug reports that are formatted using the
- &man.send-pr.1; template. They cannot parse any sort of email
- though. This is why submissions of bug reports that are sent
- to <email>freebsd-gnats-submit@FreeBSD.org</email> have to
- follow the template of <command>send-pr</command>, but email
- reports can be sent to &a.bugs;.</para>
-
- <para>Developers that come across PRs that look like they should have
- been posted to &a.bugs.name; or some other list should close the
- PR, informing the submitter in their state-change log why this
- is not really a PR and where the message should be posted.</para>
-
- <para>The email addresses that GNATS listens to for incoming PRs
- have been published as part of the FreeBSD documentation, have
- been announced and listed on the web-site. This means that
- spammers found them. Spam messages
- that reach GNATS are promptly filed
- under the <quote>pending</quote> category until someone looks
- at them. Closing one of these with &man.edit-pr.1; is very
- annoying though, because GNATS replies to the submitter and
- the sender's address of spam mail is never valid these days.
- Bounces will come back for each PR that is closed.</para>
-
- <para>Currently, with the installation of some antispam filters
- that check all submissions to the GNATS database, the amount
- of spam that reaches the <quote>pending</quote> state is very
- small.</para>
-
- <para>All developers who have access to the FreeBSD.org cluster
- machines are encouraged to check for misfiled PRs and immediately
- close those that are spam mail. Whenever you close one of
- these PRs, please do the following:</para>
-
- <itemizedlist>
- <listitem>
- <para>Set Category to <literal>junk</literal>.</para>
- </listitem>
-
- <listitem>
- <para>Set Confidential to <literal>no</literal>.</para>
- </listitem>
-
- <listitem>
- <para>Set Responsible to yourself (and not, e.g.,
- <literal>freebsd-bugs</literal>, which merely
- sends more mail).</para>
- </listitem>
-
- <listitem>
- <para>Set State to <literal>closed</literal>.</para>
- </listitem>
- </itemizedlist>
-
- <para>Junk PRs are not
- backed up, so filing spam mail under this category makes it
- obvious that we do not care to keep it around or waste disk
- space for it. If you merely close them without changing the
- category, they remain both in the master database and in
- any copies of the database mirrored through
- <application>cvsup</application>.</para>
- </section>
- </section>
- </section>
-
- <section xml:id="references">
- <title>延伸閱讀</title>
-
- <para>下面這是在寫、處理 PR 時,可以參考的資料。當然很明顯,這份清單仍須補充。</para>
-
- <itemizedlist>
- <listitem>
- <para><link xlink:href="&url.articles.problem-reports;/article.html">How to
- Write FreeBSD Problem Reports</link>&mdash;給 PR 回報者用的參考原則。</para>
- </listitem>
- </itemizedlist>
- </section>
-</article>
diff --git a/zh_TW.UTF-8/articles/problem-reports/Makefile b/zh_TW.UTF-8/articles/problem-reports/Makefile
deleted file mode 100644
index ab12340558..0000000000
--- a/zh_TW.UTF-8/articles/problem-reports/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# $FreeBSD$
-#
-# Article: Writing FreeBSD Problem Reports
-
-DOC?= article
-
-FORMATS?= html
-WITH_ARTICLE_TOC?= YES
-
-INSTALL_COMPRESSED?=gz
-INSTALL_ONLY_COMPRESSED?=
-
-SRCS= article.xml
-
-URL_RELPREFIX?= ../../../..
-DOC_PREFIX?= ${.CURDIR}/../../..
-
-.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/articles/problem-reports/article.xml b/zh_TW.UTF-8/articles/problem-reports/article.xml
deleted file mode 100644
index ebacf3e366..0000000000
--- a/zh_TW.UTF-8/articles/problem-reports/article.xml
+++ /dev/null
@@ -1,1103 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
- "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd">
-<article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="zh_tw">
- <info><title>Writing &os; Problem Reports</title>
-
-
- <pubdate>$FreeBSD$</pubdate>
-
- <legalnotice xml:id="trademarks" role="trademarks">
- &tm-attrib.freebsd;
- &tm-attrib.cvsup;
- &tm-attrib.ibm;
- &tm-attrib.intel;
- &tm-attrib.sparc;
- &tm-attrib.sun;
- &tm-attrib.general;
- </legalnotice>
-
- <abstract>
- <para>This article describes how to best formulate and submit a
- problem report to the &os; Project.</para>
- </abstract>
-
- <authorgroup>
- <author><personname><firstname>Dag-Erling</firstname><surname>Sm&oslash;rgrav</surname></personname><contrib>Contributed by </contrib></author>
-
- <author><personname><firstname>Mark</firstname><surname>Linimon</surname></personname></author>
- </authorgroup>
-
- <releaseinfo>$FreeBSD$</releaseinfo>
- </info>
-
- <indexterm><primary>problem reports</primary></indexterm>
-
- <section xml:id="pr-intro">
- <title>Introduction</title>
-
- <para>One of the most frustrating experiences one can have as a
- software user is to submit a problem report only to have it
- summarily closed with a terse and unhelpful explanation like
- <quote>not a bug</quote> or <quote>bogus PR</quote>. Similarly,
- one of the most frustrating experiences as a software developer
- is to be flooded with problem reports that are not really
- problem reports but requests for support, or that contain little
- or no information about what the problem is and how to reproduce
- it.</para>
-
- <para>This document attempts to describe how to write good problem
- reports. What, you ask, is a good problem report? Well, to go
- straight to the bottom line, a good problem report is one that
- can be analyzed and dealt with swiftly, to the mutual
- satisfaction of both user and developer.</para>
-
- <para>Although the primary focus of this article is on &os;
- problem reports, most of it should apply quite well to other
- software projects.</para>
-
- <para>Note that this article is organized thematically, not
- chronologically, so you should read through the entire document
- before submitting a problem report, rather than treat it as a
- step-by-step tutorial.</para>
- </section>
-
- <section xml:id="pr-when">
- <title>When to submit a problem report</title>
-
- <para>There are many types of problems, and not all of them should
- engender a problem report. Of course, nobody is perfect, and
- there will be times when you are convinced you have found a bug
- in a program when in fact you have misunderstood the syntax for
- a command or made a typographical error in a configuration file
- (though that in
- itself may sometimes be indicative of poor documentation or poor
- error handling in the application). There are still many cases
- where submitting a problem report is clearly
- <emphasis>not</emphasis> the right
- course of action, and will only serve to frustrate you and the
- developers. Conversely, there are cases where it might be
- appropriate to submit a problem report about something else than
- a bug&mdash;an enhancement or a feature request, for
- instance.</para>
-
- <para>So how do you determine what is a bug and what is not? As a
- simple rule of thumb your problem is <emphasis>not</emphasis> a
- bug if it can be expressed as a question (usually of the form
- <quote>How do I do X?</quote> or <quote>Where can I find
- Y?</quote>). It is not always quite so black and white, but the
- question rule covers a large majority of cases. If you are looking
- for an answer, consider posing your question to the
- &a.questions;.</para>
-
- <para>Some cases where it may be appropriate to submit a problem
- report about something that is not a bug are:</para>
-
- <itemizedlist>
- <listitem>
- <para>Requests for feature enhancements. It is generally a
- good idea to air these on the mailing lists before
- submitting a problem report.</para>
- </listitem>
-
- <listitem>
- <para>Notification of updates to externally maintained
- software (mainly ports, but also externally maintained base
- system components such as BIND or various GNU
- utilities).</para>
-
- <para>For unmaintained ports (<varname>MAINTAINER</varname> contains
- <literal>ports@FreeBSD.org</literal>), such update notifications
- might get picked up by an interested
- committer, or you might be asked to provide a patch to update
- the port; providing it upfront will greatly improve your chances
- that the port will get updated in a timely manner.</para>
-
- <para>If the port is maintained, PRs announcing new upstream releases
- are usually not very useful since they generate supplementary work
- for the committers, and the maintainer likely knows already there is
- a new version, they have probably worked with the developers on it,
- they are probably testing to see there is no regression, etc.</para>
-
- <para>In either case, following the process described in <link xlink:href="&url.books.porters-handbook;/port-upgrading.html">Porter's
- Handbook</link> will yield the best results.</para>
- </listitem>
- </itemizedlist>
-
- <para>A bug that can not be reproduced can rarely be
- fixed. If the bug only occurred once and you can not reproduce
- it, and it does not seem to happen to anybody else, chances are
- none of the developers will be able to reproduce it or figure
- out what is wrong. That does not mean it did not happen, but it
- does mean that the chances of your problem report ever leading
- to a bug fix are very slim. To make matters worse, often
- these kinds of bugs are actually caused by failing hard drives
- or overheating processors &mdash; you should always try to rule
- out these causes, whenever possible, before submitting a PR.</para>
-
- <para>Next, to decide to whom you should file your problem
- report, you need to understand that the software that makes
- up &os; is composed of several different elements:</para>
-
- <itemizedlist>
- <listitem>
- <para>Code in the base system that is written and maintained
- by &os; contributors, such as the kernel, the C library,
- and the device drivers (categorized as <literal>kern</literal>);
- the binary utilities (<literal>bin</literal>); the manual
- pages and documentation (<literal>docs</literal>); and
- the web pages (<literal>www</literal>). All bugs in
- these areas should be reported to the &os; developers.</para>
- </listitem>
-
- <listitem>
- <para>Code in the base system that is written and maintained
- by others, and imported into &os; and adapted. Examples
- include <application>bind</application>, &man.gcc.1;, and
- &man.sendmail.8;. Most bugs in these areas should be reported
- to the &os; developers; but in some cases they may need to be
- reported to the original authors instead if the problems are
- not &os;-specific. Usually these bugs will fall under either
- the <literal>bin</literal> or <literal>gnu</literal>
- categories.</para>
- </listitem>
-
- <listitem>
- <para>Individual applications that are not in the base system
- but are instead part of the &os; Ports Collection (category
- <literal>ports</literal>). Most of these applications are
- not written by &os; developers; what &os; provides is merely
- a framework for installing the application. Therefore, you
- should only report a problem to the &os; developers when you
- believe the problem is &os;-specific; otherwise, you should
- report it to the authors of the software.</para>
- </listitem>
-
- </itemizedlist>
-
- <para>Then you should ascertain whether or not the problem is
- timely. There are few things
- that will annoy a developer more than receiving a problem report
- about a bug she has already fixed.</para>
-
- <para>If the problem is in the base system, you should first read
- the FAQ section on
- <link xlink:href="&url.books.faq;/introduction.html#LATEST-VERSION">
- &os; versions</link>, if you are not already familiar with
- the topic. It is not possible for &os; to fix problems in
- anything other than certain recent branches of the base system,
- so filing a bug report about an older version will probably
- only result in a developer advising you to upgrade to a
- supported version to see if the problem still recurs. The
- Security Officer team maintains the
- <link xlink:href="http://www.freebsd.org/security/">list of supported
- versions</link>.</para>
-
- <para>If the problem is in a port, note that you must first
- upgrade to the latest version of the Ports Collection and see
- if the problem still applies. Due to the rapid pace of changes
- in these applications, it is infeasible for &os; to support
- anything other than the absolute latest versions, and problems
- with older version of applications simply cannot be fixed.</para>
- </section>
-
- <section xml:id="pr-prep">
- <title>Preparations</title>
-
- <para>A good rule to follow is to always do a background search
- before submitting a problem report. Maybe your problem has
- already been reported; maybe it is being discussed on the
- mailing lists, or recently was; it may even already be fixed in
- a newer version than what you are running. You should therefore
- check all the obvious places before submitting your problem
- report. For &os;, this means:</para>
-
- <itemizedlist>
- <listitem>
- <para>The &os;
- <link xlink:href="&url.books.faq;/index.html">Frequently Asked
- Questions</link> (FAQ) list.
- The FAQ attempts to provide answers for a wide range of questions,
- such as those concerning
- <link xlink:href="&url.books.faq;/hardware.html">hardware
- compatibility</link>,
- <link xlink:href="&url.books.faq;/applications.html">user
- applications</link>,
- and <link xlink:href="&url.books.faq;/kernelconfig.html">kernel
- configuration</link>.</para>
- </listitem>
-
- <listitem>
- <para>The
- <link xlink:href="&url.books.handbook;/eresources.html#ERESOURCES-MAIL">mailing
- lists</link>&mdash;if you are not subscribed, use
- <link xlink:href="http://www.FreeBSD.org/search/search.html#mailinglists">the
- searchable archives</link> on the &os; web site. If your
- problem has not been discussed on the lists, you might try
- posting a message about it and waiting a few days to see if
- someone can spot something you have overlooked.</para>
- </listitem>
-
- <listitem>
- <para>Optionally, the entire web&mdash;use your favorite
- search engine to locate any references to your problem. You
- may even get hits from archived mailing lists or newsgroups
- you did not know of or had not thought to search
- through.</para>
- </listitem>
-
- <listitem>
- <para>Next, the searchable
- <link xlink:href="http://www.FreeBSD.org/cgi/query-pr-summary.cgi?query">
- &os; PR database</link> (GNATS). Unless your problem
- is recent or obscure, there is a fair chance it has already
- been reported.</para>
- </listitem>
-
- <listitem>
- <para>Most importantly, you should attempt to see if existing
- documentation in the source base addresses your problem.</para>
-
- <para>For the base &os; code, you should
- carefully study the contents of the
- <filename>/usr/src/UPDATING</filename> file on your system
- or its latest version at
- <uri xlink:href="http://www.FreeBSD.org/cgi/cvsweb.cgi/src/UPDATING">http://www.FreeBSD.org/cgi/cvsweb.cgi/src/UPDATING</uri>.
- (This is vital information
- if you are upgrading from one version to
- another&mdash;especially if you are upgrading to the
- &os.current; branch).</para>
-
- <para>However, if the problem is in something that was installed
- as a part of the &os; Ports Collection, you should refer to
- <filename>/usr/ports/UPDATING</filename> (for individual ports)
- or <filename>/usr/ports/CHANGES</filename> (for changes
- that affect the entire Ports Collection).
- <uri xlink:href="http://www.FreeBSD.org/cgi/cvsweb.cgi/ports/UPDATING">http://www.FreeBSD.org/cgi/cvsweb.cgi/ports/UPDATING</uri>
- and
- <uri xlink:href="http://www.FreeBSD.org/cgi/cvsweb.cgi/ports/CHANGES">http://www.FreeBSD.org/cgi/cvsweb.cgi/ports/CHANGES</uri>
- are also available via CVSweb.</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section xml:id="pr-writing">
- <title>Writing the problem report</title>
-
- <para>Now that you have decided that your issue merits a problem
- report, and that it is a &os; problem, it is time to write
- the actual problem report. Before we get into the mechanics
- of the program used to generate and submit PRs, here are some
- tips and tricks to help make sure that your PR will be most
- effective.</para>
-
- <section>
- <title>Tips and tricks for writing a good problem report</title>
-
- <itemizedlist>
- <listitem>
- <para><emphasis>Do not leave the <quote>Synopsis</quote>
- line empty.</emphasis> The PRs go both onto a mailing list
- that goes all over the world (where the <quote>Synopsis</quote>
- is used
- for the <literal>Subject:</literal> line), but also into a
- database. Anyone who comes along later and browses the
- database by synopsis, and finds a PR with a blank subject
- line, tends just to skip over it. Remember that PRs stay
- in this database until they are closed by someone; an
- anonymous one will usually just disappear in the
- noise.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>Avoid using a weak <quote>Synopsis</quote>
- line.</emphasis> You should not assume that anyone reading
- your PR has any context for your submission, so the more
- you provide, the better. For instance, what part of the
- system does the problem apply to? Do you only see the
- problem while installing, or while running? To
- illustrate, instead of <literal>Synopsis: portupgrade is
- broken</literal>, see how much more informative this
- seems: <literal>Synopsis: port sysutils/portupgrade
- coredumps on -current</literal>. (In the case of ports,
- it is especially helpful to have both the category and
- portname in the <quote>Synopsis</quote> line.)</para>
- </listitem>
-
- <listitem>
- <para><emphasis>If you have a patch, say so.</emphasis>
- A PR with a patch included is much more likely to be
- looked at than one without. If you are including one,
- put the string <literal>[patch]</literal> at the
- beginning of the <quote>Synopsis</quote>. (Although it is
- not mandatory to use that exact string, by convention,
- that is the one that is used.)</para>
- </listitem>
-
- <listitem>
- <para><emphasis>If you are a maintainer, say so.</emphasis>
- If you are maintaining a part of the source code (for
- instance, a port), you might consider adding the string
- <literal>[maintainer update]</literal> at the beginning of
- your synopsis line, and you definitely should set the
- <quote>Class</quote> of
- your PR to <literal>maintainer-update</literal>. This way
- any committer that handles your PR will not have to check.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>Be specific.</emphasis>
- The more information you supply about what problem you
- are having, the better your chance of getting a response.</para>
-
- <itemizedlist>
- <listitem>
- <para>Include the version of &os; you are running (there
- is a place to put that, see below) and on which architecture.
- You should include whether you are running from a release
- (e.g. from a CDROM or download), or from
- a system maintained by &man.cvsup.1; (and, if so, how
- recently you updated). If you are tracking the
- &os.current; branch, that is the very first thing someone
- will ask, because fixes (especially for high-profile
- problems) tend to get committed very quickly, and
- &os.current; users are expected to keep up.</para>
- </listitem>
-
- <listitem>
- <para>Include which global options you have specified in
- your <filename>make.conf</filename>. Note: specifying
- <literal>-O2</literal> and above to &man.gcc.1; is
- known to be buggy in many situations. While the
- &os; developers will accept patches, they are
- generally unwilling to investigate such issues due
- to simple lack of time and volunteers, and may
- instead respond that this just is not supported.</para>
- </listitem>
-
- <listitem>
- <para>If this is a kernel problem, then be prepared to
- supply the following information. (You do not
- have to include these by default, which only tends to
- fill up the database, but you should include excerpts
- that you think might be relevant):</para>
-
- <itemizedlist>
- <listitem>
- <para>your kernel configuration (including which
- hardware devices you have installed)</para>
- </listitem>
- <listitem>
- <para>whether or not you have debugging options enabled
- (such as <literal>WITNESS</literal>), and if so,
- whether the problem persists when you change the
- sense of that option</para>
- </listitem>
- <listitem>
- <para>a backtrace, if one was generated</para>
- </listitem>
- <listitem>
- <para>the fact that you have read
- <filename>src/UPDATING</filename> and that your problem
- is not listed there (someone is guaranteed to ask)</para>
- </listitem>
- <listitem>
- <para>whether or not you can run any other kernel as
- a fallback (this is to rule out hardware-related
- issues such as failing disks and overheating CPUs,
- which can masquerade as kernel problems)</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para>If this is a ports problem, then be prepared to
- supply the following information. (You do not
- have to include these by default, which only tends to
- fill up the database, but you should include excerpts
- that you think might be relevant):</para>
-
- <itemizedlist>
- <listitem>
- <para>which ports you have installed</para>
- </listitem>
- <listitem>
- <para>any environment variables that override the
- defaults in <filename>bsd.port.mk</filename>, such
- as <varname>PORTSDIR</varname></para>
- </listitem>
- <listitem>
- <para>the fact that you have read
- <filename>ports/UPDATING</filename> and that your problem
- is not listed there (someone is guaranteed to ask)</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- </itemizedlist>
-
- </listitem>
-
- <listitem>
- <para><emphasis>Avoid vague requests for features.</emphasis>
- PRs of the form <quote>someone should really implement something
- that does so-and-so</quote> are less likely to get results than
- very specific requests. Remember, the source is available
- to everyone, so if you want a feature, the best way to
- ensure it being included is to get to work! Also consider
- the fact that many things like this would make a better
- topic for discussion on <literal>freebsd-questions</literal>
- than an entry in the PR database, as discussed above.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>Make sure no one else has already submitted
- a similar PR.</emphasis> Although this has already been
- mentioned above, it bears repeating here. It only take a
- minute or two to use the web-based search engine at
- <uri xlink:href="http://www.FreeBSD.org/cgi/query-pr-summary.cgi?query">http://www.FreeBSD.org/cgi/query-pr-summary.cgi?query</uri>.
- (Of course, everyone is guilty of forgetting to do this
- now and then.)</para> </listitem>
-
- <listitem>
- <para><emphasis>Avoid controversial requests.</emphasis>
- If your PR addresses an area that has been controversial
- in the past, you should probably be prepared to not only
- offer patches, but also justification for why the patches
- are <quote>The Right Thing To Do</quote>. As noted above,
- a careful search of the mailing lists using the archives
- at <uri xlink:href="http://www.FreeBSD.org/search/search.html#mailinglists">http://www.FreeBSD.org/search/search.html#mailinglists</uri>
- is always good preparation.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>Be polite.</emphasis>
- Almost anyone who would potentially work on your PR is a
- volunteer. No one likes to be told that they have to do
- something when they are already doing it for some
- motivation other than monetary gain. This is a good thing
- to keep in mind at all times on Open Source
- projects.</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Before you begin</title>
-
- <para>If you are using the &man.send-pr.1; program, make sure your
- <envar>VISUAL</envar> (or <envar>EDITOR</envar> if
- <envar>VISUAL</envar> is not set) environment variable is set
- to something sensible.</para>
-
- <para>You should also make sure that mail delivery works fine.
- &man.send-pr.1; uses mail messages for the submission and
- tracking of problem reports. If you cannot post mail messages
- from the machine you are running &man.send-pr.1; on, your
- problem report will not reach the GNATS database. For details
- on the setup of mail on &os;, see the <quote>Electronic
- Mail</quote> chapter of the &os; Handbook at
- <uri xlink:href="http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/mail.html">http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/mail.html</uri>.</para>
-
- <para>Make sure that your mailer will not mangle the message on
- its way to GNATS. In particular, if your mailer automatically
- breaks lines, changes tabs to spaces, or escapes newline
- characters, any patch that you submit will be rendered
- unusable. For the text sections, however, we request that
- you insert manual linebreaks somewhere around 70 characters,
- so that the web display of the PR will be readable.</para>
-
- <para>Similar considerations apply if you are using the web-based
- PR submittal form instead of &man.send-pr.1;. Note that
- cut-and-paste operations can have their own side-effects on
- text formatting. In certain cases it may be necessary to use
- &man.uuencode.1; to ensure that patches arrive unmodified.</para>
-
- <para>Finally, if your submission will be lengthy, you should
- to prepare your work offline so that nothing will be lost in
- case there is a problem submitting it. This can be an especial
- problem with the web form.</para>
- </section>
-
- <section>
- <title>Attaching patches or files</title>
-
- <para>The following applies to submitting PRs via email:</para>
-
- <para>The &man.send-pr.1; program has provisions for attaching
- files to a problem report. You can attach as many files as
- you want provided that each has a unique base name (i.e. the
- name of the file proper, without the path). Just use the
- <option>-a</option> command-line option to specify the names
- of the files you wish to attach:</para>
-
-<screen>&prompt.user; <userinput>send-pr -a /var/run/dmesg -a /tmp/errors</userinput></screen>
-
- <para>Do not worry about binary files, they will be automatically
- encoded so as not to upset your mail agent.</para>
-
- <para>If you attach a patch, make sure you use the
- <option>-c</option> or <option>-u</option> option to
- &man.diff.1; to create a context or unified diff (unified is
- preferred), and make
- sure to specify the exact CVS revision numbers of the files
- you modified so the developers who read your report will be
- able to apply them easily. For problems with the kernel or the
- base utilities, a patch against &os.current; (the HEAD
- CVS branch) is preferred since all new code should be applied
- and tested there first. After appropriate or substantial testing
- has been done, the code will be merged/migrated to the &os.stable;
- branch.</para>
-
- <para>If you attach a patch inline, instead of as an attachment,
- note that the most common problem by far is the tendency of some
- email programs to render tabs as spaces, which will completely
- ruin anything intended to be part of a Makefile.</para>
-
- <para>Do not send patches as attachments using
- <command>Content-Transfer-Encoding: quoted-printable</command>.
- These will perform character escaping and the entire patch
- will be useless.</para>
-
- <para>Also note that while including small patches in a PR is
- generally all right&mdash;particularly when they fix the problem
- described in the PR&mdash;large patches and especially new code
- which may require substantial review before committing should
- be placed on a web or ftp server, and the URL should be
- included in the PR instead of the patch. Patches in email
- tend to get mangled, especially when GNATS is involved, and
- the larger the patch, the harder it will be for interested
- parties to unmangle it. Also, posting a patch on the web
- allows you to modify it without having to resubmit the entire
- patch in a followup to the original PR. Finally, large
- patches simply increase the size of the database, since
- closed PRs are not actually deleted but instead kept and
- simply marked as <literal>closed</literal>.</para>
-
- <para>You should also take note that unless you explicitly
- specify otherwise in your PR or in the patch itself, any
- patches you submit will be assumed to be licensed under the
- same terms as the original file you modified.</para>
- </section>
-
- <section>
- <title>Filling out the template</title>
-
- <para>The next section applies to the email method only:</para>
-
- <para>When you run &man.send-pr.1;, you are presented with a
- template. The template consists of a list of fields, some of
- which are pre-filled, and some of which have comments explaining
- their purpose or listing acceptable values. Do not worry
- about the comments; they will be removed automatically if you
- do not modify them or remove them yourself.</para>
-
- <para>At the top of the template, below the
- <literal>SEND-PR:</literal> lines, are the email headers. You
- do not normally need to modify these, unless you are sending
- the problem report from a machine or account that can send but
- not receive mail, in which case you will want to set the
- <literal>From:</literal> and <literal>Reply-To:</literal> to
- your real email address. You may also want to send yourself
- (or someone else) a carbon copy of the problem report by
- adding one or more email addresses to the
- <literal>Cc:</literal> header.</para>
-
- <para>In the email template you will find the following two
- single-line fields:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis>Submitter-Id:</emphasis> Do not change this.
- The default value of <literal>current-users</literal> is
- correct, even if you run &os.stable;.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>Confidential:</emphasis> This is prefilled
- to <literal>no</literal>. Changing it makes no sense as
- there is no such thing as a confidential &os; problem
- report&mdash;the PR database is distributed worldwide by
- <application>CVSup</application>.</para>
- </listitem>
-
- </itemizedlist>
-
- <para>The next section describes fields that are common to both
- the email interface and the web interface:</para>
-
- <itemizedlist>
-
- <listitem>
- <para><emphasis>Originator:</emphasis>
- Please specify your real name, optionally followed
- by your email address in angle brackets.
- In the email interface, this is normally
- prefilled with the <literal>gecos</literal> field of the
- currently logged-in
- user.</para>
-
- <note>
- <para>The email address you use will become public information
- and may become available to spammers. You should either
- have spam handling procedures in place, or use a temporary
- email account. However, please note that if you do not
- use a valid email account at all, we will not be able to
- ask you questions about your PR.</para>
- </note>
-
- </listitem>
-
- <listitem>
- <para><emphasis>Organization:</emphasis> Whatever you feel
- like. This field is not used for anything
- significant.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>Synopsis:</emphasis> Fill this out with a
- short and accurate description of the problem. The
- synopsis is used as the subject of the problem report
- email, and is used in problem report listings and
- summaries; problem reports with obscure synopses tend to
- get ignored.</para>
-
- <para>As noted above, if your problem report includes a patch,
- please have the synopsis start with <literal>[patch]</literal>;
- if this is a ports PR and you are the
- maintainer, you may consider adding
- <literal>[maintainer update]</literal> and set the
- <quote>Class</quote> of your PR to
- <literal>maintainer-update</literal>.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>Severity:</emphasis> One of
- <literal>non-critical</literal>,
- <literal>serious</literal> or
- <literal>critical</literal>. Do not overreact; refrain
- from labeling your problem <literal>critical</literal>
- unless it really is (e.g. data corruption issues, serious
- regression from previous functionality in -CURRENT)
- or <literal>serious</literal> unless
- it is something that will affect many users (kernel
- panics or freezes; problems with
- particular device drivers or system utilities). &os;
- developers will not necessarily work on your problem faster
- if you inflate its importance since there are so many other
- people who have done exactly that &mdash; in fact, some
- developers pay little attention to this field
- because of this.</para>
-
- <note>
- <para>Major security problems should <emphasis>not</emphasis>
- be filed in GNATS, because all GNATS information is public
- knowledge. Please send such problems in private email to
- &a.security-officer;.</para>
- </note>
- </listitem>
-
- <listitem>
- <para><emphasis>Priority:</emphasis> One of
- <literal>low</literal>, <literal>medium</literal> or
- <literal>high</literal>. <literal>high</literal> should
- be reserved for problems that will affect practically
- every user of &os; and <literal>medium</literal> for
- something that will affect many users.</para>
-
- <note>
- <para>This field has become so widely abused that it is
- almost completely meaningless.</para>
- </note>
- </listitem>
-
- <listitem>
- <para><emphasis>Category:</emphasis> Choose an appropriate
- category.</para>
-
- <note>
- <para>There are a number of "platform" categories into which
- bugs in the base system that are specific to one particular
- hardware architecture should be filed. Problems that are
- generic all across versions of &os; should probably be
- filed as <literal>kern</literal> or <literal>bin</literal>;
- see discussion of those categories below.</para>
-
- <para>Example: you have a common PC-based machine, and think
- you have encountered a problem specific to a particular
- chipset or a particular motherboard: <literal>i386</literal>
- is the right category.</para>
-
- <para>Example: You are having a problem with an add-in
- peripheral card on a commonly seen bus, or a problem with
- a particular type of hard disk drive: in this case, it
- probably applies to more than one architecture, and
- <literal>kern</literal> is the right category.</para>
- </note>
-
- <para>Here is the current list of categories (taken from
- <uri xlink:href="http://www.FreeBSD.org/cgi/cvsweb.cgi/src/gnu/usr.bin/send-pr/categories">http://www.FreeBSD.org/cgi/cvsweb.cgi/src/gnu/usr.bin/send-pr/categories</uri>):</para>
-
- <itemizedlist>
- <listitem>
- <para><literal>advocacy:</literal> problems relating to
- &os;'s public image. Rarely used.</para>
- </listitem>
-
- <listitem>
- <para><literal>alpha:</literal> problems specific to the
- Alpha platform.</para>
- </listitem>
-
- <listitem>
- <para><literal>amd64:</literal> problems specific to the
- AMD64 platform.</para>
- </listitem>
-
- <listitem>
- <para><literal>bin:</literal> problems with userland
- programs in the base system. If running &man.whereis.1;
- shows <literal>/bin</literal>, <literal>/usr/sbin</literal>,
- or something similar, then this is probably the right
- category. (A few contributed programs might instead
- need to be in <literal>gnu</literal>; see below.)</para>
- </listitem>
-
- <listitem>
- <para><literal>conf:</literal> problems with
- configuration files, default values, and so forth.
- Things that affect <literal>/usr/share</literal>
- or <literal>/etc/rc*</literal> belong here.</para>
- </listitem>
-
- <listitem>
- <para><literal>docs:</literal> problems with manual pages
- or on-line documentation.</para>
- </listitem>
-
- <listitem>
- <para><literal>gnu:</literal> problems with imported GNU software
- such as &man.gcc.1; or &man.grep.1;.</para>
- </listitem>
-
- <listitem>
- <para><literal>i386:</literal> problems specific to the
- &i386; platform.</para>
- </listitem>
-
- <listitem>
- <para><literal>ia64:</literal> problems specific to the
- ia64 platform.</para>
- </listitem>
-
- <listitem>
- <para><literal>java:</literal> problems related to the &java;
- Virtual Machine. (Ports that merely depend on &java; to
- run should be filed under <literal>ports</literal>.)
- </para>
- </listitem>
-
- <listitem>
- <para><literal>kern:</literal> problems with
- the kernel, (non-platform-specific) device drivers,
- or the base libraries.</para>
- </listitem>
-
- <listitem>
- <para><literal>misc:</literal> anything that does not fit
- in any of the other categories. (Note that there is
- almost nothing that truly belongs in this category,
- except for problems with the release and build
- infrastructure. Temporary build failures on
- <literal>HEAD</literal> do not belong here. Also note
- that it is
- easy for things to get lost in this category).</para>
- </listitem>
-
- <listitem>
- <para><literal>ports:</literal> problems relating to the
- ports tree.</para>
- </listitem>
-
- <listitem>
- <para><literal>powerpc:</literal> problems specific to the
- &powerpc; platform.</para>
- </listitem>
-
- <listitem>
- <para><literal>sparc64:</literal> problems specific to the
- &sparc64; platform.</para>
- </listitem>
-
- <listitem>
- <para><literal>standards:</literal> Standards conformance
- issues.</para>
- </listitem>
-
- <listitem>
- <para><literal>threads:</literal> problems related to the
- &os; threads implementation (especially on &os.current;).</para>
- </listitem>
-
- <listitem>
- <para><literal>usb:</literal> problems related to the
- &os; USB implementation.</para>
- </listitem>
-
- <listitem>
- <para><literal>www:</literal> Changes or enhancements to
- the &os; website.
- Problems with code found in <literal>/usr/ports/www</literal>
- do <emphasis>not</emphasis> belong here, they belong in
- <literal>ports</literal> instead.</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para><emphasis>Class:</emphasis> Choose one of the
- following:</para>
-
- <itemizedlist>
- <listitem>
- <para><literal>sw-bug:</literal> software bugs.</para>
- </listitem>
-
- <listitem>
- <para><literal>doc-bug:</literal> errors in
- documentation.</para>
- </listitem>
-
- <listitem>
- <para><literal>change-request:</literal> requests for
- additional features or changes in existing
- features.</para>
- </listitem>
-
- <listitem>
- <para><literal>update:</literal> updates to ports or
- other contributed software.</para>
- </listitem>
-
- <listitem>
- <para><literal>maintainer-update:</literal> updates to
- ports for which you are the maintainer.</para>
- </listitem>
- </itemizedlist>
- </listitem>
-
- <listitem>
- <para><emphasis>Release:</emphasis> The version of &os;
- that you are running. This is filled out automatically if
- you are using
- &man.send-pr.1; and need only be changed if you are
- sending a problem report from a different system than the
- one that exhibits the problem.</para>
- </listitem>
- </itemizedlist>
-
- <para>Finally, there is a series of multi-line fields:</para>
-
- <itemizedlist>
- <listitem>
- <para><emphasis>Environment:</emphasis> This should
- describe, as accurately as possible, the environment in
- which the problem has been observed. This includes the
- operating system version, the version of the specific
- program or file that contains the problem, and any other
- relevant items such as system configuration, other
- installed software that influences the problem,
- etc.&mdash;quite simply everything a developer needs to
- know to reconstruct the environment in which the problem
- occurs.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>Description:</emphasis> A complete and
- accurate description of the problem you are experiencing.
- Try to avoid speculating about the causes of the problem
- unless you are certain that you are on the right track, as
- it may mislead a developer into making incorrect
- assumptions about the problem.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>How-To-Repeat:</emphasis> A summary of the
- actions you need to take to reproduce the problem.</para>
- </listitem>
-
- <listitem>
- <para><emphasis>Fix:</emphasis> Preferably a patch, or at
- least a workaround (which not only helps other people with
- the same problem work around it, but may also help a
- developer understand the cause for the problem), but if
- you do not have any firm ideas for either, it is better to
- leave this field blank than to speculate.</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Sending off the problem report</title>
-
- <para>If you are using &man.send-pr.1;:</para>
-
- <para>Once you are done filling out the template, have saved it,
- and exit your editor, &man.send-pr.1; will prompt you with
- <prompt>s)end, e)dit or a)bort?</prompt>. You can then hit
- <userinput>s</userinput> to go ahead and submit the problem report,
- <userinput>e</userinput> to restart the editor and make
- further modifications, or <userinput>a</userinput> to abort.
- If you choose the latter, your problem report will remain on
- disk (&man.send-pr.1; will tell you the filename before it
- terminates), so you can edit it at your leisure, or maybe
- transfer it to a system with better net connectivity, before
- sending it with the <option>-f</option> to
- &man.send-pr.1;:</para>
-
-<screen>&prompt.user; <userinput>send-pr -f ~/my-problem-report</userinput></screen>
-
- <para>This will read the specified file, validate the contents,
- strip comments and send it off.</para>
-
- <para>If you are using the web form:</para>
-
- <para>Before you hit <literal>submit</literal>, you will need to
- fill in a field containing text that is represented in image
- form on the page. This unfortunate measure has had to be
- adopted due to misuse by automated systems and a few misguided
- individuals. It is a necessary evil that no one likes; please
- do not ask us to remove it.</para>
-
- <para>Note that you are <literal>strongly advised</literal> to
- save your work somewhere before hitting <literal>submit</literal>.
- A common problem for users is to have their web browser displaying
- a stale image from its cache. If this happens to you, your
- submission will be rejected and you may lose your work.</para>
-
- <para>If you are unable to view images for any reason, and are also
- unable to use &man.send-pr.1;, please accept our apologies for
- the inconvenience and email your problem report to the bugbuster
- team at <email>freebsd-bugbusters@FreeBSD.org</email>.</para>
- </section>
-
- </section>
-
- <section xml:id="pr-followup">
- <title>Follow-up</title>
-
- <para>Once your problem report has been filed, you will receive a
- confirmation by email which will include the tracking number
- that was assigned to your problem report and a URL you can use
- to check its status. With a little luck, someone will take an
- interest in your problem and try to address it, or, as the case
- may be, explain why it is not a problem. You will be
- automatically notified of any change of status, and you will
- receive copies of any comments or patches someone may attach to
- your problem report's audit trail.</para>
-
- <para>If someone requests additional information from you, or you
- remember or discover something you did not mention in the
- initial report, please use one of two methods to submit your
- followup:</para>
-
- <itemizedlist>
- <listitem>
- <para>The easiest way is to use the followup link on
- the individual PR's web page, which you can reach from the
- <link xlink:href="http://www.FreeBSD.org/cgi/query-pr-summary.cgi?query">
- PR search page</link>. Clicking on this link will bring up an
- an email window with the correct To: and Subject: lines filled in
- (if your browser is configured to do this).</para>
- </listitem>
-
- <listitem>
- <para>Alternatively, you can just mail it to
- &a.bugfollowup;, making sure that the
- tracking number is included in the subject so the bug tracking
- system will know what problem report to attach it to.</para>
-
- <note>
- <para>If you do <emphasis>not</emphasis> include the tracking
- number, GNATS will become confused and create an entirely
- new PR which it then assigns to the GNATS administrator,
- and then your followup will become lost until someone
- comes in to clean up the mess, which could be days or
- weeks afterwards.</para>
-
- <para>Wrong way: <programlisting>Subject: that PR I sent</programlisting>
- Right way: <programlisting>Subject: Re: ports/12345: compilation problem with foo/bar</programlisting></para>
- </note>
- </listitem>
-
- </itemizedlist>
-
- <para>If the problem report remains open after the problem has
- gone away, just send a follow-up (in the manner prescribed
- above) saying that the problem report can be closed, and, if
- possible, explaining how or when the problem was fixed.</para>
- </section>
-
- <section xml:id="pr-problems">
- <title>If you are having problems</title>
-
- <para>Most PRs go through the system and are accepted quickly;
- however, at times GNATS runs behind and you may not get your
- email confirmation for 10 minutes or even longer. Please try to
- be patient.</para>
-
- <para>In addition, because GNATS receives all its input via email,
- it is absolutely vital that &os; runs all its submissions through
- spam filters. If you do not get a response within an hour or
- two, you may have fallen afoul of them; if so, please contact
- the GNATS administrators at <email>bugmeister@FreeBSD.org</email>
- and ask for help.</para>
-
- <note>
- <para>Among the anti-spam measures is one that weighs against
- many common abuses seen HTML-based email (although not necessarily
- the mere inclusion of HTML in a PR). We strongly recommend
- against the use of HTML-based email when sending PRs: not
- only is it more likely to fall afoul of the filters, it also
- tends to merely clutter up the database. Plain old email is
- strongly preferred.</para>
- </note>
-
- <para>On rare occasions you will encounter a GNATS bug where a
- PR is accepted and assigned a tracking number but it does not
- show up on the list of PRs on any of the web query pages. What
- may have happened is that the database index has gotten out of
- synchronization with the database itself. The way that you
- can test whether this has happened is to pull up the
- <link xlink:href="http://www.FreeBSD.org/cgi/query-pr.cgi">
- view a single PR</link> page and see whether the PR shows up.
- If it does, please notify the GNATS administrators at
- <email>bugmeister@FreeBSD.org</email>. Note that there is a
- <literal>cron</literal> job that periodically rebuilds the database,
- so unless you are in a hurry, no action needs to be taken.</para>
- </section>
-
- <section xml:id="pr-further">
- <title>Further Reading</title>
-
- <para>This is a list of resources relevant to the proper writing
- and processing of problem reports. It is by no means complete.</para>
-
- <itemizedlist>
- <listitem>
- <para><link xlink:href="http://www.chiark.greenend.org.uk/~sgtatham/bugs.html">
- How to Report Bugs Effectively</link>&mdash;an excellent
- essay by Simon G. Tatham on composing useful (non-&os;-specific)
- problem reports.</para>
- </listitem>
- <listitem>
- <para><link xlink:href="&url.articles.pr-guidelines;/article.html">Problem
- Report Handling Guidelines</link>&mdash;valuable insight
- into how problem reports are handled by the &os;
- developers.</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <index/>
-</article>
diff --git a/zh_TW.UTF-8/articles/remote-install/Makefile b/zh_TW.UTF-8/articles/remote-install/Makefile
deleted file mode 100644
index 3efa3a5e93..0000000000
--- a/zh_TW.UTF-8/articles/remote-install/Makefile
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# The FreeBSD Traditional Chinese Project
-#
-# Original Revision: 1.1
-# $FreeBSD$
-#
-
-DOC?= article
-
-FORMATS?= html
-WITH_ARTICLE_TOC?= YES
-
-INSTALL_COMPRESSED?= gz
-INSTALL_ONLY_COMPRESSED?=
-
-SRCS= article.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
-
-URL_RELPREFIX?= ../../../..
-DOC_PREFIX?= ${.CURDIR}/../../..
-
-.include "${DOC_PREFIX}/share/mk/doc.project.mk"
diff --git a/zh_TW.UTF-8/articles/remote-install/article.xml b/zh_TW.UTF-8/articles/remote-install/article.xml
deleted file mode 100644
index d927f61be6..0000000000
--- a/zh_TW.UTF-8/articles/remote-install/article.xml
+++ /dev/null
@@ -1,475 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
- "http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd">
-<!--
- The FreeBSD Documentation Project
- The FreeBSD Chinese (Traditional) Documentation Project
-
- Original Revision: 1.5
-
--->
-<article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="zh_tw">
- <info><title>遠端安裝 &os; 作業系統而不必接 Remote Console</title>
-
-
- <author><personname><firstname>Daniel</firstname><surname>Gerzo</surname></personname><affiliation>
- <address><email>danger@FreeBSD.org</email></address>
- </affiliation></author>
-
- <legalnotice xml:id="trademarks" role="trademarks">
- &tm-attrib.freebsd;
- &tm-attrib.general;
- </legalnotice>
-
- <copyright>
- <year>2008</year>
- <holder>The &os; Documentation Project</holder>
- </copyright>
-
- <pubdate>$FreeBSD$</pubdate>
-
- <releaseinfo>$FreeBSD$</releaseinfo>
-
- <abstract>
- <para>本文介紹如何在沒辦法連到遠端 console 的機器做 &os; 遠端安裝。
- 本文構想來自於作者與 &a.mm; 的合作成果,
- 以及 &a.pjd; 所投注的諸多心血。</para>
- </abstract>
- </info>
-
- <sect1 xml:id="background">
- <title>緣起</title>
-
- <para>世上有許多 server hosting provider,但其中有官方支援 &os;
- 則不是相當多。 他們通常會在所提供的機器上有 &linux; distribution
- 的安裝支援。</para>
-
- <para>有些會讓您可選擇喜好的 &linux; distribution 來裝,
- 像這種情況就可以試著安裝 &os;。 而有些則是會提供救急用的系統,
- 這種也可以用來安裝 &os;。</para>
-
- <para>本文介紹這些遠端基本安裝 &os; 的方式,以及 RAID-1 與
- <application>ZFS</application> 設定步驟。</para>
- </sect1>
-
- <sect1 xml:id="intro">
- <title>介紹</title>
-
- <para>茲摘錄一下本文的目的以及闡述這邊所涵蓋的東西。
- 對於無官方支援 &os; 的代管服務(colocation)用戶而言,
- 本文中所介紹到的指令會相當有用。</para>
-
- <procedure>
- <step>
- <para>正如先前 <link linkend="background">緣起</link> 所提到的,許多名聲還不賴的
- server hosting 公司會提供一些救急用系統,可以透過
- <acronym>LAN</acronym> 方式開機,也可以透過
- <application>SSH</application> 方式進行管理。 通常會有該加值服務,
- 以讓他們的客戶可以連進來修復有問題的作業系統。
- 本節之後將介紹如何透過救急系統來安裝 &os;。</para>
- <!-- XXXTR: Solaris has a restore command, something like
- sysrestore, FreeBSD Should have one too. -->
- </step>
-
- <step>
- <para>下一節會介紹如何在本機設定以及打造最小巧的 &os; ——
- 該版最後會在遠端機器上透過 ramdisk 方式啟動,並以
- <application>sysinstall</application> 從 <acronym>FTP</acronym>
- mirror 站來安裝完整的 &os; 作業系統。</para>
- </step>
-
- <step>
- <para>本文其餘部分將介紹安裝程序,以及 <application>ZFS</application>
- 檔案系統的設定。</para>
- </step>
- </procedure>
-
- <sect2 xml:id="requirements">
- <title>需求</title>
-
- <para>為了成功完成遠端安裝,必須要有:</para>
-
- <itemizedlist>
- <listitem>
- <para>要有可以上網的作業系統,並且 <application>SSH</application>
- 可以連線。</para>
- </listitem>
-
- <listitem>
- <para>瞭解 &os; 的安裝程序</para>
- </listitem>
-
- <listitem>
- <para>熟悉如何使用 &man.sysinstall.8;</para>
- </listitem>
-
- <listitem>
- <para>有 &os; 安裝光碟片或者 <acronym>ISO</acronym> image 檔</para>
- </listitem>
- </itemizedlist>
- </sect2>
- </sect1>
-
- <sect1 xml:id="preparation">
- <title>準備 - <application>mfsBSD</application></title>
-
- <para>在裝 &os; 之前,要先打造最小化的 &os; 作業系統 image 檔,
- 以便可以從硬碟上開機。 如此一來,新的系統就可以透過網路來操作,
- 而剩下來的安裝部分即可不必透過 console。</para>
-
- <para>而 <application>mfsBSD</application> 這套工具就是用來打造小型的
- &os; image 檔。 <application>mfsBSD</application> (名字其中
- <quote>mfs</quote> 就是 <quote>memory file system</quote>)所建造出來的
- 整套系統會透過 ramdisk 方式來運作。 由於此一特色,硬碟的部分就不受限,
- 因此可以用來安裝完整的 &os; 作業系統。 <application>mfsBSD</application>
- 的首頁位於 <uri xlink:href="http://people.freebsd.org/~mm/mfsbsd/">http://people.freebsd.org/~mm/mfsbsd/</uri>,
- 其中連結有該工具的最新 release 部分。</para>
-
- <para>請注意:<application>mfsBSD</application> 內部運作方式的細節,不
- 在本文介紹範圍之內。 若對這方面有興趣的讀者,可至
- <application>mfsBSD</application> 官網查閱相關文件。</para>
-
- <para>首先下載最新的 <application>mfsBSD</application> 並解壓縮之,
- 然後切到解壓縮後的工作目錄,也就是 <application>mfsBSD</application>
- script 檔所在處:</para>
-
- <screen>&prompt.root; <userinput>fetch http://people.freebsd.org/~mm/mfsbsd/mfsbsd-latest.tar.gz</userinput>
-&prompt.root; <userinput>tar xvzf mfsbsd-1.0-beta1.tar.gz</userinput>
-&prompt.root; <userinput>cd mfsbsd-1.0-beta1/</userinput></screen>
-
- <sect2 xml:id="mfsbsd-config">
- <title>設定 <application>mfsBSD</application></title>
-
- <para>在將 <application>mfsBSD</application> 開機之前,
- 有幾個重要設定要先設妥。 此時最重要的設定,很明顯就是網路設定。
- 到底網路怎麼設最好,則取決於所處的網路環境,
- 以及該網路卡會以哪一種驅動程式載入而定。 我們將會看到
- <application>mfsBSD</application> 如何在任何網路情況下進行設定。</para>
-
- <para>另一件重要事就是設定 <systemitem class="username">root</systemitem> 密碼。
- 這點可以透過 <filename>conf/rootpw.conf</filename> 來完成。
- 請切記:該檔密碼是以明文方式存放,因此不建議放真正平常有在用的密碼。
- 然而這密碼只是臨時密碼而已,可以在之後開機時再做更換。</para>
-
- <sect3>
- <title>設定網路(<filename>conf/interfaces.conf</filename> 方式)</title>
-
- <para>若對要裝的機器網卡為何還不知道是哪一款,但可以善加利用
- <application>mfsBSD</application> 的自動偵測功能。
- <application>mfsBSD</application> 的開機 script 會根據網卡的 MAC
- 位址範圍來偵測正確的驅動程式,像是下列的
- <filename>conf/interfaces.conf</filename> 設定內容:</para>
-
- <programlisting>initconf_interfaces="ext1"
-initconf_mac_ext1="00:00:00:00:00:00"
-initconf_ip_ext1="192.168.0.2"
-initconf_netmask_ext1="255.255.255.0"</programlisting>
-
- <para>別忘了在 <filename>conf/rc.conf</filename> 內要加上
- <literal>defaultrouter</literal> 的相關設定:</para>
-
- <programlisting>defaultrouter="192.168.0.1"</programlisting>
- </sect3>
-
- <sect3>
- <title>設定網路(<filename>conf/rc.conf</filename> 方式)</title>
-
- <para>若已經知道網卡是哪一種,那麼要設定網路的話直接改
- <filename>conf/rc.conf</filename> 會比較方便。
- 該檔設定語法與 &os; 標準的 &man.rc.conf.5; 是一致的。</para>
-
- <para>舉個例子,若知道該機器網卡是用 &man.re.4;,那麼就在
- <filename>conf/rc.conf</filename> 做下列類似設定:</para>
-
- <programlisting>defaultrouter="192.168.0.1"
-ifconfig_re0="inet 192.168.0.2 netmask 255.255.255.0"</programlisting>
- </sect3>
- </sect2>
-
- <sect2 xml:id="mfsbsd-build">
- <title>打造 <application>mfsBSD</application> image</title>
-
- <para>打造 <application>mfsBSD</application>
- image 檔的過程相當簡單。</para>
-
- <para>首先是把 &os; 安裝光碟或者安裝用的 <acronym>ISO</acronym> image
- 檔丟到 <filename>/cdrom</filename>。
- 為維持所有例子的一致,本文假設都是用 &os; 7.0-RELEASE
- <acronym>ISO</acronym>。 而把 ISO image 檔掛載到 <filename>/cdrom</filename> 目錄相當簡單,
- 就是用 &man.mdconfig.8;:</para>
-
- <screen>&prompt.root; <userinput>mdconfig -a -t vnode -u 10 -f 7.0-RELEASE-amd64-disc1.iso</userinput>
-&prompt.root; <userinput>mount_cd9660 /dev/md10 /cdrom</userinput></screen>
-
- <para>接著就開始打造可開機的 <application>mfsBSD</application>
- image:</para>
-
- <screen>&prompt.root; <userinput>make BASE=/cdrom/7.0-RELEASE</userinput></screen>
-
- <note>
- <para>上述的 <command>make</command> 指令要在
- <application>mfsBSD</application> 的最上層目錄執行,比方說 <filename>~/mfsbsd-1.0-beta1/</filename>。</para>
- </note>
- </sect2>
-
- <sect2>
- <title><application>mfsBSD</application> 開動</title>
-
- <para>現在 <application>mfsBSD</application> image 已經備妥,
- 要上傳到遠端機器的救急系統或者預先安裝的 &linux; distribution。
- 要完成這工作最適合的工具就是 <application>scp</application>:</para>
-
- <screen>&prompt.root; <userinput>scp disk.img root@192.168.0.2:.</userinput></screen>
-
- <para>為了能順利啟動 <application>mfsBSD</application> image,
- 要把檔案放在欲安裝機器的第一顆(可開機)硬碟上。
- 假設例子的第一顆開機硬碟代號為 <filename>sda</filename>,
- 那麼作法就類似下面這樣:</para>
-
- <screen>&prompt.root; <userinput>dd if=/root/disk.img of=/dev/sda bs=1m</userinput></screen>
-
- <para>若一切順利,該 image 檔現在應該會在第一顆硬碟的
- <acronym>MBR</acronym> 磁區並可以開始進行重開機了。 可以用
- &man.ping.8; 工具來檢測該機器開機完畢與否。 一旦 ping 到之後,
- 就可以透過 &man.ssh.1; 連進去,並且用 <systemitem class="username">root</systemitem>
- 以及剛設定的密碼登入。</para>
- </sect2>
- </sect1>
-
- <sect1 xml:id="installation">
- <title>&os; 作業系統的安裝</title>
-
- <para>現在 <application>mfsBSD</application> 已順利啟動,並且應該可以透過
- &man.ssh.1; 方式來連。 本節將介紹如何建立 slice 分割、設定
- <application>gmirror</application> 以作 RAID-1、如何以
- <application>sysinstall</application> 來安裝 &os;
- 作業系統的最小化安裝。</para>
-
- <sect2>
- <title>準備硬碟</title>
-
- <para>首先要作的是配置硬碟空間給 &os;,像是建立 slice 跟分割區。
- 很明顯地,目前在跑的作業系統是載入到系統記憶體內執行,
- 因此要對硬碟配置並無任何問題。 這些工作可以用
- <application>sysinstall</application> 或者以 &man.fdisk.8; 搭配
- &man.bsdlabel.8; 來完成。</para>
-
- <para>首先先把各硬碟都先清空。 請對各硬碟作下列指令:</para>
-
- <screen>&prompt.root; <userinput>dd if=/dev/zero of=/dev/ad0 count=2</userinput></screen>
-
- <para>接著,以您慣用的工具來建立 slice 以及設定 label。 通常會建議以
- 的 <application>sysinstall</application> 工具來作會比較輕鬆,
- 或者是強而又不太會出槌的文字介面 &unix; 標準工具(像是 &man.fdisk.8;,
- &man.bsdlabel.8;),這部分稍後也會一併介紹。 前者部分在 &os; Handbook
- 的 <link xlink:href="&url.books.handbook;/install-steps.html">安裝
- &os;</link> 章節有相當詳盡的介紹,所以這邊主要要介紹的是如何建立
- RAID-1 系統以及 <application>ZFS</application>。
- 這邊會介紹建立以 &man.gmirror.8; 做成的小型 mirrored 檔案系統:
- <filename>/</filename> (根目錄), <filename>/usr</filename> 以及 <filename>/var</filename>,而硬碟的其餘剩餘空間則通通以
- &man.zpool.8; 做成 <application>ZFS</application> 的 mirrored 檔案系統
- 。 請注意:必須要先把 &os; 作業系統裝好並開完機後,才能進行設定
- <application>ZFS</application> 檔案系統。</para>
-
- <para>下面的例子會介紹如何建立 slice 以及 label、在每個分割區上啟用
- &man.gmirror.8;、如何在每個 mirrored 分割區上建立
- <application>UFS2</application> 檔案系統:</para>
-
- <screen>&prompt.root; <userinput>fdisk -BI /dev/ad0</userinput> <co xml:id="fdisk"/>
-&prompt.root; <userinput>fdisk -BI /dev/ad1</userinput>
-&prompt.root; <userinput>bsdlabel -wB /dev/ad0s1</userinput> <co xml:id="bsdlabel-writing"/>
-&prompt.root; <userinput>bsdlabel -wB /dev/ad1s1</userinput>
-&prompt.root; <userinput>bsdlabel -e /dev/ad0s1</userinput> <co xml:id="bsdlabel-editing"/>
-&prompt.root; <userinput>bsdlabel /dev/ad0s1 &gt; /tmp/bsdlabel.txt &amp;&amp; bsdlabel -R /dev/ad1s1 /tmp/bsdlabel.txt</userinput> <co xml:id="bsdlabel-restore"/>
-&prompt.root; <userinput>gmirror label root /dev/ad[01]s1a</userinput> <co xml:id="gmirror1"/>
-&prompt.root; <userinput>gmirror label var /dev/ad[01]s1d</userinput>
-&prompt.root; <userinput>gmirror label usr /dev/ad[01]s1e</userinput>
-&prompt.root; <userinput>gmirror label -F swap /dev/ad[01]s1b</userinput> <co xml:id="gmirror2"/>
-&prompt.root; <userinput>newfs /dev/mirror/root</userinput> <co xml:id="newfs"/>
-&prompt.root; <userinput>newfs /dev/mirror/var</userinput>
-&prompt.root; <userinput>newfs /dev/mirror/usr</userinput></screen>
-
- <calloutlist>
- <callout arearefs="fdisk">
- <para>對該硬碟建立 slice 並且在第零軌處將開機表作初始。
- 請對該機器所有硬碟都作此一動作。</para>
- </callout>
-
- <callout arearefs="bsdlabel-writing">
- <para>對各硬碟寫入 label 以及 bootstrap 碼。</para>
- </callout>
-
- <callout arearefs="bsdlabel-editing">
- <para>現在手動修改該硬碟的 label,至於如何建立分割區(partitions)
- 請參閱 &man.bsdlabel.8; 說明。
- 分割區分別建立:<literal>a</literal> 是給 <filename>/</filename> (根目錄),
- <literal>b</literal> 給 swap,
- <literal>d</literal> 給 <filename>/var</filename>,
- <literal>e</literal> 給 <filename>/usr</filename>,
- 最後,會在稍後步驟把 <literal>f</literal> 給
- <application>ZFS</application> 使用。</para>
- </callout>
-
- <callout arearefs="bsdlabel-restore">
- <para>把剛剛的 label 設定先匯出,再匯入到第二顆硬碟上,
- 如此一來兩邊的硬碟 label 設定就會同樣。</para>
- </callout>
-
- <callout arearefs="gmirror1">
- <para>在各分割區上啟用 &man.gmirror.8;</para>
- </callout>
-
- <callout arearefs="gmirror2">
- <para>請注意:<option>-F</option> 選項是用在 swap 上。
- 這參數會讓 &man.gmirror.8; 認為該硬體是處於可靠狀態,
- 即使發生電源故障或系統當掉,也不會去同步。</para>
- </callout>
-
- <callout arearefs="newfs">
- <para>在各個有做 mirror 的分割區上建立 <application>UFS2</application>
- 檔案系統</para>
- </callout>
- </calloutlist>
- </sect2>
-
- <sect2>
- <title>系統安裝</title>
-
- <para>這裡是最重要的一環,
- 本節介紹實際上如何在先前一節所做好的硬碟安裝最小化的 &os;,
- 為了完成此一目標,所有檔案系統都必須掛載妥當,才能讓
- <application>sysinstall</application> 可以把 &os; 裝到硬碟內:</para>
-
- <screen>&prompt.root; <userinput>mount /dev/mirror/root /mnt</userinput>
-&prompt.root; <userinput>mkdir /mnt/var /mnt/usr</userinput>
-&prompt.root; <userinput>mount /dev/mirror/var /mnt/var</userinput>
-&prompt.root; <userinput>mount /dev/mirror/usr /mnt/usr</userinput></screen>
-
- <para>做完上述動作之後,請執行 &man.sysinstall.8;。 請從主選單中選擇
- <guimenuitem>Custom</guimenuitem> 安裝,選
- <guimenuitem>Options</guimenuitem> 按 <keycap>Enter</keycap>。
- 然後以方向鍵移動到 <literal>Install Root</literal> 處,按
- <keycap>Space</keycap> 鍵然後改為 <filename>/mnt</filename>,再按 <keycap>Enter</keycap>
- 鍵以將修改值存起來,然後按 <keycap>q</keycap> 鍵即可離開這個
- <guimenuitem>Options</guimenuitem> 畫面。</para>
-
- <warning>
- <para>請注意:本步驟極為重要,若忽略的話那麼
- <application>sysinstall</application> 就沒辦法安裝 &os;。</para>
- </warning>
-
- <para>接著選 <guimenuitem>Distributions</guimenuitem>,然後移動游標到
- <option>Minimal</option> 處,按 <keycap>Space</keycap> 鍵。
- 本文之所以介紹最小化安裝是為了要節省網路流量,因為系統安裝是透過
- <application>ftp</application> 方式來進行。 要離開本畫面,請選
- <option>Exit</option> 即可。</para>
-
- <note>
- <para>至於 <guimenuitem>Partition</guimenuitem> 及
- <guimenuitem>Label</guimenuitem> 步驟則可略過,
- 因為這些目前已經都設定完畢了。</para>
- </note>
-
- <para>在 <guimenuitem>Media</guimenuitem> 選單中請選
- <option>FTP</option>。 請選最近的 mirror 站,並且讓
- <application>sysinstall</application> 假設網路已經設妥。
- 接下來就會回到 <guimenuitem>Custom</guimenuitem> 選單。</para>
-
- <para>最後,按下 <guimenuitem>Commit</guimenuitem> 即可開始進行安裝。
- 完成安裝後,即可離開 <application>sysinstall</application>。</para>
- </sect2>
-
- <sect2>
- <title>後續安裝步驟</title>
-
- <para>此時 &os; 作業系統應該已經裝完,然而還有些後續流程要做。
- 必須要做一些後續設定,才能讓 &os; 可以開機跟登入。</para>
-
- <para>現在必須要用 &man.chroot.8; 以切到剛剛新裝好的系統內。
- 指令如下:</para>
-
- <screen>&prompt.root; <userinput>chroot /mnt</userinput></screen>
-
- <para>然後再打下列指令以繼續完成:</para>
-
- <itemizedlist>
- <listitem>
- <para>把 <literal>GENERIC</literal> kernel 複製到
- <filename>/boot/kernel</filename>
- 目錄:</para>
-
- <screen>&prompt.root; <userinput>cp -Rp /boot/GENERIC/* /boot/kernel</userinput></screen>
- </listitem>
-
- <listitem>
- <para>建立 <filename>/etc/rc.conf</filename>,
- <filename>/etc/resolv.conf</filename> 及
- <filename>/etc/fstab</filename> 檔案。 別忘了,要記得在
- <filename>/etc/rc.conf</filename> 檔設相關網路設定,以及把
- <application>sshd</application> 啟用。 此外,
- <filename>/etc/fstab</filename> 檔應該會長像下面這樣:</para>
-
- <programlisting># Device Mountpoint FStype Options Dump Pass#
-/dev/mirror/swap none swap sw 0 0
-/dev/mirror/root / ufs rw 1 1
-/dev/mirror/usr /usr ufs rw 2 2
-/dev/mirror/var /var ufs rw 2 2
-/dev/cd0 /cdrom cd9660 ro,noauto 0 0</programlisting>
- </listitem>
-
- <listitem>
- <para>新增 <filename>/boot/loader.conf</filename> 檔,
- 並且內容填入下列:</para>
-
- <programlisting>geom_mirror_load="YES"
-zfs_load="YES"</programlisting>
- </listitem>
-
- <listitem>
- <para>執行下列指令,以在下次開機時啟用 <application>ZFS</application>
- :</para>
-
- <screen>&prompt.root; <userinput>echo 'zfs_enable="YES"' &gt;&gt; /etc/rc.conf </userinput></screen>
- </listitem>
-
- <listitem>
- <para>使用 &man.adduser.8; 工具來新增其他使用者帳號。 別忘了,
- 至少要有一個帳號得加入 <systemitem class="groupname">wheel</systemitem> 群組,
- 才能在重開機後以該帳號切換為 root。</para>
- </listitem>
-
- <listitem>
- <para>再次檢查上述相關的設定,是否有遺漏或打錯。</para>
- </listitem>
- </itemizedlist>
-
- <para>現在該系統終於可以重開機了,請用 &man.reboot.8;
- 指令以重開機。</para>
- </sect2>
- </sect1>
-
- <sect1 xml:id="zfs">
- <title>ZFS</title>
-
- <para>系統重開機完畢之後,應該就可以登入了。 歡迎使用全新的 &os; 安裝方式,
- 完全透過遠端而不必接上 remote console!</para>
-
- <para>接下來只剩要調整 &man.zpool.8; 以及建立 &man.zfs.8; 檔案系統而已。
- <application>ZFS</application> 的建立及管理是相當淺顯易懂。 首先,
- 建立 mirrored pool:</para>
-
- <screen>&prompt.root; <userinput>zpool create tank mirror /dev/ad[01]s1f</userinput></screen>
-
- <para>接著,建立檔案系統:</para>
-
- <screen>&prompt.root; <userinput>zfs create tank/ports</userinput>
-&prompt.root; <userinput>zfs create tank/src</userinput>
-&prompt.root; <userinput>zfs set compression=gzip tank/ports</userinput>
-&prompt.root; <userinput>zfs set compression=on tank/src</userinput>
-&prompt.root; <userinput>zfs set mountpoint=/usr/ports tank/ports</userinput>
-&prompt.root; <userinput>zfs set mountpoint=/usr/src tank/src</userinput></screen>
-
- <para>一切就是這樣簡單。 若對 &os; 上的 <application>ZFS</application>
- 細節部分有興趣,請參閱 &os; Wiki 上的 <link xlink:href="http://wiki.freebsd.org/ZFS">ZFS</link> 一節說明。</para>
- </sect1>
-</article>
diff --git a/zh_TW.UTF-8/books/Makefile b/zh_TW.UTF-8/books/Makefile
deleted file mode 100644
index 45eb550a9a..0000000000
--- a/zh_TW.UTF-8/books/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-# $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
deleted file mode 100644
index dd9acff37a..0000000000
--- a/zh_TW.UTF-8/books/Makefile.inc
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# $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
deleted file mode 100644
index 81fed7b836..0000000000
--- a/zh_TW.UTF-8/books/developers-handbook/Makefile
+++ /dev/null
@@ -1,42 +0,0 @@
-#
-# $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
deleted file mode 100644
index 6b48de373f..0000000000
--- a/zh_TW.UTF-8/books/developers-handbook/book.xml
+++ /dev/null
@@ -1,183 +0,0 @@
-<?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
deleted file mode 100644
index 481ce9a436..0000000000
--- a/zh_TW.UTF-8/books/developers-handbook/chapters.ent
+++ /dev/null
@@ -1,33 +0,0 @@
-<?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
deleted file mode 100644
index 636eff06d5..0000000000
--- a/zh_TW.UTF-8/books/developers-handbook/introduction/chapter.xml
+++ /dev/null
@@ -1,186 +0,0 @@
-<?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
deleted file mode 100644
index a7b78244fb..0000000000
--- a/zh_TW.UTF-8/books/developers-handbook/ipv6/chapter.xml
+++ /dev/null
@@ -1,1571 +0,0 @@
-<?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
deleted file mode 100644
index 0f3b90b3e1..0000000000
--- a/zh_TW.UTF-8/books/developers-handbook/kerneldebug/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# 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
deleted file mode 100644
index a2cd16fa99..0000000000
--- a/zh_TW.UTF-8/books/developers-handbook/kerneldebug/chapter.xml
+++ /dev/null
@@ -1,848 +0,0 @@
-<?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
deleted file mode 100644
index 548fd08e3a..0000000000
--- a/zh_TW.UTF-8/books/developers-handbook/l10n/chapter.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?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
deleted file mode 100644
index 771a262e60..0000000000
--- a/zh_TW.UTF-8/books/developers-handbook/policies/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# 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
deleted file mode 100644
index 9dffb99394..0000000000
--- a/zh_TW.UTF-8/books/developers-handbook/policies/chapter.xml
+++ /dev/null
@@ -1,402 +0,0 @@
-<?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
deleted file mode 100644
index e382c5fc69..0000000000
--- a/zh_TW.UTF-8/books/developers-handbook/secure/chapter.xml
+++ /dev/null
@@ -1,518 +0,0 @@
-<?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
deleted file mode 100644
index 38d74e686c..0000000000
--- a/zh_TW.UTF-8/books/developers-handbook/sockets/chapter.xml
+++ /dev/null
@@ -1,1780 +0,0 @@
-<?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
deleted file mode 100644
index fde68a1b61..0000000000
--- a/zh_TW.UTF-8/books/developers-handbook/testing/chapter.xml
+++ /dev/null
@@ -1,212 +0,0 @@
-<?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
deleted file mode 100644
index c9ca702ca2..0000000000
--- a/zh_TW.UTF-8/books/developers-handbook/tools/chapter.xml
+++ /dev/null
@@ -1,2139 +0,0 @@
-<?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))