From 8766d9e7dbf6b245fc9492c71af2fa8f704b9c31 Mon Sep 17 00:00:00 2001 From: hungry-henry Date: Thu, 1 May 2025 14:45:09 +0800 Subject: [PATCH 1/2] feat: 1. Add two params: --no-ssl-check & --7zip-path; 2. Skip download if .pkg file exists in landing_dir --- brigadier | 66 +++++++++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/brigadier b/brigadier index 1b19faa..b297d27 100755 --- a/brigadier +++ b/brigadier @@ -46,7 +46,7 @@ def getMachineModel(): model = plist[0]['_items'][0]['machine_model'] return model -def downloadFile(url, filename, use_requests=False): +def downloadFile(url, filename, use_requests=False, verify=True): # http://stackoverflow.com/questions/13881092/ # download-progressbar-for-python-3/13895723#13895723 def reporthook(blocknum, blocksize, totalsize): @@ -62,18 +62,24 @@ def downloadFile(url, filename, use_requests=False): sys.stderr.write("read %d\n" % (readsofar,)) if use_requests: - resp = requests.get(url, stream=True) + resp = requests.get(url, stream=True,verify=verify) with open(filename, 'wb') as fd: for chunk in resp.iter_content(chunk_size=1024): fd.write(chunk) return + + if not verify: + status("Warning: SSL certificate verification is disabled.") # urlretrieve method will likely just go away soon, and we'll use only requests # with some kind of report/progress output urlretrieve(url, filename, reporthook=reporthook) -def sevenzipExtract(arcfile, command='e', out_dir=None): - cmd = [os.path.join(os.environ['SYSTEMDRIVE'] + "\\", "Program Files", "7-Zip", "7z.exe")] +def sevenzipExtract(arcfile, command='e', out_dir=None, exe_path=None): + if not exe_path: + exe_path = os.path.join(os.environ['SYSTEMDRIVE'] + "\\", "Program Files", "7-Zip", "7z.exe") + status("Using 7-Zip executable: %s" % exe_path) + cmd = [exe_path] cmd.append(command) if not out_dir: out_dir = os.path.dirname(arcfile) @@ -144,6 +150,10 @@ where a model has multiple BootCamp ESDs available and is not downloading the de according to the post date.") o.add_option('-V', '--version', action="store_true", help="Output the version of brigadier.") + o.add_option('--no-ssl-check', action="store_false", dest="ssl_check", default=True, + help="Disable SSL certificate verification (not recommended). Default is to verify SSL certificates.") + o.add_option('--7zip-path', dest="zip_path", + help="Specify custom path to 7-Zip executable. If not specified, will look in default locations.") opts, args = o.parse_args() if opts.version: @@ -273,51 +283,35 @@ when running the installer out of 'system32'." % output_dir) # make a sub-dir in the output_dir here, named by product landing_dir = os.path.join(output_dir, 'BootCamp-' + pkg_id) - if os.path.exists(landing_dir): - status("Final output path %s already exists, removing it..." % landing_dir) - if platform.system() == 'Windows': - # using rmdir /qs because shutil.rmtree dies on the Doc files with foreign language characters - subprocess.call(['cmd', '/c', 'rmdir', '/q', '/s', landing_dir]) - else: - shutil.rmtree(landing_dir) - - status("Making directory %s.." % landing_dir) - os.mkdir(landing_dir) - arc_workdir = tempfile.mkdtemp(prefix="bootcamp-unpack_") pkg_dl_path = os.path.join(arc_workdir, pkg_url.split('/')[-1]) - - status("Fetching Boot Camp product at URL %s." % pkg_url) - downloadFile(pkg_url, pkg_dl_path) + if os.path.exists(landing_dir): + if os.path.exists(os.path.join(landing_dir, pkg_url.split('/')[-1])): + status("Boot Camp installer already exists in %s. Skipping download." % landing_dir) + shutil.copyfile(os.path.join(landing_dir, pkg_url.split('/')[-1]), pkg_dl_path) + else: + status("Fetching Boot Camp product at URL %s." % pkg_url) + downloadFile(pkg_url, pkg_dl_path, verify=opts.ssl_check) + else: + status("Making directory %s.." % landing_dir) + os.mkdir(landing_dir) + status("Fetching Boot Camp product at URL %s." % pkg_url) + downloadFile(pkg_url, pkg_dl_path, verify=opts.ssl_check) if platform.system() == 'Windows': - we_installed_7zip = False - sevenzip_binary = os.path.join(os.environ['SYSTEMDRIVE'] + "\\", 'Program Files', '7-Zip', '7z.exe') - # fetch and install 7-Zip - if not os.path.exists(sevenzip_binary): - tempdir = tempfile.mkdtemp() - sevenzip_msi_dl_path = os.path.join(tempdir, SEVENZIP_URL.split('/')[-1]) - downloadFile(SEVENZIP_URL, sevenzip_msi_dl_path, use_requests=True) - status("Downloaded 7-zip to %s." % sevenzip_msi_dl_path) - status("We need to install 7-Zip..") - retcode = subprocess.call(['msiexec', '/qn', '/i', sevenzip_msi_dl_path]) - status("7-Zip install returned exit code %s." % retcode) - we_installed_7zip = True - status("Extracting...") # BootCamp.pkg (xar) -> Payload (gzip) -> Payload~ (cpio) -> WindowsSupport.dmg for arc in [pkg_dl_path, os.path.join(arc_workdir, 'Payload'), os.path.join(arc_workdir, 'Payload~')]: if os.path.exists(arc): - sevenzipExtract(arc) + sevenzipExtract(arc, exe_path=opts.zip_path) # finally, 7-Zip also extracts the tree within the DMG to the output dir sevenzipExtract(os.path.join(arc_workdir, 'WindowsSupport.dmg'), command='x', - out_dir=landing_dir) - if we_installed_7zip: - status("Cleaning up the 7-Zip install...") - subprocess.call(['cmd', '/c', 'msiexec', '/qn', '/x', sevenzip_msi_dl_path]) + out_dir=landing_dir, + exe_path=opts.zip_path + ) if opts.install: status("Installing Boot Camp...") installBootcamp(findBootcampMSI(landing_dir)) From 9436e6d53ae64fadf8d9c6fc915aa73204e2a867 Mon Sep 17 00:00:00 2001 From: HungryHenry <85374539+hungry-henry@users.noreply.github.com> Date: Wed, 21 May 2025 16:57:33 +0800 Subject: [PATCH 2/2] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 0e89048..4528698 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # Brigadier +> **Change Notice:** +> The following features have been added by HungryHenry (me): +> 1. Added two parameters: `--no-ssl-check` & `--7zip-path` +> 2. The script will skip downloading if the `.pkg` file already exists in `landing_dir` + A Windows- and OS X-compatible Python script that fetches, from Apple's or your software update server, the Boot Camp ESD ("Electronic Software Distribution") for a specific model of Mac. It unpacks the multiple layers of archives within the flat package and if the script is run on Windows with the `--install` option, it also runs the 64-bit MSI installer. On Windows, the archives are unpacked using [7-Zip](http://www.7-zip.org), and the 7-Zip MSI is downloaded and installed, and removed later if Brigadier installed it. This tool used to use [dmg2img](http://vu1tur.eu.org/tools/) to perform the extraction of files from Apple's `WindowsSupport.dmg` file, but more recent versions of 7-Zip have included more completely support for DMGs, so dmg2img seems to be no longer needed.