#include <fstream>
#include <sstream>
-#include "zypp/base/Logger.h"
+#include "zypp/ZConfig.h"
+#include "zypp/TmpPath.h"
+#include "zypp/Date.h"
+#include "zypp/base/LogTools.h"
+#include "zypp/base/Gettext.h"
#include "zypp/base/String.h"
#include "zypp/media/MediaHandler.h"
#include "zypp/media/MediaManager.h"
#include "zypp/media/Mount.h"
+#include <limits.h>
+#include <stdlib.h>
+#include <errno.h>
+
using namespace std;
namespace zypp {
namespace media {
-
+ Pathname MediaHandler::_attachPrefix("");
///////////////////////////////////////////////////////////////////
//
const Pathname & attach_point_r,
const Pathname & urlpath_below_attachpoint_r,
const bool does_download_r )
- : _attachPoint( new AttachPoint())
+ : _mediaSource()
+ , _attachPoint( new AttachPoint())
+ , _attachPointHint()
, _relativeRoot( urlpath_below_attachpoint_r)
, _does_download( does_download_r )
, _attach_mtime(0)
, _url( url_r )
, _parentId(0)
{
- if ( !attach_point_r.empty() ) {
+ Pathname real_attach_point( getRealPath(attach_point_r.asString()));
+
+ if ( !real_attach_point.empty() ) {
///////////////////////////////////////////////////////////////////
// check if provided attachpoint is usable.
///////////////////////////////////////////////////////////////////
- PathInfo adir( attach_point_r );
- // FIXME: verify if attach_point_r isn't a mountpoint of other device
- if ( !adir.isDir() ) {
- ERR << "Provided attach point is not a directory: " << adir << endl;
+ PathInfo adir( real_attach_point );
+ //
+ // The verify if attach_point_r isn't a mountpoint of another
+ // device is done in the particular media handler (if needed).
+ //
+ // We just verify, if attach_point_r is a directory and for
+ // schemes other than "file" and "dir", if it is absolute.
+ //
+ if ( !adir.isDir()
+ || (_url.getScheme() != "file"
+ && _url.getScheme() != "dir"
+ && !real_attach_point.absolute()) )
+ {
+ ERR << "Provided attach point is not a absolute directory: "
+ << adir << endl;
}
else {
- setAttachPoint( attach_point_r, false);
+ attachPointHint( real_attach_point, false);
+ setAttachPoint( real_attach_point, false);
}
}
}
catch(...) {}
}
+void
+MediaHandler::resetParentId()
+{
+ _parentId = 0;
+}
+
+std::string
+MediaHandler::getRealPath(const std::string &path)
+{
+ std::string real;
+ if( !path.empty())
+ {
+#if __GNUC__ > 2
+ /** GNU extension */
+ char *ptr = ::realpath(path.c_str(), NULL);
+ if( ptr != NULL)
+ {
+ real = ptr;
+ free( ptr);
+ }
+ else
+ /** the SUSv2 way */
+ if( EINVAL == errno)
+ {
+ char buff[PATH_MAX + 2];
+ memset(buff, '\0', sizeof(buff));
+ if( ::realpath(path.c_str(), buff) != NULL)
+ {
+ real = buff;
+ }
+ }
+#else
+ char buff[PATH_MAX + 2];
+ memset(buff, '\0', sizeof(buff));
+ if( ::realpath(path.c_str(), buff) != NULL)
+ {
+ real = buff;
+ }
+#endif
+ }
+ return real;
+}
+
+zypp::Pathname
+MediaHandler::getRealPath(const Pathname &path)
+{
+ return zypp::Pathname(getRealPath(path.asString()));
+}
+
+
///////////////////////////////////////////////////////////////////
//
//
}
else
{
- if( !_attachPoint->temp)
+ if( !_attachPoint->path.empty() && !_attachPoint->temp)
DBG << "MediaHandler - attachpoint is not temporary" << endl;
}
}
void
MediaHandler::setAttachPoint(const Pathname &path, bool temporary)
{
- _localRoot = Pathname();
-
_attachPoint.reset( new AttachPoint(path, temporary));
-
- if( !_attachPoint->path.empty())
- _localRoot = _attachPoint->path + _relativeRoot;
}
+Pathname
+MediaHandler::localRoot() const
+{
+ if( _attachPoint->path.empty())
+ return Pathname();
+ else
+ return _attachPoint->path + _relativeRoot;
+}
///////////////////////////////////////////////////////////////////
//
void
MediaHandler::setAttachPoint(const AttachPointRef &ref)
{
- _localRoot = Pathname();
-
if( ref)
AttachPointRef(ref).swap(_attachPoint);
else
_attachPoint.reset( new AttachPoint());
+}
- if( !_attachPoint->path.empty())
- _localRoot = _attachPoint->path + _relativeRoot;
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : MediaHandler::attachPointHint
+// METHOD TYPE : void
+//
+// DESCRIPTION :
+//
+void
+MediaHandler::attachPointHint(const Pathname &path, bool temporary)
+{
+ _attachPointHint.path = path;
+ _attachPointHint.temp = temporary;
}
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : MediaHandler::attachPointHint
+// METHOD TYPE : AttachPoint
+//
+// DESCRIPTION :
+//
+AttachPoint
+MediaHandler::attachPointHint() const
+{
+ return _attachPointHint;
+}
///////////////////////////////////////////////////////////////////
//
return MediaManager().findAttachedMedia(media);
}
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : MediaHandler::setAttachPrefix
+// METHOD TYPE : void
+//
+// DESCRIPTION :
+//
+bool
+MediaHandler::setAttachPrefix(const Pathname &attach_prefix)
+{
+ if( attach_prefix.empty())
+ {
+ MIL << "Reseting to built-in attach point prefixes."
+ << std::endl;
+ MediaHandler::_attachPrefix = attach_prefix;
+ return true;
+ }
+ else
+ if( MediaHandler::checkAttachPoint(attach_prefix, false, true))
+ {
+ MIL << "Setting user defined attach point prefix: "
+ << attach_prefix << std::endl;
+ MediaHandler::_attachPrefix = attach_prefix;
+ return true;
+ }
+ return false;
+}
///////////////////////////////////////////////////////////////////
//
Pathname
MediaHandler::createAttachPoint() const
{
- /////////////////////////////////////////////////////////////////
- // provide a default (temporary) attachpoint
- /////////////////////////////////////////////////////////////////
- const char * defmounts[] = {
- "/var/adm/mount", "/var/tmp", /**/NULL/**/
- };
+ Pathname aroot;
+ Pathname apoint;
+ {
+ aroot = MediaHandler::_attachPrefix; // explicit request
+ if ( ! aroot.empty() )
+ apoint = createAttachPoint( aroot );
+ }
+
+ if ( apoint.empty() ) // fallback to config value
+ {
+ aroot = ZConfig::instance().download_mediaMountdir();
+ if ( ! aroot.empty() )
+ apoint = createAttachPoint( aroot );
+ }
+
+ if ( apoint.empty() ) // fall back to temp space
+ {
+ aroot = filesystem::TmpPath::defaultLocation();
+ if ( ! aroot.empty() )
+ apoint = createAttachPoint( aroot );
+ }
+
+ if ( apoint.empty() )
+ {
+ auto except = MediaBadAttachPointException( url() );
+ except.addHistory( _("Create attach point: Can't find a writable directory to create an attach point") );
+ ZYPP_THROW( std::move(except) );
+ }
+ MIL << "Created default attach point " << apoint << std::endl;
+ return apoint;
+}
+
+Pathname
+MediaHandler::createAttachPoint(const Pathname &attach_root) const
+{
Pathname apoint;
- Pathname aroot;
- PathInfo adir;
- for ( const char ** def = defmounts; *def && apoint.empty(); ++def ) {
- adir( *def );
- if ( !adir.isDir() || !adir.userMayRWX() )
- continue;
- aroot = adir.path();
- if( aroot.empty())
- continue;
+ if( attach_root.empty() || !attach_root.absolute()) {
+ ERR << "Create attach point: invalid attach root: '"
+ << attach_root << "'" << std::endl;
+ return apoint;
+ }
- DBG << "Trying to create attachPoint in " << aroot << std::endl;
+ PathInfo adir( attach_root );
+ if( !adir.isDir() || (geteuid() != 0 && !adir.userMayRWX())) {
+ DBG << "Create attach point: attach root is not a writable directory: '"
+ << attach_root << "'" << std::endl;
+ return apoint;
+ }
- //
- // FIXME: use mkdtemp
- //
- Pathname abase( aroot + "AP_" );
- // ma and sh need more than 42 for debugging :-)
- // since the readonly fs are handled now, ...
- for ( unsigned i = 1; i < 1000; ++i ) {
- adir( Pathname::extend( abase, str::hexstring( i ) ) );
- if ( ! adir.isExist() ) {
- int err = mkdir( adir.path() );
- if (err == 0 ) {
- apoint = adir.path();
- break;
- }
- else
- if (err != EEXIST) // readonly fs or other, dont try further
- break;
+ static bool cleanup_once( true );
+ if ( cleanup_once )
+ {
+ cleanup_once = false;
+ DBG << "Look for orphaned attach points in " << adir << std::endl;
+ std::list<std::string> entries;
+ filesystem::readdir( entries, attach_root, false );
+ for ( const std::string & entry : entries )
+ {
+ if ( ! str::hasPrefix( entry, "AP_0x" ) )
+ continue;
+ PathInfo sdir( attach_root + entry );
+ if ( sdir.isDir()
+ && sdir.dev() == adir.dev()
+ && ( Date::now()-sdir.mtime() > Date::month ) )
+ {
+ DBG << "Remove orphaned attach point " << sdir << std::endl;
+ filesystem::recursive_rmdir( sdir.path() );
}
}
}
- if ( aroot.empty() ) {
- ERR << "Create attach point: Can't find a writable directory to create an attach point" << std::endl;
- return aroot;
+ filesystem::TmpDir tmpdir( attach_root, "AP_0x" );
+ if ( tmpdir )
+ {
+ apoint = getRealPath( tmpdir.path().asString() );
+ if ( ! apoint.empty() )
+ {
+ tmpdir.autoCleanup( false ); // Take responsibility for cleanup.
+ }
+ else
+ {
+ ERR << "Unable to resolve real path for attach point " << tmpdir << std::endl;
+ }
}
-
- if ( apoint.empty() ) {
- ERR << "Unable to create an attach point below " << aroot << std::endl;
- } else {
- MIL << "Created default attach point " << apoint << std::endl;
+ else
+ {
+ ERR << "Unable to create attach point below " << attach_root << std::endl;
}
return apoint;
}
-
///////////////////////////////////////////////////////////////////
//
//
// DESCRIPTION :
//
bool
-MediaHandler::isUseableAttachPoint(const Pathname &path) const
+MediaHandler::isUseableAttachPoint(const Pathname &path, bool mtab) const
{
- if( path.empty() || path == "/" || !PathInfo(path).isDir())
- return false;
-
MediaManager manager;
- MountEntries entries( manager.getMountEntries());
- MountEntries::const_iterator e;
-
- for( e = entries.begin(); e != entries.end(); ++e)
- {
- std::string mnt(Pathname(e->dir).asString());
-
- if( path == mnt)
- {
- // already used as mountpoint
- return false;
- }
- else
- {
- std::string our(path.asString());
-
- // mountpoint is bellow of path
- // (would hide the content)
- if( mnt.size() > our.size() &&
- mnt.at(our.size()) == '/' &&
- !mnt.compare(0, our.size(), our))
- return false;
- }
- }
-
- return true;
+ return manager.isUseableAttachPoint(path, mtab);
}
// DESCRIPTION :
//
bool
-MediaHandler::checkAttached(bool isDevice, bool fsType) const
+MediaHandler::checkAttached(bool matchMountFs) const
{
bool _isAttached = false;
- AttachedMedia ref( attachedMedia());
- if( ref.mediaSource)
+ AttachedMedia ref( attachedMedia() );
+ if( ref.mediaSource )
{
- MediaManager manager;
-
- time_t old = _attach_mtime;
- _attach_mtime = manager.getMountTableMTime();
- if( !(old <= 0 || _attach_mtime != old))
+ time_t old_mtime = _attach_mtime;
+ _attach_mtime = MediaManager::getMountTableMTime();
+ if( !(old_mtime <= 0 || _attach_mtime != old_mtime) )
{
- // OK, skip the check
+ // OK, skip the check (we've seen it at least once)
_isAttached = true;
}
else
{
- DBG << "Mount table changed - rereading it" << std::endl;
- MountEntries entries( manager.getMountEntries());
- MountEntries::const_iterator e;
- for( e = entries.begin(); e != entries.end(); ++e)
+ if( old_mtime > 0)
+ DBG << "Mount table changed - rereading it" << std::endl;
+ else
+ DBG << "Forced check of the mount table" << std::endl;
+
+ MountEntries entries( MediaManager::getMountEntries());
+ for_( e, entries.begin(), entries.end() )
{
- bool is_device = (Pathname(e->src).dirname() == "/dev");
- if( is_device == isDevice)
+ if ( ref.attachPoint->path != Pathname(e->dir) )
+ continue; // at least the mount points must match
+
+ bool is_device = false;
+ PathInfo dev_info;
+ if( str::hasPrefix( Pathname(e->src).asString(), "/dev/" ) &&
+ dev_info(e->src) && dev_info.isBlk() )
+ {
+ is_device = true;
+ }
+
+ if( is_device && (ref.mediaSource->maj_nr &&
+ ref.mediaSource->bdir.empty()))
{
- PathInfo dinfo(e->src);
- std::string mtype(fsType ? e->type : ref.mediaSource->type);
- MediaSource media(mtype, e->src, dinfo.major(), dinfo.minor());
+ std::string mtype(matchMountFs ? e->type : ref.mediaSource->type);
+ MediaSource media(mtype, e->src, dev_info.devMajor(), dev_info.devMinor());
- if( ref.mediaSource->equals( media) &&
- ref.attachPoint->path == Pathname(e->dir))
+ if( ref.mediaSource->equals( media ) )
{
- DBG << "Found media "
+ DBG << "Found media device "
<< ref.mediaSource->asString()
- << " in the mount table" << std::endl;
+ << " in the mount table as " << e->src << std::endl;
_isAttached = true;
break;
}
// differs
}
else
+ if(!is_device && (!ref.mediaSource->maj_nr ||
+ !ref.mediaSource->bdir.empty()))
{
- std::string mtype(fsType ? e->type : ref.mediaSource->type);
- MediaSource media(mtype, e->src);
- if( ref.mediaSource->equals( media) &&
- ref.attachPoint->path == Pathname(e->dir))
- {
- DBG << "Found media "
- << ref.mediaSource->asString()
- << " in the mount table" << std::endl;
- _isAttached = true;
- break;
- }
+ if( ref.mediaSource->bdir.empty())
+ {
+ // bnc#710269: Type nfs may appear as nfs4 in in the mount table
+ // and maybe vice versa. Similar cifs/smb. Need to unify these types:
+ if ( matchMountFs && e->type != ref.mediaSource->type )
+ {
+ if ( str::hasPrefix( e->type, "nfs" ) && str::hasPrefix( ref.mediaSource->type, "nfs" ) )
+ matchMountFs = false;
+ else if ( ( e->type == "cifs" || e->type == "smb" ) && ( ref.mediaSource->type == "cifs" || ref.mediaSource->type == "smb" ) )
+ matchMountFs = false;
+ else
+ continue; // different types cannot match
+ }
+ // Here: Types are ok or not to check.
+ // Check the name except for nfs (bnc#804544; symlink resolution in mount path)
+ //
+ // [fibonacci]$ ls -l /Local/ma/c12.1
+ // lrwxrwxrwx /Local/ma/c12.1 -> zypp-SuSE-Code-12_1-Branch/
+ //
+ // [localhost]$ mount -t nfs4 fibonacci:/Local/ma/c12.1 /mnt
+ // [localhost]$ mount
+ // fibonacci:/Local/ma/zypp-SuSE-Code-12_1-Branch on /mnt
+
+ // std::string mtype(matchMountFs ? e->type : ref.mediaSource->type);
+ // MediaSource media(mtype, e->src);
+
+ if( ref.mediaSource->name == e->src || str::hasPrefix( ref.mediaSource->type, "nfs" ) )
+ {
+ DBG << "Found media name "
+ << ref.mediaSource->asString()
+ << " in the mount table as " << e->src << std::endl;
+ _isAttached = true;
+ break;
+ }
+ }
+ else
+ {
+ if ( ref.mediaSource->bdir == e->src )
+ {
+ DBG << "Found bound media "
+ << ref.mediaSource->asString()
+ << " in the mount table as " << e->src << std::endl;
+ _isAttached = true;
+ break;
+ }
+ }
// differs
}
}
if( !_isAttached)
{
- ERR << "Attached media not in mount entry table any more"
- << std::endl;
+ MIL << "Looking for " << ref << endl;
+ if( entries.empty() )
+ {
+ ERR << "Unable to find any entry in the /etc/mtab file" << std::endl;
+ }
+ else
+ {
+ dumpRange( DBG << "MountEntries: ", entries.begin(), entries.end() ) << endl;
+ }
+ if( old_mtime > 0 )
+ {
+ ERR << "Attached media not in mount table any more - forcing reset!"
+ << std::endl;
+
+ _mediaSource.reset();
+ }
+ else
+ {
+ WAR << "Attached media not in mount table ..." << std::endl;
+ }
+
+ // reset the mtime and force a new check to make sure,
+ // that we've found the media at least once in the mtab.
+ _attach_mtime = 0;
}
}
}
// that checks the media against /etc/mtab ...
setMediaSource(MediaSourceRef());
- attachTo( next ); // pass to concrete handler
+ AttachPoint ap( attachPointHint());
+ setAttachPoint(ap.path, ap.temp);
+
+ try
+ {
+ attachTo( next ); // pass to concrete handler
+ }
+ catch(const MediaException &e)
+ {
+ removeAttachPoint();
+ ZYPP_RETHROW(e);
+ }
MIL << "Attached: " << *this << endl;
}
-
-
///////////////////////////////////////////////////////////////////
//
//
// METHOD NAME : MediaHandler::localPath
// METHOD TYPE : Pathname
//
-Pathname MediaHandler::localPath( const Pathname & pathname ) const {
+Pathname MediaHandler::localPath( const Pathname & pathname ) const
+{
+ Pathname _localRoot( localRoot());
if ( _localRoot.empty() )
return _localRoot;
//
// DESCRIPTION :
//
-void MediaHandler::release( bool eject )
+void MediaHandler::release( const std::string & ejectDev )
{
if ( !isAttached() ) {
- DBG << "Request to release media - not attached" << std::endl;
- if ( eject )
- forceEject();
+ DBG << "Request to release media - not attached; eject '" << ejectDev << "'"
+ << std::endl;
+ if ( !ejectDev.empty() )
+ forceEject(ejectDev);
return;
}
if( _mediaSource.unique())
{
DBG << "Releasing media " << _mediaSource->asString() << std::endl;
- releaseFrom( eject ); // pass to concrete handler
+ try {
+ releaseFrom( ejectDev ); // pass to concrete handler
+ }
+ catch(const MediaNotEjectedException &e)
+ {
+ // not ejected because the media
+ // is mounted by somebody else
+ // (if our attach point is busy,
+ // we get an umount exception)
+ _mediaSource.reset(NULL);
+ removeAttachPoint();
+ // OK, retrow now
+ ZYPP_RETHROW(e);
+ }
_mediaSource.reset(NULL);
removeAttachPoint();
}
- else if( eject) {
+ else if( !ejectDev.empty() ) {
//
// Can't eject a shared media
//
_mediaSource.reset(NULL);
MediaManager manager;
- manager.forceMediaRelease(media);
+ manager.forceReleaseShared(media);
setMediaSource(media);
DBG << "Releasing media (forced) " << _mediaSource->asString() << std::endl;
- releaseFrom( eject ); // pass to concrete handler
+ try {
+ releaseFrom( ejectDev ); // pass to concrete handler
+ }
+ catch(const MediaNotEjectedException &e)
+ {
+ // not ejected because the media
+ // is mounted by somebody else
+ // (if our attach point is busy,
+ // we get an umount exception)
+ _mediaSource.reset(NULL);
+ removeAttachPoint();
+ // OK, retrow now
+ ZYPP_RETHROW(e);
+ }
_mediaSource.reset(NULL);
removeAttachPoint();
}
else {
DBG << "Releasing shared media reference only" << std::endl;
_mediaSource.reset(NULL);
- //setAttachPoint("", true);
+ setAttachPoint("", true);
}
MIL << "Released: " << *this << endl;
}
+void MediaHandler::forceRelaseAllMedia(bool matchMountFs)
+{
+ forceRelaseAllMedia( attachedMedia().mediaSource, matchMountFs);
+}
+
+void MediaHandler::forceRelaseAllMedia(const MediaSourceRef &ref,
+ bool matchMountFs)
+{
+ if( !ref)
+ return;
+
+ MountEntries entries( MediaManager::getMountEntries());
+ MountEntries::const_iterator e;
+ for( e = entries.begin(); e != entries.end(); ++e)
+ {
+ bool is_device = false;
+ PathInfo dev_info;
+
+ if( str::hasPrefix( Pathname(e->src).asString(), "/dev/" ) &&
+ dev_info(e->src) && dev_info.isBlk())
+ {
+ is_device = true;
+ }
+
+ if( is_device && ref->maj_nr)
+ {
+ std::string mtype(matchMountFs ? e->type : ref->type);
+ MediaSource media(mtype, e->src, dev_info.devMajor(), dev_info.devMinor());
+
+ if( ref->equals( media) && e->type != "subfs")
+ {
+ DBG << "Forcing release of media device "
+ << ref->asString()
+ << " in the mount table as "
+ << e->src << std::endl;
+ try {
+ Mount mount;
+ mount.umount(e->dir);
+ }
+ catch (const Exception &e)
+ {
+ ZYPP_CAUGHT(e);
+ }
+ }
+ }
+ else
+ if(!is_device && !ref->maj_nr)
+ {
+ std::string mtype(matchMountFs ? e->type : ref->type);
+ MediaSource media(mtype, e->src);
+ if( ref->equals( media))
+ {
+ DBG << "Forcing release of media name "
+ << ref->asString()
+ << " in the mount table as "
+ << e->src << std::endl;
+ try {
+ Mount mount;
+ mount.umount(e->dir);
+ }
+ catch (const Exception &e)
+ {
+ ZYPP_CAUGHT(e);
+ }
+ }
+ }
+ }
+}
+
+bool
+MediaHandler::checkAttachPoint(const Pathname &apoint) const
+{
+ return MediaHandler::checkAttachPoint( apoint, true, false);
+}
+
+// STATIC
+bool
+MediaHandler::checkAttachPoint(const Pathname &apoint,
+ bool emptydir,
+ bool writeable)
+{
+ if( apoint.empty() || !apoint.absolute())
+ {
+ ERR << "Attach point '" << apoint << "' is not absolute"
+ << std::endl;
+ return false;
+ }
+ if( apoint == "/")
+ {
+ ERR << "Attach point '" << apoint << "' is not allowed"
+ << std::endl;
+ return false;
+ }
+
+ PathInfo ainfo(apoint);
+ if( !ainfo.isDir())
+ {
+ ERR << "Attach point '" << apoint << "' is not a directory"
+ << std::endl;
+ return false;
+ }
+
+ if( emptydir)
+ {
+ if( 0 != zypp::filesystem::is_empty_dir(apoint))
+ {
+ ERR << "Attach point '" << apoint << "' is not a empty directory"
+ << std::endl;
+ return false;
+ }
+ }
+
+ if( writeable)
+ {
+ Pathname apath(apoint + "XXXXXX");
+ char *atemp = ::strdup( apath.asString().c_str());
+ char *atest = NULL;
+ if( !ainfo.userMayRWX() || atemp == NULL ||
+ (atest=::mkdtemp(atemp)) == NULL)
+ {
+ if( atemp != NULL)
+ ::free(atemp);
+
+ ERR << "Attach point '" << ainfo.path()
+ << "' is not a writeable directory" << std::endl;
+ return false;
+ }
+ else if( atest != NULL)
+ ::rmdir(atest);
+
+ if( atemp != NULL)
+ ::free(atemp);
+ }
+ return true;
+}
+
///////////////////////////////////////////////////////////////////
//
// METHOD NAME : MediaHandler::dependsOnParent
// DESCRIPTION :
//
bool
-MediaHandler::dependsOnParent(MediaAccessId parentId)
+MediaHandler::dependsOnParent()
+{
+ return _parentId != 0;
+}
+
+bool
+MediaHandler::dependsOnParent(MediaAccessId parentId, bool exactIdMatch)
{
if( _parentId != 0)
{
if(parentId == _parentId)
return true;
-
- MediaManager mm;
- AttachedMedia am1 = mm.getAttachedMedia(_parentId);
- AttachedMedia am2 = mm.getAttachedMedia(parentId);
- if( am1.mediaSource && am2.mediaSource)
+
+ if( !exactIdMatch)
{
- return am1.mediaSource->equals( *(am2.mediaSource));
+ MediaManager mm;
+ AttachedMedia am1 = mm.getAttachedMedia(_parentId);
+ AttachedMedia am2 = mm.getAttachedMedia(parentId);
+ if( am1.mediaSource && am2.mediaSource)
+ {
+ return am1.mediaSource->equals( *(am2.mediaSource));
+ }
}
}
return false;
if ( info.isFile() ) {
unlink( info.path() );
} else if ( info.isDir() ) {
- if ( info.path() != _localRoot ) {
+ if ( info.path() != localRoot() ) {
recursive_rmdir( info.path() );
} else {
clean_dir( info.path() );
//
// DESCRIPTION :
//
-void MediaHandler::dirInfo( list<string> & retlist,
- const Pathname & dirname, bool dots ) const
+void MediaHandler::dirInfo( std::list<std::string> & retlist,
+ const Pathname & dirname, bool dots ) const
{
retlist.clear();
///////////////////////////////////////////////////////////////////
//
//
+// METHOD NAME : MediaHandler::doesFileExist
+// METHOD TYPE : PMError
+//
+// DESCRIPTION :
+//
+bool MediaHandler::doesFileExist( const Pathname & filename ) const
+{
+ // TODO do some logging
+ if ( !isAttached() ) {
+ INT << "Error Not attached on doesFileExist(" << filename << ")" << endl;
+ ZYPP_THROW(MediaNotAttachedException(url()));
+ }
+ return getDoesFileExist( filename );
+ MIL << "doesFileExist(" << filename << ")" << endl;
+}
+
+///////////////////////////////////////////////////////////////////
+//
+//
// METHOD NAME : MediaHandler::getDirectoryYast
// METHOD TYPE : PMError
//
{
#endif
- // readdir
+ // readdir
int res = readdir( retlist, info.path(), dots );
- if ( res )
- ZYPP_THROW(MediaSystemException(url(), "readdir failed"));
+ if ( res )
+ {
+ MediaSystemException nexcpt(url(), "readdir failed");
+#if NONREMOTE_DIRECTORY_YAST
+ nexcpt.remember(excpt_r);
+#endif
+ ZYPP_THROW(nexcpt);
+ }
#if NONREMOTE_DIRECTORY_YAST
}
{
#endif
- // readdir
- int res = readdir( retlist, info.path(), dots );
- if ( res )
- ZYPP_THROW(MediaSystemException(url(), "readdir failed"));
+ // readdir
+ int res = readdir( retlist, info.path(), dots );
+ if ( res )
+ {
+ MediaSystemException nexcpt(url(), "readdir failed");
+#if NONREMOTE_DIRECTORY_YAST
+ nexcpt.remember(excpt_r);
+#endif
+ ZYPP_THROW(nexcpt);
+ }
#if NONREMOTE_DIRECTORY_YAST
}
#endif
}
+///////////////////////////////////////////////////////////////////
+//
+//
+// METHOD NAME : MediaHandler::getDoesFileExist
+// METHOD TYPE : PMError
+//
+// DESCRIPTION : Asserted that file is not a directory
+// Default implementation of pure virtual.
+//
+bool MediaHandler::getDoesFileExist( const Pathname & filename ) const
+{
+ PathInfo info( localPath( filename ) );
+ if( info.isDir() ) {
+ ZYPP_THROW(MediaNotAFileException(url(), localPath(filename)));
+ }
+ return info.isExist();
+}
+
+bool MediaHandler::hasMoreDevices()
+{
+ return false;
+}
+
+void MediaHandler::getDetectedDevices(std::vector<std::string> & devices,
+ unsigned int & index) const
+{
+ // clear the vector by default
+ if (!devices.empty())
+ devices.clear();
+ index = 0;
+
+ DBG << "No devices for this medium" << endl;
+}
+
+void MediaHandler::setDeltafile( const Pathname & filename ) const
+{
+ _deltafile = filename;
+}
+
+Pathname MediaHandler::deltafile() const {
+ return _deltafile;
+}
+
} // namespace media
} // namespace zypp
+// vim: set ts=8 sts=2 sw=2 ai noet: