<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PT Ubuntu Blog &#187; freebsd</title>
	<atom:link href="http://www.ptubuntu.com/tag/freebsd/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ptubuntu.com</link>
	<description>Ruijin to linux 生活中的每一点点滴滴……</description>
	<lastBuildDate>Mon, 30 Jan 2012 09:17:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Freebsd Based GhostBSD 1.5 Beta released</title>
		<link>http://www.ptubuntu.com/2010/07/3557.html</link>
		<comments>http://www.ptubuntu.com/2010/07/3557.html#comments</comments>
		<pubDate>Wed, 14 Jul 2010 02:36:48 +0000</pubDate>
		<dc:creator>ptubuntu</dc:creator>
				<category><![CDATA[Linux Server]]></category>
		<category><![CDATA[CDlinux]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.ptubuntu.com/?p=3557</guid>
		<description><![CDATA[介绍的是BSD.这是一个全新的版本.1.0版本发布时间2010/03/09.1.5-beta发布时间2010/07/08.此版本发行的跟以前freeBsd的系统方式不一样.它是自动运行的光盘.不需要安装就可以使用.看看下面的介绍. GhostBSD是用户友好的、基于GNOME的FreeBSD发行，它以一张自启动运行光盘(尚不支持安装到硬盘)的形式来提供。除了开发该自启动运行光盘，此项目的其他目标还在于改进GNOME桌面在FreeBSD系统上的体验。 如果你还是BSD新手的话.那么你很想了解它.那么你又不想安装你可以使用此光盘.也是一个很不错的选择.对于新手来说要安装好BSD.也不是一件容易的事情. 特色 1.5-beta 1.0 发布日期 2010/07/08 2010/03/09 下载地址: download]]></description>
			<content:encoded><![CDATA[<p>介绍的是BSD.这是一个全新的版本.1.0版本发布时间2010/03/09.1.5-beta发布时间2010/07/08.此版本发行的跟以前freeBsd的系统方式不一样.它是自动运行的光盘.不需要安装就可以使用.看看下面的介绍.</p>
<p>GhostBSD是用户友好的、基于GNOME的FreeBSD发行，它以一张自启动运行光盘(尚不支持安装到硬盘)的形式来提供。除了开发该自启动运行光盘，此项目的其他目标还在于改进GNOME桌面在FreeBSD系统上的体验。<br />
<img src="http://distrowatch.com/images/cgfjoewdlbc/ghostbsd-jvbxckujv.png" alt="" /></p>
<p>如果你还是BSD新手的话.那么你很想了解它.那么你又不想安装你可以使用此光盘.也是一个很不错的选择.对于新手来说要安装好BSD.也不是一件容易的事情.</p>
<p><a href="http://www.ghostbsd.org/wp-content/uploads/2010/03/Screenshot1.png" rel="shadowbox[sbpost-3557];player=img;"><img title="ghostbsd new theme" src="http://www.ghostbsd.org/wp-content/uploads/2010/03/Screenshot1-300x187.png" alt="" width="300" height="187" /></a></p>
<p><a href="http://www.ghostbsd.org/wp-content/uploads/2010/03/Screenshot2.png" rel="shadowbox[sbpost-3557];player=img;"><img title="ghostbsd green theme" src="http://www.ghostbsd.org/wp-content/uploads/2010/03/Screenshot2-300x187.png" alt="" width="300" height="187" /></a></p>
<table>
<tbody>
<tr>
<th>特色</th>
<td>1.5-beta</td>
<td>1.0</td>
</tr>
<tr>
<th>发布日期</th>
<td>2010/07/08</td>
<td>2010/03/09</td>
</tr>
<tr>
<th></th>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<p>下载地址:<a href="http://www.ghostbsd.org/pub/GhostBSD/developement/"> download</a></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ptubuntu.com%2F2010%2F07%2F3557.html&amp;title=Freebsd%20Based%20GhostBSD%201.5%20Beta%20released" id="wpa2a_2"><img src="http://www.ptubuntu.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ptubuntu.com/2010/07/3557.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FreeBSD 7.1 稳定版</title>
		<link>http://www.ptubuntu.com/2009/01/1335.html</link>
		<comments>http://www.ptubuntu.com/2009/01/1335.html#comments</comments>
		<pubDate>Mon, 05 Jan 2009 09:01:01 +0000</pubDate>
		<dc:creator>ptubuntu</dc:creator>
				<category><![CDATA[Linux系统版本]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.ptubuntu.com/?p=1335</guid>
		<description><![CDATA[FreeBSD是一份UNIX操作系统，它面向i386、IA-64、PC-98、Alpha/AXP及UltraSPARC平台。它基于加州伯克利大学的4.4 BSD-Lite发布，并带有一些4.4 BSD-Lite2增强。它还非直接地基于William Jolitz的port，这源于加州伯克利大学i386化的“Net/2”也即“386BSD”，尽管386BSD中只有非常少的代码遗留下来。FreeBSD被遍布全世界的公司、Internet服务提供商、研究人员、计算机专家、学生，以及家庭用户用于他们的工作、教学和娱乐之中。 The first big release of the new year is FreeBSD 7.1: “The FreeBSD Release Engineering Team is pleased to announce the availability of FreeBSD 7.1-RELEASE. This is the second release from the 7-STABLE branch which improves on the functionality of FreeBSD 7.0 and introduces some new features. Some of the highlights: [...]]]></description>
			<content:encoded><![CDATA[<p>FreeBSD是一份UNIX操作系统，它面向i386、IA-64、PC-98、Alpha/AXP及UltraSPARC平台。它基于加州伯克利大学的4.4  BSD-Lite发布，并带有一些4.4 BSD-Lite2增强。它还非直接地基于William  Jolitz的port，这源于加州伯克利大学i386化的“Net/2”也即“386BSD”，尽管386BSD中只有非常少的代码遗留下来。FreeBSD被遍布全世界的公司、Internet服务提供商、研究人员、计算机专家、学生，以及家庭用户用于他们的工作、教学和娱乐之中。</p>
<p>The first big release of the new year is <a href="http://www.ptubuntu.com/tag/freebsd" class="st_tag internal_tag" rel="tag" title="标签 freebsd 下的日志">FreeBSD</a> 7.1:  “<span class="Quote">The FreeBSD Release Engineering Team is pleased  to announce the availability of FreeBSD 7.1-RELEASE. This is the second release  from the 7-STABLE branch which improves on the functionality of FreeBSD 7.0 and  introduces some new features. Some of the highlights: The ULE scheduler is now  the default in GENERIC kernels for amd64 and i386 architectures; support for  using DTrace inside the kernel has been imported from OpenSolaris; a new and  much-improved NFS Lock Manager (NLM) client; boot loader changes allow, among  other things, booting from USB devices and booting from GPT-labeled devices; the  cpuset(2) <a href="http://www.ptubuntu.com/tag/system" class="st_tag internal_tag" rel="tag" title="标签 system 下的日志">system</a> call and cpuset(1) command have been added, providing an API  for thread to CPU binding and CPU resource grouping and assignment; KDE updated  to 3.5.10, GNOME updated to 2.22.3; DVD-sized media for the amd64 and i386  architectures.</span>” See the <a href="http://www.freebsd.org/releases/7.1R/announce.html">release  announcement</a> and <a href="http://www.freebsd.org/releases/7.1R/relnotes.html">release notes</a> for  further details. <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/mirrors-ftp.html">Download</a> (<a href="http://torrents.freebsd.org:8080/">torrents</a>): <a href="ftp://ftp3.tw.freebsd.org/pub/FreeBSD/ISO-IMAGES-i386/7.1/7.1-RELEASE-i386-dvd1.iso.gz">7.1-RELEASE-i386-dvd1.iso.gz</a> (1,808MB, <a href="http://ftp.nl.freebsd.org/os/FreeBSD/ISO-IMAGES-i386/7.1/CHECKSUM.MD5">MD5</a>,  <a href="http://torrents.freebsd.org:8080/torrents/5d4fd5a64e436a831383773f85fb38b888b9ecc9.torrent">torrent</a>),  <a href="ftp://ftp1.fr.freebsd.org/pub/FreeBSD/ISO-IMAGES-amd64/7.1/7.1-RELEASE-amd64-dvd1.iso.gz">7.1-RELEASE-amd64-dvd1.iso.gz</a> (1,806MB, <a href="http://ftp.nl.freebsd.org/os/FreeBSD/ISO-IMAGES-amd64/7.1/CHECKSUM.MD5">MD5</a>,  <a href="http://torrents.freebsd.org:8080/torrents/cfbe00ecb36fe0f7d38cf0f68a4b2b7e5c505f22.torrent">torrent</a>).</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ptubuntu.com%2F2009%2F01%2F1335.html&amp;title=FreeBSD%207.1%20%E7%A8%B3%E5%AE%9A%E7%89%88" id="wpa2a_4"><img src="http://www.ptubuntu.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ptubuntu.com/2009/01/1335.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FreeBSD 7.1-RC1</title>
		<link>http://www.ptubuntu.com/2008/12/879.html</link>
		<comments>http://www.ptubuntu.com/2008/12/879.html#comments</comments>
		<pubDate>Thu, 11 Dec 2008 02:42:06 +0000</pubDate>
		<dc:creator>ptubuntu</dc:creator>
				<category><![CDATA[Linux系统版本]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[技术类]]></category>

		<guid isPermaLink="false">http://www.ptubuntu.com/?p=879</guid>
		<description><![CDATA[FreeBSD是一份UNIX操作系统，它面向i386、IA-64、PC-98、Alpha/AXP及UltraSPARC平台。它基于加州伯克利大学的4.4 BSD-Lite发布，并带有一些4.4 BSD-Lite2增强。它还非直接地基于William Jolitz的port，这源于加州伯克利大学i386化的“Net/2”也即“386BSD”，尽管386BSD中只有非常少的代码遗留下来。FreeBSD被遍布全世界的公司、Internet服务提供商、研究人员、计算机专家、学生，以及家庭用户用于他们的工作、教学和娱乐之中。 Ken Smith has announced the availability of the first release candidate for FreeBSD 7.1: “FreeBSD 7.1-RC1 is now available, the first of the release candidates. There will be at least one more release candidate before the release so the release itself is likely around three weeks from now &#8211; if no [...]]]></description>
			<content:encoded><![CDATA[<p>FreeBSD是一份UNIX操作系统，它面向i386、IA-64、PC-98、Alpha/AXP及UltraSPARC平台。它基于加州伯克利大学的4.4 BSD-Lite发布，并带有一些4.4 BSD-Lite2增强。它还非直接地基于William Jolitz的port，这源于加州伯克利大学i386化的“Net/2”也即“386BSD”，尽管386BSD中只有非常少的代码遗留下来。FreeBSD被遍布全世界的公司、Internet服务提供商、研究人员、计算机专家、学生，以及家庭用户用于他们的工作、教学和娱乐之中。</p>
<p>Ken Smith has announced the availability of the first release candidate for <a href="http://www.ptubuntu.com/tag/freebsd" class="st_tag internal_tag" rel="tag" title="标签 freebsd 下的日志">FreeBSD</a> 7.1: “<span class="Quote">FreeBSD 7.1-RC1 is now available, the first of the release candidates. There will be at least one more release candidate before the release so the release itself is likely around three weeks from now &#8211; if no new show-stoppers are uncovered during testing. In addition to general testing, we&#8217;re looking for information about potential problems with the boot loader. And a late arrival that&#8217;s not possible to test without the packages, sysinstall&#8217;s issues with excessive disc swapping when installing large sets of packages off the CDROMs should be fixed. Testing to make sure that&#8217;s working would be appreciated.</span>” Read the <a href="http://lists.freebsd.org/pipermail/freebsd-stable/2008-December/047014.html">release announcement</a> for more known issues and binary/source upgrade instructions. <a href="http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/mirrors-ftp.html">Download</a>: <a href="ftp://ftp14.freebsd.org/pub/FreeBSD/ISO-IMAGES-i386/7.1/7.1-RC1-i386-dvd1.iso.gz">7.1-RC1-i386-dvd1.iso.gz</a> (1,808MB, <a href="ftp://ftp10.freebsd.org/pub/FreeBSD/ISO-IMAGES-i386/7.1/CHECKSUM.MD5">MD5</a>), <a href="ftp://ftp12.freebsd.org/pub/FreeBSD/ISO-IMAGES-amd64/7.1/7.1-RC1-amd64-dvd1.iso.gz">7.1-RC1-amd64-dvd1.iso.gz</a> (1,806MB, <a href="ftp://ftp10.freebsd.org/pub/FreeBSD/ISO-IMAGES-amd64/7.1/CHECKSUM.MD5">MD5</a>).</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ptubuntu.com%2F2008%2F12%2F879.html&amp;title=FreeBSD%207.1-RC1" id="wpa2a_6"><img src="http://www.ptubuntu.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ptubuntu.com/2008/12/879.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>System V的启动风格和BSD的启动风格(1)&#8212;代码角度</title>
		<link>http://www.ptubuntu.com/2008/12/780.html</link>
		<comments>http://www.ptubuntu.com/2008/12/780.html#comments</comments>
		<pubDate>Mon, 08 Dec 2008 06:04:37 +0000</pubDate>
		<dc:creator>ptubuntu</dc:creator>
				<category><![CDATA[Linux Server]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[linux命令]]></category>
		<category><![CDATA[system]]></category>
		<category><![CDATA[技术类]]></category>

		<guid isPermaLink="false">http://www.ptubuntu.com/?p=780</guid>
		<description><![CDATA[  System V的启动风格和bsd的启动风格不同，网上很多文章介绍这件事，但是那些文章仅仅从应用的角度来分析，这在理解上就有很大的困难，毕竟差异算什么呢？充其量仅仅算一种习惯，没有孰优孰劣的，如果让读者非得分出个所以然来，仅从应用角度来理解就不够了，最好的方法就是从源代码的角度看个究竟，几乎所有的人都知道unix和类unix系统是从init程序开始生命历程的，但是却有了System V和BSD两种风格的启动，说什么/etc/inittab，/etc/rc.d/等等的不同，让人真的很难分辨清楚这到底是怎么一回事，实际上根本没有那么复杂，执行什么脚本以及怎么执行只是它们各自init程序的约定，从这个意义上讲这些启动脚本就是一种动态语言，而init程序就是解释器，本文就分析System V和BSD的init源代码，然后试着分析它们有什么不同并试着指出它们各自的特点以及思想。   System V和BSD的启动程序都是/sbin/init，源代码都是init.c，我先分析System V的init.c文件（以下简称init）。init从main开始执行，最开始解析命令行参数，随后就进入了一个大循环,细节我就不说了，主要谈一下代码逻辑进而指出为什么启动脚本的不同： int main(int argc, char **argv) { &#8230;     init_main(dfl_level);     /*NOTREACHED*/     return 0; }   init_main函数就是一切的循环，在其内部主要解析了/etc/inittab脚本，在进一步分析这个主循环之前首先熟悉一个数据结构，这个数据结构非常重要，从inittab中分析出的一一个要执行的程序就连同它的一些环境变量存储到这个结构里，然后所有这些结构链接成一个全局链表，这个结构就是 CHILD： typedef struct _child_ {   int flags;            /* inittab中指示进程的当前状态，比如正在执行，已退出，等待，已经执行过等等 */   int exstat;            /* inittab中指示进程如果执行后退出的退出状态，init程序由此状态和下面的action字段采取不同的动作 */   int pid;            /* 如果这个进程已经开始执行，那么这个字段表示该进程的pid */   time_t tm;            /* When respawned last */   int count;            /* Times respawned in the last 2 minutes */   char id[8];            /* Inittab中程序唯一的id号 */   char rlevel[12];        /* 运行级别，这是System V抽象出来的概念，BSD并没有运行级别的概念*/   int action;            /* 程序执行的方式，比如wait就是等待这个进程结束在继续，respawn就是结束后重启 */   char process[128];        /* 命令行，实际就是要执行的程序或脚本的全路径和参数 */   struct _child_ *new;        /* New entry (after inittab re-read) */   struct _child_ *next;        /* For the linked list */ } CHILD; 下面开始分析主循环 int init_main() {   CHILD            *ch;   struct sigaction    sa;   sigset_t        sgt;   pid_t            rc;   int            f, st;   if (!reload) {     for(f = 1; f &#60;= NSIG; f++)         SETSIG(sa, f, SIG_IGN, SA_RESTART);   }   SETSIG(sa, SIGALRM,  signal_handler, 0);//设置信号处理器，这个信号处理器是很有意思的，仅仅搜集信号并不处理，具体处理工作由下面的循环来负责。   SETSIG(sa, SIGHUP,   signal_handler, 0);   SETSIG(sa, SIGINT,   signal_handler, 0);   SETSIG(sa, SIGCHLD,  chld_handler, SA_RESTART);//这个chld_handler信号处理器很重要，inittab脚本中的程序的执行方式不同，有的结束后重新开始有的只执行一次，有的等待其结束才往下进行，这个处理器就是探测子程序结束的信号的。   SETSIG(sa, SIGPWR,   signal_handler, 0);   SETSIG(sa, SIGWINCH, signal_handler, 0);   SETSIG(sa, SIGUSR1,  signal_handler, 0);   SETSIG(sa, SIGSTOP,  stop_handler, SA_RESTART);   SETSIG(sa, SIGTSTP,  stop_handler, SA_RESTART);   SETSIG(sa, SIGCONT,  cont_handler, SA_RESTART);   SETSIG(sa, SIGSEGV,  (void (*)(int))segv_handler, SA_RESTART); [...]]]></description>
			<content:encoded><![CDATA[<p>  <a href="http://www.ptubuntu.com/tag/system" class="st_tag internal_tag" rel="tag" title="标签 system 下的日志">System</a> V的启动风格和bsd的启动风格不同，网上很多文章介绍这件事，但是那些文章仅仅从应用的角度来分析，这在理解上就有很大的困难，毕竟差异算什么呢？充其量仅仅算一种习惯，没有孰优孰劣的，如果让读者非得分出个所以然来，仅从应用角度来理解就不够了，最好的方法就是从源代码的角度看个究竟，几乎所有的人都知道unix和类unix系统是从init程序开始生命历程的，但是却有了System V和BSD两种风格的启动，说什么/etc/inittab，/etc/rc.d/等等的不同，让人真的很难分辨清楚这到底是怎么一回事，实际上根本没有那么复杂，执行什么脚本以及怎么执行只是它们各自init程序的约定，从这个意义上讲这些启动脚本就是一种动态语言，而init程序就是解释器，本文就分析System V和BSD的init源代码，然后试着分析它们有什么不同并试着指出它们各自的特点以及思想。<br />
  System V和BSD的启动程序都是/sbin/init，源代码都是init.c，我先分析System V的init.c文件（以下简称init）。init从main开始执行，最开始解析命令行参数，随后就进入了一个大循环,细节我就不说了，主要谈一下代码逻辑进而指出为什么启动脚本的不同：</p>
<p><span id="more-780"></span></p>
<div class="highlighter">
<ol class="highlighter-c">
<li><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span> main(</span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span> argc, </span><span class="keyword"><strong><span style="color: #0000ff;">char</span></strong></span><span> **argv)</span></li>
<li class="alt"><span>{</span></li>
<li><span>&#8230;</span></li>
<li class="alt"><span>    init_main(dfl_level);</span></li>
<li><span>    </span><span style="color: #008200;"><span class="comment">/*NOTREACHED*/</span></span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">return</span></strong></span><span> 0;</span></li>
<li><span>}</span></li>
</ol>
</div>
<p><span><!--more--></span></p>
<p> </p>
<p>init_main函数就是一切的循环，在其内部主要解析了/etc/inittab脚本，在进一步分析这个主循环之前首先熟悉一个数据结构，这个数据结构非常重要，从inittab中分析出的一一个要执行的程序就连同它的一些环境变量存储到这个结构里，然后所有这些结构链接成一个全局链表，这个结构就是<br />
CHILD：</p>
<div class="highlighter">
<ol class="highlighter-c">
<li><span>typedef </span><span class="keyword"><strong><span style="color: #0000ff;">struct</span></strong></span><span> _child_ {</span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span> flags;            </span><span style="color: #008200;"><span class="comment">/* inittab中指示进程的当前状态，比如正在执行，已退出，等待，已经执行过等等 */</span></span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span> exstat;            </span><span style="color: #008200;"><span class="comment">/* inittab中指示进程如果执行后退出的退出状态，init程序由此状态和下面的action字段采取不同的动作 */</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span> pid;            </span><span style="color: #008200;"><span class="comment">/* 如果这个进程已经开始执行，那么这个字段表示该进程的pid */</span></span></li>
<li><span>  time_t tm;            </span><span style="color: #008200;"><span class="comment">/* When respawned last */</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span> count;            </span><span style="color: #008200;"><span class="comment">/* Times respawned in the last 2 minutes */</span></span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">char</span></strong></span><span> id[8];            </span><span style="color: #008200;"><span class="comment">/* Inittab中程序唯一的id号 */</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">char</span></strong></span><span> rlevel[12];        </span><span style="color: #008200;"><span class="comment">/* 运行级别，这是System V抽象出来的概念，BSD并没有运行级别的概念*/</span></span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span> action;            </span><span style="color: #008200;"><span class="comment">/* 程序执行的方式，比如wait就是等待这个进程结束在继续，respawn就是结束后重启 */</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">char</span></strong></span><span> process[128];        </span><span style="color: #008200;"><span class="comment">/* 命令行，实际就是要执行的程序或脚本的全路径和参数 */</span></span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">struct</span></strong></span><span> _child_ *</span><span class="keyword"><strong><span style="color: #0000ff;">new</span></strong></span><span>;        </span><span style="color: #008200;"><span class="comment">/* New entry (after inittab re-read) */</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">struct</span></strong></span><span> _child_ *next;        </span><span style="color: #008200;"><span class="comment">/* For the linked list */</span></span></li>
<li><span>} CHILD;</span></li>
</ol>
</div>
<p>下面开始分析主循环</p>
<div class="highlighter">
<ol class="highlighter-c">
<li><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span> init_main()</span></li>
<li class="alt"><span>{</span></li>
<li><span>  CHILD            *ch;</span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">struct</span></strong></span><span> sigaction    sa;</span></li>
<li><span>  sigset_t        sgt;</span></li>
<li class="alt"><span>  pid_t            rc;</span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>            f, st;</span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (!reload) {</span></li>
<li><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>(f = 1; f &lt;= NSIG; f++)</span></li>
<li class="alt"><span>        SETSIG(sa, f, SIG_IGN, SA_RESTART);</span></li>
<li><span>  }</span></li>
<li class="alt"><span>  SETSIG(sa, SIGALRM,  signal_handler, 0);</span><span style="color: #008200;"><span class="comment">//设置信号处理器，这个信号处理器是很有意思的，仅仅搜集信号并不处理，具体处理工作由下面的循环来负责。</span></span></li>
<li><span>  SETSIG(sa, SIGHUP,   signal_handler, 0);</span></li>
<li class="alt"><span>  SETSIG(sa, SIGINT,   signal_handler, 0);</span></li>
<li><span>  SETSIG(sa, SIGCHLD,  chld_handler, SA_RESTART);</span><span style="color: #008200;"><span class="comment">//这个chld_handler信号处理器很重要，inittab脚本中的程序的执行方式不同，有的结束后重新开始有的只执行一次，有的等待其结束才往下进行，这个处理器就是探测子程序结束的信号的。</span></span></li>
<li class="alt"><span>  SETSIG(sa, SIGPWR,   signal_handler, 0);</span></li>
<li><span>  SETSIG(sa, SIGWINCH, signal_handler, 0);</span></li>
<li class="alt"><span>  SETSIG(sa, SIGUSR1,  signal_handler, 0);</span></li>
<li><span>  SETSIG(sa, SIGSTOP,  stop_handler, SA_RESTART);</span></li>
<li class="alt"><span>  SETSIG(sa, SIGTSTP,  stop_handler, SA_RESTART);</span></li>
<li><span>  SETSIG(sa, SIGCONT,  cont_handler, SA_RESTART);</span></li>
<li class="alt"><span>  SETSIG(sa, SIGSEGV,  (</span><span class="keyword"><strong><span style="color: #0000ff;">void</span></strong></span><span> (*)(</span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>))segv_handler, SA_RESTART);</span></li>
<li><span>  console_init();</span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (!reload) {</span></li>
<li><span>      </span><span style="color: #008200;"><span class="comment">/* Close whatever files are open, and reset the console. */</span></span></li>
<li class="alt"><span>    close(0);</span></li>
<li><span>    close(1);</span></li>
<li class="alt"><span>    close(2);</span></li>
<li><span>      console_stty();</span></li>
<li class="alt"><span>      setsid();</span></li>
<li><span>      putenv(PATH_DFL);</span></li>
<li class="alt"><span>      (</span><span class="keyword"><strong><span style="color: #0000ff;">void</span></strong></span><span>) close(open(UTMP_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0644));</span></li>
<li><span>      initlog(L_CO, bootmsg, </span><span class="string"><span style="color: #a31515;">“booting”</span></span><span>);</span><span style="color: #008200;"><span class="comment">//打印字符，这是我们熟悉的</span></span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (emerg_shell) {</span><span style="color: #008200;"><span class="comment">//如果有紧急的shell需要执行，那么马上执行，这个在救援模式下可能要用</span></span></li>
<li><span>        SETSIG(sa, SIGCHLD, SIG_DFL, SA_RESTART);</span></li>
<li class="alt"><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (spawn(&amp;ch_emerg, &amp;f) &gt; 0) {</span></li>
<li><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">while</span></strong></span><span>((rc = wait(&amp;st)) != f)</span></li>
<li class="alt"><span>                </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (rc &lt; 0 &amp;&amp; errno == ECHILD)</span></li>
<li><span>                    </span><span class="keyword"><strong><span style="color: #0000ff;">break</span></strong></span><span>;</span></li>
<li class="alt"><span>        }</span></li>
<li><span>          SETSIG(sa, SIGCHLD,  chld_handler, SA_RESTART);</span></li>
<li class="alt"><span>      }</span></li>
<li><span>      runlevel = </span><span class="string"><span style="color: #a31515;">&#8216;#&#8217;</span></span><span>;</span></li>
<li class="alt"><span>      read_inittab();</span><span style="color: #008200;"><span class="comment">//开始解析inittab脚本</span></span></li>
<li><span> </span></li>
<li class="alt"><span>  } </span><span class="keyword"><strong><span style="color: #0000ff;">else</span></strong></span><span> {</span></li>
<li><span>    initlog(L_CO, bootmsg, </span><span class="string"><span style="color: #a31515;">“reloading”</span></span><span>);</span></li>
<li class="alt"><span>    sigfillset(&amp;sgt);</span></li>
<li><span>    sigprocmask(SIG_UNBLOCK, &amp;sgt, NULL);</span></li>
<li class="alt"><span>  }</span></li>
<li><span>  start_if_needed();</span><span style="color: #008200;"><span class="comment">//解析完脚本后，脚本中的程序都已经被加入一个全局链表family，说是链表，实际上就是用next和prev串起来的一串要执行的程序结构。</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">while</span></strong></span><span>(1) {  </span><span style="color: #008200;"><span class="comment">//可以认为init程序执行到这里，以下的任务就是不断地执行start_if_needed和收容僵尸进程了。</span></span></li>
<li><span>     boot_transitions();</span></li>
<li class="alt"><span>     INITDBG(L_VB, </span><span class="string"><span style="color: #a31515;">“init_main: waiting..”</span></span><span>);</span></li>
<li><span>     </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>(ch = family; ch; ch = ch-&gt;next)</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> ((ch-&gt;flags &amp; RUNNING) &amp;&amp; ch-&gt;action != BOOT) </span><span class="keyword"><strong><span style="color: #0000ff;">break</span></strong></span><span>;</span></li>
<li><span>     </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch != NULL &amp;&amp; got_signals == 0) check_init_fifo();</span></li>
<li class="alt"><span>     fail_check();</span></li>
<li><span>     process_signals();</span></li>
<li class="alt"><span>     start_if_needed();</span></li>
<li><span>  }</span></li>
<li class="alt"><span>  </span><span style="color: #008200;"><span class="comment">/*NOTREACHED*/</span></span></li>
<li><span>}</span></li>
</ol>
</div>
<p>重头戏开始了，注意，解析inittab的逻辑是，一行一行解析，碰到id号重复的或者不合法的就跳过，如果没有错误则加入全局family链表</p>
<div class="highlighter">
<ol class="highlighter-c">
<li><span class="keyword"><strong><span style="color: #0000ff;">void</span></strong></span><span> read_inittab(</span><span class="keyword"><strong><span style="color: #0000ff;">void</span></strong></span><span>)</span></li>
<li class="alt"><span>{</span></li>
<li><span>  FILE        *fp;            </span><span style="color: #008200;"><span class="comment">/* The INITTAB file */</span></span></li>
<li class="alt"><span>  CHILD        *ch, *old, *i;        </span><span style="color: #008200;"><span class="comment">/* Pointers to CHILD structure */</span></span></li>
<li><span>  CHILD        *head = NULL;        </span><span style="color: #008200;"><span class="comment">/* Head of linked list */</span></span></li>
<li class="alt"></li>
<li><span>  sigset_t    nmask, omask;        </span><span style="color: #008200;"><span class="comment">/* For blocking SIGCHLD. */</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">char</span></strong></span><span>        buf[256];        </span><span style="color: #008200;"><span class="comment">/* Line buffer */</span></span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">char</span></strong></span><span>        err[64];        </span><span style="color: #008200;"><span class="comment">/* Error message. */</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">char</span></strong></span><span>        *id, *rlevel,</span></li>
<li><span>        *action, *process;    </span><span style="color: #008200;"><span class="comment">/* 这四个字段代表的正是inittab文件中每一行的信息 */</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">char</span></strong></span><span>        *p;</span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>        lineNo = 0;        </span><span style="color: #008200;"><span class="comment">/* Line number in INITTAB file */</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>        actionNo;        </span><span style="color: #008200;"><span class="comment">/* Decoded action field */</span></span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>        f;            </span><span style="color: #008200;"><span class="comment">/* Counter */</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>        round;            </span><span style="color: #008200;"><span class="comment">/* round 0 for SIGTERM, 1 for SIGKILL */</span></span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>        foundOne = 0;        </span><span style="color: #008200;"><span class="comment">/* No killing no sleep */</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>        talk;            </span><span style="color: #008200;"><span class="comment">/* Talk to the user */</span></span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>        done = 0;        </span><span style="color: #008200;"><span class="comment">/* Ready yet? */</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> ((fp = fopen(INITTAB, </span><span class="string"><span style="color: #a31515;">“r”</span></span><span>)) == NULL)</span></li>
<li><span>    initlog(L_VB, </span><span class="string"><span style="color: #a31515;">“No inittab file found”</span></span><span>);</span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">while</span></strong></span><span>(!done) {</span><span style="color: #008200;"><span class="comment">//循环读取inittab的每一个行。</span></span></li>
<li><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (fp == NULL || fgets(buf, </span><span class="keyword"><strong><span style="color: #0000ff;">sizeof</span></strong></span><span>(buf), fp) == NULL) {   </span><span style="color: #008200;"><span class="comment">//将一行的信息存入buf</span></span></li>
<li class="alt"><span>        done = 1;                                          </span><span style="color: #008200;"><span class="comment">//如果没有到行尾就说明没有结束</span></span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>(old = newFamily; old; old = old-&gt;next)         </span></li>
<li class="alt"><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (strpbrk(old-&gt;rlevel, </span><span class="string"><span style="color: #a31515;">“S”</span></span><span>)) </span><span class="keyword"><strong><span style="color: #0000ff;">break</span></strong></span><span>;</span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (old == NULL)</span></li>
<li class="alt"><span>            snprintf(buf, </span><span class="keyword"><strong><span style="color: #0000ff;">sizeof</span></strong></span><span>(buf), </span><span class="string"><span style="color: #a31515;">“~~:S:wait:%s\n”</span></span><span>, SULOGIN);</span></li>
<li><span>        </span><strong><span style="color: #0000ff;"><span class="keyword">else</span></span></strong></li>
<li class="alt"><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">continue</span></strong></span><span>;</span></li>
<li><span>    }</span></li>
<li class="alt"><span>    lineNo++;  </span><span style="color: #008200;"><span class="comment">//递增行号</span></span></li>
<li><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>(p = buf; *p == </span><span class="string"><span style="color: #a31515;">&#8216; &#8217;</span></span><span> || *p == </span><span class="string"><span style="color: #a31515;">&#8216;\t&#8217;</span></span><span>; p++);</span><span style="color: #008200;"><span class="comment">//以下的解析逻辑就不细说了，挺好理解的，就是解析字符串，我最讨厌这件事了</span></span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (*p == </span><span class="string"><span style="color: #a31515;">&#8216;#&#8217;</span></span><span> || *p == </span><span class="string"><span style="color: #a31515;">&#8216;\n&#8217;</span></span><span>) </span><span class="keyword"><strong><span style="color: #0000ff;">continue</span></strong></span><span>;</span></li>
<li><span>    id =      strsep(&amp;p, </span><span class="string"><span style="color: #a31515;">“:”</span></span><span>);</span></li>
<li class="alt"><span>    rlevel =  strsep(&amp;p, </span><span class="string"><span style="color: #a31515;">“:”</span></span><span>);</span></li>
<li><span>    action =  strsep(&amp;p, </span><span class="string"><span style="color: #a31515;">“:”</span></span><span>);</span></li>
<li class="alt"><span>    process = strsep(&amp;p, </span><span class="string"><span style="color: #a31515;">“\n”</span></span><span>);</span></li>
<li><span>    err[0] = 0;</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (!id || !*id) strcpy(err, </span><span class="string"><span style="color: #a31515;">“missing id field”</span></span><span>);</span></li>
<li><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (!rlevel)     strcpy(err, </span><span class="string"><span style="color: #a31515;">“missing runlevel field”</span></span><span>);</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (!process)    strcpy(err, </span><span class="string"><span style="color: #a31515;">“missing process field”</span></span><span>);</span></li>
<li><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (!action || !*action)</span></li>
<li class="alt"><span>            strcpy(err, </span><span class="string"><span style="color: #a31515;">“missing action field”</span></span><span>);</span></li>
<li><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (id &amp;&amp; strlen(id) &gt; </span><span class="keyword"><strong><span style="color: #0000ff;">sizeof</span></strong></span><span>(utproto.ut_id))</span></li>
<li class="alt"><span>        sprintf(err, </span><span class="string"><span style="color: #a31515;">“id field too long (max %d characters)”</span></span><span>,</span></li>
<li><span>            (</span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>)</span><span class="keyword"><strong><span style="color: #0000ff;">sizeof</span></strong></span><span>(utproto.ut_id));</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (rlevel &amp;&amp; strlen(rlevel) &gt; 11)</span></li>
<li><span>        strcpy(err, </span><span class="string"><span style="color: #a31515;">“rlevel field too long (max 11 characters)”</span></span><span>);</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (process &amp;&amp; strlen(process) &gt; 127)</span></li>
<li><span>        strcpy(err, </span><span class="string"><span style="color: #a31515;">“process field too long”</span></span><span>);</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (action &amp;&amp; strlen(action) &gt; 32)</span></li>
<li><span>        strcpy(err, </span><span class="string"><span style="color: #a31515;">“action field too long”</span></span><span>);</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (err[0] != 0) {</span></li>
<li><span>        initlog(L_VB, </span><span class="string"><span style="color: #a31515;">“%s[%d]: %s”</span></span><span>, INITTAB, lineNo, err);</span></li>
<li class="alt"><span>        INITDBG(L_VB, </span><span class="string"><span style="color: #a31515;">“%s:%s:%s:%s”</span></span><span>, id, rlevel, action, process);</span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">continue</span></strong></span><span>;</span></li>
<li class="alt"><span>    }</span></li>
<li><span>    actionNo = -1;</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>(f = 0; actions[f].name; f++)  </span><span style="color: #008200;"><span class="comment">//actions代表一个结构数组，将一个说明运行方式的字符串映射到一个数字。这个循环就是匹配运行方式字符串并将它映射成数字。</span></span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (strcasecmp(action, actions[f].name) == 0) {</span></li>
<li class="alt"><span>            actionNo = actions[f].act;</span></li>
<li><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">break</span></strong></span><span>;</span></li>
<li class="alt"><span>        }</span></li>
<li><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (actionNo == -1) {</span></li>
<li class="alt"><span>        initlog(L_VB, </span><span class="string"><span style="color: #a31515;">“%s[%d]: %s: unknown action field”</span></span><span>,</span></li>
<li><span>            INITTAB, lineNo, action);</span></li>
<li class="alt"><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">continue</span></strong></span><span>;</span></li>
<li><span>    }</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>(old = newFamily; old; old = old-&gt;next) {</span><span style="color: #008200;"><span class="comment">//这个循环检测唯一性，如果已经有这个id了，那么就不往下继续了，直接读取下一行。</span></span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span>(strcmp(old-&gt;id, id) == 0 &amp;&amp; strcmp(id, </span><span class="string"><span style="color: #a31515;">“~~”</span></span><span>)) {</span></li>
<li class="alt"><span>            initlog(L_VB, </span><span class="string"><span style="color: #a31515;">“%s[%d]: duplicate ID field \”%s\”"</span></span><span>,</span></li>
<li><span>                INITTAB, lineNo, id);</span></li>
<li class="alt"><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">break</span></strong></span><span>;</span></li>
<li><span>        }</span></li>
<li class="alt"><span>    }</span></li>
<li><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (old) </span><span class="keyword"><strong><span style="color: #0000ff;">continue</span></strong></span><span>;</span></li>
<li class="alt"><span>    ch = imalloc(</span><span class="keyword"><strong><span style="color: #0000ff;">sizeof</span></strong></span><span>(CHILD));</span><span style="color: #008200;"><span class="comment">//分配一个CHILD，注意这个结构很重要，前面已经说过了。</span></span></li>
<li><span>    ch-&gt;action = actionNo;      </span><span style="color: #008200;"><span class="comment">//从这里开始就开始初始化这个新创建的CHILD结构了，同样，细节我就不说了。</span></span></li>
<li class="alt"><span>    strncpy(ch-&gt;id, id, </span><span class="keyword"><strong><span style="color: #0000ff;">sizeof</span></strong></span><span>(utproto.ut_id) + 1); </span><span style="color: #008200;"><span class="comment">/* Hack for different libs. */</span></span></li>
<li><span>    strncpy(ch-&gt;process, process, </span><span class="keyword"><strong><span style="color: #0000ff;">sizeof</span></strong></span><span>(ch-&gt;process) - 1);</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (rlevel[0]) {</span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>(f = 0; f &lt; </span><span class="keyword"><strong><span style="color: #0000ff;">sizeof</span></strong></span><span>(rlevel) - 1 &amp;&amp; rlevel[f]; f++) {</span></li>
<li class="alt"><span>            ch-&gt;rlevel[f] = rlevel[f];</span></li>
<li><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch-&gt;rlevel[f] == </span><span class="string"><span style="color: #a31515;">&#8216;s&#8217;</span></span><span>) ch-&gt;rlevel[f] = </span><span class="string"><span style="color: #a31515;">&#8216;S&#8217;</span></span><span>;</span></li>
<li class="alt"><span>        }</span></li>
<li><span>        strncpy(ch-&gt;rlevel, rlevel, </span><span class="keyword"><strong><span style="color: #0000ff;">sizeof</span></strong></span><span>(ch-&gt;rlevel) - 1);</span></li>
<li class="alt"><span>    } </span><span class="keyword"><strong><span style="color: #0000ff;">else</span></strong></span><span> {</span></li>
<li><span>        strcpy(ch-&gt;rlevel, </span><span class="string"><span style="color: #a31515;">“0123456789&#8243;</span></span><span>);</span></li>
<li class="alt"><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ISPOWER(ch-&gt;action))</span></li>
<li><span>            strcpy(ch-&gt;rlevel, </span><span class="string"><span style="color: #a31515;">“S0123456789&#8243;</span></span><span>);</span></li>
<li class="alt"><span>    }</span></li>
<li><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch-&gt;action == SYSINIT) strcpy(ch-&gt;rlevel, </span><span class="string"><span style="color: #a31515;">“#”</span></span><span>);</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch-&gt;action == BOOT || ch-&gt;action == BOOTWAIT)</span></li>
<li><span>        strcpy(ch-&gt;rlevel, </span><span class="string"><span style="color: #a31515;">“*”</span></span><span>);</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ISPOWER(ch-&gt;action)) {   </span><span style="color: #008200;"><span class="comment">//这个if-else判断就是简单地将新创建的CHILD先链接到一个局部链表newFamily，这个newFamily链表的意义在于检测id号的唯一性</span></span></li>
<li><span>        ch-&gt;flags |= XECUTED;</span><span style="color: #008200;"><span class="comment">//XECUTED标志代表已经执行过，init程序不会再重新执行它了</span></span></li>
<li class="alt"><span>        old = NULL;</span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>(i = newFamily; i; i = i-&gt;next) {</span></li>
<li class="alt"><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (!ISPOWER(i-&gt;action)) </span><span class="keyword"><strong><span style="color: #0000ff;">break</span></strong></span><span>;</span></li>
<li><span>            old = i;</span></li>
<li class="alt"><span>        }</span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (old) {</span></li>
<li class="alt"><span>            ch-&gt;next = i;</span></li>
<li><span>            old-&gt;next = ch;</span></li>
<li class="alt"><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (i == NULL) head = ch;</span></li>
<li><span>        } </span><span class="keyword"><strong><span style="color: #0000ff;">else</span></strong></span><span> {</span></li>
<li class="alt"><span>            ch-&gt;next = newFamily;</span></li>
<li><span>            newFamily = ch;</span></li>
<li class="alt"><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch-&gt;next == NULL) head = ch;</span></li>
<li><span>        }</span></li>
<li class="alt"><span>    } </span><span class="keyword"><strong><span style="color: #0000ff;">else</span></strong></span><span> {</span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch-&gt;action == KBREQUEST) ch-&gt;flags |= XECUTED;</span></li>
<li class="alt"><span>        ch-&gt;next = NULL;</span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (head)</span></li>
<li class="alt"><span>            head-&gt;next = ch;</span></li>
<li><span>        </span><strong><span style="color: #0000ff;"><span class="keyword">else</span></span></strong></li>
<li class="alt"><span>            newFamily = ch;</span></li>
<li><span>        head = ch;</span></li>
<li class="alt"><span>    }</span></li>
<li><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>(old = family; old; old = old-&gt;next)     </span><span style="color: #008200;"><span class="comment">//全局意义上的分析，看是否有人两次解析inittab之间改动了inittab文件</span></span></li>
<li class="alt"><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (strcmp(old-&gt;id, ch-&gt;id) == 0) { </span><span style="color: #008200;"><span class="comment">//如果有人改动了，那么以最近一次解析结果为准</span></span></li>
<li><span>            old-&gt;</span><span class="keyword"><strong><span style="color: #0000ff;">new</span></strong></span><span> = ch;</span></li>
<li class="alt"><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">break</span></strong></span><span>;</span></li>
<li><span>        }</span></li>
<li class="alt"><span>  }</span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (fp) fclose(fp);</span></li>
<li class="alt"><span>  INITDBG(L_VB, </span><span class="string"><span style="color: #a31515;">“Checking for children to kill”</span></span><span>);</span></li>
<li><span> &#8230;&#8230;   </span><span style="color: #008200;"><span class="comment">//这里省略了一个逻辑，该逻辑就是检测看是否有需要结束的进程，如果有的话就进一步判断能否结束，判断通过结束之。有一点要注意的是，并不是仅仅在系统启动的时候要解析inittab，而是系统运行中的时候通过给init进程发信号也可以让init进程解析inittab脚本文件</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (foundOne) do_sleep(1);</span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>(ch = family; ch; ch = ch-&gt;next)</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch-&gt;flags &amp; KILLME) {</span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (!(ch-&gt;flags &amp; ZOMBIE))</span></li>
<li class="alt"><span>            initlog(L_CO, </span><span class="string"><span style="color: #a31515;">“Pid %d [id %s] seems to hang”</span></span><span>, ch-&gt;pid, ch-&gt;id);</span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">else</span></strong></span><span> {</span></li>
<li class="alt"><span>            INITDBG(L_VB, </span><span class="string"><span style="color: #a31515;">“Updating utmp for pid %d [id %s]“</span></span><span>,ch-&gt;pid, ch-&gt;id);</span></li>
<li><span>            ch-&gt;flags &amp;= ~RUNNING;</span></li>
<li class="alt"><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch-&gt;process[0] != </span><span class="string"><span style="color: #a31515;">&#8216;+&#8217;</span></span><span>)</span></li>
<li><span>                write_utmp_wtmp(</span><span class="string"><span style="color: #a31515;">“”</span></span><span>, ch-&gt;id, ch-&gt;pid, DEAD_PROCESS, NULL);</span></li>
<li class="alt"><span>        }</span></li>
<li><span>    }</span></li>
<li class="alt"><span>  sigemptyset(&amp;nmask);</span></li>
<li><span>  sigaddset(&amp;nmask, SIGCHLD);</span></li>
<li class="alt"><span>  sigprocmask(SIG_BLOCK, &amp;nmask, &amp;omask);</span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>(ch = family; ch; ch = old) {</span><span style="color: #008200;"><span class="comment">//释放掉原来的老的链表元素</span></span></li>
<li class="alt"><span>    old = ch-&gt;next;</span></li>
<li><span>    free(ch);</span></li>
<li class="alt"><span>  }</span></li>
<li><span>  family = newFamily;  </span><span style="color: #008200;"><span class="comment">//终于将局部链表链入全局链表了，链入的肯定是没有错误的链表</span></span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>(ch = family; ch; ch = ch-&gt;next) ch-&gt;</span><span class="keyword"><strong><span style="color: #0000ff;">new</span></strong></span><span> = NULL;</span></li>
<li><span>  newFamily = NULL;</span></li>
<li class="alt"><span>  sigprocmask(SIG_SETMASK, &amp;omask, NULL);</span></li>
<li><span>}</span></li>
</ol>
</div>
<p>解析完毕inittab之后就要开始执行inittab中要求执行的程序了，现在全局链表family已经设置好，接下来需要做的就是遍历这个链表然后依次执行链表中元素指定的程序，然后根据元素的一些字段设置一些参数，而这些参数进一步反馈到主循环，指示下一部的行为，还是看代码吧：</p>
<div class="highlighter">
<ol class="highlighter-c">
<li><span class="keyword"><strong><span style="color: #0000ff;">void</span></strong></span><span> start_if_needed(</span><span class="keyword"><strong><span style="color: #0000ff;">void</span></strong></span><span>)</span></li>
<li class="alt"><span>{</span></li>
<li><span>    CHILD *ch;        </span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span> delete;    </span></li>
<li><span>    INITDBG(L_VB, </span><span class="string"><span style="color: #a31515;">“Checking for children to start”</span></span><span>);</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>(ch = family; ch; ch = ch-&gt;next) {      </span><span style="color: #008200;"><span class="comment">//循环遍历family链表中的一切元素。</span></span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch-&gt;flags &amp; WAITING) </span><span class="keyword"><strong><span style="color: #0000ff;">break</span></strong></span><span>;    </span><span style="color: #008200;"><span class="comment">//如果有等待标志，那么说明只有这个程序执行完才可以往下进行，故直接退出循环。</span></span></li>
<li class="alt"><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch-&gt;flags &amp; RUNNING) </span><span class="keyword"><strong><span style="color: #0000ff;">continue</span></strong></span><span>; </span><span style="color: #008200;"><span class="comment">//如果已经在运行了，那么忽略它。</span></span></li>
<li><span>        delete = 1;</span></li>
<li class="alt"><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (strchr(ch-&gt;rlevel, runlevel) ||((ch-&gt;flags &amp; DEMAND) &amp;&amp; !strchr(</span><span class="string"><span style="color: #a31515;">“#*Ss”</span></span><span>, runlevel))) {</span></li>
<li><span>            startup(ch);      </span><span style="color: #008200;"><span class="comment">//启动一个进程，具体的代码就不分析了，startup中要做的就是设置一些CHILD结构的标志然后fork出一个进程并且exec这个要执行的程序，以上的if (ch-&gt;flags &amp; WAITING)判断之类的就是在startup中被设置的。</span></span></li>
<li class="alt"><span>            delete = 0;</span></li>
<li><span>        }</span></li>
<li class="alt"><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (delete) {  </span><span style="color: #008200;"><span class="comment">//如果需要删除，则将该CHILD从全局表删除，因为留着它没有任何意义</span></span></li>
<li><span>            ch-&gt;flags &amp;= ~(RUNNING|WAITING);</span></li>
<li class="alt"><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (!ISPOWER(ch-&gt;action) &amp;&amp; ch-&gt;action != KBREQUEST)</span></li>
<li><span>                ch-&gt;flags &amp;= ~XECUTED;</span></li>
<li class="alt"><span>            ch-&gt;pid = 0;</span></li>
<li><span>        } </span><strong><span style="color: #0000ff;"><span class="keyword">else</span></span></strong></li>
<li class="alt"><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch-&gt;flags &amp; WAITING) </span><span class="keyword"><strong><span style="color: #0000ff;">break</span></strong></span><span>;  </span><span style="color: #008200;"><span class="comment">//如果新执行的程序在startup中其flags被设置了WAITING，那么就不继续循环了，原因同上。</span></span></li>
<li><span>    }</span></li>
<li class="alt"><span>}</span></li>
</ol>
</div>
<p>以上这个函数很短，就是一些判断然后执行，但是如果在startup中设置了WAITING，那么何时清除它呢？这就是信号处理的事情了，众所周知，一旦子进程结束就要向父进程发送一个SIGCHLD信号，那么我们就看一下init进程的SIGCHLD信号处理器chld_handler：</p>
<div class="highlighter">
<ol class="highlighter-c">
<li><span class="keyword"><strong><span style="color: #0000ff;">void</span></strong></span><span> chld_handler()</span></li>
<li class="alt"><span>{</span></li>
<li><span>    CHILD        *ch;</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>        pid, st;</span></li>
<li><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>        saved_errno = errno;</span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">while</span></strong></span><span>((pid = waitpid(-1, &amp;st, WNOHANG)) != 0) {   </span><span style="color: #008200;"><span class="comment">//找到结束进程的pid</span></span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (errno == ECHILD) </span><span class="keyword"><strong><span style="color: #0000ff;">break</span></strong></span><span>;</span></li>
<li class="alt"><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>( ch = family; ch; ch = ch-&gt;next )     </span><span style="color: #008200;"><span class="comment">//遍历family链表，找到关于这个进程的CHILD</span></span></li>
<li><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> ( ch-&gt;pid == pid &amp;&amp; (ch-&gt;flags &amp; RUNNING) ) {</span></li>
<li class="alt"><span>                ADDSET(got_signals, SIGCHLD);  </span><span style="color: #008200;"><span class="comment">//将信号加入全局的got_signals，这个got_signals要在process_signals用</span></span></li>
<li><span>                ch-&gt;exstat = st;</span></li>
<li class="alt"><span>                ch-&gt;flags |= ZOMBIE;      </span><span style="color: #008200;"><span class="comment">//设置ZOMBIE标志，这个标志在init_main主循环中的process_signals要用来清除WAITING标志。</span></span></li>
<li><span>                </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch-&gt;</span><span class="keyword"><strong><span style="color: #0000ff;">new</span></strong></span><span>) {</span></li>
<li class="alt"><span>                    ch-&gt;</span><span class="keyword"><strong><span style="color: #0000ff;">new</span></strong></span><span>-&gt;exstat = st;</span></li>
<li><span>                    ch-&gt;</span><span class="keyword"><strong><span style="color: #0000ff;">new</span></strong></span><span>-&gt;flags |= ZOMBIE;</span></li>
<li class="alt"><span>                }</span></li>
<li><span>                </span><span class="keyword"><strong><span style="color: #0000ff;">break</span></strong></span><span>;</span></li>
<li class="alt"><span>            }</span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch == NULL)</span></li>
<li class="alt"><span>            INITDBG(L_VB, </span><span class="string"><span style="color: #a31515;">“chld_handler: unknown child %d exited.”</span></span><span>, pid);</span></li>
<li><span>    }</span></li>
<li class="alt"><span>    errno = saved_errno;</span></li>
<li><span>}</span></li>
</ol>
</div>
<p>那么我们就来看一下got_signals,我们只关心我们关注的信号：</p>
<div class="highlighter">
<ol class="highlighter-c">
<li><span class="keyword"><strong><span style="color: #0000ff;">void</span></strong></span><span> process_signals()</span></li>
<li class="alt"><span>{</span></li>
<li><span>  CHILD        *ch;</span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>        pwrstat;</span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>        oldlevel;</span></li>
<li class="alt"><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">int</span></strong></span><span>        fd;</span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">char</span></strong></span><span>        c;</span></li>
<li class="alt"><span>&#8230;&#8230;</span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ISMEMBER(got_signals, SIGCHLD)) {   </span><span style="color: #008200;"><span class="comment">//子进程结束信号</span></span></li>
<li class="alt"><span>    INITDBG(L_VB, </span><span class="string"><span style="color: #a31515;">“got SIGCHLD”</span></span><span>);</span></li>
<li><span>    DELSET(got_signals, SIGCHLD);     </span></li>
<li class="alt"><span>    </span><span class="keyword"><strong><span style="color: #0000ff;">for</span></strong></span><span>(ch = family; ch; ch = ch-&gt;next)  </span><span style="color: #008200;"><span class="comment">//找到结束的子进程</span></span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch-&gt;flags &amp; ZOMBIE) {        </span><span style="color: #008200;"><span class="comment">//注意，init在chld_handler中设置了ZOMBIE标志</span></span></li>
<li class="alt"><span>        ch-&gt;flags &amp;= ~(RUNNING|ZOMBIE|WAITING);  </span><span style="color: #008200;"><span class="comment">//清除RUNNING，ZOMBIE，WAITING</span></span></li>
<li><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ch-&gt;process[0] != </span><span class="string"><span style="color: #a31515;">&#8216;+&#8217;</span></span><span>)</span></li>
<li class="alt"><span>            write_utmp_wtmp(</span><span class="string"><span style="color: #a31515;">“”</span></span><span>, ch-&gt;id, ch-&gt;pid, DEAD_PROCESS, NULL);</span></li>
<li><span>        }</span></li>
<li class="alt"><span>  }</span></li>
<li><span>  </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (ISMEMBER(got_signals, SIGHUP)) {</span><span style="color: #008200;"><span class="comment">//这个信号大家一定很熟悉，我们经常在命令行敲的kill -1 1就是这个信号，重新载入inittab</span></span></li>
<li class="alt"><span>    {</span></li>
<li><span>        oldlevel = runlevel;</span></li>
<li class="alt"><span>        </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (runlevel == </span><span class="string"><span style="color: #a31515;">&#8216;U&#8217;</span></span><span>) {</span></li>
<li><span>            runlevel = oldlevel;</span></li>
<li class="alt"><span>            re_exec();</span></li>
<li><span>        } </span><span class="keyword"><strong><span style="color: #0000ff;">else</span></strong></span><span> {</span></li>
<li class="alt"><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (oldlevel != </span><span class="string"><span style="color: #a31515;">&#8216;S&#8217;</span></span><span> &amp;&amp; runlevel == </span><span class="string"><span style="color: #a31515;">&#8216;S&#8217;</span></span><span>) console_stty();</span></li>
<li><span>            </span><span class="keyword"><strong><span style="color: #0000ff;">if</span></strong></span><span> (runlevel == </span><span class="string"><span style="color: #a31515;">&#8217;6&#8242;</span></span><span> || runlevel == </span><span class="string"><span style="color: #a31515;">&#8217;0&#8242;</span></span><span> ||</span></li>
<li class="alt"><span>                runlevel == </span><span class="string"><span style="color: #a31515;">&#8217;1&#8242;</span></span><span>) console_stty();</span></li>
<li><span>            read_inittab();</span></li>
<li class="alt"><span>            fail_cancel();</span></li>
<li><span>            setproctitle(</span><span class="string"><span style="color: #a31515;">“init [%c]“</span></span><span>, runlevel);</span></li>
<li class="alt"><span>            DELSET(got_signals, SIGHUP);</span></li>
<li><span>        }</span></li>
<li class="alt"><span>    }</span></li>
<li><span>  }</span></li>
<li class="alt"><span>&#8230;&#8230;</span></li>
<li><span>}</span></li>
</ol>
</div>
<p>上面函数不短，但是做事逻辑很清晰，比如清除了WAITING后，在start_if_needed中就可以继续往下进行了。<br />
  这样，整个代码大体逻辑就分析完了，通读代码，并没有发现/etc/rc.d等信息，实际上这些都是在inittab中约定好的，你只要按照inittab的格式写脚本就可以了，如果不按inittab规则写的话系统就可能起不来了，因为init程序定义了inittab的解析规则，这是一种机制和策略分离的体现，机制就是inittab的规则，包括运行级别的概念，而策略完全可以在inittab中调用的脚本中体现，但是有人会问定义如此一个inittab规则是不是机制和策略的耦合性过大了，你完全可以这么说，耦合性过大可能不好，但是读完我的下一篇文章了解到bsd的init程序后你可能会认为耦合性过小也不是什么好事，所以耦合性多大为宜是很难界定的。</p>
<p>来自:http://blog.csdn.net/dog250/archive/2008/11/12/3279772.aspx</p>
<p><!--more--></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ptubuntu.com%2F2008%2F12%2F780.html&amp;title=System%20V%E7%9A%84%E5%90%AF%E5%8A%A8%E9%A3%8E%E6%A0%BC%E5%92%8CBSD%E7%9A%84%E5%90%AF%E5%8A%A8%E9%A3%8E%E6%A0%BC%281%29%26%238212%3B%E4%BB%A3%E7%A0%81%E8%A7%92%E5%BA%A6" id="wpa2a_8"><img src="http://www.ptubuntu.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ptubuntu.com/2008/12/780.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FreeBSD + Postfix &amp; Maildir + Courier-imap + Squirrelmail</title>
		<link>http://www.ptubuntu.com/2008/12/625.html</link>
		<comments>http://www.ptubuntu.com/2008/12/625.html#comments</comments>
		<pubDate>Tue, 02 Dec 2008 08:43:49 +0000</pubDate>
		<dc:creator>ptubuntu</dc:creator>
				<category><![CDATA[Mail]]></category>
		<category><![CDATA[Unix]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[Mail(postfix&sendmail)]]></category>
		<category><![CDATA[技术类]]></category>

		<guid isPermaLink="false">http://www.ptubuntu.com/?p=625</guid>
		<description><![CDATA[Description :         小弟於 FreeBSD 上安裝 Postfix + Courier-imap + Squirrelmail 郵件伺服器，採取 Maildir 的架構將使用者的信件分門別類的放置在 /home/User/Maildir 目錄下，有別於過去傳統所採用的 MailBox 方式，它是將 Mail 堆疊於 /var/spool/User 下。         過去我一直使用 MailBox 的方式將郵件堆疊到 /var/spool/User 上，這樣的方式有個蠻大的缺點，就是當使用者的郵件空間容量擴大時，你想看看會發生甚麼狀況？當單一檔案超過 1G 時必定造成 Mial Server 整體效能的下降，以及接收郵件時若突然斷線或中斷時 Mail 又得重新再接收一次，看來這樣的架構似乎已經不符合現今的需求，因此我改採 Maildir 的方式來架設 Mail Server，讓每一封郵件都獨立為單一檔案存放於自己的家目錄下，便可提高 Mail Server 的效能以及無限擴充郵件使用者的空間。         Courier-imap 是一套預設就支援 Maildir 的 pop3 及 imap 軟體，它也同時支援 pop3s 及 imaps 這兩個 [...]]]></description>
			<content:encoded><![CDATA[<p><strong><span style="font-size: x-small; color: #990000; font-family: Helvetica;">Description :<br />
</span></strong><small style="font-family: Helvetica,Arial,sans-serif;"><br />
<span style="font-size: x-small;">        小弟於 <a href="http://www.ptubuntu.com/tag/freebsd" class="st_tag internal_tag" rel="tag" title="标签 freebsd 下的日志">FreeBSD</a> 上安裝 Postfix + Courier-imap + Squirrelmail 郵件伺服器，採取 Maildir 的架構將使用者的信件分門別類的放置在 /home/User/Maildir 目錄下，有別於過去傳統所採用的 MailBox 方式，它是將 Mail 堆疊於 /var/spool/User 下。</p>
<p>        過去我一直使用 MailBox 的方式將郵件堆疊到 /var/spool/User 上，這樣的方式有個蠻大的缺點，就是當使用者的郵件空間容量擴大時</span></small><span style="font-size: x-small;"><small style="font-family: Helvetica,Arial,sans-serif;">，</small><small style="font-family: Helvetica,Arial,sans-serif;">你想看看會發生甚麼狀況？當單一檔案超過 1G 時必定造成 Mial Server 整體效能的下降，以及接收郵件時若突然斷線或中斷</small><small style="font-family: Helvetica,Arial,sans-serif;">時 Mail 又得重新再接收一次</small><small style="font-family: Helvetica,Arial,sans-serif;">，看來</small><small style="font-family: Helvetica,Arial,sans-serif;">這樣的架構似乎已經不符合現今的需求</small><small style="font-family: Helvetica,Arial,sans-serif;">，因此我改採 Maildir 的方式來架設 Mail Server</small><small style="font-family: Helvetica,Arial,sans-serif;">，</small><small style="font-family: Helvetica,Arial,sans-serif;">讓每一封郵件都獨立為單一檔案存放於自己的家目錄下</small><small style="font-family: Helvetica,Arial,sans-serif;">，便可提高 Mail Server 的效能以及無限擴充郵件使用者的空間</small></span><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-size: x-small;">。<br />
<span id="more-625"></span><br />
        Courier-imap 是一套預設就支援 Maildir 的 pop3 及 imap 軟體，它也同時支援 pop3s 及 imaps 這兩個 Service，因此 Mail Server 在選擇使用 Maildir 架構時，我們當然首選 Courier-imap 摟。</span></small><small style="font-family: Helvetica,Arial,sans-serif;"></p>
<p></small><span style="font-size: x-small;"><small><span class="content"><strong>Environment :</strong></span></small><br />
</span><small style="font-family: Helvetica,Arial,sans-serif;"><br />
</small><small><span class="content" style="font-size: x-small;">            硬體：</span></small><span style="font-size: x-small;"><small style="font-family: Helvetica,Arial,sans-serif;">i386 PC Intel P3 500<br />
</small><small><span class="content">            記憶體網卡：</span></small></span><span style="font-size: x-small;"><small style="font-family: Helvetica,Arial,sans-serif;">512M RAM <br />
</small><small><span class="content">            作業系統：</span></small></span><span style="font-size: x-small;"><small style="font-family: Helvetica,Arial,sans-serif;">FreeBSD 6.0 Release</p>
<p></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-weight: bold; color: #990000;">Setp 1. Installing Postfix</span></small><br />
</span><small style="font-family: Helvetica,Arial,sans-serif;"><br />
<span style="font-weight: bold; color: #000099;"><span style="font-size: x-small;">#vi /etc/rc.conf        </span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-size: x-small;">#  拿掉預設啟動 sendmail</span></small><small style="font-family: Helvetica,Arial,sans-serif;"></p>
<p><span style="font-size: x-small;"><span style="color: #006600;">sendmail_enable=”NONE”</span><br />
<br style="color: #000099;" /><span style="font-weight: bold; color: #000099;">#cd /usr/ports/mail/postfix</span><br style="font-weight: bold; color: #000099;" /><span style="font-weight: bold; color: #000099;">#make install</span></p>
<p><span style="font-weight: bold; color: #000099;">#vi /usr/local/etc/postfix/main.cf</span></p>
<p><span style="color: #006600;">myhostname = ms2.ntut.idv.tw</span><br style="color: #006600;" /><span style="color: #006600;">mydomain = ntut.idv.tw</span><br style="color: #006600;" /><span style="color: #006600;">alias_maps = hash:/usr/local/etc/postfix/aliases    <span style="color: #000000;"> # aliase 別名是一定要設的</span></span><br style="color: #006600;" /><span style="color: #006600;">home_mailbox = Maildir/       <span style="color: #000000;"> #  改用 Maildir 格式存放 mail</span></span></span></small><span style="font-size: x-small;"><small style="font-family: Helvetica,Arial,sans-serif;"><span style="color: #006600;"><span style="color: #000000;"> 當</span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="color: #006600;"><span style="color: #000000;">開啟這行時</span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="color: #006600;"><span style="color: #000000;">，</span></span></small></span><span style="font-size: x-small;"><small style="font-family: Helvetica,Arial,sans-serif;"><span style="color: #006600;"><span style="color: #000000;">若使用者收到第一封 mail 時會就會自動產生 /home/User/Maildir 目錄及 new tmp cur 這三個資料夾</span></span><br style="color: #006600;" /><br style="color: #006600;" /><span style="color: #006600;">disable_vrfy_command = yes    <span style="color: #000000;">#  防止別人測試你的本機郵件用戶是否存在</span>    </span><br style="color: #006600;" /><span style="color: #006600;">mailbox_size_limit = 2048000000       <span style="color: #000000;"># mailbox 的空間大小限制 2G </span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="color: #006600;"><span style="color: #000000;">，</span></span></small></span><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-size: x-small;"><span style="color: #006600;"><span style="color: #000000;">也可以使用 disk quota 來限制</span></span><br style="color: #006600;" /><span style="color: #006600;">smtpd_recipient_limit =300    <span style="color: #000000;">#  對同一封郵件的收件人數目限制，最多同一封信件可發給 300 人</span></span><br style="color: #006600;" /><span style="color: #006600;">message_size_limit = 10240000      <span style="color: #000000;"># 單一信件最大容量 10M</span></span><br />
<br style="font-weight: bold; color: #000099;" /><span style="font-weight: bold; color: #000099;">#postalias /usr/local/etc/postfix/aliases        </span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-size: x-small;">#  產生 aliases.db 檔<br />
</span></small><small style="font-family: Helvetica,Arial,sans-serif;"><br />
<span style="font-weight: bold; color: #000099;"><span style="font-size: x-small;">#exit        </span></span></small><span style="font-size: x-small;"><small style="font-family: Helvetica,Arial,sans-serif;"># 先跳出再進入 root 才可不指定路徑直接 start postfix</small><br />
</span><span style="font-size: x-small;"><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-weight: bold; color: #000099;">$su<br />
#posfix start        </span></small><small style="font-family: Helvetica,Arial,sans-serif;"># 手動開啟 postfix 25 port 服務</small></span><small style="font-family: Helvetica,Arial,sans-serif;"><br />
</small><small style="font-family: Helvetica,Arial,sans-serif;"></p>
<p></small><span style="font-size: x-small;"><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-weight: bold; color: #990000;">Setp 2. Installing Courier-imap</span></small><br />
</span><small style="font-family: Helvetica,Arial,sans-serif;"><br />
<span style="font-weight: bold; color: #000099;"><span style="font-size: x-small;">#cd /usr/ports/mail/courier-imap        </span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-size: x-small;">#   因為採用 FreeBSD 本機上的帳號及密碼認證所以不選其他種類的 AUTH</span></small><small style="font-family: Helvetica,Arial,sans-serif;"><br style="font-weight: bold; color: #000099;" /><span style="font-size: x-small;"><span style="font-weight: bold; color: #000099;">#make install</span></p>
<p><span style="color: #663366;">       Options for courier-imap 4.0.6_1,1 </span><br style="color: #663366;" /><br style="color: #663366;" /><span style="color: #663366;"> [X] OPENSSL      Build with OpenSSL support  </span><br style="color: #663366;" /><span style="color: #663366;"> [ ] FAM          Build in fam support for IDLE command </span><br style="color: #663366;" /><span style="color: #663366;"> [ ] TRASHQUOTA   Include deleted mails in the quota  </span><br style="color: #663366;" /><span style="color: #663366;"> [ ] GDBM         Use gdbm db instead of <a href="http://www.ptubuntu.com/tag/system" class="st_tag internal_tag" rel="tag" title="标签 system 下的日志">system</a> bdb </span><br style="color: #663366;" /><span style="color: #663366;"> [ ] IPV6         Build with IPv6 support  </span><br style="color: #663366;" /><span style="color: #663366;"> [ ] AUTH_LDAP    LDAP support </span><br style="color: #663366;" /><span style="color: #663366;"> [ ] AUTH_MYSQL   MySQL support </span><br style="color: #663366;" /><span style="color: #663366;"> [ ] AUTH_PGSQL   PostgreSQL support </span><br style="color: #663366;" /><span style="color: #663366;"> [ ] AUTH_USERDB  Userdb support </span><br style="color: #663366;" /><span style="color: #663366;"> [ ] AUTH_VCHKPW  Vpopmail/vchkpw support </span></p>
<p><span style="font-weight: bold; color: #000099;">#cd /usr/local/etc/courier-imap</span><br style="font-weight: bold; color: #000099;" /><span style="font-weight: bold; color: #000099;">#cp pop3d.cnf.dist pop3d.cnf</span><br style="font-weight: bold; color: #000099;" /><span style="font-weight: bold; color: #000099;">#cp imapd.cnf.dist imapd.cnf        </span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-size: x-small;">#   設定 cert 的內容以方便我們產生 ssl 加密認證，如果不使用 imaps 993 port 或 pop3s 995 port 可省掉這個動作</span></small><small style="font-family: Helvetica,Arial,sans-serif;"></p>
<p><span style="font-size: x-small;"><span style="color: #006600;">RANDFILE = /usr/local/share/courier-imap/pop3d.rand</span><br style="color: #006600;" /><br style="color: #006600;" /><span style="color: #006600;">[ req ]</span><br style="color: #006600;" /><span style="color: #006600;">default_bits = 1024</span><br style="color: #006600;" /><span style="color: #006600;">encrypt_key = yes</span><br style="color: #006600;" /><span style="color: #006600;">distinguished_name = req_dn</span><br style="color: #006600;" /><span style="color: #006600;">x509_extensions = cert_type</span><br style="color: #006600;" /><span style="color: #006600;">prompt = no</span></p>
<p><span style="color: #006600;">The [ req_dn ] should look like: </span><br style="color: #006600;" /><br style="color: #006600;" /><span style="color: #006600;">    [ req_dn ]</span><br style="color: #006600;" /><span style="color: #006600;">    C=countryName Two letters!</span><br style="color: #006600;" /><span style="color: #006600;">    ST=stateOrProvinceName</span><br style="color: #006600;" /><span style="color: #006600;">    L=localityName</span><br style="color: #006600;" /><span style="color: #006600;">    O=organizationName</span><br style="color: #006600;" /><span style="color: #006600;">    OU=OrganizationalUnitName</span><br style="color: #006600;" /><span style="color: #006600;">    CN=commonName</span><br style="color: #006600;" /><span style="color: #006600;">    emailAddress=emailAddress</span></p>
<p><span style="color: #006600;">[ cert_type ]</span><br style="color: #006600;" /><span style="color: #006600;">nsCertType = server</span></p>
<p><span style="font-weight: bold; color: #000099;">#/usr/local/sbin/mkimapdcert        </span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-size: x-small;">#   產生安全登入認證的 imapd.pem 及 pop3d.pem 檔放置於 /usr/local/share/courier-iamp 下</span></small><small style="font-family: Helvetica,Arial,sans-serif;"><br style="font-weight: bold; color: #000099;" /><span style="font-size: x-small;"><span style="font-weight: bold; color: #000099;">#/usr/local/sbin/mkpop3dcert</span></p>
<p><span style="font-weight: bold; color: #000099;">#vi /etc/rc.conf        </span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-size: x-small;">#  設定預設開機啟動程式</span></small><small style="font-family: Helvetica,Arial,sans-serif;"></p>
<p><span style="font-size: x-small;"><span style="color: #006600;">postfix_enable=”YES”</span><br style="color: #006600;" /><span style="color: #006600;">courier_authdaemond_enable=”YES”</span><br style="color: #006600;" /><span style="color: #006600;">courier_imap_pop3d_enable=”YES”</span><br style="color: #006600;" /><span style="color: #006600;">courier_imap_imapd_enable=”YES”</span><br style="color: #006600;" /><span style="color: #006600;">courier_imap_imapd_ssl_enable=”YES”</span><br style="color: #006600;" /><span style="color: #006600;">courier_imap_pop3d_ssl_enable=”YES”</span></p>
<p><span style="font-weight: bold; color: #000099;">#reboot        </span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-size: x-small;">#   重開機</span></small><small style="font-family: Helvetica,Arial,sans-serif;"></p>
<p><span style="font-weight: bold; color: #000099;"><span style="font-size: x-small;"># sockstat -l4        </span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-size: x-small;">#  測試所開啟的服務<br />
</span></small><small style="font-family: Helvetica,Arial,sans-serif;"><br />
<span style="font-size: x-small;"><span style="color: #663366;">USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      </span><br style="color: #663366;" /><span style="color: #663366;">root     master     520   11 tcp4   *:25                  *:*</span><br style="color: #663366;" /><span style="color: #663366;">root     couriertcp 454   3  tcp4   *:110                 *:*</span><br style="color: #663366;" /><span style="color: #663366;">root     couriertcp 443   3  tcp4   *:995                 *:*</span><br style="color: #663366;" /><span style="color: #663366;">root     couriertcp 432   3  tcp4   *:143                 *:*</span><br style="color: #663366;" /><span style="color: #663366;">root     couriertcp 420   3  tcp4   *:993                 *:*</span><br style="color: #663366;" /><span style="color: #663366;">root     sshd       377   4  tcp4   *:22                  *:*</span><br style="color: #663366;" /><span style="color: #663366;">root     syslogd    264   6  udp4   *:514                 *:*</span></p>
<p><span style="font-weight: bold; color: #000099;">#telnet localhost 110        </span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-size: x-small;">#  測試 pop3 110 port 有無啟動，及使用者可否登入</span></small><small style="font-family: Helvetica,Arial,sans-serif;"><br />
<span style="font-size: x-small;"><span style="font-weight: bold; color: #000099;">&gt;user jim</span><br style="font-weight: bold; color: #000099;" /><span style="font-weight: bold; color: #000099;">&gt;pass xxxx</span><br style="font-weight: bold; color: #000099;" /><span style="font-weight: bold; color: #000099;">&gt;list</span><br style="font-weight: bold; color: #000099;" /><span style="font-weight: bold; color: #000099;">&gt;stat</span><br style="font-weight: bold; color: #000099;" /><span style="font-weight: bold; color: #000099;">&gt;quit</span><br />
<span style="color: #663366;">+OK Bye-bye.</span></p>
<p></span></small><span style="font-size: x-small;"><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-weight: bold; color: #990000;">Setp 3. Installing Apache2 + PHP4 +SquirrelMail</span></small><br />
</span><small style="font-family: Helvetica,Arial,sans-serif;"><br />
<span style="font-weight: bold; color: #000099;"><span style="font-size: x-small;">#cd /usr/ports/www/apache2        </span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-size: x-small;">#  詳細的設定就不再贅述請參考 </span><a href="http://www.ptubuntu.com/wp-admin/apache21_mysql41_php4.html"><span style="font-size: x-small;">Apache20 + MySQL41 + PHP4</span></a><span style="font-size: x-small;"> </span></small><br />
<small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-weight: bold; color: #000099;"><span style="font-size: x-small;">#make install</span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><br />
</small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-weight: bold; color: #000099;"><span style="font-size: x-small;">#cd /usr/ports/www/php4<br />
#make install</span></span><span style="font-weight: bold; color: #000099;"><br />
<span style="font-size: x-small;">#cd /usr/ports/www/php4-extension<br />
#make install<br />
</span></span><br />
<span style="font-size: x-small;"><span style="font-weight: bold; color: #000099;">#cd /usr/ports/mail/squirrelmail</span><br style="font-weight: bold; color: #000099;" /><span style="font-weight: bold; color: #000099;">#make install</span></p>
<p><span style="font-weight: bold; color: #000099;">#cd /usr/local/www/data-dist</span><br style="font-weight: bold; color: #000099;" /><span style="font-weight: bold; color: #000099;">#ln -s ../squirrelmail  webmail        </span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-size: x-small;"># 建立 webmail 連結檔</span></small><small style="font-family: Helvetica,Arial,sans-serif;"><br style="font-weight: bold; color: #000099;" /><span style="font-size: x-small;"><span style="font-weight: bold; color: #000099;">#cd webmail</span><br style="font-weight: bold; color: #000099;" /><span style="font-weight: bold; color: #000099;">#./configure        </span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-size: x-small;">#  開始設定你的 config.php 檔</span></small><small style="font-family: Helvetica,Arial,sans-serif;"></p>
<p><span style="font-size: x-small;"><span style="color: #663366;">SquirrelMail Configuration : Read: config.php (1.4.0)</span><br style="color: #663366;" /><span style="color: #663366;">&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</span><br style="color: #663366;" /><span style="color: #663366;">Main Menu &#8211;</span><br style="color: #663366;" /><span style="color: #663366;">1.  Organization Preferences</span><br style="color: #663366;" /><span style="color: #663366;">2.  Server Settings</span><br style="color: #663366;" /><span style="color: #663366;">3.  Folder Defaults</span><br style="color: #663366;" /><span style="color: #663366;">4.  General Options</span><br style="color: #663366;" /><span style="color: #663366;">5.  Themes</span><br style="color: #663366;" /><span style="color: #663366;">6.  Address Books</span><br style="color: #663366;" /><span style="color: #663366;">7.  Message of the Day (MOTD)</span><br style="color: #663366;" /><span style="color: #663366;">8.  Plugins</span><br style="color: #663366;" /><span style="color: #663366;">9.  Database</span><br style="color: #663366;" /><span style="color: #663366;">10. Languages</span><br style="color: #663366;" /><br style="color: #663366;" /><span style="color: #663366;">D.  Set pre-defined settings for specific IMAP servers</span><br style="color: #663366;" /><br style="color: #663366;" /><span style="color: #663366;">C   Turn color on</span><br style="color: #663366;" /><span style="color: #663366;">S   Save data</span><br style="color: #663366;" /><span style="color: #663366;">Q   Quit</span><br style="color: #663366;" /><br style="color: #663366;" /><span style="color: #663366;">Command &gt;&gt; </span></p>
<p> <span style="font-weight: bold; color: #000099;">http://ms2.ntut.idv.tw/webmail/</span>           #  開個 Browse 輸入上面的路徑即可進入小松鼠 webmail 的登入畫面</p>
<p></span></small><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-weight: bold; color: #990000;"><span style="font-size: x-small;">Reference：</span></span></small><small style="font-family: Helvetica,Arial,sans-serif;"></p>
<p><a href="http://ezine.daemonnews.org/200308/courier-imap.html"><span style="font-size: x-small;">http://ezine.daemonnews.org/200308/courier-imap.html</span></a><br />
<a href="http://www.inter7.com/courierimap.html"><span style="font-size: x-small;">http://www.inter7.com/courierimap.html </span></a><br />
<a href="http://www.asdf.dk/text/mbox2maildir.html"><span style="font-size: x-small;">http://www.asdf.dk/text/mbox2maildir.html</span></a><span style="font-size: x-small;"><br />
</span><a href="http://karmak.org/2003/courier-imap/"><span style="font-size: x-small;">http://karmak.org/2003/courier-imap/</span></a><br />
<a href="http://mutt.sourceforge.net/imap/"><span style="font-size: x-small;">http://mutt.sourceforge.net/imap/</span></a></p>
<p></small><span style="font-size: x-small;"><small style="font-family: Helvetica,Arial,sans-serif;"><span style="font-weight: bold; color: #990000;">Add：</span></small><br />
</span><small style="font-family: Helvetica,Arial,sans-serif;"><br />
<span style="font-size: x-small;">若出現 Webmail 無法登入可能是還未產生 /home/User/Maildir 也可以手動製作 User 的 Maildir/</p>
<p><span style="font-weight: bold; color: #000099;"># cd /home/User</span><br style="font-weight: bold; color: #000099;" /><span style="font-weight: bold; color: #000099;"># maildirmake Maildir</span><br style="font-weight: bold; color: #000099;" /><span style="font-weight: bold; color: #000099;"># chown -R User:User Maildir</span><br style="font-weight: bold; color: #000099;" /><span style="font-weight: bold; color: #000099;"># chmod -R 750 Maildir</span></span></p>
<p> 来自:http://freebsd.ntut.idv.tw/document/postfix_maildir_courier-iamp_squirrelmail.html</p>
<p><!--more--></small></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ptubuntu.com%2F2008%2F12%2F625.html&amp;title=FreeBSD%20%2B%20Postfix%20%26%23038%3B%20Maildir%20%2B%20Courier-imap%20%2B%20Squirrelmail" id="wpa2a_10"><img src="http://www.ptubuntu.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ptubuntu.com/2008/12/625.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Freebsd 下加入新 ip</title>
		<link>http://www.ptubuntu.com/2008/11/307.html</link>
		<comments>http://www.ptubuntu.com/2008/11/307.html#comments</comments>
		<pubDate>Tue, 04 Nov 2008 16:47:36 +0000</pubDate>
		<dc:creator>ruijin</dc:creator>
				<category><![CDATA[Linux Server]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[ip]]></category>
		<category><![CDATA[技术类]]></category>

		<guid isPermaLink="false">http://blog.ptubuntu.com/?p=307</guid>
		<description><![CDATA[在一些特殊情況下，需要在同一張 lan card 上多加一個 ip address，在 Freebsd 下的實現方法如下:(假設 lan card 是 rl0，原有的 ip 是 192.168.1.100，新加入的 ip 是 192.168.1.101)

1. 開啟 /etc/rc.conf 並加上:

]]></description>
			<content:encoded><![CDATA[<div class="post-content">
<p>在一些特殊情況下，需要在同一張 lan card 上多加一個 <a href="http://www.ptubuntu.com/tag/ip" class="st_tag internal_tag" rel="tag" title="标签 ip 下的日志">ip</a> address，在 <a href="http://www.ptubuntu.com/tag/freebsd" class="st_tag internal_tag" rel="tag" title="标签 freebsd 下的日志">Freebsd</a> 下的實現方法如下:(假設 lan card 是 rl0，原有的 <a href="http://www.ptubuntu.com/tag/ip" class="st_tag internal_tag" rel="tag" title="标签 ip 下的日志">ip</a> 是 192.168.1.100，新加入的 <a href="http://www.ptubuntu.com/tag/ip" class="st_tag internal_tag" rel="tag" title="标签 ip 下的日志">ip</a> 是 192.168.1.101)</p>
<p>1. 開啟 /etc/rc.conf 並加上:<br />
<code><br />
ifconfig_rl0_alias0="inet 192.168.1.101 netmask 255.255.255.255"<br />
</code><br />
alias0 是加裝的第一個 ip，如要加裝更多 ip 便順序使用 alias1, alias2 等。</p>
<p>2. 執行 /etc/netstart 來重新啟動 lan card 即可。</p>
<p>来自:http://www.real-blog.com</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.ptubuntu.com/2008/11/307.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>恢复 FreeBSD 的 root 密码</title>
		<link>http://www.ptubuntu.com/2008/11/297.html</link>
		<comments>http://www.ptubuntu.com/2008/11/297.html#comments</comments>
		<pubDate>Tue, 04 Nov 2008 16:20:31 +0000</pubDate>
		<dc:creator>ruijin</dc:creator>
				<category><![CDATA[Linux Server]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[root 密码]]></category>
		<category><![CDATA[技术类]]></category>

		<guid isPermaLink="false">http://blog.ptubuntu.com/?p=297</guid>
		<description><![CDATA[当在 FreeBSD 忘记了 root 密码时，可以在开机时进入 single user mode 及重新设定密码，方法如下: 1. 重新开啟 FreeBSD 主机。 2. 在 “Welcome to FreeBSD!” 开啟选单中按 “4&#8243; 选择 “Boot FreeBSD in single user mode”。 3. 然后会看到 “When prompted Enter full pathname of shell or RETURN for /bin/sh:”，直接按 Enter。 4. 这时便会直接进入 single user mode，输入以下指令重新掛载根目录 “/” 为可读写: # mount -u / # mount -a [...]]]></description>
			<content:encoded><![CDATA[<p>当在 <a href="http://www.ptubuntu.com/tag/freebsd" class="st_tag internal_tag" rel="tag" title="标签 freebsd 下的日志">FreeBSD</a> 忘记了 root 密码时，可以在开机时进入 single user mode 及重新设定密码，方法如下:<br />
1. 重新开啟 FreeBSD 主机。</p>
<p>2. 在 “Welcome to FreeBSD!” 开啟选单中按 “4&#8243; 选择 “Boot FreeBSD in single user mode”。</p>
<p>3. 然后会看到 “When prompted Enter full pathname of shell or RETURN for /bin/sh:”，直接按 Enter。</p>
<p>4. 这时便会直接进入 single user mode，输入以下指令重新掛载根目录 “/” 为可读写:</p>
<p># mount -u /<br />
# mount -a</p>
<p>5. 用 passwd 重新设定 <a href="http://www.ptubuntu.com/tag/root-%e5%af%86%e7%a0%81" class="st_tag internal_tag" rel="tag" title="标签 root 密码 下的日志">root 密码</a>:</p>
<p># passwd</p>
<p>6. 最后重新啟动即可:</p>
<p># sync;sync;sync;reboot<br />
来源:<a href="http://www.real-blog.com/linux-bsd-notes/399">http://www.real-blog.com/linux-bsd-notes/399</a></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ptubuntu.com%2F2008%2F11%2F297.html&amp;title=%E6%81%A2%E5%A4%8D%20FreeBSD%20%E7%9A%84%20root%20%E5%AF%86%E7%A0%81" id="wpa2a_12"><img src="http://www.ptubuntu.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ptubuntu.com/2008/11/297.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

