mirror of
https://github.com/roacn/openwrt-packages.git
synced 2025-01-07 03:16:45 +08:00
🍕 Sync 2022-03-26 23:03
This commit is contained in:
parent
da9c7d82b7
commit
0dda0dcb0d
77
aliyundrive-fuse/Makefile
Normal file
77
aliyundrive-fuse/Makefile
Normal file
@ -0,0 +1,77 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=aliyundrive-fuse
|
||||
PKG_VERSION:=0.1.8
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_MAINTAINER:=messense <messense@icloud.com>
|
||||
|
||||
PKG_LIBC:=musl
|
||||
ifeq ($(ARCH),arm)
|
||||
PKG_LIBC:=musleabi
|
||||
|
||||
ARM_CPU_FEATURES:=$(word 2,$(subst +,$(space),$(call qstrip,$(CONFIG_CPU_TYPE))))
|
||||
ifneq ($(filter $(ARM_CPU_FEATURES),vfp vfpv2),)
|
||||
PKG_LIBC:=musleabihf
|
||||
endif
|
||||
endif
|
||||
|
||||
PKG_ARCH=$(ARCH)
|
||||
ifeq ($(ARCH),i386)
|
||||
PKG_ARCH:=i686
|
||||
endif
|
||||
|
||||
PKG_SOURCE:=aliyundrive-fuse-v$(PKG_VERSION).$(PKG_ARCH)-unknown-linux-$(PKG_LIBC).tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/messense/aliyundrive-fuse/releases/download/v$(PKG_VERSION)/
|
||||
PKG_HASH:=skip
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=multimedia
|
||||
CATEGORY:=Multimedia
|
||||
DEPENDS:=+fuse-utils
|
||||
TITLE:=FUSE for AliyunDrive
|
||||
URL:=https://github.com/messense/aliyundrive-fuse
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/description
|
||||
FUSE for AliyunDrive.
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/aliyundrive-fuse
|
||||
endef
|
||||
|
||||
define Download/sha256sum
|
||||
FILE:=$(PKG_SOURCE).sha256
|
||||
URL_FILE:=$(FILE)
|
||||
URL:=$(PKG_SOURCE_URL)
|
||||
HASH:=skip
|
||||
endef
|
||||
$(eval $(call Download,sha256sum))
|
||||
|
||||
define Build/Prepare
|
||||
mv $(DL_DIR)/$(PKG_SOURCE).sha256 .
|
||||
cp $(DL_DIR)/$(PKG_SOURCE) .
|
||||
shasum -a 256 -c $(PKG_SOURCE).sha256
|
||||
rm $(PKG_SOURCE).sha256 $(PKG_SOURCE)
|
||||
|
||||
tar -C $(PKG_BUILD_DIR)/ -zxf $(DL_DIR)/$(PKG_SOURCE)
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
echo "$(PKG_NAME) using precompiled binary."
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/aliyundrive-fuse $(1)/usr/bin/aliyundrive-fuse
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/aliyundrive-fuse.init $(1)/etc/init.d/aliyundrive-fuse
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) ./files/aliyundrive-fuse.config $(1)/etc/config/aliyundrive-fuse
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
7
aliyundrive-fuse/files/aliyundrive-fuse.config
Normal file
7
aliyundrive-fuse/files/aliyundrive-fuse.config
Normal file
@ -0,0 +1,7 @@
|
||||
config default
|
||||
option enable '0'
|
||||
option debug '0'
|
||||
option refresh_token ''
|
||||
option domain_id ''
|
||||
option mount_point '/mnt/aliyundrive'
|
||||
option read_buffer_size '10485760'
|
48
aliyundrive-fuse/files/aliyundrive-fuse.init
Executable file
48
aliyundrive-fuse/files/aliyundrive-fuse.init
Executable file
@ -0,0 +1,48 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
USE_PROCD=1
|
||||
|
||||
START=99
|
||||
STOP=15
|
||||
|
||||
NAME=aliyundrive-fuse
|
||||
|
||||
uci_get_by_type() {
|
||||
local ret=$(uci get $NAME.@$1[0].$2 2>/dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
|
||||
start_service() {
|
||||
local enable=$(uci_get_by_type default enable)
|
||||
case "$enable" in
|
||||
1|on|true|yes|enabled)
|
||||
local refresh_token=$(uci_get_by_type default refresh_token)
|
||||
local domain_id=$(uci_get_by_type default domain_id)
|
||||
local mount_point=$(uci_get_by_type default mount_point)
|
||||
local read_buf_size=$(uci_get_by_type default read_buffer_size 10485760)
|
||||
|
||||
local extra_options=""
|
||||
|
||||
if [[ ! -z "$domain_id" ]]; then
|
||||
extra_options="$extra_options --domain-id $domain_id"
|
||||
fi
|
||||
|
||||
mkdir -p "$mount_point"
|
||||
procd_open_instance
|
||||
procd_set_param command /bin/sh -c "/usr/bin/$NAME $extra_options -S $read_buf_size --workdir /var/run/$NAME $mount_point >>/var/log/$NAME.log 2>&1"
|
||||
procd_set_param pidfile /var/run/$NAME.pid
|
||||
procd_set_param env REFRESH_TOKEN="$refresh_token"
|
||||
case $(uci_get_by_type default debug) in
|
||||
1|on|true|yes|enabled)
|
||||
procd_append_param env RUST_LOG="aliyundrive_fuse=debug" ;;
|
||||
*) ;;
|
||||
esac
|
||||
procd_close_instance ;;
|
||||
*)
|
||||
stop_service ;;
|
||||
esac
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "aliyundrive-fuse"
|
||||
}
|
40
chinadns-ng/Makefile
Normal file
40
chinadns-ng/Makefile
Normal file
@ -0,0 +1,40 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#
|
||||
# Copyright (C) 2021 ImmortalWrt.org
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=chinadns-ng
|
||||
PKG_VERSION:=1.0-beta.25
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/zfl9/chinadns-ng.git
|
||||
PKG_SOURCE_DATE:=2021-05-08
|
||||
PKG_SOURCE_VERSION:=14cc6348d67b09cae37d9bce554c89c2c0e0b265
|
||||
PKG_MIRROR_HASH:=3b66fc0888d9488e3b8e39df3016d51fae1b43325d292381e94aa3c7d2318282
|
||||
|
||||
PKG_LICENSE:=AGPL-3.0-only
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
PKG_MAINTAINER:=pexcn <i@pexcn.me>
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_INSTALL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/chinadns-ng
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=IP Addresses and Names
|
||||
TITLE:=ChinaDNS next generation, refactoring with epoll and ipset.
|
||||
URL:=https://github.com/zfl9/chinadns-ng
|
||||
DEPENDS:=+ipset
|
||||
endef
|
||||
|
||||
define Package/chinadns-ng/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/chinadns-ng $(1)/usr/bin
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,chinadns-ng))
|
53
dns2socks/Makefile
Normal file
53
dns2socks/Makefile
Normal file
@ -0,0 +1,53 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#
|
||||
# Copyright (C) 2021 ImmortalWrt.org
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=dns2socks
|
||||
PKG_VERSION:=2.1
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE:=SourceCode.zip
|
||||
PKG_SOURCE_URL:=@SF/dns2socks
|
||||
PKG_SOURCE_DATE:=2020-02-18
|
||||
PKG_HASH:=406b5003523577d39da66767adfe54f7af9b701374363729386f32f6a3a995f4
|
||||
|
||||
PKG_MAINTAINER:=ghostmaker
|
||||
PKG_LICENSE:=BSD-3-Clause
|
||||
PKG_LICENSE_FILE:=LICENSE
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
UNZIP_CMD:=unzip -q -d $(PKG_BUILD_DIR) $(DL_DIR)/$(PKG_SOURCE)
|
||||
|
||||
define Package/dns2socks
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=IP Addresses and Names
|
||||
TITLE:=DNS to SOCKS or HTTP proxy
|
||||
URL:=http://dns2socks.sourceforge.net/
|
||||
DEPENDS:=+libpthread
|
||||
endef
|
||||
|
||||
define Package/dns2socks/description
|
||||
This is a command line utility to resolve DNS requests via
|
||||
a SOCKS tunnel like Tor or a HTTP proxy.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(TARGET_CC) \
|
||||
$(TARGET_CFLAGS) \
|
||||
$(TARGET_CPPFLAGS) \
|
||||
$(FPIC) \
|
||||
-o $(PKG_BUILD_DIR)/DNS2SOCKS/dns2socks \
|
||||
$(PKG_BUILD_DIR)/DNS2SOCKS/DNS2SOCKS.c \
|
||||
$(TARGET_LDFLAGS) -pthread
|
||||
endef
|
||||
|
||||
define Package/dns2socks/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/DNS2SOCKS/dns2socks $(1)/usr/bin/dns2socks
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,dns2socks))
|
80
hysteria/Makefile
Normal file
80
hysteria/Makefile
Normal file
@ -0,0 +1,80 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#
|
||||
# Copyright (C) 2021 ImmortalWrt.org
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=hysteria
|
||||
PKG_VERSION:=1.0.1
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/HyNetwork/hysteria/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=de3a1dbc4a28bcddda2b1e918b0b309d822ab9eaad764564dfc064c2c0d0e667
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILE:=LICENSE
|
||||
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_HYSTERIA_COMPRESS_GOPROXY \
|
||||
CONFIG_HYSTERIA_COMPRESS_UPX
|
||||
|
||||
PKG_BUILD_DEPENDS:=golang/host
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
|
||||
GO_PKG:=github.com/tobyxdd/hysteria
|
||||
GO_PKG_BUILD_PKG:=github.com/tobyxdd/hysteria/cmd
|
||||
GO_PKG_LDFLAGS:=-s -w
|
||||
GO_PKG_LDFLAGS_X:=main.appVersion=$(PKG_VERSION)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk
|
||||
|
||||
define Package/hysteria
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
TITLE:=A feature-packed network utility optimized for networks of poor quality
|
||||
URL:=https://github.com/tobyxdd/hysteria
|
||||
DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle
|
||||
endef
|
||||
|
||||
define Package/hysteria/description
|
||||
Hysteria is a feature-packed network utility optimized for networks
|
||||
of poor quality (e.g. satellite connections, congested public Wi-Fi,
|
||||
connecting from China to servers abroad) powered by a custom version
|
||||
of QUIC protocol.
|
||||
endef
|
||||
|
||||
define Package/hysteria/config
|
||||
config HYSTERIA_COMPRESS_GOPROXY
|
||||
bool "Compiling with GOPROXY proxy"
|
||||
default n
|
||||
|
||||
config HYSTERIA_COMPRESS_UPX
|
||||
bool "Compress executable files with UPX"
|
||||
depends on !mips64
|
||||
default n
|
||||
endef
|
||||
|
||||
ifeq ($(CONFIG_HYSTERIA_COMPRESS_GOPROXY),y)
|
||||
export GO111MODULE=on
|
||||
export GOPROXY=https://goproxy.bj.bcebos.com
|
||||
endif
|
||||
|
||||
define Build/Compile
|
||||
$(call GoPackage/Build/Compile)
|
||||
ifeq ($(CONFIG_HYSTERIA_COMPRESS_UPX),y)
|
||||
$(STAGING_DIR_HOST)/bin/upx --lzma --best $(GO_PKG_BUILD_BIN_DIR)/cmd
|
||||
endif
|
||||
endef
|
||||
|
||||
define Package/hysteria/install
|
||||
$(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR))
|
||||
$(INSTALL_DIR) $(1)/usr/bin/
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/cmd $(1)/usr/bin/hysteria
|
||||
endef
|
||||
|
||||
$(eval $(call GoBinPackage,hysteria))
|
||||
$(eval $(call BuildPackage,hysteria))
|
43
ipt2socks/Makefile
Normal file
43
ipt2socks/Makefile
Normal file
@ -0,0 +1,43 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#
|
||||
# Copyright (C) 2021 ImmortalWrt.org
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ipt2socks
|
||||
PKG_VERSION:=1.1.3
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/zfl9/ipt2socks/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=73a2498dc95934c225d358707e7f7d060b5ce81aa45260ada09cbd15207d27d1
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_INSTALL:=1
|
||||
|
||||
PKG_LICENSE:=AGPL-3.0
|
||||
PKG_LICENSE_FILE:=LICENSE
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/ipt2socks
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
TITLE:=Convert iptables to socks5
|
||||
URL:=https://github.com/zfl9/ipt2socks
|
||||
DEPENDS:=+libpthread +libuv
|
||||
endef
|
||||
|
||||
define Package/ipt2socks/description
|
||||
Utility for converting iptables (redirect/tproxy) to socks5.
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += $(FPIC) -flto
|
||||
TARGET_LDFLAGS += -flto
|
||||
|
||||
define Package/ipt2socks/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/ipt2socks $(1)/usr/bin
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,ipt2socks))
|
43
luci-app-advanced/Makefile
Normal file
43
luci-app-advanced/Makefile
Normal file
@ -0,0 +1,43 @@
|
||||
# Copyright (C) 2019 sirpdboy <https://github.com/sirpdboy/luci-app-advanced/>
|
||||
#
|
||||
#
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
PKG_NAME:=luci-app-advanced
|
||||
PKG_VERSION:=1.20
|
||||
PKG_RELEASE:=20220218
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=luci
|
||||
CATEGORY:=LuCI
|
||||
SUBMENU:=3. Applications
|
||||
DEPENDS:=
|
||||
TITLE:=LuCI Support for advanced and filebrowser
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci
|
||||
$(CP) ./luasrc/* $(1)/usr/lib/lua/luci
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) ./root/etc/config/advanced $(1)/etc/config/
|
||||
|
||||
$(INSTALL_DIR) $(1)/www
|
||||
cp -pR ./htdocs/* $(1)/www/
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_BIN) ./root/etc/uci-defaults/* $(1)/etc/uci-defaults/
|
||||
|
||||
$(INSTALL_DIR) $(1)/bin
|
||||
$(INSTALL_BIN) ./root/bin/* $(1)/bin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
2
luci-app-advanced/README.md
Normal file
2
luci-app-advanced/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
# luci-app-advanced
|
||||
luci-app-advanced 高级设置,包括smartdns,openclash,防火墙,DHCP等。
|
@ -0,0 +1,68 @@
|
||||
.fb-container {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.fb-container .cbi-button {
|
||||
height: 2.6rem;
|
||||
}
|
||||
.fb-container .cbi-input-text {
|
||||
margin-bottom: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
.fb-container .panel-title {
|
||||
padding-bottom: 0;
|
||||
width: 50%;
|
||||
border-bottom: none;
|
||||
}
|
||||
.fb-container .panel-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid #aaa;
|
||||
}
|
||||
.fb-container .upload-container {
|
||||
display: none;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
.fb-container .upload-file {
|
||||
margin-right: 2rem;
|
||||
}
|
||||
.fb-container .cbi-value-field {
|
||||
text-align: left;
|
||||
}
|
||||
.fb-container .parent-icon strong {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
.fb-container td[class$="-icon"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
.fb-container .file-icon, .fb-container .folder-icon, .fb-container .link-icon {
|
||||
position: relative;
|
||||
}
|
||||
.fb-container .file-icon:before, .fb-container .folder-icon:before, .fb-container .link-icon:before {
|
||||
display: inline-block;
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
content: '';
|
||||
background-size: contain;
|
||||
margin: 0 0.5rem 0 1rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.fb-container .file-icon:before {
|
||||
background-image: url(file-icon.png);
|
||||
}
|
||||
.fb-container .folder-icon:before {
|
||||
background-image: url(folder-icon.png);
|
||||
}
|
||||
.fb-container .link-icon:before {
|
||||
background-image: url(link-icon.png);
|
||||
}
|
||||
@media screen and (max-width: 480px) {
|
||||
.fb-container .upload-file {
|
||||
width: 14.6rem;
|
||||
}
|
||||
.fb-container .cbi-value-owner,
|
||||
.fb-container .cbi-value-perm {
|
||||
display: none;
|
||||
}
|
||||
}
|
@ -0,0 +1,288 @@
|
||||
String.prototype.replaceAll = function(search, replacement) {
|
||||
var target = this;
|
||||
return target.replace(new RegExp(search, 'g'), replacement);
|
||||
};
|
||||
(function () {
|
||||
var iwxhr = new XHR();
|
||||
var listElem = document.getElementById("list-content");
|
||||
listElem.onclick = handleClick;
|
||||
var currentPath;
|
||||
var pathElem = document.getElementById("current-path");
|
||||
pathElem.onblur = function () {
|
||||
update_list(this.value.trim());
|
||||
};
|
||||
pathElem.onkeyup = function (evt) {
|
||||
if (evt.keyCode == 13) {
|
||||
this.blur();
|
||||
}
|
||||
};
|
||||
function removePath(filename, isdir) {
|
||||
var c = confirm('你确定要删除 ' + filename + ' 吗?');
|
||||
if (c) {
|
||||
iwxhr.get('/cgi-bin/luci/admin/system/fileassistant/delete',
|
||||
{
|
||||
path: concatPath(currentPath, filename),
|
||||
isdir: isdir
|
||||
},
|
||||
function (x, res) {
|
||||
if (res.ec === 0) {
|
||||
refresh_list(res.data, currentPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function installPath(filename, isdir) {
|
||||
if (isdir === "1") {
|
||||
alert('这是一个目录,请选择 ipk 文件进行安装!');
|
||||
return;
|
||||
}
|
||||
var isipk = isIPK(filename);
|
||||
if (isipk === 0) {
|
||||
alert('只允许安装 ipk 格式的文件!');
|
||||
return;
|
||||
}
|
||||
var c = confirm('你确定要安装 ' + filename + ' 吗?');
|
||||
if (c) {
|
||||
iwxhr.get('/cgi-bin/luci/admin/system/fileassistant/install',
|
||||
{
|
||||
filepath: concatPath(currentPath, filename),
|
||||
isdir: isdir
|
||||
},
|
||||
function (x, res) {
|
||||
if (res.ec === 0) {
|
||||
location.reload();
|
||||
alert('安装成功!');
|
||||
} else {
|
||||
alert('安装失败,请检查文件格式!');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function isIPK(filename) {
|
||||
var index= filename.lastIndexOf(".");
|
||||
var ext = filename.substr(index+1);
|
||||
if (ext === 'ipk') {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function renamePath(filename) {
|
||||
var newname = prompt('请输入新的文件名:', filename);
|
||||
if (newname) {
|
||||
newname = newname.trim();
|
||||
if (newname != filename) {
|
||||
var newpath = concatPath(currentPath, newname);
|
||||
iwxhr.get('/cgi-bin/luci/admin/system/fileassistant/rename',
|
||||
{
|
||||
filepath: concatPath(currentPath, filename),
|
||||
newpath: newpath
|
||||
},
|
||||
function (x, res) {
|
||||
if (res.ec === 0) {
|
||||
refresh_list(res.data, currentPath);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function openpath(filename, dirname) {
|
||||
dirname = dirname || currentPath;
|
||||
window.open('/cgi-bin/luci/admin/system/fileassistant/open?path='
|
||||
+ encodeURIComponent(dirname) + '&filename='
|
||||
+ encodeURIComponent(filename));
|
||||
}
|
||||
|
||||
function getFileElem(elem) {
|
||||
if (elem.className.indexOf('-icon') > -1) {
|
||||
return elem;
|
||||
}
|
||||
else if (elem.parentNode.className.indexOf('-icon') > -1) {
|
||||
return elem.parentNode;
|
||||
}
|
||||
}
|
||||
|
||||
function concatPath(path, filename) {
|
||||
if (path === '/') {
|
||||
return path + filename;
|
||||
}
|
||||
else {
|
||||
return path.replace(/\/$/, '') + '/' + filename;
|
||||
}
|
||||
}
|
||||
|
||||
function handleClick(evt) {
|
||||
var targetElem = evt.target;
|
||||
var infoElem;
|
||||
if (targetElem.className.indexOf('cbi-button-remove') > -1) {
|
||||
infoElem = targetElem.parentNode.parentNode;
|
||||
removePath(infoElem.dataset['filename'] , infoElem.dataset['isdir'])
|
||||
}
|
||||
else if (targetElem.className.indexOf('cbi-button-install') > -1) {
|
||||
infoElem = targetElem.parentNode.parentNode;
|
||||
installPath(infoElem.dataset['filename'] , infoElem.dataset['isdir'])
|
||||
}
|
||||
else if (targetElem.className.indexOf('cbi-button-edit') > -1) {
|
||||
renamePath(targetElem.parentNode.parentNode.dataset['filename']);
|
||||
}
|
||||
else if (targetElem = getFileElem(targetElem)) {
|
||||
if (targetElem.className.indexOf('parent-icon') > -1) {
|
||||
update_list(currentPath.replace(/\/[^/]+($|\/$)/, ''));
|
||||
}
|
||||
else if (targetElem.className.indexOf('file-icon') > -1) {
|
||||
openpath(targetElem.parentNode.dataset['filename']);
|
||||
}
|
||||
else if (targetElem.className.indexOf('link-icon') > -1) {
|
||||
infoElem = targetElem.parentNode;
|
||||
var filepath = infoElem.dataset['linktarget'];
|
||||
if (filepath) {
|
||||
if (infoElem.dataset['isdir'] === "1") {
|
||||
update_list(filepath);
|
||||
}
|
||||
else {
|
||||
var lastSlash = filepath.lastIndexOf('/');
|
||||
openpath(filepath.substring(lastSlash + 1), filepath.substring(0, lastSlash));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (targetElem.className.indexOf('folder-icon') > -1) {
|
||||
update_list(concatPath(currentPath, targetElem.parentNode.dataset['filename']))
|
||||
}
|
||||
}
|
||||
}
|
||||
function refresh_list(filenames, path) {
|
||||
var listHtml = '<table class="cbi-section-table"><tbody>';
|
||||
if (path !== '/') {
|
||||
listHtml += '<tr class="cbi-section-table-row cbi-rowstyle-2"><td class="parent-icon" colspan="6"><strong>..返回上级目录</strong></td></tr>';
|
||||
}
|
||||
if (filenames) {
|
||||
for (var i = 0; i < filenames.length; i++) {
|
||||
var line = filenames[i];
|
||||
if (line) {
|
||||
var f = line.match(/(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+([\S\s]+)/);
|
||||
var isLink = f[1][0] === 'z' || f[1][0] === 'l' || f[1][0] === 'x';
|
||||
var o = {
|
||||
displayname: f[9],
|
||||
filename: isLink ? f[9].split(' -> ')[0] : f[9],
|
||||
perms: f[1],
|
||||
date: f[7] + ' ' + f[6] + ' ' + f[8],
|
||||
size: f[5],
|
||||
owner: f[3],
|
||||
icon: (f[1][0] === 'd') ? "folder-icon" : (isLink ? "link-icon" : "file-icon")
|
||||
};
|
||||
|
||||
var install_btn = ' <button class="cbi-button cbi-button-install" style="visibility: hidden;">安装</button>';
|
||||
var index= o.filename.lastIndexOf(".");
|
||||
var ext = o.filename.substr(index+1);
|
||||
if (ext === 'ipk') {
|
||||
install_btn = ' <button class="cbi-button cbi-button-install">安装</button>';
|
||||
}
|
||||
|
||||
listHtml += '<tr class="cbi-section-table-row cbi-rowstyle-' + (1 + i%2)
|
||||
+ '" data-filename="' + o.filename + '" data-isdir="' + Number(f[1][0] === 'd' || f[1][0] === 'z') + '"'
|
||||
+ ((f[1][0] === 'z' || f[1][0] === 'l') ? (' data-linktarget="' + f[9].split(' -> ')[1]) : '')
|
||||
+ '">'
|
||||
+ '<td class="cbi-value-field ' + o.icon + '">'
|
||||
+ '<strong>' + o.displayname + '</strong>'
|
||||
+ '</td>'
|
||||
|
||||
+ '<td class="cbi-value-field cbi-value-date">'+o.date+'</td>'
|
||||
+ '<td class="cbi-value-field cbi-value-size">'+o.size+'</td>'
|
||||
+ '<td class="cbi-value-field cbi-value-perm">'+o.perms+'</td>'
|
||||
+ '<td class="cbi-section-table-cell">\
|
||||
<button class="cbi-button cbi-button-edit">重命名</button>\
|
||||
<button class="cbi-button cbi-button-remove">删除</button>'
|
||||
+ install_btn
|
||||
+ '</td>'
|
||||
+ '</tr>';
|
||||
}
|
||||
}
|
||||
}
|
||||
listHtml += "</table>";
|
||||
listElem.innerHTML = listHtml;
|
||||
}
|
||||
function update_list(path, opt) {
|
||||
opt = opt || {};
|
||||
path = concatPath(path, '');
|
||||
if (currentPath != path) {
|
||||
iwxhr.get('/cgi-bin/luci/admin/system/fileassistant/list',
|
||||
{path: path},
|
||||
function (x, res) {
|
||||
if (res.ec === 0) {
|
||||
refresh_list(res.data, path);
|
||||
}
|
||||
else {
|
||||
refresh_list([], path);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (!opt.popState) {
|
||||
history.pushState({path: path}, null, '?path=' + path);
|
||||
}
|
||||
currentPath = path;
|
||||
pathElem.value = currentPath;
|
||||
}
|
||||
};
|
||||
|
||||
var uploadToggle = document.getElementById('upload-toggle');
|
||||
var uploadContainer = document.getElementById('upload-container');
|
||||
var isUploadHide = true;
|
||||
uploadToggle.onclick = function() {
|
||||
if (isUploadHide) {
|
||||
uploadContainer.style.display = 'inline-flex';
|
||||
}
|
||||
else {
|
||||
uploadContainer.style.display = 'none';
|
||||
}
|
||||
isUploadHide = !isUploadHide;
|
||||
};
|
||||
var uploadBtn = uploadContainer.getElementsByClassName('cbi-input-apply')[0];
|
||||
uploadBtn.onclick = function (evt) {
|
||||
var uploadinput = document.getElementById('upload-file');
|
||||
var fullPath = uploadinput.value;
|
||||
if (!fullPath) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
else {
|
||||
var formData = new FormData();
|
||||
var startIndex = (fullPath.indexOf('\\') >= 0 ? fullPath.lastIndexOf('\\') : fullPath.lastIndexOf('/'));
|
||||
formData.append('upload-filename', fullPath.substring(startIndex + 1));
|
||||
formData.append('upload-dir', concatPath(currentPath, ''));
|
||||
formData.append('upload-file', uploadinput.files[0]);
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "/cgi-bin/luci/admin/system/fileassistant/upload", true);
|
||||
xhr.onload = function() {
|
||||
if (xhr.status == 200) {
|
||||
var res = JSON.parse(xhr.responseText);
|
||||
refresh_list(res.data, currentPath);
|
||||
uploadinput.value = '';
|
||||
}
|
||||
else {
|
||||
alert('上传失败,请稍后再试...');
|
||||
}
|
||||
};
|
||||
xhr.send(formData);
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function(evt) {
|
||||
var initPath = '/';
|
||||
if (/path=([/\w]+)/.test(location.search)) {
|
||||
initPath = RegExp.$1;
|
||||
}
|
||||
update_list(initPath, {popState: true});
|
||||
});
|
||||
window.addEventListener('popstate', function (evt) {
|
||||
var path = '/';
|
||||
if (evt.state && evt.state.path) {
|
||||
path = evt.state.path;
|
||||
}
|
||||
update_list(path, {popState: true});
|
||||
});
|
||||
|
||||
})();
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
9
luci-app-advanced/luasrc/controller/advanced.lua
Normal file
9
luci-app-advanced/luasrc/controller/advanced.lua
Normal file
@ -0,0 +1,9 @@
|
||||
module("luci.controller.advanced",package.seeall)
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/advanced")then
|
||||
return
|
||||
end
|
||||
local e
|
||||
e=entry({"admin","system","advanced"},cbi("advanced"),_("高级设置"),60)
|
||||
e.dependent=true
|
||||
end
|
228
luci-app-advanced/luasrc/controller/fileassistant.lua
Normal file
228
luci-app-advanced/luasrc/controller/fileassistant.lua
Normal file
@ -0,0 +1,228 @@
|
||||
module("luci.controller.fileassistant", package.seeall)
|
||||
|
||||
function index()
|
||||
|
||||
local page
|
||||
page = entry({"admin", "system", "fileassistant"}, template("fileassistant"), _("文件管理"), 84)
|
||||
page.i18n = "base"
|
||||
page.dependent = true
|
||||
|
||||
page = entry({"admin", "system", "fileassistant", "list"}, call("fileassistant_list"), nil)
|
||||
page.leaf = true
|
||||
|
||||
page = entry({"admin", "system", "fileassistant", "open"}, call("fileassistant_open"), nil)
|
||||
page.leaf = true
|
||||
|
||||
page = entry({"admin", "system", "fileassistant", "delete"}, call("fileassistant_delete"), nil)
|
||||
page.leaf = true
|
||||
|
||||
page = entry({"admin", "system", "fileassistant", "rename"}, call("fileassistant_rename"), nil)
|
||||
page.leaf = true
|
||||
|
||||
page = entry({"admin", "system", "fileassistant", "upload"}, call("fileassistant_upload"), nil)
|
||||
page.leaf = true
|
||||
|
||||
page = entry({"admin", "system", "fileassistant", "install"}, call("fileassistant_install"), nil)
|
||||
page.leaf = true
|
||||
|
||||
end
|
||||
|
||||
function list_response(path, success)
|
||||
luci.http.prepare_content("application/json")
|
||||
local result
|
||||
if success then
|
||||
local rv = scandir(path)
|
||||
result = {
|
||||
ec = 0,
|
||||
data = rv
|
||||
}
|
||||
else
|
||||
result = {
|
||||
ec = 1
|
||||
}
|
||||
end
|
||||
luci.http.write_json(result)
|
||||
end
|
||||
|
||||
function fileassistant_list()
|
||||
local path = luci.http.formvalue("path")
|
||||
list_response(path, true)
|
||||
end
|
||||
|
||||
function fileassistant_open()
|
||||
local path = luci.http.formvalue("path")
|
||||
local filename = luci.http.formvalue("filename")
|
||||
local io = require "io"
|
||||
local mime = to_mime(filename)
|
||||
|
||||
file = path..filename
|
||||
|
||||
local download_fpi = io.open(file, "r")
|
||||
luci.http.header('Content-Disposition', 'inline; filename="'..filename..'"' )
|
||||
luci.http.prepare_content(mime)
|
||||
luci.ltn12.pump.all(luci.ltn12.source.file(download_fpi), luci.http.write)
|
||||
end
|
||||
|
||||
function fileassistant_delete()
|
||||
local path = luci.http.formvalue("path")
|
||||
local isdir = luci.http.formvalue("isdir")
|
||||
path = path:gsub("<>", "/")
|
||||
path = path:gsub(" ", "\ ")
|
||||
local success
|
||||
if isdir then
|
||||
success = os.execute('rm -r "'..path..'"')
|
||||
else
|
||||
success = os.remove(path)
|
||||
end
|
||||
list_response(nixio.fs.dirname(path), success)
|
||||
end
|
||||
|
||||
function fileassistant_rename()
|
||||
local filepath = luci.http.formvalue("filepath")
|
||||
local newpath = luci.http.formvalue("newpath")
|
||||
local success = os.execute('mv "'..filepath..'" "'..newpath..'"')
|
||||
list_response(nixio.fs.dirname(filepath), success)
|
||||
end
|
||||
|
||||
function fileassistant_install()
|
||||
local filepath = luci.http.formvalue("filepath")
|
||||
local isdir = luci.http.formvalue("isdir")
|
||||
local ext = filepath:match(".+%.(%w+)$")
|
||||
filepath = filepath:gsub("<>", "/")
|
||||
filepath = filepath:gsub(" ", "\ ")
|
||||
local success
|
||||
if isdir == "1" then
|
||||
success = false
|
||||
elseif ext == "ipk" then
|
||||
success = installIPK(filepath)
|
||||
else
|
||||
success = false
|
||||
end
|
||||
list_response(nixio.fs.dirname(filepath), success)
|
||||
end
|
||||
|
||||
function installIPK(filepath)
|
||||
luci.sys.exec('opkg --force-depends install "'..filepath..'"')
|
||||
luci.sys.exec('rm -rf /tmp/luci-*')
|
||||
return true;
|
||||
end
|
||||
|
||||
function fileassistant_upload()
|
||||
local filecontent = luci.http.formvalue("upload-file")
|
||||
local filename = luci.http.formvalue("upload-filename")
|
||||
local uploaddir = luci.http.formvalue("upload-dir")
|
||||
local filepath = uploaddir..filename
|
||||
|
||||
local fp
|
||||
luci.http.setfilehandler(
|
||||
function(meta, chunk, eof)
|
||||
if not fp and meta and meta.name == "upload-file" then
|
||||
fp = io.open(filepath, "w")
|
||||
end
|
||||
if fp and chunk then
|
||||
fp:write(chunk)
|
||||
end
|
||||
if fp and eof then
|
||||
fp:close()
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
list_response(uploaddir, true)
|
||||
end
|
||||
|
||||
function scandir(directory)
|
||||
local i, t, popen = 0, {}, io.popen
|
||||
|
||||
local pfile = popen("ls -lh \""..directory.."\" | egrep '^d' ; ls -lh \""..directory.."\" | egrep -v '^d|^l'")
|
||||
for fileinfo in pfile:lines() do
|
||||
i = i + 1
|
||||
t[i] = fileinfo
|
||||
end
|
||||
pfile:close()
|
||||
pfile = popen("ls -lh \""..directory.."\" | egrep '^l' ;")
|
||||
for fileinfo in pfile:lines() do
|
||||
i = i + 1
|
||||
linkindex, _, linkpath = string.find(fileinfo, "->%s+(.+)$")
|
||||
local finalpath;
|
||||
if string.sub(linkpath, 1, 1) == "/" then
|
||||
finalpath = linkpath
|
||||
else
|
||||
finalpath = nixio.fs.realpath(directory..linkpath)
|
||||
end
|
||||
local linktype;
|
||||
if not finalpath then
|
||||
finalpath = linkpath;
|
||||
linktype = 'x'
|
||||
elseif nixio.fs.stat(finalpath, "type") == "dir" then
|
||||
linktype = 'z'
|
||||
else
|
||||
linktype = 'l'
|
||||
end
|
||||
fileinfo = string.sub(fileinfo, 2, linkindex - 1)
|
||||
fileinfo = linktype..fileinfo.."-> "..finalpath
|
||||
t[i] = fileinfo
|
||||
end
|
||||
pfile:close()
|
||||
return t
|
||||
end
|
||||
|
||||
MIME_TYPES = {
|
||||
["txt"] = "text/plain";
|
||||
["conf"] = "text/plain";
|
||||
["ovpn"] = "text/plain";
|
||||
["log"] = "text/plain";
|
||||
["js"] = "text/javascript";
|
||||
["json"] = "application/json";
|
||||
["css"] = "text/css";
|
||||
["htm"] = "text/html";
|
||||
["html"] = "text/html";
|
||||
["patch"] = "text/x-patch";
|
||||
["c"] = "text/x-csrc";
|
||||
["h"] = "text/x-chdr";
|
||||
["o"] = "text/x-object";
|
||||
["ko"] = "text/x-object";
|
||||
|
||||
["bmp"] = "image/bmp";
|
||||
["gif"] = "image/gif";
|
||||
["png"] = "image/png";
|
||||
["jpg"] = "image/jpeg";
|
||||
["jpeg"] = "image/jpeg";
|
||||
["svg"] = "image/svg+xml";
|
||||
|
||||
["zip"] = "application/zip";
|
||||
["pdf"] = "application/pdf";
|
||||
["xml"] = "application/xml";
|
||||
["xsl"] = "application/xml";
|
||||
["doc"] = "application/msword";
|
||||
["ppt"] = "application/vnd.ms-powerpoint";
|
||||
["xls"] = "application/vnd.ms-excel";
|
||||
["odt"] = "application/vnd.oasis.opendocument.text";
|
||||
["odp"] = "application/vnd.oasis.opendocument.presentation";
|
||||
["pl"] = "application/x-perl";
|
||||
["sh"] = "application/x-shellscript";
|
||||
["php"] = "application/x-php";
|
||||
["deb"] = "application/x-deb";
|
||||
["iso"] = "application/x-cd-image";
|
||||
["tgz"] = "application/x-compressed-tar";
|
||||
|
||||
["mp3"] = "audio/mpeg";
|
||||
["ogg"] = "audio/x-vorbis+ogg";
|
||||
["wav"] = "audio/x-wav";
|
||||
|
||||
["mpg"] = "video/mpeg";
|
||||
["mpeg"] = "video/mpeg";
|
||||
["avi"] = "video/x-msvideo";
|
||||
}
|
||||
|
||||
function to_mime(filename)
|
||||
if type(filename) == "string" then
|
||||
local ext = filename:match("[^%.]+$")
|
||||
|
||||
if ext and MIME_TYPES[ext:lower()] then
|
||||
return MIME_TYPES[ext:lower()]
|
||||
end
|
||||
end
|
||||
|
||||
return "application/octet-stream"
|
||||
end
|
344
luci-app-advanced/luasrc/model/cbi/advanced.lua
Normal file
344
luci-app-advanced/luasrc/model/cbi/advanced.lua
Normal file
@ -0,0 +1,344 @@
|
||||
local e=require"nixio.fs"
|
||||
local t=require"luci.sys"
|
||||
local t=luci.model.uci.cursor()
|
||||
m=Map("advanced",translate("高级进阶设置"),translate("<font color=\"Red\"><strong>配置文档是直接编辑的除非你知道自己在干什么,否则请不要轻易修改这些配置文档。配置不正确可能会导致不能开机等错误。</strong></font><br/>"))
|
||||
m.apply_on_parse=true
|
||||
s=m:section(TypedSection,"advanced")
|
||||
s.anonymous=true
|
||||
|
||||
if nixio.fs.access("/bin/nuc")then
|
||||
s:tab("mode",translate("模式设置"),translate("<br />可以在这里切换旁路由和正常模式,重置你的网络设置。<br /><font color=\"Red\"><strong>点击后会立即重启设备,没有确认过程,请谨慎操作!</strong></font><br/>"))
|
||||
o=s:taboption("mode",Button,"nucmode",translate("切换为旁路由模式"),translate("<font color=\"green\"><strong>本模式适合于单口和多网口主机,自动将网口全桥接好!<br />默认gateway是:192.168.1.1,ipaddr是192.168.1.2。用本机接口LAN接上级LAN当旁路由,主路由关闭DHCP服务。应用生效会重启软路由!</strong></font><br/>"))
|
||||
o.inputtitle = translate("Apply")
|
||||
o.inputstyle = "reset"
|
||||
o.write = function()
|
||||
luci.sys.exec("/bin/nuc &> /dev/null &")
|
||||
end
|
||||
o=s:taboption("mode",Button,"normalmode",translate("切换成路由模式"),translate("<font color=\"green\"><strong>本模式适合于有两个网口或以上的设备使用,如多网口软路由或者虚拟了两个以上网口的虚拟机使用!应用生效会重启软路由!。</strong></font><br/>"))
|
||||
o.inputtitle = translate("Apply")
|
||||
o.inputstyle = "reset"
|
||||
o.write = function()
|
||||
luci.sys.exec("/bin/normalmode &> /dev/null &")
|
||||
end
|
||||
|
||||
o=s:taboption("mode",Button,"ipmode6",translate("设置为IPV6网络"),translate("<font color=\"green\"><strong>点击应用切换到IPV6模式!保存应用后即刻有效!</strong></font><br/>"))
|
||||
|
||||
o.inputtitle = translate("Apply")
|
||||
o.inputstyle = "add"
|
||||
o.write = function(self, section)
|
||||
luci.sys.exec("ipmode6 &> /dev/null &")
|
||||
end
|
||||
|
||||
o=s:taboption("mode",Button,"ipmode4",translate("设置为IPV4网络"),translate("<font color=\"green\"><strong>点击应用切换到IPV4模式!保存应用后即刻有效!</strong></font><br/>"))
|
||||
|
||||
o.inputtitle = translate("Apply")
|
||||
o.inputstyle = "add"
|
||||
o.write = function(self, section)
|
||||
luci.sys.exec("ipmode4 &> /dev/null &")
|
||||
end
|
||||
|
||||
end
|
||||
if nixio.fs.access("/etc/dnsmasq.conf")then
|
||||
|
||||
s:tab("dnsmasqconf",translate("dnsmasq"),translate("本页是配置/etc/dnsmasq.conf的文档内容。应用保存后自动重启生效"))
|
||||
|
||||
conf=s:taboption("dnsmasqconf",Value,"dnsmasqconf",nil,translate("开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"))
|
||||
conf.template="cbi/tvalue"
|
||||
conf.rows=20
|
||||
conf.wrap="off"
|
||||
conf.cfgvalue=function(t,t)
|
||||
return e.readfile("/etc/dnsmasq.conf")or""
|
||||
end
|
||||
conf.write=function(a,a,t)
|
||||
if t then
|
||||
t=t:gsub("\r\n?","\n")
|
||||
e.writefile("/tmp/dnsmasq.conf",t)
|
||||
if(luci.sys.call("cmp -s /tmp/dnsmasq.conf /etc/dnsmasq.conf")==1)then
|
||||
e.writefile("/etc/dnsmasq.conf",t)
|
||||
luci.sys.call("/etc/init.d/dnsmasq restart >/dev/null")
|
||||
end
|
||||
e.remove("/tmp/dnsmasq.conf")
|
||||
end
|
||||
end
|
||||
end
|
||||
if nixio.fs.access("/etc/config/network")then
|
||||
s:tab("netwrokconf",translate("网络"),translate("本页是配置/etc/config/network包含网络配置文档内容。应用保存后自动重启生效"))
|
||||
conf=s:taboption("netwrokconf",Value,"netwrokconf",nil,translate("开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"))
|
||||
conf.template="cbi/tvalue"
|
||||
conf.rows=20
|
||||
conf.wrap="off"
|
||||
conf.cfgvalue=function(t,t)
|
||||
return e.readfile("/etc/config/network")or""
|
||||
end
|
||||
conf.write=function(a,a,t)
|
||||
if t then
|
||||
t=t:gsub("\r\n?","\n")
|
||||
e.writefile("/tmp/network",t)
|
||||
if(luci.sys.call("cmp -s /tmp/network /etc/config/network")==1)then
|
||||
e.writefile("/etc/config/network",t)
|
||||
luci.sys.call("/etc/init.d/network restart >/dev/null")
|
||||
end
|
||||
e.remove("/tmp/network")
|
||||
end
|
||||
end
|
||||
end
|
||||
if nixio.fs.access("/etc/config/wireless")then
|
||||
s:tab("wirelessconf",translate("无线"), translate("本页是/etc/config/wireless的配置文件内容,应用保存后自动重启生效."))
|
||||
|
||||
conf=s:taboption("wirelessconf",Value,"wirelessconf",nil,translate("开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"))
|
||||
conf.template="cbi/tvalue"
|
||||
conf.rows=20
|
||||
conf.wrap="off"
|
||||
conf.cfgvalue=function(t,t)
|
||||
return e.readfile("/etc/config/wireless")or""
|
||||
end
|
||||
conf.write=function(a,a,t)
|
||||
if t then
|
||||
t=t:gsub("\r\n?","\n")
|
||||
e.writefile("/etc/config/wireless.tmp",t)
|
||||
if(luci.sys.call("cmp -s /etc/config/wireless.tmp /etc/config/wireless")==1)then
|
||||
e.writefile("/etc/config/wireless",t)
|
||||
luci.sys.call("wifi reload >/dev/null &")
|
||||
end
|
||||
e.remove("/tmp//tmp/wireless.tmp")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/etc/hosts")then
|
||||
s:tab("hostsconf",translate("hosts"),translate("本页是配置/etc/hosts的文档内容。应用保存后自动重启生效"))
|
||||
|
||||
conf=s:taboption("hostsconf",Value,"hostsconf",nil,translate("开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"))
|
||||
conf.template="cbi/tvalue"
|
||||
conf.rows=20
|
||||
conf.wrap="off"
|
||||
conf.cfgvalue=function(t,t)
|
||||
return e.readfile("/etc/hosts")or""
|
||||
end
|
||||
conf.write=function(a,a,t)
|
||||
if t then
|
||||
t=t:gsub("\r\n?","\n")
|
||||
e.writefile("/tmp/hosts.tmp",t)
|
||||
if(luci.sys.call("cmp -s /tmp/hosts.tmp /etc/hosts")==1)then
|
||||
e.writefile("/etc/hosts",t)
|
||||
luci.sys.call("/etc/init.d/dnsmasq restart >/dev/null")
|
||||
end
|
||||
e.remove("/tmp/hosts.tmp")
|
||||
end
|
||||
end
|
||||
end
|
||||
if nixio.fs.access("/etc/config/arpbind")then
|
||||
s:tab("arpbindconf",translate("ARP绑定"),translate("本页是配置/etc/config/arpbind包含APR绑定MAC地址文档内容。应用保存后自动重启生效"))
|
||||
conf=s:taboption("arpbindconf",Value,"arpbindconf",nil,translate("开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"))
|
||||
conf.template="cbi/tvalue"
|
||||
conf.rows=20
|
||||
conf.wrap="off"
|
||||
conf.cfgvalue=function(t,t)
|
||||
return e.readfile("/etc/config/arpbind")or""
|
||||
end
|
||||
conf.write=function(a,a,t)
|
||||
if t then
|
||||
t=t:gsub("\r\n?","\n")
|
||||
e.writefile("/tmp/arpbind",t)
|
||||
if(luci.sys.call("cmp -s /tmp/arpbind /etc/config/arpbind")==1)then
|
||||
e.writefile("/etc/config/arpbind",t)
|
||||
luci.sys.call("/etc/init.d/arpbind restart >/dev/null")
|
||||
end
|
||||
e.remove("/tmp/arpbind")
|
||||
end
|
||||
end
|
||||
end
|
||||
if nixio.fs.access("/etc/config/firewall")then
|
||||
s:tab("firewallconf",translate("防火墙"),translate("本页是配置/etc/config/firewall包含防火墙协议设置文档内容。应用保存后自动重启生效"))
|
||||
conf=s:taboption("firewallconf",Value,"firewallconf",nil,translate("开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"))
|
||||
conf.template="cbi/tvalue"
|
||||
conf.rows=20
|
||||
conf.wrap="off"
|
||||
conf.cfgvalue=function(t,t)
|
||||
return e.readfile("/etc/config/firewall")or""
|
||||
end
|
||||
conf.write=function(a,a,t)
|
||||
if t then
|
||||
t=t:gsub("\r\n?","\n")
|
||||
e.writefile("/tmp/firewall",t)
|
||||
if(luci.sys.call("cmp -s /tmp/firewall /etc/config/firewall")==1)then
|
||||
e.writefile("/etc/config/firewall",t)
|
||||
luci.sys.call("/etc/init.d/firewall restart >/dev/null")
|
||||
end
|
||||
e.remove("/tmp/firewall")
|
||||
end
|
||||
end
|
||||
end
|
||||
if nixio.fs.access("/etc/config/mwan3")then
|
||||
s:tab("mwan3conf",translate("负载均衡"),translate("本页是配置/etc/config/mwan3包含负载均衡设置文档内容。应用保存后自动重启生效"))
|
||||
conf=s:taboption("mwan3conf",Value,"mwan3conf",nil,translate("开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"))
|
||||
conf.template="cbi/tvalue"
|
||||
conf.rows=20
|
||||
conf.wrap="off"
|
||||
conf.cfgvalue=function(t,t)
|
||||
return e.readfile("/etc/config/mwan3")or""
|
||||
end
|
||||
conf.write=function(a,a,t)
|
||||
if t then
|
||||
t=t:gsub("\r\n?","\n")
|
||||
e.writefile("/tmp/mwan3",t)
|
||||
if(luci.sys.call("cmp -s /tmp/mwan3 /etc/config/mwan3")==1)then
|
||||
e.writefile("/etc/config/mwan3",t)
|
||||
luci.sys.call("/etc/init.d/mwan3 restart >/dev/null")
|
||||
end
|
||||
e.remove("/tmp/mwan3")
|
||||
end
|
||||
end
|
||||
end
|
||||
if nixio.fs.access("/etc/config/dhcp")then
|
||||
s:tab("dhcpconf",translate("DHCP"),translate("本页是配置/etc/config/DHCP包含机器名等设置文档内容。应用保存后自动重启生效"))
|
||||
conf=s:taboption("dhcpconf",Value,"dhcpconf",nil,translate("开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"))
|
||||
conf.template="cbi/tvalue"
|
||||
conf.rows=20
|
||||
conf.wrap="off"
|
||||
conf.cfgvalue=function(t,t)
|
||||
return e.readfile("/etc/config/dhcp")or""
|
||||
end
|
||||
conf.write=function(a,a,t)
|
||||
if t then
|
||||
t=t:gsub("\r\n?","\n")
|
||||
e.writefile("/tmp/dhcp",t)
|
||||
if(luci.sys.call("cmp -s /tmp/dhcp /etc/config/dhcp")==1)then
|
||||
e.writefile("/etc/config/dhcp",t)
|
||||
luci.sys.call("/etc/init.d/network restart >/dev/null")
|
||||
end
|
||||
e.remove("/tmp/dhcp")
|
||||
end
|
||||
end
|
||||
end
|
||||
if nixio.fs.access("/etc/config/ddns")then
|
||||
s:tab("ddnsconf",translate("DDNS"),translate("本页是配置/etc/config/ddns包含动态域名设置文档内容。应用保存后自动重启生效"))
|
||||
conf=s:taboption("ddnsconf",Value,"ddnsconf",nil,translate("开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"))
|
||||
conf.template="cbi/tvalue"
|
||||
conf.rows=20
|
||||
conf.wrap="off"
|
||||
conf.cfgvalue=function(t,t)
|
||||
return e.readfile("/etc/config/ddns")or""
|
||||
end
|
||||
conf.write=function(a,a,t)
|
||||
if t then
|
||||
t=t:gsub("\r\n?","\n")
|
||||
e.writefile("/tmp/ddns",t)
|
||||
if(luci.sys.call("cmp -s /tmp/ddns /etc/config/ddns")==1)then
|
||||
e.writefile("/etc/config/ddns",t)
|
||||
luci.sys.call("/etc/init.d/ddns restart >/dev/null")
|
||||
end
|
||||
e.remove("/tmp/ddns")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/etc/config/timecontrol")then
|
||||
s:tab("timecontrolconf",translate("时间控制"),translate("本页是配置/etc/config/timecontrol包含上网时间控制配置文档内容。应用保存后自动重启生效"))
|
||||
conf=s:taboption("timecontrolconf",Value,"timecontrolconf",nil,translate("开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"))
|
||||
conf.template="cbi/tvalue"
|
||||
conf.rows=20
|
||||
conf.wrap="off"
|
||||
conf.cfgvalue=function(t,t)
|
||||
return e.readfile("/etc/config/timecontrol")or""
|
||||
end
|
||||
conf.write=function(a,a,t)
|
||||
if t then
|
||||
t=t:gsub("\r\n?","\n")
|
||||
e.writefile("/tmp/timecontrol",t)
|
||||
if(luci.sys.call("cmp -s /tmp/timecontrol /etc/config/timecontrol")==1)then
|
||||
e.writefile("/etc/config/timecontrol",t)
|
||||
luci.sys.call("/etc/init.d/timecontrol restart >/dev/null")
|
||||
end
|
||||
e.remove("/tmp/timecontrol")
|
||||
end
|
||||
end
|
||||
end
|
||||
if nixio.fs.access("/etc/config/rebootschedule")then
|
||||
s:tab("rebootscheduleconf",translate("定时设置"),translate("本页是配置/etc/config/rebootschedule包含定时设置任务配置文档内容。应用保存后自动重启生效"))
|
||||
conf=s:taboption("rebootscheduleconf",Value,"rebootscheduleconf",nil,translate("开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"))
|
||||
conf.template="cbi/tvalue"
|
||||
conf.rows=20
|
||||
conf.wrap="off"
|
||||
conf.cfgvalue=function(t,t)
|
||||
return e.readfile("/etc/config/rebootschedule")or""
|
||||
end
|
||||
conf.write=function(a,a,t)
|
||||
if t then
|
||||
t=t:gsub("\r\n?","\n")
|
||||
e.writefile("/tmp/rebootschedule",t)
|
||||
if(luci.sys.call("cmp -s /tmp/rebootschedule /etc/config/rebootschedule")==1)then
|
||||
e.writefile("/etc/config/rebootschedule",t)
|
||||
luci.sys.call("/etc/init.d/rebootschedule restart >/dev/null")
|
||||
end
|
||||
e.remove("/tmp/rebootschedule")
|
||||
end
|
||||
end
|
||||
end
|
||||
if nixio.fs.access("/etc/config/wolplus")then
|
||||
s:tab("wolplusconf",translate("网络唤醒"),translate("本页是配置/etc/config/wolplus包含网络唤醒配置文档内容。应用保存后自动重启生效"))
|
||||
conf=s:taboption("wolplusconf",Value,"wolplusconf",nil,translate("开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"))
|
||||
conf.template="cbi/tvalue"
|
||||
conf.rows=20
|
||||
conf.wrap="off"
|
||||
conf.cfgvalue=function(t,t)
|
||||
return e.readfile("/etc/config/wolplus")or""
|
||||
end
|
||||
conf.write=function(a,a,t)
|
||||
if t then
|
||||
t=t:gsub("\r\n?","\n")
|
||||
e.writefile("/tmp/wolplus",t)
|
||||
if(luci.sys.call("cmp -s /tmp/wolplus /etc/config/wolplus")==1)then
|
||||
e.writefile("/etc/config/wolplus",t)
|
||||
luci.sys.call("/etc/init.d/wolplus restart >/dev/null")
|
||||
end
|
||||
e.remove("/tmp/wolplus")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if nixio.fs.access("/etc/config/smartdns")then
|
||||
s:tab("smartdnsconf",translate("SMARTDNS"),translate("本页是配置/etc/config/smartdns包含smartdns配置文档内容。应用保存后自动重启生效"))
|
||||
conf=s:taboption("smartdnsconf",Value,"smartdnsconf",nil,translate("开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"))
|
||||
conf.template="cbi/tvalue"
|
||||
conf.rows=20
|
||||
conf.wrap="off"
|
||||
conf.cfgvalue=function(t,t)
|
||||
return e.readfile("/etc/config/smartdns")or""
|
||||
end
|
||||
conf.write=function(a,a,t)
|
||||
if t then
|
||||
t=t:gsub("\r\n?","\n")
|
||||
e.writefile("/tmp/smartdns",t)
|
||||
if(luci.sys.call("cmp -s /tmp/smartdns /etc/config/smartdns")==1)then
|
||||
e.writefile("/etc/config/smartdns",t)
|
||||
luci.sys.call("/etc/init.d/smartdns restart >/dev/null")
|
||||
end
|
||||
e.remove("/tmp/smartdns")
|
||||
end
|
||||
end
|
||||
end
|
||||
if nixio.fs.access("/etc/config/openclash")then
|
||||
s:tab("openclashconf",translate("openclash"),translate("本页是配置/etc/config/openclash的文档内容。应用保存后自动重启生效"))
|
||||
conf=s:taboption("openclashconf",Value,"openclashconf",nil,translate("开头的数字符号(#)或分号的每一行(;)被视为注释;删除(;)启用指定选项。"))
|
||||
conf.template="cbi/tvalue"
|
||||
conf.rows=20
|
||||
conf.wrap="off"
|
||||
conf.cfgvalue=function(t,t)
|
||||
return e.readfile("/etc/config/openclash")or""
|
||||
end
|
||||
conf.write=function(a,a,t)
|
||||
if t then
|
||||
t=t:gsub("\r\n?","\n")
|
||||
e.writefile("/tmp/openclash",t)
|
||||
if(luci.sys.call("cmp -s /tmp/openclash /etc/config/openclash")==1)then
|
||||
e.writefile("/etc/config/openclash",t)
|
||||
luci.sys.call("/etc/init.d/openclash restart >/dev/null")
|
||||
end
|
||||
e.remove("/tmp/openclash")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return m
|
20
luci-app-advanced/luasrc/view/fileassistant.htm
Normal file
20
luci-app-advanced/luasrc/view/fileassistant.htm
Normal file
@ -0,0 +1,20 @@
|
||||
<%+header%>
|
||||
|
||||
<link rel="stylesheet" href="/luci-static/resources/fileassistant/fb.css?v=@ver">
|
||||
<h2 name="content">文件管理【集成上传删除及安装,非专业人员请谨慎操作】</h2>
|
||||
<fieldset class="cbi-section fb-container">
|
||||
<input id="current-path" type="text" class="current-path cbi-input-text" value="/"/>
|
||||
<div class="panel-container">
|
||||
<div class="panel-title">文件列表</div>
|
||||
<button id="upload-toggle" class="upload-toggle cbi-button cbi-button-edit">上传文件</button>
|
||||
</div>
|
||||
<div class="upload-container" id="upload-container">
|
||||
<input id="upload-file" name="upload-file" class="upload-file" type="file">
|
||||
<button type="button" class="cbi-button cbi-input-apply">执行上传</button>
|
||||
</div>
|
||||
<div id="list-content"></div>
|
||||
</fieldset>
|
||||
|
||||
<script src="/luci-static/resources/fileassistant/fb.js?v=@ver"></script>
|
||||
|
||||
<%+footer%>
|
20
luci-app-advanced/luasrc/view/filebrowser.htm
Normal file
20
luci-app-advanced/luasrc/view/filebrowser.htm
Normal file
@ -0,0 +1,20 @@
|
||||
<%+header%>
|
||||
|
||||
<link rel="stylesheet" href="/luci-static/resources/fb/fb.css?v=@ver">
|
||||
<h2 name="content">文件管理</h2>
|
||||
<fieldset class="cbi-section fb-container">
|
||||
<input id="current-path" type="text" class="current-path cbi-input-text" value="/"/>
|
||||
<div class="panel-container">
|
||||
<div class="panel-title">文件列表:</div>
|
||||
<button id="upload-toggle" class="upload-toggle cbi-button cbi-button-edit">上传</button>
|
||||
</div>
|
||||
<div class="upload-container" id="upload-container">
|
||||
<input id="upload-file" name="upload-file" class="upload-file" type="file">
|
||||
<button type="button" class="cbi-button cbi-input-apply">点我上传</button>
|
||||
</div>
|
||||
<div id="list-content"></div>
|
||||
</fieldset>
|
||||
|
||||
<script src="/luci-static/resources/fb/fb.js?v=@ver"></script>
|
||||
|
||||
<%+footer%>
|
26
luci-app-advanced/root/bin/ipmode4
Normal file
26
luci-app-advanced/root/bin/ipmode4
Normal file
@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
uci set network.@globals[0].ula_prefix=''
|
||||
uci set network.lan.delegate='0'
|
||||
uci set network.wan.mtu=1460
|
||||
uci set network.wan.metric='41'
|
||||
uci set network.wan.delegate='0'
|
||||
uci set network.wan.ipv6='0'
|
||||
uci commit network
|
||||
uci set dhcp.@dnsmasq[0].cachesize='15000'
|
||||
uci set dhcp.@dnsmasq[0].min_ttl='3600'
|
||||
uci set dhcp.@dnsmasq[0].filter_aaaa='1'
|
||||
uci set dhcp.@dnsmasq[0].localservice='0'
|
||||
uci set dhcp.@dnsmasq[0].nonwildcard='0'
|
||||
uci set dhcp.@dnsmasq[0].rebind_protection='0'
|
||||
uci set dhcp.@dnsmasq[0].noresolv='0'
|
||||
uci set dhcp.lan.ra=''
|
||||
uci set dhcp.lan.ndp=''
|
||||
uci set dhcp.lan.dhcpv6=''
|
||||
uci set dhcp.lan.ignore='0'
|
||||
uci set dhcp.lan.ra_management='1'
|
||||
uci set dhcp.lan.ra_default='1'
|
||||
uci set dhcp.lan.force='1'
|
||||
uci commit dhcp
|
||||
sed -i "/list server/d" /etc/config/dhcp
|
||||
/etc/init.d/network restart
|
||||
/etc/init.d/dnsmasq restart
|
27
luci-app-advanced/root/bin/ipmode6
Normal file
27
luci-app-advanced/root/bin/ipmode6
Normal file
@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci set dhcp.@dnsmasq[0].cachesize='15000'
|
||||
uci set dhcp.@dnsmasq[0].min_ttl='3600'
|
||||
uci set dhcp.@dnsmasq[0].filter_aaaa='0'
|
||||
uci set dhcp.@dnsmasq[0].localservice='0'
|
||||
uci set dhcp.@dnsmasq[0].nonwildcard='0'
|
||||
uci set dhcp.@dnsmasq[0].rebind_protection='0'
|
||||
uci set dhcp.@dnsmasq[0].noresolv='1'
|
||||
uci set dhcp.lan.ra='server'
|
||||
uci set dhcp.lan.ndp=''
|
||||
uci set dhcp.lan.dhcpv6=''
|
||||
uci set dhcp.lan.ignore='0'
|
||||
uci set dhcp.lan.ra_management='1'
|
||||
uci set dhcp.lan.ra_default='1'
|
||||
uci set dhcp.lan.force='1'
|
||||
uci commit dhcp
|
||||
uci set network.@globals[0].ula_prefix=''
|
||||
uci set network.lan.delegate='0'
|
||||
uci set network.wan.mtu=1460
|
||||
uci set network.wan.metric='41'
|
||||
uci set network.wan.delegate='0'
|
||||
uci set network.wan.ipv6='auto'
|
||||
uci commit network
|
||||
sed -i "/list server/d" /etc/config/dhcp
|
||||
/etc/init.d/network restart
|
||||
/etc/init.d/dnsmasq restart
|
30
luci-app-advanced/root/bin/normalmode
Normal file
30
luci-app-advanced/root/bin/normalmode
Normal file
@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci set system.@system[0].hostname="Openwrt"
|
||||
uci commit
|
||||
|
||||
cat > /etc/config/network <<EOF
|
||||
config interface 'loopback'
|
||||
option ifname 'lo'
|
||||
option proto 'static'
|
||||
option ipaddr '127.0.0.1'
|
||||
option netmask '255.0.0.0'
|
||||
|
||||
config interface 'lan'
|
||||
option type 'bridge'
|
||||
option proto 'static'
|
||||
option ipaddr '192.168.1.1'
|
||||
option netmask '255.255.255.0'
|
||||
option ifname 'eth0 eth2 eth3'
|
||||
|
||||
config interface 'wan'
|
||||
option ifname 'eth1'
|
||||
option proto 'dhcp'
|
||||
option hostname 'Openwrt'
|
||||
EOF
|
||||
|
||||
sed -i '/REDIRECT --to-ports 53/d' /etc/firewall.user
|
||||
sed -i '/MASQUERADE/d' /etc/firewall.user
|
||||
echo "iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 53" >> /etc/firewall.user
|
||||
echo "iptables -t nat -A PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 53" >> /etc/firewall.user
|
||||
reboot
|
80
luci-app-advanced/root/bin/nuc
Normal file
80
luci-app-advanced/root/bin/nuc
Normal file
@ -0,0 +1,80 @@
|
||||
#!/bin/sh
|
||||
ip=/usr/sbin/ip
|
||||
vconfig=/sbin/vconfig
|
||||
ifconfig=/sbin/ifconfig
|
||||
|
||||
uci set system.@system[0].hostname="Openwrt"
|
||||
uci commit
|
||||
cat > /etc/config/network <<EOF
|
||||
config interface 'loopback'
|
||||
option ifname 'lo'
|
||||
option proto 'static'
|
||||
option ipaddr '127.0.0.1'
|
||||
option netmask '255.0.0.0'
|
||||
|
||||
config interface 'lan'
|
||||
option type 'bridge'
|
||||
option ifname 'eth0 eth1 eth2 eth3 eth4 eth5 eth0.12 eth0.13 eth0.14 eth0.15 eth0.16 eth0.17 eth0.18'
|
||||
option proto 'static'
|
||||
option ipaddr '192.168.1.2'
|
||||
option netmask '255.255.255.0'
|
||||
option gateway '192.168.1.1'
|
||||
option dns '223.5.5.5'
|
||||
|
||||
config interface 'wan'
|
||||
option ifname 'eth0.11'
|
||||
option proto 'dhcp'
|
||||
option hostname 'Openwrt'
|
||||
EOF
|
||||
|
||||
#for eth1
|
||||
$ip link add link eth0 eth0.11 type vlan proto 802.1ad id 11
|
||||
$ifconfig eth0.11 hw ether 58:b0:35:86:cf:11
|
||||
$vconfig set_flag eth0.11 1 1
|
||||
$ifconfig eth0.11 up
|
||||
|
||||
#for eth2
|
||||
$ip link add link eth0 eth0.12 type vlan proto 802.1ad id 12
|
||||
$ifconfig eth0.12 hw ether 58:b0:35:86:cf:12
|
||||
$vconfig set_flag eth0.12 1 2
|
||||
$ifconfig eth0.12 up
|
||||
|
||||
#for eth3
|
||||
$ip link add link eth0 eth0.13 type vlan proto 802.1ad id 13
|
||||
$ifconfig eth0.13 hw ether 58:b0:35:86:cf:13
|
||||
$vconfig set_flag eth0.13 1 3
|
||||
$ifconfig eth0.13 up
|
||||
|
||||
#for eth4
|
||||
$ip link add link eth0 eth0.14 type vlan proto 802.1ad id 14
|
||||
$ifconfig eth0.14 hw ether 58:b0:35:86:cf:14
|
||||
$vconfig set_flag eth0.14 1 3
|
||||
$ifconfig eth0.14 up
|
||||
|
||||
#for eth5
|
||||
$ip link add link eth0 eth0.15 type vlan proto 802.1ad id 15
|
||||
$ifconfig eth0.15 hw ether 58:b0:35:86:cf:15
|
||||
$vconfig set_flag eth0.15 1 3
|
||||
$ifconfig eth0.15 up
|
||||
|
||||
#for eth6
|
||||
$ip link add link eth0 eth0.16 type vlan proto 802.1ad id 16
|
||||
$ifconfig eth0.16 hw ether 58:b0:35:86:cf:16
|
||||
$vconfig set_flag eth0.16 1 3
|
||||
$ifconfig eth0.16 up
|
||||
|
||||
#for eth7
|
||||
$ip link add link eth0 eth0.17 type vlan proto 802.1ad id 17
|
||||
$ifconfig eth0.17 hw ether 58:b0:35:86:cf:17
|
||||
$vconfig set_flag eth0.17 1 3
|
||||
$ifconfig eth0.17 up
|
||||
|
||||
#for eth8
|
||||
$ip link add link eth0 eth0.18 type vlan proto 802.1ad id 18
|
||||
$ifconfig eth0.18 hw ether 58:b0:35:86:cf:18
|
||||
$vconfig set_flag eth0.18 1 3
|
||||
$ifconfig eth0.18 up
|
||||
|
||||
sed -i '/MASQUERADE/d' /etc/firewall.user
|
||||
echo "iptables -t nat -I POSTROUTING -j MASQUERADE" >> /etc/firewall.user
|
||||
reboot
|
2
luci-app-advanced/root/etc/config/advanced
Normal file
2
luci-app-advanced/root/etc/config/advanced
Normal file
@ -0,0 +1,2 @@
|
||||
config advanced
|
||||
option enabled '1'
|
7
luci-app-advanced/root/etc/uci-defaults/40_luci-fb
Normal file
7
luci-app-advanced/root/etc/uci-defaults/40_luci-fb
Normal file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
ver=$(date +%s)
|
||||
sed -i "s/@ver/$ver/g" /usr/lib/lua/luci/view/filebrowser.htm
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-advanced": {
|
||||
"description": "Grant UCI access for luci-app-advanced",
|
||||
"read": {
|
||||
"uci": [ "advanced" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "advanced" ]
|
||||
}
|
||||
}
|
||||
}
|
17
luci-app-aliyundrive-fuse/Makefile
Normal file
17
luci-app-aliyundrive-fuse/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-aliyundrive-fuse
|
||||
PKG_VERSION:=0.1.8
|
||||
PKG_RELEASE:=1
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE)
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_MAINTAINER:=messense <messense@icloud.com>
|
||||
|
||||
LUCI_TITLE:=LuCI Support for aliyundrive-fuse
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+aliyundrive-fuse +lua +libuci-lua
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
@ -0,0 +1,35 @@
|
||||
module("luci.controller.aliyundrive-fuse", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/aliyundrive-fuse") then
|
||||
return
|
||||
end
|
||||
entry({"admin", "services", "aliyundrive-fuse"}, alias("admin", "services", "aliyundrive-fuse", "client"),_("AliyunDrive FUSE"), 10).dependent = true -- 首页
|
||||
entry({"admin", "services", "aliyundrive-fuse", "client"}, cbi("aliyundrive-fuse/client"),_("Settings"), 10).leaf = true -- 客户端配置
|
||||
entry({"admin", "services", "aliyundrive-fuse", "log"}, form("aliyundrive-fuse/log"),_("Log"), 30).leaf = true -- 日志页面
|
||||
|
||||
entry({"admin", "services", "aliyundrive-fuse", "status"}, call("action_status")).leaf = true
|
||||
entry({"admin", "services", "aliyundrive-fuse", "logtail"}, call("action_logtail")).leaf = true
|
||||
end
|
||||
|
||||
function action_status()
|
||||
local e = {}
|
||||
e.running = luci.sys.call("pidof aliyundrive-fuse >/dev/null") == 0
|
||||
e.application = luci.sys.exec("aliyundrive-fuse --version")
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function action_logtail()
|
||||
local fs = require "nixio.fs"
|
||||
local log_path = "/var/log/aliyundrive-fuse.log"
|
||||
local e = {}
|
||||
e.running = luci.sys.call("pidof aliyundrive-fuse >/dev/null") == 0
|
||||
if fs.access(log_path) then
|
||||
e.log = luci.sys.exec("tail -n 100 %s | sed 's/\\x1b\\[[0-9;]*m//g'" % log_path)
|
||||
else
|
||||
e.log = ""
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
@ -0,0 +1,32 @@
|
||||
local uci = luci.model.uci.cursor()
|
||||
local m, e
|
||||
|
||||
m = Map("aliyundrive-fuse")
|
||||
m.title = translate("AliyunDrive FUSE")
|
||||
m.description = translate("<a href=\"https://github.com/messense/aliyundrive-fuse\" target=\"_blank\">Project GitHub URL</a>")
|
||||
|
||||
m:section(SimpleSection).template = "aliyundrive-fuse/aliyundrive-fuse_status"
|
||||
|
||||
e = m:section(TypedSection, "default")
|
||||
e.anonymous = true
|
||||
|
||||
enable = e:option(Flag, "enable", translate("Enable"))
|
||||
enable.rmempty = false
|
||||
|
||||
refresh_token = e:option(Value, "refresh_token", translate("Refresh Token"))
|
||||
refresh_token.description = translate("<a href=\"https://github.com/messense/aliyundrive-webdav#%E8%8E%B7%E5%8F%96-refresh_token\" target=\"_blank\">How to get refresh token</a>")
|
||||
|
||||
mount_point = e:option(Value, "mount_point", translate("Mount Point"))
|
||||
mount_point.default = "/mnt/aliyundrive"
|
||||
|
||||
read_buffer_size = e:option(Value, "read_buffer_size", translate("Read Buffer Size"))
|
||||
read_buffer_size.default = "10485760"
|
||||
read_buffer_size.datatype = "uinteger"
|
||||
|
||||
domain_id = e:option(Value, "domain_id", translate("Domain ID"))
|
||||
domain_id.description = translate("Input domain_id option will use <a href=\"https://www.aliyun.com/product/storage/pds\" target=\"_blank\">Aliyun PDS</a> instead of <a href=\"https://www.aliyundrive.com\" target=\"_blank\">AliyunDrive</a>")
|
||||
|
||||
debug = e:option(Flag, "debug", translate("Debug Mode"))
|
||||
debug.rmempty = false
|
||||
|
||||
return m
|
@ -0,0 +1,9 @@
|
||||
log = SimpleForm("logview")
|
||||
log.submit = false
|
||||
log.reset = false
|
||||
|
||||
t = log:field(DummyValue, '', '')
|
||||
t.rawhtml = true
|
||||
t.template = 'aliyundrive-fuse/aliyundrive-fuse_log'
|
||||
|
||||
return log
|
@ -0,0 +1,15 @@
|
||||
<%+cbi/valueheader%>
|
||||
<textarea id="logview" class="cbi-input-textarea" style="width: 100%" rows="30" readonly="readonly"></textarea>
|
||||
|
||||
<script type="text/javascript">
|
||||
const LOG_URL = '<%=luci.dispatcher.build_url("admin", "services", "aliyundrive-fuse", "logtail")%>';
|
||||
XHR.poll(1, LOG_URL, null, (x, d) => {
|
||||
let logview = document.getElementById("logview");
|
||||
if (!d.running) {
|
||||
XHR.halt();
|
||||
}
|
||||
logview.value = d.log;
|
||||
logview.scrollTop = logview.scrollHeight;
|
||||
});
|
||||
</script>
|
||||
<%+cbi/valuefooter%>
|
@ -0,0 +1,21 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[aliyundrive-fuse]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('aliyundrive-fuse_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
tb.innerHTML = '<em><b style=color:green>' + data.application + '<%:RUNNING%></b></em>';
|
||||
} else {
|
||||
tb.innerHTML = '<em><b style=color:red>' + data.application + '<%:NOT RUNNING%></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="aliyundrive-fuse_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
50
luci-app-aliyundrive-fuse/po/zh-cn/aliyundrive-fuse.po
Normal file
50
luci-app-aliyundrive-fuse/po/zh-cn/aliyundrive-fuse.po
Normal file
@ -0,0 +1,50 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
||||
msgid "AliyunDrive"
|
||||
msgstr "阿里云盘"
|
||||
|
||||
msgid "AliyunDrive FUSE"
|
||||
msgstr "阿里云盘 FUSE"
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Refresh Token"
|
||||
msgstr "Refresh Token"
|
||||
|
||||
msgid "Mount Point"
|
||||
msgstr "挂载点"
|
||||
|
||||
msgid "Read Buffer Size"
|
||||
msgstr "下载缓冲大小(bytes)"
|
||||
|
||||
msgid "Collecting data..."
|
||||
msgstr "获取数据中..."
|
||||
|
||||
msgid "RUNNING"
|
||||
msgstr "运行中"
|
||||
|
||||
msgid "NOT RUNNING"
|
||||
msgstr "未运行"
|
||||
|
||||
msgid "Settings"
|
||||
msgstr "设置"
|
||||
|
||||
msgid "Log"
|
||||
msgstr "日志"
|
||||
|
||||
msgid "Debug Mode"
|
||||
msgstr "调试模式"
|
||||
|
||||
msgid "<a href=\"https://github.com/messense/aliyundrive-fuse\" target=\"_blank\">Project GitHub URL</a>"
|
||||
msgstr "<a href=\"https://github.com/messense/aliyundrive-fuse\" target=\"_blank\">GitHub 项目地址</a>"
|
||||
|
||||
msgid "<a href=\"https://github.com/messense/aliyundrive-webdav#%E8%8E%B7%E5%8F%96-refresh_token\" target=\"_blank\">How to get refresh token</a>"
|
||||
msgstr "<a href=\"https://github.com/messense/aliyundrive-webdav#%E8%8E%B7%E5%8F%96-refresh_token\" target=\"_blank\">查看获取 refresh token 的方法</a>"
|
||||
|
||||
msgid "Domain ID"
|
||||
msgstr "阿里云相册与云盘服务 domainId"
|
||||
|
||||
msgid "Input domain_id option will use <a href=\"https://www.aliyun.com/product/storage/pds\" target=\"_blank\">Aliyun PDS</a> instead of <a href=\"https://www.aliyundrive.com\" target=\"_blank\">AliyunDrive</a>"
|
||||
msgstr "填写此选项将使用<a href=\"https://www.aliyun.com/product/storage/pds\" target=\"_blank\">阿里云相册与网盘服务</a>而不是<a href=\"https://www.aliyundrive.com\" target=\"_blank\">阿里云盘</a>"
|
1
luci-app-aliyundrive-fuse/po/zh_Hans
Symbolic link
1
luci-app-aliyundrive-fuse/po/zh_Hans
Symbolic link
@ -0,0 +1 @@
|
||||
zh-cn
|
11
luci-app-aliyundrive-fuse/root/etc/uci-defaults/luci-aliyundrive-fuse
Executable file
11
luci-app-aliyundrive-fuse/root/etc/uci-defaults/luci-aliyundrive-fuse
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@aliyundrive-fuse[-1]
|
||||
add ucitrack aliyundrive-fuse
|
||||
set ucitrack.@aliyundrive-fuse[-1].init=aliyundrive-fuse
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
17
luci-app-aliyundrive-webdav/Makefile
Normal file
17
luci-app-aliyundrive-webdav/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-aliyundrive-webdav
|
||||
PKG_VERSION:=1.2.6
|
||||
PKG_RELEASE:=1
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE)
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_MAINTAINER:=messense <messense@icloud.com>
|
||||
|
||||
LUCI_TITLE:=LuCI Support for aliyundrive-webdav
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+aliyundrive-webdav
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
@ -0,0 +1,40 @@
|
||||
module("luci.controller.aliyundrive-webdav", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/aliyundrive-webdav") then
|
||||
return
|
||||
end
|
||||
|
||||
local page
|
||||
page = entry({"admin", "services", "aliyundrive-webdav"}, alias("admin", "services", "aliyundrive-webdav", "client"), _("AliyunDrive WebDAV"), 10) -- 首页
|
||||
page.dependent = true
|
||||
page.acl_depends = { "luci-app-aliyundrive-webdav" }
|
||||
|
||||
entry({"admin", "services", "aliyundrive-webdav", "client"}, cbi("aliyundrive-webdav/client"), _("Settings"), 10).leaf = true -- 客户端配置
|
||||
entry({"admin", "services", "aliyundrive-webdav", "log"}, form("aliyundrive-webdav/log"), _("Log"), 30).leaf = true -- 日志页面
|
||||
|
||||
entry({"admin", "services", "aliyundrive-webdav", "status"}, call("action_status")).leaf = true -- 运行状态
|
||||
entry({"admin", "services", "aliyundrive-webdav", "logtail"}, call("action_logtail")).leaf = true -- 日志采集
|
||||
end
|
||||
|
||||
function action_status()
|
||||
local e = {}
|
||||
e.running = luci.sys.call("pidof aliyundrive-webdav >/dev/null") == 0
|
||||
e.application = luci.sys.exec("aliyundrive-webdav --version")
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function action_logtail()
|
||||
local fs = require "nixio.fs"
|
||||
local log_path = "/var/log/aliyundrive-webdav.log"
|
||||
local e = {}
|
||||
e.running = luci.sys.call("pidof aliyundrive-webdav >/dev/null") == 0
|
||||
if fs.access(log_path) then
|
||||
e.log = luci.sys.exec("tail -n 100 %s | sed 's/\\x1b\\[[0-9;]*m//g'" % log_path)
|
||||
else
|
||||
e.log = ""
|
||||
end
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
@ -0,0 +1,60 @@
|
||||
m = Map("aliyundrive-webdav")
|
||||
m.title = translate("AliyunDrive WebDAV")
|
||||
m.description = translate("<a href=\"https://github.com/messense/aliyundrive-webdav\" target=\"_blank\">Project GitHub URL</a>")
|
||||
|
||||
m:section(SimpleSection).template = "aliyundrive-webdav/aliyundrive-webdav_status"
|
||||
|
||||
e = m:section(TypedSection, "server")
|
||||
e.anonymous = true
|
||||
|
||||
enable = e:option(Flag, "enable", translate("Enable"))
|
||||
enable.rmempty = false
|
||||
|
||||
refresh_token = e:option(Value, "refresh_token", translate("Refresh Token"))
|
||||
refresh_token.description = translate("<a href=\"https://github.com/messense/aliyundrive-webdav#%E8%8E%B7%E5%8F%96-refresh_token\" target=\"_blank\">How to get refresh token</a>")
|
||||
|
||||
root = e:option(Value, "root", translate("Root Directory"))
|
||||
root.description = translate("Restrict access to a folder of aliyundrive, defaults to / which means no restrictions")
|
||||
root.default = "/"
|
||||
|
||||
host = e:option(Value, "host", translate("Host"))
|
||||
host.default = "0.0.0.0"
|
||||
host.datatype = "ipaddr"
|
||||
|
||||
port = e:option(Value, "port", translate("Port"))
|
||||
port.default = "8080"
|
||||
port.datatype = "port"
|
||||
|
||||
tls_cert = e:option(Value, "tls_cert", translate("TLS certificate file path"))
|
||||
tls_key = e:option(Value, "tls_key", translate("TLS private key file path"))
|
||||
|
||||
auth_user = e:option(Value, "auth_user", translate("Username"))
|
||||
auth_password = e:option(Value, "auth_password", translate("Password"))
|
||||
auth_password.password = true
|
||||
|
||||
read_buffer_size = e:option(Value, "read_buffer_size", translate("Read Buffer Size"))
|
||||
read_buffer_size.default = "10485760"
|
||||
read_buffer_size.datatype = "uinteger"
|
||||
|
||||
cache_size = e:option(Value, "cache_size", translate("Cache Size"))
|
||||
cache_size.default = "1000"
|
||||
cache_size.datatype = "uinteger"
|
||||
|
||||
cache_ttl = e:option(Value, "cache_ttl", translate("Cache Expiration Time (seconds)"))
|
||||
cache_ttl.default = "600"
|
||||
cache_ttl.datatype = "uinteger"
|
||||
|
||||
no_trash = e:option(Flag, "no_trash", translate("Delete file permanently instead of trashing"))
|
||||
no_trash.rmempty = false
|
||||
|
||||
read_only = e:option(Flag, "read_only", translate("Enable read only mode"))
|
||||
read_only.description = translate("Disallow upload, modify and delete file operations")
|
||||
read_only.rmempty = false
|
||||
|
||||
domain_id = e:option(Value, "domain_id", translate("Domain ID"))
|
||||
domain_id.description = translate("Input domain_id option will use <a href=\"https://www.aliyun.com/product/storage/pds\" target=\"_blank\">Aliyun PDS</a> instead of <a href=\"https://www.aliyundrive.com\" target=\"_blank\">AliyunDrive</a>")
|
||||
|
||||
debug = e:option(Flag, "debug", translate("Debug Mode"))
|
||||
debug.rmempty = false
|
||||
|
||||
return m
|
@ -0,0 +1,9 @@
|
||||
log = SimpleForm("logview")
|
||||
log.submit = false
|
||||
log.reset = false
|
||||
|
||||
t = log:field(DummyValue, '', '')
|
||||
t.rawhtml = true
|
||||
t.template = 'aliyundrive-webdav/aliyundrive-webdav_log'
|
||||
|
||||
return log
|
@ -0,0 +1,15 @@
|
||||
<%+cbi/valueheader%>
|
||||
<textarea id="logview" class="cbi-input-textarea" style="width: 100%" rows="30" readonly="readonly"></textarea>
|
||||
|
||||
<script type="text/javascript">
|
||||
const LOG_URL = '<%=luci.dispatcher.build_url("admin", "services", "aliyundrive-webdav", "logtail")%>';
|
||||
XHR.poll(1, LOG_URL, null, (x, d) => {
|
||||
let logview = document.getElementById("logview");
|
||||
if (!d.running) {
|
||||
XHR.halt();
|
||||
}
|
||||
logview.value = d.log;
|
||||
logview.scrollTop = logview.scrollHeight;
|
||||
});
|
||||
</script>
|
||||
<%+cbi/valuefooter%>
|
@ -0,0 +1,21 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[aliyundrive-webdav]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('aliyundrive-webdav_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
tb.innerHTML = '<em><b style=color:green>' + data.application + '<%:RUNNING%></b></em>';
|
||||
} else {
|
||||
tb.innerHTML = '<em><b style=color:red>' + data.application + '<%:NOT RUNNING%></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="aliyundrive-webdav_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
86
luci-app-aliyundrive-webdav/po/zh-cn/aliyundrive-webdav.po
Normal file
86
luci-app-aliyundrive-webdav/po/zh-cn/aliyundrive-webdav.po
Normal file
@ -0,0 +1,86 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
||||
msgid "AliyunDrive"
|
||||
msgstr "阿里云盘"
|
||||
|
||||
msgid "AliyunDrive WebDAV"
|
||||
msgstr "阿里云盘 WebDAV"
|
||||
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
msgid "Refresh Token"
|
||||
msgstr "Refresh Token"
|
||||
|
||||
msgid "Root Directory"
|
||||
msgstr "云盘根目录"
|
||||
|
||||
msgid "Host"
|
||||
msgstr "监听主机"
|
||||
|
||||
msgid "Port"
|
||||
msgstr "监听端口"
|
||||
|
||||
msgid "TLS certificate file path"
|
||||
msgstr "TLS 证书文件路径"
|
||||
|
||||
msgid "TLS private key file path"
|
||||
msgstr "TLS 私钥文件路径"
|
||||
|
||||
msgid "Username"
|
||||
msgstr "用户名"
|
||||
|
||||
msgid "Password"
|
||||
msgstr "密码"
|
||||
|
||||
msgid "Read Buffer Size"
|
||||
msgstr "下载缓冲大小(bytes)"
|
||||
|
||||
msgid "Cache Size"
|
||||
msgstr "目录缓存大小"
|
||||
|
||||
msgid "Cache Expiration Time (seconds)"
|
||||
msgstr "目录缓存过期时间(单位为秒)"
|
||||
|
||||
msgid "Collecting data..."
|
||||
msgstr "获取数据中..."
|
||||
|
||||
msgid "RUNNING"
|
||||
msgstr "运行中"
|
||||
|
||||
msgid "NOT RUNNING"
|
||||
msgstr "未运行"
|
||||
|
||||
msgid "Settings"
|
||||
msgstr "设置"
|
||||
|
||||
msgid "Log"
|
||||
msgstr "日志"
|
||||
|
||||
msgid "Debug Mode"
|
||||
msgstr "调试模式"
|
||||
|
||||
msgid "<a href=\"https://github.com/messense/aliyundrive-webdav\" target=\"_blank\">Project GitHub URL</a>"
|
||||
msgstr "<a href=\"https://github.com/messense/aliyundrive-webdav\" target=\"_blank\">GitHub 项目地址</a>"
|
||||
|
||||
msgid "<a href=\"https://github.com/messense/aliyundrive-webdav#%E8%8E%B7%E5%8F%96-refresh_token\" target=\"_blank\">How to get refresh token</a>"
|
||||
msgstr "<a href=\"https://github.com/messense/aliyundrive-webdav#%E8%8E%B7%E5%8F%96-refresh_token\" target=\"_blank\">查看获取 refresh token 的方法</a>"
|
||||
|
||||
msgid "Restrict access to a folder of aliyundrive, defaults to / which means no restrictions"
|
||||
msgstr "限制只能访问该云盘目录,默认为 / 表示不限制,注意这个参数不是本地磁盘路径"
|
||||
|
||||
msgid "Delete file permanently instead of trashing"
|
||||
msgstr "删除文件不放入回收站"
|
||||
|
||||
msgid "Enable read only mode"
|
||||
msgstr "启用只读模式"
|
||||
|
||||
msgid "Disallow upload, modify and delete file operations"
|
||||
msgstr "禁止上传、修改和删除文件操作"
|
||||
|
||||
msgid "Domain ID"
|
||||
msgstr "阿里云相册与云盘服务 domainId"
|
||||
|
||||
msgid "Input domain_id option will use <a href=\"https://www.aliyun.com/product/storage/pds\" target=\"_blank\">Aliyun PDS</a> instead of <a href=\"https://www.aliyundrive.com\" target=\"_blank\">AliyunDrive</a>"
|
||||
msgstr "填写此选项将使用<a href=\"https://www.aliyun.com/product/storage/pds\" target=\"_blank\">阿里云相册与网盘服务</a>而不是<a href=\"https://www.aliyundrive.com\" target=\"_blank\">阿里云盘</a>"
|
1
luci-app-aliyundrive-webdav/po/zh_Hans
Symbolic link
1
luci-app-aliyundrive-webdav/po/zh_Hans
Symbolic link
@ -0,0 +1 @@
|
||||
zh-cn
|
11
luci-app-aliyundrive-webdav/root/etc/uci-defaults/luci-aliyundrive-webdav
Executable file
11
luci-app-aliyundrive-webdav/root/etc/uci-defaults/luci-aliyundrive-webdav
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@aliyundrive-webdav[-1]
|
||||
add ucitrack aliyundrive-webdav
|
||||
set ucitrack.@aliyundrive-webdav[-1].init=aliyundrive-webdav
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-aliyundrive-webdav": {
|
||||
"description": "Grant UCI access for luci-app-aliyundrive-webdav",
|
||||
"read": {
|
||||
"uci": [ "aliyundrive-webdav" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "aliyundrive-webdav" ]
|
||||
}
|
||||
}
|
||||
}
|
19
luci-app-argon-config/Makefile
Normal file
19
luci-app-argon-config/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-argon-config
|
||||
PKG_VERSION:=0.9
|
||||
PKG_RELEASE:=20210904
|
||||
|
||||
PKG_MAINTAINER:=jerrykuku <jerrykuku@qq.com>
|
||||
|
||||
LUCI_TITLE:=LuCI page for Argon Config
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+luci-compat
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/argon
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
4
luci-app-argon-config/README.md
Normal file
4
luci-app-argon-config/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# luci-app-argon-config
|
||||
Argon Theme Config Plugin
|
||||
|
||||
You can set the blur and transparency of the login page of argon theme, and manage the background pictures and videos.
|
13
luci-app-argon-config/luasrc/controller/argon-config.lua
Normal file
13
luci-app-argon-config/luasrc/controller/argon-config.lua
Normal file
@ -0,0 +1,13 @@
|
||||
--[[
|
||||
luci-app-argon-config
|
||||
]]--
|
||||
|
||||
module("luci.controller.argon-config", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access('/www/luci-static/argon/css/cascade.css') then
|
||||
return
|
||||
end
|
||||
|
||||
entry({"admin", "system", "argon-config"}, form("argon-config"), _("Argon Config"), 90)
|
||||
end
|
223
luci-app-argon-config/luasrc/model/cbi/argon-config.lua
Normal file
223
luci-app-argon-config/luasrc/model/cbi/argon-config.lua
Normal file
@ -0,0 +1,223 @@
|
||||
local nxfs = require 'nixio.fs'
|
||||
local wa = require 'luci.tools.webadmin'
|
||||
local opkg = require 'luci.model.ipkg'
|
||||
local sys = require 'luci.sys'
|
||||
local http = require 'luci.http'
|
||||
local nutil = require 'nixio.util'
|
||||
local name = 'argon'
|
||||
local uci = require 'luci.model.uci'.cursor()
|
||||
|
||||
local fstat = nxfs.statvfs(opkg.overlay_root())
|
||||
local space_total = fstat and fstat.blocks or 0
|
||||
local space_free = fstat and fstat.bfree or 0
|
||||
local space_used = space_total - space_free
|
||||
|
||||
local free_byte = space_free * fstat.frsize
|
||||
|
||||
local primary, dark_primary, blur_radius, blur_radius_dark, blur_opacity, mode
|
||||
if nxfs.access('/etc/config/argon') then
|
||||
primary = uci:get_first('argon', 'global', 'primary')
|
||||
dark_primary = uci:get_first('argon', 'global', 'dark_primary')
|
||||
blur_radius = uci:get_first('argon', 'global', 'blur')
|
||||
blur_radius_dark = uci:get_first('argon', 'global', 'blur_dark')
|
||||
blur_opacity = uci:get_first('argon', 'global', 'transparency')
|
||||
blur_opacity_dark = uci:get_first('argon', 'global', 'transparency_dark')
|
||||
mode = uci:get_first('argon', 'global', 'mode')
|
||||
bing_background = uci:get_first('argon', 'global', 'bing_background')
|
||||
end
|
||||
|
||||
function glob(...)
|
||||
local iter, code, msg = nxfs.glob(...)
|
||||
if iter then
|
||||
return nutil.consume(iter)
|
||||
else
|
||||
return nil, code, msg
|
||||
end
|
||||
end
|
||||
|
||||
local transparency_sets = {
|
||||
0,
|
||||
0.1,
|
||||
0.2,
|
||||
0.3,
|
||||
0.4,
|
||||
0.5,
|
||||
0.6,
|
||||
0.7,
|
||||
0.8,
|
||||
0.9,
|
||||
1
|
||||
}
|
||||
|
||||
-- [[ 模糊设置 ]]--
|
||||
br = SimpleForm('config', translate('Argon Config'), translate('Here you can set the blur and transparency of the login page of argon theme, and manage the background pictures and videos.[Chrome is recommended]'))
|
||||
br.reset = false
|
||||
br.submit = false
|
||||
s = br:section(SimpleSection)
|
||||
|
||||
o = s:option(ListValue, 'bing_background', translate('Wallpaper Source'))
|
||||
o:value('0', translate('Built-in'))
|
||||
o:value('1', translate('Bing Wallpapers'))
|
||||
o.default = bing_background
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, 'mode', translate('Theme mode'))
|
||||
o:value('normal', translate('Follow System'))
|
||||
o:value('light', translate('Force Light'))
|
||||
o:value('dark', translate('Force Dark'))
|
||||
o.default = mode
|
||||
o.rmempty = false
|
||||
o.description = translate('You can choose Theme color mode here')
|
||||
|
||||
o = s:option(Value, 'primary', translate('[Light mode] Primary Color'), translate('A HEX Color ; ( Default: #5e72e4 )'))
|
||||
o.default = primary
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
|
||||
|
||||
o = s:option(ListValue, 'transparency', translate('[Light mode] Transparency'), translate('0 transparent - 1 opaque ; ( Suggest: transparent: 0 or translucent preset: 0.5 )'))
|
||||
for _, v in ipairs(transparency_sets) do
|
||||
o:value(v)
|
||||
end
|
||||
o.default = blur_opacity
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, 'blur', translate('[Light mode] Frosted Glass Radius'), translate('Larger value will more blurred ; ( Suggest: clear: 1 or blur preset: 10 )'))
|
||||
o.default = blur_radius
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, 'dark_primary', translate('[Dark mode] Primary Color'), translate('A HEX Color ; ( Default: #483d8b )'))
|
||||
o.default = dark_primary
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(ListValue, 'transparency_dark', translate('[Dark mode] Transparency'), translate('0 transparent - 1 opaque ; ( Suggest: Black translucent preset: 0.5 )'))
|
||||
for _, v in ipairs(transparency_sets) do
|
||||
o:value(v)
|
||||
end
|
||||
o.default = blur_opacity_dark
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Value, 'blur_dark', translate('[Dark mode] Frosted Glass Radius'), translate('Larger value will more blurred ; ( Suggest: clear: 1 or blur preset: 10 )'))
|
||||
o.default = blur_radius_dark
|
||||
o.datatype = ufloat
|
||||
o.rmempty = false
|
||||
|
||||
o = s:option(Button, 'save', translate('Save Changes'))
|
||||
o.inputstyle = 'reload'
|
||||
|
||||
function br.handle(self, state, data)
|
||||
if (state == FORM_VALID and data.blur ~= nil and data.blur_dark ~= nil and data.transparency ~= nil and data.transparency_dark ~= nil and data.mode ~= nil) then
|
||||
nxfs.writefile('/tmp/aaa', data)
|
||||
for key, value in pairs(data) do
|
||||
uci:set('argon','@global[0]',key,value)
|
||||
end
|
||||
uci:commit('argon')
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
ful = SimpleForm('upload', translate('Upload (Free: ') .. wa.byte_format(free_byte) .. ')', translate("You can upload files such as jpg,png,gif,mp4 files, To change the login page background."))
|
||||
ful.reset = false
|
||||
ful.submit = false
|
||||
|
||||
sul = ful:section(SimpleSection, '', translate("Upload file to '/www/luci-static/argon/background/'"))
|
||||
fu = sul:option(FileUpload, '')
|
||||
fu.template = 'argon-config/other_upload'
|
||||
um = sul:option(DummyValue, '', nil)
|
||||
um.template = 'argon-config/other_dvalue'
|
||||
|
||||
local dir, fd
|
||||
dir = '/www/luci-static/argon/background/'
|
||||
nxfs.mkdir(dir)
|
||||
http.setfilehandler(
|
||||
function(meta, chunk, eof)
|
||||
if not fd then
|
||||
if not meta then
|
||||
return
|
||||
end
|
||||
|
||||
if meta and chunk then
|
||||
fd = nixio.open(dir .. meta.file, 'w')
|
||||
end
|
||||
|
||||
if not fd then
|
||||
um.value = translate('Create upload file error.')
|
||||
return
|
||||
end
|
||||
end
|
||||
if chunk and fd then
|
||||
fd:write(chunk)
|
||||
end
|
||||
if eof and fd then
|
||||
fd:close()
|
||||
fd = nil
|
||||
um.value = translate('File saved to') .. ' "/www/luci-static/argon/background/' .. meta.file .. '"'
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
if http.formvalue('upload') then
|
||||
local f = http.formvalue('ulfile')
|
||||
if #f <= 0 then
|
||||
um.value = translate('No specify upload file.')
|
||||
end
|
||||
end
|
||||
|
||||
local function getSizeStr(size)
|
||||
local i = 0
|
||||
local byteUnits = {' kB', ' MB', ' GB', ' TB'}
|
||||
repeat
|
||||
size = size / 1024
|
||||
i = i + 1
|
||||
until (size <= 1024)
|
||||
return string.format('%.1f', size) .. byteUnits[i]
|
||||
end
|
||||
|
||||
local inits, attr = {}
|
||||
for i, f in ipairs(glob(dir .. '*')) do
|
||||
attr = nxfs.stat(f)
|
||||
if attr then
|
||||
inits[i] = {}
|
||||
inits[i].name = nxfs.basename(f)
|
||||
inits[i].mtime = os.date('%Y-%m-%d %H:%M:%S', attr.mtime)
|
||||
inits[i].modestr = attr.modestr
|
||||
inits[i].size = getSizeStr(attr.size)
|
||||
inits[i].remove = 0
|
||||
inits[i].install = false
|
||||
end
|
||||
end
|
||||
|
||||
form = SimpleForm('filelist', translate('Background file list'), nil)
|
||||
form.reset = false
|
||||
form.submit = false
|
||||
|
||||
tb = form:section(Table, inits)
|
||||
nm = tb:option(DummyValue, 'name', translate('File name'))
|
||||
mt = tb:option(DummyValue, 'mtime', translate('Modify time'))
|
||||
sz = tb:option(DummyValue, 'size', translate('Size'))
|
||||
btnrm = tb:option(Button, 'remove', translate('Remove'))
|
||||
btnrm.render = function(self, section, scope)
|
||||
self.inputstyle = 'remove'
|
||||
Button.render(self, section, scope)
|
||||
end
|
||||
|
||||
btnrm.write = function(self, section)
|
||||
local v = nxfs.unlink(dir .. nxfs.basename(inits[section].name))
|
||||
if v then
|
||||
table.remove(inits, section)
|
||||
end
|
||||
return v
|
||||
end
|
||||
|
||||
function IsIpkFile(name)
|
||||
name = name or ''
|
||||
local ext = string.lower(string.sub(name, -4, -1))
|
||||
return ext == '.ipk'
|
||||
end
|
||||
|
||||
return br, ful, form
|
@ -0,0 +1,7 @@
|
||||
<%+cbi/valueheader%>
|
||||
<% if self:cfgvalue(section) ~= false then %>
|
||||
<input class="cbi-button cbi-input-<%=self.inputstyle or "button" %>" style="display: <%= display %>" type="submit"<%= attr("name", cbid) .. attr("id", cbid) .. attr("value", self.inputtitle or self.title)%> />
|
||||
<% else %>
|
||||
-
|
||||
<% end %>
|
||||
<%+cbi/valuefooter%>
|
@ -0,0 +1,8 @@
|
||||
<%+cbi/valueheader%>
|
||||
<span style="color: red">
|
||||
<%
|
||||
local val = self:cfgvalue(section) or self.default or ""
|
||||
write(pcdata(val))
|
||||
%>
|
||||
</span>
|
||||
<%+cbi/valuefooter%>
|
@ -0,0 +1,5 @@
|
||||
<%+cbi/valueheader%>
|
||||
<label class="cbi-value" style="display:inline-block; width: 130px" for="ulfile"><%:Choose local file:%></label>
|
||||
<input class="cbi-input-file" style="width: 400px" type="file" id="ulfile" name="ulfile" accept="image/png, image/jpeg, image/gif, video/mp4"/>
|
||||
<input type="submit" class="btn cbi-button cbi-input-apply" name="upload" value="<%:Upload%>" />
|
||||
<%+cbi/valuefooter%>
|
176
luci-app-argon-config/po/es/argon-config.po
Normal file
176
luci-app-argon-config/po/es/argon-config.po
Normal file
@ -0,0 +1,176 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: 2021-03-15 21:25-0300\n"
|
||||
"PO-Revision-Date: 2021-03-15 21:58-0300\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.4.2\n"
|
||||
"Last-Translator: Franco Castillo <castillofrancodamian@gmail.com>\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Language: es\n"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:97
|
||||
msgid "0 transparent - 1 opaque ; ( Suggest: Black translucent preset: 0.5 )"
|
||||
msgstr ""
|
||||
"0 transparente - 1 opaco; (Sugerencia: negro translúcido preestablecido: 0.5)"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:79
|
||||
msgid ""
|
||||
"0 transparent - 1 opaque ; ( Suggest: transparent: 0 or translucent preset: "
|
||||
"0.5 )"
|
||||
msgstr ""
|
||||
"0 transparente - 1 opaco; (Sugerencia: transparente: 0 o translúcido "
|
||||
"preestablecido: 0.5)"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:92
|
||||
msgid "A HEX Color ; ( Default: #483d8b )"
|
||||
msgstr "Un color HEX; (Predeterminado: #483d8b)"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:72
|
||||
msgid "A HEX Color ; ( Default: #5e72e4 )"
|
||||
msgstr "Un color HEX; (Predeterminado: #5e72e4)"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/controller/argon-config.lua:11
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:53
|
||||
msgid "Argon Config"
|
||||
msgstr "Configuración de Argon"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:195
|
||||
msgid "Background file list"
|
||||
msgstr "Lista de archivos de fondo"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:60
|
||||
msgid "Bing Wallpapers"
|
||||
msgstr "Fondos de Bing"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:59
|
||||
msgid "Built-in"
|
||||
msgstr "Integrado"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/view/argon-config/other_upload.htm:2
|
||||
msgid "Choose local file:"
|
||||
msgstr "Elija un archivo local:"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:149
|
||||
msgid "Create upload file error."
|
||||
msgstr "Crear archivo de error de carga."
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:200
|
||||
msgid "File name"
|
||||
msgstr "Nombre del archivo"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:159
|
||||
msgid "File saved to"
|
||||
msgstr "Archivo guardado en"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:65
|
||||
msgid "Follow System"
|
||||
msgstr "Seguir el sistema"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:67
|
||||
msgid "Force Dark"
|
||||
msgstr "Fuerza oscuro"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:66
|
||||
msgid "Force Light"
|
||||
msgstr "Forzar claro"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:53
|
||||
msgid ""
|
||||
"Here you can set the blur and transparency of the login page of argon theme, "
|
||||
"and manage the background pictures and videos.[Chrome is recommended]"
|
||||
msgstr ""
|
||||
"Aquí puede configurar el desenfoque y la transparencia de la página de "
|
||||
"inicio de sesión del tema argon y administrar las imágenes de fondo y los "
|
||||
"videos. [Se recomienda Chrome]"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:87
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:105
|
||||
msgid ""
|
||||
"Larger value will more blurred ; ( Suggest: clear: 1 or blur preset: 10 )"
|
||||
msgstr ""
|
||||
"El valor más grande se verá más borroso; (Sugerencia: claro: 1 o desenfoque "
|
||||
"predeterminado: 10)"
|
||||
|
||||
#: applications/luci-app-argon-config/root/usr/share/rpcd/acl.d/luci-app-argon-config.json:3
|
||||
msgid "Luci Argon theme config"
|
||||
msgstr "Configuración del tema Luci Argon"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:201
|
||||
msgid "Modify time"
|
||||
msgstr "Modificar la hora"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:167
|
||||
msgid "No specify upload file."
|
||||
msgstr "No especificar archivo de carga."
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:203
|
||||
msgid "Remove"
|
||||
msgstr "Eliminar"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:110
|
||||
msgid "Save Changes"
|
||||
msgstr "Guardar cambios"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:202
|
||||
msgid "Size"
|
||||
msgstr "Tamaño"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:64
|
||||
msgid "Theme mode"
|
||||
msgstr "Modo del tema"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/view/argon-config/other_upload.htm:4
|
||||
msgid "Upload"
|
||||
msgstr "Cargar"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:124
|
||||
msgid "Upload (Free:"
|
||||
msgstr "Cargar (Libre:"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:128
|
||||
msgid "Upload file to '/www/luci-static/argon/background/'"
|
||||
msgstr "Subir archivo a '/www/luci-static/argon/background/'"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:58
|
||||
msgid "Wallpaper Source"
|
||||
msgstr "Fuente del fondo de pantalla"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:70
|
||||
msgid "You can choose Theme color mode here"
|
||||
msgstr "Puede elegir el modo de color del tema aquí"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:124
|
||||
msgid ""
|
||||
"You can upload files such as jpg,png,gif,mp4 files, To change the login page "
|
||||
"background."
|
||||
msgstr ""
|
||||
"Puede cargar archivos como jpg, png, gif, mp4, para cambiar el fondo de la "
|
||||
"página de inicio de sesión."
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:105
|
||||
msgid "[Dark mode] Frosted Glass Radius"
|
||||
msgstr "[Modo oscuro] Radio de vidrio esmerilado"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:92
|
||||
msgid "[Dark mode] Primary Color"
|
||||
msgstr "[Modo oscuro] Color primario"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:97
|
||||
msgid "[Dark mode] Transparency"
|
||||
msgstr "[Modo oscuro] Transparencia"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:87
|
||||
msgid "[Light mode] Frosted Glass Radius"
|
||||
msgstr "[Modo claro] Radio de vidrio esmerilado"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:72
|
||||
msgid "[Light mode] Primary Color"
|
||||
msgstr "[Modo claro] Color primario"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:79
|
||||
msgid "[Light mode] Transparency"
|
||||
msgstr "[Modo claro] Transparencia"
|
155
luci-app-argon-config/po/templates/argon-config.pot
Normal file
155
luci-app-argon-config/po/templates/argon-config.pot
Normal file
@ -0,0 +1,155 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:97
|
||||
msgid "0 transparent - 1 opaque ; ( Suggest: Black translucent preset: 0.5 )"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:79
|
||||
msgid ""
|
||||
"0 transparent - 1 opaque ; ( Suggest: transparent: 0 or translucent preset: "
|
||||
"0.5 )"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:92
|
||||
msgid "A HEX Color ; ( Default: #483d8b )"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:72
|
||||
msgid "A HEX Color ; ( Default: #5e72e4 )"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/controller/argon-config.lua:11
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:53
|
||||
msgid "Argon Config"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:195
|
||||
msgid "Background file list"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:60
|
||||
msgid "Bing Wallpapers"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:59
|
||||
msgid "Built-in"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/view/argon-config/other_upload.htm:2
|
||||
msgid "Choose local file:"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:149
|
||||
msgid "Create upload file error."
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:200
|
||||
msgid "File name"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:159
|
||||
msgid "File saved to"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:65
|
||||
msgid "Follow System"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:67
|
||||
msgid "Force Dark"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:66
|
||||
msgid "Force Light"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:53
|
||||
msgid ""
|
||||
"Here you can set the blur and transparency of the login page of argon theme, "
|
||||
"and manage the background pictures and videos.[Chrome is recommended]"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:87
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:105
|
||||
msgid ""
|
||||
"Larger value will more blurred ; ( Suggest: clear: 1 or blur preset: 10 )"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/root/usr/share/rpcd/acl.d/luci-app-argon-config.json:3
|
||||
msgid "Luci Argon theme config"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:201
|
||||
msgid "Modify time"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:167
|
||||
msgid "No specify upload file."
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:203
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:110
|
||||
msgid "Save Changes"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:202
|
||||
msgid "Size"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:64
|
||||
msgid "Theme mode"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/view/argon-config/other_upload.htm:4
|
||||
msgid "Upload"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:124
|
||||
msgid "Upload (Free:"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:128
|
||||
msgid "Upload file to '/www/luci-static/argon/background/'"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:58
|
||||
msgid "Wallpaper Source"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:70
|
||||
msgid "You can choose Theme color mode here"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:124
|
||||
msgid ""
|
||||
"You can upload files such as jpg,png,gif,mp4 files, To change the login page "
|
||||
"background."
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:105
|
||||
msgid "[Dark mode] Frosted Glass Radius"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:92
|
||||
msgid "[Dark mode] Primary Color"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:97
|
||||
msgid "[Dark mode] Transparency"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:87
|
||||
msgid "[Light mode] Frosted Glass Radius"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:72
|
||||
msgid "[Light mode] Primary Color"
|
||||
msgstr ""
|
||||
|
||||
#: applications/luci-app-argon-config/luasrc/model/cbi/argon-config.lua:79
|
||||
msgid "[Light mode] Transparency"
|
||||
msgstr ""
|
133
luci-app-argon-config/po/zh-cn/argon-config.po
Normal file
133
luci-app-argon-config/po/zh-cn/argon-config.po
Normal file
@ -0,0 +1,133 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Project-Id-Version: \n"
|
||||
"POT-Creation-Date: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: dingpengyu <jerrykuku@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: zh_CN\n"
|
||||
"X-Generator: Poedit 2.3.1\n"
|
||||
|
||||
msgid "Argon Config"
|
||||
msgstr "Argon 主题设置"
|
||||
|
||||
msgid "Here you can set the blur and transparency of the login page of argon theme, and manage the background pictures and videos.[Chrome is recommended]"
|
||||
msgstr "在这里你可以设置argon 主题的登录页面的模糊和透明度,并管理背景图片与视频。[建议使用 Chrome]"
|
||||
|
||||
msgid "Wallpaper Source"
|
||||
msgstr "壁纸来源"
|
||||
|
||||
msgid "Built-in"
|
||||
msgstr "内建"
|
||||
|
||||
msgid "Bing Wallpapers"
|
||||
msgstr "Bing 壁纸"
|
||||
|
||||
msgid "Theme mode"
|
||||
msgstr "主题模式"
|
||||
|
||||
msgid "Follow System"
|
||||
msgstr "跟随系统"
|
||||
|
||||
msgid "Force Light"
|
||||
msgstr "强制亮色"
|
||||
|
||||
msgid "Force Dark"
|
||||
msgstr "强制暗色"
|
||||
|
||||
msgid "You can choose Theme color mode here"
|
||||
msgstr "你可以选择喜欢的主题模式"
|
||||
|
||||
msgid "[Light mode] Primary Color"
|
||||
msgstr "[亮色模式] 主色调"
|
||||
|
||||
msgid "[Dark mode] Primary Color"
|
||||
msgstr "[暗色模式] 主色调"
|
||||
|
||||
msgid "A HEX Color ; ( Default: #5e72e4 )"
|
||||
msgstr "十六进制颜色值 ( 预设为:#5e72e4 )"
|
||||
|
||||
msgid "A HEX Color ; ( Default: #483d8b )"
|
||||
msgstr "十六进制颜色值 ( 预设为:#483d8b )"
|
||||
|
||||
msgid "[Light mode] Transparency"
|
||||
msgstr "[亮色模式] 透明度"
|
||||
|
||||
msgid "[Light mode] Transparency"
|
||||
msgstr "[亮色模式] 透明度"
|
||||
|
||||
msgid "[Dark mode] Transparency"
|
||||
msgstr "[暗色模式] 透明度"
|
||||
|
||||
msgid "0 transparent - 1 opaque ; ( Suggest: transparent: 0 or translucent preset: 0.5 )"
|
||||
msgstr "0最透明 - 1不透明 ; ( 建议: 透明 0 或 半透明预设 0.5 )"
|
||||
|
||||
msgid "0 transparent - 1 opaque ; ( Suggest: Black translucent preset: 0.5 )"
|
||||
msgstr "0最透明 - 1不透明 ; ( 建议: 黑色半透明 0.5 )"
|
||||
|
||||
msgid "[Light mode] Frosted Glass Radius"
|
||||
msgstr "[亮色模式] 毛玻璃模糊半径"
|
||||
|
||||
msgid "[Dark mode] Frosted Glass Radius"
|
||||
msgstr "[暗色模式] 毛玻璃模糊半径"
|
||||
|
||||
msgid "Larger value will more blurred ; ( Suggest: clear: 1 or blur preset: 10 )"
|
||||
msgstr "值越大越模糊; ( 建议: 清透 1 或 模糊预设 10 )"
|
||||
|
||||
msgid "You can upload files such as jpg,png,gif,mp4 files, To change the login page background."
|
||||
msgstr "你可以上传jpg、png、gif或mp4文件,以创建自己喜欢的登录界面"
|
||||
|
||||
msgid "Save Changes"
|
||||
msgstr "保存更改"
|
||||
|
||||
msgid "Choose local file:"
|
||||
msgstr "选择本地文件:"
|
||||
|
||||
msgid "Couldn't open file:"
|
||||
msgstr "无法打开文件:"
|
||||
|
||||
msgid "Create upload file error."
|
||||
msgstr "创建上传文件失败。"
|
||||
|
||||
|
||||
msgid "File name"
|
||||
msgstr "文件名"
|
||||
|
||||
msgid "File saved to"
|
||||
msgstr "文件保存到"
|
||||
|
||||
msgid "FileTransfer"
|
||||
msgstr "文件传输"
|
||||
|
||||
msgid "Install"
|
||||
msgstr "安装"
|
||||
|
||||
msgid "Attributes"
|
||||
msgstr "属性"
|
||||
|
||||
msgid "Modify time"
|
||||
msgstr "修改时间"
|
||||
|
||||
msgid "No specify upload file."
|
||||
msgstr "未指定上传文件。"
|
||||
|
||||
msgid "Path on Route:"
|
||||
msgstr "路由根目录:"
|
||||
|
||||
msgid "Remove"
|
||||
msgstr "移除"
|
||||
|
||||
msgid "Size"
|
||||
msgstr "大小"
|
||||
|
||||
msgid "Upload (Free:"
|
||||
msgstr "上传 (剩余空间:"
|
||||
|
||||
msgid "Background file list"
|
||||
msgstr "背景文件列表"
|
||||
|
||||
msgid "Upload file to '/www/luci-static/argon/background/'"
|
||||
msgstr "文件将上传到'/www/luci-static/argon/background/'"
|
1
luci-app-argon-config/po/zh_Hans
Symbolic link
1
luci-app-argon-config/po/zh_Hans
Symbolic link
@ -0,0 +1 @@
|
||||
zh-cn
|
9
luci-app-argon-config/root/etc/config/argon
Normal file
9
luci-app-argon-config/root/etc/config/argon
Normal file
@ -0,0 +1,9 @@
|
||||
config global
|
||||
option primary '#5e72e4'
|
||||
option dark_primary '#483d8b'
|
||||
option blur '10'
|
||||
option blur_dark '10'
|
||||
option transparency '0.5'
|
||||
option transparency_dark '0.5'
|
||||
option mode 'normal'
|
||||
option bing_background '0'
|
6
luci-app-argon-config/root/etc/uci-defaults/luci-argon-config
Executable file
6
luci-app-argon-config/root/etc/uci-defaults/luci-argon-config
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
sed -i 's/cbi.submit\"] = true/cbi.submit\"] = \"1\"/g' /usr/lib/lua/luci/dispatcher.lua
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-argon-config": {
|
||||
"description": "Luci Argon theme config ",
|
||||
"read": {
|
||||
"uci": [ "argon" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "argon" ]
|
||||
}
|
||||
}
|
||||
}
|
21
luci-app-autotimeset/LICENSE
Normal file
21
luci-app-autotimeset/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019-2020 johnrosen1
|
||||
|
||||
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.
|
50
luci-app-autotimeset/Makefile
Normal file
50
luci-app-autotimeset/Makefile
Normal file
@ -0,0 +1,50 @@
|
||||
# Copyright (C) 2019-2021 sirpdboy https://github.com/sirpdboy/luci-app-autotimeset
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-autotimeset
|
||||
PKG_VERSION:=1.4
|
||||
PKG_RELEASE:=20210320
|
||||
|
||||
define Package/$(PKG_NAME)
|
||||
SECTION:=LuCI
|
||||
CATEGORY:=LuCI
|
||||
SUBMENU:=3. Applications
|
||||
TITLE:=luci-app-autotimeset
|
||||
DEPENDS:=+luci
|
||||
DESCRIPTION:=LuCI support for Scheduled Time setting
|
||||
PKGARCH:=all
|
||||
endef
|
||||
define Package/$(PKG_NAME)/description
|
||||
Luci Support for autotimeset.
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
$(foreach po,$(wildcard ${CURDIR}/po/zh-cn/*.po), \
|
||||
po2lmo $(po) $(PKG_BUILD_DIR)/$(patsubst %.po,%.lmo,$(notdir $(po)));)
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/conffiles
|
||||
/etc/config/autotimeset
|
||||
/etc/autotimeset/
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci
|
||||
cp -pR ./luasrc/* $(1)/usr/lib/lua/luci
|
||||
$(INSTALL_DIR) $(1)/
|
||||
cp -pR ./root/* $(1)/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/autotimeset.lmo $(1)/usr/lib/lua/luci/i18n/
|
||||
endef
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
96
luci-app-autotimeset/README.md
Normal file
96
luci-app-autotimeset/README.md
Normal file
@ -0,0 +1,96 @@
|
||||
[![若部分图片无法正常显示,请挂上机场浏览或点这里到末尾看修复教程](https://visitor-badge.glitch.me/badge?page_id=sirpdboy-visitor-badge)](#解决-github-网页上图片显示失败的问题) [![](https://img.shields.io/badge/TG群-点击加入-FFFFFF.svg)](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ)
|
||||
|
||||
[autotimeset 定时设置插件](https://github.com/sirpdboy/luci-app-autotimeset)
|
||||
======================
|
||||
请 **认真阅读完毕** 本页面,本页面包含注意事项和如何使用。
|
||||
|
||||
## 功能说明:
|
||||
|
||||
### 定时设置1.4版
|
||||
#### 2021.2.7 新增功能定时重启网络。现包括:定时重启、定时关机、定时重启网络,各功能可一起使用。
|
||||
|
||||
### 定时设置1.3版
|
||||
#### 2020.10.6 原来重定关机正式改名为定时设置,实现定时重启和定时关机功能二合一。
|
||||
|
||||
### 定时关机1.1版
|
||||
#### 2020.7.19 定时关机功能,彻底解决需要保存二次才生效的问题。
|
||||
|
||||
### 定时关机1.0版
|
||||
#### 2019.2.24 定时关机功能借鉴前辈们的开源代码首发。
|
||||
|
||||
## 编译使用方法 [![](https://img.shields.io/badge/-编译使用方法-F5F5F5.svg)](#编译使用方法-)
|
||||
|
||||
将luci-app-autotimeset添加至 LEDE/OpenWRT 源码的方法。
|
||||
|
||||
### 下载源码方法一:
|
||||
编辑源码文件夹根目录feeds.conf.default并加入如下内容:
|
||||
|
||||
```Brach
|
||||
# feeds获取源码:
|
||||
src-git autotimeset https://github.com/sirpdboy/luci-app-autotimeset
|
||||
```
|
||||
```Brach
|
||||
# 更新feeds,并安装主题:
|
||||
scripts/feeds update autotimeset
|
||||
scripts/feeds install luci-app-autotimeset
|
||||
```
|
||||
|
||||
### 下载源码方法二:
|
||||
```Brach
|
||||
# 下载源码
|
||||
git clone https://github.com/sirpdboy/luci-app-autotimeset package/luci-app-autotimeset
|
||||
make menuconfig
|
||||
```
|
||||
### 配置菜单
|
||||
```Brach
|
||||
make menuconfig
|
||||
# 找到 LuCI -> Applications, 选择 luci-app-autotimeset, 保存后退出。
|
||||
```
|
||||
### 编译
|
||||
```Brach
|
||||
# 编译固件
|
||||
make package/luci-app-autotimeset/compile V=s
|
||||
```
|
||||
|
||||
## 说明 [![](https://img.shields.io/badge/-说明-F5F5F5.svg)](#说明-)
|
||||
|
||||
源码来源:https://github.com/sirpdboy/luci-app-autotimeset
|
||||
|
||||
你可以随意使用其中的源码,但请注明出处。
|
||||
============================
|
||||
|
||||
# My other project
|
||||
网络速度测试 :https://github.com/sirpdboy/NetSpeedTest
|
||||
|
||||
定时设置插件 : https://github.com/sirpdboy/luci-app-autotimeset
|
||||
|
||||
关机功能插件 : https://github.com/sirpdboy/luci-app-poweroffdevice
|
||||
|
||||
opentopd主题 : https://github.com/sirpdboy/luci-theme-opentopd
|
||||
|
||||
opentoks 主题: https://github.com/sirpdboy/luci-theme-opentoks [仿KOOLSAHRE主题]
|
||||
|
||||
btmob 主题: https://github.com/sirpdboy/luci-theme-btmob
|
||||
|
||||
系统高级设置 : https://github.com/sirpdboy/luci-app-advanced
|
||||
|
||||
## 捐助 [![](https://img.shields.io/badge/-捐助-F5F5F5.svg)](#捐助-)
|
||||
|
||||
**如果你觉得此项目对你有帮助,请捐助我们,以使项目能持续发展,更加完善。··请作者喝杯咖啡~~~**
|
||||
|
||||
**你们的支持就是我的动力!**
|
||||
|
||||
### 捐助方式
|
||||
|
||||
| <img src="https://img.shields.io/badge/-支付宝-F5F5F5.svg" href="#赞助支持本项目-" height="25" alt="图飞了😂"/> | <img src="https://img.shields.io/badge/-微信-F5F5F5.svg" height="25" alt="图飞了😂" href="#赞助支持本项目-"/> |
|
||||
| :-----------------: | :-------------: |
|
||||
|<img src="https://img.vim-cn.com/fd/8e2793362ac3510094961b04407beec569b2b4.png" width="150" height="150" alt="图飞了😂" href="#赞助支持本项目-"/>|<img src="https://img.vim-cn.com/c7/675730a88accebf37a97d9e84e33529322b6e9.png" width="150" height="150" alt="图飞了😂" href="#赞助支持本项目-"/>|
|
||||
|
||||
<a href="#readme">
|
||||
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="图飞了😂" title="返回顶部" align="right"/>
|
||||
</a>
|
||||
|
||||
###### [解决 Github 网页上图片显示失败的问题](https://blog.csdn.net/qq_38232598/article/details/91346392)
|
||||
|
||||
[![](https://img.shields.io/badge/TG群-点击加入-FFFFFF.svg)](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ)
|
||||
|
9
luci-app-autotimeset/luasrc/controller/autotimeset.lua
Normal file
9
luci-app-autotimeset/luasrc/controller/autotimeset.lua
Normal file
@ -0,0 +1,9 @@
|
||||
module("luci.controller.autotimeset",package.seeall)
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/autotimeset") then
|
||||
return
|
||||
end
|
||||
local page
|
||||
page = entry({"admin","system","autotimeset"},cbi("autotimeset"),_("Scheduled Setting"),88)
|
||||
page.dependent = true
|
||||
end
|
47
luci-app-autotimeset/luasrc/model/cbi/autotimeset.lua
Normal file
47
luci-app-autotimeset/luasrc/model/cbi/autotimeset.lua
Normal file
@ -0,0 +1,47 @@
|
||||
local o=require"luci.dispatcher"
|
||||
local e=require("luci.model.ipkg")
|
||||
local s=require"nixio.fs"
|
||||
local e=luci.model.uci.cursor()
|
||||
local m,s,e
|
||||
|
||||
m=Map("autotimeset",translate("Scheduled Setting"),translate("Timing settings include: timing restart, timing shutdown, timing restart network, all functions can be used together."))
|
||||
|
||||
s=m:section(TypedSection,"login","")
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
e=s:option(Flag,"enable",translate("Enable"))
|
||||
e.rmempty = false
|
||||
e.default=0
|
||||
|
||||
e=s:option(ListValue,"stype",translate("Scheduled Type"), translate("Set the type of timing"))
|
||||
e:value(1,translate("Scheduled Reboot"))
|
||||
e:value(2,translate("Scheduled Poweroff"))
|
||||
e:value(3,translate("Scheduled ReNetwork"))
|
||||
e.default=2
|
||||
|
||||
e=s:option(ListValue,"week",translate("Week Day"), translate("The start-up cycle is weekly or daily"))
|
||||
e:value(7,translate("Everyday"))
|
||||
e:value(1,translate("Monday"))
|
||||
e:value(2,translate("Tuesday"))
|
||||
e:value(3,translate("Wednesday"))
|
||||
e:value(4,translate("Thursday"))
|
||||
e:value(5,translate("Friday"))
|
||||
e:value(6,translate("Saturday"))
|
||||
e:value(0,translate("Sunday"))
|
||||
e.default=7
|
||||
|
||||
e=s:option(Value,"hour",translate("Hour"), translate("Set an hour"))
|
||||
e.datatype = "range(0,23)"
|
||||
e.rmempty = false
|
||||
|
||||
e=s:option(Value,"minute",translate("Minute"), translate("Set a minute"))
|
||||
e.datatype = "range(0,59)"
|
||||
e.rmempty = false
|
||||
|
||||
local e=luci.http.formvalue("cbi.apply")
|
||||
if e then
|
||||
io.popen("/etc/init.d/autotimeset restart")
|
||||
end
|
||||
|
||||
return m
|
43
luci-app-autotimeset/po/zh-cn/autotimeset.po
Normal file
43
luci-app-autotimeset/po/zh-cn/autotimeset.po
Normal file
@ -0,0 +1,43 @@
|
||||
msgid "Scheduled Setting"
|
||||
msgstr "定时设置"
|
||||
|
||||
msgid "Timing settings include: timing restart, timing shutdown, timing restart network, all functions can be used together."
|
||||
msgstr "定时设置包括:定时重启、定时关机、定时重启网络."
|
||||
|
||||
msgid "Scheduled Type"
|
||||
msgstr "定时类型"
|
||||
|
||||
msgid "Scheduled Reboot"
|
||||
msgstr "定时重启机器"
|
||||
|
||||
msgid "Scheduled Poweroff"
|
||||
msgstr "定时关闭机器"
|
||||
|
||||
msgid "Scheduled ReNetwork"
|
||||
msgstr "定时重启网络"
|
||||
|
||||
msgid "Week Day"
|
||||
msgstr "设定星期"
|
||||
|
||||
msgid "Everyday"
|
||||
msgstr "每天"
|
||||
|
||||
msgid "Hour"
|
||||
msgstr "设定小时"
|
||||
|
||||
msgid "Minute"
|
||||
msgstr "设定分钟"
|
||||
|
||||
msgid "Set the type of timing"
|
||||
msgstr "设定定时的类型"
|
||||
|
||||
msgid "The start-up cycle is weekly or daily"
|
||||
msgstr "设置周期按星期或者每天执行"
|
||||
|
||||
msgid "Set an hour"
|
||||
msgstr "设置某一个小时"
|
||||
|
||||
msgid "Set a minute"
|
||||
msgstr "设置某一分钟"
|
||||
|
||||
Set the type of timing
|
1
luci-app-autotimeset/po/zh_Hans
Symbolic link
1
luci-app-autotimeset/po/zh_Hans
Symbolic link
@ -0,0 +1 @@
|
||||
zh-cn
|
6
luci-app-autotimeset/root/etc/config/autotimeset
Normal file
6
luci-app-autotimeset/root/etc/config/autotimeset
Normal file
@ -0,0 +1,6 @@
|
||||
config login
|
||||
option minute '1'
|
||||
option hour '1'
|
||||
option week '1'
|
||||
option enable '0'
|
||||
option stype '2'
|
117
luci-app-autotimeset/root/etc/init.d/autotimeset
Normal file
117
luci-app-autotimeset/root/etc/init.d/autotimeset
Normal file
@ -0,0 +1,117 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
#copyright by sirpdboy
|
||||
|
||||
START=95
|
||||
STOP=10
|
||||
|
||||
run_autotimeset()
|
||||
{
|
||||
config_get_bool enable $1 enable
|
||||
if [ $enable = 1 ] ; then
|
||||
config_get stype $1 stype
|
||||
config_get week $1 week
|
||||
config_get minute $1 minute
|
||||
config_get hour $1 hour
|
||||
[ "$minute" -eq 0 ] && minute="00"
|
||||
[ "$week" -eq 7 ] && week="*"
|
||||
|
||||
if [ $stype = 1 ] ; then
|
||||
local cmd="$minute $hour * * $week sleep 5 && touch /etc/banner && reboot"
|
||||
if [ ! -f "/etc/crontabs/root" ] || [ $(cat /etc/crontabs/root | grep "$cmd" | wc -l) -eq 0 ]; then
|
||||
sed -i '/reboot/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
echo "$cmd" >> /etc/crontabs/root
|
||||
|
||||
fi
|
||||
echo "Auto REBOOT has started.."
|
||||
|
||||
fi
|
||||
if [ $stype = 2 ] ; then
|
||||
local cmd="$minute $hour * * $week sleep 5 && touch /etc/banner && poweroff"
|
||||
if [ ! -f "/etc/crontabs/root" ] || [ $(cat /etc/crontabs/root | grep "$cmd" | wc -l) -eq 0 ]; then
|
||||
sed -i '/poweroff/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
echo "$cmd" >> /etc/crontabs/root
|
||||
|
||||
fi
|
||||
echo "Auto poweroff has started.."
|
||||
fi
|
||||
if [ $stype = 3 ] ; then
|
||||
local cmd="$minute $hour * * $week sleep 5 && touch /etc/banner && /etc/init.d/network restart"
|
||||
if [ ! -f "/etc/crontabs/root" ] || [ $(cat /etc/crontabs/root | grep "$cmd" | wc -l) -eq 0 ]; then
|
||||
sed -i '/network restart/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
echo "$cmd" >> /etc/crontabs/root
|
||||
|
||||
fi
|
||||
echo "Auto network restart has started."
|
||||
fi
|
||||
else
|
||||
del_cru
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
add_cru()
|
||||
{
|
||||
local enable=$(uci get autotimeset.@login[0].enable)
|
||||
if [ $enable = 1 ] ; then
|
||||
local stype=$(uci get autotimeset.@login[0].stype)
|
||||
local week=$(uci get autotimeset.@login[0].week)
|
||||
local minute=$(uci get autotimeset.@login[0].minute)
|
||||
local hour=$(uci get autotimeset.@login[0].hour)
|
||||
if [ $stype = 1 ] ; then
|
||||
local cmd="$minute $hour * * $week sleep 5 && touch /etc/banner && reboot"
|
||||
if [ ! -f "/etc/crontabs/root" ] || [ $(cat /etc/crontabs/root | grep "$cmd" | wc -l) -eq 0 ]; then
|
||||
sed -i '/reboot/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
echo "$cmd" >> /etc/crontabs/root
|
||||
|
||||
fi
|
||||
echo "Auto REBOOT has started."
|
||||
fi
|
||||
if [ $stype = 2 ] ; then
|
||||
local cmd="$minute $hour * * $week sleep 5 && touch /etc/banner && poweroff"
|
||||
if [ ! -f "/etc/crontabs/root" ] || [ $(cat /etc/crontabs/root | grep "$cmd" | wc -l) -eq 0 ]; then
|
||||
sed -i '/poweroff/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
echo "$cmd" >> /etc/crontabs/root
|
||||
|
||||
fi
|
||||
echo "Auto poweroff has started."
|
||||
fi
|
||||
if [ $stype = 3 ] ; then
|
||||
local cmd="$minute $hour * * $week sleep 5 && touch /etc/banner && /etc/init.d/network restart"
|
||||
if [ ! -f "/etc/crontabs/root" ] || [ $(cat /etc/crontabs/root | grep "$cmd" | wc -l) -eq 0 ]; then
|
||||
sed -i '/network/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
echo "$cmd" >> /etc/crontabs/root
|
||||
|
||||
fi
|
||||
echo "Auto network restart has started."
|
||||
fi
|
||||
else
|
||||
del_cru
|
||||
fi
|
||||
}
|
||||
|
||||
start()
|
||||
{
|
||||
config_load autotimeset
|
||||
config_foreach run_autotimeset login
|
||||
add_cru
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
del_cru
|
||||
echo "Auto set has stop."
|
||||
}
|
||||
|
||||
del_cru()
|
||||
{
|
||||
if [ -f "/etc/crontabs/root" ] && [ $(cat /etc/crontabs/root | grep reboot | wc -l) -ne 0 ]; then
|
||||
sed -i '/reboot/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
fi
|
||||
if [ -f "/etc/crontabs/root" ] && [ $(cat /etc/crontabs/root | grep poweroff | wc -l) -ne 0 ]; then
|
||||
sed -i '/poweroff/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
fi
|
||||
if [ -f "/etc/crontabs/root" ] && [ $(cat /etc/crontabs/root | grep network | wc -l) -ne 0 ]; then
|
||||
sed -i '/network/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@autotimeset[-1]
|
||||
add ucitrack autotimeset
|
||||
set ucitrack.@autotimeset[-1].init=autotimeset
|
||||
commit ucitrack
|
||||
EOF
|
||||
chmod 755 /etc/init.d/autotimeset >/dev/null 2>&1
|
||||
rm -rf /tmp/luci-modulecache /tmp/luci-indexcache*
|
||||
exit 0
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-autotimeset": {
|
||||
"description": "Grant UCI access for luci-app-autotimeset",
|
||||
"read": {
|
||||
"uci": [ "autotimeset" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "autotimeset" ]
|
||||
}
|
||||
}
|
||||
}
|
674
luci-app-autoupdate/LICENSE
Executable file
674
luci-app-autoupdate/LICENSE
Executable file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
11
luci-app-autoupdate/Makefile
Executable file
11
luci-app-autoupdate/Makefile
Executable file
@ -0,0 +1,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI Support for AutoBuild Firmware/AutoUpdate.sh
|
||||
LUCI_DEPENDS:=+curl +wget +bash
|
||||
LUCI_PKGARCH:=all
|
||||
PKG_VERSION:=1
|
||||
PKG_RELEASE:=20210221
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
3
luci-app-autoupdate/README.md
Executable file
3
luci-app-autoupdate/README.md
Executable file
@ -0,0 +1,3 @@
|
||||
# luci-app-autoupdate
|
||||
|
||||
此项目需要搭配 [build-actions](https://github.com/281677160/build-actions) 使用
|
5
luci-app-autoupdate/luasrc/controller/autoupdate.lua
Executable file
5
luci-app-autoupdate/luasrc/controller/autoupdate.lua
Executable file
@ -0,0 +1,5 @@
|
||||
module("luci.controller.autoupdate",package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin","system","autoupdate"},cbi("autoupdate"),_("AutoUpdate"),99)
|
||||
end
|
56
luci-app-autoupdate/luasrc/model/cbi/autoupdate.lua
Executable file
56
luci-app-autoupdate/luasrc/model/cbi/autoupdate.lua
Executable file
@ -0,0 +1,56 @@
|
||||
require("luci.sys")
|
||||
|
||||
m=Map("autoupdate",translate("AutoUpdate"),translate("AutoUpdate LUCI supports one-click firmware upgrade and scheduled upgrade"))
|
||||
|
||||
s=m:section(TypedSection,"login","")
|
||||
s.addremove=false
|
||||
s.anonymous=true
|
||||
|
||||
o = s:option(Flag, "enable", translate("Enable AutoUpdate"),translate("Automatically update firmware during the specified time"))
|
||||
o.default = 0
|
||||
o.optional = false
|
||||
|
||||
week=s:option(ListValue,"week",translate("xWeek Day"))
|
||||
week:value(7,translate("Everyday"))
|
||||
week:value(1,translate("Monday"))
|
||||
week:value(2,translate("Tuesday"))
|
||||
week:value(3,translate("Wednesday"))
|
||||
week:value(4,translate("Thursday"))
|
||||
week:value(5,translate("Friday"))
|
||||
week:value(6,translate("Saturday"))
|
||||
week:value(0,translate("Sunday"))
|
||||
week.default=0
|
||||
|
||||
hour=s:option(Value,"hour",translate("xHour"))
|
||||
hour.datatype = "range(0,23)"
|
||||
hour.rmempty = false
|
||||
|
||||
pass=s:option(Value,"minute",translate("xMinute"))
|
||||
pass.datatype = "range(0,59)"
|
||||
pass.rmempty = false
|
||||
|
||||
local github_url = luci.sys.exec("grep Github= /bin/openwrt_info | cut -c8-100")
|
||||
o=s:option(Value,"github",translate("Github Url"))
|
||||
o.default=github_url
|
||||
|
||||
luci.sys.call ( "/usr/share/autoupdate/Check_Update.sh > /dev/null")
|
||||
local cloud_version = luci.sys.exec("cat /tmp/cloud_version")
|
||||
local current_version = luci.sys.exec("grep LOCAL_Firmware= /etc/openwrt_upgrade | cut -c16-100")
|
||||
local current_model = luci.sys.exec("jsonfilter -e '@.model.id' < /etc/board.json | tr ',' '_'")
|
||||
local MODEL_type = luci.sys.exec("grep MODEL_type= /etc/openwrt_upgrade | cut -c12-100")
|
||||
local KERNEL_type = luci.sys.exec("grep KERNEL_type= /etc/openwrt_upgrade | cut -c13-100")
|
||||
|
||||
button_upgrade_firmware = s:option (Button, "_button_upgrade_firmware", translate("Upgrade to Latested Version"),
|
||||
translatef("若有更新可点击上方 手动更新 后请耐心等待至路由器重启.") .. "<br><br>当前固件版本: " .. current_version .. "<br>云端固件版本: " .. cloud_version.. "<br><br>设备名称: " .. current_model .. "<br>内核版本: " .. KERNEL_type .. "<br>固件类型: " .. MODEL_type)
|
||||
button_upgrade_firmware.inputtitle = translate ("Do Upgrade")
|
||||
button_upgrade_firmware.write = function()
|
||||
luci.sys.call ("bash /bin/AutoUpdate.sh -u > /dev/null")
|
||||
end
|
||||
|
||||
local e=luci.http.formvalue("cbi.apply")
|
||||
if e then
|
||||
io.popen("/etc/init.d/autoupdate restart")
|
||||
end
|
||||
|
||||
return m
|
||||
|
41
luci-app-autoupdate/po/zh-cn/autoupdate.po
Executable file
41
luci-app-autoupdate/po/zh-cn/autoupdate.po
Executable file
@ -0,0 +1,41 @@
|
||||
msgid "AutoUpdate"
|
||||
msgstr "定时更新"
|
||||
|
||||
msgid "xWeek Day"
|
||||
msgstr "更新时间"
|
||||
|
||||
msgid "Everyday"
|
||||
msgstr "每天"
|
||||
|
||||
msgid "Day"
|
||||
msgstr "天"
|
||||
|
||||
msgid "xHour"
|
||||
msgstr "时 [0~23]"
|
||||
|
||||
msgid "xMinute"
|
||||
msgstr "分 [0~59]"
|
||||
|
||||
msgid "Check Update"
|
||||
msgstr "检查更新"
|
||||
|
||||
msgid "Enable AutoUpdate"
|
||||
msgstr "启用定时更新"
|
||||
|
||||
msgid "AutoUpdate LUCI supports one-click firmware upgrade and scheduled upgrade"
|
||||
msgstr "定时更新 LUCI 支持手动更新以及定时更新固件"
|
||||
|
||||
msgid "Do Upgrade"
|
||||
msgstr "手动更新"
|
||||
|
||||
msgid "Upgrade to Latested Version"
|
||||
msgstr "更新固件"
|
||||
|
||||
msgid "Automatically update firmware during the specified time"
|
||||
msgstr "在指定时间段自动检测云端版本,若有新版本自动更新固件"
|
||||
|
||||
msgid "Github Url"
|
||||
msgstr "Github 地址"
|
||||
|
||||
msgid "Please wait patiently after clicking Do Upgrade button"
|
||||
msgstr "点击手动更新按钮后请耐心等待至路由器重启"
|
1
luci-app-autoupdate/po/zh_Hans
Symbolic link
1
luci-app-autoupdate/po/zh_Hans
Symbolic link
@ -0,0 +1 @@
|
||||
zh-cn
|
7
luci-app-autoupdate/root/etc/config/autoupdate
Executable file
7
luci-app-autoupdate/root/etc/config/autoupdate
Executable file
@ -0,0 +1,7 @@
|
||||
config login
|
||||
option enable '0'
|
||||
option forceupdate '0'
|
||||
option week '7'
|
||||
option hour '23'
|
||||
option minute '0'
|
||||
|
50
luci-app-autoupdate/root/etc/init.d/autoupdate
Executable file
50
luci-app-autoupdate/root/etc/init.d/autoupdate
Executable file
@ -0,0 +1,50 @@
|
||||
#!/bin/bash /etc/rc.common
|
||||
START=99
|
||||
|
||||
run_autoupdate()
|
||||
{
|
||||
local enable
|
||||
config_get_bool enable $1 enable
|
||||
if [ $enable == "1" ]; then
|
||||
local minute
|
||||
local hour
|
||||
config_get week $1 week
|
||||
config_get minute $1 minute
|
||||
config_get hour $1 hour
|
||||
[ "$week" == 7 ] && week="*"
|
||||
sed -i '/AutoUpdate/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
echo "$minute $hour * * $week bash /bin/AutoUpdate.sh -u" >> /etc/crontabs/root
|
||||
else
|
||||
sed -i '/AutoUpdate/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
fi
|
||||
if [ -f /bin/AutoUpdate.sh ] && [ -f /bin/openwrt_info ];then
|
||||
cus_url="$(uci get autoupdate.@login[0].github)"
|
||||
ApAuthor="${cus_url%.git}"
|
||||
custom_github_url="${ApAuthor##*com/}"
|
||||
current_github_url="$(grep Warehouse= /bin/openwrt_info | cut -d "=" -f2)"
|
||||
[[ -n "${custom_github_url}" ]] && {
|
||||
[[ "${custom_github_url}" != "${current_github_url}" ]] && {
|
||||
sed -i "s?${current_github_url}?${custom_github_url}?g" /bin/openwrt_info
|
||||
}
|
||||
}
|
||||
fi
|
||||
/etc/init.d/cron restart
|
||||
}
|
||||
|
||||
|
||||
start()
|
||||
{
|
||||
config_load autoupdate
|
||||
config_foreach run_autoupdate login
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
sed -i '/AutoUpdate/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
}
|
||||
|
||||
restart()
|
||||
{
|
||||
stop
|
||||
start
|
||||
}
|
10
luci-app-autoupdate/root/etc/uci-defaults/autoupdate
Executable file
10
luci-app-autoupdate/root/etc/uci-defaults/autoupdate
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@autoupdate[-1]
|
||||
add ucitrack autoupdate
|
||||
set ucitrack.@autoupdate[-1].init=autoupdate
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
exit 0
|
52
luci-app-autoupdate/root/usr/share/autoupdate/Check_Update.sh
Executable file
52
luci-app-autoupdate/root/usr/share/autoupdate/Check_Update.sh
Executable file
@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
# https://github.com/Hyy2001X/AutoBuild-Actions
|
||||
# AutoBuild Module by Hyy2001
|
||||
|
||||
|
||||
[[ -f /tmp/cloud_version ]] && rm -f /tmp/cloud_version
|
||||
[[ -f /tmp/Version_Tags ]] && rm -f /tmp/Version_Tags
|
||||
[[ -f /tmp/baidu.html ]] && rm -rf /tmp/baidu.html
|
||||
|
||||
wget -q -p /tmp http://www.baidu.com/ -O /tmp/baidu.html
|
||||
if [[ -f /tmp/baidu.html ]] && [[ `grep -c "百度一下" /tmp/baidu.html` -ge '1' ]]; then
|
||||
rm -rf /tmp/baidu.html
|
||||
else
|
||||
echo "您可能没进行联网,请检查网络!" > /tmp/cloud_version
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -f /bin/openwrt_info ]]; then
|
||||
chmod +x /bin/openwrt_info
|
||||
source /bin/openwrt_info
|
||||
if [[ $? -ne 0 ]];then
|
||||
echo "openwrt_info数据有误运行失败,请检查openwrt_info文件!" > /tmp/cloud_version
|
||||
exit 1
|
||||
fi
|
||||
chmod +x /bin/AutoUpdate.sh
|
||||
bash /bin/AutoUpdate.sh -w
|
||||
if [[ $? -ne 0 ]];then
|
||||
echo "AutoUpdate.sh数据有误运行失败,请检查AutoUpdate.sh文件!" > /tmp/cloud_version
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "未检测到openwrt_info文件,无法运行更新程序!" > /tmp/cloud_version
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[[ ! -f /tmp/Version_Tags ]] && echo "未检测到云端版本,或您的仓库为私库,或您修改的Github地址有错误,或发布已被删除!" > /tmp/cloud_version && exit 1
|
||||
chmod +x /tmp/Version_Tags && source /tmp/Version_Tags
|
||||
if [[ -n "${CLOUD_Firmware}" ]]; then
|
||||
if [[ "${LOCAL_Firmware}" -eq "${CLOUD_Firmware}" ]]; then
|
||||
Checked_Type="已是最新"
|
||||
echo "${CLOUD_Firmware} [${Checked_Type}]" > /tmp/cloud_version
|
||||
elif [[ "${LOCAL_Firmware}" -gt "${CLOUD_Firmware}" ]]; then
|
||||
Checked_Type="发现更高版本固件可更新"
|
||||
echo "${CLOUD_Firmware} [${Checked_Type}]" > /tmp/cloud_version
|
||||
elif [[ "${LOCAL_Firmware}" -lt "${CLOUD_Firmware}" ]]; then
|
||||
Checked_Type="云端最高版本固件,低于您现在所安装的版本"
|
||||
echo "${CLOUD_Firmware} [${Checked_Type}]" > /tmp/cloud_version
|
||||
fi
|
||||
else
|
||||
echo "没检测到云端固件,您可能把云端固件删除了,或格式不对称,比如很多虚拟机安装UEIF格式都会变成Legacy引导!" > /tmp/cloud_version
|
||||
fi
|
||||
exit 0
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-autoupdate": {
|
||||
"description": "Grant UCI access for luci-app-autoupdate",
|
||||
"read": {
|
||||
"uci": [ "autoupdate" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "autoupdate" ]
|
||||
}
|
||||
}
|
||||
}
|
2
luci-app-beardropper/.gitattributes
vendored
Normal file
2
luci-app-beardropper/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
2
luci-app-beardropper/.gitignore
vendored
Normal file
2
luci-app-beardropper/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
.DS_Store
|
622
luci-app-beardropper/LICENSE
Normal file
622
luci-app-beardropper/LICENSE
Normal file
@ -0,0 +1,622 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
22
luci-app-beardropper/Makefile
Normal file
22
luci-app-beardropper/Makefile
Normal file
@ -0,0 +1,22 @@
|
||||
#
|
||||
# Copyright (C) 2020 Nate Ding
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_Title:=LuCI Support for BearDropper
|
||||
LUCI_PKGARCH=all
|
||||
|
||||
PKG_VERSION:=1.1
|
||||
PKG_RELEASE:=20200522
|
||||
|
||||
PKG_MAINTANINER:=Nate Ding <natelol@github.com>
|
||||
PKG_LICENSE:=GLPv3
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
59
luci-app-beardropper/README.md
Normal file
59
luci-app-beardropper/README.md
Normal file
@ -0,0 +1,59 @@
|
||||
luci-app-beardropper
|
||||
===
|
||||
|
||||
[Preview][preview]
|
||||
---
|
||||
luci-app-beardropper, a log examination script w/ iptables firewall rule generation response.
|
||||
|
||||
This is the LuCI app built for the elegant firewall rule generation on-the-fly script [bearDropper][bearDropper], only a few modifications were made to work with Luci.
|
||||
|
||||
|
||||
|
||||
Targets/Devices
|
||||
---
|
||||
Written in shell scripts, so it shall work all good on all devices.
|
||||
|
||||
|
||||
Config
|
||||
---
|
||||
The config file path is: `/etc/config/beardropper` and this is the uci configuration format.
|
||||
|
||||
|
||||
|
||||
Compile
|
||||
---
|
||||
RECOMMENDED!!!! (推荐使用右边的feeds---->)You can use [natelol feeds][feeds]
|
||||
|
||||
|
||||
OR
|
||||
|
||||
|
||||
0. Go under `openwrt/`
|
||||
|
||||
1. Make your own local feeds, say a folder `mkdir yourfeeds`
|
||||
|
||||
2. Clone master under feeds to have `git clone https://github.com/natelol/luci-app-beardropper yourefeeds/luci-app-beardropper`
|
||||
|
||||
3. Append `src-link yourfeeds /path/to/openwrt/yourfeeds` in the file `openwrt/feeds.conf(.default)`
|
||||
|
||||
4. Run following scripts under `openwrt`:
|
||||
|
||||
```bash
|
||||
# Update feeds
|
||||
./scripts/feeds update -a
|
||||
./scripts/feeds install -a
|
||||
|
||||
# M select luci-app-beardropper in LuCI -> 3. Applications also 2. Modules->Translations if you want translations together
|
||||
make menuconfig
|
||||
# compile
|
||||
make package/feeds/luci-app-beardropper/compile V=99
|
||||
```
|
||||
|
||||
Logs
|
||||
---
|
||||
`2020-05-21` Added a new tab listing the blocked IPs.
|
||||
|
||||
|
||||
[preview]: https://github.com/natelol/luci-app-beardropper/tree/master/preview
|
||||
[bearDropper]: https://github.com/robzr/bearDropper
|
||||
[feeds]: https://github.com/natelol/natelol
|
19
luci-app-beardropper/luasrc/controller/beardropper.lua
Executable file
19
luci-app-beardropper/luasrc/controller/beardropper.lua
Executable file
@ -0,0 +1,19 @@
|
||||
module("luci.controller.beardropper", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/beardropper") then
|
||||
return
|
||||
end
|
||||
entry({"admin", "services", "beardropper"}, alias("admin", "services", "beardropper", "setting"),_("BearDropper"), 20).dependent = true
|
||||
entry({"admin", "services", "beardropper", "status"}, call("act_status"))
|
||||
entry({"admin", "services", "beardropper", "setting"}, cbi("beardropper/setting"), _("Setting"), 30).leaf= true
|
||||
entry({"admin", "services", "beardropper", "log"}, form("beardropper/log"),_("Log"),40).leaf= true
|
||||
--entry:
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e={}
|
||||
e.running = luci.sys.call("pgrep -f /usr/sbin/beardropper >/dev/null")==0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
17
luci-app-beardropper/luasrc/model/cbi/beardropper/log.lua
Normal file
17
luci-app-beardropper/luasrc/model/cbi/beardropper/log.lua
Normal file
@ -0,0 +1,17 @@
|
||||
f = SimpleForm("logview")
|
||||
f.reset = false
|
||||
f.submit = false
|
||||
t = f:field(TextValue, "conf")
|
||||
t.rmempty = true
|
||||
t.rows = 20
|
||||
function t.cfgvalue()
|
||||
local logs = luci.util.execi("logread | grep authpriv | grep beardropper")
|
||||
local s = ""
|
||||
for line in logs do
|
||||
s = line .. "\n" .. s
|
||||
end
|
||||
return s
|
||||
end
|
||||
t.readonly="readonly"
|
||||
|
||||
return f
|
54
luci-app-beardropper/luasrc/model/cbi/beardropper/setting.lua
Executable file
54
luci-app-beardropper/luasrc/model/cbi/beardropper/setting.lua
Executable file
@ -0,0 +1,54 @@
|
||||
|
||||
m = Map("beardropper", translate("BearDropper"),
|
||||
translate("luci-app-beardropper, the LuCI app built with the elegant firewall rule generation on-the-fly script bearDropper. <br /> <br /> Should you have any questions, please refer to the repo: ")..[[<a href="https://github.com/NateLol/luci-app-bearDropper" target="_blank">luci-app-beardropper</a>]]
|
||||
)
|
||||
m:chain("luci")
|
||||
|
||||
m:section(SimpleSection).template="beardropper/status"
|
||||
|
||||
s = m:section(TypedSection, "beardropper", translate(""))
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
|
||||
-- TABS
|
||||
s:tab("options", translate("Options"))
|
||||
s:tab("blocked", translate("Blocked IP"))
|
||||
|
||||
o = s:taboption("options", Flag, "enabled",translate("Enabled"))
|
||||
o.default = 0
|
||||
|
||||
-- OPTIONS
|
||||
o = s:taboption("options", ListValue, "defaultMode", translate("Running Mode"))
|
||||
o.default = "follow"
|
||||
o:value("follow", translate("Follow"))
|
||||
o:value("entire", translate("Entire"))
|
||||
o:value("today", translate("Today"))
|
||||
o:value("wipe", translate("Wipe"))
|
||||
|
||||
|
||||
o = s:taboption("options", Value, "attemptCount", translate("Attempt Tolerance"), translate("failure attempts from a given IP required to trigger a ban"))
|
||||
|
||||
o = s:taboption("options", Value, "attemptPeriod", translate("Attempt Cycle"), translate("time period during which attemptCount must be exceeded in order to trigger a ban <br> Format: 1w2d3h4m5s represents 1week 2days 3hours 4minutes 5 seconds"))
|
||||
|
||||
o = s:taboption("options", Value, "banLength", translate("Ban Period"), translate("how long a ban exist once the attempt threshold is exceeded"))
|
||||
|
||||
o = s:taboption("options", ListValue, "logLevel", translate("Log Level"))
|
||||
o.default = "1"
|
||||
o:value("0", translate("Silent"))
|
||||
o:value("1", translate("Default"))
|
||||
o:value("2", translate("Verbose"))
|
||||
o:value("3", translate("Debug"))
|
||||
|
||||
|
||||
o = s:taboption("blocked", Value, "blocked", translate("Blocked IP List"))
|
||||
o.template="cbi/tvalue"
|
||||
o.rows=40
|
||||
o.wrap="off"
|
||||
o.readonly="true"
|
||||
function o.cfgvalue(e, e)
|
||||
return luci.sys.exec("cat /tmp/beardropper.bddb | awk /'=1/'| awk -F '=' '{print $1}' | awk '{print substr($0,6)}' | awk 'gsub(/_/,\":\",$0)'")
|
||||
end
|
||||
|
||||
|
||||
|
||||
return m
|
22
luci-app-beardropper/luasrc/view/beardropper/status.htm
Executable file
22
luci-app-beardropper/luasrc/view/beardropper/status.htm
Executable file
@ -0,0 +1,22 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[beardropper]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('beardropper_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
var links = '<em><b><font color=green>BearDropper <%:RUNNING%></font></b></em>';
|
||||
tb.innerHTML = links;
|
||||
} else {
|
||||
tb.innerHTML = '<em><b><font color=red>BearDropper <%:NOT RUNNING%></font></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="beardropper_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
1
luci-app-beardropper/po/zh-cn
Symbolic link
1
luci-app-beardropper/po/zh-cn
Symbolic link
@ -0,0 +1 @@
|
||||
zh_Hans
|
115
luci-app-beardropper/po/zh_Hans/beardropper.po
Executable file
115
luci-app-beardropper/po/zh_Hans/beardropper.po
Executable file
@ -0,0 +1,115 @@
|
||||
bearDropper#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:36
|
||||
msgid "Attempt Cycle"
|
||||
msgstr "尝试登录时间段"
|
||||
|
||||
|
||||
msgid "Setting"
|
||||
msgstr "设置"
|
||||
|
||||
msgid "Log"
|
||||
msgstr "日志"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:34
|
||||
msgid "Attempt Tolerance"
|
||||
msgstr "最大尝试登录次数"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:38
|
||||
msgid "Ban Period"
|
||||
msgstr "封禁IP时长"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/controller/bearDropper.lua:7
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:7
|
||||
msgid "BearDropper"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:20
|
||||
msgid "Blocked IP"
|
||||
msgstr "屏蔽列表"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:52
|
||||
msgid "Blocked IP List"
|
||||
msgstr "已屏蔽IP列表"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:20
|
||||
msgid "Collecting data..."
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:45
|
||||
msgid "Debug"
|
||||
msgstr "调试"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:43
|
||||
msgid "Default"
|
||||
msgstr "默认"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:22
|
||||
msgid "Enabled"
|
||||
msgstr "启用"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:29
|
||||
msgid "Entire"
|
||||
msgstr "已有记录"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:28
|
||||
msgid "Follow"
|
||||
msgstr "后台监控"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:40
|
||||
msgid "Log Level"
|
||||
msgstr "日志等级"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:10
|
||||
msgid "NOT RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:19
|
||||
msgid "Options"
|
||||
msgstr "选项"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:7
|
||||
msgid "RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:26
|
||||
msgid "Running Mode"
|
||||
msgstr "运行模式"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:42
|
||||
msgid "Silent"
|
||||
msgstr "安静"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:30
|
||||
msgid "Today"
|
||||
msgstr "仅今日"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:44
|
||||
msgid "Verbose"
|
||||
msgstr "详细"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:31
|
||||
msgid "Wipe"
|
||||
msgstr "清除所有"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:34
|
||||
msgid "failure attempts from a given IP required to trigger a ban"
|
||||
msgstr "尝试登录超过设定值次数的IP将被封禁"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:38
|
||||
msgid "how long a ban exist once the attempt threshold is exceeded"
|
||||
msgstr "IP将被封禁设定的时间"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:8
|
||||
msgid ""
|
||||
"luci-app-beardropper, the LuCI app built with the elegant firewall rule "
|
||||
"generation on-the-fly script bearDropper. <br /> <br /> Should you have any "
|
||||
"questions, please refer to the repo:"
|
||||
msgstr ""
|
||||
"luci-app-beardropper, 是一款能够在开启公网访问之后对潜在的ssh attack进行防御"
|
||||
"的脚本. <br /> <br /> 如果你在使用中有任何问题,请到项目中提问: "
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:36
|
||||
msgid ""
|
||||
"time period during which attemptCount must be exceeded in order to trigger a "
|
||||
"ban <br> Format: 1w2d3h4m5s represents 1week 2days 3hours 4minutes 5 seconds"
|
||||
msgstr ""
|
||||
"在设定的时间段内连续尝试失败 <br> 格式:1w2d3h4m5s代表1周2天3小时4分5秒"
|
115
luci-app-beardropper/po/zh_Hant/beardropper.po
Normal file
115
luci-app-beardropper/po/zh_Hant/beardropper.po
Normal file
@ -0,0 +1,115 @@
|
||||
bearDropper#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:36
|
||||
msgid "Attempt Cycle"
|
||||
msgstr "嘗試登錄時間段"
|
||||
|
||||
|
||||
msgid "Setting"
|
||||
msgstr "設置"
|
||||
|
||||
msgid "Log"
|
||||
msgstr "日誌"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:34
|
||||
msgid "Attempt Tolerance"
|
||||
msgstr "最大嘗試登錄次數"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:38
|
||||
msgid "Ban Period"
|
||||
msgstr "封禁IP時長"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/controller/bearDropper.lua:7
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:7
|
||||
msgid "BearDropper"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:20
|
||||
msgid "Blocked IP"
|
||||
msgstr "屏蔽列表"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:52
|
||||
msgid "Blocked IP List"
|
||||
msgstr "已屏蔽IP列表"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:20
|
||||
msgid "Collecting data..."
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:45
|
||||
msgid "Debug"
|
||||
msgstr "調試"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:43
|
||||
msgid "Default"
|
||||
msgstr "默認"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:22
|
||||
msgid "Enabled"
|
||||
msgstr "啟用"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:29
|
||||
msgid "Entire"
|
||||
msgstr "已有記錄"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:28
|
||||
msgid "Follow"
|
||||
msgstr "後臺監控"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:40
|
||||
msgid "Log Level"
|
||||
msgstr "日誌等級"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:10
|
||||
msgid "NOT RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:19
|
||||
msgid "Options"
|
||||
msgstr "選項"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:7
|
||||
msgid "RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:26
|
||||
msgid "Running Mode"
|
||||
msgstr "運行模式"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:42
|
||||
msgid "Silent"
|
||||
msgstr "安靜"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:30
|
||||
msgid "Today"
|
||||
msgstr "僅今日"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:44
|
||||
msgid "Verbose"
|
||||
msgstr "詳細"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:31
|
||||
msgid "Wipe"
|
||||
msgstr "清除所有"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:34
|
||||
msgid "failure attempts from a given IP required to trigger a ban"
|
||||
msgstr "嘗試登錄超過設定值次數的IP將被封禁"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:38
|
||||
msgid "how long a ban exist once the attempt threshold is exceeded"
|
||||
msgstr "IP將被封禁設定的時間"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:8
|
||||
msgid ""
|
||||
"luci-app-beardropper, the LuCI app built with the elegant firewall rule "
|
||||
"generation on-the-fly script bearDropper. <br /> <br /> Should you have any "
|
||||
"questions, please refer to the repo:"
|
||||
msgstr ""
|
||||
"luci-app-beardropper, 是壹款能夠在開啟公網訪問之後對潛在的ssh attack進行防禦"
|
||||
"的腳本. <br /> <br /> 如果妳在使用中有任何問題,請到項目中提問: "
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:36
|
||||
msgid ""
|
||||
"time period during which attemptCount must be exceeded in order to trigger a "
|
||||
"ban <br> Format: 1w2d3h4m5s represents 1week 2days 3hours 4minutes 5 seconds"
|
||||
msgstr ""
|
||||
"在設定的時間段內連續嘗試失敗 <br> 格式:1w2d3h4m5s代表1周2天3小時4分5秒"
|
BIN
luci-app-beardropper/preview/1_setting.png
Normal file
BIN
luci-app-beardropper/preview/1_setting.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 111 KiB |
BIN
luci-app-beardropper/preview/2_blockedlist.png
Normal file
BIN
luci-app-beardropper/preview/2_blockedlist.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 124 KiB |
18
luci-app-beardropper/root/etc/config/beardropper
Normal file
18
luci-app-beardropper/root/etc/config/beardropper
Normal file
@ -0,0 +1,18 @@
|
||||
config beardropper
|
||||
option attemptCount '5'
|
||||
option attemptPeriod '12h'
|
||||
option banLength '1w'
|
||||
option logFacility 'authpriv.notice'
|
||||
option fileStateType 'bddb'
|
||||
option fileStateTempPrefix '/tmp/beardropper'
|
||||
option fileStatePersistPrefix '/etc/beardropper'
|
||||
list firewallHookChain 'input_wan_rule:1'
|
||||
list firewallHookChain 'forwarding_wan_rule:1'
|
||||
option firewallTarget 'DROP'
|
||||
list logRegex 's/[`$"\'\'']//g'
|
||||
list logRegex '/has invalid shell, rejected$/d'
|
||||
list logRegex '/^[A-Za-z ]+[0-9: ]+authpriv.warn dropbear\[.+([0-9]+\.){3}[0-9]+/p'
|
||||
list logRegex '/^[A-Za-z ]+[0-9: ]+authpriv.info dropbear\[.+:\ Exit before auth:.*/p'
|
||||
option defaultMode 'follow'
|
||||
option enabled '1'
|
||||
option logLevel '2'
|
46
luci-app-beardropper/root/etc/init.d/beardropper
Executable file
46
luci-app-beardropper/root/etc/init.d/beardropper
Executable file
@ -0,0 +1,46 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
START=98
|
||||
|
||||
PROG=/usr/sbin/beardropper
|
||||
SERVICE_DAEMONIZE=1
|
||||
SERVICE_WRITE_PID=1
|
||||
|
||||
getKids() {
|
||||
egrep "^PPid: *$1$" /proc/[0-9]*/s*s 2>/dev/null | cut -f3 -d/ | xargs echo
|
||||
}
|
||||
|
||||
start() {
|
||||
service_start ${PROG} -m follow
|
||||
echo "beardropper started!"
|
||||
}
|
||||
|
||||
stop() {
|
||||
#PID=`cat /var/run/bearDropper.pid`
|
||||
#kill `getKids $PID`
|
||||
kill -9 `pgrep -f /usr/sbin/beardropper`
|
||||
sleep 1
|
||||
service_stop ${PROG}
|
||||
echo "beardropper exit...."
|
||||
}
|
||||
|
||||
restart() {
|
||||
enabled=$(uci get beardropper.@beardropper[0].enabled)
|
||||
pgrep -f ${PROG} >/dev/null
|
||||
if [ $? -eq 0 ];then #running
|
||||
if [ $enabled -eq 1 ]; then
|
||||
stop
|
||||
sleep 1
|
||||
echo "beardropper is restarting..."
|
||||
start
|
||||
else
|
||||
stop
|
||||
fi
|
||||
else
|
||||
if [ $enabled -eq 1 ]; then
|
||||
start
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
11
luci-app-beardropper/root/etc/uci-defaults/luci-beardropper
Normal file
11
luci-app-beardropper/root/etc/uci-defaults/luci-beardropper
Normal file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@beardropper[-1]
|
||||
add ucitrack beardropper
|
||||
set ucitrack.@beardropper[-1].init=beardropper
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -rf /tmp/luci-*
|
||||
exit 0
|
517
luci-app-beardropper/root/usr/sbin/beardropper
Executable file
517
luci-app-beardropper/root/usr/sbin/beardropper
Executable file
@ -0,0 +1,517 @@
|
||||
#!/bin/ash
|
||||
#
|
||||
# beardropper - dropbear log parsing ban agent for OpenWRT (Chaos Calmer rewrite of dropBrute.sh)
|
||||
# http://github.com/robzr/bearDropper -- Rob Zwissler 11/2015
|
||||
#
|
||||
# - lightweight, no dependencies, busybox ash + native OpenWRT commands
|
||||
# - uses uci for configuration, overrideable via command line arguments
|
||||
# - runs continuously in background (via init script) or periodically (via cron)
|
||||
# - uses BIND time shorthand, ex: 1w5d3h1m8s is 1 week, 5 days, 3 hours, 1 minute, 8 seconds
|
||||
# - Whitelist IP or CIDR entries (TBD) in uci config file
|
||||
# - Records state file to tmpfs and intelligently syncs to persistent storage (can disable)
|
||||
# - Persistent sync routines are optimized to avoid excessive writes (persistentStateWritePeriod)
|
||||
# - Every run occurs in one of the following modes. If not specified, interval mode (24 hours) is
|
||||
# the default when not specified (the init script specifies follow mode via command line)
|
||||
#
|
||||
# "follow" mode follows syslog to process entries as they happen; generally launched via init
|
||||
# script. Responds the fastest, runs the most efficiently, but is always in memory.
|
||||
# "interval" mode only processes entries going back the specified interval; requires
|
||||
# more processing than today mode, but responds more accurately. Use with cron.
|
||||
# "today" mode looks at log entries from the day it is being run, simple and lightweight,
|
||||
# generally run from cron periodically (same simplistic behavior as dropBrute.sh)
|
||||
# "entire" mode runs through entire contents of the syslog ring buffer
|
||||
# "wipe" mode tears down the firewall rules and removes the state files
|
||||
|
||||
# Load UCI config variable, or use default if not set
|
||||
# Args: $1 = variable name (also uci option name), $2 = default_value
|
||||
uciSection='beardropper.@[0]'
|
||||
uciLoadVar () {
|
||||
local getUci
|
||||
getUci=`uci -q get ${uciSection}."$1"` || getUci="$2"
|
||||
eval $1=\'$getUci\';
|
||||
}
|
||||
uciLoad() {
|
||||
local tFile=`mktemp` delim="
|
||||
"
|
||||
[ "$1" = -d ] && { delim="$2"; shift 2; }
|
||||
uci -q -d"$delim" get "$uciSection.$1" 2>/dev/null >$tFile
|
||||
if [ $? = 0 ] ; then
|
||||
sed -e s/^\'// -e s/\'$// <$tFile
|
||||
else
|
||||
while [ -n "$2" ]; do echo $2; shift; done
|
||||
fi
|
||||
rm -f $tFile
|
||||
}
|
||||
|
||||
# Common config variables - edit these in /etc/config/beardropper
|
||||
# or they can be overridden at runtime with command line options
|
||||
#
|
||||
uciLoadVar defaultMode entire
|
||||
uciLoadVar enabled 0
|
||||
uciLoadVar attemptCount 10
|
||||
uciLoadVar attemptPeriod 12h
|
||||
uciLoadVar banLength 1w
|
||||
uciLoadVar logLevel 1
|
||||
uciLoadVar logFacility authpriv.notice
|
||||
uciLoadVar persistentStateWritePeriod -1
|
||||
uciLoadVar fileStateType bddb
|
||||
uciLoadVar fileStateTempPrefix /tmp/beardropper
|
||||
uciLoadVar fileStatePersistPrefix /etc/beardropper
|
||||
firewallHookChains="`uciLoad -d \ firewallHookChain input_wan_rule:1 forwarding_wan_rule:1`"
|
||||
uciLoadVar firewallTarget DROP
|
||||
|
||||
# Not commonly changed, but changeable via uci or cmdline (primarily
|
||||
# to enable multiple parallel runs with different parameters)
|
||||
uciLoadVar firewallChain beardropper
|
||||
|
||||
# Advanced variables, changeable via uci only (no cmdline), it is
|
||||
# unlikely that these will need to be changed, but just in case...
|
||||
#
|
||||
uciLoadVar syslogTag "beardropper[$$]"
|
||||
# how often to attempt to expire bans when in follow mode
|
||||
uciLoadVar followModeCheckInterval 30m
|
||||
uciLoadVar cmdLogread 'logread' # for tuning, ex: "logread -l250"
|
||||
uciLoadVar cmdLogreadEba 'logread' # for "Exit before auth:" backscanning
|
||||
uciLoadVar formatLogDate '%b %e %H:%M:%S %Y' # used to convert syslog dates
|
||||
uciLoadVar formatTodayLogDateRegex '^%a %b %e ..:..:.. %Y' # filter for today mode
|
||||
|
||||
# Begin functions
|
||||
#
|
||||
# Clear bddb entries from environment
|
||||
bddbClear () {
|
||||
local bddbVar
|
||||
for bddbVar in `set | egrep '^bddb_[0-9_]*=' | cut -f1 -d= | xargs echo -n` ; do eval unset $bddbVar ; done
|
||||
bddbStateChange=1
|
||||
}
|
||||
|
||||
# Returns count of unique IP entries in environment
|
||||
bddbCount () { set | egrep '^bddb_[0-9_]*=' | wc -l ; }
|
||||
|
||||
# Loads existing bddb file into environment
|
||||
# Arg: $1 = file, $2 = type (bddb/bddbz), $3 =
|
||||
bddbLoad () {
|
||||
local loadFile="$1.$2" fileType="$2"
|
||||
if [ "$fileType" = bddb -a -f "$loadFile" ] ; then
|
||||
. "$loadFile"
|
||||
elif [ "$fileType" = bddbz -a -f "$loadFile" ] ; then
|
||||
local tmpFile="`mktemp`"
|
||||
zcat $loadFile > "$tmpFile"
|
||||
. "$tmpFile"
|
||||
rm -f "$tmpFile"
|
||||
fi
|
||||
bddbStateChange=0
|
||||
}
|
||||
|
||||
# Saves environment bddb entries to file, Arg: $1 = file to save in
|
||||
bddbSave () {
|
||||
local saveFile="$1.$2" fileType="$2"
|
||||
if [ "$fileType" = bddb ] ; then
|
||||
set | egrep '^bddb_[0-9_]*=' | sed s/\'//g > "$saveFile"
|
||||
elif [ "$fileType" = bddbz ] ; then
|
||||
set | egrep '^bddb_[0-9_]*=' | sed s/\'//g | gzip -c > "$saveFile"
|
||||
fi
|
||||
bddbStateChange=0
|
||||
}
|
||||
|
||||
# Set bddb record status=1, update ban time flag with newest
|
||||
# Args: $1=IP Address $2=timeFlag
|
||||
bddbEnableStatus () {
|
||||
local record=`echo $1 | sed -e 's/\./_/g' -e 's/^/bddb_/'`
|
||||
local newestTime=`bddbGetTimes $1 | sed 's/.* //' | xargs echo $2 | tr \ '\n' | sort -n | tail -1 `
|
||||
eval $record="1,$newestTime"
|
||||
bddbStateChange=1
|
||||
}
|
||||
|
||||
# Args: $1=IP Address
|
||||
bddbGetStatus () {
|
||||
bddbGetRecord $1 | cut -d, -f1
|
||||
}
|
||||
|
||||
# Args: $1=IP Address
|
||||
bddbGetTimes () {
|
||||
bddbGetRecord $1 | cut -d, -f2-
|
||||
}
|
||||
|
||||
# Args: $1 = IP address, $2 [$3 ...] = timestamp (seconds since epoch)
|
||||
bddbAddRecord () {
|
||||
local ip="`echo "$1" | tr . _`" ; shift
|
||||
local newEpochList="$@" status="`eval echo \\\$bddb_$ip | cut -f1 -d,`"
|
||||
local oldEpochList="`eval echo \\\$bddb_$ip | cut -f2- -d, | tr , \ `"
|
||||
local epochList=`echo $oldEpochList $newEpochList | xargs -n 1 echo | sort -un | xargs echo -n | tr \ ,`
|
||||
[ -z "$status" ] && status=0
|
||||
eval "bddb_$ip"\=\"$status,$epochList\"
|
||||
bddbStateChange=1
|
||||
}
|
||||
|
||||
# Args: $1 = IP address
|
||||
bddbRemoveRecord () {
|
||||
local ip="`echo "$1" | tr . _`"
|
||||
eval unset bddb_$ip
|
||||
bddbStateChange=1
|
||||
}
|
||||
|
||||
# Returns all IPs (not CIDR) present in records
|
||||
bddbGetAllIPs () {
|
||||
local ipRaw record
|
||||
set | egrep '^bddb_[0-9_]*=' | tr \' \ | while read record ; do
|
||||
ipRaw=`echo $record | cut -f1 -d= | sed 's/^bddb_//'`
|
||||
if [ `echo $ipRaw | tr _ \ | wc -w` -eq 4 ] ; then
|
||||
echo $ipRaw | tr _ .
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# retrieve single IP record, Args: $1=IP
|
||||
bddbGetRecord () {
|
||||
local record
|
||||
record=`echo $1 | sed -e 's/\./_/g' -e 's/^/bddb_/'`
|
||||
eval echo \$$record
|
||||
}
|
||||
|
||||
isValidBindTime () { echo "$1" | egrep -q '^[0-9]+$|^([0-9]+[wdhms]?)+$' ; }
|
||||
|
||||
# expands Bind time syntax into seconds (ex: 3w6d23h59m59s), Arg: $1=time string
|
||||
expandBindTime () {
|
||||
isValidBindTime "$1" || { logLine 0 "Error: Invalid time specified ($1)" >&2 ; exit 254 ; }
|
||||
echo $((`echo "$1" | sed -e 's/w+*/*7d+/g' -e 's/d+*/*24h+/g' -e 's/h+*/*60m+/g' -e 's/m+*/*60+/g' \
|
||||
-e s/s//g -e s/+\$//`))
|
||||
}
|
||||
|
||||
# Args: $1 = loglevel, $2 = info to log
|
||||
logLine () {
|
||||
[ $1 -gt $logLevel ] && return
|
||||
shift
|
||||
if [ "$logFacility" = "stdout" ] ; then echo "$@"
|
||||
elif [ "$logFacility" = "stderr" ] ; then echo "$@" >&2
|
||||
else logger -t "$syslogTag" -p "$logFacility" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# extra validation, fails safe. Args: $1=log line
|
||||
getLogTime () {
|
||||
local logDateString=`echo "$1" | sed -n \
|
||||
's/^[A-Z][a-z]* \([A-Z][a-z]* *[0-9][0-9]* *[0-9][0-9]*:[0-9][0-9]:[0-9][0-9] [0-9][0-9]*\) .*$/\1/p'`
|
||||
date -d"$logDateString" -D"$formatLogDate" +%s || logLine 1 \
|
||||
"Error: logDateString($logDateString) malformed line ($1)"
|
||||
}
|
||||
|
||||
# extra validation, fails safe. Args: $1=log line
|
||||
getLogIP () {
|
||||
local logLine="$1"
|
||||
local ebaPID=`echo "$logLine" | sed -n 's/^.*authpriv.info \(dropbear\[[0-9]*\]:\) Exit before auth:.*/\1/p'`
|
||||
[ -n "$ebaPID" ] && logLine=`$cmdLogreadEba | fgrep "${ebaPID} Child connection from "`
|
||||
echo "$logLine" | sed -n 's/^.*[^0-9]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/p'
|
||||
}
|
||||
|
||||
# Args: $1=IP
|
||||
unBanIP () {
|
||||
if iptables -C $firewallChain -s $ip -j "$firewallTarget" 2>/dev/null ; then
|
||||
logLine 1 "Removing ban rule for IP $ip from iptables"
|
||||
iptables -D $firewallChain -s $ip -j "$firewallTarget"
|
||||
else
|
||||
logLine 3 "unBanIP() Ban rule for $ip not present in iptables"
|
||||
fi
|
||||
}
|
||||
|
||||
# Args: $1=IP
|
||||
banIP () {
|
||||
local ip="$1" x chain position
|
||||
if ! iptables -nL $firewallChain >/dev/null 2>/dev/null ; then
|
||||
logLine 1 "Creating iptables chain $firewallChain"
|
||||
iptables -N $firewallChain
|
||||
fi
|
||||
for x in $firewallHookChains ; do
|
||||
chain="${x%:*}" ; position="${x#*:}"
|
||||
if [ $position -ge 0 ] && ! iptables -C $chain -j $firewallChain 2>/dev/null ; then
|
||||
logLine 1 "Inserting hook into iptables chain $chain"
|
||||
if [ $position = 0 ] ; then
|
||||
iptables -A $chain -j $firewallChain
|
||||
else
|
||||
iptables -I $chain $position -j $firewallChain
|
||||
fi ; fi
|
||||
done
|
||||
if ! iptables -C $firewallChain -s $ip -j "$firewallTarget" 2>/dev/null ; then
|
||||
logLine 1 "Inserting ban rule for IP $ip into iptables chain $firewallChain"
|
||||
iptables -A $firewallChain -s $ip -j "$firewallTarget"
|
||||
else
|
||||
logLine 3 "banIP() rule for $ip already present in iptables chain"
|
||||
fi
|
||||
}
|
||||
|
||||
wipeFirewall () {
|
||||
local x chain position
|
||||
for x in $firewallHookChains ; do
|
||||
chain="${x%:*}" ; position="${x#*:}"
|
||||
if [ $position -ge 0 ] ; then
|
||||
if iptables -C $chain -j $firewallChain 2>/dev/null ; then
|
||||
logLine 1 "Removing hook from iptables chain $chain"
|
||||
iptables -D $chain -j $firewallChain
|
||||
fi ; fi
|
||||
done
|
||||
if iptables -nL $firewallChain >/dev/null 2>/dev/null ; then
|
||||
logLine 1 "Flushing and removing iptables chain $firewallChain"
|
||||
iptables -F $firewallChain 2>/dev/null
|
||||
iptables -X $firewallChain 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
# review state file for expired records - we could add the bantime to
|
||||
# the rule via --comment but I can't think of a reason why that would
|
||||
# be necessary unless there is a bug in the expiration logic. The
|
||||
# state db should be more resiliant than the firewall in practice.
|
||||
#
|
||||
bddbCheckStatusAll () {
|
||||
local now=`date +%s`
|
||||
bddbGetAllIPs | while read ip ; do
|
||||
if [ `bddbGetStatus $ip` -eq 1 ] ; then
|
||||
logLine 3 "bddbCheckStatusAll($ip) testing banLength:$banLength + bddbGetTimes:`bddbGetTimes $ip` vs. now:$now"
|
||||
if [ $((banLength + `bddbGetTimes $ip`)) -lt $now ] ; then
|
||||
logLine 1 "Ban expired for $ip, removing from iptables"
|
||||
unBanIP $ip
|
||||
bddbRemoveRecord $ip
|
||||
else
|
||||
logLine 3 "bddbCheckStatusAll($ip) not expired yet"
|
||||
banIP $ip
|
||||
fi
|
||||
elif [ `bddbGetStatus $ip` -eq 0 ] ; then
|
||||
local times=`bddbGetTimes $ip | tr , \ `
|
||||
local timeCount=`echo $times | wc -w`
|
||||
local lastTime=`echo $times | cut -d\ -f$timeCount`
|
||||
if [ $((lastTime + attemptPeriod)) -lt $now ] ; then
|
||||
bddbRemoveRecord $ip
|
||||
fi ; fi
|
||||
saveState
|
||||
done
|
||||
loadState
|
||||
}
|
||||
|
||||
# Only used when status is already 0 and possibly going to 1, Args: $1=IP
|
||||
bddbEvaluateRecord () {
|
||||
local ip=$1 firstTime lastTime
|
||||
local times=`bddbGetRecord $1 | cut -d, -f2- | tr , \ `
|
||||
local timeCount=`echo $times | wc -w`
|
||||
local didBan=0
|
||||
|
||||
# 1: not enough attempts => do nothing and exit
|
||||
# 2: attempts exceed threshold in time period => ban
|
||||
# 3: attempts exceed threshold but time period is too long => trim oldest time, recalculate
|
||||
while [ $timeCount -ge $attemptCount ] ; do
|
||||
firstTime=`echo $times | cut -d\ -f1`
|
||||
lastTime=`echo $times | cut -d\ -f$timeCount`
|
||||
timeDiff=$((lastTime - firstTime))
|
||||
logLine 3 "bddbEvaluateRecord($ip) count=$timeCount timeDiff=$timeDiff/$attemptPeriod"
|
||||
if [ $timeDiff -le $attemptPeriod ] ; then
|
||||
bddbEnableStatus $ip $lastTime
|
||||
logLine 2 "bddbEvaluateRecord($ip) exceeded ban threshold, adding to iptables"
|
||||
banIP $ip
|
||||
didBan=1
|
||||
fi
|
||||
times=`echo $times | cut -d\ -f2-`
|
||||
timeCount=`echo $times | wc -w`
|
||||
done
|
||||
[ $didBan = 0 ] && logLine 2 "bddbEvaluateRecord($ip) does not exceed threshhold, skipping"
|
||||
}
|
||||
|
||||
# Reads filtered log line and evaluates for action Args: $1=log line
|
||||
processLogLine () {
|
||||
local time=`getLogTime "$1"`
|
||||
local ip=`getLogIP "$1"`
|
||||
local status="`bddbGetStatus $ip`"
|
||||
|
||||
if [ "$status" = -1 ] ; then
|
||||
logLine 2 "processLogLine($ip,$time) IP is whitelisted"
|
||||
elif [ "$status" = 1 ] ; then
|
||||
if [ "`bddbGetTimes $ip`" -ge $time ] ; then
|
||||
logLine 2 "processLogLine($ip,$time) already banned, ban timestamp already equal or newer"
|
||||
else
|
||||
logLine 2 "processLogLine($ip,$time) already banned, updating ban timestamp"
|
||||
bddbEnableStatus $ip $time
|
||||
fi
|
||||
banIP $ip
|
||||
elif [ -n "$ip" -a -n "$time" ] ; then
|
||||
bddbAddRecord $ip $time
|
||||
logLine 2 "processLogLine($ip,$time) Added record, comparing"
|
||||
bddbEvaluateRecord $ip
|
||||
else
|
||||
logLine 1 "processLogLine($ip,$time) malformed line ($1)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Args, $1=-f to force a persistent write (unless lastPersistentStateWrite=-1)
|
||||
saveState () {
|
||||
local forcePersistent=0
|
||||
[ "$1" = "-f" ] && forcePersistent=1
|
||||
|
||||
if [ $bddbStateChange -gt 0 ] ; then
|
||||
logLine 3 "saveState() saving to temp state file"
|
||||
bddbSave "$fileStateTempPrefix" "$fileStateType"
|
||||
logLine 3 "saveState() now=`date +%s` lPSW=$lastPersistentStateWrite pSWP=$persistentStateWritePeriod fP=$forcePersistent"
|
||||
fi
|
||||
if [ $persistentStateWritePeriod -gt 1 ] || [ $persistentStateWritePeriod -eq 0 -a $forcePersistent -eq 1 ] ; then
|
||||
if [ $((`date +%s` - lastPersistentStateWrite)) -ge $persistentStateWritePeriod ] || [ $forcePersistent -eq 1 ] ; then
|
||||
if [ ! -f "$fileStatePersist" ] || ! cmp -s "$fileStateTemp" "$fileStatePersist" ; then
|
||||
logLine 2 "saveState() writing to persistent state file"
|
||||
bddbSave "$fileStatePersistPrefix" "$fileStateType"
|
||||
lastPersistentStateWrite="`date +%s`"
|
||||
fi ; fi ; fi
|
||||
}
|
||||
|
||||
loadState () {
|
||||
bddbClear
|
||||
bddbLoad "$fileStatePersistPrefix" "$fileStateType"
|
||||
bddbLoad "$fileStateTempPrefix" "$fileStateType"
|
||||
logLine 2 "loadState() loaded `bddbCount` entries"
|
||||
}
|
||||
|
||||
printUsage () {
|
||||
cat <<-_EOF_
|
||||
Usage: beardropper [-m mode] [-a #] [-b #] [-c ...] [-C ...] [-f ...] [-l #] [-j ...] [-p #] [-P #] [-s ...]
|
||||
|
||||
Running Modes (-m) (def: $defaultMode)
|
||||
follow constantly monitors log
|
||||
entire processes entire log contents
|
||||
today processes log entries from same day only
|
||||
# interval mode, specify time string or seconds
|
||||
wipe wipe state files, unhook and remove firewall chain
|
||||
|
||||
Options
|
||||
-a # attempt count before banning (def: $attemptCount)
|
||||
-b # ban length once attempts hit threshold (def: $banLength)
|
||||
-c ... firewall chain to record bans (def: $firewallChain)
|
||||
-C ... firewall chains/positions to hook into (def: $firewallHookChains)
|
||||
-f ... log facility (syslog facility or stdout/stderr) (def: $logFacility)
|
||||
-j ... firewall target (def: $firewallTarget)
|
||||
-l # log level - 0=off, 1=standard, 2=verbose (def: $logLevel)
|
||||
-p # attempt period which attempt counts must happen in (def: $attemptPeriod)
|
||||
-P # persistent state file write period (def: $persistentStateWritePeriod)
|
||||
-s ... persistent state file prefix (def: $fileStatePersistPrefix)
|
||||
-t ... temporary state file prefix (def: $fileStateTempPrefix)
|
||||
|
||||
All time strings can be specified in seconds, or using BIND style
|
||||
time strings, ex: 1w2d3h5m30s is 1 week, 2 days, 3 hours, etc...
|
||||
|
||||
_EOF_
|
||||
}
|
||||
|
||||
# Begin main logic
|
||||
#
|
||||
unset logMode
|
||||
while getopts a:b:c:C:f:hj:l:m:p:P:s:t: arg ; do
|
||||
case "$arg" in
|
||||
a) attemptCount="$OPTARG" ;;
|
||||
b) banLength="$OPTARG" ;;
|
||||
c) firewallChain="$OPTARG" ;;
|
||||
C) firewallHookChains="$OPTARG" ;;
|
||||
f) logFacility="$OPTARG" ;;
|
||||
j) firewallTarget="$OPTARG" ;;
|
||||
l) logLevel="$OPTARG" ;;
|
||||
m) logMode="$OPTARG" ;;
|
||||
p) attemptPeriod="$OPTARG" ;;
|
||||
P) persistentStateWritePeriod="$OPTARG" ;;
|
||||
s) fileStatePersistPrefix="$OPTARG" ;;
|
||||
s) fileStatePersistPrefix="$OPTARG" ;;
|
||||
*) printUsage
|
||||
exit 254
|
||||
esac
|
||||
shift `expr $OPTIND - 1`
|
||||
done
|
||||
[ -z $logMode ] && logMode="$defaultMode"
|
||||
|
||||
fileStateTemp="$fileStateTempPrefix.$fileStateType"
|
||||
fileStatePersist="$fileStatePersistPrefix.$fileStateType"
|
||||
|
||||
attemptPeriod=`expandBindTime $attemptPeriod`
|
||||
banLength=`expandBindTime $banLength`
|
||||
[ $persistentStateWritePeriod != -1 ] && persistentStateWritePeriod=`expandBindTime $persistentStateWritePeriod`
|
||||
followModeCheckInterval=`expandBindTime $followModeCheckInterval`
|
||||
exitStatus=0
|
||||
|
||||
# Here we convert the logRegex list into a sed -f file
|
||||
fileRegex="/tmp/beardropper.$$.regex"
|
||||
uciLoad logRegex 's/[`$"'\\\'']//g' '/has invalid shell, rejected$/d' \
|
||||
'/^[A-Za-z ]+[0-9: ]+authpriv.warn dropbear\[.+([0-9]+\.){3}[0-9]+/p' \
|
||||
'/^[A-Za-z ]+[0-9: ]+authpriv.info dropbear\[.+:\ Exit before auth:.*/p' > "$fileRegex"
|
||||
lastPersistentStateWrite="`date +%s`"
|
||||
loadState
|
||||
bddbCheckStatusAll
|
||||
|
||||
# main event loops
|
||||
|
||||
if [ "$logMode" = follow ] ; then
|
||||
logLine 1 "Running in follow mode"
|
||||
readsSinceSave=0 lastCheckAll=0 worstCaseReads=1 tmpFile="/tmp/beardropper.$$.1"
|
||||
# Verify if these do any good - try saving to a temp. Scope may make saveState useless.
|
||||
trap "rm -f "$tmpFile" "$fileRegex" ; exit " SIGINT
|
||||
[ $persistentStateWritePeriod -gt 1 ] && worstCaseReads=$((persistentStateWritePeriod / followModeCheckInterval))
|
||||
firstRun=1
|
||||
$cmdLogread -f | while read -t $followModeCheckInterval line || true ; do
|
||||
if [ $firstRun -eq 1 ] ; then
|
||||
trap "saveState -f" SIGHUP
|
||||
trap "saveState -f; exit" SIGINT
|
||||
firstRun=0
|
||||
fi
|
||||
sed -nEf "$fileRegex" > "$tmpFile" <<-_EOF_
|
||||
$line
|
||||
_EOF_
|
||||
line="`cat $tmpFile`"
|
||||
[ -n "$line" ] && processLogLine "$line"
|
||||
logLine 3 "ReadComp:$readsSinceSave/$worstCaseReads"
|
||||
if [ $((++readsSinceSave)) -ge $worstCaseReads ] ; then
|
||||
now="`date +%s`"
|
||||
if [ $((now - lastCheckAll)) -ge $followModeCheckInterval ] ; then
|
||||
bddbCheckStatusAll
|
||||
lastCheckAll="$now"
|
||||
saveState
|
||||
readsSinceSave=0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
elif [ "$logMode" = entire ] ; then
|
||||
logLine 1 "Running in entire mode"
|
||||
$cmdLogread | sed -nEf "$fileRegex" | while read line ; do
|
||||
processLogLine "$line"
|
||||
saveState
|
||||
done
|
||||
loadState
|
||||
bddbCheckStatusAll
|
||||
saveState -f
|
||||
elif [ "$logMode" = today ] ; then
|
||||
logLine 1 "Running in today mode"
|
||||
# merge the egrep into sed with -e /^$formatTodayLogDateRegex/!d
|
||||
$cmdLogread | egrep "`date +\'$formatTodayLogDateRegex\'`" | sed -nEf "$fileRegex" | while read line ; do
|
||||
processLogLine "$line"
|
||||
saveState
|
||||
done
|
||||
loadState
|
||||
bddbCheckStatusAll
|
||||
saveState -f
|
||||
elif isValidBindTime "$logMode" ; then
|
||||
logInterval=`expandBindTime $logMode`
|
||||
logLine 1 "Running in interval mode (reviewing $logInterval seconds of log entries)..."
|
||||
timeStart=$((`date +%s` - logInterval))
|
||||
$cmdLogread | sed -nEf "$fileRegex" | while read line ; do
|
||||
timeWhen=`getLogTime "$line"`
|
||||
[ $timeWhen -ge $timeStart ] && processLogLine "$line"
|
||||
saveState
|
||||
done
|
||||
loadState
|
||||
bddbCheckStatusAll
|
||||
saveState -f
|
||||
elif [ "$logMode" = wipe ] ; then
|
||||
logLine 2 "Wiping state files, unhooking and removing iptables chains"
|
||||
wipeFirewall
|
||||
if [ -f "$fileStateTemp" ] ; then
|
||||
logLine 1 "Removing non-persistent statefile ($fileStateTemp)"
|
||||
rm -f "$fileStateTemp"
|
||||
fi
|
||||
if [ -f "$fileStatePersist" ] ; then
|
||||
logLine 1 "Removing persistent statefile ($fileStatePersist)"
|
||||
rm -f "$fileStatePersist"
|
||||
fi
|
||||
else
|
||||
logLine 0 "Error: invalid log mode ($logMode)"
|
||||
exitStatus=254
|
||||
fi
|
||||
|
||||
rm -f "$fileRegex"
|
||||
exit $exitStatus
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user