Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / Patch.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/Patch.cc
10  *
11 */
12 #include <iostream>
13
14 #include "zypp/base/LogTools.h"
15 #include "zypp/base/String.h"
16 #include "zypp/Patch.h"
17 #include "zypp/sat/WhatProvides.h"
18
19 using std::endl;
20
21 ///////////////////////////////////////////////////////////////////
22 namespace zypp
23 { /////////////////////////////////////////////////////////////////
24
25   IMPL_PTR_TYPE( Patch );
26
27   ///////////////////////////////////////////////////////////////////
28   //
29   //    METHOD NAME : Patch::Patch
30   //    METHOD TYPE : Ctor
31   //
32   Patch::Patch( const sat::Solvable & solvable_r )
33   : ResObject( solvable_r )
34   {}
35
36   ///////////////////////////////////////////////////////////////////
37   //
38   //    METHOD NAME : Patch::~Patch
39   //    METHOD TYPE : Dtor
40   //
41   Patch::~Patch()
42   {}
43
44   ///////////////////////////////////////////////////////////////////
45
46   std::string Patch::category() const
47   { return lookupStrAttribute( sat::SolvAttr::patchcategory ); }
48
49   Patch::Category Patch::categoryEnum() const
50   { return categoryEnum( category() ); }
51
52   bool Patch::isCategory( const std::string & category_r ) const
53   { return( str::compareCI( category_r, category() ) == 0 ); }
54
55   Patch::Category Patch::categoryEnum( const std::string & category_r )
56   {
57     switch ( category_r[0] )
58     {
59       //        CAT_YAST
60       case 'y':
61       case 'Y':
62         if ( str::compareCI( category_r, "yast" ) == 0 )
63           return CAT_YAST;
64         break;
65
66       //        CAT_SECURITY
67       case 's':
68       case 'S':
69         if ( str::compareCI( category_r, "security" ) == 0 )
70           return CAT_SECURITY;
71         break;
72
73       //        CAT_RECOMMENDED
74       case 'r':
75       case 'R':
76         if ( str::compareCI( category_r, "recommended" ) == 0 )
77           return CAT_RECOMMENDED;
78         break;
79       case 'b':
80       case 'B':
81         if ( str::compareCI( category_r, "bugfix" ) == 0 )      // rhn
82           return CAT_RECOMMENDED;
83         break;
84
85       //        CAT_OPTIONAL
86       case 'o':
87       case 'O':
88         if ( str::compareCI( category_r, "optional" ) == 0 )
89           return CAT_OPTIONAL;
90         break;
91       case 'f':
92       case 'F':
93         if ( str::compareCI( category_r, "feature" ) == 0 )
94           return CAT_OPTIONAL;
95         break;
96       case 'e':
97       case 'E':
98         if ( str::compareCI( category_r, "enhancement" ) == 0 ) // rhn
99           return CAT_OPTIONAL;
100         break;
101
102       //        CAT_DOCUMENT
103       case 'd':
104       case 'D':
105         if ( str::compareCI( category_r, "document" ) == 0 )
106           return CAT_DOCUMENT;
107         break;
108     }
109     // default:
110     return CAT_OTHER;
111   }
112
113   ///////////////////////////////////////////////////////////////////
114
115   std::string Patch::severity() const
116   { return lookupStrAttribute( sat::SolvAttr::severity ); }
117
118   Patch::SeverityFlag Patch::severityFlag() const
119   { return severityFlag( severity() ); }
120
121   bool Patch::isSeverity( const std::string & severity_r ) const
122   { return( str::compareCI( severity_r, severity() ) == 0 ); }
123
124   Patch::SeverityFlag Patch::severityFlag( const std::string & severity_r )
125   {
126     switch ( severity_r[0] )
127     {
128       case 'l':
129       case 'L':
130         if ( str::compareCI( severity_r, "low" ) == 0 )
131           return SEV_LOW;
132         break;
133
134       case 'm':
135       case 'M':
136         if ( str::compareCI( severity_r, "moderate" ) == 0 )
137           return SEV_MODERATE;
138         break;
139
140       case 'i':
141       case 'I':
142         if ( str::compareCI( severity_r, "important" ) == 0 )
143           return SEV_IMPORTANT;
144         break;
145
146       case 'c':
147       case 'C':
148         if ( str::compareCI( severity_r, "critical" ) == 0 )
149           return SEV_CRITICAL;
150         break;
151
152       case 'u':
153       case 'U':
154         if ( str::compareCI( severity_r, "unspecified" ) == 0 )
155           return SEV_NONE;
156         break;
157
158       case '\0':
159         return SEV_NONE;
160         break;
161     }
162     // default:
163     return SEV_OTHER;
164   }
165
166   std::string asString( const Patch::SeverityFlag & obj )
167   {
168     switch ( obj )
169     {
170       case Patch::SEV_NONE:     return std::string( "unspecified" );    break;
171       case Patch::SEV_OTHER:    return std::string( "unknown" );        break;
172       case Patch::SEV_LOW:      return std::string( "low" );            break;
173       case Patch::SEV_MODERATE: return std::string( "moderate" );       break;
174       case Patch::SEV_IMPORTANT:return std::string( "important" );      break;
175       case Patch::SEV_CRITICAL: return std::string( "critical" );       break;
176     }
177     // make gcc happy:
178     return std::string( "unknown" );
179   }
180
181   ///////////////////////////////////////////////////////////////////
182
183   std::string Patch::message( const Locale & lang_r ) const
184   { return lookupStrAttribute( sat::SolvAttr::message, lang_r ); }
185
186   bool Patch::rebootSuggested() const
187   { return lookupBoolAttribute( sat::SolvAttr::rebootSuggested ); }
188
189   bool Patch::restartSuggested() const
190   { return lookupBoolAttribute( sat::SolvAttr::restartSuggested ); }
191
192   bool Patch::reloginSuggested() const
193   { return lookupBoolAttribute( sat::SolvAttr::reloginSuggested ); }
194
195   Patch::InteractiveFlags Patch::interactiveFlags() const
196   {
197     InteractiveFlags patchFlags (NoFlags);
198     if ( rebootSuggested() )
199       patchFlags |= Reboot;
200
201     if ( ! message().empty() )
202       patchFlags |= Message;
203
204     if ( ! licenseToConfirm().empty() )
205       patchFlags |= License;
206
207     Patch::Contents c( contents() );
208     for_( it, c.begin(), c.end() )
209     {
210       if ( ! makeResObject(*it)->licenseToConfirm().empty() )
211       {
212         patchFlags |= License;
213         break;
214       }
215     }
216     return patchFlags;
217   }
218
219   bool Patch::interactiveWhenIgnoring( InteractiveFlags flags_r ) const
220   {
221     if ( interactiveFlags() & ( ~flags_r ) )
222     {
223       return true;
224     }
225     else
226     {
227       return false;
228     }
229   }
230
231   bool Patch::interactive() const
232   {
233     return interactiveWhenIgnoring();
234   }
235
236   Patch::Contents Patch::contents() const
237   {
238     Contents result;
239     // DBG << *this << endl;
240     sat::LookupAttr updateCollection( sat::SolvAttr::updateCollection, satSolvable() );
241     for_( entry, updateCollection.begin(), updateCollection.end() )
242     {
243       IdString name    ( entry.subFind( sat::SolvAttr::updateCollectionName ).idStr() );
244       Edition  edition ( entry.subFind( sat::SolvAttr::updateCollectionEvr ).idStr() );
245       Arch     arch    ( entry.subFind( sat::SolvAttr::updateCollectionArch ).idStr() );
246       if ( name.empty() )
247       {
248         WAR << "Ignore malformed updateCollection entry: " << name << "-" << edition << "." << arch << endl;
249         continue;
250       }
251
252       // The entry is relevant if there is an installed
253       // package with the same name and arch.
254       bool relevant = false;
255       sat::WhatProvides providers( (Capability( name.id() )) );
256       for_( it, providers.begin(), providers.end() )
257       {
258         if ( it->isSystem() && it->ident() == name && it->arch() == arch )
259         {
260           relevant = true;
261           break;
262         }
263       }
264       if ( ! relevant )
265       {
266         // DBG << "Not relevant: " << name << "-" << edition << "." << arch << endl;
267         continue;
268       }
269
270       /* find exact providers first (this matches the _real_ 'collection content' of the patch */
271       providers = sat::WhatProvides( Capability( arch, name.c_str(), Rel::EQ, edition, ResKind::package ) );
272       if ( providers.empty() )
273       {
274         /* no exact providers: find 'best' providers: those with a larger evr */
275         providers = sat::WhatProvides( Capability( arch, name.c_str(), Rel::GT, edition, ResKind::package ) );
276         if ( providers.empty() )
277         {
278           // Hmm, this patch is not installable, no one is providing the package in the collection
279           // FIXME: raise execption ? fake a solvable ?
280           WAR << "Missing provider: " << name << "-" << edition << "." << arch << endl;
281           continue;
282         }
283       }
284
285       // FIXME ?! loop over providers and try to find installed ones ?
286       // DBG << "Found " << name << "-" << edition << "." << arch << ": " << *(providers.begin()) << endl;
287       result.get().insert( *(providers.begin()) );
288     }
289
290     return result;
291   }
292
293   ///////////////////////////////////////////////////////////////////
294   //
295   //    CLASS NAME : Patch::ReferenceIterator
296   //
297   ///////////////////////////////////////////////////////////////////
298
299   Patch::ReferenceIterator::ReferenceIterator( const sat::Solvable & val_r )
300   { base_reference() = sat::LookupAttr( sat::SolvAttr::updateReference, val_r ).begin(); }
301
302   std::string Patch::ReferenceIterator::id() const
303   { return base_reference().subFind( sat::SolvAttr::updateReferenceId ).asString(); }
304   std::string Patch::ReferenceIterator::href() const
305   { return base_reference().subFind( sat::SolvAttr::updateReferenceHref ).asString(); }
306   std::string Patch::ReferenceIterator::title() const
307   { return base_reference().subFind( sat::SolvAttr::updateReferenceTitle ).asString(); }
308   std::string Patch::ReferenceIterator::type() const
309   { return base_reference().subFind( sat::SolvAttr::updateReferenceType ).asString(); }
310
311   /////////////////////////////////////////////////////////////////
312 } // namespace zypp
313 ///////////////////////////////////////////////////////////////////