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

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