+ // Read the record
+ return PkgF.Open(I.FileName(), FileFd::ReadOnly, FileFd::Extension);
+}
+ /*}}}*/
+static APT_PURE unsigned char const* skipDescriptionFields(unsigned char const * DescP)/*{{{*/
+{
+ char const * const TagName = "\nDescription";
+ size_t const TagLen = strlen(TagName);
+ while ((DescP = (unsigned char*)strchr((char*)DescP, '\n')) != NULL)
+ {
+ if (DescP[1] == ' ')
+ DescP += 2;
+ else if (strncmp((char*)DescP, TagName, TagLen) == 0)
+ DescP += TagLen;
+ else
+ break;
+ }
+ if (DescP != NULL)
+ ++DescP;
+ return DescP;
+}
+ /*}}}*/
+bool DisplayRecordV1(pkgCacheFile &CacheFile, pkgCache::VerIterator const &V,/*{{{*/
+ std::ostream &out)
+{
+ FileFd PkgF;
+ pkgCache::VerFileIterator Vf;
+ if (OpenPackagesFile(CacheFile, V, PkgF, Vf) == false)
+ return false;
+
+ pkgCache * const Cache = CacheFile.GetPkgCache();
+ if (unlikely(Cache == NULL))
+ return false;
+
+ // Read the record (and ensure that it ends with a newline and NUL)
+ unsigned char *Buffer = new unsigned char[Cache->HeaderP->MaxVerFileSize+2];
+ Buffer[Vf->Size] = '\n';
+ Buffer[Vf->Size+1] = '\0';
+ if (PkgF.Seek(Vf->Offset) == false ||
+ PkgF.Read(Buffer,Vf->Size) == false)
+ {
+ delete [] Buffer;
+ return false;
+ }
+
+ // Get a pointer to start of Description field
+ const unsigned char *DescP = (unsigned char*)strstr((char*)Buffer, "\nDescription");
+ if (DescP != NULL)
+ ++DescP;
+ else
+ DescP = Buffer + Vf->Size;
+
+ // Write all but Description
+ size_t const length = DescP - Buffer;
+ if (length != 0 && FileFd::Write(STDOUT_FILENO, Buffer, length) == false)
+ {
+ delete [] Buffer;
+ return false;
+ }
+
+ // Show the right description
+ pkgRecords Recs(*Cache);
+ pkgCache::DescIterator Desc = V.TranslatedDescription();
+ if (Desc.end() == false)
+ {
+ pkgRecords::Parser &P = Recs.Lookup(Desc.FileList());
+ out << "Description" << ( (strcmp(Desc.LanguageCode(),"") != 0) ? "-" : "" ) << Desc.LanguageCode() << ": " << P.LongDesc();
+ out << std::endl << "Description-md5: " << Desc.md5() << std::endl;
+
+ // Find the first field after the description (if there is any)
+ DescP = skipDescriptionFields(DescP);
+ }
+ // else we have no translation, so we found a lonely Description-md5 -> don't skip it
+
+ // write the rest of the buffer, but skip mixed in Descriptions* fields
+ while (DescP != NULL)
+ {
+ const unsigned char * const Start = DescP;
+ const unsigned char *End = (unsigned char*)strstr((char*)DescP, "\nDescription");
+ if (End == NULL)
+ {
+ End = &Buffer[Vf->Size];
+ DescP = NULL;
+ }
+ else
+ {
+ ++End; // get the newline into the output
+ DescP = skipDescriptionFields(End + strlen("Description"));
+ }
+ size_t const length = End - Start;
+ if (length != 0 && FileFd::Write(STDOUT_FILENO, Start, length) == false)
+ {
+ delete [] Buffer;
+ return false;
+ }
+ }
+ // write a final newline after the last field
+ out << std::endl;
+
+ delete [] Buffer;
+ return true;
+}
+ /*}}}*/
+static bool DisplayRecordV2(pkgCacheFile &CacheFile, pkgCache::VerIterator const &V,/*{{{*/
+ std::ostream &out)
+{
+ FileFd PkgF;
+ pkgCache::VerFileIterator Vf;
+ if (OpenPackagesFile(CacheFile, V, PkgF, Vf) == false)
+ return false;
+
+ // Check and load the package list file
+ pkgCache::PkgFileIterator I = Vf.File();
+ if (I.IsOk() == false)
+ return _error->Error(_("Package file %s is out of sync."),I.FileName());
+