Free Short Stories

Here are some free short science-fiction stories that I enjoyed reading:

Cory Doctorow has released enough great sci-fi stories that he deserves his own section:

Robert Reed has released enough great free sci-fi stories that he deserves his own section:



Wikileaks/Assange supports Russia

How to Talk to Science Deniers

Pro-lifers really want misogyny

The modern definition of the word “Libertarian” means anarcho-capitalist

A short summary of bad things that Trump did with full support from conservatives

Fake news is almost entirely a right wing thing

PsyPost has an interesting article on the correlation between watching Fox News and lacking knowledge of science and of society


Ayn Rand was a sociopath who admired a serial killer

Murray Rothbard believed that parents should be allowed to starve their children to death

A Libertarian walks into a bear, Libertarians take over a town and get attacked by bears

Galt Gulch Chile, one of the failed attempts at a Libertarian town


Why Evangelism aims to alienate the non-believers

Has “Homosexual” Always Been in the Bible? No, it was originally about pedophilia.

The Only Moral Abortion is My Abortion – when anti-choice women choose abortion.


Things I won’t Work With – blog posts about nasty chemicals like FOOF and ClF3

How a Brisbane school limited the spread of Covid though checking air quality.


Between 5 and 10 people in the UK die each year putting on socks

Postfix Training

Basic MTA Configuration

All instructions here are for Postfix. If you want to use a different MTA then you will mostly be working without instructions.

  1. To install Postfix run “apt install postfix” (or for the preconfigured images I setup reconfigure it by running “rm /etc/postfix/ ; dpkg-reconfigure postfix“.
    1. Select “Internet Site” for the type of mail configuration.
    2. Enter the domain name you selected for the mail name (for the VMs I host it will be
    3. When it asks for a user to receive root mail set it to the name of a test user (EG “test”). Make the user with the command “useradd -m test
    4. When it asks for a comma separated list of domains delete the default text for that field and replace it with
    5. For “Force synchronous updates on mail queue” select No as apparently modern filesystems don’t need it and it significantly increases system load. If you say Yes this causes shell code equivalent to the following to be run:
      cd /var/spool/postfix
      chattr +S incoming active bounce defer deferred flush saved corrupt
    6. For “local networks” and the other settings the defaults should be good.
    7. After running the Debian package configuration create the account you specified for the root email, if it was “test” then run “useradd -m test“.
  2. The main Postfix configuration file is /etc/postfix/ Change the myhostname setting to the fully qualified name of the system, something like
    You can edit /etc/postfix/ with vi (or any other editor) or use the postconf command to change it, eg “postconf -e“.
  3. Add “home_mailbox=Maildir/” to the Postfix configuration to make it deliver to a Maildir spool in the user’s home directory (the trailing / is important).
  4. Restart Postfix to apply the changes.
  5. Test delivery by installing swaks via “apt install swaks libio-socket-inet6-perl” and then running the command “swaks -f -t -s localhost“. Note that swaks displays the SMTP data so you can see exactly what happens and if something goes wrong you will see everything about the error.
  6. Inspect /var/log/mail.log to see the messages about the delivery. View the message which is in ~test/Maildir/new.
  7. When other students get to this stage run the same swaks command but with the -t changed to the address in their domain, check the mail.log to see that the messages were transferred and view the mail with less to see the received lines.

Certbot Configuration

To avoid password sniffing we need to use SSL for both authenticated sending of mail and for receiving mail via POP/IMAP.

Run the following commands to install letsencrypt (also the gnutls-bin utilities to test SSL and the libnet-ssleay-perl library for swaks with SSL support) and request a SSL certificate:

apt install certbot gnutls-bin libnet-ssleay-perl
letsencrypt certonly --standalone -m $EMAIL_ADDRESS -d

Run the command “gnutls-cli --starttls-proto=smtp” to check the certificate used by Postfix, it should say that the certificate is not trusted.

Run the following commands to change the Postfix configuration to use the TLS certificate and then repeat the gnutls-cli command to show that it works:

postconf -e smtpd_tls_cert_file=/etc/letsencrypt/live/
postconf -e smtpd_tls_key_file=/etc/letsencrypt/live/
postconf -e smtpd_tls_CAfile=/etc/letsencrypt/live/
postconf -e smtpd_tls_received_header=yes
postconf -e smtpd_tls_loglevel=1
systemctl restart postfix.service

To test the SMTP TLS the command go to another system and run “swaks -f -t -s -tls -tlsp tlsv1_3“, this specifies that the connection must be encrypted via TLS version 1.3 (the most secure SSL protocol).

Basic Pop/IMAP Configuration

All instructions here are for Dovecot. Other POP/IMAP servers are available, but there is less reason for choosing an alternative than there is for the MTA.

  1. Run “apt install dovecot-pop3d dovecot-imapd” to install Dovecot POP and IMAP servers.
    Run “netstat -tln” to see the ports that have daemons listening on them, observe that ports 110, 143, 993, and 995 are in use.
  2. Edit /etc/dovecot/conf.d/10-mail.conf and change “mail_location = mbox:~/mail:INBOX=/var/mail/%u” to “mail_location = maildir:~/Maildir“. Then restart Dovecot.
  3. Run the command “nc localhost 110” to connect to POP, then run the following commands to get capabilities, login, and retrieve mail:
    user test
    retr 1
  4. Run the command “nc localhost 143” to connect to IMAP, then run the following commands to list capabilities, login, and logout:
    a capability
    b login test WHATEVERYOUMADEIT
    c logout
  5. For the above commands make note of the capabilities, we will refer to that later.

Now you have a basically functional mail server on the Internet!


Edit /etc/dovecot/conf.d/10-ssl.conf, remove the following 2 lines:

ssl_cert = </etc/dovecot/private/dovecot.pem
ssl_key = </etc/dovecot/private/dovecot.key

Add the following 2 lines:

ssl_cert =</etc/letsencrypt/live/
ssl_key = </etc/letsencrypt/live/

Restart Dovecot, then run the command “gnutls-cli” to connect via encrypted POP and after the connection is established you can use the same POP commands as before.


SASL is the system of SMTP authentication for mail relaying. It is needed to permit devices without fixed IP addresses to send mail through a server.

Run the following commands to configure Postfix for SASL:

# allow parts of Postfix to work with the same configuration regardless of whether they are running in a chroot
mkdir -p /var/spool/postfix/var/spool
ln -s ../.. /var/spool/postfix/var/spool/postfix
# configure Postfix for SASL with Dovecot as authentication server
postconf -e smtpd_sasl_auth_enable=yes
postconf -e smtpd_sasl_type=dovecot
postconf -e smtpd_sasl_path=/var/spool/postfix/private/auth
postconf -e broken_sasl_auth_clients=yes
postconf -e smtpd_sasl_authenticated_header=yes
systemctl restart postfix.service

Edit /etc/dovecot/conf.d/10-master.conf, uncomment the following lines, and then restart Dovecot:

unix_listener /var/spool/postfix/private/auth {
 mode = 0666

Edit /etc/postfix/, uncomment the line for the submission service, and restart Postfix. This makes Postfix listen on port 587 which is allowed through firewalls.

From another system (IE not the virtual machine you are working on) run “swaks -f -t YOURADDRESS -s -tls -tlsp tlsv1_3” (where YOURADDRESS is an address you use) and note that the message is rejected with “Relay access denied“.

Now run “swaks -f -t YOURADDRESS -s -tls -tlsp tlsv1_3 --auth-user test --auth-password WHATEVER and note that the message is accepted and observe that the mail is delivered (subject to anti-spam measures at the recipient).

Configuring a MUA

If every part of the previous 3 sections is complete then you should be able to setup your favourite MUA. Use “test” as the user-name for SMTP and IMAP, for the SMTP/IMAP server and it should just work!

Note that as the VMs I run are only accessible by SMTP and IMAP over IPv6 you need to have IPv6 on your workstation to connect. If you don’t have IPv6 then run a text mode MUA such as mutt on the VM.

Anti Spam

  1. Header checks allows rejecting mail based on known bad headers (such as blocking known spammers.
    1. Run the following command to send a test message (should work):
      swaks -f -t -s localhost
    2. Create the file /etc/postfix/header_checks with the following contents:
      /^From:.* REJECT

      This consists of a regular expression matching a header line and a policy (generally only REJECT makes sense).

    3. Run the following commands to enable it:
      postconf -e header_checks=regexp:/etc/postfix/header_checks
      systemctl restart postfix.service
    4. Test it with the following swaks command that should be rejected:
      swaks -f -t -s localhost
    1. Run the following command to install the postfix-policyd-spf-python package, this is a daemon that is launched by the Postfix master process for the use of other Postfix processes:
      apt install postfix-policyd-spf-python
    2. Add the following line to /etc/postfix/
      policyd-spf  unix  -       n       n       -       0       spawn user=policyd-spf argv=/usr/bin/policyd-spf
    3. Run the following command to set the smtpd_recipient_restrictions (which hasn’t been set previously in this exercise):
      postconf -e smtpd_recipient_restrictions=permit_sasl_authenticated,permit_mynetworks,check_policy_service unix:private/policyd-spf,reject_unauth_destination
    4. Then restart postfix and SPF checks will be enabled.
    1. Run the following command to install SpamAssassin packages:
      apt install spamassassin spamc spamass-milter
    2. Configure Postfix to use SpamAssassin as a milter (a mail filter program supporting the Milter interface from Sendmail):
      postconf -e smtpd_milters=unix:/var/spool/postfix/spamass/spamass.sock
    3. Edit /etc/default/spamass-milter and set the following as the OPTIONS line:
      OPTIONS="-u spamass-milter -i -r 5 -- -s 100485760"

      This sets a SpamAssassin score of 5 be the criteria for rejecting mail (the default for the SpamAssassin spamd daemon, spamass-milter should match spamd in this regard) and sets 10MB as the amount of data to be scanned in a message (the default is that mail that isn’t small bypasses some tests, the -s option is passed to spamc the SpamAssassin utility that talks to the daemon. Note that any typo in this line will cause things to break in unexpected ways that are difficult to debug.

    4. Run the following commands to restart all daemons and then test sending mail:
      systemctl restart spamassassin.service
      systemctl restart spamass-milter.service
      systemctl restart postfix.service
    5. Get the GTUBE spam test and try sending it to verify that spam mail is rejected:
      apt install wget
      cd /tmp
      swaks -f -t -s --body /tmp/gtube.txt

      This message should be rejected because GTUBE is a standard pattern for testing anti-spam systems.

    1. Run the following command to install DKIM packages:
      apt install opendkim opendkim-tools


ETBE Mon is my fork of the traditional Unix system and network monitoring system “Mon” by Jim Trocki. My aim with this fork is to take the best patches available for the existing Mon codebase and the best “contrib” monitoring scripts and include them in one package. I also aim to write all scripts necessary for typical Linux systems. I don’t believe that a working system should involve “mon”, “mon-contrib”, and searching the net for scripts, it should be just the etbemon package.


The Mon mailing list is at [1] . Please use the list instead of mailing me directly so other people can benefit from the answers.

I have created a Wiki for documenting etbemon [2].

If you need commercial support for Mon that is available too. As a basic offer for $100US by Paypal I’ll write a basic monitor script for any Linux service or RFC standard service. If there’s any other commercial support you want then just ask.


  • Version 1.3.6. Added dell-temp.monitor and hp-temp.monitor to monitor server temperatures. Add -x option to ps.monitor to find process name according to Perl. Make it compile with glibc 2.32. Add selinux.monitor. Add -M option to smartctl.monitor for MegaRAID AKA PERC support and added support for NVMe devices. Improvements to imapnew.monitor deleted-mapped.monitor. Make loadavg.monitor use PSI and cgroups for more useful info.
  • Version 1.3.5. Added monitor for SMART data (smartctl). Made the sslcert check search all IPv6 and IPv4 addresses for each hostname. Make freespace check look for filesystem mountpoint. Made smtpswaks check use latest swaks command-line.
  • Version 1.3.4. Added monitor for deleted mapped files.
  • Version 1.3.3. Improved sslcert.monitor, smtpswaks.monitor, and mailxmpp.alert.
  • Version 1.3.2. Improved http.monitor, dns.monitor, zfs.monitor, freespace.monitor, sslcert.monitor, loadavg.monitor, and mailxmpp.alert. Also improved systemd support.
  • Version 1.3.1. Improvements to freespace.monitor, remote.monitor, loadavg.monitor, and msql-mysql.monitor. Increased the summary length for monshow.
  • This is the first release, numbered 1.3.0 to be higher than other releases of Mon. It is the same as the Debian version of Mon 1.2.0 (which had a dozen patches against Trocki Mon 1.2.0 from 2010).


ZFS Training Exercises

In 2015 I ran a training session on BTRFS and ZFS. Here are the notes for ZFS updated for the latest versions of everything when running on KVM. You can do all the same exercises on a non virtual machine, but it’s safest not to do this on a machine with important data. For the KVM setup I use /dev/vdc, /dev/vdd, and /dev/vde are the devices for test data.

For running ZFS on Linux in serious use I recommend having more than 4G of RAM in the system or VM that’s doing it to prevent kernel OOM issues. You should be able to complete this training exercise on a 64bit VM with 2G of RAM. To do this on Debian/Buster just replace the references to “bullseye” with “buster” in the APT configuration.

  1. Installing zfsonlinux on Debian/Bullseye
    1. Note that /etc/apt/sources.list has the following lines (the “contrib” is very important):
      deb bullseye-updates contrib main
      deb bullseye-backports contrib main
    2. Run the following commands:
      apt install linux-headers-amd64
      apt install -t bullseye-backports dkms spl-dkms zfs-dkms
      apt install -t bullseye-backports zfsutils-linux
      The apt command installing spl-dkms takes ages, 4 minutes real time and 9 minutes CPU time on my last test on a 4 core VM. It will take much longer if several people are doing it at the same time.
  2. Making the filesystem
    1. Create the pool:
      zpool create -o ashift=12 nyancat raidz /dev/vdc /dev/vdd /dev/vde
      NB You need to add a “-f” to overwrite the BTRFS filesystem
    2. Make some default filesystem settings:
      zfs set devices=off nyancat
      zfs set atime=off nyancat
      zfs set setuid=off nyancat
      zfs set compression=on nyancat
    3. Get information on the pool:
      zfs get all nyancat|less
      zpool list
      zpool status
    4. Make a filesystem:
      zfs create nyancat/friday
      df -h
    5. See if there are any errors, shouldn’t be any (yet):
      zpool scrub nyancat
      zpool status
    6. Copy some files to the filesystem:
      cp -r /usr /nyancat/friday
    7. Scrub the filesystem:
      zpool scrub nyancat
      zpool status
    1. Online corruption

    2. Corrupt the filesystem:
      dd if=/dev/zero of=/dev/vdd bs=1024k count=2000 seek=50
    3. Scrub again, should give a warning about errors:
      zpool scrub nyancat
      zpool status
    4. Verify that the data is intact:
      diff -ru /usr /nyancat/friday/usr
    5. Corrupt it again:
      dd if=/dev/zero of=/dev/vdd bs=1024k count=2000 seek=50
    6. Unmount the ZFS filesystems and export (stop using) the zpool:
      zfs umount -a
      zpool export -a
      zpool status
    7. “Import” the pool, mount the filesystems, and note that the checksum error count is back to zero (it counts since the last mount not for all time – unlike BTRFS):
      zpool import -a
      zfs mount -a
      zpool status
    8. Check that the data is still intact and look for increases in the error count:
      zpool status
      diff -ru /usr /nyancat/friday/usr
      zpool status
    1. Offline corruption

    2. Umount the filesystem and corrupt the start of one device:
      zfs umount -a
      zpool export -a
      dd if=/dev/zero of=/dev/vdd bs=1024k count=200
    3. Try mounting it again which will work even though one block device is unavailable:
      zpool import -a
      zpool status
    4. Replace the missing device, look for the device name in the “zpool status” output to replace “123456789” in the following sample command:
      zpool replace -f nyancat 123456789 /dev/vdd
    5. Check that everything is ok:
      zpool status
      diff -ru /usr /nyancat/friday/usr

BTRFS Training Exercises

In 2015 I ran a training session on BTRFS and ZFS. Here are the notes for BTRFS updated for the latest versions of everything when running on KVM. You can do all the same exercises on a non virtual machine, but it’s safest not to do this on a machine with important data. For the KVM setup I use /dev/vdc and /dev/vdd are the devices for test data.

On a Debian Buster or Bullseye system all that you need to do to get ready for this is to install the btrfs-progs package.

  1. Making the filesystem
    1. Make the filesystem, this makes a filesystem that spans 2 devices (note you must use the-f option if there was already a filesystem on those devices):
      mkfs.btrfs /dev/vdc /dev/vdd
    2. Use file(1) to see basic data from the superblocks:
      file -s /dev/vdc /dev/vdd
    3. Mount the filesystem (can mount either block device, the kernel knows they belong together):
      mount /dev/vdd /mnt/tmp
    4. See a BTRFS df of the filesystem, shows what type of RAID is used (note the use of “single” IE RAID-0 for data):
      btrfs filesystem df /mnt/tmp
    5. See more information about FS device use:
      btrfs filesystem show /mnt/tmp
    6. Balance the filesystem to change it to RAID-1 and verify the change, note that some parts of the filesystem were single and RAID-0 before this change):
      btrfs balance start -dconvert=raid1 -mconvert=raid1 -sconvert=raid1 --force /mnt/tmp
      btrfs filesystem df /mnt/tmp
    7. See if there are any errors, shouldn’t be any (yet):
      btrfs device stats /mnt/tmp
    8. Copy some files to the filesystem:
      cp -r /usr /mnt/tmp
    9. Check the filesystem for basic consistency (only checks checksums):
      btrfs scrub start -B -d /mnt/tmp
  2. Online corruption
    1. Corrupt the filesystem:
      dd if=/dev/zero of=/dev/vdd bs=1024k count=2000 seek=50
    2. Scrub again, should give a warning about errors:
      btrfs scrub start -B /mnt/tmp
    3. Check error count:
      btrfs device stats /mnt/tmp
    4. Corrupt it again:
      dd if=/dev/zero of=/dev/vdd bs=1024k count=2000 seek=50
    5. Unmount it:
      umount /mnt/tmp
    6. In another terminal follow the kernel log:
      tail -f /var/log/kern.log
    7. Mount it again and observe it reporting (and maybe correcting) errors on mount:
      mount /dev/vdd /mnt/tmp
    8. Run a diff, observe kernel error messages and observe that diff reports no file differences:
      diff -ru /usr /mnt/tmp/usr/
    9. Run another diff, you probably won’t observe kernel error messages as all errors in data read by diff were probably fixed in the previous run. Observe that diff reports no file differences:
      diff -ru /usr /mnt/tmp/usr/
    10. Run another scrub, this may correct some errors which weren’t discovered by diff:
      btrfs scrub start -B -d /mnt/tmp
  3. Offline corruption
    1. Umount the filesystem, corrupt the start, then try mounting it again which will fail because the superblocks were wiped:
      umount /mnt/tmp
      dd if=/dev/zero of=/dev/vdd bs=1024k count=200
      mount /dev/vdd /mnt/tmp
      mount /dev/vdc /mnt/tmp
    2. Note that the filesystem was not mountable due to a lack of a superblock. It might be possible to recover from this but that’s more advanced so we will restore the RAID.
      Mount the filesystem in a degraded RAID mode, this allows full operation.
      mount /dev/vdc /mnt/tmp -o degraded
    3. Add /dev/vdd back to the RAID:
      btrfs device add /dev/vdd /mnt/tmp
    4. Show the filesystem devices, observe that vdd is listed twice, the missing device and the one that was just added:
      btrfs filesystem show /mnt/tmp
    5. Remove the missing device and observe the change:
      btrfs device delete missing /mnt/tmp
      btrfs filesystem show /mnt/tmp
    6. Balance the filesystem, not sure this is necessary but it’s good practice to do it when in doubt:
      btrfs balance start /mnt/tmp
    7. Umount and mount it, note that the degraded option is not needed:
      umount /mnt/tmp
      mount /dev/vdc /mnt/tmp
  4. Compression
    1. Get the properties of the root of the btrfs filesystem, set it to zstd compression (which is inherited when creating subdirectories) and inspect the change:
      btrfs property get /mnt/tmp
      btrfs property set /mnt/tmp compression zstd
      btrfs property get /mnt/tmp
    2. View the space used, convert the filesystem to zstd compression, and view the new space used:
      df -h /mnt/tmp
      btrfs filesystem defrag -czstd -r /mnt/tmp
      df -h /mnt/tmp

  5. Experiment
    1. Experiment with the “btrfs subvolume create” and “btrfs subvolume delete” commands (which act like mkdir and rmdir).
    2. Experiment with “btrfs subvolume snapshot SOURCE DEST” and “btrfs subvolume snapshot -r SOURCE DEST” for creating regular and read-only snapshots of other subvolumes (including the root).


This is a program I wrote to benchmark SMTP servers. I started work on this because I need to know which mail server will give the best performance with more than 1,000,000 users. I have decided to release it under the GPL because there is no benefit in keeping the source secret, and the world needs to know which mail servers perform well and which don’t!

At the OSDC conference in 2006 I presented a paper on mail relay performance based on the new BHM program that is now part of Postal.

I have a Postal category on my main blog that I use for a variety of news related to Postal. This post (which will be updated periodically) will be the main reference page for the software. Please use the comments section for bug reports and feature requests.

It works by taking a list of email addresses to use as FROM and TO addresses. I originally used a template to generate the list of users because if each email address takes 30 bytes of storage then 3,000,000 accounts would take 90M of RAM which would be more than the memory in the test machine I was using at the time. Since that time the RAM size in commodity machines has increased far faster than the size of ISP mail servers so I removed the template feature (which seemed to confuse many people).

When sending the mail the subject and body will be random data. A header field X-Postal will be used so that procmail can easily filter out such email just in case you accidentally put your own email address as one of the test addresses. ;)

I have now added two new programs to the suite, postal-list, and rabid. Postal-list will list all the possible expansions for an
account name (used for creating a list of accounts to create on your test server). Rabid is the mad Biff, it is a POP benchmark.

Postal now adds a MD5 checksum in the header X-PostalHash to all messages it sends (checksum is over the Subject, Date, Message-ID, From, and To headers and the message body including the “\r\n” that ends each line of text in the SMTP protocol). Rabid now checks the MD5 checksum and displays error messages when it doesn’t match.

I have added rate limiting support in Rabid and Postal. This means that you can specify that these programs send a specific number of messages and perform a specific number of POP connections per minute respectively. This should make it easy to determine the amount of system resources that are used by a particular volume of traffic. Also if you want to run performance analysis software to determine what the bottlenecks are on your mail server then you could set Postal and Rabid to only use half the maximum speed (so the CPU and disk usage of the analysis software won’t impact on the mail server).

I will not release a 1.0 version until the following features are implemented:

  • Matching email sent by Postal and mail received by BHM and Rabid to ensure that each message is delivered correctly (no repeats and no corruption)
  • IMAP support in Rabid that works
  • Support for simulating large numbers of source addresses in Postal. This needs to support at least 2^24 addresses so it is entirely impractical to have so many IP addresses permanently assigned to the test machine.
  • Support for simulating slow servers in Postal and BHM (probably reducing TCP window size and delaying read() calls)
  • Making BHM simulate the more common anti-spam measures that are in use to determine the impact that they have on list servers
  • Determining a solution to the problem of benchmarking DNS servers. This may mean just including documentation on how to simulate the use patterns of a mail server using someone else’s DNS benchmark, but may mean writing my own DNS benchmark.

Here are links to download the source:

  • postal-0.76.tgz – #define PATH_MAX if it’s not already defined, for HURD.
  • postal-0.75.tgz – Fix some compiler warnings. Stop autoconf controlling stripping. Add -b option to bind to an address to bhm. Do not #include when unnecessary.
    Stop linking against libgcrypt. Build against GnuTLS v3. Fix buffer underrun. Made it build with GCC-6.
  • postal-0.73.tgz – Make postal correctly issue the quit command after delivery failure. Fixed a bunch of valgrind errors. Fixed a nasty bug with tab separated fields.
  • postal-0.72.tgz – made LMTP work and accept TAB as a field delimiter.
  • postal-0.71.tgz – rewrote the md5 checking code and fixed lots of little bugs.
  • postal-0.70.tgz – tidied up the man pages and made it build without SSL support.
  • postal-0.69.tgz – fixed some compile warnings, and really made it compile with GCC 4.3
  • postal-0.68.tgz – fixed some compile warnings, made it compile with GCC 4.3, and I think I made it compile correctly with OpenSolaris.
  • postal-0.67.tgz – changed the license to GPL 3
  • postal-0.66.tgz – made GNUTLS work in BHM and added MessageId to Postal.
  • postal-0.65.tgz – significant improvement, many new features and many bugs fixed!
  • postal-0.62.tgz – Slightly improved the installation documents and made it build with GCC 3.2.
  • postal-0.61.tgz – version 0.61. Fixed the bug with optind that stopped it working on BSD systems, and a few other minor bugs.
  • postal-0.60.tgz – version 0.60. Fixed the POP deletion bug, made it compile with GCC 3.0, and added logging of all network IO to disk.
  • postal-0.59.tgz – version 0.59.
  • postal-0.58.tgz – version 0.58. Added some new autoconf stuff, RPM build support, and the first steps to OS/2 and Win32 portability.
  • postal-0.57.tgz – version 0.57. Fixed lots of trivial bugs and some BSD portability issues.
  • postal-0.56.tgz – version 0.56. Added Solaris package manager support. Made it compile without SSL. Added heaps of autoconf stuff.
  • postal-0.55.tgz – version 0.55. Made Rabid work with POP servers that support the CAPA command. Fixed some compile problems on Solaris.
  • postal-0.54.tgz – version 0.54. Added a ./configure option to turn off name expansion (for systems with buggy regex). Fixed a locking bug that allowed Rabid to access the same account through two threads.
  • postal-0.53.tgz – version 0.53. Don’t use NIS domain name etc for SMTP protocol.
  • postal-0.52.tgz – version 0.52. Better portability with autoconf.
  • postal-0.51.tgz – version 0.51. Supports compiling without SSL and some hacky Solaris support.
  • postal-0.50.tgz – version 0.50. Adds SSL support to Postal (Rabid comes next).

RAM Speed according to Memtest86+

Here are some speed results for RAM according to Memtest86+ on some machines that I have run. Note that the reported speed varies between runs by a few percent.

Thinkpad 600e PentiumII 400Mhz PC-66 RAM (2 DIMMs) 174MB/s
Compaq P3-866MHz PC133 RAM (3 DIMMs, 2*128 + 256) 190MB/s
Compaq Athlon 1GHz PC133 RAM (3 DIMMs) 219MB/s
Compaq P3-800MHz PC133 RAM (1 DIMM) 270MB/s
Compaq P3-800MHz PC133 RAM (3 DIMMs, 2*128 + 256) 240MB/s
Compaq P4 1.5GHz PC133 RAM (3 DIMMs) 486MB/s
Compaq P4 1.5GHz PC133 RAM (1 or 2 DIMMs) 490MB/s
EeePC 701, DDR2-665 PC2-5300 running at DDR2-333 speed 798MB/s
HP Celeron 1.8GHz PC2100/DDR266 (1 DIMM) 824MB/s
HP Celeron 2.4GHz PC2100/DDR266 RAM (2 DIMMs) 984MB/s
Celeron D (32bit) 2.93GHz PC2400/DDR300 PC3200 RAM 1,140MB/s
HP Celeron 2.4GHz PC2700/DDR333 RAM (2 DIMMs) 1,027MB/s
HP Celeron 2.4GHz PC2700/DDR333 RAM (2 DIMMs) 1,375MB/s
Dell PowerEdge T105 Dual-core Opteron 1212 (2GHz) single DDR2-667 ECC RAM 1,670MB/s
Dell PowerEdge T105 Dual-core Opteron 1212 (2GHz) pair of DDR2-667 ECC RAM 1,826MB/s
NEC Pentium E2160 1.8GHz DDR663 (two mismatched DIMMs) 2,307MB/s
IBM Pentium E2160 1.8GHz DDR2-667 PC2-5300 (single DIMM) 2,371MB/s
IBM Pentium E2160 1.8GHz PC2-4200 (paired DIMMs) 2,436MB/s
NEC Pentium E4600 2.4GHz DDR2-667 PC2-5300 (single DIMM) 2,528MB/s
NEC Pentium D 2.8GHz DDR 533 (unpaired DIMMS) 1,600MB/s
NEC Pentium D 2.8GHz DDR 533 (paired DIMMS) 2,600MB/s
Thinkpad T61 DDR2-665 PC2-5300 (single DIMM) 2,023MB/s
Thinkpad T61 DDR2-665 PC2-5300 (paired or mismatched DIMMs) 2,823MB/s
Core Gen2 2492MHz 3,804MB/s
Core Gen2 2492MHz 2 DIMMs 3,930MB/s
Q8400 2*PC6400 4,830MB/s
Dell PowerEdge T320 E5-2430 2.2GHz, DDR3-1600 PC3-12800 (single DIMM) 7,692MB/s
Intel X3450 2.67GHz, DDR3-1066 (4 DIMMs) 10.0GB/s
Dell PowerEdge T320 E5-2430 2.2GHz, DDR3-1600 PC3-12800 (pair DIMMs) 11.3GB/s
Dell PowerEdge T30 Core E3-1225 3.3GHz, DDR4-2133 PC4-17000 (single DIMM) 12.5GB/s
Dell PowerEdge T320 E5-2430 2.2GHz, DDR3-1600 PC3-12800 (3 DIMMs) 12.6GB/s
Dell PowerEdge T320 E5-2430 2.2GHz, DDR3-1600 PC3-12800 (3 DIMMs) 13.5GB/s
i7-2600 3.4GHz, DDR3-1333 PC3-10600 (paired DIMMs) 16.6GB/s
Dell PowerEdge T110-II Core i3-3220 3.3GHz, DDR3-1600 PC3-12800 (paired DIMMs) 17.9GB/s

The Wikipedia page on SDRAM lists the theoretical speeds and the various names of the different types of DDR RAM (each type seems to have at least two names).

DDR266 theoretically can do 2100MB/s, but I’ve only seen it do 984MB/s (with two DIMMs).


This version starts the re-write of Bonnie++! I will make it totally threaded (the new code does not use fork()). It will also support testing with a specified number of threads doing the same test, this will allow you to really thrash those RAID arrays!

  • bonnie++-2.00a.tgz – fixed a column assignment issue in bon_csv2html and called it 2.00a because 1.9x hasn’t changed much for years and because I stuffed up the first release of 2.00.
  • bonnie++-1.98.tgz – Allow specifying the number of random seeks and the number of seeker processes and store that in the CSV (for testing NVMe). Changed the text output to use KiB/MiB/GiB as units of measurement so we can fit NVMe results on screen.
  • bonnie++-1.97.3.tgz – man page fixes, fixed symlink test, and CSS fix for bon_csv2html.
  • bonnie++-1.97.2.tgz – make it build with GCC-6 and fix some Debian bugs.
  • bonnie++-1.97.tgz – fixed a bunch of bugs including bad CSV output.
  • bonnie++-1.96.tgz – fixed a bunch of bugs and got the colors working correctly in the HTML output.
  • bonnie++-1.95.tgz – support direct IO and made some changes to the build process (including dropping NT and OS/2 support).
  • bonnie++-1.94.tgz – major improvements to zcav.
  • bonnie++-1.93d.tgz – added write support to ZCAV.
  • bonnie++-1.93c.tgz – added support for GCC 3.2.
  • bonnie++-1.93b.tgz – version 1.93b. Fixed an error in calculating seek time and added support for large numbers of directories for the file creation tests.
  • bonnie++-1.93a.tgz – version 1.93a. Better support of NT, better RPM packaging code, and a minor warning fix.
  • bonnie++-1.93.tgz – version 1.93. Added a new test program for per-char IO for the people on the linux-kernel mailing list. ;)
  • bonnie++1.92b.tgz – version 1.92b. Fixed a bunch of bugs in the random seed selection code.
  • bonnie++1.92a.tgz – version 1.92a. Added support for setting the seed for random numbers and fixed a few bugs.
  • bonnie++1.92.tgz – version 1.92. Changed the code to do per-char tests with read() and write() instead. Now reports much lower results for those tests which are more useful IMHO.
  • bonnie++1.91c.tgz – version 1.91c, it now compiles with namespace support in GCC 3.0 and fixed some minor bugs.
  • bonnie++1.91b.tgz – version 1.91b
  • bonnie++1.91a.tgz – version 1.91a, fixed zcav properly and fixed a bunch of minor bugs in Bonnie++.
  • bonnie++1.91.tgz – version 1.91, fixes all known bugs in the 1.90 series.
  • bonnie++1.90g.tgz – version 1.90g, now latency works properly and always gets parsed properly. Changed the -f option to allow tests of per-char IO for small amounts of data.
  • bonnie++1.90f.tgz – version 1.90f, more work on latency in bonnie++ and some slight changes for OS/2 and NT portability.
  • bonnie++1.90e.tgz – version 1.90e, better OS/2 and NT support.
  • bonnie++1.90d.tgz – version 1.90d, contains code from the OS/2 and NT ports, may break things for some versions of UNIX.
  • bonnie++1.90c.tgz – version 1.90c, produces better web pages (full color) with bon_csv2html.
  • bonnie++1.90b.tgz – version 1.90b, adds support for measuring latency.
  • bonnie++1.90a.tgz – version 1.90a, adds basic threading, changes the format of the CSV files, and updates the programs for managing CSV files (and the man pages).

My Programming Profile

Job adverts are asking for a Github or Stack Overflow account nowadays, I don’t use those sites much so here’s a list of comparable resources:

Here is my list of Debian packages with their QA status. I’ve been a Debian Developer since November 2000.

Here is my Salsa profile, Salsa is the Debian equivalent to Github (using Gitlab software). My account shows as active since 2017 because Salsa was created in 2017.

Here is a list of Projects that I’m the primary maintainer of.

Here are some of the papers I’ve presented at conferences.