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