X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/c511c5e8ed3f59ddee1b174b39e5cc16a2f11922..6cfadda161ce19e6c8076d0aa118f8f436805a6a:/ftparchive/writer.cc diff --git a/ftparchive/writer.cc b/ftparchive/writer.cc index db617e92a..1bc926d21 100644 --- a/ftparchive/writer.cc +++ b/ftparchive/writer.cc @@ -51,20 +51,6 @@ using namespace std; FTWScanner *FTWScanner::Owner; -// SetTFRewriteData - Helper for setting rewrite lists /*{{{*/ -// --------------------------------------------------------------------- -/* */ -static inline TFRewriteData SetTFRewriteData(const char *tag, - const char *rewrite, - const char *newtag = 0) -{ - 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) { @@ -83,15 +69,29 @@ static void ConfigToDoHashes(unsigned int &DoHashes, std::string const &Conf) /*}}}*/ // FTWScanner::FTWScanner - Constructor /*{{{*/ -// --------------------------------------------------------------------- -/* */ -FTWScanner::FTWScanner(string const &Arch): Arch(Arch), DoHashes(~0) +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 @@ -331,11 +331,11 @@ bool FTWScanner::Delink(string &FileName,const char *OriginalPath, // PackagesWriter::PackagesWriter - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -PackagesWriter::PackagesWriter(string const &DB,string const &Overrides,string const &ExtOverrides, - string const &Arch) : - FTWScanner(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) { - Output = stdout; SetExts(".deb .udeb"); DeLinkLimit = 0; @@ -385,7 +385,6 @@ bool FTWScanner::SetExts(string const &Vals) return true; } - /*}}}*/ // PackagesWriter::DoPackage - Process a single package /*{{{*/ // --------------------------------------------------------------------- @@ -440,9 +439,6 @@ bool PackagesWriter::DoPackage(string FileName) OverItem->Priority = Tags.FindS("Priority"); } - char Size[40]; - sprintf(Size,"%llu", (unsigned long long) FileSize); - // Strip the DirStrip prefix from the FileName and add the PathPrefix string NewFileName; if (DirStrip.empty() == false && @@ -464,27 +460,32 @@ bool PackagesWriter::DoPackage(string FileName) } // This lists all the changes to the fields we are going to make. - std::vector Changes; + std::vector Changes; + + std::string Size; + strprintf(Size, "%llu", (unsigned long long) FileSize); + Changes.push_back(pkgTagSection::Tag::Rewrite("Size", Size)); - 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())); + Changes.push_back(pkgTagSection::Tag::Rewrite("MD5sum", hs->HashValue())); + else if (hs->HashType() == "Checksum-FileSize") + continue; else - Changes.push_back(SetTFRewriteData(hs->HashType().c_str(), hs->HashValue().c_str())); + Changes.push_back(pkgTagSection::Tag::Rewrite(hs->HashType(), hs->HashValue())); } - 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)); + Changes.push_back(pkgTagSection::Tag::Rewrite("Filename", NewFileName)); + Changes.push_back(pkgTagSection::Tag::Rewrite("Priority", OverItem->Priority)); + Changes.push_back(pkgTagSection::Tag::Remove("Status")); + Changes.push_back(pkgTagSection::Tag::Remove("Optional")); string DescriptionMd5; if (LongDescription == false) { MD5Summation descmd5; descmd5.Add(desc.c_str()); DescriptionMd5 = descmd5.Result().Value(); - Changes.push_back(SetTFRewriteData("Description-md5", DescriptionMd5.c_str())); + Changes.push_back(pkgTagSection::Tag::Rewrite("Description-md5", DescriptionMd5)); if (TransWriter != NULL) TransWriter->DoPackage(Package, desc, DescriptionMd5); } @@ -503,7 +504,7 @@ bool PackagesWriter::DoPackage(string FileName) } if (NewMaint.empty() == false) - Changes.push_back(SetTFRewriteData("Maintainer", NewMaint.c_str())); + Changes.push_back(pkgTagSection::Tag::Rewrite("Maintainer", NewMaint)); /* 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 @@ -515,36 +516,37 @@ bool PackagesWriter::DoPackage(string FileName) { if (Tags.FindS("Suggests").empty() == false) OptionalStr = Tags.FindS("Suggests") + ", " + OptionalStr; - Changes.push_back(SetTFRewriteData("Suggests", OptionalStr.c_str())); + Changes.push_back(pkgTagSection::Tag::Rewrite("Suggests", OptionalStr)); } for (map::const_iterator I = OverItem->FieldOverride.begin(); I != OverItem->FieldOverride.end(); ++I) - Changes.push_back(SetTFRewriteData(I->first.c_str(),I->second.c_str())); - - Changes.push_back(SetTFRewriteData( 0, 0)); + Changes.push_back(pkgTagSection::Tag::Rewrite(I->first, I->second)); // Rewrite and store the fields. - if (TFRewrite(Output,Tags,TFRewritePackageOrder,Changes.data()) == false) + if (Tags.Write(*Output, TFRewritePackageOrder, Changes) == false || + Output->Write("\n", 1) == false) return false; - fprintf(Output,"\n"); 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) : Output(NULL), - RefCounter(0) + mode_t const &Permissions) : Comp(NULL), Output(NULL) { if (File.empty() == true) return; Comp = new MultiCompress(File, TransCompress, Permissions); - Output = Comp->Input; + Output = &Comp->Input; } /*}}}*/ // TranslationWriter::DoPackage - Process a single package /*{{{*/ @@ -563,8 +565,10 @@ bool TranslationWriter::DoPackage(string const &Pkg, string const &Desc, if (Included.find(Record) != Included.end()) return true; - fprintf(Output, "Package: %s\nDescription-md5: %s\nDescription-en: %s\n", + std::string out; + strprintf(out, "Package: %s\nDescription-md5: %s\nDescription-en: %s\n", Pkg.c_str(), MD5.c_str(), Desc.c_str()); + Output->Write(out.c_str(), out.length()); Included.insert(Record); return true; @@ -575,21 +579,18 @@ bool TranslationWriter::DoPackage(string const &Pkg, string const &Desc, /* */ TranslationWriter::~TranslationWriter() { - if (Comp == NULL) - return; - - delete Comp; + if (Comp != NULL) + delete Comp; } /*}}}*/ // SourcesWriter::SourcesWriter - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -SourcesWriter::SourcesWriter(string const &DB, string const &BOverrides,string const &SOverrides, +SourcesWriter::SourcesWriter(FileFd * const GivenOutput, string const &DB, string const &BOverrides,string const &SOverrides, string const &ExtOverrides) : - Db(DB), Stats(Db.Stats) + FTWScanner(GivenOutput), Db(DB), Stats(Db.Stats) { - Output = stdout; AddPattern("*.dsc"); DeLinkLimit = 0; Buffer = 0; @@ -618,15 +619,16 @@ 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, +static std::string getDscHash(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; + return ""; + std::ostringstream out; out << "\n " << Hash->HashValue() << " " << Size << " " << FileName << "\n " << Tags.FindS(FieldName); - return out; + return out.str(); } bool SourcesWriter::DoPackage(string FileName) { @@ -646,18 +648,10 @@ bool SourcesWriter::DoPackage(string FileName) // the "db cursor" Db.Finish(); - // read stuff - char *Start = Db.Dsc.Data; - char *BlkEnd = Db.Dsc.Data + Db.Dsc.Length; - - // Add extra \n to the end, just in case (as in clearsigned they are missing) - *BlkEnd++ = '\n'; - *BlkEnd++ = '\n'; - pkgTagSection Tags; - if (Tags.Scan(Start,BlkEnd - Start) == false) + if (Tags.Scan(Db.Dsc.Data.c_str(), Db.Dsc.Data.length()) == false) return _error->Error("Could not find a record in the DSC '%s'",FileName.c_str()); - + if (Tags.Exists("Source") == false) return _error->Error("Could not find a Source entry in the DSC '%s'",FileName.c_str()); Tags.Trim(); @@ -727,16 +721,10 @@ bool SourcesWriter::DoPackage(string FileName) // Add the dsc to the files hash list string const strippedName = flNotDir(FileName); - std::ostringstream ostreamFiles; - addDscHash(ostreamFiles, DoHashes, Hashes::MD5SUM, Tags, "Files", Db.HashesList.find("MD5Sum"), St.st_size, strippedName); - string const Files = ostreamFiles.str(); - - std::ostringstream ostreamSha1; - addDscHash(ostreamSha1, DoHashes, Hashes::SHA1SUM, Tags, "Checksums-Sha1", Db.HashesList.find("SHA1"), St.st_size, strippedName); - std::ostringstream ostreamSha256; - addDscHash(ostreamSha256, DoHashes, Hashes::SHA256SUM, Tags, "Checksums-Sha256", Db.HashesList.find("SHA256"), St.st_size, strippedName); - std::ostringstream ostreamSha512; - addDscHash(ostreamSha512, DoHashes, Hashes::SHA512SUM, Tags, "Checksums-Sha512", Db.HashesList.find("SHA512"), St.st_size, strippedName); + std::string const Files = getDscHash(DoHashes, Hashes::MD5SUM, Tags, "Files", Db.HashesList.find("MD5Sum"), St.st_size, strippedName); + std::string ChecksumsSha1 = getDscHash(DoHashes, Hashes::SHA1SUM, Tags, "Checksums-Sha1", Db.HashesList.find("SHA1"), St.st_size, strippedName); + std::string ChecksumsSha256 = getDscHash(DoHashes, Hashes::SHA256SUM, Tags, "Checksums-Sha256", Db.HashesList.find("SHA256"), St.st_size, strippedName); + std::string ChecksumsSha512 = getDscHash(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; @@ -758,7 +746,7 @@ bool SourcesWriter::DoPackage(string FileName) char *RealPath = NULL; for (;isspace(*C); C++); while (*C != 0) - { + { // Parse each of the elements if (ParseQuoteWord(C,ParseJnk) == false || ParseQuoteWord(C,ParseJnk) == false || @@ -785,24 +773,24 @@ bool SourcesWriter::DoPackage(string FileName) for (HashStringList::const_iterator hs = Db.HashesList.begin(); hs != Db.HashesList.end(); ++hs) { - if (hs->HashType() == "MD5Sum") + if (hs->HashType() == "MD5Sum" || hs->HashType() == "Checksum-FileSize") continue; char const * fieldname; - std::ostream * out; + std::string * out; if (hs->HashType() == "SHA1") { fieldname = "Checksums-Sha1"; - out = &ostreamSha1; + out = &ChecksumsSha1; } else if (hs->HashType() == "SHA256") { fieldname = "Checksums-Sha256"; - out = &ostreamSha256; + out = &ChecksumsSha256; } else if (hs->HashType() == "SHA512") { fieldname = "Checksums-Sha512"; - out = &ostreamSha512; + out = &ChecksumsSha512; } else { @@ -811,10 +799,12 @@ bool SourcesWriter::DoPackage(string FileName) } if (Tags.Exists(fieldname) == true) continue; - (*out) << "\n " << hs->HashValue() << " " << Db.GetFileSize() << " " << ParseJnk; + std::ostringstream streamout; + streamout << "\n " << hs->HashValue() << " " << Db.GetFileSize() << " " << ParseJnk; + out->append(streamout.str()); } - // write back the GetFileInfo() stats data + // write back the GetFileInfo() stats data Db.Finish(); } @@ -835,53 +825,48 @@ bool SourcesWriter::DoPackage(string FileName) if (Directory.length() > 2) Directory.erase(Directory.end()-1); - string const ChecksumsSha1 = ostreamSha1.str(); - string const ChecksumsSha256 = ostreamSha256.str(); - string const ChecksumsSha512 = ostreamSha512.str(); - // This lists all the changes to the fields we are going to make. // (5 hardcoded + checksums + maintainer + end marker) - std::vector Changes; + std::vector Changes; - Changes.push_back(SetTFRewriteData("Source",Package.c_str(),"Package")); + Changes.push_back(pkgTagSection::Tag::Remove("Source")); + Changes.push_back(pkgTagSection::Tag::Rewrite("Package", Package)); if (Files.empty() == false) - Changes.push_back(SetTFRewriteData("Files",Files.c_str())); + Changes.push_back(pkgTagSection::Tag::Rewrite("Files", Files)); if (ChecksumsSha1.empty() == false) - Changes.push_back(SetTFRewriteData("Checksums-Sha1",ChecksumsSha1.c_str())); + Changes.push_back(pkgTagSection::Tag::Rewrite("Checksums-Sha1", ChecksumsSha1)); if (ChecksumsSha256.empty() == false) - Changes.push_back(SetTFRewriteData("Checksums-Sha256",ChecksumsSha256.c_str())); + Changes.push_back(pkgTagSection::Tag::Rewrite("Checksums-Sha256", ChecksumsSha256)); if (ChecksumsSha512.empty() == false) - Changes.push_back(SetTFRewriteData("Checksums-Sha512",ChecksumsSha512.c_str())); + Changes.push_back(pkgTagSection::Tag::Rewrite("Checksums-Sha512", ChecksumsSha512)); if (Directory != "./") - Changes.push_back(SetTFRewriteData("Directory",Directory.c_str())); - Changes.push_back(SetTFRewriteData("Priority",BestPrio.c_str())); - Changes.push_back(SetTFRewriteData("Status",0)); + Changes.push_back(pkgTagSection::Tag::Rewrite("Directory", Directory)); + Changes.push_back(pkgTagSection::Tag::Rewrite("Priority", BestPrio)); + Changes.push_back(pkgTagSection::Tag::Remove("Status")); // Rewrite the maintainer field if necessary bool MaintFailed; - string NewMaint = OverItem->SwapMaint(Tags.FindS("Maintainer"),MaintFailed); + string NewMaint = OverItem->SwapMaint(Tags.FindS("Maintainer"), MaintFailed); if (MaintFailed == true) { if (NoOverride == false) { - NewLine(1); + 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) - Changes.push_back(SetTFRewriteData("Maintainer", NewMaint.c_str())); - - for (map::const_iterator I = SOverItem->FieldOverride.begin(); + Changes.push_back(pkgTagSection::Tag::Rewrite("Maintainer", NewMaint.c_str())); + + for (map::const_iterator I = SOverItem->FieldOverride.begin(); I != SOverItem->FieldOverride.end(); ++I) - Changes.push_back(SetTFRewriteData(I->first.c_str(),I->second.c_str())); + Changes.push_back(pkgTagSection::Tag::Rewrite(I->first, I->second)); - Changes.push_back(SetTFRewriteData(0, 0)); - // Rewrite and store the fields. - if (TFRewrite(Output,Tags,TFRewriteSourceOrder,Changes.data()) == false) + if (Tags.Write(*Output, TFRewriteSourceOrder, Changes) == false || + Output->Write("\n", 1) == false) return false; - fprintf(Output,"\n"); Stats.Packages++; @@ -892,12 +877,11 @@ bool SourcesWriter::DoPackage(string FileName) // ContentsWriter::ContentsWriter - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -ContentsWriter::ContentsWriter(string const &DB, string const &Arch) : - FTWScanner(Arch), Db(DB), Stats(Db.Stats) +ContentsWriter::ContentsWriter(FileFd * const GivenOutput, string const &DB, string const &Arch) : + FTWScanner(GivenOutput, Arch), Db(DB), Stats(Db.Stats) { SetExts(".deb"); - Output = stdout; } /*}}}*/ // ContentsWriter::DoPackage - Process a single package /*{{{*/ @@ -979,7 +963,7 @@ bool ContentsWriter::ReadFromPkgs(string const &PkgFile,string const &PkgCompres // ReleaseWriter::ReleaseWriter - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -ReleaseWriter::ReleaseWriter(string const &/*DB*/) +ReleaseWriter::ReleaseWriter(FileFd * const GivenOutput, string const &/*DB*/) : FTWScanner(GivenOutput) { if (_config->FindB("APT::FTPArchive::Release::Default-Patterns", true) == true) { @@ -1001,7 +985,6 @@ ReleaseWriter::ReleaseWriter(string const &/*DB*/) } AddPatterns(_config->FindVector("APT::FTPArchive::Release::Patterns")); - Output = stdout; time_t const now = time(NULL); setlocale(LC_TIME, "C"); @@ -1045,7 +1028,8 @@ ReleaseWriter::ReleaseWriter(string const &/*DB*/) if (Value == "") continue; - fprintf(Output, "%s: %s\n", (*I).first.c_str(), Value.c_str()); + std::string const out = I->first + ": " + Value + "\n"; + Output->Write(out.c_str(), out.length()); } ConfigToDoHashes(DoHashes, "APT::FTPArchive::Release"); @@ -1081,8 +1065,8 @@ bool ReleaseWriter::DoPackage(string FileName) CheckSums[NewFileName].size = fd.Size(); - Hashes hs; - hs.AddFD(fd, 0, DoHashes); + Hashes hs(DoHashes); + hs.AddFD(fd); CheckSums[NewFileName].Hashes = hs.GetHashStringList(); fd.Close(); @@ -1092,29 +1076,35 @@ bool ReleaseWriter::DoPackage(string FileName) /*}}}*/ // ReleaseWriter::Finish - Output the checksums /*{{{*/ // --------------------------------------------------------------------- -static void printChecksumTypeRecord(FILE * const Output, char const * const Type, map const &CheckSums) +static void printChecksumTypeRecord(FileFd &Output, char const * const Type, map const &CheckSums) { - fprintf(Output, "%s:\n", Type); - for(map::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", - hs->HashValue().c_str(), - (*I).second.size, - (*I).first.c_str()); - } + { + std::string out; + strprintf(out, "%s:\n", Type); + Output.Write(out.c_str(), out.length()); + } + for(map::const_iterator I = CheckSums.begin(); + I != CheckSums.end(); ++I) + { + HashString const * const hs = I->second.Hashes.find(Type); + if (hs == NULL) + continue; + std::string out; + strprintf(out, " %s %16llu %s\n", + hs->HashValue().c_str(), + (*I).second.size, + (*I).first.c_str()); + Output.Write(out.c_str(), out.length()); + } } void ReleaseWriter::Finish() { if ((DoHashes & Hashes::MD5SUM) == Hashes::MD5SUM) - printChecksumTypeRecord(Output, "MD5Sum", CheckSums); + printChecksumTypeRecord(*Output, "MD5Sum", CheckSums); if ((DoHashes & Hashes::SHA1SUM) == Hashes::SHA1SUM) - printChecksumTypeRecord(Output, "SHA1", CheckSums); + printChecksumTypeRecord(*Output, "SHA1", CheckSums); if ((DoHashes & Hashes::SHA256SUM) == Hashes::SHA256SUM) - printChecksumTypeRecord(Output, "SHA256", CheckSums); + printChecksumTypeRecord(*Output, "SHA256", CheckSums); if ((DoHashes & Hashes::SHA512SUM) == Hashes::SHA512SUM) - printChecksumTypeRecord(Output, "SHA512", CheckSums); + printChecksumTypeRecord(*Output, "SHA512", CheckSums); }