def getMinUpgrade(vulnerableList, unaffectedList, minimize=True): """ Checks if the systemstate is matching an atom in I{vulnerableList} and returns string describing the lowest version for the package that matches an atom in I{unaffectedList} and is greater than the currently installed version. It will return an empty list if the system is affected, and no upgrade is possible or None if the system is not affected. Both I{vulnerableList} and I{unaffectedList} should have the same base package. @type vulnerableList: List of Strings @param vulnerableList: atoms matching vulnerable package versions @type unaffectedList: List of Strings @param unaffectedList: atoms matching unaffected package versions @type minimize: Boolean @param minimize: True for a least-change upgrade, False for emerge-like algorithm @rtype: String | None @return: the lowest unaffected version that is greater than the installed version. """ rValue = "" v_installed = reduce(operator.add, [match(v, "vartree") for v in vulnerableList], []) u_installed = reduce(operator.add, [match(u, "vartree") for u in unaffectedList], []) # remove all unaffected atoms from vulnerable list v_installed = list(set(v_installed).difference(set(u_installed))) if not v_installed: return None # this tuple holds all vulnerable atoms, and the related upgrade atom vuln_update = [] avail_updates = set() for u in unaffectedList: # TODO: This had match_type="match-all" before. I don't think it should # since we disregarded masked items later anyway (match(=rValue, "porttree")) avail_updates.update(match(u, "porttree")) # if an atom is already installed, we should not consider it for upgrades avail_updates.difference_update(u_installed) for vuln in v_installed: update = "" for c in avail_updates: c_pv = portage.catpkgsplit(c) i_pv = portage.catpkgsplit(vuln) if portage.pkgcmp(c_pv[1:], i_pv[1:]) > 0 \ and (update == "" \ or (minimize ^ (portage.pkgcmp(c_pv[1:], portage.catpkgsplit(update)[1:]) > 0))) \ and portage.db[portage.root]["porttree"].dbapi.aux_get(c, ["SLOT"]) == portage.db[portage.root]["vartree"].dbapi.aux_get(vuln, ["SLOT"]): update = c_pv[0] + "/" + c_pv[1] + "-" + c_pv[2] if c_pv[3] != "r0": # we don't like -r0 for display update += "-" + c_pv[3] vuln_update.append([vuln, update]) return vuln_update
def getMinUpgrade(vulnerableList, unaffectedList, minimize=True): """ Checks if the systemstate is matching an atom in I{vulnerableList} and returns string describing the lowest version for the package that matches an atom in I{unaffectedList} and is greater than the currently installed version. It will return an empty list if the system is affected, and no upgrade is possible or None if the system is not affected. Both I{vulnerableList} and I{unaffectedList} should have the same base package. @type vulnerableList: List of Strings @param vulnerableList: atoms matching vulnerable package versions @type unaffectedList: List of Strings @param unaffectedList: atoms matching unaffected package versions @type minimize: Boolean @param minimize: True for a least-change upgrade, False for emerge-like algorithm @rtype: String | None @return: the lowest unaffected version that is greater than the installed version. """ rValue = "" v_installed = reduce(operator.add, [match(v, "vartree") for v in vulnerableList], []) u_installed = reduce(operator.add, [match(u, "vartree") for u in unaffectedList], []) # remove all unaffected atoms from vulnerable list v_installed = list(set(v_installed).difference(set(u_installed))) if not v_installed: return None # this tuple holds all vulnerable atoms, and the related upgrade atom vuln_update = [] avail_updates = set() for u in unaffectedList: # TODO: This had match_type="match-all" before. I don't think it should # since we disregarded masked items later anyway (match(=rValue, "porttree")) avail_updates.update(match(u, "porttree")) # if an atom is already installed, we should not consider it for upgrades avail_updates.difference_update(u_installed) for vuln in v_installed: update = "" for c in avail_updates: c_pv = portage.catpkgsplit(c) i_pv = portage.catpkgsplit(vuln) if portage.pkgcmp(c_pv[1:], i_pv[1:]) > 0 \ and (update == "" \ or (minimize ^ (portage.pkgcmp(c_pv[1:], portage.catpkgsplit(update)[1:]) > 0))) \ and portage.db[portage.root]["porttree"].dbapi.aux_get(c, ["SLOT"]) == portage.db[portage.root]["vartree"].dbapi.aux_get(vuln, ["SLOT"]): update = c_pv[0]+"/"+c_pv[1]+"-"+c_pv[2] if c_pv[3] != "r0": # we don't like -r0 for display update += "-"+c_pv[3] vuln_update.append([vuln, update]) return vuln_update
def get_max_version(self, category, name): """ Get the recent available version of a package. Args: category: Category name. name: package name. Returns: The recent version of a package. """ if not category or (not category in self.categories): raise InvalidKeyError('No such category: ' + category) if not category in self.database \ or not name in self.database[category]['packages']: raise InvalidKeyError('No such package: ' + category + '/' + name) pkgname = category + '/' + name versions = list(self.database[category]['packages'][name]) max_ver = versions[0] for version in versions[1:]: if portage.pkgcmp(portage.pkgsplit(pkgname + '-' + version), portage.pkgsplit(pkgname + '-' + max_ver)) > 0: max_ver = version return max_ver
def compare_versions(self, v1, v2): v1 = self.split_cpv(v1) v2 = self.split_cpv(v2) # if category is different if v1[0] != v2[0]: return cmp(v1[0], v2[0]) # if name is different elif v1[1] != v2[1]: return cmp(v1[1], v2[1]) # Compare versions else: return portage.pkgcmp(v1[1:], v2[1:])
def compare_versions(self, v1, v2): v1 = self.split_cpv(v1) v2 = self.split_cpv(v2) # if category is different if v1[0] != v2[0]: return cmp(v1[0],v2[0]) # if name is different elif v1[1] != v2[1]: return cmp(v1[1],v2[1]) # Compare versions else: return portage.pkgcmp(v1[1:],v2[1:])
def crossref_gentoo(fm): """Insert each gentoo package in db, add freshmeat id""" #rss items: items = [] #Get all gentoo pkgs, installed, uninstalled and overlay. pkgs = get_gentoo_pkgs() #print len(pkgs) for cpn in pkgs: #pkg element is in cat/packagname format cpn = cpn.strip() cat, pn = cpn.split("/") pn = pn.lower() if fm.has_key(pn): vers = get_versions(pn) if vers: highest = get_highest(pn, vers) pv = split_package_name(get_highest(pn, vers))[2] fm_ver = fm[pn]['latestReleaseVersion'] try: res = portage.pkgcmp([pn, pv, "r0"], [pn, fm_ver, "r0"]) # -1 if fm is higher except: #This means its a fm version that won't compare with Gentoo's #version. We accept it as being higher. e.g. pkgfoo_BeTa.12 #FIXME: Lets add an sql field for these and only show ignore #icon for these. Make a filter on the website to just show them. res = -1 desc = portage.portdb.aux_get(highest, ["DESCRIPTION"])[0] maints = get_maints(cpn) if res == -1: #freshmeat version is higher than portage's #or freshmeat's version is so screwy we assume its higher update_sql(desc, fm[pn], cat, pn, pv, maints, 1) else: #freshmeat version is equal or lower that portage's update_sql(desc, fm[pn], cat, pn, pv, maints, 0) del fm[pn]
def __ge__(self, other): if other.cp != self.cp: return False if portage.pkgcmp(self.pv_split, other.pv_split) >= 0: return True return False
def mypkgcmp(pkg1, pkg2): return pkgcmp(pkg1[:3], pkg2[:3])
i = 1 while i < len(sys.argv): atom1, atom2 = sys.argv[i:i + 2] if atom2[0] in ('>', '<', '=', '~'): if '/' not in atom1: # Portage really wants a category. a1 = 'c/' + atom1 pfx = atom2[0] if atom2[1] == '=': pfx += atom2[1] a2 = '%sc/%s' % (pfx, atom2[len(pfx):]) else: a1, a2 = atom1, atom2 ret = portage.dep.match_from_list(a2, [a1]) rel = '==' if ret else '!=' else: try: pkg1 = portage.pkgsplit(atom1) pkg2 = portage.pkgsplit(atom2) ret = portage.pkgcmp(pkg1, pkg2) if ret == 1: rel = '>' elif ret == -1: rel = '<' else: rel = '==' except Exception as e: rel = '!=' print('%s %s %s' % (atom1, rel, atom2)) i += 2
def populate_from_repository( g, overlay_path, porttree, vertices={}, only_overlay=True, overlay_color=GENTOO_PURPLE_LIGHT2, overlay_text_color=GENTOO_PURPLE, overlay_edge_color=GENTOO_PURPLE_LIGHT2, overlay_edge_order=2, extraneous_color=GENTOO_PURPLE_GREY, extraneous_text_color=GENTOO_PURPLE, extraneous_edge_color=GENTOO_PURPLE_GREY, extraneous_edge_order=1, ): all_cp = porttree.dbapi.cp_all(trees=[overlay_path]) for cp in all_cp: newest_cpv = cp + "-0_beta" #nothing should be earlier than this for cpv in porttree.dbapi.cp_list(cp, mytree=overlay_path): if portage.pkgcmp(portage.pkgsplit(cpv), portage.pkgsplit(newest_cpv)) >= 0: newest_cpv = cpv if newest_cpv != cp + "-0_beta": deps = porttree.dbapi.aux_get(newest_cpv, ["DEPEND", "RDEPEND", "PDEPEND"]) deps = ' '.join(deps).split() # consolidate deps deps = list(set(deps)) # de-duplicate #correct dependency list formatting for ix in range(len(deps)): #remove non-package entries from deps list if not "/" in deps[ix]: deps[ix] = None else: #remove all syntax that does not match cpv for delimiter in ["[", ":"]: if delimiter in deps[ix]: deps[ix] = deps[ix].split(delimiter)[0] if deps[ix][:2] in [">=", "<=", "!<", "!>"]: deps[ix] = deps[ix][2:] if deps[ix][:1] in [">", "<", "~", "=", "!"]: deps[ix] = deps[ix][1:] if deps[ix][-1:] in ["*"]: deps[ix] = deps[ix][:-1] deps = list(filter(None, deps)) for ix, a in enumerate(deps): if portage.pkgsplit(a) != None: deps[ix] = portage.pkgsplit(a)[0] #Populate graph try: cp_index = vertices[cp] except KeyError: v1 = g.add_vertex() g.vp.vlabel[v1] = cp g.vp.vcolor[v1] = overlay_color g.vp.vtext_color[v1] = overlay_text_color vertices[cp] = g.vertex_index[v1] else: v1 = g.vertex(cp_index) for dep in deps: if only_overlay: if dep in all_cp or dep in vertices: vertices, _ = add_vertex_and_edge( g, dep, vertices, v1, vcolor=overlay_color, vtext_color=overlay_text_color, ecolor=overlay_edge_color, eorder=overlay_edge_order, ) else: break sets_property_values = [] sets_property_values.append([ all_cp, [ overlay_color, overlay_text_color, overlay_edge_color, overlay_edge_order ] ]) sets_property_values.append([ all_cp + deps, [ extraneous_color, extraneous_text_color, extraneous_edge_color, extraneous_edge_order ] ]) vcolor, vtext_color, ecolor, eorder = vertex_and_edge_appearance( dep, sets_property_values, g, v1) vertices, _ = add_vertex_and_edge(g, dep, vertices, v1, vcolor=vcolor, vtext_color=vtext_color, ecolor=ecolor, eorder=eorder) return g, vertices
def get_cp_deps(cp, overlay_path, porttree, matchnone=True, matchall=True): """Get cp formatted deps for given cp. Parameters ---------- cp : str Category and package formatted according to the Portage cp syntax (category/package) overlay_path : str Path to the overlay in which to check for package versions porttree : porttree object Porttree object obtained via e.g. `porttree = portage.db[portage.root]['porttree']` matchnone : boolean , optional Whether to only match mandatory dependencies. matcall : boolean , optional Whether to match all mandatory dependencies. """ newest_cpv = cp + "-0_alpha_pre" #nothing should be earlier than this ceil_cpv = cp + "-9999" #ideally we would not want live packages for cpv in porttree.dbapi.cp_list(cp, mytree=overlay_path): if portage.pkgcmp(portage.pkgsplit(cpv), portage.pkgsplit(newest_cpv)) >= 0: if portage.pkgcmp(portage.pkgsplit(ceil_cpv), portage.pkgsplit(cpv)) > 0: newest_cpv = cpv elif newest_cpv == cp + "-0_alpha_pre": newest_cpv = cpv if newest_cpv != cp + "-0_alpha_pre": deps = porttree.dbapi.aux_get(newest_cpv, ["DEPEND", "RDEPEND", "PDEPEND"]) deps = portage.dep.use_reduce(depstr=deps, matchnone=matchnone, matchall=matchall, flat=True) deps = ' '.join(deps) # only keep first package from exactly-one-of lists deps = re.sub(r"\|\| \( (.+?) .+? \)", r"\1", deps) deps = deps.split(" ") deps = list(set(deps)) # de-duplicate else: print("WARNING: skipping " + newest_cpv) return False #correct dependency list formatting for ix in range(len(deps)): #remove non-package entries from deps list if not "/" in deps[ix]: deps[ix] = None else: #remove all syntax that does not match cpv for delimiter in ["[", ":"]: if delimiter in deps[ix]: deps[ix] = deps[ix].split(delimiter)[0] if deps[ix][:2] in [">=", "<="]: deps[ix] = deps[ix][2:] if deps[ix][:1] in [">", "<", "~", "="]: deps[ix] = deps[ix][1:] if deps[ix][-1:] in ["*"]: deps[ix] = deps[ix][:-1] if deps[ix][:2] in ["!!", "!~", "!<", "!>", "!="]: deps[ix] = None elif deps[ix][:1] == "!": deps[ix] = None deps = list(filter(None, deps)) for ix in range(len(deps)): if portage.pkgsplit(deps[ix]) != None: deps[ix] = portage.pkgsplit(deps[ix])[0] return deps
def get_all_packages(overlay_paths): """Returns all packages from a given overlay path. Originally ftom https://gist.github.com/noisebleed/3194783 """ packages = {} porttree = portage.db[portage.root]['porttree'] for overlay_path in overlay_paths: if overlay_path not in porttree.dbapi.porttrees: print( 'Overlay "{}" is not known to Portage.\n'.format( overlay_path) + 'Please set it. Learn how at https://wiki.gentoo.org/wiki/Overlay' ) return False for cp in porttree.dbapi.cp_all(trees=overlay_paths): newest_cpv = cp + "-0_beta" #nothing should be earlier than this for cpv in porttree.dbapi.cp_list(cp, mytree=overlay_paths): if portage.pkgcmp(portage.pkgsplit(cpv), portage.pkgsplit(newest_cpv)) >= 0: newest_cpv = cpv if newest_cpv != cp + "-0_beta": deps = porttree.dbapi.aux_get(newest_cpv, ["DEPEND", "RDEPEND", "PDEPEND"]) deps = ' '.join(deps).split() # consolidate deps deps = list(set(deps)) # de-duplicate #correct dependency list formatting for ix in range(len(deps)): #remove non-package entries from deps list if not "/" in deps[ix]: deps[ix] = None else: #remove all syntax that does not match cpv for delimiter in ["[", ":"]: if delimiter in deps[ix]: deps[ix] = deps[ix].split(delimiter)[0] if deps[ix][:2] in [">=", "<=", "!<", "!>"]: deps[ix] = deps[ix][2:] if deps[ix][:1] in [">", "<", "~", "=", "!"]: deps[ix] = deps[ix][1:] if deps[ix][-1:] in ["*"]: deps[ix] = deps[ix][:-1] deps = list(filter(None, deps)) for ix, a in enumerate(deps): if portage.pkgsplit(a) != None: deps[ix] = portage.pkgsplit(a)[0] packages[cp] = deps G = nx.Graph(packages) options = { 'with_labels': False, 'node_color': 'red', 'node_size': 5, 'linewidths': 0, 'width': 0.5, } plt.figure(figsize=(14, 14), tight_layout=True) plt.axis('equal') # print(packages["sci-mathematics/yoricks"]) # nx.draw_shell(G, nlist=[range(0,10), range(10,1000)], **options) # nx.draw(G, shell_layout(G, nlist=[range(0,10), range(10,2000)]), **options) # nx.draw_spring(G, iterations=500000, **options) # pos=pygraphviz_layout(G,prog='neato',args='') # pos=nx.spring_layout(G,dim=3,iterations=10000) pos = nx.spring_layout(G, k=0.05, iterations=1000) nx.draw(G, pos, **options) plt.show() return G
def populate_from_repository(g, overlay_path, porttree, vertices={}, only_overlay=True, overlay_color=GENTOO_PURPLE_LIGHT2, overlay_text_color=GENTOO_PURPLE, overlay_edge_color=GENTOO_PURPLE_LIGHT2, overlay_edge_order=2, extraneous_color=GENTOO_PURPLE_GREY, extraneous_text_color=GENTOO_PURPLE, extraneous_edge_color=GENTOO_PURPLE_GREY, extraneous_edge_order=1, ): all_cp = porttree.dbapi.cp_all(trees=[overlay_path]) for cp in all_cp: newest_cpv = cp+"-0_beta" #nothing should be earlier than this for cpv in porttree.dbapi.cp_list(cp, mytree=overlay_path): if portage.pkgcmp(portage.pkgsplit(cpv), portage.pkgsplit(newest_cpv)) >= 0: newest_cpv = cpv if newest_cpv != cp+"-0_beta": deps = porttree.dbapi.aux_get(newest_cpv, ["DEPEND","RDEPEND","PDEPEND"]) deps = ' '.join(deps).split() # consolidate deps deps = list(set(deps)) # de-duplicate #correct dependency list formatting for ix in range(len(deps)): #remove non-package entries from deps list if not "/" in deps[ix]: deps[ix] = None else: #remove all syntax that does not match cpv for delimiter in ["[",":"]: if delimiter in deps[ix]: deps[ix] = deps[ix].split(delimiter)[0] if deps[ix][:2] in [">=", "<=", "!<", "!>"]: deps[ix] = deps[ix][2:] if deps[ix][:1] in [">", "<", "~", "=", "!"]: deps[ix] = deps[ix][1:] if deps[ix][-1:] in ["*"]: deps[ix] = deps[ix][:-1] deps = list(filter(None, deps)) for ix, a in enumerate(deps): if portage.pkgsplit(a) != None: deps[ix] = portage.pkgsplit(a)[0] #Populate graph try: cp_index = vertices[cp] except KeyError: v1 = g.add_vertex() g.vp.vlabel[v1] = cp g.vp.vcolor[v1] = overlay_color g.vp.vtext_color[v1] = overlay_text_color vertices[cp] = g.vertex_index[v1] else: v1 = g.vertex(cp_index) for dep in deps: if only_overlay: if dep in all_cp or dep in vertices: vertices, _ = add_vertex_and_edge(g, dep, vertices, v1, vcolor=overlay_color, vtext_color=overlay_text_color, ecolor=overlay_edge_color, eorder=overlay_edge_order, ) else: break sets_property_values=[] sets_property_values.append([all_cp,[overlay_color,overlay_text_color,overlay_edge_color,overlay_edge_order]]) sets_property_values.append([all_cp+deps,[extraneous_color,extraneous_text_color,extraneous_edge_color,extraneous_edge_order]]) vcolor, vtext_color, ecolor, eorder = vertex_and_edge_appearance(dep, sets_property_values, g, v1) vertices, _ = add_vertex_and_edge(g, dep, vertices, v1, vcolor=vcolor, vtext_color=vtext_color, ecolor=ecolor, eorder=eorder) return g, vertices
def get_all_packages(overlay_paths): """Returns all packages from a given overlay path. Originally ftom https://gist.github.com/noisebleed/3194783 """ packages = {} porttree = portage.db[portage.root]['porttree'] for overlay_path in overlay_paths: if overlay_path not in porttree.dbapi.porttrees: print('Overlay "{}" is not known to Portage.\n'.format(overlay_path) + 'Please set it. Learn how at https://wiki.gentoo.org/wiki/Overlay') return False for cp in porttree.dbapi.cp_all(trees=overlay_paths): newest_cpv = cp+"-0_beta" #nothing should be earlier than this for cpv in porttree.dbapi.cp_list(cp, mytree=overlay_paths): if portage.pkgcmp(portage.pkgsplit(cpv), portage.pkgsplit(newest_cpv)) >= 0: newest_cpv = cpv if newest_cpv != cp+"-0_beta": deps = porttree.dbapi.aux_get(newest_cpv, ["DEPEND","RDEPEND","PDEPEND"]) deps = ' '.join(deps).split() # consolidate deps deps = list(set(deps)) # de-duplicate #correct dependency list formatting for ix in range(len(deps)): #remove non-package entries from deps list if not "/" in deps[ix]: deps[ix] = None else: #remove all syntax that does not match cpv for delimiter in ["[",":"]: if delimiter in deps[ix]: deps[ix] = deps[ix].split(delimiter)[0] if deps[ix][:2] in [">=", "<=", "!<", "!>"]: deps[ix] = deps[ix][2:] if deps[ix][:1] in [">", "<", "~", "=", "!"]: deps[ix] = deps[ix][1:] if deps[ix][-1:] in ["*"]: deps[ix] = deps[ix][:-1] deps = list(filter(None, deps)) for ix, a in enumerate(deps): if portage.pkgsplit(a) != None: deps[ix] = portage.pkgsplit(a)[0] packages[cp] = deps G = nx.Graph(packages) options = { 'with_labels': False, 'node_color': 'red', 'node_size': 5, 'linewidths': 0, 'width': 0.5, } plt.figure(figsize=(14,14), tight_layout=True) plt.axis('equal') # print(packages["sci-mathematics/yoricks"]) # nx.draw_shell(G, nlist=[range(0,10), range(10,1000)], **options) # nx.draw(G, shell_layout(G, nlist=[range(0,10), range(10,2000)]), **options) # nx.draw_spring(G, iterations=500000, **options) # pos=pygraphviz_layout(G,prog='neato',args='') # pos=nx.spring_layout(G,dim=3,iterations=10000) pos=nx.spring_layout(G,k=0.05,iterations=1000) nx.draw(G, pos, **options) plt.show() return G
def get_cp_deps(cp, overlay_path, porttree, matchnone=True, matchall=True): """Get cp formatted deps for given cp. Parameters ---------- cp : str Category and package formatted according to the Portage cp syntax (category/package) overlay_path : str Path to the overlay in which to check for package versions porttree : porttree object Porttree object obtained via e.g. `porttree = portage.db[portage.root]['porttree']` matchnone : boolean , optional Whether to only match mandatory dependencies. matcall : boolean , optional Whether to match all mandatory dependencies. """ newest_cpv = cp+"-0_alpha_pre" #nothing should be earlier than this ceil_cpv = cp+"-9999" #ideally we would not want live packages for cpv in porttree.dbapi.cp_list(cp, mytree=overlay_path): if portage.pkgcmp(portage.pkgsplit(cpv), portage.pkgsplit(newest_cpv)) >= 0: if portage.pkgcmp(portage.pkgsplit(ceil_cpv), portage.pkgsplit(cpv)) > 0: newest_cpv = cpv elif newest_cpv == cp+"-0_alpha_pre": newest_cpv = cpv if newest_cpv != cp+"-0_alpha_pre": deps = porttree.dbapi.aux_get(newest_cpv, ["DEPEND","RDEPEND","PDEPEND"]) deps = portage.dep.use_reduce(depstr=deps, matchnone=matchnone, matchall=matchall, flat=True) deps = ' '.join(deps) # only keep first package from exactly-one-of lists deps = re.sub(r"\|\| \( (.+?) .+? \)",r"\1",deps) deps = deps.split(" ") deps = list(set(deps)) # de-duplicate else: print("WARNING: skipping "+newest_cpv) return False #correct dependency list formatting for ix in range(len(deps)): #remove non-package entries from deps list if not "/" in deps[ix]: deps[ix] = None else: #remove all syntax that does not match cpv for delimiter in ["[",":"]: if delimiter in deps[ix]: deps[ix] = deps[ix].split(delimiter)[0] if deps[ix][:2] in [">=", "<="]: deps[ix] = deps[ix][2:] if deps[ix][:1] in [">", "<", "~", "="]: deps[ix] = deps[ix][1:] if deps[ix][-1:] in ["*"]: deps[ix] = deps[ix][:-1] if deps[ix][:2] in ["!!", "!~", "!<", "!>", "!="]: deps[ix] = None elif deps[ix][:1] == "!": deps[ix] = None deps = list(filter(None, deps)) for ix in range(len(deps)): if portage.pkgsplit(deps[ix]) != None: deps[ix] = portage.pkgsplit(deps[ix])[0] return deps