summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/cacheiterators.h281
-rw-r--r--apt-pkg/contrib/error.cc139
-rw-r--r--apt-pkg/contrib/error.h84
-rw-r--r--apt-pkg/contrib/fileutl.cc214
-rw-r--r--apt-pkg/contrib/fileutl.h63
-rw-r--r--apt-pkg/contrib/mmap.cc227
-rw-r--r--apt-pkg/contrib/mmap.h92
-rw-r--r--apt-pkg/contrib/system.h57
-rw-r--r--apt-pkg/pkgcache.cc360
-rw-r--r--apt-pkg/pkgcache.h280
-rw-r--r--apt-pkg/pkgcachegen.cc184
-rw-r--r--apt-pkg/pkgcachegen.h69
-rw-r--r--apt-pkg/tagfile.cc195
-rw-r--r--apt-pkg/tagfile.h64
-rw-r--r--apt-pkg/version.cc249
-rw-r--r--apt-pkg/version.h45
-rw-r--r--doc/apt-cache.8199
-rw-r--r--doc/apt-get.8250
-rw-r--r--doc/apt.850
-rw-r--r--doc/cache.sgml761
-rw-r--r--doc/design.sgml411
-rw-r--r--doc/dpkg-tech.sgml509
-rw-r--r--doc/files.sgml491
-rw-r--r--doc/ftp.conf.593
-rw-r--r--doc/guide.sgml548
-rw-r--r--doc/sources.list.5177
26 files changed, 6092 insertions, 0 deletions
diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h
new file mode 100644
index 000000000..539444c33
--- /dev/null
+++ b/apt-pkg/cacheiterators.h
@@ -0,0 +1,281 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: cacheiterators.h,v 1.1 1998/07/02 02:58:12 jgg Exp $
+/* ######################################################################
+
+ Cache Iterators - Iterators for navigating the cache structure
+
+ The iterators all provides ++,==,!=,->,* and end for their type.
+ The end function can be used to tell if the list has been fully
+ traversed.
+
+ Unlike STL iterators these contain helper functions to access the data
+ that is being iterated over. This is because the data structures can't
+ be formed in a manner that is intuitive to use and also mmapable.
+
+ For each variable in the target structure that would need a translation
+ to be accessed correctly a translating function of the same name is
+ present in the iterator. If applicable the translating function will
+ return an iterator.
+
+ The DepIterator can iterate over two lists, a list of 'version depends'
+ or a list of 'package reverse depends'. The type is determined by the
+ structure passed to the constructor, which should be the structure
+ that has the depends pointer as a member.
+
+ This header is not user includable, please use pkglib/pkgcache.h
+
+ ##################################################################### */
+ /*}}}*/
+// Header section: pkglib
+#ifndef PKGLIB_CACHEITERATORS_H
+#define PKGLIB_CACHEITERATORS_H
+
+// Package Iterator
+class pkgCache::PkgIterator
+{
+ Package *Pkg;
+ pkgCache *Owner;
+ long HashIndex;
+
+ public:
+
+ enum OkState {NeedsNothing,NeedsUnpack,NeedsConfigure};
+
+ // Iteration
+ void operator ++(int);
+ inline void operator ++() {operator ++(0);};
+ inline bool end() const {return Owner == 0 || Pkg == Owner->PkgP?true:false;};
+
+ // Comparison
+ inline bool operator ==(const PkgIterator &B) const {return Pkg == B.Pkg;};
+ inline bool operator !=(const PkgIterator &B) const {return Pkg != B.Pkg;};
+
+ // Accessors
+ inline Package *operator ->() {return Pkg;};
+ inline Package const *operator ->() const {return Pkg;};
+ inline Package const &operator *() const {return *Pkg;};
+ inline operator Package *() {return Pkg == Owner->PkgP?0:Pkg;};
+ inline operator Package const *() const {return Pkg == Owner->PkgP?0:Pkg;};
+ inline const char *Name() const {return Pkg->Name == 0?0:Owner->StrP + Pkg->Name;};
+ inline const char *Section() const {return Pkg->Section == 0?0:Owner->StrP + Pkg->Section;};
+ inline const char *TargetDist() const {return Pkg->TargetDist == 0?0:Owner->StrP + Pkg->TargetDist;};
+ inline VerIterator VersionList() const;
+ inline VerIterator TargetVer() const;
+ inline VerIterator CurrentVer() const;
+ inline DepIterator RevDependsList() const;
+ inline PrvIterator ProvidesList() const;
+ OkState State() const;
+
+ // Constructors
+ inline PkgIterator(pkgCache &Owner) : Owner(&Owner), HashIndex(-1)
+ {
+ Pkg = Owner.PkgP;
+ operator ++(0);
+ };
+ inline PkgIterator(pkgCache &Owner,Package *Trg) : Pkg(Trg), Owner(&Owner),
+ HashIndex(0)
+ {
+ if (Pkg == 0)
+ Pkg = Owner.PkgP;
+ };
+ inline PkgIterator() : Pkg(0), Owner(0), HashIndex(0) {};
+};
+
+// Version Iterator
+class pkgCache::VerIterator
+{
+ Version *Ver;
+ pkgCache &Owner;
+
+ void _dummy();
+
+ public:
+
+ // Iteration
+ void operator ++(int) {if (Ver != Owner.VerP) Ver = Owner.VerP + Ver->NextVer;};
+ inline void operator ++() {operator ++(0);};
+ inline bool end() const {return Ver == Owner.VerP?true:false;};
+ inline void operator =(const VerIterator &B) {Ver = B.Ver;};
+
+ // Comparison
+ inline bool operator ==(const VerIterator &B) const {return Ver == B.Ver;};
+ inline bool operator !=(const VerIterator &B) const {return Ver != B.Ver;};
+ int CompareVer(const VerIterator &B) const;
+
+ // Accessors
+ inline Version *operator ->() {return Ver;};
+ inline Version const *operator ->() const {return Ver;};
+ inline Version &operator *() {return *Ver;};
+ inline Version const &operator *() const {return *Ver;};
+ inline operator Version *() {return Ver == Owner.VerP?0:Ver;};
+ inline operator Version const *() const {return Ver == Owner.VerP?0:Ver;};
+ inline const char *VerStr() const {return Ver->VerStr == 0?0:Owner.StrP + Ver->VerStr;};
+ inline const char *Section() const {return Ver->Section == 0?0:Owner.StrP + Ver->Section;};
+ inline PkgFileIterator File() const;
+ inline PkgIterator ParentPkg() const {return PkgIterator(Owner,Owner.PkgP + Ver->ParentPkg);};
+ inline DepIterator DependsList() const;
+ inline PrvIterator ProvidesList() const;
+
+ inline VerIterator(pkgCache &Owner,Version *Trg) : Ver(Trg), Owner(Owner)
+ {
+ if (Ver == 0)
+ Ver = Owner.VerP;
+ };
+};
+
+// Dependency iterator
+class pkgCache::DepIterator
+{
+ Dependency *Dep;
+ enum {DepVer, DepRev} Type;
+ pkgCache *Owner;
+
+ void _dummy();
+
+ public:
+
+ // Iteration
+ void operator ++(int) {if (Dep != Owner->DepP) Dep = Owner->DepP +
+ (Type == DepVer?Dep->NextDepends:Dep->NextRevDepends);};
+ inline void operator ++() {operator ++(0);};
+ inline bool end() const {return Owner == 0 || Dep == Owner->DepP?true:false;};
+
+ // Comparison
+ inline bool operator ==(const DepIterator &B) const {return Dep == B.Dep;};
+ inline bool operator !=(const DepIterator &B) const {return Dep != B.Dep;};
+
+ // Accessors
+ inline Dependency *operator ->() {return Dep;};
+ inline Dependency const *operator ->() const {return Dep;};
+ inline Dependency &operator *() {return *Dep;};
+ inline Dependency const &operator *() const {return *Dep;};
+ inline operator Dependency *() {return Dep == Owner->DepP?0:Dep;};
+ inline operator Dependency const *() const {return Dep == Owner->DepP?0:Dep;};
+ inline const char *TargetVer() const {return Dep->Version == 0?0:Owner->StrP + Dep->Version;};
+ inline PkgIterator TargetPkg() {return PkgIterator(*Owner,Owner->PkgP + Dep->Package);};
+ Version **AllTargets();
+ bool SmartTargetPkg(PkgIterator &Result);
+ inline PkgIterator SmartTargetPkg() {PkgIterator R(*Owner);SmartTargetPkg(R);return R;};
+ inline VerIterator ParentVer() {return VerIterator(*Owner,Owner->VerP + Dep->ParentVer);};
+ inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Dep->ParentVer].ParentPkg);};
+ bool IsCritical();
+ inline bool Reverse() {return Type == DepRev;};
+
+ inline DepIterator(pkgCache &Owner,Dependency *Trg,Version * = 0) :
+ Dep(Trg), Type(DepVer), Owner(&Owner)
+ {
+ if (Dep == 0)
+ Dep = Owner.DepP;
+ };
+ inline DepIterator(pkgCache &Owner,Dependency *Trg,Package *) :
+ Dep(Trg), Type(DepRev), Owner(&Owner)
+ {
+ if (Dep == 0)
+ Dep = Owner.DepP;
+ };
+ inline DepIterator() : Dep(0), Type(DepVer), Owner(0) {};
+};
+
+// Provides iterator
+class pkgCache::PrvIterator
+{
+ Provides *Prv;
+ enum {PrvVer, PrvPkg} Type;
+ pkgCache *Owner;
+
+ void _dummy();
+
+ public:
+
+ // Iteration
+ void operator ++(int) {if (Prv != Owner->ProvideP) Prv = Owner->ProvideP +
+ (Type == PrvVer?Prv->NextPkgProv:Prv->NextProvides);};
+ inline void operator ++() {operator ++(0);};
+ inline bool end() const {return Prv == Owner->ProvideP?true:false;};
+
+ // Comparison
+ inline bool operator ==(const PrvIterator &B) const {return Prv == B.Prv;};
+ inline bool operator !=(const PrvIterator &B) const {return Prv != B.Prv;};
+
+ // Accessors
+ inline Provides *operator ->() {return Prv;};
+ inline Provides const *operator ->() const {return Prv;};
+ inline Provides &operator *() {return *Prv;};
+ inline Provides const &operator *() const {return *Prv;};
+ inline operator Provides *() {return Prv == Owner->ProvideP?0:Prv;};
+ inline operator Provides const *() const {return Prv == Owner->ProvideP?0:Prv;};
+ inline const char *Name() const {return Owner->StrP + Owner->PkgP[Prv->ParentPkg].Name;};
+ inline const char *ProvideVersion() const {return Prv->ProvideVersion == 0?0:Owner->StrP + Prv->ProvideVersion;};
+ inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Prv->ParentPkg);};
+ inline VerIterator OwnerVer() {return VerIterator(*Owner,Owner->VerP + Prv->Version);};
+ inline PkgIterator OwnerPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Prv->Version].ParentPkg);};
+
+ inline PrvIterator(pkgCache &Owner,Provides *Trg,Version *) :
+ Prv(Trg), Type(PrvVer), Owner(&Owner)
+ {
+ if (Prv == 0)
+ Prv = Owner.ProvideP;
+ };
+ inline PrvIterator(pkgCache &Owner,Provides *Trg,Package *) :
+ Prv(Trg), Type(PrvPkg), Owner(&Owner)
+ {
+ if (Prv == 0)
+ Prv = Owner.ProvideP;
+ };
+};
+
+// Package file
+class pkgCache::PkgFileIterator
+{
+ pkgCache *Owner;
+ PackageFile *File;
+
+ public:
+
+ // Iteration
+ void operator ++(int) {if (File!= Owner->PkgFileP) File = Owner->PkgFileP + File->NextFile;};
+ inline void operator ++() {operator ++(0);};
+ inline bool end() const {return File == Owner->PkgFileP?true:false;};
+
+ // Comparison
+ inline bool operator ==(const PkgFileIterator &B) const {return File == B.File;};
+ inline bool operator !=(const PkgFileIterator &B) const {return File != B.File;};
+
+ // Accessors
+ inline PackageFile *operator ->() {return File;};
+ inline PackageFile const *operator ->() const {return File;};
+ inline PackageFile const &operator *() const {return *File;};
+ inline operator PackageFile *() {return File == Owner->PkgFileP?0:File;};
+ inline operator PackageFile const *() const {return File == Owner->PkgFileP?0:File;};
+
+ inline const char *FileName() const {return File->FileName == 0?0:Owner->StrP + File->FileName;};
+ inline const char *Version() const {return File->Version == 0?0:Owner->StrP + File->Version;};
+ inline const char *Distribution() const {return File->Distribution == 0?0:Owner->StrP + File->Distribution;};
+
+ bool IsOk();
+
+ // Constructors
+ inline PkgFileIterator(pkgCache &Owner) : Owner(&Owner), File(Owner.PkgFileP + Owner.Head().FileList) {};
+ inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Owner(&Owner), File(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);};
+inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const
+ {return VerIterator(*Owner,Owner->VerP + Pkg->CurrentVer);};
+inline pkgCache::VerIterator pkgCache::PkgIterator::TargetVer() const
+ {return VerIterator(*Owner,Owner->VerP + Pkg->TargetVer);};
+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::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::PkgFileIterator pkgCache::VerIterator::File() const
+ {return PkgFileIterator(Owner,Owner.PkgFileP + Ver->File);};
+
+#endif
diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc
new file mode 100644
index 000000000..59d2b8c8b
--- /dev/null
+++ b/apt-pkg/contrib/error.cc
@@ -0,0 +1,139 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: error.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $
+/* ######################################################################
+
+ Global Erorr Class - Global error mechanism
+
+ We use a simple STL vector to store each error record. A PendingFlag
+ is kept which indicates when the vector contains a Sever error.
+
+ This source is placed in the Public Domain, do with it what you will
+ It was originally written by Jason Gunthorpe.
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include <pkglib/error.h>
+ /*}}}*/
+
+GlobalError *_error = new GlobalError;
+
+// GlobalError::GlobalError - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+GlobalError::GlobalError() : PendingFlag(false)
+{
+}
+ /*}}}*/
+// GlobalError::Errno - Get part of the error string from errno /*{{{*/
+// ---------------------------------------------------------------------
+/* Function indicates the stdlib function that failed and Description is
+ a user string that leads the text. Form is:
+ Description - Function (errno: strerror)
+ Carefull of the buffer overrun, sprintf.
+ */
+bool GlobalError::Errno(const char *Function,const char *Description,...)
+{
+ va_list args;
+ va_start(args,Description);
+
+ // sprintf the description
+ char S[400];
+ vsprintf(S,Description,args);
+ sprintf(S + strlen(S)," - %s (%i %s)",Function,errno,strerror(errno));
+
+ // Put it on the list
+ Item Itm;
+ Itm.Text = S;
+ Itm.Error = true;
+ List.push_back(Itm);
+
+ PendingFlag = true;
+
+ return false;
+}
+ /*}}}*/
+// GlobalError::Error - Add an error to the list /*{{{*/
+// ---------------------------------------------------------------------
+/* Just vsprintfs and pushes */
+bool GlobalError::Error(const char *Description,...)
+{
+ va_list args;
+ va_start(args,Description);
+
+ // sprintf the description
+ char S[400];
+ vsprintf(S,Description,args);
+
+ // Put it on the list
+ Item Itm;
+ Itm.Text = S;
+ Itm.Error = true;
+ List.push_back(Itm);
+
+ PendingFlag = true;
+
+ return false;
+}
+ /*}}}*/
+// GlobalError::Warning - Add a warning to the list /*{{{*/
+// ---------------------------------------------------------------------
+/* This doesn't set the pending error flag */
+bool GlobalError::Warning(const char *Description,...)
+{
+ va_list args;
+ va_start(args,Description);
+
+ // sprintf the description
+ char S[400];
+ vsprintf(S,Description,args);
+
+ // Put it on the list
+ Item Itm;
+ Itm.Text = S;
+ Itm.Error = false;
+ List.push_back(Itm);
+
+ return false;
+}
+ /*}}}*/
+// GlobalError::PopMessage - Pulls a single message out /*{{{*/
+// ---------------------------------------------------------------------
+/* This should be used in a loop checking empty() each cycle. It returns
+ true if the message is an error. */
+bool GlobalError::PopMessage(string &Text)
+{
+ bool Ret = List.front().Error;
+ Text = List.front().Text;
+ List.erase(List.begin());
+
+ // This really should check the list to see if only warnings are left..
+ if (empty())
+ PendingFlag = false;
+
+ return Ret;
+}
+ /*}}}*/
+// GlobalError::DumpErrors - Dump all of the errors/warns to cerr /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void GlobalError::DumpErrors()
+{
+ // Print any errors or warnings found
+ string Err;
+ while (empty() == false)
+ {
+ bool Type = PopMessage(Err);
+ if (Type == true)
+ cerr << "E: " << Err << endl;
+ else
+ cerr << "W: " << Err << endl;
+ }
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h
new file mode 100644
index 000000000..06b998e5e
--- /dev/null
+++ b/apt-pkg/contrib/error.h
@@ -0,0 +1,84 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: error.h,v 1.1 1998/07/02 02:58:13 jgg Exp $
+/* ######################################################################
+
+ Global Erorr Class - Global error mechanism
+
+ This class has a single global instance. When a function needs to
+ generate an error condition, such as a read error, it calls a member
+ in this class to add the error to a stack of errors.
+
+ By using a stack the problem with a scheme like errno is removed and
+ it allows a very detailed account of what went wrong to be transmitted
+ to the UI for display. (Errno has problems because each function sets
+ errno to 0 if it didn't have an error thus eraseing erno in the process
+ of cleanup)
+
+ Several predefined error generators are provided to handle common
+ things like errno. The general idea is that all methods return a bool.
+ If the bool is true then things are OK, if it is false then things
+ should start being undone and the stack should unwind under program
+ control.
+
+ A Warning should not force the return of false. Things did not fail, but
+ they might have had unexpected problems. Errors are stored in a FIFO
+ so Pop will return the first item..
+
+ I have some thoughts about extending this into a more general UI<->
+ Engine interface, ie allowing the Engine to say 'The disk is full' in
+ a dialog that says 'Panic' and 'Retry'.. The error generator functions
+ like errno, Warning and Error return false always so this is normal:
+ if (open(..))
+ return _error->Errno(..);
+
+ This source is placed in the Public Domain, do with it what you will
+ It was originally written by Jason Gunthorpe.
+
+ ##################################################################### */
+ /*}}}*/
+// Header section: pkglib
+#ifndef PKGLIB_ERROR_H
+#define PKGLIB_ERROR_H
+
+#include <string>
+#include <vector.h>
+
+class GlobalError
+{
+ struct Item
+ {
+ string Text;
+ bool Error;
+ };
+
+ vector<Item> List;
+ bool PendingFlag;
+
+ public:
+
+ // Call to generate an error from a library call.
+ bool Errno(const char *Function,const char *Description,...);
+
+ /* A warning should be considered less severe than an error, and may be
+ ignored by the client. */
+ bool Error(const char *Description,...);
+ bool Warning(const char *Description,...);
+
+ // Simple accessors
+ inline bool PendingError() {return PendingFlag;};
+ inline bool empty() {return List.empty();};
+ bool PopMessage(string &Text);
+ void Discard() {List.erase(List.begin(),List.end()); PendingFlag = false;};
+
+ // Usefull routine to dump to cerr
+ void DumpErrors();
+
+ GlobalError();
+};
+
+/* The 'extra-ansi' syntax is used to help with collisions. This is the
+ single global instance of this class. */
+extern GlobalError *_error;
+
+#endif
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
new file mode 100644
index 000000000..6048ff0bb
--- /dev/null
+++ b/apt-pkg/contrib/fileutl.cc
@@ -0,0 +1,214 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: fileutl.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $
+/* ######################################################################
+
+ File Utilities
+
+ CopyFile - Buffered copy of a single file
+ GetLock - dpkg compatible lock file manipulation (fcntl)
+
+ This source is placed in the Public Domain, do with it what you will
+ It was originally written by Jason Gunthorpe.
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <fileutl.h>
+#include <pkglib/error.h>
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+ /*}}}*/
+
+// CopyFile - Buffered copy of a file /*{{{*/
+// ---------------------------------------------------------------------
+/* The caller is expected to set things so that failure causes erasure */
+bool CopyFile(File From,File To)
+{
+ if (From.IsOpen() == false || To.IsOpen() == false)
+ return false;
+
+ // Buffered copy between fds
+ unsigned char *Buf = new unsigned char[64000];
+ long Size;
+ while ((Size = read(From.Fd(),Buf,64000)) > 0)
+ {
+ if (To.Write(Buf,Size) == false)
+ {
+ delete [] Buf;
+ return false;
+ }
+ }
+
+ delete [] Buf;
+ return true;
+}
+ /*}}}*/
+// GetLock - Gets a lock file /*{{{*/
+// ---------------------------------------------------------------------
+/* This will create an empty file of the given name and lock it. Once this
+ is done all other calls to GetLock in any other process will fail with
+ -1. The return result is the fd of the file, the call should call
+ close at some time. */
+int GetLock(string File,bool Errors)
+{
+ int FD = open(File.c_str(),O_RDWR | O_CREAT | O_TRUNC,0640);
+ if (FD < 0)
+ {
+ if (Errors == true)
+ _error->Errno("open","Could not open lock file %s",File.c_str());
+ return -1;
+ }
+
+ // Aquire a write lock
+ struct flock fl;
+ fl.l_type= F_WRLCK;
+ fl.l_whence= SEEK_SET;
+ fl.l_start= 0;
+ fl.l_len= 1;
+ if (fcntl(FD,F_SETLK,&fl) == -1)
+ {
+ if (Errors == true)
+ _error->Errno("open","Could not get lock %s",File.c_str());
+ close(FD);
+ return -1;
+ }
+
+ return FD;
+}
+ /*}}}*/
+// FileExists - Check if a file exists /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool FileExists(string File)
+{
+ struct stat Buf;
+ if (stat(File.c_str(),&Buf) != 0)
+ return false;
+ return true;
+}
+ /*}}}*/
+// SafeGetCWD - This is a safer getcwd that returns a dynamic string /*{{{*/
+// ---------------------------------------------------------------------
+/* We return / on failure. */
+string SafeGetCWD()
+{
+ // Stash the current dir.
+ char S[300];
+ S[0] = 0;
+ if (getcwd(S,sizeof(S)) == 0)
+ return "/";
+ return S;
+}
+ /*}}}*/
+
+// File::File - Open a file /*{{{*/
+// ---------------------------------------------------------------------
+/* The most commonly used open mode combinations are given with Mode */
+File::File(string FileName,OpenMode Mode, unsigned long Perms)
+{
+ Flags = 0;
+ switch (Mode)
+ {
+ case ReadOnly:
+ iFd = open(FileName.c_str(),O_RDONLY);
+ break;
+
+ case WriteEmpty:
+ unlink(FileName.c_str());
+ iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_EXCL,Perms);
+ break;
+
+ case WriteExists:
+ iFd = open(FileName.c_str(),O_RDWR);
+ break;
+ }
+
+ if (iFd < 0)
+ _error->Errno("open","Could not open file %s",FileName.c_str());
+ else
+ this->FileName = FileName;
+}
+ /*}}}*/
+// File::~File - Closes the file /*{{{*/
+// ---------------------------------------------------------------------
+/* If the proper modes are selected then we close the Fd and possibly
+ unlink the file on error. */
+File::~File()
+{
+ Close();
+}
+ /*}}}*/
+// File::Read - Read a bit of the file /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool File::Read(void *To,unsigned long Size)
+{
+ if (read(iFd,To,Size) != (signed)Size)
+ {
+ Flags |= Fail;
+ return _error->Errno("read","Read error");
+ }
+
+ return true;
+}
+ /*}}}*/
+// File::Write - Write to the file /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool File::Write(void *From,unsigned long Size)
+{
+ if (write(iFd,From,Size) != (signed)Size)
+ {
+ Flags |= Fail;
+ return _error->Errno("write","Write error");
+ }
+
+ return true;
+}
+ /*}}}*/
+// File::Seek - Seek in the file /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool File::Seek(unsigned long To)
+{
+ if (lseek(iFd,To,SEEK_SET) != (signed)To)
+ {
+ Flags |= Fail;
+ return _error->Error("Unable to seek to %u",To);
+ }
+
+ return true;
+}
+ /*}}}*/
+// File::Size - Return the size of the file /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+unsigned long File::Size()
+{
+ struct stat Buf;
+ if (fstat(iFd,&Buf) != 0)
+ return _error->Errno("fstat","Unable to determine the file size");
+ return Buf.st_size;
+}
+ /*}}}*/
+// File::Close - Close the file if the close flag is set /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool File::Close()
+{
+ bool Res = true;
+ if ((Flags & AutoClose) == AutoClose)
+ if (close(iFd) != 0)
+ Res &= _error->Errno("close","Problem closing the file");
+
+ if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail &&
+ FileName.empty() == false)
+ if (unlink(FileName.c_str()) != 0)
+ Res &= _error->Warning("unlnk","Problem unlinking the file");
+ return Res;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
new file mode 100644
index 000000000..1b6666843
--- /dev/null
+++ b/apt-pkg/contrib/fileutl.h
@@ -0,0 +1,63 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: fileutl.h,v 1.1 1998/07/02 02:58:13 jgg Exp $
+/* ######################################################################
+
+ File Utilities
+
+ CopyFile - Buffered copy of a single file
+ GetLock - dpkg compatible lock file manipulation (fcntl)
+ FileExists - Returns true if the file exists
+ SafeGetCWD - Returns the CWD in a string with overrun protection
+
+ The file class is a handy abstraction for various functions+classes
+ that need to accept filenames.
+
+ This source is placed in the Public Domain, do with it what you will
+ It was originally written by Jason Gunthorpe.
+
+ ##################################################################### */
+ /*}}}*/
+// Header section: pkglib
+#ifndef PKGLIB_FILEUTL_H
+#define PKGLIB_FILEUTL_H
+
+#include <string>
+
+class File
+{
+ protected:
+ int iFd;
+
+ enum LocalFlags {AutoClose = (1<<0),Fail = (1<<1),DelOnFail = (1<<2)};
+ unsigned long Flags;
+ string FileName;
+
+ public:
+ enum OpenMode {ReadOnly,WriteEmpty,WriteExists};
+
+ bool Read(void *To,unsigned long Size);
+ bool Write(void *From,unsigned long Size);
+ bool Seek(unsigned long To);
+ unsigned long Size();
+ bool Close();
+
+ // Simple manipulators
+ inline int Fd() {return iFd;};
+ inline bool IsOpen() {return iFd >= 0;};
+ inline bool Failed() {return (Flags & Fail) == Fail;};
+ inline void EraseOnFailure() {Flags |= DelOnFail;};
+ inline void OpFail() {Flags |= Fail;};
+
+ File(string FileName,OpenMode Mode,unsigned long Perms = 0666);
+ File(int Fd) : iFd(Fd), Flags(AutoClose) {};
+ File(int Fd,bool) : iFd(Fd), Flags(0) {};
+ virtual ~File();
+};
+
+bool CopyFile(string From,string To);
+int GetLock(string File,bool Errors = true);
+bool FileExists(string File);
+string SafeGetCWD();
+
+#endif
diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc
new file mode 100644
index 000000000..85cac1cca
--- /dev/null
+++ b/apt-pkg/contrib/mmap.cc
@@ -0,0 +1,227 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: mmap.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $
+/* ######################################################################
+
+ MMap Class - Provides 'real' mmap or a faked mmap using read().
+
+ MMap cover class.
+
+ Some broken versions of glibc2 (libc6) have a broken definition
+ of mmap that accepts a char * -- all other systems (and libc5) use
+ void *. We can't safely do anything here that would be portable, so
+ libc6 generates warnings -- which should be errors, g++ isn't properly
+ strict.
+
+ The configure test notes that some OS's have broken private mmap's
+ so on those OS's we can't use mmap. This means we have to use
+ configure to test mmap and can't rely on the POSIX
+ _POSIX_MAPPED_FILES test.
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#define _BSD_SOURCE
+#include <pkglib/mmap.h>
+#include <pkglib/error.h>
+
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/user.h>
+#include <unistd.h>
+#include <fcntl.h>
+ /*}}}*/
+
+// MMap::MMap - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+MMap::MMap(File &F,unsigned long Flags) : Fd(F), Flags(Flags), iSize(0),
+ Base(0)
+{
+ if ((Flags & NoImmMap) != NoImmMap)
+ Map();
+}
+ /*}}}*/
+// MMap::~MMap - Destructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+MMap::~MMap()
+{
+ Close(true);
+}
+ /*}}}*/
+// MMap::Map - Perform the mapping /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool MMap::Map()
+{
+ iSize = Fd.Size();
+
+ // Set the permissions.
+ int Prot = PROT_READ;
+ int Map = MAP_SHARED;
+ if ((Flags & ReadOnly) != ReadOnly)
+ Prot |= PROT_WRITE;
+ if ((Flags & Public) != Public)
+ Map = MAP_PRIVATE;
+
+ // Map it.
+ Base = mmap(0,iSize,Prot,Map,Fd.Fd(),0);
+ if (Base == (void *)-1)
+ return _error->Errno("mmap","Couldn't make mmap of %u bytes",iSize);
+
+ return true;
+}
+ /*}}}*/
+// MMap::Close - Close the map /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool MMap::Close(bool DoClose)
+{
+ if (Fd.IsOpen() == false)
+ return true;
+
+ Sync();
+
+ if (munmap((char *)Base,iSize) != 0)
+ _error->Warning("Unable to munmap");
+
+ iSize = 0;
+ if (DoClose == true)
+ Fd.Close();
+ return true;
+}
+ /*}}}*/
+// MMap::Sync - Syncronize the map with the disk /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool MMap::Sync()
+{
+ if ((Flags & ReadOnly) == ReadOnly)
+ if (msync((char *)Base,iSize,MS_SYNC) != 0)
+ return _error->Error("msync","Unable to write mmap");
+ return true;
+}
+ /*}}}*/
+// MMap::Sync - Syncronize a section of the file to disk /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool MMap::Sync(unsigned long Start,unsigned long Stop)
+{
+ if ((Flags & ReadOnly) == ReadOnly)
+ if (msync((char *)Base+(int)(Start/PAGE_SIZE)*PAGE_SIZE,Stop - Start,MS_SYNC) != 0)
+ return _error->Error("msync","Unable to write mmap");
+ return true;
+}
+ /*}}}*/
+
+// DynamicMMap::DynamicMMap - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+DynamicMMap::DynamicMMap(File &F,unsigned long Flags,unsigned long WorkSpace) :
+ MMap(F,Flags | NoImmMap), WorkSpace(WorkSpace)
+{
+ unsigned long EndOfFile = Fd.Size();
+ Fd.Seek(WorkSpace);
+ char C = 0;
+ Fd.Write(&C,sizeof(C));
+ Map();
+ iSize = EndOfFile;
+}
+ /*}}}*/
+// DynamicMMap::~DynamicMMap - Destructor /*{{{*/
+// ---------------------------------------------------------------------
+/* We truncate the file to the size of the memory data set */
+DynamicMMap::~DynamicMMap()
+{
+ unsigned long EndOfFile = iSize;
+ Close(false);
+ ftruncate(Fd.Fd(),EndOfFile);
+ Fd.Close();
+}
+ /*}}}*/
+// DynamicMMap::RawAllocate - Allocate a raw chunk of unaligned space /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+unsigned long DynamicMMap::RawAllocate(unsigned long Size)
+{
+ unsigned long Result = iSize;
+ iSize += Size;
+
+ // Just in case error check
+ if (Result > WorkSpace)
+ {
+ _error->Error("Dynamic MMap ran out of room");
+ return 0;
+ }
+
+ return Result;
+}
+ /*}}}*/
+// DynamicMMap::Allocate - Pooled aligned allocation /*{{{*/
+// ---------------------------------------------------------------------
+/* This allocates an Item of size ItemSize so that it is aligned to its
+ size in the file. */
+unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
+{
+ // Look for a matching pool entry
+ Pool *I;
+ Pool *Empty = 0;
+ for (I = Pools; I != Pools + PoolCount; I++)
+ {
+ if (I->ItemSize == 0)
+ Empty = I;
+ if (I->ItemSize == ItemSize)
+ break;
+ }
+
+ // No pool is allocated, use an unallocated one
+ if (I == Pools + PoolCount)
+ {
+ // Woops, we ran out, the calling code should allocate more.
+ if (Empty == 0)
+ {
+ _error->Error("Ran out of allocation pools");
+ return 0;
+ }
+
+ I = Empty;
+ I->ItemSize = ItemSize;
+ I->Count = 0;
+ }
+
+ // Out of space, allocate some more
+ if (I->Count == 0)
+ {
+ I->Count = 20*1024/ItemSize;
+ I->Start = RawAllocate(I->Count*ItemSize);
+ }
+
+ I->Count--;
+ unsigned long Result = I->Start;
+ I->Start += ItemSize;
+ return Result/ItemSize;
+}
+ /*}}}*/
+// DynamicMMap::WriteString - Write a string to the file /*{{{*/
+// ---------------------------------------------------------------------
+/* Strings are not aligned to anything */
+unsigned long DynamicMMap::WriteString(const char *String,
+ unsigned long Len)
+{
+ unsigned long Result = iSize;
+ // Just in case error check
+ if (Result > WorkSpace)
+ {
+ _error->Error("Dynamic MMap ran out of room");
+ return 0;
+ }
+
+ if (Len == 0)
+ Len = strlen(String);
+ iSize += Len + 1;
+ memcpy((char *)Base + Result,String,Len);
+ ((char *)Base)[Result + Len] = 0;
+ return Result;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h
new file mode 100644
index 000000000..096304177
--- /dev/null
+++ b/apt-pkg/contrib/mmap.h
@@ -0,0 +1,92 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: mmap.h,v 1.1 1998/07/02 02:58:13 jgg Exp $
+/* ######################################################################
+
+ MMap Class - Provides 'real' mmap or a faked mmap using read().
+
+ The purpose of this code is to provide a generic way for clients to
+ access the mmap function. In enviroments that do not support mmap
+ from file fd's this function will use read and normal allocated
+ memory.
+
+ Writing to a public mmap will always fully comit all changes when the
+ class is deleted. Ie it will rewrite the file, unless it is readonly
+
+ The DynamicMMap class is used to help the on-disk data structure
+ generators. It provides a large allocated workspace and members
+ to allocate space from the workspace in an effecient fashion.
+
+ This source is placed in the Public Domain, do with it what you will
+ It was originally written by Jason Gunthorpe.
+
+ ##################################################################### */
+ /*}}}*/
+// Header section: pkglib
+#ifndef PKGLIB_MMAP_H
+#define PKGLIB_MMAP_H
+
+#include <string>
+#include <pkglib/fileutl.h>
+
+class MMap
+{
+ protected:
+
+ File &Fd;
+ unsigned long Flags;
+ unsigned long iSize;
+ void *Base;
+
+ bool Map();
+ bool Close(bool DoClose = true);
+
+ public:
+
+ enum OpenFlags {NoImmMap = (1<<0),Public = (1<<1),ReadOnly = (1<<2)};
+
+ // Simple accessors
+ inline operator void *() {return Base;};
+ inline void *Data() {return Base;};
+ inline unsigned long Size() {return iSize;};
+
+ // File manipulators
+ bool Sync();
+ bool Sync(unsigned long Start,unsigned long Stop);
+
+ MMap(File &F,unsigned long Flags);
+ virtual ~MMap();
+};
+
+class DynamicMMap : public MMap
+{
+ public:
+
+ // This is the allocation pool structure
+ struct Pool
+ {
+ unsigned long ItemSize;
+ unsigned long Start;
+ unsigned long Count;
+ };
+
+ protected:
+
+ unsigned long WorkSpace;
+ Pool *Pools;
+ unsigned int PoolCount;
+
+ public:
+
+ // Allocation
+ unsigned long RawAllocate(unsigned long Size);
+ unsigned long Allocate(unsigned long ItemSize);
+ unsigned long WriteString(const char *String,unsigned long Len = 0);
+ inline unsigned long WriteString(string S) {return WriteString(S.begin(),S.size());};
+ void UsePools(Pool &P,unsigned int Count) {Pools = &P; PoolCount = Count;};
+
+ DynamicMMap(File &F,unsigned long Flags,unsigned long WorkSpace = 1024*1024);
+ virtual ~DynamicMMap();
+};
+
+#endif
diff --git a/apt-pkg/contrib/system.h b/apt-pkg/contrib/system.h
new file mode 100644
index 000000000..e652348b0
--- /dev/null
+++ b/apt-pkg/contrib/system.h
@@ -0,0 +1,57 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: system.h,v 1.1 1998/07/02 02:58:13 jgg Exp $
+/* ######################################################################
+
+ System Header - Usefull private definitions
+
+ This source is placed in the Public Domain, do with it what you will
+ It was originally written by Brian C. White.
+
+ ##################################################################### */
+ /*}}}*/
+// Private header
+// Header section: /
+#ifndef SYSTEM_H
+#define SYSTEM_H
+
+// MIN_VAL(SINT16) will return -0x8000 and MAX_VAL(SINT16) = 0x7FFF
+#define MIN_VAL(t) (((t)(-1) > 0) ? (t)( 0) : (t)(((1L<<(sizeof(t)*8-1)) )))
+#define MAX_VAL(t) (((t)(-1) > 0) ? (t)(-1) : (t)(((1L<<(sizeof(t)*8-1))-1)))
+
+// Min/Max functions
+#if defined(__HIGHC__)
+#define MIN(x,y) _min(x,y)
+#define MAX(x,y) _max(x,y)
+#endif
+
+// GNU C++ has a min/max operator <coolio>
+#if defined(__GNUG__)
+#define MIN(A,B) ((A) <? (B))
+#define MAX(A,B) ((A) >? (B))
+#endif
+
+/* Templates tend to mess up existing code that uses min/max because of the
+ strict matching requirements */
+#if !defined(MIN)
+#define MIN(A,B) ((A) < (B)?(A):(B))
+#define MAX(A,B) ((A) > (B)?(A):(B))
+#endif
+
+/* Bound functions, bound will return the value b within the limits a-c
+ bounv will change b so that it is within the limits of a-c. */
+#define _bound(a,b,c) MIN(c,MAX(b,a))
+#define _boundv(a,b,c) b = _bound(a,b,c)
+#define ABS(a) (((a) < (0)) ?-(a) : (a))
+
+/* Usefull count macro, use on an array of things and it will return the
+ number of items in the array */
+#define _count(a) (sizeof(a)/sizeof(a[0]))
+
+// Flag Macros
+#define FLAG(f) (1L << (f))
+#define SETFLAG(v,f) ((v) |= FLAG(f))
+#define CLRFLAG(v,f) ((v) &=~FLAG(f))
+#define CHKFLAG(v,f) ((v) & FLAG(f) ? true : false)
+
+#endif
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
new file mode 100644
index 000000000..b75fe6d94
--- /dev/null
+++ b/apt-pkg/pkgcache.cc
@@ -0,0 +1,360 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: pkgcache.cc,v 1.1 1998/07/02 02:58:12 jgg Exp $
+/* ######################################################################
+
+ Package Cache - Accessor code for the cache
+
+ Please see doc/pkglib/cache.sgml for a more detailed description of
+ this format. Also be sure to keep that file up-to-date!!
+
+ This is the general utility functions for cache managment. They provide
+ a complete set of accessor functions for the cache. The cacheiterators
+ header contains the STL-like iterators that can be used to easially
+ navigate the cache as well as seemlessly dereference the mmap'd
+ indexes. Use these always.
+
+ The main class provides for ways to get package indexes and some
+ general lookup functions to start the iterators.
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <pkglib/pkgcache.h>
+#include <pkglib/version.h>
+#include <pkglib/error.h>
+#include <system.h>
+
+#include <string>
+#include <sys/stat.h>
+#include <unistd.h>
+ /*}}}*/
+
+// Cache::Header::Header - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* Simply initialize the header */
+pkgCache::Header::Header()
+{
+ Signature = 0x98FE76DC;
+
+ /* Whenever the structures change the major version should be bumped,
+ whenever the generator changes the minor version should be bumped. */
+ MajorVersion = 2;
+ MinorVersion = 0;
+ Dirty = true;
+
+ HeaderSz = sizeof(pkgCache::Header);
+ PackageSz = sizeof(pkgCache::Package);
+ PackageFileSz = sizeof(pkgCache::PackageFile);
+ VersionSz = sizeof(pkgCache::Version);
+ DependencySz = sizeof(pkgCache::Dependency);
+ ProvidesSz = sizeof(pkgCache::Provides);
+
+ PackageCount = 0;
+ VersionCount = 0;
+ DependsCount = 0;
+ PackageFileCount = 0;
+
+ FileList = 0;
+ StringList = 0;
+ memset(HashTable,0,sizeof(HashTable));
+ memset(Pools,0,sizeof(Pools));
+}
+ /*}}}*/
+// Cache::Header::CheckSizes - Check if the two headers have same *sz /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool pkgCache::Header::CheckSizes(Header &Against) const
+{
+ if (HeaderSz == Against.HeaderSz &&
+ PackageSz == Against.PackageSz &&
+ PackageFileSz == Against.PackageFileSz &&
+ VersionSz == Against.VersionSz &&
+ DependencySz == Against.DependencySz &&
+ ProvidesSz == Against.ProvidesSz)
+ return true;
+ return false;
+}
+ /*}}}*/
+
+// Cache::pkgCache - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgCache::pkgCache(MMap &Map) : Map(Map)
+{
+ ReMap();
+}
+ /*}}}*/
+// Cache::ReMap - Reopen the cache file /*{{{*/
+// ---------------------------------------------------------------------
+/* If the file is already closed then this will open it open it. */
+bool pkgCache::ReMap()
+{
+ // Apply the typecasts.
+ HeaderP = (Header *)Map.Data();
+ PkgP = (Package *)Map.Data();
+ PkgFileP = (PackageFile *)Map.Data();
+ VerP = (Version *)Map.Data();
+ ProvideP = (Provides *)Map.Data();
+ DepP = (Dependency *)Map.Data();
+ StringItemP = (StringItem *)Map.Data();
+ StrP = (char *)Map.Data();
+
+ cout << "Size is " << Map.Size() << endl;
+ if (Map.Size() == 0)
+ return false;
+
+ // Check the header
+ Header DefHeader;
+ if (HeaderP->Signature != DefHeader.Signature ||
+ HeaderP->Dirty == true)
+ return _error->Error("The package cache file is corrupted");
+
+ if (HeaderP->MajorVersion != DefHeader.MajorVersion ||
+ HeaderP->MinorVersion != DefHeader.MinorVersion ||
+ HeaderP->CheckSizes(DefHeader) == false)
+ return _error->Error("The package cache file is an incompatible version");
+
+ return true;
+}
+ /*}}}*/
+// Cache::Hash - Hash a string /*{{{*/
+// ---------------------------------------------------------------------
+/* This is used to generate the hash entries for the HashTable. With my
+ package list from bo this function gets 94% table usage on a 512 item
+ table (480 used items) */
+unsigned long pkgCache::sHash(string Str)
+{
+ unsigned long Hash = 0;
+ for (const char *I = Str.begin(); I != Str.end(); I++)
+ Hash += *I * ((Str.end() - I + 1));
+ Header H;
+ return Hash % _count(H.HashTable);
+}
+
+unsigned long pkgCache::sHash(const char *Str)
+{
+ unsigned long Hash = 0;
+ const char *End = Str + strlen(Str);
+ for (const char *I = Str; I != End; I++)
+ Hash += *I * ((End - I + 1));
+ Header H;
+ return Hash % _count(H.HashTable);
+}
+
+ /*}}}*/
+// Cache::FindPkg - Locate a package by name /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns 0 on error, pointer to the package otherwise */
+pkgCache::PkgIterator pkgCache::FindPkg(string Name)
+{
+ // Look at the hash bucket
+ Package *Pkg = PkgP + HeaderP->HashTable[Hash(Name)];
+ for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage)
+ {
+ if (Pkg->Name != 0 && StrP + Pkg->Name == Name)
+ return PkgIterator(*this,Pkg);
+ }
+ return PkgIterator(*this,0);
+}
+ /*}}}*/
+
+// Cache::PkgIterator - operator ++ - Postfix incr /*{{{*/
+// ---------------------------------------------------------------------
+/* This will advance to the next logical package in the hash table. */
+void pkgCache::PkgIterator::operator ++(int)
+{
+ // Follow the current links
+ if (Pkg != Owner->PkgP)
+ Pkg = Owner->PkgP + Pkg->NextPackage;
+
+ // Follow the hash table
+ while (Pkg == Owner->PkgP && HashIndex < (signed)_count(Owner->HeaderP->HashTable))
+ {
+ HashIndex++;
+ Pkg = Owner->PkgP + Owner->HeaderP->HashTable[HashIndex];
+ }
+};
+ /*}}}*/
+// Bases for iterator classes /*{{{*/
+void pkgCache::VerIterator::_dummy() {}
+void pkgCache::DepIterator::_dummy() {}
+void pkgCache::PrvIterator::_dummy() {}
+ /*}}}*/
+// PkgIterator::State - Check the State of the package /*{{{*/
+// ---------------------------------------------------------------------
+/* By this we mean if it is either cleanly installed or cleanly removed. */
+pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const
+{
+ if (Pkg->CurrentState == pkgSTATE_UnPacked ||
+ Pkg->CurrentState == pkgSTATE_HalfConfigured)
+ return NeedsConfigure;
+
+ if (Pkg->CurrentState == pkgSTATE_UnInstalled ||
+ Pkg->CurrentState == pkgSTATE_HalfInstalled ||
+ Pkg->InstState != pkgSTATE_Ok)
+ return NeedsUnpack;
+
+ return NeedsNothing;
+}
+ /*}}}*/
+// DepIterator::IsCritical - Returns true if the dep is important /*{{{*/
+// ---------------------------------------------------------------------
+/* Currently critical deps are defined as depends, predepends and
+ conflicts. */
+bool pkgCache::DepIterator::IsCritical()
+{
+ if (Dep->Type == pkgDEP_Conflicts || Dep->Type == pkgDEP_Depends ||
+ Dep->Type == pkgDEP_PreDepends)
+ return true;
+ return false;
+}
+ /*}}}*/
+// DepIterator::SmartTargetPkg - Resolve dep target pointers w/provides /*{{{*/
+// ---------------------------------------------------------------------
+/* This intellegently looks at dep target packages and tries to figure
+ out which package should be used. This is needed to nicely handle
+ provide mapping. If the target package has no other providing packages
+ then it returned. Otherwise the providing list is looked at to
+ see if there is one one unique providing package if so it is returned.
+ Otherwise true is returned and the target package is set. The return
+ result indicates whether the node should be expandable */
+bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result)
+{
+ Result = TargetPkg();
+
+ // No provides at all
+ if (Result->ProvidesList == 0)
+ return false;
+
+ // There is the Base package and the providing ones which is at least 2
+ if (Result->VersionList != 0)
+ return true;
+
+ /* We have to skip over indirect provisions of the package that
+ owns the dependency. For instance, if libc5-dev depends on the
+ virtual package libc-dev which is provided by libc5-dev and libc6-dev
+ we must ignore libc5-dev when considering the provides list. */
+ PrvIterator PStart = Result.ProvidesList();
+ for (; PStart.end() != true && PStart.OwnerPkg() == ParentPkg(); PStart++);
+
+ // Nothing but indirect self provides
+ if (PStart.end() == true)
+ return false;
+
+ // Check for single packages in the provides list
+ PrvIterator P = PStart;
+ for (; P.end() != true; P++)
+ {
+ // Skip over self provides
+ if (P.OwnerPkg() == ParentPkg())
+ continue;
+ if (PStart.OwnerPkg() != P.OwnerPkg())
+ break;
+ }
+
+ // Check for non dups
+ if (P.end() != true)
+ return true;
+ Result = PStart.OwnerPkg();
+ return false;
+}
+ /*}}}*/
+// DepIterator::AllTargets - Returns the set of all possible targets /*{{{*/
+// ---------------------------------------------------------------------
+/* This is a more usefull version of TargetPkg() that follows versioned
+ provides. It includes every possible package-version that could satisfy
+ the dependency. The last item in the list has a 0. */
+pkgCache::Version **pkgCache::DepIterator::AllTargets()
+{
+ Version **Res = 0;
+ unsigned long Size =0;
+ while (1)
+ {
+ Version **End = Res;
+ PkgIterator DPkg = TargetPkg();
+
+ // Walk along the actual package providing versions
+ for (VerIterator I = DPkg.VersionList(); I.end() == false; I++)
+ {
+ if (pkgCheckDep(TargetVer(),I.VerStr(),Dep->CompareOp) == false)
+ continue;
+
+ if (Dep->Type == pkgDEP_Conflicts && ParentPkg() == I.ParentPkg())
+ continue;
+
+ Size++;
+ if (Res != 0)
+ *End++ = I;
+ }
+
+ // Follow all provides
+ for (PrvIterator I = DPkg.ProvidesList(); I.end() == false; I++)
+ {
+ if (pkgCheckDep(TargetVer(),I.ProvideVersion(),Dep->CompareOp) == false)
+ continue;
+
+ if (Dep->Type == pkgDEP_Conflicts && ParentPkg() == I.OwnerPkg())
+ continue;
+
+ Size++;
+ if (Res != 0)
+ *End++ = I.OwnerVer();
+ }
+
+ // Do it again and write it into the array
+ if (Res == 0)
+ {
+ Res = new Version *[Size+1];
+ Size = 0;
+ }
+ else
+ {
+ *End = 0;
+ break;
+ }
+ }
+
+ return Res;
+}
+ /*}}}*/
+// VerIterator::CompareVer - Fast version compare for same pkgs /*{{{*/
+// ---------------------------------------------------------------------
+/* This just looks over the version list to see if B is listed before A. In
+ most cases this will return in under 4 checks, ver lists are short. */
+int pkgCache::VerIterator::CompareVer(const VerIterator &B) const
+{
+ // Check if they are equal
+ if (*this == B)
+ return 0;
+ if (end() == true)
+ return -1;
+ if (B.end() == true)
+ return 1;
+
+ /* Start at A and look for B. If B is found then A > B otherwise
+ B was before A so A < B */
+ VerIterator I = *this;
+ for (;I.end() == false; I++)
+ if (I == B)
+ return 1;
+ return -1;
+}
+ /*}}}*/
+// PkgFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/
+// ---------------------------------------------------------------------
+/* This stats the file and compares its stats with the ones that were
+ stored during generation. Date checks should probably also be
+ included here. */
+bool pkgCache::PkgFileIterator::IsOk()
+{
+ struct stat Buf;
+ if (stat(FileName(),&Buf) != 0)
+ return false;
+
+ if (Buf.st_size != (signed)File->Size || Buf.st_mtime != File->mtime)
+ return false;
+
+ return true;
+}
+ /*}}}*/
diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h
new file mode 100644
index 000000000..0dc939a51
--- /dev/null
+++ b/apt-pkg/pkgcache.h
@@ -0,0 +1,280 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: pkgcache.h,v 1.1 1998/07/02 02:58:12 jgg Exp $
+/* ######################################################################
+
+ Cache - Structure definitions for the cache file
+
+ Please see doc/pkglib/cache.sgml for a more detailed description of
+ this format. Also be sure to keep that file up-to-date!!
+
+ Clients should always use the CacheIterators classes for access to the
+ cache. They provide a simple STL-like method for traversing the links
+ of the datastructure.
+
+ See pkgcachegen.h for information about generating cache structures.
+
+ ##################################################################### */
+ /*}}}*/
+// Header section: pkglib
+#ifndef PKGLIB_PKGCACHE_H
+#define PKGLIB_PKGCACHE_H
+
+#include <string>
+#include <time.h>
+#include <pkglib/mmap.h>
+
+// Definitions for Depends::Type
+#define pkgDEP_Depends 1
+#define pkgDEP_PreDepends 2
+#define pkgDEP_Suggests 3
+#define pkgDEP_Recommends 4
+#define pkgDEP_Conflicts 5
+#define pkgDEP_Replaces 6
+
+// Definitions for Version::Priority
+#define pkgPRIO_Important 1
+#define pkgPRIO_Required 2
+#define pkgPRIO_Standard 3
+#define pkgPRIO_Optional 4
+#define pkgPRIO_Extra 5
+
+// Definitions for Package::SelectedState
+#define pkgSTATE_Unkown 0
+#define pkgSTATE_Install 1
+#define pkgSTATE_Hold 2
+#define pkgSTATE_DeInstall 3
+#define pkgSTATE_Purge 4
+
+// Definitions for Package::Flags
+#define pkgFLAG_Auto (1 << 0)
+#define pkgFLAG_New (1 << 1)
+#define pkgFLAG_Obsolete (1 << 2)
+#define pkgFLAG_Essential (1 << 3)
+#define pkgFLAG_ImmediateConf (1 << 4)
+
+// Definitions for Package::InstState
+#define pkgSTATE_Ok 0
+#define pkgSTATE_ReInstReq 1
+#define pkgSTATE_Hold 2
+#define pkgSTATE_HoldReInstReq 3
+
+// Definitions for Package::CurrentState
+#define pkgSTATE_NotInstalled 0
+#define pkgSTATE_UnPacked 1
+#define pkgSTATE_HalfConfigured 2
+#define pkgSTATE_UnInstalled 3
+#define pkgSTATE_HalfInstalled 4
+#define pkgSTATE_ConfigFiles 5
+#define pkgSTATE_Installed 6
+
+// Definitions for PackageFile::Flags
+#define pkgFLAG_NotSource (1 << 0)
+
+// Definitions for Dependency::CompareOp
+#define pkgOP_OR 0x10
+#define pkgOP_LESSEQ 0x1
+#define pkgOP_GREATEREQ 0x2
+#define pkgOP_LESS 0x3
+#define pkgOP_GREATER 0x4
+#define pkgOP_EQUALS 0x5
+#define pkgOP_NOTEQUALS 0x6
+
+class pkgCache
+{
+ public:
+ // Cache element predeclarations
+ struct Header;
+ struct Package;
+ struct PackageFile;
+ struct Version;
+ struct Provides;
+ struct Dependency;
+ struct StringItem;
+
+ // Iterators
+ class PkgIterator;
+ class VerIterator;
+ class DepIterator;
+ class PrvIterator;
+ class PkgFileIterator;
+ friend PkgIterator;
+ friend VerIterator;
+ friend DepIterator;
+ friend PrvIterator;
+ friend PkgFileIterator;
+
+ protected:
+
+ // Memory mapped cache file
+ string CacheFile;
+ MMap &Map;
+
+ bool Public;
+ bool ReadOnly;
+
+ static unsigned long sHash(string S);
+ static unsigned long sHash(const char *S);
+
+ public:
+
+ // Pointers to the arrays of items
+ Header *HeaderP;
+ Package *PkgP;
+ PackageFile *PkgFileP;
+ Version *VerP;
+ Provides *ProvideP;
+ Dependency *DepP;
+ StringItem *StringItemP;
+ char *StrP;
+
+ virtual bool ReMap();
+ inline bool Sync() {return Map.Sync();};
+
+ // String hashing function (512 range)
+ inline unsigned long Hash(string S) const {return sHash(S);};
+ inline unsigned long Hash(const char *S) const {return sHash(S);};
+
+ // Accessors
+ PkgIterator FindPkg(string Name);
+ Header &Head() {return *HeaderP;};
+ inline PkgIterator PkgBegin();
+ inline PkgIterator PkgEnd();
+
+ pkgCache(MMap &Map);
+ virtual ~pkgCache() {};
+};
+
+// Header structure
+struct pkgCache::Header
+{
+ // Signature information
+ unsigned long Signature;
+ short MajorVersion;
+ short MinorVersion;
+ bool Dirty;
+
+ // Size of structure values
+ unsigned short HeaderSz;
+ unsigned short PackageSz;
+ unsigned short PackageFileSz;
+ unsigned short VersionSz;
+ unsigned short DependencySz;
+ unsigned short ProvidesSz;
+
+ // Structure counts
+ unsigned long PackageCount;
+ unsigned long VersionCount;
+ unsigned long DependsCount;
+ unsigned long PackageFileCount;
+
+ // Offsets
+ unsigned long FileList; // struct PackageFile
+ unsigned long StringList; // struct StringItem
+
+ /* Allocation pools, there should be one of these for each structure
+ excluding the header */
+ DynamicMMap::Pool Pools[6];
+
+ // Rapid package name lookup
+ unsigned long HashTable[512];
+
+ bool CheckSizes(Header &Against) const;
+ Header();
+};
+
+struct pkgCache::Package
+{
+ // Pointers
+ unsigned long Name; // Stringtable
+ unsigned long VersionList; // Version
+ unsigned long TargetVer; // Version
+ unsigned long CurrentVer; // Version
+ unsigned long TargetDist; // StringTable (StringItem)
+ unsigned long Section; // StringTable (StringItem)
+
+ // Linked list
+ unsigned long NextPackage; // Package
+ unsigned long RevDepends; // Dependency
+ unsigned long ProvidesList; // Provides
+
+ // Install/Remove/Purge etc
+ unsigned char SelectedState; // What
+ unsigned char InstState; // Flags
+ unsigned char CurrentState; // State
+
+ unsigned short ID;
+ unsigned short Flags;
+};
+
+struct pkgCache::PackageFile
+{
+ // Names
+ unsigned long FileName; // Stringtable
+ unsigned long Version; // Stringtable
+ unsigned long Distribution; // Stringtable
+ unsigned long Size;
+
+ // Linked list
+ unsigned long NextFile; // PackageFile
+ unsigned short ID;
+ unsigned short Flags;
+ time_t mtime; // Modification time for the file
+};
+
+struct pkgCache::Version
+{
+ unsigned long VerStr; // Stringtable
+ unsigned long File; // PackageFile
+ unsigned long Section; // StringTable (StringItem)
+
+ // Lists
+ unsigned long NextVer; // Version
+ unsigned long DependsList; // Dependency
+ unsigned long ParentPkg; // Package
+ unsigned long ProvidesList; // Provides
+
+ unsigned long Offset;
+ unsigned long Size;
+ unsigned long InstalledSize;
+ unsigned short ID;
+ unsigned char Priority;
+};
+
+struct pkgCache::Dependency
+{
+ unsigned long Version; // Stringtable
+ unsigned long Package; // Package
+ unsigned long NextDepends; // Dependency
+ unsigned long NextRevDepends; // Dependency
+ unsigned long ParentVer; // Version
+
+ // Specific types of depends
+ unsigned char Type;
+ unsigned char CompareOp;
+ unsigned short ID;
+};
+
+struct pkgCache::Provides
+{
+ unsigned long ParentPkg; // Pacakge
+ unsigned long Version; // Version
+ unsigned long ProvideVersion; // Stringtable
+ unsigned long NextProvides; // Provides
+ unsigned long NextPkgProv; // Provides
+};
+
+struct pkgCache::StringItem
+{
+ unsigned long String; // Stringtable
+ unsigned long NextItem; // StringItem
+};
+
+#include <pkglib/cacheiterators.h>
+
+inline pkgCache::PkgIterator pkgCache::PkgBegin()
+ {return PkgIterator(*this);};
+inline pkgCache::PkgIterator pkgCache::PkgEnd()
+ {return PkgIterator(*this,PkgP);};
+
+#endif
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
new file mode 100644
index 000000000..cb0fd3f74
--- /dev/null
+++ b/apt-pkg/pkgcachegen.cc
@@ -0,0 +1,184 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: pkgcachegen.cc,v 1.1 1998/07/02 02:58:12 jgg Exp $
+/* ######################################################################
+
+ Package Cache Generator - Generator for the cache structure.
+
+ This builds the cache structure from the abstract package list parser.
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <pkglib/pkgcachegen.h>
+#include <pkglib/error.h>
+#include <pkglib/version.h>
+
+#include <sys/stat.h>
+#include <unistd.h>
+ /*}}}*/
+
+// CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* We set the diry flag and make sure that is written to the disk */
+pkgCacheGenerator::pkgCacheGenerator(DynamicMMap &Map) : Map(Map), Cache(Map)
+{
+ if (_error->PendingError() == true)
+ return;
+
+ if (Map.Size() == 0)
+ {
+ Map.RawAllocate(sizeof(pkgCache::Header));
+ *Cache.HeaderP = pkgCache::Header();
+ }
+ Cache.HeaderP->Dirty = true;
+ Map.Sync(0,sizeof(pkgCache::Header));
+ Map.UsePools(*Cache.HeaderP->Pools,sizeof(Cache.HeaderP->Pools)/sizeof(Cache.HeaderP->Pools[0]));
+}
+ /*}}}*/
+// CacheGenerator::~pkgCacheGenerator - Destructor /*{{{*/
+// ---------------------------------------------------------------------
+/* We sync the data then unset the dirty flag in two steps so as to
+ advoid a problem during a crash */
+pkgCacheGenerator::~pkgCacheGenerator()
+{
+ if (_error->PendingError() == true)
+ return;
+ if (Map.Sync() == false)
+ return;
+
+ Cache.HeaderP->Dirty = false;
+ Map.Sync(0,sizeof(pkgCache::Header));
+}
+ /*}}}*/
+// CacheGenerator::MergeList - Merge the package list /*{{{*/
+// ---------------------------------------------------------------------
+/* This provides the generation of the entries in the cache. Each loop
+ goes through a single package record from the underlying parse engine. */
+bool pkgCacheGenerator::MergeList(ListParser &List)
+{
+ List.Owner = this;
+
+ do
+ {
+ // Get a pointer to the package structure
+ string Package = List.Package();
+ pkgCache::PkgIterator Pkg = Cache.FindPkg(Package);
+ if (Pkg.end() == false)
+ {
+ if (NewPackage(Pkg,Package) == false)
+ return false;
+
+ if (List.NewPackage(Pkg) == false)
+ return false;
+ }
+ if (List.UsePackage(Pkg) == false)
+ return false;
+
+ /* Get a pointer to the version structure. We know the list is sorted
+ so we use that fact in the search. Insertion of new versions is
+ done with correct sorting */
+ string Version = List.Version();
+ pkgCache::VerIterator Ver = Pkg.VersionList();
+ unsigned long *Last = &Pkg->VersionList;
+ int Res;
+ for (; Ver.end() == false; Ver++, Last = &Ver->NextVer)
+ {
+ Res = pkgVersionCompare(Version.begin(),Version.end(),Ver.VerStr(),
+ Ver.VerStr() + strlen(Ver.VerStr()));
+ if (Res >= 0)
+ break;
+ }
+
+ /* We already have a version for this item, record that we
+ saw it */
+ if (Res == 0)
+ {
+ if (NewFileVer(Ver,List) == false)
+ return false;
+
+ continue;
+ }
+
+ // Add a new version
+ *Last = NewVersion(Ver,*Last);
+ if (List.NewVersion(Ver) == false)
+ return false;
+
+ if (NewFileVer(Ver,List) == false)
+ return false;
+ }
+ while (List.Step() == true);
+
+ return true;
+}
+ /*}}}*/
+// CacheGenerator::NewPackage - Add a new package /*{{{*/
+// ---------------------------------------------------------------------
+/* This creates a new package structure and adds it to the hash table */
+bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator Pkg,string Name)
+{
+ // Get a structure
+ unsigned long Package = Map.Allocate(sizeof(pkgCache::Package));
+ if (Package == 0)
+ return false;
+
+ Pkg = pkgCache::PkgIterator(Cache,Cache.PackageP + Package);
+
+ // Insert it into the hash table
+ unsigned long Hash = Map.Hash(Name);
+ Pkg->NextPackage = Cache.HeaderP->HashTable[Hash];
+ Cache.HeaderP->HashTable[Hash] = Package;
+
+ // Set the name and the ID
+ Pkg->Name = Map.WriteString(Name);
+ if (Pkg->Name == 0)
+ return false;
+ Pkg->ID = Cache.HeaderP->PackageCount++;
+
+ return true;
+}
+ /*}}}*/
+// CacheGenerator::NewFileVer - Create a new File<->Version association /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator Ver,
+ ListParser &List)
+{
+}
+ /*}}}*/
+// CacheGenerator::NewVersion - Create a new Version /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver,
+ unsigned long Next)
+{
+}
+ /*}}}*/
+// CacheGenerator::SelectFile - Select the current file being parsed /*{{{*/
+// ---------------------------------------------------------------------
+/* This is used to select which file is to be associated with all newly
+ added versions. */
+bool pkgCacheGenerator::SelectFile(string File,unsigned long Flags)
+{
+ struct stat Buf;
+ if (stat(File.c_str(),&Buf) == -1)
+ return _error->Errno("stat","Couldn't stat ",File.c_str());
+
+ // Get some space for the structure
+ CurrentFile = Cache.PkgFileP + Map.Allocate(sizeof(*CurrentFile));
+ if (CurrentFile == Cache.PkgFileP)
+ return false;
+
+ // Fill it in
+ CurrentFile->FileName = Map.WriteString(File);
+ CurrentFile->Size = Buf.st_size;
+ CurrentFile->mtime = Buf.st_mtime;
+ CurrentFile->NextFile = Cache.HeaderP->FileList;
+ CurrentFile->Flags = Flags;
+ PkgFileName = File;
+
+ if (CurrentFile->FileName == 0)
+ return false;
+}
+ /*}}}*/
diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h
new file mode 100644
index 000000000..1385ab964
--- /dev/null
+++ b/apt-pkg/pkgcachegen.h
@@ -0,0 +1,69 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: pkgcachegen.h,v 1.1 1998/07/02 02:58:13 jgg Exp $
+/* ######################################################################
+
+ Package Cache Generator - Generator for the cache structure.
+
+ This builds the cache structure from the abstract package list parser.
+
+ ##################################################################### */
+ /*}}}*/
+// Header section: pkglib
+#ifndef PKGLIB_PKGCACHEGEN_H
+#define PKGLIB_PKGCACHEGEN_H
+
+#include <pkglib/pkgcache.h>
+
+class pkgCacheGenerator
+{
+ public:
+
+ class ListParser;
+
+ protected:
+
+ DynamicMMap &Map;
+ pkgCache Cache;
+
+ string PkgFileName;
+ pkgCache::PackageFile *CurrentFile;
+
+ bool NewPackage(pkgCache::PkgIterator Pkg,string Pkg);
+ bool NewFileVer(pkgCache::VerIterator Ver,ListParser &List);
+ unsigned long NewVersion(pkgCache::VerIterator &Ver,unsigned long Next);
+
+ public:
+
+ // This is the abstract package list parser class.
+ class ListParser
+ {
+ pkgCacheGenerator *Owner;
+ friend pkgCacheGenerator;
+
+ protected:
+
+ inline unsigned long WriteString(string S) {return Owner->Map.WriteString(S);};
+ inline unsigned long WriteString(const char *S,unsigned int Size) {return Owner->Map.WriteString(S,Size);};
+
+ public:
+
+ // These all operate against the current section
+ virtual string Package() = 0;
+ virtual string Version() = 0;
+ virtual bool NewVersion(pkgCache::VerIterator Ver) = 0;
+ virtual bool NewPackage(pkgCache::PkgIterator Pkg) = 0;
+ virtual bool UsePackage(pkgCache::PkgIterator Pkg) = 0;
+
+ virtual bool Step() = 0;
+ };
+ friend ListParser;
+
+ bool SelectFile(string File,unsigned long Flags = 0);
+ bool MergeList(ListParser &List);
+
+ pkgCacheGenerator(DynamicMMap &Map);
+ ~pkgCacheGenerator();
+};
+
+#endif
diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc
new file mode 100644
index 000000000..106b0febe
--- /dev/null
+++ b/apt-pkg/tagfile.cc
@@ -0,0 +1,195 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: tagfile.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $
+/* ######################################################################
+
+ Fast scanner for RFC-822 type header information
+
+ This uses a rotating 64K buffer to load the package information into.
+ The scanner runs over it and isolates and indexes a single section.
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <pkglib/tagfile.h>
+#include <pkglib/error.h>
+
+#include <string>
+#include <stdio.h>
+ /*}}}*/
+
+// TagFile::pkgTagFile - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgTagFile::pkgTagFile(File &Fd) : Fd(Fd)
+{
+ Buffer = new char[64*1024];
+ Start = End = Buffer + 64*1024;
+ Left = Fd.Size();
+ Fill();
+}
+ /*}}}*/
+// TagFile::Step - Advance to the next section /*{{{*/
+// ---------------------------------------------------------------------
+/* If the Section Scanner fails we refill the buffer and try again. */
+bool pkgTagFile::Step(pkgTagSection &Tag)
+{
+ if (Tag.Scan(Start,End - Start) == false)
+ {
+ if (Fill() == false)
+ return false;
+
+ if (Tag.Scan(Start,End - Start) == false)
+ return _error->Error("Unable to parse package file");
+ }
+ Start += Tag.Length();
+ return true;
+}
+ /*}}}*/
+// TagFile::Fill - Top up the buffer /*{{{*/
+// ---------------------------------------------------------------------
+/* This takes the bit at the end of the buffer and puts it at the start
+ then fills the rest from the file */
+bool pkgTagFile::Fill()
+{
+ unsigned long Size = End - Start;
+
+ if (Left == 0)
+ {
+ if (Size <= 1)
+ return false;
+ return true;
+ }
+
+ memmove(Buffer,Start,Size);
+ Start = Buffer;
+
+ // See if only a bit of the file is left or if
+ if (Left < End - Buffer - Size)
+ {
+ if (Fd.Read(Buffer + Size,Left) == false)
+ return false;
+ End = Buffer + Size + Left;
+ Left = 0;
+ }
+ else
+ {
+ if (Fd.Read(Buffer + Size, End - Buffer - Size) == false)
+ return false;
+ Left -= End - Buffer - Size;
+ }
+ 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
+ indexes the tags in the section. */
+bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
+{
+ const char *End = Start + MaxLength;
+ Stop = Section = Start;
+
+ TagCount = 0;
+ Indexes[TagCount++] = Stop - Section;
+ Stop++;
+ for (; Stop < End; Stop++)
+ {
+ if (Stop[-1] != '\n')
+ continue;
+ if (Stop[0] == '\n')
+ {
+ // Extra one at the end to simplify find
+ Indexes[TagCount] = Stop - Section;
+ for (; Stop[0] == '\n' && Stop < End; Stop++);
+ return true;
+ break;
+ }
+
+ if (isspace(Stop[0]) == 0)
+ Indexes[TagCount++] = Stop - Section;
+
+ // Just in case.
+ if (TagCount > sizeof(Indexes)/sizeof(Indexes[0]))
+ TagCount = sizeof(Indexes)/sizeof(Indexes[0]);
+ }
+ return false;
+}
+ /*}}}*/
+// TagSection::Find - Locate a tag /*{{{*/
+// ---------------------------------------------------------------------
+/* This searches the section for a tag that matches the given string. */
+bool pkgTagSection::Find(const char *Tag,const char *&Start,
+ const char *&End)
+{
+ unsigned int Length = strlen(Tag);
+ for (unsigned int I = 0; I != TagCount; I++)
+ {
+ if (strncasecmp(Tag,Section + Indexes[I],Length) != 0)
+ continue;
+
+ // Make sure the colon is in the right place
+ const char *C = Section + Length + Indexes[I];
+ for (; isspace(*C) != 0; C++);
+ if (*C != ':')
+ continue;
+
+ // Strip off the gunk from the start end
+ Start = C;
+ End = Section + Indexes[I+1];
+ for (; (isspace(*Start) != 0 || *Start == ':') && Start < End; Start++);
+ for (; isspace(End[-1]) != 0 && End > Start; End--);
+ return true;
+ }
+ Start = End = 0;
+ return false;
+}
+ /*}}}*/
+
+#include <pkglib/pkgcachegen.h>
+
+int main(int argc,char *argv[])
+{
+ {
+ File F(argv[1],File::ReadOnly);
+ pkgTagFile Test(F);
+ File CacheF("./cache",File::WriteEmpty);
+ DynamicMMap Map(CacheF,MMap::Public);
+ pkgCacheGenerator Gen(Map);
+ Gen.SelectFile("tet");
+ }
+
+#if 0
+ pkgTagSection I;
+ while (Test.Step(I) == true)
+ {
+ const char *Start;
+ const char *End;
+ if (I.Find("Package",Start,End) == false)
+ {
+ cout << "Failed" << endl;
+ continue;
+ }
+
+ cout << "Package: " << string(Start,End - Start) << endl;
+
+/* for (const char *I = Start; I < End; I++)
+ {
+ const char *Begin = I;
+ bool Number = true;
+ while (isspace(*I) == 0 && ispunct(*I) == 0 && I < End)
+ {
+ if (isalpha(*I) != 0)
+ Number = false;
+ I++;
+ }
+ if (Number == false)
+ cout << string(Begin,I-Begin) << endl;
+ while ((isspace(*I) != 0 || ispunct(*I) != 0) && I < End)
+ I++;
+ I--;
+ } */
+ }
+#endif
+ _error->DumpErrors();
+}
diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h
new file mode 100644
index 000000000..a7a82dd1c
--- /dev/null
+++ b/apt-pkg/tagfile.h
@@ -0,0 +1,64 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: tagfile.h,v 1.1 1998/07/02 02:58:13 jgg Exp $
+/* ######################################################################
+
+ Fast scanner for RFC-822 type header information
+
+ This parser handles Debian package files (and others). Their form is
+ RFC-822 type header fields in groups seperated by a blank line.
+
+ The parser reads the and provides methods to step linearly
+ over it or to jump to a pre-recorded start point and read that record.
+
+ A second class is used to perform pre-parsing of the record. It works
+ by indexing the start of each header field and providing lookup
+ functions for header fields.
+
+ ##################################################################### */
+ /*}}}*/
+// Header section: pkglib
+#ifndef PKGLIB_TAGFILE_H
+#define PKGLIB_TAGFILE_H
+
+#include <pkglib/fileutl.h>
+
+class pkgTagSection
+{
+ const char *Section;
+ const char *Stop;
+
+ // We have a limit of 256 tags per section.
+ unsigned short Indexes[256];
+ unsigned int TagCount;
+
+ public:
+
+ inline bool operator ==(const pkgTagSection &rhs) {return Section == rhs.Section;};
+ inline bool operator !=(const pkgTagSection &rhs) {return Section != rhs.Section;};
+
+ bool Find(const char *Tag,const char *&Start, const char *&End);
+ bool Scan(const char *Start,unsigned long MaxLength);
+ inline unsigned long Length() {return Stop - Section;};
+
+ pkgTagSection() : Section(0), Stop(0) {};
+};
+
+class pkgTagFile
+{
+ File Fd;
+ char *Buffer;
+ char *Start;
+ char *End;
+ unsigned long Left;
+
+ bool Fill();
+
+ public:
+
+ bool Step(pkgTagSection &Section);
+
+ pkgTagFile(File &F);
+};
+
+#endif
diff --git a/apt-pkg/version.cc b/apt-pkg/version.cc
new file mode 100644
index 000000000..c02ee5f87
--- /dev/null
+++ b/apt-pkg/version.cc
@@ -0,0 +1,249 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: version.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $
+/* ######################################################################
+
+ Version - Version string
+
+ Version comparing is done using the == and < operators. STL's
+ function.h provides the remaining set of comparitors. A directly
+ callable non-string class version is provided for functions manipulating
+ the cache file (esp the sort function).
+
+ A version is defined to be equal if a case sensitive compare returns
+ that the two strings are the same. For compatibility with the QSort
+ function this version returns -1,0,1.
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <pkglib/version.h>
+#include <pkglib/pkgcache.h>
+
+#include <stdlib.h>
+ /*}}}*/
+
+// Version::pkgVersion - Default Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgVersion::pkgVersion()
+{
+}
+ /*}}}*/
+// Version::operator == - Checks if two versions are equal /*{{{*/
+// ---------------------------------------------------------------------
+/* We can't simply perform a string compare because of epochs. */
+bool pkgVersion::operator ==(const pkgVersion &Vrhs) const
+{
+ if (pkgVersionCompare(Value.begin(),Value.end(),
+ Vrhs.Value.begin(),Vrhs.Value.end()) == 0)
+ return true;
+ return false;
+}
+ /*}}}*/
+// Version::operator < - Checks if this is less than another version /*{{{*/
+// ---------------------------------------------------------------------
+/* All other forms of comparision can be built up from this single function.
+ a > b -> b < a
+ a <= b -> !(a > b) -> !(b < a)
+ a >= b -> !(a < b)
+ */
+bool pkgVersion::operator <(const pkgVersion &Vrhs) const
+{
+ if (pkgVersionCompare(Value.begin(),Value.end(),
+ Vrhs.Value.begin(),Vrhs.Value.end()) == -1)
+ return true;
+ return false;
+}
+ /*}}}*/
+// StrToLong - Convert the string between two iterators to a long /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+static unsigned long StrToLong(const char *begin,const char *end)
+{
+ char S[40];
+ char *I = S;
+ for (; begin != end && I < S + 40;)
+ *I++ = *begin++;
+ *I = 0;
+ return strtoul(S,0,10);
+}
+ /*}}}*/
+// VersionCompare (op) - Greater than comparison for versions /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+int pkgVersionCompare(const char *A, const char *B)
+{
+ return pkgVersionCompare(A,A + strlen(A),B,B + strlen(B));
+}
+int pkgVersionCompare(string A,string B)
+{
+ return pkgVersionCompare(A.begin(),A.end(),B.begin(),B.end());
+}
+
+ /*}}}*/
+// VersionCompare - Greater than comparison for versions /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+int pkgVersionCompare(const char *A, const char *AEnd, const char *B,
+ const char *BEnd)
+{
+ // lhs = left hand side, rhs = right hand side
+ const char *lhs = A;
+ const char *rhs = B;
+
+ /* Consider epochs. They need special handling because an epoch
+ must not be compared against the first element of the real version.
+ This works okay when both sides have an epoch but when only one
+ does it must compare the missing epoch to 0 */
+ for (;lhs != AEnd && *lhs != ':'; lhs++);
+ for (;rhs != BEnd && *rhs != ':'; rhs++);
+
+ // Parse the epoch out
+ unsigned long lhsEpoch = 0;
+ unsigned long rhsEpoch = 0;
+ if (lhs != AEnd && *lhs == ':')
+ lhsEpoch = StrToLong(A,lhs);
+ if (rhs != BEnd && *rhs == ':')
+ rhsEpoch = StrToLong(B,rhs);
+ if (lhsEpoch != rhsEpoch)
+ {
+ if (lhsEpoch > rhsEpoch)
+ return 1;
+ return -1;
+ }
+
+ /* Iterate over the whole string
+ What this does is to spilt the whole string into groups of
+ numeric and non numeric portions. For instance:
+ a67bhgs89
+ Has 4 portions 'a', '67', 'bhgs', '89'. A more normal:
+ 2.7.2-linux-1
+ Has '2', '.', '7', '.' ,'-linux-','1' */
+ lhs = A;
+ rhs = B;
+ while (lhs != AEnd && rhs != BEnd)
+ {
+ // Starting points
+ const char *Slhs = lhs;
+ const char *Srhs = rhs;
+
+ // Compute ending points were we have passed over the portion
+ bool Digit = (isdigit(*lhs) > 0?true:false);
+ for (;lhs != AEnd && (isdigit(*lhs) > 0?true:false) == Digit; lhs++);
+ for (;rhs != BEnd && (isdigit(*rhs) > 0?true:false) == Digit; rhs++);
+
+ if (Digit == true)
+ {
+ // If the lhs has a digit and the rhs does not then true
+ if (rhs - Srhs == 0)
+ return -1;
+
+ // Generate integers from the strings.
+ unsigned long Ilhs = StrToLong(Slhs,lhs);
+ unsigned long Irhs = StrToLong(Srhs,rhs);
+ if (Ilhs != Irhs)
+ {
+ if (Ilhs > Irhs)
+ return 1;
+ return -1;
+ }
+ }
+ else
+ {
+ // They are equal length so do a straight text compare
+ for (;Slhs != lhs && Srhs != rhs; Slhs++, Srhs++)
+ {
+ if (*Slhs != *Srhs)
+ {
+ /* We need to compare non alpha chars as higher than alpha
+ chars (a < !) This is so things like 7.6p2-4 and 7.6-0
+ compare higher as well as . and -. I am not sure how
+ the dpkg code manages to achive the != '-' test, but it
+ is necessary. */
+ int lc = *Slhs;
+ int rc = *Srhs;
+ if (isalpha(lc) == 0 && lc != '-') lc += 256;
+ if (isalpha(rc) == 0 && rc != '-') rc += 256;
+ if (lc > rc)
+ return 1;
+ return -1;
+ }
+ }
+
+ // If the lhs is shorter than the right it is 'less'
+ if (lhs - Slhs < rhs - Srhs)
+ return -1;
+
+ // If the lhs is longer than the right it is 'more'
+ if (lhs - Slhs > rhs - Srhs)
+ return 1;
+ }
+ }
+
+ // The strings must be equal
+ if (lhs == AEnd && rhs == BEnd)
+ return 0;
+
+ // lhs is shorter
+ if (lhs == AEnd)
+ return -1;
+
+ // rhs is shorter
+ if (rhs == BEnd)
+ return 1;
+
+ // Shouldnt happen
+ return 1;
+}
+ /*}}}*/
+// CheckDep - Check a single dependency /*{{{*/
+// ---------------------------------------------------------------------
+/* This simply preforms the version comparison and switch based on
+ operator. */
+bool pkgCheckDep(const char *DepVer,const char *PkgVer,int Op)
+{
+ if (DepVer == 0)
+ return true;
+ if (PkgVer == 0)
+ return false;
+
+ // Perform the actuall comparision.
+ int Res = pkgVersionCompare(PkgVer,DepVer);
+ switch (Op & 0x0F)
+ {
+ case pkgOP_LESSEQ:
+ if (Res <= 0)
+ return true;
+ break;
+
+ case pkgOP_GREATEREQ:
+ if (Res >= 0)
+ return true;
+ break;
+
+ case pkgOP_LESS:
+ if (Res < 0)
+ return true;
+ break;
+
+ case pkgOP_GREATER:
+ if (Res > 0)
+ return true;
+ break;
+
+ case pkgOP_EQUALS:
+ if (Res == 0)
+ return true;
+ break;
+
+ case pkgOP_NOTEQUALS:
+ if (Res != 0)
+ return true;
+ break;
+ }
+
+ return false;
+}
+ /*}}}*/
+
diff --git a/apt-pkg/version.h b/apt-pkg/version.h
new file mode 100644
index 000000000..a30246946
--- /dev/null
+++ b/apt-pkg/version.h
@@ -0,0 +1,45 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: version.h,v 1.1 1998/07/02 02:58:13 jgg Exp $
+/* ######################################################################
+
+ Version - Version string
+
+ This class implements storage and operators for version strings.
+
+ The client is responsible for stripping epochs should it be desired.
+
+ ##################################################################### */
+ /*}}}*/
+// Header section: pkglib
+#ifndef PKGLIB_VERSION_H
+#define PKGLIB_VERSION_H
+
+#include <string>
+
+class pkgVersion
+{
+ string Value;
+
+ public:
+
+ inline operator string () const {return Value;};
+
+ // Assignmnet
+ void operator =(string rhs) {Value = rhs;};
+
+ // Comparitors. STL will provide the rest
+ bool operator ==(const pkgVersion &rhs) const;
+ bool operator <(const pkgVersion &rhs) const;
+
+ pkgVersion();
+ pkgVersion(string Version) : Value(Version) {};
+};
+
+int pkgVersionCompare(const char *A, const char *B);
+int pkgVersionCompare(const char *A, const char *AEnd, const char *B,
+ const char *BEnd);
+int pkgVersionCompare(string A,string B);
+bool pkgCheckDep(const char *DepVer,const char *PkgVer,int Op);
+
+#endif
diff --git a/doc/apt-cache.8 b/doc/apt-cache.8
new file mode 100644
index 000000000..0292973ed
--- /dev/null
+++ b/doc/apt-cache.8
@@ -0,0 +1,199 @@
+.\" This manpage is copyright (C) 1998 Branden Robinson <branden@debian.org>.
+.\"
+.\" This is free software; you may redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2,
+.\" or (at your option) any later version.
+.\"
+.\" This is distributed in the hope that it will be useful, but
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with APT; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+.\" 02111-1307 USA
+.TH apt-cache 8 "16 June 1998" "Debian GNU/Linux"
+.SH NAME
+apt-cache \- APT package handling utility \(em cache manipulator
+.SH SYNOPSIS
+.B apt-cache
+.I command cache
+.RI [ argument
+.IR ... ]
+.SH DESCRIPTION
+.B apt-cache
+performs a variety of operations on APT's package cache.
+.I apt-cache
+is seldom called directly; instead it is usually invoked internally by
+.BR apt-get (8)
+or
+.BR apt (8).
+.PP
+.I command
+is one of
+.RS
+.PD 0
+.B add
+.PP
+.B dump
+.PP
+.B dumpavail
+.PP
+.B showpkg
+.PP
+.B stats
+.RE
+.PD 1
+.PP
+.I cache
+must be a package cache file (for instance,
+.IR /var/cache/apt/pkgcache.bin ).
+Some
+.IR command s
+require additional arguments.
+.SS add
+.B add
+adds a new set of package records to
+.IR cache .
+Remaining arguments are of the form
+.IR file : dist : ver ,
+where
+.I file
+is the full path to file in question.
+.I dist
+and
+.I ver
+can be any string and are not yet implemented.
+.SS dump
+.B dump
+displays information about all the packages in the cache. See
+.B showpkg
+below for an explanation of what data is output for each package.
+.SS dumpavail
+.B dumpavail
+generates an
+.I available
+file suitable for use with
+.BR dpkg (8)
+based on the information in the cache.
+.SS showpkg
+.B showpkg
+displays information about the packages listed on the command line.
+Remaining arguments are package names. The available versions and
+reverse dependencies of each package listed are listed, as well as
+forward dependencies for each version. Forward (normal) dependencies
+are those packages upon which the package in question depends; reverse
+dependencies are those packages that depend upon the package in
+question. Thus, forward dependencies must be satisfied for a package,
+but reverse dependencies need not be.
+For instance,
+.B apt-cache showpkg
+.I cache
+.B libreadline2
+would produce output similar to the following:
+.PP
+.RS
+.PD 0
+Package: libreadline2
+.PP
+Versions: 2.1-8,2.1-7,
+.PP
+Reverse Depends:
+.RS
+.PP
+libreadlineg2,libreadline2
+.PP
+libreadlineg2,libreadline2
+.PP
+libreadline2-altdev,libreadline2
+.RE
+.PP
+Dependencies:
+.PP
+2.1-8 - libc5 ncurses3.0 ldso
+.PP
+2.1-7 - ldso libc5 ncurses3.0
+.RE
+.PD 1
+.PP
+Thus it may be seen that libreadline2, version 2.1-8, depends on libc5,
+ncurses3.0, and ldso, which must be installed for libreadline2 to work. In
+turn, libreadlineg2 and libreadline2-altdev depend on libreadline2. If
+libreadline2 is installed, libc5, ncurses3.0, and ldso must also be
+installed; libreadlineg2 and libreadline2-altdev do not have to be
+installed.
+.SS stats
+.B stats
+displays some statistics about
+.IR cache .
+No further arguments are expected. Statistics reported are:
+.RS
+.TP
+.I Total package names
+is the number of package names found in the cache.
+.TP
+.I Normal packages
+is the number of regular, ordinary package names; these
+are packages that bear a one-to-one correspondence between their names and
+the names used by other packages for them in dependencies. The majority of
+packages fall into this category.
+.TP
+.I Pure virtual packages
+is the number of packages that exist only as a virtual package name; that
+is, packages only "provide" the virtual package name, and no package
+actually uses the name. For instance, "mail-transport-agent" in the Debian
+GNU/Linux system is a pure virtual package; several packages provide
+"mail-transport-agent", but there is no package named "mail-transport-agent".
+.TP
+.I Single virtual packages
+is the number of packages with only one package providing a particular
+virtual package. For instance, in the Debian GNU/Linux system,
+"X11-text-viewer" is a virtual package, but only one package, xless,
+provides "X11-text-viewer".
+.TP
+.I Mixed virtual packages
+is the number of packages that either provide a particular virtual package
+or have the virtual package name as the package name. For instance, in the
+Debian GNU/Linux system, e2fsprogs is both an actual package, and
+provided by the e2compr package.
+.TP
+.I Missing
+is the number of package names that were referenced in a dependency but
+were not provided by any package. Missing packages may be in evidence
+if a full distribution is not accesssed, or if a package (real or virtual)
+has been dropped from the distribution.
+.TP
+.I Total distinct versions
+is the number of package versions found in the cache; this value is
+therefore at least equal to the number of total package names. If more than
+one distribution (both "stable" and "unstable", for instance), is being
+accessed, this value can be considerably larger than the number of total
+package names.
+.TP
+.I Total dependencies
+is the number of dependency relationships claimed by all of the packages in
+the cache.
+.RE
+.SH OPTIONS
+None.
+.SH FILES
+None.
+.SH SEE ALSO
+.BR apt (8),
+.BR apt-get (8),
+.I /usr/doc/apt/cache*
+.SH DIAGNOSTICS
+apt-cache returns zero on normal operation, decimal 100 on error.
+.SH BUGS
+See <http://www.debian.org/Bugs/db/pa/lapt.html>. If you wish to report a
+bug in
+.BR apt-cache ,
+please see
+.I /usr/doc/debian/bug-reporting.txt
+or the
+.BR bug (1)
+command.
+.SH AUTHOR
+apt-cache was written by the APT team <apt@packages.debian.org>.
diff --git a/doc/apt-get.8 b/doc/apt-get.8
new file mode 100644
index 000000000..c53dc70d7
--- /dev/null
+++ b/doc/apt-get.8
@@ -0,0 +1,250 @@
+.\" $Id: apt-get.8,v 1.1 1998/07/02 02:58:12 jgg Exp $
+.\" This manpage is copyright (C) 1998 Branden Robinson <branden@debian.org>.
+.\"
+.\" This is free software; you may redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2,
+.\" or (at your option) any later version.
+.\"
+.\" This is distributed in the hope that it will be useful, but
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with APT; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+.\" 02111-1307 USA
+.TH apt-get 8 "16 June 1998" "Debian GNU/Linux"
+.SH NAME
+apt-get \- APT package handling utility \(em command-line interface
+.SH SYNOPSIS
+.B apt-get
+.RI [ options ]
+.RI [ command ]
+.RI [ package
+.IR ... ]
+.SH DESCRIPTION
+.B apt-get
+is the command-line tool for handling packages, and may be considered the
+user's "back-end" to
+.BR apt (8).
+Use
+.BR apt (8)
+if the usage of apt-get does not seem intuitive.
+.PP
+.I command
+is one of
+.RS
+.PD 0
+.B update
+.PP
+.B upgrade
+.PP
+.B dselect-upgrade
+.PP
+.B dist-upgrade
+.PP
+.B install
+.PP
+.B check
+.PP
+.B clean
+.RE
+.PD 1
+.PP
+Unless one of the
+.IR -h ,
+.IR --help ,
+.IR -f ,
+or
+.I --fix-broken
+options is given, one of the above commands must be present. Only the
+.B install
+command requires any further arguments.
+.SS update
+.B update
+is used to resynchronize the package overview files from their
+sources. The overviews of available packages are fetched from the
+location(s) specified in
+.IR /etc/apt/sources.list .
+For example, when using a Debian archive, this command retrieves and
+scans the
+.I Packages.gz
+files, so that information about new and updated packages is available. An
+.B update
+should always be performed before an
+.B upgrade
+or
+.BR dist-upgrade .
+.SS upgrade
+.B upgrade
+is used to install the newest versions of all packages currently installed
+on the system from the sources enumerated in
+.IR /etc/apt/sources.list .
+Packages currently installed with new versions available are retrieved
+and upgraded; under no circumstances are currently installed packages
+removed, or packages not already installed retrieved and installed. New
+versions of currently installed packages that cannot be upgraded without
+changing the install status of another package will be left at their
+current version. An
+.B update
+must be performed first so that
+.B apt-get
+knows that new versions of packages are available.
+.SS dselect-upgrade
+.B dselect-upgrade
+is used in conjunction with the traditional Debian GNU/Linux packaging
+front-end,
+.BR dselect (8). " dselect-upgrade"
+follows the changes made by
+.B dselect
+to the
+.I Status
+field of available packages, and performs the actions necessary to realize
+that state (for instance, the removal of old and the installation of new
+packages).
+.B dselect-upgrade
+does not attempt to intelligently address dependency issues as
+.B dist-upgrade
+or
+.B install
+do. If any dependency problems arise,
+.B apt-get
+aborts without performing any of the actions requested, even those
+without problems.
+.B dselect-upgrade
+is only useful to users of
+.B dselect
+and the
+.I .deb
+package file format. The
+.I /etc/apt/sources.list
+file contains a list of locations from which to retrieve desired package
+files.
+.SS dist-upgrade
+.BR dist-upgrade ,
+in addition to performing the function of
+.BR upgrade ,
+also intelligently handles changing dependencies with new versions of
+packages;
+.B apt-get
+has a "smart" conflict resolution system, and it will attempt to upgrade
+the most important packages at the expense of less important ones if
+necessary. The
+.I /etc/apt/sources.list
+file contains a list of locations from which to retrieve desired package
+files.
+.SS install
+.B install
+is followed by one or more
+.I packages
+desired for installation. Each
+.I package
+is a package name, not a fully qualified filename (for instance, in a
+Debian GNU/Linux system,
+.I lsdo
+would be the argument provided, not
+.IR ldso_1.9.6-2.deb ).
+All packages required by the package(s) specified for installation will
+also be retrieved and installed. The
+.I /etc/apt/sources.list
+file is used to locate the desired packages. If a hyphen is appended to
+the package name (with no intervening space), the identified package will
+be removed if it is installed. This latter feature may be used to override
+decisions made by apt-get's conflict resolution system.
+.SS check
+.B check
+is a diagnostic tool; it updates the package cache and checks for broken
+packages.
+.SS clean
+.B clean
+clears out the local repository of retrieved package files. It removes
+everything but the lock file from
+.I /var/cache/apt/archives/
+and
+.IR /var/cache/apt/archives/partial/ .
+When APT is used as a
+.BR dselect (8)
+method,
+.B
+clean
+is run automatically. Those who do not use dselect will likely want to
+run
+.B
+apt-get clean
+from time to time to free up disk space.
+.SH OPTIONS
+.TP
+.IR \-d , " --download-only"
+Download only; package files are only retrieved, not unpacked or installed.
+.TP
+.IR \-f , " --fix-broken"
+Fix; attempt to correct a system with broken dependencies in
+place. This option may be used alone or in conjunction with any of the
+command actions, and is sometimes necessary when running APT for the
+first time; APT itself does not allow broken package dependencies to
+exist on a system. It is possible that a system's dependency structure
+can be so corrupt as to require manual intervention (which usually
+means using dselect or dpkg --remove to eliminate some of the offending
+packages). Use of this option together with -m is discouraged.
+.TP
+.IR \-h , " --help"
+Help; display a helpful usage message and exit.
+.TP
+.IR \-m , " --ignore-missing"
+Ignore missing packages; If packages cannot be retrieved or fail the
+integrity check after retrieval (corrupted package files), hold back
+those packages and handle the result. Use of this option together with
+-f is discouraged.
+.TP
+.IR \-q , " --silent"
+Quiet; produces output suitable for logging, omitting progress indicators.
+.TP
+.I \-qq
+Very quiet; no output except for errors.
+.TP
+.IR \-s , " --simulate" , " --just-print" , " --dry-run" , " --recon " , " --no-act"
+No action; perform a simulation of events that would occur but do not
+actually change the system.
+.TP
+.IR \-y , " --yes" , " --assume-yes"
+Automatic yes to prompts; assume "yes" as answer to all prompts and run
+non-interactively.
+.SH FILES
+.TP
+.I /etc/apt/sources.list
+see
+.BR sources.list (5)
+.TP
+.I /var/cache/apt/archives/
+storage area for retrieved package files
+.TP
+.I /var/cache/apt/archives/partial/
+storage area for package files in transit
+.TP
+.I /var/state/apt/lists/
+storage area for state information for each package resource specified in
+.I /etc/apt/sources.list
+.TP
+.I /var/state/apt/lists/partial/
+storage area for state information in transit
+.SH SEE ALSO
+.BR apt (8),
+.BR apt-cache (8),
+.BR dpkg (8),
+.BR dselect (8),
+.BR sources.list (5)
+.SH DIAGNOSTICS
+apt-get returns zero on normal operation, decimal 100 on error.
+.SH BUGS
+See <http://www.debian.org/Bugs/db/pa/lapt.html>. If you wish to report a
+bug in
+.BR apt-get ,
+please see
+.I /usr/doc/debian/bug-reporting.txt
+or the
+.BR bug (1)
+command.
+.SH AUTHOR
+apt-get was written by the APT team <apt@packages.debian.org>.
diff --git a/doc/apt.8 b/doc/apt.8
new file mode 100644
index 000000000..08aa2c4fd
--- /dev/null
+++ b/doc/apt.8
@@ -0,0 +1,50 @@
+.\" This manpage is copyright (C) 1998 Branden Robinson <branden@debian.org>.
+.\"
+.\" This is free software; you may redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2,
+.\" or (at your option) any later version.
+.\"
+.\" This is distributed in the hope that it will be useful, but
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with APT; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+.\" 02111-1307 USA
+.TH apt 8 "16 June 1998" "Debian GNU/Linux"
+.SH NAME
+apt \- Advanced Package Tool
+.SH SYNOPSIS
+.B apt
+.SH DESCRIPTION
+APT is a management system for software packages. It is still
+under development; the snazzy front ends are not yet available. In the
+meantime, please see
+.BR apt-get (8).
+.SH OPTIONS
+None.
+.SH FILES
+None.
+.SH SEE ALSO
+.BR apt-cache (8),
+.BR apt-get (8),
+.BR ftp.conf (5),
+.BR sources.list (5)
+.SH DIAGNOSTICS
+apt returns zero on normal operation, decimal 100 on error.
+.SH BUGS
+This manpage isn't even started.
+.PP
+See <http://www.debian.org/Bugs/db/pa/lapt.html>. If you wish to report a
+bug in
+.BR apt ,
+please see
+.I /usr/doc/debian/bug-reporting.txt
+or the
+.BR bug (1)
+command.
+.SH AUTHOR
+apt was written by the APT team <apt@packages.debian.org>.
diff --git a/doc/cache.sgml b/doc/cache.sgml
new file mode 100644
index 000000000..43f8d4fff
--- /dev/null
+++ b/doc/cache.sgml
@@ -0,0 +1,761 @@
+<!doctype debiandoc system>
+<!-- -*- mode: sgml; mode: fold -*- -->
+<book>
+<title>APT Cache File Format</title>
+
+<author>Jason Gunthorpe <email>jgg@debian.org</email></author>
+<version>$Id: cache.sgml,v 1.1 1998/07/02 02:58:12 jgg Exp $</version>
+
+<abstract>
+This document describes the complete implementation and format of the APT
+Cache file. The APT Cache file is a way for APT to parse and store a
+large number of package files for display in the UI. It's primary design
+goal is to make display of a single package in the tree very fast by
+pre-linking important things like dependencies and provides.
+
+The specification doubles as documentation for one of the in-memory
+structures used by the package library and the APT GUI.
+
+</abstract>
+
+<copyright>
+Copyright &copy; Jason Gunthorpe, 1997.
+<p>
+APT and this document are free software; you can redistribute them and/or
+modify them under the terms of the GNU General Public License as published
+by the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+<p>
+For more details, on Debian GNU/Linux systems, see the file
+/usr/doc/copyright/GPL for the full license.
+</copyright>
+
+<toc sect>
+
+<chapt>Introduction
+<!-- Purpose {{{ -->
+<!-- ===================================================================== -->
+<sect>Purpose
+
+<p>
+This document describes the implementation of an architecture
+dependent binary cache file. The goal of this cache file is two fold,
+firstly to speed loading and processing of the package file array and
+secondly to reduce memory consumption of the package file array.
+
+<p>
+The implementation is aimed at an environment with many primary package
+files, for instance someone that has a Package file for their CD-ROM, a
+Package file for the latest version of the distribution on the CD-ROM and a
+package file for the development version. Always present is the information
+contained in the status file which might be considered a separate package
+file.
+
+<p>
+Please understand, this is designed as a -CACHE FILE- it is not ment to be
+used on any system other than the one it was created for. It is not ment to
+be authoritative either, ie if a system crash or software failure occures it
+must be perfectly acceptable for the cache file to be in an inconsistant
+state. Furthermore at any time the cache file may be erased without losing
+any information.
+
+<p>
+Also the structures and storage layout is optimized for use by the APT
+GUI and may not be suitable for all purposes. However it should be possible
+to extend it with associate cache files that contain other information.
+
+<p>
+To keep memory use down the cache file only contains often used fields and
+fields that are inexepensive to store, the Package file has a full list of
+fields. Also the client may assume that all items are perfectly valid and
+need not perform checks against their correctness. Removal of information
+from the cache is possible, but blanks will be left in the file, and
+unused strings will also be present. The recommended implementation is to
+simply rebuild the cache each time any of the data files change. It is
+possible to add a new package file to the cache without any negative side
+effects.
+
+<sect1>Note on Pointer access
+<p>
+Every item in every structure is stored as the index to that structure.
+What this means is that once the files is mmaped every data access has to
+go through a fixup stage to get a real memory pointer. This is done
+by taking the tndex, multiplying it by the type size and then adding
+it to the start address of the memory block. This sounds complex, but
+in C it is a single array dereference. Because all items are aligned to
+their size and indexs are stored as multiples of the size of the structure
+the format is immediately portable to all possible architectures - BUT the
+generated files are -NOT-.
+
+<p>
+This scheme allows code like this to be written:
+<example>
+ void *Map = mmap(...);
+ Package *PkgList = (Package *)Map;
+ Header *Head = (Header *)Map;
+ char *Strings = (char *)Map;
+ cout << (Strings + PkgList[Head->HashTable[0]]->Name) << endl;
+</example>
+<p>
+Notice the lack of casting or multiplication. The net result is to return
+the name of the first package in the first hash bucket, without error
+checks.
+
+<p>
+The generator uses allocation pools to group similarly sized structures in
+large blocks to eliminate any alignment overhead. The generator also
+assures that no structures overlap and all indexes are unique. Although
+at first glance it may seem like there is the potential for two structures
+to exist at the same point the generator never allows this to happen.
+(See the discussion of free space pools)
+ <!-- }}} -->
+
+<chapt>Structures
+<!-- Header {{{ -->
+<!-- ===================================================================== -->
+<sect>Header
+<p>
+This is the first item in the file.
+<example>
+ struct Header
+ {
+ // Signature information
+ unsigned long Signature;
+ short MajorVersion;
+ short MinorVersion;
+ bool Dirty;
+
+ // Size of structure values
+ unsigned short HeaderSz;
+ unsigned short PackageSz;
+ unsigned short PackageFileSz;
+ unsigned short VersionSz;
+ unsigned short DependencySz;
+ unsigned short ProvidesSz;
+
+ // Structure counts
+ unsigned long PackageCount;
+ unsigned long VersionCount;
+ unsigned long DependsCount;
+ unsigned long PackageFileCount;
+
+ // Offsets
+ unsigned long FileList; // PackageFile
+ unsigned long StringList; // StringItem
+
+ // Pool structures
+ unsigned long PoolStart[6];
+ unsigned long PoolSize[6];
+ unsigned long PoolAln[6];
+
+ // Package name lookup
+ unsigned long HashTable[512]; // Package
+ };
+</example>
+<taglist>
+<tag>Signature<item>
+This must contain the hex value 0x98FE76DC which is designed to verify
+that the system loading the image has the same byte order and byte size as
+the system saving the image
+
+<tag>MajorVersion
+<tag>MinorVersion<item>
+These contain the version of the cache file, currently 0.2.
+
+<tag>Dirty<item>
+Dirty is true if the cache file was opened for reading, the client expects
+to have written things to it and have not fully synced it. The file should
+be erased and rebuilt if it is true.
+
+<tag>HeaderSz
+<tag>PackageSz
+<tag>PackageFileSz
+<tag>VersionSz
+<tag>DependencySz
+<tag>ProvidesSz<item>
+*Sz contains the sizeof() that particular structure. It is used as an
+extra consistancy check on the structure of the file.
+
+If any of the size values do not exactly match what the client expects then
+the client should refuse the load the file.
+
+<tag>PackageCount
+<tag>VersionCount
+<tag>DependsCount
+<tag>PackageFileCount<item>
+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>FileList<item>
+This contains the index of the first PackageFile structure. The PackageFile
+structures are singely linked lists that represent all package files that
+have been merged into the cache.
+
+<tag>StringList<item>
+This contains a list of all the unique strings (string item type strings) in
+the cache. The parser reads this list into memory so it can match strings
+against it.
+
+<tag>PoolStart
+<tag>PoolSize
+<tag>PoolAln<item>
+The Pool structures manage the allocation pools that the generator uses.
+Start indicates the first byte of the pool, Size is the number of bytes
+remaining in the pool and Aln (alignment) is the structure size of the pool.
+An Aln of 0 indicates the slot is empty. There should be the same number of
+slots as there are structure types. The generator stores this information
+so future additions can make use of any unused pool blocks.
+
+<tag>HashTable<item>
+HashTable is a hash table that provides indexing for all of the packages.
+Each package name is inserted into the hash table using the following has
+function:
+<example>
+ unsigned long Hash(string Str)
+ {
+ unsigned long Hash = 0;
+ for (const char *I = Str.begin(); I != Str.end(); I++)
+ Hash += *I * ((Str.end() - I + 1));
+ return Hash % _count(Head.HashTable);
+ }
+</example>
+<p>
+By iterating over each entry in the hash table it is possible to iterate over
+the entire list of packages. Hash Collisions are handled with a singely linked
+list of packages based at the hash item. The linked list contains only
+packages that macth the hashing function.
+
+</taglist>
+ <!-- }}} -->
+<!-- Package {{{ -->
+<!-- ===================================================================== -->
+<sect>Package
+<p>
+This contians information for a single unique package. There can be any
+number of versions of a given package. Package exists in a singly
+linked list of package records starting at the hash index of the name in
+the Header->HashTable.
+<example>
+ struct Pacakge
+ {
+ // Pointers
+ unsigned long Name; // Stringtable
+ unsigned long VersionList; // Version
+ unsigned long TargetVer; // Version
+ unsigned long CurrentVer; // Version
+ unsigned long TargetDist; // StringTable (StringItem)
+ unsigned long Section; // StringTable (StringItem)
+
+ // Linked lists
+ unsigned long NextPackage; // Package
+ unsigned long RevDepends; // Dependency
+ unsigned long ProvidesList; // Provides
+
+ // Install/Remove/Purge etc
+ unsigned char SelectedState; // What
+ unsigned char InstState; // Flags
+ unsigned char CurrentState; // State
+
+ // Unique ID for this pkg
+ unsigned short ID;
+ unsigned short Flags;
+ };
+</example>
+
+<taglist>
+<tag>Name<item>
+Name of the package.
+
+<tag>VersionList<item>
+Base of a singely linked list of version structures. Each structure
+represents a unique version of the package. The version structures
+contain links into PackageFile and the original text file as well as
+detailed infromation about the size and dependencies of the specific
+package. In this way multiple versions of a package can be cleanly handled
+by the system. Furthermore, this linked list is guarenteed to be sorted
+from Highest version to lowest version with no duplicate entries.
+
+<tag>TargetVer
+<tag>CurrentVer<item>
+This is an index (pointer) to the sub version that is being targeted for
+upgrading. CurrentVer is an index to the installed version, either can be
+0.
+
+<tag>TargetDist<item>
+This indicates the target distribution. Automatic upgrades should not go
+outside of the specified dist. If it is 0 then the global target dist should
+be used. The string should be contained in the StringItem list.
+
+<tag>Section<item>
+This indicates the deduced section. It should be "Unknown" or the section
+of the last parsed item.
+
+<tag>NextPackage<item>
+Next link in this hash item. This linked list is based at Header.HashTable
+and contains only packages with the same hash value.
+
+<tag>RevDepends<item>
+Reverse Depends is a linked list of all dependencies linked to this package.
+
+<tag>ProvidesList<item>
+This is a linked list of all provides for this package name.
+
+<tag>SelectedState
+<tag>InstState
+<tag>CurrentState<item>
+These corrispond to the 3 items in the Status field found in the status
+file. See the section on defines for the possible values.
+<p>
+SelectedState is the state that the user wishes the package to be
+in.
+<p>
+InstState is the installation state of the package. This normally
+should be Ok, but if the installation had an accident it may be otherwise.
+<p>
+CurrentState indicates if the package is installed, partially installed or
+not installed.
+
+<tag>ID<item>
+ID is a value from 0 to Header->PackageCount. It is a unique value assigned
+by the generator. This allows clients to create an array of size PackageCount
+and use it to store state information for the package map. For instance the
+status file emitter uses this to track which packages have been emitted
+already.
+
+<tag>Flags<item>
+Flags are some usefull indicators of the package's state.
+
+</taglist>
+
+ <!-- }}} -->
+<!-- PackageFile {{{ -->
+<!-- ===================================================================== -->
+<sect>PackageFile
+<p>
+This contians information for a single package file. Package files are
+referenced by Version structures. This is a singly linked list based from
+Header.FileList
+<example>
+ struct PackageFile
+ {
+ // Names
+ unsigned long FileName; // Stringtable
+ unsigned long Version; // Stringtable
+ unsigned long Distribution; // Stringtable
+ unsigned long Size;
+
+ // Linked list
+ unsigned long NextFile; // PackageFile
+ unsigned short ID;
+ unsigned short Flags;
+ time_t mtime; // Modification time
+ };
+</example>
+<taglist>
+
+<tag>FileName<item>
+Refers the the physical disk file that this PacakgeFile represents.
+
+<tag>Version<item>
+Version is the given version, ie 1.3.1, 2.4_revision_1 etc.
+
+<tag>Distribution<item>
+Distribution is the symbolic name for this PackageFile, hamm,bo,rexx etc
+
+<tag>Size<item>
+Size is provided as a simple check to ensure that the package file has not
+been altered.
+
+<tag>ID<item>
+See Package::ID.
+
+<tag>Flags<item>
+Provides some flags for the PackageFile, see the section on defines.
+
+<tag>mtime<item>
+Modification time for the file at time of cache generation.
+
+</taglist>
+
+ <!-- }}} -->
+<!-- Version {{{ -->
+<!-- ===================================================================== -->
+<sect>Version
+<p>
+This contians the information for a single version of a package. This is a
+singley linked list based from Package.Versionlist.
+
+<p>
+The version list is always sorted from highest version to lowest version by
+the generator. Also there may not be any duplicate entries in the list (same
+VerStr).
+
+<example>
+ struct Version
+ {
+ unsigned long VerStr; // Stringtable
+ unsigned long File; // PackageFile
+ unsigned long Section; // StringTable (StringItem)
+
+ // Lists
+ unsigned long NextVer; // Version
+ unsigned long DependsList; // Dependency
+ unsigned long ParentPkg; // Package
+ unsigned long ProvidesList; // Provides
+
+ unsigned long Offset;
+ unsigned long Size;
+ unsigned long InstalledSize;
+ unsigned short ID;
+ unsigned char Priority;
+ };
+</example>
+<taglist>
+
+<tag>VerStr<item>
+This is the complete version string.
+
+<tag>File<item>
+References the PackageFile that this version came out of. File can be used
+to determine what distribution the Version applies to. If File is 0 then
+this is a blank version. The structure should also have a 0 in all other
+fields excluding VerStr and Possibly NextVer.
+
+<tag>Section<item>
+This string indicates which section it is part of. The string should be
+contained in the StringItem list.
+
+<tag>NextVer<item>
+Next step in the linked list.
+
+<tag>DependsList<item>
+This is the base of the dependency list.
+
+<tag>ParentPkg<item>
+This links the version to the owning package, allowing reverse dependencies
+to determine the package.
+
+<tag>ProvidesList<item>
+Head of the linked list of Provides::NextPkgProv, forward provides.
+
+<tag>Offset<item>
+The byte offset of the first line of this item in the specified
+PackageFile
+
+<tag>Size
+<tag>InstalledSize<item>
+The archive size for this version. For debian this is the size of the .deb
+file. Installed size is the uncompressed size for this version
+
+<tag>ID<item>
+See Package::ID.
+
+<tag>Priority<item>
+This is the parsed priority value of the package.
+</taglist>
+
+ <!-- }}} -->
+<!-- Dependency {{{ -->
+<!-- ===================================================================== -->
+<sect>Dependency
+<p>
+Dependency contains the information for a single dependency record. The records
+are split up like this to ease processing by the client. The base of list
+linked list is Version.DependsList. All forms of dependencies are recorded
+here including Conflicts, Suggests and Recommends.
+
+<p>
+Multiple depends on the same package must be grouped together in
+the Dependency lists. Clients should assume this is always true.
+
+<example>
+ struct Dependency
+ {
+ unsigned long Version; // Stringtable
+ unsigned long Package; // Package
+ unsigned long NextDepends; // Dependency
+ unsigned long NextRevDepends; // Reverse dependency linking
+ unsigned long ParentVer; // Upwards parent version link
+
+ // Specific types of depends
+ unsigned char Type;
+ unsigned char CompareOp;
+ unsigned short ID;
+ };
+</example>
+<taglist>
+<tag>Version<item>
+The string form of the version that the dependency is applied against.
+
+<tag>Package<item>
+The index of the package file this depends applies to. If the package file
+does not already exist when the dependency is inserted a blank one (no
+version records) should be created.
+
+<tag>NextDepends<item>
+Linked list based off a Version structure of all the dependencies in that
+version.
+
+<tag>NextRevDepends<item>
+Reverse dependency linking, based off a Package structure. This linked list
+is a list of all packages that have a depends line for a given package.
+
+<tag>ParentVer<item>
+Parent version linking, allows the reverse dependency list to link
+back to the version and package that the dependency are for.
+
+<tag>Type<item>
+Describes weather it is depends, predepends, recommends, suggests, etc.
+
+<tag>CompareOp<item>
+Describes the comparison operator specified on the depends line. If the high
+bit is set then it is a logical or with the previous record.
+
+<tag>ID<item>
+See Package::ID.
+
+</taglist>
+
+ <!-- }}} -->
+<!-- Provides {{{ -->
+<!-- ===================================================================== -->
+<sect>Provides
+<p>
+Provides handles virtual packages. When a Provides: line is encountered
+a new provides record is added associating the package with a virtual
+package name. The provides structures are linked off the package structures.
+This simplifies the analysis of dependencies and other aspects A provides
+refers to a specific version of a specific package, not all versions need to
+provide that provides.
+
+<p>
+There is a linked list of provided package names started from each
+version that provides packages. This is the forwards provides mechanism.
+<example>
+ struct Provides
+ {
+ unsigned long ParentPkg; // Package
+ unsigned long Version; // Version
+ unsigned long ProvideVersion; // Stringtable
+ unsigned long NextProvides; // Provides
+ unsigned long NextPkgProv; // Provides
+ };
+</example>
+<taglist>
+<tag>ParentPkg<item>
+The index of the package that head of this linked list is in. ParentPkg->Name
+is the name of the provides.
+
+<tag>Version<item>
+The index of the version this provide line applies to.
+
+<tag>ProvideVersion<item>
+Each provides can specify a version in the provides line. This version allows
+dependencies to depend on specific versions of a Provides, as well as allowing
+Provides to override existing packages. This is experimental.
+
+<tag>NextProvides<item>
+Next link in the singly linked list of provides (based off package)
+
+<tag>NextPkgProv<item>
+Next link in the singly linked list of provides for 'Version'.
+
+</taglist>
+
+ <!-- }}} -->
+<!-- StringItem {{{ -->
+<!-- ===================================================================== -->
+<sect>StringItem
+<p>
+StringItem is used for generating single instances of strings. Some things
+like Section Name are are usefull to have as unique tags. It is part of
+a linked list based at Header::StringList.
+<example>
+ struct StringItem
+ {
+ unsigned long String; // Stringtable
+ unsigned long NextItem; // StringItem
+ };
+</example>
+<taglist>
+<tag>String<item>
+The string this refers to.
+
+<tag>NextItem<item>
+Next link in the chain.
+</taglist>
+ <!-- }}} -->
+<!-- StringTable {{{ -->
+<!-- ===================================================================== -->
+<sect>StringTable
+<p>
+All strings are simply inlined any place in the file that is natural for the
+writer. The client should make no assumptions about the positioning of
+strings. All stringtable values point to a byte offset from the start of the
+file that a null terminated string will begin.
+ <!-- }}} -->
+<!-- Defines {{{ -->
+<!-- ===================================================================== -->
+<sect>Defines
+<p>
+Several structures use variables to indicate things. Here is a list of all
+of them.
+
+<sect1>Definitions for Dependency::Type
+<p>
+<example>
+#define pkgDEP_Depends 1
+#define pkgDEP_PreDepends 2
+#define pkgDEP_Suggests 3
+#define pkgDEP_Recommends 4
+#define pkgDEP_Conflicts 5
+#define pkgDEP_Replaces 6
+</example>
+</sect1>
+
+<sect1>Definitions for Dependency::CompareOp
+<p>
+<example>
+#define pkgOP_OR 0x10
+#define pkgOP_LESSEQ 0x1
+#define pkgOP_GREATEREQ 0x2
+#define pkgOP_LESS 0x3
+#define pkgOP_GREATER 0x4
+#define pkgOP_EQUALS 0x5
+</example>
+The lower 4 bits are used to indicate what operator is being specified and
+the upper 4 bits are flags. pkgOP_OR indicates that the next package is
+or'd with the current package.
+</sect1>
+
+<sect1>Definitions for Package::SelectedState
+<p>
+<example>
+#define pkgSTATE_Unkown 0
+#define pkgSTATE_Install 1
+#define pkgSTATE_Hold 2
+#define pkgSTATE_DeInstall 3
+#define pkgSTATE_Purge 4
+</example>
+</sect1>
+
+<sect1>Definitions for Package::InstState
+<p>
+<example>
+#define pkgSTATE_Ok 0
+#define pkgSTATE_ReInstReq 1
+#define pkgSTATE_Hold 2
+#define pkgSTATE_HoldReInstReq 3
+</example>
+</sect1>
+
+<sect1>Definitions for Package::CurrentState
+<p>
+<example>
+#define pkgSTATE_NotInstalled 0
+#define pkgSTATE_UnPacked 1
+#define pkgSTATE_HalfConfigured 2
+#define pkgSTATE_UnInstalled 3
+#define pkgSTATE_HalfInstalled 4
+#define pkgSTATE_ConfigFiles 5
+#define pkgSTATE_Installed 6
+</example>
+</sect1>
+
+<sect1>Definitions for Package::Flags
+<p>
+<example>
+#define pkgFLAG_Auto (1 << 0)
+#define pkgFLAG_New (1 << 1)
+#define pkgFLAG_Obsolete (1 << 2)
+#define pkgFLAG_Essential (1 << 3)
+#define pkgFLAG_ImmediateConf (1 << 4)
+</example>
+</sect1>
+
+<sect1>Definitions for Version::Priority
+<p>
+Zero is used for unparsable or absent Priority fields.
+<example>
+#define pkgPRIO_Important 1
+#define pkgPRIO_Required 2
+#define pkgPRIO_Standard 3
+#define pkgPRIO_Optional 4
+#define pkgPRIO_Extra 5
+</example>
+</sect1>
+
+<sect1>Definitions for PackageFile::Flags
+<p>
+<example>
+#define pkgFLAG_NotSource (1 << 0)
+</example>
+</sect1>
+
+ <!-- }}} -->
+
+<chapt>Notes on the Generator
+<!-- Notes on the Generator {{{ -->
+<!-- ===================================================================== -->
+<p>
+The pkgCache::MergePackageFile function is currently the only generator of
+the cache file. It implements a conversion from the normal textual package
+file into the cache file.
+
+<p>
+The generator assumes any package declaration with a
+Status: line is a 'Status of the package' type of package declaration.
+A Package with a Target-Version field should also really have a status field.
+The processing of a Target-Version field can create a place-holder Version
+structure that is empty to refer to the specified version (See Version
+for info on what a empty Version looks like). The Target-Version syntax
+allows the specification of a specific version and a target distribution.
+
+<p>
+Different section names on different versions is supported, but I
+do not expect to use it. To simplify the GUI it will mearly use the section
+in the Package structure. This should be okay as I hope sections do not change
+much.
+
+<p>
+The generator goes through a number of post processing steps after producing
+a disk file. It sorts all of the version lists to be in descending order
+and then generates the reverse dependency lists for all of the packages.
+ID numbers and count values are also generated in the post processing step.
+
+<p>
+It is possible to extend many of the structures in the cache with extra data.
+This is done by using the ID member. ID will be a unique number from 0 to
+Header->??Count. For example
+<example>
+struct MyPkgData;
+MyPkgData *Data = new MyPkgData[Header->PackageCount];
+Data[Package->ID]->Item = 0;
+</example>
+This provides a one way reference between package structures and user data. To
+get a two way reference would require a member inside the MyPkgData structure.
+
+<p>
+The generators use of free space pools tend to make the package file quite
+large, and quite full of blank space. This could be fixed with sparse files.
+
+ <!-- }}} -->
+
+<chapt>Future Directions
+<!-- Future Directions {{{ -->
+<!-- ===================================================================== -->
+<p>
+Some good directions to take the cache file is into a cache directory that
+contains many associated caches that cache other important bits of
+information. (/var/cache/apt, FHS2)
+
+<p>
+Caching of the info/*.list is an excellent place to start, by generating all
+the list files into a tree structure and reverse linking them to the package
+structures in the main cache file major speed gains in dpkg might be achived.
+
+ <!-- }}} -->
+
+</book>
diff --git a/doc/design.sgml b/doc/design.sgml
new file mode 100644
index 000000000..55fd7e551
--- /dev/null
+++ b/doc/design.sgml
@@ -0,0 +1,411 @@
+<!doctype debiandoc system>
+<debiandoc>
+ <book>
+ <titlepag>
+ <title> The APT project design document</title>
+ <author>
+ <name>Manoj Srivastava</name>
+ <email>srivasta@debian.org</email>
+ </author>
+ <version>$Id: design.sgml,v 1.1 1998/07/02 02:58:12 jgg Exp $</version>
+ <abstract>
+ This document is an overview of the specifications and design
+ goals of the APT project. It also attempts to give a broad
+ description of the implementation as well.
+ </abstract>
+ <copyright>
+ <copyrightsummary>Copyright &copy;1997 Manoj Srivastava
+ </copyrightsummary>
+ <p>
+ APT, including this document, is free software; you may
+ redistribute it and/or modify it under the terms of the GNU
+ General Public License as published by the Free Software
+ Foundation; either version 2, or (at your option) any later
+ version.</p>
+ <p>
+ This is distributed in the hope that it will be useful, but
+ <em>without any warranty</em>; without even the implied
+ warranty of merchantability or fitness for a particular
+ purpose. See the GNU General Public License for more
+ details.</p>
+
+ <p>
+ You should have received a copy of the GNU General Public
+ License with your Debian GNU/Linux system, in
+ <tt>/usr/doc/copyright/GPL</tt>, or with the
+ <prgn/debiandoc-sgml/ source package as the file
+ <tt>COPYING</tt>. If not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ USA.</p>
+ </copyright>
+ </titlepag>
+ <chapt id="introduction">
+ <heading>Introduction</heading>
+ <p>APT is supposed to be a replacement for dselect, and not a
+ replacement for dpkg. However, since addition functionality
+ has been required for APT, and given the fact that this is
+ very closely related to dpkg, it is not unreasonable to expect
+ that additional functionality in the underlying dpkg would
+ also be requested.</p>
+
+ <p> Diety/dselect are the first introduction that people have to
+ Debian, and unfortunately this first impression contributes
+ greatly to the public perception of the distribution. It is
+ imperative that this be a showcase for Debian, rather than
+ frighten novices away (which has been an accusation often
+ levelled at the current system)</p>
+ </chapt>
+ <chapt>
+ <heading>Requirements</heading>
+ <p>
+ <enumlist compact="compact">
+ <item>
+ <p>
+ APT should be a replacement for dselect. Therefore it
+ should have all the functionality that dselect has
+ currently. This is the primary means of interaction
+ between the user and the package management system, and
+ it should be able to handle all tasks involved in
+ installing, upgrading, and routine management without
+ having the users take recourse to the underlying
+ management system.</p>
+ </item>
+ <item>
+ <p>
+ It should be easier to use and less confusing for novice
+ users. The primary stimulus for the creation of APT
+ was the perceived intractability, complexity, and
+ non-intuitive behavior of the existing user interface,
+ and as such, human factors must be a primary mandate of
+ APT.</p>
+ </item>
+ <item>
+ <p>
+ It should be able to group packages more flexibly, and
+ possibly allow operations based on a group. One should
+ be able to select, or deselect, a coherent group of
+ related packages simultaneously, allowing one to add,
+ remove, or upgrade functionality to a machine as one
+ step.
+ </p>
+ </item>
+ <item>
+ <p>
+ This would allow APT to handle <em>standard
+ installations</em>, namely, one could then install a
+ set of packages to enable a machine to fulfill specific
+ tasks. Define a few standard installations, and which
+ packages are included therein. The packages should be
+ internally consistent.</p>
+ </item>
+ <item>
+ <p>
+ Make use of a keywords field in package headers; provide
+ a standard list of keywords for people to use. This
+ could be the underpinning to allow the previous two
+ requirements to work (though the developers are not
+ constrained to implement the previous requirements using
+ keywords)
+ </p>
+ </item>
+ <item>
+ <p>
+ Use dependencies, conflicts, and reverse dependencies to
+ properly order packages for installation and
+ removal. This has been a complaint in the past that the
+ installation methods do not really understand
+ dependencies, causing the upgrade process to break, or
+ allowing the removal of packages that left the system in
+ an untenable state by breaking the dependencies on
+ packages that were dependent on the package being
+ removed. A special emhasis is placed on handling
+ pre-dependencies correctly; the target of a
+ predependency has to be fully configured before
+ attempting to install the pre-dependent package. Also,
+ <em>configure immediately</em> requests mentioned below
+ should be handled.</p>
+ </item>
+ <item>
+ <p>
+ Handle replacement of a package providing a virtual
+ package with another (for example, it has been very
+ difficult replacing <prgn>sendmail</prgn> with
+ <prgn>smail</prgn>, or vice versa), making sure that the
+ dependencies are still satisfied. </p>
+ </item>
+ <item>
+ <p>
+ Handle source lists for updates from multiple
+ sources. APT should also be able to handle diverse
+ methods of acquiring new packages; local filesystem,
+ mountable CD-ROM drives, FTP accesible repositories are
+ some of the methods that come to mind. Also, the source
+ lists can be separated into categories, such as main,
+ contrib, non-us, non-local, non-free, my-very-own,
+ etc. APT should be set up to retrive the Packages
+ files from these multiple source lists, as well as
+ retrieving the packages themselves. </p>
+ </item>
+ <item>
+ <p>
+ Handle base of source and acquire all Packages files
+ underneath. (possibly select based on architecture),
+ this should be a simple extension of the previous
+ requirement.</p>
+ </item>
+ <item>
+ <p>
+ Handle remote installation (to be implemented maybe in a
+ future version, it still needs to be designed). This
+ would ease the burden of maintaining multiple Debian
+ machines on a site. In the authors opinion this is a
+ killer difference for the distribution, though it may be
+ too hard a problem to be implemented with the initial
+ version of APT. However, some thought must be given to
+ this to enable APT to retain hooks for future
+ functionality, or at least to refrain from methods that
+ may preclude remote activity. It is desirable that
+ adding remote installation not require a redesign of
+ APT from the ground up.</p>
+ </item>
+ <item>
+ <p>
+ Be scalable. Dselect worked a lot better with 400
+ packages, but at last count the number of packages was
+ around twelve hundred and climbing. This also requires
+ APT to pay attention to the needs of small machines
+ which are low on memory (though this requirement shall
+ diminish as we move towards bigger machines, it would
+ still be nice if Debian worked on all old machines where
+ Linux itself would work).</p>
+ </item>
+ <item>
+ <p>
+ Handle install immediately requests. Some packages, like
+ watchdog, are required to be working for the stability
+ of the machine itself. There are others which may be
+ required for the correct functioning of a production
+ machine, or which are mission critical
+ applications. APT should, in these cases, upgrade the
+ packages with minimal downtime; allowing these packages
+ to be one of potentially hundreds of packages being
+ upgraded concurrently may not satisfy the requirements
+ of the package or the site. (Watchdog, for example, if
+ not restarted quickly, may cause the machine to reboot
+ in the midst of installation, which may cause havoc on
+ the machine)</p>
+ </item>
+ </enumlist>
+ </p>
+ </chapt>
+ <chapt>
+ <heading>Procedural description</heading>
+ <p><taglist>
+ <tag>Set Options</tag>
+ <item>
+ <p>
+ This process handles setting of user or
+ site options, and configuration of all aspects of
+ APT. It allows the user to set the location and order
+ of package sources, allowing them to set up source list
+ details, like ftp site locations, passwords,
+ etc. Display options may also be set.</p>
+ </item>
+ <tag>Updates</tag>
+ <item>
+ <p>
+ Build a list of available packages, using
+ source lists or a base location and trawling for
+ Packages files (needs to be aware of architecture). This
+ may involve finding and retrieving Packages files,
+ storing them locally for efficiency, and parsing the
+ data for later use. This would entail contacting various
+ underlying access modules (ftp, cdrom mounts, etc) Use a
+ backing store for speed. This may also require
+ downloading the actual package files locally for
+ speed.</p>
+ </item>
+ <tag>Local status</tag>
+ <item>
+ <p>
+ Build up a list of packages already
+ installed. This requires reading and writing the local??
+ status file. For remote installation, this should
+ probably use similar mechanisms as the Packages file
+ retrieval does. Use the backing store for speed. One
+ should consider multiple backing stores, one for each
+ machine.
+ </p>
+ </item>
+ <tag>Relationship determination</tag>
+ <item>
+ <p>
+ Determine forward and reverse dependencies. All known
+ dependency fields should be acted upon, since it is
+ fairly cheap to do so. Update the backing store with
+ this information.</p>
+ </item>
+ <tag>Selection</tag>
+ <item>
+ <p>
+ Present the data to the user. Look at Behan Webster's
+ documentation for the user interface procedures. (Note:
+ In the authors opinion deletions and reverse
+ dependencies should also be presented to the user, in a
+ strictly symmetric fashion; this may make it easier to
+ prevent a package being removed that breaks
+ dependencies)
+ </p>
+ </item>
+ <tag>Ordering of package installations and configuration </tag>
+ <item>
+ <p>
+ Build a list of events. Simple topological sorting gives
+ order of packages in dependency order. At certain points
+ in this ordering, predependencies/immediate configure
+ directives cause an break in normal ordering. We need to
+ insert the uninstall/purge directive in the stream
+ (default: as early as possible).</p>
+ </item>
+ <tag>Action</tag>
+ <item>
+ <p>
+ Take the order of installations and removals and build
+ up a stream of events to send to the packaging system
+ (dpkg). Execute the list of events if succesful. Do not
+ partially install packages and leave system in broken
+ state. Go to The Selection step as needed.</p>
+ </item>
+
+ </taglist>
+ </p>
+ </chapt>
+ <chapt>
+ <heading>Modules and interfaces</heading>
+ <p><taglist>
+ <tag>The user interface module</tag>
+ <item>
+ <p> Look at Behan Webster's documentation.</p>
+ </item>
+ <tag>Widget set</tag>
+ <item>
+ <p>
+ Related closely to above Could some one present design
+ decisions of the widget set here?</p>
+ </item>
+ <tag>pdate Module</tag>
+ <item>
+ <p>
+ Distinct versions of the same package are recorded
+ separately, but if multiple Packages files contain the
+ same version of a package, then only the forst one is
+ recorded. For this reason, the least expensive update
+ source should be listed first (local file system is
+ better than a remote ftp site)</p>
+ <p>
+ This module should interact with the user interface
+ module to set and change configuration parameters for
+ the modules listed below. It needs to record that
+ information in an on disk data file, to be read on
+ future invocations. </p>
+ <p><enumlist>
+ <item>
+ <p>FTP methods</p>
+ </item>
+ <item>
+ <p>mount and file traversal module(s)?</p>
+ </item>
+ <item>
+ <p>Other methods ???</p>
+ </item>
+ </enumlist>
+ </p>
+ </item>
+ <tag>Status file parser/generator</tag>
+ <item>
+ <p>
+ The status file records the current state of the system,
+ listing the packages installed, etc. The status file is
+ also one method of communicating with dpkg, since it is
+ perfectly permissible for the user to use APT to
+ request packages be updated, put others on hold, mark
+ other for removal, etc, and then run <tt>dpkg
+ -BORGiE</tt> on a file system.</p>
+ </item>
+ <tag>Package file parser/generator</tag>
+ <item>
+ <p>
+ Related to above. Handle multiple Packages files, from
+ different sources. Each package contains a link back to
+ the packages file structure that contains details about
+ the origin of the data. </p>
+ </item>
+ <tag>Dependency module</tag>
+ <item>
+ <p><list>
+ <item>
+ <p>dependency/conflict determination and linking</p>
+ </item>
+ <item>
+ <p>reverse dependency generator. Maybe merged with above</p>
+ </item>
+ </list>
+ </p>
+ </item>
+ <tag>Package ordering Module</tag>
+ <item>
+ <p>Create an ordering of the actions to be taken.</p>
+ </item>
+ <tag>Event genrator</tag>
+ <item>
+ <p>module to interact with dpkg</p>
+ </item>
+ </taglist>
+ </chapt>
+ <chapt>
+ <heading>Data flow and conversions analysis.</heading>
+ <p>
+ <example>
+ ____________
+ __\|ftp modules|
+ / /|___________|
+ _ ____________ / ________________
+ | update | / |mount/local file|
+ |==========================>| module |/_____\| traversals |
+ | |_____________| /|________________|
+ | ^ ^
+ | | | ______________
+ ______|_______ _ _____ ______ | _____v________ \| |
+ |Configuration | |configuration| | |Packages Files| ===|Status file |
+ | module |<=>| data | | |______________| / /|____________|
+ |______________| |_____________| | ^ /
+ ^ | | /
+ | | _______v_______|/_
+ | | | | ________________
+ | | | |/_\| Dependency |
+ | | |backing store |\ /| Module |
+ | | |______________| _|_______________|
+ | \ ^ /| ^
+ | \ | / |
+ | _\|____v_______|/__ ____v_______
+ |_____________________________\| User interaction| | dpkg |
+ /|_________________|<==>| Invoker |
+ |___________|
+
+ </example>
+ <p> dpkg also interacts with status and available files.</p>
+
+
+ <p>
+ The backing store and the associated data structures are the
+ core of APT. All modules essentially revolve around the
+ backing store, feeding it data, adding and manipulating links
+ and relationships between data in the backing store, allowing
+ the user to interact with and modify the data in the backing
+ store, and finally writing it out as the status file and
+ possibly issuing directives to dpkg.</p>
+
+ <p>The other focal point for APT is the user interface.</p>
+ </chapt>
+ </book>
+</debiandoc>
diff --git a/doc/dpkg-tech.sgml b/doc/dpkg-tech.sgml
new file mode 100644
index 000000000..3c01ee8f0
--- /dev/null
+++ b/doc/dpkg-tech.sgml
@@ -0,0 +1,509 @@
+<!doctype debiandoc system>
+<book>
+<title>dpkg technical manual</title>
+
+<author>Tom Lees <email>tom@lpsg.demon.co.uk</email></author>
+<version>$Id: dpkg-tech.sgml,v 1.1 1998/07/02 02:58:12 jgg Exp $</version>
+
+<abstract>
+This document describes the minimum necessary workings for the APT dselect
+replacement. It gives an overall specification of what its external interface
+must look like for compatibility, and also gives details of some internal
+quirks.
+</abstract>
+
+<copyright>
+Copyright &copy; Tom Lees, 1997.
+<p>
+APT and this document are free software; you can redistribute them and/or
+modify them under the terms of the GNU General Public License as published
+by the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+<p>
+For more details, on Debian GNU/Linux systems, see the file
+/usr/doc/copyright/GPL for the full license.
+</copyright>
+
+<toc sect>
+
+<chapt>Quick summary of dpkg's external interface
+<sect id="control">Control files
+
+<p>
+The basic dpkg package control file supports the following major features:-
+
+<list>
+<item>5 types of dependencies:-
+ <list>
+ <item>Pre-Depends, which must be satisfied before a package may be
+ unpacked
+ <item>Depends, which must be satisfied before a package may be
+ configured
+ <item>Recommends, to specify a package which if not installed may
+ severely limit the usefulness of the package
+ <item>Suggests, to specify a package which may increase the
+ productivity of the package
+ <item>Conflicts, to specify a package which must NOT be installed
+ in order for the package to be configured
+ </list>
+Each of these dependencies can specify a version and a depedency on that
+version, for example "<= 0.5-1", "== 2.7.2-1", etc. The comparators available
+are:-
+ <list>
+ <item>"&lt;&lt;" - less than
+ <item>"&lt;=" - less than or equal to
+ <item>"&gt;&gt;" - greater than
+ <item>"&gt;=" - greater than or equal to
+ <item>"==" - equal to
+ </list>
+<item>The concept of "virtual packages", which many other packages may provide,
+using the Provides mechanism. An example of this is the "httpd" virtual package,
+which all web servers should provide. Virtual package names may be used in
+dependency headers. However, current policy is that virtual packages do not
+support version numbers, so dependencies on virtual packages with versions
+will always fail.
+<item>Several other control fields, such as Package, Version, Description,
+Section, Priority, etc., which are mainly for classification purposes. The
+package name must consist entirely of lowercase characters, plus the characters
+'+', '-', and '.'. Fields can extend across multiple lines - on the second
+and subsequent lines, there is a space at the beginning instead of a field
+name and a ':'. Empty lines must consist of the text " .", which will be
+ignored, as will the initial space for other continuation lines. This feature
+is usually only used in the Description field.
+</list>
+
+<sect>The dpkg status area
+
+<p>
+The "dpkg status area" is the term used to refer to the directory where dpkg
+keeps its various status files (GNU would have you call it the dpkg shared
+state directory). This is always, on Debian systems, /var/lib/dpkg. However,
+the default directory name should not be hard-coded, but #define'd, so that
+alteration is possible (it is available via configure in dpkg 1.4.0.9 and
+above). Of course, in a library, code should be allowed to override the
+default directory, but the default should be part of the library (so that
+the user may change the dpkg admin dir simply by replacing the library).
+
+<p>
+Dpkg keeps a variety of files in its status area. These are discussed later
+on in this document, but a quick summary of the files is here:-
+
+<list>
+<item>available - this file contains a concatenation of control information
+from all the packages which dpkg knows about. This is updated using the dpkg
+commands "--update-avail &lt;file&gt;", "--merge-avail &lt;file&gt;", and
+"--clear-avail".
+<item>status - this file contains information on the following things for
+every package:-
+ <list>
+ <item>Whether it is installed, not installed, unpacked, removed,
+ failed configuration, or half-installed (deconfigured in
+ favour of another package).
+ <item>Whether it is selected as install, hold, remove, or purge.
+ <item>If it is "ok" (no installation problems), or "not-ok".
+ <item>It usually also contains the section and priority (so that
+ dselect may classify packages not in available)
+ <item>For packages which did not initially appear in the "available"
+ file when they were installed, the other control information
+ for them.
+ </list>
+ <p>
+ The exact format for the "Status:" field is:
+ <example>
+ Status: Want Flag Status
+ </example>
+ Where <var>Want</> may be one of <em>unknown</>, <em>install</>,
+ <em>hold</>, <em>deinstall</>, <em>purge</>. <var>Flag</>
+ may be one of <em>ok</>, <em>reinstreq</>, <em>hold</>,
+ <em>hold-reinstreq</>.
+ <var>Status</> may be one of <em>not-installed</>, <em>unpacked</>,
+ <em>half-configured</>, <em>installed</>, <em>half-installed</>
+ <em>config-files</>, <em>post-inst-failed</>, <em>removal-failed</>.
+ The states are as follows:-
+ <taglist>
+ <tag>not-installed
+ <item>No files are installed from the package, it has no config files
+ left, it uninstalled cleanly if it ever was installed.
+ <tag>unpacked
+ <item>The basic files have been unpacked (and are listed in
+ /var/lib/dpkg/info/[package].list. There are config files present,
+ but the postinst script has _NOT_ been run.
+ <tag>half-configured
+ <item>The package was installed and unpacked, but the postinst script
+ failed in some way.
+ <tag>installed
+ <item>All files for the package are installed, and the configuration
+ was also successful.
+ <tag>half-installed
+ <item>An attempt was made to remove the packagem but there was a failure
+ in the prerm script.
+ <tag>config-files
+ <item>The package was "removed", not "purged". The config files are left,
+ but nothing else.
+ <tag>post-inst-failed
+ <item>Old name for half-configured. Do not use.
+ <tag>removal-failed
+ <item>Old name for half-installed. Do not use.
+ </taglist>
+ The two last items are only left in dpkg for compatibility - they are
+ understood by it, but never written out in this form.
+
+ <p>
+ Please see the dpkg source code, <tt>lib/parshelp.c</tt>,
+ <em>statusinfos</>, <em>eflaginfos</> and <em>wantinfos</> for more
+ details.
+
+<item>info - this directory contains files from the control archive of every
+package currently installed. They are installed with a prefix of "&lt;packagename&gt;.".
+In addition to this, it also contains a file called &lt;package&gt;.list for every
+package, which contains a list of files. Note also that the control file is
+not copied into here; it is instead found as part of status or available.
+<item>methods - this directory is reserved for "method"-specific files - each
+"method" has a subdirectory underneath this directory (or at least, it can
+have). In addition, there is another subdirectory "mnt", where misc.
+filesystems (floppies, CDROMs, etc.) are mounted.
+<item>alternatives - directory used by the "update-alternatives" program. It
+contains one file for each "alternatives" interface, which contains information
+about all the needed symlinked files for each alternative.
+<item>diversions - file used by the "dpkg-divert" program. Each diversion takes
+three lines. The first is the package name (or ":" for user diversion), the
+second the original filename, and the third the diverted filename.
+<item>updates - directory used internally by dpkg. This is discussed later,
+in the section <ref id="updates">.
+<item>parts - temporary directory used by dpkg-split
+</list>
+
+<sect>The dpkg library files
+
+<p>
+These files are installed under /usr/lib/dpkg (usually), but
+/usr/local/lib/dpkg is also a possibility (as Debian policy dictates). Under
+this directory, there is a "methods" subdirectory. The methods subdirectory
+in turn contains any number of subdirectories for each general method
+processor (note that one set of method scripts can, and is, used for more than
+one of the methods listed under dselect).
+
+<p>
+The following files may be found in each of these subdirectories:-
+
+<list>
+<item>names - One line per method, two-digit priority to appear on menu
+at beginning, followed by a space, the name, and then another space and the
+short description.
+<item>desc.&lt;name&gt; - Contains the long description displayed by dselect
+when the cursor is put over the &lt;name&gt; method.
+<item>setup - Script or program which sets up the initial values to be used
+by this method. Called with first argument as the status area directory
+(/var/lib/dpkg), second argument as the name of the method (as in the directory
+name), and the third argument as the option (as in the names file).
+<item>install - Script/program called when the "install" option of dselect is
+run with this method. Same arguments as for setup.
+<item>update - Script/program called when the "update" option of dselect is
+run. Same arguments as for setup/install.
+</list>
+
+<sect>The "dpkg" command-line utility
+
+<sect1>"Documented" command-line interfaces
+
+<p>
+As yet unwritten. You can refer to the other manuals for now. See
+<manref name="dpkg" section="8">.
+
+<sect1>Environment variables which dpkg responds to
+
+<p>
+<list>
+<item>DPKG_NO_TSTP - if set to a non-null value, this variable causes dpkg to
+run a child shell process instead of sending itself a SIGTSTP, when the user
+selects to background the dpkg process when it asks about conffiles.
+<item>SHELL - used to determine which shell to run in the case when
+DPKG_NO_TSTP is set.
+<item>CC - used as the C compiler to call to determine the target architecture.
+The default is "gcc".
+<item>PATH - dpkg checks that it can find at least the following files in the
+path when it wants to run package installation scripts, and gives an error if
+it cannot find all of them:-
+ <list>
+ <item>ldconfig
+ <item>start-stop-daemon
+ <item>install-info
+ <item>update-rc.d
+ </list>
+</list>
+
+<sect1>Assertions
+
+<p>
+The dpkg utility itself is required for quite a number of packages, even if
+they have been installed with a tool totally separate from dpkg. The reason for
+this is that some packages, in their pre-installation scripts, check that your
+version of dpkg supports certain features. This was broken from the start, and
+it should have actually been a control file header "Dpkg-requires", or similar.
+What happens is that the configuration scripts will abort or continue according
+to the exit code of a call to dpkg, which will stop them from being wrongly
+configured.
+
+<p>
+These special command-line options, which simply return as true or false are
+all prefixed with "--assert-". Here is a list of them (without the prefix):-
+
+<list>
+<item>support-predepends - Returns success or failure according to whether
+a version of dpkg which supports predepends properly (1.1.0 or above) is
+installed, according to the database.
+<item>working-epoch - Return success or failure according to whether a version
+of dpkg which supports epochs in version properly (1.4.0.7 or above) is
+installed, according to the database.
+</list>
+
+<p>
+Both these options check the status database to see what version of the "dpkg"
+package is installed, and check it against a known working version.
+
+<sect1>--predep-package
+
+<p>
+This strange option is described as follows in the source code:
+
+<example>
+/* Print a single package which:
+ * (a) is the target of one or more relevant predependencies.
+ * (b) has itself no unsatisfied pre-dependencies.
+ * If such a package is present output is the Packages file entry,
+ * which can be massaged as appropriate.
+ * Exit status:
+ * 0 = a package printed, OK
+ * 1 = no suitable package available
+ * 2 = error
+ */
+</example>
+
+<p>
+On further inspection of the source code, it appears that what is does is
+this:-
+
+<list>
+<item>Looks at the packages in the database which are selected as "install",
+and are installed.
+<item>It then looks at the Pre-Depends information for each of these packages
+from the available file. When it find a package for which any of the
+pre-dependencies are not satisfied, it breaks from the loop through the packages.
+<item>It then looks through the unsatisfied pre-dependencies, and looks for
+packages which would satisfy this pre-dependency, stopping on the first it
+finds. If it finds none, it bombs out with an error.
+<item>It then continues this for every dependency of the initial package.
+</list>
+
+Eventually, it writes out the record of all the packages to satisfy the
+pre-dependencies. This is used by the disk method to make sure that its
+dependency ordering is correct. What happens is that all pre-depending
+packages are first installed, then it runs dpkg -iGROEB on the directory,
+which installs in the order package files are found. Since pre-dependencies
+mean that a package may not even be unpacked unless they are satisfied, it is
+necessary to do this (usually, since all the package files are unpacked in one
+phase, the configured in another, this is not needed).
+
+<chapt>dpkg-deb and .deb file internals
+
+<p>
+This chapter describes the internals to the "dpkg-deb" tool, which is used
+by "dpkg" as a back-end. dpkg-deb has its own tar extraction functions, which
+is the source of many problems, as it does not support long filenames, using
+extension blocks.
+
+<sect>The .deb archive format
+
+<p>
+The main principal of the new-format Debian archive (I won't describe the old
+format - for that have a look at deb-old.5), is that the archive really is
+an archive - as used by "ar" and friends. However, dpkg-deb uses this format
+internally, rather than calling "ar". Inside this archive, there are usually
+the folowing members:-
+
+<list>
+<item>debian-binary
+<item>control.tar.gz
+<item>data.tar.gz
+</list>
+
+<p>
+The debian-binary member consists simply of the string "2.0", indicating the
+format version. control.tar.gz contains the control files (and scripts), and
+the data.tar.gz contains the actual files to populate the filesystem with.
+Both tarfiles extract straight into the current directory. Information on the
+tar formats can be found in the GNU tar info page. Since dpkg-deb calls
+"tar -cf" to build packages, the Debian packages use the GNU extensions.
+
+<sect>The dpkg-deb command-line
+
+<p>
+dpkg-deb documents itself thoroughly with its '--help' command-line option.
+However, I am including a reference to these for completeness. dpkg-deb
+supports the following options:-
+
+<list>
+<item>--build (-b) &lt;dir&gt; - builds a .deb archive, takes a directory which
+contains all the files as an argument. Note that the directory
+&lt;dir&gt;/DEBIAN will be packed separately into the control archive.
+<item>--contents (-c) &lt;debfile&gt; - Lists the contents of ther "data.tar.gz"
+member.
+<item>--control (-e) &lt;debfile&gt; - Extracts the control archive into a
+directory called DEBIAN. Alternatively, with another argument, it will extract
+it into a different directory.
+<item>--info (-I) &lt;debfile&gt; - Prints the contents of the "control" file
+in the control archive to stdout. Alternatively, giving it other arguments will
+cause it to print the contents of those files instead.
+<item>--field (-f) &lt;debfile&gt; &lt;field&gt; ... - Prints any number of
+fields from the "control" file. Giving it extra arguments limits the fields it
+prints to only those specified. With no command-line arguments other than a
+filename, it is equivalent to -I and just the .deb filename.
+<item>--extract (-x) &lt;debfile&gt; &lt;dir&gt; - Extracts the data archive
+of a debian package under the directory &lt;dir&gt;.
+<item>--vextract (-X) &lt;debfile&gt; &lt;dir&gt; - Same as --extract, except
+it is equivalent of giving tar the '-v' option - it prints the filenames as
+it extracts them.
+<item>--fsys-tarfile &lt;debfile&gt; - This option outputs a gunzip'd version
+of data.tar.gz to stdout.
+<item>--new - sets the archive format to be used to the new Debian format
+<item>--old - sets the archive format to be used to the old Debian format
+<item>--debug - Tells dpkg-deb to produce debugging output
+<item>--nocheck - Tells dpkg-deb not to check the sanity of the control file
+<item>--help (-h) - Gives a help message
+<item>--version - Shows the version number
+<item>--licence/--license (UK/US spellings) - Shows a brief outline of the GPL
+</list>
+
+<sect1>Internal checks used by dpkg-deb when building packages
+
+<p>
+Here is a list of the internal checks used by dpkg-deb when building packages.
+It is in the order they are done.
+
+<list>
+<item>First, the output Debian archive argument, if it is given, is checked
+using stat. If it is a directory, an internal flag is set. This check is only
+made if the archive name is specified explicitly on the command-line. If the
+argument was not given, the default is the directory name, with ".deb"
+appended.
+<item>Next, the control file is checked, unless the --nocheck flag was
+specified on the command-line. dpkg-deb will bomb out if the second argument
+to --build was a directory, and --nocheck was specified. Note that dpkg-deb
+will not be able to determine the name of the package in this case. In the
+control file, the following things are checked:-
+ <list>
+ <item>The package name is checked to see if it contains any invalid
+ characters (see <ref id="control"> for this).
+ <item>The priority field is checked to see if it uses standard values,
+ and user-defined values are warned against. However, note that this
+ check is now redundant, since the control file no longer contains
+ the priority - the changes file now does this.
+ <item>The control file fields are then checked against the standard
+ list of fields which appear in control files, and any "user-defined"
+ fields are reported as warnings.
+ <item>dpkg-deb then checks that the control file contains a valid
+ version number.
+ </list>
+<item>After this, in the case where a directory was specified to build the
+.deb file in, the filename is created as "directory/pkg_ver.deb" or
+"directory/pkg_ver_arch.deb", depending on whether the control file contains
+an architecture field.
+<item>Next, dpkg-deb checks for the &lt;dir&gt;/DEBIAN directory. It complains
+if it doesn't exist, or if it has permissions &lt; 0755, or &gt; 0775.
+<item>It then checks that all the files in this subdir are either symlinks
+or plain files, and have permissions between 0555 and 0775.
+<item>The conffiles file is then checked to see if the filenames are too
+long. Warnings are produced for each that is. After this, it checks that
+the package provides initial copies of each of these conffiles, and that
+they are all plain files.
+</list>
+
+<chapt>dpkg internals
+
+<p>
+This chapter describes the internals of dpkg itself. Although the low-level
+formats are quite simple, what dpkg does in certain cases often does not
+make sense.
+
+<sect id="updates">Updates
+
+<p>
+This describes the /var/lib/dpkg/updates directory. The function of this
+directory is somewhat strange, and seems only to be used internally. A function
+called cleanupdates is called whenever the database is scanned. This function
+in turn uses <manref name="scandir" section="3">, to sort the files in this
+directory. Files who names do not consist entirely of digits are discarded.
+dpkg also causes a fatal error if any of the filenames are different lengths.
+
+<p>
+After having scanned the directory, dpkg in turn parses each file the same way
+it parses the status file (they are sorted by the scandir to be in numerical
+order). After having done this, it then writes the status information back
+to the "status" file, and removes all the "updates" files.
+
+<p>
+These files are created internally by dpkg's "checkpoint" function, and are
+cleaned up when dpkg exits cleanly.
+
+<p>
+Juding by the use of the updates directory I would call it a Journal. Inorder
+to effeciently ensure the complete integrity of the status file dpkg will
+"checkpoint" or journal all of it's activities in the updates directory. By
+merging the contents of the updates directory (in order!!) against the
+original status file it can get the precise current state of the system,
+even in the event of a system failure while dpkg is running.
+
+<p>
+The other option would be to sync-rewrite the status file after each
+operation, which would kill performance.
+
+<p>
+It is very important that any program that uses the status file abort if
+the updates directory is not empty! The user should be informed to run dpkg
+manually (what options though??) to correct the situation.
+
+<sect>What happens when dpkg reads the database
+
+<p>
+First, the status file is read. This gives dpkg an initial idea of the packages
+that are there. Next, the updates files are read in, overriding the status
+file, and if necessary, the status file is re-written, and updates files are
+removed. Finally, the available file is read. The available file is read
+with flags which preclude dpkg from updating any status information from it,
+though - installed version, etc., and is also told to record that the packages
+it reads this time are available, not installed.
+
+<p>
+More information on updates is given above.
+
+<sect>How dpkg compares version numbers
+
+<p>
+Version numbers consist of three parts: the epoch, the upstream version, and
+the Debian revision. Dpkg compares these parts in that order. If the epochs
+are different, it returns immediately, and so on.
+
+<p>
+However, the important part is how it compares the versions which are
+essentially stored as just strings. These are compared in two distinct parts:
+those consisting of numerical characters (which are evaluated, and then
+compared), and those consisting of other characters. When comparing
+non-numerical parts, they are compared as the character values (ASCII), but
+non-alphabetical characters are considered "greater than" alphabetical ones.
+Also note that longer strings (after excluding differences where numerical
+values are equal) are considered "greater than" shorter ones.
+
+<p>
+Here are a few examples of how these rules apply:-
+
+<example>
+15 > 10
+0010 == 10
+
+d.r > dsr
+32.d.r == 0032.d.r
+d.rnr < d.rnrn
+</example>
+
+</book>
diff --git a/doc/files.sgml b/doc/files.sgml
new file mode 100644
index 000000000..d98d6f68a
--- /dev/null
+++ b/doc/files.sgml
@@ -0,0 +1,491 @@
+<!doctype debiandoc system>
+<!-- -*- mode: sgml; mode: fold -*- -->
+<book>
+<title>APT Files</title>
+
+<author>Jason Gunthorpe <email>jgg@debian.org</email></author>
+<version>$Id: files.sgml,v 1.1 1998/07/02 02:58:12 jgg Exp $</version>
+
+<abstract>
+This document describes the complete implementation and format of the
+installed APT directory structure. It also serves as guide to how APT
+views the Debian archive.
+</abstract>
+
+<copyright>
+Copyright &copy; Jason Gunthorpe, 1998.
+<p>
+"APT" and this document are free software; you can redistribute them and/or
+modify them under the terms of the GNU General Public License as published
+by the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+<p>
+For more details, on Debian GNU/Linux systems, see the file
+/usr/doc/copyright/GPL for the full license.
+</copyright>
+
+<toc sect>
+
+<chapt>Introduction
+<!-- General {{{ -->
+<!-- ===================================================================== -->
+<sect>General
+
+<p>
+This document serves two purposes. The first is to document the installed
+directory structure and the format and purpose of each file. The second
+purpose is to document how APT views the Debian archive and deals with
+multiple package files.
+
+<p>
+The var directory structure is as follows:
+<example>
+ /var/state/apt/
+ lists/
+ partial/
+ xstatus
+ /var/cache/apt/
+ pkgcache.bin
+ srcpkgcache.bin
+ archives/
+ partial/
+ /etc/apt/
+ sources.list
+ cdromdevs.list
+ /usr/lib/apt/
+ methods/
+ cdrom
+ ftp
+ http
+</example>
+
+<p>
+As is specified in the FHS 2.0 /var/state/apt is used for application
+data that is not expected to be user modified. /var/cache/apt is used
+for regeneratable data and is where the package cache and downloaded .debs
+go.
+</sect>
+ <!-- }}} -->
+
+<chapt>Files
+<!-- Distribution Source List {{{ -->
+<!-- ===================================================================== -->
+<sect>Distribution Source list (sources.list)
+
+<p>
+The distribution source list is used to locate archives of the debian
+distribution. It is designed to support any number of active sources and to
+support a mix of source media. The file lists one source per line, with the
+fastest source listed first. The format of each line is:
+
+<p>
+<var>type ui args</var>
+
+<p>
+The first item, <var>type</var>, indicates the format for the remainder
+of the line. It is designed to indicate the structure of the distribution
+the line is talking about. Currently the only defined value is <em>deb</em>
+which indicates a standard debian archive with a dists dir.
+
+<sect1>The deb Type
+ <p>
+ The <em>deb</em> type is to be a typical two level debian distributions,
+ dist/<var>distribution</var>/<var>component</var>. Typically distribution
+ is one of stable, unstable or frozen while component is one of main,
+ contrib, non-free or non-us. The format for the deb line is as follows:
+
+ <p>
+ deb <var>uri</var> <var>distribution</var> <var>compontent</var>
+ [<var>component</var> ...]
+
+ <p>
+ <var>uri</var> for the <em>deb</em> type must specify the base of the
+ debian distribution. APT will automatically generate the proper longer
+ URIs to get the information it needs. <var>distribution</var> can specify
+ an exact path, in this case the components must be omitted and
+ <var>distribution</var> must end in a slash.
+
+ <p>
+ Since only one distribution can be specified per deb line it may be
+ necessary to list a number of deb lines for the same URI. APT will
+ sort the URI list after it has generated a complete set to allow
+ connection reuse. It is important to order things in the sourcelist
+ from most prefered to least prefered (fastest to slowest).
+</sect1>
+
+<sect1>URI specification
+<p>
+URIs in the source list support a large number of access schemes.
+
+<taglist>
+<tag>cdrom<item>
+ The cdrom scheme is special in that If Modifed Since queries are never
+ performed and that APT knows how to match a cdrom to the name it
+ was given when first inserted. It does this by examining the date
+ and size of the package file. APT also knows all of the possible
+ prefix paths for the cdrom drives and that the user should be prompted
+ to insert a CD if it cannot be found. The path is relative to an
+ arbitary mount point (of APT's choosing) and must not start with a
+ slash. The first pathname component is the given name and is purely
+ descriptive and of the users choice. However, if a file in the root of
+ the cdrom is called 'cdname' its contents will be used instead of
+ prompting. The name serves as a tag for the cdrom and should be unique.
+ APT will track the CDROM's based on their tag and package file
+ properties.
+ <example>
+ cdrom:Debian 1.3/debian
+ </example>
+
+<tag>http<item>
+ This scheme specifies a HTTP server for the debian archive. HTTP is prefered
+ over FTP because If Modified Since queries against the Package file are
+ possible. Newer HTTP protcols may even support reget which would make
+ http the protocol of choice.
+ <example>
+ http://www.debian.org/archive
+ </example>
+
+<tag>ftp<item>
+ This scheme specifies a FTP connection to the server. FTP is limited because
+ there is no support for IMS and is hard to proxy over firewalls.
+ <example>
+ ftp://ftp.debian.org/debian
+ </example>
+
+<tag>file<item>
+ The file scheme allows an arbitary directory in the file system to be
+ considered as a debian archive. This is usefull for NFS mounts and
+ local mirrors/archives.
+ <example>
+ file:/var/debian
+ </example>
+
+<tag>mirror<item>
+ The mirror scheme is special in that it does not specify the location of a
+ debian archive but specifies the location of a list of mirrors to use
+ to access the archive. Some technique will be used to determine the
+ best choice for a mirror. The mirror file is specified in the Mirror File
+ section. If/when URIs take off they should obsolete this field.
+ <example>
+ mirror:http://www.debian.org/archivemirrors
+ </example>
+
+<tag>smb<item>
+ A possible future expansion may be to have direct support for smb (Samba
+ servers).
+ <example>
+ smb://ftp.kernel.org/pub/mirrors/debian
+ </example>
+</taglist>
+</sect1>
+
+<sect1>Hashing the URI
+<p>
+All permanent information aquired from any of the sources is stored in the
+lists directory. Thus, there must be a way to relate the filename in the
+lists directory to a line in the sourcelist. To simplify things this is
+done by quoting the URI and treating ='s as quoteable characters and
+converting / to =. The URI spec says this is done by converting a
+sensitive character into %xx where xx is the hexadecimal representation
+from the ascii character set. Examples:
+
+<example>
+http://www.debian.org/archive/dists/stable/binary-i386/Packages
+/var/state/apt/lists/www.debian.org=archive=dists=stable=binary-i386=Packages
+
+cdrom:Debian 1.3/debian/Packages
+/var/state/apt/info/Debian%201.3=debian=Packages
+</example>
+
+<p>
+The other alternative that was considered was to use a deep directory
+structure but this poses two problems, it makes it very difficult to prune
+directories back when sources are no longer used and complicates the handling
+of the partial directory. This gives a very simple way to deal with all
+of the situations that can arise. The equals sign was choosen on the
+suggestion of Manoj because it is very infrequently used in filenames.
+Also note that the same rules described in the <em>Archive Directory</>
+section regarding the partial sub dir apply here as well.
+</sect1>
+
+</sect>
+ <!-- }}} -->
+<!-- Extra Status {{{ -->
+<!-- ===================================================================== -->
+<sect>Extra Status File (xstatus)
+
+<p>
+The extra status file serves the same purpose as the normal dpkg status file
+(/var/lib/dpkg/status) except that it stores information unique to diety.
+This includes the autoflag, target distribution and version and any other
+uniqe features that come up over time. It duplicates nothing from the normal
+dpkg status file. Please see other APT documentation for a discussion
+of the exact internal behavior of these fields. The Package field is
+placed directly before the new fields to indicate which package they
+apply to. The new fields are as follows:
+
+<taglist>
+<tag>X-Auto<item>
+ The Auto flag can be Yes or No and controls whether the package is in
+ auto mode.
+
+<tag>X-TargetDist<item>
+ The TargetDist item indicates which distribution versions are offered for
+ installation from. It should be stable, unstable or frozen.
+
+<tag>X-TargetVersion<item>
+ The target version item is set if the user selects a specific version, it
+ overrides the TargetDist selection if both are present.
+</taglist>
+</sect>
+ <!-- }}} -->
+<!-- Binary Package Cache {{{ -->
+<!-- ===================================================================== -->
+<sect>Binary Package Cache (pkgcache.bin)
+
+<p>
+Please see cache.sgml for a complete description of what this file is. The
+cache file is updated whenever the contents of the lists directory changes.
+If the cache is erased, corrupted or of a non-matching version it will
+be automatically rebuilt by all of the tools that need it.
+<em>srcpkgcache.bin</> contains a cache of all of the package files in the
+source list. This allows regeneration of the cache when the status files
+change to use a prebuilt version for greater speed.
+</sect>
+ <!-- }}} -->
+<!-- Downloads Directory {{{ -->
+<!-- ===================================================================== -->
+<sect>Downloads Directory (archives)
+
+<p>
+The archives directory is where all downloaded .deb archives go. When the
+file transfer is initiated the deb is placed in partial. Once the file
+is fully downloaded and its MD5 hash and size are verifitied it is moved
+from partial into archives/. Any files found in archives/ can be assumed
+to be verified.
+
+<p>
+No dirctory structure is transfered from the receiving site and all .deb
+file names conform to debian conventions. No short (msdos) filename should
+be placed in archives. If the need arises .debs should be unpacked, scanned
+and renamed to their correct internal names. This is mostly to prevent
+file name conflicts but other programs may depend on this if convenient.
+Downloaded .debs must be found in one of the package lists with an exact
+name + version match..
+</sect>
+ <!-- }}} -->
+<!-- The Methods Directory {{{ -->
+<!-- ===================================================================== -->
+<sect> The Methods Directory (/usr/lib/apt/methods)
+
+<p>
+Like dselect, APT will support plugable acquisition methods to complement
+its internaly supported methods. The files in
+this directory are execultables named after the URI type. APT will
+sort the required URIs and spawn these programs giving a full sorted, quoted
+list of URIs.
+
+<p>
+The interface is simple, the program will be given a list
+of URIs on the command line. The URIs will be in pairs, the first
+being the actual URI and the second being the filename to write the data to.
+The current directory will be set properly by APT and it is
+expected the method will put files relative to the current directory.
+The output of these programs is strictly speficied. The programs must accept
+nothing from stdin (stdin will be an invalid fd) and they must output
+status information to stdout according to the format below.
+Stderr will be redirected to the logging facility.
+
+<p>
+Each line sent to stdout must be a line that has a single letter and a
+space. Strings after the first letter do not need quoting, they are taken
+as is till the end of the line. The tag letters, listed in expected order,
+is as follows:
+
+<taglist>
+
+<tag>F - Change URI<item>
+This specifies a change in URI. All information after this will be applied
+to the new URI. When the URI is changed it is assumed that the old URI has
+completed unless an error is set. The format is <var>F URI</>
+
+<tag>S - Object Size<item>
+This specifies the expected size of the object. APT will use this to
+compute percent done figures. If it is not sent then a kilobyte meter
+will be used instead of a percent display. The foramat is <var>S INTEGER</>
+
+<tag>E - Error Information<item>
+Exactly one line of error information can be set for each URI. The
+information will be summarized for the user. If an E tag is send before
+any F tags then the error is assumed to be a fatal method error and all URI
+fetches for that method are aborted with that error string. The format
+is <var>E String</>
+
+<tag>I - Informative progress information<item>
+The I tag allows the method to specify the status of the connection.
+Typically the GUI will show the last recieved I line. The format is
+<var>I String</> As a general rule an I tag should be ommitted before a
+lengthy operation only. Things that always take a short period are not
+suited for I tags. I tags should change wnenever the methods state changes.
+Some standard forms, in order of occurance, are <var>Connecting to SITE</>,
+<var>Connecting to SITE (1.1.1.1)</>, <var>Waiting for file</>,
+<var>Authenticating</>, <var>Downloading</>, <var>Resuming (size)</>,
+<var>Computing MD5</> <var>I</> lines should never print out information that
+APT is already aware of, such as file names.
+
+<tag>R - Set final path<item>
+The R tag allows the method to tell APT that the file is present in the
+local file system. APT might copy it into a the download directory. The format
+is <var>R String</>
+
+<tag>M - MD5Sum of the file<item>
+The method is expected to compute the md5 hash on the fly as the download
+progresses. The final md5 of the file is to be output when the file is
+completed. If the md5 is not output it will not be checked! Some methods
+such as the file method will not check md5's because they are most
+commonly used on mirrors or local CD-ROM's, a paranoid option may be
+provided in future to force checking. The format is <var>M MD5-String</>
+
+<tag>L - Log output<item>
+This tag indicates a string that should be dumped to some log file. The
+string is for debugging and is not ment to be seen by the user. The format
+is <var>L String</> Log things should only be used in a completed method
+if they have special relavence to what is happening.
+</taglist>
+
+<p>
+APT monitors the progress of the transfer by watching the file size. This
+means the method must not create any temp files and must use a fairly small
+buffer. The method is also responsible for If-Modified-Since (IMS) queries
+for the object. It should check ../outputname to get the time stamp but not
+size. The size may be different because the file was uncompressed after
+it was transfed. A method must <em>never</> change the file in .., it may
+only change the output file in the current directory.
+
+<p>
+The APT 'http' program is the reference implementation of this specification,
+it implements all of the features a method is expected to do.
+</sect>
+ <!-- }}} -->
+<!-- The Mirror List {{{ -->
+<!-- ===================================================================== -->
+<sect> The Mirror List
+
+<p>
+The mirror list is stored on the primary debian web server (www.debian.org)
+and contains a machine readable list of all known debian mirrors. The mirror
+URI type will cause this list to be downloaded and considered. It has the
+same form as the source list. When the source list specifies mirror
+as the target the mirror list is scanned to find the nescessary parts for
+the requested distributions and components. This means the user could
+have a line like:
+
+<var>deb mirror:http://www.debian.org/mirrorlist stable main non-us</var>
+
+which would likely cause APT to choose two separate sites to download from,
+one for main and another for non-us.
+
+<p>
+Some form of network measurement will have to be used to gauge performance
+of each of the mirrors. This will be discussed later, initial versions
+will use the first found URI.
+</sect>
+ <!-- }}} -->
+<!-- The Release File {{{ -->
+<!-- ===================================================================== -->
+<sect> The Release File
+
+<p>
+This file plays and important role in how APT presents the archive to the
+user. Its main purpose is to present a descriptive name for the source
+of each version of each package. It also is used to detect when new versions
+of debian are released. It augments the package file it is associated with
+by providing meta information about the entire archive which the Packages
+file describes.
+
+<p>
+The full name of the distribution for presentation to the user is formed
+as 'label version archive', with a possible extended name being
+'label version archive component'.
+
+<p>
+The file is formed as the package file (RFC-822) with the following tags
+defined:
+
+<taglist>
+<tag>Archive<item>
+This is the common name we give our archives, such as <em>stable</> or
+<em>unstable</>.
+
+<tag>Component<item>
+Referes to the sub-component of the archive, <em>main</>, <em>contrib</>
+etc.
+
+<tag>Version<item>
+This is a version string with the same properties as in the Packages file.
+It represents the release level of the archive.
+
+<tag>Origin<item>
+This specifies who is providing this archive. In the case of Debian the
+string will read 'Debian'. Other providers may use their own string
+
+<tag>Label<item>
+This carries the encompassing name of the distribution. For Debian proper
+this field reads 'Debian'. For derived distributions it should contain their
+proper name.
+
+<tag>Architecture<item>
+When the archive has packages for a single architecture then the Architecture
+is listed here. If a mixed set of systems are represented then this should
+contain the keyword <em>mixed</em>.
+
+<tag>NotAutomatic<item>
+A Yes/No flag indicating that the archive is extremely unstable and its
+version's should never be automatically selected. This is to be used by
+experimental.
+
+<tag>Description<item>
+Description is used to describe the release. For instance experimental would
+contain a warning that the packages have problems.
+</taglist>
+
+<p>
+The location of the Release file in the archive is very important, it must
+be located in the same location as the packages file so that it can be
+located in all situations. The following is an example for the current stable
+release, 1.3.1r6
+
+<example>
+Archive: stable
+Compontent: main
+Version: 1.3.1r6
+Origin: Debian
+Label: Debian
+Architecture: i386
+</example>
+
+This is an example of experimental,
+<example>
+Archive: experimental
+Version: 0
+Origin: Debian
+Label: Debian
+Architecture: mixed
+NotAutomatic: Yes
+</example>
+
+And unstable,
+<example>
+Archive: unstable
+Compontent: main
+Version: 2.1
+Origin: Debian
+Label: Debian
+Architecture: i386
+</example>
+
+</sect>
+ <!-- }}} -->
+
+</book>
diff --git a/doc/ftp.conf.5 b/doc/ftp.conf.5
new file mode 100644
index 000000000..30c7c031b
--- /dev/null
+++ b/doc/ftp.conf.5
@@ -0,0 +1,93 @@
+.\" This manpage is copyright (C) 1998 Branden Robinson <branden@debian.org>
+.\" and Manoj Srivastava <srivasta@datasync.com>.
+.\"
+.\" This is free software; you may redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2,
+.\" or (at your option) any later version.
+.\"
+.\" This is distributed in the hope that it will be useful, but
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with APT; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+.\" 02111-1307 USA
+.TH ftp.conf 5 "16 June 1998" "Debian GNU/Linux"
+.SH NAME
+ftp.conf \- configuration file for APT FTP method
+.SH DESCRIPTION
+The ftp.conf file determines the behavior of the FTP method for the APT
+packaging tool. The syntax of the file is
+.IR variable = value .
+Quotes are not required around
+.IR value s.
+Comments start with a '#' and end at the next newline. Blank lines are
+ignored. The following
+.I variables
+are understood:
+.IP Firewall
+is the hostname of a machine which acts as an FTP firewall. This can be
+overridden by an environment variable
+.IR FTP_FIREWALL .
+If specified, and the given hostname cannot be directly contacted, a connection
+is made to the firewall machine and the string
+.B @hostname
+is appended to the login identifier. This type of setup is also known as an
+FTP proxy.
+.IP ProxyLogName
+is a parameter used by some firewall FTP proxies. It is used to authorize
+the user specified by
+.I ProxyLogName
+to send data beyond the
+.I Firewall
+machine.
+.IP ProxyPassword
+is the password used to authenticate
+.I ProxyLogName
+on the
+.I Firewall
+machine.
+.IP TimeOut
+sets a timeout value in seconds (the default is sixty seconds).
+.IP Passive
+is either
+.B true
+or
+.BR false .
+If true, then all data transfers will be done using passive mode. This is
+required for some dumb FTP servers and firewall configurations. It can
+also be overridden by the environment variable
+.IR FTP_PASSIVE .
+.IP Verbose
+is either
+.B true
+or
+.B false,
+and makes the FTP method output more data than it normally does.
+.IP Debug
+is either
+.B true
+or
+.B false,
+and makes the FTP method output debugging information. This variable is
+not currently implemented.
+.IP MaxReTry
+sets the number of times a connection is re-tried before giving up (the
+default is twice).
+.SH SEE ALSO
+.BR apt (8),
+.BR apt-get (8)
+.SH BUGS
+See <http://www.debian.org/Bugs/db/pa/lapt.html>. If you wish to report a
+bug in
+.BR apt-get ,
+please see
+.I /usr/doc/debian/bug-reporting.txt
+or the
+.BR bug (1)
+command.
+.SH AUTHOR
+APT was written by the APT team <apt@packages.debian.org>.
diff --git a/doc/guide.sgml b/doc/guide.sgml
new file mode 100644
index 000000000..bbc01b78b
--- /dev/null
+++ b/doc/guide.sgml
@@ -0,0 +1,548 @@
+<!doctype debiandoc system>
+<!-- -*- mode: sgml; mode: fold -*- -->
+<book>
+<title>APT User's Guide</title>
+
+<author>Jason Gunthorpe <email>jgg@debian.org</email></author>
+<version>$Id: guide.sgml,v 1.1 1998/07/02 02:58:12 jgg Exp $</version>
+
+<abstract>
+This document provides an overview of how to use the the APT package manager.
+</abstract>
+
+<copyright>
+Copyright &copy; Jason Gunthorpe, 1998.
+<p>
+"APT" and this document are free software; you can redistribute them and/or
+modify them under the terms of the GNU General Public License as published
+by the Free Software Foundation; either version 2 of the License, or (at your
+option) any later version.
+
+<p>
+For more details, on Debian GNU/Linux systems, see the file
+/usr/doc/copyright/GPL for the full license.
+</copyright>
+
+<toc sect>
+
+<!-- General {{{ -->
+<!-- ===================================================================== -->
+<chapt>General
+
+<p>
+The APT package currently contains two sections, the APT <prgn>dselect</>
+method and the <prgn>apt-get</> command line user interface. Both provide
+a way to install and remove packages as well as download new packages from
+the Internet.
+
+<sect>Anatomy of the Package System
+<p>
+The Debian packaging system has a large amount of information associated with
+each package to help assure that it integrates cleanly and easily into
+the system. The most prominent of features is the dependency system.
+
+<p>
+The dependency system allows individual programs to make use of shared
+elements in the system such as libraries. It simplifies placing infrequently
+used portions of a program in separate packages to reduce the
+number of things the average user is required to install. Also, it allows
+a choices in for such things as mail transport agents, X servers and
+so on.
+
+<p>
+The first step to understanding the dependency system is to grasp the concept
+of a simple dependency. The meaning of a simple dependency is that a package
+requires another package to be installed at the same time to work properly.
+
+<p>
+For instance, mail-crypt is an emacs extension that aids in encrypting email
+with PGP. Without PGP installed mail-crypt is useless, so mail-crypt has a
+simple dependency on PGP. Also, because it is an emacs extension it has a
+simple dependency on emacs, without emacs it is completely useless.
+
+<p>
+The other important dependency to understand is a conflicting dependency. It
+means that a package, when installed with another package, will not work and
+may possibly be extremely harmful to the system. As an example consider a
+mail transport agent such as sendmail, exim or qmail. It is not possible
+to have two mail transport agents installed because both need to listen to
+the network to receive mail. Attempting to install two will seriously
+damage the system so all mail transport agents have a conflicting dependency
+with all other mail transport agents.
+
+<p>
+As an added complication there is the possibility for a package to pretend
+to be another package. Consider that exim and sendmail for many intents are
+identical, they both deliver mail and understand a common interface. Hence,
+the package system has a way for them to declare that they are both
+mail-transport-agents. So, exim and sendmail both declare that they provide a
+mail-transport-agent and other packages that need a mail transport agent
+depend on mail-transport-agent. This can add a great deal of confusion when
+trying to manually fix packages.
+
+<p>
+At any given time a single dependency may be met by packages that are already
+installed or it may not be. APT attempts to help resolve dependency issues
+by providing a number of automatic algorithms that help in selecting packages
+for installation.
+</sect>
+
+</chapt>
+ <!-- }}} -->
+<!-- apt-get {{{ -->
+<!-- ===================================================================== -->
+<chapt>apt-get
+
+<p>
+<prgn>apt-get</> provides a simple way to install packages from the command
+line. Unlike <prgn>dpkg</>, <prgn>apt-get</> does not understand .deb files,
+it works with the packages proper name and can only install .deb archives from
+a <em>Source</>.
+
+<p>
+The first <footnote>If you are using an http proxy server you must set the
+http_proxy environment variable first, see sources.list(5)</footnote> thing that
+should be done before using <prgn>apt-get</> is to fetch the package lists
+from the <em>Sources</> so that it knows what packages are
+available. This is done with <tt>apt-get update</>. For instance,
+
+<p>
+<example>
+# apt-get update
+Get http://ftp.de.debian.org/debian-non-US/ stable/binary-i386/ Packages
+Get http://llug.sep.bnl.gov/debian/ frozen/contrib Packages
+Updating package file cache...done
+Updating package status cache...done
+Checking system integrity...ok
+</example>
+
+<p>
+Once updated there are several useful commands that can be used,
+<taglist>
+<tag>upgrade<item>
+Upgrade will attempt to gently upgrade the whole system. Upgrade will
+never install a new package or remove an existing package, nor will it
+ever upgrade a package that might cause some other package to break.
+This can be used daily to relatively safely upgrade the system. Upgrade
+will list all of the packages that it could not upgrade, this usually
+means that they depend on new packages or conflict with some other package.
+<prgn>Dselect</> or <tt>apt-get install</> can be used to force these
+packages to install.
+
+<tag>install<item>
+Install is used to install single packages by name. The package is
+automatically fetched and installed. This can be useful if you already
+know the name of the package to install and do not want to go into a GUI
+to select it. Any number of packages may be passed to install, they will
+all be fetched. Install automatically attempts to resolve dependency problems
+with the listed packages and will print a summary and ask for confirmation
+if anything other than it's arguments are changed
+
+<tag>dist-upgrade<item>
+Dist-upgrade is a complete upgrader designed to make simple upgrading between
+releases of Debian. It uses a sophisticated algorithm to determine the best
+set of packages to install, upgrade and remove to get as much of the system
+to the newest release. In some situations it may be desired to use dist-upgrade
+rather than spend the time manually resolving dependencies in <prgn>dselect</>.
+Once dist-upgrade has completed then <prgn>dselect</> can be used to install
+any packages that may have been left out.
+
+<p>
+It is important to closely look at what dist-upgrade is going to do, its
+decisions may sometimes be quite surprising.
+</taglist>
+
+<p>
+<prgn>apt-get</> has several command line options that are detailed in it's
+man page, <manref name="apt-get" section="8">. The most useful option is
+<tt>-d</> which does not install the fetched files. If the system has to
+download a large number of package it would be undesired to start installing
+them in case something goes wrong. When <tt>-d</> is used the downloaded
+archives can be installed by simply running the command that caused them to
+be downloaded again without <tt>-d</>.
+
+</chapt>
+ <!-- }}} -->
+<!-- DSelect {{{ -->
+<!-- ===================================================================== -->
+<chapt>DSelect
+<p>
+The APT <prgn>dselect</> method provides the complete APT system with
+the <prgn>dselect</> package selection GUI. <prgn>dselect</> is used to
+select the packages to be installed or removed and APT actually installs them.
+
+<p>
+To enable the APT method you need to to select [A]ccess in <prgn>dselect</>
+and then choose the APT method. You will be prompted for a set of
+<em>Sources</> which are places to fetch archives from. These can be remote
+Internet sites, local Debian mirrors or CDROMs. Each source can provide
+a fragment of the total Debian archive, APT will automatically combine them
+to form a complete set of packages. If you have a CDROM then it is a good idea
+to specify it first and then specify a mirror so that you have access to
+the latest bug fixes. APT will automatically use packages on your CDROM before
+downloading from the Internet.
+
+<p>
+<example>
+ Set up a list of distribution source locations
+
+ Please give the base URL of the debian distribution.
+ The access schemes I know about are: http file
+
+ For example:
+ file:/mnt/debian,
+ ftp://ftp.debian.org/debian,
+ http://ftp.de.debian.org/debian,
+
+
+ URL [http://llug.sep.bnl.gov/debian]:
+</example>
+
+<p>
+The <em>Sources</> setup starts by asking for the base of the Debian
+archive, defaulting to a HTTP mirror. Next it asks for the distribution to
+get.
+
+<p>
+<example>
+ Please give the distribution tag to get or a path to the
+ package file ending in a /. The distribution
+ tags are typically something like: stable unstable frozen non-US
+
+ Distribution [stable]:
+</example>
+
+<p>
+The distribution refers to the Debian version in the archive, <em>stable</>
+refers to the latest released version and <em>unstable</> refers to the
+developmental version. <em>non-US</> is only available on some mirrors and
+refers to packages that contain encryption technology or other things that
+cannot be exported from the United States. Importing these packages into the
+US is legal however.
+<footnote>As of this writing the non-US distribution has
+not been created, the only way to access it is by specifying
+stable/binary-i386/ at this prompt and by specifying a URL ending in
+debian-non-US </footnote>
+
+<p>
+<example>
+ Please give the components to get
+ The components are typically something like: main contrib non-free
+
+ Components [main contrib non-free]:
+</example>
+
+<p>
+The components list refers to the list of sub distributions to fetch. The
+distribution is split up based on software copyright, main being DFSG free
+packages while contrib and non-free contain things that have various
+restrictions placed on their use and distribution.
+
+<p>
+Any number of sources can be added, the setup script will continue to
+prompt until you have specified all that you want.
+
+<p>
+Before starting to use <prgn>dselect</> it is necessary to update the
+available list by selecting [U]pdate from the menu. This is a super-set of
+<tt>apt-get update</> that makes the fetched information available to
+<prgn>dselect</>. [U]pdate must be performed even if <tt>apt-get update</>
+has been run before.
+
+<p>
+You can then go on and make your selections using [S]elect and then
+perform the installation using [I]nstall. When using the APT method
+the [C]onfig and [R]emove commands have no meaning, the [I]nstall command
+performs both of them together.
+
+</chapt>
+ <!-- }}} -->
+<!-- The Interfaces {{{ -->
+<!-- ===================================================================== -->
+<chapt>The Interface
+
+<p>
+Both that APT <prgn>dselect</> method and <prgn>apt-get</> share the same
+interface. It is a simple system that generally tells you what it will do
+and then goes and does it.
+<footnote>
+The <prgn>dselect</> method actually is a set of wrapper scripts
+to <prgn>apt-get</>. The method actually provides more functionality than
+is present in <prgn>apt-get</> alone.
+</footnote>
+After printing out a summary of what will happen APT then will print out some
+informative status messages so that you can estimate how far along it is and
+how much is left to do.
+
+<!-- ===================================================================== -->
+<sect>The Pre-Checks
+
+<p>
+Before all operations, except update, APT performs a number of checks on the
+systems. These are designed to safe guard the operations it is about to
+undertake. At any time the full set of checks may be run by performing
+<tt>apt-get check</>.
+<p>
+<example>
+# apt-get check
+Updating package file cache...done
+Updating package status cache...done
+Checking system integrity...ok
+</example>
+
+<p>
+The first check is to ensure that the archive package lists are matched to
+the pre-generated data cache, if they are not then the cache is automatically
+refreshed. This may fail if <tt>apt-get update</> has not been run to
+synchronize with the <em>Sources</>. The next check verifies that the state of
+the system matches the cached state and automatically rebuilds the cached
+state if they are not synchronized. This check should never fail and it
+indicates a serious error if it ever does.
+
+<p>
+The final check performs a detailed analysis of the system integrity. It
+checks every dependency of every installed or unpacked package and considers
+if it is ok. Should this find a problem then a report will be printed out and
+<prgn>apt-get</> will refuse to run.
+
+<p>
+<example>
+# apt-get check
+Updating package file cache...done
+Updating package status cache...done
+Checking system integrity...dependency error
+You might want to run apt-get -f install' to correct these.
+Sorry, but the following packages are broken - this means they have unmet
+dependencies:
+ libdbd-mysql-perl: Depends:perl
+ xzx: Depends:xlib6
+ libdbd-msql-perl: Depends:perl
+ mailpgp: Depends:pgp-i Depends:pgp-us
+ xdpkg: Depends:python
+ squake: Depends:quake-lib Depends:quake-lib-stub
+ debmake: Depends:fileutils
+ libreadlineg2: Conflicts:libreadline2
+ ssh: Depends:gmp2 Depends:xlib6g Depends:zlib1g
+</example>
+
+<p>
+In this example the system has many problems, including a serious problem
+with libreadlineg2. For each package that has unmet dependencies a line
+is printed out indicating the package with the problem and the dependencies
+that are unmet. For brevity the version inter-relationships are omitted.
+
+<p>
+There are two ways a system can get into a broken state like this. The
+first is caused by <prgn>dpkg missing</> some subtle relationships between
+packages when performing upgrades. <footnote>APT however considers all known
+dependencies and attempts to prevent broken packages</footnote>. The second is
+if a package installation fails during an operation. In this situation a
+package may have been unpacked without its dependents being installed.
+
+<p>
+The second situation is much less serious than the first because APT places
+certain assurances on the order that packages are installed. In both cases
+supplying the <tt>-f</> option to <prgn>atp-get</> will cause APT to deduce a
+possible solution to the problem and then continue on. The APT <prgn>dselect</>
+method always supplies the <tt>-f</> option to allow for easy continuation
+of failed maintainer scripts.
+
+<p>
+However, if the <tt>-f</> option is used to correct a seriously broken system
+caused by the first case then it is possible that it will either fail
+immediately or the installation sequence will fail. In either case it is
+necessary to manually use dpkg (possibly with forcing options) to correct
+the situation enough to allow APT to proceed.
+</sect>
+
+<!-- ===================================================================== -->
+<sect>The Status Report
+
+<p>
+Before proceeding <prgn>apt-get</> will present a report on what will happen.
+Generally the report reflects the type of operation being performed but there
+are several common elements. In all cases the lists reflect the final state
+of things, taking into account the <tt>-f</> option and any other relevant
+activities to the command being executed.
+
+<sect1>The Extra Package list
+<p>
+<example>
+The following extra packages will be installed:
+ libdbd-mysql-perl xlib6 zlib1 xzx libreadline2 libdbd-msql-perl
+ mailpgp xdpkg fileutils pinepgp zlib1g xlib6g perl-base
+ bin86 libgdbm1 libgdbmg1 quake-lib gmp2 bcc xbuffy
+ squake pgp-i python-base debmake ldso perl libreadlineg2
+ ssh
+</example>
+
+<p>
+The Extra Package list shows all of the packages that will be installed
+or upgraded in excess of the ones mentioned on the command line. It is
+only generated for an <tt>install</> command. The listed packages are
+often the result of an Auto Install.
+</sect1>
+
+<sect1>The Packages to Remove
+<p>
+<example>
+The following packages will be REMOVED:
+ xlib6-dev xpat2 tk40-dev xkeycaps xbattle xonix
+ xdaliclock tk40 tk41 xforms0.86 ghostview xloadimage xcolorsel
+ xadmin xboard perl-debug tkined xtetris libreadline2-dev perl-suid
+ nas xpilot xfig
+</example>
+
+<p>
+The Packages to Remove list shows all of the packages that will be
+removed from the system. It can be shown for any of the operations and
+should be given a careful inspection to ensure nothing important is to
+be taken off. The <tt>-f</> option is especially good at generating packages
+to remove so extreme care should be used in that case. The list may contain
+packages that are going to be removed because they are only
+partially removed, possibly due to an aborted installation.
+</sect1>
+
+<sect1>The New Packages list
+<p>
+<example>
+The following NEW packages will installed:
+ zlib1g xlib6g perl-base libgdbmg1 quake-lib gmp2 pgp-i python-base
+</example>
+
+<p>
+The New Packages list is simply a reminder of what will happen. The packages
+listed are not presently installed in the system but will be when APT is done.
+</sect1>
+
+<sect1>The Kept Back list
+<p>
+<example>
+The following packages have been kept back
+ compface man-db tetex-base msql libpaper svgalib1
+ gs snmp arena lynx xpat2 groff xscreensaver
+</example>
+
+<p>
+Whenever the whole system is being upgraded there is the possibility that
+new versions of packages cannot be installed because they require new things
+or conflict with already installed things. In this case the package will
+appear in the Kept Back list. The best way to convince packages listed
+there to install is with <tt>apt-get install</> or by using <prgn>dselect</>
+to resolve their problems.
+</sect1>
+
+<sect1>Held Packages warning
+<p>
+<example>
+The following held packages will be changed:
+ cvs
+</example>
+
+<p>
+Sometimes you can ask APT to install a package that is on hold, in such a
+case it prints out a warning that the held package is going to be
+changed. This should only happen during dist-upgrade or install.
+</sect1>
+
+<sect1>Final summary
+<p>
+Finally, APT will print out a summary of all the changes that will occur.
+
+<p>
+<example>
+206 packages upgraded, 8 newly installed, 23 to remove and 51 not upgraded.
+12 packages not fully installed or removed.
+Need to get 65.7M/66.7M of archives. After unpacking 26.5M will be used.
+</example>
+
+<p>
+The first line of the summary simply is a reduced version of all of the
+lists and includes the number of upgrades - that is packages already
+installed that have new versions available. The second line indicates the
+number of poorly configured packages, possibly the result of an aborted
+installation. The final line shows the space requirements that the
+installation needs. The first pair of numbers refer to the size of
+the archive files. The first number indicates the number of bytes that
+must be fetched from remote locations and the second indicates the
+total size of all the archives required. The next number indicates the
+size difference between the presently installed packages and the newly
+installed packages. It is roughly equivalent to the space required in
+/usr after everything is done. If a large number of packages are being
+removed then the value may indicate the amount of space that will be
+freed.
+
+</sect>
+
+<!-- ===================================================================== -->
+<sect>The Status Display
+<p>
+During the download of archives and package files APT prints out a series of
+status messages,
+
+<p>
+<example>
+# apt-get update
+Get http://ftp.de.debian.org/debian-non-US/ stable/binary-i386/ Packages
+Get http://llug.sep.bnl.gov/debian/ frozen/contrib Packages
+Get http://llug.sep.bnl.gov/debian/ frozen/main Packages
+Get http://ftp.de.debian.org/debian-non-US/ unstable/binary-i386/ Packages
+Get http://llug.sep.bnl.gov/debian/ frozen/non-free Packages
+11% [Packages `Waiting for file' 0/32.1k 0%] 2203b/s 1m52s
+</example>
+
+<p>
+The lines starting with <em>Get</> are printed out when APT begins to fetch
+a file while the last line indicates the progress of the download. The first
+percent value on the progress line indicates the total percent done of all
+files. Unfortunately since the size of the Package files is unknown
+<tt>apt-get update</> estimates the percent done which causes some
+inaccuracies.
+
+<p>
+The next section of the status line is repeated once for each dowload thread
+and indicates the operation being performed and some usefull information
+about what is happening. Sometimes this section will simply read <em>Forking</>
+which means the OS is loading the download module. The first word after the [
+is the short form name of the object being downloaded. For archives it will
+contain the name of the package that is being fetched.
+
+<p>
+Inside of the single quote is an informative string indicating the progress
+of the negotiation phase of the download. Typically it progresses from
+<em>Connecting</> to <em>Waiting for file</> to <em>Downloading</> or
+<em>Resuming</>. The final value is the number of bytes downloaded from the
+remote site. Once the download beings this is represented as <tt>102/10.2k</>
+indicating that 102 bytes have been fetched and 10.2 kilobytes is expected.
+The total size is always shown in 4 figure notation to preserve space. After
+the size display is a percent meter for the file itself.
+The second last element is the instantenous average speed. This values is
+updated every 5 seconds and reflects the rate of data transfer for that
+period. Finally is shown the estimated transfer time. This is updated
+regularly and reflects the time to complete everything at the shown
+transfer rate.
+
+<p>
+The status display updates every half second to provide a constant feedback
+on the download progress while the Get lines scroll back whenever a new
+file is started. Since the status display is constantly updated it is
+unsuitable for logging to a file, use the <tt>-q</> option to remove the
+status display.
+</sect>
+
+<!-- ===================================================================== -->
+<sect>Dpkg
+
+<p>
+APT uses <prgn>dpkg</> for installing the archives and will switch
+over to the <prgn>dpkg</> interface once downloading is completed.
+<prgn>dpkg</> will also as a number of questions as it processes the packages
+and the packages themselves may also ask several questions. Before each
+question there is usually a description of what it is asking and the
+questions are too varied to discuss completely here.
+</sect>
+
+</chapt>
+ <!-- }}} -->
+
+</book>
diff --git a/doc/sources.list.5 b/doc/sources.list.5
new file mode 100644
index 000000000..779f216bf
--- /dev/null
+++ b/doc/sources.list.5
@@ -0,0 +1,177 @@
+.\" $Id: sources.list.5,v 1.1 1998/07/02 02:58:12 jgg Exp $
+.\" This manpage is copyright (C) 1998 Branden Robinson <branden@debian.org>.
+.\"
+.\" This is free software; you may redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as
+.\" published by the Free Software Foundation; either version 2,
+.\" or (at your option) any later version.
+.\"
+.\" This is distributed in the hope that it will be useful, but
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public
+.\" License along with APT; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+.\" 02111-1307 USA
+.TH sources.list 5 "16 June 1998" "Debian GNU/Linux"
+.SH NAME
+sources.list \- package resource list for APT
+.SH DESCRIPTION
+The package resource list is used to locate archives of the package
+distribution system in use on the system. At this time, this manual page
+documents only the packaging system used by the Debian GNU/Linux system.
+.PP
+The source list is designed to support any number of active sources and a
+variety of source media. The file lists one source per line, with the
+most preferred source listed first. The format of each line is:
+.I type uri args
+The first item,
+.IR type ,
+determines the format for
+.IR args .
+.I uri
+is a Universal Resource Identifier (URI), which is a superset of the more
+specific and well-known Universal Resource Locator, or URL.
+.SS The deb type
+The
+.B deb
+type describes a typical two-level Debian archive,
+.IR distribution / component .
+Typically,
+.I distribution
+is one of
+.BR stable ,
+.BR unstable ,
+or
+.BR frozen ,
+while component is one of
+.BR main ,
+.BR contrib ,
+.BR non-free ,
+or
+.BR non-us .
+The format for a
+.I sources.list
+entry using the
+.B deb
+type is:
+.RS
+deb
+.I uri distribution
+.RI [ component
+.I ...
+]
+.RE
+The URI for the
+.B deb
+type must specify the base of the Debian distribution, from which
+.B APT
+will find the information it needs.
+.I distribution
+can specify an exact path, in which case the
+.IR component s
+must be omitted and
+.I distribution
+must end with a slash (/). This is useful for when only a particular
+sub-section of the archive denoted by the URI is of interest.
+If
+.I distribution
+does not specify an exact path, at least one
+.I component
+must be present.
+.PP
+.I distribution
+may also contain a variable,
+.BR $(ARCH) ,
+which expands to the Debian architecture (i386, m68k, powerpc, ...)
+used on the system. This permits archiecture-independent
+.I sources.list
+files to be used.
+.PP
+Since only one distribution can be specified per line it may be necessary
+to have multiple lines for the same URI, if a subset of all available
+distributions or components at that location is desired.
+.B APT
+will sort the URI list after it has generated a complete set internally,
+and will collapse multiple references to the same Internet host, for
+instance, into a single connection, so that it does not inefficiently
+establish an FTP connection, close it, do something else, and then
+re-establish a connection to that same host. This feature is useful
+for accessing busy FTP sites with limits on the number of simultaneous
+anonymous users.
+.PP
+It is important to list sources in order of preference, with the most
+preferred source listed first. Typically this will result in sorting
+by speed from fastest to slowest (CD-ROM followed by hosts on a local
+network, followed by distant Internet hosts, for example).
+.SS URI specification
+The three currently recognized URI types are file, http, and ftp.
+.IP file
+The file scheme allows an arbitrary directory in the file system to be
+considered an archive. This is useful for NFS mounts and local mirrors or
+archives.
+.IP http
+The http scheme specifies an HTTP server for the archive. If an environment
+variable
+.B $http_proxy
+is set with the format
+.\" Ugly hackery ahead, nroff doesn't like three different typefaces in a
+.\" row with no spaces between anything.
+.BI http:// server : port /\c
+, the proxy server specified in
+.B $http_proxy
+will be used. Users of
+authenticated HTTP/1.1 proxies may use a string of the format
+.BI http:// user : pass @ server : port /\c
+.\" For some reason, starting the next line with \. didn't work. So we kludge.
+\&. Note that this is an insecure method of authentication.
+.IP ftp
+The ftp scheme specifies an FTP server for the archive. APT's FTP behavior
+is highly configurable; for more information see the
+.BR ftp.conf (5)
+manual page.
+.SH EXAMPLES
+.IP "deb file:/home/jason/debian stable main contrib non-free"
+Uses the archive stored locally (or NFS mounted) at
+.I /home/jason/debian
+for stable/main, stable/contrib, and stable/non-free.
+.IP "deb file:/home/jason/debian unstable main contrib non-free"
+As above, except this uses the unstable (development) distribution.
+.IP "deb http://www.debian.org/archive stable main"
+Uses HTTP to access the archive at www.debian.org, and uses only the
+stable/main area.
+.IP "deb ftp://ftp.debian.org/debian stable contrib"
+Uses FTP to access the archive at ftp.debian.org, under the debian
+directory, and uses only the stable/contrib area.
+.IP "deb ftp://ftp.debian.org/debian unstable contrib"
+Uses FTP to access the archive at ftp.debian.org, under the debian
+directory, and uses only the unstable/contrib area. If this line appears as
+well as the one in the previous example in
+.IR sources.list ,
+a single FTP session will be used for both resource lines.
+.IP "deb ftp://nonus.debian.org/debian-non-US unstable/binary-i386/"
+Uses FTP to access the archive at nonus.debian.org, under the debian-non-US
+directory, and uses only files found under unstable/binary-i386.
+.IP "deb http://ftp.de.debian.org/debian-non-US unstable/binary-$(ARCH)/"
+Uses HTTP to access the archive at nonus.debian.org, under the
+debian-non-US directory, and uses only files found under
+unstable/binary-i386 on i386 machines, unstable/binary-m68k on m68k, and so
+forth for other supported architectures.
+.SH SEE ALSO
+.BR apt (8),
+.BR apt-cache (8),
+.BR apt-get (8),
+.BR ftp.conf (5)
+.SH BUGS
+See <http://www.debian.org/Bugs/db/pa/lapt.html>. If you wish to report a
+bug in
+.BR apt-get ,
+please see
+.I /usr/doc/debian/bug-reporting.txt
+or the
+.BR bug (1)
+command.
+.SH AUTHOR
+APT was written by the APT team <apt@packages.debian.org>.