Explorar o código

Added some control over how dpkg is invoked
Author: jgg
Date: 1999-01-31 08:49:39 GMT
Added some control over how dpkg is invoked

Arch Librarian %!s(int64=22) %!d(string=hai) anos
pai
achega
6dd55be709
Modificáronse 4 ficheiros con 135 adicións e 12 borrados
  1. 107 8
      apt-pkg/deb/dpkgpm.cc
  2. 5 2
      apt-pkg/deb/dpkgpm.h
  3. 15 0
      doc/apt.conf.5.yo
  4. 8 2
      doc/examples/apt.conf

+ 107 - 8
apt-pkg/deb/dpkgpm.cc

@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // 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;
       return false;
    
    
    List.push_back(Item(Item::Remove,Pkg));
    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 */
 /* This globs the operations and calls dpkg */
 bool pkgDPkgPM::Go()
 bool pkgDPkgPM::Go()
 {
 {
+   if (RunScripts("DPkg::Pre-Invoke") == false)
+      return false;
+   
    for (vector<Item>::iterator I = List.begin(); I != List.end();)
    for (vector<Item>::iterator I = List.begin(); I != List.end();)
    {
    {
       vector<Item>::iterator J = I;
       vector<Item>::iterator J = I;
@@ -94,6 +172,20 @@ bool pkgDPkgPM::Go()
       Args[n++] = _config->Find("Dir::Bin::dpkg","dpkg").c_str();
       Args[n++] = _config->Find("Dir::Bin::dpkg","dpkg").c_str();
       Size += strlen(Args[n-1]);
       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)
       switch (I->Op)
       {
       {
 	 case Item::Remove:
 	 case Item::Remove:
@@ -154,12 +246,12 @@ bool pkgDPkgPM::Go()
 	 it doesn't die but we do! So we must also ignore it */
 	 it doesn't die but we do! So we must also ignore it */
       signal(SIGQUIT,SIG_IGN);
       signal(SIGQUIT,SIG_IGN);
       signal(SIGINT,SIG_IGN);
       signal(SIGINT,SIG_IGN);
-	     
+		     
       // Fork dpkg
       // Fork dpkg
       pid_t Child = fork();
       pid_t Child = fork();
       if (Child < 0)
       if (Child < 0)
 	 return _error->Errno("fork","Could't fork");
 	 return _error->Errno("fork","Could't fork");
-      
+            
       // This is the child
       // This is the child
       if (Child == 0)
       if (Child == 0)
       {
       {
@@ -169,7 +261,7 @@ bool pkgDPkgPM::Go()
 	 signal(SIGWINCH,SIG_DFL);
 	 signal(SIGWINCH,SIG_DFL);
 	 signal(SIGCONT,SIG_DFL);
 	 signal(SIGCONT,SIG_DFL);
 	 signal(SIGTSTP,SIG_DFL);
 	 signal(SIGTSTP,SIG_DFL);
-
+	 
 	 if (chdir(_config->FindDir("Dir::Cache::Archives").c_str()) != 0)
 	 if (chdir(_config->FindDir("Dir::Cache::Archives").c_str()) != 0)
 	    _exit(100);
 	    _exit(100);
 	 
 	 
@@ -204,17 +296,24 @@ bool pkgDPkgPM::Go()
       {
       {
 	 if (errno == EINTR)
 	 if (errno == EINTR)
 	    continue;
 	    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
       // Restore sig int/quit
       signal(SIGQUIT,SIG_DFL);
       signal(SIGQUIT,SIG_DFL);
       signal(SIGINT,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;
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 5 - 2
apt-pkg/deb/dpkgpm.h

@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // -*- mode: cpp; mode: fold -*-
 // Description								/*{{{*/
 // 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
    // The Actuall installation implementation
    virtual bool Install(PkgIterator Pkg,string File);
    virtual bool Install(PkgIterator Pkg,string File);
    virtual bool Configure(PkgIterator Pkg);
    virtual bool Configure(PkgIterator Pkg);

+ 15 - 0
doc/apt.conf.5.yo

@@ -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.
 The default is to prompt only on error.
 enddit()
 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)
 manpagesection(Debug Options)
 Most of the options in the bf(debug) section are not interesting to the
 Most of the options in the bf(debug) section are not interesting to the
 normal user, however bf(Debug::pkgProblemResolver) shows interesting
 normal user, however bf(Debug::pkgProblemResolver) shows interesting

+ 8 - 2
doc/examples/apt.conf

@@ -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
 /* 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
    NOT actually be used as a real config file, though it is a completely
    valid file.
    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
    directory when the path is evaluated. This means you can use relative
    paths within the sub scope.
    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
 /* Options you can set to see some debugging text They corrispond to names
    of classes in the source code */
    of classes in the source code */
 Debug {
 Debug {