istoreos: add istoreos system packages

This commit is contained in:
Liangbin Lian 2024-12-31 14:42:45 +08:00
parent c956349da7
commit a68f09ae43
21 changed files with 1323 additions and 0 deletions

40
package/diy/dkml/Makefile Normal file
View File

@ -0,0 +1,40 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dkml
PKG_VERSION:=1.0.3
PKG_RELEASE:=1
PKG_FLAGS:=hold essential nonshared
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
include $(INCLUDE_DIR)/package.mk
define Package/dkml
SECTION:=utils
CATEGORY:=Base system
TITLE:=iStoreOS DKML
DEPENDS:=+ubox
endef
define Package/dkml/description
iStoreOS dynamic kernel modules loader
endef
define Package/dkml/conffiles
/etc/config/kmods
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/dkml/install
$(INSTALL_DIR) $(1)/etc/config $(1)/etc/init.d
$(INSTALL_BIN) ./files/kmods.init $(1)/etc/init.d/kmods
$(INSTALL_BIN) ./files/kmods-unload.init $(1)/etc/init.d/kmods-unload
$(INSTALL_DATA) ./files/kmods.config $(1)/etc/config/kmods
endef
$(eval $(call BuildPackage,dkml))

View File

@ -0,0 +1,45 @@
#!/bin/sh /etc/rc.common
START=25
check_driver_bond() {
local kmod="$1"
ls /sys/module/$kmod/drivers/*/ | grep -Fq :
}
rmmod_r() {
local kmod="$1"
local holder
for holder in `ls /sys/module/$kmod/holders/`; do
rmmod $holder
done
rmmod $kmod
}
auto_unload() {
local function support keep kmod
config_get function "$1" function
config_get support "$1" support
keep=0
if [ -n "$function" ]; then
for kmod in $function; do
if check_driver_bond $kmod; then
keep=1
else
echo "auto rmmod $kmod" >>/dev/kmsg
rmmod_r $kmod
fi
done
fi
if [ "$keep" = "0" -a -n "$support" ]; then
for kmod in $support; do
rmmod $kmod 2>/dev/null
done
fi
}
boot() {
config_load kmods
config_foreach auto_unload auto_unload
}

View File

@ -0,0 +1,31 @@
config global 'kmods'
# list enable 'r8125'
# list enable 'r8168'
# config auto_unload 'amdgpu'
# option function 'amdgpu'
# option support ''
# config auto_unload 'i915'
# option function 'i915'
# option support ''
# config auto_unload 'radeon'
# option function 'radeon'
# option support ''
# config auto_unload 'rtw89'
# option function 'rtw_8851be rtw_8852ae rtw_8852be rtw_8852ce'
# option support 'rtw_8852c rtw_8852b rtw_8852a rtw_8851b rtw89pci rtw89core'
# config auto_unload 'mwifiex'
# option function 'mwifiex_pcie'
# option support 'mwifiex'
# config auto_unload 'ath10k'
# option function 'ath10k_pci'
# option support 'ath10k_core'
# config auto_unload 'x86_others'
# option function 'bnx2x mlx5_core i40e mpt3sas ixgbe'
# option support ''

View File

@ -0,0 +1,36 @@
#!/bin/sh /etc/rc.common
START=09
enable_kmod() {
local kmod="$1"
sed -i "/^blacklist $kmod\$/d" /etc/modules.conf
}
disable_kmod() {
local kmod="$1"
grep -q "^blacklist $kmod\$" /etc/modules.conf || {
[ -n "$(tail -c1 /etc/modules.conf)" ] && echo >> /etc/modules.conf
echo "blacklist $kmod" >> /etc/modules.conf
}
}
boot() {
local info kmod action p1 ignore
local enable="$( uci -q get kmods.kmods.enable )"
ls /etc/modules-pending.d/ 2>/dev/null | while read info; do
if echo "$enable" | grep -qFw "$info" ; then
action=enable_kmod
else
action=disable_kmod
fi
echo "$action.group $info" >>/dev/kmsg
while read p1 ignore; do
kmod=$(echo "$p1" | grep -o '^[^#]*')
if [[ -n "$kmod" ]]; then
echo "$action $kmod" >>/dev/kmsg
$action $kmod
fi
done < "/etc/modules-pending.d/$info"
done
}

View File

@ -0,0 +1,58 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=grub-conf
PKG_VERSION:=1.0.0
PKG_RELEASE:=2
PKG_FLAGS:=hold nonshared
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
include $(INCLUDE_DIR)/package.mk
define Package/grub-conf
CATEGORY:=Boot Loaders
SECTION:=boot
TITLE:=iStoreOS GRUB configure
DEPENDS:=@TARGET_x86 +grub2-editenv
endef
define Package/grub-conf/description
iStoreOS GRUB configure
endef
define Package/grub-conf/conffiles
/etc/config/grub
endef
define Package/iommu-conf
CATEGORY:=Boot Loaders
SECTION:=boot
TITLE:=iStoreOS GRUB IOMMU configure
DEPENDS:=@TARGET_x86_64 +grub-conf
endef
define Package/iommu-conf/description
iStoreOS IOMMU configure for PCI passthrough
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/grub-conf/install
$(INSTALL_DIR) $(1)/etc/config $(1)/etc/init.d $(1)/etc/uci-defaults $(1)/etc/grub.cfg.d
$(INSTALL_BIN) ./files/grub.init $(1)/etc/init.d/grub
$(INSTALL_DATA) ./files/grub.config $(1)/etc/config/grub
$(INSTALL_DATA) ./files/grub.default $(1)/etc/uci-defaults/grub
$(INSTALL_DATA) ./files/cmdline.grubcfg $(1)/etc/grub.cfg.d/02-cmdline.cfg
endef
define Package/iommu-conf/install
$(INSTALL_DIR) $(1)/etc/grub.cfg.d
$(INSTALL_DATA) ./files/iommu.grubcfg $(1)/etc/grub.cfg.d/01-iommu.cfg
endef
$(eval $(call BuildPackage,grub-conf))
$(eval $(call BuildPackage,iommu-conf))

View File

@ -0,0 +1 @@
set cmdline_ext="$cmdline_ext $CUSTOM_CMDLINE"

View File

@ -0,0 +1,8 @@
config iommu 'iommu'
option enabled '0'
# option cmdline 'intel_iommu=on iommu=pt'
config cmdline
option enabled '0'
option cmdline 'usb-storage.quirks=0bda:9210:u,0080:a001:u'
option comment 'Disable UAS for some NVMe/SATA to USB Adapters'

View File

@ -0,0 +1,10 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@grub[-1]
add ucitrack grub
set ucitrack.@grub[-1].init=grub
commit ucitrack
EOF
exit 0

View File

@ -0,0 +1,48 @@
#!/bin/sh /etc/rc.common
START=99
boot() {
return 0
}
grub_iommu_conf() {
local enabled cmdline
config_get enabled iommu enabled 0
if [ "$enabled" = 1 ]; then
config_get cmdline iommu cmdline
if [ -z "$cmdline" ]; then
if grep -Fq Intel /proc/cpuinfo; then
cmdline="intel_iommu=on iommu=pt"
else
cmdline="amd_iommu=on iommu=pt"
fi
fi
grub-editenv - set IOMMU_CMDLINE="$cmdline"
else
grub-editenv - unset IOMMU_CMDLINE
fi
}
grub_concat_cmdlines() {
local enabled cmdline
config_get_bool enabled "$1" enabled 0
[ "$enabled" = 1 ] || return 0
config_get cmdline "$1" cmdline
[ -n "$cmdline" ] || return 0
CUSTOM_CMDLINE="$CUSTOM_CMDLINE $cmdline"
}
start() {
local enabled cmdline
config_load grub
[ -e /etc/grub.cfg.d/01-iommu.cfg ] && grub_iommu_conf
CUSTOM_CMDLINE=""
config_foreach grub_concat_cmdlines cmdline
if [ -n "$CUSTOM_CMDLINE" ]; then
grub-editenv - set CUSTOM_CMDLINE="${CUSTOM_CMDLINE## }"
else
grub-editenv - unset CUSTOM_CMDLINE
fi
update-grub || true
}

View File

@ -0,0 +1 @@
set cmdline_ext="$cmdline_ext $IOMMU_CMDLINE"

View File

@ -0,0 +1,13 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI for OTA upgrade
LUCI_DEPENDS:=+curl
LUCI_PKGARCH:=all
PKG_VERSION:=1.4.0
PKG_RELEASE:=2
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -0,0 +1,177 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2021 jjm2473
]]--
module("luci.controller.admin.ota",package.seeall)
require "luci.util"
function index()
if luci.sys.call("ota >/dev/null 2>&1") ~= 0 then
return
end
entry({"admin", "system", "ota"}, post_on({ apply = "1" }, "action_ota"), _("OTA"), 69)
entry({"admin", "system", "ota", "check"}, post("action_check"))
entry({"admin", "system", "ota", "download"}, post("action_download"))
entry({"admin", "system", "ota", "progress"}, call("action_progress"))
entry({"admin", "system", "ota", "cancel"}, post("action_cancel"))
end
local function ota_exec(cmd)
local nixio = require "nixio"
local os = require "os"
local fs = require "nixio.fs"
local rshift = nixio.bit.rshift
local oflags = nixio.open_flags("wronly", "creat")
local lock, code, msg = nixio.open("/var/lock/ota_api.lock", oflags)
if not lock then
return 255, "", "Open stdio lock failed: " .. msg
end
-- Acquire lock
local stat, code, msg = lock:lock("tlock")
if not stat then
lock:close()
return 255, "", "Lock stdio failed: " .. msg
end
local r = os.execute(cmd .. " >/var/log/ota.stdout 2>/var/log/ota.stderr")
local e = fs.readfile("/var/log/ota.stderr")
local o = fs.readfile("/var/log/ota.stdout")
fs.unlink("/var/log/ota.stderr")
fs.unlink("/var/log/ota.stdout")
lock:lock("ulock")
lock:close()
e = e or ""
if r == 256 and e == "" then
e = "os.execute failed, is /var/log full or not existed?"
end
return rshift(r, 8), o or "", e or ""
end
local function image_supported(image)
return (os.execute("sysupgrade -T %q >/dev/null" % image) == 0)
end
function action_ota()
local image_tmp = "/tmp/firmware.img"
local http = require "luci.http"
if http.formvalue("apply") == "1" then
if not luci.dispatcher.test_post_security() then
return
end
if not image_supported(image_tmp) then
luci.template.render("admin_system/ota", {image_invalid = true})
return
end
local keep = (http.formvalue("keep") == "1") and "" or "-n"
luci.template.render("admin_system/ota_flashing", {
title = luci.i18n.translate("Flashing…"),
msg = luci.i18n.translate("The system is flashing 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 = (#keep > 0) and "192.168.1.1" or nil
})
fork_exec("sleep 1; killall dropbear uhttpd; sleep 1; /sbin/sysupgrade %s %q" %{ keep, image_tmp })
else
luci.template.render("admin_system/ota")
end
end
function action_check()
local r,o,e = ota_exec("ota check")
local ret = {
code = 500,
msg = "Unknown"
}
if r == 0 or r == 1 or r == 2 then
ret.code = r
ret.msg = o
else
ret.code = 500
ret.msg = e
end
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
end
function action_download()
local r,o,e = ota_exec("ota download")
local ret = {
code = 500,
msg = "Unknown"
}
if r == 0 then
ret.code = 0
ret.msg = ""
else
ret.code = 500
ret.msg = e
end
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
end
function action_progress()
local r,o,e = ota_exec("ota progress")
local ret = {
code = 500,
msg = "Unknown"
}
if r == 0 then
ret.code = 0
ret.msg = "done"
elseif r == 1 or r == 2 or r == 254 then
ret.code = r
ret.msg = o
else
ret.code = 500
ret.msg = e
end
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
end
function action_cancel()
local r,o,e = ota_exec("ota cancel")
local ret = {
code = 500,
msg = "Unknown"
}
if r == 0 then
ret.code = 0
ret.msg = "ok"
else
ret.code = 500
ret.msg = e
end
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
end
function fork_exec(command)
local pid = nixio.fork()
if pid > 0 then
return
elseif pid == 0 then
-- change to root dir
nixio.chdir("/")
-- patch stdin, out, err to /dev/null
local null = nixio.open("/dev/null", "w+")
if null then
nixio.dup(null, nixio.stderr)
nixio.dup(null, nixio.stdout)
nixio.dup(null, nixio.stdin)
if null:fileno() > 2 then
null:close()
end
end
-- replace with target command
nixio.exec("/bin/sh", "-c", command)
end
end

View File

@ -0,0 +1,240 @@
<%#
Licensed to the public under the Apache License 2.0.
-%>
<%+header%>
<%
local fs = require "nixio.fs"
-%>
<div class="cbi-map" id="cbi-ota">
<style>
#cbi-ota .state-ctl .state {
display: none !important;
padding: 0 !important;
margin: 0 !important;
border: 0 !important;
}
#cbi-ota .state-ctl.state-ctl-unchecked .state.state-unchecked,
#cbi-ota .state-ctl.state-ctl-checked .state.state-checked,
#cbi-ota .state-ctl.state-ctl-downloading .state.state-downloading,
#cbi-ota .state-ctl.state-ctl-downloaded .state.state-downloaded
{
display: inherit !important;
}
</style>
<h2 name="content"><%:OTA%></h2>
<div class="cbi-section state-ctl state-ctl-unchecked">
<div class="cbi-section-descr"><%:Check and upgrade firmware from the Internet%></div>
<% if image_invalid then %>
<div class="cbi-section-error"><%:The image file does not contain a supported format. Maybe try again later.%></div>
<% end %>
<div class="cbi-section-node">
<div class="state state-unchecked">
<form>
<div class="cbi-value">
<label class="cbi-value-title" id="check_result"></label>
<div class="cbi-value-field">
<button type="button" class="cbi-button cbi-button-reload" name="check"><%:Check update%></button>
<div class="cbi-value-description">Step 1/3: <%:Check update%></div>
</div>
</div>
</form>
</div>
<div class="state state-checked">
<form>
<div class="cbi-value">
<label class="cbi-value-title" id="download_result"><%:Found new firmware%></label>
<div class="cbi-value-field">
<button type="button" class="cbi-button cbi-button-apply" name="download"><%:Download firmware%></button>
<div class="cbi-value-description">Step 2/3: <%:Download firmware%></div>
</div>
</div>
</form>
</div>
<div class="state state-downloading">
<form>
<div class="cbi-value">
<label class="cbi-value-title" id="download_progress">0%</label>
<div class="cbi-value-field">
<button type="button" class="cbi-button cbi-button-reset" name="cancel"><%:Cancel download%></button>
<div class="cbi-value-description">Step 2/3: <%:Download firmware%></div>
</div>
</div>
</form>
</div>
<div class="state state-downloaded">
<% if fs.access("/usr/lib/lua/luci/controller/admin/system.lua") then %>
<form method="post" action="<%=url('admin/system/flashops/sysupgrade')%>" enctype="multipart/form-data">
<input type="hidden" name="token" value="<%=token%>" />
<input type="hidden" name="step" value="1" />
<div class="cbi-value">
<label class="cbi-value-title"><%:Firmware downloaded%></label>
<div class="cbi-value-field">
<input type="submit" class="cbi-button cbi-input-apply" value="<%:Flash image...%>" />
<div class="cbi-value-description">Step 3/3: <%:Flash image...%></div>
</div>
</div>
</form>
<% else %>
<form method="post" action="<%=url('admin/system/ota')%>">
<input type="hidden" name="apply" value="1" />
<input type="hidden" name="token" value="<%=token%>" />
<div class="cbi-value">
<label class="cbi-value-title" for="keep"><%:Keep settings and retain the current configuration%></label>
<div class="cbi-value-field">
<input type="checkbox" name="keep" value="1" id="keep" checked="checked" />
</div>
</div>
<div class="cbi-value cbi-value-last">
<label class="cbi-value-title"><%:Firmware downloaded%></label>
<div class="cbi-value-field">
<button type="submit" class="cbi-button cbi-input-apply"><%:Flash image%></button>
<div class="cbi-value-description">Step 3/3: <%:Flash image%></div>
</div>
</div>
</form>
<% end %>
</div>
</div>
<div class="state state-checked state-downloading state-downloaded">
<div class="cbi-section-descr">
<h2><%:The latest firmware%>:</h2>
<div id="upgrade_log"></div>
</div>
</div>
<div class="state state-unchecked">
<div class="cbi-section-descr">
<div id="history_log"></div>
</div>
</div>
</div>
<script>
(function(){
var csrfToken = "<%=token%>";
var check = document.querySelector('button[name="check"]');
var download = document.querySelector('button[name="download"]');
var cancel = document.querySelector('button[name="cancel"]');
var state_ctl = document.querySelector('.state-ctl');
var check_result = document.querySelector('#check_result');
var download_result = document.querySelector('#download_result');
var download_progress = document.querySelector('#download_progress');
var upgrade_log = document.querySelector('#upgrade_log');
var history_log = document.querySelector('#history_log');
var xhr_post = function(url, data, cb) {
data = data || {};
data.token = '<%=token%>';
new XHR().post(url, data, function(x, d){
cb && cb(x, x.status==200?JSON.parse(x.responseText):{code:500,msg:x.responseText});
});
};
var state_switch = function(from, to) {
state_ctl.classList.remove("state-ctl-" + from);
state_ctl.classList.add("state-ctl-" + to);
};
check.onclick = function(){
check.disabled = 'disabled';
check_result.innerText = "<%:Checking...%>";
xhr_post("<%=url('admin/system/ota/check')%>", {}, function(x, d){
check.disabled = undefined;
switch(d.code){
case 0:
case 2:
check_result.innerText = "";
upgrade_log.innerHTML = d.msg;
if (d.code == 0) {
state_switch("unchecked", "checked");
} else {
alert("<%:Found downloading firmware, will show progress%>");
download_progress.innerText = "<%:Downloading%>: ...";
cancel.disabled = 'disabled';
state_switch("unchecked", "downloading");
refresh_download_progress_timer = setTimeout(refresh_download_progress, 500);
}
break;
case 1:
check_result.innerText = "<%:Already the latest firmware%>";
history_log.innerHTML = '<h2><%:History Log%>:</h2>' + d.msg;
break;
default:
check_result.innerText = "<%:Check failed%>";
alert("<%:Check failed%>:\n"+d.msg);
}
});
};
var refresh_download_progress_paused = false;
var refresh_download_progress_timer = null;
var refresh_download_progress = function() {
if (refresh_download_progress_paused) {
refresh_download_progress_timer = setTimeout(refresh_download_progress, 500);
return;
}
XHR.get("<%=url('admin/system/ota/progress')%>", {}, function(x, d){
refresh_download_progress_timer = null;
switch(d.code){
case 0:
download_progress.innerText = "";
state_switch("downloading", "downloaded");
break;
case 1:
if (d.msg.startsWith('#') || d.msg.startsWith(' ') || d.msg.startsWith('-')) {
if (!refresh_download_progress_paused)
cancel.disabled = undefined;
if (d.msg.endsWith('%'))
download_progress.innerText = "<%:Downloading%>: "+d.msg.replaceAll(/[# ]/g, '');
else
download_progress.innerText = "<%:Downloading%>";
} else {
if (!refresh_download_progress_paused)
cancel.disabled = 'disabled';
download_progress.innerText = d.msg;
}
refresh_download_progress_timer = setTimeout(refresh_download_progress, 500);
break;
case 2:
download_result.innerText = "<%:Download canceled%>";
state_switch("downloading", "checked");
break;
case 254:
state_switch("downloading", "unchecked");
break;
default:
download_result.innerText = "<%:Download failed%>";
state_switch("downloading", "checked");
alert("<%:Download failed%>:"+d.msg);
}
});
};
download.onclick = function(){
download.disabled = 'disabled';
xhr_post("<%=url('admin/system/ota/download')%>", {}, function(x, d){
download.disabled = undefined;
switch(d.code){
case 0:
download_progress.innerText = "<%:Downloading%>: ...";
cancel.disabled = 'disabled';
state_switch("checked", "downloading");
refresh_download_progress_timer = setTimeout(refresh_download_progress, 500);
break;
default:
alert("<%:Download failed%>:"+d.msg);
}
});
};
cancel.onclick = function() {
cancel.disabled = 'disabled';
refresh_download_progress_paused = true;
xhr_post("<%=url('admin/system/ota/cancel')%>", {}, function(x, d){
refresh_download_progress_paused = false;
});
};
})();
</script>
</div>
<%+footer%>

View File

@ -0,0 +1,52 @@
<%#
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" />
<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 device...%>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,62 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "OTA"
msgstr ""
msgid "Already the latest firmware"
msgstr ""
msgid "Check update"
msgstr ""
msgid "Found new firmware"
msgstr ""
msgid "Download firmware"
msgstr ""
msgid "Cancel download"
msgstr ""
msgid "Firmware downloaded"
msgstr ""
msgid "Flash image..."
msgstr ""
msgid "Flash image"
msgstr ""
msgid "Checking..."
msgstr ""
msgid "Check failed"
msgstr ""
msgid "Downloading"
msgstr ""
msgid "Download canceled"
msgstr ""
msgid "Download failed"
msgstr ""
msgid "Upgrade firmware On the Air"
msgstr ""
msgid "Check and upgrade firmware from the Internet"
msgstr ""
msgid "The latest firmware"
msgstr ""
msgid "The image file does not contain a supported format. Maybe try again later."
msgstr ""
msgid "History Log"
msgstr ""
msgid "Found downloading firmware, will show progress"
msgstr ""

View File

@ -0,0 +1,62 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "OTA"
msgstr ""
msgid "Already the latest firmware"
msgstr ""
msgid "Check update"
msgstr ""
msgid "Found new firmware"
msgstr ""
msgid "Download firmware"
msgstr ""
msgid "Cancel download"
msgstr ""
msgid "Firmware downloaded"
msgstr ""
msgid "Flash image..."
msgstr ""
msgid "Flash image"
msgstr ""
msgid "Checking..."
msgstr ""
msgid "Check failed"
msgstr ""
msgid "Downloading"
msgstr ""
msgid "Download canceled"
msgstr ""
msgid "Download failed"
msgstr ""
msgid "Upgrade firmware On the Air"
msgstr ""
msgid "Check and upgrade firmware from the Internet"
msgstr ""
msgid "The latest firmware"
msgstr ""
msgid "The image file does not contain a supported format. Maybe try again later."
msgstr ""
msgid "History Log"
msgstr ""
msgid "Found downloading firmware, will show progress"
msgstr ""

View File

@ -0,0 +1,62 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "OTA"
msgstr "在线升级"
msgid "Already the latest firmware"
msgstr "已经是最新固件"
msgid "Check update"
msgstr "检查更新"
msgid "Found new firmware"
msgstr "发现新固件"
msgid "Download firmware"
msgstr "下载固件"
msgid "Cancel download"
msgstr "取消下载"
msgid "Firmware downloaded"
msgstr "固件已下载"
msgid "Flash image..."
msgstr "刷写固件..."
msgid "Flash image"
msgstr "刷写固件"
msgid "Checking..."
msgstr "检查中..."
msgid "Check failed"
msgstr "检查失败"
msgid "Downloading"
msgstr "下载中"
msgid "Download canceled"
msgstr "下载已取消"
msgid "Download failed"
msgstr "下载失败"
msgid "Upgrade firmware On the Air"
msgstr "在线升级固件"
msgid "Check and upgrade firmware from the Internet"
msgstr "通过网络检查和更新固件"
msgid "The latest firmware"
msgstr "最新固件"
msgid "The image file does not contain a supported format. Maybe try again later."
msgstr "镜像文件格式不支持或损坏。也许稍候再试试"
msgid "History Log"
msgstr "历史更新日志"
msgid "Found downloading firmware, will show progress"
msgstr "发现下载中的固件,将显示当前进度"

View File

@ -0,0 +1,242 @@
#!/bin/sh
# author jjm2473
mirrors() {
local url="$1"
case "$url" in
https://fw0.koolcenter.com/iStoreOS/*|\
https://fw.koolcenter.com/iStoreOS/*)
local path=$(echo "$url" | sed -E 's#^https?://[^/]+/(.*)#\1#')
# echo "https://dl2.istoreos.com/$path"
echo "https://dl.istoreos.com/$path"
;;
esac
echo "$url"
return 0
}
if [ -f /lib/upgrade/ota.sh ]; then
. /lib/upgrade/ota.sh
export_ota_url
fi
if [ -z "$OTA_URL_BASE" ]; then
echo "Unsupported device." >&2
exit 255
fi
WRLOCK=/var/lock/ota_background.lock
STLOCK=/var/lock/ota_status.lock
action=${1}
shift
sha256() {
sha256sum $1 | cut -d' ' -f1
}
alias fcurl='curl -L --fail --show-error'
download() {
local img=$1
local sum=$2
exec 300>$STLOCK
flock 300
touch /tmp/firmware.img.part
echo >/tmp/firmware.img.progress
rm -f /tmp/firmware.img.sha256sum
flock -u 300
if [ -f /tmp/firmware.img ]; then
echo "Checking existed firmware.img..." >> /tmp/firmware.img.progress
if [ "`sha256 /tmp/firmware.img`" = "$sum" ]; then
flock 300
echo $sum > /tmp/firmware.img.sha256sum;
rm -f /tmp/firmware.img.part
rm -f /tmp/firmware.img.progress
flock -u 300
return 0;
else
echo "Check failed, redownload" >> /tmp/firmware.img.progress
rm -f /tmp/firmware.img
fi
fi
local pid url
mirrors "$OTA_URL_BASE/$img" | while read; do
url="$REPLY"
echo "Try $url" >>/tmp/firmware.img.progress
flock 300
echo "#=#=#" >>/tmp/firmware.img.progress
fcurl --connect-timeout 5 --progress-bar -o /tmp/firmware.img.part "$url" 2>>/tmp/firmware.img.progress &
pid="$!"
echo "$pid" > /var/run/ota/download.pid
flock -u 300
if wait $pid; then
rm -f /var/run/ota/download.pid
echo "Checking new firmware.img.part..." > /tmp/firmware.img.progress
if [ "`sha256 /tmp/firmware.img.part`" = "$sum" ]; then
flock 300
mv /tmp/firmware.img.part /tmp/firmware.img && echo $sum > /tmp/firmware.img.sha256sum
rm -f /tmp/firmware.img.progress
flock -u 300
return 0
else
echo "Checksum failed!" >>/tmp/firmware.img.progress
fi
else
# on Terminated $? == 143, on Timeout $? == 28
local ecode=$?
echo >>/tmp/firmware.img.progress
if [ $ecode -eq 143 ]; then
echo "Canceled!" >> /tmp/firmware.img.progress
break
fi
fi
flock 300
sed -i '/\r/d' /tmp/firmware.img.progress
flock -u 300
done
rm -f /var/run/ota/download.pid
rm -f /tmp/firmware.img.part
return 1
}
lock_download() {
local lock="$WRLOCK"
exec 200>$lock
flock -n 200 || return
download $1 $2
flock -u 200
}
prepare_check() {
local line
local release=`grep 'DISTRIB_RELEASE=' /etc/openwrt_release | sed -E "s/.*'(.+)'.*/\1/"`
local revision=`grep 'DISTRIB_REVISION=' /etc/openwrt_release | sed -E "s/.*'(.+)'.*/\1/" | cut -d'-' -f1`
local current="$release-$revision"
local latest=0
cat /dev/null > /var/run/ota/ota.log
fcurl --connect-timeout 5 -o /var/run/ota/ota.latest "$OTA_URL_BASE/version.latest" || { rm -f /var/run/ota/ota.latest ; return 255; }
if head -1 /var/run/ota/ota.latest | grep -Fq "$current"; then
latest=1
current=""
fi
fcurl --connect-timeout 5 -o /var/run/ota/ota.index "$OTA_URL_BASE/version.index" || return 255;
head -5 /var/run/ota/ota.index | while read line; do
if [ -z "$line" -o "$line" = "$current" ]; then
break
fi
echo "<h3>`echo $line | sed 's/-/ /'`</h3><pre>" >> /var/run/ota/ota.log
fcurl --connect-timeout 1 "$OTA_URL_BASE/log/$line.log" >> /var/run/ota/ota.log 2>/dev/null
echo "</pre>" >> /var/run/ota/ota.log
done
[ "`wc -l /var/run/ota/ota.log | cut -d' ' -f1`" -eq 0 ] && return 1
[ "`wc -l /var/run/ota/ota.index | cut -d' ' -f1`" -gt 5 ] && echo "<a href=\"$OTA_URL_BASE/\" onclick=\"void(0)\" target=\"_blank\">More</a>" >> /var/run/ota/ota.log
fcurl --connect-timeout 1 "$OTA_URL_BASE/ota.footer.html" >> /var/run/ota/ota.log 2>/dev/null
return $latest
}
# 0: found newer fw, 1: already newest fw, 2: found running task, *: err
do_check() {
local ret=0
local lock="$WRLOCK"
exec 200>$lock
if flock -n 200; then
prepare_check
ret=$?
flock -u 200 >/dev/null 2>&1
elif [ -f /tmp/firmware.img.progress -o -f /tmp/firmware.img.sha256sum ]; then
ret=2
else
echo "lock failed!" >&2
return 255
fi
if [ "$ret" -eq 0 -o "$ret" -eq 2 ]; then
# output
echo "<pre>"
sed -E '1 s/^\[.*\]\((.+)\)\s*$/\1/' /var/run/ota/ota.latest
echo "</pre>"
echo "<br><h2>ChangeLog:</h2>"
fi
[ "$ret" -eq 0 -o "$ret" -eq 1 -o "$ret" -eq 2 ] && cat /var/run/ota/ota.log
return $ret
}
# async download
do_download(){
local img=`head -1 /var/run/ota/ota.latest | sed -E 's/.*\((.+)\).*/\1/'`
local sum=`head -3 /var/run/ota/ota.latest | grep '^SHA256: ' | cut -d' ' -f2`
[ -z "$img" -o -z "$sum" ] && { echo "do check first" >&2 ; return 254; }
lock_download $img $sum &
return 0
}
# 0: done, 1: downloading, 2: failed, 254: wrong state, *: err
do_progress() {
local sum=`head -3 /var/run/ota/ota.latest | grep '^SHA256: ' | cut -d' ' -f2`
[ -z "$sum" ] && { echo "do check first" >&2 ; return 254; }
[ -f /tmp/firmware.img.sha256sum ] && [ "`cat /tmp/firmware.img.sha256sum`" = "$sum" ] && return 0
[ -f /tmp/firmware.img.progress ] || { echo "download not in progress" >&2 ; return 254; }
[ -f /tmp/firmware.img.part ] && { cat /tmp/firmware.img.progress | tr '\r' '\n' | tail -n1; return 1; }
tail -1 /tmp/firmware.img.progress | grep -Fq 'Canceled!' && { echo "Canceled"; return 2; }
cat /tmp/firmware.img.progress | tr '\r' '\n' | grep -v '^$' | tail -n1 >&2
return 3
}
do_progress_locked() {
local ret
exec 300>$STLOCK
flock -s 300
do_progress
ret=$?
flock -u 300
return $ret
}
do_cancel() {
if [ -f /var/run/ota/download.pid ]; then
local pid=`cat /var/run/ota/download.pid`
if [ -n "$pid" ]; then
kill -TERM $pid;
while kill -0 $pid >/dev/null 2>&1; do
if ! sleep 1; then
break
fi
done
fi
fi
return 0
}
ota_init(){
mkdir -p /var/run/ota >/dev/null 2>&1 || true
}
usage() {
echo "usage: ota sub-command"
echo "where sub-command is one of:"
echo " check Check firmware upgrade"
echo " download Download latest firmware"
echo " progress Download progress"
echo " cancel Cancel download"
}
ota_init || exit 255
case $action in
"check")
do_check
;;
"download")
do_download
;;
"progress")
do_progress_locked
;;
"cancel")
do_cancel
;;
*)
usage
;;
esac

View File

@ -0,0 +1,45 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ntfs3-mount
PKG_RELEASE:=6
include $(INCLUDE_DIR)/package.mk
define Package/ntfs3-mount
SECTION:=utils
CATEGORY:=Utilities
SUBMENU:=Filesystem
TITLE:=NTFS mount script for Paragon NTFS3 driver
DEPENDS:=+kmod-fs-ntfs3
PKGARCH:=all
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/ntfs3-mount/install
$(INSTALL_DIR) $(1)/sbin $(1)/sbin/fs
$(INSTALL_BIN) ./files/mount.ntfs $(1)/sbin
$(LN) /sbin/mount.ntfs $(1)/sbin/fs/mount.ntfs
endef
define Package/ntfs3-mount/postinst
#!/bin/sh
FILE="$${IPKG_INSTROOT}/etc/filesystems"
ID="ntfs"
if ! [ -f $$FILE ]; then
echo "Create '$$FILE'."
touch "$$FILE"
fi
if ! grep -q -e '^'"$$ID"'$$' "$$FILE"; then
echo "Add '$$ID' to known filesystems."
echo "$$ID" >> "$$FILE"
fi
endef
$(eval $(call BuildPackage,ntfs3-mount))

View File

@ -0,0 +1,2 @@
#!/bin/sh
mount -t ntfs3 -o iocharset=utf8,force "$@" || mount -t ntfs3 -o iocharset=utf8,ro "$@"

View File

@ -0,0 +1,88 @@
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=ntfsprogs
PKG_RELEASE:=1
PKG_VERSION:=2021.8.22
PKG_SOURCE:=ntfs-3g_ntfsprogs-$(PKG_VERSION).tgz
PKG_SOURCE_URL:=https://www.tuxera.com/opensource/
PKG_HASH:=55b883aa05d94b2ec746ef3966cb41e66bed6db99f22ddd41d1b8b94bb202efb
PKG_LICENSE:=GPL-2.0 LGPL-2.0
PKG_LICENSE_FILES:=COPYING COPYING.LIB
PKG_FIXUP:=autoreconf
PKG_INSTALL:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)/description
Suite of NTFS utilities for doing neat things with NTFS.
Contains:
- mkntfs - Create an NTFS filesystem.
- ntfscat - Dump a file's content to the standard output.
- ntfsclone - Efficiently clone, backup, restore or rescue NTFS.
- ntfscluster - Locate the files which use the given sectors or clusters.
- ntfscmp - Compare two NTFS filesystems and tell the differences.
- ntfscp - Copy a file to an NTFS volume.
- ntfssecaudit - Display ownership and permissions, check consistency
- ntfsfix - Check and fix some common errors, clear the LogFile.
- ntfsinfo - Show information about NTFS or one of the files or directories within it.
- ntfslabel - Show, or set, an NTFS filesystem's volume label.
- ntfsls - List information about files in a directory residing on an NTFS.
- ntfsresize - Resize NTFS without losing data.
- ntfsundelete - Recover deleted files from NTFS.
- ntfsusermap - Define mapping of Windows accounts to Linux logins
endef
define Package/$(PKG_NAME)
SECTION:=utils
CATEGORY:=Utilities
URL:=http://www.tuxera.com
SUBMENU:=Filesystem
TITLE:=ntfsprogs from ntfs-3g
DEPENDS+= +libgcrypt +libuuid
CONFLICTS:=ntfs-3g ntfs-3g-utils
endef
CONFIGURE_ARGS += \
--enable-ntfsprogs \
--disable-ntfs-3g \
--enable-shared \
--enable-static \
--with-uuid
CONFIGURE_ARGS += --with-fuse=internal
TARGET_CPPFLAGS:=-I../include/fuse-lite $(TARGET_CPPFLAGS)
# redefine prepare to extract to our build dir
# apply patches
define Build/Prepare
rm -rf $(PKG_BUILD_DIR)/
mkdir -p $(PKG_BUILD_DIR)/
$(TAR) -xzf $(DL_DIR)/$(PKG_SOURCE) -C $(PKG_BUILD_DIR) --strip 1
$(Build/Patch)
endef
define Package/$(PKG_NAME)/install
[ -f $(PKG_INSTALL_DIR)/usr/sbin/mkntfs ] && [ -f $(PKG_INSTALL_DIR)/usr/bin/ntfsfix ]
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libntfs-3g.so.* $(1)/usr/lib/
$(INSTALL_DIR) $(1)/sbin
$(LN) /usr/sbin/mkntfs $(1)/sbin/mkfs.ntfs
$(INSTALL_DIR) $(1)/usr/bin
$(FIND) $(PKG_INSTALL_DIR)/usr/bin/ -type f ! -regex '.*[^/]*ntfs-3g[^/]*' -exec $(INSTALL_BIN) {} $(1)/usr/bin/ \;
$(INSTALL_DIR) $(1)/usr/sbin
$(FIND) $(PKG_INSTALL_DIR)/usr/sbin/ -type f ! -regex '.*[^/]mkfs\.ntfs[^/]*' -exec $(INSTALL_BIN) {} $(1)/usr/sbin/ \;
$(LN) /usr/sbin/mkntfs $(1)/usr/sbin/mkfs.ntfs
$(LN) /usr/bin/ntfsfix $(1)/usr/sbin/fsck.ntfs
endef
$(eval $(call BuildPackage,$(PKG_NAME)))