From acdafb440bd086fdb81bd61e03d5c89b057f0f6c Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Mon, 20 Apr 2009 22:41:10 +0000 Subject: [PATCH] Numerous fundamental performance improvements for APT. M cfnetwork.diff A display.diff A find.diff A finddesc.diff A hashtable.diff A intl.diff A longdesc.diff A mmap.diff A printf.diff A public.diff A tag.diff D textdomain.diff git-svn-id: http://svn.telesphoreo.org/trunk@593 514c082c-b64e-11dc-b46d-3d985efe055d --- apt-inst/makefile | 2 +- apt-inst/makefile.orig | 32 + apt-pkg/cacheiterators.h | 47 + apt-pkg/cacheiterators.h.orig | 438 +++++ apt-pkg/deb/debindexfile.h | 3 +- apt-pkg/deb/deblistparser.cc | 53 + apt-pkg/deb/deblistparser.cc.orig | 671 +++++++ apt-pkg/deb/deblistparser.h | 1 + apt-pkg/deb/debrecords.cc | 49 +- apt-pkg/deb/debrecords.cc.orig | 214 +++ apt-pkg/deb/debrecords.h | 5 + apt-pkg/deb/debrecords.h.orig | 55 + apt-pkg/pkgcache.cc | 1 + apt-pkg/pkgcache.h | 16 + apt-pkg/pkgcache.h.orig | 357 ++++ apt-pkg/pkgcachegen.cc | 26 + apt-pkg/pkgcachegen.h | 1 + apt-pkg/pkgrecords.h | 4 + apt-pkg/tagfile.cc | 142 +- apt-pkg/tagfile.h | 4 +- cmdline/apt-cache.cc | 2 +- cmdline/apt-cdrom.cc | 2 +- cmdline/apt-config.cc | 2 +- cmdline/apt-extracttemplates.cc | 2 +- cmdline/apt-get.cc | 2 +- cmdline/apt-get.cc.orig | 2820 ----------------------------- cmdline/apt-sortpkgs.cc | 2 +- ftparchive/writer.cc | 2 +- methods/http.cc | 2 +- 29 files changed, 2020 insertions(+), 2937 deletions(-) create mode 100644 apt-inst/makefile.orig create mode 100644 apt-pkg/cacheiterators.h.orig create mode 100644 apt-pkg/deb/deblistparser.cc.orig create mode 100644 apt-pkg/deb/debrecords.cc.orig create mode 100644 apt-pkg/deb/debrecords.h.orig create mode 100644 apt-pkg/pkgcache.h.orig delete mode 100644 cmdline/apt-get.cc.orig diff --git a/apt-inst/makefile b/apt-inst/makefile index c4c96c5..449dad0 100644 --- a/apt-inst/makefile +++ b/apt-inst/makefile @@ -15,7 +15,7 @@ LIBEXT= #$(GLIBC_VER)$(LIBSTDCPP_VER) MAJOR=1.1 MINOR=0 -SLIBS=$(PTHREADLIB) -lapt-pkg +SLIBS=$(PTHREADLIB) -lapt-pkg $(INTLLIBS) APT_DOMAIN:=libapt-inst$(MAJOR) # Source code for the contributed non-core things diff --git a/apt-inst/makefile.orig b/apt-inst/makefile.orig new file mode 100644 index 0000000..8dcfe73 --- /dev/null +++ b/apt-inst/makefile.orig @@ -0,0 +1,32 @@ +# -*- make -*- +BASE=.. +SUBDIR=apt-inst + +# Header location +SUBDIRS = contrib deb +HEADER_TARGETDIRS = apt-pkg + +# Bring in the default rules +include ../buildlib/defaults.mak + +# The library name +LIBRARY=apt-inst +LIBEXT=$(GLIBC_VER)$(LIBSTDCPP_VER) +MAJOR=1.1 +MINOR=0 +SLIBS=$(PTHREADLIB) -lapt-pkg $(INTLLIBS) +APT_DOMAIN:=libapt-inst$(MAJOR) + +# Source code for the contributed non-core things +SOURCE = contrib/extracttar.cc contrib/arfile.cc + +# Source code for the main library +SOURCE+= filelist.cc database.cc dirstream.cc extract.cc \ + deb/dpkgdb.cc deb/debfile.cc + +# Public header files +HEADERS = extracttar.h arfile.h filelist.h database.h extract.h \ + dpkgdb.h dirstream.h debfile.h + +HEADERS := $(addprefix apt-pkg/,$(HEADERS)) +include $(LIBRARY_H) diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 08eafca..38b3505 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -71,6 +71,7 @@ class pkgCache::PkgIterator inline pkgCache *Cache() {return Owner;}; inline const char *Name() const {return Pkg->Name == 0?0:Owner->StrP + Pkg->Name;}; + inline const char *Display() const {return Pkg->Display == 0?0:Owner->StrP + Pkg->Display;}; inline const char *Section() const {return Pkg->Section == 0?0:Owner->StrP + Pkg->Section;}; inline bool Purge() const {return Pkg->CurrentState == pkgCache::State::Purge || (Pkg->CurrentVer == 0 && Pkg->CurrentState == pkgCache::State::NotInstalled);}; @@ -78,6 +79,7 @@ class pkgCache::PkgIterator inline VerIterator CurrentVer() const; inline DepIterator RevDependsList() const; inline PrvIterator ProvidesList() const; + inline TagIterator TagList() const; inline unsigned long Index() const {return Pkg - Owner->PkgP;}; OkState State() const; @@ -122,6 +124,7 @@ class pkgCache::VerIterator inline pkgCache *Cache() {return Owner;}; inline const char *VerStr() const {return Ver->VerStr == 0?0:Owner->StrP + Ver->VerStr;}; + inline const char *Display() const {return Ver->Display == 0?0:Owner->StrP + Ver->Display;}; inline const char *Section() const {return Ver->Section == 0?0:Owner->StrP + Ver->Section;}; inline const char *Arch() const {return Ver->Arch == 0?0:Owner->StrP + Ver->Arch;}; inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Ver->ParentPkg);}; @@ -147,6 +150,48 @@ class pkgCache::VerIterator }; }; +// Tag Iterator +class pkgCache::TagIterator +{ + Tag *Tg; + pkgCache *Owner; + + void _dummy(); + + public: + + // Iteration + void operator ++(int) {if (Tg != Owner->TagP) Tg = Owner->TagP + Tg->NextTag;}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Tg == Owner->TagP?true:false;}; + inline void operator =(const TagIterator &B) {Tg = B.Tg; Owner = B.Owner;}; + + // Comparison + inline bool operator ==(const TagIterator &B) const {return Tg == B.Tg;}; + inline bool operator !=(const TagIterator &B) const {return Tg != B.Tg;}; + int CompareTag(const TagIterator &B) const; + + // Accessors + inline Tag *operator ->() {return Tg;}; + inline Tag const *operator ->() const {return Tg;}; + inline Tag &operator *() {return *Tg;}; + inline Tag const &operator *() const {return *Tg;}; + inline operator Tag *() {return Tg == Owner->TagP?0:Tg;}; + inline operator Tag const *() const {return Tg == Owner->TagP?0:Tg;}; + inline pkgCache *Cache() {return Owner;}; + + inline const char *Name() const {return Owner->StrP + Tg->Name;}; + inline unsigned long Index() const {return Tg - Owner->TagP;}; + + inline TagIterator() : Tg(0), Owner(0) {}; + inline TagIterator(pkgCache &Owner,Tag *Trg = 0) : Tg(Trg), + Owner(&Owner) + { + if (Tg == 0) + Tg = Owner.TagP; + }; +}; + // Description Iterator class pkgCache::DescIterator { @@ -422,6 +467,8 @@ inline pkgCache::DepIterator pkgCache::PkgIterator::RevDependsList() const {return DepIterator(*Owner,Owner->DepP + Pkg->RevDepends,Pkg);}; inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const {return PrvIterator(*Owner,Owner->ProvideP + Pkg->ProvidesList,Pkg);}; +inline pkgCache::TagIterator pkgCache::PkgIterator::TagList() const + {return TagIterator(*Owner,Owner->TagP + Pkg->TagList);}; inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const {return DescIterator(*Owner,Owner->DescP + Ver->DescriptionList);}; inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const diff --git a/apt-pkg/cacheiterators.h.orig b/apt-pkg/cacheiterators.h.orig new file mode 100644 index 0000000..78abeca --- /dev/null +++ b/apt-pkg/cacheiterators.h.orig @@ -0,0 +1,438 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: cacheiterators.h,v 1.18.2.1 2004/05/08 22:44:27 mdz Exp $ +/* ###################################################################### + + Cache Iterators - Iterators for navigating the cache structure + + The iterators all provides ++,==,!=,->,* and end for their type. + The end function can be used to tell if the list has been fully + traversed. + + Unlike STL iterators these contain helper functions to access the data + that is being iterated over. This is because the data structures can't + be formed in a manner that is intuitive to use and also mmapable. + + For each variable in the target structure that would need a translation + to be accessed correctly a translating function of the same name is + present in the iterator. If applicable the translating function will + return an iterator. + + The DepIterator can iterate over two lists, a list of 'version depends' + or a list of 'package reverse depends'. The type is determined by the + structure passed to the constructor, which should be the structure + that has the depends pointer as a member. The provide iterator has the + same system. + + This header is not user includable, please use apt-pkg/pkgcache.h + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_CACHEITERATORS_H +#define PKGLIB_CACHEITERATORS_H + + +// Package Iterator +class pkgCache::PkgIterator +{ + friend class pkgCache; + Package *Pkg; + pkgCache *Owner; + long HashIndex; + + protected: + + // This constructor is the 'begin' constructor, never use it. + inline PkgIterator(pkgCache &Owner) : Owner(&Owner), HashIndex(-1) + { + Pkg = Owner.PkgP; + operator ++(0); + }; + + public: + + enum OkState {NeedsNothing,NeedsUnpack,NeedsConfigure}; + + // Iteration + void operator ++(int); + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Owner == 0 || Pkg == Owner->PkgP?true:false;}; + + // Comparison + inline bool operator ==(const PkgIterator &B) const {return Pkg == B.Pkg;}; + inline bool operator !=(const PkgIterator &B) const {return Pkg != B.Pkg;}; + + // Accessors + inline Package *operator ->() {return Pkg;}; + inline Package const *operator ->() const {return Pkg;}; + inline Package const &operator *() const {return *Pkg;}; + inline operator Package *() {return Pkg == Owner->PkgP?0:Pkg;}; + inline operator Package const *() const {return Pkg == Owner->PkgP?0:Pkg;}; + inline pkgCache *Cache() {return Owner;}; + + inline const char *Name() const {return Pkg->Name == 0?0:Owner->StrP + Pkg->Name;}; + inline const char *Display() const {return Pkg->Display == 0?0:Owner->StrP + Pkg->Display;}; + inline const char *Section() const {return Pkg->Section == 0?0:Owner->StrP + Pkg->Section;}; + inline bool Purge() const {return Pkg->CurrentState == pkgCache::State::Purge || + (Pkg->CurrentVer == 0 && Pkg->CurrentState == pkgCache::State::NotInstalled);}; + inline VerIterator VersionList() const; + inline VerIterator CurrentVer() const; + inline DepIterator RevDependsList() const; + inline PrvIterator ProvidesList() const; + inline unsigned long Index() const {return Pkg - Owner->PkgP;}; + OkState State() const; + + // Constructors + inline PkgIterator(pkgCache &Owner,Package *Trg) : Pkg(Trg), Owner(&Owner), + HashIndex(0) + { + if (Pkg == 0) + Pkg = Owner.PkgP; + }; + inline PkgIterator() : Pkg(0), Owner(0), HashIndex(0) {}; +}; + +// Version Iterator +class pkgCache::VerIterator +{ + Version *Ver; + pkgCache *Owner; + + void _dummy(); + + public: + + // Iteration + void operator ++(int) {if (Ver != Owner->VerP) Ver = Owner->VerP + Ver->NextVer;}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Owner == NULL || (Ver == Owner->VerP?true:false);}; + inline void operator =(const VerIterator &B) {Ver = B.Ver; Owner = B.Owner;}; + + // Comparison + inline bool operator ==(const VerIterator &B) const {return Ver == B.Ver;}; + inline bool operator !=(const VerIterator &B) const {return Ver != B.Ver;}; + int CompareVer(const VerIterator &B) const; + + // Accessors + inline Version *operator ->() {return Ver;}; + inline Version const *operator ->() const {return Ver;}; + inline Version &operator *() {return *Ver;}; + inline Version const &operator *() const {return *Ver;}; + inline operator Version *() {return Ver == Owner->VerP?0:Ver;}; + inline operator Version const *() const {return Ver == Owner->VerP?0:Ver;}; + inline pkgCache *Cache() {return Owner;}; + + inline const char *VerStr() const {return Ver->VerStr == 0?0:Owner->StrP + Ver->VerStr;}; + inline const char *Display() const {return Ver->Display == 0?0:Owner->StrP + Ver->Display;}; + inline const char *Section() const {return Ver->Section == 0?0:Owner->StrP + Ver->Section;}; + inline const char *Arch() const {return Ver->Arch == 0?0:Owner->StrP + Ver->Arch;}; + inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Ver->ParentPkg);}; + inline DescIterator DescriptionList() const; + DescIterator TranslatedDescription() const; + inline DepIterator DependsList() const; + inline PrvIterator ProvidesList() const; + inline VerFileIterator FileList() const; + inline unsigned long Index() const {return Ver - Owner->VerP;}; + bool Downloadable() const; + inline const char *PriorityType() {return Owner->Priority(Ver->Priority);}; + string RelStr(); + + bool Automatic() const; + VerFileIterator NewestFile() const; + + inline VerIterator() : Ver(0), Owner(0) {}; + inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Ver(Trg), + Owner(&Owner) + { + if (Ver == 0) + Ver = Owner.VerP; + }; +}; + +// Description Iterator +class pkgCache::DescIterator +{ + Description *Desc; + pkgCache *Owner; + + void _dummy(); + + public: + + // Iteration + void operator ++(int) {if (Desc != Owner->DescP) Desc = Owner->DescP + Desc->NextDesc;}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Desc == Owner->DescP?true:false;}; + inline void operator =(const DescIterator &B) {Desc = B.Desc; Owner = B.Owner;}; + + // Comparison + inline bool operator ==(const DescIterator &B) const {return Desc == B.Desc;}; + inline bool operator !=(const DescIterator &B) const {return Desc != B.Desc;}; + int CompareDesc(const DescIterator &B) const; + + // Accessors + inline Description *operator ->() {return Desc;}; + inline Description const *operator ->() const {return Desc;}; + inline Description &operator *() {return *Desc;}; + inline Description const &operator *() const {return *Desc;}; + inline operator Description *() {return Desc == Owner->DescP?0:Desc;}; + inline operator Description const *() const {return Desc == Owner->DescP?0:Desc;}; + inline pkgCache *Cache() {return Owner;}; + + inline const char *LanguageCode() const {return Owner->StrP + Desc->language_code;}; + inline const char *md5() const {return Owner->StrP + Desc->md5sum;}; + inline DescFileIterator FileList() const; + inline unsigned long Index() const {return Desc - Owner->DescP;}; + + inline DescIterator() : Desc(0), Owner(0) {}; + inline DescIterator(pkgCache &Owner,Description *Trg = 0) : Desc(Trg), + Owner(&Owner) + { + if (Desc == 0) + Desc = Owner.DescP; + }; +}; + +// Dependency iterator +class pkgCache::DepIterator +{ + Dependency *Dep; + enum {DepVer, DepRev} Type; + pkgCache *Owner; + + void _dummy(); + + public: + + // Iteration + void operator ++(int) {if (Dep != Owner->DepP) Dep = Owner->DepP + + (Type == DepVer?Dep->NextDepends:Dep->NextRevDepends);}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Owner == 0 || Dep == Owner->DepP?true:false;}; + + // Comparison + inline bool operator ==(const DepIterator &B) const {return Dep == B.Dep;}; + inline bool operator !=(const DepIterator &B) const {return Dep != B.Dep;}; + + // Accessors + inline Dependency *operator ->() {return Dep;}; + inline Dependency const *operator ->() const {return Dep;}; + inline Dependency &operator *() {return *Dep;}; + inline Dependency const &operator *() const {return *Dep;}; + inline operator Dependency *() {return Dep == Owner->DepP?0:Dep;}; + inline operator Dependency const *() const {return Dep == Owner->DepP?0:Dep;}; + inline pkgCache *Cache() {return Owner;}; + + inline const char *TargetVer() const {return Dep->Version == 0?0:Owner->StrP + Dep->Version;}; + inline PkgIterator TargetPkg() {return PkgIterator(*Owner,Owner->PkgP + Dep->Package);}; + inline PkgIterator SmartTargetPkg() {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;}; + inline VerIterator ParentVer() {return VerIterator(*Owner,Owner->VerP + Dep->ParentVer);}; + inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Dep->ParentVer].ParentPkg);}; + inline bool Reverse() {return Type == DepRev;}; + inline unsigned long Index() const {return Dep - Owner->DepP;}; + bool IsCritical(); + void GlobOr(DepIterator &Start,DepIterator &End); + Version **AllTargets(); + bool SmartTargetPkg(PkgIterator &Result); + inline const char *CompType() {return Owner->CompType(Dep->CompareOp);}; + inline const char *DepType() {return Owner->DepType(Dep->Type);}; + + inline DepIterator(pkgCache &Owner,Dependency *Trg,Version * = 0) : + Dep(Trg), Type(DepVer), Owner(&Owner) + { + if (Dep == 0) + Dep = Owner.DepP; + }; + inline DepIterator(pkgCache &Owner,Dependency *Trg,Package *) : + Dep(Trg), Type(DepRev), Owner(&Owner) + { + if (Dep == 0) + Dep = Owner.DepP; + }; + inline DepIterator() : Dep(0), Type(DepVer), Owner(0) {}; +}; + +// Provides iterator +class pkgCache::PrvIterator +{ + Provides *Prv; + enum {PrvVer, PrvPkg} Type; + pkgCache *Owner; + + void _dummy(); + + public: + + // Iteration + void operator ++(int) {if (Prv != Owner->ProvideP) Prv = Owner->ProvideP + + (Type == PrvVer?Prv->NextPkgProv:Prv->NextProvides);}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Owner == 0 || Prv == Owner->ProvideP?true:false;}; + + // Comparison + inline bool operator ==(const PrvIterator &B) const {return Prv == B.Prv;}; + inline bool operator !=(const PrvIterator &B) const {return Prv != B.Prv;}; + + // Accessors + inline Provides *operator ->() {return Prv;}; + inline Provides const *operator ->() const {return Prv;}; + inline Provides &operator *() {return *Prv;}; + inline Provides const &operator *() const {return *Prv;}; + inline operator Provides *() {return Prv == Owner->ProvideP?0:Prv;}; + inline operator Provides const *() const {return Prv == Owner->ProvideP?0:Prv;}; + inline pkgCache *Cache() {return Owner;}; + + inline const char *Name() const {return Owner->StrP + Owner->PkgP[Prv->ParentPkg].Name;}; + inline const char *ProvideVersion() const {return Prv->ProvideVersion == 0?0:Owner->StrP + Prv->ProvideVersion;}; + inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Prv->ParentPkg);}; + inline VerIterator OwnerVer() {return VerIterator(*Owner,Owner->VerP + Prv->Version);}; + inline PkgIterator OwnerPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Prv->Version].ParentPkg);}; + inline unsigned long Index() const {return Prv - Owner->ProvideP;}; + + inline PrvIterator() : Prv(0), Type(PrvVer), Owner(0) {}; + + inline PrvIterator(pkgCache &Owner,Provides *Trg,Version *) : + Prv(Trg), Type(PrvVer), Owner(&Owner) + { + if (Prv == 0) + Prv = Owner.ProvideP; + }; + inline PrvIterator(pkgCache &Owner,Provides *Trg,Package *) : + Prv(Trg), Type(PrvPkg), Owner(&Owner) + { + if (Prv == 0) + Prv = Owner.ProvideP; + }; +}; + +// Package file +class pkgCache::PkgFileIterator +{ + pkgCache *Owner; + PackageFile *File; + + public: + + // Iteration + void operator ++(int) {if (File!= Owner->PkgFileP) File = Owner->PkgFileP + File->NextFile;}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return File == Owner->PkgFileP?true:false;}; + + // Comparison + inline bool operator ==(const PkgFileIterator &B) const {return File == B.File;}; + inline bool operator !=(const PkgFileIterator &B) const {return File != B.File;}; + + // Accessors + inline PackageFile *operator ->() {return File;}; + inline PackageFile const *operator ->() const {return File;}; + inline PackageFile const &operator *() const {return *File;}; + inline operator PackageFile *() {return File == Owner->PkgFileP?0:File;}; + inline operator PackageFile const *() const {return File == Owner->PkgFileP?0:File;}; + inline pkgCache *Cache() {return Owner;}; + + inline const char *FileName() const {return File->FileName == 0?0:Owner->StrP + File->FileName;}; + inline const char *Archive() const {return File->Archive == 0?0:Owner->StrP + File->Archive;}; + inline const char *Component() const {return File->Component == 0?0:Owner->StrP + File->Component;}; + inline const char *Version() const {return File->Version == 0?0:Owner->StrP + File->Version;}; + inline const char *Origin() const {return File->Origin == 0?0:Owner->StrP + File->Origin;}; + inline const char *Label() const {return File->Label == 0?0:Owner->StrP + File->Label;}; + inline const char *Site() const {return File->Site == 0?0:Owner->StrP + File->Site;}; + inline const char *Architecture() const {return File->Architecture == 0?0:Owner->StrP + File->Architecture;}; + inline const char *IndexType() const {return File->IndexType == 0?0:Owner->StrP + File->IndexType;}; + + inline unsigned long Index() const {return File - Owner->PkgFileP;}; + + bool IsOk(); + string RelStr(); + + // Constructors + inline PkgFileIterator() : Owner(0), File(0) {}; + inline PkgFileIterator(pkgCache &Owner) : Owner(&Owner), File(Owner.PkgFileP) {}; + inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Owner(&Owner), File(Trg) {}; +}; + +// Version File +class pkgCache::VerFileIterator +{ + pkgCache *Owner; + VerFile *FileP; + + public: + + // Iteration + void operator ++(int) {if (FileP != Owner->VerFileP) FileP = Owner->VerFileP + FileP->NextFile;}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return FileP == Owner->VerFileP?true:false;}; + + // Comparison + inline bool operator ==(const VerFileIterator &B) const {return FileP == B.FileP;}; + inline bool operator !=(const VerFileIterator &B) const {return FileP != B.FileP;}; + + // Accessors + inline VerFile *operator ->() {return FileP;}; + inline VerFile const *operator ->() const {return FileP;}; + inline VerFile const &operator *() const {return *FileP;}; + inline operator VerFile *() {return FileP == Owner->VerFileP?0:FileP;}; + inline operator VerFile const *() const {return FileP == Owner->VerFileP?0:FileP;}; + inline pkgCache *Cache() {return Owner;}; + + inline PkgFileIterator File() const {return PkgFileIterator(*Owner,FileP->File + Owner->PkgFileP);}; + inline unsigned long Index() const {return FileP - Owner->VerFileP;}; + + inline VerFileIterator() : Owner(0), FileP(0) {}; + inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Owner(&Owner), FileP(Trg) {}; +}; + +// Description File +class pkgCache::DescFileIterator +{ + pkgCache *Owner; + DescFile *FileP; + + public: + + // Iteration + void operator ++(int) {if (FileP != Owner->DescFileP) FileP = Owner->DescFileP + FileP->NextFile;}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return FileP == Owner->DescFileP?true:false;}; + + // Comparison + inline bool operator ==(const DescFileIterator &B) const {return FileP == B.FileP;}; + inline bool operator !=(const DescFileIterator &B) const {return FileP != B.FileP;}; + + // Accessors + inline DescFile *operator ->() {return FileP;}; + inline DescFile const *operator ->() const {return FileP;}; + inline DescFile const &operator *() const {return *FileP;}; + inline operator DescFile *() {return FileP == Owner->DescFileP?0:FileP;}; + inline operator DescFile const *() const {return FileP == Owner->DescFileP?0:FileP;}; + inline pkgCache *Cache() {return Owner;}; + + inline PkgFileIterator File() const {return PkgFileIterator(*Owner,FileP->File + Owner->PkgFileP);}; + inline unsigned long Index() const {return FileP - Owner->DescFileP;}; + + inline DescFileIterator() : Owner(0), FileP(0) {}; + inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Owner(&Owner), FileP(Trg) {}; +}; + +// Inlined Begin functions cant be in the class because of order problems +inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const + {return VerIterator(*Owner,Owner->VerP + Pkg->VersionList);}; +inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const + {return VerIterator(*Owner,Owner->VerP + Pkg->CurrentVer);}; +inline pkgCache::DepIterator pkgCache::PkgIterator::RevDependsList() const + {return DepIterator(*Owner,Owner->DepP + Pkg->RevDepends,Pkg);}; +inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const + {return PrvIterator(*Owner,Owner->ProvideP + Pkg->ProvidesList,Pkg);}; +inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const + {return DescIterator(*Owner,Owner->DescP + Ver->DescriptionList);}; +inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const + {return PrvIterator(*Owner,Owner->ProvideP + Ver->ProvidesList,Ver);}; +inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const + {return DepIterator(*Owner,Owner->DepP + Ver->DependsList,Ver);}; +inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const + {return VerFileIterator(*Owner,Owner->VerFileP + Ver->FileList);}; +inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const + {return DescFileIterator(*Owner,Owner->DescFileP + Desc->FileList);}; + +#endif diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h index b0012c9..487caa2 100644 --- a/apt-pkg/deb/debindexfile.h +++ b/apt-pkg/deb/debindexfile.h @@ -49,9 +49,10 @@ class debPackagesIndex : public pkgIndexFile string Info(const char *Type) const; string IndexFile(const char *Type) const; - string IndexURI(const char *Type) const; public: + + string IndexURI(const char *Type) const; virtual const Type *GetType() const; diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 896d4d6..5b0da50 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -75,6 +75,10 @@ string debListParser::Version() /* */ bool debListParser::NewVersion(pkgCache::VerIterator Ver) { + Ver->Display = UniqFindTagWrite("Name"); + if (Ver->Display == 0) + Ver->Display = UniqFindTagWrite("Maemo-Display-Name"); + // Parse the section Ver->Section = UniqFindTagWrite("Section"); Ver->Arch = UniqFindTagWrite("Architecture"); @@ -169,6 +173,10 @@ MD5SumValue debListParser::Description_md5() bool debListParser::UsePackage(pkgCache::PkgIterator Pkg, pkgCache::VerIterator Ver) { + if (Pkg->Display == 0) + Pkg->Display = UniqFindTagWrite("Name"); + if (Pkg->Display == 0) + Pkg->Display = UniqFindTagWrite("Maemo-Display-Name"); if (Pkg->Section == 0) Pkg->Section = UniqFindTagWrite("Section"); if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false) @@ -181,6 +189,11 @@ bool debListParser::UsePackage(pkgCache::PkgIterator Pkg, if (ParseStatus(Pkg,Ver) == false) return false; + + if (Pkg->TagList == 0) + if (ParseTag(Pkg) == false) + return false; + return true; } /*}}}*/ @@ -563,6 +576,46 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver) break; } + return true; +} + /*}}}*/ +// ListParser::ParseTag - Parse the tag list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debListParser::ParseTag(pkgCache::PkgIterator Pkg) +{ + const char *Start; + const char *Stop; + if (Section.Find("Tag",Start,Stop) == false) + return true; + + while (1) { + while (1) { + if (Start == Stop) + return true; + if (Stop[-1] != ' ' && Stop[-1] != '\t') + break; + --Stop; + } + + const char *Begin = Stop - 1; + while (Begin != Start && Begin[-1] != ' ' && Begin[-1] != ',') + --Begin; + + if (NewTag(Pkg, Begin, Stop - Begin) == false) + return false; + + while (1) { + if (Begin == Start) + return true; + if (Begin[-1] == ',') + break; + --Begin; + } + + Stop = Begin - 1; + } + return true; } /*}}}*/ diff --git a/apt-pkg/deb/deblistparser.cc.orig b/apt-pkg/deb/deblistparser.cc.orig new file mode 100644 index 0000000..cd909cd --- /dev/null +++ b/apt-pkg/deb/deblistparser.cc.orig @@ -0,0 +1,671 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: deblistparser.cc,v 1.29.2.5 2004/01/06 01:43:44 mdz Exp $ +/* ###################################################################### + + Package Cache Generator - Generator for the cache structure. + + This builds the cache structure from the abstract package list parser. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include +#include +#include + +#include + +#include + /*}}}*/ + +static debListParser::WordList PrioList[] = {{"important",pkgCache::State::Important}, + {"required",pkgCache::State::Required}, + {"standard",pkgCache::State::Standard}, + {"optional",pkgCache::State::Optional}, + {"extra",pkgCache::State::Extra}, + {}}; + +// ListParser::debListParser - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +debListParser::debListParser(FileFd *File) : Tags(File) +{ + Arch = _config->Find("APT::architecture"); +} + /*}}}*/ +// ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned long debListParser::UniqFindTagWrite(const char *Tag) +{ + const char *Start; + const char *Stop; + if (Section.Find(Tag,Start,Stop) == false) + return 0; + return WriteUniqString(Start,Stop - Start); +} + /*}}}*/ +// ListParser::Package - Return the package name /*{{{*/ +// --------------------------------------------------------------------- +/* This is to return the name of the package this section describes */ +string debListParser::Package() +{ + string Result = Section.FindS("Package"); + if (Result.empty() == true) + _error->Error("Encountered a section with no Package: header"); + return Result; +} + /*}}}*/ +// ListParser::Version - Return the version string /*{{{*/ +// --------------------------------------------------------------------- +/* This is to return the string describing the version in debian form, + epoch:upstream-release. If this returns the blank string then the + entry is assumed to only describe package properties */ +string debListParser::Version() +{ + return Section.FindS("Version"); +} + /*}}}*/ +// ListParser::NewVersion - Fill in the version structure /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debListParser::NewVersion(pkgCache::VerIterator Ver) +{ + Ver->Display = UniqFindTagWrite("Name"); + if (Ver->Display == 0) + Ver->Display = UniqFindTagWrite("Maemo-Display-Name"); + + // Parse the section + Ver->Section = UniqFindTagWrite("Section"); + Ver->Arch = UniqFindTagWrite("Architecture"); + + // Archive Size + Ver->Size = (unsigned)Section.FindI("Size"); + + // Unpacked Size (in K) + Ver->InstalledSize = (unsigned)Section.FindI("Installed-Size"); + Ver->InstalledSize *= 1024; + + // Priority + const char *Start; + const char *Stop; + if (Section.Find("Priority",Start,Stop) == true) + { + if (GrabWord(string(Start,Stop-Start),PrioList,Ver->Priority) == false) + Ver->Priority = pkgCache::State::Extra; + } + + if (ParseDepends(Ver,"Depends",pkgCache::Dep::Depends) == false) + return false; + if (ParseDepends(Ver,"Pre-Depends",pkgCache::Dep::PreDepends) == false) + return false; + if (ParseDepends(Ver,"Suggests",pkgCache::Dep::Suggests) == false) + return false; + if (ParseDepends(Ver,"Recommends",pkgCache::Dep::Recommends) == false) + return false; + if (ParseDepends(Ver,"Conflicts",pkgCache::Dep::Conflicts) == false) + return false; + if (ParseDepends(Ver,"Breaks",pkgCache::Dep::DpkgBreaks) == false) + return false; + if (ParseDepends(Ver,"Replaces",pkgCache::Dep::Replaces) == false) + return false; + + // Obsolete. + if (ParseDepends(Ver,"Optional",pkgCache::Dep::Suggests) == false) + return false; + + if (ParseProvides(Ver) == false) + return false; + + return true; +} + /*}}}*/ +// ListParser::Description - Return the description string /*{{{*/ +// --------------------------------------------------------------------- +/* This is to return the string describing the package in debian + form. If this returns the blank string then the entry is assumed to + only describe package properties */ +string debListParser::Description() +{ + if (DescriptionLanguage().empty()) + return Section.FindS("Description"); + else + return Section.FindS(("Description-" + pkgIndexFile::LanguageCode()).c_str()); +} + /*}}}*/ +// ListParser::DescriptionLanguage - Return the description lang string /*{{{*/ +// --------------------------------------------------------------------- +/* This is to return the string describing the language of + description. If this returns the blank string then the entry is + assumed to describe original description. */ +string debListParser::DescriptionLanguage() +{ + return Section.FindS("Description").empty() ? pkgIndexFile::LanguageCode() : ""; +} + /*}}}*/ +// ListParser::Description - Return the description_md5 MD5SumValue /*{{{*/ +// --------------------------------------------------------------------- +/* This is to return the md5 string to allow the check if it is the right + description. If no Description-md5 is found in the section it will be + calculated. + */ +MD5SumValue debListParser::Description_md5() +{ + string value = Section.FindS("Description-md5"); + + if (value.empty()) + { + MD5Summation md5; + md5.Add((Description() + "\n").c_str()); + return md5.Result(); + } else + return MD5SumValue(value); +} + /*}}}*/ +// ListParser::UsePackage - Update a package structure /*{{{*/ +// --------------------------------------------------------------------- +/* This is called to update the package with any new information + that might be found in the section */ +bool debListParser::UsePackage(pkgCache::PkgIterator Pkg, + pkgCache::VerIterator Ver) +{ + if (Pkg->Display == 0) + Pkg->Display = UniqFindTagWrite("Name"); + if (Pkg->Display == 0) + Pkg->Display = UniqFindTagWrite("Maemo-Display-Name"); + if (Pkg->Section == 0) + Pkg->Section = UniqFindTagWrite("Section"); + if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false) + return false; + if (Section.FindFlag("Important",Pkg->Flags,pkgCache::Flag::Important) == false) + return false; + + if (strcmp(Pkg.Name(),"apt") == 0) + Pkg->Flags |= pkgCache::Flag::Important; + + if (ParseStatus(Pkg,Ver) == false) + return false; + return true; +} + /*}}}*/ +// ListParser::VersionHash - Compute a unique hash for this version /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned short debListParser::VersionHash() +{ + const char *Sections[] ={"Installed-Size", + "Depends", + "Pre-Depends", +// "Suggests", +// "Recommends", + "Conflicts", + "Breaks", + "Replaces",0}; + unsigned long Result = INIT_FCS; + char S[1024]; + for (const char **I = Sections; *I != 0; I++) + { + const char *Start; + const char *End; + if (Section.Find(*I,Start,End) == false || End - Start >= (signed)sizeof(S)) + continue; + + /* 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; + for (; Start != End; Start++) + { + if (isspace(*Start) == 0) + *I++ = tolower(*Start); + if (*Start == '<' && Start[1] != '<' && Start[1] != '=') + *I++ = '='; + if (*Start == '>' && Start[1] != '>' && Start[1] != '=') + *I++ = '='; + } + + Result = AddCRC16(Result,S,I - S); + } + + return Result; +} + /*}}}*/ +// ListParser::ParseStatus - Parse the status field /*{{{*/ +// --------------------------------------------------------------------- +/* Status lines are of the form, + Status: want flag status + want = unknown, install, hold, deinstall, purge + flag = ok, reinstreq, hold, hold-reinstreq + status = not-installed, unpacked, half-configured, + half-installed, config-files, post-inst-failed, + removal-failed, installed + + Some of the above are obsolete (I think?) flag = hold-* and + status = post-inst-failed, removal-failed at least. + */ +bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg, + pkgCache::VerIterator Ver) +{ + const char *Start; + const char *Stop; + if (Section.Find("Status",Start,Stop) == false) + return true; + + // Isolate the first word + const char *I = Start; + for(; I < Stop && *I != ' '; I++); + if (I >= Stop || *I != ' ') + return _error->Error("Malformed Status line"); + + // Process the want field + WordList WantList[] = {{"unknown",pkgCache::State::Unknown}, + {"install",pkgCache::State::Install}, + {"hold",pkgCache::State::Hold}, + {"deinstall",pkgCache::State::DeInstall}, + {"purge",pkgCache::State::Purge}, + {}}; + if (GrabWord(string(Start,I-Start),WantList,Pkg->SelectedState) == false) + return _error->Error("Malformed 1st word in the Status line"); + + // Isloate the next word + I++; + Start = I; + for(; I < Stop && *I != ' '; I++); + if (I >= Stop || *I != ' ') + return _error->Error("Malformed status line, no 2nd word"); + + // Process the flag field + WordList FlagList[] = {{"ok",pkgCache::State::Ok}, + {"reinstreq",pkgCache::State::ReInstReq}, + {"hold",pkgCache::State::HoldInst}, + {"hold-reinstreq",pkgCache::State::HoldReInstReq}, + {}}; + if (GrabWord(string(Start,I-Start),FlagList,Pkg->InstState) == false) + return _error->Error("Malformed 2nd word in the Status line"); + + // Isloate the last word + I++; + Start = I; + for(; I < Stop && *I != ' '; I++); + if (I != Stop) + return _error->Error("Malformed Status line, no 3rd word"); + + // Process the flag field + WordList StatusList[] = {{"not-installed",pkgCache::State::NotInstalled}, + {"unpacked",pkgCache::State::UnPacked}, + {"half-configured",pkgCache::State::HalfConfigured}, + {"installed",pkgCache::State::Installed}, + {"half-installed",pkgCache::State::HalfInstalled}, + {"config-files",pkgCache::State::ConfigFiles}, + {"triggers-awaited",pkgCache::State::TriggersAwaited}, + {"triggers-pending",pkgCache::State::TriggersPending}, + {"post-inst-failed",pkgCache::State::HalfConfigured}, + {"removal-failed",pkgCache::State::HalfInstalled}, + {}}; + if (GrabWord(string(Start,I-Start),StatusList,Pkg->CurrentState) == false) + return _error->Error("Malformed 3rd word in the Status line"); + + /* A Status line marks the package as indicating the current + version as well. Only if it is actually installed.. Otherwise + the interesting dpkg handling of the status file creates bogus + entries. */ + if (!(Pkg->CurrentState == pkgCache::State::NotInstalled || + Pkg->CurrentState == pkgCache::State::ConfigFiles)) + { + if (Ver.end() == true) + _error->Warning("Encountered status field in a non-version description"); + else + Pkg->CurrentVer = Ver.Index(); + } + + return true; +} + +const char *debListParser::ConvertRelation(const char *I,unsigned int &Op) +{ + // Determine the operator + switch (*I) + { + case '<': + I++; + if (*I == '=') + { + I++; + Op = pkgCache::Dep::LessEq; + break; + } + + if (*I == '<') + { + I++; + Op = pkgCache::Dep::Less; + break; + } + + // < is the same as <= and << is really Cs < for some reason + Op = pkgCache::Dep::LessEq; + break; + + case '>': + I++; + if (*I == '=') + { + I++; + Op = pkgCache::Dep::GreaterEq; + break; + } + + if (*I == '>') + { + I++; + Op = pkgCache::Dep::Greater; + break; + } + + // > is the same as >= and >> is really Cs > for some reason + Op = pkgCache::Dep::GreaterEq; + break; + + case '=': + Op = pkgCache::Dep::Equals; + I++; + break; + + // HACK around bad package definitions + default: + Op = pkgCache::Dep::Equals; + break; + } + return I; +} + + /*}}}*/ +// ListParser::ParseDepends - Parse a dependency element /*{{{*/ +// --------------------------------------------------------------------- +/* This parses the dependency elements out of a standard string in place, + bit by bit. */ +const char *debListParser::ParseDepends(const char *Start,const char *Stop, + string &Package,string &Ver, + unsigned int &Op, bool ParseArchFlags) +{ + // Strip off leading space + for (;Start != Stop && isspace(*Start) != 0; Start++); + + // Parse off the package name + const char *I = Start; + for (;I != Stop && isspace(*I) == 0 && *I != '(' && *I != ')' && + *I != ',' && *I != '|'; I++); + + // Malformed, no '(' + if (I != Stop && *I == ')') + return 0; + + if (I == Start) + return 0; + + // Stash the package name + Package.assign(Start,I - Start); + + // Skip white space to the '(' + for (;I != Stop && isspace(*I) != 0 ; I++); + + // Parse a version + if (I != Stop && *I == '(') + { + // Skip the '(' + for (I++; I != Stop && isspace(*I) != 0 ; I++); + if (I + 3 >= Stop) + return 0; + I = ConvertRelation(I,Op); + + // Skip whitespace + for (;I != Stop && isspace(*I) != 0; I++); + Start = I; + for (;I != Stop && *I != ')'; I++); + if (I == Stop || Start == I) + return 0; + + // Skip trailing whitespace + const char *End = I; + for (; End > Start && isspace(End[-1]); End--); + + Ver.assign(Start,End-Start); + I++; + } + else + { + Ver.clear(); + Op = pkgCache::Dep::NoOp; + } + + // Skip whitespace + for (;I != Stop && isspace(*I) != 0; I++); + + if (ParseArchFlags == true) + { + string arch = _config->Find("APT::Architecture"); + + // Parse an architecture + if (I != Stop && *I == '[') + { + // malformed + I++; + if (I == Stop) + return 0; + + const char *End = I; + bool Found = false; + bool NegArch = false; + while (I != Stop) + { + // look for whitespace or ending ']' + while (End != Stop && !isspace(*End) && *End != ']') + End++; + + if (End == Stop) + return 0; + + if (*I == '!') + { + NegArch = true; + I++; + } + + if (stringcmp(arch,I,End) == 0) + Found = true; + + if (*End++ == ']') { + I = End; + break; + } + + I = End; + for (;I != Stop && isspace(*I) != 0; I++); + } + + if (NegArch) + Found = !Found; + + if (Found == false) + Package = ""; /* not for this arch */ + } + + // Skip whitespace + for (;I != Stop && isspace(*I) != 0; I++); + } + + if (I != Stop && *I == '|') + Op |= pkgCache::Dep::Or; + + if (I == Stop || *I == ',' || *I == '|') + { + if (I != Stop) + for (I++; I != Stop && isspace(*I) != 0; I++); + return I; + } + + return 0; +} + /*}}}*/ +// ListParser::ParseDepends - Parse a dependency list /*{{{*/ +// --------------------------------------------------------------------- +/* This is the higher level depends parser. It takes a tag and generates + a complete depends tree for the given version. */ +bool debListParser::ParseDepends(pkgCache::VerIterator Ver, + const char *Tag,unsigned int Type) +{ + const char *Start; + const char *Stop; + if (Section.Find(Tag,Start,Stop) == false) + return true; + + string Package; + string Version; + unsigned int Op; + + while (1) + { + Start = ParseDepends(Start,Stop,Package,Version,Op); + if (Start == 0) + return _error->Error("Problem parsing dependency %s",Tag); + + if (NewDepends(Ver,Package,Version,Op,Type) == false) + return false; + if (Start == Stop) + break; + } + return true; +} + /*}}}*/ +// ListParser::ParseProvides - Parse the provides list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debListParser::ParseProvides(pkgCache::VerIterator Ver) +{ + const char *Start; + const char *Stop; + if (Section.Find("Provides",Start,Stop) == false) + return true; + + string Package; + string Version; + unsigned int Op; + + while (1) + { + Start = ParseDepends(Start,Stop,Package,Version,Op); + if (Start == 0) + return _error->Error("Problem parsing Provides line"); + if (Op != pkgCache::Dep::NoOp) { + _error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str()); + } else { + if (NewProvides(Ver,Package,Version) == false) + return false; + } + + if (Start == Stop) + break; + } + + return true; +} + /*}}}*/ +// ListParser::GrabWord - Matches a word and returns /*{{{*/ +// --------------------------------------------------------------------- +/* Looks for a word in a list of words - for ParseStatus */ +bool debListParser::GrabWord(string Word,WordList *List,unsigned char &Out) +{ + for (unsigned int C = 0; List[C].Str != 0; C++) + { + if (strcasecmp(Word.c_str(),List[C].Str) == 0) + { + Out = List[C].Val; + return true; + } + } + return false; +} + /*}}}*/ +// ListParser::Step - Move to the next section in the file /*{{{*/ +// --------------------------------------------------------------------- +/* This has to be carefull to only process the correct architecture */ +bool debListParser::Step() +{ + iOffset = Tags.Offset(); + while (Tags.Step(Section) == true) + { + /* See if this is the correct Architecture, if it isn't then we + drop the whole section. A missing arch tag only happens (in theory) + inside the Status file, so that is a positive return */ + const char *Start; + const char *Stop; + if (Section.Find("Architecture",Start,Stop) == false) + return true; + + if (stringcmp(Arch,Start,Stop) == 0) + return true; + + if (stringcmp(Start,Stop,"all") == 0) + return true; + + iOffset = Tags.Offset(); + } + return false; +} + /*}}}*/ +// ListParser::LoadReleaseInfo - Load the release information /*{{{*/ +// --------------------------------------------------------------------- +/* */ +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; + + //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("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"); + + return !_error->PendingError(); +} + /*}}}*/ +// ListParser::GetPrio - Convert the priority from a string /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned char debListParser::GetPrio(string Str) +{ + unsigned char Out; + if (GrabWord(Str,PrioList,Out) == false) + Out = pkgCache::State::Extra; + + return Out; +} + /*}}}*/ diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 34bb29c..a7b7373 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -38,6 +38,7 @@ class debListParser : public pkgCacheGenerator::ListParser bool ParseDepends(pkgCache::VerIterator Ver,const char *Tag, unsigned int Type); bool ParseProvides(pkgCache::VerIterator Ver); + bool ParseTag(pkgCache::PkgIterator Pkg); static bool GrabWord(string Word,WordList *List,unsigned char &Out); public: diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc index 8ed0bb7..819e49f 100644 --- a/apt-pkg/deb/debrecords.cc +++ b/apt-pkg/deb/debrecords.cc @@ -51,6 +51,17 @@ string debRecordParser::Name() return Section.FindS("Package"); } /*}}}*/ +// RecordParser::Display - Return the package display name /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::Display() +{ + string display(Section.FindS("Name")); + if (display.empty()) + display = Section.FindS("Maemo-Display-Name"); + return display; +} + /*}}}*/ // RecordParser::Homepage - Return the package homepage /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -111,10 +122,9 @@ string debRecordParser::LongDesc() string orig, dest; char *codeset = nl_langinfo(CODESET); - if (!Section.FindS("Description").empty()) - orig = Section.FindS("Description").c_str(); - else - orig = Section.FindS(("Description-" + pkgIndexFile::LanguageCode()).c_str()).c_str(); + orig = Section.FindS("Description"); + if (orig.empty()) + orig = Section.FindS(("Description-" + pkgIndexFile::LanguageCode()).c_str()); if (strcmp(codeset,"UTF-8") != 0) { UTF8ToCodeset(codeset, orig, &dest); @@ -124,6 +134,29 @@ string debRecordParser::LongDesc() return orig; } /*}}}*/ +// RecordParser::ShortDesc - Return a 1 line description /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debRecordParser::ShortDesc(const char *&Start,const char *&End) +{ + if (!LongDesc(Start,End)) + return false; + const char *Line = (const char *) memchr(Start, '\n', End - Start); + if (Line != NULL) + End = Line; + return true; +} + /*}}}*/ +// RecordParser::LongDesc - Return a longer description /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debRecordParser::LongDesc(const char *&Start,const char *&End) +{ + if (!Section.Find("Description",Start,End)) + return Section.Find(("Description-" + pkgIndexFile::LanguageCode()).c_str(),Start,End); + return true; +} + /*}}}*/ static const char *SourceVerSeparators = " ()"; @@ -170,3 +203,11 @@ void debRecordParser::GetRec(const char *&Start,const char *&Stop) Section.GetSection(Start,Stop); } /*}}}*/ +// RecordParser::Find - Locate a tag /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debRecordParser::Find(const char *Tag,const char *&Start, const char *&End) +{ + return Section.Find(Tag,Start,End); +} + /*}}}*/ diff --git a/apt-pkg/deb/debrecords.cc.orig b/apt-pkg/deb/debrecords.cc.orig new file mode 100644 index 0000000..ac3897b --- /dev/null +++ b/apt-pkg/deb/debrecords.cc.orig @@ -0,0 +1,214 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: debrecords.cc,v 1.10 2001/03/13 06:51:46 jgg Exp $ +/* ###################################################################### + + Debian Package Records - Parser for debian package records + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include + /*}}}*/ + +// RecordParser::debRecordParser - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +debRecordParser::debRecordParser(string FileName,pkgCache &Cache) : + File(FileName,FileFd::ReadOnly), + Tags(&File,Cache.Head().MaxVerFileSize + 200) +{ +} + /*}}}*/ +// RecordParser::Jump - Jump to a specific record /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debRecordParser::Jump(pkgCache::VerFileIterator const &Ver) +{ + return Tags.Jump(Section,Ver->Offset); +} +bool debRecordParser::Jump(pkgCache::DescFileIterator const &Desc) +{ + return Tags.Jump(Section,Desc->Offset); +} + /*}}}*/ +// RecordParser::FileName - Return the archive filename on the site /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::FileName() +{ + return Section.FindS("Filename"); +} + /*}}}*/ +// RecordParser::Name - Return the package name /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::Name() +{ + return Section.FindS("Package"); +} + /*}}}*/ +// RecordParser::Display - Return the package display name /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::Display() +{ + string display(Section.FindS("Name")); + if (display.empty()) + display = Section.FindS("Maemo-Display-Name"); + return display; +} + /*}}}*/ +// RecordParser::Homepage - Return the package homepage /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::Homepage() +{ + return Section.FindS("Homepage"); +} + /*}}}*/ +// RecordParser::MD5Hash - Return the archive hash /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::MD5Hash() +{ + return Section.FindS("MD5Sum"); +} + /*}}}*/ +// RecordParser::SHA1Hash - Return the archive hash /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::SHA1Hash() +{ + return Section.FindS("SHA1"); +} + /*}}}*/ +// RecordParser::SHA1Hash - Return the archive hash /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::SHA256Hash() +{ + return Section.FindS("SHA256"); +} + /*}}}*/ +// RecordParser::Maintainer - Return the maintainer email /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::Maintainer() +{ + return Section.FindS("Maintainer"); +} + /*}}}*/ +// RecordParser::ShortDesc - Return a 1 line description /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::ShortDesc() +{ + string Res = LongDesc(); + string::size_type Pos = Res.find('\n'); + if (Pos == string::npos) + return Res; + return string(Res,0,Pos); +} + /*}}}*/ +// RecordParser::LongDesc - Return a longer description /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::LongDesc() +{ + string orig, dest; + char *codeset = nl_langinfo(CODESET); + + if (!Section.FindS("Description").empty()) + orig = Section.FindS("Description").c_str(); + else + orig = Section.FindS(("Description-" + pkgIndexFile::LanguageCode()).c_str()).c_str(); + + if (strcmp(codeset,"UTF-8") != 0) { + UTF8ToCodeset(codeset, orig, &dest); + orig = dest; + } + + return orig; +} + /*}}}*/ +// RecordParser::ShortDesc - Return a 1 line description /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debRecordParser::ShortDesc(const char *&Start,const char *&End) +{ + if (!LongDesc(Start,End)) + return false; + const char *Line = (const char *) memchr(Start, '\n', End - Start); + if (Line != NULL) + End = Line; + return true; +} + /*}}}*/ +// RecordParser::LongDesc - Return a longer description /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debRecordParser::LongDesc(const char *&Start,const char *&End) +{ + if (!Section.Find("Description",Start,End)) + return Section.Find(("Description-" + pkgIndexFile::LanguageCode()).c_str(),Start,End); + return true; +} + /*}}}*/ + +static const char *SourceVerSeparators = " ()"; + +// RecordParser::SourcePkg - Return the source package name if any /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::SourcePkg() +{ + string Res = Section.FindS("Source"); + string::size_type Pos = Res.find_first_of(SourceVerSeparators); + if (Pos == string::npos) + return Res; + return string(Res,0,Pos); +} + /*}}}*/ +// RecordParser::SourceVer - Return the source version number if present /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::SourceVer() +{ + string Pkg = Section.FindS("Source"); + string::size_type Pos = Pkg.find_first_of(SourceVerSeparators); + if (Pos == string::npos) + return ""; + + string::size_type VerStart = Pkg.find_first_not_of(SourceVerSeparators, Pos); + if(VerStart == string::npos) + return ""; + + string::size_type VerEnd = Pkg.find_first_of(SourceVerSeparators, VerStart); + if(VerEnd == string::npos) + // Corresponds to the case of, e.g., "foo (1.2" without a closing + // paren. Be liberal and guess what it means. + return string(Pkg, VerStart); + else + return string(Pkg, VerStart, VerEnd - VerStart); +} + /*}}}*/ +// RecordParser::GetRec - Return the whole record /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void debRecordParser::GetRec(const char *&Start,const char *&Stop) +{ + Section.GetSection(Start,Stop); +} + /*}}}*/ +// RecordParser::Find - Locate a tag /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debRecordParser::Find(const char *Tag,const char *&Start, const char *&End) +{ + return Section.Find(Tag,Start,End); +} + /*}}}*/ diff --git a/apt-pkg/deb/debrecords.h b/apt-pkg/deb/debrecords.h index 6f358ab..e3dccd8 100644 --- a/apt-pkg/deb/debrecords.h +++ b/apt-pkg/deb/debrecords.h @@ -39,14 +39,19 @@ class debRecordParser : public pkgRecords::Parser virtual string SourcePkg(); virtual string SourceVer(); + virtual bool ShortDesc(const char *&Start,const char *&End); + virtual bool LongDesc(const char *&Start,const char *&End); + // These are some general stats about the package virtual string Maintainer(); virtual string ShortDesc(); virtual string LongDesc(); virtual string Name(); + virtual string Display(); virtual string Homepage(); virtual void GetRec(const char *&Start,const char *&Stop); + virtual bool Find(const char *Tag,const char *&Start, const char *&End); debRecordParser(string FileName,pkgCache &Cache); }; diff --git a/apt-pkg/deb/debrecords.h.orig b/apt-pkg/deb/debrecords.h.orig new file mode 100644 index 0000000..c583118 --- /dev/null +++ b/apt-pkg/deb/debrecords.h.orig @@ -0,0 +1,55 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: debrecords.h,v 1.8 2001/03/13 06:51:46 jgg Exp $ +/* ###################################################################### + + Debian Package Records - Parser for debian package records + + This provides display-type parsing for the Packages file. This is + different than the the list parser which provides cache generation + services. There should be no overlap between these two. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_DEBRECORDS_H +#define PKGLIB_DEBRECORDS_H + +#include +#include +#include + +class debRecordParser : public pkgRecords::Parser +{ + FileFd File; + pkgTagFile Tags; + pkgTagSection Section; + + protected: + + virtual bool Jump(pkgCache::VerFileIterator const &Ver); + virtual bool Jump(pkgCache::DescFileIterator const &Desc); + + public: + + // These refer to the archive file for the Version + virtual string FileName(); + virtual string MD5Hash(); + virtual string SHA1Hash(); + virtual string SHA256Hash(); + virtual string SourcePkg(); + virtual string SourceVer(); + + // These are some general stats about the package + virtual string Maintainer(); + virtual string ShortDesc(); + virtual string LongDesc(); + virtual string Name(); + virtual string Display(); + virtual string Homepage(); + + virtual void GetRec(const char *&Start,const char *&Stop); + + debRecordParser(string FileName,pkgCache &Cache); +}; + +#endif diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 8eb6208..47b5d61 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -124,6 +124,7 @@ bool pkgCache::ReMap() VerP = (Version *)Map.Data(); DescP = (Description *)Map.Data(); ProvideP = (Provides *)Map.Data(); + TagP = (Tag *)Map.Data(); DepP = (Dependency *)Map.Data(); StringItemP = (StringItem *)Map.Data(); StrP = (char *)Map.Data(); diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 59d5003..a1001f8 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -41,6 +41,7 @@ class pkgCache struct StringItem; struct VerFile; struct DescFile; + struct Tag; // Iterators class PkgIterator; @@ -51,6 +52,7 @@ class pkgCache class PkgFileIterator; class VerFileIterator; class DescFileIterator; + class TagIterator; friend class PkgIterator; friend class VerIterator; friend class DescInterator; @@ -59,6 +61,7 @@ class pkgCache friend class PkgFileIterator; friend class VerFileIterator; friend class DescFileIterator; + friend class TagIterator; class Namespace; @@ -109,6 +112,7 @@ class pkgCache DescFile *DescFileP; PackageFile *PkgFileP; Version *VerP; + Tag *TagP; Description *DescP; Provides *ProvideP; Dependency *DepP; @@ -161,6 +165,7 @@ struct pkgCache::Header unsigned short PackageSz; unsigned short PackageFileSz; unsigned short VersionSz; + unsigned short TagSz; unsigned short DescriptionSz; unsigned short DependencySz; unsigned short ProvidesSz; @@ -170,6 +175,7 @@ struct pkgCache::Header // Structure counts unsigned long PackageCount; unsigned long VersionCount; + unsigned long TagCount; unsigned long DescriptionCount; unsigned long DependsCount; unsigned long PackageFileCount; @@ -200,6 +206,7 @@ struct pkgCache::Package { // Pointers map_ptrloc Name; // Stringtable + map_ptrloc Display; // Stringtable map_ptrloc VersionList; // Version map_ptrloc CurrentVer; // Version map_ptrloc Section; // StringTable (StringItem) @@ -208,6 +215,7 @@ struct pkgCache::Package map_ptrloc NextPackage; // Package map_ptrloc RevDepends; // Dependency map_ptrloc ProvidesList; // Provides + map_ptrloc TagList; // Tag // Install/Remove/Purge etc unsigned char SelectedState; // What @@ -247,6 +255,12 @@ struct pkgCache::VerFile unsigned short Size; }; +struct pkgCache::Tag +{ + map_ptrloc Name; // Stringtable + map_ptrloc NextTag; // Tag +}; + struct pkgCache::DescFile { map_ptrloc File; // PackageFile @@ -258,6 +272,7 @@ struct pkgCache::DescFile struct pkgCache::Version { map_ptrloc VerStr; // Stringtable + map_ptrloc Display; // Stringtable map_ptrloc Section; // StringTable (StringItem) map_ptrloc Arch; // StringTable @@ -339,6 +354,7 @@ class pkgCache::Namespace typedef pkgCache::PkgIterator PkgIterator; typedef pkgCache::VerIterator VerIterator; + typedef pkgCache::TagIterator TagIterator; typedef pkgCache::DescIterator DescIterator; typedef pkgCache::DepIterator DepIterator; typedef pkgCache::PrvIterator PrvIterator; diff --git a/apt-pkg/pkgcache.h.orig b/apt-pkg/pkgcache.h.orig new file mode 100644 index 0000000..fc3f4c8 --- /dev/null +++ b/apt-pkg/pkgcache.h.orig @@ -0,0 +1,357 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgcache.h,v 1.25 2001/07/01 22:28:24 jgg Exp $ +/* ###################################################################### + + Cache - Structure definitions for the cache file + + Please see doc/apt-pkg/cache.sgml for a more detailed description of + this format. Also be sure to keep that file up-to-date!! + + Clients should always use the CacheIterators classes for access to the + cache. They provide a simple STL-like method for traversing the links + of the datastructure. + + See pkgcachegen.h for information about generating cache structures. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_PKGCACHE_H +#define PKGLIB_PKGCACHE_H + + +#include +#include +#include + +using std::string; + +class pkgVersioningSystem; +class pkgCache +{ + public: + // Cache element predeclarations + struct Header; + struct Package; + struct PackageFile; + struct Version; + struct Description; + struct Provides; + struct Dependency; + struct StringItem; + struct VerFile; + struct DescFile; + + // Iterators + class PkgIterator; + class VerIterator; + class DescIterator; + class DepIterator; + class PrvIterator; + class PkgFileIterator; + class VerFileIterator; + class DescFileIterator; + friend class PkgIterator; + friend class VerIterator; + friend class DescInterator; + friend class DepIterator; + friend class PrvIterator; + friend class PkgFileIterator; + friend class VerFileIterator; + friend class DescFileIterator; + + class Namespace; + + // These are all the constants used in the cache structures + + // WARNING - if you change these lists you must also edit + // the stringification in pkgcache.cc and also consider whether + // the cache file will become incompatible. + struct Dep + { + enum DepType {Depends=1,PreDepends=2,Suggests=3,Recommends=4, + Conflicts=5,Replaces=6,Obsoletes=7,DpkgBreaks=8}; + enum DepCompareOp {Or=0x10,NoOp=0,LessEq=0x1,GreaterEq=0x2,Less=0x3, + Greater=0x4,Equals=0x5,NotEquals=0x6}; + }; + + struct State + { + enum VerPriority {Important=1,Required=2,Standard=3,Optional=4,Extra=5}; + enum PkgSelectedState {Unknown=0,Install=1,Hold=2,DeInstall=3,Purge=4}; + enum PkgInstState {Ok=0,ReInstReq=1,HoldInst=2,HoldReInstReq=3}; + enum PkgCurrentState {NotInstalled=0,UnPacked=1,HalfConfigured=2, + HalfInstalled=4,ConfigFiles=5,Installed=6, + TriggersAwaited=7,TriggersPending=8}; + }; + + struct Flag + { + enum PkgFlags {Auto=(1<<0),Essential=(1<<3),Important=(1<<4)}; + enum PkgFFlags {NotSource=(1<<0),NotAutomatic=(1<<1)}; + }; + + protected: + + // Memory mapped cache file + string CacheFile; + MMap ⤅ + + unsigned long sHash(const string &S) const; + unsigned long sHash(const char *S) const; + + public: + + // Pointers to the arrays of items + Header *HeaderP; + Package *PkgP; + VerFile *VerFileP; + DescFile *DescFileP; + PackageFile *PkgFileP; + Version *VerP; + Description *DescP; + Provides *ProvideP; + Dependency *DepP; + StringItem *StringItemP; + char *StrP; + + virtual bool ReMap(); + inline bool Sync() {return Map.Sync();}; + inline MMap &GetMap() {return Map;}; + inline void *DataEnd() {return ((unsigned char *)Map.Data()) + Map.Size();}; + + // String hashing function (512 range) + inline unsigned long Hash(const string &S) const {return sHash(S);}; + inline unsigned long Hash(const char *S) const {return sHash(S);}; + + // Usefull transformation things + const char *Priority(unsigned char Priority); + + // Accessors + PkgIterator FindPkg(const string &Name); + Header &Head() {return *HeaderP;}; + inline PkgIterator PkgBegin(); + inline PkgIterator PkgEnd(); + inline PkgFileIterator FileBegin(); + inline PkgFileIterator FileEnd(); + + // Make me a function + pkgVersioningSystem *VS; + + // Converters + static const char *CompTypeDeb(unsigned char Comp); + static const char *CompType(unsigned char Comp); + static const char *DepType(unsigned char Dep); + + pkgCache(MMap *Map,bool DoMap = true); + virtual ~pkgCache() {}; +}; + +// Header structure +struct pkgCache::Header +{ + // Signature information + unsigned long Signature; + short MajorVersion; + short MinorVersion; + bool Dirty; + + // Size of structure values + unsigned short HeaderSz; + unsigned short PackageSz; + unsigned short PackageFileSz; + unsigned short VersionSz; + unsigned short DescriptionSz; + unsigned short DependencySz; + unsigned short ProvidesSz; + unsigned short VerFileSz; + unsigned short DescFileSz; + + // Structure counts + unsigned long PackageCount; + unsigned long VersionCount; + unsigned long DescriptionCount; + unsigned long DependsCount; + unsigned long PackageFileCount; + unsigned long VerFileCount; + unsigned long DescFileCount; + unsigned long ProvidesCount; + + // Offsets + map_ptrloc FileList; // struct PackageFile + map_ptrloc StringList; // struct StringItem + map_ptrloc VerSysName; // StringTable + map_ptrloc Architecture; // StringTable + unsigned long MaxVerFileSize; + unsigned long MaxDescFileSize; + + /* Allocation pools, there should be one of these for each structure + excluding the header */ + DynamicMMap::Pool Pools[8]; + + // Rapid package name lookup + map_ptrloc HashTable[2*1048]; + + bool CheckSizes(Header &Against) const; + Header(); +}; + +struct pkgCache::Package +{ + // Pointers + map_ptrloc Name; // Stringtable + map_ptrloc Display; // Stringtable + map_ptrloc VersionList; // Version + map_ptrloc CurrentVer; // Version + map_ptrloc Section; // StringTable (StringItem) + + // Linked list + map_ptrloc NextPackage; // Package + map_ptrloc RevDepends; // Dependency + map_ptrloc ProvidesList; // Provides + + // Install/Remove/Purge etc + unsigned char SelectedState; // What + unsigned char InstState; // Flags + unsigned char CurrentState; // State + + unsigned short ID; + unsigned long Flags; +}; + +struct pkgCache::PackageFile +{ + // Names + map_ptrloc FileName; // Stringtable + map_ptrloc Archive; // Stringtable + map_ptrloc Component; // Stringtable + map_ptrloc Version; // Stringtable + map_ptrloc Origin; // Stringtable + map_ptrloc Label; // Stringtable + map_ptrloc Architecture; // Stringtable + map_ptrloc Site; // Stringtable + map_ptrloc IndexType; // Stringtable + unsigned long Size; + unsigned long Flags; + + // Linked list + map_ptrloc NextFile; // PackageFile + unsigned short ID; + time_t mtime; // Modification time for the file +}; + +struct pkgCache::VerFile +{ + map_ptrloc File; // PackageFile + map_ptrloc NextFile; // PkgVerFile + map_ptrloc Offset; // File offset + unsigned short Size; +}; + +struct pkgCache::DescFile +{ + map_ptrloc File; // PackageFile + map_ptrloc NextFile; // PkgVerFile + map_ptrloc Offset; // File offset + unsigned short Size; +}; + +struct pkgCache::Version +{ + map_ptrloc VerStr; // Stringtable + map_ptrloc Display; // Stringtable + map_ptrloc Section; // StringTable (StringItem) + map_ptrloc Arch; // StringTable + + // Lists + map_ptrloc FileList; // VerFile + map_ptrloc NextVer; // Version + map_ptrloc DescriptionList; // Description + map_ptrloc DependsList; // Dependency + map_ptrloc ParentPkg; // Package + map_ptrloc ProvidesList; // Provides + + map_ptrloc Size; // These are the .deb size + map_ptrloc InstalledSize; + unsigned short Hash; + unsigned short ID; + unsigned char Priority; +}; + +struct pkgCache::Description +{ + // Language Code store the description translation language code. If + // the value has a 0 lenght then this is readed using the Package + // file else the Translation-CODE are used. + map_ptrloc language_code; // StringTable + map_ptrloc md5sum; // StringTable + + // Linked list + map_ptrloc FileList; // DescFile + map_ptrloc NextDesc; // Description + map_ptrloc ParentPkg; // Package + + unsigned short ID; +}; + +struct pkgCache::Dependency +{ + map_ptrloc Version; // Stringtable + map_ptrloc Package; // Package + map_ptrloc NextDepends; // Dependency + map_ptrloc NextRevDepends; // Dependency + map_ptrloc ParentVer; // Version + + // Specific types of depends + map_ptrloc ID; + unsigned char Type; + unsigned char CompareOp; +}; + +struct pkgCache::Provides +{ + map_ptrloc ParentPkg; // Pacakge + map_ptrloc Version; // Version + map_ptrloc ProvideVersion; // Stringtable + map_ptrloc NextProvides; // Provides + map_ptrloc NextPkgProv; // Provides +}; + +struct pkgCache::StringItem +{ + map_ptrloc String; // Stringtable + map_ptrloc NextItem; // StringItem +}; + +#include + +inline pkgCache::PkgIterator pkgCache::PkgBegin() + {return PkgIterator(*this);}; +inline pkgCache::PkgIterator pkgCache::PkgEnd() + {return PkgIterator(*this,PkgP);}; +inline pkgCache::PkgFileIterator pkgCache::FileBegin() + {return PkgFileIterator(*this,PkgFileP + HeaderP->FileList);}; +inline pkgCache::PkgFileIterator pkgCache::FileEnd() + {return PkgFileIterator(*this,PkgFileP);}; + +// Oh I wish for Real Name Space Support +class pkgCache::Namespace +{ + public: + + typedef pkgCache::PkgIterator PkgIterator; + typedef pkgCache::VerIterator VerIterator; + typedef pkgCache::DescIterator DescIterator; + typedef pkgCache::DepIterator DepIterator; + typedef pkgCache::PrvIterator PrvIterator; + typedef pkgCache::PkgFileIterator PkgFileIterator; + typedef pkgCache::VerFileIterator VerFileIterator; + typedef pkgCache::Version Version; + typedef pkgCache::Description Description; + typedef pkgCache::Package Package; + typedef pkgCache::Header Header; + typedef pkgCache::Dep Dep; + typedef pkgCache::Flag Flag; +}; + +#endif diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 397c198..1b53649 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -567,6 +567,32 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver, Prv->NextProvides = Pkg->ProvidesList; Pkg->ProvidesList = Prv.Index(); + return true; +} + /*}}}*/ +// ListParser::NewTag - Create a Tag element /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgCacheGenerator::ListParser::NewTag(pkgCache::PkgIterator Pkg, + const char *NameStart, + unsigned int NameSize) +{ + pkgCache &Cache = Owner->Cache; + + // Get a structure + unsigned long Tagg = Owner->Map.Allocate(sizeof(pkgCache::Tag)); + if (Tagg == 0) + return false; + Cache.HeaderP->TagCount++; + + // Fill it in + pkgCache::TagIterator Tg(Cache,Cache.TagP + Tagg); + Tg->Name = WriteString(NameStart,NameSize); + if (Tg->Name == 0) + return false; + Tg->NextTag = Pkg->TagList; + Pkg->TagList = Tg.Index(); + return true; } /*}}}*/ diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h index b671529..63aefc7 100644 --- a/apt-pkg/pkgcachegen.h +++ b/apt-pkg/pkgcachegen.h @@ -101,6 +101,7 @@ class pkgCacheGenerator::ListParser unsigned int Type); bool NewProvides(pkgCache::VerIterator Ver,const string &Package, const string &Version); + bool NewTag(pkgCache::PkgIterator Pkg,const char *NameStart,unsigned int NameSize); public: diff --git a/apt-pkg/pkgrecords.h b/apt-pkg/pkgrecords.h index 17f3b15..b2c9446 100644 --- a/apt-pkg/pkgrecords.h +++ b/apt-pkg/pkgrecords.h @@ -61,6 +61,9 @@ class pkgRecords::Parser virtual string SourcePkg() {return string();}; virtual string SourceVer() {return string();}; + virtual bool ShortDesc(const char *&Start,const char *&End) {return false;} + virtual bool LongDesc(const char *&Start,const char *&End) {return false;} + // These are some general stats about the package virtual string Maintainer() {return string();}; virtual string ShortDesc() {return string();}; @@ -70,6 +73,7 @@ class pkgRecords::Parser // The record in binary form virtual void GetRec(const char *&Start,const char *&Stop) {Start = Stop = 0;}; + virtual bool Find(const char *Tag,const char *&Start, const char *&End) {Start = End = 0; return false;}; virtual ~Parser() {}; }; diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 893cb8e..de73c53 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -28,11 +28,11 @@ using std::string; // --------------------------------------------------------------------- /* */ pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long Size) : - Fd(*pFd), - Size(Size) + Fd(*pFd) { - if (Fd.IsOpen() == false) + if (Fd.IsOpen() == false || Fd.Size() == 0) { + Map = NULL; Buffer = 0; Start = End = Buffer = 0; Done = true; @@ -40,7 +40,8 @@ pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long Size) : return; } - Buffer = new char[Size]; + Map = new MMap(*pFd, MMap::ReadOnly); + Buffer = reinterpret_cast(Map->Data()); Start = End = Buffer; Done = false; iOffset = 0; @@ -52,36 +53,9 @@ pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long Size) : /* */ pkgTagFile::~pkgTagFile() { - delete [] Buffer; + delete Map; } /*}}}*/ -// TagFile::Resize - Resize the internal buffer /*{{{*/ -// --------------------------------------------------------------------- -/* Resize the internal buffer (double it in size). Fail if a maximum size - * size is reached. - */ -bool pkgTagFile::Resize() -{ - char *tmp; - unsigned long EndSize = End - Start; - - // fail is the buffer grows too big - if(Size > 1024*1024+1) - return false; - - // get new buffer and use it - tmp = new char[2*Size]; - memcpy(tmp, Buffer, Size); - Size = Size*2; - delete [] Buffer; - Buffer = tmp; - - // update the start/end pointers to the new buffer - Start = Buffer; - End = Start + EndSize; - return true; -} - // TagFile::Step - Advance to the next section /*{{{*/ // --------------------------------------------------------------------- /* If the Section Scanner fails we refill the buffer and try again. @@ -90,15 +64,11 @@ bool pkgTagFile::Resize() */ bool pkgTagFile::Step(pkgTagSection &Tag) { - while (Tag.Scan(Start,End - Start) == false) + if (Tag.Scan(Start,End - Start) == false) { - if (Fill() == false) - return false; - - if(Tag.Scan(Start,End - Start)) - break; - - if (Resize() == false) + if (Start == End) + return false; + else return _error->Error(_("Unable to parse package file %s (1)"), Fd.Name().c_str()); } @@ -115,41 +85,11 @@ bool pkgTagFile::Step(pkgTagSection &Tag) then fills the rest from the file */ bool pkgTagFile::Fill() { - unsigned long EndSize = End - Start; - unsigned long Actual = 0; - - memmove(Buffer,Start,EndSize); - Start = Buffer; - End = Buffer + EndSize; - - if (Done == false) - { - // See if only a bit of the file is left - if (Fd.Read(End,Size - (End - Buffer),&Actual) == false) - return false; - if (Actual != Size - (End - Buffer)) - Done = true; - End += Actual; - } - - if (Done == true) - { - if (EndSize <= 3 && Actual == 0) - return false; - if (Size - (End - Buffer) < 4) - return true; - - // Append a double new line if one does not exist - unsigned int LineCount = 0; - for (const char *E = End - 1; E - End < 6 && (*E == '\n' || *E == '\r'); E--) - if (*E == '\n') - LineCount++; - for (; LineCount < 2; LineCount++) - *End++ = '\n'; - - return true; - } - + unsigned int Size(Map->Size()); + End = Buffer + Size; + if (iOffset >= Size) + return false; + Start = Buffer + iOffset; return true; } /*}}}*/ @@ -171,20 +111,11 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long Offset) // Reposition and reload.. iOffset = Offset; Done = false; - if (Fd.Seek(Offset) == false) - return false; End = Start = Buffer; if (Fill() == false) return false; - if (Tag.Scan(Start,End - Start) == true) - return true; - - // This appends a double new line (for the real eof handling) - if (Fill() == false) - return false; - if (Tag.Scan(Start,End - Start) == false) return _error->Error(_("Unable to parse package file %s (2)"),Fd.Name().c_str()); @@ -220,19 +151,24 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength) if (isspace(Stop[0]) == 0) { Indexes[TagCount++] = Stop - Section; - AlphaIndexes[AlphaHash(Stop,End)] = TagCount; + unsigned long hash(AlphaHash(Stop, End)); + while (AlphaIndexes[hash] != 0) + hash = (hash + 1) % (sizeof(AlphaIndexes) / sizeof(AlphaIndexes[0])); + AlphaIndexes[hash] = TagCount; } Stop = (const char *)memchr(Stop,'\n',End - Stop); - if (Stop == 0) - return false; + if (Stop == 0) { + Stop = End; + goto end; + } for (; Stop+1 < End && Stop[1] == '\r'; Stop++); // Double newline marks the end of the record - if (Stop+1 < End && Stop[1] == '\n') - { + if (Stop+1 == End || Stop[1] == '\n') + end: { Indexes[TagCount] = Stop - Section; for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r'); Stop++); return true; @@ -258,14 +194,16 @@ void pkgTagSection::Trim() bool pkgTagSection::Find(const char *Tag,unsigned &Pos) const { unsigned int Length = strlen(Tag); - unsigned int I = AlphaIndexes[AlphaHash(Tag)]; - if (I == 0) - return false; - I--; + unsigned int J = AlphaHash(Tag); - for (unsigned int Counter = 0; Counter != TagCount; Counter++, - I = (I+1)%TagCount) + for (unsigned int Counter = 0; Counter != TagCount; Counter++, + J = (J+1)%(sizeof(AlphaIndexes)/sizeof(AlphaIndexes[0]))) { + unsigned int I = AlphaIndexes[J]; + if (I == 0) + return false; + I--; + const char *St; St = Section + Indexes[I]; if (strncasecmp(Tag,St,Length) != 0) @@ -291,14 +229,16 @@ bool pkgTagSection::Find(const char *Tag,const char *&Start, const char *&End) const { unsigned int Length = strlen(Tag); - unsigned int I = AlphaIndexes[AlphaHash(Tag)]; - if (I == 0) - return false; - I--; + unsigned int J = AlphaHash(Tag); - for (unsigned int Counter = 0; Counter != TagCount; Counter++, - I = (I+1)%TagCount) + for (unsigned int Counter = 0; Counter != TagCount; Counter++, + J = (J+1)%(sizeof(AlphaIndexes)/sizeof(AlphaIndexes[0]))) { + unsigned int I = AlphaIndexes[J]; + if (I == 0) + return false; + I--; + const char *St; St = Section + Indexes[I]; if (strncasecmp(Tag,St,Length) != 0) diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h index 6536932..17b03f2 100644 --- a/apt-pkg/tagfile.h +++ b/apt-pkg/tagfile.h @@ -21,6 +21,7 @@ #define PKGLIB_TAGFILE_H +#include #include #include @@ -71,10 +72,9 @@ class pkgTagFile char *End; bool Done; unsigned long iOffset; - unsigned long Size; + MMap *Map; bool Fill(); - bool Resize(); public: diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index febe08c..4431fd4 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -1810,7 +1810,7 @@ int main(int argc,const char *argv[]) // Set up gettext support setlocale(LC_ALL,""); - //textdomain(PACKAGE); + textdomain(PACKAGE); // Parse the command line and initialize the package library CommandLine CmdL(Args,_config); diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc index 8e49234..379a433 100644 --- a/cmdline/apt-cdrom.cc +++ b/cmdline/apt-cdrom.cc @@ -188,7 +188,7 @@ int main(int argc,const char *argv[]) // Set up gettext support setlocale(LC_ALL,""); - //textdomain(PACKAGE); + textdomain(PACKAGE); // Parse the command line and initialize the package library CommandLine CmdL(Args,_config); diff --git a/cmdline/apt-config.cc b/cmdline/apt-config.cc index 9ac5c4c..63fa086 100644 --- a/cmdline/apt-config.cc +++ b/cmdline/apt-config.cc @@ -103,7 +103,7 @@ int main(int argc,const char *argv[]) // Set up gettext support setlocale(LC_ALL,""); - //textdomain(PACKAGE); + textdomain(PACKAGE); // Parse the command line and initialize the package library CommandLine CmdL(Args,_config); diff --git a/cmdline/apt-extracttemplates.cc b/cmdline/apt-extracttemplates.cc index 1e6509d..de22386 100644 --- a/cmdline/apt-extracttemplates.cc +++ b/cmdline/apt-extracttemplates.cc @@ -361,7 +361,7 @@ int main(int argc, const char **argv) // Set up gettext support setlocale(LC_ALL,""); - //textdomain(PACKAGE); + textdomain(PACKAGE); // Parse the command line and initialize the package library CommandLine CmdL(Args,_config); diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 3ddaf7d..f7e6f8b 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2760,7 +2760,7 @@ int main(int argc,const char *argv[]) // Set up gettext support setlocale(LC_ALL,""); - //textdomain(PACKAGE); + textdomain(PACKAGE); // Parse the command line and initialize the package library CommandLine CmdL(Args,_config); diff --git a/cmdline/apt-get.cc.orig b/cmdline/apt-get.cc.orig deleted file mode 100644 index f7e6f8b..0000000 --- a/cmdline/apt-get.cc.orig +++ /dev/null @@ -1,2820 +0,0 @@ -// -*- mode: cpp; mode: fold -*- -// Description /*{{{*/ -// $Id: apt-get.cc,v 1.156 2004/08/28 01:05:16 mdz Exp $ -/* ###################################################################### - - apt-get - Cover for dpkg - - This is an allout cover for dpkg implementing a safer front end. It is - based largely on libapt-pkg. - - The syntax is different, - apt-get [opt] command [things] - Where command is: - update - Resyncronize the package files from their sources - upgrade - Smart-Download the newest versions of all packages - dselect-upgrade - Follows dselect's changes to the Status: field - and installes new and removes old packages - dist-upgrade - Powerfull upgrader designed to handle the issues with - a new distribution. - install - Download and install a given package (by name, not by .deb) - check - Update the package cache and check for broken packages - clean - Erase the .debs downloaded to /var/cache/apt/archives and - the partial dir too - - ##################################################################### */ - /*}}}*/ -// Include Files /*{{{*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "acqprogress.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - /*}}}*/ - -#define RAMFS_MAGIC 0x858458f6 - -#define _trace() printf("_trace(%s:%d)\n", __FILE__, __LINE__) - -using namespace std; - -ostream c0out(0); -ostream c1out(0); -ostream c2out(0); -unsigned int ScreenWidth = 80 - 1; /* - 1 for the cursor */ - -// class CacheFile - Cover class for some dependency cache functions /*{{{*/ -// --------------------------------------------------------------------- -/* */ -class CacheFile : public pkgCacheFile -{ - static pkgCache *SortCache; - static int NameComp(const void *a,const void *b); - - public: - pkgCache::Package **List; - - void Sort(); - bool CheckDeps(bool AllowBroken = false); - bool BuildCaches(bool WithLock = true) - { - OpTextProgress Prog(*_config); - if (pkgCacheFile::BuildCaches(Prog,WithLock) == false) - return false; - return true; - } - bool Open(bool WithLock = true) - { - OpTextProgress Prog(*_config); - if (pkgCacheFile::Open(Prog,WithLock) == false) - return false; - Sort(); - - return true; - }; - bool OpenForInstall() - { - if (_config->FindB("APT::Get::Print-URIs") == true) - return Open(false); - else - return Open(true); - } - CacheFile() : List(0) {}; -}; - /*}}}*/ - -// YnPrompt - Yes No Prompt. /*{{{*/ -// --------------------------------------------------------------------- -/* Returns true on a Yes.*/ -bool YnPrompt(bool Default=true) -{ - if (_config->FindB("APT::Get::Assume-Yes",false) == true) - { - c1out << _("Y") << endl; - return true; - } - - char response[1024] = ""; - cin.getline(response, sizeof(response)); - - if (!cin) - return false; - - if (strlen(response) == 0) - return Default; - - regex_t Pattern; - int Res; - - Res = regcomp(&Pattern, nl_langinfo(YESEXPR), - REG_EXTENDED|REG_ICASE|REG_NOSUB); - - if (Res != 0) { - char Error[300]; - regerror(Res,&Pattern,Error,sizeof(Error)); - return _error->Error(_("Regex compilation error - %s"),Error); - } - - Res = regexec(&Pattern, response, 0, NULL, 0); - if (Res == 0) - return true; - return false; -} - /*}}}*/ -// AnalPrompt - Annoying Yes No Prompt. /*{{{*/ -// --------------------------------------------------------------------- -/* Returns true on a Yes.*/ -bool AnalPrompt(const char *Text) -{ - char Buf[1024]; - cin.getline(Buf,sizeof(Buf)); - if (strcmp(Buf,Text) == 0) - return true; - return false; -} - /*}}}*/ -// ShowList - Show a list /*{{{*/ -// --------------------------------------------------------------------- -/* This prints out a string of space separated words with a title and - a two space indent line wraped to the current screen width. */ -bool ShowList(ostream &out,string Title,string List,string VersionsList) -{ - if (List.empty() == true) - return true; - // trim trailing space - int NonSpace = List.find_last_not_of(' '); - if (NonSpace != -1) - { - List = List.erase(NonSpace + 1); - if (List.empty() == true) - return true; - } - - // Acount for the leading space - int ScreenWidth = ::ScreenWidth - 3; - - out << Title << endl; - string::size_type Start = 0; - string::size_type VersionsStart = 0; - while (Start < List.size()) - { - if(_config->FindB("APT::Get::Show-Versions",false) == true && - VersionsList.size() > 0) { - string::size_type End; - string::size_type VersionsEnd; - - End = List.find(' ',Start); - VersionsEnd = VersionsList.find('\n', VersionsStart); - - out << " " << string(List,Start,End - Start) << " (" << - string(VersionsList,VersionsStart,VersionsEnd - VersionsStart) << - ")" << endl; - - if (End == string::npos || End < Start) - End = Start + ScreenWidth; - - Start = End + 1; - VersionsStart = VersionsEnd + 1; - } else { - string::size_type End; - - if (Start + ScreenWidth >= List.size()) - End = List.size(); - else - End = List.rfind(' ',Start+ScreenWidth); - - if (End == string::npos || End < Start) - End = Start + ScreenWidth; - out << " " << string(List,Start,End - Start) << endl; - Start = End + 1; - } - } - - return false; -} - /*}}}*/ -// ShowBroken - Debugging aide /*{{{*/ -// --------------------------------------------------------------------- -/* This prints out the names of all the packages that are broken along - with the name of each each broken dependency and a quite version - description. - - The output looks like: - The following packages have unmet dependencies: - exim: Depends: libc6 (>= 2.1.94) but 2.1.3-10 is to be installed - Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed - Depends: libsasl7 but it is not going to be installed - */ -void ShowBroken(ostream &out,CacheFile &Cache,bool Now) -{ - out << _("The following packages have unmet dependencies:") << endl; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - - if (Now == true) - { - if (Cache[I].NowBroken() == false) - continue; - } - else - { - if (Cache[I].InstBroken() == false) - continue; - } - - // Print out each package and the failed dependencies - out <<" " << I.Name() << ":"; - unsigned Indent = strlen(I.Name()) + 3; - bool First = true; - pkgCache::VerIterator Ver; - - if (Now == true) - Ver = I.CurrentVer(); - else - Ver = Cache[I].InstVerIter(Cache); - - if (Ver.end() == true) - { - out << endl; - continue; - } - - for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;) - { - // Compute a single dependency element (glob or) - pkgCache::DepIterator Start; - pkgCache::DepIterator End; - D.GlobOr(Start,End); // advances D - - if (Cache->IsImportantDep(End) == false) - continue; - - if (Now == true) - { - if ((Cache[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow) - continue; - } - else - { - if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall) - continue; - } - - bool FirstOr = true; - while (1) - { - if (First == false) - for (unsigned J = 0; J != Indent; J++) - out << ' '; - First = false; - - if (FirstOr == false) - { - for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++) - out << ' '; - } - else - out << ' ' << End.DepType() << ": "; - FirstOr = false; - - out << Start.TargetPkg().Name(); - - // Show a quick summary of the version requirements - if (Start.TargetVer() != 0) - out << " (" << Start.CompType() << " " << Start.TargetVer() << ")"; - - /* Show a summary of the target package if possible. In the case - of virtual packages we show nothing */ - pkgCache::PkgIterator Targ = Start.TargetPkg(); - if (Targ->ProvidesList == 0) - { - out << ' '; - pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache); - if (Now == true) - Ver = Targ.CurrentVer(); - - if (Ver.end() == false) - { - if (Now == true) - ioprintf(out,_("but %s is installed"),Ver.VerStr()); - else - ioprintf(out,_("but %s is to be installed"),Ver.VerStr()); - } - else - { - if (Cache[Targ].CandidateVerIter(Cache).end() == true) - { - if (Targ->ProvidesList == 0) - out << _("but it is not installable"); - else - out << _("but it is a virtual package"); - } - else - out << (Now?_("but it is not installed"):_("but it is not going to be installed")); - } - } - - if (Start != End) - out << _(" or"); - out << endl; - - if (Start == End) - break; - Start++; - } - } - } -} - /*}}}*/ -// ShowNew - Show packages to newly install /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void ShowNew(ostream &out,CacheFile &Cache) -{ - /* Print out a list of packages that are going to be installed extra - to what the user asked */ - string List; - string VersionsList; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - if (Cache[I].NewInstall() == true) { - List += string(I.Name()) + " "; - VersionsList += string(Cache[I].CandVersion) + "\n"; - } - } - - ShowList(out,_("The following NEW packages will be installed:"),List,VersionsList); -} - /*}}}*/ -// ShowDel - Show packages to delete /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void ShowDel(ostream &out,CacheFile &Cache) -{ - /* Print out a list of packages that are going to be removed extra - to what the user asked */ - string List; - string VersionsList; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - if (Cache[I].Delete() == true) - { - if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge) - List += string(I.Name()) + "* "; - else - List += string(I.Name()) + " "; - - VersionsList += string(Cache[I].CandVersion)+ "\n"; - } - } - - ShowList(out,_("The following packages will be REMOVED:"),List,VersionsList); -} - /*}}}*/ -// ShowKept - Show kept packages /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void ShowKept(ostream &out,CacheFile &Cache) -{ - string List; - string VersionsList; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - - // Not interesting - if (Cache[I].Upgrade() == true || Cache[I].Upgradable() == false || - I->CurrentVer == 0 || Cache[I].Delete() == true) - continue; - - List += string(I.Name()) + " "; - VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; - } - ShowList(out,_("The following packages have been kept back:"),List,VersionsList); -} - /*}}}*/ -// ShowUpgraded - Show upgraded packages /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void ShowUpgraded(ostream &out,CacheFile &Cache) -{ - string List; - string VersionsList; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - - // Not interesting - if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true) - continue; - - List += string(I.Name()) + " "; - VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; - } - ShowList(out,_("The following packages will be upgraded:"),List,VersionsList); -} - /*}}}*/ -// ShowDowngraded - Show downgraded packages /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool ShowDowngraded(ostream &out,CacheFile &Cache) -{ - string List; - string VersionsList; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - - // Not interesting - if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true) - continue; - - List += string(I.Name()) + " "; - VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; - } - return ShowList(out,_("The following packages will be DOWNGRADED:"),List,VersionsList); -} - /*}}}*/ -// ShowHold - Show held but changed packages /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool ShowHold(ostream &out,CacheFile &Cache) -{ - string List; - string VersionsList; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() && - I->SelectedState == pkgCache::State::Hold) { - List += string(I.Name()) + " "; - VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n"; - } - } - - return ShowList(out,_("The following held packages will be changed:"),List,VersionsList); -} - /*}}}*/ -// ShowEssential - Show an essential package warning /*{{{*/ -// --------------------------------------------------------------------- -/* This prints out a warning message that is not to be ignored. It shows - all essential packages and their dependents that are to be removed. - It is insanely risky to remove the dependents of an essential package! */ -bool ShowEssential(ostream &out,CacheFile &Cache) -{ - string List; - string VersionsList; - bool *Added = new bool[Cache->Head().PackageCount]; - for (unsigned int I = 0; I != Cache->Head().PackageCount; I++) - Added[I] = false; - - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential && - (I->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important) - continue; - - // The essential package is being removed - if (Cache[I].Delete() == true) - { - if (Added[I->ID] == false) - { - Added[I->ID] = true; - List += string(I.Name()) + " "; - //VersionsList += string(Cache[I].CurVersion) + "\n"; ??? - } - } - - if (I->CurrentVer == 0) - continue; - - // Print out any essential package depenendents that are to be removed - for (pkgCache::DepIterator D = I.CurrentVer().DependsList(); D.end() == false; D++) - { - // Skip everything but depends - if (D->Type != pkgCache::Dep::PreDepends && - D->Type != pkgCache::Dep::Depends) - continue; - - pkgCache::PkgIterator P = D.SmartTargetPkg(); - if (Cache[P].Delete() == true) - { - if (Added[P->ID] == true) - continue; - Added[P->ID] = true; - - char S[300]; - snprintf(S,sizeof(S),_("%s (due to %s) "),P.Name(),I.Name()); - List += S; - //VersionsList += "\n"; ??? - } - } - } - - delete [] Added; - return ShowList(out,_("WARNING: The following essential packages will be removed.\n" - "This should NOT be done unless you know exactly what you are doing!"),List,VersionsList); -} - - /*}}}*/ -// Stats - Show some statistics /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void Stats(ostream &out,pkgDepCache &Dep) -{ - unsigned long Upgrade = 0; - unsigned long Downgrade = 0; - unsigned long Install = 0; - unsigned long ReInstall = 0; - for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++) - { - if (Dep[I].NewInstall() == true) - Install++; - else - { - if (Dep[I].Upgrade() == true) - Upgrade++; - else - if (Dep[I].Downgrade() == true) - Downgrade++; - } - - if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall) - ReInstall++; - } - - ioprintf(out,_("%lu upgraded, %lu newly installed, "), - Upgrade,Install); - - if (ReInstall != 0) - ioprintf(out,_("%lu reinstalled, "),ReInstall); - if (Downgrade != 0) - ioprintf(out,_("%lu downgraded, "),Downgrade); - - ioprintf(out,_("%lu to remove and %lu not upgraded.\n"), - Dep.DelCount(),Dep.KeepCount()); - - if (Dep.BadCount() != 0) - ioprintf(out,_("%lu not fully installed or removed.\n"), - Dep.BadCount()); -} - /*}}}*/ - -// CacheFile::NameComp - QSort compare by name /*{{{*/ -// --------------------------------------------------------------------- -/* */ -pkgCache *CacheFile::SortCache = 0; -int CacheFile::NameComp(const void *a,const void *b) -{ - if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0) - return *(pkgCache::Package **)a - *(pkgCache::Package **)b; - - const pkgCache::Package &A = **(pkgCache::Package **)a; - const pkgCache::Package &B = **(pkgCache::Package **)b; - - return strcmp(SortCache->StrP + A.Name,SortCache->StrP + B.Name); -} - /*}}}*/ -// CacheFile::Sort - Sort by name /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void CacheFile::Sort() -{ - delete [] List; - List = new pkgCache::Package *[Cache->Head().PackageCount]; - memset(List,0,sizeof(*List)*Cache->Head().PackageCount); - pkgCache::PkgIterator I = Cache->PkgBegin(); - for (;I.end() != true; I++) - List[I->ID] = I; - - SortCache = *this; - qsort(List,Cache->Head().PackageCount,sizeof(*List),NameComp); -} - /*}}}*/ -// CacheFile::CheckDeps - Open the cache file /*{{{*/ -// --------------------------------------------------------------------- -/* This routine generates the caches and then opens the dependency cache - and verifies that the system is OK. */ -bool CacheFile::CheckDeps(bool AllowBroken) -{ - bool FixBroken = _config->FindB("APT::Get::Fix-Broken",false); - - if (_error->PendingError() == true) - return false; - - // Check that the system is OK - if (DCache->DelCount() != 0 || DCache->InstCount() != 0) - return _error->Error("Internal error, non-zero counts"); - - // Apply corrections for half-installed packages - if (pkgApplyStatus(*DCache) == false) - return false; - - if (_config->FindB("APT::Get::Fix-Policy-Broken",false) == true) - { - FixBroken = true; - if ((DCache->PolicyBrokenCount() > 0)) - { - // upgrade all policy-broken packages with ForceImportantDeps=True - for (pkgCache::PkgIterator I = Cache->PkgBegin(); !I.end(); I++) - if ((*DCache)[I].NowPolicyBroken() == true) - DCache->MarkInstall(I,true,0, false, true); - } - } - - // Nothing is broken - if (DCache->BrokenCount() == 0 || AllowBroken == true) - return true; - - // Attempt to fix broken things - if (FixBroken == true) - { - c1out << _("Correcting dependencies...") << flush; - if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0) - { - c1out << _(" failed.") << endl; - ShowBroken(c1out,*this,true); - - return _error->Error(_("Unable to correct dependencies")); - } - if (pkgMinimizeUpgrade(*DCache) == false) - return _error->Error(_("Unable to minimize the upgrade set")); - - c1out << _(" Done") << endl; - } - else - { - c1out << _("You might want to run `apt-get -f install' to correct these.") << endl; - ShowBroken(c1out,*this,true); - - return _error->Error(_("Unmet dependencies. Try using -f.")); - } - - return true; -} - -static bool CheckAuth(pkgAcquire& Fetcher) -{ - string UntrustedList; - for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd(); ++I) - { - if (!(*I)->IsTrusted()) - { - UntrustedList += string((*I)->ShortDesc()) + " "; - } - } - - if (UntrustedList == "") - { - return true; - } - - ShowList(c2out,_("WARNING: The following packages cannot be authenticated!"),UntrustedList,""); - - if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true) - { - c2out << _("Authentication warning overridden.\n"); - return true; - } - - if (_config->FindI("quiet",0) < 2 - && _config->FindB("APT::Get::Assume-Yes",false) == false) - { - c2out << _("Install these packages without verification [y/N]? ") << flush; - if (!YnPrompt(false)) - return _error->Error(_("Some packages could not be authenticated")); - - return true; - } - else if (_config->FindB("APT::Get::Force-Yes",false) == true) - { - return true; - } - - return _error->Error(_("There are problems and -y was used without --force-yes")); -} - - - /*}}}*/ - -// InstallPackages - Actually download and install the packages /*{{{*/ -// --------------------------------------------------------------------- -/* This displays the informative messages describing what is going to - happen and then calls the download routines */ -bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, - bool Safety = true) -{ - if (_config->FindB("APT::Get::Purge",false) == true) - { - pkgCache::PkgIterator I = Cache->PkgBegin(); - for (; I.end() == false; I++) - { - if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete) - Cache->MarkDelete(I,true); - } - } - - bool Fail = false; - bool Essential = false; - - // Show all the various warning indicators - ShowDel(c1out,Cache); - ShowNew(c1out,Cache); - if (ShwKept == true) - ShowKept(c1out,Cache); - Fail |= !ShowHold(c1out,Cache); - if (_config->FindB("APT::Get::Show-Upgraded",true) == true) - ShowUpgraded(c1out,Cache); - Fail |= !ShowDowngraded(c1out,Cache); - if (_config->FindB("APT::Get::Download-Only",false) == false) - Essential = !ShowEssential(c1out,Cache); - Fail |= Essential; - Stats(c1out,Cache); - - // Sanity check - if (Cache->BrokenCount() != 0) - { - ShowBroken(c1out,Cache,false); - return _error->Error(_("Internal error, InstallPackages was called with broken packages!")); - } - - if (Cache->DelCount() == 0 && Cache->InstCount() == 0 && - Cache->BadCount() == 0) - return true; - - // No remove flag - if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false) - return _error->Error(_("Packages need to be removed but remove is disabled.")); - - // Run the simulator .. - if (_config->FindB("APT::Get::Simulate") == true) - { - pkgSimulate PM(Cache); - int status_fd = _config->FindI("APT::Status-Fd",-1); - pkgPackageManager::OrderResult Res = PM.DoInstall(status_fd); - if (Res == pkgPackageManager::Failed) - return false; - if (Res != pkgPackageManager::Completed) - return _error->Error(_("Internal error, Ordering didn't finish")); - return true; - } - - // Create the text record parser - pkgRecords Recs(Cache); - if (_error->PendingError() == true) - return false; - - // Lock the archive directory - FileFd Lock; - if (_config->FindB("Debug::NoLocking",false) == false && - _config->FindB("APT::Get::Print-URIs") == false) - { - Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock")); - if (_error->PendingError() == true) - return _error->Error(_("Unable to lock the download directory")); - } - - // Create the download object - AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); - pkgAcquire Fetcher(&Stat); - - // Read the source list - pkgSourceList List; - if (List.ReadMainList() == false) - return _error->Error(_("The list of sources could not be read.")); - - // Create the package manager and prepare to download - SPtr PM= _system->CreatePM(Cache); - if (PM->GetArchives(&Fetcher,&List,&Recs) == false || - _error->PendingError() == true) - return false; - - // Display statistics - double FetchBytes = Fetcher.FetchNeeded(); - double FetchPBytes = Fetcher.PartialPresent(); - double DebBytes = Fetcher.TotalNeeded(); - if (DebBytes != Cache->DebSize()) - { - c0out << DebBytes << ',' << Cache->DebSize() << endl; - c0out << _("How odd.. The sizes didn't match, email apt@packages.debian.org") << endl; - } - - // Number of bytes - if (DebBytes != FetchBytes) - ioprintf(c1out,_("Need to get %sB/%sB of archives.\n"), - SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str()); - else if (DebBytes != 0) - ioprintf(c1out,_("Need to get %sB of archives.\n"), - SizeToStr(DebBytes).c_str()); - - // Size delta - if (Cache->UsrSize() >= 0) - ioprintf(c1out,_("After this operation, %sB of additional disk space will be used.\n"), - SizeToStr(Cache->UsrSize()).c_str()); - else - ioprintf(c1out,_("After this operation, %sB disk space will be freed.\n"), - SizeToStr(-1*Cache->UsrSize()).c_str()); - - if (_error->PendingError() == true) - return false; - - /* Check for enough free space, but only if we are actually going to - download */ - if (_config->FindB("APT::Get::Print-URIs") == false && - _config->FindB("APT::Get::Download",true) == true) - { - struct statvfs Buf; - string OutputDir = _config->FindDir("Dir::Cache::Archives"); - if (statvfs(OutputDir.c_str(),&Buf) != 0) - return _error->Errno("statvfs",_("Couldn't determine free space in %s"), - OutputDir.c_str()); - if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize) - { - struct statfs Stat; - if (statfs(OutputDir.c_str(),&Stat) != 0 || - unsigned(Stat.f_type) != RAMFS_MAGIC) - return _error->Error(_("You don't have enough free space in %s."), - OutputDir.c_str()); - } - } - - // Fail safe check - if (_config->FindI("quiet",0) >= 2 || - _config->FindB("APT::Get::Assume-Yes",false) == true) - { - if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false) - return _error->Error(_("There are problems and -y was used without --force-yes")); - } - - if (Essential == true && Safety == true) - { - if (_config->FindB("APT::Get::Trivial-Only",false) == true) - return _error->Error(_("Trivial Only specified but this is not a trivial operation.")); - - const char *Prompt = _("Yes, do as I say!"); - ioprintf(c2out, - _("You are about to do something potentially harmful.\n" - "To continue type in the phrase '%s'\n" - " ?] "),Prompt); - c2out << flush; - if (AnalPrompt(Prompt) == false) - { - c2out << _("Abort.") << endl; - exit(1); - } - } - else - { - // Prompt to continue - if (Ask == true || Fail == true) - { - if (_config->FindB("APT::Get::Trivial-Only",false) == true) - return _error->Error(_("Trivial Only specified but this is not a trivial operation.")); - - if (_config->FindI("quiet",0) < 2 && - _config->FindB("APT::Get::Assume-Yes",false) == false) - { - c2out << _("Do you want to continue [Y/n]? ") << flush; - - if (YnPrompt() == false) - { - c2out << _("Abort.") << endl; - exit(1); - } - } - } - } - - // Just print out the uris an exit if the --print-uris flag was used - if (_config->FindB("APT::Get::Print-URIs") == true) - { - pkgAcquire::UriIterator I = Fetcher.UriBegin(); - for (; I != Fetcher.UriEnd(); I++) - cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << - I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl; - return true; - } - - if (!CheckAuth(Fetcher)) - return false; - - /* Unlock the dpkg lock if we are not going to be doing an install - after. */ - if (_config->FindB("APT::Get::Download-Only",false) == true) - _system->UnLock(); - - // Run it - while (1) - { - bool Transient = false; - if (_config->FindB("APT::Get::Download",true) == false) - { - for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();) - { - if ((*I)->Local == true) - { - I++; - continue; - } - - // Close the item and check if it was found in cache - (*I)->Finished(); - if ((*I)->Complete == false) - Transient = true; - - // Clear it out of the fetch list - delete *I; - I = Fetcher.ItemsBegin(); - } - } - - if (Fetcher.Run() == pkgAcquire::Failed) - return false; - - // Print out errors - bool Failed = false; - for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++) - { - if ((*I)->Status == pkgAcquire::Item::StatDone && - (*I)->Complete == true) - continue; - - if ((*I)->Status == pkgAcquire::Item::StatIdle) - { - Transient = true; - // Failed = true; - continue; - } - - fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(), - (*I)->ErrorText.c_str()); - Failed = true; - } - - /* If we are in no download mode and missing files and there were - 'failures' then the user must specify -m. Furthermore, there - is no such thing as a transient error in no-download mode! */ - if (Transient == true && - _config->FindB("APT::Get::Download",true) == false) - { - Transient = false; - Failed = true; - } - - if (_config->FindB("APT::Get::Download-Only",false) == true) - { - if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false) - return _error->Error(_("Some files failed to download")); - c1out << _("Download complete and in download only mode") << endl; - return true; - } - - if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false) - { - return _error->Error(_("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?")); - } - - if (Transient == true && Failed == true) - return _error->Error(_("--fix-missing and media swapping is not currently supported")); - - // Try to deal with missing package files - if (Failed == true && PM->FixMissing() == false) - { - cerr << _("Unable to correct missing packages.") << endl; - return _error->Error(_("Aborting install.")); - } - - _system->UnLock(); - int status_fd = _config->FindI("APT::Status-Fd",-1); - pkgPackageManager::OrderResult Res = PM->DoInstall(status_fd); - if (Res == pkgPackageManager::Failed || _error->PendingError() == true) - return false; - if (Res == pkgPackageManager::Completed) - return true; - - // Reload the fetcher object and loop again for media swapping - Fetcher.Shutdown(); - if (PM->GetArchives(&Fetcher,&List,&Recs) == false) - return false; - - _system->Lock(); - } -} - /*}}}*/ -// TryToInstall - Try to install a single package /*{{{*/ -// --------------------------------------------------------------------- -/* This used to be inlined in DoInstall, but with the advent of regex package - name matching it was split out.. */ -bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, - pkgProblemResolver &Fix,bool Remove,bool BrokenFix, - unsigned int &ExpectedInst,bool AllowFail = true) -{ - /* This is a pure virtual package and there is a single available - provides */ - if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0 && - Pkg.ProvidesList()->NextProvides == 0) - { - pkgCache::PkgIterator Tmp = Pkg.ProvidesList().OwnerPkg(); - ioprintf(c1out,_("Note, selecting %s instead of %s\n"), - Tmp.Name(),Pkg.Name()); - Pkg = Tmp; - } - - // Handle the no-upgrade case - if (_config->FindB("APT::Get::upgrade",true) == false && - Pkg->CurrentVer != 0) - { - if (AllowFail == true) - ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"), - Pkg.Name()); - return true; - } - - // Check if there is something at all to install - pkgDepCache::StateCache &State = Cache[Pkg]; - if (Remove == true && Pkg->CurrentVer == 0) - { - Fix.Clear(Pkg); - Fix.Protect(Pkg); - Fix.Remove(Pkg); - - /* We want to continue searching for regex hits, so we return false here - otherwise this is not really an error. */ - if (AllowFail == false) - return false; - - ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.Name()); - return true; - } - - if (State.CandidateVer == 0 && Remove == false) - { - if (AllowFail == false) - return false; - - if (Pkg->ProvidesList != 0) - { - ioprintf(c1out,_("Package %s is a virtual package provided by:\n"), - Pkg.Name()); - - pkgCache::PrvIterator I = Pkg.ProvidesList(); - for (; I.end() == false; I++) - { - pkgCache::PkgIterator Pkg = I.OwnerPkg(); - - if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer()) - { - if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false) - c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << - _(" [Installed]") << endl; - else - c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl; - } - } - c1out << _("You should explicitly select one to install.") << endl; - } - else - { - ioprintf(c1out, - _("Package %s is not available, but is referred to by another package.\n" - "This may mean that the package is missing, has been obsoleted, or\n" - "is only available from another source\n"),Pkg.Name()); - - string List; - string VersionsList; - SPtrArray Seen = new bool[Cache.Head().PackageCount]; - memset(Seen,0,Cache.Head().PackageCount*sizeof(*Seen)); - pkgCache::DepIterator Dep = Pkg.RevDependsList(); - for (; Dep.end() == false; Dep++) - { - if (Dep->Type != pkgCache::Dep::Replaces) - continue; - if (Seen[Dep.ParentPkg()->ID] == true) - continue; - Seen[Dep.ParentPkg()->ID] = true; - List += string(Dep.ParentPkg().Name()) + " "; - //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ??? - } - ShowList(c1out,_("However the following packages replace it:"),List,VersionsList); - } - - _error->Error(_("Package %s has no installation candidate"),Pkg.Name()); - return false; - } - - Fix.Clear(Pkg); - Fix.Protect(Pkg); - if (Remove == true) - { - Fix.Remove(Pkg); - Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false)); - return true; - } - - // Install it - Cache.MarkInstall(Pkg,false); - if (State.Install() == false) - { - if (_config->FindB("APT::Get::ReInstall",false) == true) - { - if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false) - ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"), - Pkg.Name()); - else - Cache.SetReInstall(Pkg,true); - } - else - { - if (AllowFail == true) - ioprintf(c1out,_("%s is already the newest version.\n"), - Pkg.Name()); - } - } - else - ExpectedInst++; - - // Install it with autoinstalling enabled (if we not respect the minial - // required deps or the policy) - if ((State.InstBroken() == true || State.InstPolicyBroken() == true) && BrokenFix == false) - Cache.MarkInstall(Pkg,true); - - return true; -} - /*}}}*/ -// TryToChangeVer - Try to change a candidate version /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool TryToChangeVer(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, - const char *VerTag,bool IsRel) -{ - pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release : - pkgVersionMatch::Version)); - - pkgCache::VerIterator Ver = Match.Find(Pkg); - - if (Ver.end() == true) - { - if (IsRel == true) - return _error->Error(_("Release '%s' for '%s' was not found"), - VerTag,Pkg.Name()); - return _error->Error(_("Version '%s' for '%s' was not found"), - VerTag,Pkg.Name()); - } - - if (strcmp(VerTag,Ver.VerStr()) != 0) - { - ioprintf(c1out,_("Selected version %s (%s) for %s\n"), - Ver.VerStr(),Ver.RelStr().c_str(),Pkg.Name()); - } - - Cache.SetCandidateVersion(Ver); - return true; -} - /*}}}*/ -// FindSrc - Find a source record /*{{{*/ -// --------------------------------------------------------------------- -/* */ -pkgSrcRecords::Parser *FindSrc(const char *Name,pkgRecords &Recs, - pkgSrcRecords &SrcRecs,string &Src, - pkgDepCache &Cache) -{ - // We want to pull the version off the package specification.. - string VerTag; - string TmpSrc = Name; - string::size_type Slash = TmpSrc.rfind('='); - - // honor default release - string DefRel = _config->Find("APT::Default-Release"); - pkgCache::PkgIterator Pkg = Cache.FindPkg(TmpSrc); - - if (Slash != string::npos) - { - VerTag = string(TmpSrc.begin() + Slash + 1,TmpSrc.end()); - TmpSrc = string(TmpSrc.begin(),TmpSrc.begin() + Slash); - } - else if(!Pkg.end() && DefRel.empty() == false) - { - // we have a default release, try to locate the pkg. we do it like - // this because GetCandidateVer() will not "downgrade", that means - // "apt-get source -t stable apt" won't work on a unstable system - for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; - Ver++) - { - for (pkgCache::VerFileIterator VF = Ver.FileList(); VF.end() == false; - VF++) - { - /* If this is the status file, and the current version is not the - version in the status file (ie it is not installed, or somesuch) - then it is not a candidate for installation, ever. This weeds - out bogus entries that may be due to config-file states, or - other. */ - if ((VF.File()->Flags & pkgCache::Flag::NotSource) == - pkgCache::Flag::NotSource && Pkg.CurrentVer() != Ver) - continue; - - //std::cout << VF.File().Archive() << std::endl; - if(VF.File().Archive() && (VF.File().Archive() == DefRel)) - { - VerTag = Ver.VerStr(); - break; - } - } - } - } - - /* Lookup the version of the package we would install if we were to - install a version and determine the source package name, then look - in the archive for a source package of the same name. */ - if (_config->FindB("APT::Get::Only-Source") == false) - { - if (Pkg.end() == false) - { - pkgCache::VerIterator Ver = Cache.GetCandidateVer(Pkg); - if (Ver.end() == false) - { - pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); - Src = Parse.SourcePkg(); - } - } - } - - // No source package name.. - if (Src.empty() == true) - Src = TmpSrc; - - // The best hit - pkgSrcRecords::Parser *Last = 0; - unsigned long Offset = 0; - string Version; - bool IsMatch = false; - - // If we are matching by version then we need exact matches to be happy - if (VerTag.empty() == false) - IsMatch = true; - - /* Iterate over all of the hits, which includes the resulting - binary packages in the search */ - pkgSrcRecords::Parser *Parse; - SrcRecs.Restart(); - while ((Parse = SrcRecs.Find(Src.c_str(),false)) != 0) - { - string Ver = Parse->Version(); - - // Skip name mismatches - if (IsMatch == true && Parse->Package() != Src) - continue; - - if (VerTag.empty() == false) - { - /* Don't want to fall through because we are doing exact version - matching. */ - if (Cache.VS().CmpVersion(VerTag,Ver) != 0) - continue; - - Last = Parse; - Offset = Parse->Offset(); - break; - } - - // Newer version or an exact match - if (Last == 0 || Cache.VS().CmpVersion(Version,Ver) < 0 || - (Parse->Package() == Src && IsMatch == false)) - { - IsMatch = Parse->Package() == Src; - Last = Parse; - Offset = Parse->Offset(); - Version = Ver; - } - } - - if (Last == 0 || Last->Jump(Offset) == false) - return 0; - - return Last; -} - /*}}}*/ - -// DoUpdate - Update the package lists /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool DoUpdate(CommandLine &CmdL) -{ - if (CmdL.FileSize() != 1) - return _error->Error(_("The update command takes no arguments")); - - // Get the source list - pkgSourceList List; - if (List.ReadMainList() == false) - return false; - - // Lock the list directory - FileFd Lock; - if (_config->FindB("Debug::NoLocking",false) == false) - { - Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock")); - if (_error->PendingError() == true) - return _error->Error(_("Unable to lock the list directory")); - } - - // Create the progress - AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); - - // Just print out the uris an exit if the --print-uris flag was used - if (_config->FindB("APT::Get::Print-URIs") == true) - { - // get a fetcher - pkgAcquire Fetcher(&Stat); - - // Populate it with the source selection and get all Indexes - // (GetAll=true) - if (List.GetIndexes(&Fetcher,true) == false) - return false; - - pkgAcquire::UriIterator I = Fetcher.UriBegin(); - for (; I != Fetcher.UriEnd(); I++) - cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << - I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl; - return true; - } - - // do the work - CacheFile Cache; - if (_config->FindB("APT::Get::Download",true) == true) - ListUpdate(Stat, List); - - // Rebuild the cache. - if (Cache.BuildCaches() == false) - return false; - - return true; -} - /*}}}*/ -// DoAutomaticRemove - Remove all automatic unused packages /*{{{*/ -// --------------------------------------------------------------------- -/* Remove unused automatic packages */ -bool DoAutomaticRemove(CacheFile &Cache) -{ - bool Debug = _config->FindI("Debug::pkgAutoRemove",false); - bool doAutoRemove = _config->FindB("APT::Get::AutomaticRemove", false); - bool hideAutoRemove = _config->FindB("APT::Get::HideAutoRemove"); - pkgDepCache::ActionGroup group(*Cache); - - if(Debug) - std::cout << "DoAutomaticRemove()" << std::endl; - - if (_config->FindB("APT::Get::Remove",true) == false && - doAutoRemove == true) - { - c1out << _("We are not supposed to delete stuff, can't start " - "AutoRemover") << std::endl; - doAutoRemove = false; - } - - string autoremovelist, autoremoveversions; - // look over the cache to see what can be removed - for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); ! Pkg.end(); ++Pkg) - { - if (Cache[Pkg].Garbage) - { - if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install()) - if(Debug) - std::cout << "We could delete %s" << Pkg.Name() << std::endl; - - // only show stuff in the list that is not yet marked for removal - if(Cache[Pkg].Delete() == false) - { - autoremovelist += string(Pkg.Name()) + " "; - autoremoveversions += string(Cache[Pkg].CandVersion) + "\n"; - } - if (doAutoRemove) - { - if(Pkg.CurrentVer() != 0 && - Pkg->CurrentState != pkgCache::State::ConfigFiles) - Cache->MarkDelete(Pkg, _config->FindB("APT::Get::Purge", false)); - else - Cache->MarkKeep(Pkg, false, false); - } - } - } - if (!hideAutoRemove) - ShowList(c1out, _("The following packages were automatically installed and are no longer required:"), autoremovelist, autoremoveversions); - if (!doAutoRemove && !hideAutoRemove && autoremovelist.size() > 0) - c1out << _("Use 'apt-get autoremove' to remove them.") << std::endl; - - // Now see if we destroyed anything - if (Cache->BrokenCount() != 0) - { - c1out << _("Hmm, seems like the AutoRemover destroyed something which really\n" - "shouldn't happen. Please file a bug report against apt.") << endl; - c1out << endl; - c1out << _("The following information may help to resolve the situation:") << endl; - c1out << endl; - ShowBroken(c1out,Cache,false); - - return _error->Error(_("Internal Error, AutoRemover broke stuff")); - } - return true; -} - -// DoUpgrade - Upgrade all packages /*{{{*/ -// --------------------------------------------------------------------- -/* Upgrade all packages without installing new packages or erasing old - packages */ -bool DoUpgrade(CommandLine &CmdL) -{ - CacheFile Cache; - if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false) - return false; - - // Do the upgrade - if (pkgAllUpgrade(Cache) == false) - { - ShowBroken(c1out,Cache,false); - return _error->Error(_("Internal error, AllUpgrade broke stuff")); - } - - return InstallPackages(Cache,true); -} - /*}}}*/ -// DoInstallTask - Install task from the command line /*{{{*/ -// --------------------------------------------------------------------- -/* Install named task */ -bool TryInstallTask(pkgDepCache &Cache, pkgProblemResolver &Fix, - bool BrokenFix, - unsigned int& ExpectedInst, - const char *taskname, - bool Remove) -{ - const char *start, *end; - pkgCache::PkgIterator Pkg; - char buf[64*1024]; - regex_t Pattern; - - // get the records - pkgRecords Recs(Cache); - - // build regexp for the task - char S[300]; - snprintf(S, sizeof(S), "^Task:.*[, ]%s([, ]|$)", taskname); - if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0) - return _error->Error("Failed to compile task regexp"); - - bool found = false; - bool res = true; - - // two runs, first ignore dependencies, second install any missing - for(int IgnoreBroken=1; IgnoreBroken >= 0; IgnoreBroken--) - { - for (Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) - { - pkgCache::VerIterator ver = Cache[Pkg].CandidateVerIter(Cache); - if(ver.end()) - continue; - pkgRecords::Parser &parser = Recs.Lookup(ver.FileList()); - parser.GetRec(start,end); - strncpy(buf, start, end-start); - buf[end-start] = 0x0; - if (regexec(&Pattern,buf,0,0,0) != 0) - continue; - res &= TryToInstall(Pkg,Cache,Fix,Remove,IgnoreBroken,ExpectedInst); - found = true; - } - } - - // now let the problem resolver deal with any issues - Fix.Resolve(true); - - if(!found) - _error->Error(_("Couldn't find task %s"),taskname); - - regfree(&Pattern); - return res; -} - -// DoInstall - Install packages from the command line /*{{{*/ -// --------------------------------------------------------------------- -/* Install named packages */ -bool DoInstall(CommandLine &CmdL) -{ - CacheFile Cache; - if (Cache.OpenForInstall() == false || - Cache.CheckDeps(CmdL.FileSize() != 1) == false) - return false; - - // Enter the special broken fixing mode if the user specified arguments - bool BrokenFix = false; - if (Cache->BrokenCount() != 0) - BrokenFix = true; - - unsigned int AutoMarkChanged = 0; - unsigned int ExpectedInst = 0; - unsigned int Packages = 0; - pkgProblemResolver Fix(Cache); - - bool DefRemove = false; - if (strcasecmp(CmdL.FileList[0],"remove") == 0) - DefRemove = true; - else if (strcasecmp(CmdL.FileList[0], "purge") == 0) - { - _config->Set("APT::Get::Purge", true); - DefRemove = true; - } - else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0) - { - _config->Set("APT::Get::AutomaticRemove", "true"); - DefRemove = true; - } - // new scope for the ActionGroup - { - pkgDepCache::ActionGroup group(Cache); - for (const char **I = CmdL.FileList + 1; *I != 0; I++) - { - // Duplicate the string - unsigned int Length = strlen(*I); - char S[300]; - if (Length >= sizeof(S)) - continue; - strcpy(S,*I); - - // See if we are removing and special indicators.. - bool Remove = DefRemove; - char *VerTag = 0; - bool VerIsRel = false; - - // this is a task! - if (Length >= 1 && S[Length - 1] == '^') - { - S[--Length] = 0; - // tasks must always be confirmed - ExpectedInst += 1000; - // see if we can install it - TryInstallTask(Cache, Fix, BrokenFix, ExpectedInst, S, Remove); - continue; - } - - while (Cache->FindPkg(S).end() == true) - { - // Handle an optional end tag indicating what to do - if (Length >= 1 && S[Length - 1] == '-') - { - Remove = true; - S[--Length] = 0; - continue; - } - - if (Length >= 1 && S[Length - 1] == '+') - { - Remove = false; - S[--Length] = 0; - continue; - } - - char *Slash = strchr(S,'='); - if (Slash != 0) - { - VerIsRel = false; - *Slash = 0; - VerTag = Slash + 1; - } - - Slash = strchr(S,'/'); - if (Slash != 0) - { - VerIsRel = true; - *Slash = 0; - VerTag = Slash + 1; - } - - break; - } - - // Locate the package - pkgCache::PkgIterator Pkg = Cache->FindPkg(S); - Packages++; - if (Pkg.end() == true) - { - // Check if the name is a regex - const char *I; - for (I = S; *I != 0; I++) - if (*I == '?' || *I == '*' || *I == '|' || - *I == '[' || *I == '^' || *I == '$') - break; - if (*I == 0) - return _error->Error(_("Couldn't find package %s"),S); - - // Regexs must always be confirmed - ExpectedInst += 1000; - - // Compile the regex pattern - regex_t Pattern; - int Res; - if ((Res = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE | - REG_NOSUB)) != 0) - { - char Error[300]; - regerror(Res,&Pattern,Error,sizeof(Error)); - return _error->Error(_("Regex compilation error - %s"),Error); - } - - // Run over the matches - bool Hit = false; - for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++) - { - if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0) - continue; - - ioprintf(c1out,_("Note, selecting %s for regex '%s'\n"), - Pkg.Name(),S); - - if (VerTag != 0) - if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false) - return false; - - Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix, - ExpectedInst,false); - } - regfree(&Pattern); - - if (Hit == false) - return _error->Error(_("Couldn't find package %s"),S); - } - else - { - if (VerTag != 0) - if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false) - return false; - if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false) - return false; - - // see if we need to fix the auto-mark flag - // e.g. apt-get install foo - // where foo is marked automatic - if(!Remove && - Cache[Pkg].Install() == false && - (Cache[Pkg].Flags & pkgCache::Flag::Auto) && - _config->FindB("APT::Get::ReInstall",false) == false) - { - ioprintf(c1out,_("%s set to manually installed.\n"), - Pkg.Name()); - Cache->MarkAuto(Pkg,false); - AutoMarkChanged++; - } - } - } - - /* If we are in the Broken fixing mode we do not attempt to fix the - problems. This is if the user invoked install without -f and gave - packages */ - if (BrokenFix == true && Cache->BrokenCount() != 0) - { - c1out << _("You might want to run `apt-get -f install' to correct these:") << endl; - ShowBroken(c1out,Cache,false); - - return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).")); - } - - // Call the scored problem resolver - Fix.InstallProtect(); - if (Fix.Resolve(true) == false) - _error->Discard(); - - // Now we check the state of the packages, - if (Cache->BrokenCount() != 0) - { - c1out << - _("Some packages could not be installed. This may mean that you have\n" - "requested an impossible situation or if you are using the unstable\n" - "distribution that some required packages have not yet been created\n" - "or been moved out of Incoming.") << endl; - /* - if (Packages == 1) - { - c1out << endl; - c1out << - _("Since you only requested a single operation it is extremely likely that\n" - "the package is simply not installable and a bug report against\n" - "that package should be filed.") << endl; - } - */ - - c1out << _("The following information may help to resolve the situation:") << endl; - c1out << endl; - ShowBroken(c1out,Cache,false); - return _error->Error(_("Broken packages")); - } - } - if (!DoAutomaticRemove(Cache)) - return false; - - /* Print out a list of packages that are going to be installed extra - to what the user asked */ - if (Cache->InstCount() != ExpectedInst) - { - string List; - string VersionsList; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator I(Cache,Cache.List[J]); - if ((*Cache)[I].Install() == false) - continue; - - const char **J; - for (J = CmdL.FileList + 1; *J != 0; J++) - if (strcmp(*J,I.Name()) == 0) - break; - - if (*J == 0) { - List += string(I.Name()) + " "; - VersionsList += string(Cache[I].CandVersion) + "\n"; - } - } - - ShowList(c1out,_("The following extra packages will be installed:"),List,VersionsList); - } - - /* Print out a list of suggested and recommended packages */ - { - string SuggestsList, RecommendsList, List; - string SuggestsVersions, RecommendsVersions; - for (unsigned J = 0; J < Cache->Head().PackageCount; J++) - { - pkgCache::PkgIterator Pkg(Cache,Cache.List[J]); - - /* Just look at the ones we want to install */ - if ((*Cache)[Pkg].Install() == false) - continue; - - // get the recommends/suggests for the candidate ver - pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache); - for (pkgCache::DepIterator D = CV.DependsList(); D.end() == false; ) - { - pkgCache::DepIterator Start; - pkgCache::DepIterator End; - D.GlobOr(Start,End); // advances D - - // FIXME: we really should display a or-group as a or-group to the user - // the problem is that ShowList is incapable of doing this - string RecommendsOrList,RecommendsOrVersions; - string SuggestsOrList,SuggestsOrVersions; - bool foundInstalledInOrGroup = false; - for(;;) - { - /* Skip if package is installed already, or is about to be */ - string target = string(Start.TargetPkg().Name()) + " "; - - if ((*Start.TargetPkg()).SelectedState == pkgCache::State::Install - || Cache[Start.TargetPkg()].Install()) - { - foundInstalledInOrGroup=true; - break; - } - - /* Skip if we already saw it */ - if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1) - { - foundInstalledInOrGroup=true; - break; - } - - // this is a dep on a virtual pkg, check if any package that provides it - // should be installed - if(Start.TargetPkg().ProvidesList() != 0) - { - pkgCache::PrvIterator I = Start.TargetPkg().ProvidesList(); - for (; I.end() == false; I++) - { - pkgCache::PkgIterator Pkg = I.OwnerPkg(); - if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer() && - Pkg.CurrentVer() != 0) - foundInstalledInOrGroup=true; - } - } - - if (Start->Type == pkgCache::Dep::Suggests) - { - SuggestsOrList += target; - SuggestsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n"; - } - - if (Start->Type == pkgCache::Dep::Recommends) - { - RecommendsOrList += target; - RecommendsOrVersions += string(Cache[Start.TargetPkg()].CandVersion) + "\n"; - } - - if (Start >= End) - break; - Start++; - } - - if(foundInstalledInOrGroup == false) - { - RecommendsList += RecommendsOrList; - RecommendsVersions += RecommendsOrVersions; - SuggestsList += SuggestsOrList; - SuggestsVersions += SuggestsOrVersions; - } - - } - } - - ShowList(c1out,_("Suggested packages:"),SuggestsList,SuggestsVersions); - ShowList(c1out,_("Recommended packages:"),RecommendsList,RecommendsVersions); - - } - - // if nothing changed in the cache, but only the automark information - // we write the StateFile here, otherwise it will be written in - // cache.commit() - if (AutoMarkChanged > 0 && - Cache->DelCount() == 0 && Cache->InstCount() == 0 && - Cache->BadCount() == 0) - Cache->writeStateFile(NULL); - - // See if we need to prompt - if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0) - return InstallPackages(Cache,false,false); - - return InstallPackages(Cache,false); -} - /*}}}*/ -// DoDistUpgrade - Automatic smart upgrader /*{{{*/ -// --------------------------------------------------------------------- -/* Intelligent upgrader that will install and remove packages at will */ -bool DoDistUpgrade(CommandLine &CmdL) -{ - CacheFile Cache; - if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false) - return false; - - c0out << _("Calculating upgrade... ") << flush; - if (pkgDistUpgrade(*Cache) == false) - { - c0out << _("Failed") << endl; - ShowBroken(c1out,Cache,false); - return false; - } - - c0out << _("Done") << endl; - - return InstallPackages(Cache,true); -} - /*}}}*/ -// DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/ -// --------------------------------------------------------------------- -/* Follows dselect's selections */ -bool DoDSelectUpgrade(CommandLine &CmdL) -{ - CacheFile Cache; - if (Cache.OpenForInstall() == false || Cache.CheckDeps() == false) - return false; - - pkgDepCache::ActionGroup group(Cache); - - // Install everything with the install flag set - pkgCache::PkgIterator I = Cache->PkgBegin(); - for (;I.end() != true; I++) - { - /* Install the package only if it is a new install, the autoupgrader - will deal with the rest */ - if (I->SelectedState == pkgCache::State::Install) - Cache->MarkInstall(I,false); - } - - /* Now install their deps too, if we do this above then order of - the status file is significant for | groups */ - for (I = Cache->PkgBegin();I.end() != true; I++) - { - /* Install the package only if it is a new install, the autoupgrader - will deal with the rest */ - if (I->SelectedState == pkgCache::State::Install) - Cache->MarkInstall(I,true); - } - - // Apply erasures now, they override everything else. - for (I = Cache->PkgBegin();I.end() != true; I++) - { - // Remove packages - if (I->SelectedState == pkgCache::State::DeInstall || - I->SelectedState == pkgCache::State::Purge) - Cache->MarkDelete(I,I->SelectedState == pkgCache::State::Purge); - } - - /* Resolve any problems that dselect created, allupgrade cannot handle - such things. We do so quite agressively too.. */ - if (Cache->BrokenCount() != 0) - { - pkgProblemResolver Fix(Cache); - - // Hold back held packages. - if (_config->FindB("APT::Ignore-Hold",false) == false) - { - for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; I++) - { - if (I->SelectedState == pkgCache::State::Hold) - { - Fix.Protect(I); - Cache->MarkKeep(I); - } - } - } - - if (Fix.Resolve() == false) - { - ShowBroken(c1out,Cache,false); - return _error->Error(_("Internal error, problem resolver broke stuff")); - } - } - - // Now upgrade everything - if (pkgAllUpgrade(Cache) == false) - { - ShowBroken(c1out,Cache,false); - return _error->Error(_("Internal error, problem resolver broke stuff")); - } - - return InstallPackages(Cache,false); -} - /*}}}*/ -// DoClean - Remove download archives /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool DoClean(CommandLine &CmdL) -{ - if (_config->FindB("APT::Get::Simulate") == true) - { - cout << "Del " << _config->FindDir("Dir::Cache::archives") << "* " << - _config->FindDir("Dir::Cache::archives") << "partial/*" << endl; - return true; - } - - // Lock the archive directory - FileFd Lock; - if (_config->FindB("Debug::NoLocking",false) == false) - { - Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock")); - if (_error->PendingError() == true) - return _error->Error(_("Unable to lock the download directory")); - } - - pkgAcquire Fetcher; - Fetcher.Clean(_config->FindDir("Dir::Cache::archives")); - Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/"); - return true; -} - /*}}}*/ -// DoAutoClean - Smartly remove downloaded archives /*{{{*/ -// --------------------------------------------------------------------- -/* This is similar to clean but it only purges things that cannot be - downloaded, that is old versions of cached packages. */ -class LogCleaner : public pkgArchiveCleaner -{ - protected: - virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St) - { - c1out << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "B]" << endl; - - if (_config->FindB("APT::Get::Simulate") == false) - unlink(File); - }; -}; - -bool DoAutoClean(CommandLine &CmdL) -{ - // Lock the archive directory - FileFd Lock; - if (_config->FindB("Debug::NoLocking",false) == false) - { - Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock")); - if (_error->PendingError() == true) - return _error->Error(_("Unable to lock the download directory")); - } - - CacheFile Cache; - if (Cache.Open() == false) - return false; - - LogCleaner Cleaner; - - return Cleaner.Go(_config->FindDir("Dir::Cache::archives"),*Cache) && - Cleaner.Go(_config->FindDir("Dir::Cache::archives") + "partial/",*Cache); -} - /*}}}*/ -// DoCheck - Perform the check operation /*{{{*/ -// --------------------------------------------------------------------- -/* Opening automatically checks the system, this command is mostly used - for debugging */ -bool DoCheck(CommandLine &CmdL) -{ - CacheFile Cache; - Cache.Open(); - Cache.CheckDeps(); - - return true; -} - /*}}}*/ -// DoSource - Fetch a source archive /*{{{*/ -// --------------------------------------------------------------------- -/* Fetch souce packages */ -struct DscFile -{ - string Package; - string Version; - string Dsc; -}; - -bool DoSource(CommandLine &CmdL) -{ - CacheFile Cache; - if (Cache.Open(false) == false) - return false; - - if (CmdL.FileSize() <= 1) - return _error->Error(_("Must specify at least one package to fetch source for")); - - // Read the source list - pkgSourceList List; - if (List.ReadMainList() == false) - return _error->Error(_("The list of sources could not be read.")); - - // Create the text record parsers - pkgRecords Recs(Cache); - pkgSrcRecords SrcRecs(List); - if (_error->PendingError() == true) - return false; - - // Create the download object - AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); - pkgAcquire Fetcher(&Stat); - - DscFile *Dsc = new DscFile[CmdL.FileSize()]; - - // insert all downloaded uris into this set to avoid downloading them - // twice - set queued; - // Load the requestd sources into the fetcher - unsigned J = 0; - for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) - { - string Src; - pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache); - - if (Last == 0) - return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); - - // Back track - vector Lst; - if (Last->Files(Lst) == false) - return false; - - // Load them into the fetcher - for (vector::const_iterator I = Lst.begin(); - I != Lst.end(); I++) - { - // Try to guess what sort of file it is we are getting. - if (I->Type == "dsc") - { - Dsc[J].Package = Last->Package(); - Dsc[J].Version = Last->Version(); - Dsc[J].Dsc = flNotDir(I->Path); - } - - // Diff only mode only fetches .diff files - if (_config->FindB("APT::Get::Diff-Only",false) == true && - I->Type != "diff") - continue; - - // Tar only mode only fetches .tar files - if (_config->FindB("APT::Get::Tar-Only",false) == true && - I->Type != "tar") - continue; - - // Dsc only mode only fetches .dsc files - if (_config->FindB("APT::Get::Dsc-Only",false) == true && - I->Type != "dsc") - continue; - - // don't download the same uri twice (should this be moved to - // the fetcher interface itself?) - if(queued.find(Last->Index().ArchiveURI(I->Path)) != queued.end()) - continue; - queued.insert(Last->Index().ArchiveURI(I->Path)); - - // check if we have a file with that md5 sum already localy - if(!I->MD5Hash.empty() && FileExists(flNotDir(I->Path))) - { - FileFd Fd(flNotDir(I->Path), FileFd::ReadOnly); - MD5Summation sum; - sum.AddFD(Fd.Fd(), Fd.Size()); - Fd.Close(); - if((string)sum.Result() == I->MD5Hash) - { - ioprintf(c1out,_("Skipping already downloaded file '%s'\n"), - flNotDir(I->Path).c_str()); - continue; - } - } - - new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path), - I->MD5Hash,I->Size, - Last->Index().SourceInfo(*Last,*I),Src); - } - } - - // Display statistics - double FetchBytes = Fetcher.FetchNeeded(); - double FetchPBytes = Fetcher.PartialPresent(); - double DebBytes = Fetcher.TotalNeeded(); - - // Check for enough free space - struct statvfs Buf; - string OutputDir = "."; - if (statvfs(OutputDir.c_str(),&Buf) != 0) - return _error->Errno("statvfs",_("Couldn't determine free space in %s"), - OutputDir.c_str()); - if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize) - { - struct statfs Stat; - if (statfs(OutputDir.c_str(),&Stat) != 0 || - unsigned(Stat.f_type) != RAMFS_MAGIC) - return _error->Error(_("You don't have enough free space in %s"), - OutputDir.c_str()); - } - - // Number of bytes - if (DebBytes != FetchBytes) - ioprintf(c1out,_("Need to get %sB/%sB of source archives.\n"), - SizeToStr(FetchBytes).c_str(),SizeToStr(DebBytes).c_str()); - else - ioprintf(c1out,_("Need to get %sB of source archives.\n"), - SizeToStr(DebBytes).c_str()); - - if (_config->FindB("APT::Get::Simulate",false) == true) - { - for (unsigned I = 0; I != J; I++) - ioprintf(cout,_("Fetch source %s\n"),Dsc[I].Package.c_str()); - return true; - } - - // Just print out the uris an exit if the --print-uris flag was used - if (_config->FindB("APT::Get::Print-URIs") == true) - { - pkgAcquire::UriIterator I = Fetcher.UriBegin(); - for (; I != Fetcher.UriEnd(); I++) - cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << - I->Owner->FileSize << ' ' << I->Owner->HashSum() << endl; - return true; - } - - // Run it - if (Fetcher.Run() == pkgAcquire::Failed) - return false; - - // Print error messages - bool Failed = false; - for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++) - { - if ((*I)->Status == pkgAcquire::Item::StatDone && - (*I)->Complete == true) - continue; - - fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(), - (*I)->ErrorText.c_str()); - Failed = true; - } - if (Failed == true) - return _error->Error(_("Failed to fetch some archives.")); - - if (_config->FindB("APT::Get::Download-only",false) == true) - { - c1out << _("Download complete and in download only mode") << endl; - return true; - } - - // Unpack the sources - pid_t Process = ExecFork(); - - if (Process == 0) - { - for (unsigned I = 0; I != J; I++) - { - string Dir = Dsc[I].Package + '-' + Cache->VS().UpstreamVersion(Dsc[I].Version.c_str()); - - // Diff only mode only fetches .diff files - if (_config->FindB("APT::Get::Diff-Only",false) == true || - _config->FindB("APT::Get::Tar-Only",false) == true || - Dsc[I].Dsc.empty() == true) - continue; - - // See if the package is already unpacked - struct stat Stat; - if (stat(Dir.c_str(),&Stat) == 0 && - S_ISDIR(Stat.st_mode) != 0) - { - ioprintf(c0out ,_("Skipping unpack of already unpacked source in %s\n"), - Dir.c_str()); - } - else - { - // Call dpkg-source - char S[500]; - snprintf(S,sizeof(S),"%s -x %s", - _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(), - Dsc[I].Dsc.c_str()); - if (system(S) != 0) - { - fprintf(stderr,_("Unpack command '%s' failed.\n"),S); - fprintf(stderr,_("Check if the 'dpkg-dev' package is installed.\n")); - _exit(1); - } - } - - // Try to compile it with dpkg-buildpackage - if (_config->FindB("APT::Get::Compile",false) == true) - { - // Call dpkg-buildpackage - char S[500]; - snprintf(S,sizeof(S),"cd %s && %s %s", - Dir.c_str(), - _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(), - _config->Find("DPkg::Build-Options","-b -uc").c_str()); - - if (system(S) != 0) - { - fprintf(stderr,_("Build command '%s' failed.\n"),S); - _exit(1); - } - } - } - - _exit(0); - } - - // Wait for the subprocess - int Status = 0; - while (waitpid(Process,&Status,0) != Process) - { - if (errno == EINTR) - continue; - return _error->Errno("waitpid","Couldn't wait for subprocess"); - } - - if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) - return _error->Error(_("Child process failed")); - - return true; -} - /*}}}*/ -// DoBuildDep - Install/removes packages to satisfy build dependencies /*{{{*/ -// --------------------------------------------------------------------- -/* This function will look at the build depends list of the given source - package and install the necessary packages to make it true, or fail. */ -bool DoBuildDep(CommandLine &CmdL) -{ - CacheFile Cache; - if (Cache.Open(true) == false) - return false; - - if (CmdL.FileSize() <= 1) - return _error->Error(_("Must specify at least one package to check builddeps for")); - - // Read the source list - pkgSourceList List; - if (List.ReadMainList() == false) - return _error->Error(_("The list of sources could not be read.")); - - // Create the text record parsers - pkgRecords Recs(Cache); - pkgSrcRecords SrcRecs(List); - if (_error->PendingError() == true) - return false; - - // Create the download object - AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); - pkgAcquire Fetcher(&Stat); - - unsigned J = 0; - for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) - { - string Src; - pkgSrcRecords::Parser *Last = FindSrc(*I,Recs,SrcRecs,Src,*Cache); - if (Last == 0) - return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); - - // Process the build-dependencies - vector BuildDeps; - if (Last->BuildDepends(BuildDeps, _config->FindB("APT::Get::Arch-Only",false)) == false) - return _error->Error(_("Unable to get build-dependency information for %s"),Src.c_str()); - - // Also ensure that build-essential packages are present - Configuration::Item const *Opts = _config->Tree("APT::Build-Essential"); - if (Opts) - Opts = Opts->Child; - for (; Opts; Opts = Opts->Next) - { - if (Opts->Value.empty() == true) - continue; - - pkgSrcRecords::Parser::BuildDepRec rec; - rec.Package = Opts->Value; - rec.Type = pkgSrcRecords::Parser::BuildDependIndep; - rec.Op = 0; - BuildDeps.push_back(rec); - } - - if (BuildDeps.size() == 0) - { - ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str()); - continue; - } - - // Install the requested packages - unsigned int ExpectedInst = 0; - vector ::iterator D; - pkgProblemResolver Fix(Cache); - bool skipAlternatives = false; // skip remaining alternatives in an or group - for (D = BuildDeps.begin(); D != BuildDeps.end(); D++) - { - bool hasAlternatives = (((*D).Op & pkgCache::Dep::Or) == pkgCache::Dep::Or); - - if (skipAlternatives == true) - { - if (!hasAlternatives) - skipAlternatives = false; // end of or group - continue; - } - - if ((*D).Type == pkgSrcRecords::Parser::BuildConflict || - (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep) - { - pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package); - // Build-conflicts on unknown packages are silently ignored - if (Pkg.end() == true) - continue; - - pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache); - - /* - * Remove if we have an installed version that satisfies the - * version criteria - */ - if (IV.end() == false && - Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true) - TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst); - } - else // BuildDep || BuildDepIndep - { - pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package); - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << "Looking for " << (*D).Package << "...\n"; - - if (Pkg.end() == true) - { - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " (not found)" << (*D).Package << endl; - - if (hasAlternatives) - continue; - - return _error->Error(_("%s dependency for %s cannot be satisfied " - "because the package %s cannot be found"), - Last->BuildDepType((*D).Type),Src.c_str(), - (*D).Package.c_str()); - } - - /* - * if there are alternatives, we've already picked one, so skip - * the rest - * - * TODO: this means that if there's a build-dep on A|B and B is - * installed, we'll still try to install A; more importantly, - * if A is currently broken, we cannot go back and try B. To fix - * this would require we do a Resolve cycle for each package we - * add to the install list. Ugh - */ - - /* - * If this is a virtual package, we need to check the list of - * packages that provide it and see if any of those are - * installed - */ - pkgCache::PrvIterator Prv = Pkg.ProvidesList(); - for (; Prv.end() != true; Prv++) - { - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " Checking provider " << Prv.OwnerPkg().Name() << endl; - - if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false) - break; - } - - // Get installed version and version we are going to install - pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache); - - if ((*D).Version[0] != '\0') { - // Versioned dependency - - pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache); - - for (; CV.end() != true; CV++) - { - if (Cache->VS().CheckDep(CV.VerStr(),(*D).Op,(*D).Version.c_str()) == true) - break; - } - if (CV.end() == true) - { - if (hasAlternatives) - { - continue; - } - else - { - return _error->Error(_("%s dependency for %s cannot be satisfied " - "because no available versions of package %s " - "can satisfy version requirements"), - Last->BuildDepType((*D).Type),Src.c_str(), - (*D).Package.c_str()); - } - } - } - else - { - // Only consider virtual packages if there is no versioned dependency - if (Prv.end() == false) - { - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " Is provided by installed package " << Prv.OwnerPkg().Name() << endl; - skipAlternatives = hasAlternatives; - continue; - } - } - - if (IV.end() == false) - { - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " Is installed\n"; - - if (Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true) - { - skipAlternatives = hasAlternatives; - continue; - } - - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " ...but the installed version doesn't meet the version requirement\n"; - - if (((*D).Op & pkgCache::Dep::LessEq) == pkgCache::Dep::LessEq) - { - return _error->Error(_("Failed to satisfy %s dependency for %s: Installed package %s is too new"), - Last->BuildDepType((*D).Type), - Src.c_str(), - Pkg.Name()); - } - } - - - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " Trying to install " << (*D).Package << endl; - - if (TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst) == true) - { - // We successfully installed something; skip remaining alternatives - skipAlternatives = hasAlternatives; - if(_config->FindB("APT::Get::Build-Dep-Automatic", false) == true) - Cache->MarkAuto(Pkg, true); - continue; - } - else if (hasAlternatives) - { - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " Unsatisfiable, trying alternatives\n"; - continue; - } - else - { - return _error->Error(_("Failed to satisfy %s dependency for %s: %s"), - Last->BuildDepType((*D).Type), - Src.c_str(), - (*D).Package.c_str()); - } - } - } - - Fix.InstallProtect(); - if (Fix.Resolve(true) == false) - _error->Discard(); - - // Now we check the state of the packages, - if (Cache->BrokenCount() != 0) - return _error->Error(_("Build-dependencies for %s could not be satisfied."),*I); - } - - if (InstallPackages(Cache, false, true) == false) - return _error->Error(_("Failed to process build dependencies")); - return true; -} - /*}}}*/ - -// DoMoo - Never Ask, Never Tell /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool DoMoo(CommandLine &CmdL) -{ - cout << - " (__) \n" - " (oo) \n" - " /------\\/ \n" - " / | || \n" - " * /\\---/\\ \n" - " ~~ ~~ \n" - "....\"Have you mooed today?\"...\n"; - - return true; -} - /*}}}*/ -// ShowHelp - Show a help screen /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool ShowHelp(CommandLine &CmdL) -{ - ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION, - COMMON_ARCH,__DATE__,__TIME__); - - if (_config->FindB("version") == true) - { - cout << _("Supported modules:") << endl; - - for (unsigned I = 0; I != pkgVersioningSystem::GlobalListLen; I++) - { - pkgVersioningSystem *VS = pkgVersioningSystem::GlobalList[I]; - if (_system != 0 && _system->VS == VS) - cout << '*'; - else - cout << ' '; - cout << "Ver: " << VS->Label << endl; - - /* Print out all the packaging systems that will work with - this VS */ - for (unsigned J = 0; J != pkgSystem::GlobalListLen; J++) - { - pkgSystem *Sys = pkgSystem::GlobalList[J]; - if (_system == Sys) - cout << '*'; - else - cout << ' '; - if (Sys->VS->TestCompatibility(*VS) == true) - cout << "Pkg: " << Sys->Label << " (Priority " << Sys->Score(*_config) << ")" << endl; - } - } - - for (unsigned I = 0; I != pkgSourceList::Type::GlobalListLen; I++) - { - pkgSourceList::Type *Type = pkgSourceList::Type::GlobalList[I]; - cout << " S.L: '" << Type->Name << "' " << Type->Label << endl; - } - - for (unsigned I = 0; I != pkgIndexFile::Type::GlobalListLen; I++) - { - pkgIndexFile::Type *Type = pkgIndexFile::Type::GlobalList[I]; - cout << " Idx: " << Type->Label << endl; - } - - return true; - } - - cout << - _("Usage: apt-get [options] command\n" - " apt-get [options] install|remove pkg1 [pkg2 ...]\n" - " apt-get [options] source pkg1 [pkg2 ...]\n" - "\n" - "apt-get is a simple command line interface for downloading and\n" - "installing packages. The most frequently used commands are update\n" - "and install.\n" - "\n" - "Commands:\n" - " update - Retrieve new lists of packages\n" - " upgrade - Perform an upgrade\n" - " install - Install new packages (pkg is libc6 not libc6.deb)\n" - " remove - Remove packages\n" - " autoremove - Remove automatically all unused packages\n" - " purge - Remove and purge packages\n" - " source - Download source archives\n" - " build-dep - Configure build-dependencies for source packages\n" - " dist-upgrade - Distribution upgrade, see apt-get(8)\n" - " dselect-upgrade - Follow dselect selections\n" - " clean - Erase downloaded archive files\n" - " autoclean - Erase old downloaded archive files\n" - " check - Verify that there are no broken dependencies\n" - "\n" - "Options:\n" - " -h This help text.\n" - " -q Loggable output - no progress indicator\n" - " -qq No output except for errors\n" - " -d Download only - do NOT install or unpack archives\n" - " -s No-act. Perform ordering simulation\n" - " -y Assume Yes to all queries and do not prompt\n" - " -f Attempt to correct a system with broken dependencies in place\n" - " -m Attempt to continue if archives are unlocatable\n" - " -u Show a list of upgraded packages as well\n" - " -b Build the source package after fetching it\n" - " -V Show verbose version numbers\n" - " -c=? Read this configuration file\n" - " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n" - "See the apt-get(8), sources.list(5) and apt.conf(5) manual\n" - "pages for more information and options.\n" - " This APT has Super Cow Powers.\n"); - return true; -} - /*}}}*/ -// GetInitialize - Initialize things for apt-get /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void GetInitialize() -{ - _config->Set("quiet",0); - _config->Set("help",false); - _config->Set("APT::Get::Download-Only",false); - _config->Set("APT::Get::Simulate",false); - _config->Set("APT::Get::Assume-Yes",false); - _config->Set("APT::Get::Fix-Broken",false); - _config->Set("APT::Get::Force-Yes",false); - _config->Set("APT::Get::List-Cleanup",true); - _config->Set("APT::Get::AutomaticRemove",false); -} - /*}}}*/ -// SigWinch - Window size change signal handler /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void SigWinch(int) -{ - // Riped from GNU ls -#ifdef TIOCGWINSZ - struct winsize ws; - - if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5) - ScreenWidth = ws.ws_col - 1; -#endif -} - /*}}}*/ - -int main(int argc,const char *argv[]) -{ - CommandLine::Args Args[] = { - {'h',"help","help",0}, - {'v',"version","version",0}, - {'V',"verbose-versions","APT::Get::Show-Versions",0}, - {'q',"quiet","quiet",CommandLine::IntLevel}, - {'q',"silent","quiet",CommandLine::IntLevel}, - {'d',"download-only","APT::Get::Download-Only",0}, - {'b',"compile","APT::Get::Compile",0}, - {'b',"build","APT::Get::Compile",0}, - {'s',"simulate","APT::Get::Simulate",0}, - {'s',"just-print","APT::Get::Simulate",0}, - {'s',"recon","APT::Get::Simulate",0}, - {'s',"dry-run","APT::Get::Simulate",0}, - {'s',"no-act","APT::Get::Simulate",0}, - {'y',"yes","APT::Get::Assume-Yes",0}, - {'y',"assume-yes","APT::Get::Assume-Yes",0}, - {'f',"fix-broken","APT::Get::Fix-Broken",0}, - {'u',"show-upgraded","APT::Get::Show-Upgraded",0}, - {'m',"ignore-missing","APT::Get::Fix-Missing",0}, - {'t',"target-release","APT::Default-Release",CommandLine::HasArg}, - {'t',"default-release","APT::Default-Release",CommandLine::HasArg}, - {0,"download","APT::Get::Download",0}, - {0,"fix-missing","APT::Get::Fix-Missing",0}, - {0,"ignore-hold","APT::Ignore-Hold",0}, - {0,"upgrade","APT::Get::upgrade",0}, - {0,"force-yes","APT::Get::force-yes",0}, - {0,"print-uris","APT::Get::Print-URIs",0}, - {0,"diff-only","APT::Get::Diff-Only",0}, - {0,"tar-only","APT::Get::Tar-Only",0}, - {0,"dsc-only","APT::Get::Dsc-Only",0}, - {0,"purge","APT::Get::Purge",0}, - {0,"list-cleanup","APT::Get::List-Cleanup",0}, - {0,"reinstall","APT::Get::ReInstall",0}, - {0,"trivial-only","APT::Get::Trivial-Only",0}, - {0,"remove","APT::Get::Remove",0}, - {0,"only-source","APT::Get::Only-Source",0}, - {0,"arch-only","APT::Get::Arch-Only",0}, - {0,"auto-remove","APT::Get::AutomaticRemove",0}, - {0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0}, - {0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean}, - {0,"fix-policy","APT::Get::Fix-Policy-Broken",0}, - {'c',"config-file",0,CommandLine::ConfigFile}, - {'o',"option",0,CommandLine::ArbItem}, - {0,0,0,0}}; - CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate}, - {"upgrade",&DoUpgrade}, - {"install",&DoInstall}, - {"remove",&DoInstall}, - {"purge",&DoInstall}, - {"autoremove",&DoInstall}, - {"purge",&DoInstall}, - {"dist-upgrade",&DoDistUpgrade}, - {"dselect-upgrade",&DoDSelectUpgrade}, - {"build-dep",&DoBuildDep}, - {"clean",&DoClean}, - {"autoclean",&DoAutoClean}, - {"check",&DoCheck}, - {"source",&DoSource}, - {"moo",&DoMoo}, - {"help",&ShowHelp}, - {0,0}}; - - // Set up gettext support - setlocale(LC_ALL,""); - textdomain(PACKAGE); - - // Parse the command line and initialize the package library - CommandLine CmdL(Args,_config); - if (pkgInitConfig(*_config) == false || - CmdL.Parse(argc,argv) == false || - pkgInitSystem(*_config,_system) == false) - { - if (_config->FindB("version") == true) - ShowHelp(CmdL); - - _error->DumpErrors(); - return 100; - } - - // See if the help should be shown - if (_config->FindB("help") == true || - _config->FindB("version") == true || - CmdL.FileSize() == 0) - { - ShowHelp(CmdL); - return 0; - } - - // Deal with stdout not being a tty - if (!isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1) - _config->Set("quiet","1"); - - ofstream devnull; - devnull.open("/dev/null"); - - // Setup the output streams - c0out.rdbuf(cout.rdbuf()); - c1out.rdbuf(cout.rdbuf()); - c2out.rdbuf(cout.rdbuf()); - if (_config->FindI("quiet",0) > 0) - c0out.rdbuf(devnull.rdbuf()); - if (_config->FindI("quiet",0) > 1) - c1out.rdbuf(devnull.rdbuf()); - - // Setup the signals - signal(SIGPIPE,SIG_IGN); - signal(SIGWINCH,SigWinch); - SigWinch(0); - - // Match the operation - CmdL.DispatchArg(Cmds); - - // Print any errors or warnings found during parsing - if (_error->empty() == false) - { - bool Errors = _error->PendingError(); - _error->DumpErrors(); - return Errors == true?100:0; - } - - return 0; -} diff --git a/cmdline/apt-sortpkgs.cc b/cmdline/apt-sortpkgs.cc index 8bb5c56..7b2a74a 100644 --- a/cmdline/apt-sortpkgs.cc +++ b/cmdline/apt-sortpkgs.cc @@ -174,7 +174,7 @@ int main(int argc,const char *argv[]) // Set up gettext support setlocale(LC_ALL,""); - //textdomain(PACKAGE); + textdomain(PACKAGE); // Parse the command line and initialize the package library CommandLine CmdL(Args,_config); diff --git a/ftparchive/writer.cc b/ftparchive/writer.cc index 9d248ab..25ae2b0 100644 --- a/ftparchive/writer.cc +++ b/ftparchive/writer.cc @@ -629,7 +629,7 @@ bool SourcesWriter::DoPackage(string FileName) // Add the dsc to the files hash list char Files[1000]; - snprintf(Files,sizeof(Files),"\n %s %lu %s\n %s", + snprintf(Files,sizeof(Files),"\n %s %llu %s\n %s", string(MD5.Result()).c_str(),St.st_size, flNotDir(FileName).c_str(), Tags.FindS("Files").c_str()); diff --git a/methods/http.cc b/methods/http.cc index 2c25e50..5fe7469 100644 --- a/methods/http.cc +++ b/methods/http.cc @@ -1224,7 +1224,7 @@ int HttpMethod::Loop() if (UniqueID_ != NULL) CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("X-Unique-ID"), UniqueID_); - CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("User-Agent"), CFSTR("Telesphoreo APT-HTTP/1.0.534")); + CFHTTPMessageSetHeaderFieldValue(hm, CFSTR("User-Agent"), CFSTR("Telesphoreo APT-HTTP/1.0.592")); CFReadStreamRef rs = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, hm); CFRelease(hm); -- 2.45.2