4 * This file is part of Zippy.
6 * (c) Alchemy <info@alchemy.fr>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
11 namespace Alchemy\Zippy\Parser;
13 use Alchemy\Zippy\Exception\RuntimeException;
16 * This class is responsible of parsing GNUTar command line output
18 class BSDTarOutputParser implements ParserInterface
20 const PERMISSIONS = '([ldrwx-]+)';
21 const HARD_LINK = '(\d+)';
22 const OWNER = '([a-z][-a-z0-9]*)';
23 const GROUP = '([a-z][-a-z0-9]*)';
24 const FILESIZE = '(\d*)';
25 const DATE = '([a-zA-Z0-9]+\s+[a-z0-9]+\s+[a-z0-9:]+)';
26 const FILENAME = '(.*)';
31 public function parseFileListing($output)
33 $lines = array_values(array_filter(explode("\n", $output)));
36 // BSDTar outputs two differents format of date according to the mtime
37 // of the member. If the member is younger than six months the year is not shown.
38 // On 4.5+ FreeBSD system the day is displayed first
39 $dateFormats = array('M d Y', 'M d H:i', 'd M Y', 'd M H:i');
41 foreach ($lines as $line) {
44 // drw-rw-r-- 0 toto titi 0 Jan 3 1980 practice/
45 // -rw-rw-r-- 0 toto titi 10240 Jan 22 13:31 practice/records
46 if (!preg_match_all("#" .
47 self::PERMISSIONS . "\s+" . // match (drw-r--r--)
48 self::HARD_LINK . "\s+" . // match (1)
49 self::OWNER . "\s" . // match (toto)
50 self::GROUP . "\s+" . // match (titi)
51 self::FILESIZE . "\s+" . // match (0)
52 self::DATE . "\s+" . // match (Jan 3 1980)
53 self::FILENAME . // match (practice)
54 "#", $line, $matches, PREG_SET_ORDER
59 $chunks = array_shift($matches);
61 if (8 !== count($chunks)) {
67 foreach ($dateFormats as $format) {
68 $date = \DateTime::createFromFormat($format, $chunks[6]);
70 if (false === $date) {
77 if (false === $date) {
78 throw new RuntimeException(sprintf('Failed to parse mtime date from %s', $line));
82 'location' => $chunks[7],
85 'is_dir' => 'd' === $chunks[1][0]
95 public function parseInflatorVersion($output)
97 $chunks = explode(' ', $output, 3);
99 if (2 > count($chunks)) {
103 list(, $version) = explode(' ', $output, 3);
111 public function parseDeflatorVersion($output)
113 return $this->parseInflatorVersion($output);