~thopiekar/zypper/libzypp-manual-import

1 by Thomas-Karl Pietrowski
first import
1
/*---------------------------------------------------------------------\
2
|                          ____ _   __ __ ___                          |
3
|                         |__  / \ / / . \ . \                         |
4
|                           / / \ V /|  _/  _/                         |
5
|                          / /__ | | | | | |                           |
6
|                         /_____||_| |_| |_|                           |
7
|                                                                      |
8
\---------------------------------------------------------------------*/
9
/** \file	zypp/sat/Repository.cc
10
 *
11
*/
12
#include <climits>
13
#include <iostream>
14
15
#include "zypp/base/Logger.h"
16
#include "zypp/base/Gettext.h"
17
#include "zypp/base/Exception.h"
18
#include "zypp/base/Xml.h"
19
20
#include "zypp/AutoDispose.h"
21
#include "zypp/Pathname.h"
22
23
#include "zypp/sat/detail/PoolImpl.h"
24
#include "zypp/Repository.h"
5 by Thomas-Karl Pietrowski
syncing again
25
#include "zypp/ResPool.h"
26
#include "zypp/Product.h"
1 by Thomas-Karl Pietrowski
first import
27
#include "zypp/sat/Pool.h"
28
29
using std::endl;
30
31
///////////////////////////////////////////////////////////////////
32
namespace zypp
33
{ /////////////////////////////////////////////////////////////////
34
35
    const Repository Repository::noRepository;
36
37
    const std::string & Repository::systemRepoAlias()
38
    { return sat::detail::PoolImpl::systemRepoAlias(); }
39
40
    /////////////////////////////////////////////////////////////////
41
42
    ::_Repo * Repository::get() const
43
    { return myPool().getRepo( _id ); }
44
45
#define NO_REPOSITORY_RETURN( VAL ) \
46
    ::_Repo * _repo( get() ); \
47
    if ( ! _repo ) return VAL
48
49
#define NO_REPOSITORY_THROW( VAL ) \
50
    ::_Repo * _repo( get() ); \
51
    if ( ! _repo ) ZYPP_THROW( VAL )
52
53
    bool Repository::isSystemRepo() const
54
    {
55
	NO_REPOSITORY_RETURN( false );
56
	return myPool().isSystemRepo( _repo );
57
    }
58
59
    std::string Repository::alias() const
60
    {
61
      NO_REPOSITORY_RETURN( std::string() );
62
      if ( ! _repo->name )
63
        return std::string();
64
      return _repo->name;
65
    }
66
67
    std::string Repository::name() const
68
    { return info().name(); }
69
2 by Thomas-Karl Pietrowski
syncing code with latest from github
70
    std::string Repository::label() const
71
    { return info().label(); }
72
1 by Thomas-Karl Pietrowski
first import
73
    int Repository::satInternalPriority() const
74
    {
75
      NO_REPOSITORY_RETURN( INT_MIN );
76
      return _repo->priority;
77
    }
78
79
    int Repository::satInternalSubPriority() const
80
    {
81
      NO_REPOSITORY_RETURN( INT_MIN );
82
      return _repo->subpriority;
83
    }
84
2 by Thomas-Karl Pietrowski
syncing code with latest from github
85
    Repository::ContentRevision Repository::contentRevision() const
86
    {
87
      NO_REPOSITORY_RETURN( ContentRevision() );
88
      sat::LookupRepoAttr q( sat::SolvAttr::repositoryRevision, *this );
89
      return q.empty() ? std::string() : q.begin().asString();
90
    }
91
92
    Repository::ContentIdentifier Repository::contentIdentifier() const
93
    {
94
      NO_REPOSITORY_RETURN( ContentIdentifier() );
95
      sat::LookupRepoAttr q( sat::SolvAttr::repositoryRepoid, *this );
96
      return q.empty() ? std::string() : q.begin().asString();
97
    }
98
99
    bool Repository::hasContentIdentifier( const ContentIdentifier & id_r ) const
100
    {
101
      NO_REPOSITORY_RETURN( false );
102
      sat::LookupRepoAttr q( sat::SolvAttr::repositoryRepoid, *this );
103
      for_( it, q.begin(), q.end() )
104
	if ( it.asString() == id_r )
105
	  return true;
106
      return false;
107
    }
1 by Thomas-Karl Pietrowski
first import
108
109
    zypp::Date Repository::generatedTimestamp() const
110
    {
111
      NO_REPOSITORY_RETURN( 0 );
112
      sat::LookupRepoAttr q( sat::SolvAttr::repositoryTimestamp, *this );
113
      return( q.empty() ? 0 : q.begin().asUnsigned() );
114
    }
115
116
    zypp::Date Repository::suggestedExpirationTimestamp() const
117
    {
118
      NO_REPOSITORY_RETURN( 0 );
119
      Date generated = generatedTimestamp();
120
      if ( ! generated )
121
        return 0; // do not calculate over a missing generated timestamp
122
123
      sat::LookupRepoAttr q( sat::SolvAttr::repositoryExpire, *this );
124
      if ( q.empty() )
125
        return 0;
126
2 by Thomas-Karl Pietrowski
syncing code with latest from github
127
      return generated + Date(q.begin().asUnsigned());
1 by Thomas-Karl Pietrowski
first import
128
    }
129
130
    Repository::Keywords Repository::keywords() const
131
    {
132
      NO_REPOSITORY_RETURN( Keywords() );
133
      return Keywords( sat::SolvAttr::repositoryKeywords, *this, sat::LookupAttr::REPO_ATTR );
134
    }
135
2 by Thomas-Karl Pietrowski
syncing code with latest from github
136
    bool Repository::hasKeyword( const std::string & val_r ) const
137
    {
138
      for ( const auto & val : keywords() )
139
	if ( val == val_r )
140
	  return true;
141
      return false;
142
    }
143
1 by Thomas-Karl Pietrowski
first import
144
    bool Repository::maybeOutdated() const
145
    {
146
      NO_REPOSITORY_RETURN( false );
147
      // system repo is not mirrored
148
      if ( isSystemRepo() )
149
        return false;
150
151
      Date suggested = suggestedExpirationTimestamp();
152
153
      // if no data, don't suggest
154
      if ( ! suggested )
155
        return false;
156
157
      return suggestedExpirationTimestamp() < Date::now();
158
    }
159
2 by Thomas-Karl Pietrowski
syncing code with latest from github
160
    bool Repository::providesUpdatesFor( const CpeId & cpeid_r ) const
1 by Thomas-Karl Pietrowski
first import
161
    {
162
      NO_REPOSITORY_RETURN( false );
5 by Thomas-Karl Pietrowski
syncing again
163
      if ( ! cpeid_r )
164
	return false;	// filter queries/products without CpeId, as an empty CpeId matches ANYthing.
165
166
      // check in repository metadata
2 by Thomas-Karl Pietrowski
syncing code with latest from github
167
      for_( it, updatesProductBegin(), updatesProductEnd() )
1 by Thomas-Karl Pietrowski
first import
168
      {
2 by Thomas-Karl Pietrowski
syncing code with latest from github
169
	if ( compare( cpeid_r, it.cpeId(), SetRelation::subset ) )
170
	  return true;
1 by Thomas-Karl Pietrowski
first import
171
      }
5 by Thomas-Karl Pietrowski
syncing again
172
173
      // check whether known products refer to this as update repo
174
      sat::LookupRepoAttr myIds( sat::SolvAttr::repositoryRepoid, *this );	// usually just one, but...
175
      if ( ! myIds.empty() )
176
      {
177
	const ResPool & pool( ResPool::instance() );
178
	for_( it, pool.byKindBegin<Product>(), pool.byKindEnd<Product>() )
179
	{
180
	  Product::constPtr prod( (*it)->asKind<Product>() );
181
	  if ( compare( cpeid_r, prod->cpeId(), SetRelation::superset ) )
182
	  {
183
	    for_( myId, myIds.begin(), myIds.end() )
184
	    {
185
	      if ( prod->hasUpdateContentIdentifier( myId.asString() ) )
186
		return true;
187
	    }
188
	  }
189
	}
190
      }
1 by Thomas-Karl Pietrowski
first import
191
      return false;
192
    }
193
194
    bool Repository::isUpdateRepo() const
195
    {
196
      NO_REPOSITORY_RETURN( false );
5 by Thomas-Karl Pietrowski
syncing again
197
198
      // check in repository metadata
199
      if ( updatesProductBegin() != updatesProductEnd() )
200
	return true;
201
202
      // check whether known products refer to this as update repo
203
      sat::LookupRepoAttr myIds( sat::SolvAttr::repositoryRepoid, *this );	// usually just one, but...
204
      if ( ! myIds.empty() )
205
      {
206
	const ResPool & pool( ResPool::instance() );
207
	for_( it, pool.byKindBegin<Product>(), pool.byKindEnd<Product>() )
208
	{
209
	  for_( myId, myIds.begin(), myIds.end() )
210
	  {
211
	    if ( (*it)->asKind<Product>()->hasUpdateContentIdentifier( myId.asString() ) )
212
	      return true;
213
	  }
214
	}
215
      }
216
      return false;
1 by Thomas-Karl Pietrowski
first import
217
    }
218
219
    bool Repository::solvablesEmpty() const
220
    {
221
      NO_REPOSITORY_RETURN( true );
222
      return !_repo->nsolvables;
223
    }
224
225
    Repository::size_type Repository::solvablesSize() const
226
    {
227
      NO_REPOSITORY_RETURN( 0 );
228
      return _repo->nsolvables;
229
    }
230
231
    Repository::SolvableIterator Repository::solvablesBegin() const
232
    {
233
      NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
234
                            sat::detail::SolvableIterator(),
235
                            sat::detail::SolvableIterator() ) );
236
      return make_filter_iterator( detail::ByRepository( *this ),
237
                                   sat::detail::SolvableIterator(_repo->start),
238
                                   sat::detail::SolvableIterator(_repo->end) );
239
    }
240
241
    Repository::SolvableIterator Repository::solvablesEnd() const
242
    {
243
      NO_REPOSITORY_RETURN( make_filter_iterator( detail::ByRepository( *this ),
244
                            sat::detail::SolvableIterator(),
245
                            sat::detail::SolvableIterator() ) );
246
      return make_filter_iterator(detail::ByRepository( *this ),
247
                                  sat::detail::SolvableIterator(_repo->end),
248
                                  sat::detail::SolvableIterator(_repo->end) );
249
    }
250
251
    Repository::ProductInfoIterator Repository::compatibleWithProductBegin() const
252
    {
253
      NO_REPOSITORY_RETURN( ProductInfoIterator() );
254
      return ProductInfoIterator( sat::SolvAttr::repositoryDistros, *this );
255
    }
256
257
    Repository::ProductInfoIterator Repository::compatibleWithProductEnd() const
258
    {
259
      return ProductInfoIterator();
260
    }
261
262
    Repository::ProductInfoIterator Repository::updatesProductBegin() const
263
    {
264
      NO_REPOSITORY_RETURN( ProductInfoIterator() );
265
      return ProductInfoIterator( sat::SolvAttr::repositoryUpdates, *this );
266
    }
267
268
    Repository::ProductInfoIterator Repository::updatesProductEnd() const
269
    {
270
      return ProductInfoIterator();
271
    }
272
273
    RepoInfo Repository::info() const
274
    {
275
      NO_REPOSITORY_RETURN( RepoInfo() );
276
      return myPool().repoInfo( _repo );
277
    }
278
279
    void Repository::setInfo( const RepoInfo & info_r )
280
    {
281
	NO_REPOSITORY_THROW( Exception( "Can't set RepoInfo for norepo." ) );
282
	if ( info_r.alias() != alias() )
283
	{
284
	    ZYPP_THROW( Exception( str::form( "RepoInfo alias (%s) does not match repository alias (%s)",
285
					      info_r.alias().c_str(), alias().c_str() ) ) );
286
	}
287
	myPool().setRepoInfo( _repo, info_r );
288
        MIL << *this << endl;
289
    }
290
291
    void Repository::clearInfo()
292
    {
293
	NO_REPOSITORY_RETURN();
294
	myPool().setRepoInfo( _repo, RepoInfo() );
295
    }
296
297
    void Repository::eraseFromPool()
298
    {
299
	NO_REPOSITORY_RETURN();
300
        MIL << *this << " removed from pool" << endl;
301
	myPool()._deleteRepo( _repo );
302
	_id = sat::detail::noRepoId;
303
    }
304
305
    Repository Repository::nextInPool() const
306
    {
307
      NO_REPOSITORY_RETURN( noRepository );
308
      for_( it, sat::Pool::instance().reposBegin(), sat::Pool::instance().reposEnd() )
309
      {
310
        if ( *it == *this )
311
        {
312
          if ( ++it != _for_end )
313
            return *it;
314
          break;
315
        }
316
      }
317
      return noRepository;
318
    }
319
320
    void Repository::addSolv( const Pathname & file_r )
321
    {
322
      NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
323
324
      AutoDispose<FILE*> file( ::fopen( file_r.c_str(), "re" ), ::fclose );
325
      if ( file == NULL )
326
      {
327
        file.resetDispose();
328
        ZYPP_THROW( Exception( "Can't open solv-file: "+file_r.asString() ) );
329
      }
330
331
      if ( myPool()._addSolv( _repo, file ) != 0 )
332
      {
333
        ZYPP_THROW( Exception( "Error reading solv-file: "+file_r.asString() ) );
334
      }
335
336
      MIL << *this << " after adding " << file_r << endl;
337
    }
338
339
    void Repository::addHelix( const Pathname & file_r )
340
    {
341
      NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo." ) );
342
343
      std::string command( file_r.extension() == ".gz" ? "zcat " : "cat " );
344
      command += file_r.asString();
345
346
      AutoDispose<FILE*> file( ::popen( command.c_str(), "re" ), ::pclose );
347
      if ( file == NULL )
348
      {
349
        file.resetDispose();
350
        ZYPP_THROW( Exception( "Can't open helix-file: "+file_r.asString() ) );
351
      }
352
353
      if ( myPool()._addHelix( _repo, file ) != 0 )
354
      {
355
        ZYPP_THROW( Exception( "Error reading helix-file: "+file_r.asString() ) );
356
      }
357
358
      MIL << *this << " after adding " << file_r << endl;
359
    }
360
361
    sat::detail::SolvableIdType Repository::addSolvables( unsigned count_r )
362
    {
363
	NO_REPOSITORY_THROW( Exception( "Can't add solvables to norepo.") );
364
	return myPool()._addSolvables( _repo, count_r );
365
    }
366
367
    /******************************************************************
368
     **
369
     **	FUNCTION NAME : operator<<
370
     **	FUNCTION TYPE : std::ostream &
371
     */
372
    std::ostream & operator<<( std::ostream & str, const Repository & obj )
373
    {
374
	if ( ! obj )
375
	    return str << "noRepository";
376
377
	return str << "sat::repo(" << obj.alias() << ")"
378
		   << "{"
379
                   << "prio " << obj.get()->priority << '.' << obj.get()->subpriority
380
		   << ", size " << obj.solvablesSize()
381
		   << "}";
382
    }
383
384
    std::ostream & dumpAsXmlOn( std::ostream & str, const Repository & obj )
385
    {
386
      return xmlout::node( str, "repository", {
2 by Thomas-Karl Pietrowski
syncing code with latest from github
387
	{ "name", obj.name() },
388
	{ "alias", obj.alias() }
1 by Thomas-Karl Pietrowski
first import
389
      } );
390
    }
391
392
    //////////////////////////////////////////////////////////////////
393
    namespace detail
394
    {
395
      void RepositoryIterator::increment()
396
      {
397
	if ( base() )
398
	{
399
	  ::_Pool * satpool = sat::Pool::instance().get();
400
	  do {
401
	    ++base_reference();
402
	  } while ( base() < satpool->repos+satpool->nrepos && !*base() );
403
	}
404
      }
405
    } // namespace detail
406
    //////////////////////////////////////////////////////////////////
407
408
    ///////////////////////////////////////////////////////////////////
409
    //
410
    // Repository::ProductInfoIterator
411
    //
412
    ///////////////////////////////////////////////////////////////////
413
414
    Repository::ProductInfoIterator::ProductInfoIterator( sat::SolvAttr attr_r, Repository repo_r )
415
    { base_reference() = sat::LookupRepoAttr( attr_r, repo_r ).begin(); }
416
417
    std::string Repository::ProductInfoIterator::label() const
418
    { return base_reference().subFind( sat::SolvAttr::repositoryProductLabel ).asString(); }
419
2 by Thomas-Karl Pietrowski
syncing code with latest from github
420
    CpeId Repository::ProductInfoIterator::cpeId() const
421
    { return CpeId( base_reference().subFind( sat::SolvAttr::repositoryProductCpeid ).asString(), CpeId::noThrow ); }
1 by Thomas-Karl Pietrowski
first import
422
423
    /////////////////////////////////////////////////////////////////
424
} // namespace zypp
425
///////////////////////////////////////////////////////////////////