1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaHandler.cc
17 #include "zypp/base/Logger.h"
18 #include "zypp/base/String.h"
19 #include "zypp/media/MediaHandler.h"
20 #include "zypp/media/MediaManager.h"
21 #include "zypp/media/Mount.h"
29 // use directory.yast on every media (not just via ftp/http)
30 #define NONREMOTE_DIRECTORY_YAST 1
35 Pathname MediaHandler::_attachPrefix("");
37 ///////////////////////////////////////////////////////////////////
39 // CLASS NAME : MediaHandler
41 ///////////////////////////////////////////////////////////////////
43 ///////////////////////////////////////////////////////////////////
46 // METHOD NAME : MediaHandler::MediaHandler
47 // METHOD TYPE : Constructor
51 MediaHandler::MediaHandler ( const Url & url_r,
52 const Pathname & attach_point_r,
53 const Pathname & urlpath_below_attachpoint_r,
54 const bool does_download_r )
56 , _attachPoint( new AttachPoint())
58 , _relativeRoot( urlpath_below_attachpoint_r)
59 , _does_download( does_download_r )
64 Pathname real_attach_point( getRealPath(attach_point_r.asString()));
66 if ( !real_attach_point.empty() ) {
67 ///////////////////////////////////////////////////////////////////
68 // check if provided attachpoint is usable.
69 ///////////////////////////////////////////////////////////////////
71 PathInfo adir( real_attach_point );
73 // The verify if attach_point_r isn't a mountpoint of another
74 // device is done in the particular media handler (if needed).
76 // We just verify, if attach_point_r is a directory and for
77 // schemes other than "file" and "dir", if it is absolute.
80 || (_url.getScheme() != "file"
81 && _url.getScheme() != "dir"
82 && !real_attach_point.absolute()) )
84 ERR << "Provided attach point is not a absolute directory: "
88 attachPointHint( real_attach_point, false);
89 setAttachPoint( real_attach_point, false);
94 ///////////////////////////////////////////////////////////////////
97 // METHOD NAME : MediaHandler::~MediaHandler
98 // METHOD TYPE : Destructor
102 MediaHandler::~MediaHandler()
112 MediaHandler::resetParentId()
118 MediaHandler::getRealPath(const std::string &path)
125 char *ptr = ::realpath(path.c_str(), NULL);
135 char buff[PATH_MAX + 2];
136 memset(buff, '\0', sizeof(buff));
137 if( ::realpath(path.c_str(), buff) != NULL)
143 char buff[PATH_MAX + 2];
144 memset(buff, '\0', sizeof(buff));
145 if( ::realpath(path.c_str(), buff) != NULL)
155 MediaHandler::getRealPath(const Pathname &path)
157 return zypp::Pathname(getRealPath(path.asString()));
161 ///////////////////////////////////////////////////////////////////
164 // METHOD NAME : MediaHandler::removeAttachPoint
165 // METHOD TYPE : void
170 MediaHandler::removeAttachPoint()
172 if ( _mediaSource ) {
173 INT << "MediaHandler deleted with media attached." << endl;
174 return; // no cleanup if media still mounted!
177 DBG << "MediaHandler - checking if to remove attach point" << endl;
178 if ( _attachPoint.unique() &&
179 _attachPoint->temp &&
180 !_attachPoint->path.empty() &&
181 PathInfo(_attachPoint->path).isDir())
183 Pathname path(_attachPoint->path);
185 setAttachPoint("", true);
187 int res = recursive_rmdir( path );
189 MIL << "Deleted default attach point " << path << endl;
191 ERR << "Failed to Delete default attach point " << path
192 << " errno(" << res << ")" << endl;
197 if( !_attachPoint->path.empty() && !_attachPoint->temp)
198 DBG << "MediaHandler - attachpoint is not temporary" << endl;
203 ///////////////////////////////////////////////////////////////////
206 // METHOD NAME : MediaHandler::attachPoint
207 // METHOD TYPE : Pathname
212 MediaHandler::attachPoint() const
214 return _attachPoint->path;
218 ///////////////////////////////////////////////////////////////////
221 // METHOD NAME : MediaHandler::attachPoint
227 MediaHandler::setAttachPoint(const Pathname &path, bool temporary)
229 _attachPoint.reset( new AttachPoint(path, temporary));
233 MediaHandler::localRoot() const
235 if( _attachPoint->path.empty())
238 return _attachPoint->path + _relativeRoot;
241 ///////////////////////////////////////////////////////////////////
244 // METHOD NAME : MediaHandler::attachPoint
250 MediaHandler::setAttachPoint(const AttachPointRef &ref)
253 AttachPointRef(ref).swap(_attachPoint);
255 _attachPoint.reset( new AttachPoint());
258 ///////////////////////////////////////////////////////////////////
261 // METHOD NAME : MediaHandler::attachPointHint
262 // METHOD TYPE : void
267 MediaHandler::attachPointHint(const Pathname &path, bool temporary)
269 _AttachPointHint.path = path;
270 _AttachPointHint.temp = temporary;
273 ///////////////////////////////////////////////////////////////////
276 // METHOD NAME : MediaHandler::attachPointHint
277 // METHOD TYPE : AttachPoint
282 MediaHandler::attachPointHint() const
284 return _AttachPointHint;
287 ///////////////////////////////////////////////////////////////////
290 // METHOD NAME : MediaHandler::findAttachedMedia
291 // METHOD TYPE : AttachedMedia
296 MediaHandler::findAttachedMedia(const MediaSourceRef &media) const
298 return MediaManager().findAttachedMedia(media);
301 ///////////////////////////////////////////////////////////////////
304 // METHOD NAME : MediaHandler::setAttachPrefix
305 // METHOD TYPE : void
310 MediaHandler::setAttachPrefix(const Pathname &attach_prefix)
312 if( attach_prefix.empty())
314 MIL << "Reseting to built-in attach point prefixes."
316 MediaHandler::_attachPrefix = attach_prefix;
320 if( MediaHandler::checkAttachPoint(attach_prefix, false, true))
322 MIL << "Setting user defined attach point prefix: "
323 << attach_prefix << std::endl;
324 MediaHandler::_attachPrefix = attach_prefix;
330 ///////////////////////////////////////////////////////////////////
333 // METHOD NAME : MediaHandler::attach
334 // METHOD TYPE : Pathname
339 MediaHandler::createAttachPoint() const
341 /////////////////////////////////////////////////////////////////
342 // provide a default (temporary) attachpoint
343 /////////////////////////////////////////////////////////////////
344 const char * defmounts[] = {
345 "/var/adm/mount", "/var/tmp", /**/NULL/**/
349 Pathname aroot( MediaHandler::_attachPrefix);
353 apoint = createAttachPoint(aroot);
355 for ( const char ** def = defmounts; *def && apoint.empty(); ++def ) {
360 apoint = createAttachPoint(aroot);
363 if ( aroot.empty() ) {
364 ERR << "Create attach point: Can't find a writable directory to create an attach point" << std::endl;
368 if ( !apoint.empty() ) {
369 MIL << "Created default attach point " << apoint << std::endl;
375 MediaHandler::createAttachPoint(const Pathname &attach_root) const
379 if( attach_root.empty() || !attach_root.absolute()) {
380 ERR << "Create attach point: invalid attach root: '"
381 << attach_root << "'" << std::endl;
385 PathInfo adir( attach_root);
386 if( !adir.isDir() || (getuid() != 0 && !adir.userMayRWX())) {
387 DBG << "Create attach point: attach root is not a writable directory: '"
388 << attach_root << "'" << std::endl;
392 DBG << "Trying to create attach point in " << attach_root << std::endl;
395 // FIXME: use mkdtemp?
397 #warning Use class TmpDir from TmpPath.h
398 Pathname abase( attach_root + "AP_" );
399 // ma and sh need more than 42 for debugging :-)
400 // since the readonly fs are handled now, ...
401 for ( unsigned i = 1; i < 1000; ++i ) {
402 adir( Pathname::extend( abase, str::hexstring( i ) ) );
403 if ( ! adir.isExist() ) {
404 int err = mkdir( adir.path() );
406 apoint = getRealPath(adir.asString());
409 ERR << "Unable to resolve a real path for "
410 << adir.path() << std::endl;
416 if (err != EEXIST) // readonly fs or other, dont try further
421 if ( apoint.empty()) {
422 ERR << "Unable to create an attach point below of "
423 << attach_root << std::endl;
428 ///////////////////////////////////////////////////////////////////
431 // METHOD NAME : MediaHandler::isUseableAttachPoint
432 // METHOD TYPE : bool
437 MediaHandler::isUseableAttachPoint(const Pathname &path, bool mtab) const
439 MediaManager manager;
440 return manager.isUseableAttachPoint(path, mtab);
444 ///////////////////////////////////////////////////////////////////
447 // METHOD NAME : MediaHandler::setMediaSource
448 // METHOD TYPE : void
453 MediaHandler::setMediaSource(const MediaSourceRef &ref)
455 _mediaSource.reset();
456 if( ref && !ref->type.empty() && !ref->name.empty())
460 ///////////////////////////////////////////////////////////////////
463 // METHOD NAME : MediaHandler::attachedMedia
464 // METHOD TYPE : AttachedMedia
469 MediaHandler::attachedMedia() const
471 if ( _mediaSource && _attachPoint)
472 return AttachedMedia(_mediaSource, _attachPoint);
474 return AttachedMedia();
477 ///////////////////////////////////////////////////////////////////
480 // METHOD NAME : MediaHandler::isSharedMedia
481 // METHOD TYPE : bool
486 MediaHandler::isSharedMedia() const
488 return !_mediaSource.unique();
491 ///////////////////////////////////////////////////////////////////
494 // METHOD NAME : MediaHandler::checkAttached
495 // METHOD TYPE : bool
500 MediaHandler::checkAttached(bool matchMountFs) const
502 bool _isAttached = false;
504 AttachedMedia ref( attachedMedia());
507 time_t old_mtime = _attach_mtime;
508 _attach_mtime = MediaManager::getMountTableMTime();
509 if( !(old_mtime <= 0 || _attach_mtime != old_mtime))
511 // OK, skip the check (we've seen it at least once)
517 DBG << "Mount table changed - rereading it" << std::endl;
519 DBG << "Forced check of the mount table" << std::endl;
521 MountEntries entries( MediaManager::getMountEntries());
522 MountEntries::const_iterator e;
523 for( e = entries.begin(); e != entries.end(); ++e)
525 bool is_device = false;
526 std::string dev_path(Pathname(e->src).asString());
529 if( dev_path.compare(0, sizeof("/dev/")-1, "/dev/") == 0 &&
530 dev_info(e->src) && dev_info.isBlk())
535 if( is_device && (ref.mediaSource->maj_nr &&
536 ref.mediaSource->bdir.empty()))
538 std::string mtype(matchMountFs ? e->type : ref.mediaSource->type);
539 MediaSource media(mtype, e->src, dev_info.major(), dev_info.minor());
541 if( ref.mediaSource->equals( media) &&
542 ref.attachPoint->path == Pathname(e->dir))
544 DBG << "Found media device "
545 << ref.mediaSource->asString()
546 << " in the mount table as " << e->src << std::endl;
553 if(!is_device && (!ref.mediaSource->maj_nr ||
554 !ref.mediaSource->bdir.empty()))
556 std::string mtype(matchMountFs ? e->type : ref.mediaSource->type);
557 if( ref.mediaSource->bdir.empty())
559 MediaSource media(mtype, e->src);
561 if( ref.mediaSource->equals( media) &&
562 ref.attachPoint->path == Pathname(e->dir))
564 DBG << "Found media name "
565 << ref.mediaSource->asString()
566 << " in the mount table as " << e->src << std::endl;
573 if(ref.mediaSource->bdir == e->src &&
574 ref.attachPoint->path == Pathname(e->dir))
576 DBG << "Found bound media "
577 << ref.mediaSource->asString()
578 << " in the mount table as " << e->src << std::endl;
591 ERR << "Unable to find any entry in the /etc/mtab file" << std::endl;
595 MountEntries::const_iterator e;
596 for( e = entries.begin(); e != entries.end(); ++e)
598 XXX << "mount entry: " << e->src << " on " << e->dir
599 << " type " << e->type << "(" << e->opts << ")" << endl;
604 ERR << "Attached media not in mount table any more - forcing reset!"
607 _mediaSource.reset();
611 WAR << "Attached media not in mount table ..." << std::endl;
614 // reset the mtime and force a new check to make sure,
615 // that we've found the media at least once in the mtab.
623 ///////////////////////////////////////////////////////////////////
626 // METHOD NAME : MediaHandler::attach
627 // METHOD TYPE : PMError
631 void MediaHandler::attach( bool next )
636 // reset it in case of overloaded isAttached()
637 // that checks the media against /etc/mtab ...
638 setMediaSource(MediaSourceRef());
640 AttachPoint ap( attachPointHint());
641 setAttachPoint(ap.path, ap.temp);
645 attachTo( next ); // pass to concrete handler
647 catch(const MediaException &e)
652 MIL << "Attached: " << *this << endl;
656 ///////////////////////////////////////////////////////////////////
659 // METHOD NAME : MediaHandler::localPath
660 // METHOD TYPE : Pathname
662 Pathname MediaHandler::localPath( const Pathname & pathname ) const
664 Pathname _localRoot( localRoot());
665 if ( _localRoot.empty() )
668 // we must check maximum file name length
669 // this is important for fetching the suseservers, the
670 // url with all parameters can get too long (bug #42021)
672 return _localRoot + pathname.absolutename();
679 ///////////////////////////////////////////////////////////////////
682 // METHOD NAME : MediaHandler::disconnect
683 // METHOD TYPE : PMError
685 void MediaHandler::disconnect()
690 disconnectFrom(); // pass to concrete handler
691 MIL << "Disconnected: " << *this << endl;
694 ///////////////////////////////////////////////////////////////////
697 // METHOD NAME : MediaHandler::release
698 // METHOD TYPE : PMError
702 void MediaHandler::release( bool eject )
704 if ( !isAttached() ) {
705 DBG << "Request to release media - not attached; eject " << eject << std::endl;
711 DBG << "Request to release attached media "
712 << _mediaSource->asString()
713 << ", use count=" << _mediaSource.use_count()
716 if( _mediaSource.unique())
718 DBG << "Releasing media " << _mediaSource->asString() << std::endl;
720 releaseFrom( eject ); // pass to concrete handler
722 catch(const MediaNotEjectedException &e)
724 // not ejected because the media
725 // is mounted by somebody else
726 // (if our attach point is busy,
727 // we get an umount exception)
728 _mediaSource.reset(NULL);
733 _mediaSource.reset(NULL);
738 // Can't eject a shared media
740 //ZYPP_THROW(MediaIsSharedException(_mediaSource->asString()));
742 MediaSourceRef media( new MediaSource(*_mediaSource));
743 _mediaSource.reset(NULL);
745 MediaManager manager;
746 manager.forceReleaseShared(media);
748 setMediaSource(media);
749 DBG << "Releasing media (forced) " << _mediaSource->asString() << std::endl;
751 releaseFrom( eject ); // pass to concrete handler
753 catch(const MediaNotEjectedException &e)
755 // not ejected because the media
756 // is mounted by somebody else
757 // (if our attach point is busy,
758 // we get an umount exception)
759 _mediaSource.reset(NULL);
764 _mediaSource.reset(NULL);
768 DBG << "Releasing shared media reference only" << std::endl;
769 _mediaSource.reset(NULL);
770 setAttachPoint("", true);
772 MIL << "Released: " << *this << endl;
775 bool MediaHandler::isAutoMountedMedia(const AttachedMedia &media)
781 void MediaHandler::forceRelaseAllMedia(bool matchMountFs, bool autoMountedOny)
783 forceRelaseAllMedia( attachedMedia().mediaSource, matchMountFs, autoMountedOny);
786 void MediaHandler::forceRelaseAllMedia(const MediaSourceRef &ref,
793 MountEntries entries( MediaManager::getMountEntries());
794 MountEntries::const_iterator e;
795 for( e = entries.begin(); e != entries.end(); ++e)
797 bool is_device = false;
798 std::string dev_path(Pathname(e->src).asString());
801 if( dev_path.compare(0, sizeof("/dev/")-1, "/dev/") == 0 &&
802 dev_info(e->src) && dev_info.isBlk())
807 if( is_device && ref->maj_nr)
809 std::string mtype(matchMountFs ? e->type : ref->type);
810 MediaSource media(mtype, e->src, dev_info.major(), dev_info.minor());
812 if( ref->equals( media) && e->type != "subfs")
817 AttachedMedia am(MediaSourceRef(new MediaSource(media)),
818 AttachPointRef(new AttachPoint(e->dir)));
819 if( !isAutoMountedMedia(am))
827 DBG << "Forcing release of media device "
829 << " in the mount table as "
830 << e->src << std::endl;
833 mount.umount(e->dir);
835 catch (const Exception &e)
842 if(!is_device && !ref->maj_nr)
844 std::string mtype(matchMountFs ? e->type : ref->type);
845 MediaSource media(mtype, e->src);
846 if( ref->equals( media))
851 AttachedMedia am(MediaSourceRef(new MediaSource(media)),
852 AttachPointRef(new AttachPoint(e->dir)));
853 if( !isAutoMountedMedia(am))
861 DBG << "Forcing release of media name "
863 << " in the mount table as "
864 << e->src << std::endl;
867 mount.umount(e->dir);
869 catch (const Exception &e)
879 MediaHandler::checkAttachPoint(const Pathname &apoint) const
881 return MediaHandler::checkAttachPoint( apoint, true, false);
886 MediaHandler::checkAttachPoint(const Pathname &apoint,
890 if( apoint.empty() || !apoint.absolute())
892 ERR << "Attach point '" << apoint << "' is not absolute"
898 ERR << "Attach point '" << apoint << "' is not allowed"
903 PathInfo ainfo(apoint);
906 ERR << "Attach point '" << apoint << "' is not a directory"
913 if( 0 != zypp::filesystem::is_empty_dir(apoint))
915 ERR << "Attach point '" << apoint << "' is not a empty directory"
923 Pathname apath(apoint + "XXXXXX");
924 char *atemp = ::strdup( apath.asString().c_str());
926 if( !ainfo.userMayRWX() || atemp == NULL ||
927 (atest=::mkdtemp(atemp)) == NULL)
932 ERR << "Attach point '" << ainfo.path()
933 << "' is not a writeable directory" << std::endl;
936 else if( atest != NULL)
945 ///////////////////////////////////////////////////////////////////
947 // METHOD NAME : MediaHandler::dependsOnParent
948 // METHOD TYPE : bool
953 MediaHandler::dependsOnParent()
955 return _parentId != 0;
959 MediaHandler::dependsOnParent(MediaAccessId parentId, bool exactIdMatch)
963 if(parentId == _parentId)
969 AttachedMedia am1 = mm.getAttachedMedia(_parentId);
970 AttachedMedia am2 = mm.getAttachedMedia(parentId);
971 if( am1.mediaSource && am2.mediaSource)
973 return am1.mediaSource->equals( *(am2.mediaSource));
980 ///////////////////////////////////////////////////////////////////
983 // METHOD NAME : MediaHandler::provideFile
984 // METHOD TYPE : PMError
988 void MediaHandler::provideFileCopy( Pathname srcFilename,
989 Pathname targetFilename ) const
991 if ( !isAttached() ) {
992 INT << "Media not_attached on provideFileCopy(" << srcFilename
993 << "," << targetFilename << ")" << endl;
994 ZYPP_THROW(MediaNotAttachedException(url()));
997 getFileCopy( srcFilename, targetFilename ); // pass to concrete handler
998 DBG << "provideFileCopy(" << srcFilename << "," << targetFilename << ")" << endl;
1001 void MediaHandler::provideFile( Pathname filename ) const
1003 if ( !isAttached() ) {
1004 INT << "Error: Not attached on provideFile(" << filename << ")" << endl;
1005 ZYPP_THROW(MediaNotAttachedException(url()));
1008 getFile( filename ); // pass to concrete handler
1009 DBG << "provideFile(" << filename << ")" << endl;
1013 ///////////////////////////////////////////////////////////////////
1016 // METHOD NAME : MediaHandler::provideDir
1017 // METHOD TYPE : PMError
1021 void MediaHandler::provideDir( Pathname dirname ) const
1023 if ( !isAttached() ) {
1024 INT << "Error: Not attached on provideDir(" << dirname << ")" << endl;
1025 ZYPP_THROW(MediaNotAttachedException(url()));
1028 getDir( dirname, /*recursive*/false ); // pass to concrete handler
1029 MIL << "provideDir(" << dirname << ")" << endl;
1032 ///////////////////////////////////////////////////////////////////
1035 // METHOD NAME : MediaHandler::provideDirTree
1036 // METHOD TYPE : PMError
1040 void MediaHandler::provideDirTree( Pathname dirname ) const
1042 if ( !isAttached() ) {
1043 INT << "Error Not attached on provideDirTree(" << dirname << ")" << endl;
1044 ZYPP_THROW(MediaNotAttachedException(url()));
1047 getDir( dirname, /*recursive*/true ); // pass to concrete handler
1048 MIL << "provideDirTree(" << dirname << ")" << endl;
1051 ///////////////////////////////////////////////////////////////////
1054 // METHOD NAME : MediaHandler::releasePath
1055 // METHOD TYPE : PMError
1059 void MediaHandler::releasePath( Pathname pathname ) const
1061 if ( ! _does_download || _attachPoint->empty() )
1064 PathInfo info( localPath( pathname ) );
1066 if ( info.isFile() ) {
1067 unlink( info.path() );
1068 } else if ( info.isDir() ) {
1069 if ( info.path() != localRoot() ) {
1070 recursive_rmdir( info.path() );
1072 clean_dir( info.path() );
1077 ///////////////////////////////////////////////////////////////////
1080 // METHOD NAME : MediaHandler::dirInfo
1081 // METHOD TYPE : PMError
1085 void MediaHandler::dirInfo( std::list<std::string> & retlist,
1086 const Pathname & dirname, bool dots ) const
1090 if ( !isAttached() ) {
1091 INT << "Error: Not attached on dirInfo(" << dirname << ")" << endl;
1092 ZYPP_THROW(MediaNotAttachedException(url()));
1095 getDirInfo( retlist, dirname, dots ); // pass to concrete handler
1096 MIL << "dirInfo(" << dirname << ")" << endl;
1099 ///////////////////////////////////////////////////////////////////
1102 // METHOD NAME : MediaHandler::dirInfo
1103 // METHOD TYPE : PMError
1107 void MediaHandler::dirInfo( filesystem::DirContent & retlist,
1108 const Pathname & dirname, bool dots ) const
1112 if ( !isAttached() ) {
1113 INT << "Error: Not attached on dirInfo(" << dirname << ")" << endl;
1114 ZYPP_THROW(MediaNotAttachedException(url()));
1117 getDirInfo( retlist, dirname, dots ); // pass to concrete handler
1118 MIL << "dirInfo(" << dirname << ")" << endl;
1121 ///////////////////////////////////////////////////////////////////
1124 // METHOD NAME : MediaHandler::doesFileExist
1125 // METHOD TYPE : PMError
1129 bool MediaHandler::doesFileExist( const Pathname & filename ) const
1131 // TODO do some logging
1132 if ( !isAttached() ) {
1133 INT << "Error Not attached on doesFileExist(" << filename << ")" << endl;
1134 ZYPP_THROW(MediaNotAttachedException(url()));
1136 return getDoesFileExist( filename );
1137 MIL << "doesFileExist(" << filename << ")" << endl;
1140 ///////////////////////////////////////////////////////////////////
1143 // METHOD NAME : MediaHandler::getDirectoryYast
1144 // METHOD TYPE : PMError
1146 void MediaHandler::getDirectoryYast( std::list<std::string> & retlist,
1147 const Pathname & dirname, bool dots ) const
1151 filesystem::DirContent content;
1152 getDirectoryYast( content, dirname, dots );
1154 // convert to std::list<std::string>
1155 for ( filesystem::DirContent::const_iterator it = content.begin(); it != content.end(); ++it ) {
1156 retlist.push_back( it->name );
1160 ///////////////////////////////////////////////////////////////////
1163 // METHOD NAME : MediaHandler::getDirectoryYast
1164 // METHOD TYPE : PMError
1166 void MediaHandler::getDirectoryYast( filesystem::DirContent & retlist,
1167 const Pathname & dirname, bool dots ) const
1171 // look for directory.yast
1172 Pathname dirFile = dirname + "directory.yast";
1174 DBG << "provideFile(" << dirFile << "): " << "OK" << endl;
1176 // using directory.yast
1177 ifstream dir( localPath( dirFile ).asString().c_str() );
1179 ERR << "Unable to load '" << localPath( dirFile ) << "'" << endl;
1180 ZYPP_THROW(MediaSystemException(url(),
1181 "Unable to load '" + localPath( dirFile ).asString() + "'"));
1185 while( getline( dir, line ) ) {
1186 if ( line.empty() ) continue;
1187 if ( line == "directory.yast" ) continue;
1189 // Newer directory.yast append '/' to directory names
1190 // Remaining entries are unspecified, although most probabely files.
1191 filesystem::FileType type = filesystem::FT_NOT_AVAIL;
1192 if ( *line.rbegin() == '/' ) {
1193 line.erase( line.end()-1 );
1194 type = filesystem::FT_DIR;
1198 if ( line == "." || line == ".." ) continue;
1200 if ( *line.begin() == '.' ) continue;
1203 retlist.push_back( filesystem::DirEntry( line, type ) );
1207 /******************************************************************
1210 ** FUNCTION NAME : operator<<
1211 ** FUNCTION TYPE : ostream &
1213 ostream & operator<<( ostream & str, const MediaHandler & obj )
1215 str << obj.url() << ( obj.isAttached() ? "" : " not" )
1216 << " attached; localRoot \"" << obj.localRoot() << "\"";
1220 ///////////////////////////////////////////////////////////////////
1223 // METHOD NAME : MediaHandler::getFile
1224 // METHOD TYPE : PMError
1226 // DESCRIPTION : Asserted that media is attached.
1227 // Default implementation of pure virtual.
1229 void MediaHandler::getFile( const Pathname & filename ) const
1231 PathInfo info( localPath( filename ) );
1232 if( info.isFile() ) {
1237 ZYPP_THROW(MediaNotAFileException(url(), localPath(filename)));
1239 ZYPP_THROW(MediaFileNotFoundException(url(), filename));
1243 void MediaHandler::getFileCopy ( const Pathname & srcFilename, const Pathname & targetFilename ) const
1245 getFile(srcFilename);
1247 if ( copy( localPath( srcFilename ), targetFilename ) != 0 ) {
1248 ZYPP_THROW(MediaWriteException(targetFilename));
1254 ///////////////////////////////////////////////////////////////////
1257 // METHOD NAME : MediaHandler::getDir
1258 // METHOD TYPE : PMError
1260 // DESCRIPTION : Asserted that media is attached.
1261 // Default implementation of pure virtual.
1263 void MediaHandler::getDir( const Pathname & dirname, bool recurse_r ) const
1265 PathInfo info( localPath( dirname ) );
1266 if( info.isDir() ) {
1271 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
1273 ZYPP_THROW(MediaFileNotFoundException(url(), dirname));
1276 ///////////////////////////////////////////////////////////////////
1279 // METHOD NAME : MediaHandler::getDirInfo
1280 // METHOD TYPE : PMError
1282 // DESCRIPTION : Asserted that media is attached and retlist is empty.
1283 // Default implementation of pure virtual.
1285 void MediaHandler::getDirInfo( std::list<std::string> & retlist,
1286 const Pathname & dirname, bool dots ) const
1288 PathInfo info( localPath( dirname ) );
1289 if( ! info.isDir() ) {
1290 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
1293 #if NONREMOTE_DIRECTORY_YAST
1294 // use directory.yast if available
1296 getDirectoryYast( retlist, dirname, dots );
1298 catch (const MediaException & excpt_r)
1303 int res = readdir( retlist, info.path(), dots );
1305 ZYPP_THROW(MediaSystemException(url(), "readdir failed"));
1307 #if NONREMOTE_DIRECTORY_YAST
1314 ///////////////////////////////////////////////////////////////////
1317 // METHOD NAME : MediaHandler::getDirInfo
1318 // METHOD TYPE : PMError
1320 // DESCRIPTION : Asserted that media is attached and retlist is empty.
1321 // Default implementation of pure virtual.
1323 void MediaHandler::getDirInfo( filesystem::DirContent & retlist,
1324 const Pathname & dirname, bool dots ) const
1326 PathInfo info( localPath( dirname ) );
1327 if( ! info.isDir() ) {
1328 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
1331 #if NONREMOTE_DIRECTORY_YAST
1332 // use directory.yast if available
1334 getDirectoryYast( retlist, dirname, dots );
1336 catch (const MediaException & excpt_r)
1341 int res = readdir( retlist, info.path(), dots );
1343 ZYPP_THROW(MediaSystemException(url(), "readdir failed"));
1344 #if NONREMOTE_DIRECTORY_YAST
1349 ///////////////////////////////////////////////////////////////////
1352 // METHOD NAME : MediaHandler::getDoesFileExist
1353 // METHOD TYPE : PMError
1355 // DESCRIPTION : Asserted that file is not a directory
1356 // Default implementation of pure virtual.
1358 bool MediaHandler::getDoesFileExist( const Pathname & filename ) const
1360 PathInfo info( localPath( filename ) );
1361 if( info.isDir() ) {
1362 ZYPP_THROW(MediaNotAFileException(url(), localPath(filename)));
1364 return info.isExist();
1367 bool MediaHandler::hasMoreDevices()
1372 } // namespace media
1374 // vim: set ts=8 sts=2 sw=2 ai noet: