std/archive
ZIP and TAR, gzip-compressed TAR among them: read, written, made of a directory, and extracted without leaving the directory they are extracted into.
import "std/archive"
ArchiveEntry[] entries = read_archive("release.zip")?
for e in entries do
print(e.name, e.kind, len(e.data))
end
extract(entries, "out")?
write_archive("notes.tar.gz", archive_directory("notes", "notes/")?)?An ArchiveEntry has its name, with / between its parts (a
directory's ends with /); its data; its kind, one of "file",
"directory", "symlink", and "hardlink"; modified, in seconds since
1970 UTC, 0 when not known; mode, the permissions, 0 for the usual
(0o644 for files and 0o755 for directories); and link, what a link
points to.
| Function | Result |
|---|---|
read_zip(data, limit), write_zip(entries, level) |
ZIP: entries stored or deflated at level, stored when deflating does not make them smaller; ZIP64 for archives past 4 GiB or 65,535 entries |
read_tar(data), write_tar(entries) |
TAR: POSIX ustar, with PAX headers for names and links that ustar cannot hold or that are not ASCII, sizes of 8 GiB or more, and times before 1970 |
read_tar_gz(data, limit), write_tar_gz(entries, level) |
gzip-compressed TAR |
read_archive_bytes(data, limit) |
any of them, known by how the data starts; a ZIP after other data, as a self-extracting program has it, too |
read_archive(path, limit), write_archive(path, entries, level) |
a file: written as its extension says, .zip, .tar, .tar.gz, or .tgz |
archive_directory(directory, prefix) |
the entries of everything below a directory, named from it after prefix; links are kept as links |
read_ar(data), write_ar(entries) |
ar, as Debian packages and static libraries are made of: files only, with GNU's and BSD's long names read; an ERROR of kind "invalid_ar" for data that is not ar |
extract(entries, directory) |
writes the entries under the directory and gives how many |
Reading checks what the formats can check: ZIP's CRC-32s and sizes, and
TAR's header checksums. A ZIP entry's name without the UTF-8 mark is read
as code page 437, as ZIP has it, unless Info-ZIP's Unicode path field
gives it; its time is the extended timestamp when the archive has one, or
else MS-DOS's local time, taken as UTC; and names that Windows tools
wrote with \ between their parts are read with /. GNU tar's long
names and its numbers in base 256 are read, and devices and FIFOs passed
over. limit stops archives whose entries would come to more bytes, with
an ERROR of kind "too_large".
The errors are of kind "invalid_zip" and "invalid_tar" for damaged
archives; "unsupported" for encrypted ZIP entries, compression other
than store and deflate, and archives on several disks; and
"invalid_argument" for writing a name that is absolute or has .., or a
hard link into ZIP, which has none.
extract keeps every path in the directory: before writing anything, it
refuses an entry with an absolute name, a name with .. that goes out, a
symbolic link that points out, and a hard link to something outside, with
an ERROR of kind "unsafe_path"; while writing, it refuses to write a
file through a link that is already there. Links are made after the files
and directories. Times and permissions are kept, without set-user-ID and
set-group-ID bits. A hard link is made as one, or as a copy where the
system makes none.