libzypp 17.37.5
mediafacade.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
9#include "mediafacade.h"
12#include <zypp/ZYppCallbacks.h>
13#include <zypp-core/TriBool.h>
15#include <utility>
16#include <zypp-media/ng/ProvideSpec>
17#include <zypp-media/mount.h>
19
20namespace zyppng {
21
23 {
24
25 public:
26
27 AttachedSyncMediaInfo( MediaSyncFacadeRef parentRef, zypp::media::MediaAccessId mediaId, zypp::Url baseUrl, std::vector<zypp::Url> mirrors, ProvideMediaSpec mediaSpec, const zypp::Pathname &locPath );
28
30 const ProvideMediaSpec &spec() const;
31 zypp::Url url() const;
32 const std::vector<zypp::Url> &mirrors() const;
33 const std::optional<zypp::Pathname> &rootPath() const;
34 MediaSyncFacadeRef parent() const;
35
39 bool isSameMedium ( const std::vector<zypp::Url> &urls, const ProvideMediaSpec &spec );
40
41 // ReferenceCounted interface
42 protected:
43 void unref_to(unsigned int) const override;
44
45 private:
47 std::vector<zypp::Url> _mirrors;
49 MediaSyncFacadeRef _parent;
50 std::optional<zypp::Pathname> _localPath;
51 };
52
54
55 AttachedSyncMediaInfo::AttachedSyncMediaInfo(MediaSyncFacadeRef parentRef, zypp::media::MediaAccessId mediaId, zypp::Url baseUrl, std::vector<zypp::Url> mirrors, ProvideMediaSpec mediaSpec, const zypp::Pathname &locPath)
56 : _id( mediaId )
57 , _mirrors( std::move( mirrors ) )
58 , _spec(std::move( mediaSpec ))
59 , _parent(std::move( parentRef ))
60 , _localPath( locPath )
61 {
62 // make sure attach URL is in front
63 if ( _mirrors.empty () ) {
64 _mirrors.push_back ( baseUrl );
65 } else {
66 auto i = std::find( _mirrors.begin(), _mirrors.end(), baseUrl );
67 if ( i != _mirrors.begin() ) {
68 if ( i != _mirrors.end() )
69 _mirrors.erase(i);
70 _mirrors.insert( _mirrors.begin(), baseUrl );
71 }
72 }
73
74 }
75
80
82 {
83 return _spec;
84 }
85
87 {
88 if ( !_mirrors.size() )
89 return {};
90
91 return _mirrors.at(0);
92 }
93
94 const std::vector<zypp::Url> &AttachedSyncMediaInfo::mirrors() const
95 {
96 return _mirrors;
97 }
98
99 const std::optional<zypp::Pathname> &AttachedSyncMediaInfo::rootPath() const
100 {
101 return _localPath;
102 }
103
104 MediaSyncFacadeRef AttachedSyncMediaInfo::parent() const
105 {
106 return _parent;
107 }
108
109 bool AttachedSyncMediaInfo::isSameMedium(const std::vector<zypp::Url> &urls, const ProvideMediaSpec &spec)
110 {
112 }
113
114 void AttachedSyncMediaInfo::unref_to( unsigned int count ) const
115 {
116 // once count reaches 1 only the MediaSyncFacade holds a reference,
117 // time to release the medium
118 if ( count == 1 ) {
119 _parent->releaseMedium ( this );
120 // !!!! careful from here on out 'this' is most likely invalid !!!!
121 return;
122 }
123 }
124
125
127
128 SyncMediaHandle::SyncMediaHandle(AttachedSyncMediaInfo_Ptr dataPtr) : _data( std::move(dataPtr) )
129 { }
130
131 MediaSyncFacadeRef SyncMediaHandle::parent() const
132 {
133 return _data->parent();
134 }
135
137 {
138 return _data.get() != nullptr;
139 }
140
142 {
143 static zypp::Url invalidHandle;
144 if ( !_data || !_data->mirrors().size () )
145 return invalidHandle;
146 return _data->mirrors().at(0);
147 }
148
149 const std::optional<zypp::Pathname> &SyncMediaHandle::localPath() const
150 {
151 static std::optional<zypp::Pathname> invalidPath;
152 if ( !_data )
153 return invalidPath;
154 return _data->rootPath();
155 }
156
158 {
159 return *_data;
160 }
161
163 : _res( std::move(file) )
164 , _provideHandle( std::move (hdl) )
165 { }
166
168 return _res;
169 }
170
172
173 std::vector<zypp::Url> MediaSyncFacade::sanitizeUrls(const std::vector<zypp::Url> &urls) const
174 {
175 std::vector<zypp::Url> usableMirrs;
176 std::optional<zypp::media::MediaHandlerFactory::MediaHandlerType> handlerType;
177
178 for ( auto mirrIt = urls.begin() ; mirrIt != urls.end(); mirrIt++ ) {
179 const auto &s = zypp::media::MediaHandlerFactory::handlerType ( *mirrIt );
180 if ( !s ) {
181 WAR << "URL: " << *mirrIt << " is not supported, ignoring!" << std::endl;
182 continue;
183 }
184 if ( !handlerType ) {
185 handlerType = *s;
186 usableMirrs.push_back ( *mirrIt );
187 } else {
188 if ( handlerType == *s) {
189 usableMirrs.push_back( *mirrIt );
190 } else {
191 WAR << "URL: " << *mirrIt << " has different handler type than the primary URL: "<< usableMirrs.front() <<", ignoring!" << std::endl;
192 }
193 }
194 }
195
196 if ( !handlerType || usableMirrs.empty() ) {
197 return {};
198 }
199
200 return usableMirrs;
201 }
202
204 {
205 return attachMedia( std::vector<zypp::Url>{url}, request );
206 }
207
209 {
210 // rewrite and sanitize the urls if required
211 std::vector<zypp::Url> useableUrls = sanitizeUrls(urls);
212
213 if ( useableUrls.empty () )
215
216 if ( request.medianr() > 1 )
217 useableUrls = zyppng::transform ( useableUrls, [&]( const zypp::Url &u ) { return zypp::MediaSetAccess::rewriteUrl( u, request.medianr() );} );
218
219 // first try and find a already attached medium
220 auto i = std::find_if( _attachedMedia.begin (), _attachedMedia.end(), [&]( const AttachedSyncMediaInfo_Ptr &medium ) {
221 return medium->isSameMedium( useableUrls, request );
222 });
223
224 if ( i != _attachedMedia.end() ) {
226 }
227
228 bool isVolatile = useableUrls.front().schemeIsVolatile();
229
230 std::optional<zypp::media::MediaAccessId> attachId;
232
233 // nothing attached, make a new one
235 do {
236 try {
237 if ( !attachId ) {
238 attachId = mgr.open( zyppng::transform ( useableUrls, [](const auto &u) { return zypp::media::MediaUrl(u); } ) );
239 if ( !request.mediaFile().empty() ) {
240 mgr.addVerifier( *attachId, zypp::media::MediaVerifierRef( new zypp::repo::SUSEMediaVerifier( request.mediaFile(), request.medianr() ) ) );
241 }
242 }
243
244 // attach the medium
245 mgr.attach( *attachId );
246
247 auto locPath = mgr.localPath( *attachId, "/" );
248 auto attachInfo = AttachedSyncMediaInfo_Ptr( new AttachedSyncMediaInfo( shared_this<MediaSyncFacade>(), *attachId, useableUrls.front(), useableUrls, request, locPath ) );
249 _attachedMedia.push_back( attachInfo );
250 return expected<MediaSyncFacade::MediaHandle>::success( std::move(attachInfo) );
251
252 } catch ( const zypp::media::MediaException &excp ) {
253
254 ZYPP_CAUGHT(excp);
255
256 // if no one is listening, just return the error as is
259 }
260
261 // default action is to cancel
263
264 do {
265 // here: Manager tried all not attached drives and could not find the desired medium
266 // we need to send the media change report
267
268 // set up the reason
270 if( typeid(excp) == typeid( zypp::media::MediaNotDesiredException) ) {
272 }
273
274 unsigned int devindex = 0;
275
276 std::vector<std::string> devices;
277 mgr.getDetectedDevices(*attachId, devices, devindex);
278
279 std::optional<std::string> currentlyUsed;
280 if ( devices.size() ) currentlyUsed = devices[devindex];
281
282 if ( isVolatile ) {
283 // filter devices that are mounted, aka used, we can not eject them
284 const auto &mountedDevs = zypp::media::Mount::getEntries();
285 devices.erase( std::remove_if( devices.begin (), devices.end(), [&](const std::string &dev) {
286 zypp::PathInfo devInfo(dev);
287 return std::any_of( mountedDevs.begin (), mountedDevs.end(), [&devInfo]( const zypp::media::MountEntry &e ) {
288 zypp::PathInfo pi( e.src );
289 return ( pi.isBlk() && pi.devMajor() == devInfo.devMajor() && pi.devMinor() == devInfo.devMinor() );
290 });
291 }), devices.end() );
292
293 if ( !devices.size () ) {
294 // Jammed, no currently free device
295 MIL << "No free device available, return jammed and try again later ( hopefully) " << std::endl;
296 if ( attachId ) mgr.close ( *attachId );
298 }
299
300 // update index to currenty used dev
301 bool foundCurrent = false;
302 if ( currentlyUsed ) {
303 for ( unsigned int i = 0; i < devices.size(); i++ ) {
304 if ( devices[i] == *currentlyUsed ) {
305 foundCurrent = true;
306 devindex = i;
307 break;
308 }
309 }
310 }
311
312 if ( !foundCurrent ){
313 devindex = 0; // seems 0 is what is set in the handlers too if there is no current
314 }
315 }
316
317 zypp::Url effectiveUrl = useableUrls.front();
318
319 user = report->requestMedia (
320 effectiveUrl,
321 request.medianr(),
322 request.label(),
323 reason,
324 excp.asUserHistory(),
325 devices,
326 devindex
327 );
328
329 MIL << "ProvideFile exception caught, callback answer: " << user << std::endl;
330
331 switch ( user ) {
333 DBG << "Aborting" << std::endl;
334 if ( attachId ) mgr.close ( *attachId );
335 zypp::AbortRequestException aexcp("Aborting requested by user");
336 aexcp.remember(excp);
338 }
340 DBG << "Skipping" << std::endl;
341 if ( attachId ) mgr.close ( *attachId );
342 zypp::SkipRequestException nexcp("User-requested skipping of a file");
343 nexcp.remember(excp);
345 }
347 DBG << "Eject: try to release" << std::endl;
348 try
349 {
350 // MediaSetAccess does a releaseAll, but we can not release other devices that are in use
351 // media_mgr.releaseAll();
352 mgr.release (*attachId, devindex < devices.size() ? devices[devindex] : "");
353 }
354 catch ( const zypp::Exception & e)
355 {
356 ZYPP_CAUGHT(e);
357 }
358 break;
359 }
362 // retry
363 DBG << "Going to try again" << std::endl;
364
365 // invalidate current media access id
366 if ( attachId ) {
367 mgr.close(*attachId);
368 attachId.reset();
369 }
370
371 // explicitely setting a URL from the callback wipes all mirrors
372 if ( useableUrls.front() != effectiveUrl ) {
373 useableUrls.clear ();
374 useableUrls.push_back ( effectiveUrl );
375 }
376
377 // not attaching, media set will do that for us
378 // this could generate uncaught exception (#158620)
379 break;
380 }
381 default: {
382 DBG << "Don't know, let's ABORT" << std::endl;
383 if ( attachId ) mgr.close ( *attachId );
385 }
386 }
387 } while( user == zypp::media::MediaChangeReport::EJECT );
388 } catch ( const zypp::Exception &e ) {
389 ZYPP_CAUGHT(e);
390 if ( attachId ) mgr.close ( *attachId );
392 } catch (...) {
393 // didn't work -> clean up
394 if ( attachId ) mgr.close ( *attachId );
396 }
397 } while ( true );
398 }
399
401 {
402 // this should never happen because every handle has a reference to the media manager, but still add a debug output
403 // so we know in case we have weird behavior.
404 if ( _attachedMedia.size () ) {
405 WAR << "Releasing zyppng::MediaSyncFacade with still valid MediaHandles, this is a bug!" << std::endl;
406 }
407 }
408
410 {
411 const auto &useableUrls = sanitizeUrls(urls);
412 if ( useableUrls.empty () )
414 return expected<LazyMediaHandle>::success( shared_this<MediaSyncFacade>(), std::move(useableUrls), request );
415 }
416
418 {
419 return prepareMedia( std::vector<zypp::Url>{url}, request );
420 }
421
423 {
424 using namespace zyppng::operators;
425 if ( lazyHandle.attached() )
426 return expected<MediaHandle>::success( *lazyHandle.handle() );
427
428 MIL << "Attaching lazy medium with label: [" << lazyHandle.spec().label() << "]" << std::endl;
429
430 return attachMedia( lazyHandle.urls(), lazyHandle.spec () )
431 | and_then([lazyHandle]( MediaHandle handle ) {
432 lazyHandle._sharedData->_mediaHandle = handle;
433 return expected<MediaHandle>::success( std::move(handle) );
434 });
435 }
436
437 expected<MediaSyncFacade::Res> MediaSyncFacade::provide(const std::vector<zypp::Url> &urls, const ProvideFileSpec &request)
438 {
439 using namespace zyppng::operators;
440
441 if ( !urls.size() )
442 return expected<MediaSyncFacade::Res>::error( ZYPP_EXCPT_PTR ( zypp::media::MediaException("Can not provide a file without a URL.") ));
443
444 std::optional<expected<MediaSyncFacade::Res>> lastErr;
445 for ( const zypp::Url& file_url : urls ) {
446
447 zypp::Url url(file_url);
448 zypp::Pathname fileName(url.getPathName());
449 url.setPathName ("/");
450
452 | and_then( [&, this]( const MediaSyncFacade::MediaHandle& handle ) {
453 return provide( handle, fileName, request.asOnMediaLocation(fileName, 1));
454 });
455
456 if ( res )
457 return res;
458
459 lastErr = res;
460 }
461
462 // we always should have a last error, except if the URLs are empty
463 if ( lastErr )
464 return *lastErr;
465
466 // we should not get here, but if we do simply use the first entry to make a not found error
467 zypp::Url url( urls.front() );
468 zypp::Pathname fileName(url.getPathName());
469 url.setPathName ("/");
471
472 }
473
475 {
476 return provide( std::vector<zypp::Url>{url}, request );
477 }
478
480 {
482 const auto &handleInfo = attachHandle.info();
483
484 try {
485 if ( request.checkExistsOnly() ) {
486 if ( !mgr.doesFileExist ( handleInfo.mediaId (), fileName ) ) {
488 }
489
490 // we return a result pointing to a non existant file, since the code just asked us to check if the file exists
491 return expected<MediaSyncFacade::Res>::success( attachHandle, zypp::ManagedFile( mgr.localPath( handleInfo.mediaId(), fileName ) ) );
492
493 } else {
494 mgr.provideFile( handleInfo.mediaId (), request.asOnMediaLocation( fileName, handleInfo.spec().medianr()) );
495
496 zypp::ManagedFile locFile( mgr.localPath( handleInfo.mediaId(), fileName ) );
497
498 // do not clean up files for now, they are cleaned up anyways on detach
499#if 0
500 // if the file is downloaded we want to clean it up again
501 if ( handleInfo.url().schemeIsDownloading() )
503#endif
504
505 return expected<MediaSyncFacade::Res>::success( attachHandle, locFile );
506 }
507 } catch ( const zypp::Exception &e ) {
508 ZYPP_CAUGHT(e);
510 } catch (...) {
512 }
513 }
514
516 {
517 using namespace zyppng::operators;
518 return attachMediaIfNeeded ( attachHandle )
519 | and_then([weakMe = weak_this<MediaSyncFacade>(), fName = fileName, req = request ]( MediaHandle handle ){
520 auto me = weakMe.lock();
521 if ( !me )
522 return expected<Res>::error(ZYPP_EXCPT_PTR(zypp::Exception("Provide was released during a operation")));
523 return me->provide( handle, fName, req);
524 });
525 }
526
528 {
529 try {
530 return expected<zypp::CheckSum>::success( zypp::CheckSum( algorithm, zypp::filesystem::checksum ( p, algorithm ) ) );
531 } catch(...) {
532 return expected<zypp::CheckSum>::error ( std::current_exception () );
533 }
534 }
535
537 {
538 try {
539 // do what Provide would do and make a URL
540 zypp::Url url("copy:///");
541 url.setPathName( source );
542
543 auto sourcePi = zypp::PathInfo(source);
544 if ( !sourcePi.isExist() ) {
546 }
547 if ( !sourcePi.isFile () )
549
550 auto res = zypp::filesystem::hardlinkCopy( source, target.asString() );
551 if ( res == 0 ) {
553 } else {
554 return expected<zypp::ManagedFile>::error ( ZYPP_EXCPT_PTR( zypp::media::MediaException( zypp::str::Str() << "Failed to create file " << target << " errno: " << res ) ) );
555 }
556 } catch(...) {
557 return expected<zypp::ManagedFile>::error ( std::current_exception () );
558 }
559 }
560
562 {
563 // not much to do here, since this will block until the file has been copied we do not need to remember the ProvideRes
564 return copyFile( source.file(), target );
565 }
566
568 {
569 if ( !ptr ) return;
570
571 auto i = std::find_if(_attachedMedia.begin (), _attachedMedia.end(), [&]( const auto &p ) { return p.get() == ptr; } );
572
573 try {
575 mgr.close ( ptr->mediaId() );
576 } catch ( const zypp::Exception & e ) {
577 ZYPP_CAUGHT(e);
578 }
579
580 if ( i != _attachedMedia.end() ) {
581 _attachedMedia.erase(i);
582 } else {
583 ERR << "Releasing unknown medium " << ptr->mediaId () << " should not happen";
584 }
585 }
586
587
588}
void setDispose(const Dispose &dispose_r)
Set a new dispose function.
Base class for Exception.
Definition Exception.h:153
std::string asUserHistory() const
A single (multiline) string composed of asUserString and historyAsString.
Definition Exception.cc:140
static Url rewriteUrl(const Url &url_r, const media::MediaNr medianr)
Replaces media number in specified url with given medianr.
Url manipulation class.
Definition Url.h:93
Base class for reference counted objects.
Wrapper class for stat/lstat.
Definition PathInfo.h:226
bool empty() const
Test for an empty path.
Definition Pathname.h:116
Just inherits Exception to separate media exceptions.
static std::optional< MediaHandlerType > handlerType(const Url &url)
Manages access to the 'physical' media, e.g CDROM drives, Disk volumes, directory trees,...
MediaAccessId open(const Url &url, const Pathname &preferred_attach_point="")
Opens the media access for specified with the url.
void attach(MediaAccessId accessId)
Attach the media using the concrete handler (checks all devices).
void close(MediaAccessId accessId)
Close the media access with specified id.
ZYPP_DEPRECATED void provideFile(MediaAccessId accessId, const Pathname &filename, const ByteCount &expectedFileSize) const
void release(MediaAccessId accessId, const std::string &ejectDev="")
Release the attached media and optionally eject.
bool doesFileExist(MediaAccessId accessId, const Pathname &filename) const
FIXME: see MediaAccess class.
Pathname localPath(MediaAccessId accessId, const Pathname &pathname) const
Shortcut for 'localRoot() + pathname', but returns an empty pathname if media is not attached.
void addVerifier(MediaAccessId accessId, const MediaVerifierRef &verifier)
Add verifier implementation for the specified media id.
void getDetectedDevices(MediaAccessId accessId, std::vector< std::string > &devices, unsigned int &index) const
Fill in a vector of detected ejectable devices and the index of the currently attached device within ...
static MountEntries getEntries(const std::string &mtab="")
Return mount entries from /etc/mtab or /etc/fstab file.
Definition mount.cc:169
Implementation of the traditional SUSE media verifier.
bool isSameMedium(const std::vector< zypp::Url > &urls, const ProvideMediaSpec &spec)
zypp::media::MediaAccessId _id
MediaSyncFacadeRef _parent
AttachedSyncMediaInfo(MediaSyncFacadeRef parentRef, zypp::media::MediaAccessId mediaId, zypp::Url baseUrl, std::vector< zypp::Url > mirrors, ProvideMediaSpec mediaSpec, const zypp::Pathname &locPath)
std::vector< zypp::Url > _mirrors
std::optional< zypp::Pathname > _localPath
MediaSyncFacadeRef parent() const
const std::vector< zypp::Url > & mirrors() const
bool isSameMedium(const std::vector< zypp::Url > &urls, const ProvideMediaSpec &spec)
const std::optional< zypp::Pathname > & rootPath() const
zypp::media::MediaAccessId mediaId() const
void unref_to(unsigned int) const override
const ProvideMediaSpec & spec() const
std::shared_ptr< T > shared_this() const
Definition base.h:113
std::weak_ptr< T > weak_this() const
Definition base.h:123
const std::vector< zypp::Url > & urls() const
const ProvideMediaSpec & spec() const
std::optional< MediaHandle > handle() const
Res(MediaHandle hdl, zypp::ManagedFile file)
const zypp::Pathname file() const
expected< Res > provide(const std::vector< zypp::Url > &urls, const ProvideFileSpec &request)
expected< MediaHandle > attachMedia(const std::vector< zypp::Url > &urls, const ProvideMediaSpec &request)
friend class AttachedSyncMediaInfo
Definition mediafacade.h:53
expected< zypp::CheckSum > checksumForFile(const zypp::Pathname &p, const std::string &algorithm)
::zyppng::LazyMediaHandle< MediaSyncFacade > LazyMediaHandle
Definition mediafacade.h:56
expected< zypp::ManagedFile > copyFile(const zypp::Pathname &source, const zypp::Pathname &target)
SyncMediaHandle MediaHandle
Definition mediafacade.h:55
std::vector< AttachedSyncMediaInfo_Ptr > _attachedMedia
expected< MediaHandle > attachMediaIfNeeded(LazyMediaHandle lazyHandle)
std::vector< zypp::Url > sanitizeUrls(const std::vector< zypp::Url > &urls) const
void releaseMedium(const AttachedSyncMediaInfo *ptr)
expected< LazyMediaHandle > prepareMedia(const std::vector< zypp::Url > &urls, const ProvideMediaSpec &request)
zypp::OnMediaLocation asOnMediaLocation(const zypp::Pathname &path, unsigned int mediaNr) const
bool checkExistsOnly() const
unsigned medianr() const
zypp::Pathname mediaFile() const
const std::string & label() const
const std::optional< zypp::Pathname > & localPath() const
const AttachedSyncMediaInfo & info() const
MediaSyncFacadeRef parent() const
const zypp::Url & baseUrl() const
AttachedSyncMediaInfo_Ptr _data
Definition mediafacade.h:40
static expected success(ConsParams &&...params)
Definition expected.h:115
Definition Arch.h:364
boost::noncopyable NonCopyable
Ensure derived classes cannot be copied.
Definition NonCopyable.h:26
std::string checksum(const Pathname &file, const std::string &algorithm)
Compute a files checksum.
Definition PathInfo.cc:1056
int hardlinkCopy(const Pathname &oldpath, const Pathname &newpath)
Create newpath as hardlink or copy of oldpath.
Definition PathInfo.cc:888
int unlink(const Pathname &path)
Like 'unlink'.
Definition PathInfo.cc:705
unsigned int MediaAccessId
Media manager access Id type.
Definition MediaSource.h:30
zypp::RW_pointer< MediaVerifierBase > MediaVerifierRef
A shared reference to the MediaVerifier implementation.
Url details namespace.
Definition UrlBase.cc:58
AutoDispose< const Pathname > ManagedFile
A Pathname plus associated cleanup code to be executed when path is no longer needed.
Definition ManagedFile.h:27
ResultType and_then(const expected< T, E > &exp, Function &&f)
Definition expected.h:423
Container< Ret > transform(Container< Msg, CArgs... > &&val, Transformation &&transformation)
Definition transform.h:31
static bool connected()
Definition Callback.h:251
Convenient building of std::string via std::ostringstream Basically a std::ostringstream autoconverti...
Definition String.h:213
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition Exception.h:475
#define ZYPP_EXCPT_PTR(EXCPT)
Drops a logline and returns Exception as a std::exception_ptr.
Definition Exception.h:463
#define ZYPP_FWD_CURRENT_EXCPT()
Drops a logline and returns the current Exception as a std::exception_ptr.
Definition Exception.h:471
#define DBG
Definition Logger.h:99
#define MIL
Definition Logger.h:100
#define ERR
Definition Logger.h:102
#define WAR
Definition Logger.h:101
#define IMPL_PTR_TYPE(NAME)
#define ZYPP_IMPL_PRIVATE_CONSTR(Class)
Definition zyppglobal.h:222