Eric, I see nothing about these changes to do.c that couldn't be  
accomplished inside the portage-specific functions.  If I'm  
overlooking something, could you please clarify the issue for me?

If it does require something specific, I think we might be better off  
making an intermediary function that calls a pkgmgr-specific routine  
to alter the package info prior to adding to a list.  For instance,  
this would be useful for freebsd -- just not so useful that I wanted  
to add that abstraction just for freebsd.  But if we find that most  
pkgmgrs need it, then...

On Jul 20, 2007, at 5:14 PM, [EMAIL PROTECTED] wrote:
> This patch updates Portage package manager support to the new code  
> introduced in 2.2.1.  Portage support was broken by that patch,  
> this restores it, while making several improvements (like moving  
> from equery to qlist for drastic speed improvements).
>
> Note: a lot of Portage-specific code was introduced to do.c; this  
> code is essential here because the package code has to modify the  
> package name given to it.  This could be handled in package.c if  
> the complete Package* object was passed to PackageCheck().  I'll  
> work on a patch for this later.
>
> Index: cfengine-trunk/src/do.c
> ===================================================================
> --- cfengine-trunk.orig/src/do.c
> +++ cfengine-trunk/src/do.c
> @@ -2738,6 +2738,7 @@ void CheckPackages()
>    /* pkgmgr_none will always be the highest number in the enum so set
>       the array size with that */
>    struct Item *pending_pkgs = NULL;
> +  char *wholepackage = NULL;
>    enum pkgmgrs prev_pkgmgr = pkgmgr_none;
>    enum pkgactions prev_action = pkgaction_none;
>
> @@ -2778,8 +2779,31 @@ for (ptr = VPKG; ptr != NULL; ptr=ptr->n
>        AddMultipleClasses(ptr->defines);
>        if (ptr->action == pkgaction_remove)
>           {
> -         PackageList(ptr->name, ptr->pkgmgr, ptr->ver, ptr->cmp,  
> &pending_pkgs);
> -         AppendItem(&pending_pkgs, ptr->name, NULL);
> +         if (ptr->pkgmgr == pkgmgr_portage && (ptr->ver)[0])
> +            {
> +            /* Portage doesn't use a list, just the package atom */
> +            int wholesize = 2 + strlen(ptr->name) + strlen(ptr- 
> >ver) + strlen(CMPSENSEOPERAND[ptr->cmp]);
> +            wholepackage = (char *) malloc(wholesize);
> +            strncpy(wholepackage, CMPSENSEOPERAND[ptr->cmp],  
> wholesize - 1);
> +            strncat(wholepackage, ptr->name, wholesize - strlen 
> (wholepackage) - 1);
> +            strncat(wholepackage, "-", wholesize - strlen 
> (wholepackage) - 1);
> +            strncat(wholepackage, ptr->ver, wholesize - strlen 
> (wholepackage) - 1);
> +
> +            /* Replace pkg->name with package atom */
> +            free(ptr->name);
> +            ptr->name = wholepackage;
> +            wholepackage = NULL;
> +
> +            AppendItem(&pending_pkgs, ptr->name, NULL);
> +            }
> +         else if (ptr->pkgmgr == pkgmgr_portage)
> +            {
> +            AppendItem(&pending_pkgs, ptr->name, NULL);
> +            }
> +         else
> +            {
> +            PackageList(ptr->name, ptr->pkgmgr, ptr->ver, ptr- 
> >cmp, &pending_pkgs);
> +            }
>
>           /* Some package managers operate best doing things one at  
> a time. */
>           if ( (ptr->pkgmgr == pkgmgr_freebsd) || (ptr->pkgmgr ==  
> pkgmgr_sun) )
> @@ -2798,6 +2822,22 @@ for (ptr = VPKG; ptr != NULL; ptr=ptr->n
>        AddMultipleClasses(ptr->elsedef);
>        if (ptr->action == pkgaction_install)
>           {
> +         if (ptr->pkgmgr == pkgmgr_portage && (ptr->ver)[0])
> +            {
> +            /* Portage wants the version in the package atom */
> +            int wholesize = 2 + strlen(ptr->name) + strlen(ptr- 
> >ver) + strlen(CMPSENSEOPERAND[ptr->cmp]);
> +            wholepackage = (char *) malloc(wholesize);
> +            strncpy(wholepackage, CMPSENSEOPERAND[ptr->cmp],  
> wholesize - 1);
> +            strncat(wholepackage, ptr->name, wholesize - strlen 
> (wholepackage) - 1);
> +            strncat(wholepackage, "-", wholesize - strlen 
> (wholepackage) - 1);
> +            strncat(wholepackage, ptr->ver, wholesize - strlen 
> (wholepackage) - 1);
> +
> +            /* Replace pkg->name with package atom */
> +            free(ptr->name);
> +            ptr->name = wholepackage;
> +            wholepackage = NULL;
> +            }
> +
>           AppendItem(&pending_pkgs, ptr->name, NULL);
>
>           /* Some package managers operate best doing things one at  
> a time. */
> Index: cfengine-trunk/src/package.c
> ===================================================================
> --- cfengine-trunk.orig/src/package.c
> +++ cfengine-trunk/src/package.c
> @@ -246,7 +246,7 @@ switch(pkgmgr)
>        Verbose("InstallPackage(): using '%s'\n", instcmd);
>        if (DONTDO)
>           {
> -         Verbose("--skipping because DONTDO is enabled.");
> +         Verbose("--skipping because DONTDO is enabled.\n");
>           result = 1;
>           }
>        else
> @@ -337,6 +337,18 @@ int RemovePackage(enum pkgmgrs pkgmgr, s
>              }
>           break;
>
> +      /* Portage */
> +      case pkgmgr_portage:
> +         if (!GetMacroValue(CONTEXTID,"PortageRemoveCommand"))
> +            {
> +               strncpy(rawdelcmd, "/usr/bin/emerge -C %s", 21 );
> +            }
> +         else
> +            {
> +            strncpy(rawdelcmd, GetMacroValue 
> (CONTEXTID,"PortageRemoveCommand"),CF_BUFSIZE);
> +            }
> +         break;
> +
>        /* Default */
>        default:
>           Verbose("Package removal not yet implemented for this  
> package manager.");
> @@ -348,7 +360,7 @@ int RemovePackage(enum pkgmgrs pkgmgr, s
>        Verbose("RemovePackage(): using '%s'\n", delcmd);
>        if (DONTDO)
>           {
> -         Verbose("--skipping because DONTDO is enabled.");
> +         Verbose("--skipping because DONTDO is enabled.\n");
>           result = 1;
>           }
>        else
> @@ -448,7 +460,6 @@ int BuildCommandLine(char *resolvedcmd,
>           strncpy(cmd_ptr, cmd_tail, &resolvedcmd[CF_BUFSIZE*2] -  
> cmd_ptr);
>           }
>        }
> -   Verbose("Resolved command is '%s'\n", resolvedcmd );
>     return 1;
>  }
>
> @@ -1326,27 +1337,21 @@ int v,r,m,f;
>
>  int PortagePackageCheck(char *package,char *version,enum cmpsense  
> cmp)
>
> -{ FILE *pp;
> -  struct Item *ebuildlist = NULL;
> -  struct Item *ebuild;
> -  enum cmpsense result;
> -  int match = 0;
> -  char *comparehead = NULL;
> -  char *comparetail = NULL;
> -  char *installedhead = NULL;
> -  char *installedtail = NULL;
> -
> -  /* Yes, it's an ugly python one-liner that does something  
> beautiful */
> -
> -snprintf(VBUFF,CF_BUFSIZE,"/usr/bin/python -c 'import portage, re,  
> sys; "
> -         "[sys.stdout.write(re.sub(\"\\w*?\\-\\w*?\\/([a-zA-Z0-9_ 
> +]|\\-(?![0-9]))*\\-\", \"\", package, 1) + "
> -         "\"\\n\") for package in portage.db[\"/\"][\"vartree 
> \"].dbapi.match("
> -         "\"%s\")]'", package);
> +{  FILE *pp;
> +   struct Item *ebuildlist = NULL;
> +   struct Item *ebuild;
> +   int match = 0;
> +   char *result = NULL;
> +
> +/* Search for installed versions of package */
> +snprintf(VBUFF,CF_BUFSIZE,"/usr/bin/qlist -IevC %s",package);
>
>  if ((pp = cfpopen(VBUFF, "r")) == NULL)
>     {
> -   Verbose("Could not execute the equery command.  Assuming  
> package not installed.\n");
> -   return 0;
> +   snprintf(OUTPUT,CF_BUFSIZE,"Could not execute the qlist  
> command.  "
> +      "Is portage-utils installed?\n");
> +   CfLog(cferror,OUTPUT,"");
> +   return -1;
>     }
>
>  while(!feof(pp))
> @@ -1361,14 +1366,7 @@ while(!feof(pp))
>        }
>     }
>
> -/* Non-zero exit status means that we could not find the package, so
> - * zero the list and bail. */
> -
> -if (cfpclose(pp) != 0)
> -   {
> -   DeleteItemList(ebuildlist);
> -   ebuildlist = NULL;
> -   }
> +cfpclose(pp);
>
>  if (ebuildlist == NULL)
>     {
> @@ -1376,145 +1374,92 @@ if (ebuildlist == NULL)
>     return 0;
>     }
>
> -
>  Verbose("PortageCheckPackage(): Requested %s %s %s\n", package,  
> CMPSENSETEXT[cmp],(version[0] ? version : "ANY"));
>
> -/* If no version was specified, just return 1, because if we got  
> this far
> - * some package by that name exists. */
> -
> +/* If no version was specified, return successful (found  
> something) */
>  if (!version[0])
>     {
>     DeleteItemList(ebuildlist);
>     return 1;
>     }
>
> -/* The rule here will be: if any package in the list matches, then  
> the
> - * first one to match wins, and we bail out. */
> -
> -
> +/* Iterate through all installed versions until match is found */
>  for (ebuild = ebuildlist; ebuild != NULL; ebuild=ebuild->next)
> -  {
> -  char *ebuildver;
> -  ebuildver = ebuild->name;
> -
> -  Verbose("PortageCheckPackage(): Trying installed version %s\n",  
> ebuildver);
> -
> -  /* Start out assuming the comparison will be equal. */
> -  result = cmpsense_eq;
> -
> -  comparehead = version;
> -  comparetail = NULL;
> -  installedhead = ebuildver;
> -  installedtail = NULL;
> -
> -  /* Iterate over version portions delimited by `-' */
> -  while (result == cmpsense_eq)
> -     {
> -     if (*comparehead == '\0' && *installedhead == '\0')
> -        {
> -        /* No substrings remain, break from while */
> -        break;
> -        }
> -     else if (*comparehead == '\0')
> -        {
> -        /* Installed version has more version substrings than  
> given */
> -        result = cmpsense_gt;
> -        }
> -     else if (*installedhead == '\0')
> -        {
> -        /* Installed version has less version substrings than  
> given */
> -        result = cmpsense_lt;
> -        }
> -     else
> -        {
> -        /* New substring in both to test */
> -        comparetail = strchr(comparehead, '-');
> -        installedtail = strchr(installedhead, '-');
> -
> -        /* Throw a \0 over the `-' so just the substring is tested.
> -         * If the tail is less than the head, we must be at last  
> substring,
> -         * as no `-'s were found (so the `\0' is already there) */
> -        if (comparetail > comparehead) *comparetail = '\0';
> -        if (installedtail > installedhead) *installedtail = '\0';
> -
> -        switch (rpmvercmp(installedhead, comparehead))
> -           {
> -           case 1:
> -               result = cmpsense_gt;
> -               break;
> -           case -1:
> -               result = cmpsense_lt;
> -               break;
> -           }
> -
> -        if (comparetail > comparehead)
> -           {
> -           /* Restore `-' at tail and move head just past it */
> -           *comparetail = '-';
> -           comparehead = comparetail + 1;
> -           }
> -        else
> -           {
> -           /* Move head to the end of the line (`\0') */
> -           comparehead = comparehead + strlen(comparehead);
> -           }
> -        if (installedtail > installedhead)
> -           {
> -           /* Restore `-' at tail and move head just past it */
> -           *installedtail = '-';
> -           installedhead = installedtail + 1;
> -           }
> -        else
> -           {
> -           /* Move head to the end of the line (`\0') */
> -           installedhead = installedhead + strlen(installedhead);
> -           }
> -        }
> -     }
> -
> -  Verbose("Comparison result: %s\n",CMPSENSETEXT[result]);
> -
> -  switch(cmp)
> -     {
> -     case cmpsense_gt:
> -         match = (result == cmpsense_gt);
> -         break;
> -     case cmpsense_ge:
> -         match = (result == cmpsense_gt || result == cmpsense_eq);
> -         break;
> -     case cmpsense_lt:
> -         match = (result == cmpsense_lt);
> -         break;
> -     case cmpsense_le:
> -         match = (result == cmpsense_lt || result == cmpsense_eq);
> -         break;
> -     case cmpsense_eq:
> -         match = (result == cmpsense_eq);
> -         break;
> -     case cmpsense_ne:
> -         match = (result != cmpsense_eq);
> -         break;
> -     }
> -
> -  /* If we find a match, just return it now, and don't bother  
> checking
> -   * other ebuilds */
> +   {
>
> -  if (match)
> -     {
> -     DeleteItemList(ebuildlist);
> -     return 1;
> -     }
> -  }
> +   Verbose("PortageCheckPackage(): Trying installed version %s\n",  
> ebuild->name);
> +
> +   /* Run comparison tool to do the grunt work */
> +   snprintf(VBUFF,CF_BUFSIZE,"/usr/bin/qatom -cC %s %s-%s", ebuild- 
> >name, package, version);
> +
> +   if ((pp = cfpopen(VBUFF, "r")) == NULL)
> +      {
> +      snprintf(OUTPUT,CF_BUFSIZE,"Could not execute the qatom  
> command.  "
> +         "Is portage-utils installed?\n");
> +      CfLog(cferror,OUTPUT,"");
> +      continue;
> +      }
> +
> +   if (feof(pp))
> +      {
> +      snprintf(OUTPUT,CF_BUFSIZE,"Internal error!  No output from % 
> s.",VBUFF);
> +      CfLog(cferror,OUTPUT,"");
> +      continue;
> +      }
> +
> +   /* Format of output is `package < package' */
> +   *VBUFF = '\0';
> +   ReadLine(VBUFF,CF_BUFSIZE,pp);
> +   Verbose("PortagePackageCheck(): Result %s\n",VBUFF);
> +   cfpclose(pp);
> +
> +   /* Find first space, give up otherwise */
> +   result = strchr(VBUFF, ' ');
> +   if (result == NULL) continue;
> +
> +   /* Relocate to right of space (the comparison symbol) */
> +   ++result;
> +
> +   switch(cmp)
> +   {
> +   case cmpsense_gt:
> +      match = (*result == *CMPSENSEOPERAND[cmpsense_gt]);
> +      break;
> +   case cmpsense_ge:
> +      match = (*result == *CMPSENSEOPERAND[cmpsense_gt] ||
> +               *result == *CMPSENSEOPERAND[cmpsense_eq]);
> +      break;
> +   case cmpsense_lt:
> +      match = (*result == *CMPSENSEOPERAND[cmpsense_lt]);
> +      break;
> +   case cmpsense_le:
> +      match = (*result == *CMPSENSEOPERAND[cmpsense_lt] ||
> +               *result == *CMPSENSEOPERAND[cmpsense_eq]);
> +      break;
> +   case cmpsense_eq:
> +      match = (*result == *CMPSENSEOPERAND[cmpsense_eq]);
> +      break;
> +   case cmpsense_ne:
> +      match = (*result != *CMPSENSEOPERAND[cmpsense_eq]);
> +      break;
> +   }
>
> -/* if we manage to make it out of the loop, we did not find a  
> match. */
> +   /* Return successful on finding a match */
> +   if (match)
> +      {
> +      DeleteItemList(ebuildlist);
> +      return 1;
> +      }
> +   }
>
> +/* No match found, return false */
>  DeleteItemList(ebuildlist);
>  return 0;
>  }
>
>  int PortagePackageList(char *package, char *version, enum cmpsense  
> cmp, struct Item **pkglist)
>  {
> -     return 0; /* not implemented yet */
> +return 0; /* unused! */
>  }
>
>  / 
> *********************************************************************/
>
> --
> Eric Searcy
> OSU Open Source Lab
>
> _______________________________________________
> Bug-cfengine mailing list
> [email protected]
> https://cfengine.org/mailman/listinfo/bug-cfengine

-- 
Jo Rhett
senior geek

Silicon Valley Colocation
Support Phone: 408-400-0550




_______________________________________________
Bug-cfengine mailing list
[email protected]
https://cfengine.org/mailman/listinfo/bug-cfengine

Reply via email to