X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/21231056c2f4fb82730c0ac7e7f90456668cae38..655122418d714f342b5d9789f45f8035f3fe8b9a:/ftparchive/apt-ftparchive.cc diff --git a/ftparchive/apt-ftparchive.cc b/ftparchive/apt-ftparchive.cc index 3b1e80631..f13e4648a 100644 --- a/ftparchive/apt-ftparchive.cc +++ b/ftparchive/apt-ftparchive.cc @@ -3,30 +3,32 @@ // $Id: apt-ftparchive.cc,v 1.8.2.3 2004/01/02 22:01:48 mdz Exp $ /* ###################################################################### - apt-scanpackages - Efficient work-alike for dpkg-scanpackages + apt-ftparchive - Efficient work-alike for dpkg-scanpackages Let contents be disabled from the conf ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#include "apt-ftparchive.h" - +#include + #include #include #include #include -#include -#include +#include #include #include #include #include +#include "apt-ftparchive.h" #include "contents.h" #include "multicompress.h" -#include "writer.h" +#include "writer.h" + +#include /*}}}*/ using namespace std; @@ -62,6 +64,10 @@ struct PackageMap string SrcOverride; string SrcExtraOverride; + // Translation master file + bool LongDesc; + TranslationWriter *TransWriter; + // Contents string Contents; string ContentsHead; @@ -100,8 +106,9 @@ struct PackageMap vector::iterator End, unsigned long &Left); - PackageMap() : DeLinkLimit(0), Permissions(1), ContentsDone(false), - PkgDone(false), SrcDone(false), ContentsMTime(0) {}; + PackageMap() : LongDesc(true), TransWriter(NULL), DeLinkLimit(0), Permissions(1), + ContentsDone(false), PkgDone(false), SrcDone(false), + ContentsMTime(0) {}; }; /*}}}*/ @@ -130,7 +137,7 @@ void PackageMap::GetGeneral(Configuration &Setup,Configuration &Block) Setup.Find("Default::Packages::Extensions",".deb").c_str()); Permissions = Setup.FindI("Default::FileMode",0644); - + if (FLFile.empty() == false) FLFile = flCombine(Setup.Find("Dir::FileListDir"),FLFile); @@ -169,6 +176,9 @@ bool PackageMap::GenPackages(Configuration &Setup,struct CacheDB::Stats &Stats) Packages.DirStrip = ArchiveDir; Packages.InternalPrefix = flCombine(ArchiveDir,InternalPrefix); + Packages.TransWriter = TransWriter; + Packages.LongDescription = LongDesc; + Packages.Stats.DeLinkBytes = Stats.DeLinkBytes; Packages.DeLinkLimit = DeLinkLimit; @@ -196,7 +206,7 @@ bool PackageMap::GenPackages(Configuration &Setup,struct CacheDB::Stats &Stats) Packages.Output = 0; // Just in case // Finish compressing - unsigned long Size; + unsigned long long Size; if (Comp.Finalize(Size) == false) { c0out << endl; @@ -244,7 +254,8 @@ bool PackageMap::GenSources(Configuration &Setup,struct CacheDB::Stats &Stats) SrcDone = true; // Create a package writer object. - SourcesWriter Sources(flCombine(OverrideDir,BinOverride), + SourcesWriter Sources(_config->Find("APT::FTPArchive::DB"), + flCombine(OverrideDir,BinOverride), flCombine(OverrideDir,SrcOverride), flCombine(OverrideDir,SrcExtraOverride)); if (SrcExt.empty() == false && Sources.SetExts(SrcExt) == false) @@ -282,7 +293,7 @@ bool PackageMap::GenSources(Configuration &Setup,struct CacheDB::Stats &Stats) Sources.Output = 0; // Just in case // Finish compressing - unsigned long Size; + unsigned long long Size; if (Comp.Finalize(Size) == false) { c0out << endl; @@ -333,7 +344,7 @@ bool PackageMap::GenContents(Configuration &Setup, gettimeofday(&StartTime,0); // Create a package writer object. - ContentsWriter Contents(""); + ContentsWriter Contents("", Arch); if (PkgExt.empty() == false && Contents.SetExts(PkgExt) == false) return _error->Error(_("Package extension list is too long")); if (_error->PendingError() == true) @@ -353,11 +364,11 @@ bool PackageMap::GenContents(Configuration &Setup, if (_error->PendingError() == true) return false; - unsigned long Size = Head.Size(); + unsigned long long Size = Head.Size(); unsigned char Buf[4096]; while (Size != 0) { - unsigned long ToRead = Size; + unsigned long long ToRead = Size; if (Size > sizeof(Buf)) ToRead = sizeof(Buf); @@ -375,7 +386,7 @@ bool PackageMap::GenContents(Configuration &Setup, files associated with this contents file into one great big honking memory structure, then dump the sorted version */ c0out << ' ' << this->Contents << ":" << flush; - for (vector::iterator I = Begin; I != End; I++) + for (vector::iterator I = Begin; I != End; ++I) { if (I->Contents != this->Contents) continue; @@ -391,7 +402,7 @@ bool PackageMap::GenContents(Configuration &Setup, Contents.Finish(); // Finish compressing - unsigned long Size; + unsigned long long Size; if (Comp.Finalize(Size) == false || _error->PendingError() == true) { c0out << endl; @@ -427,7 +438,7 @@ bool PackageMap::GenContents(Configuration &Setup, // --------------------------------------------------------------------- /* This populates the PkgList with all the possible permutations of the section/arch lists. */ -void LoadTree(vector &PkgList,Configuration &Setup) +static void LoadTree(vector &PkgList,Configuration &Setup) { // Load the defaults string DDir = Setup.Find("TreeDefault::Directory", @@ -436,10 +447,12 @@ void LoadTree(vector &PkgList,Configuration &Setup) "$(DIST)/$(SECTION)/source/"); string DPkg = Setup.Find("TreeDefault::Packages", "$(DIST)/$(SECTION)/binary-$(ARCH)/Packages"); + string DTrans = Setup.Find("TreeDefault::Translation", + "$(DIST)/$(SECTION)/i18n/Translation-en"); string DIPrfx = Setup.Find("TreeDefault::InternalPrefix", "$(DIST)/$(SECTION)/"); string DContents = Setup.Find("TreeDefault::Contents", - "$(DIST)/Contents-$(ARCH)"); + "$(DIST)/$(SECTION)/Contents-$(ARCH)"); string DContentsH = Setup.Find("TreeDefault::Contents::Header",""); string DBCache = Setup.Find("TreeDefault::BinCacheDB", "packages-$(ARCH).db"); @@ -448,6 +461,12 @@ void LoadTree(vector &PkgList,Configuration &Setup) string DFLFile = Setup.Find("TreeDefault::FileList", ""); string DSFLFile = Setup.Find("TreeDefault::SourceFileList", ""); + mode_t const Permissions = Setup.FindI("Default::FileMode",0644); + + bool const LongDescription = Setup.FindB("Default::LongDescription", + _config->FindB("APT::FTPArchive::LongDescription", true)); + string const TranslationCompress = Setup.Find("Default::Translation::Compress",". gzip").c_str(); + // Process 'tree' type sections const Configuration::Item *Top = Setup.Tree("tree"); for (Top = (Top == 0?0:Top->Child); Top != 0;) @@ -461,17 +480,30 @@ void LoadTree(vector &PkgList,Configuration &Setup) string Section; while (ParseQuoteWord(Sections,Section) == true) { - string Tmp2 = Block.Find("Architectures"); string Arch; + struct SubstVar const Vars[] = {{"$(DIST)",&Dist}, + {"$(SECTION)",&Section}, + {"$(ARCH)",&Arch}, + {NULL, NULL}}; + mode_t const Perms = Block.FindI("FileMode", Permissions); + bool const LongDesc = Block.FindB("LongDescription", LongDescription); + TranslationWriter *TransWriter; + if (DTrans.empty() == false && LongDesc == false) + { + string const TranslationFile = flCombine(Setup.FindDir("Dir::ArchiveDir"), + SubstVar(Block.Find("Translation", DTrans.c_str()), Vars)); + string const TransCompress = Block.Find("Translation::Compress", TranslationCompress); + TransWriter = new TranslationWriter(TranslationFile, TransCompress, Perms); + } + else + TransWriter = NULL; + + string const Tmp2 = Block.Find("Architectures"); const char *Archs = Tmp2.c_str(); while (ParseQuoteWord(Archs,Arch) == true) { - struct SubstVar Vars[] = {{"$(DIST)",&Dist}, - {"$(SECTION)",&Section}, - {"$(ARCH)",&Arch}, - {}}; PackageMap Itm; - + Itm.Permissions = Perms; Itm.BinOverride = SubstVar(Block.Find("BinOverride"),Vars); Itm.InternalPrefix = SubstVar(Block.Find("InternalPrefix",DIPrfx.c_str()),Vars); @@ -491,6 +523,12 @@ void LoadTree(vector &PkgList,Configuration &Setup) Itm.PkgFile = SubstVar(Block.Find("Packages",DPkg.c_str()),Vars); Itm.Tag = SubstVar("$(DIST)/$(SECTION)/$(ARCH)",Vars); Itm.Arch = Arch; + Itm.LongDesc = LongDesc; + if (TransWriter != NULL) + { + TransWriter->IncreaseRefCounter(); + Itm.TransWriter = TransWriter; + } Itm.Contents = SubstVar(Block.Find("Contents",DContents.c_str()),Vars); Itm.ContentsHead = SubstVar(Block.Find("Contents::Header",DContentsH.c_str()),Vars); Itm.FLFile = SubstVar(Block.Find("FileList",DFLFile.c_str()),Vars); @@ -500,6 +538,9 @@ void LoadTree(vector &PkgList,Configuration &Setup) Itm.GetGeneral(Setup,Block); PkgList.push_back(Itm); } + // we didn't use this TransWriter, so we can release it + if (TransWriter != NULL && TransWriter->GetRefCounter() == 0) + delete TransWriter; } Top = Top->Next; @@ -509,8 +550,10 @@ void LoadTree(vector &PkgList,Configuration &Setup) // LoadBinDir - Load a 'bindirectory' section from the Generate Config /*{{{*/ // --------------------------------------------------------------------- /* */ -void LoadBinDir(vector &PkgList,Configuration &Setup) +static void LoadBinDir(vector &PkgList,Configuration &Setup) { + mode_t const Permissions = Setup.FindI("Default::FileMode",0644); + // Process 'bindirectory' type sections const Configuration::Item *Top = Setup.Tree("bindirectory"); for (Top = (Top == 0?0:Top->Child); Top != 0;) @@ -530,6 +573,7 @@ void LoadBinDir(vector &PkgList,Configuration &Setup) Itm.InternalPrefix = Block.Find("InternalPrefix",Top->Tag.c_str()); Itm.Contents = Block.Find("Contents"); Itm.ContentsHead = Block.Find("Contents::Header"); + Itm.Permissions = Block.FindI("FileMode", Permissions); Itm.GetGeneral(Setup,Block); PkgList.push_back(Itm); @@ -542,9 +586,9 @@ void LoadBinDir(vector &PkgList,Configuration &Setup) // ShowHelp - Show the help text /*{{{*/ // --------------------------------------------------------------------- /* */ -bool ShowHelp(CommandLine &CmdL) +static bool ShowHelp(CommandLine &) { - ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION, + ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, COMMON_ARCH,__DATE__,__TIME__); if (_config->FindB("version") == true) return true; @@ -595,7 +639,7 @@ bool ShowHelp(CommandLine &CmdL) // SimpleGenPackages - Generate a Packages file for a directory tree /*{{{*/ // --------------------------------------------------------------------- /* This emulates dpkg-scanpackages's command line interface. 'mostly' */ -bool SimpleGenPackages(CommandLine &CmdL) +static bool SimpleGenPackages(CommandLine &CmdL) { if (CmdL.FileSize() < 2) return ShowHelp(CmdL); @@ -606,7 +650,7 @@ bool SimpleGenPackages(CommandLine &CmdL) // Create a package writer object. PackagesWriter Packages(_config->Find("APT::FTPArchive::DB"), - Override, ""); + Override, "", _config->Find("APT::FTPArchive::Architecture")); if (_error->PendingError() == true) return false; @@ -623,13 +667,13 @@ bool SimpleGenPackages(CommandLine &CmdL) // SimpleGenContents - Generate a Contents listing /*{{{*/ // --------------------------------------------------------------------- /* */ -bool SimpleGenContents(CommandLine &CmdL) +static bool SimpleGenContents(CommandLine &CmdL) { if (CmdL.FileSize() < 2) return ShowHelp(CmdL); // Create a package writer object. - ContentsWriter Contents(_config->Find("APT::FTPArchive::DB")); + ContentsWriter Contents(_config->Find("APT::FTPArchive::DB"), _config->Find("APT::FTPArchive::Architecture")); if (_error->PendingError() == true) return false; @@ -645,7 +689,7 @@ bool SimpleGenContents(CommandLine &CmdL) // SimpleGenSources - Generate a Sources file for a directory tree /*{{{*/ // --------------------------------------------------------------------- /* This emulates dpkg-scanpackages's command line interface. 'mostly' */ -bool SimpleGenSources(CommandLine &CmdL) +static bool SimpleGenSources(CommandLine &CmdL) { if (CmdL.FileSize() < 2) return ShowHelp(CmdL); @@ -662,7 +706,7 @@ bool SimpleGenSources(CommandLine &CmdL) SOverride.c_str()); // Create a package writer object. - SourcesWriter Sources(Override,SOverride); + SourcesWriter Sources(_config->Find("APT::FTPArchive::DB"),Override,SOverride); if (_error->PendingError() == true) return false; @@ -678,7 +722,7 @@ bool SimpleGenSources(CommandLine &CmdL) /*}}}*/ // SimpleGenRelease - Generate a Release file for a directory tree /*{{{*/ // --------------------------------------------------------------------- -bool SimpleGenRelease(CommandLine &CmdL) +static bool SimpleGenRelease(CommandLine &CmdL) { if (CmdL.FileSize() < 2) return ShowHelp(CmdL); @@ -703,7 +747,7 @@ bool SimpleGenRelease(CommandLine &CmdL) // Generate - Full generate, using a config file /*{{{*/ // --------------------------------------------------------------------- /* */ -bool Generate(CommandLine &CmdL) +static bool Generate(CommandLine &CmdL) { struct CacheDB::Stats SrcStats; if (CmdL.FileSize() < 2) @@ -728,10 +772,10 @@ bool Generate(CommandLine &CmdL) // Generate packages if (CmdL.FileSize() <= 2) { - for (vector::iterator I = PkgList.begin(); I != PkgList.end(); I++) + for (vector::iterator I = PkgList.begin(); I != PkgList.end(); ++I) if (I->GenPackages(Setup,Stats) == false) _error->DumpErrors(); - for (vector::iterator I = PkgList.begin(); I != PkgList.end(); I++) + for (vector::iterator I = PkgList.begin(); I != PkgList.end(); ++I) if (I->GenSources(Setup,SrcStats) == false) _error->DumpErrors(); } @@ -740,7 +784,7 @@ bool Generate(CommandLine &CmdL) // Make a choice list out of the package list.. RxChoiceList *List = new RxChoiceList[2*PkgList.size()+1]; RxChoiceList *End = List; - for (vector::iterator I = PkgList.begin(); I != PkgList.end(); I++) + for (vector::iterator I = PkgList.begin(); I != PkgList.end(); ++I) { End->UserData = &(*I); End->Str = I->BaseDir.c_str(); @@ -788,15 +832,20 @@ bool Generate(CommandLine &CmdL) delete [] List; } - + + // close the Translation master files + for (vector::reverse_iterator I = PkgList.rbegin(); I != PkgList.rend(); ++I) + if (I->TransWriter != NULL && I->TransWriter->DecreaseRefCounter() == 0) + delete I->TransWriter; + if (_config->FindB("APT::FTPArchive::Contents",true) == false) return true; - c1out << "Done Packages, Starting contents." << endl; + c1out << "Packages done, Starting contents." << endl; // Sort the contents file list by date string ArchiveDir = Setup.FindDir("Dir::ArchiveDir"); - for (vector::iterator I = PkgList.begin(); I != PkgList.end(); I++) + for (vector::iterator I = PkgList.begin(); I != PkgList.end(); ++I) { struct stat A; if (MultiCompress::GetStat(flCombine(ArchiveDir,I->Contents), @@ -813,9 +862,9 @@ bool Generate(CommandLine &CmdL) hashes of the .debs this means they have not changed either so the contents must be up to date. */ unsigned long MaxContentsChange = Setup.FindI("Default::MaxContentsChange",UINT_MAX)*1024; - for (vector::iterator I = PkgList.begin(); I != PkgList.end(); I++) + for (vector::iterator I = PkgList.begin(); I != PkgList.end(); ++I) { - // This record is not relevent + // This record is not relevant if (I->ContentsDone == true || I->Contents.empty() == true) continue; @@ -862,7 +911,7 @@ bool Generate(CommandLine &CmdL) // Clean - Clean out the databases /*{{{*/ // --------------------------------------------------------------------- /* */ -bool Clean(CommandLine &CmdL) +static bool Clean(CommandLine &CmdL) { if (CmdL.FileSize() != 2) return ShowHelp(CmdL); @@ -889,7 +938,7 @@ bool Clean(CommandLine &CmdL) _error->DumpErrors(); string CacheDB = I->BinCacheDB; - for (; I != PkgList.end() && I->BinCacheDB == CacheDB; I++); + for (; I != PkgList.end() && I->BinCacheDB == CacheDB; ++I); } return true; @@ -898,9 +947,12 @@ bool Clean(CommandLine &CmdL) int main(int argc, const char *argv[]) { + setlocale(LC_ALL, ""); CommandLine::Args Args[] = { {'h',"help","help",0}, {0,"md5","APT::FTPArchive::MD5",0}, + {0,"sha1","APT::FTPArchive::SHA1",0}, + {0,"sha256","APT::FTPArchive::SHA256",0}, {'v',"version","version",0}, {'d',"db","APT::FTPArchive::DB",CommandLine::HasArg}, {'s',"source-override","APT::FTPArchive::SourceOverride",CommandLine::HasArg}, @@ -909,6 +961,7 @@ int main(int argc, const char *argv[]) {0,"delink","APT::FTPArchive::DeLinkAct",0}, {0,"readonly","APT::FTPArchive::ReadOnlyDB",0}, {0,"contents","APT::FTPArchive::Contents",0}, + {'a',"arch","APT::FTPArchive::Architecture",CommandLine::HasArg}, {'c',"config-file",0,CommandLine::ConfigFile}, {'o',"option",0,CommandLine::ArbItem}, {0,0,0,0}}; @@ -923,7 +976,7 @@ int main(int argc, const char *argv[]) // Parse the command line and initialize the package library CommandLine CmdL(Args,_config); - if (CmdL.Parse(argc,argv) == false) + if (pkgInitConfig(*_config) == false || CmdL.Parse(argc,argv) == false) { _error->DumpErrors(); return 100;