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;
617 MIL << "Looking for " << ref << endl;
618 if( entries.empty() )
620 ERR << "Unable to find any entry in the /etc/mtab file" << std::endl;
624 dumpRange( DBG << "MountEntries: ", entries.begin(), entries.end() ) << endl;
628 ERR << "Attached media not in mount table any more - forcing reset!"
631 _mediaSource.reset();
635 WAR << "Attached media not in mount table ..." << std::endl;
638 // reset the mtime and force a new check to make sure,
639 // that we've found the media at least once in the mtab.
647 ///////////////////////////////////////////////////////////////////
650 // METHOD NAME : MediaHandler::attach
651 // METHOD TYPE : PMError
655 void MediaHandler::attach( bool next )
660 // reset it in case of overloaded isAttached()
661 // that checks the media against /etc/mtab ...
662 setMediaSource(MediaSourceRef());
664 AttachPoint ap( attachPointHint());
665 setAttachPoint(ap.path, ap.temp);
669 attachTo( next ); // pass to concrete handler
671 catch(const MediaException &e)
676 MIL << "Attached: " << *this << endl;
680 ///////////////////////////////////////////////////////////////////
683 // METHOD NAME : MediaHandler::localPath
684 // METHOD TYPE : Pathname
686 Pathname MediaHandler::localPath( const Pathname & pathname ) const
688 Pathname _localRoot( localRoot());
689 if ( _localRoot.empty() )
692 // we must check maximum file name length
693 // this is important for fetching the suseservers, the
694 // url with all parameters can get too long (bug #42021)
696 return _localRoot + pathname.absolutename();
703 ///////////////////////////////////////////////////////////////////
706 // METHOD NAME : MediaHandler::disconnect
707 // METHOD TYPE : PMError
709 void MediaHandler::disconnect()
714 disconnectFrom(); // pass to concrete handler
715 MIL << "Disconnected: " << *this << endl;
718 ///////////////////////////////////////////////////////////////////
721 // METHOD NAME : MediaHandler::release
722 // METHOD TYPE : PMError
726 void MediaHandler::release( const std::string & ejectDev )
728 if ( !isAttached() ) {
729 DBG << "Request to release media - not attached; eject '" << ejectDev << "'"
731 if ( !ejectDev.empty() )
732 forceEject(ejectDev);
736 DBG << "Request to release attached media "
737 << _mediaSource->asString()
738 << ", use count=" << _mediaSource.use_count()
741 if( _mediaSource.unique())
743 DBG << "Releasing media " << _mediaSource->asString() << std::endl;
745 releaseFrom( ejectDev ); // pass to concrete handler
747 catch(const MediaNotEjectedException &e)
749 // not ejected because the media
750 // is mounted by somebody else
751 // (if our attach point is busy,
752 // we get an umount exception)
753 _mediaSource.reset(NULL);
758 _mediaSource.reset(NULL);
761 else if( !ejectDev.empty() ) {
763 // Can't eject a shared media
765 //ZYPP_THROW(MediaIsSharedException(_mediaSource->asString()));
767 MediaSourceRef media( new MediaSource(*_mediaSource));
768 _mediaSource.reset(NULL);
770 MediaManager manager;
771 manager.forceReleaseShared(media);
773 setMediaSource(media);
774 DBG << "Releasing media (forced) " << _mediaSource->asString() << std::endl;
776 releaseFrom( ejectDev ); // pass to concrete handler
778 catch(const MediaNotEjectedException &e)
780 // not ejected because the media
781 // is mounted by somebody else
782 // (if our attach point is busy,
783 // we get an umount exception)
784 _mediaSource.reset(NULL);
789 _mediaSource.reset(NULL);
793 DBG << "Releasing shared media reference only" << std::endl;
794 _mediaSource.reset(NULL);
795 setAttachPoint("", true);
797 MIL << "Released: " << *this << endl;
800 void MediaHandler::forceRelaseAllMedia(bool matchMountFs)
802 forceRelaseAllMedia( attachedMedia().mediaSource, matchMountFs);
805 void MediaHandler::forceRelaseAllMedia(const MediaSourceRef &ref,
811 MountEntries entries( MediaManager::getMountEntries());
812 MountEntries::const_iterator e;
813 for( e = entries.begin(); e != entries.end(); ++e)
815 bool is_device = false;
818 if( str::hasPrefix( Pathname(e->src).asString(), "/dev/" ) &&
819 dev_info(e->src) && dev_info.isBlk())
824 if( is_device && ref->maj_nr)
826 std::string mtype(matchMountFs ? e->type : ref->type);
827 MediaSource media(mtype, e->src, dev_info.devMajor(), dev_info.devMinor());
829 if( ref->equals( media) && e->type != "subfs")
831 DBG << "Forcing release of media device "
833 << " in the mount table as "
834 << e->src << std::endl;
837 mount.umount(e->dir);
839 catch (const Exception &e)
846 if(!is_device && !ref->maj_nr)
848 std::string mtype(matchMountFs ? e->type : ref->type);
849 MediaSource media(mtype, e->src);
850 if( ref->equals( media))
852 DBG << "Forcing release of media name "
854 << " in the mount table as "
855 << e->src << std::endl;
858 mount.umount(e->dir);
860 catch (const Exception &e)
870 MediaHandler::checkAttachPoint(const Pathname &apoint) const
872 return MediaHandler::checkAttachPoint( apoint, true, false);
877 MediaHandler::checkAttachPoint(const Pathname &apoint,
881 if( apoint.empty() || !apoint.absolute())
883 ERR << "Attach point '" << apoint << "' is not absolute"
889 ERR << "Attach point '" << apoint << "' is not allowed"
894 PathInfo ainfo(apoint);
897 ERR << "Attach point '" << apoint << "' is not a directory"
904 if( 0 != zypp::filesystem::is_empty_dir(apoint))
906 ERR << "Attach point '" << apoint << "' is not a empty directory"
914 Pathname apath(apoint + "XXXXXX");
915 char *atemp = ::strdup( apath.asString().c_str());
917 if( !ainfo.userMayRWX() || atemp == NULL ||
918 (atest=::mkdtemp(atemp)) == NULL)
923 ERR << "Attach point '" << ainfo.path()
924 << "' is not a writeable directory" << std::endl;
927 else if( atest != NULL)
936 ///////////////////////////////////////////////////////////////////
938 // METHOD NAME : MediaHandler::dependsOnParent
939 // METHOD TYPE : bool
944 MediaHandler::dependsOnParent()
946 return _parentId != 0;
950 MediaHandler::dependsOnParent(MediaAccessId parentId, bool exactIdMatch)
954 if(parentId == _parentId)
960 AttachedMedia am1 = mm.getAttachedMedia(_parentId);
961 AttachedMedia am2 = mm.getAttachedMedia(parentId);
962 if( am1.mediaSource && am2.mediaSource)
964 return am1.mediaSource->equals( *(am2.mediaSource));
971 ///////////////////////////////////////////////////////////////////
974 // METHOD NAME : MediaHandler::provideFile
975 // METHOD TYPE : PMError
979 void MediaHandler::provideFileCopy( Pathname srcFilename,
980 Pathname targetFilename ) const
982 if ( !isAttached() ) {
983 INT << "Media not_attached on provideFileCopy(" << srcFilename
984 << "," << targetFilename << ")" << endl;
985 ZYPP_THROW(MediaNotAttachedException(url()));
988 getFileCopy( srcFilename, targetFilename ); // pass to concrete handler
989 DBG << "provideFileCopy(" << srcFilename << "," << targetFilename << ")" << endl;
992 void MediaHandler::provideFile( Pathname filename ) const
994 if ( !isAttached() ) {
995 INT << "Error: Not attached on provideFile(" << filename << ")" << endl;
996 ZYPP_THROW(MediaNotAttachedException(url()));
999 getFile( filename ); // pass to concrete handler
1000 DBG << "provideFile(" << filename << ")" << endl;
1004 ///////////////////////////////////////////////////////////////////
1007 // METHOD NAME : MediaHandler::provideDir
1008 // METHOD TYPE : PMError
1012 void MediaHandler::provideDir( Pathname dirname ) const
1014 if ( !isAttached() ) {
1015 INT << "Error: Not attached on provideDir(" << dirname << ")" << endl;
1016 ZYPP_THROW(MediaNotAttachedException(url()));
1019 getDir( dirname, /*recursive*/false ); // pass to concrete handler
1020 MIL << "provideDir(" << dirname << ")" << endl;
1023 ///////////////////////////////////////////////////////////////////
1026 // METHOD NAME : MediaHandler::provideDirTree
1027 // METHOD TYPE : PMError
1031 void MediaHandler::provideDirTree( Pathname dirname ) const
1033 if ( !isAttached() ) {
1034 INT << "Error Not attached on provideDirTree(" << dirname << ")" << endl;
1035 ZYPP_THROW(MediaNotAttachedException(url()));
1038 getDir( dirname, /*recursive*/true ); // pass to concrete handler
1039 MIL << "provideDirTree(" << dirname << ")" << endl;
1042 ///////////////////////////////////////////////////////////////////
1045 // METHOD NAME : MediaHandler::releasePath
1046 // METHOD TYPE : PMError
1050 void MediaHandler::releasePath( Pathname pathname ) const
1052 if ( ! _does_download || _attachPoint->empty() )
1055 PathInfo info( localPath( pathname ) );
1057 if ( info.isFile() ) {
1058 unlink( info.path() );
1059 } else if ( info.isDir() ) {
1060 if ( info.path() != localRoot() ) {
1061 recursive_rmdir( info.path() );
1063 clean_dir( info.path() );
1068 ///////////////////////////////////////////////////////////////////
1071 // METHOD NAME : MediaHandler::dirInfo
1072 // METHOD TYPE : PMError
1076 void MediaHandler::dirInfo( std::list<std::string> & retlist,
1077 const Pathname & dirname, bool dots ) const
1081 if ( !isAttached() ) {
1082 INT << "Error: Not attached on dirInfo(" << dirname << ")" << endl;
1083 ZYPP_THROW(MediaNotAttachedException(url()));
1086 getDirInfo( retlist, dirname, dots ); // pass to concrete handler
1087 MIL << "dirInfo(" << dirname << ")" << endl;
1090 ///////////////////////////////////////////////////////////////////
1093 // METHOD NAME : MediaHandler::dirInfo
1094 // METHOD TYPE : PMError
1098 void MediaHandler::dirInfo( filesystem::DirContent & retlist,
1099 const Pathname & dirname, bool dots ) const
1103 if ( !isAttached() ) {
1104 INT << "Error: Not attached on dirInfo(" << dirname << ")" << endl;
1105 ZYPP_THROW(MediaNotAttachedException(url()));
1108 getDirInfo( retlist, dirname, dots ); // pass to concrete handler
1109 MIL << "dirInfo(" << dirname << ")" << endl;
1112 ///////////////////////////////////////////////////////////////////
1115 // METHOD NAME : MediaHandler::doesFileExist
1116 // METHOD TYPE : PMError
1120 bool MediaHandler::doesFileExist( const Pathname & filename ) const
1122 // TODO do some logging
1123 if ( !isAttached() ) {
1124 INT << "Error Not attached on doesFileExist(" << filename << ")" << endl;
1125 ZYPP_THROW(MediaNotAttachedException(url()));
1127 return getDoesFileExist( filename );
1128 MIL << "doesFileExist(" << filename << ")" << endl;
1131 ///////////////////////////////////////////////////////////////////
1134 // METHOD NAME : MediaHandler::getDirectoryYast
1135 // METHOD TYPE : PMError
1137 void MediaHandler::getDirectoryYast( std::list<std::string> & retlist,
1138 const Pathname & dirname, bool dots ) const
1142 filesystem::DirContent content;
1143 getDirectoryYast( content, dirname, dots );
1145 // convert to std::list<std::string>
1146 for ( filesystem::DirContent::const_iterator it = content.begin(); it != content.end(); ++it ) {
1147 retlist.push_back( it->name );
1151 ///////////////////////////////////////////////////////////////////
1154 // METHOD NAME : MediaHandler::getDirectoryYast
1155 // METHOD TYPE : PMError
1157 void MediaHandler::getDirectoryYast( filesystem::DirContent & retlist,
1158 const Pathname & dirname, bool dots ) const
1162 // look for directory.yast
1163 Pathname dirFile = dirname + "directory.yast";
1165 DBG << "provideFile(" << dirFile << "): " << "OK" << endl;
1167 // using directory.yast
1168 ifstream dir( localPath( dirFile ).asString().c_str() );
1170 ERR << "Unable to load '" << localPath( dirFile ) << "'" << endl;
1171 ZYPP_THROW(MediaSystemException(url(),
1172 "Unable to load '" + localPath( dirFile ).asString() + "'"));
1176 while( getline( dir, line ) ) {
1177 if ( line.empty() ) continue;
1178 if ( line == "directory.yast" ) continue;
1180 // Newer directory.yast append '/' to directory names
1181 // Remaining entries are unspecified, although most probabely files.
1182 filesystem::FileType type = filesystem::FT_NOT_AVAIL;
1183 if ( *line.rbegin() == '/' ) {
1184 line.erase( line.end()-1 );
1185 type = filesystem::FT_DIR;
1189 if ( line == "." || line == ".." ) continue;
1191 if ( *line.begin() == '.' ) continue;
1194 retlist.push_back( filesystem::DirEntry( line, type ) );
1198 /******************************************************************
1201 ** FUNCTION NAME : operator<<
1202 ** FUNCTION TYPE : ostream &
1204 ostream & operator<<( ostream & str, const MediaHandler & obj )
1206 str << obj.url() << ( obj.isAttached() ? "" : " not" )
1207 << " attached; localRoot \"" << obj.localRoot() << "\"";
1211 ///////////////////////////////////////////////////////////////////
1214 // METHOD NAME : MediaHandler::getFile
1215 // METHOD TYPE : PMError
1217 // DESCRIPTION : Asserted that media is attached.
1218 // Default implementation of pure virtual.
1220 void MediaHandler::getFile( const Pathname & filename ) const
1222 PathInfo info( localPath( filename ) );
1223 if( info.isFile() ) {
1228 ZYPP_THROW(MediaNotAFileException(url(), localPath(filename)));
1230 ZYPP_THROW(MediaFileNotFoundException(url(), filename));
1234 void MediaHandler::getFileCopy ( const Pathname & srcFilename, const Pathname & targetFilename ) const
1236 getFile(srcFilename);
1238 if ( copy( localPath( srcFilename ), targetFilename ) != 0 ) {
1239 ZYPP_THROW(MediaWriteException(targetFilename));
1245 ///////////////////////////////////////////////////////////////////
1248 // METHOD NAME : MediaHandler::getDir
1249 // METHOD TYPE : PMError
1251 // DESCRIPTION : Asserted that media is attached.
1252 // Default implementation of pure virtual.
1254 void MediaHandler::getDir( const Pathname & dirname, bool recurse_r ) const
1256 PathInfo info( localPath( dirname ) );
1257 if( info.isDir() ) {
1262 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
1264 ZYPP_THROW(MediaFileNotFoundException(url(), dirname));
1267 ///////////////////////////////////////////////////////////////////
1270 // METHOD NAME : MediaHandler::getDirInfo
1271 // METHOD TYPE : PMError
1273 // DESCRIPTION : Asserted that media is attached and retlist is empty.
1274 // Default implementation of pure virtual.
1276 void MediaHandler::getDirInfo( std::list<std::string> & retlist,
1277 const Pathname & dirname, bool dots ) const
1279 PathInfo info( localPath( dirname ) );
1280 if( ! info.isDir() ) {
1281 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
1284 #if NONREMOTE_DIRECTORY_YAST
1285 // use directory.yast if available
1287 getDirectoryYast( retlist, dirname, dots );
1289 catch (const MediaException & excpt_r)
1294 int res = readdir( retlist, info.path(), dots );
1297 MediaSystemException nexcpt(url(), "readdir failed");
1298 #if NONREMOTE_DIRECTORY_YAST
1299 nexcpt.remember(excpt_r);
1304 #if NONREMOTE_DIRECTORY_YAST
1311 ///////////////////////////////////////////////////////////////////
1314 // METHOD NAME : MediaHandler::getDirInfo
1315 // METHOD TYPE : PMError
1317 // DESCRIPTION : Asserted that media is attached and retlist is empty.
1318 // Default implementation of pure virtual.
1320 void MediaHandler::getDirInfo( filesystem::DirContent & retlist,
1321 const Pathname & dirname, bool dots ) const
1323 PathInfo info( localPath( dirname ) );
1324 if( ! info.isDir() ) {
1325 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
1328 #if NONREMOTE_DIRECTORY_YAST
1329 // use directory.yast if available
1331 getDirectoryYast( retlist, dirname, dots );
1333 catch (const MediaException & excpt_r)
1338 int res = readdir( retlist, info.path(), dots );
1341 MediaSystemException nexcpt(url(), "readdir failed");
1342 #if NONREMOTE_DIRECTORY_YAST
1343 nexcpt.remember(excpt_r);
1347 #if NONREMOTE_DIRECTORY_YAST
1352 ///////////////////////////////////////////////////////////////////
1355 // METHOD NAME : MediaHandler::getDoesFileExist
1356 // METHOD TYPE : PMError
1358 // DESCRIPTION : Asserted that file is not a directory
1359 // Default implementation of pure virtual.
1361 bool MediaHandler::getDoesFileExist( const Pathname & filename ) const
1363 PathInfo info( localPath( filename ) );
1364 if( info.isDir() ) {
1365 ZYPP_THROW(MediaNotAFileException(url(), localPath(filename)));
1367 return info.isExist();
1370 bool MediaHandler::hasMoreDevices()
1375 void MediaHandler::getDetectedDevices(std::vector<std::string> & devices,
1376 unsigned int & index) const
1378 // clear the vector by default
1379 if (!devices.empty())
1383 DBG << "No devices for this medium" << endl;
1386 void MediaHandler::setDeltafile( const Pathname & filename ) const
1388 _deltafile = filename;
1391 Pathname MediaHandler::deltafile() const {
1395 } // namespace media
1397 // vim: set ts=8 sts=2 sw=2 ai noet: