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_("The signed repomd.xml file failed the 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 if ( ! *product )
00470 {
00471 ERR << "skipping invalid product from " << filename << endl;
00472 continue;
00473 }
00474
00475 Product::Ptr p = createProduct( source_r, **product );
00476 store.insert (p);
00477 }
00478
00479 if (product.errorStatus())
00480 {
00481
00482 report->finish( selfSourceRef(), str::form(_("Reading product from %s"), filename.asString().c_str()), source::SourceReport::INVALID, product.errorStatus()->msg() );
00483 ZYPP_THROW(SourceMetadataException( "Error reading product from " + filename.asString()+ " : " + product.errorStatus()->msg()));
00484 }
00485 else
00486 {
00487
00488 report->finish( selfSourceRef(), str::form(_("Reading product from %s"), filename.asString().c_str()), source::SourceReport::NO_ERROR, "" );
00489 }
00490 }
00491 }
00492 catch ( const Exception &e )
00493 {
00494 ZYPP_CAUGHT(e);
00495
00496 report->finish( selfSourceRef(), str::form(_("Reading product from %s"), filename.asString().c_str()), source::SourceReport::INVALID, e.msg() );
00497 ZYPP_THROW(SourceMetadataException(e.msg()));
00498 }
00499
00500 }
00501
00502 void YUMSourceImpl::providePackages(Source_Ref source_r, ResStore& store)
00503 {
00504 Pathname filename;
00505 callback::SendReport<SourceReport> report;
00506
00507
00508 map<NVRA, YUMFileListData_Ptr> files_data;
00509 map<NVRA, YUMOtherData_Ptr> other_data;
00510
00511 try
00512 {
00513 for (std::list<YUMRepomdData_Ptr>::const_iterator it
00514 = _repo_files.begin();
00515 it != _repo_files.end();
00516 it++)
00517 {
00518 Pathname filename = metadataRoot() + (*it)->location;
00519 DBG << "Reading ifgz file " << filename << endl;
00520 ifgzstream st( filename.asString().c_str() );
00521
00522 parser::ParserProgress::Ptr progress;
00523 YUMSourceEventHandler npp(report);
00524 progress.reset( new parser::ParserProgress( npp, get_stream_size(filename) ) );
00525
00526 report->start( selfSourceRef(), str::form(_("Reading filelist from %s"), filename.asString().c_str()) );
00527
00528 YUMFileListParser filelist ( st, "", progress );
00529 for (; ! filelist.atEnd(); ++filelist)
00530 {
00531 if (*filelist == NULL) continue;
00532 NVRA nvra( (*filelist)->name,
00533 Edition( (*filelist)->ver, (*filelist)->rel, str::strtonum<int>( (*filelist)->epoch ) ),
00534 Arch ( (*filelist)->arch ) );
00535 files_data[nvra] = *filelist;
00536 }
00537
00538 if (filelist.errorStatus())
00539 {
00540
00541 report->finish( selfSourceRef(), str::form(_("Reading filelist from %s"), filename.asString().c_str()), source::SourceReport::INVALID, filelist.errorStatus()->msg() );
00542 ZYPP_THROW(SourceMetadataException( "Error reading filelists from " + filename.asString()+ " : " + filelist.errorStatus()->msg()));
00543 }
00544 else
00545 {
00546
00547 report->finish( selfSourceRef(), str::form(_("Reading filelist from %s"), filename.asString().c_str()), source::SourceReport::NO_ERROR, "" );
00548 }
00549 }
00550 }
00551 catch ( const Exception &e )
00552 {
00553 ZYPP_CAUGHT(e);
00554
00555 report->finish( selfSourceRef(),str::form(_("Reading filelist from %s"), filename.asString().c_str()), source::SourceReport::INVALID, e.msg() );
00556 ZYPP_THROW(SourceMetadataException(e.msg()));
00557 }
00558
00559 try
00560 {
00561
00562 for (std::list<YUMRepomdData_Ptr>::const_iterator it = _repo_primary.begin(); it != _repo_primary.end(); it++)
00563 {
00564 filename = metadataRoot() + (*it)->location;
00565 DBG << "Reading file " << filename << endl;
00566
00567 parser::ParserProgress::Ptr progress;
00568 YUMSourceEventHandler npp(report);
00569 progress.reset( new parser::ParserProgress( npp ) );
00570
00571 report->start( selfSourceRef(), str::form(_("Reading packages from %s"), filename.asString().c_str()) );
00572
00573 ifgzstream st ( filename.asString().c_str() );
00574
00575 YUMPrimaryParser prim(st, "", progress);
00576
00577 for (; !prim.atEnd(); ++prim)
00578 {
00579 if (*prim == NULL) continue;
00580
00581 Arch arch;
00582 if (!(*prim)->arch.empty())
00583 arch = Arch((*prim)->arch);
00584
00585 NVRA nvra( (*prim)->name,
00586 Edition( (*prim)->ver, (*prim)->rel, str::strtonum<int>( (*prim)->epoch ) ),
00587 arch );
00588 map<NVRA, YUMOtherData_Ptr>::iterator found_other = other_data.find( nvra );
00589 map<NVRA, YUMFileListData_Ptr>::iterator found_files = files_data.find( nvra );
00590
00591 YUMFileListData filelist_empty;
00592 YUMOtherData other_empty;
00593 ResImplTraits<YUMPackageImpl>::Ptr impl;
00594 Package::Ptr p = createPackage( source_r, **prim, found_files != files_data.end()
00595 ? *(found_files->second)
00596 : filelist_empty,
00597 found_other != other_data.end()
00598 ? *(found_other->second)
00599 : other_empty,
00600 impl
00601 );
00602 ImplAndPackage iap = { impl, p };
00603 _package_impl[nvra] = iap;
00604
00605 store.insert (p);
00606 }
00607
00608 if (prim.errorStatus())
00609 {
00610
00611 report->finish( selfSourceRef(), str::form(_("Reading packages from %s"), filename.asString().c_str()), source::SourceReport::INVALID, prim.errorStatus()->msg() );
00612 ZYPP_THROW(SourceMetadataException( "Error packages from " + filename.asString()+ " : " + prim.errorStatus()->msg()));
00613 }
00614 else
00615 {
00616
00617 report->finish( selfSourceRef(), str::form(_("Reading packages from %s"), filename.asString().c_str()), source::SourceReport::NO_ERROR, "" );
00618 }
00619 }
00620 }
00621 catch ( const Exception &e )
00622 {
00623 ZYPP_CAUGHT(e);
00624
00625 report->finish( selfSourceRef(), str::form(_("Reading packages from %s"), filename.asString().c_str()), source::SourceReport::INVALID, e.msg() );
00626 ZYPP_THROW(SourceMetadataException(e.msg()));
00627 }
00628
00629 }
00630
00631 void YUMSourceImpl::provideSelections(Source_Ref source_r, ResStore& store)
00632 {
00633 callback::SendReport<SourceReport> report;
00634 Pathname filename;
00635 try
00636 {
00637 for (std::list<YUMRepomdData_Ptr>::const_iterator it = _repo_group.begin();
00638 it != _repo_group.end();
00639 it++)
00640 {
00641 Pathname filename = metadataRoot() + (*it)->location;
00642 DBG << "Reading file " << filename << endl;
00643 ifgzstream st ( filename.asString().c_str() );
00644
00645 parser::ParserProgress::Ptr progress;
00646 YUMSourceEventHandler npp(report);
00647 progress.reset( new parser::ParserProgress( npp ) );
00648
00649 report->start( selfSourceRef(), str::form(_("Reading selection from %s"), filename.asString().c_str()) );
00650
00651 YUMGroupParser group(st, "", progress);
00652 for (; !group.atEnd(); ++group)
00653 {
00654 Selection::Ptr p = createGroup( source_r, **group );
00655 store.insert (p);
00656 }
00657
00658 if (group.errorStatus())
00659 {
00660
00661 report->finish( selfSourceRef(), str::form(_("Reading selection from %s"), filename.asString().c_str()), source::SourceReport::INVALID, group.errorStatus()->msg() );
00662 ZYPP_THROW(SourceMetadataException( "Error Parsing selection " + filename.asString()+ " : " + group.errorStatus()->msg()));
00663 }
00664 else
00665 {
00666
00667 report->finish( selfSourceRef(), str::form(_("Reading selection from %s"), filename.asString().c_str()), source::SourceReport::NO_ERROR, "" );
00668 }
00669 }
00670 }
00671 catch ( const Exception &e )
00672 {
00673 ZYPP_CAUGHT(e);
00674
00675 report->finish( selfSourceRef(), str::form(_("Reading selection from %s"), filename.asString().c_str()), source::SourceReport::INVALID, e.msg() );
00676 ZYPP_THROW(SourceMetadataException(e.msg()));
00677 }
00678
00679 }
00680
00681 void YUMSourceImpl::providePatterns(Source_Ref source_r, ResStore& store)
00682 {
00683 callback::SendReport<SourceReport> report;
00684 Pathname filename;
00685 try
00686 {
00687 for (std::list<YUMRepomdData_Ptr>::const_iterator it = _repo_pattern.begin();
00688 it != _repo_pattern.end(); it++)
00689 {
00690 Pathname filename = metadataRoot() + (*it)->location;
00691
00692 DBG << "Reading file " << filename << endl;
00693 ifgzstream st ( filename.asString().c_str() );
00694
00695 parser::ParserProgress::Ptr progress;
00696 YUMSourceEventHandler npp(report);
00697 progress.reset( new parser::ParserProgress( npp ) );
00698
00699 report->start( selfSourceRef(), str::form(_("Reading pattern from %s"), filename.asString().c_str()) );
00700
00701 YUMPatternParser pattern(st, "", progress);
00702 for (; !pattern.atEnd(); ++pattern)
00703 {
00704 Pattern::Ptr p = createPattern( source_r, **pattern );
00705 store.insert (p);
00706 }
00707
00708 if (pattern.errorStatus())
00709 {
00710
00711 report->finish( selfSourceRef(), str::form(_("Reading pattern from %s"), filename.asString().c_str()), source::SourceReport::INVALID, pattern.errorStatus()->msg() );
00712 ZYPP_THROW(SourceMetadataException( "Error parsing pattern" + filename.asString()+ " : " + pattern.errorStatus()->msg()));
00713 }
00714 else
00715 {
00716
00717 report->finish( selfSourceRef(), str::form(_("Reading pattern from %s"), filename.asString().c_str()), source::SourceReport::NO_ERROR, "" );
00718 }
00719 }
00720 }
00721 catch ( const Exception &e )
00722 {
00723 ZYPP_CAUGHT(e);
00724
00725 report->finish( selfSourceRef(), str::form(_("Reading pattern from %s"), filename.asString().c_str()), source::SourceReport::INVALID, e.msg() );
00726 ZYPP_THROW(SourceMetadataException(e.msg()));
00727 }
00728
00729 }
00730
00731 void YUMSourceImpl::providePatches(Source_Ref source_r, ResStore& store)
00732 {
00733 std::list<std::string> patch_files;
00734 callback::SendReport<SourceReport> report;
00735 Pathname filename;
00736
00737 try
00738 {
00739 for (std::list<YUMRepomdData_Ptr>::const_iterator it = _repo_patches.begin();
00740 it != _repo_patches.end();
00741 it++)
00742 {
00743 filename = metadataRoot() + (*it)->location;
00744
00745 DBG << "Reading file " << filename << endl;
00746 ifgzstream st ( filename.asString().c_str() );
00747
00748 parser::ParserProgress::Ptr progress;
00749 YUMSourceEventHandler npp(report);
00750 progress.reset( new parser::ParserProgress( npp ) );
00751
00752 report->start( selfSourceRef(), str::form(_("Reading patches index %s"), filename.asString().c_str()) );
00753 YUMPatchesParser patch(st, "", progress);
00754
00755 for (; !patch.atEnd(); ++patch)
00756 {
00757 string filename = (*patch)->location;
00758 patch_files.push_back(filename);
00759 }
00760
00761 if (patch.errorStatus())
00762 {
00763
00764 report->finish( selfSourceRef(), str::form(_("Reading patches index %s"), filename.asString().c_str()), source::SourceReport::INVALID, patch.errorStatus()->msg() );
00765 ZYPP_THROW(SourceMetadataException( "Error Parsing patch " + filename.asString()+ " : " + patch.errorStatus()->msg()));
00766 }
00767 else
00768 {
00769
00770 report->finish( selfSourceRef(), str::form(_("Reading patches index %s"), filename.asString().c_str()), source::SourceReport::NO_ERROR, "" );
00771 }
00772 }
00773 }
00774 catch ( const Exception &e )
00775 {
00776 ZYPP_CAUGHT(e);
00777
00778 report->finish( selfSourceRef(), str::form(_("Reading patches index %s"), filename.asString().c_str()), source::SourceReport::INVALID, e.msg() );
00779 ZYPP_THROW(SourceMetadataException(e.msg()));
00780 }
00781
00782 try
00783 {
00784
00785
00786 for (std::list<std::string>::const_iterator it = patch_files.begin();
00787 it != patch_files.end();
00788 it++)
00789 {
00790 filename = metadataRoot() + *it;
00791 DBG << "Reading file " << filename << endl;
00792
00793
00794 ifgzstream st ( filename.asString().c_str() );
00795
00796 parser::ParserProgress::Ptr progress;
00797 YUMSourceEventHandler npp(report);
00798 progress.reset( new parser::ParserProgress( npp ) );
00799
00800
00801 report->start( selfSourceRef(), str::form(_("Reading patch %s"), filename.asString().c_str()) );
00802
00803 YUMPatchParser ptch(st, "", progress);
00804 for (; !ptch.atEnd(); ++ptch)
00805 {
00806 Patch::Ptr p = createPatch( source_r, **ptch );
00807 store.insert (p);
00808 Patch::AtomList atoms = p->atoms();
00809 for (Patch::AtomList::iterator at = atoms.begin(); at != atoms.end(); at++)
00810 {
00811 _store.insert (*at);
00812 }
00813 }
00814
00815 if (ptch.errorStatus())
00816 {
00817
00818 report->finish( selfSourceRef(), str::form(_("Reading patch %s"), filename.asString().c_str()), source::SourceReport::INVALID, ptch.errorStatus()->msg() );
00819 ZYPP_THROW(SourceMetadataException( "Error Parsing patch " + filename.asString()+ " : " + ptch.errorStatus()->msg()));
00820 }
00821 else
00822 {
00823
00824 report->finish( selfSourceRef(), str::form(_("Reading patch %s"), filename.asString().c_str()), source::SourceReport::NO_ERROR, "" );
00825 }
00826 }
00827 }
00828 catch ( const Exception &e )
00829 {
00830 ERR << "Cannot read patch metadata" << endl;
00831 ZYPP_CAUGHT(e);
00832
00833 report->finish( selfSourceRef(), str::form(_("Reading patch %s"), filename.asString().c_str()), source::SourceReport::INVALID, e.msg() );
00834 ZYPP_THROW(SourceMetadataException(e.msg()));
00835 }
00836 }
00837
00838 ResStore YUMSourceImpl::provideResolvablesByKind(Source_Ref source_r, zypp::Resolvable::Kind kind)
00839 {
00840 ResStore store;
00841
00842
00843
00844 if ( kind == ResTraits<Product>::kind )
00845 provideProducts ( selfSourceRef(), store );
00846 else if ( kind == ResTraits<Package>::kind )
00847 providePackages (selfSourceRef(), store );
00848 else if ( kind == ResTraits<Selection>::kind )
00849 provideSelections ( selfSourceRef(), store );
00850 else if ( kind == ResTraits<Pattern>::kind )
00851 providePatterns ( selfSourceRef(), store );
00852 else if ( kind == ResTraits<Pattern>::kind )
00853 providePatches ( selfSourceRef(), store );
00854
00855 return store;
00856 }
00857
00858 void YUMSourceImpl::createResolvables(Source_Ref source_r)
00859 {
00860
00861
00862 provideProducts(selfSourceRef(), _store);
00863 providePackages(selfSourceRef(), _store);
00864 provideSelections(selfSourceRef(), _store);
00865 providePatterns(selfSourceRef(), _store);
00866 providePatches(selfSourceRef(), _store);
00867
00868 }
00869
00870
00871 Package::Ptr YUMSourceImpl::createPackage(
00872 Source_Ref source_r,
00873 const zypp::parser::yum::YUMPrimaryData & parsed,
00874 const zypp::parser::yum::YUMFileListData & filelist,
00875 const zypp::parser::yum::YUMOtherData & other,
00876 ResImplTraits<YUMPackageImpl>::Ptr & impl
00877 )
00878 {
00879 try
00880 {
00881 impl = new YUMPackageImpl( source_r, parsed, filelist, other );
00882
00883 Dependencies deps( createDependencies( parsed, ResTraits<Package>::kind ) );
00884
00885 CapFactory f;
00886
00887 for (std::list<FileData>::const_iterator it = filelist.files.begin();
00888 it != filelist.files.end();
00889 it++)
00890 {
00891 deps[Dep::PROVIDES].insert( f.parse( ResTraits<Package>::kind, it->name ) );
00892 }
00893
00894 Arch arch;
00895 if (!parsed.arch.empty())
00896 arch = Arch(parsed.arch);
00897
00898
00899 NVRAD dataCollect( parsed.name,
00900 Edition( parsed.ver, parsed.rel, parsed.epoch ),
00901 arch,
00902 deps
00903 );
00904 Package::Ptr package = detail::makeResolvableFromImpl(
00905 dataCollect, impl
00906 );
00907 return package;
00908 }
00909 catch (const Exception & excpt_r)
00910 {
00911 ZYPP_CAUGHT(excpt_r);
00912 ZYPP_THROW(Exception("Cannot create package object"));
00913 }
00914 return 0L;
00915 }
00916
00917 Atom::Ptr YUMSourceImpl::augmentPackage(
00918 Source_Ref source_r,
00919 const zypp::parser::yum::YUMPatchPackage & parsed
00920 )
00921 {
00922 try
00923 {
00924 Arch arch;
00925 if (!parsed.arch.empty())
00926 arch = Arch( parsed.arch );
00927
00928 Edition edition( parsed.ver, parsed.rel, parsed.epoch );
00929 NVRA nvra( parsed.name,
00930 edition,
00931 arch );
00932
00933 DBG << "augmentPackage(" << nvra << ")" << endl;
00934
00935
00936 CapFactory f;
00937 Dependencies deps = createDependencies( parsed, ResTraits<Package>::kind );
00938
00939 NVRAD atomdata( nvra, deps );
00940 ResImplTraits<YUMAtomImpl>::Ptr atomimpl = new YUMAtomImpl( source_r );
00941 Atom::Ptr atom = detail::makeResolvableFromImpl( atomdata, atomimpl );
00942
00943
00944 PackageImplMapT::const_iterator it = _package_impl.find( nvra );
00945 if (it == _package_impl.end())
00946 {
00947 WAR << "Patch augments non-existant package " << nvra << endl;
00948 }
00949 else
00950 {
00951 ResImplTraits<YUMPackageImpl>::Ptr impl = it->second.impl;
00952
00953 if (!parsed.location.empty())
00954 {
00955 impl->_location = parsed.location;
00956 impl->_mediaNumber = str::strtonum<unsigned>( parsed.media );
00957 impl->_checksum = CheckSum(parsed.checksumType, parsed.checksum);
00958 }
00959 impl->_install_only = parsed.installOnly;
00960
00961
00962 impl->_patch_rpms = std::list<YUMPackageImpl::PatchRpm>();
00963 for ( std::list<YUMPatchRpm>::const_iterator it = parsed.patchRpms.begin();
00964 it != parsed.patchRpms.end(); ++it )
00965 {
00966 YUMPackageImpl::PatchRpm patch_rpm;
00967
00968 patch_rpm.location( source::OnMediaLocation()
00969 .medianr( str::strtonum<unsigned>( it->media ) )
00970 .filename( it->location )
00971 .checksum( CheckSum( it->checksumType, it->checksum ) )
00972 .downloadsize( str::strtonum<ByteCount::SizeType>( it->downloadsize ) ) );
00973
00974 for ( std::list<YUMPatchBaseVersion>::const_iterator bvit = it->baseVersions.begin();
00975 bvit != it->baseVersions.end(); ++bvit )
00976 {
00977 patch_rpm.baseversion( Edition( bvit->edition.ver,
00978 bvit->edition.rel,
00979 bvit->edition.epoch ) );
00980 }
00981
00982 patch_rpm.buildtime( str::strtonum<Date::ValueType>( it->buildtime ) );
00983
00984 impl->_patch_rpms.push_back( patch_rpm );
00985 }
00986
00987
00988 impl->_delta_rpms = std::list<YUMPackageImpl::DeltaRpm>();
00989 for ( std::list<YUMDeltaRpm>::const_iterator it = parsed.deltaRpms.begin();
00990 it != parsed.deltaRpms.end(); ++it )
00991 {
00992 YUMPackageImpl::DeltaRpm delta_rpm;
00993
00994 delta_rpm.location( source::OnMediaLocation()
00995 .medianr( str::strtonum<unsigned>( it->media ) )
00996 .filename( it->location )
00997 .checksum( CheckSum( it->checksumType, it->checksum ) )
00998 .downloadsize( str::strtonum<ByteCount::SizeType>( it->downloadsize ) ) );
00999
01000 const YUMDeltaBaseVersion & ybv( it->baseVersion );
01001 delta_rpm.baseversion( YUMPackageImpl::DeltaRpm::BaseVersion()
01002 .edition( Edition( ybv.edition.ver,
01003 ybv.edition.rel,
01004 ybv.edition.epoch ) )
01005 .buildtime( str::strtonum<Date::ValueType>( ybv.buildtime ) )
01006 .checksum( CheckSum::md5( ybv.md5sum ) )
01007 .sequenceinfo( ybv.sequence_info )
01008 );
01009
01010 delta_rpm.buildtime( str::strtonum<Date::ValueType>( it->buildtime ) );
01011
01012 impl->_delta_rpms.push_back( delta_rpm );
01013 }
01014 }
01015 return atom;
01016 }
01017 catch (const Exception & excpt_r)
01018 {
01019 ZYPP_CAUGHT(excpt_r);
01020 ZYPP_THROW(Exception("Cannot create augmented package object"));
01021 }
01022 return 0L;
01023 }
01024
01025 Selection::Ptr YUMSourceImpl::createGroup(
01026 Source_Ref source_r,
01027 const zypp::parser::yum::YUMGroupData & parsed
01028 )
01029 {
01030 try
01031 {
01032 ResImplTraits<YUMGroupImpl>::Ptr impl(new YUMGroupImpl(source_r, parsed));
01033
01034 NVRAD dataCollect( parsed.groupId,
01035 Edition::noedition,
01036 Arch_noarch,
01037 createGroupDependencies(parsed));
01038 Selection::Ptr group = detail::makeResolvableFromImpl(
01039 dataCollect, impl
01040 );
01041 return group;
01042 }
01043 catch (const Exception & excpt_r)
01044 {
01045 ZYPP_CAUGHT(excpt_r);
01046 ZYPP_THROW(Exception("Cannot create package group object"));
01047 }
01048 return 0L;
01049 }
01050
01051 Pattern::Ptr YUMSourceImpl::createPattern(
01052 Source_Ref source_r,
01053 const zypp::parser::yum::YUMPatternData & parsed
01054 )
01055 {
01056 try
01057 {
01058 ResImplTraits<YUMPatternImpl>::Ptr impl(new YUMPatternImpl(source_r, parsed));
01059
01060 Arch arch;
01061 if (!parsed.arch.empty())
01062 arch = Arch(parsed.arch);
01063
01064 NVRAD dataCollect( parsed.name,
01065 Edition( parsed.ver, parsed.rel, parsed.epoch ),
01066 arch,
01067 createDependencies(parsed, ResTraits<Pattern>::kind));
01068 Pattern::Ptr pattern = detail::makeResolvableFromImpl(
01069 dataCollect, impl
01070 );
01071 return pattern;
01072 }
01073 catch (const Exception & excpt_r)
01074 {
01075 ZYPP_CAUGHT(excpt_r);
01076 ZYPP_THROW(Exception("Cannot create installation pattern object"));
01077 }
01078 return 0L;
01079 }
01080
01081 Message::Ptr YUMSourceImpl::createMessage(
01082 Source_Ref source_r,
01083 const zypp::parser::yum::YUMPatchMessage & parsed,
01084 Patch::constPtr patch
01085 )
01086 {
01087 try
01088 {
01089 ResImplTraits<YUMMessageImpl>::Ptr impl(new YUMMessageImpl(source_r, parsed, patch));
01090 Arch arch;
01091 if (!parsed.arch.empty())
01092 arch = Arch(parsed.arch);
01093
01094 NVRAD dataCollect( parsed.name,
01095 Edition( parsed.ver, parsed.rel, parsed.epoch ),
01096 arch,
01097 createDependencies(parsed,
01098 ResTraits<Message>::kind)
01099 );
01100 Message::Ptr message = detail::makeResolvableFromImpl(
01101 dataCollect, impl
01102 );
01103 return message;
01104 }
01105 catch (const Exception & excpt_r)
01106 {
01107 ZYPP_CAUGHT(excpt_r);
01108 ZYPP_THROW(Exception("Cannot create message object"));
01109 }
01110 return 0L;
01111 }
01112
01113 Script::Ptr YUMSourceImpl::createScript(
01114 Source_Ref source_r,
01115 const zypp::parser::yum::YUMPatchScript & parsed
01116 )
01117 {
01118 try
01119 {
01120 ResImplTraits<YUMScriptImpl>::Ptr impl(new YUMScriptImpl(source_r, parsed));
01121 Arch arch;
01122 if (!parsed.arch.empty())
01123 arch = Arch(parsed.arch);
01124
01125 NVRAD dataCollect( parsed.name,
01126 Edition( parsed.ver, parsed.rel, parsed.epoch ),
01127 arch,
01128 createDependencies(parsed,
01129 ResTraits<Script>::kind)
01130 );
01131 Script::Ptr script = detail::makeResolvableFromImpl(
01132 dataCollect, impl
01133 );
01134 return script;
01135 }
01136 catch (const Exception & excpt_r)
01137 {
01138 ZYPP_CAUGHT(excpt_r);
01139 ZYPP_THROW(Exception("Cannot create script object"));
01140 }
01141 return 0L;
01142 }
01143
01144 Product::Ptr YUMSourceImpl::createProduct(
01145 Source_Ref source_r,
01146 const zypp::parser::yum::YUMProductData & parsed
01147 )
01148 {
01149 try
01150 {
01151 ResImplTraits<YUMProductImpl>::Ptr impl(new YUMProductImpl(source_r, parsed));
01152
01153
01154 Arch arch;
01155 if (!parsed.arch.empty())
01156 arch = Arch(parsed.arch);
01157
01158 string name(parsed.name);
01159 std::replace(name.begin(), name.end(), ' ', '_');
01160
01161 NVRAD dataCollect( name,
01162 Edition( parsed.ver, parsed.rel, parsed.epoch ),
01163 arch,
01164 createDependencies(parsed,
01165 ResTraits<Product>::kind)
01166 );
01167 Product::Ptr product = detail::makeResolvableFromImpl(
01168 dataCollect, impl
01169 );
01170 return product;
01171 }
01172 catch (const Exception & excpt_r)
01173 {
01174 ZYPP_CAUGHT(excpt_r);
01175 ZYPP_THROW(Exception("Cannot create product object"));
01176 }
01177 return 0L;
01178 }
01179
01180 Patch::Ptr YUMSourceImpl::createPatch(
01181 Source_Ref source_r,
01182 const zypp::parser::yum::YUMPatchData & parsed
01183 )
01184 {
01185 try
01186 {
01187 ResImplTraits<YUMPatchImpl>::Ptr impl(new YUMPatchImpl(source_r, parsed, *this));
01188
01189 Arch arch;
01190 if (!parsed.arch.empty())
01191 arch = Arch(parsed.arch);
01192
01193
01194 NVRAD dataCollect( parsed.name,
01195 Edition( parsed.ver, parsed.rel, parsed.epoch ),
01196 arch,
01197 createDependencies( parsed,
01198 ResTraits<Patch>::kind)
01199 );
01200 Patch::Ptr patch = detail::makeResolvableFromImpl(
01201 dataCollect, impl
01202 );
01203
01204 CapFactory _f;
01205 Capability cap( _f.parse(
01206 Patch::TraitsType::kind,
01207 parsed.name,
01208 Rel::EQ,
01209 Edition(parsed.ver, parsed.rel, parsed.epoch)
01210 ));
01211
01212
01213 typedef std::map<std::string, shared_ptr<YUMPatchPackage> > PkgAtomsMap;
01214 PkgAtomsMap pkg_atoms;
01215
01216 for (std::list<shared_ptr<YUMPatchAtom> >::const_iterator it
01217 = parsed.atoms.begin();
01218 it != parsed.atoms.end();
01219 it++)
01220 {
01221 switch ((*it)->atomType())
01222 {
01223
01224
01225
01226
01227
01228 case YUMPatchAtom::Package:
01229 {
01230 shared_ptr<YUMPatchPackage> package_data
01231 = dynamic_pointer_cast<YUMPatchPackage>(*it);
01232 string atomkey( package_data->name + "-" + package_data->epoch + ":" + package_data->ver + "-" + package_data->rel );
01233
01234
01235 PkgAtomsMap::iterator pa_pos = pkg_atoms.find( atomkey );
01236 if (pa_pos != pkg_atoms.end())
01237 {
01238 try
01239 {
01240 Arch oldarch, newarch;
01241 if (!(pa_pos->second->arch.empty())) oldarch = Arch( pa_pos->second->arch );
01242 if (!(package_data->arch.empty())) newarch = Arch( package_data->arch );
01243 if (newarch.compatibleWith( getZYpp()->architecture() ) )
01244 {
01245
01246 if (!oldarch.compatibleWith( getZYpp()->architecture() )
01247 || oldarch.compare( newarch ) < 0)
01248 {
01249 pa_pos->second = package_data;
01250 }
01251 }
01252 }
01253 catch ( const Exception & excpt_r )
01254 {
01255 ZYPP_CAUGHT( excpt_r );
01256 ERR << "Package " << package_data->name << " in patch's atomlist has bad architecture '" << package_data->arch << "'" << endl;
01257 }
01258 }
01259 else
01260 {
01261 pkg_atoms[atomkey] = package_data;
01262 }
01263 break;
01264 }
01265 case YUMPatchAtom::Message:
01266 {
01267 shared_ptr<YUMPatchMessage> message_data
01268 = dynamic_pointer_cast<YUMPatchMessage>(*it);
01269 Message::Ptr message = createMessage(source_r, *message_data, patch);
01270 impl->_atoms.push_back(message);
01271 break;
01272 }
01273 case YUMPatchAtom::Script:
01274 {
01275 shared_ptr<YUMPatchScript> script_data
01276 = dynamic_pointer_cast<YUMPatchScript>(*it);
01277 Script::Ptr script = createScript(source_r, *script_data);
01278 impl->_atoms.push_back(script);
01279 break;
01280 }
01281 default:
01282 ERR << "Unknown type of atom" << endl;
01283 }
01284 #if 0 // atoms require their patch, why ?
01285 for (Patch::AtomList::iterator it = impl->_atoms.begin();
01286 it != impl->_atoms.end();
01287 it++)
01288 {
01289 (*it)->injectRequires(cap);
01290 }
01291 #endif
01292 }
01293
01294 for (PkgAtomsMap::const_iterator pa_pos = pkg_atoms.begin(); pa_pos != pkg_atoms.end(); ++pa_pos)
01295 {
01296 Atom::Ptr atom = augmentPackage( source_r, *(pa_pos->second) );
01297 impl->_atoms.push_back(atom);
01298 }
01299
01300 return patch;
01301 }
01302 catch (const Exception & excpt_r)
01303 {
01304 ZYPP_CAUGHT(excpt_r);
01305 ZYPP_THROW(Exception("Cannot create patch object"));
01306 }
01307 return 0L;
01308 }
01309
01310 Dependencies YUMSourceImpl::createDependencies(
01311 const zypp::parser::yum::YUMObjectData & parsed,
01312 const Resolvable::Kind my_kind
01313 )
01314 {
01315 Dependencies _deps;
01316 for (std::list<YUMDependency>::const_iterator it = parsed.provides.begin();
01317 it != parsed.provides.end();
01318 it++)
01319 {
01320 _deps[Dep::PROVIDES].insert(createCapability(*it, my_kind));
01321 }
01322
01323 for (std::list<YUMDependency>::const_iterator it = parsed.conflicts.begin();
01324 it != parsed.conflicts.end();
01325 it++)
01326 {
01327 _deps[Dep::CONFLICTS].insert(createCapability(*it, my_kind));
01328 }
01329
01330 for (std::list<YUMDependency>::const_iterator it = parsed.obsoletes.begin();
01331 it != parsed.obsoletes.end();
01332 it++)
01333 {
01334 _deps[Dep::OBSOLETES].insert(createCapability(*it, my_kind));
01335 }
01336
01337 for (std::list<YUMDependency>::const_iterator it = parsed.freshens.begin();
01338 it != parsed.freshens.end();
01339 it++)
01340 {
01341 _deps[Dep::FRESHENS].insert(createCapability(*it, my_kind));
01342 }
01343
01344 for (std::list<YUMDependency>::const_iterator it = parsed.recommends.begin();
01345 it != parsed.recommends.end();
01346 it++)
01347 {
01348 _deps[Dep::RECOMMENDS].insert(createCapability(*it, my_kind));
01349 }
01350
01351 for (std::list<YUMDependency>::const_iterator it = parsed.suggests.begin();
01352 it != parsed.suggests.end();
01353 it++)
01354 {
01355 _deps[Dep::SUGGESTS].insert(createCapability(*it, my_kind));
01356 }
01357
01358 for (std::list<YUMDependency>::const_iterator it = parsed.supplements.begin();
01359 it != parsed.supplements.end();
01360 it++)
01361 {
01362 _deps[Dep::SUPPLEMENTS].insert(createCapability(*it, my_kind));
01363 }
01364
01365 for (std::list<YUMDependency>::const_iterator it = parsed.enhances.begin();
01366 it != parsed.enhances.end();
01367 it++)
01368 {
01369 _deps[Dep::ENHANCES].insert(createCapability(*it, my_kind));
01370 }
01371
01372 for (std::list<YUMDependency>::const_iterator it = parsed.prerequires.begin();
01373 it != parsed.prerequires.end();
01374 it++)
01375 {
01376 _deps[Dep::PREREQUIRES].insert(createCapability(*it, my_kind));
01377 }
01378
01379 for (std::list<YUMDependency>::const_iterator it = parsed.requires.begin();
01380 it != parsed.requires.end();
01381 it++)
01382 {
01383 if (it->pre == "1")
01384 _deps[Dep::PREREQUIRES].insert(createCapability(*it, my_kind));
01385 else
01386 _deps[Dep::REQUIRES].insert(createCapability(*it, my_kind));
01387 }
01388
01389 return _deps;
01390 }
01391
01392 Dependencies YUMSourceImpl::createGroupDependencies(
01393 const zypp::parser::yum::YUMGroupData & parsed
01394 )
01395 {
01396 Dependencies _deps;
01397
01398 for (std::list<PackageReq>::const_iterator it = parsed.packageList.begin();
01399 it != parsed.packageList.end();
01400 it++)
01401 {
01402 Dep _dep_kind = Dep::REQUIRES;
01403 if (it->type == "mandatory" || it->type == "")
01404 {
01405 _dep_kind = Dep::REQUIRES;
01406 }
01407 else if (it->type == "default")
01408 {
01409 _dep_kind = Dep::RECOMMENDS;
01410 }
01411 else if (it->type == "optional")
01412 {
01413 _dep_kind = Dep::SUGGESTS;
01414 }
01415 _deps[_dep_kind].insert(createCapability(YUMDependency(
01416 "",
01417 it->name,
01418 "EQ",
01419 it->epoch,
01420 it->ver,
01421 it->rel,
01422 ""
01423 ),
01424 ResTraits<Package>::kind));
01425 }
01426 for (std::list<MetaPkg>::const_iterator it = parsed.grouplist.begin();
01427 it != parsed.grouplist.end();
01428 it++)
01429 {
01430 Dep _dep_kind = Dep::REQUIRES;
01431 if (it->type == "mandatory" || it->type == "")
01432 {
01433 _dep_kind = Dep::REQUIRES;
01434 }
01435 else if (it->type == "default")
01436 {
01437 _dep_kind = Dep::RECOMMENDS;
01438 }
01439 else if (it->type == "optional")
01440 {
01441 _dep_kind = Dep::SUGGESTS;
01442 }
01443 _deps[_dep_kind].insert(createCapability(YUMDependency(
01444 "",
01445 it->name,
01446 "",
01447 "",
01448 "",
01449 "",
01450 ""
01451 ),
01452 ResTraits<Selection>::kind));
01453 }
01454 return _deps;
01455 }
01456
01457 Capability YUMSourceImpl::createCapability(const YUMDependency & dep,
01458 const Resolvable::Kind & my_kind)
01459 {
01460 CapFactory _f;
01461 Resolvable::Kind _kind = dep.kind == "" ? my_kind : Resolvable::Kind(dep.kind);
01462 Capability cap;
01463 if ( ! dep.isEncoded() )
01464 {
01465 cap = _f.parse(
01466 _kind,
01467 dep.name,
01468 Rel(dep.flags),
01469 Edition(dep.ver, dep.rel, dep.epoch)
01470 );
01471 }
01472 else
01473 {
01474 cap = _f.parse( _kind, dep.encoded );
01475 }
01476 return cap;
01477 }
01478
01479 }
01481 }
01484 }