summaryrefslogtreecommitdiff
path: root/apt-pkg/deb
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/deb')
-rw-r--r--apt-pkg/deb/debrecords.cc4
-rw-r--r--apt-pkg/deb/debrecords.h4
-rw-r--r--apt-pkg/deb/dpkgpm.cc197
-rw-r--r--apt-pkg/deb/dpkgpm.h49
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