Browse Source

Port DDTP to APT 0.6 branch

debian/1.8.y
Otavio Salvador 18 years ago
parent
commit
a52f938bcf
  1. 29
      apt-pkg/acquire-item.cc
  2. 14
      apt-pkg/acquire-item.h
  3. 81
      apt-pkg/cacheiterators.h
  4. 45
      apt-pkg/contrib/strutl.cc
  5. 3
      apt-pkg/contrib/strutl.h
  6. 138
      apt-pkg/deb/debindexfile.cc
  7. 29
      apt-pkg/deb/debindexfile.h
  8. 41
      apt-pkg/deb/deblistparser.cc
  9. 4
      apt-pkg/deb/deblistparser.h
  10. 1
      apt-pkg/deb/debmetaindex.cc
  11. 23
      apt-pkg/deb/debrecords.cc
  12. 2
      apt-pkg/deb/debrecords.h
  13. 43
      apt-pkg/indexfile.cc
  14. 7
      apt-pkg/indexfile.h
  15. 3
      apt-pkg/init.cc
  16. 11
      apt-pkg/pkgcache.cc
  17. 44
      apt-pkg/pkgcache.h
  18. 108
      apt-pkg/pkgcachegen.cc
  19. 6
      apt-pkg/pkgcachegen.h
  20. 9
      apt-pkg/pkgrecords.cc
  21. 2
      apt-pkg/pkgrecords.h
  22. 103
      cmdline/apt-cache.cc
  23. 13
      cmdline/apt-get.cc
  24. 8
      debian/changelog

29
apt-pkg/acquire-item.cc

@ -307,6 +307,35 @@ void pkgAcqIndex::Done(string Message,unsigned long Size,string MD5,
Mode = decompProg;
}
// AcqIndexTrans::pkgAcqIndexTrans - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* The Translation file is added to the queue */
pkgAcqIndexTrans::pkgAcqIndexTrans(pkgAcquire *Owner,
string URI,string URIDesc,string ShortDesc) :
pkgAcqIndex(Owner, URI, URIDesc, ShortDesc)
{
}
/*}}}*/
// AcqIndexTrans::Failed - Silence failure messages for missing files /*{{{*/
// ---------------------------------------------------------------------
/* */
void pkgAcqIndexTrans::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
{
if (Cnf->LocalOnly == true ||
StringToBool(LookupTag(Message,"Transient-Failure"),false) == false)
{
// Ignore this
Status = StatDone;
Complete = false;
Dequeue();
return;
}
Item::Failed(Message,Cnf);
}
/*}}}*/
pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner,
string URI,string URIDesc,string ShortDesc,
string MetaIndexURI, string MetaIndexURIDesc,

14
apt-pkg/acquire-item.h

@ -9,8 +9,8 @@
the Owner Acquire class. Derived classes will then call QueueURI to
register all the URI's they wish to fetch at the initial moment.
Two item classes are provided to provide functionality for downloading
of Index files and downloading of Packages.
Tree item classes are provided to provide functionality for
downloading of Index, Translation and Packages files.
A Archive class is provided for downloading .deb files. It does Md5
checking and source location as well as a retry algorithm.
@ -106,6 +106,16 @@ class pkgAcqIndex : public pkgAcquire::Item
string ShortDesct, string ExpectedMD5, string compressExt="");
};
// Item class for index files
class pkgAcqIndexTrans : public pkgAcqIndex
{
public:
virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf);
pkgAcqIndexTrans(pkgAcquire *Owner,string URI,string URIDesc,
string ShortDesct);
};
struct IndexTarget
{
string URI;

81
apt-pkg/cacheiterators.h

@ -128,6 +128,7 @@ class pkgCache::VerIterator
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;
inline DepIterator DependsList() const;
inline PrvIterator ProvidesList() const;
inline VerFileIterator FileList() const;
@ -148,6 +149,50 @@ class pkgCache::VerIterator
};
};
// 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
{
@ -336,6 +381,38 @@ class pkgCache::VerFileIterator
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);};
@ -345,11 +422,15 @@ 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

45
apt-pkg/contrib/strutl.cc

@ -32,12 +32,55 @@
#include <regex.h>
#include <errno.h>
#include <stdarg.h>
#include <iconv.h>
#include "config.h"
using namespace std;
/*}}}*/
// UTF8ToCodeset - Convert some UTF-8 string for some codeset /*{{{*/
// ---------------------------------------------------------------------
/* This is handy to use before display some information for enduser */
bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest)
{
iconv_t cd;
const char *inbuf;
char *inptr, *outbuf, *outptr;
size_t insize, outsize, nconv;
cd = iconv_open(codeset, "UTF-8");
if (cd == (iconv_t)(-1)) {
// Something went wrong
if (errno == EINVAL)
_error->Error("conversion from 'UTF-8' to '%s' not available",
codeset);
else
perror("iconv_open");
// Clean the destination string
*dest = "";
return false;
}
insize = outsize = orig.size();
inbuf = orig.data();
inptr = (char *)inbuf;
outbuf = new char[insize+1];
outptr = outbuf;
iconv(cd, &inptr, &insize, &outptr, &outsize);
*outptr = '\0';
*dest = outbuf;
delete[] outbuf;
iconv_close(cd);
return true;
}
/*}}}*/
// strstrip - Remove white space from the front and back of a string /*{{{*/
// ---------------------------------------------------------------------
/* This is handy to use when parsing a file. It also removes \n's left
@ -357,7 +400,7 @@ string URItoFileName(string URI)
U.Access = "";
// "\x00-\x20{}|\\\\^\\[\\]<>\"\x7F-\xFF";
URI = QuoteString(U,"\\|{}[]<>\"^~_=!@#$%^&*");
URI = QuoteString(U,"\\|{}[]<>\"^~=!@#$%^&*");
string::iterator J = URI.begin();
for (; J != URI.end(); J++)
if (*J == '/')

3
apt-pkg/contrib/strutl.h

@ -38,7 +38,8 @@ using std::ostream;
#define APT_FORMAT2
#define APT_FORMAT3
#endif
bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest);
char *_strstrip(char *String);
char *_strtabexpand(char *String,size_t Len);
bool ParseQuoteWord(const char *&String,string &Res);

138
apt-pkg/deb/debindexfile.cc

@ -320,6 +320,140 @@ pkgCache::PkgFileIterator debPackagesIndex::FindInCache(pkgCache &Cache) const
}
/*}}}*/
// TranslationsIndex::debTranslationsIndex - Contructor /*{{{*/
// ---------------------------------------------------------------------
/* */
debTranslationsIndex::debTranslationsIndex(string URI,string Dist,string Section) :
URI(URI), Dist(Dist), Section(Section)
{
}
/*}}}*/
// TranslationIndex::Trans* - Return the URI to the translation files /*{{{*/
// ---------------------------------------------------------------------
/* */
inline string debTranslationsIndex::IndexFile(const char *Type) const
{
return _config->FindDir("Dir::State::lists") + URItoFileName(IndexURI(Type));
}
string debTranslationsIndex::IndexURI(const char *Type) const
{
string Res;
if (Dist[Dist.size() - 1] == '/')
{
if (Dist != "/")
Res = URI + Dist;
else
Res = URI;
}
else
Res = URI + "dists/" + Dist + '/' + Section +
"/i18n/Translation-";
Res += Type;
return Res;
}
/*}}}*/
// TranslationsIndex::GetIndexes - Fetch the index files /*{{{*/
// ---------------------------------------------------------------------
/* */
bool debTranslationsIndex::GetIndexes(pkgAcquire *Owner) const
{
if (UseTranslation()) {
string TranslationFile = "Translation-" + LanguageCode();
new pkgAcqIndexTrans(Owner, IndexURI(LanguageCode().c_str()),
Info(TranslationFile.c_str()),
TranslationFile);
}
return true;
}
/*}}}*/
// TranslationsIndex::Describe - Give a descriptive path to the index /*{{{*/
// ---------------------------------------------------------------------
/* This should help the user find the index in the sources.list and
in the filesystem for problem solving */
string debTranslationsIndex::Describe(bool Short) const
{
char S[300];
if (Short == true)
snprintf(S,sizeof(S),"%s",Info(TranslationFile().c_str()).c_str());
else
snprintf(S,sizeof(S),"%s (%s)",Info(TranslationFile().c_str()).c_str(),
IndexFile(LanguageCode().c_str()).c_str());
return S;
}
/*}}}*/
// TranslationsIndex::Info - One liner describing the index URI /*{{{*/
// ---------------------------------------------------------------------
/* */
string debTranslationsIndex::Info(const char *Type) const
{
string Info = ::URI::SiteOnly(URI) + ' ';
if (Dist[Dist.size() - 1] == '/')
{
if (Dist != "/")
Info += Dist;
}
else
Info += Dist + '/' + Section;
Info += " ";
Info += Type;
return Info;
}
/*}}}*/
// TranslationsIndex::Exists - Check if the index is available /*{{{*/
// ---------------------------------------------------------------------
/* */
bool debTranslationsIndex::Exists() const
{
return true;
}
/*}}}*/
// TranslationsIndex::Size - Return the size of the index /*{{{*/
// ---------------------------------------------------------------------
/* This is really only used for progress reporting. */
unsigned long debTranslationsIndex::Size() const
{
struct stat S;
if (stat(IndexFile(LanguageCode().c_str()).c_str(),&S) != 0)
return 0;
return S.st_size;
}
/*}}}*/
// TranslationsIndex::Merge - Load the index file into a cache /*{{{*/
// ---------------------------------------------------------------------
/* */
bool debTranslationsIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const
{
// Check the translation file, if in use
string TranslationFile = IndexFile(LanguageCode().c_str());
if (UseTranslation() && FileExists(TranslationFile))
{
FileFd Trans(TranslationFile,FileFd::ReadOnly);
debListParser TransParser(&Trans);
if (_error->PendingError() == true)
return false;
Prog.SubProgress(0, Info(TranslationFile.c_str()));
if (Gen.SelectFile(TranslationFile,string(),*this) == false)
return _error->Error("Problem with SelectFile %s",TranslationFile.c_str());
// Store the IMS information
pkgCache::PkgFileIterator TransFile = Gen.GetCurFile();
struct stat TransSt;
if (fstat(Trans.Fd(),&TransSt) != 0)
return _error->Errno("fstat","Failed to stat");
TransFile->Size = TransSt.st_size;
TransFile->mtime = TransSt.st_mtime;
if (Gen.MergeList(TransParser) == false)
return _error->Error("Problem with MergeList %s",TranslationFile.c_str());
}
return true;
}
/*}}}*/
// StatusIndex::debStatusIndex - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
@ -438,6 +572,10 @@ const pkgIndexFile::Type *debPackagesIndex::GetType() const
{
return &_apt_Pkg;
}
const pkgIndexFile::Type *debTranslationsIndex::GetType() const
{
return &_apt_Pkg;
}
const pkgIndexFile::Type *debStatusIndex::GetType() const
{
return &_apt_Status;

29
apt-pkg/deb/debindexfile.h

@ -74,6 +74,35 @@ class debPackagesIndex : public pkgIndexFile
debPackagesIndex(string URI,string Dist,string Section,bool Trusted);
};
class debTranslationsIndex : public pkgIndexFile
{
string URI;
string Dist;
string Section;
string Info(const char *Type) const;
string IndexFile(const char *Type) const;
string IndexURI(const char *Type) const;
inline string TranslationFile() const {return "Translation-" + LanguageCode();};
public:
virtual const Type *GetType() const;
// Interface for acquire
virtual string Describe(bool Short) const;
virtual bool GetIndexes(pkgAcquire *Owner) const;
// Interface for the Cache Generator
virtual bool Exists() const;
virtual bool HasPackages() const {return true;};
virtual unsigned long Size() const;
virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const;
debTranslationsIndex(string URI,string Dist,string Section);
};
class debSourcesIndex : public pkgIndexFile
{
string URI;

41
apt-pkg/deb/deblistparser.cc

@ -15,6 +15,7 @@
#include <apt-pkg/configuration.h>
#include <apt-pkg/strutl.h>
#include <apt-pkg/crc-16.h>
#include <apt-pkg/md5.h>
#include <ctype.h>
@ -117,6 +118,46 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
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 is the right
description. If thisreturns a blank string then calculate the md5
value. */
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

4
apt-pkg/deb/deblistparser.h

@ -12,6 +12,7 @@
#define PKGLIB_DEBLISTPARSER_H
#include <apt-pkg/pkgcachegen.h>
#include <apt-pkg/indexfile.h>
#include <apt-pkg/tagfile.h>
class debListParser : public pkgCacheGenerator::ListParser
@ -47,6 +48,9 @@ class debListParser : public pkgCacheGenerator::ListParser
virtual string Package();
virtual string Version();
virtual bool NewVersion(pkgCache::VerIterator Ver);
virtual string Description();
virtual string DescriptionLanguage();
virtual MD5SumValue Description_md5();
virtual unsigned short VersionHash();
virtual bool UsePackage(pkgCache::PkgIterator Pkg,
pkgCache::VerIterator Ver);

1
apt-pkg/deb/debmetaindex.cc

@ -227,6 +227,7 @@ class debSLTypeDebian : public pkgSourceList::Type
debReleaseIndex *Deb = new debReleaseIndex(URI,Dist);
Deb->PushSectionEntry (new debReleaseIndex::debSectionEntry(Section, IsSrc));
List.push_back(Deb);
List.push_back(new debTranslationsIndex(URI,Dist,Section));
return true;
}
};

23
apt-pkg/deb/debrecords.cc

@ -12,7 +12,9 @@
#pragma implementation "apt-pkg/debrecords.h"
#endif
#include <apt-pkg/debrecords.h>
#include <apt-pkg/strutl.h>
#include <apt-pkg/error.h>
#include <langinfo.h>
/*}}}*/
// RecordParser::debRecordParser - Constructor /*{{{*/
@ -30,6 +32,10 @@ debRecordParser::debRecordParser(string FileName,pkgCache &Cache) :
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 /*{{{*/
@ -77,7 +83,7 @@ string debRecordParser::Maintainer()
/* */
string debRecordParser::ShortDesc()
{
string Res = Section.FindS("Description");
string Res = LongDesc();
string::size_type Pos = Res.find('\n');
if (Pos == string::npos)
return Res;
@ -89,7 +95,20 @@ string debRecordParser::ShortDesc()
/* */
string debRecordParser::LongDesc()
{
return Section.FindS("Description");
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::SourcePkg - Return the source package name if any /*{{{*/

2
apt-pkg/deb/debrecords.h

@ -19,6 +19,7 @@
#endif
#include <apt-pkg/pkgrecords.h>
#include <apt-pkg/indexfile.h>
#include <apt-pkg/tagfile.h>
class debRecordParser : public pkgRecords::Parser
@ -30,6 +31,7 @@ class debRecordParser : public pkgRecords::Parser
protected:
virtual bool Jump(pkgCache::VerFileIterator const &Ver);
virtual bool Jump(pkgCache::DescFileIterator const &Desc);
public:

43
apt-pkg/indexfile.cc

@ -12,8 +12,11 @@
#pragma implementation "apt-pkg/indexfile.h"
#endif
#include <apt-pkg/configuration.h>
#include <apt-pkg/indexfile.h>
#include <apt-pkg/error.h>
#include <clocale>
/*}}}*/
// Global list of Item supported
@ -67,3 +70,43 @@ string pkgIndexFile::SourceInfo(pkgSrcRecords::Parser const &Record,
return string();
}
/*}}}*/
// IndexFile::UseTranslation - Check if will use Translation /*{{{*/
// ---------------------------------------------------------------------
/* */
bool pkgIndexFile::UseTranslation()
{
const string Translation = _config->Find("APT::Acquire::Translation");
if (Translation.compare("none") != 0)
return CheckLanguageCode(LanguageCode().c_str());
else
return false;
}
/*}}}*/
// IndexFile::CheckLanguageCode - Check the Language Code /*{{{*/
// ---------------------------------------------------------------------
/* */
bool pkgIndexFile::CheckLanguageCode(const char *Lang)
{
if (strlen(Lang) == 2 || (strlen(Lang) == 5 && Lang[2] == '_'))
return true;
if (strcmp(Lang,"C") != 0)
_error->Warning("Wrong language code %s", Lang);
return false;
}
/*}}}*/
// IndexFile::LanguageCode - Return the Language Code /*{{{*/
// ---------------------------------------------------------------------
/* */
string pkgIndexFile::LanguageCode()
{
const string Translation = _config->Find("APT::Acquire::Translation");
if (Translation.compare("environment") == 0)
return std::setlocale(LC_ALL,NULL);
else
return Translation;
}
/*}}}*/

7
apt-pkg/indexfile.h

@ -5,10 +5,11 @@
Index File - Abstraction for an index of archive/source file.
There are 3 primary sorts of index files, all represented by this
There are 4 primary sorts of index files, all represented by this
class:
Binary index files
Binary translation files
Bianry index files decribing the local system
Source index files
@ -79,6 +80,10 @@ class pkgIndexFile
virtual bool MergeFileProvides(pkgCacheGenerator &/*Gen*/,OpProgress &/*Prog*/) const {return true;};
virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
static bool UseTranslation();
static bool CheckLanguageCode(const char *Lang);
static string LanguageCode();
bool IsTrusted() const { return Trusted; };
pkgIndexFile(bool Trusted): Trusted(Trusted) {};

3
apt-pkg/init.cc

@ -33,6 +33,9 @@ const char *pkgOS = COMMON_OS;
is prepended, this allows a fair degree of flexability. */
bool pkgInitConfig(Configuration &Cnf)
{
// Translation
Cnf.Set("APT::Acquire::Translation", "environment");
// General APT things
if (strcmp(COMMON_OS,"linux") == 0 ||
strcmp(COMMON_OS,"unknown") == 0)

11
apt-pkg/pkgcache.cc

@ -52,7 +52,7 @@ pkgCache::Header::Header()
/* Whenever the structures change the major version should be bumped,
whenever the generator changes the minor version should be bumped. */
MajorVersion = 4;
MajorVersion = 5;
MinorVersion = 0;
Dirty = false;
@ -60,17 +60,22 @@ pkgCache::Header::Header()
PackageSz = sizeof(pkgCache::Package);
PackageFileSz = sizeof(pkgCache::PackageFile);
VersionSz = sizeof(pkgCache::Version);
DescriptionSz = sizeof(pkgCache::Description);
DependencySz = sizeof(pkgCache::Dependency);
ProvidesSz = sizeof(pkgCache::Provides);
VerFileSz = sizeof(pkgCache::VerFile);
DescFileSz = sizeof(pkgCache::DescFile);
PackageCount = 0;
VersionCount = 0;
DescriptionCount = 0;
DependsCount = 0;
PackageFileCount = 0;
VerFileCount = 0;
DescFileCount = 0;
ProvidesCount = 0;
MaxVerFileSize = 0;
MaxDescFileSize = 0;
FileList = 0;
StringList = 0;
@ -89,8 +94,10 @@ bool pkgCache::Header::CheckSizes(Header &Against) const
PackageSz == Against.PackageSz &&
PackageFileSz == Against.PackageFileSz &&
VersionSz == Against.VersionSz &&
DescriptionSz == Against.DescriptionSz &&
DependencySz == Against.DependencySz &&
VerFileSz == Against.VerFileSz &&
DescFileSz == Against.DescFileSz &&
ProvidesSz == Against.ProvidesSz)
return true;
return false;
@ -115,8 +122,10 @@ bool pkgCache::ReMap()
HeaderP = (Header *)Map.Data();
PkgP = (Package *)Map.Data();
VerFileP = (VerFile *)Map.Data();
DescFileP = (DescFile *)Map.Data();
PkgFileP = (PackageFile *)Map.Data();
VerP = (Version *)Map.Data();
DescP = (Description *)Map.Data();
ProvideP = (Provides *)Map.Data();
DepP = (Dependency *)Map.Data();
StringItemP = (StringItem *)Map.Data();

44
apt-pkg/pkgcache.h

@ -38,24 +38,30 @@ class pkgCache
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;
@ -98,8 +104,10 @@ class pkgCache
Header *HeaderP;
Package *PkgP;
VerFile *VerFileP;
DescFile *DescFileP;
PackageFile *PkgFileP;
Version *VerP;
Description *DescP;
Provides *ProvideP;
Dependency *DepP;
StringItem *StringItemP;
@ -151,16 +159,20 @@ struct pkgCache::Header
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
@ -169,10 +181,11 @@ struct pkgCache::Header
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[7];
DynamicMMap::Pool Pools[8];
// Rapid package name lookup
map_ptrloc HashTable[2*1048];
@ -193,7 +206,7 @@ struct pkgCache::Package
map_ptrloc NextPackage; // Package
map_ptrloc RevDepends; // Dependency
map_ptrloc ProvidesList; // Provides
// Install/Remove/Purge etc
unsigned char SelectedState; // What
unsigned char InstState; // Flags
@ -232,6 +245,14 @@ struct pkgCache::VerFile
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
@ -241,6 +262,7 @@ struct pkgCache::Version
// 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
@ -252,6 +274,22 @@ struct pkgCache::Version
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
@ -299,11 +337,13 @@ class pkgCache::Namespace
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;

108
apt-pkg/pkgcachegen.cc

@ -125,6 +125,28 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
string Version = List.Version();
if (Version.empty() == true)
{
// Find the right version to write the description
MD5SumValue CurMd5 = List.Description_md5();
pkgCache::VerIterator Ver = Pkg.VersionList();
map_ptrloc *LastVer = &Pkg->VersionList;
for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++)
{
pkgCache::DescIterator Desc = Ver.DescriptionList();
map_ptrloc *LastDesc = &Ver->DescriptionList;
for (; Desc.end() == false; LastDesc = &Desc->NextDesc, Desc++)
if (MD5SumValue(Desc.md5()) == CurMd5) {
// Add new description
*LastDesc = NewDescription(Desc, List.DescriptionLanguage(), CurMd5, *LastDesc);
Desc->ParentPkg = Pkg.Index();
if (NewFileDesc(Desc,List) == false)
return _error->Error(_("Error occured while processing %s (NewFileDesc1)"),PackageName.c_str());
break;
}
}
if (List.UsePackage(Pkg,pkgCache::VerIterator(Cache)) == false)
return _error->Error(_("Error occured while processing %s (UsePackage1)"),
PackageName.c_str());
@ -132,9 +154,9 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
}
pkgCache::VerIterator Ver = Pkg.VersionList();
map_ptrloc *Last = &Pkg->VersionList;
map_ptrloc *LastVer = &Pkg->VersionList;
int Res = 1;
for (; Ver.end() == false; Last = &Ver->NextVer, Ver++)
for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++)
{
Res = Cache.VS->CmpVersion(Version,Ver.VerStr());
if (Res >= 0)
@ -168,7 +190,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
// Skip to the end of the same version set.
if (Res == 0)
{
for (; Ver.end() == false; Last = &Ver->NextVer, Ver++)
for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++)
{
Res = Cache.VS->CmpVersion(Version,Ver.VerStr());
if (Res != 0)
@ -177,9 +199,10 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
}
// Add a new version
*Last = NewVersion(Ver,Version,*Last);
*LastVer = NewVersion(Ver,Version,*LastVer);
Ver->ParentPkg = Pkg.Index();
Ver->Hash = Hash;
if (List.NewVersion(Ver) == false)
return _error->Error(_("Error occured while processing %s (NewVersion1)"),
PackageName.c_str());
@ -199,6 +222,21 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
FoundFileDeps |= List.HasFileDeps();
return true;
}
/* Record the Description data. Description data always exist in
Packages and Translation-* files. */
pkgCache::DescIterator Desc = Ver.DescriptionList();
map_ptrloc *LastDesc = &Ver->DescriptionList;
// Skip to the end of description set
for (; Desc.end() == false; LastDesc = &Desc->NextDesc, Desc++);
// Add new description
*LastDesc = NewDescription(Desc, List.DescriptionLanguage(), List.Description_md5(), *LastDesc);
Desc->ParentPkg = Pkg.Index();
if (NewFileDesc(Desc,List) == false)
return _error->Error(_("Error occured while processing %s (NewFileDesc2)"),PackageName.c_str());
}
FoundFileDeps |= List.HasFileDeps();
@ -209,6 +247,9 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
if (Cache.HeaderP->VersionCount >= (1ULL<<(sizeof(Cache.VerP->ID)*8))-1)
return _error->Error(_("Wow, you exceeded the number of versions "
"this APT is capable of."));
if (Cache.HeaderP->DescriptionCount >= (1ULL<<(sizeof(Cache.DescP->ID)*8))-1)
return _error->Error(_("Wow, you exceeded the number of descriptions "
"this APT is capable of."));
if (Cache.HeaderP->DependsCount >= (1ULL<<(sizeof(Cache.DepP->ID)*8))-1ULL)
return _error->Error(_("Wow, you exceeded the number of dependencies "
"this APT is capable of."));
@ -271,7 +312,7 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,string Name)
Pkg = Cache.FindPkg(Name);
if (Pkg.end() == false)
return true;
// Get a structure
unsigned long Package = Map.Allocate(sizeof(pkgCache::Package));
if (Package == 0)
@ -349,6 +390,61 @@ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver,
return Version;
}
/*}}}*/
// CacheGenerator::NewFileDesc - Create a new File<->Desc association /*{{{*/
// ---------------------------------------------------------------------
/* */
bool pkgCacheGenerator::NewFileDesc(pkgCache::DescIterator &Desc,
ListParser &List)
{
if (CurrentFile == 0)
return true;
// Get a structure
unsigned long DescFile = Map.Allocate(sizeof(pkgCache::DescFile));
if (DescFile == 0)
return 0;
pkgCache::DescFileIterator DF(Cache,Cache.DescFileP + DescFile);
DF->File = CurrentFile - Cache.PkgFileP;
// Link it to the end of the list
map_ptrloc *Last = &Desc->FileList;
for (pkgCache::DescFileIterator D = Desc.FileList(); D.end() == false; D++)
Last = &D->NextFile;
DF->NextFile = *Last;
*Last = DF.Index();
DF->Offset = List.Offset();
DF->Size = List.Size();
if (Cache.HeaderP->MaxDescFileSize < DF->Size)
Cache.HeaderP->MaxDescFileSize = DF->Size;
Cache.HeaderP->DescFileCount++;
return true;
}
/*}}}*/
// CacheGenerator::NewDescription - Create a new Description /*{{{*/
// ---------------------------------------------------------------------
/* This puts a description structure in the linked list */
map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc,
const string &Lang, const MD5SumValue &md5sum,
map_ptrloc Next)
{
// Get a structure
map_ptrloc Description = Map.Allocate(sizeof(pkgCache::Description));
if (Description == 0)
return 0;
// Fill it in
Desc = pkgCache::DescIterator(Cache,Cache.DescP + Description);
Desc->NextDesc = Next;
Desc->ID = Cache.HeaderP->DescriptionCount++;
Desc->language_code = Map.WriteString(Lang);
Desc->md5sum = Map.WriteString(md5sum.Value());
return Description;
}
/*}}}*/
// ListParser::NewDepends - Create a dependency element /*{{{*/
// ---------------------------------------------------------------------
/* This creates a dependency element in the tree. It is linked to the
@ -580,7 +676,7 @@ static bool CheckValidity(string CacheFile, FileIterator Start,
pkgCache::PkgFileIterator File = (*Start)->FindInCache(Cache);
if (File.end() == true)
return false;
Visited[File->ID] = true;
}

6
apt-pkg/pkgcachegen.h

@ -24,6 +24,7 @@
#endif
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/md5.h>
class pkgSourceList;
class OpProgress;
@ -55,7 +56,9 @@ class pkgCacheGenerator
bool NewPackage(pkgCache::PkgIterator &Pkg,string Pkg);
bool NewFileVer(pkgCache::VerIterator &Ver,ListParser &List);
bool NewFileDesc(pkgCache::DescIterator &Desc,ListParser &List);
unsigned long NewVersion(pkgCache::VerIterator &Ver,string VerStr,unsigned long Next);
map_ptrloc NewDescription(pkgCache::DescIterator &Desc,const string &Lang,const MD5SumValue &md5sum,map_ptrloc Next);
public:
@ -107,6 +110,9 @@ class pkgCacheGenerator::ListParser
virtual string Package() = 0;
virtual string Version() = 0;
virtual bool NewVersion(pkgCache::VerIterator Ver) = 0;
virtual string Description() = 0;
virtual string DescriptionLanguage() = 0;
virtual MD5SumValue Description_md5() = 0;
virtual unsigned short VersionHash() = 0;
virtual bool UsePackage(pkgCache::PkgIterator Pkg,
pkgCache::VerIterator Ver) = 0;

9
apt-pkg/pkgrecords.cc

@ -63,3 +63,12 @@ pkgRecords::Parser &pkgRecords::Lookup(pkgCache::VerFileIterator const &Ver)
return *Files[Ver.File()->ID];
}
/*}}}*/
// Records::Lookup - Get a parser for the package description file /*{{{*/
// ---------------------------------------------------------------------
/* */
pkgRecords::Parser &pkgRecords::Lookup(pkgCache::DescFileIterator const &Desc)
{
Files[Desc.File()->ID]->Jump(Desc);
return *Files[Desc.File()->ID];
}
/*}}}*/

2
apt-pkg/pkgrecords.h

@ -38,6 +38,7 @@ class pkgRecords
// Lookup function
Parser &Lookup(pkgCache::VerFileIterator const &Ver);
Parser &Lookup(pkgCache::DescFileIterator const &Desc);
// Construct destruct
pkgRecords(pkgCache &Cache);
@ -49,6 +50,7 @@ class pkgRecords::Parser
protected:
virtual bool Jump(pkgCache::VerFileIterator const &Ver) = 0;
virtual bool Jump(pkgCache::DescFileIterator const &Desc) = 0;
public:
friend class pkgRecords;

103
cmdline/apt-cache.cc

@ -71,6 +71,12 @@ void LocalitySort(pkgCache::VerFile **begin,
{
qsort(begin,Count,Size,LocalityCompare);
}
void LocalitySort(pkgCache::DescFile **begin,
unsigned long Count,size_t Size)
{
qsort(begin,Count,Size,LocalityCompare);
}
/*}}}*/
// UnMet - Show unmet dependencies /*{{{*/
// ---------------------------------------------------------------------
@ -182,7 +188,14 @@ bool DumpPackage(CommandLine &CmdL)
{
cout << Cur.VerStr();
for (pkgCache::VerFileIterator Vf = Cur.FileList(); Vf.end() == false; Vf++)
cout << "(" << Vf.File().FileName() << ")";
cout << " (" << Vf.File().FileName() << ")";
cout << endl;
for (pkgCache::DescIterator D = Cur.DescriptionList(); D.end() == false; D++)
{
cout << " Description Language: " << D.LanguageCode() << endl
<< " File: " << D.FileList().File().FileName() << endl
<< " MD5: " << D.md5() << endl;
}
cout << endl;
}
@ -277,11 +290,15 @@ bool Stats(CommandLine &Cmd)
cout << _("Total Distinct Versions: ") << Cache.Head().VersionCount << " (" <<
SizeToStr(Cache.Head().VersionCount*Cache.Head().VersionSz) << ')' << endl;
cout << _("Total Distinct Descriptions: ") << Cache.Head().DescriptionCount << " (" <<
SizeToStr(Cache.Head().DescriptionCount*Cache.Head().DescriptionSz) << ')' << endl;
cout << _("Total Dependencies: ") << Cache.Head().DependsCount << " (" <<
SizeToStr(Cache.Head().DependsCount*Cache.Head().DependencySz) << ')' << endl;
cout << _("Total Ver/File relations: ") << Cache.Head().VerFileCount << " (" <<
SizeToStr(Cache.Head().VerFileCount*Cache.Head().VerFileSz) << ')' << endl;
cout << _("Total Desc/File relations: ") << Cache.Head().DescFileCount << " (" <<
SizeToStr(Cache.Head().DescFileCount*Cache.Head().DescFileSz) << ')' << endl;
cout << _("Total Provides Mappings: ") << Cache.Head().ProvidesCount << " (" <<
SizeToStr(Cache.Head().ProvidesCount*Cache.Head().ProvidesSz) << ')' << endl;
@ -344,6 +361,12 @@ bool Dump(CommandLine &Cmd)
for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
cout << " Depends: " << D.TargetPkg().Name() << ' ' <<
DeNull(D.TargetVer()) << endl;
for (pkgCache::DescIterator D = V.DescriptionList(); D.end() == false; D++)
{
cout << " Description Language: " << D.LanguageCode() << endl
<< " File: " << D.FileList().File().FileName() << endl
<< " MD5: " << D.md5() << endl;
}
}
}
@ -1192,28 +1215,51 @@ bool DisplayRecord(pkgCache::VerIterator V)
if (_error->PendingError() == true)
return false;
// Read the record and then write it out again.
// Read the record
unsigned char *Buffer = new unsigned char[GCache->HeaderP->MaxVerFileSize+1];
Buffer[V.FileList()->Size] = '\n';
if (PkgF.Seek(V.FileList()->Offset) == false ||
PkgF.Read(Buffer,V.FileList()->Size) == false ||
fwrite(Buffer,1,V.FileList()->Size+1,stdout) < (size_t)(V.FileList()->Size+1))
PkgF.Read(Buffer,V.FileList()->Size) == false)
{
delete [] Buffer;
return false;
}
// Strip the Description
unsigned char *DescP = (unsigned char*)strstr((char*)Buffer, "Description:");
*DescP='\0';
// Write all the rest
if (fwrite(Buffer,1,V.FileList()->Size+1,stdout) < V.FileList()->Size+1))
{
delete [] Buffer;
return false;
}
delete [] Buffer;
// Show the right description
pkgRecords Recs(*GCache);
pkgCache::DescIterator DescDefault = V.DescriptionList();
pkgCache::DescIterator Desc = DescDefault;
for (; Desc.end() == false; Desc++)
if (pkgIndexFile::LanguageCode() == Desc.LanguageCode())
break;
if (Desc.end() == true) Desc = DescDefault;
pkgRecords::Parser &P = Recs.Lookup(Desc.FileList());
cout << "Description" << ( (strcmp(Desc.LanguageCode(),"") != 0) ? "-" : "" ) << Desc.LanguageCode() << ": " << P.LongDesc() << endl;
return true;
}
/*}}}*/
// Search - Perform a search /*{{{*/
// ---------------------------------------------------------------------
/* This searches the package names and pacakge descriptions for a pattern */
struct ExVerFile
struct ExDescFile
{
pkgCache::VerFile *Vf;
pkgCache::DescFile *Df;
bool NameMatch;
};
@ -1253,35 +1299,35 @@ bool Search(CommandLine &CmdL)
return false;
}
ExVerFile *VFList = new ExVerFile[Cache.HeaderP->PackageCount+1];
memset(VFList,0,sizeof(*VFList)*Cache.HeaderP->PackageCount+1);
ExDescFile *DFList = new ExDescFile[Cache.HeaderP->PackageCount+1];
memset(DFList,0,sizeof(*DFList)*Cache.HeaderP->PackageCount+1);
// Map versions that we want to write out onto the VerList array.
for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
{
VFList[P->ID].NameMatch = NumPatterns != 0;
DFList[P->ID].NameMatch = NumPatterns != 0;
for (unsigned I = 0; I != NumPatterns; I++)
{
if (regexec(&Patterns[I],P.Name(),0,0,0) == 0)
VFList[P->ID].NameMatch &= true;
DFList[P->ID].NameMatch &= true;
else
VFList[P->ID].NameMatch = false;
DFList[P->ID].NameMatch = false;
}
// Doing names only, drop any that dont match..
if (NamesOnly == true && VFList[P->ID].NameMatch == false)
if (NamesOnly == true && DFList[P->ID].NameMatch == false)
continue;
// Find the proper version to use.
pkgCache::VerIterator V = Plcy.GetCandidateVer(P);
if (V.end() == false)
VFList[P->ID].Vf = V.FileList();
DFList[P->ID].Df = V.DescriptionList().FileList();
}
// Include all the packages that provide matching names too
for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
{
if (VFList[P->ID].NameMatch == false)
if (DFList[P->ID].NameMatch == false)
continue;
for (pkgCache::PrvIterator Prv = P.ProvidesList() ; Prv.end() == false; Prv++)
@ -1289,18 +1335,18 @@ bool Search(CommandLine &CmdL)
pkgCache::VerIterator V = Plcy.GetCandidateVer(Prv.OwnerPkg());
if (V.end() == false)
{
VFList[Prv.OwnerPkg()->ID].Vf = V.FileList();
VFList[Prv.OwnerPkg()->ID].NameMatch = true;
DFList[Prv.OwnerPkg()->ID].Df = V.DescriptionList().FileList();
DFList[Prv.OwnerPkg()->ID].NameMatch = true;
}
}
}
LocalitySort(&VFList->Vf,Cache.HeaderP->PackageCount,sizeof(*VFList));
LocalitySort(&DFList->Df,Cache.HeaderP->PackageCount,sizeof(*DFList));
// Iterate over all the version records and check them
for (ExVerFile *J = VFList; J->Vf != 0; J++)
for (ExDescFile *J = DFList; J->Df != 0; J++)
{
pkgRecords::Parser &P = Recs.Lookup(pkgCache::VerFileIterator(Cache,J->Vf));
pkgRecords::Parser &P = Recs.Lookup(pkgCache::DescFileIterator(Cache,J->Df));