Be more careful when testing that repeated saves can produce the same tree.

Previously, test.sh would run multiple saves with no intervening
modifications, and check to see that the top-level "save -t" hash
didn't change, but with the addition of metadata this may fail on some
platforms where the test process itself (the save runs, etc.) affects
atime values.  That's because save is pulling the metadata for
unindexed parent directories directly from the filesystem.  And note
that atime is only special here because the test itself may
incidentally alter it -- we would see the same problem if any of the
other metdata for one of the unindexed parent directories changed
during the test run (i.e. mtime, uid, gid, ...).

To fix this, move the relevant test code from test.sh to
test-redundant-saves.sh, and use a newly added subdir-hash tool so
that we can compare the hashes of the roots of the indexed subtrees
instead of the top-level "save -t" hashes, ignoring the unindexed
parents entirely.

Thanks to Robert Edmonds <edmonds@debian.org> for running rc3 through
the Debian buildds which lead to the kFreeBSD test failure that
demonstrated the problem.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Handle EOPNOTSUPP as an indicator that Linux attrs are not supported.

Add EOPNOTSUPP to the set of errno values in _add_linux_attr() that
indicate Linux attrs are not supported by the target filesystem.  The
problem was observed on ZFS-on-Linux, 0.6.2.

Thanks to Will Rouesnel <w.rouesnel@gmail.com> for the report and an
initial patch.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Fall back from mknod() to socket()/bind() on EPERM for SOCK_STREAM.

Apparently OS X is throwing EPERM for mknod(... SOCK_STREAM), and the
current OS X manpage does state that mknod() requires superuser
privileges.

Thanks to Zoran Zaric <zz@zoranzaric.de> for the report.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
bloom-cmd.py: close open file object for tfname before attempting a rename.

Ben Kelly reported a an IOException (permission denied) during "bup
bloom" on Cygwin.  The exception was caused by the attempt to
os.rename(tfname, outfilename) in do_bloom().

This appears to be because Cygwin doesn't allow you to rename a file
while it's still open.  At first, we thought this might be because
bloom.py create() opens tfname, passes the resulting file to ShaBloom,
and then no one ever explicitly closes it.  So if the gc hasn't
collected the ShaBloom object before the rename, we're in trouble.

However, the problem may also have been caused by an unrelated process
scanning the file at the same time.

In any case, for the moment, explicitly close the ShaBloom object
before the rename.  That shouldn't hurt, and may help.

Thanks to Ben Kelly <btk@google.com> for the report.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Update version extraction for _version.py to work with the new tag syntax.

The version tag used to be in the form "bup-<version>".

The syntax is now just "<version>" to allow github to produce
reasonable archives (i.e. not bup-bup-VERSION).

Signed-off-by: Patrick Rouleau <prouleau72@gmail.com>
Reviewed-by: Gabriel Filion <gabster@lelutin.ca>
[rlb@defaultvalue.org: adjust commit message.]
Reviewed-by: Rob Browning <rlb@defaultvalue.org>
Only forward signals when appropriate; on SIGTSTP suspend parent too.

Finish the main.py work, started in
aa6f2c87e6f1292f1fa22f618532b65a5565d604, which began forwarding
SIGTSTP and SIGCONT to the child process so that it would
suspend/resume with the parent.

Only forward signals to the child when appropriate -- guarded by p and
forward_signals.  After forwarding SIGTSTP (as SIGSTOP) to the child,
reset the SIGTSTP handler to its default behavior and re-send SIGTSTP
to the parent so that it will actually suspend too.

Thanks to Karl Kiniger <karl.kiniger@med.ge.com> for reporting the
problem.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Fix id-other-than usage message.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Add "bup cat-file [--meta|--bupm] /branch/revision/[path]".

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
metadata_file(): don't load metadata objects for all the files in a dir.

When only asked for the .bupm via metdata_file(), don't also parse the
.bupm and create all the metadata objects for the dir.  Aside from
being potentially wasteful, that may also make it impossible to
retrieve a broken .bupm via "cat-file --bupm" (for analysis).

Thanks to Anton Eliasson <devel@antoneliasson.se> for helping find the
problem and test the fix.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Don't create ACL objects until they're needed.

Previously bup would store the POSIX1e ACL information in metadata
objects as pylibacl objects.  That meant bup would have to be able to
create those objects immediately when loading the metadata record.

Aside from being unnecessary, that was causing top-level crashes in
cases where the ACL object creation failed.  That's because bup would
throw an exception (deferred via add_error()) without skipping the ACL
metadata record content.  After that, all metadata reads would be out
of sync, resulting in erroneous reads, and an eventual EOFError.

To fix the problem, don't convert the encoded ACL data to pylibacl
objects until necessary (i.e. unless trying to apply the ACLs to the
filesystem via bup restore).  With that change bup should no longer
get out of sync when reading the metadata, and in cases where it would
be impossible to create the pylibacl objects (i.e. the local machine's
user/groups won't allow it), bup won't just drop the metadata.  For
example,

  bup meta --edit --set-user rlb < metadata.old > metadata.new

will no longer silently drop ACL information in metadata.old on error.

Thanks to Anton Eliasson <devel@antoneliasson.se> for reporting the
problem and helping track it down.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Ignore atime when testing bup cat-file --meta.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Fix top-level non-dir metadata restoration with /foo/latest/target/ syntax.

Previously something like "bup restore -C dest /foo/latest/bar/" would
fail to restore metadata for top-level, non-directory paths inside
bar.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>