--- /dev/null
+-- Copyright 2017 Stan Grishin <stangri@melmac.net>
+-- Licensed to the public under the Apache License 2.0.
+
+module("luci.controller.advanced_reboot", package.seeall)
+
+-- device, board_name, part1, part2, offset, env_var_1, value_1_1, value_1_2, env_var_2, value_2_1, value_2_2
+devices = {
+ {"Linksys WRT1200AC", "armada-385-linksys-caiman", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
+ {"Linksys WRT1900AC", "armada-xp-linksys-mamba", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
+ {"Linksys WRT1900ACv2", "armada-385-linksys-cobra", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
+ {"Linksys WRT1900ACS", "armada-385-linksys-shelby", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
+ {"Linksys WRT3200ACM", "armada-385-linksys-rango", "mtd5", "mtd7", 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 EA8500", "ea8500", "mtd13", "mtd15", 32, "boot_part", 1, 2}
+}
+
+board_name = luci.util.trim(luci.sys.exec("cat /tmp/sysinfo/board_name"))
+for i=1, #devices do
+ if board_name and devices[i][2] == 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=25" .. " 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=25" .. " 2>/dev/null"))
+ n, partition_two_version = string.match(partition_two_label, '(Linux)-([%d|.]+)')
+ end
+ if string.find(partition_one_label, "LEDE") then partition_one_os = "LEDE" end
+ if string.find(partition_one_label, "OpenWrt") then partition_one_os = "OpenWrt" end
+ if string.find(partition_one_label, "Linksys") then partition_one_os = "Linksys" end
+ if string.find(partition_two_label, "LEDE") then partition_two_os = "LEDE" end
+ if string.find(partition_two_label, "OpenWrt") then partition_two_os = "OpenWrt" end
+ if string.find(partition_two_label, "Linksys") then partition_two_os = "Linksys" 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
+ 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)))
+ other_partition = current_partition == boot_envvar1_partition_one and boot_envvar1_partition_two or boot_envvar1_partition_one
+ 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"))
+-- if device_name then entry({"admin", "system", "advanced_reboot", "altreboot"}, post("action_altreboot")) end
+ entry({"admin", "system", "advanced_reboot", "alternative_reboot"}, post("action_altreboot"))
+ entry({"admin", "system", "advanced_reboot", "power_off"}, post("action_poweroff"))
+end
+
+function action_reboot()
+ luci.template.render("admin_system/applyreboot", {
+ title = luci.i18n.translate("Rebooting..."),
+ msg = luci.i18n.translate("The system is rebooting now.<br /> DO NOT POWER OFF THE DEVICE!<br /> 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.cursor():get("network", "lan", "ipaddr")) or "192.168.1.1"
+ })
+ luci.sys.reboot()
+end
+
+function action_altreboot()
+ 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",{})
+ end
+ elseif step == 2 then
+ luci.template.render("admin_system/applyreboot", {
+ title = luci.i18n.translate("Rebooting..."),
+ msg = luci.i18n.translate("The system is rebooting to an alternative partition now.<br /> DO NOT POWER OFF THE DEVICE!<br /> 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.cursor():get("network", "lan", "ipaddr")) or "192.168.1.1"
+ })
+ if boot_envvar1 then env1 = tonumber(luci.util.trim(luci.sys.exec("/usr/sbin/fw_printenv -n " .. boot_envvar1))) end
+ if boot_envvar2 then env2 = luci.util.trim(luci.sys.exec("/usr/sbin/fw_printenv -n " .. boot_envvar2)) end
+ if env1 and env1 == boot_envvar1_partition_one then luci.sys.call("/usr/sbin/fw_setenv " .. boot_envvar1 .. " " .. boot_envvar1_partition_two) end
+ if env1 and env1 == boot_envvar1_partition_two then luci.sys.call("/usr/sbin/fw_setenv " .. boot_envvar1 .. " " .. boot_envvar1_partition_one) end
+ if env2 and env2 == boot_envvar2_partition_one then luci.sys.call("/usr/sbin/fw_setenv " .. boot_envvar2 .. " '" .. boot_envvar2_partition_two .. "'") end
+ if env2 and env2 == boot_envvar2_partition_two then luci.sys.call("/usr/sbin/fw_setenv " .. boot_envvar2 .. " '" .. boot_envvar2_partition_one .. "'") end
+ luci.sys.reboot()
+ end
+end
+
+function action_poweroff()
+ 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("admin_system/applyreboot", {
+ title = luci.i18n.translate("Shutting down..."),
+ msg = luci.i18n.translate("The system is shutting down now.<br /> DO NOT POWER OFF THE DEVICE!<br /> 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.cursor():get("network", "lan", "ipaddr")) or "192.168.1.1"
+ })
+ luci.sys.call("/sbin/poweroff")
+ end
+end
--- /dev/null
+<%#
+ Copyright 2008 Steven Barth <steven@midlink.org>
+ Copyright 2008-2015 Jo-Philipp Wich <jow@openwrt.org>
+ Copyright 2017 Stan Grishin <stangri@melmac.net>
+ Licensed to the public under the Apache License 2.0.
+-%>
+
+<%+header%>
+
+<h2 name="content"><%:Advanced Reboot%></h2>
+<br />
+
+<%- local c = require("luci.model.uci").cursor():changes(); if c and next(c) then -%>
+ <p class="alert-message warning"><%:Warning: There are unsaved changes that will get lost on reboot!%></p>
+<%- end -%>
+
+<%- if device_name then -%>
+<fieldset class="cbi-section">
+ <legend><%=device_name%><%: Partitions%></legend>
+ <table class="cbi-section-table" id="partitions">
+ <tr class="cbi-section-table-titles">
+ <th class="cbi-section-table-cell"><%:Partition%></th>
+ <th class="cbi-section-table-cell"><%:Status%></th>
+ <th class="cbi-section-table-cell"><%:Firmware/OS (Kernel)%></th>
+ <th class="cbi-section-table-cell"><%:Action%></th>
+ </tr>
+ <tr class="cbi-section-table-row">
+ <td>
+ <%=boot_envvar1_partition_one%>
+ </td>
+ <td>
+ <%- if boot_envvar1_partition_one == current_partition then -%><%:Current%><%- else -%><%:Alternative%><%- end -%>
+ </td>
+ <td>
+ <%=partition_one_os%>
+ </td>
+ <td>
+ <%- if boot_envvar1_partition_one == current_partition then -%>
+ <form method="post" action="<%=url('admin/system/advanced_reboot/reboot')%>">
+ <input type="hidden" name="token" value="<%=token%>" />
+ <input id="reboot-button" type="submit" class="cbi-button cbi-button-apply" value="<%:Reboot to current partition%>" />
+ </form>
+ <%- else -%>
+ <form method="post" action="<%=url('admin/system/advanced_reboot/alternative_reboot')%>">
+ <input type="hidden" name="token" value="<%=token%>" />
+ <input id="altreboot-button" type="submit" class="cbi-button cbi-button-apply" value="<%:Reboot to alternative partition...%>" />
+ </form>
+ <%- end -%>
+ </td>
+ </tr>
+ <tr class="cbi-section-table-row">
+ <td>
+ <%=boot_envvar1_partition_two%>
+ </td>
+ <td>
+ <%- if boot_envvar1_partition_two == current_partition then -%><%:Current%><%- else -%><%:Alternative%><%- end -%>
+ </td>
+ <td>
+ <%=partition_two_os%>
+ </td>
+ <td>
+ <%- if boot_envvar1_partition_two == current_partition then -%>
+ <form method="post" action="<%=url('admin/system/advanced_reboot/reboot')%>">
+ <input type="hidden" name="token" value="<%=token%>" />
+ <input id="reboot-button" type="submit" class="cbi-button cbi-button-apply" value="<%:Reboot to current partition%>" />
+ </form>
+ <%- else -%>
+ <form method="post" action="<%=url('admin/system/advanced_reboot/alternative_reboot')%>">
+ <input type="hidden" name="token" value="<%=token%>" />
+ <input id="altreboot-button" type="submit" class="cbi-button cbi-button-apply" value="<%:Reboot to alternative partition...%>" />
+ </form>
+ <%- end -%>
+ </td>
+ </tr>
+ </table>
+</fieldset>
+<%- else -%>
+ <p class="alert-message warning"><%:Warning: This system does not have two partitions!%></p>
+<%- end -%>
+
+<hr />
+
+<%- if nixio.fs.access("/sbin/poweroff") then -%>
+<form method="post" action="<%=url('admin/system/advanced_reboot/power_off')%>">
+ <input type="hidden" name="token" value="<%=token%>" />
+ <input id="poweroff-button" type="submit" class="cbi-button cbi-button-apply" value="<%:Perform power off...%>" />
+</form>
+<%- else -%>
+ <p class="alert-message warning"><%:Warning: This system does not support powering off!%></p>
+<%- end -%>
+
+<%+footer%>
--- /dev/null
+msgid ""
+msgstr "Content-Type: text/plain; charset=UTF-8"
+
+msgid "Action"
+msgstr ""
+
+msgid "Advanced Reboot"
+msgstr ""
+
+msgid "Alternative"
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "Confirm"
+msgstr ""
+
+msgid "Current"
+msgstr ""
+
+msgid "Firmware/OS (Kernel)"
+msgstr ""
+
+msgid "Partition"
+msgstr ""
+
+msgid "Partitions"
+msgstr ""
+
+msgid "Perform power off..."
+msgstr ""
+
+msgid "Power Off Device"
+msgstr ""
+
+msgid "Proceed"
+msgstr ""
+
+msgid "Reboot Device to an Alternative Partition"
+msgstr ""
+
+msgid "Reboot to alternative partition..."
+msgstr ""
+
+msgid "Reboot to current partition"
+msgstr ""
+
+msgid "Rebooting..."
+msgstr ""
+
+msgid "Shutting down..."
+msgstr ""
+
+msgid "Status"
+msgstr ""
+
+msgid ""
+"The system is rebooting now.<br /> DO NOT POWER OFF THE DEVICE!<br /> 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."
+msgstr ""
+
+msgid ""
+"The system is rebooting to an alternative partition now.<br /> DO NOT POWER "
+"OFF THE DEVICE!<br /> 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."
+msgstr ""
+
+msgid ""
+"The system is shutting down now.<br /> DO NOT POWER OFF THE DEVICE!<br /> It "
+"might be necessary to renew the address of your computer to reach the device "
+"again, depending on your settings."
+msgstr ""
+
+msgid ""
+"WARNING: An alternative partition might have its own settings and completely "
+"different firmware.<br /><br /> 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.<br /><br /> 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.<br /><br /> Click \"Proceed\" below "
+"to reboot device to an alternative partition."
+msgstr ""
+
+msgid ""
+"WARNING: Power off might result in a reboot on a device which doesn't "
+"support power off.<br /><br /> Click \"Proceed\" below to power off your "
+"device."
+msgstr ""
+
+msgid "Warning: There are unsaved changes that will get lost on reboot!"
+msgstr ""
+
+msgid "Warning: This system does not have two partitions!"
+msgstr ""
+
+msgid "Warning: This system does not support powering off!"
+msgstr ""