tar-0.4.2.2: Reading, writing and manipulating ".tar" archive files.

Copyright(c) 2007 Bjorn Bringert, 2008 Andrea Vezzosi, 2008-2009 Duncan Coutts
LicenseBSD3
Maintainerduncan@community.haskell.org
Portabilityportable
Safe HaskellNone
LanguageHaskell98

Codec.Archive.Tar.Entry

Contents

Description

Types and functions to manipulate tar entries.

While the Codec.Archive.Tar module provides only the simple high level API, this module provides full access to the details of tar entries. This lets you inspect all the meta-data, construct entries and handle error cases more precisely.

This module uses common names and so is designed to be imported qualified:

import qualified Codec.Archive.Tar       as Tar
import qualified Codec.Archive.Tar.Entry as Tar

Synopsis

Tar entry and associated types

data Entry Source

Tar archive entry.

Constructors

Entry 

Fields

entryTarPath :: !TarPath

The path of the file or directory within the archive. This is in a tar-specific form. Use entryPath to get a native FilePath.

entryContent :: !EntryContent

The real content of the entry. For NormalFile this includes the file data. An entry usually contains a NormalFile or a Directory.

entryPermissions :: !Permissions

File permissions (Unix style file mode).

entryOwnership :: !Ownership

The user and group to which this file belongs.

entryTime :: !EpochTime

The time the file was last modified.

entryFormat :: !Format

The tar format the archive is using.

entryPath :: Entry -> FilePath Source

Native FilePath of the file or directory within the archive.

data EntryContent Source

The content of a tar archive entry, which depends on the type of entry.

Portable archives should contain only NormalFile and Directory.

data Ownership Source

Constructors

Ownership 

Fields

ownerName :: String

The owner user name. Should be set to "" if unknown.

groupName :: String

The owner group name. Should be set to "" if unknown.

ownerId :: !Int

Numeric owner user id. Should be set to 0 if unknown.

groupId :: !Int

Numeric owner group id. Should be set to 0 if unknown.

type EpochTime = Int64 Source

The number of seconds since the UNIX epoch

data Format Source

There have been a number of extensions to the tar file format over the years. They all share the basic entry fields and put more meta-data in different extended headers.

Constructors

V7Format

This is the classic Unix V7 tar format. It does not support owner and group names, just numeric Ids. It also does not support device numbers.

UstarFormat

The "USTAR" format is an extension of the classic V7 format. It was later standardised by POSIX. It has some restrictions but is the most portable format.

GnuFormat

The GNU tar implementation also extends the classic V7 format, though in a slightly different way from the USTAR format. In general for new archives the standard USTAR/POSIX should be used.

Constructing simple entry values

simpleEntry :: TarPath -> EntryContent -> Entry Source

An Entry with all default values except for the file name and type. It uses the portable USTAR/POSIX format (see UstarHeader).

You can use this as a basis and override specific fields, eg:

(emptyEntry name HardLink) { linkTarget = target }

fileEntry :: TarPath -> ByteString -> Entry Source

A tar Entry for a file.

Entry fields such as file permissions and ownership have default values.

You can use this as a basis and override specific fields. For example if you need an executable file you could use:

(fileEntry name content) { fileMode = executableFileMode }

directoryEntry :: TarPath -> Entry Source

A tar Entry for a directory.

Entry fields such as file permissions and ownership have default values.

Standard file permissions

For maximum portability when constructing archives use only these file permissions.

ordinaryFilePermissions :: Permissions Source

rw-r--r-- for normal files

executableFilePermissions :: Permissions Source

rwxr-xr-x for executable files

directoryPermissions :: Permissions Source

rwxr-xr-x for directories

Constructing entries from disk files

packFileEntry Source

Arguments

:: FilePath

Full path to find the file on the local disk

-> TarPath

Path to use for the tar Entry in the archive

-> IO Entry 

Construct a tar Entry based on a local file.

This sets the entry size, the data contained in the file and the file's modification time. If the file is executable then that information is also preserved. File ownership and detailed permissions are not preserved.

  • The file contents is read lazily.

packDirectoryEntry Source

Arguments

:: FilePath

Full path to find the file on the local disk

-> TarPath

Path to use for the tar Entry in the archive

-> IO Entry 

Construct a tar Entry based on a local directory (but not its contents).

The only attribute of the directory that is used is its modification time. Directory ownership and detailed permissions are not preserved.

getDirectoryContentsRecursive :: FilePath -> IO [FilePath] Source

This is a utility function, much like getDirectoryContents. The difference is that it includes the contents of subdirectories.

The paths returned are all relative to the top directory. Directory paths are distinguishable by having a trailing path separator (see hasTrailingPathSeparator).

All directories are listed before the files that they contain. Amongst the contents of a directory, subdirectories are listed after normal files. The overall result is that files within a directory will be together in a single contiguous group. This tends to improve file layout and IO performance when creating or extracting tar archives.

  • This function returns results lazily. Subdirectories are not scanned until the files entries in the parent directory have been consumed.

TarPath type

data TarPath Source

The classic tar format allowed just 100 characters for the file name. The USTAR format extended this with an extra 155 characters, however it uses a complex method of splitting the name between the two sections.

Instead of just putting any overflow into the extended area, it uses the extended area as a prefix. The aggravating insane bit however is that the prefix (if any) must only contain a directory prefix. That is the split between the two areas must be on a directory separator boundary. So there is no simple calculation to work out if a file name is too long. Instead we have to try to find a valid split that makes the name fit in the two areas.

The rationale presumably was to make it a bit more compatible with old tar programs that only understand the classic format. A classic tar would be able to extract the file name and possibly some dir prefix, but not the full dir prefix. So the files would end up in the wrong place, but that's probably better than ending up with the wrong names too.

So it's understandable but rather annoying.

  • Tar paths use Posix format (ie '/' directory separators), irrespective of the local path conventions.
  • The directory separator between the prefix and name is not stored.

toTarPath Source

Arguments

:: Bool

Is the path for a directory? This is needed because for directories a TarPath must always use a trailing /.

-> FilePath 
-> Either String TarPath 

Convert a native FilePath to a TarPath.

The conversion may fail if the FilePath is too long. See TarPath for a description of the problem with splitting long FilePaths.

fromTarPath :: TarPath -> FilePath Source

Convert a TarPath to a native FilePath.

The native FilePath will use the native directory separator but it is not otherwise checked for validity or sanity. In particular:

  • The tar path may be invalid as a native path, eg the file name "nul" is not valid on Windows.
  • The tar path may be an absolute path or may contain ".." components. For security reasons this should not usually be allowed, but it is your responsibility to check for these conditions (eg using checkSecurity).

fromTarPathToPosixPath :: TarPath -> FilePath Source

Convert a TarPath to a Unix/Posix FilePath.

The difference compared to fromTarPath is that it always returns a Unix style path irrespective of the current operating system.

This is useful to check how a TarPath would be interpreted on a specific operating system, eg to perform portability checks.

fromTarPathToWindowsPath :: TarPath -> FilePath Source

Convert a TarPath to a Windows FilePath.

The only difference compared to fromTarPath is that it always returns a Windows style path irrespective of the current operating system.

This is useful to check how a TarPath would be interpreted on a specific operating system, eg to perform portability checks.

LinkTarget type

data LinkTarget Source

The tar format allows just 100 ASCII characters for the SymbolicLink and HardLink entry types.

toLinkTarget :: FilePath -> Maybe LinkTarget Source

Convert a native FilePath to a tar LinkTarget. This may fail if the string is longer than 100 characters or if it contains non-portable characters.