1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 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;
}
/*}}}*/
|