From 578bfd0aed2ec993f4ad85fa6a7094a852261422 Mon Sep 17 00:00:00 2001 From: Arch Librarian Date: Mon, 20 Sep 2004 16:50:36 +0000 Subject: Base revisions Author: jgg Date: 1998-07-02 02:58:12 GMT Base revisions --- apt-pkg/cacheiterators.h | 281 +++++++++++++++++ apt-pkg/contrib/error.cc | 139 +++++++++ apt-pkg/contrib/error.h | 84 +++++ apt-pkg/contrib/fileutl.cc | 214 +++++++++++++ apt-pkg/contrib/fileutl.h | 63 ++++ apt-pkg/contrib/mmap.cc | 227 ++++++++++++++ apt-pkg/contrib/mmap.h | 92 ++++++ apt-pkg/contrib/system.h | 57 ++++ apt-pkg/pkgcache.cc | 360 +++++++++++++++++++++ apt-pkg/pkgcache.h | 280 +++++++++++++++++ apt-pkg/pkgcachegen.cc | 184 +++++++++++ apt-pkg/pkgcachegen.h | 69 ++++ apt-pkg/tagfile.cc | 195 ++++++++++++ apt-pkg/tagfile.h | 64 ++++ apt-pkg/version.cc | 249 +++++++++++++++ apt-pkg/version.h | 45 +++ doc/apt-cache.8 | 199 ++++++++++++ doc/apt-get.8 | 250 +++++++++++++++ doc/apt.8 | 50 +++ doc/cache.sgml | 761 +++++++++++++++++++++++++++++++++++++++++++++ doc/design.sgml | 411 ++++++++++++++++++++++++ doc/dpkg-tech.sgml | 509 ++++++++++++++++++++++++++++++ doc/files.sgml | 491 +++++++++++++++++++++++++++++ doc/ftp.conf.5 | 93 ++++++ doc/guide.sgml | 548 ++++++++++++++++++++++++++++++++ doc/sources.list.5 | 177 +++++++++++ 26 files changed, 6092 insertions(+) create mode 100644 apt-pkg/cacheiterators.h create mode 100644 apt-pkg/contrib/error.cc create mode 100644 apt-pkg/contrib/error.h create mode 100644 apt-pkg/contrib/fileutl.cc create mode 100644 apt-pkg/contrib/fileutl.h create mode 100644 apt-pkg/contrib/mmap.cc create mode 100644 apt-pkg/contrib/mmap.h create mode 100644 apt-pkg/contrib/system.h create mode 100644 apt-pkg/pkgcache.cc create mode 100644 apt-pkg/pkgcache.h create mode 100644 apt-pkg/pkgcachegen.cc create mode 100644 apt-pkg/pkgcachegen.h create mode 100644 apt-pkg/tagfile.cc create mode 100644 apt-pkg/tagfile.h create mode 100644 apt-pkg/version.cc create mode 100644 apt-pkg/version.h create mode 100644 doc/apt-cache.8 create mode 100644 doc/apt-get.8 create mode 100644 doc/apt.8 create mode 100644 doc/cache.sgml create mode 100644 doc/design.sgml create mode 100644 doc/dpkg-tech.sgml create mode 100644 doc/files.sgml create mode 100644 doc/ftp.conf.5 create mode 100644 doc/guide.sgml create mode 100644 doc/sources.list.5 diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h new file mode 100644 index 000000000..539444c33 --- /dev/null +++ b/apt-pkg/cacheiterators.h @@ -0,0 +1,281 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: cacheiterators.h,v 1.1 1998/07/02 02:58:12 jgg Exp $ +/* ###################################################################### + + Cache Iterators - Iterators for navigating the cache structure + + The iterators all provides ++,==,!=,->,* and end for their type. + The end function can be used to tell if the list has been fully + traversed. + + Unlike STL iterators these contain helper functions to access the data + that is being iterated over. This is because the data structures can't + be formed in a manner that is intuitive to use and also mmapable. + + For each variable in the target structure that would need a translation + to be accessed correctly a translating function of the same name is + present in the iterator. If applicable the translating function will + return an iterator. + + The DepIterator can iterate over two lists, a list of 'version depends' + or a list of 'package reverse depends'. The type is determined by the + structure passed to the constructor, which should be the structure + that has the depends pointer as a member. + + This header is not user includable, please use pkglib/pkgcache.h + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_CACHEITERATORS_H +#define PKGLIB_CACHEITERATORS_H + +// Package Iterator +class pkgCache::PkgIterator +{ + Package *Pkg; + pkgCache *Owner; + long HashIndex; + + public: + + enum OkState {NeedsNothing,NeedsUnpack,NeedsConfigure}; + + // Iteration + void operator ++(int); + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Owner == 0 || Pkg == Owner->PkgP?true:false;}; + + // Comparison + inline bool operator ==(const PkgIterator &B) const {return Pkg == B.Pkg;}; + inline bool operator !=(const PkgIterator &B) const {return Pkg != B.Pkg;}; + + // Accessors + inline Package *operator ->() {return Pkg;}; + inline Package const *operator ->() const {return Pkg;}; + inline Package const &operator *() const {return *Pkg;}; + inline operator Package *() {return Pkg == Owner->PkgP?0:Pkg;}; + inline operator Package const *() const {return Pkg == Owner->PkgP?0:Pkg;}; + inline const char *Name() const {return Pkg->Name == 0?0:Owner->StrP + Pkg->Name;}; + inline const char *Section() const {return Pkg->Section == 0?0:Owner->StrP + Pkg->Section;}; + inline const char *TargetDist() const {return Pkg->TargetDist == 0?0:Owner->StrP + Pkg->TargetDist;}; + inline VerIterator VersionList() const; + inline VerIterator TargetVer() const; + inline VerIterator CurrentVer() const; + inline DepIterator RevDependsList() const; + inline PrvIterator ProvidesList() const; + OkState State() const; + + // Constructors + inline PkgIterator(pkgCache &Owner) : Owner(&Owner), HashIndex(-1) + { + Pkg = Owner.PkgP; + operator ++(0); + }; + inline PkgIterator(pkgCache &Owner,Package *Trg) : Pkg(Trg), Owner(&Owner), + HashIndex(0) + { + if (Pkg == 0) + Pkg = Owner.PkgP; + }; + inline PkgIterator() : Pkg(0), Owner(0), HashIndex(0) {}; +}; + +// Version Iterator +class pkgCache::VerIterator +{ + Version *Ver; + pkgCache &Owner; + + void _dummy(); + + public: + + // Iteration + void operator ++(int) {if (Ver != Owner.VerP) Ver = Owner.VerP + Ver->NextVer;}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Ver == Owner.VerP?true:false;}; + inline void operator =(const VerIterator &B) {Ver = B.Ver;}; + + // Comparison + inline bool operator ==(const VerIterator &B) const {return Ver == B.Ver;}; + inline bool operator !=(const VerIterator &B) const {return Ver != B.Ver;}; + int CompareVer(const VerIterator &B) const; + + // Accessors + inline Version *operator ->() {return Ver;}; + inline Version const *operator ->() const {return Ver;}; + inline Version &operator *() {return *Ver;}; + inline Version const &operator *() const {return *Ver;}; + inline operator Version *() {return Ver == Owner.VerP?0:Ver;}; + inline operator Version const *() const {return Ver == Owner.VerP?0:Ver;}; + inline const char *VerStr() const {return Ver->VerStr == 0?0:Owner.StrP + Ver->VerStr;}; + inline const char *Section() const {return Ver->Section == 0?0:Owner.StrP + Ver->Section;}; + inline PkgFileIterator File() const; + inline PkgIterator ParentPkg() const {return PkgIterator(Owner,Owner.PkgP + Ver->ParentPkg);}; + inline DepIterator DependsList() const; + inline PrvIterator ProvidesList() const; + + inline VerIterator(pkgCache &Owner,Version *Trg) : Ver(Trg), Owner(Owner) + { + if (Ver == 0) + Ver = Owner.VerP; + }; +}; + +// Dependency iterator +class pkgCache::DepIterator +{ + Dependency *Dep; + enum {DepVer, DepRev} Type; + pkgCache *Owner; + + void _dummy(); + + public: + + // Iteration + void operator ++(int) {if (Dep != Owner->DepP) Dep = Owner->DepP + + (Type == DepVer?Dep->NextDepends:Dep->NextRevDepends);}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Owner == 0 || Dep == Owner->DepP?true:false;}; + + // Comparison + inline bool operator ==(const DepIterator &B) const {return Dep == B.Dep;}; + inline bool operator !=(const DepIterator &B) const {return Dep != B.Dep;}; + + // Accessors + inline Dependency *operator ->() {return Dep;}; + inline Dependency const *operator ->() const {return Dep;}; + inline Dependency &operator *() {return *Dep;}; + inline Dependency const &operator *() const {return *Dep;}; + inline operator Dependency *() {return Dep == Owner->DepP?0:Dep;}; + inline operator Dependency const *() const {return Dep == Owner->DepP?0:Dep;}; + inline const char *TargetVer() const {return Dep->Version == 0?0:Owner->StrP + Dep->Version;}; + inline PkgIterator TargetPkg() {return PkgIterator(*Owner,Owner->PkgP + Dep->Package);}; + Version **AllTargets(); + bool SmartTargetPkg(PkgIterator &Result); + inline PkgIterator SmartTargetPkg() {PkgIterator R(*Owner);SmartTargetPkg(R);return R;}; + inline VerIterator ParentVer() {return VerIterator(*Owner,Owner->VerP + Dep->ParentVer);}; + inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Dep->ParentVer].ParentPkg);}; + bool IsCritical(); + inline bool Reverse() {return Type == DepRev;}; + + inline DepIterator(pkgCache &Owner,Dependency *Trg,Version * = 0) : + Dep(Trg), Type(DepVer), Owner(&Owner) + { + if (Dep == 0) + Dep = Owner.DepP; + }; + inline DepIterator(pkgCache &Owner,Dependency *Trg,Package *) : + Dep(Trg), Type(DepRev), Owner(&Owner) + { + if (Dep == 0) + Dep = Owner.DepP; + }; + inline DepIterator() : Dep(0), Type(DepVer), Owner(0) {}; +}; + +// Provides iterator +class pkgCache::PrvIterator +{ + Provides *Prv; + enum {PrvVer, PrvPkg} Type; + pkgCache *Owner; + + void _dummy(); + + public: + + // Iteration + void operator ++(int) {if (Prv != Owner->ProvideP) Prv = Owner->ProvideP + + (Type == PrvVer?Prv->NextPkgProv:Prv->NextProvides);}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Prv == Owner->ProvideP?true:false;}; + + // Comparison + inline bool operator ==(const PrvIterator &B) const {return Prv == B.Prv;}; + inline bool operator !=(const PrvIterator &B) const {return Prv != B.Prv;}; + + // Accessors + inline Provides *operator ->() {return Prv;}; + inline Provides const *operator ->() const {return Prv;}; + inline Provides &operator *() {return *Prv;}; + inline Provides const &operator *() const {return *Prv;}; + inline operator Provides *() {return Prv == Owner->ProvideP?0:Prv;}; + inline operator Provides const *() const {return Prv == Owner->ProvideP?0:Prv;}; + inline const char *Name() const {return Owner->StrP + Owner->PkgP[Prv->ParentPkg].Name;}; + inline const char *ProvideVersion() const {return Prv->ProvideVersion == 0?0:Owner->StrP + Prv->ProvideVersion;}; + inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Prv->ParentPkg);}; + inline VerIterator OwnerVer() {return VerIterator(*Owner,Owner->VerP + Prv->Version);}; + inline PkgIterator OwnerPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Prv->Version].ParentPkg);}; + + inline PrvIterator(pkgCache &Owner,Provides *Trg,Version *) : + Prv(Trg), Type(PrvVer), Owner(&Owner) + { + if (Prv == 0) + Prv = Owner.ProvideP; + }; + inline PrvIterator(pkgCache &Owner,Provides *Trg,Package *) : + Prv(Trg), Type(PrvPkg), Owner(&Owner) + { + if (Prv == 0) + Prv = Owner.ProvideP; + }; +}; + +// Package file +class pkgCache::PkgFileIterator +{ + pkgCache *Owner; + PackageFile *File; + + public: + + // Iteration + void operator ++(int) {if (File!= Owner->PkgFileP) File = Owner->PkgFileP + File->NextFile;}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return File == Owner->PkgFileP?true:false;}; + + // Comparison + inline bool operator ==(const PkgFileIterator &B) const {return File == B.File;}; + inline bool operator !=(const PkgFileIterator &B) const {return File != B.File;}; + + // Accessors + inline PackageFile *operator ->() {return File;}; + inline PackageFile const *operator ->() const {return File;}; + inline PackageFile const &operator *() const {return *File;}; + inline operator PackageFile *() {return File == Owner->PkgFileP?0:File;}; + inline operator PackageFile const *() const {return File == Owner->PkgFileP?0:File;}; + + inline const char *FileName() const {return File->FileName == 0?0:Owner->StrP + File->FileName;}; + inline const char *Version() const {return File->Version == 0?0:Owner->StrP + File->Version;}; + inline const char *Distribution() const {return File->Distribution == 0?0:Owner->StrP + File->Distribution;}; + + bool IsOk(); + + // Constructors + inline PkgFileIterator(pkgCache &Owner) : Owner(&Owner), File(Owner.PkgFileP + Owner.Head().FileList) {}; + inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Owner(&Owner), File(Trg) {}; +}; + +// Inlined Begin functions cant be in the class because of order problems +inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const + {return VerIterator(*Owner,Owner->VerP + Pkg->VersionList);}; +inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const + {return VerIterator(*Owner,Owner->VerP + Pkg->CurrentVer);}; +inline pkgCache::VerIterator pkgCache::PkgIterator::TargetVer() const + {return VerIterator(*Owner,Owner->VerP + Pkg->TargetVer);}; +inline pkgCache::DepIterator pkgCache::PkgIterator::RevDependsList() const + {return DepIterator(*Owner,Owner->DepP + Pkg->RevDepends,Pkg);}; +inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const + {return PrvIterator(*Owner,Owner->ProvideP + Pkg->ProvidesList,Pkg);}; +inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const + {return PrvIterator(Owner,Owner.ProvideP + Ver->ProvidesList,Ver);}; +inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const + {return DepIterator(Owner,Owner.DepP + Ver->DependsList,Ver);}; +inline pkgCache::PkgFileIterator pkgCache::VerIterator::File() const + {return PkgFileIterator(Owner,Owner.PkgFileP + Ver->File);}; + +#endif diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc new file mode 100644 index 000000000..59d2b8c8b --- /dev/null +++ b/apt-pkg/contrib/error.cc @@ -0,0 +1,139 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: error.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + Global Erorr Class - Global error mechanism + + We use a simple STL vector to store each error record. A PendingFlag + is kept which indicates when the vector contains a Sever error. + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include + +#include + /*}}}*/ + +GlobalError *_error = new GlobalError; + +// GlobalError::GlobalError - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +GlobalError::GlobalError() : PendingFlag(false) +{ +} + /*}}}*/ +// GlobalError::Errno - Get part of the error string from errno /*{{{*/ +// --------------------------------------------------------------------- +/* Function indicates the stdlib function that failed and Description is + a user string that leads the text. Form is: + Description - Function (errno: strerror) + Carefull of the buffer overrun, sprintf. + */ +bool GlobalError::Errno(const char *Function,const char *Description,...) +{ + va_list args; + va_start(args,Description); + + // sprintf the description + char S[400]; + vsprintf(S,Description,args); + sprintf(S + strlen(S)," - %s (%i %s)",Function,errno,strerror(errno)); + + // Put it on the list + Item Itm; + Itm.Text = S; + Itm.Error = true; + List.push_back(Itm); + + PendingFlag = true; + + return false; +} + /*}}}*/ +// GlobalError::Error - Add an error to the list /*{{{*/ +// --------------------------------------------------------------------- +/* Just vsprintfs and pushes */ +bool GlobalError::Error(const char *Description,...) +{ + va_list args; + va_start(args,Description); + + // sprintf the description + char S[400]; + vsprintf(S,Description,args); + + // Put it on the list + Item Itm; + Itm.Text = S; + Itm.Error = true; + List.push_back(Itm); + + PendingFlag = true; + + return false; +} + /*}}}*/ +// GlobalError::Warning - Add a warning to the list /*{{{*/ +// --------------------------------------------------------------------- +/* This doesn't set the pending error flag */ +bool GlobalError::Warning(const char *Description,...) +{ + va_list args; + va_start(args,Description); + + // sprintf the description + char S[400]; + vsprintf(S,Description,args); + + // Put it on the list + Item Itm; + Itm.Text = S; + Itm.Error = false; + List.push_back(Itm); + + return false; +} + /*}}}*/ +// GlobalError::PopMessage - Pulls a single message out /*{{{*/ +// --------------------------------------------------------------------- +/* This should be used in a loop checking empty() each cycle. It returns + true if the message is an error. */ +bool GlobalError::PopMessage(string &Text) +{ + bool Ret = List.front().Error; + Text = List.front().Text; + List.erase(List.begin()); + + // This really should check the list to see if only warnings are left.. + if (empty()) + PendingFlag = false; + + return Ret; +} + /*}}}*/ +// GlobalError::DumpErrors - Dump all of the errors/warns to cerr /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void GlobalError::DumpErrors() +{ + // Print any errors or warnings found + string Err; + while (empty() == false) + { + bool Type = PopMessage(Err); + if (Type == true) + cerr << "E: " << Err << endl; + else + cerr << "W: " << Err << endl; + } +} + /*}}}*/ diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h new file mode 100644 index 000000000..06b998e5e --- /dev/null +++ b/apt-pkg/contrib/error.h @@ -0,0 +1,84 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: error.h,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + Global Erorr Class - Global error mechanism + + This class has a single global instance. When a function needs to + generate an error condition, such as a read error, it calls a member + in this class to add the error to a stack of errors. + + By using a stack the problem with a scheme like errno is removed and + it allows a very detailed account of what went wrong to be transmitted + to the UI for display. (Errno has problems because each function sets + errno to 0 if it didn't have an error thus eraseing erno in the process + of cleanup) + + Several predefined error generators are provided to handle common + things like errno. The general idea is that all methods return a bool. + If the bool is true then things are OK, if it is false then things + should start being undone and the stack should unwind under program + control. + + A Warning should not force the return of false. Things did not fail, but + they might have had unexpected problems. Errors are stored in a FIFO + so Pop will return the first item.. + + I have some thoughts about extending this into a more general UI<-> + Engine interface, ie allowing the Engine to say 'The disk is full' in + a dialog that says 'Panic' and 'Retry'.. The error generator functions + like errno, Warning and Error return false always so this is normal: + if (open(..)) + return _error->Errno(..); + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_ERROR_H +#define PKGLIB_ERROR_H + +#include +#include + +class GlobalError +{ + struct Item + { + string Text; + bool Error; + }; + + vector List; + bool PendingFlag; + + public: + + // Call to generate an error from a library call. + bool Errno(const char *Function,const char *Description,...); + + /* A warning should be considered less severe than an error, and may be + ignored by the client. */ + bool Error(const char *Description,...); + bool Warning(const char *Description,...); + + // Simple accessors + inline bool PendingError() {return PendingFlag;}; + inline bool empty() {return List.empty();}; + bool PopMessage(string &Text); + void Discard() {List.erase(List.begin(),List.end()); PendingFlag = false;}; + + // Usefull routine to dump to cerr + void DumpErrors(); + + GlobalError(); +}; + +/* The 'extra-ansi' syntax is used to help with collisions. This is the + single global instance of this class. */ +extern GlobalError *_error; + +#endif diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc new file mode 100644 index 000000000..6048ff0bb --- /dev/null +++ b/apt-pkg/contrib/fileutl.cc @@ -0,0 +1,214 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: fileutl.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + File Utilities + + CopyFile - Buffered copy of a single file + GetLock - dpkg compatible lock file manipulation (fcntl) + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include + +#include +#include +#include +#include + /*}}}*/ + +// CopyFile - Buffered copy of a file /*{{{*/ +// --------------------------------------------------------------------- +/* The caller is expected to set things so that failure causes erasure */ +bool CopyFile(File From,File To) +{ + if (From.IsOpen() == false || To.IsOpen() == false) + return false; + + // Buffered copy between fds + unsigned char *Buf = new unsigned char[64000]; + long Size; + while ((Size = read(From.Fd(),Buf,64000)) > 0) + { + if (To.Write(Buf,Size) == false) + { + delete [] Buf; + return false; + } + } + + delete [] Buf; + return true; +} + /*}}}*/ +// GetLock - Gets a lock file /*{{{*/ +// --------------------------------------------------------------------- +/* This will create an empty file of the given name and lock it. Once this + is done all other calls to GetLock in any other process will fail with + -1. The return result is the fd of the file, the call should call + close at some time. */ +int GetLock(string File,bool Errors) +{ + int FD = open(File.c_str(),O_RDWR | O_CREAT | O_TRUNC,0640); + if (FD < 0) + { + if (Errors == true) + _error->Errno("open","Could not open lock file %s",File.c_str()); + return -1; + } + + // Aquire a write lock + struct flock fl; + fl.l_type= F_WRLCK; + fl.l_whence= SEEK_SET; + fl.l_start= 0; + fl.l_len= 1; + if (fcntl(FD,F_SETLK,&fl) == -1) + { + if (Errors == true) + _error->Errno("open","Could not get lock %s",File.c_str()); + close(FD); + return -1; + } + + return FD; +} + /*}}}*/ +// FileExists - Check if a file exists /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool FileExists(string File) +{ + struct stat Buf; + if (stat(File.c_str(),&Buf) != 0) + return false; + return true; +} + /*}}}*/ +// SafeGetCWD - This is a safer getcwd that returns a dynamic string /*{{{*/ +// --------------------------------------------------------------------- +/* We return / on failure. */ +string SafeGetCWD() +{ + // Stash the current dir. + char S[300]; + S[0] = 0; + if (getcwd(S,sizeof(S)) == 0) + return "/"; + return S; +} + /*}}}*/ + +// File::File - Open a file /*{{{*/ +// --------------------------------------------------------------------- +/* The most commonly used open mode combinations are given with Mode */ +File::File(string FileName,OpenMode Mode, unsigned long Perms) +{ + Flags = 0; + switch (Mode) + { + case ReadOnly: + iFd = open(FileName.c_str(),O_RDONLY); + break; + + case WriteEmpty: + unlink(FileName.c_str()); + iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_EXCL,Perms); + break; + + case WriteExists: + iFd = open(FileName.c_str(),O_RDWR); + break; + } + + if (iFd < 0) + _error->Errno("open","Could not open file %s",FileName.c_str()); + else + this->FileName = FileName; +} + /*}}}*/ +// File::~File - Closes the file /*{{{*/ +// --------------------------------------------------------------------- +/* If the proper modes are selected then we close the Fd and possibly + unlink the file on error. */ +File::~File() +{ + Close(); +} + /*}}}*/ +// File::Read - Read a bit of the file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool File::Read(void *To,unsigned long Size) +{ + if (read(iFd,To,Size) != (signed)Size) + { + Flags |= Fail; + return _error->Errno("read","Read error"); + } + + return true; +} + /*}}}*/ +// File::Write - Write to the file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool File::Write(void *From,unsigned long Size) +{ + if (write(iFd,From,Size) != (signed)Size) + { + Flags |= Fail; + return _error->Errno("write","Write error"); + } + + return true; +} + /*}}}*/ +// File::Seek - Seek in the file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool File::Seek(unsigned long To) +{ + if (lseek(iFd,To,SEEK_SET) != (signed)To) + { + Flags |= Fail; + return _error->Error("Unable to seek to %u",To); + } + + return true; +} + /*}}}*/ +// File::Size - Return the size of the file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned long File::Size() +{ + struct stat Buf; + if (fstat(iFd,&Buf) != 0) + return _error->Errno("fstat","Unable to determine the file size"); + return Buf.st_size; +} + /*}}}*/ +// File::Close - Close the file if the close flag is set /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool File::Close() +{ + bool Res = true; + if ((Flags & AutoClose) == AutoClose) + if (close(iFd) != 0) + Res &= _error->Errno("close","Problem closing the file"); + + if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail && + FileName.empty() == false) + if (unlink(FileName.c_str()) != 0) + Res &= _error->Warning("unlnk","Problem unlinking the file"); + return Res; +} + /*}}}*/ diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h new file mode 100644 index 000000000..1b6666843 --- /dev/null +++ b/apt-pkg/contrib/fileutl.h @@ -0,0 +1,63 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: fileutl.h,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + File Utilities + + CopyFile - Buffered copy of a single file + GetLock - dpkg compatible lock file manipulation (fcntl) + FileExists - Returns true if the file exists + SafeGetCWD - Returns the CWD in a string with overrun protection + + The file class is a handy abstraction for various functions+classes + that need to accept filenames. + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_FILEUTL_H +#define PKGLIB_FILEUTL_H + +#include + +class File +{ + protected: + int iFd; + + enum LocalFlags {AutoClose = (1<<0),Fail = (1<<1),DelOnFail = (1<<2)}; + unsigned long Flags; + string FileName; + + public: + enum OpenMode {ReadOnly,WriteEmpty,WriteExists}; + + bool Read(void *To,unsigned long Size); + bool Write(void *From,unsigned long Size); + bool Seek(unsigned long To); + unsigned long Size(); + bool Close(); + + // Simple manipulators + inline int Fd() {return iFd;}; + inline bool IsOpen() {return iFd >= 0;}; + inline bool Failed() {return (Flags & Fail) == Fail;}; + inline void EraseOnFailure() {Flags |= DelOnFail;}; + inline void OpFail() {Flags |= Fail;}; + + File(string FileName,OpenMode Mode,unsigned long Perms = 0666); + File(int Fd) : iFd(Fd), Flags(AutoClose) {}; + File(int Fd,bool) : iFd(Fd), Flags(0) {}; + virtual ~File(); +}; + +bool CopyFile(string From,string To); +int GetLock(string File,bool Errors = true); +bool FileExists(string File); +string SafeGetCWD(); + +#endif diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc new file mode 100644 index 000000000..85cac1cca --- /dev/null +++ b/apt-pkg/contrib/mmap.cc @@ -0,0 +1,227 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: mmap.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + MMap Class - Provides 'real' mmap or a faked mmap using read(). + + MMap cover class. + + Some broken versions of glibc2 (libc6) have a broken definition + of mmap that accepts a char * -- all other systems (and libc5) use + void *. We can't safely do anything here that would be portable, so + libc6 generates warnings -- which should be errors, g++ isn't properly + strict. + + The configure test notes that some OS's have broken private mmap's + so on those OS's we can't use mmap. This means we have to use + configure to test mmap and can't rely on the POSIX + _POSIX_MAPPED_FILES test. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#define _BSD_SOURCE +#include +#include + +#include +#include +#include +#include +#include + /*}}}*/ + +// MMap::MMap - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +MMap::MMap(File &F,unsigned long Flags) : Fd(F), Flags(Flags), iSize(0), + Base(0) +{ + if ((Flags & NoImmMap) != NoImmMap) + Map(); +} + /*}}}*/ +// MMap::~MMap - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +MMap::~MMap() +{ + Close(true); +} + /*}}}*/ +// MMap::Map - Perform the mapping /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool MMap::Map() +{ + iSize = Fd.Size(); + + // Set the permissions. + int Prot = PROT_READ; + int Map = MAP_SHARED; + if ((Flags & ReadOnly) != ReadOnly) + Prot |= PROT_WRITE; + if ((Flags & Public) != Public) + Map = MAP_PRIVATE; + + // Map it. + Base = mmap(0,iSize,Prot,Map,Fd.Fd(),0); + if (Base == (void *)-1) + return _error->Errno("mmap","Couldn't make mmap of %u bytes",iSize); + + return true; +} + /*}}}*/ +// MMap::Close - Close the map /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool MMap::Close(bool DoClose) +{ + if (Fd.IsOpen() == false) + return true; + + Sync(); + + if (munmap((char *)Base,iSize) != 0) + _error->Warning("Unable to munmap"); + + iSize = 0; + if (DoClose == true) + Fd.Close(); + return true; +} + /*}}}*/ +// MMap::Sync - Syncronize the map with the disk /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool MMap::Sync() +{ + if ((Flags & ReadOnly) == ReadOnly) + if (msync((char *)Base,iSize,MS_SYNC) != 0) + return _error->Error("msync","Unable to write mmap"); + return true; +} + /*}}}*/ +// MMap::Sync - Syncronize a section of the file to disk /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool MMap::Sync(unsigned long Start,unsigned long Stop) +{ + if ((Flags & ReadOnly) == ReadOnly) + if (msync((char *)Base+(int)(Start/PAGE_SIZE)*PAGE_SIZE,Stop - Start,MS_SYNC) != 0) + return _error->Error("msync","Unable to write mmap"); + return true; +} + /*}}}*/ + +// DynamicMMap::DynamicMMap - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +DynamicMMap::DynamicMMap(File &F,unsigned long Flags,unsigned long WorkSpace) : + MMap(F,Flags | NoImmMap), WorkSpace(WorkSpace) +{ + unsigned long EndOfFile = Fd.Size(); + Fd.Seek(WorkSpace); + char C = 0; + Fd.Write(&C,sizeof(C)); + Map(); + iSize = EndOfFile; +} + /*}}}*/ +// DynamicMMap::~DynamicMMap - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* We truncate the file to the size of the memory data set */ +DynamicMMap::~DynamicMMap() +{ + unsigned long EndOfFile = iSize; + Close(false); + ftruncate(Fd.Fd(),EndOfFile); + Fd.Close(); +} + /*}}}*/ +// DynamicMMap::RawAllocate - Allocate a raw chunk of unaligned space /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned long DynamicMMap::RawAllocate(unsigned long Size) +{ + unsigned long Result = iSize; + iSize += Size; + + // Just in case error check + if (Result > WorkSpace) + { + _error->Error("Dynamic MMap ran out of room"); + return 0; + } + + return Result; +} + /*}}}*/ +// DynamicMMap::Allocate - Pooled aligned allocation /*{{{*/ +// --------------------------------------------------------------------- +/* This allocates an Item of size ItemSize so that it is aligned to its + size in the file. */ +unsigned long DynamicMMap::Allocate(unsigned long ItemSize) +{ + // Look for a matching pool entry + Pool *I; + Pool *Empty = 0; + for (I = Pools; I != Pools + PoolCount; I++) + { + if (I->ItemSize == 0) + Empty = I; + if (I->ItemSize == ItemSize) + break; + } + + // No pool is allocated, use an unallocated one + if (I == Pools + PoolCount) + { + // Woops, we ran out, the calling code should allocate more. + if (Empty == 0) + { + _error->Error("Ran out of allocation pools"); + return 0; + } + + I = Empty; + I->ItemSize = ItemSize; + I->Count = 0; + } + + // Out of space, allocate some more + if (I->Count == 0) + { + I->Count = 20*1024/ItemSize; + I->Start = RawAllocate(I->Count*ItemSize); + } + + I->Count--; + unsigned long Result = I->Start; + I->Start += ItemSize; + return Result/ItemSize; +} + /*}}}*/ +// DynamicMMap::WriteString - Write a string to the file /*{{{*/ +// --------------------------------------------------------------------- +/* Strings are not aligned to anything */ +unsigned long DynamicMMap::WriteString(const char *String, + unsigned long Len) +{ + unsigned long Result = iSize; + // Just in case error check + if (Result > WorkSpace) + { + _error->Error("Dynamic MMap ran out of room"); + return 0; + } + + if (Len == 0) + Len = strlen(String); + iSize += Len + 1; + memcpy((char *)Base + Result,String,Len); + ((char *)Base)[Result + Len] = 0; + return Result; +} + /*}}}*/ diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h new file mode 100644 index 000000000..096304177 --- /dev/null +++ b/apt-pkg/contrib/mmap.h @@ -0,0 +1,92 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: mmap.h,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + MMap Class - Provides 'real' mmap or a faked mmap using read(). + + The purpose of this code is to provide a generic way for clients to + access the mmap function. In enviroments that do not support mmap + from file fd's this function will use read and normal allocated + memory. + + Writing to a public mmap will always fully comit all changes when the + class is deleted. Ie it will rewrite the file, unless it is readonly + + The DynamicMMap class is used to help the on-disk data structure + generators. It provides a large allocated workspace and members + to allocate space from the workspace in an effecient fashion. + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_MMAP_H +#define PKGLIB_MMAP_H + +#include +#include + +class MMap +{ + protected: + + File &Fd; + unsigned long Flags; + unsigned long iSize; + void *Base; + + bool Map(); + bool Close(bool DoClose = true); + + public: + + enum OpenFlags {NoImmMap = (1<<0),Public = (1<<1),ReadOnly = (1<<2)}; + + // Simple accessors + inline operator void *() {return Base;}; + inline void *Data() {return Base;}; + inline unsigned long Size() {return iSize;}; + + // File manipulators + bool Sync(); + bool Sync(unsigned long Start,unsigned long Stop); + + MMap(File &F,unsigned long Flags); + virtual ~MMap(); +}; + +class DynamicMMap : public MMap +{ + public: + + // This is the allocation pool structure + struct Pool + { + unsigned long ItemSize; + unsigned long Start; + unsigned long Count; + }; + + protected: + + unsigned long WorkSpace; + Pool *Pools; + unsigned int PoolCount; + + public: + + // Allocation + unsigned long RawAllocate(unsigned long Size); + unsigned long Allocate(unsigned long ItemSize); + unsigned long WriteString(const char *String,unsigned long Len = 0); + inline unsigned long WriteString(string S) {return WriteString(S.begin(),S.size());}; + void UsePools(Pool &P,unsigned int Count) {Pools = &P; PoolCount = Count;}; + + DynamicMMap(File &F,unsigned long Flags,unsigned long WorkSpace = 1024*1024); + virtual ~DynamicMMap(); +}; + +#endif diff --git a/apt-pkg/contrib/system.h b/apt-pkg/contrib/system.h new file mode 100644 index 000000000..e652348b0 --- /dev/null +++ b/apt-pkg/contrib/system.h @@ -0,0 +1,57 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: system.h,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + System Header - Usefull private definitions + + This source is placed in the Public Domain, do with it what you will + It was originally written by Brian C. White. + + ##################################################################### */ + /*}}}*/ +// Private header +// Header section: / +#ifndef SYSTEM_H +#define SYSTEM_H + +// MIN_VAL(SINT16) will return -0x8000 and MAX_VAL(SINT16) = 0x7FFF +#define MIN_VAL(t) (((t)(-1) > 0) ? (t)( 0) : (t)(((1L<<(sizeof(t)*8-1)) ))) +#define MAX_VAL(t) (((t)(-1) > 0) ? (t)(-1) : (t)(((1L<<(sizeof(t)*8-1))-1))) + +// Min/Max functions +#if defined(__HIGHC__) +#define MIN(x,y) _min(x,y) +#define MAX(x,y) _max(x,y) +#endif + +// GNU C++ has a min/max operator +#if defined(__GNUG__) +#define MIN(A,B) ((A) ? (B)) +#endif + +/* Templates tend to mess up existing code that uses min/max because of the + strict matching requirements */ +#if !defined(MIN) +#define MIN(A,B) ((A) < (B)?(A):(B)) +#define MAX(A,B) ((A) > (B)?(A):(B)) +#endif + +/* Bound functions, bound will return the value b within the limits a-c + bounv will change b so that it is within the limits of a-c. */ +#define _bound(a,b,c) MIN(c,MAX(b,a)) +#define _boundv(a,b,c) b = _bound(a,b,c) +#define ABS(a) (((a) < (0)) ?-(a) : (a)) + +/* Usefull count macro, use on an array of things and it will return the + number of items in the array */ +#define _count(a) (sizeof(a)/sizeof(a[0])) + +// Flag Macros +#define FLAG(f) (1L << (f)) +#define SETFLAG(v,f) ((v) |= FLAG(f)) +#define CLRFLAG(v,f) ((v) &=~FLAG(f)) +#define CHKFLAG(v,f) ((v) & FLAG(f) ? true : false) + +#endif diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc new file mode 100644 index 000000000..b75fe6d94 --- /dev/null +++ b/apt-pkg/pkgcache.cc @@ -0,0 +1,360 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgcache.cc,v 1.1 1998/07/02 02:58:12 jgg Exp $ +/* ###################################################################### + + Package Cache - Accessor code for the cache + + Please see doc/pkglib/cache.sgml for a more detailed description of + this format. Also be sure to keep that file up-to-date!! + + This is the general utility functions for cache managment. They provide + a complete set of accessor functions for the cache. The cacheiterators + header contains the STL-like iterators that can be used to easially + navigate the cache as well as seemlessly dereference the mmap'd + indexes. Use these always. + + The main class provides for ways to get package indexes and some + general lookup functions to start the iterators. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include + +#include +#include +#include + /*}}}*/ + +// Cache::Header::Header - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* Simply initialize the header */ +pkgCache::Header::Header() +{ + Signature = 0x98FE76DC; + + /* Whenever the structures change the major version should be bumped, + whenever the generator changes the minor version should be bumped. */ + MajorVersion = 2; + MinorVersion = 0; + Dirty = true; + + HeaderSz = sizeof(pkgCache::Header); + PackageSz = sizeof(pkgCache::Package); + PackageFileSz = sizeof(pkgCache::PackageFile); + VersionSz = sizeof(pkgCache::Version); + DependencySz = sizeof(pkgCache::Dependency); + ProvidesSz = sizeof(pkgCache::Provides); + + PackageCount = 0; + VersionCount = 0; + DependsCount = 0; + PackageFileCount = 0; + + FileList = 0; + StringList = 0; + memset(HashTable,0,sizeof(HashTable)); + memset(Pools,0,sizeof(Pools)); +} + /*}}}*/ +// Cache::Header::CheckSizes - Check if the two headers have same *sz /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgCache::Header::CheckSizes(Header &Against) const +{ + if (HeaderSz == Against.HeaderSz && + PackageSz == Against.PackageSz && + PackageFileSz == Against.PackageFileSz && + VersionSz == Against.VersionSz && + DependencySz == Against.DependencySz && + ProvidesSz == Against.ProvidesSz) + return true; + return false; +} + /*}}}*/ + +// Cache::pkgCache - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgCache::pkgCache(MMap &Map) : Map(Map) +{ + ReMap(); +} + /*}}}*/ +// Cache::ReMap - Reopen the cache file /*{{{*/ +// --------------------------------------------------------------------- +/* If the file is already closed then this will open it open it. */ +bool pkgCache::ReMap() +{ + // Apply the typecasts. + HeaderP = (Header *)Map.Data(); + PkgP = (Package *)Map.Data(); + PkgFileP = (PackageFile *)Map.Data(); + VerP = (Version *)Map.Data(); + ProvideP = (Provides *)Map.Data(); + DepP = (Dependency *)Map.Data(); + StringItemP = (StringItem *)Map.Data(); + StrP = (char *)Map.Data(); + + cout << "Size is " << Map.Size() << endl; + if (Map.Size() == 0) + return false; + + // Check the header + Header DefHeader; + if (HeaderP->Signature != DefHeader.Signature || + HeaderP->Dirty == true) + return _error->Error("The package cache file is corrupted"); + + if (HeaderP->MajorVersion != DefHeader.MajorVersion || + HeaderP->MinorVersion != DefHeader.MinorVersion || + HeaderP->CheckSizes(DefHeader) == false) + return _error->Error("The package cache file is an incompatible version"); + + return true; +} + /*}}}*/ +// Cache::Hash - Hash a string /*{{{*/ +// --------------------------------------------------------------------- +/* This is used to generate the hash entries for the HashTable. With my + package list from bo this function gets 94% table usage on a 512 item + table (480 used items) */ +unsigned long pkgCache::sHash(string Str) +{ + unsigned long Hash = 0; + for (const char *I = Str.begin(); I != Str.end(); I++) + Hash += *I * ((Str.end() - I + 1)); + Header H; + return Hash % _count(H.HashTable); +} + +unsigned long pkgCache::sHash(const char *Str) +{ + unsigned long Hash = 0; + const char *End = Str + strlen(Str); + for (const char *I = Str; I != End; I++) + Hash += *I * ((End - I + 1)); + Header H; + return Hash % _count(H.HashTable); +} + + /*}}}*/ +// Cache::FindPkg - Locate a package by name /*{{{*/ +// --------------------------------------------------------------------- +/* Returns 0 on error, pointer to the package otherwise */ +pkgCache::PkgIterator pkgCache::FindPkg(string Name) +{ + // Look at the hash bucket + Package *Pkg = PkgP + HeaderP->HashTable[Hash(Name)]; + for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage) + { + if (Pkg->Name != 0 && StrP + Pkg->Name == Name) + return PkgIterator(*this,Pkg); + } + return PkgIterator(*this,0); +} + /*}}}*/ + +// Cache::PkgIterator - operator ++ - Postfix incr /*{{{*/ +// --------------------------------------------------------------------- +/* This will advance to the next logical package in the hash table. */ +void pkgCache::PkgIterator::operator ++(int) +{ + // Follow the current links + if (Pkg != Owner->PkgP) + Pkg = Owner->PkgP + Pkg->NextPackage; + + // Follow the hash table + while (Pkg == Owner->PkgP && HashIndex < (signed)_count(Owner->HeaderP->HashTable)) + { + HashIndex++; + Pkg = Owner->PkgP + Owner->HeaderP->HashTable[HashIndex]; + } +}; + /*}}}*/ +// Bases for iterator classes /*{{{*/ +void pkgCache::VerIterator::_dummy() {} +void pkgCache::DepIterator::_dummy() {} +void pkgCache::PrvIterator::_dummy() {} + /*}}}*/ +// PkgIterator::State - Check the State of the package /*{{{*/ +// --------------------------------------------------------------------- +/* By this we mean if it is either cleanly installed or cleanly removed. */ +pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const +{ + if (Pkg->CurrentState == pkgSTATE_UnPacked || + Pkg->CurrentState == pkgSTATE_HalfConfigured) + return NeedsConfigure; + + if (Pkg->CurrentState == pkgSTATE_UnInstalled || + Pkg->CurrentState == pkgSTATE_HalfInstalled || + Pkg->InstState != pkgSTATE_Ok) + return NeedsUnpack; + + return NeedsNothing; +} + /*}}}*/ +// DepIterator::IsCritical - Returns true if the dep is important /*{{{*/ +// --------------------------------------------------------------------- +/* Currently critical deps are defined as depends, predepends and + conflicts. */ +bool pkgCache::DepIterator::IsCritical() +{ + if (Dep->Type == pkgDEP_Conflicts || Dep->Type == pkgDEP_Depends || + Dep->Type == pkgDEP_PreDepends) + return true; + return false; +} + /*}}}*/ +// DepIterator::SmartTargetPkg - Resolve dep target pointers w/provides /*{{{*/ +// --------------------------------------------------------------------- +/* This intellegently looks at dep target packages and tries to figure + out which package should be used. This is needed to nicely handle + provide mapping. If the target package has no other providing packages + then it returned. Otherwise the providing list is looked at to + see if there is one one unique providing package if so it is returned. + Otherwise true is returned and the target package is set. The return + result indicates whether the node should be expandable */ +bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result) +{ + Result = TargetPkg(); + + // No provides at all + if (Result->ProvidesList == 0) + return false; + + // There is the Base package and the providing ones which is at least 2 + if (Result->VersionList != 0) + return true; + + /* We have to skip over indirect provisions of the package that + owns the dependency. For instance, if libc5-dev depends on the + virtual package libc-dev which is provided by libc5-dev and libc6-dev + we must ignore libc5-dev when considering the provides list. */ + PrvIterator PStart = Result.ProvidesList(); + for (; PStart.end() != true && PStart.OwnerPkg() == ParentPkg(); PStart++); + + // Nothing but indirect self provides + if (PStart.end() == true) + return false; + + // Check for single packages in the provides list + PrvIterator P = PStart; + for (; P.end() != true; P++) + { + // Skip over self provides + if (P.OwnerPkg() == ParentPkg()) + continue; + if (PStart.OwnerPkg() != P.OwnerPkg()) + break; + } + + // Check for non dups + if (P.end() != true) + return true; + Result = PStart.OwnerPkg(); + return false; +} + /*}}}*/ +// DepIterator::AllTargets - Returns the set of all possible targets /*{{{*/ +// --------------------------------------------------------------------- +/* This is a more usefull version of TargetPkg() that follows versioned + provides. It includes every possible package-version that could satisfy + the dependency. The last item in the list has a 0. */ +pkgCache::Version **pkgCache::DepIterator::AllTargets() +{ + Version **Res = 0; + unsigned long Size =0; + while (1) + { + Version **End = Res; + PkgIterator DPkg = TargetPkg(); + + // Walk along the actual package providing versions + for (VerIterator I = DPkg.VersionList(); I.end() == false; I++) + { + if (pkgCheckDep(TargetVer(),I.VerStr(),Dep->CompareOp) == false) + continue; + + if (Dep->Type == pkgDEP_Conflicts && ParentPkg() == I.ParentPkg()) + continue; + + Size++; + if (Res != 0) + *End++ = I; + } + + // Follow all provides + for (PrvIterator I = DPkg.ProvidesList(); I.end() == false; I++) + { + if (pkgCheckDep(TargetVer(),I.ProvideVersion(),Dep->CompareOp) == false) + continue; + + if (Dep->Type == pkgDEP_Conflicts && ParentPkg() == I.OwnerPkg()) + continue; + + Size++; + if (Res != 0) + *End++ = I.OwnerVer(); + } + + // Do it again and write it into the array + if (Res == 0) + { + Res = new Version *[Size+1]; + Size = 0; + } + else + { + *End = 0; + break; + } + } + + return Res; +} + /*}}}*/ +// VerIterator::CompareVer - Fast version compare for same pkgs /*{{{*/ +// --------------------------------------------------------------------- +/* This just looks over the version list to see if B is listed before A. In + most cases this will return in under 4 checks, ver lists are short. */ +int pkgCache::VerIterator::CompareVer(const VerIterator &B) const +{ + // Check if they are equal + if (*this == B) + return 0; + if (end() == true) + return -1; + if (B.end() == true) + return 1; + + /* Start at A and look for B. If B is found then A > B otherwise + B was before A so A < B */ + VerIterator I = *this; + for (;I.end() == false; I++) + if (I == B) + return 1; + return -1; +} + /*}}}*/ +// PkgFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/ +// --------------------------------------------------------------------- +/* This stats the file and compares its stats with the ones that were + stored during generation. Date checks should probably also be + included here. */ +bool pkgCache::PkgFileIterator::IsOk() +{ + struct stat Buf; + if (stat(FileName(),&Buf) != 0) + return false; + + if (Buf.st_size != (signed)File->Size || Buf.st_mtime != File->mtime) + return false; + + return true; +} + /*}}}*/ diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h new file mode 100644 index 000000000..0dc939a51 --- /dev/null +++ b/apt-pkg/pkgcache.h @@ -0,0 +1,280 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgcache.h,v 1.1 1998/07/02 02:58:12 jgg Exp $ +/* ###################################################################### + + Cache - Structure definitions for the cache file + + Please see doc/pkglib/cache.sgml for a more detailed description of + this format. Also be sure to keep that file up-to-date!! + + Clients should always use the CacheIterators classes for access to the + cache. They provide a simple STL-like method for traversing the links + of the datastructure. + + See pkgcachegen.h for information about generating cache structures. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_PKGCACHE_H +#define PKGLIB_PKGCACHE_H + +#include +#include +#include + +// 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 ⤅ + + 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 + +inline pkgCache::PkgIterator pkgCache::PkgBegin() + {return PkgIterator(*this);}; +inline pkgCache::PkgIterator pkgCache::PkgEnd() + {return PkgIterator(*this,PkgP);}; + +#endif diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc new file mode 100644 index 000000000..cb0fd3f74 --- /dev/null +++ b/apt-pkg/pkgcachegen.cc @@ -0,0 +1,184 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgcachegen.cc,v 1.1 1998/07/02 02:58:12 jgg Exp $ +/* ###################################################################### + + Package Cache Generator - Generator for the cache structure. + + This builds the cache structure from the abstract package list parser. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include + +#include +#include + /*}}}*/ + +// CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* We set the diry flag and make sure that is written to the disk */ +pkgCacheGenerator::pkgCacheGenerator(DynamicMMap &Map) : Map(Map), Cache(Map) +{ + if (_error->PendingError() == true) + return; + + if (Map.Size() == 0) + { + Map.RawAllocate(sizeof(pkgCache::Header)); + *Cache.HeaderP = pkgCache::Header(); + } + Cache.HeaderP->Dirty = true; + Map.Sync(0,sizeof(pkgCache::Header)); + Map.UsePools(*Cache.HeaderP->Pools,sizeof(Cache.HeaderP->Pools)/sizeof(Cache.HeaderP->Pools[0])); +} + /*}}}*/ +// CacheGenerator::~pkgCacheGenerator - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* We sync the data then unset the dirty flag in two steps so as to + advoid a problem during a crash */ +pkgCacheGenerator::~pkgCacheGenerator() +{ + if (_error->PendingError() == true) + return; + if (Map.Sync() == false) + return; + + Cache.HeaderP->Dirty = false; + Map.Sync(0,sizeof(pkgCache::Header)); +} + /*}}}*/ +// CacheGenerator::MergeList - Merge the package list /*{{{*/ +// --------------------------------------------------------------------- +/* This provides the generation of the entries in the cache. Each loop + goes through a single package record from the underlying parse engine. */ +bool pkgCacheGenerator::MergeList(ListParser &List) +{ + List.Owner = this; + + do + { + // Get a pointer to the package structure + string Package = List.Package(); + pkgCache::PkgIterator Pkg = Cache.FindPkg(Package); + if (Pkg.end() == false) + { + if (NewPackage(Pkg,Package) == false) + return false; + + if (List.NewPackage(Pkg) == false) + return false; + } + if (List.UsePackage(Pkg) == false) + return false; + + /* Get a pointer to the version structure. We know the list is sorted + so we use that fact in the search. Insertion of new versions is + done with correct sorting */ + string Version = List.Version(); + pkgCache::VerIterator Ver = Pkg.VersionList(); + unsigned long *Last = &Pkg->VersionList; + int Res; + for (; Ver.end() == false; Ver++, Last = &Ver->NextVer) + { + Res = pkgVersionCompare(Version.begin(),Version.end(),Ver.VerStr(), + Ver.VerStr() + strlen(Ver.VerStr())); + if (Res >= 0) + break; + } + + /* We already have a version for this item, record that we + saw it */ + if (Res == 0) + { + if (NewFileVer(Ver,List) == false) + return false; + + continue; + } + + // Add a new version + *Last = NewVersion(Ver,*Last); + if (List.NewVersion(Ver) == false) + return false; + + if (NewFileVer(Ver,List) == false) + return false; + } + while (List.Step() == true); + + return true; +} + /*}}}*/ +// CacheGenerator::NewPackage - Add a new package /*{{{*/ +// --------------------------------------------------------------------- +/* This creates a new package structure and adds it to the hash table */ +bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator Pkg,string Name) +{ + // Get a structure + unsigned long Package = Map.Allocate(sizeof(pkgCache::Package)); + if (Package == 0) + return false; + + Pkg = pkgCache::PkgIterator(Cache,Cache.PackageP + Package); + + // Insert it into the hash table + unsigned long Hash = Map.Hash(Name); + Pkg->NextPackage = Cache.HeaderP->HashTable[Hash]; + Cache.HeaderP->HashTable[Hash] = Package; + + // Set the name and the ID + Pkg->Name = Map.WriteString(Name); + if (Pkg->Name == 0) + return false; + Pkg->ID = Cache.HeaderP->PackageCount++; + + return true; +} + /*}}}*/ +// CacheGenerator::NewFileVer - Create a new File<->Version association /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator Ver, + ListParser &List) +{ +} + /*}}}*/ +// CacheGenerator::NewVersion - Create a new Version /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver, + unsigned long Next) +{ +} + /*}}}*/ +// CacheGenerator::SelectFile - Select the current file being parsed /*{{{*/ +// --------------------------------------------------------------------- +/* This is used to select which file is to be associated with all newly + added versions. */ +bool pkgCacheGenerator::SelectFile(string File,unsigned long Flags) +{ + struct stat Buf; + if (stat(File.c_str(),&Buf) == -1) + return _error->Errno("stat","Couldn't stat ",File.c_str()); + + // Get some space for the structure + CurrentFile = Cache.PkgFileP + Map.Allocate(sizeof(*CurrentFile)); + if (CurrentFile == Cache.PkgFileP) + return false; + + // Fill it in + CurrentFile->FileName = Map.WriteString(File); + CurrentFile->Size = Buf.st_size; + CurrentFile->mtime = Buf.st_mtime; + CurrentFile->NextFile = Cache.HeaderP->FileList; + CurrentFile->Flags = Flags; + PkgFileName = File; + + if (CurrentFile->FileName == 0) + return false; +} + /*}}}*/ diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h new file mode 100644 index 000000000..1385ab964 --- /dev/null +++ b/apt-pkg/pkgcachegen.h @@ -0,0 +1,69 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgcachegen.h,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + Package Cache Generator - Generator for the cache structure. + + This builds the cache structure from the abstract package list parser. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_PKGCACHEGEN_H +#define PKGLIB_PKGCACHEGEN_H + +#include + +class pkgCacheGenerator +{ + public: + + class ListParser; + + protected: + + DynamicMMap ⤅ + pkgCache Cache; + + string PkgFileName; + pkgCache::PackageFile *CurrentFile; + + bool NewPackage(pkgCache::PkgIterator Pkg,string Pkg); + bool NewFileVer(pkgCache::VerIterator Ver,ListParser &List); + unsigned long NewVersion(pkgCache::VerIterator &Ver,unsigned long Next); + + public: + + // This is the abstract package list parser class. + class ListParser + { + pkgCacheGenerator *Owner; + friend pkgCacheGenerator; + + protected: + + inline unsigned long WriteString(string S) {return Owner->Map.WriteString(S);}; + inline unsigned long WriteString(const char *S,unsigned int Size) {return Owner->Map.WriteString(S,Size);}; + + public: + + // These all operate against the current section + virtual string Package() = 0; + virtual string Version() = 0; + virtual bool NewVersion(pkgCache::VerIterator Ver) = 0; + virtual bool NewPackage(pkgCache::PkgIterator Pkg) = 0; + virtual bool UsePackage(pkgCache::PkgIterator Pkg) = 0; + + virtual bool Step() = 0; + }; + friend ListParser; + + bool SelectFile(string File,unsigned long Flags = 0); + bool MergeList(ListParser &List); + + pkgCacheGenerator(DynamicMMap &Map); + ~pkgCacheGenerator(); +}; + +#endif diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc new file mode 100644 index 000000000..106b0febe --- /dev/null +++ b/apt-pkg/tagfile.cc @@ -0,0 +1,195 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: tagfile.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + Fast scanner for RFC-822 type header information + + This uses a rotating 64K buffer to load the package information into. + The scanner runs over it and isolates and indexes a single section. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include + +#include +#include + /*}}}*/ + +// 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 + +int main(int argc,char *argv[]) +{ + { + File F(argv[1],File::ReadOnly); + pkgTagFile Test(F); + File CacheF("./cache",File::WriteEmpty); + DynamicMMap Map(CacheF,MMap::Public); + pkgCacheGenerator Gen(Map); + Gen.SelectFile("tet"); + } + +#if 0 + pkgTagSection I; + while (Test.Step(I) == true) + { + const char *Start; + const char *End; + if (I.Find("Package",Start,End) == false) + { + cout << "Failed" << endl; + continue; + } + + cout << "Package: " << string(Start,End - Start) << endl; + +/* for (const char *I = Start; I < End; I++) + { + const char *Begin = I; + bool Number = true; + while (isspace(*I) == 0 && ispunct(*I) == 0 && I < End) + { + if (isalpha(*I) != 0) + Number = false; + I++; + } + if (Number == false) + cout << string(Begin,I-Begin) << endl; + while ((isspace(*I) != 0 || ispunct(*I) != 0) && I < End) + I++; + I--; + } */ + } +#endif + _error->DumpErrors(); +} diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h new file mode 100644 index 000000000..a7a82dd1c --- /dev/null +++ b/apt-pkg/tagfile.h @@ -0,0 +1,64 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: tagfile.h,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + Fast scanner for RFC-822 type header information + + This parser handles Debian package files (and others). Their form is + RFC-822 type header fields in groups seperated by a blank line. + + The parser reads the and provides methods to step linearly + over it or to jump to a pre-recorded start point and read that record. + + A second class is used to perform pre-parsing of the record. It works + by indexing the start of each header field and providing lookup + functions for header fields. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_TAGFILE_H +#define PKGLIB_TAGFILE_H + +#include + +class pkgTagSection +{ + const char *Section; + const char *Stop; + + // We have a limit of 256 tags per section. + unsigned short Indexes[256]; + unsigned int TagCount; + + public: + + inline bool operator ==(const pkgTagSection &rhs) {return Section == rhs.Section;}; + inline bool operator !=(const pkgTagSection &rhs) {return Section != rhs.Section;}; + + bool Find(const char *Tag,const char *&Start, const char *&End); + bool Scan(const char *Start,unsigned long MaxLength); + inline unsigned long Length() {return Stop - Section;}; + + pkgTagSection() : Section(0), Stop(0) {}; +}; + +class pkgTagFile +{ + File Fd; + char *Buffer; + char *Start; + char *End; + unsigned long Left; + + bool Fill(); + + public: + + bool Step(pkgTagSection &Section); + + pkgTagFile(File &F); +}; + +#endif diff --git a/apt-pkg/version.cc b/apt-pkg/version.cc new file mode 100644 index 000000000..c02ee5f87 --- /dev/null +++ b/apt-pkg/version.cc @@ -0,0 +1,249 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: version.cc,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + Version - Version string + + Version comparing is done using the == and < operators. STL's + function.h provides the remaining set of comparitors. A directly + callable non-string class version is provided for functions manipulating + the cache file (esp the sort function). + + A version is defined to be equal if a case sensitive compare returns + that the two strings are the same. For compatibility with the QSort + function this version returns -1,0,1. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include + +#include + /*}}}*/ + +// Version::pkgVersion - Default Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgVersion::pkgVersion() +{ +} + /*}}}*/ +// Version::operator == - Checks if two versions are equal /*{{{*/ +// --------------------------------------------------------------------- +/* We can't simply perform a string compare because of epochs. */ +bool pkgVersion::operator ==(const pkgVersion &Vrhs) const +{ + if (pkgVersionCompare(Value.begin(),Value.end(), + Vrhs.Value.begin(),Vrhs.Value.end()) == 0) + return true; + return false; +} + /*}}}*/ +// Version::operator < - Checks if this is less than another version /*{{{*/ +// --------------------------------------------------------------------- +/* All other forms of comparision can be built up from this single function. + a > b -> b < a + a <= b -> !(a > b) -> !(b < a) + a >= b -> !(a < b) + */ +bool pkgVersion::operator <(const pkgVersion &Vrhs) const +{ + if (pkgVersionCompare(Value.begin(),Value.end(), + Vrhs.Value.begin(),Vrhs.Value.end()) == -1) + return true; + return false; +} + /*}}}*/ +// StrToLong - Convert the string between two iterators to a long /*{{{*/ +// --------------------------------------------------------------------- +/* */ +static unsigned long StrToLong(const char *begin,const char *end) +{ + char S[40]; + char *I = S; + for (; begin != end && I < S + 40;) + *I++ = *begin++; + *I = 0; + return strtoul(S,0,10); +} + /*}}}*/ +// VersionCompare (op) - Greater than comparison for versions /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int pkgVersionCompare(const char *A, const char *B) +{ + return pkgVersionCompare(A,A + strlen(A),B,B + strlen(B)); +} +int pkgVersionCompare(string A,string B) +{ + return pkgVersionCompare(A.begin(),A.end(),B.begin(),B.end()); +} + + /*}}}*/ +// VersionCompare - Greater than comparison for versions /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int pkgVersionCompare(const char *A, const char *AEnd, const char *B, + const char *BEnd) +{ + // lhs = left hand side, rhs = right hand side + const char *lhs = A; + const char *rhs = B; + + /* Consider epochs. They need special handling because an epoch + must not be compared against the first element of the real version. + This works okay when both sides have an epoch but when only one + does it must compare the missing epoch to 0 */ + for (;lhs != AEnd && *lhs != ':'; lhs++); + for (;rhs != BEnd && *rhs != ':'; rhs++); + + // Parse the epoch out + unsigned long lhsEpoch = 0; + unsigned long rhsEpoch = 0; + if (lhs != AEnd && *lhs == ':') + lhsEpoch = StrToLong(A,lhs); + if (rhs != BEnd && *rhs == ':') + rhsEpoch = StrToLong(B,rhs); + if (lhsEpoch != rhsEpoch) + { + if (lhsEpoch > rhsEpoch) + return 1; + return -1; + } + + /* Iterate over the whole string + What this does is to spilt the whole string into groups of + numeric and non numeric portions. For instance: + a67bhgs89 + Has 4 portions 'a', '67', 'bhgs', '89'. A more normal: + 2.7.2-linux-1 + Has '2', '.', '7', '.' ,'-linux-','1' */ + lhs = A; + rhs = B; + while (lhs != AEnd && rhs != BEnd) + { + // Starting points + const char *Slhs = lhs; + const char *Srhs = rhs; + + // Compute ending points were we have passed over the portion + bool Digit = (isdigit(*lhs) > 0?true:false); + for (;lhs != AEnd && (isdigit(*lhs) > 0?true:false) == Digit; lhs++); + for (;rhs != BEnd && (isdigit(*rhs) > 0?true:false) == Digit; rhs++); + + if (Digit == true) + { + // If the lhs has a digit and the rhs does not then true + if (rhs - Srhs == 0) + return -1; + + // Generate integers from the strings. + unsigned long Ilhs = StrToLong(Slhs,lhs); + unsigned long Irhs = StrToLong(Srhs,rhs); + if (Ilhs != Irhs) + { + if (Ilhs > Irhs) + return 1; + return -1; + } + } + else + { + // They are equal length so do a straight text compare + for (;Slhs != lhs && Srhs != rhs; Slhs++, Srhs++) + { + if (*Slhs != *Srhs) + { + /* We need to compare non alpha chars as higher than alpha + chars (a < !) This is so things like 7.6p2-4 and 7.6-0 + compare higher as well as . and -. I am not sure how + the dpkg code manages to achive the != '-' test, but it + is necessary. */ + int lc = *Slhs; + int rc = *Srhs; + if (isalpha(lc) == 0 && lc != '-') lc += 256; + if (isalpha(rc) == 0 && rc != '-') rc += 256; + if (lc > rc) + return 1; + return -1; + } + } + + // If the lhs is shorter than the right it is 'less' + if (lhs - Slhs < rhs - Srhs) + return -1; + + // If the lhs is longer than the right it is 'more' + if (lhs - Slhs > rhs - Srhs) + return 1; + } + } + + // The strings must be equal + if (lhs == AEnd && rhs == BEnd) + return 0; + + // lhs is shorter + if (lhs == AEnd) + return -1; + + // rhs is shorter + if (rhs == BEnd) + return 1; + + // Shouldnt happen + return 1; +} + /*}}}*/ +// CheckDep - Check a single dependency /*{{{*/ +// --------------------------------------------------------------------- +/* This simply preforms the version comparison and switch based on + operator. */ +bool pkgCheckDep(const char *DepVer,const char *PkgVer,int Op) +{ + if (DepVer == 0) + return true; + if (PkgVer == 0) + return false; + + // Perform the actuall comparision. + int Res = pkgVersionCompare(PkgVer,DepVer); + switch (Op & 0x0F) + { + case pkgOP_LESSEQ: + if (Res <= 0) + return true; + break; + + case pkgOP_GREATEREQ: + if (Res >= 0) + return true; + break; + + case pkgOP_LESS: + if (Res < 0) + return true; + break; + + case pkgOP_GREATER: + if (Res > 0) + return true; + break; + + case pkgOP_EQUALS: + if (Res == 0) + return true; + break; + + case pkgOP_NOTEQUALS: + if (Res != 0) + return true; + break; + } + + return false; +} + /*}}}*/ + diff --git a/apt-pkg/version.h b/apt-pkg/version.h new file mode 100644 index 000000000..a30246946 --- /dev/null +++ b/apt-pkg/version.h @@ -0,0 +1,45 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: version.h,v 1.1 1998/07/02 02:58:13 jgg Exp $ +/* ###################################################################### + + Version - Version string + + This class implements storage and operators for version strings. + + The client is responsible for stripping epochs should it be desired. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_VERSION_H +#define PKGLIB_VERSION_H + +#include + +class pkgVersion +{ + string Value; + + public: + + inline operator string () const {return Value;}; + + // Assignmnet + void operator =(string rhs) {Value = rhs;}; + + // Comparitors. STL will provide the rest + bool operator ==(const pkgVersion &rhs) const; + bool operator <(const pkgVersion &rhs) const; + + pkgVersion(); + pkgVersion(string Version) : Value(Version) {}; +}; + +int pkgVersionCompare(const char *A, const char *B); +int pkgVersionCompare(const char *A, const char *AEnd, const char *B, + const char *BEnd); +int pkgVersionCompare(string A,string B); +bool pkgCheckDep(const char *DepVer,const char *PkgVer,int Op); + +#endif diff --git a/doc/apt-cache.8 b/doc/apt-cache.8 new file mode 100644 index 000000000..0292973ed --- /dev/null +++ b/doc/apt-cache.8 @@ -0,0 +1,199 @@ +.\" This manpage is copyright (C) 1998 Branden Robinson . +.\" +.\" This is free software; you may redistribute it and/or modify +.\" it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2, +.\" or (at your option) any later version. +.\" +.\" This is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public +.\" License along with APT; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +.\" 02111-1307 USA +.TH apt-cache 8 "16 June 1998" "Debian GNU/Linux" +.SH NAME +apt-cache \- APT package handling utility \(em cache manipulator +.SH SYNOPSIS +.B apt-cache +.I command cache +.RI [ argument +.IR ... ] +.SH DESCRIPTION +.B apt-cache +performs a variety of operations on APT's package cache. +.I apt-cache +is seldom called directly; instead it is usually invoked internally by +.BR apt-get (8) +or +.BR apt (8). +.PP +.I command +is one of +.RS +.PD 0 +.B add +.PP +.B dump +.PP +.B dumpavail +.PP +.B showpkg +.PP +.B stats +.RE +.PD 1 +.PP +.I cache +must be a package cache file (for instance, +.IR /var/cache/apt/pkgcache.bin ). +Some +.IR command s +require additional arguments. +.SS add +.B add +adds a new set of package records to +.IR cache . +Remaining arguments are of the form +.IR file : dist : ver , +where +.I file +is the full path to file in question. +.I dist +and +.I ver +can be any string and are not yet implemented. +.SS dump +.B dump +displays information about all the packages in the cache. See +.B showpkg +below for an explanation of what data is output for each package. +.SS dumpavail +.B dumpavail +generates an +.I available +file suitable for use with +.BR dpkg (8) +based on the information in the cache. +.SS showpkg +.B showpkg +displays information about the packages listed on the command line. +Remaining arguments are package names. The available versions and +reverse dependencies of each package listed are listed, as well as +forward dependencies for each version. Forward (normal) dependencies +are those packages upon which the package in question depends; reverse +dependencies are those packages that depend upon the package in +question. Thus, forward dependencies must be satisfied for a package, +but reverse dependencies need not be. +For instance, +.B apt-cache showpkg +.I cache +.B libreadline2 +would produce output similar to the following: +.PP +.RS +.PD 0 +Package: libreadline2 +.PP +Versions: 2.1-8,2.1-7, +.PP +Reverse Depends: +.RS +.PP +libreadlineg2,libreadline2 +.PP +libreadlineg2,libreadline2 +.PP +libreadline2-altdev,libreadline2 +.RE +.PP +Dependencies: +.PP +2.1-8 - libc5 ncurses3.0 ldso +.PP +2.1-7 - ldso libc5 ncurses3.0 +.RE +.PD 1 +.PP +Thus it may be seen that libreadline2, version 2.1-8, depends on libc5, +ncurses3.0, and ldso, which must be installed for libreadline2 to work. In +turn, libreadlineg2 and libreadline2-altdev depend on libreadline2. If +libreadline2 is installed, libc5, ncurses3.0, and ldso must also be +installed; libreadlineg2 and libreadline2-altdev do not have to be +installed. +.SS stats +.B stats +displays some statistics about +.IR cache . +No further arguments are expected. Statistics reported are: +.RS +.TP +.I Total package names +is the number of package names found in the cache. +.TP +.I Normal packages +is the number of regular, ordinary package names; these +are packages that bear a one-to-one correspondence between their names and +the names used by other packages for them in dependencies. The majority of +packages fall into this category. +.TP +.I Pure virtual packages +is the number of packages that exist only as a virtual package name; that +is, packages only "provide" the virtual package name, and no package +actually uses the name. For instance, "mail-transport-agent" in the Debian +GNU/Linux system is a pure virtual package; several packages provide +"mail-transport-agent", but there is no package named "mail-transport-agent". +.TP +.I Single virtual packages +is the number of packages with only one package providing a particular +virtual package. For instance, in the Debian GNU/Linux system, +"X11-text-viewer" is a virtual package, but only one package, xless, +provides "X11-text-viewer". +.TP +.I Mixed virtual packages +is the number of packages that either provide a particular virtual package +or have the virtual package name as the package name. For instance, in the +Debian GNU/Linux system, e2fsprogs is both an actual package, and +provided by the e2compr package. +.TP +.I Missing +is the number of package names that were referenced in a dependency but +were not provided by any package. Missing packages may be in evidence +if a full distribution is not accesssed, or if a package (real or virtual) +has been dropped from the distribution. +.TP +.I Total distinct versions +is the number of package versions found in the cache; this value is +therefore at least equal to the number of total package names. If more than +one distribution (both "stable" and "unstable", for instance), is being +accessed, this value can be considerably larger than the number of total +package names. +.TP +.I Total dependencies +is the number of dependency relationships claimed by all of the packages in +the cache. +.RE +.SH OPTIONS +None. +.SH FILES +None. +.SH SEE ALSO +.BR apt (8), +.BR apt-get (8), +.I /usr/doc/apt/cache* +.SH DIAGNOSTICS +apt-cache returns zero on normal operation, decimal 100 on error. +.SH BUGS +See . If you wish to report a +bug in +.BR apt-cache , +please see +.I /usr/doc/debian/bug-reporting.txt +or the +.BR bug (1) +command. +.SH AUTHOR +apt-cache was written by the APT team . diff --git a/doc/apt-get.8 b/doc/apt-get.8 new file mode 100644 index 000000000..c53dc70d7 --- /dev/null +++ b/doc/apt-get.8 @@ -0,0 +1,250 @@ +.\" $Id: apt-get.8,v 1.1 1998/07/02 02:58:12 jgg Exp $ +.\" This manpage is copyright (C) 1998 Branden Robinson . +.\" +.\" This is free software; you may redistribute it and/or modify +.\" it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2, +.\" or (at your option) any later version. +.\" +.\" This is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public +.\" License along with APT; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +.\" 02111-1307 USA +.TH apt-get 8 "16 June 1998" "Debian GNU/Linux" +.SH NAME +apt-get \- APT package handling utility \(em command-line interface +.SH SYNOPSIS +.B apt-get +.RI [ options ] +.RI [ command ] +.RI [ package +.IR ... ] +.SH DESCRIPTION +.B apt-get +is the command-line tool for handling packages, and may be considered the +user's "back-end" to +.BR apt (8). +Use +.BR apt (8) +if the usage of apt-get does not seem intuitive. +.PP +.I command +is one of +.RS +.PD 0 +.B update +.PP +.B upgrade +.PP +.B dselect-upgrade +.PP +.B dist-upgrade +.PP +.B install +.PP +.B check +.PP +.B clean +.RE +.PD 1 +.PP +Unless one of the +.IR -h , +.IR --help , +.IR -f , +or +.I --fix-broken +options is given, one of the above commands must be present. Only the +.B install +command requires any further arguments. +.SS update +.B update +is used to resynchronize the package overview files from their +sources. The overviews of available packages are fetched from the +location(s) specified in +.IR /etc/apt/sources.list . +For example, when using a Debian archive, this command retrieves and +scans the +.I Packages.gz +files, so that information about new and updated packages is available. An +.B update +should always be performed before an +.B upgrade +or +.BR dist-upgrade . +.SS upgrade +.B upgrade +is used to install the newest versions of all packages currently installed +on the system from the sources enumerated in +.IR /etc/apt/sources.list . +Packages currently installed with new versions available are retrieved +and upgraded; under no circumstances are currently installed packages +removed, or packages not already installed retrieved and installed. New +versions of currently installed packages that cannot be upgraded without +changing the install status of another package will be left at their +current version. An +.B update +must be performed first so that +.B apt-get +knows that new versions of packages are available. +.SS dselect-upgrade +.B dselect-upgrade +is used in conjunction with the traditional Debian GNU/Linux packaging +front-end, +.BR dselect (8). " dselect-upgrade" +follows the changes made by +.B dselect +to the +.I Status +field of available packages, and performs the actions necessary to realize +that state (for instance, the removal of old and the installation of new +packages). +.B dselect-upgrade +does not attempt to intelligently address dependency issues as +.B dist-upgrade +or +.B install +do. If any dependency problems arise, +.B apt-get +aborts without performing any of the actions requested, even those +without problems. +.B dselect-upgrade +is only useful to users of +.B dselect +and the +.I .deb +package file format. The +.I /etc/apt/sources.list +file contains a list of locations from which to retrieve desired package +files. +.SS dist-upgrade +.BR dist-upgrade , +in addition to performing the function of +.BR upgrade , +also intelligently handles changing dependencies with new versions of +packages; +.B apt-get +has a "smart" conflict resolution system, and it will attempt to upgrade +the most important packages at the expense of less important ones if +necessary. The +.I /etc/apt/sources.list +file contains a list of locations from which to retrieve desired package +files. +.SS install +.B install +is followed by one or more +.I packages +desired for installation. Each +.I package +is a package name, not a fully qualified filename (for instance, in a +Debian GNU/Linux system, +.I lsdo +would be the argument provided, not +.IR ldso_1.9.6-2.deb ). +All packages required by the package(s) specified for installation will +also be retrieved and installed. The +.I /etc/apt/sources.list +file is used to locate the desired packages. If a hyphen is appended to +the package name (with no intervening space), the identified package will +be removed if it is installed. This latter feature may be used to override +decisions made by apt-get's conflict resolution system. +.SS check +.B check +is a diagnostic tool; it updates the package cache and checks for broken +packages. +.SS clean +.B clean +clears out the local repository of retrieved package files. It removes +everything but the lock file from +.I /var/cache/apt/archives/ +and +.IR /var/cache/apt/archives/partial/ . +When APT is used as a +.BR dselect (8) +method, +.B +clean +is run automatically. Those who do not use dselect will likely want to +run +.B +apt-get clean +from time to time to free up disk space. +.SH OPTIONS +.TP +.IR \-d , " --download-only" +Download only; package files are only retrieved, not unpacked or installed. +.TP +.IR \-f , " --fix-broken" +Fix; attempt to correct a system with broken dependencies in +place. This option may be used alone or in conjunction with any of the +command actions, and is sometimes necessary when running APT for the +first time; APT itself does not allow broken package dependencies to +exist on a system. It is possible that a system's dependency structure +can be so corrupt as to require manual intervention (which usually +means using dselect or dpkg --remove to eliminate some of the offending +packages). Use of this option together with -m is discouraged. +.TP +.IR \-h , " --help" +Help; display a helpful usage message and exit. +.TP +.IR \-m , " --ignore-missing" +Ignore missing packages; If packages cannot be retrieved or fail the +integrity check after retrieval (corrupted package files), hold back +those packages and handle the result. Use of this option together with +-f is discouraged. +.TP +.IR \-q , " --silent" +Quiet; produces output suitable for logging, omitting progress indicators. +.TP +.I \-qq +Very quiet; no output except for errors. +.TP +.IR \-s , " --simulate" , " --just-print" , " --dry-run" , " --recon " , " --no-act" +No action; perform a simulation of events that would occur but do not +actually change the system. +.TP +.IR \-y , " --yes" , " --assume-yes" +Automatic yes to prompts; assume "yes" as answer to all prompts and run +non-interactively. +.SH FILES +.TP +.I /etc/apt/sources.list +see +.BR sources.list (5) +.TP +.I /var/cache/apt/archives/ +storage area for retrieved package files +.TP +.I /var/cache/apt/archives/partial/ +storage area for package files in transit +.TP +.I /var/state/apt/lists/ +storage area for state information for each package resource specified in +.I /etc/apt/sources.list +.TP +.I /var/state/apt/lists/partial/ +storage area for state information in transit +.SH SEE ALSO +.BR apt (8), +.BR apt-cache (8), +.BR dpkg (8), +.BR dselect (8), +.BR sources.list (5) +.SH DIAGNOSTICS +apt-get returns zero on normal operation, decimal 100 on error. +.SH BUGS +See . If you wish to report a +bug in +.BR apt-get , +please see +.I /usr/doc/debian/bug-reporting.txt +or the +.BR bug (1) +command. +.SH AUTHOR +apt-get was written by the APT team . diff --git a/doc/apt.8 b/doc/apt.8 new file mode 100644 index 000000000..08aa2c4fd --- /dev/null +++ b/doc/apt.8 @@ -0,0 +1,50 @@ +.\" This manpage is copyright (C) 1998 Branden Robinson . +.\" +.\" 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 . 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 . diff --git a/doc/cache.sgml b/doc/cache.sgml new file mode 100644 index 000000000..43f8d4fff --- /dev/null +++ b/doc/cache.sgml @@ -0,0 +1,761 @@ + + + +APT Cache File Format + +Jason Gunthorpe jgg@debian.org +$Id: cache.sgml,v 1.1 1998/07/02 02:58:12 jgg Exp $ + + +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. + + + + +Copyright © Jason Gunthorpe, 1997. +

+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. + +

+For more details, on Debian GNU/Linux systems, see the file +/usr/doc/copyright/GPL for the full license. + + + + +Introduction + + +Purpose + +

+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. + +

+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. + +

+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. + +

+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. + +

+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. + +Note on Pointer access +

+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-. + +

+This scheme allows code like this to be written: + + void *Map = mmap(...); + Package *PkgList = (Package *)Map; + Header *Head = (Header *)Map; + char *Strings = (char *)Map; + cout << (Strings + PkgList[Head->HashTable[0]]->Name) << endl; + +

+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. + +

+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) + + +Structures + + +Header +

+This is the first item in the file. + + 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 + }; + + +Signature +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 + +MajorVersion +MinorVersion +These contain the version of the cache file, currently 0.2. + +Dirty +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. + +HeaderSz +PackageSz +PackageFileSz +VersionSz +DependencySz +ProvidesSz +*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. + +PackageCount +VersionCount +DependsCount +PackageFileCount +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. + +FileList +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. + +StringList +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. + +PoolStart +PoolSize +PoolAln +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. + +HashTable +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: + + 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); + } + +

+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. + + + + + +Package +

+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. + + 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; + }; + + + +Name +Name of the package. + +VersionList +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. + +TargetVer +CurrentVer +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. + +TargetDist +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. + +Section +This indicates the deduced section. It should be "Unknown" or the section +of the last parsed item. + +NextPackage +Next link in this hash item. This linked list is based at Header.HashTable +and contains only packages with the same hash value. + +RevDepends +Reverse Depends is a linked list of all dependencies linked to this package. + +ProvidesList +This is a linked list of all provides for this package name. + +SelectedState +InstState +CurrentState +These corrispond to the 3 items in the Status field found in the status +file. See the section on defines for the possible values. +

+SelectedState is the state that the user wishes the package to be +in. +

+InstState is the installation state of the package. This normally +should be Ok, but if the installation had an accident it may be otherwise. +

+CurrentState indicates if the package is installed, partially installed or +not installed. + +ID +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. + +Flags +Flags are some usefull indicators of the package's state. + + + + + + +PackageFile +

+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 + + 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 + }; + + + +FileName +Refers the the physical disk file that this PacakgeFile represents. + +Version +Version is the given version, ie 1.3.1, 2.4_revision_1 etc. + +Distribution +Distribution is the symbolic name for this PackageFile, hamm,bo,rexx etc + +Size +Size is provided as a simple check to ensure that the package file has not +been altered. + +ID +See Package::ID. + +Flags +Provides some flags for the PackageFile, see the section on defines. + +mtime +Modification time for the file at time of cache generation. + + + + + + +Version +

+This contians the information for a single version of a package. This is a +singley linked list based from Package.Versionlist. + +

+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). + + + 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; + }; + + + +VerStr +This is the complete version string. + +File +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. + +Section +This string indicates which section it is part of. The string should be +contained in the StringItem list. + +NextVer +Next step in the linked list. + +DependsList +This is the base of the dependency list. + +ParentPkg +This links the version to the owning package, allowing reverse dependencies +to determine the package. + +ProvidesList +Head of the linked list of Provides::NextPkgProv, forward provides. + +Offset +The byte offset of the first line of this item in the specified +PackageFile + +Size +InstalledSize +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 + +ID +See Package::ID. + +Priority +This is the parsed priority value of the package. + + + + + +Dependency +

+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. + +

+Multiple depends on the same package must be grouped together in +the Dependency lists. Clients should assume this is always true. + + + 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; + }; + + +Version +The string form of the version that the dependency is applied against. + +Package +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. + +NextDepends +Linked list based off a Version structure of all the dependencies in that +version. + +NextRevDepends +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. + +ParentVer +Parent version linking, allows the reverse dependency list to link +back to the version and package that the dependency are for. + +Type +Describes weather it is depends, predepends, recommends, suggests, etc. + +CompareOp +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. + +ID +See Package::ID. + + + + + + +Provides +

+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. + +

+There is a linked list of provided package names started from each +version that provides packages. This is the forwards provides mechanism. + + struct Provides + { + unsigned long ParentPkg; // Package + unsigned long Version; // Version + unsigned long ProvideVersion; // Stringtable + unsigned long NextProvides; // Provides + unsigned long NextPkgProv; // Provides + }; + + +ParentPkg +The index of the package that head of this linked list is in. ParentPkg->Name +is the name of the provides. + +Version +The index of the version this provide line applies to. + +ProvideVersion +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. + +NextProvides +Next link in the singly linked list of provides (based off package) + +NextPkgProv +Next link in the singly linked list of provides for 'Version'. + + + + + + +StringItem +

+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. + + struct StringItem + { + unsigned long String; // Stringtable + unsigned long NextItem; // StringItem + }; + + +String +The string this refers to. + +NextItem +Next link in the chain. + + + + +StringTable +

+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 +

+Several structures use variables to indicate things. Here is a list of all +of them. + +Definitions for Dependency::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 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 + +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. + + +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::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 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 Version::Priority +

+Zero is used for unparsable or absent Priority fields. + +#define pkgPRIO_Important 1 +#define pkgPRIO_Required 2 +#define pkgPRIO_Standard 3 +#define pkgPRIO_Optional 4 +#define pkgPRIO_Extra 5 + + + +Definitions for PackageFile::Flags +

+ +#define pkgFLAG_NotSource (1 << 0) + + + + + +Notes on the Generator + + +

+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. + +

+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. + +

+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. + +

+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. + +

+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 + +struct MyPkgData; +MyPkgData *Data = new MyPkgData[Header->PackageCount]; +Data[Package->ID]->Item = 0; + +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. + +

+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. + + + +Future Directions + + +

+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) + +

+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. + + + + diff --git a/doc/design.sgml b/doc/design.sgml new file mode 100644 index 000000000..55fd7e551 --- /dev/null +++ b/doc/design.sgml @@ -0,0 +1,411 @@ + + + + + The APT project design document + + Manoj Srivastava + srivasta@debian.org + + $Id: design.sgml,v 1.1 1998/07/02 02:58:12 jgg Exp $ + + 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. + + + Copyright ©1997 Manoj Srivastava + +

+ 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.

+

+ 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 with your Debian GNU/Linux system, in + /usr/doc/copyright/GPL, or with the + COPYING. If not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, + USA.

+
+ + + Introduction +

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.

+ +

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)

+
+ + Requirements +

+ + +

+ 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.

+
+ +

+ 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.

+
+ +

+ 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. +

+
+ +

+ This would allow APT to handle standard + installations, 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.

+
+ +

+ 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) +

+
+ +

+ 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, + configure immediately requests mentioned below + should be handled.

+
+ +

+ Handle replacement of a package providing a virtual + package with another (for example, it has been very + difficult replacing sendmail with + smail, or vice versa), making sure that the + dependencies are still satisfied.

+
+ +

+ 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.

+
+ +

+ 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.

+
+ +

+ 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.

+
+ +

+ 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).

+
+ +

+ 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)

+
+ +

+ + + Procedural description +

+ Set Options + +

+ 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.

+ + Updates + +

+ 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.

+
+ Local status + +

+ 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. +

+
+ Relationship determination + +

+ 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.

+
+ Selection + +

+ 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) +

+
+ Ordering of package installations and configuration + +

+ 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).

+
+ Action + +

+ 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.

+
+ + +

+
+ + Modules and interfaces +

+ The user interface module + +

Look at Behan Webster's documentation.

+ + Widget set + +

+ Related closely to above Could some one present design + decisions of the widget set here?

+
+ pdate Module + +

+ 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)

+

+ 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.

+

+ +

FTP methods

+
+ +

mount and file traversal module(s)?

+
+ +

Other methods ???

+
+ +

+ + Status file parser/generator + +

+ 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 dpkg + -BORGiE on a file system.

+
+ Package file parser/generator + +

+ 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.

+
+ Dependency module + +

+ +

dependency/conflict determination and linking

+
+ +

reverse dependency generator. Maybe merged with above

+
+ +

+ + Package ordering Module + +

Create an ordering of the actions to be taken.

+
+ Event genrator + +

module to interact with dpkg

+
+ +
+ + Data flow and conversions analysis. +

+ + ____________ + __\|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 | + |___________| + + +

dpkg also interacts with status and available files.

+ + +

+ 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.

+ +

The other focal point for APT is the user interface.

+
+ + diff --git a/doc/dpkg-tech.sgml b/doc/dpkg-tech.sgml new file mode 100644 index 000000000..3c01ee8f0 --- /dev/null +++ b/doc/dpkg-tech.sgml @@ -0,0 +1,509 @@ + + +dpkg technical manual + +Tom Lees tom@lpsg.demon.co.uk +$Id: dpkg-tech.sgml,v 1.1 1998/07/02 02:58:12 jgg Exp $ + + +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. + + + +Copyright © Tom Lees, 1997. +

+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. + +

+For more details, on Debian GNU/Linux systems, see the file +/usr/doc/copyright/GPL for the full license. + + + + +Quick summary of dpkg's external interface +Control files + +

+The basic dpkg package control file supports the following major features:- + + +5 types of dependencies:- + + Pre-Depends, which must be satisfied before a package may be + unpacked + Depends, which must be satisfied before a package may be + configured + Recommends, to specify a package which if not installed may + severely limit the usefulness of the package + Suggests, to specify a package which may increase the + productivity of the package + Conflicts, to specify a package which must NOT be installed + in order for the package to be configured + +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:- + + "<<" - less than + "<=" - less than or equal to + ">>" - greater than + ">=" - greater than or equal to + "==" - equal to + +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. +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. + + +The dpkg status area + +

+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). + +

+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:- + + +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 <file>", "--merge-avail <file>", and +"--clear-avail". +status - this file contains information on the following things for +every package:- + + Whether it is installed, not installed, unpacked, removed, + failed configuration, or half-installed (deconfigured in + favour of another package). + Whether it is selected as install, hold, remove, or purge. + If it is "ok" (no installation problems), or "not-ok". + It usually also contains the section and priority (so that + dselect may classify packages not in available) + For packages which did not initially appear in the "available" + file when they were installed, the other control information + for them. + +

+ The exact format for the "Status:" field is: + + Status: Want Flag Status + + Where Want may be one of unknown, install, + hold, deinstall, purge. Flag + may be one of ok, reinstreq, hold, + hold-reinstreq. + Status may be one of not-installed, unpacked, + half-configured, installed, half-installed + config-files, post-inst-failed, removal-failed. + The states are as follows:- + + not-installed + No files are installed from the package, it has no config files + left, it uninstalled cleanly if it ever was installed. + unpacked + 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. + half-configured + The package was installed and unpacked, but the postinst script + failed in some way. + installed + All files for the package are installed, and the configuration + was also successful. + half-installed + An attempt was made to remove the packagem but there was a failure + in the prerm script. + config-files + The package was "removed", not "purged". The config files are left, + but nothing else. + post-inst-failed + Old name for half-configured. Do not use. + removal-failed + Old name for half-installed. Do not use. + + The two last items are only left in dpkg for compatibility - they are + understood by it, but never written out in this form. + +

+ Please see the dpkg source code, lib/parshelp.c, + statusinfos, eflaginfos and wantinfos for more + details. + +info - this directory contains files from the control archive of every +package currently installed. They are installed with a prefix of "<packagename>.". +In addition to this, it also contains a file called <package>.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. +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. +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. +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. +updates - directory used internally by dpkg. This is discussed later, +in the section . +parts - temporary directory used by dpkg-split + + +The dpkg library files + +

+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). + +

+The following files may be found in each of these subdirectories:- + + +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. +desc.<name> - Contains the long description displayed by dselect +when the cursor is put over the <name> method. +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). +install - Script/program called when the "install" option of dselect is +run with this method. Same arguments as for setup. +update - Script/program called when the "update" option of dselect is +run. Same arguments as for setup/install. + + +The "dpkg" command-line utility + +"Documented" command-line interfaces + +

+As yet unwritten. You can refer to the other manuals for now. See +. + +Environment variables which dpkg responds to + +

+ +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. +SHELL - used to determine which shell to run in the case when +DPKG_NO_TSTP is set. +CC - used as the C compiler to call to determine the target architecture. +The default is "gcc". +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:- + + ldconfig + start-stop-daemon + install-info + update-rc.d + + + +Assertions + +

+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. + +

+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):- + + +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. +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. + + +

+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. + +--predep-package + +

+This strange option is described as follows in the source code: + + +/* 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 + */ + + +

+On further inspection of the source code, it appears that what is does is +this:- + + +Looks at the packages in the database which are selected as "install", +and are installed. +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. +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. +It then continues this for every dependency of the initial package. + + +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). + +dpkg-deb and .deb file internals + +

+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. + +The .deb archive format + +

+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:- + + +debian-binary +control.tar.gz +data.tar.gz + + +

+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. + +The dpkg-deb command-line + +

+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:- + + +--build (-b) <dir> - builds a .deb archive, takes a directory which +contains all the files as an argument. Note that the directory +<dir>/DEBIAN will be packed separately into the control archive. +--contents (-c) <debfile> - Lists the contents of ther "data.tar.gz" +member. +--control (-e) <debfile> - Extracts the control archive into a +directory called DEBIAN. Alternatively, with another argument, it will extract +it into a different directory. +--info (-I) <debfile> - 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. +--field (-f) <debfile> <field> ... - 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. +--extract (-x) <debfile> <dir> - Extracts the data archive +of a debian package under the directory <dir>. +--vextract (-X) <debfile> <dir> - Same as --extract, except +it is equivalent of giving tar the '-v' option - it prints the filenames as +it extracts them. +--fsys-tarfile <debfile> - This option outputs a gunzip'd version +of data.tar.gz to stdout. +--new - sets the archive format to be used to the new Debian format +--old - sets the archive format to be used to the old Debian format +--debug - Tells dpkg-deb to produce debugging output +--nocheck - Tells dpkg-deb not to check the sanity of the control file +--help (-h) - Gives a help message +--version - Shows the version number +--licence/--license (UK/US spellings) - Shows a brief outline of the GPL + + +Internal checks used by dpkg-deb when building packages + +

+Here is a list of the internal checks used by dpkg-deb when building packages. +It is in the order they are done. + + +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. +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:- + + The package name is checked to see if it contains any invalid + characters (see for this). + 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. + 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. + dpkg-deb then checks that the control file contains a valid + version number. + +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. +Next, dpkg-deb checks for the <dir>/DEBIAN directory. It complains +if it doesn't exist, or if it has permissions < 0755, or > 0775. +It then checks that all the files in this subdir are either symlinks +or plain files, and have permissions between 0555 and 0775. +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. + + +dpkg internals + +

+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. + +Updates + +

+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 , 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. + +

+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. + +

+These files are created internally by dpkg's "checkpoint" function, and are +cleaned up when dpkg exits cleanly. + +

+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. + +

+The other option would be to sync-rewrite the status file after each +operation, which would kill performance. + +

+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. + +What happens when dpkg reads the database + +

+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. + +

+More information on updates is given above. + +How dpkg compares version numbers + +

+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. + +

+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. + +

+Here are a few examples of how these rules apply:- + + +15 > 10 +0010 == 10 + +d.r > dsr +32.d.r == 0032.d.r +d.rnr < d.rnrn + + + diff --git a/doc/files.sgml b/doc/files.sgml new file mode 100644 index 000000000..d98d6f68a --- /dev/null +++ b/doc/files.sgml @@ -0,0 +1,491 @@ + + + +APT Files + +Jason Gunthorpe jgg@debian.org +$Id: files.sgml,v 1.1 1998/07/02 02:58:12 jgg Exp $ + + +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. + + + +Copyright © Jason Gunthorpe, 1998. +

+"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. + +

+For more details, on Debian GNU/Linux systems, see the file +/usr/doc/copyright/GPL for the full license. + + + + +Introduction + + +General + +

+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. + +

+The var directory structure is as follows: + + /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 + + +

+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. + + + +Files + + +Distribution Source list (sources.list) + +

+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: + +

+type ui args + +

+The first item, type, 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 deb +which indicates a standard debian archive with a dists dir. + +The deb Type +

+ The deb type is to be a typical two level debian distributions, + dist/distribution/component. 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: + +

+ deb uri distribution compontent + [component ...] + +

+ uri for the deb type must specify the base of the + debian distribution. APT will automatically generate the proper longer + URIs to get the information it needs. distribution can specify + an exact path, in this case the components must be omitted and + distribution must end in a slash. + +

+ 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). + + +URI specification +

+URIs in the source list support a large number of access schemes. + + +cdrom + 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. + + cdrom:Debian 1.3/debian + + +http + 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. + + http://www.debian.org/archive + + +ftp + 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. + + ftp://ftp.debian.org/debian + + +file + 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. + + file:/var/debian + + +mirror + 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. + + mirror:http://www.debian.org/archivemirrors + + +smb + A possible future expansion may be to have direct support for smb (Samba + servers). + + smb://ftp.kernel.org/pub/mirrors/debian + + + + +Hashing the URI +

+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: + + +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 + + +

+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 Archive Directory +section regarding the partial sub dir apply here as well. + + + + + + +Extra Status File (xstatus) + +

+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: + + +X-Auto + The Auto flag can be Yes or No and controls whether the package is in + auto mode. + +X-TargetDist + The TargetDist item indicates which distribution versions are offered for + installation from. It should be stable, unstable or frozen. + +X-TargetVersion + The target version item is set if the user selects a specific version, it + overrides the TargetDist selection if both are present. + + + + + +Binary Package Cache (pkgcache.bin) + +

+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. +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. + + + + +Downloads Directory (archives) + +

+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. + +

+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.. + + + + + The Methods Directory (/usr/lib/apt/methods) + +

+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. + +

+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. + +

+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: + + + +F - Change URI +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 F URI + +S - Object Size +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 S INTEGER + +E - Error Information +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 E String + +I - Informative progress information +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 +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 Connecting to SITE, +Connecting to SITE (1.1.1.1), Waiting for file, +Authenticating, Downloading, Resuming (size), +Computing MD5 I lines should never print out information that +APT is already aware of, such as file names. + +R - Set final path +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 R String + +M - MD5Sum of the file +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 M MD5-String + +L - Log output +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 L String Log things should only be used in a completed method +if they have special relavence to what is happening. + + +

+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 never change the file in .., it may +only change the output file in the current directory. + +

+The APT 'http' program is the reference implementation of this specification, +it implements all of the features a method is expected to do. + + + + + The Mirror List + +

+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: + +deb mirror:http://www.debian.org/mirrorlist stable main non-us + +which would likely cause APT to choose two separate sites to download from, +one for main and another for non-us. + +

+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. + + + + + The Release File + +

+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. + +

+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'. + +

+The file is formed as the package file (RFC-822) with the following tags +defined: + + +Archive +This is the common name we give our archives, such as stable or +unstable. + +Component +Referes to the sub-component of the archive, main, contrib +etc. + +Version +This is a version string with the same properties as in the Packages file. +It represents the release level of the archive. + +Origin +This specifies who is providing this archive. In the case of Debian the +string will read 'Debian'. Other providers may use their own string + +Label +This carries the encompassing name of the distribution. For Debian proper +this field reads 'Debian'. For derived distributions it should contain their +proper name. + +Architecture +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 mixed. + +NotAutomatic +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. + +Description +Description is used to describe the release. For instance experimental would +contain a warning that the packages have problems. + + +

+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 + + +Archive: stable +Compontent: main +Version: 1.3.1r6 +Origin: Debian +Label: Debian +Architecture: i386 + + +This is an example of experimental, + +Archive: experimental +Version: 0 +Origin: Debian +Label: Debian +Architecture: mixed +NotAutomatic: Yes + + +And unstable, + +Archive: unstable +Compontent: main +Version: 2.1 +Origin: Debian +Label: Debian +Architecture: i386 + + + + + + diff --git a/doc/ftp.conf.5 b/doc/ftp.conf.5 new file mode 100644 index 000000000..30c7c031b --- /dev/null +++ b/doc/ftp.conf.5 @@ -0,0 +1,93 @@ +.\" This manpage is copyright (C) 1998 Branden Robinson +.\" and Manoj Srivastava . +.\" +.\" This is free software; you may redistribute it and/or modify +.\" it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2, +.\" or (at your option) any later version. +.\" +.\" This is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public +.\" License along with APT; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +.\" 02111-1307 USA +.TH ftp.conf 5 "16 June 1998" "Debian GNU/Linux" +.SH NAME +ftp.conf \- configuration file for APT FTP method +.SH DESCRIPTION +The ftp.conf file determines the behavior of the FTP method for the APT +packaging tool. The syntax of the file is +.IR variable = value . +Quotes are not required around +.IR value s. +Comments start with a '#' and end at the next newline. Blank lines are +ignored. The following +.I variables +are understood: +.IP Firewall +is the hostname of a machine which acts as an FTP firewall. This can be +overridden by an environment variable +.IR FTP_FIREWALL . +If specified, and the given hostname cannot be directly contacted, a connection +is made to the firewall machine and the string +.B @hostname +is appended to the login identifier. This type of setup is also known as an +FTP proxy. +.IP ProxyLogName +is a parameter used by some firewall FTP proxies. It is used to authorize +the user specified by +.I ProxyLogName +to send data beyond the +.I Firewall +machine. +.IP ProxyPassword +is the password used to authenticate +.I ProxyLogName +on the +.I Firewall +machine. +.IP TimeOut +sets a timeout value in seconds (the default is sixty seconds). +.IP Passive +is either +.B true +or +.BR false . +If true, then all data transfers will be done using passive mode. This is +required for some dumb FTP servers and firewall configurations. It can +also be overridden by the environment variable +.IR FTP_PASSIVE . +.IP Verbose +is either +.B true +or +.B false, +and makes the FTP method output more data than it normally does. +.IP Debug +is either +.B true +or +.B false, +and makes the FTP method output debugging information. This variable is +not currently implemented. +.IP MaxReTry +sets the number of times a connection is re-tried before giving up (the +default is twice). +.SH SEE ALSO +.BR apt (8), +.BR apt-get (8) +.SH BUGS +See . If you wish to report a +bug in +.BR apt-get , +please see +.I /usr/doc/debian/bug-reporting.txt +or the +.BR bug (1) +command. +.SH AUTHOR +APT was written by the APT team . diff --git a/doc/guide.sgml b/doc/guide.sgml new file mode 100644 index 000000000..bbc01b78b --- /dev/null +++ b/doc/guide.sgml @@ -0,0 +1,548 @@ + + + +APT User's Guide + +Jason Gunthorpe jgg@debian.org +$Id: guide.sgml,v 1.1 1998/07/02 02:58:12 jgg Exp $ + + +This document provides an overview of how to use the the APT package manager. + + + +Copyright © Jason Gunthorpe, 1998. +

+"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. + +

+For more details, on Debian GNU/Linux systems, see the file +/usr/doc/copyright/GPL for the full license. + + + + + + +General + +

+The APT package currently contains two sections, the APT dselect +method and the apt-get command line user interface. Both provide +a way to install and remove packages as well as download new packages from +the Internet. + +Anatomy of the Package System +

+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. + +

+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. + +

+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. + +

+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. + +

+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. + +

+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. + +

+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. + + + + + + +apt-get + +

+apt-get provides a simple way to install packages from the command +line. Unlike dpkg, apt-get does not understand .deb files, +it works with the packages proper name and can only install .deb archives from +a Source. + +

+The first If you are using an http proxy server you must set the +http_proxy environment variable first, see sources.list(5) thing that +should be done before using apt-get is to fetch the package lists +from the Sources so that it knows what packages are +available. This is done with apt-get update. For instance, + +

+ +# 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 + + +

+Once updated there are several useful commands that can be used, + +upgrade +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. +Dselect or apt-get install can be used to force these +packages to install. + +install +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 + +dist-upgrade +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 dselect. +Once dist-upgrade has completed then dselect can be used to install +any packages that may have been left out. + +

+It is important to closely look at what dist-upgrade is going to do, its +decisions may sometimes be quite surprising. + + +

+apt-get has several command line options that are detailed in it's +man page, . The most useful option is +-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 -d is used the downloaded +archives can be installed by simply running the command that caused them to +be downloaded again without -d. + + + + + +DSelect +

+The APT dselect method provides the complete APT system with +the dselect package selection GUI. dselect is used to +select the packages to be installed or removed and APT actually installs them. + +

+To enable the APT method you need to to select [A]ccess in dselect +and then choose the APT method. You will be prompted for a set of +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. + +

+ + 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]: + + +

+The 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. + +

+ + 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]: + + +

+The distribution refers to the Debian version in the archive, stable +refers to the latest released version and unstable refers to the +developmental version. 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. +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 + +

+ + Please give the components to get + The components are typically something like: main contrib non-free + + Components [main contrib non-free]: + + +

+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. + +

+Any number of sources can be added, the setup script will continue to +prompt until you have specified all that you want. + +

+Before starting to use dselect it is necessary to update the +available list by selecting [U]pdate from the menu. This is a super-set of +apt-get update that makes the fetched information available to +dselect. [U]pdate must be performed even if apt-get update +has been run before. + +

+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. + + + + + +The Interface + +

+Both that APT dselect method and 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. + +The dselect method actually is a set of wrapper scripts +to apt-get. The method actually provides more functionality than +is present in apt-get alone. + +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. + + +The Pre-Checks + +

+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 +apt-get check. +

+ +# apt-get check +Updating package file cache...done +Updating package status cache...done +Checking system integrity...ok + + +

+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 apt-get update has not been run to +synchronize with the 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. + +

+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 +apt-get will refuse to run. + +

+ +# 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 + + +

+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. + +

+There are two ways a system can get into a broken state like this. The +first is caused by dpkg missing some subtle relationships between +packages when performing upgrades. APT however considers all known +dependencies and attempts to prevent broken packages. 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. + +

+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 -f option to atp-get will cause APT to deduce a +possible solution to the problem and then continue on. The APT dselect +method always supplies the -f option to allow for easy continuation +of failed maintainer scripts. + +

+However, if the -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. + + + +The Status Report + +

+Before proceeding 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 -f option and any other relevant +activities to the command being executed. + +The Extra Package list +

+ +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 + + +

+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 install command. The listed packages are +often the result of an Auto Install. + + +The Packages to Remove +

+ +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 + + +

+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 -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. + + +The New Packages list +

+ +The following NEW packages will installed: + zlib1g xlib6g perl-base libgdbmg1 quake-lib gmp2 pgp-i python-base + + +

+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. + + +The Kept Back list +

+ +The following packages have been kept back + compface man-db tetex-base msql libpaper svgalib1 + gs snmp arena lynx xpat2 groff xscreensaver + + +

+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 apt-get install or by using dselect +to resolve their problems. + + +Held Packages warning +

+ +The following held packages will be changed: + cvs + + +

+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. + + +Final summary +

+Finally, APT will print out a summary of all the changes that will occur. + +

+ +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. + + +

+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. + + + + +The Status Display +

+During the download of archives and package files APT prints out a series of +status messages, + +

+ +# 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 + + +

+The lines starting with 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 +apt-get update estimates the percent done which causes some +inaccuracies. + +

+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 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. + +

+Inside of the single quote is an informative string indicating the progress +of the negotiation phase of the download. Typically it progresses from +Connecting to Waiting for file to Downloading or +Resuming. The final value is the number of bytes downloaded from the +remote site. Once the download beings this is represented as 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. + +

+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 -q option to remove the +status display. + + + +Dpkg + +

+APT uses dpkg for installing the archives and will switch +over to the dpkg interface once downloading is completed. +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. + + + + + + diff --git a/doc/sources.list.5 b/doc/sources.list.5 new file mode 100644 index 000000000..779f216bf --- /dev/null +++ b/doc/sources.list.5 @@ -0,0 +1,177 @@ +.\" $Id: sources.list.5,v 1.1 1998/07/02 02:58:12 jgg Exp $ +.\" This manpage is copyright (C) 1998 Branden Robinson . +.\" +.\" This is free software; you may redistribute it and/or modify +.\" it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2, +.\" or (at your option) any later version. +.\" +.\" This is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public +.\" License along with APT; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +.\" 02111-1307 USA +.TH sources.list 5 "16 June 1998" "Debian GNU/Linux" +.SH NAME +sources.list \- package resource list for APT +.SH DESCRIPTION +The package resource list is used to locate archives of the package +distribution system in use on the system. At this time, this manual page +documents only the packaging system used by the Debian GNU/Linux system. +.PP +The source list is designed to support any number of active sources and a +variety of source media. The file lists one source per line, with the +most preferred source listed first. The format of each line is: +.I type uri args +The first item, +.IR type , +determines the format for +.IR args . +.I uri +is a Universal Resource Identifier (URI), which is a superset of the more +specific and well-known Universal Resource Locator, or URL. +.SS The deb type +The +.B deb +type describes a typical two-level Debian archive, +.IR distribution / component . +Typically, +.I distribution +is one of +.BR stable , +.BR unstable , +or +.BR frozen , +while component is one of +.BR main , +.BR contrib , +.BR non-free , +or +.BR non-us . +The format for a +.I sources.list +entry using the +.B deb +type is: +.RS +deb +.I uri distribution +.RI [ component +.I ... +] +.RE +The URI for the +.B deb +type must specify the base of the Debian distribution, from which +.B APT +will find the information it needs. +.I distribution +can specify an exact path, in which case the +.IR component s +must be omitted and +.I distribution +must end with a slash (/). This is useful for when only a particular +sub-section of the archive denoted by the URI is of interest. +If +.I distribution +does not specify an exact path, at least one +.I component +must be present. +.PP +.I distribution +may also contain a variable, +.BR $(ARCH) , +which expands to the Debian architecture (i386, m68k, powerpc, ...) +used on the system. This permits archiecture-independent +.I sources.list +files to be used. +.PP +Since only one distribution can be specified per line it may be necessary +to have multiple lines for the same URI, if a subset of all available +distributions or components at that location is desired. +.B APT +will sort the URI list after it has generated a complete set internally, +and will collapse multiple references to the same Internet host, for +instance, into a single connection, so that it does not inefficiently +establish an FTP connection, close it, do something else, and then +re-establish a connection to that same host. This feature is useful +for accessing busy FTP sites with limits on the number of simultaneous +anonymous users. +.PP +It is important to list sources in order of preference, with the most +preferred source listed first. Typically this will result in sorting +by speed from fastest to slowest (CD-ROM followed by hosts on a local +network, followed by distant Internet hosts, for example). +.SS URI specification +The three currently recognized URI types are file, http, and ftp. +.IP file +The file scheme allows an arbitrary directory in the file system to be +considered an archive. This is useful for NFS mounts and local mirrors or +archives. +.IP http +The http scheme specifies an HTTP server for the archive. If an environment +variable +.B $http_proxy +is set with the format +.\" Ugly hackery ahead, nroff doesn't like three different typefaces in a +.\" row with no spaces between anything. +.BI http:// server : port /\c +, the proxy server specified in +.B $http_proxy +will be used. Users of +authenticated HTTP/1.1 proxies may use a string of the format +.BI http:// user : pass @ server : port /\c +.\" For some reason, starting the next line with \. didn't work. So we kludge. +\&. Note that this is an insecure method of authentication. +.IP ftp +The ftp scheme specifies an FTP server for the archive. APT's FTP behavior +is highly configurable; for more information see the +.BR ftp.conf (5) +manual page. +.SH EXAMPLES +.IP "deb file:/home/jason/debian stable main contrib non-free" +Uses the archive stored locally (or NFS mounted) at +.I /home/jason/debian +for stable/main, stable/contrib, and stable/non-free. +.IP "deb file:/home/jason/debian unstable main contrib non-free" +As above, except this uses the unstable (development) distribution. +.IP "deb http://www.debian.org/archive stable main" +Uses HTTP to access the archive at www.debian.org, and uses only the +stable/main area. +.IP "deb ftp://ftp.debian.org/debian stable contrib" +Uses FTP to access the archive at ftp.debian.org, under the debian +directory, and uses only the stable/contrib area. +.IP "deb ftp://ftp.debian.org/debian unstable contrib" +Uses FTP to access the archive at ftp.debian.org, under the debian +directory, and uses only the unstable/contrib area. If this line appears as +well as the one in the previous example in +.IR sources.list , +a single FTP session will be used for both resource lines. +.IP "deb ftp://nonus.debian.org/debian-non-US unstable/binary-i386/" +Uses FTP to access the archive at nonus.debian.org, under the debian-non-US +directory, and uses only files found under unstable/binary-i386. +.IP "deb http://ftp.de.debian.org/debian-non-US unstable/binary-$(ARCH)/" +Uses HTTP to access the archive at nonus.debian.org, under the +debian-non-US directory, and uses only files found under +unstable/binary-i386 on i386 machines, unstable/binary-m68k on m68k, and so +forth for other supported architectures. +.SH SEE ALSO +.BR apt (8), +.BR apt-cache (8), +.BR apt-get (8), +.BR ftp.conf (5) +.SH BUGS +See . If you wish to report a +bug in +.BR apt-get , +please see +.I /usr/doc/debian/bug-reporting.txt +or the +.BR bug (1) +command. +.SH AUTHOR +APT was written by the APT team . -- cgit v1.2.3