<?xml version="1.0" encoding="UTF-8"?>
<rss version="0.92">
<channel>
 <title>www.nick-andrew.net</title>
 <link>http://www.nick-andrew.net/</link>
 <description>Nick Andrew's homepage</description>
 <language>en</language>
 <copyright>Creative Commons Attribution Share Alike (by-sa)</copyright>

<item>
	<title>Configuring IPv6 using AARNet's free broker</title>
	<description>
&lt;p&gt; You can obtain IPv6 connectivity in Australia using the &lt;a href="http://broker.aarnet.net.au/"&gt;AARNet IPv6 Migration Broker&lt;/a&gt; if your ISP does not already provide IPv6. As at August 2008, only &lt;a href="http://www.internode.on.net/"&gt;Internode&lt;/a&gt; is known to provide &lt;a href="http://ipv6.internode.on.net/"&gt;consumer level IPv6 access&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt; For Australian users who cannot obtain IPv6 through your ISP, the AARNet IPv6 tunnel is probably the next lowest latency choice. These instructions describe setting up IPv6 with linux over a consumer DSL connection with a dynamic IPv4 address (i.e. every time you connect you get a different IP address) and NAT (Network Address Translation) on the DSL modem. &lt;/p&gt;
&lt;p&gt; With IPv6 you can get a static address (well, 2^64 or more static addresses) and it's quite useful if you run a home network and want to provide access to devices within the network, from outside. That is, so long as the outside client has IPv6 (the chicken-and-egg problem). &lt;/p&gt;
&lt;p&gt; Certain assumptions are made in this document - like installed software or an IPv6 enabled kernel. If these instructions don't work for you, drop me an email at &lt;b&gt;nick&lt;/b&gt; at &lt;b&gt;nick-andrew.net&lt;/b&gt;. &lt;/p&gt;
&lt;h2&gt;Preparation - Kernel and Software&lt;/h2&gt;
&lt;p&gt; Make sure your kernel has IPv6 support. Do "ifconfig eth0" and check for a line like this in the output: &lt;/p&gt;
&lt;pre&gt;
          inet6 addr: fe80::212:34ff:fe56:789a/64 Scope:Link
&lt;/pre&gt;
&lt;p&gt; You may need to load the "ipv6" module. &lt;/p&gt;
&lt;p&gt; Check that you have the commands "ip6tables" and "ip". &lt;/p&gt;
&lt;h2&gt;Preparation - Firewall&lt;/h2&gt;
 It's good for security to setup the IPv6 firewall before you even start configuring it. Although you may have an IPv4 firewall already in place, that won't stop any IPv6 packets. I'll assume you want to make connections out, but block all connections in, which is the standard functionality you get with NAT, and useful for a client. For a server you will need to allow connections in for the server ports. &lt;h3&gt;ip6tables setup&lt;/h3&gt;
 I use a shell script with a function alias, to set the firewall. &lt;pre style="border-style:solid; background-color: #F0E0E0"&gt;
#!/bin/bash
#    Simple IPv6 firewall rules

doCmd6() {
        /sbin/ip6tables $*
        rc=$?
        if [ $rc != 0 ] ; then
                echo Error $rc doing ip6tables $*
        fi
}

doCmd6 -P INPUT DROP
doCmd6 -P FORWARD DROP

doCmd6 -F
doCmd6 -X

doCmd6 -N 6_log_drop
doCmd6 -N 6_icmp
doCmd6 -N 6_tcp

doCmd6 -A 6_log_drop -j LOG --log-prefix "ipv6:"
doCmd6 -A 6_log_drop -j DROP

#enable ssh in   doCmd6 -A 6_tcp -p tcp -d ::/0 --dport 22 -j ACCEPT
doCmd6 -A 6_tcp -j 6_log_drop

doCmd6 -F 6_icmp
doCmd6 -A 6_icmp -j ACCEPT


doCmd6 -A INPUT -i lo -j ACCEPT
doCmd6 -A INPUT -p ALL -m state --state ESTABLISHED,RELATED -j ACCEPT
doCmd6 -A INPUT -p icmpv6 -j 6_icmp
doCmd6 -A INPUT -p tcp -j 6_tcp
doCmd6 -A INPUT -j 6_log_drop
&lt;/pre&gt;
&lt;p&gt; This set of rules will allow you to make outbound IPv6 connections and will block inbound except for ICMP (your address can be pinged) and you can uncomment a line to enable ssh connections in. &lt;/p&gt;
&lt;h2&gt;Preparation - DSL modem&lt;/h2&gt;
&lt;p&gt; Assuming your DSL modem has a firewall, you will need to enable two things: &lt;ul&gt;&lt;li&gt;Outbound UDP connections to port 3653&lt;/li&gt;&lt;li&gt;Protocol 41 inbound/outbound&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;
&lt;p&gt;UDP port 3653 is used by the AARNet tunnel broker. Protocol 41 is used by 6to4 tunneling, which I will describe now. &lt;/p&gt;
&lt;h2&gt;Alternate access - 6to4 tunnel&lt;/h2&gt;
&lt;p&gt; Although this document is about obtaining IPv6 through AARNet's migration broker, there's a quicker way to get started on IPv6 using your dynamic IPv4 address. You will need the "curl" command installed. Run this script: &lt;/p&gt;
&lt;pre style="border-style:solid; background-color: #F0E0E0"&gt;
#!/bin/bash
#  Sets up an ipv6 tunnel through the nearest public gateway.
#  Automatically learns current ipv4 address.

ipv4=$(curl -s http://www.whatismyip.com/automation/n09230945.asp)
ipv6=$(printf "2002:%02x%02x:%02x%02x::1" $(echo $ipv4 | tr "." " " ) )

echo ipv4 is $ipv4 and ipv6 is $ipv6

ifconfig sit0 up
ifconfig sit0 add $ipv6/16
route -A inet6 add 2000::/3 gw ::192.88.99.1 dev sit0
&lt;/pre&gt;
&lt;p&gt; 192.88.99.1 is an address which routes to the nearest public IPv6 gateway. Unfortunately for us Australians, that's probably in the USA. But it's easy to setup, as you can see. &lt;/p&gt;
&lt;p&gt; This technique has some advantages and disadvantages. On the positive side, you have 2^80 addresses to use. That should be enough for anyone. On the negative side, these addresses are as dynamic as your IPv4 address because they are derived from it. Also, you may be able to make outbound connections but not accept inbound connections, depending on what functionality your DSL modem provides. My DSL modem allows me to open up protocol 41 traffic, but it doesn't provide a configuration option to forward all incoming protocol 41 connections to my linux box. So my box can only accept inbound connections while there's a working outbound connection (this is standard NAT functionality). &lt;/p&gt;
&lt;p&gt; So 6to4 is a good technique to get started with IPv6 if you want to, say, browse ipv6 websites. But it's not so useful for servers. &lt;/p&gt;
&lt;h2&gt;Testing - IPv6 using commands&lt;/h2&gt;
&lt;p&gt;"ping6" and "telnet" are your friends. &lt;/p&gt;
&lt;pre&gt;
$ ping6 ipv6.l.google.com
PING ipv6.l.google.com(2001:4860:0:2001::68) 56 data bytes
64 bytes from 2001:4860:0:2001::68: icmp_seq=1 ttl=52 time=308 ms
64 bytes from 2001:4860:0:2001::68: icmp_seq=2 ttl=52 time=335 ms
64 bytes from 2001:4860:0:2001::68: icmp_seq=3 ttl=52 time=321 ms
&lt;/pre&gt;
 &lt;pre&gt;
$ telnet luyer.net 80
Trying 2001:470:1f05:14d::1...
Connected to luyer.net.
Escape character is '^]'.
GET / HTTP/1.0

HTTP/1.1 200 OK
Date: Mon, 25 Aug 2008 00:38:50 GMT
Server: Apache/2.2.3 (Debian) PHP/4.4.4-8+etch6 mod_ssl/2.2.3
OpenSSL/0.9.8c
[ ... etc ... ]
&lt;/pre&gt;
&lt;p&gt; You can also install the netcat6 package (the command is "nc6") to connect out or listen for incoming connections. To test if your web browser is using IPv6 correctly, try these sites: &lt;ul&gt;&lt;li&gt;&lt;a href="http://www.kame.net/"&gt;www.kame.net&lt;/a&gt; - on IPv6 you will see a swimming turtle, on IPv4 the turtle will not move &lt;/li&gt;&lt;li&gt;&lt;a href="http://luyer.net/"&gt;luyer.net&lt;/a&gt; and it will tell you if you connected through IPv4 or IPv6 &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.sixxs.net/main/"&gt;www.sixxs.net&lt;/a&gt; will show your originating address and protocol at the bottom of the page. &lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;
&lt;h2&gt;Registering with AARNet&lt;/h2&gt;
&lt;p&gt; You'll need to create a username on the &lt;a href="http://broker.aarnet.net.au/"&gt;AARNet IPv6 Migration Broker&lt;/a&gt; and then associate that username with a tunnel. &lt;ol&gt;&lt;li&gt;&lt;a href="http://broker.aarnet.net.au/usercreate.html"&gt;Create User Account&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://broker.aarnet.net.au/tunnelreq.html"&gt;Request Tunnel&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/p&gt;
&lt;p&gt; The "Request Tunnel" CGI hangs for me, I don't know why. I assume it created a tunnel correctly because I'm getting one. &lt;/p&gt;
&lt;h2&gt;Installation of TSPC&lt;/h2&gt;
&lt;p&gt; Install the "tspc" package. I'm using Debian, so it's just "apt-get install tspc". &lt;/p&gt;
&lt;p&gt; When Debian installs tspc, it automatically configures it to obtain an anonymous IPv6 tunnel from freenet6.net. Although that's great and easy, it's not what we need in Australia. So after installation, stop the daemon with "/etc/init.d/tspc stop". &lt;/p&gt;
&lt;h2&gt;Configuring the AARNet tunnel broker&lt;/h2&gt;
&lt;p&gt; To be continued ... no time to write the rest of the document today. &lt;/p&gt;
&lt;p&gt; In brief, you need to use the v6udpv4 method and all traffic will be tunneled through a UDP connection. 30 second keepalive messages (I believe it's an ipv6 ping?) will keep NAT working. Your config file should look like this: &lt;/p&gt;
&lt;pre style="border-style:solid; background-color: #F0E0E0"&gt;
auth_method=any
userid=YOURUSERID
passwd=YOURPASSWORD

server=broker.aarnet.net.au
tunnel_mode=v6udpv4
host_type=router
prefixlen=64

client_v4=auto
if_prefix=eth0
if_tunnel_v6udpv4=tun
if_tunnel_v6v4=sit1

keepalive_interval=30
keepalive=yes

proxy_client=no
retry_delay=30
template=setup
&lt;/pre&gt;
&lt;p&gt; Note that AARNet assigns a /56 even though this config asks for a /64. &lt;/p&gt;
&lt;h2&gt;Monitoring the IPv6 tunnel&lt;/h2&gt;
&lt;p&gt; AARNet's broker seems a bit flaky. It sometimes ignores the UDP packets so you may need to start the daemon a few times before it connects properly. As I mentioned, the CGI to request a tunnel hangs for me. If it doesn't hang, it may return a shell script, which you can ignore. &lt;/p&gt;
&lt;p&gt; It's possible you don't even need to use the "Request Tunnel" CGI, maybe it will assign a permanent tunnel when tspc connects for the first time. &lt;/p&gt;
&lt;p&gt; Also AARNet reboot the server at 03:00 every morning. The tspc daemon will try to reconnect if the tunnel fails, but perhaps not forever. &lt;/p&gt;
&lt;p&gt; In any case, you want IPv6 to be always available, which means monitoring it. If the tspc daemon stops, you will need to restart it manually. I wrote this simple perl script which just logs whenever IPv6 stops working. It doesn't monitor the process or interface at all (you'd want to monitor the process itself if you change the script to restart a failed process). &lt;/p&gt;
&lt;pre style="border-style:solid; background-color: #F0E0E0"&gt;
#!/usr/bin/perl -w
#       @(#) $Id$
#       vim:sw=4:ts=4:

use Date::Format qw(time2str);
use Getopt::Std qw(getopts);

use vars qw($opt_h);

$| = 1;
getopts('h:');

$opt_h || die "Need option -h hostname";

# Initial and current state
my $state = 'down';

while (1) {
        my $now = time();
        my $newstate = getPingState($opt_h);

        if ($newstate ne $state) {
                open(OF, "&amp;gt;&amp;gt;ipv6-state.log");
                my $ts = time2str('%Y-%m-%d %T', $now);
                print OF "$ts $opt_h $newstate\n";
                close(OF);

                $state = $newstate;
        }

        my $to_wait = 60 - ($now % 60);
        print '.';
        sleep($to_wait);
}

# NOTREACHED
exit(0);

# ------------------------------------------------------------------------
# ping6 a host, and figure out if it is up
# ------------------------------------------------------------------------

sub getPingState {
        my $host = shift;

        my $rc = system("ping6 -c 2 -q -W 8 $host &amp;gt;/dev/null");
        if ($rc == 0) {
                return 'up';
        }

        return 'down';
}
&lt;/pre&gt;
&lt;p&gt; I just run it like this: "check-ipv6.pl ipv6.l.google.com" and it pings once a minute (on the minute) and logs whenever the calculated state of the IPv6 connectivity changes. &lt;/p&gt;
&lt;p&gt; For production use you'd want to change the 'sleep' to sleep(60) since it's not friendly to google for many sites to ping in synchronisation (i.e. always at :00). Of course you could always ping6 to broker.aarnet.net.au instead ... &lt;/p&gt;
&lt;pre&gt;
64 bytes from 2001:388:1:5001:2a0:a5ff:fe4b:ae3: icmp_seq=1 ttl=64 time=52.8 ms
64 bytes from 2001:388:1:5001:2a0:a5ff:fe4b:ae3: icmp_seq=2 ttl=64 time=51.6 ms
64 bytes from 2001:388:1:5001:2a0:a5ff:fe4b:ae3: icmp_seq=3 ttl=64 time=51.1 ms
&lt;/pre&gt;
	</description>
</item>

<item>
	<title>Forcing NFS to use consistent port numbers</title>
	<description>
&lt;p&gt; NFS servers don't play nice with iptables when the daemons use random port numbers (which is the default in debian). &lt;/p&gt;
&lt;p&gt; To force consistent port numbers upon NFS (when using nfs-kernel-server), set the following in /etc/default/nfs-kernel-server. This will force mountd to use port 4002 for both TCP and UDP. &lt;pre&gt;
RPCMOUNTDOPTS="--port 4002"
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt; For lockd, add the following into /etc/modules (you need to build lockd as a module for this) ... &lt;pre&gt;
lockd    nlm_udpport=33000 nlm_tcpport=42049
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt; Next, you can force statd to use port 4000 and port 4001 by setting this in /etc/default/nfs-common: &lt;pre&gt;
STATDOPTS="--port 4000 --outgoing-port 4001"
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt; Finally, add iptables rules: &lt;pre&gt;
iptables -F nfs_server
iptables -A nfs_server -p TCP --dport 2049 -j ACCEPT # nfs
iptables -A nfs_server -p TCP --dport 4000:4001 -j ACCEPT # statd
iptables -A nfs_server -p TCP --dport 4002 -j ACCEPT # mountd
iptables -A nfs_server -p UDP --destination-port 4002 -j ACCEPT # mountd
iptables -A nfs_server -p UDP --destination-port 33000 -j ACCEPT # lockd
iptables -A nfs_server -p TCP --dport 42049 -j ACCEPT # lockd
&lt;/pre&gt; Be sure that only packets from client IP addresses are directed through the nfs_server table. &lt;/p&gt;
	</description>
</item>

<item>
	<title>NameVirtualHost *:80 has no VirtualHosts</title>
	<description>
&lt;p&gt; Have you seen this error? &lt;pre style="background-color: #FF8080"&gt;
[Wed Jul 16 10:18:17 2008] [warn] NameVirtualHost *:80 has no VirtualHosts
&lt;/pre&gt; This is a particularly annoying message because there are many questions about it on many forums and no definitive answers. &lt;/p&gt;
&lt;p&gt; Quoting from &lt;a href="http://lists.debian.org/debian-user/2004/04/msg00856.html"&gt; apache2 &amp;lt;perl&amp;gt; sections: "*:80 has no VirtualHosts" error &lt;/a&gt; ... &lt;blockquote&gt;&lt;pre&gt;
In short, the following is an example that will produce the error
message quoted above :
    NameVirtualHosts    *:80
    &amp;lt;VirtualHost foo:80&amp;gt;
    &amp;lt;/VirtualHost&amp;gt;

In other words, if you have 'NameVirtualHosts BLAH' and you do not
have a '&amp;lt;VirtualHost BLAH&amp;gt;' directive, you get that error.
&lt;/pre&gt;&lt;/blockquote&gt;&lt;/p&gt;
&lt;p&gt; But that's not the end of the story. The following configuration also causes that error message (on "apache2 -f test.conf -S") ... &lt;pre style="border-style:solid; background-color: #F0E0E0"&gt;
Listen 80
NameVirtualHost *:80


&amp;lt;VirtualHost *:80&amp;gt;
        ServerName      name1.tull.net
        DocumentRoot    /var/www/
&amp;lt;/VirtualHost&amp;gt;


&amp;lt;VirtualHost *:80&amp;gt;
        ServerName      name2.tull.net
        DocumentRoot    /var/www/
&amp;lt;/VirtualHost&amp;gt;


&amp;lt;VirtualHost *:80&amp;gt;
        ServerName      name4.tull.net
        DocumentRoot    /var/www/
&amp;lt;/VirtualHost&amp;gt;


&amp;lt;VirtualHost *&amp;gt;
        ServerName      name4.tull.net
        DocumentRoot    var/www/
&amp;lt;/VirtualHost&amp;gt;
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt; The errors are: &lt;pre style="border-style:solid; background-color: #F0E0E0"&gt;
[Wed Jul 16 10:24:47 2008] [warn] _default_ VirtualHost overlap on port 80, the first has precedence
[Wed Jul 16 10:24:47 2008] [warn] _default_ VirtualHost overlap on port 80, the first has precedence
[Wed Jul 16 10:24:47 2008] [warn] NameVirtualHost *:80 has no VirtualHosts
VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
*:80                   name1.tull.net (/etc/apache2/strip.conf:4)
*:80                   name2.tull.net (/etc/apache2/strip.conf:10)
*:80                   name4.tull.net (/etc/apache2/strip.conf:16)
*:*                    name4.tull.net (/etc/apache2/strip.conf:21)
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt; In this configuration there &lt;b&gt;are&lt;/b&gt; corresponding "VirtualHost *:80" definitions. What's confusing apache2 is the last definition which is "VirtualHost *", and it's reporting a warning with the wrong directive (NameVirtualHost). &lt;/p&gt;
&lt;p&gt; Furthermore, the "VirtualHost overlap on port 80" warnings are being generated for &lt;u&gt;correct&lt;/u&gt; directives, and no warning about the incorrect directive. &lt;/p&gt;
&lt;p&gt; So the fix, at least for this scenario, is to ensure that all "VirtualHost" directives use the same value as specified in "NameVirtualHost". &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Update 2008-07-18 ...&lt;/b&gt; also you don't want to have two "NameVirtualHost *:80" directives in the configuration. Multiple directives with the same arguments are not treated as one! &lt;/p&gt;
	</description>
</item>

<item>
	<title>Scan and update ssh keys</title>
	<description>
&lt;p&gt; Due to the recently exposed ssh key generation vulnerability, many ssh keys may need to be deleted and recreated. This tool may help with that. &lt;/p&gt;
&lt;p&gt; What it does is find all the ssh keys existing on several hosts and where those keys appear in .ssh/authorized_keys files. It collates the results from all hosts and writes a directed graph for the 'graphviz' tool, which helps to visualise which keys are providing access to which users. &lt;/p&gt;
&lt;p&gt; The scan tool works by connecting to each specified host using ssh and executing a host script. The host script examines the user's .ssh directory and sends a report to STDOUT, which is received by the scan tool. The host script can also iterate through /etc/passwd and examine every user's .ssh directory. &lt;/p&gt;
&lt;p&gt; Use graphviz to visualise the graph. How to use: firstly make a file 'host-list' of all hosts you have access to, one line per hostname. Include any hosts you have root access to just as the hostname, and if you have only user access, use "user@hostname". You need to run the scan tool from a place which can ssh to all these hosts -- as root for all hostnames listed in your 'host-list' file which are not qualified with a username. &lt;/p&gt;
&lt;pre&gt;
scan-ssh-keys.pl $(cat host-list) &amp;gt; output.dot
dot -Txlib output.dot
&lt;/pre&gt;
&lt;p&gt; Use the mouse wheel to zoom in/out of the graph image. Use the mouse middle button to pan the image. You can also use 'dot' to write various output files such as JPEG or SVG. &lt;/p&gt;
&lt;p&gt; Here is a sample graph produced by the scan tool. The graph resolution is deliberately reduced (to make the node labels unreadable) for security reasons. Also my full ssh key graph is somewhat larger than this :-) &lt;/p&gt;
&lt;img src="{URI file=Misc/Pics/sample-ssh-scan.jpg}" width="100%" /&gt;
&lt;p&gt; Later on I expect to enhance the scan tool to assist with adding and deleting ssh keys. &lt;/p&gt;
&lt;p&gt; To download from my Mercurial repository, see: &lt;a href="http://www.nick-andrew.net/hg/nick-src-regen-ssh-keys"&gt;nick-src-regen-ssh-keys&lt;/a&gt;. &lt;/p&gt;
	</description>
</item>

<item>
	<title>ars technica on Windows programming</title>
	<description>
&lt;p&gt; In &lt;a href="http://arstechnica.com/articles/culture/microsoft-learn-from-apple-II.ars/3"&gt; From Win32 to Cocoa: a Windows user's conversion to Mac OS X—Part II&lt;/a&gt;, Peter Bright writes: &lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt; So Windows is just a disaster to write programs for. It's miserable. [...] &lt;/p&gt;&lt;p&gt; The code isn't just inconsistent and ugly on the outside; it's that way on the inside, too. There's a lot of software for Windows, a lot of business-critical software, that's not maintained any more. And that software is usually buggy. It passes bad parameters to API calls, uses memory that it has released, assumes that files live in particular hardcoded locations, all sorts of things that it shouldn't do. If the OS changes underneath—to prohibit the reuse of freed memory, to more aggressively validate parameters, to stick more closely to the documentation without making extra assumptions or causing special side-effects—then these programs break. &lt;/p&gt;&lt;p&gt; So Windows has all sorts of bits of code which are there to provide compatibility with these broken applications. It's hard for MS to maintain and fix this code, because it means the code no longer does what it's documented to do; it does that plus some other stuff. It's hard to test, because there's no knowing exactly what broken things programs are going to try to do. And it makes things more expensive; Microsoft has all sorts of special behaviours it needs to preserve. This means that not only can it not make the API better—it can't even easily make the API's implementation better. It's all too fragile. &lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt; It's nice to see confirmation of this from an experienced Windows programmer. Since I don't program for Windows at all, my opinions are based on what I see and read about Windows, rather than coal face development experience. The take-home message from this article is that mediocrity rules the Windows development ecosystem; although there are no doubt many developers who write high quality Windows applications, there are also many who do not, and Microsoft supports the latter to the detriment of the former. &lt;/p&gt;
	</description>
</item>

<item>
	<title>Distributed SCM</title>
	<description>
&lt;p&gt; I've become a recent convert to distributed SCM systems, particularly &lt;a href="http://www.selenic.com/mercurial/"&gt;Mercurial&lt;/a&gt; and &lt;a href="http://git.or.cz/"&gt;Git&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt; Use of a distributed SCM is a much more sensible way to release open source software than the traditional tarfile, or even having a public CVS or SVN repository. In particular: &lt;ul&gt;&lt;li&gt;It makes it easy for users of the software to feed back their local changes, which encourages more participation and development of the code &lt;/li&gt;&lt;li&gt;It helps users maintain their own local changes in an SCM &lt;/li&gt;&lt;li&gt;It helps users upgrade to newer releases (without wiping out their local changes, for instance). &lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;
&lt;p&gt; Having a public CVS or SVN repository solves only the problem of giving users quick access to the latest version of the software. CVS and SVN don't help with feedback or maintenance of local changes. They can help with upgrades - but it's of little practical benefit when local changes can't be committed into the repository. &lt;/p&gt;
&lt;p&gt; I was in the process of converting my CVS repositories to SVN (it takes a long time) when I discovered the virtues of Distributed SCMs. I'm using both Git and Mercurial. Git is perhaps more powerful but Mercurial is more user-friendly. So I have halted all conversion to SVN and I'll be converting remaining repositories to Mercurial. I'll be converting most of my SVN repositories over to Mercurial too. Ultimately the only code/data remaining in SVN will be that which I particularly need to be centralised (it might end up being none at all). &lt;/p&gt;
&lt;p&gt; I have started to put some repositories of my public source code online already. The full list is available at: &lt;a href="http://www.nick-andrew.net/hg"&gt;http://www.nick-andrew.net/hg&lt;/a&gt; and individual repositories which are currently online are: &lt;/p&gt;
&lt;table bgcolor="#c0f8f8" border="1" cellpadding="2" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="/hg/develooper.com-src-qpsmtpd"&gt;develooper.com-src-qpsmtpd&lt;/a&gt;&lt;/td&gt;&lt;td&gt; I use qpsmtpd on the mail servers here primarily for spam entrapment; for example to refuse emails addressed to nonexistent users at my domains. I get quite a lot of spam due to my long history with USENET. This repository contains the qpsmptd 0.26, 0.32 and 0.40 releases as downloaded from tarballs plus my local changes (mostly against 0.26 so far). &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="/hg/nick-pub-src-minix-ar"&gt;nick-pub-src-minix-ar&lt;/a&gt;&lt;/td&gt;&lt;td&gt; To extract my old stuff (circa 1990) successfully, I need a V7-compatible 'ar' program. This is the original 'ar' program from Minix 1.x, modified to work on a modern machine (32-bit, with prototypes, etc). &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="/hg/nick-src-apt-cacher"&gt;nick-src-apt-cacher&lt;/a&gt;&lt;/td&gt;&lt;td&gt; This is the original apt-cacher program (versions 0.1 through 0.4) before being picked up by Jon Oxer and packaged into Debian. Don't use this code; the repository is here merely for historical purposes. &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="/hg/nick-src-backup-cdr"&gt;nick-src-backup-cdr&lt;/a&gt;&lt;/td&gt;&lt;td&gt; I wrote this system to do encrypted incremental backups of modified files - first to CDR, then to DVD. I need something to do size limited incremental backups since the total amount of backup is many times the capacity of a DVD. This system regulates the quantity of backup per day. &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="/hg/nick-src-direct"&gt;nick-src-direct&lt;/a&gt;&lt;/td&gt;&lt;td&gt; This is a perl implementation of the 'direct' program I used in the TRS-80 days, to pack several files together into 2 (!) structured files, a 'DIR' and a 'DAT' file. Think of it as like a zipfile without any compression. Anyway when I restored my old TRS-80 software I needed to extract data from some of these structured file pairs so I wrote it in perl - a language which was not available back in the mid-1980s. It was trivial to do in perl, heh. &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="/hg/nick-src-distributed-filesystem"&gt;nick-src-distributed-filesystem&lt;/a&gt;&lt;/td&gt;&lt;td&gt; This repository contains my 2003 ruminations on distributed filesystems. Useful if nothing else for the pointers to various designs people may have implemented. &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="/hg/nick-src-incremental-tar"&gt;nick-src-incremental-tar&lt;/a&gt;&lt;/td&gt;&lt;td&gt; This C program replicates the function of Gnu TAR and optionally compresses its output on the fly. The point is that you can feed it with a (possibly infinite) list of files to be archived, and an output size limit, and it will ensure that its output size does not exceed the limit. It is useful for incremental backup - you give it a list of all your modified files, and a size (say 699 MBytes) and it will cram as many of those files in compressed form as can fit in 699 megs. &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="/hg/nick-src-misc-https-proxy"&gt;nick-src-misc-https-proxy&lt;/a&gt;&lt;/td&gt;&lt;td&gt; This perl program listens on localhost port 80 and when it receives a connection, makes an SSL connection to a specified server on port 443 and forwards the data in both directions. This allows logging or debugging of an HTTPS data stream by using HTTP at the browser end. &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="/hg/nick-src-misc-logrun"&gt;nick-src-misc-logrun&lt;/a&gt;&lt;/td&gt;&lt;td&gt; This cute little program reopens STDOUT and STDERR to files in a logging directory and runs the program. If the program exits with a non-zero code, the log files are moved to a 'bad' directory, otherwise they are moved to an 'ok' directory. &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="/hg/nick-src-misc-showdns"&gt;nick-src-misc-showdns&lt;/a&gt;&lt;/td&gt;&lt;td&gt; This program does several DNS lookups on a specified domain name, and possibly filters the output. The aim is to quickly find the nameservers, web servers etc for a domain name and particularly to find those which are _not_ served by a specified nameserver. &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="/hg/nick-src-trs80"&gt;nick-src-trs80&lt;/a&gt;&lt;/td&gt;&lt;td&gt; This is all my old TRS-80 source code in a single repository, rather than having to download many tarfiles. Again, it's for historical purposes. Unless you like Z80 assembler a lot. &lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;br /&gt;
	</description>
</item>

<item>
	<title>Linux vsplice export fix for OpenVZ</title>
	<description>
&lt;p&gt; Here's a patch which I believe solves the recent linux local root problems, for the latest stable OpenVZ kernel (2.6.18-028stab053). &lt;/p&gt;
&lt;div style="text-align: center; margin-bottom: 1em"&gt;&lt;a href="/Patches/20080213-openvz-2.6.18-stab053-security.patch"&gt; 20080213-openvz-2.6.18-stab053-security.patch &lt;/a&gt;&lt;/div&gt;
	</description>
</item>

<item>
	<title>OpenVZ virtualisation</title>
	<description>
&lt;p&gt; To run linux guests I can highly recommend OpenVZ. It's a container system - you run only the host kernel which is modified to implement isolation between containers and each other, and the host. Processes in the containers run as processes on the host, with a container-specific root directory. &lt;/p&gt;
&lt;p&gt; The upshot of all this is that overhead is almost zero; each guest runs at almost native speed. There are various other benefits too, such as: &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;The guest root filesystem is a directory on the host, so the host has full visibility to the guest files. It isn't necessary to preallocate space to each guest, so there's no wasted space and each guest can grow dynamically.&lt;/li&gt;&lt;li&gt;Resource utilisation limits are enforced and can be modified on the fly.&lt;/li&gt;&lt;li&gt;Guests can be minimal because they don't have to support hardware. A typical guest, before installing additional software, may be running only these processes: init, syslogd, sshd and cron. 4 processes - and you don't even need cron.&lt;/li&gt;&lt;li&gt;Networking is very easy to get going (unlike user-mode-linux).&lt;/li&gt;&lt;li&gt;Using templates, you can have a new guest installed and running in under 2 minutes.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt; There are some caveats though: &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;The host kernel is modified in many places. The latest stable patch is over 4M.&lt;/li&gt;&lt;li&gt;Not every linux kernel version is supported. The latest stable, supported patch is against 2.6.18 or you can use a development level patch against 2.6.22&lt;/li&gt;&lt;li&gt;You can see all the guest processes on the host; it can be tricky to know which guest a given process is running on.&lt;/li&gt;&lt;li&gt;Some kernel functions are restricted, such as kernel-space NFS server (use the userspace one instead).&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt; Overall OpenVZ is very stable and functional. I haven't had any kernel crashes related to OpenVZ. I would like them to support newer kernels - specifically 2.6.23 and above, since there are features in 2.6.23 that I want to use. But the patch is quite extensive and so I can't really blame them for picking a version and sticking with it for a long time. OpenVZ patch developers have contributed many security and stability fixes back to Linus. One day, much of OpenVZ will be integrated into the mainline kernel. Already 2.6.24 supports PID namespaces (in which process IDs are unique to each guest, not the host) and further OpenVZ functionality will move into the mainline kernel over time. &lt;/p&gt;
	</description>
</item>

<item>
	<title>The bank, a law unto itself</title>
	<description>
&lt;p&gt; Importing my bank account history today from a CSV file exported by the bank's website, as I do every month, and the import failed. The reason was that the bank changed the dates on several transactions made from December 2007 to as early as April 2006. The dates were changed from 17th or 16th to 15th in each case. &lt;/p&gt;
&lt;p&gt; What is it about banks that they can arbitrarily change transaction dates, even 12+ months after the transaction occurs? This could have been legally problematic for me, say if I had to transfer money by a certain date (and did that) and sometime later the bank's "official" record of the transaction has changed. &lt;/p&gt;
&lt;p&gt; What has happened is that my financial records now no longer agree with those of the bank, for no good reason, and I have to adjust mine accordingly, or else there will forever be a discrepancy. &lt;/p&gt;
	</description>
</item>

<item>
	<title>LifeView TV Walker Twin</title>
	<description>
&lt;img src="{URI file=Misc/Pics/pic-20070508-205708-2.jpg}" width="100%" /&gt;
&lt;p&gt; Firmware for the LifeView TV Walker Twin (DVB-T USB digital TV receiver) can be found here at &lt;a href="LifeView/dvb-usb-tvwalkert.fw"&gt;dvb-usb-tvwalkert.fw&lt;/a&gt;. Copy the file (without renaming it) into /usr/lib/hotplug/firmware/. This is needed to make the device work in linux. &lt;/p&gt;
&lt;p&gt; I'm working on a driver and it will be merged into the linux-dvb project repository in a few days. &lt;/p&gt;
&lt;br clear="all" /&gt;
	</description>
</item>

<item>
	<title>pwned again!</title>
	<description>
&lt;p&gt; AA 85 6A 1B A8 14 AB 99 FF DE BA 6A EF BE 1C 04 &lt;/p&gt;
	</description>
</item>

<item>
	<title>raid1 superblock version</title>
	<description>
&lt;p&gt; It seems that the software raid1 superblock version 1.0 is not fully supported by linux. I created two raid1 arrays, one with a version 0.90 superblock and the other with version 1.0. During kernel boot, the md autoconfiguration found the 0.90 superblock array, but said it could not find a superblock for the other array. &lt;/p&gt;
&lt;p&gt; Furthermore, LILO refuses to install onto a raid1 array with a version 1.0 superblock. As soon as I converted it to version 0.90, LILO worked fine. &lt;/p&gt;
&lt;p&gt; Lastly, the manpage for &lt;b&gt;pivot_root(2)&lt;/b&gt; fails to note that the system call cannot be used to move away an initramfs. I dug into the kernel source code and it's clearly noted in a comment above the function definition. &lt;/p&gt;
	</description>
</item>

<item>
	<title>2007-02-14</title>
	<description>
&lt;p&gt; 09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0 &lt;/p&gt;
	</description>
</item>

<item>
	<title>A tiny web template tool</title>
	<description>
&lt;p&gt; It took me just one hour to write a tiny web template tool in perl which is now driving this website. The news items are now included using the following tag: &lt;/p&gt;
&lt;div style="text-align: center; background: #e0d080; margin-bottom: 1em"&gt; {News dir=data/news limit=10} &lt;/div&gt;
&lt;p&gt; This instantiates the 'News' module and runs it with the supplied arguments. &lt;/p&gt;
&lt;p&gt; The key to getting it going so quickly was that it processes the same SHTML files which I used to use to give the site a consistent layout. It parses the '#include' directives and runs itself recursively on the specified filename. Thus, I was able to move the site to the templating CGI script without changing any of the content files. I then added the tag parser to instantiate modules from a "Plugins" directory, and wrote a &lt;code&gt;News&lt;/code&gt; module to read a sequence of news items from individual files in a directory. Finally I split the single news.html file into one file per news item. &lt;/p&gt;
	</description>
</item>

<item>
	<title>Euphemisms for share price movements</title>
	<description>
&lt;p&gt; In &lt;a href="http://theaustralian.news.com.au/story/0,20867,20721842-1702,00.html"&gt; Market catches breath after record pace&lt;/a&gt; I can see a huge variety of euphemisms for share price rises and falls. &lt;/p&gt;
&lt;p&gt; Let's categorise them ... &lt;/p&gt;
&lt;b&gt;Falls&lt;/b&gt;
&lt;ol&gt;&lt;li&gt;fell x 2&lt;/li&gt;&lt;li&gt;dropped&lt;/li&gt;&lt;li&gt;reversed x 3&lt;/li&gt;&lt;li&gt;dumped x 2&lt;/li&gt;&lt;li&gt;gave away&lt;/li&gt;&lt;li&gt;backtracked&lt;/li&gt;&lt;li&gt;sagged&lt;/li&gt;&lt;li&gt;eased&lt;/li&gt;&lt;li&gt;off&lt;/li&gt;&lt;li&gt;descended&lt;/li&gt;&lt;li&gt;poorer&lt;/li&gt;&lt;li&gt;stepped back&lt;/li&gt;&lt;/ol&gt;
&lt;b&gt;Rises&lt;/b&gt;
&lt;ol&gt;&lt;li&gt;jumped x 2&lt;/li&gt;&lt;li&gt;rose x 2&lt;/li&gt;&lt;li&gt;firmed&lt;/li&gt;&lt;li&gt;heavier&lt;/li&gt;&lt;li&gt;surged&lt;/li&gt;&lt;li&gt;up&lt;/li&gt;&lt;/ol&gt;
&lt;b&gt;Unchanged&lt;/b&gt;
&lt;ol&gt;&lt;li&gt;steady x 2&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt; That's quite a swag of terms. Each one holds some connotations - like "reversed" would imply that the stock price had gone down soon after a rise. But ultimately aren't these words all talking about the same thing - the share price dropped? I wonder if there's any meaning in those words or if the author simply has a list of synonyms and chooses them at random, for variety. &lt;/p&gt;
&lt;p&gt; The whole article could have been written much more compactly with a 4-column table: the share name, the closing price, the number of cents up or down, and the surmised reason for the change, if any. &lt;/p&gt;
	</description>
</item>

<item>
	<title>Cleaning up the inbox</title>
	<description>
&lt;p&gt; I started refiling my inbox. It is too full! I've moved most of them to vertical files in my desk drawer, neatly labeled. My goal is to eliminate paper from my desk. &lt;/p&gt;
 Related links: &lt;ul&gt;&lt;li&gt;&lt;a href="http://www.davidbrunelle.com/2006/08/24/at-least-im-trying-to-keep-my-desk-organized/"&gt;At Least I'm Trying to Keep my Desk Organized&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.lifeclever.com/2006/08/21/10-tips-for-keeping-your-desk-clean-and-tidy/"&gt;10 tips for keeping your desk clean and tidy&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.43folders.com/2006/08/23/tidy-desk/"&gt;Life Clever: Secrets of the Tidy Desk&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>A search engine, at last</title>
	<description>
&lt;p&gt; I added a search box to the left-hand column. The database is updated nightly. It uses &lt;a href="http://www.htdig.org"&gt;ht://Dig&lt;/a&gt; as the engine. &lt;a href="http://www.stallman.org/"&gt;Richard Stallman's homepage&lt;/a&gt; provided the final motivation. &lt;/p&gt;
	</description>
</item>

<item>
	<title>On the robustness of DVDs</title>
	<description>
&lt;p&gt; I burned a bad DVD today (used wrong mkisofs options and so didn't get the necessary Rock Ridge extensions). So after re-burning a correct one I set about destroying the data on the old one. It's sensitive and encrypted data. &lt;/p&gt;
&lt;p&gt; I scored the top of the DVD several times with a kitchen knife. In the past that has destroyed some CDRs because it removes the reflective layer needed for the reader to get at the data. This process didn't harm this DVD; all the files are still readable with no I/O errors. Even though I can see through the scratches. &lt;/p&gt;
&lt;p&gt; In Stage 2 I rubbed steel wool all over the underside. That wasn't sufficient. I can still read some files without errors, although it is definitely unable to read the bigger files. &lt;/p&gt;
&lt;p&gt; In Stage 3 I tried to snap the DVD into two pieces. Unfortunately it is very flexible. I bent the surface 180 degrees and it didn't snap, in fact it looks totally unscathed by that maltreatment. Next I held it over an open flame, with only minimal damage apparent. It seems today's DVDs are &lt;b&gt;virtually indestructible&lt;/b&gt;. &lt;/p&gt;
	</description>
</item>

<item>
	<title>2006-01-28</title>
	<description>
&lt;p&gt; I modified the &lt;a href="http://www.nick-andrew.net/projects/apt-cacher/"&gt;apt-cacher project&lt;/a&gt; page to reflect the current situation with respect to apt-cacher (i.e. in that I no longer maintain it and it's part of Debian proper now). &lt;/p&gt;
	</description>
</item>

<item>
	<title>2005-12-24</title>
	<description>
&lt;ul&gt;&lt;li&gt;I know waiting over 2 years between updates is not good web karma. Anyway I had an old Molymerx software catalogue in my cupboard. I plan to put all the old TRS-80 stuff online sometime, and I wanted to clear some space in the cupboard. So I have scanned it in at 200 dpi for anybody interested. Here's the link: &lt;a href="/TRS-80/Molymerx-Catalogue/"&gt;Molymerx Catalogue Dec 1982&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Merry Xmas to all!&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2003-07-14</title>
	<description>
&lt;ul&gt;&lt;li&gt;I have created the &lt;a href="/System80/Gallery/512x384/index.html"&gt;System-80 Gallery&lt;/a&gt; with some pictures of my first computer. Sorry, no descriptions are online (it would take me much longer to write descriptions than to simply place the photos online).&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2003-02-17</title>
	<description>
&lt;ul&gt;&lt;li&gt;Does anybody have a scanner for microfiche? I have about 50 sheets of microfiche containing a small amount of source code I wish to preserve. I tried scanning them, even at 2400dpi the characters are little black blobs. Some optical magnification is obviously necessary prior to scanning.&lt;/li&gt;&lt;li&gt;It appears that with Tel$tra's February 11th press release about supporting ICQ over SMS, that they have blocked SMS to Tel$tra numbers except to subscribers to this "new service", who pay their outrageous 25c charge per SMS received. My mobile is on Vodafone because it saves me $25 to $30 per month compared to T$, who were screwing me blind for years with their mobile rates. Vodafone and Optus numbers are still able to receive SMS from ICQ. Except that when I gave T$ the finger, I kept the T$ number and ported it to Voda. Therefore, my mobile can no longer receive SMS from ICQ. T$ continues to screw me, even though I'm no longer a customer!&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-12-08</title>
	<description>
&lt;ul&gt;&lt;li&gt;Added a mini-rant on ethical Internet Advertising.&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-12-01</title>
	<description>
&lt;ul&gt;&lt;li&gt;I got an email from somebody in a position of some responsibility, asking that one of my projects be removed from my website. Can you guess which? Naturally I refused. &lt;b&gt;Freedom 1, Self-censorship 0&lt;/b&gt;.&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-11-11</title>
	<description>
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;I added a new project, &lt;i&gt;logrun&lt;/i&gt;. It's a script I have used for years to reduce the amount of unnecessary output from cron jobs which ends up in my mailbox. Logrun keeps the output unless the job failed (in which case the output is sent to STDOUT or emailed to any desired email address). &lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-11-10</title>
	<description>
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;I added a new project, &lt;i&gt;math-trainer&lt;/i&gt;. It's just a trivial little CGI script for a child to use to practice answering random math questions. It shows a (random) cute image on each correct answer. &lt;/li&gt;&lt;li&gt;I wrote a document, "Big Server" which describes an architecture I designed be a little scalable and provide some protection against disk failure, yet still be cheap to implement. It's in the new "Technical" section on the links part on the left. &lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-11-09</title>
	<description>
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;I added a "donate" button on the left hand side of each page. This uses PayPal. If some of my source code helped you out of a tough spot, please feel free to send some appreciation. Also I wanted to do something with PayPal's e-commerce interface for proper business transactions, but haven't had time to look at it yet (the donate button was only 5 minutes work copied from somebody else's website). &lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-10-05</title>
	<description>
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;My main home server (which also runs my screen and keyboard) died (disk failure). I took that opportunity to complete the installation of my &lt;b&gt;new&lt;/b&gt; main server, which is much more powerful and uses RAID-1 (mirroring) for redundancy of data storage. &lt;/li&gt;&lt;li&gt;Note for John ... see &lt;a href="http://members.iinet.net.au/~oscar2125/"&gt;oscar2125&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-08-30</title>
	<description>
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;I added a new project, &lt;i&gt;mp3cd-tools&lt;/i&gt;, which I wrote to put a lot of my MP3 albums onto CD-R in an efficient and painless way. &lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-08-04</title>
	<description>
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;I released an update to the Ausadmin software today. It fixes a lot of minor issues regarding following the process of newsgroup creation. The next update will be even better.&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-07-15</title>
	<description>
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;I got really sick with the flu which was going around. It put me down for about a week!&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-06-29</title>
	<description>
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;I made another snapshot release of the ausadmin software from today and put it online. This has some bugs fixed re proposal state handling.&lt;/li&gt;&lt;li&gt;I finished placing all my TRS-80 source code online. By my count there are 226 programs in the archive, not including patches to other peoples' code nor multiple similar versions of the same thing.&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-06-26</title>
	<description>
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;I've been diagnosed with some kind of lung allergy causing bronchitis. I need to use asthma medication (inhaled) for the next 6 weeks, and then according to the Doc that will be the end of it. Cross fingers!&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-06-23</title>
	<description>
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;I'm slowly making a TRS-80 package for each category and then putting it online.&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-06-18</title>
	<description>
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;A post I made to &lt;a href="news:comp.sys.tandy"&gt;comp.sys.tandy&lt;/a&gt; (describing a potential development project for Tim Mann's xtrs TRS-80 emulator) has inspired George Phillips to start his own project, &lt;a href="http://members.shaw.ca/gp2000/trsdisk/trsdisk.html"&gt;trsdisk&lt;/a&gt;. Trsdisk builds a "virtual TRS-80 disk image" for use in an emulator (i.e. xtrs) based on the content of files in the host's directory. In other words, the emulated TRS-80 system can access native files. George points out that his project is still experimental. I am hoping that I get the chance to improve on it sometime.&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-06-13</title>
	<description>
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;I've been systematically going through my recovered TRS-80 files looking for source code, categorising and adding it to CVS revision management. There were over 200 programs, last time I counted. Next step is to clean up the categories and then package up the sources for release on this website. I will probably be grouping similar programs for release efficiency, so might end up with 30 or so packages.&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-05-31</title>
	<description>
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Added the first of the TRS-80 packages, as a test.&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

<item>
	<title>2002-05-30</title>
	<description>
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Updated the calendar program so it works properly with Evolution. See &lt;a href="/projects/sms-notify/"&gt;projects/sms-notify&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Added aunic-modify project, some cool code I wrote to do bulk updates of the database at &lt;a href="http://www.aunic.net/"&gt;www.aunic.net&lt;/a&gt;. See &lt;a href="/projects/aunic-modify/"&gt;projects/aunic-modify&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Added links to new apt-cacher website. See &lt;a href="/projects/apt-cacher/"&gt;projects/apt-cacher&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Somehow the wav-fixer project got lost. It is replaced now.&lt;/li&gt;&lt;li&gt;Added "Miscellaneous Project" and moved misc sources into it. See &lt;a href="/projects/misc/"&gt;projects/misc&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;
	</description>
</item>

</channel>
</rss>
