Browse Source

DumpAvail works and apt-cache is complete

Author: jgg
Date: 1998-07-19 04:22:00 GMT
DumpAvail works and apt-cache is complete
debian/1.8.y
Arch Librarian 18 years ago
parent
commit
ad00ae81eb
  1. 21
      apt-pkg/contrib/strutl.cc
  2. 3
      apt-pkg/contrib/strutl.h
  3. 3
      apt-pkg/pkgcache.cc
  4. 11
      apt-pkg/pkgcache.h
  5. 8
      apt-pkg/pkgcachegen.cc
  6. 7
      apt-pkg/pkgcachegen.h
  7. 41
      apt-pkg/sourcelist.cc
  8. 4
      apt-pkg/sourcelist.h
  9. 49
      apt-pkg/tagfile.cc
  10. 8
      apt-pkg/tagfile.h
  11. 231
      cmdline/apt-cache.cc
  12. 7
      doc/cache.sgml

21
apt-pkg/contrib/strutl.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: strutl.cc,v 1.2 1998/07/16 06:08:41 jgg Exp $
// $Id: strutl.cc,v 1.3 1998/07/19 04:22:08 jgg Exp $
/* ######################################################################
String Util - Some usefull string functions.
@ -243,6 +243,25 @@ string SubstVar(string Str,string Subst,string Contents)
return Temp + string(Str,OldPos);
}
/*}}}*/
// URItoFileName - Convert the uri into a unique file name /*{{{*/
// ---------------------------------------------------------------------
/* This converts a URI into a safe filename. It quotes all unsafe characters
and converts / to _ and removes the scheme identifier. The resulting
file name should be unique and never occur again for a different file */
string URItoFileName(string URI)
{
string::const_iterator I = URI.begin() + URI.find(':') + 1;
for (; I < URI.end() && *I == '/'; I++);
// "\x00-\x20{}|\\\\^\\[\\]<>\"\x7F-\xFF";
URI = QuoteString(string(I,URI.end() - I),"\\|{}[]<>\"^~_=!@#$%^&*");
string::iterator J = URI.begin();
for (; J != URI.end(); J++)
if (*J == '/')
*J = '_';
return URI;
}
/*}}}*/
// Base64Encode - Base64 Encoding routine for short strings /*{{{*/
// ---------------------------------------------------------------------
/* This routine performs a base64 transformation on a string. It was ripped

3
apt-pkg/contrib/strutl.h

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: strutl.h,v 1.2 1998/07/09 05:12:35 jgg Exp $
// $Id: strutl.h,v 1.3 1998/07/19 04:22:09 jgg Exp $
/* ######################################################################
String Util - These are some usefull string functions
@ -29,6 +29,7 @@ string SizeToStr(double Bytes);
string TimeToStr(unsigned long Sec);
string SubstVar(string Str,string Subst,string Contents);
string Base64Encode(string Str);
string URItoFileName(string URI);
int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
inline int stringcmp(const char *A,const char *AEnd,const char *B) {return stringcmp(A,AEnd,B,B+strlen(B));};

3
apt-pkg/pkgcache.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: pkgcache.cc,v 1.7 1998/07/12 23:58:32 jgg Exp $
// $Id: pkgcache.cc,v 1.8 1998/07/19 04:22:00 jgg Exp $
/* ######################################################################
Package Cache - Accessor code for the cache
@ -59,6 +59,7 @@ pkgCache::Header::Header()
VersionCount = 0;
DependsCount = 0;
PackageFileCount = 0;
MaxVerFileSize = 0;
FileList = 0;
StringList = 0;

11
apt-pkg/pkgcache.h

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: pkgcache.h,v 1.6 1998/07/12 23:58:33 jgg Exp $
// $Id: pkgcache.h,v 1.7 1998/07/19 04:22:01 jgg Exp $
/* ######################################################################
Cache - Structure definitions for the cache file
@ -120,7 +120,9 @@ class pkgCache
Header &Head() {return *HeaderP;};
inline PkgIterator PkgBegin();
inline PkgIterator PkgEnd();
inline PkgFileIterator FileBegin();
inline PkgFileIterator FileEnd();
pkgCache(MMap &Map);
virtual ~pkgCache() {};
};
@ -152,6 +154,7 @@ struct pkgCache::Header
// Offsets
unsigned long FileList; // struct PackageFile
unsigned long StringList; // struct StringItem
unsigned long MaxVerFileSize;
/* Allocation pools, there should be one of these for each structure
excluding the header */
@ -264,5 +267,9 @@ inline pkgCache::PkgIterator pkgCache::PkgBegin()
{return PkgIterator(*this);};
inline pkgCache::PkgIterator pkgCache::PkgEnd()
{return PkgIterator(*this,PkgP);};
inline pkgCache::PkgFileIterator pkgCache::FileBegin()
{return PkgFileIterator(*this);};
inline pkgCache::PkgFileIterator pkgCache::FileEnd()
{return PkgFileIterator(*this,PkgFileP);};
#endif

8
apt-pkg/pkgcachegen.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: pkgcachegen.cc,v 1.10 1998/07/16 06:08:38 jgg Exp $
// $Id: pkgcachegen.cc,v 1.11 1998/07/19 04:22:02 jgg Exp $
/* ######################################################################
Package Cache Generator - Generator for the cache structure.
@ -170,7 +170,8 @@ bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator &Ver,
Ver->FileList = VF.Index();
VF->Offset = List.Offset();
VF->Size = List.Size();
if (Cache.HeaderP->MaxVerFileSize < VF->Size)
Cache.HeaderP->MaxVerFileSize = VF->Size;
return true;
}
/*}}}*/
@ -313,7 +314,8 @@ bool pkgCacheGenerator::SelectFile(string File,unsigned long Flags)
CurrentFile->NextFile = Cache.HeaderP->FileList;
CurrentFile->Flags = Flags;
PkgFileName = File;
Cache.HeaderP->FileList = CurrentFile - Cache.PkgFileP;
if (CurrentFile->FileName == 0)
return false;
return true;

7
apt-pkg/pkgcachegen.h

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: pkgcachegen.h,v 1.5 1998/07/12 23:58:35 jgg Exp $
// $Id: pkgcachegen.h,v 1.6 1998/07/19 04:22:03 jgg Exp $
/* ######################################################################
Package Cache Generator - Generator for the cache structure.
@ -69,7 +69,7 @@ class pkgCacheGenerator
pkgCache::VerIterator Ver) = 0;
virtual unsigned long Offset() = 0;
virtual unsigned long Size() = 0;
virtual bool Step() = 0;
virtual ~ListParser() {};
@ -78,7 +78,8 @@ class pkgCacheGenerator
bool SelectFile(string File,unsigned long Flags = 0);
bool MergeList(ListParser &List);
inline pkgCache &GetCache() {return Cache;};
pkgCacheGenerator(DynamicMMap &Map);
~pkgCacheGenerator();
};

41
apt-pkg/sourcelist.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: sourcelist.cc,v 1.3 1998/07/12 23:58:36 jgg Exp $
// $Id: sourcelist.cc,v 1.4 1998/07/19 04:22:04 jgg Exp $
/* ######################################################################
List of Sources
@ -108,45 +108,6 @@ bool pkgSourceList::Read(string File)
return true;
}
/*}}}*/
// SourceList::SanitizeURI - Hash the uri /*{{{*/
// ---------------------------------------------------------------------
/* This converts a URI into a safe filename. It quotes all unsafe characters
and converts / to _ and removes the scheme identifier. */
string pkgSourceList::SanitizeURI(string URI)
{
string::const_iterator I = URI.begin() + URI.find(':') + 1;
for (; I < URI.end() && *I == '/'; I++);
// "\x00-\x20{}|\\\\^\\[\\]<>\"\x7F-\xFF";
URI = QuoteString(string(I,URI.end() - I),"\\|{}[]<>\"^~_=!@#$%^&*");
string::iterator J = URI.begin();
for (; J != URI.end(); J++)
if (*J == '/')
*J = '_';
return URI;
}
/*}}}*/
// SourceList::MatchPkgFile - Find the package file that has the ver /*{{{*/
// ---------------------------------------------------------------------
/* This will return List.end() if it could not find the matching
file */
pkgSourceList::const_iterator pkgSourceList::MatchPkgFile(pkgCache::VerIterator Ver)
{
string Base = _config->Find("APT::Architecture");
for (const_iterator I = List.begin(); I != List.end(); I++)
{
string URI = I->PackagesURI();
switch (I->Type)
{
case Item::Deb:
/* if (Base + SanitizeURI(URI) == Ver.File().FileName())
return I;*/
break;
};
}
return List.end();
}
/*}}}*/
// SourceList::Item << - Writes the item to a stream /*{{{*/
// ---------------------------------------------------------------------
/* This is not suitable for rebuilding the sourcelist file but it good for

4
apt-pkg/sourcelist.h

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: sourcelist.h,v 1.3 1998/07/12 23:58:38 jgg Exp $
// $Id: sourcelist.h,v 1.4 1998/07/19 04:22:05 jgg Exp $
/* ######################################################################
SourceList - Manage a list of sources
@ -56,8 +56,6 @@ class pkgSourceList
bool ReadMainList();
bool Read(string File);
string SanitizeURI(string URI);
const_iterator MatchPkgFile(pkgCache::VerIterator Ver);
// List accessors
inline const_iterator begin() const {return List.begin();};

49
apt-pkg/tagfile.cc

@ -1,11 +1,11 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: tagfile.cc,v 1.8 1998/07/16 06:08:39 jgg Exp $
// $Id: tagfile.cc,v 1.9 1998/07/19 04:22:06 jgg Exp $
/* ######################################################################
Fast scanner for RFC-822 type header information
This uses a rotating 64K buffer to load the package information into.
This uses a rotating buffer to load the package information into.
The scanner runs over it and isolates and indexes a single section.
##################################################################### */
@ -25,10 +25,10 @@
// TagFile::pkgTagFile - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
pkgTagFile::pkgTagFile(File &Fd) : Fd(Fd)
pkgTagFile::pkgTagFile(File &Fd,unsigned long Size) : Fd(Fd), Size(Size)
{
Buffer = new char[64*1024];
Start = End = Buffer + 64*1024;
Buffer = new char[Size];
Start = End = Buffer;
Left = Fd.Size();
iOffset = 0;
Fill();
@ -59,35 +59,56 @@ bool pkgTagFile::Step(pkgTagSection &Tag)
then fills the rest from the file */
bool pkgTagFile::Fill()
{
unsigned long Size = End - Start;
unsigned long EndSize = End - Start;
if (Left == 0)
{
if (Size <= 1)
if (EndSize <= 1)
return false;
return true;
}
memmove(Buffer,Start,Size);
memmove(Buffer,Start,EndSize);
Start = Buffer;
End = Buffer + EndSize;
// See if only a bit of the file is left or if
if (Left < End - Buffer - Size)
// See if only a bit of the file is left
if (Left < Size)
{
if (Fd.Read(Buffer + Size,Left) == false)
if (Fd.Read(End,Left) == false)
return false;
End = Buffer + Size + Left;
End += Left;
Left = 0;
}
else
{
if (Fd.Read(Buffer + Size, End - Buffer - Size) == false)
if (Fd.Read(End,Size - (End - Buffer)) == false)
return false;
Left -= End - Buffer - Size;
Left -= Size - (End - Buffer);
End = Buffer + Size;
}
return true;
}
/*}}}*/
// TagFile::Jump - Jump to a pre-recorded location in the file /*{{{*/
// ---------------------------------------------------------------------
/* This jumps to a pre-recorded file location and */
bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long Offset)
{
iOffset = Offset;
Left = Fd.Size() - Offset;
if (Fd.Seek(Offset) == false)
return false;
End = Start = Buffer;
if (Fill() == false)
return false;
if (Tag.Scan(Start,End - Start) == false)
return _error->Error("Unable to parse package file");
return true;
}
/*}}}*/
// TagSection::Scan - Scan for the end of the header information /*{{{*/
// ---------------------------------------------------------------------
/* This looks for the first double new line in the data stream. It also

8
apt-pkg/tagfile.h

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: tagfile.h,v 1.5 1998/07/16 06:08:40 jgg Exp $
// $Id: tagfile.h,v 1.6 1998/07/19 04:22:07 jgg Exp $
/* ######################################################################
Fast scanner for RFC-822 type header information
@ -56,6 +56,7 @@ class pkgTagFile
char *End;
unsigned long Left;
unsigned long iOffset;
unsigned long Size;
bool Fill();
@ -63,8 +64,9 @@ class pkgTagFile
bool Step(pkgTagSection &Section);
inline unsigned long Offset() {return iOffset;};
pkgTagFile(File &F);
bool Jump(pkgTagSection &Tag,unsigned long Offset);
pkgTagFile(File &F,unsigned long Size = 32*1024);
};
#endif

231
cmdline/apt-cache.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: apt-cache.cc,v 1.2 1998/07/16 06:08:43 jgg Exp $
// $Id: apt-cache.cc,v 1.3 1998/07/19 04:22:10 jgg Exp $
/* ######################################################################
apt-cache - Manages the cache file.
@ -62,69 +62,14 @@ bool SplitArg(const char *Arg,string &File,string &Dist,string Ver)
return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg);
Ver = string(Start,I - Start);
return true;
}
/*}}}*/
// DoAdd - Perform an adding operation /*{{{*/
// ---------------------------------------------------------------------
/* */
bool DoAdd(int argc,char *argv[])
{
string FileName;
string Dist;
string Ver;
File CacheF(CacheFile,File::WriteEmpty);
if (_error->PendingError() == true)
return false;
DynamicMMap Map(CacheF,MMap::Public);
if (_error->PendingError() == true)
return false;
pkgCacheGenerator Gen(Map);
if (_error->PendingError() == true)
return false;
for (int I = 0; I != argc; I++)
{
if (SplitArg(argv[I],FileName,Dist,Ver) == false)
return false;
cout << FileName << endl;
// Do the merge
File TagF(FileName.c_str(),File::ReadOnly);
debListParser Parser(TagF);
if (_error->PendingError() == true)
return _error->Error("Problem opening %s",FileName.c_str());
if (Gen.SelectFile(FileName) == false)
return _error->Error("Problem with SelectFile");
if (Gen.MergeList(Parser) == false)
return _error->Error("Problem with MergeList");
}
return true;
}
/*}}}*/
// DumpPackage - Show a dump of a package record /*{{{*/
// ---------------------------------------------------------------------
/* */
bool DumpPackage(int argc,char *argv[])
{
File CacheF(CacheFile,File::ReadOnly);
if (_error->PendingError() == true)
return false;
MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
if (_error->PendingError() == true)
return false;
pkgCache Cache(Map);
if (_error->PendingError() == true)
return false;
bool DumpPackage(pkgCache &Cache,int argc,char *argv[])
{
for (int I = 0; I != argc; I++)
{
pkgCache::PkgIterator Pkg = Cache.FindPkg(argv[I]);
@ -173,20 +118,8 @@ bool DumpPackage(int argc,char *argv[])
// Stats - Dump some nice statistics /*{{{*/
// ---------------------------------------------------------------------
/* */
bool Stats(const char *FileName)
bool Stats(pkgCache &Cache)
{
File CacheF(FileName,File::ReadOnly);
if (_error->PendingError() == true)
return false;
MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
if (_error->PendingError() == true)
return false;
pkgCache Cache(Map);
if (_error->PendingError() == true)
return false;
cout << "Total Package Names : " << Cache.Head().PackageCount << endl;
pkgCache::PkgIterator I = Cache.PkgBegin();
@ -240,20 +173,8 @@ bool Stats(const char *FileName)
// Dump - show everything /*{{{*/
// ---------------------------------------------------------------------
/* */
bool Dump()
bool Dump(pkgCache &Cache)
{
File CacheF(CacheFile,File::ReadOnly);
if (_error->PendingError() == true)
return false;
MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
if (_error->PendingError() == true)
return false;
pkgCache Cache(Map);
if (_error->PendingError() == true)
return false;
for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
{
cout << "Package: " << P.Name() << endl;
@ -281,53 +202,97 @@ bool Dump()
// DumpAvail - Print out the available list /*{{{*/
// ---------------------------------------------------------------------
/* This is needed to make dpkg --merge happy */
bool DumpAvail()
bool DumpAvail(pkgCache &Cache)
{
#if 0
pkgCache Cache(CacheFile,true,true);
if (_error->PendingError() == true)
return false;
unsigned char *Buffer = new unsigned char[Cache.HeaderP->MaxVerFileSize];
pkgControlCache CCache(Cache);
if (_error->PendingError() == true)
return false;
vector<string> Lines;
Lines.reserve(30);
pkgCache::PkgIterator I = Cache.PkgBegin();
for (;I.end() != true; I++)
for (pkgCache::PkgFileIterator I = Cache.FileBegin(); I.end() == false; I++)
{
if (I->VersionList == 0)
if ((I->Flags & pkgCache::Flag::NotSource) != 0)
continue;
pkgSPkgCtrlInfo Inf = CCache[I.VersionList()];
if (Inf.isNull() == true)
return _error->Error("Couldn't locate info record");
if (I.IsOk() == false)
{
delete [] Buffer;
return _error->Error("Package file %s is out of sync.",I.FileName());
}
// Iterate over each element
pkgPkgCtrlInfo::const_iterator Elm = Inf->begin();
for (; Elm != Inf->end(); Elm++)
File PkgF(I.FileName(),File::ReadOnly);
if (_error->PendingError() == true)
{
// Write the tag: value
cout << (*Elm)->Tag() << ": " << (*Elm)->Value() << endl;
// Write the multiline
(*Elm)->GetLines(Lines);
for (vector<string>::iterator j = Lines.begin(); j != Lines.end(); j++)
delete [] Buffer;
return false;
}
/* Write all of the records from this package file, we search the entire
structure to find them */
for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
{
for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
{
if ((*j).length() == 0)
cout << " ." << endl;
else
cout << " " << *j << endl;
if (V->FileList == 0)
continue;
if (V.FileList().File() != I)
continue;
// Read the record and then write it out again.
if (PkgF.Seek(V.FileList()->Offset) == false ||
PkgF.Read(Buffer,V.FileList()->Size) == false ||
write(STDOUT_FILENO,Buffer,V.FileList()->Size) != V.FileList()->Size)
{
delete [] Buffer;
return false;
}
}
Lines.erase(Lines.begin(),Lines.end());
}
}
return true;
}
/*}}}*/
// DoAdd - Perform an adding operation /*{{{*/
// ---------------------------------------------------------------------
/* */
bool DoAdd(int argc,char *argv[])
{
string FileName;
string Dist;
string Ver;
// Open the cache
File CacheF(CacheFile,File::WriteEmpty);
if (_error->PendingError() == true)
return false;
DynamicMMap Map(CacheF,MMap::Public);
if (_error->PendingError() == true)
return false;
pkgCacheGenerator Gen(Map);
if (_error->PendingError() == true)
return false;
for (int I = 0; I != argc; I++)
{
if (SplitArg(argv[I],FileName,Dist,Ver) == false)
return false;
cout << FileName << endl;
cout << endl;
// Do the merge
File TagF(FileName.c_str(),File::ReadOnly);
debListParser Parser(TagF);
if (_error->PendingError() == true)
return _error->Error("Problem opening %s",FileName.c_str());
if (Gen.SelectFile(FileName) == false)
return _error->Error("Problem with SelectFile");
if (Gen.MergeList(Parser) == false)
return _error->Error("Problem with MergeList");
}
#endif
Stats(Gen.GetCache());
return true;
}
/*}}}*/
@ -344,38 +309,48 @@ int main(int argc, char *argv[])
pkgInitialize(*_config);
while (1)
{
CacheFile = argv[2];
if (strcmp(argv[1],"add") == 0)
{
CacheFile = argv[2];
if (DoAdd(argc - 3,argv + 3) == true)
Stats(argv[2]);
DoAdd(argc - 3,argv + 3);
break;
}
// Open the cache file
File CacheF(CacheFile,File::ReadOnly);
if (_error->PendingError() == true)
break;
MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
if (_error->PendingError() == true)
break;
pkgCache Cache(Map);
if (_error->PendingError() == true)
break;
if (strcmp(argv[1],"showpkg") == 0)
{
CacheFile = argv[2];
DumpPackage(argc - 3,argv + 3);
DumpPackage(Cache,argc - 3,argv + 3);
break;
}
if (strcmp(argv[1],"stats") == 0)
{
Stats(argv[2]);
Stats(Cache);
break;
}
if (strcmp(argv[1],"dump") == 0)
{
CacheFile = argv[2];
Dump();
Dump(Cache);
break;
}
if (strcmp(argv[1],"dumpavail") == 0)
{
CacheFile = argv[2];
DumpAvail();
DumpAvail(Cache);
break;
}

7
doc/cache.sgml

@ -4,7 +4,7 @@
<title>APT Cache File Format</title>
<author>Jason Gunthorpe <email>jgg@debian.org</email></author>
<version>$Id: cache.sgml,v 1.2 1998/07/05 05:43:09 jgg Exp $</version>
<version>$Id: cache.sgml,v 1.3 1998/07/19 04:22:11 jgg Exp $</version>
<abstract>
This document describes the complete implementation and format of the APT
@ -140,6 +140,7 @@ This is the first item in the file.
unsigned long VersionCount;
unsigned long DependsCount;
unsigned long PackageFileCount;
unsigned long MaxVerFileSize;
// Offsets
unsigned long FileList; // PackageFile
@ -193,6 +194,10 @@ These indicate the number of each structure contianed in the cache.
PackageCount is especially usefull for generating user state structures.
See Package::Id for more info.
<tag>MaxVerFileSize<item>
The maximum size of a raw entry from the original Package file
(ie VerFile::Size) is stored here.
<tag>FileList<item>
This contains the index of the first PackageFile structure. The PackageFile
structures are singely linked lists that represent all package files that

Loading…
Cancel
Save