Beispiel #1
0
    def _read_conditions(self):
        """Read any existing conditions in the conditional items property list file."""
        result = dict()

        if os.path.exists(self._conditions_file):
            result = plist.readPlist(path=self._conditions_file)

        return result
    def _read_remote_plist(self):
        """Gets the property list."""
        result = None

        _basename = os.path.basename(self._plist_url_path)
        _tmp_file = os.path.join(self._tmp_dir, _basename)

        _bad_wolf_fixes = bad_wolf.BAD_WOLF_PKGS.get(_basename, None)
        _bwd = None

        _req = curl_requests.CURL(url=self._plist_url_path)

        # NOTE 2019-11-04: Seems that using the 'resume' capability in cURL does not
        # work here now for some reason, so don't resume.
        if _req.status in config.HTTP_OK_STATUS:
            _req.get(url=self._plist_url_path, output=_tmp_file, resume=False)
        else:
            _req.get(url=self._plist_failover_url_path,
                     output=_tmp_file,
                     resume=False)

        _root = plist.readPlist(_tmp_file)

        if _root:
            result = set()

            # Apply 'Bad Wolf' pathches
            for _pkg in _root['Packages']:
                _new_pkg = _root['Packages'][_pkg].copy()  # Work on copy

                # Create a new key called 'PackageName' that
                # contains the value '_pkg' for use with content packs.
                _new_pkg['PackageName'] = _pkg

                if _bad_wolf_fixes:
                    _bwd = _bad_wolf_fixes.get(
                        _pkg, None)  # A dictionary from '_bad_wolf_fixes'

                # Merge new/existing keys from matching '_bwd'
                if _bwd:
                    _new_pkg.update(_bwd)

                _pkg_obj = package.LoopPackage(**_new_pkg)

                # pylint: disable=no-member
                # Only add/process packages that are _not_ 'BadWolfIgnore = True'
                if not _pkg_obj.BadWolfIgnore:
                    result.add(_pkg_obj)
                # pylint: enable=no-member

            # Now process option packs
            _opt_packs = option_packs.OptionPack(source=_root,
                                                 release=_basename)
            self.option_packs = _opt_packs.option_packs

        misc.clean_up(file_path=_tmp_file)

        return result
Beispiel #3
0
    def _get_app_info(self):
        """Returns the contents of the 'Contents/Info.plist' of the app."""
        result = None
        _info_file_path = os.path.join(self._file_path, config.CONTENTS_PATH, 'Info.plist')

        if os.path.exists(_info_file_path):
            result = plist.readPlist(_info_file_path)

        return result
Beispiel #4
0
 def get_system_info(self):
     self.installed_version = "Not Installed!"
     self.os_build_number = self.r.run(
         {"args": ["sw_vers", "-buildVersion"]})[0].strip()
     self.os_number = self.r.run({"args": ["sw_vers",
                                           "-productVersion"]})[0].strip()
     if self.wd_loc:
         info_plist = plist.readPlist(self.wd_loc + "/Contents/Info.plist")
         self.installed_version = info_plist["CFBundleGetInfoString"].split(
             " ")[-1].replace("(", "").replace(")", "")
Beispiel #5
0
    def patch_menu(self):
        self.u.head("Web Driver Patch")
        print(" ")
        os.chdir(os.path.dirname(os.path.realpath(__file__)))

        if not self.wd_loc:
            print(
                "NVDAStartupWeb.kext was not found in either /L/E or /S/L/E!\n"
            )
            print("Please make sure you have the Web Drivers installed.")
            self.u.grab("", timeout=5)
            return
        info_plist = plist.readPlist(self.wd_loc + "/Contents/Info.plist")
        current_build = info_plist.get("IOKitPersonalities",
                                       {}).get("NVDAStartup",
                                               {}).get("NVDARequiredOS", None)

        print("OS Build Number:  {}".format(self.os_build_number))
        print("WD Target Build:  {}".format(current_build))

        print(" ")
        print("C. Set to Current Build Number")
        print("I. Input New Build Number")
        can_restore = False
        if os.path.exists(self.wd_loc + "/Contents/Info.plist.bak"):
            print("R. Restore Backup")
            print("D. Delete Backup")
            can_restore = True
        print(" ")
        print("M. Main Menu")
        print("Q. Quit")
        print(" ")

        menu = self.grab("Please make a selection:  ")

        if not len(menu):
            self.patch_menu()
            return

        if menu[:1].lower() == "q":
            self.custom_quit()
        elif menu[:1].lower() == "c":
            self.set_build(self.os_build_number)
        elif menu[:1].lower() == "i":
            self.custom_build()
        elif menu[:1].lower() == "r" and can_restore:
            self.restore_backup()
        elif menu[:1].lower() == "d" and can_restore:
            self.delete_backup()
        elif menu[:1].lower() == "m":
            return

        self.patch_menu()
        return
Beispiel #6
0
    def _get_packages(self):
        """Returns a set of all packages (as object instances). Also patches any 'issues'
        that resolve known issues with Apple's audiocontentdownload mirrored files."""
        result = None

        if self.plist_file_path:
            _basename = os.path.basename(self.plist_file_path)

            _bad_wolf_fixes = bad_wolf.BAD_WOLF_PKGS.get(_basename, None)
            _bwd = None

            _root = plist.readPlist(self.plist_file_path)

            if _root:
                result = set()

                # Apply 'Bad Wolf' pathches
                for _pkg in _root['Packages']:
                    _new_pkg = _root['Packages'][_pkg].copy()  # Work on copy

                    # Create a new key called 'PackageName' that
                    # contains the value '_pkg' for use with content packs.
                    _new_pkg['PackageName'] = _pkg

                    if _bad_wolf_fixes:
                        _bwd = _bad_wolf_fixes.get(
                            _pkg, None)  # A dictionary from '_bad_wolf_fixes'

                    # Merge new/existing keys from matching '_bwd'
                    if _bwd:
                        _new_pkg.update(_bwd)

                    _pkg_obj = package.LoopPackage(**_new_pkg)

                    # pylint: disable=no-member
                    # Only add/process packages that are _not_ 'BadWolfIgnore = True'
                    if not _pkg_obj.BadWolfIgnore:
                        result.add(_pkg_obj)
                    # pylint: enable=no-member

                # Now process option packs
                self.option_packs = option_packs.OptionPack(
                    source=_root, release=_basename).option_packs

        return result
Beispiel #7
0
    def custom_build(self):
        self.u.head("Custom Build")
        print(" ")
        print("")

        if not self.wd_loc:
            print(
                "NVDAStartupWeb.kext was not found in either /L/E or /S/L/E!\n"
            )
            print("Please make sure you have the Web Drivers installed.")
            self.u.grab("", timeout=5)
            return
        info_plist = plist.readPlist(self.wd_loc + "/Contents/Info.plist")
        current_build = info_plist.get("IOKitPersonalities",
                                       {}).get("NVDAStartup",
                                               {}).get("NVDARequiredOS", None)

        print("OS Build Number:  {}".format(self.os_build_number))
        print("WD Target Build:  {}".format(current_build))

        print(" ")
        print("P. Patch Menu")
        print(" ")
        print("M. Main Menu")
        print("Q. Quit")
        print(" ")

        menu = self.grab("Please enter a new build number:  ")

        if not len(menu):
            self.custom_build()
            return

        if menu.lower() == "q":
            self.custom_quit()
        elif menu.lower() == "m":
            self.main()
        elif menu.lower() == "p":
            return

        # We have a build number
        self.set_build(menu)
        self.main()
        return
Beispiel #8
0
    def config_menu(self):
        self.u.head("Config.plist Patch Menu")
        print(" ")
        os.chdir(os.path.dirname(os.path.realpath(__file__)))
        if not self.wd_loc:
            print(
                "NVDAStartupWeb.kext was not found in either /L/E or /S/L/E!\n"
            )
            print("Please make sure you have the Web Drivers installed.")
            self.u.grab("", timeout=5)
            return
        info_plist = plist.readPlist(self.wd_loc + "/Contents/Info.plist")
        current_build = info_plist.get("IOKitPersonalities",
                                       {}).get("NVDAStartup",
                                               {}).get("NVDARequiredOS", None)

        print("OS Build Number:  {}".format(self.os_build_number))
        print("WD Target Build:  {}".format(current_build))
        print(" ")
        print("C. Current Build Number")
        print(" ")
        print("M. Main Menu")
        print("Q. Quit")
        print(" ")

        menu = self.grab(
            "Please make a selection (or type a custom build number):  ")

        if not len(menu):
            self.config_menu()
            return

        if menu[:1].lower() == "m":
            return
        elif menu[:1].lower() == "q":
            self.custom_quit()
        elif menu[:1].lower() == "c":
            self.type_menu(self.os_build_number)
        else:
            self.type_menu(menu)
        self.config_menu()
        return
Beispiel #9
0
def differences(file_a, file_b, detailed_info=False):
    """Compares the package details in 'file_a' against 'file_b' to determine
    what files exist in 'file_b' but not in 'file_a'. This will also display
    packages _removed_.
    This function sorts the files into smallest to largest order. So if
    'garageband1021.plist' is compared to 'garageband1011.plist', the
    output will be based on packages that are in 'garageband1021.plist' but
    not in 'garageband1011.plist'. In otherwords, '1021' is the _right_
    file, '1011' is the _left_ file."""
    sorted_files = sorted([f for f in [file_a, file_b]])
    file_a = sorted_files[0]
    base_a = os.path.basename(file_a)
    file_b = sorted_files[1]
    base_b = os.path.basename(file_b)

    _supported = [_v for _v in config.SUPPORTED_PLISTS.values()]
    _supported.sort()

    if not all(_file.endswith('.plist') for _file in [file_a, file_b]):
        print('Files must both be property list files.')
        sys.exit(1)

    if not all(_file in _supported for _file in [base_a, base_b]):
        print('Files must be from {}'.format(_supported))
        sys.exit(1)

    # Sort the two files so if the order of 'file_a' 'file_b' is
    # 'garageband1021.plist' 'garageband1011.plist' it becomes
    # 'garageband1011.plist' 'garageband1021.plist'
    _tmp_dir = os.path.join(tempfile.gettempdir(), config.BUNDLE_ID)

    if not os.path.exists(file_a):
        _fa_fallback = os.path.join(config.AUDIOCONTENT_FAILOVER_URL,
                                    'lp10_ms3_content_2016', base_a)
        _fa_url = misc.plist_url_path(base_a)
        file_a = os.path.join(_tmp_dir, base_a)

        _req = curl_requests.CURL(url=_fa_url)

        if _req.status in config.HTTP_OK_STATUS:
            _req.get(url=_fa_url, output=file_a)
        else:
            _req.get(url=_fa_fallback, output=file_a)

        file_a_plist = plist.readPlist(plist_path=file_a)['Packages']
        misc.clean_up(file_a)
    elif os.path.exists(file_a):
        file_a_plist = plist.readPlist(plist_path=file_a)['Packages']

    if not os.path.exists(file_b):
        _fb_fallback = os.path.join(config.AUDIOCONTENT_FAILOVER_URL,
                                    'lp10_ms3_content_2016', base_b)
        _fb_url = misc.plist_url_path(base_b)
        file_b = os.path.join(_tmp_dir, base_b)

        _req = curl_requests.CURL(url=_fb_url)

        if _req.status in config.HTTP_OK_STATUS:
            _req.get(url=_fb_url, output=file_b)
        else:
            _req.get(url=_fb_fallback, output=file_b)

        file_b_plist = plist.readPlist(plist_path=file_b)['Packages']
        misc.clean_up(file_b)
    elif os.path.exists(file_b):
        file_a_plist = plist.readPlist(plist_path=file_a)['Packages']

    # Build a set of package names.
    file_a_packages = set([
        os.path.basename(file_a_plist[_pkg]['DownloadName'])
        for _pkg in file_a_plist
    ])
    file_b_packages = set([
        os.path.basename(file_b_plist[_pkg]['DownloadName'])
        for _pkg in file_b_plist
    ])

    # Get the new/removed files by using 'set_b.difference(set_a)'
    new_files = file_b_packages.difference(file_a_packages)
    rem_files = file_a_packages.difference(file_b_packages)
    cmn_files = file_b_packages.intersection(file_a_packages)

    if not detailed_info:
        if new_files:
            print('{} new packages in {} when compared to {}'.format(
                len(new_files), base_b, base_a))

        if rem_files:
            print('{} packages removed from {} compared to {}'.format(
                len(rem_files), base_a, base_b))

        if cmn_files:
            print('{} packages common between {} and {}'.format(
                len(cmn_files), base_a, base_b))

    # Exit success because nothing else to do.
    sys.exit(0)
Beispiel #10
0
    def type_menu(self, build):
        self.u.head("Config.plist Patch: {}".format(build))
        print(" ")
        os.chdir(os.path.dirname(os.path.realpath(__file__)))
        if not self.wd_loc:
            print(
                "NVDAStartupWeb.kext was not found in either /L/E or /S/L/E!\n"
            )
            print("Please make sure you have the Web Drivers installed.")
            self.u.grab("", timeout=5)
            return
        info_plist = plist.readPlist(self.wd_loc + "/Contents/Info.plist")
        current_build = info_plist.get("IOKitPersonalities",
                                       {}).get("NVDAStartup",
                                               {}).get("NVDARequiredOS", None)
        if build == current_build:
            print(
                "Both builds are the same - this defeats the purpose of the patch."
            )
            self.u.grab("", timeout=5)
            return
        print("B. Show Base64 Values")
        print("H. Show Hex Values")
        print("P. Show Plist Patch")
        print(" ")
        print("M. Main Menu")
        print("C. Config.plist Patch Menu")
        print("Q. Quit")
        print(" ")
        menu = self.grab("Please make a selection:  ")

        if not len(menu):
            self.config_menu()
            return

        display_text = data_type = ""

        if menu[:1].lower() == "m":
            self.main()
            return
        elif menu[:1].lower() == "q":
            self.custom_quit()
        elif menu[:1].lower() == "b":
            data_type = "Base64"
            display_text += "Name:      NVDAStartupWeb\n"
            display_text += "Disabled:  False\n"
            display_text += "Find:      {}\n".format(
                self.get_base(current_build))
            display_text += "Replace:   {}\n".format(self.get_base(build))
            display_text += "InfoPlist: True"
        elif menu[:1].lower() == "h":
            data_type = "Hex"
            display_text += "Name:      NVDAStartupWeb\n"
            display_text += "Disabled:  False\n"
            display_text += "Find:      {}\n".format(
                self.get_hex(current_build))
            display_text += "Replace:   {}\n".format(self.get_hex(build))
            display_text += "InfoPlist: True"
        elif menu[:1].lower() == "p":
            # Get some plist wizardry
            data_type = "Plist"
            plist_dict = {
                "Name": "NVDAStartupWeb",
                "Comment": "Nvidia {} to {}".format(current_build, build),
                "InfoPlistPatch": True,
                "Disabled": False,
                "Find": self.get_base(current_build),
                "Replace": self.get_base(build)
            }
            plist_string = plist.dumps(plist_dict).decode("utf-8")
            # Trim the plist
            display_text = "\n".join(plist_string.split("\n")[3:-2])

        if len(display_text):
            self.u.head("Config.plist Patch: {}".format(build))
            print(" ")
            print("Your {} Data:\n".format(data_type))
            print(display_text)
            print(" ")
            self.grab("Press [enter] to return...")
        self.type_menu(build)
        return
Beispiel #11
0
    def patch_pkg(self, package, temp, build=None):
        self.u.head("Patching Install Package")
        print(" ")
        script_path = os.path.dirname(os.path.realpath(__file__))
        print("Expanding package...\n")
        stat = self.r.run(
            {"args": ["pkgutil", "--expand", package, temp + "/package"]})
        if not stat[2] == 0:
            print("Something went wrong!\n")
            print(stat[1])
            return
        new_dist = ""
        print("Patching Distribution...\n")
        with open(temp + "/package/Distribution") as f:
            for line in f:
                if "if (!validatesoftware())" in line.lower():
                    continue
                if "if (!validatehardware())" in line.lower():
                    continue
                if "return false;" in line:
                    line = line.replace("return false;", "return true;")
                new_dist += line
        with open(temp + "/package/Distribution", "w") as f:
            f.write(new_dist)

        if build:
            # We have a build - let's do stuff
            print("Patching Kext for {}...".format(build))
            os.chdir(temp + "/package")
            os.chdir(
                self.r.run({
                    "args": "ls | grep -i nvwebdrivers",
                    "shell": True
                })[0].strip())
            self.r.run({"args": ["mkdir", "temp"]})
            os.chdir("temp")
            print("    Extracting Payload...")
            self.r.run({"args": ["tar", "xvf", "../Payload"]})
            info_path = None
            if os.path.exists("./NVDAStartupWeb.kext/Contents/Info.plist"):
                info_path = "./NVDAStartupWeb.kext/Contents/Info.plist"
            elif os.path.exists(
                    "./Library/Extensions/NVDAStartupWeb.kext/Contents/Info.plist"
            ):
                info_path = "./Library/Extensions/NVDAStartupWeb.kext/Contents/Info.plist"
            elif os.path.exists("./NVDAStartup.kext/Contents/Info.plist"):
                # Old stuff...
                info_path = "./NVDAStartup.kext/Contents/Info.plist"
            if not info_path:
                print("Couldn't find Info.plist to patch!")
                return
            print("    Patching Info.plist for {}...".format(build))
            # Got the info.plist - load it and patch it
            info_plist = plist.readPlist(os.path.realpath(info_path))
            info_plist["IOKitPersonalities"]["NVDAStartup"][
                "NVDARequiredOS"] = build
            # Write the changes
            plist.writePlist(info_plist, os.path.realpath(info_path))
            # Remove the old Payload and BOM
            print("    Removing old Payload and BOM...")
            self.r.run({"args": ["rm", "../Payload"]})
            self.r.run({"args": ["rm", "../BOM"]})
            # Repacking Payload
            print("    Setting ownership...")
            stat = self.r.run({"args": "sudo chown -R 0:0 ./*", "shell": True})
            if not stat[2] == 0:
                print("Something went wrong!\n")
                print(stat[1])
                return
            print("    Repacking Payload...")
            stat = self.r.run({
                "args":
                "sudo find . | sudo cpio -o --format odc | gzip -c > ../Payload",
                "shell": True
            })
            if not stat[2] == 0:
                print("Something went wrong!\n")
                print(stat[1])
                return
            # Generate BOM
            print("    Generating BOM...")
            stat = self.r.run({
                "args": ["mkbom", "../../", "../BOM"],
                "sudo": True
            })
            if not stat[2] == 0:
                print("Something went wrong!\n")
                print(stat[1])
                return
            # Clean up the temp folder
            print("    Cleaning up...\n")
            os.chdir("../")
            stat = self.r.run({"args": ["rm", "-rf", "temp"], "sudo": True})
            if not stat[2] == 0:
                print("Something went wrong!\n")
                print(stat[1])
                return

        self.check_dir("Patched")
        print("Repacking...\n")
        os.chdir(os.path.dirname(os.path.realpath(__file__)))
        os.chdir("../Web Drivers/Patched/")
        suffix = " (Patched).pkg" if build == None else " ({}).pkg".format(
            build)
        self.r.run({
            "args": [
                "pkgutil", "--flatten", temp + "/package",
                os.getcwd() + "/" + os.path.basename(package)[:-4] + suffix
            ]
        })
        print("Done.")
        self.r.run({"args": ["open", os.getcwd()]})
        self.u.grab("", timeout=5)
Beispiel #12
0
    def set_build(self, build_number):
        if not self.sip_checked:
            res = self.check_sip()
            if res == None or res == True:
                # Likely on Yosemite?
                self.sip_checked = True
            else:
                return

        self.u.head("Setting NVDARequiredOS to {}".format(build_number))
        print(" ")
        os.chdir(os.path.dirname(os.path.realpath(__file__)))

        # Start our command list
        c = []

        info_plist = plist.readPlist(self.wd_loc + "/Contents/Info.plist")
        if not os.path.exists(self.wd_loc + "/Contents/Info.plist.bak"):
            # Create a backup
            self.r.run({
                "args": [
                    "cp", self.wd_loc + "/Contents/Info.plist",
                    self.wd_loc + "/Contents/Info.plist.bak"
                ],
                "sudo":
                True,
                "message":
                "Creating backup...\n"
            })
            # plist.writePlist(info_plist, self.wd_loc + "/Contents/Info.plist.bak")
        # Change the build number and write to the main plist
        print("Patching plist for build \"{}\"...\n".format(build_number))
        info_plist["IOKitPersonalities"]["NVDAStartup"][
            "NVDARequiredOS"] = build_number
        # Make a temp folder for our plist
        temp_folder = tempfile.mkdtemp()
        # Write the changes
        plist.writePlist(info_plist, temp_folder + "/Info.plist")
        # Build and run commands
        c = [{
            "args": [
                "mv", "-f", temp_folder + "/Info.plist",
                self.wd_loc + "/Contents/Info.plist"
            ],
            "sudo":
            True
        }, {
            "args": ["chown", "0:0", self.wd_loc + "/Contents/Info.plist"],
            "sudo": True,
            "message": "Updating ownership and permissions...\n"
        }, {
            "args": ["chmod", "755", self.wd_loc + "/Contents/Info.plist"],
            "sudo": True
        }, {
            "args": ["kextcache", "-i", "/"],
            "sudo": True,
            "stream": True,
            "message": "Rebuilding kext cache...\n"
        }, {
            "args": ["kextcache", "-u", "/"],
            "sudo": True,
            "stream": True,
        }]
        self.r.run(c, True)
        # Remove temp
        if os.path.exists(temp_folder):
            shutil.rmtree(temp_folder)
        print(" ")
        print("Done.")
        self.u.grab("", timeout=5)
        return
Beispiel #13
0
    def main(self):
        self._check_info()
        self.get_system_info()
        self.u.head("Web Driver Toolkit")
        print(" ")
        os.chdir(os.path.dirname(os.path.realpath(__file__)))

        print("OS Version:       {} - {}".format(self.os_number,
                                                 self.os_build_number))
        print("WD Version:       " + self.installed_version)

        if self.wd_loc:
            info_plist = plist.readPlist(self.wd_loc + "/Contents/Info.plist")
            current_build = info_plist.get("IOKitPersonalities", {}).get(
                "NVDAStartup", {}).get("NVDARequiredOS", None)
            print("WD Target Build:  {}".format(current_build))

        if not "updates" in self.web_drivers:
            newest_version = "Manifest not available!"
        else:
            newest_version = "None for this build number!"
        for update in self.web_drivers.get("updates", []):
            if update["OS"].lower() == self.os_build_number.lower():
                newest_version = update["version"]
                break

        if self.installed_version.lower() == newest_version.lower():
            print("Newest:           " + newest_version + " (Current)")
        else:
            print("Newest:           " + newest_version)

        try:
            nv = self.r.run({
                "args": "nvram -p | grep -i nvda_drv | cut -d$'\t' -f 2",
                "shell": True
            })[0].strip("\n")
        except:
            nv = ""
        aptio_loaded = "Unknown"
        aptio = next((x for x in bdmesg.bdmesg().split("\n")
                      if "aptiomemoryfix" in x.lower()), None)
        if aptio:
            aptio_loaded = "Loaded" if "success" in aptio.lower(
            ) else "Not Loaded"

        if nv in ["1", "1%00"]:
            print("Status:           Enabled (AptioMemoryFix {})".format(
                aptio_loaded))
        else:
            print(
                "Status:           Disabled - or Unknown (AptioMemoryFix {})".
                format(aptio_loaded))

        print(" ")
        patch = False
        if self.wd_loc:
            print("P. Patch Menu")
            patch = True
        print("I. Patch Install Package")
        print("D. Download For Current")
        print("B. Download By Build Number")
        print("S. Search By Build/OS Number")
        print("R. Remove Web Drivers")
        print("U. Update Manifest")
        print("C. Config.plist Patch Menu")
        print("F. Flush Kext Cache")
        print("N. Attempt to {} nvram_drv=1 in NVRAM".format(
            "unset" if nv in ["1", "1%00"] else "set"))
        print("")
        print("Q. Quit")
        print(" ")

        menu = self.grab(
            "Please make a selection (just press enter to reload):  ")

        if not len(menu):
            return

        if menu[:1].lower() == "q":
            self.custom_quit()
        elif menu[:1].lower() == "p" and patch:
            self.patch_menu()
        elif menu[:1].lower() == "d":
            self.download_for_build(self.os_build_number)
        elif menu[:1].lower() == "b":
            self.build_list()
        elif menu[:1].lower() == "s":
            self.build_search()
        elif menu[:1].lower() == "i":
            self.patch_installer_build()
        elif menu[:1].lower() == "u":
            self.get_manifest()
        elif menu[:1].lower() == "r":
            self.remove_drivers()
        elif menu[:1].lower() == "c":
            self.config_menu()
        elif menu[:1].lower() == "f":
            self.flush_cache(True)
        elif menu[:1].lower() == "n":
            if nv in ["1", "1%00"]:
                # Unset
                self.u.head("Unsetting nvda_drv=1")
                print("")
                print("Running:\n\nsudo nvram -d nvda_drv")
                self.r.run({
                    "args": ["sudo", "nvram", "-d", "nvda_drv"],
                    "stream": True
                })
            else:
                # Set
                self.u.head("Setting nvda_drv=1")
                print("")
                print("Running:\n\nsudo nvram nvda_drv=1")
                self.r.run({
                    "args": ["sudo", "nvram", "nvda_drv=1"],
                    "stream": True
                })
            print("")
            print("Done.")
            self.u.grab("", timeout=5)

        return