Hello...

Attached is a patch to 2.1.13 that will add an action= argument to
packages: items.  I submitted this a while back and nobody bit, but
there seemed to be interest in it afterward so I'm re-posting.  Sorry
for taking so long to re-post :(...

This patch is complete with docs additions to describe it, along with
some other small (mostly formatting) cleanups of the packages:
documentation.

In short, this adds the ability to do something like this:

control:
        actionsequence = ( packages )
        DefaultPkgMgr = ( rpm )
        RPMInstallCommand = ( /usr/sbin/up2date %s )

packages:
        foo     action=install
        bar     action=install
        baz     action=install

Any of the packages that are not installed will be grouped together and
installed after the package checks complete.  That is, after checking
for foo, bar, and baz, if for example foo and baz are found to not be
installed, then the following would be run:

/usr/sbin/up2date foo baz

Should be simple enough.  The next logical extension to this would be an
action=remove, and indeed I have placed skeleton code in to process
that, so action=remove will be accepted, but the operation is not
implemented at this time, mainly because I don't know how to deal with
package dependencies, or if I should even worry about them.

I used RPM as an example here, but all three supported package managers
*should* work.  You can actually use more than one package manager at
once, since each keeps its own to-be-installed list.  If folks could
test the Debian and Sun parts of this, it'd be greatly appreciated, as I
don't really have the facilities to do so ;).  Most of the code for this
is package manager agnostic, except for the part that decides which
variable to read for the install command (RPMInstallCommand,
DPKGInstallCommand, SUNInstallCommand), so I'm expecting it will Just
Work (tm).

Let me know if I can make this more useful...

-- 
Phil D'Amore                             "Sometimes there is a fine line
Senior System Administrator               between criminally abusive
Red Hat, Inc                              behavior and fun."
Office: 919.754.3700 x44395                 -- Ted the Generic Guy
Pager: 877.383.8795                            (Dilbert 4/19/2003)
diff -Naur cfengine-2.1.13.orig/doc/cfengine-Reference.texinfo cfengine-2.1.13/doc/cfengine-Reference.texinfo
--- cfengine-2.1.13.orig/doc/cfengine-Reference.texinfo	2005-01-23 03:08:01.000000000 -0500
+++ cfengine-2.1.13/doc/cfengine-Reference.texinfo	2005-02-24 22:45:07.000000000 -0500
@@ -2397,6 +2397,7 @@
 * deletenonownermail::          
 * domain::                      
 * dryrun::                      
+* dpkginstallcommand::                      
 * editbinaryfilesize::          
 * editfilesize::                
 * emptyresolvconf::             
@@ -2423,6 +2424,7 @@
 * repchar::                     
 * repository::                  
 * RPMcommand::                  
+* rpminstallcommand::                  
 * schedule::                    
 * secureinput::                 
 * sensiblecount::               
@@ -2435,6 +2437,7 @@
 * SplayTime::                   
 * split::                       
 * spooldirectories::            
+* suninstallcommand::                  
 * suspiciousnames::             
 * sysadm::                      
 * Syslog::                      
@@ -2654,8 +2657,10 @@
 @item packages
 executes commands defined under the @code{packages} section
 of the program.  This will query the system's package database
-for the specified packages, at the specified versions, and set
-classes based on whether or not those packages exist.
+for the specified packages, at the specified versions, set
+classes based on whether or not those packages exist, and
+optionally install those packages using a pre-defined package
+manager command.
 
 @item shellcommands
 executes all the commands defined under the @code{shellcommands}
@@ -3163,7 +3168,7 @@
 @c SUBSECTION
 @c .....................................................
 
[EMAIL PROTECTED] domain, dryrun, deletenonownermail, control
[EMAIL PROTECTED] domain, dpkginstallcommand, deletenonownermail, control
 @subsection domain
 @cindex domain
 @vindex domain
@@ -3187,7 +3192,26 @@
 @c SUBSECTION
 @c .....................................................
 
[EMAIL PROTECTED] dryrun, editbinaryfilesize, domain, control
[EMAIL PROTECTED] dpkginstallcommand, dryrun, domain, control
[EMAIL PROTECTED] DPKGInstallCommand
+
+Sets the command used to install packages that need to be installed
+under the DPKG package manager.
+
[EMAIL PROTECTED]
+DPKGInstallCommand = ( "/usr/bin/pkgmgr %s" )
[EMAIL PROTECTED] smallexample
+
+By default, this variable is not set, meaning that any packages with
+action=install will NOT be installed if installation is required.  Note
+the "'s around the string, and the %s is replaced with the list of
+packages to be installed, each separated by a ' ' (space).
+
[EMAIL PROTECTED] .....................................................
[EMAIL PROTECTED] SUBSECTION
[EMAIL PROTECTED] .....................................................
+
[EMAIL PROTECTED] dryrun, editbinaryfilesize, dpkginstallcommand, control
 @subsection DryRun
 @cindex DryRun
 @vindex DryRun
@@ -3963,7 +3987,7 @@
 @c SUBSECTION
 @c .....................................................
 
[EMAIL PROTECTED] RPMcommand, schedule, repository, control
[EMAIL PROTECTED] RPMcommand, rpminstallcommand, repository, control
 @subsection RPMcommand
 
 The default value of the Red Hat Package manager command @file{/bin/rpm} can be altered
@@ -3976,7 +4000,26 @@
 @c SUBSECTION
 @c .....................................................
 
[EMAIL PROTECTED] schedule, secureinput, RPMcommand, control
[EMAIL PROTECTED] rpminstallcommand, schedule, RPMcommand, control
[EMAIL PROTECTED] RPMInstallCommand
+
+Sets the command used to install packages that need to be installed
+under the RPM package manager.
+
[EMAIL PROTECTED]
+RPMInstallCommand = ( "/usr/bin/pkgmgr %s" )
[EMAIL PROTECTED] smallexample
+
+By default, this variable is not set, meaning that any packages with
+action=install will NOT be installed if installation is required.  Note
+the "'s around the string, and the %s is replaced with the list of
+packages to be installed, each separated by a ' ' (space).
+
[EMAIL PROTECTED] .....................................................
[EMAIL PROTECTED] SUBSECTION
[EMAIL PROTECTED] .....................................................
+
[EMAIL PROTECTED] schedule, secureinput, rpminstallcommand, control
 @subsection Schedule
 @cindex scheduling
 @vindex scheduling
@@ -4238,7 +4281,7 @@
 @c SUBSECTION
 @c .....................................................
 
[EMAIL PROTECTED] spooldirectories, suspiciousnames, split, control
[EMAIL PROTECTED] spooldirectories, suninstallcommand, split, control
 @subsection SpoolDirectories
 @cindex SpoolDirectories
 @vindex SpoolDirectories
@@ -4253,12 +4296,30 @@
   SpoolDirectories = ( /var/spool/cron/crontabs /var/spool/cron/atjobs )
 @end example
 
[EMAIL PROTECTED] .....................................................
[EMAIL PROTECTED] SUBSECTION
[EMAIL PROTECTED] .....................................................
+
[EMAIL PROTECTED] suninstallcommand, suspiciousnames, spooldirectories, control
[EMAIL PROTECTED] SUNInstallCommand
+
+Sets the command used to install packages that need to be installed
+under the SUN package manager.
+
[EMAIL PROTECTED]
+SUNInstallCommand = ( "/usr/bin/pkgmgr %s" )
[EMAIL PROTECTED] smallexample
+
+By default, this variable is not set, meaning that any packages with
+action=install will NOT be installed if installation is required.  Note
+the "'s around the string, and the %s is replaced with the list of
+packages to be installed, each separated by a ' ' (space).
 
 @c .....................................................
 @c SUBSECTION
 @c .....................................................
 
[EMAIL PROTECTED] suspiciousnames, sysadm, spooldirectories, control
[EMAIL PROTECTED] suspiciousnames, sysadm, suninstallcommand, control
 @subsection suspiciousnames
 @cindex suspiciousnames
 @vindex SuspiciousNames
@@ -8766,7 +8827,10 @@
 @cindex Checking for installed packages
 
 The packages action allows you to check for the existance of packages
-on the system, as determined by the package database you select.
+on the system, as determined by the package database you select.  Optionally,
+if a package install command was specified, the package can be installed
+if it is not there.
+
 This operation is set up such that it tries not to make assumptions about
 the package manager in use.  For example, it should be possible to use
 RPM on a Solaris box.
@@ -8781,20 +8845,18 @@
    @var{class}::
 
       @var{package-name}
-                        [EMAIL PROTECTED]/@var{rpm}
+                        [EMAIL PROTECTED]/@var{rpm/dpkg/sun}
                         [EMAIL PROTECTED]/@var{lt/gt/ge/le/ne}
                         [EMAIL PROTECTED]
                         [EMAIL PROTECTED](,:.)
                         [EMAIL PROTECTED](,:.)
+                        [EMAIL PROTECTED]/@var{install/remove}
 
                         [EMAIL PROTECTED] 
                         [EMAIL PROTECTED]
 
 @end smallexample
 @end cartouche
-
[EMAIL PROTECTED]
-Associated variables in control are @code{DefaultPkgMgr} and @code{RPMcommand}.
 @table @code
 
 @item cmp
@@ -8879,6 +8941,14 @@
 the package you really want, and specify it.  It may take a few extra
 extra seconds to check, but it will save you lots of headaches later.
 
[EMAIL PROTECTED] dpkg
[EMAIL PROTECTED] Debian Package Database Queries
+Please document me!
+
[EMAIL PROTECTED] sun
[EMAIL PROTECTED] Sun Package Database Queries
+Please document me!
+
 @end table
 
 @item define
@@ -8889,17 +8959,64 @@
 Specifies the list of classes to define if the specified package is not
 installed.
 
[EMAIL PROTECTED] action
+Specifies whether the packages should actually do anything about the
+situation it finds.  The default for this is to do nothing.  Of course,
+the classes in @code{define} and @code{elsedefine} will alwass be defined,
+as applicable, regardless of the action specified.
+
[EMAIL PROTECTED] @code
[EMAIL PROTECTED] install
+Installs the package using the command associated with the selected
+package manager, if it is not currently on the system at the requested
+version, as follows:
+
[EMAIL PROTECTED] @bullet
[EMAIL PROTECTED]
+RPM - 
+RPMInstallCommand
[EMAIL PROTECTED]
+DPKG - 
+DPKGInstallCommand
[EMAIL PROTECTED]
+SUN - 
+SUNInstallCommand
[EMAIL PROTECTED] itemize
+
+Each variable is of the format:
+
[EMAIL PROTECTED]
+FOOInstallCommand = ( "/usr/bin/foo --args %s --more-args" )
[EMAIL PROTECTED] smallexample
+
+The ---args are of course optional.  The %s is replaced with a space-separated
+list of the package names that were checked, and found to not be installed.
+
[EMAIL PROTECTED] remove
+CURRENTLY PARSED BUT NOT IMPLEMENTED
[EMAIL PROTECTED] table
 @end table
 
-Example:
[EMAIL PROTECTED]
+NOTE: classes are defined according to the result of the check, not
+any action performed as a result of that check.  In otherwords, if for
+example you have a situation where a package is not installed,
+and the action= is set to install, the classes in @code{elsedefine} will
+be defined @b{regardless} of whether or not the install was successful.
+Assuming the package installed, the next run of cfagent will pick up that
+fact.  This has to be done since the package installs are batched, so there
+is no reliable way to know if a given package was installed.
+
[EMAIL PROTECTED]
+Examples:
 
 @smallexample
 packages:
 
     redhat_8_0::
         m4  version=0:1.4.1-11 cmp=eq pkgmgr=rpm elsedefine=needsm4
-
 @end smallexample
+
 @noindent
 In this first example, we are looking for the m4 package at exactly version
 0:1.4.1-11.  The installed m4 package on a redhat_8_0 box has no epoch
@@ -8917,6 +9034,7 @@
         make version=0:4.5-2 cmp=ge define=hasmake elsedefine=needsmake
 
 @end smallexample
+
 @noindent
 In the second example, we use the DefaultPkgMgr variable to set the default
 for the @code{pkgmgr} attribute to @code{rpm}.  The actual version of make
@@ -8924,6 +9042,32 @@
 for greater than or equal to this version, the hasmake class will be
 defined.
 
[EMAIL PROTECTED]
+control:
+    redhat:;
+        DefaultPkgMgr = ( rpm )
+        RPMInstallCommand = ( "/usr/sbin/up2date %s" )
+
+packages:
+    redhat_8_0::
+        make define=hasmake elsedefine=needsmake action=install
[EMAIL PROTECTED] smallexample
+
[EMAIL PROTECTED]
+This example is much like the second example, except that if the package is
+not installed, cfengine will attempt to install it using the command in
+RPMInstallCommand, replacing the %s with the package name, @code{make}.
+If there were multiple packages specified in this way, the package installation
+would occur at the end of the package checks, and one command would be run,
+with %s replaced with a list of all package names.  In this example we chose
+not to use a version spec, but it is allowed, and as always, is optional.
+
[EMAIL PROTECTED]
+NOTE here that if make was not installed when the check is made,
[EMAIL PROTECTED] is defined, regardless of whether or not the
+install succeeds.  If the install is successful, the next cfagent
+run will define @code{hasmake}.
+
 @page
 
 @c -------------------------------------------------------------------------------
diff -Naur cfengine-2.1.13.orig/src/cf.defs.h cfengine-2.1.13/src/cf.defs.h
--- cfengine-2.1.13.orig/src/cf.defs.h	2005-01-17 17:24:51.000000000 -0500
+++ cfengine-2.1.13/src/cf.defs.h	2005-02-23 22:14:00.000000000 -0500
@@ -1163,6 +1163,15 @@
 
 /*******************************************************************/
 
+enum pkgactions /* What to do with a package if it is found/not found */
+    {
+    pkgaction_install,
+    pkgaction_remove,
+    pkgaction_none
+    };
+
+/*******************************************************************/
+
 typedef char flag;
 
 enum socks
@@ -1832,6 +1841,7 @@
    char              *ver;
    enum cmpsense     cmp;
    enum pkgmgrs      pkgmgr;
+   enum pkgactions   action;
    struct Package    *next;
    int ifelapsed;
    int expireafter;
diff -Naur cfengine-2.1.13.orig/src/cf.extern.h cfengine-2.1.13/src/cf.extern.h
--- cfengine-2.1.13.orig/src/cf.extern.h	2005-01-06 08:29:51.000000000 -0500
+++ cfengine-2.1.13/src/cf.extern.h	2005-02-23 22:14:00.000000000 -0500
@@ -463,6 +463,7 @@
 extern char *VRESOURCES[];
 extern char *CMPSENSETEXT[];
 extern char *PKGMGRTEXT[];
+extern char *PKGACTIONTEXT[];
 
 extern int VTIMEOUT;
 extern mode_t UMASK;
@@ -486,6 +487,7 @@
 extern enum cmpsense CMPSENSE;
 extern enum pkgmgrs PKGMGR;
 extern enum pkgmgrs DEFAULTPKGMGR;
+extern enum pkgactions PKGACTION;
 
 extern unsigned short PORTNUMBER;
 
diff -Naur cfengine-2.1.13.orig/src/do.c cfengine-2.1.13/src/do.c
--- cfengine-2.1.13.orig/src/do.c	2005-01-23 03:10:49.000000000 -0500
+++ cfengine-2.1.13/src/do.c	2005-02-23 22:14:00.000000000 -0500
@@ -2663,6 +2663,10 @@
 
 { struct Package *ptr;
   int match = 0;
+  int i;
+  /* pkgmgr_none will always be the highest number in the enum so set
+     the array size with that */
+  char *package_install_list[pkgmgr_none] = { NULL };
 
 for (ptr = VPKG; ptr != NULL; ptr=ptr->next)
    {
@@ -2705,6 +2709,38 @@
          CfLog(cferror,OUTPUT,"");
          break;
      }
+
+   /* Handle install/remove logic now. */
+   if (match)
+     {
+     if (ptr->action == pkgaction_remove)
+       {
+       match = match;
+       }
+     }
+   else
+     {
+     if (ptr->action == pkgaction_install)
+       {
+         /* Initial allocation of memory if we have not yet allocated any */
+         if(package_install_list[ptr->pkgmgr] == NULL)
+         {
+         package_install_list[ptr->pkgmgr] = malloc(CF_BUFSIZE);
+         ((char **)package_install_list[ptr->pkgmgr])[0] = NULL;
+         }
+
+         /* Make sure we don't overflow the buffer */
+         if(strlen(ptr->name) >
+           (CF_BUFSIZE - strlen(package_install_list[ptr->pkgmgr])))
+         {
+            Verbose("Package list exceeds CF_BUFSIZE.  Skipping %s", ptr->name);
+         }
+
+         /* Finally add the name to the list. */
+         strcat(package_install_list[ptr->pkgmgr], ptr->name);
+         strcat(package_install_list[ptr->pkgmgr], " ");
+       }
+     }
    
    if (match)
       {
@@ -2719,6 +2755,19 @@
    ReleaseCurrentLock();
    }
 
+/* Run through the package managers, and execute the package install
+ * for each of them... */
+for(i=0; i < pkgmgr_none; i++)
+{
+    if(package_install_list[i] != NULL)
+    {
+        Verbose("Package install list for %s is: %s\n", PKGMGRTEXT[i],
+                    package_install_list[i]);
+        InstallPackage(package_install_list[i], i);
+        free(package_install_list[i]);
+    }
+}
+
 }
 
 /*******************************************************************/
diff -Naur cfengine-2.1.13.orig/src/globals.c cfengine-2.1.13/src/globals.c
--- cfengine-2.1.13.orig/src/globals.c	2005-01-06 08:29:12.000000000 -0500
+++ cfengine-2.1.13/src/globals.c	2005-02-23 22:14:00.000000000 -0500
@@ -649,6 +649,15 @@
       NULL
       };
 
+  /*********************************************************************/
+  /* The names of the possible package-related actions */
+  PRIVATE char *PKGACTIONTEXT[] =
+      {
+      "install",
+      "remove",
+      NULL
+      };
+
 /*******************************************************************/
 /*                                                                 */
 /* parse object : variables belonging to the Parse object          */
@@ -802,6 +811,7 @@
   PRIVATE enum cmpsense CMPSENSE = cmpsense_eq; /* Comparison for packages: */
   PRIVATE enum pkgmgrs PKGMGR = pkgmgr_none;  /* Which package mgr to query */
   PRIVATE enum pkgmgrs DEFAULTPKGMGR = pkgmgr_none;
+  PRIVATE enum pkgactions PKGACTION = pkgaction_none;
 
   PRIVATE flag ACTION_IS_LINK = false;
   PRIVATE flag ACTION_IS_LINKCHILDREN = false;
diff -Naur cfengine-2.1.13.orig/src/install.c cfengine-2.1.13/src/install.c
--- cfengine-2.1.13.orig/src/install.c	2004-12-09 14:47:13.000000000 -0500
+++ cfengine-2.1.13/src/install.c	2005-02-23 22:14:00.000000000 -0500
@@ -1344,7 +1344,9 @@
                    break;
    case cfexpaft:  HandleIntSwitch("expireafter",value,&PEXPIREAFTER,0,999999);
                    break;
-
+   case cfaction:
+                   PKGACTION = (enum pkgactions) GetPkgAction(value);
+                   break;
    default:        yyerror("Illegal packages attribute");
    }
 }
@@ -2644,7 +2646,7 @@
        break;
        
    case packages:
-       InstallPackagesItem(CURRENTOBJECT,PKGVER,CMPSENSE,PKGMGR);
+       InstallPackagesItem(CURRENTOBJECT,PKGVER,CMPSENSE,PKGMGR,PKGACTION);
        break;
    }
 
@@ -4646,7 +4648,7 @@
 
 /*******************************************************************/
 
-void InstallPackagesItem(char *name,char *ver,enum cmpsense sense,enum pkgmgrs mgr)
+void InstallPackagesItem(char *name,char *ver,enum cmpsense sense,enum pkgmgrs mgr,enum pkgactions action)
 
 { struct Package *ptr;
   char buffer[CF_EXPANDSIZE];
@@ -4667,8 +4669,8 @@
    return;
    }
 
-Debug1("InstallPackagesItem(%s,%s,%s,%s)\n",
-        name,ver,CMPSENSETEXT[sense],PKGMGRTEXT[mgr]);
+Debug1("InstallPackagesItem(%s,%s,%s,%s,%s)\n",
+        name,ver,CMPSENSETEXT[sense],PKGMGRTEXT[mgr],PKGACTIONTEXT[action]);
 
 if ((ptr = (struct Package *)malloc(sizeof(struct Package))) == NULL)
    {
@@ -4738,6 +4740,7 @@
 ptr->inform = INFORMP;
 ptr->cmp = sense;
 ptr->pkgmgr = mgr;
+ptr->action = action;
 ptr->done = 'n';
 ptr->scope = strdup(CONTEXTID);
 
@@ -4783,6 +4786,23 @@
 
 /*******************************************************************/
 
+int GetPkgAction(char *pkgaction)
+
+{ int i;
+for (i = 0; PKGACTIONTEXT[i] != '\0'; i++)
+   {
+   if (strcmp(pkgaction,PKGACTIONTEXT[i]) == 0)
+      {
+      return i;
+      }
+   }
+
+yyerror("Unknown package action");
+return (int) pkgaction_none;
+}
+
+/*******************************************************************/
+
 void InstallImageItem(char *cf_findertype,char *path,mode_t plus,mode_t minus,char *destination,char *action,char *uidnames,char *gidnames,int size,char comp,int rec,char type,char lntype,char *server)
 
 { struct Image *ptr;
diff -Naur cfengine-2.1.13.orig/src/package.c cfengine-2.1.13/src/package.c
--- cfengine-2.1.13.orig/src/package.c	2004-10-10 03:42:51.000000000 -0400
+++ cfengine-2.1.13/src/package.c	2005-02-24 22:48:28.000000000 -0500
@@ -265,6 +265,105 @@
 return 0;
 }
 
+int InstallPackage(char *name, enum pkgmgrs pkgmgr)
+{
+    char rawinstcmd[CF_BUFSIZE];
+    /* Make the instcmd twice the normal buffer size since the package list
+       limit is CF_BUFSIZE so this can obviously get larger! */
+    char instcmd[CF_BUFSIZE*2];
+    char line[CF_BUFSIZE];
+    char *percent;
+    char *ptr;
+    FILE *pp;
+
+    /* Determine the command to use for the install. */
+    switch(pkgmgr)
+    {
+        /* RPM */
+        case pkgmgr_rpm:
+        if (!GetMacroValue(CONTEXTID,"RPMInstallCommand"))
+          {
+          Verbose("RPMInstallCommand NOT Set.  Package Installation Not Possible!\n");
+          return 0;
+          }
+        strncpy(rawinstcmd, GetMacroValue(CONTEXTID,"RPMInstallCommand"),
+                    CF_BUFSIZE);
+        break;
+
+        /* Debian */
+        case pkgmgr_dpkg:
+        if (!GetMacroValue(CONTEXTID,"DPKGInstallCommand"))
+          {
+          Verbose("DPKGInstallCommand NOT Set.  Package Installation Not Possible!\n");
+          return 0;
+          }
+        strncpy(rawinstcmd, GetMacroValue(CONTEXTID,"DPKGInstallCommand"),
+                    CF_BUFSIZE);
+        break;
+
+        /* Solaris */
+        case pkgmgr_sun:
+        if (!GetMacroValue(CONTEXTID,"SUNInstallCommand"))
+          {
+          Verbose("SUNInstallCommand NOT Set.  Package Installation Not Possible!\n");
+          return 0;
+          }
+        strncpy(rawinstcmd, GetMacroValue(CONTEXTID,"SUNInstallCommand"),
+                    CF_BUFSIZE);
+        break;
+
+        /* Default */
+        default:
+        Verbose("InstallPackage(): Unknown package manager %d\n",
+                    pkgmgr);
+        break;
+    }
+
+    /* Common to all pkg managers */
+
+    /* This could probably be a bit more complete, but I don't think
+        that anyone would want to expand the package name more than
+        once in a single command invocation anyhow. */
+    if (percent = strstr(rawinstcmd, "%s"))
+      {
+      *percent = '\0';
+      strncpy(instcmd, rawinstcmd, CF_BUFSIZE*2);
+      ptr = instcmd + strlen(rawinstcmd);
+      *percent = '%';
+      strcat(ptr, name);
+      ptr += strlen(name);
+      percent += 2;
+      strncpy(ptr, percent, (CF_BUFSIZE*2 - (ptr-instcmd)));
+      }
+    else
+      {
+      sprintf(instcmd, "%s %s", rawinstcmd, name);
+      }
+    Verbose("Installing package(s) %s using %s\n", name, instcmd);
+    if ((pp = cfpopen(instcmd, "r")) == NULL)
+      {
+      Verbose("Could not execute package install command\n");
+      /* Return that the package is still not installed */
+      return 0;
+      }
+    while (!feof(pp))
+      {
+      ReadLine(line,CF_BUFSIZE-1,pp);
+      printf("%s:package install: %s\n",VPREFIX,line);
+      }
+    if (cfpclose(pp) != 0)
+      {
+      Verbose("Package install command was not successful\n");
+      return 0;
+      }
+    return 1;
+}
+
+int RemovePackage(char *name, enum pkgmgrs pkgmgr)
+{
+    Verbose("Package removal not yet implemented");
+    return 1;
+}
 
 /*********************************************************************/
 /* Debian */
diff -Naur cfengine-2.1.13.orig/src/parse.c cfengine-2.1.13/src/parse.c
--- cfengine-2.1.13.orig/src/parse.c	2004-10-26 10:20:41.000000000 -0400
+++ cfengine-2.1.13/src/parse.c	2005-02-23 22:14:00.000000000 -0500
@@ -1248,6 +1248,7 @@
  VTIMEOUT=0;
 
  PKGMGR = DEFAULTPKGMGR; /* pkgmgr_none */
+ PKGACTION = pkgaction_none;
  CMPSENSE = cmpsense_eq;
  PKGVER[0] = '\0';
 
diff -Naur cfengine-2.1.13.orig/src/prototypes.h cfengine-2.1.13/src/prototypes.h
--- cfengine-2.1.13.orig/src/prototypes.h	2005-01-06 06:46:50.000000000 -0500
+++ cfengine-2.1.13/src/prototypes.h	2005-02-24 15:52:12.000000000 -0500
@@ -498,9 +498,10 @@
 void InstallImageItem ARGLIST((char *cf_findertype, char *path, mode_t plus, mode_t minus, char *destination, char *action, char *uidnames, char *gidnames, int size, char comp, int rec, char type, char lntype, char *server));
 void InstallMethod ARGLIST((char *function, char *file));
 void InstallAuthItem ARGLIST((char *path, char *attribute, struct Auth **list, struct Auth **listtop, char *classes));
-void InstallPackagesItem ARGLIST((char *name, char *ver, enum cmpsense sense, enum pkgmgrs mgr));
+void InstallPackagesItem ARGLIST((char *name, char *ver, enum cmpsense sense, enum pkgmgrs mgr, enum pkgactions action));
 int GetCmpSense ARGLIST((char *sense));
 int GetPkgMgr ARGLIST((char *mgr));
+int GetPkgAction ARGLIST((char *pkgaction));
 int GetCommAttribute ARGLIST((char *s));
 void HandleRecurse ARGLIST((char *value));
 void HandleCopyType ARGLIST((char *value));
@@ -852,6 +853,8 @@
 int RPMPackageCheck ARGLIST((char *package, char *version, enum cmpsense cmp));
 int DPKGPackageCheck ARGLIST((char *package, char *version, enum cmpsense cmp));
 int SUNPackageCheck ARGLIST((char *package, char *version, enum cmpsense cmp));
+int InstallPackage  ARGLIST((char *name, enum pkgmgrs pkgmgr));
+int RemovePackage  ARGLIST((char *name, enum pkgmgrs pkgmgr));
 
 /* popen.c */
 
_______________________________________________
Help-cfengine mailing list
Help-cfengine@gnu.org
http://lists.gnu.org/mailman/listinfo/help-cfengine

Reply via email to