SuseTagsImpl.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 #include <fstream>
00014 #include "zypp/base/Logger.h"
00015 #include "zypp/base/Exception.h"
00016 
00017 #include "zypp/PathInfo.h"
00018 #include "zypp/Digest.h"
00019 #include "zypp/CheckSum.h"
00020 #include "zypp/KeyRing.h"
00021 
00022 #include "zypp/source/susetags/SuseTagsImpl.h"
00023 #include "zypp/source/susetags/PackagesParser.h"
00024 #include "zypp/source/susetags/PackagesLangParser.h"
00025 #include "zypp/source/susetags/SelectionTagFileParser.h"
00026 #include "zypp/source/susetags/PatternTagFileParser.h"
00027 #include "zypp/source/susetags/ProductMetadataParser.h"
00028 
00029 #include "zypp/SourceFactory.h"
00030 #include "zypp/ZYppCallbacks.h"
00031 #include "zypp/ZYppFactory.h"
00032 
00033 using std::endl;
00034 
00036 namespace zypp
00037 { 
00038 
00039   namespace source
00040   { 
00041 
00042     namespace susetags
00043     { 
00044       
00046       //
00047       //        METHOD NAME : SuseTagsImpl::SuseTagsImpl
00048       //        METHOD TYPE : Ctor
00049       //
00050       SuseTagsImpl::SuseTagsImpl()
00051       {}
00052 
00053       const Pathname SuseTagsImpl::metadataRoot() const
00054       {
00055         return _cache_dir.empty() ? _tmp_metadata_dir : _cache_dir;
00056       }
00057       
00058       const Pathname SuseTagsImpl::contentFile() const
00059       {
00060         return metadataRoot() + "/DATA" + "content";
00061       }
00062       
00063       const Pathname SuseTagsImpl::contentFileSignature() const
00064       {
00065         return metadataRoot() + "/DATA" + "content.asc";
00066       }
00067       
00068       const Pathname SuseTagsImpl::contentFileKey() const
00069       {
00070         return metadataRoot() + "/DATA" + "/content.key";
00071       }
00072       
00073       const Pathname SuseTagsImpl::mediaFile() const
00074       {
00075         return metadataRoot() + "MEDIA/media.1/media";
00076       }
00077       
00078       const Pathname SuseTagsImpl::descrDir() const
00079       {
00080         return metadataRoot() + "DATA/descr";
00081       }
00082       
00083       const Pathname SuseTagsImpl::dataDir() const
00084       {
00085         return _data_dir;
00086       }
00087       
00088       const Pathname SuseTagsImpl::mediaDescrDir() const
00089       {
00090         return _media_descr_dir;
00091       }
00092       
00093       bool SuseTagsImpl::downloadNeeded(const Pathname & localdir)
00094       {
00095         Pathname new_media_file = provideFile("media.1/media");
00096         // before really download all the data and init the cache, check
00097         // if the source has really changed, otherwise, make it quick
00098         Pathname cached_media_file = localdir + "/MEDIA/media.1/media";
00099         if ( cacheExists() )
00100         {
00101           CheckSum old_media_file_checksum( "SHA1", filesystem::sha1sum(cached_media_file));
00102           CheckSum new_media_file_checksum( "SHA1", filesystem::sha1sum(new_media_file));
00103           if ( (new_media_file_checksum == old_media_file_checksum) && (!new_media_file_checksum.empty()) && (! old_media_file_checksum.empty()))
00104           {
00105             MIL << "susetags source " << alias() << " has not changed. Refresh completed. SHA1 of media.1/media file is " << old_media_file_checksum.checksum() << std::endl;
00106             return false;
00107           }
00108         }
00109         MIL << "susetags source " << alias() << " has changed. Refresh needed." << std::endl;
00110         return true;
00111       }
00112       
00113       void SuseTagsImpl::readMediaFile(const Pathname &p)
00114       {
00115         media::MediaManager media_mgr;
00116         
00117         std::ifstream pfile( p.asString().c_str() );
00118         if ( pfile.bad() ) {
00119           ZYPP_THROW(Exception("Error parsing media.1/media") );
00120         }
00121         _vendor = str::getline( pfile, str::TRIM );
00122         if ( pfile.fail() ) {
00123           ZYPP_THROW(Exception("Error parsing media.1/media") );
00124         }
00125         _media_id = str::getline( pfile, str::TRIM );
00126         if ( pfile.fail() ) {
00127           ZYPP_THROW(Exception("Error parsing media.1/media") );
00128         }
00129         std::string media_count_str = str::getline( pfile, str::TRIM );
00130         if ( pfile.fail() ) {
00131           ZYPP_THROW(Exception("Error parsing media.1/media") );
00132         }
00133         _media_count = str::strtonum<unsigned>( media_count_str );
00134 
00135         try {
00136           MIL << "Adding susetags media verifier: " << endl;
00137           MIL << "Vendor: " << _vendor << endl;
00138           MIL << "Media ID: " << _media_id << endl;
00139 
00140           // get media ID, but not attaching
00141           media::MediaAccessId _media = _media_set->getMediaAccessId(1, true);
00142           media_mgr.delVerifier(_media);
00143           media_mgr.addVerifier(_media, media::MediaVerifierRef(
00144               new SourceImpl::Verifier (_vendor, _media_id) ));
00145         }
00146         catch (const Exception & excpt_r)
00147         {
00148 #warning FIXME: If media data is not set, verifier is not set. Should the media
00149           ZYPP_CAUGHT(excpt_r);
00150           WAR << "Verifier not found" << endl;
00151         }
00152       }
00153       
00154       TmpDir SuseTagsImpl::downloadMetadata()
00155       {
00156         TmpDir tmpdir;
00157         MIL << "Downloading metadata to " << tmpdir.path() << std::endl;
00158         
00159         Pathname local_dir = tmpdir.path();
00160         
00161         // (#163196)
00162         // before we used _descr_dir, which is is wrong if we 
00163         // store metadata already running from cache
00164         // because it points to a local file and not
00165         // to the media. So use the original media descr_dir.
00166         Pathname media_src;
00167         Pathname descr_src;
00168         Pathname content_src;    
00169             
00170         // init the cache structure
00171         if (0 != assert_dir(local_dir + "DATA", 0755))
00172           ZYPP_THROW(Exception("Cannot create /DATA directory in download dir." + local_dir.asString()));
00173         if (0 != assert_dir(local_dir + "MEDIA", 0755))
00174           ZYPP_THROW(Exception("Cannot create /MEDIA directory in download dir." + local_dir.asString()));
00175         if (0 != assert_dir(local_dir + "PUBLICKEYS", 0755))
00176           ZYPP_THROW(Exception("Cannot create /PUBLICKEYS directory in download dir." + local_dir.asString()));
00177         
00178         try {
00179           media_src = provideDirTree("media.1");
00180         }
00181         catch(Exception &e) {
00182           ZYPP_THROW(Exception("Can't provide " + _path.asString() + "/media.1 from " + url().asString() ));
00183         }
00184         
00185         if ( filesystem::copy_dir(media_src, local_dir + "MEDIA") != 0 )
00186           ZYPP_THROW(Exception("Unable to copy media directory to " + (local_dir + "/MEDIA").asString()));
00187     
00188         MIL << "cached media directory" << std::endl;
00189 
00190         // media is provided, now we can install a media verifier.
00191         readMediaFile(local_dir + "/MEDIA/media.1/media");
00192         
00193         try {
00194           content_src = provideFile( _path + "content");
00195         }
00196         catch(Exception &e) {
00197           ZYPP_THROW(Exception("Can't provide " + _path.asString() + "/content from " + url().asString() ));
00198         }
00199         
00200         if ( filesystem::copy(content_src, local_dir + "DATA/content") != 0)
00201           ZYPP_THROW(Exception("Unable to copy the content file to " + (local_dir + "DATA/content").asString()));
00202         
00203         // get the list of cache keys
00204         std::list<std::string> files;
00205         dirInfo( 1, files, _path);
00206         
00207         // cache all the public keys
00208         for( std::list<std::string>::const_iterator it = files.begin(); it != files.end(); ++it)
00209         {
00210           ZYpp::Ptr z = getZYpp();
00211           
00212           std::string filename = *it;
00213           if ( filename.substr(0, 10) == "gpg-pubkey" )
00214           {
00215             Pathname key_src;
00216             try {
00217               key_src = provideFile(_path + filename);
00218             }
00219             catch(Exception &e) {
00220               ZYPP_THROW(Exception("Can't provide " + (_path + filename).asString() + " from " + url().asString() ));
00221             }
00222             
00223             MIL << "Trying to cache " << key_src << std::endl;
00224             
00225             if ( filesystem::copy(key_src, local_dir + "PUBLICKEYS/" + filename) != 0 )
00226               ZYPP_THROW(Exception("Unable to copy key " + key_src.asString() + " to " + (local_dir + "PUBLICKEYS").asString()));
00227            
00228             MIL << "cached " << filename << std::endl;
00229             z->keyRing()->importKey(local_dir + "PUBLICKEYS/" + filename, false);  
00230           }
00231           else if( (filename == "content.asc") || (filename == "content.key"))
00232           {
00233             Pathname src_data;
00234             try {
00235               src_data = provideFile(_path + filename);
00236             }
00237             catch(Exception &e) {
00238               ZYPP_THROW(Exception("Can't provide " + filename + " from " + url().asString() + ". File was listed as available."));
00239             }
00240             
00241             if ( filesystem::copy( src_data, local_dir + "DATA/" + filename) != 0 )
00242               ZYPP_THROW(Exception("Unable to copy " + filename + " to " + (local_dir + "/DATA").asString()));
00243             
00244             if ( filename == "content.key" )
00245               z->keyRing()->importKey(contentFileKey(), false);  
00246               
00247             MIL << "cached " << filename << std::endl;
00248           }
00249         }
00250 
00251         // verify it is a valid content file
00252         ZYpp::Ptr z = getZYpp();
00253         MIL << "SuseTags source: checking 'content' file vailidity using digital signature.." << endl;
00254         // verify the content file
00255         bool valid = z->keyRing()->verifyFileSignatureWorkflow( local_dir + "/DATA/content", (path() + "content").asString() + " (" + url().asString() + ")", local_dir + "/DATA/content.asc");
00256           
00257         // the source is not valid and the user did not want to continue
00258         if (!valid)
00259           ZYPP_THROW (Exception( "Error. Source signature does not validate and user does not want to continue. "));
00260         
00261         // now we have the content file copied, we need to init data and descrdir from the product
00262         readContentFile(local_dir + "/DATA/content");
00263         
00264         try {
00265           descr_src = provideDirTree(mediaDescrDir());        
00266         }
00267         catch(Exception &e) {
00268           ZYPP_THROW(Exception("Can't provide " + _path.asString() + "  " + mediaDescrDir().asString() + " from " + url().asString() ));
00269         }
00270         
00271         if ( filesystem::copy_dir(descr_src, local_dir + "DATA") != 0 )
00272           ZYPP_THROW(Exception("Unable to copy the descr dir to " + (local_dir + "DATA").asString()));
00273         
00274         // now we have descr dir cached and keys, lets validate checksums
00275         checkMetadataChecksums(local_dir);
00276         return tmpdir;
00277       }
00278       
00279       void SuseTagsImpl::initCacheDir(const Pathname & cache_dir_r)
00280       {
00281         // refuse to use stupid paths as cache dir
00282         if (cache_dir_r == Pathname("/") )
00283           ZYPP_THROW(Exception("I refuse to use / as cache dir"));
00284 
00285         if (0 != assert_dir(cache_dir_r.dirname(), 0700))
00286           ZYPP_THROW(Exception("Cannot create cache directory" + cache_dir_r.asString()));
00287 
00288         filesystem::clean_dir(cache_dir_r);
00289         filesystem::mkdir(cache_dir_r + "DATA");
00290         filesystem::mkdir(cache_dir_r + "MEDIA");
00291         //filesystem::mkdir(cache_dir_r + "DESCRIPTION");
00292         filesystem::mkdir(cache_dir_r + "PUBLICKEYS");
00293       }
00294       
00295       void SuseTagsImpl::storeMetadata(const Pathname & cache_dir_r)
00296       {
00297         if ( !_cache_dir.empty() )
00298         {
00299           saveMetadataTo(cache_dir_r);
00300         }
00301         else
00302         {
00303           // no previous cache, use the data read temporarely
00304           copyLocalMetadata(_tmp_metadata_dir.path(), cache_dir_r);
00305         }
00306         
00307         MIL << "Metadata saved in " << cache_dir_r << ". Setting as cache." << std::endl;
00308         _cache_dir = cache_dir_r;
00309       }
00310       
00311       void SuseTagsImpl::saveMetadataTo(const Pathname & dir_r)
00312       {
00313         TmpDir download_tmp_dir;
00314         
00315         bool need_to_refresh = true;
00316         try {
00317           need_to_refresh = downloadNeeded(dir_r);
00318         }
00319         catch(Exception &e) {
00320           ZYPP_THROW(Exception("Can't check if source has changed or not. Aborting refresh."));
00321         }
00322         
00323         if ( need_to_refresh )
00324         {
00325           MIL << "SuseTags source " << alias() << "has changed since last download. Re-reading metadata into " << dir_r << endl;
00326         }
00327         else
00328         {
00329           MIL << "SUSEtags source " << alias() << "has not changed. Refresh completed. timestamp of media file is  the same." << std::endl;    
00330           return;
00331         }
00332         
00333         try {
00334           download_tmp_dir = downloadMetadata();
00335         }
00336         catch(Exception &e) {
00337           ZYPP_THROW(Exception("Downloading metadata failed (is a susetags source?) or user did not accept remote source. Aborting refresh."));
00338         }
00339         
00340         copyLocalMetadata(download_tmp_dir, dir_r);
00341         
00342         // download_tmp_dir go out of scope now but it is ok as we already copied the content.
00343       }
00344 
00345       bool SuseTagsImpl::cacheExists() const
00346       {
00347         MIL << "Checking if source cache exists in "<< _cache_dir << std::endl;
00348         bool exists = true;
00349 
00350         bool data_exists = PathInfo(_cache_dir + "DATA").isExist();
00351         exists = exists && data_exists;
00352 
00353         //bool description_exists = PathInfo(_cache_dir + "DESCRIPTION").isExist();
00354         //exists = exists && description_exists;
00355 
00356         bool media_exists = PathInfo(_cache_dir + "MEDIA").isExist();
00357         exists = exists && media_exists;
00358 
00359         bool media_file_exists = PathInfo(_cache_dir + "MEDIA/media.1/media").isExist();
00360         exists = exists && media_file_exists;
00361 
00362         MIL << "DATA " << (data_exists ? "exists" : "not found") << ", MEDIA " << (media_exists ? "exists" : "not found") << ", MEDIA/media.1/media " <<  (media_file_exists ? "exists" : "not found") << std::endl;
00363         return exists;
00364       }
00365 
00366       bool SuseTagsImpl::verifyChecksumsMode() const
00367       {
00368         return ! _prodImpl->_descr_files_checksums.empty();
00369       }
00370       
00371       void SuseTagsImpl::factoryInit()
00372       {
00373         bool cache = cacheExists();
00374         if ( cache )
00375         {
00376           MIL << "Cached metadata found in [" << _cache_dir << "]." << endl;
00377           // we need to read the content file to init data dir and descr dir
00378           // in the media.
00379           readMediaFile(mediaFile());
00380           readContentFile(contentFile());
00381         }
00382         else
00383         {
00384           if ( _cache_dir.empty() || !PathInfo(_cache_dir).isExist() )
00385           {
00386             MIL << "Cache dir not set. Downloading to temp dir: " << _tmp_metadata_dir << std::endl;
00387             // as we have no local dir set we use a tmp one, but we use a member variable because
00388             // it cant go out of scope while the source exists.
00389             saveMetadataTo(_tmp_metadata_dir);
00390           }
00391           else
00392           {
00393             MIL << "Cached metadata not found in [" << _cache_dir << "]. Will download." << std::endl;
00394             saveMetadataTo(_cache_dir);
00395           }
00396         }
00397         MIL << "SUSETags source initialized." << std::endl;
00398         MIL << "   Url      : " << url() << std::endl;
00399         MIL << "   Path     : " << path() << std::endl;
00400         MIL << "   Data     : " << dataDir() << std::endl;
00401         MIL << "   Metadata : " << metadataRoot() << (_cache_dir.empty() ? " [TMP]" : " [CACHE]") << std::endl;
00402         MIL << "   N-Media  : " << numberOfMedia() << std::endl;
00403       }
00404 
00405       void SuseTagsImpl::createResolvables(Source_Ref source_r)
00406       {
00407         callback::SendReport<CreateSourceReport> report;
00408         report->startData( url() );
00409 
00410         provideProducts ( source_r, _store );
00411         providePackages ( source_r, _store );
00412         provideSelections ( source_r, _store );
00413         providePatterns ( source_r, _store );
00414 
00415         report->finishData( url(), CreateSourceReport::NO_ERROR, "" );
00416       }
00417 
00418       const std::list<Pathname> SuseTagsImpl::publicKeys()
00419       {
00420         std::list<std::string> files;
00421         std::list<Pathname> paths;
00422 
00423         MIL << "Reading public keys..." << std::endl;
00424         filesystem::readdir(files, metadataRoot() + "PUBLICKEYS");
00425         for( std::list<std::string>::const_iterator it = files.begin(); it != files.end(); ++it)
00426           paths.push_back(Pathname(*it));
00427 
00428         MIL << "read " << files.size() << " keys from cache " << metadataRoot() << std::endl;
00429         return paths;
00430       }
00431 
00432       ResStore SuseTagsImpl::provideResolvables(Source_Ref source_r, Resolvable::Kind kind)
00433       {
00434         callback::SendReport<CreateSourceReport> report;
00435         report->startData( url() );
00436 
00437         ResStore store;
00438 
00439         if ( kind == ResTraits<Product>::kind )
00440             provideProducts ( source_r, store );
00441         else if ( kind == ResTraits<Package>::kind )
00442             providePackages ( source_r, store );
00443         else if ( kind == ResTraits<Selection>::kind )
00444             provideSelections ( source_r, store );
00445         else if ( kind == ResTraits<Pattern>::kind )
00446             providePatterns ( source_r, store );
00447 
00448         report->finishData( url(), CreateSourceReport::NO_ERROR, "" );
00449 
00450         return store;
00451       }
00452 
00454       //
00455       //        METHOD NAME : SuseTagsImpl::~SuseTagsImpl
00456       //        METHOD TYPE : Dtor
00457       //
00458       SuseTagsImpl::~SuseTagsImpl()
00459       {}
00460 
00461       Pathname SuseTagsImpl::sourceDir( const std::string & dir )
00462       {
00463         return Pathname( _data_dir + Pathname( dir ) + "/");
00464       }
00465 
00466       media::MediaVerifierRef SuseTagsImpl::verifier(media::MediaNr media_nr)
00467       {
00468         return media::MediaVerifierRef(
00469             new SourceImpl::Verifier (_vendor, _media_id, media_nr));
00470       }
00471 
00472       unsigned SuseTagsImpl::numberOfMedia(void) const
00473       { return _media_count; }
00474 
00475       std::string SuseTagsImpl::vendor (void) const
00476       { return _vendor; }
00477 
00478       std::string SuseTagsImpl::unique_id (void) const
00479       { return _media_id; }
00480 
00481       Date SuseTagsImpl::timestamp() const
00482       {
00483         return PathInfo(contentFile()).mtime();
00484       }
00485       
00486       void SuseTagsImpl::readContentFile(const Pathname &content_file)
00487       { 
00488         SourceFactory factory; 
00489         try {
00490           DBG << "Going to parse content file " << content_file << endl;
00491           
00492           ProductMetadataParser p;
00493           p.parse( content_file, factory.createFrom(this) );
00494           _product = p.result;
00495           
00496           // data dir is the same, it is determined by the content file
00497           _data_dir = _path + p.prodImpl->_data_dir;
00498           // description dir also changes when using cache  
00499           _media_descr_dir = _path + p.prodImpl->_description_dir;        
00500           
00501           MIL << "Read product: " << _product->summary() << endl;
00502           
00503           _prodImpl = p.prodImpl;
00504           _autorefresh = p.volatile_content && media::MediaAccess::canBeVolatile( _url );
00505         }
00506         catch (Exception & excpt_r) {
00507           ZYPP_THROW (Exception( "cannot parse content file."));
00508         }
00509       }
00510 
00511       void SuseTagsImpl::provideProducts(Source_Ref source_r, ResStore &store)
00512       {
00513         MIL << "Adding product: " << _product->summary() << " to the store" << endl;
00514         store.insert( _product );
00515       }
00516       
00517       void SuseTagsImpl::checkMetadataChecksums(const Pathname &p) const
00518       {
00519         // iterate through all available checksums
00520         for ( std::map<std::string, CheckSum>::const_iterator it = _prodImpl->_descr_files_checksums.begin(); it != _prodImpl->_descr_files_checksums.end(); ++it)
00521         {
00522           std::string key = it->first;
00523           verifyFile( p + "/DATA/descr" + key, key);
00524         }
00525         
00526         // FIXME add and check the gpg keys
00527       }
00528       
00529       void SuseTagsImpl::verifyFile( const Pathname &path, const std::string &key) const
00530       {
00531         // for old products, we dont check anything.
00532         if ( verifyChecksumsMode() )
00533         {
00534           MIL << "Going to check " << path << " file checksum" << std::endl;
00535           std::ifstream file(path.asString().c_str());
00536           if (!file) {
00537             ZYPP_THROW (Exception( "Can't open " + path.asString() ) );
00538           }  
00539           
00540           // get the checksum for that file.
00541           CheckSum checksum = _prodImpl->_descr_files_checksums[key];
00542           if (checksum.empty())
00543           {
00544             callback::SendReport<DigestReport> report;
00545 
00546             if ( report->askUserToAcceptNoDigest(path) )
00547             {
00548                 MIL << path << " user accepted file without a checksum " << endl;
00549                 return;
00550             }
00551 
00552             ZYPP_THROW (Exception( "Error, Missing checksum for " + path.asString() ) ); 
00553           }
00554           else
00555           {
00556             std::string found_checksum = Digest::digest( checksum.type(), file);
00557             if ( found_checksum != checksum.checksum() )
00558             {
00559               ZYPP_THROW (Exception( "Corrupt source, Expected " + checksum.type() + " " + checksum.checksum() + ", got " + found_checksum + " for " + path.asString() ) );
00560             }
00561             else
00562             {
00563               MIL << path << " checksum ok (" << checksum.type() << " " << checksum.checksum() << ")" << std::endl;
00564               return;
00565             }
00566           }
00567         }
00568       }
00569       
00570       void SuseTagsImpl::providePackages(Source_Ref source_r, ResStore &store)
00571       {
00572         Pathname p = descrDir() + "packages";
00573         
00574         //verifyFile( p, "packages");
00575         
00576         DBG << "Going to parse " << p << endl;
00577         PkgContent content( parsePackages( source_r, this, p ) );
00578 
00579 #warning Should use correct locale and locale fallback list
00580         // note, this locale detection has nothing to do with translated text.
00581         // basically we are only loading the data we need. Instead of parsing all
00582         // package description we fill the TranslatedText properties only
00583         // with the detected locale.
00584 
00585         ZYpp::Ptr z = getZYpp();
00586         Locale lang( z->getTextLocale() );
00587 
00588         std::string packages_lang_prefix( "packages." );
00589         std::string packages_lang_name;
00590 
00591         // get the list of available packages.X trsnlation files
00592         std::list<std::string> all_files;
00593         filesystem::readdir(all_files, descrDir());
00594         
00595         std::list<std::string> _pkg_translations;
00596         for( std::list<std::string>::const_iterator it = all_files.begin(); it != all_files.end(); ++it)
00597         {
00598           if ( ((*it).substr(0, 9) == "packages." ) && ((*it) != "packages.DU" ))
00599           {
00600             MIL << *it << " available as package data translation." << std::endl;
00601             _pkg_translations.push_back(*it);
00602           }
00603         }
00604         
00605         // find the most apropiate file
00606         bool trymore = true;
00607         while ( (lang != Locale()) && trymore )
00608         {
00609           packages_lang_name = packages_lang_prefix + lang.code();
00610           MIL << "Translation candidate: " << lang.code() << std::endl;
00611           try
00612           {
00613             // only provide it if it exists
00614             if ( find( _pkg_translations.begin(), _pkg_translations.end(), packages_lang_name ) != _pkg_translations.end() )
00615             {
00616               p = descrDir() + packages_lang_name;
00617               if ( PathInfo(p).isExist() )
00618               {
00619                 MIL << packages_lang_name << " found" << std::endl;
00620                 DBG << "Going to parse " << p << endl;
00621                 //verifyFile( p, packages_lang_name);
00622                 parsePackagesLang( this, p, lang, content );
00623                 trymore = false;
00624               }
00625               else
00626               {
00627                 ERR << packages_lang_name << " can't be provided, even if it should" << endl;
00628               }
00629             }
00630             else
00631             {
00632               MIL << "Skipping translation candidate " << packages_lang_name << " (not present in media)" << endl;
00633             }
00634           }
00635           catch (Exception & excpt_r)
00636           {
00637             ZYPP_CAUGHT(excpt_r);
00638           }
00639           lang = lang.fallback();
00640         }
00641         
00642         MIL << _package_data.size() << " packages holding real data" << std::endl;
00643         MIL << content.size() << " packages parsed" << std::endl;
00644         
00645         int counter =0;
00646         for ( std::map<NVRA, DefaultFalseBool>::const_iterator it = _is_shared.begin(); it != _is_shared.end(); ++it)
00647         {
00648           if( it->second)
00649             counter++;
00650         }
00651         
00652         MIL << counter << " packages sharing data" << std::endl;
00653         
00654         
00655         PkgDiskUsage du;
00656         try
00657         {
00658           p = descrDir() +  + "packages.DU";
00659           //verifyFile( p, "packages.DU");
00660           du = parsePackagesDiskUsage(p);
00661         }
00662         catch (Exception & excpt_r)
00663         {
00664             WAR << "Problem trying to parse the disk usage info" << endl;
00665         }
00666 
00667         for (PkgContent::const_iterator it = content.begin(); it != content.end(); ++it)
00668         {
00669           it->second->_diskusage = du[it->first /* NVRAD */];
00670           Package::Ptr pkg = detail::makeResolvableFromImpl( it->first, it->second );
00671           store.insert( pkg );
00672          
00673           //MIL << "Package " << pkg->summary() << std::endl;
00674           //MIL << "        " << pkg->description() << std::endl;
00675           //MIL << "----------------------------------" << std::endl;
00676           
00677         }
00678         DBG << "SuseTagsImpl (fake) from " << p << ": "
00679             << content.size() << " packages" << endl;
00680       }
00681 
00682       void SuseTagsImpl::provideSelections(Source_Ref source_r, ResStore &store)
00683       {
00684         Pathname p;
00685 
00686         bool file_found = true;
00687 
00688         // parse selections
00689         p = descrDir() + "selections";
00690         if ( ! PathInfo(p).isExist() )
00691         {
00692           MIL << p << " not found." << endl;
00693           file_found = false;
00694         }
00695 
00696         if (file_found)
00697         {
00698           //verifyFile( p, "selections");
00699           std::ifstream sels (p.asString().c_str());
00700 
00701           while (sels && !sels.eof())
00702           {
00703             std::string selfile;
00704             getline(sels,selfile);
00705 
00706             if (selfile.empty() ) continue;
00707               DBG << "Going to parse selection " << selfile << endl;
00708 
00709             Pathname file = descrDir() + selfile;
00710             //verifyFile( file, selfile);
00711             
00712             MIL << "Selection file to parse " << file << endl;
00713             Selection::Ptr sel( parseSelection( source_r, file ) );
00714 
00715             if (sel)
00716             {
00717               DBG << "Selection:" << sel << endl;
00718               store.insert( sel );
00719               DBG << "Parsing of " << file << " done" << endl;
00720             }
00721             else
00722             {
00723               DBG << "Parsing of " << file << " failed" << endl;
00724             }
00725 
00726 
00727           }
00728         }
00729       }
00730 
00731       void SuseTagsImpl::providePatterns(Source_Ref source_r, ResStore &store)
00732       {
00733         Pathname p;
00734 
00735         // parse patterns
00736         bool file_found = true;
00737 
00738         p = descrDir() + "patterns";
00739         if ( ! PathInfo(p).isExist() )
00740         {
00741           MIL << p << " not found." << endl;
00742           file_found = false;
00743         }
00744         
00745         if ( file_found )
00746         {
00747           //verifyFile( p, "patterns");
00748           std::ifstream pats (p.asString().c_str());
00749 
00750           while (pats && !pats.eof())
00751           {
00752             std::string patfile;
00753             getline(pats,patfile);
00754 
00755             if (patfile.empty() ) continue;
00756 
00757             DBG << "Going to parse pattern " << patfile << endl;
00758 
00759             Pathname file = descrDir() + patfile;
00760             
00761             MIL << "Pattern file to parse " << file << endl;
00762             Pattern::Ptr pat( parsePattern( source_r, file ) );
00763 
00764             if (pat)
00765             {
00766               DBG << "Pattern:" << pat << endl;
00767               _store.insert( pat );
00768               DBG << "Parsing of " << file << " done" << endl;
00769             }
00770             else
00771             {
00772               DBG << "Parsing of " << file << " failed" << endl;
00773             }
00774           }
00775         }
00776       }
00777 
00779       //
00780       //        METHOD NAME : SuseTagsImpl::dumpOn
00781       //        METHOD TYPE : std::ostream &
00782       //
00783       std::ostream & SuseTagsImpl::dumpOn( std::ostream & str ) const
00784       {
00785         return SourceImpl::dumpOn( str );
00786       }
00787 
00789     } // namespace susetags
00792   } // namespace source
00795 } // namespace zypp

Generated on Mon Jun 5 19:10:38 2006 for zypp by  doxygen 1.4.6