diff options
Diffstat (limited to 'apt-pkg/deb')
-rw-r--r-- | apt-pkg/deb/debrecords.cc | 4 | ||||
-rw-r--r-- | apt-pkg/deb/debrecords.h | 4 | ||||
-rw-r--r-- | apt-pkg/deb/dpkgpm.cc | 197 | ||||
-rw-r--r-- | apt-pkg/deb/dpkgpm.h | 49 |
4 files changed, 250 insertions, 4 deletions
diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc index c28e11afb..c4019b48f 100644 --- a/apt-pkg/deb/debrecords.cc +++ b/apt-pkg/deb/debrecords.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: debrecords.cc,v 1.2 1998/10/08 04:55:02 jgg Exp $ +// $Id: debrecords.cc,v 1.3 1998/11/13 04:23:37 jgg Exp $ /* ###################################################################### Debian Package Records - Parser for debian package records @@ -25,7 +25,7 @@ debRecordParser::debRecordParser(FileFd &File) : Tags(File,4*1024) // RecordParser::Jump - Jump to a specific record /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debRecordParser::Jump(pkgCache::VerFileIterator &Ver) +bool debRecordParser::Jump(pkgCache::VerFileIterator const &Ver) { return Tags.Jump(Section,Ver->Offset); } diff --git a/apt-pkg/deb/debrecords.h b/apt-pkg/deb/debrecords.h index 6255d79ed..68fe0f6a6 100644 --- a/apt-pkg/deb/debrecords.h +++ b/apt-pkg/deb/debrecords.h @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: debrecords.h,v 1.2 1998/10/08 04:55:04 jgg Exp $ +// $Id: debrecords.h,v 1.3 1998/11/13 04:23:38 jgg Exp $ /* ###################################################################### Debian Package Records - Parser for debian package records @@ -31,7 +31,7 @@ class debRecordParser : public pkgRecords::Parser protected: - virtual bool Jump(pkgCache::VerFileIterator &Ver); + virtual bool Jump(pkgCache::VerFileIterator const &Ver); public: diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc new file mode 100644 index 000000000..75a5c77be --- /dev/null +++ b/apt-pkg/deb/dpkgpm.cc @@ -0,0 +1,197 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: dpkgpm.cc,v 1.1 1998/11/13 04:23:39 jgg Exp $ +/* ###################################################################### + + DPKG Package Manager - Provide an interface to dpkg + + ##################################################################### */ + /*}}}*/ +// Includes /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/dpkgpm.h" +#endif +#include <apt-pkg/dpkgpm.h> +#include <apt-pkg/error.h> +#include <apt-pkg/configuration.h> + +#include <unistd.h> +#include <stdlib.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <signal.h> +#include <errno.h> + /*}}}*/ + +// DPkgPM::pkgDPkgPM - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgDPkgPM::pkgDPkgPM(pkgDepCache &Cache) : pkgPackageManager(Cache) +{ +} + /*}}}*/ +// DPkgPM::pkgDPkgPM - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgDPkgPM::~pkgDPkgPM() +{ +} + /*}}}*/ +// DPkgPM::Install - Install a package /*{{{*/ +// --------------------------------------------------------------------- +/* Add an install operation to the sequence list */ +bool pkgDPkgPM::Install(PkgIterator Pkg,string File) +{ + if (File.empty() == true || Pkg.end() == true) + return _error->Error("Internal Error, No file name for %s",Pkg.Name()); + + List.push_back(Item(Item::Install,Pkg,File)); + return true; +} + /*}}}*/ +// DPkgPM::Configure - Configure a package /*{{{*/ +// --------------------------------------------------------------------- +/* Add a configure operation to the sequence list */ +bool pkgDPkgPM::Configure(PkgIterator Pkg) +{ + if (Pkg.end() == true) + return false; + + List.push_back(Item(Item::Configure,Pkg)); + return true; +} + /*}}}*/ +// DPkgPM::Remove - Remove a package /*{{{*/ +// --------------------------------------------------------------------- +/* Add a remove operation to the sequence list */ +bool pkgDPkgPM::Remove(PkgIterator Pkg) +{ + if (Pkg.end() == true) + return false; + + List.push_back(Item(Item::Remove,Pkg)); + return true; +} + /*}}}*/ +// DPkgPM::Go - Run the sequence /*{{{*/ +// --------------------------------------------------------------------- +/* This globs the operations and calls dpkg */ +bool pkgDPkgPM::Go() +{ + for (vector<Item>::iterator I = List.begin(); I != List.end();) + { + vector<Item>::iterator J = I; + for (; J != List.end() && J->Op == I->Op; J++); + + // Generate the argument list + const char *Args[400]; + if (J - I > 350) + J = I + 350; + + int n= 0; + Args[n++] = "dpkg"; + + switch (I->Op) + { + case Item::Remove: + Args[n++] = "--force-depends"; + Args[n++] = "--force-remove-essential"; + Args[n++] = "--remove"; + break; + + case Item::Configure: + Args[n++] = "--configure"; + break; + + case Item::Install: + Args[n++] = "--unpack"; + break; + } + + // Write in the file or package names + if (I->Op == Item::Install) + for (;I != J; I++) + Args[n++] = I->File.c_str(); + else + for (;I != J; I++) + Args[n++] = I->Pkg.Name(); + Args[n] = 0; + +/* for (int k = 0; k != n; k++) + cout << Args[k] << ' '; + cout << endl;*/ + + cout << flush; + clog << flush; + cerr << flush; + + /* Mask off sig int/quit. We do this because dpkg also does when + it forks scripts. What happens is that when you hit ctrl-c it sends + it to all processes in the group. Since dpkg ignores the signal + it doesn't die but we do! So we must also ignore it */ + signal(SIGQUIT,SIG_IGN); + signal(SIGINT,SIG_IGN); + + // Fork dpkg + pid_t Child = fork(); + if (Child < 0) + return _error->Errno("fork","Could't fork"); + + // This is the child + if (Child == 0) + { + signal(SIGQUIT,SIG_DFL); + signal(SIGINT,SIG_DFL); + signal(SIGWINCH,SIG_DFL); + signal(SIGCONT,SIG_DFL); + signal(SIGTSTP,SIG_DFL); + + if (chdir(_config->FindDir("Dir::Cache::Archives").c_str()) != 0) + exit(100); + + // Close all of our FDs - just in case + for (int K = 3; K != 40; K++) + fcntl(K,F_SETFD,FD_CLOEXEC); + + int Flags,dummy; + if ((Flags = fcntl(STDIN_FILENO,F_GETFL,dummy)) < 0) + exit(100); + + // Discard everything in stdin before forking dpkg + if (fcntl(STDIN_FILENO,F_SETFL,Flags | O_NONBLOCK) < 0) + exit(100); + + while (read(STDIN_FILENO,&dummy,1) == 1); + + if (fcntl(STDIN_FILENO,F_SETFL,Flags & (~(long)O_NONBLOCK)) < 0) + exit(100); + + /* No Job Control Stop Env is a magic dpkg var that prevents it + from using sigstop */ + setenv("DPKG_NO_TSTP","yes",1); + execvp("dpkg",(char **)Args); + cerr << "Could not exec dpkg!" << endl; + exit(100); + } + + // Wait for dpkg + int Status = 0; + while (waitpid(Child,&Status,0) != Child) + { + if (errno == EINTR) + continue; + return _error->Errno("waitpid","Couldn't wait for subprocess"); + } + + // Check for an error code. + if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) + return _error->Error("Sub-process returned an error code"); + + // Restore sig int/quit + signal(SIGQUIT,SIG_DFL); + signal(SIGINT,SIG_DFL); + } + return true; +} + /*}}}*/ diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h new file mode 100644 index 000000000..b5f08ea32 --- /dev/null +++ b/apt-pkg/deb/dpkgpm.h @@ -0,0 +1,49 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: dpkgpm.h,v 1.1 1998/11/13 04:23:39 jgg Exp $ +/* ###################################################################### + + DPKG Package Manager - Provide an interface to dpkg + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_DPKGPM_H +#define PKGLIB_DPKGPM_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/dpkgpm.h" +#endif + +#include <apt-pkg/packagemanager.h> +#include <vector> + +class pkgDPkgPM : public pkgPackageManager +{ + protected: + + struct Item + { + enum Ops {Install, Configure, Remove} Op; + string File; + PkgIterator Pkg; + Item(Ops Op,PkgIterator Pkg,string File = "") : Op(Op), + File(File), Pkg(Pkg) {}; + Item() {}; + + }; + vector<Item> List; + + // The Actuall installation implementation + virtual bool Install(PkgIterator Pkg,string File); + virtual bool Configure(PkgIterator Pkg); + virtual bool Remove(PkgIterator Pkg); + virtual bool Go(); + + public: + + pkgDPkgPM(pkgDepCache &Cache); + virtual ~pkgDPkgPM(); +}; + +#endif |