# LispKit Archive Tar

Library `(lispkit archive tar)` provides an API for creating and managing tar archives. `(lispkit archive tar)` manages tar archives fully in memory, i.e. they are created and mutated in memory and can be saved and loaded from disk. A tar archive is made up of file objects, also called tar entries, which consist of the actual file data, compressed or uncompressed, as well as metadata, such as creation and modification date and file permissions.

## Constructors

(make-tar-archive) [procedure]
(make-tar-archive bytevector)
(make-tar-archive bytevector start)
(make-tar-archive bytevector start end)

Returns a new tar archive. If no argument is provided, a new, empty tar archive object is created. Otherwise, a tar archive is created from the binary data provided by bytevector between indices start and end.

If is an error if bytevector, between start and end, is not encoded using a supported tar encoding. At this point, the basic tar format and POSIX encodings ustar and pax are supported. If end is not provided, it is assumed to be the length of bytevector. If start is not provided, it is assumed to be 0.

## Reading and writing archives

(load-tar-archive filepath) [procedure]

Loads the tar file at path filepath and stores its content in a new tar archive object in memory. This new object is returned by `load-tar-archive`. It is an error if the file at the given file path is not in a supported tar file format. Supported tar file formats are the basic tar format as well as the two POSIX encodings ustar and pax.

(save-tar-archive archive) [procedure]
(save-tar-archive archive filepath)

Saves the given tar archive at path filepath using the pax encoding. If the archive was previously loaded from disk, then it is possible to omit parameter filepath and overwrite the previously loaded archive at the same location on disk.

## Properties of archives

tar-archive-type-tag [constant]

Symbol representing the `tar-archive` type. The `type-for` procedure of library `(lispkit type)` returns this symbol for all tar archive objects.

(tar-archive? obj) [procedure]

Returns `#t` if obj is a tar archive object; otherwise `#f` is returned.

(tar-archive-path archive) [procedure]

Returns the file path of archive or `#f` if archive was not loaded from disk, i.e. it was created via `make-tar-archive`.

(tar-archive-bytevector archive) [procedure]

Procedure `tar-archive-bytevector` returns archive encoded using the pax format into a bytevector. This bytevector can be written to disk or used to create an in-memory copy of the tar archive via `make-tar-archive`.

(tar-entry-count archive) [procedure]

Returns the number of entries in tar archive.

(tar-entries archive) [procedure]
(tar-entries archive prefix)

Returns a list of file paths for all entries of tar archive which have prefix as their file path prefix. If prefix is not given, the file paths of all entries are being returned as a list.

## Introspecting entries

Entries in zip archives are referred to via their relative file path in the archive. All procedures that provide information about a zip archive entry therefore expect two arguments: the zip archive and a file path.

(tar-entry-exists? archive path) [procedure]
(tar-entry-exists? archive path prefix?)

Returns `#t` if archive contains an entry for path (string) if prefix? is `#f`, or archive contains an entry whose path is a prefix of path if prefix? is `#t`.

(tar-entry-file? archive path) [procedure]

Returns `#t` if archive contains an entry for the given path and this entry is a file. If path does not refer to a valid entry in archive, the procedure `tar-entry-file?` fails with an error.

(tar-entry-directory? archive path) [procedure]

Returns `#t` if archive contains an entry for the given path and this entry is a directory. If path does not refer to a valid entry in archive, the procedure `tar-entry-directory?` fails with an error.

(tar-entry-symlink? archive path) [procedure]

Returns `#t` if archive contains an entry for the given path and this entry is a symbolic link. If path does not refer to a valid entry in archive, the procedure `tar-entry-symlink?` fails with an error.

(tar-entry-linked archive path) [procedure]

If archive contains an entry for the given path and this entry is a symbolic link, then procedure `tar-entry-linked` returns the path of the linked file as a string, otherwise `#f` is returned. If path does not refer to a valid entry in archive, the procedure `tar-entry-linked` fails with an error.

(tar-entry-creation-date archive path) [procedure]

Returns the creation date of the entry to which path refers to in archive. If there is no entry in archive for the given path, `#f` gets returned.

(tar-entry-modification-date archive path) [procedure]

Returns the modification date of the entry to which path refers to in archive. If there is no entry in archive for the given path, `#f` gets returned.

(tar-entry-permissions archive path) [procedure]

Returns the access permissions of the entry to which path refers to in archive as a fixnum (Unix style). If there is no entry in archive for the given path, `#f` gets returned.

Permission numbers can be created by selecting from the following attributes and summing up the corresponding values: Read by owner (400), Write by owner (200), Execute by owner (100), Read by group (040), Write by group (020), Execute by group (010), Read by others (004), Write by others (002), Execute by others (001).

(tar-entry-size archive path) [procedure]

Returns the size of the entry in bytes to which path refers to in archive. If there is no entry in archive for the given path, `#f` gets returned.

(tar-entry-data archive path) [procedure]

Returns the data of the entry to which path refers to in archive as a bytevector. If there is no entry in archive for the given path, `#f` gets returned.

## Adding and removing entries

(add-tar-entry! archive path base) [procedure]
(add-tar-entry! archive path base recursive?)

Adds the file, directory, or symbolic link at path relative to path base to the given tar archive. The corresponding entry in archive is identified via path. If the entry is a directory and parameter recursive? is true, all entries in the directory are added to archive as well.

(set-tar-entry! archive path content) [procedure]
(set-tar-entry! archive path content mdate)
(set-tar-entry! archive path content mdate permissions)

Adds or overwrites the entry in archive at path. Parameter content determines whether the new entry is a file, directory, or symbolic link. If content is a bytevector, the new entry is a file containing the data of the bytevector. If content is a string, it represents a path of a symbolic link. If content is `()`, the new entry is a directory.

The creation date of the new entry is the current date, the modification date is mdate or the current date if mdate is not provided. The permissions are permissions or an entry type specific default (`644` for files, and `755` otherwise).

(delete-tar-entry! archive path) [procedure]
(delete-tar-entry! archive path prefix?)

Deletes the entry at path from archive. If argument prefix? is true, path is interpreted as a prefix and all entries with prefix path are deleted.

## Extracting entries

(extract-tar-entry archive path base) [procedure]
(extract-tar-entry archive path base prefix?)

Extracts the entry at path in archive and stores it on the file system at path relative to path base. If prefix? is true, all entries with prefix path are extracted.

(get-tar-entry archive path) [procedure]

Returns a representation of the entry at path in archive. If the entry is a file, `get-tar-entry` returns the content of this file as a bytevector. If the entry is a symbolic link, then the target of the link is returned as a string. If the entry is a directory, `()` is returned. The procedure fails if the entry does not exist.