Base revisions
authorArch Librarian <arch@canonical.com>
Mon, 20 Sep 2004 16:50:36 +0000 (16:50 +0000)
committerArch Librarian <arch@canonical.com>
Mon, 20 Sep 2004 16:50:36 +0000 (16:50 +0000)
Author: jgg
Date: 1998-07-02 02:58:12 GMT
Base revisions

26 files changed:
apt-pkg/cacheiterators.h [new file with mode: 0644]
apt-pkg/contrib/error.cc [new file with mode: 0644]
apt-pkg/contrib/error.h [new file with mode: 0644]
apt-pkg/contrib/fileutl.cc [new file with mode: 0644]
apt-pkg/contrib/fileutl.h [new file with mode: 0644]
apt-pkg/contrib/mmap.cc [new file with mode: 0644]
apt-pkg/contrib/mmap.h [new file with mode: 0644]
apt-pkg/contrib/system.h [new file with mode: 0644]
apt-pkg/pkgcache.cc [new file with mode: 0644]
apt-pkg/pkgcache.h [new file with mode: 0644]
apt-pkg/pkgcachegen.cc [new file with mode: 0644]
apt-pkg/pkgcachegen.h [new file with mode: 0644]
apt-pkg/tagfile.cc [new file with mode: 0644]
apt-pkg/tagfile.h [new file with mode: 0644]
apt-pkg/version.cc [new file with mode: 0644]
apt-pkg/version.h [new file with mode: 0644]
doc/apt-cache.8 [new file with mode: 0644]
doc/apt-get.8 [new file with mode: 0644]
doc/apt.8 [new file with mode: 0644]
doc/cache.sgml [new file with mode: 0644]
doc/design.sgml [new file with mode: 0644]
doc/dpkg-tech.sgml [new file with mode: 0644]
doc/files.sgml [new file with mode: 0644]
doc/ftp.conf.5 [new file with mode: 0644]
doc/guide.sgml [new file with mode: 0644]
doc/sources.list.5 [new file with mode: 0644]

diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h
new file mode 100644 (file)
index 0000000..539444c
--- /dev/null
@@ -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 (file)
index 0000000..59d2b8c
--- /dev/null
@@ -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 (file)
index 0000000..06b998e
--- /dev/null
@@ -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 (file)
index 0000000..6048ff0
--- /dev/null
@@ -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 (file)
index 0000000..1b66668
--- /dev/null
@@ -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 (file)
index 0000000..85cac1c
--- /dev/null
@@ -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 (file)
index 0000000..0963041
--- /dev/null
@@ -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 (file)
index 0000000..e652348
--- /dev/null
@@ -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 (file)
index 0000000..b75fe6d
--- /dev/null
@@ -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 (file)
index 0000000..0dc939a
--- /dev/null
@@ -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 (file)
index 0000000..cb0fd3f
--- /dev/null
@@ -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 (file)
index 0000000..1385ab9
--- /dev/null
@@ -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 (file)
index 0000000..106b0fe
--- /dev/null
@@ -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 (file)
index 0000000..a7a82dd
--- /dev/null
@@ -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 (file)
index 0000000..c02ee5f
--- /dev/null
@@ -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 (file)
index 0000000..a302469
--- /dev/null
@@ -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 (file)
index 0000000..0292973
--- /dev/null
@@ -0,0 +1,199 @@
+.\" This manpage is copyright (C) 1998 Branden Robinson <branden@debian.org>.\r
+.\" \r
+.\" This is free software; you may redistribute it and/or modify\r
+.\" it under the terms of the GNU General Public License as\r
+.\" published by the Free Software Foundation; either version 2,\r
+.\" or (at your option) any later version.\r
+.\"\r
+.\" This is distributed in the hope that it will be useful, but\r
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of\r
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+.\" GNU General Public License for more details.\r
+.\"\r
+.\" You should have received a copy of the GNU General Public\r
+.\" License along with APT; if not, write to the Free Software\r
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA \r
+.\" 02111-1307 USA\r
+.TH apt-cache 8 "16 June 1998" "Debian GNU/Linux"\r
+.SH NAME\r
+apt-cache \- APT package handling utility \(em cache manipulator\r
+.SH SYNOPSIS\r
+.B apt-cache\r
+.I command cache\r
+.RI [ argument \r
+.IR ... ]\r
+.SH DESCRIPTION\r
+.B apt-cache\r
+performs a variety of operations on APT's package cache.\r
+.I apt-cache\r
+is seldom called directly; instead it is usually invoked internally by\r
+.BR apt-get (8)\r
+or\r
+.BR apt (8).\r
+.PP\r
+.I command\r
+is one of\r
+.RS\r
+.PD 0\r
+.B add\r
+.PP\r
+.B dump\r
+.PP\r
+.B dumpavail\r
+.PP\r
+.B showpkg\r
+.PP\r
+.B stats\r
+.RE\r
+.PD 1\r
+.PP\r
+.I cache\r
+must be a package cache file (for instance,\r
+.IR /var/cache/apt/pkgcache.bin ).\r
+Some\r
+.IR command s\r
+require additional arguments.\r
+.SS add\r
+.B add\r
+adds a new set of package records to\r
+.IR cache .\r
+Remaining arguments are of the form\r
+.IR file : dist : ver ,\r
+where\r
+.I file\r
+is the full path to file in question.\r
+.I dist\r
+and\r
+.I ver\r
+can be any string and are not yet implemented.\r
+.SS dump\r
+.B dump\r
+displays information about all the packages in the cache. See\r
+.B showpkg\r
+below for an explanation of what data is output for each package.\r
+.SS dumpavail\r
+.B dumpavail\r
+generates an\r
+.I available\r
+file suitable for use with\r
+.BR dpkg (8)\r
+based on the information in the cache.\r
+.SS showpkg\r
+.B showpkg\r
+displays information about the packages listed on the command line.     \r
+Remaining arguments are package names. The available versions and       \r
+reverse dependencies of each package listed are listed, as well as      \r
+forward dependencies for each version. Forward (normal) dependencies   \r
+are those packages upon which the package in question depends; reverse  \r
+dependencies are those packages that depend upon the package in         \r
+question. Thus, forward dependencies must be satisfied for a package,  \r
+but reverse dependencies need not be.                                   \r
+For instance,\r
+.B apt-cache showpkg\r
+.I cache\r
+.B libreadline2\r
+would produce output similar to the following:\r
+.PP\r
+.RS\r
+.PD 0\r
+Package: libreadline2\r
+.PP\r
+Versions: 2.1-8,2.1-7,\r
+.PP\r
+Reverse Depends:\r
+.RS\r
+.PP\r
+libreadlineg2,libreadline2\r
+.PP\r
+libreadlineg2,libreadline2\r
+.PP\r
+libreadline2-altdev,libreadline2\r
+.RE\r
+.PP\r
+Dependencies:\r
+.PP\r
+2.1-8 - libc5 ncurses3.0 ldso\r
+.PP\r
+2.1-7 - ldso libc5 ncurses3.0\r
+.RE\r
+.PD 1\r
+.PP\r
+Thus it may be seen that libreadline2, version 2.1-8, depends on libc5,\r
+ncurses3.0, and ldso, which must be installed for libreadline2 to work. In\r
+turn, libreadlineg2 and libreadline2-altdev depend on libreadline2. If\r
+libreadline2 is installed, libc5, ncurses3.0, and ldso must also be\r
+installed; libreadlineg2 and libreadline2-altdev do not have to be\r
+installed.\r
+.SS stats\r
+.B stats\r
+displays some statistics about\r
+.IR cache .\r
+No further arguments are expected. Statistics reported are:\r
+.RS\r
+.TP\r
+.I Total package names\r
+is the number of package names found in the cache.\r
+.TP\r
+.I Normal packages\r
+is the number of regular, ordinary package names; these\r
+are packages that bear a one-to-one correspondence between their names and\r
+the names used by other packages for them in dependencies. The majority of\r
+packages fall into this category.\r
+.TP\r
+.I Pure virtual packages\r
+is the number of packages that exist only as a virtual package name; that\r
+is, packages only "provide" the virtual package name, and no package\r
+actually uses the name. For instance, "mail-transport-agent" in the Debian\r
+GNU/Linux system is a pure virtual package; several packages provide\r
+"mail-transport-agent", but there is no package named "mail-transport-agent".\r
+.TP\r
+.I Single virtual packages\r
+is the number of packages with only one package providing a particular  \r
+virtual package. For instance, in the Debian GNU/Linux system,         \r
+"X11-text-viewer" is a virtual package, but only one package, xless,    \r
+provides "X11-text-viewer".\r
+.TP\r
+.I Mixed virtual packages\r
+is the number of packages that either provide a particular virtual package\r
+or have the virtual package name as the package name. For instance, in the\r
+Debian GNU/Linux system, e2fsprogs is both an actual package, and\r
+provided by the e2compr package.\r
+.TP\r
+.I Missing\r
+is the number of package names that were referenced in a dependency but\r
+were not provided by any package. Missing packages may be in evidence\r
+if a full distribution is not accesssed, or if a package (real or virtual)\r
+has been dropped from the distribution.\r
+.TP\r
+.I Total distinct versions\r
+is the number of package versions found in the cache; this value is\r
+therefore at least equal to the number of total package names. If more than\r
+one distribution (both "stable" and "unstable", for instance), is being\r
+accessed, this value can be considerably larger than the number of total\r
+package names.\r
+.TP\r
+.I Total dependencies\r
+is the number of dependency relationships claimed by all of the packages in\r
+the cache.\r
+.RE\r
+.SH OPTIONS\r
+None.\r
+.SH FILES\r
+None.\r
+.SH SEE ALSO\r
+.BR apt (8),\r
+.BR apt-get (8),\r
+.I /usr/doc/apt/cache*\r
+.SH DIAGNOSTICS\r
+apt-cache returns zero on normal operation, decimal 100 on error.\r
+.SH BUGS\r
+See <http://www.debian.org/Bugs/db/pa/lapt.html>.  If you wish to report a\r
+bug in\r
+.BR apt-cache ,\r
+please see\r
+.I /usr/doc/debian/bug-reporting.txt\r
+or the\r
+.BR bug (1)\r
+command.\r
+.SH AUTHOR\r
+apt-cache was written by the APT team <apt@packages.debian.org>.\r
diff --git a/doc/apt-get.8 b/doc/apt-get.8
new file mode 100644 (file)
index 0000000..c53dc70
--- /dev/null
@@ -0,0 +1,250 @@
+.\" $Id: apt-get.8,v 1.1 1998/07/02 02:58:12 jgg Exp $\r
+.\" This manpage is copyright (C) 1998 Branden Robinson <branden@debian.org>.\r
+.\" \r
+.\" This is free software; you may redistribute it and/or modify\r
+.\" it under the terms of the GNU General Public License as\r
+.\" published by the Free Software Foundation; either version 2,\r
+.\" or (at your option) any later version.\r
+.\"\r
+.\" This is distributed in the hope that it will be useful, but\r
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of\r
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+.\" GNU General Public License for more details.\r
+.\"\r
+.\" You should have received a copy of the GNU General Public\r
+.\" License along with APT; if not, write to the Free Software\r
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA \r
+.\" 02111-1307 USA\r
+.TH apt-get 8 "16 June 1998" "Debian GNU/Linux"\r
+.SH NAME\r
+apt-get \- APT package handling utility \(em command-line interface\r
+.SH SYNOPSIS\r
+.B apt-get\r
+.RI [ options ]\r
+.RI [ command ]\r
+.RI [ package\r
+.IR ... ]\r
+.SH DESCRIPTION\r
+.B apt-get\r
+is the command-line tool for handling packages, and may be considered the\r
+user's "back-end" to\r
+.BR apt (8).\r
+Use\r
+.BR apt (8)\r
+if the usage of apt-get does not seem intuitive.\r
+.PP\r
+.I command\r
+is one of\r
+.RS\r
+.PD 0\r
+.B update\r
+.PP\r
+.B upgrade\r
+.PP\r
+.B dselect-upgrade\r
+.PP\r
+.B dist-upgrade\r
+.PP\r
+.B install\r
+.PP\r
+.B check\r
+.PP\r
+.B clean\r
+.RE\r
+.PD 1\r
+.PP\r
+Unless one of the\r
+.IR -h ,\r
+.IR --help ,\r
+.IR -f ,\r
+or\r
+.I --fix-broken\r
+options is given, one of the above commands must be present. Only the\r
+.B install\r
+command requires any further arguments.\r
+.SS update\r
+.B update\r
+is used to resynchronize the package overview files from their\r
+sources. The overviews of available packages are fetched from the\r
+location(s) specified in\r
+.IR /etc/apt/sources.list .\r
+For example, when using a Debian archive, this command retrieves and\r
+scans the\r
+.I Packages.gz\r
+files, so that information about new and updated packages is available. An\r
+.B update\r
+should always be performed before an\r
+.B upgrade\r
+or\r
+.BR dist-upgrade .\r
+.SS upgrade\r
+.B upgrade\r
+is used to install the newest versions of all packages currently installed\r
+on the system from the sources enumerated in\r
+.IR /etc/apt/sources.list .\r
+Packages currently installed with new versions available are retrieved\r
+and upgraded; under no circumstances are currently installed packages\r
+removed, or packages not already installed retrieved and installed. New\r
+versions of currently installed packages that cannot be upgraded without\r
+changing the install status of another package will be left at their\r
+current version. An\r
+.B update\r
+must be performed first so that\r
+.B apt-get\r
+knows that new versions of packages are available.\r
+.SS dselect-upgrade\r
+.B dselect-upgrade\r
+is used in conjunction with the traditional Debian GNU/Linux packaging\r
+front-end,\r
+.BR dselect (8). " dselect-upgrade"\r
+follows the changes made by\r
+.B dselect\r
+to the\r
+.I Status\r
+field of available packages, and performs the actions necessary to realize\r
+that state (for instance, the removal of old and the installation of new\r
+packages).\r
+.B dselect-upgrade\r
+does not attempt to intelligently address dependency issues as\r
+.B dist-upgrade\r
+or\r
+.B install\r
+do. If any dependency problems arise,\r
+.B apt-get\r
+aborts without performing any of the actions requested, even those\r
+without problems.\r
+.B dselect-upgrade\r
+is only useful to users of\r
+.B dselect\r
+and the\r
+.I .deb\r
+package file format. The\r
+.I /etc/apt/sources.list\r
+file contains a list of locations from which to retrieve desired package\r
+files.\r
+.SS dist-upgrade\r
+.BR dist-upgrade ,\r
+in addition to performing the function of\r
+.BR upgrade ,\r
+also intelligently handles changing dependencies with new versions of\r
+packages;\r
+.B apt-get\r
+has a "smart" conflict resolution system, and it will attempt to upgrade\r
+the most important packages at the expense of less important ones if\r
+necessary. The\r
+.I /etc/apt/sources.list\r
+file contains a list of locations from which to retrieve desired package\r
+files.\r
+.SS install\r
+.B install\r
+is followed by one or more\r
+.I packages\r
+desired for installation. Each\r
+.I package\r
+is a package name, not a fully qualified filename (for instance, in a\r
+Debian GNU/Linux system,\r
+.I lsdo\r
+would be the argument provided, not\r
+.IR ldso_1.9.6-2.deb ).\r
+All packages required by the package(s) specified for installation will\r
+also be retrieved and installed. The\r
+.I /etc/apt/sources.list\r
+file is used to locate the desired packages. If a hyphen is appended to\r
+the package name (with no intervening space), the identified package will\r
+be removed if it is installed. This latter feature may be used to override\r
+decisions made by apt-get's conflict resolution system.\r
+.SS check\r
+.B check\r
+is a diagnostic tool; it updates the package cache and checks for broken\r
+packages.\r
+.SS clean\r
+.B clean\r
+clears out the local repository of retrieved package files. It removes\r
+everything but the lock file from\r
+.I /var/cache/apt/archives/\r
+and\r
+.IR /var/cache/apt/archives/partial/ .\r
+When APT is used as a\r
+.BR dselect (8)\r
+method,\r
+.B\r
+clean\r
+is run automatically.  Those who do not use dselect will likely want to\r
+run\r
+.B\r
+apt-get clean\r
+from time to time to free up disk space.\r
+.SH OPTIONS\r
+.TP\r
+.IR \-d , " --download-only"\r
+Download only; package files are only retrieved, not unpacked or installed.\r
+.TP\r
+.IR \-f , " --fix-broken"\r
+Fix; attempt to correct a system with broken dependencies in            \r
+place. This option may be used alone or in conjunction with any of the  \r
+command actions, and is sometimes necessary when running APT for the    \r
+first time; APT itself does not allow broken package dependencies to    \r
+exist on a system. It is possible that a system's dependency structure  \r
+can be so corrupt as to require manual intervention (which usually      \r
+means using dselect or dpkg --remove to eliminate some of the offending \r
+packages). Use of this option together with -m is discouraged.          \r
+.TP\r
+.IR \-h , " --help"\r
+Help; display a helpful usage message and exit.\r
+.TP\r
+.IR \-m , " --ignore-missing"\r
+Ignore missing packages; If packages cannot be retrieved or fail the    \r
+integrity check after retrieval (corrupted package files), hold back    \r
+those packages and handle the result. Use of this option together with  \r
+-f is discouraged.                                                      \r
+.TP\r
+.IR \-q , " --silent"\r
+Quiet; produces output suitable for logging, omitting progress indicators.\r
+.TP\r
+.I \-qq\r
+Very quiet; no output except for errors.\r
+.TP\r
+.IR \-s , " --simulate" , " --just-print" , " --dry-run" , " --recon " , " --no-act"\r
+No action; perform a simulation of events that would occur but do not\r
+actually change the system.\r
+.TP\r
+.IR \-y , " --yes" , " --assume-yes"\r
+Automatic yes to prompts; assume "yes" as answer to all prompts and run\r
+non-interactively.\r
+.SH FILES\r
+.TP\r
+.I /etc/apt/sources.list\r
+see\r
+.BR sources.list (5)\r
+.TP\r
+.I /var/cache/apt/archives/\r
+storage area for retrieved package files\r
+.TP\r
+.I /var/cache/apt/archives/partial/\r
+storage area for package files in transit\r
+.TP\r
+.I /var/state/apt/lists/\r
+storage area for state information for each package resource specified in\r
+.I /etc/apt/sources.list\r
+.TP\r
+.I /var/state/apt/lists/partial/\r
+storage area for state information in transit\r
+.SH SEE ALSO\r
+.BR apt (8),\r
+.BR apt-cache (8),\r
+.BR dpkg (8),\r
+.BR dselect (8),\r
+.BR sources.list (5)\r
+.SH DIAGNOSTICS\r
+apt-get returns zero on normal operation, decimal 100 on error.\r
+.SH BUGS\r
+See <http://www.debian.org/Bugs/db/pa/lapt.html>.  If you wish to report a\r
+bug in\r
+.BR apt-get ,\r
+please see\r
+.I /usr/doc/debian/bug-reporting.txt\r
+or the\r
+.BR bug (1)\r
+command.\r
+.SH AUTHOR\r
+apt-get was written by the APT team <apt@packages.debian.org>.\r
diff --git a/doc/apt.8 b/doc/apt.8
new file mode 100644 (file)
index 0000000..08aa2c4
--- /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 (file)
index 0000000..43f8d4f
--- /dev/null
@@ -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 (file)
index 0000000..55fd7e5
--- /dev/null
@@ -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 (file)
index 0000000..3c01ee8
--- /dev/null
@@ -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 (file)
index 0000000..d98d6f6
--- /dev/null
@@ -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 (file)
index 0000000..30c7c03
--- /dev/null
@@ -0,0 +1,93 @@
+.\" This manpage is copyright (C) 1998 Branden Robinson <branden@debian.org>\r
+.\" and Manoj Srivastava <srivasta@datasync.com>.\r
+.\" \r
+.\" This is free software; you may redistribute it and/or modify\r
+.\" it under the terms of the GNU General Public License as\r
+.\" published by the Free Software Foundation; either version 2,\r
+.\" or (at your option) any later version.\r
+.\"\r
+.\" This is distributed in the hope that it will be useful, but\r
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of\r
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+.\" GNU General Public License for more details.\r
+.\"\r
+.\" You should have received a copy of the GNU General Public\r
+.\" License along with APT; if not, write to the Free Software\r
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA \r
+.\" 02111-1307 USA\r
+.TH ftp.conf 5 "16 June 1998" "Debian GNU/Linux"\r
+.SH NAME\r
+ftp.conf \- configuration file for APT FTP method\r
+.SH DESCRIPTION\r
+The ftp.conf file determines the behavior of the FTP method for the APT\r
+packaging tool.  The syntax of the file is\r
+.IR variable = value .\r
+Quotes are not required around\r
+.IR value s.\r
+Comments start with a '#' and end at the next newline. Blank lines are  \r
+ignored. The following\r
+.I variables\r
+are understood:                        \r
+.IP Firewall\r
+is the hostname of a machine which acts as an FTP firewall. This can be \r
+overridden by an environment variable                                   \r
+.IR FTP_FIREWALL .\r
+If specified, and the given hostname cannot be directly contacted, a connection\r
+is made to the firewall machine and the string\r
+.B @hostname\r
+is appended to the login identifier. This type of setup is also known as an\r
+FTP proxy.\r
+.IP ProxyLogName\r
+is a parameter used by some firewall FTP proxies. It is used to authorize\r
+the user specified by\r
+.I ProxyLogName\r
+to send data beyond the\r
+.I Firewall\r
+machine.\r
+.IP ProxyPassword\r
+is the password used to authenticate\r
+.I ProxyLogName\r
+on the\r
+.I Firewall\r
+machine.\r
+.IP TimeOut\r
+sets a timeout value in seconds (the default is sixty seconds).\r
+.IP Passive\r
+is either\r
+.B true\r
+or\r
+.BR false .\r
+If true, then all data transfers will be done using passive mode. This is\r
+required for some dumb FTP servers and firewall configurations. It can\r
+also be overridden by the environment variable\r
+.IR FTP_PASSIVE .\r
+.IP Verbose\r
+is either\r
+.B true\r
+or\r
+.B false,\r
+and makes the FTP method output more data than it normally does.\r
+.IP Debug\r
+is either\r
+.B true\r
+or\r
+.B false,\r
+and makes the FTP method output debugging information. This variable is \r
+not currently implemented.                                              \r
+.IP MaxReTry\r
+sets the number of times a connection is re-tried before giving up (the\r
+default is twice).\r
+.SH SEE ALSO\r
+.BR apt (8),\r
+.BR apt-get (8)\r
+.SH BUGS\r
+See <http://www.debian.org/Bugs/db/pa/lapt.html>.  If you wish to report a\r
+bug in\r
+.BR apt-get ,\r
+please see\r
+.I /usr/doc/debian/bug-reporting.txt\r
+or the\r
+.BR bug (1)\r
+command.\r
+.SH AUTHOR\r
+APT was written by the APT team <apt@packages.debian.org>.\r
diff --git a/doc/guide.sgml b/doc/guide.sgml
new file mode 100644 (file)
index 0000000..bbc01b7
--- /dev/null
@@ -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 (file)
index 0000000..779f216
--- /dev/null
@@ -0,0 +1,177 @@
+.\" $Id: sources.list.5,v 1.1 1998/07/02 02:58:12 jgg Exp $\r
+.\" This manpage is copyright (C) 1998 Branden Robinson <branden@debian.org>.\r
+.\" \r
+.\" This is free software; you may redistribute it and/or modify\r
+.\" it under the terms of the GNU General Public License as\r
+.\" published by the Free Software Foundation; either version 2,\r
+.\" or (at your option) any later version.\r
+.\"\r
+.\" This is distributed in the hope that it will be useful, but\r
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of\r
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+.\" GNU General Public License for more details.\r
+.\"\r
+.\" You should have received a copy of the GNU General Public\r
+.\" License along with APT; if not, write to the Free Software\r
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA \r
+.\" 02111-1307 USA\r
+.TH sources.list 5 "16 June 1998" "Debian GNU/Linux"\r
+.SH NAME\r
+sources.list \- package resource list for APT\r
+.SH DESCRIPTION\r
+The package resource list is used to locate archives of the package\r
+distribution system in use on the system. At this time, this manual page\r
+documents only the packaging system used by the Debian GNU/Linux system.\r
+.PP\r
+The source list is designed to support any number of active sources and a\r
+variety of source media. The file lists one source per line, with the\r
+most preferred source listed first. The format of each line is:\r
+.I type uri args\r
+The first item,\r
+.IR type ,\r
+determines the format for\r
+.IR args .\r
+.I uri\r
+is a Universal Resource Identifier (URI), which is a superset of the more\r
+specific and well-known Universal Resource Locator, or URL.\r
+.SS The deb type\r
+The\r
+.B deb\r
+type describes a typical two-level Debian archive,\r
+.IR distribution / component .\r
+Typically,\r
+.I distribution\r
+is one of\r
+.BR stable ,\r
+.BR unstable ,\r
+or\r
+.BR frozen ,\r
+while component is one of\r
+.BR main ,\r
+.BR contrib ,\r
+.BR non-free ,\r
+or\r
+.BR non-us .\r
+The format for a\r
+.I sources.list\r
+entry using the\r
+.B deb\r
+type is:\r
+.RS\r
+deb\r
+.I uri distribution\r
+.RI [ component\r
+.I ...\r
+]\r
+.RE\r
+The URI for the\r
+.B deb\r
+type must specify the base of the Debian distribution, from which\r
+.B APT\r
+will find the information it needs.\r
+.I distribution\r
+can specify an exact path, in which case the\r
+.IR component s\r
+must be omitted and\r
+.I distribution\r
+must end with a slash (/). This is useful for when only a particular\r
+sub-section of the archive denoted by the URI is of interest.\r
+If\r
+.I distribution\r
+does not specify an exact path, at least one\r
+.I component\r
+must be present.\r
+.PP\r
+.I distribution\r
+may also contain a variable, \r
+.BR $(ARCH) ,\r
+which expands to the Debian architecture (i386, m68k, powerpc, ...)     \r
+used on the system. This permits archiecture-independent                \r
+.I sources.list\r
+files to be used.\r
+.PP\r
+Since only one distribution can be specified per line it may be necessary\r
+to have multiple lines for the same URI, if a subset of all available\r
+distributions or components at that location is desired.\r
+.B APT\r
+will sort the URI list after it has generated a complete set internally,\r
+and will collapse multiple references to the same Internet host, for\r
+instance, into a single connection, so that it does not inefficiently\r
+establish an FTP connection, close it, do something else, and then\r
+re-establish a connection to that same host. This feature is useful\r
+for accessing busy FTP sites with limits on the number of simultaneous\r
+anonymous users.\r
+.PP\r
+It is important to list sources in order of preference, with the most\r
+preferred source listed first. Typically this will result in sorting\r
+by speed from fastest to slowest (CD-ROM followed by hosts on a local\r
+network, followed by distant Internet hosts, for example).\r
+.SS URI specification\r
+The three currently recognized URI types are file, http, and ftp.\r
+.IP file\r
+The file scheme allows an arbitrary directory in the file system to be\r
+considered an archive. This is useful for NFS mounts and local mirrors or\r
+archives.\r
+.IP http\r
+The http scheme specifies an HTTP server for the archive. If an environment\r
+variable\r
+.B $http_proxy\r
+is set with the format\r
+.\" Ugly hackery ahead, nroff doesn't like three different typefaces in a\r
+.\" row with no spaces between anything.\r
+.BI http:// server : port /\c\r
+, the proxy server specified in\r
+.B $http_proxy\r
+will be used. Users of\r
+authenticated HTTP/1.1 proxies may use a string of the format\r
+.BI http:// user : pass @ server : port /\c\r
+.\" For some reason, starting the next line with \. didn't work. So we kludge.\r
+\&. Note that this is an insecure method of authentication.\r
+.IP ftp\r
+The ftp scheme specifies an FTP server for the archive. APT's FTP behavior\r
+is highly configurable; for more information see the\r
+.BR ftp.conf (5)\r
+manual page.\r
+.SH EXAMPLES\r
+.IP "deb file:/home/jason/debian stable main contrib non-free"\r
+Uses the archive stored locally (or NFS mounted) at\r
+.I /home/jason/debian\r
+for stable/main, stable/contrib, and stable/non-free.\r
+.IP "deb file:/home/jason/debian unstable main contrib non-free"\r
+As above, except this uses the unstable (development) distribution.\r
+.IP "deb http://www.debian.org/archive stable main"\r
+Uses HTTP to access the archive at www.debian.org, and uses only the\r
+stable/main area.\r
+.IP "deb ftp://ftp.debian.org/debian stable contrib"\r
+Uses FTP to access the archive at ftp.debian.org, under the debian\r
+directory, and uses only the stable/contrib area.\r
+.IP "deb ftp://ftp.debian.org/debian unstable contrib"\r
+Uses FTP to access the archive at ftp.debian.org, under the debian\r
+directory, and uses only the unstable/contrib area. If this line appears as\r
+well as the one in the previous example in\r
+.IR sources.list ,\r
+a single FTP session will be used for both resource lines.\r
+.IP "deb ftp://nonus.debian.org/debian-non-US unstable/binary-i386/"\r
+Uses FTP to access the archive at nonus.debian.org, under the debian-non-US\r
+directory, and uses only files found under unstable/binary-i386.\r
+.IP "deb http://ftp.de.debian.org/debian-non-US unstable/binary-$(ARCH)/"\r
+Uses HTTP to access the archive at nonus.debian.org, under the\r
+debian-non-US directory, and uses only files found under\r
+unstable/binary-i386 on i386 machines, unstable/binary-m68k on m68k, and so\r
+forth for other supported architectures.\r
+.SH SEE ALSO\r
+.BR apt (8),\r
+.BR apt-cache (8),\r
+.BR apt-get (8),\r
+.BR ftp.conf (5)\r
+.SH BUGS\r
+See <http://www.debian.org/Bugs/db/pa/lapt.html>.  If you wish to report a\r
+bug in\r
+.BR apt-get ,\r
+please see\r
+.I /usr/doc/debian/bug-reporting.txt\r
+or the\r
+.BR bug (1)\r
+command.\r
+.SH AUTHOR\r
+APT was written by the APT team <apt@packages.debian.org>.\r