#include <sstream>
#include "zypp/TmpPath.h"
+#include "zypp/Date.h"
#include "zypp/base/LogTools.h"
#include "zypp/base/String.h"
#include "zypp/media/MediaHandler.h"
return apoint;
}
- PathInfo adir( attach_root);
+ PathInfo adir( attach_root );
if( !adir.isDir() || (getuid() != 0 && !adir.userMayRWX())) {
DBG << "Create attach point: attach root is not a writable directory: '"
<< attach_root << "'" << std::endl;
return apoint;
}
- DBG << "Trying to create attach point in " << attach_root << std::endl;
-
- //
- // FIXME: use mkdtemp?
- //
-#warning Use class TmpDir from TmpPath.h
- Pathname abase( attach_root + "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 = getRealPath(adir.asString());
- if( apoint.empty())
- {
- ERR << "Unable to resolve a real path for "
- << adir.path() << std::endl;
- rmdir(adir.path());
- }
- 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() );
}
- else
- if (err != EEXIST) // readonly fs or other, dont try further
- break;
}
}
- if ( apoint.empty()) {
- ERR << "Unable to create an attach point below of "
- << attach_root << std::endl;
+ 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;
+ }
+ }
+ else
+ {
+ ERR << "Unable to create attach point below " << attach_root << std::endl;
}
return apoint;
}