Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / MediaSetAccess.cc
index be3b4e0..a7c5f8d 100644 (file)
@@ -62,8 +62,6 @@ IMPL_PTR_TYPE(MediaSetAccess);
       media_mgr.addVerifier( id, verifier );
       // remove any saved verifier for this media
       _verifiers.erase(media_nr);
-      //if (! noattach && ! media_mgr.isAttached(id))
-      //media_mgr.attach(id);
     }
     else
     {
@@ -73,16 +71,6 @@ IMPL_PTR_TYPE(MediaSetAccess);
     }
   }
 
-//       callback::SendReport<source::DownloadFileReport> report;
-//       DownloadProgressFileReceiver download_report( report );
-//       SourceFactory source_factory;
-//       Url file_url( url().asString() + file_r.asString() );
-//       report->start( source_factory.createFrom(this), file_url );
-//       callback::TempConnect<media::DownloadProgressReport> tmp_download( download_report );
-//       Pathname file = provideJustFile( file_r, media_nr, cached, checkonly );
-//       report->finish( file_url, source::DownloadFileReport::NO_ERROR, "" );
-//       return file;
-
   void MediaSetAccess::releaseFile( const OnMediaLocation & on_media_file )
   {
     releaseFile( on_media_file.filename(), on_media_file.medianr() );
@@ -112,146 +100,93 @@ IMPL_PTR_TYPE(MediaSetAccess);
 
     // try to attach the media
     if ( ! media_mgr.isAttached(media) )
-        media_mgr.attachDesiredMedia(media);
+        media_mgr.attach(media);
 
     media_mgr.dirInfo(media, retlist, dirname, dots);
   }
 
-  Pathname MediaSetAccess::provideFile( const OnMediaLocation & on_media_file )
+  struct ProvideFileOperation
   {
-    return provideFile( on_media_file.filename(), on_media_file.medianr() );
-  }
-
+    Pathname result;
+    void operator()( media::MediaAccessId media, const Pathname &file )
+    {
+      media::MediaManager media_mgr;
+      media_mgr.provideFile(media, file);
+      result = media_mgr.localPath(media, file);
+    }
+  };
 
-  Pathname MediaSetAccess::provideFile(const Pathname & file, unsigned media_nr )
+  struct ProvideDirTreeOperation
   {
-    return provideFileInternal( file, media_nr, false, false);
-  }
+    Pathname result;
+    void operator()( media::MediaAccessId media, const Pathname &file )
+    {
+      media::MediaManager media_mgr;
+      media_mgr.provideDirTree(media, file);
+      result = media_mgr.localPath(media, file);
+    }
+  };
 
-  bool MediaSetAccess::doesFileExist(const Pathname & file, unsigned media_nr )
+  struct ProvideDirOperation
   {
-    callback::SendReport<media::MediaChangeReport> report;
-    media::MediaManager media_mgr;
-
-    bool exists = false;
-
-    do
+    Pathname result;
+    void operator()( media::MediaAccessId media, const Pathname &file )
     {
-      // get the mediaId, but don't try to attach it here
-      media::MediaAccessId media = getMediaAccessId( media_nr);
-
-      try
-      {
-        DBG << "Cheking if file " << file
-            << " from media number " << media_nr << " exists." << endl;
-        // try to attach the media
-        if ( ! media_mgr.isAttached(media) )
-          media_mgr.attachDesiredMedia(media);
-        exists = media_mgr.doesFileExist(media, file);
-        break;
-      }
-      catch ( media::MediaException & excp )
-      {
-        ZYPP_CAUGHT(excp);
-        media::MediaChangeReport::Action user;
-        do
-        {
-          DBG << "Media couldn't provide file " << file << " , releasing." << endl;
-          try
-          {
-            media_mgr.release (media);
-          }
-          catch (const Exception & excpt_r)
-          {
-              ZYPP_CAUGHT(excpt_r);
-              MIL << "Failed to release media " << media << endl;
-          }
-
-          // set up the reason
-          media::MediaChangeReport::Error reason = media::MediaChangeReport::INVALID;
-
-          if( typeid(excp) == typeid( media::MediaFileNotFoundException )  ||
-              typeid(excp) == typeid( media::MediaNotAFileException ) )
-          {
-            reason = media::MediaChangeReport::NOT_FOUND;
-          }
-          else if( typeid(excp) == typeid( media::MediaNotDesiredException)  ||
-              typeid(excp) == typeid( media::MediaNotAttachedException) )
-          {
-            reason = media::MediaChangeReport::WRONG;
-          }
-          else if( typeid(excp) == typeid( media::MediaTimeoutException))
-          {
-            reason = media::MediaChangeReport::IO_SOFT;
-          }
+      media::MediaManager media_mgr;
+      media_mgr.provideDir(media, file);
+      result = media_mgr.localPath(media, file);
+    }
+  };
 
-          vector<string> devices;
-          unsigned int devindex;
-          media_mgr.getDetectedDevices(media, devices, devindex);
+  struct ProvideFileExistenceOperation
+  {
+    bool result;
+    ProvideFileExistenceOperation()
+        : result(false)
+    {}
 
-          // release all media before requesting another (#336881)
-          media_mgr.releaseAll();
+    void operator()( media::MediaAccessId media, const Pathname &file )
+    {
+      media::MediaManager media_mgr;
+      result = media_mgr.doesFileExist(media, file);
+    }
+  };
 
-          user = report->requestMedia (
-              _url,
-              media_nr,
-              _label,
-              reason,
-              excp.asUserString(),
-              devices, devindex
-            );
 
-          MIL << "doesFileExist exception caught, callback answer: " << user << endl;
 
-          if( user == media::MediaChangeReport::ABORT )
-          {
-            DBG << "Aborting" << endl;
-            ZYPP_RETHROW ( excp );
-          }
-          else if ( user == media::MediaChangeReport::IGNORE )
-          {
-            DBG << "Skipping" << endl;
-           SkipRequestException nexcp("User-requested skipping of a file");
-           nexcp.remember(excp);
-           ZYPP_THROW(nexcp);
-          }
-          else if ( user == media::MediaChangeReport::EJECT )
-          {
-            DBG << "Eject: try to release" << endl;
-            media_mgr.releaseAll();
-            // eject
-            media_mgr.release (media,
-              devindex < devices.size() ? devices[devindex] : "");
-          }
-          else if ( user == media::MediaChangeReport::RETRY  ||
-            user == media::MediaChangeReport::CHANGE_URL )
-          {
-            // retry
-            DBG << "Going to try again" << endl;
-            // invalidate current media access id
-            media_mgr.close(media);
-            _medias.erase(media_nr);
-
-            // not attaching, media set will do that for us
-            // this could generate uncaught exception (#158620)
-            break;
-          }
-          else
-          {
-            DBG << "Don't know, let's ABORT" << endl;
-            ZYPP_RETHROW ( excp );
-          }
-        } while( user == media::MediaChangeReport::EJECT );
-      }
+  Pathname MediaSetAccess::provideFile( const OnMediaLocation & resource, ProvideFileOptions options, const Pathname &deltafile )
+  {
+    ProvideFileOperation op;
+    provide( boost::ref(op), resource, options, deltafile );
+    return op.result;
+  }
 
-      // retry or change URL
-    } while( true );
+  Pathname MediaSetAccess::provideFile(const Pathname & file, unsigned media_nr, ProvideFileOptions options )
+  {
+    OnMediaLocation resource;
+    ProvideFileOperation op;
+    resource.setLocation(file, media_nr);
+    provide( boost::ref(op), resource, options, Pathname() );
+    return op.result;
+  }
 
-    return exists;
+  bool MediaSetAccess::doesFileExist(const Pathname & file, unsigned media_nr )
+  {
+    ProvideFileExistenceOperation op;
+    OnMediaLocation resource;
+    resource.setLocation(file, media_nr);
+    provide( boost::ref(op), resource, PROVIDE_DEFAULT, Pathname());
+    return op.result;
   }
 
-  Pathname MediaSetAccess::provideFileInternal(const Pathname & file, unsigned media_nr, bool cached, bool checkonly )
+  void MediaSetAccess::provide( ProvideOperation op,
+                                const OnMediaLocation &resource,
+                                ProvideFileOptions options,
+                                const Pathname &deltafile )
   {
+    Pathname file(resource.filename());
+    unsigned media_nr(resource.medianr());
+
     callback::SendReport<media::MediaChangeReport> report;
     media::MediaManager media_mgr;
 
@@ -261,20 +196,26 @@ IMPL_PTR_TYPE(MediaSetAccess);
     {
       // get the mediaId, but don't try to attach it here
       media = getMediaAccessId( media_nr);
+      bool deltafileset = false;
 
       try
       {
-        DBG << "Going to try to provide file " << file
+        DBG << "Going to try to provide " << (resource.optional() ? "optional" : "") << " file " << file
             << " from media number " << media_nr << endl;
         // try to attach the media
         if ( ! media_mgr.isAttached(media) )
-          media_mgr.attachDesiredMedia(media);
-        media_mgr.provideFile (media, file, false, false);
+          media_mgr.attach(media);
+       media_mgr.setDeltafile(media, deltafile);
+       deltafileset = true;
+        op(media, file);
+       media_mgr.setDeltafile(media, Pathname());
         break;
       }
       catch ( media::MediaException & excp )
       {
         ZYPP_CAUGHT(excp);
+       if (deltafileset)
+         media_mgr.setDeltafile(media, Pathname());
         media::MediaChangeReport::Action user = media::MediaChangeReport::ABORT;
         unsigned int devindex = 0;
         vector<string> devices;
@@ -309,10 +250,20 @@ IMPL_PTR_TYPE(MediaSetAccess);
           {
             reason = media::MediaChangeReport::WRONG;
           }
+          else if( typeid(excp) == typeid( media::MediaTimeoutException) ||
+                   typeid(excp) == typeid( media::MediaTemporaryProblemException))
+          {
+            reason = media::MediaChangeReport::IO_SOFT;
+          }
 
-
-          if (checkonly)
-            user  = media::MediaChangeReport::ABORT;
+          // Propagate the original error if _no_ callback receiver is connected, or
+         // non_interactive mode (for optional files) is used (except for wrong media).
+          if ( ! callback::SendReport<media::MediaChangeReport>::connected()
+            || (( options & PROVIDE_NON_INTERACTIVE ) && reason != media::MediaChangeReport::WRONG ) )
+          {
+              MIL << "Can't provide file. Non-Interactive mode." << endl;
+              ZYPP_RETHROW(excp);
+          }
           else
           {
             // release all media before requesting another (#336881)
@@ -334,7 +285,9 @@ IMPL_PTR_TYPE(MediaSetAccess);
           if( user == media::MediaChangeReport::ABORT )
           {
             DBG << "Aborting" << endl;
-            ZYPP_RETHROW ( excp );
+            AbortRequestException aexcp("Aborting requested by user");
+            aexcp.remember(excp);
+            ZYPP_THROW(aexcp);
           }
           else if ( user == media::MediaChangeReport::IGNORE )
           {
@@ -346,10 +299,15 @@ IMPL_PTR_TYPE(MediaSetAccess);
           else if ( user == media::MediaChangeReport::EJECT )
           {
             DBG << "Eject: try to release" << endl;
-            media_mgr.releaseAll();
-            // eject
-            media_mgr.release (media,
-              devindex < devices.size() ? devices[devindex] : "");
+           try
+           {
+             media_mgr.releaseAll();
+             media_mgr.release (media, devindex < devices.size() ? devices[devindex] : "");
+           }
+           catch ( const Exception & e)
+           {
+             ZYPP_CAUGHT(e);
+           }
           }
           else if ( user == media::MediaChangeReport::RETRY  ||
             user == media::MediaChangeReport::CHANGE_URL )
@@ -374,145 +332,24 @@ IMPL_PTR_TYPE(MediaSetAccess);
 
       // retry or change URL
     } while( true );
-
-    return media_mgr.localPath( media, file );
   }
 
-
   Pathname MediaSetAccess::provideDir(const Pathname & dir,
                                       bool recursive,
-                                      unsigned media_nr)
+                                      unsigned media_nr,
+                                      ProvideFileOptions options )
   {
-    callback::SendReport<media::MediaChangeReport> report;
-    media::MediaManager media_mgr;
-    media::MediaAccessId _media;
-
-    do
+    OnMediaLocation resource;
+    resource.setLocation(dir, media_nr);
+    if ( recursive )
     {
-      // get the mediaId, but don't try to attach it here
-      _media = getMediaAccessId(media_nr);
-
-      try
-      {
-        DBG << "Going to try provide direcotry " << dir
-            << (recursive ? " (recursively)" : "")
-            << " from media nr. " << media_nr << endl;
-
-        // try to attach the media
-        if (!media_mgr.isAttached(_media))
-          media_mgr.attachDesiredMedia(_media);
-
-        _media = getMediaAccessId(media_nr); // in case of redirect
-
-        if (recursive)
-          media_mgr.provideDirTree(_media, dir);
-        else
-          media_mgr.provideDir(_media, dir);
-
-        break; // quit the retry loop
-      }
-      catch (media::MediaException & excp)
-      {
-        ZYPP_CAUGHT(excp);
-        media::MediaChangeReport::Action user;
-
-        do
-        {
-          DBG << "Media couldn't provide dir " << dir << ", releasing." << endl;
-          try
-          {
-            media_mgr.release (_media);
-          }
-          catch (const Exception & excpt_r)
-          {
-            ZYPP_CAUGHT(excpt_r);
-            ERR << "Failed to release media " << _media << endl;
-          }
-
-          //MIL << "Releasing all medias of all sources" << endl;
-          try
-          {
-            //! \todo do we need replacement for this at all?
-            //zypp::SourceManager::sourceManager()->releaseAllSources();
-          }
-          catch (const zypp::Exception& excpt_r)
-          {
-            ZYPP_CAUGHT(excpt_r);
-            ERR << "Failed to release all sources" << endl;
-          }
-
-          // set up the reason
-          media::MediaChangeReport::Error reason = media::MediaChangeReport::INVALID;
-
-          if (typeid(excp) == typeid(media::MediaFileNotFoundException)
-              || typeid(excp) == typeid(media::MediaNotAFileException))
-          {
-            reason = media::MediaChangeReport::NOT_FOUND;
-          }
-          else if (typeid(excp) == typeid( media::MediaNotDesiredException)
-              || typeid(excp) == typeid(media::MediaNotAttachedException))
-          {
-            reason = media::MediaChangeReport::WRONG;
-          }
-
-          vector<string> devices;
-          unsigned int devindex;
-          media_mgr.getDetectedDevices(_media, devices, devindex);
-
-          // release all media before requesting another (#336881)
-          media_mgr.releaseAll();
-
-          user = report->requestMedia(_url,
-                                      media_nr,
-                                      _label,
-                                      reason,
-                                      excp.asUserString(),
-                                      devices,
-                                      devindex);
-
-          MIL << "ProvideDir exception caught, callback answer: " << user << endl;
-
-          if (user == media::MediaChangeReport::ABORT)
-          {
-            DBG << "Aborting" << endl;
-            ZYPP_RETHROW ( excp );
-          }
-          else if (user == media::MediaChangeReport::EJECT)
-          {
-            DBG << "Eject: try to release" << endl;
-            media_mgr.releaseAll();
-            // eject
-            media_mgr.release (_media,
-              devindex < devices.size() ? devices[devindex] : "");
-          }
-          else if (user == media::MediaChangeReport::RETRY ||
-              user == media::MediaChangeReport::CHANGE_URL)
-          {
-            // retry
-            DBG << "Going to try again" << endl;
-            // invalidate current media access id
-            media_mgr.close(_media);
-            _medias.erase(media_nr);
-
-            // not attaching, media set will do that for us
-            // this could generate uncaught exception (#158620)
-
-            break;
-          }
-          else
-          {
-            DBG << "Don't know, let's ABORT" << endl;
-
-            ZYPP_RETHROW (excp);
-          }
-        }
-        while (user == media::MediaChangeReport::EJECT);
-      }
-      // retry or change URL
+        ProvideDirTreeOperation op;
+        provide( boost::ref(op), resource, options, Pathname());
+        return op.result;
     }
-    while (true);
-
-    return media_mgr.localPath(_media, dir);
+    ProvideDirOperation op;
+    provide( boost::ref(op), resource, options, Pathname());
+    return op.result;
   }
 
   media::MediaAccessId MediaSetAccess::getMediaAccessId (media::MediaNr medianr)
@@ -522,8 +359,6 @@ IMPL_PTR_TYPE(MediaSetAccess);
     if (_medias.find(medianr) != _medias.end())
     {
       media::MediaAccessId id = _medias[medianr];
-      //if (! noattach && ! media_mgr.isAttached(id))
-      //media_mgr.attach(id);
       return id;
     }
     Url url;
@@ -570,7 +405,7 @@ IMPL_PTR_TYPE(MediaSetAccess);
       // code has to be adapted together with the MediaISO change.
       // maybe some MediaISOURL interface should be used.
       std::string isofile = url_r.getQueryParam("iso");
-      str::regex e("^(.*)(cd|dvd)[0-9]+\\.iso$", str::regex::icase);
+      str::regex e("^(.*)(cd|dvd|media)[0-9]+\\.iso$", str::regex::icase);
 
       str::smatch what;
       if(str::regex_match(isofile, what, e))
@@ -585,7 +420,7 @@ IMPL_PTR_TYPE(MediaSetAccess);
     else
     {
       std::string pathname = url_r.getPathName();
-      str::regex e("^(.*)(cd|dvd)[0-9]+(/)?$", str::regex::icase);
+      str::regex e("^(.*)(cd|dvd|media)[0-9]+(/)?$", str::regex::icase);
       str::smatch what;
       if(str::regex_match(pathname, what, e))
       {
@@ -613,9 +448,6 @@ IMPL_PTR_TYPE(MediaSetAccess);
     return str;
   }
 
-//     media::MediaVerifierRef MediaSetAccess::verifier(unsigned media_nr)
-//     { return media::MediaVerifierRef(new media::NoVerifier()); }
-
 /////////////////////////////////////////////////////////////////
 } // namespace zypp
 ///////////////////////////////////////////////////////////////////