1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaHandler.cc
17 #include "zypp/ZConfig.h"
18 #include "zypp/TmpPath.h"
19 #include "zypp/Date.h"
20 #include "zypp/base/LogTools.h"
21 #include "zypp/base/Gettext.h"
22 #include "zypp/base/String.h"
23 #include "zypp/media/MediaHandler.h"
24 #include "zypp/media/MediaManager.h"
25 #include "zypp/media/Mount.h"
33 // use directory.yast on every media (not just via ftp/http)
34 #define NONREMOTE_DIRECTORY_YAST 1
39 Pathname MediaHandler::_attachPrefix("");
41 ///////////////////////////////////////////////////////////////////
43 // CLASS NAME : MediaHandler
45 ///////////////////////////////////////////////////////////////////
47 ///////////////////////////////////////////////////////////////////
50 // METHOD NAME : MediaHandler::MediaHandler
51 // METHOD TYPE : Constructor
55 MediaHandler::MediaHandler ( const Url & url_r,
56 const Pathname & attach_point_r,
57 const Pathname & urlpath_below_attachpoint_r,
58 const bool does_download_r )
60 , _attachPoint( new AttachPoint())
62 , _relativeRoot( urlpath_below_attachpoint_r)
63 , _does_download( does_download_r )
68 Pathname real_attach_point( getRealPath(attach_point_r.asString()));
70 if ( !real_attach_point.empty() ) {
71 ///////////////////////////////////////////////////////////////////
72 // check if provided attachpoint is usable.
73 ///////////////////////////////////////////////////////////////////
75 PathInfo adir( real_attach_point );
77 // The verify if attach_point_r isn't a mountpoint of another
78 // device is done in the particular media handler (if needed).
80 // We just verify, if attach_point_r is a directory and for
81 // schemes other than "file" and "dir", if it is absolute.
84 || (_url.getScheme() != "file"
85 && _url.getScheme() != "dir"
86 && !real_attach_point.absolute()) )
88 ERR << "Provided attach point is not a absolute directory: "
92 attachPointHint( real_attach_point, false);
93 setAttachPoint( real_attach_point, false);
98 ///////////////////////////////////////////////////////////////////
101 // METHOD NAME : MediaHandler::~MediaHandler
102 // METHOD TYPE : Destructor
106 MediaHandler::~MediaHandler()
116 MediaHandler::resetParentId()
122 MediaHandler::getRealPath(const std::string &path)
129 char *ptr = ::realpath(path.c_str(), NULL);
139 char buff[PATH_MAX + 2];
140 memset(buff, '\0', sizeof(buff));
141 if( ::realpath(path.c_str(), buff) != NULL)
147 char buff[PATH_MAX + 2];
148 memset(buff, '\0', sizeof(buff));
149 if( ::realpath(path.c_str(), buff) != NULL)
159 MediaHandler::getRealPath(const Pathname &path)
161 return zypp::Pathname(getRealPath(path.asString()));
165 ///////////////////////////////////////////////////////////////////
168 // METHOD NAME : MediaHandler::removeAttachPoint
169 // METHOD TYPE : void
174 MediaHandler::removeAttachPoint()
176 if ( _mediaSource ) {
177 INT << "MediaHandler deleted with media attached." << endl;
178 return; // no cleanup if media still mounted!
181 DBG << "MediaHandler - checking if to remove attach point" << endl;
182 if ( _attachPoint.unique() &&
183 _attachPoint->temp &&
184 !_attachPoint->path.empty() &&
185 PathInfo(_attachPoint->path).isDir())
187 Pathname path(_attachPoint->path);
189 setAttachPoint("", true);
191 int res = recursive_rmdir( path );
193 MIL << "Deleted default attach point " << path << endl;
195 ERR << "Failed to Delete default attach point " << path
196 << " errno(" << res << ")" << endl;
201 if( !_attachPoint->path.empty() && !_attachPoint->temp)
202 DBG << "MediaHandler - attachpoint is not temporary" << endl;
207 ///////////////////////////////////////////////////////////////////
210 // METHOD NAME : MediaHandler::attachPoint
211 // METHOD TYPE : Pathname
216 MediaHandler::attachPoint() const
218 return _attachPoint->path;
222 ///////////////////////////////////////////////////////////////////
225 // METHOD NAME : MediaHandler::attachPoint
231 MediaHandler::setAttachPoint(const Pathname &path, bool temporary)
233 _attachPoint.reset( new AttachPoint(path, temporary));
237 MediaHandler::localRoot() const
239 if( _attachPoint->path.empty())
242 return _attachPoint->path + _relativeRoot;
245 ///////////////////////////////////////////////////////////////////
248 // METHOD NAME : MediaHandler::attachPoint
254 MediaHandler::setAttachPoint(const AttachPointRef &ref)
257 AttachPointRef(ref).swap(_attachPoint);
259 _attachPoint.reset( new AttachPoint());
262 ///////////////////////////////////////////////////////////////////
265 // METHOD NAME : MediaHandler::attachPointHint
266 // METHOD TYPE : void
271 MediaHandler::attachPointHint(const Pathname &path, bool temporary)
273 _attachPointHint.path = path;
274 _attachPointHint.temp = temporary;
277 ///////////////////////////////////////////////////////////////////
280 // METHOD NAME : MediaHandler::attachPointHint
281 // METHOD TYPE : AttachPoint
286 MediaHandler::attachPointHint() const
288 return _attachPointHint;
291 ///////////////////////////////////////////////////////////////////
294 // METHOD NAME : MediaHandler::findAttachedMedia
295 // METHOD TYPE : AttachedMedia
300 MediaHandler::findAttachedMedia(const MediaSourceRef &media) const
302 return MediaManager().findAttachedMedia(media);
305 ///////////////////////////////////////////////////////////////////
308 // METHOD NAME : MediaHandler::setAttachPrefix
309 // METHOD TYPE : void
314 MediaHandler::setAttachPrefix(const Pathname &attach_prefix)
316 if( attach_prefix.empty())
318 MIL << "Reseting to built-in attach point prefixes."
320 MediaHandler::_attachPrefix = attach_prefix;
324 if( MediaHandler::checkAttachPoint(attach_prefix, false, true))
326 MIL << "Setting user defined attach point prefix: "
327 << attach_prefix << std::endl;
328 MediaHandler::_attachPrefix = attach_prefix;
334 ///////////////////////////////////////////////////////////////////
337 // METHOD NAME : MediaHandler::attach
338 // METHOD TYPE : Pathname
343 MediaHandler::createAttachPoint() const
348 aroot = MediaHandler::_attachPrefix; // explicit request
349 if ( ! aroot.empty() )
350 apoint = createAttachPoint( aroot );
353 if ( apoint.empty() ) // fallback to config value
355 aroot = ZConfig::instance().download_mediaMountdir();
356 if ( ! aroot.empty() )
357 apoint = createAttachPoint( aroot );
360 if ( apoint.empty() ) // fall back to temp space
362 aroot = filesystem::TmpPath::defaultLocation();
363 if ( ! aroot.empty() )
364 apoint = createAttachPoint( aroot );
367 if ( apoint.empty() )
369 auto except = MediaBadAttachPointException( url() );
370 except.addHistory( _("Create attach point: Can't find a writable directory to create an attach point") );
371 ZYPP_THROW( std::move(except) );
374 MIL << "Created default attach point " << apoint << std::endl;
379 MediaHandler::createAttachPoint(const Pathname &attach_root) const
383 if( attach_root.empty() || !attach_root.absolute()) {
384 ERR << "Create attach point: invalid attach root: '"
385 << attach_root << "'" << std::endl;
389 PathInfo adir( attach_root );
390 if( !adir.isDir() || (geteuid() != 0 && !adir.userMayRWX())) {
391 DBG << "Create attach point: attach root is not a writable directory: '"
392 << attach_root << "'" << std::endl;
396 static bool cleanup_once( true );
399 cleanup_once = false;
400 DBG << "Look for orphaned attach points in " << adir << std::endl;
401 std::list<std::string> entries;
402 filesystem::readdir( entries, attach_root, false );
403 for ( const std::string & entry : entries )
405 if ( ! str::hasPrefix( entry, "AP_0x" ) )
407 PathInfo sdir( attach_root + entry );
409 && sdir.dev() == adir.dev()
410 && ( Date::now()-sdir.mtime() > Date::month ) )
412 DBG << "Remove orphaned attach point " << sdir << std::endl;
413 filesystem::recursive_rmdir( sdir.path() );
418 filesystem::TmpDir tmpdir( attach_root, "AP_0x" );
421 apoint = getRealPath( tmpdir.path().asString() );
422 if ( ! apoint.empty() )
424 tmpdir.autoCleanup( false ); // Take responsibility for cleanup.
428 ERR << "Unable to resolve real path for attach point " << tmpdir << std::endl;
433 ERR << "Unable to create attach point below " << attach_root << std::endl;
438 ///////////////////////////////////////////////////////////////////
441 // METHOD NAME : MediaHandler::isUseableAttachPoint
442 // METHOD TYPE : bool
447 MediaHandler::isUseableAttachPoint(const Pathname &path, bool mtab) const
449 MediaManager manager;
450 return manager.isUseableAttachPoint(path, mtab);
454 ///////////////////////////////////////////////////////////////////
457 // METHOD NAME : MediaHandler::setMediaSource
458 // METHOD TYPE : void
463 MediaHandler::setMediaSource(const MediaSourceRef &ref)
465 _mediaSource.reset();
466 if( ref && !ref->type.empty() && !ref->name.empty())
470 ///////////////////////////////////////////////////////////////////
473 // METHOD NAME : MediaHandler::attachedMedia
474 // METHOD TYPE : AttachedMedia
479 MediaHandler::attachedMedia() const
481 if ( _mediaSource && _attachPoint)
482 return AttachedMedia(_mediaSource, _attachPoint);
484 return AttachedMedia();
487 ///////////////////////////////////////////////////////////////////
490 // METHOD NAME : MediaHandler::isSharedMedia
491 // METHOD TYPE : bool
496 MediaHandler::isSharedMedia() const
498 return !_mediaSource.unique();
501 ///////////////////////////////////////////////////////////////////
504 // METHOD NAME : MediaHandler::checkAttached
505 // METHOD TYPE : bool
510 MediaHandler::checkAttached(bool matchMountFs) const
512 bool _isAttached = false;
514 AttachedMedia ref( attachedMedia() );
515 if( ref.mediaSource )
517 time_t old_mtime = _attach_mtime;
518 _attach_mtime = MediaManager::getMountTableMTime();
519 if( !(old_mtime <= 0 || _attach_mtime != old_mtime) )
521 // OK, skip the check (we've seen it at least once)
527 DBG << "Mount table changed - rereading it" << std::endl;
529 DBG << "Forced check of the mount table" << std::endl;
531 MountEntries entries( MediaManager::getMountEntries());
532 for_( e, entries.begin(), entries.end() )
534 if ( ref.attachPoint->path != Pathname(e->dir) )
535 continue; // at least the mount points must match
537 bool is_device = false;
539 if( str::hasPrefix( Pathname(e->src).asString(), "/dev/" ) &&
540 dev_info(e->src) && dev_info.isBlk() )
545 if( is_device && (ref.mediaSource->maj_nr &&
546 ref.mediaSource->bdir.empty()))
548 std::string mtype(matchMountFs ? e->type : ref.mediaSource->type);
549 MediaSource media(mtype, e->src, dev_info.devMajor(), dev_info.devMinor());
551 if( ref.mediaSource->equals( media ) )
553 DBG << "Found media device "
554 << ref.mediaSource->asString()
555 << " in the mount table as " << e->src << std::endl;
562 if(!is_device && (!ref.mediaSource->maj_nr ||
563 !ref.mediaSource->bdir.empty()))
565 if( ref.mediaSource->bdir.empty())
567 // bnc#710269: Type nfs may appear as nfs4 in in the mount table
568 // and maybe vice versa. Similar cifs/smb. Need to unify these types:
569 if ( matchMountFs && e->type != ref.mediaSource->type )
571 if ( str::hasPrefix( e->type, "nfs" ) && str::hasPrefix( ref.mediaSource->type, "nfs" ) )
572 matchMountFs = false;
573 else if ( ( e->type == "cifs" || e->type == "smb" ) && ( ref.mediaSource->type == "cifs" || ref.mediaSource->type == "smb" ) )
574 matchMountFs = false;
576 continue; // different types cannot match
578 // Here: Types are ok or not to check.
579 // Check the name except for nfs (bnc#804544; symlink resolution in mount path)
581 // [fibonacci]$ ls -l /Local/ma/c12.1
582 // lrwxrwxrwx /Local/ma/c12.1 -> zypp-SuSE-Code-12_1-Branch/
584 // [localhost]$ mount -t nfs4 fibonacci:/Local/ma/c12.1 /mnt
585 // [localhost]$ mount
586 // fibonacci:/Local/ma/zypp-SuSE-Code-12_1-Branch on /mnt
588 // std::string mtype(matchMountFs ? e->type : ref.mediaSource->type);
589 // MediaSource media(mtype, e->src);
591 if( ref.mediaSource->name == e->src || str::hasPrefix( ref.mediaSource->type, "nfs" ) )
593 DBG << "Found media name "
594 << ref.mediaSource->asString()
595 << " in the mount table as " << e->src << std::endl;
602 if ( ref.mediaSource->bdir == e->src )
604 DBG << "Found bound media "
605 << ref.mediaSource->asString()
606 << " in the mount table as " << e->src << std::endl;
615 // Type ISO: Since 11.1 mtab might contain the name of
616 // the loop device instead of the iso file:
617 if ( ref.mediaSource->type == "iso"
618 && str::hasPrefix( Pathname(e->src).asString(), "/dev/loop" )
619 && ref.attachPoint->path == Pathname(e->dir) )
621 DBG << "Found bound media "
622 << ref.mediaSource->asString()
623 << " in the mount table as " << e->src << std::endl;
632 MIL << "Looking for " << ref << endl;
633 if( entries.empty() )
635 ERR << "Unable to find any entry in the /etc/mtab file" << std::endl;
639 dumpRange( DBG << "MountEntries: ", entries.begin(), entries.end() ) << endl;
643 ERR << "Attached media not in mount table any more - forcing reset!"
646 _mediaSource.reset();
650 WAR << "Attached media not in mount table ..." << std::endl;
653 // reset the mtime and force a new check to make sure,
654 // that we've found the media at least once in the mtab.
662 ///////////////////////////////////////////////////////////////////
665 // METHOD NAME : MediaHandler::attach
666 // METHOD TYPE : PMError
670 void MediaHandler::attach( bool next )
675 // reset it in case of overloaded isAttached()
676 // that checks the media against /etc/mtab ...
677 setMediaSource(MediaSourceRef());
679 AttachPoint ap( attachPointHint());
680 setAttachPoint(ap.path, ap.temp);
684 attachTo( next ); // pass to concrete handler
686 catch(const MediaException &e)
691 MIL << "Attached: " << *this << endl;
695 ///////////////////////////////////////////////////////////////////
698 // METHOD NAME : MediaHandler::localPath
699 // METHOD TYPE : Pathname
701 Pathname MediaHandler::localPath( const Pathname & pathname ) const
703 Pathname _localRoot( localRoot());
704 if ( _localRoot.empty() )
707 // we must check maximum file name length
708 // this is important for fetching the suseservers, the
709 // url with all parameters can get too long (bug #42021)
711 return _localRoot + pathname.absolutename();
718 ///////////////////////////////////////////////////////////////////
721 // METHOD NAME : MediaHandler::disconnect
722 // METHOD TYPE : PMError
724 void MediaHandler::disconnect()
729 disconnectFrom(); // pass to concrete handler
730 MIL << "Disconnected: " << *this << endl;
733 ///////////////////////////////////////////////////////////////////
736 // METHOD NAME : MediaHandler::release
737 // METHOD TYPE : PMError
741 void MediaHandler::release( const std::string & ejectDev )
743 if ( !isAttached() ) {
744 DBG << "Request to release media - not attached; eject '" << ejectDev << "'"
746 if ( !ejectDev.empty() )
747 forceEject(ejectDev);
751 DBG << "Request to release attached media "
752 << _mediaSource->asString()
753 << ", use count=" << _mediaSource.use_count()
756 if( _mediaSource.unique())
758 DBG << "Releasing media " << _mediaSource->asString() << std::endl;
760 releaseFrom( ejectDev ); // pass to concrete handler
762 catch(const MediaNotEjectedException &e)
764 // not ejected because the media
765 // is mounted by somebody else
766 // (if our attach point is busy,
767 // we get an umount exception)
768 _mediaSource.reset(NULL);
773 _mediaSource.reset(NULL);
776 else if( !ejectDev.empty() ) {
778 // Can't eject a shared media
780 //ZYPP_THROW(MediaIsSharedException(_mediaSource->asString()));
782 MediaSourceRef media( new MediaSource(*_mediaSource));
783 _mediaSource.reset(NULL);
785 MediaManager manager;
786 manager.forceReleaseShared(media);
788 setMediaSource(media);
789 DBG << "Releasing media (forced) " << _mediaSource->asString() << std::endl;
791 releaseFrom( ejectDev ); // pass to concrete handler
793 catch(const MediaNotEjectedException &e)
795 // not ejected because the media
796 // is mounted by somebody else
797 // (if our attach point is busy,
798 // we get an umount exception)
799 _mediaSource.reset(NULL);
804 _mediaSource.reset(NULL);
808 DBG << "Releasing shared media reference only" << std::endl;
809 _mediaSource.reset(NULL);
810 setAttachPoint("", true);
812 MIL << "Released: " << *this << endl;
815 void MediaHandler::forceRelaseAllMedia(bool matchMountFs)
817 forceRelaseAllMedia( attachedMedia().mediaSource, matchMountFs);
820 void MediaHandler::forceRelaseAllMedia(const MediaSourceRef &ref,
826 MountEntries entries( MediaManager::getMountEntries());
827 MountEntries::const_iterator e;
828 for( e = entries.begin(); e != entries.end(); ++e)
830 bool is_device = false;
833 if( str::hasPrefix( Pathname(e->src).asString(), "/dev/" ) &&
834 dev_info(e->src) && dev_info.isBlk())
839 if( is_device && ref->maj_nr)
841 std::string mtype(matchMountFs ? e->type : ref->type);
842 MediaSource media(mtype, e->src, dev_info.devMajor(), dev_info.devMinor());
844 if( ref->equals( media) && e->type != "subfs")
846 DBG << "Forcing release of media device "
848 << " in the mount table as "
849 << e->src << std::endl;
852 mount.umount(e->dir);
854 catch (const Exception &e)
861 if(!is_device && !ref->maj_nr)
863 std::string mtype(matchMountFs ? e->type : ref->type);
864 MediaSource media(mtype, e->src);
865 if( ref->equals( media))
867 DBG << "Forcing release of media name "
869 << " in the mount table as "
870 << e->src << std::endl;
873 mount.umount(e->dir);
875 catch (const Exception &e)
885 MediaHandler::checkAttachPoint(const Pathname &apoint) const
887 return MediaHandler::checkAttachPoint( apoint, true, false);
892 MediaHandler::checkAttachPoint(const Pathname &apoint,
896 if( apoint.empty() || !apoint.absolute())
898 ERR << "Attach point '" << apoint << "' is not absolute"
904 ERR << "Attach point '" << apoint << "' is not allowed"
909 PathInfo ainfo(apoint);
912 ERR << "Attach point '" << apoint << "' is not a directory"
919 if( 0 != zypp::filesystem::is_empty_dir(apoint))
921 ERR << "Attach point '" << apoint << "' is not a empty directory"
929 Pathname apath(apoint + "XXXXXX");
930 char *atemp = ::strdup( apath.asString().c_str());
932 if( !ainfo.userMayRWX() || atemp == NULL ||
933 (atest=::mkdtemp(atemp)) == NULL)
938 ERR << "Attach point '" << ainfo.path()
939 << "' is not a writeable directory" << std::endl;
942 else if( atest != NULL)
951 ///////////////////////////////////////////////////////////////////
953 // METHOD NAME : MediaHandler::dependsOnParent
954 // METHOD TYPE : bool
959 MediaHandler::dependsOnParent()
961 return _parentId != 0;
965 MediaHandler::dependsOnParent(MediaAccessId parentId, bool exactIdMatch)
969 if(parentId == _parentId)
975 AttachedMedia am1 = mm.getAttachedMedia(_parentId);
976 AttachedMedia am2 = mm.getAttachedMedia(parentId);
977 if( am1.mediaSource && am2.mediaSource)
979 return am1.mediaSource->equals( *(am2.mediaSource));
986 ///////////////////////////////////////////////////////////////////
989 // METHOD NAME : MediaHandler::provideFile
990 // METHOD TYPE : PMError
994 void MediaHandler::provideFileCopy( Pathname srcFilename,
995 Pathname targetFilename ) const
997 if ( !isAttached() ) {
998 INT << "Media not_attached on provideFileCopy(" << srcFilename
999 << "," << targetFilename << ")" << endl;
1000 ZYPP_THROW(MediaNotAttachedException(url()));
1003 getFileCopy( srcFilename, targetFilename ); // pass to concrete handler
1004 DBG << "provideFileCopy(" << srcFilename << "," << targetFilename << ")" << endl;
1007 void MediaHandler::provideFile( Pathname filename ) const
1009 if ( !isAttached() ) {
1010 INT << "Error: Not attached on provideFile(" << filename << ")" << endl;
1011 ZYPP_THROW(MediaNotAttachedException(url()));
1014 getFile( filename ); // pass to concrete handler
1015 DBG << "provideFile(" << filename << ")" << endl;
1019 ///////////////////////////////////////////////////////////////////
1022 // METHOD NAME : MediaHandler::provideDir
1023 // METHOD TYPE : PMError
1027 void MediaHandler::provideDir( Pathname dirname ) const
1029 if ( !isAttached() ) {
1030 INT << "Error: Not attached on provideDir(" << dirname << ")" << endl;
1031 ZYPP_THROW(MediaNotAttachedException(url()));
1034 getDir( dirname, /*recursive*/false ); // pass to concrete handler
1035 MIL << "provideDir(" << dirname << ")" << endl;
1038 ///////////////////////////////////////////////////////////////////
1041 // METHOD NAME : MediaHandler::provideDirTree
1042 // METHOD TYPE : PMError
1046 void MediaHandler::provideDirTree( Pathname dirname ) const
1048 if ( !isAttached() ) {
1049 INT << "Error Not attached on provideDirTree(" << dirname << ")" << endl;
1050 ZYPP_THROW(MediaNotAttachedException(url()));
1053 getDir( dirname, /*recursive*/true ); // pass to concrete handler
1054 MIL << "provideDirTree(" << dirname << ")" << endl;
1057 ///////////////////////////////////////////////////////////////////
1060 // METHOD NAME : MediaHandler::releasePath
1061 // METHOD TYPE : PMError
1065 void MediaHandler::releasePath( Pathname pathname ) const
1067 if ( ! _does_download || _attachPoint->empty() )
1070 PathInfo info( localPath( pathname ) );
1072 if ( info.isFile() ) {
1073 unlink( info.path() );
1074 } else if ( info.isDir() ) {
1075 if ( info.path() != localRoot() ) {
1076 recursive_rmdir( info.path() );
1078 clean_dir( info.path() );
1083 ///////////////////////////////////////////////////////////////////
1086 // METHOD NAME : MediaHandler::dirInfo
1087 // METHOD TYPE : PMError
1091 void MediaHandler::dirInfo( std::list<std::string> & retlist,
1092 const Pathname & dirname, bool dots ) const
1096 if ( !isAttached() ) {
1097 INT << "Error: Not attached on dirInfo(" << dirname << ")" << endl;
1098 ZYPP_THROW(MediaNotAttachedException(url()));
1101 getDirInfo( retlist, dirname, dots ); // pass to concrete handler
1102 MIL << "dirInfo(" << dirname << ")" << endl;
1105 ///////////////////////////////////////////////////////////////////
1108 // METHOD NAME : MediaHandler::dirInfo
1109 // METHOD TYPE : PMError
1113 void MediaHandler::dirInfo( filesystem::DirContent & retlist,
1114 const Pathname & dirname, bool dots ) const
1118 if ( !isAttached() ) {
1119 INT << "Error: Not attached on dirInfo(" << dirname << ")" << endl;
1120 ZYPP_THROW(MediaNotAttachedException(url()));
1123 getDirInfo( retlist, dirname, dots ); // pass to concrete handler
1124 MIL << "dirInfo(" << dirname << ")" << endl;
1127 ///////////////////////////////////////////////////////////////////
1130 // METHOD NAME : MediaHandler::doesFileExist
1131 // METHOD TYPE : PMError
1135 bool MediaHandler::doesFileExist( const Pathname & filename ) const
1137 // TODO do some logging
1138 if ( !isAttached() ) {
1139 INT << "Error Not attached on doesFileExist(" << filename << ")" << endl;
1140 ZYPP_THROW(MediaNotAttachedException(url()));
1142 return getDoesFileExist( filename );
1143 MIL << "doesFileExist(" << filename << ")" << endl;
1146 ///////////////////////////////////////////////////////////////////
1149 // METHOD NAME : MediaHandler::getDirectoryYast
1150 // METHOD TYPE : PMError
1152 void MediaHandler::getDirectoryYast( std::list<std::string> & retlist,
1153 const Pathname & dirname, bool dots ) const
1157 filesystem::DirContent content;
1158 getDirectoryYast( content, dirname, dots );
1160 // convert to std::list<std::string>
1161 for ( filesystem::DirContent::const_iterator it = content.begin(); it != content.end(); ++it ) {
1162 retlist.push_back( it->name );
1166 ///////////////////////////////////////////////////////////////////
1169 // METHOD NAME : MediaHandler::getDirectoryYast
1170 // METHOD TYPE : PMError
1172 void MediaHandler::getDirectoryYast( filesystem::DirContent & retlist,
1173 const Pathname & dirname, bool dots ) const
1177 // look for directory.yast
1178 Pathname dirFile = dirname + "directory.yast";
1180 DBG << "provideFile(" << dirFile << "): " << "OK" << endl;
1182 // using directory.yast
1183 ifstream dir( localPath( dirFile ).asString().c_str() );
1185 ERR << "Unable to load '" << localPath( dirFile ) << "'" << endl;
1186 ZYPP_THROW(MediaSystemException(url(),
1187 "Unable to load '" + localPath( dirFile ).asString() + "'"));
1191 while( getline( dir, line ) ) {
1192 if ( line.empty() ) continue;
1193 if ( line == "directory.yast" ) continue;
1195 // Newer directory.yast append '/' to directory names
1196 // Remaining entries are unspecified, although most probabely files.
1197 filesystem::FileType type = filesystem::FT_NOT_AVAIL;
1198 if ( *line.rbegin() == '/' ) {
1199 line.erase( line.end()-1 );
1200 type = filesystem::FT_DIR;
1204 if ( line == "." || line == ".." ) continue;
1206 if ( *line.begin() == '.' ) continue;
1209 retlist.push_back( filesystem::DirEntry( line, type ) );
1213 /******************************************************************
1216 ** FUNCTION NAME : operator<<
1217 ** FUNCTION TYPE : ostream &
1219 ostream & operator<<( ostream & str, const MediaHandler & obj )
1221 str << obj.url() << ( obj.isAttached() ? "" : " not" )
1222 << " attached; localRoot \"" << obj.localRoot() << "\"";
1226 ///////////////////////////////////////////////////////////////////
1229 // METHOD NAME : MediaHandler::getFile
1230 // METHOD TYPE : PMError
1232 // DESCRIPTION : Asserted that media is attached.
1233 // Default implementation of pure virtual.
1235 void MediaHandler::getFile( const Pathname & filename ) const
1237 PathInfo info( localPath( filename ) );
1238 if( info.isFile() ) {
1243 ZYPP_THROW(MediaNotAFileException(url(), localPath(filename)));
1245 ZYPP_THROW(MediaFileNotFoundException(url(), filename));
1249 void MediaHandler::getFileCopy ( const Pathname & srcFilename, const Pathname & targetFilename ) const
1251 getFile(srcFilename);
1253 if ( copy( localPath( srcFilename ), targetFilename ) != 0 ) {
1254 ZYPP_THROW(MediaWriteException(targetFilename));
1260 ///////////////////////////////////////////////////////////////////
1263 // METHOD NAME : MediaHandler::getDir
1264 // METHOD TYPE : PMError
1266 // DESCRIPTION : Asserted that media is attached.
1267 // Default implementation of pure virtual.
1269 void MediaHandler::getDir( const Pathname & dirname, bool recurse_r ) const
1271 PathInfo info( localPath( dirname ) );
1272 if( info.isDir() ) {
1277 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
1279 ZYPP_THROW(MediaFileNotFoundException(url(), dirname));
1282 ///////////////////////////////////////////////////////////////////
1285 // METHOD NAME : MediaHandler::getDirInfo
1286 // METHOD TYPE : PMError
1288 // DESCRIPTION : Asserted that media is attached and retlist is empty.
1289 // Default implementation of pure virtual.
1291 void MediaHandler::getDirInfo( std::list<std::string> & retlist,
1292 const Pathname & dirname, bool dots ) const
1294 PathInfo info( localPath( dirname ) );
1295 if( ! info.isDir() ) {
1296 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
1299 #if NONREMOTE_DIRECTORY_YAST
1300 // use directory.yast if available
1302 getDirectoryYast( retlist, dirname, dots );
1304 catch (const MediaException & excpt_r)
1309 int res = readdir( retlist, info.path(), dots );
1312 MediaSystemException nexcpt(url(), "readdir failed");
1313 #if NONREMOTE_DIRECTORY_YAST
1314 nexcpt.remember(excpt_r);
1319 #if NONREMOTE_DIRECTORY_YAST
1326 ///////////////////////////////////////////////////////////////////
1329 // METHOD NAME : MediaHandler::getDirInfo
1330 // METHOD TYPE : PMError
1332 // DESCRIPTION : Asserted that media is attached and retlist is empty.
1333 // Default implementation of pure virtual.
1335 void MediaHandler::getDirInfo( filesystem::DirContent & retlist,
1336 const Pathname & dirname, bool dots ) const
1338 PathInfo info( localPath( dirname ) );
1339 if( ! info.isDir() ) {
1340 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
1343 #if NONREMOTE_DIRECTORY_YAST
1344 // use directory.yast if available
1346 getDirectoryYast( retlist, dirname, dots );
1348 catch (const MediaException & excpt_r)
1353 int res = readdir( retlist, info.path(), dots );
1356 MediaSystemException nexcpt(url(), "readdir failed");
1357 #if NONREMOTE_DIRECTORY_YAST
1358 nexcpt.remember(excpt_r);
1362 #if NONREMOTE_DIRECTORY_YAST
1367 ///////////////////////////////////////////////////////////////////
1370 // METHOD NAME : MediaHandler::getDoesFileExist
1371 // METHOD TYPE : PMError
1373 // DESCRIPTION : Asserted that file is not a directory
1374 // Default implementation of pure virtual.
1376 bool MediaHandler::getDoesFileExist( const Pathname & filename ) const
1378 PathInfo info( localPath( filename ) );
1379 if( info.isDir() ) {
1380 ZYPP_THROW(MediaNotAFileException(url(), localPath(filename)));
1382 return info.isExist();
1385 bool MediaHandler::hasMoreDevices()
1390 void MediaHandler::getDetectedDevices(std::vector<std::string> & devices,
1391 unsigned int & index) const
1393 // clear the vector by default
1394 if (!devices.empty())
1398 DBG << "No devices for this medium" << endl;
1401 void MediaHandler::setDeltafile( const Pathname & filename ) const
1403 _deltafile = filename;
1406 Pathname MediaHandler::deltafile() const {
1410 } // namespace media
1412 // vim: set ts=8 sts=2 sw=2 ai noet: