Patch.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 
00014 #include "zypp/base/LogTools.h"
00015 #include "zypp/Patch.h"
00016 #include "zypp/sat/WhatProvides.h"
00017 
00018 using std::endl;
00019 
00021 namespace zypp
00022 { 
00023 
00024   IMPL_PTR_TYPE( Patch );
00025 
00027   //
00028   //    METHOD NAME : Patch::Patch
00029   //    METHOD TYPE : Ctor
00030   //
00031   Patch::Patch( const sat::Solvable & solvable_r )
00032   : ResObject( solvable_r )
00033   {}
00034 
00036   //
00037   //    METHOD NAME : Patch::~Patch
00038   //    METHOD TYPE : Dtor
00039   //
00040   Patch::~Patch()
00041   {}
00042 
00044   //
00045   //    Patch interface forwarded to implementation
00046   //
00048 
00049   Patch::Category Patch::categoryEnum() const
00050   {
00051     std::string cat( category() );
00052     switch ( cat[0] )
00053     {
00054       //        CAT_YAST
00055       case 'y':
00056       case 'Y':
00057         if ( str::compareCI( cat, "yast" ) == 0 )
00058           return CAT_YAST;
00059         break;
00060 
00061       //        CAT_SECURITY
00062       case 's':
00063       case 'S':
00064         if ( str::compareCI( cat, "security" ) == 0 )
00065           return CAT_SECURITY;
00066         break;
00067 
00068       //        CAT_RECOMMENDED
00069       case 'r':
00070       case 'R':
00071         if ( str::compareCI( cat, "recommended" ) == 0 )
00072           return CAT_RECOMMENDED;
00073         break;
00074       case 'b':
00075       case 'B':
00076         if ( str::compareCI( cat, "bugfix" ) == 0 )     // rhn
00077           return CAT_RECOMMENDED;
00078         break;
00079 
00080       //        CAT_OPTIONAL
00081       case 'o':
00082       case 'O':
00083         if ( str::compareCI( cat, "optional" ) == 0 )
00084           return CAT_OPTIONAL;
00085         break;
00086       case 'f':
00087       case 'F':
00088         if ( str::compareCI( cat, "feature" ) == 0 )
00089           return CAT_OPTIONAL;
00090         break;
00091       case 'e':
00092       case 'E':
00093         if ( str::compareCI( cat, "enhancement" ) == 0 )        // rhn
00094           return CAT_OPTIONAL;
00095         break;
00096 
00097       //        CAT_DOCUMENT
00098       case 'd':
00099       case 'D':
00100         if ( str::compareCI( cat, "document" ) == 0 )
00101           return CAT_DOCUMENT;
00102         break;
00103     }
00104     // default:
00105     return CAT_OTHER;
00106   }
00107 
00108   std::string Patch::message( const Locale & lang_r ) const
00109   { return lookupStrAttribute( sat::SolvAttr::message, lang_r ); }
00110 
00111   std::string Patch::category() const
00112   { return lookupStrAttribute( sat::SolvAttr::patchcategory ); }
00113 
00114   bool Patch::rebootSuggested() const
00115   { return lookupBoolAttribute( sat::SolvAttr::rebootSuggested ); }
00116 
00117   bool Patch::restartSuggested() const
00118   { return lookupBoolAttribute( sat::SolvAttr::restartSuggested ); }
00119 
00120   bool Patch::reloginSuggested() const
00121   { return lookupBoolAttribute( sat::SolvAttr::reloginSuggested ); }
00122 
00123 
00124   bool Patch::interactive() const
00125   {
00126     if ( rebootSuggested()
00127          || ! message().empty()
00128          || ! licenseToConfirm().empty() )
00129     {
00130       return true;
00131     }
00132 
00133     Patch::Contents c( contents() );
00134     for_( it, c.begin(), c.end() )
00135     {
00136       if ( ! licenseToConfirm().empty() )
00137       {
00138         return true;
00139       }
00140     }
00141 
00142     return false;
00143   }
00144 
00145   Patch::Contents Patch::contents() const
00146   {
00147     Contents result;
00148     // DBG << *this << endl;
00149     sat::LookupAttr updateCollection( sat::SolvAttr::updateCollection, satSolvable() );
00150     for_( entry, updateCollection.begin(), updateCollection.end() )
00151     {
00152       IdString name    ( entry.subFind( sat::SolvAttr::updateCollectionName ).idStr() );
00153       Edition  edition ( entry.subFind( sat::SolvAttr::updateCollectionEvr ).idStr() );
00154       Arch     arch    ( entry.subFind( sat::SolvAttr::updateCollectionArch ).idStr() );
00155       if ( name.empty() )
00156       {
00157         WAR << "Ignore malformed updateCollection entry: " << name << "-" << edition << "." << arch << endl;
00158         continue;
00159       }
00160 
00161       // The entry is relevant if there is an installed
00162       // package with the same name and arch.
00163       bool relevant = false;
00164       sat::WhatProvides providers( (Capability( name.id() )) );
00165       for_( it, providers.begin(), providers.end() )
00166       {
00167         if ( it->isSystem() && it->ident() == name && it->arch() == arch )
00168         {
00169           relevant = true;
00170           break;
00171         }
00172       }
00173       if ( ! relevant )
00174       {
00175         // DBG << "Not relevant: " << name << "-" << edition << "." << arch << endl;
00176         continue;
00177       }
00178 
00179       /* find exact providers first (this matches the _real_ 'collection content' of the patch */
00180       providers = sat::WhatProvides( Capability( arch, name.c_str(), Rel::EQ, edition, ResKind::package ) );
00181       if ( providers.empty() )
00182       {
00183         /* no exact providers: find 'best' providers: those with a larger evr */
00184         providers = sat::WhatProvides( Capability( arch, name.c_str(), Rel::GT, edition, ResKind::package ) );
00185         if ( providers.empty() )
00186         {
00187           // Hmm, this patch is not installable, no one is providing the package in the collection
00188           // FIXME: raise execption ? fake a solvable ?
00189           WAR << "Missing provider: " << name << "-" << edition << "." << arch << endl;
00190           continue;
00191         }
00192       }
00193 
00194       // FIXME ?! loop over providers and try to find installed ones ?
00195       // DBG << "Found " << name << "-" << edition << "." << arch << ": " << *(providers.begin()) << endl;
00196       result.get().insert( *(providers.begin()) );
00197     }
00198 
00199     return result;
00200   }
00201 
00203   //
00204   //    CLASS NAME : Patch::ReferenceIterator
00205   //
00207 
00208   Patch::ReferenceIterator::ReferenceIterator( const sat::Solvable & val_r )
00209   { base_reference() = sat::LookupAttr( sat::SolvAttr::updateReference, val_r ).begin(); }
00210 
00211   std::string Patch::ReferenceIterator::id() const
00212   { return base_reference().subFind( sat::SolvAttr::updateReferenceId ).asString(); }
00213   std::string Patch::ReferenceIterator::href() const
00214   { return base_reference().subFind( sat::SolvAttr::updateReferenceHref ).asString(); }
00215   std::string Patch::ReferenceIterator::title() const
00216   { return base_reference().subFind( sat::SolvAttr::updateReferenceTitle ).asString(); }
00217   std::string Patch::ReferenceIterator::type() const
00218   { return base_reference().subFind( sat::SolvAttr::updateReferenceType ).asString(); }
00219 
00221 } // namespace zypp

doxygen