Recent changes to this wiki:

update FML version reference
diff --git a/minecraft/craftallthethings.mdwn b/minecraft/craftallthethings.mdwn
index c2d4479..cf63211 100644
--- a/minecraft/craftallthethings.mdwn
+++ b/minecraft/craftallthethings.mdwn
@@ -48,7 +48,7 @@ but can identify items by name rather than numeric ID
   <http://files.minecraftforge.net/fml/>, or Minecraft Forge
   from <http://files.minecraftforge.net/>,
   according to the [Minecraft Forge installation instructions][].
-  I tested with [FML][] version 6.2.35.723 and [Forge][] version 9.10.0.804.
+  I tested with [FML][] version 6.4.3.755.
 
 * Put `minecraft-1.6.4-craftallthethings-0.8.zip` in
   `.minecraft/mods/1.6.4`.

update CraftAllTheThings to 0.8
diff --git a/minecraft/craftallthethings.mdwn b/minecraft/craftallthethings.mdwn
index b69ce30..c2d4479 100644
--- a/minecraft/craftallthethings.mdwn
+++ b/minecraft/craftallthethings.mdwn
@@ -3,7 +3,7 @@
 Craft All the Things is a [Minecraft][] mod to add whatever crafting
 recipes you want.
 
-It's compatible with Minecraft 1.6.2 + [Forge Mod Loader (FML)][FML] or
+It's compatible with Minecraft 1.6.4 + [Forge Mod Loader (FML)][FML] or
 [Minecraft Forge][], in single-player and multiplayer (in multiplayer,
 the server admin configures the additional crafting recipes).
 
@@ -32,7 +32,7 @@ but can identify items by name rather than numeric ID
 [[!if test="sourcepage(*)" then="""
 ## Download
 
-* [[minecraft-1.6.2-craftallthethings-0.7.zip]]
+* [[minecraft-1.6.4-craftallthethings-0.8.zip]]
 """]]
 
 ## Usage
@@ -50,8 +50,8 @@ but can identify items by name rather than numeric ID
   according to the [Minecraft Forge installation instructions][].
   I tested with [FML][] version 6.2.35.723 and [Forge][] version 9.10.0.804.
 
-* Put `minecraft-1.6.2-craftallthethings-0.7.zip` in
-  `.minecraft/mods/1.6.2`.
+* Put `minecraft-1.6.4-craftallthethings-0.8.zip` in
+  `.minecraft/mods/1.6.4`.
 
 * Put recipes in `.minecraft/config/craftallthethings/*.json`.
 
@@ -225,6 +225,10 @@ internal name or alias, such as tile.dirt or orange_wool:
 
 ## Release history
 
+* 0.8:
+
+  * update for Minecraft 1.6.4
+
 * 0.7:
 
   * only reload languages, not all resources, avoiding a bug where sound

point to source code etc.
diff --git a/minecraft/craftallthethings.mdwn b/minecraft/craftallthethings.mdwn
index cf7545f..b69ce30 100644
--- a/minecraft/craftallthethings.mdwn
+++ b/minecraft/craftallthethings.mdwn
@@ -217,6 +217,11 @@ internal name or alias, such as tile.dirt or orange_wool:
 * Author: Simon McVittie (smcv), <http://smcv.pseudorandom.co.uk/>
 * Website: <http://www.pseudorandom.co.uk/minecraft/craftallthethings/>
 * E-mail: webmaster @ that domain name
+* Source code (for developers/contributors):
+  `git clone git://git.pseudorandom.co.uk/git/minecraft/craftallthethings.git`
+  (or browse in
+  [gitweb](http://git.pseudorandom.co.uk/minecraft/craftallthethings.git/),
+  or extract the `.java` files from the zip file)
 
 ## Release history
 
@@ -258,4 +263,10 @@ This mod is open source under the
 (the same as the Forge Mod Loader), or at your option, any later version.
 See COPYING.txt in the zip file. There is no warranty, express or implied.
 
+If you release a fork of CraftAllTheThings, please change the name,
+contact details and Java package name.
+
+If you want to incorporate part or all of CraftAllTheThings into a mod
+under a non-LGPL license, please ask. I'll probably say "yes".
+
 [LGPL]: https://www.gnu.org/licenses/lgpl-2.1.html

craftallthethings 0.7
diff --git a/minecraft/craftallthethings.mdwn b/minecraft/craftallthethings.mdwn
index f639bbb..cf7545f 100644
--- a/minecraft/craftallthethings.mdwn
+++ b/minecraft/craftallthethings.mdwn
@@ -32,7 +32,7 @@ but can identify items by name rather than numeric ID
 [[!if test="sourcepage(*)" then="""
 ## Download
 
-* [[minecraft-1.6.2-craftallthethings-0.6.zip]]
+* [[minecraft-1.6.2-craftallthethings-0.7.zip]]
 """]]
 
 ## Usage
@@ -50,7 +50,7 @@ but can identify items by name rather than numeric ID
   according to the [Minecraft Forge installation instructions][].
   I tested with [FML][] version 6.2.35.723 and [Forge][] version 9.10.0.804.
 
-* Put `minecraft-1.6.2-craftallthethings-0.6.zip` in
+* Put `minecraft-1.6.2-craftallthethings-0.7.zip` in
   `.minecraft/mods/1.6.2`.
 
 * Put recipes in `.minecraft/config/craftallthethings/*.json`.
@@ -145,6 +145,10 @@ normally write that recipe more like this:
         ]
     }
 
+I deliberately don't use the localized names in other languages (including
+my own): the server always runs in US English, and by sticking to the US
+English names, recipes written anywhere can be used anywhere.
+
 In the ingredients (the shapeless and rows bits), you can also say "any X" to
 accept any of several "damage values" for a block (dye colours, wood types
 and so on). For instance, here's the vanilla recipe for beds:
@@ -192,9 +196,21 @@ and you can also define your own aliases. Here are some example recipes
 
 ### The /givebyname command
 
-Players with "op" privileges can use the /givebyname command. It's just
+Players with "op" privileges can use the new `/givebyname` command. It's just
 like the /give command, but the second argument (item) is an item's
-internal name or alias, such as tile.dirt or orange_wool.
+internal name or alias, such as tile.dirt or orange_wool:
+
+    # give smcv a dirt block
+    # equivalent to /give smcv 3
+    /givebyname smcv tile.dirt
+
+    # give smcv a stack of orange wool
+    # equivalent to /give smcv 35 64 1
+    /givebyname smcv orange_wool 64
+
+    # give smcv a stack of red wool (wool with metadata/damage value 14 is red)
+    # equivalent to /give smcv 35 64 14
+    /givebyname smcv orange_wool 64 14
 
 ## Contact
 
@@ -202,6 +218,29 @@ internal name or alias, such as tile.dirt or orange_wool.
 * Website: <http://www.pseudorandom.co.uk/minecraft/craftallthethings/>
 * E-mail: webmaster @ that domain name
 
+## Release history
+
+* 0.7:
+
+  * only reload languages, not all resources, avoiding a bug where sound
+    gets disabled
+
+* 0.6:
+
+  * special-case metadata for spawn eggs
+  * add example recipes for mossy cobblestone and chiselled stone bricks
+  * fix default alias for oak stairs
+  * add more default aliases
+  * avoid a null pointer exception if an alias doesn't point to a valid item
+  * generate a more informative reference.txt
+  * fix generation of stacks of more than one item with a specific
+    metadata/damage value
+  * add `/givebyname` command
+
+* 0.5:
+
+  * first public release
+
 ## Thanks
 
 * [Mojang][]

update to 0.6
diff --git a/minecraft/craftallthethings.mdwn b/minecraft/craftallthethings.mdwn
index b5a4b7d..f639bbb 100644
--- a/minecraft/craftallthethings.mdwn
+++ b/minecraft/craftallthethings.mdwn
@@ -18,6 +18,10 @@ item names from Minecraft (the internal names and the US English
 translations), so it should hopefully support named blocks from mods
 automatically.
 
+It also adds a /givebyname command, which works just like /give,
+but can identify items by name rather than numeric ID
+(e.g. "/givebyname smcv black_wool 42" would give me 42 black wool).
+
 [Minecraft]: https://minecraft.net/
 [FML]: http://www.minecraftforge.net/forum/
 [Forge Mod Loader]: http://www.minecraftforge.net/forum/
@@ -28,10 +32,12 @@ automatically.
 [[!if test="sourcepage(*)" then="""
 ## Download
 
-* [[minecraft-1.6.2-craftallthethings-0.5.zip]]
+* [[minecraft-1.6.2-craftallthethings-0.6.zip]]
 """]]
 
-## Single-player
+## Usage
+
+### Single-player
 
 * Locate your `.minecraft` folder. On Windows it's `%appdata%\.minecraft`,
   on Linux it's `~/.minecraft` and on Mac it's
@@ -44,23 +50,14 @@ automatically.
   according to the [Minecraft Forge installation instructions][].
   I tested with [FML][] version 6.2.35.723 and [Forge][] version 9.10.0.804.
 
-* Put `minecraft-1.6.2-craftallthethings-0.5.zip` in
+* Put `minecraft-1.6.2-craftallthethings-0.6.zip` in
   `.minecraft/mods/1.6.2`.
 
-* Run Minecraft with the mod loaded. It will generate
-  `.minecraft/config/craftallthethings/reference.txt`.
-
-* Extract the example recipes (`*.json`) from the `examples` directory
-  in the zip file.
-
-* Write whatever recipes you want, based on the examples and using
-  information from `reference.txt`.
-
-* Save your recipes as `.json` files in `.minecraft/config/craftallthethings`.
+* Put recipes in `.minecraft/config/craftallthethings/*.json`.
 
 [Minecraft Forge installation instructions]: http://www.minecraftforge.net/wiki/Installation/Universal
 
-## Multiplayer
+### Multiplayer
 
 * To share your single-player world with "share to LAN", do the same as
   for single-player.
@@ -84,12 +81,125 @@ the result square will stay blank, but if they click on the blank result
 square, crafting will take place according to the server's rules and they'll
 get the appropriate item anyway.
 
+### Writing recipes
+
+Whenever you start Minecraft with Craft All the Things enabled, it will
+write out `.minecraft/config/craftallthethings/reference.txt` containing
+information about the blocks in Minecraft.
+
+Recipes are [JSON][] files with, at a minimum, this structure:
+
+    {
+        "recipes": [
+            { ... }
+        ]
+    }
+
+Each recipe is a JSON "object" with at least the keys "product" and
+either "rows" or "shapeless". For instance, here's the equivalent of
+the vanilla Minecraft recipes for stone bricks (shaped) and red wool
+(shapeless):
+
+    {
+        "recipes": [
+            {
+                "product": "tile.stonebricksmooth",
+                "rows": [
+                    ["tile.stone", "tile.stone"],
+                    ["tile.stone", "tile.stone"]
+                ]
+            },
+            {
+                "product": "tile.cloth.red",
+                "shapeless": [
+                    "tile.cloth.white",
+                    "item.dyePowder.red"
+                ]
+            }
+        ]
+    }
+
+To make it easier to write recipes without using Minecraft's internal
+names for all the items and blocks, Craft All the Things sets up
+"aliases" for various items and blocks, based on their internal names,
+their USA English names, and some extras. Aliases are not case-sensitive,
+and spaces are considered to be equivalent to underscores. So, you'd
+normally write that recipe more like this:
+
+    {
+        "recipes": [
+            {
+                "product": "stone bricks",
+                "rows": [
+                    ["stone", "stone"],
+                    ["stone", "stone"]
+                ]
+            },
+            {
+                "product": "red wool",
+                "shapeless": [
+                    "white wool",
+                    "rose red"
+                ]
+            }
+        ]
+    }
+
+In the ingredients (the shapeless and rows bits), you can also say "any X" to
+accept any of several "damage values" for a block (dye colours, wood types
+and so on). For instance, here's the vanilla recipe for beds:
+
+    {
+        "recipes": [
+            {
+                "product": "bed",
+                "rows": [
+                    ["any wool", "any wool", "any wool"],
+                    ["any planks", "any planks", "any planks"]
+                ]
+            }
+        ]
+    }
+
+There's an alternative syntax for shaped recipes which is sometimes easier
+for repetitive ingredients:
+
+    {
+        "recipes": [
+            {
+                "product": "bed",
+                "rows": [
+                    "www",
+                    "ppp"
+                ],
+                "w": "any wool",
+                "p": "any planks"
+            }
+        ]
+    }
+
+and you can also define your own aliases. Here are some example recipes
+(which you can also get from the examples/ folder in the zip file):
+
+* [various examples to demonstrate the syntax](http://git.pseudorandom.co.uk/minecraft/craftallthethings.git/blob_plain?f=examples/examples.json)
+* [chainmail from iron and wool](http://git.pseudorandom.co.uk/minecraft/craftallthethings.git/blob_plain?f=examples/chainmail.json)
+* [horse armour](http://git.pseudorandom.co.uk/minecraft/craftallthethings.git/blob_plain?f=examples/horsearmour.json)
+* [name tags](http://git.pseudorandom.co.uk/minecraft/craftallthethings.git/blob_plain?f=examples/nametag.json)
+* [saddles](http://git.pseudorandom.co.uk/minecraft/craftallthethings.git/blob_plain?f=examples/saddle.json)
+* [special stone blocks](http://git.pseudorandom.co.uk/minecraft/craftallthethings.git/blob_plain?f=examples/stones.json)
+
+[JSON]: http://www.json.org/
+
+### The /givebyname command
+
+Players with "op" privileges can use the /givebyname command. It's just
+like the /give command, but the second argument (item) is an item's
+internal name or alias, such as tile.dirt or orange_wool.
+
 ## Contact
 
 * Author: Simon McVittie (smcv), <http://smcv.pseudorandom.co.uk/>
-[[!if test="sourcepage(*)" then="<!--"]]
 * Website: <http://www.pseudorandom.co.uk/minecraft/craftallthethings/>
-[[!if test="sourcepage(*)" then="-->"]]
 * E-mail: webmaster @ that domain name
 
 ## Thanks

Craft All the Things 0.5
diff --git a/minecraft/craftallthethings.mdwn b/minecraft/craftallthethings.mdwn
new file mode 100644
index 0000000..b5a4b7d
--- /dev/null
+++ b/minecraft/craftallthethings.mdwn
@@ -0,0 +1,112 @@
+[[!meta title="Craft All the Things"]]
+
+Craft All the Things is a [Minecraft][] mod to add whatever crafting
+recipes you want.
+
+It's compatible with Minecraft 1.6.2 + [Forge Mod Loader (FML)][FML] or
+[Minecraft Forge][], in single-player and multiplayer (in multiplayer,
+the server admin configures the additional crafting recipes).
+
+This mod does not add any crafting recipes on its own, but it makes
+it easier to add them, by writing text files. There are some ideas in
+the examples directory in the zip file, to get you started.
+
+It's basically a reimplementation of the [CustomRecipes][] mod by
+MightyPork and TheBoo. It does not contain any code from CustomRecipes,
+but the ideas are similar. Unlike CustomRecipes, it automatically reads
+item names from Minecraft (the internal names and the US English
+translations), so it should hopefully support named blocks from mods
+automatically.
+
+[Minecraft]: https://minecraft.net/
+[FML]: http://www.minecraftforge.net/forum/
+[Forge Mod Loader]: http://www.minecraftforge.net/forum/
+[Minecraft Forge]: http://www.minecraftforge.net/forum/
+[Forge]: http://www.minecraftforge.net/forum/
+[CustomRecipes]: http://minecraft.curseforge.com/mc-mods/custom-recipes/
+
+[[!if test="sourcepage(*)" then="""
+## Download
+
+* [[minecraft-1.6.2-craftallthethings-0.5.zip]]
+"""]]
+
+## Single-player
+
+* Locate your `.minecraft` folder. On Windows it's `%appdata%\.minecraft`,
+  on Linux it's `~/.minecraft` and on Mac it's
+  `~/Library/Application Support/minecraft`). If in doubt,
+  refer to [the Minecraft wiki](http://www.minecraftwiki.net/wiki/.minecraft).
+
+* Install either Forge Mod Loader from
+  <http://files.minecraftforge.net/fml/>, or Minecraft Forge
+  from <http://files.minecraftforge.net/>,
+  according to the [Minecraft Forge installation instructions][].
+  I tested with [FML][] version 6.2.35.723 and [Forge][] version 9.10.0.804.
+
+* Put `minecraft-1.6.2-craftallthethings-0.5.zip` in
+  `.minecraft/mods/1.6.2`.
+
+* Run Minecraft with the mod loaded. It will generate
+  `.minecraft/config/craftallthethings/reference.txt`.
+
+* Extract the example recipes (`*.json`) from the `examples` directory
+  in the zip file.
+
+* Write whatever recipes you want, based on the examples and using
+  information from `reference.txt`.
+
+* Save your recipes as `.json` files in `.minecraft/config/craftallthethings`.
+
+[Minecraft Forge installation instructions]: http://www.minecraftforge.net/wiki/Installation/Universal
+
+## Multiplayer
+
+* To share your single-player world with "share to LAN", do the same as
+  for single-player.
+
+* For a dedicated server, first install either [Minecraft Forge][] or
+  [Forge Mod Loader][] using the [Minecraft Forge installation instructions];
+  then do the same as for single-player, but instead of the
+  `.minecraft` folder, use the server's folder containing
+  `server.properties` and `world`.
+
+* All players who will join the server must install Forge Mod Loader
+  (with the same instructions as for single player).
+
+* It is recommended, but not essential, that players who will join
+  the server also install Craft All The Things, using the same instructions
+  as for single-player.
+
+Players who don't have Craft All The Things installed will still be able to
+join the server. When they craft something using the server's extra recipes,
+the result square will stay blank, but if they click on the blank result
+square, crafting will take place according to the server's rules and they'll
+get the appropriate item anyway.
+
+## Contact
+
+* Author: Simon McVittie (smcv), <http://smcv.pseudorandom.co.uk/>
+[[!if test="sourcepage(*)" then="<!--"]]
+* Website: <http://www.pseudorandom.co.uk/minecraft/craftallthethings/>
+[[!if test="sourcepage(*)" then="-->"]]
+* E-mail: webmaster @ that domain name
+
+## Thanks
+
+* [Mojang][]
+* the [FML][] team
+* the authors of [CustomRecipes][] (MightyPork, TheBoo)
+
+[Mojang]: https://mojang.com/
+
+## License
+
+Copyright © 2013 Simon McVittie. Some rights reserved.
+
+This mod is open source under the
+[GNU Lesser General Public License, v2.1][LGPL]
+(the same as the Forge Mod Loader), or at your option, any later version.
+See COPYING.txt in the zip file. There is no warranty, express or implied.
+
+[LGPL]: https://www.gnu.org/licenses/lgpl-2.1.html

update
diff --git a/2003/contact.html b/2003/contact.html
index 30cab02..b6f0e4c 100644
--- a/2003/contact.html
+++ b/2003/contact.html
@@ -1,86 +1,116 @@
 <div>
 [[!meta description="Contact Simon McVittie, owner of pseudorandom.co.uk"]]
 [[!meta title="Contact pseudorandom"]]
-[[!meta copyright="Copyright © 1999-2008 Simon McVittie"]]
+[[!meta copyright="Copyright © 1999-2012 Simon McVittie"]]
 
 <div class="section"><h2>E-mail</h2>
 
-<p>To send me a quick e-mail without starting your e-mail program, you can use
-the form below.</p>
-
-<p>Alternatively, you can e-mail me by the usual method.
-Signed and/or encrypted e-mail using OpenPGP is welcome; my public key is
-available on pgp.net keyservers (keyID <code>5530EC76</code>) or from further down
-this page.</p>
-
 <p>My address is something like
 <code>webmaster&#160;*&#160;pseudorandom&#160;*&#160;co&#160;*&#160;uk</code>,
 but with an @ sign and dots in the appropriate places. (Address mangled to
 avoid spammers' address harvesting)</p>
 
 </div>
-<div class="section"><h2><a name="quickmail" id="quickmail">Quick e-mail</a></h2>
-
-<form method="post" action="/cgi-bin/contact-form.cgi" enctype="application/x-www-form-urlencoded">
-<div><input type="hidden" name="to" value="Webmaster" /></div>
-<p><label for="email">Your email address</label><br /><input id="email" class="textentry" type="text" name="email" value="" /></p>
-<p><label for="name">Your name, alias, screen-name or pseudonym</label><br /><input id="name" class="textentry" type="text" name="name" value="" /></p>
-<p><label for="subject">Message subject</label><br /><input id="subject" class="textentry" type="text" name="subject" value="" /></p>
-<p><label for="message">Message text</label><br /><textarea id="message" class="textentry" cols="40" rows="10" name="message"></textarea></p>
 
-<p><input type="submit" value="Send" /></p>
-</form>
+<div class="section"><h2>GPG public key</h2>
+<p>4096 bit RSA key, ID <code>63C7CC90</code>, fingerprint:
+<code>DA98 F25C 0871 C49A 59EA  FF2C 4DE8 FF2A 63C7 CC90</code>.
+It should be available from all synched keyservers.</p>
 
-<p>All fields are required.</p>
-<p class="credit">[Based on Stephen Ostermiller's <a href="http://ostermiller.org/contactform/">Contact Form</a> script]</p>
-</div>
-<div class="section"><h2>My public key</h2>
-<p>I have <a href="http://www.gnupg.org/">Gnu Privacy Guard</a>, but recent
-versions of Pretty Good Privacy should accept these keys too.</p>
-
-<p>Key fingerprint: <code>6998 18EF 768A E1BB 6DAE  E611 5927 3CCD 5530 EC76</code>.</p>
+<p>I also have an older DSA key, which signed the new RSA key:
+<code>1024D/5530EC76</code>, fingerprint
+<code>6998 18EF 768A E1BB 6DAE  E611 5927 3CCD 5530 EC76</code>.</p>
 
 <pre>
 -----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.2.2 (GNU/Linux)
-Comment: OpenPGP key: http://www.pseudorandom.co.uk/2003/contact/
 
-mQGiBDuJVLcRBACktIX/iZ/q7S/1eAITkLf8kvsRyU3wD3DSwLhBXkPDgvJIGNvO
-ZbCS4m+JQe97g4zRLb1QmN0QBLroKECvxaPk5xwniLtu+pvmuAf4x4vSvfJ/XdzO
-bphaI+88H++YDflV018NyKS9TXnI3645d6xJmo6Qyx0BnQUkLQ7EtnQJkwCg8mv0
-gF08DKgmlw//GgUvvT4zhaUD/jCE9jBLvdrlTGMFPk2clKmdTYd10qqa3M8vo49Z
-VhIK1kWMjmk8MLb4EwHxMTlDLoRGIhz5g+vcmhzvN+n2qgawHfgL54fgRje6bwth
-Q2XL/yViqvx1Smuk3Ywuqz7Jkn7DPjnqlUDTDtE2/e/FpD4MLaRgRyb3iL6B8bno
-5x1YA/wPOECWSY6e8R5gwqIUBBd22CHL+urHfK5Q9vjxHscz4vks+kRig/dDDf6r
-gLbn6nE9laSrfWm7FMm3z+qaqGtJWcll8iIgyB+IvNbAZ5MhGLWssnqnfxJY05y5
-APBUuD9BxTH7EKPCYq4PUJMxyW/sDCVoM+Z1L2RM4dm57j0Dg7Q9U2ltb24gTWNW
-aXR0aWUgKHBzZXVkb3JhbmRvbS5jby51aykgPHNtY3ZAcHNldWRvcmFuZG9tLmNv
-LnVrPohaBBMRAgAaBQsHCgMEAxUDAgMWAgECF4ACGQEFAjuJVLgACgkQWSc8zVUw
-7HbxbgCfRv6MJKKxQy0MBGL8dCVch3CqcSIAoKoY6OAj5zErkqE7mrGD/+bsvZsM
-iEYEEBECAAYFAj3G2jwACgkQPkOEudOdQeF3YwCg1NgOl48X49KJA8kgu78yOzTE
-P/sAn1GjNJSik/yP13mdVOot88K7YbVGiEYEExECAAYFAj3G2LIACgkQQgzZ2iBi
-pZuyJwCdFQ1I2oIj+YF7nyfhOsGR7LnC4mIAni1pCoF3AvSrgLGuOrxYRk2es5ez
-iEYEEBECAAYFAj3G1VUACgkQkMnJ0R5YCfOwBgCg4l6SB8WZuX26kDZZ8P/vsSZZ
-p2UAni67lHXkTwTzpjHnjTJ6ubtKX4f6iEYEEBECAAYFAj3G3pUACgkQrdOIUvoi
-8hI12ACg67gu3aeQfYv1DMk85SETv2gg18YAoNlk1i3WvJIZdWEuc9IXU+UKkFUS
-tCFTaW1vbiBNY1ZpdHRpZSA8c2ptMjEyQGNhbS5hYy51az6IVwQTEQIAFwUCPMVR
-EwULBwoDBAMVAwIDFgIBAheAAAoJEFknPM1VMOx2id4AmgID+Dc/PhskolPtr8sw
-5Aqdd/K+AJ9BkU6w9Ty8cHrktloXWTNAZzywJIhGBBARAgAGBQI9xtpXAAoJED5D
-hLnTnUHhDp8An1I+u1vJRlVjHOSev3R9F/Mi/RrsAKCBGFalW5xTsbwsW0Tt8L+N
-217MUYhGBBMRAgAGBQI9xti4AAoJEEIM2dogYqWbRaYAoInwEsuASt9q0tfdVh9m
-7RF/rt+HAJ9ZW9QrSklTuA+QWgK8kZZNr1rtr4hGBBARAgAGBQI9xtV+AAoJEJDJ
-ydEeWAnz+0MAoIvgfj86wRMLeCbK0ggn3oRwduahAKC9b3t5Kg+DihBN5uC4rHXc
-1S5UerkBDQQ7iVS3EAQA1DUq0YgdC4JZWFhIb0AeyF/ytcxlGqnAxLzxkPs6OAQg
-NvqJpiqzoJeHC7Z3BldtEXrOiXn52l5+1KYv8y2M4vNZFmXEJrxB71IfFfCjkI6A
-AA7CSOqkn5gTazwJ06AwezRr03C7SV3XyrPovfA+a6ZapRJP+dcF/Jt2xFDcdUMA
-AwUD/jAyNYapmpIQLktRrfI2n1DXzV65NQkzI4hau1wRKO2e/b5yTn5F8Y5788fu
-XNCg2By8Dr4+UJkCLOfcPR5gok1h8N7qUPCMQFMWFuL1eL5mwQjMJ001fbBXcKEC
-Z7HQPFmDlX58rfITYyT7iSJ4BP+dCWyccAe4hHwmipsHyZCNiEYEGBECAAYFAjuJ
-VLcACgkQWSc8zVUw7HaSZACfWeUKSr9RP1h6h6GsG3+FqPMdI/MAn0Xg58bOO1fg
-0vm3OfcmbfMGcyy1
-=kN90
+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
+fqO+14gha9DuX9SrolCuuwhceBmxokve
+=/x6C
 -----END PGP PUBLIC KEY BLOCK-----
-
 </pre>
 </div>
 </div>

disallow ikiwiki.cgi in robots.txt so search engines don't try to create pages
diff --git a/robots.txt b/robots.txt
index 3fd531a..8d1a913 100644
--- a/robots.txt
+++ b/robots.txt
@@ -12,3 +12,4 @@ Disallow: /2006/fragments/demo/
 Disallow: /2008/ikiwiki/demo
 Disallow: /templates/
 Disallow: /ikiwiki/
+Disallow: /ikiwiki.cgi

gfcombinefs: add a brief introduction
diff --git a/src/gfcombinefs.mdwn b/src/gfcombinefs.mdwn
index 302cbe3..657dc59 100644
--- a/src/gfcombinefs.mdwn
+++ b/src/gfcombinefs.mdwn
@@ -1,6 +1,18 @@
 [[!meta title="gfcombinefs - a filesystem for n-of-m secret sharing"]]
 [[!tag software]]
 
+gfcombinefs combines several "shares" of a secret file previously split using
+Shamir secret sharing, to produce the original secret, and presents it as
+a file in a FUSE filesystem.
+
+So far, there have been no releases.
+[Current source code](http://git.pseudorandom.co.uk/gfcombinefs.git) is
+available.
+
+The contents of the README follow.
+
+--------------------------
+
     ######################### WARNING ################################
     # So far, gfcombinefs is experimental and mostly untested.       #
     # No real release has been made yet. I suggest not trusting it.  #

Update software stuff, add gfcombinefs
diff --git a/2003/opensource.mdwn b/2003/opensource.mdwn
index 0e16da2..81b4482 100644
--- a/2003/opensource.mdwn
+++ b/2003/opensource.mdwn
@@ -1,21 +1,25 @@
 [[!meta title="Software"]]
-[[!meta copyright="Copyright © 2008 Simon McVittie"]]
+[[!meta copyright="Copyright © 2003-2009 Simon McVittie"]]
 
 ## Work
 
 I currently work for [Collabora] on various open-source projects. The main
-one is [Telepathy], an instant messaging and voice/video over IP framework
-based on D-Bus, used on the Nokia 770/N800/N810 and on the
-[One Laptop Per Child] laptops, as well as in mainstream Linux desktop apps.
-I've worked on most parts of the Telepathy stack, mainly the reference
-connection manager (Gabble, a connection manager using XMPP/Jabber which
-interoperates with Google Talk), the specification, and the GLib, Python
-and Qt 4 bindings.
+one is [Telepathy], a presence, messaging and voice/video over IP framework
+based on D-Bus; it's used on Nokia's [Maemo] devices (notably the [N900],
+which even uses it for phone calls), on the GNOME desktop (via Empathy),
+on [One Laptop Per Child], and elsewhere.
+
+I mainly work on the API specification, Mission Control (the reference
+implementation of an account manager and channel dispatcher), and
+the GObject binding telepathy-glib; I've also contributed to the Qt4 and
+Python bindings and to most of the connection managers.
 
 I'm also the maintainer of [dbus-python], and part of the [pkg-telepathy] team
 that maintains Telepathy in Debian.
 
 [Collabora]: http://www.collabora.co.uk/
+[Maemo]: http://maemo.org/
+[N900]: http://maemo.nokia.com/n900/
 [One Laptop per Child]: http://www.laptop.org/
 [Telepathy]: http://telepathy.freedesktop.org/
 [dbus-python]: http://www.freedesktop.org/Software/DBusBindings
@@ -23,22 +27,22 @@ that maintains Telepathy in Debian.
 
 ## Current personal projects
 
-I've recently (as of late 2008) been developing various plugins for
-[IkiWiki](http://ikiwiki.info/) and trying to get Debian 5.0 released.
+I sporadically contribute to [IkiWiki], the wiki compiler used by this website
+(including various plugins and some significant performance improvements),
+and do various QA work in [Debian] (fixing
+release-critical bugs and asking for the removal of redundant packages).
 
-## Game modifications and utilities
+[IkiWiki]: http://ikiwiki.info/
+[Debian]: http://www.debian.org/
 
-[[UT System Config|/2000/paradox/utsc]],
-[[Marginally Enhanced UT|/2002/paradox/ut/marginal]], and my
-[[quick fix|/2002/paradox/ut/reconfix]] for Gotham/UDS's Recon Force and
-Desert Agent models are all properly open-source.
-[[Advanced Model Support|/2001/paradox/ams]] is under a license which
-approaches open source, although it's not quite. See the
-[[Paradox Productions|/2003/paradox]] section for more
-details.
+I've also written [[src/gfcombinefs]], a filesystem to reconstitute secrets
+shared with [libgfshare](http://www.digital-scurf.org/software/libgfshare).
 
 ## Various old projects
 
+The [[Paradox Productions|/2003/paradox]] section contains some old game
+modifications, some with source code.
+
 [[/2002/Pseudosite]] and [[/2004/Pseudoweb]] were two attempts at a website
 generation framework.
 
diff --git a/src/gfcombinefs.mdwn b/src/gfcombinefs.mdwn
new file mode 100644
index 0000000..302cbe3
--- /dev/null
+++ b/src/gfcombinefs.mdwn
@@ -0,0 +1,190 @@
+[[!meta title="gfcombinefs - a filesystem for n-of-m secret sharing"]]
+[[!tag software]]
+
+    ######################### WARNING ################################
+    # So far, gfcombinefs is experimental and mostly untested.       #
+    # No real release has been made yet. I suggest not trusting it.  #
+    ##################################################################
+
+gfcombinefs combines several "shares" of a secret file previously split using
+Shamir secret sharing, to produce the original secret, and presents it as
+a file in a FUSE filesystem.
+
+The idea is that the secret file (probably a GnuPG secret keyring, i.e.
+secring.gpg) is split into (say) 6 shares (of the same length in bytes
+as the secret), of which 4 are needed to reconstitute the original secret
+(that would be a "4-of-6" share). Thanks to the algorithm used, having fewer
+than the required number of shares gives no information whatsoever about the
+secret's contents.
+
+For the actual mathematics, gfcombinefs uses libgfshare, written by Daniel
+Silverstone - see libgfshare's documentation for more about the algorithm.
+
+gfcombinefs is primarily designed for use with GnuPG secret keyrings, which
+has various consequences:
+
+* it locks itself into memory to stop the secret from being paged out
+* the secret can be removed, which should be done prior to suspend-to-disk
+  (hibernate), again to prevent it from being paged out
+* when not enough parts have been provided, the file exists but has zero
+  length (this stops gpg from complaining about it)
+
+Requirements
+------------
+
+At runtime:
+
+* FUSE library, tools and kernel module <http://fuse.sourceforge.net/>
+* libgfshare <http://www.digital-scurf.org/software/libgfshare>
+
+For compilation:
+
+* pkg-config <http://pkg-config.freedesktop.org/>
+* GNU make <http://www.gnu.org/software/make/>
+
+Usage
+-----
+
+The filesystem currently has one file in the root directory, called "secret".
+There's only one secret per mountpoint so far.
+
+The only normal operations supported are:
+
+* list the root directory (it contains "secret", "." and "..")
+* read from "secret"
+* get the attributes of "secret" (its permissions are 0400, i.e. r--------)
+* unlink "secret", e.g. with `rm -f $mountpoint/secret` - this doesn't actually
+  remove it, but it discards all its data (by clearing the relevant memory),
+  then truncates it to be an empty file
+
+In addition, you can provide shares. This is done by setting an XFS-style
+extended attribute on the secret, whose name is "user." plus the share number
+in ASCII, for instance:
+
+    rm -f $mountpoint/secret
+    attr -q -s user.023 $mountpoint/secret < secring.gpg.023
+    attr -q -s user.042 $mountpoint/secret < secring.gpg.042
+    attr -q -s user.111 $mountpoint/secret < /media/usbdisk/secring.gpg.111
+    attr -q -s user.123 $mountpoint/secret < /media/usbdisk/secring.gpg.123
+
+When enough shares have been provided (currently the filesystem is hard-coded
+to expect exactly 4 shares), the secret file's size will change from 0 to the
+real size (which is equal to the size of each share), and its contents will
+change from empty to the real secret.
+
+Example
+-------
+
+For instance, you could do a 4-of-6 share and put two shares on your laptop,
+two on a USB stick in your pocket, and two backup shares kept in safe
+places.
+
+If you have both the laptop and the USB stick, you can get your secret keyring
+and do GnuPG things, but if either your laptop or your USB stick are lost
+or stolen (but not both devices at the same time!) you don't need to revoke
+your key: just take the remaining device and the two backup shares, combine
+them to get the secret, re-split the secret into a new set of shares, and
+securely destroy the old shares (to guarantee that they cannot be obtained by
+the same person as the lost device, and used to recover the secret).
+
+The lost device contains only two shares, which isn't enough to recover the
+secret (you can make sure they're entirely useless by destroying the other
+shares in that set).
+
+Many other sharing schemes are possible; the author of libgfshare suggests
+a 3-of-5 share, with two shares on a USB stick and one each on three
+computers. You can adjust the number of shares, and their distribution
+between various locations, as necessary, but at the moment the number of shares
+expected is hard-coded in gfcombinefs.
+
+For shares stored on large storage devices (like the laptop's hard disk), I
+recommend making a small partition (or LVM logical volume) to contain them -
+that way, you can wipe the whole partition with wipe(1) without it taking too
+long, and be reasonably sure that the old shares are unrecoverable.
+
+Limitations
+-----------
+
+gfcombinefs is a read-only filesystem - you'll have to split the secret
+yourself, probably using gfsplit(1). Supporting writing would be problematic -
+splitting the new secret wouldn't be a problem, but it wouldn't be possible
+to copy the new shares from gfcombinefs to their various locations
+automatically (the backup shares shouldn't even be present most of the time).
+
+Luckily, gpg can usually operate well with a read-only secret keyring; you'll
+usually only have to alter the secret keyring (and hence re-split) if you add
+uids or subkeys to a key, or create a whole new key.
+
+In particular, you can encrypt data, sign data, certify (sign keys), and so on
+with the secret keyring on a read-only filesystem like gfcombinefs.
+
+gfcombinefs doesn't help you to do the actual splitting. This is probably
+best done with a temporary GNUPGHOME in a tmpfs, with swap disabled (so the

(Diff truncated)
2007/sbuild: update for current Debian, while setting up armel schroots on testament
diff --git a/2007/sbuild.mdwn b/2007/sbuild.mdwn
index e92d797..96231ce 100644
--- a/2007/sbuild.mdwn
+++ b/2007/sbuild.mdwn
@@ -19,13 +19,6 @@ to upgrade it.
 I use this configuration on [Collabora]'s build box, and also on my
 laptop.
 
-[Updated 2007-12-10: better instructions for making chroots,
-avoiding Recommends being installed]
-
-[Updated 2008-04-13: updated hook scripts to the ones I actually use.
-Search for "2008-04-13". See also:
-[[Using sbuild as a Debian maintainer|/2008/sbuild-dm]]]
-
 The naive thing to do would be to allocate a logical volume for each chroot.
 However, each LV needs enough space to hold a minimal base system, plus
 the largest package build you ever want to do (including its build
@@ -44,22 +37,21 @@ another, you can share the base system using some schroot hooks I describe
 later. For instance, I don't have a base for Debian experimental - I just
 construct it as needed, by upgrading from unstable.
 
-On [Collabora]'s x86-64 build box the base chroots currently occupy 1.6 GiB of
-a 5 GiB LV, with the following sizes (just after an apt-get clean):
+Some rather outdated statistics: on [Collabora]'s x86-64 build box, the base
+chroots at one point occupied 1.6 GiB of a 5 GiB LV, with the following sizes
+(just after an apt-get clean):
 
 * Debian etch i386: 213M
 * Debian etch x86-64: 216M
 * Debian sid i386: 216M
 * Debian sid x86-64: 221M
-
-and for Ubuntu builds:
-
 * Ubuntu dapper i386: 207M
 * Ubuntu edgy i386: 196M
 * Ubuntu edgy x86-64: 154M
 
-On my laptop I allocated 3 GiB for the base system, which should in practice
-be plenty for an i386-only environment.
+On my laptop I originally allocated 3 GiB for the base system, which should in
+practice be plenty for an i386-only environment. I now use 5 GiB, since I have
+plenty of disk.
 
 You'll also need some free space in the same volume group - the maximum you
 can theoretically need is the free space on your base LV, plus the size of the
@@ -70,10 +62,10 @@ away with rather less than that.
 ## Setting up the logical volumes
 
 Having decided how much space you want in the base, set up an LV for your
-base system (here I use 3 GiB in the volume group "vg", naming the
+base system (here I use 5 GiB in the volume group "vg", naming the
 resulting LV "/dev/vg/schroot"):
 
-    sudo lvcreate -L3G -nschroot vg
+    sudo lvcreate -L5G -nschroot vg
 
 format it:
 
@@ -92,35 +84,13 @@ For use on a laptop with potentially wobbly networking, you probably want
 to cache installed packages with a local instance of [approx], in which case
 replace *MIRROR* with `localhost:9999`.
 
-    cd /mnt
-    sudo cdebootstrap --flavour=build sarge sarge http://MIRROR/debian
-    sudo cdebootstrap --flavour=build etch etch http://MIRROR/debian
-    sudo cdebootstrap --flavour=build sid sid http://MIRROR/debian
-
-## Setting up Ubuntu or Debian base systems with `debootstrap`
-
-`debootstrap` was the shell script that inspired `cdebootstrap`.
-It's likely to be more fragile, but the version shipped in Ubuntu supports
-making Ubuntu as well as Debian chroots, which `cdebootstrap` doesn't.
-
-As an alternative to the `cdebootstrap` commands above, you could use:
+If you have a Debian mirror on your LAN, giving it the DNS alias `mirror` is
+extremely convenient.
 
     cd /mnt
-    sudo debootstrap --variant=buildd sarge sarge http://MIRROR/debian
-    sudo debootstrap --variant=buildd etch etch http://MIRROR/debian
-    sudo debootstrap --variant=buildd sid sid http://MIRROR/debian
-
-To get Ubuntu chroots on a Debian system, you'll have to fetch the
-`debootstrap` source tarball from <http://packages.ubuntu.com/debootstrap>.
-Untar it somewhere (I used ~/tmp) and use:
-
-    cd /mnt
-    sudo debootstrap dapper dapper http://MIRROR/ubuntu \
-            ~/tmp/debootstrap-0.3.3.2ubuntu3/dapper
-    sudo debootstrap edgy edgy http://MIRROR/ubuntu \
-            ~/tmp/debootstrap-0.3.3.2ubuntu3/edgy
-    sudo debootstrap feisty feisty http://MIRROR/ubuntu \
-            ~/tmp/debootstrap-0.3.3.2ubuntu3/feisty
+    sudo cdebootstrap --flavour=build lenny lenny http://MIRROR/debian
+    sudo cdebootstrap --flavour=build squeeze squeeze http://MIRROR/debian
+    sudo cdebootstrap --flavour=build sid sid http://MIRROR/debian
 
 ## Very basic chroot configuration
 
@@ -139,7 +109,7 @@ After that, unmount `/mnt` before continuing.
 
 ## Configuring `schroot`
 
-Here's what to put in `/etc/schroot/schroot.conf` for each chroot:
+Here's what to put in `/etc/schroot/chroot.d/NAME` for each chroot:
 
     [sid]
     # Optional. The chroot with alias 'default' is used if you just type
@@ -182,48 +152,47 @@ Put this in `/etc/schroot/setup.d/60append-apt-sources`:
 
     #!/bin/sh
     # /etc/schroot/setup.d/60append-apt-sources
-    # Updated 2008-04-13 to support replacing /etc/apt/preferences
-
-    if [ "z$1" = "zsetup-start" ] || [ "z$1" = "zsetup-recover" ]; then
-
+    
+    if [ $1 = "setup-start" ] || [ $1 = "setup-recover" ]; then
+    
       NAME=$(echo "${CHROOT_NAME}" | sed -e 's/-[a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9]-[a-z0-9][a-z0-9][a-z0-9][a-z0-9]-[a-z0-9][a-z0-9][a-z0-9][a-z0-9]-[a-z0-9][a-z0-9][a-z0-9][a-z0-9]-[a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9][a-z0-9]//g')
-
+    
       EXTRA_APT_SOURCES="/etc/schroot/sources.list.d/${NAME}.sources.list"
       APT_PREFS="/etc/schroot/sources.list.d/${NAME}.preferences"
-
+    
       if [ "$AUTH_VERBOSITY" = "verbose" ]; then
-        echo "Checking for auxiliary apt sources in $EXTRA_APT_SOURCES"
+        echo "Checking for auxiliary apt sources in $EXTRA_APT_SOURCES" >&2
       fi
       if [ -e "$EXTRA_APT_SOURCES" ]; then
         if [ "$AUTH_VERBOSITY" = "verbose" ]; then
-          echo "... extra apt sources found"
+          echo "... extra apt sources found" >&2
         fi
         cat "$EXTRA_APT_SOURCES" >> "${CHROOT_PATH}/etc/apt/sources.list"
       fi
-
+    
       if [ "$AUTH_VERBOSITY" = "verbose" ]; then
-        echo "Checking for apt preferences in $APT_PREFS"
+        echo "Checking for apt preferences in $APT_PREFS" >&2
       fi
       if [ -e "$APT_PREFS" ]; then
         if [ "$AUTH_VERBOSITY" = "verbose" ]; then
-          echo "... apt preferences found"
+          echo "... apt preferences found" >&2
         fi
         install -m644 "$APT_PREFS" "${CHROOT_PATH}/etc/apt/preferences"
       fi
+    
     fi
 
 and this in /etc/schroot/setup.d/80apt-get-update:
 
     #!/bin/sh
     # /etc/schroot/setup.d/80apt-get-update
-    # Updated 2008-04-13 to never output to stdout
-
-    if [ "z$1" = "zsetup-start" ]; then
-        if [ "z$AUTH_VERBOSITY" = "zverbose" ]; then
-            chroot "${CHROOT_PATH}" apt-get update >&2 || true
-        else
-            chroot "${CHROOT_PATH}" apt-get update >/dev/null || true
-        fi
+    
+    if [ $1 = "setup-start" ]; then
+	    if : || [ "$AUTH_VERBOSITY" = "verbose" ]; then
+		    chroot "${CHROOT_PATH}" apt-get update >&2 || true
+	    else
+		    chroot "${CHROOT_PATH}" apt-get update >/dev/null || true
+	    fi
     fi
 
 `chmod` them both to be executable.
@@ -236,9 +205,10 @@ after a chroot, with `.sources.list` appended. For instance, in
 
     # /etc/schroot/sources.list.d/experimental.sources.list
     deb http://MIRROR/debian experimental main
+    deb-src http://MIRROR/debian experimental main
 
-with MIRROR replaced as above. Now that sources.list fragment will be appended
-to `/etc/apt/sources.list` in `[experimental]` chroots only. `apt`'s
+with *MIRROR* replaced as above. Now that sources.list fragment will be
+appended to `/etc/apt/sources.list` in `[experimental]` chroots only. `apt`'s
 default pinning behaviour means the experimental packages will only be used
 where selected by a versioned dependency.
 
@@ -283,14 +253,6 @@ Enter a snapshot with a command like:
 
 Any changes you make will be lost after the snapshot is closed.
 
-Build a package in a single-use snapshot with:
-
-    sbuild foo-1.2.3.dsc
-
-or to override the distribution in the .dsc file,
-

(Diff truncated)
Cross-ref Debian posts on smcv.pseudorandom.co.uk
diff --git a/tags/debian.mdwn b/tags/debian.mdwn
index 87ffac9..07ff237 100644
--- a/tags/debian.mdwn
+++ b/tags/debian.mdwn
@@ -1,4 +1,7 @@
 [[!meta title="Debian-related"]]
 
+See also:
+[blog posts tagged as Debian](http://smcv.pseudorandom.co.uk/tags/debian/)
+
 [[!inline pages="link(/tags/debian)" archive="yes" feeds="no"
   timeformat="%B %Y"]]

Don't put smcv.pseudorandom.co.uk tag on the front page
diff --git a/index.mdwn b/index.mdwn
index 53daf98..7191433 100644
--- a/index.mdwn
+++ b/index.mdwn
@@ -1,7 +1,8 @@
 [[!meta copyright="Copyright © 1999-2009 Simon McVittie"]]
 [[!meta title="pseudorandom.co.uk"]]
 
-[[!pagestats pages="tags/* and !tags/abandoned"]]
+[[!pagestats pages="tags/* and !tags/abandoned
+  and !tags/smcv.pseudorandom.co.uk"]]
 
 <dl>
 <dt><a href="http://smcv.pseudorandom.co.uk/">smcv.pseudorandom.co.uk</a></dt>

it's 2009
diff --git a/index.mdwn b/index.mdwn
index 006b748..53daf98 100644
--- a/index.mdwn
+++ b/index.mdwn
@@ -1,4 +1,4 @@
-[[!meta copyright="Copyright © 1999-2008 Simon McVittie"]]
+[[!meta copyright="Copyright © 1999-2009 Simon McVittie"]]
 [[!meta title="pseudorandom.co.uk"]]
 
 [[!pagestats pages="tags/* and !tags/abandoned"]]

Don't allow indexing of ikiwiki internals
diff --git a/robots.txt b/robots.txt
index 912efad..3fd531a 100644
--- a/robots.txt
+++ b/robots.txt
@@ -10,3 +10,5 @@ Disallow: /2007/_
 Disallow: /2008/_
 Disallow: /2006/fragments/demo/
 Disallow: /2008/ikiwiki/demo
+Disallow: /templates/
+Disallow: /ikiwiki/

Add robots.txt to main site's source code control
diff --git a/robots.txt b/robots.txt
new file mode 100644
index 0000000..912efad
--- /dev/null
+++ b/robots.txt
@@ -0,0 +1,12 @@
+User-agent: *
+# Temporary directories start with _ or ~
+Disallow: /_
+Disallow: /~
+Disallow: /2004/pseudoweb/darcs/
+Disallow: /2004/
+Disallow: /2005/_
+Disallow: /2006/_
+Disallow: /2007/_
+Disallow: /2008/_
+Disallow: /2006/fragments/demo/
+Disallow: /2008/ikiwiki/demo

Typo fixes in tp-svc
diff --git a/2008/04/16/tp-svc.mdwn b/2008/04/16/tp-svc.mdwn
index 8f42764..2c8bbf2 100644
--- a/2008/04/16/tp-svc.mdwn
+++ b/2008/04/16/tp-svc.mdwn
@@ -9,9 +9,10 @@
 *(Part 1 of an ongoing series: shiny things in telepathy-glib)*
 
 > `16:46 < epmf> tp-glib is made of magic`
+>
 > -- `#telepathy`, 2008-04-15
 
-Rob_ pointed out today that I'd been promising to blog about
+[Rob] pointed out today that I'd been promising to blog about
 [telepathy-glib] for several months and still haven't done so. I think
 there's too much to cover in one blog post, so I'll start with the
 oldest part - implementing a service (typically a Telepathy connection

misc articles: translate from reST to Markdown and update
diff --git a/2004/pseudoweb.mdwn b/2004/pseudoweb.mdwn
new file mode 100644
index 0000000..cc3e945
--- /dev/null
+++ b/2004/pseudoweb.mdwn
@@ -0,0 +1,24 @@
+[[!meta title="Pseudoweb 0.4.0"]]
+[[!meta copyright="Copyright © 2003-2008 Simon McVittie"]]
+[[!meta date="2003-03-06"]]
+[[!tag abandoned software]]
+
+Pseudoweb is another program formerly used to maintain pseudorandom.co.uk.
+It compiles XHTML pages from XHTML source conforming to a (fairly ad-hoc)
+profile, uses RDF metadata throughout and is as awkward to use in practice
+as you'd expect from that description...
+
+Pseudoweb copyright © 2004 Simon McVittie. Some rights reserved.
+Released under the same BSD-style license as zlib/libpng: see COPYING.txt
+for details.
+
+* [[Download version 0.4.0|/2004/pseudoweb/0.4.0/pseudoweb-0.4.0.zip]]
+
+(As of 2008 I've taken down the old [Darcs] repository. If you really want the
+change history, you can get [a repository tarball]. It unpacks into a darcs
+repository from which the working tree has been deleted - you can use
+`darcs revert -a` to get it back.)
+
+[a repository tarball]: /2005/pseudoweb.darcs.tar.bz2
+
+[Darcs]: http://www.abridgegame.org/darcs/
diff --git a/2004/pseudoweb.rst b/2004/pseudoweb.rst
deleted file mode 100644
index e8b1529..0000000
--- a/2004/pseudoweb.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-[[!meta title="Pseudoweb 0.4.0"]]
-[[!meta copyright="Copyright © 2003-2008 Simon McVittie"]]
-[[!meta date="2003-03-06"]]
-[[!tag abandoned software]]
-
-Pseudoweb is another program formerly used to maintain pseudorandom.co.uk.
-It compiles XHTML pages from XHTML source conforming to a (fairly ad-hoc)
-profile, uses RDF metadata throughout and is as awkward to use in practice
-as you'd expect from that description...
-
-Pseudoweb copyright © 2004 Simon McVittie. Some rights reserved.
-Released under the same BSD-style license as zlib/libpng: see COPYING.txt
-for details.
-
-* `Download version 0.4.0`__
-
-__ /2004/pseudoweb/0.4.0/pseudoweb-0.4.0.zip
-
-(As of 2008 I've taken down the old Darcs_ repository. If you really want the
-change history, you can `get a repository tarball`__. It unpacks into a darcs
-repository from which the working tree has been deleted - you can use
-``darcs revert -a`` to get it back.)
-
-__ /2005/pseudoweb.darcs.tar.bz2
-
-.. _Darcs: http://www.abridgegame.org/darcs/
-.. _Python: http://www.python.org/
-.. _libxml2: http://xmlsoft.org/
-.. _rdflib: http://rdflib.net/
diff --git a/2006/fragments.mdwn b/2006/fragments.mdwn
new file mode 100644
index 0000000..c2797fc
--- /dev/null
+++ b/2006/fragments.mdwn
@@ -0,0 +1,8 @@
+[[!meta title="fragments"]]
+[[!meta copyright="Copyright © 2008 Simon McVittie"]]
+[[!tag abandoned software]]
+
+`fragments` was going to be a collection of reusable [Django] components.
+It turns out they weren't (reusable, that is).
+
+[Django]: http://www.djangoproject.com/
diff --git a/2006/fragments.rst b/2006/fragments.rst
deleted file mode 100644
index 04f6838..0000000
--- a/2006/fragments.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-[[!meta title="fragments"]]
-[[!meta copyright="Copyright © 2008 Simon McVittie"]]
-[[!tag abandoned software]]
-
-``fragments`` was going to be a collection of reusable Django_ components.
-It turns out they weren't (reusable, that is).
-
-.. _Django: http://www.djangoproject.com/
diff --git a/2006/fragments/gallery.mdwn b/2006/fragments/gallery.mdwn
new file mode 100644
index 0000000..5ab8f6f
--- /dev/null
+++ b/2006/fragments/gallery.mdwn
@@ -0,0 +1,12 @@
+[[!meta title="fragments.gallery"]]
+[[!meta copyright="Copyright © 2008 Simon McVittie"]]
+[[!tag abandoned software]]
+
+`fragments` was going to be a collection of reusable [Django] components.
+It turns out they weren't.
+
+`fragments.gallery` was a simple photo gallery,
+using the filesystem as the authoritative source of information and the
+database as a cache.
+
+[Django]: http://www.djangoproject.com/
diff --git a/2006/fragments/gallery.rst b/2006/fragments/gallery.rst
deleted file mode 100644
index bc153d8..0000000
--- a/2006/fragments/gallery.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-[[!meta title="fragments.gallery"]]
-[[!meta copyright="Copyright © 2008 Simon McVittie"]]
-[[!tag abandoned software]]
-
-``fragments`` was going to be a collection of reusable Django_ components.
-It turns out they weren't.
-
-``fragments.gallery`` was a simple photo gallery,
-using the filesystem as the authoritative source of information and the
-database as a cache.
-
-.. _Django: http://www.djangoproject.com/
diff --git a/2006/mailserver.mdwn b/2006/mailserver.mdwn
new file mode 100644
index 0000000..c8c95fa
--- /dev/null
+++ b/2006/mailserver.mdwn
@@ -0,0 +1,300 @@
+[[!meta title="Mailserver configuration with Debian, Exim, ClamAV & dspam"]]
+[[!meta description="""
+    Mailserver configuration fragments similar to those previously used by
+    pseudorandom.co.uk, including virus rejection, spam filtering and
+    greylisting"""]]
+[[!meta guid="urn:uuid:7e41fe55-caf3-427f-b788-44f66917b97f"]]
+[[!meta date="2006-10-15T16:39:58Z"]]
+[[!meta copyright="Copyright © 2006-2008 Simon McVittie"]]
+[[!tag debian howto]]
+
+This document no longer describes a live configuration; I'll hopefully
+write up my current Postfix setup at some point.
+
+## Assumptions
+
+This is a slightly anonymized version of pseudorandom.co.uk's mail
+configuration, in which I'll pretend I'm configuring a host whose real name
+is colo.example.com, which hosts domains example.com, example.org
+and subdomain.example.com. You can find out what those names are pseudonyms for
+if you spend 5 minutes doing DNS lookups ;-)
+
+In my configuration, only real system users in /etc/passwd receive mail;
+for each user, e.g. "fred", there is a "real" address `fred@colo.example.com`.
+There are also hosted virtual domains like example.com, example.org and
+subdomain.example.com - each address at one of these domains either gets
+delivered to one or more system users, or rejected as unknown. You can do
+catch-all delivery too, but I don't, for spam reasons.
+
+I'm not using databases for configuration, for simplicity - I don't host
+many domains.
+
+## Simple Exim 4 virtual hosting
+
+    apt-get install exim4-daemon-heavy exim4
+
+I used the `-heavy` rather than `-light` variant so I could have
+content scanning using `clamav`, which is configured later.
+
+When `exim4-config` prompts you, select:
+
+- Internet site
+- Use split configuration
+- Local hostnames are e.g. `colo.example.com`, `colo` and
+  `spam.example.com` (there's no need to include your virtual hosts,
+  we'll set that up in a moment). `spam.example.com` is for dspam support,
+  which I'll configure later on. Depending which version of Debian
+  you're using, you may need to separate the hostnames with colons
+  `:` or with semicolons `;` - pay attention to the debconf
+  prompt.
+
+Create an empty directory `/etc/exim4/virtual`.
+
+If you want users' mail delivered into a Maildir (for use with Courier
+or Dovecot IMAP) by default, edit /etc/exim4/update-exim4.conf.conf to
+include
+
+    dc_localdelivery='maildir_home'
+
+To add all your virtual hosts to the list of local hostnames, edit
+`/etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs` and add
+`dsearch;/etc/exim4/virtual` to the line that defines local_domains,
+so it looks something like::
+
+    local_domains = MAIN_LOCAL_DOMAINS : dsearch;/etc/exim4/virtual
+

(Diff truncated)
structural stuff: translate reST to Markdown and update
diff --git a/2003/about.mdwn b/2003/about.mdwn
new file mode 100644
index 0000000..eb3f456
--- /dev/null
+++ b/2003/about.mdwn
@@ -0,0 +1,30 @@
+[[!meta title="About pseudorandom"]]
+[[!meta description="About this site and its author"]]
+[[!meta copyright="Copyright © 1999-2008 Simon McVittie"]]
+
+pseudorandom is Simon McVittie's personal website.
+
+## About smcv
+
+I'm a programmer at [Collabora], mostly in C and Python. See
+[[Software|/2003/opensource]] for stuff I've worked on.
+I'm also a [Debian] [developer].
+
+[Debian]: http://www.debian.org/
+[developer]: http://qa.debian.org/developer.php?login=smcv@debian.org
+[Collabora]: http://www.collabora.co.uk/
+
+Site history
+============
+
+This site started off mostly hosting game modifications
+([[Paradox Productions|/2003/paradox]]), but most recent stuff is related to
+Debian, Linux and free software development. New things are now linked from
+[my blog].
+
+[my blog]: http://smcv.pseudorandom.co.uk/
+
+Legalese
+========
+
+[[Copyright, disclaimer of responsibility and privacy statement|/2003/legal]]
diff --git a/2003/about.rst b/2003/about.rst
deleted file mode 100644
index 4256b01..0000000
--- a/2003/about.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-[[!meta title="About pseudorandom"]]
-[[!meta description="About this site and its author"]]
-[[!meta copyright="Copyright © 1999-2008 Simon McVittie"]]
-
-pseudorandom is Simon McVittie's personal website.
-
-About smcv
-==========
-
-I'm a programmer at Collabora_, mostly in C and Python. See
-Software_ for stuff I've worked on. I'm also a Debian_ developer_.
-
-.. _Software: /2003/opensource/
-.. _Debian: http://www.debian.org/
-.. _developer: http://qa.debian.org/developer.php?login=smcv@debian.org
-.. _Collabora: http://www.collabora.co.uk/
-
-Site history
-============
-
-This site started off mostly hosting game modifications
-(`Paradox Productions`_), but most recent stuff is related to Debian,
-Linux and free software development. New things are now linked from `my blog`_.
-
-.. _Paradox Productions: /2003/paradox/
-.. _my blog: http://smcv.pseudorandom.co.uk/
-
-Legalese
-========
-
-`Copyright, disclaimer of responsibility and privacy statement </2003/legal/>`__
diff --git a/2003/legal.mdwn b/2003/legal.mdwn
new file mode 100644
index 0000000..fc2957f
--- /dev/null
+++ b/2003/legal.mdwn
@@ -0,0 +1,29 @@
+[[!meta title="Legal information"]]
+[[!meta copyright="Copyright © 1999-2008 Simon McVittie"]]
+
+## Copyright
+
+This website copyright © 1999-2008 Simon McVittie except where stated
+otherwise. Redistribution of content is not permitted unless stated
+otherwise.
+
+## Disclaimer of all responsibility
+
+Content on this site is offered "as-is" with no guarantee or warranty,
+express or implied.
+
+I make no guarantees and/or warranties that information contained herein
+is accurate, reliable, sensible, plausible, or legible. You exist entirely
+at your own risk and I accept no responsibility for anything.
+
+Opinions expressed on this site are not those of my employer.
+
+## Privacy
+
+I live in Europe, so you have data protection law on your side. :-)
+
+This site is run by an individual who has no interest in spying on you or
+covering your browser in ads. If you see ad banners on pseudorandom.co.uk,
+I have nothing to do with them; try checking for spyware on your computer.
+I do keep access logs, which I use to see
+which pages are visited and which browsers the visitors use.
diff --git a/2003/legal.rst b/2003/legal.rst
deleted file mode 100644
index 96947ab..0000000
--- a/2003/legal.rst
+++ /dev/null
@@ -1,35 +0,0 @@
-[[!meta title="Legal information"]]
-[[!meta copyright="Copyright © 1999-2008 Simon McVittie"]]
-
-Copyright
-=========
-
-This website copyright © 1999-2008 Simon McVittie except where stated
-otherwise. Redistribution of content is not permitted unless stated
-otherwise.
-
-Disclaimer of all responsibility
-================================
-
-Content on this site is offered "as-is" with no guarantee or warranty,
-express or implied.
-
-I make no guarantees and/or warranties that information contained herein
-is accurate, reliable, sensible, plausible, or legible. You exist entirely
-at your own risk and I accept no responsibility for anything.
-
-Opinions expressed on this site are not those of my employer.
-
-Privacy
-=======
-
-I live in Europe, so you have data protection law on your side. :-)
-
-This site is run by an individual who has no interest in spying on you or
-covering your browser in ads. If you see ad banners on pseudorandom.co.uk,
-I have nothing to do with them; try checking for spyware on your computer.
-I do keep access logs, which I use to see
-which pages are visited and which browsers the visitors use.
-
-At the time of writing I don't use cookies; if I do in future, I'll use
-them sparingly.
diff --git a/2003/opensource.mdwn b/2003/opensource.mdwn
new file mode 100644
index 0000000..0e16da2
--- /dev/null
+++ b/2003/opensource.mdwn
@@ -0,0 +1,51 @@
+[[!meta title="Software"]]
+[[!meta copyright="Copyright © 2008 Simon McVittie"]]
+
+## Work
+
+I currently work for [Collabora] on various open-source projects. The main
+one is [Telepathy], an instant messaging and voice/video over IP framework
+based on D-Bus, used on the Nokia 770/N800/N810 and on the
+[One Laptop Per Child] laptops, as well as in mainstream Linux desktop apps.
+I've worked on most parts of the Telepathy stack, mainly the reference
+connection manager (Gabble, a connection manager using XMPP/Jabber which
+interoperates with Google Talk), the specification, and the GLib, Python
+and Qt 4 bindings.
+
+I'm also the maintainer of [dbus-python], and part of the [pkg-telepathy] team
+that maintains Telepathy in Debian.
+
+[Collabora]: http://www.collabora.co.uk/
+[One Laptop per Child]: http://www.laptop.org/
+[Telepathy]: http://telepathy.freedesktop.org/
+[dbus-python]: http://www.freedesktop.org/Software/DBusBindings
+[pkg-telepathy]: http://alioth.debian.org/projects/pkg-telepathy/
+
+## Current personal projects
+
+I've recently (as of late 2008) been developing various plugins for
+[IkiWiki](http://ikiwiki.info/) and trying to get Debian 5.0 released.
+
+## Game modifications and utilities
+
+[[UT System Config|/2000/paradox/utsc]],
+[[Marginally Enhanced UT|/2002/paradox/ut/marginal]], and my
+[[quick fix|/2002/paradox/ut/reconfix]] for Gotham/UDS's Recon Force and
+Desert Agent models are all properly open-source.
+[[Advanced Model Support|/2001/paradox/ams]] is under a license which
+approaches open source, although it's not quite. See the
+[[Paradox Productions|/2003/paradox]] section for more
+details.
+
+## Various old projects
+
+[[/2002/Pseudosite]] and [[/2004/Pseudoweb]] were two attempts at a website
+generation framework.
+
+Other old projects include

(Diff truncated)
Adjust contact form location
diff --git a/2003/contact.html b/2003/contact.html
index 9d224c8..30cab02 100644
--- a/2003/contact.html
+++ b/2003/contact.html
@@ -21,7 +21,7 @@ avoid spammers' address harvesting)</p>
 </div>
 <div class="section"><h2><a name="quickmail" id="quickmail">Quick e-mail</a></h2>
 
-<form method="post" action="/2003/contact/form-impl.cgi" enctype="application/x-www-form-urlencoded">
+<form method="post" action="/cgi-bin/contact-form.cgi" enctype="application/x-www-form-urlencoded">
 <div><input type="hidden" name="to" value="Webmaster" /></div>
 <p><label for="email">Your email address</label><br /><input id="email" class="textentry" type="text" name="email" value="" /></p>
 <p><label for="name">Your name, alias, screen-name or pseudonym</label><br /><input id="name" class="textentry" type="text" name="name" value="" /></p>

Fix typo "apt-get-update"
diff --git a/2007/sbuild.rst b/2007/sbuild.rst
index 0671911..001bd56 100644
--- a/2007/sbuild.rst
+++ b/2007/sbuild.rst
@@ -235,9 +235,9 @@ and this in /etc/schroot/setup.d/80apt-get-update::
 
         if [ "z$1" = "zsetup-start" ]; then
             if [ "z$AUTH_VERBOSITY" = "zverbose" ]; then
-                chroot "${CHROOT_PATH}" apt-get-update >&2 || true
+                chroot "${CHROOT_PATH}" apt-get update >&2 || true
             else
-                chroot "${CHROOT_PATH}" apt-get-update >/dev/null || true
+                chroot "${CHROOT_PATH}" apt-get update >/dev/null || true
             fi
         fi
 

Convert to ikiwiki syntax etc.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b84c806
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/.ikiwiki
+/recentchanges
diff --git a/2000.mdwn b/2000.mdwn
new file mode 100644
index 0000000..229361c
--- /dev/null
+++ b/2000.mdwn
@@ -0,0 +1,3 @@
+[[!meta title="Content first published in or before 2000"]]
+[[!meta copyright="Copyright © 2008 Simon McVittie"]]
+[[!map pages="copyright(*) and 2000/*" show="title"]]
diff --git a/2000.rst b/2000.rst
deleted file mode 100644
index 9bf1325..0000000
--- a/2000.rst
+++ /dev/null
@@ -1,39 +0,0 @@
-Content first published in or before 2000
-=========================================
-
-.. metalink::
-	:rel=up: /
-
-.. meta::
-	:copyright: Copyright © 2003 Simon McVittie
-
-.. class:: auto-synopses
-
-	`.`__
-		.
-	`.`__
-		.
-	`.`__
-		.
-	`.`__
-		.
-	`.`__
-		.
-	`.`__
-		.
-	`.`__
-		.
-	`.`__
-		.
-	`.`__
-		.
-
-__ /2000/news/
-__ /2000/paradox/fpsctls/
-__ /2000/paradox/sctghost/
-__ /2000/paradox/utsc/
-__ /2000/paradox/ut-obscure/
-__ /2000/paradox/xvt/
-__ /2000/paradox/xwa/
-__ /2000/gen2/
-__ /2000/maths/inequal/
diff --git a/2000/gen2.html b/2000/gen2.html
new file mode 100644
index 0000000..1a43b59
--- /dev/null
+++ b/2000/gen2.html
@@ -0,0 +1,33 @@
+<div>
+[[!meta title="Genesis II fractal landscapes"]]
+[[!meta copyright="Copyright © 2000 Simon McVittie"]]
+[[!meta date="2000-01-01"]]
+[[!meta description="Landscape images generated by Geomantics' 'Genesis II'"]]
+
+<p>These were generated with Genesis 2, a Windows program by Scottish company
+<a href="http://www.geomantics.com/">Geomantics</a>. They're not of real
+places (I used Geomantics' fractal landscape plugin) but look fairly
+impressive.</p>
+<dl>
+<dt>Forested hillside (71 KB)</dt>
+<dd><a href="/2000/gen2/forest.jpg">
+<img src="/2000/gen2/thumbs/forest.jpg" alt="Forest" /></a>
+</dd>
+<dt>Mountain lake (92 KB)</dt>
+<dd><a href="/2000/gen2/lake1.jpg">
+<img src="/2000/gen2/thumbs/lake1.jpg" alt="Mountain lake" /></a>
+</dd>
+<dt>Sunset (80 KB)</dt>
+<dd><a href="/2000/gen2/sunset.jpg">
+<img src="/2000/gen2/thumbs/sunset.jpg" alt="Sunset" /></a>
+</dd>
+<dt>Mistscape (49 KB)</dt>
+<dd><a href="/2000/gen2/mistscape.jpg">
+<img src="/2000/gen2/thumbs/mistscape.jpg" alt="Mist" /></a>
+</dd>
+<dt>Tranquil lake (42 KB)</dt>
+<dd><a href="/2000/gen2/lake2.jpg">
+<img src="/2000/gen2/thumbs/lake2.jpg" alt="Lake" /></a>
+</dd>
+</dl>
+</div>
diff --git a/2000/gen2.xhtml b/2000/gen2.xhtml
deleted file mode 100644
index 66761f3..0000000
--- a/2000/gen2.xhtml
+++ /dev/null
@@ -1,41 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB" lang="en-GB">
-  <head>
-
-    <title>Genesis II fractal landscapes</title>
-    <meta name="copyright" content="Copyright © 2000 Simon McVittie" />
-    <link rel="up" href="/2003/other/"/>
-    <meta name="dcterms.created" content="2000" />
-    <meta name="description" content="Landscape images generated by Geomantics' 'Genesis II'" />
-  </head>
-  <body>
-    <div class="content" id="pse-content">
-<p>These were generated with Genesis 2, a Windows program by Scottish company
-<a href="http://www.geomantics.com/">Geomantics</a>. They're not of real
-places (I used Geomantics' fractal landscape plugin) but look fairly
-impressive.</p>
-<dl>
-<dt>Forested hillside (71 KB)</dt>
-<dd><a href="/2000/gen2/forest.jpg">
-<img src="/2000/gen2/thumbs/forest.jpg" alt="Forest" /></a>
-</dd>
-<dt>Mountain lake (92 KB)</dt>
-<dd><a href="/2000/gen2/lake1.jpg">
-<img src="/2000/gen2/thumbs/lake1.jpg" alt="Mountain lake" /></a>
-</dd>
-<dt>Sunset (80 KB)</dt>
-<dd><a href="/2000/gen2/sunset.jpg">
-<img src="/2000/gen2/thumbs/sunset.jpg" alt="Sunset" /></a>
-</dd>
-<dt>Mistscape (49 KB)</dt>
-<dd><a href="/2000/gen2/mistscape.jpg">
-<img src="/2000/gen2/thumbs/mistscape.jpg" alt="Mist" /></a>
-</dd>
-<dt>Tranquil lake (42 KB)</dt>
-<dd><a href="/2000/gen2/lake2.jpg">
-<img src="/2000/gen2/thumbs/lake2.jpg" alt="Lake" /></a>
-</dd>
-</dl>
-</div>
-  </body>
-</html>
diff --git a/2000/maths.mdwn b/2000/maths.mdwn
new file mode 100644
index 0000000..e69de29
diff --git a/2000/maths/inequal.html b/2000/maths/inequal.html
new file mode 100644
index 0000000..c718dcb
--- /dev/null
+++ b/2000/maths/inequal.html
@@ -0,0 +1,28 @@
+<div>
+[[!meta title="Geometric proof: (a+b)&#247;2 &#8805; &#8730;(ab)"]]
+[[!meta description="An alternative proof of the arithmetic/geometric mean inequality; this is not the usual proof, or the best proof"]]
+[[!meta copyright="Copyright © 2000 Simon McVittie"]]
+[[!tag maths]]
+[[!meta date="2000-03-01"]]
+
+<div class="section"><h2>Introduction</h2>
+<p>This is a fairly random proof of a simple special case of the
+arithmetic/geometric mean inequality (which is basically that the sum of a set
+of <i>n</i> positive real numbers, divided by <i>n</i>, is at least as large as the <i>n</i>th root
+of the product of the same <i>n</i> positive real numbers). It's not a very
+useful proof, because it doesn't add anything to your understanding of the
+problem and can't be extended to more than 2 numbers, but it has weird looking
+diagrams :-)</p>
+</div>
+<div class="section"><h2>Geometric proof that (<i>a</i>+<i>b</i>)&#247;2 &#8805; &#8730;<i>ab</i> (<i>a</i>, <i>b</i> &#8712; <b>R</b><sup>+</sup>)</h2>
+<p> <img src="/2000/maths/inequal/image004.gif" alt="The same diagram with some sides labelled" /> Fig.1</p>
+<p>Consider a triangle inscribed in a semicircle as shown (Fig.1), with its longest side the semicircle's diameter <i>d</i>, and its shorter sides &#8730;<i>a</i> and &#8730;<i>b</i>. Let the angles adjacent to this side be <i>&#945;</i> and <i>&#946;</i>. The angle opposite the diameter, <i>d</i>, is 90&#176;, because the angle subtended at the circumference is half the angle subtended at the centre (in this case, 180&#176;). This implies that <i>&#945;</i>+<i>&#946;</i>=90&#176;. Also, by Pythagoras' Theorem (as d is a right angle),</p>
+<p><img src="/2000/maths/inequal/image006.gif" alt="d squared = (sqrt(a)) squared + (sqrt(b)) squared; d squared = a + b; d = sqrt(a+b)" /></p>
+<p>The area of the triangle is &#189; &#215; base &#215; perpendicular height and, as d is a right angle, <i>A<sub>triangle</sub></i> = &#189; &#8730;<i>a</i>&#8730;<i>b =</i> &#189; &#8730;(<i>ab)</i>.</p>
+<p> <img src="/2000/maths/inequal/image008.gif" alt="Four semicircle/triangle sets with the hypotenuses forming the sides of a square, and everything else inside that square; the bottom and right triangles are emphasised with thicker lines" /> Fig.2</p>
+<p>Consider four of these arrangements, placed together as shown (Fig.2), such that the hypotenuses of the triangles form a square of side <i>d</i>=&#8730;(<i>a</i>+<i>b</i>), which therefore has area (<i>a</i>+<i>b</i>). The triangles touch but do not overlap at each side, as <i>&#945;</i>+<i>&#946;</i>=90&#176;. This means that, in any pair of adjacent triangles (one such pair is shown with thicker lines in Fig.2), the triangles do not overlap at any point.</p>
+<p> <img src="/2000/maths/inequal/image010.gif" alt="Same as Fig.2, but this time the top and bottom semicircles are emphasised" /> Fig.3</p>
+<p>As the square has height and width <i>d</i>=2 radii, the semicircles in which opposite triangles are inscribed (highlighted in Fig.3) touch at the centre (i.e. have a common tangent) but do not overlap. The triangles lie entirely within these semicircles and therefore cannot overlap either, although they will touch at the centre of the square when <i>&#945;</i>=<i>&#946;</i>=45&#176;.</p>
+<p>As there is no overlap between any triangles in this arrangement,</p>
+<p> <img src="/2000/maths/inequal/image012.gif" alt="A(square) is at least 4A(triangle), so a+b is at least 4 x 1/2 x sqrt(ab), so (a+b)/2 is at least sqrt(ab) for all positive real a, b. QED." /></p>
+</div></div>
diff --git a/2000/maths/inequal.xhtml b/2000/maths/inequal.xhtml
deleted file mode 100644
index 51af309..0000000
--- a/2000/maths/inequal.xhtml
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB" lang="en-GB">
-  <head>
-
-    <title>Geometric proof: (a+b)&#247;2 &#8805; &#8730;(ab)</title>
-    <meta name="description" content="An alternative proof of the arithmetic/geometric mean inequality; this is not the usual proof, or the best proof" />
-    <meta name="copyright" content="Copyright &#169; 2000 Simon McVittie" />
-    <link rel="up" href="/2003/other/" />
-    <meta name="dcterms.created" content="2000" />

(Diff truncated)
Import content from pseudorandom.co.uk
diff --git a/2000.rst b/2000.rst
new file mode 100644
index 0000000..9bf1325
--- /dev/null
+++ b/2000.rst
@@ -0,0 +1,39 @@
+Content first published in or before 2000
+=========================================
+
+.. metalink::
+	:rel=up: /
+
+.. meta::
+	:copyright: Copyright © 2003 Simon McVittie
+
+.. class:: auto-synopses
+
+	`.`__
+		.
+	`.`__
+		.
+	`.`__
+		.
+	`.`__
+		.
+	`.`__
+		.
+	`.`__
+		.
+	`.`__
+		.
+	`.`__
+		.
+	`.`__
+		.
+
+__ /2000/news/
+__ /2000/paradox/fpsctls/
+__ /2000/paradox/sctghost/
+__ /2000/paradox/utsc/
+__ /2000/paradox/ut-obscure/
+__ /2000/paradox/xvt/
+__ /2000/paradox/xwa/
+__ /2000/gen2/
+__ /2000/maths/inequal/
diff --git a/2000/gen2.xhtml b/2000/gen2.xhtml
new file mode 100644
index 0000000..66761f3
--- /dev/null
+++ b/2000/gen2.xhtml
@@ -0,0 +1,41 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB" lang="en-GB">
+  <head>
+
+    <title>Genesis II fractal landscapes</title>
+    <meta name="copyright" content="Copyright © 2000 Simon McVittie" />
+    <link rel="up" href="/2003/other/"/>
+    <meta name="dcterms.created" content="2000" />
+    <meta name="description" content="Landscape images generated by Geomantics' 'Genesis II'" />
+  </head>
+  <body>
+    <div class="content" id="pse-content">
+<p>These were generated with Genesis 2, a Windows program by Scottish company
+<a href="http://www.geomantics.com/">Geomantics</a>. They're not of real
+places (I used Geomantics' fractal landscape plugin) but look fairly
+impressive.</p>
+<dl>
+<dt>Forested hillside (71 KB)</dt>
+<dd><a href="/2000/gen2/forest.jpg">
+<img src="/2000/gen2/thumbs/forest.jpg" alt="Forest" /></a>
+</dd>
+<dt>Mountain lake (92 KB)</dt>
+<dd><a href="/2000/gen2/lake1.jpg">
+<img src="/2000/gen2/thumbs/lake1.jpg" alt="Mountain lake" /></a>
+</dd>
+<dt>Sunset (80 KB)</dt>
+<dd><a href="/2000/gen2/sunset.jpg">
+<img src="/2000/gen2/thumbs/sunset.jpg" alt="Sunset" /></a>
+</dd>
+<dt>Mistscape (49 KB)</dt>
+<dd><a href="/2000/gen2/mistscape.jpg">
+<img src="/2000/gen2/thumbs/mistscape.jpg" alt="Mist" /></a>
+</dd>
+<dt>Tranquil lake (42 KB)</dt>
+<dd><a href="/2000/gen2/lake2.jpg">
+<img src="/2000/gen2/thumbs/lake2.jpg" alt="Lake" /></a>
+</dd>
+</dl>
+</div>
+  </body>
+</html>
diff --git a/2000/maths/inequal.xhtml b/2000/maths/inequal.xhtml
new file mode 100644
index 0000000..51af309
--- /dev/null
+++ b/2000/maths/inequal.xhtml
@@ -0,0 +1,35 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB" lang="en-GB">
+  <head>
+
+    <title>Geometric proof: (a+b)&#247;2 &#8805; &#8730;(ab)</title>
+    <meta name="description" content="An alternative proof of the arithmetic/geometric mean inequality; this is not the usual proof, or the best proof" />
+    <meta name="copyright" content="Copyright &#169; 2000 Simon McVittie" />
+    <link rel="up" href="/2003/other/" />
+    <meta name="dcterms.created" content="2000" />
+  </head>
+  <body>
+    <div class="content" id="pse-content">
+<div class="section"><h2>Introduction</h2>
+<p>This is a fairly random proof of a simple special case of the
+arithmetic/geometric mean inequality (which is basically that the sum of a set
+of <i>n</i> positive real numbers, divided by <i>n</i>, is at least as large as the <i>n</i>th root
+of the product of the same <i>n</i> positive real numbers). It's not a very
+useful proof, because it doesn't add anything to your understanding of the
+problem and can't be extended to more than 2 numbers, but it has weird looking
+diagrams :-)</p>
+</div>
+<div class="section"><h2>Geometric proof that (<i>a</i>+<i>b</i>)&#247;2 &#8805; &#8730;<i>ab</i> (<i>a</i>, <i>b</i> &#8712; <b>R</b><sup>+</sup>)</h2>
+<p> <img src="/2000/maths/inequal/image004.gif" alt="The same diagram with some sides labelled" /> Fig.1</p>
+<p>Consider a triangle inscribed in a semicircle as shown (Fig.1), with its longest side the semicircle's diameter <i>d</i>, and its shorter sides &#8730;<i>a</i> and &#8730;<i>b</i>. Let the angles adjacent to this side be <i>&#945;</i> and <i>&#946;</i>. The angle opposite the diameter, <i>d</i>, is 90&#176;, because the angle subtended at the circumference is half the angle subtended at the centre (in this case, 180&#176;). This implies that <i>&#945;</i>+<i>&#946;</i>=90&#176;. Also, by Pythagoras' Theorem (as d is a right angle),</p>
+<p><img src="/2000/maths/inequal/image006.gif" alt="d squared = (sqrt(a)) squared + (sqrt(b)) squared; d squared = a + b; d = sqrt(a+b)" /></p>
+<p>The area of the triangle is &#189; &#215; base &#215; perpendicular height and, as d is a right angle, <i>A<sub>triangle</sub></i> = &#189; &#8730;<i>a</i>&#8730;<i>b =</i> &#189; &#8730;(<i>ab)</i>.</p>
+<p> <img src="/2000/maths/inequal/image008.gif" alt="Four semicircle/triangle sets with the hypotenuses forming the sides of a square, and everything else inside that square; the bottom and right triangles are emphasised with thicker lines" /> Fig.2</p>
+<p>Consider four of these arrangements, placed together as shown (Fig.2), such that the hypotenuses of the triangles form a square of side <i>d</i>=&#8730;(<i>a</i>+<i>b</i>), which therefore has area (<i>a</i>+<i>b</i>). The triangles touch but do not overlap at each side, as <i>&#945;</i>+<i>&#946;</i>=90&#176;. This means that, in any pair of adjacent triangles (one such pair is shown with thicker lines in Fig.2), the triangles do not overlap at any point.</p>
+<p> <img src="/2000/maths/inequal/image010.gif" alt="Same as Fig.2, but this time the top and bottom semicircles are emphasised" /> Fig.3</p>
+<p>As the square has height and width <i>d</i>=2 radii, the semicircles in which opposite triangles are inscribed (highlighted in Fig.3) touch at the centre (i.e. have a common tangent) but do not overlap. The triangles lie entirely within these semicircles and therefore cannot overlap either, although they will touch at the centre of the square when <i>&#945;</i>=<i>&#946;</i>=45&#176;.</p>
+<p>As there is no overlap between any triangles in this arrangement,</p>
+<p> <img src="/2000/maths/inequal/image012.gif" alt="A(square) is at least 4A(triangle), so a+b is at least 4 x 1/2 x sqrt(ab), so (a+b)/2 is at least sqrt(ab) for all positive real a, b. QED." /></p>
+</div></div>
+  </body>
+</html>
diff --git a/2000/news/_0416.xhtml b/2000/news/_0416.xhtml
new file mode 100644
index 0000000..8d7f528
--- /dev/null
+++ b/2000/news/_0416.xhtml
@@ -0,0 +1,21 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB" lang="en-GB">
+  <head>
+
+    <title>Terran Ghost</title>
+    <meta name="dc.date" content="2000-04-16"/>
+    <link rel="up" href="/2000/news/"/>
+    <meta name="copyright" content="Copyright © 2000-2004 Simon McVittie" />
+    <link rel="generates" href="/2000/news/#news0416"/>
+  </head>
+  <body>
+    <div class="content" id="pse-content">
+    
+<p>Changed some colour schemes around and added a skin to the Unreal Tournament
+section. The skin is a Terran Ghost from the RTS game Starcraft, for UT's Male
+Commando model.</p>
+<p><em>[Link-rot removal update, late 2002:
+<a href="/2000/paradox/sctghost/">the skin is archived here</a>]</em></p>
+</div>
+  </body>
+</html>
diff --git a/2000/news/_0521.xhtml b/2000/news/_0521.xhtml
new file mode 100644
index 0000000..540ded1
--- /dev/null
+++ b/2000/news/_0521.xhtml
@@ -0,0 +1,27 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB" lang="en-GB">
+  <head>
+
+    <title>Site move</title>
+    <meta name="dc.date" content="2000-05-21"/>
+    <link rel="up" href="/2000/news/"/>
+    <meta name="copyright" content="Copyright © 2000-2004 Simon McVittie" />
+    <link rel="generates" href="/2000/news/#news0521"/>
+  </head>
+  <body>
+    <div class="content" id="pse-content">
+    
+<p>Finally got round to uploading some Half-Life decals Rebel sent me a while ago,
+and moved the entire site to f9 (File Not Found's ISP) in the interests of
+avoiding ad banners.</p>
+<p>News update: I've been doing a bit of mapping in UnrealEd [the map might be
+finished by next year :-)]. I've also been trying to get UT running under
+Linux - I'll put up instructions if I can get it working. Finally, Veers
+over at unreal.gameobserver.net is making a new default face for my Starcraft
+Terran Ghost skin to replace my Executioner face - I'll release a modified
+version, with a few detail improvements and so on, when this is finished.</p>
+
+<p><em>[Link-rot removal update, late 2002: the new face never happened]</em></p>
+</div>
+  </body>
+</html>
diff --git a/2000/news/_0618.xhtml b/2000/news/_0618.xhtml
new file mode 100644
index 0000000..681c662
--- /dev/null
+++ b/2000/news/_0618.xhtml
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

(Diff truncated)