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

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