diff options
author | Michael Vogt <michael.vogt@ubuntu.com> | 2006-08-11 19:14:51 +0200 |
---|---|---|
committer | Michael Vogt <michael.vogt@ubuntu.com> | 2006-08-11 19:14:51 +0200 |
commit | 79f24b42cfa60fa79a427c5e37a01de303543a4b (patch) | |
tree | 3a1de45fb9b37f2e6ba71948c3c8028093f812b2 | |
parent | 2ae2e04d97028b558bfe954e55a80513e0202889 (diff) | |
parent | fb603534bf69ae4b01f5abda4e42814450e59a31 (diff) |
* merged ddtp support
31 files changed, 1217 insertions, 115 deletions
@@ -0,0 +1,9 @@ + +DDTP problems: +-------------- +- apt-get update clean the /var/lib/apt/lists dir + from all Translation-$index that are not in the current + enviroment or Translations apt variable +- there needs to be a list of locales (pt, sv, en) that need + both language and country code to get the right file + (is in the code in indexfile::LanguageCode(), just a bit ugly diff --git a/README.ddtp b/README.ddtp new file mode 100644 index 000000000..98f6109aa --- /dev/null +++ b/README.ddtp @@ -0,0 +1,74 @@ +TODO: +- URL-Remap for the translation files (to hack around the problem that + they are not on any ftp server yet but only on http://ddtp.debian.org/) + +Here is the original announcement of the ddtp support: + +* To: debian-devel-announce@lists.debian.org +* Subject: Translate files +* From: Michael Bramer <grisu@debian.org> +* Date: Sun, 6 Oct 2002 21:56:06 +0200 +* Mail-followup-to: debian-devel@lists.debian.org +* Message-id: <20021006195605.GA30516@home.debsupport.de> +* Old-return-path: <michael@home.debsupport.de> +* User-agent: Mutt/1.3.28i + +Hello all + +After some discussion between Anthony Towns (a ftpmaster), Jason +Gunthorpe (APT Developer) and some DDTP Coordinators we find a way to +transfer the translated package descriptions from the archive to the +user. + +The translated descriptions need to be downloadable befor any +installation process, like the other package meta information. We +choose a new file per languages with all translated package +descriptions. The package system can download one or more of this +files at 'apt-get update' time and know the translations. + +The new files are names 'Translate-$lang' and the file have this +rfc822-format: + Package: <package-name> + Description-md5: <the md5 checksum of the english description> + Description-$lang.$encoding: <translated headline> + <translated section> + +The encoding of the Description is 'UTF-8' in all languages normal. +The files will be located at 'debian/dists/sid/main/i18n/' on the ftp +server (for all architecture). In addition of the plain +'Translate-$lang' file, there will be a 'gz' and a 'bz2' version and +in future also the new incremental format version. + +The <the md5 checksum of the english description> is the md5 checksum +of the full english description, without the 'Description: '-tag and +with all spaces and newlines. Look at this example: + Description: XXX + YYY + . + ZZZ +is md5("XXX\n YYY\n .\n ZZZ\n") (perl-syntax). + + +A future APT version will download one or some 'Translate-$lang' +file(s) at 'update'-time. After this download it show a translated +description instead of the english form, if it found a translated +description of the package with the right md5 chechsum. The enviroment +of the user will controlled this process (LANG, LANGUAGE, LC_MESSAGES, +etc). With this the package system will never show a outdated +translation. + +The translations come all from the DDTP. A daily process on +ddtp.debian.org make new 'Translated-$lang' files and a script on +ftp-master request this files and move this to the debian archive. +Now the first files are accessable at + <a href="http://ddtp.debian.org/pdesc/translatefiles/">http://ddtp.debian.org/pdesc/translatefiles/</a> + +If you found wrong translations, please read the guides on +ddtp.debian.org, make a better translation and send this per mail to +the DDTP server. Don't bug the package maintainer! + +Thanks +Grisu +-- +Michael Bramer - a Debian Linux Developer <a href="http://www.debsupport.de">http://www.debsupport.de</a> +PGP: finger grisu@db.debian.org -- Linux Sysadmin -- Use Debian Linux diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 18ce1076f..2ecb77814 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -308,6 +308,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 1c83f8d2e..3a0a690e1 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. + Three 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. @@ -108,6 +108,16 @@ class pkgAcqIndex : public pkgAcquire::Item string ShortDesct, string ExpectedMD5, string compressExt=""); }; +// Item class for translated package 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 2b326bd65..d5a9c7b0d 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -99,7 +99,7 @@ class pkgCache::VerIterator { Version *Ver; pkgCache *Owner; - + void _dummy(); public: @@ -128,6 +128,8 @@ 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; + DescIterator TranslatedDescription() const; inline DepIterator DependsList() const; inline PrvIterator ProvidesList() const; inline VerFileIterator FileList() const; @@ -148,6 +150,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 { @@ -338,6 +384,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);}; @@ -347,11 +425,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/cdrom.cc b/apt-pkg/cdrom.cc index ce1beb39b..b42c82dd0 100644 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@ -30,12 +30,16 @@ using namespace std; search that short circuits when it his a package file in the dir. This speeds it up greatly as the majority of the size is in the binary-* sub dirs. */ -bool pkgCdrom::FindPackages(string CD,vector<string> &List, - vector<string> &SList, vector<string> &SigList, +bool pkgCdrom::FindPackages(string CD, + vector<string> &List, + vector<string> &SList, + vector<string> &SigList, + vector<string> &TransList, string &InfoDir, pkgCdromStatus *log, unsigned int Depth) { static ino_t Inodes[9]; + DIR *D; // if we have a look we "pulse" now if(log) @@ -90,8 +94,28 @@ bool pkgCdrom::FindPackages(string CD,vector<string> &List, if (_config->FindB("APT::CDROM::Thorough",false) == false) return true; } + + // see if we find translatin indexes + if (stat("i18n",&Buf) == 0) + { + D = opendir("i18n"); + for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D)) + { + if(strstr(Dir->d_name,"Translation") != NULL) + { + if (_config->FindB("Debug::aptcdrom",false) == true) + std::clog << "found translations: " << Dir->d_name << "\n"; + string file = Dir->d_name; + if(file.substr(file.size()-3,file.size()) == ".gz") + file = file.substr(0,file.size()-3); + TransList.push_back(CD+"i18n/"+ file); + } + } + closedir(D); + } + - DIR *D = opendir("."); + D = opendir("."); if (D == 0) return _error->Errno("opendir","Unable to read %s",CD.c_str()); @@ -127,7 +151,7 @@ bool pkgCdrom::FindPackages(string CD,vector<string> &List, Inodes[Depth] = Buf.st_ino; // Descend - if (FindPackages(CD + Dir->d_name,List,SList,SigList,InfoDir,log,Depth+1) == false) + if (FindPackages(CD + Dir->d_name,List,SList,SigList,TransList,InfoDir,log,Depth+1) == false) break; if (chdir(CD.c_str()) != 0) @@ -612,9 +636,10 @@ bool pkgCdrom::Add(pkgCdromStatus *log) vector<string> List; vector<string> SourceList; vector<string> SigList; + vector<string> TransList; string StartDir = SafeGetCWD(); string InfoDir; - if (FindPackages(CDROM,List,SourceList, SigList,InfoDir,log) == false) + if (FindPackages(CDROM,List,SourceList, SigList,TransList,InfoDir,log) == false) { log->Update("\n"); return false; @@ -642,11 +667,13 @@ bool pkgCdrom::Add(pkgCdromStatus *log) DropRepeats(List,"Packages"); DropRepeats(SourceList,"Sources"); DropRepeats(SigList,"Release.gpg"); + DropRepeats(TransList,""); if(log) { msg.str(""); - ioprintf(msg, _("Found %i package indexes, %i source indexes and " - "%i signatures\n"), - List.size(), SourceList.size(), SigList.size()); + ioprintf(msg, _("Found %i package indexes, %i source indexes, " + "%i translation indexes and %i signatures\n"), + List.size(), SourceList.size(), TransList.size(), + SigList.size()); log->Update(msg.str(), STEP_SCAN); } @@ -736,8 +763,10 @@ bool pkgCdrom::Add(pkgCdromStatus *log) // Copy the package files to the state directory PackageCopy Copy; SourceCopy SrcCopy; + TranslationsCopy TransCopy; if (Copy.CopyPackages(CDROM,Name,List, log) == false || - SrcCopy.CopyPackages(CDROM,Name,SourceList, log) == false) + SrcCopy.CopyPackages(CDROM,Name,SourceList, log) == false || + TransCopy.CopyTranslations(CDROM,Name,TransList, log) == false) return false; // reduce the List so that it takes less space in sources.list diff --git a/apt-pkg/cdrom.h b/apt-pkg/cdrom.h index 085eb64e2..e18aaff3e 100644 --- a/apt-pkg/cdrom.h +++ b/apt-pkg/cdrom.h @@ -50,8 +50,11 @@ class pkgCdrom }; - bool FindPackages(string CD,vector<string> &List, - vector<string> &SList, vector<string> &SigList, + bool FindPackages(string CD, + vector<string> &List, + vector<string> &SList, + vector<string> &SigList, + vector<string> &TransList, string &InfoDir, pkgCdromStatus *log, unsigned int Depth = 0); bool DropBinaryArch(vector<string> &List); diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index d96155917..37d263794 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 diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index 6ec2b7811..254087267 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 ff8bce85d..38ecdd16a 100644 --- a/apt-pkg/deb/debindexfile.cc +++ b/apt-pkg/deb/debindexfile.cc @@ -320,6 +320,170 @@ 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 (TranslationsAvailable()) { + 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; +} + /*}}}*/ +bool debTranslationsIndex::HasPackages() const +{ + if(!TranslationsAvailable()) + return false; + + return FileExists(IndexFile(LanguageCode().c_str())); +} + +// TranslationsIndex::Exists - Check if the index is available /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debTranslationsIndex::Exists() const +{ + return FileExists(IndexFile(LanguageCode().c_str())); +} + /*}}}*/ +// 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 (TranslationsAvailable() && 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; +} + /*}}}*/ +// TranslationsIndex::FindInCache - Find this index /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgCache::PkgFileIterator debTranslationsIndex::FindInCache(pkgCache &Cache) const +{ + string FileName = IndexFile(LanguageCode().c_str()); + + pkgCache::PkgFileIterator File = Cache.FileBegin(); + for (; File.end() == false; File++) + { + if (FileName != File.FileName()) + continue; + + struct stat St; + if (stat(File.FileName(),&St) != 0) + return pkgCache::PkgFileIterator(Cache); + if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) + return pkgCache::PkgFileIterator(Cache); + return File; + } + return File; +} + /*}}}*/ // StatusIndex::debStatusIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -416,6 +580,11 @@ class debIFTypePkg : public pkgIndexFile::Type }; debIFTypePkg() {Label = "Debian Package Index";}; }; +class debIFTypeTrans : public debIFTypePkg +{ + public: + debIFTypeTrans() {Label = "Debian Translation Index";}; +}; class debIFTypeStatus : public pkgIndexFile::Type { public: @@ -428,6 +597,7 @@ class debIFTypeStatus : public pkgIndexFile::Type }; static debIFTypeSrc _apt_Src; static debIFTypePkg _apt_Pkg; +static debIFTypeTrans _apt_Trans; static debIFTypeStatus _apt_Status; const pkgIndexFile::Type *debSourcesIndex::GetType() const @@ -438,6 +608,10 @@ const pkgIndexFile::Type *debPackagesIndex::GetType() const { return &_apt_Pkg; } +const pkgIndexFile::Type *debTranslationsIndex::GetType() const +{ + return &_apt_Trans; +} 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..57005222f 100644 --- a/apt-pkg/deb/debindexfile.h +++ b/apt-pkg/deb/debindexfile.h @@ -74,6 +74,36 @@ 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; + virtual unsigned long Size() const; + virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const; + virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) 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 d0dc7a260..c2b26b5eb 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,48 @@ 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 it is the right + description. If no Description-md5 is found in the section it will be + calculated. + */ +MD5SumValue debListParser::Description_md5() +{ + string value = Section.FindS("Description-md5"); + + if (value.empty()) + { + MD5Summation md5; + md5.Add((Description() + "\n").c_str()); + return md5.Result(); + } else + return MD5SumValue(value); +} + /*}}}*/ // ListParser::UsePackage - Update a package structure /*{{{*/ // --------------------------------------------------------------------- /* This is called to update the package with any new information diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 3a0e0421b..34bb29c72 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 85e5b16b3..8cf31b326 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -157,6 +157,16 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool GetAll) const ComputeIndexTargets(), new indexRecords (Dist)); + // Queue the translations + for (vector<const debSectionEntry *>::const_iterator I = SectionEntries.begin(); + I != SectionEntries.end(); I++) { + + if((*I)->IsSrc) + continue; + debTranslationsIndex i = debTranslationsIndex(URI,Dist,(*I)->Section); + i.GetIndexes(Owner); + } + return true; } @@ -181,11 +191,16 @@ 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/indexcopy.cc b/apt-pkg/indexcopy.cc index 1f65062f7..c9dded134 100644 --- a/apt-pkg/indexcopy.cc +++ b/apt-pkg/indexcopy.cc @@ -32,6 +32,8 @@ using namespace std; + + // IndexCopy::CopyPackages - Copy the package files from the CD /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -512,10 +514,10 @@ bool SourceCopy::RewriteEntry(FILE *Target,string File) fputc('\n',Target); return true; } - - /*}}}*/ - +// SigVerify::Verify - Verify a files md5sum against its metaindex /*{{{*/ +// --------------------------------------------------------------------- +/* */ bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex) { const indexRecords::checkSum *Record = MetaIndex->Lookup(file); @@ -670,3 +672,178 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList, return true; } + + +bool TranslationsCopy::CopyTranslations(string CDROM,string Name,vector<string> &List, + pkgCdromStatus *log) +{ + OpProgress *Progress = NULL; + if (List.size() == 0) + return true; + + if(log) + Progress = log->GetOpProgress(); + + bool Debug = _config->FindB("Debug::aptcdrom",false); + + // Prepare the progress indicator + unsigned long TotalSize = 0; + for (vector<string>::iterator I = List.begin(); I != List.end(); I++) + { + struct stat Buf; + if (stat(string(*I).c_str(),&Buf) != 0 && + stat(string(*I + ".gz").c_str(),&Buf) != 0) + return _error->Errno("stat","Stat failed for %s", + string(*I).c_str()); + TotalSize += Buf.st_size; + } + + unsigned long CurrentSize = 0; + unsigned int NotFound = 0; + unsigned int WrongSize = 0; + unsigned int Packages = 0; + for (vector<string>::iterator I = List.begin(); I != List.end(); I++) + { + string OrigPath = string(*I,CDROM.length()); + unsigned long FileSize = 0; + + // Open the package file + FileFd Pkg; + if (FileExists(*I) == true) + { + Pkg.Open(*I,FileFd::ReadOnly); + FileSize = Pkg.Size(); + } + else + { + FileFd From(*I + ".gz",FileFd::ReadOnly); + if (_error->PendingError() == true) + return false; + FileSize = From.Size(); + + // Get a temp file + FILE *tmp = tmpfile(); + if (tmp == 0) + return _error->Errno("tmpfile","Unable to create a tmp file"); + Pkg.Fd(dup(fileno(tmp))); + fclose(tmp); + + // Fork gzip + pid_t Process = fork(); + if (Process < 0) + return _error->Errno("fork","Couldn't fork gzip"); + + // The child + if (Process == 0) + { + dup2(From.Fd(),STDIN_FILENO); + dup2(Pkg.Fd(),STDOUT_FILENO); + SetCloseExec(STDIN_FILENO,false); + SetCloseExec(STDOUT_FILENO,false); + + const char *Args[3]; + string Tmp = _config->Find("Dir::bin::gzip","gzip"); + Args[0] = Tmp.c_str(); + Args[1] = "-d"; + Args[2] = 0; + execvp(Args[0],(char **)Args); + exit(100); + } + + // Wait for gzip to finish + if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false) + return _error->Error("gzip failed, perhaps the disk is full."); + + Pkg.Seek(0); + } + pkgTagFile Parser(&Pkg); + if (_error->PendingError() == true) + return false; + + // Open the output file + char S[400]; + snprintf(S,sizeof(S),"cdrom:[%s]/%s",Name.c_str(), + (*I).c_str() + CDROM.length()); + string TargetF = _config->FindDir("Dir::State::lists") + "partial/"; + TargetF += URItoFileName(S); + if (_config->FindB("APT::CDROM::NoAct",false) == true) + TargetF = "/dev/null"; + FileFd Target(TargetF,FileFd::WriteEmpty); + FILE *TargetFl = fdopen(dup(Target.Fd()),"w"); + if (_error->PendingError() == true) + return false; + if (TargetFl == 0) + return _error->Errno("fdopen","Failed to reopen fd"); + + // Setup the progress meter + if(Progress) + Progress->OverallProgress(CurrentSize,TotalSize,FileSize, + string("Reading Translation Indexes")); + + // Parse + if(Progress) + Progress->SubProgress(Pkg.Size()); + pkgTagSection Section; + this->Section = &Section; + string Prefix; + unsigned long Hits = 0; + unsigned long Chop = 0; + while (Parser.Step(Section) == true) + { + if(Progress) + Progress->Progress(Parser.Offset()); + + const char *Start; + const char *Stop; + Section.GetSection(Start,Stop); + fwrite(Start,Stop-Start, 1, TargetFl); + fputc('\n',TargetFl); + + Packages++; + Hits++; + } + fclose(TargetFl); + + if (Debug == true) + cout << " Processed by using Prefix '" << Prefix << "' and chop " << Chop << endl; + + if (_config->FindB("APT::CDROM::NoAct",false) == false) + { + // Move out of the partial directory + Target.Close(); + string FinalF = _config->FindDir("Dir::State::lists"); + FinalF += URItoFileName(S); + if (rename(TargetF.c_str(),FinalF.c_str()) != 0) + return _error->Errno("rename","Failed to rename"); + } + + + CurrentSize += FileSize; + } + if(Progress) + Progress->Done(); + + // Some stats + if(log) { + stringstream msg; + if(NotFound == 0 && WrongSize == 0) + ioprintf(msg, _("Wrote %i records.\n"), Packages); + else if (NotFound != 0 && WrongSize == 0) + ioprintf(msg, _("Wrote %i records with %i missing files.\n"), + Packages, NotFound); + else if (NotFound == 0 && WrongSize != 0) + ioprintf(msg, _("Wrote %i records with %i mismatched files\n"), + Packages, WrongSize); + if (NotFound != 0 && WrongSize != 0) + ioprintf(msg, _("Wrote %i records with %i missing files and %i mismatched files\n"), Packages, NotFound, WrongSize); + } + + if (Packages == 0) + _error->Warning("No valid records were found."); + + if (NotFound + WrongSize > 10) + _error->Warning("Alot of entries were discarded, something may be wrong.\n"); + + + return true; +} diff --git a/apt-pkg/indexcopy.h b/apt-pkg/indexcopy.h index 4dcb2b46d..7778ae595 100644 --- a/apt-pkg/indexcopy.h +++ b/apt-pkg/indexcopy.h @@ -70,6 +70,17 @@ class SourceCopy : public IndexCopy public: }; +class TranslationsCopy +{ + protected: + pkgTagSection *Section; + + public: + bool CopyTranslations(string CDROM,string Name,vector<string> &List, + pkgCdromStatus *log); +}; + + class SigVerify { bool Verify(string prefix,string file, indexRecords *records); @@ -81,4 +92,6 @@ class SigVerify vector<string> PkgList,vector<string> SrcList); }; + + #endif diff --git a/apt-pkg/indexfile.cc b/apt-pkg/indexfile.cc index 49665161d..bb2210bf6 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,63 @@ string pkgIndexFile::SourceInfo(pkgSrcRecords::Parser const &Record, return string(); } /*}}}*/ +// IndexFile::TranslationsAvailable - Check if will use Translation /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgIndexFile::TranslationsAvailable() +{ + 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 /*{{{*/ +// --------------------------------------------------------------------- +/* */ +/* common cases: de_DE, de_DE@euro, de_DE.UTF-8, de_DE.UTF-8@euro, + de_DE.ISO8859-1, tig_ER + more in /etc/gdm/locale.conf +*/ + +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 /*{{{*/ +// --------------------------------------------------------------------- +/* return the language code */ +string pkgIndexFile::LanguageCode() +{ + const string Translation = _config->Find("APT::Acquire::Translation"); + + if (Translation.compare("environment") == 0) + { + string lang = std::setlocale(LC_MESSAGES,NULL); + + // we have a mapping of the language codes that contains all the language + // codes that need the country code as well + // (like pt_BR, pt_PT, sv_SE, zh_*, en_*) + char *need_full_langcode[] = { "pt","sv","zh","en", NULL }; + for(char **s = need_full_langcode;*s != NULL; s++) + if(lang.find(*s) == 0) + return lang.substr(0,5); + + if(lang.size() > 2) + return lang.substr(0,2); + else + return lang; + } + else + return Translation; +} + /*}}}*/ diff --git a/apt-pkg/indexfile.h b/apt-pkg/indexfile.h index 61049f4bd..d5d1cf57a 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 @@ -80,6 +81,10 @@ class pkgIndexFile virtual bool MergeFileProvides(pkgCacheGenerator &/*Gen*/,OpProgress &/*Prog*/) const {return true;}; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; + static bool TranslationsAvailable(); + 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 a26f1d01c..579a19ab9 100644 --- a/apt-pkg/init.cc +++ b/apt-pkg/init.cc @@ -104,6 +104,9 @@ bool pkgInitConfig(Configuration &Cnf) bindtextdomain(textdomain(0),Cnf.FindDir("Dir::Locale").c_str()); } #endif + + // Translation + Cnf.Set("APT::Acquire::Translation", "environment"); return true; } diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 9926befe9..162ab4f27 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -26,6 +26,7 @@ #endif #include <apt-pkg/pkgcache.h> +#include <apt-pkg/indexfile.h> #include <apt-pkg/version.h> #include <apt-pkg/error.h> #include <apt-pkg/strutl.h> @@ -43,6 +44,7 @@ using std::string; + // Cache::Header::Header - Constructor /*{{{*/ // --------------------------------------------------------------------- /* Simply initialize the header */ @@ -52,7 +54,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 +62,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 +96,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 +124,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(); @@ -235,11 +246,11 @@ const char *pkgCache::Priority(unsigned char Prio) return 0; } /*}}}*/ - // Bases for iterator classes /*{{{*/ void pkgCache::VerIterator::_dummy() {} void pkgCache::DepIterator::_dummy() {} void pkgCache::PrvIterator::_dummy() {} +void pkgCache::DescIterator::_dummy() {} /*}}}*/ // PkgIterator::operator ++ - Postfix incr /*{{{*/ // --------------------------------------------------------------------- @@ -599,3 +610,20 @@ string pkgCache::PkgFileIterator::RelStr() return Res; } /*}}}*/ +// VerIterator::TranslatedDescription - Return the a DescIter for locale/*{{{*/ +// --------------------------------------------------------------------- +/* return a DescIter for the current locale or the default if none is + * found + */ +pkgCache::DescIterator pkgCache::VerIterator::TranslatedDescription() const +{ + pkgCache::DescIterator DescDefault = DescriptionList(); + pkgCache::DescIterator Desc = DescDefault; + for (; Desc.end() == false; Desc++) + if (pkgIndexFile::LanguageCode() == Desc.LanguageCode()) + break; + if (Desc.end() == true) Desc = DescDefault; + return Desc; +}; + + /*}}}*/ diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 587d97534..c7a3172cc 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 4ac4d1d1c..b2725a99d 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -127,16 +127,46 @@ bool pkgCacheGenerator::MergeList(ListParser &List, string Version = List.Version(); if (Version.empty() == true) { + // we first process the package, then the descriptions + // (this has the bonus that we get MMap error when we run out + // of MMap space) if (List.UsePackage(Pkg,pkgCache::VerIterator(Cache)) == false) return _error->Error(_("Error occurred while processing %s (UsePackage1)"), PackageName.c_str()); + + // 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; + } + } + } + continue; } 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) @@ -170,7 +200,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) @@ -179,9 +209,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 occurred while processing %s (NewVersion1)"), PackageName.c_str()); @@ -201,6 +232,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(); @@ -211,6 +257,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.")); @@ -273,7 +322,7 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const 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) @@ -351,6 +400,62 @@ 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 @@ -584,7 +689,7 @@ static bool CheckValidity(const 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 9a729eea4..fae1a60a6 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,const string &Pkg); bool NewFileVer(pkgCache::VerIterator &Ver,ListParser &List); + bool NewFileDesc(pkgCache::DescIterator &Desc,ListParser &List); unsigned long NewVersion(pkgCache::VerIterator &Ver,const string &VerStr,unsigned long Next); + map_ptrloc NewDescription(pkgCache::DescIterator &Desc,const string &Lang,const MD5SumValue &md5sum,map_ptrloc Next); public: @@ -108,6 +111,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; diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc index aea9ebeba..74fa71cba 100644 --- a/cmdline/apt-cache.cc +++ b/cmdline/apt-cache.cc @@ -71,6 +71,12 @@ void LocalitySort(pkgCache::VerFile **begin, { qsort(begin,Count,Size,LocalityCompare); } + +void LocalitySort(pkgCache::DescFile **begin, + unsigned long Count,size_t Size) +{ + qsort(begin,Count,Size,LocalityCompare); +} /*}}}*/ // UnMet - Show unmet dependencies /*{{{*/ // --------------------------------------------------------------------- @@ -182,7 +188,14 @@ bool DumpPackage(CommandLine &CmdL) { cout << Cur.VerStr(); for (pkgCache::VerFileIterator Vf = Cur.FileList(); Vf.end() == false; Vf++) - cout << "(" << Vf.File().FileName() << ")"; + cout << " (" << Vf.File().FileName() << ")"; + cout << endl; + for (pkgCache::DescIterator D = Cur.DescriptionList(); D.end() == false; D++) + { + cout << " Description Language: " << D.LanguageCode() << endl + << " File: " << D.FileList().File().FileName() << endl + << " MD5: " << D.md5() << endl; + } cout << endl; } @@ -277,11 +290,15 @@ bool Stats(CommandLine &Cmd) cout << _("Total distinct versions: ") << Cache.Head().VersionCount << " (" << SizeToStr(Cache.Head().VersionCount*Cache.Head().VersionSz) << ')' << endl; + cout << _("Total Distinct Descriptions: ") << Cache.Head().DescriptionCount << " (" << + SizeToStr(Cache.Head().DescriptionCount*Cache.Head().DescriptionSz) << ')' << endl; cout << _("Total dependencies: ") << Cache.Head().DependsCount << " (" << SizeToStr(Cache.Head().DependsCount*Cache.Head().DependencySz) << ')' << endl; cout << _("Total ver/file relations: ") << Cache.Head().VerFileCount << " (" << SizeToStr(Cache.Head().VerFileCount*Cache.Head().VerFileSz) << ')' << endl; + cout << _("Total Desc/File relations: ") << Cache.Head().DescFileCount << " (" << + SizeToStr(Cache.Head().DescFileCount*Cache.Head().DescFileSz) << ')' << endl; cout << _("Total Provides mappings: ") << Cache.Head().ProvidesCount << " (" << SizeToStr(Cache.Head().ProvidesCount*Cache.Head().ProvidesSz) << ')' << endl; @@ -344,6 +361,12 @@ bool Dump(CommandLine &Cmd) for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++) cout << " Depends: " << D.TargetPkg().Name() << ' ' << DeNull(D.TargetVer()) << endl; + for (pkgCache::DescIterator D = V.DescriptionList(); D.end() == false; D++) + { + cout << " Description Language: " << D.LanguageCode() << endl + << " File: " << D.FileList().File().FileName() << endl + << " MD5: " << D.md5() << endl; + } } } @@ -1192,17 +1215,50 @@ 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; } - + + // Get a pointer to start of Description field + const unsigned char *DescP = (unsigned char*)strstr((char*)Buffer, "Description:"); + + // Write all but Description + if (fwrite(Buffer,1,DescP - Buffer,stdout) < (size_t)(DescP - Buffer)) + { + delete [] Buffer; + return false; + } + + // Show the right description + pkgRecords Recs(*GCache); + pkgCache::DescIterator Desc = V.TranslatedDescription(); + pkgRecords::Parser &P = Recs.Lookup(Desc.FileList()); + cout << "Description" << ( (strcmp(Desc.LanguageCode(),"") != 0) ? "-" : "" ) << Desc.LanguageCode() << ": " << P.LongDesc(); + + // Find the first field after the description (if there is any) + for(DescP++;DescP != &Buffer[V.FileList()->Size];DescP++) + { + if(*DescP == '\n' && *(DescP+1) != ' ') + { + // write the rest of the buffer + const unsigned char *end=&Buffer[V.FileList()->Size]; + if (fwrite(DescP,1,end-DescP,stdout) < (size_t)(end-DescP)) + { + delete [] Buffer; + return false; + } + + break; + } + } + // write a final newline (after the description) + cout<<endl; delete [] Buffer; return true; @@ -1211,9 +1267,9 @@ bool DisplayRecord(pkgCache::VerIterator V) // 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 +1309,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 +1345,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 +1387,7 @@ bool Search(CommandLine &CmdL) } } - delete [] VFList; + delete [] DFList; for (unsigned I = 0; I != NumPatterns; I++) regfree(&Patterns[I]); if (ferror(stdout)) diff --git a/configure.in b/configure.in index aa9abc1e6..d9134f4b1 100644 --- a/configure.in +++ b/configure.in @@ -18,7 +18,7 @@ AC_CONFIG_AUX_DIR(buildlib) AC_CONFIG_HEADER(include/config.h:buildlib/config.h.in include/apti18n.h:buildlib/apti18n.h.in) dnl -- SET THIS TO THE RELEASE VERSION -- -AC_DEFINE_UNQUOTED(VERSION,"0.6.45ubuntu2") +AC_DEFINE_UNQUOTED(VERSION,"0.6.45ubuntu3") PACKAGE="apt" AC_DEFINE_UNQUOTED(PACKAGE,"$PACKAGE") AC_SUBST(PACKAGE) diff --git a/debian/changelog b/debian/changelog index 946971906..16678d805 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,8 +5,9 @@ apt (0.6.45ubuntu3) edgy; urgency=low * added "--fix-policy" option to can be used as "--fix-broken" and will install missing weak depends (recommends, and/or suggests depending on the settings) + * merged the apt--ddtp branch - -- + -- Michael Vogt <michael.vogt@ubuntu.com> Fri, 11 Aug 2006 12:53:23 +0200 apt (0.6.45ubuntu2) edgy; urgency=low diff --git a/po/apt-all.pot b/po/apt-all.pot index 8567df7ca..586f9e545 100644 --- a/po/apt-all.pot +++ b/po/apt-all.pot @@ -244,6 +244,7 @@ msgid "" msgstr "" #: cmdline/apt-extracttemplates.cc:267 apt-pkg/pkgcachegen.cc:714 +#: apt-pkg/pkgcachegen.cc:819 #, c-format msgid "Unable to write to %s" msgstr "" @@ -1376,7 +1377,9 @@ msgstr "" #. Build the status cache #: apt-inst/deb/dpkgdb.cc:139 apt-pkg/pkgcachegen.cc:647 #: apt-pkg/pkgcachegen.cc:716 apt-pkg/pkgcachegen.cc:721 -#: apt-pkg/pkgcachegen.cc:844 +#: apt-pkg/pkgcachegen.cc:844 apt-pkg/pkgcachegen.cc:752 +#: apt-pkg/pkgcachegen.cc:821 apt-pkg/pkgcachegen.cc:826 +#: apt-pkg/pkgcachegen.cc:949 msgid "Reading package lists" msgstr "" @@ -1848,7 +1851,7 @@ msgstr "" msgid "Couldn't make mmap of %lu bytes" msgstr "" -#: apt-pkg/contrib/strutl.cc:938 +#: apt-pkg/contrib/strutl.cc:938 apt-pkg/contrib/strutl.cc:981 #, c-format msgid "Selection %s not found" msgstr "" @@ -2045,72 +2048,72 @@ msgstr "" msgid "Problem syncing the file" msgstr "" -#: apt-pkg/pkgcache.cc:126 +#: apt-pkg/pkgcache.cc:126 apt-pkg/pkgcache.cc:137 msgid "Empty package cache" msgstr "" -#: apt-pkg/pkgcache.cc:132 +#: apt-pkg/pkgcache.cc:132 apt-pkg/pkgcache.cc:143 msgid "The package cache file is corrupted" msgstr "" -#: apt-pkg/pkgcache.cc:137 +#: apt-pkg/pkgcache.cc:137 apt-pkg/pkgcache.cc:148 msgid "The package cache file is an incompatible version" msgstr "" -#: apt-pkg/pkgcache.cc:142 +#: apt-pkg/pkgcache.cc:142 apt-pkg/pkgcache.cc:153 #, c-format msgid "This APT does not support the versioning system '%s'" msgstr "" -#: apt-pkg/pkgcache.cc:147 +#: apt-pkg/pkgcache.cc:147 apt-pkg/pkgcache.cc:158 msgid "The package cache was built for a different architecture" msgstr "" -#: apt-pkg/pkgcache.cc:218 +#: apt-pkg/pkgcache.cc:218 apt-pkg/pkgcache.cc:229 msgid "Depends" msgstr "" -#: apt-pkg/pkgcache.cc:218 +#: apt-pkg/pkgcache.cc:218 apt-pkg/pkgcache.cc:229 msgid "PreDepends" msgstr "" -#: apt-pkg/pkgcache.cc:218 +#: apt-pkg/pkgcache.cc:218 apt-pkg/pkgcache.cc:229 msgid "Suggests" msgstr "" -#: apt-pkg/pkgcache.cc:219 +#: apt-pkg/pkgcache.cc:219 apt-pkg/pkgcache.cc:230 msgid "Recommends" msgstr "" -#: apt-pkg/pkgcache.cc:219 +#: apt-pkg/pkgcache.cc:219 apt-pkg/pkgcache.cc:230 msgid "Conflicts" msgstr "" -#: apt-pkg/pkgcache.cc:219 +#: apt-pkg/pkgcache.cc:219 apt-pkg/pkgcache.cc:230 msgid "Replaces" msgstr "" -#: apt-pkg/pkgcache.cc:220 +#: apt-pkg/pkgcache.cc:220 apt-pkg/pkgcache.cc:231 msgid "Obsoletes" msgstr "" -#: apt-pkg/pkgcache.cc:231 +#: apt-pkg/pkgcache.cc:231 apt-pkg/pkgcache.cc:242 msgid "important" msgstr "" -#: apt-pkg/pkgcache.cc:231 +#: apt-pkg/pkgcache.cc:231 apt-pkg/pkgcache.cc:242 msgid "required" msgstr "" -#: apt-pkg/pkgcache.cc:231 +#: apt-pkg/pkgcache.cc:231 apt-pkg/pkgcache.cc:242 msgid "standard" msgstr "" -#: apt-pkg/pkgcache.cc:232 +#: apt-pkg/pkgcache.cc:232 apt-pkg/pkgcache.cc:243 msgid "optional" msgstr "" -#: apt-pkg/pkgcache.cc:232 +#: apt-pkg/pkgcache.cc:232 apt-pkg/pkgcache.cc:243 msgid "extra" msgstr "" @@ -2180,7 +2183,7 @@ msgstr "" msgid "Opening %s" msgstr "" -#: apt-pkg/sourcelist.cc:220 apt-pkg/cdrom.cc:426 +#: apt-pkg/sourcelist.cc:220 apt-pkg/cdrom.cc:426 apt-pkg/cdrom.cc:450 #, c-format msgid "Line %u too long in source list %s." msgstr "" @@ -2266,12 +2269,12 @@ msgstr "" msgid "Please insert the disc labeled: '%s' in the drive '%s' and press enter." msgstr "" -#: apt-pkg/init.cc:122 +#: apt-pkg/init.cc:122 apt-pkg/init.cc:125 #, c-format msgid "Packaging system '%s' is not supported" msgstr "" -#: apt-pkg/init.cc:138 +#: apt-pkg/init.cc:138 apt-pkg/init.cc:141 msgid "Unable to determine a suitable packaging system type" msgstr "" @@ -2314,73 +2317,74 @@ msgstr "" msgid "Error occurred while processing %s (NewPackage)" msgstr "" -#: apt-pkg/pkgcachegen.cc:131 +#: apt-pkg/pkgcachegen.cc:131 apt-pkg/pkgcachegen.cc:134 #, c-format msgid "Error occurred while processing %s (UsePackage1)" msgstr "" -#: apt-pkg/pkgcachegen.cc:152 +#: apt-pkg/pkgcachegen.cc:152 apt-pkg/pkgcachegen.cc:182 #, c-format msgid "Error occurred while processing %s (UsePackage2)" msgstr "" -#: apt-pkg/pkgcachegen.cc:156 +#: apt-pkg/pkgcachegen.cc:156 apt-pkg/pkgcachegen.cc:186 #, c-format msgid "Error occurred while processing %s (NewFileVer1)" msgstr "" -#: apt-pkg/pkgcachegen.cc:186 +#: apt-pkg/pkgcachegen.cc:186 apt-pkg/pkgcachegen.cc:217 #, c-format msgid "Error occurred while processing %s (NewVersion1)" msgstr "" -#: apt-pkg/pkgcachegen.cc:190 +#: apt-pkg/pkgcachegen.cc:190 apt-pkg/pkgcachegen.cc:221 #, c-format msgid "Error occurred while processing %s (UsePackage3)" msgstr "" -#: apt-pkg/pkgcachegen.cc:194 +#: apt-pkg/pkgcachegen.cc:194 apt-pkg/pkgcachegen.cc:225 #, c-format msgid "Error occurred while processing %s (NewVersion2)" msgstr "" -#: apt-pkg/pkgcachegen.cc:209 +#: apt-pkg/pkgcachegen.cc:209 apt-pkg/pkgcachegen.cc:255 msgid "Wow, you exceeded the number of package names this APT is capable of." msgstr "" -#: apt-pkg/pkgcachegen.cc:212 +#: apt-pkg/pkgcachegen.cc:212 apt-pkg/pkgcachegen.cc:258 msgid "Wow, you exceeded the number of versions this APT is capable of." msgstr "" -#: apt-pkg/pkgcachegen.cc:215 +#: apt-pkg/pkgcachegen.cc:215 apt-pkg/pkgcachegen.cc:264 msgid "Wow, you exceeded the number of dependencies this APT is capable of." msgstr "" -#: apt-pkg/pkgcachegen.cc:243 +#: apt-pkg/pkgcachegen.cc:243 apt-pkg/pkgcachegen.cc:292 #, c-format msgid "Error occurred while processing %s (FindPkg)" msgstr "" -#: apt-pkg/pkgcachegen.cc:256 +#: apt-pkg/pkgcachegen.cc:256 apt-pkg/pkgcachegen.cc:305 #, c-format msgid "Error occurred while processing %s (CollectFileProvides)" msgstr "" -#: apt-pkg/pkgcachegen.cc:262 +#: apt-pkg/pkgcachegen.cc:262 apt-pkg/pkgcachegen.cc:311 #, c-format msgid "Package %s %s was not found while processing file dependencies" msgstr "" -#: apt-pkg/pkgcachegen.cc:577 +#: apt-pkg/pkgcachegen.cc:577 apt-pkg/pkgcachegen.cc:682 #, c-format msgid "Couldn't stat source package list %s" msgstr "" -#: apt-pkg/pkgcachegen.cc:662 +#: apt-pkg/pkgcachegen.cc:662 apt-pkg/pkgcachegen.cc:767 msgid "Collecting File Provides" msgstr "" #: apt-pkg/pkgcachegen.cc:789 apt-pkg/pkgcachegen.cc:796 +#: apt-pkg/pkgcachegen.cc:894 apt-pkg/pkgcachegen.cc:901 msgid "IO Error saving source cache" msgstr "" @@ -2390,34 +2394,35 @@ msgid "rename failed, %s (%s -> %s)." msgstr "" #: apt-pkg/acquire-item.cc:236 apt-pkg/acquire-item.cc:951 +#: apt-pkg/acquire-item.cc:980 msgid "MD5Sum mismatch" msgstr "" -#: apt-pkg/acquire-item.cc:646 +#: apt-pkg/acquire-item.cc:646 apt-pkg/acquire-item.cc:675 msgid "There are no public key available for the following key IDs:\n" msgstr "" -#: apt-pkg/acquire-item.cc:759 +#: apt-pkg/acquire-item.cc:759 apt-pkg/acquire-item.cc:788 #, c-format msgid "" "I wasn't able to locate a file for the %s package. This might mean you need " "to manually fix this package. (due to missing arch)" msgstr "" -#: apt-pkg/acquire-item.cc:818 +#: apt-pkg/acquire-item.cc:818 apt-pkg/acquire-item.cc:847 #, c-format msgid "" "I wasn't able to locate file for the %s package. This might mean you need to " "manually fix this package." msgstr "" -#: apt-pkg/acquire-item.cc:854 +#: apt-pkg/acquire-item.cc:854 apt-pkg/acquire-item.cc:883 #, c-format msgid "" "The package index files are corrupted. No Filename: field for package %s." msgstr "" -#: apt-pkg/acquire-item.cc:941 +#: apt-pkg/acquire-item.cc:941 apt-pkg/acquire-item.cc:970 msgid "Size mismatch" msgstr "" @@ -2426,41 +2431,42 @@ msgstr "" msgid "Vendor block %s contains no fingerprint" msgstr "" -#: apt-pkg/cdrom.cc:507 +#: apt-pkg/cdrom.cc:507 apt-pkg/cdrom.cc:531 #, c-format msgid "" "Using CD-ROM mount point %s\n" "Mounting CD-ROM\n" msgstr "" -#: apt-pkg/cdrom.cc:516 apt-pkg/cdrom.cc:598 +#: apt-pkg/cdrom.cc:516 apt-pkg/cdrom.cc:598 apt-pkg/cdrom.cc:540 +#: apt-pkg/cdrom.cc:622 msgid "Identifying.. " msgstr "" -#: apt-pkg/cdrom.cc:541 +#: apt-pkg/cdrom.cc:541 apt-pkg/cdrom.cc:565 #, c-format msgid "Stored label: %s \n" msgstr "" -#: apt-pkg/cdrom.cc:561 +#: apt-pkg/cdrom.cc:561 apt-pkg/cdrom.cc:585 #, c-format msgid "Using CD-ROM mount point %s\n" msgstr "" -#: apt-pkg/cdrom.cc:579 +#: apt-pkg/cdrom.cc:579 apt-pkg/cdrom.cc:603 msgid "Unmounting CD-ROM\n" msgstr "" -#: apt-pkg/cdrom.cc:583 +#: apt-pkg/cdrom.cc:583 apt-pkg/cdrom.cc:607 msgid "Waiting for disc...\n" msgstr "" #. Mount the new CDROM -#: apt-pkg/cdrom.cc:591 +#: apt-pkg/cdrom.cc:591 apt-pkg/cdrom.cc:615 msgid "Mounting CD-ROM...\n" msgstr "" -#: apt-pkg/cdrom.cc:609 +#: apt-pkg/cdrom.cc:609 apt-pkg/cdrom.cc:633 msgid "Scanning disc for index files..\n" msgstr "" @@ -2469,49 +2475,49 @@ msgstr "" msgid "Found %i package indexes, %i source indexes and %i signatures\n" msgstr "" -#: apt-pkg/cdrom.cc:710 +#: apt-pkg/cdrom.cc:710 apt-pkg/cdrom.cc:737 msgid "That is not a valid name, try again.\n" msgstr "" -#: apt-pkg/cdrom.cc:726 +#: apt-pkg/cdrom.cc:726 apt-pkg/cdrom.cc:753 #, c-format msgid "" "This disc is called: \n" "'%s'\n" msgstr "" -#: apt-pkg/cdrom.cc:730 +#: apt-pkg/cdrom.cc:730 apt-pkg/cdrom.cc:757 msgid "Copying package lists..." msgstr "" -#: apt-pkg/cdrom.cc:754 +#: apt-pkg/cdrom.cc:754 apt-pkg/cdrom.cc:783 msgid "Writing new source list\n" msgstr "" -#: apt-pkg/cdrom.cc:763 +#: apt-pkg/cdrom.cc:763 apt-pkg/cdrom.cc:792 msgid "Source list entries for this disc are:\n" msgstr "" -#: apt-pkg/cdrom.cc:803 +#: apt-pkg/cdrom.cc:803 apt-pkg/cdrom.cc:832 msgid "Unmounting CD-ROM..." msgstr "" -#: apt-pkg/indexcopy.cc:261 +#: apt-pkg/indexcopy.cc:261 apt-pkg/indexcopy.cc:263 apt-pkg/indexcopy.cc:830 #, c-format msgid "Wrote %i records.\n" msgstr "" -#: apt-pkg/indexcopy.cc:263 +#: apt-pkg/indexcopy.cc:263 apt-pkg/indexcopy.cc:265 apt-pkg/indexcopy.cc:832 #, c-format msgid "Wrote %i records with %i missing files.\n" msgstr "" -#: apt-pkg/indexcopy.cc:266 +#: apt-pkg/indexcopy.cc:266 apt-pkg/indexcopy.cc:268 apt-pkg/indexcopy.cc:835 #, c-format msgid "Wrote %i records with %i mismatched files\n" msgstr "" -#: apt-pkg/indexcopy.cc:269 +#: apt-pkg/indexcopy.cc:269 apt-pkg/indexcopy.cc:271 apt-pkg/indexcopy.cc:838 #, c-format msgid "Wrote %i records with %i missing files and %i mismatched files\n" msgstr "" @@ -2569,3 +2575,24 @@ msgstr "" #: methods/rsh.cc:330 msgid "Connection closed prematurely" msgstr "" + +#: apt-pkg/pkgcachegen.cc:157 +#, c-format +msgid "Error occured while processing %s (NewFileDesc1)" +msgstr "" + +#: apt-pkg/pkgcachegen.cc:249 +#, c-format +msgid "Error occured while processing %s (NewFileDesc2)" +msgstr "" + +#: apt-pkg/pkgcachegen.cc:261 +msgid "Wow, you exceeded the number of descriptions this APT is capable of." +msgstr "" + +#: apt-pkg/cdrom.cc:673 +#, c-format +msgid "" +"Found %i package indexes, %i source indexes, %i translation indexes and %i " +"signatures\n" +msgstr "" |