- repository license methods added to RepoManager (bnc #372386)
authorJan Kupec <jkupec@suse.cz>
Thu, 16 Oct 2008 15:59:17 +0000 (15:59 +0000)
committerJan Kupec <jkupec@suse.cz>
Thu, 16 Oct 2008 15:59:17 +0000 (15:59 +0000)
zypp/RepoManager.cc
zypp/RepoManager.h

index 616eac1..8df8891 100644 (file)
@@ -55,6 +55,7 @@
 #include "satsolver/repo_solv.h"
 
 using std::endl;
+using std::string;
 using namespace zypp::repo;
 
 ///////////////////////////////////////////////////////////////////
@@ -1870,6 +1871,8 @@ namespace zypp
     //! \todo refresh the service automatically if url is changed?
   }
 
+  ////////////////////////////////////////////////////////////////////////////
+
   repo::ServiceType RepoManager::probeService( const Url &url ) const
   {
     try
@@ -1897,7 +1900,182 @@ namespace zypp
   }
 
   ////////////////////////////////////////////////////////////////////////////
+  //
+  // Misc. utils
+  //
+  ////////////////////////////////////////////////////////////////////////////
+
+  bool RepoManager::getLicenseFiles(const RepoInfo & repo, const Pathname & target)
+  {
+    Pathname lpack;
+    for_(url, repo.baseUrlsBegin(), repo.baseUrlsEnd())
+    {
+      // try to get /licenses.tar.gz
+      MediaSetAccess access(*url);
+      lpack = access.provideOptionalFile("/license.tar.gz");
+
+      // try to get /media.1/license.zip (SLE10, openSUSE10.2 used this)
+      if (lpack.empty())
+      {
+        DBG << "/license.tar.gz not found, trying /media.1/license.zip" << endl;
+        lpack = access.provideOptionalFile("/media.1/license.zip");
+      }
+      // unpack license.tar.gz to target dir
+      else
+      {
+        DBG << "got /license.tar.gz, unpacking..." << endl;
+
+        const char* const argv[] =
+        {
+          "tar",
+          "-xz",
+          "-f",
+          lpack.asString().c_str(),
+          "-C",
+          target.asString().c_str(),
+          NULL
+        };
+
+        // execute tar in / (we dont know if there is a tar below _root !)
+        ExternalProgram tar(argv, ExternalProgram::Stderr_To_Stdout, false, -1, true);
+
+        string tarmsg;
+        for (string output = tar.receiveLine(); output.length() ;output = tar.receiveLine())
+          tarmsg += output;
+
+        int ret = tar.close();
+        if ( ret != 0 )
+        {
+          ERR << "extracting licenses from tar failed: " << tarmsg << endl;
+          return false;
+        }
+
+        break;
+      }
+
+      if (lpack.empty())
+      {
+        MIL << "No repository license to confirm for " << repo.alias() << endl;
+        return false;
+      }
+      // unpack license.zip to target dir
+      else
+      {
+        DBG << "got /media.1/license.zip, unpacking..." << endl;
+        break;
+      }
+    }
+
+    // check whether the target dir contains license files
+    std::list<Pathname> files;
+
+    if ( filesystem::readdir( files, target, false ) != 0 )
+    {
+      ERR << "Cannot read the target directory" << endl;
+      return false;
+    }
+
+    str::regex lfilesregex( "^license\\.?(.*)\\.txt$" );
+    for_( it, files.begin(), files.end() )
+    {
+      const string & filename = it->basename();
+      if ( str::regex_match( filename, lfilesregex ) )
+        return true;
+    }
+
+    return false;
+  }
+
+  ////////////////////////////////////////////////////////////////////////////
+
+  Pathname RepoManager::getLicenseFile( const Pathname & ldir )
+  {
+    return getLicenseFile(ldir, ZConfig::instance().defaultTextLocale());
+  }
+
+  ////////////////////////////////////////////////////////////////////////////
+
+  Pathname RepoManager::getLicenseFile( const Pathname & ldir, const Locale & locale )
+  {
+    MIL << "Looking for license file suitable for locale "
+        << locale << " in directory " << ldir << endl;
+
+    std::list<Pathname> files;
+    std::set<Locale> available;
+
+    if ( filesystem::readdir( files, ldir, false ) != 0 )
+    {
+      ERR << "Cannot read the directory." << endl;
+      return Pathname();
+    }
+
+    str::regex lfilesregex("^license\\.?(.*)\\.txt$");
+    for_( it, files.begin(), files.end() )
+    {
+      const string & filename = it->basename();
+      str::smatch what;
+      if( str::regex_match(filename, what, lfilesregex) )
+      {
+        Locale l( what[1].empty() ? "" : what[1] );
+        DBG << "got license file " << *it << ", locale: " << l << endl;
+
+        if ( locale == l )
+        {
+          MIL << "got license file " << *it << " for locale " << locale << endl;
+          return *it;
+        }
+        else
+          available.insert(l);
+      }
+      else
+        XXX << "got unknown file: " << it->basename() << endl;
+    }
+
+    DBG << "No license file found for locale " << locale << endl;
+
+    // fall back to language code only
+    if ( locale.country().hasCode() )
+    {
+      Locale l(locale.language());
+      std::set<Locale>::const_iterator it = available.find(l); 
+      if ( it != available.end() )
+      {
+        Pathname ret = ldir / ("license."+l.code()+".txt");
+        MIL << "Got match for locale " << l << ", returning " << ret << endl;
+        return ret;
+      }
+    }
+
+    Pathname def;
+    // check for en_US
+    if (PathInfo(ldir/"license.en_US.txt").isFile())
+      def = ldir/"license.en_US.txt";
+    // check for en_GB
+    if (PathInfo(ldir/"license.en_GB.txt").isFile())
+      def = ldir/"license.en_GB.txt";
+    // check for en
+    if (PathInfo(ldir/"license.en.txt").isFile())
+      def = ldir/"license.en.txt";
+    // check for default
+    if (PathInfo(ldir/"license.txt").isFile())
+      def = ldir/"license.txt";
+
+    MIL << "Returning '" << def << "'" << endl;
+
+    return def;
+  }
+
+  ////////////////////////////////////////////////////////////////////////////
 
+  std::set<Locale> getAvailableLicenseLocales( const Pathname & ldir )
+  {
+#warning getAvailableLicenseLocales not yet implemented
+  }
+
+  // Pathname getInfoFile( const RepoInfo & repo ) media.1/info.txt
+
+  ////////////////////////////////////////////////////////////////////////////
+  
   std::ostream & operator<<( std::ostream & str, const RepoManager & obj )
   {
     return str << *obj._pimpl;
index 5950f15..2706215 100644 (file)
@@ -645,6 +645,49 @@ namespace zypp
                  out);
     }
 
+    /**
+     * Checks for existing repository license files of \a repo and extract them
+     * in \a target directory.
+     * 
+     * \param repo   Repository to check.
+     * \param target Path to directory where the license files should be copied.
+     * \return true if license files were found and successfully extracted,
+     *         false otherwise.
+     */
+    bool getLicenseFiles(const RepoInfo & repo, const Pathname & target);
+
+    /**
+     * Returns path to a license file suitable for current system locale, given
+     * a directory with all available license files. License files' names must
+     * match the following regex: <tt>^license\.?(.*)\.txt$</tt> where the
+     * substring enclosed in parentheses is the locale code.
+     * 
+     * Examples: license.en_US.txt, license.en.txt, license.txt 
+     * 
+     * \param ldir Path to a directory containing all license files.
+     * \return path to the license file, or an empty path on failure.
+     * 
+     * \see getLicenseFiles(RepoInfo const&, Pathanme const&)
+     */
+    Pathname getLicenseFile( const Pathname & ldir );
+
+    /**
+     * Returns path to a license file suitable for given \a locale, given
+     * a directory with all available license files.
+     * 
+     * \param ldir Path to a directory containing all license files.
+     * \return path to the license file, or an empty path on failure.
+     * 
+     * \see getLicenseFiles(RepoInfo const&, Pathanme const&)
+     * \see getLicenseFile(Pathanme const&)
+     */
+    Pathname getLicenseFile( const Pathname & ldir, const Locale & locale );
+
+    /**
+     * \todo implement
+     */
+    std::set<Locale> getAvailableLicenseLocales( const Pathname & ldir );
+
   protected:
     RepoStatus rawMetadataStatus( const RepoInfo &info );
     void setCacheStatus( const RepoInfo &info, const RepoStatus &status );