/** * Returns an array with pax header information. * * This method reads an extended set of data from the ezcArchiveBlockFile * $file and returns the values in an array. * * @param ezcArchiveBlockFile $file * @return array(string=>string) */ protected function getPaxDecodedHeader(ezcArchiveBlockFile $file) { $result = array(); // next block has the info. $file->next(); $data = $file->current(); $offset = 0; while (strcmp($data[$offset], "") != 0) { $space = strpos($data, " ", $offset); $length = substr($data, $offset, $space - $offset); $equalSign = strpos($data, "=", $space); $keyword = substr($data, $space + 1, $equalSign - $space - 1); $value = rtrim(substr($data, $equalSign + 1, $length - $equalSign - 1), "\n"); $result[$keyword] = $value; $offset += $length; } return $result; }
/** * Reads an extended set of data from the Block file and returns it as a string. * * Some filenames or link names do not fit in the Ustar header, and are therefor placed in a new block. * This method read the block(s) and returns the data as a string. * * @param ezcArchiveBlockFile $file * @return string */ protected function readExtension(ezcArchiveBlockFile $file) { $completeBlocks = (int) ($this->fileSize / self::BLOCK_SIZE); $rest = $this->fileSize % self::BLOCK_SIZE; $data = ""; for ($i = 0; $i < $completeBlocks; $i++) { $data .= $file->next(); } $data .= substr($file->next(), 0, $rest); $file->next(); return $data; }
/** * Serializes this header and appends it to the given ezcArchiveBlockFile $archiveFile. * * @param ezcArchiveBlockFile $archiveFile * @return void */ public function writeEncodedHeader(ezcArchiveBlockFile $archiveFile) { // Offset | Field size | Description // ---------------------------------- // 0 | 100 | Name of file // 100 | 8 | File mode // 108 | 8 | Owner user ID // 116 | 8 | Owner group ID // 124 | 12 | Length of file in bytes // 136 | 12 | Modify time of file // 148 | 8 | Checksum for header // 156 | 1 | Type flag. // 157 | 100 | Name of linked file // 257 | 6 | USTAR indicator. // 263 | 2 | USTAR version. // 265 | 32 | Owner user name. // 297 | 32 | Owner group name. // 329 | 8 | Major device number. // 337 | 8 | Minor device number. // 345 | 155 | Filename prefix. // 500 | 12 | NUL. if (ezcBaseFeatures::hasFunction('posix_getpwuid')) { $posixName = posix_getpwuid($this->userId); $posixGroup = posix_getgrgid($this->groupId); } else { $posixName['name'] = 'nobody'; $posixGroup['name'] = 'nogroup'; } $enc = pack("a100a8a8a8a12a12a8a1a100a6a2a32a32a8a8a155a12", $this->fileName, str_pad($this->fileMode, 7, "0", STR_PAD_LEFT), str_pad(decoct($this->userId), 7, "0", STR_PAD_LEFT), str_pad(decoct($this->groupId), 7, "0", STR_PAD_LEFT), str_pad(decoct($this->fileSize), 11, "0", STR_PAD_LEFT), str_pad(decoct($this->modificationTime), 11, "0", STR_PAD_LEFT), " ", $this->type, $this->linkName, "ustar", "00", $posixName["name"], $posixGroup["name"], sprintf("%07s", decoct($this->deviceMajorNumber)), sprintf("%07s", decoct($this->deviceMinorNumber)), $this->filePrefix, ""); $enc = $this->setChecksum($enc); $archiveFile->append($enc); }
public function testCompressedStream() { $dir = $this->createTempDir("ezcArchive_"); // $file = $dir . "/blockfile"; $file = "compress.zlib://" . $dir . "/blockfile"; // Create the file. // Blocksize = 4. $bf = new ezcArchiveBlockFile($file, true, 4); $this->assertFalse($bf->valid()); // Exact 1 block. $bf->append("abcd"); $this->assertTrue($bf->valid()); $this->assertEquals(0, $bf->key(), "Current block should be 0"); $this->assertEquals(0, $bf->getLastBlockNumber(), "Last block should be 0"); // halve block. $bf->append("ef"); $this->assertEquals(1, $bf->key(), "Current block should be 1"); $this->assertEquals(1, $bf->getLastBlockNumber(), "Last block should be 1"); // File should contain: abcdef\0\0 $this->assertEquals("abcdef", file_get_contents($file)); $bf->rewind(); $this->assertEquals(0, $bf->key(), "Current block should be 0"); $this->assertEquals("abcd", $bf->current()); $this->assertTrue($bf->valid()); $this->assertEquals(1, $bf->getLastBlockNumber()); try { $bf->append("ZZ"); $this->fail("Expected an exception that the block could not be appended in the middle"); } catch (ezcArchiveException $e) { } $bf->next(); $bf->append("ZZ"); $this->assertEquals(2, $bf->key(), "Current block should be 0"); $this->assertEquals("ZZ", $bf->current()); $this->assertTrue($bf->valid()); $this->assertEquals(2, $bf->getLastBlockNumber()); }
public function testTruncateAmountOfBlocks() { if (!$this->canWrite) { return; } $blockFile = new ezcArchiveBlockFile($this->file); $i = 1; while ($blockFile->next()) { $i++; } $this->assertEquals(20, $i, "Expected 20 blocks in the file."); $blockFile->seek(2); $this->assertFalse($blockFile->isNullBlock(), "Didn't expect a null block."); $blockFile->seek(3); $this->assertFalse($blockFile->isNullBlock(), "Didn't expect a null block."); $blockFile->seek(4); $this->assertTrue($blockFile->isNullBlock(), "Expected a null block."); // Give the block File to the archive. $archive = new ezcArchiveV7Tar($blockFile); $entry = $archive->current(); // A non rewinded block file, does that work? $this->assertEquals("file1.txt", $entry->getPath()); $archive->truncate(1); // keep the first file. $archive->close(); $blockFile = new ezcArchiveBlockFile($this->file); // Should be 20 blocks.. $i = 1; while ($blockFile->next()) { $i++; } $this->assertEquals(20, $i, "Expected 20 blocks in the file."); $blockFile->seek(0); $this->assertFalse($blockFile->isNullBlock(), "Didn't expect a null block."); $blockFile->seek(1); $this->assertFalse($blockFile->isNullBlock(), "Didn't expect a null block."); $blockFile->seek(2); $this->assertTrue($blockFile->isNullBlock(), "Expected a null block."); unset($blockFile); }
/** * Serializes this header and appends it to the given ezcArchiveBlockFile $archiveFile. * * @param ezcArchiveBlockFile $archiveFile * @return void */ public function writeEncodedHeader(ezcArchiveBlockFile $archiveFile) { // Offset | Field size | Description // ---------------------------------- // 0 | 100 | Name of file // 100 | 8 | File mode // 108 | 8 | Owner user ID // 116 | 8 | Owner group ID // 124 | 12 | Length of file in bytes // 136 | 12 | Modify time of file // 148 | 8 | Checksum for header // 156 | 1 | Indicator for links // 157 | 100 | Name of linked file // ------------------------------------------ // 257 | 72 | NUL. // 329 | 8 | Compatibility with GNU tar: Major device set to: 00000000. // 337 | 8 | Compatibility with GNU tar: Minor device set to: 00000000. // 345 | 167 | NUL. // $enc = pack("a100a8a8a8a12a12a8a1a100a72a8a8a167", $this->fileName, str_pad($this->fileMode, 7, "0", STR_PAD_LEFT), str_pad(decoct($this->userId), 7, "0", STR_PAD_LEFT), str_pad(decoct($this->groupId), 7, "0", STR_PAD_LEFT), str_pad(decoct($this->fileSize), 11, "0", STR_PAD_LEFT), str_pad(decoct($this->modificationTime), 11, "0", STR_PAD_LEFT), " ", $this->type, $this->linkName, "", "0000000", "0000000", ""); $enc = $this->setChecksum($enc); $archiveFile->append($enc); }