15#include <linux/cdrom.h> 
   27#include <zypp-media/Mount> 
   28#include <zypp-media/CDTools> 
   39#define  REPORT_EJECT_ERRORS     0 
   52      using DeviceList = std::list<MediaSource>;
 
   59      DeviceList systemDetectDevices( 
bool supportingDVD_r )
 
   68          ERR << 
"Can't create udev context." << endl;
 
   75          ERR << 
"Can't create udev list entry." << endl;
 
   79        ::udev_enumerate_add_match_subsystem( enumerate, 
"block" );
 
   80        ::udev_enumerate_add_match_property( enumerate, 
"ID_CDROM", 
"1" );
 
   81        ::udev_enumerate_scan_devices( enumerate );
 
   83        struct udev_list_entry * entry = 0;
 
   84        udev_list_entry_foreach( entry, ::udev_enumerate_get_list_entry( enumerate ) )
 
   87                                                                                          ::udev_list_entry_get_name( entry ) ),
 
   88                                                          ::udev_device_unref );
 
   91            ERR << 
"Can't create udev device." << endl;
 
   95          if ( supportingDVD_r && ! ::udev_device_get_property_value( device, 
"ID_CDROM_DVD" ) )
 
  100          const char * devnodePtr( ::udev_device_get_devnode( device ) );
 
  103            ERR << 
"Got NULL devicenode." << endl;
 
  110          PathInfo devnode( devnodePtr );
 
  111          if ( devnode.isBlk() )
 
  113            MediaSource media( 
"cdrom", devnode.path().asString(), devnode.devMajor(), devnode.devMinor() );
 
  114            DBG << 
"Found (udev): " << media << std::endl;
 
  115            detected.push_back( media );
 
  118        if ( detected.empty() )
 
  120          WAR << 
"Did not find any CD/DVD device." << endl;
 
  131      : 
MediaHandler( origin_r, attach_point_hint_r, origin_r.authority().
url().getPathName(), false )
 
  135      MIL << 
"MediaCD::MediaCD(" << 
url() << 
", " << attach_point_hint_r << 
")" << endl;
 
  137    const auto &authorityUrl = 
_origin.authority().url();
 
  140      ERR << 
"Unsupported schema in the Url: " << authorityUrl.asString() << endl;
 
  144    std::string devices = authorityUrl.getQueryParam( 
"devices" );
 
  145    if ( ! devices.empty() )
 
  147      std::vector<std::string> words;
 
  148      str::split( devices, std::back_inserter(words), 
"," );
 
  149      for ( 
const std::string & device : words )
 
  151        if ( device.empty() )
 
  156        DBG << 
"use device (delayed verify)" << device << endl;
 
  161      DBG << 
"going to use on-demand device list" << endl;
 
  167      ERR << 
"Unable to find any cdrom drive for " << authorityUrl.asString() << endl;
 
 
  197    DeviceList detected( systemDetectDevices( supportingDVD_r ) );
 
  199    if ( detected.empty() )
 
  201      WAR << 
"CD/DVD drive detection with UDEV failed! Guessing..." << std::endl;
 
  204      if ( dvdinfo.
isBlk() )
 
  207        DBG << 
"Found (GUESS): " << 
media << std::endl;
 
  208        detected.push_back( 
media );
 
  214        DBG << 
"Found (GUESS): " << 
media << std::endl;
 
  215        detected.push_back( 
media );
 
  224      DBG << 
"creating on-demand device list" << endl;
 
  226      std::string device( 
"/dev/cdrom" );
 
  236        if ( detected.empty() )
 
  242          for( 
const auto & d : detected )
 
  245            if ( 
media.equals( d ) )
 
 
  277    const auto &authorityUrl = 
_origin.authority().url();
 
  285    std::string options = authorityUrl.getQueryParam( 
"mountoptions" );
 
  286    if ( options.empty() )
 
  292    std::list<std::string> filesystems;
 
  294    filesystems.push_back(
"iso9660");
 
  297    if ( authorityUrl.getScheme() == 
"dvd" )
 
  298      filesystems.push_back(
"udf");
 
  303    bool mountsucceeded = 
false;
 
  304    for ( DeviceList::iterator it = 
_devices.begin() ; ! mountsucceeded && it != 
_devices.end() ; ++it, ++count )
 
  306      DBG << 
"count " << count << endl;
 
  309        DBG << 
"skipping device " << it->name << endl;
 
  319      if ( ! dinfo.
isBlk() )
 
  321        WAR <<  
"skipping non block device: " << dinfo << endl;
 
  324      DBG << 
"trying device " << dinfo << endl;
 
  334        DBG << 
"Using a shared media " 
  343        mountsucceeded = 
true;
 
  350        MountEntries::const_iterator e;
 
  351        for( e = entries.begin(); e != entries.end(); ++e)
 
  353          bool        is_device = 
false;
 
  357          if( dev_path.compare(0, 
sizeof(
"/dev/")-1, 
"/dev/") == 0 &&
 
  358              dev_info(e->src) && dev_info.
isBlk())
 
  369              DBG << 
"Using a system mounted media " 
  380              mountsucceeded = 
true;
 
  393      for(std::list<std::string>::iterator fsit = filesystems.begin()
 
  394          ; !mountsucceeded && fsit != filesystems.end()
 
  405          mount.
mount(it->name, mountpoint, *fsit, options);
 
  412          while( !(mountsucceeded=
isAttached()) && --limit)
 
  414            WAR << 
"Wait for /proc/mounts update and retry...." << endl;
 
  434              "Unable to verify that the media was mounted",
 
  460                                       authorityUrl.asString(),
 
  467                                       authorityUrl.asString(), mountpoint));
 
 
  494      if (!ejectDev.empty())
 
  504    if (!ejectDev.empty())
 
  509#if REPORT_EJECT_ERRORS 
 
  526#if REPORT_EJECT_ERRORS 
  527    bool ejected = 
false;
 
  536        if ( 
media->name != ejectDev_r )
 
  543        if( ! dinfo.
isBlk() )
 
  545          WAR <<  
"skipping non block device: " << dinfo << endl;
 
  548        DBG << 
"trying device " << dinfo << endl;
 
  557#if REPORT_EJECT_ERRORS 
  565#if REPORT_EJECT_ERRORS 
 
  619                            const Pathname & dirname, 
bool dots )
 const 
 
  657    if ( ! devices.empty() )
 
  665      devices.push_back( it.name );
 
  669    MIL << 
"got " << devices.size() << 
" detected devices, current: " 
  670        << (index < devices.size() ? devices[index] : 
"<none>")
 
  671        << 
"(" << index << 
")" << endl;
 
 
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Base class for Exception.
Manages a data source characterized by an authoritative URL and a list of mirror URLs.
Wrapper class for stat/lstat.
const Pathname & path() const
Return current Pathname.
unsigned int devMinor() const
unsigned int devMajor() const
const std::string & asString() const
String representation.
std::list< DirEntry > DirContent
Returned by readdir.
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.
Easy-to use interface to the ZYPP dependency resolver.
std::string asString(const Patch::Category &obj)
#define for_(IT, BEG, END)
Convenient for-loops using iterator.
#define ZYPP_RETHROW(EXCPT)
Drops a logline and rethrows, updating the CodeLocation.
#define ZYPP_CAUGHT(EXCPT)
Drops a logline telling the Exception was caught (in order to handle it).
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.