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