Beispiel #1
0
 /**
  * @param \OCP\Files\Storage $sourceStorage
  * @param string $sourceInternalPath
  * @param string $targetInternalPath
  * @param bool $preserveMtime
  * @return bool
  */
 public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false)
 {
     if ($sourceStorage === $this) {
         return $this->copy($sourceInternalPath, $targetInternalPath);
     }
     if ($sourceStorage->is_dir($sourceInternalPath)) {
         $dh = $sourceStorage->opendir($sourceInternalPath);
         $result = $this->mkdir($targetInternalPath);
         if (is_resource($dh)) {
             while ($result and ($file = readdir($dh)) !== false) {
                 if (!Filesystem::isIgnoredDir($file)) {
                     $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file);
                 }
             }
         }
     } else {
         $source = $sourceStorage->fopen($sourceInternalPath, 'r');
         // TODO: call fopen in a way that we execute again all storage wrappers
         // to avoid that we bypass storage wrappers which perform important actions
         // for this operation. Same is true for all other operations which
         // are not the same as the original one.Once this is fixed we also
         // need to adjust the encryption wrapper.
         $target = $this->fopen($targetInternalPath, 'w');
         list(, $result) = \OC_Helper::streamCopy($source, $target);
         if ($result and $preserveMtime) {
             $this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath));
         }
         fclose($source);
         fclose($target);
         if (!$result) {
             // delete partially written target file
             $this->unlink($targetInternalPath);
             // delete cache entry that was created by fopen
             $this->getCache()->remove($targetInternalPath);
         }
     }
     return (bool) $result;
 }
 /**
  * copy file between two storages
  *
  * @param Storage $sourceStorage
  * @param string $sourceInternalPath
  * @param string $targetInternalPath
  * @param bool $preserveMtime
  * @param bool $isRename
  * @return bool
  */
 private function copyBetweenStorage(Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime, $isRename)
 {
     // first copy the keys that we reuse the existing file key on the target location
     // and don't create a new one which would break versions for example.
     $mount = $this->mountManager->findByStorageId($sourceStorage->getId());
     if (count($mount) === 1) {
         $mountPoint = $mount[0]->getMountPoint();
         $source = $mountPoint . '/' . $sourceInternalPath;
         $target = $this->getFullPath($targetInternalPath);
         $this->copyKeys($source, $target);
     } else {
         $this->logger->error('Could not find mount point, can\'t keep encryption keys');
     }
     if ($sourceStorage->is_dir($sourceInternalPath)) {
         $dh = $sourceStorage->opendir($sourceInternalPath);
         $result = $this->mkdir($targetInternalPath);
         if (is_resource($dh)) {
             while ($result and ($file = readdir($dh)) !== false) {
                 if (!Filesystem::isIgnoredDir($file)) {
                     $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file);
                 }
             }
         }
     } else {
         $source = $sourceStorage->fopen($sourceInternalPath, 'r');
         $target = $this->fopen($targetInternalPath, 'w');
         list(, $result) = \OC_Helper::streamCopy($source, $target);
         fclose($source);
         fclose($target);
         if ($result) {
             if ($preserveMtime) {
                 $this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath));
             }
             $isEncrypted = $this->mount->getOption('encrypt', true) ? 1 : 0;
             // in case of a rename we need to manipulate the source cache because
             // this information will be kept for the new target
             if ($isRename) {
                 $sourceStorage->getCache()->put($sourceInternalPath, ['encrypted' => $isEncrypted]);
             } else {
                 $this->getCache()->put($targetInternalPath, ['encrypted' => $isEncrypted]);
             }
         } else {
             // delete partially written target file
             $this->unlink($targetInternalPath);
             // delete cache entry that was created by fopen
             $this->getCache()->remove($targetInternalPath);
         }
     }
     return (bool) $result;
 }