def testParseRcBooleanValue(self, value, expected): with open(self._getTmpFileName(), 'w') as f: f.write("always_update = {0}".format(value)); ret = utils.parse_rc(self._getTmpFileName()); self.assertTrue(isinstance(ret, ConfigStructure)); self.assertEqual(ret.always_update, expected);
def testParseRcWithTrailingWhitespace(self, whitespace): f = open(self._getTmpFileName(), 'w'); f.write("mirror = \"http://foo\""+whitespace); f.close(); ret = utils.parse_rc(self._getTmpFileName()); self.assertTrue(isinstance(ret, ConfigStructure)); self.assertEqual("http://foo", ret.mirror);
def testParseRc(self): self._writeUserConfig(self._getTmpFileName()); ret = utils.parse_rc(self._getTmpFileName()); self.assertTrue(isinstance(ret, ConfigStructure)); self.assertFalse(ret.always_update); self.assertEqual(ret.ROOT, self._dir_mtroot); self.assertEqual(ret.mirror, self._var_mirror); self.assertEqual(ret.cache, self._dir_execache); self.assertEqual(ret.distname, 'curr'); self.assertEqual(ret.barred, '');
def testParseRc(self): f = open(self._getTmpFileName(), 'w'); f.write("always_update = \"True\""); f.close(); ret = utils.parse_rc(self._getTmpFileName()); self.assertTrue(ret); f = open(self._getTmpFileName(), 'w'); f.write("always_update = \"False\""); f.close(); ret = utils.parse_rc(self._getTmpFileName()); self.assertFalse(ret); f = open(self._getTmpFileName(), 'w'); f.write("always_update = bad_value"); f.close(); self.assertRaises( NameError, utils.parse_rc, self._getTmpFileName() );
def getRessource(self, filename): self.__rc = cautils.parse_rc(filename) if not self.__rc.cache: msg = "{0} doesn't define cache.".format(self.__rcFile) raise UnexpectedValueException(msg) if not self.__rc.mirror: msg = "{0} doesn't define mirror.".format(self.__rcFile) raise UnexpectedValueException(msg) # We want ROOT + "/etc/setup" and cd(ROOT) to work: # necessitates two different forms, prefix and absolute if (self.__cygwinPlatform): self.setRoot("/") else: self.setRoot(self.__rc.ROOT) self.__rc.ROOT = None self.__pm = PathMapper(self.__prefixRoot, self.__cygwinPlatform) self.__setupDir = self.__pm.mapPath(self.__setupDir) self.__rc.cache = self.__pm.mapPath(self.__rc.cache) self.__downloadDir = os.path.join( self.__rc.cache, urllib.quote( self.__rc.mirror + ('' if self.__rc.mirror.endswith('/') else '/'), '').lower()) self.__installedDbFile = os.path.join(self.__setupDir, "installed.db") self.__setupIniPath = os.path.join( self.__downloadDir, self.__arch, "setup.ini", ) self.__dosBash = "{0}bin/bash".format(self.__pm.getMountRoot()) self.__dosLn = "{0}bin/ln".format(self.__pm.getMountRoot()) self.__dosXz = self.__pm.mapPath("/usr/bin/xz") self.__dosDash = "{0}bin/dash".format(self.__pm.getMountRoot()) return 0
def getRessource(self, filename): self.__rc = cautils.parse_rc(filename); if not self.__rc.cache: msg = "{0} doesn't define cache.".format(self.__rcFile); raise UnexpectedValueException(msg); if not self.__rc.mirror: msg = "{0} doesn't define mirror.".format(self.__rcFile); raise UnexpectedValueException(msg); # We want ROOT + "/etc/setup" and cd(ROOT) to work: # necessitates two different forms, prefix and absolute if(self.__cygwinPlatform): self.setRoot("/"); else: self.setRoot(self.__rc.ROOT); self.__rc.ROOT = None; self.__pm = PathMapper(self.__prefixRoot, self.__cygwinPlatform); self.__setupDir = self.__pm.mapPath(self.__setupDir); self.__rc.cache = self.__pm.mapPath(self.__rc.cache); self.__downloadDir = os.path.join( self.__rc.cache, urllib.quote(self.__rc.mirror+('' if self.__rc.mirror.endswith('/') else '/'), '').lower() ); self.__installedDbFile = os.path.join(self.__setupDir, "installed.db"); self.__setupIniPath = os.path.join( self.__downloadDir, self.__arch, "setup.ini", ); self.__dosBash = "{0}bin/bash".format(self.__pm.getMountRoot()); self.__dosLn = "{0}bin/ln".format(self.__pm.getMountRoot()); self.__dosXz = self.__pm.mapPath("/usr/bin/xz"); self.__dosDash = "{0}bin/dash".format(self.__pm.getMountRoot()); return 0;
def main(self): # parse command line arguments cap = CygAptArgParser(scriptname=self.getAppName()) args = cap.parse() # initialize main variables with command line arguments and options main_command = args.command main_files = args.package[:] main_files.insert(0, main_command) main_packagename = None if len(args.package) > 0: main_packagename = args.package[0] main_verbose = args.verbose main_download_p = args.download_p main_mirror = args.mirror main_distname = args.distname main_noupdate = args.noupdate main_nodeps_p = args.nodeps_p main_regex_search = args.regex_search main_nobarred = args.force main_verify = args.verify main_nopostinstall = args.nopostinstall main_nopostremove = args.nopostremove main_downloads = None main_dists = 0 main_installed = 0 # locate and parse the configuration file main_cyg_apt_rc = self.getConfigPath() config = None if main_cyg_apt_rc: config = cautils.parse_rc(main_cyg_apt_rc) elif (main_command != "setup"): print("{0}: no .{0}: run \"{0} setup\"".format(self.getAppName()), file=sys.stderr) return 1 # create a CygAptSetup instance and its dependencies main_cygwin_p = (sys.platform == "cygwin") is_64_bit = False if main_cygwin_p: # Running Cygwin python, so python architecture == Cygwin architecture if 2**32 < sys.maxsize: is_64_bit = True elif config and main_command != 'setup': # Running Windows python, so examine cygwin1.dll pathMapper = PathMapper(config.ROOT.rstrip('\\/'), main_cygwin_p) if cautils.pe_is_64_bit(pathMapper.mapPath("/bin/cygwin1.dll")): is_64_bit = True if is_64_bit: main_arch = 'x86_64' else: main_arch = 'x86' cas = CygAptSetup(main_cygwin_p, main_verbose, main_arch) # run command if (main_command == "setup"): cas.setup(args.force) return 0 elif (main_command == "help"): cas.usage(main_cyg_apt_rc) return 0 elif (main_command == "update"): cas.update(main_cyg_apt_rc, main_verify, main_mirror=main_mirror) return 0 # make an update if needed update_not_needed = [ "ball", "find", "help", "purge", "remove", "version", "filelist", "update", "setup", "md5", ] always_update = config.always_update always_update = always_update and\ main_command not in update_not_needed and\ not main_noupdate if always_update: cas.update(main_cyg_apt_rc, main_verify, main_mirror=main_mirror) if main_command and main_command in dir(CygApt): cyg_apt = CygApt( main_packagename, main_files, main_cyg_apt_rc, main_cygwin_p, main_download_p, main_mirror, main_downloads, main_distname, main_nodeps_p, main_regex_search, main_nobarred, main_nopostinstall, main_nopostremove, main_dists, main_installed, self.getAppName(), main_verbose, main_arch, ) getattr(cyg_apt, main_command)() else: cas.usage(main_cyg_apt_rc) return 0
def main(self): main_downloads = None; main_dists = 0; main_installed = 0; main_packagename = None; main_cyg_apt_rc = None; home_cyg_apt_rc = None; main_verbose = False; main_cygwin_p = (sys.platform == "cygwin"); cas = CygAptSetup(main_cygwin_p, main_verbose); update_not_needed = [ "ball", "find", "help", "purge", "remove", "version", "filelist", "update", "setup", "md5", ]; ob = CygAptOb(True); cas.usage(); usage = ob.getFlush(); cap = CygAptArgParser(usage=usage, scriptname=self.getAppName()); args = cap.parse(); main_command = args.command; main_files = args.package[:]; main_files.insert(0, main_command); if len(args.package) > 0: main_packagename = args.package[0]; else: main_packagename = None; main_verbose = args.verbose; main_download_p = args.download_p; main_mirror = args.mirror; main_distname = args.distname; main_noupdate = args.noupdate; main_nodeps_p = args.nodeps_p; main_regex_search = args.regex_search; main_nobarred = args.force; main_verify = args.verify; main_nopostinstall = args.nopostinstall; main_nopostremove = args.nopostremove; cas.setVerbose(main_verbose); # Take most of our configuration from .cyg-apt # preferring .cyg-apt in current directory over $(HOME)/.cyg-apt cwd_cyg_apt_rc = os.path.join( os.getcwd(), ".{0}".format(self.getAppName()) ); if os.path.exists(cwd_cyg_apt_rc): main_cyg_apt_rc = cwd_cyg_apt_rc; elif "HOME" in os.environ: home_cyg_apt_rc = os.path.join( os.environ['HOME'], ".{0}".format(self.getAppName()) ); if os.path.exists(home_cyg_apt_rc): main_cyg_apt_rc = home_cyg_apt_rc; if main_cyg_apt_rc: # Take our configuration from .cyg-apt # Command line options can override, but only for this run. main_cyg_apt_rc = main_cyg_apt_rc.replace("\\","/"); elif (main_command != "setup"): print( "{0}: no .{0}: run \"{0} setup\"".format(self.getAppName()), file=sys.stderr ); return 1; if (main_command == "setup"): cas.setup(args.force); return 0; elif (main_command == "help"): cas.usage(main_cyg_apt_rc); return 0; elif (main_command == "update"): cas.update(main_cyg_apt_rc, main_verify, main_mirror=main_mirror); return 0; always_update = cautils.parse_rc(main_cyg_apt_rc); always_update = always_update and\ main_command not in update_not_needed and\ not main_noupdate; if always_update: cas.update(main_cyg_apt_rc, main_verify, main_mirror=main_mirror); if main_command and main_command in dir(CygApt): cyg_apt = CygApt( main_packagename, main_files, main_cyg_apt_rc, main_cygwin_p, main_download_p, main_mirror, main_downloads, main_distname, main_nodeps_p, main_regex_search, main_nobarred, main_nopostinstall, main_nopostremove, main_dists, main_installed, self.getAppName(), main_verbose ); getattr(cyg_apt, main_command)(); else: cas.usage(main_cyg_apt_rc); return 0;
def update(self, cyg_apt_rc, verify, main_mirror=None): """fetch current package database from mirror""" sig_name = None self.__rc = cautils.parse_rc(cyg_apt_rc) if (not self.__cygwinPlatform): self.__pm = PathMapper(self.__rc.ROOT[:-1], False) if (main_mirror): mirror = main_mirror else: mirror = self.__rc.mirror if not mirror: raise UnexpectedValueException( "A mirror must be specified on the configuration file \"{0}\" " "or with the command line option \"--mirror\". " "See cygwin.com/mirrors.html for the list of mirrors." "".format(cyg_apt_rc)) if not mirror[-1] == "/": sep = "/" else: sep = "" setup_ini_names = [ "setup.bz2", "setup.ini", ] bag = zip(setup_ini_names, list(range(len(setup_ini_names)))) platform_dir = self.__arch + "/" for (setup_ini_name, index) in bag: setup_ini_url = '{0}{1}{2}{3}'.format(mirror, sep, platform_dir, setup_ini_name) try: cautils.uri_get(self.__tmpDir, setup_ini_url, verbose=self.__verbose) except ApplicationException as e: # Failed to find a possible .ini if index == len(setup_ini_names) - 1: raise e else: continue # Not an error to fail to find the first one # Take the first one we find break if setup_ini_name[-4:] == ".bz2": bz_file = os.path.join(self.__tmpDir, setup_ini_name) f = open(bz_file, "rb") compressed = f.read() f.close() decomp = bz2.decompress(compressed) os.remove(bz_file) setup_ini_name = "setup.ini" f = open(os.path.join(self.__tmpDir, setup_ini_name), "wb") f.write(decomp) f.close() if not self.__cygwinPlatform: sys.stderr.write( "WARNING can't verify setup.ini outside Cygwin.\n") verify = False if verify: sig_name = "{0}.sig".format(setup_ini_name) sig_url = "{0}{1}{2}{3}".format(mirror, sep, platform_dir, sig_name) try: cautils.uri_get(self.__tmpDir, sig_url, verbose=self.__verbose) except RequestException as e: msg = ("Failed to download signature {0} Use -X to ignore " "signatures.".format(sig_url)) raise RequestException(msg, previous=e) if self.__cygwinPlatform: gpg_path = "gpg" else: if self._cygwinVersion() < 1.7: gpg_path = "/usr/bin/gpg" else: gpg_path = "/usr/local/bin/gpg" cmd = [gpg_path, "--verify", "--no-secmem-warning"] cmd.append("{0}/{1}".format(self.__tmpDir, sig_name)) cmd.append("{0}/{1}".format(self.__tmpDir, setup_ini_name)) p = Process(cmd) p.run() verify = p.getErrorOutput() if isinstance(verify, bytes): marker = self.GPG_GOOD_FINGER.encode() else: marker = self.GPG_GOOD_FINGER if not marker in verify: msg = ("{0} not signed by Cygwin's public key. " "Use -X to ignore signatures.".format(setup_ini_url)) raise SignatureException(msg) downloads = os.path.join( self.__pm.mapPath(self.__rc.cache), urllib.quote(mirror + ('' if mirror.endswith('/') else '/'), '').lower(), platform_dir, ) if not os.path.exists(downloads): os.makedirs(downloads) shutil.copy(os.path.join(self.__tmpDir, setup_ini_name), os.path.join(downloads, setup_ini_name)) # BC layer for `setup_ini` configuration field if self.__rc.setup_ini: setup_ini = self.__pm.mapPath(self.__rc.setup_ini) if os.path.exists(setup_ini): shutil.copy(setup_ini, "{0}.bak".format(setup_ini)) shutil.copy(os.path.join(downloads, setup_ini_name), setup_ini) if os.path.exists(os.path.join(self.__tmpDir, setup_ini_name)): os.remove(os.path.join(self.__tmpDir, setup_ini_name)) if sig_name: if os.path.exists(os.path.join(self.__tmpDir, sig_name)): os.remove(os.path.join(self.__tmpDir, sig_name))
def update(self, cyg_apt_rc, verify, main_mirror=None): """fetch current package database from mirror""" sig_name = None; self.__rc = cautils.parse_rc(cyg_apt_rc); if(not self.__cygwinPlatform): self.__pm = PathMapper(self.__rc.ROOT[:-1], False); if (main_mirror): mirror = main_mirror; else: mirror = self.__rc.mirror; if not mirror : raise UnexpectedValueException( "A mirror must be specified on the configuration file \"{0}\" " "or with the command line option \"--mirror\". " "See cygwin.com/mirrors.html for the list of mirrors." "".format(cyg_apt_rc) ); if not mirror[-1] == "/": sep = "/"; else: sep = ""; setup_ini_names = [ "setup.bz2", "setup.ini", ]; bag = zip(setup_ini_names, list(range(len(setup_ini_names)))); platform_dir = self.__arch+"/"; for (setup_ini_name, index) in bag: setup_ini_url = '{0}{1}{2}{3}'.format(mirror, sep, platform_dir, setup_ini_name); try: cautils.uri_get( self.__tmpDir, setup_ini_url, verbose=self.__verbose ); except ApplicationException as e: # Failed to find a possible .ini if index == len(setup_ini_names) - 1: raise e; else: continue; # Not an error to fail to find the first one # Take the first one we find break; if setup_ini_name[-4:] == ".bz2": bz_file = os.path.join(self.__tmpDir, setup_ini_name); f = open(bz_file, "rb"); compressed = f.read(); f.close(); decomp = bz2.decompress(compressed); os.remove(bz_file); setup_ini_name = "setup.ini"; f = open(os.path.join(self.__tmpDir, setup_ini_name), "wb"); f.write(decomp); f.close(); if not self.__cygwinPlatform: sys.stderr.write("WARNING can't verify setup.ini outside Cygwin.\n"); verify = False; if verify: sig_name = "{0}.sig".format(setup_ini_name); sig_url = "{0}{1}{2}{3}".format(mirror, sep, platform_dir, sig_name); try: cautils.uri_get(self.__tmpDir, sig_url, verbose=self.__verbose); except RequestException as e: msg = ( "Failed to download signature {0} Use -X to ignore " "signatures.".format(sig_url) ); raise RequestException(msg, previous=e); if self.__cygwinPlatform: gpg_path = "gpg"; else: if self._cygwinVersion() < 1.7: gpg_path = "/usr/bin/gpg"; else: gpg_path = "/usr/local/bin/gpg"; cmd = [gpg_path, "--verify", "--no-secmem-warning"]; cmd.append("{0}/{1}".format(self.__tmpDir, sig_name)); cmd.append("{0}/{1}".format(self.__tmpDir, setup_ini_name)); p = Process(cmd); p.run(); verify = p.getErrorOutput(); if isinstance(verify, bytes): marker = self.GPG_GOOD_FINGER.encode(); else: marker = self.GPG_GOOD_FINGER; if not marker in verify: msg = ( "{0} not signed by Cygwin's public key. " "Use -X to ignore signatures.".format(setup_ini_url) ); raise SignatureException(msg); downloads = os.path.join( self.__pm.mapPath(self.__rc.cache), urllib.quote(mirror+('' if mirror.endswith('/') else '/'), '').lower(), platform_dir, ); if not os.path.exists(downloads): os.makedirs(downloads); shutil.copy( os.path.join(self.__tmpDir, setup_ini_name), os.path.join(downloads, setup_ini_name) ); # BC layer for `setup_ini` configuration field if self.__rc.setup_ini : setup_ini = self.__pm.mapPath(self.__rc.setup_ini); if os.path.exists(setup_ini): shutil.copy(setup_ini, "{0}.bak".format(setup_ini)); shutil.copy( os.path.join(downloads, setup_ini_name), setup_ini ); if os.path.exists(os.path.join(self.__tmpDir, setup_ini_name)): os.remove(os.path.join(self.__tmpDir, setup_ini_name)); if sig_name: if os.path.exists(os.path.join(self.__tmpDir, sig_name)): os.remove(os.path.join(self.__tmpDir, sig_name));
def main(self): # parse command line arguments cap = CygAptArgParser(scriptname=self.getAppName()); args = cap.parse(); # initialize main variables with command line arguments and options main_command = args.command; main_files = args.package[:]; main_files.insert(0, main_command); main_packagename = None; if len(args.package) > 0: main_packagename = args.package[0]; main_verbose = args.verbose; main_download_p = args.download_p; main_mirror = args.mirror; main_distname = args.distname; main_noupdate = args.noupdate; main_nodeps_p = args.nodeps_p; main_regex_search = args.regex_search; main_nobarred = args.force; main_verify = args.verify; main_nopostinstall = args.nopostinstall; main_nopostremove = args.nopostremove; main_downloads = None; main_dists = 0; main_installed = 0; # locate and parse the configuration file main_cyg_apt_rc = self.getConfigPath(); config = None; if main_cyg_apt_rc: config = cautils.parse_rc(main_cyg_apt_rc); elif (main_command != "setup"): print( "{0}: no .{0}: run \"{0} setup\"".format(self.getAppName()), file=sys.stderr ); return 1; # create a CygAptSetup instance and its dependencies main_cygwin_p = (sys.platform == "cygwin"); is_64_bit = False; if main_cygwin_p : # Running Cygwin python, so python architecture == Cygwin architecture if 2**32 < sys.maxsize : is_64_bit = True; elif config and main_command != 'setup' : # Running Windows python, so examine cygwin1.dll pathMapper = PathMapper(config.ROOT.rstrip('\\/'), main_cygwin_p); if cautils.pe_is_64_bit(pathMapper.mapPath("/bin/cygwin1.dll")) : is_64_bit = True; if is_64_bit : main_arch = 'x86_64'; else: main_arch = 'x86'; cas = CygAptSetup(main_cygwin_p, main_verbose, main_arch); # run command if (main_command == "setup"): cas.setup(args.force); return 0; elif (main_command == "help"): cas.usage(main_cyg_apt_rc); return 0; elif (main_command == "update"): cas.update(main_cyg_apt_rc, main_verify, main_mirror=main_mirror); return 0; # make an update if needed update_not_needed = [ "ball", "find", "help", "purge", "remove", "version", "filelist", "update", "setup", "md5", ]; always_update = config.always_update; always_update = always_update and\ main_command not in update_not_needed and\ not main_noupdate; if always_update: cas.update(main_cyg_apt_rc, main_verify, main_mirror=main_mirror); if main_command and main_command in dir(CygApt): cyg_apt = CygApt( main_packagename, main_files, main_cyg_apt_rc, main_cygwin_p, main_download_p, main_mirror, main_downloads, main_distname, main_nodeps_p, main_regex_search, main_nobarred, main_nopostinstall, main_nopostremove, main_dists, main_installed, self.getAppName(), main_verbose, main_arch, ); getattr(cyg_apt, main_command)(); else: cas.usage(main_cyg_apt_rc); return 0;