Browse Source

Sync

Author: jgg
Date: 1998-10-30 07:53:30 GMT
Sync
debian/1.8.y
Arch Librarian 18 years ago
parent
commit
93bf083d69
  1. 36
      AUTHORS
  2. 14
      Makefile
  3. 38
      README.make
  4. 12
      apt-pkg/acquire-item.cc
  5. 245
      apt-pkg/acquire-method.cc
  6. 65
      apt-pkg/acquire-method.h
  7. 40
      apt-pkg/acquire-worker.cc
  8. 5
      apt-pkg/acquire-worker.h
  9. 125
      apt-pkg/acquire.cc
  10. 6
      apt-pkg/acquire.h
  11. 27
      apt-pkg/contrib/configuration.cc
  12. 4
      apt-pkg/contrib/configuration.h
  13. 114
      apt-pkg/contrib/strutl.cc
  14. 19
      apt-pkg/contrib/strutl.h
  15. 20
      apt-pkg/init.cc
  16. 4
      apt-pkg/makefile
  17. 8
      apt-pkg/tagfile.cc
  18. 4
      buildlib/defaults.mak
  19. 2
      buildlib/makefile.in
  20. 3
      configure.in
  21. 37
      doc/examples/apt.conf
  22. 30
      doc/method.sgml
  23. 167
      methods/copy.cc
  24. 168
      methods/file.cc
  25. 235
      methods/gzip.cc
  26. 13
      test/scratch.cc

36
AUTHORS

@ -0,0 +1,36 @@
NOTE: The ChangeLog generator will parse for names and email addresses. The
'CVS:<name>' tag should indicate who this pair refers to.
The project hierachy stands at:
CVS:bcwhite Brian White <bcwhite@verisim.com>
- Project Leader
- General organization, dispute resolution, final say on "capabilities"
CVS:jgg Jason Gunthorpe <jgg@gpu.srv.ualberta.ca>
- Chief Programmer
- Code organization, task breakdown, final say on "code"
CVS:tom Tom Lees <tom@lpsg.demon.co.uk>
- Dpkg Consultant
- Make system
- Expert on compatibility with existing dpkg, dependency algorithms, etc.
CVS:srivasta Manoj Srivastava <srivasta@datasync.com>
- Dependency Expert
CVS:behanw Behan Webster <behanw@verisim.com>
- Chief Designer
- Screen layout, ease of use, final say on "user interface"
CVS:che Ben Gertzfield <che@debian.org>
- Documentation
CVS:branden Branden Robinson <branden@purdue.edu>
- Man Page Documentation
CVS:scott Scott Ellis <storm@gate.net>
- .deb archive creater
CVS:doogie Adam Heath <doogie@debian.org>
- FTP method author

14
Makefile

@ -2,7 +2,9 @@
# This is the top level make file for APT, it recurses to each lower
# level make file and runs it with the proper target
ifndef NOISY
.SILENT:
endif
.PHONY: headers library clean veryclean all binary program doc
all headers library clean veryclean binary program doc:
@ -15,3 +17,15 @@ all headers library clean veryclean binary program doc:
.PHONY: maintainer-clean dist-clean distclean pristine sanity
maintainer-clean dist-clean distclean pristine sanity: veryclean
# The startup target builds the necessary configure scripts. It should
# be used after a CVS checkout.
.PHONY: startup
startup: configure
configure: aclocal.m4 configure.in
autoconf
aclocal.m4:
aclocal -I buildlib

38
README.make

@ -58,10 +58,16 @@ the source directory but is logically divided in the following manner
Only .o and .d files are placed in the obj/ subdirectory. The final compiled
binaries are placed in bin, published headers for inter-component linking
are placed in include/ and documentation is generated into doc/. This means
all runnable programs are within the bin/ directory a huge benifit for
all runnable programs are within the bin/ directory, a huge benifit for
debugging inter-program relationships. The .so files are also placed in
bin/ for simplicity.
By default make is put into silent mode. During operation there should be
no shell or compiler messages only status messages from the makefiles,
if any pop up that indicates there may be a problem with your environment.
For debugging you can disable this by setting NOISY=1, ala
make NOISY=1
Using the makefiles
~~~~~ ~~~ ~~~~~~~~~
The makefiles for the components are really simple. The complexity is hidden
@ -76,4 +82,32 @@ directories and other interesting features. They are more completely
described in the fragment code in buildlib. Some tips on writing fragments
are included in buildlib/defaults.mak
Jason
The fragments are NEVER processed by configure, so if you make changes to
them they will have an immediate effect.
Autoconf
~~~~~~~~
Straight out of CVS you have to initialize autoconf. This requires
automake (I really don't know why) and autoconf and requires doing
aclocal -I buidlib
autoconf
Autoconf is configured to do some basic system probes for optional and
required functionality and generate an environment.mak and include/config.h
from it's findings. It will then write a 'makefile' and run make dirs to
create the output directory tree.
It is not my belief that autoconf should be used to generate substantial
source code markup to escape OS problems. If an OS problem does crop up
it can likely be corrected by installing the correct files into the
build include/ dir and perhaps writing some replacement code and
linking it in. To the fullest extent possible the source code should conform
to standards and not cater to broken systems.
Autoconf will also wite a makefile into the top level of the build dir,
this simply acts as a wrapper to the main top level make in the source tree.
There is one big warning, you can't use both this make file and the
ones in the top level tree. Make is not able to resolve rules that
go to the same file through different paths and this will confuse the
depends mechanism. I recommend always using the makefiles in the
source directory and exporting BUILD

12
apt-pkg/acquire-item.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: acquire-item.cc,v 1.5 1998/10/26 07:11:43 jgg Exp $
// $Id: acquire-item.cc,v 1.6 1998/10/30 07:53:34 jgg Exp $
/* ######################################################################
Acquire Item - Item to acquire
@ -46,13 +46,17 @@ pkgAcquire::Item::~Item()
/*}}}*/
// Acquire::Item::Failed - Item failed to download /*{{{*/
// ---------------------------------------------------------------------
/* */
/* We return to an idle state if there are still other queues that could
fetch this object */
void pkgAcquire::Item::Failed(string Message)
{
Status = StatError;
ErrorText = LookupTag(Message,"Message");
Status = StatIdle;
if (QueueCounter <= 1)
{
ErrorText = LookupTag(Message,"Message");
Status = StatError;
Owner->Dequeue(this);
}
}
/*}}}*/
// Acquire::Item::Done - Item downloaded OK /*{{{*/

245
apt-pkg/acquire-method.cc

@ -0,0 +1,245 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: acquire-method.cc,v 1.1 1998/10/30 07:53:35 jgg Exp $
/* ######################################################################
Acquire Method
##################################################################### */
/*}}}*/
// Include Files /*{{{*/
#ifdef __GNUG__
#pragma implementation "apt-pkg/acquire-method.h"
#endif
#include <apt-pkg/acquire-method.h>
#include <apt-pkg/error.h>
#include <apt-pkg/configuration.h>
#include <strutl.h>
#include <apt-pkg/fileutl.h>
#include <stdio.h>
/*}}}*/
// AcqMethod::pkgAcqMethod - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* This constructs the initialization text */
pkgAcqMethod::pkgAcqMethod(const char *Ver,unsigned long Flags)
{
char S[300] = "";
char *End = S;
strcat(End,"100 Capabilities\n");
sprintf(End+strlen(End),"Version: %s\n",Ver);
if ((Flags & SingleInstance) == SingleInstance)
strcat(End,"Single-Instance: true\n");
if ((Flags & PreScan) == PreScan)
strcat(End,"Pre-Scan: true\n");
if ((Flags & Pipeline) == Pipeline)
strcat(End,"Pipeline: true\n");
if ((Flags & SendConfig) == SendConfig)
strcat(End,"Send-Config: true\n");
strcat(End,"\n");
if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
exit(100);
}
/*}}}*/
// AcqMethod::Fail - A fetch has failed /*{{{*/
// ---------------------------------------------------------------------
/* */
void pkgAcqMethod::Fail()
{
string Err = "Undetermined Error";
if (_error->empty() == false)
_error->PopMessage(Err);
_error->Discard();
Fail(Err);
}
/*}}}*/
// AcqMethod::Fail - A fetch has failed /*{{{*/
// ---------------------------------------------------------------------
/* */
void pkgAcqMethod::Fail(string Err)
{
char S[1024];
snprintf(S,sizeof(S),"400 URI Failure\nURI: %s\n"
"Message %s\n\n",CurrentURI.c_str(),Err.c_str());
if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
exit(100);
}
/*}}}*/
// AcqMethod::URIStart - Indicate a download is starting /*{{{*/
// ---------------------------------------------------------------------
/* */
void pkgAcqMethod::URIStart(FetchResult &Res,unsigned long Resume = 0)
{
char S[1024] = "";
char *End = S;
End += snprintf(S,sizeof(S),"200 URI Start\nURI: %s\n",CurrentURI.c_str());
if (Res.Size != 0)
End += snprintf(End,sizeof(S) - (End - S),"Size: %u\n",Res.Size);
if (Res.LastModified != 0)
End += snprintf(End,sizeof(S) - (End - S),"Last-Modified: %s\n",
TimeRFC1123(Res.LastModified).c_str());
if (Resume != 0)
End += snprintf(End,sizeof(S) - (End - S),"Resume-Point: %u\n",
Resume);
strcat(End,"\n");
if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
exit(100);
}
/*}}}*/
// AcqMethod::URIDone - A URI is finished /*{{{*/
// ---------------------------------------------------------------------
/* */
void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt)
{
char S[1024] = "";
char *End = S;
End += snprintf(S,sizeof(S),"201 URI Done\nURI: %s\n",CurrentURI.c_str());
if (Res.Filename.empty() == false)
End += snprintf(End,sizeof(S) - (End - S),"Filename: %s\n",Res.Filename.c_str());
if (Res.Size != 0)
End += snprintf(End,sizeof(S) - (End - S),"Size: %u\n",Res.Size);
if (Res.LastModified != 0)
End += snprintf(End,sizeof(S) - (End - S),"Last-Modified: %s\n",
TimeRFC1123(Res.LastModified).c_str());
if (Res.MD5Sum.empty() == false)
End += snprintf(End,sizeof(S) - (End - S),"MD5Sum: %s\n",Res.MD5Sum.c_str());
if (Res.IMSHit == true)
strcat(End,"IMS-Hit: true\n");
End = S + strlen(S);
if (Alt != 0)
{
if (Alt->Filename.empty() == false)
End += snprintf(End,sizeof(S) - (End - S),"Alt-Filename: %s\n",Alt->Filename.c_str());
if (Alt->Size != 0)
End += snprintf(End,sizeof(S) - (End - S),"Alt-Size: %u\n",Alt->Size);
if (Alt->LastModified != 0)
End += snprintf(End,sizeof(S) - (End - S),"Alt-Last-Modified: %s\n",
TimeRFC1123(Alt->LastModified).c_str());
if (Alt->MD5Sum.empty() == false)
End += snprintf(End,sizeof(S) - (End - S),"Alt-MD5Sum: %s\n",
Alt->MD5Sum.c_str());
if (Alt->IMSHit == true)
strcat(End,"Alt-IMS-Hit: true\n");
}
strcat(End,"\n");
if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S))
exit(100);
}
/*}}}*/
// AcqMethod::Configuration - Handle the configuration message /*{{{*/
// ---------------------------------------------------------------------
/* This parses each configuration entry and puts it into the _config
Configuration class. */
bool pkgAcqMethod::Configuration(string Message)
{
::Configuration &Cnf = *_config;
const char *I = Message.begin();
unsigned int Length = strlen("Config-Item");
for (; I + Length < Message.end(); I++)
{
// Not a config item
if (I[Length] != ':' || stringcasecmp(I,I+Length,"Config-Item") != 0)
continue;
I += Length + 1;
for (; I < Message.end() && *I == ' '; I++);
const char *Equals = I;
for (; Equals < Message.end() && *Equals != '='; Equals++);
const char *End = Equals;
for (; End < Message.end() && *End != '\n'; End++);
if (End == Equals)
return false;
Cnf.Set(string(I,Equals-I),string(Equals+1,End-Equals-1));
I = End;
}
return true;
}
/*}}}*/
// AcqMethod::Run - Run the message engine /*{{{*/
// ---------------------------------------------------------------------
/* */
int pkgAcqMethod::Run()
{
SetNonBlock(STDIN_FILENO,true);
while (1)
{
if (Messages.empty() == true)
if (WaitFd(STDIN_FILENO) == false)
return 0;
if (ReadMessages(STDIN_FILENO,Messages) == false)
return 0;
string Message = Messages.front();
Messages.erase(Messages.begin());
// Fetch the message number
char *End;
int Number = strtol(Message.c_str(),&End,10);
if (End == Message.c_str())
{
cerr << "Malformed message!" << endl;
return 100;
}
switch (Number)
{
case 601:
if (Configuration(Message) == false)
return 100;
break;
case 600:
{
CurrentURI = LookupTag(Message,"URI");
DestFile = LookupTag(Message,"FileName");
StrToTime(LookupTag(Message,"Last-Modified"),LastModified);
if (Fetch(Message,CurrentURI) == false)
Fail();
break;
}
}
}
return 0;
}
/*}}}*/
// AcqMethod::FetchResult::FetchResult - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
pkgAcqMethod::FetchResult::FetchResult() : LastModified(0),
IMSHit(false), Size(0)
{
}
/*}}}*/

65
apt-pkg/acquire-method.h

@ -0,0 +1,65 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: acquire-method.h,v 1.1 1998/10/30 07:53:35 jgg Exp $
/* ######################################################################
Acquire Method - Method helper class + functions
These functions are designed to be used within the method task to
ease communication with APT.
##################################################################### */
/*}}}*/
#ifndef PKGLIB_ACQUIRE_METHOD_H
#define PKGLIB_ACQUIRE_METHOD_H
#include <apt-pkg/configuration.h>
#include <strutl.h>
#ifdef __GNUG__
#pragma interface "apt-pkg/acquire-method.h"
#endif
class pkgAcqMethod
{
protected:
string CurrentURI;
string DestFile;
time_t LastModified;
vector<string> Messages;
struct FetchResult
{
string MD5Sum;
time_t LastModified;
bool IMSHit;
string Filename;
unsigned long Size;
FetchResult();
};
// Handlers for messages
virtual bool Configuration(string Message);
virtual bool Fetch(string Message,URI Get) {return true;};
// Outgoing messages
void Fail();
void Fail(string Why);
// void Log(const char *Format,...);
void URIStart(FetchResult &Res,unsigned long Resume = 0);
void URIDone(FetchResult &Res,FetchResult *Alt = 0);
public:
enum CnfFlags {SingleInstance = (1<<0), PreScan = (1<<1),
Pipeline = (1<<2), SendConfig = (1<<3)};
int Run();
pkgAcqMethod(const char *Ver,unsigned long Flags = 0);
virtual ~pkgAcqMethod() {};
};
#endif

40
apt-pkg/acquire-worker.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: acquire-worker.cc,v 1.7 1998/10/26 07:11:45 jgg Exp $
// $Id: acquire-worker.cc,v 1.8 1998/10/30 07:53:35 jgg Exp $
/* ######################################################################
Acquire Worker
@ -218,7 +218,7 @@ bool pkgAcquire::Worker::RunMessages()
{
if (Itm == 0)
{
_error->Warning("Method gave invalid 200 URI Start message");
_error->Error("Method gave invalid 200 URI Start message");
break;
}
CurrentItem = Itm;
@ -233,7 +233,7 @@ bool pkgAcquire::Worker::RunMessages()
{
if (Itm == 0)
{
_error->Warning("Method gave invalid 400 URI Failure message");
_error->Error("Method gave invalid 201 URI Done message");
break;
}
@ -248,7 +248,7 @@ bool pkgAcquire::Worker::RunMessages()
{
if (Itm == 0)
{
_error->Warning("Method gave invalid 400 URI Failure message");
_error->Error("Method gave invalid 400 URI Failure message");
break;
}
@ -417,35 +417,3 @@ bool pkgAcquire::Worker::MethodFailure()
return false;
}
/*}}}*/
// InjectConfiguration - Configuration aid for methods /*{{{*/
// ---------------------------------------------------------------------
/* */
bool pkgInjectConfiguration(string &Message,Configuration &Cnf)
{
const char *I = Message.begin();
unsigned int Length = strlen("Config-Item");
for (; I + Length < Message.end(); I++)
{
// Not a config item
if (I[Length] != ':' || stringcasecmp(I,I+Length,"Config-Item") != 0)
continue;
I += Length + 1;
for (; I < Message.end() && *I == ' '; I++);
const char *Equals = I;
for (; Equals < Message.end() && *Equals != '='; Equals++);
const char *End = Equals;
for (; End < Message.end() && *End != '\n'; End++);
if (End == Equals)
return false;
Cnf.Set(string(I,Equals-I),string(Equals+1,End-Equals-1));
I = End;
}
return true;
}
/*}}}*/

5
apt-pkg/acquire-worker.h

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: acquire-worker.h,v 1.5 1998/10/26 07:11:46 jgg Exp $
// $Id: acquire-worker.h,v 1.6 1998/10/30 07:53:36 jgg Exp $
/* ######################################################################
Acquire Worker - Worker process manager
@ -13,7 +13,6 @@
#define PKGLIB_ACQUIRE_WORKER_H
#include <apt-pkg/acquire.h>
#include <apt-pkg/configuration.h>
#ifdef __GNUG__
#pragma interface "apt-pkg/acquire-worker.h"
@ -81,6 +80,4 @@ class pkgAcquire::Worker
~Worker();
};
bool pkgInjectConfiguration(string &Message,Configuration &Cnf);
#endif

125
apt-pkg/acquire.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: acquire.cc,v 1.5 1998/10/26 07:11:47 jgg Exp $
// $Id: acquire.cc,v 1.6 1998/10/30 07:53:37 jgg Exp $
/* ######################################################################
Acquire - File Acquiration
@ -26,7 +26,7 @@
// Acquire::pkgAcquire - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
/* We grab some runtime state from the configuration space */
pkgAcquire::pkgAcquire()
{
Queues = 0;
@ -46,7 +46,7 @@ pkgAcquire::pkgAcquire()
/*}}}*/
// Acquire::~pkgAcquire - Destructor /*{{{*/
// ---------------------------------------------------------------------
/* Free our memory */
/* Free our memory, clean up the queues (destroy the workers) */
pkgAcquire::~pkgAcquire()
{
while (Items.size() != 0)
@ -69,7 +69,8 @@ pkgAcquire::~pkgAcquire()
/*}}}*/
// Acquire::Add - Add a new item /*{{{*/
// ---------------------------------------------------------------------
/* */
/* This puts an item on the acquire list. This list is mainly for tracking
item status */
void pkgAcquire::Add(Item *Itm)
{
Items.push_back(Itm);
@ -77,7 +78,7 @@ void pkgAcquire::Add(Item *Itm)
/*}}}*/
// Acquire::Remove - Remove a item /*{{{*/
// ---------------------------------------------------------------------
/* */
/* Remove an item from the acquire list. This is usually not used.. */
void pkgAcquire::Remove(Item *Itm)
{
for (vector<Item *>::iterator I = Items.begin(); I < Items.end(); I++)
@ -89,7 +90,8 @@ void pkgAcquire::Remove(Item *Itm)
/*}}}*/
// Acquire::Add - Add a worker /*{{{*/
// ---------------------------------------------------------------------
/* */
/* A list of workers is kept so that the select loop can direct their FD
usage. */
void pkgAcquire::Add(Worker *Work)
{
Work->NextAcquire = Workers;
@ -98,9 +100,14 @@ void pkgAcquire::Add(Worker *Work)
/*}}}*/
// Acquire::Remove - Remove a worker /*{{{*/
// ---------------------------------------------------------------------
/* */
/* A worker has died. This can not be done while the select loop is running
as it would require that RunFds could handling a changing list state and
it cant.. */
void pkgAcquire::Remove(Worker *Work)
{
if (Running == true)
abort();
Worker **I = &Workers;
for (; *I != 0;)
{
@ -113,7 +120,10 @@ void pkgAcquire::Remove(Worker *Work)
/*}}}*/
// Acquire::Enqueue - Queue an URI for fetching /*{{{*/
// ---------------------------------------------------------------------
/* */
/* This is the entry point for an item. An item calls this function when
it is construction which creates a queue (based on the current queue
mode) and puts the item in that queue. If the system is running then
the queue might be started. */
void pkgAcquire::Enqueue(Item *Itm,string URI,string Description)
{
// Determine which queue to put the item in
@ -129,15 +139,15 @@ void pkgAcquire::Enqueue(Item *Itm,string URI,string Description)
I = new Queue(Name,this);
I->Next = Queues;
Queues = I;
if (Running == true)
I->Startup();
}
// Queue it into the named queue
I->Enqueue(Itm,URI,Description);
ToFetch++;
if (Running == true)
I->Startup();
// Some trace stuff
if (Debug == true)
{
@ -149,12 +159,16 @@ void pkgAcquire::Enqueue(Item *Itm,string URI,string Description)
/*}}}*/
// Acquire::Dequeue - Remove an item from all queues /*{{{*/
// ---------------------------------------------------------------------
/* */
/* This is called when an item is finished being fetched. It removes it
from all the queues */
void pkgAcquire::Dequeue(Item *Itm)
{
Queue *I = Queues;
for (; I != 0; I = I->Next)
I->Dequeue(Itm);
if (Debug == true)
clog << "Dequeuing " << Itm->DestFile << endl;
ToFetch--;
}
/*}}}*/
@ -163,24 +177,20 @@ void pkgAcquire::Dequeue(Item *Itm)
/* The string returned depends on the configuration settings and the
method parameters. Given something like http://foo.org/bar it can
return http://foo.org or http */
string pkgAcquire::QueueName(string URI)
string pkgAcquire::QueueName(string Uri)
{
const MethodConfig *Config = GetConfig(URIAccess(URI));
URI U(Uri);
const MethodConfig *Config = GetConfig(U.Access);
if (Config == 0)
return string();
/* Single-Instance methods get exactly one queue per URI. This is
also used for the Access queue method */
if (Config->SingleInstance == true || QueueMode == QueueAccess)
return URIAccess(URI);
// Host based queue
string::iterator I = URI.begin();
for (; I < URI.end() && *I != ':'; I++);
for (; I < URI.end() && (*I == '/' || *I == ':'); I++);
for (; I < URI.end() && *I != '/'; I++);
return string(URI,0,I - URI.begin());
return U.Access;
return U.Access + ':' + U.Host;
}
/*}}}*/
// Acquire::GetConfig - Fetch the configuration information /*{{{*/
@ -234,7 +244,9 @@ void pkgAcquire::SetFds(int &Fd,fd_set *RSet,fd_set *WSet)
/*}}}*/
// Acquire::RunFds - Deal with active FDs /*{{{*/
// ---------------------------------------------------------------------
/* Dispatch active FDs over to the proper workers */
/* Dispatch active FDs over to the proper workers. It is very important
that a worker never be erased while this is running! The queue class
should never erase a worker except during shutdown processing. */
void pkgAcquire::RunFds(fd_set *RSet,fd_set *WSet)
{
for (Worker *I = Workers; I != 0; I = I->NextAcquire)
@ -273,15 +285,26 @@ bool pkgAcquire::Run()
Running = false;
return _error->Errno("select","Select has failed");
}
RunFds(&RFds,&WFds);
if (_error->PendingError() == true)
break;
}
for (Queue *I = Queues; I != 0; I = I->Next)
I->Shutdown();
Running = false;
return true;
return _error->PendingError();
}
/*}}}*/
// pkgAcquire::Bump - Called when an item is dequeued /*{{{*/
// ---------------------------------------------------------------------
/* This routine bumps idle queues in hopes that they will be able to fetch
the dequeued item */
void pkgAcquire::Bump()
{
}
/*}}}*/
@ -339,6 +362,9 @@ void pkgAcquire::Queue::Enqueue(Item *Owner,string URI,string Description)
Items->URI = URI;
Items->Description = Description;
Owner->QueueCounter++;
if (Items->Next == 0)
Cycle();
}
/*}}}*/
// Queue::Dequeue - Remove an item from the queue /*{{{*/
@ -368,7 +394,8 @@ bool pkgAcquire::Queue::Startup()
{
Shutdown();
pkgAcquire::MethodConfig *Cnf = Owner->GetConfig(URIAccess(Name));
URI U(Name);
pkgAcquire::MethodConfig *Cnf = Owner->GetConfig(U.Access);
if (Cnf == 0)
return false;
@ -376,11 +403,8 @@ bool pkgAcquire::Queue::Startup()
Owner->Add(Workers);
if (Workers->Start() == false)
return false;
Items->Worker = Workers;
Workers->QueueItem(Items);
return true;
return Cycle();
}
/*}}}*/
// Queue::Shutdown - Shutdown the worker processes /*{{{*/
@ -414,16 +438,41 @@ pkgAcquire::Queue::QItem *pkgAcquire::Queue::FindItem(string URI,pkgAcquire::Wor
// Queue::ItemDone - Item has been completed /*{{{*/
// ---------------------------------------------------------------------
/* The worker signals this which causes the item to be removed from the
queue. */
queue. If this is the last queue instance then it is removed from the
main queue too.*/
bool pkgAcquire::Queue::ItemDone(QItem *Itm)
{
Dequeue(Itm->Owner);
if (Itm->Owner->QueueCounter <= 1)
Owner->Dequeue(Itm->Owner);
else
{
Dequeue(Itm->Owner);
Owner->Bump();
}
if (Items == 0)
return Cycle();
}
/*}}}*/
// Queue::Cycle - Queue new items into the method /*{{{*/
// ---------------------------------------------------------------------
/* This locates a new idle item and sends it to the worker */
bool pkgAcquire::Queue::Cycle()
{
if (Items == 0 || Workers == 0)
return true;
Items->Worker = Workers;
Items->Owner->Status = pkgAcquire::Item::StatFetching;
return Workers->QueueItem(Items);
// Look for a queable item
QItem *I = Items;
for (; I != 0; I = I->Next)
if (I->Owner->Status == pkgAcquire::Item::StatIdle)
break;
// Nothing to do, queue is idle.
if (I == 0)
return true;
I->Worker = Workers;
I->Owner->Status = pkgAcquire::Item::StatFetching;
return Workers->QueueItem(I);
}
/*}}}*/

6
apt-pkg/acquire.h

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: acquire.h,v 1.5 1998/10/26 07:11:48 jgg Exp $
// $Id: acquire.h,v 1.6 1998/10/30 07:53:38 jgg Exp $
/* ######################################################################
Acquire - File Acquiration
@ -80,6 +80,9 @@ class pkgAcquire
// FDSET managers for derived classes
void SetFds(int &Fd,fd_set *RSet,fd_set *WSet);
void RunFds(fd_set *RSet,fd_set *WSet);
// A queue calls this when it dequeues an item
void Bump();
public:
@ -129,6 +132,7 @@ class pkgAcquire::Queue
bool Startup();
bool Shutdown();
bool Cycle();
Queue(string Name,pkgAcquire *Owner);
~Queue();

27
apt-pkg/contrib/configuration.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: configuration.cc,v 1.8 1998/10/22 04:56:45 jgg Exp $
// $Id: configuration.cc,v 1.9 1998/10/30 07:53:42 jgg Exp $
/* ######################################################################
Configuration Class
@ -212,6 +212,31 @@ bool Configuration::Exists(const char *Name)
return true;
}
/*}}}*/
// Configuration::Dump - Dump the config /*{{{*/
// ---------------------------------------------------------------------
/* Dump the entire configuration space */
void Configuration::Dump()
{
/* Write out all of the configuration directives by walking the
configuration tree */
const Configuration::Item *Top = _config->Tree(0);
for (; Top != 0;)
{
clog << Top->FullTag() << " \"" << Top->Value << "\";" << endl;
if (Top->Child != 0)
{
Top = Top->Child;
continue;
}
while (Top != 0 && Top->Next == 0)
Top = Top->Parent;
if (Top != 0)
Top = Top->Next;
}
}
/*}}}*/
// Configuration::Item::FullTag - Return the fully scoped tag /*{{{*/
// ---------------------------------------------------------------------

4
apt-pkg/contrib/configuration.h

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: configuration.h,v 1.6 1998/10/22 04:56:46 jgg Exp $
// $Id: configuration.h,v 1.7 1998/10/30 07:53:44 jgg Exp $
/* ######################################################################
Configuration Class
@ -65,6 +65,8 @@ class Configuration
bool Exists(const char *Name);
inline const Item *Tree(const char *Name) {return Lookup(Name,false);};
void Dump();
Configuration();
};

114
apt-pkg/contrib/strutl.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: strutl.cc,v 1.8 1998/10/24 04:58:07 jgg Exp $
// $Id: strutl.cc,v 1.9 1998/10/30 07:53:45 jgg Exp $
/* ######################################################################
String Util - Some usefull string functions.
@ -308,17 +308,6 @@ string URItoFileName(string URI)
return URI;
}
/*}}}*/
// URIAccess - Return the access method for the URI /*{{{*/
// ---------------------------------------------------------------------
/* */
string URIAccess(string URI)
{
string::size_type Pos = URI.find(':');
if (Pos == string::npos)
return URI;
return string(URI,0,Pos);
}
/*}}}*/
// Base64Encode - Base64 Encoding routine for short strings /*{{{*/
// ---------------------------------------------------------------------
/* This routine performs a base64 transformation on a string. It was ripped
@ -619,3 +608,104 @@ bool StrToTime(string Val,time_t &Result)
return true;
}
/*}}}*/
// URI::URI - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* This parses the URI into all of its components */
URI::URI(string U)
{
string::const_iterator I = U.begin();
// Locate the first colon, this seperates the scheme
for (; I < U.end() && *I != ':' ; I++);
string::const_iterator FirstColon = I;
// Determine if this is a host type URI with a leading double //
string::const_iterator SingleSlash = I;
if (I + 3 < U.end() && I[1] == '/' && I[2] == '/')
{
// Locate the single / that starts the path
for (; I < U.end(); I++)
{
if (*I == '/' && I[1] == '/')
I += 2;
else
if (*I == '/')
break;
}
if (I > U.end())
I = U.end();
SingleSlash = I;
}
// We can now write the access and path specifiers
Access = string(U,0,FirstColon - U.begin());
if (SingleSlash != U.end())
Path = string(U,SingleSlash - U.begin() + 1);
// Now we attempt to locate a user:pass@host fragment
FirstColon += 3;
if (FirstColon >= U.end())
return;
if (FirstColon > SingleSlash)
FirstColon = SingleSlash;
// Search for the @
I = FirstColon;
for (; I < SingleSlash && *I != '@'; I++);
string::const_iterator At = I;
// Colon in the @ section
I = FirstColon + 1;
for (; I < At && *I != ':'; I++);
string::const_iterator SecondColon = I;
// Now write the host and user/pass
if (At == SingleSlash)
{
if (FirstColon < SingleSlash)
Host = string(U,FirstColon - U.begin(),SingleSlash - FirstColon);
}
else
{
Host = string(U,At - U.begin() + 1,SingleSlash - At - 1);
User = string(U,FirstColon - U.begin(),SecondColon - FirstColon);
if (SecondColon < At)
Password = string(U,SecondColon - U.begin() + 1,At - SecondColon - 1);
}
// Now we parse off a pot number from the hostname
Port = 0;
string::size_type Pos = Host.rfind(':');
if (Pos == string::npos)
return;
Port = atoi(string(Host,Pos+1).c_str());
Host = string(Host,0,Pos);
}
/*}}}*/
// URI::operator string - Convert the URI to a string /*{{{*/
// ---------------------------------------------------------------------
/* */
URI::operator string()
{
string Res = Access + ':';
if (Host.empty() == false)
{
if (User.empty() == false)
{
Res += "//" + User;
if (Password.empty() == false)
Res += ":" + Password;
Res += "@";
}
Res += Host;
}
if (Path.empty() == false)
Res += "/" + Path;
return Res;
}
/*}}}*/

19
apt-pkg/contrib/strutl.h

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: strutl.h,v 1.7 1998/10/23 00:50:00 jgg Exp $
// $Id: strutl.h,v 1.8 1998/10/30 07:53:46 jgg Exp $
/* ######################################################################
String Util - These are some usefull string functions
@ -32,7 +32,6 @@ string TimeToStr(unsigned long Sec);
string SubstVar(string Str,string Subst,string Contents);
string Base64Encode(string Str);
string URItoFileName(string URI);
string URIAccess(string URI);
string TimeRFC1123(time_t Date);
bool StrToTime(string Val,time_t &Result);
string LookupTag(string Message,const char *Tag,const char *Default = 0);
@ -44,4 +43,20 @@ inline int stringcmp(const char *A,const char *AEnd,const char *B) {return strin
int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
inline int stringcasecmp(const char *A,const char *AEnd,const char *B) {return stringcasecmp(A,AEnd,B,B+strlen(B));};
class URI
{
public:
string Access;
string User;
string Password;
string Host;
string Path;
unsigned int Port;
operator string();
URI(string Path);
};
#endif

20
apt-pkg/init.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: init.cc,v 1.8 1998/10/20 02:39:19 jgg Exp $
// $Id: init.cc,v 1.9 1998/10/30 07:53:39 jgg Exp $
/* ######################################################################
Init - Initialize the package library
@ -9,6 +9,7 @@
/*}}}*/
// Include files /*{{{*/
#include <apt-pkg/init.h>
#include <config.h>
#include <sys/stat.h>
#include <unistd.h>
@ -22,7 +23,7 @@
bool pkgInitialize(Configuration &Cnf)
{
// General APT things
Cnf.Set("APT::Architecture","i386");
Cnf.Set("APT::Architecture",ARCHITECTURE);
// State
Cnf.Set("Dir::State","/var/state/apt/");
@ -45,12 +46,23 @@ bool pkgInitialize(Configuration &Cnf)
Cnf.Set("Dir::Etc","/etc/apt/");
Cnf.Set("Dir::Etc::sourcelist","sources.list");
Cnf.Set("Dir::Etc::main","apt.conf");
Cnf.Set("Dir::Bin::methods","/usr/lib/apt/metods");
// Read the main config file
string FName = Cnf.FindFile("Dir::Etc::main");
struct stat Buf;
if (stat(FName.c_str(),&Buf) != 0)
return true;
return ReadConfigFile(Cnf,FName);
// Read an alternate config file
const char *Cfg = getenv("APT_CONFIG");
if (ReadConfigFile(Cnf,FName) != true || ReadConfigFile(Cnf,Cfg) != true)
return false;
if (Cnf.FindB("Debug::pkgInitialize",false) == true)
Cnf.Dump();
return true;
}
/*}}}*/

4
apt-pkg/makefile

@ -23,7 +23,7 @@ SOURCE = contrib/mmap.cc contrib/error.cc contrib/strutl.cc \
SOURCE+= pkgcache.cc version.cc fileutl.cc pkgcachegen.cc depcache.cc \
orderlist.cc tagfile.cc sourcelist.cc packagemanager.cc \
pkgrecords.cc algorithms.cc acquire.cc acquire-item.cc \
acquire-worker.cc init.cc templates.cc
acquire-worker.cc acquire-method.cc init.cc templates.cc
# Source code for the debian specific components
SOURCE+= deb/deblistparser.cc deb/debrecords.cc
@ -33,7 +33,7 @@ HEADERS = algorithms.h depcache.h mmap.h pkgcachegen.h cacheiterators.h \
error.h orderlist.h sourcelist.h configuration.h fileutl.h \
packagemanager.h tagfile.h deblistparser.h init.h pkgcache.h \
version.h progress.h pkgrecords.h debrecords.h cmndline.h \
acquire.h acquire-worker.h acquire-item.h
acquire.h acquire-worker.h acquire-item.h acquire-method.h
HEADERS := $(addprefix apt-pkg/,$(HEADERS))

8
apt-pkg/tagfile.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: tagfile.cc,v 1.12 1998/10/24 04:58:06 jgg Exp $
// $Id: tagfile.cc,v 1.13 1998/10/30 07:53:41 jgg Exp $
/* ######################################################################
Fast scanner for RFC-822 type header information
@ -45,10 +45,7 @@ bool pkgTagFile::Step(pkgTagSection &Tag)
return false;
if (Tag.Scan(Start,End - Start) == false)
{
cout << string(Start,End-Start) << endl;
return _error->Error("Unable to parse package file");
}
}
Start += Tag.size();
iOffset += Tag.size();
@ -87,10 +84,7 @@ bool pkgTagFile::Fill()
else
{
if (Fd.Read(End,Size - (End - Buffer)) == false)
{
cout << "boink" << endl;
return false;
}
Left -= Size - (End - Buffer);
End = Buffer + Size;

4
buildlib/defaults.mak

@ -26,7 +26,9 @@
# but by explicly setting the BUILD variable. Make is invoked from
# within the source itself which is much more compatible with compilation
# environments.
ifndef NOISY
.SILENT:
endif
# Search for the build directory
ifdef BUILD
@ -51,7 +53,7 @@ BIN := $(BUILD)/bin
LIB := $(BIN)
OBJ := $(BUILD)/obj/$(SUBDIR)
DEP := $(OBJ)
DOC := $(BUILD)/doc
DOC := $(BUILD)/docs
# Module types
LIBRARY_H = $(BASE)/buildlib/library.mak

2
buildlib/makefile.in

@ -6,7 +6,7 @@
SRCDIR=@top_srcdir@
SUBDIRS:=./doc ./bin ./bin/methods ./obj ./include/apt-pkg ./include/deity
SUBDIRS+=./obj/doc ./obj/apt-pkg ./obj/deity ./obj/gui ./obj/cmdline \
SUBDIRS+=./obj/docs ./obj/apt-pkg ./obj/deity ./obj/gui ./obj/cmdline \
./obj/test ./obj/methods
BUILD:=$(shell pwd)
export BUILD

3
configure.in

@ -9,6 +9,9 @@ dnl some of the more populare bsd/sysv ones (like select). You'll also
dnl need a C++ compiler that is semi-standard conformant, exceptions are
dnl not used but STL is.
dnl 'make -f Makefile startup' will generate the configure file from
dnl configure.in correctly and can be run at any time
AC_INIT(configure.in)
AC_CONFIG_AUX_DIR(buildlib)
AC_CONFIG_HEADER(include/config.h:buildlib/config.h.in)

37
doc/examples/apt.conf

@ -1,12 +1,25 @@
// $Id: apt.conf,v 1.6 1998/10/26 07:11:51 jgg Exp $
// $Id: apt.conf,v 1.7 1998/10/30 07:53:50 jgg Exp $
/* This file is an index of all APT configuration directives. It should
NOT actually be used as a real config file, though it is a completely
valid file.
In some instances involing filenames it is possible to set the default
directory when the path is evaluated. This means you can use relative
paths within the sub scope.
The configuration directives are specified in a tree with {} designating
a subscope relative to the tag before the {}. You can further specify
a subscope using scope notation eg,
APT::Architecture "i386";
This is prefixed with the current scope. Scope notation must be used
if an option is specified on the command line with -o.
*/
// Options for APT in general
APT {
Architecture "i386";
// Options for apt-get
Get {
Download-Only "false";
Simulate "false";
@ -15,17 +28,20 @@ APT {
Show-Upgraded "false";
};
// Some general options
Ingore-Hold "false";
};
// Options for the downloading routines
Acquire
{
Queue-Mode "access"; // host|access
};
// Directory layout
Dir
{
// Location of the state dir
State "/var/state/apt/"
{
lists "lists/";
@ -34,20 +50,23 @@ Dir
status "/var/lib/dpkg/status";
};
// Location of the cache dir
Cache "/var/cache/apt/" {
archives "archives/";
srcpkgcache "srcpkgcache.bin";
pkgcache "pkgcache.bin";
};
// Config files
Etc "/etc/apt/" {
sourcelist "sources.list.test";
sourcelist "sources.list";
main "apt.conf";
};
// Locations of binaries
Bin {
methods "/home/jgg/work/apt/build/bin/methods/";
gzip "gzip";
gzip "/bin/gzip";
};
};
@ -55,10 +74,12 @@ DSelect {
}
/* Options you can set to see some debugging text They corrispond to names
of classes in the source code */
Debug {
pkgProblemResolver "true";
pkgProblemResolver "false";
pkgAcquire "false";
pkgAcquire::Worker "true";
pkgAcquire::Worker "false";
pkgInitialize "false"; // This one will dump the configuration space
}
dir::state::lists "/tmp/lists/";

30
doc/method.sgml

@ -4,7 +4,7 @@
<title>APT Method Interface </title>
<author>Jason Gunthorpe <email>jgg@debian.org</email></author>
<version>$Id: method.sgml,v 1.3 1998/10/08 04:55:06 jgg Exp $</version>
<version>$Id: method.sgml,v 1.4 1998/10/30 07:53:49 jgg Exp $</version>
<abstract>
This document describes the interface that APT uses to the archive
@ -128,15 +128,6 @@ are opened for use by the method allowing two way communication and
emergency error reporting. The FD's corrispond to the well known unix FD's,
stdin, stdout and stderr.
<p>
The basic startup sequence depends on how the method is invoked. If any
command line arguments are passed then the method should start in
automatic mode. This facility is provided soley to make the methods
easier to test and perhaps use outside of APT. Upon startup the method
will print out a header describing its capabilities and requirements.
After that it either begins processing the command line arugments and
exits when done or waits for commands to be fed to it.
<p>
Throught operation of the method communication is done via http
style plain text. Specifically RFC-822 (like the Package file) fields
@ -175,7 +166,6 @@ status code is an informational string provided for visual debugging.
<item>601 Configuration - Sends the configuration space
<item>602 Authorization Credentials - Response to the 402 message
<item>603 Media Changed - Response to the 403 message
<item>605 Shutdown - Exit
</list>
Only the 6xx series of status codes is sent TO the method. Furthermore
@ -208,6 +198,7 @@ The following is a short index of the header fields that are supported
<tag>URI<item>URI being described by the message
<tag>Filename<item>Location in the filesystem
<tag>Last-Modified<item>A time stamp in RFC1123 notation for use by IMS checks
<tag>IMS-Hit<item>The already existing item is valid
<tag>Size<item>Size of the file in bytes
<tag>Resume-Point<item>Location that transfer was started
<tag>MD5-Hash<item>Computed MD5 hash for the file
@ -225,6 +216,8 @@ the ones it wants.
This is a yes/no value.
<tag>Pre-Scan<item>Method can detect if archives are already available.
This is a yes/no value.
<tag>Pipeline<item>The method is capable of pipelining.
<tag>Send-Config<item>Send configuration to the method.
<tag>Version<item>Version string for the method
</taglist>
@ -232,8 +225,10 @@ This is a list of which headers each status code can use
<taglist>
<tag>100 Capabilities<item>
Displays the capabilities of the method.
Fields: Version, Single-Instance, Pre-Scan
Displays the capabilities of the method. Methods should set the
pipeline bit if their underlying protocol supports pipeling. The
only known method that does support pipelining is http.
Fields: Version, Single-Instance, Pre-Scan, Pipeline, Send-Config
<tag>101 Log<item>
A log message may be printed to the screen if debugging is enabled. This
@ -256,7 +251,9 @@ to specify a <em>201 URI Done</> without a <em>URI Start</> which would
mean no data was transfered but the file is now available. A Filename
field is specified when the URI is directly available in the local
pathname space. APT will either directly use that file or copy it into
another location.
another location. It is possible to return Alt-* feilds to indicate that
another possibility for the URI has been found in the local pathname space.
This is done if a decompressed version of a .gz file is found.
Fields: URI, Size, Last-Modified, Filename, MD5-Hash
<tag>400 URI Failure<item>
@ -305,11 +302,6 @@ Fields: Site, User, Password
This is sent in response to a <em>403 Media Failure</> message. It
indicates that the user has changed media and it is safe to proceed.
Fields: Media
<tag>605 Shutdown<item>
APT sends this to signal the shutdown of the method. The method should
terminate immidiately.
Fields: None
</taglist>
</sect>

167
methods/copy.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: copy.cc,v 1.3 1998/10/26 07:11:52 jgg Exp $
// $Id: copy.cc,v 1.4 1998/10/30 07:53:51 jgg Exp $
/* ######################################################################
Copy URI - This method takes a uri like a file: uri and copies it
@ -10,130 +10,75 @@
/*}}}*/
// Include Files /*{{{*/
#include <apt-pkg/fileutl.h>
#include <strutl.h>
#include <apt-pkg/acquire-method.h>
#include <apt-pkg/error.h>
#include <sys/stat.h>
#include <utime.h>
#include <unistd.h>
#include <stdio.h>
/*}}}*/
// Fail - Generate a failure message /*{{{*/
class CopyMethod : public pkgAcqMethod
{
virtual bool Fetch(string Message,URI Get);
public:
CopyMethod() : pkgAcqMethod("1.0",SingleInstance) {};
};
// CopyMethod::Fetch - Fetch a file /*{{{*/
// ---------------------------------------------------------------------
/* */
void Fail(string URI)
bool CopyMethod::Fetch(string Message,URI Get)
{
string Err = "Undetermined Error";
if (_error->empty() == false)
_error->PopMessage(Err);
string File = Get.Path;
// See if the file exists
FileFd From(File,FileFd::ReadOnly);
FileFd To(DestFile,FileFd::WriteEmpty);
To.EraseOnFailure();
if (_error->PendingError() == true)
return false;
printf("400 URI Failure\n"
"URI: %s\n"
"Message: %s\n\n",URI.c_str(),Err.c_str());
_error->Discard();
}
/*}}}*/
// Copy the file
if (CopyFile(From,To) == false)
return false;