#include <sstream>
#include <memory>
#include <utility>
+#include <algorithm>
#include "apt-ftparchive.h"
#include "writer.h"
#include "cachedb.h"
#include "multicompress.h"
+#include "byhash.h"
#include <apti18n.h>
/*}}}*/
/*}}}*/
// FTWScanner::FTWScanner - Constructor /*{{{*/
-// ---------------------------------------------------------------------
-/* */
FTWScanner::FTWScanner(FileFd * const GivenOutput, string const &Arch): Arch(Arch), DoHashes(~0)
{
if (GivenOutput == NULL)
{
Output = new FileFd;
+ OwnsOutput = true;
Output->OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly, false);
}
else
+ {
Output = GivenOutput;
+ OwnsOutput = false;
+ }
ErrorPrinted = false;
NoLinkAct = !_config->FindB("APT::FTPArchive::DeLinkAct",true);
ConfigToDoHashes(DoHashes, "APT::FTPArchive");
}
/*}}}*/
+FTWScanner::~FTWScanner()
+{
+ if (Output != NULL && OwnsOutput)
+ delete Output;
+}
// FTWScanner::Scanner - FTW Scanner /*{{{*/
// ---------------------------------------------------------------------
/* This is the FTW scanner, it processes each directory element in the
// PackagesWriter::PackagesWriter - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-PackagesWriter::PackagesWriter(FileFd * const GivenOutput, string const &DB,string const &Overrides,string const &ExtOverrides,
- string const &Arch) :
- FTWScanner(GivenOutput, Arch), Db(DB), Stats(Db.Stats), TransWriter(NULL)
+PackagesWriter::PackagesWriter(FileFd * const GivenOutput, TranslationWriter * const transWriter,
+ string const &DB,string const &Overrides,string const &ExtOverrides,
+ string const &Arch) :
+ FTWScanner(GivenOutput, Arch), Db(DB), Stats(Db.Stats), TransWriter(transWriter)
{
SetExts(".deb .udeb");
DeLinkLimit = 0;
return true;
}
-
/*}}}*/
// PackagesWriter::DoPackage - Process a single package /*{{{*/
// ---------------------------------------------------------------------
Architecture = Arch;
else
Architecture = Tags.FindS("Architecture");
- auto_ptr<Override::Item> OverItem(Over.GetItem(Package,Architecture));
+ unique_ptr<Override::Item> OverItem(Over.GetItem(Package,Architecture));
if (Package.empty() == true)
return _error->Error(_("Archive had no package field"));
ioprintf(c1out, _(" %s has no override entry\n"), Package.c_str());
}
- OverItem = auto_ptr<Override::Item>(new Override::Item);
+ OverItem = unique_ptr<Override::Item>(new Override::Item);
OverItem->FieldOverride["Section"] = Tags.FindS("Section");
OverItem->Priority = Tags.FindS("Priority");
}
return Db.Finish();
}
/*}}}*/
+PackagesWriter::~PackagesWriter() /*{{{*/
+{
+}
+ /*}}}*/
// TranslationWriter::TranslationWriter - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* Create a Translation-Master file for this Packages file */
TranslationWriter::TranslationWriter(string const &File, string const &TransCompress,
- mode_t const &Permissions) : RefCounter(0)
+ mode_t const &Permissions) : Comp(NULL), Output(NULL)
{
if (File.empty() == true)
return;
/* */
TranslationWriter::~TranslationWriter()
{
- if (Comp == NULL)
- return;
-
- delete Comp;
+ if (Comp != NULL)
+ delete Comp;
}
/*}}}*/
string BestPrio;
string Bins = Tags.FindS("Binary");
char Buffer[Bins.length() + 1];
- auto_ptr<Override::Item> OverItem(0);
+ unique_ptr<Override::Item> OverItem(nullptr);
if (Bins.empty() == false)
{
strcpy(Buffer,Bins.c_str());
unsigned char BestPrioV = pkgCache::State::Extra;
for (unsigned I = 0; BinList[I] != 0; I++)
{
- auto_ptr<Override::Item> Itm(BOver.GetItem(BinList[I]));
+ unique_ptr<Override::Item> Itm(BOver.GetItem(BinList[I]));
if (Itm.get() == 0)
continue;
}
if (OverItem.get() == 0)
- OverItem = Itm;
+ OverItem = std::move(Itm);
}
}
ioprintf(c1out, _(" %s has no override entry\n"), Tags.FindS("Source").c_str());
}
- OverItem = auto_ptr<Override::Item>(new Override::Item);
+ OverItem.reset(new Override::Item);
}
struct stat St;
if (stat(FileName.c_str(), &St) != 0)
return _error->Errno("fstat","Failed to stat %s",FileName.c_str());
- auto_ptr<Override::Item> SOverItem(SOver.GetItem(Tags.FindS("Source")));
- // const auto_ptr<Override::Item> autoSOverItem(SOverItem);
+ unique_ptr<Override::Item> SOverItem(SOver.GetItem(Tags.FindS("Source")));
+ // const unique_ptr<Override::Item> autoSOverItem(SOverItem);
if (SOverItem.get() == 0)
{
ioprintf(c1out, _(" %s has no source override entry\n"), Tags.FindS("Source").c_str());
- SOverItem = auto_ptr<Override::Item>(BOver.GetItem(Tags.FindS("Source")));
+ SOverItem = unique_ptr<Override::Item>(BOver.GetItem(Tags.FindS("Source")));
if (SOverItem.get() == 0)
{
ioprintf(c1out, _(" %s has no binary override entry either\n"), Tags.FindS("Source").c_str());
- SOverItem = auto_ptr<Override::Item>(new Override::Item);
+ SOverItem = unique_ptr<Override::Item>(new Override::Item);
*SOverItem = *OverItem;
}
}
Fields["Architectures"] = "";
Fields["Components"] = "";
Fields["Description"] = "";
-
+ if (_config->FindB("APT::FTPArchive::DoByHash", false) == true)
+ Fields["Acquire-By-Hash"] = "true";
+
for(map<string,string>::const_iterator I = Fields.begin();
I != Fields.end();
++I)
CheckSums[NewFileName].Hashes = hs.GetHashStringList();
fd.Close();
+ // FIXME: wrong layer in the code(?)
+ // FIXME2: symlink instead of create a copy
+ if (_config->FindB("APT::FTPArchive::DoByHash", false) == true)
+ {
+ std::string Input = FileName;
+ HashStringList hsl = hs.GetHashStringList();
+ for(HashStringList::const_iterator h = hsl.begin();
+ h != hsl.end(); ++h)
+ {
+ if (!h->usable())
+ continue;
+ if (flNotDir(FileName) == "Release" || flNotDir(FileName) == "InRelease")
+ continue;
+
+ std::string ByHashOutputFile = GenByHashFilename(Input, *h);
+ std::string ByHashOutputDir = flNotFile(ByHashOutputFile);
+ if(!CreateDirectory(flNotFile(Input), ByHashOutputDir))
+ return _error->Warning("can not create dir %s", flNotFile(ByHashOutputFile).c_str());
+
+ // write new hashes
+ FileFd In(Input, FileFd::ReadOnly);
+ FileFd Out(ByHashOutputFile, FileFd::WriteEmpty);
+ if(!CopyFile(In, Out))
+ return _error->Warning("failed to copy %s %s", Input.c_str(), ByHashOutputFile.c_str());
+ }
+ }
+
return true;
}
printChecksumTypeRecord(*Output, "SHA256", CheckSums);
if ((DoHashes & Hashes::SHA512SUM) == Hashes::SHA512SUM)
printChecksumTypeRecord(*Output, "SHA512", CheckSums);
+
+ // go by-hash cleanup
+ map<string,ReleaseWriter::CheckSum>::const_iterator prev = CheckSums.begin();
+ if (_config->FindB("APT::FTPArchive::DoByHash", false) == true)
+ {
+ for(map<string,ReleaseWriter::CheckSum>::const_iterator I = CheckSums.begin();
+ I != CheckSums.end(); ++I)
+ {
+ if (I->first == "Release" || I->first == "InRelease")
+ continue;
+
+ // keep iterating until we find a new subdir
+ if(flNotFile(I->first) == flNotFile(prev->first))
+ continue;
+
+ // clean that subdir up
+ int keepFiles = _config->FindI("APT::FTPArchive::By-Hash-Keep", 3);
+ // calculate how many compressors are used (the amount of files
+ // in that subdir generated for this run)
+ keepFiles *= std::distance(prev, I);
+ prev = I;
+
+ HashStringList hsl = prev->second.Hashes;
+ for(HashStringList::const_iterator h = hsl.begin();
+ h != hsl.end(); ++h)
+ {
+
+ if (!h->usable())
+ continue;
+
+ std::string RealFilename = DirStrip+"/"+prev->first;
+ std::string ByHashOutputFile = GenByHashFilename(RealFilename, *h);
+ DeleteAllButMostRecent(flNotFile(ByHashOutputFile), keepFiles);
+ }
+ }
+ }
}