libzypp 17.31.23
MediaCD.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
12extern "C"
13{
14#include <sys/ioctl.h>
15#include <linux/cdrom.h>
16#if HAVE_UDEV
17#include <libudev.h>
18#endif
19}
20
21#include <cstring> // strerror
22#include <cstdlib> // getenv
23#include <iostream>
24
25#include <zypp/base/Logger.h>
26#include <zypp/ExternalProgram.h>
27#include <zypp-media/Mount>
28#include <zypp-media/CDTools>
29#include <zypp/media/MediaCD.h>
31#include <zypp/Url.h>
32#include <zypp/AutoDispose.h>
33
34using std::endl;
35
36/*
37** if to throw exception on eject errors or ignore them
38*/
39#define REPORT_EJECT_ERRORS 0
40
41
43namespace zypp
44{
46 namespace media
47 {
48
50 namespace
51 {
52 typedef std::list<MediaSource> DeviceList;
53
59 DeviceList systemDetectDevices( bool supportingDVD_r )
60 {
61 DeviceList detected;
62
63#ifdef HAVE_UDEV
64 // http://www.kernel.org/pub/linux/utils/kernel/hotplug/libudev/index.html
65 zypp::AutoDispose<struct udev *> udev( ::udev_new(), ::udev_unref );
66 if ( ! udev )
67 {
68 ERR << "Can't create udev context." << endl;
69 return DeviceList();
70 }
71
72 zypp::AutoDispose<struct udev_enumerate *> enumerate( ::udev_enumerate_new(udev), ::udev_enumerate_unref );
73 if ( ! enumerate )
74 {
75 ERR << "Can't create udev list entry." << endl;
76 return DeviceList();
77 }
78
79 ::udev_enumerate_add_match_subsystem( enumerate, "block" );
80 ::udev_enumerate_add_match_property( enumerate, "ID_CDROM", "1" );
81 ::udev_enumerate_scan_devices( enumerate );
82
83 struct udev_list_entry * entry = 0;
84 udev_list_entry_foreach( entry, ::udev_enumerate_get_list_entry( enumerate ) )
85 {
86 zypp::AutoDispose<struct udev_device *> device( ::udev_device_new_from_syspath( ::udev_enumerate_get_udev( enumerate ),
87 ::udev_list_entry_get_name( entry ) ),
88 ::udev_device_unref );
89 if ( ! device )
90 {
91 ERR << "Can't create udev device." << endl;
92 continue;
93 }
94
95 if ( supportingDVD_r && ! ::udev_device_get_property_value( device, "ID_CDROM_DVD" ) )
96 {
97 continue; // looking for dvd only
98 }
99
100 const char * devnodePtr( ::udev_device_get_devnode( device ) );
101 if ( ! devnodePtr )
102 {
103 ERR << "Got NULL devicenode." << endl;
104 continue;
105 }
106
107 // In case we need it someday:
108 //const char * mountpath = ::udev_device_get_property_value( device, "FSTAB_DIR" );
109
110 PathInfo devnode( devnodePtr );
111 if ( devnode.isBlk() )
112 {
113 MediaSource media( "cdrom", devnode.path().asString(), devnode.devMajor(), devnode.devMinor() );
114 DBG << "Found (udev): " << media << std::endl;
115 detected.push_back( media );
116 }
117 }
118 if ( detected.empty() )
119 {
120 WAR << "Did not find any CD/DVD device." << endl;
121 }
122#endif
123 return detected;
124 }
125
126 } // namespace
128
129
130 MediaCD::MediaCD( const Url & url_r, const Pathname & attach_point_hint_r )
131 : MediaHandler( url_r, attach_point_hint_r, url_r.getPathName(), false )
132 , _lastdev( -1 )
133 , _lastdev_tried( -1 )
134 {
135 MIL << "MediaCD::MediaCD(" << url_r << ", " << attach_point_hint_r << ")" << endl;
136
137 if ( url_r.getScheme() != "dvd" && url_r.getScheme() != "cd" )
138 {
139 ERR << "Unsupported schema in the Url: " << url_r.asString() << endl;
141 }
142
143 std::string devices = _url.getQueryParam( "devices" );
144 if ( ! devices.empty() )
145 {
146 std::vector<std::string> words;
147 str::split( devices, std::back_inserter(words), "," );
148 for ( const std::string & device : words )
149 {
150 if ( device.empty() )
151 continue;
152
153 MediaSource media( "cdrom", device, 0, 0 );
154 _devices.push_back( media );
155 DBG << "use device (delayed verify)" << device << endl;
156 }
157 }
158 else
159 {
160 DBG << "going to use on-demand device list" << endl;
161 return;
162 }
163
164 if ( _devices.empty() )
165 {
166 ERR << "Unable to find any cdrom drive for " << _url.asString() << endl;
168 }
169 }
170
172 //
173 //
174 // METHOD NAME : MediaCD::openTray
175 // METHOD TYPE : bool
176 //
177 bool MediaCD::openTray( const std::string & device_r )
178 {
179 return CDTools::openTray(device_r);
180 }
181
183 //
184 //
185 // METHOD NAME : MediaCD::closeTray
186 // METHOD TYPE : bool
187 //
188 bool MediaCD::closeTray( const std::string & device_r )
189 {
190 return CDTools::closeTray(device_r);
191 }
192
193
194 MediaCD::DeviceList MediaCD::detectDevices( bool supportingDVD_r ) const
195 {
196 DeviceList detected( systemDetectDevices( supportingDVD_r ) );
197
198 if ( detected.empty() )
199 {
200 WAR << "CD/DVD drive detection with UDEV failed! Guessing..." << std::endl;
201 PathInfo dvdinfo( "/dev/dvd" );
202 PathInfo cdrinfo( "/dev/cdrom" );
203 if ( dvdinfo.isBlk() )
204 {
205 MediaSource media( "cdrom", dvdinfo.path().asString(), dvdinfo.devMajor(), dvdinfo.devMinor() );
206 DBG << "Found (GUESS): " << media << std::endl;
207 detected.push_back( media );
208 }
209 if ( cdrinfo.isBlk()
210 && ! ( cdrinfo.devMajor() == dvdinfo.devMajor() && cdrinfo.devMinor() == dvdinfo.devMinor() ) )
211 {
212 MediaSource media( "cdrom", cdrinfo.path().asString(), cdrinfo.devMajor(), cdrinfo.devMinor() );
213 DBG << "Found (GUESS): " << media << std::endl;
214 detected.push_back( media );
215 }
216 }
217
218 // NOTE: On the fly build on-demand device list. Code was moved to
219 // here to get rid of code duplication, while keeping the ABI. Acuallty
220 // this code should be moved to a _devices accessor method.
221 if ( _devices.empty() )
222 {
223 DBG << "creating on-demand device list" << endl;
224 //default is /dev/cdrom; for dvd: /dev/dvd if it exists
225 std::string device( "/dev/cdrom" );
226 if ( _url.getScheme() == "dvd" && PathInfo( "/dev/dvd" ).isBlk() )
227 {
228 device = "/dev/dvd";
229 }
230
231 PathInfo dinfo( device );
232 if ( dinfo.isBlk() )
233 {
234 MediaSource media( "cdrom", device, dinfo.devMajor(), dinfo.devMinor() );
235 if ( detected.empty() )
236 {
237 _devices.push_front( media ); // better try this than nothing
238 }
239 else
240 {
241 for( const auto & d : detected )
242 {
243 // /dev/cdrom or /dev/dvd to the front
244 if ( media.equals( d ) )
245 _devices.push_front( d );
246 else
247 _devices.push_back( d );
248 }
249 }
250 }
251 else
252 {
253 // no /dev/cdrom or /dev/dvd link
254 _devices = detected;
255 }
256 }
257
258 return detected;
259 }
260
261
263 //
264 //
265 // METHOD NAME : MediaCD::attachTo
266 // METHOD TYPE : PMError
267 //
268 // DESCRIPTION : Asserted that not already attached, and attachPoint is a directory.
269 //
270 void MediaCD::attachTo( bool next )
271 {
272 DBG << "next " << next << " last " << _lastdev << " last tried " << _lastdev_tried << endl;
273 if ( next && _lastdev == -1 )
275
276 // This also fills the _devices list on demand
277 DeviceList detected( detectDevices( _url.getScheme() == "dvd" ? true : false ) );
278
279 Mount mount;
281
282 std::string options = _url.getQueryParam( "mountoptions" );
283 if ( options.empty() )
284 {
285 options="ro";
286 }
287
288 //TODO: make configurable
289 std::list<std::string> filesystems;
290
291 filesystems.push_back("iso9660");
292
293 // if DVD, try UDF filesystem after iso9660
294 if ( _url.getScheme() == "dvd" )
295 filesystems.push_back("udf");
296
297 // try all devices in sequence
298 int count = 0;
299 std::string mountpoint( attachPoint().asString() );
300 bool mountsucceeded = false;
301 for ( DeviceList::iterator it = _devices.begin() ; ! mountsucceeded && it != _devices.end() ; ++it, ++count )
302 {
303 DBG << "count " << count << endl;
304 if (next && count <=_lastdev_tried )
305 {
306 DBG << "skipping device " << it->name << endl;
307 continue;
308 }
309 _lastdev_tried = count;
310
311 // bnc#755815: _devices contains either devices passed as url option
312 // or autodetected ones. Accept both as long as they are block
313 // devices.
314 MediaSource temp( *it );
315 PathInfo dinfo( temp.name );
316 if ( ! dinfo.isBlk() )
317 {
318 WAR << "skipping non block device: " << dinfo << endl;
319 continue;
320 }
321 DBG << "trying device " << dinfo << endl;
322
323 temp.maj_nr = dinfo.devMajor();
324 temp.min_nr = dinfo.devMinor();
325 MediaSourceRef media( new MediaSource(temp));
326 AttachedMedia ret( findAttachedMedia( media));
327
328 if( ret.mediaSource && ret.attachPoint &&
329 !ret.attachPoint->empty())
330 {
331 DBG << "Using a shared media "
332 << ret.mediaSource->name
333 << " attached on "
334 << ret.attachPoint->path
335 << endl;
339 _lastdev = count;
340 mountsucceeded = true;
341 break;
342 }
343
344 {
345 MediaManager manager;
346 MountEntries entries( manager.getMountEntries());
347 MountEntries::const_iterator e;
348 for( e = entries.begin(); e != entries.end(); ++e)
349 {
350 bool is_device = false;
351 std::string dev_path(Pathname(e->src).asString());
352 PathInfo dev_info;
353
354 if( dev_path.compare(0, sizeof("/dev/")-1, "/dev/") == 0 &&
355 dev_info(e->src) && dev_info.isBlk())
356 {
357 is_device = true;
358 }
359
360 if( is_device && media->maj_nr == dev_info.devMajor() &&
361 media->min_nr == dev_info.devMinor())
362 {
363 AttachPointRef ap( new AttachPoint(e->dir, false));
364 AttachedMedia am( media, ap);
365 {
366 DBG << "Using a system mounted media "
367 << media->name
368 << " attached on "
369 << ap->path
370 << endl;
371
372 media->iown = false; // mark attachment as foreign
373
374 setMediaSource(media);
375 setAttachPoint(ap);
376 _lastdev = count;
377 mountsucceeded = true;
378 break;
379 }
380 }
381 }
382 if( mountsucceeded)
383 break;
384 }
385
386 // close tray
387 closeTray( it->name );
388
389 // try all filesystems in sequence
390 for(std::list<std::string>::iterator fsit = filesystems.begin()
391 ; !mountsucceeded && fsit != filesystems.end()
392 ; ++fsit)
393 {
394 try
395 {
397 {
399 mountpoint = attachPoint().asString();
400 }
401
402 mount.mount(it->name, mountpoint, *fsit, options);
403
404 setMediaSource(media);
405
406 // wait for /etc/mtab update ...
407 // (shouldn't be needed)
408 int limit = 2;
409 while( !(mountsucceeded=isAttached()) && --limit)
410 {
411 WAR << "Wait for /proc/mounts update and retry...." << endl;
412 sleep(1);
413 }
414
415 if( mountsucceeded)
416 {
417 _lastdev = count;
418 }
419 else
420 {
422 try
423 {
424 mount.umount(attachPoint().asString());
425 }
426 catch (const MediaException & excpt_r)
427 {
428 ZYPP_CAUGHT(excpt_r);
429 }
431 "Unable to verify that the media was mounted",
432 it->name, mountpoint
433 ));
434 }
435 }
436 catch (const MediaMountException &e)
437 {
438 merr = e;
440 ZYPP_CAUGHT(e);
441 }
442 catch (const MediaException & excpt_r)
443 {
445 ZYPP_CAUGHT(excpt_r);
446 }
447 } // for filesystems
448 } // for _devices
449
450 if (!mountsucceeded)
451 {
452 _lastdev = -1;
453
454 if( !merr.mountOutput().empty())
455 {
457 _url.asString(),
458 mountpoint,
459 merr.mountOutput()));
460 }
461 else
462 {
463 ZYPP_THROW(MediaMountException("Mounting media failed",
464 _url.asString(), mountpoint));
465 }
466 }
467 DBG << _lastdev << " " << count << endl;
468 }
469
470
472 //
473 //
474 // METHOD NAME : MediaCD::releaseFrom
475 // METHOD TYPE : PMError
476 //
477 // DESCRIPTION : Asserted that media is attached.
478 //
479 void MediaCD::releaseFrom( const std::string & ejectDev )
480 {
481 Mount mount;
482 try
483 {
485 if(am.mediaSource && am.mediaSource->iown)
486 mount.umount(am.attachPoint->path.asString());
487 }
488 catch (const Exception & excpt_r)
489 {
490 ZYPP_CAUGHT(excpt_r);
491 if (!ejectDev.empty())
492 {
493 forceRelaseAllMedia(false);
494 if(openTray( ejectDev ))
495 return;
496 }
497 ZYPP_RETHROW(excpt_r);
498 }
499
500 // eject device
501 if (!ejectDev.empty())
502 {
503 forceRelaseAllMedia(false);
504 if( !openTray( ejectDev ))
505 {
506#if REPORT_EJECT_ERRORS
508#endif
509 }
510 }
511 }
512
514 //
515 //
516 // METHOD NAME : MediaCD::forceEject
517 // METHOD TYPE : void
518 //
519 // Asserted that media is not attached.
520 //
521 void MediaCD::forceEject( const std::string & ejectDev_r )
522 {
523#if REPORT_EJECT_ERRORS
524 bool ejected = false;
525#endif
526 if ( ! isAttached() ) // no device mounted in this instance
527 {
528 // This also fills the _devices list on demand
529 DeviceList detected( detectDevices( _url.getScheme() == "dvd" ? true : false ) );
530 for_( it, _devices.begin(), _devices.end() )
531 {
532 MediaSourceRef media( new MediaSource( *it ) );
533 if ( media->name != ejectDev_r )
534 continue;
535
536 // bnc#755815: _devices contains either devices passed as url option
537 // or autodetected ones. Accept both as long as they are block
538 // devices.
539 PathInfo dinfo( media->name );
540 if( ! dinfo.isBlk() )
541 {
542 WAR << "skipping non block device: " << dinfo << endl;
543 continue;
544 }
545 DBG << "trying device " << dinfo << endl;
546
547 // FIXME: we have also to check if it is mounted in the system
548 AttachedMedia ret( findAttachedMedia( media));
549 if( !ret.mediaSource )
550 {
551 forceRelaseAllMedia( media, false );
552 if ( openTray( it->name ) )
553 {
554#if REPORT_EJECT_ERRORS
555 ejected = true;
556#endif
557 break; // on 1st success
558 }
559 }
560 }
561 }
562#if REPORT_EJECT_ERRORS
563 if( !ejected)
564 {
566 }
567#endif
568 }
569
571 //
572 // METHOD NAME : MediaCD::isAttached
573 // METHOD TYPE : bool
574 //
575 // DESCRIPTION : Override check if media is attached.
576 //
577 bool
579 {
580 return checkAttached(false);
581 }
582
584 //
585 // METHOD NAME : MediaCD::getFile
586 // METHOD TYPE : PMError
587 //
588 // DESCRIPTION : Asserted that media is attached.
589 //
590 void MediaCD::getFile( const OnMediaLocation &file ) const
591 {
592 MediaHandler::getFile( file );
593 }
594
596 //
597 // METHOD NAME : MediaCD::getDir
598 // METHOD TYPE : PMError
599 //
600 // DESCRIPTION : Asserted that media is attached.
601 //
602 void MediaCD::getDir( const Pathname & dirname, bool recurse_r ) const
603 {
604 MediaHandler::getDir( dirname, recurse_r );
605 }
606
608 //
609 //
610 // METHOD NAME : MediaCD::getDirInfo
611 // METHOD TYPE : PMError
612 //
613 // DESCRIPTION : Asserted that media is attached and retlist is empty.
614 //
615 void MediaCD::getDirInfo( std::list<std::string> & retlist,
616 const Pathname & dirname, bool dots ) const
617 {
618 MediaHandler::getDirInfo( retlist, dirname, dots );
619 }
620
622 //
623 //
624 // METHOD NAME : MediaCD::getDirInfo
625 // METHOD TYPE : PMError
626 //
627 // DESCRIPTION : Asserted that media is attached and retlist is empty.
628 //
629 void MediaCD::getDirInfo( filesystem::DirContent & retlist, const Pathname & dirname, bool dots ) const
630 {
631 MediaHandler::getDirInfo( retlist, dirname, dots );
632 }
633
634
635 bool MediaCD::getDoesFileExist( const Pathname & filename ) const
636 {
637 return MediaHandler::getDoesFileExist( filename );
638 }
639
640
642 {
643 if (_devices.size() == 0)
644 return false;
645 else if (_lastdev_tried < 0)
646 return true;
647
648 return (unsigned) _lastdev_tried < _devices.size() - 1;
649 }
650
651
652 void MediaCD::getDetectedDevices( std::vector<std::string> & devices, unsigned int & index ) const
653 {
654 if ( ! devices.empty() )
655 devices.clear();
656
657 if ( _devices.empty() )
658 // This also fills the _devices list on demand
659 detectDevices( _url.getScheme() == "dvd" ? true : false );
660
661 for ( const auto & it : _devices )
662 devices.push_back( it.name );
663
664 index = ( _lastdev >= 0 ? (unsigned)_lastdev : 0 );
665
666 MIL << "got " << devices.size() << " detected devices, current: "
667 << (index < devices.size() ? devices[index] : "<none>")
668 << "(" << index << ")" << endl;
669 }
670
671 } // namespace media
673} // namespace zypp
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition: AutoDispose.h:94
Base class for Exception.
Definition: Exception.h:146
Describes a resource file located on a medium.
Url manipulation class.
Definition: Url.h:92
std::string getScheme() const
Returns the scheme name of the URL.
Definition: Url.cc:533
std::string asString() const
Returns a default string representation of the Url object.
Definition: Url.cc:497
std::string getQueryParam(const std::string &param, EEncoding eflag=zypp::url::E_DECODED) const
Return the value for the specified query parameter.
Definition: Url.cc:660
Wrapper class for stat/lstat.
Definition: PathInfo.h:221
const Pathname & path() const
Return current Pathname.
Definition: PathInfo.h:246
unsigned int devMinor() const
Definition: PathInfo.cc:251
unsigned int devMajor() const
Definition: PathInfo.cc:241
const std::string & asString() const
String representation.
Definition: Pathname.h:91
Attach point of a media source.
Definition: MediaSource.h:106
static bool openTray(const std::string &device_r)
Definition: cdtools.cc:33
static bool closeTray(const std::string &device_r)
Definition: cdtools.cc:86
static bool closeTray(const std::string &device_r)
Definition: MediaCD.cc:188
virtual bool isAttached() const override
True if media is attached.
Definition: MediaCD.cc:578
virtual void forceEject(const std::string &ejectDev) override
Call concrete handler to physically eject the media (i.e.
Definition: MediaCD.cc:521
virtual void getDirInfo(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const override
Call concrete handler to provide a content list of directory on media via retlist.
Definition: MediaCD.cc:615
virtual void getDetectedDevices(std::vector< std::string > &devices, unsigned int &index) const override
Fill in a vector of detected ejectable devices and the index of the currently attached device within ...
Definition: MediaCD.cc:652
std::list< MediaSource > DeviceList
Definition: MediaCD.h:31
MediaCD(const Url &url_r, const Pathname &attach_point_hint_r)
Definition: MediaCD.cc:130
virtual void getFile(const OnMediaLocation &file) const override
Call concrete handler to provide file below attach point.
Definition: MediaCD.cc:590
virtual void getDir(const Pathname &dirname, bool recurse_r) const override
Call concrete handler to provide directory content (not recursive!) below attach point.
Definition: MediaCD.cc:602
virtual void releaseFrom(const std::string &ejectDev) override
Call concrete handler to release the media.
Definition: MediaCD.cc:479
virtual bool getDoesFileExist(const Pathname &filename) const override
check if a file exists
Definition: MediaCD.cc:635
int _lastdev
number of last successful mounted device in list
Definition: MediaCD.h:36
static bool openTray(const std::string &device_r)
Definition: MediaCD.cc:177
DeviceList detectDevices(bool supportingDVD) const
Definition: MediaCD.cc:194
virtual bool hasMoreDevices() override
Check if the media has one more device available for attach(true).
Definition: MediaCD.cc:641
DeviceList _devices
list of devices to try to mount
Definition: MediaCD.h:33
virtual void attachTo(bool next=false) override
Call concrete handler to attach the media.
Definition: MediaCD.cc:270
Just inherits Exception to separate media exceptions.
Abstract base class for 'physical' MediaHandler like MediaCD, etc.
Definition: MediaHandler.h:51
bool isUseableAttachPoint(const Pathname &path, bool mtab=true) const
Ask media manager, if the specified path is already used as attach point or if there are another atta...
virtual void getFile(const OnMediaLocation &file) const
Call concrete handler to provide file below attach point.
Url url() const
Url used.
Definition: MediaHandler.h:503
virtual bool getDoesFileExist(const Pathname &filename) const =0
check if a file exists
Pathname createAttachPoint() const
Try to create a default / temporary attach point.
void setMediaSource(const MediaSourceRef &ref)
Set new media source reference.
void forceRelaseAllMedia(bool matchMountFs)
Call to this function will try to release all media matching the currenlty attached media source,...
const Url _url
Url to handle.
Definition: MediaHandler.h:113
bool checkAttached(bool matchMountFs) const
Check actual mediaSource attachment against the current mount table of the system.
void removeAttachPoint()
Remove unused attach point.
void setAttachPoint(const Pathname &path, bool temp)
Set a new attach point.
Pathname attachPoint() const
Return the currently used attach point.
virtual void getDir(const Pathname &dirname, bool recurse_r) const =0
Call concrete handler to provide directory content (not recursive!) below attach point.
AttachedMedia findAttachedMedia(const MediaSourceRef &media) const
Ask the media manager if specified media source is already attached.
AttachedMedia attachedMedia() const
Returns the attached media.
virtual void getDirInfo(std::list< std::string > &retlist, const Pathname &dirname, bool dots=true) const =0
Call concrete handler to provide a content list of directory on media via retlist.
Manages access to the 'physical' media, e.g CDROM drives, Disk volumes, directory trees,...
Definition: MediaManager.h:454
static std::vector< MountEntry > getMountEntries()
Get current mount entries from /etc/mtab file.
const std::string & mountError() const
const std::string & mountOutput() const
Media source internally used by MediaManager and MediaHandler.
Definition: MediaSource.h:37
unsigned int min_nr
A minor number if source is a device.
Definition: MediaSource.h:90
unsigned int maj_nr
A major number if source is a device.
Definition: MediaSource.h:89
std::string name
A media handler specific source name.
Definition: MediaSource.h:92
virtual bool equals(const MediaSource &src) const
Check if the both sources are equal.
Definition: MediaSource.h:62
Interface to the mount program.
Definition: mount.h:75
void umount(const std::string &path)
umount device
Definition: mount.cc:117
void mount(const std::string &source, const std::string &target, const std::string &filesystem, const std::string &options, const Environment &environment=Environment())
mount device
Definition: mount.cc:62
std::list< DirEntry > DirContent
Returned by readdir.
Definition: PathInfo.h:518
zypp::RW_pointer< MediaSource > MediaSourceRef
Definition: MediaSource.h:124
unsigned split(const C_Str &line_r, TOutputIterator result_r, const C_Str &sepchars_r=" \t", const Trim trim_r=NO_TRIM)
Split line_r into words.
Definition: String.h:531
Easy-to use interface to the ZYPP dependency resolver.
Definition: CodePitfalls.doc:2
A simple structure containing references to a media source and its attach point.
Definition: MediaSource.h:134
MediaSourceRef mediaSource
Definition: MediaSource.h:144
AttachPointRef attachPoint
Definition: MediaSource.h:145
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
Definition: Easy.h:28
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
Definition: Exception.h:440
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
Definition: Exception.h:436
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition: Exception.h:428
#define DBG
Definition: Logger.h:95
#define MIL
Definition: Logger.h:96
#define ERR
Definition: Logger.h:98
#define WAR
Definition: Logger.h:97