YUMSourceImpl.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00013 #include "zypp/source/yum/YUMSourceImpl.h"
00014 #include "zypp/source/yum/YUMAtomImpl.h"
00015 #include "zypp/source/yum/YUMPackageImpl.h"
00016 #include "zypp/source/yum/YUMScriptImpl.h"
00017 #include "zypp/source/yum/YUMMessageImpl.h"
00018 #include "zypp/source/yum/YUMPatchImpl.h"
00019 #include "zypp/source/yum/YUMProductImpl.h"
00020 #include "zypp/source/yum/YUMGroupImpl.h"
00021 #include "zypp/source/yum/YUMPatternImpl.h"
00022 
00023 #include "zypp/NVRA.h"
00024 #include "zypp/PathInfo.h"
00025 #include "zypp/base/Logger.h"
00026 #include "zypp/base/Exception.h"
00027 #include "zypp/CapFactory.h"
00028 #include "zypp/Digest.h"
00029 #include "zypp/ExternalProgram.h"
00030 #include "zypp/TmpPath.h"
00031 #include "zypp/ZYppFactory.h"
00032 #include "zypp/KeyRing.h"
00033 
00034 #include "zypp/parser/yum/YUMParser.h"
00035 #include "zypp/SourceFactory.h"
00036 #include "zypp/ZYppCallbacks.h"
00037 #include "zypp/SilentCallbacks.h"
00038 
00039 #include "zypp/base/GzStream.h"
00040 #include "zypp/base/Gettext.h"
00041 #include "zypp/PathInfo.h"
00042 
00043 #include <fstream>
00044 
00045 using namespace std;
00046 using namespace zypp::detail;
00047 using namespace zypp::parser::yum;
00048 
00050 namespace zypp
00051 { 
00052 
00053   namespace source
00054   { 
00055     namespace yum
00056     {
00058       //
00059       //        CLASS NAME : YUMSourceImpl
00060       //
00062 
00063       YUMSourceImpl::YUMSourceImpl()
00064       {}
00065 
00066       bool YUMSourceImpl::cacheExists()
00067       {
00068         bool exists = PathInfo(_cache_dir + "/repodata/repomd.xml").isExist();
00069         if (exists)
00070           MIL << "YUM cache found at " << _cache_dir << std::endl;
00071         else
00072           MIL << "YUM cache not found" << std::endl;
00073 
00074         return exists;
00075       }
00076 
00077       void YUMSourceImpl::factoryInit()
00078       {
00079         bool cache = cacheExists();
00080         
00081         try
00082         {
00083           media::MediaManager media_mgr;
00084           MIL << "Adding no media verifier" << endl;
00085         
00086           // don't try to attach media
00087           media::MediaAccessId _media = _media_set->getMediaAccessId(1, true);
00088           media_mgr.delVerifier(_media);
00089           media_mgr.addVerifier(_media, media::MediaVerifierRef(new media::NoVerifier()));
00090         }
00091         catch (const Exception & excpt_r)
00092         {
00093           #warning FIXME: If media data is not set, verifier is not set. Should the media be refused instead?
00094           ZYPP_CAUGHT(excpt_r);
00095           WAR << "Verifier not found" << endl;
00096         }
00097         
00098         if ( cache )
00099         {
00100           DBG << "Cached metadata found in [" << _cache_dir << "]." << endl;
00101           _repomd_file = _cache_dir + "/repodata/repomd.xml";
00102           
00103           if (PathInfo(_cache_dir + "/repodata/repomd.xml.asc").isExist())
00104             _repomd_signature = _cache_dir + "/repodata/repomd.xml.asc";
00105         
00106           if (PathInfo(_cache_dir + "/repodata/repomd.xml.key").isExist())
00107             _repomd_key = _cache_dir + "/repodata/repomd.xml.key";
00108         }
00109         else
00110         {
00111           DBG << "Cached metadata not found in [" << _cache_dir << "]. Reading from " << _path << endl;
00112           _repomd_file = provideFile(_path + "/repodata/repomd.xml");          
00113  
00114           // key and signature are optional
00115           
00116           try {
00117             _repomd_key = tryToProvideFile( _path + "/repodata/repomd.xml.key");
00118           }
00119           catch( const Exception &e ) {
00120             WAR << "Repository does not contain repomd signing key" << std::endl;
00121           }
00122                 
00123           try {
00124             _repomd_signature = tryToProvideFile( _path + "/repodata/repomd.xml.asc");
00125           }
00126           catch( const Exception &e ) {
00127             WAR << "Repository does not contain repomd signature" << std::endl;
00128           }  
00129           // if they not exists both will be Pathname()
00130         }
00131         
00132         if ( ! PathInfo(_repomd_file).isExist() )
00133           ZYPP_THROW(Exception("repodata/repomd.xml not found"));
00134         else
00135           MIL << "repomd file is [" << _repomd_file << "]" << std::endl;
00136           
00137         MIL << "Trying to get the key" << endl;
00138         if ( ! _repomd_key.empty() )
00139         {
00140           try
00141           {
00142             MIL << "Importing key " << "/repodata/repomd.xml.key" << endl;
00143             getZYpp()->keyRing()->importKey(_repomd_key , false);
00144           }
00145           catch (const Exception & excpt_r)
00146           {
00147             WAR << "Failed to import key " << _path + ("/repodata/repomd.xml.key") << endl;
00148             ZYPP_CAUGHT(excpt_r);
00149           }
00150         }
00151         else
00152         {
00153           WAR << "Source provides no key" << std::endl;
00154         }
00155             
00156         checkMetadataChecksums(cache);
00157       }
00158 
00159       void YUMSourceImpl::checkMetadataChecksums(bool from_cache)
00160       {
00161         bool cache = from_cache;
00162       
00163         MIL << "Checking [" << _repomd_file << "] integrity"  << endl;
00164         
00165         if (! getZYpp()->keyRing()->verifyFileSignatureWorkflow(_repomd_file, (_path + "/repodata/repomd.xml").asString()+ " (" + url().asString() + ")", _repomd_signature))
00166           ZYPP_THROW(Exception(N_("Signed repomd.xml file fails signature check")));
00167          
00168         DBG << "Reading file " << _repomd_file << " to check integrity of metadata." << endl;
00169         ifstream repo_st(_repomd_file.asString().c_str());
00170         YUMRepomdParser repomd(repo_st, "");
00171         
00172         for(; ! repomd.atEnd(); ++repomd)
00173         {
00174           if ((*repomd)->type == "other")
00175           {             // dont parse other.xml (#159316)
00176             continue;
00177           }
00178           else
00179           {
00180             Pathname file_to_check = cache ? (_cache_dir + _path + (*repomd)->location) : provideFile(_path + (*repomd)->location);
00181             if (! checkCheckSum( file_to_check, (*repomd)->checksumType, (*repomd)->checksum))
00182             {
00183               ZYPP_THROW(Exception( (*repomd)->location + " " + N_("fails checksum verification.") ));
00184             }
00185             
00186             // now parse patches mentioned if we are in patches.xml
00187             
00188             if ((*repomd)->type == "patches")
00189             {
00190               Pathname patch_index = file_to_check;
00191               DBG << "reading patches from file " << patch_index << endl;
00192               ifgzstream st ( patch_index.asString().c_str() );
00193               YUMPatchesParser patch(st, "");
00194               for (; !patch.atEnd(); ++patch)
00195               {
00196                 Pathname patch_filename = cache ? (_cache_dir + _path + (*patch)->location) : provideFile(_path + (*patch)->location);
00197                 if (! checkCheckSum(patch_filename, (*patch)->checksumType, (*patch)->checksum))
00198                 {
00199                   ZYPP_THROW(Exception( (*patch)->location + " " + N_("fails checksum verification.") ));
00200                 }
00201               }
00202             }  
00203           }
00204         }
00205       }
00206       
00207       void YUMSourceImpl::storeMetadata(const Pathname & cache_dir_r)
00208       {
00209         _cache_dir = cache_dir_r;
00210 
00211         // first read list of all files in the repository
00212         Pathname remote_repomd;
00213         try
00214         {
00215           remote_repomd = provideFile(_path + "/repodata/repomd.xml");
00216         }
00217         catch(Exception &e)
00218         {
00219           return;
00220         }
00221 
00222         // refuse to use stupid paths as cache dir
00223         if (cache_dir_r == Pathname("/") )
00224           ZYPP_THROW(Exception("I refuse to use / as cache dir"));
00225 
00226         if (0 != assert_dir(cache_dir_r.dirname(), 0700))
00227           ZYPP_THROW(Exception("Cannot create cache directory" + cache_dir_r.asString()));
00228 
00229         // before really download all the data and init the cache, check
00230         // if the source has really changed, otherwise, make it quick
00231         Pathname cached_repomd = cache_dir_r + "/repodata/repomd.xml";
00232         
00233         // we can only assume repomd intact means the source changed if the source is signed.
00234         if ( cacheExists() && PathInfo( _cache_dir + "/repodata/repomd.xml.asc").isExist() )
00235         {
00236           CheckSum old_repomd_checksum( "SHA1", filesystem::sha1sum(cached_repomd));
00237           CheckSum new_repomd_checksum( "SHA1", filesystem::sha1sum(remote_repomd));
00238           if ( (new_repomd_checksum == old_repomd_checksum) && (!new_repomd_checksum.empty()) && (! old_repomd_checksum.empty()))
00239           {
00240             MIL << "YUM source " << alias() << "has not changed. Refresh completed. SHA1 of repomd.xml file is " << old_repomd_checksum.checksum() << std::endl;
00241             return;
00242           }
00243         }
00244         MIL << "YUM source " << alias() << "has changed. Re-reading metadata into " << cache_dir_r << endl;
00245         
00246         
00247         MIL << "Cleaning up cache dir" << std::endl;
00248         filesystem::clean_dir(cache_dir_r);
00249 
00250         Pathname dst = cache_dir_r + "/repodata";
00251         if (0 != assert_dir(dst, 0700))
00252           ZYPP_THROW(Exception("Cannot create repodata cache directory"));
00253 
00254         MIL << "Storing data to cache" << endl;
00255 
00256         // source was invalidated
00257         // re-read all data
00258 
00259         _repomd_file = remote_repomd;
00260                 
00261         // provide optional files
00262         Pathname remote_repomd_key;
00263         Pathname remote_repomd_signature;
00264         try {
00265           remote_repomd_key = tryToProvideFile( _path + "/repodata/repomd.xml.key");
00266         }
00267         catch( const Exception &e ) {
00268           WAR << "Repository does not contain repomd signing key" << std::endl;
00269         }
00270         _repomd_key = remote_repomd_key;
00271         try {
00272           remote_repomd_signature = tryToProvideFile( _path + "/repodata/repomd.xml.asc");
00273         }
00274         catch( const Exception &e ) {
00275           WAR << "Repository does not contain repomd signinature" << std::endl;
00276         }
00277         _repomd_signature = remote_repomd_signature;
00278 
00279         // check again all file integrity, on the just downloaded files
00280         checkMetadataChecksums(false);
00281  
00282         filesystem::copy( remote_repomd, dst + "repomd.xml");
00283         
00284         if (PathInfo(remote_repomd_key).isExist())
00285           filesystem::copy( remote_repomd_key, dst + "repomd.xml.key");
00286         if (PathInfo(remote_repomd_signature).isExist())
00287           filesystem::copy( remote_repomd_signature, dst + "repomd.xml.asc");
00288         
00289         DBG << "Reading file " << remote_repomd << endl;
00290         ifstream repo_st(remote_repomd.asString().c_str());
00291         YUMRepomdParser repomd(repo_st, "");
00292         
00293         for(;
00294               ! repomd.atEnd();
00295               ++repomd)
00296         {
00297             if ((*repomd)->type == "other")     // don't parse 'other.xml' (#159316)
00298                 continue;
00299 
00300             Pathname src = provideFile(_path + (*repomd)->location);
00301             
00302             dst = cache_dir_r + (*repomd)->location;
00303             filesystem::copy(src, dst);
00304             if ((*repomd)->type == "patches")
00305             {
00306               Pathname filename = provideFile(_path + (*repomd)->location);
00307               DBG << "reading file " << filename << endl;
00308               ifgzstream st ( filename.asString().c_str() );
00309               YUMPatchesParser patch(st, "");
00310               for (;
00311                   !patch.atEnd();
00312                   ++patch)
00313               {
00314                 string filename = (*patch)->location;
00315                 src = provideFile(_path + filename);
00316                 dst = cache_dir_r + filename;
00317                 if (0 != assert_dir(dst.dirname(), 0700))
00318                   ZYPP_THROW(Exception("Cannot create cache directory: " + dst.dirname().asString()));
00319                 filesystem::copy(src, dst);
00320               }
00321             }
00322         }
00323       }
00324 
00325       void YUMSourceImpl::createResolvables(Source_Ref source_r)
00326       {
00327         std::list<YUMRepomdData_Ptr> repo_primary;
00328         std::list<YUMRepomdData_Ptr> repo_files;
00329         //std::list<YUMRepomdData_Ptr> repo_other;
00330         std::list<YUMRepomdData_Ptr> repo_group;
00331         std::list<YUMRepomdData_Ptr> repo_pattern;
00332         std::list<YUMRepomdData_Ptr> repo_product;
00333         std::list<YUMRepomdData_Ptr> repo_patches;
00334 
00335         callback::SendReport<CreateSourceReport> report;
00336 
00337         report->startData( url() );
00338 
00339     //---------------------------------
00340     // repomd
00341 
00342       try {
00343           // first read list of all files in the repository
00344         Pathname filename = cacheExists()
00345           ? _cache_dir + "/repodata/repomd.xml"
00346           : provideFile(_path + "/repodata/repomd.xml");
00347           _metadata_files.push_back("/repodata/repomd.xml");
00348           
00349           DBG << "Reading ifgz file " << filename << endl;
00350           ifgzstream repo_st(filename.asString().c_str());
00351           YUMRepomdParser repomd(repo_st, "");
00352           for(;
00353               ! repomd.atEnd();
00354               ++repomd)
00355           {
00356             // note that we skip adding other.xml to the list of files to provide
00357             
00358             if ((*repomd)->type == "primary")
00359               repo_primary.push_back(*repomd);
00360             else if ((*repomd)->type == "filelists")
00361               repo_files.push_back(*repomd);
00362             else if ((*repomd)->type == "group")
00363               repo_group.push_back(*repomd);
00364             else if ((*repomd)->type == "pattern")
00365               repo_pattern.push_back(*repomd);
00366             else if ((*repomd)->type == "product")
00367               repo_product.push_back(*repomd);
00368             else if ((*repomd)->type == "patches")
00369               repo_patches.push_back(*repomd);
00370             else if ((*repomd)->type != "other")        // type "other" is ok, anything else not
00371               ERR << "Unknown type of repo file: " << (*repomd)->type << endl;
00372         }
00373       }
00374       catch( const Exception &  excpt_r )
00375       {
00376           ZYPP_CAUGHT( excpt_r );       // log the caught exception
00377           ERR << "Cannot read repomd file, cannot initialize source" << endl;
00378           ZYPP_THROW( Exception("Cannot read repomd file, cannot initialize source") );
00379       }
00380 
00381     //---------------------------------
00382     // files mentioned within repomd
00383 
00384       try {
00385           // now put other and filelist data to structures for easier find
00386           map<NVRA, YUMFileListData_Ptr> files_data;
00387           map<NVRA, YUMOtherData_Ptr> other_data;
00388           for (std::list<YUMRepomdData_Ptr>::const_iterator it
00389                   = repo_files.begin();
00390               it != repo_files.end();
00391               it++)
00392           {
00393             Pathname filename = cacheExists()
00394               ? _cache_dir + (*it)->location
00395               :  provideFile(_path + (*it)->location);
00396             _metadata_files.push_back((*it)->location);
00397             DBG << "Reading ifgz file " << filename << endl;
00398 
00399             ifgzstream st( filename.asString().c_str() );
00400 
00401             YUMFileListParser filelist ( st, "" );
00402             for (;
00403                   ! filelist.atEnd();
00404                   ++filelist)
00405             {
00406                 if (*filelist == NULL) continue;        // skip incompatible archs
00407 
00408                 NVRA nvra( (*filelist)->name,
00409                            Edition( (*filelist)->ver, (*filelist)->rel, str::strtonum<int>( (*filelist)->epoch ) ),
00410                            Arch ( (*filelist)->arch ) );
00411                 files_data[nvra] = *filelist;
00412             }
00413             if (filelist.errorStatus())
00414               ZYPP_THROW(Exception(filelist.errorStatus()->msg()));
00415           }
00416 
00417 #if 0   // don't parse 'other.xml' (#159316)
00418 
00419           for (std::list<YUMRepomdData_Ptr>::const_iterator it
00420                   = repo_other.begin();
00421               it != repo_other.end();
00422               it++)
00423           {
00424             Pathname filename = cacheExists()
00425               ? _cache_dir + (*it)->location
00426               : provideFile(_path + (*it)->location);
00427             if (!cacheExists())
00428             {
00429               if (! checkCheckSum(filename, (*it)->checksumType, (*it)->checksum))
00430               {
00431                 ZYPP_THROW(Exception(N_("Failed check for the metadata file check sum")));
00432               }
00433             }
00434             _metadata_files.push_back((*it)->location);
00435             DBG << "Reading file " << filename << endl;
00436 
00437             ifgzstream st ( filename.asString().c_str() );
00438             YUMOtherParser other(st, "");
00439             for (;
00440                   ! other.atEnd();
00441                   ++other)
00442             {
00443                 if (*other == NULL) continue;   // skip incompatible archs
00444                 Arch arch;
00445                 if (!(*other)->arch.empty())
00446                   arch = Arch((*other)->arch);
00447 
00448                 NVRA nvra( (*other)->name,
00449                            Edition( (*other)->ver, (*other)->rel, str::strtonum<int>( (*other)->epoch ) ),
00450                            arch );
00451                 other_data[nvra] = *other;
00452             }
00453             if (other.errorStatus())
00454               throw *other.errorStatus();
00455         }
00456 #endif
00457 
00458         // now read primary data, merge them with filelist and changelog
00459           for (std::list<YUMRepomdData_Ptr>::const_iterator it
00460                   = repo_primary.begin();
00461               it != repo_primary.end();
00462               it++)
00463         {
00464           Pathname filename = cacheExists()
00465               ? _cache_dir + (*it)->location
00466             : provideFile(_path + (*it)->location);
00467           
00468             _metadata_files.push_back((*it)->location);
00469             DBG << "Reading file " << filename << endl;
00470             ifgzstream st ( filename.asString().c_str() );
00471             YUMPrimaryParser prim(st, "");
00472 
00473             for (;
00474                   !prim.atEnd();
00475                   ++prim)
00476             {
00477               if (*prim == NULL) continue;      // incompatible arch detected during parsing
00478 
00479                 Arch arch;
00480                 if (!(*prim)->arch.empty())
00481                   arch = Arch((*prim)->arch);
00482 
00483                 NVRA nvra( (*prim)->name,
00484                            Edition( (*prim)->ver, (*prim)->rel, str::strtonum<int>( (*prim)->epoch ) ),
00485                            arch );
00486                 map<NVRA, YUMOtherData_Ptr>::iterator found_other
00487                     = other_data.find( nvra );
00488                 map<NVRA, YUMFileListData_Ptr>::iterator found_files
00489                     = files_data.find( nvra );
00490 
00491                 YUMFileListData filelist_empty;
00492                 YUMOtherData other_empty;
00493                 ResImplTraits<YUMPackageImpl>::Ptr impl;
00494                 Package::Ptr p = createPackage(
00495                   source_r,
00496                   **prim,
00497                   found_files != files_data.end()
00498                     ? *(found_files->second)
00499                     : filelist_empty,
00500                   found_other != other_data.end()
00501                     ? *(found_other->second)
00502                      : other_empty,
00503                   impl
00504                 );
00505                 ImplAndPackage iap = { impl, p };
00506                 _package_impl[nvra] = iap;
00507 //                MIL << "inserting package "<< p->name() << std::endl;
00508                 _store.insert (p);
00509             }
00510             if (prim.errorStatus())
00511               ZYPP_THROW(Exception(prim.errorStatus()->msg()));
00512         }
00513     }
00514     catch (...) {
00515         ERR << "Cannot read package information" << endl;
00516     }
00517 
00518     //---------------------------------
00519     // groups
00520     try {
00521         for (std::list<YUMRepomdData_Ptr>::const_iterator it = repo_group.begin();
00522               it != repo_group.end();
00523               it++)
00524         {
00525           Pathname filename = cacheExists()
00526               ? _cache_dir + (*it)->location
00527             : provideFile(_path + (*it)->location);
00528             
00529             _metadata_files.push_back((*it)->location);
00530             DBG << "Reading file " << filename << endl;
00531             ifgzstream st ( filename.asString().c_str() );
00532             YUMGroupParser group(st, "");
00533             for (;
00534                   !group.atEnd();
00535                   ++group)
00536             {
00537                 Selection::Ptr p = createGroup(
00538                   source_r,
00539                   **group
00540                 );
00541                 _store.insert (p);
00542             }
00543             if (group.errorStatus())
00544               ZYPP_THROW(Exception(group.errorStatus()->msg()));
00545         }
00546     }
00547     catch (...) {
00548         ERR << "Cannot read package groups information" << endl;
00549     }
00550 
00551     //---------------------------------
00552     // patterns
00553 
00554     try {
00555         for (std::list<YUMRepomdData_Ptr>::const_iterator it = repo_pattern.begin();
00556               it != repo_pattern.end();
00557               it++)
00558         {
00559           Pathname filename = cacheExists()
00560               ? _cache_dir + (*it)->location
00561             : provideFile(_path + (*it)->location);
00562             
00563             _metadata_files.push_back((*it)->location);
00564             DBG << "Reading file " << filename << endl;
00565             ifgzstream st ( filename.asString().c_str() );
00566             YUMPatternParser pattern(st, "");
00567             for (;
00568                   !pattern.atEnd();
00569                   ++pattern)
00570             {
00571                 Pattern::Ptr p = createPattern(
00572                   source_r,
00573                   **pattern
00574                 );
00575                 _store.insert (p);
00576             }
00577             if (pattern.errorStatus())
00578               ZYPP_THROW(Exception(pattern.errorStatus()->msg()));
00579         }
00580     }
00581     catch (...) {
00582           ERR << "Cannot read installation patterns information" << endl;
00583     }
00584 
00585 
00586     //---------------------------------
00587     // products
00588     try {
00589         for (std::list<YUMRepomdData_Ptr>::const_iterator it = repo_product.begin();
00590               it != repo_product.end();
00591               it++)
00592         {
00593           Pathname filename = cacheExists()
00594               ? _cache_dir + (*it)->location
00595             : provideFile(_path + (*it)->location);
00596             
00597             _metadata_files.push_back((*it)->location);
00598             DBG << "Reading file " << filename << endl;
00599             ifgzstream st ( filename.asString().c_str() );
00600             YUMProductParser product(st, "");
00601             for (;
00602                   !product.atEnd();
00603                   ++product)
00604             {
00605                 Product::Ptr p = createProduct(
00606                   source_r,
00607                   **product
00608                 );
00609                 _store.insert (p);
00610             }
00611             if (product.errorStatus())
00612               ZYPP_THROW(Exception(product.errorStatus()->msg()));
00613           }
00614     }
00615     catch (...) {
00616           ERR << "Cannot read products information" << endl;
00617     }
00618 
00619     //---------------------------------
00620     // patches, first the patches.xml index
00621     try {
00622           std::list<std::string> patch_files;
00623           for (std::list<YUMRepomdData_Ptr>::const_iterator it = repo_patches.begin();
00624               it != repo_patches.end();
00625               it++)
00626           {
00627             Pathname filename = cacheExists()
00628                 ? _cache_dir + (*it)->location
00629               : provideFile(_path + (*it)->location);
00630             
00631             _metadata_files.push_back((*it)->location);
00632             DBG << "Reading file " << filename << endl;
00633             ifgzstream st ( filename.asString().c_str() );
00634             YUMPatchesParser patch(st, "");
00635             for (;
00636                   !patch.atEnd();
00637                   ++patch)
00638             {
00639                 string filename = (*patch)->location;
00640                 if (!cacheExists())
00641                 {
00642                   if (! checkCheckSum(provideFile(_path + filename), (*patch)->checksumType, (*patch)->checksum))
00643                   {
00644                     ZYPP_THROW(Exception(N_("Failed check for the metadata file check sum")));
00645                   }
00646                 }
00647                 patch_files.push_back(filename);
00648             }
00649             if (patch.errorStatus())
00650               ZYPP_THROW(Exception(patch.errorStatus()->msg()));
00651         }
00652 
00653         //---------------------------------
00654         // now the individual patch files
00655 
00656         for (std::list<std::string>::const_iterator it = patch_files.begin();
00657           it != patch_files.end();
00658           it++)
00659         {
00660           Pathname filename = cacheExists()
00661               ? _cache_dir + *it
00662             : provideFile(_path + *it);
00663             _metadata_files.push_back(*it);
00664             DBG << "Reading file " << filename << endl;
00665             ifgzstream st ( filename.asString().c_str() );
00666             YUMPatchParser ptch(st, "");
00667             for(;
00668                     !ptch.atEnd();
00669                     ++ptch)
00670             {
00671                   Patch::Ptr p = createPatch(
00672                     source_r,
00673                     **ptch
00674                   );
00675                   _store.insert (p);
00676                   Patch::AtomList atoms = p->atoms();
00677                   for (Patch::AtomList::iterator at = atoms.begin();
00678                       at != atoms.end();
00679                       at++)
00680                   {
00681                     _store.insert (*at);
00682                   }
00683             }
00684             if (ptch.errorStatus())
00685               ZYPP_THROW(Exception(ptch.errorStatus()->msg()));
00686         }
00687     }
00688     catch (...)
00689     {
00690         ERR << "Cannot read patch metadata" << endl;
00691     }
00692 
00693     report->finishData( url(), CreateSourceReport::NO_ERROR, "" );
00694   }
00695 
00696 
00697   Package::Ptr YUMSourceImpl::createPackage(
00698     Source_Ref source_r,
00699     const zypp::parser::yum::YUMPrimaryData & parsed,
00700     const zypp::parser::yum::YUMFileListData & filelist,
00701     const zypp::parser::yum::YUMOtherData & other,
00702     ResImplTraits<YUMPackageImpl>::Ptr & impl
00703   )
00704   {
00705     try
00706     {
00707       impl = new YUMPackageImpl( source_r, parsed, filelist, other );
00708 
00709       Dependencies deps( createDependencies( parsed, ResTraits<Package>::kind ) );
00710 
00711       CapFactory f;
00712 
00713         for (std::list<FileData>::const_iterator it = filelist.files.begin();
00714              it != filelist.files.end();
00715              it++)
00716         {
00717             deps[Dep::PROVIDES].insert( f.parse( ResTraits<Package>::kind, it->name ) );
00718         }
00719 
00720       Arch arch;
00721       if (!parsed.arch.empty())
00722         arch = Arch(parsed.arch);
00723 
00724       // Collect basic Resolvable data
00725       NVRAD dataCollect( parsed.name,
00726                          Edition( parsed.ver, parsed.rel, parsed.epoch ),
00727                          arch,
00728                          deps
00729                        );
00730       Package::Ptr package = detail::makeResolvableFromImpl(
00731         dataCollect, impl
00732       );
00733       return package;
00734     }
00735     catch (const Exception & excpt_r)
00736     {
00737       ZYPP_CAUGHT(excpt_r);
00738       ZYPP_THROW(Exception("Cannot create package object"));
00739     }
00740     return 0L;
00741   }
00742 
00743   Atom::Ptr YUMSourceImpl::augmentPackage(
00744     Source_Ref source_r,
00745     const zypp::parser::yum::YUMPatchPackage & parsed
00746   )
00747   {
00748     try
00749     {
00750         Arch arch;
00751         if (!parsed.arch.empty())
00752           arch = Arch( parsed.arch );
00753 
00754         Edition edition( parsed.ver, parsed.rel, parsed.epoch );
00755         NVRA nvra( parsed.name,
00756                    edition,
00757                    arch );
00758 
00759         DBG << "augmentPackage(" << nvra << ")" << endl;
00760 
00761         // create Atom
00762         CapFactory f;
00763         Dependencies deps = createDependencies( parsed, ResTraits<Package>::kind );
00764 //        deps[Dep::REQUIRES].insert( f.parse( ResTraits<Package>::kind, parsed.name, Rel::EQ, edition ) );
00765         NVRAD atomdata( nvra, deps );
00766         ResImplTraits<YUMAtomImpl>::Ptr atomimpl = new YUMAtomImpl( source_r );
00767         Atom::Ptr atom = detail::makeResolvableFromImpl( atomdata, atomimpl );
00768 
00769         //source_r
00770         PackageImplMapT::const_iterator it = _package_impl.find( nvra );
00771         if (it == _package_impl.end()) {
00772             WAR << "Patch augments non-existant package " << nvra << endl;
00773         }
00774         else
00775         {
00776           ResImplTraits<YUMPackageImpl>::Ptr impl = it->second.impl;
00777           Package::Ptr package = it->second.package;
00778           //DBG << "found " << *package << ", impl " << impl << endl;
00779 
00780           _store.erase( package );
00781           impl->unmanage();
00782 
00783           // Atoms are inserted in the store after patch creation
00784           //DBG << "Inserting atom " << *atom << endl;
00785           //DBG << "with deps " << deps << endl;
00786           //_store.insert( atom );
00787 
00788           // Collect augmented package data
00789           NVRAD packagedata( nvra, package->deps() );
00790 
00791           if (!parsed.location.empty()) {
00792               impl->_location = parsed.location;
00793               impl->_mediaid = str::strtonum<unsigned>( parsed.media );
00794               impl->_checksum = CheckSum(parsed.checksumType, parsed.checksum);
00795           }
00796           impl->_install_only = parsed.installOnly;
00797 
00798           //DBG << "Inserting patch RPMs" << endl;
00799           impl->_patch_rpms = std::list<PatchRpm>();
00800           for (std::list<YUMPatchRpm>::const_iterator it = parsed.patchRpms.begin();
00801             it != parsed.patchRpms.end(); ++it)
00802           {
00803             std::list<BaseVersion> bv_list;
00804             for (std::list<YUMBaseVersion>::const_iterator bvit = it->baseVersions.begin();
00805               bvit != it->baseVersions.end(); ++bvit)
00806             {
00807               BaseVersion bv(
00808                 Edition (bvit->ver, bvit->rel, bvit->epoch),
00809                 CheckSum("md5", bvit->md5sum),
00810                 strtol(bvit->buildtime.c_str(), 0, 10)
00811               );
00812               bv_list.push_back(bv);
00813             }
00814             PatchRpm patch_rpm(
00815               Arch(it->arch),
00816               Pathname(it->location),
00817               strtol(it->downloadsize.c_str(), 0, 10),
00818               CheckSum (it->checksumType, it->checksum),
00819               strtol(it->buildtime.c_str(), 0, 10),
00820               bv_list
00821             );
00822             impl->_patch_rpms.push_back(patch_rpm);
00823           }
00824 
00825           //DBG << "Inserting delta RPMs" << endl;
00826 
00827           impl->_delta_rpms = std::list<DeltaRpm>();
00828           for (std::list<YUMDeltaRpm>::const_iterator it = parsed.deltaRpms.begin();
00829             it != parsed.deltaRpms.end(); ++it)
00830           {
00831             DeltaRpm delta_rpm(
00832               Arch(it->arch),
00833               Pathname(it->location),
00834               strtol(it->downloadsize.c_str(), 0, 10),
00835               CheckSum (it->checksumType, it->checksum),
00836               strtol(it->buildtime.c_str(), 0, 10),
00837               BaseVersion(
00838                 Edition (it->baseVersion.ver, it->baseVersion.rel, it->baseVersion.epoch),
00839                 CheckSum("md5", it->baseVersion.md5sum),
00840                 strtol(it->baseVersion.buildtime.c_str(), 0, 10)
00841               )
00842             );
00843             impl->_delta_rpms.push_back(delta_rpm);
00844           }
00845         
00846           Package::Ptr new_package = detail::makeResolvableFromImpl(
00847               packagedata, impl
00848           );
00849 
00850           //DBG << "new_package " << *new_package << endl;
00851 
00852           _store.insert( new_package );
00853         }
00854         return atom;
00855     }
00856     catch (const Exception & excpt_r)
00857     {
00858       ZYPP_CAUGHT(excpt_r);
00859       ZYPP_THROW(Exception("Cannot create augmented package object"));
00860     }
00861     return 0L;
00862   }
00863 
00864   Selection::Ptr YUMSourceImpl::createGroup(
00865     Source_Ref source_r,
00866     const zypp::parser::yum::YUMGroupData & parsed
00867   )
00868   {
00869     try
00870     {
00871       ResImplTraits<YUMGroupImpl>::Ptr impl(new YUMGroupImpl(source_r, parsed));
00872       // Collect basic Resolvable data
00873       NVRAD dataCollect( parsed.groupId,
00874                          Edition::noedition,                    // group has just a name,
00875                          Arch_noarch,                           //   pattern has edition & arch
00876                          createGroupDependencies(parsed));
00877       Selection::Ptr group = detail::makeResolvableFromImpl(
00878         dataCollect, impl
00879       );
00880       return group;
00881     }
00882     catch (const Exception & excpt_r)
00883     {
00884       ZYPP_CAUGHT(excpt_r);
00885       ZYPP_THROW(Exception("Cannot create package group object"));
00886     }
00887     return 0L;
00888   }
00889 
00890   Pattern::Ptr YUMSourceImpl::createPattern(
00891     Source_Ref source_r,
00892     const zypp::parser::yum::YUMPatternData & parsed
00893   )
00894   {
00895     try
00896     {
00897       ResImplTraits<YUMPatternImpl>::Ptr impl(new YUMPatternImpl(source_r, parsed));
00898       // Collect basic Resolvable data
00899       Arch arch;
00900       if (!parsed.arch.empty())
00901         arch = Arch(parsed.arch);
00902 
00903       NVRAD dataCollect( parsed.name,
00904                          Edition( parsed.ver, parsed.rel, parsed.epoch ),
00905                          arch,
00906                          createDependencies(parsed, ResTraits<Pattern>::kind));
00907       Pattern::Ptr pattern = detail::makeResolvableFromImpl(
00908         dataCollect, impl
00909       );
00910       return pattern;
00911     }
00912     catch (const Exception & excpt_r)
00913     {
00914       ZYPP_CAUGHT(excpt_r);
00915       ZYPP_THROW(Exception("Cannot create installation pattern object"));
00916     }
00917     return 0L;
00918   }
00919 
00920   Message::Ptr YUMSourceImpl::createMessage(
00921     Source_Ref source_r,
00922     const zypp::parser::yum::YUMPatchMessage & parsed,
00923     Patch::constPtr patch
00924   )
00925   {
00926     try
00927     {
00928       ResImplTraits<YUMMessageImpl>::Ptr impl(new YUMMessageImpl(source_r, parsed, patch));
00929       Arch arch;
00930       if (!parsed.arch.empty())
00931         arch = Arch(parsed.arch);
00932       // Collect basic Resolvable data
00933       NVRAD dataCollect( parsed.name,
00934                               Edition( parsed.ver, parsed.rel, parsed.epoch ),
00935                               arch,
00936                               createDependencies(parsed,
00937                                                   ResTraits<Message>::kind)
00938                             );
00939       Message::Ptr message = detail::makeResolvableFromImpl(
00940         dataCollect, impl
00941       );
00942       return message;
00943     }
00944     catch (const Exception & excpt_r)
00945     {
00946       ZYPP_CAUGHT(excpt_r);
00947       ZYPP_THROW(Exception("Cannot create message object"));
00948     }
00949     return 0L;
00950   }
00951 
00952   Script::Ptr YUMSourceImpl::createScript(
00953     Source_Ref source_r,
00954     const zypp::parser::yum::YUMPatchScript & parsed
00955   )
00956   {
00957     try
00958     {
00959       ResImplTraits<YUMScriptImpl>::Ptr impl(new YUMScriptImpl(source_r, parsed));
00960       Arch arch;
00961       if (!parsed.arch.empty())
00962         arch = Arch(parsed.arch);
00963       // Collect basic Resolvable data
00964       NVRAD dataCollect( parsed.name,
00965                       Edition( parsed.ver, parsed.rel, parsed.epoch ),
00966                       arch,
00967                       createDependencies(parsed,
00968                                           ResTraits<Script>::kind)
00969                     );
00970       Script::Ptr script = detail::makeResolvableFromImpl(
00971         dataCollect, impl
00972       );
00973       return script;
00974     }
00975     catch (const Exception & excpt_r)
00976     {
00977       ZYPP_CAUGHT(excpt_r);
00978       ZYPP_THROW(Exception("Cannot create script object"));
00979     }
00980     return 0L;
00981   }
00982 
00983   Product::Ptr YUMSourceImpl::createProduct(
00984     Source_Ref source_r,
00985     const zypp::parser::yum::YUMProductData & parsed
00986   )
00987   {
00988     try
00989     {
00990       ResImplTraits<YUMProductImpl>::Ptr impl(new YUMProductImpl(source_r, parsed));
00991 
00992             // Collect basic Resolvable data
00993       Arch arch;
00994       if (!parsed.arch.empty())
00995         arch = Arch(parsed.arch);
00996       NVRAD dataCollect( parsed.name,
00997                               Edition( parsed.ver, parsed.rel, parsed.epoch ),
00998                               arch,
00999                               createDependencies(parsed,
01000                                                   ResTraits<Product>::kind)
01001                             );
01002       Product::Ptr product = detail::makeResolvableFromImpl(
01003         dataCollect, impl
01004       );
01005       return product;
01006     }
01007     catch (const Exception & excpt_r)
01008     {
01009       ZYPP_CAUGHT(excpt_r);
01010       ZYPP_THROW(Exception("Cannot create product object"));
01011     }
01012     return 0L;
01013   }
01014 
01015   Patch::Ptr YUMSourceImpl::createPatch(
01016     Source_Ref source_r,
01017     const zypp::parser::yum::YUMPatchData & parsed
01018   )
01019   {
01020     try
01021     {
01022       ResImplTraits<YUMPatchImpl>::Ptr impl(new YUMPatchImpl(source_r, parsed, *this));
01023 
01024       Arch arch;
01025       if (!parsed.arch.empty())
01026         arch = Arch(parsed.arch);
01027 
01028       // Collect basic Resolvable data
01029       NVRAD dataCollect( parsed.name,
01030                       Edition( parsed.ver, parsed.rel, parsed.epoch ),
01031                       arch,
01032                       createDependencies( parsed,
01033                                           ResTraits<Patch>::kind)
01034                     );
01035       Patch::Ptr patch = detail::makeResolvableFromImpl(
01036         dataCollect, impl
01037       );
01038         // now process the atoms
01039         CapFactory _f;
01040         Capability cap( _f.parse(
01041           Patch::TraitsType::kind,
01042           parsed.name,
01043           Rel::EQ,
01044           Edition(parsed.ver, parsed.rel, parsed.epoch)
01045           ));
01046 
01047         // maps name to parser data in order to find 'best' architectureC
01048         typedef std::map<std::string, shared_ptr<YUMPatchPackage> > PkgAtomsMap;
01049         PkgAtomsMap pkg_atoms;
01050 
01051         for (std::list<shared_ptr<YUMPatchAtom> >::const_iterator it
01052                                         = parsed.atoms.begin();
01053              it != parsed.atoms.end();
01054              it++)
01055         {
01056           switch ((*it)->atomType())
01057           {
01058             // for packages, try to find best architecture for name-version-release first (#168840)
01059             // we can't use the name alone as there might be different editions for the same name
01060             // with different architecture.
01061             // So we only choose the best architecture if name-version-edition matches (#170098)
01062 
01063             case YUMPatchAtom::Package: {
01064               shared_ptr<YUMPatchPackage> package_data
01065                 = dynamic_pointer_cast<YUMPatchPackage>(*it);
01066               string atomkey( package_data->name + "-" + package_data->epoch + ":" + package_data->ver + "-" + package_data->rel );
01067 
01068               // check if atomkey is already known
01069               PkgAtomsMap::iterator pa_pos = pkg_atoms.find( atomkey );
01070               if (pa_pos != pkg_atoms.end()) {
01071                 try {
01072                   Arch oldarch, newarch;
01073                   if (!(pa_pos->second->arch.empty())) oldarch = Arch( pa_pos->second->arch );
01074                   if (!(package_data->arch.empty())) newarch = Arch( package_data->arch );
01075                   if (newarch.compatibleWith( getZYpp()->architecture() ) ) {                   // new one is compatible (if not, we don't care)
01076 
01077                     if (!oldarch.compatibleWith( getZYpp()->architecture() )                    // old one is not compatible
01078                         || oldarch.compare( newarch ) < 0)                                      //  or compatible but worse
01079                     {
01080                       pa_pos->second = package_data;                            // new one is it !
01081                     }
01082                   }
01083                 }
01084                 catch( const Exception & excpt_r ) {
01085                     ZYPP_CAUGHT( excpt_r );
01086                     ERR << "Package " << package_data->name << " in patch's atomlist has bad architecture '" << package_data->arch << "'" << endl;
01087                 }
01088               }
01089               else {
01090                 pkg_atoms[atomkey] = package_data;                                      // first occurence of this atomkey
01091               }
01092               break;
01093             }
01094             case YUMPatchAtom::Message: {
01095               shared_ptr<YUMPatchMessage> message_data
01096                 = dynamic_pointer_cast<YUMPatchMessage>(*it);
01097               Message::Ptr message = createMessage(source_r, *message_data, patch);
01098               impl->_atoms.push_back(message);
01099               break;
01100             }
01101             case YUMPatchAtom::Script: {
01102               shared_ptr<YUMPatchScript> script_data
01103                 = dynamic_pointer_cast<YUMPatchScript>(*it);
01104               Script::Ptr script = createScript(source_r, *script_data);
01105               impl->_atoms.push_back(script);
01106               break;
01107             }
01108             default:
01109               ERR << "Unknown type of atom" << endl;
01110           }
01111 #if 0                                   // atoms require their patch, why ?
01112           for (Patch::AtomList::iterator it = impl->_atoms.begin();
01113                it != impl->_atoms.end();
01114                it++)
01115           {
01116             (*it)->injectRequires(cap);
01117           }
01118 #endif
01119         }
01120 
01121         for (PkgAtomsMap::const_iterator pa_pos = pkg_atoms.begin(); pa_pos != pkg_atoms.end(); ++pa_pos) {
01122           Atom::Ptr atom = augmentPackage( source_r, *(pa_pos->second) );
01123           impl->_atoms.push_back(atom);
01124         }
01125 
01126       return patch;
01127     }
01128     catch (const Exception & excpt_r)
01129     {
01130       ZYPP_CAUGHT(excpt_r);
01131       ZYPP_THROW(Exception("Cannot create patch object"));
01132     }
01133     return 0L;
01134   }
01135 
01136   Dependencies YUMSourceImpl::createDependencies(
01137     const zypp::parser::yum::YUMObjectData & parsed,
01138     const Resolvable::Kind my_kind
01139   )
01140   {
01141     Dependencies _deps;
01142     for (std::list<YUMDependency>::const_iterator it = parsed.provides.begin();
01143         it != parsed.provides.end();
01144         it++)
01145     {
01146       _deps[Dep::PROVIDES].insert(createCapability(*it, my_kind));
01147     }
01148 
01149     for (std::list<YUMDependency>::const_iterator it = parsed.conflicts.begin();
01150         it != parsed.conflicts.end();
01151         it++)
01152     {
01153       _deps[Dep::CONFLICTS].insert(createCapability(*it, my_kind));
01154     }
01155 
01156     for (std::list<YUMDependency>::const_iterator it = parsed.obsoletes.begin();
01157         it != parsed.obsoletes.end();
01158         it++)
01159     {
01160       _deps[Dep::OBSOLETES].insert(createCapability(*it, my_kind));
01161     }
01162 
01163     for (std::list<YUMDependency>::const_iterator it = parsed.freshens.begin();
01164         it != parsed.freshens.end();
01165         it++)
01166     {
01167       _deps[Dep::FRESHENS].insert(createCapability(*it, my_kind));
01168     }
01169 
01170     for (std::list<YUMDependency>::const_iterator it = parsed.recommends.begin();
01171         it != parsed.recommends.end();
01172         it++)
01173     {
01174       _deps[Dep::RECOMMENDS].insert(createCapability(*it, my_kind));
01175     }
01176 
01177     for (std::list<YUMDependency>::const_iterator it = parsed.suggests.begin();
01178         it != parsed.suggests.end();
01179         it++)
01180     {
01181       _deps[Dep::SUGGESTS].insert(createCapability(*it, my_kind));
01182     }
01183 
01184     for (std::list<YUMDependency>::const_iterator it = parsed.supplements.begin();
01185         it != parsed.supplements.end();
01186         it++)
01187     {
01188       _deps[Dep::SUPPLEMENTS].insert(createCapability(*it, my_kind));
01189     }
01190 
01191     for (std::list<YUMDependency>::const_iterator it = parsed.enhances.begin();
01192         it != parsed.enhances.end();
01193         it++)
01194     {
01195       _deps[Dep::ENHANCES].insert(createCapability(*it, my_kind));
01196     }
01197 
01198     for (std::list<YUMDependency>::const_iterator it = parsed.requires.begin();
01199         it != parsed.requires.end();
01200         it++)
01201     {
01202       if (it->pre == "1")
01203         _deps[Dep::PREREQUIRES].insert(createCapability(*it, my_kind));
01204       else
01205         _deps[Dep::REQUIRES].insert(createCapability(*it, my_kind));
01206     }
01207 
01208     return _deps;
01209   }
01210 
01211   Dependencies YUMSourceImpl::createGroupDependencies(
01212     const zypp::parser::yum::YUMGroupData & parsed
01213   )
01214   {
01215     Dependencies _deps;
01216 
01217     for (std::list<PackageReq>::const_iterator it = parsed.packageList.begin();
01218       it != parsed.packageList.end();
01219       it++)
01220     {
01221       Dep _dep_kind = Dep::REQUIRES;
01222       if (it->type == "mandatory" || it->type == "")
01223       {
01224         _dep_kind = Dep::REQUIRES;
01225       }
01226       else if (it->type == "default")
01227       {
01228         _dep_kind = Dep::RECOMMENDS;
01229       }
01230       else if (it->type == "optional")
01231       {
01232         _dep_kind = Dep::SUGGESTS;
01233       }
01234       _deps[_dep_kind].insert(createCapability(YUMDependency(
01235       "",
01236       it->name,
01237       "EQ",
01238       it->epoch,
01239       it->ver,
01240       it->rel,
01241       ""
01242         ),
01243         ResTraits<Package>::kind));
01244     }
01245     for (std::list<MetaPkg>::const_iterator it = parsed.grouplist.begin();
01246       it != parsed.grouplist.end();
01247       it++)
01248     {
01249       Dep _dep_kind = Dep::REQUIRES;
01250       if (it->type == "mandatory" || it->type == "")
01251       {
01252         _dep_kind = Dep::REQUIRES;
01253       }
01254       else if (it->type == "default")
01255       {
01256         _dep_kind = Dep::RECOMMENDS;
01257       }
01258       else if (it->type == "optional")
01259       {
01260         _dep_kind = Dep::SUGGESTS;
01261       }
01262       _deps[_dep_kind].insert(createCapability(YUMDependency(
01263       "",
01264       it->name,
01265       "",
01266       "",
01267       "",
01268       "",
01269       ""
01270         ),
01271         ResTraits<Selection>::kind));
01272     }
01273     return _deps;
01274   }
01275 
01276   Capability YUMSourceImpl::createCapability(const YUMDependency & dep,
01277                 const Resolvable::Kind & my_kind)
01278   {
01279     CapFactory _f;
01280     Resolvable::Kind _kind = dep.kind == "" ? my_kind : Resolvable::Kind(dep.kind);
01281     Capability cap;
01282     if ( ! dep.isEncoded() )
01283     {
01284       cap = _f.parse(
01285       _kind,
01286       dep.name,
01287       Rel(dep.flags),
01288       Edition(dep.ver, dep.rel, dep.epoch)
01289       );
01290     }
01291     else
01292     {
01293       cap = _f.parse( _kind, dep.encoded );
01294     }
01295     return cap;
01296   }
01297 
01298 
01299 
01300 
01301       bool YUMSourceImpl::checkCheckSum (const Pathname & filename, std::string csum_type, const std::string & csum)
01302       {
01303         MIL << "Checking checksum for " << filename << " as type: " << csum_type << "; value: " << csum << endl;
01304         if (str::toLower(csum_type) == "sha")
01305         {
01306           if (csum.size() == 40)
01307             csum_type = "sha1";
01308           else if (csum.size() == 64)
01309             csum_type = "sha256";
01310           DBG << "Checksum size is " << csum.size() << ", checksum type set to " << csum_type << endl;
01311         }
01312         ifstream st(filename.asString().c_str());
01313         std::string dig = Digest::digest (csum_type, st, 4096);
01314         if (dig == "")
01315         {
01316           ERR << "Cannot compute the checksum" << endl;
01317           return true;
01318 #warning TODO Define behavior if checksum computing fails
01319         }
01320         dig = str::toLower (dig);
01321         bool ret = (dig == str::toLower(csum));
01322         if (ret)
01323           MIL << "Checksums are the same" << endl;
01324         else
01325           WAR << "Checksum missmatch: metadata: " << csum << "; real: " << dig << endl;
01326         return true;
01327 #warning remove line above, ask user what to do...
01328         return ret;
01329       }
01330 
01331     } // namespace yum
01333   } // namespace source
01336 } // namespace zypp

Generated on Thu May 4 16:03:28 2006 for zypp by  doxygen 1.4.6