🛸 Sync 2024-01-10 01:02

This commit is contained in:
github-actions[bot] 2024-01-10 01:02:08 +08:00
parent 3a50341537
commit e078bb91d5
209 changed files with 34 additions and 5803 deletions

View File

@ -1,67 +0,0 @@
#
# Copyright (C) 2015-2016 OpenWrt.org
# Copyright (C) 2020 jjm2473@gmail.com
#
# This is free software, licensed under the GNU General Public License v3.
#
include $(TOPDIR)/rules.mk
PKG_ARCH_DDNSTO:=$(ARCH)
PKG_NAME:=ddnsto
PKG_VERSION:=3.0.4
PKG_RELEASE:=$(PKG_ARCH_DDNSTO)-7
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://fw.koolcenter.com/binary/ddnsto/
PKG_HASH:=486aa15a5e026b5a3aca72f1850746e127a7e86ef11db8a7c498dad29545eaf6
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-binary-$(PKG_VERSION)
PKG_BUILD_PARALLEL:=1
PKG_USE_MIPS16:=0
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=net
CATEGORY:=Network
SUBMENU:=Web Servers/Proxies
TITLE:=DDNS.to - the reverse proxy
DEPENDS:=
PKGARCH:=all
URL:=https://www.ddnsto.com/
endef
define Package/$(PKG_NAME)/description
DDNS.to is a reverse proxy
endef
define Package/$(PKG_NAME)/conffiles
/etc/config/ddnsto
endef
define Package/$(PKG_NAME)/postinst
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
[ -f /etc/uci-defaults/ddnsto ] && /etc/uci-defaults/ddnsto && rm -f /etc/uci-defaults/ddnsto
fi
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/config $(1)/etc/init.d $(1)/etc/uci-defaults
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ddnsto.$(PKG_ARCH_DDNSTO) $(1)/usr/sbin/ddnstod
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ddwebdav.$(PKG_ARCH_DDNSTO) $(1)/usr/sbin/ddwebdav
$(INSTALL_CONF) ./files/ddnsto.config $(1)/etc/config/ddnsto
$(INSTALL_BIN) ./files/ddnsto.init $(1)/etc/init.d/ddnsto
$(INSTALL_BIN) ./files/ddnsto.uci-default $(1)/etc/uci-defaults/ddnsto
$(LN) /usr/sbin/ddnstod $(1)/usr/sbin/ddnsto
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@ -1,49 +0,0 @@
#!/bin/sh
DEVICE_IDX=0
LOG_LEVEL=2
while getopts u:x:l: flag
do
case "${flag}" in
u) TOKEN=${OPTARG};;
x) DEVICE_IDX=${OPTARG};;
l) LOG_LEVEL=${OPTARG};;
esac
done
if [ -z "${TOKEN}" ]; then
logger "ddnsto: the token is empty, get token from https://www.ddnsto.com/ "
exit 2
fi
echo "ddnsto version device_id is is:"
/usr/sbin/ddnsto -u ${TOKEN} -w
_term() {
logger "ddnsto: SIGTERM"
killall ddnsto 2>/dev/null
killall ddwebdav 2>/dev/null
rm -f /tmp/.ddnsto.pid
rm -f /tmp/.ddnsto.status
rm -f /tmp/.ddnsto.up
exit
}
trap "_term;" SIGTERM
while true ; do
if ! pidof "ddnsto" > /dev/null ; then
logger "ddnsto try running"
/usr/sbin/ddnsto -u ${TOKEN} -x ${DEVICE_IDX} &
PID=$!
wait $PID
RET=$?
logger "ddnsto EXIT CODE: ${RET}"
if [ "${RET}" == "100" ]; then
logger "ddnsto token error, please set a correct token from https://www.ddnsto.com/ "
exit 100
fi
fi
sleep 20
done

View File

@ -1,5 +0,0 @@
config ddnsto
option enabled '0'
option feat_port '3033'
option feat_enabled '0'
option index '0'

View File

@ -1,45 +0,0 @@
#!/bin/sh /etc/rc.common
START=99
USE_PROCD=1
get_config() {
config_get_bool enabled $1 enabled 1
config_get_bool logger $1 logger 0
config_get token $1 token
config_get index $1 index 0
config_get_bool feat_enabled $1 feat_enabled 1
}
ddnsto_prepare() {
killall ddnstod 2>/dev/null
killall ddwebdav 2>/dev/null
}
stop_service() {
ddnsto_prepare
}
start_service() {
ddnsto_prepare
config_load ddnsto
config_foreach get_config ddnsto
if [ $enabled != 1 ]; then
return 1
fi
if [ -z "$token" ]; then
logger -t ddnsto -p warn "token not set"
return 1
fi
procd_open_instance
procd_set_param command /usr/sbin/ddnstod -u "$token" -x $index -F
[ "$logger" == 1 ] && procd_set_param stderr 1
procd_set_param respawn
procd_close_instance
}
service_triggers() {
procd_add_reload_trigger "ddnsto"
}

View File

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

View File

@ -1,223 +0,0 @@
#
# Copyright (C) 2017-2020 Ian Leonard <antonlacon@gmail.com>
# Copyright (C) 2018 Ted Hess <thess@kitschensync.net>
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=ffmpeg-remux
PKG_VERSION:=4.3.3
PKG_RELEASE:=1
PKG_SOURCE:=ffmpeg-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://ffmpeg.org/releases/
PKG_HASH:=9f0a68fbd74feb4e50dc220bddd59d84626774a53687fb737806ae00e5c6e9e6
PKG_MAINTAINER:=Ted Hess <thess@kitschensync.net>, \
Ian Leonard <antonlacon@gmail.com>
PKG_LICENSE:=LGPL-2.1-or-later GPL-2.0-or-later LGPL-3.0-or-later
PKG_LICENSE_FILES:=COPYING.GPLv2 COPYING.GPLv3 COPYING.LGPLv2.1 COPYING.LGPLv3
PKG_CPE_ID:=cpe:/a:ffmpeg:ffmpeg
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-x/ffmpeg-$(PKG_VERSION)
FFMPEG_REMUX_DECODERS:= \
mpeg1video \
mpeg2video \
mpeg4 \
mpegvideo \
h264 \
hevc \
vc1 \
FFMPEG_REMUX_MUXERS:= \
matroska \
h264 \
hevc \
mp4 \
mpeg1video \
mpeg2video \
mpegts \
ogg \
FFMPEG_REMUX_DEMUXERS:= \
avi \
h264 \
hevc \
matroska \
mov \
mpegps \
mpegts \
mpegvideo \
ogg \
rm \
vc1 \
wv \
FFMPEG_REMUX_PARSERS:= \
aac \
flac \
ac3 \
h264 \
hevc \
mpegaudio \
mpeg4video \
mpegvideo \
vc1 \
FFMPEG_REMUX_PROTOCOLS:= \
file pipe
include $(INCLUDE_DIR)/package.mk
define Package/ffmpeg-remux
TITLE:=FFmpeg remux
SECTION:=multimedia
CATEGORY:=Multimedia
URL:=https://ffmpeg.org/
DEPENDS+= +libpthread +zlib +libbz2
endef
define Package/ffmpeg-remux/description
FFmpeg remux only program
endef
# Strip off FPU notation
REAL_CPU_TYPE:=$(firstword $(subst +, ,$(CONFIG_CPU_TYPE)))
# Fixup cpu types recogized by ffmpeg configure
REAL_CPU_TYPE:=$(subst octeonplus,octeon+,$(REAL_CPU_TYPE))
FFMPEG_CONFIGURE:= \
CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS) $(FPIC)" \
LDFLAGS="$(TARGET_LDFLAGS)" \
./configure \
--enable-cross-compile \
--cross-prefix="$(TARGET_CROSS)" \
--arch="$(ARCH)" \
$(if $(REAL_CPU_TYPE),--cpu=$(call qstrip,$(REAL_CPU_TYPE)),) \
--target-os=linux \
--prefix="/usr" \
--pkg-config="pkg-config" \
--enable-shared \
--enable-pthreads \
--enable-zlib \
--disable-doc \
--disable-debug \
\
--disable-lzma \
--disable-vaapi \
--disable-vdpau \
--disable-outdevs
ifeq ($(CONFIG_SOFT_FLOAT),y)
FFMPEG_CONFIGURE+= \
--disable-altivec \
--disable-vsx \
--disable-power8 \
--disable-armv5te \
--disable-armv6 \
--disable-armv6t2 \
--disable-fast-unaligned \
--disable-runtime-cpudetect
else ifneq ($(findstring arm,$(CONFIG_ARCH))$(findstring aarch64,$(CONFIG_ARCH)),)
FFMPEG_CONFIGURE+= \
--disable-runtime-cpudetect
# XXX: GitHub issue 3320 ppc cpu with fpu but no altivec (WNDR4700)
else ifneq ($(findstring powerpc,$(CONFIG_ARCH)),)
FFMPEG_CONFIGURE+= \
--disable-altivec
endif
# selectively disable optimizations according to arch/cpu type
ifneq ($(findstring arm,$(CONFIG_ARCH)),)
FFMPEG_CONFIGURE+= --enable-lto
ifneq ($(findstring vfp,$(CONFIG_CPU_TYPE)),)
FFMPEG_CONFIGURE+= --enable-vfp
else
FFMPEG_CONFIGURE+= --disable-vfp
endif
ifneq ($(findstring neon,$(CONFIG_CPU_TYPE)),)
FFMPEG_CONFIGURE+= \
--enable-neon \
--enable-vfp
else
FFMPEG_CONFIGURE+= --disable-neon
endif
endif
ifneq ($(findstring aarch64,$(CONFIG_ARCH)),)
FFMPEG_CONFIGURE+= \
--enable-lto \
--enable-neon \
--enable-vfp
endif
ifeq ($(ARCH),x86_64)
FFMPEG_CONFIGURE+= --enable-lto
endif
ifeq ($(CONFIG_FFMPEG_X86ASM),y)
FFMPEG_CONFIGURE += --enable-x86asm
else
FFMPEG_CONFIGURE += --disable-x86asm
endif
FFMPEG_ENABLE= \
$(foreach c, $(2), \
--enable-$(1)="$(c)" \
)
FFMPEG_CONFIGURE+= \
--enable-hardcoded-tables \
--disable-static \
--libdir="/usr/lib/remux" \
--enable-rpath \
\
--disable-ffplay \
--disable-alsa \
--disable-iconv \
--disable-sndio \
--disable-schannel \
--disable-sdl2 \
--disable-securetransport \
--disable-xlib \
--disable-v4l2-m2m \
--disable-avdevice \
--disable-postproc \
--disable-swresample \
--disable-swscale \
--disable-everything \
$(call FFMPEG_ENABLE,decoder,$(FFMPEG_REMUX_DECODERS)) \
$(call FFMPEG_ENABLE,parser,$(FFMPEG_REMUX_PARSERS)) \
$(call FFMPEG_ENABLE,demuxer,$(FFMPEG_REMUX_DEMUXERS)) \
$(call FFMPEG_ENABLE,muxer,$(FFMPEG_REMUX_MUXERS)) \
$(call FFMPEG_ENABLE,protocol,$(FFMPEG_REMUX_PROTOCOLS))
ifneq ($(CONFIG_TARGET_x86),)
TARGET_CFLAGS+= -fomit-frame-pointer
endif
define Build/Configure
( cd $(PKG_BUILD_DIR); $(FFMPEG_CONFIGURE) )
endef
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) \
DESTDIR="$(PKG_INSTALL_DIR)" \
all install
endef
define Package/ffmpeg-remux/install
$(INSTALL_DIR) $(1)/usr/lib/remux
$(INSTALL_DIR) $(1)/usr/bin
$(CP) $(PKG_INSTALL_DIR)/usr/lib/remux/lib{avcodec,avfilter,avformat,avutil}.so.* $(1)/usr/lib/remux/
$(CP) $(PKG_INSTALL_DIR)/usr/bin/ffmpeg $(1)/usr/bin/remux
endef
$(eval $(call BuildPackage,ffmpeg-remux))

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2021 易有云团队
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,4 +0,0 @@
# iStore
## Introduce
The iStore is a app store for OpenWRT, it is implemented using Shell scripts, only depends on OpenWRT standard components, and does not contain binary files itself

View File

@ -1,51 +0,0 @@
# iStore
## 介绍
iStore 是一个[开源](https://github.com/linkease/istore)且标准的 OpenWRT 软件中心实现。
是属于易有云团队的固件 [iStoreOS](https://github.com/istoreos) 的一部分。
iStore 的设计目标:
1. 方便用户安装插件
2. 每个插件都有教程,方便初学者入门使用插件
3. 适配所有的 OpenWRT 皮肤,以及移动端
4. 全部基于 OpenWRT 的标准接口开发,不用以前 KoolShare LEDE 的特有的插件风格的软件中心
iStore 的无法弥补的缺陷:
1. 因为 OpenWRT 版本特别多,导致不同平台的插件依赖不一样。所以即使你的系统能安装 iStoreiStore 里面的插件不一定能安装
2. 我们需要固件开发者自主集成 iStore并解决 iStore 里面的各种插件的依赖
我们建议固件开发者集成 iStore这样固件开发者只需要发布一个精简固件用户可以按需安装自己喜欢的插件。还能共享插件的教程独立更新某个插件版本。
> 21版本的固件安装 iStore 需要依赖 `luci-compat`
## 安装 iStore 到 OpenWRT 官方固件
只支持 x86_64 和 arm64 设备。
```
opkg update || exit 1
cd /tmp
wget https://github.com/linkease/openwrt-app-actions/raw/main/applications/luci-app-systools/root/usr/share/systools/istore-reinstall.run
chmod 755 istore-reinstall.run
./istore-reinstall.run
```
## 集成到自己编译的固件中
iStore 官方的软件仓库支持 `x86_64``arm64` 两个架构,这两个架构的基于 **OpenWRT** 固件都可以直接集成 iStore
只需在固件编译目录下执行:
```shell
echo >> feeds.conf.default
echo 'src-git istore https://github.com/linkease/istore;main' >> feeds.conf.default
./scripts/feeds update istore
./scripts/feeds install -d y -p istore luci-app-store
```
然后正常编译固件即可
## 功能预览
![istore-preview.png](./preview/istore-preview.png)

View File

@ -1,150 +0,0 @@
### 路由器端API
0. 获取csrfToken用于POST请求
```
GET /cgi-bin/luci/admin/store/token
{"token":"xxx"}
```
1. 已安装软件列表
```
GET /cgi-bin/luci/admin/store/installed
[
{
"description": "DDNS.TO内网穿透",
"tags": [
"net",
"tool"
],
"entry": "/cgi-bin/luci/admin/services/ddnsto",
"author": "xiaobao",
"depends": [
"ddnsto",
"luci-app-ddnsto",
"luci-i18n-ddnsto-zh-cn"
],
"title": "DDNS.TO",
"time": 1629356347,
"release": 1,
"website": "https://www.ddnsto.com/",
"name": "ddnsto",
"version": "1.0.0"
}
]
```
2. 安装软件
```
POST /cgi-bin/luci/admin/store/install
token=xxx&package=upnp
{"code":0, "stdout":"", "stderr":""}
```
3. 更新软件
```
POST /cgi-bin/luci/admin/store/upgrade
token=xxx&package=upnp
{"code":0, "stdout":"", "stderr":""}
```
4. 卸载软件
```
POST /cgi-bin/luci/admin/store/remove
token=xxx&package=upnp
{"code":0, "stdout":"", "stderr":""}
```
5. 刷新可用软件列表
```
POST /cgi-bin/luci/admin/store/update
token=xxx
{"code":0, "stdout":"", "stderr":""}
```
6. 查询特定软件状态
```
GET /cgi-bin/luci/admin/store/status?package=ddnsto
{
"description": "DDNS.TO内网穿透",
"tags": [
"net",
"tool"
],
"entry": "/cgi-bin/luci/admin/services/ddnsto",
"author": "xiaobao",
"depends": [
"ddnsto",
"luci-app-ddnsto",
"luci-i18n-ddnsto-zh-cn"
],
"installed": true,
"title": "DDNS.TO",
"time": "1629356347",
"release": 1,
"website": "https://www.ddnsto.com/",
"name": "ddnsto",
"version": "1.0.0"
}
{"installed":false}
```
7. 任务状态(日志)
```
GET /cgi-bin/luci/admin/store/log
{
"stdout": "Installing app-meta-ddnsto (1.0.0) to root...\nDownloading http://192.168.9.168:9999/packages/aarch64_cortex-a53/meta/app-meta-ddnsto_1.0.0_all.ipk\nConfiguring app-meta-ddnsto.\n",
"stderr": "",
"code": 206
}
{"stdout":"","stderr":"","code":0}
```
8. 上传安装
```
POST /cgi-bin/luci/admin/store/upload
(文件上传表单,支持文件扩展名".ipk,.run")
{"code":0, "stdout":"", "stderr":""}
```
9. 检查iStore自身更新
```
GET /cgi-bin/luci/admin/store/check_self_upgrade
{"code":500, "msg":"Internal Error"}
{"code":200, "msg":"1.1.2"}
{"code":304, "msg":""}
```
1. 更新iStore自身
> 检查iStore自身更新接口返回code为200时才调用这个接口
```
POST /cgi-bin/luci/admin/store/do_self_upgrade
token=xxx
{"code":0, "stdout":"", "stderr":""}
```
2. 枚举块设备
```
GET /cgi-bin/luci/admin/store/get_block_devices
{"code":500, "msg":"Unable to execute block utility"}
{"code":200, "data":{"sda1":{"dev":"\/dev\/sda1","uuid":"f54566dd-ec58-4e24-9451-bbf75834add3","version":"1.0","type":"ext4","size":"238.46 GB"},"mmcblk0p2":{"dev":"\/dev\/mmcblk0p2","uuid":"dba3d0dc-f072-4e81-a0ac-ac35197fb286","version":"1.0","label":"etc","mount":"\/overlay","type":"ext4","size":"6.87 GB"},"mmcblk0p1":{"dev":"\/dev\/mmcblk0p1","uuid":"8f9564a1-68006e25-c4c26df6-de88ef16","version":"4.0","mount":"\/rom","type":"squashfs","size":"127.99 MB"}}}
```

View File

@ -1,39 +0,0 @@
# Copyright (C) 2016 Openwrt.org
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI based ipk store
LUCI_DESCRIPTION:=luci-app-store is a ipk store developed by LinkEase team
LUCI_DEPENDS:=+curl +opkg +luci-lib-ipkg +tar +coreutils +coreutils-stat +libuci-lua +mount-utils +luci-lib-taskd
LUCI_EXTRA_DEPENDS:=luci-lib-taskd (>=1.0.17)
LUCI_PKGARCH:=all
PKG_VERSION:=0.1.14-2
# PKG_RELEASE MUST be empty for luci.mk
PKG_RELEASE:=
ISTORE_UI_VERSION:=0.1.14
ISTORE_UI_RELEASE:=2
PKG_HASH:=4d20ffeabfe6572b01e0bedd860043ec0dbd6f2f63aaf0ee58caeb851df18e73
PKG_SOURCE_URL_FILE:=v$(ISTORE_UI_VERSION)-$(ISTORE_UI_RELEASE).tar.gz
PKG_SOURCE:=istore-ui-$(PKG_SOURCE_URL_FILE)
PKG_SOURCE_URL:=https://github.com/linkease/istore-ui/archive/refs/tags
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
TARGET_CONFIGURE_OPTS= FRONTEND_DIST="$(BUILD_DIR)/istore-ui-$(ISTORE_UI_VERSION)-$(ISTORE_UI_RELEASE)/app-store-ui/src/dist" APP_STORE_VERSION="$(PKG_VERSION)"
TARGET_CONFIGURE_OPTS+= SED="$(SED)"
define Package/luci-app-store/conffiles
/etc/.app_store.id
/etc/config/istore
endef
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -1,3 +0,0 @@
# luci-app-store
OpenWRT应用商店

View File

@ -1,759 +0,0 @@
module("luci.controller.store", package.seeall)
local myopkg = "is-opkg"
local is_backup = "/usr/libexec/istore/backup"
local page_index = {"admin", "store", "pages"}
function index()
local function store_api(action, onlypost)
local e = entry({"admin", "store", action}, onlypost and post("store_action", {action = action}) or call("store_action", {action = action}))
e.dependent = false -- 父节点不是必须的
e.leaf = true -- 没有子节点
end
local action
entry({"admin", "store"}, call("redirect_index"), _("iStore"), 31)
entry({"admin", "store", "pages"}, call("store_index")).leaf = true
if nixio.fs.access("/usr/lib/lua/luci/view/store/main_dev.htm") then
entry({"admin", "store", "dev"}, call("store_dev")).leaf = true
end
entry({"admin", "store", "token"}, call("store_token"))
entry({"admin", "store", "log"}, call("store_log"))
entry({"admin", "store", "uid"}, call("action_user_id"))
entry({"admin", "store", "upload"}, post("store_upload"))
entry({"admin", "store", "check_self_upgrade"}, call("check_self_upgrade"))
entry({"admin", "store", "do_self_upgrade"}, post("do_self_upgrade"))
entry({"admin", "store", "toggle_docker"}, post("toggle_docker"))
for _, action in ipairs({"update", "install", "upgrade", "remove"}) do
store_api(action, true)
end
for _, action in ipairs({"status", "installed"}) do
store_api(action, false)
end
if nixio.fs.access("/usr/libexec/istore/backup") then
entry({"admin", "store", "get_support_backup_features"}, call("get_support_backup_features"))
entry({"admin", "store", "light_backup"}, post("light_backup"))
entry({"admin", "store", "get_light_backup_file"}, call("get_light_backup_file"))
entry({"admin", "store", "local_backup"}, post("local_backup"))
entry({"admin", "store", "light_restore"}, post("light_restore"))
entry({"admin", "store", "local_restore"}, post("local_restore"))
entry({"admin", "store", "get_backup_app_list_file_path"}, call("get_backup_app_list_file_path"))
entry({"admin", "store", "get_backup_app_list"}, call("get_backup_app_list"))
entry({"admin", "store", "get_available_backup_file_list"}, call("get_available_backup_file_list"))
entry({"admin", "store", "set_local_backup_dir_path"}, post("set_local_backup_dir_path"))
entry({"admin", "store", "get_local_backup_dir_path"}, call("get_local_backup_dir_path"))
entry({"admin", "store", "get_block_devices"}, call("get_block_devices"))
end
end
local function user_id()
local jsonc = require "luci.jsonc"
local json_parse = jsonc.parse
local fs = require "nixio.fs"
local data = fs.readfile("/etc/.app_store.id")
local id
if data ~= nil then
id = json_parse(data)
end
if id == nil then
fs.unlink("/etc/.app_store.id")
id = {arch="",uid=""}
end
id.version = (fs.readfile("/etc/.app_store.version") or "?"):gsub("[\r\n]", "")
return id
end
local function user_config()
local uci = require "luci.model.uci".cursor()
local data = {
hide_docker = uci:get("istore", "istore", "hide_docker") == "1",
channel = uci:get("istore", "istore", "channel")
}
return data
end
local function vue_lang()
local i18n = require("luci.i18n")
local lang = i18n.translate("istore_vue_lang")
if lang == "istore_vue_lang" or lang == "" then
lang = "en"
end
return lang
end
local function is_exec(cmd, async)
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/istore.lock", oflags)
if not lock then
return 255, "", "Open lock failed: " .. msg
end
-- Acquire lock
local stat, code, msg = lock:lock("tlock")
if not stat then
lock:close()
return 255, "", "Lock failed: " .. msg
end
if async then
cmd = "/etc/init.d/tasks task_add istore " .. luci.util.shellquote(cmd)
end
local r = os.execute(cmd .. " >/var/log/istore.stdout 2>/var/log/istore.stderr")
local e = fs.readfile("/var/log/istore.stderr")
local o = fs.readfile("/var/log/istore.stdout")
fs.unlink("/var/log/istore.stderr")
fs.unlink("/var/log/istore.stdout")
lock:lock("ulock")
lock:close()
e = e or ""
if r == 256 and e == "" then
e = "os.execute exit code 1"
end
return rshift(r,8), o or "", e or ""
end
function redirect_index()
luci.http.redirect(luci.dispatcher.build_url(unpack(page_index)))
end
function store_index()
local fs = require "nixio.fs"
local features = { "_lua_force_array_" }
if fs.access("/usr/libexec/istore/backup") then
features[#features+1] = "backup"
end
if luci.sys.call("which docker >/dev/null 2>&1") == 0 then
features[#features+1] = "docker"
end
if luci.sys.call("[ -d /ext_overlay ] >/dev/null 2>&1") == 0 then
features[#features+1] = "sandbox"
end
if luci.sys.call("[ -f /www/luci-static/resources/luci.js ] >/dev/null 2>&1") == 0 then
features[#features+1] = "luci-js"
end
luci.template.render("store/main", {prefix=luci.dispatcher.build_url(unpack(page_index)),id=user_id(),lang=vue_lang(),user_config=user_config(),features=features})
end
function store_dev()
luci.template.render("store/main_dev", {prefix=luci.dispatcher.build_url(unpack({"admin", "store", "dev"})),id=user_id(),lang=vue_lang(),user_config=user_config()})
end
function store_log()
local fs = require "nixio.fs"
local code = 0
local e = fs.readfile("/var/log/istore.stderr")
local o = fs.readfile("/var/log/istore.stdout")
if o ~= nil then
code = 206
end
luci.http.prepare_content("application/json")
luci.http.write_json({code=code,stdout=o or "",stderr=e or ""})
end
function action_user_id()
luci.http.prepare_content("application/json")
luci.http.write_json(user_id())
end
function check_self_upgrade()
local ret = {
code = 500,
msg = "Unknown"
}
local r,o,e = is_exec(myopkg .. " check_self_upgrade")
if r ~= 0 then
ret.msg = e
else
ret.code = o == "" and 304 or 200
ret.msg = o:gsub("[\r\n]", "")
end
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
end
function do_self_upgrade()
local code, out, err, ret
code,out,err = is_exec(myopkg .. " do_self_upgrade")
ret = {
code = code,
stdout = out,
stderr = err
}
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
end
-- Internal action function
local function _action(exe, cmd, ...)
local pkg = ""
for k, v in pairs({...}) do
pkg = pkg .. " " .. luci.util.shellquote(v)
end
local c = "%s %s %s" %{ exe, cmd, pkg }
return is_exec(c, true)
end
function store_action(param)
local metadir = "/usr/lib/opkg/meta"
local metapkgpre = "app-meta-"
local code, out, err, ret
local fs = require "nixio.fs"
local ipkg = require "luci.model.ipkg"
local jsonc = require "luci.jsonc"
local json_parse = jsonc.parse
local action = param.action or ""
if action == "status" then
local pkg = luci.http.formvalue("package")
local metapkg = metapkgpre .. pkg
local meta = {}
local metadata = fs.readfile(metadir .. "/" .. pkg .. ".json")
if metadata ~= nil then
meta = json_parse(metadata) or {}
end
meta.installed = false
local status = ipkg.status(metapkg)
if next(status) ~= nil then
meta.installed=true
meta.time=tonumber(status[metapkg]["Installed-Time"])
end
ret = meta
elseif action == "installed" then
local itr = fs.dir(metadir)
local data = {}
if itr then
local pkg
for pkg in itr do
if pkg:match("^.*%.json$") then
local metadata = fs.readfile(metadir .. "/" .. pkg)
if metadata ~= nil then
local meta = json_parse(metadata)
if meta == nil then
local i18n = require("luci.i18n")
local name = pkg:gsub("^(.-)%.json$", "%1")
meta = {
name = name,
title = "{ " .. name .. " }",
author = "<UNKNOWN>",
version = "0.0.0",
description = i18n.translate("This package is broken! Please reinstall or uninstall it."),
depends = {},
tags = {"broken"},
broken = true,
}
end
local metapkg = metapkgpre .. meta.name
local status = ipkg.status(metapkg)
if next(status) ~= nil then
meta.time = tonumber(status[metapkg]["Installed-Time"])
data[#data+1] = meta
end
end
end
end
end
ret = data
else
local pkg = luci.http.formvalue("package")
local metapkg = pkg and (metapkgpre .. pkg) or ""
if action == "update" or pkg then
if action == "update" or action == "install" then
code, out, err = _action(myopkg, action, metapkg)
else
local meta = json_parse(fs.readfile(metadir .. "/" .. pkg .. ".json"))
local pkgs = {}
if meta == nil then
meta = {
depends = {},
}
end
if action == "upgrade" then
pkgs = meta.depends
table.insert(pkgs, metapkg)
code, out, err = _action(myopkg, action, unpack(pkgs))
else -- remove
for _, dep in ipairs(meta.depends) do
if dep ~= "docker-deps" and dep ~= "luci-js-deps" then
pkgs[#pkgs+1] = dep
end
end
table.insert(pkgs, metapkg)
code, out, err = _action(myopkg, action, unpack(pkgs))
fs.unlink("/tmp/luci-indexcache")
end
end
else
code = 400
err = "package is null"
end
ret = {
code = code,
stdout = out,
stderr = err
}
end
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
end
function store_token()
luci.http.prepare_content("application/json")
require "luci.template".render_string("{\"token\":\"<%=token%>\"}")
end
function store_upload()
local fd
local path
local finished = false
local tmpdir = "/tmp/is-root/tmp"
luci.http.setfilehandler(
function(meta, chunk, eof)
if not fd then
path = tmpdir .. "/" .. meta.file
nixio.fs.mkdirr(tmpdir)
fd = io.open(path, "w")
end
if chunk then
fd:write(chunk)
end
if eof then
fd:close()
finished = true
end
end
)
local code, out, err
out = ""
if finished then
if string.lower(string.sub(path, -4, -1)) == ".run" then
code, out, err = _action("sh", "-c", "ls -l \"%s\"; md5sum \"%s\" 2>/dev/null; chmod 755 \"%s\" && \"%s\"; RET=$?; rm -f \"%s\"; exit $RET" %{ path, path, path, path, path })
else
code, out, err = _action("sh", "-c", "opkg install \"%s\"; RET=$?; rm -f \"%s\"; exit $RET" %{ path, path })
end
else
code = 500
err = "upload failed!"
end
--nixio.fs.unlink(path)
local ret = {
code = code,
stdout = out,
stderr = err
}
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
end
local function split(str,reps)
local resultStrList = {}
string.gsub(str,'[^'..reps..']+',function (w)
table.insert(resultStrList,w)
end)
return resultStrList
end
local function ltn12_popen(command)
local fdi, fdo = nixio.pipe()
local pid = nixio.fork()
if pid > 0 then
fdo:close()
local close
return function()
local buffer = fdi:read(2048)
local wpid, stat = nixio.waitpid(pid, "nohang")
if not close and wpid and stat == "exited" then
close = true
end
if buffer and #buffer > 0 then
return buffer
elseif close then
fdi:close()
return nil
end
end
elseif pid == 0 then
nixio.dup(fdo, nixio.stdout)
fdi:close()
fdo:close()
nixio.exec("/bin/sh", "-c", command)
end
end
-- call get_support_backup_features
function get_support_backup_features()
local jsonc = require "luci.jsonc"
local error_ret = {code = 500, msg = "Unknown"}
local success_ret = {code = 200, msg = "Unknown"}
local r,o,e = is_exec(is_backup .. " get_support_backup_features")
if r ~= 0 then
error_ret.msg = e
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
success_ret.code = 200
success_ret.msg = jsonc.stringify(split(o,'\n'))
luci.http.prepare_content("application/json")
luci.http.write_json(success_ret)
end
end
-- post light_backup
function light_backup()
local jsonc = require "luci.jsonc"
local error_ret = {code = 500, msg = "Unknown"}
local success_ret = {code = 200,msg = "Unknown"}
local r,o,e = is_exec(is_backup .. " backup")
if r ~= 0 then
error_ret.msg = e
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
success_ret.code = 200
success_ret.msg = o:gsub("[\r\n]", "")
luci.http.prepare_content("application/json")
luci.http.write_json(success_ret)
end
end
-- call get_light_backup_file
function get_light_backup_file()
local light_backup_cmd = "tar -c %s | gzip 2>/dev/null"
local loght_backup_filelist = "/etc/istore/app.list"
local reader = ltn12_popen(light_backup_cmd:format(loght_backup_filelist))
luci.http.header('Content-Disposition', 'attachment; filename="light-backup-%s-%s.tar.gz"' % {
luci.sys.hostname(), os.date("%Y-%m-%d")})
luci.http.prepare_content("application/x-targz")
luci.ltn12.pump.all(reader, luci.http.write)
end
local function update_local_backup_path(path)
local uci = require "uci"
local fs = require "nixio.fs"
local x = uci.cursor()
local local_backup_path
if fs.access("/etc/config/istore") then
local_backup_path = x:get("istore","istore","local_backup_path")
else
--create config file
local f=io.open("/etc/config/istore","a+")
f:write("config istore \'istore\'\n\toption local_backup_path \'\'")
f:flush()
f:close()
end
if path ~= local_backup_path then
-- set uci config
x:set("istore","istore","local_backup_path",path)
x:commit("istore")
end
end
-- post local_backup
function local_backup()
local code, out, err, ret
local error_ret
local path = luci.http.formvalue("path")
if path ~= "" then
-- judge path
code,out,err = is_exec("findmnt -T " .. path .. " -o TARGET|sed -n 2p")
if out:gsub("[\r\n]", "") == "/" or out:gsub("[\r\n]", "") == "/tmp" then
-- error
error_ret = {code = 500, stderr = "Path Error,Can not be / or tmp."}
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
-- update local backup path
update_local_backup_path(path)
code,out,err = _action(is_backup, "backup", path)
ret = {
code = code,
stdout = out,
stderr = err
}
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
end
else
-- error
error_ret = {code = 500, stderr = "Path Unknown"}
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
end
end
-- post light_restore
function light_restore()
local fd
local path
local finished = false
local tmpdir = "/tmp/"
luci.http.setfilehandler(
function(meta, chunk, eof)
if not fd then
path = tmpdir .. "/" .. meta.file
fd = io.open(path, "w")
end
if chunk then
fd:write(chunk)
end
if eof then
fd:close()
finished = true
end
end
)
local code, out, err, ret
if finished then
is_exec("rm /etc/istore/app.list;tar -xzf " .. path .. " -C /")
nixio.fs.unlink(path)
if nixio.fs.access("/etc/istore/app.list") then
code,out,err = _action(is_backup, "restore")
ret = {
code = code,
stdout = out,
stderr = err
}
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
else
local error_ret = {code = 500, stderr = "File is error!"}
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
end
else
ret = {code = 500, stderr = "upload failed!"}
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
end
end
-- post local_restore
function local_restore()
local path = luci.http.formvalue("path")
local code, out, err, ret
if path ~= "" then
code,out,err = _action(is_backup, "restore", path)
ret = {
code = code,
stdout = out,
stderr = err
}
luci.http.prepare_content("application/json")
luci.http.write_json(ret)
else
-- error
error_ret = {code = 500, stderr = "Path Unknown"}
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
end
end
-- call get_backup_app_list_file_path
function get_backup_app_list_file_path()
local jsonc = require "luci.jsonc"
local error_ret = {code = 500, msg = "Unknown"}
local success_ret = {code = 200,msg = "Unknown"}
local r,o,e = is_exec(is_backup .. " get_backup_app_list_file_path")
if r ~= 0 then
error_ret.msg = e
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
success_ret.code = 200
success_ret.msg = o:gsub("[\r\n]", "")
luci.http.prepare_content("application/json")
luci.http.write_json(success_ret)
end
end
-- call get_backup_app_list
function get_backup_app_list()
local jsonc = require "luci.jsonc"
local error_ret = {code = 500, msg = "Unknown"}
local success_ret = {code = 200,msg = "Unknown"}
local r,o,e = is_exec(is_backup .. " get_backup_app_list")
if r ~= 0 then
error_ret.msg = e
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
success_ret.code = 200
success_ret.msg = jsonc.stringify(split(o,'\n'))
luci.http.prepare_content("application/json")
luci.http.write_json(success_ret)
end
end
-- call get_available_backup_file_list
function get_available_backup_file_list()
local jsonc = require "luci.jsonc"
local error_ret = {code = 500, msg = "Unknown"}
local success_ret = {code = 200,msg = "Unknown"}
local path = luci.http.formvalue("path")
local r,o,e
if path ~= "" then
-- update local backup path
update_local_backup_path(path)
r,o,e = is_exec(is_backup .. " get_available_backup_file_list " .. path)
if r ~= 0 then
error_ret.msg = e
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
success_ret.code = 200
success_ret.msg = jsonc.stringify(split(o,'\n'))
luci.http.prepare_content("application/json")
luci.http.write_json(success_ret)
end
else
-- set error code
error_ret.msg = "Path Unknown"
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
end
end
-- post set_local_backup_dir_path
function set_local_backup_dir_path()
local path = luci.http.formvalue("path")
local success_ret = {code = 200, msg = "Success"}
local error_ret = {code = 500, msg = "Unknown"}
if path ~= "" then
-- update local backup path
update_local_backup_path(path)
luci.http.prepare_content("application/json")
luci.http.write_json(success_ret)
else
-- set error code
error_ret.msg = "Path Unknown"
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
end
end
-- call get_local_backup_dir_path
function get_local_backup_dir_path()
local uci = require "uci"
local fs = require "nixio.fs"
local x = uci.cursor()
local local_backup_path = nil
local success_ret = {code = 200,msg = "Unknown"}
local error_ret = {code = 500, msg = "Path Unknown"}
if fs.access("/etc/config/istore") then
local_backup_path = x:get("istore","istore","local_backup_path")
if local_backup_path == nil then
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
else
success_ret.msg = local_backup_path:gsub("[\r\n]", "")
luci.http.prepare_content("application/json")
luci.http.write_json(success_ret)
end
else
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
end
end
-- copy from /usr/lib/lua/luci/model/diskman.lua
local function byte_format(byte)
local suff = {"B", "KB", "MB", "GB", "TB"}
for i=1, 5 do
if byte > 1024 and i < 5 then
byte = byte / 1024
else
return string.format("%.2f %s", byte, suff[i])
end
end
end
-- copy from /usr/libexec/rpcd/luci
local function getBlockDevices()
local fs = require "nixio.fs"
local block = io.popen("/sbin/block info", "r")
if block then
local rv = {}
while true do
local ln = block:read("*l")
if not ln then
break
end
local dev = ln:match("^/dev/(.-):")
if dev then
local s = tonumber((fs.readfile("/sys/class/block/" .. dev .."/size")))
local e = {
dev = "/dev/" .. dev,
size = s and byte_format(s * 512)
}
local key, val = { }
for key, val in ln:gmatch([[(%w+)="(.-)"]]) do
e[key:lower()] = val
end
rv[dev] = e
end
end
block:close()
return rv
else
return
end
end
function get_block_devices()
local error_ret = {code = 500, msg = "Unable to execute block utility"}
local devices = getBlockDevices()
if devices ~= nil then
luci.http.prepare_content("application/json")
luci.http.write_json({code = 200, data = devices})
else
luci.http.prepare_content("application/json")
luci.http.write_json(error_ret)
end
end
function toggle_docker()
local uci = require "luci.model.uci".cursor()
local hide = luci.http.formvalue("hide")
uci:set("istore", "istore", "hide_docker", hide == "true" and "1" or "0")
uci:commit("istore")
luci.http.prepare_content("application/json")
luci.http.write_json({code = 200, msg = "Success"})
end

View File

@ -1,62 +0,0 @@
<%+header%>
<%
local jsonc = require "luci.jsonc"
%>
<script>
(function(){
var vue_prefix="<%=prefix%>";
var myurl = window.location.pathname;
window.addEventListener('popstate', function(){
if (myurl != window.location.pathname
&& window.location.pathname != vue_prefix
&& ! window.location.pathname.startsWith(vue_prefix+'/')) {
window.location.href = window.location.pathname;
}
});
window.vue_base = vue_prefix + '/';
// window.istore_api_base = "https://istore.linkease.com";
window.vue_lang_data = '/luci-static/istore/i18n/<%=lang%>.json?v=<%=id.version%>';
window.vue_lang = '<%=lang%>';
window.token = "<%=token%>";
window.device_id = {arch:"<%=id.arch%>",uid:"<%=id.uid%>",version:"<%=id.version%>"};
window.istore_features = <%=jsonc.stringify(features)%>.filter(f => f !== '_lua_force_array_');
window.istore_config = <%=jsonc.stringify(user_config or {})%>;
})();
</script>
<h2 name="content"><%:iStore%>
<a onclick="void(0)" href="https://github.com/linkease/istore/issues/22" target="_blank" style="text-decoration: none;">
v<%=id.version%>
</a>
</h2>
<link rel="stylesheet" href="/luci-static/istore/style.css?v=<%=id.version%>">
<div id="app">
</div>
<%+tasks/embed%>
<script>
(function() {
let beforeunloadRegistered = false;
window.istore_log = function(flush_menu_onclose) {
if (flush_menu_onclose && !beforeunloadRegistered) {
beforeunloadRegistered = true;
window.addEventListener("beforeunload", function(event) {
try { window.L.ui.menu.flushCache() } catch (e) { }
return true;
});
}
taskd.show_log("istore", true);
};
})();
<%
local taskd = require "luci.model.tasks"
local status = taskd.status("istore")
if status.running or status.exit_code ~= 404 then
-%>
window.istore_log(true);
<%
end
%>
</script>
<script type="module" crossorigin src="/luci-static/istore/index.js?v=<%=id.version%>"></script>
<%+footer%>

View File

@ -1,218 +0,0 @@
#!/bin/sh
# this script MUST supports executting without luci-app-store installed,
# so we can use this script to install luci-app-store itself
IS_ROOT=/tmp/is-root
DL_DIR=${IS_ROOT}/tmp/dl
LISTS_DIR_O=/tmp/opkg-lists
LISTS_DIR=${IS_ROOT}${LISTS_DIR_O}
OPKG_CONF_DIR=${IS_ROOT}/etc/opkg
FEEDS_SERVER=https://istore.linkease.com/repo
ARCH=`sed -n -e 's/^Architecture: *\([^ ]\+\) *$/\1/p' /rom/usr/lib/opkg/info/libc.control /usr/lib/opkg/info/libc.control 2>/dev/null | head -1`
# for istore self upgrade
ISTORE_PKG=luci-app-store
ISTORE_DEP_PKGS="luci-lib-taskd luci-lib-xterm taskd"
ISTORE_INDEX=https://istore.linkease.com/repo/all/store/Packages.gz
action=${1}
shift
is_init() {
mkdir -p ${DL_DIR} ${LISTS_DIR} ${IS_ROOT}/etc ${IS_ROOT}/var
cat /etc/opkg.conf | grep -Fv lists_dir | grep -Fv check_signature > ${IS_ROOT}/etc/opkg.conf
cp ${IS_ROOT}/etc/opkg.conf ${IS_ROOT}/etc/opkg_o.conf
echo >> ${IS_ROOT}/etc/opkg.conf
echo "lists_dir ext ${LISTS_DIR}" >> ${IS_ROOT}/etc/opkg.conf
# create opkg_o.conf for executting 'opkg update' with offline-root, so we don't overwrite system opkg list
echo >> ${IS_ROOT}/etc/opkg_o.conf
echo "lists_dir ext ${LISTS_DIR_O}" >> ${IS_ROOT}/etc/opkg_o.conf
cp -au /etc/opkg ${IS_ROOT}/etc/
[ -e ${IS_ROOT}/var/lock ] || ln -s /var/lock ${IS_ROOT}/var/lock
}
opkg_wrap() {
OPKG_CONF_DIR=${OPKG_CONF_DIR} opkg -f ${IS_ROOT}/etc/opkg.conf "$@"
}
fcurl() {
curl --fail --show-error "$@"
}
check_space() {
local free="$((`stat -c '%a * %S' -f /` >> 20 ))"
if [ "$free" -lt 1 ]; then
echo "Root disk full!" >&2
exit 1
fi
return 0
}
update() {
if [ -z "${ARCH}" ]; then
echo "Get architecture failed" >&2
return 1
fi
fcurl -o ${OPKG_CONF_DIR}/meta.conf "${FEEDS_SERVER}/all/meta.conf" && \
fcurl -o ${OPKG_CONF_DIR}/all.conf "${FEEDS_SERVER}/all/isfeeds.conf" && \
fcurl -o ${OPKG_CONF_DIR}/arch.conf "${FEEDS_SERVER}/${ARCH}/isfeeds.conf" || \
return 1
opkg -f ${IS_ROOT}/etc/opkg_o.conf --offline-root ${IS_ROOT} update
return 0
}
update_if_outdate() {
local idle_t=$((`date '+%s'` - `date -r ${IS_ROOT}/.last_force_ts '+%s' 2>/dev/null || echo '0'`))
[ $idle_t -gt ${1:-120} ] || return 2
update || return 1
touch ${IS_ROOT}/.last_force_ts
return 0
}
check_self_upgrade() {
local newest=`curl --connect-timeout 2 --max-time 5 -s ${ISTORE_INDEX} | gunzip | grep -FA10 "Package: ${ISTORE_PKG}" | grep -Fm1 'Version: ' | sed 's/^Version: //'`
local current=`grep -Fm1 'Version: ' /usr/lib/opkg/info/${ISTORE_PKG}.control | sed 's/^Version: //'`
if [ "v$newest" = "v" -o "v$current" = "v" ]; then
echo "Check version failed!" >&2
exit 255
fi
if [ "$newest" != "$current" ]; then
echo "$newest"
fi
return 0
}
do_self_upgrade_0() {
opkg_wrap upgrade ${ISTORE_DEP_PKGS} && opkg_wrap upgrade ${ISTORE_PKG}
}
do_self_upgrade() {
check_mtime || return 1
local newest=`curl --connect-timeout 2 --max-time 5 -s ${ISTORE_INDEX} | gunzip | grep -FA10 "Package: ${ISTORE_PKG}" | grep -Fm1 'Version: ' | sed 's/^Version: //'`
local current=`grep -Fm1 'Version: ' /usr/lib/opkg/info/${ISTORE_PKG}.control | sed 's/^Version: //'`
if [ "v$newest" = "v" -o "v$current" = "v" ]; then
echo "Check version failed!" >&2
return 1
fi
if [ "$newest" = "$current" ]; then
echo "Already the latest version!" >&2
return 1
fi
if opkg_wrap info ${ISTORE_PKG} | grep -qFm1 "Version: $newest"; then
do_self_upgrade_0 && return 0
update_if_outdate || return 1
do_self_upgrade_0
else
update_if_outdate || return 1
do_self_upgrade_0
fi
}
check_mtime() {
find ${OPKG_CONF_DIR}/arch.conf -mtime -1 2>/dev/null | grep -q . || update
}
wrapped_in_update() {
check_mtime || return 1
eval "$@" && return 0
update_if_outdate || return 1
eval "$@"
}
step_upgrade() {
local pkg
local pkgs=""
local metapkg=""
for pkg in $@; do
if [[ $pkg == app-meta-* ]]; then
metapkg="$metapkg $pkg"
else
pkgs="$pkgs $pkg"
fi
done
if [ -n "$pkgs" ]; then
opkg_wrap upgrade $pkgs || return 1
fi
if [ -n "$metapkg" ]; then
opkg_wrap upgrade $metapkg || return 1
fi
return 0
}
new_upgrade() {
check_mtime || return 1
local metapkg=`echo "$@" | sed 's/ /\n/g' | grep -F app-meta-`
if [ -z "$metapkg" ] || opkg_wrap info $metapkg | grep -qF not-installed ; then
true
else
update_if_outdate
fi
wrapped_in_update step_upgrade "$@"
}
remove() {
opkg_wrap --autoremove --force-removal-of-dependent-packages remove "$@"
}
usage() {
echo "usage: is-opkg sub-command [arguments...]"
echo "where sub-command is one of:"
echo " update Update list of available packages"
echo " upgrade <pkgs> Upgrade package(s)"
echo " install <pkgs> Install package(s)"
echo " remove <pkgs|regexp> Remove package(s)"
echo " info [pkg|regexp] Display all info for <pkg>"
echo " list-upgradable List installed and upgradable packages"
echo " check_self_upgrade Check iStore upgrade"
echo " do_self_upgrade Upgrade iStore"
echo " arch Show libc architecture"
echo " opkg sys opkg wrap"
}
is_init >/dev/null 2>&1
case $action in
"update")
update
;;
"install")
check_space
wrapped_in_update opkg_wrap install "$@"
;;
"upgrade")
new_upgrade "$@"
;;
"remove")
remove "$@" || remove "$@"
;;
"info")
opkg_wrap info "$@"
;;
"list-upgradable")
opkg_wrap list-upgradable
;;
"check_self_upgrade")
check_self_upgrade
;;
"do_self_upgrade")
check_space
do_self_upgrade
;;
"arch")
echo "$ARCH"
;;
"opkg")
opkg_wrap "$@"
;;
*)
usage
;;
esac

View File

@ -1,3 +0,0 @@
config istore 'istore'
option hide_docker '0'
# option channel 'istore'

View File

@ -1,23 +0,0 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2016 OpenWrt.org
START=45
boot() {
[ -s /etc/.app_store.id ] && return 0
ARCH=`/bin/is-opkg arch`
for iface in eth0 br-lan; do
if [ -e /sys/class/net/$iface/address ]; then
HASH=`md5sum /sys/class/net/$iface/address | cut -d ' ' -f1`
break
fi
done
if [ -z "$HASH" ]; then
HASH=`dd if=/dev/urandom bs=512 count=1 2>/dev/null | md5sum | cut -d ' ' -f1`
fi
echo "{\"arch\":\"${ARCH}\", \"uid\":\"${HASH}\"}" > /etc/.app_store.id
}

View File

@ -1,5 +0,0 @@
#!/bin/sh
/etc/init.d/istore boot
rm -rf /tmp/luci-indexcache /tmp/luci-modulecache

View File

@ -1,295 +0,0 @@
#!/bin/sh
#set -x
#IS_DEBUG=1
IS_ROOT=/tmp/is-backup
APP_LIST_FILE=/etc/istore/app.list
BACKUP_CONFIG_FILE=/etc/config/istore
action=${1}
shift
is_init() {
mkdir -p ${IS_ROOT}
}
opkg_list_installed_packages() {
target=$1
case $target in
"preinstalled")
OPKG_INFO_DIR="/rom/usr/lib/opkg/info"
;;
"userinstalled")
OPKG_INFO_DIR="/overlay/upper/usr/lib/opkg/info"
;;
"allinstalled")
OPKG_INFO_DIR="/usr/lib/opkg/info"
;;
*)
echo "invalid target"
exit
;;
esac
(cd $OPKG_INFO_DIR && find . -depth -maxdepth 1 -name "*.list" -type f | sed 's#^\./\(.*\)\.list$#\1#g')
}
ipk_build() {
PKG_NAME_TEMP=$1
IPK_OUTPUT_DIR=$2
UCI_BAK_DIR="/etc/istore/uci-defaults_bak/"
UCI_DEF_DIR="etc/uci-defaults"
OPKG_INFO_DIR="/usr/lib/opkg/info/"
[ -n "${PKG_NAME_TEMP}" ] || exit 1
#get real pkg name in opkg
PKG_NAME_TEMP=`cat ${IS_ROOT}/all_installed_package.list | sort -u | grep "^${PKG_NAME_TEMP}" | head -n 1`
[ -n "${PKG_NAME_TEMP}" ] || exit 1
PKG_NAME=`cat ${OPKG_INFO_DIR}${PKG_NAME_TEMP}.control | grep "^Package: " | cut -d ' ' -f2`
PKG_VER=`cat ${OPKG_INFO_DIR}${PKG_NAME}.control | grep "^Version: " | cut -d ' ' -f2`
PKG_ARCH=`cat ${OPKG_INFO_DIR}${PKG_NAME}.control | grep "^Architecture: " | cut -d ' ' -f2`
IPK_FILE_NAME="${PKG_NAME}_${PKG_VER}_${PKG_ARCH}"
rm -rf ${IS_ROOT}/${IPK_FILE_NAME}
mkdir -p ${IS_ROOT}/${IPK_FILE_NAME}
#(1)make CONTROL dir; (2)copy control file to dir
cd ${IS_ROOT}/${IPK_FILE_NAME}
mkdir -p CONTROL
for control_file in `ls ${OPKG_INFO_DIR}${PKG_NAME}.* | grep -v ".list$"`; do
file=${control_file##*/}
suffix=${file##*.}
cp ${control_file} CONTROL/${suffix}
done
#(1)make DATA depend dir; (2)copy uci-defaults_bak file to dir; (3)copy other file to dir
for pkgfile in `cat ${OPKG_INFO_DIR}${PKG_NAME}.list | cut -b 2-`; do
file=${pkgfile##*/}
path=${pkgfile%/*}
mkdir -p ${path}
if [ `echo "${path}" | grep "^${UCI_DEF_DIR}"` ]; then
cp "${UCI_BAK_DIR}${file}" "${pkgfile}"
else
cp "/${pkgfile}" "${pkgfile}"
fi
done
#call ipkg-build script to build ipk
/usr/libexec/istore/ipkg-build ${IS_ROOT}/${IPK_FILE_NAME} ${IPK_OUTPUT_DIR}
echo "${IPK_FILE_NAME}.ipk" >> ${IPK_OUTPUT_DIR}/appdepipk.list
[ -n "${IS_DEBUG}" ] || rm -rf ${IS_ROOT}/${IPK_FILE_NAME}
}
# if arg is NULL, use light backup, otherwise use local backup
backup() {
[ -n "$1" ] && BACKUP_PATH=$1
#1.add all istore self data to sysupgrade config file,
#sysupgrade will backup/restore it auto when flash new firmware
echo "/etc/.app_store.id" > /lib/upgrade/keep.d/luci-app-store
cat /usr/lib/opkg/info/luci-app-store.list >> /lib/upgrade/keep.d/luci-app-store
echo "/etc/rc.d/S45istore" >> /lib/upgrade/keep.d/luci-app-store
echo "/etc/istore/uci-defaults_bak" >> /lib/upgrade/keep.d/luci-app-store
echo "${APP_LIST_FILE}" >> /lib/upgrade/keep.d/luci-app-store
echo "${BACKUP_CONFIG_FILE}" >> /lib/upgrade/keep.d/luci-app-store
#write user installed package list to file
opkg_list_installed_packages "userinstalled" 2>/dev/null | sort -u > ${IS_ROOT}/user_installed_package.list
#write installed package list by istore feed to file
cat ${IS_ROOT}/user_installed_package.list | \
grep '^app-meta-' > ${IS_ROOT}/istore_installed_package.list
#if no input backup path, only back app.list
mkdir -p /etc/istore
cp ${IS_ROOT}/istore_installed_package.list ${APP_LIST_FILE}
echo "backup installed package list to ${APP_LIST_FILE}"
if [ ! -n "${BACKUP_PATH}" ]; then
echo "backup success"
exit 0
fi
if [ ! -d "${BACKUP_PATH}" ] && ! mkdir -p "${BACKUP_PATH}" ; then
echo "invalid backup path, can not backup ipk"
exit 1
fi
#write all installed package list to file
opkg_list_installed_packages "allinstalled" 2>/dev/null | sort -u > ${IS_ROOT}/all_installed_package.list
#write system pre installed package list to file
opkg_list_installed_packages "preinstalled" 2>/dev/null | sort -u > ${IS_ROOT}/pre_installed_package.list
#write installed packages and depends list by istore feed to file by depend sequence
appdep_list=""
temp_list=`cat ${IS_ROOT}/istore_installed_package.list | sed 's/^/\t/'`
while [ -n "${temp_list}" ]
do
#get real pkg name
for PKG_NAME_TEMP in ${temp_list}; do
REAL_PKG_NAME=`cat ${IS_ROOT}/all_installed_package.list | sort -u | grep "^${PKG_NAME_TEMP}" | head -n 1`
if [ "${REAL_PKG_NAME}" != "${PKG_NAME_TEMP}" ]; then
temp_list=`echo "${temp_list}" | sed 's/^\t'"${PKG_NAME_TEMP}"'$/\t'"${REAL_PKG_NAME}"'/'`
fi
done
appdep_list=`echo -e "${temp_list}\n${appdep_list}"`
[ -n "${IS_DEBUG}" ] && echo -e "temp_list:\n""${temp_list}"
[ -n "${IS_DEBUG}" ] && echo -e "appdep_list:\n""${appdep_list}"
temp_list=`echo "${temp_list}" | xargs opkg depends | grep -v "depends on:" | grep -v " (>= " | grep -v " (= " | sort -u`
done
appdep_list_all=`echo "${appdep_list}" | cut -f2 | grep -v "^$" | awk '!seen[$0]++'`
[ -n "${IS_DEBUG}" ] && echo -e "appdep_list_all:\n""${appdep_list_all}"
echo "${appdep_list_all}" > ${IS_ROOT}/appdep.list
#3.rebuild all istore installed package to ipk and backup to userdata partation
# 4. create dir
date=$(date +%Y-%m%d-%H%M)
if [ ! -d "$BACKUP_PATH/backup_istore_$date" ];then
mkdir $BACKUP_PATH/backup_istore_$date
fi
cp ${IS_ROOT}/istore_installed_package.list $BACKUP_PATH/backup_istore_$date/app.list
cp ${IS_ROOT}/appdep.list $BACKUP_PATH/backup_istore_$date/appdep.list
#only backup non pre installed ipk
cp ${IS_ROOT}/appdep.list ${IS_ROOT}/appdep_strip.list
for pre_installed_pkg in `cat ${IS_ROOT}/appdep.list ${IS_ROOT}/pre_installed_package.list | sort -n | uniq -d`; do
sed -i '/^'"$pre_installed_pkg"'$/d' ${IS_ROOT}/appdep_strip.list
done
rm -f $BACKUP_PATH/backup_istore_$date/appdepipk.list
echo "build ipk"
for pkg_name in `cat ${IS_ROOT}/appdep_strip.list`; do
ipk_build ${pkg_name} $BACKUP_PATH/backup_istore_$date
done
# 5. create tar.gz file,and remove fir
cd $BACKUP_PATH
echo "write backup file to $BACKUP_PATH/backup_istore_$date.backup.tar.gz"
tar -czf $BACKUP_PATH/backup_istore_$date.backup.tar.gz backup_istore_$date
rm -rf $BACKUP_PATH/backup_istore_$date
echo "backup success"
}
# if arg is NULL, use light backup, otherwise use local backup
restore() {
if [ -n "$1" ]; then
BACKUP_PATH_FILE=$1
else
echo "install package by ${APP_LIST_FILE}"
is-opkg update
for app in `cat ${APP_LIST_FILE}`; do
#skip resotre istore self
[ "A${app}" == "A""luci-app-store" ] && continue
is-opkg install ${app}
done
exit 0
fi
if [ ! -f "${BACKUP_PATH_FILE}" ];then
echo "invalid backup file, can not restore ipk"
exit 1
fi
#1. Unzip file to dir
BACKUP_PATH_FILE_NAME=${BACKUP_PATH_FILE##*/}
BACKUP_PATH=/tmp/${BACKUP_PATH_FILE_NAME%.backup.tar.gz*}
if [ -d "$BACKUP_PATH" ];then
rm -rf $BACKUP_PATH
fi
mkdir -p $BACKUP_PATH
echo "unpack input file..."
# fix tar path error
tar -zxf ${BACKUP_PATH_FILE} -C /tmp/
echo "check file"
if [ ! -f "${BACKUP_PATH}/appdep.list" ];then
echo "no available appdep.list, can not restore ipk"
exit 1
fi
echo "check success"
#2. install ipk by backup path
echo "restore begin"
( cd ${BACKUP_PATH}; opkg install `cat ${BACKUP_PATH}/appdepipk.list` )
#3. rm dir
rm -rf ${BACKUP_PATH}
echo "restore success"
}
get_support_backup_features() {
echo "light_backup"
#istore custom img mean support local_backup
if [ -f /etc/istore_img_flag ];then
echo "local_backup"
fi
}
get_backup_app_list_file_path() {
echo "${APP_LIST_FILE}"
}
get_backup_app_list() {
if [ ! -f "${APP_LIST_FILE}" ];then
echo "no app.list, can not get backup app list"
exit 1
fi
cat ${APP_LIST_FILE}
}
get_available_backup_file_list() {
if [ -n "$1" ]; then
for backup_file in `ls $1/*.backup.tar.gz`; do
filename=${backup_file##*/}
echo "${filename}"
done
else
echo "input backup path is null"
exit 1
fi
}
usage() {
echo "usage: backup sub-command [arguments...]"
echo "where sub-command is one of:"
echo " backup [dir] Backup all installed package(s) to [directory]"
echo " restore [dir] Restore package(s) by [directory]"
echo " get_support_backup_features get device support backup features"
echo " get_backup_app_list_file_path get light backup app list file path"
echo " get_backup_app_list get light backup app list"
echo " get_available_backup_file_list get local available backup file list"
}
is_init >/dev/null 2>&1
case $action in
"get_support_backup_features")
get_support_backup_features
;;
"backup")
backup "$@"
;;
"restore")
restore "$@"
;;
"get_backup_app_list_file_path")
get_backup_app_list_file_path
;;
"get_backup_app_list")
get_backup_app_list
;;
"get_available_backup_file_list")
get_available_backup_file_list "$@"
;;
*)
usage
;;
esac

View File

@ -1,200 +0,0 @@
#!/bin/sh
# ipkg-build -- construct a .ipk from a directory
# Carl Worth <cworth@east.isi.edu>
# based on a script by Steve Redler IV, steve@sr-tech.com 5-21-2001
# 2003-04-25 rea@sr.unh.edu
# Updated to work on Familiar Pre0.7rc1, with busybox tar.
# Note it Requires: binutils-ar (since the busybox ar can't create)
# For UID debugging it needs a better "find".
set -e
version=1.0
FIND="$(command -v find)"
FIND="${FIND:-$(command -v gfind)}"
TAR="${TAR:-$(command -v tar)}"
GZIP="$(command -v gzip)"
# try to use fixed source epoch
if [ -n "$PKG_SOURCE_DATE_EPOCH" ]; then
TIMESTAMP=$(date --date="@$PKG_SOURCE_DATE_EPOCH")
elif [ -n "$SOURCE_DATE_EPOCH" ]; then
TIMESTAMP=$(date --date="@$SOURCE_DATE_EPOCH")
else
TIMESTAMP=$(date)
fi
ipkg_extract_value() {
sed -e "s/^[^:]*:[[:space:]]*//"
}
required_field() {
field=$1
grep "^$field:" < $CONTROL/control | ipkg_extract_value
}
pkg_appears_sane() {
local pkg_dir=$1
local owd=$PWD
cd $pkg_dir
PKG_ERROR=0
pkg=`required_field Package`
version=`required_field Version | sed 's/Version://; s/^.://g;'`
arch=`required_field Architecture`
if echo $pkg | grep '[^a-zA-Z0-9_.+-]'; then
echo "*** Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])" >&2
PKG_ERROR=1;
fi
if [ -f $CONTROL/conffiles ]; then
rm -f $CONTROL/conffiles.resolved
for cf in `$FIND $(sed -e "s!^/!$pkg_dir/!" $CONTROL/conffiles) -type f`; do
echo "${cf#$pkg_dir}" >> $CONTROL/conffiles.resolved
done
rm $CONTROL/conffiles
if [ -f $CONTROL/conffiles.resolved ]; then
mv $CONTROL/conffiles.resolved $CONTROL/conffiles
chmod 0644 $CONTROL/conffiles
fi
fi
cd $owd
return $PKG_ERROR
}
resolve_file_mode_id() {
local var=$1 type=$2 name=$3 id
case "$name" in
root)
id=0
;;
*[!0-9]*)
id=$(sed -ne "s#^$type $name \\([0-9]\\+\\)\\b.*\$#\\1#p" "$TOPDIR/tmp/.packageusergroup" 2>/dev/null)
;;
*)
id=$name
;;
esac
export "$var=$id"
[ -n "$id" ]
}
###
# ipkg-build "main"
###
file_modes=""
usage="Usage: $0 [-v] [-h] [-m] <pkg_directory> [<destination_directory>]"
while getopts "hvm:" opt; do
case $opt in
v ) echo $version
exit 0
;;
h ) echo $usage >&2 ;;
m ) file_modes=$OPTARG ;;
\? ) echo $usage >&2
esac
done
shift $(($OPTIND - 1))
# continue on to process additional arguments
case $# in
1)
dest_dir=$PWD
;;
2)
dest_dir=$2
if [ "$dest_dir" = "." -o "$dest_dir" = "./" ] ; then
dest_dir=$PWD
fi
;;
*)
echo $usage >&2
exit 1
;;
esac
pkg_dir=$1
if [ ! -d $pkg_dir ]; then
echo "*** Error: Directory $pkg_dir does not exist" >&2
exit 1
fi
# CONTROL is second so that it takes precedence
CONTROL=
[ -d $pkg_dir/CONTROL ] && CONTROL=CONTROL
if [ -z "$CONTROL" ]; then
echo "*** Error: Directory $pkg_dir has no CONTROL subdirectory." >&2
exit 1
fi
if ! pkg_appears_sane $pkg_dir; then
echo >&2
echo "ipkg-build: Please fix the above errors and try again." >&2
exit 1
fi
tmp_dir=$dest_dir/IPKG_BUILD.$$
mkdir $tmp_dir
echo $CONTROL > $tmp_dir/tarX
cd $pkg_dir
for file_mode in $file_modes; do
case $file_mode in
/*:*:*:*)
;;
*)
echo "ERROR: file modes must use absolute path and contain user:group:mode"
echo "$file_mode"
exit 1
;;
esac
mode=${file_mode##*:}; path=${file_mode%:*}
group=${path##*:}; path=${path%:*}
user=${path##*:}; path=${path%:*}
if ! resolve_file_mode_id uid user "$user"; then
echo "ERROR: unable to resolve uid of $user" >&2
exit 1
fi
if ! resolve_file_mode_id gid group "$group"; then
echo "ERROR: unable to resolve gid of $group" >&2
exit 1
fi
chown "$uid:$gid" "$pkg_dir/$path"
chmod "$mode" "$pkg_dir/$path"
done
$TAR -X $tmp_dir/tarX --format=gnu --sort=name -cpf - --mtime="$TIMESTAMP" . | $GZIP -n - > $tmp_dir/data.tar.gz
installed_size=`stat -c "%s" $tmp_dir/data.tar.gz`
sed -i -e "s/^Installed-Size: .*/Installed-Size: $installed_size/" \
$pkg_dir/$CONTROL/control
( cd $pkg_dir/$CONTROL && $TAR --format=gnu --sort=name -cf - --mtime="$TIMESTAMP" . | $GZIP -n - > $tmp_dir/control.tar.gz )
rm $tmp_dir/tarX
echo "2.0" > $tmp_dir/debian-binary
pkg_file=$dest_dir/${pkg}_${version}_${arch}.ipk
rm -f $pkg_file
( cd $tmp_dir && $TAR --format=gnu --sort=name -cf - --mtime="$TIMESTAMP" ./debian-binary ./data.tar.gz ./control.tar.gz | $GZIP -n - > $pkg_file )
rm $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz
rmdir $tmp_dir
echo "Packaged contents of $pkg_dir into $pkg_file"

View File

@ -1,7 +0,0 @@
#!/bin/sh
for i in "$@"; do
echo "$i" | grep -s -q "/etc/uci-defaults/" \
&& mkdir -p /etc/istore/uci-defaults_bak \
&& cp -f "$i" /etc/istore/uci-defaults_bak/
done
/bin/rm "$@"

View File

@ -1,23 +0,0 @@
clean:
compile:
include $(TOPDIR)/rules.mk
LUCI_NAME:=luci-lib-dummy
INCLUDE_DIR:=./dummy
include $(TOPDIR)/feeds/luci/luci.mk
install:
[ -n "$(APP_STORE_VERSION)" ]
mkdir -p "$(DESTDIR)/www/luci-static"
cp -a "$(FRONTEND_DIST)/luci-static/istore" "$(DESTDIR)/www/luci-static/"
$(SED) 's#\.js"#.js?v=$(APP_STORE_VERSION)"#g' "$(DESTDIR)/www/luci-static/istore/index.js"
mkdir -p "$(DESTDIR)/etc/opkg/keys"
echo "$(APP_STORE_VERSION)" > "$(DESTDIR)/etc/.app_store.version"
cp -a ./compat.conf "$(DESTDIR)/etc/opkg/compatfeeds.conf"
cp -a ./key-build.pub $(DESTDIR)/etc/opkg/keys/`$(STAGING_DIR_HOST)/bin/usign -F -p ./key-build.pub`
mkdir -p "$(DESTDIR)$(LUCI_LIBRARYDIR)/i18n"
$(foreach lang,$(LUCI_LANGUAGES),$(foreach po,$(wildcard ${CURDIR}/po/$(lang)/*.po), \
po2lmo $(po) \
$(DESTDIR)$(LUCI_LIBRARYDIR)/i18n/$(basename $(notdir $(po))).$(lang).lmo;))

View File

@ -1 +0,0 @@
src/gz istore_compat https://istore.linkease.com/repo/all/compat

View File

@ -1,2 +0,0 @@
define BuildPackage
endef

View File

@ -1,2 +0,0 @@
untrusted comment: istore key
RWSlbxYnTG1Ia0BvB+xd7YdP7QDQACljfpve7sx9KYq94QgIqtlljuME

View File

@ -1,11 +0,0 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "istore_vue_lang"
msgstr "en"
msgid "iStore"
msgstr ""
msgid "This package is broken! Please reinstall or uninstall it."
msgstr ""

View File

@ -1,11 +0,0 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "istore_vue_lang"
msgstr "zh-cn"
msgid "iStore"
msgstr "iStore"
msgid "This package is broken! Please reinstall or uninstall it."
msgstr "此软件包已损坏!请重新安装或卸载它。"

View File

@ -1,11 +0,0 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "istore_vue_lang"
msgstr "zh-cn"
msgid "iStore"
msgstr "iStore"
msgid "This package is broken! Please reinstall or uninstall it."
msgstr "此軟體包已損壞!請重新安裝或卸載它。"

View File

@ -1,20 +0,0 @@
#
# Copyright (C) 2022 jjm2473 <jjm2473@gmail.com>
#
# This is free software, licensed under the MIT License.
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=Task library
LUCI_DEPENDS:=+luci-lib-xterm +taskd
LUCI_EXTRA_DEPENDS:=taskd (>=1.0.3-1)
LUCI_PKGARCH:=all
PKG_VERSION:=1.0.18
PKG_RELEASE:=
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -1,112 +0,0 @@
[hidden] {
display: none !important;
}
#tasks_detail_container {
position: fixed;
z-index: 1000;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
background-color: #0008;
}
#tasks_dialog {
position: absolute;
width: 770px;
max-width: 100%;
max-height: 100%;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: #000;
border-radius: 10px;
box-shadow: 2px 2px 6px #000a;
padding: 20px;
color: white;
}
.dialog-title-bar {
margin-top: -10px;
margin-right: -10px;
margin-bottom: 5px;
display: flex;
flex-direction: row;
justify-content: space-between;
flex-wrap: nowrap;
align-items: center;
}
.dialog-title-bar .dialog-title {
word-break: break-all;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.dialog-content {
max-height: 500px;
overflow-y: scroll;
margin-right: -10px;
}
.dialog-icons {
align-self: center;
display: flex;
justify-content: flex-end;
}
.dialog-icon {
display: flex;
align-items: center;
flex-wrap: nowrap;
width: 20px;
height: 20px;
background-color: white;
color: black;
border-radius: 50%;
font-size: 10px;
font-weight: bold;
user-select: none;
margin-left: 10px;
line-height: 1;
font-family: sans-serif;
justify-content: center;
cursor: pointer;
}
.dialog-icon.dialog-icon-min {
background-color: darkorange;
}
.dialog-icon.dialog-icon-close {
background-color: #ff5f56;
}
.dialog-icons:hover .dialog-icon.dialog-icon-min:before {
content: "_";
}
.dialog-icons:hover .dialog-icon.dialog-icon-close:before {
content: "X";
}
.tasks_stopped .dialog-icon.dialog-icon-close {
background-color: #27c840;
}
.tasks_stopped #tasks_dialog, .tasks_unknown #tasks_dialog {
padding: 19px;
border: 1px #27c840 solid;
animation: border-blink 1s;
animation-iteration-count: infinite;
}
.tasks_failed #tasks_dialog {
border-color: #ff0000;
}
.tasks_failed .dialog-icon.dialog-icon-close {
background-color: #ff0000;
}
.tasks_unknown #tasks_dialog {
border-color: darkorange;
}
@keyframes border-blink { 50% { border-color:#fff ; } }

View File

@ -1,232 +0,0 @@
(function(){
const taskd={};
const $gettext = function(str) {
return taskd.i18n[str] || str;
};
const retryPromise = function(fn) {
return new Promise((resolve, reject) => {
const retry = function() {
fn(resolve, reject, retry);
};
retry();
});
};
const retry403XHR = function(url, method, responseType) {
return retryPromise((resolve, reject, retry) => {
var oReq = new XMLHttpRequest();
oReq.onerror = reject;
oReq.open(method || 'GET', url, true);
if (responseType) {
oReq.responseType = responseType;
}
oReq.onload = function (oEvent) {
if (oReq.status == 403) {
alert($gettext("Lost login status"));
location.href = location.href;
} else if (oReq.status == 404) {
reject(oEvent);
} else {
resolve(oReq);
}
};
if (method=='POST') {
oReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
}
oReq.send(method=='POST'?("token="+taskd.csrfToken):null);
});
};
const request = function(url, method) {
return retry403XHR(url, method).then(oReq => oReq.responseText);
};
const getBin = function(url) {
return retry403XHR(url, null, "arraybuffer").then(oReq => {return {status: oReq.status, buffer: new Uint8Array(oReq.response)}});
};
const getTaskDetail = function(task_id) {
return request("/cgi-bin/luci/admin/system/tasks/status?task_id="+task_id).then(data=>JSON.parse(data));
};
const create_dialog = function(cfg) {
const container = document.createElement('div');
container.id = "tasks_detail_container";
container.innerHTML = taskd.dialog_template;
document.body.appendChild(container);
const title_view = container.querySelector(".dialog-title-bar .dialog-title");
title_view.innerText = cfg.title;
const term = new Terminal({convertEol: cfg.convertEol||false});
if (cfg.nohide) {
container.querySelector(".dialog-icon-min").hidden = true;
} else {
container.querySelector(".dialog-icon-min").onclick = function(){
container.hidden=true;
term.dispose();
document.body.removeChild(container);
cfg.onhide && cfg.onhide();
return false;
};
}
term.open(document.getElementById("tasks_xterm_log"));
return {term,container};
};
const show_log_txt = function(title, content, onclose) {
const dialog = create_dialog({title, convertEol:true, onhine:onclose});
const container = dialog.container;
const term = dialog.term;
container.querySelector(".dialog-icon-close").hidden = true;
term.write(content);
};
const show_log = function(task_id, nohide) {
let showing = true;
let running = true;
const dialog = create_dialog({title:task_id, nohide, onhide:function(){showing=false;}});
const container = dialog.container;
const term = dialog.term;
const title_view = container.querySelector(".dialog-title-bar .dialog-title");
container.querySelector(".dialog-icon-close").onclick = function(){
if (!running || confirm($gettext("Stop running task?"))) {
running=false;
showing=false;
del_task(task_id).then(()=>{
location.href = location.href;
});
}
return false;
};
const checkTask = function() {
return getTaskDetail(task_id).then(data=>{
if (!running) {
return false;
}
running = data.running;
let title = task_id;
if (!data.running && data.stop) {
title += " (" + (data.exit_code?$gettext("Failed at:"):$gettext("Finished at:")) + " " + new Date(data.stop * 1000).toLocaleString() + ")";
}
title += " > " + (data.command || '');
title_view.title = title;
title_view.innerText = title;
if (!data.running) {
container.classList.add('tasks_stopped');
if (data.exit_code) {
container.classList.add('tasks_failed');
}
}
// last pull
return showing;
});
};
let logoffset = 0;
const pulllog = function(check) {
let starter = Promise.resolve(showing);
if (check) {
starter = checkTask();
}
starter.then(again => {
if (again)
return getBin("/cgi-bin/luci/admin/system/tasks/log?task_id="+task_id+"&offset="+logoffset);
else
return {status: 204};
}).then(function(res){
if (!showing) {
return false;
}
switch(res.status){
case 205:
term.reset();
logoffset = 0;
return running;
break;
case 204:
return running && checkTask();
break;
case 200:
logoffset += res.buffer.byteLength;
term.write(res.buffer);
return running;
break;
}
}).then(again => {
if (again) {
setTimeout(pulllog, 0);
}
}).catch(err => {
if (showing) {
if (err.target.status == 0) {
title_view.innerText = task_id + ' (' + $gettext("Fetch log failed, retrying...") + ')';
setTimeout(()=>pulllog(true), 1000);
} else if (err.target.status == 403 || err.target.status == 404) {
title_view.innerText = task_id + ' (' + $gettext(err.target.status == 403?"Lost login status":"Task does not exist or has been deleted") + ')';
container.querySelector(".dialog-icon-close").hidden = true;
container.classList.add('tasks_unknown');
} else {
console.error(err);
}
}
});
};
pulllog(true);
};
const del_task = function(task_id) {
return request("/cgi-bin/luci/admin/system/tasks/stop?task_id="+task_id, "POST");
};
taskd.show_log = show_log;
taskd.remove = del_task;
taskd.show_log_txt = show_log_txt;
window.taskd=taskd;
})();
(function(){
// compat
if (typeof(window.findParent) !== 'function') {
const elem = function(e) {
return (e != null && typeof(e) == 'object' && 'nodeType' in e);
};
const matches = function(node, selector) {
var m = elem(node) ? node.matches || node.msMatchesSelector : null;
return m ? m.call(node, selector) : false;
};
window.findParent = function (node, selector) {
if (elem(node) && node.closest)
return node.closest(selector);
while (elem(node))
if (matches(node, selector))
return node;
else
node = node.parentNode;
return null;
};
}
if (typeof(window.cbi_submit) !== 'function') {
const makeHidden = function(name) {
const input = document.createElement('input');
input.type = 'hidden';
input.name = name;
return input;
};
window.cbi_submit = function(elem, name, value, action) {
var form = elem.form || findParent(elem, 'form');
if (!form)
return false;
if (action)
form.action = action;
if (name) {
var hidden = form.querySelector('input[type="hidden"][name="%s"]'.format(name)) ||
makeHidden(name);
hidden.value = value || '1';
form.appendChild(hidden);
}
form.submit();
return true;
};
}
})();

View File

@ -1,98 +0,0 @@
module("luci.controller.tasks-lib", package.seeall)
function index()
entry({"admin", "system", "tasks"}, call("tasks_ping")).dependent=false -- just for compatible
entry({"admin", "system", "tasks", "status"}, call("tasks_status")).dependent=false
entry({"admin", "system", "tasks", "log"}, call("tasks_log")).dependent=false
entry({"admin", "system", "tasks", "stop"}, post("tasks_stop")).dependent=false
end
local util = require "luci.util"
local jsonc = require "luci.jsonc"
local ltn12 = require "luci.ltn12"
local taskd = require "luci.model.tasks"
function tasks_ping()
luci.http.prepare_content("application/json")
luci.http.write_json({})
end
function tasks_status()
local data = taskd.status(luci.http.formvalue("task_id"))
luci.http.prepare_content("application/json")
luci.http.write_json(data)
end
function tasks_log()
local wait = 107
local task_id = luci.http.formvalue("task_id")
local offset = luci.http.formvalue("offset")
offset = offset and tonumber(offset) or 0
local logpath = "/var/log/tasks/"..task_id..".log"
local i
local logfd = io.open(logpath, "rb")
if logfd == nil then
luci.http.status(404)
luci.http.write("log not found")
return
end
local size = logfd:seek("end")
if size < offset then
luci.http.status(205, "Reset Content")
luci.http.write("reset offset")
return
end
i = 0
while (i < wait)
do
if size > offset then
break
end
nixio.nanosleep(0, 10000000) -- sleep 10ms
size = logfd:seek("end")
i = i+1
end
if i == wait then
logfd:close()
luci.http.status(204)
luci.http.prepare_content("application/octet-stream")
return
end
logfd:seek("set", offset)
local write_log = function()
local buffer = logfd:read(4096)
if buffer and #buffer > 0 then
return buffer
else
logfd:close()
return nil
end
end
luci.http.prepare_content("application/octet-stream")
if logfd then
ltn12.pump.all(write_log, luci.http.write)
end
end
function tasks_stop()
local sys = require("luci.sys")
local task_id = luci.http.formvalue("task_id") or ""
if task_id == "" then
luci.http.status(400)
luci.http.write("task_id is empty")
return
end
if sys.call("/etc/init.d/tasks task_del "..task_id.." >/dev/null 2>&1") ~= 0 then
nixio.nanosleep(2, 10000000)
end
luci.http.status(204)
end

View File

@ -1,100 +0,0 @@
local util = require "luci.util"
local jsonc = require "luci.jsonc"
local taskd = {}
local function output(data)
local ret={}
ret.running=data.running
if not data.running then
ret.exit_code=data.exit_code
if nil == ret.exit_code then
if data["data"] and data["data"]["exit_code"] and data["data"]["exit_code"] ~= "" then
ret.exit_code=tonumber(data["data"]["exit_code"])
else
ret.exit_code=143
end
end
end
ret.command=data["command"] and data["command"][4] or '#'
if data["data"] then
ret.start=tonumber(data["data"]["start"])
if not data.running and data["data"]["stop"] then
ret.stop=tonumber(data["data"]["stop"])
end
end
return ret
end
taskd.status = function (task_id)
task_id = task_id or ""
local data = util.trim(util.exec("/etc/init.d/tasks task_status "..task_id.." 2>/dev/null")) or ""
if data ~= "" then
data = jsonc.parse(data)
else
if task_id == "" then
data = {}
else
data = {running=false, exit_code=404}
end
end
if task_id ~= "" then
return output(data)
end
local ary={}
for k, v in pairs(data) do
ary[k] = output(v)
end
return ary
end
taskd.docker_map = function(config, task_id, script_path, title, desc)
require("luci.cbi")
require("luci.http")
require("luci.sys")
local translate = require("luci.i18n").translate
local m
m = luci.cbi.Map(config, title, desc)
m.template = "tasks/docker"
-- hide default buttons
m.pageaction = false
-- we want hook 'on_after_apply' works, 'apply_on_parse' can be true (rollback) or false (no rollback),
-- but 'apply_on_parse' must be true for luci 17.01 and below
m.apply_on_parse = true
m.script_path = script_path
m.task_id = task_id
m.auto_show_task = true
m.on_before_apply = function(self)
if self.uci.rollback then
-- luci 18.06+ has 'rollback' function
-- rollback dialog will show because 'apply_on_parse' is true,
-- hide rollback dialog by hook 'apply' function
local apply = self.uci.apply
self.uci.apply = function(uci, rollback)
apply(uci, false)
end
end
end
m.on_after_apply = function(self)
local cmd
local action = luci.http.formvalue("cbi.apply") or "null"
if "upgrade" == action or "install" == action
or "start" == action or "stop" == action or "restart" == action or "rm" == action then
cmd = string.format("\"%s\" %s", script_path, action)
end
if cmd then
if luci.sys.call("/etc/init.d/tasks task_add " .. task_id .. " " .. luci.util.shellquote(cmd) .. " >/dev/null 2>&1") ~= 0 then
self.task_start_failed = true
self.message = translate("Config saved, but apply failed")
end
else
self.message = translate("Unknown command: ") .. action
end
if self.message then
self.auto_show_task = false
end
end
return m
end
return taskd

View File

@ -1,56 +0,0 @@
<% if self.task_start_failed then %>
<div class="alert-message warning"><%:Another task running, try again later.%> <a href="javascript:void(taskd.show_log('<%=self.task_id%>'))"><%:Click here to check running task%></a></div>
<% end %>
<%+cbi/map%>
<%
local task_running = false
local taskd = require "luci.model.tasks"
local status = taskd.status(self.task_id)
task_running = status.running
-%>
<div class="cbi-page-actions control-group">
<%
if not task_running then
%>
<%
local util = require "luci.util"
local container_status = util.trim(util.exec(self.script_path.." status"))
local container_install = (string.len(container_status) > 0)
local container_running = container_status == "running"
if container_install then
-%>
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Upgrade%>/<%:Apply%>" onclick="cbi_submit(this, 'cbi.apply', 'upgrade')" />
<%
if container_running then
-%>
<input class="btn cbi-button cbi-button-remove" type="button" value="<%:Stop%>" onclick="cbi_submit(this, 'cbi.apply', 'stop')" />
<input class="btn cbi-button cbi-button-reload" type="button" value="<%:Restart%>" onclick="cbi_submit(this, 'cbi.apply', 'restart')" />
<% else %>
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Start%>" onclick="cbi_submit(this, 'cbi.apply', 'start')" />
<input class="btn cbi-button cbi-button-remove" type="button" value="<%:Remove%>" onclick="cbi_submit(this, 'cbi.apply', 'rm')" />
<% end
else %>
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Install%>" onclick="cbi_submit(this, 'cbi.apply', 'install')" />
<% end
else
%>
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Task Running%>&hellip;" onclick="taskd.show_log('<%=self.task_id%>')" />
<%
end
%>
</div>
<%+tasks/embed%>
<%
if self.auto_show_task and task_running then
-%>
<script>
taskd.show_log("<%=self.task_id%>");
</script>
<%
end
%>

View File

@ -1,34 +0,0 @@
<%+xterm/embed%>
<link rel="stylesheet" href="<%=resource%>/tasks/tasks.css<%# ?v=PKG_VERSION %>">
<script src="<%=resource%>/tasks/tasks.js<%# ?v=PKG_VERSION %>"></script>
<%
local i18n = {}
local function tr(str)
i18n[str]=translate(str)
end
tr("Stop running task?")
tr("Stopped at:")
tr("Finished at:")
tr("Failed at:")
tr("Lost login status")
tr("Fetch log failed, retrying...")
tr("Task does not exist or has been deleted")
-%>
<script>
window.taskd.csrfToken="<%=token%>";
window.taskd.i18n=<% luci.http.write_json(i18n) %>;
window.taskd.dialog_template=`
<div id="tasks_dialog">
<div class="dialog-title-bar">
<span class="dialog-title" id="tasks_id"></span>
<span class="dialog-icons">
<span class="dialog-icon dialog-icon-close" title="<%:Stop and Remove%>"></span>
<span class="dialog-icon dialog-icon-min" title="<%:Hide%>"></span>
</span>
</div>
<div class="dialog-content">
<div id="tasks_xterm_log"></div>
</div>
</div>
`;
</script>

View File

@ -1,15 +0,0 @@
clean:
compile:
include $(TOPDIR)/rules.mk
LUCI_NAME:=luci-lib-dummy
INCLUDE_DIR:=./dummy
include $(TOPDIR)/feeds/luci/luci.mk
install:
mkdir -p "$(DESTDIR)$(LUCI_LIBRARYDIR)/i18n"
$(foreach lang,$(LUCI_LANGUAGES),$(foreach po,$(wildcard ${CURDIR}/po/$(lang)/*.po), \
po2lmo $(po) \
$(DESTDIR)$(LUCI_LIBRARYDIR)/i18n/$(basename $(notdir $(po))).$(lang).lmo;))

View File

@ -1,2 +0,0 @@
define BuildPackage
endef

View File

@ -1,41 +0,0 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "Stop running task?"
msgstr "删除运行中的任务?"
msgid "Finished at:"
msgstr "完成于:"
msgid "Failed at:"
msgstr "失败于:"
msgid "Lost login status"
msgstr "丢失登陆状态"
msgid "Fetch log failed, retrying..."
msgstr "拉取日志失败,正在重试..."
msgid "Task does not exist or has been deleted"
msgstr "任务不存在或已删除"
msgid "Stop and Remove"
msgstr "停止并删除"
msgid "Hide"
msgstr "隐藏"
msgid "Config saved, but apply failed"
msgstr "配置已保存,但应用失败"
msgid "Unknown command: "
msgstr "未知命令:"
msgid "Another task running, try again later."
msgstr "已有后台任务运行中,请稍后重试。"
msgid "Click here to check running task"
msgstr "点此查看运行中的任务"
msgid "Task Running"
msgstr "任务执行中"

View File

@ -1,21 +0,0 @@
#
# Copyright (c) 2017-2019, The xterm.js authors (MIT License)
# Copyright (c) 2014-2017, SourceLair, Private Company (www.sourcelair.com) (MIT License)
# Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
#
# This is free software, licensed under the MIT License.
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=Xterm.js library
LUCI_DEPENDS:=
PKG_LICENSE:=MIT
PKG_VERSION:=4.18.0
PKG_RELEASE:=
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -1,180 +0,0 @@
/**
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
* https://github.com/chjj/term.js
* @license MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Originally forked from (with the author's permission):
* Fabrice Bellard's javascript vt100 for jslinux:
* http://bellard.org/jslinux/
* Copyright (c) 2011 Fabrice Bellard
* The original design remains. The terminal itself
* has been extended to include xterm CSI codes, among
* other features.
*/
/**
* Default styles for xterm.js
*/
.xterm {
position: relative;
user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
}
.xterm.focus,
.xterm:focus {
outline: none;
}
.xterm .xterm-helpers {
position: absolute;
top: 0;
/**
* The z-index of the helpers must be higher than the canvases in order for
* IMEs to appear on top.
*/
z-index: 5;
}
.xterm .xterm-helper-textarea {
padding: 0;
border: 0;
margin: 0;
/* Move textarea out of the screen to the far left, so that the cursor is not visible */
position: absolute;
opacity: 0;
left: -9999em;
top: 0;
width: 0;
height: 0;
z-index: -5;
/** Prevent wrapping so the IME appears against the textarea at the correct position */
white-space: nowrap;
overflow: hidden;
resize: none;
}
.xterm .composition-view {
/* TODO: Composition position got messed up somewhere */
background: #000;
color: #FFF;
display: none;
position: absolute;
white-space: nowrap;
z-index: 1;
}
.xterm .composition-view.active {
display: block;
}
.xterm .xterm-viewport {
/* On OS X this is required in order for the scroll bar to appear fully opaque */
background-color: #000;
overflow-y: scroll;
cursor: default;
position: absolute;
right: 0;
left: 0;
top: 0;
bottom: 0;
}
.xterm .xterm-screen {
position: relative;
}
.xterm .xterm-screen canvas {
position: absolute;
left: 0;
top: 0;
}
.xterm .xterm-scroll-area {
visibility: hidden;
}
.xterm-char-measure-element {
display: inline-block;
visibility: hidden;
position: absolute;
top: 0;
left: -9999em;
line-height: normal;
}
.xterm {
cursor: text;
}
.xterm.enable-mouse-events {
/* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
cursor: default;
}
.xterm.xterm-cursor-pointer,
.xterm .xterm-cursor-pointer {
cursor: pointer;
}
.xterm.column-select.focus {
/* Column selection mode */
cursor: crosshair;
}
.xterm .xterm-accessibility,
.xterm .xterm-message {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 10;
color: transparent;
}
.xterm .live-region {
position: absolute;
left: -9999px;
width: 1px;
height: 1px;
overflow: hidden;
}
.xterm-dim {
opacity: 0.5;
}
.xterm-underline {
text-decoration: underline;
}
.xterm-strikethrough {
text-decoration: line-through;
}
.xterm-screen .xterm-decoration-container .xterm-decoration {
z-index: 6;
position: absolute;
}

File diff suppressed because one or more lines are too long

View File

@ -1,3 +0,0 @@
<link rel="stylesheet" href="<%=resource%>/xterm/xterm.css<%# ?v=PKG_VERSION %>">
<script src="<%=resource%>/xterm/xterm.js<%# ?v=PKG_VERSION %>"></script>

View File

@ -1,41 +0,0 @@
#
# Copyright (C) 2022 jjm2473 <jjm2473@gmail.com>
#
# This is free software, licensed under the MIT License.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=taskd
PKG_VERSION:=1.0.3
PKG_RELEASE:=1
PKG_MAINTAINER:=jjm2473 <jjm2473@gmail.com>
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Simple Task Manager
DEPENDS:=+procd +script-utils +coreutils-stty
PKGARCH:=all
endef
define Package/$(PKG_NAME)/description
Simple Task Manager based on procd
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/etc/init.d $(1)/usr/libexec
$(INSTALL_BIN) ./files/tasks.init $(1)/etc/init.d/tasks
$(INSTALL_BIN) ./files/taskd.sh $(1)/usr/libexec/taskd
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@ -1,16 +0,0 @@
#!/bin/sh
TASK_ID="$1"
TASK_CMD="$2"
exec </dev/null >>"/var/log/tasks/$TASK_ID.log" 2>&1
export HOME=/root
export TERM=xterm-256color
exec script -efqc 'onexit() {
/etc/init.d/tasks _task_onstop "'"$TASK_ID"'" "$?"
}
trap onexit EXIT;
stty cols 80 rows 24;
'"$TASK_CMD" /dev/null

View File

@ -1,157 +0,0 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2022 jjm2473@gmail.com
USE_PROCD=1
START=49
extra_command "task_add" "<task_id> <task_cmd> [<time_wait>] Add and run a task, time_wait is wait time before auto delete stopped task, in seconds, -1 means forever"
extra_command "task_del" "<task_id> Stop and delete task"
extra_command "task_status" "[<task_id>] Dump task status, dump all tasks if no task_id specified"
extra_command "task_gc" "Auto delete exipred (stopped and after timw_wait) tasks"
extra_command "_task_onstop" "<task_id> Update stop time, for internal usage"
_task_add() {
local task_id="${1}"
local task_cmd="${2}"
local time_wait="${3}"
> "/var/log/tasks/$task_id.log"
procd_open_instance "$task_id"
procd_set_param data start=`date +'%s'` time_wait="$time_wait"
procd_set_param command sh -c "exec /usr/libexec/taskd '$task_id' \"\$0\"" "$task_cmd"
procd_set_param stderr 1
procd_close_instance
}
task_add() {
local task_id="${1}"
local task_cmd="${2}"
local time_wait="${3}"
[ -z "$task_id" -o -z "$task_cmd" ] && return 127
if service_running "$task_id"; then
echo "already running" >&2
return 1
fi
if ! mkdir -p /var/log/tasks; then
echo "create /var/log/tasks failed!" >&2
return 1
fi
rc_procd _task_add "$task_id" "$task_cmd" "$time_wait"
return 0
}
_task_del() {
local service="${1}"
local task_id="${2}"
procd_kill "$service" "$task_id"
> "/var/log/tasks/$task_id.log"
rm -f "/var/log/tasks/$task_id.log"
}
task_del() {
local task_id="${1}"
[ -z "$task_id" ] && return 127
procd_lock
_task_del "$(basename ${basescript:-$initscript})" "$task_id"
if [ "$(_task_status "$task_id" | jsonfilter -e '$.running' 2>/dev/null)" = "true" ]; then
return 1
else
return 0
fi
}
_task_status() {
local service="$(basename ${basescript:-$initscript})"
local instance="$1"
local data
json_init
json_add_string name "$service"
data=$(_procd_ubus_call list | jsonfilter -e '@["'"$service"'"]')
[ -z "$data" ] && return 1
data=$(echo "$data" | jsonfilter -e '$.instances')
if [ -z "$data" ]; then
if [ -z "$instance" ]; then
echo "{}"
return 0
fi
return 1
fi
if [ -z "$instance" ]; then
echo "$data"
else
instance="\"$instance\""
echo "$data" | jsonfilter -e '$['"$instance"']'
fi
return 0
}
task_status() {
local task_id="${1}"
_task_status "$task_id"
}
task_gc() {
local service="$(basename ${basescript:-$initscript})"
local task_id instance time_wait
local data
json_init
[ -n "$service" ] && json_add_string name "$service"
data=$(_procd_ubus_call list | jsonfilter -e '@["'"$service"'"]')
[ -z "$data" ] && return 1
data=$(echo "$data" | jsonfilter -e '$.instances')
[ -z "$data" ] && return 1
procd_lock
ls /var/log/tasks/ | sed 's/.log$//g' | while read task_id; do
instance=$(echo "$data" | jsonfilter -e '$["'"$task_id"'"]')
[ "$(echo "$instance" | jsonfilter -e '$.running')" = "false" ] || continue
time_wait=$(echo "$instance" | jsonfilter -e '$.data.time_wait')
[ "$time_wait" = "-1" ] && continue
[ $(($(date +'%s' -r "/var/log/tasks/$task_id.log") + ${time_wait:-0})) -lt `date +'%s'` ] && _task_del "$service" "$task_id"
done
}
_insert_exit() {
local exit_code="$2"
eval "`jshn -r "$1" | grep -v json_init`"
json_select data || {
_procd_set_param data stop=`date +'%s'` exit_code="$exit_code"
return
}
json_add_string stop `date +'%s'`
json_add_string exit_code "$exit_code"
json_select ..
}
_task_exit() {
local task_id="$1"
local exit_code="$2"
local inst_json="$3"
_procd_call json_add_object "$task_id"
_procd_call _insert_exit "$inst_json" "$exit_code"
_procd_call json_close_object
}
_task_onstop() {
local task_id="${1}"
local exit_code="${2}"
[ -z "$task_id" ] && return 127
local service="$(basename ${basescript:-$initscript})"
json_init
json_add_string name "$service"
data=$(_procd_ubus_call list | jsonfilter -e '@["'"$service"'"].instances["'"$task_id"'"]')
[ -z "$data" ] && return 1
json_cleanup
rc_procd _task_exit "$task_id" "$exit_code" "$data"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

View File

@ -1,377 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: istore 0.1\n"
"Last-Translator: jjm2473\n"
"Language-Team: none\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/components/app/index.vue:24
msgid "%{ num } download"
msgid_plural "%{ num } downloads"
msgstr[0] "%{ num } download"
msgstr[1] "%{ num } downloads"
#: src/components/app/index.vue:31
msgid "%{ num } like"
msgid_plural "%{ num } likes"
msgstr[0] "%{ num } like"
msgstr[1] "%{ num } likes"
#: src/components/tabs/index.vue:27
msgid "all app"
msgstr "all app"
#: src/pages/maintance/index.vue:8
msgid "app backup"
msgstr "app backup"
#: src/components/app/index.vue:179
msgid "are you sure you want to uninstall %{name}?"
msgstr "are you sure you want to uninstall %{name}?"
#: src/components/app/index.vue:50
msgid "author"
msgstr "author"
#: src/pages/maintance/lightBackup.vue:42
#: src/pages/maintance/localBackup.vue:208
msgid "backup fail"
msgstr "backup fail"
#: src/pages/maintance/lightBackup.vue:18
#: src/pages/maintance/localBackup.vue:34
msgid "backup now"
msgstr "backup now"
#: src/pages/maintance/localBackup.vue:62
msgid ""
"backup now backs up installed software (unlimited installation sources) to "
"external storage"
msgstr ""
"backup now backs up installed software (unlimited installation sources) to "
"external storage"
#: src/pages/maintance/lightBackup.vue:9
msgid "backup now will download a list of iStore installed software"
msgstr "backup now will download a list of iStore installed software"
#: src/pages/maintance/lightBackup.vue:41
#: src/pages/maintance/localBackup.vue:200
msgid "backup success"
msgstr "backup success"
#: src/pages/maintance/lightBackup.vue:40
#: src/pages/maintance/localBackup.vue:195
msgid "backuping"
msgstr "backuping"
#: src/pages/store/components/sort.vue:24
msgid "By download"
msgstr "By download"
#: src/pages/store/components/sort.vue:28
msgid "By rating"
msgstr "By rating"
#: src/pages/maintance/update.vue:4
msgid "checking for latest version"
msgstr "checking for latest version"
#: src/pages/maintance/localBackup.vue:22
msgid "choose"
msgstr "choose"
#: src/pages/maintance/localBackup.vue:41
msgid "choose backup file"
msgstr "choose backup file"
#: src/pages/maintance/lightBackup.vue:43
msgid "click to download"
msgstr "click to download"
#: src/pages/maintance/update.vue:11
msgid "click to update"
msgstr "click to update"
#: src/components/app/index.vue:131 src/components/app/index.vue:154
#: src/components/app/index.vue:188 src/components/toast/index.vue:3
#: src/pages/upload/index.vue:86
msgid "closed"
msgstr "closed"
#: src/pages/maintance/localBackup.vue:26
msgid "customize"
msgstr "customize"
#: src/pages/store/components/sort.vue:20 src/pages/store/components/tag.vue:8
msgid "default"
msgstr "default"
#: src/components/app/index.vue:130 src/components/app/index.vue:153
#: src/components/app/index.vue:187 src/pages/upload/index.vue:85
msgid "do not refresh this page during plugin installation/uninstallation"
msgstr "do not refresh this page during plugin installation/uninstallation"
#: src/plugins/i18n/index.ts:38
msgid "download"
msgstr "Download"
#: src/pages/maintance/lightBackup.vue:4 src/pages/maintance/localBackup.vue:4
msgid "explain"
msgstr "explain"
#: src/pages/maintance/localBackup.vue:16
msgid "external storage directory"
msgstr "external storage directory"
#: src/pages/upload/index.vue:6
msgid "from this page, you can upload plugin packages to install plugins"
msgstr "from this page, you can upload plugin packages to install plugins"
#: src/components/app/index.vue:6
msgid "Icon is gone"
msgstr "Icon is gone"
#: src/components/app/index.vue:83
msgid "install"
msgstr "install"
#: src/components/app/index.vue:172
msgid "installation failed, error code"
msgstr "installation failed, error code"
#: src/components/app/index.vue:169
msgid "installation is complete, please close the current window"
msgstr "installation is complete, please close the current window"
#: src/components/tabs/index.vue:23
msgid "installed"
msgstr "installed"
#. `正在安装插件`,
#: src/components/app/index.vue:152
msgid "installing plugin"
msgstr "installing plugin"
#: src/pages/maintance/update.vue:9
msgid "last version"
msgstr "last version"
#: src/pages/maintance/index.vue:13
msgid "light backup"
msgstr "light backup"
#: src/components/app/index.vue:40
msgid "like"
msgstr "like"
#: src/components/app/index.vue:37
msgid "liked"
msgstr "liked"
#: src/pages/store/components/apps.vue:7
msgid "loading data"
msgstr "loading data"
#: src/pages/maintance/index.vue:18
msgid "local backup"
msgstr "local backup"
#: src/components/tabs/index.vue:35
msgid "maintain"
msgstr "maintain"
#: src/components/tabs/index.vue:31
msgid "manual install"
msgstr "manual install"
#: src/plugins/i18n/index.ts:42
msgid "monitor"
msgstr "Monitor"
#: src/plugins/i18n/index.ts:40
msgid "multimedia"
msgstr "Multimedia"
#: src/plugins/i18n/index.ts:41
msgid "nas"
msgstr "NAS"
#: src/plugins/i18n/index.ts:36
msgid "net"
msgstr "Net"
#: src/plugins/i18n/index.ts:44
msgid "networking"
msgstr "Networking"
#: src/pages/upload/index.vue:14 src/pages/upload/index.vue:15
msgid "no files selected"
msgstr "no files selected"
#: src/pages/maintance/localBackup.vue:12
msgid "no internet required for recovery"
msgstr "no internet required for recovery"
#: src/pages/upload/index.vue:4
msgid "offline install"
msgstr "offline install"
#: src/pages/upload/index.vue:101
msgid "offline installation failed with error code"
msgstr "offline installation failed with error code"
#: src/pages/upload/index.vue:98
msgid "offline installation is successful, please close the current window"
msgstr "offline installation is successful, please close the current window"
#: src/components/app/index.vue:74
msgid "open"
msgstr "open"
#: src/pages/store/components/sort.vue:3
msgid "order"
msgstr "order"
#: src/pages/maintance/localBackup.vue:29
msgid "please enter an absolute path starting with %{name}"
msgstr "please enter an absolute path starting with %{name}"
#: src/pages/maintance/localBackup.vue:140
msgid "please enter the path, give up the input, please clear the input box"
msgstr "please enter the path, give up the input, please clear the input box"
#: src/pages/store/components/search.vue:6
msgid "please enter the search keyword"
msgstr "please enter the search keyword"
#: src/pages/maintance/localBackup.vue:158
#: src/pages/maintance/localBackup.vue:192
msgid "please fill in the external storage directory"
msgstr "please fill in the external storage directory"
#: src/pages/maintance/localBackup.vue:225
msgid "please select a backup file to restore"
msgstr "please select a backup file to restore"
#: src/pages/maintance/lightBackup.vue:21
#: src/pages/maintance/localBackup.vue:36
msgid "restore backup"
msgstr "restore backup"
#: src/pages/maintance/localBackup.vue:47
msgid "restore now"
msgstr "restore now"
#: src/pages/maintance/localBackup.vue:228
msgid "restoring backup"
msgstr "restoring backup"
#: src/pages/upload/index.vue:17
msgid "select or drag and drop files"
msgstr "select or drag and drop files"
#: src/plugins/i18n/index.ts:39
msgid "service"
msgstr "Service"
#: src/pages/upload/index.vue:9
msgid "support .ipk plug-in, .run self-extracting format"
msgstr "support .ipk plug-in, .run self-extracting format"
#: src/plugins/i18n/index.ts:43
msgid "system"
msgstr "System"
#: src/pages/store/components/tag.vue:4
msgid "tag"
msgstr "Tag"
#: src/pages/maintance/localBackup.vue:241
msgid "the backup was restored fail"
msgstr "the backup was restored fail"
#: src/pages/maintance/localBackup.vue:233
msgid "the backup was restored success"
msgstr "the backup was restored success"
#: src/pages/maintance/update.vue:13
msgid "the is last version"
msgstr "the is last version"
#: src/components/app/index.vue:141
msgid "the update is success, please close the current window"
msgstr "the update is success, please close the current window"
#: src/pages/maintance/localBackup.vue:168
msgid "there are no backup files in this path"
msgstr "there are no backup files in this path"
#: src/plugins/i18n/index.ts:37
msgid "tool"
msgstr "Tool"
#: src/components/app/index.vue:77 src/components/app/index.vue:78
msgid "uninstall"
msgstr "uninstall"
#: src/components/app/index.vue:201
msgid "uninstall failed, error code"
msgstr "uninstall failed, error code"
#: src/components/app/index.vue:198
msgid "uninstallation succeeded, please close the current window"
msgstr "uninstallation succeeded, please close the current window"
#: src/components/app/index.vue:186
msgid "uninstalling plugin"
msgstr "uninstalling plugin"
#: src/components/app/index.vue:54
msgid "update date"
msgstr "update date"
#: src/pages/maintance/update.vue:46
msgid "update error"
msgstr "update error"
#: src/components/app/index.vue:144
msgid "update failed with error code"
msgstr "update failed with error code"
#: src/pages/maintance/update.vue:37
msgid "update success"
msgstr "update success"
#: src/pages/maintance/update.vue:32
msgid "updateing"
msgstr "updateing"
#. `正在更新插件`,
#: src/components/app/index.vue:129
msgid "updating plugin"
msgstr "updating plugin"
#: src/components/app/index.vue:68 src/pages/maintance/index.vue:4
msgid "upgrade"
msgstr "upgrade"
#: src/pages/maintance/lightBackup.vue:13
msgid "upload software list and install from iStore when restoring backup"
msgstr "upload software list and install from iStore when restoring backup"
#: src/pages/upload/index.vue:84
msgid "uploading plugin"
msgstr "uploading plugin"
#: src/components/app/index.vue:61
msgid "website"
msgstr "website"
#: src/components/app/index.vue:223
msgid "you have already liked"
msgstr "you have already liked"

View File

@ -1,375 +0,0 @@
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
#: src/components/app/index.vue:24
msgid "%{ num } download"
msgid_plural "%{ num } downloads"
msgstr[0] ""
msgstr[1] ""
#: src/components/app/index.vue:31
msgid "%{ num } like"
msgid_plural "%{ num } likes"
msgstr[0] ""
msgstr[1] ""
#: src/components/tabs/index.vue:27
msgid "all app"
msgstr ""
#: src/pages/maintance/index.vue:8
msgid "app backup"
msgstr ""
#: src/components/app/index.vue:179
msgid "are you sure you want to uninstall %{name}?"
msgstr ""
#: src/components/app/index.vue:50
msgid "author"
msgstr ""
#: src/pages/maintance/lightBackup.vue:42
#: src/pages/maintance/localBackup.vue:208
msgid "backup fail"
msgstr ""
#: src/pages/maintance/lightBackup.vue:18
#: src/pages/maintance/localBackup.vue:34
msgid "backup now"
msgstr ""
#: src/pages/maintance/localBackup.vue:62
msgid "backup now backs up installed software (unlimited installation sources) to external storage"
msgstr ""
#: src/pages/maintance/lightBackup.vue:9
msgid "backup now will download a list of iStore installed software"
msgstr ""
#: src/pages/maintance/lightBackup.vue:41
#: src/pages/maintance/localBackup.vue:200
msgid "backup success"
msgstr ""
#: src/pages/maintance/lightBackup.vue:40
#: src/pages/maintance/localBackup.vue:195
msgid "backuping"
msgstr ""
#: src/pages/store/components/sort.vue:24
msgid "By download"
msgstr ""
#: src/pages/store/components/sort.vue:28
msgid "By rating"
msgstr ""
#: src/pages/maintance/update.vue:4
msgid "checking for latest version"
msgstr ""
#: src/pages/maintance/localBackup.vue:22
msgid "choose"
msgstr ""
#: src/pages/maintance/localBackup.vue:41
msgid "choose backup file"
msgstr ""
#: src/pages/maintance/lightBackup.vue:43
msgid "click to download"
msgstr ""
#: src/pages/maintance/update.vue:11
msgid "click to update"
msgstr ""
#: src/components/app/index.vue:131
#: src/components/app/index.vue:154
#: src/components/app/index.vue:188
#: src/components/toast/index.vue:3
#: src/pages/upload/index.vue:86
msgid "closed"
msgstr ""
#: src/pages/maintance/localBackup.vue:26
msgid "customize"
msgstr ""
#: src/pages/store/components/sort.vue:20
#: src/pages/store/components/tag.vue:8
msgid "default"
msgstr ""
#: src/components/app/index.vue:130
#: src/components/app/index.vue:153
#: src/components/app/index.vue:187
#: src/pages/upload/index.vue:85
msgid "do not refresh this page during plugin installation/uninstallation"
msgstr ""
#: src/plugins/i18n/index.ts:38
msgid "download"
msgstr ""
#: src/pages/maintance/lightBackup.vue:4
#: src/pages/maintance/localBackup.vue:4
msgid "explain"
msgstr ""
#: src/pages/maintance/localBackup.vue:16
msgid "external storage directory"
msgstr ""
#: src/pages/upload/index.vue:6
msgid "from this page, you can upload plugin packages to install plugins"
msgstr ""
#: src/components/app/index.vue:6
msgid "Icon is gone"
msgstr ""
#: src/components/app/index.vue:83
msgid "install"
msgstr ""
#: src/components/app/index.vue:172
msgid "installation failed, error code"
msgstr ""
#: src/components/app/index.vue:169
msgid "installation is complete, please close the current window"
msgstr ""
#: src/components/tabs/index.vue:23
msgid "installed"
msgstr ""
#. `正在安装插件`,
#: src/components/app/index.vue:152
msgid "installing plugin"
msgstr ""
#: src/pages/maintance/update.vue:9
msgid "last version"
msgstr ""
#: src/pages/maintance/index.vue:13
msgid "light backup"
msgstr ""
#: src/components/app/index.vue:40
msgid "like"
msgstr ""
#: src/components/app/index.vue:37
msgid "liked"
msgstr ""
#: src/pages/store/components/apps.vue:7
msgid "loading data"
msgstr ""
#: src/pages/maintance/index.vue:18
msgid "local backup"
msgstr ""
#: src/components/tabs/index.vue:35
msgid "maintain"
msgstr ""
#: src/components/tabs/index.vue:31
msgid "manual install"
msgstr ""
#: src/plugins/i18n/index.ts:42
msgid "monitor"
msgstr ""
#: src/plugins/i18n/index.ts:40
msgid "multimedia"
msgstr ""
#: src/plugins/i18n/index.ts:41
msgid "nas"
msgstr ""
#: src/plugins/i18n/index.ts:36
msgid "net"
msgstr ""
#: src/plugins/i18n/index.ts:44
msgid "networking"
msgstr ""
#: src/pages/upload/index.vue:14
#: src/pages/upload/index.vue:15
msgid "no files selected"
msgstr ""
#: src/pages/maintance/localBackup.vue:12
msgid "no internet required for recovery"
msgstr ""
#: src/pages/upload/index.vue:4
msgid "offline install"
msgstr ""
#: src/pages/upload/index.vue:101
msgid "offline installation failed with error code"
msgstr ""
#: src/pages/upload/index.vue:98
msgid "offline installation is successful, please close the current window"
msgstr ""
#: src/components/app/index.vue:74
msgid "open"
msgstr ""
#: src/pages/store/components/sort.vue:3
msgid "order"
msgstr ""
#: src/pages/maintance/localBackup.vue:29
msgid "please enter an absolute path starting with %{name}"
msgstr ""
#: src/pages/maintance/localBackup.vue:140
msgid "please enter the path, give up the input, please clear the input box"
msgstr ""
#: src/pages/store/components/search.vue:6
msgid "please enter the search keyword"
msgstr ""
#: src/pages/maintance/localBackup.vue:158
#: src/pages/maintance/localBackup.vue:192
msgid "please fill in the external storage directory"
msgstr ""
#: src/pages/maintance/localBackup.vue:225
msgid "please select a backup file to restore"
msgstr ""
#: src/pages/maintance/lightBackup.vue:21
#: src/pages/maintance/localBackup.vue:36
msgid "restore backup"
msgstr ""
#: src/pages/maintance/localBackup.vue:47
msgid "restore now"
msgstr ""
#: src/pages/maintance/localBackup.vue:228
msgid "restoring backup"
msgstr ""
#: src/pages/upload/index.vue:17
msgid "select or drag and drop files"
msgstr ""
#: src/plugins/i18n/index.ts:39
msgid "service"
msgstr ""
#: src/pages/upload/index.vue:9
msgid "support .ipk plug-in, .run self-extracting format"
msgstr ""
#: src/plugins/i18n/index.ts:43
msgid "system"
msgstr ""
#: src/pages/store/components/tag.vue:4
msgid "tag"
msgstr ""
#: src/pages/maintance/localBackup.vue:241
msgid "the backup was restored fail"
msgstr ""
#: src/pages/maintance/localBackup.vue:233
msgid "the backup was restored success"
msgstr ""
#: src/pages/maintance/update.vue:13
msgid "the is last version"
msgstr ""
#: src/components/app/index.vue:141
msgid "the update is success, please close the current window"
msgstr ""
#: src/pages/maintance/localBackup.vue:168
msgid "there are no backup files in this path"
msgstr ""
#: src/plugins/i18n/index.ts:37
msgid "tool"
msgstr ""
#: src/components/app/index.vue:77
#: src/components/app/index.vue:78
msgid "uninstall"
msgstr ""
#: src/components/app/index.vue:201
msgid "uninstall failed, error code"
msgstr ""
#: src/components/app/index.vue:198
msgid "uninstallation succeeded, please close the current window"
msgstr ""
#: src/components/app/index.vue:186
msgid "uninstalling plugin"
msgstr ""
#: src/components/app/index.vue:54
msgid "update date"
msgstr ""
#: src/pages/maintance/update.vue:46
msgid "update error"
msgstr ""
#: src/components/app/index.vue:144
msgid "update failed with error code"
msgstr ""
#: src/pages/maintance/update.vue:37
msgid "update success"
msgstr ""
#: src/pages/maintance/update.vue:32
msgid "updateing"
msgstr ""
#. `正在更新插件`,
#: src/components/app/index.vue:129
msgid "updating plugin"
msgstr ""
#: src/components/app/index.vue:68
#: src/pages/maintance/index.vue:4
msgid "upgrade"
msgstr ""
#: src/pages/maintance/lightBackup.vue:13
msgid "upload software list and install from iStore when restoring backup"
msgstr ""
#: src/pages/upload/index.vue:84
msgid "uploading plugin"
msgstr ""
#: src/components/app/index.vue:61
msgid "website"
msgstr ""
#: src/components/app/index.vue:223
msgid "you have already liked"
msgstr ""

View File

@ -1,374 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: istore 0.1\n"
"Last-Translator: jjm2473\n"
"Language-Team: none\n"
"Language: zh-cn\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/components/app/index.vue:24
msgid "%{ num } download"
msgid_plural "%{ num } downloads"
msgstr[0] "%{ num } 次下载"
msgstr[1] "%{ num } 次下载"
#: src/components/app/index.vue:31
msgid "%{ num } like"
msgid_plural "%{ num } likes"
msgstr[0] "%{ num } 次点赞"
msgstr[1] "%{ num } 次点赞"
#: src/components/tabs/index.vue:27
msgid "all app"
msgstr "全部软件"
#: src/pages/maintance/index.vue:8
msgid "app backup"
msgstr "软件备份"
#: src/components/app/index.vue:179
msgid "are you sure you want to uninstall %{name}?"
msgstr "确定要卸载 %{name} 吗?"
#: src/components/app/index.vue:50
msgid "author"
msgstr "作者"
#: src/pages/maintance/lightBackup.vue:42
#: src/pages/maintance/localBackup.vue:208
msgid "backup fail"
msgstr "备份失败"
#: src/pages/maintance/lightBackup.vue:18
#: src/pages/maintance/localBackup.vue:34
msgid "backup now"
msgstr "立即备份"
#: src/pages/maintance/localBackup.vue:62
msgid ""
"backup now backs up installed software (unlimited installation sources) to "
"external storage"
msgstr "立即备份将备份已安装软件(不限安装来源)到外部存储"
#: src/pages/maintance/lightBackup.vue:9
msgid "backup now will download a list of iStore installed software"
msgstr "立即备份将下载iStore已安装的软件列表"
#: src/pages/maintance/lightBackup.vue:41
#: src/pages/maintance/localBackup.vue:200
msgid "backup success"
msgstr "备份成功"
#: src/pages/maintance/lightBackup.vue:40
#: src/pages/maintance/localBackup.vue:195
msgid "backuping"
msgstr "正在备份"
#: src/pages/store/components/sort.vue:24
msgid "By download"
msgstr "按下载"
#: src/pages/store/components/sort.vue:28
msgid "By rating"
msgstr "按评分"
#: src/pages/maintance/update.vue:4
msgid "checking for latest version"
msgstr "正在检查最新版本"
#: src/pages/maintance/localBackup.vue:22
msgid "choose"
msgstr "请选择"
#: src/pages/maintance/localBackup.vue:41
msgid "choose backup file"
msgstr "选择备份文件"
#: src/pages/maintance/lightBackup.vue:43
msgid "click to download"
msgstr "点此下载"
#: src/pages/maintance/update.vue:11
msgid "click to update"
msgstr "点我更新"
#: src/components/app/index.vue:131 src/components/app/index.vue:154
#: src/components/app/index.vue:188 src/components/toast/index.vue:3
#: src/pages/upload/index.vue:86
msgid "closed"
msgstr "关闭"
#: src/pages/maintance/localBackup.vue:26
msgid "customize"
msgstr "自定义"
#: src/pages/store/components/sort.vue:20 src/pages/store/components/tag.vue:8
msgid "default"
msgstr "默认"
#: src/components/app/index.vue:130 src/components/app/index.vue:153
#: src/components/app/index.vue:187 src/pages/upload/index.vue:85
msgid "do not refresh this page during plugin installation/uninstallation"
msgstr "插件安装/卸载过程中请勿刷新此页面"
#: src/plugins/i18n/index.ts:38
msgid "download"
msgstr "下载"
#: src/pages/maintance/lightBackup.vue:4 src/pages/maintance/localBackup.vue:4
msgid "explain"
msgstr "说明"
#: src/pages/maintance/localBackup.vue:16
msgid "external storage directory"
msgstr "外部存储目录"
#: src/pages/upload/index.vue:6
msgid "from this page, you can upload plugin packages to install plugins"
msgstr "通过本页,你可以上传插件包来安装插件"
#: src/components/app/index.vue:6
msgid "Icon is gone"
msgstr "图标出走啦"
#: src/components/app/index.vue:83
msgid "install"
msgstr "安装"
#: src/components/app/index.vue:172
msgid "installation failed, error code"
msgstr "安装失败,错误码"
#: src/components/app/index.vue:169
msgid "installation is complete, please close the current window"
msgstr "安装完成,请关闭当前窗口"
#: src/components/tabs/index.vue:23
msgid "installed"
msgstr "已安装"
#. `正在安装插件`,
#: src/components/app/index.vue:152
msgid "installing plugin"
msgstr "正在安装插件"
#: src/pages/maintance/update.vue:9
msgid "last version"
msgstr "最新版本"
#: src/pages/maintance/index.vue:13
msgid "light backup"
msgstr "轻量备份"
#: src/components/app/index.vue:40
msgid "like"
msgstr "点赞"
#: src/components/app/index.vue:37
msgid "liked"
msgstr "已点赞"
#: src/pages/store/components/apps.vue:7
msgid "loading data"
msgstr "正在努力的获取数据"
#: src/pages/maintance/index.vue:18
msgid "local backup"
msgstr "本地备份"
#: src/components/tabs/index.vue:35
msgid "maintain"
msgstr "维护"
#: src/components/tabs/index.vue:31
msgid "manual install"
msgstr "手动安装"
#: src/plugins/i18n/index.ts:42
msgid "monitor"
msgstr "监控"
#: src/plugins/i18n/index.ts:40
msgid "multimedia"
msgstr "多媒体"
#: src/plugins/i18n/index.ts:41
msgid "nas"
msgstr "NAS"
#: src/plugins/i18n/index.ts:36
msgid "net"
msgstr "网络"
#: src/plugins/i18n/index.ts:44
msgid "networking"
msgstr "组网"
#: src/pages/upload/index.vue:14 src/pages/upload/index.vue:15
msgid "no files selected"
msgstr "未选择任何文件"
#: src/pages/maintance/localBackup.vue:12
msgid "no internet required for recovery"
msgstr "恢复时不需要网络"
#: src/pages/upload/index.vue:4
msgid "offline install"
msgstr "离线安装"
#: src/pages/upload/index.vue:101
msgid "offline installation failed with error code"
msgstr "离线安装失败,错误码"
#: src/pages/upload/index.vue:98
msgid "offline installation is successful, please close the current window"
msgstr "离线安装成功,请关闭当前窗口"
#: src/components/app/index.vue:74
msgid "open"
msgstr "打开"
#: src/pages/store/components/sort.vue:3
msgid "order"
msgstr "排序"
#: src/pages/maintance/localBackup.vue:29
msgid "please enter an absolute path starting with %{name}"
msgstr "请输入 %{name} 开头的绝对路径"
#: src/pages/maintance/localBackup.vue:140
msgid "please enter the path, give up the input, please clear the input box"
msgstr "请输入路径,放弃输入请清空输入框"
#: src/pages/store/components/search.vue:6
msgid "please enter the search keyword"
msgstr "请输入搜索关键词"
#: src/pages/maintance/localBackup.vue:158
#: src/pages/maintance/localBackup.vue:192
msgid "please fill in the external storage directory"
msgstr "请填写外部存储目录"
#: src/pages/maintance/localBackup.vue:225
msgid "please select a backup file to restore"
msgstr "请选择要恢复的备份文件"
#: src/pages/maintance/lightBackup.vue:21
#: src/pages/maintance/localBackup.vue:36
msgid "restore backup"
msgstr "恢复备份"
#: src/pages/maintance/localBackup.vue:47
msgid "restore now"
msgstr "立即恢复"
#: src/pages/maintance/localBackup.vue:228
msgid "restoring backup"
msgstr "正在恢复备份"
#: src/pages/upload/index.vue:17
msgid "select or drag and drop files"
msgstr "选择或拖放文件"
#: src/plugins/i18n/index.ts:39
msgid "service"
msgstr "服务"
#: src/pages/upload/index.vue:9
msgid "support .ipk plug-in, .run self-extracting format"
msgstr "支持 .ipk 插件,.run 自解压格式"
#: src/plugins/i18n/index.ts:43
msgid "system"
msgstr "系统"
#: src/pages/store/components/tag.vue:4
msgid "tag"
msgstr "标签"
#: src/pages/maintance/localBackup.vue:241
msgid "the backup was restored fail"
msgstr "恢复备份失败"
#: src/pages/maintance/localBackup.vue:233
msgid "the backup was restored success"
msgstr "恢复备份成功"
#: src/pages/maintance/update.vue:13
msgid "the is last version"
msgstr "当前已经是最新版本"
#: src/components/app/index.vue:141
msgid "the update is success, please close the current window"
msgstr "更新成功,请关闭当前窗口"
#: src/pages/maintance/localBackup.vue:168
msgid "there are no backup files in this path"
msgstr "此路径下没有备份文件"
#: src/plugins/i18n/index.ts:37
msgid "tool"
msgstr "工具"
#: src/components/app/index.vue:77 src/components/app/index.vue:78
msgid "uninstall"
msgstr "卸载"
#: src/components/app/index.vue:201
msgid "uninstall failed, error code"
msgstr "卸载失败,错误码"
#: src/components/app/index.vue:198
msgid "uninstallation succeeded, please close the current window"
msgstr "卸载完成,请关闭当前窗口"
#: src/components/app/index.vue:186
msgid "uninstalling plugin"
msgstr "正在卸载插件"
#: src/components/app/index.vue:54
msgid "update date"
msgstr "更新日期"
#: src/pages/maintance/update.vue:46
msgid "update error"
msgstr "更新失败"
#: src/components/app/index.vue:144
msgid "update failed with error code"
msgstr "更新失败,错误代码"
#: src/pages/maintance/update.vue:37
msgid "update success"
msgstr "更新成功"
#: src/pages/maintance/update.vue:32
msgid "updateing"
msgstr "正在更新中"
#. `正在更新插件`,
#: src/components/app/index.vue:129
msgid "updating plugin"
msgstr "正在更新插件"
#: src/components/app/index.vue:68 src/pages/maintance/index.vue:4
msgid "upgrade"
msgstr "更新"
#: src/pages/maintance/lightBackup.vue:13
msgid "upload software list and install from iStore when restoring backup"
msgstr "复备份时上传软件列表并从iStore安装"
#: src/pages/upload/index.vue:84
msgid "uploading plugin"
msgstr "正在上传插件"
#: src/components/app/index.vue:61
msgid "website"
msgstr "官网"
#: src/components/app/index.vue:223
msgid "you have already liked"
msgstr "您已经点赞过啦"

View File

@ -1,68 +0,0 @@
#
# Copyright (C) 2015-2016 OpenWrt.org
# Copyright (C) 2020 jjm2473@gmail.com
#
# This is free software, licensed under the GNU General Public License v3.
#
include $(TOPDIR)/rules.mk
PKG_ARCH_LINKEASE:=$(ARCH)
PKG_NAME:=linkease
PKG_VERSION:=1.2.9
PKG_RELEASE:=$(PKG_ARCH_LINKEASE)-2
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://fw0.koolcenter.com/binary/LinkEase/LinuxStorage/
PKG_HASH:=31e3eea526d8328a59e1bfd39e7800cea935d62721958227f40d52b495ce3712
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-binary-$(PKG_VERSION)
PKG_BUILD_PARALLEL:=1
PKG_USE_MIPS16:=0
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=net
CATEGORY:=Network
SUBMENU:=Web Servers/Proxies
TITLE:=LinkEase - the file cloud
DEPENDS:=@(arm||x86_64||aarch64) +ffmpeg-remux
PKGARCH:=all
URL:=https://www.ddnsto.com/linkease/
endef
define Package/$(PKG_NAME)/description
LinkEase is a file cloud
endef
define Package/$(PKG_NAME)/conffiles
/etc/config/linkease
endef
define Package/$(PKG_NAME)/postinst
#!/bin/sh
if [ -z "$${IPKG_INSTROOT}" ]; then
[ -f /etc/uci-defaults/linkease ] && /etc/uci-defaults/linkease && rm -f /etc/uci-defaults/linkease
fi
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/sbin/linkease-plugins $(1)/etc/config $(1)/etc/init.d $(1)/etc/uci-defaults
$(INSTALL_BIN) $(PKG_BUILD_DIR)/linkease.$(PKG_ARCH_LINKEASE) $(1)/usr/sbin/linkease
$(INSTALL_BIN) $(PKG_BUILD_DIR)/heif-converter.$(PKG_ARCH_LINKEASE) $(1)/usr/sbin/heif-converter
$(INSTALL_BIN) ./files/linkease-config.sh $(1)/usr/sbin/linkease-config.sh
$(INSTALL_BIN) ./files/aria2.sh $(1)/usr/sbin/linkease-plugins/aria2.sh
$(INSTALL_CONF) ./files/linkease.config $(1)/etc/config/linkease
$(INSTALL_BIN) ./files/linkease.init $(1)/etc/init.d/linkease
$(INSTALL_BIN) ./files/linkease.uci-default $(1)/etc/uci-defaults/linkease
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

34
linkease/README.md Normal file
View File

@ -0,0 +1,34 @@
# nas-packages-luci
luci for [nas-packages](https://github.com/linkease/nas-packages)
## 使用方法
### 增加feed源
```shell
echo >> feeds.conf.default
echo 'src-git nas https://github.com/linkease/nas-packages.git;master' >> feeds.conf.default
echo 'src-git nas_luci https://github.com/linkease/nas-packages-luci.git;main' >> feeds.conf.default
./scripts/feeds update nas nas_luci
./scripts/feeds install -a -p nas
./scripts/feeds install -a -p nas_luci
```
### 集成软件包
```shell
make menuconfig
```
选择软件包
```plain
LuCI --->
3. Applications --->
<*> luci-app-ddnsto.................................. LuCI support for ddnsto
<*> luci-app-linkease.................................. LuCI support for linkease
```
### 构建固件
```shell
make
```

View File

@ -1,134 +0,0 @@
#!/bin/bash
sh_ver="1.0.0"
export PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/sbin:/bin
aria2_conf_dir=/var/etc/aria2/
#替换成你设备aria2.conf路径
aria2_conf=${aria2_conf_dir}/aria2.conf.main
#替换成你设备的aria2c路径
aria2c=/usr/bin/aria2c
Green_font_prefix="\033[32m"
Red_font_prefix="\033[31m"
Green_background_prefix="\033[42;37m"
Red_background_prefix="\033[41;37m"
Font_color_suffix="\033[0m"
Info="[${Green_font_prefix}信息${Font_color_suffix}]"
Error="[${Red_font_prefix}错误${Font_color_suffix}]"
Tip="[${Green_font_prefix}注意${Font_color_suffix}]"
error_code=11
success_code=0
return_error(){
echo 'Content-Type:application/json;charset=utf-8'
echo
echo "{
"\"success\"":$error_code,
"\"error\"":"\"$1\"",
"\"result"\":null
}"
exit 1
}
return_ok(){
echo 'Content-Type:application/json;charset=utf-8'
echo
echo "{
"\"success\"":$success_code,
"\"error\"":"\"$1\"",
"\"result"\":null
}"
exit 0
}
return_result(){
echo 'Content-Type:application/json;charset=utf-8'
echo
echo "{
"\"success\"":$success_code,
"\"error\"":"\"\"",
"\"result"\":$1
}"
exit 0
}
#进程中是否运行aria2
check_pid() {
PID=$(ps -ef | grep "aria2c" | grep -v grep | grep -v "aria2.sh" | grep -v "init.d" | grep -v "service" | awk '{print $2}')
}
#aria2是否正在运行
aria2_work_status(){
check_pid
# [[ ! -z ${PID} ]] && echo -e "${Error} Aria2 正在运行,请检查 !" && exit 1
[[ ! -z ${PID} ]] && return_ok "Aria2正在运行"
return_error "Aria2未运行"
}
#检测设备是否安装aria2
check_installed_status() {
[[ ! -e ${aria2c} ]] && return_error "Aria2 没有安装,请检查 !"
[[ ! -e ${aria2_conf} ]] && return_error "Aria2 配置文件不存在,请检查 !"
# return_ok "Aria2已安装"
}
#读取aria2配置信息
read_config() {
check_installed_status
if [[ ! -e ${aria2_conf} ]]; then
return_error "Aria2 配置文件不存在,请检查 !"
else
conf_text=$(cat ${aria2_conf} | grep -v '#')
aria2_dir=$(echo -e "${conf_text}" | grep "^dir=" | awk -F "=" '{print $NF}')
aria2_port=$(echo -e "${conf_text}" | grep "^rpc-listen-port=" | awk -F "=" '{print $NF}')
aria2_passwd=$(echo -e "${conf_text}" | grep "^rpc-secret=" | awk -F "=" '{print $NF}')
aria2_bt_port=$(echo -e "${conf_text}" | grep "^listen-port=" | awk -F "=" '{print $NF}')
aria2_dht_port=$(echo -e "${conf_text}" | grep "^dht-listen-port=" | awk -F "=" '{print $NF}')
return_result "{
"\"dir"\":"\"$aria2_dir"\",
"\"rpc-listen-port"\":"\"$aria2_port"\",
"\"rpc-secret"\":"\"$aria2_passwd"\",
"\"listen-port"\":"\"$aria2_bt_port"\",
"\"dht-listen-port"\":"\"$aria2_dht_port"\"}"
fi
}
#"Content-Type:text/html;charset=utf-8"
#echo
#SERVER_SOFTWARE = $SERVER_SOFTWARE #服务器软件
#SERVER_NAME = $SERVER_NAME #服务器主机名
#GATEWAY_INTERFACE = $GATEWAY_INTERFACE #CGI版本
#SERVER_PROTOCOL = $SERVER_PROTOCOL #通信使用的协议
#SERVER_PORT = $SERVER_PORT #服务器的端口号
#REQUEST_METHOD = $REQUEST_METHOD #请求方法(GET/POST/PUT/DELETE..)
#HTTP_ACCEPT = $HTTP_ACCEPT #HTTP定义的浏览器能够接受的数据类型
#SCRIPT_NAME = $SCRIPT_NAME #当前运行的脚本名称(包含路径)
#QUERY_STRING = $QUERY_STRING #地址栏中传的数据get方式
#REMOTE_ADDR = $REMOTE_ADDR #客户端的ip
#根据url QUERY调不同方法
query(){
aria2Query=${QUERY_STRING}
parse(){
echo $1 | sed 's/.*'$2'=\([[:alnum:]]*\).*/\1/'
}
value=$(parse $aria2Query "action")
if [ ! -z = "$value" ]
then
if [ "$value" = "status" ]
then
check_installed_status
elif [ "$value" = "readConfig" ]
then
read_config
elif [ "$value" = "workStatus" ]
then
aria2_work_status
else
echo
fi
else
return_error "action不能为空"
fi
}
query

View File

@ -1,89 +0,0 @@
#!/bin/sh
source /lib/functions.sh
case "$1" in
save)
if [ ! -z "$2" ]; then
uci set "linkease.@linkease[0].preconfig=$2"
uci commit
fi
;;
load)
if [ -f "/usr/sbin/preconfig.data" ]; then
data="`cat /usr/sbin/preconfig.data`"
uci set "linkease.@linkease[0].preconfig=${data}"
uci commit
rm /usr/sbin/preconfig.data
else
data="`uci -q get linkease.@linkease[0].preconfig`"
fi
if [ -z "${data}" ]; then
echo "nil"
else
echo "${data}"
fi
;;
local_save)
if [ ! -z "$2" ]; then
uci set "linkease.@linkease[0].local_home=$2"
uci commit
ROOT_DIR="$2"
if [ -f "/etc/config/quickstart" ]; then
config_load quickstart
config_get MAIN_DIR main main_dir ""
config_get CONF_DIR main conf_dir ""
config_get PUB_DIR main pub_dir ""
config_get DL_DIR main dl_dir ""
config_get TMP_DIR main tmp_dir ""
# echo "$MAIN_DIR $CONF_DIR $PUB_DIR $DL_DIR $TMP_DIR"
if [ "$ROOT_DIR" = "$MAIN_DIR" ]; then
exit 0
fi
uci set "quickstart.main.main_dir=$ROOT_DIR"
if [ -z "$CONF_DIR" -o "$CONF_DIR" = "$MAIN_DIR/Configs" ]; then
uci set "quickstart.main.conf_dir=$ROOT_DIR/Configs"
fi
if [ -z "$PUB_DIR" -o "$PUB_DIR" = "$MAIN_DIR/Public" ]; then
uci set "quickstart.main.pub_dir=$ROOT_DIR/Public"
fi
if [ -z "$DL_DIR" -o "$DL_DIR" = "$MAIN_DIR/Public/Downloads" ]; then
uci set "quickstart.main.dl_dir=$ROOT_DIR/Public/Downloads"
fi
if [ -z "$TMP_DIR" -o "$TMP_DIR" = "$MAIN_DIR/Caches" ]; then
uci set "quickstart.main.tmp_dir=$ROOT_DIR/Caches"
fi
uci commit
fi
fi
;;
local_load)
if [ -f "/etc/config/quickstart" ]; then
data="`uci -q get quickstart.main.main_dir`"
fi
if [ -z "$data" ]; then
data="`uci -q get linkease.@linkease[0].local_home`"
fi
if [ -z "${data}" ]; then
echo "nil"
else
echo "${data}"
fi
;;
status)
echo "TODO"
;;
*)
echo "Usage: $0 {save|load|status}"
exit 1
esac

View File

@ -1,3 +0,0 @@
config linkease
option port '8897'
option enabled '1'

View File

@ -1,28 +0,0 @@
#!/bin/sh /etc/rc.common
START=99
USE_PROCD=1
get_config() {
config_get_bool enabled $1 enabled 1
config_get_bool logger $1 logger
config_get port $1 port 8897
}
start_service() {
config_load linkease
config_foreach get_config linkease
[ $enabled != 1 ] && return 1
procd_open_instance
procd_set_param limits nofile="65535 65535"
procd_set_param command /usr/sbin/linkease
[ -n "$port" ] && procd_append_param command --deviceAddr ":$port" --localApi /var/run/linkease.sock
[ "$logger" == 1 ] && procd_set_param stderr 1
procd_set_param respawn
procd_close_instance
}
service_triggers() {
procd_add_reload_trigger "linkease"
}

View File

@ -1,22 +0,0 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@linkease[-1]
add ucitrack linkease
set ucitrack.@linkease[-1].init=linkease
commit ucitrack
delete firewall.linkease
set firewall.linkease=rule
set firewall.linkease.name="linkease"
set firewall.linkease.target="ACCEPT"
set firewall.linkease.src="wan"
set firewall.linkease.proto="tcp"
set firewall.linkease.dest_port="8897"
commit firewall
EOF
/etc/init.d/linkease enable
/etc/init.d/linkease start
exit 0

View File

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

View File

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

View File

Before

Width:  |  Height:  |  Size: 527 B

After

Width:  |  Height:  |  Size: 527 B

View File

Before

Width:  |  Height:  |  Size: 692 B

After

Width:  |  Height:  |  Size: 692 B

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

Before

Width:  |  Height:  |  Size: 317 B

After

Width:  |  Height:  |  Size: 317 B

Some files were not shown because too many files have changed in this diff Show More