glsa-check updates
authorgenone <genone@gentoo.org>
Wed, 31 Mar 2004 06:22:35 +0000 (06:22 -0000)
committergenone <genone@gentoo.org>
Wed, 31 Mar 2004 06:22:35 +0000 (06:22 -0000)
svn path=/; revision=98

trunk/ChangeLog
trunk/Makefile
trunk/src/glsa-check/glsa-check
trunk/src/glsa-check/glsa.py

index 48286aa6aa7e9c17d9d455570d5f9317aa7dd4bb..fd3e72a37a25d177dab10c4c043f116530753263 100644 (file)
@@ -1,3 +1,6 @@
+2004-03-31 Marius Mauch <genone@gentoo.org>
+       * glsa-check updates, fixing #45528 and #45522, adding support for
+               rXX operators and passing filenames as arguments to Glsa()
 2004-03-13 Marius Mauch <genone@gentoo.org>
        * Added glsa-check and glsa.py, please note:
                - they are only temporary for testing, so no manpage/ChangeLog
index 27bc559ad87bf0a7d0d7def05b93cae9ac6b43d6..d4c804ac768d58ddf6770e9535ab290fd75fb28f 100644 (file)
@@ -36,7 +36,7 @@ dist-gentoolkit-dev:
 dist-gentoolkit:
        mkdir -p release/gentoolkit-$(VERSION)$(RELEASE_TAG)
        rm -rf release/gentoolkit-$(VERSION)$(RELEASE_TAG)/
-       for x in equery etcat euse qpkg gentoolkit revdep-rebuild old-scripts ; do \
+       for x in equery etcat euse qpkg gentoolkit revdep-rebuild old-scripts glsa-check; do \
                ( cd src/$$x ; make distdir=release/gentoolkit-$(VERSION)$(RELEASE_TAG) dist ) \
        done
        cp {Makefile,AUTHORS,README,TODO,COPYING,NEWS,ChangeLog} release/gentoolkit-$(VERSION)$(RELEASE_TAG)/
@@ -59,7 +59,7 @@ install-gentoolkit:
 
        install -m 0644 {AUTHORS,ChangeLog,COPYING,NEWS,README,TODO} $(docdir)/
 
-       for x in equery etcat euse qpkg gentoolkit revdep-rebuild old-scripts ; do \
+       for x in equery etcat euse qpkg gentoolkit revdep-rebuild old-scripts glsa-check ; do \
                ( cd src/$$x ; make DESTDIR=$(DESTDIR) install )  \
        done
 
index d59ec081aeb8b442efc194b7e6e1ef7bf0be1f99..25d27b95fb11b2d33777e200ec5c8d8aa670d7e0 100644 (file)
@@ -4,6 +4,7 @@
 # This program is licensed under the GPL, version 2
 
 import os,string,sys
+sys.path.insert(0, "/usr/lib/gentoolkit/pym")
 from getopt import getopt,GetoptError
 
 __program__ = "glsa-check"
@@ -75,8 +76,9 @@ if mode == "help":
                for o in m[2:-1]:
                        print "\t" + o
        print
-       print "glsa-list can contain an arbitrary number of GLSA ids "
-       print "or the special identifiers 'all' and 'new'"
+       print "glsa-list can contain an arbitrary number of GLSA ids, "
+       print "filenames containing GLSAs or the special identifiers "
+       print "'all' and 'new'"
        print
        sys.exit(1)
 
@@ -97,7 +99,6 @@ if mode == "version":
        sys.exit(0)
 
 # delay this for speed increase
-sys.path.insert(0, "/usr/lib/gentoolkit/pym")
 from glsa import *
 
 glsaconfig = checkconfig(portage.config(clone=portage.settings))
@@ -149,7 +150,11 @@ if mode == "list":
 # dump, fix, inject and fix are nearly the same code, only the glsa method call differs
 if mode in ["dump", "fix", "inject", "pretend"]:
        for myid in glsalist:
-               myglsa = Glsa(myid, glsaconfig)
+               try:
+                       myglsa = Glsa(myid, glsaconfig)
+               except GlsaTypeException, e:
+                       #print "invalid GLSA: %s (error message was: %s)" % (myid, e)
+                       continue
                if mode == "dump":
                        myglsa.dump()
                elif mode == "fix":
@@ -165,13 +170,17 @@ if mode in ["dump", "fix", "inject", "pretend"]:
                                        sys.exit(exitcode)
                        myglsa.inject()
                elif mode == "pretend":
+                       print "Checking GLSA "+myid
                        mergelist = myglsa.getMergeList()
-                       print "The following updates will be performed for this GLSA:"
-                       for pkg in mergelist:
-                               # we simplify a bit here
-                               oldver = portage.db["/"]["vartree"].dbapi.match(portage.dep_getkey(pkg))[-1]
-                               oldver = oldver[len(portage.dep_getkey(oldver))+1:]
-                               print "    ", pkg, "("+oldver+")"
+                       if mergelist:
+                               print "The following updates will be performed for this GLSA:"
+                               for pkg in mergelist:
+                                       # we simplify a bit here
+                                       oldver = portage.db["/"]["vartree"].dbapi.match(portage.dep_getkey(pkg))[-1]
+                                       oldver = oldver[len(portage.dep_getkey(oldver))+1:]
+                                       print "    ", pkg, "("+oldver+")"
+                       else:
+                               print "Nothing to do for this GLSA"
                elif mode == "inject":
                        print "injecting " + myid
                        myglsa.inject()
@@ -179,6 +188,8 @@ if mode in ["dump", "fix", "inject", "pretend"]:
                        print 
                        print 70*'*'
                        print
+               else:
+                       print
        sys.exit(0)
 
 # test is a bit different as Glsa.test() produces no output
index 4848a89d0e9bfeeb30db94842f587134d3f0a013..614ceff9074ebc978d176ec6a423a002dcbb1701 100644 (file)
 
 __author__ = "Marius Mauch <genone@gentoo.org>"
 
-import os, sys, urllib, time, string, portage, codecs, re
+import os, sys, urllib, time, string, codecs, re
 import xml.dom.minidom
 
 sys.path.insert(0, "/usr/lib/portage/pym")     # to find portage.py
 
-opMapping = {"le": "<=", "lt": "<", "eq": "=", "gt": ">", "ge": ">="}
+import portage
+
+# Note: the space for rgt and rlt is important !!
+opMapping = {"le": "<=", "lt": "<", "eq": "=", "gt": ">", "ge": ">=", 
+                        "rge": ">=~", "rle": "<=~", "rgt": " >~", "rlt": " <~"}
 NEWLINE_ESCAPE = "!;\\n"       # some random string to mark newlines that should be preserved
 
 def center(text, width):
@@ -263,6 +267,30 @@ def makeVersion(versionNode):
        return opMapping[versionNode.getAttribute("range")] \
                        +getText(versionNode, format="strip")
 
+def revisionMatch(revisionAtom, portdb):
+       """
+       handler for the special >~, >=~, <=~ and <~ atoms that are supposed to behave
+       as > and < except that they are limited to the same version, the range only
+       applies to the revision part.
+       
+       @type   revisionAtom: string
+       @param  revisionAtom: a <~ or >~ atom that contains the atom to match against
+       @type   portdb: portage.dbapi
+       @param  portdb: one of the portage databases to use as information source
+       
+       @rtype:         list of strings
+       @return:        a list with the matching versions
+       """
+       mylist = portdb.match(revisionAtom[2:])
+       rValue = []
+       for v in mylist:
+               r1 = "\""+portage.pkgsplit(v)[-1]+"\""
+               r2 = "\""+portage.pkgsplit(revisionAtom[3:])[-1]+"\""
+               if eval(r1+" "+revisionAtom[0:1]+" "+r2):
+                       rValue.append(v)
+       return rValue
+               
+
 def getMinUpgrade(vulnerableList, unaffectedList):
        """
        Checks if the systemstate is matching an atom in
@@ -283,11 +311,18 @@ def getMinUpgrade(vulnerableList, unaffectedList):
        """
        rValue = None
        for v in vulnerableList:
-               installed = portage.db["/"]["vartree"].dbapi.match(v)
+               if v[2] == "~":
+                       installed = revisionMatch(v, portage.db["/"]["vartree"].dbapi)
+               else:
+                       installed = portage.db["/"]["vartree"].dbapi.match(v)
                if not installed:
                        continue
                for u in unaffectedList:
-                       for c in portage.db["/"]["porttree"].dbapi.match(u):
+                       if u[2] == "~":
+                               mylist = revisionMatch(u, portage.db["/"]["porttree"].dbapi)
+                       else:
+                               mylist = portage.db["/"]["porttree"].dbapi.match(u)
+                       for c in mylist:
                                c_pv = portage.catpkgsplit(c)
                                i_pv = portage.catpkgsplit(portage.best(installed))
                                if portage.pkgcmp(c_pv[1:], i_pv[1:]) > 0 and (rValue == None or portage.pkgcmp(c_pv[1:], rValue) < 0):
@@ -301,9 +336,12 @@ class GlsaTypeException(Exception):
        def __init__(self, doctype):
                Exception.__init__(self, "wrong DOCTYPE: %s" % doctype)
 
-class GlsaFormatExceptio(Exception):
+class GlsaFormatException(Exception):
        pass
                                
+class GlsaArgumentException(Exception):
+       pass
+
 # GLSA xml data wrapper class
 class Glsa:
        """
@@ -317,10 +355,17 @@ class Glsa:
                
                @type   myid: String
                @param  myid: String describing the id for the GLSA object (standard
-                                         GLSAs have an ID of the form YYYYMM-nn)
+                                         GLSAs have an ID of the form YYYYMM-nn) or an existing
+                                         filename containing a GLSA.
                @type   myconfig: portage.config
                @param  myconfig: the config that should be used for this object.
                """
+               if re.match(r'\d{6}-\d{2}', myid):
+                       self.type = "id"
+               elif os.path.exists(myid):
+                       self.type = "file"
+               else:
+                       raise GlsaArgumentException("Given ID "+myid+" isn't a valid GLSA ID or filename.")
                self.nr = myid
                self.config = myconfig
                self.read()
@@ -337,7 +382,10 @@ class Glsa:
                        repository = "file://" + self.config["GLSA_DIR"]
                else:
                        repository = self.config["GLSA_SERVER"]
-               myurl = repository + self.config["GLSA_PREFIX"] + str(self.nr) + self.config["GLSA_SUFFIX"]
+               if self.type == "file":
+                       myurl = "file://"+self.nr
+               else:
+                       myurl = repository + self.config["GLSA_PREFIX"] + str(self.nr) + self.config["GLSA_SUFFIX"]
                self.parse(urllib.urlopen(myurl))
                return None
 
@@ -358,7 +406,7 @@ class Glsa:
                elif self.DOM.doctype.systemId != "http://www.gentoo.org/dtd/glsa.dtd":
                        raise GlsaTypeException(self.DOM.doctype.systemId)
                myroot = self.DOM.getElementsByTagName("glsa")[0]
-               if myroot.getAttribute("id") != self.nr:
+               if self.type == "id" and myroot.getAttribute("id") != self.nr:
                        raise GlsaFormatException("filename and internal id don't match:" + myroot.getAttribute("id") + " != " + self.nr)
 
                # the simple (single, required, top-level, #PCDATA) tags first