<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
	<title>La Vita è Bella</title>
	<link>http://wang.yuxuan.org/blog/</link>
	<description>May the Force be with you. RAmen</description>
	<language>en-us</language>           
	<generator>Nucleus CMS v3.51</generator>
	<copyright>Yuxuan Wang</copyright>             
	<category>Weblog</category>
	<docs>http://backend.userland.com/rss</docs>
	<image>
		<url>http://wang.yuxuan.org/greenfish.png</url>
		<title>La Vita è Bella</title>
		<link>http://wang.yuxuan.org/blog/</link>
	</image>
		<item>
		<title><![CDATA[More tips about my projtags.vim]]></title>
		<link>http://wang.yuxuan.org/blog/2010/3/2/more_tips_about_my_projtags_vim</link>
		<guid>http://wang.yuxuan.org/blog/2010/3/2/more_tips_about_my_projtags_vim</guid>
		<description><![CDATA[<p>I wrote a <a href="http://www.vim.org/scripts/script.php?script_id=1873">vim plugin named projtags</a>, initially for loading tags file for projects. But as I can <a href="http://wang.yuxuan.org/blog/2007/4/25/vim_tip_vim_and_ctags">&quot;set tags+=tags;&quot;</a> in my vimrc, it's not that useful on the tags file way. I expanded its feature to support commands for per projects, and this is much more useful  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_razz.gif" alt=":P" title="" />  Here are some examples:</p>
<h4>Case 1: different coding styles</h4>
<p>I did some <a href="http://www.squid-cache.org/">squid</a> hacking before. My coding style is as below:</p>
<blockquote class="vimblock"><p>
<span class="Statement">set</span>&nbsp;<span class="PreProc">cindent</span><br />
<span class="Statement">set</span>&nbsp;<span class="PreProc">autoindent</span><br />
<span class="Statement">set</span>&nbsp;<span class="PreProc">smartindent</span><br />
<span class="Statement">set</span>&nbsp;<span class="PreProc">tabstop</span>=8<br />
<span class="Statement">set</span>&nbsp;<span class="PreProc">softtabstop</span>=8<br />
<span class="Statement">set</span>&nbsp;<span class="PreProc">shiftwidth</span>=8<br />
<span class="Statement">set</span>&nbsp;<span class="PreProc">noexpandtab</span><br />
<span class="Statement">set</span>&nbsp;<span class="PreProc">smarttab</span><br />
<span class="Statement">set</span>&nbsp;<span class="PreProc">cino</span>=<span class="Statement">:</span>0<span class="Statement">,</span>g0<span class="Statement">,</span>t0
</p></blockquote>
<p>But squid coding style is different. They use 4 for shiftwidth. As hacking some project, you should always follow the original coding style. But add vim modeline into every file is also unacceptable. So I use projtags.vim to do this job:</p>
<blockquote class="vimblock"><p>
<span class="Statement">let</span>&nbsp;g:<span />ProjTags&nbsp;<span class="Statement">+=</span>&nbsp;[[<span class="Constant">&quot;~/work/squid&quot;</span>, <span class="Constant">&quot;:set sw=4&quot;</span>]]
</p></blockquote>
<p>So that every time I'm editing a file within squid, vim will use 4 instead of 8 for shiftwidth, now I'm happy with both my own codes and squid codes.</p>
<h4>Case 2: use ant as makeprg for java projects</h4>
<p>First, I use a autocmd to set ant as makeprg for java files:</p>
<blockquote class="vimblock"><p>
<span class="Statement">autocmd</span>&nbsp;<span class="Type">BufNewFile</span>,<span class="Type">BufRead</span>&nbsp;*.java&nbsp;:<span class="Statement">setlocal</span>&nbsp;makeprg<span class="Statement">=</span>ant\ <span class="Statement">-</span>s\ build<span class="Statement">.</span>xml
</p></blockquote>
<p>It works well for java files. But as I did some Android development these days, I also have lots of xml files to edit (and then make to see the result). I can't use such a autocmd for xml's, as not all xml's are in a java project. So projtags.vim is again the answer:</p>
<blockquote class="vimblock"><p>
<span class="Statement">let</span>&nbsp;g:<span />ProjTags&nbsp;<span class="Statement">+=</span>&nbsp;[[<span class="Constant">&quot;~/work/pmats&quot;</span>, <span class="Constant">&quot;:set mp=ant</span><span class="Constant">\\</span><span class="Constant">&nbsp;-s</span><span class="Constant">\\</span><span class="Constant">&nbsp;build.xml&quot;</span>]]
</p></blockquote>
<p>So I can always use &quot;:make&quot; for ant under my Android project now, no matter it's .java or .xml.</p>
<h4>My vimrc segment for tags and projtags</h4>
<blockquote class="vimblock"><p>
<span class="Statement">set</span>&nbsp;<span class="PreProc">tags</span>+=/usr/local/include/tags<br />
<span class="Statement">set</span>&nbsp;<span class="PreProc">tags</span>+=/usr/include/tags<br />
<span class="Statement">set</span>&nbsp;<span class="PreProc">tags</span>+=/opt/local/include/tags<br />
<span class="Statement">set</span>&nbsp;<span class="PreProc">tags</span>+=tags;<br />
<br />
<span class="Statement">let</span>&nbsp;g:<span />ProjTags&nbsp;<span class="Statement">=</span>&nbsp;[]<br />
<span class="Statement">let</span>&nbsp;g:<span />ProjTags&nbsp;<span class="Statement">+=</span>&nbsp;[[<span class="Constant">&quot;~/work/squid&quot;</span>, <span class="Constant">&quot;:set sw=4&quot;</span>]]<br />
<span class="Statement">let</span>&nbsp;g:<span />ProjTags&nbsp;<span class="Statement">+=</span>&nbsp;[[<span class="Constant">&quot;~/work/pmats&quot;</span>, <span class="Constant">&quot;:set mp=ant</span><span class="Constant">\\</span><span class="Constant">&nbsp;-s</span><span class="Constant">\\</span><span class="Constant">&nbsp;build.xml&quot;</span>]]
</p></blockquote>
<p>Patches for projtags.vim (e.g. Windows support, I haven't tested it but I guess it won't work under Windows now) are welcomed  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_biggrin.gif" alt=":D" title="" />  You can get the code from <a href="http://github.com/fishy/scripts">the git repo for my various scripts</a>.</p><br/><br/>tags: <a href="http://technorati.com/tag/dev" rel="tag">dev</a>, <a href="http://technorati.com/tag/vim" rel="tag">vim</a>, <a href="http://technorati.com/tag/tags" rel="tag">tags</a>, <a href="http://technorati.com/tag/projtags" rel="tag">projtags</a>]]></description>
		<category>dev</category>
		<comments>http://wang.yuxuan.org/blog/2010/3/2/more_tips_about_my_projtags_vim</comments>
		<pubDate>Tue, 2 Mar 2010 19:58:01 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Modified Pwitter to support 3rd party twitter API]]></title>
		<link>http://wang.yuxuan.org/blog/2009/10/11/modified_pwitter_to_support_3rd_party_twitter_api</link>
		<guid>http://wang.yuxuan.org/blog/2009/10/11/modified_pwitter_to_support_3rd_party_twitter_api</guid>
		<description><![CDATA[<p><a href="http://wiki.github.com/koroshiya1/pwitter">Pwitter</a> is a good open source <a href="https://twitter.com">Twitter</a> client for Mac. I just added supporting for 3rd party twitter API to it to make it better.</p>
<p>You can get <a href="http://selif.yhsif.com/pwitter.patch">my patch here</a> or <a href="http://selif.yhsif.com/Pwitter.app.zip">my build here</a>.</p>
<p>There's no GUI for setting 3rd party twitter API address. Instead, you need to change the configuration file. You can use either Property List Editor or the Terminal &quot;defaults write&quot; way. Here's an example:</p>
<blockquote><p>$ defaults write com.aki.Pwitter twitter_https -bool NO<br />
$ defaults write com.aki.Pwitter twitter_base "teewt.yhsif.com"
</p></blockquote>
<p>To restore the default settings ( https and &quot;twitter.com&quot; ), you can just delete the custom settings by:</p>
<blockquote><p>$ defaults delete com.aki.Pwitter twitter_https<br />
$ defaults delete com.aki.Pwitter twitter_base
</p></blockquote>
<p>It's useful when you can't connect to twitter.com directly, like me in China. Enjoy it.</p><br/><br/>tags: <a href="http://technorati.com/tag/hack" rel="tag">hack</a>, <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/pwitter" rel="tag">pwitter</a>, <a href="http://technorati.com/tag/twitter" rel="tag">twitter</a>, <a href="http://technorati.com/tag/api" rel="tag">api</a>]]></description>
		<category>opensource</category>
		<comments>http://wang.yuxuan.org/blog/2009/10/11/modified_pwitter_to_support_3rd_party_twitter_api</comments>
		<pubDate>Sun, 11 Oct 2009 22:06:13 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[A script for Columbus V-900 GPS]]></title>
		<link>http://wang.yuxuan.org/blog/2009/4/28/a_script_for_columbus_v_900_gps</link>
		<guid>http://wang.yuxuan.org/blog/2009/4/28/a_script_for_columbus_v_900_gps</guid>
		<description><![CDATA[<p><a href="http://www.google.com/search?q=columbus%20v900">Columbus V-900</a> is so far the GPS that best fit my requirements: it can log, it can take waypoints while logging, and it (can) have a big storage for logging (via TF card). I got one from WC, a friend to give it a try.</p>
<p>It log GPS tracks to <acronym title="comma separated values">CSV</acronym> format, WC wrote a <a href="http://contrib.exoweb.net/browser/geoutils/columbus.pl">script</a> to convert it to the <a href="http://www.topografix.com/gpx.asp">GPX format</a>, but without waypoints. So I rewrote a Python script (as I'm not so familiar with perl), to add the waypoints to the GPX file.</p>
<p><a href="http://github.com/fishy/scripts/blob/master/columbus.py">Get the script here</a>, it will use the voice record filename as the name of the waypoint if available, or otherwise just &quot;Waypoint #N&quot;. You may want to edit the converted GPX file to rename the waypoints.</p><br/><br/>tags: <a href="http://technorati.com/tag/script" rel="tag">script</a>, <a href="http://technorati.com/tag/python" rel="tag">python</a>, <a href="http://technorati.com/tag/gps" rel="tag">gps</a>, <a href="http://technorati.com/tag/columbus" rel="tag">columbus</a>, <a href="http://technorati.com/tag/v900" rel="tag">v900</a>, <a href="http://technorati.com/tag/gpx" rel="tag">gpx</a>]]></description>
		<category>dev</category>
		<comments>http://wang.yuxuan.org/blog/2009/4/28/a_script_for_columbus_v_900_gps</comments>
		<pubDate>Tue, 28 Apr 2009 11:47:57 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Python script to convert from IP range to IP mask]]></title>
		<link>http://wang.yuxuan.org/blog/2009/4/2/python_script_to_convert_from_ip_range_to_ip_mask</link>
		<guid>http://wang.yuxuan.org/blog/2009/4/2/python_script_to_convert_from_ip_range_to_ip_mask</guid>
		<description><![CDATA[<p><a href="http://github.com/fishy/scripts/blob/master/convertip.py">This script</a> will convert a line contains start and end IP separated by space like:</p>
<blockquote><p>221.192.0.0 221.199.207.255</p></blockquote>
<p>Into IP mask format (with comment) like:</p>
<blockquote><p>
#221.192.0.0 - 221.199.207.255<br />
221.192.0.0/14<br />
221.196.0.0/15<br />
221.198.0.0/16<br />
221.199.0.0/17<br />
221.199.128.0/18<br />
221.199.192.0/20</p>
</blockquote>
<p>The script is:</p>
<blockquote class="vimblock"><p>
<span class="lnr">&nbsp;1 </span><span class="Comment">#!/usr/bin/env python</span><br />
<span class="lnr">&nbsp;2 </span><br />
<span class="lnr">&nbsp;3 </span><span class="PreProc">import</span>&nbsp;sys<br />
<span class="lnr">&nbsp;4 </span><span class="PreProc">import</span>&nbsp;re<br />
<span class="lnr">&nbsp;5 </span><br />
<span class="lnr">&nbsp;6 </span><span class="Statement">def</span>&nbsp;<span class="Identifier">ip2int</span>(ip) :<br />
<span class="lnr">&nbsp;7 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = 0<br />
<span class="lnr">&nbsp;8 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;match = re.match(<span class="Normal">&quot;</span><span class="Constant">(\d*)\.(\d*)\.(\d*)\.(\d*)</span><span class="Normal">&quot;</span>, ip)<br />
<span class="lnr">&nbsp;9 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">if</span>&nbsp;<span class="Statement">not</span>&nbsp;match : <span class="Statement">return</span>&nbsp;0<br />
<span class="lnr">10 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">for</span>&nbsp;i <span class="Statement">in</span>&nbsp;xrange(4) : ret = (ret &lt;&lt; 8<span />) + int(match.groups()[i])<br />
<span class="lnr">11 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">return</span>&nbsp;ret<br />
<span class="lnr">12 </span><br />
<span class="lnr">13 </span><span class="Statement">def</span>&nbsp;<span class="Identifier">int2ip</span>(ipnum) :<br />
<span class="lnr">14 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip1 = ipnum &gt;&gt; 24<br />
<span class="lnr">15 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip2 = ipnum &gt;&gt; 16 &amp; 0xFF<br />
<span class="lnr">16 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip3 = ipnum &gt;&gt; 8 &amp; 0xFF<br />
<span class="lnr">17 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip4 = ipnum &amp; 0xFF<br />
<span class="lnr">18 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">return</span>&nbsp;<span class="Normal">&quot;</span><span class="Constant">%d.%d.%d.%d</span><span class="Normal">&quot;</span>&nbsp;% (ip1, ip2, ip3, ip4)<br />
<span class="lnr">19 </span><br />
<span class="lnr">20 </span><span class="Statement">def</span>&nbsp;<span class="Identifier">printrange</span>(startip, endip) :<br />
<span class="lnr">21 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bits = 1<br />
<span class="lnr">22 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mask = 1<br />
<span class="lnr">23 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">while</span>&nbsp;bits &lt; 32 :<br />
<span class="lnr">24 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newip = startip | mask<br />
<span class="lnr">25 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">if</span>&nbsp;(newip&gt;endip) <span class="Statement">or</span>&nbsp;(((startip&gt;&gt;bits) &lt;&lt; bits) != startip) :<br />
<span class="lnr">26 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bits = bits - 1<br />
<span class="lnr">27 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mask = mask &gt;&gt; 1<br />
<span class="lnr">28 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">break</span><br />
<span class="lnr">29 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bits = bits + 1<br />
<span class="lnr">30 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mask = (mask&lt;&lt;1) + 1<br />
<span class="lnr">31 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newip = startip | mask<br />
<span class="lnr">32 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bits = 32 - bits<br />
<span class="lnr">33 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">print</span>&nbsp;<span class="Normal">&quot;</span><span class="Constant">%s/%d</span><span class="Normal">&quot;</span>&nbsp;% (int2ip(startip), bits)<br />
<span class="lnr">34 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">if</span>&nbsp;newip &lt; endip : <br />
<span class="lnr">35 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printrange(newip + 1, endip)<br />
<span class="lnr">36 </span><br />
<span class="lnr">37 </span><span class="Statement">while</span>&nbsp;1 :<br />
<span class="lnr">38 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line = sys.stdin.readline().strip()<br />
<span class="lnr">39 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">if</span>&nbsp;<span class="Statement">not</span>&nbsp;line : <span class="Statement">break</span><br />
<span class="lnr">40 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chars = line.split(<span class="Normal">&quot;</span><span class="Constant">&nbsp;</span><span class="Normal">&quot;</span>)<br />
<span class="lnr">41 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">print</span>&nbsp;<span class="Normal">&quot;</span><span class="Constant">#%s - %s</span><span class="Normal">&quot;</span>&nbsp;% (chars[0], chars[1])<br />
<span class="lnr">42 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip1 = ip2int(chars[0])<br />
<span class="lnr">43 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip2 = ip2int(chars[1])<br />
<span class="lnr">44 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printrange(ip1, ip2)<br />
<span class="lnr">45 </span><br />
</p></blockquote><br/><br/>tags: <a href="http://technorati.com/tag/code" rel="tag">code</a>, <a href="http://technorati.com/tag/python" rel="tag">python</a>, <a href="http://technorati.com/tag/ip" rel="tag">ip</a>, <a href="http://technorati.com/tag/range" rel="tag">range</a>, <a href="http://technorati.com/tag/mask" rel="tag">mask</a>]]></description>
		<category>dev</category>
		<comments>http://wang.yuxuan.org/blog/2009/4/2/python_script_to_convert_from_ip_range_to_ip_mask</comments>
		<pubDate>Thu, 2 Apr 2009 18:57:10 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[NucleusCMS patch: use UTF-8 base64 to encode email subject]]></title>
		<link>http://wang.yuxuan.org/blog/2009/3/28/nucleuscms_patch_use_utf_8_base64_to_encode_email_subject</link>
		<guid>http://wang.yuxuan.org/blog/2009/3/28/nucleuscms_patch_use_utf_8_base64_to_encode_email_subject</guid>
		<description><![CDATA[<p>The emails sent by NucleusCMS (e.g. new comment notification) didn't encode the subject, but just put the raw text there. For english language file, that's OK. But for other languages such as Chinese, it's not that good. It will produce garbled text on the subject (but not always garbled, weird).</p>
<p>So I wrote <a href="http://selif.yhsif.com/nucleus_email.patch">this patch</a> to resolve this problem. Google tell me that if I want to encode an email subject in PHP, I should use the <a href="http://php.net/mb_encode_mimeheader">mb_encode_mimeheader()</a> function. But Dreamhost just didn't provide any mb_ functions in PHP. I dug more about email subject encoding, and found that a hardcoded base64  should just do the trick. As the original sending mail code in NucleusCMS hardcoded UTF-8 in the Content-Type, I assume that hardcode UTF-8 in the subject is fine, too.</p><br/><br/>tags: <a href="http://technorati.com/tag/dev" rel="tag">dev</a>, <a href="http://technorati.com/tag/php" rel="tag">php</a>, <a href="http://technorati.com/tag/nucleus" rel="tag">nucleus</a>, <a href="http://technorati.com/tag/patch" rel="tag">patch</a>, <a href="http://technorati.com/tag/email" rel="tag">email</a>, <a href="http://technorati.com/tag/encode" rel="tag">encode</a>, <a href="http://technorati.com/tag/utf8" rel="tag">utf8</a>, <a href="http://technorati.com/tag/base64" rel="tag">base64</a>]]></description>
		<category>dev</category>
		<comments>http://wang.yuxuan.org/blog/2009/3/28/nucleuscms_patch_use_utf_8_base64_to_encode_email_subject</comments>
		<pubDate>Sat, 28 Mar 2009 00:10:27 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Note: dhcpd configuration]]></title>
		<link>http://wang.yuxuan.org/blog/2009/2/25/note_dhcpd_configuration</link>
		<guid>http://wang.yuxuan.org/blog/2009/2/25/note_dhcpd_configuration</guid>
		<description><![CDATA[<p>Although I've <a href="http://wang.yuxuan.org/blog/2008/11/8/got_802_11n_working_on_asus_eee_box">got 802.11n working</a> on my <a href="http://wang.yuxuan.org/blog/2008/11/6/debian_lenny_on_asus_eee_box">Asus Eee Box</a>, copy big files between Eee Box and my lap-top over WiFi is slow (as my Time Capsule is far away). So I use a cable for file copying, that's gigabit!</p>
<p>But I have to set my lap-top's ethernet to use DHCP in office, to avoid 2 network configurations on my lap-top, I need my Eee Box to act as a dhcpd, that can automatically assign an IP to my lap-top, but don't harm the router/nameserver configurations on my lap-top, and the existing DHCP in the WiFi network.</p>
<p>I aptituded the dhcp3-server package, and look into the default configuration file, got this code:</p>
<blockquote><pre>
subnet 192.168.1.0 netmask 255.255.255.0 {
  range 192.168.1.100 192.168.1.254;
}
</pre></blockquote>
<p>And it works!</p><br/><br/>tags: <a href="http://technorati.com/tag/linux" rel="tag">linux</a>, <a href="http://technorati.com/tag/dhcpd" rel="tag">dhcpd</a>, <a href="http://technorati.com/tag/conf" rel="tag">conf</a>]]></description>
		<category>linux</category>
		<comments>http://wang.yuxuan.org/blog/2009/2/25/note_dhcpd_configuration</comments>
		<pubDate>Wed, 25 Feb 2009 20:07:09 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[The high memory usage of Squid with external acl]]></title>
		<link>http://wang.yuxuan.org/blog/2009/1/5/the_high_memory_usage_of_squid_with_external_acl</link>
		<guid>http://wang.yuxuan.org/blog/2009/1/5/the_high_memory_usage_of_squid_with_external_acl</guid>
		<description><![CDATA[<p>We configured some <a href="http://www.squid-cache.org/">Squid</a> 2.6 servers that use <a href="http://www.squid-cache.org/Versions/v2/2.6/cfgman/external_acl_type.html">external_acl_type</a> to use some headers sent by client for access control. And the authentication isn't username/password routine, but use some tag to calculate hash. When running, the memory used by Squid just keep increasing from time to time, just like it have a memory leak. We tried to disable the acl on some server, and these servers runs just fine.</p>
<p>As external acl run in individual process, even if the acl program have memory leak, the memory used by the squid process shouldn't be growing.</p>
<p>We tried many ways to figure out the problem, but all fails. Finally someone noticed that in the <a href="http://www.squid-cache.org/Versions/v2/2.6/cfgman/external_acl_type.html">external_acl_type documentation</a>, there's a parameter named &quot;cache&quot;, with this description:</p>
<blockquote><p>result cache size, 0 is unbounded (default)</p></blockquote>
<p>&quot;unbounded&quot;! So this is the problem. For username/password routine, cache is useful. the next time some user with the same username/password comes, Squid can get the result from cache without communicate with acl program. But for our authentication method, as the headers used to calculate hash is differ from every request, cache is totally useless.</p>
<p>I really hope that &quot;0&quot; means no cache and &quot;-1&quot; means unbounded. But anyway, set &quot;cache&quot; to 1 can do the trick. Now the Squids don't have memory problems anymore, although cache replace will slow them down a bit.</p><br/><br/>tags: <a href="http://technorati.com/tag/squid" rel="tag">squid</a>, <a href="http://technorati.com/tag/memory" rel="tag">memory</a>, <a href="http://technorati.com/tag/linux" rel="tag">linux</a>, <a href="http://technorati.com/tag/external" rel="tag">external</a>, <a href="http://technorati.com/tag/acl" rel="tag">acl</a>]]></description>
		<category>linux</category>
		<comments>http://wang.yuxuan.org/blog/2009/1/5/the_high_memory_usage_of_squid_with_external_acl</comments>
		<pubDate>Mon, 5 Jan 2009 18:09:03 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Got 802.11n working on Asus Eee Box!]]></title>
		<link>http://wang.yuxuan.org/blog/2008/11/8/got_802_11n_working_on_asus_eee_box</link>
		<guid>http://wang.yuxuan.org/blog/2008/11/8/got_802_11n_working_on_asus_eee_box</guid>
		<description><![CDATA[<p>In <a href="http://wang.yuxuan.org/blog/2008/11/6/debian_lenny_on_asus_eee_box">my last blog</a>, I use ndiswrapper for wireless driver and it can only use 802.11g, but not 802.11n. But today I've got the solution!</p>
<p>According to <a href="http://forum.eeeuser.com/viewtopic.php?pid=401279">this article on EeeUser forum</a>, the rt2860 chipset released the source code for Linux driver! Download them from <a href="http://www.ralinktech.com/ralink/Home/Support/Linux.html">the official website</a>, and build it. You will need kernel header package to build the driver.</p>
<p>After successfully build, use &quot;modprobe rt2860sta&quot; to install this module, and you may also add the line &quot;rt2860sta&quot; to your &quot;/etc/mmodules&quot; file to load it automatically every time (but seems that modprobe have done this, you may don't need this step).</p>
<p>Now here's a problem: seems that wpa_supplicant didn't support this driver. So you need to set wireless parameters by iwpriv manually. And the biggest problem is WPAPSK, you can't just input your passphrase to do it. Luckily there's <a href="http://www.wireshark.org/tools/wpa-psk.html">a webpage</a> that can calculate the WPAPSK for us. I'm using WPA2 and it works. I'm not sure about WPA. But <a href="http://www.pcworld.com/businesscenter/article/153396/once_thought_safe_wpa_wifi_encryption_is_cracked.html">WPA is broken</a>! Why don't you move to WPA2?  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_wink.gif" alt=";)" title="" /> </p>
<p>Save the below script to &quot;/etc/restart_wireless.sh&quot; and give it execute privilege:</p>
<blockquote class="vimblock"><p>
<span class="Identifier">iface</span>=ra0<br />
<span class="Identifier">w</span>=<span class="Statement">&quot;</span><span class="Constant">iwpriv </span><span class="PreProc">$iface</span><span class="Statement">&quot;</span><br />
<br />
<span class="Identifier">total_start</span>=<span class="Error">$(</span><span class="Special">date +%s</span><span class="Error">)</span><br />
<br />
<span class="Identifier">init_start</span>=<span class="Error">$(</span><span class="Special">date +%s</span><span class="Error">)</span><br />
<span class="Statement">echo</span><span class="Constant">&nbsp;-en </span><span class="Statement">&quot;</span><span class="Constant">iwpriv config...</span><span class="Statement">&quot;</span><br />
<span class="PreProc">$w</span>&nbsp;<span class="Statement">set</span><span class="Identifier">&nbsp;NetworkType</span><span class="Statement">=</span>Infra<br />
<span class="PreProc">$w</span>&nbsp;<span class="Statement">set</span><span class="Identifier">&nbsp;AuthMode</span><span class="Statement">=</span>WPA2PSK<br />
<span class="PreProc">$w</span>&nbsp;<span class="Statement">set</span><span class="Identifier">&nbsp;EncrypType</span><span class="Statement">=</span>AES<br />
<span class="PreProc">$w</span>&nbsp;<span class="Statement">set</span><span class="Identifier">&nbsp;SSID</span><span class="Statement">=</span>Your SSID<br />
<span class="Comment"># get WPAPSK from <a href="http://www.wireshark.org/tools/wpa-psk.html">http://www.wireshark.org/tools/wpa-psk.html</a></span><br />
<span class="PreProc">$w</span>&nbsp;<span class="Statement">set</span><span class="Identifier">&nbsp;WPAPSK</span><span class="Statement">=</span>Your WPAPSK<br />
<span class="Statement">echo</span><span class="Constant">&nbsp;</span><span class="Statement">&quot;</span><span class="Constant">done</span><span class="Statement">&quot;</span><br />
<span class="Identifier">init_end</span>=<span class="Error">$(</span><span class="Special">date +%s</span><span class="Error">)</span><br />
<span class="Identifier">init_time</span>=<span class="Error">$(</span><span class="Statement">(</span><span class="PreProc">$init_end</span><span class="Special">-</span><span class="PreProc">$init_start</span><span class="Statement">)</span><span class="Error">)</span><br />
<br />
<span class="Identifier">assoc_start</span>=<span class="Error">$(</span><span class="Special">date +%s</span><span class="Error">)</span><br />
<span class="Identifier">assoc</span>=<span class="Constant">0</span><br />
<span class="Identifier">assoc_report</span>=<span class="Constant">10</span><br />
<span class="Identifier">assoc_loop</span>=<span class="Constant">310</span><br />
<span class="Statement">echo</span><span class="Constant">&nbsp;-n </span><span class="Statement">&quot;</span><span class="Constant">Associating...</span><span class="Statement">&quot;</span><br />
<span class="Statement">for </span><span class="Statement">((</span><span class="Identifier">i</span>=<span class="Constant">0</span><span class="Statement">;</span>&nbsp;<span class="PreProc">$i</span>&nbsp;<span class="Statement">&lt;</span>&nbsp;<span class="PreProc">$assoc_loop</span><span class="Statement">;</span>&nbsp;i++<span class="Statement">))</span><span class="Statement">;</span>&nbsp;<span class="Statement">do</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">if </span><span class="Statement">[</span>&nbsp;<span class="Statement">&quot;</span><span class="Error">$(</span><span class="Special">iwconfig ra0 </span><span class="Constant">2</span><span class="Special">&gt;/dev/null </span><span class="Statement">|</span><span class="Special">&nbsp;head </span><span class="Constant">-1</span><span class="Special">&nbsp;</span><span class="Statement">|</span><span class="Special">&nbsp;cut -f2 -d: </span><span class="Statement">|</span><span class="Special">&nbsp;cut -f1 -d</span><span class="Statement">&quot;</span><span class="Constant">&nbsp;</span><span class="Statement">&quot;</span><span class="Error">)</span><span class="Statement">&quot;</span>&nbsp;<span class="Statement">==</span>&nbsp;<span class="Constant">&quot;\&quot;</span>\<span class="Statement">&quot;&quot;</span>&nbsp;<span class="Statement">]</span><span class="Statement">;</span>&nbsp;<span class="Statement">then</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">if </span><span class="Statement">[[</span>&nbsp;<span class="Error">$(</span><span class="Statement">(</span><span class="Special">&nbsp;</span><span class="Statement">(</span><span class="PreProc">$i</span><span class="Special">+</span><span class="Constant">1</span><span class="Statement">)</span><span class="Special">&nbsp;% </span><span class="PreProc">$assoc_report</span><span class="Special">&nbsp;</span><span class="Statement">)</span><span class="Error">)</span>&nbsp;<span class="Statement">==</span>&nbsp;<span class="Constant">0</span>&nbsp;<span class="Statement">]]</span><span class="Statement">;</span>&nbsp;<span class="Statement">then</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">echo</span><span class="Constant">&nbsp;-n .</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">fi</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">echo</span><span class="Constant">&nbsp;done</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Identifier">assoc</span>=<span class="Constant">1</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">break</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">fi</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep <span class="Constant">1</span><br />
<span class="Statement">done</span><br />
<br />
<span class="Statement">if </span><span class="Statement">[[</span>&nbsp;<span class="PreProc">$assoc</span>&nbsp;<span class="Statement">!=</span>&nbsp;<span class="Constant">1</span>&nbsp;<span class="Statement">]]</span><span class="Statement">;</span>&nbsp;<span class="Statement">then</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">echo</span><span class="Constant">&nbsp;failed</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">exit</span>&nbsp;<span class="Constant">1</span><br />
<span class="Statement">fi</span><br />
<span class="Identifier">assoc_end</span>=<span class="Error">$(</span><span class="Special">date +%s</span><span class="Error">)</span><br />
<span class="Identifier">assoc_time</span>=<span class="Error">$(</span><span class="Statement">(</span><span class="PreProc">$assoc_end</span><span class="Special">-</span><span class="PreProc">$assoc_start</span><span class="Statement">)</span><span class="Error">)</span><br />
<br />
<span class="Identifier">total_end</span>=<span class="Error">$(</span><span class="Special">date +%s</span><span class="Error">)</span><br />
<span class="Identifier">total_time</span>=<span class="Error">$(</span><span class="Statement">(</span><span class="PreProc">$total_end</span><span class="Special">-</span><span class="PreProc">$total_start</span><span class="Statement">)</span><span class="Error">)</span><br />
<br />
<span class="Statement">echo</span><span class="Constant">&nbsp;-e </span><span class="Statement">&quot;</span><span class="Constant">Time spent (sesconds)</span><span class="Special">\n\t</span><span class="Constant">init: </span><span class="PreProc">$init_time</span><span class="Special">\n\t</span><span class="Constant">association: </span><span class="PreProc">$assoc_time</span><span class="Special">\n\t</span><span class="Constant">Total: </span><span class="PreProc">$total_time</span><span class="Statement">&quot;</span>
</p></blockquote>
<p>Credit to a1l0a2k9, the above script is also from EeeUser forum, but I removed the DHCP part and modprobe part. If you are using DHCP, then you may need the DHCP part and modprobe part from the original script.</p>
<p>Now the &quot;/etc/network/interfaces&quot; part, add the following lines for the ra0 interface:</p>
<blockquote><p>
iface ra0 inet static<br />
up /etc/restart_wireless.sh<br />
address 10.0.14.14<br />
netmask 255.255.255.0<br />
gateway 10.0.14.1<br />
auto ra0
</p></blockquote>
<p>(for DHCP users: change &quot;static&quot; to &quot;manual&quot; and remove the &quot;address&quot;, &quot;netmask&quot; and &quot;gateway&quot; lines.)</p>
<p>And now, &quot;ifup ra0&quot;, then you're done!</p><br/><br/>tags: <a href="http://technorati.com/tag/linux" rel="tag">linux</a>, <a href="http://technorati.com/tag/debian" rel="tag">debian</a>, <a href="http://technorati.com/tag/lenny" rel="tag">lenny</a>, <a href="http://technorati.com/tag/asus" rel="tag">asus</a>, <a href="http://technorati.com/tag/eee" rel="tag">eee</a>, <a href="http://technorati.com/tag/box" rel="tag">box</a>, <a href="http://technorati.com/tag/wireless" rel="tag">wireless</a>, <a href="http://technorati.com/tag/802.11n" rel="tag">802.11n</a>, <a href="http://technorati.com/tag/rt2860" rel="tag">rt2860</a>]]></description>
		<category>linux</category>
		<comments>http://wang.yuxuan.org/blog/2008/11/8/got_802_11n_working_on_asus_eee_box</comments>
		<pubDate>Sat, 8 Nov 2008 11:01:14 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Debian Lenny on Asus Eee Box]]></title>
		<link>http://wang.yuxuan.org/blog/2008/11/6/debian_lenny_on_asus_eee_box</link>
		<guid>http://wang.yuxuan.org/blog/2008/11/6/debian_lenny_on_asus_eee_box</guid>
		<description><![CDATA[<p><em>UPDATE: now we have 802.11n!</em></p>
<p>My old home server is dying these days, so I bought a new <a href="http://www.asus.com/products.aspx?l1=24&l2=165">Asus Eee Box B202</a> to replace it. It uses Intel Atom N270 CPU, 1G memory, 80G harddisk, 10/100/1000 Ethernet and 802.11n wireless.</p>
<p>The first thing I do on it is install Debian Lenny, my favourite system for server.</p>
<h4>Preparing USB flash for net install</h4>
<p>As it didn't come with a cd-rom, I choose USB flash. I use the SD card from my camera and a USB card reader to combine a USB flash, and it can be used to boot successfully.</p>
<p>I prepared the USB flash according to the <a href="http://www.debian.org/releases/lenny/i386/ch04s04.html.en">Debian Lenny documentation</a>, but meet some problems:</p>
<ol>
<li>Google for hd-media returned the hd-media link for Sarge as the first result, I used the boot.img.gz from Sarge and lenny-businesscard iso but the iso can't be found by the installer, so the installer (boot.img.gz) and the iso must match.</li>
<li>The <a href="http://ftp.debian.org/debian/dists/lenny/main/installer-i386/current/images/hd-media/">hd-media from Lenny</a> and the <a href="http://cdimage.debian.org/cdimage/lenny_di_beta2/i386/iso-cd/debian-LennyBeta2-i386-netinst.iso">Lenny beta2 iso</a> didn't match, neither. The installer can recognize the iso, but complain about mismatched kernel version, and prompt you that it need network update. But the installer from boot.img.gz didn't come with ethernet driver, so it will fail and can't continue.</li>
</ol>
<p>So finally I have to use <a href="http://www.debian.org/releases/lenny/i386/ch04s04.html.en#usb-copy-flexible">&quot;the flexible way&quot;</a> and net install. I use the <a href="http://ftp.debian.org/debian/dists/lenny/main/installer-i386/current/images/netboot/debian-installer/i386/initrd.gz">initrd.gz that have ethernet driver</a>, and the <a href="http://ftp.debian.org/debian/dists/lenny/main/installer-i386/current/images/hd-media/vmlinuz">vmlinuz from Lenny hd-media</a>. None of the iso is needed (and you can't use them), all packages will be downloaded from one of the Debian mirrors.</p>
<p>After prepared the USB flash, <b>DON'T FORGET</b> to lock the write protection lock before boot. It will save your life later.</p>
<h4>Install Debian</h4>
<p>Boot from the prepared USB flash, and it contains only GRUB CLI, so you need to boot the installer manually:</p>
<blockquote><p>
root (hd0,0)<br />
kernel /vmlinuz<br />
initrd /initrd.gz<br />
boot
</p></blockquote>
<p>Now you have a Debian Installer that can drive your ethernet card, so you're ready to install.</p>
<p>Install steps are normal, nothing more to say until the grub-install step.</p>
<h4>grub-install failure</h4>
<p>On the grub-install step, it will complain that grub-install (hd0) failed. Why? cause (hd0) is your USB flash and (hd1) is your harddisk! That's why lock the write-protection lock is important, or otherwise it may succeed without write your harddisk mbr. That's really stupid. Manually install grub on (hd1) and it will continue.</p>
<p>And the installation completes.</p>
<h4>The X problem</h4>
<p>After installation, you may find that your X didn't work. This is because it uses a Intel Graphic chipset for lap-top, but it's not lap-top. <a href="https://wiki.ubuntu.com/X/Quirks#Ignore%20LVDS%20Output%20Quirk">Ubuntu wiki</a> have the solution, and it works.</p>
<h4>Wireless driver</h4>
<p><em>UPDATE: follow <a href="http://wang.yuxuan.org/blog/2008/11/8/got_802_11n_working_on_asus_eee_box">my next blog article</a> for official driver and 802.11n!</em></p>
<p>After installation, the first important thing to do is to drive the wireless card. It uses AzureWare card which uses a rt2860 chipset. And luckily, ndiswrapper can do it.</p>
<p>Follow the <a href="http://wiki.debian.org/NdisWrapper">instructions on Debian wiki</a> to install ndiswrapper. The Windows driver is on the CD (you have another computer to read the CD and copy the driver to the Eee Box, do you?), I used the WIN2KXP one. After install ndiswrapper, it works.</p>
<p>But there are some problem in the /etc/network/interfaces, if you use WPA (I didn't get thie problem when using WEP):</p>
<blockquote><p>
auto wlan0<br />
iface wlan0 inet static<br />
address 10.0.14.14<br />
netmask 255.255.255.0<br />
gateway 10.0.14.1<br />
wpa-conf /etc/wpa_supplicant.conf
</p></blockquote>
<p>The configure above can be used to connect router (that I can see it from router admin), but the IP 10.0.14.14 can't be reached by another computer in the subnet. But if you execute an extra:</p>
<blockquote><p># ifconfig wlan0 10.0.14.14</p></blockquote>
<p>Then it will be OK. I don't know why but if I move the &quot;auto wlan0&quot; line after the &quot;wpa-conf&quot; line, it works fine. Maybe it must wait wpa-supplicant to do something first?</p>
<p><del>Another problem is that it can only use 802.11g wireless, if anyone knows how to drive it to 802.11n, please tell me  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_smile.gif" alt=":)" title="" /> </del></p>
<h4>The end and photos</h4>
<p>Finally, I have a new home server now.</p>
<p><a href="http://www.flickr.com/photos/fishywang/3007184120/" title="Asus Eee Box by Yuxuan.fishy.Wang, on Flickr"><img src="http://farm4.static.flickr.com/3154/3007184120_13bca10e7b.jpg" width="500" height="375" alt="Asus Eee Box" /></a></p>
<p><a href="http://www.flickr.com/photos/fishywang/3006345119/" title="Asus Eee Box by Yuxuan.fishy.Wang, on Flickr"><img src="http://farm4.static.flickr.com/3227/3006345119_88de40e81e.jpg" width="375" height="500" alt="Asus Eee Box" /></a></p>
<p><a href="http://www.flickr.com/photos/fishywang/3006346113/" title="Asus Eee Box by Yuxuan.fishy.Wang, on Flickr"><img src="http://farm4.static.flickr.com/3061/3006346113_3aa87452ba.jpg" width="500" height="375" alt="Asus Eee Box" /></a></p>
<p><a href="http://www.flickr.com/photos/fishywang/3007182540/" title="Asus Eee Box by Yuxuan.fishy.Wang, on Flickr"><img src="http://farm4.static.flickr.com/3199/3007182540_105ddb5178.jpg" width="500" height="375" alt="Asus Eee Box" /></a></p><br/><br/>tags: <a href="http://technorati.com/tag/linux" rel="tag">linux</a>, <a href="http://technorati.com/tag/debian" rel="tag">debian</a>, <a href="http://technorati.com/tag/lenny" rel="tag">lenny</a>, <a href="http://technorati.com/tag/asus" rel="tag">asus</a>, <a href="http://technorati.com/tag/eee" rel="tag">eee</a>, <a href="http://technorati.com/tag/box" rel="tag">box</a>]]></description>
		<category>linux</category>
		<comments>http://wang.yuxuan.org/blog/2008/11/6/debian_lenny_on_asus_eee_box</comments>
		<pubDate>Thu, 6 Nov 2008 14:31:00 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Note: git-svn recover from svn failures]]></title>
		<link>http://wang.yuxuan.org/blog/2008/10/9/note_git_svn_recover_from_svn_failures</link>
		<guid>http://wang.yuxuan.org/blog/2008/10/9/note_git_svn_recover_from_svn_failures</guid>
		<description><![CDATA[<p>My company uses svn, and a VPN without Mac client. So I can't commit from home. In order to manage my off-time works, I use git-svn on my MacBook Pro.</p>
<p>Today I'm going to sync my 2 commits in git to svn, using:</p>
<blockquote><p>$ git svn dcommit</p></blockquote>
<p>But after committed the first change, the svn server have no spaces left! So the second commit was failed:</p>
<blockquote><p>End of file found: Can't read file '/tmp/report.tmp': End of file found at /usr/bin/git-svn line 3856</p></blockquote>
<p>After svn admin resolved this problem, and I dcommit again, but it still fails:</p>
<blockquote><p>Merge conflict during commit: File or directory '***.cpp' is out of date; try updating: The version resource does not correspond to the resource within the transaction.  Either the requested version resource is out of date (needs to be updated), or the requested version resource is newer than the transaction root (restart the commit). at /usr/bin/git-svn line 461</p></blockquote>
<p>And I've tried</p>
<blockquote><p>$ git svn fetch</p></blockquote>
<p>but the problem remains. So I decided to manually commit that change.</p>
<p>First, generate a patch from git (&quot;HEAD^&quot; means make a patch against the parent of HEAD, so it's my last change):</p>
<blockquote><p>$ git format-patch HEAD^</p></blockquote>
<p>And this command will generate a 0001--***.patch file. Then, use &quot;svn co&quot; to checkout a svn working copy, and apply that patch:</p>
<blockquote><p>$ patch -i /path/to/0001--***.patch -p1</p></blockquote>
<p>Then, get my last commit log from &quot;git log&quot;, then use &quot;svn ci&quot; to commit it.</p>
<p>Now back to the git working copy, rebase svn:</p>
<blockquote><p>
$ git svn fetch<br />
$ git svn rebase
</p></blockquote>
<p>Then try dcommit again, no conflicts and no commit made (as the svn repository is already up to date).</p>
<p>Hooray!</p><br/><br/>tags: <a href="http://technorati.com/tag/dev" rel="tag">dev</a>, <a href="http://technorati.com/tag/note" rel="tag">note</a>, <a href="http://technorati.com/tag/git" rel="tag">git</a>, <a href="http://technorati.com/tag/svn" rel="tag">svn</a>]]></description>
		<category>dev</category>
		<comments>http://wang.yuxuan.org/blog/2008/10/9/note_git_svn_recover_from_svn_failures</comments>
		<pubDate>Thu, 9 Oct 2008 16:40:25 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Note: how to delete an error calendar in Lightning]]></title>
		<link>http://wang.yuxuan.org/blog/2008/8/12/note_how_to_delete_an_error_calendar_in_lightning</link>
		<guid>http://wang.yuxuan.org/blog/2008/8/12/note_how_to_delete_an_error_calendar_in_lightning</guid>
		<description><![CDATA[<p>As <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=428274"><del>Bug #428274</del></a>, I can't accept any meeting requests sent to my work mailbox, and have to add the meetings into Lightning manually. This is really annoying. As the bug got fixed, I decided to upgrade Lightning to a 0.9pre nightly to get it working.</p>
<p>After upgrading, the following error dialog will greet me every time I start Thunderbird:</p>
<p><a href="http://www.flickr.com/photos/fishywang/2754016772/" title="The error message after I upgrade Lightning to 0.9pre nightly by Yuxuan.fishy.Wang, on Flickr"><img src="http://farm4.static.flickr.com/3222/2754016772_8208af4b9a.jpg" width="500" height="226" alt="The error message after I upgrade Lightning to 0.9pre nightly" /></a></p>
<p>I googled this error message and found that it was caused by the incompatible extension <a href="https://addons.mozilla.org/en-US/thunderbird/addon/5337">ThunderBirthDay</a>. OK, delete the calendar should fix it. No! The calendar was hide from Lightning's calendar list!</p>
<p>Fine, downgrade Lightning and then remove the calendar should work. But unfortunately, Lightning 0.9 have changed the storage format and can't downgrade to 0.8 anymore.</p>
<p>So how to delete that calendar? Maybe I should delete the calendar direct from Lightning's storage. According to <a href="http://www.mozilla.org/projects/calendar/faq.html#format">the official <acronym title="frequently asked questions">FAQ</acronym></a>, it's stored as an SQLite database file.</p>
<p>Under Thunderbird's <a href="http://kb.mozillazine.org/Profile_folder_-_Thunderbird">profile directory</a>, I got a <b>&quot;storage.sdb&quot;</b> file. I tried to use the command line sqlite to open it, and it works:</p>
<blockquote><pre>
$ sqlite3 storage.sdb 
SQLite version 3.5.0
Enter ".help" for instructions
sqlite> .tables
cal_attachments              cal_metadata               
cal_attendees                cal_properties             
cal_calendar_schema_version  cal_recurrence             
cal_calendars                cal_relations              
cal_calendars_prefs          cal_todos                  
cal_calmgr_schema_version    cal_tz_version             
cal_events                 
</pre></blockquote>
<p>The <b>&quot;cal_calendars&quot;</b> table seems to be the one I'm looking for:</p>
<blockquote><p>
sqlite> select * from cal_calendars;<br />
1|storage|moz-profile-calendar://<br />
2|thunderbirthday|moz-abmdbdirectory://abook.mab
</p></blockquote>
<p>Yes it is! so I need to know how to delete that record:</p>
<blockquote><p>
sqlite> .schema cal_calendars<br />
CREATE TABLE cal_calendars (id INTEGER PRIMARY KEY, type TEXT, uri TEXT);
</p></blockquote>
<p>OK, then this should work:</p>
<blockquote><p>
sqlite> delete from cal_calendars where type = "thunderbirthday";<br />
sqlite> select * from cal_calendars;<br />
1|storage|moz-profile-calendar://
</p></blockquote>
<p>It DOES work!</p>
<p>Now my Thunderbird is quiet on starting.</p>
<p>But, the guys in Lightning really should give a chance to delete calendars that aren't compatible. <del>I should file a bug for it.</del> I've filed <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=450121">Bug #450121</a>!</p><br/><br/>tags: <a href="http://technorati.com/tag/thunderbird" rel="tag">thunderbird</a>, <a href="http://technorati.com/tag/lightning" rel="tag">lightning</a>, <a href="http://technorati.com/tag/sqlite" rel="tag">sqlite</a>, <a href="http://technorati.com/tag/thuderbirthday" rel="tag">thuderbirthday</a>]]></description>
		<category>opensource</category>
		<comments>http://wang.yuxuan.org/blog/2008/8/12/note_how_to_delete_an_error_calendar_in_lightning</comments>
		<pubDate>Tue, 12 Aug 2008 00:51:44 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Don't try to fool compilers]]></title>
		<link>http://wang.yuxuan.org/blog/2008/7/11/don_t_try_to_fool_compilers</link>
		<guid>http://wang.yuxuan.org/blog/2008/7/11/don_t_try_to_fool_compilers</guid>
		<description><![CDATA[<p>There's a macro in <a href="http://www.cse.wustl.edu/~schmidt/ACE-overview.html"><acronym title="ADAPTIVE Communication Environment">ACE</acronym></a> to eliminate a compiler warning:</p>
<blockquote class="vimblock"><p>
<span class="lnr">379 </span><span class="Comment">// Some compilers complain about &quot;statement with no effect&quot; with (a).</span><br />
<span class="lnr">380 </span><span class="Comment">// This eliminates the warnings, and no code is generated for the null</span><br />
<span class="lnr">381 </span><span class="Comment">// conditional statement.&nbsp;&nbsp;@note that may only be true if -O is enabled,</span><br />
<span class="lnr">382 </span><span class="Comment">// such as with GreenHills (ghs) 1.8.8.</span><br />
<span class="lnr">383 </span><span class="PreProc"># define ACE_UNUSED_ARG(a) </span><span class="Statement">do</span><span class="PreProc">&nbsp;{</span><span class="Comment">/*</span><span class="Comment">&nbsp;null </span><span class="Comment">*/</span><span class="PreProc">} </span><span class="Statement">while</span><span class="PreProc">&nbsp;(&amp;a == </span><span class="Constant">0</span><span class="PreProc">)</span>
</p></blockquote>
<p>But when I use this macro, gcc 4.3 will complain:</p>
<blockquote>
<p>warning: the address of ‘a’ will never be NULL</p>
</blockquote><br/><br/>tags: <a href="http://technorati.com/tag/dev" rel="tag">dev</a>, <a href="http://technorati.com/tag/compiler" rel="tag">compiler</a>, <a href="http://technorati.com/tag/gcc" rel="tag">gcc</a>, <a href="http://technorati.com/tag/warning" rel="tag">warning</a>, <a href="http://technorati.com/tag/ace" rel="tag">ace</a>]]></description>
		<category>dev</category>
		<comments>http://wang.yuxuan.org/blog/2008/7/11/don_t_try_to_fool_compilers</comments>
		<pubDate>Fri, 11 Jul 2008 12:25:52 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Miao cancelled]]></title>
		<link>http://wang.yuxuan.org/blog/2008/5/26/miao_cancelled</link>
		<guid>http://wang.yuxuan.org/blog/2008/5/26/miao_cancelled</guid>
		<description><![CDATA[<p>I've started <a href="http://oaim.yhsif.com/">the Miao project</a> <a href="http://wang.yuxuan.org/blog/2007/5/14/miao_will_be_a_new_smart_pinyin_input_method_for_mac_os_x">one year ago</a>, aim to build a smart pinyin input method for Mac. But I just got a new job 2 weeks after I started this project. This is quite a busy year, and I haven't really wrote much code for it.</p>
<p>A month ago <a href="http://blogs.sun.com/yongsun/">Yong Sun</a> from <a href="http://www.sun.com/">Sun</a> begin to port <a href="http://opensolaris.org/os/project/input-method/">SunPinyin</a> to Mac, and now it's more than just works. I'm satisfied with the <a href="http://blogs.sun.com/yongsun/tags/sunpinyin" class="chinese">Mac port</a> and use it everyday. As the Miao project is scratching my own itch, and I'm not itchy anymore, I should call it a day.</p>
<p>Sorry for anyone who waits for Miao, but I'm not going to reinvent the wheel.</p><br/><br/>tags: <a href="http://technorati.com/tag/miao" rel="tag">miao</a>, <a href="http://technorati.com/tag/pinyin" rel="tag">pinyin</a>, <a href="http://technorati.com/tag/input" rel="tag">input</a>, <a href="http://technorati.com/tag/method" rel="tag">method</a>, <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/osx" rel="tag">osx</a>, <a href="http://technorati.com/tag/sunpinyin" rel="tag">sunpinyin</a>]]></description>
		<category>opensource</category>
		<comments>http://wang.yuxuan.org/blog/2008/5/26/miao_cancelled</comments>
		<pubDate>Mon, 26 May 2008 20:29:46 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Some facts about Apple Time Capsule performance]]></title>
		<link>http://wang.yuxuan.org/blog/2008/5/7/some_facts_about_apple_time_capsule_performance</link>
		<guid>http://wang.yuxuan.org/blog/2008/5/7/some_facts_about_apple_time_capsule_performance</guid>
		<description><![CDATA[<p>On the Mac side, the initial backup takes me about 6 hours to backup 126GB data, by ethernet cable, so the speed is about 20GB/hr.</p>
<p>The writing speed via 802.11n wireless is as below:</p>
<blockquote><p>
fishy@Makelele:~/Video$ dd if=Pixar\ -\ Lifted.wmv of=/Volumes/Cacapa-1/foo.wmv<br />
91582+1 records in<br />
91582+1 records out<br />
46890385 bytes transferred in 15.478993 secs (3029292 bytes/sec)
</p></blockquote>
<p>That's about 3MB/s. So I think the speed on Mac is acceptable, but it should be faster.</p>
<p>On the Linux side, I use Debian Lenny, with samba, <a href="http://afpfs-ng.sf.net">afpfs-ng</a> and a 100M ethernet cable (my Linux machine didn't come with a Gigabit ethernet port). The facts are:</p>
<p>Writing via AFP:</p>
<blockquote><p>
root@deBoer:~# dd if=prog03.mdb of=foo/foo.mdb<br />
8736+0 records in<br />
8736+0 records out<br />
4472832 bytes (4.5 MB) copied, 6.89061 s, 649 kB/s
</p></blockquote>
<p>Writing via SMB:</p>
<blockquote><p>
root@deBoer:~# dd if=prog03.mdb of=/media/cacapa/bar.mdb<br />
8736+0 records in<br />
8736+0 records out<br />
4472832 bytes (4.5 MB) copied, 6.57683 s, 680 kB/s
</p></blockquote>
<p>Reading via AFP:</p>
<blockquote><p>
root@deBoer:~# dd if=foo/bar.mdb of=bar.mdb<br />
8736+0 records in<br />
8736+0 records out<br />
4472832 bytes (4.5 MB) copied, 8.87068 s, 504 kB/s
</p></blockquote>
<p>Reading via SMB:</p>
<blockquote><p>
root@deBoer:~# dd if=/media/cacapa/foo.mdb of=foo.mdb<br />
8736+0 records in<br />
8736+0 records out<br />
4472832 bytes (4.5 MB) copied, 0.919922 s, 4.9 MB/s
</p></blockquote>
<p>So the conclusion is that, for writing, AFP and SMB are both slow. But for reading, SMB is much much faster than AFP, so you should use SMB to connect a Time Capsule on Linux.</p><br/><br/>tags: <a href="http://technorati.com/tag/apple" rel="tag">apple</a>, <a href="http://technorati.com/tag/time+capsule" rel="tag">time&nbsp;capsule</a>, <a href="http://technorati.com/tag/performance" rel="tag">performance</a>, <a href="http://technorati.com/tag/test" rel="tag">test</a>, <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/linux" rel="tag">linux</a>, <a href="http://technorati.com/tag/smb" rel="tag">smb</a>, <a href="http://technorati.com/tag/afp" rel="tag">afp</a>, <a href="http://technorati.com/tag/speed" rel="tag">speed</a>]]></description>
		<category>General</category>
		<comments>http://wang.yuxuan.org/blog/2008/5/7/some_facts_about_apple_time_capsule_performance</comments>
		<pubDate>Wed, 7 May 2008 23:19:25 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Apple Time Capsule hand on]]></title>
		<link>http://wang.yuxuan.org/blog/2008/4/29/apple_time_capsule_hand_on</link>
		<guid>http://wang.yuxuan.org/blog/2008/4/29/apple_time_capsule_hand_on</guid>
		<description><![CDATA[<p>After long waiting, I got one finally.</p>
<p>The box:</p>
<p><a href="http://www.flickr.com/photos/fishywang/2451150973/" title="Time Capsule - the box by fishy.wang, on Flickr"><img src="http://farm3.static.flickr.com/2009/2451150973_81b254f42e.jpg" width="500" height="375" alt="Time Capsule - the box" /></a></p>
<p>Unboxing:</p>
<p><a href="http://www.flickr.com/photos/fishywang/2451152355/" title="Time Capsule - unboxing by fishy.wang, on Flickr"><img src="http://farm4.static.flickr.com/3097/2451152355_46496e1b8e.jpg" width="500" height="375" alt="Time Capsule - unboxing" /></a></p>
<p>And then working!</p>
<p><a href="http://www.flickr.com/photos/fishywang/2451979758/" title="Time Capsule - working by fishy.wang, on Flickr"><img src="http://farm4.static.flickr.com/3121/2451979758_fd69911e83.jpg" width="500" height="375" alt="Time Capsule - working" /></a></p>
<p>And here's a note, the command to limit my 1TB Time Capsule use only 500G for backup (so that I can use the other 500G for other stuffs), according to the comment of <a href="http://www.macosxhints.com/article.php?story=20071108020121567">this hint</a>:</p>
<blockquote>
<p>hdiutil resize -size 500g -shrinkonly /Volumes/path/to/sparsebundle/</p>
</blockquote>
<p>But the speed of backup is really really slow, that disappointed me. What a shame! It would be perfect if the backup speed up.</p><br/><br/>tags: <a href="http://technorati.com/tag/apple" rel="tag">apple</a>, <a href="http://technorati.com/tag/time" rel="tag">time</a>, <a href="http://technorati.com/tag/capsule" rel="tag">capsule</a>, <a href="http://technorati.com/tag/time" rel="tag">time</a>, <a href="http://technorati.com/tag/machine" rel="tag">machine</a>, <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/osx" rel="tag">osx</a>]]></description>
		<category>General</category>
		<comments>http://wang.yuxuan.org/blog/2008/4/29/apple_time_capsule_hand_on</comments>
		<pubDate>Tue, 29 Apr 2008 20:28:59 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Flickr Video vs. Youtube]]></title>
		<link>http://wang.yuxuan.org/blog/2008/4/14/flickr_video_vs_youtube</link>
		<guid>http://wang.yuxuan.org/blog/2008/4/14/flickr_video_vs_youtube</guid>
		<description><![CDATA[<p>Finally, Video on Flickr!</p>
<p>I've uploaded a test video:</p>
<p><object type="application/x-shockwave-flash" width="400" height="300" data="http://www.flickr.com/apps/video/stewart.swf?v=1.172"> <param name="flashvars" value="intl_lang=en-us&amp;photo_secret=fc3a19b809&amp;photo_id=2400242204&amp;show_info_box=true"></param> <param name="movie" value="http://www.flickr.com/apps/video/stewart.swf?v=1.172"></param> <param name="bgcolor" value="#000000"></param> <param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/video/stewart.swf?v=1.172" bgcolor="#000000" allowfullscreen="true" flashvars="intl_lang=en-us&amp;photo_secret=fc3a19b809&amp;photo_id=2400242204&amp;flickr_show_info_box=true" height="300" width="400"></embed></object></p>
<p>And here's the same video on youtube, to be compared:</p>  
<p><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/HN5LH9g1djA&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/HN5LH9g1djA&amp;hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object></p>
<p>So here's the comparison:</p>
<ul>
<li>Speed: youtube is much much faster than flickr, anyway, youtube consumed half of California's bandwidth, so it's no surprise.</li>
<li>Who can upload: everybody, every free users can upload to youtube, but only pro users ($24.95/y) can upload videos to flickr now.</li>
<li>Geotag: you can geotag your video on flickr, but seems that you can't do it on youtube.</li>
<li>Original file: you can download the original file of <b>your video</b> in flickr's embed page, so in case you lost your original file, it's a way to get it back.</li>
<li>Sizes: there's only 1 size on youtube, but many sizes on flickr to embed.</li>
<li>Group: on flickr, you can group your videos along with your photos, so the photos/videos can be grouped together.</li>
<li>Privacy control: you can filter viewers with your flickr contacts, as I already have a community on flickr, but not on youtube.</li>
</ul>
<p>So, from now on, I may move from youtube to flickr, flickr rocks!</p><br/><br/>tags: <a href="http://technorati.com/tag/youtube" rel="tag">youtube</a>, <a href="http://technorati.com/tag/flickr" rel="tag">flickr</a>, <a href="http://technorati.com/tag/internet" rel="tag">internet</a>, <a href="http://technorati.com/tag/video" rel="tag">video</a>]]></description>
		<category>General</category>
		<comments>http://wang.yuxuan.org/blog/2008/4/14/flickr_video_vs_youtube</comments>
		<pubDate>Mon, 14 Apr 2008 22:03:36 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Yet another NP_Trackback hack]]></title>
		<link>http://wang.yuxuan.org/blog/2007/12/2/yet_another_np_trackback_hack</link>
		<guid>http://wang.yuxuan.org/blog/2007/12/2/yet_another_np_trackback_hack</guid>
		<description><![CDATA[<p>I've got an email from my host administrator to warn me that one of my MySQL table consumed lots of system load, and the table is nucleus_trackback.</p>
<p>But I haven't got any &quot;real&quot; trackbacks, so they are all spams, and more accurate, crazy spams, that simply too much to overload my DB.</p>
<p>So I have to wrote this <a href="http://selif.yhsif.com/np_trackback.drop.patch">patch</a> to add an option to <a href="http://wakka.xiffy.nl/trackback">NP_Trackback</a>: drop blocked trackbacks directly. After enabled, trackbacks that blocked by NP_Trackback (failed spam test or no link) will not be stored into the DB.</p><br/><br/>tags: <a href="http://technorati.com/tag/nucleus" rel="tag">nucleus</a>, <a href="http://technorati.com/tag/trackback" rel="tag">trackback</a>, <a href="http://technorati.com/tag/patch" rel="tag">patch</a>, <a href="http://technorati.com/tag/spam" rel="tag">spam</a>, <a href="http://technorati.com/tag/db" rel="tag">db</a>, <a href="http://technorati.com/tag/mysql" rel="tag">mysql</a>, <a href="http://technorati.com/tag/php" rel="tag">php</a>]]></description>
		<category>opensource</category>
		<comments>http://wang.yuxuan.org/blog/2007/12/2/yet_another_np_trackback_hack</comments>
		<pubDate>Sun, 2 Dec 2007 12:35:40 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[AFP versus SMB]]></title>
		<link>http://wang.yuxuan.org/blog/2007/11/19/afp_versus_smb</link>
		<guid>http://wang.yuxuan.org/blog/2007/11/19/afp_versus_smb</guid>
		<description><![CDATA[<p>I have a Linux file server in my home running Debian Lenny, and I always use SMB for file sharing, it have a very very bad performance. Today I suddenly remember Apple have an AFP protocol, so gave it a try.</p>
<p>I use &quot;apt-cache search afp&quot; to find out that there's a package named &quot;netatalk&quot; can provide AFP file sharing, so install it. But I can only login use guest account, not my system user, from Leopard.</p>
<p>I googled it and found that the problem is: on the Debian side, as a license issue, the Debian package didn't come with SSL support; on the Leopard side, it didn't allow you exchange your password with AFP server without SSL. So the solution is build netatalk yourself, with SSL.</p>
<p>The building steps are described on <a href="http://blog.our-files.com/?p=5">this blog</a>, and I also disabled atalkd as the author suggested, it caused netatalk to start-up much faster than before.</p>
<p>So finally I got a AFP server for my Mac (compare this icon to <a href="http://www.flickr.com/photos/dreamx117/1806309841/">the famous BSOD icon for SMB servers in Leopard</a>  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_razz.gif" alt=":P" title="" /> ):</p>
<p><a href="http://www.flickr.com/photos/fishywang/2046512905/" title="AFP server icon in Leopard by &lt;fishy /&gt;, on Flickr"><img src="http://farm3.static.flickr.com/2325/2046512905_c01641403a_o.png" width="516" height="378" alt="AFP server icon in Leopard" /></a></p>
<p>And as expected, AFP is much much faster than SMB, here's the write test:</p>
<p>For AFP:</p>
<blockquote><pre>
fishy@McManaman:~$ dd if=/dev/zero of=/Volumes/Home\ Directory/foo
^C57345+0 records in
57345+0 records out
29360640 bytes (29 MB) copied, 11.0833 s, 2.6 MB/s
</pre></blockquote>
<p>And for SMB:</p>
<blockquote><pre>
fishy@McManaman:~$ dd if=/dev/zero of=/Volumes/fishy/bar
^C4235+0 records in
4235+0 records out
2168320 bytes (2.2 MB) copied, 10.6889 s, 203 kB/s
</pre></blockquote>
<p>I'm impressed!</p><br/><br/>tags: <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/osx" rel="tag">osx</a>, <a href="http://technorati.com/tag/linux" rel="tag">linux</a>, <a href="http://technorati.com/tag/debian" rel="tag">debian</a>, <a href="http://technorati.com/tag/afp" rel="tag">afp</a>, <a href="http://technorati.com/tag/netatalk" rel="tag">netatalk</a>, <a href="http://technorati.com/tag/leopard" rel="tag">leopard</a>]]></description>
		<category>linux</category>
		<comments>http://wang.yuxuan.org/blog/2007/11/19/afp_versus_smb</comments>
		<pubDate>Mon, 19 Nov 2007 22:38:32 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Gmail IMAP and Date in emails]]></title>
		<link>http://wang.yuxuan.org/blog/2007/10/27/gmail_imap_and_date_in_emails</link>
		<guid>http://wang.yuxuan.org/blog/2007/10/27/gmail_imap_and_date_in_emails</guid>
		<description><![CDATA[<p><em>UPDATE: As in RFC 2822, the format Gmail used is &quot;obsolete&quot;, which means although it's not recommended, clients such as Thunderbird should support it.</em></p>
<p>Finally I've got my <a href="http://www.gmail.com">Gmail</a> account with IMAP access. I use Thunderbird as the mail client, and find that the &quot;date&quot; of many mails are the time I retrieved them via IMAP, which is incorrect.</p>
<p>These mails including gtalk chat logs and Gmail invitation accepted responses, that means most of the mails are sent/generated by Gmail.</p>
<p>An incorrect date mail have a Date line in the headers like this:</p>
<blockquote><p>Date: Fri, 1 Dec 2006 05:35:25 -0800 (PST)</p></blockquote>
<p>And a normal mail have a Date line in the headers like this:</p>
<blockquote><p>﻿﻿Date: Thu, 21 Dec 2006 19:16:34 +0800﻿</p></blockquote>
<p>Seems that the problem is, Thunderbird didn't recognize a Date line with a 3-letter timezone description(the &quot;PST&quot; in this example), so it use the date retrieved instead.</p>
<p>As most of mail clients (even Gmail itself) didn't add this timezone description in the Date line while sending a mail, I guess it's Gmail's fault to add it into the chat logs and invitation responses to make it unstandard? Anyone can tell me what's the definition in the RFC?</p><br/><br/>tags: <a href="http://technorati.com/tag/gmail" rel="tag">gmail</a>, <a href="http://technorati.com/tag/imap" rel="tag">imap</a>, <a href="http://technorati.com/tag/thunderbird" rel="tag">thunderbird</a>, <a href="http://technorati.com/tag/date" rel="tag">date</a>, <a href="http://technorati.com/tag/mail" rel="tag">mail</a>]]></description>
		<category>General</category>
		<comments>http://wang.yuxuan.org/blog/2007/10/27/gmail_imap_and_date_in_emails</comments>
		<pubDate>Sat, 27 Oct 2007 16:54:37 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Patches to make NucleusCMS plugins multi-blog ready]]></title>
		<link>http://wang.yuxuan.org/blog/2007/9/16/patches_to_make_nucleuscms_plugins_multi_blog_ready</link>
		<guid>http://wang.yuxuan.org/blog/2007/9/16/patches_to_make_nucleuscms_plugins_multi_blog_ready</guid>
		<description><![CDATA[<p>I was struggling to find a good multi-blog system to replace <a href="http://www.lifetype.net/">LifeType</a> used on <a class="chinese" href="http://www.buddie5.com">buddie5.com</a> in the past few weeks. I've tried <a href="http://www.movabletype.org/">Movable Type</a> but didn't feel satisfy with it. Finally I found that <a href="http://www.nucleuscms.org">NucleusCMS</a>, which is used here, have good support for multi-blog, so I think it's the solution for me.</p>
<p>Although NucleusCMS itself have good support for multi-blog, as it's mainly used as a single blog system like <a href="http://www.wordpress.org">WordPress</a>, nearly none of the plugins considered the multi-blog situation.</p>
<p>So I made patches for the plugins I used, to make them multi-blog ready.</p>
<p>These patches generally move some option from global to blog, so that every blog can have its own setting. And for some plugins that have an admin area, I also filtered the things it can admin to avoid security risk.</p>
<ul>
<li><a href="http://wang.yuxuan.org/files/multiblog/trackback.patch">patch</a> for <a href="http://wakka.xiffy.nl/trackback">NP_TrackBack</a> 2.1.0:
<ol>
<li>move notify options into blog settings (Notify, NotifyEmail and NoNotifyBlocked)</li>
<li>show admin area when user is blog admin (copied from NP_Referer 1.0 code  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_biggrin.gif" alt=":D" title="" />  )</li>
<li>in admin area, user can only see/manage the trackbacks in a blog he have admin privilege</li>
</ol></li>
<li><a href="http://wang.yuxuan.org/files/multiblog/referrer.patch">patch</a> for <a href="http://wakka.xiffy.nl/referrer">NP_Referrer</a> 1.0.1:
<ol>
<li>roll back to 1.0 to show admin area for non-admin users</li>
<li>in admin area, user can only see/modify the referrers in a blog he have admin privilege</li>
</ol></li>
<li><a href="http://wang.yuxuan.org/files/multiblog/calendar.patch">patch</a> for <a href="http://wakka.xiffy.nl/calendar">NP_Calendar</a>: move the locale option into blog option</li>
<li><a href="http://wang.yuxuan.org/files/multiblog/rssitem.patch">patch</a> for <a href="http://wakka.xiffy.nl/rssitem">NP_RSSItem</a>: move lang, RSSLink and RSSImage option into blog option.</li>
<li><a href="http://wang.yuxuan.org/files/multiblog/weatherreport.patch">patch</a> for <a href="http://wakka.xiffy.nl/weatherreport">NP_WeatherReport</a>: move city_name, city_id and unit option into blog option.</li>
</ul><br/><br/>tags: <a href="http://technorati.com/tag/nucleus" rel="tag">nucleus</a>, <a href="http://technorati.com/tag/nucleuscms" rel="tag">nucleuscms</a>, <a href="http://technorati.com/tag/plugin" rel="tag">plugin</a>, <a href="http://technorati.com/tag/trackback" rel="tag">trackback</a>, <a href="http://technorati.com/tag/referrer" rel="tag">referrer</a>, <a href="http://technorati.com/tag/calendar" rel="tag">calendar</a>, <a href="http://technorati.com/tag/rssitem" rel="tag">rssitem</a>, <a href="http://technorati.com/tag/weatherreport" rel="tag">weatherreport</a>, <a href="http://technorati.com/tag/patch" rel="tag">patch</a>, <a href="http://technorati.com/tag/multiblog" rel="tag">multiblog</a>]]></description>
		<category>opensource</category>
		<comments>http://wang.yuxuan.org/blog/2007/9/16/patches_to_make_nucleuscms_plugins_multi_blog_ready</comments>
		<pubDate>Sun, 16 Sep 2007 22:06:35 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Sync your Lightning with your iCal]]></title>
		<link>http://wang.yuxuan.org/blog/2007/8/14/sync_your_lightning_with_your_ical</link>
		<guid>http://wang.yuxuan.org/blog/2007/8/14/sync_your_lightning_with_your_ical</guid>
		<description><![CDATA[<p>I love Thunderbird, so I use <a href="http://www.mozilla.com/en-US/thunderbird/">Thunderbird</a> + <a href="http://www.mozilla.org/projects/calendar/lightning/">Lightning</a> instead of Mail.app + iCal as my personal schedule and mail solution.</p>
<p>Also it's <a href="http://wiki.mozilla.org/Calendar:Roadmap">promised</a> to have a syncing feature, it didn't have now. But I need the ability to sync my schedule with <a href="http://www.flickr.com/photos/fishywang/608514260/">my Palm Treo 680</a>. I can sync my Palm with iCal, so getting the linkage between Lightning and iCal is a good way to do this.</p>
<p>First, I installed the <a href="https://addons.mozilla.org/en-US/thunderbird/addon/4631">Provider for Google Calendar</a> extension to get the bidirectional access to <a href="http://www.google.com/calendar/">Google Calendar</a> to Lightning.</p>
<p>Then, I use <a href="http://gcaldaemon.sf.net">GCALDaemon</a> to sync my iCal with Google Calendar. It can also sync Google Calendar with Lightning, but Provider for Google Calendar is much better at this.</p>
<p>Now if I add/modify/remove an event in Lightning, Provider for Google Calendar will update my Google Calendar immediately. Later, GCALDaemon will find the update, and update iCal. Now I sync my Palm with my computer, it will get the update.</p>
<p>If I update an event in my Palm, and sync it to iCal, GCALDaemon will update Google Calendar later, and then Lightning will update it later.</p>
<p>So it works.</p>
<p>Make a symbolic link with the ics file of Lightning and iCal may also work, but I can't find the ics file for Lightning  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_razz.gif" alt=":P" title="" /> </p>
<p>You can subscribe <a href="http://www.google.com/calendar/render?cid=fishywang%40gmail.com">my busy/available status on Google Calendar</a> now  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_smile.gif" alt=":)" title="" /> </p>
<p>This should also works for <a href="http://www.mozilla.org/projects/calendar/sunbird/">Mozilla Sunbird</a>.</p><br/><br/>tags: <a href="http://technorati.com/tag/lightning" rel="tag">lightning</a>, <a href="http://technorati.com/tag/sunbird" rel="tag">sunbird</a>, <a href="http://technorati.com/tag/google" rel="tag">google</a>, <a href="http://technorati.com/tag/calendar" rel="tag">calendar</a>, <a href="http://technorati.com/tag/palm" rel="tag">palm</a>, <a href="http://technorati.com/tag/ical" rel="tag">ical</a>, <a href="http://technorati.com/tag/sync" rel="tag">sync</a>]]></description>
		<category>mac</category>
		<comments>http://wang.yuxuan.org/blog/2007/8/14/sync_your_lightning_with_your_ical</comments>
		<pubDate>Tue, 14 Aug 2007 21:18:25 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[The reversed diff]]></title>
		<link>http://wang.yuxuan.org/blog/2007/8/1/the_reversed_diff</link>
		<guid>http://wang.yuxuan.org/blog/2007/8/1/the_reversed_diff</guid>
		<description><![CDATA[<p>We use diff to find out the different lines in 2 files, but sometimes we also need to find out the same lines in 2 files. So we need the &quot;reversed diff&quot;</p>
<p>And this command can be used as the reversed diff:</p>
<blockquote>
<p>cat file1 file2 | sort | uniq -d</p>
</blockquote><br/><br/>tags: <a href="http://technorati.com/tag/diff" rel="tag">diff</a>, <a href="http://technorati.com/tag/uniq" rel="tag">uniq</a>, <a href="http://technorati.com/tag/linux" rel="tag">linux</a>, <a href="http://technorati.com/tag/shell" rel="tag">shell</a>, <a href="http://technorati.com/tag/same" rel="tag">same</a>]]></description>
		<category>linux</category>
		<comments>http://wang.yuxuan.org/blog/2007/8/1/the_reversed_diff</comments>
		<pubDate>Wed, 1 Aug 2007 17:55:56 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Deal with 2 versions of iconv.h]]></title>
		<link>http://wang.yuxuan.org/blog/2007/7/9/deal_with_2_versions_of_iconv_h</link>
		<guid>http://wang.yuxuan.org/blog/2007/7/9/deal_with_2_versions_of_iconv_h</guid>
		<description><![CDATA[<p>There're 2 versions of iconv.h in which the iconv() have different prototypes.</p>
<p>In Debian, it's:</p>
<blockquote class="vimblock">
<p>
<span class="lnr">43 </span><span class="Type">extern</span>&nbsp;<span class="Type">size_t</span>&nbsp;iconv (iconv_t __cd, <span class="Type">char</span>&nbsp;**__restrict __inbuf,<br />
<span class="lnr">44 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">size_t</span>&nbsp;*__restrict __inbytesleft,<br />
<span class="lnr">45 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">char</span>&nbsp;**__restrict __outbuf,<br />
<span class="lnr">46 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="Type">size_t</span>&nbsp;*__restrict __outbytesleft);<br />
</p>
</blockquote>
<p>And in other systems, such as Mac OS X, it's:</p>
<blockquote class="vimblock">
<p>
<span class="lnr">83 </span><span class="Type">extern</span>&nbsp;<span class="Type">size_t</span>&nbsp;iconv (iconv_t cd, <span class="Type">const</span>&nbsp;<span class="Type">char</span>* * inbuf, <span class="Type">size_t</span>&nbsp;*inbytesleft, <span class="Type">char</span>* * outbuf, <span class="Type">size_t</span>&nbsp;*outbytesleft);<br />
</p>
</blockquote>
<p>So you can see that the second parameter, &quot;inbuf&quot;, can be &quot;const char **&quot; or &quot;char **&quot;</p>
<p>It will make a big problem while writing code for both systems. One resolution is to use condition compile (&quot;#ifdef&quot; blah blah...), but RoachCock@<a href="http://www.newsmth.net" class="chinese">newsmth</a> give me another (and much better) resolution: use operator overload (so it's C++ only):</p>
<blockquote class="vimblock">
<p>
<span class="lnr">133 </span><span class="Type">struct</span>&nbsp;iconv_param_adapter {<br />
<span class="lnr">134 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iconv_param_adapter(<span class="Type">const</span>&nbsp;<span class="Type">char</span>**p) : p(p) {}<br />
<span class="lnr">135 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iconv_param_adapter(<span class="Type">char</span>**p) : p((<span class="Type">const</span>&nbsp;<span class="Type">char</span>**)p) {}<br />
<span class="lnr">136 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">operator</span>&nbsp;<span class="Type">char</span>**() <span class="Type">const</span><br />
<span class="lnr">137 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<span class="lnr">138 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">return</span>&nbsp;(<span class="Type">char</span>**)p;<br />
<span class="lnr">139 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span class="lnr">140 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">operator</span>&nbsp;<span class="Type">const</span>&nbsp;<span class="Type">char</span>**() <span class="Type">const</span><br />
<span class="lnr">141 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<span class="lnr">142 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">return</span>&nbsp;(<span class="Type">const</span>&nbsp;<span class="Type">char</span>**)p;<br />
<span class="lnr">143 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span class="lnr">144 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">const</span>&nbsp;<span class="Type">char</span>** p;<br />
<span class="lnr">145 </span>};<br />
</p>
</blockquote>
<p>When you calling &quot;iconv()&quot;, call it like this:</p>
<blockquote class="vimblock">
<p>
<span class="lnr">111 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">size_t</span>&nbsp;res = iconv(data, iconv_param_adapter(&amp;s), &amp;inbytesleft, &amp;outnew, &amp;outbytesleft);<br />
</p>
</blockquote>
<p>Thank you RoachCock!</p><br/><br/>tags: <a href="http://technorati.com/tag/iconv" rel="tag">iconv</a>, <a href="http://technorati.com/tag/debian" rel="tag">debian</a>, <a href="http://technorati.com/tag/c" rel="tag">c</a>, <a href="http://technorati.com/tag/cxx" rel="tag">cxx</a>, <a href="http://technorati.com/tag/cpp" rel="tag">cpp</a>]]></description>
		<category>dev</category>
		<comments>http://wang.yuxuan.org/blog/2007/7/9/deal_with_2_versions_of_iconv_h</comments>
		<pubDate>Mon, 9 Jul 2007 15:58:25 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Add GBK encoding support to expat]]></title>
		<link>http://wang.yuxuan.org/blog/2007/6/18/add_gbk_encoding_support_to_expat</link>
		<guid>http://wang.yuxuan.org/blog/2007/6/18/add_gbk_encoding_support_to_expat</guid>
		<description><![CDATA[<p><a href="http://expat.sf.net">expat</a> is a good XML parser, light and quick. But it only support latin1, UTF-8 and UTF-16 naturally, if you want to use it to deal with other encoding XML's, you need to <a href="http://www.xml.com/pub/a/1999/09/expat/index.html?page=3#setunknown">set a unknown encoding handler</a>.</p>
<p>I use <a href="http://www.gnu.org/software/libiconv/">libiconv</a> to convert the GBK string to Unicode for expat.</p>
<p>First, implement a function to pass to XML_SetUnknownEncodingHandler:</p>
<blockquote class="vimblock">
<p>
<span class="Type">int</span><br />
XML_Stream_Parser::<span />xml_unknown_encoding(<span class="Type">void</span>* data, <span class="Type">const</span>&nbsp;<span class="Type">char</span>* name, XML_Encoding* info) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iconv_t cd;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">if</span>(strncasecmp(name, <span class="Constant">&quot;GB&quot;</span>, <span class="Constant">2</span>) != <span class="Constant">0</span>&nbsp;|| (cd = iconv_open(<span class="Constant">&quot;UCS-2BE&quot;</span>, name)) == (iconv_t)-<span class="Constant">1</span>) {&nbsp;&nbsp;&nbsp;&nbsp; <span class="Comment">// not GB, unsupported</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;can't convert </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, name);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">return</span>&nbsp;<span class="Constant">0</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">for</span>(<span class="Type">size_t</span>&nbsp;i=<span class="Constant">0</span>; i&lt;<span class="Constant">128</span>; i++) info-&gt;map[i] = i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">for</span>(<span class="Type">size_t</span>&nbsp;i=<span class="Constant">128</span>; i&lt;<span class="Constant">256</span>; i++) info-&gt;map[i] = -<span class="Constant">2</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info-&gt;convert = XML_Stream_Parser::<span />xml_convert_gb;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info-&gt;release = XML_Stream_Parser::<span />xml_convert_release;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info-&gt;data = cd;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">return</span>&nbsp;<span class="Constant">1</span>;<br />
}<br />
</p>
</blockquote>
<p>In this function, I tell expat that for GBK encoding, ASCII 0~127 is left as is, and ASCII 128~255 will need to be dealt together with the next byte.</p>
<p>Then implement the &quot;convert&quot; and &quot;release&quot; functions:</p>
<blockquote class="vimblock">
<p>
<span class="Type">int</span><br />
XML_Stream_Parser::<span />xml_convert_gb(<span class="Type">void</span>* data, <span class="Type">const</span>&nbsp;<span class="Type">char</span>* s) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">const</span>&nbsp;<span class="Type">size_t</span>&nbsp;out_initial = <span class="Constant">4</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">size_t</span>&nbsp;inbytesleft = <span class="Constant">2</span>, outbytesleft = out_initial;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">char</span>&nbsp;*out = <span class="Statement">new</span>&nbsp;<span class="Type">char</span>[out_initial], *outnew = out;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">size_t</span>&nbsp;res = iconv(data, &amp;s, &amp;inbytesleft, &amp;outnew, &amp;outbytesleft);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">int</span>&nbsp;ret = <span class="Constant">0</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">if</span>(res == (<span class="Type">size_t</span>)-<span class="Constant">1</span>) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;error in conversion</span><span class="Special">\n</span><span class="Constant">&quot;</span>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">delete</span>&nbsp;[]out;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">return</span>&nbsp;<span class="Constant">'?'</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">for</span>(<span class="Type">size_t</span>&nbsp;i = <span class="Constant">0</span>; i &lt; out_initial - outbytesleft; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = (ret&lt;&lt;<span class="Constant">8</span>) + (<span class="Type">unsigned</span>&nbsp;<span class="Type">char</span>)out[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">delete</span>&nbsp;[]out;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">return</span>&nbsp;ret;<br />
}<br />
<br />
<span class="Type">void</span><br />
XML_Stream_Parser::<span />xml_convert_release(<span class="Type">void</span>* data) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iconv_close(data);<br />
}<br />
</p>
</blockquote>
<p>In &quot;convert&quot;, I use iconv to convert the string to unicode, and return the unicode to expat.</p>
<p>The limitation in this interface is that it can't deal with 4-byte GB18030 codes, as I can't judge whether it's a 4-byte code just by the first code.</p>
<p>Anyway, I suggest that all XML should be encoded to UTF-8, so that this is unneeded  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_razz.gif" alt=":P" title="" /> </p><br/><br/>tags: <a href="http://technorati.com/tag/expat" rel="tag">expat</a>, <a href="http://technorati.com/tag/encoding" rel="tag">encoding</a>, <a href="http://technorati.com/tag/iconv" rel="tag">iconv</a>, <a href="http://technorati.com/tag/libiconv" rel="tag">libiconv</a>, <a href="http://technorati.com/tag/gbk" rel="tag">gbk</a>]]></description>
		<category>dev</category>
		<comments>http://wang.yuxuan.org/blog/2007/6/18/add_gbk_encoding_support_to_expat</comments>
		<pubDate>Mon, 18 Jun 2007 18:46:30 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Farmr]]></title>
		<link>http://wang.yuxuan.org/blog/2007/6/10/farmr</link>
		<guid>http://wang.yuxuan.org/blog/2007/6/10/farmr</guid>
		<description><![CDATA[<p><a href="http://selif.yhsif.com/farmr.user.js">farmr</a> is a <a href="http://greasemonkey.mozdev.org/">GreaseMonkey</a> script.</p>
<p>It's purpose is to recover some image source URL that was f'ed by some firewall, with the URL with web proxy.</p>
<p>I used the web proxy code from <a href="https://addons.mozilla.org/en-US/firefox/addon/2864">gladder</a>, credit to <a href="http://www.gneheix.com">gneheix</a>.</p>
<p>For <a href="http://www.caminobrowser.com">Camino</a> users that can't use GreaseMonkey directly, you can use <a href="http://pimpmycamino.com/parts/geekmonkey">GeekMonkey</a>.</p>
<p>Enjoy it and f' back.</p><br/><br/>tags: <a href="http://technorati.com/tag/greasemonkey" rel="tag">greasemonkey</a>, <a href="http://technorati.com/tag/geekmonkey" rel="tag">geekmonkey</a>, <a href="http://technorati.com/tag/camino" rel="tag">camino</a>, <a href="http://technorati.com/tag/gfw" rel="tag">gfw</a>]]></description>
		<category>opensource</category>
		<comments>http://wang.yuxuan.org/blog/2007/6/10/farmr</comments>
		<pubDate>Sun, 10 Jun 2007 11:43:18 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Simple SQLite test C program, without callbacks]]></title>
		<link>http://wang.yuxuan.org/blog/2007/5/22/simple_sqlite_test_c_program_without_callbacks</link>
		<guid>http://wang.yuxuan.org/blog/2007/5/22/simple_sqlite_test_c_program_without_callbacks</guid>
		<description><![CDATA[<p>I need some efficient way for <a href="http://oaim.yhsif.com">Miao</a> for word database, and I guess <a href="http://www.sqlite.org">SQLite</a> is the solution. So I wrote this simple test program to get familiar with SQLite <acronym title="application program interface">API</acronym>. (read more for the program)</p>
<p>And there's something should be kept in mind: don't use &quot;`&quot;s.</p>
<p>As I used to use MySQL before, I always put &quot;`&quot; in SQL statements, for example:</p>
<blockquote><p>create table `foo` (`bar` int)</p></blockquote>
<p>It's OK in SQLite command line program, but not in the C library.</p>
<p>When I execute a SQL query with &quot;`&quot;, I'll get this error message:</p>
<blockquote><p>sql error #1: unrecognized token: &quot;`&quot;</p></blockquote>
<p>So I deleted &quot;`&quot;s in the SQL statement, but still get this error message:</p>
<blockquote><p>sql error #4: malformed database schema - unrecognized token: &quot;`&quot;</p></blockquote>
<p>This really drive me crazy, as I don't know what's wrong. But finally I've got the reason: that's because there's &quot;`&quot; in the &quot;create table&quot; statement. So I recreated the table and rerun the program, it's finally OK now.</p>The program:</p>
<blockquote class="vimblock">
<p>
<span class="lnr">&nbsp;1 </span><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span><br />
<span class="lnr">&nbsp;2 </span><span class="PreProc">#include </span><span class="Constant">&lt;stdlib.h&gt;</span><br />
<span class="lnr">&nbsp;3 </span><span class="PreProc">#include </span><span class="Constant">&lt;sqlite3.h&gt;</span><br />
<span class="lnr">&nbsp;4 </span><br />
<span class="lnr">&nbsp;5 </span><span class="PreProc">#define NAME </span><span class="Constant">&quot;miao.db&quot;</span><br />
<span class="lnr">&nbsp;6 </span><br />
<span class="lnr">&nbsp;7 </span><span class="Type">int</span>&nbsp;main() {<br />
<span class="lnr">&nbsp;8 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sqlite3 *db;<br />
<span class="lnr">&nbsp;9 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sqlite3_stmt *stmt;<br />
<span class="lnr">10 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">int</span>&nbsp;rc;<br />
<span class="lnr">11 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">char</span>&nbsp;*errmsg = <span class="Constant">0</span>;<br />
<span class="lnr">12 </span><br />
<span class="lnr">13 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rc = sqlite3_open(NAME, &amp;db);<br />
<span class="lnr">14 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">if</span>(rc) {<br />
<span class="lnr">15 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;can't open db </span><span class="Special">%s</span><span class="Constant">: </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, NAME, sqlite3_errmsg(db));<br />
<span class="lnr">16 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sqlite3_close(db);<br />
<span class="lnr">17 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(<span class="Constant">1</span>);<br />
<span class="lnr">18 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span class="lnr">19 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rc = sqlite3_prepare(db, <span class="Constant">&quot;select * from words&quot;</span>, <span class="Constant">0</span>, &amp;stmt, <span class="Constant">0</span>);<br />
<span class="lnr">20 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">if</span>(rc!=SQLITE_OK) {<br />
<span class="lnr">21 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;sql error #</span><span class="Special">%d</span><span class="Constant">: </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, rc, sqlite3_errmsg(db));<br />
<span class="lnr">22 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <span class="Statement">else</span>&nbsp;<span class="Statement">while</span>((rc = sqlite3_step(stmt)) != SQLITE_DONE) {<br />
<span class="lnr">23 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">switch</span>(rc) {<br />
<span class="lnr">24 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">case</span>&nbsp;SQLITE_BUSY:<br />
<span class="lnr">25 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;busy, wait 1 seconds</span><span class="Special">\n</span><span class="Constant">&quot;</span>);<br />
<span class="lnr">26 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(<span class="Constant">1</span>);<br />
<span class="lnr">27 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">break</span>;<br />
<span class="lnr">28 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">case</span>&nbsp;SQLITE_ERROR:<br />
<span class="lnr">29 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(<span class="Constant">stderr</span>, <span class="Constant">&quot;step error: </span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>, sqlite3_errmsg(db));<br />
<span class="lnr">30 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">break</span>;<br />
<span class="lnr">31 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">case</span>&nbsp;SQLITE_ROW:<br />
<span class="lnr">32 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<span class="lnr">33 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">int</span>&nbsp;n = sqlite3_column_count(stmt);<br />
<span class="lnr">34 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">int</span>&nbsp;i;<br />
<span class="lnr">35 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">for</span>(i=<span class="Constant">0</span>; i&lt;n; i++) {<br />
<span class="lnr">36 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant">&nbsp;= &quot;</span>, sqlite3_column_name(stmt, i));<br />
<span class="lnr">37 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">switch</span>(sqlite3_column_type(stmt, i)) {<br />
<span class="lnr">38 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">case</span>&nbsp;SQLITE_TEXT:<br />
<span class="lnr">39 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Constant">&quot;</span>, sqlite3_column_text(stmt, i));<br />
<span class="lnr">40 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">break</span>;<br />
<span class="lnr">41 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">case</span>&nbsp;SQLITE_INTEGER:<br />
<span class="lnr">42 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(<span class="Constant">&quot;</span><span class="Special">%d</span><span class="Constant">&quot;</span>, sqlite3_column_int(stmt, i));<br />
<span class="lnr">43 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">break</span>;<br />
<span class="lnr">44 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">case</span>&nbsp;SQLITE_FLOAT:<br />
<span class="lnr">45 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(<span class="Constant">&quot;</span><span class="Special">%f</span><span class="Constant">&quot;</span>, sqlite3_column_double(stmt, i));<br />
<span class="lnr">46 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">break</span>;<br />
<span class="lnr">47 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">case</span>&nbsp;SQLITE_BLOB:<br />
<span class="lnr">48 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(<span class="Constant">&quot;(blob)&quot;</span>);<br />
<span class="lnr">49 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">break</span>;<br />
<span class="lnr">50 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">case</span>&nbsp;SQLITE_NULL:<br />
<span class="lnr">51 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(<span class="Constant">&quot;(null)&quot;</span>);<br />
<span class="lnr">52 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">break</span>;<br />
<span class="lnr">53 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">default</span>:<br />
<span class="lnr">54 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(<span class="Constant">&quot;(unknown: </span><span class="Special">%d</span><span class="Constant">)&quot;</span>, sqlite3_column_type(stmt, i));<br />
<span class="lnr">55 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span class="lnr">56 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(<span class="Constant">&quot;</span><span class="Special">\n</span><span class="Constant">&quot;</span>);<br />
<span class="lnr">57 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span class="lnr">58 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span class="lnr">59 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">break</span>;<br />
<span class="lnr">60 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span class="lnr">61 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span class="lnr">62 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sqlite3_finalize(stmt);<br />
<span class="lnr">63 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sqlite3_close(db);<br />
<span class="lnr">64 </span>}<br />
<span class="lnr">65 </span><br />
</p>
</blockquote>
<p><br/><br/>tags: <a href="http://technorati.com/tag/sqlite" rel="tag">sqlite</a>, <a href="http://technorati.com/tag/c" rel="tag">c</a>, <a href="http://technorati.com/tag/program" rel="tag">program</a>]]></description>
		<category>dev</category>
		<comments>http://wang.yuxuan.org/blog/2007/5/22/simple_sqlite_test_c_program_without_callbacks</comments>
		<pubDate>Tue, 22 May 2007 00:38:33 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Add emacs mode line support to vim, and call for help]]></title>
		<link>http://wang.yuxuan.org/blog/2007/5/19/add_emacs_mode_line_support_to_vim_and_call_for_help</link>
		<guid>http://wang.yuxuan.org/blog/2007/5/19/add_emacs_mode_line_support_to_vim_and_call_for_help</guid>
		<description><![CDATA[<p>Different editor configurations, especially tabstops are always pain for co-work. So if everyone uses vim, you can specify some vim instruction to override one's vim configuration in your file, just like:</p>
<blockquote><p>// vim:tabstop=4:</p></blockquote>
<p>And if everyone uses emacs, you can also specify emacs mode line like:</p>
<blockquote><p>// -*- tab-width: 2 -*-</p></blockquote>
<p>But what about make vim to read emacs mode line? I've wrote a <a href="http://wang.yuxuan.org/files/emacsmodeline.vim">script</a> to do so.</p>
<p>As I didn't use emacs at all, I don't know which instructions can be specified in the emacs mode line. I just wrote a handler for &quot;tab-width&quot; as an example. If you are familiar with both emacs and vim, please help me to add more handlers into this script.</p>
<p>After more handlers added, I'll submit this script to <a href="http://www.vim.org">vim.org</a>.</p><br/><br/>tags: <a href="http://technorati.com/tag/vim" rel="tag">vim</a>, <a href="http://technorati.com/tag/emacs" rel="tag">emacs</a>, <a href="http://technorati.com/tag/mode" rel="tag">mode</a>, <a href="http://technorati.com/tag/line" rel="tag">line</a>, <a href="http://technorati.com/tag/script" rel="tag">script</a>]]></description>
		<category>opensource</category>
		<comments>http://wang.yuxuan.org/blog/2007/5/19/add_emacs_mode_line_support_to_vim_and_call_for_help</comments>
		<pubDate>Sat, 19 May 2007 02:25:41 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Miao: (will be) a new smart pinyin input method for Mac OS X]]></title>
		<link>http://wang.yuxuan.org/blog/2007/5/14/miao_will_be_a_new_smart_pinyin_input_method_for_mac_os_x</link>
		<guid>http://wang.yuxuan.org/blog/2007/5/14/miao_will_be_a_new_smart_pinyin_input_method_for_mac_os_x</guid>
		<description><![CDATA[<h4>Why another pinyin input method?</h4>
<p>The answer is simple: the current pinyin input methods on Mac doesn't satisfy me. I'm going to scratch my own itch  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_razz.gif" alt=":P" title="" /> </p>
<p>ITABC (comes with Mac) and Pinyin Module in <a href="http://openvanilla.org">OpenVanilla</a> isn't a smart input method; <a href="http://glider.ismac.cn/RegQIME.html">QIM</a> is smart but it's a shareware, and a expensive shareware (USD 19.99 or RMB 69.00, but only for one major version free update); <a href="http://fit.coollittlethings.com/" class="chinese"><acronym title="fun input toy">FIT</acronym></a> is smarter than ITABC and free (for charge), but is not smart enough and I don't like some of its feature but can't turn them off.</p>
<p>Miao will be a smart pinyin input method, designed for people who likes to input a whole sentence once. It will learn user's accustoming and finally become a essential tool in inputing (after some training).</p>
<h4>The idea and feature</h4>
<p>I won't focus on pre-train dictionaries, just like <a href="http://www.sogou.com/pinyin/" class="chinese">Sogou Pinyin</a> or <a href="http://tools.google.com/pinyin/" class="chinese">Google Pinyin</a>. My focus will be on &quot;learning&quot;</p>
<p>For each sentence you input, it will record the words within the sentence, including continuos words and non-continuos words, and calculated for probability.</p>
<p>Continuos word probability will be used to auto-learn new words, that is, if there's a high probability that two known words will comes together, they will be formed as a new word.</p>
<p>Non-continuos word probability will be used for candidate word sorting. The word with the highest probability will get ordered first. As a instance, for the pinyin word &quot;yaoming&quot;, if the sentence comes with &quot;huojian&quot;(火箭/Rockets), &quot;maidi&quot;(麦迪/McGrady), it's more likely to be &quot;姚明&quot;(Yao Ming the NBA player); If the sentence comes with &quot;can&quot;(惨/misery), it's more likely to be &quot;要命&quot;(Kill me!).</p>
<h4>The license</h4>
<p>It may be licensed under GPL or BSD license, it's not decided yet. But I can assume that it will be certainly free, as freedom!</p>
<h4>About the name</h4>
<p>&quot;Miao&quot; is the pinyin of the Chinese character &quot;<a href="http://zh.uncyclopedia.info/wiki/%E5%96%B5%E5%96%B5%E5%96%B5%E5%96%B5%E5%96%B5%21">喵</a>&quot;, which just like &quot;meow&quot; in English, is &quot;the characteristic crying sound of a cat&quot; (from Oxford American Dictionaries).</p>
<p>It's a pinyin input method, so I choose a pinyin word as its name  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_razz.gif" alt=":P" title="" /> </p>
<h4>Other informations</h4>
<p>I should write it as a module for <a href="http://openvanilla.org">OpenVanilla</a>, instead of stand-alone. The reason is that I'm not going to reinvent the wheel. I want to focus on the learning algorithm, but not the system interfaces. And this may make it easier to port into other platforms, for example Linux.</p>
<p>The project homepage will be <a href="http://oaim.yhsif.com">http://oaim.yhsif.com</a>. I'll start it soon, any contribution, e.g. codes, ideas or artworks, are appreciated.</p><br/><br/>tags: <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/osx" rel="tag">osx</a>, <a href="http://technorati.com/tag/pinyin" rel="tag">pinyin</a>, <a href="http://technorati.com/tag/input" rel="tag">input</a>, <a href="http://technorati.com/tag/method" rel="tag">method</a>, <a href="http://technorati.com/tag/miao" rel="tag">miao</a>]]></description>
		<category>opensource</category>
		<comments>http://wang.yuxuan.org/blog/2007/5/14/miao_will_be_a_new_smart_pinyin_input_method_for_mac_os_x</comments>
		<pubDate>Mon, 14 May 2007 16:30:55 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Vim Tip: vim and ctags]]></title>
		<link>http://wang.yuxuan.org/blog/2007/4/25/vim_tip_vim_and_ctags</link>
		<guid>http://wang.yuxuan.org/blog/2007/4/25/vim_tip_vim_and_ctags</guid>
		<description><![CDATA[<p>If you use <a href="http://www.vim.org/">vim</a> for programming, then you can't live without <a href="http://ctags.sourceforge.net/">ctags</a> (can you?). ctags generate the &quot;tags&quot; file, vim and its plugins use this file to help your programming more efficiently.</p>
<p>By default, vim will only use the &quot;tags&quot; file under your current working directory. You can use this command to see it:</p>
<blockquote>
<p>:set tags?</p>
</blockquote>
<p>Generally, your &quot;tags&quot; file under you current working directory won't contain informations about system libraries (glibc, stl, etc.). If you miss them, you can generate tags file for your system libraries, and ask your vim to load them:</p>
<blockquote class="vimblock">
<p>
<span class="Statement">set</span>&nbsp;<span class="PreProc">tags</span>+=/usr/local/include/tags<br/>
<span class="Statement">set</span>&nbsp;<span class="PreProc">tags</span>+=/usr/include/tags<br/>
</p>
</blockquote>
<p>If you are working on a big project, which have many subdirectories, the &quot;tags&quot; file under each working directory may be not enough, as you also need some information about the functions under other subdirectories. So you can generate a &quot;tags&quot; file under your project root, and ask vim to load it when editing a file within your project:</p>
<blockquote class="vimblock">
<p>
<span class="Statement">autocmd</span>&nbsp;<span class="Type">BufEnter</span>&nbsp;~/work/myproj/*&nbsp;:<span class="Statement">setlocal</span>&nbsp;<span class="Statement">tags</span><span class="Statement">+=~</span>/work/myproj/<span class="Statement">tags</span><br/>
</p>
</blockquote>
<p>Thanks for Ryan Phillips, you can also add &quot;tags;&quot; (notice the semicolon) to your tags so that vim will automatically look up &quot;tags&quot; file in the file tree (&quot;:help file-searching&quot; for document):</p>
<blockquote class="vimblock">
<p>
<span class="Statement">set</span>&nbsp;<span class="PreProc">tags</span>+=tags;<br/>
</p>
</blockquote>
<p>To make it easier to use, I've also made a script named <a href="http://www.vim.org/scripts/script.php?script_id=1873">&quot;projtags.vim&quot;</a> so that you need only set your project directories in your vimrc:</p>
<blockquote class="vimblock">
<p>
<span class="Statement">let</span>&nbsp;g<span>:</span>ProjTags&nbsp;<span class="Statement">=</span>&nbsp;[<span class="Constant">&quot;~/work/proj1&quot;</span>]<br/>
<span class="Statement">let</span>&nbsp;g<span>:</span>ProjTags<span class="Statement">+=</span>&nbsp;[[<span class="Constant">&quot;~/work/proj2&quot;</span>, <span class="Constant">&quot;~/work/proj2.tags&quot;</span>]]<br/>
</p>
</blockquote>
<p>Happy vimming  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_razz.gif" alt=":P" title="" /> </p><br/><br/>tags: <a href="http://technorati.com/tag/vim" rel="tag">vim</a>, <a href="http://technorati.com/tag/ctags" rel="tag">ctags</a>, <a href="http://technorati.com/tag/tags" rel="tag">tags</a>, <a href="http://technorati.com/tag/project" rel="tag">project</a>]]></description>
		<category>dev</category>
		<comments>http://wang.yuxuan.org/blog/2007/4/25/vim_tip_vim_and_ctags</comments>
		<pubDate>Wed, 25 Apr 2007 02:37:29 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Live Spaces suck, one more time]]></title>
		<link>http://wang.yuxuan.org/blog/2007/4/24/live_spaces_suck_one_more_time</link>
		<guid>http://wang.yuxuan.org/blog/2007/4/24/live_spaces_suck_one_more_time</guid>
		<description><![CDATA[<p>Live Spaces made some change days before, and that makes me unable to see any live space pages.</p>
<p>When I use Camino to visit live spaces pages, I always get a &quot;XML Parsing Error&quot;, even the page I'm visiting is not the RSS but a html. When I use Firefox or Safari, I always get a <acronym title="hyper text transfer protocol">HTTP</acronym> 500 error.</p>
<p>The &quot;XML Parsing Error&quot; is really weird. It seems that the live spaces server send a wrong &quot;Content-Type&quot; so that Camino treat it as a XML document and try to parse it use a XML tree, and that failed (with &quot;view source&quot; I can see the html source corretly).</p>
<p>But Camino didn't have a extension like <a href="http://livehttpheaders.mozdev.org/">live <acronym title="hyper text transfer protocol">HTTP</acronym> headers</a> to see what Content-Type do the server send, thanks to smorgan on <a href="http://forums.mozillazine.org/">MozillaZine Forums</a>, I can see it using <a href="http://curl.haxx.se/">curl</a>.</p>
<p>This is what curl get:</p>
<blockquote><p>
McManaman:~ fishy$ curl -v <a href="http://spaces.live.com">http://spaces.live.com</a> -o /dev/null 2>&amp;1 | grep Content-Type<br />
&lt; Content-Type: application/xhtml+xml; charset=utf-8
</p></blockquote>
<p>This is what Camino will get:</p>
<blockquote><p>
McManaman:~ fishy$ curl -v <a href="http://spaces.live.com">http://spaces.live.com</a> -o /dev/null -A &quot;Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en; rv:1.8.1.4pre) Gecko/20070408 Camino/1.1b+&quot; 2>&amp;1 | grep Content-Type<br />
&lt; Content-Type: application/xhtml+xml; charset=utf-8
</p></blockquote>
<p>This is what Firefox will get:</p>
<blockquote><p>
McManaman:~ fishy$ curl -v <a href="http://spaces.live.com">http://spaces.live.com</a> -o /dev/null -A &quot;Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0&quot; 2>&amp;1 | grep Content-Type<br />
&lt; Content-Type: text/html; charset=utf-8
</p></blockquote>
<p>And this is what Safari will get:</p>
<blockquote><p>
McManaman:~ fishy$ curl -v <a href="http://spaces.live.com">http://spaces.live.com</a> -o /dev/null -A &quot;Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/418.9.1 (KHTML, like Gecko) Safari/419.3&quot; 2>&amp;1 | grep Content-Type<br />
&lt; Content-Type: text/html; charset=utf-8
</p></blockquote>
<p>As you can see, for some common browsers, such as Firefox or Safari, live spaces server send the right Content-Type. For unknown browsers (including curl, Camino, etc.), it claims that it's &quot;application/xhtml+xml&quot;. Oh my god, what did they think they are doing? What can they get from this Content-Type? I can't understand this at all.</p>
<p>So the only word I can say is, &quot;live spaces suck, one more time&quot;</p><br/><br/>tags: <a href="http://technorati.com/tag/live" rel="tag">live</a>, <a href="http://technorati.com/tag/spaces" rel="tag">spaces</a>, <a href="http://technorati.com/tag/content-type" rel="tag">content-type</a>, <a href="http://technorati.com/tag/browser" rel="tag">browser</a>, <a href="http://technorati.com/tag/user-agent" rel="tag">user-agent</a>]]></description>
		<category>w3c</category>
		<comments>http://wang.yuxuan.org/blog/2007/4/24/live_spaces_suck_one_more_time</comments>
		<pubDate>Tue, 24 Apr 2007 03:18:46 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Note: make ISO image of your disks on Mac OS X]]></title>
		<link>http://wang.yuxuan.org/blog/2007/4/19/note_make_iso_image_of_your_disks_on_mac_os_x</link>
		<guid>http://wang.yuxuan.org/blog/2007/4/19/note_make_iso_image_of_your_disks_on_mac_os_x</guid>
		<description><![CDATA[<p>If you prefer DMG or CDR format, then you can just use Disk Utilities to make image of your disks. But if you prefer ISO format, then this is the way.</p>
<ol>
<li>Insert your disk into your driver, of course.</li>
<li>Unmount it but didn't eject it. To do so, you need to type this command in your Terminal: &quot;sudo umount /dev/disk1&quot;. &quot;disk1&quot; may vary depends on your other drivers.</li>
<li>Use dd to create the image: &quot;dd if=/dev/disk1 of=/path/to/foo.iso&quot;. Again, &quot;disk1&quot; may vary.</li>
<li>When it's done, you've got the ISO image file, and you may eject the disk now. But as a bug in Finder, you can't eject a volume which you unmounted in Terminal in normal ways. Instead, you need to type this command in Terminal to eject it: &quot;sudo diskutil eject /dev/disk1&quot;</li>
</ol>
<p>The Finder bug is really annoying, even a logout can't eject the disk, you must reboot your machine. But fortunately I've found the workaround on <a href="http://www.macosxhints.com/article.php?story=20070313192221659">macosxhints</a>.</p><br/><br/>tags: <a href="http://technorati.com/tag/iso" rel="tag">iso</a>, <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/osx" rel="tag">osx</a>, <a href="http://technorati.com/tag/disk" rel="tag">disk</a>, <a href="http://technorati.com/tag/image" rel="tag">image</a>]]></description>
		<category>mac</category>
		<comments>http://wang.yuxuan.org/blog/2007/4/19/note_make_iso_image_of_your_disks_on_mac_os_x</comments>
		<pubDate>Thu, 19 Apr 2007 01:24:59 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Bash script: batch resize your photos]]></title>
		<link>http://wang.yuxuan.org/blog/2007/3/21/bash_script_batch_resize_your_photos</link>
		<guid>http://wang.yuxuan.org/blog/2007/3/21/bash_script_batch_resize_your_photos</guid>
		<description><![CDATA[<p>If you toke some photos by your camera, and want to post them to somewhere (for example, I want to post the photo of my Treo 650 because I'm going to sell it), you may need to batch resize your photos.</p>
<p>This bash script shows how to uses ImageMagick to batch resize your photos:</p>
<blockquote class="vimblock">
<p>
<span class="lnr">1 </span><span class="Comment">#!/bin/sh</span><br/>
<span class="lnr">2 </span><br/>
<span class="lnr">3 </span><span class="Statement">for</span>&nbsp;file <span class="Statement">in</span>&nbsp;*.JPG<span class="Statement">;</span>&nbsp;<span class="Statement">do</span><br/>
<span class="lnr">4 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;convert -resize 1024x768 <span class="PreProc">$file</span>&nbsp;<span class="PreProc">${</span><span class="PreProc">file</span><span class="Error">%.JPG</span><span class="PreProc">}</span>_resize.jpg<br/>
<span class="lnr">5 </span><span class="Statement">done</span><br/>
</p>
</blockquote><br/><br/>tags: <a href="http://technorati.com/tag/batch" rel="tag">batch</a>, <a href="http://technorati.com/tag/resize" rel="tag">resize</a>, <a href="http://technorati.com/tag/imagemagick" rel="tag">imagemagick</a>, <a href="http://technorati.com/tag/bash" rel="tag">bash</a>, <a href="http://technorati.com/tag/script" rel="tag">script</a>]]></description>
		<category>linux</category>
		<comments>http://wang.yuxuan.org/blog/2007/3/21/bash_script_batch_resize_your_photos</comments>
		<pubDate>Wed, 21 Mar 2007 21:28:36 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Note: set proxy for wget]]></title>
		<link>http://wang.yuxuan.org/blog/2007/3/20/note_set_proxy_for_wget</link>
		<guid>http://wang.yuxuan.org/blog/2007/3/20/note_set_proxy_for_wget</guid>
		<description><![CDATA[<blockquote><p>wget -Y -e &quot;http_proxy=host:port&quot; url</p></blockquote>
<p>&quot;How to set proxy for wget?&quot; I've been asked this question for many times, but it seems didn't appears in the &quot;-h&quot; output nor man page, so I always forgot it.</p>
<p>That's why I'm making a note here  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_smile.gif" alt=":)" title="" /> </p><br/><br/>tags: <a href="http://technorati.com/tag/wget" rel="tag">wget</a>, <a href="http://technorati.com/tag/proxy" rel="tag">proxy</a>, <a href="http://technorati.com/tag/linux" rel="tag">linux</a>, <a href="http://technorati.com/tag/note" rel="tag">note</a>]]></description>
		<category>linux</category>
		<comments>http://wang.yuxuan.org/blog/2007/3/20/note_set_proxy_for_wget</comments>
		<pubDate>Tue, 20 Mar 2007 00:42:01 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[My first ever Obj-C hack: Google Reader Notifier]]></title>
		<link>http://wang.yuxuan.org/blog/2007/3/11/my_first_ever_obj_c_hack_google_reader_notifier</link>
		<guid>http://wang.yuxuan.org/blog/2007/3/11/my_first_ever_obj_c_hack_google_reader_notifier</guid>
		<description><![CDATA[<p><em>UPDATED: Troels Bay have use another way to do it, please wait for his official build  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_razz.gif" alt=":P" title="" /> </em></p>
<p><a href="http://troelsbay.eu/software/reader">Google Reader Notifier</a> by <a href="http://troelsbay.eu">Troels Bay</a> is a great open source application that provide a desktop notifier for <a href="http://www.google.com/reader/">Google Reader</a>, the online feed reader, and also a feed subscriber. As I'm using <a href="http://www.caminobrowser.org">Camino</a> as my browser, which didn't have a build-in RSS support, I need it even more to subscribe feeds to Google Reader with one click. (not just &quot;notifier&quot;  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_biggrin.gif" alt=":D" title="" />  )</p>
<p>But when subscribe with preview, if there's a &quot;?&quot; in the URL, the problem is that Google Reader will ignore the part after &quot;?&quot;. So that for example my photos on <a href="http://www.flickr.com">Flickr</a>, &quot;http://api.flickr.com/services/feeds/photos_public.gne?id=76236359@N00&amp;format=rss_200&quot; , will be recognised by Google as &quot;http://api.flickr.com/services/feeds/photos_public.gne&quot;.</p>
<p>So I wrote this patch to escape URL before submit to Google.</p>
<blockquote class="vimblock">
<p>
<span class="lnr">&nbsp;1 </span><span class="Type">--- Google Reader copy/GRController.m&nbsp;&nbsp; 2007-03-11 18:45:56.000000000 +0800</span><br/>
<span class="lnr">&nbsp;2 </span><span class="Type">+++ Google Reader/GRController.m&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2007-03-11 18:49:46.000000000 +0800</span><br/>
<span class="lnr">&nbsp;3 </span><span class="Statement">@@ -1610,7 +1610,15 @@</span><br/>
<span class="lnr">&nbsp;4 </span>&nbsp;<br/>
<span class="lnr">&nbsp;5 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ([[prefs valueForKey:@&quot;dontVerifySubscription&quot;] boolValue] != YES) {<br/>
<span class="lnr">&nbsp;6 </span>&nbsp;<br/>
<span class="lnr">&nbsp;7 </span><span class="Special">-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[[NSString <a href="mailto:stringWithFormat:@&quot;%@://www.google.com/reader/preview/*/feed/&quot;,">stringWithFormat:@&quot;%@://www.google.com/reader/preview/*/feed/&quot;,</a> [self getURLPrefix]] stringByAppendingString:url]]];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><br/>
<span class="lnr">&nbsp;8 </span><span class="Identifier">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NSMutableString * escapedUrl = [NSMutableString stringWithCapacity: ([url length]*3)];&nbsp;&nbsp; // for the worst case the length will growth to 3 times</span><br/>
<span class="lnr">&nbsp;9 </span><span class="Identifier">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [escapedUrl setString:url];</span><br/>
<span class="lnr">10 </span><span class="Identifier">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [escapedUrl replaceOccurrencesOfString:@&quot;?&quot; withString:@&quot;%3F&quot; options:0 range:NSMakeRange(0, [escapedUrl length])];</span><br/>
<span class="lnr">11 </span><span class="Identifier">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [escapedUrl replaceOccurrencesOfString:@&quot;&amp;&quot; withString:@&quot;%26&quot; options:0 range:NSMakeRange(0, [escapedUrl length])];</span><br/>
<span class="lnr">12 </span><span class="Identifier">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [escapedUrl replaceOccurrencesOfString:@&quot;:&quot; withString:@&quot;%3A&quot; options:0 range:NSMakeRange(0, [escapedUrl length])];</span><br/>
<span class="lnr">13 </span><span class="Identifier">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [escapedUrl replaceOccurrencesOfString:@&quot;/&quot; withString:@&quot;%2F&quot; options:0 range:NSMakeRange(0, [escapedUrl length])];</span><br/>
<span class="lnr">14 </span><span class="Identifier">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [escapedUrl replaceOccurrencesOfString:@&quot;=&quot; withString:@&quot;%3D&quot; options:0 range:NSMakeRange(0, [escapedUrl length])];</span><br/>
<span class="lnr">15 </span><span class="Identifier">+</span><br/>
<span class="lnr">16 </span><span class="Identifier">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[[NSString <a href="mailto:stringWithFormat:@&quot;%@://www.google.com/reader/preview/*/feed/&quot;,">stringWithFormat:@&quot;%@://www.google.com/reader/preview/*/feed/&quot;,</a> [self getURLPrefix]] stringByAppendingString:escapedUrl]]];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><br/>
<span class="lnr">17 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>
<span class="lnr">18 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {<br/>
<span class="lnr">19 </span>&nbsp;<br/>
</p>
</blockquote><br/><br/>tags: <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/google" rel="tag">google</a>, <a href="http://technorati.com/tag/reader" rel="tag">reader</a>, <a href="http://technorati.com/tag/notifier" rel="tag">notifier</a>, <a href="http://technorati.com/tag/patch" rel="tag">patch</a>, <a href="http://technorati.com/tag/escape" rel="tag">escape</a>]]></description>
		<category>opensource</category>
		<comments>http://wang.yuxuan.org/blog/2007/3/11/my_first_ever_obj_c_hack_google_reader_notifier</comments>
		<pubDate>Sun, 11 Mar 2007 21:13:23 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Some (not so many) handy aliases]]></title>
		<link>http://wang.yuxuan.org/blog/2007/3/2/some_not_so_many_handy_aliases</link>
		<guid>http://wang.yuxuan.org/blog/2007/3/2/some_not_so_many_handy_aliases</guid>
		<description><![CDATA[<p>Under my Debian Linux, when I use <a href="http://www.gnu.org/software/screen/">screen</a>, I always get some keymap/TERM setting problems, for example, the backspace key never work.</p>
<p>But if I set TERM to &quot;vt100&quot; before launch screen, it's OK, so this alias can resolve the problem:</p>
<blockquote class="vimblock"><p>
<span class="Statement">alias </span><span class="Identifier">screen</span><span class="Statement">=</span><span class="Statement">'</span><span class="Constant">env TERM=vt100 screen</span><span class="Statement">'</span>
</p></blockquote>
<p>For the poor network, I always need a multi-thread http downloader. Firefox has a extension <a href="http://www.downthemall.net/">DownThemAll!</a>, but after I finish surfing websites (but didn't finish downloading yet), I used to press Command+Q to quit Firefox, and the download was interrupted. <a href="http://lftp.yar.ru/">lftp</a> has a built-in downloader: pget, so use pget is a good idea:</p>
<blockquote class="vimblock"><p>
<span class="Statement">alias </span><span class="Identifier">pget</span><span class="Statement">=</span><span class="Statement">&quot;</span><span class="Constant">lftp -c pget</span><span class="Statement">&quot;</span>
</p></blockquote>
<p>Put the codes into your bashrc file, and restart your terminal, it's done.</p><br/><br/>tags: <a href="http://technorati.com/tag/alias" rel="tag">alias</a>, <a href="http://technorati.com/tag/bash" rel="tag">bash</a>, <a href="http://technorati.com/tag/screen" rel="tag">screen</a>, <a href="http://technorati.com/tag/pget" rel="tag">pget</a>, <a href="http://technorati.com/tag/lftp" rel="tag">lftp</a>]]></description>
		<category>linux</category>
		<comments>http://wang.yuxuan.org/blog/2007/3/2/some_not_so_many_handy_aliases</comments>
		<pubDate>Fri, 2 Mar 2007 21:25:26 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[MySQL collation charset problem and patch for NucleusCMS and WikkaWiki]]></title>
		<link>http://wang.yuxuan.org/blog/2007/1/26/mysql_collation_charset_problem_and_patch_for_nucleuscms_and_wikkawiki</link>
		<guid>http://wang.yuxuan.org/blog/2007/1/26/mysql_collation_charset_problem_and_patch_for_nucleuscms_and_wikkawiki</guid>
		<description><![CDATA[<p>First of all, I must say MySQL sucks!</p>
<p>As from MySQL 4.1, if the database default charset is UTF8 but the default charset setting in my.cnf is not UTF8, you must do a &quot;SET NAMES UTF8&quot; query after connection, to make sure that in this mysql connection, all query will be handled as UTF8. otherwise seems that it will use latin1 as default.</p>
<p>If the "SET NAMES" isn't queried, the articles and comments won't be malformed, but the data that stored in MySQL database isn't actually in UTF8 encoding, so that for example mysqldump, or phpmyadmin, won't get the right data.</p>
<p>So what we need to do is check database's charset setting, and send a &quot;SET NAME&quot; query to ensure we're using the database's charset setting.</p>
<p>I've found that <a href="http://www.lifetype.org">LifeType</a> did this thing, so I copied its detecting code and made patches for <a href="http://nucleuscms.org">NucleusCMS</a> and <a href="http://wikkawiki.org/">Wikka Wiki</a> (and also my custom homepage for LifeType, of course!).</p>
<p>But before downloading the patches, I should tell you that:</p>
<p>First, you <em>MUST</em> convert your database. Cause before you patch NucleusCMS or Wikka Wiki, your articles, comments, etc. that already posted, was stored in the old way in the db.</p>
<p>To do that, follow the following steps (this is in case the my.cnf indicate "latin1" but your database was in "utf8", if you're using other charsets, modify them):</p>
<ol>
<li>mysqldump -h host -u username -ppassword database --default-character-set=latin1 &gt; dump.sql</li>
<li>Edit dump.sql, on Line 10, replace "latin1" with "utf8"</li>
<li>mysql -h host -u username -ppassword database &lt; dump.sql</li>
</ol>
<p>Second, you must ensure that in your database, <em>ALL</em> charset settings are set to "utf8". The word &quot;<em>ALL</em>&quot; means databases, tables and fields.</p>
<p>Finally, here're the patches: <a href="http://wang.yuxuan.org/files/nucleus_dbcharset.patch">for nucleus</a>, <a href="http://wang.yuxuan.org/files/wikka_dbcharset.patch">for wikka</a>, released under <a href="http://www.gnu.org/copyleft/gpl.html"><acronym title="GNU Public License">GPL</acronym></a>. <em>WARNING: Use it on your own risk, and make backup before patching.</em></p><br/><br/>tags: <a href="http://technorati.com/tag/wikka" rel="tag">wikka</a>, <a href="http://technorati.com/tag/wiki" rel="tag">wiki</a>, <a href="http://technorati.com/tag/nucleus" rel="tag">nucleus</a>, <a href="http://technorati.com/tag/blog" rel="tag">blog</a>, <a href="http://technorati.com/tag/utf8" rel="tag">utf8</a>, <a href="http://technorati.com/tag/mysql" rel="tag">mysql</a>, <a href="http://technorati.com/tag/patch" rel="tag">patch</a>, <a href="http://technorati.com/tag/charset" rel="tag">charset</a>, <a href="http://technorati.com/tag/use" rel="tag">use</a>, <a href="http://technorati.com/tag/names" rel="tag">names</a>]]></description>
		<category>opensource</category>
		<comments>http://wang.yuxuan.org/blog/2007/1/26/mysql_collation_charset_problem_and_patch_for_nucleuscms_and_wikkawiki</comments>
		<pubDate>Fri, 26 Jan 2007 22:47:17 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[A patch for Gecko based browsers on Mac for buttons]]></title>
		<link>http://wang.yuxuan.org/blog/2007/1/23/a_patch_for_gecko_based_browsers_on_mac_for_buttons</link>
		<guid>http://wang.yuxuan.org/blog/2007/1/23/a_patch_for_gecko_based_browsers_on_mac_for_buttons</guid>
		<description><![CDATA[<p>Gecko based browsers, including Mozilla Firefox, Mozilla Camino, Mozilla Seamonkey, optimized 3rd-party builds of Firefox and etc. , didn't display buttons on webpages well on Mac OS X.</p>
<p>For aqua buttons, that shown in Camino and some optimized 3rd-party builds of Firefox, the <acronym title="Chinese, Japanese, Korean">CJK</acronym> buttons often be malformed and cause you can't see the text on the button well. For common buttons, they're just ugly.</p>
<p>I've found a hack through the internet, and I'm not so sure what did it actually do (seems to be some dirty tricks), but it works. So I cut off some unnecessary codes and made <a href="http://wang.yuxuan.org/files/moz-forms.patch">this patch</a>. To use it, just execute the following command under terminal (Terminal.app or iTerm.app, replace &quot;/Applications/Camino.app&quot; to the path of the app you want to patch):</p>
<blockquote><p>
cd /Applications/Camino.app/Contents/MacOS/res/<br />
patch -i /path/to/moz-forms.patch
</p></blockquote>
<p>And it's done.</p>
<p><em>Before:</em><br />
<a href="http://www.flickr.com/photos/fishywang/366902803/" title="Photo Sharing"><img src="http://farm1.static.flickr.com/117/366902803_4a3592edea_o.png" width="364" height="169" alt="A patch for Gecko browsers on Mac: Aqua buttons, before" /></a><br />
<a href="http://www.flickr.com/photos/fishywang/366902860/" title="Photo Sharing"><img src="http://farm1.static.flickr.com/132/366902860_dc51ba0ea1_o.png" width="436" height="33" alt="A patch for Gecko browsers on Mac: common buttons, before" /></a></p>
<p><em>After:</em><br />
<a href="http://www.flickr.com/photos/fishywang/366902835/" title="Photo Sharing"><img src="http://farm1.static.flickr.com/150/366902835_fec62bbfbb_o.png" width="363" height="168" alt="A patch for Gecko browsers on Mac: Aqua buttons, after" /></a><br />
<a href="http://www.flickr.com/photos/fishywang/366902920/" title="Photo Sharing"><img src="http://farm1.static.flickr.com/162/366902920_7f1aee641c_o.png" width="450" height="36" alt="A patch for Gecko browsers on Mac: common buttons, before" /></a></p>
<p>I didn't write this patch. I just found it and made it easier to use.</p><br/><br/>tags: <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/osx" rel="tag">osx</a>, <a href="http://technorati.com/tag/patch" rel="tag">patch</a>, <a href="http://technorati.com/tag/cjk" rel="tag">cjk</a>, <a href="http://technorati.com/tag/button" rel="tag">button</a>, <a href="http://technorati.com/tag/gecko" rel="tag">gecko</a>, <a href="http://technorati.com/tag/firefox" rel="tag">firefox</a>, <a href="http://technorati.com/tag/camino" rel="tag">camino</a>, <a href="http://technorati.com/tag/seamonkey" rel="tag">seamonkey</a>]]></description>
		<category>opensource</category>
		<comments>http://wang.yuxuan.org/blog/2007/1/23/a_patch_for_gecko_based_browsers_on_mac_for_buttons</comments>
		<pubDate>Tue, 23 Jan 2007 20:04:14 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Trying Camino]]></title>
		<link>http://wang.yuxuan.org/blog/2007/1/21/trying_camino</link>
		<guid>http://wang.yuxuan.org/blog/2007/1/21/trying_camino</guid>
		<description><![CDATA[<p><a href="http://www.caminobrowser.org/">Camino</a> is superb fast. Much much faster than Firefox and maybe a bit faster than Safari.</p>
<p>Compare to Firefox, it comes with some good system integrations, including Address Book integration, Keychain Access integration, etc. And compare to Safari, it's much closer to Firefox, it also have a &quot;about:config&quot; thing (though a little different from Firefox), and a powerful ad-blocking engine.</p>
<p>So I'm going to give it a week's trial, to see if I can be used to it.</p>
<p>Although it's close to Firefox, it didn't have extensions. So there's something I missing in Firefox:</p>
<ol>
<li>It can't force links that open a new window to open in new tab. I can <a href="http://www.caminobrowser.org/support/hiddenprefs/">use about:config to set &quot;browser.link.open_newwindow&quot; to &quot;1&quot; to disable links that opens a new window</a>, but can't use a new tab instead. Anyway, this is acceptable. At least they won't open lots of new windows to annoy me.</li>
<li>I can't type a site name (e.g. &quot;google&quot; ) and press cmd+enter to automatically surround it with &quot;www.&quot; and &quot;.com&quot;, this will open it in new tab and use &quot;I'm feeling lucky&quot; search. So I must type more words to input a address.</li>
<li><del>Keyboard short-cut is different from Firefox, it mixed some Firefox short-cuts and Safari short-cuts up. I don't like this. I prefer a configurable keyboard short-cuts. Maybe I can configure it in System Preferences?</del> <em>UPDATED: Oh yes, I can configure them in System Preferences. This makes me feel much better.</em></li>
<li>I can't specify the text encoding of the keyword in the search tool-box. Some search engines in China only accept GBK keywords but Camino can only encode keyword in UTF-8.</li>
<li>Lack of spell checkers. It can't use the system spell check for standard text editors (cause it didn't use the standard text editor?), nor the spell checker provided by Google Toolbar for Firefox or Firefox 2.</li>
</ol>
<p>Anyway, a impressive thing is that the build-in ad-blocking engine is powerful, and the default black-list is very useful that it filtered out almost all the ad from the pages I visited. And if the black-list isn't powerful enough, I can <a href="http://www.caminobrowser.org/support/docs/annoyances/#adv_block">edit it myself</a>.</p><br/><br/>tags: <a href="http://technorati.com/tag/camino" rel="tag">camino</a>, <a href="http://technorati.com/tag/firefox" rel="tag">firefox</a>, <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/osx" rel="tag">osx</a>, <a href="http://technorati.com/tag/safari" rel="tag">safari</a>, <a href="http://technorati.com/tag/adblock" rel="tag">adblock</a>]]></description>
		<category>mac</category>
		<comments>http://wang.yuxuan.org/blog/2007/1/21/trying_camino</comments>
		<pubDate>Sun, 21 Jan 2007 02:48:09 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Mac is for geeks?]]></title>
		<link>http://wang.yuxuan.org/blog/2007/1/11/mac_is_for_geeks</link>
		<guid>http://wang.yuxuan.org/blog/2007/1/11/mac_is_for_geeks</guid>
		<description><![CDATA[<p>Or at least, <a href="http://www.skype.com/download/skype/macosx/">Skype for Mac</a> is for geeks? There are some cool stuffs in Skype for Mac, but not available on other platform versions of Skype.</p>
<ol>
<li>In the chat style tweak window, the chat example is from George Orwell's 1984. Maybe because of <a href="http://www.youtube.com/watch?v=IFtuNPTBZ2k">Mac begins from 1984</a>?<br /><a href="http://www.flickr.com/photos/fishywang/318591561/" title="Photo Sharing"><img src="http://farm1.static.flickr.com/135/318591561_1b181b7ec6_m.jpg" width="240" height="198" alt="&quot;1984&quot; in Skype" /></a></li>
<li>In the <a href="http://www.skype.com/download/skype/macosx/25beta.html">newest beta (currently) version</a>, the history events was brought on and off with a cool effect, similar to the water wave effect of dashboard.<br /><a href="http://www.flickr.com/photos/fishywang/350324341/" title="Photo Sharing"><img src="http://farm1.static.flickr.com/139/350324341_2abe0d4e4e_m.jpg" width="106" height="240" alt="Skype for mac: the history effect" /></a></li>
</ol><br/><br/>tags: <a href="http://technorati.com/tag/skype" rel="tag">skype</a>, <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/1984" rel="tag">1984</a>]]></description>
		<category>mac</category>
		<comments>http://wang.yuxuan.org/blog/2007/1/11/mac_is_for_geeks</comments>
		<pubDate>Thu, 11 Jan 2007 22:09:34 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Selective unlink script (to uninstall TeXLive)]]></title>
		<link>http://wang.yuxuan.org/blog/2007/1/5/selective_unlink_script_to_uninstall_texlive</link>
		<guid>http://wang.yuxuan.org/blog/2007/1/5/selective_unlink_script_to_uninstall_texlive</guid>
		<description><![CDATA[<p>In fact, to uninstall <a href="http://www.tug.org/texlive/">TeXLive</a> should be very easy: &quot;rm -Rf /usr/local/texlive&quot;, that's all.</p>
<p>But things are sometimes not so easy. If you've chosen to make symbolic links to your system path (/usr/bin) during the installation, like I had, then you have to unlink all the links TeXLive created.</p>
<p>It's hard to do that manually, so I wrote the following script. You just need to run it under your /usr/bin directory and it will unlink all links that pointed to /usr/local/texlive.</p>
<blockquote class="vimblock">
<p>
<span class="lnr">&nbsp;1 </span><span class="Comment">#!/bin/sh</span><br/>
<span class="lnr">&nbsp;2 </span><br/>
<span class="lnr">&nbsp;3 </span><span class="Identifier">tlprefix</span>=<span class="Statement">&quot;</span><span class="Constant">^/usr/local/texlive/</span><span class="Statement">&quot;</span><br/>
<span class="lnr">&nbsp;4 </span><br/>
<span class="lnr">&nbsp;5 </span><span class="Statement">for</span>&nbsp;file <span class="Statement">in</span>&nbsp;*<span class="Statement">;</span>&nbsp;<span class="Statement">do</span><br/>
<span class="lnr">&nbsp;6 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">if</span>&nbsp;<span class="Statement">[</span>&nbsp;<span class="Statement">-L</span>&nbsp;<span class="PreProc">${</span><span class="PreProc">file</span><span class="PreProc">}</span>&nbsp;<span class="Statement">]</span><span class="Statement">;</span>&nbsp;<span class="Statement">then</span><br/>
<span class="lnr">&nbsp;7 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Identifier">link</span>=<span class="Special">`readlink </span><span class="PreProc">${</span><span class="PreProc">file</span><span class="PreProc">}</span><span class="Special">`</span><br/>
<span class="lnr">&nbsp;8 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Identifier">tllink</span>=<span class="Special">`echo </span><span class="Statement">&quot;</span><span class="PreProc">${</span><span class="PreProc">link</span><span class="PreProc">}</span><span class="Statement">&quot;</span><span class="Special">&nbsp;</span><span class="Statement">|</span><span class="Special">&nbsp;grep </span><span class="Statement">&quot;</span><span class="PreProc">${</span><span class="PreProc">tlprefix</span><span class="PreProc">}</span><span class="Statement">&quot;</span><span class="Special">`</span><br/>
<span class="lnr">&nbsp;9 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">if</span>&nbsp;<span class="Statement">[</span>&nbsp;<span class="Statement">-n</span>&nbsp;<span class="Statement">&quot;</span><span class="PreProc">${</span><span class="PreProc">tllink</span><span class="PreProc">}</span><span class="Statement">&quot;</span>&nbsp;<span class="Statement">]</span><span class="Statement">;</span>&nbsp;<span class="Statement">then</span><br/>
<span class="lnr">10 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">echo</span><span class="Constant">&nbsp;</span><span class="Statement">&quot;</span><span class="Constant">going to unlink </span><span class="Special">\&quot;</span><span class="PreProc">${</span><span class="PreProc">file</span><span class="PreProc">}</span><span class="Special">\&quot;</span><span class="Constant">&nbsp;that links to </span><span class="Special">\&quot;</span><span class="PreProc">${</span><span class="PreProc">link</span><span class="PreProc">}</span><span class="Special">\&quot;</span><span class="Constant">...</span><span class="Statement">&quot;</span><br/>
<span class="lnr">11 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unlink <span class="PreProc">${</span><span class="PreProc">file</span><span class="PreProc">}</span><br/>
<span class="lnr">12 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">fi</span><br/>
<span class="lnr">13 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">fi</span><br/>
<span class="lnr">14 </span><span class="Statement">done</span><br/>
</p>
</blockquote>
<p>It unlinked 240 symbolic links from my /usr/bin directory, horrible! I'll never choose the &quot;make symbolic links to your system path&quot; option again during the installation of TeXLive.</p><br/><br/>tags: <a href="http://technorati.com/tag/texlive" rel="tag">texlive</a>, <a href="http://technorati.com/tag/unlink" rel="tag">unlink</a>, <a href="http://technorati.com/tag/bash" rel="tag">bash</a>]]></description>
		<category>latex</category>
		<comments>http://wang.yuxuan.org/blog/2007/1/5/selective_unlink_script_to_uninstall_texlive</comments>
		<pubDate>Fri, 5 Jan 2007 23:59:57 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Make sure your often crash daemon is still running]]></title>
		<link>http://wang.yuxuan.org/blog/2006/12/7/make_sure_your_often_crash_daemon_is_still_running</link>
		<guid>http://wang.yuxuan.org/blog/2006/12/7/make_sure_your_often_crash_daemon_is_still_running</guid>
		<description><![CDATA[<p>I have used my old lap-top as a home server. Cause I'm using ADSL at home, I have to use a dynamic DNS.</p>
<p>I choosed a Chinese dynamic DNS provider "Peanut Shell", they've provided a Linux client to commit your IP.</p>
<p>But the Linux client they provided is close-source and often crashes. After it crashed, my domain name can't be kept up-to-date.</p>
<p>So I have to write a script to make sure it's still running:</p>
<blockquote class="vimblock"><p>
<span class="lnr">1 </span><span class="Comment">#!/bin/sh</span><br/>
<span class="lnr">2 </span><span class="Identifier">pid</span>=<span class="Special">`pidof phlinux`</span><br/>
<span class="lnr">3 </span><span class="Statement">if</span>&nbsp;<span class="Statement">[</span>&nbsp;<span class="Statement">-z</span>&nbsp;<span class="Statement">&quot;</span><span class="PreProc">$pid</span><span class="Statement">&quot;</span>&nbsp;<span class="Statement">]</span><span class="Statement">;</span>&nbsp;<span class="Statement">then</span><br/>
<span class="lnr">4 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">echo</span><span class="Constant">&nbsp;</span><span class="Statement">&quot;</span><span class="Constant">phlinux not running, start it as daemon now...</span><span class="Statement">&quot;</span><span class="Constant">&nbsp;</span><span class="Statement">&gt;&amp;2</span><br/>
<span class="lnr">5 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/usr/local/phlinux/phlinux <span class="Statement">-d</span><br/>
<span class="lnr">6 </span><span class="Statement">else</span><br/>
<span class="lnr">7 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">echo</span><span class="Constant">&nbsp;</span><span class="Statement">&quot;</span><span class="Constant">phlinux is running</span><span class="Statement">&quot;</span><br/>
<span class="lnr">8 </span><span class="Statement">fi</span><br/>
</p></blockquote>
<p>Save this script in some place, and make a link to your &quot;/etc/cron.hourly&quot;, so it will be checked every hour.</p>
<p><em>UPDATED: or maybe you don't want to get mail report on every check, I've updated the script, and you should write a script in your &quot;/etc/cron.hourly&quot; instead of link the script, and writes &quot;/path/to/your/script > /dev/null&quot;</em></p><br/><br/>tags: <a href="http://technorati.com/tag/ph" rel="tag">ph</a>, <a href="http://technorati.com/tag/daemon" rel="tag">daemon</a>, <a href="http://technorati.com/tag/crash" rel="tag">crash</a>, <a href="http://technorati.com/tag/dyn-dns" rel="tag">dyn-dns</a>]]></description>
		<category>linux</category>
		<comments>http://wang.yuxuan.org/blog/2006/12/7/make_sure_your_often_crash_daemon_is_still_running</comments>
		<pubDate>Thu, 7 Dec 2006 13:41:50 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Too cool to refuse: NP_Revision]]></title>
		<link>http://wang.yuxuan.org/blog/2006/11/22/too_cool_to_refuse_np_revision</link>
		<guid>http://wang.yuxuan.org/blog/2006/11/22/too_cool_to_refuse_np_revision</guid>
		<description><![CDATA[<p>Yesterday I <a href="http://wang.yuxuan.org/blog/2006/11/22/a_hack_for_np_trackback">made a patch for NucleusCMS plugin NP_TrackBack</a>, and post in into the forum. On the forum, I've found another amazing plugin from the same author: <a href="http://wakka.xiffy.nl/revision">NP_Revision</a></p>
<p>It's amazing because, it can track all your changes, just like a wiki (or CVS/svn)! It can show the old version, and show the diff's.</p>
<p>For instance, <a href="http://wang.yuxuan.org/blog/action.php?action=plugin&amp;name=Revision&amp;type=diff&amp;itemid=40&amp;old=1.0&amp;new=1.1">this is the diff</a> between <a href="http://wang.yuxuan.org/blog/item/40/revision/1.0">revision 1.0</a> and <a href="http://wang.yuxuan.org/blog/item/40/revision/1.1">revision 1.1</a> of my <a href="http://wang.yuxuan.org/blog/2006/11/22/a_hack_for_np_trackback">last post</a>.</p>
<p>But seems for the posts post before installation of this plugin, the time was wrong. I'll try to fix it later.</p>
<p><acronym title="by the way">btw</acronym>: I've changed the url here from Fancy URL to <a href="http://wakka.xiffy.nl/fancierurl">Fancier URL</a>. So if you're using bloglines or google reader or some RSS reader that track changes, you'll get notify for old items. My apologize for that. Old stuff fancy URLs still works.</p>
<br/><br/>tags: <a href="http://technorati.com/tag/np_revision" rel="tag">np_revision</a>, <a href="http://technorati.com/tag/nucleus" rel="tag">nucleus</a>, <a href="http://technorati.com/tag/np_fancierurl" rel="tag">np_fancierurl</a>, <a href="http://technorati.com/tag/revision" rel="tag">revision</a>]]></description>
		<category>opensource</category>
		<comments>http://wang.yuxuan.org/blog/2006/11/22/too_cool_to_refuse_np_revision</comments>
		<pubDate>Wed, 22 Nov 2006 19:13:39 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[A hack for NP_TrackBack]]></title>
		<link>http://wang.yuxuan.org/blog/2006/11/22/a_hack_for_np_trackback</link>
		<guid>http://wang.yuxuan.org/blog/2006/11/22/a_hack_for_np_trackback</guid>
		<description><![CDATA[<p>You are visiting a <a href="http://www.nucleuscms.org/">NucleusCMS</a> powered blog. NucleusCMS is a good blog system, the only (?) problem is that it doesn't support trackbacks itself. So I use the plugin <a href="http://wakka.xiffy.nl/trackback">NP_TrackBack</a> to add trackback support.</p>
<p>NP_TrackBack was good, especially on its anti-spam ability. It blocks nearly all my received trackback pings automatically (I haven't got any real trackback yet, all I got were spams).</p>
<p>NP_TrackBack can also send a notification to me when a trackback ping received. But the problem is, that it also send me notification about blocked trackback pings.</p>
<p>I have faith on its anti-spam ability, so I don't wanna get notifications about blocked trackbacks. But I do hope get a notification on real trackbacks. So finally, I've made this hack.</p>
<p>I've added a option to NP_TrackBack not to send notification on blocked pings (see the screenshot below), so that my mailbox won't be spammed instead of my blog. And its default value is &quot;no&quot;, so that it won't change your default settings.</p>
<p><a href="http://www.flickr.com/photos/fishywang/302905751/" title="Photo Sharing"><img src="http://static.flickr.com/103/302905751_73dbf7435d.jpg" width="500" height="89" alt="NP_TrackBack hack" /></a></p>
<p>Here's the <a href="http://wang.yuxuan.org/files/trackback.patch">patch</a> file and the <a href="http://wang.yuxuan.org/files/NP_TrackBack.txt">plugin php file itself</a> (don't forget to replace the &quot;.txt&quot; extension with &quot;.php&quot; ). Cause I've added a option, you can't simply replace your old file if you are currently using NP_TrackBack plugin. You may need to uninstall your old one and install your new one to make it work.</p><br/><br/>tags: <a href="http://technorati.com/tag/nucleus" rel="tag">nucleus</a>, <a href="http://technorati.com/tag/nucleuscms" rel="tag">nucleuscms</a>, <a href="http://technorati.com/tag/np_trackback" rel="tag">np_trackback</a>, <a href="http://technorati.com/tag/trackback" rel="tag">trackback</a>, <a href="http://technorati.com/tag/hack" rel="tag">hack</a>, <a href="http://technorati.com/tag/patch" rel="tag">patch</a>]]></description>
		<category>opensource</category>
		<comments>http://wang.yuxuan.org/blog/2006/11/22/a_hack_for_np_trackback</comments>
		<pubDate>Wed, 22 Nov 2006 02:20:34 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[How to install ie in Mac via Darwine]]></title>
		<link>http://wang.yuxuan.org/blog/2006/11/3/how_to_install_ie_in_mac_via_darwine</link>
		<guid>http://wang.yuxuan.org/blog/2006/11/3/how_to_install_ie_in_mac_via_darwine</guid>
		<description><![CDATA[<ol>
<li>Get the latest <a href="http://sourceforge.net/projects/darwine/">darwine distribution</a> from <a href="http://sf.net">sf</a>, and install it. Files on sf seems differ from files on <a href="http://darwine.opendarwin.org/">darwine homepage</a></li>
<li>Get <a href="http://www.tatanka.com.br/ies4linux/page/Main_Page">IEs4Linux</a></li>
<li>Install wget, cabextract, etc. from <a href="http://macports.org">MacPorts</a></li>
<li>Run the ies4linux script. You should need to add wine path into PATH before that. The wine path should normally be: &quot;/Applications/Darwine/Wine.bundle/Contents/bin&quot;.</li>
<li>After ies4linux script finished, edit the generated &quot;ie6&quot; script, add the following line(you can also add this line into your bashrc):<br />
<blockquote>
<p>export DISPLAY=":0.0"</p>
</blockquote></li>
</ol>
<p>After that, you'll be able to use "ie6" to start-up ie 6 via Darwine. Remember to open X11.app first.</p>
<p><a href="http://www.flickr.com/photos/fishywang/287579539/" title="Photo Sharing"><img src="http://static.flickr.com/110/287579539_7ed7cd6b72.jpg" width="500" height="328" alt="Internet Explorer 6 in Darwine" /></a></p>
<p>As you can see, the font is really, really ugly, and Chinese characters can't be displayed properly.</p><br/><br/>tags: <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/darwine" rel="tag">darwine</a>, <a href="http://technorati.com/tag/wine" rel="tag">wine</a>, <a href="http://technorati.com/tag/ie" rel="tag">ie</a>]]></description>
		<category>mac</category>
		<comments>http://wang.yuxuan.org/blog/2006/11/3/how_to_install_ie_in_mac_via_darwine</comments>
		<pubDate>Fri, 3 Nov 2006 18:15:22 +0700</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Mac OS X Tip: Set 24-hour format time]]></title>
		<link>http://wang.yuxuan.org/blog/2006/10/15/mac_os_x_tip_set_24_hour_format_time</link>
		<guid>http://wang.yuxuan.org/blog/2006/10/15/mac_os_x_tip_set_24_hour_format_time</guid>
		<description><![CDATA[<p>I hate times that in the &quot;am/pm&quot; format. It's a big waste of screen space, especially when I am using a 13.3 inch screen. I miss the 24-hour format time, but I didn't find it in Mac.</p>
<p>But finally I've found the way:</p>
<ol>
<li>Open System Preferences</li>
<li>Open International</li>
<li>Click the Format tab</li>
<li>Click the Customize button beside "Times"</li>
<li>Hover your mouse over the hour indicator, and it will show a arrow. Click on the arrow you'll get a drop-down list to choose hour formats.</li>
</ol>
<p>Here's my snapshot:</p>
<p><a href="http://www.flickr.com/photos/fishywang/269503403/" title="Photo Sharing"><img src="http://static.flickr.com/121/269503403_cb25103892.jpg" width="494" height="358" alt="Set 24 hour format time in Mac OS X" /></a></p>
<p>So I get my 24-hour format time back, in my iCal, Mail, anywhere.</p><br/><br/>tags: <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/time" rel="tag">time</a>, <a href="http://technorati.com/tag/format" rel="tag">format</a>, <a href="http://technorati.com/tag/24-hour" rel="tag">24-hour</a>]]></description>
		<category>mac</category>
		<comments>http://wang.yuxuan.org/blog/2006/10/15/mac_os_x_tip_set_24_hour_format_time</comments>
		<pubDate>Sun, 15 Oct 2006 04:00:04 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[virtual class in c++]]></title>
		<link>http://wang.yuxuan.org/blog/2006/9/13/virtual_class_in_c</link>
		<guid>http://wang.yuxuan.org/blog/2006/9/13/virtual_class_in_c</guid>
		<description><![CDATA[<p>Here's a example to make a virtual class in c++, similar to "interface" in Pascal and Java:</p>
<blockquote class="vimblock">
<p>
<span class="lnr">&nbsp;1 </span><span class="PreProc">#include </span><span class="Constant">&lt;stdio.h&gt;</span><br/>
<span class="lnr">&nbsp;2 </span><span class="PreProc">#include </span><span class="Constant">&lt;string&gt;</span><br/>
<span class="lnr">&nbsp;3 </span><span class="PreProc">#include </span><span class="Constant">&lt;vector&gt;</span><br/>
<span class="lnr">&nbsp;4 </span><br/>
<span class="lnr">&nbsp;5 </span><span class="Type">class</span>&nbsp;base_foo {<br/>
<span class="lnr">&nbsp;6 </span><span class="Statement">public</span>:<br/>
<span class="lnr">&nbsp;7 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Type">virtual</span>&nbsp;std::string name() { <span class="Statement">return</span>&nbsp;<span class="Constant">&quot;base_foo&quot;</span>; }<br/>
<span class="lnr">&nbsp;8 </span>};<br/>
<span class="lnr">&nbsp;9 </span><br/>
<span class="lnr">10 </span><span class="Type">class</span>&nbsp;foo: <span class="Statement">public</span>&nbsp;base_foo {<br/>
<span class="lnr">11 </span><span class="Statement">public</span>:<br/>
<span class="lnr">12 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::string name() { <span class="Statement">return</span>&nbsp;<span class="Constant">&quot;foo&quot;</span>; }<br/>
<span class="lnr">13 </span>};<br/>
<span class="lnr">14 </span><br/>
<span class="lnr">15 </span><span class="Type">class</span>&nbsp;bar: <span class="Statement">public</span>&nbsp;base_foo {<br/>
<span class="lnr">16 </span><span class="Statement">public</span>:<br/>
<span class="lnr">17 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::string name() { <span class="Statement">return</span>&nbsp;<span class="Constant">&quot;bar&quot;</span>; }<br/>
<span class="lnr">18 </span>};<br/>
<span class="lnr">19 </span><br/>
<span class="lnr">20 </span><span class="Type">int</span>&nbsp;main() {<br/>
<span class="lnr">21 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::vector&lt;base_foo*&gt; foo_list;<br/>
<span class="lnr">22 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo f;<br/>
<span class="lnr">23 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bar b;<br/>
<span class="lnr">24 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo_list.push_back(&amp;f);<br/>
<span class="lnr">25 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo_list.push_back(&amp;b);<br/>
<span class="lnr">26 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(<span class="Constant">&quot;</span><span class="Special">%s</span><span class="Special">\n</span><span class="Special">%s</span><span class="Special">\n</span><span class="Constant">&quot;</span>,<br/>
<span class="lnr">27 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo_list[<span class="Constant">0</span>]-&gt;name().c_str(),<br/>
<span class="lnr">28 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo_list[<span class="Constant">1</span>]-&gt;name().c_str());<br/>
<span class="lnr">29 </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="Statement">return</span>&nbsp;<span class="Constant">0</span>;<br/>
<span class="lnr">30 </span>}<br/>
</p>
</blockquote>
<p>The result of this program is:</p>
<blockquote>
<p>foo<br />
bar</p>
</blockquote><br/><br/>tags: <a href="http://technorati.com/tag/cpp" rel="tag">cpp</a>, <a href="http://technorati.com/tag/c" rel="tag">c</a>, <a href="http://technorati.com/tag/virtual" rel="tag">virtual</a>, <a href="http://technorati.com/tag/interface" rel="tag">interface</a>]]></description>
		<category>dev</category>
		<comments>http://wang.yuxuan.org/blog/2006/9/13/virtual_class_in_c</comments>
		<pubDate>Wed, 13 Sep 2006 22:51:34 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[QTerm 0.4.0 Intel Mac build(s)]]></title>
		<link>http://wang.yuxuan.org/blog/2006/8/20/qterm_0_4_0_intel_mac_build_s</link>
		<guid>http://wang.yuxuan.org/blog/2006/8/20/qterm_0_4_0_intel_mac_build_s</guid>
		<description><![CDATA[<p><a href="http://qterm.sf.net/">QTerm</a> is a Qt based open source <a href="http://en.wikipedia.org/wiki/Bbs">BBS</a> client</p>
<p>I've made a static build of the latest release (0.4.0) on my MacBook. It's a static build, that means you don't need Qt installed, you need just this app to run stand alone. And it's not a Universal Binary, it can only run on Intel Macs</p>
<p>QTerm is designed to be primarily ran on Linux platforms, so that the keyboard shortcuts are in Linux-style. I've also made a modified version to change some of the keyboard shortcuts into Mac-style. The changes include:</p>
<ol>
<li>alt+0~9 -&gt; cmd+0~9</li>
<li>alt+up, alt+down, alt+left, alt+right -&gt; cmd+up, cmd+down, cmd+left, cmd+right</li>
<li>copy: cmd+c, paste: cmd+v</li>
</ol>
<p>Here are my builds: <a href="http://wang.yuxuan.org/files/qterm-0.4.0-mac-intel.tar.bz2">original version</a>, <a href="http://wang.yuxuan.org/files/qterm-0.4.0-mac-intel-mod.tar.bz2">modified version</a>. They are bzipped tarballs of &quot;.app&quot;, extract them and move qterm.app to your Applications folder.</p><br/><br/>tags: <a href="http://technorati.com/tag/qterm" rel="tag">qterm</a>, <a href="http://technorati.com/tag/intel" rel="tag">intel</a>, <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/build" rel="tag">build</a>]]></description>
		<category>opensource</category>
		<comments>http://wang.yuxuan.org/blog/2006/8/20/qterm_0_4_0_intel_mac_build_s</comments>
		<pubDate>Sun, 20 Aug 2006 04:50:58 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Can google search it out?]]></title>
		<link>http://wang.yuxuan.org/blog/2006/7/13/can_google_search_it_out</link>
		<guid>http://wang.yuxuan.org/blog/2006/7/13/can_google_search_it_out</guid>
		<description><![CDATA[<p>Here's a funny domain name: <a href="http://www.mamashuojiusuannizhucedeyumingzaichanggoogledounengsousuochulai.cn/">http://www.mamashuojiusuannizhucedeyumingzaichanggoogledounengsousuochulai.cn/</a></p>
<p>This domain is in <a href="http://en.wikipedia.org/wiki/Pinyin">Chinese pinyin</a>, which means:</p>
<blockquote>
<p>Mom says that, whatever how long your domain name is, Google can also search it out</p>
</blockquote>
<p>But, can google really search it out?  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_wink.gif" alt=";)" title="" /> </p><br/><br/>tags: <a href="http://technorati.com/tag/google" rel="tag">google</a>, <a href="http://technorati.com/tag/long" rel="tag">long</a>, <a href="http://technorati.com/tag/domain" rel="tag">domain</a>]]></description>
		<category>General</category>
		<comments>http://wang.yuxuan.org/blog/2006/7/13/can_google_search_it_out</comments>
		<pubDate>Thu, 13 Jul 2006 21:22:28 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[libmysqlclient didn't report error while insert duplicate data in primary keys.]]></title>
		<link>http://wang.yuxuan.org/blog/2006/7/12/libmysqlclient_didn_t_report_error_while_insert_duplicate_data_in_primary_keys</link>
		<guid>http://wang.yuxuan.org/blog/2006/7/12/libmysqlclient_didn_t_report_error_while_insert_duplicate_data_in_primary_keys</guid>
		<description><![CDATA[<p>The title said it.</p><br/><br/>tags: <a href="http://technorati.com/tag/mysql" rel="tag">mysql</a>, <a href="http://technorati.com/tag/client" rel="tag">client</a>, <a href="http://technorati.com/tag/lib" rel="tag">lib</a>, <a href="http://technorati.com/tag/c" rel="tag">c</a>]]></description>
		<category>dev</category>
		<comments>http://wang.yuxuan.org/blog/2006/7/12/libmysqlclient_didn_t_report_error_while_insert_duplicate_data_in_primary_keys</comments>
		<pubDate>Wed, 12 Jul 2006 22:34:33 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>
	<item>
		<title><![CDATA[Name my computers]]></title>
		<link>http://wang.yuxuan.org/blog/2006/7/2/name_my_computers</link>
		<guid>http://wang.yuxuan.org/blog/2006/7/2/name_my_computers</guid>
		<description><![CDATA[<p>I've got my new <a href="http://www.flickr.com/photos/fishywang/171121062/">MacBook</a> (hooray!), and decide to name my computers, base on their system.</p>
<p>For my new MacBook, the name's <a href="http://en.wikipedia.org/wiki/Steve_McManaman">McManaman</a>, he's one of my favorite players  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_razz.gif" alt=":P" title="" /> </p>
<p>Based on this rule, I named my old lap-top with Debian to <a href="http://en.wikipedia.org/wiki/Frank_de_Boer">deBoer</a>.</p>
<p>And finally, I decided to name my router <a href="http://en.wikipedia.org/wiki/Wayne_Routledge">Routledge</a>, this name is perfect for a router, isn't it?  <img src="http://wang.yuxuan.org/blog/nucleus/plugins/emoticons/icon_wink.gif" alt=";)" title="" /> </p>
<br/><br/>tags: <a href="http://technorati.com/tag/MacBook" rel="tag">MacBook</a>, <a href="http://technorati.com/tag/mac" rel="tag">mac</a>, <a href="http://technorati.com/tag/hostname" rel="tag">hostname</a>]]></description>
		<category>General</category>
		<comments>http://wang.yuxuan.org/blog/2006/7/2/name_my_computers</comments>
		<pubDate>Sun, 2 Jul 2006 03:58:00 +0800</pubDate>
		<author>fishy &lt;nospam@yuxuan.org&gt;</author>
	</item>

</channel>
</rss>