Tar My Attributes Up

At last! A way of saving file attributes in tar files (or any other sort of multi-file archive).

How does it do it?

Basically it puts all of the attributes of a list of files into the data portion of a single file (the attribute archive). It utilises flattened BMessages for this purpose.

You what?

An example may help ...
 ls a.cpp b.cpp ab.h | tart attr.arc
tart is the program that does all the donkey work. It takes a list of files (one per line) and saves their attributes into a single attribute archive (called attr.arc in this example).
Because the attribute archive is a flat file it can be safely added to a tar file, or emailed, or written to a DOS floppy, or FTP'd or whatever.

Details

Currently, tarring-up attributes uses a multi-step approach which is rather simplistic, (see below for how I'd really like it to work).

The steps are:

  1. create a tar file as normal (not compressed!)
    tar cf tarfile files
  2. create an attribute archive using the file list from the tar file
    tar tf tarfile | tart .Attributes
  3. add the attribute archive to the tar file
    tar rf tarfile .Attributes
  4. compress the tarfile
    gzip tarfile

A Convenient Script

Since most of the time you want to tar up a whole sub-directory, this script makes that task slightly easier, notice that it puts the attribute archive into the tarred-up directory
# script to tar-up a whole sub-directory, also storing any attributes
# usage: quicktart directory
DIR="$1"
TARFILE="$DIR.tar"
AA="$DIR/.Attributes"

tar cf "$TARFILE" "$DIR"
tar tf "$TARFILE" | tart "$AA"
tar rf "$TARFILE" "$AA"

gzip "$TARFILE"
This script (quicktart) is not very clever, so you have to get the arguments right. The directory you want to tar up should be below the current directory. And make sure you don't have a trailing slash on the directory name.
[All this will be improved in a later release (honest)]

Unpacking

  1. unpack as usual
    gunzip < compressed-tarfile | tar xf -
  2. add attributes to files
    untart dir/.Attributes

How I Would Like it to Work

The neatest way would be as follows:
tar cf - files | tart attr-archive | gzip > archive.tgz

Here, tart would read the output from tar, extracting the pathnames from the tar header blocks and saving the attributes into attr-archive. At the end of the input, it would send a tar header for attr-archive followed by the contents of attr-archive. This would involve knowing what a tar header is like (yes, I know it is all documented in the GNU tar distribution) and how to calculate the checksum, etc. And I really can't be bothered to look into this right now, so hopefully some bright BeDev will do it for me :-)

Data Format

The format of the attribute archive is as follows:
Attribute-Archive
	MANY Path-Attribute
		pathname-length (1 unsigned char)
		pathname (string without terminating NUL)
		flat-length (4 byte BIG_ENDIAN integer)
		attributes (flattened BMessage)
Note that we use flat-length so that we can skip over the BMessage without having to unflatten it.

Future Work

If you would like to implement any of these features (or if you have already done so!) then please email me
Better Attribute Archive Handling
Currently all you can do to an Attribute Archive is create/overwrite one from a list of pathnames. It would be nice if you could insert/update/delete
Better Tar Handling
Although you don't have to use Attribute Archives with tar, it's probably its major use, so a full tar wrapper would be nice. (It only has to be a wrapper, you shouldn't have to change the tar source code.)
Better Data Format
Is the len/path/len/message format OK? Or should we use something else (especially if we want to support insert/update/delete)?
Bug Fixing
what bugs? this isn't Windows you know :-)