luci-app-advanced-reboot: convert to client side 4489/head
authorAnsuel Smith <ansuelsmth@gmail.com>
Wed, 7 Oct 2020 12:42:39 +0000 (14:42 +0200)
committerAnsuel Smith <ansuelsmth@gmail.com>
Wed, 7 Oct 2020 12:42:39 +0000 (14:42 +0200)
Rework the advanced-reboot app to client side implementation.
Change devices file to json type.

Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
Tested-by: Stefan Lippers-Hollmann <s.l-h@gmx.de>
42 files changed:
applications/luci-app-advanced-reboot/htdocs/luci-static/resources/view/system/advanced_reboot.js [new file with mode: 0644]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices.disabled/linksys-ea9500.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-e4200v2-ea4500.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-e4200v2.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea3500.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea4500.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea6350v3.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea8300.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea8500.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-mr8300.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt1200ac.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt1900ac.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt1900acs.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt1900acv2.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt3200acm.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt32x.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/zyxel-nbg6817.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/controller/advanced_reboot.lua [deleted file]
applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/advanced_reboot.htm [deleted file]
applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/alternative_reboot.htm [deleted file]
applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/applyreboot.htm [deleted file]
applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/power_off.htm [deleted file]
applications/luci-app-advanced-reboot/root/etc/uci-defaults/40_luci-advanced-reboot
applications/luci-app-advanced-reboot/root/usr/libexec/rpcd/luci.advanced_reboot [new file with mode: 0755]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices.disabled/linksys-ea9500.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-e4200v2-ea4500.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-e4200v2.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea3500.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea4500.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea6350v3.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea8300.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea8500.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-mr8300.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt1200ac.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt1900ac.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt1900acs.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt1900acv2.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt3200acm.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt32x.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/zyxel-nbg6817.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/luci/menu.d/luci-app-advanced-reboot.json [new file with mode: 0644]
applications/luci-app-advanced-reboot/root/usr/share/rpcd/acl.d/luci-app-advanced-reboot.json

diff --git a/applications/luci-app-advanced-reboot/htdocs/luci-static/resources/view/system/advanced_reboot.js b/applications/luci-app-advanced-reboot/htdocs/luci-static/resources/view/system/advanced_reboot.js
new file mode 100644 (file)
index 0000000..762d65f
--- /dev/null
@@ -0,0 +1,237 @@
+'use strict';
+'require view';
+'require rpc';
+'require ui';
+'require uci';
+'require fs';
+
+return view.extend({
+       translateTable: {
+               NO_BOARD_NAME : function(args) { return _('Unable to find Device Board Name.')},
+               NO_DUAL_FLAG : function(args) {return _('Unable to find Dual Boot Flag Partition.')},
+               ERR_SET_DUAL_FLAG : function(args) { return _('Unable to set Dual Boot Flag Partition entry for partition: %s.').format(args[0])},
+               NO_FIRM_ENV : function(args) { return _('Unable to obtain firmware environment variable: %s.').format(args[0])},
+               ERR_SET_ENV : function(args) { return _('Unable to set firmware environment variable: %s to %s.').format(args[0],args[1])}
+       },
+
+       callReboot: rpc.declare({
+               object: 'system',
+               method: 'reboot',
+               expect: { result: 0 }
+       }),
+
+       callObtainDeviceInfo: rpc.declare({
+               object: 'luci.advanced_reboot',
+               method: 'obtain_device_info',
+               expect: {  }
+       }),
+
+       callTogglePartition: rpc.declare({
+               object: 'luci.advanced_reboot',
+               method: 'toggle_boot_partition',
+               expect: {  }
+       }),
+
+       callPowerOff: function() {
+               return fs.exec('/sbin/poweroff').then(function() {
+                       ui.showModal(_('Shutting down...'), [
+                               E('p', { 'class': 'spinning' }, _('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.'))
+                       ]);
+               })
+       },
+
+       handlePowerOff: function() {
+
+               ui.showModal(_('Power Off Device'), [
+                       E('p', _("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.")),
+                       E('div', { 'class': 'right' }, [
+                               E('button', {
+                                       'class': 'btn',
+                                       'click': ui.hideModal
+                               }, _('Cancel')), ' ',
+                               E('button', {
+                                       'class': 'cbi-button cbi-button-positive important',
+                                       'click': L.bind(this.callPowerOff, this)
+                               }, _('Proceed'))
+                       ])
+               ]);
+
+       },
+
+       handleReboot: function(ev) {
+               return this.callReboot().then(function(res) {
+                       if (res != 0) {
+                               ui.addNotification(null, E('p', _('The reboot command failed with code %d').format(res)));
+                               L.raise('Error', 'Reboot failed');
+                       }
+
+                       ui.showModal(_('Rebooting…'), [
+                               E('p', { 'class': 'spinning' }, _('Waiting for device...'))
+                       ]);
+
+                       window.setTimeout(function() {
+                               ui.showModal(_('Rebooting…'), [
+                                       E('p', { 'class': 'spinning alert-message warning' },
+                                               _('Device unreachable! Still waiting for device...'))
+                               ]);
+                       }, 150000);
+
+                       ui.awaitReconnect();
+               })
+               .catch(function(e) { ui.addNotification(null, E('p', e.message)) });
+       },
+
+       handleTogglePartition: function(ev) {
+               return this.callTogglePartition().then(L.bind(function(res) {
+                       if (res.error) {
+                               ui.hideModal()
+                               return ui.addNotification(null, E('p', this.translateTable[res.error](res.args)));
+                       }
+
+                       return this.callReboot().then(function(res) {
+                               if (res != 0) {
+                                       ui.addNotification(null, E('p', _('The reboot command failed with code %d').format(res)));
+                                       L.raise('Error', 'Reboot failed');
+                               }
+
+                               ui.showModal(_('Rebooting…'), [
+                                       E('p', { 'class': 'spinning' }, _('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.'))
+                               ]);
+
+                               window.setTimeout(function() {
+                                       ui.showModal(_('Rebooting…'), [
+                                               E('p', { 'class': 'spinning alert-message warning' },
+                                                       _('Device unreachable! Still waiting for device...'))
+                                       ]);
+                               }, 150000);
+
+                               ui.awaitReconnect();
+                       })
+                       .catch(function(e) { ui.addNotification(null, E('p', e.message)) });
+               }, this));
+       },
+
+       handleAlternativeReboot: function(ev) {
+               return Promise.all([
+                       L.resolveDefault(fs.stat('/usr/sbin/fw_printenv'), null),
+                       L.resolveDefault(fs.stat('/usr/sbin/fw_setenv'), null),
+               ]).then(L.bind(function (data) {
+                       if (!data[0] || !data[1]) {
+                               return ui.addNotification(null, E('p', _('No access to fw_printenv or fw_printenv!')));
+                       }
+
+                       ui.showModal(_('Reboot Device to an Alternative Partition') + " - " + _("Confirm"), [
+                               E('p', _("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.")),
+                               E('div', { 'class': 'right' }, [
+                                       E('button', {
+                                               'class': 'btn',
+                                               'click': ui.hideModal
+                                       }, _('Cancel')), ' ',
+                                       E('button', {
+                                               'class': 'cbi-button cbi-button-positive important',
+                                               'click': L.bind(this.handleTogglePartition, this)
+                                       }, _('Proceed'))
+                               ])
+                       ]);
+               }, this))
+       },
+
+       parsePartitions: function(partitions) {
+               var res = [];
+
+               partitions.forEach(L.bind(function(partition) {
+                       var func, text;
+
+                       if (partition.state == 'Current') {
+                               func = 'handleReboot';
+                               text = _('Reboot to current partition');
+                       } else {
+                               func = 'handleAlternativeReboot';
+                               text = _('Reboot to alternative partition...');
+                       }
+
+                       res.push([
+                               (partition.number).toString(16).toUpperCase(),
+                               _(partition.state),
+                               partition.os.replace("Unknown", _("Unknown")).replace("Compressed", _("Compressed")),
+                               E('button', {
+                                       'class': 'cbi-button cbi-button-apply important',
+                                       'click': ui.createHandlerFn(this, func)
+                               }, text)
+                       ])
+               }, this));
+
+               return res;
+       },
+
+       load: function() {
+               return Promise.all([
+                       uci.changes(),
+                       L.resolveDefault(fs.stat('/sbin/poweroff'), null),
+                       this.callObtainDeviceInfo()
+               ]);
+       },
+
+       render: function(data) {
+               var changes = data[0],
+                       poweroff_supported = data[1] != null ? true : false,
+                       device_info = data[2];
+
+               var body = E([
+                       E('h2', _('Advanced Reboot'))
+               ]);
+
+               for (var config in (changes || {})) {
+                       body.appendChild(E('p', { 'class': 'alert-message warning' },
+                               _('Warning: There are unsaved changes that will get lost on reboot!')));
+                       break;
+               }
+
+               if (device_info.error)
+                       body.appendChild(E('p', { 'class' : 'alert-message warning'}, _("ERROR: ") + this.translateTable[device_info.error]()));
+
+               body.appendChild(E('h3', device_info.device_name + _(' Partitions')));
+               if (device_info.device_name) {
+                       var partitions_table = E('div', { 'class': 'table' }, [
+                               E('div', { 'class': 'tr table-titles' }, [
+                                       E('div', { 'class': 'th' }, [ _('Partition') ]),
+                                       E('div', { 'class': 'th' }, [ _('Status') ]),
+                                       E('div', { 'class': 'th' }, [ _('Firmware') ]),
+                                       E('div', { 'class': 'th' }, [ _('Reboot') ])
+                               ])
+                       ]);
+
+                       cbi_update_table(partitions_table, this.parsePartitions(device_info.partitions));
+
+                       body.appendChild(partitions_table);
+               } else {
+                       body.appendChild(E('p', { 'class' : 'alert-message warning'},
+                       device_info.rom_board_name ? _("Warning: Device (%s) is unknown or isn't a dual-partition device!").format(device_info.rom_board_name)
+                               : _('Warning: Unable to obtain device information!')
+                       ));
+               }
+
+               body.appendChild(E('hr'));
+               body.appendChild(
+                       poweroff_supported ? E('button', {
+                               'class': 'cbi-button cbi-button-apply important',
+                               'click': ui.createHandlerFn(this, 'handlePowerOff')
+                       }, _('Perform power off...'))
+
+                       : E('p', { 'class' : 'alert-message warning'},
+                       _('Warning: This system does not support powering off!'))
+               );
+
+               return body;
+       },
+
+       handleSaveApply: null,
+       handleSave: null,
+       handleReset: null
+});
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices.disabled/linksys-ea9500.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices.disabled/linksys-ea9500.lua
deleted file mode 100644 (file)
index 82f82dd..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "EA9500",
-       boardName = "linksys-panamera",
-       partition1MTD = "mtd3",
-       partition2MTD = "mtd6",
-       labelOffset = 28,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = nil,
-       bootEnv2Partition1Value = nil,
-       bootEnv2Partition2Value = nil
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-e4200v2-ea4500.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-e4200v2-ea4500.lua
deleted file mode 100644 (file)
index 6122409..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "E4200v2/EA4500",
-       boardNames = { "linksys-viper", "linksys,viper" },
-       partition1MTD = "mtd3",
-       partition2MTD = "mtd5",
-       labelOffset = 32,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = "bootcmd",
-       bootEnv2Partition1Value = "run nandboot",
-       bootEnv2Partition2Value = "run altnandboot"
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-e4200v2.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-e4200v2.lua
deleted file mode 100644 (file)
index 50c4970..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "E4200v2",
-       boardNames = { "linksys-e4200v2", "linksys,e4200v2" },
-       partition1MTD = "mtd3",
-       partition2MTD = "mtd5",
-       labelOffset = 32,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = "bootcmd",
-       bootEnv2Partition1Value = "run nandboot",
-       bootEnv2Partition2Value = "run altnandboot"
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea3500.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea3500.lua
deleted file mode 100644 (file)
index 2b72cd4..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "EA3500",
-       boardNames = { "linksys-audi", "linksys,audi", "linksys-ea3500", "linksys,ea3500" },
-       partition1MTD = "mtd3",
-       partition2MTD = "mtd5",
-       labelOffset = 32,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = "bootcmd",
-       bootEnv2Partition1Value = "run nandboot",
-       bootEnv2Partition2Value = "run altnandboot"
-}
-
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea4500.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea4500.lua
deleted file mode 100644 (file)
index 10f53d1..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "EA4500",
-       boardNames = { "linksys-e4500", "linksys,e4500" },
-       partition1MTD = "mtd3",
-       partition2MTD = "mtd5",
-       labelOffset = 32,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = "bootcmd",
-       bootEnv2Partition1Value = "run nandboot",
-       bootEnv2Partition2Value = "run altnandboot"
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea6350v3.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea6350v3.lua
deleted file mode 100644 (file)
index ccfe55e..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "EA6350v3",
-       boardNames = { "linksys-ea6350v3", "linksys,ea6350v3" },
-       partition1MTD = "mtd10",
-       partition2MTD = "mtd12",
-       labelOffset = 192,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = nil,
-       bootEnv2Partition1Value = nil,
-       bootEnv2Partition2Value = nil
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea8300.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea8300.lua
deleted file mode 100644 (file)
index e5faf27..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "EA8300",
-       boardNames = { "linksys-ea8300", "linksys,ea8300" },
-       partition1MTD = "mtd10",
-       partition2MTD = "mtd12",
-       labelOffset = 192,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = nil,
-       bootEnv2Partition1Value = nil,
-       bootEnv2Partition2Value = nil
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea8500.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-ea8500.lua
deleted file mode 100644 (file)
index 865b726..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "EA8500",
-       boardNames = { "linksys-ea8500", "linksys,ea8500" },
-       partition1MTD = "mtd13",
-       partition2MTD = "mtd15",
-       labelOffset = 32,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = nil,
-       bootEnv2Partition1Value = nil,
-       bootEnv2Partition2Value = nil
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-mr8300.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-mr8300.lua
deleted file mode 100644 (file)
index 49b3086..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "MR8300",
-       boardNames = { "linksys-mr8300", "linksys,mr8300" },
-       partition1MTD = "mtd10",
-       partition2MTD = "mtd12",
-       labelOffset = 192,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = nil,
-       bootEnv2Partition1Value = nil,
-       bootEnv2Partition2Value = nil
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt1200ac.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt1200ac.lua
deleted file mode 100644 (file)
index a3efb69..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "WRT1200AC",
-       boardNames = { "linksys-caiman", "linksys,caiman", "linksys,wrt1200ac" },
-       partition1MTD = "mtd4",
-       partition2MTD = "mtd6",
-       labelOffset = 32,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = "bootcmd",
-       bootEnv2Partition1Value = "run nandboot",
-       bootEnv2Partition2Value = "run altnandboot"
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt1900ac.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt1900ac.lua
deleted file mode 100644 (file)
index 24869be..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "WRT1900ACv1",
-       boardNames = { "linksys-mamba", "linksys,mamba", "linksys,wrt1900ac-v1" },
-       partition1MTD = "mtd4",
-       partition2MTD = "mtd6",
-       labelOffset = 32,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = "bootcmd",
-       bootEnv2Partition1Value = "run nandboot",
-       bootEnv2Partition2Value = "run altnandboot"
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt1900acs.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt1900acs.lua
deleted file mode 100644 (file)
index 6b409a1..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "WRT1900ACS",
-       boardNames = { "linksys-shelby", "linksys,shelby", "linksys,wrt1900acs" },
-       partition1MTD = "mtd4",
-       partition2MTD = "mtd6",
-       labelOffset = 32,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = "bootcmd",
-       bootEnv2Partition1Value = "run nandboot",
-       bootEnv2Partition2Value = "run altnandboot"
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt1900acv2.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt1900acv2.lua
deleted file mode 100644 (file)
index 15062eb..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "WRT1900ACv2",
-       boardNames = { "linksys-cobra", "linksys,cobra", "linksys,wrt1900ac-v2" },
-       partition1MTD = "mtd4",
-       partition2MTD = "mtd6",
-       labelOffset = 32,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = "bootcmd",
-       bootEnv2Partition1Value = "run nandboot",
-       bootEnv2Partition2Value = "run altnandboot"
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt3200acm.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt3200acm.lua
deleted file mode 100644 (file)
index 2e4cbec..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "WRT3200ACM",
-       boardNames = { "linksys-rango", "linksys,rango", "linksys,wrt3200acm" },
-       partition1MTD = "mtd5",
-       partition2MTD = "mtd7",
-       labelOffset = 32,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = "bootcmd",
-       bootEnv2Partition1Value = "run nandboot",
-       bootEnv2Partition2Value = "run altnandboot"
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt32x.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/linksys-wrt32x.lua
deleted file mode 100644 (file)
index dd9baf5..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "Linksys",
-       deviceName = "WRT32X",
-       boardNames = { "linksys-venom", "linksys,venom", "linksys,wrt32x" },
-       partition1MTD = "mtd5",
-       partition2MTD = "mtd7",
-       labelOffset = nil,
-       bootEnv1 = "boot_part",
-       bootEnv1Partition1Value = 1,
-       bootEnv1Partition2Value = 2,
-       bootEnv2 = "bootcmd",
-       bootEnv2Partition1Value = "run nandboot",
-       bootEnv2Partition2Value = "run altnandboot"
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/zyxel-nbg6817.lua b/applications/luci-app-advanced-reboot/luasrc/advanced-reboot/devices/zyxel-nbg6817.lua
deleted file mode 100644 (file)
index 0e91124..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-return {
-       vendorName = "ZyXEL",
-       deviceName = "NBG6817",
-       boardNames = { "nbg6817" },
-       partition1MTD = "mmcblk0p4",
-       partition2MTD = "mmcblk0p7",
-       labelOffset = 32,
-       bootEnv1 = nil,
-       bootEnv1Partition1Value = 255,
-       bootEnv1Partition2Value = 1,
-       bootEnv2 = nil,
-       bootEnv2Partition1Value = nil,
-       bootEnv2Partition2Value = nil
-}
diff --git a/applications/luci-app-advanced-reboot/luasrc/controller/advanced_reboot.lua b/applications/luci-app-advanced-reboot/luasrc/controller/advanced_reboot.lua
deleted file mode 100644 (file)
index 1fb4d46..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
--- Copyright 2017-2020 Stan Grishin <stangri@melmac.net>
--- Licensed to the public under the Apache License 2.0.
-
-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()
-local packageName = "advanced-reboot"
-local devices_dir = "/usr/lib/lua/luci/" .. packageName .. "/devices/"
-
-function logger(t)
-       util.exec("logger -t " .. packageName .. " '" .. tostring(t) .. "'")
-end
-
-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, op_info
-       if fs.access("/etc/os-release") then
-               cp_info = util.trim(util.exec('. /etc/os-release && echo "$PRETTY_NAME"'))
-               if cp_info:find("SNAPSHOT") then
-                       cp_info = util.trim(util.exec('. /etc/os-release && echo "$OPENWRT_RELEASE"'))
-               end 
-       end
-       logger(i18n.translatef("attempting to mount alternative partition (mtd%s)", tostring(op_ubi)))
-       alt_partition_unmount(op_ubi)
-       alt_partition_mount(op_ubi)
-       if fs.access("/alt/rom/etc/os-release") then
-               op_info = util.trim(util.exec('. /alt/rom/etc/os-release && echo "$PRETTY_NAME"'))
-               if op_info:find("SNAPSHOT") then
-                       op_info = util.trim(util.exec('. /alt/rom/etc/os-release && echo "$OPENWRT_RELEASE"'))
-               end 
-       end
-       logger(i18n.translatef("attempting to unmount alternative partition (mtd%s)", tostring(op_ubi)))
-       alt_partition_unmount(op_ubi)
-       return cp_info, op_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')
-       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/ubi" .. ubi_dev .. "_1 /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)
-       local i
-       local mtdCount = tonumber(util.exec("ubinfo | grep 'Present UBI devices' | grep -c ','"))
-       mtdCount = mtdCount and mtdCount + 1 or 10
---     util.exec("[ -d /alt/firmware ] && umount /alt/firmware")
-       util.exec("[ -d /alt/overlay ] && umount /alt/overlay")
-       util.exec("[ -d /alt/rom ] && umount /alt/rom")
-       for i = 0, mtdCount do
-               if not fs.access("/sys/devices/virtual/ubi/ubi" .. tostring(i) .. "/mtd_num") then break end
-               ubi_mtd =  tonumber(util.trim(util.exec("cat /sys/devices/virtual/ubi/ubi" .. i .. "/mtd_num")))
-               if ubi_mtd and ubi_mtd == op_ubi then
-                       util.exec("ubiblock --remove /dev/ubi" .. tostring(i) .. "_0")
-                       util.exec("ubidetach -m " .. tostring(op_ubi))
-                       util.exec('rm -rf /alt')
-               end
-       end
-end
-
-function obtain_device_info()
-       local p, boardName, n, p1_label, p1_version, p2_label, p2_version, p1_os, p2_os
-       local errorMessage, current_partition
-       local op_ubi, cp_info, op_info, zyxelFlagPartition
-       local romBoardName = util.trim(util.exec("cat /tmp/sysinfo/board_name"))
-       for filename in fs.dir(devices_dir) do
-               local p_func = loadfile(devices_dir .. filename)
-               setfenv(p_func, { _ = i18n.translate })
-               p = p_func()
-               if p.boardName then
-                       boardName = p.boardName:gsub('%p','')
-               end
-               if p.boardNames then
-                       for i, v in pairs(p.boardNames) do
-                               boardName = v:gsub('%p','')
-                               if romBoardName and romBoardName:gsub('%p',''):match(boardName) then break end
-                       end
-               end
-               if romBoardName and romBoardName:gsub('%p',''):match(boardName) then
-                       if p.labelOffset then
-                               if p.partition1MTD then
-                                       p1_label = util.trim(util.exec("dd if=/dev/" .. p.partition1MTD .. " bs=1 skip=" .. p.labelOffset .. " count=128" .. " 2>/dev/null"))
-                                       n, p1_version = p1_label:match('(Linux)-([%d|.]+)')
-                               end
-                               if p.partition2MTD then
-                                       p2_label = util.trim(util.exec("dd if=/dev/" .. p.partition2MTD .. " bs=1 skip=" .. p.labelOffset .. " 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 p.vendorName and p1_label:find(p.vendorName) then p1_os = p.vendorName 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 p.vendorName and p2_label:find(p.vendorName) then p2_os = p.vendorName end
-                               if not p1_os then p1_os = p.vendorName .. "/" .. i18n.translate("Unknown") end
-                               if not p2_os then p2_os = p.vendorName .. "/" .. i18n.translate("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
-                       else
-                               p1_os = p.vendorName .. "/" .. i18n.translate("Unknown") .. " (" .. i18n.translate("Compressed") .. ")"
-                               p2_os = p.vendorName .. "/" .. i18n.translate("Unknown") .. " (" .. i18n.translate("Compressed") .. ")"
-                       end
-
-                       if p.bootEnv1 then
-                               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 " .. p.bootEnv1)))
-                               end
-                       else
-                               if not zyxelFlagPartition then zyxelFlagPartition = util.trim(util.exec(". /lib/functions.sh; find_mtd_part 0:DUAL_FLAG")) end
-                               if zyxelFlagPartition then
-                                       current_partition = tonumber(util.exec("dd if=" .. zyxelFlagPartition .. " bs=1 count=1 2>/dev/null | hexdump -n 1 -e '1/1 \"%d\"'"))
-                               else
-                                       errorMessage = errorMessage or i18n.translate("Unable to find Dual Boot Flag Partition.")
-                                       util.perror(i18n.translate("Unable to find Dual Boot Flag Partition."))
-                               end
-                       end
-                       
-                       if is_alt_mountable(p.partition1MTD, p.partition2MTD) then
-                               if current_partition == p.bootEnv1Partition1Value then
-                                       op_ubi = tonumber(p.partition2MTD:sub(4)) + 1
-                               else
-                                       op_ubi = tonumber(p.partition1MTD:sub(4)) + 1
-                               end
-                               local cp_info, op_info = get_partition_os_info(op_ubi)
-                               if current_partition == p.bootEnv1Partition1Value then
-                                       p1_os = cp_info or p1_os
-                                       p2_os = op_info or p2_os
-                               else
-                                       p1_os = op_info or p1_os
-                                       p2_os = cp_info or p2_os
-                               end
-                       end
-                       return romBoardName, p.vendorName .. " " .. p.deviceName, p.bootEnv1, p.bootEnv1Partition1Value, p1_os, p.bootEnv1Partition2Value, p2_os, p.bootEnv2, p.bootEnv2Partition1Value, p.bootEnv2Partition1Value, current_partition
-               end
-       end
-       return romBoardName, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil
-end
-
-function index()
-       entry({"admin", "system", "advanced_reboot"}, call("action_template"), _("Advanced Reboot"), 90).acl_depends = { "luci-app-advanced-reboot" }
-       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_template()
-       local romBoardName, device_name, bev1, bev1p1, p1_os, bev1p2, p2_os, bev2, bev2p1, bev2p2, current_partition = obtain_device_info()
-       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
-
-function action_reboot()
-       ltemplate.render("advanced_reboot/applyreboot", {
-                               title = i18n.translate("Rebooting..."),
-                               msg   = 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  = ip.new(util.imatch(uci:get("network", "lan", "ipaddr"))() or "192.168.1.1")
-                       })
-       sys.reboot()
-end
-
-function action_altreboot()
-       local romBoardName, device_name, bev1, bev1p1, p1_os, bev1p2, p2_os, bev2, bev2p1, bev2p2, current_partition = obtain_device_info()
-       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.translatef("Unable to obtain firmware environment variable: %s.", bev1)
-                                       util.perror(i18n.translatef("Unable to obtain firmware environment variable: %s.", bev1))
-                               else
-                                       newEnvSetting = curEnvSetting == bev1p1 and bev1p2 or bev1p1
-                                       errorCode = sys.call("fw_setenv " .. bev1 .. " " .. newEnvSetting)
-                                               if errorCode ~= 0 then
-                                                       errorMessage = errorMessage or "" .. i18n.translatef("Unable to set firmware environment variable: %s to %s.", bev1, newEnvSetting)
-                                                       util.perror(i18n.translatef("Unable to set firmware environment variable: %s to %s.", bev1, newEnvSetting))
-                                               end
-                               end
-                       end
-                       if bev2 then
-                               curEnvSetting = util.trim(util.exec("fw_printenv -n " .. bev2))
-                               if not curEnvSetting then
-                                       errorMessage = errorMessage or "" .. i18n.translatef("Unable to obtain firmware environment variable: %s.", bev2)
-                                       util.perror(i18n.translatef("Unable to obtain firmware environment variable: %s.", bev2))
-                               else
-                                       newEnvSetting = curEnvSetting == bev2p1 and bev2p2 or bev2p1
-                                       errorCode = sys.call("fw_setenv " .. bev2 .. " '" .. newEnvSetting .. "'")
-                                       if errorCode ~= 0 then
-                                               errorMessage = errorMessage or "" .. i18n.translatef("Unable to set firmware environment variable: %s to %s.", bev2, newEnvSetting)
-                                               util.perror(i18n.translatef("Unable to set firmware environment variable: %s to %s.", bev2, 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.translatef("Unable to set Dual Boot Flag Partition entry for partition: %s.", zyxelFlagPartition)
-                                               util.perror(i18n.translatef("Unable to set Dual Boot Flag Partition entry for partition: %s.", zyxelFlagPartition))
-                                       end
-                               end
-                       end
-               end
-               if not errorMessage then
-                       ltemplate.render("advanced_reboot/applyreboot", {
-                                               title = i18n.translate("Rebooting..."),
-                                               msg   = 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  = ip.new(util.imatch(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()
-       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("advanced_reboot/applyreboot", {
-                                       title = i18n.translate("Shutting down..."),
-                                       msg   = 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  = ip.new(util.imatch(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
deleted file mode 100644 (file)
index a28418c..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-<%#
- Copyright 2008 Steven Barth <steven@midlink.org>
- Copyright 2008-2015 Jo-Philipp Wich <jow@openwrt.org>
- Copyright 2017-2020 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 errorMessage and errorMessage ~= "" then -%>
-       <p class="alert-message warning"><%:ERROR: %><%=errorMessage%></p>
-<%- end -%>
-
-<%- if device_name then -%>
-<fieldset class="cbi-section">
-       <legend><%=device_name%><%: Partitions%></legend>
-       <div class="table cbi-section-table" id="partitions">
-               <div class="tr cbi-section-table-titles">
-                       <div class="th cbi-section-table-cell"><%:Partition%></div>
-                       <div class="th cbi-section-table-cell"><%:Status%></div>
-                       <div class="th cbi-section-table-cell"><%:Firmware%></div>
-                       <div class="th cbi-section-table-cell"><%:Reboot%></div>
-               </div>
-               <div class="tr cbi-section-table-row cbi-rowstyle-<%- if bev1p1 == current_partition then -%><%=1%><%- else -%><%=2%><%- end -%>">
-                       <div class="td">
-                               <%=string.format("%X", bev1p1)%>
-                       </div>
-                       <div class="td">
-                               <%- if bev1p1 == current_partition then -%><%:Current%><%- else -%><%:Alternative%><%- end -%>
-                       </div>
-                       <div class="td">
-                               <%=p1_os%>
-                       </div>
-                       <div class="td">
-                               <%- if bev1p1 == 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="btn cbi-button cbi-button-apply important" 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="btn cbi-button cbi-button-apply important" value="<%:Reboot to alternative partition...%>" />
-                       </form>
-                               <%- end -%>
-                       </div>
-               </div>
-               <div class="tr cbi-section-table-row cbi-rowstyle-<%- if bev1p2 == current_partition then -%><%=1%><%- else -%><%=2%><%- end -%>">
-                       <div class="td">
-                               <%=string.format("%X", bev1p2)%>
-                       </div>
-                       <div class="td">
-                               <%- if bev1p2 == current_partition then -%><%:Current%><%- else -%><%:Alternative%><%- end -%>
-                       </div>
-                       <div class="td">
-                               <%=p2_os%>
-                       </div>
-                       <div class="td">
-                               <%- if bev1p2 == 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="btn cbi-button cbi-button-apply important" 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="btn cbi-button cbi-button-apply important" value="<%:Reboot to alternative partition...%>" />
-                               </form>
-                               <%- end -%>
-                       </div>
-               </div>
-       </div>
-</fieldset>
-<%- else -%>
-       <%- if rom_board_name then -%>
-               <p class="alert-message warning"><%=pcdata(translatef("Warning: Device (%s) is unknown or isn't a dual-partition device!", rom_board_name))%></p>
-       <%- else -%>
-               <p class="alert-message warning"><%=pcdata(translatef("Warning: Unable to obtain device information!"))%></p>
-       <%- end -%>
-<%- 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="btn cbi-button cbi-button-apply important" value="<%:Perform power off...%>" />
-</form>
-<%- else -%>
-       <p class="alert-message warning"><%:Warning: This system does not support powering off!%></p>
-<%- 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
deleted file mode 100644 (file)
index b81aaf4..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-<%#
- Copyright 2008 Steven Barth <steven@midlink.org>
- Copyright 2008-2009 Jo-Philipp Wich <jow@openwrt.org>
- Copyright 2017-2018 Stan Grishin <stangri@melmac.net>
- Licensed to the public under the Apache License 2.0.
--%>
-
-<%+header%>
-
-<h2 name="content"><%:Reboot Device to an Alternative Partition%> - <%:Confirm%></h2>
-<p>
-       <%_ 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. %>
-</p>
-
-<div class="cbi-page-actions right">
-       <form class="inline" action="<%=REQUEST_URI%>" method="post">
-               <input type="hidden" name="token" value="<%=token%>" />
-               <input type="hidden" name="step" value="2" />
-               <input class="btn cbi-button cbi-button-reset important" name="cancel" type="submit" value="<%:Cancel%>" />
-               <input class="btn cbi-button cbi-button-apply important" type="submit" value="<%:Proceed%>" />
-       </form>
-</div>
-
-<%+footer%>
diff --git a/applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/applyreboot.htm b/applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/applyreboot.htm
deleted file mode 100644 (file)
index 94ac36b..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<%#
- Copyright 2008 Steven Barth <steven@midlink.org>
- Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
- Licensed to the public under the Apache License 2.0.
--%>
-
-<html>
-       <head>
-               <title><%=luci.sys.hostname()%> - <%= title or translate("Rebooting...") %></title>
-               <link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css?v=git-19.271.68204-f8775ee" />
-               <script type="text/javascript" src="<%=resource%>/xhr.js?v=git-19.271.68204-f8775ee"></script>
-               <script type="text/javascript">//<![CDATA[
-                       var interval = window.setInterval(function() {
-                               var img = new Image();
-                               var target = ('https:' == document.location.protocol ? 'https://' : 'http://') + <%=addr and "'%s'" % addr or "window.location.host"%>;
-               
-                               img.onload = function() {
-                                       window.clearInterval(interval);
-                                       window.location.replace(target);
-                               };
-                               
-                               img.src = target + '<%=resource%>/icons/loading.gif?' + Math.random();
-                               
-                       }, 5000);
-               //]]></script>
-       </head>
-       <body>
-               <header>
-                       <div class="fill">
-                               <div class="container">
-                                       <p class="brand"><%=luci.sys.hostname() or "?"%></p>
-                               </div>
-                       </div>
-               </header>
-               &#160;
-               <div class="main">
-                       <div id="maincontainer">
-                               <div id="maincontent" class="container">
-                                       <h2 name="content" id="applyreboot-container" ><%:System%> - <%= title or translate("Rebooting...") %></h2>
-                                       <div class="cbi-section" id="applyreboot-section">
-                                               <div>
-                                                       <%= msg or translate("Changes applied.") %>
-                                               </div>
-                                               <div>
-                                                       <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" />
-                                                       <%:Waiting for changes to be applied...%>
-                                               </div>
-                                       </div>
-                               </div>
-                       </div>
-               </div>
-       </body>
-</html>
\ No newline at end of file
diff --git a/applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/power_off.htm b/applications/luci-app-advanced-reboot/luasrc/view/advanced_reboot/power_off.htm
deleted file mode 100644 (file)
index 56200a4..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-<%#
- Copyright 2008 Steven Barth <steven@midlink.org>
- Copyright 2008-2009 Jo-Philipp Wich <jow@openwrt.org>
- Copyright 2017-2018 Stan Grishin <stangri@melmac.net>
- Licensed to the public under the Apache License 2.0.
--%>
-
-<%+header%>
-
-<h2 name="content"><%:Power Off Device%> - <%:Confirm%></h2>
-<p>
-       <%_ 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. %>
-</p>
-
-<div class="cbi-page-actions right">
-       <form class="inline" action="<%=REQUEST_URI%>" method="post">
-               <input type="hidden" name="token" value="<%=token%>" />
-               <input type="hidden" name="step" value="2" />
-               <input class="btn cbi-button cbi-button-reset important" name="cancel" type="submit" value="<%:Cancel%>" />
-               <input class="btn cbi-button cbi-button-apply important" type="submit" value="<%:Proceed%>" />
-       </form>
-</div>
-
-<%+footer%>
index e1a8f1e3075833729cf1a2c9b3ee390dcdd403e2..fd22801e988cebd1e67f8a2a5b0454f6705bdccb 100644 (file)
@@ -1,5 +1,6 @@
 #!/bin/sh
 
+/etc/init.d/rpcd reload
 rm -rf /var/luci-modulecache/; rm -f /var/luci-indexcache;
 exit 0
 
diff --git a/applications/luci-app-advanced-reboot/root/usr/libexec/rpcd/luci.advanced_reboot b/applications/luci-app-advanced-reboot/root/usr/libexec/rpcd/luci.advanced_reboot
new file mode 100755 (executable)
index 0000000..a6c7c0e
--- /dev/null
@@ -0,0 +1,362 @@
+#!/usr/bin/env lua
+
+local json = require "luci.jsonc"
+local nixio = require "nixio"
+local fs   = require "nixio.fs"
+local sys  = require "luci.sys"
+local util = require "luci.util"
+
+local devices_dir = "/usr/share/advanced-reboot/devices/"
+
+local function logger(t)
+       util.exec("logger -t advanced-reboot '" .. tostring(t) .. "'")
+end
+
+local 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
+
+local function alt_partition_mount(op_ubi)
+       local ubi_dev
+       util.exec('for i in alt_rom alt_overlay firmware; do [ ! -d "$i" ] && mkdir -p "/alt/${i}"; done')
+       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/alt_rom")
+       util.exec("mount -t ubifs /dev/ubi" .. ubi_dev .. "_1 /alt/alt_overlay")
+--     util.exec("mount -t overlay overlay -o noatime,lowerdir=/alt/rom,upperdir=/alt/overlay/upper,workdir=/alt/overlay/work /alt/firmware")
+end
+
+local function alt_partition_unmount(op_ubi)
+       local i
+       local mtdCount = tonumber(util.exec("ubinfo | grep 'Present UBI devices' | grep -c ','"))
+       mtdCount = mtdCount and mtdCount + 1 or 10
+--     util.exec("[ -d /alt/firmware ] && umount /alt/firmware")
+       util.exec("[ -d /alt/alt_overlay ] && umount /alt/alt_overlay")
+       util.exec("[ -d /alt/alt_rom ] && umount /alt/alt_rom")
+       for i = 0, mtdCount do
+               if not fs.access("/sys/devices/virtual/ubi/ubi" .. tostring(i) .. "/mtd_num") then break end
+               ubi_mtd =  tonumber(util.trim(util.exec("cat /sys/devices/virtual/ubi/ubi" .. i .. "/mtd_num")))
+               if ubi_mtd and ubi_mtd == op_ubi then
+                       util.exec("ubiblock --remove /dev/ubi" .. tostring(i) .. "_0")
+                       util.exec("ubidetach -m " .. tostring(op_ubi))
+                       util.exec('rm -rf /alt')
+               end
+       end
+end
+
+local function get_partition_os_info(op_ubi)
+       local cp_info, op_info
+       if fs.access("/etc/os-release") then
+               cp_info = util.trim(util.exec('. /etc/os-release && echo "$PRETTY_NAME"'))
+               if cp_info:find("SNAPSHOT") then
+                       cp_info = util.trim(util.exec('. /etc/os-release && echo "$OPENWRT_RELEASE"'))
+               end
+       end
+       logger(string.format("attempting to mount alternative partition (mtd%s)", tostring(op_ubi)))
+       alt_partition_unmount(op_ubi)
+       alt_partition_mount(op_ubi)
+       if fs.access("/alt/alt_rom/etc/os-release") then
+               op_info = util.trim(util.exec('. /alt/alt_rom/etc/os-release && echo "$PRETTY_NAME"'))
+               if op_info:find("SNAPSHOT") then
+                       op_info = util.trim(util.exec('. /alt/alt_rom/etc/os-release && echo "$OPENWRT_RELEASE"'))
+               end
+       end
+       logger(string.format("attempting to unmount alternative partition (mtd%s)", tostring(op_ubi)))
+       alt_partition_unmount(op_ubi)
+       return cp_info, op_info
+end
+
+local function find_device_data(romBoardName)
+       local filename
+
+       for filename in fs.dir(devices_dir) do
+               local filedata = fs.readfile(devices_dir .. filename)
+
+               local p = json.parse(filedata or {})
+
+               if p then
+                       local boardName
+
+                       if p.boardName then
+                               boardName = p.boardName:gsub('%p','')
+                               if romBoardName:match(boardName) then return p end
+                       end
+                       if p.boardNames then
+                               for i, v in pairs(p.boardNames) do
+                                       boardName = v:gsub('%p','')
+                                       if romBoardName:match(boardName) then return p end
+                               end
+                       end
+               end
+       end
+
+       return nil
+end
+
+local methods = {
+       obtain_device_info = {
+               call = function()
+
+                       local ret = {}
+                       local romBoardName = fs.readfile('/tmp/sysinfo/board_name')
+
+                       if not romBoardName then
+                               ret.error = 'NO_BOARD_NAME'
+                               return ret
+                       end
+
+                       romBoardName = romBoardName:gsub('\n','')
+
+                       ret.rom_board_name = romBoardName
+
+                       romBoardName = romBoardName:gsub('%p','')
+
+                       local p, boardName, n, p1_label, p1_version, p2_label, p2_version, p1_os, p2_os
+                       local current_partition
+                       local op_ubi, cp_info, op_info, zyxelFlagPartition
+
+                       p = find_device_data(romBoardName)
+
+                       if p then
+                               if p.labelOffset then
+                                       if p.partition1MTD then
+                                               p1_label = util.trim(util.exec("dd if=/dev/" .. p.partition1MTD .. " bs=1 skip=" .. p.labelOffset .. " count=128" .. " 2>/dev/null"))
+                                               n, p1_version = p1_label:match('(Linux)-([%d|.]+)')
+                                       end
+
+                                       if p1_label then
+                                               if p1_label:find("LEDE") then p1_os = "LEDE" end
+                                               if p1_label:find("OpenWrt") then p1_os = "OpenWrt" end
+                                               if p.vendorName and p1_label:find(p.vendorName) then p1_os = p.vendorName end
+                                       end
+
+                                       if not p1_os then
+                                               p1_os = (p.vendorName and p.vendorName or 'Unknown') .. "/" .. "Unknown"
+                                       end
+                                       if p1_os and p1_version then p1_os = p1_os .. " (Linux " .. p1_version .. ")" end
+
+                                       if p.partition2MTD then
+                                               p2_label = util.trim(util.exec("dd if=/dev/" .. p.partition2MTD .. " bs=1 skip=" .. p.labelOffset .. " count=128" .. " 2>/dev/null"))
+                                               n, p2_version = p2_label:match('(Linux)-([%d|.]+)')
+                                       end
+
+                                       if p2_label then
+                                               if p2_label:find("LEDE") then p2_os = "LEDE" end
+                                               if p2_label:find("OpenWrt") then p2_os = "OpenWrt" end
+                                               if p.vendorName and p2_label:find(p.vendorName) then p2_os = p.vendorName end
+                                       end
+
+                                       if not p2_os then
+                                               p2_os = (p.vendorName and p.vendorName or 'Unknown') .. "/" .. "Unknown"
+                                       end
+                                       if p2_os and p2_version then p2_os = p2_os .. " (Linux " .. p2_version .. ")" end
+                               else
+                                       p1_os = p.vendorName .. "/" .. "Unknown" .. " (" .. "Compressed" .. ")"
+                                       p2_os = p.vendorName .. "/" .. "Unknown" .. " (" .. "Compressed" .. ")"
+                               end
+
+                               if p.bootEnv1 then
+                                       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 " .. p.bootEnv1)))
+                                       end
+                               else
+                                       if not zyxelFlagPartition then zyxelFlagPartition = util.trim(util.exec(". /lib/functions.sh; find_mtd_part 0:DUAL_FLAG")) end
+                                       if zyxelFlagPartition then
+                                               current_partition = tonumber(util.exec("dd if=" .. zyxelFlagPartition .. " bs=1 count=1 2>/dev/null | hexdump -n 1 -e '1/1 \"%d\"'"))
+                                       else
+                                               ret.error = 'NO_DUAL_FLAG'
+                                               logger("Unable to find Dual Boot Flag Partition.")
+                                               return ret
+                                       end
+                               end
+
+                               ret.current_partition = current_partition
+
+                               if is_alt_mountable(p.partition1MTD, p.partition2MTD) then
+                                       if current_partition == p.bootEnv1Partition1Value then
+                                               op_ubi = tonumber(p.partition2MTD:sub(4)) + 1
+                                       else
+                                               op_ubi = tonumber(p.partition1MTD:sub(4)) + 1
+                                       end
+                                       local cp_info, op_info = get_partition_os_info(op_ubi)
+                                       if current_partition == p.bootEnv1Partition1Value then
+                                               p1_os = cp_info or p1_os
+                                               p2_os = op_info or p2_os
+                                       else
+                                               p1_os = op_info or p1_os
+                                               p2_os = cp_info or p2_os
+                                       end
+                               end
+
+                               ret.device_name = (p.vendorName and p.vendorName or "") .. " " .. p.deviceName
+
+                               ret.partitions = {
+                                       {
+                                               os = p1_os,
+                                               state = p.bootEnv1Partition1Value == current_partition and 'Current' or 'Alternative',
+                                               number = p.bootEnv1Partition1Value
+                                       },
+                                       {
+                                               os = p2_os,
+                                               state = p.bootEnv1Partition2Value == current_partition and 'Current' or 'Alternative',
+                                               number = p.bootEnv1Partition2Value
+                                       }
+                               }
+                       end
+
+                       return ret
+               end
+       },
+       toggle_boot_partition = {
+               call = function()
+                       local ret = {}
+                       local zyxelFlagPartition, zyxelBootFlag, zyxelNewBootFlag, errorCode, curEnvSetting, newEnvSetting
+
+                       local romBoardName = fs.readfile('/tmp/sysinfo/board_name')
+
+                       if not romBoardName then
+                               ret.error = 'NO_BOARD_NAME'
+                               return ret
+                       end
+
+                       romBoardName = romBoardName:gsub('\n',''):gsub('%p','')
+                       p = find_device_data(romBoardName)
+                       local bev1, bev2 = p.bootEnv1, p.bootEnv2
+
+                       if bev1 or bev2 then -- Linksys devices
+                               if bev1 then
+                                       curEnvSetting = tonumber(util.trim(util.exec("fw_printenv -n " .. bev1)))
+                                       if not curEnvSetting then
+                                               logger(string.format("Unable to obtain firmware environment variable: %s.", bev1))
+                                               ret.error = 'NO_FIRM_ENV'
+                                               ret.args = { bev1 }
+                                               return ret
+                                       else
+                                               local bev1p1, bev1p2 = p.bootEnv1Partition1Value, p.bootEnv1Partition2Value
+                                               newEnvSetting = curEnvSetting == bev1p1 and bev1p2 or bev1p1
+                                               errorCode = sys.call("fw_setenv " .. bev1 .. " " .. newEnvSetting)
+                                               if errorCode ~= 0 then
+                                                       logger(string.format("Unable to set firmware environment variable: %s to %s.", bev1, newEnvSetting))
+                                                       ret.error = 'ERR_SET_ENV'
+                                                       ret.args = { bev1, newEnvSetting }
+                                                       return ret
+                                               end
+                                       end
+                               end
+                               if bev2 then
+                                       curEnvSetting = util.trim(util.exec("fw_printenv -n " .. bev2))
+                                       if not curEnvSetting then
+                                               logger(string.format("Unable to obtain firmware environment variable: %s.", bev2))
+                                               ret.error = 'NO_FIRM_ENV'
+                                               ret.args = { bev2 }
+                                               return ret
+                                       else
+                                               local bev2p1, bev2p2 = p.bootEnv2Partition1Value, p.bootEnv2Partition1Value
+                                               newEnvSetting = curEnvSetting == bev2p1 and bev2p2 or bev2p1
+                                               errorCode = sys.call("fw_setenv " .. bev2 .. " '" .. newEnvSetting .. "'")
+                                               if errorCode ~= 0 then
+                                                       logger(string.format("Unable to set firmware environment variable: %s to %s.", bev2, newEnvSetting))
+                                                       ret.error = 'ERR_SET_ENV'
+                                                       ret.args = { bev2, newEnvSetting }
+                                                       return ret
+                                               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
+                                       logger("Unable to find Dual Boot Flag Partition.")
+                                       ret.error = 'NO_DUAL_FLAG'
+                               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
+                                                       logger(string.format("Unable to set Dual Boot Flag Partition entry for partition: %s.", zyxelFlagPartition))
+                                                       ret.error = 'ERR_SET_DUAL_FLAG'
+                                                       ret.args = { zyxelFlagPartition }
+                                                       return ret
+                                               end
+                                       end
+                               end
+                       end
+
+                       return ret
+               end
+       }
+}
+
+local function parseInput()
+       local parse = json.new()
+       local done, err
+
+       while true do
+               local chunk = io.read(4096)
+               if not chunk then
+                       break
+               elseif not done and not err then
+                       done, err = parse:parse(chunk)
+               end
+       end
+
+       if not done then
+               print(json.stringify({ error = err or "Incomplete input" }))
+               os.exit(1)
+       end
+
+       return parse:get()
+end
+
+local function validateArgs(func, uargs)
+       local method = methods[func]
+       if not method then
+               print(json.stringify({ error = "Method not found" }))
+               os.exit(1)
+       end
+
+       if type(uargs) ~= "table" then
+               print(json.stringify({ error = "Invalid arguments" }))
+               os.exit(1)
+       end
+
+       uargs.ubus_rpc_session = nil
+
+       local k, v
+       local margs = method.args or {}
+       for k, v in pairs(uargs) do
+               if margs[k] == nil or
+                  (v ~= nil and type(v) ~= type(margs[k]))
+               then
+                       print(json.stringify({ error = "Invalid arguments" }))
+                       os.exit(1)
+               end
+       end
+
+       return method
+end
+
+if arg[1] == "list" then
+       local _, method, rv = nil, nil, {}
+       for _, method in pairs(methods) do rv[_] = method.args or {} end
+       print((json.stringify(rv):gsub(":%[%]", ":{}")))
+elseif arg[1] == "call" then
+       local args = parseInput()
+       local method = validateArgs(arg[2], args)
+       local result, code = method.call(args)
+       print((json.stringify(result):gsub("^%[%]$", "{}")))
+       os.exit(code or 0)
+end
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices.disabled/linksys-ea9500.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices.disabled/linksys-ea9500.json
new file mode 100644 (file)
index 0000000..7c84413
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "EA9500",
+       "boardName": "linksys-panamera",
+       "partition1MTD": "mtd3",
+       "partition2MTD": "mtd6",
+       "labelOffset": 28,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": null,
+       "bootEnv2Partition1Value": null,
+       "bootEnv2Partition2Value": null
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-e4200v2-ea4500.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-e4200v2-ea4500.json
new file mode 100644 (file)
index 0000000..be749a9
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "E4200v2/EA4500",
+       "boardNames": [ "linksys-viper", "linksys,viper" ],
+       "partition1MTD": "mtd3",
+       "partition2MTD": "mtd5",
+       "labelOffset": 32,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": "bootcmd",
+       "bootEnv2Partition1Value": "run nandboot",
+       "bootEnv2Partition2Value": "run altnandboot"
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-e4200v2.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-e4200v2.json
new file mode 100644 (file)
index 0000000..c32aaf8
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "E4200v2",
+       "boardNames": [ "linksys-e4200v2", "linksys,e4200v2" ],
+       "partition1MTD": "mtd3",
+       "partition2MTD": "mtd5",
+       "labelOffset": 32,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": "bootcmd",
+       "bootEnv2Partition1Value": "run nandboot",
+       "bootEnv2Partition2Value": "run altnandboot"
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea3500.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea3500.json
new file mode 100644 (file)
index 0000000..6cdc726
--- /dev/null
@@ -0,0 +1,15 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "EA3500",
+       "boardNames": [ "linksys-audi", "linksys,audi", "linksys-ea3500", "linksys,ea3500" ],
+       "partition1MTD": "mtd3",
+       "partition2MTD": "mtd5",
+       "labelOffset": 32,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": "bootcmd",
+       "bootEnv2Partition1Value": "run nandboot",
+       "bootEnv2Partition2Value": "run altnandboot"
+}
+
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea4500.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea4500.json
new file mode 100644 (file)
index 0000000..aa897f8
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "EA4500",
+       "boardNames": [ "linksys-e4500", "linksys,e4500" ],
+       "partition1MTD": "mtd3",
+       "partition2MTD": "mtd5",
+       "labelOffset": 32,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": "bootcmd",
+       "bootEnv2Partition1Value": "run nandboot",
+       "bootEnv2Partition2Value": "run altnandboot"
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea6350v3.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea6350v3.json
new file mode 100644 (file)
index 0000000..f5fc476
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "EA6350v3",
+       "boardNames": [ "linksys-ea6350v3", "linksys,ea6350v3" ],
+       "partition1MTD": "mtd10",
+       "partition2MTD": "mtd12",
+       "labelOffset": 192,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": null,
+       "bootEnv2Partition1Value": null,
+       "bootEnv2Partition2Value": null
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea8300.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea8300.json
new file mode 100644 (file)
index 0000000..d4a4788
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "EA8300",
+       "boardNames": [ "linksys-ea8300", "linksys,ea8300" ],
+       "partition1MTD": "mtd10",
+       "partition2MTD": "mtd12",
+       "labelOffset": 192,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": null,
+       "bootEnv2Partition1Value": null,
+       "bootEnv2Partition2Value": null
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea8500.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-ea8500.json
new file mode 100644 (file)
index 0000000..cafa573
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "EA8500",
+       "boardNames": [ "linksys-ea8500", "linksys,ea8500" ],
+       "partition1MTD": "mtd13",
+       "partition2MTD": "mtd15",
+       "labelOffset": 32,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": null,
+       "bootEnv2Partition1Value": null,
+       "bootEnv2Partition2Value": null
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-mr8300.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-mr8300.json
new file mode 100644 (file)
index 0000000..644f171
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "MR8300",
+       "boardNames": [ "linksys-mr8300", "linksys,mr8300" ],
+       "partition1MTD": "mtd10",
+       "partition2MTD": "mtd12",
+       "labelOffset": 192,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": null,
+       "bootEnv2Partition1Value": null,
+       "bootEnv2Partition2Value": null
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt1200ac.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt1200ac.json
new file mode 100644 (file)
index 0000000..3d1b19a
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "WRT1200AC",
+       "boardNames": [ "linksys-caiman", "linksys,caiman", "linksys,wrt1200ac" ],
+       "partition1MTD": "mtd4",
+       "partition2MTD": "mtd6",
+       "labelOffset": 32,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": "bootcmd",
+       "bootEnv2Partition1Value": "run nandboot",
+       "bootEnv2Partition2Value": "run altnandboot"
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt1900ac.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt1900ac.json
new file mode 100644 (file)
index 0000000..d088e9a
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "WRT1900ACv1",
+       "boardNames": [ "linksys-mamba", "linksys,mamba", "linksys,wrt1900ac-v1" ],
+       "partition1MTD": "mtd4",
+       "partition2MTD": "mtd6",
+       "labelOffset": 32,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": "bootcmd",
+       "bootEnv2Partition1Value": "run nandboot",
+       "bootEnv2Partition2Value": "run altnandboot"
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt1900acs.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt1900acs.json
new file mode 100644 (file)
index 0000000..a30b3dc
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "WRT1900ACS",
+       "boardNames": [ "linksys-shelby", "linksys,shelby", "linksys,wrt1900acs" ],
+       "partition1MTD": "mtd4",
+       "partition2MTD": "mtd6",
+       "labelOffset": 32,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": "bootcmd",
+       "bootEnv2Partition1Value": "run nandboot",
+       "bootEnv2Partition2Value": "run altnandboot"
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt1900acv2.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt1900acv2.json
new file mode 100644 (file)
index 0000000..361b434
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "WRT1900ACv2",
+       "boardNames": [ "linksys-cobra", "linksys,cobra", "linksys,wrt1900ac-v2" ],
+       "partition1MTD": "mtd4",
+       "partition2MTD": "mtd6",
+       "labelOffset": 32,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": "bootcmd",
+       "bootEnv2Partition1Value": "run nandboot",
+       "bootEnv2Partition2Value": "run altnandboot"
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt3200acm.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt3200acm.json
new file mode 100644 (file)
index 0000000..09fcf96
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "WRT3200ACM",
+       "boardNames": [ "linksys-rango", "linksys,rango", "linksys,wrt3200acm" ],
+       "partition1MTD": "mtd5",
+       "partition2MTD": "mtd7",
+       "labelOffset": 32,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": "bootcmd",
+       "bootEnv2Partition1Value": "run nandboot",
+       "bootEnv2Partition2Value": "run altnandboot"
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt32x.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/linksys-wrt32x.json
new file mode 100644 (file)
index 0000000..47e94ab
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "Linksys",
+       "deviceName": "WRT32X",
+       "boardNames": [ "linksys-venom", "linksys,venom", "linksys,wrt32x" ],
+       "partition1MTD": "mtd5",
+       "partition2MTD": "mtd7",
+       "labelOffset": null,
+       "bootEnv1": "boot_part",
+       "bootEnv1Partition1Value": 1,
+       "bootEnv1Partition2Value": 2,
+       "bootEnv2": "bootcmd",
+       "bootEnv2Partition1Value": "run nandboot",
+       "bootEnv2Partition2Value": "run altnandboot"
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/zyxel-nbg6817.json b/applications/luci-app-advanced-reboot/root/usr/share/advanced-reboot/devices/zyxel-nbg6817.json
new file mode 100644 (file)
index 0000000..719900b
--- /dev/null
@@ -0,0 +1,14 @@
+{
+       "vendorName": "ZyXEL",
+       "deviceName": "NBG6817",
+       "boardNames": [ "nbg6817" ],
+       "partition1MTD": "mmcblk0p4",
+       "partition2MTD": "mmcblk0p7",
+       "labelOffset": 32,
+       "bootEnv1": null,
+       "bootEnv1Partition1Value": 255,
+       "bootEnv1Partition2Value": 1,
+       "bootEnv2": null,
+       "bootEnv2Partition1Value": null,
+       "bootEnv2Partition2Value": null
+}
diff --git a/applications/luci-app-advanced-reboot/root/usr/share/luci/menu.d/luci-app-advanced-reboot.json b/applications/luci-app-advanced-reboot/root/usr/share/luci/menu.d/luci-app-advanced-reboot.json
new file mode 100644 (file)
index 0000000..e377fa9
--- /dev/null
@@ -0,0 +1,13 @@
+{
+       "admin/system/advanced_reboot": {
+               "title": "Advanced Reboot",
+               "order": 90,
+               "action": {
+                       "type": "view",
+                       "path": "system/advanced_reboot"
+               },
+               "depends": {
+                       "acl": [ "luci-app-advanced-reboot" ]
+               }
+       }
+}
index 50d50bc2f7920a42975c910e16949897637c4ffd..4b22db1083f08bfbbf9ee5cdc92b85016225fe80 100644 (file)
@@ -2,95 +2,14 @@
        "luci-app-advanced-reboot": {
                "description": "Grant UCI and file access for luci-app-advanced-reboot",
                "read": {
-                       "cgi-io": [
-                               "exec"
-                       ],
-                       "file": {
-                               "/usr/lib/lua/luci/advanced-reboot/devices/*": [
-                                       "read"
-                               ],
-                               "/sys/devices/virtual/ubi/ubi*/mtd_num": [
-                                       "read"
-                               ],
-                               "/etc/os-release": [
-                                       "read"
-                               ],
-                               "/alt/rom/etc/os-release": [
-                                       "read"
-                               ],
-                               "/usr/sbin/fw_printenv *": [
-                                       "exec"
-                               ],
-                               "/usr/sbin/fw_setenv *": [
-                                       "exec"
-                               ],
-                               "/usr/sbin/ubiattach *": [
-                                       "exec"
-                               ],
-                               "/usr/sbin/ubiblock *": [
-                                       "exec"
-                               ],
-                               "/usr/sbin/ubidetach *": [
-                                       "exec"
-                               ],
-                               "/usr/sbin/ubinfo *": [
-                                       "exec"
-                               ],
-                               "/bin/cat *": [
-                                       "exec"
-                               ],
-                               "/usr/bin/cat *": [
-                                       "exec"
-                               ],
-                               "/bin/dd *": [
-                                       "exec"
-                               ],
-                               "/usr/bin/dd *": [
-                                       "exec"
-                               ],
-                               "/bin/hexdump *": [
-                                       "exec"
-                               ],
-                               "/usr/bin/hexdump *": [
-                                       "exec"
-                               ],
-                               "/bin/logger -t advanced-reboot *": [
-                                       "exec"
-                               ],
-                               "/usr/bin/logger -t advanced-reboot *": [
-                                       "exec"
-                               ],
-                               "/bin/mkdir *": [
-                                       "exec"
-                               ],
-                               "/usr/bin/mkdir *": [
-                                       "exec"
-                               ],
-                               "/bin/mount *": [
-                                       "exec"
-                               ],
-                               "/usr/bin/mount *": [
-                                       "exec"
-                               ],
-                               "/bin/printf *": [
-                                       "exec"
-                               ],
-                               "/usr/bin/printf *": [
-                                       "exec"
-                               ],
-                               "/bin/rm *": [
-                                       "exec"
-                               ],
-                               "/usr/bin/rm *": [
-                                       "exec"
-                               ],
-                               "/lib/functions.sh": [
-                                       "exec"
-                               ]
+                       "ubus": {
+                               "luci.advanced_reboot": [ "obtain_device_info", "toggle_boot_partition" ]
                        },
-                       "uci": [
-                               "network"
-                       ]
+                       "file": {
+                               "/usr/sbin/fw_printenv": [ "list" ],
+                               "/usr/sbin/fw_setenv": [ "list" ],
+                               "/sbin/poweroff": [ "list", "exec" ]
+                       }
                }
        }
 }