diff options
Diffstat (limited to '')
-rw-r--r-- | apt-pkg/update.cc | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/apt-pkg/update.cc b/apt-pkg/update.cc new file mode 100644 index 0000000..1bf818a --- /dev/null +++ b/apt-pkg/update.cc @@ -0,0 +1,152 @@ +// Include Files /*{{{*/ +#include <config.h> + +#include <apt-pkg/acquire-item.h> +#include <apt-pkg/acquire.h> +#include <apt-pkg/configuration.h> +#include <apt-pkg/error.h> +#include <apt-pkg/fileutl.h> +#include <apt-pkg/sourcelist.h> +#include <apt-pkg/strutl.h> +#include <apt-pkg/update.h> + +#include <string> + +#include <apti18n.h> + /*}}}*/ + +using namespace std; + +// ListUpdate - construct Fetcher and update the cache files /*{{{*/ +// --------------------------------------------------------------------- +/* This is a simple wrapper to update the cache. it will fetch stuff + * from the network (or any other sources defined in sources.list) + */ +bool ListUpdate(pkgAcquireStatus &Stat, + pkgSourceList &List, + int PulseInterval) +{ + pkgAcquire Fetcher(&Stat); + if (Fetcher.GetLock(_config->FindDir("Dir::State::Lists")) == false) + return false; + + // Populate it with the source selection + if (List.GetIndexes(&Fetcher) == false) + return false; + + return AcquireUpdate(Fetcher, PulseInterval, true); +} + /*}}}*/ +// AcquireUpdate - take Fetcher and update the cache files /*{{{*/ +// --------------------------------------------------------------------- +/* This is a simple wrapper to update the cache with a provided acquire + * If you only need control over Status and the used SourcesList use + * ListUpdate method instead. + */ +bool AcquireUpdate(pkgAcquire &Fetcher, int const PulseInterval, + bool const RunUpdateScripts, bool const ListCleanup) +{ + enum class ErrorMode + { + Persistent, + Any + }; + std::string errorModeS = _config->Find("APT::Update::Error-Mode", "persistent"); + ErrorMode errorMode = ErrorMode::Persistent; + if (errorModeS == "persistent") + errorMode = ErrorMode::Persistent; + else if (errorModeS == "any") + errorMode = ErrorMode::Any; + else + return _error->Error("Unknown update error mode %s", errorModeS.c_str()); + + // Run scripts + if (RunUpdateScripts == true) + RunScripts("APT::Update::Pre-Invoke"); + + pkgAcquire::RunResult res; + if(PulseInterval > 0) + res = Fetcher.Run(PulseInterval); + else + res = Fetcher.Run(); + + bool const errorsWereReported = (res == pkgAcquire::Failed); + bool Failed = errorsWereReported; + bool TransientNetworkFailure = false; + bool AllFailed = true; + for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); + I != Fetcher.ItemsEnd(); ++I) + { + switch ((*I)->Status) + { + case pkgAcquire::Item::StatDone: + AllFailed = false; + continue; + case pkgAcquire::Item::StatTransientNetworkError: + if (errorMode == ErrorMode::Any) + Failed = true; + else + TransientNetworkFailure = true; + break; + case pkgAcquire::Item::StatIdle: + case pkgAcquire::Item::StatFetching: + case pkgAcquire::Item::StatError: + case pkgAcquire::Item::StatAuthError: + Failed = true; + break; + } + + (*I)->Finished(); + + if (errorsWereReported) + continue; + + ::URI uri((*I)->DescURI()); + uri.User.clear(); + uri.Password.clear(); + if ((*I)->Local) + uri.Path = DeQuoteString(uri.Path); + std::string const descUri = std::string(uri); + // Show an error for non-transient failures, otherwise only warn + if ((*I)->Status == pkgAcquire::Item::StatTransientNetworkError && errorMode != ErrorMode::Any) + _error->Warning(_("Failed to fetch %s %s"), descUri.c_str(), + (*I)->ErrorText.c_str()); + else + _error->Error(_("Failed to fetch %s %s"), descUri.c_str(), + (*I)->ErrorText.c_str()); + } + + // Clean out any old list files + // Keep "APT::Get::List-Cleanup" name for compatibility, but + // this is really a global option for the APT library now + if (!TransientNetworkFailure && !Failed && ListCleanup == true && + (_config->FindB("APT::Get::List-Cleanup",true) == true && + _config->FindB("APT::List-Cleanup",true) == true)) + { + if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false || + Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false) + // something went wrong with the clean + return false; + } + + bool Res = true; + + if (errorsWereReported == true) + Res = false; + else if (TransientNetworkFailure == true) + Res = _error->Warning(_("Some index files failed to download. They have been ignored, or old ones used instead.")); + else if (Failed == true) + Res = _error->Error(_("Some index files failed to download. They have been ignored, or old ones used instead.")); + + // Run the success scripts if all was fine + if (RunUpdateScripts == true) + { + if(AllFailed == false) + RunScripts("APT::Update::Post-Invoke-Success"); + + // Run the other scripts + RunScripts("APT::Update::Post-Invoke"); + } + return Res; +} + /*}}}*/ |