tar

Imports

Imports #

"syscall"
"time"
"io/fs"
"os/user"
"runtime"
"strconv"
"sync"
"syscall"
"bytes"
"fmt"
"strconv"
"strings"
"time"
"errors"
"fmt"
"io"
"io/fs"
"maps"
"path"
"slices"
"strings"
"time"
"errors"
"fmt"
"internal/godebug"
"io/fs"
"maps"
"math"
"path"
"reflect"
"strconv"
"strings"
"time"
"strings"
"bytes"
"io"
"path/filepath"
"strconv"
"strings"
"time"
"syscall"
"time"

Constants & Variables

ErrFieldTooLong var #

var ErrFieldTooLong = *ast.CallExpr

ErrHeader var #

var ErrHeader = *ast.CallExpr

ErrInsecurePath var #

var ErrInsecurePath = *ast.CallExpr

ErrWriteAfterClose var #

var ErrWriteAfterClose = *ast.CallExpr

ErrWriteTooLong var #

var ErrWriteTooLong = *ast.CallExpr

FormatGNU const #

FormatGNU represents the GNU header format. The GNU header format is older than the USTAR and PAX standards and is not compatible with them. The GNU format supports arbitrary file sizes, filenames of arbitrary encoding and length, sparse files, and other features. It is recommended that PAX be chosen over GNU unless the target application can only parse GNU formatted archives. Reference: https://www.gnu.org/software/tar/manual/html_node/Standard.html

const FormatGNU

FormatPAX const #

FormatPAX represents the PAX header format defined in POSIX.1-2001. PAX extends USTAR by writing a special file with Typeflag TypeXHeader preceding the original header. This file contains a set of key-value records, which are used to overcome USTAR's shortcomings, in addition to providing the ability to have sub-second resolution for timestamps. Some newer formats add their own extensions to PAX by defining their own keys and assigning certain semantic meaning to the associated values. For example, sparse file support in PAX is implemented using keys defined by the GNU manual (e.g., "GNU.sparse.map"). Reference: http://pubs.opengroup.org/onlinepubs/009695399/utilities/pax.html

const FormatPAX

FormatUSTAR const #

FormatUSTAR represents the USTAR header format defined in POSIX.1-1988. While this format is compatible with most tar readers, the format has several limitations making it unsuitable for some usages. Most notably, it cannot support sparse files, files larger than 8GiB, filenames larger than 256 characters, and non-ASCII filenames. Reference: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_06

const FormatUSTAR

FormatUnknown const #

FormatUnknown indicates that the format is unknown.

const FormatUnknown

TypeBlock const #

Type flags for Header.Typeflag.

const TypeBlock = '4'

TypeChar const #

Type flags for Header.Typeflag.

const TypeChar = '3'

TypeCont const #

Type '7' is reserved.

const TypeCont = '7'

TypeDir const #

Type flags for Header.Typeflag.

const TypeDir = '5'

TypeFifo const #

Type flags for Header.Typeflag.

const TypeFifo = '6'

TypeGNULongName const #

Types 'L' and 'K' are used by the GNU format for a meta file used to store the path or link name for the next file. This package transparently handles these types.

const TypeGNULongName = 'L'

TypeGNUSparse const #

Type 'S' indicates a sparse file in the GNU format.

const TypeGNUSparse = 'S'

TypeReg const #

Type '0' indicates a regular file.

const TypeReg = '0'

TypeRegA const #

Deprecated: Use TypeReg instead.

const TypeRegA = '\x00'

TypeXGlobalHeader const #

Type 'g' is used by the PAX format to store key-value records that are relevant to all subsequent files. This package only supports parsing and composing such headers, but does not currently support persisting the global state across files.

const TypeXGlobalHeader = 'g'

TypeXHeader const #

Type 'x' is used by the PAX format to store key-value records that are only relevant to the next file. This package transparently handles these types.

const TypeXHeader = 'x'

_ const #

Deliberately hide the meaning of constants from public API.

const _ Format = *ast.BinaryExpr

basicKeys var #

basicKeys is a set of the PAX keys for which we have built-in support. This does not contain "charset" or "comment", which are both PAX-specific, so adding them as first-class features of Header is unlikely. Users can use the PAXRecords field to set it themselves.

var basicKeys = map[string]bool{...}

blockSize const #

Size constants from various tar specifications.

const blockSize = 512

c_ISBLK const #

const c_ISBLK = 060000

c_ISCHR const #

const c_ISCHR = 020000

c_ISDIR const #

Common Unix mode constants; these are not defined in any common tar standard. Header.FileInfo understands these, but FileInfoHeader will never produce these.

const c_ISDIR = 040000

c_ISFIFO const #

const c_ISFIFO = 010000

c_ISGID const #

const c_ISGID = 02000

c_ISLNK const #

const c_ISLNK = 0120000

c_ISREG const #

const c_ISREG = 0100000

c_ISSOCK const #

const c_ISSOCK = 0140000

c_ISUID const #

Mode constants from the USTAR spec: See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_06

const c_ISUID = 04000

c_ISVTX const #

const c_ISVTX = 01000

errMissData var #

var errMissData = *ast.CallExpr

errUnrefData var #

var errUnrefData = *ast.CallExpr

errWriteHole var #

var errWriteHole = *ast.CallExpr

formatMax const #

Constants to identify various tar formats.

const formatMax

formatNames var #

var formatNames = map[Format]string{...}

formatSTAR const #

Schily's tar format, which is incompatible with USTAR. This does not cover STAR extensions to the PAX format; these fall under the PAX format.

const formatSTAR

formatV7 const #

The format of the original Unix V7 tar tool prior to standardization.

const formatV7

groupMap var #

userMap and groupMap caches UID and GID lookups for performance reasons. The downside is that renaming uname or gname by the OS never takes effect.

var groupMap sync.Map

magicGNU const #

Magics used to identify various formats.

const magicGNU = "ustar "

magicUSTAR const #

Magics used to identify various formats.

const magicUSTAR = "ustar\x00"

maxSpecialFileSize const #

Max length of a special file (PAX header, GNU long name or link). This matches the limit used by libarchive.

const maxSpecialFileSize = *ast.BinaryExpr

nameSize const #

Size constants from various tar specifications.

const nameSize = 100

paxAtime const #

Keywords for PAX extended header records.

const paxAtime = "atime"

paxCharset const #

Keywords for PAX extended header records.

const paxCharset = "charset"

paxComment const #

Keywords for PAX extended header records.

const paxComment = "comment"

paxCtime const #

Keywords for PAX extended header records.

const paxCtime = "ctime"

paxGNUSparse const #

Keywords for GNU sparse files in a PAX extended header.

const paxGNUSparse = "GNU.sparse."

paxGNUSparseMajor const #

Keywords for PAX extended header records.

const paxGNUSparseMajor = "GNU.sparse.major"

paxGNUSparseMap const #

Keywords for PAX extended header records.

const paxGNUSparseMap = "GNU.sparse.map"

paxGNUSparseMinor const #

Keywords for PAX extended header records.

const paxGNUSparseMinor = "GNU.sparse.minor"

paxGNUSparseName const #

Keywords for PAX extended header records.

const paxGNUSparseName = "GNU.sparse.name"

paxGNUSparseNumBlocks const #

Keywords for PAX extended header records.

const paxGNUSparseNumBlocks = "GNU.sparse.numblocks"

paxGNUSparseNumBytes const #

Keywords for PAX extended header records.

const paxGNUSparseNumBytes = "GNU.sparse.numbytes"

paxGNUSparseOffset const #

Keywords for PAX extended header records.

const paxGNUSparseOffset = "GNU.sparse.offset"

paxGNUSparseRealSize const #

Keywords for PAX extended header records.

const paxGNUSparseRealSize = "GNU.sparse.realsize"

paxGNUSparseSize const #

Keywords for PAX extended header records.

const paxGNUSparseSize = "GNU.sparse.size"

paxGid const #

Keywords for PAX extended header records.

const paxGid = "gid"

paxGname const #

Keywords for PAX extended header records.

const paxGname = "gname"

paxLinkpath const #

Keywords for PAX extended header records.

const paxLinkpath = "linkpath"

paxMtime const #

Keywords for PAX extended header records.

const paxMtime = "mtime"

paxNone const #

Keywords for PAX extended header records.

const paxNone = ""

paxPath const #

Keywords for PAX extended header records.

const paxPath = "path"

paxSchilyXattr const #

Keywords for PAX extended header records.

const paxSchilyXattr = "SCHILY.xattr."

paxSize const #

Keywords for PAX extended header records.

const paxSize = "size"

paxUid const #

Keywords for PAX extended header records.

const paxUid = "uid"

paxUname const #

Keywords for PAX extended header records.

const paxUname = "uname"

prefixSize const #

Size constants from various tar specifications.

const prefixSize = 155

sysStat var #

sysStat, if non-nil, populates h from system-dependent fields of fi.

var sysStat func(fi fs.FileInfo, h *Header, doNameLookups bool) error

tarinsecurepath var #

var tarinsecurepath = *ast.CallExpr

trailerSTAR const #

Magics used to identify various formats.

const trailerSTAR = "tar\x00"

userMap var #

userMap and groupMap caches UID and GID lookups for performance reasons. The downside is that renaming uname or gname by the OS never takes effect.

var userMap sync.Map

versionGNU const #

Magics used to identify various formats.

const versionGNU = " \x00"

versionUSTAR const #

Magics used to identify various formats.

const versionUSTAR = "00"

zeroBlock var #

var zeroBlock block

Type Aliases

Format type #

Format represents the tar archive format. The original tar format was introduced in Unix V7. Since then, there have been multiple competing formats attempting to standardize or extend the V7 format to overcome its limitations. The most common formats are the USTAR, PAX, and GNU formats, each with their own advantages and limitations. The following table captures the capabilities of each format: | USTAR | PAX | GNU ------------------+--------+-----------+---------- Name | 256B | unlimited | unlimited Linkname | 100B | unlimited | unlimited Size | uint33 | unlimited | uint89 Mode | uint21 | uint21 | uint57 Uid/Gid | uint21 | unlimited | uint57 Uname/Gname | 32B | unlimited | 32B ModTime | uint33 | unlimited | int89 AccessTime | n/a | unlimited | int89 ChangeTime | n/a | unlimited | int89 Devmajor/Devminor | uint21 | uint21 | uint57 ------------------+--------+-----------+---------- string encoding | ASCII | UTF-8 | binary sub-second times | no | yes | no sparse files | no | yes | yes The table's upper portion shows the [Header] fields, where each format reports the maximum number of bytes allowed for each string field and the integer type used to store each numeric field (where timestamps are stored as the number of seconds since the Unix epoch). The table's lower portion shows specialized features of each format, such as supported string encodings, support for sub-second timestamps, or support for sparse files. The Writer currently provides no support for sparse files.

type Format int

block type #

type block [blockSize]byte

headerError type #

type headerError []string

headerGNU type #

type headerGNU [blockSize]byte

headerSTAR type #

type headerSTAR [blockSize]byte

headerUSTAR type #

type headerUSTAR [blockSize]byte

headerV7 type #

type headerV7 [blockSize]byte

numberFormatter type #

type numberFormatter func([]byte, int64)

sparseArray type #

type sparseArray []byte

sparseDatas type #

A sparse file can be represented as either a sparseDatas or a sparseHoles. As long as the total size is known, they are equivalent and one can be converted to the other form and back. The various tar formats with sparse file support represent sparse files in the sparseDatas form. That is, they specify the fragments in the file that has data, and treat everything else as having zero bytes. As such, the encoding and decoding logic in this package deals with sparseDatas. However, the external API uses sparseHoles instead of sparseDatas because the zero value of sparseHoles logically represents a normal file (i.e., there are no holes in it). On the other hand, the zero value of sparseDatas implies that the file has no data in it, which is rather odd. As an example, if the underlying raw file contains the 10-byte data: var compactFile = "abcdefgh" And the sparse map has the following entries: var spd sparseDatas = []sparseEntry{ {Offset: 2, Length: 5}, // Data fragment for 2..6 {Offset: 18, Length: 3}, // Data fragment for 18..20 } var sph sparseHoles = []sparseEntry{ {Offset: 0, Length: 2}, // Hole fragment for 0..1 {Offset: 7, Length: 11}, // Hole fragment for 7..17 {Offset: 21, Length: 4}, // Hole fragment for 21..24 } Then the content of the resulting sparse file with a Header.Size of 25 is: var sparseFile = "\x00"*2 + "abcde" + "\x00"*11 + "fgh" + "\x00"*4

type sparseDatas []sparseEntry

sparseElem type #

type sparseElem []byte

sparseHoles type #

A sparse file can be represented as either a sparseDatas or a sparseHoles. As long as the total size is known, they are equivalent and one can be converted to the other form and back. The various tar formats with sparse file support represent sparse files in the sparseDatas form. That is, they specify the fragments in the file that has data, and treat everything else as having zero bytes. As such, the encoding and decoding logic in this package deals with sparseDatas. However, the external API uses sparseHoles instead of sparseDatas because the zero value of sparseHoles logically represents a normal file (i.e., there are no holes in it). On the other hand, the zero value of sparseDatas implies that the file has no data in it, which is rather odd. As an example, if the underlying raw file contains the 10-byte data: var compactFile = "abcdefgh" And the sparse map has the following entries: var spd sparseDatas = []sparseEntry{ {Offset: 2, Length: 5}, // Data fragment for 2..6 {Offset: 18, Length: 3}, // Data fragment for 18..20 } var sph sparseHoles = []sparseEntry{ {Offset: 0, Length: 2}, // Hole fragment for 0..1 {Offset: 7, Length: 11}, // Hole fragment for 7..17 {Offset: 21, Length: 4}, // Hole fragment for 21..24 } Then the content of the resulting sparse file with a Header.Size of 25 is: var sparseFile = "\x00"*2 + "abcde" + "\x00"*11 + "fgh" + "\x00"*4

type sparseHoles []sparseEntry

stringFormatter type #

type stringFormatter func([]byte, string)

Interfaces

FileInfoNames interface #

FileInfoNames extends [fs.FileInfo]. Passing an instance of this to [FileInfoHeader] permits the caller to avoid a system-dependent name lookup by specifying the Uname and Gname directly.

type FileInfoNames interface {
fs.FileInfo
Uname() (string, error)
Gname() (string, error)
}

fileReader interface #

type fileReader interface {
io.Reader
fileState
WriteTo(io.Writer) (int64, error)
}

fileState interface #

fileState tracks the number of logical (includes sparse holes) and physical (actual in tar archive) bytes remaining for the current file. Invariant: logicalRemaining >= physicalRemaining

type fileState interface {
logicalRemaining() int64
physicalRemaining() int64
}

fileWriter interface #

type fileWriter interface {
io.Writer
fileState
ReadFrom(io.Reader) (int64, error)
}

Structs

Reader struct #

Reader provides sequential access to the contents of a tar archive. Reader.Next advances to the next file in the archive (including the first), and then Reader can be treated as an io.Reader to access the file's data.

type Reader struct {
r io.Reader
pad int64
curr fileReader
blk block
err error
}

Writer struct #

Writer provides sequential writing of a tar archive. [Writer.WriteHeader] begins a new file with the provided [Header], and then Writer can be treated as an io.Writer to supply that file's data.

type Writer struct {
w io.Writer
pad int64
curr fileWriter
hdr Header
blk block
err error
}

formatter struct #

type formatter struct {
err error
}

headerFileInfo struct #

headerFileInfo implements fs.FileInfo.

type headerFileInfo struct {
h *Header
}

parser struct #

type parser struct {
err error
}

regFileReader struct #

regFileReader is a fileReader for reading data from a regular file entry.

type regFileReader struct {
r io.Reader
nb int64
}

regFileWriter struct #

regFileWriter is a fileWriter for writing data to a regular file entry.

type regFileWriter struct {
w io.Writer
nb int64
}

sparseEntry struct #

sparseEntry represents a Length-sized fragment at Offset in the file.

type sparseEntry struct {
Offset int64
Length int64
}

sparseFileReader struct #

sparseFileReader is a fileReader for reading data from a sparse file entry.

type sparseFileReader struct {
fr fileReader
sp sparseHoles
pos int64
}

sparseFileWriter struct #

sparseFileWriter is a fileWriter for writing data to a sparse file entry.

type sparseFileWriter struct {
fw fileWriter
sp sparseDatas
pos int64
}

zeroReader struct #

type zeroReader struct {

}

zeroWriter struct #

zeroWriter may only be written with NULs, otherwise it returns errWriteHole.

type zeroWriter struct {

}

Functions

AddFS method #

AddFS adds the files from fs.FS to the archive. It walks the directory tree starting at the root of the filesystem adding each file to the tar archive while maintaining the directory structure.

func (tw *Writer) AddFS(fsys fs.FS) error

Close method #

Close closes the tar archive by flushing the padding, and writing the footer. If the current file (from a prior call to [Writer.WriteHeader]) is not fully written, then this returns an error.

func (tw *Writer) Close() error

Error method #

func (he headerError) Error() string

FileInfo method #

FileInfo returns an fs.FileInfo for the Header.

func (h *Header) FileInfo() fs.FileInfo

FileInfoHeader function #

FileInfoHeader creates a partially-populated [Header] from fi. If fi describes a symlink, FileInfoHeader records link as the link target. If fi describes a directory, a slash is appended to the name. Since fs.FileInfo's Name method only returns the base name of the file it describes, it may be necessary to modify Header.Name to provide the full path name of the file. If fi implements [FileInfoNames] Header.Gname and Header.Uname are provided by the methods of the interface.

func FileInfoHeader(fi fs.FileInfo, link string) (*Header, error)

Flush method #

Flush finishes writing the current file's block padding. The current file must be fully written before Flush can be called. This is unnecessary as the next call to [Writer.WriteHeader] or [Writer.Close] will implicitly flush out the file's padding.

func (tw *Writer) Flush() error

IsDir method #

func (fi headerFileInfo) IsDir() bool

ModTime method #

func (fi headerFileInfo) ModTime() time.Time

Mode method #

Mode returns the permission and mode bits for the headerFileInfo.

func (fi headerFileInfo) Mode() (mode fs.FileMode)

Name method #

Name returns the base name of the file.

func (fi headerFileInfo) Name() string

NewReader function #

NewReader creates a new [Reader] reading from r.

func NewReader(r io.Reader) *Reader

NewWriter function #

NewWriter creates a new Writer writing to w.

func NewWriter(w io.Writer) *Writer

Next method #

Next advances to the next entry in the tar archive. The Header.Size determines how many bytes can be read for the next file. Any remaining data in the current file is automatically discarded. At the end of the archive, Next returns the error io.EOF. If Next encounters a non-local name (as defined by [filepath.IsLocal]) and the GODEBUG environment variable contains `tarinsecurepath=0`, Next returns the header with an [ErrInsecurePath] error. A future version of Go may introduce this behavior by default. Programs that want to accept non-local names can ignore the [ErrInsecurePath] error and use the returned header.

func (tr *Reader) Next() (*Header, error)

Read method #

func (sr *sparseFileReader) Read(b []byte) (n int, err error)

Read method #

Read reads from the current file in the tar archive. It returns (0, io.EOF) when it reaches the end of that file, until [Next] is called to advance to the next file. If the current file is sparse, then the regions marked as a hole are read back as NUL-bytes. Calling Read on special types like [TypeLink], [TypeSymlink], [TypeChar], [TypeBlock], [TypeDir], and [TypeFifo] returns (0, [io.EOF]) regardless of what the [Header.Size] claims.

func (tr *Reader) Read(b []byte) (int, error)

Read method #

func (fr *regFileReader) Read(b []byte) (n int, err error)

Read method #

func (zeroReader) Read(b []byte) (int, error)

ReadFrom method #

func (sw *sparseFileWriter) ReadFrom(r io.Reader) (n int64, err error)

ReadFrom method #

func (fw *regFileWriter) ReadFrom(r io.Reader) (int64, error)

Size method #

func (fi headerFileInfo) Size() int64

String method #

func (fi headerFileInfo) String() string

String method #

func (f Format) String() string

Sys method #

func (fi headerFileInfo) Sys() any

Write method #

func (zeroWriter) Write(b []byte) (int, error)

Write method #

func (sw *sparseFileWriter) Write(b []byte) (n int, err error)

Write method #

func (fw *regFileWriter) Write(b []byte) (n int, err error)

Write method #

Write writes to the current file in the tar archive. Write returns the error [ErrWriteTooLong] if more than Header.Size bytes are written after [Writer.WriteHeader]. Calling Write on special types like [TypeLink], [TypeSymlink], [TypeChar], [TypeBlock], [TypeDir], and [TypeFifo] returns (0, [ErrWriteTooLong]) regardless of what the [Header.Size] claims.

func (tw *Writer) Write(b []byte) (int, error)

WriteHeader method #

WriteHeader writes hdr and prepares to accept the file's contents. The Header.Size determines how many bytes can be written for the next file. If the current file is not fully written, then this returns an error. This implicitly flushes any padding necessary before writing the header.

func (tw *Writer) WriteHeader(hdr *Header) error

WriteTo method #

func (sr *sparseFileReader) WriteTo(w io.Writer) (n int64, err error)

WriteTo method #

func (fr *regFileReader) WriteTo(w io.Writer) (int64, error)

accessTime method #

func (h *headerSTAR) accessTime() []byte

accessTime method #

func (h *headerGNU) accessTime() []byte

alignSparseEntries function #

alignSparseEntries mutates src and returns dst where each fragment's starting offset is aligned up to the nearest block edge, and each ending offset is aligned down to the nearest block edge. Even though the Go tar Reader and the BSD tar utility can handle entries with arbitrary offsets and lengths, the GNU tar utility can only handle offsets and lengths that are multiples of blockSize.

func alignSparseEntries(src []sparseEntry, size int64) []sparseEntry

allowedFormats method #

allowedFormats determines which formats can be used. The value returned is the logical OR of multiple possible formats. If the value is FormatUnknown, then the input Header cannot be encoded and an error is returned explaining why. As a by-product of checking the fields, this function returns paxHdrs, which contain all fields that could not be directly encoded. A value receiver ensures that this method does not mutate the source Header.

func (h Header) allowedFormats() (format Format, paxHdrs map[string]string, err error)

blockPadding function #

blockPadding computes the number of bytes needed to pad offset up to the nearest block edge where 0 <= n < blockSize.

func blockPadding(offset int64) (n int64)

changeTime method #

func (h *headerGNU) changeTime() []byte

changeTime method #

func (h *headerSTAR) changeTime() []byte

chksum method #

func (h *headerV7) chksum() []byte

computeChecksum method #

computeChecksum computes the checksum for the header block. POSIX specifies a sum of the unsigned byte values, but the Sun tar used signed byte values. We compute and return both.

func (b *block) computeChecksum() (unsigned int64, signed int64)

devMajor method #

func (h *headerSTAR) devMajor() []byte

devMajor method #

func (h *headerGNU) devMajor() []byte

devMajor method #

func (h *headerUSTAR) devMajor() []byte

devMinor method #

func (h *headerSTAR) devMinor() []byte

devMinor method #

func (h *headerUSTAR) devMinor() []byte

devMinor method #

func (h *headerGNU) devMinor() []byte

discard function #

discard skips n bytes in r, reporting an error if unable to do so.

func discard(r io.Reader, n int64) error

endOffset method #

func (s sparseEntry) endOffset() int64

ensureEOF function #

ensureEOF checks whether r is at EOF, reporting ErrWriteTooLong if not so.

func ensureEOF(r io.Reader) error

entry method #

func (s sparseArray) entry(i int) sparseElem

fitsInBase256 function #

fitsInBase256 reports whether x can be encoded into n bytes using base-256 encoding. Unlike octal encoding, base-256 encoding does not require that the string ends with a NUL character. Thus, all n bytes are available for output. If operating in binary mode, this assumes strict GNU binary mode; which means that the first byte can only be either 0x80 or 0xff. Thus, the first byte is equivalent to the sign bit in two's complement form.

func fitsInBase256(n int, x int64) bool

fitsInOctal function #

fitsInOctal reports whether the integer x fits in a field n-bytes long using octal encoding with the appropriate NUL terminator.

func fitsInOctal(n int, x int64) bool

formatNumeric method #

formatNumeric encodes x into b using base-8 (octal) encoding if possible. Otherwise it will attempt to use base-256 (binary) encoding.

func (f *formatter) formatNumeric(b []byte, x int64)

formatOctal method #

func (f *formatter) formatOctal(b []byte, x int64)

formatPAXRecord function #

formatPAXRecord formats a single PAX record, prefixing it with the appropriate length.

func formatPAXRecord(k string, v string) (string, error)

formatPAXTime function #

formatPAXTime converts ts into a time of the form %d.%d as described in the PAX specification. This function is capable of negative timestamps.

func formatPAXTime(ts time.Time) (s string)

formatString method #

formatString copies s into b, NUL-terminating if possible.

func (f *formatter) formatString(b []byte, s string)

getFormat method #

getFormat checks that the block is a valid tar header based on the checksum. It then attempts to guess the specific format based on magic values. If the checksum fails, then FormatUnknown is returned.

func (b *block) getFormat() Format

gid method #

func (h *headerV7) gid() []byte

groupName method #

func (h *headerSTAR) groupName() []byte

groupName method #

func (h *headerUSTAR) groupName() []byte

groupName method #

func (h *headerGNU) groupName() []byte

handleRegularFile method #

handleRegularFile sets up the current file reader and padding such that it can only read the following logical data section. It will properly handle special headers that contain no data section.

func (tr *Reader) handleRegularFile(hdr *Header) error

handleSparseFile method #

handleSparseFile checks if the current file is a sparse format of any type and sets the curr reader appropriately.

func (tr *Reader) handleSparseFile(hdr *Header, rawHdr *block) error

has method #

func (f Format) has(f2 Format) bool

hasNUL function #

hasNUL reports whether the NUL character exists within s.

func hasNUL(s string) bool

init function #

func init()

invertSparseEntries function #

invertSparseEntries converts a sparse map from one form to the other. If the input is sparseHoles, then it will output sparseDatas and vice-versa. The input must have been already validated. This function mutates src and returns a normalized map where: - adjacent fragments are coalesced together - only the last fragment may be empty - the endOffset of the last fragment is the total size

func invertSparseEntries(src []sparseEntry, size int64) []sparseEntry

isASCII function #

isASCII reports whether the input is an ASCII C-style string.

func isASCII(s string) bool

isExtended method #

func (s sparseArray) isExtended() []byte

isHeaderOnlyType function #

isHeaderOnlyType checks if the given type flag is of the type that has no data section even if a size is specified.

func isHeaderOnlyType(flag byte) bool

length method #

func (s sparseElem) length() []byte

linkName method #

func (h *headerV7) linkName() []byte

logicalRemaining method #

logicalRemaining implements fileState.logicalRemaining.

func (fw regFileWriter) logicalRemaining() int64

logicalRemaining method #

func (sw sparseFileWriter) logicalRemaining() int64

logicalRemaining method #

logicalRemaining implements fileState.logicalRemaining.

func (fr regFileReader) logicalRemaining() int64

logicalRemaining method #

func (sr sparseFileReader) logicalRemaining() int64

magic method #

func (h *headerGNU) magic() []byte

magic method #

func (h *headerUSTAR) magic() []byte

magic method #

func (h *headerSTAR) magic() []byte

maxEntries method #

func (s sparseArray) maxEntries() int

mayBe method #

func (f *Format) mayBe(f2 Format)

mayOnlyBe method #

func (f *Format) mayOnlyBe(f2 Format)

mergePAX function #

mergePAX merges paxHdrs into hdr for all relevant fields of Header.

func mergePAX(hdr *Header, paxHdrs map[string]string) (err error)

modTime method #

func (h *headerV7) modTime() []byte

mode method #

func (h *headerV7) mode() []byte

mustNotBe method #

func (f *Format) mustNotBe(f2 Format)

mustReadFull function #

mustReadFull is like io.ReadFull except it returns io.ErrUnexpectedEOF when io.EOF is hit before len(b) bytes are read.

func mustReadFull(r io.Reader, b []byte) (int, error)

name method #

func (h *headerV7) name() []byte

next method #

func (tr *Reader) next() (*Header, error)

offset method #

func (s sparseElem) offset() []byte

parseNumeric method #

parseNumeric parses the input as being encoded in either base-256 or octal. This function may return negative numbers. If parsing fails or an integer overflow occurs, err will be set.

func (p *parser) parseNumeric(b []byte) int64

parseOctal method #

func (p *parser) parseOctal(b []byte) int64

parsePAX function #

parsePAX parses PAX headers. If an extended header (type 'x') is invalid, ErrHeader is returned.

func parsePAX(r io.Reader) (map[string]string, error)

parsePAXRecord function #

parsePAXRecord parses the input PAX record string into a key-value pair. If parsing is successful, it will slice off the currently read record and return the remainder as r.

func parsePAXRecord(s string) (k string, v string, r string, err error)

parsePAXTime function #

parsePAXTime takes a string of the form %d.%d as described in the PAX specification. Note that this implementation allows for negative timestamps, which is allowed for by the PAX specification, but not always portable.

func parsePAXTime(s string) (time.Time, error)

parseString method #

parseString parses bytes as a NUL-terminated C-style string. If a NUL byte is not found then the whole slice is returned as a string.

func (*parser) parseString(b []byte) string

physicalRemaining method #

func (sw sparseFileWriter) physicalRemaining() int64

physicalRemaining method #

physicalRemaining implements fileState.physicalRemaining.

func (fw regFileWriter) physicalRemaining() int64

physicalRemaining method #

func (sr sparseFileReader) physicalRemaining() int64

physicalRemaining method #

physicalRemaining implements fileState.physicalRemaining.

func (fr regFileReader) physicalRemaining() int64

prefix method #

func (h *headerSTAR) prefix() []byte

prefix method #

func (h *headerUSTAR) prefix() []byte

readFrom method #

readFrom populates the content of the current file by reading from r. The bytes read must match the number of remaining bytes in the current file. If the current file is sparse and r is an io.ReadSeeker, then readFrom uses Seek to skip past holes defined in Header.SparseHoles, assuming that skipped regions are all NULs. This always reads the last byte to ensure r is the right size. TODO(dsnet): Re-export this when adding sparse file support. See https://golang.org/issue/22735

func (tw *Writer) readFrom(r io.Reader) (int64, error)

readGNUSparseMap0x1 function #

readGNUSparseMap0x1 reads the sparse map as stored in GNU's PAX sparse format version 0.1. The sparse map is stored in the PAX headers.

func readGNUSparseMap0x1(paxHdrs map[string]string) (sparseDatas, error)

readGNUSparseMap1x0 function #

readGNUSparseMap1x0 reads the sparse map as stored in GNU's PAX sparse format version 1.0. The format of the sparse map consists of a series of newline-terminated numeric fields. The first field is the number of entries and is always present. Following this are the entries, consisting of two fields (offset, length). This function must stop reading at the end boundary of the block containing the last newline. Note that the GNU manual says that numeric values should be encoded in octal format. However, the GNU tar utility itself outputs these values in decimal. As such, this library treats values as being encoded in decimal.

func readGNUSparseMap1x0(r io.Reader) (sparseDatas, error)

readGNUSparsePAXHeaders method #

readGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers. If they are found, then this function reads the sparse map and returns it. This assumes that 0.0 headers have already been converted to 0.1 headers by the PAX header parsing logic.

func (tr *Reader) readGNUSparsePAXHeaders(hdr *Header) (sparseDatas, error)

readHeader method #

readHeader reads the next block header and assumes that the underlying reader is already aligned to a block boundary. It returns the raw block of the header in case further processing is required. The err will be set to io.EOF only when one of the following occurs: - Exactly 0 bytes are read and EOF is hit. - Exactly 1 block of zeros is read and EOF is hit. - At least 2 blocks of zeros are read.

func (tr *Reader) readHeader() (*Header, *block, error)

readOldGNUSparseMap method #

readOldGNUSparseMap reads the sparse map from the old GNU sparse format. The sparse map is stored in the tar header if it's small enough. If it's larger than four entries, then one or more extension headers are used to store the rest of the sparse map. The Header.Size does not reflect the size of any extended headers used. Thus, this function will read from the raw io.Reader to fetch extra headers. This method mutates blk in the process.

func (tr *Reader) readOldGNUSparseMap(hdr *Header, blk *block) (sparseDatas, error)

readSpecialFile function #

readSpecialFile is like io.ReadAll except it returns ErrFieldTooLong if more than maxSpecialFileSize is read.

func readSpecialFile(r io.Reader) ([]byte, error)

realSize method #

func (h *headerGNU) realSize() []byte

reset method #

reset clears the block with all zeros.

func (b *block) reset()

setFormat method #

setFormat writes the magic values necessary for specified format and then updates the checksum accordingly.

func (b *block) setFormat(format Format)

size method #

func (h *headerV7) size() []byte

sparse method #

func (h *headerGNU) sparse() sparseArray

splitUSTARPath function #

splitUSTARPath splits a path according to USTAR prefix and suffix rules. If the path is not splittable, then it will return ("", "", false).

func splitUSTARPath(name string) (prefix string, suffix string, ok bool)

statAtime function #

func statAtime(st *syscall.Stat_t) time.Time

statAtime function #

func statAtime(st *syscall.Stat_t) time.Time

statCtime function #

func statCtime(st *syscall.Stat_t) time.Time

statCtime function #

func statCtime(st *syscall.Stat_t) time.Time

statUnix function #

func statUnix(fi fs.FileInfo, h *Header, doNameLookups bool) error

templateV7Plus method #

templateV7Plus fills out the V7 fields of a block using values from hdr. It also fills out fields (uname, gname, devmajor, devminor) that are shared in the USTAR, PAX, and GNU formats using the provided formatters. The block returned is only valid until the next call to templateV7Plus or writeRawFile.

func (tw *Writer) templateV7Plus(hdr *Header, fmtStr stringFormatter, fmtNum numberFormatter) *block

toASCII function #

toASCII converts the input to an ASCII C-style string. This is a best effort conversion, so invalid characters are dropped.

func toASCII(s string) string

toGNU method #

func (b *block) toGNU() *headerGNU

toSTAR method #

func (b *block) toSTAR() *headerSTAR

toSparse method #

func (b *block) toSparse() sparseArray

toUSTAR method #

func (b *block) toUSTAR() *headerUSTAR

toV7 method #

Convert block to any number of formats.

func (b *block) toV7() *headerV7

trailer method #

func (h *headerSTAR) trailer() []byte

tryReadFull function #

tryReadFull is like io.ReadFull except it returns io.EOF when it is hit before len(b) bytes are read.

func tryReadFull(r io.Reader, b []byte) (n int, err error)

typeFlag method #

func (h *headerV7) typeFlag() []byte

uid method #

func (h *headerV7) uid() []byte

userName method #

func (h *headerUSTAR) userName() []byte

userName method #

func (h *headerGNU) userName() []byte

userName method #

func (h *headerSTAR) userName() []byte

v7 method #

func (h *headerUSTAR) v7() *headerV7

v7 method #

func (h *headerSTAR) v7() *headerV7

v7 method #

func (h *headerGNU) v7() *headerV7

validPAXRecord function #

validPAXRecord reports whether the key-value pair is valid where each record is formatted as: "%d %s=%s\n" % (size, key, value) Keys and values should be UTF-8, but the number of bad writers out there forces us to be a more liberal. Thus, we only reject all keys with NUL, and only reject NULs in values for the PAX version of the USTAR string fields. The key must not contain an '=' character.

func validPAXRecord(k string, v string) bool

validateSparseEntries function #

validateSparseEntries reports whether sp is a valid sparse map. It does not matter whether sp represents data fragments or hole fragments.

func validateSparseEntries(sp []sparseEntry, size int64) bool

version method #

func (h *headerUSTAR) version() []byte

version method #

func (h *headerSTAR) version() []byte

version method #

func (h *headerGNU) version() []byte

writeGNUHeader method #

func (tw *Writer) writeGNUHeader(hdr *Header) error

writePAXHeader method #

func (tw *Writer) writePAXHeader(hdr *Header, paxHdrs map[string]string) error

writeRawFile method #

writeRawFile writes a minimal file with the given name and flag type. It uses format to encode the header format and will write data as the body. It uses default values for all of the other fields (as BSD and GNU tar does).

func (tw *Writer) writeRawFile(name string, data string, flag byte, format Format) error

writeRawHeader method #

writeRawHeader writes the value of blk, regardless of its value. It sets up the Writer such that it can accept a file of the given size. If the flag is a special header-only flag, then the size is treated as zero.

func (tw *Writer) writeRawHeader(blk *block, size int64, flag byte) error

writeTo method #

writeTo writes the content of the current file to w. The bytes written matches the number of remaining bytes in the current file. If the current file is sparse and w is an io.WriteSeeker, then writeTo uses Seek to skip past holes defined in Header.SparseHoles, assuming that skipped regions are filled with NULs. This always writes the last byte to ensure w is the right size. TODO(dsnet): Re-export this when adding sparse file support. See https://golang.org/issue/22735

func (tr *Reader) writeTo(w io.Writer) (int64, error)

writeUSTARHeader method #

func (tw *Writer) writeUSTARHeader(hdr *Header) error

Generated with Arrow