Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 09 May 2007 01:33:13 -0700
From:      Jo Rhett <jrhett@svcolo.com>
To:        ports@freebsd.org
Subject:   full FreeBSD package/port support in CFengine
Message-ID:  <46418749.9020902@svcolo.com>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------050708070107010909070501
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

This is a copy of a posting made to the cfengine list.  I've added 
freebsd's package manager to the cfengine supported package commands, 
and actually updated it to handle package removal and upgrades.

This could seriously use some testing.  Please give it a test out, and 
report back on the cfengine list.  We're looking for complete support in 
2.2.1...

(these patches should apply to both 2.1.x and 2.2 equally.

-------- Original Message --------
Subject: full install/upgrade/remove package management patch
Date: Tue, 08 May 2007 22:48:55 -0700
From: Jo Rhett <jrhett@svcolo.com>
Organization: Silicon Valley Colocation
To: help-cfengine <help-cfengine@cfengine.org>

Attached is a patch which provides full install/upgrade/remove package
management in a generic sense.

NOTES:

1. Please run this by hand with "-v" option.  If you have any problems,
I need to see the "-v" output to know what's going on.  Yes, right now
it's probably too verbose -- I'll fix that later.

2. Right now only FreeBSD has a working remove command.  I'll happily
integrate other package managers as soon as someone provides me with the
details necessary to do so.  I could make a best guess, but that could
be really tricky without a test platform.

---  Previous message about the original patch

Okay, here is a fully tested and properly working patch for freebsd.

It works like this:

control:
   DefaultPkgMgr = ( freebsd )
   FreeBSDInstallCommand = ( "/var/cfengine/packages/pkginstall %s" )

packages:
   bsdsar-1.10_2 action=install
                 version=1.10_2
                 cmp=ge

Note that specifying the version of the package that is part of the 
freebsd package filename is required.  However, it does not use this for 
comparison, just for the package to install.  So you could install 1.10 
only if nothing larger than 1.0 was installed.

packages:
   bsdsar-1.10_2 action=install
                 version=1.0
                 cmp=ge

You can also backgrade if you know that 1.2 is bad for instance.

packages:
   bsdsar-1.10_2 action=install
                 version=1.1
                 cmp=gt

Now, due to the unfortunate fact that freebsd doesn't provide a command 
line option -- only an environment variable -- for specifying the source 
repository, you have a few options.

Get it from the main FreeBSD binary package home:

   FreeBSDInstallCommand = ( "pkg_add -r %s" )

Or write a script that tells pkg_add where to find it, like so:

   FreeBSDInstallCommand = ( "/var/cfengine/packages/pkginstall %s" )

#!/bin/sh
PACKAGESITE=http://my.local.repository/packages/
export PACKAGESITE
/usr/sbin/pkg_add -r $*

or even

#!/bin/sh
cd /my/local/repository
for pkg in $*
/usr/sbin/pkg_add ${pkg}.tbz

YMMV on all this stuff.

pkg_add really needs a command line option instead of only using the 
environment variables...

-- 
Jo Rhett
senior geek
Silicon Valley Colocation

--------------050708070107010909070501
Content-Type: text/plain;
 name="package-mgmt.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="package-mgmt.patch"

--- cf.defs.h_orig	Thu May  3 13:34:39 2007
+++ cf.defs.h	Tue May  8 13:31:07 2007
@@ -1215,6 +1215,7 @@
    pkgmgr_sun,
    pkgmgr_aix,
    pkgmgr_portage,
+   pkgmgr_freebsd,
    pkgmgr_none
    };
 
@@ -1224,6 +1225,7 @@
     {
     pkgaction_install,
     pkgaction_remove,
+    pkgaction_upgrade,
     pkgaction_none
     };
 
--- globals.c-new	Fri May  4 15:46:20 2007
+++ globals.c	Tue May  8 13:33:16 2007
@@ -745,6 +745,18 @@
       NULL
       };
 
+  PRIVATE char *CMPSENSEOPERAND[] =
+      {
+      "=",
+      ">",
+      "<",
+      ">=",
+      "<=",
+      "!=",
+      NULL,
+      NULL
+      };
+
   /*********************************************************************/
   /* The names of the available package managers */
 
@@ -765,6 +777,7 @@
       {
       "install",
       "remove",
+      "upgrade",
       NULL
       };
 
--- prototypes.h-new	Mon May  7 16:08:32 2007
+++ prototypes.h	Tue May  8 22:37:59 2007
@@ -875,14 +875,9 @@
 void DoAlerts (void);
 
 /* package.c */
-int RPMPackageCheck (char *package, char *version, enum cmpsense cmp);
-int DPKGPackageCheck (char *package, char *version, enum cmpsense cmp);
-int SUNPackageCheck (char *package, char *version, enum cmpsense cmp);
-int PortagePackageCheck (char *package, char *version, enum cmpsense cmp);
-int AIXPackageCheck (char *package, char *version, enum cmpsense cmp);
-int FreeBSDPackageCheck (char *package, char *version, enum cmpsense cmp);
+int PackageCheck (char *package, enum pkgmgrs pkgmgr, char *version, enum cmpsense cmp);
 int InstallPackage  (char *name, enum pkgmgrs pkgmgr);
-int RemovePackage  (char *name, enum pkgmgrs pkgmgr);
+int RemovePackage  (char *name, enum pkgmgrs pkgmgr, char *version, enum cmpsense cmp);
 
 /* popen.c */
 
--- do.c-new	Fri May  4 15:33:26 2007
+++ do.c	Tue May  8 22:11:07 2007
@@ -2688,11 +2688,12 @@
 
 { struct Package *ptr;
   int match = 0;
-  int i;
+  int result = 0;
   char lock[CF_BUFSIZE];
   /* 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 };
+  char *package_remove_list[pkgmgr_none] = { NULL };
 
 for (ptr = VPKG; ptr != NULL; ptr=ptr->next)
    {
@@ -2718,68 +2719,41 @@
       continue;
       }
    
-   switch(ptr->pkgmgr)
-     {
-     case pkgmgr_rpm:
-       match = RPMPackageCheck(ptr->name, ptr->ver, ptr->cmp);
-       break;
-     case pkgmgr_dpkg:
-       match = DPKGPackageCheck(ptr->name, ptr->ver, ptr->cmp);
-       break;
-     case pkgmgr_sun:
-       match = SUNPackageCheck(ptr->name, ptr->ver, ptr->cmp);
-       break;
-     case pkgmgr_aix:
-       match = AIXPackageCheck(ptr->name, ptr->ver, ptr->cmp);
-       break;
-     case pkgmgr_portage:
-       match = PortagePackageCheck(ptr->name, ptr->ver, ptr->cmp);
-       break;
-     case pkgmgr_freebsd:
-       match = FreeBSDPackageCheck(ptr->name, ptr->ver, ptr->cmp);
-       break;
-     default:
-       /* UGH!  This should *never* happen.  GetPkgMgr() and
-        * InstallPackagesItem() should have caught this before it
-        * was ever installed!!!
-        * */
-         snprintf(OUTPUT,CF_BUFSIZE,"Internal error!  Tried to check package %s in an unknown database: %d.  This should never happen!\n", ptr->name, ptr->pkgmgr);
-         CfLog(cferror,OUTPUT,"");
-         break;
-     }
+   match = PackageCheck(ptr->name, ptr->pkgmgr, ptr->ver, ptr->cmp);
+   Verbose("Match status for %s is %u\n", ptr->name, match );
 
    /* 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)
+      {
+      if (ptr->action == pkgaction_remove) 
          {
-         package_install_list[ptr->pkgmgr] = malloc(CF_BUFSIZE);
-         ((char **)package_install_list[ptr->pkgmgr])[0] = NULL;
+         Verbose("Package removal for %s: %s\n", PKGMGRTEXT[ptr->pkgmgr], ptr->name );
+         RemovePackage( ptr->name, ptr->pkgmgr, ptr->ver, ptr->cmp );
          }
-
-         /* Make sure we don't overflow the buffer */
-         if(strlen(ptr->name) >
-           (CF_BUFSIZE - strlen(package_install_list[ptr->pkgmgr])))
+      else if (ptr->action == pkgaction_upgrade)
          {
-            Verbose("Package list exceeds CF_BUFSIZE.  Skipping %s", ptr->name);
+         Verbose("Package removal for %s: %s\n", PKGMGRTEXT[ptr->pkgmgr], ptr->name );
+         if( RemovePackage( ptr->name, ptr->pkgmgr, ptr->ver, ptr->cmp ) ) 
+            {
+            Verbose("Package install for %s: %s\n", PKGMGRTEXT[ptr->pkgmgr], ptr->name );
+            InstallPackage( ptr->name, ptr->pkgmgr );
+            }
+         else 
+            {
+            Verbose("Package %s cannot be upgraded because the old version was not removed.\n", ptr->name );
+            }
          }
-
-         /* Finally add the name to the list. */
-         strcat(package_install_list[ptr->pkgmgr], ptr->name);
-         strcat(package_install_list[ptr->pkgmgr], " ");
-       }
-     }
+      }
+   else
+      {
+      if (ptr->action == pkgaction_install)
+         {
+         Verbose("Package install for %s: %s\n", PKGMGRTEXT[ptr->pkgmgr], ptr->name );
+         InstallPackage( ptr->name, ptr->pkgmgr );
+         }
+      }
    
+   /* Not sure why we didn't do this above? */
    if (match)
       {
       AddMultipleClasses(ptr->defines);
@@ -2792,20 +2766,6 @@
    ptr->done = 'y';
    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]);
-    }
-}
-
 }
 
 /*******************************************************************/
--- package.c-new	Fri May  4 15:36:47 2007
+++ package.c	Tue May  8 22:48:05 2007
@@ -30,11 +30,23 @@
 /****************************************************************************/
 
 /* Local prototypes that nobody else should care about... */
-
-void ParseEVR(char * evr, const char **ep, const char **vp, const char **rp);
+int BuildCommandLine  (char *resolvedcmd, char* rawcmd, char*name );
+int RPMPackageCheck (char *package, char *version, enum cmpsense cmp);
+int RPMPackageList (char *package, char *version, enum cmpsense cmp, char *pkglist);
+int DPKGPackageCheck (char *package, char *version, enum cmpsense cmp);
+int DPKGPackageList (char *package, char *version, enum cmpsense cmp, char *pkglist);
+int SUNPackageCheck (char *package, char *version, enum cmpsense cmp);
+int SUNPackageList (char *package, char *version, enum cmpsense cmp, char *pkglist);
 void ParseSUNVR(char * vr, int *major, int *minor, int *micro);
+int PortagePackageCheck (char *package, char *version, enum cmpsense cmp);
+int PortagePackageList (char *package, char *version, enum cmpsense cmp, char *pkglist);
+int AIXPackageCheck (char *package, char *version, enum cmpsense cmp);
+int AIXPackageList (char *package, char *version, enum cmpsense cmp, char *pkglist);
 void ParseAIXVR(char * vr, int *ver, int *release, int *maint, int *fix);
+int FreeBSDPackageCheck (char *package, char *version, enum cmpsense cmp);
+int FreeBSDPackageList (char *package, char *version, enum cmpsense cmp, char *pkglist);
 int rpmvercmp(const char *a, const char *b);
+void ParseEVR(char * evr, const char **ep, const char **vp, const char **rp);
 int xislower(int c);
 int xisupper(int c);
 int xisalpha(int c);
@@ -271,8 +283,48 @@
 return 0;
 }
 
-/*********************************************************************************/
+int RPMPackageList (char *package, char *version, enum cmpsense cmp, char *pkglist)
+{
+   return 0; /* not implemented yet */
+}
+
+/* This is moved here to allow do.c to be ignorant of the various package managers */
+int PackageCheck(char* package, enum pkgmgrs pkgmgr, char *version,enum cmpsense cmp)
+{ int match=0;
+
+switch(pkgmgr)
+   {
+   case pkgmgr_rpm:
+      match = RPMPackageCheck(package, version, cmp);
+      break;
+   case pkgmgr_dpkg:
+      match = DPKGPackageCheck(package, version, cmp);
+      break;
+   case pkgmgr_sun:
+      match = SUNPackageCheck(package, version, cmp);
+      break;
+   case pkgmgr_aix:
+      match = AIXPackageCheck(package, version, cmp);
+      break;
+   case pkgmgr_portage:
+      match = PortagePackageCheck(package, version, cmp);
+      break;
+   case pkgmgr_freebsd:
+      match = FreeBSDPackageCheck(package, version, cmp);
+      break;
+   default:
+      /* UGH!  This should *never* happen.  GetPkgMgr() and
+       * InstallPackagesItem() should have caught this before it
+       * was ever installed!!!
+       * */
+       snprintf(OUTPUT,CF_BUFSIZE,"Internal error!  Tried to check package %s in an unknown database: %d.  This should never happen!\n", package, pkgmgr);
+       CfLog(cferror,OUTPUT,"");
+       break;
+   }
+return match;
+}
 
+/*********************************************************************************/
 int InstallPackage(char *name, enum pkgmgrs pkgmgr)
 
 { char rawinstcmd[CF_BUFSIZE];
@@ -280,12 +332,7 @@
     limit is CF_BUFSIZE so this can obviously get larger! */
  char instcmd[CF_BUFSIZE*2];
  char line[CF_BUFSIZE];
- char *percent;
  FILE *pp;
- char *ptr, *arg_ptr, *next_ptr;
- int instcmd_args, package_args;
- int instcmd_tail_len = 0;
- int instcmd_len, arg_len;
 
 if (DONTDO)
    {
@@ -351,16 +398,16 @@
        strncpy(rawinstcmd, GetMacroValue(CONTEXTID,"PortageInstallCommand"),CF_BUFSIZE);
        break;
        
-       /* FreeBSD */
+   /* FreeBSD */
    case pkgmgr_freebsd:
        
-       if (!GetMacroValue(CONTEXTID,"FreeBSDInstallCommand"))
-          {
-          Verbose("FreeBSDInstallCommand NOT Set.  Package Installation Not Possible!\n");
-          return 0;
-          }
-       strncpy(rawinstcmd, GetMacroValue(CONTEXTID,"FreeBSDInstallCommand"),CF_BUFSIZE);
-       break;
+      if (!GetMacroValue(CONTEXTID,"FreeBSDInstallCommand"))
+         {
+         Verbose("FreeBSDInstallCommand NOT Set.  Package Installation Not Possible!\n");
+         return 0;
+         }
+      strncpy(rawinstcmd, GetMacroValue(CONTEXTID,"FreeBSDInstallCommand"),CF_BUFSIZE);
+      break;
        
        /* Default */
    default:
@@ -368,82 +415,10 @@
        break;
    }
 
-/* Common to all pkg managers */
-
-    /* How many words are there in the package manager invocation? */
-for (ptr = rawinstcmd, instcmd_args = 1; NULL != ptr; ptr = strchr(++ptr, ' '))
-   {
-   ++instcmd_args;
-   }
-
-/* 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';
-   percent += 2;
-   instcmd_tail_len = strlen(percent);
-   --instcmd_args;
-   }
-
-instcmd_len = strlen(rawinstcmd);
-
-/* Copy the initial part of the install command */
-strncpy(instcmd, rawinstcmd, CF_BUFSIZE*2);
-
-snprintf(OUTPUT,CF_BUFSIZE,"Installing package(s) %s using %s\n", name, instcmd);
-CfLog(cfinform,OUTPUT,"");
-
-if ((pp = cfpopen(instcmd, "r")) == NULL)
-   {
-   Verbose("Could not execute package install command\n");
-   /* Return that the package is still not installed */
-   return 0;
-   }
-
-  /* Loop over packages until we reach the maximum number that cfpopen
-     can take */
-
-ptr = name;
-
-while (NULL != ptr)
-   {
-   arg_ptr = &instcmd[instcmd_len];
-   
-   for (package_args = instcmd_args;(package_args < CF_MAXSHELLARGS) && (NULL != ptr);package_args++)
+   /* Common to all pkg managers */
+   if( BuildCommandLine( instcmd, rawinstcmd, name ) )
       {
-      next_ptr = strchr(ptr, ' ');
-      if (next_ptr)
-         {
-         *next_ptr = '\0';
-         }
-      
-      arg_len = strlen(ptr);
-      *arg_ptr++ = ' ';
-      strncpy(arg_ptr, ptr, &instcmd[CF_BUFSIZE*2] - arg_ptr);
-      arg_ptr += arg_len;
-      
-      if (next_ptr)
-         {
-         *next_ptr++ = ' ';
-         }
-      
-      ptr = next_ptr;
-      }
-   
-   if (arg_ptr != &instcmd[instcmd_len])
-      {      
-      /* Have a full command line, so append the tail, if necessary,
-         and run it */
-      
-      if (instcmd_tail_len > 0)
-         {
-         strncpy(arg_ptr, percent, &instcmd[CF_BUFSIZE*2] - arg_ptr);
-         }
-      
-      Verbose("Installing package group using %s\n", instcmd);
+      Verbose("Installing package using %s\n", instcmd);
       
       if ((pp = cfpopen(instcmd, "r")) == NULL)
          {
@@ -463,21 +438,174 @@
          Verbose("Package install command was not successful\n");
          return 0;
          }
+      return 1;
+      }
+      else 
+      {
+         Verbose("Unable to build package manager command.\n");
+         return 0;
       }
-   }
-
-return 1;
 }
 
-/*********************************************************************/
+int RemovePackage(char *name, enum pkgmgrs pkgmgr, char* version, enum cmpsense cmp)
+{  char rawdelcmd[CF_BUFSIZE];
+   /* The removal list could be considerably bigger than the original list */
+   char pkglist[CF_BUFSIZE*2];
+ /* Make the delcmd 3x the normal buffer size since the package list
+    limit is CF_BUFSIZE*2 so this can obviously get larger! */
+   char delcmd[CF_BUFSIZE*3];
+   char line[CF_BUFSIZE];
+   FILE *pp;
 
-int RemovePackage(char *name, enum pkgmgrs pkgmgr)
+   if (DONTDO)
+      {
+      Verbose("Need to remove package(s) %s\n",name);
+      return 0;
+      }
 
-{
-Verbose("Package removal not yet implemented");
-return 1;
+   /* Determine the command to use for the removal. */
+   switch(pkgmgr)
+      {
+      /* FreeBSD */
+      case pkgmgr_freebsd:
+         if (!GetMacroValue(CONTEXTID,"FreeBSDRemoveCommand"))
+            {
+         	strncpy(rawdelcmd, "/usr/sbin/pkg_delete %s", 23 );
+            }
+         else
+            {
+            strncpy(rawdelcmd, GetMacroValue(CONTEXTID,"FreeBSDRemoveCommand"),CF_BUFSIZE);
+            }
+
+         FreeBSDPackageList(name, version, cmp, pkglist);
+         break;
+       
+      /* Default */
+      default:
+         Verbose("Package removal not yet implemented for this package manager.");
+         break;
+      }
+   Verbose("Resolved packagelist is %s\n", pkglist);
+
+   if( BuildCommandLine( delcmd, rawdelcmd, pkglist ) )
+      {
+      Verbose("Removing package using %s\n", delcmd);
+         
+      if ((pp = cfpopen(delcmd, "r")) == NULL)
+         {
+         Verbose("Could not execute package removal command\n");
+         /* Return that the package is still not removed */
+         return 0;
+      }
+         
+      while (!feof(pp))
+         {
+         ReadLine(line,CF_BUFSIZE-1,pp);
+         snprintf(OUTPUT,CF_BUFSIZE,"Package removal: %s\n",line);
+         }
+         
+      if (cfpclose(pp) != 0)
+         {
+         Verbose("Package removal command was not successful\n");
+         return 0;
+         }
+      return 1;
+      }
+   else 
+      {
+      Verbose("Unable to evaluate package manager command.\n");
+      return 0;
+      }
 }
 
+int BuildCommandLine(char *resolvedcmd, char* rawcmd, char* name)   
+{ 
+   char *cmd_tail;
+   FILE *pp;
+   char *ptr, *arg_ptr, *next_ptr;
+   int cmd_args = 0;
+   int cmd_tail_len = 0;
+   int cmd_len, arg_len;
+
+    /* How many words are there in the package manager invocation? */
+   for (ptr = rawcmd, cmd_args = 1; NULL != ptr; ptr = strchr(++ptr, ' '))
+      {
+      ++cmd_args;
+      }
+
+   /* 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 (cmd_tail = strstr(rawcmd, "%s"))
+      {
+      *cmd_tail = '\0';
+      cmd_tail += 2;
+      cmd_tail_len = strlen(cmd_tail);
+      --cmd_args;
+      }
+   
+   cmd_len = strlen(rawcmd);
+   
+   /* Copy the initial part of the install command */
+   strncpy(resolvedcmd, rawcmd, CF_BUFSIZE*2);
+   
+   snprintf(OUTPUT,CF_BUFSIZE,"Package manager will be invoked as %s\n", resolvedcmd);
+   CfLog(cfinform,OUTPUT,"");
+   
+   if ((pp = cfpopen(resolvedcmd, "r")) == NULL)
+      {
+      Verbose("Could not execute package manager\n");
+      /* Return that the package is still not installed */
+      return 0;
+      }
+   
+   /* Loop over packages until we reach the maximum number that cfpopen can take */
+   ptr = name;
+   while (NULL != ptr)
+      {
+      
+      arg_ptr = &resolvedcmd[cmd_len];
+
+      /* Find each space, change to NULL, copy shortened string into arg_ptr, change back to space... */
+      for (;(cmd_args < CF_MAXSHELLARGS) && (NULL != ptr);cmd_args++)
+         {
+         next_ptr = strchr(ptr, ' ');
+         if (next_ptr)
+            {
+            *next_ptr = '\0';
+            }
+         
+
+         /* Skip double spaces */
+         if( arg_len = strlen(ptr) ) 
+            {
+            strncpy(arg_ptr, ptr, &resolvedcmd[CF_BUFSIZE*2] - arg_ptr);
+            arg_ptr += arg_len;
+            *arg_ptr++ = ' ';
+            }
+
+         if (next_ptr)
+            {
+            *next_ptr++ = ' ';
+            }
+         
+         ptr = next_ptr;
+         }
+      *--arg_ptr = '\0'; // Remove trailing space
+      
+      if (arg_ptr != &resolvedcmd[cmd_len])
+         {      
+         /* Have a full command line, so append the tail if necessary. */
+         if (cmd_tail_len > 0)
+            {
+            strncpy(arg_ptr, cmd_tail, &resolvedcmd[CF_BUFSIZE*2] - arg_ptr);
+            }
+         }
+      Verbose("Resolved command is '%s'\n", resolvedcmd );
+      }
+   return 1;
+}
+      
 /*********************************************************************/
 /* Debian                                                            */
 /*********************************************************************/
@@ -533,7 +661,7 @@
    ReadLine (VBUFF, CF_BUFSIZE, pp);
    if (*VBUFF != '\0')
       {
-      if (sscanf (VBUFF, "  Installed: %s", tmpBUFF) > 0)
+      if (sscanf (VBUFF, "  Removed: %s", tmpBUFF) > 0)
          {
          AppendItem (&evrlist, tmpBUFF, "");
          }
@@ -680,6 +808,11 @@
 return 0;
 }
 
+int DPKGPackageList (char *package, char *version, enum cmpsense cmp, char *pkglist)
+{
+   return 0; /* not implemented yet */
+}
+
 /*********************************************************************/
 /* Sun - pkginfo/pkgadd/pkgrm                                        */
 /*********************************************************************/
@@ -856,12 +989,17 @@
 return 0;
 }
 
+int SUNPackageList (char *package, char *version, enum cmpsense cmp, char *pkglist)
+{
+   return 0; /* not implemented yet */
+}
+
 /*********************************************************************/
 /* Sun's manual pages say that the version number is a major, minor,
  * and optional micro version number.  This code checks for that.
  * It will not handle other arbitrary and strange values people might
  * put in like "2.6d.12a" or "1.11 beta" or "pre-release 7"
- */
+/*********************************************************************/
 
 void ParseSUNVR (char * vr, int *major, int *minor, int *micro)
 {
@@ -1100,6 +1238,11 @@
 return 0;
 }
 
+int AIXPackageList(char *package, char *version, enum cmpsense cmp, char *pkglist)
+{
+   return 0; /* not implemented yet */
+}
+
 /*********************************************************************/
 /* AIX docs describe the version as:
  * Version.Release.Maintenance/Modification.Fix (V.R.M.F).  
@@ -1107,7 +1250,7 @@
  * numeric digits will be extracted.  standalone non-digits will be 
  * treated as 0 for the entire field.  V.R.M.F shouldn't contain any 
  * non numeric data (this is enforced by IBM tools like mkinstallp)
- */ 
+/*********************************************************************/
 
 void ParseAIXVR(char * vr, int *ver, int *release, int *maint, int *fix)
 {
@@ -1127,7 +1270,6 @@
     *fix = f;
 }
 
-
 /*********************************************************************/
 /* Gentoo Portage                                                    */
 /*********************************************************************/
@@ -1320,98 +1462,131 @@
 return 0;
 }
 
+int PortagePackageList(char *package, char *version, enum cmpsense cmp, char *pkglist)
+{
+   return 0; /* not implemented yet */
+}
+
 /*********************************************************************/
 /* FreeBSD - pkg_info/pkg_add/pkg_delete                             */
 /*********************************************************************/
 
 int FreeBSDPackageCheck(char *package,char *version,enum cmpsense cmp)
 
-{  FILE *pp;
-   int match = 0;
-   char line[CF_BUFSIZE];
-   char pkgname[CF_BUFSIZE];
-   char *pkgversion;
+{ FILE *pp;
+  int match = 0;
+  char line[CF_BUFSIZE];
+  char pkgname[CF_BUFSIZE];
+  char *pkgversion;
 
-   /* The package to install must contain a version number
-    * The version starts after the last '-' in the pkgname
-    */
+  /* The package to install must contain a version number
+   * The version starts after the last '-' in the pkgname
+   */
    strncpy(pkgname, package, CF_BUFSIZE - 1);
    pkgversion = strrchr(pkgname, '-');
    *pkgversion = '\0';
    pkgversion += 1;
 
-   Verbose("FreeBSDPackageCheck(): Requested version %s %s of %s\n", CMPSENSETEXT[cmp],(version[0] ? version : "ANY"), pkgname);
+  Verbose("FreeBSDPackageCheck(): Requested version %s %s of %s\n", CMPSENSETEXT[cmp],(version[0] ? version : "ANY"), pkgname);
 
   /* If no version was specified, we're just checking if the package
    * is present, not for a particular number, so >0 will match.
    */
-   if (!*version)
-      {
-      cmp = cmpsense_gt;
-      version[0] = '0';
-      version[1] = 0;
-      }
+  if (!*version)
+    {
+    cmp = cmpsense_gt;
+    version[0] = '0';
+    version[1] = 0;
+    }
 
-   /* Convert to > or < ... */
-   char compare_operator[3];
-   switch(cmp)
-      {
-      case cmpsense_gt:
-      	 compare_operator[0] = '>';
-      	 compare_operator[1] = 0;
-         break;
-      case cmpsense_lt:
-      	 compare_operator[0] = '<';
-      	 compare_operator[1] = 0;
-         break;
-      case cmpsense_ge:
-      	 compare_operator[0] = '>';
-      	 compare_operator[1] = '=';
-      	 compare_operator[2] = 0;
-         break;
-      case cmpsense_le:
-      	 compare_operator[0] = '<';
-      	 compare_operator[1] = '=';
-      	 compare_operator[2] = 0;
-         break;
-      case cmpsense_ne:
-      	 compare_operator[0] = '!';
-      	 compare_operator[1] = '=';
-      	 compare_operator[2] = 0;
-      default:
-         compare_operator[0] = '=';
-      	 compare_operator[1] = 0;
-         break;
-	  } 
+  /* check what version is installed on the system (if any) */
+  Verbose("FreeBSDPackageCheck(): Running /usr/sbin/pkg_info -qE '%s%s%s'\n", pkgname, CMPSENSEOPERAND[cmp], version);
+  snprintf (VBUFF, CF_BUFSIZE, "/usr/sbin/pkg_info -qE '%s%s%s'", pkgname, CMPSENSEOPERAND[cmp], version);
+
+  if ((pp = cfpopen (VBUFF, "r")) == NULL)
+    {
+    Verbose ("Could not execute pkg_info.\n");
+    return 0;
+    }
+
+  while (!feof (pp))
+    {
+    *VBUFF = '\0';
+    ReadLine (line, CF_BUFSIZE - 1, pp);
+    snprintf(OUTPUT,CF_BUFSIZE,"Package install: %s\n",line);
+    }
+
+  if (cfpclose (pp) == 0)
+    {
+    Verbose ("The package and version requested are installed in the package database.\n",package);
+    match=1;
+    }
+  else 
+    {
+    Verbose ("The package and version requested do not exist in the package database.\n",package);
+    match=0;
+    }
+  return match;
+}
+
+int FreeBSDPackageList(char *package, char *version, enum cmpsense cmp, char *pkglist)
+
+{ FILE *pp;
+  int match = 0;
+  char line[CF_BUFSIZE];
+  char pkgname[CF_BUFSIZE];
+  char *pkgversion;
+
+  /* The package name is derived by stripping off the version number
+   */
+   strncpy(pkgname, package, CF_BUFSIZE - 1);
+   pkgversion = strrchr(pkgname, '-');
+   *pkgversion = '\0';
+   pkgversion += 1;
+
+  Verbose("FreeBSDPackageList(): Requested version %s %s of %s\n", CMPSENSETEXT[cmp],(version[0] ? version : "ANY"), pkgname);
+
+  /* If no version was specified, we're just checking if the package
+   * is present, not for a particular number, so >0 will match.
+   */
+  if (!*version)
+    {
+    cmp = cmpsense_gt;
+    version[0] = '0';
+    version[1] = 0;
+    }
 
   /* check what version is installed on the system (if any) */
-   Verbose("FreeBSDPackageCheck(): Running /usr/sbin/pkg_info -qE '%s%s%s'\n", pkgname, compare_operator, version);
-   snprintf (VBUFF, CF_BUFSIZE, "/usr/sbin/pkg_info -qE '%s%s%s'", pkgname, compare_operator, version);
+  Verbose("FreeBSDPackageList(): Running /usr/sbin/pkg_info -E '%s%s%s'\n", pkgname, CMPSENSEOPERAND[cmp], version);
+  snprintf (VBUFF, CF_BUFSIZE, "/usr/sbin/pkg_info -E '%s%s%s'", pkgname, CMPSENSEOPERAND[cmp], version);
 
-   if ((pp = cfpopen (VBUFF, "r")) == NULL)
-      {
-      Verbose ("Could not execute pkg_info.\n");
-      return 0;
-      }
+  if ((pp = cfpopen (VBUFF, "r")) == NULL)
+    {
+    Verbose ("Could not execute pkg_info.\n");
+    return 0;
+    }
 
-   while (!feof (pp))
-      {
-      *VBUFF = '\0';
-      ReadLine (line, CF_BUFSIZE - 1, pp);
-      snprintf(OUTPUT,CF_BUFSIZE,"Package install: %s\n",line);
-      }
+  while (!feof (pp))
+    {
+    *VBUFF = '\0';
+    ReadLine (line, CF_BUFSIZE - 1, pp);
+    Verbose ("PackageList: read line %s\n",line);
+    snprintf(OUTPUT,CF_BUFSIZE,"Package to remove: %s\n",line);
+	strcat( pkglist, line);
+	strcat( pkglist, " ");
+    }
 
-   if (cfpclose (pp) == 0)
-      {
-      Verbose ("The package and version requested are installed in the package database.\n",package);
-      match=1;
-      }
-   else 
-      {
-      Verbose ("The package and version requested do not exist in the package database.\n",package);
-      match=0;
-      }
-   return match;
+  if (cfpclose (pp) == 0)
+    {
+    Verbose ("The packages requested are installed in the package database.\n",package);
+    match=1;
+    }
+  else 
+    {
+    Verbose ("The package and version requested do not exist in the package database.\n",package);
+    match=0;
+    }
+  return match;
 }
 
 /*********************************************************************/
@@ -1426,6 +1601,7 @@
 /* return 1: a is newer than b */
 /*        0: a and b are the same version */
 /*       -1: b is newer than a */
+/*********************************************************************/
 
 int rpmvercmp(const char * a, const char * b)
 


--------------050708070107010909070501
Content-Type: text/plain;
 name="freebsd-package.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="freebsd-package.patch"

*** cf.defs.h_orig	Thu May  3 13:34:39 2007
--- cf.defs.h	Thu May  3 13:34:55 2007
***************
*** 1215,1220 ****
--- 1215,1221 ----
     pkgmgr_sun,
     pkgmgr_aix,
     pkgmgr_portage,
+    pkgmgr_freebsd,
     pkgmgr_none
     };
  
*** prototypes.h_orig	Thu May  3 13:36:14 2007
--- prototypes.h	Thu May  3 13:36:33 2007
***************
*** 880,885 ****
--- 880,886 ----
  int SUNPackageCheck (char *package, char *version, enum cmpsense cmp);
  int PortagePackageCheck (char *package, char *version, enum cmpsense cmp);
  int AIXPackageCheck (char *package, char *version, enum cmpsense cmp);
+ int FreeBSDPackageCheck (char *package, char *version, enum cmpsense cmp);
  int InstallPackage  (char *name, enum pkgmgrs pkgmgr);
  int RemovePackage  (char *name, enum pkgmgrs pkgmgr);
  
*** do.c_orig	Thu May  3 13:36:47 2007
--- do.c	Thu May  3 13:37:06 2007
***************
*** 2735,2740 ****
--- 2735,2743 ----
       case pkgmgr_portage:
         match = PortagePackageCheck(ptr->name, ptr->ver, ptr->cmp);
         break;
+      case pkgmgr_freebsd:
+        match = FreeBSDPackageCheck(ptr->name, ptr->ver, ptr->cmp);
+        break;
       default:
         /* UGH!  This should *never* happen.  GetPkgMgr() and
          * InstallPackagesItem() should have caught this before it
*** globals.c_orig	Thu May  3 13:41:09 2007
--- globals.c	Thu May  3 13:41:30 2007
***************
*** 755,760 ****
--- 755,761 ----
        "sun",    /* pkginfo/pkgadd/pkgrm */
        "aix",    /* lslpp/installp */
        "portage",
+       "freebsd",
        NULL
        };
  
*** package.c_orig	Thu May  3 11:55:17 2007
--- package.c	Thu May  3 16:52:17 2007
***************
*** 351,356 ****
--- 351,366 ----
         strncpy(rawinstcmd, GetMacroValue(CONTEXTID,"PortageInstallCommand"),CF_BUFSIZE);
         break;
         
+        /* FreeBSD */
+    case pkgmgr_freebsd:
+        
+        if (!GetMacroValue(CONTEXTID,"FreeBSDInstallCommand"))
+           {
+           Verbose("FreeBSDInstallCommand NOT Set.  Package Installation Not Possible!\n");
+           return 0;
+           }
+        strncpy(rawinstcmd, GetMacroValue(CONTEXTID,"FreeBSDInstallCommand"),CF_BUFSIZE);
+        break;
         
         /* Default */
     default:
***************
*** 1308,1313 ****
--- 1318,1417 ----
  
  DeleteItemList(ebuildlist);
  return 0;
+ }
+ 
+ /*********************************************************************/
+ /* FreeBSD - pkg_info/pkg_add/pkg_delete                             */
+ /*********************************************************************/
+ 
+ int FreeBSDPackageCheck(char *package,char *version,enum cmpsense cmp)
+ 
+ { FILE *pp;
+   int match = 0;
+   char line[CF_BUFSIZE];
+   char pkgname[CF_BUFSIZE];
+   char *pkgversion;
+ 
+   /* The package to install must contain a version number
+    * The version starts after the last '-' in the pkgname
+    */
+    strncpy(pkgname, package, CF_BUFSIZE - 1);
+    pkgversion = strrchr(pkgname, '-');
+    *pkgversion = '\0';
+    pkgversion += 1;
+ 
+   Verbose("FreeBSDPackageCheck(): Requested version %s %s of %s\n", CMPSENSETEXT[cmp],(version[0] ? version : "ANY"), pkgname);
+ 
+   /* If no version was specified, we're just checking if the package
+    * is present, not for a particular number, so >0 will match.
+    */
+   if (!*version)
+     {
+     cmp = cmpsense_gt;
+     version[0] = '0';
+     version[1] = 0;
+     }
+ 
+   /* Convert to > or < ... */
+   char compare_operator[3];
+    switch(cmp)
+       {
+       case cmpsense_gt:
+       	compare_operator[0] = '>';
+       	compare_operator[1] = 0;
+         break;
+       case cmpsense_lt:
+       	compare_operator[0] = '<';
+       	compare_operator[1] = 0;
+         break;
+       case cmpsense_ge:
+       	compare_operator[0] = '>';
+       	compare_operator[1] = '=';
+       	compare_operator[2] = 0;
+         break;
+       case cmpsense_le:
+       	compare_operator[0] = '<';
+       	compare_operator[1] = '=';
+       	compare_operator[2] = 0;
+         break;
+       case cmpsense_ne:
+       	compare_operator[0] = '!';
+       	compare_operator[1] = '=';
+       	compare_operator[2] = 0;
+       default:
+       	compare_operator[0] = '=';
+       	compare_operator[1] = 0;
+         break;
+ 	  } 
+ 
+   /* check what version is installed on the system (if any) */
+   Verbose("FreeBSDPackageCheck(): Running /usr/sbin/pkg_info -qE '%s%s%s'\n", pkgname, compare_operator, version);
+   snprintf (VBUFF, CF_BUFSIZE, "/usr/sbin/pkg_info -qE '%s%s%s'", pkgname, compare_operator, version);
+ 
+   if ((pp = cfpopen (VBUFF, "r")) == NULL)
+     {
+     Verbose ("Could not execute pkg_info.\n");
+     return 0;
+     }
+ 
+   while (!feof (pp))
+     {
+     *VBUFF = '\0';
+     ReadLine (line, CF_BUFSIZE - 1, pp);
+     snprintf(OUTPUT,CF_BUFSIZE,"Package install: %s\n",line);
+     }
+ 
+   if (cfpclose (pp) == 0)
+     {
+     Verbose ("The package and version requested are installed in the package database.\n",package);
+     match=1;
+     }
+   else 
+     {
+     Verbose ("The package and version requested do not exist in the package database.\n",package);
+     match=0;
+     }
+   return match;
  }
  
  /*********************************************************************/

--------------050708070107010909070501--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?46418749.9020902>