summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/acquire-item.cc29
-rw-r--r--apt-pkg/acquire-item.h14
-rw-r--r--apt-pkg/cacheiterators.h81
-rw-r--r--apt-pkg/contrib/strutl.cc45
-rw-r--r--apt-pkg/contrib/strutl.h3
-rw-r--r--apt-pkg/deb/debindexfile.cc138
-rw-r--r--apt-pkg/deb/debindexfile.h29
-rw-r--r--apt-pkg/deb/deblistparser.cc41
-rw-r--r--apt-pkg/deb/deblistparser.h4
-rw-r--r--apt-pkg/deb/debmetaindex.cc5
-rw-r--r--apt-pkg/deb/debrecords.cc23
-rw-r--r--apt-pkg/deb/debrecords.h2
-rw-r--r--apt-pkg/indexfile.cc43
-rw-r--r--apt-pkg/indexfile.h7
-rw-r--r--apt-pkg/init.cc3
-rw-r--r--apt-pkg/pkgcache.cc11
-rw-r--r--apt-pkg/pkgcache.h44
-rw-r--r--apt-pkg/pkgcachegen.cc108
-rw-r--r--apt-pkg/pkgcachegen.h6
-rw-r--r--apt-pkg/pkgrecords.cc9
-rw-r--r--apt-pkg/pkgrecords.h2
21 files changed, 630 insertions, 17 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc
index 714edd8d8..3df9f2407 100644
--- a/apt-pkg/acquire-item.cc
+++ b/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,
diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h
index ea71153d5..0000f366c 100644
--- a/apt-pkg/acquire-item.h
+++ b/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;
diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h
index 62d2695dd..797e854b6 100644
--- a/apt-pkg/cacheiterators.h
+++ b/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
diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc
index a75fbdf92..303cb27db 100644
--- a/apt-pkg/contrib/strutl.cc
+++ b/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;
+
+ 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 == '/')
diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h
index 353e78ac9..72fc34d6d 100644
--- a/apt-pkg/contrib/strutl.h
+++ b/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);
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc
index f26265fff..4113137eb 100644
--- a/apt-pkg/deb/debindexfile.cc
+++ b/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) :
+ pkgIndexFile(true), 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;
diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h
index a1b9583a4..7bd7ea4f3 100644
--- a/apt-pkg/deb/debindexfile.h
+++ b/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;
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 96a80582d..6e78ed42b 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/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
diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h
index 9f305211a..3a8aec3a5 100644
--- a/apt-pkg/deb/deblistparser.h
+++ b/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);
diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc
index 526c8c0b2..7f15fd2e1 100644
--- a/apt-pkg/deb/debmetaindex.cc
+++ b/apt-pkg/deb/debmetaindex.cc
@@ -177,11 +177,14 @@ vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles()
Indexes = new vector <pkgIndexFile*>;
for (vector<const debSectionEntry *>::const_iterator I = SectionEntries.begin();
- I != SectionEntries.end(); I++)
+ I != SectionEntries.end(); I++) {
if ((*I)->IsSrc)
Indexes->push_back(new debSourcesIndex (URI, Dist, (*I)->Section, IsTrusted()));
else
Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted()));
+ Indexes->push_back(new debTranslationsIndex(URI,Dist,(*I)->Section));
+ }
+
return Indexes;
}
diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc
index 6652a6ad9..518988bb6 100644
--- a/apt-pkg/deb/debrecords.cc
+++ b/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 /*{{{*/
@@ -31,6 +33,10 @@ 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 /*{{{*/
diff --git a/apt-pkg/deb/debrecords.h b/apt-pkg/deb/debrecords.h
index efef2e588..24e5aab88 100644
--- a/apt-pkg/deb/debrecords.h
+++ b/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:
diff --git a/apt-pkg/indexfile.cc b/apt-pkg/indexfile.cc
index 49665161d..7aafe3c31 100644
--- a/apt-pkg/indexfile.cc
+++ b/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;
+}
+ /*}}}*/
diff --git a/apt-pkg/indexfile.h b/apt-pkg/indexfile.h
index be02669fa..d3a8f9917 100644
--- a/apt-pkg/indexfile.h
+++ b/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) {};
diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc
index f4b816c0b..3e4c17289 100644
--- a/apt-pkg/init.cc
+++ b/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)
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index 6ef7cafb0..2189d5111 100644
--- a/apt-pkg/pkgcache.cc
+++ b/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();
diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h
index b07951dfb..6a54ad5ba 100644
--- a/apt-pkg/pkgcache.h
+++ b/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;
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index 075af3eec..3ed6175ea 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/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;
}
diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h
index 7d0920629..6ab8594d9 100644
--- a/apt-pkg/pkgcachegen.h
+++ b/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;
diff --git a/apt-pkg/pkgrecords.cc b/apt-pkg/pkgrecords.cc
index 9c2655d6a..b22f3e73f 100644
--- a/apt-pkg/pkgrecords.cc
+++ b/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];
+}
+ /*}}}*/
diff --git a/apt-pkg/pkgrecords.h b/apt-pkg/pkgrecords.h
index 08f004414..31c444dbf 100644
--- a/apt-pkg/pkgrecords.h
+++ b/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;