|
libzypp
9.1.2
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00012 extern "C" 00013 { 00014 #include <sys/ioctl.h> 00015 #include <linux/cdrom.h> 00016 #if HAVE_UDEV 00017 #include <libudev.h> 00018 #endif 00019 } 00020 00021 #ifndef HAVE_UDEV 00022 #if HAVE_HAL 00023 #include "zypp/target/hal/HalContext.h" 00024 #endif 00025 #endif 00026 00027 #include <cstring> // strerror 00028 #include <cstdlib> // getenv 00029 #include <iostream> 00030 00031 #include "zypp/base/Logger.h" 00032 #include "zypp/ExternalProgram.h" 00033 #include "zypp/media/Mount.h" 00034 #include "zypp/media/MediaCD.h" 00035 #include "zypp/media/MediaManager.h" 00036 #include "zypp/Url.h" 00037 #include "zypp/AutoDispose.h" 00038 00039 00040 00041 /* 00042 ** if to throw exception on eject errors or ignore them 00043 */ 00044 #define REPORT_EJECT_ERRORS 1 00045 00046 /* 00047 ** If defined to the full path of the eject utility, 00048 ** it will be used additionally to the eject-ioctl. 00049 */ 00050 #define EJECT_TOOL_PATH "/bin/eject" 00051 00052 00053 using namespace std; 00054 00055 namespace zypp { 00056 namespace media { 00057 00059 // 00060 // CLASS NAME : MediaCD 00061 // 00063 00064 00066 // 00067 // 00068 // METHOD NAME : MediaCD::MediaCD 00069 // METHOD TYPE : Constructor 00070 // 00071 // DESCRIPTION : 00072 // 00073 MediaCD::MediaCD( const Url & url_r, 00074 const Pathname & attach_point_hint_r ) 00075 : MediaHandler( url_r, attach_point_hint_r, 00076 url_r.getPathName(), // urlpath below attachpoint 00077 false ), 00078 _lastdev(-1), _lastdev_tried(-1) 00079 { 00080 MIL << "MediaCD::MediaCD(" << url_r << ", " << attach_point_hint_r << ")" 00081 << endl; 00082 00083 if( url_r.getScheme() != "dvd" && url_r.getScheme() != "cd") 00084 { 00085 ERR << "Unsupported schema in the Url: " << url_r.asString() << endl; 00086 ZYPP_THROW(MediaUnsupportedUrlSchemeException(_url)); 00087 } 00088 00089 string devices = _url.getQueryParam("devices"); 00090 if (!devices.empty()) 00091 { 00092 string::size_type pos; 00093 DBG << "parse " << devices << endl; 00094 while(!devices.empty()) 00095 { 00096 pos = devices.find(','); 00097 string device = devices.substr(0,pos); 00098 if (!device.empty()) 00099 { 00100 MediaSource media("cdrom", device, 0, 0); 00101 _devices.push_back( media); 00102 DBG << "use device (delayed verify)" << device << endl; 00103 } 00104 if (pos!=string::npos) 00105 devices=devices.substr(pos+1); 00106 else 00107 devices.erase(); 00108 } 00109 } 00110 else 00111 { 00112 DBG << "going to use on-demand device list" << endl; 00113 return; 00114 } 00115 00116 if( _devices.empty()) 00117 { 00118 ERR << "Unable to find any cdrom drive for " << _url.asString() << endl; 00119 ZYPP_THROW(MediaBadUrlEmptyDestinationException(_url)); 00120 } 00121 } 00122 00124 // 00125 // 00126 // METHOD NAME : MediaCD::openTray 00127 // METHOD TYPE : bool 00128 // 00129 bool MediaCD::openTray( const std::string & device_r ) 00130 { 00131 int fd = ::open( device_r.c_str(), O_RDONLY|O_NONBLOCK ); 00132 int res = -1; 00133 00134 if ( fd != -1) 00135 { 00136 res = ::ioctl( fd, CDROMEJECT ); 00137 ::close( fd ); 00138 } 00139 00140 if ( res ) 00141 { 00142 if( fd == -1) 00143 { 00144 WAR << "Unable to open '" << device_r 00145 << "' (" << ::strerror( errno ) << ")" << endl; 00146 } 00147 else 00148 { 00149 WAR << "Eject " << device_r 00150 << " failed (" << ::strerror( errno ) << ")" << endl; 00151 } 00152 00153 #if defined(EJECT_TOOL_PATH) 00154 DBG << "Try to eject " << device_r << " using " 00155 << EJECT_TOOL_PATH << " utility" << std::endl; 00156 00157 const char *cmd[3]; 00158 cmd[0] = EJECT_TOOL_PATH; 00159 cmd[1] = device_r.c_str(); 00160 cmd[2] = NULL; 00161 ExternalProgram eject(cmd, ExternalProgram::Stderr_To_Stdout); 00162 00163 for(std::string out( eject.receiveLine()); 00164 out.length(); out = eject.receiveLine()) 00165 { 00166 DBG << " " << out; 00167 } 00168 00169 if(eject.close() != 0) 00170 { 00171 WAR << "Eject of " << device_r << " failed." << std::endl; 00172 return false; 00173 } 00174 #else 00175 return false; 00176 #endif 00177 } 00178 MIL << "Eject of " << device_r << " successful." << endl; 00179 return true; 00180 } 00181 00183 // 00184 // 00185 // METHOD NAME : MediaCD::closeTray 00186 // METHOD TYPE : bool 00187 // 00188 bool MediaCD::closeTray( const std::string & device_r ) 00189 { 00190 int fd = ::open( device_r.c_str(), O_RDONLY|O_NONBLOCK ); 00191 if ( fd == -1 ) { 00192 WAR << "Unable to open '" << device_r << "' (" << ::strerror( errno ) << ")" << endl; 00193 return false; 00194 } 00195 int res = ::ioctl( fd, CDROMCLOSETRAY ); 00196 ::close( fd ); 00197 if ( res ) { 00198 WAR << "Close tray " << device_r << " failed (" << ::strerror( errno ) << ")" << endl; 00199 return false; 00200 } 00201 DBG << "Close tray " << device_r << endl; 00202 return true; 00203 } 00204 00206 // 00207 // 00208 // METHOD NAME : MediaCD::detectDevices 00209 // METHOD TYPE : MediaCD::DeviceList 00210 // 00211 MediaCD::DeviceList MediaCD::detectDevices( bool supportingDVD ) const 00212 { 00213 DeviceList detected; 00214 #ifdef HAVE_UDEV 00215 // http://www.kernel.org/pub/linux/utils/kernel/hotplug/libudev/index.html 00216 zypp::AutoDispose<struct udev *> udev( ::udev_new(), ::udev_unref ); 00217 if ( ! udev ) 00218 { 00219 ERR << "Can't create udev context." << endl; 00220 return DeviceList(); 00221 } 00222 00223 zypp::AutoDispose<struct udev_enumerate *> enumerate( ::udev_enumerate_new(udev), ::udev_enumerate_unref ); 00224 if ( ! enumerate ) 00225 { 00226 ERR << "Can't create udev list entry." << endl; 00227 return DeviceList(); 00228 } 00229 00230 ::udev_enumerate_add_match_subsystem( enumerate, "block" ); 00231 ::udev_enumerate_add_match_property( enumerate, "ID_CDROM", "1" ); 00232 ::udev_enumerate_scan_devices( enumerate ); 00233 00234 struct udev_list_entry * entry = 0; 00235 udev_list_entry_foreach( entry, ::udev_enumerate_get_list_entry( enumerate ) ) 00236 { 00237 zypp::AutoDispose<struct udev_device *> device( ::udev_device_new_from_syspath( ::udev_enumerate_get_udev( enumerate ), 00238 ::udev_list_entry_get_name( entry ) ), 00239 ::udev_device_unref ); 00240 if ( ! device ) 00241 { 00242 ERR << "Can't create udev device." << endl; 00243 continue; 00244 } 00245 00246 if ( supportingDVD && ! ::udev_device_get_property_value( device, "ID_CDROM_DVD" ) ) 00247 { 00248 continue; // looking for dvd only 00249 } 00250 00251 const char * devnodePtr( ::udev_device_get_devnode( device ) ); 00252 if ( ! devnodePtr ) 00253 { 00254 ERR << "Got NULL devicenode." << endl; 00255 continue; 00256 } 00257 00258 // In case we need it someday: 00259 //const char * mountpath = ::udev_device_get_property_value( device, "FSTAB_DIR" ); 00260 00261 PathInfo devnode( devnodePtr ); 00262 if ( devnode.isBlk() ) 00263 { 00264 MediaSource media( "cdrom", devnode.path().asString(), devnode.major(), devnode.minor() ); 00265 DBG << "Found (udev): " << media << std::endl; 00266 detected.push_back( media ); 00267 } 00268 } 00269 if ( detected.empty() ) 00270 WAR << "Did not find any CD/DVD device." << endl; 00271 #elif HAVE_HAL 00272 using namespace zypp::target::hal; 00273 try 00274 { 00275 HalContext hal(true); 00276 00277 std::vector<std::string> drv_udis; 00278 drv_udis = hal.findDevicesByCapability("storage.cdrom"); 00279 00280 DBG << "Found " << drv_udis.size() << " cdrom drive udis" << std::endl; 00281 for(size_t d = 0; d < drv_udis.size(); d++) 00282 { 00283 HalDrive drv( hal.getDriveFromUDI( drv_udis[d])); 00284 00285 if( drv) 00286 { 00287 bool supportsDVD=false; 00288 if( supportingDVD) 00289 { 00290 std::vector<std::string> caps; 00291 try { 00292 caps = drv.getCdromCapabilityNames(); 00293 } 00294 catch(const HalException &e) 00295 { 00296 ZYPP_CAUGHT(e); 00297 } 00298 00299 std::vector<std::string>::const_iterator ci; 00300 for( ci=caps.begin(); ci != caps.end(); ++ci) 00301 { 00302 if( *ci == "dvd") 00303 supportsDVD = true; 00304 } 00305 } 00306 00307 MediaSource media("cdrom", drv.getDeviceFile(), 00308 drv.getDeviceMajor(), 00309 drv.getDeviceMinor()); 00310 DBG << "Found " << drv_udis[d] << ": " 00311 << media.asString() << std::endl; 00312 if( supportingDVD && supportsDVD) 00313 { 00314 detected.push_front(media); 00315 } 00316 else 00317 { 00318 detected.push_back(media); 00319 } 00320 } 00321 } 00322 } 00323 catch(const zypp::target::hal::HalException &e) 00324 { 00325 ZYPP_CAUGHT(e); 00326 } 00327 #else // manual way 00328 #warning Poor CDROM devices detection without udev/HAL 00329 WAR << "Cdrom drive detection without HAL! " << std::endl; 00330 PathInfo dvdinfo( "/dev/dvd" ); 00331 PathInfo cdrinfo( "/dev/cdrom" ); 00332 if ( dvdinfo.isBlk() ) 00333 { 00334 MediaSource media( "cdrom", dvdinfo.path().asString(), dvdinfo.major(), dvdinfo.minor() ); 00335 DBG << "Found (NO_HAL): " << media << std::endl; 00336 detected.push_back( media ); 00337 } 00338 if ( cdrinfo.isBlk() 00339 && ! ( cdrinfo.major() == dvdinfo.major() && cdrinfo.minor() == dvdinfo.minor() ) ) 00340 { 00341 MediaSource media( "cdrom", cdrinfo.path().asString(), cdrinfo.major(), cdrinfo.minor() ); 00342 DBG << "Found (NO_HAL): " << media << std::endl; 00343 detected.push_back( media ); 00344 } 00345 #endif 00346 return detected; 00347 } 00348 00349 00351 // 00352 // 00353 // METHOD NAME : MediaCD::attachTo 00354 // METHOD TYPE : PMError 00355 // 00356 // DESCRIPTION : Asserted that not already attached, and attachPoint is a directory. 00357 // 00358 void MediaCD::attachTo(bool next) 00359 { 00360 DBG << "next " << next << " last " << _lastdev << " last tried " << _lastdev_tried << endl; 00361 if (next && _lastdev == -1) 00362 ZYPP_THROW(MediaNotSupportedException(url())); 00363 00364 DeviceList detected( 00365 detectDevices(_url.getScheme() == "dvd" ? true : false)); 00366 00367 if(_devices.empty()) 00368 { 00369 DBG << "creating on-demand device list" << endl; 00370 //default is /dev/cdrom; for dvd: /dev/dvd if it exists 00371 string device( "/dev/cdrom" ); 00372 if ( _url.getScheme() == "dvd" && PathInfo( "/dev/dvd" ).isBlk() ) 00373 { 00374 device = "/dev/dvd"; 00375 } 00376 00377 PathInfo dinfo(device); 00378 if( dinfo.isBlk()) 00379 { 00380 MediaSource media("cdrom", device, dinfo.major(), dinfo.minor()); 00381 00382 DeviceList::const_iterator d( detected.begin()); 00383 for( ; d != detected.end(); ++d) 00384 { 00385 // /dev/cdrom or /dev/dvd to the front 00386 if( media.equals( *d)) 00387 _devices.push_front( *d); 00388 else 00389 _devices.push_back( *d); 00390 } 00391 } 00392 else 00393 { 00394 // no /dev/cdrom or /dev/dvd link 00395 _devices = detected; 00396 } 00397 } 00398 00399 Mount mount; 00400 string mountpoint = attachPoint().asString(); 00401 bool mountsucceeded = false; 00402 int count = 0; 00403 MediaMountException merr; 00404 00405 string options = _url.getQueryParam("mountoptions"); 00406 if (options.empty()) 00407 { 00408 options="ro"; 00409 } 00410 00411 //TODO: make configurable 00412 list<string> filesystems; 00413 00414 // if DVD, try UDF filesystem before iso9660 00415 if ( _url.getScheme() == "dvd" ) 00416 filesystems.push_back("udf"); 00417 00418 filesystems.push_back("iso9660"); 00419 00420 // try all devices in sequence 00421 for (DeviceList::iterator it = _devices.begin() 00422 ; !mountsucceeded && it != _devices.end() 00423 ; ++it, count++ ) 00424 { 00425 DBG << "count " << count << endl; 00426 if (next && count <=_lastdev_tried ) 00427 { 00428 DBG << "skipping device " << it->name << endl; 00429 continue; 00430 } 00431 00432 _lastdev_tried = count; 00433 00434 MediaSource temp( *it); 00435 bool valid=false; 00436 PathInfo dinfo(temp.name); 00437 if( dinfo.isBlk()) 00438 { 00439 temp.maj_nr = dinfo.major(); 00440 temp.min_nr = dinfo.minor(); 00441 00442 DeviceList::const_iterator d( detected.begin()); 00443 for( ; d != detected.end(); ++d) 00444 { 00445 if( temp.equals( *d)) 00446 { 00447 valid = true; 00448 break; 00449 } 00450 } 00451 } 00452 if( !valid) 00453 { 00454 DBG << "skipping invalid device: " << it->name << endl; 00455 continue; 00456 } 00457 00458 MediaSourceRef media( new MediaSource(temp)); 00459 AttachedMedia ret( findAttachedMedia( media)); 00460 00461 if( ret.mediaSource && ret.attachPoint && 00462 !ret.attachPoint->empty()) 00463 { 00464 DBG << "Using a shared media " 00465 << ret.mediaSource->name 00466 << " attached on " 00467 << ret.attachPoint->path 00468 << endl; 00469 removeAttachPoint(); 00470 setAttachPoint(ret.attachPoint); 00471 setMediaSource(ret.mediaSource); 00472 _lastdev = count; 00473 mountsucceeded = true; 00474 break; 00475 } 00476 00477 { 00478 MediaManager manager; 00479 MountEntries entries( manager.getMountEntries()); 00480 MountEntries::const_iterator e; 00481 for( e = entries.begin(); e != entries.end(); ++e) 00482 { 00483 bool is_device = false; 00484 std::string dev_path(Pathname(e->src).asString()); 00485 PathInfo dev_info; 00486 00487 if( dev_path.compare(0, sizeof("/dev/")-1, "/dev/") == 0 && 00488 dev_info(e->src) && dev_info.isBlk()) 00489 { 00490 is_device = true; 00491 } 00492 00493 if( is_device && media->maj_nr == dev_info.major() && 00494 media->min_nr == dev_info.minor()) 00495 { 00496 AttachPointRef ap( new AttachPoint(e->dir, false)); 00497 AttachedMedia am( media, ap); 00498 { 00499 DBG << "Using a system mounted media " 00500 << media->name 00501 << " attached on " 00502 << ap->path 00503 << endl; 00504 00505 media->iown = false; // mark attachment as foreign 00506 00507 setMediaSource(media); 00508 setAttachPoint(ap); 00509 _lastdev = count; 00510 mountsucceeded = true; 00511 break; 00512 } 00513 } 00514 } 00515 if( mountsucceeded) 00516 break; 00517 } 00518 00519 // close tray 00520 closeTray( it->name ); 00521 00522 // try all filesystems in sequence 00523 for(list<string>::iterator fsit = filesystems.begin() 00524 ; !mountsucceeded && fsit != filesystems.end() 00525 ; ++fsit) 00526 { 00527 try 00528 { 00529 if( !isUseableAttachPoint(Pathname(mountpoint))) 00530 { 00531 mountpoint = createAttachPoint().asString(); 00532 setAttachPoint( mountpoint, true); 00533 if( mountpoint.empty()) 00534 { 00535 ZYPP_THROW( MediaBadAttachPointException(url())); 00536 } 00537 } 00538 00539 mount.mount(it->name, mountpoint, *fsit, options); 00540 00541 setMediaSource(media); 00542 00543 // wait for /etc/mtab update ... 00544 // (shouldn't be needed) 00545 int limit = 5; 00546 while( !(mountsucceeded=isAttached()) && --limit) 00547 { 00548 sleep(1); 00549 } 00550 00551 if( mountsucceeded) 00552 { 00553 _lastdev = count; 00554 } 00555 else 00556 { 00557 setMediaSource(MediaSourceRef()); 00558 try 00559 { 00560 mount.umount(attachPoint().asString()); 00561 } 00562 catch (const MediaException & excpt_r) 00563 { 00564 ZYPP_CAUGHT(excpt_r); 00565 } 00566 ZYPP_THROW(MediaMountException( 00567 "Unable to verify that the media was mounted", 00568 it->name, mountpoint 00569 )); 00570 } 00571 } 00572 catch (const MediaMountException &e) 00573 { 00574 merr = e; 00575 removeAttachPoint(); 00576 ZYPP_CAUGHT(e); 00577 } 00578 catch (const MediaException & excpt_r) 00579 { 00580 removeAttachPoint(); 00581 ZYPP_CAUGHT(excpt_r); 00582 } 00583 } // for filesystems 00584 } // for _devices 00585 00586 if (!mountsucceeded) 00587 { 00588 _lastdev = -1; 00589 00590 if( !merr.mountOutput().empty()) 00591 { 00592 ZYPP_THROW(MediaMountException(merr.mountError(), 00593 _url.asString(), 00594 mountpoint, 00595 merr.mountOutput())); 00596 } 00597 else 00598 { 00599 ZYPP_THROW(MediaMountException("Mounting media failed", 00600 _url.asString(), mountpoint)); 00601 } 00602 } 00603 DBG << _lastdev << " " << count << endl; 00604 } 00605 00606 00608 // 00609 // 00610 // METHOD NAME : MediaCD::releaseFrom 00611 // METHOD TYPE : PMError 00612 // 00613 // DESCRIPTION : Asserted that media is attached. 00614 // 00615 void MediaCD::releaseFrom( const std::string & ejectDev ) 00616 { 00617 Mount mount; 00618 try 00619 { 00620 AttachedMedia am( attachedMedia()); 00621 if(am.mediaSource && am.mediaSource->iown) 00622 mount.umount(am.attachPoint->path.asString()); 00623 } 00624 catch (const Exception & excpt_r) 00625 { 00626 ZYPP_CAUGHT(excpt_r); 00627 if (!ejectDev.empty()) 00628 { 00629 forceRelaseAllMedia(false); 00630 if(openTray( ejectDev )) 00631 return; 00632 } 00633 ZYPP_RETHROW(excpt_r); 00634 } 00635 00636 // eject device 00637 if (!ejectDev.empty()) 00638 { 00639 forceRelaseAllMedia(false); 00640 if( !openTray( ejectDev )) 00641 { 00642 #if REPORT_EJECT_ERRORS 00643 ZYPP_THROW(MediaNotEjectedException(ejectDev)); 00644 #endif 00645 } 00646 } 00647 } 00648 00650 // 00651 // 00652 // METHOD NAME : MediaCD::forceEject 00653 // METHOD TYPE : void 00654 // 00655 // Asserted that media is not attached. 00656 // 00657 void MediaCD::forceEject(const std::string & ejectDev) 00658 { 00659 bool ejected=false; 00660 if ( !isAttached()) { // no device mounted in this instance 00661 00662 DeviceList detected( 00663 detectDevices(_url.getScheme() == "dvd" ? true : false)); 00664 00665 if(_devices.empty()) 00666 { 00667 DBG << "creating on-demand device list" << endl; 00668 //default is /dev/cdrom; for dvd: /dev/dvd if it exists 00669 string device( "/dev/cdrom" ); 00670 if ( _url.getScheme() == "dvd" && PathInfo( "/dev/dvd" ).isBlk() ) { 00671 device = "/dev/dvd"; 00672 } 00673 00674 PathInfo dinfo(device); 00675 if( dinfo.isBlk()) 00676 { 00677 MediaSource media("cdrom", device, dinfo.major(), dinfo.minor()); 00678 00679 DeviceList::const_iterator d( detected.begin()); 00680 for( ; d != detected.end(); ++d) 00681 { 00682 // /dev/cdrom or /dev/dvd to the front 00683 if( media.equals( *d)) 00684 _devices.push_front( *d); 00685 else 00686 _devices.push_back( *d); 00687 } 00688 } 00689 else 00690 { 00691 // no /dev/cdrom or /dev/dvd link 00692 _devices = detected; 00693 } 00694 } 00695 00696 DeviceList::iterator it; 00697 for( it = _devices.begin(); it != _devices.end(); ++it ) { 00698 MediaSourceRef media( new MediaSource( *it)); 00699 if (media->name != ejectDev) 00700 continue; 00701 00702 bool valid=false; 00703 PathInfo dinfo(media->name); 00704 if( dinfo.isBlk()) 00705 { 00706 media->maj_nr = dinfo.major(); 00707 media->min_nr = dinfo.minor(); 00708 00709 DeviceList::const_iterator d( detected.begin()); 00710 for( ; d != detected.end(); ++d) 00711 { 00712 if( media->equals( *d)) 00713 { 00714 valid = true; 00715 break; 00716 } 00717 } 00718 } 00719 if( !valid) 00720 { 00721 DBG << "skipping invalid device: " << it->name << endl; 00722 continue; 00723 } 00724 00725 // FIXME: we have also to check if it is mounted in the system 00726 AttachedMedia ret( findAttachedMedia( media)); 00727 if( !ret.mediaSource) 00728 { 00729 forceRelaseAllMedia(media, false); 00730 if ( openTray( it->name ) ) 00731 { 00732 ejected = true; 00733 break; // on 1st success 00734 } 00735 } 00736 } 00737 } 00738 if( !ejected) 00739 { 00740 #if REPORT_EJECT_ERRORS 00741 ZYPP_THROW(MediaNotEjectedException()); 00742 #endif 00743 } 00744 } 00745 00747 // 00748 // METHOD NAME : MediaCD::isAttached 00749 // METHOD TYPE : bool 00750 // 00751 // DESCRIPTION : Override check if media is attached. 00752 // 00753 bool 00754 MediaCD::isAttached() const 00755 { 00756 return checkAttached(false); 00757 } 00758 00760 // 00761 // METHOD NAME : MediaCD::getFile 00762 // METHOD TYPE : PMError 00763 // 00764 // DESCRIPTION : Asserted that media is attached. 00765 // 00766 void MediaCD::getFile( const Pathname & filename ) const 00767 { 00768 MediaHandler::getFile( filename ); 00769 } 00770 00772 // 00773 // METHOD NAME : MediaCD::getDir 00774 // METHOD TYPE : PMError 00775 // 00776 // DESCRIPTION : Asserted that media is attached. 00777 // 00778 void MediaCD::getDir( const Pathname & dirname, bool recurse_r ) const 00779 { 00780 MediaHandler::getDir( dirname, recurse_r ); 00781 } 00782 00784 // 00785 // 00786 // METHOD NAME : MediaCD::getDirInfo 00787 // METHOD TYPE : PMError 00788 // 00789 // DESCRIPTION : Asserted that media is attached and retlist is empty. 00790 // 00791 void MediaCD::getDirInfo( std::list<std::string> & retlist, 00792 const Pathname & dirname, bool dots ) const 00793 { 00794 MediaHandler::getDirInfo( retlist, dirname, dots ); 00795 } 00796 00798 // 00799 // 00800 // METHOD NAME : MediaCD::getDirInfo 00801 // METHOD TYPE : PMError 00802 // 00803 // DESCRIPTION : Asserted that media is attached and retlist is empty. 00804 // 00805 void MediaCD::getDirInfo( filesystem::DirContent & retlist, 00806 const Pathname & dirname, bool dots ) const 00807 { 00808 MediaHandler::getDirInfo( retlist, dirname, dots ); 00809 } 00810 00811 bool MediaCD::getDoesFileExist( const Pathname & filename ) const 00812 { 00813 return MediaHandler::getDoesFileExist( filename ); 00814 } 00815 00816 bool MediaCD::hasMoreDevices() 00817 { 00818 if (_devices.size() == 0) 00819 return false; 00820 else if (_lastdev_tried < 0) 00821 return true; 00822 00823 return (unsigned) _lastdev_tried < _devices.size() - 1; 00824 } 00825 00826 void 00827 MediaCD::getDetectedDevices(std::vector<std::string> & devices, 00828 unsigned int & index) const 00829 { 00830 index = 0; 00831 if (!devices.empty()) 00832 devices.clear(); 00833 00834 for (DeviceList::const_iterator it = _devices.begin(); 00835 it != _devices.end(); ++it) 00836 devices.push_back(it->name); 00837 00838 if (_lastdev >= 0) 00839 index = _lastdev; 00840 00841 // try to detect again if _devices are empty (maybe this method will be 00842 // called before _devices get actually filled) 00843 if (devices.empty()) 00844 { 00845 DBG << "no device list so far, trying to detect" << endl; 00846 00847 DeviceList detected( 00848 detectDevices(_url.getScheme() == "dvd" ? true : false)); 00849 00850 for (DeviceList::const_iterator it = detected.begin(); 00851 it != detected.end(); ++it) 00852 devices.push_back(it->name); 00853 00854 // don't know which one is in use in this case 00855 index = 0; 00856 } 00857 00858 MIL << "got " << devices.size() << " detected devices, current: " 00859 << (index < devices.size() ? devices[index] : "<none>") 00860 << "(" << index << ")" << endl; 00861 } 00862 00863 00864 } // namespace media 00865 } // namespace zypp 00866 // vim: set ts=8 sts=2 sw=2 ai noet:
1.7.6.1