#include <ftw.h>
#include <fnmatch.h>
#include <iostream>
+#include <sstream>
#include <memory>
#include "cachedb.h"
// FTWScanner::FTWScanner - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-FTWScanner::FTWScanner()
+FTWScanner::FTWScanner(string const &Arch): Arch(Arch)
{
ErrorPrinted = false;
NoLinkAct = !_config->FindB("APT::FTPArchive::DeLinkAct",true);
- RealPath = 0;
- long PMax = pathconf(".",_PC_PATH_MAX);
- if (PMax > 0)
- RealPath = new char[PMax];
}
/*}}}*/
// FTWScanner::Scanner - FTW Scanner /*{{{*/
int FTWScanner::ScannerFile(const char *File, bool const &ReadLink)
{
const char *LastComponent = strrchr(File, '/');
+ char *RealPath = NULL;
+
if (LastComponent == NULL)
LastComponent = File;
else
given are not links themselves. */
char Jnk[2];
Owner->OriginalPath = File;
- if (ReadLink && Owner->RealPath != 0 &&
+ if (ReadLink &&
readlink(File,Jnk,sizeof(Jnk)) != -1 &&
- realpath(File,Owner->RealPath) != 0)
- Owner->DoPackage(Owner->RealPath);
+ (RealPath = realpath(File,NULL)) != 0)
+ {
+ Owner->DoPackage(RealPath);
+ free(RealPath);
+ }
else
Owner->DoPackage(File);
/* */
bool FTWScanner::RecursiveScan(string const &Dir)
{
+ char *RealPath = NULL;
/* If noprefix is set then jam the scan root in, so we don't generate
link followed paths out of control */
if (InternalPrefix.empty() == true)
{
- if (realpath(Dir.c_str(),RealPath) == 0)
+ if ((RealPath = realpath(Dir.c_str(),NULL)) == 0)
return _error->Errno("realpath",_("Failed to resolve %s"),Dir.c_str());
- InternalPrefix = RealPath;
+ InternalPrefix = RealPath;
+ free(RealPath);
}
// Do recursive directory searching
of files from another file. */
bool FTWScanner::LoadFileList(string const &Dir, string const &File)
{
+ char *RealPath = NULL;
/* If noprefix is set then jam the scan root in, so we don't generate
link followed paths out of control */
if (InternalPrefix.empty() == true)
{
- if (realpath(Dir.c_str(),RealPath) == 0)
+ if ((RealPath = realpath(Dir.c_str(),NULL)) == 0)
return _error->Errno("realpath",_("Failed to resolve %s"),Dir.c_str());
InternalPrefix = RealPath;
+ free(RealPath);
}
Owner = this;
// ---------------------------------------------------------------------
/* */
PackagesWriter::PackagesWriter(string const &DB,string const &Overrides,string const &ExtOverrides,
- string const &aArch) :
- Db(DB),Stats(Db.Stats), Arch(aArch)
+ string const &Arch) :
+ FTWScanner(Arch), Db(DB), Stats(Db.Stats), TransWriter(NULL)
{
Output = stdout;
- SetExts(".deb .udeb .foo .bar .baz");
- AddPattern("*.deb");
+ SetExts(".deb .udeb");
DeLinkLimit = 0;
// Process the command line options
if (Db.Loaded() == false)
DoContents = false;
-
+
// Read the override file
if (Overrides.empty() == false && Over.ReadOverride(Overrides) == false)
return;
string::size_type Start = 0;
while (Start <= Vals.length()-1)
{
- string::size_type Space = Vals.find(' ',Start);
- string::size_type Length;
- if (Space == string::npos)
+ string::size_type const Space = Vals.find(' ',Start);
+ string::size_type const Length = ((Space == string::npos) ? Vals.length() : Space) - Start;
+ if ( Arch.empty() == false )
{
- Length = Vals.length()-Start;
+ AddPattern(string("*_") + Arch + Vals.substr(Start, Length));
+ AddPattern(string("*_all") + Vals.substr(Start, Length));
}
else
- {
- Length = Space-Start;
- }
- AddPattern(string("*") + Vals.substr(Start, Length));
+ AddPattern(string("*") + Vals.substr(Start, Length));
+
Start += Length + 1;
}
descmd5.Add(desc.c_str());
DescriptionMd5 = descmd5.Result().Value();
SetTFRewriteData(Changes[End++], "Description-md5", DescriptionMd5.c_str());
+ if (TransWriter != NULL)
+ TransWriter->DoPackage(Package, desc, DescriptionMd5);
}
// Rewrite the maintainer field if necessary
}
/*}}}*/
+// TranslationWriter::TranslationWriter - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* Create a Translation-Master file for this Packages file */
+TranslationWriter::TranslationWriter(string const &File, string const &TransCompress,
+ mode_t const &Permissions) : Output(NULL),
+ RefCounter(0)
+{
+ if (File.empty() == true)
+ return;
+
+ Comp = new MultiCompress(File, TransCompress, Permissions);
+ Output = Comp->Input;
+}
+ /*}}}*/
+// TranslationWriter::DoPackage - Process a single package /*{{{*/
+// ---------------------------------------------------------------------
+/* Create a Translation-Master file for this Packages file */
+bool TranslationWriter::DoPackage(string const &Pkg, string const &Desc,
+ string const &MD5)
+{
+ if (Output == NULL)
+ return true;
+
+ // Different archs can include different versions and therefore
+ // different descriptions - so we need to check for both name and md5.
+ string const Record = Pkg + ":" + MD5;
+
+ if (Included.find(Record) != Included.end())
+ return true;
+
+ fprintf(Output, "Package: %s\nDescription-md5: %s\nDescription-en: %s\n",
+ Pkg.c_str(), MD5.c_str(), Desc.c_str());
+
+ Included.insert(Record);
+ return true;
+}
+ /*}}}*/
+// TranslationWriter::~TranslationWriter - Destructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+TranslationWriter::~TranslationWriter()
+{
+ if (Comp == NULL)
+ return;
+
+ delete Comp;
+}
+ /*}}}*/
+
// SourcesWriter::SourcesWriter - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
char *BlkEnd = Buffer + St.st_size;
MD5Summation MD5;
MD5.Add((unsigned char *)Start,BlkEnd - Start);
-
+
+ SHA1Summation SHA1;
+ SHA256Summation SHA256;
+ SHA1.Add((unsigned char *)Start,BlkEnd - Start);
+ SHA256.Add((unsigned char *)Start,BlkEnd - Start);
+
// Add an extra \n to the end, just in case
*BlkEnd++ = '\n';
}
// Add the dsc to the files hash list
- char Files[1000];
- snprintf(Files,sizeof(Files),"\n %s %lu %s\n %s",
- string(MD5.Result()).c_str(),St.st_size,
- flNotDir(FileName).c_str(),
- Tags.FindS("Files").c_str());
-
+ string const strippedName = flNotDir(FileName);
+ std::ostringstream ostreamFiles;
+ if (Tags.Exists("Files"))
+ ostreamFiles << "\n " << string(MD5.Result()) << " " << St.st_size << " "
+ << strippedName << "\n " << Tags.FindS("Files");
+ string const Files = ostreamFiles.str();
+
+ std::ostringstream ostreamSha1;
+ if (Tags.Exists("Checksums-Sha1"))
+ ostreamSha1 << "\n " << string(SHA1.Result()) << " " << St.st_size << " "
+ << strippedName << "\n " << Tags.FindS("Checksums-Sha1");
+ string const ChecksumsSha1 = ostreamSha1.str();
+
+ std::ostringstream ostreamSha256;
+ if (Tags.Exists("Checksums-Sha256"))
+ ostreamSha256 << "\n " << string(SHA256.Result()) << " " << St.st_size << " "
+ << strippedName << "\n " << Tags.FindS("Checksums-Sha256");
+ string const ChecksumsSha256 = ostreamSha256.str();
+
// Strip the DirStrip prefix from the FileName and add the PathPrefix
string NewFileName;
if (DirStrip.empty() == false &&
// Perform the delinking operation over all of the files
string ParseJnk;
- const char *C = Files;
+ const char *C = Files.c_str();
+ char *RealPath = NULL;
for (;isspace(*C); C++);
while (*C != 0)
{
char Jnk[2];
string OriginalPath = Directory + ParseJnk;
- if (RealPath != 0 && readlink(OriginalPath.c_str(),Jnk,sizeof(Jnk)) != -1 &&
- realpath(OriginalPath.c_str(),RealPath) != 0)
+ if (readlink(OriginalPath.c_str(),Jnk,sizeof(Jnk)) != -1 &&
+ (RealPath = realpath(OriginalPath.c_str(),NULL)) != 0)
{
string RP = RealPath;
+ free(RealPath);
if (Delink(RP,OriginalPath.c_str(),Stats.DeLinkBytes,St.st_size) == false)
return false;
}
Directory.erase(Directory.end()-1);
// This lists all the changes to the fields we are going to make.
- // (5 hardcoded + maintainer + end marker)
- TFRewriteData Changes[5+1+SOverItem->FieldOverride.size()+1];
+ // (5 hardcoded + checksums + maintainer + end marker)
+ TFRewriteData Changes[5+2+1+SOverItem->FieldOverride.size()+1];
unsigned int End = 0;
SetTFRewriteData(Changes[End++],"Source",Package.c_str(),"Package");
- SetTFRewriteData(Changes[End++],"Files",Files);
+ SetTFRewriteData(Changes[End++],"Files",Files.c_str());
+ SetTFRewriteData(Changes[End++],"Checksums-Sha1",ChecksumsSha1.c_str());
+ SetTFRewriteData(Changes[End++],"Checksums-Sha256",ChecksumsSha256.c_str());
if (Directory != "./")
SetTFRewriteData(Changes[End++],"Directory",Directory.c_str());
SetTFRewriteData(Changes[End++],"Priority",BestPrio.c_str());
// ContentsWriter::ContentsWriter - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-ContentsWriter::ContentsWriter(string const &DB) :
- Db(DB), Stats(Db.Stats)
+ContentsWriter::ContentsWriter(string const &DB, string const &Arch) :
+ FTWScanner(Arch), Db(DB), Stats(Db.Stats)
{
- AddPattern("*.deb");
+ SetExts(".deb");
Output = stdout;
}
/*}}}*/
datestr[0] = '\0';
}
+ time_t const validuntil = now + _config->FindI("APT::FTPArchive::Release::ValidTime", 0);
+ char validstr[128];
+ if (now == validuntil ||
+ strftime(validstr, sizeof(validstr), "%a, %d %b %Y %H:%M:%S UTC",
+ gmtime(&validuntil)) == 0)
+ {
+ validstr[0] = '\0';
+ }
+
map<string,string> Fields;
Fields["Origin"] = "";
Fields["Label"] = "";
Fields["Version"] = "";
Fields["Codename"] = "";
Fields["Date"] = datestr;
+ Fields["Valid-Until"] = validstr;
Fields["Architectures"] = "";
Fields["Components"] = "";
Fields["Description"] = "";