Imported Upstream version 17.16.0
[platform/upstream/libzypp.git] / zypp / sat / Pool.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/sat/Pool.cc
10  *
11 */
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15
16 extern "C"
17 {
18 #include <solv/pool.h>
19 #include <solv/repo.h>
20 #include <solv/solvable.h>
21 }
22
23 #include <iostream>
24 #include <fstream>
25
26 #include "zypp/base/Easy.h"
27 #include "zypp/base/Logger.h"
28 #include "zypp/base/Gettext.h"
29 #include "zypp/base/Exception.h"
30
31 #include "zypp/AutoDispose.h"
32
33 #include "zypp/sat/detail/PoolImpl.h"
34 #include "zypp/sat/Pool.h"
35 #include "zypp/sat/LookupAttr.h"
36
37 using std::endl;
38
39 ///////////////////////////////////////////////////////////////////
40 namespace zypp
41 { /////////////////////////////////////////////////////////////////
42   ///////////////////////////////////////////////////////////////////
43   namespace sat
44   { /////////////////////////////////////////////////////////////////
45
46     const std::string & Pool::systemRepoAlias()
47     { return detail::PoolImpl::systemRepoAlias(); }
48
49     detail::CPool * Pool::get() const
50     { return myPool().getPool(); }
51
52     Pool::size_type Pool::capacity() const
53     { return myPool()->nsolvables; }
54
55     const SerialNumber & Pool::serial() const
56     { return myPool().serial(); }
57
58     const SerialNumber & Pool::serialIDs() const
59     { return myPool().serialIDs(); }
60
61     void Pool::prepare() const
62     { return myPool().prepare(); }
63
64     Pathname Pool::rootDir() const
65     { return myPool().rootDir(); }
66
67     void Pool::rootDir( const Pathname & root_r )
68     { return myPool().rootDir( root_r ); }
69
70     bool Pool::reposEmpty() const
71     { return ! myPool()->urepos; }
72
73     Pool::size_type Pool::reposSize() const
74     { return myPool()->urepos; }
75
76     Pool::RepositoryIterator Pool::reposBegin() const
77     {
78       if ( myPool()->urepos )
79       { // repos[0] == NULL
80         for_( it, myPool()->repos+1, myPool()->repos+myPool()->nrepos )
81           if ( *it )
82             return RepositoryIterator( it );
83       }
84       return reposEnd();
85     }
86
87     Pool::RepositoryIterator Pool::reposEnd() const
88     { return RepositoryIterator( myPool()->repos+myPool()->nrepos ); }
89
90     bool Pool::solvablesEmpty() const
91     {
92       // return myPool()->nsolvables;
93       // nsolvables is the array size including
94       // invalid Solvables.
95       for_( it, reposBegin(), reposEnd() )
96       {
97         if ( ! it->solvablesEmpty() )
98           return false;
99       }
100       return true;
101     }
102
103     Pool::size_type Pool::solvablesSize() const
104     {
105       // Do not return myPool()->nsolvables;
106       // nsolvables is the array size including
107       // invalid Solvables.
108       size_type ret = 0;
109       for_( it, reposBegin(), reposEnd() )
110       {
111         ret += it->solvablesSize();
112       }
113       return ret;
114     }
115
116     Pool::SolvableIterator Pool::solvablesBegin() const
117     { return SolvableIterator( myPool().getFirstId() ); }
118
119     Pool::SolvableIterator Pool::solvablesEnd() const
120     { return SolvableIterator(); }
121
122     sat::Queue Pool::whatMatchesDep( const SolvAttr &attr, const Capability &cap ) const
123     {
124       sat::Queue q;
125       pool_whatmatchesdep( get(), attr.id(), cap.id(), q, 0);
126       return q;
127     }
128
129     Queue Pool::whatMatchesSolvable( const SolvAttr &attr, const Solvable &solv ) const
130     {
131       sat::Queue q;
132       pool_whatmatchessolvable( get(), attr.id(), static_cast<Id>( solv.id() ), q, 0 );
133       return q;
134     }
135
136     Queue Pool::whatContainsDep( const SolvAttr &attr, const Capability &cap ) const
137     {
138       sat::Queue q;
139       pool_whatcontainsdep( get(), attr.id(), cap.id(), q, 0 );
140       return q;
141     }
142
143     Repository Pool::reposInsert( const std::string & alias_r )
144     {
145       Repository ret( reposFind( alias_r ) );
146       if ( ret )
147         return ret;
148
149       ret = Repository( myPool()._createRepo( alias_r ) );
150       if ( ret.isSystemRepo() )
151       {
152         // autoprovide (dummy) RepoInfo
153         RepoInfo info;
154         info.setAlias( alias_r );
155         info.setName( alias_r );
156         info.setAutorefresh( true );
157         info.setEnabled( true );
158         ret.setInfo( info );
159       }
160       return ret;
161     }
162
163     Repository Pool::reposFind( const std::string & alias_r ) const
164     {
165       for_( it, reposBegin(), reposEnd() )
166       {
167         if ( alias_r == it->alias() )
168           return *it;
169       }
170       return Repository();
171     }
172
173     Repository Pool::findSystemRepo() const
174     {
175       return Repository( myPool().systemRepo() );
176     }
177
178     Repository Pool::systemRepo()
179     {
180       if ( myPool().systemRepo() )
181         return Repository( myPool().systemRepo() );
182       return reposInsert( systemRepoAlias() );
183     }
184
185     Repository Pool::addRepoSolv( const Pathname & file_r, const std::string & alias_r )
186     {
187       // Using a temporay repo! (The additional parenthesis are required.)
188       AutoDispose<Repository> tmprepo( (Repository::EraseFromPool()) );
189       *tmprepo = reposInsert( alias_r );
190       tmprepo->addSolv( file_r );
191
192       // no exceptions so we keep it:
193       tmprepo.resetDispose();
194       return tmprepo;
195     }
196
197     Repository Pool::addRepoSolv( const Pathname & file_r )
198     { return addRepoSolv( file_r, file_r.basename() ); }
199
200     Repository Pool::addRepoSolv( const Pathname & file_r, const RepoInfo & info_r )
201     {
202       Repository ret( addRepoSolv( file_r, info_r.alias() ) );
203       ret.setInfo( info_r );
204       return ret;
205     }
206
207     /////////////////////////////////////////////////////////////////
208
209     Repository Pool::addRepoHelix( const Pathname & file_r, const std::string & alias_r )
210     {
211       // Using a temporay repo! (The additional parenthesis are required.)
212       AutoDispose<Repository> tmprepo( (Repository::EraseFromPool()) );
213       *tmprepo = reposInsert( alias_r );
214       tmprepo->addHelix( file_r );
215
216       // no exceptions so we keep it:
217       tmprepo.resetDispose();
218       return tmprepo;
219     }
220
221     Repository Pool::addRepoHelix( const Pathname & file_r )
222     { return addRepoHelix( file_r, file_r.basename() ); }
223
224     Repository Pool::addRepoHelix( const Pathname & file_r, const RepoInfo & info_r )
225     {
226       Repository ret( addRepoHelix( file_r, info_r.alias() ) );
227       ret.setInfo( info_r );
228       return ret;
229     }
230
231    /////////////////////////////////////////////////////////////////
232
233     void Pool::setTextLocale( const Locale & locale_r )
234     { myPool().setTextLocale( locale_r ); }
235
236     void Pool::setRequestedLocales( const LocaleSet & locales_r )
237     { myPool().setRequestedLocales( locales_r ); }
238
239     bool Pool::addRequestedLocale( const Locale & locale_r )
240     { return myPool().addRequestedLocale( locale_r ); }
241
242     bool Pool::eraseRequestedLocale( const Locale & locale_r )
243     { return myPool().eraseRequestedLocale( locale_r ); }
244
245     const LocaleSet & Pool::getRequestedLocales() const
246     { return myPool().getRequestedLocales(); }
247
248     bool Pool::isRequestedLocale( const Locale & locale_r ) const
249     { return myPool().isRequestedLocale( locale_r ); }
250
251     void Pool::initRequestedLocales( const LocaleSet & locales_r )      { myPool().initRequestedLocales( locales_r ); }
252     const LocaleSet & Pool::getAddedRequestedLocales() const            { return myPool().getAddedRequestedLocales(); }
253     const LocaleSet & Pool::getRemovedRequestedLocales() const          { return myPool().getRemovedRequestedLocales(); }
254
255     const LocaleSet & Pool::getAvailableLocales() const
256     {  return myPool().getAvailableLocales(); }
257
258     bool Pool::isAvailableLocale( const Locale & locale_r ) const
259     { return myPool().isAvailableLocale( locale_r ); }
260
261     const  Pool::MultiversionList &  Pool::multiversion() const
262     { return myPool().multiversionList(); }
263
264     Queue Pool::autoInstalled() const                           { return myPool().autoInstalled(); }
265     void Pool::setAutoInstalled( const Queue & autoInstalled_r ){ myPool().setAutoInstalled( autoInstalled_r ); }
266
267     void Pool::setNeedrebootSpec( sat::SolvableSpec needrebootSpec_r )  { myPool().setNeedrebootSpec( std::move(needrebootSpec_r) ); }
268
269    /******************************************************************
270     **
271     **  FUNCTION NAME : operator<<
272     **  FUNCTION TYPE : std::ostream &
273     */
274     std::ostream & operator<<( std::ostream & str, const Pool & obj )
275     {
276       return str << "sat::pool(" << obj.serial() << ")["
277           << obj.capacity() << "]{"
278           << obj.reposSize() << "repos|"
279           << obj.solvablesSize() << "solv}";
280     }
281
282     /////////////////////////////////////////////////////////////////
283     #undef ZYPP_BASE_LOGGER_LOGGROUP
284     #define ZYPP_BASE_LOGGER_LOGGROUP "solvidx"
285
286     void updateSolvFileIndex( const Pathname & solvfile_r )
287     {
288       AutoDispose<FILE*> solv( ::fopen( solvfile_r.c_str(), "re" ), ::fclose );
289       if ( solv == NULL )
290       {
291         solv.resetDispose();
292         ERR << "Can't open solv-file: " << solv << endl;
293         return;
294       }
295
296       std::string solvidxfile( solvfile_r.extend(".idx").asString() );
297       if ( ::unlink( solvidxfile.c_str() ) == -1 && errno != ENOENT )
298       {
299         ERR << "Can't unlink solv-idx: " << Errno() << endl;
300         return;
301       }
302       {
303         int fd = ::open( solvidxfile.c_str(), O_CREAT|O_EXCL|O_WRONLY|O_TRUNC, 0644 );
304         if ( fd == -1 )
305         {
306           ERR << "Can't create solv-idx: " << Errno() << endl;
307           return;
308         }
309         ::close( fd );
310       }
311       std::ofstream idx( solvidxfile.c_str() );
312
313
314       detail::CPool * _pool = ::pool_create();
315       detail::CRepo * _repo = ::repo_create( _pool, "" );
316       if ( ::repo_add_solv( _repo, solv, 0 ) == 0 )
317       {
318         int _id = 0;
319         detail::CSolvable * _solv = nullptr;
320         FOR_REPO_SOLVABLES( _repo, _id, _solv )
321         {
322           if ( _solv )
323           {
324 #define SEP '\t'
325 #define idstr(V) pool_id2str( _pool, _solv->V )
326             if ( _solv->arch == ARCH_SRC || _solv->arch == ARCH_NOSRC )
327               idx << "srcpackage:" << idstr(name) << SEP << idstr(evr) << SEP << "noarch" << endl;
328             else
329               idx << idstr(name) << SEP << idstr(evr) << SEP << idstr(arch) << endl;
330           }
331         }
332       }
333       else
334       {
335         ERR << "Can't read solv-file: " << ::pool_errstr( _pool ) << endl;
336       }
337       ::repo_free( _repo, 0 );
338       ::pool_free( _pool );
339     }
340
341     /////////////////////////////////////////////////////////////////
342   } // namespace sat
343   ///////////////////////////////////////////////////////////////////
344   /////////////////////////////////////////////////////////////////
345 } // namespace zypp
346 ///////////////////////////////////////////////////////////////////