Come hack Perl for Best Practical! (We're hiring)

3 min read

About us

We're Best Practical Solutions, a small software company located in Somerville, MA. We build software and sell support, training, consulting, and custom development. Our main product, RT (Request Tracker), is the premiere open source issue tracking system. We've been around since the fall of 2001 and are entirely self-funded. We're currently hard at work on our next new product. Things just keep getting busier.

About the job

We're looking for a Perl Hacker to help us enhance and refine our products, and help us be excellent to our customers. You'll be responsible for everything from implementing new features across all our products to testing and applying user-contributed patches to our released software. In a typical week, you'll probably spend about half your time working on customer projects and half working on internal and open source projects.

The hours are flexible and we all telecommute some of the time...though we work from our office in the heart of Davis Sq, Somerville, most days. We do just about EVERYTHING online and on the phone. You should be comfortable using email and instant messaging systems to collaborate and get work done.

About you

You should be a self-starter who has some experience with Perl, as well as a bit of experience with at least a few of the following:

  • Open source development practices
  • Distributed source control
  • Test driven development
  • User interface design
  • Documentation
  • Javascript
  • SQL databases
  • Optimization, profiling, and debugging
  • UNIX systems administration

It's okay if you don't know everything out of the gate, but you should be able to learn on the fly and be comfortable asking questions when you get in over your head. RT is a large codebase to dive into, so you should be prepared to work with a project that's too big to hold in your head at once. If you want to see what sort of trouble you're getting yourself into, you can find all of our open source code

We're a small company and the boss is typically overextended. You should be comfortable working both independently and in small teams, prioritizing tasks on your own, and juggling tasks and projects.


DOE - This is a full-time salaried position, but the details are negotiable. We're a small, self funded company. The standard benefits apply, of course: health insurance, dental insurance, and junk food to make that dental insurance worthwhile.

How to apply

Send something approximating a cover letter, and a resume in plain text, HTML or PDF, and a sample of some code you've written to If you're involved in open source development of one kind or another, please tell us about it. If you have a CPAN ID, tell us what it is. We won't consider applications without a code sample. We'll be paying particular attention to the readability, comments and tests.


K-9 Mail 3.600 for Android

4 min read

It gives me great pleasure to announce the release of version 3.600 of K-9 Mail.  Notable in this release are significant performance improvements and proper support for replying to / forwarding HTML mail.

While K-9 was originally "my fault", its continued success wouldn't be possible without the hard work of a number of contributors and committers.  At the risk of accidentally leaving out any recent contributor, I'd particularly like to thank (in alphabetical order): 

    achen.code, cketti, fiouzy, hiranotaka, jca02266, kris.p.wong, and marcus.wolschon

Their bug triage and commits are a big part of why K-9 is as wonderful as it is.

A rough changelog of "important" updates in K-9 3.6 follows:


  • Restore "only vibrate once" vibration notification option.
  • Add a setting to enable Outlook-style message quoting.
  • Add a setting to allow users to always show email addresses instead of the "friendly" parts of email addresses.
  • Add a setting to disable unread count in notification bar.
  • Add a setting to change the font size of the message preview in the message list. Fixes  issue 2788 

User Interface

  • Round account color chips
  • Be a little more graceful when scrolling horizontally in a (vertical) scroll view. Not quite to the point of diagonal scrolling, but hopefully closer.
  • Visual cleanup to Message Lists, Message views
  • Stop showing "Not polling" in the status header. Most of the time, this is because Push mail is enabled.
  • Improve the first page of the wizard on tablet-scale devices


  • Added a Brazilian Portugese translation from Marcio Viterbo
  • Updated Italian translation from Giuseppe Arrigo and Paolo Maccione. Fixes  issue 2778 
  • Updated Czech translation from lubekgc. Fixes  issue 2808 
  • Updated German translation with slightly modified version of the patch provided by OliverMe?
  • Updated Italian translation from paolo.maccione
  • Updated Spanish translation from Adolfo Gutiérrez Ocaña
  • Improved emoji support for a wide variety of carriers. HIRANO Takahito
  • Support for emoji in message subjects. HIRANO Takahito
  • Allow emoji input on Japanese devices. HIRANO Takahito
  • Implement phonetic search of Contacts on Eclair and earlier.


  • Upgrade to a newer version of MIME4J to gain significant performance improvements from the past few years of development
  • Enable Strict Mode when a new "developer mode" is enabled and we're running on 2.3 or newer
  • Update URL regexes by importing from AOSP and then from IANA
  • Initial implementation of folder attributes on the folder, rather than in preferences
  • Improve generation of plain text versions of HTML mail
  • Improve generation of message previews


  • Improve performance of account statistics generation.
  • Call the routine to convert emoji to images only when a message actually contains emoji.
  • Batch storing of unsynced messages to speed up DB update (chunk size set to 5).
  • Execute LocalMessage?.appendMessage() & LocalMessage?.setFlag() in the same transaction for small message storing in order to speed up DB update.


  • Disable webview cache and javascript.


  • When mail is sent successfully, cancel the "couldn't send mail" notification
  • Don't notify for new mail in a designated spam folder
  • Prevent new mail notifications for IMAP messages older than our most recent message.
  • Use a heuristic to try to avoid notifying POP3 users about older mail messages

Sending mail

  • Preserve HTML formatting when replying to or forwarding HTML mail
  • Clean up the display of quoted messages on the mail composition screen.
  • When editing a previously saved draft, only show the BCC field if it has entries other than the auto-bcc for that account.
  • Switch from generating X-User-Agent to User-Agent headers. Fixes  issue 1917 

Account setup

  • Use full email addresses as usernames for alternate Yahoo! domains.
  • Add support for other Yahoo! domains (,
  • Set up some reasonableish defaults for which folders to sync when creating a new account.


  • Correctly encode/escape strings when used in IMAP commands. Fixes  issue 2832 
  • Escape backslashes in IMAP mailbox names
  • Fix for the "K9 skips every 101st message when fetching on IMAP" bug by e-t172 . Fixes  Issue 2819 
  • Better handle the case where a list in an IMAP response is prematurely ended by CRLF. Fixes  issue 2852 


  • Changed SMTP code to handle reply codes without additional text. Fixes  issue 2801 
  • Try using IP addresses for EHLO if the local hostname is unavailable. Only use a default hostname if the IP address is unavailable. ref r2958 issue 2750 .



  • Fix usage of 'advanced' exchange settings.
  • Fix form based re-authentication when logon cookies had expired.


  • Don't reset visible limits every time K-9 is opened, only when the user changes how many messages they want to be synced.



Froyo for nookcolor

16 min read



If you've read my blog for a while, you've probably seen my unfortunate interactions with Barnes and Noble trying to buy a nook last Christmas. You've also probably seen some of my Kindle hacking and Android development work.

The big takeaway from last Christmas was "don't by a nook"

The nookcolor is B&N's latest - a 7 inch eReader.

Calling it an eReader is somewhat disingenuous. It's somewhat different from the original nook:

  • No 3G
  • No E Ink screen
  • 50% heavier than the original nook

Like the original nook, it's running Android. It has a microSD slot. And it's been rooted. (Not by me.)

I've been on the road for work a lot lately. That usually means I have rather a lot of time to kill in the evenings. Last Wednesday night, I found myself in a Barnes & Noble store in Northern Virginia. I wanted to check out the new nookcolor, but, well, I wasn't about to give Barnes & Noble any more of my money.

I walked in the front door to find one of the booksellers standing in front of the nook kisok messing around with the nookcolor. I asked if I could play with it for a moment.

As I popped into the Setttings menu, she started to tell me about the device. I'm...not quite sure how it happened, but some of the first words out of her mouth were "It's been rooted, you know."

I guess I look the part.

I played with the device for a while. It felt reasonably solid and was impressively speedy. The bookseller (I've forgotten her name :/) started talking about how much she was looking forward to a community port of Froyo.

My resolve began to weaken, but I knew that I knew nothing about the internals of the device and I wasn't about to buy another Android tablet with an anemic CPU. (I bought a ZT-180 from China and dropped my PixelQi display into it, just to see if it would work. I bought a Viewsonic G Tablet a couple weeks ago with the same intent, but haven't fully disassembled it to get to the display yet.)

I played my get out of jail free card: "So, uh, I suspect that this isn't the typical sort of question you get about the nookcolor, but how fast is the CPU?"

"It's 800MHz."

I bought one. And sat down in the B&N cafe. I used their free wifi to download nooter from nookdevs.

15 minutes later, I had ADW.Launcher, Angry Birds and K-9 Mail installed. Angry Birds was remarkably smooth.

Like everyone else, I spent some time messing around on the device, which identified itself as a "LogicPD zoom2" internally.

"Wow. This is a pretty standard Android device. I wonder how hard a vanilla Android build would be."

Flash forward to Friday.

B&N finally shipped bootloader and kernel source. The source distribution was a zip file containing "Documents and Settings/awu/Desktop/distro.tar"

The content inside the tarball left a bit to be desired. I haven't yet found enough markers to figure out what kernel tree and tag was used as the branchpoint, so I don't know precisely what the local changes are.

I have made reasonable headway on figuring that out, though.

I started reading up on the relevant bits.

Meanwhile, this YouTube video was NOT posted by me:

Over the past couple days, with help from [mbm] on (who did all this before I did ;), I've cobbled together a basic working Froyo userland.

Below is a first pass braindump of what I've done. I'm 100% sure I'm missing steps - and what I have running so far is hardly something I'd want to run full time on my device.

Per usual, what you're doing could turn your device into an expensive paperweight. (It's too flat to make a decent doorstop.)

As nooter (the nookcolor rooting tool) showed us, the nookcolor can boot from SD. In fact, it's set to prefer to boot from SD. This makes development rather less painful than it might otherwise be.

I initially started building a full cleanroom filesystem, but [mbm] convinced me that it's a bit easier to start off with the working nookcolor filesystem image and customize from there. Long term, this is obviously not the right plan.

Root your nookcolor (nc) with nooter.

Download a full filesystem image from the nc. There are a few ways to do this. The fastest is to dd to a local filesystem on the flash card. and mount that on your workstation. The most trivial is:

adb pull /dev/block/mmcblk0 ./nook-8-gig-raw-filesystem

You'll need a MicroSD card of at least 8 gigs to drop this filesystem onto. This will (sort of obviously) obliterate every single bit on that MicroSD.

dd  /dev/sdX

When you pop the MicroSD out and re-insert it, you'll likely see a whole bunch of partitions automount.

Be careful not to distribute this SD image, as the factory partition contains a zip file including a full (proprietary) OS image and the rom partition includes personal device details.

If you stick this into your nc, it should boot to the regular nook image using the boot partition on the MicroSD card.

Right now, the one you REALLY care about is "boot" (On ubuntu, it'll mount as /media/boot). It's a VFAT filesystem on partition 1.

For now, what we care about on that filesystem is uRamdisk, the boot ramdisk. As of this moment, it's set up to mount the nook's internal flash and continue boot from there.

Make a backup of uRamdisk.

uRamdisk is a u-boot filesystem.

You need to unpack it, twiddle some bits and repack it. I have some tools for this, which I'll publish to github as soon as I untangle them from the rest of the nook image in my local repo (Which contains B&N code I can't distribute because it's not obviously under an opensource license).

There's likely a correct way to do this, but the quick-and-dirty way was a bit easier for me to sort out. u-boot ramdisks are gzipped cpio archives with a 64 byte header.

My "unpack" script looks like this:

mkdir work-$$
dd if=$IMAGE of=/tmp/image.cpio.gz bs=64 skip=1
zcat /tmp/image.cpio.gz > work-$$.cpio
cd work-$$
cpio -i -F ../work-$$.cpio
echo "Unpacked ramdisk is in work-$$"

The two files you really care about right now are env.txt and init.rc

Right now, all we care about is twiddling pointers to partitions.

env.txt should look like this:

bootargs=console=ttyS0,115200n8 androidboot.console=ttyS0 root=/dev/mmcblk1p2 rw rootdelay=1 mem=512M init=/init videoout=omap24xxvout omap_vout.video1_numbuffers=6 omap_vout.vid1_static_vrfb_alloc=y omapfb.vram=0:8M
bootcmd=mmc 0 read 0x800 0x81c00000 ${kernel_size}; bootm 81c00000
recovery=echo recovery mode

I've altered the bootcmd's pointer from "mmc 1" to "mmc 0" - this is very much cargo-culting based on the TI docs and not something I've looked at.

Similarly, I've flipped the "root" argument of "bootargs" from mmcblk0p2 to mmcblk1p2. It shouldn't really matter.

EDIT: Turns out this isn't strictly necessary

In init.rc, anywhere the mmcblk0 is mentioned, make it mmcblk1

I also forced adb to always start, just for ease of development.

Now you'll want to repack the ramdisk. My "repack" script looks like this:

DIR="$( basename `pwd`)"
cpio -i -t -F ../${DIR}.cpio | cpio -o -H newc -O ../ramdisk-repacked-${DIR}.cpio
cd ..
gzip ramdisk-repacked-${DIR}.cpio
./mkimage  -A ARM -O Linux -T RAMDisk -C gzip -n Image -d ramdisk-repacked-${DIR}.cpio.gz uRamdisk-${DIR}

mkimage is a standard tool from the u-boot tools directory shipped as part of the B&N nookcolor sourcedrop. I'd assume that the mkimage from any copy of u-boot would be fine.

Once you repack the ramdisk, put it back on the boot partition as uRamdisk.

Umount all the filesystems on the MicroSD, eject the MicroSD and drop it in your nc.

Boot your nc. It should boot normally.

Once it's booted, use adb shell to check that filesystems are mounted from mmcblk1 and not mmcblk0

You can now shutdown your nook.

You have a full OS image on SD.

It's now time for the interesting bit, building Android.

I built from TI's omapzoom branch of Android - They're the folks who make the innermost parts of the nc. should tell you everything you need to know about using repo to clone the repositories, check out froyo and build.

You'll need a crosscompiler. TI recommend:

Follow the instructions for zoom2

Once the build is done, put your MicroSD card back in the nc. This time, you're looking for the system partition (sdX5).

You have two options. You can either wipe out B&N's Android build entirely and install the pristine zoom2 build or you can overlay the zoom2 build on top of B&N's build of Eclair.

I went for the former, though [mbm] had better luck with the latter, as it means you won't have to pick out proprietary libraries and tools and install them one by one.

Obviously, if you use any of the B&N bits, you MUST not distribute your filesystem image. It appears that TI publishes just about every proprietary bit we could possibly want on their GForge instance, though I haven't actually dug in too deep just yet.

You'll want to neuter etc/vold.* on the system partition once you've installed the new image, as it tries to mount an sd card that's now... otherwise occupied.

Once you're done with this, it's time to go back to work on your uRamdisk image, since froyo wants somewhat different startup bits than eclair.

I ended up with something a bit wonky causing mount failures as I was migrating init.rc to froyo. Again, this is courtesy of [mbm]:

	--- ../work-20413/init.rc   2010-12-05 11:22:40.514818375 -0500
+++ init.rc 2010-12-04 21:34:36.209385337 -0500
@@ -1,4 +1,3 @@
-# init.rc used on Encore hardware
on early-init
# Give the kernel time to enumerate the internal and external MMC/SD cards
@@ -16,7 +15,8 @@
export ANDROID_ROOT /system
export ANDROID_ASSETS /system/app
export ANDROID_DATA /data
-    export EXTERNAL_STORAGE /sdcard
+    export EXTERNAL_STORAGE /mnt/sdcard
+    export ASEC_MOUNTPOINT /mnt/asec
export INTERNAL_STORAGE /media
export BOOTCLASSPATH /system/framework/core.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar
export DSP_PATH /system/lib/dsp
@@ -37,16 +37,39 @@
# Backward compatibility
symlink /system/etc /etc
-# create mountpoints and mount tmpfs on sqlite_stmt_journals
+# create mountpoints
+    mkdir /mnt 0775 root system
+    mkdir /mnt/sdcard 0000 system system
+# Create cgroup mount point for cpu accounting
+    mkdir /acct
+    mount cgroup none /acct cpuacct
+    mkdir /acct/uid
+# Backwards Compat - XXX: Going away in G*
+    symlink /mnt/sdcard /sdcard
mkdir /system
-    mkdir /tmp 0777
mkdir /data 0771 system system
mkdir /cache 0770 system cache
mkdir /media 0777 system system
-    mkdir /sdcard 0777 system system
-    mkdir /sqlite_stmt_journals 01777 root root
mkdir /rom 0777 root root
-    mount tmpfs tmpfs /sqlite_stmt_journals size=4m
+    mkdir /config 0500 root root
+    # Directory for putting things only root should see.
+    mkdir /mnt/secure 0700 root root
+    # Directory for staging bindmounts
+    mkdir /mnt/secure/staging 0700 root root
+    # Directory-target for where the secure container
+    # imagefile directory will be bind-mounted
+    mkdir /mnt/secure/asec  0700 root root
+    # Secure container public mount points.
+    mkdir /mnt/asec  0700 root system
+    mount tmpfs tmpfs /mnt/asec mode=0755,gid=1000
mount rootfs rootfs / ro remount
@@ -55,6 +78,46 @@
write /proc/cpu/alignment 4
write /proc/sys/kernel/sched_latency_ns 10000000
write /proc/sys/kernel/sched_wakeup_granularity_ns 2000000
+    write /proc/sys/kernel/sched_compat_yield 1
+    write /proc/sys/kernel/sched_child_runs_first 0
+# Create cgroup mount points for process groups
+    mkdir /dev/cpuctl
+    mount cgroup none /dev/cpuctl cpu
+    chown system system /dev/cpuctl
+    chown system system /dev/cpuctl/tasks
+    chmod 0777 /dev/cpuctl/tasks
+    write /dev/cpuctl/cpu.shares 1024
+    mkdir /dev/cpuctl/fg_boost
+    chown system system /dev/cpuctl/fg_boost/tasks
+    chmod 0777 /dev/cpuctl/fg_boost/tasks
+    write /dev/cpuctl/fg_boost/cpu.shares 1024
+    mkdir /dev/cpuctl/bg_non_interactive
+    chown system system /dev/cpuctl/bg_non_interactive/tasks
+    chmod 0777 /dev/cpuctl/bg_non_interactive/tasks
+    # 5.0 %
+    write /dev/cpuctl/bg_non_interactive/cpu.shares 52
+    # Create dump dir and collect dumps.
+    # Do this before we mount cache so eventually we can use cache for
+    # storing dumps on platforms which do not have a dedicated dump partition.
+    mkdir /data/dontpanic
+    chown root log /data/dontpanic
+    chmod 0750 /data/dontpanic
+    # Collect apanic data, free resources and re-arm trigger
+    copy /proc/apanic_console /data/dontpanic/apanic_console
+    chown root log /data/dontpanic/apanic_console
+    chmod 0640 /data/dontpanic/apanic_console
+    copy /proc/apanic_threads /data/dontpanic/apanic_threads
+    chown root log /data/dontpanic/apanic_threads
+    chmod 0640 /data/dontpanic/apanic_threads
+    write /proc/apanic_console 1
# mount MMC partitions
mount vfat /dev/block/mmcblk1p2 /rom sync noatime nodiratime uid=1000,gid=1000,fmask=117,dmask=007
@@ -382,8 +445,8 @@
service vold /system/bin/vold
socket vold stream 0660 root mount
-#service mountd /system/bin/mountd
-#    socket mountd stream 0660 root mount
+service netd /system/bin/netd
+    socket netd stream 0660 root system
service debuggerd /system/bin/debuggerd
@@ -396,10 +459,13 @@
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
+    onrestart write /sys/power/state on
+    onrestart restart media
service media /system/bin/mediaserver
user media
-    group system audio camera graphics inet net_bt net_bt_admin
+    group system audio camera graphics inet net_bt net_bt_admin net_raw
+    ioprio rt 4
service fw3a /system/bin/fw3a_core
user root
@@ -421,6 +487,37 @@
user bluetooth
group bluetooth net_bt_admin
+service bluetoothd /system/bin/bluetoothd -n
+    socket bluetooth stream 660 bluetooth bluetooth
+    socket dbus_bluetooth stream 660 bluetooth bluetooth
+    # init.rc does not yet support applying capabilities, so run as root and
+    # let bluetoothd drop uid to bluetooth with the right linux capabilities
+    group bluetooth net_bt_admin misc
+    disabled
+service hfag /system/bin/sdptool add --channel=10 HFAG
+    user bluetooth
+    group bluetooth net_bt_admin
+    disabled
+    oneshot
+service hsag /system/bin/sdptool add --channel=11 HSAG
+    user bluetooth
+    group bluetooth net_bt_admin
+    disabled
+    oneshot
+service opush /system/bin/sdptool add --channel=12 OPUSH
+    user bluetooth
+    group bluetooth net_bt_admin
+    disabled
+    oneshot
+service pbap /system/bin/sdptool add --channel=19 PBAP
+    user bluetooth
+    group bluetooth net_bt_admin
+    disabled
+    oneshot
service installd /system/bin/installd
socket installd stream 600 system system
@@ -432,8 +529,6 @@
service ifcfg_ti /system/bin/ifconfig tiwlan0 up
@@ -447,6 +542,19 @@
+service racoon /system/bin/racoon
+    socket racoon stream 600 system system
+    # racoon will setuid to vpn after getting necessary resources.
+    group net_admin
+    disabled
+    oneshot
+service mtpd /system/bin/mtpd
+    socket mtpd stream 600 system system
+    user vpn
+    group vpn net_admin net_raw
+    disabled
+    oneshot
service keystore /system/bin/keystore /data/misc/keystore
user keystore
@@ -463,5 +571,7 @@
service debuglog /system/bin/
user root
+service dumpstate /system/bin/dumpstate -s
+    socket dumpstate stream 0660 shell log
+    disabled
+    oneshot

At this point, (assuming I haven't forgotten anything), you should have a MicroSD that will boot froyo on a nookcolor.

...and then immediately shut down, ostensibly due to power issues. My sneaking suspicion is that this is because the kernel the nc is booting from is B&N's original 2.6.29 image and there's been a bit of skew in how it reads some bit of information out of /proc.

The correct next step is to go and build a proper kernel for the device.

The easy next step is to perform a brutal hackjob on android's batteryservice.


Edit: I have no reason to believe that this is actually likely. But it'd be double-plus irresponsible of me to suggest that turning off a hardware safety feature was a good idea.


	jesse@puppy ~/android-omapzoom/frameworks/base/services ((6c81cb0...) *) $ git diff
diff --git a/services/java/com/android/server/ b/services/java/com/android/server/
index 5cf61bd..bf96479 100644
--- a/services/java/com/android/server/
+++ b/services/java/com/android/server/
@@ -176,8 +176,8 @@ class BatteryService extends Binder {
void systemReady() {
// check our power situation now that it is safe to display the shutdown dialog.
-        shutdownIfNoPower();
-        shutdownIfOverTemp();
+        //shutdownIfNoPower();
+       // shutdownIfOverTemp();
private final void shutdownIfNoPower() {
@@ -210,8 +210,8 @@ class BatteryService extends Binder {
boolean logOutlier = false;
long dischargeDuration = 0;
-        shutdownIfNoPower();
-        shutdownIfOverTemp();
+      //  shutdownIfNoPower();
+        //shutdownIfOverTemp();
mBatteryLevelCritical = mBatteryLevel 

Once you've rebuilt the android core and reinstalled it on your system partition, you should now have something that boots froyo on your nook.

This froyo is VERY MUCH not ready for primetime. Don't expect WIFI, Bluetooth, Google Apps, reasonable performance, sensor access, etc.

TI distributes wifi drivers and all the hardware acceleration you could possibly want:

This all would have taken me a great deal longer without [mbm]'s assistance and advice.

My next steps will (probably) be to try to build a modern kernel from source and see what that does for driver support.

Please note that I don't plan to build a distributable ROM or to port Cyanogenmod, though I'd be thrilled to see someone pick up the torch and do so.

I can't distribute the OS image I have, as it contains a mix of free stuff and proprietary stuff pulled off of my nookcolor's system partitions.

If you're looking to chatter with folks about development for the nookcolor, I'd recommend on

On privacy

1 min read

Not that I'm really posting here much these days, but I don't expect you to limit your responses to me to LJ. If you want to spam your tweeps and faces with your replies to my posts, be my guest.

OSI Model of the Internet - circa 2010

1 min read

(With apologies to Evi Nemeth.)

Pixel Qi

1 min read

Last weekend at foo camp, I got the opportunity to see a Pixel Qi display in person. Yesterday morning, they went up for sale on the Maker Shed. I clicked buy. I bit the bullet and paid for overnight shipping. Last night I popped over to Microcenter and picked up a Samsung N135.

This morning, FedEx delivered a box from Sebastapol.

8 screws and some fiddly plastic bits later, I have a netbook I can use outside. The display is Wow. Just Wow.

Inside, it's a normal laptop display. Outside, it's almost as bright as a Kindle (eInk) screen. Yes, it plays video just fine.


1 min read

Some friends of mine have been hard at work on a social music app called ;MixApp for...a good long time now. They've recently made the jump from desktop clients to a completely in-browser experience. This makes it a lot easier for new users to get started with it.

Since the new UI is all-HTML, it means I can mess around with it using javascript bookmarklets.  If you're a mixapp user and you want a "mini" desktop player, just drag this link to your bookmarks bar. When you're logged into MixApp and click it, the player will minimise.

      Mixapp Miniplayer

Perl 5.12.1

2 min read

"Now suppose," chortled Dr. Breed, enjoying himself, "that there were
many possible ways in which water could crystallize, could freeze.
Suppose that the sort of ice we skate upon and put into highballs—
what we might call ice-one—is only one of several types of ice.
Suppose water always froze as ice-one on Earth because it had never
had a seed to teach it how to form ice-two, ice-three, ice-four
... And suppose," he rapped on his desk with his old hand again,
"that there were one form, which we will call ice-nine—a crystal as
hard as this desk—with a melting point of, let us say, one-hundred
degrees Fahrenheit, or, better still, a melting point of one-hundred-
and-thirty degrees."

-- Kurt Vonnegut, Cat's Cradle

It gives me great pleasure to announce Perl 5.12.1, the second stable release of Perl 5.12.

You can download Perl 5.12.1 from your favorite CPAN mirror or from:

SHA1 digests for this release are:

75a8a17cec15d68c6bb959b0aa9879d2ded6f90d  perl-5.12.1.tar.bz2
83b99f08379782dc06594a85eeb279edc5b0ca44  perl-5.12.1.tar.gz

This release contains minor bug fixes and updates of several core modules, as well as minor documentation updates. It should be fully backward compatible with Perl 5.12.0.

Perl 5.12.1 is a recommended upgrade for all users of Perl 5.12.

You can find a full list of changes in the file "perl5121delta.pod" located in the "pod" directory inside the release and on the web at:

Perl 5.12.1 represents approximately four weeks of development since Perl 5.12.0 and contains approximately 4,000 lines of changes across 142 files from 28 authors.

Perl continues to flourish into its third decade thanks to a vibrant community of users and developers. The following people are known to have contributed the improvements that became Perl 5.12.1:

Ævar Arnfjörð Bjarmason, Chris Williams, chromatic, Craig A. Berry, David Golden, Father Chrysostomos, Florian Ragwitz, Frank Wiegand, Gene Sullivan, Goro Fuji, H.Merijn Brand, James E Keenan, Jan Dubois, Jesse Vincent, Josh ben Jore, Karl Williamson, Leon Brocard, Michael Schwern, Nga Tang Chan, Nicholas Clark, Niko Tyni, Philippe Bruhat, Rafael Garcia-Suarez, Ricardo Signes, Steffen Mueller, Todd Rinaldo, Vincent Pit and Zefram.

We expect to release Perl 5.12.2 in mid-August 2010, followed by Perl 5.12.3 in mid-November. The next major release of Perl 5, 5.14.0 should appear in spring 2011.

Goodbye, old friend.

1 min read

Broadcast message from root@diesel (pts/1) (Mon Mar 22 21:04:25 2010): is being decommissioned.
The system is going down for system halt NOW!
Shared connection to closed.

K-9 Mail 2.400 for Android

4 min read

It gives me great pleasure to announce K-9 Mail 2.400.  This release represents a significant improvement on K-9 Mail 2.000, released in early December.

K-9 Mail is an open-source email client for Android-powered devices. Originally based on the client shipped with Android 1.0, K-9 Mail has seen extensive development by a community of developers around the world over the past 15 months.

Major new features in this release include full-text search of mail, "starring" of messages, the ability to perform actions on multiple messages at once, a much more robust and efficient IMAP push mail implementation, significant performance improvements and a new icon designed by Vincent Lum.

You can download K-9 Mail 2.400 from or from the Android Market.

Other user-visible changes include:

  * Guess mime type (when not specified) of attachments of received messages using file name extension so that we can open them - baolongnt

  * Headers in Accounts, Folder List and Message List now show unread count and background processing activity -- danapple0

  * Added a new "touch friendly" style with message previews - jessev

  * Made it possible to enable or disable "stars" for flagged messages - jessev

  * Added swipe-to-select for operations on multiple messages - jessev

  * There is now an Expunge action in the option menu. - danapple0

  * A new "Batch ops" option menu in Message List.  Provides star/unstar, mark as read/unread and delete and select/deselect all.  Move and copy are partially implemented, but disabled. -danapple0

  * The "Sort by..." menu now toggles ascending/descending when the currently selected sort mode is clicked. -danapple0

  * Eliminate carriage returns from reply and forward text.  (Fixes Issue 518) - danapple0

  * Add a global preference for enabling animations, beyond those that are necessary.  Defaults to "enabled." -danapple0

  * 250, 500 and 1000 messages may now be synced per folder. - jessev

  * Allow user to set a limit on the number of folders to be handled with push technology. - danapple0

  * Initial implementation of CRAM-MD5 support for IMAP and SMTP. (Patch contributed by Russ Weeks ) - jessev

  * For IMAP accounts, it is now possible to disable the copying of deleted messages to the Trash folder, by setting the Trash folder to -NONE-. - danapple0

  * Each IMAP account can be set to expunge messages in a folder as soon as a move or delete is performed on the folder ("immediately"), each time the folder is polled, or only when executed manually. - danapple0

  * For WebDAV accounts, the user can now choose the server-side equivalents of the special folders, just like for IMAP. - danapple0

  * Implemented delete intent broadcast using a modified patch from stephane.lajeunesse - baolongnt

  * Implementation of a Receiver and Service to provide for the capability to accept control from other Android applications.  Allows for changing both Account-level and global settings.  Account-level settings can be applied to a single Account or to all Accounts. - danapple0

  * Overhaul our setup wizard to have a more reasonable bottom bar and to reuse that layout code where possible; standardize the id of the 'next' button - jessev

  * "Starred" messages in MessageList and Message views - jessev

  * Bulk-star, delete and "mark as read" for messages - baolongnt,danapple0,jessev

  * Implement References/In-Reply-To/X-User-Agent headers. Patch from e.w.stemle - jessev

  * You can now "swipe" left or right in the Message view to go to the previous or next message, respectively - jessev

  * First pass at stopping the "Sending messages" notification when there's nothing to send. - jessev

  * fix the header background color to not ignore theme in horizontal mode - jessev

  * Add double-tap at top or bottom of a message to jump to the top or bottom of the message - jessev

  * Improvements to render quality of plaintext messages. - jessev

  * Added a message-flip animation. - jessev

  * New sort-by and reverse-sort icons by Vincent Lum - jessev

  * Deleting messages in messageView now preserves the direction the user was "travelling" in before the delete - jessev

  * Provide additional date format display options in Preferences - danapple0

For a full set of release notes, please visit: