Пример #1
0
 /**
  * Get the file entries from the archive.
  *
  * @param string|array(string) $files  Array or a single path to a file.
  * @param string $prefix               First part of the path used in $files.
  *
  * @return ezcArchiveEntry
  */
 protected function getEntries($files, $prefix)
 {
     if (!is_array($files)) {
         $files = array($files);
     }
     // Check whether the files are correct.
     foreach ($files as $file) {
         if (!file_exists($file) && !is_link($file)) {
             throw new ezcBaseFileNotFoundException($file);
         }
     }
     // Search for all the entries, because otherwise hardlinked files show up as an ordinary file.
     return ezcArchiveEntry::getEntryFromFile($files, $prefix);
 }
Пример #2
0
 /**
  * Appends a file to the archive after the current entry.
  *
  * One or multiple files can be added directly after the current file.
  * The remaining entries after the current are removed from the archive!
  *
  * The $files can either be a string or an array of strings. Which, respectively, represents a
  * single file or multiple files.
  *
  * $prefix specifies the begin part of the $files path that should not be included in the archive.
  * The files in the archive are always stored relatively.
  *
  * Example:
  * <code>
  * $tar = ezcArchive( "/tmp/my_archive.tar", ezcArchive::TAR );
  *
  * // Append two files to the end of the archive.
  * $tar->seek( 0, SEEK_END );
  * $tar->appendToCurrent( array( "/home/rb/file1.txt", "/home/rb/file2.txt" ), "/home/rb/" );
  * </code>
  *
  * When multiple files are added to the archive at the same time, thus using an array, does not
  * necessarily produce the same archive as repeatively adding one file to the archive.
  * For example, the Tar archive format, can detect that files hardlink to each other and will store
  * it in a more efficient way.
  *
  * @throws ezcArchiveException            if the archive is closed or read-only
  * @throws ezcBaseFileNotFoundException   if one of the specified files is missing
  * @throws ezcBaseFilePermissionException if the archive is not writable
  *
  * @param string|array(string) $files  Array or a single path to a file.
  * @param string $prefix               First part of the path used in $files.
  * @return bool
  */
 public function appendToCurrent($files, $prefix)
 {
     if (!$this->isWritable()) {
         throw new ezcBaseFilePermissionException($this->file->getFileName(), ezcBaseFilePermissionException::WRITE, "Archive is read-only");
     }
     // Current position valid?
     if (!$this->isEmpty() && !$this->valid()) {
         return false;
     }
     if (!is_array($files)) {
         $files = array($files);
     }
     // Check whether the files are correct.
     foreach ($files as $file) {
         if (!file_exists($file) && !is_link($file)) {
             throw new ezcBaseFileNotFoundException($file);
         }
     }
     // Search for all the entries, because otherwise hardlinked files show up as an ordinary file.
     $entries = ezcArchiveEntry::getEntryFromFile($files, $prefix);
     if ($this->isEmpty()) {
         $this->file->truncate();
         $this->file->rewind();
         $cur = -1;
     } else {
         // Create the new headers.
         $cur = $this->key();
         // Current Header.
         $lh = $this->getLocalHeader($cur);
         $pos = $this->localHeaderPositions[$cur] + $lh->getHeaderSize() + $lh->compressedSize;
         $this->file->truncate($pos);
         $this->file->seek($pos);
     }
     foreach ($entries as $entry) {
         $cur++;
         // Set local header position
         $this->localHeaderPositions[$cur] = $this->file->getPosition();
         // Set local header
         $this->localHeaders[$cur] = new ezcArchiveLocalFileHeader();
         $this->localHeaders[$cur]->setHeaderFromArchiveEntry($entry);
         if ($entry->isSymLink()) {
             $fileData = $entry->getLink();
             $this->localHeaders[$cur]->setCompression(0, $this->localHeaders[$cur]->uncompressedSize);
             // Compression is 0, for now.
         } else {
             if ($entry->isDirectory()) {
                 // Added for issue #13517: Not possible to add directories to an archive on Windows
                 $fileData = gzdeflate('');
                 // empty string for directories
                 $this->localHeaders[$cur]->setCompression(8, strlen($fileData));
             } else {
                 // FIXME, File in memory, compression level always 8, add constants.
                 $fileData = gzdeflate(file_get_contents($entry->getPath()));
                 $this->localHeaders[$cur]->setCompression(8, strlen($fileData));
             }
         }
         $this->localHeaders[$cur]->writeEncodedHeader($this->file);
         // Write link or file.
         $this->file->write($fileData);
         unset($fileData);
         // Create also the central headers.
         $this->centralHeaders[$cur] = new ezcArchiveCentralDirectoryHeader();
         $this->centralHeaders[$cur]->setHeaderFromLocalFileHeader($this->localHeaders[$cur]);
         $this->centralHeaders[$cur]->setHeaderFromArchiveEntry($entry);
         $this->centralHeaders[$cur]->relativeHeaderOffset = $this->localHeaderPositions[$cur];
         // Set the entry.
         $entry->removePrefixFromPath();
         $this->entries[$cur] = $entry;
     }
     for ($i = 0; $i <= $cur; $i++) {
         // Write the headers.
         $this->centralHeaderPositions[$i] = $this->file->getPosition();
         $this->centralHeaders[$i]->writeEncodedHeader($this->file);
     }
     // Remove the rest of the localHeaders and centralHeaders.
     for ($i = $cur + 1; $i < $this->entriesRead; $i++) {
         unset($this->localHeaders[$i]);
         unset($this->localHeaderPositions[$i]);
         unset($this->centralHeaders[$i]);
         unset($this->centralHeaderPositions[$i]);
     }
     $this->entriesRead = $cur + 1;
     // Write the end record.
     $this->endRecord = new ezcArchiveCentralDirectoryEndHeader();
     $this->endRecord->centralDirectoryStart = $this->centralHeaderPositions[0];
     $this->endRecord->centralDirectorySize = $this->file->getPosition() - $this->centralHeaderPositions[0];
     $this->endRecord->totalCentralDirectoryEntries = $cur + 1;
     $this->endRecord->writeEncodedHeader($this->file);
 }