vim completion

I’ve just found something rather useful in vim: :set wildmode. Normally in vim, you can use TAB to complete filenames. So you enter :e some/ve<TAB> and vim pads it out to :e some/very_long_filename.html. Lovely.

But in a directory full of files with similar prefixes, it’s less than helpful. I hit :e acc<TAB> and vim expands to :e acc_click_here_to_continue.html. But then I need to backspace all the way back so it reads :e acc and hit TAB again. This is a pain.

But, if you stick set wildmode=longest,full into ~/.vimrc, then vim stops when it’s completed the longest unique prefix (“acc”) and gives you a chance to type. Or, if you just keep banging on the TAB key like a deranged gibbon it will start rotating through all the possible completions. But by stopping at that point, I get a chance to intervene.

It sounds like a teeny-tiny little thing. But it’s one less thing that’s getting in the way of me doing things.

That said, any time saved has already been wiped out by writing this blog entry. 🙂


Malware removal

I’ve spent a fun evening1 trying to get rid of some insidious malware on the house gaming PC. I think it’s mostly gone, though I’m not certain (and I don’t have the day’s time to reinstall everything). However, I did find some useful stuff along the way.

Firstly, even though googling for something related to the malware will turn up some information about it, chances are that it’s a bloody rootkit that’s thrust itself into the windows kernel like a rhino in heat. So you won’t be able to see, or delete the files it’s talking about.

Finding out problems that are being covered up by the rootkit is greatly aided by the wonderful sysinternals utilities. In particular RootkitRevealer successfully found a number of hidden registry entries. Later on, AutoRuns helped me to find a few other things lurking around my boot process.

But the real pièce de résistance was ntpasswd: a miniature bootable Linux, only 3Mb, which made finding and removing those troublesome files (even though they’re on an NTFS partition) a snap. I like it a lot. Plus, it’ll let you change the admin password on people’s PCs, so I may have to take it in to work. 🙂

Anyway, the end result is that I’ve spent a couple of hours working on something I don’t particularly care about by somebody on the other side of the planet who doesn’t know me from Adam. Isn’t the Internet a sheer bloody marvel?

Now. Work or bed?

1 as in “not fun at all.”


mod_perl 1 blows chunks

At $WORK, I’m looking at a web service built on mod_perl 1 / Apache 1. The service takes XML as input and returns XML as output. So far, so good.

Unfortunately, whilst I was testing with curl, I found something odd:

  curl -s -v -T- -H'Content-Type: text/xml;charset=UTF-8' http://localhost/api < input.xml

That -T- says to do a PUT request from stdin. It fails and my code returned “no input”.

But when I did this, things worked:

  curl -s -v -Tinput.xml -H'Content-Type: text/xml;charset=UTF-8' http://localhost/api

That reads directly from the file. The only difference between the two requests is that the latter includes a Content-Length header whilst the former has Transfer-Encoding: chunked instead.

This is the code that was reading the request.

    my $content;
    if ( $r->header_in( 'Content-Type' ) ) {
        $r->read( $content, $r->header_in( 'Content-Length' ) );
    return $content;

So, if there’s no Content-Length, what should we do? My first stop is always the venerable eagle book. There’s a little footnote next to read():

At the time of this writing, HTTP/1.1 requests which do not have a Content-Length header, such as one that uses chunked encoding, are not properly handled by this API.

Marvellous. Now, I had a look around in the source code and noticed a function called new_read(). Unfortunately, that failed to work. It stopped chunked reads, but failed to work for ordinary ones.

I did see a post on the mod_perl mailing list which reckoned you could loop and read all input. But I was unable to get that to work either.

So I just decided to disallow chunked input. That’s fairly easy to do, and HTTP has a special status code for it: 411 Length Required. It’s not ideal, but unless this project gets upgraded to Apache 2 (unlikely, quite frankly), it seems to be the best option.


Embedding the maven version number

If you build a jar file with maven, it helpfully embeds a properties file so that you can pull out information about the build environment. You just need some code like this.

  String path = "/META-INF/maven/groupId/artifactId/"
  InputStream stream = getClass().getResourceAsStream(path);
  Properties props = new Properties();
  System.out.println("my version is" + props.get("version"));

Now, this is all well and good, but it only works when you’ve built the artifact1. In development, it simply doesn’t exist, and you have to work around that in the code.

It would be much simpler if you could just compile in the version as a constant.

Thankfully, when I asked the question on the maven-users list, Lee Meador showed me an example. In a nutshell, you use ant to generate an extra source file containing the version number.

First, you need a little ant script to emit some Java code.

            package com.mycompany.myproject;
            /** Automatically generated by ant. */
            public class Version {
              public static final String VERSION = "${version}";

Then, you need to add the antrun plugin to your pom.xml.


This binds the antrun:run goal to the “generate-sources” phase (which happens right at the start of the build). It runs the little ant script above, passing in the correct properties. Then, it adds a new source directory, so maven knows to compile that one file that we’re generating.

When I initially tried this in Eclipse, it couldn’t find the Version class. However, running “Maven → Update Project Configuration” added target/generated-sources as a new source folder. And everything worked just fine after that. If you don’t have that option, you need to update to a new version of m2eclipse. Deleting and reimporting the project should sort it out.

This might seem like a fairly complicated way of solving the problem of getting the maven version number. But it’s more reliable than any of the other methods I have seen, so I’m pretty happy with it.

1 Yeah, I know. American spelling. I’ve been polluted by years of exposure.