Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
tbblgm119
lede
提交
2a6fb41b
L
lede
项目概览
tbblgm119
/
lede
与 Fork 源项目一致
从无法访问的项目Fork
通知
7
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
lede
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
2a6fb41b
编写于
4月 27, 2019
作者:
C
coolsnowwolf
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
luci app haproxy: package add
上级
228c4785
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
1130 addition
and
0 deletion
+1130
-0
package/lean/luci-app-haproxy-tcp/Makefile
package/lean/luci-app-haproxy-tcp/Makefile
+51
-0
package/lean/luci-app-haproxy-tcp/README.md
package/lean/luci-app-haproxy-tcp/README.md
+54
-0
package/lean/luci-app-haproxy-tcp/files/etc/config/haproxy
package/lean/luci-app-haproxy-tcp/files/etc/config/haproxy
+29
-0
package/lean/luci-app-haproxy-tcp/files/etc/haproxy_init.sh
package/lean/luci-app-haproxy-tcp/files/etc/haproxy_init.sh
+129
-0
package/lean/luci-app-haproxy-tcp/files/etc/haproxy_start
package/lean/luci-app-haproxy-tcp/files/etc/haproxy_start
+73
-0
package/lean/luci-app-haproxy-tcp/files/etc/uci-defaults/z99-haproxy
...n/luci-app-haproxy-tcp/files/etc/uci-defaults/z99-haproxy
+7
-0
package/lean/luci-app-haproxy-tcp/files/usr/lib/lua/luci/controller/haproxy.lua
...haproxy-tcp/files/usr/lib/lua/luci/controller/haproxy.lua
+7
-0
package/lean/luci-app-haproxy-tcp/files/usr/lib/lua/luci/model/cbi/haproxy.lua
...-haproxy-tcp/files/usr/lib/lua/luci/model/cbi/haproxy.lua
+67
-0
package/lean/luci-app-haproxy-tcp/i18n/zh-cn/haproxy.zh-cn.po
...age/lean/luci-app-haproxy-tcp/i18n/zh-cn/haproxy.zh-cn.po
+34
-0
package/lean/luci-app-haproxy-tcp/tools/po2lmo/Makefile
package/lean/luci-app-haproxy-tcp/tools/po2lmo/Makefile
+12
-0
package/lean/luci-app-haproxy-tcp/tools/po2lmo/src/po2lmo
package/lean/luci-app-haproxy-tcp/tools/po2lmo/src/po2lmo
+0
-0
package/lean/luci-app-haproxy-tcp/tools/po2lmo/src/po2lmo.c
package/lean/luci-app-haproxy-tcp/tools/po2lmo/src/po2lmo.c
+247
-0
package/lean/luci-app-haproxy-tcp/tools/po2lmo/src/template_lmo.c
...lean/luci-app-haproxy-tcp/tools/po2lmo/src/template_lmo.c
+328
-0
package/lean/luci-app-haproxy-tcp/tools/po2lmo/src/template_lmo.h
...lean/luci-app-haproxy-tcp/tools/po2lmo/src/template_lmo.h
+92
-0
未找到文件。
package/lean/luci-app-haproxy-tcp/Makefile
0 → 100644
浏览文件 @
2a6fb41b
include
$(TOPDIR)/rules.mk
PKG_NAME
:=
luci-app-haproxy-tcp
PKG_VERSION
=
1.4
PKG_RELEASE
:=
1
PKG_MAINTAINER
:=
Alex Zhuo <1886090@gmail.com>
PKG_BUILD_DIR
:=
$(BUILD_DIR)
/
$(PKG_NAME)
include
$(INCLUDE_DIR)/package.mk
define
Package/$(PKG_NAME)
CATEGORY
:=
Utilities
SUBMENU
:=
Luci
TITLE
:=
luci
for
haproxy and shadowsocks
PKGARCH
:=
all
DEPENDS
:=
+haproxy
endef
define
Package/$(PKG_NAME)/description
A
luci
app
for
haproxy
with
shadowsocks
endef
define
Package/$(PKG_NAME)/postinst
#!/bin/sh
rm
-rf
/tmp/luci*
echo
stopping
haproxy
/etc/init.d/haproxy
stop
/etc/init.d/haproxy
disable
echo
haproxy
disabled
endef
define
Build/Prepare
$(foreach
po,$(wildcard
${CURDIR}/i18n/zh-cn/*.po),
\
po2lmo
$(po)
$(PKG_BUILD_DIR)/$(patsubst
%.po,%.lmo,$(notdir
$(po)));)
endef
define
Build/Configure
endef
define
Build/Compile
endef
define
Package/$(PKG_NAME)/install
$(INSTALL_DIR)
$(1)/usr/lib/lua/luci/i18n
$(INSTALL_DATA)
$(PKG_BUILD_DIR)/*.*.lmo
$(1)/usr/lib/lua/luci/i18n/
$(CP)
./files/*
$(1)/
endef
$(eval
$(call
BuildPackage,$(PKG_NAME)))
package/lean/luci-app-haproxy-tcp/README.md
0 → 100644
浏览文件 @
2a6fb41b
# luci-app-haproxy-tcp
OpenWrt HAProxy的Luci配置页面,已在
[
该固件
][
A
]
中使用
简介
---
本软件包为OpenWRT HAPrxoy的 LuCI 控制界面,用于Shadowsocks在多服务器条件下实现负载均衡和高可用
可以设置多个主服务器或多个备用服务器. 默认监听端口127.0.0.1:2222 后台监控页面端口0.0.0.0:1111,后台监控页面地址192.168.1.1:1111/haproxy
多主服务器是将所有TCP流量分流,并可以设置每个服务器的分流比例;多备用服务器是在检测到主服务器A宕机之后切换至备用服务器B,B宕机之后切换到服务器C...依次类推,可以防止因为单个服务器或者线路故障导致的断网问题。
使用效果和更多使用方法请
[
点击这里
][
A
]
依赖
---
显式依赖
`haproxy`
, 安装完毕该luci包后会stop并disable当前op的haproxy,点击“保存&应用”后会修改HAProxy默认配置文件/etc/haproxy.cfg并自动重启,支持开机自启.
配置
---
如果有需要,可以修改/etc/haproxy_init.sh ,不要直接修改/etc/haproxy.cfg,否则会被覆盖
编译
---
从 OpenWrt 的
[
SDK
][
openwrt-sdk
]
编译
```
bash
# 解压下载好的 SDK
tar
xjf OpenWrt-SDK-ar71xx-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2.tar.bz2
cd
OpenWrt-SDK-ar71xx-
*
# Clone 项目
git clone https://github.com/AlexZhuo/luci-app-haproxy-tcp package/luci-app-haproxy-tcp
# 编译 po2lmo (如果有po2lmo可跳过)
pushd
package/luci-app-haproxy-tcp/tools/po2lmo
make
&&
sudo
make
install
popd
# 选择要编译的包 Utilities -> LuCI -> luci-app-haproxy-tcp
make menuconfig
# 开始编译
make package/luci-app-haproxy-tcp/compile
V
=
99
```
截图
---
![](
https://github.com/AlexZhuo/BreakwallOpenWrt/raw/master/screenshots/haproxy.png
)
[
A
]:
http://www.right.com.cn/forum/thread-198649-1-1.html
[
openwrt-sdk
]:
http://wiki.openwrt.org/doc/howto/obtain.firmware.sdk
package/lean/luci-app-haproxy-tcp/files/etc/config/haproxy
0 → 100644
浏览文件 @
2a6fb41b
config arguments
option enabled '0'
config main_server
option server_weight '10'
option server_ip '1.2.3.4'
option server_port '443'
option server_name 'JP1'
option validate '1'
config backup_server
option server_name 'JP2'
option server_ip '2.2.2.2'
option server_port '8038'
option validate '1'
config backup_server
option server_name 'JP3'
option server_ip '3.3.3.3'
option server_port '443'
option validate '1'
config backup_server
option server_name 'JP4'
option server_ip '4.4.4.4'
option server_port '443'
option validate '1'
package/lean/luci-app-haproxy-tcp/files/etc/haproxy_init.sh
0 → 100755
浏览文件 @
2a6fb41b
#!/bin/sh /etc/rc.common
CFG_FILE
=
/etc/haproxy.cfg
stop
(){
logger
-t
alex stopping haproxy
echo
"stopping haproxy"
/etc/init.d/haproxy disable
/etc/init.d/haproxy stop
[
-f
/etc/haproxy_backup
]
&&
{
cp
/etc/haproxy_backup /etc/init.d/haproxy
}
iptables
-t
nat
-D
OUTPUT
-j
HAPROXY &> /dev/null
iptables
-t
nat
-F
HAPROXY &> /dev/null
sleep
1
iptables
-t
nat
-X
HAPROXY &> /dev/null
}
start
(){
echo
"starting haproxy"
logger
-t
restarting haproxy
echo
global
>
$CFG_FILE
cat
>>
$CFG_FILE
<<
EOF
log 127.0.0.1 local0 #[日志输出配置,所有日志都记录在本机,通过local0输出]
log 127.0.0.1 local1 notice #定义haproxy 日志级别[error warringinfo debug]
daemon #以后台形式运行harpoxy
nbproc 1 #设置进程数量
pidfile /var/run/haproxy.pid
ulimit-n 1024 #ulimit 的数量限制
maxconn 1024 #默认最大连接数,需考虑ulimit-n限制
#chroot /usr/local/haproxy
defaults
log global
mode tcp #默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK
retries 3 #两次连接失败就认为是服务器不可用,也可以通过后面设置
option abortonclose #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
option redispatch
maxconn 1024 #默认的最大连接数
timeout connect 5000ms #连接超时
timeout client 30000ms #客户端超时
timeout server 30000ms #服务器超时
balance roundrobin #设置默认负载均衡方式,轮询方式
#balance source #设置默认负载均衡方式,类似于nginx的ip_hash
#balnace leastconn #设置默认负载均衡方式,最小连接数
listen admin_stats
bind 0.0.0.0:1111 #节点统计页面的访问端口
mode http #http的7层模式
option httplog #采用http日志格式
maxconn 10 #节点统计页面默认的最大连接数
stats refresh 30s #节点统计页面自动刷新时间
stats uri /haproxy #节点统计页面url
stats realm Haproxy #统计页面密码框上提示文本
stats auth admin:root #设置监控页面的用户和密码:admin,可以设置多个用户名
stats admin if TRUE #设置手工启动/禁用,后端服务器(haproxy-1.4.9以后版本)
frontend ss-in
bind 127.0.0.1:2222
default_backend ss-out
backend ss-out
mode tcp
balance roundrobin
option tcplog
EOF
local
COUNTER
=
0
#添加主服务器
iptables
-t
nat
-X
HAPROXY
iptables
-t
nat
-N
HAPROXY
iptables
-t
nat
-F
HAPROXY
while
true
do
local
server_ip
=
`
uci get haproxy.@main_server[
$COUNTER
]
.server_ip 2>/dev/null
`
local
server_name
=
`
uci get haproxy.@main_server[
$COUNTER
]
.server_name 2>/dev/null
`
local
server_port
=
`
uci get haproxy.@main_server[
$COUNTER
]
.server_port 2>/dev/null
`
local
server_weight
=
`
uci get haproxy.@main_server[
$COUNTER
]
.server_weight 2>/dev/null
`
local
validate
=
`
uci get haproxy.@main_server[
$COUNTER
]
.validate 2>/dev/null
`
if
[
-z
"
$server_ip
"
]
||
[
-z
"
$server_name
"
]
||
[
-z
"
$server_port
"
]
||
[
-z
"
$server_weight
"
]
;
then
echo break
break
fi
echo
the main server
$COUNTER
$server_ip
$server_name
$server_port
$server_weight
[
"
$validate
"
=
1
]
&&
{
echo
server
$server_name
$server_ip
:
$server_port
weight
$server_weight
maxconn 1024 check inter 1500 rise 3 fall 3
>>
$CFG_FILE
}
iptables
-t
nat
-A
HAPROXY
-p
tcp
-d
$server_ip
-j
ACCEPT
COUNTER
=
$((
$COUNTER
+
1
))
done
COUNTER
=
0
#添加备用服务器
while
true
do
local
server_ip
=
`
uci get haproxy.@backup_server[
$COUNTER
]
.server_ip 2>/dev/null
`
local
server_name
=
`
uci get haproxy.@backup_server[
$COUNTER
]
.server_name 2>/dev/null
`
local
server_port
=
`
uci get haproxy.@backup_server[
$COUNTER
]
.server_port 2>/dev/null
`
local
validate
=
`
uci get haproxy.@backup_server[
$COUNTER
]
.validate 2>/dev/null
`
if
[
-z
"
$server_ip
"
]
||
[
-z
"
$server_name
"
]
||
[
-z
"
$server_port
"
]
;
then
echo break
break
fi
echo
the backup server
$COUNTER
$server_ip
$server_name
$server_port
[
"
$validate
"
=
1
]
&&
{
echo
server
$server_name
$server_ip
:
$server_port
weight 10 check backup inter 1500 rise 3 fall 3
>>
$CFG_FILE
}
iptables
-t
nat
-A
HAPROXY
-p
tcp
-d
$server_ip
-j
ACCEPT
COUNTER
=
$((
$COUNTER
+
1
))
done
iptables
-t
nat
-I
OUTPUT
-j
HAPROXY
/etc/init.d/haproxy
enable
/etc/init.d/haproxy restart
cp
/etc/init.d/haproxy /etc/haproxy_backup
cp
/etc/haproxy_start /etc/init.d/haproxy
}
restart
(){
echo
luci
for
haproxy
sleep
1s
local
vt_enabled
=
`
uci get haproxy.@arguments[0].enabled 2>/dev/null
`
logger
-t
haproxy is initializing enabled is
$vt_enabled
echo
$vt_enabled
if
[
"
$vt_enabled
"
=
1
]
;
then
[
-f
/etc/haproxy_backup
]
&&
{
cp
/etc/haproxy_backup /etc/init.d/haproxy
}
iptables
-t
nat
-D
OUTPUT
-j
HAPROXY &> /dev/null
iptables
-t
nat
-F
HAPROXY &> /dev/null
sleep
1
iptables
-t
nat
-X
HAPROXY &> /dev/null
start
;
else
stop
;
fi
}
\ No newline at end of file
package/lean/luci-app-haproxy-tcp/files/etc/haproxy_start
0 → 100755
浏览文件 @
2a6fb41b
#!/bin/sh /etc/rc.common
# Copyright (C) 2009-2010 OpenWrt.org
START
=
99
STOP
=
80
SERVICE_USE_PID
=
1
HAPROXY_BIN
=
"/usr/sbin/haproxy"
HAPROXY_CONFIG
=
"/etc/haproxy.cfg"
HAPROXY_PID
=
"/var/run/haproxy.pid"
start
()
{
service_start
$HAPROXY_BIN
-q
-D
-f
"
$HAPROXY_CONFIG
"
-p
"
$HAPROXY_PID
"
local
COUNTER
=
0
#添加主服务器
iptables
-t
nat
-D
OUTPUT
-j
HAPROXY &> /dev/null
iptables
-t
nat
-X
HAPROXY
iptables
-t
nat
-N
HAPROXY
iptables
-t
nat
-F
HAPROXY
while
true
do
local
server_ip
=
`
uci get haproxy.@main_server[
$COUNTER
]
.server_ip 2>/dev/null
`
local
server_name
=
`
uci get haproxy.@main_server[
$COUNTER
]
.server_name 2>/dev/null
`
local
server_port
=
`
uci get haproxy.@main_server[
$COUNTER
]
.server_port 2>/dev/null
`
local
server_weight
=
`
uci get haproxy.@main_server[
$COUNTER
]
.server_weight 2>/dev/null
`
local
validate
=
`
uci get haproxy.@main_server[
$COUNTER
]
.validate 2>/dev/null
`
if
[
-z
"
$server_ip
"
]
||
[
-z
"
$server_name
"
]
||
[
-z
"
$server_port
"
]
||
[
-z
"
$server_weight
"
]
;
then
echo break
break
fi
echo
the main2 server
$COUNTER
$server_ip
$server_name
$server_port
$server_weight
[
"
$validate
"
=
1
]
&&
{
iptables
-t
nat
-A
HAPROXY
-p
tcp
-d
$server_ip
-j
ACCEPT
}
COUNTER
=
$((
$COUNTER
+
1
))
done
COUNTER
=
0
#添加备用服务器
while
true
do
local
server_ip
=
`
uci get haproxy.@backup_server[
$COUNTER
]
.server_ip 2>/dev/null
`
local
server_name
=
`
uci get haproxy.@backup_server[
$COUNTER
]
.server_name 2>/dev/null
`
local
server_port
=
`
uci get haproxy.@backup_server[
$COUNTER
]
.server_port 2>/dev/null
`
local
validate
=
`
uci get haproxy.@backup_server[
$COUNTER
]
.validate 2>/dev/null
`
if
[
-z
"
$server_ip
"
]
||
[
-z
"
$server_name
"
]
||
[
-z
"
$server_port
"
]
;
then
echo break
break
fi
echo
the backup2 server
$COUNTER
$server_ip
$server_name
$server_port
[
"
$validate
"
=
1
]
&&
{
iptables
-t
nat
-A
HAPROXY
-p
tcp
-d
$server_ip
-j
ACCEPT
}
COUNTER
=
$((
$COUNTER
+
1
))
done
iptables
-t
nat
-I
OUTPUT
-j
HAPROXY
}
stop
()
{
kill
-9
$(
cat
$HAPROXY_PID
|
tr
"
\n
"
" "
)
service_stop
$HAPROXY_BIN
iptables
-t
nat
-D
OUTPUT
-j
HAPROXY &> /dev/null
iptables
-t
nat
-F
HAPROXY &> /dev/null
sleep
1
iptables
-t
nat
-X
HAPROXY &> /dev/null
}
reload
()
{
$HAPROXY_BIN
-D
-q
-f
$HAPROXY_CONFIG
-p
$HAPROXY_PID
-sf
$(
cat
$HAPROXY_PID
|
tr
"
\n
"
" "
)
#$HAPROXY_BIN -D -q -f $HAPROXY_CONFIG -p $HAPROXY_PID -sf $(cat $HAPROXY_PID)
}
package/lean/luci-app-haproxy-tcp/files/etc/uci-defaults/z99-haproxy
0 → 100755
浏览文件 @
2a6fb41b
#!/bin/sh
/etc/init.d/haproxy disable
/etc/init.d/haproxy stop
rm
-f
/tmp/luci-indexcache
exit
0
package/lean/luci-app-haproxy-tcp/files/usr/lib/lua/luci/controller/haproxy.lua
0 → 100644
浏览文件 @
2a6fb41b
module
(
"luci.controller.haproxy"
,
package
.
seeall
)
function
index
()
if
not
nixio
.
fs
.
access
(
"/etc/config/haproxy"
)
then
return
end
entry
({
"admin"
,
"services"
,
"haproxy"
},
cbi
(
"haproxy"
),
_
(
"HAProxy"
)).
dependent
=
true
end
\ No newline at end of file
package/lean/luci-app-haproxy-tcp/files/usr/lib/lua/luci/model/cbi/haproxy.lua
0 → 100644
浏览文件 @
2a6fb41b
--Alex<1886090@gmail.com>
local
fs
=
require
"nixio.fs"
function
sync_value_to_file
(
value
,
file
)
--用来写入文件的函数,目前这种方式已经弃用
value
=
value
:
gsub
(
"
\r\n?
"
,
"
\n
"
)
local
old_value
=
nixio
.
fs
.
readfile
(
file
)
if
value
~=
old_value
then
nixio
.
fs
.
writefile
(
file
,
value
)
end
end
local
state_msg
=
""
local
haproxy_on
=
(
luci
.
sys
.
call
(
"pidof haproxy > /dev/null"
)
==
0
)
local
router_ip
=
luci
.
sys
.
exec
(
"uci get network.lan.ipaddr"
)
if
haproxy_on
then
state_msg
=
"<b><font color=\"
green
\
">"
..
translate
(
"Running"
)
..
"</font></b>"
else
state_msg
=
"<b><font color=\"
red
\
">"
..
translate
(
"Not running"
)
..
"</font></b>"
end
m
=
Map
(
"haproxy"
,
translate
(
"HAProxy"
),
translate
(
"HAProxy能够检测Shadowsocks服务器的连通情况,从而实现负载均衡和高可用的功能,支持主备用服务器宕机自动切换,并且可以设置多个主服务器用于分流,规定每个分流节点的流量比例等。前提条件是你的所有Shadowsocks服务器的【加密方式】和【密码】一致。<br><br>使用方法:配置好你的Shadowsocks服务器ip地址和端口,然后开启Shadowsocks服务,将服务器地址填写为【127.0.0.1】,端口【2222】,其他参数和之前一样即可,你可以通过访问【路由器的IP:1111/haproxy】输入用户名admin,密码root来观察各节点健康状况,红色为宕机,绿色正常,使用说明请<a href='http://www.right.com.cn/forum/thread-198649-1-1.html'>点击这里</a>"
)
..
"<br><br>后台监控页面:<a href='http://"
..
router_ip
..
":1111/haproxy'>"
..
router_ip
..
":1111/haproxy</a> 用户名admin,密码root"
..
"<br><br>状态 - "
..
state_msg
)
s
=
m
:
section
(
TypedSection
,
"arguments"
,
""
)
s
.
addremove
=
false
s
.
anonymous
=
true
view_enable
=
s
:
option
(
Flag
,
"enabled"
,
translate
(
"Enable"
))
--通过读写配置文件控制HAProxy这种方式已经弃用
--view_cfg = s:option(TextValue, "1", nil)
--view_cfg.rmempty = false
--view_cfg.rows = 43
--function view_cfg.cfgvalue()
-- return nixio.fs.readfile("/etc/haproxy.cfg") or ""
--end
--function view_cfg.write(self, section, value)
-- sync_value_to_file(value, "/etc/haproxy.cfg")
--end
s
=
m
:
section
(
TypedSection
,
"main_server"
,
"<b>"
..
translate
(
"Main Server List"
)
..
"<b>"
)
s
.
anonymous
=
true
s
.
addremove
=
true
o
=
s
:
option
(
Value
,
"server_name"
,
translate
(
"Display Name"
),
translate
(
"Only English Characters,No spaces"
))
o
.
rmempty
=
false
o
=
s
:
option
(
Flag
,
"validate"
,
translate
(
"validate"
))
o
=
s
:
option
(
Value
,
"server_ip"
,
translate
(
"Proxy Server IP"
))
o
.
datatype
=
"ip4addr"
o
=
s
:
option
(
Value
,
"server_port"
,
translate
(
"Proxy Server Port"
))
o
.
datatype
=
"uinteger"
o
=
s
:
option
(
Value
,
"server_weight"
,
translate
(
"Weight"
))
o
.
datatype
=
"uinteger"
s
=
m
:
section
(
TypedSection
,
"backup_server"
,
"<b>"
..
translate
(
"Backup Server List"
)
..
"<b>"
)
s
.
anonymous
=
true
s
.
addremove
=
true
o
=
s
:
option
(
Value
,
"server_name"
,
translate
(
"Display Name"
),
translate
(
"Only English Characters,No spaces"
))
o
.
rmempty
=
false
o
=
s
:
option
(
Flag
,
"validate"
,
translate
(
"validate"
))
o
=
s
:
option
(
Value
,
"server_ip"
,
translate
(
"Proxy Server IP"
))
o
.
datatype
=
"ip4addr"
o
=
s
:
option
(
Value
,
"server_port"
,
translate
(
"Proxy Server Port"
))
o
.
datatype
=
"uinteger"
-- ---------------------------------------------------
local
apply
=
luci
.
http
.
formvalue
(
"cbi.apply"
)
if
apply
then
os.execute
(
"/etc/haproxy_init.sh restart >/dev/null 2>&1 &"
)
end
return
m
package/lean/luci-app-haproxy-tcp/i18n/zh-cn/haproxy.zh-cn.po
0 → 100755
浏览文件 @
2a6fb41b
msgid "Running"
msgstr "运行中"
msgid "Not running"
msgstr "未运行"
msgid "Main Server List"
msgstr "主服务器列表"
msgid "Display Name"
msgstr "服务器名称"
msgid "Only English Characters,No spaces"
msgstr "仅限英文字母,不要有空格"
msgid "Proxy Server IP"
msgstr "代理服务器IP"
msgid "Proxy Server Port"
msgstr "代理服务器端口"
msgid "Weight"
msgstr "分流权重"
msgid "Backup Server List"
msgstr "备用服务器列表"
msgid "validate"
msgstr "生效"
package/lean/luci-app-haproxy-tcp/tools/po2lmo/Makefile
0 → 100644
浏览文件 @
2a6fb41b
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
package/lean/luci-app-haproxy-tcp/tools/po2lmo/src/po2lmo
0 → 100755
浏览文件 @
2a6fb41b
文件已添加
package/lean/luci-app-haproxy-tcp/tools/po2lmo/src/po2lmo.c
0 → 100644
浏览文件 @
2a6fb41b
/*
* 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
);
}
package/lean/luci-app-haproxy-tcp/tools/po2lmo/src/template_lmo.c
0 → 100644
浏览文件 @
2a6fb41b
/*
* 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
;
}
}
}
package/lean/luci-app-haproxy-tcp/tools/po2lmo/src/template_lmo.h
0 → 100644
浏览文件 @
2a6fb41b
/*
* 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
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录