<?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>Dada's Blog &#187; 電腦資訊</title>
	<atom:link href="http://blog.urdada.net/category/comp/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.urdada.net</link>
	<description>Just for fun</description>
	<lastBuildDate>Fri, 13 Jan 2012 09:14:11 +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>噗浪機器人範例程式 - 使用 Plurk API 2.0</title>
		<link>http://blog.urdada.net/2011/10/28/426/</link>
		<comments>http://blog.urdada.net/2011/10/28/426/#comments</comments>
		<pubDate>Fri, 28 Oct 2011 09:04:27 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[軟體]]></category>
		<category><![CDATA[網路科技]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/?p=426</guid>
		<description><![CDATA[這篇文章說明如何用 Plurk API 2.0 自己寫一個噗浪機器人 (本文同步發表於 噗浪官方部落格) 噗浪大部分的機器人仍然使用 Plurk 1.0 撰寫，甚至有一部分機器人使用的是非官方的 API，這篇文章將簡介如何使用 Plurk API 2.0 OAuth 的方式開發機器人程式，同時，這個範例也使用 Plurk Realtime API (Comet Push) 的方式來追蹤時間軸，避免給伺服器帶來過多的負擔 由於 Plurk API 2.0 使用 OAuth 方式，所以啟動機器人之前，您必須先獲得以下四個參數 App Key App Secret Access Token Access Token Secret 獲得 App Key 及 App Secret 的方式很簡單，首先先註冊一個新的噗浪帳號用來跑這個機器人，然後登入新帳號後，開啟以下這個連結： http://www.plurk.com/PlurkApp/ 按下「註冊新的應用服務」，填寫關於你的程式的資料，其中 OAuth callback 保持空白即可 註冊完畢後就可以看到你的應用程式列表 然後按下「編輯」這個按鈕，就可以看到以下畫面： 這邊我們就可以得到 App [...]]]></description>
			<content:encoded><![CDATA[<p>這篇文章說明如何用 <a href="http://www.plurk.com/API" target="_blank">Plurk API 2.0</a> 自己寫一個噗浪機器人</p>
<p>(本文同步發表於 <a href="http://zh.blog.plurk.com/" title="噗浪官方部落格" target="_blank">噗浪官方部落格</a>)</p>
<p>噗浪大部分的機器人仍然使用 Plurk 1.0 撰寫，甚至有一部分機器人使用的是非官方的 API，這篇文章將簡介如何使用 Plurk API 2.0 OAuth 的方式開發機器人程式，同時，這個範例也使用 Plurk Realtime API (Comet Push) 的方式來追蹤時間軸，避免給伺服器帶來過多的負擔</p>
<p>由於 Plurk API 2.0 使用 OAuth 方式，所以啟動機器人之前，您必須先獲得以下四個參數</p>
<ul>
<li>App Key</li>
<li>App Secret</li>
<li>Access Token</li>
<li>Access Token Secret</li>
</ul>
<p>獲得 App Key 及 App Secret 的方式很簡單，首先先註冊一個新的噗浪帳號用來跑這個機器人，然後登入新帳號後，開啟以下這個連結：</p>
<p><a href="http://www.plurk.com/PlurkApp/" target="_blank">http://www.plurk.com/PlurkApp/</a></p>
<p>按下「註冊新的應用服務」，填寫關於你的程式的資料，其中 OAuth callback 保持空白即可</p>
<p><a href="http://blog.urdada.net/wp-content/uploads/2011/10/bot-11.png" rel="lightbox[426]"><img src="http://blog.urdada.net/wp-content/uploads/2011/10/bot-11.png" alt="" title="註冊新的應用服務" width="511" height="392" class="alignnone size-full wp-image-435" /></a></p>
<p>註冊完畢後就可以看到你的應用程式列表</p>
<p><a href="http://blog.urdada.net/wp-content/uploads/2011/10/bot-2.png" rel="lightbox[426]"><img src="http://blog.urdada.net/wp-content/uploads/2011/10/bot-2.png" alt="" title="應用程式列表" width="471" height="113" class="alignnone size-full wp-image-437" /></a></p>
<p>然後按下「編輯」這個按鈕，就可以看到以下畫面：</p>
<p><a href="http://blog.urdada.net/wp-content/uploads/2011/10/bot-3.png" rel="lightbox[426]"><img src="http://blog.urdada.net/wp-content/uploads/2011/10/bot-3.png" alt="" title="應用程式資料" width="511" height="214" class="alignnone size-full wp-image-439" /></a></p>
<p>這邊我們就可以得到 App Key 以及 App Secret 了</p>
<p>接下來要進行 OAuth 的授權驗證來取得 Access Token 及 Access Token Secret</p>
<p>按下「測試工具」來開啟 OAuth 的 Test Console</p>
<p><a href="http://blog.urdada.net/wp-content/uploads/2011/10/bot-4.png" rel="lightbox[426]"><img src="http://blog.urdada.net/wp-content/uploads/2011/10/bot-4.png" alt="" title="Test Console" width="834" height="156" class="alignnone size-full wp-image-441" /></a></p>
<p>首先按下「Get Request Token」來取得暫時的 Request Token，<br />
接下來按下「Open Authorization URL」來開啟授權頁面：</p>
<p><a href="http://blog.urdada.net/wp-content/uploads/2011/10/bot-5.png" rel="lightbox[426]"><img src="http://blog.urdada.net/wp-content/uploads/2011/10/bot-5.png" alt="" title="授權" width="405" height="230" class="alignnone size-full wp-image-442" /></a></p>
<p>按下「是，我要授權」後，會得到一個認證碼：</p>
<p><a href="http://blog.urdada.net/wp-content/uploads/2011/10/bot-6.png" rel="lightbox[426]"><img src="http://blog.urdada.net/wp-content/uploads/2011/10/bot-6.png" alt="" title="認證碼" width="212" height="111" class="alignnone size-full wp-image-444" /></a></p>
<p>把這個六位數的認證碼記下來，然後回到 Test Console，<br />
按下「Get Access Token」，這時會提示您輸入認證碼</p>
<p><a href="http://blog.urdada.net/wp-content/uploads/2011/10/bot-7.png" rel="lightbox[426]"><img src="http://blog.urdada.net/wp-content/uploads/2011/10/bot-7.png" alt="" title="Get Access Token" width="426" height="172" class="alignnone size-full wp-image-445" /></a></p>
<p>把您剛剛記下來的數字填進去，按下「確定」後，<br />
就可以得到永久有效的 Access Token 及 Access Token Secret 了</p>
<p><a href="http://blog.urdada.net/wp-content/uploads/2011/10/bot-8.png" rel="lightbox[426]"><img src="http://blog.urdada.net/wp-content/uploads/2011/10/bot-8.png" alt="" title="所有需要的參數" width="360" height="121" class="alignnone size-full wp-image-446" /></a></p>
<p>然後你就可以開始寫程式了，下面是一個用 Python 寫的噗浪機器人，<br />
把其中 APP_KEY, APP_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET 置換掉即可</p>
<p>這個程式需要使用到 <a href="https://github.com/clsung/plurk-oauth" target="_blank">plurk-oauth</a> 這個 Python library，<br />
請把 plurk_oauth/ 這個目錄下的檔案下載回來跟你的程式放在一起就可以了</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/python</span>
<span style="color: #808080; font-style: italic;"># -*- coding:utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span>
<span style="color: #ff7700;font-weight:bold;">import</span> json
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib2</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> PlurkAPI <span style="color: #ff7700;font-weight:bold;">import</span> PlurkAPI
&nbsp;
plurk = PlurkAPI<span style="color: black;">&#40;</span><span style="color: #483d8b;">'APP_KEY'</span>, <span style="color: #483d8b;">'APP_SECRET'</span><span style="color: black;">&#41;</span>
plurk.<span style="color: black;">authorize</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'ACCEESS_TOKEN'</span>, <span style="color: #483d8b;">'ACCESS_TOKEN_SECRET'</span><span style="color: black;">&#41;</span>
&nbsp;
comet = plurk.<span style="color: black;">callAPI</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/APP/Realtime/getUserChannel'</span><span style="color: black;">&#41;</span>
comet_channel = comet.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'comet_server'</span><span style="color: black;">&#41;</span> + <span style="color: #483d8b;">&quot;&amp;new_offset=%d&quot;</span>
jsonp_re = <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'CometChannel.scriptCallback<span style="color: #000099; font-weight: bold;">\(</span>(.+)<span style="color: #000099; font-weight: bold;">\)</span>;<span style="color: #000099; font-weight: bold;">\s</span>*'</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
new_offset = -<span style="color: #ff4500;">1</span>
<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
    plurk.<span style="color: black;">callAPI</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/APP/Alerts/addAllAsFriends'</span><span style="color: black;">&#41;</span>
    req = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>comet_channel <span style="color: #66cc66;">%</span> new_offset, timeout=<span style="color: #ff4500;">80</span><span style="color: black;">&#41;</span>
    rawdata = req.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    match = jsonp_re.<span style="color: black;">match</span><span style="color: black;">&#40;</span>rawdata<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> match:
        rawdata = match.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
    data = json.<span style="color: black;">loads</span><span style="color: black;">&#40;</span>rawdata<span style="color: black;">&#41;</span>
    new_offset = data.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'new_offset'</span>, -<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
    msgs = data.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'data'</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> msgs:
        <span style="color: #ff7700;font-weight:bold;">continue</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> msg <span style="color: #ff7700;font-weight:bold;">in</span> msgs:
        <span style="color: #ff7700;font-weight:bold;">if</span> msg.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'type'</span><span style="color: black;">&#41;</span> == <span style="color: #483d8b;">'new_plurk'</span>:
            pid = msg.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'plurk_id'</span><span style="color: black;">&#41;</span>
            content = msg.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'content_raw'</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> content.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;hello&quot;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= -<span style="color: #ff4500;">1</span>:
                plurk.<span style="color: black;">callAPI</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/APP/Responses/responseAdd'</span>,
                              <span style="color: black;">&#123;</span><span style="color: #483d8b;">'plurk_id'</span>: pid,
                               <span style="color: #483d8b;">'content'</span>: <span style="color: #483d8b;">'world'</span>,
                               <span style="color: #483d8b;">'qualifier'</span>: <span style="color: #483d8b;">':'</span> <span style="color: black;">&#125;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>執行方式：</p>
<pre language="shell">
# python my-robot.py
</pre>
<p>這個範例程式作的事情很簡單，就是一個無窮迴圈，首先每次都會先接受所有成為朋友的請求，然後看看有沒有新的噗，如果有新的噗，而且內容有 'hello' 字串的話，就會自動回覆一個 'world' 字串</p>
<p>提醒大家，噗浪並不反對機器人的存在，但使用這個範例程式請注意以下幾點：</p>
<ol>
<li>建議使用新的帳號，不要用原有的帳號</li>
<li>機器人請勿主動去加網友為朋友</li>
<li>機器人請勿去關注(追蹤)任何其他網友</li>
<li>請勿自動回覆未成為機器人的朋友所發的噗</li>
<li>請勿張貼廣告訊息</li>
<li>請注意回覆頻率，以不過度干擾使用者的方式為原則</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2011/10/28/426/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>我愛用的免費軟體 (my favorite freeware)</title>
		<link>http://blog.urdada.net/2009/03/02/148/</link>
		<comments>http://blog.urdada.net/2009/03/02/148/#comments</comments>
		<pubDate>Mon, 02 Mar 2009 14:53:02 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[作業系統]]></category>
		<category><![CDATA[軟體]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/?p=148</guid>
		<description><![CDATA[最近已經快滿三年的 Thinkpad X60 跑得越來越慢，又常常當機，所以找個比較有空的時間就把它重灌 Windows XP Professional，順便作一下筆記 灌好作業系統後，可以先把 ThinkVantage System Update 裝起來，這樣 Thinkpad 相關的驅動程式及軟體都可以直接從這邊更新回來。對了，記得不要裝 Client Security Solution 因為裝了真的是自找麻煩! 另外 System Migration Assistant 和 Rescue and Recovery 我也沒裝.. 接下來就是安裝應用程式了，儘可能都以免費的軟體為主: PicPick 是一個很強大的截圖軟體 XnView 看圖及簡單的圖形處理 Paint.NET 是一個短小精幹的繪圖軟體 FileZilla 支援 FTP 及 SFTP 的檔案傳輸軟體 7-Zip 檔案解壓縮工具 K-Lite Codec Pack 播放各種影音檔案 Adobe Reader 閱讀 PDF 文件 Alcohol 52% Free Edition [...]]]></description>
			<content:encoded><![CDATA[<p>最近已經快滿三年的 Thinkpad X60 跑得越來越慢，又常常當機，所以找個比較有空的時間就把它重灌 Windows XP Professional，順便作一下筆記</p>
<p>灌好作業系統後，可以先把 <a href="http://www-307.ibm.com/pc/support/site.wss/TVSU-UPDATE.html" target=_blank>ThinkVantage System Update</a> 裝起來，這樣 Thinkpad 相關的驅動程式及軟體都可以直接從這邊更新回來。對了，記得不要裝 Client Security Solution 因為裝了真的是自找麻煩! 另外 System Migration Assistant 和 Rescue and Recovery 我也沒裝..</p>
<p>接下來就是安裝應用程式了，儘可能都以免費的軟體為主:</p>
<p><a href="http://picpick.wiziple.net/" target=_blank>PicPick</a> 是一個很強大的截圖軟體<br />
<a href="http://www.xnview.com/" target=_blank>XnView</a> 看圖及簡單的圖形處理<br />
<a href="http://www.paint.net/" target=_blank>Paint.NET</a> 是一個短小精幹的繪圖軟體<br />
<a href="http://filezilla-project.org/" target=_blank>FileZilla</a> 支援 FTP 及 SFTP 的檔案傳輸軟體<br />
<a href="http://7-zip.org/" target=_blank>7-Zip</a> 檔案解壓縮工具<br />
<a href="http://www.free-codecs.com/download/K_lite_codec_pack.htm" target=_blank>K-Lite Codec Pack</a> 播放各種影音檔案<br />
<a href="http://www.adobe.com/tw/products/reader/" target=_blank>Adobe Reader</a> 閱讀 PDF 文件</p>
<p><a href="http://trial.alcohol-soft.com/en/" target=_blank>Alcohol 52% Free Edition</a> 虛擬光碟 (裝免費版的即可, 可選擇不裝贊助軟體)<br />
<a href="http://www.free-av.com/" target=_blank>Avira AntiVir</a> 掃毒軟體<br />
<a href="http://ccollomb.free.fr/unlocker/" target=_blank>Unlocker</a> 強制解鎖<br />
<a href="http://rocketdock.com/" target=_blank>RocketDock</a> 像蘋果的工具列<br />
<a href="http://chewing.csie.net/download/win32/" target=_blank>新酷音輸入法</a> (最新版: 0.3.4.8)</p>
<p>其他網路工具包含:</p>
<ul>
<li><a href="http://pank.org/im/" target=_blank>Messenger</a>
<li><a href="http://www.moztw.org/firefox/" target=_blank>Mozilla Firefox</a>
<li><a href="http://www.skype.com/intl/zh-Hant/" target=_blank>Skype</a>
<li><a href="http://pcman.openfoundry.org/" target=_blank>PCMan Lite</a>
<li><a href="http://www.flickr.com/tools/uploadr/" target=_blank>Flickr Uploadr</a>
</ul>
<p>Google 提供的工具:</p>
<ul>
<li><a href="http://www.google.com/chrome" target=_blank>Google Chrome</a>
<li><a href="http://www.google.com/talk/intl/zh-TW/" target=_blank>Google Talk</a>
<li><a href="http://earth.google.com/intl/zh-TW/" target=_blank>Google Earth</a>
<li><a href="http://picasa.google.com.tw/" target=_blank>Picasa</a>
</ul>
<p>另外微軟的 <a href="http://www.microsoft.com/windowsxp/Downloads/powertoys/Xppowertoys.mspx" target=_blank>PowerToys for Windows XP</a> 也有幾個不錯的小工具:</p>
<ul>
<li>CmdHere
<li>PowerToy Calculator
<li>Tweak UI
</ul>
<p>還有之前微軟有提供一個 Microsoft Chinese Date and Time，是一個我很愛用的農民曆及世界時間工具，但現在微軟似乎把連結拿掉了，不過網路上搜尋一下就找到了</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2009/03/02/148/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mantis Mail Gateway (perl script)</title>
		<link>http://blog.urdada.net/2008/11/11/95/</link>
		<comments>http://blog.urdada.net/2008/11/11/95/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 15:09:26 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[軟體]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/2008/11/11/95/</guid>
		<description><![CDATA[This is a simple Mantis Mail Gateway for mail-in tickets. It can be used for alert management for monitoring system. For installation, add the line below to /etc/aliases: bug: "&#124;/usr/local/bin/mantis-mail-gateway.pl &#160; PROJECT &#160; REPORTER" and then run newaliases. The incoming mail will be posted to a Mantis project named 'PROJECT' on behave of user 'REPORTER'. [...]]]></description>
			<content:encoded><![CDATA[<p>This is a simple Mantis Mail Gateway for mail-in tickets.<br />
It can be used for alert management for monitoring system.</p>
<p>For installation, add the line below to /etc/aliases:</p>
<p><strong>bug:   "|/usr/local/bin/mantis-mail-gateway.pl  &nbsp; PROJECT &nbsp;  REPORTER"</strong></p>
<p>and then run newaliases.</p>
<p>The incoming mail will be posted to a Mantis project named 'PROJECT' on behave of user 'REPORTER'. The mail subject will become the bug summary and the mail content will become the bug description.</p>
<p>Note that this script does not understand MIME multipart encoding and may have problems on mail contents besides plain-ASCII encoding.</p>
<p>You are welcome to add more features.</p>
<p><img src=http://farm4.static.flickr.com/3286/3022458848_b690e23167.jpg /></p>
<p>mantis-mail-gateway.pl: (can be downloaded <a href=http://urdada.net/codings/mantis-mail-gateway.pl>here</a>)</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># mantis-mail-gateway.pl</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Mantis Mail Gateway</span>
<span style="color: #666666; font-style: italic;"># Shen Cheng-Da (cdsheen AT gmail.com)</span>
<span style="color: #666666; font-style: italic;"># require DBI to connect MySQL database</span>
<span style="color: #666666; font-style: italic;"># http://blog.urdada.net/2008/11/11/95/</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> POSIX <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>strftime<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$db_host</span>    <span style="color: #339933;">=</span> <span style="color: #ff0000;">'localhost'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$db_name</span>    <span style="color: #339933;">=</span> <span style="color: #ff0000;">'mantis'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$db_user</span>    <span style="color: #339933;">=</span> <span style="color: #ff0000;">'monitor'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$db_pass</span>    <span style="color: #339933;">=</span> <span style="color: #ff0000;">'monitorpass'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$debug</span>      <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$db</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;dbi:mysql:dbname=${db_name};host=${db_host}&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;Usage: $0 [project-name] [reporter]<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #b1b100;">unless</span> <span style="color: #339933;">@</span><span style="color: #000000; font-weight: bold;">ARGV</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$project_name</span>  <span style="color: #339933;">=</span> <span style="color: #0000ff;">$ARGV</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$reporter_name</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$ARGV</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sql</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$project</span>  <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$reporter</span> <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$db</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$db_user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$db_pass</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">||</span> <span style="color: #000066;">die</span> <span style="color: #ff0000;">'ERROR: '</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">errstr</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;SELECT id,name FROM mantis_project_table
        WHERE name LIKE '$project_name'&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$sql</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #000066;">die</span> <span style="color: #ff0000;">'ERROR: '</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">errstr</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #000066;">die</span> <span style="color: #ff0000;">'ERROR: '</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">errstr</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">@data</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetchrow_array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #0000ff;">$project</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">finish</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;ERROR: project <span style="color: #000099; font-weight: bold;">\`</span>$project_name' does not exist<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #b1b100;">unless</span> <span style="color: #0000ff;">$project</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;project: $project_name ($project)<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$debug</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;SELECT id,username FROM mantis_user_table
        WHERE username = '$reporter_name'&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$sql</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #000066;">die</span> <span style="color: #ff0000;">'ERROR: '</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">errstr</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #000066;">die</span> <span style="color: #ff0000;">'ERROR: '</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">errstr</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">@data</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetchrow_array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #0000ff;">$reporter</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">finish</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;ERROR: user <span style="color: #000099; font-weight: bold;">\`</span>$reporter_name' does not exist<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #b1b100;">unless</span> <span style="color: #0000ff;">$reporter</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;reporter: $reporter_name ($reporter)<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$debug</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$subject</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">''</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$content</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">''</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #009999;">&lt;STDIN&gt;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #009966; font-style: italic;">s/\s+$//</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">last</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$_</span> <span style="color: #b1b100;">eq</span> <span style="color: #ff0000;">''</span><span style="color: #339933;">;</span>
        <span style="color: #0000ff;">$subject</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$1</span> <span style="color: #b1b100;">if</span> <span style="color: #009966; font-style: italic;">/^Subject: (.+)$/</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #009999;">&lt;STDIN&gt;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #0000ff;">$content</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">$_</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'INSERT INTO mantis_bug_text_table (description) VALUES (?)'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$sql</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #000066;">die</span> <span style="color: #ff0000;">'ERROR: '</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">errstr</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$content</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #000066;">die</span> <span style="color: #ff0000;">'ERROR: '</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">errstr</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">finish</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$textid</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066;">q</span><span style="color: #009900;">&#123;</span>mysql_insertid<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;bug text id: $textid<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$debug</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'INSERT INTO mantis_bug_table
                ( project_id, reporter_id,
                  date_submitted, last_updated,
                  bug_text_id, summary )
        VALUES (?,?,?,?,?,?)'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$now</span> <span style="color: #339933;">=</span> strftime<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'%Y-%m-%d %H:%M:%S'</span><span style="color: #339933;">,</span> <span style="color: #000066;">localtime</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">time</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$sql</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #000066;">die</span> <span style="color: #ff0000;">'ERROR: '</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">errstr</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$project</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$reporter</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$now</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$now</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$textid</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$subject</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">||</span> <span style="color: #000066;">die</span> <span style="color: #ff0000;">'ERROR: '</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">errstr</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">finish</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">disconnect</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2008/11/11/95/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Subversion pre-commit hook</title>
		<link>http://blog.urdada.net/2008/07/30/88/</link>
		<comments>http://blog.urdada.net/2008/07/30/88/#comments</comments>
		<pubDate>Tue, 29 Jul 2008 16:54:26 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[軟體]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/2008/07/30/88/</guid>
		<description><![CDATA[很多人寫完程式要 commit 的時候會偷懶不寫 log，導致有時候要追問題時， 很難得知到底別人改了什麼，這時候裝個 pre-commit hook 還是蠻有用的 下面這個 pre-commit hook 只是很簡單的不允許空白或不含字母的 commit log， 如果需要的話可以很容易擴充加上更多的判斷.. 記得要 chmod 755 喔 [Subversion pre-commit hook to reject commit with empty log] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #!/usr/bin/perl &#160; # pre-commit hook to reject [...]]]></description>
			<content:encoded><![CDATA[<p>很多人寫完程式要 commit 的時候會偷懶不寫 log，導致有時候要追問題時，<br />
很難得知到底別人改了什麼，這時候裝個 pre-commit hook 還是蠻有用的</p>
<p>下面這個 <a href=http://svnbook.red-bean.com/en/1.4/svn.ref.reposhooks.pre-commit.html target=_blank>pre-commit hook</a> 只是很簡單的不允許空白或不含字母的 commit log，<br />
如果需要的話可以很容易擴充加上更多的判斷.. 記得要 chmod 755 喔</p>
<p><strong>[Subversion pre-commit hook to reject commit with empty log]</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># pre-commit hook to reject commit with empty log</span>
<span style="color: #666666; font-style: italic;"># remember to chmod 755 on this file</span>
&nbsp;
<span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;Usage: $0 [REPOS] [TXN]<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #b1b100;">unless</span> <span style="color: #339933;">@</span><span style="color: #000000; font-weight: bold;">ARGV</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$REPOS</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$ARGV</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$TXN</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$ARGV</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$svnlook</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'/usr/local/bin/svnlook'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">chomp</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$author</span><span style="color: #339933;">=</span><span style="color: #ff0000;">`$svnlook author -t $TXN $REPOS`</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">chomp</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$log</span><span style="color: #339933;">=</span><span style="color: #ff0000;">`$svnlook log -t $TXN $REPOS`</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$log</span> <span style="color: #b1b100;">eq</span> <span style="color: #ff0000;">''</span> <span style="color: #339933;">||</span> <span style="color: #0000ff;">$log</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">/^\W+$/</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>Hello, $author. Empty commit log is not permitted!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>除此之外，對於 pre-commit hook，我還加上了檢查不允許跨 branch 的 commit，<br />
因為一旦有了跨 branch 的 commit，會使得未來需要作 merge 的時候遇到許多麻煩</p>
<p>例如常用的 repository 結構如下:</p>
<p>/trunk/<br />
/branches/helloworld-1.0/<br />
/branches/helloworld-1.1/</p>
<p>要防止使用者同時對兩個以上的 branch (包含 main trunk) 作 commit，<br />
可以把下面這一段程式再加進去 pre-commit 的 hook 中</p>
<p><strong>[Subversion pre-commit hook to reject cross-branch commit]</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># pre-commit hook to reject empty commit log and cross-branch commit</span>
<span style="color: #666666; font-style: italic;"># remember to chmod 755 on this file</span>
&nbsp;
<span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;Usage: $0 [REPOS] [TXN]<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #b1b100;">unless</span> <span style="color: #339933;">@</span><span style="color: #000000; font-weight: bold;">ARGV</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$REPOS</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$ARGV</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$TXN</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$ARGV</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$svnlook</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">'/usr/local/bin/svnlook'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">chomp</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$author</span><span style="color: #339933;">=</span><span style="color: #ff0000;">`$svnlook author -t $TXN $REPOS`</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">chomp</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$log</span><span style="color: #339933;">=</span><span style="color: #ff0000;">`$svnlook log -t $TXN $REPOS`</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$log</span> <span style="color: #b1b100;">eq</span> <span style="color: #ff0000;">''</span> <span style="color: #339933;">||</span> <span style="color: #0000ff;">$log</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">/^\W+$/</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>Hello, $author. Empty commit log is not permitted!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span>DIRS<span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;$svnlook dirs-changed -t $TXN $REPOS|&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #009999;">&lt;DIRS&gt;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #009966; font-style: italic;">/^(trunk)\//</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #0000ff;">$branches</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$1</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">++;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">elsif</span><span style="color: #009900;">&#40;</span> <span style="color: #009966; font-style: italic;">/^branches\/([^\/]+)/</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #0000ff;">$branches</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$1</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">++;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000066;">close</span><span style="color: #009900;">&#40;</span>DIRS<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$c</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">%branches</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$c</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>Hello, $author. You can't commit to $c branches at the same time!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2008/07/30/88/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>一個長整數各自表述 (in 64-bit system)</title>
		<link>http://blog.urdada.net/2008/04/18/85/</link>
		<comments>http://blog.urdada.net/2008/04/18/85/#comments</comments>
		<pubDate>Fri, 18 Apr 2008 14:06:30 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[作業系統]]></category>
		<category><![CDATA[程式語言]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/2008/04/18/85/</guid>
		<description><![CDATA[Size of long integer may be different between 64-bit systems (一個長整數各自表述) 不知道是不是我太落伍了... 我一直以為 C/C++ 下面 short, long, long long 三種資料型態都固定是 2, 4, 8 個 bytes 大小。只有 int 這個資料型態會因為 16-bit/32-bit 系統的不同而變成 2 或 4 bytes 的大小，所以理所當然 int 在 64-bit 的電腦也應該會變成 8 bytes (64-bit) 的大小囉 ?! 在整理前一篇文章《Bypass the 2GB file size limit on 32-bit Linux》的時候，讓我驚覺在 64-bit 的系統下，long [...]]]></description>
			<content:encoded><![CDATA[<p>Size of long integer may be different between 64-bit systems (一個長整數各自表述)</p>
<p>不知道是不是我太落伍了...</p>
<p>我一直以為 C/C++ 下面 short, long, long long 三種資料型態都固定是 2, 4, 8 個 bytes 大小。只有 int 這個資料型態會因為 16-bit/32-bit 系統的不同而變成 2 或 4 bytes 的大小，所以理所當然 int 在 64-bit 的電腦也應該會變成 8 bytes (64-bit) 的大小囉 ?!</p>
<p>在整理前一篇文章《<a href=http://blog.urdada.net/2008/04/18/84/ target=_blank>Bypass the 2GB file size limit on 32-bit Linux</a>》的時候，讓我驚覺在 64-bit 的系統下，long 的長度也是各自表述的！</p>
<p>首先，int 的大小即使到了 64-bit 的機器上，大部分的系統仍然使用 4 bytes 的大小而已，這主要是為了避免程式從 32-bit 系統轉換到 64-bit 系統需要修改太多地方</p>
<p>再來，請參考 Wikipedia: <a href=http://en.wikipedia.org/wiki/64-bit#64-bit_data_models target=_blank>64-bit data models</a> 的說明</p>
<p>絕大多數的 UNIX 系統在 64-bit 下面採用 <a href=http://www.unix.org/version2/whatsnew/lp64_wp.html target=_blank>LP64</a> 這種 data model，這時候 long 就不再是固定為 4 bytes 大小，而是變成 8 bytes 的大小了！</p>
<p>然而，Win64 卻不是使用 LP64，而是採用 LLP64 這個 data model，這時候 long 的大小仍然還是 4 bytes</p>
<p><img src=http://farm4.static.flickr.com/3219/2422521769_4f4c50c2f2.jpg /></p>
<p><strong><i>Many 64-bit compilers today use the <strong>LP64</strong> model (including Solaris, AIX, HP, Linux, Mac OS X, and IBM z/OS native compilers). Microsoft's VC++ compiler uses the <strong>LLP64</strong> model.</i></strong></p>
<p>兩種 data model 的最大差異點就是 long 這個資料型態的大小，LP64 是 64-bit，而 LLP64 則是 32-bit</p>
<p>LLP64 data model 基本上可以說跟 32-bit 的系統一樣，唯一差別只有位址(pointer)改成了 64-bit 而已。資料物件(class, structure) 等如果沒有包含 pointer 的成員的話，整個物件的大小是與 32-bit 系統一樣的！</p>
<p>而 LP64 則是除了位址(pointer)改成 64-bit 之外，long 的大小也變成了 64-bit 大小。所以在 UNIX 下面，要把 32-bit 程式 porting 到 64-bit 可能要比 Windows 多花費多一點功夫。</p>
<p>所以呢，我們觀察到兩個問題影響著程式的相容性</p>
<ol>
<li>在 UNIX 下面，long 的大小在 32-bit 與 64-bit 的系統下是不一樣的
<li>同樣是 64-bit 系統，UNIX 與 Windows 對於 long 的大小看法是不一致的
</ol>
<p>為了使程式在 32-bit 與 64-bit 之間以及 UNIX 與 Windows 之間的相容性提昇，改用固定長度的資料型態是寫程式的一個好習慣</p>
<p>在 UNIX 下面，我們可以改用 <a href=http://en.wikipedia.org/wiki/Stdint.h target=_blank>stdint.h</a> 這個 header file 中對於資料型態的定義:</p>
<pre>
int8_t     8-bit signed interger
int16_t    16-bit signed interger
int32_t    32-bit signed interger
int64_t    64-bit signed interger
uint8_t    8-bit unsigned interger
uint16_t   16-bit unsigned interger
uint32_t   32-bit unsigned interger
uint64_t   64-bit unsigned interger
</pre>
<p>在 Windows 下面，則改用下面這些整數固定大小的資料型態</p>
<pre>
INT8       8-bit signed integer
INT16      16-bit signed integer
INT32      32-bit signed integer
INT64      64-bit signed integer
UINT8      8-bit unsigned integer
UINT16     16-bit unsigned integer
UINT32     32-bit unsigned integer
UINT64     64-bit unsigned integer
</pre>
<p>絕對不要再使用 int 和 long 了！</p>
<p>尤其是寫網路程式時，很可能 client 是 Windows 而 server 是 UNIX，然後又有 32-bit 及 64-bit 系統混在裡面，一不小心就發生不相容的問題了...</p>
<p>當然，在 64-bit 的系統下寫程式，要考慮的絕對不只上面這些基本的資料型態。除了 pointer 的大小變成 64-bit 外，許多系統內建函式會用到的 size_t 及 off_t 的大小也變成 64-bit 了.... 寫程式時若有用到這些資料型態，需特別注意，尤其是 casting 時，千萬不要用 32-bit 的整數去裝這些資料，免得造成不可預期的結果！</p>
<p>最後提供一個小程式讓你得知你的系統主要資料型態的大小</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#include &lt;sys/types.h&gt;</span>
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;sizeof(short)     = %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">short</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;sizeof(int)       = %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;sizeof(long)      = %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">long</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;sizeof(long long) = %d<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">long</span> <span style="color: #993333;">long</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;sizeof(size_t)    = %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>size_t<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;sizeof(off_t)     = %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>off_t<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;sizeof(void *)    = %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>參考資料:</p>
<ol>
<li>Wikipedia: <a href=http://en.wikipedia.org/wiki/64-bit#64-bit_data_models target=_blank>64-bit data models</a>
<li><a href=http://www.unix.org/version2/whatsnew/lp64_wp.html target=_blank>64-Bit Programming Models: Why LP64?</a>
<li><a href=http://technet.microsoft.com/en-us/library/bb496995.aspx target=_blank>Introduction to Win32/Win64</a>
<li><a href=http://softwarecommunity.intel.com/articles/eng/1660.htm target=_blank>Porting 32-bit Applications to the Itanium® Architecture</a>
<li><a href=http://cache-www.intel.com/cd/00/00/01/79/17969_codeclean_r02.pdf target=_blank>Preparing Code for the IA-64 Architecture</a> (PDF)
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2008/04/18/85/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Bypass the 2GB file size limit on 32-bit Linux</title>
		<link>http://blog.urdada.net/2008/04/18/84/</link>
		<comments>http://blog.urdada.net/2008/04/18/84/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 18:18:56 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[作業系統]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/2008/04/18/84/</guid>
		<description><![CDATA[Bypass the 2GB file size limit on 32-bit Linux (在 Linux 上面突破 2GB 的檔案大小限制) 在 32 位元的 Linux 上面寫超過 2GB 的檔案會發生錯誤，甚至導致程式終止執行 這是因為 Linux 的系統內部處理檔案時用的指標定義為 long，而 long 在 32 位元的系統上的大小為 32 位元，因此最大只能支援 2^31-1 = 2,147,483,647 bytes 等於是 2GB 扣掉 1 byte 的檔案大小 64 位元的系統 (例如 AMD64 或 IA64) 則因為 long 定義成 64 位元，所以不會有問題.. # if __WORDSIZE [...]]]></description>
			<content:encoded><![CDATA[<p>Bypass the 2GB file size limit on 32-bit Linux (在 Linux 上面突破 2GB 的檔案大小限制)</p>
<p>在 32 位元的 Linux 上面寫超過 2GB 的檔案會發生錯誤，甚至導致程式終止執行</p>
<p>這是因為 Linux 的系統內部處理檔案時用的指標定義為 long，而 long 在 32 位元的系統上的大小為 32 位元，因此最大只能支援 2^31-1 = 2,147,483,647 bytes 等於是 2GB 扣掉 1 byte 的檔案大小</p>
<p>64 位元的系統 (例如 <a href=http://en.wikipedia.org/wiki/Amd64 target=_blank>AMD64</a> 或 <a href=http://en.wikipedia.org/wiki/IA64 target=_blank>IA64</a>) 則因為 long 定義成 64 位元，所以不會有問題..</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#  if __WORDSIZE == 64</span>
<span style="color: #993333;">typedef</span> <span style="color: #993333;">long</span> <span style="color: #993333;">int</span> <span style="color: #993333;">int64_t</span><span style="color: #339933;">;</span>
<span style="color: #339933;"># endif</span></pre></div></div>

<p>不過在 FreeBSD 上面，即使是 32 位元的系統，也不會有 2GB 檔案大小的限制，這是因為 FreeBSD 內部處理檔案時，本來就是使用 64 位元的數字當作指標，所以不會有問題</p>
<p>因此在 32 位元的 Linux 上面，程式需要作一些額外處理才能正確寫超過 2GB 的檔案</p>
<p>我們先寫一個小程式來測試一下 (large.c)</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#include &lt;string.h&gt;</span>
<span style="color: #339933;">#include &lt;stdlib.h&gt;</span>
<span style="color: #339933;">#include &lt;fcntl.h&gt;</span>
<span style="color: #339933;">#include &lt;sys/types.h&gt;</span>
<span style="color: #339933;">#include &lt;sys/stat.h&gt;</span>
<span style="color: #339933;">#include &lt;signal.h&gt;</span>
<span style="color: #339933;">#include &lt;unistd.h&gt;</span>
<span style="color: #339933;">#include &lt;errno.h&gt;</span>
<span style="color: #993333;">void</span> sig_xfsz<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> sig<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;ERROR: SIGXFSZ (%d) signal received!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> sig<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        <span style="color: #993333;">int</span>     i<span style="color: #339933;">,</span> fd<span style="color: #339933;">;</span>
        <span style="color: #993333;">char</span>    dummy<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4096</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
        signal<span style="color: #009900;">&#40;</span> SIGXFSZ<span style="color: #339933;">,</span> sig_xfsz <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        unlink<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;large.log&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        fd <span style="color: #339933;">=</span> open<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;large.log&quot;</span><span style="color: #339933;">,</span> O_CREAT<span style="color: #339933;">|</span>O_WRONLY<span style="color: #339933;">,</span> <span style="color: #208080;">0644</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        bzero<span style="color: #009900;">&#40;</span> dummy<span style="color: #339933;">,</span> <span style="color: #0000dd;">4096</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #808080; font-style: italic;">/* 2GB = 4KB x 524288 */</span>
        <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span> <span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">524287</span> <span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span>
                write<span style="color: #009900;">&#40;</span> fd<span style="color: #339933;">,</span> dummy<span style="color: #339933;">,</span> <span style="color: #0000dd;">4096</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        write<span style="color: #009900;">&#40;</span> fd<span style="color: #339933;">,</span> dummy<span style="color: #339933;">,</span> <span style="color: #0000dd;">4095</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;large.log: 2147483647 bytes<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> write<span style="color: #009900;">&#40;</span> fd<span style="color: #339933;">,</span> dummy<span style="color: #339933;">,</span> <span style="color: #0000dd;">1</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">0</span> <span style="color: #009900;">&#41;</span>
                <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;ERROR: %s [errno:%d]<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span>strerror<span style="color: #009900;">&#40;</span>errno<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>errno<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">else</span>
                <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;large.log: 2147483648 bytes<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        close<span style="color: #009900;">&#40;</span>fd<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>在 32 位元的 Linux 下面，以上程式編譯後若沒有特殊處理，執行結果如下:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># gcc -o large32 large.c
# ./large32
large.log: 2147483647 bytes
ERROR: SIGXFSZ (25) signal received!
ERROR: File too large [errno:27]</pre></div></div>

<p>在寫第 2147483648 byte 的時候，程式會收到 signal <a href=http://en.wikipedia.org/wiki/SIGXFSZ target=_blank>SIGXFSZ</a>，同時 write() 會回傳 -1 錯誤，errno 則為 27 (File too large)。更甚者，如果程式沒有像上面一樣去處理 SIGXFSZ 的話，內定的 signal handler 甚至會造成程式停止執行並產生 core dump</p>
<p>接下來，我們在編譯同一個程式的時候加入 -D_FILE_OFFSET_BITS=64 再試看看:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># gcc -D_FILE_OFFSET_BITS=64 -o large64 large.c
# ./large64
large.log: 2147483647 bytes
large.log: 2147483648 bytes</pre></div></div>

<p>果然順利突破 2GB 的限制了!</p>
<p>而同樣的程式在 32 位元的 FreeBSD 下面，不論有沒有加這個定義，跑起來都是正確的</p>
<p>不過處理這些大檔案的時候，除了編譯程式時的參數不同外，有些函數的使用上也要作一些調整，例如 fseek() 與 ftell() 這兩個原本使用到 long integer 當作 offset 的函數:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> fseek<span style="color: #009900;">&#40;</span>FILE <span style="color: #339933;">*</span>stream<span style="color: #339933;">,</span> <span style="color: #993333;">long</span> offset<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> whence<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">long</span> ftell<span style="color: #009900;">&#40;</span>FILE <span style="color: #339933;">*</span>stream<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>只要系統是 32 位元，即使是在 FreeBSD 下面，都需要改為使用 off_t 的版本:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> fseeko<span style="color: #009900;">&#40;</span>FILE <span style="color: #339933;">*</span>stream<span style="color: #339933;">,</span> off_t offset<span style="color: #339933;">,</span> <span style="color: #993333;">int</span> whence<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
off_t ftello<span style="color: #009900;">&#40;</span>FILE <span style="color: #339933;">*</span>stream<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>在 Linux 下面，如果 _FILE_OFFSET_BITS 定義為 64，則 off_t 這個型態會自動轉成 64 位元的大小（在 FreeBSD 上面，off_t 本來就是 64 位元的大小)</p>
<p>每種系統支援大於 2GB 的檔案讀寫所需要的編譯選項都會有一些差異，即使是同樣是 Linux 也會因為 32 位元或 64 位元而有不同。有一個簡單的方法可以判斷，就是利用 glibc 提供的 getconf 來取得編譯(compile)以及連結(linking)時所需的參數:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># getconf LFS_CFLAGS
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
# getconf LFS_LDFLAGS 
&nbsp;
#</pre></div></div>

<p>上面是在 32 位元的 Redhat Linux 上面跑出來的結果，代表的是在這個系統上，若要讓程式支援 2GB 的檔案讀寫，編譯(compile)時需要加上 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 這兩個參數，連結(linking)時則不用加任何參數</p>
<p>參考資料:</p>
<ul>
<li><a href=http://www.suse.de/~aj/linux_lfs.html target=_blank>Large File Support in Linux</a>
<li><a href=http://en.wikipedia.org/wiki/Large_file_support target=_blank>LFS: Large File Support</a> (Wikipedia)
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2008/04/18/84/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SDHC support on Thinkpad X60</title>
		<link>http://blog.urdada.net/2008/01/19/77/</link>
		<comments>http://blog.urdada.net/2008/01/19/77/#comments</comments>
		<pubDate>Fri, 18 Jan 2008 17:29:05 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[硬體]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/2008/01/19/77/</guid>
		<description><![CDATA[Thinkpad X60 原本並沒有 支援 SDHC 卡，把 SDHC 卡插入 X60 左方的 SD 插槽會讀不到 本來以為 X60 對於 SDHC 的支援是無望了，沒想到現在竟然可以了，而且還只要更新作業系統即可... 詳情請參考微軟發佈的 Hotfix 923293 (標題: 在 Windows XP Hotfix 923293 為高容量的 SD 記憶卡加入支援) 不過這個 Hotfix 微軟還沒有釋放出來讓大家下載安裝，未來新的 Service Pack 3 才會放進去，有需要的人必須自己去線上申請，選擇好你的作業系統版本及語言即可 申請之後，微軟就會把 Hotfix 的下載連結寄給你（還有個密碼來解壓縮），正體中文 WinXP 的 Hotfix 檔名為: WindowsXP-KB923293-v4-x86-CHT.exe，怕麻煩的話網路上搜尋一下應該找得到.. 或者寄信給我吧... 安裝此 Hotfix、重新開機後，果然可以讀到 SDHC 卡了! 同事的華碩 ASUS W5 (WinXP) 原本也是不能讀 SDHC [...]]]></description>
			<content:encoded><![CDATA[<p><a href=http://www.tpuser.idv.tw/articles/x60-test-main.htm target=_blank>Thinkpad X60</a> 原本並沒有 支援 <a href=http://zh.wikipedia.org/wiki/SDHC target=_blank>SDHC</a> 卡，把 SDHC 卡插入 X60 左方的 <a href=http://zh.wikipedia.org/wiki/Secure_Digital target=_blank>SD</a> 插槽會讀不到</p>
<p>本來以為 X60 對於 SDHC 的支援是無望了，沒想到現在竟然可以了，而且還只要更新作業系統即可... 詳情請參考微軟發佈的 <a href=http://support.microsoft.com/kb/923293 target=_blank>Hotfix 923293</a><br />
(標題: 在 Windows XP Hotfix 923293 為高容量的 SD 記憶卡加入支援)</p>
<p>不過這個 Hotfix 微軟還沒有釋放出來讓大家下載安裝，未來新的 Service Pack 3 才會放進去，有需要的人必須自己去<a href=http://go.microsoft.com/?linkid=6294451 target=_blank>線上申請</a>，選擇好你的作業系統版本及語言即可</p>
<p>申請之後，微軟就會把 Hotfix 的下載連結寄給你（還有個密碼來解壓縮），正體中文 WinXP 的 Hotfix 檔名為: WindowsXP-KB923293-v4-x86-CHT.exe，怕麻煩的話網路上搜尋一下應該找得到.. 或者寄信給我吧...</p>
<p>安裝此 Hotfix、重新開機後，果然可以讀到 SDHC 卡了!  同事的華碩 ASUS W5 (WinXP) 原本也是不能讀 SDHC 卡，服用這帖 Hotfix 後也 OK 了</p>
<p>Yeah! 這樣方便多了</p>
<p>2008/04/30 update: Windows XP SP3 已經包含這個修正了，不需要再特別安裝 hotfix 了...</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2008/01/19/77/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>SSH Keyboard-Interactive Authentication</title>
		<link>http://blog.urdada.net/2008/01/07/75/</link>
		<comments>http://blog.urdada.net/2008/01/07/75/#comments</comments>
		<pubDate>Mon, 07 Jan 2008 03:11:11 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[資訊安全]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/2008/01/07/75/</guid>
		<description><![CDATA[有些 SSH clients （例如: SecureCRT）允許使用者「儲存」密碼，這對系統安全是個大忌，一旦 client 遭受入侵，server 也會暴露在危險之中。 建議直接在伺服器端取消 SSH 的 password authentication 功能，改用 keyboard interactive 的方式認證，通常這樣的話，client 就無法儲存密碼了: 1. OpenSSH - /etc/ssh/sshd_config PasswordAuthentication no ChallengeResponseAuthentication yes 2. SSH2 (Tectia) - /etc/ssh2/sshd2_config AllowedAuthentications publickey,keyboard-interactive AuthKbdInt.Optional pam,password AuthKbdInt.Required password 修改好上述 sshd 的設定檔後，送個 HUP 給 sshd 即可（注意不要不小心把目前用的 session 也砍了，不然改錯的話只好到 console 前面去救了） # ps ax &#124; grep sbin/sshd &#124; [...]]]></description>
			<content:encoded><![CDATA[<p>有些 SSH clients （例如: <a href=http://www.vandyke.com/products/securecrt/index.html target=_blank>SecureCRT</a>）允許使用者「儲存」密碼，這對系統安全是個大忌，一旦 client 遭受入侵，server 也會暴露在危險之中。</p>
<p>建議直接在伺服器端取消 SSH 的 password authentication 功能，改用 keyboard interactive 的方式認證，通常這樣的話，client 就無法儲存密碼了:</p>
<p>1. OpenSSH - /etc/ssh/sshd_config</p>
<pre class=mono>
PasswordAuthentication no
ChallengeResponseAuthentication yes
</pre>
<p>2. SSH2 (Tectia) - /etc/ssh2/sshd2_config</p>
<pre class=mono>
AllowedAuthentications          publickey,keyboard-interactive
AuthKbdInt.Optional             pam,password
AuthKbdInt.Required             password
</pre>
<p>修改好上述 sshd 的設定檔後，送個 HUP 給 sshd 即可（注意不要不小心把目前用的 session 也砍了，不然改錯的話只好到 console 前面去救了）</p>
<pre class=mono>
# ps ax | grep sbin/sshd | grep Ss
 9767 ?        Ss     0:00 /usr/sbin/sshd
# kill -HUP 9767
</pre>
<p>然後就可以請大家改用 keyboard-interactive authentication 了:</p>
<p><a href="http://www.flickr.com/photos/urdada/2174161870/" class="tt-flickr"><img src="http://farm3.static.flickr.com/2181/2174161870_58d7f2dbaa.jpg" alt="SSH keyboard-interactive authentication" width="500" height="430" border="0" /></a> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2008/01/07/75/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSH2 vs OpenSSH</title>
		<link>http://blog.urdada.net/2008/01/03/70/</link>
		<comments>http://blog.urdada.net/2008/01/03/70/#comments</comments>
		<pubDate>Thu, 03 Jan 2008 13:25:34 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[資訊安全]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/2008/01/03/70/</guid>
		<description><![CDATA[常見的 SSH Implementation 有兩種，ssh.com 的 SSH 以及 OpenSSH，詳細發展原由可參考 OpenSSH History 由於歷史因素，所以提到 SSH 相關用語時，常因不明確而混淆。建議可以參考 O'Reilly book 出版的 SSH, The Secure Shell: The Definitive Guide 一書中對於 SSH 各種詞彙的精確定義： Terminology: SSH Protocols and Products SSH A generic term referring to SSH protocols or software products. SSH-1 The SSH protocol, Version 1. This protocol went through several revisions, of [...]]]></description>
			<content:encoded><![CDATA[<p>常見的 SSH Implementation 有兩種，<a href=http://www.ssh.com/ target=_blank>ssh.com</a> 的 SSH 以及 <a href=http://www.openssh.com/ target=_blank>OpenSSH</a>，詳細發展原由可參考 <a href=http://www.openssh.com/history.html target=_blank>OpenSSH History</a></p>
<p>由於歷史因素，所以提到 SSH 相關用語時，常因不明確而混淆。建議可以參考 <a href=http://www.oreilly.com/ target=_blank>O'Reilly book</a> 出版的 <a href=http://books.google.com.tw/books?id=NZJsza5q4JQC target=_blank>SSH, The Secure Shell: The Definitive Guide</a> 一書中對於 SSH 各種詞彙的精確定義：</p>
<p><b>Terminology: SSH Protocols and Products</b></p>
<pre class=mono>
SSH
    A generic term referring to SSH protocols or software products.
SSH-1
    The SSH protocol, Version 1. This protocol went through several
    revisions, of which 1.3 and 1.5 are the best known, and we will
    write SSH-1.3 and SSH-1.5 should the distinction be necessary.
SSH-2
    The SSH protocol, Version 2, as defined by several draft standards
    documents of the IETF SECSH working group.
SSH1
    Tatu Ylönen's software implementing the SSH-1 protocol; the original
    SSH. Now distributed and maintained (minimally) by SSH
    Communications Security, Inc.
SSH2
    The "SSH Secure Shell" product from SSH Communications Security, Inc.
    This is a commercial SSH-2 protocol implementation, though it is
    licensed free of charge in some circumstances.
ssh (all lowercase letters)
    A client program included in SSH1, SSH2, OpenSSH, F-Secure SSH, and
    other products, for running secure terminal sessions and remote
    commands. In SSH1 and SSH2, it is also named ssh1/ssh2, respectively.
OpenSSH
    The product OpenSSH from the OpenBSD project,
    which implements both the SSH-1 and SSH-2 protocols.
OpenSSH/1
    OpenSSH, referring specifically to its behavior
    when using the SSH-1 protocol.
OpenSSH/2
    OpenSSH, referring specifically to its behavior
    when using the SSH-2 protocol.
</pre>
<p>OpenSSH 基於相容 BSD license 的 ssh 1.2.12 來開發，後續又加上了對 SSH-2 的支援</p>
<p>但 OpenSSH 對 SSH-2 的實作與 ssh.com 後來對 SSH-2 的實作已經有了一些差異。</p>
<p>現今大部分的 open source 作業系統都已經改用 OpenSSH 了，不過有些地方還是可以看到 SSH2 的蹤跡，可能是商業版本或是非商業版本，例如:</p>
<pre class=mono>
# ssh -V
ssh: SSH Secure Shell 3.2.9.1 (non-commercial version) on i686-pc-linux-gnu
</pre>
<p>SSH Communications Security, Inc. (<a href=http://www.ssh.com/ target=_blank>www.ssh.com</a>) 的商業版本 SSH (SSH2) 正式名稱叫做 <a href=http://www.ssh.com/products/client-server/ target=_blank>Tectia SSH client/server</a></p>
<p>熟悉 OpenSSH 的人初次接觸 SSH2 最常遇到的問題就是 Public-Key Authentication 的作法以及 Key format 都不太一樣。</p>
<p>OpenSSH/1 與 SSH1 的 authorization file 都是放在 ~/.ssh/authorized_keys 這個檔案之內，identity 則是放在 ~/.ssh/identity 這個檔案內</p>
<p>OpenSSH/2 的 authorization file 一樣是 ~/.ssh/authorized_keys，identity 則是在 ~/.ssh/id_dsa 或 ~/.ssh/id_rsa 內，依據 key type 而異。但其實因為 OpenSSH/2 有向下相容 OpenSSH/1 的功能，所以事實上也會參考 ~/.ssh/identity 來當作 SSH-1 的 identity</p>
<p>SSH2 就很不一樣了。SSH2 允許有多個 identity，因此會有一個檔案 ~/.ssh/identification 可以設定有哪些 identity 可用，例如:</p>
<pre class=mono>
IdKey identity-1
IdKey identity-2
IdKey identity-3
</pre>
<p>真正的 private key 放在 identity-1, identity-2, identity-3 這三個檔案內，而使用 ssh -i 指定 identity 時，不同於 OpenSSH 是直接指到 key 本身，SSH2 必須指定這個間接的 identification file</p>
<p>SSH2 的 public key format 也與 OpenSSH 不同，不再是一行而已，也因此 authorization file 沒辦法跟 ~/.ssh/authorized_keys 一樣一行放一個 key 值。</p>
<p>SSH2 也是一樣使用一個檔案來設定允許的 public key 有哪些，檔案放在 ~/.ssh/authorization</p>
<pre class=mono>
Key identity-1.pub
Key identity-2.pub
Key identity-3.pub
</pre>
<p>這個檔案表示可接受三個 public key 分別為 identity-1.pub, identity-2.pub, identity-3.pub</p>
<p>而如同 OpenSSH 一樣，SSH2 的 authorization 檔案內也可以指定各種 options，例如：</p>
<pre class=mono>
Key identity-1.pub
Options no-port-forwarding,no-pty
Key identity-2.pub
Options command="rsync -az --server . /home/backup-x",no-pty
</pre>
<p>詳細資訊可參考 SSH2 的 manual</p>
<p>SSH2 的 key format 與 OpenSSH 不同，這在兩者之間要作 public key authentication 時造成了一些麻煩。OpenSSH 提供的 ssh-keygen 可以用 -e 和 -i 兩個選項來轉換兩者的 key format:</p>
<pre class=mono>
# ssh-keygen -e -f openssh-key.pub > ssh2-key.pub
# ssh-keygen -i -f ssh2-key.pub > openssh-key.pub
</pre>
<p>OpenSSH 與 SSH2 之間的問題還不只這樣，SCP 的實作方式也不同</p>
<p>OpenSSH 與 SSH1 的 SCP 是 RCP over SSH，而 SSH2 附的 SCP2 背地裡則是用 SFTP 實作的，因此兩者互相 copy 東西時有時會 copy 不過去，建議還是一律改用有經過 IETF 標準認證的 SFTP 就好了</p>
<p>如果可以的話，全部用 OpenSSH 是最單純的，不過有時不是自己能控制的，碰到使用 SSH2 的系統，其實只要稍微了解一下差異也很容易適應就是了</p>
<p>參考資料:</p>
<ul>
<li>O'Reilly: <a href=http://books.google.com.tw/books?id=NZJsza5q4JQC target=_blank>SSH, The Secure Shell: The Definitive Guide</a>
<li><a href=http://www.onlamp.com/pub/a/onlamp/excerpt/ssh_8/ target=_blank>SSH Public-Key Authentication</a>
<li><a href=http://landru.uwaterloo.ca/cgi-bin/wiki.pl?OpenSSH_-_SSH.Com_Interoperability target=_blank>OpenSSH - SSH.Com Interoperability</a>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2008/01/03/70/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SSH Escape Character</title>
		<link>http://blog.urdada.net/2008/01/02/73/</link>
		<comments>http://blog.urdada.net/2008/01/02/73/#comments</comments>
		<pubDate>Wed, 02 Jan 2008 13:36:51 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[軟體]]></category>
		<category><![CDATA[資訊安全]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/2008/01/02/73/</guid>
		<description><![CDATA[SSH client 有一個 Escape Character (跳脫字元)，事實上 rsh/rlogin 也有支援 Escape Character (~)，就如同 Ctrl-] 之於 telnet 一樣... SSH client 的 Escape Character 一般跟 rsh/rlogin 一樣設定成 ~，詳細用法可於命令列按 ~? 來取得說明，要注意的是，為了避免影響一般正常的輸入，Escape Character 必須是命令列換行後的第一個按鍵，如果你已經輸入別的按鍵，即使按 backspace 把游標移回開頭處再輸入 Escape Character 也是無效的！請先按 Enter 換行後再輸入吧！ myhost# ~? Supported escape sequences: ~. - terminate connection ~B - send a BREAK to the remote system ~C - [...]]]></description>
			<content:encoded><![CDATA[<p>SSH client 有一個 Escape Character (跳脫字元)，事實上 rsh/rlogin 也有支援 Escape Character (~)，就如同 Ctrl-] 之於 telnet 一樣...</p>
<p>SSH client 的 Escape Character 一般跟 rsh/rlogin 一樣設定成 ~，詳細用法可於命令列按 ~? 來取得說明，要注意的是，為了避免影響一般正常的輸入，Escape Character 必須是<u>命令列換行後的第一個按鍵</u>，如果你已經輸入別的按鍵，即使按 backspace 把游標移回開頭處再輸入 Escape Character 也是無效的！請先按 Enter 換行後再輸入吧！</p>
<pre class=mono>
myhost# ~?
Supported escape sequences:
~.  - terminate connection
~B  - send a BREAK to the remote system
~C  - open a command line
~R  - Request rekey (SSH protocol 2 only)
~^Z - suspend ssh
~#  - list forwarded connections
~&#038;  - background ssh (when waiting for connections to terminate)
~?  - this message
~~  - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)
</pre>
<p>最常用的 Escape Character 就是 ~. 以及 ~^Z 這兩個：</p>
<p>~. 是直接切斷目前的 SSH 連線，如果你遇到遠端機器沒有反應時，可用此方式來切斷連線</p>
<p>~^Z (~ 及 Ctrl-Z) 則是把目前的 SSH 連線先 suspend，一般可用來回到原來機器上處理一些事情，若要再回去，輸入 fg 即可</p>
<p>問題來了，假設你從 HOST1 先 SSH 到 HOST2，然後再從 HOST2 SSH 到 HOST3</p>
<p>HOST1 ===1===> HOST2 ===2===> HOST3</p>
<p>如果你在 HOST3 的 terminal 下輸入 ~. 的話，你會直接切斷上面的第一段連線回到 HOST1 的 terminal，當然這樣的話第二段連線也一併 bye-bye 了！如果只是想切斷第二段連線回到 HOST2 該怎麼作呢？</p>
<p>這時候 ~~ 就發揮作用了，你只要輸入 ~~. 就可以切斷第二段連線了</p>
<p>以此累推，輸入 N 個 Escape Character 代表對第 N 段連線送出 Escape Character</p>
<p>最後，若不想用 ~ 當作跳脫字元，可於命令列用 -e 修改，例如把 SSH 跳脫字元改成 #：</p>
<pre class=mono>
ssh -e "#" myhost.mydomain.com
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2008/01/02/73/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Change the core dump file name in Linux and FreeBSD</title>
		<link>http://blog.urdada.net/2008/01/02/72/</link>
		<comments>http://blog.urdada.net/2008/01/02/72/#comments</comments>
		<pubDate>Wed, 02 Jan 2008 05:57:02 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[作業系統]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/2008/01/02/72/</guid>
		<description><![CDATA[Following the previous notes about enabling core dump, here's a note about changing the filename of core dump. In Linux (since Linux 2.6 and 2.4.21) you can change the core dump filename from the file /proc/sys/kernel/core_pattern %% A single % character %p PID of dumped process %u real UID of dumped process %g real GID [...]]]></description>
			<content:encoded><![CDATA[<p>Following the <a href=http://blog.urdada.net/2007/12/31/71/ target=_blank>previous notes</a> about enabling core dump, here's a note about changing the filename of core dump.</p>
<p>In Linux (since Linux 2.6 and 2.4.21)<br />
you can change the core dump filename from the file /proc/sys/kernel/core_pattern</p>
<pre class=mono>
         %%  A single % character
         %p  PID of dumped process
         %u  real UID of dumped process
         %g  real GID of dumped process
         %s  number of signal causing dump
         %t  time of dump (seconds since 0:00h, 1 Jan 1970)
         %h  hostname (same as 'nodename' returned by uname(2))
         %e  executable filename
</pre>
<p>Linux have a default core filename pattern of "core".<br />
Alternatively, if /proc/sys/kernel/core_uses_pid contains a non-zero value, then the core dump file name will include a suffix .PID (process id), ex: core.PID</p>
<p>In FreeBSD, sysctl variable "kern.corefile" controls the filename of core dump.</p>
<pre class=mono>
Any sequence of %N in this filename template will be replaced by
the process name, %P by the processes PID, and %U by the UID.
</pre>
<p>FreeBSD have a default core filename pattern of "%N.core"</p>
<p>You can include path in the filename pattern both in Linux and FreeBSD.<br />
This make it possible to put core dump file in a separated directory.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2008/01/02/72/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enable core dump in Linux and FreeBSD</title>
		<link>http://blog.urdada.net/2007/12/31/71/</link>
		<comments>http://blog.urdada.net/2007/12/31/71/#comments</comments>
		<pubDate>Mon, 31 Dec 2007 00:46:59 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[作業系統]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/2007/12/31/71/</guid>
		<description><![CDATA[Just a note. You can enable core dump by: [bash] edit /etc/profile ulimit -c unlimited [csh/tcsh] edit /etc/csh.cshrc limit coredumpsize unlimited You can disable core dump by: [bash] edit /etc/profile ulimit -c 0 [csh/tcsh] edit /etc/csh.cshrc limit coredumpsize 0 On FreeBSD, you also need to check the setting of kern.coredump: # sysctl -a &#124;grep kern.coredump [...]]]></description>
			<content:encoded><![CDATA[<p>Just a note.</p>
<p>You can enable <a href=http://en.wikipedia.org/wiki/Core_dump target=_blank>core dump</a> by:</p>
<p>[bash] edit /etc/profile</p>
<pre class=mono>
ulimit -c unlimited
</pre>
<p>[csh/tcsh] edit /etc/csh.cshrc</p>
<pre class=mono>
limit coredumpsize unlimited
</pre>
<p>You can disable <a href=http://en.wikipedia.org/wiki/Core_dump target=_blank>core dump</a> by:</p>
<p>[bash] edit /etc/profile</p>
<pre class=mono>
ulimit -c 0
</pre>
<p>[csh/tcsh] edit /etc/csh.cshrc</p>
<pre class=mono>
limit coredumpsize 0
</pre>
<p>On FreeBSD, you also need to check the setting of kern.coredump:</p>
<pre class=mono>
# sysctl -a |grep kern.coredump
kern.coredump: 0
# sysctl kern.coredump=1
kern.coredump: 0 -> 1
# sysctl -a | grep kern.coredump
kern.coredump: 1
</pre>
<p>You can enforce this setting in /etc/sysctl.conf</p>
<p>[2008/01/01] Thanks for the <a href=http://blog.gslin.org/archives/2007/12/31/1400/ target=_blank>complement</a> from <a href=http://blog.gslin.org/ target=_blank>gslin</a>, kern.sugid_coredump controls the core dump for setuid/setgid process in FreeBSD.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2007/12/31/71/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Script: 取得 FreeBSD CVSUP 的更新狀態</title>
		<link>http://blog.urdada.net/2007/12/24/69/</link>
		<comments>http://blog.urdada.net/2007/12/24/69/#comments</comments>
		<pubDate>Mon, 24 Dec 2007 15:52:43 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[軟體]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/2007/12/24/69/</guid>
		<description><![CDATA[這是今年1月寫的 script... 用來監控各大 FreeBSD CVSUP mirror 網站的檔案更新程度， 提供服務的網址是 http://ftp.giga.net.tw/cvsup.php 內容其實很簡單，下面把程式放出來，有興趣的人歡迎免費拿去修改使用 == 原理說明: CVS 不像 Subversion 一樣可以很容易知道目前 repository 中的最新版本為何， 必須要把每個檔案檢查一遍才有辦法知道最新的版本是什麼... 不過在 FreeBSD Source CVS 下面，每次 commit 都會有 commit log 可經由 CVSUP 取得， 因此我們可以利用 CVSROOT-*/commitlogs/* 這幾個檔案來判斷目前 source tree 的狀態.. 只要把這幾個檔案經由 CVSUP 取出來就可以大致知道該伺服器的目前保存的最新版本是哪一個了 == 第一個是一個 Perl script，主要是連結到各大 FreeBSD CVSUP 網站取得相關資訊存下來 後面則附上一個 PHP script，可以把這些資訊用 HTML 表格方式呈現出來 check-cvsup.pl 1 2 [...]]]></description>
			<content:encoded><![CDATA[<p>這是今年1月寫的 script...  用來監控各大 FreeBSD CVSUP mirror 網站的檔案更新程度，<br />
提供服務的網址是 <a href=http://ftp.giga.net.tw/cvsup.php target=_blank>http://ftp.giga.net.tw/cvsup.php</a></p>
<p><img src="http://farm3.static.flickr.com/2057/2134694712_0811886762.jpg" alt="" /></p>
<p>內容其實很簡單，下面把程式放出來，有興趣的人歡迎免費拿去修改使用</p>
<p>==<br />
原理說明:</p>
<p><a href=http://www.nongnu.org/cvs/ target=_blank>CVS</a> 不像 <a href=http://subversion.tigris.org/ target=_blank>Subversion</a> 一樣可以很容易知道目前 repository 中的最新版本為何，<br />
必須要把每個檔案檢查一遍才有辦法知道最新的版本是什麼...</p>
<p>不過在 FreeBSD Source CVS 下面，每次 commit 都會有 commit log 可經由 CVSUP 取得，<br />
因此我們可以利用 CVSROOT-*/commitlogs/* 這幾個檔案來判斷目前 source tree 的狀態..<br />
只要把這幾個檔案經由 CVSUP 取出來就可以大致知道該伺服器的目前保存的最新版本是哪一個了<br />
==</p>
<p>第一個是一個 Perl script，主要是連結到各大 FreeBSD CVSUP 網站取得相關資訊存下來<br />
後面則附上一個 PHP script，可以把這些資訊用 HTML 表格方式呈現出來</p>
<p>check-cvsup.pl</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Check the update status for CVSUP servers</span>
<span style="color: #666666; font-style: italic;"># BSD license</span>
<span style="color: #666666; font-style: italic;"># Shen Cheng-Da (cdsheen AT gmail.com)</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> POSIX <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>strftime<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Net<span style="color: #339933;">::</span><span style="color: #006600;">DNS</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Time<span style="color: #339933;">::</span><span style="color: #006600;">HiRes</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span> gettimeofday tv_interval <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">@servers</span> <span style="color: #339933;">=</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span> cvsup<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org cvsup1<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org cvsup2<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org 
                cvsup3<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org cvsup4<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org cvsup5<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org 
                cvsup6<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org cvsup7<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org cvsup8<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org 
                cvsup9<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org cvsup10<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org cvsup11<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org 
                cvsup12<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org cvsup13<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org cvsup14<span style="color: #339933;">.</span>tw<span style="color: #339933;">.</span>freebsd<span style="color: #339933;">.</span>org <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$dir</span>    <span style="color: #339933;">=</span> <span style="color: #ff0000;">'/home/cvsup-monitor'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$cvsup</span>  <span style="color: #339933;">=</span> <span style="color: #ff0000;">'/usr/local/bin/cvsup'</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$base</span>   <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dir</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">'/base'</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$log</span>    <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dir</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">'/check.log'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">chdir</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$dir</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #000066;">die</span> <span style="color: #ff0000;">&quot;ERROR: Can not change to directory [$dir]<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">mkdir</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$base</span><span style="color: #339933;">,</span> 0755 <span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">unless</span> <span style="color: #339933;">-</span>d <span style="color: #0000ff;">$base</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">@files_src</span> <span style="color: #339933;">=</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span> CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>CVSROOT CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>bin
                CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>etc CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>contrib
                CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>gnu CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>games
                CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>include CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>lib
                CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>release CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>sys
                CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>sbin CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>share
                CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>tools CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>user
                CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>usrbin CVSROOT<span style="color: #339933;">-</span>src<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>usrsbin <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">@files_ports</span> <span style="color: #339933;">=</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span> CVSROOT<span style="color: #339933;">-</span>ports<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>CVSROOT
                        CVSROOT<span style="color: #339933;">-</span>ports<span style="color: #339933;">/</span>commitlogs<span style="color: #339933;">/</span>ports <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$includes</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">''</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #0000ff;">$f</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">@files_src</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #0000ff;">$includes</span> <span style="color: #339933;">.=</span> <span style="color: #ff0000;">&quot; -i $f&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #0000ff;">$f</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">@files_ports</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #0000ff;">$includes</span> <span style="color: #339933;">.=</span> <span style="color: #ff0000;">&quot; -i $f&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span> LOG<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;&gt;$log&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$resolver</span> <span style="color: #339933;">=</span> Net<span style="color: #339933;">::</span><span style="color: #006600;">DNS</span><span style="color: #339933;">::</span><span style="color: #006600;">Resolver</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #0000ff;">$resolver</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">usevc</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$resolver</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">udp_timeout</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$resolver</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">tcp_timeout</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$resolver</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">retrans</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$resolver</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">retry</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$resolver</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">persistent_tcp</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #0000ff;">$server</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">@servers</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$query</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$resolver</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$server</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'A'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #0000ff;">@ipaddr</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@cname</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$query</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #b1b100;">foreach</span> <span style="color: #0000ff;">$rr</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">answer</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$rr</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">type</span> <span style="color: #b1b100;">eq</span> <span style="color: #ff0000;">'A'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                                <span style="color: #000066;">print</span> LOG <span style="color: #ff0000;">&quot;$server =&gt; [A] &quot;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$rr</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">address</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
                                <span style="color: #000066;">push</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">@ipaddr</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$rr</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">address</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #009900;">&#125;</span>
                        <span style="color: #b1b100;">elsif</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$rr</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">type</span> <span style="color: #b1b100;">eq</span> <span style="color: #ff0000;">'CNAME'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                                <span style="color: #000066;">print</span> LOG <span style="color: #ff0000;">&quot;$server =&gt; [CNAME] &quot;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$rr</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cname</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
                                <span style="color: #000066;">push</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">@cname</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$rr</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">cname</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #0000ff;">$ip</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$ipaddr</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #0000ff;">$ipaddr</span> <span style="color: #339933;">=</span> <span style="color: #000066;">join</span><span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">'|'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">@ipaddr</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #0000ff;">$cname</span>  <span style="color: #339933;">=</span> <span style="color: #000066;">join</span><span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">'|'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">@cname</span>  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #0000ff;">$ibase</span>   <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;$base/$server&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">mkdir</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$ibase</span><span style="color: #339933;">,</span> 0755 <span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">unless</span> <span style="color: #339933;">-</span>d <span style="color: #0000ff;">$ibase</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">mkdir</span><span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;$ibase/SRC&quot;</span><span style="color: #339933;">,</span> 0755 <span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">unless</span> <span style="color: #339933;">-</span>d <span style="color: #ff0000;">&quot;$ibase/SRC&quot;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #0000ff;">$cmd</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">&quot;$cvsup -h $ip -L 0 -b $ibase -r 0 $includes supfile&quot;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #0000ff;">$time_start</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span>gettimeofday<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">system</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$cmd</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #0000ff;">$elapsed</span> <span style="color: #339933;">=</span> tv_interval<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$time_start</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066;">printf</span> LOG <span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;$server =&gt; cvsup on $ip elapsed %.2fs<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$time_elapsed</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">unless</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$?</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #0000ff;">$mt_src</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$mt_ports</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
                <span style="color: #b1b100;">foreach</span> <span style="color: #0000ff;">$f</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">@files_src</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #0000ff;">$t</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066;">stat</span><span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;$ibase/SRC/$f&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">9</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                        <span style="color: #0000ff;">$mt_src</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$t</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$t</span> <span style="color: #339933;">&gt;</span> <span style="color: #0000ff;">$mt_src</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #b1b100;">foreach</span> <span style="color: #0000ff;">$f</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">@files_ports</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #0000ff;">$t</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066;">stat</span><span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;$ibase/SRC/$f&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">9</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                        <span style="color: #0000ff;">$mt_ports</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$t</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$t</span> <span style="color: #339933;">&gt;</span> <span style="color: #0000ff;">$mt_ports</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span> REC<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;&gt;$ibase/last-commit.txt&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066;">printf</span> REC<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;$mt_src,$mt_ports,%.2f,$ipaddr,$cname&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$elapsed</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066;">close</span><span style="color: #009900;">&#40;</span>REC<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                <span style="color: #000066;">printf</span> LOG <span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;$server =&gt; SRC: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span>
                        strftime<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%Y/%m/%d %H:%M:%S&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066;">localtime</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$mt_src</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066;">printf</span> LOG <span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;$server =&gt; PORTS: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span>
                        strftime<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%Y/%m/%d %H:%M:%S&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066;">localtime</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$mt_ports</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066;">close</span><span style="color: #009900;">&#40;</span>LOG<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>supfile:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">*default prefix=SRC
*default release=cvs delete use-rel-suffix
*default compress
&nbsp;
cvsroot-src
cvsroot-ports</pre></div></div>

<p>cvsup.php</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;style type=&quot;text/css&quot;&gt;
  td       { font-size: 12px; vertical-align: top }
  td.head  { background: #FFFFC0 }
  td.c     { background: #E0E0FF }
  td.red   { background: #FFE0E0 }
  td.green { background: #E0FFE0 }
&lt;/style&gt;
&lt;table border=1 cellspacing=0 cellpadding=2&gt;
&lt;tr&gt;&lt;td class=head&gt;Server Name&lt;/td&gt;&lt;td class=head&gt;IP&lt;/td&gt;
&lt;td class=head&gt;CNAME&lt;/td&gt;&lt;td class=head&gt;latest commit of src&lt;/td&gt;
&lt;td class=head&gt;latest commit of ports&lt;/td&gt;
&lt;/tr&gt;
<span style="color: #000000; font-weight: bold;">&lt;?</span>
        <span style="color: #000088;">$dir</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/home/cvsup-monitor'</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$servers</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
              <span style="color: #0000ff;">'cvsup.tw.freebsd.org'</span><span style="color: #339933;">,</span>  <span style="color: #0000ff;">'cvsup1.tw.freebsd.org'</span><span style="color: #339933;">,</span>  <span style="color: #0000ff;">'cvsup2.tw.freebsd.org'</span><span style="color: #339933;">,</span>
              <span style="color: #0000ff;">'cvsup3.tw.freebsd.org'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'cvsup4.tw.freebsd.org'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'cvsup5.tw.freebsd.org'</span><span style="color: #339933;">,</span>
              <span style="color: #0000ff;">'cvsup6.tw.freebsd.org'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'cvsup7.tw.freebsd.org'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'cvsup8.tw.freebsd.org'</span><span style="color: #339933;">,</span>
              <span style="color: #0000ff;">'cvsup9.tw.freebsd.org'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'cvsup10.tw.freebsd.org'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'cvsup11.tw.freebsd.org'</span><span style="color: #339933;">,</span>
              <span style="color: #0000ff;">'cvsup12.tw.freebsd.org'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'cvsup13.tw.freebsd.org'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'cvsup14.tw.freebsd.org'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$check</span> <span style="color: #339933;">=</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">86400</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$time_format</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'%Y/%m/%d %H:%M:%S'</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$latest_src</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$latest_ports</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$servers</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$server</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$dir</span>/base/<span style="color: #006699; font-weight: bold;">$server</span>/last-commit.txt&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$data</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">''</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #000088;">$SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$server</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$server</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;</span> <span style="color: #000088;">$latest_src</span> <span style="color: #009900;">&#41;</span>
                                <span style="color: #000088;">$latest_src</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$server</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$server</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;</span> <span style="color: #000088;">$latest_ports</span> <span style="color: #009900;">&#41;</span>
                                <span style="color: #000088;">$latest_ports</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$server</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$servers</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$server</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$server</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #990000;">list</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$src</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ports</span><span style="color: #339933;">,</span> <span style="color: #000088;">$elapsed</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ipaddr</span><span style="color: #339933;">,</span> <span style="color: #000088;">$aliases</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$server</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                        <span style="color: #000088;">$ipaddr</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'|'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br /&gt;'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ipaddr</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #000088;">$aliases</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'|'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br /&gt;'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$aliases</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$aliases</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">''</span> <span style="color: #009900;">&#41;</span>
                                <span style="color: #000088;">$aliases</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'&amp;nbsp;'</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;&lt;tr&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;  &lt;td class=c&gt;<span style="color: #006699; font-weight: bold;">$server</span>&lt;/td&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;  &lt;td class=c&gt;<span style="color: #006699; font-weight: bold;">$ipaddr</span>&lt;/td&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;  &lt;td class=c&gt;<span style="color: #006699; font-weight: bold;">$aliases</span>&lt;/td&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$src</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$latest_src</span> <span style="color: #009900;">&#41;</span>
                                <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;  &lt;td class=green&gt;&quot;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">elseif</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$src</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$check</span> <span style="color: #009900;">&#41;</span>
                                <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;  &lt;td class=red&gt;&quot;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">else</span>
                                <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;  &lt;td class=c&gt;&quot;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">print</span> <span style="color: #990000;">strftime</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$time_format</span><span style="color: #339933;">,</span> <span style="color: #000088;">$src</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;&lt;/td&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$ports</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$latest_ports</span> <span style="color: #009900;">&#41;</span>
                                <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;  &lt;td class=green&gt;&quot;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">elseif</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$ports</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$check</span> <span style="color: #009900;">&#41;</span>
                                <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;  &lt;td class=red&gt;&quot;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">else</span>
                                <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;  &lt;td class=c&gt;&quot;</span><span style="color: #339933;">;</span>
                        <span style="color: #b1b100;">print</span> <span style="color: #990000;">strftime</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$time_format</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ports</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;&lt;/td&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">#                       print &quot;  &lt;td align=right&gt;$elapsed s&lt;/td&gt;\n&quot;;
</span>                        <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;&lt;/tr&gt;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&lt;/table&gt;</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2007/12/24/69/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>消失的硬碟空間</title>
		<link>http://blog.urdada.net/2007/11/20/65/</link>
		<comments>http://blog.urdada.net/2007/11/20/65/#comments</comments>
		<pubDate>Mon, 19 Nov 2007 17:02:32 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[作業系統]]></category>
		<category><![CDATA[程式語言]]></category>
		<category><![CDATA[disk]]></category>
		<category><![CDATA[fstat]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[rotation]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/2007/11/20/65/</guid>
		<description><![CDATA[話說某一天，一位同事發現某個在 UNIX 上用 C 寫的程式，跑一陣子後似乎會吃掉很多硬碟空間，吃掉的硬碟空間用 du 去算卻跟 df 的結果差異很大，而且把 process 停掉後，空間竟然又自動恢復正常了 最後，用 fstat 去仔細分析，終於找到原因： 已經開啟的檔案，即使開啟中被強制砍掉(unlink)，對原 file descriptor 持續寫入的部份仍會繼續佔用硬碟空間，寫得越多，佔用的空間也越多 實務上最常遇到這種狀況的就是 log rotation，尤其是 rotation 後的舊 LOG 是壓縮過的情況。因為經過 gzip 壓縮過後，原始的 LOG 會被刪除，只留下 XXX.gz。這個時候如果沒有人通知原來寫 LOG 的程式要重新開啟一次 LOG (重新寫一個檔案)，就會導致程式在不知情狀況下繼續寫 LOG，然後空間就莫名其妙被用掉了！ 例如 FreeBSD 下專門作 log rotation 的 newsyslog 設定檔 (newsyslog.conf) 就有個欄位可以設定在 log rotation 後送一個 signal 給 process，而 apache (httpd) 就接受 SIGUSR1 [...]]]></description>
			<content:encoded><![CDATA[<p>話說某一天，一位同事發現某個在 UNIX 上用 C 寫的程式，跑一陣子後似乎會吃掉很多硬碟空間，吃掉的硬碟空間用 du 去算卻跟 df 的結果差異很大，而且把 process 停掉後，空間竟然又自動恢復正常了</p>
<p>最後，用 fstat 去仔細分析，終於找到原因：</p>
<blockquote><p><strong>已經開啟的檔案，即使開啟中被強制砍掉(unlink)，對原 file descriptor 持續寫入的部份仍會繼續佔用硬碟空間，寫得越多，佔用的空間也越多</strong></p></blockquote>
<p>實務上最常遇到這種狀況的就是 log rotation，尤其是 rotation 後的舊 LOG 是壓縮過的情況。因為經過 gzip 壓縮過後，原始的 LOG 會被刪除，只留下 XXX.gz。這個時候如果沒有人通知原來寫 LOG 的程式要重新開啟一次 LOG (重新寫一個檔案)，就會導致程式在不知情狀況下繼續寫 LOG，然後空間就莫名其妙被用掉了！</p>
<p>例如 <a href=http://www.freebsd.org/ target=_blank>FreeBSD</a> 下專門作 log rotation 的 <a href=http://www.freebsd.org/cgi/man.cgi?query=newsyslog&#038;sektion=8 target=_blank>newsyslog</a> 設定檔 (<a href=http://www.freebsd.org/cgi/man.cgi?query=newsyslog.conf&#038;sektion=5&#038;apropos=0&#038;manpath=FreeBSD+6.2-RELEASE target=_blank>newsyslog.conf</a>) 就有個欄位可以設定在 log rotation 後送一個 signal 給 process，而 apache (httpd) 就接受 SIGUSR1 來當作重新開啟 LOG 檔案的訊號（事實上對 apache 而言是 graceful restart）。很多人以為這只是為了讓 LOG 能繼續寫不會漏掉，但其實更重要的是：如果不這麼作，你的硬碟可能很快就爆掉啦...</p>
<p>我們可以寫個簡單的程式來測試一下這種狀況：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#include &lt;fcntl.h&gt;</span>
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
        <span style="color: #993333;">int</span>     fd<span style="color: #339933;">,</span> i<span style="color: #339933;">;</span>
        <span style="color: #993333;">char</span>    cmd<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">32</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> buf<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1024</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        memset<span style="color: #009900;">&#40;</span> buf<span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">1024</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        snprintf<span style="color: #009900;">&#40;</span>cmd<span style="color: #339933;">,</span><span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>cmd<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;df .&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;==&gt; open file for write and delete it ...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        fd <span style="color: #339933;">=</span> open<span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;test-file.log&quot;</span><span style="color: #339933;">,</span> O_CREAT<span style="color: #339933;">|</span>O_WRONLY<span style="color: #339933;">|</span>O_TRUNC <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        unlink<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;test-file.log&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        system<span style="color: #009900;">&#40;</span>cmd<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>==&gt; write 100MB to file ...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span> <span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">1000</span><span style="color: #339933;">*</span><span style="color: #0000dd;">100</span> <span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span>
                write<span style="color: #009900;">&#40;</span> fd<span style="color: #339933;">,</span> buf<span style="color: #339933;">,</span> <span style="color: #0000dd;">1024</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        system<span style="color: #009900;">&#40;</span>cmd<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>==&gt; close file ...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        close<span style="color: #009900;">&#40;</span>fd<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        system<span style="color: #009900;">&#40;</span>cmd<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>首先，這個小程式會先開啟一個檔案，然後馬上砍掉它（但先不關閉檔案），接下來執行 "df ." 來查看目前硬碟用量。第二步驟是寫入100MB的垃圾資料到這個已開啟的檔案(file descriptor)中，然後再執行 "df ." 來取得硬碟用量。最後關閉檔案後，再執行一次 "df ."。執行結果如下：</p>
<pre class=mono>
==> open file for write and delete it ...
Filesystem  1K-blocks     Used     Avail Capacity  Mounted on
/dev/ad8s1d 144520482 <u>28011428</u> 104947416    21%    /home

==> write 100MB to file ...
Filesystem  1K-blocks     Used     Avail Capacity  Mounted on
/dev/ad8s1d 144520482 <u>28111508</u> 104847336    21%    /home

==> close file ...
Filesystem  1K-blocks     Used     Avail Capacity  Mounted on
/dev/ad8s1d 144520482 <u>28011428</u> 104947416    21%    /home
</pre>
<p>我們可以看到程式寫了100MB之後，空間真的被佔掉了，即使我們已經刪除這個檔案，且從目錄的檔案列表中無法直接看到這個檔案了。而當被開啟的檔案關掉後，這些空間也立即被釋放回來了</p>
<p>接下來我們把程式中的 df 改成 fstat，可以更清楚看到狀況</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="c" style="font-family:monospace;">        snprintf<span style="color: #009900;">&#40;</span>cmd<span style="color: #339933;">,</span><span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>cmd<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;fstat -f -p %d .&quot;</span><span style="color: #339933;">,</span> getpid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>這是最後的結果：</p>
<pre class=mono>
==> open file for write and delete it ...
USER     CMD     PID   FD MOUNT     INUM MODE         SZ|DV R/W
cdsheen  a.out 91475   wd /home 12694528 drwxr-xr-x    2048  r
cdsheen  a.out 91475 text /home 12694672 -rwxr-xr-x    7910  r
cdsheen  a.out 91475    3 /home 12694673 ----r-x--x       0  w

==> write 100MB to file ...
USER     CMD     PID   FD MOUNT     INUM MODE         SZ|DV R/W
cdsheen  a.out 91475   wd /home 12694528 drwxr-xr-x    2048  r
cdsheen  a.out 91475 text /home 12694672 -rwxr-xr-x    7910  r
cdsheen  a.out 91475    3 /home 12694673 ----r-x--x  <u>102400000</u>  w

==> close file ...
USER     CMD     PID   FD MOUNT     INUM MODE         SZ|DV R/W
cdsheen  a.out 91475   wd /home 12694528 drwxr-xr-x    2048  r
cdsheen  a.out 91475 text /home 12694672 -rwxr-xr-x    7910  r
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2007/11/20/65/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Subversion: revert a commit [時光倒轉]</title>
		<link>http://blog.urdada.net/2007/11/07/63/</link>
		<comments>http://blog.urdada.net/2007/11/07/63/#comments</comments>
		<pubDate>Wed, 07 Nov 2007 15:09:31 +0000</pubDate>
		<dc:creator>dada</dc:creator>
				<category><![CDATA[軟體]]></category>

		<guid isPermaLink="false">http://blog.urdada.net/2007/11/07/63/</guid>
		<description><![CDATA[使用 Subversion 偶而就會遇到有人不小心把一堆不該存在的檔案 commit 進來了，這在去年寫的一篇「svndumpflter with wildcards support ?」有提到從歷史記憶中去除個別檔案的方式 但如果你能即時發現最新的一個(或幾個) commit(s) 的任何更動都是不該發生的（通常就是有人做了蠢事），那麼在有其他正常人繼續 commit 之前，其實是有蠻好的挽救機會的 假設你的 repository 名稱是 foobar，最新的 revision number 是 r105，但是你即時發現 r101 ~ r105 都是某人亂搞的結果，那麼在 r106 commit 之前，應該還有機會把時光倒轉到 r100 那時清純未受污染的狀態.. 廢話不多說，下面是作法 # cd /home/svn # svnadmin create foobar.new # svnadmin dump -r0:100 foobar &#124; svnadmin load --force-uuid foobar.new # mv foobar foobar.old # mv [...]]]></description>
			<content:encoded><![CDATA[<p>使用 <a href=http://subversion.tigris.org/ target=_blank>Subversion</a> 偶而就會遇到有人不小心把一堆不該存在的檔案 commit 進來了，這在去年寫的一篇「<a href=http://blog.urdada.net/2006/10/06/64/ target=_blank>svndumpflter with wildcards support ?</a>」有提到從歷史記憶中去除個別檔案的方式</p>
<p>但如果你能即時發現最新的一個(或幾個) commit(s) 的任何更動都是不該發生的（通常就是有人做了蠢事），那麼在有其他正常人繼續 commit 之前，其實是有蠻好的挽救機會的 <img src='http://blog.urdada.net/wp-includes/images/smilies/icon_idea.gif' alt=':idea:' class='wp-smiley' /> </p>
<p>假設你的 repository 名稱是 foobar，最新的 revision number 是 r105，但是你即時發現 r101 ~ r105 都是某人亂搞的結果，那麼在 r106 commit 之前，應該還有機會把時光倒轉到 r100 那時清純未受污染的狀態..</p>
<p>廢話不多說，下面是作法</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;"># cd /home/svn
# svnadmin create foobar.new
# svnadmin dump -r0:100 foobar | svnadmin load --force-uuid foobar.new
# mv foobar foobar.old
# mv foobar.new foobar</pre></div></div>

<p>做完以上動作後再把該設的權限弄好，hooks 下的東西 copy 回去就可以了</p>
<p>如果有其他人在這段動作完成前 checkout 了 r101~r105 之間的版本，就跟他們說他們看到鬼了，請他們砍掉 source tree 重新 checkout 一份吧 <img src='http://blog.urdada.net/wp-includes/images/smilies/icon_rolleyes.gif' alt=':roll:' class='wp-smiley' />  </p>
<p>上面這段作法最重要的地方是 <strong>--force-uuid</strong> 這個選項，沒有加這個選項會使得回復的 repository 的 UUID 跟原本的不同，進而導致之前已經 checkout 的 working copy 都會認不得新的 repository！</p>
<p>如果還來不及作上述動作，就有其他正常人 commit 東西進來了，其實也不會很麻煩，反正做完回復動作後，統統當作沒發生過，再叫作蠢事的人請一頓飯，拜託其他人把新的修改再改一次就好了</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.urdada.net/2007/11/07/63/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

