From 5589dba07a164517cc458473d08ec02fb37e799c Mon Sep 17 00:00:00 2001 From: Stan Grishin Date: Fri, 15 Nov 2019 16:41:58 -0700 Subject: [PATCH] luci-app-advanced-reboot: show OpenWrt info on compatible NAND routers Signed-off-by: Stan Grishin --- .../luci-app-advanced-reboot/Makefile | 6 +- .../luci-app-advanced-reboot/README.md | 4 +- .../luasrc/controller/advanced_reboot.lua | 441 +++++++++++------- .../view/advanced_reboot/advanced_reboot.htm | 128 ++--- .../advanced_reboot/alternative_reboot.htm | 8 +- .../etc/uci-defaults/40_luci-advanced-reboot | 5 + 6 files changed, 338 insertions(+), 254 deletions(-) create mode 100644 applications/luci-app-advanced-reboot/root/etc/uci-defaults/40_luci-advanced-reboot diff --git a/applications/luci-app-advanced-reboot/Makefile b/applications/luci-app-advanced-reboot/Makefile index 329acece4..a08d57fd8 100644 --- a/applications/luci-app-advanced-reboot/Makefile +++ b/applications/luci-app-advanced-reboot/Makefile @@ -3,7 +3,7 @@ include $(TOPDIR)/rules.mk -PKG_LICENSE:=GPL-3.0+ +PKG_LICENSE:=GPL-3.0-or-later PKG_MAINTAINER:=Stan Grishin LUCI_TITLE:=Advanced Linksys Reboot Web UI @@ -11,9 +11,9 @@ LUCI_DESCRIPTION:=Provides Web UI (found under System/Advanced Reboot) to reboot an alternative partition. Also provides Web UI to shut down (power off) your device. Supported dual-partition\ routers are listed at https://github.com/openwrt/luci/blob/master/applications/luci-app-advanced-reboot/README.md -LUCI_DEPENDS:=+luci-mod-admin-full +LUCI_DEPENDS:=+luci-compat +luci-mod-admin-full LUCI_PKGARCH:=all -PKG_RELEASE:=42 +PKG_RELEASE:=43 include ../../luci.mk diff --git a/applications/luci-app-advanced-reboot/README.md b/applications/luci-app-advanced-reboot/README.md index 61e43637d..50ca1bc2d 100644 --- a/applications/luci-app-advanced-reboot/README.md +++ b/applications/luci-app-advanced-reboot/README.md @@ -22,11 +22,11 @@ Currently supported dual-partition devices include: - Linksys WRT32X - ZyXEL NBG6817 -If you're interested in having your device supported, please post in [OpenWrt Forum Support Thread](https://forum.openwrt.org/t/web-ui-to-reboot-to-another-partition-dual-partition-routers/3423). +If your device is not in the list above, however it is a [dual-firmware device](https://openwrt.org/tag/dual_firmware?do=showtag&tag=dual_firmware) and you're interested in having your device supported, please post in [OpenWrt Forum Support Thread](https://forum.openwrt.org/t/web-ui-to-reboot-to-another-partition-dual-partition-routers/3423). ## Screenshot (luci-app-advanced-reboot) -![screenshot](https://raw.githubusercontent.com/stangri/openwrt_packages/master/screenshots/luci-app-advanced-reboot/screenshot01.png "screenshot") +![screenshot](https://raw.githubusercontent.com/stangri/openwrt_packages/master/screenshots/luci-app-advanced-reboot/screenshot02.png "screenshot") ## How to install diff --git a/applications/luci-app-advanced-reboot/luasrc/controller/advanced_reboot.lua b/applications/luci-app-advanced-reboot/luasrc/controller/advanced_reboot.lua index 6b8cba4c4..8b97f2e56 100644 --- a/applications/luci-app-advanced-reboot/luasrc/controller/advanced_reboot.lua +++ b/applications/luci-app-advanced-reboot/luasrc/controller/advanced_reboot.lua @@ -3,203 +3,282 @@ module("luci.controller.advanced_reboot", package.seeall) +local util = require "luci.util" +local fs = require "nixio.fs" +local sys = require "luci.sys" +local http = require "luci.http" +local dispatcher = require "luci.dispatcher" +local i18n = require "luci.i18n" +local ltemplate = require "luci.template" +local ip = require "luci.ip" +local http = require "luci.http" +local sys = require "luci.sys" +local dispatcher = require "luci.dispatcher" +local uci = require "luci.model.uci".cursor() + +function is_alt_mountable(p1_mtd, p2_mtd) + if p1_mtd:sub(1,3) == "mtd" and + p2_mtd:sub(1,3) == "mtd" and + fs.access("/usr/sbin/ubiattach") and + fs.access("/usr/sbin/ubiblock") and + fs.access("/bin/mount") then + return true + else + return false + end +end + +function get_partition_os_info(op_ubi) + local cp_info, ap_info + if fs.access("/etc/os-release") then + cp_info = util.trim(util.exec('. /etc/os-release && echo "$PRETTY_NAME"')) + end + alt_partition_unmount(op_ubi) + alt_partition_mount(op_ubi) + if fs.access("/alt/rom/etc/os-release") then + ap_info = util.trim(util.exec('. /alt/rom/etc/os-release && echo "$PRETTY_NAME"')) + end + alt_partition_unmount(op_ubi) + return cp_info, ap_info +end + +function alt_partition_mount(op_ubi) + local ubi_dev + util.exec('for i in rom overlay firmware; do [ ! -d "$i" ] && mkdir -p "/alt/${i}"; done') + util.exec("ubidetach -m " .. tostring(op_ubi)) + ubi_dev = tostring(util.exec("ubiattach -m " .. tostring(op_ubi))) + _, _, ubi_dev = ubi_dev:find("UBI device number (%d+)") + if not ubi_dev then + util.exec("ubidetach -m " .. tostring(op_ubi)) + return + end + util.exec("ubiblock --create /dev/ubi" .. ubi_dev .. "_0") + util.exec("mount -t squashfs -o ro /dev/ubiblock" .. ubi_dev .. "_0 /alt/rom") + util.exec("mount -t ubifs /dev/ubi1_" .. ubi_dev .. " /alt/overlay") + util.exec("mount -t overlay overlay -o noatime,lowerdir=/alt/rom,upperdir=/alt/overlay/upper,workdir=/alt/overlay/work /alt/firmware") +end + +function alt_partition_unmount(op_ubi) + util.exec("umount /alt/firmware") + util.exec("umount /alt/overlay") + util.exec("umount /alt/rom") + util.exec("ubiblock --remove /dev/ubi1_0") + util.exec("ubidetach -m " .. tostring(op_ubi)) + util.exec('rm -rf /alt') +end + devices = { - -- deviceName, boardName, partition1, partition2, offset, envVar1, envVar1Value1, envVar1Value2, envVar2, envVar2Value1, envVar2Value2 - {"Linksys EA3500", "linksys-audi", "mtd3", "mtd5", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, - {"Linksys E4200v2/EA4500", "linksys-viper", "mtd3", "mtd5", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, - {"Linksys EA6350v3", "linksys-ea6350v3", "mtd10", "mtd12", 192, "boot_part", 1, 2}, - {"Linksys EA8300", "linksys-ea8300", "mtd10", "mtd12", 192, "boot_part", 1, 2}, - {"Linksys EA8500", "ea8500", "mtd13", "mtd15", 32, "boot_part", 1, 2}, + -- deviceName, boardName, part1MTD, part2MTD, offset, envVar1, envVar1Value1, envVar1Value2, envVar2, envVar2Value1, envVar2Value2 + {"Linksys EA3500", "linksys-audi", "mtd3", "mtd5", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, + {"Linksys E4200v2/EA4500", "linksys-viper", "mtd3", "mtd5", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, + {"Linksys EA6350v3", "linksys-ea6350v3", "mtd10", "mtd12", 192, "boot_part", 1, 2}, + {"Linksys EA8300", "linksys-ea8300", "mtd10", "mtd12", 192, "boot_part", 1, 2}, + {"Linksys EA8500", "ea8500", "mtd13", "mtd15", 32, "boot_part", 1, 2}, -- {"Linksys EA9500", "linksys-panamera", "mtd3", "mtd6", 28, "boot_part", 1, 2}, - {"Linksys WRT1200AC", "linksys-caiman", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, - {"Linksys WRT1900AC", "linksys-mamba", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, - {"Linksys WRT1900ACv2", "linksys-cobra", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, - {"Linksys WRT1900ACS", "linksys-shelby", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, - {"Linksys WRT3200ACM", "linksys-rango", "mtd5", "mtd7", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, - {"Linksys WRT32X", "linksys-venom", "mtd5", "mtd7", nil, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, - {"ZyXEL NBG6817","nbg6817","mmcblk0p4","mmcblk0p7", 32, nil, 255, 1} + {"Linksys WRT1200AC", "linksys-caiman", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, + {"Linksys WRT1900AC", "linksys-mamba", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, + {"Linksys WRT1900ACv2", "linksys-cobra", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, + {"Linksys WRT1900ACS", "linksys-shelby", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, + {"Linksys WRT3200ACM", "linksys-rango", "mtd5", "mtd7", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, + {"Linksys WRT32X", "linksys-venom", "mtd5", "mtd7", nil, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, + {"ZyXEL NBG6817", "nbg6817", "mmcblk0p4", "mmcblk0p7", 32, nil, 255, 1} } -errorMessage = nil -rom_board_name = luci.util.trim(luci.sys.exec("cat /tmp/sysinfo/board_name")) +-- local errorMessage, d +-- local device_name, p1_mtd, p2_mtd, offset, bev1, bev1p1, bev1p2, bev2, bev2p1, bev2p2 +romBoardName = util.trim(util.exec("cat /tmp/sysinfo/board_name")) + for i=1, #devices do - device_board_name = devices[i][2]:gsub('%p','') - if rom_board_name and rom_board_name:gsub('%p',''):match(device_board_name) then - device_name = devices[i][1] - partition_one_mtd = devices[i][3] or nil - partition_two_mtd = devices[i][4] or nil - partition_skip = devices[i][5] or nil - boot_envvar1 = devices[i][6] or nil - boot_envvar1_partition_one = tonumber(devices[i][7]) or nil - boot_envvar1_partition_two = tonumber(devices[i][8]) or nil - boot_envvar2 = devices[i][9] or nil - boot_envvar2_partition_one = devices[i][10] or nil - boot_envvar2_partition_two = devices[i][11] or nil - if partition_one_mtd and partition_skip then - partition_one_label = luci.util.trim(luci.sys.exec("dd if=/dev/" .. partition_one_mtd .. " bs=1 skip=" .. partition_skip .. " count=128" .. " 2>/dev/null")) - n, partition_one_version = string.match(partition_one_label, '(Linux)-([%d|.]+)') - end - if partition_two_mtd and partition_skip then - partition_two_label = luci.util.trim(luci.sys.exec("dd if=/dev/" .. partition_two_mtd .. " bs=1 skip=" .. partition_skip .. " count=128" .. " 2>/dev/null")) - n, partition_two_version = string.match(partition_two_label, '(Linux)-([%d|.]+)') - end - if partition_one_label and string.find(partition_one_label, "LEDE") then partition_one_os = "LEDE" end - if partition_one_label and string.find(partition_one_label, "OpenWrt") then partition_one_os = "OpenWrt" end - if partition_one_label and string.find(partition_one_label, "Linksys") then partition_one_os = "Linksys" end - if partition_two_label and string.find(partition_two_label, "LEDE") then partition_two_os = "LEDE" end - if partition_two_label and string.find(partition_two_label, "OpenWrt") then partition_two_os = "OpenWrt" end - if partition_two_label and string.find(partition_two_label, "Linksys") then partition_two_os = "Linksys" end - if device_name and device_name == "ZyXEL NBG6817" then - if not partition_one_os then partition_one_os = "ZyXEL" end - if not partition_two_os then partition_two_os = "ZyXEL" end - end - if device_name and device_name == "Linksys WRT32X" then - if not partition_one_os then partition_one_os = "Unknown/Compressed" end - if not partition_two_os then partition_two_os = "Unknown/Compressed" end - end - if not partition_one_os then partition_one_os = "Unknown" end - if not partition_two_os then partition_two_os = "Unknown" end - if partition_one_os and partition_one_version then partition_one_os = partition_one_os .. " (Linux " .. partition_one_version .. ")" end - if partition_two_os and partition_two_version then partition_two_os = partition_two_os .. " (Linux " .. partition_two_version .. ")" end + d = devices[i][2]:gsub('%p','') + if romBoardName and romBoardName:gsub('%p',''):match(d) then + device_name = devices[i][1] + p1_mtd = devices[i][3] or nil + p2_mtd = devices[i][4] or nil + offset = devices[i][5] or nil + bev1 = devices[i][6] or nil + bev1p1 = tonumber(devices[i][7]) or nil + bev1p2 = tonumber(devices[i][8]) or nil + bev2 = devices[i][9] or nil + bev2p1 = devices[i][10] or nil + bev2p2 = devices[i][11] or nil + if p1_mtd and offset then + p1_label = util.trim(util.exec("dd if=/dev/" .. p1_mtd .. " bs=1 skip=" .. offset .. " count=128" .. " 2>/dev/null")) + n, p1_version = p1_label:match('(Linux)-([%d|.]+)') + end + if p2_mtd and offset then + p2_label = util.trim(util.exec("dd if=/dev/" .. p2_mtd .. " bs=1 skip=" .. offset .. " count=128" .. " 2>/dev/null")) + n, p2_version = p2_label:match('(Linux)-([%d|.]+)') + end + if p1_label and p1_label:find("LEDE") then p1_os = "LEDE" end + if p1_label and p1_label:find("OpenWrt") then p1_os = "OpenWrt" end + if p1_label and p1_label:find("Linksys") then p1_os = "Linksys" end + if p2_label and p2_label:find("LEDE") then p2_os = "LEDE" end + if p2_label and p2_label:find("OpenWrt") then p2_os = "OpenWrt" end + if p2_label and p2_label:find("Linksys") then p2_os = "Linksys" end + if device_name == "ZyXEL NBG6817" then + if not p1_os then p1_os = "ZyXEL" end + if not p2_os then p2_os = "ZyXEL" end + end + if device_name == "Linksys WRT32X" then + if not p1_os then p1_os = "Unknown/Compressed" end + if not p2_os then p2_os = "Unknown/Compressed" end + end + if not p1_os then p1_os = "Unknown" end + if not p2_os then p2_os = "Unknown" end + if p1_os and p1_version then p1_os = p1_os .. " (Linux " .. p1_version .. ")" end + if p2_os and p2_version then p2_os = p2_os .. " (Linux " .. p2_version .. ")" end - if device_name and device_name == "ZyXEL NBG6817" then - if not zyxelFlagPartition then zyxelFlagPartition = luci.util.trim(luci.sys.exec("source /lib/functions.sh; find_mtd_part 0:DUAL_FLAG")) end - if not zyxelFlagPartition then - errorMessage = errorMessage or "" .. luci.i18n.translate("Unable to find Dual Boot Flag Partition." .. " ") - luci.util.perror(luci.i18n.translate("Unable to find Dual Boot Flag Partition.")) - else - current_partition = tonumber(luci.sys.exec("dd if=" .. zyxelFlagPartition .. " bs=1 count=1 2>/dev/null | hexdump -n 1 -e '1/1 \"%d\"'")) - end - else - if nixio.fs.access("/usr/sbin/fw_printenv") and nixio.fs.access("/usr/sbin/fw_setenv") then - current_partition = tonumber(luci.util.trim(luci.sys.exec("/usr/sbin/fw_printenv -n " .. boot_envvar1))) - end - end - other_partition = current_partition == boot_envvar1_partition_two and boot_envvar1_partition_one or boot_envvar1_partition_two - end + if device_name == "ZyXEL NBG6817" then + if not zyxelFlagPartition then zyxelFlagPartition = util.trim(util.exec(". /lib/functions.sh; find_mtd_part 0:DUAL_FLAG")) end + if not zyxelFlagPartition then + errorMessage = errorMessage or "" .. i18n.translate("Unable to find Dual Boot Flag Partition." .. " ") + util.perror(i18n.translate("Unable to find Dual Boot Flag Partition.")) + else + current_partition = tonumber(util.exec("dd if=" .. zyxelFlagPartition .. " bs=1 count=1 2>/dev/null | hexdump -n 1 -e '1/1 \"%d\"'")) + end + else + if fs.access("/usr/sbin/fw_printenv") and fs.access("/usr/sbin/fw_setenv") then + current_partition = tonumber(util.trim(util.exec("fw_printenv -n " .. bev1))) + end + end + other_partition = current_partition == bev1p2 and bev1p1 or bev1p2 + + if is_alt_mountable(p1_mtd, p2_mtd) then + if current_partition == bev1p1 then + op_ubi = tonumber(p2_mtd:sub(4)) + 1 + else + op_ubi = tonumber(p1_mtd:sub(4)) + 1 + end + local cp_info, ap_info = get_partition_os_info(op_ubi) + if current_partition == bev1p1 then + p1_os = cp_info or p1_os + p2_os = ap_info or p2_os + else + p1_os = ap_info or p1_os + p2_os = cp_info or p2_os + end + end + end end function index() - entry({"admin", "system", "advanced_reboot"}, template("advanced_reboot/advanced_reboot"), _("Advanced Reboot"), 90) - entry({"admin", "system", "advanced_reboot", "reboot"}, post("action_reboot")) - entry({"admin", "system", "advanced_reboot", "alternative_reboot"}, post("action_altreboot")) - entry({"admin", "system", "advanced_reboot", "power_off"}, post("action_poweroff")) + entry({"admin", "system", "advanced_reboot"}, template("advanced_reboot/advanced_reboot"), _("Advanced Reboot"), 90) + entry({"admin", "system", "advanced_reboot", "reboot"}, post("action_reboot")) + entry({"admin", "system", "advanced_reboot", "alternative_reboot"}, post("action_altreboot")) + entry({"admin", "system", "advanced_reboot", "power_off"}, post("action_poweroff")) end function action_reboot() - local uci = require "luci.model.uci".cursor() - local ip = uci:get("network", "lan", "ipaddr") - luci.template.render("advanced_reboot/applyreboot", { - title = luci.i18n.translate("Rebooting..."), - msg = luci.i18n.translate("The system is rebooting now.
DO NOT POWER OFF THE DEVICE!
Wait a few minutes before you try to reconnect. It might be necessary to renew the address of your computer to reach the device again, depending on your settings."), - addr = luci.ip.new(type(ip) == "string" and ip or "192.168.1.1") or "192.168.1.1" - }) - luci.sys.reboot() + ltemplate.render("admin_system/applyreboot", { + title = i18n.translate("Rebooting..."), + msg = i18n.translate("The system is rebooting now.
DO NOT POWER OFF THE DEVICE!
Wait a few minutes before you try to reconnect. It might be necessary to renew the address of your computer to reach the device again, depending on your settings."), + addr = ip.new(type(ip) == "string" and ip or "192.168.1.1") or "192.168.1.1" + }) + sys.reboot() end function action_altreboot() - local uci = require "luci.model.uci".cursor() - local zyxelFlagPartition, zyxelBootFlag, zyxelNewBootFlag, errorCode, curEnvSetting, newEnvSetting - errorMessage = nil - errorCode = 0 - if luci.http.formvalue("cancel") then - luci.http.redirect(luci.dispatcher.build_url('admin/system/advanced_reboot')) - return - end - local step = tonumber(luci.http.formvalue("step") or 1) - if step == 1 then - if device_name and nixio.fs.access("/usr/sbin/fw_printenv") and nixio.fs.access("/usr/sbin/fw_setenv") then - luci.template.render("advanced_reboot/alternative_reboot",{}) - else - luci.template.render("advanced_reboot/advanced_reboot",{errorMessage = luci.i18n.translate("No access to fw_printenv or fw_printenv!")}) - end - elseif step == 2 then - if boot_envvar1 or boot_envvar2 then -- Linksys devices - if boot_envvar1 then - curEnvSetting = tonumber(luci.util.trim(luci.sys.exec("/usr/sbin/fw_printenv -n " .. boot_envvar1))) - if not curEnvSetting then - errorMessage = errorMessage .. luci.i18n.translate("Unable to obtain firmware environment variable") .. ": " .. boot_envvar1 .. ". " - luci.util.perror(luci.i18n.translate("Unable to obtain firmware environment variable") .. ": " .. boot_envvar1 .. ".") - else - newEnvSetting = curEnvSetting == boot_envvar1_partition_one and boot_envvar1_partition_two or boot_envvar1_partition_one - errorCode = luci.sys.call("/usr/sbin/fw_setenv " .. boot_envvar1 .. " " .. newEnvSetting) - if errorCode ~= 0 then - errorMessage = errorMessage or "" .. luci.i18n.translate("Unable to set firmware environment variable") .. ": " .. boot_envvar1 .. " " .. luci.i18n.translate("to") .. " " .. newEnvSetting .. ". " - luci.util.perror(luci.i18n.translate("Unable to set firmware environment variable") .. ": " .. boot_envvar1 .. " " .. luci.i18n.translate("to") .. " " .. newEnvSetting .. ".") - end - end - end - if boot_envvar2 then - curEnvSetting = luci.util.trim(luci.sys.exec("/usr/sbin/fw_printenv -n " .. boot_envvar2)) - if not curEnvSetting then - errorMessage = errorMessage or "" .. luci.i18n.translate("Unable to obtain firmware environment variable") .. ": " .. boot_envvar2 .. ". " - luci.util.perror(luci.i18n.translate("Unable to obtain firmware environment variable") .. ": " .. boot_envvar2 .. ".") - else - newEnvSetting = curEnvSetting == boot_envvar2_partition_one and boot_envvar2_partition_two or boot_envvar2_partition_one - errorCode = luci.sys.call("/usr/sbin/fw_setenv " .. boot_envvar2 .. " '" .. newEnvSetting .. "'") - if errorCode ~= 0 then - errorMessage = errorMessage or "" .. luci.i18n.translate("Unable to set firmware environment variable") .. ": " .. boot_envvar2 .. " " .. luci.i18n.translate("to") .. " " .. newEnvSetting .. ". " - luci.util.perror(luci.i18n.translate("Unable to set firmware environment variable") .. ": " .. boot_envvar2 .. " " .. luci.i18n.translate("to") .. " " .. newEnvSetting .. ".") - end - end - end - else -- NetGear device - if not zyxelFlagPartition then zyxelFlagPartition = luci.util.trim(luci.sys.exec("source /lib/functions.sh; find_mtd_part 0:DUAL_FLAG")) end - if not zyxelFlagPartition then - errorMessage = errorMessage .. luci.i18n.translate("Unable to find Dual Boot Flag Partition." .. " ") - luci.util.perror(luci.i18n.translate("Unable to find Dual Boot Flag Partition.")) - else - zyxelBootFlag = tonumber(luci.sys.exec("dd if=" .. zyxelFlagPartition .. " bs=1 count=1 2>/dev/null | hexdump -n 1 -e '1/1 \"%d\"'")) - zyxelNewBootFlag = zyxelBootFlag and zyxelBootFlag == 1 and "\\xff" or "\\x01" - if zyxelNewBootFlag then - errorCode = luci.sys.call("printf \"" .. zyxelNewBootFlag .. "\" >" .. zyxelFlagPartition ) - if errorCode ~= 0 then - errorMessage = errorMessage or "" .. luci.i18n.translate("Unable to set Dual Boot Flag Partition entry for partition") .. ": " .. zyxelFlagPartition .. ". " - luci.util.perror(luci.i18n.translate("Unable to set Dual Boot Flag Partition entry for partition") .. ": " .. zyxelFlagPartition .. ".") - end - end - end - end - if not errorMessage then - luci.template.render("advanced_reboot/applyreboot", { - title = luci.i18n.translate("Rebooting..."), - msg = luci.i18n.translate("The system is rebooting to an alternative partition now.
DO NOT POWER OFF THE DEVICE!
Wait a few minutes before you try to reconnect. It might be necessary to renew the address of your computer to reach the device again, depending on your settings."), - addr = luci.ip.new(uci:get("network", "lan", "ipaddr")) or "192.168.1.1" - }) - luci.sys.reboot() - else - luci.template.render("advanced_reboot/advanced_reboot",{ - rom_board_name=rom_board_name, - device_name=device_name, - boot_envvar1_partition_one=boot_envvar1_partition_one, - partition_one_os=partition_one_os, - boot_envvar1_partition_two=boot_envvar1_partition_two, - partition_two_os=partition_two_os, - current_partition=current_partition, - errorMessage = errorMessage}) - end - end + local zyxelFlagPartition, zyxelBootFlag, zyxelNewBootFlag, errorCode, curEnvSetting, newEnvSetting + errorMessage = nil + errorCode = 0 + if http.formvalue("cancel") then + http.redirect(dispatcher.build_url('admin/system/advanced_reboot')) + return + end + local step = tonumber(http.formvalue("step") or 1) + if step == 1 then + if fs.access("/usr/sbin/fw_printenv") and fs.access("/usr/sbin/fw_setenv") then + ltemplate.render("advanced_reboot/alternative_reboot",{}) + else + ltemplate.render("advanced_reboot/advanced_reboot",{errorMessage = i18n.translate("No access to fw_printenv or fw_printenv!")}) + end + elseif step == 2 then + if bev1 or bev2 then -- Linksys devices + if bev1 then + curEnvSetting = tonumber(util.trim(util.exec("fw_printenv -n " .. bev1))) + if not curEnvSetting then + errorMessage = errorMessage .. i18n.translate("Unable to obtain firmware environment variable") .. ": " .. bev1 .. ". " + util.perror(i18n.translate("Unable to obtain firmware environment variable") .. ": " .. bev1 .. ".") + else + newEnvSetting = curEnvSetting == bev1p1 and bev1p2 or bev1p1 + errorCode = sys.call("fw_setenv " .. bev1 .. " " .. newEnvSetting) + if errorCode ~= 0 then + errorMessage = errorMessage or "" .. i18n.translate("Unable to set firmware environment variable") .. ": " .. bev1 .. " " .. i18n.translate("to") .. " " .. newEnvSetting .. ". " + util.perror(i18n.translate("Unable to set firmware environment variable") .. ": " .. bev1 .. " " .. i18n.translate("to") .. " " .. newEnvSetting .. ".") + end + end + end + if bev2 then + curEnvSetting = util.trim(util.exec("fw_printenv -n " .. bev2)) + if not curEnvSetting then + errorMessage = errorMessage or "" .. i18n.translate("Unable to obtain firmware environment variable") .. ": " .. bev2 .. ". " + util.perror(i18n.translate("Unable to obtain firmware environment variable") .. ": " .. bev2 .. ".") + else + newEnvSetting = curEnvSetting == bev2p1 and bev2p2 or bev2p1 + errorCode = sys.call("fw_setenv " .. bev2 .. " '" .. newEnvSetting .. "'") + if errorCode ~= 0 then + errorMessage = errorMessage or "" .. i18n.translate("Unable to set firmware environment variable") .. ": " .. bev2 .. " " .. i18n.translate("to") .. " " .. newEnvSetting .. ". " + util.perror(i18n.translate("Unable to set firmware environment variable") .. ": " .. bev2 .. " " .. i18n.translate("to") .. " " .. newEnvSetting .. ".") + end + end + end + else -- NetGear device + if not zyxelFlagPartition then zyxelFlagPartition = util.trim(util.exec(". /lib/functions.sh; find_mtd_part 0:DUAL_FLAG")) end + if not zyxelFlagPartition then + errorMessage = errorMessage .. i18n.translate("Unable to find Dual Boot Flag Partition." .. " ") + util.perror(i18n.translate("Unable to find Dual Boot Flag Partition.")) + else + zyxelBootFlag = tonumber(util.exec("dd if=" .. zyxelFlagPartition .. " bs=1 count=1 2>/dev/null | hexdump -n 1 -e '1/1 \"%d\"'")) + zyxelNewBootFlag = zyxelBootFlag and zyxelBootFlag == 1 and "\\xff" or "\\x01" + if zyxelNewBootFlag then + errorCode = sys.call("printf \"" .. zyxelNewBootFlag .. "\" >" .. zyxelFlagPartition ) + if errorCode ~= 0 then + errorMessage = errorMessage or "" .. i18n.translate("Unable to set Dual Boot Flag Partition entry for partition") .. ": " .. zyxelFlagPartition .. ". " + util.perror(i18n.translate("Unable to set Dual Boot Flag Partition entry for partition") .. ": " .. zyxelFlagPartition .. ".") + end + end + end + end + if not errorMessage then + ltemplate.render("admin_system/applyreboot", { + title = i18n.translate("Rebooting..."), + msg = i18n.translate("The system is rebooting to an alternative partition now.
DO NOT POWER OFF THE DEVICE!
Wait a few minutes before you try to reconnect. It might be necessary to renew the address of your computer to reach the device again, depending on your settings."), + addr = ip.new(uci:get("network", "lan", "ipaddr")) or "192.168.1.1" + }) + sys.reboot() + else + ltemplate.render("advanced_reboot/advanced_reboot",{ + romBoardName=romBoardName, + device_name=device_name, + bev1p1=bev1p1, + p1_os=p1_os, + bev1p2=bev1p2, + p2_os=p2_os, + current_partition=current_partition, + errorMessage = errorMessage}) + end + end end function action_poweroff() - local uci = require "luci.model.uci".cursor() - if luci.http.formvalue("cancel") then - luci.http.redirect(luci.dispatcher.build_url('admin/system/advanced_reboot')) - return - end - local step = tonumber(luci.http.formvalue("step") or 1) - if step == 1 then - if nixio.fs.access("/sbin/poweroff") then - luci.template.render("advanced_reboot/power_off",{}) - else - luci.template.render("advanced_reboot/advanced_reboot",{}) - end - elseif step == 2 then - luci.template.render("advanced_reboot/applyreboot", { - title = luci.i18n.translate("Shutting down..."), - msg = luci.i18n.translate("The system is shutting down now.
DO NOT POWER OFF THE DEVICE!
It might be necessary to renew the address of your computer to reach the device again, depending on your settings."), - addr = luci.ip.new(uci:get("network", "lan", "ipaddr")) or "192.168.1.1" - }) - luci.sys.call("/sbin/poweroff") - end + local uci = require "luci.model.uci".cursor() + if http.formvalue("cancel") then + http.redirect(dispatcher.build_url('admin/system/advanced_reboot')) + return + end + local step = tonumber(http.formvalue("step") or 1) + if step == 1 then + if fs.access("/sbin/poweroff") then + ltemplate.render("advanced_reboot/power_off",{}) + else + ltemplate.render("advanced_reboot/advanced_reboot",{}) + end + elseif step == 2 then + ltemplate.render("admin_system/applyreboot", { + title = i18n.translate("Shutting down..."), + msg = i18n.translate("The system is shutting down now.
DO NOT POWER OFF THE DEVICE!
It might be necessary to renew the address of your computer to reach the device again, depending on your settings."), + addr = ip.new(uci:get("network", "lan", "ipaddr")) or "192.168.1.1" + }) + sys.call("/sbin/poweroff") + end end diff --git a/applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/advanced_reboot.htm b/applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/advanced_reboot.htm index 5c14f52ff..f3d8338c4 100644 --- a/applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/advanced_reboot.htm +++ b/applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/advanced_reboot.htm @@ -20,70 +20,70 @@ <%- if device_name then -%>
- <%=device_name%><%: Partitions%> -
-
-
<%:Partition%>
-
<%:Status%>
-
<%:Firmware/OS (Kernel)%>
-
<%:Action%>
-
-
-
- <%=string.format("%X", boot_envvar1_partition_one)%> -
-
- <%- if boot_envvar1_partition_one == current_partition then -%><%:Current%><%- else -%><%:Alternative%><%- end -%> -
-
- <%=partition_one_os%> -
-
- <%- if boot_envvar1_partition_one == current_partition then -%> -
- - -
- <%- else -%> -
- - -
- <%- end -%> -
-
-
-
- <%=string.format("%X", boot_envvar1_partition_two)%> -
-
- <%- if boot_envvar1_partition_two == current_partition then -%><%:Current%><%- else -%><%:Alternative%><%- end -%> -
-
- <%=partition_two_os%> -
-
- <%- if boot_envvar1_partition_two == current_partition then -%> -
- - -
- <%- else -%> -
- - -
- <%- end -%> -
-
-
+ <%=device_name%><%: Partitions%> +
+
+
<%:Partition%>
+
<%:Status%>
+
<%:Firmware%>
+
<%:Reboot%>
+
+
+
+ <%=string.format("%X", bev1p1)%> +
+
+ <%- if bev1p1 == current_partition then -%><%:Current%><%- else -%><%:Alternative%><%- end -%> +
+
+ <%=p1_os%> +
+
+ <%- if bev1p1 == current_partition then -%> +
+ + +
+ <%- else -%> +
+ + +
+ <%- end -%> +
+
+
+
+ <%=string.format("%X", bev1p2)%> +
+
+ <%- if bev1p2 == current_partition then -%><%:Current%><%- else -%><%:Alternative%><%- end -%> +
+
+ <%=p2_os%> +
+
+ <%- if bev1p2 == current_partition then -%> +
+ + +
+ <%- else -%> +
+ + +
+ <%- end -%> +
+
+
<%- else -%> - <%- if rom_board_name then -%> -

<%=pcdata(translatef("Warning: Device (%s) is unknown or isn't a dual-partition device!", rom_board_name))%>

- <%- else -%> -

<%=pcdata(translatef("Warning: Unable to obtain device information!"))%>

- <%- end -%> + <%- if rom_board_name then -%> +

<%=pcdata(translatef("Warning: Device (%s) is unknown or isn't a dual-partition device!", rom_board_name))%>

+ <%- else -%> +

<%=pcdata(translatef("Warning: Unable to obtain device information!"))%>

+ <%- end -%> <%- end -%>
@@ -91,10 +91,10 @@ <%- if nixio.fs.access("/sbin/poweroff") then -%>
- +
<%- else -%> -

<%:Warning: This system does not support powering off!%>

+

<%:Warning: This system does not support powering off!%>

<%- end -%> <%+footer%> diff --git a/applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/alternative_reboot.htm b/applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/alternative_reboot.htm index b15f16b0d..db1102062 100644 --- a/applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/alternative_reboot.htm +++ b/applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/alternative_reboot.htm @@ -10,10 +10,10 @@

<%:Reboot Device to an Alternative Partition%> - <%:Confirm%>

<%_ WARNING: An alternative partition might have its own settings and completely different firmware.

- As your network configuration and WiFi SSID/password on alternative partition might be different, - you might have to adjust your computer settings to be able to access your device once it reboots.

- Please also be aware that alternative partition firmware might not provide an easy way to switch active partition - and boot back to the currently active partition.

+ As your network configuration and WiFi SSID/password on alternative partition might be different, + you might have to adjust your computer settings to be able to access your device once it reboots.

+ Please also be aware that alternative partition firmware might not provide an easy way to switch active partition + and boot back to the currently active partition.

Click "Proceed" below to reboot device to an alternative partition. %>

diff --git a/applications/luci-app-advanced-reboot/root/etc/uci-defaults/40_luci-advanced-reboot b/applications/luci-app-advanced-reboot/root/etc/uci-defaults/40_luci-advanced-reboot new file mode 100644 index 000000000..e1a8f1e30 --- /dev/null +++ b/applications/luci-app-advanced-reboot/root/etc/uci-defaults/40_luci-advanced-reboot @@ -0,0 +1,5 @@ +#!/bin/sh + +rm -rf /var/luci-modulecache/; rm -f /var/luci-indexcache; +exit 0 + -- 2.25.1