summaryrefslogtreecommitdiff
path: root/apt-pkg/acquire-item.cc
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/acquire-item.cc')
-rw-r--r--apt-pkg/acquire-item.cc304
1 files changed, 183 insertions, 121 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index a7386da71..53dc08160 100644
--- a/apt-pkg/acquire-item.cc
+++ b/apt-pkg/acquire-item.cc
@@ -16,55 +16,42 @@
#include <config.h>
#include <apt-pkg/acquire-item.h>
-#include <apt-pkg/configuration.h>
+#include <apt-pkg/acquire.h>
#include <apt-pkg/aptconfiguration.h>
-#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/configuration.h>
#include <apt-pkg/error.h>
-#include <apt-pkg/strutl.h>
#include <apt-pkg/fileutl.h>
-#include <apt-pkg/tagfile.h>
-#include <apt-pkg/metaindex.h>
-#include <apt-pkg/acquire.h>
+#include <apt-pkg/gpgv.h>
#include <apt-pkg/hashes.h>
#include <apt-pkg/indexfile.h>
+#include <apt-pkg/metaindex.h>
#include <apt-pkg/pkgcache.h>
-#include <apt-pkg/cacheiterators.h>
#include <apt-pkg/pkgrecords.h>
-#include <apt-pkg/gpgv.h>
+#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/tagfile.h>
#include <algorithm>
+#include <ctime>
+#include <iostream>
+#include <numeric>
+#include <random>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <errno.h>
#include <stddef.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <iostream>
-#include <vector>
#include <sys/stat.h>
#include <unistd.h>
-#include <errno.h>
-#include <string>
-#include <stdio.h>
-#include <ctime>
-#include <sstream>
-#include <numeric>
-#include <random>
#include <apti18n.h>
/*}}}*/
using namespace std;
-static void printHashSumComparison(std::string const &URI, HashStringList const &Expected, HashStringList const &Actual) /*{{{*/
-{
- if (_config->FindB("Debug::Acquire::HashSumMismatch", false) == false)
- return;
- std::cerr << std::endl << URI << ":" << std::endl << " Expected Hash: " << std::endl;
- for (HashStringList::const_iterator hs = Expected.begin(); hs != Expected.end(); ++hs)
- std::cerr << "\t- " << hs->toStr() << std::endl;
- std::cerr << " Actual Hash: " << std::endl;
- for (HashStringList::const_iterator hs = Actual.begin(); hs != Actual.end(); ++hs)
- std::cerr << "\t- " << hs->toStr() << std::endl;
-}
- /*}}}*/
static std::string GetPartialFileName(std::string const &file) /*{{{*/
{
std::string DestFile = _config->FindDir("Dir::State::lists") + "partial/";
@@ -1114,11 +1101,13 @@ void pkgAcqMetaBase::AbortTransaction()
case TransactionCommit: _error->Fatal("Transaction %s was already aborted and is now committed", TransactionManager->Target.URI.c_str()); return;
}
TransactionManager->State = TransactionAbort;
+ TransactionManager->ExpectedAdditionalItems = 0;
// ensure the toplevel is in error state too
for (std::vector<pkgAcqTransactionItem*>::iterator I = Transaction.begin();
I != Transaction.end(); ++I)
{
+ (*I)->ExpectedAdditionalItems = 0;
if ((*I)->Status != pkgAcquire::Item::StatFetching)
Owner->Dequeue(*I);
(*I)->TransactionState(TransactionAbort);
@@ -1411,6 +1400,16 @@ void pkgAcqMetaClearSig::QueueIndexes(bool const verify) /*{{{*/
{
if (TransactionManager->MetaIndexParser->Exists(Target.MetaKey) == false)
{
+ auto const component = Target.Option(IndexTarget::COMPONENT);
+ if (component.empty() == false && TransactionManager->MetaIndexParser->HasSupportForComponent(component) == false)
+ {
+ new CleanupItem(Owner, TransactionManager, Target);
+ _error->Warning(_("Skipping acquire of configured file '%s' as repository '%s' doesn't have the component '%s' (component misspelt in sources.list?)"),
+ Target.MetaKey.c_str(), TransactionManager->Target.Description.c_str(), component.c_str());
+ continue;
+
+ }
+
// optional targets that we do not have in the Release file are skipped
if (hasHashes == true && Target.IsOptional)
{
@@ -1440,9 +1439,10 @@ void pkgAcqMetaClearSig::QueueIndexes(bool const verify) /*{{{*/
if (hasHashes == true)
{
- Status = StatAuthError;
- strprintf(ErrorText, _("Unable to find expected entry '%s' in Release file (Wrong sources.list entry or malformed file)"), Target.MetaKey.c_str());
- return;
+ new CleanupItem(Owner, TransactionManager, Target);
+ _error->Warning(_("Skipping acquire of configured file '%s' as repository '%s' does not seem to provide it (sources.list entry misspelt?)"),
+ Target.MetaKey.c_str(), TransactionManager->Target.Description.c_str());
+ continue;
}
else
{
@@ -1606,13 +1606,79 @@ bool pkgAcqMetaBase::VerifyVendor(string const &) /*{{{*/
if (TransactionManager->MetaIndexParser->CheckDist(ExpectedDist) == false)
_error->Warning(_("Conflicting distribution: %s (expected %s but got %s)"),
Desc.Description.c_str(), ExpectedDist.c_str(), NowCodename.c_str());
- // might be okay, might be not
+
+ // changed info potentially breaks user config like pinning
if (TransactionManager->LastMetaIndexParser != nullptr)
{
- auto const LastCodename = TransactionManager->LastMetaIndexParser->GetCodename();
- if (LastCodename.empty() == false && NowCodename.empty() == false && LastCodename != NowCodename)
- _error->Warning(_("Conflicting distribution: %s (expected %s but got %s)"),
- Desc.Description.c_str(), LastCodename.c_str(), NowCodename.c_str());
+ std::vector<pkgAcquireStatus::ReleaseInfoChange> Changes;
+ auto const AllowInfoChange = _config->FindB("Acquire::AllowReleaseInfoChange", false);
+ auto const quietInfoChange = _config->FindB("quiet::ReleaseInfoChange", false);
+ struct {
+ char const * const Type;
+ bool const Allowed;
+ decltype(&metaIndex::GetOrigin) const Getter;
+ } checkers[] = {
+ { "Origin", AllowInfoChange, &metaIndex::GetOrigin },
+ { "Label", AllowInfoChange, &metaIndex::GetLabel },
+ { "Version", true, &metaIndex::GetVersion }, // numbers change all the time, that is okay
+ { "Suite", AllowInfoChange, &metaIndex::GetSuite },
+ { "Codename", AllowInfoChange, &metaIndex::GetCodename },
+ { nullptr, false, nullptr }
+ };
+ auto const CheckReleaseInfo = [&](char const * const Type, bool const AllowChange, decltype(checkers[0].Getter) const Getter) {
+ std::string const Last = (TransactionManager->LastMetaIndexParser->*Getter)();
+ std::string const Now = (TransactionManager->MetaIndexParser->*Getter)();
+ if (Last == Now)
+ return;
+ auto const Allow = _config->FindB(std::string("Acquire::AllowReleaseInfoChange::").append(Type), AllowChange);
+ if (Allow == true && _config->FindB(std::string("quiet::ReleaseInfoChange::").append(Type), quietInfoChange) == true)
+ return;
+ std::string msg;
+ strprintf(msg, _("Repository '%s' changed its '%s' value from '%s' to '%s'"),
+ Desc.Description.c_str(), Type, Last.c_str(), Now.c_str());
+ Changes.push_back({Type, std::move(Last), std::move(Now), std::move(msg), Allow});
+ };
+ for (short i = 0; checkers[i].Type != nullptr; ++i)
+ CheckReleaseInfo(checkers[i].Type, checkers[i].Allowed, checkers[i].Getter);
+
+ {
+ auto const Last = TransactionManager->LastMetaIndexParser->GetDefaultPin();
+ auto const Now = TransactionManager->MetaIndexParser->GetDefaultPin();
+ if (Last != Now)
+ {
+ auto const Allow = _config->FindB("Acquire::AllowReleaseInfoChange::DefaultPin", AllowInfoChange);
+ if (Allow == false || _config->FindB("quiet::ReleaseInfoChange::DefaultPin", quietInfoChange) == false)
+ {
+ std::string msg;
+ strprintf(msg, _("Repository '%s' changed its default priority for %s from %hi to %hi."),
+ Desc.Description.c_str(), "apt_preferences(5)", Last, Now);
+ Changes.push_back({"DefaultPin", std::to_string(Last), std::to_string(Now), std::move(msg), Allow});
+ }
+ }
+ }
+ if (Changes.empty() == false)
+ {
+ auto const notes = TransactionManager->MetaIndexParser->GetReleaseNotes();
+ if (notes.empty() == false)
+ {
+ std::string msg;
+ // TRANSLATOR: the "this" refers to changes in the repository like a new release or owner change
+ strprintf(msg, _("More information about this can be found online in the Release notes at: %s"), notes.c_str());
+ Changes.push_back({"Release-Notes", "", std::move(notes), std::move(msg), true});
+ }
+ if (std::any_of(Changes.begin(),Changes.end(),[](pkgAcquireStatus::ReleaseInfoChange const &c) { return c.DefaultAction == false; }))
+ {
+ std::string msg;
+ // TRANSLATOR: %s is the name of the manpage in question, e.g. apt-secure(8)
+ strprintf(msg, _("This must be accepted explicitly before updates for "
+ "this repository can be applied. See %s manpage for details."), "apt-secure(8)");
+ Changes.push_back({"Confirmation", "", "", std::move(msg), true});
+ }
+
+ }
+ if (Owner->Log == nullptr)
+ return pkgAcquireStatus::ReleaseInfoChangesAsGlobalErrors(std::move(Changes));
+ return Owner->Log->ReleaseInfoChanges(TransactionManager->LastMetaIndexParser, TransactionManager->MetaIndexParser, std::move(Changes));
}
return true;
}
@@ -1664,7 +1730,8 @@ void pkgAcqMetaClearSig::Finished() /*{{{*/
bool pkgAcqMetaClearSig::VerifyDone(std::string const &Message, /*{{{*/
pkgAcquire::MethodConfig const * const Cnf)
{
- Item::VerifyDone(Message, Cnf);
+ if (Item::VerifyDone(Message, Cnf) == false)
+ return false;
if (FileExists(DestFile) && !StartsWithGPGClearTextSignature(DestFile))
return RenameOnError(NotClearsigned);
@@ -1717,7 +1784,11 @@ void pkgAcqMetaClearSig::Failed(string const &Message,pkgAcquire::MethodConfig c
if (AuthPass == false)
{
- if (Status == StatAuthError || Status == StatTransientNetworkError)
+ auto const failreason = LookupTag(Message, "FailReason");
+ auto const httperror = "HttpError";
+ if (Status == StatAuthError || Status == StatTransientNetworkError ||
+ (strncmp(failreason.c_str(), httperror, strlen(httperror)) == 0 &&
+ failreason != "HttpError404"))
{
// if we expected a ClearTextSignature (InRelease) but got a network
// error or got a file, but it wasn't valid, we end up here (see VerifyDone).
@@ -2040,13 +2111,11 @@ void pkgAcqDiffIndex::QueueOnIMSHit() const /*{{{*/
new pkgAcqIndexDiffs(Owner, TransactionManager, Target, UsedMirror, Target.URI);
}
/*}}}*/
-static bool RemoveFileForBootstrapLinking(bool const Debug, std::string const &For, std::string const &Boot)/*{{{*/
+static bool RemoveFileForBootstrapLinking(std::string &ErrorText, std::string const &For, std::string const &Boot)/*{{{*/
{
if (FileExists(Boot) && RemoveFile("Bootstrap-linking", Boot) == false)
{
- if (Debug)
- std::clog << "Bootstrap-linking for patching " << For
- << " by removing stale " << Boot << " failed!" << std::endl;
+ strprintf(ErrorText, "Bootstrap for patching %s by removing stale %s failed!", For.c_str(), Boot.c_str());
return false;
}
return true;
@@ -2054,6 +2123,7 @@ static bool RemoveFileForBootstrapLinking(bool const Debug, std::string const &F
/*}}}*/
bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/
{
+ available_patches.clear();
ExpectedAdditionalItems = 0;
// failing here is fine: our caller will take care of trying to
// get the complete file if patching fails
@@ -2097,8 +2167,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/
if (ServerHashes.usable() == false)
{
- if (Debug == true)
- std::clog << "pkgAcqDiffIndex: " << IndexDiffFile << ": Did not find a good hashsum in the index" << std::endl;
+ ErrorText = "Did not find a good hashsum in the index";
return false;
}
@@ -2106,11 +2175,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/
HashStringList const TargetFileHashes = GetExpectedHashesFor(Target.MetaKey);
if (TargetFileHashes.usable() == false || ServerHashes != TargetFileHashes)
{
- if (Debug == true)
- {
- std::clog << "pkgAcqDiffIndex: " << IndexDiffFile << ": Index has different hashes than parser, probably older, so fail pdiffing" << std::endl;
- printHashSumComparison(CurrentPackagesFile, ServerHashes, TargetFileHashes);
- }
+ ErrorText = "Index has different hashes than parser (probably older)";
return false;
}
@@ -2128,10 +2193,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/
if (ServerHashes == LocalHashes)
{
- // we have the same sha1 as the server so we are done here
- if(Debug)
- std::clog << "pkgAcqDiffIndex: Package file " << CurrentPackagesFile << " is up-to-date" << std::endl;
- QueueOnIMSHit();
+ available_patches.clear();
return true;
}
@@ -2148,7 +2210,6 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/
types.push_back(*type);
// parse all of (provided) history
- vector<DiffInfo> available_patches;
bool firstAcceptedHashes = true;
for (auto type = types.crbegin(); type != types.crend(); ++type)
{
@@ -2203,9 +2264,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/
if (unlikely(available_patches.empty() == true))
{
- if (Debug)
- std::clog << "pkgAcqDiffIndex: " << IndexDiffFile << ": "
- << "Couldn't find any patches for the patch series." << std::endl;
+ ErrorText = "Couldn't find any patches for the patch series";
return false;
}
@@ -2307,9 +2366,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/
if (foundStart == false || unlikely(available_patches.empty() == true))
{
- if (Debug)
- std::clog << "pkgAcqDiffIndex: " << IndexDiffFile << ": "
- << "Couldn't find the start of the patch series." << std::endl;
+ ErrorText = "Couldn't find the start of the patch series";
return false;
}
@@ -2318,9 +2375,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/
patch.patch_hashes.usable() == false ||
patch.download_hashes.usable() == false)
{
- if (Debug)
- std::clog << "pkgAcqDiffIndex: " << IndexDiffFile << ": provides no usable hashes for " << patch.file
- << " so fallback to complete download" << std::endl;
+ strprintf(ErrorText, "Provides no usable hashes for %s", patch.file.c_str());
return false;
}
@@ -2328,9 +2383,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/
unsigned long const fileLimit = _config->FindI("Acquire::PDiffs::FileLimit", 0);
if (fileLimit != 0 && fileLimit < available_patches.size())
{
- if (Debug)
- std::clog << "Need " << available_patches.size() << " diffs (Limit is " << fileLimit
- << ") so fallback to complete download" << std::endl;
+ strprintf(ErrorText, "Need %lu diffs, but limit is %lu", available_patches.size(), fileLimit);
return false;
}
@@ -2360,25 +2413,18 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/
unsigned long long const sizeLimit = downloadSizeIdx * sizeLimitPercent;
if ((sizeLimit/100) < downloadSize)
{
- if (Debug)
- std::clog << "Need " << downloadSize << " compressed bytes (Limit is " << (sizeLimit/100) << ", "
- << "original is " << downloadSizeIdx << ") so fallback to complete download" << std::endl;
+ strprintf(ErrorText, "Need %llu compressed bytes, but limit is %llu and original is %llu", downloadSize, (sizeLimit/100), downloadSizeIdx);
return false;
}
}
}
- // we have something, queue the diffs
- string::size_type const last_space = Description.rfind(" ");
- if(last_space != string::npos)
- Description.erase(last_space, Description.size()-last_space);
-
/* decide if we should download patches one by one or in one go:
The first is good if the server merges patches, but many don't so client
based merging can be attempt in which case the second is better.
"bad things" will happen if patches are merged on the server,
but client side merging is attempt as well */
- bool pdiff_merge = _config->FindB("Acquire::PDiffs::Merge", true);
+ pdiff_merge = _config->FindB("Acquire::PDiffs::Merge", true);
if (pdiff_merge == true)
{
// reprepro adds this flag if it has merged patches on the server
@@ -2393,53 +2439,24 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string const &IndexDiffFile) /*{{{*/
return false;
std::string const PartialFile = GetPartialFileNameFromURI(Target.URI);
std::string const PatchedFile = GetKeepCompressedFileName(PartialFile + "-patched", Target);
- if (RemoveFileForBootstrapLinking(Debug, CurrentPackagesFile, PartialFile) == false ||
- RemoveFileForBootstrapLinking(Debug, CurrentPackagesFile, PatchedFile) == false)
+ if (RemoveFileForBootstrapLinking(ErrorText, CurrentPackagesFile, PartialFile) == false ||
+ RemoveFileForBootstrapLinking(ErrorText, CurrentPackagesFile, PatchedFile) == false)
return false;
for (auto const &ext : APT::Configuration::getCompressorExtensions())
{
- if (RemoveFileForBootstrapLinking(Debug, CurrentPackagesFile, PartialFile + ext) == false ||
- RemoveFileForBootstrapLinking(Debug, CurrentPackagesFile, PatchedFile + ext) == false)
+ if (RemoveFileForBootstrapLinking(ErrorText, CurrentPackagesFile, PartialFile + ext) == false ||
+ RemoveFileForBootstrapLinking(ErrorText, CurrentPackagesFile, PatchedFile + ext) == false)
return false;
}
std::string const Ext = Final.substr(CurrentPackagesFile.length());
std::string const Partial = PartialFile + Ext;
if (symlink(Final.c_str(), Partial.c_str()) != 0)
{
- if (Debug)
- std::clog << "Bootstrap-linking for patching " << CurrentPackagesFile
- << " by linking " << Final << " to " << Partial << " failed!" << std::endl;
+ strprintf(ErrorText, "Bootstrap for patching by linking %s to %s failed!", Final.c_str(), Partial.c_str());
return false;
}
}
- std::string indexURI = Desc.URI;
- auto const byhashidx = indexURI.find("/by-hash/");
- if (byhashidx != std::string::npos)
- indexURI = indexURI.substr(0, byhashidx - strlen(".diff"));
- else
- {
- auto end = indexURI.length() - strlen(".diff/Index");
- if (CurrentCompressionExtension != "uncompressed")
- end -= (1 + CurrentCompressionExtension.length());
- indexURI = indexURI.substr(0, end);
- }
-
- if (pdiff_merge == false)
- new pkgAcqIndexDiffs(Owner, TransactionManager, Target, UsedMirror, indexURI, available_patches);
- else
- {
- diffs = new std::vector<pkgAcqIndexMergeDiffs*>(available_patches.size());
- for(size_t i = 0; i < available_patches.size(); ++i)
- (*diffs)[i] = new pkgAcqIndexMergeDiffs(Owner, TransactionManager,
- Target, UsedMirror, indexURI,
- available_patches[i],
- diffs);
- }
-
- Complete = false;
- Status = StatDone;
- Dequeue();
return true;
}
/*}}}*/
@@ -2451,6 +2468,10 @@ void pkgAcqDiffIndex::Failed(string const &Message,pkgAcquire::MethodConfig cons
Status = StatDone;
ExpectedAdditionalItems = 0;
+ // queue for final move - this should happen even if we fail
+ // while parsing (e.g. on sizelimit) and download the complete file.
+ TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename());
+
if(Debug)
std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << " with " << Message << std::endl
<< "Falling back to normal index file acquire" << std::endl;
@@ -2458,6 +2479,21 @@ void pkgAcqDiffIndex::Failed(string const &Message,pkgAcquire::MethodConfig cons
new pkgAcqIndex(Owner, TransactionManager, Target);
}
/*}}}*/
+bool pkgAcqDiffIndex::VerifyDone(std::string const &Message, pkgAcquire::MethodConfig const * const)/*{{{*/
+{
+ string const FinalFile = GetFinalFilename();
+ if(StringToBool(LookupTag(Message,"IMS-Hit"),false))
+ DestFile = FinalFile;
+
+ if (ParseDiffIndex(DestFile))
+ return true;
+
+ Status = StatError;
+ if (ErrorText.empty())
+ ErrorText = "Couldn't parse pdiff index";
+ return false;
+}
+ /*}}}*/
void pkgAcqDiffIndex::Done(string const &Message,HashStringList const &Hashes, /*{{{*/
pkgAcquire::MethodConfig const * const Cnf)
{
@@ -2466,20 +2502,46 @@ void pkgAcqDiffIndex::Done(string const &Message,HashStringList const &Hashes, /
Item::Done(Message, Hashes, Cnf);
- string const FinalFile = GetFinalFilename();
- if(StringToBool(LookupTag(Message,"IMS-Hit"),false))
- DestFile = FinalFile;
-
- if(ParseDiffIndex(DestFile) == false)
+ if (available_patches.empty())
{
- Failed("Message: Couldn't parse pdiff index", Cnf);
- // queue for final move - this should happen even if we fail
- // while parsing (e.g. on sizelimit) and download the complete file.
- TransactionManager->TransactionStageCopy(this, DestFile, FinalFile);
- return;
+ // we have the same sha1 as the server so we are done here
+ if(Debug)
+ std::clog << "pkgAcqDiffIndex: Package file is up-to-date" << std::endl;
+ QueueOnIMSHit();
+ }
+ else
+ {
+ // we have something, queue the diffs
+ string::size_type const last_space = Description.rfind(" ");
+ if(last_space != string::npos)
+ Description.erase(last_space, Description.size()-last_space);
+
+ std::string indexURI = Desc.URI;
+ auto const byhashidx = indexURI.find("/by-hash/");
+ if (byhashidx != std::string::npos)
+ indexURI = indexURI.substr(0, byhashidx - strlen(".diff"));
+ else
+ {
+ auto end = indexURI.length() - strlen(".diff/Index");
+ if (CurrentCompressionExtension != "uncompressed")
+ end -= (1 + CurrentCompressionExtension.length());
+ indexURI = indexURI.substr(0, end);
+ }
+
+ if (pdiff_merge == false)
+ new pkgAcqIndexDiffs(Owner, TransactionManager, Target, UsedMirror, indexURI, available_patches);
+ else
+ {
+ diffs = new std::vector<pkgAcqIndexMergeDiffs*>(available_patches.size());
+ for(size_t i = 0; i < available_patches.size(); ++i)
+ (*diffs)[i] = new pkgAcqIndexMergeDiffs(Owner, TransactionManager,
+ Target, UsedMirror, indexURI,
+ available_patches[i],
+ diffs);
+ }
}
- TransactionManager->TransactionStageCopy(this, DestFile, FinalFile);
+ TransactionManager->TransactionStageCopy(this, DestFile, GetFinalFilename());
Complete = true;
Status = StatDone;