]> git.saurik.com Git - apt.git/commitdiff
Sync with apt@packages.debian.org/apt--main--0--patch-75
authorOtavio Salvador <otavio@debian.org>
Wed, 30 Mar 2005 23:36:25 +0000 (23:36 +0000)
committerOtavio Salvador <otavio@debian.org>
Wed, 30 Mar 2005 23:36:25 +0000 (23:36 +0000)
Patches applied:

 * apt@packages.debian.org/apt--main--0--patch-75
   Merge bubulle@debian.org--2005/apt--main--0

 * bubulle@debian.org--2005/apt--main--0--patch-58
   Correct file permissions

 * bubulle@debian.org--2005/apt--main--0--patch-59
   Bring consistency to the use of capitals in programs messages

 * bubulle@debian.org--2005/apt--main--0--patch-60
   Correct the permission change on configure.in

 * bubulle@debian.org--2005/apt--main--0--patch-61
   Complete unfuzzification of PO files after the capitalization fixes

 * bubulle@debian.org--2005/apt--main--0--patch-62
   Final work of capitalization cleaning and translation unfuzzyfication

 * bubulle@debian.org--2005/apt--main--0--patch-63
   Correct the "arbitary" typo in apt-ftparchive

 * bubulle@debian.org--2005/apt--main--0--patch-64
   Italian translation update

 * bubulle@debian.org--2005/apt--main--0--patch-65
   Italian translation update

24 files changed:
apt-pkg/acquire-item.cc
apt-pkg/acquire-item.h
apt-pkg/cacheiterators.h
apt-pkg/contrib/strutl.cc
apt-pkg/contrib/strutl.h
apt-pkg/deb/debindexfile.cc
apt-pkg/deb/debindexfile.h
apt-pkg/deb/deblistparser.cc
apt-pkg/deb/deblistparser.h
apt-pkg/deb/debmetaindex.cc
apt-pkg/deb/debrecords.cc
apt-pkg/deb/debrecords.h
apt-pkg/indexfile.cc
apt-pkg/indexfile.h
apt-pkg/init.cc
apt-pkg/pkgcache.cc
apt-pkg/pkgcache.h
apt-pkg/pkgcachegen.cc
apt-pkg/pkgcachegen.h
apt-pkg/pkgrecords.cc
apt-pkg/pkgrecords.h
cmdline/apt-cache.cc
cmdline/apt-get.cc
debian/changelog

index 714edd8d8caff9920f9e10ffbfbb1de1ee0c1575..3df9f24073094b8d3a2a6837c85518a536d33662 100644 (file)
@@ -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,
index ea71153d50e0428d5779e3433736502b36a43fd4..0000f366ceee3a9cad806e8c861650e57aafc08f 100644 (file)
@@ -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;
index 62d2695ddcf085723e663105d9c980b7480431eb..797e854b67cfebd7c69f264c782be3b853dab9a7 100644 (file)
@@ -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
index a75fbdf9292e4720e4fab6878deaa699aa8a28c5..303cb27dbce986be7f972f8ada6c992db0ffc090 100644 (file)
 #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 == '/') 
index 353e78ac94cd2a3d9826ab31134cc392f1db5483..72fc34d6d8613704f43f7ebca1b9f95c8e3c981a 100644 (file)
@@ -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);
index f26265fff8c1324e103f2c59aca4fefdeb328d6e..4113137eb921c6da4f4d13dcb2bff51df3a184fe 100644 (file)
@@ -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;
index a1b9583a44bb19070da01ef9cd3ed7a3475c2262..7bd7ea4f36ae178802f73be21db0f717802f9a18 100644 (file)
@@ -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;
index 96a80582dd54685f38bbcad371fdc386975b6f47..6e78ed42b80b71950d7fe0bdd7c6683f5ccb89fc 100644 (file)
@@ -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 
index 9f305211a9118d4224fed3558874cf248d1c979f..3a8aec3a54c6f05acf47e9b3366972a4b97edb3a 100644 (file)
@@ -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);
index 526c8c0b242f28ea4a7f602e43f92e9bdfa245b9..7f15fd2e1f17ea4ddd41d2b6cd135a2bf9c03390 100644 (file)
@@ -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;
 }
 
index 6652a6ad98945a0e83170e068894d8bdf91b327a..518988bb660edffb6c2f00ef20d2267dc182bee0 100644 (file)
@@ -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     /*{{{*/
index efef2e5882a01df63b5924ec820a64c001db947a..24e5aab88761f231ab24622e4d64bae619286137 100644 (file)
@@ -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:
 
index 49665161dd18e5a0f4e25f173c6d04be84165797..7aafe3c313bbebc59628d473c1098535413515d1 100644 (file)
 #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;
+}
+                                                                       /*}}}*/
index be02669fa4ad5d432aad8780236f9d6ed1ce6bf0..d3a8f991705abddd2f529518a5055552214402bc 100644 (file)
@@ -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) {};
index f4b816c0be468c11b7818a2905e4e8b74ff72c3c..3e4c17289eab90f4dfad01007c727d403fc2d15e 100644 (file)
@@ -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)
index 6ef7cafb09476f053bd4145d516c3ced73b278ce..2189d5111cfb7b575ef63be80a3418d0aa2df57b 100644 (file)
@@ -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();
index b07951dfb8fbf26710c8790cd73af87e30c38f3d..6a54ad5ba66afee6cf3baf609dc6b19c5592bb07 100644 (file)
@@ -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;
index 075af3eec2ab89cef855fcba67133ecd41967bb3..3ed6175ea8e1dce436e91df6f2d2c024b6588e62 100644 (file)
@@ -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;
    }
    
index 7d092062929b892bdf6250430ba8b056100419b5..6ab8594d932ef63cc9e78765f0a053a33f6dbb2a 100644 (file)
@@ -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;
index 9c2655d6a774a3b452707f2f5958ec972fc3d7ed..b22f3e73fc80ccf6ffe2943529f17aaa30561102 100644 (file)
@@ -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];
+}
+                                                                       /*}}}*/
index 08f00441463e428da12e6268c9123a5116742f55..31c444dbf9c82becf1cdde4fbf94be5eea74d890 100644 (file)
@@ -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;
index 0014563b8a6a5765ca09a692bd686016b7235d2f..7d402a2fd422675e750f4324128ddd49e94ac56f 100644 (file)
@@ -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) < (size_t)(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));
 
       bool Match = true;
       if (J->NameMatch == false)
@@ -1331,7 +1377,7 @@ bool Search(CommandLine &CmdL)
       }
    }
    
-   delete [] VFList;
+   delete [] DFList;
    for (unsigned I = 0; I != NumPatterns; I++)
       regfree(&Patterns[I]);
    if (ferror(stdout))
@@ -1360,6 +1406,19 @@ bool ShowPackage(CommandLine &CmdL)
 
       ++found;
 
+      // Show virtual packages
+      if (Pkg->ProvidesList != 0)
+      {
+        ioprintf(std::cout,_("Package %s is a virtual package provided by:\n"),
+                 Pkg.Name());
+        
+        pkgCache::PrvIterator I = Pkg.ProvidesList();
+        for (; I.end() == false; I++)
+           cout << "  " << I.OwnerPkg().Name() << endl;
+        cout << _("You should explicitly select one to show.") << endl;
+        continue;
+      }
+
       // Find the proper version to use.
       if (_config->FindB("APT::Cache::AllVersions","true") == true)
       {
index 6268f49532e1b45e39e800e7ada300a8ef8baa66..a161847c8530f2a87d7646e1a4edb1c49cdb0793 100644 (file)
@@ -1380,6 +1380,15 @@ bool DoUpgrade(CommandLine &CmdL)
 /* Install named packages */
 bool DoInstall(CommandLine &CmdL)
 {
+   // 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"));
+   }
+   
    CacheFile Cache;
    if (Cache.OpenForInstall() == false || 
        Cache.CheckDeps(CmdL.FileSize() != 1) == false)
@@ -1580,8 +1589,8 @@ bool DoInstall(CommandLine &CmdL)
       {
         pkgCache::PkgIterator I(Cache,Cache.List[J]);
 
-        /* Just look at the ones we want to install */
-        if ((*Cache)[I].Install() == false)
+        /* Just look at the ones we want to install but skip all already selected */
+        if ((*Cache)[I].Install() == false || (*Cache)[I].NewInstall() == true)
           continue;
 
         for (pkgCache::VerIterator V = I.VersionList(); V.end() == false; V++)
index f20dcc31361ea5e15d3422f20f082501a066677b..974ba5ec78c8af2319100104e55d42c7a47fed2f 100644 (file)
@@ -1,3 +1,17 @@
+apt (0.6.35os1) unstable; urgency=low
+
+   * Resync with apt--main--0--patch-71.
+     [ This include the DDTP support for testing propose, report bugs
+     directly to me ]
+
+ -- Otavio Salvador <otavio@debian.org>  Wed, 23 Mar 2005 17:19:28 -0300
+
+apt (0.6.36) hoary; urgency=low
+
+  * 
+
+ -- Matt Zimmerman <mdz@ubuntu.com>  Sat, 26 Mar 2005 08:27:23 -0800
+
 apt (0.6.35) hoary; urgency=low
 
   * Merge apt--mvo--0 (incorporates 0.6.34ubuntu1):