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