def main(): allpaths = set() for pkg in pyalpm.Handle('/', '/var/lib/pacman').get_localdb().pkgcache: for path, db_md5 in pkg.backup: md5 = hashlib.md5() try: f = open('/' + path, 'rb', BUFSIZE) except FileNotFoundError: if path in (p for p, _, _ in pkg.files): print('D /{} ({})'.format(path, pkg.name)) except PermissionError as e: errprint('{} ({})'.format(e, pkg.name)) else: for chunk in iter(lambda: f.read(BUFSIZE), b''): md5.update(chunk) f.close() if md5.hexdigest() != db_md5: print('M /{} ({})'.format(path, pkg.name)) allpaths.update('/' + path for path, _, _ in pkg.files) for top in DIRS: for dirpath, dirnames, filenames in os.walk(top, onerror=errprint): for d in SKIP_DIRS.get(dirpath, ()): with suppress(ValueError): dirnames.remove(d) for fn in filenames: path = os.path.join(dirpath, fn) if path not in allpaths: print('A ' + path)
def __init__(self, max_day: int = 60, log_file: str = '/var/log/pacman.log'): self.max_day = max_day self.log_file = log_file self.items = [] handle = pyalpm.Handle('/', '/var/lib/pacman') self.db = handle.get_localdb()
def __init__(self, name, directory, find_packages=_default_find_packages): super().__init__(name) self._logger = logbook.Logger(name) self._directory = directory self._find_packages = find_packages self._pacman_handle = pyalpm.Handle('/', '/var/lib/pacman') self.update()
def setupRemote(self): handle = pyalpm.Handle('/', '/var/lib/pacman') repos = ['core', 'community', 'extra'] db = {} for repo in repos: db[repo] = handle.register_syncdb(repo, pyalpm.SIG_DATABASE_OPTIONAL) sync = handle.get_syncdbs() return db
def initialize_alpm(self): h = pyalpm.Handle(self.options["RootDir"], self.options["DBPath"]) h.arch = self.options["Architecture"] h.logfile = self.options["LogFile"] h.gpgdir = self.options["GPGDir"] h.cachedirs = self.options["CacheDir"] if "IgnoreGroup" in self.options: h.ignoregrps = self.options["IgnoreGroup"] if "IgnorePkg" in self.options: h.ignorepkgs = self.options["IgnorePkg"] if "NoExtract" in self.options: h.noextracts = self.options["NoExtract"] if "NoUpgrade" in self.options: h.noupgrades = self.options["NoUpgrade"] if "UseSyslog" in self.options: h.usesyslog = self.options["UseSyslog"] if "CheckSpace" in self.options: h.checkspace = self.options["CheckSpace"] # register default siglevel, it should have been updated previously h.siglevel = self.default_siglevel # update localsiglevel if "LocalFileSigLevel" in self.options: localsiglevel = define_siglevel(self.default_siglevel, self.options["LocalFileSigLevel"]) localsiglevel = merge_siglevel(self.default_siglevel, localsiglevel) else: localsiglevel = self.default_siglevel # define localsiglevel h.localsiglevel = localsiglevel # update remotesiglevel if "RemoteFileSigLevel" in self.options: remotesiglevel = define_siglevel( self.default_siglevel, self.options["RemoteFileSigLevel"]) remotesiglevel = merge_siglevel(self.default_siglevel, remotesiglevel) else: remotesiglevel = self.default_siglevel # define remotesiglevel h.remotesiglevel = remotesiglevel # set sync databases for repo, servers in self.repos.items(): db = h.register_syncdb(repo, servers[1]) db_servers = [] for rawurl in servers[0]: url = rawurl.replace("$repo", repo) url = url.replace("$arch", self.options["Architecture"]) db_servers.append(url) db.servers = db_servers return h
def get_vulnerable_pkgs(cve_list): alpm_handle = pyalpm.Handle("/", "/var/lib/pacman") alpmdb = alpm_handle.get_localdb() vulnerables = [] for pkgname, info in cve_list.items(): pkg = alpmdb.get_pkg(pkgname) if not pkg: continue # Not installed for cve_version, cves in info.items(): if pyalpm.vercmp(pkg.version, cve_version) != 1: vulnerables.append((pkgname, pkg.version, cves)) return vulnerables
def _main(force: bool = False): blacklist = set() providers = set() repomap = dict() db_path = aurweb.config.get("aurblup", "db-path") sync_dbs = aurweb.config.get('aurblup', 'sync-dbs').split(' ') server = aurweb.config.get('aurblup', 'server') h = pyalpm.Handle("/", db_path) for sync_db in sync_dbs: repo = h.register_syncdb(sync_db, pyalpm.SIG_DATABASE_OPTIONAL) repo.servers = [server.replace("%s", sync_db)] t = h.init_transaction() repo.update(force) t.release() for pkg in repo.pkgcache: blacklist.add(pkg.name) util.apply_all(pkg.replaces, blacklist.add) providers.add((pkg.name, pkg.name)) repomap[(pkg.name, pkg.name)] = repo.name for provision in pkg.provides: provisionname = re.sub(r'(<|=|>).*', '', provision) providers.add((pkg.name, provisionname)) repomap[(pkg.name, provisionname)] = repo.name with db.begin(): old_providers = set( db.query(OfficialProvider).with_entities( OfficialProvider.Name.label("Name"), OfficialProvider.Provides.label("Provides") ).distinct().order_by("Name").all() ) for name, provides in old_providers.difference(providers): db.delete_all(db.query(OfficialProvider).filter( and_(OfficialProvider.Name == name, OfficialProvider.Provides == provides) )) for name, provides in providers.difference(old_providers): repo = repomap.get((name, provides)) db.create(OfficialProvider, Name=name, Repo=repo, Provides=provides)
def get_minecraft_info(): if not alpm_imported or not dbus_imported: out = "Minecraft info not available due to modules:" out += "" if alpm_imported else " pyalpm" out += "" if dbus_imported else " dbus" return out bus = SystemBus() systemd = bus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1') manager = Interface(systemd, dbus_interface='org.freedesktop.systemd1.Manager') unit = manager.LoadUnit(config_get("minecraft", "unit")) uproxy = bus.get_object('org.freedesktop.systemd1', str(unit)) state = Interface(uproxy, dbus_interface='org.freedesktop.DBus.Properties') active_state = str( state.Get('org.freedesktop.systemd1.Unit', 'ActiveState', dbus_interface='org.freedesktop.DBus.Properties')) if active_state == 'active': active_time = int( state.Get('org.freedesktop.systemd1.Unit', 'ActiveEnterTimestamp', dbus_interface='org.freedesktop.DBus.Properties')) else: active_time = 0 alpm_handle = pyalpm.Handle(config_get("alpm", "rootdir"), config_get("alpm", "dbdir")) local_db = alpm_handle.get_localdb() mc_pkg = local_db.get_pkg(config_get("minecraft", "pkgname")) ver = mc_pkg.version sanitized_ver = ''.join(re.findall(r'(\d+\.)(\d+\.)?(\*|\d*)', ver)[0]) if active_state == 'active': out = "Minecraft server is up!\nUptime: %s\nVersion: %s\nAddress: %s" % \ (datetime.datetime.now() - datetime.datetime.fromtimestamp(int(active_time/1000000)), sanitized_ver, config_get("minecraft", "address")) else: out = "Minecraft server is down!" return out
def __init__(self, root_path: str = "/", db_path: str = "/var/lib/pacman", conf_path: str = "/etc/pacman.conf"): self.handle: pyalpm.Handle = pyalpm.Handle(root_path, db_path) self.syncdbs: list = [] with open(conf_path) as f: lines: list = [line.strip() for line in f.readlines()] for number, line in enumerate(lines): match: re.Match = re.match(r"^\[(?P<REPO_NAME>.*)\]$", line) if match and "SigLevel" in lines[number + 1]: self.syncdbs.append( self.handle.register_syncdb(match.group("REPO_NAME"), pyalpm.SIG_DATABASE_OPTIONAL)) self.installed = sorted(run_cmd(["pacman", "-Qq"]).stdout.split())
def main(): blacklist = set() providers = set() repomap = dict() h = pyalpm.Handle("/", db_path) for sync_db in sync_dbs: repo = h.register_syncdb(sync_db, pyalpm.SIG_DATABASE_OPTIONAL) repo.servers = [server.replace("%s", sync_db)] t = h.init_transaction() repo.update(False) t.release() for pkg in repo.pkgcache: blacklist.add(pkg.name) [blacklist.add(x) for x in pkg.replaces] providers.add((pkg.name, pkg.name)) repomap[(pkg.name, pkg.name)] = repo.name for provision in pkg.provides: provisionname = re.sub(r'(<|=|>).*', '', provision) providers.add((pkg.name, provisionname)) repomap[(pkg.name, provisionname)] = repo.name conn = aurweb.db.Connection() cur = conn.execute("SELECT Name, Provides FROM OfficialProviders") oldproviders = set(cur.fetchall()) for pkg, provides in oldproviders.difference(providers): conn.execute("DELETE FROM OfficialProviders " "WHERE Name = ? AND Provides = ?", [pkg, provides]) for pkg, provides in providers.difference(oldproviders): repo = repomap[(pkg, provides)] conn.execute("INSERT INTO OfficialProviders (Name, Repo, Provides) " "VALUES (?, ?, ?)", [pkg, repo, provides]) conn.commit() conn.close()
def init_data(dbpath: Path, *, quiet: bool = False) -> None: global _repo_package_versions if quiet: kwargs = {'stdout': subprocess.DEVNULL} else: kwargs = {} for _ in range(3): p = subprocess.run( # type: ignore # what a mess... ['fakeroot', 'pacman', '-Sy', '--dbpath', dbpath], **kwargs, ) if p.returncode == 0: break else: p.check_returncode() now = int(time.time()) deadline = now - 90 * 86400 _official_packages.update( _load_timed_dict(dbpath / 'packages.txt', deadline)) _official_groups.update( _load_timed_dict(dbpath / 'groups.txt', deadline)) H = pyalpm.Handle('/', str(dbpath)) for repo in _official_repos: db = H.register_syncdb(repo, 0) _official_packages.update((p.name, now) for p in db.pkgcache) _official_packages_current.update(p.name for p in db.pkgcache) _official_groups.update((g[0], now) for g in db.grpcache) _save_timed_dict(dbpath / 'packages.txt', _official_packages) _save_timed_dict(dbpath / 'groups.txt', _official_groups) if hasattr(_G, 'repo'): db = H.register_syncdb(_G.repo.name, 0) _repo_package_versions = {p.name: p.version for p in db.pkgcache}
def initialize(self, updates=False): if self.config is not None: root_dir = self.config.options["RootDir"] db_path = self.config.options["DBPath"] else: root_dir = _DEFAULT_ROOT_DIR db_path = _DEFAULT_DB_PATH self.handle = pyalpm.Handle(root_dir, db_path) if self.handle is None: raise pyalpm.error if self.config is not None: self.config.apply(self.handle, updates) # Set callback functions # Callback used for logging self.handle.logcb = self.cb_log # Callback used to report download progress self.handle.dlcb = self.cb_dl # Callback used to report total download size self.handle.totaldlcb = self.cb_totaldl # Callback used for events self.handle.eventcb = self.cb_event # Callback used for questions self.handle.questioncb = self.cb_question # Callback used for operation progress self.handle.progresscb = self.cb_progress # Downloading callback self.handle.fetchcb = None
def get_minecraft_info(): bus = SystemBus() systemd = bus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1') manager = Interface(systemd, dbus_interface='org.freedesktop.systemd1.Manager') unit = manager.LoadUnit('spigot.service') uproxy = bus.get_object('org.freedesktop.systemd1', str(unit)) state = Interface(uproxy, dbus_interface='org.freedesktop.DBus.Properties') active_state = str( state.Get('org.freedesktop.systemd1.Unit', 'ActiveState', dbus_interface='org.freedesktop.DBus.Properties')) if active_state == 'active': active_time = int( state.Get('org.freedesktop.systemd1.Unit', 'ActiveEnterTimestamp', dbus_interface='org.freedesktop.DBus.Properties')) else: active_time = 0 alpm_handle = pyalpm.Handle("/", "/var/lib/pacman") local_db = alpm_handle.get_localdb() spigot_pkg = local_db.get_pkg("spigot") ver = spigot_pkg.version if active_state == 'active': out = "Minecraft server is up!\nUptime: %s\nVersion: %s\nAddress: %s" % \ (datetime.datetime.now() - datetime.datetime.fromtimestamp(int(active_time/1000000)), ver.split(":")[1].split("-")[0], config_get("minecraft", "address")) else: out = "Minecraft server is down!" return out
def setup(): """TODO DOCSTRING""" handle = pyalpm.Handle(r"/", r"/var/lib/pacman") localdb = handle.get_localdb() return handle, localdb
def test_create_failed(): with raises(pyalpm.error) as excinfo: pyalpm.Handle('/non-existant', '/') assert 'could not create a libalpm handle' in str(excinfo.value)
def main(action, uninstalled, signed_off, quiet, username, password, package, db_path, noconfirm, nocolor): """ Interface with Arch Linux package signoffs. """ if action is None: if package: action = "signoff" else: action = "list" options = Options(action=action, show_uninstalled=uninstalled, show_signed_off=signed_off, quiet=quiet, packages=set(package), db_path=db_path, username=username, noconfirm=noconfirm, nocolor=nocolor) # initialize alpm handle and signoff session try: alpm_handle = pyalpm.Handle("/", options.db_path) except pyalpm.error: click.echo("error: could not read alpm database {}".format( options.db_path), err=True) sys.exit(1) session = SignoffSession(options.username, password) if options.nocolor or os.environ.get("TERM") == "dumb": colorize = False else: colorize = True # fetch and filter signoff packages signoffs = list(list_signoffs(session, alpm_handle)) packages = list(filter_signoffs(signoffs, options)) pkgbases = set(signoff_pkg["pkgbase"] for signoff_pkg, _ in packages) # if packages are supplied as parameters, validate them for pkgbase in options.packages: if pkgbase not in pkgbases: raise click.BadParameter( "package base {} not found in signoffs".format(pkgbase)) if action == "list": # output packages and exit for signoff_pkg, local_pkg in packages: click.echo(format_signoff(signoff_pkg, local_pkg, options), color=colorize) if not options.quiet: click.echo() # add a line between packages elif action == "signoff": # sign-off packages for signoff_pkg, local_pkg in packages: if not local_pkg: raise click.UsageError("{} package not installed".format( signoff_pkg['pkgbase'])) warn_if_outdated(signoff_pkg, local_pkg, colorize) warn_if_bad(signoff_pkg, colorize) if options.noconfirm or confirm( "Sign off {}?".format( click.style(" ".join(pkgbases), bold=True)), colorize): for signoff_pkg, local_pkg in packages: try: session.signoff_package(signoff_pkg) except requests.exceptions.HTTPError as e: click.echo("Could not sign off {} ({})".format( signoff_pkg["pkgbase"], e)) else: click.echo("Signed off {}.".format(signoff_pkg["pkgbase"])) elif action == "revoke": # revoke sign-offs for signoff_pkg, local_pkg in packages: if not local_pkg: raise click.UsageError("{} package not installed".format( signoff_pkg['pkgbase'])) warn_if_outdated(signoff_pkg, local_pkg, colorize) warn_if_bad(signoff_pkg, colorize) if options.noconfirm or confirm( "Revoke sign-off for {}?".format( click.style(" ".join(pkgbases), bold=True)), colorize): for signoff_pkg, local_pkg in packages: session.revoke_package(signoff_pkg) click.echo("Revoked sign-off for {}.".format( signoff_pkg["pkgbase"])) elif action == "interactive": # interactively sign-off or revoke for signoff_pkg, local_pkg in packages: click.echo(format_signoff(signoff_pkg, local_pkg, options)) warn_if_outdated(signoff_pkg, local_pkg, colorize) warn_if_bad(signoff_pkg, colorize) if not options.quiet: click.echo() # check if we're signing off or revoking pkgbase = signoff_pkg["pkgbase"] signed_off = signoff_status(signoff_pkg, options.username) == "signed-off" if signed_off: prompt = "Revoke sign-off for {}?".format(pkgbase) else: prompt = "Sign off {}?".format(pkgbase) # confirm and signoff/revoke if confirm(prompt, colorize): if signed_off: session.revoke_package(signoff_pkg) click.echo("Revoked sign-off for {}.".format(pkgbase)) else: session.signoff_package(signoff_pkg) click.echo("Signed off {}.".format(pkgbase)) click.echo() session.logout()
def setupLocal(self): handle = pyalpm.Handle('/', '/var/lib/pacman') db = handle.get_localdb() return db
def vrms(): parser = OptionParser() parser.add_option( "-g", "--global-repos", dest="use_global_repos", action="store_true", default=False, help= "Check licenses in all packages in all synced repositories (might exclude the AUR!), rather than that of locally installed packages" ) parser.add_option("-a", "--list-licenses", dest="list_all_licenses", action="store_true", default=False, help="List all licenses") parser.add_option( "-e", "--list-ethical", dest="list_ethical", action="store_true", default=False, help="List only non-free packages with 'ethical source' licenses") parser.add_option( "-u", "--list-unknowns", dest="list_unknowns", action="store_true", default=False, help="List packages of unknown license instead of non-free packages") (options, _) = parser.parse_args() h = pyalpm.Handle("/", "/var/lib/pacman") dbs_to_visit = [] if options.use_global_repos: for d in set( os.path.splitext(f)[0] for f in os.listdir("/var/lib/pacman/sync")): h.register_syncdb(d, 0) dbs_to_visit = h.get_syncdbs() else: # print("There are %d installed packages." % len(h.get_localdb())) dbs_to_visit.append(h.get_localdb()) visitor = LicenseFinder() for db in dbs_to_visit: # print("Reading pacman DB: %s" % db.name, file=sys.stderr) db = UnambiguousDb(db) visitor.visit_db(db) if options.list_unknowns: visitor.list_all_unknown_packages() elif options.list_ethical: visitor.list_all_ethical_packages() elif options.list_all_licenses: visitor.list_all_licenses_as_python() else: visitor.list_all_nonfree_packages()
config = configparser.RawConfigParser() config.read(os.path.dirname(os.path.realpath(__file__)) + "/../conf/config") aur_db_host = config.get('database', 'host') aur_db_name = config.get('database', 'name') aur_db_user = config.get('database', 'user') aur_db_pass = config.get('database', 'password') aur_db_socket = config.get('database', 'socket') db_path = config.get('aurblup', 'db-path') sync_dbs = config.get('aurblup', 'sync-dbs').split(' ') servers = config.get('aurblup', 'servers').split(' ') blacklist = set() h = pyalpm.Handle("/", db_path) for sync_db in sync_dbs: repo = h.register_syncdb(sync_db, pyalpm.SIG_DATABASE_OPTIONAL) repo.servers = [server.replace("%s", sync_db) for server in servers] t = h.init_transaction() repo.update(False) t.release() for pkg in repo.pkgcache: blacklist.add(pkg.name) [blacklist.add(x) for x in pkg.replaces] db = mysql.connector.connect(host=aur_db_host, user=aur_db_user, passwd=aur_db_pass, db=aur_db_name, unix_socket=aur_db_socket, buffered=True) cur = db.cursor()
def main(action, uninstalled, signed_off, quiet, username, password, package, db_path, noconfirm): """ Interface with Arch Linux package signoffs. """ if action is None: if package: action = "signoff" else: action = "list" options = Options(action=action, show_uninstalled=uninstalled, show_signed_off=signed_off, quiet=quiet, packages=set(package), db_path=db_path, username=username, noconfirm=noconfirm) # initialize alpm handle and signoff session alpm_handle = pyalpm.Handle("/", options.db_path) session = SignoffSession(options.username, password) # fetch and filter signoff packages signoffs = list(list_signoffs(session, alpm_handle)) packages = list(filter_signoffs(signoffs, options)) pkgbases = set(signoff_pkg["pkgbase"] for signoff_pkg, _ in packages) # if packages are supplied as parameters, validate them for pkgbase in options.packages: if pkgbase not in pkgbases: raise click.BadParameter( "package base {} not found in signoffs".format(pkgbase)) if action == "list": # output packages and exit for signoff_pkg, local_pkg in packages: click.echo(format_signoff(signoff_pkg, local_pkg, options)) if not options.quiet: click.echo() # add a line between packages elif action == "signoff": # sign-off packages for signoff_pkg, local_pkg in packages: warn_if_outdated(signoff_pkg, local_pkg) if options.noconfirm or confirm("Sign off {}?".format( click.style(" ".join(pkgbases), bold=True))): for signoff_pkg, local_pkg in packages: session.signoff_package(signoff_pkg) click.echo("Signed off {}.".format(signoff_pkg["pkgbase"])) elif action == "revoke": # revoke sign-offs for signoff_pkg, local_pkg in packages: warn_if_outdated(signoff_pkg, local_pkg) if options.noconfirm or confirm("Revoke sign-off for {}?".format( click.style(" ".join(pkgbases), bold=True))): for signoff_pkg, local_pkg in packages: session.revoke_package(signoff_pkg) click.echo("Revoked sign-off for {}.".format( signoff_pkg["pkgbase"])) elif action == "interactive": # interactively sign-off or revoke for signoff_pkg, local_pkg in packages: click.echo(format_signoff(signoff_pkg, local_pkg, options)) warn_if_outdated(signoff_pkg, local_pkg) if not options.quiet: click.echo() # check if we're signing off or revoking pkgbase = signoff_pkg["pkgbase"] signed_off = signoff_status(signoff_pkg, options.username) == "signed-off" if signed_off: prompt = "Revoke sign-off for {}?".format(pkgbase) else: prompt = "Sign off {}?".format(pkgbase) # confirm and signoff/revoke if confirm(prompt): if signed_off: session.revoke_package(signoff_pkg) click.echo("Revoked sign-off for {}.".format(pkgbase)) else: session.signoff_package(signoff_pkg) click.echo("Signed off {}.".format(pkgbase)) click.echo() session.logout()
def __init__(self, *args, **kwargs): self.opts = kwargs self.handle = pyalpm.Handle('/', '/var/lib/pacman') self.db = self.handle.get_localdb()
def setUp(self): self.handle = pyalpm.Handle('/', '/var/lib/pacman')
parser = argparse.ArgumentParser() parser.add_argument("-d", "--days", help="history age", type=int, default=60) parser.add_argument("-f", "--file", help="pacman log", type=argparse.FileType('r'), default='/var/log/pacman.log') parser.add_argument("-v", "--version", help="version", action="store_true") args = parser.parse_args() if args.version: db = pyalpm.Handle('/', '/var/lib/pacman').get_localdb() pkg = db.get_pkg("pacman-logs-gui-git") print('Version:', pkg.version) exit(0) print('days:', args.days) print('log:', args.file.name) logs = AlpmLog(max_day=args.days, log_file=args.file.name) t0 = time.perf_counter() logs.load_file() print('parse log seconds: ', time.perf_counter() - t0, 's') # 3.336281957999745 #ssd, python parse .desc pkg_is_installed() # 0.3611748469993472 # sdd, pyalpm print("count logs:", len(logs.items)) applog = MainApp(classlog=logs)
#!/usr/bin/env python3 import subprocess, os, pyalpm from distutils import spawn handle = pyalpm.Handle("/", "/var/lib/pacman") ldb = handle.get_localdb() sdb = handle.get_syncdbs() devnull = open(os.devnull, 'w') sudo = spawn.find_executable("sudo") def execute_privileged(cmdlist): if sudo: return subprocess.call(["sudo"] + cmdlist) else: return subprocess.call(["su", "-c"] + [" ".join(cmdlist)]) def is_installed(pkgname): return pyalpm.find_satisfier(ldb.pkgcache, pkgname) def installed_version(pkgname): s = pyalpm.find_satisfier(ldb.pkgcache, pkgname) return s.version def in_repos(pkgname): r = subprocess.call(['pacman', '-Si' , pkgname], stdout=devnull, stderr=devnull) return r == 0 def get_foreign_package_versions(): pkgs = subprocess.getoutput("pacman -Qm")