Oihana PHP

untarEntries.php

Table of Contents

Functions

untarEntries()  : array<int, array{name: string, size: int, directory: bool}>
Lists what an archive holds, without extracting it.

Functions

untarEntries()

Lists what an archive holds, without extracting it.

untarEntries(string $binary, string $tarFile) : array<int, array{name: string, size: int, directory: bool}>

The listing pass of untar(). It exists because three of that function's guarantees — a dry run, refusing to overwrite, and the decompression-bomb cap — all need to know the contents before the first byte is written, and tar will not tell and extract in one go. The pass streams: tar reads headers and reports, so a 2 GB archive costs a listing, not a copy.

It runs tar -tvf with three flags that are not decoration:

  • --quoting-style=literal, because the default style escapes unusual characters, so a name would come back spelled differently from the name on disk;
  • --numeric-owner, so the owner column is 501/0 and cannot contain a space, which is what lets the name be read as everything after the time;
  • LC_ALL=C, so the date column keeps the one shape this parses.

A line that does not parse raises. It would be easier to skip it, and that is exactly what must not happen: a maxExtractedSize computed from a listing with a hole in it is a cap that under-counts, which is to say a guard that no longer guards. The known case is a filename containing a newline, which no line-based listing can represent — rare, legal on POSIX, and reported rather than ignored.

Parameters
$binary : string

The GNU tar to run, from tarBinary().

$tarFile : string

Path to the archive.

Tags
throws
RuntimeException

If tar cannot read the archive, or prints a line this cannot parse.

example
use function oihana\files\archive\tar\tarBinary;
use function oihana\files\archive\tar\untarEntries;

foreach ( untarEntries( tarBinary() , '/backups/site.tar.gz' ) as $entry )
{
    printf( "%-60s %d\n" , $entry[ 'name' ] , $entry[ 'size' ] ) ;
}
author

Marc Alcaraz (ekameleon)

since
1.5.0
Return values
array<int, array{name: string, size: int, directory: bool}> —

One entry per member, in archive order. A link's name stops before its -> target.

On this page

Search results