diff options
Diffstat (limited to 'ftparchive')
-rw-r--r-- | ftparchive/cachedb.cc | 204 | ||||
-rw-r--r-- | ftparchive/cachedb.h | 35 | ||||
-rw-r--r-- | ftparchive/contents.cc | 10 | ||||
-rw-r--r-- | ftparchive/sources.h | 2 | ||||
-rw-r--r-- | ftparchive/writer.cc | 326 | ||||
-rw-r--r-- | ftparchive/writer.h | 14 |
6 files changed, 248 insertions, 343 deletions
diff --git a/ftparchive/cachedb.cc b/ftparchive/cachedb.cc index 0901492f7..df5eb1451 100644 --- a/ftparchive/cachedb.cc +++ b/ftparchive/cachedb.cc @@ -21,29 +21,31 @@ #include <apt-pkg/fileutl.h> #include <apt-pkg/debfile.h> #include <apt-pkg/gpgv.h> +#include <apt-pkg/hashes.h> #include <netinet/in.h> // htonl, etc #include <ctype.h> #include <stddef.h> #include <sys/stat.h> +#include <strings.h> #include "cachedb.h" #include <apti18n.h> /*}}}*/ -CacheDB::CacheDB(std::string const &DB) +CacheDB::CacheDB(std::string const &DB) : Dbp(0), Fd(NULL), DebFile(0) { TmpKey[0]='\0'; ReadyDB(DB); -}; +} CacheDB::~CacheDB() { ReadyDB(); delete DebFile; -}; +} // CacheDB::ReadyDB - Ready the DB2 /*{{{*/ // --------------------------------------------------------------------- @@ -268,15 +270,10 @@ bool CacheDB::GetCurStat() /*}}}*/ // CacheDB::GetFileInfo - Get all the info about the file /*{{{*/ // --------------------------------------------------------------------- -bool CacheDB::GetFileInfo(std::string const &FileName, bool const &DoControl, - bool const &DoContents, - bool const &GenContentsOnly, - bool const &DoSource, - bool const &DoMD5, bool const &DoSHA1, - bool const &DoSHA256, bool const &DoSHA512, +bool CacheDB::GetFileInfo(std::string const &FileName, bool const &DoControl, bool const &DoContents, + bool const &GenContentsOnly, bool const DoSource, unsigned int const DoHashes, bool const &checkMtime) { - bool result = true; this->FileName = FileName; if (GetCurStat() == false) @@ -284,31 +281,28 @@ bool CacheDB::GetFileInfo(std::string const &FileName, bool const &DoControl, OldStat = CurStat; if (GetFileStat(checkMtime) == false) - return false; + return false; /* if mtime changed, update CurStat from disk */ if (checkMtime == true && OldStat.mtime != CurStat.mtime) CurStat.Flags = FlSize; Stats.Bytes += CurStat.FileSize; - Stats.Packages++; + ++Stats.Packages; if ((DoControl && LoadControl() == false) - || (DoContents && LoadContents(GenContentsOnly) == false) - || (DoSource && LoadSource() == false) - || (DoMD5 && GetMD5(false) == false) - || (DoSHA1 && GetSHA1(false) == false) - || (DoSHA256 && GetSHA256(false) == false) - || (DoSHA512 && GetSHA512(false) == false) ) + || (DoContents && LoadContents(GenContentsOnly) == false) + || (DoSource && LoadSource() == false) + || (DoHashes != 0 && GetHashes(false, DoHashes) == false) + ) { - result = false; + return false; } - - return result; + + return true; } /*}}}*/ - -bool CacheDB::LoadSource() +bool CacheDB::LoadSource() /*{{{*/ { // Try to read the control information out of the DB. if ((CurStat.Flags & FlSource) == FlSource) @@ -338,7 +332,7 @@ bool CacheDB::LoadSource() return true; } - + /*}}}*/ // CacheDB::LoadControl - Load Control information /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -407,7 +401,7 @@ bool CacheDB::LoadContents(bool const &GenOnly) return true; } /*}}}*/ - +// CacheDB::GetHashes - Get the hashs /*{{{*/ static std::string bytes2hex(uint8_t *bytes, size_t length) { char buf[3]; std::string space; @@ -437,125 +431,63 @@ static void hex2bytes(uint8_t *bytes, const char *hex, int length) { bytes++; } } - -// CacheDB::GetMD5 - Get the MD5 hash /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool CacheDB::GetMD5(bool const &GenOnly) +bool CacheDB::GetHashes(bool const GenOnly, unsigned int const DoHashes) { - // Try to read the control information out of the DB. - if ((CurStat.Flags & FlMD5) == FlMD5) - { - if (GenOnly == true) - return true; - - MD5Res = bytes2hex(CurStat.MD5, sizeof(CurStat.MD5)); - return true; - } - - Stats.MD5Bytes += CurStat.FileSize; - - if (OpenFile() == false) - return false; + unsigned int FlHashes = DoHashes & (Hashes::MD5SUM | Hashes::SHA1SUM | Hashes::SHA256SUM | Hashes::SHA512SUM); + HashesList.clear(); - MD5Summation MD5; - if (Fd->Seek(0) == false || MD5.AddFD(*Fd, CurStat.FileSize) == false) - return false; - - MD5Res = MD5.Result(); - hex2bytes(CurStat.MD5, MD5Res.data(), sizeof(CurStat.MD5)); - CurStat.Flags |= FlMD5; - return true; -} - /*}}}*/ -// CacheDB::GetSHA1 - Get the SHA1 hash /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool CacheDB::GetSHA1(bool const &GenOnly) -{ - // Try to read the control information out of the DB. - if ((CurStat.Flags & FlSHA1) == FlSHA1) + if (FlHashes != 0) { - if (GenOnly == true) - return true; + if (OpenFile() == false) + return false; - SHA1Res = bytes2hex(CurStat.SHA1, sizeof(CurStat.SHA1)); - return true; - } - - Stats.SHA1Bytes += CurStat.FileSize; - - if (OpenFile() == false) - return false; + Hashes hashes; + if (Fd->Seek(0) == false || hashes.AddFD(*Fd, CurStat.FileSize, FlHashes) == false) + return false; - SHA1Summation SHA1; - if (Fd->Seek(0) == false || SHA1.AddFD(*Fd, CurStat.FileSize) == false) - return false; - - SHA1Res = SHA1.Result(); - hex2bytes(CurStat.SHA1, SHA1Res.data(), sizeof(CurStat.SHA1)); - CurStat.Flags |= FlSHA1; - return true; -} - /*}}}*/ -// CacheDB::GetSHA256 - Get the SHA256 hash /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool CacheDB::GetSHA256(bool const &GenOnly) -{ - // Try to read the control information out of the DB. - if ((CurStat.Flags & FlSHA256) == FlSHA256) - { - if (GenOnly == true) - return true; - - SHA256Res = bytes2hex(CurStat.SHA256, sizeof(CurStat.SHA256)); - return true; + HashStringList hl = hashes.GetHashStringList(); + for (HashStringList::const_iterator hs = hl.begin(); hs != hl.end(); ++hs) + { + HashesList.push_back(*hs); + if (strcasecmp(hs->HashType().c_str(), "SHA512") == 0) + { + Stats.SHA512Bytes += CurStat.FileSize; + hex2bytes(CurStat.SHA512, hs->HashValue().data(), sizeof(CurStat.SHA512)); + CurStat.Flags |= FlSHA512; + } + else if (strcasecmp(hs->HashType().c_str(), "SHA256") == 0) + { + Stats.SHA256Bytes += CurStat.FileSize; + hex2bytes(CurStat.SHA256, hs->HashValue().data(), sizeof(CurStat.SHA256)); + CurStat.Flags |= FlSHA256; + } + else if (strcasecmp(hs->HashType().c_str(), "SHA1") == 0) + { + Stats.SHA1Bytes += CurStat.FileSize; + hex2bytes(CurStat.SHA1, hs->HashValue().data(), sizeof(CurStat.SHA1)); + CurStat.Flags |= FlSHA1; + } + else if (strcasecmp(hs->HashType().c_str(), "MD5Sum") == 0) + { + Stats.MD5Bytes += CurStat.FileSize; + hex2bytes(CurStat.MD5, hs->HashValue().data(), sizeof(CurStat.MD5)); + CurStat.Flags |= FlMD5; + } + else if (strcasecmp(hs->HashType().c_str(), "Checksum-FileSize") == 0) + { + // we store it in a different field already + } + else + return _error->Error("Got unknown unrequested hashtype %s", hs->HashType().c_str()); + } } - - Stats.SHA256Bytes += CurStat.FileSize; - - if (OpenFile() == false) - return false; - - SHA256Summation SHA256; - if (Fd->Seek(0) == false || SHA256.AddFD(*Fd, CurStat.FileSize) == false) - return false; - - SHA256Res = SHA256.Result(); - hex2bytes(CurStat.SHA256, SHA256Res.data(), sizeof(CurStat.SHA256)); - CurStat.Flags |= FlSHA256; - return true; -} - /*}}}*/ -// CacheDB::GetSHA256 - Get the SHA256 hash /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool CacheDB::GetSHA512(bool const &GenOnly) -{ - // Try to read the control information out of the DB. - if ((CurStat.Flags & FlSHA512) == FlSHA512) - { - if (GenOnly == true) - return true; - - SHA512Res = bytes2hex(CurStat.SHA512, sizeof(CurStat.SHA512)); + if (GenOnly == true) return true; - } - - Stats.SHA512Bytes += CurStat.FileSize; - - if (OpenFile() == false) - return false; - SHA512Summation SHA512; - if (Fd->Seek(0) == false || SHA512.AddFD(*Fd, CurStat.FileSize) == false) - return false; - - SHA512Res = SHA512.Result(); - hex2bytes(CurStat.SHA512, SHA512Res.data(), sizeof(CurStat.SHA512)); - CurStat.Flags |= FlSHA512; - return true; + return HashesList.push_back(HashString("MD5Sum", bytes2hex(CurStat.MD5, sizeof(CurStat.MD5)))) && + HashesList.push_back(HashString("SHA1", bytes2hex(CurStat.SHA1, sizeof(CurStat.SHA1)))) && + HashesList.push_back(HashString("SHA256", bytes2hex(CurStat.SHA256, sizeof(CurStat.SHA256)))) && + HashesList.push_back(HashString("SHA512", bytes2hex(CurStat.SHA512, sizeof(CurStat.SHA512)))); } /*}}}*/ // CacheDB::Finish - Write back the cache structure /*{{{*/ diff --git a/ftparchive/cachedb.h b/ftparchive/cachedb.h index 29d710d2c..613963f6f 100644 --- a/ftparchive/cachedb.h +++ b/ftparchive/cachedb.h @@ -12,6 +12,7 @@ #ifndef CACHEDB_H #define CACHEDB_H +#include <apt-pkg/hashes.h> #include <apt-pkg/debfile.h> #include <db.h> @@ -94,15 +95,12 @@ class CacheDB bool LoadControl(); bool LoadContents(bool const &GenOnly); bool LoadSource(); - bool GetMD5(bool const &GenOnly); - bool GetSHA1(bool const &GenOnly); - bool GetSHA256(bool const &GenOnly); - bool GetSHA512(bool const &GenOnly); - + bool GetHashes(bool const GenOnly, unsigned int const DoHashes); + // Stat info stored in the DB, Fixed types since it is written to disk. enum FlagList {FlControl = (1<<0),FlMD5=(1<<1),FlContents=(1<<2), - FlSize=(1<<3), FlSHA1=(1<<4), FlSHA256=(1<<5), - FlSHA512=(1<<6), FlSource=(1<<7), + FlSize=(1<<3), FlSHA1=(1<<4), FlSHA256=(1<<5), + FlSHA512=(1<<6), FlSource=(1<<7) }; // the on-disk format changed (FileSize increased to 64bit) in @@ -142,12 +140,8 @@ class CacheDB debDebFile::MemControlExtract Control; ContentsExtract Contents; DscExtract Dsc; + HashStringList HashesList; - std::string MD5Res; - std::string SHA1Res; - std::string SHA256Res; - std::string SHA512Res; - // Runtime statistics struct Stats { @@ -183,16 +177,13 @@ class CacheDB bool SetFile(std::string const &FileName,struct stat St,FileFd *Fd); // terrible old overloaded interface - bool GetFileInfo(std::string const &FileName, - bool const &DoControl, - bool const &DoContents, - bool const &GenContentsOnly, - bool const &DoSource, - bool const &DoMD5, - bool const &DoSHA1, - bool const &DoSHA256, - bool const &DoSHA512, - bool const &checkMtime = false); + bool GetFileInfo(std::string const &FileName, + bool const &DoControl, + bool const &DoContents, + bool const &GenContentsOnly, + bool const DoSource, + unsigned int const DoHashes, + bool const &checkMtime = false); bool Finish(); diff --git a/ftparchive/contents.cc b/ftparchive/contents.cc index 91dd2b8bd..8c4181eda 100644 --- a/ftparchive/contents.cc +++ b/ftparchive/contents.cc @@ -302,17 +302,17 @@ void GenContents::DoPrint(FILE *Out,GenContents::Node *Top, char *Buf) DoPrint(Out,Top->BTreeRight,Buf); } /*}}}*/ -// ContentsExtract Constructor /*{{{*/ +// ContentsExtract Constructor /*{{{*/ ContentsExtract::ContentsExtract() - : Data(0), MaxSize(0), CurSize(0) + : Data(0), MaxSize(0), CurSize(0) { -}; +} /*}}}*/ -// ContentsExtract Destructor /*{{{*/ +// ContentsExtract Destructor /*{{{*/ ContentsExtract::~ContentsExtract() { free(Data); -}; +} /*}}}*/ // ContentsExtract::Read - Read the archive /*{{{*/ // --------------------------------------------------------------------- diff --git a/ftparchive/sources.h b/ftparchive/sources.h index 91e0b1376..9ada15728 100644 --- a/ftparchive/sources.h +++ b/ftparchive/sources.h @@ -17,7 +17,7 @@ class DscExtract bool TakeDsc(const void *Data, unsigned long Size); bool Read(std::string FileName); - DscExtract() : Data(0), Length(0) { + DscExtract() : Data(0), Length(0), IsClearSigned(false) { Data = new char[maxSize]; }; ~DscExtract() { diff --git a/ftparchive/writer.cc b/ftparchive/writer.cc index 7c1c9cc03..ded8715f8 100644 --- a/ftparchive/writer.cc +++ b/ftparchive/writer.cc @@ -54,29 +54,42 @@ FTWScanner *FTWScanner::Owner; // SetTFRewriteData - Helper for setting rewrite lists /*{{{*/ // --------------------------------------------------------------------- /* */ -inline void SetTFRewriteData(struct TFRewriteData &tfrd, - const char *tag, +static inline TFRewriteData SetTFRewriteData(const char *tag, const char *rewrite, const char *newtag = 0) { - tfrd.Tag = tag; - tfrd.Rewrite = rewrite; - tfrd.NewTag = newtag; + TFRewriteData tfrd; + tfrd.Tag = tag; + tfrd.Rewrite = rewrite; + tfrd.NewTag = newtag; + return tfrd; +} + /*}}}*/ +// ConfigToDoHashes - which hashes to generate /*{{{*/ +static void SingleConfigToDoHashes(unsigned int &DoHashes, std::string const &Conf, unsigned int const Flag) +{ + if (_config->FindB(Conf, true) == true) + DoHashes |= Flag; + else + DoHashes &= ~Flag; +} +static void ConfigToDoHashes(unsigned int &DoHashes, std::string const &Conf) +{ + SingleConfigToDoHashes(DoHashes, Conf + "::MD5", Hashes::MD5SUM); + SingleConfigToDoHashes(DoHashes, Conf + "::SHA1", Hashes::SHA1SUM); + SingleConfigToDoHashes(DoHashes, Conf + "::SHA256", Hashes::SHA256SUM); + SingleConfigToDoHashes(DoHashes, Conf + "::SHA512", Hashes::SHA512SUM); } /*}}}*/ // FTWScanner::FTWScanner - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -FTWScanner::FTWScanner(string const &Arch): Arch(Arch) +FTWScanner::FTWScanner(string const &Arch): Arch(Arch), DoHashes(~0) { ErrorPrinted = false; NoLinkAct = !_config->FindB("APT::FTPArchive::DeLinkAct",true); - - DoMD5 = _config->FindB("APT::FTPArchive::MD5",true); - DoSHA1 = _config->FindB("APT::FTPArchive::SHA1",true); - DoSHA256 = _config->FindB("APT::FTPArchive::SHA256",true); - DoSHA512 = _config->FindB("APT::FTPArchive::SHA512",true); + ConfigToDoHashes(DoHashes, "APT::FTPArchive"); } /*}}}*/ // FTWScanner::Scanner - FTW Scanner /*{{{*/ @@ -327,10 +340,7 @@ PackagesWriter::PackagesWriter(string const &DB,string const &Overrides,string c DeLinkLimit = 0; // Process the command line options - DoMD5 = _config->FindB("APT::FTPArchive::Packages::MD5",DoMD5); - DoSHA1 = _config->FindB("APT::FTPArchive::Packages::SHA1",DoSHA1); - DoSHA256 = _config->FindB("APT::FTPArchive::Packages::SHA256",DoSHA256); - DoSHA512 = _config->FindB("APT::FTPArchive::Packages::SHA512",DoSHA512); + ConfigToDoHashes(DoHashes, "APT::FTPArchive::Packages"); DoAlwaysStat = _config->FindB("APT::FTPArchive::AlwaysStat", false); DoContents = _config->FindB("APT::FTPArchive::Contents",true); NoOverride = _config->FindB("APT::FTPArchive::NoOverrideMsg",false); @@ -385,12 +395,12 @@ bool FTWScanner::SetExts(string const &Vals) bool PackagesWriter::DoPackage(string FileName) { // Pull all the data we need form the DB - if (Db.GetFileInfo(FileName, - true, /* DoControl */ - DoContents, - true, /* GenContentsOnly */ - false, /* DoSource */ - DoMD5, DoSHA1, DoSHA256, DoSHA512, DoAlwaysStat) == false) + if (Db.GetFileInfo(FileName, + true, /* DoControl */ + DoContents, + true, /* GenContentsOnly */ + false, /* DoSource */ + DoHashes, DoAlwaysStat) == false) { return false; } @@ -454,30 +464,29 @@ bool PackagesWriter::DoPackage(string FileName) } // This lists all the changes to the fields we are going to make. - // (7 hardcoded + maintainer + suggests + end marker) - TFRewriteData Changes[6+2+OverItem->FieldOverride.size()+1+1]; - - unsigned int End = 0; - SetTFRewriteData(Changes[End++], "Size", Size); - if (DoMD5 == true) - SetTFRewriteData(Changes[End++], "MD5sum", Db.MD5Res.c_str()); - if (DoSHA1 == true) - SetTFRewriteData(Changes[End++], "SHA1", Db.SHA1Res.c_str()); - if (DoSHA256 == true) - SetTFRewriteData(Changes[End++], "SHA256", Db.SHA256Res.c_str()); - if (DoSHA512 == true) - SetTFRewriteData(Changes[End++], "SHA512", Db.SHA512Res.c_str()); - SetTFRewriteData(Changes[End++], "Filename", NewFileName.c_str()); - SetTFRewriteData(Changes[End++], "Priority", OverItem->Priority.c_str()); - SetTFRewriteData(Changes[End++], "Status", 0); - SetTFRewriteData(Changes[End++], "Optional", 0); + std::vector<TFRewriteData> Changes; + + Changes.push_back(SetTFRewriteData("Size", Size)); + for (HashStringList::const_iterator hs = Db.HashesList.begin(); hs != Db.HashesList.end(); ++hs) + { + if (hs->HashType() == "MD5Sum") + Changes.push_back(SetTFRewriteData("MD5sum", hs->HashValue().c_str())); + else if (hs->HashType() == "Checksum-FileSize") + continue; + else + Changes.push_back(SetTFRewriteData(hs->HashType().c_str(), hs->HashValue().c_str())); + } + Changes.push_back(SetTFRewriteData("Filename", NewFileName.c_str())); + Changes.push_back(SetTFRewriteData("Priority", OverItem->Priority.c_str())); + Changes.push_back(SetTFRewriteData("Status", 0)); + Changes.push_back(SetTFRewriteData("Optional", 0)); string DescriptionMd5; if (LongDescription == false) { MD5Summation descmd5; descmd5.Add(desc.c_str()); DescriptionMd5 = descmd5.Result().Value(); - SetTFRewriteData(Changes[End++], "Description-md5", DescriptionMd5.c_str()); + Changes.push_back(SetTFRewriteData("Description-md5", DescriptionMd5.c_str())); if (TransWriter != NULL) TransWriter->DoPackage(Package, desc, DescriptionMd5); } @@ -492,12 +501,12 @@ bool PackagesWriter::DoPackage(string FileName) NewLine(1); ioprintf(c1out, _(" %s maintainer is %s not %s\n"), Package.c_str(), Tags.FindS("Maintainer").c_str(), OverItem->OldMaint.c_str()); - } + } } - + if (NewMaint.empty() == false) - SetTFRewriteData(Changes[End++], "Maintainer", NewMaint.c_str()); - + Changes.push_back(SetTFRewriteData("Maintainer", NewMaint.c_str())); + /* Get rid of the Optional tag. This is an ugly, ugly, ugly hack that dpkg-scanpackages does. Well sort of. dpkg-scanpackages just does renaming but dpkg does this append bit. So we do the append bit, at least that way the @@ -508,17 +517,17 @@ bool PackagesWriter::DoPackage(string FileName) { if (Tags.FindS("Suggests").empty() == false) OptionalStr = Tags.FindS("Suggests") + ", " + OptionalStr; - SetTFRewriteData(Changes[End++], "Suggests", OptionalStr.c_str()); + Changes.push_back(SetTFRewriteData("Suggests", OptionalStr.c_str())); } - for (map<string,string>::const_iterator I = OverItem->FieldOverride.begin(); + for (map<string,string>::const_iterator I = OverItem->FieldOverride.begin(); I != OverItem->FieldOverride.end(); ++I) - SetTFRewriteData(Changes[End++],I->first.c_str(),I->second.c_str()); + Changes.push_back(SetTFRewriteData(I->first.c_str(),I->second.c_str())); - SetTFRewriteData(Changes[End++], 0, 0); + Changes.push_back(SetTFRewriteData( 0, 0)); // Rewrite and store the fields. - if (TFRewrite(Output,Tags,TFRewritePackageOrder,Changes) == false) + if (TFRewrite(Output,Tags,TFRewritePackageOrder,Changes.data()) == false) return false; fprintf(Output,"\n"); @@ -589,10 +598,7 @@ SourcesWriter::SourcesWriter(string const &DB, string const &BOverrides,string c BufSize = 0; // Process the command line options - DoMD5 = _config->FindB("APT::FTPArchive::Sources::MD5",DoMD5); - DoSHA1 = _config->FindB("APT::FTPArchive::Sources::SHA1",DoSHA1); - DoSHA256 = _config->FindB("APT::FTPArchive::Sources::SHA256",DoSHA256); - DoSHA512 = _config->FindB("APT::FTPArchive::Sources::SHA512",DoSHA512); + ConfigToDoHashes(DoHashes, "APT::FTPArchive::Sources"); NoOverride = _config->FindB("APT::FTPArchive::NoOverrideMsg",false); DoAlwaysStat = _config->FindB("APT::FTPArchive::AlwaysStat", false); @@ -614,17 +620,25 @@ SourcesWriter::SourcesWriter(string const &DB, string const &BOverrides,string c } /*}}}*/ // SourcesWriter::DoPackage - Process a single package /*{{{*/ -// --------------------------------------------------------------------- -/* */ +static std::ostream& addDscHash(std::ostream &out, unsigned int const DoHashes, + Hashes::SupportedHashes const DoIt, pkgTagSection &Tags, char const * const FieldName, + HashString const * const Hash, unsigned long long Size, std::string FileName) +{ + if ((DoHashes & DoIt) != DoIt || Tags.Exists(FieldName) == false || Hash == NULL) + return out; + out << "\n " << Hash->HashValue() << " " << Size << " " << FileName + << "\n " << Tags.FindS(FieldName); + return out; +} bool SourcesWriter::DoPackage(string FileName) { // Pull all the data we need form the DB if (Db.GetFileInfo(FileName, - false, /* DoControl */ - false, /* DoContents */ - false, /* GenContentsOnly */ - true, /* DoSource */ - DoMD5, DoSHA1, DoSHA256, DoSHA512, DoAlwaysStat) == false) + false, /* DoControl */ + false, /* DoContents */ + false, /* GenContentsOnly */ + true, /* DoSource */ + DoHashes, DoAlwaysStat) == false) { return false; } @@ -712,29 +726,19 @@ bool SourcesWriter::DoPackage(string FileName) *SOverItem = *OverItem; } } - + // Add the dsc to the files hash list string const strippedName = flNotDir(FileName); std::ostringstream ostreamFiles; - if (DoMD5 == true && Tags.Exists("Files")) - ostreamFiles << "\n " << Db.MD5Res.c_str() << " " << St.st_size << " " - << strippedName << "\n " << Tags.FindS("Files"); + addDscHash(ostreamFiles, DoHashes, Hashes::MD5SUM, Tags, "Files", Db.HashesList.find("MD5Sum"), St.st_size, strippedName); string const Files = ostreamFiles.str(); std::ostringstream ostreamSha1; - if (DoSHA1 == true && Tags.Exists("Checksums-Sha1")) - ostreamSha1 << "\n " << string(Db.SHA1Res.c_str()) << " " << St.st_size << " " - << strippedName << "\n " << Tags.FindS("Checksums-Sha1"); - + addDscHash(ostreamSha1, DoHashes, Hashes::SHA1SUM, Tags, "Checksums-Sha1", Db.HashesList.find("SHA1"), St.st_size, strippedName); std::ostringstream ostreamSha256; - if (DoSHA256 == true && Tags.Exists("Checksums-Sha256")) - ostreamSha256 << "\n " << string(Db.SHA256Res.c_str()) << " " << St.st_size << " " - << strippedName << "\n " << Tags.FindS("Checksums-Sha256"); - + addDscHash(ostreamSha256, DoHashes, Hashes::SHA256SUM, Tags, "Checksums-Sha256", Db.HashesList.find("SHA256"), St.st_size, strippedName); std::ostringstream ostreamSha512; - if (DoSHA512 == true && Tags.Exists("Checksums-Sha512")) - ostreamSha512 << "\n " << string(Db.SHA512Res.c_str()) << " " << St.st_size << " " - << strippedName << "\n " << Tags.FindS("Checksums-Sha512"); + addDscHash(ostreamSha512, DoHashes, Hashes::SHA512SUM, Tags, "Checksums-Sha512", Db.HashesList.find("SHA512"), St.st_size, strippedName); // Strip the DirStrip prefix from the FileName and add the PathPrefix string NewFileName; @@ -766,35 +770,54 @@ bool SourcesWriter::DoPackage(string FileName) string OriginalPath = Directory + ParseJnk; // Add missing hashes to source files - if ((DoSHA1 == true && !Tags.Exists("Checksums-Sha1")) || - (DoSHA256 == true && !Tags.Exists("Checksums-Sha256")) || - (DoSHA512 == true && !Tags.Exists("Checksums-Sha512"))) + if (((DoHashes & Hashes::SHA1SUM) == Hashes::SHA1SUM && !Tags.Exists("Checksums-Sha1")) || + ((DoHashes & Hashes::SHA256SUM) == Hashes::SHA256SUM && !Tags.Exists("Checksums-Sha256")) || + ((DoHashes & Hashes::SHA512SUM) == Hashes::SHA512SUM && !Tags.Exists("Checksums-Sha512"))) { - if (Db.GetFileInfo(OriginalPath, + if (Db.GetFileInfo(OriginalPath, false, /* DoControl */ false, /* DoContents */ false, /* GenContentsOnly */ false, /* DoSource */ - DoMD5, DoSHA1, DoSHA256, DoSHA512, + DoHashes, DoAlwaysStat) == false) { return _error->Error("Error getting file info"); } - if (DoSHA1 == true && !Tags.Exists("Checksums-Sha1")) - ostreamSha1 << "\n " << string(Db.SHA1Res) << " " - << Db.GetFileSize() << " " << ParseJnk; - - if (DoSHA256 == true && !Tags.Exists("Checksums-Sha256")) - ostreamSha256 << "\n " << string(Db.SHA256Res) << " " - << Db.GetFileSize() << " " << ParseJnk; - - if (DoSHA512 == true && !Tags.Exists("Checksums-Sha512")) - ostreamSha512 << "\n " << string(Db.SHA512Res) << " " - << Db.GetFileSize() << " " << ParseJnk; + for (HashStringList::const_iterator hs = Db.HashesList.begin(); hs != Db.HashesList.end(); ++hs) + { + if (hs->HashType() == "MD5Sum" || hs->HashType() == "Checksum-FileSize") + continue; + char const * fieldname; + std::ostream * out; + if (hs->HashType() == "SHA1") + { + fieldname = "Checksums-Sha1"; + out = &ostreamSha1; + } + else if (hs->HashType() == "SHA256") + { + fieldname = "Checksums-Sha256"; + out = &ostreamSha256; + } + else if (hs->HashType() == "SHA512") + { + fieldname = "Checksums-Sha512"; + out = &ostreamSha512; + } + else + { + _error->Warning("Ignoring unknown Checksumtype %s in SourcesWriter::DoPackages", hs->HashType().c_str()); + continue; + } + if (Tags.Exists(fieldname) == true) + continue; + (*out) << "\n " << hs->HashValue() << " " << Db.GetFileSize() << " " << ParseJnk; + } - // write back the GetFileInfo() stats data - Db.Finish(); + // write back the GetFileInfo() stats data + Db.Finish(); } // Perform the delinking operation @@ -820,22 +843,21 @@ bool SourcesWriter::DoPackage(string FileName) // This lists all the changes to the fields we are going to make. // (5 hardcoded + checksums + maintainer + end marker) - TFRewriteData Changes[5+2+1+SOverItem->FieldOverride.size()+1]; + std::vector<TFRewriteData> Changes; - unsigned int End = 0; - SetTFRewriteData(Changes[End++],"Source",Package.c_str(),"Package"); + Changes.push_back(SetTFRewriteData("Source",Package.c_str(),"Package")); if (Files.empty() == false) - SetTFRewriteData(Changes[End++],"Files",Files.c_str()); + Changes.push_back(SetTFRewriteData("Files",Files.c_str())); if (ChecksumsSha1.empty() == false) - SetTFRewriteData(Changes[End++],"Checksums-Sha1",ChecksumsSha1.c_str()); + Changes.push_back(SetTFRewriteData("Checksums-Sha1",ChecksumsSha1.c_str())); if (ChecksumsSha256.empty() == false) - SetTFRewriteData(Changes[End++],"Checksums-Sha256",ChecksumsSha256.c_str()); + Changes.push_back(SetTFRewriteData("Checksums-Sha256",ChecksumsSha256.c_str())); if (ChecksumsSha512.empty() == false) - SetTFRewriteData(Changes[End++],"Checksums-Sha512",ChecksumsSha512.c_str()); + Changes.push_back(SetTFRewriteData("Checksums-Sha512",ChecksumsSha512.c_str())); if (Directory != "./") - SetTFRewriteData(Changes[End++],"Directory",Directory.c_str()); - SetTFRewriteData(Changes[End++],"Priority",BestPrio.c_str()); - SetTFRewriteData(Changes[End++],"Status",0); + Changes.push_back(SetTFRewriteData("Directory",Directory.c_str())); + Changes.push_back(SetTFRewriteData("Priority",BestPrio.c_str())); + Changes.push_back(SetTFRewriteData("Status",0)); // Rewrite the maintainer field if necessary bool MaintFailed; @@ -850,16 +872,16 @@ bool SourcesWriter::DoPackage(string FileName) } } if (NewMaint.empty() == false) - SetTFRewriteData(Changes[End++], "Maintainer", NewMaint.c_str()); + Changes.push_back(SetTFRewriteData("Maintainer", NewMaint.c_str())); for (map<string,string>::const_iterator I = SOverItem->FieldOverride.begin(); I != SOverItem->FieldOverride.end(); ++I) - SetTFRewriteData(Changes[End++],I->first.c_str(),I->second.c_str()); + Changes.push_back(SetTFRewriteData(I->first.c_str(),I->second.c_str())); - SetTFRewriteData(Changes[End++], 0, 0); + Changes.push_back(SetTFRewriteData(0, 0)); // Rewrite and store the fields. - if (TFRewrite(Output,Tags,TFRewriteSourceOrder,Changes) == false) + if (TFRewrite(Output,Tags,TFRewriteSourceOrder,Changes.data()) == false) return false; fprintf(Output,"\n"); @@ -886,15 +908,13 @@ ContentsWriter::ContentsWriter(string const &DB, string const &Arch) : determine what the package name is. */ bool ContentsWriter::DoPackage(string FileName, string Package) { - if (!Db.GetFileInfo(FileName, - Package.empty(), /* DoControl */ - true, /* DoContents */ - false, /* GenContentsOnly */ - false, /* DoSource */ - false, /* DoMD5 */ - false, /* DoSHA1 */ - false, /* DoSHA256 */ - false)) /* DoSHA512 */ + if (!Db.GetFileInfo(FileName, + Package.empty(), /* DoControl */ + true, /* DoContents */ + false, /* GenContentsOnly */ + false, /* DoSource */ + 0, /* DoHashes */ + false /* checkMtime */)) { return false; } @@ -1030,9 +1050,7 @@ ReleaseWriter::ReleaseWriter(string const &/*DB*/) fprintf(Output, "%s: %s\n", (*I).first.c_str(), Value.c_str()); } - DoMD5 = _config->FindB("APT::FTPArchive::Release::MD5",DoMD5); - DoSHA1 = _config->FindB("APT::FTPArchive::Release::SHA1",DoSHA1); - DoSHA256 = _config->FindB("APT::FTPArchive::Release::SHA256",DoSHA256); + ConfigToDoHashes(DoHashes, "APT::FTPArchive::Release"); } /*}}}*/ // ReleaseWriter::DoPackage - Process a single package /*{{{*/ @@ -1066,15 +1084,8 @@ bool ReleaseWriter::DoPackage(string FileName) CheckSums[NewFileName].size = fd.Size(); Hashes hs; - hs.AddFD(fd, 0, DoMD5, DoSHA1, DoSHA256, DoSHA512); - if (DoMD5 == true) - CheckSums[NewFileName].MD5 = hs.MD5.Result(); - if (DoSHA1 == true) - CheckSums[NewFileName].SHA1 = hs.SHA1.Result(); - if (DoSHA256 == true) - CheckSums[NewFileName].SHA256 = hs.SHA256.Result(); - if (DoSHA512 == true) - CheckSums[NewFileName].SHA512 = hs.SHA512.Result(); + hs.AddFD(fd, 0, DoHashes); + CheckSums[NewFileName].Hashes = hs.GetHashStringList(); fd.Close(); return true; @@ -1083,54 +1094,29 @@ bool ReleaseWriter::DoPackage(string FileName) /*}}}*/ // ReleaseWriter::Finish - Output the checksums /*{{{*/ // --------------------------------------------------------------------- -void ReleaseWriter::Finish() +static void printChecksumTypeRecord(FILE * const Output, char const * const Type, map<string, ReleaseWriter::CheckSum> const &CheckSums) { - if (DoMD5 == true) - { - fprintf(Output, "MD5Sum:\n"); - for(map<string,struct CheckSum>::const_iterator I = CheckSums.begin(); - I != CheckSums.end(); ++I) - { - fprintf(Output, " %s %16llu %s\n", - (*I).second.MD5.c_str(), - (*I).second.size, - (*I).first.c_str()); - } - } - if (DoSHA1 == true) - { - fprintf(Output, "SHA1:\n"); - for(map<string,struct CheckSum>::const_iterator I = CheckSums.begin(); - I != CheckSums.end(); ++I) - { - fprintf(Output, " %s %16llu %s\n", - (*I).second.SHA1.c_str(), - (*I).second.size, - (*I).first.c_str()); - } - } - if (DoSHA256 == true) - { - fprintf(Output, "SHA256:\n"); - for(map<string,struct CheckSum>::const_iterator I = CheckSums.begin(); + fprintf(Output, "%s:\n", Type); + for(map<string,ReleaseWriter::CheckSum>::const_iterator I = CheckSums.begin(); I != CheckSums.end(); ++I) { + HashString const * const hs = I->second.Hashes.find(Type); + if (hs == NULL) + continue; fprintf(Output, " %s %16llu %s\n", - (*I).second.SHA256.c_str(), + hs->HashValue().c_str(), (*I).second.size, (*I).first.c_str()); } - } - - fprintf(Output, "SHA512:\n"); - for(map<string,struct CheckSum>::const_iterator I = CheckSums.begin(); - I != CheckSums.end(); - ++I) - { - fprintf(Output, " %s %16llu %s\n", - (*I).second.SHA512.c_str(), - (*I).second.size, - (*I).first.c_str()); - } - +} +void ReleaseWriter::Finish() +{ + if ((DoHashes & Hashes::MD5SUM) == Hashes::MD5SUM) + printChecksumTypeRecord(Output, "MD5Sum", CheckSums); + if ((DoHashes & Hashes::SHA1SUM) == Hashes::SHA1SUM) + printChecksumTypeRecord(Output, "SHA1", CheckSums); + if ((DoHashes & Hashes::SHA256SUM) == Hashes::SHA256SUM) + printChecksumTypeRecord(Output, "SHA256", CheckSums); + if ((DoHashes & Hashes::SHA512SUM) == Hashes::SHA512SUM) + printChecksumTypeRecord(Output, "SHA512", CheckSums); } diff --git a/ftparchive/writer.h b/ftparchive/writer.h index d8a10e0bb..226996475 100644 --- a/ftparchive/writer.h +++ b/ftparchive/writer.h @@ -13,6 +13,8 @@ #ifndef WRITER_H #define WRITER_H +#include <apt-pkg/hashes.h> + #include <string> #include <stdio.h> #include <iostream> @@ -61,10 +63,7 @@ class FTWScanner } public: - bool DoMD5; - bool DoSHA1; - bool DoSHA256; - bool DoSHA512; + unsigned int DoHashes; unsigned long DeLinkLimit; string InternalPrefix; @@ -197,17 +196,14 @@ public: string PathPrefix; string DirStrip; -protected: struct CheckSum { - string MD5; - string SHA1; - string SHA256; - string SHA512; + HashStringList Hashes; // Limited by FileFd::Size() unsigned long long size; ~CheckSum() {}; }; +protected: map<string,struct CheckSum> CheckSums; }; |