re-add default-settings

This commit is contained in:
coolsnowwolf 2018-10-06 21:30:00 +08:00
parent b0b4ad0f5d
commit 0e3e0b4147
11 changed files with 2070 additions and 0 deletions

View File

@ -254,6 +254,7 @@ $(call KernelPackage/$(1)/config)
$$(eval $$(call BuildPackage,kmod-$(1))) $$(eval $$(call BuildPackage,kmod-$(1)))
$$(IPKG_kmod-$(1)): $$(wildcard $$(FILES)) $$(IPKG_kmod-$(1)): $$(wildcard $$(FILES))
endef endef
version_filter=$(if $(findstring @,$(1)),$(shell $(SCRIPT_DIR)/package-metadata.pl version_filter $(KERNEL_PATCHVER) $(1)),$(1)) version_filter=$(if $(findstring @,$(1)),$(shell $(SCRIPT_DIR)/package-metadata.pl version_filter $(KERNEL_PATCHVER) $(1)),$(1))

View File

@ -0,0 +1,49 @@
#
# Copyright (C) 2016-2017 GitHub
#
# This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information.
include $(TOPDIR)/rules.mk
PKG_NAME:=default-settings
PKG_VERSION:=1.0
PKG_RELEASE:=58
PKG_LICENSE:=GPLv3
PKG_LICENSE_FILES:=LICENSE
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
define Package/default-settings
SECTION:=luci
CATEGORY:=LuCI
TITLE:=LuCI support for Default Settings
PKGARCH:=all
DEPENDS:=+@LUCI_LANG_zh-cn
endef
define Package/default-settings/description
Language Support Packages.
endef
define Build/Prepare
$(foreach po,$(wildcard ${CURDIR}/i18n/*.po), \
po2lmo $(po) $(PKG_BUILD_DIR)/$(patsubst %.po,%.lmo,$(notdir $(po)));)
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/default-settings/install
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DATA) $(PKG_BUILD_DIR)/*.lmo $(1)/usr/lib/lua/luci/i18n/
$(INSTALL_BIN) ./files/zzz-default-settings $(1)/etc/uci-defaults/99-default-settings
endef
$(eval $(call BuildPackage,default-settings))

View File

@ -0,0 +1,69 @@
#!/bin/sh
uci set luci.main.lang=zh_cn
uci commit luci
uci set system.@system[0].hostname=OpenWrt
uci set system.@system[0].timezone=CST-8
uci set system.@system[0].zonename=Asia/Shanghai
uci commit system
uci set fstab.@global[0].anon_mount=1
uci commit fstab
rm -f /usr/lib/lua/luci/view/admin_status/index/mwan.htm
rm -f /usr/lib/lua/luci/view/admin_status/index/upnp.htm
rm -f /usr/lib/lua/luci/view/admin_status/index/ddns.htm
rm -f /usr/lib/lua/luci/view/admin_status/index/minidlna.htm
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/aria2.lua
sed -i 's/services/nas/g' /usr/lib/lua/luci/view/aria2/overview_status.htm
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/hd_idle.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/samba.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/minidlna.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/transmission.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/mjpg-streamer.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/p910nd.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/usb_printer.lua
sed -i 's/\"services\"/\"nas\"/g' /usr/lib/lua/luci/controller/xunlei.lua
sed -i 's/services/nas/g' /usr/lib/lua/luci/view/minidlna_status.htm
uci set minidlna.config.enabled=0
uci commit minidlna
/etc/init.d/minidlna stop
ln -sf /sbin/ip /usr/bin/ip
rm -rf /tmp/luci-modulecache/
rm -f /tmp/luci-indexcache
sed -i 's/downloads.openwrt.org/openwrt.proxy.ustclug.org/g' /etc/opkg/distfeeds.conf
sed -i 's/root::0:0:99999:7:::/root:$1$V4UetPzk$CYXluq4wUazHjmCDBCqXF.:0:0:99999:7:::/g' /etc/shadow
sed -i "s/# //g" /etc/opkg/distfeeds.conf
uci set dhcp.@dnsmasq[0].cachesize='1024'
uci set dhcp.lan.ra='hybrid'
uci set dhcp.lan.dhcpv6='hybrid'
uci set dhcp.lan.ndp='hybrid'
uci commit dhcp
sed -i '/REDIRECT --to-ports 53/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
sed -i '/option disabled/d' /etc/config/wireless
sed -i '/set wireless.radio${devidx}.disabled/d' /lib/wifi/mac80211.sh
wifi up
sed -i '/DISTRIB_REVISION/d' /etc/openwrt_release
echo "DISTRIB_REVISION='R8.1.6 By Lean'" >> /etc/openwrt_release
sed -i '/DISTRIB_DESCRIPTION/d' /etc/openwrt_release
echo "DISTRIB_DESCRIPTION='OpenWrt '" >> /etc/openwrt_release
sed -i 's/cbi.submit\"] = true/cbi.submit\"] = \"1\"/g' /usr/lib/lua/luci/dispatcher.lua
exit 0

View File

@ -0,0 +1,32 @@
msgid "Processor"
msgstr "处理器"
msgid "Architecture"
msgstr "架构"
msgid "CPU Temperature"
msgstr "CPU温度"
msgid "CPU Info"
msgstr "CPU信息"
msgid "CPU Model"
msgstr "处理器型号"
msgid "CPU frequency"
msgstr "CPU频率"
msgid "RAM frequency"
msgstr "RAM频率"
msgid "Flash Size"
msgstr "闪存大小"
msgid "Free Memory"
msgstr "释放内存"
msgid "RUNNING"
msgstr "运行中"
msgid "NOT RUNNING"
msgstr "未运行"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,203 @@
msgid ""
msgstr ""
"Project-Id-Version: luci-i18n-sqm\n"
"POT-Creation-Date: 2017-03-28 04:14+0800\n"
"PO-Revision-Date: 2017-03-28 04:15+0800\n"
"Last-Translator: \n"
"Language-Team: player131 <player1311@gmail.com>\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.10\n"
"X-Poedit-Basepath: .\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Poedit-KeywordsList: translate\n"
"X-Poedit-SearchPath-0: .\n"
#: usr/lib/lua/luci/controller/sqm.lua:24
msgid "SQM QoS"
msgstr "SQM QoS"
#: usr/lib/lua/luci/model/cbi/sqm.lua:25
msgid "Smart Queue Management"
msgstr "智能队列管理"
#: usr/lib/lua/luci/model/cbi/sqm.lua:26
msgid ""
"With <abbr title=\"Smart Queue Management\">SQM</abbr> you can enable "
"traffic shaping, better mixing (Fair Queueing), active queue length "
"management (AQM) and prioritisation on one network interface."
msgstr ""
"使用 <abbr title=\"智能列队管理\">SQM</abbr> 你可以启用流量整形,更好的混合"
"(公平列队)主动列队管理(AQM) 并设置网络接口优先级。"
#: usr/lib/lua/luci/model/cbi/sqm.lua:32
msgid "Queues"
msgstr "队列"
#: usr/lib/lua/luci/model/cbi/sqm.lua:33
msgid "Basic Settings"
msgstr "基本设置"
#: usr/lib/lua/luci/model/cbi/sqm.lua:34
msgid "Queue Discipline"
msgstr "列队规则"
#: usr/lib/lua/luci/model/cbi/sqm.lua:35
msgid "Link Layer Adaptation"
msgstr "链路层适配"
#: usr/lib/lua/luci/model/cbi/sqm.lua:40
msgid "Enable this SQM instance."
msgstr "启用此SQM实例"
#: usr/lib/lua/luci/model/cbi/sqm.lua:54
msgid ""
"The SQM GUI has just enabled the sqm initscript on your behalf. Remember to "
"disable the sqm initscript manually under System Startup menu in case this "
"change was not wished for."
msgstr ""
"你刚刚开启了SQM随机启动功能如果你不希望SQM随机启动可以在系统启动菜单下手"
"动禁用。"
#: usr/lib/lua/luci/model/cbi/sqm.lua:60
msgid "Interface name"
msgstr "接口名称"
#: usr/lib/lua/luci/model/cbi/sqm.lua:70
msgid ""
"Download speed (kbit/s) (ingress) set to 0 to selectively disable ingress "
"shaping:"
msgstr "下载速度(kbit/s)(入口)<br />设置为0关闭入口控制"
#: usr/lib/lua/luci/model/cbi/sqm.lua:74
msgid ""
"Upload speed (kbit/s) (egress) set to 0 to selectively disable egress "
"shaping:"
msgstr "上传速度(kbit/s)(出口)<br />设置为0关闭出口控制"
#: usr/lib/lua/luci/model/cbi/sqm.lua:78
msgid ""
"Create log file for this SQM instance under /var/run/sqm/${Inerface_name}."
"debug.log. Make sure to delete log files manually."
msgstr ""
"创建日志文件到/var/run/sqm/<br />${Inerface_name}.debug.log。<br />请务必手动"
"删除日志文件。"
#: usr/lib/lua/luci/model/cbi/sqm.lua:82
msgid "Verbosity of SQM's output into the system log."
msgstr "SQM输出到系统日志的详细程度。"
#: usr/lib/lua/luci/model/cbi/sqm.lua:86 usr/lib/lua/luci/model/cbi/sqm.lua:99
#: usr/lib/lua/luci/model/cbi/sqm.lua:148
#: usr/lib/lua/luci/model/cbi/sqm.lua:155
#: usr/lib/lua/luci/model/cbi/sqm.lua:202
#: usr/lib/lua/luci/model/cbi/sqm.lua:243
msgid "default"
msgstr "默认"
#: usr/lib/lua/luci/model/cbi/sqm.lua:98
msgid ""
"Queuing disciplines useable on this system. After installing a new qdisc, "
"you need to restart the router to see updates!"
msgstr "系统上可用的列队规则。安装新的队列规则后,重新启动路由器才会看到更新!"
#: usr/lib/lua/luci/model/cbi/sqm.lua:112
msgid "Queue setup script"
msgstr "队列脚本设置"
#: usr/lib/lua/luci/model/cbi/sqm.lua:129
msgid ""
"Show and Use Advanced Configuration. Advanced options will only be used as "
"long as this box is checked."
msgstr "选中该复选框显示高级配置。"
#: usr/lib/lua/luci/model/cbi/sqm.lua:133
msgid "Squash DSCP on inbound packets (ingress):"
msgstr "入站数据包压缩DSCP:"
#: usr/lib/lua/luci/model/cbi/sqm.lua:140
msgid "Ignore DSCP on ingress:"
msgstr "忽略入站DSCP"
#: usr/lib/lua/luci/model/cbi/sqm.lua:147
msgid ""
"Explicit congestion notification (ECN) status on inbound packets (ingress):"
msgstr "入站数据包的显式拥塞通知ECN状态"
#: usr/lib/lua/luci/model/cbi/sqm.lua:154
msgid ""
"Explicit congestion notification (ECN) status on outbound packets (egress)."
msgstr "出站数据包的显式拥塞通知ECN状态"
#: usr/lib/lua/luci/model/cbi/sqm.lua:161
msgid ""
"Show and Use Dangerous Configuration. Dangerous options will only be used as "
"long as this box is checked."
msgstr "选中该复选框显示危险配置。"
#: usr/lib/lua/luci/model/cbi/sqm.lua:166
msgid "Hard limit on ingress queues; leave empty for default."
msgstr "入站队列严格限制;留空为默认。"
#: usr/lib/lua/luci/model/cbi/sqm.lua:173
msgid "Hard limit on egress queues; leave empty for default."
msgstr "出站队列严格限制;留空为默认。"
#: usr/lib/lua/luci/model/cbi/sqm.lua:180
msgid "Latency target for ingress, e.g 5ms [units: s, ms, or us]; leave empty for automatic selection, put in the word default for the qdisc's default."
msgstr "入站延迟目标,例如 5ms [单位: s, ms, 或 us]留空为自动选择default为列队规则默认值。"
#: usr/lib/lua/luci/model/cbi/sqm.lua:185
msgid "Latency target for egress, e.g. 5ms [units: s, ms, or us]; leave empty for automatic selection, put in the word default for the qdisc's default."
msgstr "出站延迟目标,例如 5ms [单位: s, ms, 或 us]留空为自动选择default为列队规则默认值。"
#: usr/lib/lua/luci/model/cbi/sqm.lua:192
msgid ""
"Advanced option string to pass to the ingress queueing disciplines; no error "
"checking, use very carefully."
msgstr "传递到入站队列规则的高级选项字符串;没有错误检查。请谨慎使用!"
#: usr/lib/lua/luci/model/cbi/sqm.lua:196
msgid ""
"Advanced option string to pass to the egress queueing disciplines; no error "
"checking, use very carefully."
msgstr "传递到出站队列规则的高级选项字符串;没有错误检查。请谨慎使用!"
#: usr/lib/lua/luci/model/cbi/sqm.lua:201
msgid "Which link layer to account for:"
msgstr "对哪个链路层生效:"
#: usr/lib/lua/luci/model/cbi/sqm.lua:207
msgid "Per Packet Overhead (byte):"
msgstr "每个数据包开销"
#: usr/lib/lua/luci/model/cbi/sqm.lua:216
msgid ""
"Show Advanced Linklayer Options, (only needed if MTU > 1500). Advanced "
"options will only be used as long as this box is checked."
msgstr ""
"显示高级链路选项仅在MTU> 1500时才需要。 只有选中此框时,才会使用高级选"
"项。"
#: usr/lib/lua/luci/model/cbi/sqm.lua:221
msgid ""
"Maximal Size for size and rate calculations, tcMTU (byte); needs to be >= "
"interface MTU + overhead:"
msgstr "大小和速率计算的最大尺寸tcMTUbyte; 需要> =接口MTU +开销:"
#: usr/lib/lua/luci/model/cbi/sqm.lua:228
msgid ""
"Number of entries in size/rate tables, TSIZE; for ATM choose TSIZE = (tcMTU "
"+ 1) / 16:"
msgstr "大小/速率表中的条目数TSIZE; 对于ATM选择TSIZE =tcMTU + 1/ 16"
#: usr/lib/lua/luci/model/cbi/sqm.lua:235
msgid ""
"Minimal packet size, MPU (byte); needs to be > 0 for ethernet size tables:"
msgstr "最小数据包大小MPUbyte; 在以太网中需要>0"
#: usr/lib/lua/luci/model/cbi/sqm.lua:242
msgid "Which linklayer adaptation mechanism to use; for testing only"
msgstr "使用哪个链路适应机制; 仅用于测试"

View 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

Binary file not shown.

View 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);
}

View 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;
}
}
}

View 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