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

<channel>
	<title>John&#039;s Blog &#187; John</title>
	<atom:link href="http://john.nachtimwald.com/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://john.nachtimwald.com</link>
	<description>My little blog</description>
	<lastBuildDate>Sat, 31 Jul 2010 17:28:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>WPMU OpenID and SSL</title>
		<link>http://john.nachtimwald.com/2010/07/28/wpmu-openid-and-ssl/</link>
		<comments>http://john.nachtimwald.com/2010/07/28/wpmu-openid-and-ssl/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 11:40:12 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[site maintenance]]></category>
		<category><![CDATA[openid]]></category>
		<category><![CDATA[ssl]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wpmu]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=443</guid>
		<description><![CDATA[It&#8217;s no secret that I&#8217;m using WordPress MU for this website. It makes it very easy to keep the main site as well as my and Tati&#8217;s blogs updated. Recently I&#8217;ve been wanting to continue properly securing the blogs and added HTTPS support as well as Yubikey required logins. Once that was in place my [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s no secret that I&#8217;m using <a href="http://mu.wordpress.org/">WordPress MU</a> for this website. It makes it very easy to keep the main site as well as my and Tati&#8217;s blogs updated. Recently I&#8217;ve been wanting to continue properly securing the blogs and added HTTPS support as well as <a href="http://www.yubico.com/products/yubikey/">Yubikey</a> required logins. Once that was in place my next goal was to get <a href="http://openid.net/">OpenID</a> integrated with the sites again. This way the blogs can be used as our OpenID identify. I also wanted to use OpenID to allow others to comment on posts. I ended up using the <a href="http://wordpress.org/extend/plugins/openid/">WordPress OpenID</a> plugin and with a little tweaking works perfectly with WPMU.</p>
<p>All total setting everything up did not go as smoothly as I had hoped but it all got implemented and is working properly. The easiest part of adding HTTPS support was getting Apache configured. I&#8217;m not going to go into detail about how to use SSL with Apache mainly because there are plenty of <a href="http://library.linode.com/ssl-guides/subject-alt-name-ssl">tutorials</a> <a href="http://www.debian-administration.org/article/Setting_up_an_SSL_server_with_Apache2">available</a> for this.</p>
<p>I ran into HTTPS problems with WordPress itself. I first read the WordPress guide for <a href="http://codex.wordpress.org/Administration_Over_SSL">Administration Over SSL</a> but could not get the force SSL options to work. I ended up using the rewrite rules. The rewrite rules worked fine until I tried adding OpenID. Since they rewrite the URL from HTTP to HTTPS under certain circumstances it was causing the OpenID redirects to fail. Removing the rewrite rules would made everything work. After a while I went back to trying to get the force SSL options working. What I discovered is the following options need to be toward the beginning of the wp-config.php file not the end. Putting them at the end causes them to not be loaded.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'FORCE_SSL_ADMIN'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'FORCE_SSL_LOGIN'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The SSL issues didn&#8217;t end there. The OpenID plugin&#8217;s <a href="http://wordpress.org/extend/plugins/openid/faq/">FAQ</a> says that the following option needs to be set when using the force SSL options.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'OPENID_SSL'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>However, <b>don&#8217;t set the OPENID_SSL option</b> because it will cause OpenID logins to fail. WordPress MU (at least 3.0) will redirect to SSL for login and then redirect back just fine without OpenID needing to account for the HTTPS connection itself.</p>
<p>That takes care of getting SSL working getting OpenID working with SSL. However, I did have two issues with getting the OpenID plugin working.</p>
<p>First, I was using the <a href="http://wordpress.org/extend/plugins/bad-behavior/">Bad Behavior</a> plugin. I say was because it causes OpenID logins to fail. For some reason Bad Behavior detects OpenID logins directed to the OpenID server that the OpenID plugin has created as attacks on the blog. I have not tried to find a way to make the two work together and instead just removed Bad Behavior. This was an easy decision because in the past few months I was using Bad Behavior it only reports stopping a very low number of attacks.</p>
<p>Second, the latest release of the OpenID plugin does not work properly with PHP 5.3. Luckily there is a <a href="http://code.google.com/p/diso/issues/detail?id=161">patch</a> to fix this. Changing the two lines makes is all that&#8217;s need to get it working.</p>
<p>The OpenID plugin works with WordPress MU 3.0 and works with and SSL protected logins. You need to patch OpenID if you are using PHP 5.3 and don&#8217;t set the OPENID_SSL option. Also, don&#8217;t use Bad Behavior and use WordPress&#8217;s built in SSL options instead of rewrite rules.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2010/07/28/wpmu-openid-and-ssl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Yubikey Auto Lock in Gnome</title>
		<link>http://john.nachtimwald.com/2010/07/25/yubikey-auto-lock-in-gnome/</link>
		<comments>http://john.nachtimwald.com/2010/07/25/yubikey-auto-lock-in-gnome/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 22:05:29 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[screen saver]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[yubikey]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=433</guid>
		<description><![CDATA[I recently purchased a Yubikey from Yubico. What got me to buy it was the discount they&#8217;re offering to Security Now! listeners. So far I&#8217;m liking it quite a bit and have been looking to use it any way I can. One of the uses I found was to have the presence of they Yubikey [...]]]></description>
			<content:encoded><![CDATA[<p>I recently purchased a <a href="http://www.yubico.com/products/yubikey/">Yubikey</a> from <a href="http://www.yubico.com/">Yubico</a>. What got me to buy it was the discount they&#8217;re offering to <a href="http://twit.tv/sn">Security Now!</a> listeners. So far I&#8217;m liking it quite a bit and have been looking to use it any way I can. One of the uses I found was to have the presence of they Yubikey <a href="http://forum.yubico.com/viewtopic.php?f=11&#038;t=246">unlock and lock</a> Gnome Screen Saver.</p>
<p>Toward the end of the forum thread there is a very nice set of udev rules that work perfect for me and are very clean. I put the following into /etc/udev/rules.d/85-yubikey.rules</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">ACTION</span>==<span style="color: #ff0000;">&quot;add&quot;</span>, ENV<span style="color: #7a0874; font-weight: bold;">&#123;</span>ID_VENDOR<span style="color: #7a0874; font-weight: bold;">&#125;</span>==<span style="color: #ff0000;">&quot;Yubico&quot;</span>, RUN+=<span style="color: #ff0000;">&quot;/usr/local/bin/gnome-screensaver-unlock&quot;</span>
<span style="color: #007800;">ACTION</span>==<span style="color: #ff0000;">&quot;remove&quot;</span>, ENV<span style="color: #7a0874; font-weight: bold;">&#123;</span>ID_VENDOR<span style="color: #7a0874; font-weight: bold;">&#125;</span>==<span style="color: #ff0000;">&quot;Yubico&quot;</span>, RUN+=<span style="color: #ff0000;">&quot;/usr/local/bin/gnome-screensaver-lock&quot;</span></pre></div></div>

<p>I really dislike the scripts that are in the thread for locking and unlocking the computer. Gnome Screen Saver is a DBus enabled application so controlling it is very easy. Below are the unlock and lock scripts I&#8217;ve written. They use qdbus to send the dbus commands. This could be replaced with dbus-send but I use Qt and qdbus&#8217;s syntax is easier to work with.</p>
<p>gnome-screensaver-unlock</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
&nbsp;
<span style="color: #007800;">user</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">ps</span> aux <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> gnome-screensaver <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">head</span> <span style="color: #660033;">-n</span> <span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1}'</span><span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-n</span> <span style="color: #007800;">$user</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #007800;">GNOME_SCREENSAVER_PROC</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">ps</span> xa <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> gnome-screensaver <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">head</span> <span style="color: #660033;">-n</span> <span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1}'</span><span style="color: #000000; font-weight: bold;">`</span>
        <span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-z</span> DBUS_SESSION_BUS_ADDRESS <span style="color: #000000; font-weight: bold;">/</span>proc<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$GNOME_SCREENSAVER_PROC</span><span style="color: #000000; font-weight: bold;">/</span>environ<span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
        <span style="color: #c20cb9; font-weight: bold;">su</span> <span style="color: #007800;">$user</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;qdbus org.gnome.ScreenSaver / SetActive false&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>gnome-screensaver-lock</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
&nbsp;
<span style="color: #007800;">user</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">ps</span> aux <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> gnome-screensaver <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">head</span> <span style="color: #660033;">-n</span> <span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1}'</span><span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-n</span> <span style="color: #007800;">$user</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #007800;">GNOME_SCREENSAVER_PROC</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">ps</span> xa <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> gnome-screensaver <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">head</span> <span style="color: #660033;">-n</span> <span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $1}'</span><span style="color: #000000; font-weight: bold;">`</span>
	<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">grep</span> <span style="color: #660033;">-z</span> DBUS_SESSION_BUS_ADDRESS <span style="color: #000000; font-weight: bold;">/</span>proc<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$GNOME_SCREENSAVER_PROC</span><span style="color: #000000; font-weight: bold;">/</span>environ<span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
	<span style="color: #c20cb9; font-weight: bold;">su</span> <span style="color: #007800;">$user</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;qdbus org.gnome.ScreenSaver / SetActive true&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>One thing that isn&#8217;t mentioned in the forum thread that is very important, <b>this unlocking method is highly insecure</b>. The locking portion is fine but unlocking shouldn&#8217;t actually be done in this way. The above udev rules only checks that a Yubikey is inserted. It does not which which Yubikey is inserted. Any Yubikey can bypass your password and unlock the computer. The unlocking script does not preform any additional checks against the yubikey. Due to this, I don&#8217;t have the unlock code enabled on my computer.</p>
<p>However, it is possible to make unlocking secure. You can use one of the two yubikey pam modules, Yubico&#8217;s <a href="http://code.google.com/p/yubico-pam/">yubico-pam</a> and Securix Live&#8217;s <a href="http://www.securixlive.com/yubipam/index.php">yubipam</a>. Yubico-pam requires internet access because it validates against Yubico&#8217;s servers. Yubipam does not need internet access but you will have to reprogram your Yubikey with a new AES key. The new key must be stored in the computer. Each has it&#8217;s advantages and disadvantages but using the pam module with Gnome Screen Saver (I haven&#8217;t actually tried so it might not work) will provide you with a secure unlock.</p>
<p>Thinking about secure unlocks there is a <a href="http://forum.yubico.com/viewtopic.php?f=11&#038;t=210">clever solution</a> that allows for the Yubikey to be used with SSH without the need for the pam module. If I can find a way (I haven&#8217;t looked yet) to have an input that can capture the Yubikey&#8217;s output then it would be possible to handle the unlock in a secure manner without the need for the pam module&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2010/07/25/yubikey-auto-lock-in-gnome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>KDocker 4.4 Released</title>
		<link>http://john.nachtimwald.com/2010/07/17/kdocker-4-4-released/</link>
		<comments>http://john.nachtimwald.com/2010/07/17/kdocker-4-4-released/#comments</comments>
		<pubDate>Sat, 17 Jul 2010 15:03:09 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[KDocker]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=429</guid>
		<description><![CDATA[I&#8217;ve released KDocker 4.4 today. It is mostly bug fixes and clean up. However, there is one major change. The feature to dock when the window decorator close button (the x in the upper corner) is clicked has been removed. This feature was introduced in 4.3 and I really like how it. It gives KDocker [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve released KDocker 4.4 today. It is mostly bug fixes and clean up. However, there is one major change. The feature to dock when the window decorator close button (the x in the upper corner) is clicked has been removed. This feature was introduced in 4.3 and I really like how it. It gives KDocker a feature that no similar application has. However, I was not able to keep it due to a number of issues it introduced.</p>
<p>The dock when closed feature was implemented via XEmbed. Basically I was creating my own window mimicking the window border of the application&#8217;s window. I would then remove the border from the application&#8217;s window and embed it into my window. Events would be passed from my window into the embedded window. This should work just fine in theory but it didn&#8217;t work out so nicely. Embedding caused five issues. The first four are serious and the last is only an annoyance.</p>
<p>The most serious issue was, it broke drag and drop. This looks to be an issue with X itself because I could recreate the problem using Qt and GTK&#8217;s embed support as well as writing the embed calls myself using xlib.</p>
<p>Another issue it caused related to support windows. When the main window was embedded it broke the connection between the main window and it&#8217;s support windows. So when docking the main window there were issues docking the applications other windows. This is an issue for applications such as XMMS and the Gimp.</p>
<p>Embedding didn&#8217;t get along very well with borderless windows. Applications like Chrome and XMMS draw their own window border in place of using the window manager&#8217;s decorations. These applications have special handling for moving when clicking and dragging their border. When they are embedded you end up with one of two situations. You can click and drag the window but only in the container window. So instead of moving the window you just move the window&#8217;s contents. The other situation is moving via the border doesn&#8217;t work at all. In this case resizing doesn&#8217;t work either. Oh, and the minimize, maximize, close buttons might not work either. In both cases you can still move the window using alt+left mouse button but this isn&#8217;t ideal.</p>
<p>Focus handling with embedded windows didn&#8217;t work correctly between different window managers and possibly different versions of Xorg. Some combinations it was fine. Others focus handling only followed the mouse. There were issues with the embedded window never getting focus or only getting focus when using alt+tab to select the window after it was docked.</p>
<p>The only annoying issue that I was okay with having was when undocking a window the window manager (compiz) would cause it to move a little bit. When undocking the position of the container window is recorded, the embedded window is removed from the container and moved to it&#8217;s location. Then the container window is destroyed. Compiz didn&#8217;t like placing two windows in the exact same place and kept moving the second window down and right by the size of the decoration and frame. This isn&#8217;t a very big issue but I really don&#8217;t want to have window manager specific work arounds in the code base.</p>
<p>The decision to remove iconify on close wasn&#8217;t taken lightly. It was only due to the large number of issues it created. There is not point in using KDocker if it is only going to make docked applications unusable. I have created a <a href="https://code.launchpad.net/~user-none/kdocker/EmbedContainer">branch</a> for iconify on close so I can hopefully get it working properly.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2010/07/17/kdocker-4-4-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>lebookread 0.2</title>
		<link>http://john.nachtimwald.com/2010/07/11/lebookread-0-2/</link>
		<comments>http://john.nachtimwald.com/2010/07/11/lebookread-0-2/#comments</comments>
		<pubDate>Mon, 12 Jul 2010 01:21:49 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=420</guid>
		<description><![CDATA[I&#8217;ve made a new release of lebookread. This version supports the following formats: palmdoc, ztxt, epub, tcr, rb, mobi, and fb2. The library is usable but still needs a lot of work. Unit testing, examples, more code comments and more formats to name a few things.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve made a new release of <a href="https://launchpad.net/lebookread">lebookread</a>. This version supports the following formats: palmdoc, ztxt, epub, tcr, rb, mobi, and fb2. The library is usable but still needs a lot of work. Unit testing, examples, more code comments and more formats to name a few things.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2010/07/11/lebookread-0-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Qt Remove Directory and Its Contents</title>
		<link>http://john.nachtimwald.com/2010/06/08/qt-remove-directory-and-its-contents/</link>
		<comments>http://john.nachtimwald.com/2010/06/08/qt-remove-directory-and-its-contents/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 12:47:28 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[qt]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=391</guid>
		<description><![CDATA[When dealing with directories, Qt has a large number of functions to make manipulating them easy. However, it does not include a way to delete a non-empty directory. This little omission is easily solved. Following is a recursive function that will delete a directory along with all of it&#8217;s contents. This will delete depth first. [...]]]></description>
			<content:encoded><![CDATA[<p>When dealing with directories, Qt has a large number of functions to make manipulating them easy. However, it does not include a way to delete a non-empty directory. This little omission is easily solved.</p>
<p>Following is a recursive function that will delete a directory along with all of it&#8217;s contents. This will delete depth first. Meaning it will recurse into sub-directories and only start deleting once the directory has no sub-directories. Changing QDir::DirsFirst to QDir::DirsLast will change this into a breadth first search.</p>
<p>fileutils.h</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifndef FILEUTILS_H</span>
<span style="color: #339900;">#define FILEUTILS_H</span>
&nbsp;
<span style="color: #339900;">#include &lt;QString&gt;</span>
&nbsp;
<span style="color: #0000ff;">class</span> FileUtils
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> removeDir<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> QString <span style="color: #000040;">&amp;</span>dirName<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#endif // FILEUTILS_H</span></pre></div></div>

<p>fileutils.cpp</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;QDir&gt;</span>
<span style="color: #339900;">#include &lt;QFile&gt;</span>
<span style="color: #339900;">#include &lt;QFileInfo&gt;</span>
<span style="color: #339900;">#include &lt;QFileInfoList&gt;</span>
&nbsp;
<span style="color: #339900;">#include &quot;fileutils.h&quot;</span>
&nbsp;
<span style="color: #ff0000; font-style: italic;">/*!
   Delete a directory along with all of its contents.
&nbsp;
   \param dirName Path of directory to remove.
   \return true on success; false on error.
*/</span>
<span style="color: #0000ff;">bool</span> FileUtils<span style="color: #008080;">::</span><span style="color: #007788;">removeDir</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> QString <span style="color: #000040;">&amp;</span>dirName<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">bool</span> result <span style="color: #000080;">=</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
    QDir dir<span style="color: #008000;">&#40;</span>dirName<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>dir.<span style="color: #007788;">exists</span><span style="color: #008000;">&#40;</span>dirName<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        Q_FOREACH<span style="color: #008000;">&#40;</span>QFileInfo info, dir.<span style="color: #007788;">entryInfoList</span><span style="color: #008000;">&#40;</span>QDir<span style="color: #008080;">::</span><span style="color: #007788;">NoDotAndDotDot</span> <span style="color: #000040;">|</span> QDir<span style="color: #008080;">::</span><span style="color: #007788;">System</span> <span style="color: #000040;">|</span> QDir<span style="color: #008080;">::</span><span style="color: #007788;">Hidden</span>  <span style="color: #000040;">|</span> QDir<span style="color: #008080;">::</span><span style="color: #007788;">AllDirs</span> <span style="color: #000040;">|</span> QDir<span style="color: #008080;">::</span><span style="color: #007788;">Files</span>, QDir<span style="color: #008080;">::</span><span style="color: #007788;">DirsFirst</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>info.<span style="color: #007788;">isDir</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
                result <span style="color: #000080;">=</span> removeDir<span style="color: #008000;">&#40;</span>info.<span style="color: #007788;">absoluteFilePath</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
            <span style="color: #008000;">&#125;</span>
            <span style="color: #0000ff;">else</span> <span style="color: #008000;">&#123;</span>
                result <span style="color: #000080;">=</span> QFile<span style="color: #008080;">::</span><span style="color: #0000dd;">remove</span><span style="color: #008000;">&#40;</span>info.<span style="color: #007788;">absoluteFilePath</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
            <span style="color: #008000;">&#125;</span>
&nbsp;
            <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>result<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
                <span style="color: #0000ff;">return</span> result<span style="color: #008080;">;</span>
            <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span>
        result <span style="color: #000080;">=</span> dir.<span style="color: #007788;">rmdir</span><span style="color: #008000;">&#40;</span>dirName<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> result<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2010/06/08/qt-remove-directory-and-its-contents/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++ Derived Classes and Object Destruction</title>
		<link>http://john.nachtimwald.com/2010/05/29/c-derived-classes-and-object-destruction/</link>
		<comments>http://john.nachtimwald.com/2010/05/29/c-derived-classes-and-object-destruction/#comments</comments>
		<pubDate>Sat, 29 May 2010 15:56:09 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=385</guid>
		<description><![CDATA[While working on lebookread I realized that the the destructor for my reader classes would never be called. lebook read has a base class (FormatReader) that exports all of the necessary functionality for use by applications using the library. All of the readers are a subclass of FormatReader. The library will find the appropriate reader [...]]]></description>
			<content:encoded><![CDATA[<p>While working on lebookread I realized that the the destructor for my reader classes would never be called. lebook read has a base class (FormatReader) that exports all of the necessary functionality for use by applications using the library. All of the readers are a subclass of FormatReader. The library will find the appropriate reader for the specified ebook create a reader object and return it as a FormatReader pointer.</p>
<p>When you are dealing with a pointer <i>p</i> of type <i>base</i> that points to an object of type <i>derived</i> you need to take special care. To have the destruction of <i>p</i> call the derived and base destructor the base class must have a virtual destructor. Otherwise only the base class&#8217;s destructor will be called. This is one of those little things to look out for when dealing with C++.</p>
<p>Here is some example code to demonstrate the above.</p>
<p>main.cpp</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
&nbsp;
<span style="color: #339900;">#include &quot;base.h&quot;</span>
<span style="color: #339900;">#include &quot;deriv.h&quot;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span><span style="color: #000040;">**</span> argv<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Base *b = new Base();&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;delete b;&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    Base <span style="color: #000040;">*</span>b <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> Base<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; --- &quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">delete</span> b<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; --- &quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;b destroyed&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Deriv *d = new Deriv();&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;delete d&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    Deriv <span style="color: #000040;">*</span>d <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> Deriv<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; --- &quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">delete</span> d<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; --- &quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;d destroyed&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Base *c = new Deriv();&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;delete c&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    Base <span style="color: #000040;">*</span>c <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> Deriv<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; --- &quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">delete</span> c<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot; --- &quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;c destroyed&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifndef BASE_H</span>
<span style="color: #339900;">#define BASE_H</span>
&nbsp;
<span style="color: #0000ff;">class</span> Base
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    ~Base<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#endif /* BASE_H */</span></pre></div></div>

<p>base.cpp</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
&nbsp;
<span style="color: #339900;">#include &quot;base.h&quot;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
Base<span style="color: #008080;">::</span>~Base<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;base dest&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>deriv.h</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifndef DERIV_H</span>
<span style="color: #339900;">#define DERIV_H</span>
&nbsp;
<span style="color: #339900;">#include &quot;base.h&quot;</span>
&nbsp;
<span style="color: #0000ff;">class</span> Deriv <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> Base
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    ~Deriv<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#endif /* DERIV_H */</span></pre></div></div>

<p>deriv.cpp</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
&nbsp;
<span style="color: #339900;">#include &quot;deriv.h&quot;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
Deriv<span style="color: #008080;">::</span>~Deriv<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;deriv dest&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<p>The output of this will be:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ .<span style="color: #000000; font-weight: bold;">/</span>a.out 
Base <span style="color: #000000; font-weight: bold;">*</span>b = new Base<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;
delete b;
 <span style="color: #660033;">---</span> 
base dest
 <span style="color: #660033;">---</span> 
b destroyed
&nbsp;
Deriv <span style="color: #000000; font-weight: bold;">*</span>d = new Deriv<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;
delete d
 <span style="color: #660033;">---</span> 
deriv dest
base dest
 <span style="color: #660033;">---</span> 
d destroyed
&nbsp;
Base <span style="color: #000000; font-weight: bold;">*</span>c = new Deriv<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;
delete c
 <span style="color: #660033;">---</span> 
base dest
 <span style="color: #660033;">---</span> 
c destroyed</pre></div></div>

<p>Notice that when destroying c only the Base&#8217;s destructor is called. To fix this and have both Base and Deriv&#8217;s destructors called just make Base&#8217;s destructor virtual.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifndef BASE_H</span>
<span style="color: #339900;">#define BASE_H</span>
&nbsp;
<span style="color: #0000ff;">class</span> Base
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">virtual</span> ~Base<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#endif /* BASE_H */</span></pre></div></div>

<p>This simple change will cause the output to become:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ .<span style="color: #000000; font-weight: bold;">/</span>a.out 
Base <span style="color: #000000; font-weight: bold;">*</span>b = new Base<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;
delete b;
 <span style="color: #660033;">---</span> 
base dest
 <span style="color: #660033;">---</span> 
b destroyed
&nbsp;
Deriv <span style="color: #000000; font-weight: bold;">*</span>d = new Deriv<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;
delete d
 <span style="color: #660033;">---</span> 
deriv dest
base dest
 <span style="color: #660033;">---</span> 
d destroyed
&nbsp;
Base <span style="color: #000000; font-weight: bold;">*</span>c = new Deriv<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;
delete c
 <span style="color: #660033;">---</span> 
deriv dest
base dest
 <span style="color: #660033;">---</span> 
c destroyed</pre></div></div>

<p>Now when destroying c the destructor for both Base and Deriv are called.</p>
<p>To compile</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">g++</span> base.cpp deriv.cpp main.cpp</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2010/05/29/c-derived-classes-and-object-destruction/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>lebookread</title>
		<link>http://john.nachtimwald.com/2010/05/16/lebookread/</link>
		<comments>http://john.nachtimwald.com/2010/05/16/lebookread/#comments</comments>
		<pubDate>Mon, 17 May 2010 01:52:56 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[lebookread]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[epub]]></category>
		<category><![CDATA[palmdoc]]></category>
		<category><![CDATA[pdb]]></category>
		<category><![CDATA[qt]]></category>
		<category><![CDATA[rb]]></category>
		<category><![CDATA[ztxt]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=358</guid>
		<description><![CDATA[I have been taking a short break from blogging again. The pressure at work has only increased and is eating into a lot of my time. I haven&#8217;t been motivated to work on personal projects because well they are work. However, this has recently changed a bit. I&#8217;ve started a Qt based library for reading [...]]]></description>
			<content:encoded><![CDATA[<p>I have been taking a short break from blogging again. The pressure at work has only increased and is eating into a lot of my time. I haven&#8217;t been motivated to work on personal projects because well they are work. However, this has recently changed a bit.</p>
<p>I&#8217;ve started a Qt based library for reading ebooks in a generic manner. It is called <a href="https://launchpad.net/lebookread">lebookread</a>! It is it&#8217;s early stages. So far I have it supporting epub, palmdoc pdb, ztxt pdb, tcr, and rb files. I plan to support ereader pdb, mobi, and plucker files in the near future.</p>
<p>The main goal of this project is to make reading ebooks easy for Qt based projects. I&#8217;ve chose to write the library in C++. This is also my first attempt at writing a library and it shows. I hope that it will be used by <a href="http://code.google.com/p/sigil/">Sigil</a>.</p>
<p>The real motivation of writing lebook read is I really want a good light weight ebook reader. The current offering have issues. I want something that is a bit more advanced in it&#8217;s rendering than <a href="http://www.fbreader.org/">FBReader</a>. I also didn&#8217;t want anything with as large a dependency list as <a href="http://calibre-ebook.com/">calibre</a>. So, I plan on using lebookread to write my own ebook viewer.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2010/05/16/lebookread/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Long time no see</title>
		<link>http://john.nachtimwald.com/2010/03/10/long-time-no-see/</link>
		<comments>http://john.nachtimwald.com/2010/03/10/long-time-no-see/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 00:19:06 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[calibre]]></category>
		<category><![CDATA[site maintenance]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=355</guid>
		<description><![CDATA[It&#8217;s been a while since I&#8217;ve made any posts. Mainly work and other matters have kept me away. I haven&#8217;t been working on very much recently. This isn&#8217;t to say my participation with calibre has been abandoned. I&#8217;m still making regular bug fixes. I&#8217;ve also been working on a rather large change that is coming [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I&#8217;ve made any posts. Mainly work and other matters have kept me away. I haven&#8217;t been working on very much recently.</p>
<p>This isn&#8217;t to say my participation with calibre has been abandoned. I&#8217;m still making regular bug fixes. I&#8217;ve also been working on a rather large change that is coming along much slower that I would like. Mainly metadata caching and muli way syncing. I was shooting for the end of March to complete the changes but it might not be done until the end of April.</p>
<p>I&#8217;ve also moved this blog off of the shared hosting package I was using. It&#8217;s now hosted on my own virtual private server. Attachments, images and the now reading list did not make it over in the transition. I&#8217;m still using WordPress but instead of having multiple separate installs of it all the blogs here are powered by one WordPress MU installation.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2010/03/10/long-time-no-see/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cybook t4b Format Specification</title>
		<link>http://john.nachtimwald.com/2010/01/13/cybook-t4b-format-specification/</link>
		<comments>http://john.nachtimwald.com/2010/01/13/cybook-t4b-format-specification/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 02:09:23 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[hardware]]></category>
		<category><![CDATA[cybook]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[pgm]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[t2b]]></category>
		<category><![CDATA[t4b]]></category>
		<category><![CDATA[thumbnail]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=349</guid>
		<description><![CDATA[The new epub thumbnail files (.epub.thn) are what Bookeen calls t4b files. They are very similar to the older t2b thumbnail files they were using in earlier versions of the Cybook firmware. As the name suggests instead of using 2 bits to represent color values 4 bits are now used. This increases the number of [...]]]></description>
			<content:encoded><![CDATA[<p>The new epub thumbnail files (.epub.thn) are what Bookeen calls t4b files. They are very similar to the older <a href="http://john.nachtimwald.com/2009/01/19/cybook-t2b-format-specification/">t2b</a> thumbnail files they were using in earlier versions of the Cybook firmware. As the name suggests instead of using 2 bits to represent color values 4 bits are now used. This increases the number of colors from 4 to 16. In addition to the increased color range the t4b files now require a header of &#8220;t4bp&#8221; without the quotes.</p>
<p>The image’s dimensions are 96×144. The bits representing 0, 1, 2, 3&#8230; are written directly to the file. it is very similar to a pgm file in this regard. Each 4 bit sequence represents a pixel color. Only black, white and shades of gray are supported.</p>
<p>Every t4b file will have 13,824 pixels. The file size will always be 6,916 bytes. The formula to determine this is: (height x width x 2 bits per pixel) / 8 bits per byte. ((96 * 144 * 4) / 8 ) + 4 = 6,916. The + 4 is the header.</p>
<p>Following are two python scripts for converting an image to a t4b file and for converting a t4b file into a <a href="http://netpbm.sourceforge.net/doc/pgm.html">pgm image</a>.</p>
<p>image2t4b.py</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>, Image
&nbsp;
REDUCE_MARKS = <span style="color: black;">&#91;</span><span style="color: #ff4500;">16</span>, <span style="color: #ff4500;">32</span>, <span style="color: #ff4500;">48</span>, <span style="color: #ff4500;">64</span>, <span style="color: #ff4500;">80</span>, <span style="color: #ff4500;">96</span>, <span style="color: #ff4500;">112</span>, <span style="color: #ff4500;">128</span>, <span style="color: #ff4500;">144</span>, <span style="color: #ff4500;">160</span>, <span style="color: #ff4500;">176</span>, <span style="color: #ff4500;">192</span>, <span style="color: #ff4500;">208</span>, <span style="color: #ff4500;">224</span>, <span style="color: #ff4500;">240</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> reduce_color<span style="color: black;">&#40;</span>c<span style="color: black;">&#41;</span>:
    val = <span style="color: #ff4500;">0</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> mark <span style="color: #ff7700;font-weight:bold;">in</span> REDUCE_MARKS:
        <span style="color: #ff7700;font-weight:bold;">if</span> c <span style="color: #66cc66;">&amp;</span>gt<span style="color: #66cc66;">;</span> mark:
            val += <span style="color: #ff4500;">1</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #ff7700;font-weight:bold;">break</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> val
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= <span style="color: #ff4500;">3</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">Exception</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Must have 2 arguments. %s input.image output.epub.thn'</span> <span style="color: #66cc66;">%</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
    outf = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>, <span style="color: #483d8b;">'wb'</span><span style="color: black;">&#41;</span>
&nbsp;
    im = Image.<span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>.<span style="color: black;">convert</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;L&quot;</span><span style="color: black;">&#41;</span>
    im.<span style="color: black;">thumbnail</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">96</span>, <span style="color: #ff4500;">144</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    newim = Image.<span style="color: #dc143c;">new</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'L'</span>, <span style="color: black;">&#40;</span><span style="color: #ff4500;">96</span>, <span style="color: #ff4500;">144</span><span style="color: black;">&#41;</span>, <span style="color: #483d8b;">'white'</span><span style="color: black;">&#41;</span>
&nbsp;
    x,y = im.<span style="color: black;">size</span>
    newim.<span style="color: black;">paste</span><span style="color: black;">&#40;</span>im, <span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">96</span>-x<span style="color: black;">&#41;</span>/<span style="color: #ff4500;">2</span>, <span style="color: black;">&#40;</span><span style="color: #ff4500;">144</span>-y<span style="color: black;">&#41;</span>/<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    outf.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'t4bp'</span><span style="color: black;">&#41;</span>
&nbsp;
    px = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> p <span style="color: #ff7700;font-weight:bold;">in</span> newim.<span style="color: black;">getdata</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        px.<span style="color: black;">append</span><span style="color: black;">&#40;</span>p<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>px<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">2</span>:
            byte_val = bin<span style="color: black;">&#40;</span>reduce_color<span style="color: black;">&#40;</span>px<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span>:<span style="color: black;">&#93;</span>.<span style="color: black;">zfill</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span> + bin<span style="color: black;">&#40;</span>reduce_color<span style="color: black;">&#40;</span>px<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span>:<span style="color: black;">&#93;</span>.<span style="color: black;">zfill</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>
            outf.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #008000;">chr</span><span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span>byte_val, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            px = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>px<span style="color: black;">&#41;</span> <span style="color: #66cc66;">&amp;</span>gt<span style="color: #66cc66;">;</span> <span style="color: #ff4500;">2</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">Exception</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Fatal error px length increased past 2.'</span><span style="color: black;">&#41;</span>
&nbsp;
    outf.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>t4b2pgm.py</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>, <span style="color: #dc143c;">os</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> get_greys<span style="color: black;">&#40;</span>b<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> b:
        <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span>
&nbsp;
    b = bin<span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span><span style="color: #008000;">ord</span><span style="color: black;">&#40;</span>b<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    b = b<span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span>:<span style="color: black;">&#93;</span>.<span style="color: black;">zfill</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">8</span><span style="color: black;">&#41;</span>
&nbsp;
    w = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span>b<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span>:<span style="color: #ff4500;">4</span><span style="color: black;">&#93;</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    x = <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#40;</span>b<span style="color: black;">&#91;</span><span style="color: #ff4500;">4</span>:<span style="color: #ff4500;">8</span><span style="color: black;">&#93;</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">return</span> w, x
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">!</span>= <span style="color: #ff4500;">3</span>:
        <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">Exception</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Must have 2 arguments. %s input.epub.thm output.pgm'</span> <span style="color: #66cc66;">%</span> <span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
    t4bfile = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, <span style="color: #483d8b;">'rb'</span><span style="color: black;">&#41;</span>
    pgmfile = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">argv</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>, <span style="color: #483d8b;">'w'</span><span style="color: black;">&#41;</span>
&nbsp;
    pgmfile.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'P2<span style="color: #000099; font-weight: bold;">\n</span>96 144<span style="color: #000099; font-weight: bold;">\n</span>15<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Read past the t4b header</span>
    t4bfile.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">144</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">for</span> j <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">48</span><span style="color: black;">&#41;</span>:
            b = t4bfile.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
            vals = get_greys<span style="color: black;">&#40;</span>b<span style="color: black;">&#41;</span>
            pgmfile.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s %s '</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>vals<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, vals<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        pgmfile.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: black;">&#41;</span>
&nbsp;
    pgmfile.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    t4bfile.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2010/01/13/cybook-t4b-format-specification/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cybook 2.0 Thumbnail Observations</title>
		<link>http://john.nachtimwald.com/2010/01/13/cybook-2-0-thumbnail-observations/</link>
		<comments>http://john.nachtimwald.com/2010/01/13/cybook-2-0-thumbnail-observations/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 00:38:51 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[hardware]]></category>
		<category><![CDATA[cybook]]></category>
		<category><![CDATA[gadgets]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[thumbnail]]></category>

		<guid isPermaLink="false">http://john.nachtimwald.com/?p=346</guid>
		<description><![CDATA[The 2.0 fimware for the Cybook and Opus have new thumbnails for epub files. They use the .thn extension and it is append after the .epub extension. This is unlike the _6090.t2b thumbnails which use the book name without the extension and _6090.t2b appended to it. I have yet to start figuring out this new [...]]]></description>
			<content:encoded><![CDATA[<p>The 2.0 fimware for the Cybook and Opus have new thumbnails for epub files. They use the .thn extension and it is append after the .epub extension. This is unlike the _6090.t2b thumbnails which use the book name without the extension and _6090.t2b appended to it. I have yet to start figuring out this new format but at first glance it looks to be similar to the _6090.t2b files.</p>
<p>What I have found is, if a _6090.t2b file is present that will be used and the .thn file will not be generated and the _6090.t2b will be used as the thumbnail. However, if both the _6090.t2b and .thn are present then the .thn will be used.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.nachtimwald.com/2010/01/13/cybook-2-0-thumbnail-observations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
