00001
00002
00003
00004
00005
00006
00007
00008
00013 #include <iostream>
00014 #include <fstream>
00015 #include <sstream>
00016
00017 #include "zypp/TmpPath.h"
00018 #include "zypp/Date.h"
00019 #include "zypp/base/LogTools.h"
00020 #include "zypp/base/String.h"
00021 #include "zypp/media/MediaHandler.h"
00022 #include "zypp/media/MediaManager.h"
00023 #include "zypp/media/Mount.h"
00024 #include <limits.h>
00025 #include <stdlib.h>
00026 #include <errno.h>
00027
00028
00029 using namespace std;
00030
00031
00032 #define NONREMOTE_DIRECTORY_YAST 1
00033
00034 namespace zypp {
00035 namespace media {
00036
00037 Pathname MediaHandler::_attachPrefix("");
00038
00040
00041
00042
00044
00046
00047
00048
00049
00050
00051
00052
00053 MediaHandler::MediaHandler ( const Url & url_r,
00054 const Pathname & attach_point_r,
00055 const Pathname & urlpath_below_attachpoint_r,
00056 const bool does_download_r )
00057 : _mediaSource()
00058 , _attachPoint( new AttachPoint())
00059 , _AttachPointHint()
00060 , _relativeRoot( urlpath_below_attachpoint_r)
00061 , _does_download( does_download_r )
00062 , _attach_mtime(0)
00063 , _url( url_r )
00064 , _parentId(0)
00065 {
00066 Pathname real_attach_point( getRealPath(attach_point_r.asString()));
00067
00068 if ( !real_attach_point.empty() ) {
00070
00072
00073 PathInfo adir( real_attach_point );
00074
00075
00076
00077
00078
00079
00080
00081 if ( !adir.isDir()
00082 || (_url.getScheme() != "file"
00083 && _url.getScheme() != "dir"
00084 && !real_attach_point.absolute()) )
00085 {
00086 ERR << "Provided attach point is not a absolute directory: "
00087 << adir << endl;
00088 }
00089 else {
00090 attachPointHint( real_attach_point, false);
00091 setAttachPoint( real_attach_point, false);
00092 }
00093 }
00094 }
00095
00097
00098
00099
00100
00101
00102
00103
00104 MediaHandler::~MediaHandler()
00105 {
00106 try
00107 {
00108 removeAttachPoint();
00109 }
00110 catch(...) {}
00111 }
00112
00113 void
00114 MediaHandler::resetParentId()
00115 {
00116 _parentId = 0;
00117 }
00118
00119 std::string
00120 MediaHandler::getRealPath(const std::string &path)
00121 {
00122 std::string real;
00123 if( !path.empty())
00124 {
00125 #if __GNUC__ > 2
00126
00127 char *ptr = ::realpath(path.c_str(), NULL);
00128 if( ptr != NULL)
00129 {
00130 real = ptr;
00131 free( ptr);
00132 }
00133 else
00135 if( EINVAL == errno)
00136 {
00137 char buff[PATH_MAX + 2];
00138 memset(buff, '\0', sizeof(buff));
00139 if( ::realpath(path.c_str(), buff) != NULL)
00140 {
00141 real = buff;
00142 }
00143 }
00144 #else
00145 char buff[PATH_MAX + 2];
00146 memset(buff, '\0', sizeof(buff));
00147 if( ::realpath(path.c_str(), buff) != NULL)
00148 {
00149 real = buff;
00150 }
00151 #endif
00152 }
00153 return real;
00154 }
00155
00156 zypp::Pathname
00157 MediaHandler::getRealPath(const Pathname &path)
00158 {
00159 return zypp::Pathname(getRealPath(path.asString()));
00160 }
00161
00162
00164
00165
00166
00167
00168
00169
00170
00171 void
00172 MediaHandler::removeAttachPoint()
00173 {
00174 if ( _mediaSource ) {
00175 INT << "MediaHandler deleted with media attached." << endl;
00176 return;
00177 }
00178
00179 DBG << "MediaHandler - checking if to remove attach point" << endl;
00180 if ( _attachPoint.unique() &&
00181 _attachPoint->temp &&
00182 !_attachPoint->path.empty() &&
00183 PathInfo(_attachPoint->path).isDir())
00184 {
00185 Pathname path(_attachPoint->path);
00186
00187 setAttachPoint("", true);
00188
00189 int res = recursive_rmdir( path );
00190 if ( res == 0 ) {
00191 MIL << "Deleted default attach point " << path << endl;
00192 } else {
00193 ERR << "Failed to Delete default attach point " << path
00194 << " errno(" << res << ")" << endl;
00195 }
00196 }
00197 else
00198 {
00199 if( !_attachPoint->path.empty() && !_attachPoint->temp)
00200 DBG << "MediaHandler - attachpoint is not temporary" << endl;
00201 }
00202 }
00203
00204
00206
00207
00208
00209
00210
00211
00212
00213 Pathname
00214 MediaHandler::attachPoint() const
00215 {
00216 return _attachPoint->path;
00217 }
00218
00219
00221
00222
00223
00224
00225
00226
00227
00228 void
00229 MediaHandler::setAttachPoint(const Pathname &path, bool temporary)
00230 {
00231 _attachPoint.reset( new AttachPoint(path, temporary));
00232 }
00233
00234 Pathname
00235 MediaHandler::localRoot() const
00236 {
00237 if( _attachPoint->path.empty())
00238 return Pathname();
00239 else
00240 return _attachPoint->path + _relativeRoot;
00241 }
00242
00244
00245
00246
00247
00248
00249
00250
00251 void
00252 MediaHandler::setAttachPoint(const AttachPointRef &ref)
00253 {
00254 if( ref)
00255 AttachPointRef(ref).swap(_attachPoint);
00256 else
00257 _attachPoint.reset( new AttachPoint());
00258 }
00259
00261
00262
00263
00264
00265
00266
00267
00268 void
00269 MediaHandler::attachPointHint(const Pathname &path, bool temporary)
00270 {
00271 _AttachPointHint.path = path;
00272 _AttachPointHint.temp = temporary;
00273 }
00274
00276
00277
00278
00279
00280
00281
00282
00283 AttachPoint
00284 MediaHandler::attachPointHint() const
00285 {
00286 return _AttachPointHint;
00287 }
00288
00290
00291
00292
00293
00294
00295
00296
00297 AttachedMedia
00298 MediaHandler::findAttachedMedia(const MediaSourceRef &media) const
00299 {
00300 return MediaManager().findAttachedMedia(media);
00301 }
00302
00304
00305
00306
00307
00308
00309
00310
00311 bool
00312 MediaHandler::setAttachPrefix(const Pathname &attach_prefix)
00313 {
00314 if( attach_prefix.empty())
00315 {
00316 MIL << "Reseting to built-in attach point prefixes."
00317 << std::endl;
00318 MediaHandler::_attachPrefix = attach_prefix;
00319 return true;
00320 }
00321 else
00322 if( MediaHandler::checkAttachPoint(attach_prefix, false, true))
00323 {
00324 MIL << "Setting user defined attach point prefix: "
00325 << attach_prefix << std::endl;
00326 MediaHandler::_attachPrefix = attach_prefix;
00327 return true;
00328 }
00329 return false;
00330 }
00331
00333
00334
00335
00336
00337
00338
00339
00340 Pathname
00341 MediaHandler::createAttachPoint() const
00342 {
00344
00346 const char * defmounts[] = {
00347 "/var/adm/mount", filesystem::TmpPath::defaultLocation().c_str(), NULL
00348 };
00349
00350 Pathname apoint;
00351 Pathname aroot( MediaHandler::_attachPrefix);
00352
00353 if( !aroot.empty())
00354 {
00355 apoint = createAttachPoint(aroot);
00356 }
00357 for ( const char ** def = defmounts; *def && apoint.empty(); ++def ) {
00358 aroot = *def;
00359 if( aroot.empty())
00360 continue;
00361
00362 apoint = createAttachPoint(aroot);
00363 }
00364
00365 if ( aroot.empty() ) {
00366 ERR << "Create attach point: Can't find a writable directory to create an attach point" << std::endl;
00367 return aroot;
00368 }
00369
00370 if ( !apoint.empty() ) {
00371 MIL << "Created default attach point " << apoint << std::endl;
00372 }
00373 return apoint;
00374 }
00375
00376 Pathname
00377 MediaHandler::createAttachPoint(const Pathname &attach_root) const
00378 {
00379 Pathname apoint;
00380
00381 if( attach_root.empty() || !attach_root.absolute()) {
00382 ERR << "Create attach point: invalid attach root: '"
00383 << attach_root << "'" << std::endl;
00384 return apoint;
00385 }
00386
00387 PathInfo adir( attach_root );
00388 if( !adir.isDir() || (getuid() != 0 && !adir.userMayRWX())) {
00389 DBG << "Create attach point: attach root is not a writable directory: '"
00390 << attach_root << "'" << std::endl;
00391 return apoint;
00392 }
00393
00394 static bool cleanup_once( true );
00395 if ( cleanup_once )
00396 {
00397 cleanup_once = false;
00398 DBG << "Look for orphaned attach points in " << adir << std::endl;
00399 std::list<std::string> entries;
00400 filesystem::readdir( entries, attach_root, false );
00401 for_each_( it, entries )
00402 {
00403 const std::string & entry( *it );
00404
00405 if ( ! str::hasPrefix( entry, "AP_0x" ) )
00406 continue;
00407 PathInfo sdir( attach_root + entry );
00408 if ( sdir.isDir()
00409 && sdir.dev() == adir.dev()
00410 && ( Date::now()-sdir.mtime() > Date::month ) )
00411 {
00412 DBG << "Remove orphaned attach point " << sdir << std::endl;
00413 filesystem::recursive_rmdir( sdir.path() );
00414 }
00415 }
00416 }
00417
00418 filesystem::TmpDir tmpdir( attach_root, "AP_0x" );
00419 if ( tmpdir )
00420 {
00421 apoint = getRealPath( tmpdir.path().asString() );
00422 if ( ! apoint.empty() )
00423 {
00424 tmpdir.autoCleanup( false );
00425 }
00426 else
00427 {
00428 ERR << "Unable to resolve real path for attach point " << tmpdir << std::endl;
00429 }
00430 }
00431 else
00432 {
00433 ERR << "Unable to create attach point below " << attach_root << std::endl;
00434 }
00435 return apoint;
00436 }
00437
00439
00440
00441
00442
00443
00444
00445
00446 bool
00447 MediaHandler::isUseableAttachPoint(const Pathname &path, bool mtab) const
00448 {
00449 MediaManager manager;
00450 return manager.isUseableAttachPoint(path, mtab);
00451 }
00452
00453
00455
00456
00457
00458
00459
00460
00461
00462 void
00463 MediaHandler::setMediaSource(const MediaSourceRef &ref)
00464 {
00465 _mediaSource.reset();
00466 if( ref && !ref->type.empty() && !ref->name.empty())
00467 _mediaSource = ref;
00468 }
00469
00471
00472
00473
00474
00475
00476
00477
00478 AttachedMedia
00479 MediaHandler::attachedMedia() const
00480 {
00481 if ( _mediaSource && _attachPoint)
00482 return AttachedMedia(_mediaSource, _attachPoint);
00483 else
00484 return AttachedMedia();
00485 }
00486
00488
00489
00490
00491
00492
00493
00494
00495 bool
00496 MediaHandler::isSharedMedia() const
00497 {
00498 return !_mediaSource.unique();
00499 }
00500
00502
00503
00504
00505
00506
00507
00508
00509 bool
00510 MediaHandler::checkAttached(bool matchMountFs) const
00511 {
00512 bool _isAttached = false;
00513
00514 AttachedMedia ref( attachedMedia());
00515 if( ref.mediaSource )
00516 {
00517 time_t old_mtime = _attach_mtime;
00518 _attach_mtime = MediaManager::getMountTableMTime();
00519 if( !(old_mtime <= 0 || _attach_mtime != old_mtime) )
00520 {
00521
00522 _isAttached = true;
00523 }
00524 else
00525 {
00526 if( old_mtime > 0)
00527 DBG << "Mount table changed - rereading it" << std::endl;
00528 else
00529 DBG << "Forced check of the mount table" << std::endl;
00530
00531 MountEntries entries( MediaManager::getMountEntries());
00532 for_( e, entries.begin(), entries.end() )
00533 {
00534 bool is_device = false;
00535 PathInfo dev_info;
00536
00537 if( str::hasPrefix( Pathname(e->src).asString(), "/dev/" ) &&
00538 dev_info(e->src) && dev_info.isBlk())
00539 {
00540 is_device = true;
00541 }
00542
00543 if( is_device && (ref.mediaSource->maj_nr &&
00544 ref.mediaSource->bdir.empty()))
00545 {
00546 std::string mtype(matchMountFs ? e->type : ref.mediaSource->type);
00547 MediaSource media(mtype, e->src, dev_info.major(), dev_info.minor());
00548
00549 if( ref.mediaSource->equals( media) &&
00550 ref.attachPoint->path == Pathname(e->dir))
00551 {
00552 DBG << "Found media device "
00553 << ref.mediaSource->asString()
00554 << " in the mount table as " << e->src << std::endl;
00555 _isAttached = true;
00556 break;
00557 }
00558
00559 }
00560 else
00561 if(!is_device && (!ref.mediaSource->maj_nr ||
00562 !ref.mediaSource->bdir.empty()))
00563 {
00564 if( ref.mediaSource->bdir.empty())
00565 {
00566
00567
00568 if ( matchMountFs && e->type != ref.mediaSource->type )
00569 {
00570 if ( str::hasPrefix( e->type, "nfs" ) && str::hasPrefix( ref.mediaSource->type, "nfs" ) )
00571 matchMountFs = false;
00572 else if ( ( e->type == "cifs" || e->type == "smb" ) && ( ref.mediaSource->type == "cifs" || ref.mediaSource->type == "smb" ) )
00573 matchMountFs = false;
00574 }
00575 std::string mtype(matchMountFs ? e->type : ref.mediaSource->type);
00576 MediaSource media(mtype, e->src);
00577
00578 if( ref.mediaSource->equals( media) &&
00579 ref.attachPoint->path == Pathname(e->dir))
00580 {
00581 DBG << "Found media name "
00582 << ref.mediaSource->asString()
00583 << " in the mount table as " << e->src << std::endl;
00584 _isAttached = true;
00585 break;
00586 }
00587 }
00588 else
00589 {
00590 if(ref.mediaSource->bdir == e->src &&
00591 ref.attachPoint->path == Pathname(e->dir))
00592 {
00593 DBG << "Found bound media "
00594 << ref.mediaSource->asString()
00595 << " in the mount table as " << e->src << std::endl;
00596 _isAttached = true;
00597 break;
00598 }
00599 }
00600
00601 }
00602 }
00603
00604 if( !_isAttached)
00605 {
00606 MIL << "Looking for " << ref << endl;
00607 if( entries.empty() )
00608 {
00609 ERR << "Unable to find any entry in the /etc/mtab file" << std::endl;
00610 }
00611 else
00612 {
00613 dumpRange( DBG << "MountEntries: ", entries.begin(), entries.end() ) << endl;
00614 }
00615 if( old_mtime > 0 )
00616 {
00617 ERR << "Attached media not in mount table any more - forcing reset!"
00618 << std::endl;
00619
00620 _mediaSource.reset();
00621 }
00622 else
00623 {
00624 WAR << "Attached media not in mount table ..." << std::endl;
00625 }
00626
00627
00628
00629 _attach_mtime = 0;
00630 }
00631 }
00632 }
00633 return _isAttached;
00634 }
00635
00637
00638
00639
00640
00641
00642
00643
00644 void MediaHandler::attach( bool next )
00645 {
00646 if ( isAttached() )
00647 return;
00648
00649
00650
00651 setMediaSource(MediaSourceRef());
00652
00653 AttachPoint ap( attachPointHint());
00654 setAttachPoint(ap.path, ap.temp);
00655
00656 try
00657 {
00658 attachTo( next );
00659 }
00660 catch(const MediaException &e)
00661 {
00662 removeAttachPoint();
00663 ZYPP_RETHROW(e);
00664 }
00665 MIL << "Attached: " << *this << endl;
00666 }
00667
00668
00670
00671
00672
00673
00674
00675 Pathname MediaHandler::localPath( const Pathname & pathname ) const
00676 {
00677 Pathname _localRoot( localRoot());
00678 if ( _localRoot.empty() )
00679 return _localRoot;
00680
00681
00682
00683
00684
00685 return _localRoot + pathname.absolutename();
00686 }
00687
00688
00689
00690
00691
00693
00694
00695
00696
00697
00698 void MediaHandler::disconnect()
00699 {
00700 if ( !isAttached() )
00701 return;
00702
00703 disconnectFrom();
00704 MIL << "Disconnected: " << *this << endl;
00705 }
00706
00708
00709
00710
00711
00712
00713
00714
00715 void MediaHandler::release( const std::string & ejectDev )
00716 {
00717 if ( !isAttached() ) {
00718 DBG << "Request to release media - not attached; eject '" << ejectDev << "'"
00719 << std::endl;
00720 if ( !ejectDev.empty() )
00721 forceEject(ejectDev);
00722 return;
00723 }
00724
00725 DBG << "Request to release attached media "
00726 << _mediaSource->asString()
00727 << ", use count=" << _mediaSource.use_count()
00728 << std::endl;
00729
00730 if( _mediaSource.unique())
00731 {
00732 DBG << "Releasing media " << _mediaSource->asString() << std::endl;
00733 try {
00734 releaseFrom( ejectDev );
00735 }
00736 catch(const MediaNotEjectedException &e)
00737 {
00738
00739
00740
00741
00742 _mediaSource.reset(NULL);
00743 removeAttachPoint();
00744
00745 ZYPP_RETHROW(e);
00746 }
00747 _mediaSource.reset(NULL);
00748 removeAttachPoint();
00749 }
00750 else if( !ejectDev.empty() ) {
00751
00752
00753
00754
00755
00756 MediaSourceRef media( new MediaSource(*_mediaSource));
00757 _mediaSource.reset(NULL);
00758
00759 MediaManager manager;
00760 manager.forceReleaseShared(media);
00761
00762 setMediaSource(media);
00763 DBG << "Releasing media (forced) " << _mediaSource->asString() << std::endl;
00764 try {
00765 releaseFrom( ejectDev );
00766 }
00767 catch(const MediaNotEjectedException &e)
00768 {
00769
00770
00771
00772
00773 _mediaSource.reset(NULL);
00774 removeAttachPoint();
00775
00776 ZYPP_RETHROW(e);
00777 }
00778 _mediaSource.reset(NULL);
00779 removeAttachPoint();
00780 }
00781 else {
00782 DBG << "Releasing shared media reference only" << std::endl;
00783 _mediaSource.reset(NULL);
00784 setAttachPoint("", true);
00785 }
00786 MIL << "Released: " << *this << endl;
00787 }
00788
00789 void MediaHandler::forceRelaseAllMedia(bool matchMountFs)
00790 {
00791 forceRelaseAllMedia( attachedMedia().mediaSource, matchMountFs);
00792 }
00793
00794 void MediaHandler::forceRelaseAllMedia(const MediaSourceRef &ref,
00795 bool matchMountFs)
00796 {
00797 if( !ref)
00798 return;
00799
00800 MountEntries entries( MediaManager::getMountEntries());
00801 MountEntries::const_iterator e;
00802 for( e = entries.begin(); e != entries.end(); ++e)
00803 {
00804 bool is_device = false;
00805 PathInfo dev_info;
00806
00807 if( str::hasPrefix( Pathname(e->src).asString(), "/dev/" ) &&
00808 dev_info(e->src) && dev_info.isBlk())
00809 {
00810 is_device = true;
00811 }
00812
00813 if( is_device && ref->maj_nr)
00814 {
00815 std::string mtype(matchMountFs ? e->type : ref->type);
00816 MediaSource media(mtype, e->src, dev_info.major(), dev_info.minor());
00817
00818 if( ref->equals( media) && e->type != "subfs")
00819 {
00820 DBG << "Forcing release of media device "
00821 << ref->asString()
00822 << " in the mount table as "
00823 << e->src << std::endl;
00824 try {
00825 Mount mount;
00826 mount.umount(e->dir);
00827 }
00828 catch (const Exception &e)
00829 {
00830 ZYPP_CAUGHT(e);
00831 }
00832 }
00833 }
00834 else
00835 if(!is_device && !ref->maj_nr)
00836 {
00837 std::string mtype(matchMountFs ? e->type : ref->type);
00838 MediaSource media(mtype, e->src);
00839 if( ref->equals( media))
00840 {
00841 DBG << "Forcing release of media name "
00842 << ref->asString()
00843 << " in the mount table as "
00844 << e->src << std::endl;
00845 try {
00846 Mount mount;
00847 mount.umount(e->dir);
00848 }
00849 catch (const Exception &e)
00850 {
00851 ZYPP_CAUGHT(e);
00852 }
00853 }
00854 }
00855 }
00856 }
00857
00858 bool
00859 MediaHandler::checkAttachPoint(const Pathname &apoint) const
00860 {
00861 return MediaHandler::checkAttachPoint( apoint, true, false);
00862 }
00863
00864
00865 bool
00866 MediaHandler::checkAttachPoint(const Pathname &apoint,
00867 bool emptydir,
00868 bool writeable)
00869 {
00870 if( apoint.empty() || !apoint.absolute())
00871 {
00872 ERR << "Attach point '" << apoint << "' is not absolute"
00873 << std::endl;
00874 return false;
00875 }
00876 if( apoint == "/")
00877 {
00878 ERR << "Attach point '" << apoint << "' is not allowed"
00879 << std::endl;
00880 return false;
00881 }
00882
00883 PathInfo ainfo(apoint);
00884 if( !ainfo.isDir())
00885 {
00886 ERR << "Attach point '" << apoint << "' is not a directory"
00887 << std::endl;
00888 return false;
00889 }
00890
00891 if( emptydir)
00892 {
00893 if( 0 != zypp::filesystem::is_empty_dir(apoint))
00894 {
00895 ERR << "Attach point '" << apoint << "' is not a empty directory"
00896 << std::endl;
00897 return false;
00898 }
00899 }
00900
00901 if( writeable)
00902 {
00903 Pathname apath(apoint + "XXXXXX");
00904 char *atemp = ::strdup( apath.asString().c_str());
00905 char *atest = NULL;
00906 if( !ainfo.userMayRWX() || atemp == NULL ||
00907 (atest=::mkdtemp(atemp)) == NULL)
00908 {
00909 if( atemp != NULL)
00910 ::free(atemp);
00911
00912 ERR << "Attach point '" << ainfo.path()
00913 << "' is not a writeable directory" << std::endl;
00914 return false;
00915 }
00916 else if( atest != NULL)
00917 ::rmdir(atest);
00918
00919 if( atemp != NULL)
00920 ::free(atemp);
00921 }
00922 return true;
00923 }
00924
00926
00927
00928
00929
00930
00931
00932 bool
00933 MediaHandler::dependsOnParent()
00934 {
00935 return _parentId != 0;
00936 }
00937
00938 bool
00939 MediaHandler::dependsOnParent(MediaAccessId parentId, bool exactIdMatch)
00940 {
00941 if( _parentId != 0)
00942 {
00943 if(parentId == _parentId)
00944 return true;
00945
00946 if( !exactIdMatch)
00947 {
00948 MediaManager mm;
00949 AttachedMedia am1 = mm.getAttachedMedia(_parentId);
00950 AttachedMedia am2 = mm.getAttachedMedia(parentId);
00951 if( am1.mediaSource && am2.mediaSource)
00952 {
00953 return am1.mediaSource->equals( *(am2.mediaSource));
00954 }
00955 }
00956 }
00957 return false;
00958 }
00959
00961
00962
00963
00964
00965
00966
00967
00968 void MediaHandler::provideFileCopy( Pathname srcFilename,
00969 Pathname targetFilename ) const
00970 {
00971 if ( !isAttached() ) {
00972 INT << "Media not_attached on provideFileCopy(" << srcFilename
00973 << "," << targetFilename << ")" << endl;
00974 ZYPP_THROW(MediaNotAttachedException(url()));
00975 }
00976
00977 getFileCopy( srcFilename, targetFilename );
00978 DBG << "provideFileCopy(" << srcFilename << "," << targetFilename << ")" << endl;
00979 }
00980
00981 void MediaHandler::provideFile( Pathname filename ) const
00982 {
00983 if ( !isAttached() ) {
00984 INT << "Error: Not attached on provideFile(" << filename << ")" << endl;
00985 ZYPP_THROW(MediaNotAttachedException(url()));
00986 }
00987
00988 getFile( filename );
00989 DBG << "provideFile(" << filename << ")" << endl;
00990 }
00991
00992
00994
00995
00996
00997
00998
00999
01000
01001 void MediaHandler::provideDir( Pathname dirname ) const
01002 {
01003 if ( !isAttached() ) {
01004 INT << "Error: Not attached on provideDir(" << dirname << ")" << endl;
01005 ZYPP_THROW(MediaNotAttachedException(url()));
01006 }
01007
01008 getDir( dirname, false );
01009 MIL << "provideDir(" << dirname << ")" << endl;
01010 }
01011
01013
01014
01015
01016
01017
01018
01019
01020 void MediaHandler::provideDirTree( Pathname dirname ) const
01021 {
01022 if ( !isAttached() ) {
01023 INT << "Error Not attached on provideDirTree(" << dirname << ")" << endl;
01024 ZYPP_THROW(MediaNotAttachedException(url()));
01025 }
01026
01027 getDir( dirname, true );
01028 MIL << "provideDirTree(" << dirname << ")" << endl;
01029 }
01030
01032
01033
01034
01035
01036
01037
01038
01039 void MediaHandler::releasePath( Pathname pathname ) const
01040 {
01041 if ( ! _does_download || _attachPoint->empty() )
01042 return;
01043
01044 PathInfo info( localPath( pathname ) );
01045
01046 if ( info.isFile() ) {
01047 unlink( info.path() );
01048 } else if ( info.isDir() ) {
01049 if ( info.path() != localRoot() ) {
01050 recursive_rmdir( info.path() );
01051 } else {
01052 clean_dir( info.path() );
01053 }
01054 }
01055 }
01056
01058
01059
01060
01061
01062
01063
01064
01065 void MediaHandler::dirInfo( std::list<std::string> & retlist,
01066 const Pathname & dirname, bool dots ) const
01067 {
01068 retlist.clear();
01069
01070 if ( !isAttached() ) {
01071 INT << "Error: Not attached on dirInfo(" << dirname << ")" << endl;
01072 ZYPP_THROW(MediaNotAttachedException(url()));
01073 }
01074
01075 getDirInfo( retlist, dirname, dots );
01076 MIL << "dirInfo(" << dirname << ")" << endl;
01077 }
01078
01080
01081
01082
01083
01084
01085
01086
01087 void MediaHandler::dirInfo( filesystem::DirContent & retlist,
01088 const Pathname & dirname, bool dots ) const
01089 {
01090 retlist.clear();
01091
01092 if ( !isAttached() ) {
01093 INT << "Error: Not attached on dirInfo(" << dirname << ")" << endl;
01094 ZYPP_THROW(MediaNotAttachedException(url()));
01095 }
01096
01097 getDirInfo( retlist, dirname, dots );
01098 MIL << "dirInfo(" << dirname << ")" << endl;
01099 }
01100
01102
01103
01104
01105
01106
01107
01108
01109 bool MediaHandler::doesFileExist( const Pathname & filename ) const
01110 {
01111
01112 if ( !isAttached() ) {
01113 INT << "Error Not attached on doesFileExist(" << filename << ")" << endl;
01114 ZYPP_THROW(MediaNotAttachedException(url()));
01115 }
01116 return getDoesFileExist( filename );
01117 MIL << "doesFileExist(" << filename << ")" << endl;
01118 }
01119
01121
01122
01123
01124
01125
01126 void MediaHandler::getDirectoryYast( std::list<std::string> & retlist,
01127 const Pathname & dirname, bool dots ) const
01128 {
01129 retlist.clear();
01130
01131 filesystem::DirContent content;
01132 getDirectoryYast( content, dirname, dots );
01133
01134
01135 for ( filesystem::DirContent::const_iterator it = content.begin(); it != content.end(); ++it ) {
01136 retlist.push_back( it->name );
01137 }
01138 }
01139
01141
01142
01143
01144
01145
01146 void MediaHandler::getDirectoryYast( filesystem::DirContent & retlist,
01147 const Pathname & dirname, bool dots ) const
01148 {
01149 retlist.clear();
01150
01151
01152 Pathname dirFile = dirname + "directory.yast";
01153 getFile( dirFile );
01154 DBG << "provideFile(" << dirFile << "): " << "OK" << endl;
01155
01156
01157 ifstream dir( localPath( dirFile ).asString().c_str() );
01158 if ( dir.fail() ) {
01159 ERR << "Unable to load '" << localPath( dirFile ) << "'" << endl;
01160 ZYPP_THROW(MediaSystemException(url(),
01161 "Unable to load '" + localPath( dirFile ).asString() + "'"));
01162 }
01163
01164 string line;
01165 while( getline( dir, line ) ) {
01166 if ( line.empty() ) continue;
01167 if ( line == "directory.yast" ) continue;
01168
01169
01170
01171 filesystem::FileType type = filesystem::FT_NOT_AVAIL;
01172 if ( *line.rbegin() == '/' ) {
01173 line.erase( line.end()-1 );
01174 type = filesystem::FT_DIR;
01175 }
01176
01177 if ( dots ) {
01178 if ( line == "." || line == ".." ) continue;
01179 } else {
01180 if ( *line.begin() == '.' ) continue;
01181 }
01182
01183 retlist.push_back( filesystem::DirEntry( line, type ) );
01184 }
01185 }
01186
01187
01188
01189
01190
01191
01192
01193 ostream & operator<<( ostream & str, const MediaHandler & obj )
01194 {
01195 str << obj.url() << ( obj.isAttached() ? "" : " not" )
01196 << " attached; localRoot \"" << obj.localRoot() << "\"";
01197 return str;
01198 }
01199
01201
01202
01203
01204
01205
01206
01207
01208
01209 void MediaHandler::getFile( const Pathname & filename ) const
01210 {
01211 PathInfo info( localPath( filename ) );
01212 if( info.isFile() ) {
01213 return;
01214 }
01215
01216 if (info.isExist())
01217 ZYPP_THROW(MediaNotAFileException(url(), localPath(filename)));
01218 else
01219 ZYPP_THROW(MediaFileNotFoundException(url(), filename));
01220 }
01221
01222
01223 void MediaHandler::getFileCopy ( const Pathname & srcFilename, const Pathname & targetFilename ) const
01224 {
01225 getFile(srcFilename);
01226
01227 if ( copy( localPath( srcFilename ), targetFilename ) != 0 ) {
01228 ZYPP_THROW(MediaWriteException(targetFilename));
01229 }
01230 }
01231
01232
01233
01235
01236
01237
01238
01239
01240
01241
01242
01243 void MediaHandler::getDir( const Pathname & dirname, bool recurse_r ) const
01244 {
01245 PathInfo info( localPath( dirname ) );
01246 if( info.isDir() ) {
01247 return;
01248 }
01249
01250 if (info.isExist())
01251 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
01252 else
01253 ZYPP_THROW(MediaFileNotFoundException(url(), dirname));
01254 }
01255
01257
01258
01259
01260
01261
01262
01263
01264
01265 void MediaHandler::getDirInfo( std::list<std::string> & retlist,
01266 const Pathname & dirname, bool dots ) const
01267 {
01268 PathInfo info( localPath( dirname ) );
01269 if( ! info.isDir() ) {
01270 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
01271 }
01272
01273 #if NONREMOTE_DIRECTORY_YAST
01274
01275 try {
01276 getDirectoryYast( retlist, dirname, dots );
01277 }
01278 catch (const MediaException & excpt_r)
01279 {
01280 #endif
01281
01282
01283 int res = readdir( retlist, info.path(), dots );
01284 if ( res )
01285 {
01286 MediaSystemException nexcpt(url(), "readdir failed");
01287 #if NONREMOTE_DIRECTORY_YAST
01288 nexcpt.remember(excpt_r);
01289 #endif
01290 ZYPP_THROW(nexcpt);
01291 }
01292
01293 #if NONREMOTE_DIRECTORY_YAST
01294 }
01295 #endif
01296
01297 return;
01298 }
01299
01301
01302
01303
01304
01305
01306
01307
01308
01309 void MediaHandler::getDirInfo( filesystem::DirContent & retlist,
01310 const Pathname & dirname, bool dots ) const
01311 {
01312 PathInfo info( localPath( dirname ) );
01313 if( ! info.isDir() ) {
01314 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
01315 }
01316
01317 #if NONREMOTE_DIRECTORY_YAST
01318
01319 try {
01320 getDirectoryYast( retlist, dirname, dots );
01321 }
01322 catch (const MediaException & excpt_r)
01323 {
01324 #endif
01325
01326
01327 int res = readdir( retlist, info.path(), dots );
01328 if ( res )
01329 {
01330 MediaSystemException nexcpt(url(), "readdir failed");
01331 #if NONREMOTE_DIRECTORY_YAST
01332 nexcpt.remember(excpt_r);
01333 #endif
01334 ZYPP_THROW(nexcpt);
01335 }
01336 #if NONREMOTE_DIRECTORY_YAST
01337 }
01338 #endif
01339 }
01340
01342
01343
01344
01345
01346
01347
01348
01349
01350 bool MediaHandler::getDoesFileExist( const Pathname & filename ) const
01351 {
01352 PathInfo info( localPath( filename ) );
01353 if( info.isDir() ) {
01354 ZYPP_THROW(MediaNotAFileException(url(), localPath(filename)));
01355 }
01356 return info.isExist();
01357 }
01358
01359 bool MediaHandler::hasMoreDevices()
01360 {
01361 return false;
01362 }
01363
01364 void MediaHandler::getDetectedDevices(std::vector<std::string> & devices,
01365 unsigned int & index) const
01366 {
01367
01368 if (!devices.empty())
01369 devices.clear();
01370 index = 0;
01371
01372 DBG << "No devices for this medium" << endl;
01373 }
01374
01375 void MediaHandler::setDeltafile( const Pathname & filename ) const
01376 {
01377 _deltafile = filename;
01378 }
01379
01380 Pathname MediaHandler::deltafile() const {
01381 return _deltafile;
01382 }
01383
01384 }
01385 }
01386