1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaHandler.cc
17 #include "zypp/TmpPath.h"
18 #include "zypp/Date.h"
19 #include "zypp/base/LogTools.h"
20 #include "zypp/base/String.h"
21 #include "zypp/media/MediaHandler.h"
22 #include "zypp/media/MediaManager.h"
23 #include "zypp/media/Mount.h"
31 // use directory.yast on every media (not just via ftp/http)
32 #define NONREMOTE_DIRECTORY_YAST 1
37 Pathname MediaHandler::_attachPrefix("");
39 ///////////////////////////////////////////////////////////////////
41 // CLASS NAME : MediaHandler
43 ///////////////////////////////////////////////////////////////////
45 ///////////////////////////////////////////////////////////////////
48 // METHOD NAME : MediaHandler::MediaHandler
49 // METHOD TYPE : Constructor
53 MediaHandler::MediaHandler ( const Url & url_r,
54 const Pathname & attach_point_r,
55 const Pathname & urlpath_below_attachpoint_r,
56 const bool does_download_r )
58 , _attachPoint( new AttachPoint())
60 , _relativeRoot( urlpath_below_attachpoint_r)
61 , _does_download( does_download_r )
66 Pathname real_attach_point( getRealPath(attach_point_r.asString()));
68 if ( !real_attach_point.empty() ) {
69 ///////////////////////////////////////////////////////////////////
70 // check if provided attachpoint is usable.
71 ///////////////////////////////////////////////////////////////////
73 PathInfo adir( real_attach_point );
75 // The verify if attach_point_r isn't a mountpoint of another
76 // device is done in the particular media handler (if needed).
78 // We just verify, if attach_point_r is a directory and for
79 // schemes other than "file" and "dir", if it is absolute.
82 || (_url.getScheme() != "file"
83 && _url.getScheme() != "dir"
84 && !real_attach_point.absolute()) )
86 ERR << "Provided attach point is not a absolute directory: "
90 attachPointHint( real_attach_point, false);
91 setAttachPoint( real_attach_point, false);
96 ///////////////////////////////////////////////////////////////////
99 // METHOD NAME : MediaHandler::~MediaHandler
100 // METHOD TYPE : Destructor
104 MediaHandler::~MediaHandler()
114 MediaHandler::resetParentId()
120 MediaHandler::getRealPath(const std::string &path)
127 char *ptr = ::realpath(path.c_str(), NULL);
137 char buff[PATH_MAX + 2];
138 memset(buff, '\0', sizeof(buff));
139 if( ::realpath(path.c_str(), buff) != NULL)
145 char buff[PATH_MAX + 2];
146 memset(buff, '\0', sizeof(buff));
147 if( ::realpath(path.c_str(), buff) != NULL)
157 MediaHandler::getRealPath(const Pathname &path)
159 return zypp::Pathname(getRealPath(path.asString()));
163 ///////////////////////////////////////////////////////////////////
166 // METHOD NAME : MediaHandler::removeAttachPoint
167 // METHOD TYPE : void
172 MediaHandler::removeAttachPoint()
174 if ( _mediaSource ) {
175 INT << "MediaHandler deleted with media attached." << endl;
176 return; // no cleanup if media still mounted!
179 DBG << "MediaHandler - checking if to remove attach point" << endl;
180 if ( _attachPoint.unique() &&
181 _attachPoint->temp &&
182 !_attachPoint->path.empty() &&
183 PathInfo(_attachPoint->path).isDir())
185 Pathname path(_attachPoint->path);
187 setAttachPoint("", true);
189 int res = recursive_rmdir( path );
191 MIL << "Deleted default attach point " << path << endl;
193 ERR << "Failed to Delete default attach point " << path
194 << " errno(" << res << ")" << endl;
199 if( !_attachPoint->path.empty() && !_attachPoint->temp)
200 DBG << "MediaHandler - attachpoint is not temporary" << endl;
205 ///////////////////////////////////////////////////////////////////
208 // METHOD NAME : MediaHandler::attachPoint
209 // METHOD TYPE : Pathname
214 MediaHandler::attachPoint() const
216 return _attachPoint->path;
220 ///////////////////////////////////////////////////////////////////
223 // METHOD NAME : MediaHandler::attachPoint
229 MediaHandler::setAttachPoint(const Pathname &path, bool temporary)
231 _attachPoint.reset( new AttachPoint(path, temporary));
235 MediaHandler::localRoot() const
237 if( _attachPoint->path.empty())
240 return _attachPoint->path + _relativeRoot;
243 ///////////////////////////////////////////////////////////////////
246 // METHOD NAME : MediaHandler::attachPoint
252 MediaHandler::setAttachPoint(const AttachPointRef &ref)
255 AttachPointRef(ref).swap(_attachPoint);
257 _attachPoint.reset( new AttachPoint());
260 ///////////////////////////////////////////////////////////////////
263 // METHOD NAME : MediaHandler::attachPointHint
264 // METHOD TYPE : void
269 MediaHandler::attachPointHint(const Pathname &path, bool temporary)
271 _AttachPointHint.path = path;
272 _AttachPointHint.temp = temporary;
275 ///////////////////////////////////////////////////////////////////
278 // METHOD NAME : MediaHandler::attachPointHint
279 // METHOD TYPE : AttachPoint
284 MediaHandler::attachPointHint() const
286 return _AttachPointHint;
289 ///////////////////////////////////////////////////////////////////
292 // METHOD NAME : MediaHandler::findAttachedMedia
293 // METHOD TYPE : AttachedMedia
298 MediaHandler::findAttachedMedia(const MediaSourceRef &media) const
300 return MediaManager().findAttachedMedia(media);
303 ///////////////////////////////////////////////////////////////////
306 // METHOD NAME : MediaHandler::setAttachPrefix
307 // METHOD TYPE : void
312 MediaHandler::setAttachPrefix(const Pathname &attach_prefix)
314 if( attach_prefix.empty())
316 MIL << "Reseting to built-in attach point prefixes."
318 MediaHandler::_attachPrefix = attach_prefix;
322 if( MediaHandler::checkAttachPoint(attach_prefix, false, true))
324 MIL << "Setting user defined attach point prefix: "
325 << attach_prefix << std::endl;
326 MediaHandler::_attachPrefix = attach_prefix;
332 ///////////////////////////////////////////////////////////////////
335 // METHOD NAME : MediaHandler::attach
336 // METHOD TYPE : Pathname
341 MediaHandler::createAttachPoint() const
343 /////////////////////////////////////////////////////////////////
344 // provide a default (temporary) attachpoint
345 /////////////////////////////////////////////////////////////////
346 const char * defmounts[] = {
347 "/var/adm/mount", filesystem::TmpPath::defaultLocation().c_str(), /**/NULL/**/
351 Pathname aroot( MediaHandler::_attachPrefix);
355 apoint = createAttachPoint(aroot);
357 for ( const char ** def = defmounts; *def && apoint.empty(); ++def ) {
362 apoint = createAttachPoint(aroot);
365 if ( aroot.empty() ) {
366 ERR << "Create attach point: Can't find a writable directory to create an attach point" << std::endl;
370 if ( !apoint.empty() ) {
371 MIL << "Created default attach point " << apoint << std::endl;
377 MediaHandler::createAttachPoint(const Pathname &attach_root) const
381 if( attach_root.empty() || !attach_root.absolute()) {
382 ERR << "Create attach point: invalid attach root: '"
383 << attach_root << "'" << std::endl;
387 PathInfo adir( attach_root );
388 if( !adir.isDir() || (geteuid() != 0 && !adir.userMayRWX())) {
389 DBG << "Create attach point: attach root is not a writable directory: '"
390 << attach_root << "'" << std::endl;
394 static bool cleanup_once( true );
397 cleanup_once = false;
398 DBG << "Look for orphaned attach points in " << adir << std::endl;
399 std::list<std::string> entries;
400 filesystem::readdir( entries, attach_root, false );
401 for ( const std::string & entry : entries )
403 if ( ! str::hasPrefix( entry, "AP_0x" ) )
405 PathInfo sdir( attach_root + entry );
407 && sdir.dev() == adir.dev()
408 && ( Date::now()-sdir.mtime() > Date::month ) )
410 DBG << "Remove orphaned attach point " << sdir << std::endl;
411 filesystem::recursive_rmdir( sdir.path() );
416 filesystem::TmpDir tmpdir( attach_root, "AP_0x" );
419 apoint = getRealPath( tmpdir.path().asString() );
420 if ( ! apoint.empty() )
422 tmpdir.autoCleanup( false ); // Take responsibility for cleanup.
426 ERR << "Unable to resolve real path for attach point " << tmpdir << std::endl;
431 ERR << "Unable to create attach point below " << attach_root << std::endl;
436 ///////////////////////////////////////////////////////////////////
439 // METHOD NAME : MediaHandler::isUseableAttachPoint
440 // METHOD TYPE : bool
445 MediaHandler::isUseableAttachPoint(const Pathname &path, bool mtab) const
447 MediaManager manager;
448 return manager.isUseableAttachPoint(path, mtab);
452 ///////////////////////////////////////////////////////////////////
455 // METHOD NAME : MediaHandler::setMediaSource
456 // METHOD TYPE : void
461 MediaHandler::setMediaSource(const MediaSourceRef &ref)
463 _mediaSource.reset();
464 if( ref && !ref->type.empty() && !ref->name.empty())
468 ///////////////////////////////////////////////////////////////////
471 // METHOD NAME : MediaHandler::attachedMedia
472 // METHOD TYPE : AttachedMedia
477 MediaHandler::attachedMedia() const
479 if ( _mediaSource && _attachPoint)
480 return AttachedMedia(_mediaSource, _attachPoint);
482 return AttachedMedia();
485 ///////////////////////////////////////////////////////////////////
488 // METHOD NAME : MediaHandler::isSharedMedia
489 // METHOD TYPE : bool
494 MediaHandler::isSharedMedia() const
496 return !_mediaSource.unique();
499 ///////////////////////////////////////////////////////////////////
502 // METHOD NAME : MediaHandler::checkAttached
503 // METHOD TYPE : bool
508 MediaHandler::checkAttached(bool matchMountFs) const
510 bool _isAttached = false;
512 AttachedMedia ref( attachedMedia() );
513 if( ref.mediaSource )
515 time_t old_mtime = _attach_mtime;
516 _attach_mtime = MediaManager::getMountTableMTime();
517 if( !(old_mtime <= 0 || _attach_mtime != old_mtime) )
519 // OK, skip the check (we've seen it at least once)
525 DBG << "Mount table changed - rereading it" << std::endl;
527 DBG << "Forced check of the mount table" << std::endl;
529 MountEntries entries( MediaManager::getMountEntries());
530 for_( e, entries.begin(), entries.end() )
532 if ( ref.attachPoint->path != Pathname(e->dir) )
533 continue; // at least the mount points must match
535 bool is_device = false;
537 if( str::hasPrefix( Pathname(e->src).asString(), "/dev/" ) &&
538 dev_info(e->src) && dev_info.isBlk() )
543 if( is_device && (ref.mediaSource->maj_nr &&
544 ref.mediaSource->bdir.empty()))
546 std::string mtype(matchMountFs ? e->type : ref.mediaSource->type);
547 MediaSource media(mtype, e->src, dev_info.devMajor(), dev_info.devMinor());
549 if( ref.mediaSource->equals( media ) )
551 DBG << "Found media device "
552 << ref.mediaSource->asString()
553 << " in the mount table as " << e->src << std::endl;
560 if(!is_device && (!ref.mediaSource->maj_nr ||
561 !ref.mediaSource->bdir.empty()))
563 if( ref.mediaSource->bdir.empty())
565 // bnc#710269: Type nfs may appear as nfs4 in in the mount table
566 // and maybe vice versa. Similar cifs/smb. Need to unify these types:
567 if ( matchMountFs && e->type != ref.mediaSource->type )
569 if ( str::hasPrefix( e->type, "nfs" ) && str::hasPrefix( ref.mediaSource->type, "nfs" ) )
570 matchMountFs = false;
571 else if ( ( e->type == "cifs" || e->type == "smb" ) && ( ref.mediaSource->type == "cifs" || ref.mediaSource->type == "smb" ) )
572 matchMountFs = false;
574 continue; // different types cannot match
576 // Here: Types are ok or not to check.
577 // Check the name except for nfs (bnc#804544; symlink resolution in mount path)
579 // [fibonacci]$ ls -l /Local/ma/c12.1
580 // lrwxrwxrwx /Local/ma/c12.1 -> zypp-SuSE-Code-12_1-Branch/
582 // [localhost]$ mount -t nfs4 fibonacci:/Local/ma/c12.1 /mnt
583 // [localhost]$ mount
584 // fibonacci:/Local/ma/zypp-SuSE-Code-12_1-Branch on /mnt
586 // std::string mtype(matchMountFs ? e->type : ref.mediaSource->type);
587 // MediaSource media(mtype, e->src);
589 if( ref.mediaSource->name == e->src || str::hasPrefix( ref.mediaSource->type, "nfs" ) )
591 DBG << "Found media name "
592 << ref.mediaSource->asString()
593 << " in the mount table as " << e->src << std::endl;
600 if ( ref.mediaSource->bdir == e->src )
602 DBG << "Found bound media "
603 << ref.mediaSource->asString()
604 << " in the mount table as " << e->src << std::endl;
613 // Type ISO: Since 11.1 mtab might contain the name of
614 // the loop device instead of the iso file:
615 if ( ref.mediaSource->type == "iso"
616 && str::hasPrefix( Pathname(e->src).asString(), "/dev/loop" )
617 && ref.attachPoint->path == Pathname(e->dir) )
619 DBG << "Found bound media "
620 << ref.mediaSource->asString()
621 << " in the mount table as " << e->src << std::endl;
630 MIL << "Looking for " << ref << endl;
631 if( entries.empty() )
633 ERR << "Unable to find any entry in the /etc/mtab file" << std::endl;
637 dumpRange( DBG << "MountEntries: ", entries.begin(), entries.end() ) << endl;
641 ERR << "Attached media not in mount table any more - forcing reset!"
644 _mediaSource.reset();
648 WAR << "Attached media not in mount table ..." << std::endl;
651 // reset the mtime and force a new check to make sure,
652 // that we've found the media at least once in the mtab.
660 ///////////////////////////////////////////////////////////////////
663 // METHOD NAME : MediaHandler::attach
664 // METHOD TYPE : PMError
668 void MediaHandler::attach( bool next )
673 // reset it in case of overloaded isAttached()
674 // that checks the media against /etc/mtab ...
675 setMediaSource(MediaSourceRef());
677 AttachPoint ap( attachPointHint());
678 setAttachPoint(ap.path, ap.temp);
682 attachTo( next ); // pass to concrete handler
684 catch(const MediaException &e)
689 MIL << "Attached: " << *this << endl;
693 ///////////////////////////////////////////////////////////////////
696 // METHOD NAME : MediaHandler::localPath
697 // METHOD TYPE : Pathname
699 Pathname MediaHandler::localPath( const Pathname & pathname ) const
701 Pathname _localRoot( localRoot());
702 if ( _localRoot.empty() )
705 // we must check maximum file name length
706 // this is important for fetching the suseservers, the
707 // url with all parameters can get too long (bug #42021)
709 return _localRoot + pathname.absolutename();
716 ///////////////////////////////////////////////////////////////////
719 // METHOD NAME : MediaHandler::disconnect
720 // METHOD TYPE : PMError
722 void MediaHandler::disconnect()
727 disconnectFrom(); // pass to concrete handler
728 MIL << "Disconnected: " << *this << endl;
731 ///////////////////////////////////////////////////////////////////
734 // METHOD NAME : MediaHandler::release
735 // METHOD TYPE : PMError
739 void MediaHandler::release( const std::string & ejectDev )
741 if ( !isAttached() ) {
742 DBG << "Request to release media - not attached; eject '" << ejectDev << "'"
744 if ( !ejectDev.empty() )
745 forceEject(ejectDev);
749 DBG << "Request to release attached media "
750 << _mediaSource->asString()
751 << ", use count=" << _mediaSource.use_count()
754 if( _mediaSource.unique())
756 DBG << "Releasing media " << _mediaSource->asString() << std::endl;
758 releaseFrom( ejectDev ); // pass to concrete handler
760 catch(const MediaNotEjectedException &e)
762 // not ejected because the media
763 // is mounted by somebody else
764 // (if our attach point is busy,
765 // we get an umount exception)
766 _mediaSource.reset(NULL);
771 _mediaSource.reset(NULL);
774 else if( !ejectDev.empty() ) {
776 // Can't eject a shared media
778 //ZYPP_THROW(MediaIsSharedException(_mediaSource->asString()));
780 MediaSourceRef media( new MediaSource(*_mediaSource));
781 _mediaSource.reset(NULL);
783 MediaManager manager;
784 manager.forceReleaseShared(media);
786 setMediaSource(media);
787 DBG << "Releasing media (forced) " << _mediaSource->asString() << std::endl;
789 releaseFrom( ejectDev ); // pass to concrete handler
791 catch(const MediaNotEjectedException &e)
793 // not ejected because the media
794 // is mounted by somebody else
795 // (if our attach point is busy,
796 // we get an umount exception)
797 _mediaSource.reset(NULL);
802 _mediaSource.reset(NULL);
806 DBG << "Releasing shared media reference only" << std::endl;
807 _mediaSource.reset(NULL);
808 setAttachPoint("", true);
810 MIL << "Released: " << *this << endl;
813 void MediaHandler::forceRelaseAllMedia(bool matchMountFs)
815 forceRelaseAllMedia( attachedMedia().mediaSource, matchMountFs);
818 void MediaHandler::forceRelaseAllMedia(const MediaSourceRef &ref,
824 MountEntries entries( MediaManager::getMountEntries());
825 MountEntries::const_iterator e;
826 for( e = entries.begin(); e != entries.end(); ++e)
828 bool is_device = false;
831 if( str::hasPrefix( Pathname(e->src).asString(), "/dev/" ) &&
832 dev_info(e->src) && dev_info.isBlk())
837 if( is_device && ref->maj_nr)
839 std::string mtype(matchMountFs ? e->type : ref->type);
840 MediaSource media(mtype, e->src, dev_info.devMajor(), dev_info.devMinor());
842 if( ref->equals( media) && e->type != "subfs")
844 DBG << "Forcing release of media device "
846 << " in the mount table as "
847 << e->src << std::endl;
850 mount.umount(e->dir);
852 catch (const Exception &e)
859 if(!is_device && !ref->maj_nr)
861 std::string mtype(matchMountFs ? e->type : ref->type);
862 MediaSource media(mtype, e->src);
863 if( ref->equals( media))
865 DBG << "Forcing release of media name "
867 << " in the mount table as "
868 << e->src << std::endl;
871 mount.umount(e->dir);
873 catch (const Exception &e)
883 MediaHandler::checkAttachPoint(const Pathname &apoint) const
885 return MediaHandler::checkAttachPoint( apoint, true, false);
890 MediaHandler::checkAttachPoint(const Pathname &apoint,
894 if( apoint.empty() || !apoint.absolute())
896 ERR << "Attach point '" << apoint << "' is not absolute"
902 ERR << "Attach point '" << apoint << "' is not allowed"
907 PathInfo ainfo(apoint);
910 ERR << "Attach point '" << apoint << "' is not a directory"
917 if( 0 != zypp::filesystem::is_empty_dir(apoint))
919 ERR << "Attach point '" << apoint << "' is not a empty directory"
927 Pathname apath(apoint + "XXXXXX");
928 char *atemp = ::strdup( apath.asString().c_str());
930 if( !ainfo.userMayRWX() || atemp == NULL ||
931 (atest=::mkdtemp(atemp)) == NULL)
936 ERR << "Attach point '" << ainfo.path()
937 << "' is not a writeable directory" << std::endl;
940 else if( atest != NULL)
949 ///////////////////////////////////////////////////////////////////
951 // METHOD NAME : MediaHandler::dependsOnParent
952 // METHOD TYPE : bool
957 MediaHandler::dependsOnParent()
959 return _parentId != 0;
963 MediaHandler::dependsOnParent(MediaAccessId parentId, bool exactIdMatch)
967 if(parentId == _parentId)
973 AttachedMedia am1 = mm.getAttachedMedia(_parentId);
974 AttachedMedia am2 = mm.getAttachedMedia(parentId);
975 if( am1.mediaSource && am2.mediaSource)
977 return am1.mediaSource->equals( *(am2.mediaSource));
984 ///////////////////////////////////////////////////////////////////
987 // METHOD NAME : MediaHandler::provideFile
988 // METHOD TYPE : PMError
992 void MediaHandler::provideFileCopy(Pathname srcFilename,
993 Pathname targetFilename , const ByteCount &expectedFileSize_r) const
995 if ( !isAttached() ) {
996 INT << "Media not_attached on provideFileCopy(" << srcFilename
997 << "," << targetFilename << ")" << endl;
998 ZYPP_THROW(MediaNotAttachedException(url()));
1001 getFileCopy( srcFilename, targetFilename, expectedFileSize_r ); // pass to concrete handler
1002 DBG << "provideFileCopy(" << srcFilename << "," << targetFilename << ")" << endl;
1005 void MediaHandler::provideFile(Pathname filename , const ByteCount &expectedFileSize_r) const
1007 if ( !isAttached() ) {
1008 INT << "Error: Not attached on provideFile(" << filename << ")" << endl;
1009 ZYPP_THROW(MediaNotAttachedException(url()));
1012 getFile( filename, expectedFileSize_r ); // pass to concrete handler
1013 DBG << "provideFile(" << filename << ")" << endl;
1017 ///////////////////////////////////////////////////////////////////
1020 // METHOD NAME : MediaHandler::provideDir
1021 // METHOD TYPE : PMError
1025 void MediaHandler::provideDir( Pathname dirname ) const
1027 if ( !isAttached() ) {
1028 INT << "Error: Not attached on provideDir(" << dirname << ")" << endl;
1029 ZYPP_THROW(MediaNotAttachedException(url()));
1032 getDir( dirname, /*recursive*/false ); // pass to concrete handler
1033 MIL << "provideDir(" << dirname << ")" << endl;
1036 ///////////////////////////////////////////////////////////////////
1039 // METHOD NAME : MediaHandler::provideDirTree
1040 // METHOD TYPE : PMError
1044 void MediaHandler::provideDirTree( Pathname dirname ) const
1046 if ( !isAttached() ) {
1047 INT << "Error Not attached on provideDirTree(" << dirname << ")" << endl;
1048 ZYPP_THROW(MediaNotAttachedException(url()));
1051 getDir( dirname, /*recursive*/true ); // pass to concrete handler
1052 MIL << "provideDirTree(" << dirname << ")" << endl;
1055 ///////////////////////////////////////////////////////////////////
1058 // METHOD NAME : MediaHandler::releasePath
1059 // METHOD TYPE : PMError
1063 void MediaHandler::releasePath( Pathname pathname ) const
1065 if ( ! _does_download || _attachPoint->empty() )
1068 PathInfo info( localPath( pathname ) );
1070 if ( info.isFile() ) {
1071 unlink( info.path() );
1072 } else if ( info.isDir() ) {
1073 if ( info.path() != localRoot() ) {
1074 recursive_rmdir( info.path() );
1076 clean_dir( info.path() );
1081 ///////////////////////////////////////////////////////////////////
1084 // METHOD NAME : MediaHandler::dirInfo
1085 // METHOD TYPE : PMError
1089 void MediaHandler::dirInfo( std::list<std::string> & retlist,
1090 const Pathname & dirname, bool dots ) const
1094 if ( !isAttached() ) {
1095 INT << "Error: Not attached on dirInfo(" << dirname << ")" << endl;
1096 ZYPP_THROW(MediaNotAttachedException(url()));
1099 getDirInfo( retlist, dirname, dots ); // pass to concrete handler
1100 MIL << "dirInfo(" << dirname << ")" << endl;
1103 ///////////////////////////////////////////////////////////////////
1106 // METHOD NAME : MediaHandler::dirInfo
1107 // METHOD TYPE : PMError
1111 void MediaHandler::dirInfo( filesystem::DirContent & retlist,
1112 const Pathname & dirname, bool dots ) const
1116 if ( !isAttached() ) {
1117 INT << "Error: Not attached on dirInfo(" << dirname << ")" << endl;
1118 ZYPP_THROW(MediaNotAttachedException(url()));
1121 getDirInfo( retlist, dirname, dots ); // pass to concrete handler
1122 MIL << "dirInfo(" << dirname << ")" << endl;
1125 ///////////////////////////////////////////////////////////////////
1128 // METHOD NAME : MediaHandler::doesFileExist
1129 // METHOD TYPE : PMError
1133 bool MediaHandler::doesFileExist( const Pathname & filename ) const
1135 // TODO do some logging
1136 if ( !isAttached() ) {
1137 INT << "Error Not attached on doesFileExist(" << filename << ")" << endl;
1138 ZYPP_THROW(MediaNotAttachedException(url()));
1140 return getDoesFileExist( filename );
1141 MIL << "doesFileExist(" << filename << ")" << endl;
1144 ///////////////////////////////////////////////////////////////////
1147 // METHOD NAME : MediaHandler::getDirectoryYast
1148 // METHOD TYPE : PMError
1150 void MediaHandler::getDirectoryYast( std::list<std::string> & retlist,
1151 const Pathname & dirname, bool dots ) const
1155 filesystem::DirContent content;
1156 getDirectoryYast( content, dirname, dots );
1158 // convert to std::list<std::string>
1159 for ( filesystem::DirContent::const_iterator it = content.begin(); it != content.end(); ++it ) {
1160 retlist.push_back( it->name );
1164 ///////////////////////////////////////////////////////////////////
1167 // METHOD NAME : MediaHandler::getDirectoryYast
1168 // METHOD TYPE : PMError
1170 void MediaHandler::getDirectoryYast( filesystem::DirContent & retlist,
1171 const Pathname & dirname, bool dots ) const
1175 // look for directory.yast
1176 Pathname dirFile = dirname + "directory.yast";
1177 getFile( dirFile, 0 );
1178 DBG << "provideFile(" << dirFile << "): " << "OK" << endl;
1180 // using directory.yast
1181 ifstream dir( localPath( dirFile ).asString().c_str() );
1183 ERR << "Unable to load '" << localPath( dirFile ) << "'" << endl;
1184 ZYPP_THROW(MediaSystemException(url(),
1185 "Unable to load '" + localPath( dirFile ).asString() + "'"));
1189 while( getline( dir, line ) ) {
1190 if ( line.empty() ) continue;
1191 if ( line == "directory.yast" ) continue;
1193 // Newer directory.yast append '/' to directory names
1194 // Remaining entries are unspecified, although most probabely files.
1195 filesystem::FileType type = filesystem::FT_NOT_AVAIL;
1196 if ( *line.rbegin() == '/' ) {
1197 line.erase( line.end()-1 );
1198 type = filesystem::FT_DIR;
1202 if ( line == "." || line == ".." ) continue;
1204 if ( *line.begin() == '.' ) continue;
1207 retlist.push_back( filesystem::DirEntry( line, type ) );
1211 /******************************************************************
1214 ** FUNCTION NAME : operator<<
1215 ** FUNCTION TYPE : ostream &
1217 ostream & operator<<( ostream & str, const MediaHandler & obj )
1219 str << obj.url() << ( obj.isAttached() ? "" : " not" )
1220 << " attached; localRoot \"" << obj.localRoot() << "\"";
1224 ///////////////////////////////////////////////////////////////////
1227 // METHOD NAME : MediaHandler::getFile
1228 // METHOD TYPE : PMError
1230 // DESCRIPTION : Asserted that media is attached.
1231 // Default implementation of pure virtual.
1233 void MediaHandler::getFile(const Pathname & filename , const ByteCount &) const
1235 PathInfo info( localPath( filename ) );
1236 if( info.isFile() ) {
1241 ZYPP_THROW(MediaNotAFileException(url(), localPath(filename)));
1243 ZYPP_THROW(MediaFileNotFoundException(url(), filename));
1247 void MediaHandler::getFileCopy (const Pathname & srcFilename, const Pathname & targetFilename , const ByteCount &expectedFileSize_r) const
1249 getFile(srcFilename, expectedFileSize_r);
1251 if ( copy( localPath( srcFilename ), targetFilename ) != 0 ) {
1252 ZYPP_THROW(MediaWriteException(targetFilename));
1258 ///////////////////////////////////////////////////////////////////
1261 // METHOD NAME : MediaHandler::getDir
1262 // METHOD TYPE : PMError
1264 // DESCRIPTION : Asserted that media is attached.
1265 // Default implementation of pure virtual.
1267 void MediaHandler::getDir( const Pathname & dirname, bool recurse_r ) const
1269 PathInfo info( localPath( dirname ) );
1270 if( info.isDir() ) {
1275 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
1277 ZYPP_THROW(MediaFileNotFoundException(url(), dirname));
1280 ///////////////////////////////////////////////////////////////////
1283 // METHOD NAME : MediaHandler::getDirInfo
1284 // METHOD TYPE : PMError
1286 // DESCRIPTION : Asserted that media is attached and retlist is empty.
1287 // Default implementation of pure virtual.
1289 void MediaHandler::getDirInfo( std::list<std::string> & retlist,
1290 const Pathname & dirname, bool dots ) const
1292 PathInfo info( localPath( dirname ) );
1293 if( ! info.isDir() ) {
1294 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
1297 #if NONREMOTE_DIRECTORY_YAST
1298 // use directory.yast if available
1300 getDirectoryYast( retlist, dirname, dots );
1302 catch (const MediaException & excpt_r)
1307 int res = readdir( retlist, info.path(), dots );
1310 MediaSystemException nexcpt(url(), "readdir failed");
1311 #if NONREMOTE_DIRECTORY_YAST
1312 nexcpt.remember(excpt_r);
1317 #if NONREMOTE_DIRECTORY_YAST
1324 ///////////////////////////////////////////////////////////////////
1327 // METHOD NAME : MediaHandler::getDirInfo
1328 // METHOD TYPE : PMError
1330 // DESCRIPTION : Asserted that media is attached and retlist is empty.
1331 // Default implementation of pure virtual.
1333 void MediaHandler::getDirInfo( filesystem::DirContent & retlist,
1334 const Pathname & dirname, bool dots ) const
1336 PathInfo info( localPath( dirname ) );
1337 if( ! info.isDir() ) {
1338 ZYPP_THROW(MediaNotADirException(url(), localPath(dirname)));
1341 #if NONREMOTE_DIRECTORY_YAST
1342 // use directory.yast if available
1344 getDirectoryYast( retlist, dirname, dots );
1346 catch (const MediaException & excpt_r)
1351 int res = readdir( retlist, info.path(), dots );
1354 MediaSystemException nexcpt(url(), "readdir failed");
1355 #if NONREMOTE_DIRECTORY_YAST
1356 nexcpt.remember(excpt_r);
1360 #if NONREMOTE_DIRECTORY_YAST
1365 ///////////////////////////////////////////////////////////////////
1368 // METHOD NAME : MediaHandler::getDoesFileExist
1369 // METHOD TYPE : PMError
1371 // DESCRIPTION : Asserted that file is not a directory
1372 // Default implementation of pure virtual.
1374 bool MediaHandler::getDoesFileExist( const Pathname & filename ) const
1376 PathInfo info( localPath( filename ) );
1377 if( info.isDir() ) {
1378 ZYPP_THROW(MediaNotAFileException(url(), localPath(filename)));
1380 return info.isExist();
1383 bool MediaHandler::hasMoreDevices()
1388 void MediaHandler::getDetectedDevices(std::vector<std::string> & devices,
1389 unsigned int & index) const
1391 // clear the vector by default
1392 if (!devices.empty())
1396 DBG << "No devices for this medium" << endl;
1399 void MediaHandler::setDeltafile( const Pathname & filename ) const
1401 _deltafile = filename;
1404 Pathname MediaHandler::deltafile() const {
1408 } // namespace media
1410 // vim: set ts=8 sts=2 sw=2 ai noet: