star archives use the extended headers of POSIX.1-2001: members of type
x or g whose data is a list of key and value records. star(5)
defines the exustar form as one that “always includes x-headers and g-headers”, and
star keeps much of what its header cannot hold in records of its own, under the prefix
SCHILY..
Extended headers
An extended header is an ordinary 512-byte
header with type flag
x, followed by data blocks holding the records; its
t_size is their length. It applies to the member straight after it, whose
header follows the records, and its records replace the matching fields of that
header.
0Extended header type flagx512 bytes512Records padded with zeros to a multiple of 512size rounded up…Member header the star header the records apply to512 bytes…Member datasize rounded up
The extended header’s own name is not used for anything; POSIX’s default is
%d/PaxHeaders.%p/%f, the member’s folder, PaxHeaders. and the
process ID, then its file name. Solaris’s type X is read the same way as x.
Global headers
A header with type flag g holds records in the same form, applying to
every member that follows until another g header changes them. A record in
a member’s own x header takes priority over a global one. star puts
volume information in global headers, in the SCHILY.volhdr. keys (see
SCHILY keys).
POSIX’s default name for a global header is $TMPDIR/GlobalHead.%p.%n.
Records
Each record is a line of text, in the form "%d %s=%s\n": a decimal
length, a space, the keyword, =, the value and a line feed. The length
counts the whole record in bytes, its own digits, the space and the line feed
included.
30 mtime=1730851200.123456789
To read the records:
- Read decimal digits up to a space: the length n.
- The record is the n bytes from the first digit. Its last byte must be a line feed.
- After the space, the keyword runs to the first
=; keywords are UTF-8 and cannot contain=. - The value is everything after the
=up to the final line feed, and may hold any byte. - Move on n bytes and repeat, until the header’s size is used up.
Values are UTF-8 unless a hdrcharset record says otherwise. Numbers are
decimal text, and times are seconds since 1970 with an optional fraction. A record with
an empty value deletes the field or the value an earlier record set.
Standard keys
| Keyword | Meaning |
|---|---|
path | The member’s full path, replacing t_name and t_prefix. |
linkpath | The full link target, replacing t_linkname. |
size | The size of the data. |
uid, gid | The numeric owner and group. |
uname, gname | The owner and group names, of any length. |
mtime, atime | The modification and access times, with an optional fraction, replacing t_mtime and t_atime. |
ctime | The status change time. Not in POSIX’s list, but written by several programs and read by libarchive. |
comment | Free text, ignored when extracting. |
charset | The character set of the file’s contents. |
hdrcharset | The character set of the header values; BINARY means raw bytes. |
realtime.…, security.… | Reserved by POSIX. |
When a value is set in several places, the x record wins over a
g record, and both win over the header itself. POSIX’s full order also
places the -o options of the pax command among them.
Sparse files
star(5) says that the real size and the volume offset of a file, which star’s
sparse header once held, are
now kept in the records SCHILY.realsize and SCHILY.offset, and
that t_size holds “the sum of the sparse hole descriptors plus the size of
the compacted file data”.
A reader may also meet GNU tar’s sparse records in a star archive. GNU tar has three versions of them. Which GNU tar release brought each is not confirmed here.
| Version | Records | Where the map is |
|---|---|---|
| 0.0 | GNU.sparse.size, GNU.sparse.numblocks, then repeated GNU.sparse.offset and GNU.sparse.numbytes | in the records |
| 0.1 | GNU.sparse.size, GNU.sparse.numblocks, GNU.sparse.map | in one record, a comma-separated list of offset and size |
| 1.0 | GNU.sparse.major=1, GNU.sparse.minor=0, GNU.sparse.name, GNU.sparse.realsize | at the start of the data: decimal numbers, each ended by a line feed, first the count, then each offset and size, padded to a whole block |
The explorer decodes the 1.0 map at the start of the data, and shows the stored parts after it.
SCHILY keys
The keys star defines, from star(5). A reader that does not know a key skips it.
| Keyword | Meaning |
|---|---|
SCHILY.acl.access | The file’s access control list. |
SCHILY.acl.default | A folder’s default access control list. |
SCHILY.acl.ace | Access control entries of NFSv4-style lists. |
SCHILY.acl.type | The kind of access control list. |
SCHILY.dev, SCHILY.ino, SCHILY.nlink | The file’s device, inode number and link count. |
SCHILY.devmajor, SCHILY.devminor | Device numbers, without the header’s limits. |
SCHILY.fflags | File flags. |
SCHILY.filetype | The kind of file. |
SCHILY.offset | For a continued file, where this part starts in the whole file. |
SCHILY.realsize | For a sparse file, its full size. |
SCHILY.xattr.name | An extended attribute and its value. |
SCHILY.dir | Folder contents (see star(5)). |
SCHILY.volhdr.… | Volume header information, in global headers. |
SCHILY.archtype | The archive format. |
SCHILY.release | The release of star that wrote the archive. |
Other programs’ keys may appear too: LIBARCHIVE. keys from libarchive
(creationtime, and xattr. keys with a URL-encoded name and a
base-64 value), and GNU. keys from GNU tar.