Be nicer about character encoding of import files

When files are opened in text mode, the Python interpreter decodes the data
in bulk, and this can make it difficult for a user to identify any malformed
filenames.

It's better to open the file in binary mode and decode each line ourselves.
This allows for more meaningful error reporting; we can report the repr() of
the line that couldn't be decoded.

There's also no good reason to abort the import when encountering a line that
can't be decoded; we may as well skip that line and import as much as we can.
Move commands into functions
Use a dict mapping command names to functions

TODO: Use argparse directly for this, maybe
HashEntry: allow __eq__ against os.stat_result

I was about to add a type comparison to the relevant line in
HashDatabase.update, but this started to get a bit unwieldy. Rather than adding
all of the logic to this line, allow direct equality comparisons between
HashEntry objects and stat_result objects.

If you pass something that isn't a stat_result to HashEntry.__eq__, it falls
back to the normal object.__eq__ behavior.
HashDatabase: add _find_changes, refactor update

It will be easier to implement a 'status' command with common 'find changes'
functionality. update() now wraps this new method.

As a consequence, the 'rehash' option is gone. It was a bad idea anyway;
you can perform the same operation by deleting hash_db.json and running 'init'
again.
Add a 'status' command

Unlike the old 'update --pretend', 'status' doesn't hash anything. This can be
used to see what's changed without any expensive I/O operations.

The '--pretend' argument is still supported, though: 'update --pretend' is
the only way to identify spurious mtime updates and 'update' doesn't report
modifications if the hash matches.
README.md: add 'status' info, remove TODO item