diff options
Diffstat (limited to 'apt-pkg/deb')
-rw-r--r-- | apt-pkg/deb/debindexfile.cc | 13 | ||||
-rw-r--r-- | apt-pkg/deb/debindexfile.h | 5 | ||||
-rw-r--r-- | apt-pkg/deb/deblistparser.cc | 238 | ||||
-rw-r--r-- | apt-pkg/deb/deblistparser.h | 10 | ||||
-rw-r--r-- | apt-pkg/deb/debmetaindex.cc | 112 | ||||
-rw-r--r-- | apt-pkg/deb/debmetaindex.h | 2 | ||||
-rw-r--r-- | apt-pkg/deb/debrecords.cc | 10 | ||||
-rw-r--r-- | apt-pkg/deb/debrecords.h | 1 | ||||
-rw-r--r-- | apt-pkg/deb/debsrcrecords.cc | 8 | ||||
-rw-r--r-- | apt-pkg/deb/dpkgpm.cc | 53 |
10 files changed, 281 insertions, 171 deletions
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc index af1209ccb..1e8c04033 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -66,7 +66,10 @@ pkgSrcRecords::Parser *debSourcesIndex::CreateSrcParser() const string SourcesURI = _config->FindDir("Dir::State::lists") + URItoFileName(IndexURI("Sources")); string SourcesURIgzip = SourcesURI + ".gz"; - if (!FileExists(SourcesURI) && FileExists(SourcesURIgzip)) + + if (!FileExists(SourcesURI) && !FileExists(SourcesURIgzip)) + return NULL; + else if (!FileExists(SourcesURI) && FileExists(SourcesURIgzip)) SourcesURI = SourcesURIgzip; return new debSrcRecordParser(SourcesURI,this); @@ -324,8 +327,14 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const return _error->Error("Problem with MergeList %s",PackageFile.c_str()); // Check the release file - string ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("Release"); + string ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("InRelease"); + bool releaseExists = false; if (FileExists(ReleaseFile) == true) + releaseExists = true; + else + ReleaseFile = debReleaseIndex(URI,Dist).MetaIndexFile("Release"); + + if (releaseExists == true || FileExists(ReleaseFile) == true) { FileFd Rel(ReleaseFile,FileFd::ReadOnly); if (_error->PendingError() == true) diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h index 0f8d4433f..678c22473 100644 --- a/apt-pkg/deb/debindexfile.h +++ b/apt-pkg/deb/debindexfile.h @@ -24,8 +24,10 @@ class debStatusIndex : public pkgIndexFile { /** \brief dpointer placeholder (for later in case we need it) */ void *d; + + protected: string File; - + public: virtual const Type *GetType() const; @@ -38,6 +40,7 @@ class debStatusIndex : public pkgIndexFile virtual bool HasPackages() const {return true;}; virtual unsigned long Size() const; virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; + bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog, unsigned long const Flag) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; debStatusIndex(string File); diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 1b3bfd6ae..a94b79f05 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -67,23 +67,12 @@ string debListParser::Package() { /*}}}*/ // ListParser::Architecture - Return the package arch /*{{{*/ // --------------------------------------------------------------------- -/* This will return the Architecture of the package this section describes - Note that architecture "all" packages will get the architecture of the - Packages file parsed here. */ +/* This will return the Architecture of the package this section describes */ string debListParser::Architecture() { - string const Result = Section.FindS("Architecture"); - if (Result.empty() == true || Result == "all") - { - if (Arch.empty() == true) - /* FIXME: this is a problem for installed arch all - packages as we don't know from which arch this - package was installed - and therefore which - dependency this package resolves. */ - return _config->Find("APT::Architecture"); - else - return Arch; - } - return Result; + std::string const Arch = Section.FindS("Architecture"); + if (Arch.empty() == true) + return _config->Find("APT::Architecture"); + return Arch; } /*}}}*/ // ListParser::ArchitectureAll /*{{{*/ @@ -112,29 +101,35 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) Ver->Section = UniqFindTagWrite("Section"); // Parse multi-arch - if (Section.FindS("Architecture") == "all") - /* Arch all packages can't have a Multi-Arch field, - but we need a special treatment for them nonetheless */ - Ver->MultiArch = pkgCache::Version::All; - else - { - string const MultiArch = Section.FindS("Multi-Arch"); - if (MultiArch.empty() == true) - Ver->MultiArch = pkgCache::Version::None; - else if (MultiArch == "same") - Ver->MultiArch = pkgCache::Version::Same; - else if (MultiArch == "foreign") - Ver->MultiArch = pkgCache::Version::Foreign; - else if (MultiArch == "allowed") - Ver->MultiArch = pkgCache::Version::Allowed; - else + string const MultiArch = Section.FindS("Multi-Arch"); + if (MultiArch.empty() == true) + Ver->MultiArch = pkgCache::Version::None; + else if (MultiArch == "same") { + // Parse multi-arch + if (ArchitectureAll() == true) { - _error->Warning("Unknown Multi-Arch type »%s« for package »%s«", - MultiArch.c_str(), Section.FindS("Package").c_str()); + /* Arch all packages can't be Multi-Arch: same */ + _error->Warning("Architecture: all package '%s' can't be Multi-Arch: same", + Section.FindS("Package").c_str()); Ver->MultiArch = pkgCache::Version::None; } + else + Ver->MultiArch = pkgCache::Version::Same; + } + else if (MultiArch == "foreign") + Ver->MultiArch = pkgCache::Version::Foreign; + else if (MultiArch == "allowed") + Ver->MultiArch = pkgCache::Version::Allowed; + else + { + _error->Warning("Unknown Multi-Arch type '%s' for package '%s'", + MultiArch.c_str(), Section.FindS("Package").c_str()); + Ver->MultiArch = pkgCache::Version::None; } + if (ArchitectureAll() == true) + Ver->MultiArch |= pkgCache::Version::All; + // Archive Size Ver->Size = Section.FindULL("Size"); // Unpacked Size (in K) @@ -150,24 +145,6 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) Ver->Priority = pkgCache::State::Extra; } - if (Ver->MultiArch == pkgCache::Version::All) - { - /* We maintain a "pseudo" arch=all package for architecture all versions - on which these versions can depend on. This pseudo package is many used - for downloading/installing: The other pseudo-packages will degenerate - to a NOP in the download/install step - this package will ensure that - it is downloaded only one time and installed only one time -- even if - the architecture bound versions coming in and out on regular basis. */ - if (strcmp(Ver.Arch(true),"all") == 0) - return true; - else if (MultiArchEnabled == true) - { - // our pseudo packages have no size to not confuse the fetcher - Ver->Size = 0; - Ver->InstalledSize = 0; - } - } - if (ParseDepends(Ver,"Depends",pkgCache::Dep::Depends) == false) return false; if (ParseDepends(Ver,"Pre-Depends",pkgCache::Dep::PreDepends) == false) @@ -302,18 +279,18 @@ unsigned short debListParser::VersionHash() /* Strip out any spaces from the text, this undoes dpkgs reformatting of certain fields. dpkg also has the rather interesting notion of reformatting depends operators < -> <= */ - char *I = S; + char *J = S; for (; Start != End; Start++) { if (isspace(*Start) == 0) - *I++ = tolower_ascii(*Start); + *J++ = tolower_ascii(*Start); if (*Start == '<' && Start[1] != '<' && Start[1] != '=') - *I++ = '='; + *J++ = '='; if (*Start == '>' && Start[1] != '>' && Start[1] != '=') - *I++ = '='; + *J++ = '='; } - Result = AddCRC16(Result,S,I - S); + Result = AddCRC16(Result,S,J - S); } return Result; @@ -505,7 +482,7 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop, // Parse off the package name const char *I = Start; for (;I != Stop && isspace(*I) == 0 && *I != '(' && *I != ')' && - *I != ',' && *I != '|'; I++); + *I != ',' && *I != '|' && *I != '[' && *I != ']'; I++); // Malformed, no '(' if (I != Stop && *I == ')') @@ -644,13 +621,13 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver, return true; string Package; - string const pkgArch = Ver.Arch(true); + string const pkgArch = Ver.Arch(); string Version; unsigned int Op; while (1) { - Start = ParseDepends(Start,Stop,Package,Version,Op); + Start = ParseDepends(Start,Stop,Package,Version,Op,false,!MultiArchEnabled); if (Start == 0) return _error->Error("Problem parsing dependency %s",Tag); @@ -683,7 +660,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver) { string Package; string Version; - string const Arch = Ver.Arch(true); + string const Arch = Ver.Arch(); unsigned int Op; while (1) @@ -703,27 +680,28 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver) } } - if (Ver->MultiArch == pkgCache::Version::Allowed) + if (MultiArchEnabled == false) + return true; + else if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed) { string const Package = string(Ver.ParentPkg().Name()).append(":").append("any"); - NewProvides(Ver, Package, "any", Ver.VerStr()); + return NewProvidesAllArch(Ver, Package, Ver.VerStr()); } + else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) + return NewProvidesAllArch(Ver, Ver.ParentPkg().Name(), Ver.VerStr()); - if (Ver->MultiArch != pkgCache::Version::Foreign) - return true; - - if (MultiArchEnabled == false) - return true; - - string const Package = Ver.ParentPkg().Name(); - string const Version = Ver.VerStr(); + return true; +} + /*}}}*/ +// ListParser::NewProvides - add provides for all architectures /*{{{*/ +bool debListParser::NewProvidesAllArch(pkgCache::VerIterator &Ver, string const &Package, + string const &Version) { for (std::vector<string>::const_iterator a = Architectures.begin(); a != Architectures.end(); ++a) { if (NewProvides(Ver, Package, *a, Version) == false) return false; } - return true; } /*}}}*/ @@ -768,7 +746,7 @@ bool debListParser::Step() if (Architecture == Arch) return true; - if (Architecture == "all") + if (Architecture == "all" && Arch == _config->Find("APT::Architecture")) return true; } @@ -783,45 +761,89 @@ bool debListParser::Step() bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, FileFd &File, string component) { - pkgTagFile Tags(&File, File.Size() + 256); // XXX - pkgTagSection Section; - if (Tags.Step(Section) == false) - return false; - - // FIXME: Do we need it now for multi-arch? - // mvo: I don't think we need to fill that in (it's unused since apt-0.6) -// FileI->Architecture = WriteUniqString(Arch); - // apt-secure does no longer download individual (per-section) Release // file. to provide Component pinning we use the section name now FileI->Component = WriteUniqString(component); - const char *Start; - const char *Stop; - if (Section.Find("Suite",Start,Stop) == true) - FileI->Archive = WriteUniqString(Start,Stop - Start); - if (Section.Find("Component",Start,Stop) == true) - FileI->Component = WriteUniqString(Start,Stop - Start); - if (Section.Find("Version",Start,Stop) == true) - FileI->Version = WriteUniqString(Start,Stop - Start); - if (Section.Find("Origin",Start,Stop) == true) - FileI->Origin = WriteUniqString(Start,Stop - Start); - if (Section.Find("Codename",Start,Stop) == true) - FileI->Codename = WriteUniqString(Start,Stop - Start); - if (Section.Find("Label",Start,Stop) == true) - FileI->Label = WriteUniqString(Start,Stop - Start); - if (Section.Find("Architecture",Start,Stop) == true) - FileI->Architecture = WriteUniqString(Start,Stop - Start); - - if (Section.FindFlag("NotAutomatic",FileI->Flags, - pkgCache::Flag::NotAutomatic) == false) - _error->Warning("Bad NotAutomatic flag"); - if (Section.FindFlag("ButAutomaticUpgrades",FileI->Flags, - pkgCache::Flag::ButAutomaticUpgrades) == false) - _error->Warning("Bad ButAutomaticUpgrades flag"); - // overrule the NotAutomatic setting if needed as they are both present for compatibility - else if ((FileI->Flags & pkgCache::Flag::ButAutomaticUpgrades) == pkgCache::Flag::ButAutomaticUpgrades) - FileI->Flags &= ~pkgCache::Flag::NotAutomatic; + FILE* release = fdopen(dup(File.Fd()), "r"); + if (release == NULL) + return false; + + char buffer[101]; + bool gpgClose = false; + while (fgets(buffer, sizeof(buffer), release) != NULL) + { + size_t len = 0; + + // Skip empty lines + for (; buffer[len] == '\r' && buffer[len] == '\n'; ++len); + if (buffer[len] == '\0') + continue; + + // only evalute the first GPG section + if (strncmp("-----", buffer, 5) == 0) + { + if (gpgClose == true) + break; + gpgClose = true; + continue; + } + + // seperate the tag from the data + for (; buffer[len] != ':' && buffer[len] != '\0'; ++len); + if (buffer[len] == '\0') + continue; + char* dataStart = buffer + len; + for (++dataStart; *dataStart == ' '; ++dataStart); + char* dataEnd = dataStart; + for (++dataEnd; *dataEnd != '\0'; ++dataEnd); + + // which datastorage need to be updated + map_ptrloc* writeTo = NULL; + if (buffer[0] == ' ') + ; + #define APT_PARSER_WRITETO(X, Y) else if (strncmp(Y, buffer, len) == 0) writeTo = &X; + APT_PARSER_WRITETO(FileI->Archive, "Suite") + APT_PARSER_WRITETO(FileI->Component, "Component") + APT_PARSER_WRITETO(FileI->Version, "Version") + APT_PARSER_WRITETO(FileI->Origin, "Origin") + APT_PARSER_WRITETO(FileI->Codename, "Codename") + APT_PARSER_WRITETO(FileI->Label, "Label") + #undef APT_PARSER_WRITETO + #define APT_PARSER_FLAGIT(X) else if (strncmp(#X, buffer, len) == 0) \ + pkgTagSection::FindFlag(FileI->Flags, pkgCache::Flag:: X, dataStart, dataEnd-1); + APT_PARSER_FLAGIT(NotAutomatic) + APT_PARSER_FLAGIT(ButAutomaticUpgrades) + #undef APT_PARSER_FLAGIT + + // load all data from the line and save it + string data; + if (writeTo != NULL) + data.append(dataStart, dataEnd); + if (sizeof(buffer) - 1 == (dataEnd - buffer)) + { + while (fgets(buffer, sizeof(buffer), release) != NULL) + { + if (writeTo != NULL) + data.append(buffer); + if (strlen(buffer) != sizeof(buffer) - 1) + break; + } + } + if (writeTo != NULL) + { + // remove spaces and stuff from the end of the data line + for (std::string::reverse_iterator s = data.rbegin(); + s != data.rend(); ++s) + { + if (*s != '\r' && *s != '\n' && *s != ' ') + break; + *s = '\0'; + } + *writeTo = WriteUniqString(data); + } + } + fclose(release); return !_error->PendingError(); } diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 54da938ec..41d712fbf 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -25,11 +25,12 @@ class debListParser : public pkgCacheGenerator::ListParser const char *Str; unsigned char Val; }; - + private: /** \brief dpointer placeholder (for later in case we need it) */ void *d; - + + protected: pkgTagFile Tags; pkgTagSection Section; unsigned long iOffset; @@ -38,10 +39,11 @@ class debListParser : public pkgCacheGenerator::ListParser bool MultiArchEnabled; unsigned long UniqFindTagWrite(const char *Tag); - bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver); + virtual bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver); bool ParseDepends(pkgCache::VerIterator &Ver,const char *Tag, unsigned int Type); bool ParseProvides(pkgCache::VerIterator &Ver); + bool NewProvidesAllArch(pkgCache::VerIterator &Ver, string const &Package, string const &Version); static bool GrabWord(string Word,WordList *List,unsigned char &Out); public: @@ -71,7 +73,7 @@ class debListParser : public pkgCacheGenerator::ListParser static const char *ParseDepends(const char *Start,const char *Stop, string &Package,string &Ver,unsigned int &Op, bool const &ParseArchFlags = false, - bool const &StripMultiArch = false); + bool const &StripMultiArch = true); static const char *ConvertRelation(const char *I,unsigned int &Op); debListParser(FileFd *File, string const &Arch = ""); diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index 717d0bcde..a91cc34e9 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -119,6 +119,29 @@ string debReleaseIndex::SourceIndexURI(const char *Type, const string &Section) return URI + "dists/" + Dist + "/" + SourceIndexURISuffix(Type, Section); } +string debReleaseIndex::TranslationIndexURISuffix(const char *Type, const string &Section) const +{ + string Res =""; + if (Dist[Dist.size() - 1] != '/') + Res += Section + "/i18n/"; + return Res + Type; +} + +string debReleaseIndex::TranslationIndexURI(const char *Type, const string &Section) const +{ + string Res; + if (Dist[Dist.size() - 1] == '/') + { + if (Dist != "/") + Res = URI + Dist; + else + Res = URI; + return Res + Type; + } + else + return URI + "dists/" + Dist + "/" + TranslationIndexURISuffix(Type, Section); +} + debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist) { this->URI = URI; this->Dist = Dist; @@ -155,6 +178,7 @@ vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const { if (IndexTargets->empty() == false && ArchEntries.size() == 1) return IndexTargets; + std::set<std::string> sections; for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin(); a != ArchEntries.end(); ++a) { if (a->first == "source") @@ -167,6 +191,40 @@ vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const { Target->URI = IndexURI(Target->ShortDesc.c_str(), (*I)->Section, a->first); Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section, a->first); IndexTargets->push_back (Target); + sections.insert((*I)->Section); + } + } + + std::vector<std::string> const lang = APT::Configuration::getLanguages(true); + if (lang.empty() == true) + return IndexTargets; + + // get the Translations: + // - if its a dists-style repository get the i18n/Index first + // - if its flat try to acquire files by guessing + if (Dist[Dist.size() - 1] == '/') { + for (std::set<std::string>::const_iterator s = sections.begin(); + s != sections.end(); ++s) { + for (std::vector<std::string>::const_iterator l = lang.begin(); + l != lang.end(); l++) { + if (*l == "none") continue; + IndexTarget * Target = new OptionalIndexTarget(); + Target->ShortDesc = "Translation-" + *l; + Target->MetaKey = TranslationIndexURISuffix(l->c_str(), *s); + Target->URI = TranslationIndexURI(l->c_str(), *s); + Target->Description = Info (Target->ShortDesc.c_str(), *s); + IndexTargets->push_back(Target); + } + } + } else { + for (std::set<std::string>::const_iterator s = sections.begin(); + s != sections.end(); ++s) { + IndexTarget * Target = new OptionalIndexTarget(); + Target->ShortDesc = "TranslationIndex"; + Target->MetaKey = TranslationIndexURISuffix("Index", *s); + Target->URI = TranslationIndexURI("Index", *s); + Target->Description = Info (Target->ShortDesc.c_str(), *s); + IndexTargets->push_back (Target); } } @@ -182,58 +240,34 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const new pkgAcqIndex(Owner, (*Target)->URI, (*Target)->Description, (*Target)->ShortDesc, HashString()); } - // this is normally created in pkgAcqMetaSig, but if we run - // in --print-uris mode, we add it here - new pkgAcqMetaIndex(Owner, MetaIndexURI("Release"), - MetaIndexInfo("Release"), "Release", - MetaIndexURI("Release.gpg"), - ComputeIndexTargets(), - new indexRecords (Dist)); - } - new pkgAcqMetaSig(Owner, MetaIndexURI("Release.gpg"), - MetaIndexInfo("Release.gpg"), "Release.gpg", - MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release", - ComputeIndexTargets(), - new indexRecords (Dist)); - - // Queue the translations - std::vector<std::string> const lang = APT::Configuration::getLanguages(true); - map<string, set<string> > sections; - for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin(); - a != ArchEntries.end(); ++a) { - if (a->first == "source") - continue; - for (vector<debSectionEntry const*>::const_iterator I = a->second.begin(); - I != a->second.end(); I++) - sections[(*I)->Section].insert(lang.begin(), lang.end()); - } - - for (map<string, set<string> >::const_iterator s = sections.begin(); - s != sections.end(); ++s) - for (set<string>::const_iterator l = s->second.begin(); - l != s->second.end(); l++) { - if (*l == "none") continue; - debTranslationsIndex i = debTranslationsIndex(URI,Dist,s->first,(*l).c_str()); - i.GetIndexes(Owner); - } + new pkgAcqMetaClearSig(Owner, MetaIndexURI("InRelease"), + MetaIndexInfo("InRelease"), "InRelease", + MetaIndexURI("Release"), MetaIndexInfo("Release"), "Release", + MetaIndexURI("Release.gpg"), MetaIndexInfo("Release.gpg"), "Release.gpg", + ComputeIndexTargets(), + new indexRecords (Dist)); return true; } bool debReleaseIndex::IsTrusted() const { - string VerifiedSigFile = _config->FindDir("Dir::State::lists") + - URItoFileName(MetaIndexURI("Release")) + ".gpg"; - if(_config->FindB("APT::Authentication::TrustCDROM", false)) if(URI.substr(0,strlen("cdrom:")) == "cdrom:") return true; - + + string VerifiedSigFile = _config->FindDir("Dir::State::lists") + + URItoFileName(MetaIndexURI("Release")) + ".gpg"; + if (FileExists(VerifiedSigFile)) return true; - return false; + + VerifiedSigFile = _config->FindDir("Dir::State::lists") + + URItoFileName(MetaIndexURI("InRelease")); + + return FileExists(VerifiedSigFile); } vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() { diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h index ffcc7c4bb..0aaf7f14a 100644 --- a/apt-pkg/deb/debmetaindex.h +++ b/apt-pkg/deb/debmetaindex.h @@ -39,6 +39,8 @@ class debReleaseIndex : public metaIndex { string IndexURISuffix(const char *Type, string const &Section, string const &Arch="native") const; string SourceIndexURI(const char *Type, const string &Section) const; string SourceIndexURISuffix(const char *Type, const string &Section) const; + string TranslationIndexURI(const char *Type, const string &Section) const; + string TranslationIndexURISuffix(const char *Type, const string &Section) const; virtual vector <pkgIndexFile *> *GetIndexFiles(); virtual bool IsTrusted() const; diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc index ec9e395ef..1ca9ae1d2 100644 --- a/apt-pkg/deb/debrecords.cc +++ b/apt-pkg/deb/debrecords.cc @@ -77,7 +77,7 @@ string debRecordParser::SHA1Hash() return Section.FindS("SHA1"); } /*}}}*/ -// RecordParser::SHA1Hash - Return the archive hash /*{{{*/ +// RecordParser::SHA256Hash - Return the archive hash /*{{{*/ // --------------------------------------------------------------------- /* */ string debRecordParser::SHA256Hash() @@ -85,6 +85,14 @@ string debRecordParser::SHA256Hash() return Section.FindS("SHA256"); } /*}}}*/ +// RecordParser::SHA512Hash - Return the archive hash /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::SHA512Hash() +{ + return Section.FindS("SHA512"); +} + /*}}}*/ // RecordParser::Maintainer - Return the maintainer email /*{{{*/ // --------------------------------------------------------------------- /* */ diff --git a/apt-pkg/deb/debrecords.h b/apt-pkg/deb/debrecords.h index bbcb5640d..9692ac94c 100644 --- a/apt-pkg/deb/debrecords.h +++ b/apt-pkg/deb/debrecords.h @@ -39,6 +39,7 @@ class debRecordParser : public pkgRecords::Parser virtual string MD5Hash(); virtual string SHA1Hash(); virtual string SHA256Hash(); + virtual string SHA512Hash(); virtual string SourcePkg(); virtual string SourceVer(); diff --git a/apt-pkg/deb/debsrcrecords.cc b/apt-pkg/deb/debsrcrecords.cc index 21336e1af..749305005 100644 --- a/apt-pkg/deb/debsrcrecords.cc +++ b/apt-pkg/deb/debsrcrecords.cc @@ -14,6 +14,7 @@ #include <apt-pkg/error.h> #include <apt-pkg/strutl.h> #include <apt-pkg/configuration.h> +#include <apt-pkg/aptconfiguration.h> using std::max; /*}}}*/ @@ -111,7 +112,9 @@ bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List) string Base = Sect.FindS("Directory"); if (Base.empty() == false && Base[Base.length()-1] != '/') Base += '/'; - + + std::vector<std::string> const compExts = APT::Configuration::getCompressorExtensions(); + // Iterate over the entire list grabbing each triplet const char *C = Files.c_str(); while (*C != 0) @@ -144,7 +147,8 @@ bool debSrcRecordParser::Files(vector<pkgSrcRecords::File> &List) } F.Type = string(F.Path,Tmp+1,Pos-Tmp); - if (F.Type == "gz" || F.Type == "bz2" || F.Type == "lzma" || F.Type == "tar") + if (std::find(compExts.begin(), compExts.end(), std::string(".").append(F.Type)) != compExts.end() || + F.Type == "tar") { Pos = Tmp-1; continue; diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 55525db85..cd7c4e5d5 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -324,6 +324,15 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) SetCloseExec(STDIN_FILENO,false); SetCloseExec(STDERR_FILENO,false); + if (_config->FindDir("DPkg::Chroot-Directory","/") != "/") + { + std::cerr << "Chrooting into " + << _config->FindDir("DPkg::Chroot-Directory") + << std::endl; + if (chroot(_config->FindDir("DPkg::Chroot-Directory","/").c_str()) != 0) + _exit(100); + } + const char *Args[4]; Args[0] = "/bin/sh"; Args[1] = "-c"; @@ -338,7 +347,6 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) return _error->Errno("fdopen","Faild to open new FD"); // Feed it the filenames. - bool Die = false; if (Version <= 1) { for (vector<Item>::iterator I = List.begin(); I != List.end(); I++) @@ -355,14 +363,11 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) into the pipe. */ fprintf(F,"%s\n",I->File.c_str()); if (ferror(F) != 0) - { - Die = true; break; - } } } else - Die = !SendV2Pkgs(F); + SendV2Pkgs(F); fclose(F); @@ -402,8 +407,9 @@ void pkgDPkgPM::DoTerminalPty(int master) { // this happens when the child is about to exit, we // give it time to actually exit, otherwise we run - // into a race - usleep(500000); + // into a race so we sleep for half a second. + struct timespec sleepfor = { 0, 500000000 }; + nanosleep(&sleepfor, NULL); return; } if(len <= 0) @@ -901,7 +907,10 @@ bool pkgDPkgPM::Go(int OutStatusFd) // Generate the argument list const char *Args[MaxArgs + 50]; - + // keep track of allocated strings for multiarch package names + char *Packages[MaxArgs + 50]; + unsigned int pkgcount = 0; + // Now check if we are within the MaxArgs limit // // this code below is problematic, because it may happen that @@ -1009,16 +1018,27 @@ bool pkgDPkgPM::Go(int OutStatusFd) } else { + string const nativeArch = _config->Find("APT::Architecture"); + unsigned long const oldSize = I->Op == Item::Configure ? Size : 0; for (;I != J && Size < MaxArgBytes; I++) { if((*I).Pkg.end() == true) continue; if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end()) continue; - Args[n++] = I->Pkg.Name(); + if (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all")) + Args[n++] = I->Pkg.Name(); + else + { + Packages[pkgcount] = strdup(I->Pkg.FullName(false).c_str()); + Args[n++] = Packages[pkgcount++]; + } Size += strlen(Args[n-1]); - } - } + } + // skip configure action if all sheduled packages disappeared + if (oldSize == Size) + continue; + } Args[n] = 0; J = I; @@ -1165,6 +1185,11 @@ bool pkgDPkgPM::Go(int OutStatusFd) sigemptyset(&sigmask); sigprocmask(SIG_BLOCK,&sigmask,&original_sigmask); + /* clean up the temporary allocation for multiarch package names in + the parent, so we don't leak memory when we return. */ + for (unsigned int i = 0; i < pkgcount; i++) + free(Packages[i]); + // the result of the waitpid call int res; int select_ret; @@ -1246,7 +1271,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) strprintf(d->dpkg_error, "Sub-process %s exited unexpectedly",Args[0]); if(d->dpkg_error.size() > 0) - _error->Error(d->dpkg_error.c_str()); + _error->Error("%s", d->dpkg_error.c_str()); if(stopOnError) { @@ -1431,7 +1456,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) { while( fgets(buf, sizeof(buf), log) != NULL) fprintf(report, " %s", buf); - fclose(log); + pclose(log); } } @@ -1447,7 +1472,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) { while( fgets(buf, sizeof(buf), log) != NULL) fprintf(report, " %s", buf); - fclose(log); + pclose(log); } } |