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