Apt-mark: implement storing and retrieving list of automatically-installed packages.

This commit is contained in:
Aleksei Nikiforov 2017-10-26 17:48:17 +03:00
parent 9d47fcf4db
commit 0834061d1f
4 changed files with 90 additions and 7 deletions

View File

@ -32,6 +32,11 @@
#include <apti18n.h>
#include <cstdio>
#include <fcntl.h>
#include <unistd.h>
#include <fstream>
/*}}}*/
// DepCache::pkgDepCache - Constructors /*{{{*/
@ -667,14 +672,92 @@ void pkgDepCache::Update(PkgIterator const &Pkg)
Update(P.ParentPkg().RevDependsList());
}
bool pkgDepCache::readStateFile(OpProgress * const prog)
bool pkgDepCache::readStateFile(OpProgress * const /*prog*/)
{
return false;
std::string AptMarkStorageFileName = _config->FindFile("Dir::State::apt_mark_storage");
std::set<std::string> auto_installed_packages;
{
std::ifstream StateFile(AptMarkStorageFileName);
std::string line;
if (!StateFile.is_open())
{
// No extended state file - just skip rest of function and exit
_error->Warning(_("Failed to open file: %s\n"), AptMarkStorageFileName.c_str());
return true;
}
while (std::getline(StateFile, line))
{
auto_installed_packages.insert(line);
}
}
for (auto iter = PkgBegin(); !iter.end(); ++iter)
{
if (auto_installed_packages.find(iter.Name()) != auto_installed_packages.end())
{
PkgState[iter->ID].Flags |= Flag::Auto;
}
}
return true;
}
bool pkgDepCache::writeStateFile(OpProgress * const prog, bool const InstalledOnly)
bool pkgDepCache::writeStateFile(OpProgress * const /*prog*/)
{
return false;
std::string AptMarkStorageFileName = _config->FindFile("Dir::State::apt_mark_storage");
// create a temporary file in same directory
std::string AptMarkTempFileName;
{
std::string::size_type delim_index = AptMarkStorageFileName.rfind('/');
if ((delim_index == std::string::npos) || (delim_index == 0) || (delim_index == AptMarkStorageFileName.length()))
{
return _error->Error(_("Invalid value of \"Dir::State::apt_mark_storage\": %s"), AptMarkStorageFileName.c_str());
}
AptMarkTempFileName = AptMarkStorageFileName.substr(0, delim_index + 1) + ".__tmp__apt_mark_storage";
}
FileFd StateFile(AptMarkTempFileName, FileFd::WriteTemp, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
StateFile.EraseOnFailure();
{
std::string linestr;
for (auto iter = PkgBegin(); !iter.end(); ++iter)
{
StateCache const &stateCache = PkgState[iter->ID];
if ((stateCache.Flags & Flag::Auto) == Flag::Auto)
{
linestr = iter.Name();
linestr += '\n';
if (!StateFile.Write(linestr.c_str(), linestr.length()))
{
return false;
}
}
}
}
if (!StateFile.Close())
{
return false;
}
if (rename(AptMarkTempFileName.c_str(), AptMarkStorageFileName.c_str()) != 0)
{
unlink(AptMarkTempFileName.c_str());
return _error->Error(_("Failed to replace file: %s"), AptMarkStorageFileName.c_str());
}
return true;
}
// DepCache::MarkKeep - Put the package in the keep state /*{{{*/

View File

@ -223,7 +223,7 @@ class pkgDepCache : protected pkgCache::Namespace
// read and write persistent states
bool readStateFile(OpProgress * const prog);
bool writeStateFile(OpProgress * const prog, bool const InstalledOnly = true);
bool writeStateFile(OpProgress * const prog);
// Size queries
inline double UsrSize() {return iUsrSize;};

View File

@ -528,7 +528,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
Ret &= DoClean(*CmdL);
else if (_config->FindB("APT::Post-Install::AutoClean",false) == true)
Ret &= DoAutoClean(*CmdL);
Cache->writeStateFile(0, false);
Cache->writeStateFile(0);
return Ret;
}

View File

@ -992,7 +992,7 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
Ret &= DoClean(*CmdL);
else if (_config->FindB("APT::Post-Install::AutoClean",false) == true)
Ret &= DoAutoClean(*CmdL);
Cache->writeStateFile(0, false);
Cache->writeStateFile(0);
return Ret;
}