]> git.saurik.com Git - apt.git/commitdiff
Added some control over how dpkg is invoked
authorArch Librarian <arch@canonical.com>
Mon, 20 Sep 2004 16:52:37 +0000 (16:52 +0000)
committerArch Librarian <arch@canonical.com>
Mon, 20 Sep 2004 16:52:37 +0000 (16:52 +0000)
Author: jgg
Date: 1999-01-31 08:49:39 GMT
Added some control over how dpkg is invoked

apt-pkg/deb/dpkgpm.cc
apt-pkg/deb/dpkgpm.h
doc/apt.conf.5.yo
doc/examples/apt.conf

index b9c8cf968832dbb5e664a6b66d6056f0ccb5c6a5..9322a868d9d434e0d27197ba30818c392b3cfee9 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: dpkgpm.cc,v 1.5 1998/12/14 06:54:44 jgg Exp $
+// $Id: dpkgpm.cc,v 1.6 1999/01/31 08:49:39 jgg Exp $
 /* ######################################################################
 
    DPKG Package Manager - Provide an interface to dpkg
 /* ######################################################################
 
    DPKG Package Manager - Provide an interface to dpkg
@@ -71,6 +71,81 @@ bool pkgDPkgPM::Remove(PkgIterator Pkg)
       return false;
    
    List.push_back(Item(Item::Remove,Pkg));
       return false;
    
    List.push_back(Item(Item::Remove,Pkg));
+   return true;
+}
+                                                                       /*}}}*/
+// DPkgPM::RunScripts - Run a set of scripts                           /*{{{*/
+// ---------------------------------------------------------------------
+/* This looks for a list of script sto run from the configuration file,
+   each one is run with system from a forked child. */
+bool pkgDPkgPM::RunScripts(const char *Cnf)
+{
+   Configuration::Item const *Opts = _config->Tree(Cnf);
+   if (Opts == 0 || Opts->Child == 0)
+      return true;
+   Opts = Opts->Child;
+
+   // Fork for running the system calls
+   pid_t Child = fork();
+   if (Child < 0)
+      return _error->Errno("fork","Could't fork");
+   
+   // This is the child
+   if (Child == 0)
+   {
+      signal(SIGPIPE,SIG_DFL);
+      signal(SIGQUIT,SIG_DFL);
+      signal(SIGINT,SIG_DFL);
+      signal(SIGWINCH,SIG_DFL);
+      signal(SIGCONT,SIG_DFL);
+      signal(SIGTSTP,SIG_DFL);
+      
+      if (chdir("/tmp/") != 0)
+        _exit(100);
+        
+      // Close all of our FDs - just in case
+      for (int K = 3; K != 40; K++)
+        fcntl(K,F_SETFD,FD_CLOEXEC);
+
+      unsigned int Count = 1;
+      for (; Opts != 0; Opts = Opts->Next, Count++)
+      {
+        if (Opts->Value.empty() == true)
+           continue;
+        
+        if (system(Opts->Value.c_str()) != 0)
+           _exit(100+Count);
+      }
+      _exit(0);
+   }      
+
+   // Wait for the child
+   int Status = 0;
+   while (waitpid(Child,&Status,0) != Child)
+   {
+      if (errno == EINTR)
+        continue;
+      return _error->Errno("waitpid","Couldn't wait for subprocess");
+   }
+
+   // Restore sig int/quit
+   signal(SIGQUIT,SIG_DFL);
+   signal(SIGINT,SIG_DFL);   
+       
+   // Check for an error code.
+   if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
+   {
+      unsigned int Count = WEXITSTATUS(Status);
+      if (Count > 100)
+      {
+        Count -= 100;
+        for (; Opts != 0 && Count != 1; Opts = Opts->Next, Count--);
+        _error->Error("Probablem executing scripts %s '%s'",Cnf,Opts->Value.c_str());
+      }
+      
+      return _error->Error("Sub-process returned an error code");
+   }
+   
    return true;
 }
                                                                        /*}}}*/
    return true;
 }
                                                                        /*}}}*/
@@ -79,6 +154,9 @@ bool pkgDPkgPM::Remove(PkgIterator Pkg)
 /* This globs the operations and calls dpkg */
 bool pkgDPkgPM::Go()
 {
 /* This globs the operations and calls dpkg */
 bool pkgDPkgPM::Go()
 {
+   if (RunScripts("DPkg::Pre-Invoke") == false)
+      return false;
+   
    for (vector<Item>::iterator I = List.begin(); I != List.end();)
    {
       vector<Item>::iterator J = I;
    for (vector<Item>::iterator I = List.begin(); I != List.end();)
    {
       vector<Item>::iterator J = I;
@@ -94,6 +172,20 @@ bool pkgDPkgPM::Go()
       Args[n++] = _config->Find("Dir::Bin::dpkg","dpkg").c_str();
       Size += strlen(Args[n-1]);
       
       Args[n++] = _config->Find("Dir::Bin::dpkg","dpkg").c_str();
       Size += strlen(Args[n-1]);
       
+      // Stick in any custom dpkg options
+      Configuration::Item const *Opts = _config->Tree("DPkg::Options");
+      if (Opts != 0)
+      {
+        Opts = Opts->Child;
+        for (; Opts != 0; Opts = Opts->Next)
+        {
+           if (Opts->Value.empty() == true)
+              continue;
+           Args[n++] = Opts->Value.c_str();
+           Size += Opts->Value.length();
+        }       
+      }
+      
       switch (I->Op)
       {
         case Item::Remove:
       switch (I->Op)
       {
         case Item::Remove:
@@ -154,12 +246,12 @@ bool pkgDPkgPM::Go()
         it doesn't die but we do! So we must also ignore it */
       signal(SIGQUIT,SIG_IGN);
       signal(SIGINT,SIG_IGN);
         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");
       // Fork dpkg
       pid_t Child = fork();
       if (Child < 0)
         return _error->Errno("fork","Could't fork");
-      
+            
       // This is the child
       if (Child == 0)
       {
       // This is the child
       if (Child == 0)
       {
@@ -169,7 +261,7 @@ bool pkgDPkgPM::Go()
         signal(SIGWINCH,SIG_DFL);
         signal(SIGCONT,SIG_DFL);
         signal(SIGTSTP,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);
         
         if (chdir(_config->FindDir("Dir::Cache::Archives").c_str()) != 0)
            _exit(100);
         
@@ -204,17 +296,24 @@ bool pkgDPkgPM::Go()
       {
         if (errno == EINTR)
            continue;
       {
         if (errno == EINTR)
            continue;
+        RunScripts("DPkg::Post-Invoke");
         return _error->Errno("waitpid","Couldn't wait for subprocess");
       }
         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);
 
       // Restore sig int/quit
       signal(SIGQUIT,SIG_DFL);
       signal(SIGINT,SIG_DFL);
+       
+      // Check for an error code.
+      if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
+      {
+        RunScripts("DPkg::Post-Invoke");
+        return _error->Error("Sub-process returned an error code");
+      }      
    }
    }
+
+   if (RunScripts("DPkg::Post-Invoke") == false)
+      return false;
    return true;
 }
                                                                        /*}}}*/
    return true;
 }
                                                                        /*}}}*/
index dcb6e9db0b6e9a546edd0917f04c14062af23c8d..db6ce2a28879d2b8d3f884b390e00a3f5b9f792a 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: dpkgpm.h,v 1.2 1998/11/23 07:03:12 jgg Exp $
+// $Id: dpkgpm.h,v 1.3 1999/01/31 08:49:39 jgg Exp $
 /* ######################################################################
 
    DPKG Package Manager - Provide an interface to dpkg
 /* ######################################################################
 
    DPKG Package Manager - Provide an interface to dpkg
@@ -32,7 +32,10 @@ class pkgDPkgPM : public pkgPackageManager
       
    };
    vector<Item> List;
       
    };
    vector<Item> List;
-      
+
+   // Helpers
+   bool RunScripts(const char *Cnf);
+   
    // The Actuall installation implementation
    virtual bool Install(PkgIterator Pkg,string File);
    virtual bool Configure(PkgIterator Pkg);
    // The Actuall installation implementation
    virtual bool Install(PkgIterator Pkg,string File);
    virtual bool Configure(PkgIterator Pkg);
index c2807199b69a67c8c926a2ffce4e318c9b92ed77..feb7bbe53f20bd4746add3b94f4ffb41625494a3 100644 (file)
@@ -155,6 +155,21 @@ If true the [U]pdate operation in dselect will always prompt to continue.
 The default is to prompt only on error.
 enddit()
 
 The default is to prompt only on error.
 enddit()
 
+manpagesection(How APT calls DPkg)
+Several configuration directives control how APT invokes dpkg. These are in 
+the bf(DPkg) section.
+
+startdit()
+dit(bf(Options))
+This is a list of options to pass to dpkg. The options must be specified
+using the list notation and each list item is passed as a single arugment
+to dpkg.
+
+dit(bf(Pre-Invoke))
+This is a list of shell commands to run before invoking dpkg. 
+
+enddit()
+
 manpagesection(Debug Options)
 Most of the options in the bf(debug) section are not interesting to the
 normal user, however bf(Debug::pkgProblemResolver) shows interesting
 manpagesection(Debug Options)
 Most of the options in the bf(debug) section are not interesting to the
 normal user, however bf(Debug::pkgProblemResolver) shows interesting
index f4c147b3e04cc47824f352757df2345f632d6c1b..9e92fd4543c90269c22b442b934351ce42f3f651 100644 (file)
@@ -1,9 +1,9 @@
-// $Id: apt.conf,v 1.22 1999/01/31 06:24:46 jgg Exp $
+// $Id: apt.conf,v 1.23 1999/01/31 08:49:39 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.
    
 /* 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
+   In some instances involving 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.
    
    directory when the path is evaluated. This means you can use relative
    paths within the sub scope.
    
@@ -116,6 +116,12 @@ DSelect {
    PromptAfterUpdate "no";
 }
 
    PromptAfterUpdate "no";
 }
 
+DPkg {
+   Options {"--force-downgrade";}
+   Pre-Invoke {"mount -o remount,rw /usr";};
+   Post-Invoke {"mount -o remount,ro /usr";};
+}
+
 /* Options you can set to see some debugging text They corrispond to names
    of classes in the source code */
 Debug {
 /* Options you can set to see some debugging text They corrispond to names
    of classes in the source code */
 Debug {