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