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

Generated on Thu Jul 6 00:07:24 2006 for zypp by  doxygen 1.4.6