mirror of
https://github.com/kenzok8/small-package
synced 2025-01-07 09:16:47 +08:00
update 2023-01-26 20:19:28
This commit is contained in:
parent
38030555cd
commit
afe81772b2
21
luci-app-aliddns/LICENSE
Normal file
21
luci-app-aliddns/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 chenhw2
|
||||
|
||||
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.
|
@ -1,24 +1,84 @@
|
||||
#
|
||||
# Copyright (C) 2018 chenhw2 <https://github.com/chenhw2/>
|
||||
# Copyright (C) 2018-2021 chenhw2 <https://github.com/chenhw2/>
|
||||
#
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI Support for aliddns
|
||||
LUCI_DESCRIPTION:=LuCI Support for ALiDDNS.
|
||||
LUCI_DEPENDS:=+openssl-util +curl
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_NAME:=luci-app-aliddns
|
||||
PKG_VERSION:=0.3.0
|
||||
PKG_VERSION:=0.4.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
PKG_MAINTAINER:=chenhw2 <https://github.com/chenhw2/>
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/luci-app-aliddns
|
||||
SECTION:=luci
|
||||
CATEGORY:=LuCI
|
||||
SUBMENU:=3. Applications
|
||||
TITLE:=LuCI Support for aliddns
|
||||
PKGARCH:=all
|
||||
DEPENDS:=+openssl-util +curl
|
||||
endef
|
||||
|
||||
define Package/luci-app-aliddns/description
|
||||
LuCI Support for ALiDDNS.
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
$(foreach po,$(wildcard ${CURDIR}/files/luci/i18n/*.po), \
|
||||
po2lmo $(po) $(PKG_BUILD_DIR)/$(patsubst %.po,%.lmo,$(notdir $(po)));)
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/luci-app-aliddns/postinst
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
if [ -f /etc/uci-defaults/luci-aliddns ]; then
|
||||
( . /etc/uci-defaults/luci-aliddns ) && \
|
||||
rm -f /etc/uci-defaults/luci-aliddns
|
||||
fi
|
||||
rm -rf /tmp/luci-indexcache /tmp/luci-modulecache
|
||||
fi
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Package/luci-app-aliddns/prerm
|
||||
#!/bin/sh
|
||||
/etc/init.d/aliddns stop
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Package/luci-app-aliddns/conffiles
|
||||
/etc/config/aliddns
|
||||
endef
|
||||
|
||||
define Package/luci-app-aliddns/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/aliddns.*.lmo $(1)/usr/lib/lua/luci/i18n/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller
|
||||
$(INSTALL_DATA) ./files/luci/controller/*.lua $(1)/usr/lib/lua/luci/controller/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/aliddns
|
||||
$(INSTALL_DATA) ./files/luci/model/cbi/*.lua $(1)/usr/lib/lua/luci/model/cbi/
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_DATA) ./files/root/etc/config/aliddns $(1)/etc/config/aliddns
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/root/etc/init.d/aliddns $(1)/etc/init.d/aliddns
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_BIN) ./files/root/etc/uci-defaults/luci-aliddns $(1)/etc/uci-defaults/luci-aliddns
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) ./files/root/usr/sbin/aliddns $(1)/usr/sbin/aliddns
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,luci-app-aliddns))
|
||||
|
68
luci-app-aliddns/README.md
Normal file
68
luci-app-aliddns/README.md
Normal file
@ -0,0 +1,68 @@
|
||||
# luci-app-aliddns
|
||||
LEDE/OpenWrt LuCI for AliDDNS
|
||||
===
|
||||
|
||||
简介
|
||||
---
|
||||
|
||||
本软件包是 AliDDNS 的 LuCI 控制界面,
|
||||
|
||||
软件包文件结构:
|
||||
```
|
||||
/
|
||||
├── etc/
|
||||
│ ├── config/
|
||||
│ │ └── aliddns // UCI 配置文件
|
||||
│ │── init.d/
|
||||
│ │ └── aliddns // init 脚本
|
||||
│ └── uci-defaults/
|
||||
│ └── luci-aliddns // uci-defaults 脚本
|
||||
└── usr/
|
||||
├── sbin/
|
||||
│ └── aliddns // 主程序
|
||||
└── lib/
|
||||
└── lua/
|
||||
└── luci/ // LuCI 部分
|
||||
├── controller/
|
||||
│ └── aliddns.lua // LuCI 菜单配置
|
||||
├── i18n/ // LuCI 语言文件目录
|
||||
│ └── aliddns.zh-cn.lmo
|
||||
└── model/
|
||||
└── cbi/
|
||||
└── aliddns.lua // LuCI 基本设置
|
||||
```
|
||||
|
||||
依赖
|
||||
---
|
||||
|
||||
软件包的正常使用需要依赖 `openssl-util` 和 `curl`.
|
||||
|
||||
配置
|
||||
---
|
||||
|
||||
软件包的配置文件路径: `/etc/config/aliddns`
|
||||
此文件为 UCI 配置文件, 配置方式可参考 [Wiki][uci]
|
||||
|
||||
编译
|
||||
---
|
||||
|
||||
从 LEDE 的 [SDK][lede-sdk] 编译
|
||||
```bash
|
||||
# 解压下载好的 SDK
|
||||
tar axvf lede-sdk-17.01.*-ar71xx-generic_gcc-5.4.0_musl-1.1.16.Linux-x86_64.tar.xz
|
||||
cd lede-sdk-17.01.*-ar71xx-*
|
||||
# Clone 项目
|
||||
mkdir -p package/feeds
|
||||
git clone https://github.com/chenhw2/luci-app-aliddns.git package/feeds/luci-app-aliddns
|
||||
# 编译 po2lmo (如果有po2lmo可跳过)
|
||||
pushd package/feeds/luci-app-aliddns/tools/po2lmo
|
||||
make && sudo make install
|
||||
popd
|
||||
# 选择要编译的包 LuCI -> 3. Applications
|
||||
make menuconfig
|
||||
# 开始编译
|
||||
make package/feeds/luci-app-aliddns/compile V=s
|
||||
```
|
||||
|
||||
[lede-sdk]: https://lede-project.org/docs/guide-developer/compile_packages_for_lede_with_the_sdk
|
||||
[uci]: https://lede-project.org/docs/user-guide/introduction_to_lede_configuration
|
4
luci-app-aliddns/files/luci/controller/aliddns.lua
Normal file
4
luci-app-aliddns/files/luci/controller/aliddns.lua
Normal file
@ -0,0 +1,4 @@
|
||||
module("luci.controller.aliddns",package.seeall)
|
||||
function index()
|
||||
entry({"admin","services","aliddns"},cbi("aliddns"),_("AliDDNS"),58)
|
||||
end
|
@ -10,6 +10,9 @@ msgstr "启用"
|
||||
msgid "Clean Before Update"
|
||||
msgstr "清除所有同名记录"
|
||||
|
||||
msgid "Enabled IPv6"
|
||||
msgstr "启用 IPv6"
|
||||
|
||||
msgid "Base"
|
||||
msgstr "基本设置"
|
||||
|
||||
@ -22,6 +25,15 @@ msgstr "选择WAN-IP来源"
|
||||
msgid "Select the WAN-IP Source for AliDDNS, like wan/internet"
|
||||
msgstr "动态域名的IP来源,如wan/internet"
|
||||
|
||||
msgid "WAN6-IP Source"
|
||||
msgstr "WAN6-IP来源"
|
||||
|
||||
msgid "Select WAN6-IP Source"
|
||||
msgstr "选择WAN6-IP来源"
|
||||
|
||||
msgid "Select the WAN6-IP Source for AliDDNS, like wan6/internet"
|
||||
msgstr "动态域名的IPv6来源,如wan6/internet"
|
||||
|
||||
msgid "Main Domain"
|
||||
msgstr "主域名"
|
||||
|
@ -15,19 +15,32 @@ enable.rmempty = false
|
||||
enable = e:option(Flag, "clean", translate("Clean Before Update"))
|
||||
enable.rmempty = false
|
||||
|
||||
ipv6 = e:option(Flag,"ipv6",translate("Enabled IPv6"))
|
||||
ipv6.rmempty=false
|
||||
|
||||
token = e:option(Value, "app_key", translate("Access Key ID"))
|
||||
|
||||
email = e:option(Value, "app_secret", translate("Access Key Secret"))
|
||||
|
||||
iface = e:option(ListValue, "interface", translate("WAN-IP Source"), translate("Select the WAN-IP Source for AliDDNS, like wan/internet"))
|
||||
iface:value("", translate("Select WAN-IP Source"))
|
||||
iface:value("internet")
|
||||
iface:value("wan")
|
||||
|
||||
iface.rmempty = false
|
||||
|
||||
iface6 = e:option(ListValue, "interface6", translate("WAN6-IP Source"),translate("Select the WAN6-IP Source for AliDDNS, like wan6/internet"))
|
||||
iface6:value("",translate("Select WAN6-IP Source"))
|
||||
iface6:value("internet")
|
||||
iface6:value("wan")
|
||||
iface6:value("wan6")
|
||||
iface6.rmempty = true
|
||||
|
||||
main = e:option(Value, "main_domain", translate("Main Domain"), translate("For example: test.github.com -> github.com"))
|
||||
main.rmempty = false
|
||||
|
||||
sub = e:option(Value, "sub_domain", translate("Sub Domain"), translate("For example: test.github.com -> test"))
|
||||
sub.rmempty = false
|
||||
|
||||
time = e:option(Value, "time", translate("Inspection Time"), translate("Unit: Minute, Range: 1-59"))
|
||||
time.rmempty = false
|
||||
|
||||
@ -49,6 +62,7 @@ end
|
||||
|
||||
tvlog.write = function(e,e,e)
|
||||
end
|
||||
|
||||
local e = luci.http.formvalue("cbi.apply")
|
||||
if e then
|
||||
io.popen("/etc/init.d/aliddns restart")
|
18
luci-app-aliddns/root/etc/init.d/aliddns → luci-app-aliddns/files/root/etc/init.d/aliddns
Executable file → Normal file
18
luci-app-aliddns/root/etc/init.d/aliddns → luci-app-aliddns/files/root/etc/init.d/aliddns
Executable file → Normal file
@ -2,6 +2,8 @@
|
||||
|
||||
START=80
|
||||
NAME=aliddns
|
||||
EXTRA_COMMANDS="status"
|
||||
EXTRA_HELP=" status Service status"
|
||||
|
||||
NE_TIPS='AliDDNS NOT ENABLED'
|
||||
|
||||
@ -51,7 +53,9 @@ start() {
|
||||
[ -f /etc/crontabs/root ] || mkdir -p /etc/crontabs && touch /etc/crontabs/root
|
||||
sed -i '/aliddns/d' /etc/crontabs/root
|
||||
echo "*/$time * * * * /usr/sbin/aliddns >> /var/log/aliddns.log 2>&1" >> /etc/crontabs/root
|
||||
/etc/init.d/cron restart
|
||||
if [ "$(/etc/init.d/cron status)" = "running" ]; then
|
||||
/etc/init.d/cron reload
|
||||
fi
|
||||
|
||||
( /usr/sbin/aliddns >> /var/log/aliddns.log 2>&1 ) &
|
||||
}
|
||||
@ -59,6 +63,16 @@ start() {
|
||||
stop() {
|
||||
rm -rf "/etc/hotplug.d/iface/${START}-${NAME}"
|
||||
sed -i '/aliddns/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
/etc/init.d/cron restart
|
||||
if [ "$(/etc/init.d/cron status)" = "running" ]; then
|
||||
/etc/init.d/cron reload
|
||||
fi
|
||||
echo "${NE_TIPS}" > /var/log/aliddns.log
|
||||
}
|
||||
|
||||
status() {
|
||||
if [ "$(/etc/init.d/cron status)" != "running" ]; then
|
||||
echo "inactive" && false
|
||||
else
|
||||
grep -q aliddns /etc/crontabs/root && echo "running" || echo "inactive" && false
|
||||
fi
|
||||
}
|
0
luci-app-aliddns/root/etc/uci-defaults/luci-aliddns → luci-app-aliddns/files/root/etc/uci-defaults/luci-aliddns
Executable file → Normal file
0
luci-app-aliddns/root/etc/uci-defaults/luci-aliddns → luci-app-aliddns/files/root/etc/uci-defaults/luci-aliddns
Executable file → Normal file
283
luci-app-aliddns/files/root/usr/sbin/aliddns
Executable file
283
luci-app-aliddns/files/root/usr/sbin/aliddns
Executable file
@ -0,0 +1,283 @@
|
||||
#!/bin/sh
|
||||
|
||||
NAME=aliddns
|
||||
log_file=/var/log/$NAME.log
|
||||
|
||||
uci_get_by_name() {
|
||||
local ret=$(uci get $NAME.$1.$2 2>/dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
|
||||
uci_bool_by_name() {
|
||||
case "$(uci_get_by_name $1 $2)" in
|
||||
1|on|true|yes|enabled) return 0;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
intelnetip() {
|
||||
tmp_ip=`curl -sL --connect-timeout 3 members.3322.org/dyndns/getip`
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`curl -sL --connect-timeout 3 api-ipv4.ip.sb/ip`
|
||||
fi
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`curl -sL --connect-timeout 3 v4.myip.la`
|
||||
fi
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`curl -sL --connect-timeout 3 whatismyip.akamai.com`
|
||||
fi
|
||||
echo -n $tmp_ip
|
||||
}
|
||||
|
||||
intelnetip6() {
|
||||
tmp_ip6=`curl -sL --connect-timeout 3 ipv6.whatismyip.akamai.com`
|
||||
if [ "Z$tmp_ip6" == "Z" ]; then
|
||||
tmp_ip6=`curl -sL --connect-timeout 3 speed.neu6.edu.cn/getIP.php`
|
||||
fi
|
||||
if [ "Z$tmp_ip6" == "Z" ]; then
|
||||
tmp_ip6=`curl -sL --connect-timeout 3 v6.ident.me`
|
||||
fi
|
||||
if [ "Z$tmp_ip6" == "Z" ]; then
|
||||
tmp_ip6=`curl -sL --connect-timeout 3 api-ipv6.ip.sb/ip`
|
||||
fi
|
||||
echo -n $tmp_ip6
|
||||
}
|
||||
|
||||
resolve2ip() {
|
||||
# resolve2ip domain<string>
|
||||
domain=$1
|
||||
tmp_ip=`nslookup $domain ns1.alidns.com 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -n1`
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`nslookup $domain ns2.alidns.com 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -n1`
|
||||
fi
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`nslookup $domain 114.114.115.115 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -n1`
|
||||
fi
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`curl -sL --connect-timeout 3 "119.29.29.29/d?dn=$domain"`
|
||||
fi
|
||||
echo -n $tmp_ip
|
||||
}
|
||||
|
||||
resolve2ip6() {
|
||||
# resolve2ip6 domain<string>
|
||||
domain=$1
|
||||
tmp_ip6=`nslookup $domain ns1.alidns.com 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{1,4}$|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4})' | tail -n1`
|
||||
if [ "Z$tmp_ip6" == "Z" ]; then
|
||||
tmp_ip6=`nslookup $domain ns2.alidns.com 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{1,4}$|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4})' | tail -n1`
|
||||
fi
|
||||
if [ "Z$tmp_ip6" == "Z" ]; then
|
||||
tmp_ip6=`nslookup $domain 114.114.115.115 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{1,4}$|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4})' | tail -n1`
|
||||
fi
|
||||
if [ "Z$tmp_ip6" == "Z" ]; then
|
||||
tmp_ip6=`curl -sL --connect-timeout 3 "119.29.29.29/d?dn=$domain&type=AAAA"`
|
||||
fi
|
||||
echo -n $tmp_ip6
|
||||
}
|
||||
|
||||
check_aliddns() {
|
||||
echo "$DATE WAN-IP: ${ip}"
|
||||
if [ "Z$ip" == "Z" ]; then
|
||||
echo "$DATE ERROR, cant get WAN-IP..."
|
||||
return 0
|
||||
fi
|
||||
current_ip=$(resolve2ip "$dm_real")
|
||||
if [ "Z$current_ip" == "Z" ]; then
|
||||
rrid='' # NO Resolve IP Means new Record_ID
|
||||
fi
|
||||
echo "$DATE DOMAIN-IP: ${current_ip}"
|
||||
if [ "Z$ip" == "Z$current_ip" ]; then
|
||||
echo "$DATE IP dont need UPDATE..."
|
||||
return 0
|
||||
else
|
||||
echo "$DATE UPDATING..."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_aliddns6() {
|
||||
echo "$DATE WAN6-IP: ${ip6}"
|
||||
if [ "Z$ip6" == "Z" ]; then
|
||||
echo "$DATE ERROR, cant get WAN6-IP..."
|
||||
return 0
|
||||
fi
|
||||
current_ip6=$(resolve2ip6 "$dm_real")
|
||||
if [ "Z$current_ip6" == "Z" ]; then
|
||||
rrid6='' # NO Resolve IP Means new Record_ID
|
||||
fi
|
||||
echo "$DATE DOMAIN-IP6: ${current_ip6}"
|
||||
if [ "Z$ip6" == "Z$current_ip6" ]; then
|
||||
echo "$DATE IPv6 dont need UPDATE..."
|
||||
return 0
|
||||
else
|
||||
echo "$DATE UPDATING AAAA..."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
urlencode() {
|
||||
# urlencode url<string>
|
||||
out=''
|
||||
for c in $(echo -n $1 | sed 's/[^\n]/&\n/g'); do
|
||||
case $c in
|
||||
[a-zA-Z0-9._-]) out="$out$c" ;;
|
||||
*) out="$out$(printf '%%%02X' "'$c")" ;;
|
||||
esac
|
||||
done
|
||||
echo -n $out
|
||||
}
|
||||
|
||||
send_request() {
|
||||
# send_request action<string> args<string>
|
||||
local args="AccessKeyId=$ak_id&Action=$1&Format=json&$2&Version=2015-01-09"
|
||||
local hash=$(urlencode $(echo -n "GET&%2F&$(urlencode $args)" | openssl dgst -sha1 -hmac "$ak_sec&" -binary | openssl base64))
|
||||
curl -sSL --connect-timeout 10 "http://alidns.aliyuncs.com/?$args&Signature=$hash"
|
||||
}
|
||||
|
||||
get_recordid() {
|
||||
sed 's/RR/\n/g' | sed -n 's/.*RecordId[^0-9]*\([0-9]*\).*/\1\n/p' | sort -ru | sed /^$/d
|
||||
}
|
||||
|
||||
query_recordid() {
|
||||
send_request "DescribeSubDomainRecords" "SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&SubDomain=$dm_escape&Timestamp=$timestamp&Type=A"
|
||||
}
|
||||
|
||||
query_recordid6() {
|
||||
send_request "DescribeSubDomainRecords" "SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&SubDomain=$dm_escape&Timestamp=$timestamp&Type=AAAA"
|
||||
}
|
||||
|
||||
update_record() {
|
||||
send_request "UpdateDomainRecord" "RR=$sub_dm_escape&RecordId=$1&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp&Type=A&Value=$ip"
|
||||
}
|
||||
|
||||
add_record() {
|
||||
send_request "AddDomainRecord&DomainName=$main_dm" "RR=$sub_dm_escape&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp&Type=A&Value=$ip"
|
||||
}
|
||||
|
||||
update_record6() {
|
||||
send_request "UpdateDomainRecord" "RR=$sub_dm_escape&RecordId=$1&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp&Type=AAAA&Value=$ip6_escape"
|
||||
}
|
||||
|
||||
add_record6() {
|
||||
send_request "AddDomainRecord&DomainName=$main_dm" "RR=$sub_dm_escape&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp&Type=AAAA&Value=$ip6_escape"
|
||||
}
|
||||
|
||||
del_record() {
|
||||
send_request "DeleteDomainRecord" "RecordId=$1&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp"
|
||||
}
|
||||
|
||||
do_ddns_record() {
|
||||
if uci_bool_by_name base clean ; then
|
||||
query_recordid | get_recordid | while read rr; do
|
||||
echo "$DATE Clean record $dm_show: $rr"
|
||||
del_record $rr >/dev/null
|
||||
timestamp=$(date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ")
|
||||
done
|
||||
rrid=''
|
||||
fi
|
||||
if [ "Z$rrid" == "Z" ]; then
|
||||
rrid=`query_recordid | get_recordid`
|
||||
fi
|
||||
if [ "Z$rrid" == "Z" ]; then
|
||||
rrid=`add_record | get_recordid`
|
||||
echo "$DATE ADD record $rrid"
|
||||
else
|
||||
update_record $rrid >/dev/null 2>&1
|
||||
echo "$DATE UPDATE record $rrid"
|
||||
fi
|
||||
if [ "Z$rrid" == "Z" ]; then
|
||||
# failed
|
||||
echo "$DATE # ERROR, Please Check Config/Time"
|
||||
else
|
||||
# save rrid
|
||||
uci set aliddns.base.record_id=$rrid
|
||||
uci commit aliddns
|
||||
echo "$DATE # UPDATED($ip)"
|
||||
fi
|
||||
}
|
||||
|
||||
do_ddns_record6() {
|
||||
if uci_bool_by_name base clean ; then
|
||||
query_recordid6 | get_recordid | while read rr; do
|
||||
echo "$DATE Clean record $dm_show: $rr"
|
||||
del_record $rr >/dev/null
|
||||
timestamp=$(date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ")
|
||||
done
|
||||
rrid6=''
|
||||
fi
|
||||
if [ "Z$rrid6" == "Z" ]; then
|
||||
rrid6=`query_recordid6 | get_recordid`
|
||||
fi
|
||||
if [ "Z$rrid6" == "Z" ]; then
|
||||
rrid6=`add_record6 | get_recordid`
|
||||
echo "$DATE ADD record $rrid6"
|
||||
else
|
||||
update_record6 $rrid6 >/dev/null 2>&1
|
||||
echo "$DATE UPDATE record $rrid6"
|
||||
fi
|
||||
if [ "Z$rrid6" == "Z" ]; then
|
||||
# failed
|
||||
echo "$DATE # ERROR, Please Check Config/Time"
|
||||
else
|
||||
# save rrid6
|
||||
uci set aliddns.base.record_id6=$rrid6
|
||||
uci commit aliddns
|
||||
echo "$DATE # UPDATED($ip6)"
|
||||
fi
|
||||
}
|
||||
|
||||
clean_log() {
|
||||
if [ $(cat $log_file 2>/dev/null | wc -l) -ge 16 ]; then
|
||||
rm -f $log_file && touch $log_file
|
||||
echo "$DATE Log Cleaned"
|
||||
fi
|
||||
}
|
||||
|
||||
[ -x /usr/bin/openssl -a -x /usr/bin/curl -a -x /bin/sed ] || {
|
||||
echo "Need [ openssl + curl + sed ]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
ak_id=$(uci_get_by_name base app_key)
|
||||
ak_sec=$(uci_get_by_name base app_secret)
|
||||
rrid=$(uci_get_by_name base record_id)
|
||||
rrid6=$(uci_get_by_name base record_id6)
|
||||
main_dm=$(uci_get_by_name base main_domain)
|
||||
sub_dm=$(uci_get_by_name base sub_domain)
|
||||
|
||||
if [ "Z$sub_dm" == "Z@" -o "Z$sub_dm" == "Z" ]; then
|
||||
dm_real="$main_dm"
|
||||
else
|
||||
dm_real="$sub_dm.$main_dm"
|
||||
fi
|
||||
dm_show="$sub_dm.$main_dm"
|
||||
dm_escape=`urlencode "$sub_dm.$main_dm"`
|
||||
sub_dm_escape=`urlencode "$sub_dm"`
|
||||
|
||||
iface=$(uci_get_by_name base interface)
|
||||
if [ "Z$iface" == "Zinternet" -o "Z$iface" == "Z" ]; then
|
||||
ip=$(intelnetip)
|
||||
else
|
||||
ip=$(ubus call network.interface.$iface status | grep '"address"' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1)
|
||||
fi
|
||||
|
||||
DATE=$(date +'%Y-%m-%d %H:%M:%S')
|
||||
timestamp=$(date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ")
|
||||
|
||||
clean_log
|
||||
check_aliddns || do_ddns_record
|
||||
|
||||
# exit if ipv6 not-enabled
|
||||
uci_bool_by_name base ipv6 || exit 0
|
||||
|
||||
iface6=$(uci_get_by_name base interface6)
|
||||
if [ "Z$iface6" == "Zinternet" -o "Z$iface6" == "Z" ]; then
|
||||
ip6=$(intelnetip6)
|
||||
else
|
||||
ip6=$(ubus call network.interface.$iface6 status | grep '"address"' | grep -oE '([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){4})' | head -1)
|
||||
fi
|
||||
ip6_escape=`urlencode "$ip6"`
|
||||
|
||||
clean_log
|
||||
check_aliddns6 || do_ddns_record6
|
@ -1,11 +0,0 @@
|
||||
module("luci.controller.aliddns", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/aliddns") then
|
||||
return
|
||||
end
|
||||
|
||||
local page = entry({"admin", "services", "aliddns"}, cbi("aliddns"), _("AliDDNS"), 58)
|
||||
page.dependent = true
|
||||
page.acl_depends = { "luci-app-aliddns" }
|
||||
end
|
@ -1 +0,0 @@
|
||||
zh_Hans
|
@ -1,164 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
NAME=aliddns
|
||||
log_file=/var/log/$NAME.log
|
||||
|
||||
uci_get_by_name() {
|
||||
local ret=$(uci get $NAME.$1.$2 2>/dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
|
||||
uci_bool_by_name() {
|
||||
case "$(uci_get_by_name $1 $2)" in
|
||||
1|on|true|yes|enabled) return 0;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
intelnetip() {
|
||||
tmp_ip=`curl -sL --connect-timeout 3 ns1.dnspod.net:6666`
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`curl -sL --connect-timeout 3 members.3322.org/dyndns/getip`
|
||||
fi
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`curl -sL --connect-timeout 3 14.215.150.17:6666`
|
||||
fi
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`curl -sL --connect-timeout 3 whatismyip.akamai.com`
|
||||
fi
|
||||
echo -n $tmp_ip
|
||||
}
|
||||
|
||||
resolve2ip() {
|
||||
# resolve2ip domain<string>
|
||||
domain=$1
|
||||
tmp_ip=`nslookup $domain ns1.alidns.com 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -n1`
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`nslookup $domain ns2.alidns.com 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -n1`
|
||||
fi
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`nslookup $domain 114.114.115.115 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -n1`
|
||||
fi
|
||||
if [ "Z$tmp_ip" == "Z" ]; then
|
||||
tmp_ip=`curl -sL --connect-timeout 3 "119.29.29.29/d?dn=$domain"`
|
||||
fi
|
||||
echo -n $tmp_ip
|
||||
}
|
||||
|
||||
check_aliddns() {
|
||||
echo "$DATE WAN-IP: ${ip}"
|
||||
if [ "Z$ip" == "Z" ]; then
|
||||
echo "$DATE ERROR, cant get WAN-IP..."
|
||||
return 0
|
||||
fi
|
||||
current_ip=$(resolve2ip "$sub_dm.$main_dm")
|
||||
if [ "Z$current_ip" == "Z" ]; then
|
||||
rrid='' # NO Resolve IP Means new Record_ID
|
||||
fi
|
||||
echo "$DATE DOMAIN-IP: ${current_ip}"
|
||||
if [ "Z$ip" == "Z$current_ip" ]; then
|
||||
echo "$DATE IP dont need UPDATE..."
|
||||
return 0
|
||||
else
|
||||
echo "$DATE UPDATING..."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
urlencode() {
|
||||
# urlencode url<string>
|
||||
out=''
|
||||
for c in $(echo -n $1 | sed 's/[^\n]/&\n/g'); do
|
||||
case $c in
|
||||
[a-zA-Z0-9._-]) out="$out$c" ;;
|
||||
*) out="$out$(printf '%%%02X' "'$c")" ;;
|
||||
esac
|
||||
done
|
||||
echo -n $out
|
||||
}
|
||||
|
||||
send_request() {
|
||||
# send_request action<string> args<string>
|
||||
local args="AccessKeyId=$ak_id&Action=$1&Format=json&$2&Version=2015-01-09"
|
||||
local hash=$(urlencode $(echo -n "GET&%2F&$(urlencode $args)" | openssl dgst -sha1 -hmac "$ak_sec&" -binary | openssl base64))
|
||||
curl -sSL --connect-timeout 5 "http://alidns.aliyuncs.com/?$args&Signature=$hash"
|
||||
}
|
||||
|
||||
get_recordid() {
|
||||
sed 's/RR/\n/g' | sed -n 's/.*RecordId[^0-9]*\([0-9]*\).*/\1\n/p' | sort -ru | sed /^$/d
|
||||
}
|
||||
|
||||
query_recordid() {
|
||||
send_request "DescribeSubDomainRecords" "SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&SubDomain=$sub_dm.$main_dm&Timestamp=$timestamp"
|
||||
}
|
||||
|
||||
update_record() {
|
||||
send_request "UpdateDomainRecord" "RR=$sub_dm&RecordId=$1&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp&Type=A&Value=$ip"
|
||||
}
|
||||
|
||||
add_record() {
|
||||
send_request "AddDomainRecord&DomainName=$main_dm" "RR=$sub_dm&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp&Type=A&Value=$ip"
|
||||
}
|
||||
|
||||
del_record() {
|
||||
send_request "DeleteDomainRecord" "RecordId=$1&SignatureMethod=HMAC-SHA1&SignatureNonce=$timestamp&SignatureVersion=1.0&Timestamp=$timestamp"
|
||||
}
|
||||
|
||||
do_ddns_record() {
|
||||
if uci_bool_by_name base clean ; then
|
||||
query_recordid | get_recordid | while read rr; do
|
||||
echo "$DATE Clean record $sub_dm.$main_dm: $rr"
|
||||
del_record $rr >/dev/null
|
||||
timestamp=$(date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ")
|
||||
done
|
||||
rrid=''
|
||||
fi
|
||||
if [ "Z$rrid" == "Z" ]; then
|
||||
rrid=`query_recordid | get_recordid`
|
||||
fi
|
||||
if [ "Z$rrid" == "Z" ]; then
|
||||
rrid=`add_record | get_recordid`
|
||||
echo "$DATE ADD record $rrid"
|
||||
else
|
||||
update_record $rrid >/dev/null 2>&1
|
||||
echo "$DATE UPDATE record $rrid"
|
||||
fi
|
||||
if [ "Z$rrid" == "Z" ]; then
|
||||
# failed
|
||||
echo "$DATE # ERROR, Please Check Config/Time"
|
||||
else
|
||||
# save rrid
|
||||
uci set aliddns.base.record_id=$rrid
|
||||
uci commit aliddns
|
||||
echo "$DATE # UPDATED($ip)"
|
||||
fi
|
||||
}
|
||||
|
||||
clean_log() {
|
||||
if [ $(cat $log_file 2>/dev/null | wc -l) -ge 16 ]; then
|
||||
rm -f $log_file && touch $log_file
|
||||
echo "$DATE Log Cleaned"
|
||||
fi
|
||||
}
|
||||
|
||||
[ -x /usr/bin/openssl -a -x /usr/bin/curl -a -x /bin/sed ] ||
|
||||
( echo "Need [ openssl + curl + sed ]" && exit 1 )
|
||||
|
||||
ak_id=$(uci_get_by_name base app_key)
|
||||
ak_sec=$(uci_get_by_name base app_secret)
|
||||
rrid=$(uci_get_by_name base record_id)
|
||||
main_dm=$(uci_get_by_name base main_domain)
|
||||
sub_dm=$(uci_get_by_name base sub_domain)
|
||||
|
||||
iface=$(uci_get_by_name base interface)
|
||||
if [ "Z$iface" == "Zinternet" -o "Z$iface" == "Z" ]; then
|
||||
ip=$(intelnetip)
|
||||
else
|
||||
ip=$(ubus call network.interface.$iface status | grep '"address"' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
|
||||
fi
|
||||
|
||||
DATE=$(date +'%Y-%m-%d %H:%M:%S')
|
||||
timestamp=$(date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ")
|
||||
|
||||
clean_log
|
||||
check_aliddns || do_ddns_record
|
@ -1,11 +0,0 @@
|
||||
{
|
||||
"luci-app-aliddns": {
|
||||
"description": "Grant UCI access for luci-app-aliddns",
|
||||
"read": {
|
||||
"uci": [ "aliddns" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "aliddns" ]
|
||||
}
|
||||
}
|
||||
}
|
12
luci-app-aliddns/tools/po2lmo/Makefile
Normal file
12
luci-app-aliddns/tools/po2lmo/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
INSTALL = install
|
||||
PREFIX = /usr/bin
|
||||
|
||||
po2lmo: src/po2lmo.o src/template_lmo.o
|
||||
$(CC) $(LDFLAGS) -o src/po2lmo src/po2lmo.o src/template_lmo.o
|
||||
|
||||
install:
|
||||
$(INSTALL) -m 755 src/po2lmo $(PREFIX)
|
||||
|
||||
clean:
|
||||
$(RM) src/po2lmo src/*.o
|
247
luci-app-aliddns/tools/po2lmo/src/po2lmo.c
Normal file
247
luci-app-aliddns/tools/po2lmo/src/po2lmo.c
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* lmo - Lua Machine Objects - PO to LMO conversion tool
|
||||
*
|
||||
* Copyright (C) 2009-2012 Jo-Philipp Wich <xm@subsignal.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "template_lmo.h"
|
||||
|
||||
static void die(const char *msg)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void usage(const char *name)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s input.po output.lmo\n", name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void print(const void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
if( fwrite(ptr, size, nmemb, stream) == 0 )
|
||||
die("Failed to write stdout");
|
||||
}
|
||||
|
||||
static int extract_string(const char *src, char *dest, int len)
|
||||
{
|
||||
int pos = 0;
|
||||
int esc = 0;
|
||||
int off = -1;
|
||||
|
||||
for( pos = 0; (pos < strlen(src)) && (pos < len); pos++ )
|
||||
{
|
||||
if( (off == -1) && (src[pos] == '"') )
|
||||
{
|
||||
off = pos + 1;
|
||||
}
|
||||
else if( off >= 0 )
|
||||
{
|
||||
if( esc == 1 )
|
||||
{
|
||||
switch (src[pos])
|
||||
{
|
||||
case '"':
|
||||
case '\\':
|
||||
off++;
|
||||
break;
|
||||
}
|
||||
dest[pos-off] = src[pos];
|
||||
esc = 0;
|
||||
}
|
||||
else if( src[pos] == '\\' )
|
||||
{
|
||||
dest[pos-off] = src[pos];
|
||||
esc = 1;
|
||||
}
|
||||
else if( src[pos] != '"' )
|
||||
{
|
||||
dest[pos-off] = src[pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
dest[pos-off] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (off > -1) ? strlen(dest) : -1;
|
||||
}
|
||||
|
||||
static int cmp_index(const void *a, const void *b)
|
||||
{
|
||||
uint32_t x = ((const lmo_entry_t *)a)->key_id;
|
||||
uint32_t y = ((const lmo_entry_t *)b)->key_id;
|
||||
|
||||
if (x < y)
|
||||
return -1;
|
||||
else if (x > y)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_uint32(uint32_t x, FILE *out)
|
||||
{
|
||||
uint32_t y = htonl(x);
|
||||
print(&y, sizeof(uint32_t), 1, out);
|
||||
}
|
||||
|
||||
static void print_index(void *array, int n, FILE *out)
|
||||
{
|
||||
lmo_entry_t *e;
|
||||
|
||||
qsort(array, n, sizeof(*e), cmp_index);
|
||||
|
||||
for (e = array; n > 0; n--, e++)
|
||||
{
|
||||
print_uint32(e->key_id, out);
|
||||
print_uint32(e->val_id, out);
|
||||
print_uint32(e->offset, out);
|
||||
print_uint32(e->length, out);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char line[4096];
|
||||
char key[4096];
|
||||
char val[4096];
|
||||
char tmp[4096];
|
||||
int state = 0;
|
||||
int offset = 0;
|
||||
int length = 0;
|
||||
int n_entries = 0;
|
||||
void *array = NULL;
|
||||
lmo_entry_t *entry = NULL;
|
||||
uint32_t key_id, val_id;
|
||||
|
||||
FILE *in;
|
||||
FILE *out;
|
||||
|
||||
if( (argc != 3) || ((in = fopen(argv[1], "r")) == NULL) || ((out = fopen(argv[2], "w")) == NULL) )
|
||||
usage(argv[0]);
|
||||
|
||||
memset(line, 0, sizeof(key));
|
||||
memset(key, 0, sizeof(val));
|
||||
memset(val, 0, sizeof(val));
|
||||
|
||||
while( (NULL != fgets(line, sizeof(line), in)) || (state >= 2 && feof(in)) )
|
||||
{
|
||||
if( state == 0 && strstr(line, "msgid \"") == line )
|
||||
{
|
||||
switch(extract_string(line, key, sizeof(key)))
|
||||
{
|
||||
case -1:
|
||||
die("Syntax error in msgid");
|
||||
case 0:
|
||||
state = 1;
|
||||
break;
|
||||
default:
|
||||
state = 2;
|
||||
}
|
||||
}
|
||||
else if( state == 1 || state == 2 )
|
||||
{
|
||||
if( strstr(line, "msgstr \"") == line || state == 2 )
|
||||
{
|
||||
switch(extract_string(line, val, sizeof(val)))
|
||||
{
|
||||
case -1:
|
||||
state = 4;
|
||||
break;
|
||||
default:
|
||||
state = 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(extract_string(line, tmp, sizeof(tmp)))
|
||||
{
|
||||
case -1:
|
||||
state = 2;
|
||||
break;
|
||||
default:
|
||||
strcat(key, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( state == 3 )
|
||||
{
|
||||
switch(extract_string(line, tmp, sizeof(tmp)))
|
||||
{
|
||||
case -1:
|
||||
state = 4;
|
||||
break;
|
||||
default:
|
||||
strcat(val, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if( state == 4 )
|
||||
{
|
||||
if( strlen(key) > 0 && strlen(val) > 0 )
|
||||
{
|
||||
key_id = sfh_hash(key, strlen(key));
|
||||
val_id = sfh_hash(val, strlen(val));
|
||||
|
||||
if( key_id != val_id )
|
||||
{
|
||||
n_entries++;
|
||||
array = realloc(array, n_entries * sizeof(lmo_entry_t));
|
||||
entry = (lmo_entry_t *)array + n_entries - 1;
|
||||
|
||||
if (!array)
|
||||
die("Out of memory");
|
||||
|
||||
entry->key_id = key_id;
|
||||
entry->val_id = val_id;
|
||||
entry->offset = offset;
|
||||
entry->length = strlen(val);
|
||||
|
||||
length = strlen(val) + ((4 - (strlen(val) % 4)) % 4);
|
||||
|
||||
print(val, length, 1, out);
|
||||
offset += length;
|
||||
}
|
||||
}
|
||||
|
||||
state = 0;
|
||||
memset(key, 0, sizeof(key));
|
||||
memset(val, 0, sizeof(val));
|
||||
}
|
||||
|
||||
memset(line, 0, sizeof(line));
|
||||
}
|
||||
|
||||
print_index(array, n_entries, out);
|
||||
|
||||
if( offset > 0 )
|
||||
{
|
||||
print_uint32(offset, out);
|
||||
fsync(fileno(out));
|
||||
fclose(out);
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(out);
|
||||
unlink(argv[2]);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
return(0);
|
||||
}
|
328
luci-app-aliddns/tools/po2lmo/src/template_lmo.c
Normal file
328
luci-app-aliddns/tools/po2lmo/src/template_lmo.c
Normal file
@ -0,0 +1,328 @@
|
||||
/*
|
||||
* lmo - Lua Machine Objects - Base functions
|
||||
*
|
||||
* Copyright (C) 2009-2010 Jo-Philipp Wich <xm@subsignal.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "template_lmo.h"
|
||||
|
||||
/*
|
||||
* Hash function from http://www.azillionmonkeys.com/qed/hash.html
|
||||
* Copyright (C) 2004-2008 by Paul Hsieh
|
||||
*/
|
||||
|
||||
uint32_t sfh_hash(const char *data, int len)
|
||||
{
|
||||
uint32_t hash = len, tmp;
|
||||
int rem;
|
||||
|
||||
if (len <= 0 || data == NULL) return 0;
|
||||
|
||||
rem = len & 3;
|
||||
len >>= 2;
|
||||
|
||||
/* Main loop */
|
||||
for (;len > 0; len--) {
|
||||
hash += sfh_get16(data);
|
||||
tmp = (sfh_get16(data+2) << 11) ^ hash;
|
||||
hash = (hash << 16) ^ tmp;
|
||||
data += 2*sizeof(uint16_t);
|
||||
hash += hash >> 11;
|
||||
}
|
||||
|
||||
/* Handle end cases */
|
||||
switch (rem) {
|
||||
case 3: hash += sfh_get16(data);
|
||||
hash ^= hash << 16;
|
||||
hash ^= data[sizeof(uint16_t)] << 18;
|
||||
hash += hash >> 11;
|
||||
break;
|
||||
case 2: hash += sfh_get16(data);
|
||||
hash ^= hash << 11;
|
||||
hash += hash >> 17;
|
||||
break;
|
||||
case 1: hash += *data;
|
||||
hash ^= hash << 10;
|
||||
hash += hash >> 1;
|
||||
}
|
||||
|
||||
/* Force "avalanching" of final 127 bits */
|
||||
hash ^= hash << 3;
|
||||
hash += hash >> 5;
|
||||
hash ^= hash << 4;
|
||||
hash += hash >> 17;
|
||||
hash ^= hash << 25;
|
||||
hash += hash >> 6;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
uint32_t lmo_canon_hash(const char *str, int len)
|
||||
{
|
||||
char res[4096];
|
||||
char *ptr, prev;
|
||||
int off;
|
||||
|
||||
if (!str || len >= sizeof(res))
|
||||
return 0;
|
||||
|
||||
for (prev = ' ', ptr = res, off = 0; off < len; prev = *str, off++, str++)
|
||||
{
|
||||
if (isspace(*str))
|
||||
{
|
||||
if (!isspace(prev))
|
||||
*ptr++ = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr++ = *str;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ptr > res) && isspace(*(ptr-1)))
|
||||
ptr--;
|
||||
|
||||
return sfh_hash(res, ptr - res);
|
||||
}
|
||||
|
||||
lmo_archive_t * lmo_open(const char *file)
|
||||
{
|
||||
int in = -1;
|
||||
uint32_t idx_offset = 0;
|
||||
struct stat s;
|
||||
|
||||
lmo_archive_t *ar = NULL;
|
||||
|
||||
if (stat(file, &s) == -1)
|
||||
goto err;
|
||||
|
||||
if ((in = open(file, O_RDONLY)) == -1)
|
||||
goto err;
|
||||
|
||||
if ((ar = (lmo_archive_t *)malloc(sizeof(*ar))) != NULL)
|
||||
{
|
||||
memset(ar, 0, sizeof(*ar));
|
||||
|
||||
ar->fd = in;
|
||||
ar->size = s.st_size;
|
||||
|
||||
fcntl(ar->fd, F_SETFD, fcntl(ar->fd, F_GETFD) | FD_CLOEXEC);
|
||||
|
||||
if ((ar->mmap = mmap(NULL, ar->size, PROT_READ, MAP_SHARED, ar->fd, 0)) == MAP_FAILED)
|
||||
goto err;
|
||||
|
||||
idx_offset = ntohl(*((const uint32_t *)
|
||||
(ar->mmap + ar->size - sizeof(uint32_t))));
|
||||
|
||||
if (idx_offset >= ar->size)
|
||||
goto err;
|
||||
|
||||
ar->index = (lmo_entry_t *)(ar->mmap + idx_offset);
|
||||
ar->length = (ar->size - idx_offset - sizeof(uint32_t)) / sizeof(lmo_entry_t);
|
||||
ar->end = ar->mmap + ar->size;
|
||||
|
||||
return ar;
|
||||
}
|
||||
|
||||
err:
|
||||
if (in > -1)
|
||||
close(in);
|
||||
|
||||
if (ar != NULL)
|
||||
{
|
||||
if ((ar->mmap != NULL) && (ar->mmap != MAP_FAILED))
|
||||
munmap(ar->mmap, ar->size);
|
||||
|
||||
free(ar);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void lmo_close(lmo_archive_t *ar)
|
||||
{
|
||||
if (ar != NULL)
|
||||
{
|
||||
if ((ar->mmap != NULL) && (ar->mmap != MAP_FAILED))
|
||||
munmap(ar->mmap, ar->size);
|
||||
|
||||
close(ar->fd);
|
||||
free(ar);
|
||||
|
||||
ar = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
lmo_catalog_t *_lmo_catalogs = NULL;
|
||||
lmo_catalog_t *_lmo_active_catalog = NULL;
|
||||
|
||||
int lmo_load_catalog(const char *lang, const char *dir)
|
||||
{
|
||||
DIR *dh = NULL;
|
||||
char pattern[16];
|
||||
char path[PATH_MAX];
|
||||
struct dirent *de = NULL;
|
||||
|
||||
lmo_archive_t *ar = NULL;
|
||||
lmo_catalog_t *cat = NULL;
|
||||
|
||||
if (!lmo_change_catalog(lang))
|
||||
return 0;
|
||||
|
||||
if (!dir || !(dh = opendir(dir)))
|
||||
goto err;
|
||||
|
||||
if (!(cat = malloc(sizeof(*cat))))
|
||||
goto err;
|
||||
|
||||
memset(cat, 0, sizeof(*cat));
|
||||
|
||||
snprintf(cat->lang, sizeof(cat->lang), "%s", lang);
|
||||
snprintf(pattern, sizeof(pattern), "*.%s.lmo", lang);
|
||||
|
||||
while ((de = readdir(dh)) != NULL)
|
||||
{
|
||||
if (!fnmatch(pattern, de->d_name, 0))
|
||||
{
|
||||
snprintf(path, sizeof(path), "%s/%s", dir, de->d_name);
|
||||
ar = lmo_open(path);
|
||||
|
||||
if (ar)
|
||||
{
|
||||
ar->next = cat->archives;
|
||||
cat->archives = ar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dh);
|
||||
|
||||
cat->next = _lmo_catalogs;
|
||||
_lmo_catalogs = cat;
|
||||
|
||||
if (!_lmo_active_catalog)
|
||||
_lmo_active_catalog = cat;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (dh) closedir(dh);
|
||||
if (cat) free(cat);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int lmo_change_catalog(const char *lang)
|
||||
{
|
||||
lmo_catalog_t *cat;
|
||||
|
||||
for (cat = _lmo_catalogs; cat; cat = cat->next)
|
||||
{
|
||||
if (!strncmp(cat->lang, lang, sizeof(cat->lang)))
|
||||
{
|
||||
_lmo_active_catalog = cat;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static lmo_entry_t * lmo_find_entry(lmo_archive_t *ar, uint32_t hash)
|
||||
{
|
||||
unsigned int m, l, r;
|
||||
uint32_t k;
|
||||
|
||||
l = 0;
|
||||
r = ar->length - 1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
m = l + ((r - l) / 2);
|
||||
|
||||
if (r < l)
|
||||
break;
|
||||
|
||||
k = ntohl(ar->index[m].key_id);
|
||||
|
||||
if (k == hash)
|
||||
return &ar->index[m];
|
||||
|
||||
if (k > hash)
|
||||
{
|
||||
if (!m)
|
||||
break;
|
||||
|
||||
r = m - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = m + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int lmo_translate(const char *key, int keylen, char **out, int *outlen)
|
||||
{
|
||||
uint32_t hash;
|
||||
lmo_entry_t *e;
|
||||
lmo_archive_t *ar;
|
||||
|
||||
if (!key || !_lmo_active_catalog)
|
||||
return -2;
|
||||
|
||||
hash = lmo_canon_hash(key, keylen);
|
||||
|
||||
for (ar = _lmo_active_catalog->archives; ar; ar = ar->next)
|
||||
{
|
||||
if ((e = lmo_find_entry(ar, hash)) != NULL)
|
||||
{
|
||||
*out = ar->mmap + ntohl(e->offset);
|
||||
*outlen = ntohl(e->length);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void lmo_close_catalog(const char *lang)
|
||||
{
|
||||
lmo_archive_t *ar, *next;
|
||||
lmo_catalog_t *cat, *prev;
|
||||
|
||||
for (prev = NULL, cat = _lmo_catalogs; cat; prev = cat, cat = cat->next)
|
||||
{
|
||||
if (!strncmp(cat->lang, lang, sizeof(cat->lang)))
|
||||
{
|
||||
if (prev)
|
||||
prev->next = cat->next;
|
||||
else
|
||||
_lmo_catalogs = cat->next;
|
||||
|
||||
for (ar = cat->archives; ar; ar = next)
|
||||
{
|
||||
next = ar->next;
|
||||
lmo_close(ar);
|
||||
}
|
||||
|
||||
free(cat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
92
luci-app-aliddns/tools/po2lmo/src/template_lmo.h
Normal file
92
luci-app-aliddns/tools/po2lmo/src/template_lmo.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* lmo - Lua Machine Objects - General header
|
||||
*
|
||||
* Copyright (C) 2009-2012 Jo-Philipp Wich <xm@subsignal.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _TEMPLATE_LMO_H_
|
||||
#define _TEMPLATE_LMO_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fnmatch.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if (defined(__GNUC__) && defined(__i386__))
|
||||
#define sfh_get16(d) (*((const uint16_t *) (d)))
|
||||
#else
|
||||
#define sfh_get16(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
|
||||
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
||||
#endif
|
||||
|
||||
|
||||
struct lmo_entry {
|
||||
uint32_t key_id;
|
||||
uint32_t val_id;
|
||||
uint32_t offset;
|
||||
uint32_t length;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct lmo_entry lmo_entry_t;
|
||||
|
||||
|
||||
struct lmo_archive {
|
||||
int fd;
|
||||
int length;
|
||||
uint32_t size;
|
||||
lmo_entry_t *index;
|
||||
char *mmap;
|
||||
char *end;
|
||||
struct lmo_archive *next;
|
||||
};
|
||||
|
||||
typedef struct lmo_archive lmo_archive_t;
|
||||
|
||||
|
||||
struct lmo_catalog {
|
||||
char lang[6];
|
||||
struct lmo_archive *archives;
|
||||
struct lmo_catalog *next;
|
||||
};
|
||||
|
||||
typedef struct lmo_catalog lmo_catalog_t;
|
||||
|
||||
|
||||
uint32_t sfh_hash(const char *data, int len);
|
||||
uint32_t lmo_canon_hash(const char *data, int len);
|
||||
|
||||
lmo_archive_t * lmo_open(const char *file);
|
||||
void lmo_close(lmo_archive_t *ar);
|
||||
|
||||
|
||||
extern lmo_catalog_t *_lmo_catalogs;
|
||||
extern lmo_catalog_t *_lmo_active_catalog;
|
||||
|
||||
int lmo_load_catalog(const char *lang, const char *dir);
|
||||
int lmo_change_catalog(const char *lang);
|
||||
int lmo_translate(const char *key, int keylen, char **out, int *outlen);
|
||||
void lmo_close_catalog(const char *lang);
|
||||
|
||||
#endif
|
@ -123,15 +123,15 @@ function to_check()
|
||||
elseif board_name:match("redmi,ax6$") then
|
||||
model = "ipq807x_generic/redmi_ax6"
|
||||
check_update()
|
||||
download_url = "https://op.supes.top/firmware/" ..model.. "/" ..remote_version.. "-openwrt-ipq807x-generic-redmi_ax6-squashfs-sysupgrade.bin"
|
||||
download_url = "https://op.supes.top/firmware/" ..model.. "/" ..remote_version.. "-openwrt-ipq807x-generic-redmi_ax6-squashfs-nand-sysupgrade.bin"
|
||||
elseif board_name:match("xiaomi,ax9000$") then
|
||||
model = "ipq807x_generic/xiaomi_ax9000"
|
||||
check_update()
|
||||
download_url = "https://op.supes.top/firmware/" ..model.. "/" ..remote_version.. "-openwrt-ipq807x-generic-xiaomi_ax9000-squashfs-sysupgrade.bin"
|
||||
download_url = "https://op.supes.top/firmware/" ..model.. "/" ..remote_version.. "-openwrt-ipq807x-generic-xiaomi_ax9000-squashfs-nand-sysupgrade.bin"
|
||||
elseif board_name:match("xiaomi,ax3600$") then
|
||||
model = "ipq807x_generic/xiaomi_ax3600"
|
||||
check_update()
|
||||
download_url = "https://op.supes.top/firmware/" ..model.. "/" ..remote_version.. "-openwrt-ipq807x-generic-xiaomi_ax3600-squashfs-sysupgrade.bin"
|
||||
download_url = "https://op.supes.top/firmware/" ..model.. "/" ..remote_version.. "-openwrt-ipq807x-generic-xiaomi_ax3600-squashfs-nand-sysupgrade.bin"
|
||||
elseif board_name:match("xy%-c5$") then
|
||||
model = "ramips_mt7621/xiaoyu_xy-c5"
|
||||
check_update()
|
||||
|
Loading…
Reference in New Issue
Block a user