meta-cmd.py: mention --list in the invocation summary.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Use sys.platform instead of platform.system().

If nothing else, the former is computed at compile time, and so should
be more efficient.  Use the recommended "startswith()" idiom.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
metadata.py: use socket() instead of mknod(...IF_SOCK) on Cygwin.

Apparently os.mknod(...IF_SOCK) fails on Cygwin, but our t/mksock tool
(which uses socket()) works just fine, so use that in
_create_via_common_rec() when on Cygwin.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Remove lib.sh actually-root in favor of t/root-status.

Create a t/root-status command that outputs root, fake, or none and
that uses the same cross-platform logic as helpers.py is_superuser().
Use it everywhere.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
t/compare-trees: don't check ACLs on Cygwin (no support).

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
README.md: add Cygwin dependencies.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
t/test.sh: skip two "tree SHA1 didn't change" tests on Cygwin for now.

Apparently Cygwin has some unusual behaviors with respect to access
times, so disable these two tests for now.

Possibly related: http://cygwin.com/ml/cygwin/2007-06/msg00436.html

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Skip the large bloom filter test if mmap fails on 32-bit archtectures.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Fix completely broken invocations of t/root-status.

No idea what I was thinking.

Thanks to Sascha Silbe <sascha-ml-reply-to-2013-2@silbe.org> for the
report.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
git.py: flush idx_map before close so FILE* operations will see changes.

Flush idx_map (msync()) before closing it, since it doesn't look like
POSIX guarantees that a matching FILE* (i.e. idx_f) will see the
parallel changes if we don't.

From the original report:

  After `bup save`, `git fsck` would show messages like
  "Packfile index for %s SHA1 mismatch"
  This indicated a bad trailing checksum on the pack index file.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Reported-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
Reviewed-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
Tested-by: Alan Jenkins <alan.christopher.jenkins@gmail.com>
Add method Metadata.__str__ to help debugging.

This is mainly for debugging, when you want to see/print whats inside the
metadata. The string representation is given as detailed_str(metadata).

Signed-off-by: Thomas Haller <thom311@gmail.com>
Add getuid() and getgid() functions to helpers.py

These functions call to os.getuid() and os.getgid(), respectively.
The result will be cached.

Signed-off-by: Thomas Haller <thom311@gmail.com>
fuse: add option --no-metadata

We are about to expose some metadata in the fuse filesystem. This has a
performance penalty, especially on first access. The new option
--no-metadata/-m disables loading of the metadata and thus provides the old
behaviour.

Signed-off-by: Thomas Haller <thom311@gmail.com>
vfs: add time from metadata to vfs.Node

Each file has three timestamps: atime, ctime and mtime. These timings
are saved in the metadata. This commit adds new properties and methods
to expose these time stamps in the vfs nodes.

There preexisting attributes [acm]time still exist and have the original
meaning (altough now they are properties). They are the time stamps (in
seconds) as they are determined while reading the git objects.

This commit changes the behaviour of atime, in the sense, that now it
will be set to the same value as [cm]time. Before, this value was always
left at 0.

Having timestamps with seconds precision is a problem, because IEEE
double cannot exactly express the timestamps up to nano seconds
precision. Thus there are the new properties [acm]time_nsec and
[acm]time_nsec_meta. The former is just the [acm]time parameter
in nano seconds, the latter is the timestamp as provided from
the metadata (or None if it doesn't exist).

Then there are new methods [acm]time_nsec_meta_default and
[acm]time_nsec_default which try to return the times and if they are not
available, the return a sensible default.

Signed-off-by: Thomas Haller <thom311@gmail.com>
fuse: expose time stamps from metadata in the file system.

Set the file timestamps atime, ctime, mtime to the values from the
metadata of a file (if not --no-metadata specified).

This currently does not work at nano seconds precision, because of a
limitation in fuse-python.

Signed-off-by: Thomas Haller <thom311@gmail.com>
vfs: add property mode_meta to vfs.Node for the file mode from metadata.

This new property mode_meta returns the file mode as found in the file
metadata. If there is no such metadata, None is returned.

Signed-off-by: Thomas Haller <thom311@gmail.com>
fuse: set the file mode to mode_meta as stored in the metadata

Signed-off-by: Thomas Haller <thom311@gmail.com>
vfs: add uid,user,gid,group from metadata to vfs.Node

Expose the user and group information of the file as stored in the
metadata.

Signed-off-by: Thomas Haller <thom311@gmail.com>
fuse: set the uid,gid of the files as stored in the metadata

Signed-off-by: Thomas Haller <thom311@gmail.com>
vfs: add inode to vfs.Node

When metadata is available, a vfs.Node has a hardlink_target. With
this property, we can generate an inode for each node. Of course the
inode cannot be the same as in hardlink_target, because that number
might already be used by another file.

This also makes it possible for nlinks() to return the actual link
count for a node. Note, that this is not really correct until all node
with the same inode are loaded -- because before loading all nodes, we
don't know which nodes will end up having the same hardlink_target.
This means, when you encounter the first node for the same inode, the
inode will be 1. As you encounter more nodes for the same inode, the
nlinks count will increase.

Signed-off-by: Thomas Haller <thom311@gmail.com>