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