optimize luci speed

This commit is contained in:
LEAN-ESX 2019-09-22 08:26:02 -07:00
parent fd6fdb2cc7
commit 700edad596
159 changed files with 7213 additions and 9135 deletions

View File

@ -1,30 +0,0 @@
#!/usr/bin/env bash
[ -d build ] || {
echo "Execute as ./build/check-controllers.sh" >&2
exit 1
}
find . -type f -name '*.lua' -path '*/controller/*' | while read controller; do
controller="${controller#./}"
base="${controller%%/controller/*}"
sed -rne 's#^.*\b(cbi|form)\([[:space:]]*("([^"]*)"|\047([^\047]*)\047)[[:space:]]*[,)].*$#\1 \3\4#gp' "$controller" | while read type map; do
model="$base/model/cbi/$map.lua"
package="${controller##*/controller/}"; package="${package%.lua}"; package="luci.controller.${package//\//.}"
if ! grep -sqE '\bmodule[[:space:]]*\(?[[:space:]]*("|\047|\[=*\[)'"$package" "$controller"; then
echo "'$controller' does not containt the expected\n\t'module(\"$package\", ...)' line.\n"
fi
grep -sqE '\b(Form|SimpleForm)[[:space:]]*\(' "$model" && ! grep -sqE '\bMap[[:space:]]*\(' "$model" && is_form=1 || is_form=0
if [ ! -f "$model" ]; then
echo -e "'$controller' references $type('$map')\n\tbut expected file '$model' does not exist.\n"
elif [ $type = "cbi" -a $is_form = 1 ]; then
echo -e "'$controller' references $type('$map')\n\tbut '$model' looks like a Form or SimpleForm.\n"
elif [ $type = "form" -a $is_form = 0 ]; then
echo -e "'$controller' references $type('$map')\n\tbut '$model' does not look like a Form or SimpleForm.\n"
fi
done
done

View File

@ -0,0 +1,17 @@
#
# Copyright (C) 2008-2014 The LuCI Team <luci@lists.subsignal.org>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TYPE:=col
LUCI_BASENAME:=light
LUCI_TITLE:=Minimum package set using only admin mini and the standard theme
LUCI_DEPENDS:=+uhttpd +luci-mod-admin-mini +luci-theme-openwrt @BROKEN
include ../../luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -33,7 +33,7 @@ config 'defaults' 'ssidscheme'
config 'defaults' 'interface'
option 'netmask' '255.255.255.255'
option 'dns' '85.214.20.141 194.150.168.168 2001:4ce8::53 2001:910:800::12'
option 'dns' '85.214.20.141 213.73.91.35 194.150.168.168 2001:4ce8::53 2001:910:800::12'
config 'dhcp' 'dhcp'
option leasetime '5m'

View File

@ -31,7 +31,7 @@ config 'defaults' 'ssidscheme'
config 'defaults' 'interface'
option 'netmask' '255.255.255.255'
option 'dns' '85.214.20.141 194.150.168.168 2001:4ce8::53 2001:910:800::12'
option 'dns' '85.214.20.141 213.73.91.35 194.150.168.168 2001:4ce8::53 2001:910:800::12'
config 'dhcp' 'dhcp'
option 'leasetime' '5m'

View File

@ -0,0 +1,12 @@
config 'community' 'profile'
option 'name' 'Freifunk Hannover'
option 'homepage' 'http://hannover.freifunk.net'
option 'ssid' 'hannover.freifunk.net'
option 'mesh_network' '10.2.0.0/16'
option 'splash_network' '10.104.0.0/16'
option 'splash_prefix' '27'
option 'latitude' '52.38427'
option 'longitude' '9.74359'
config 'defaults' 'wifi_iface'
option 'bssid' 'CA:FF:EE:CA:FF:EE'

View File

@ -1,7 +1,7 @@
config 'community' 'profile'
option 'name' 'Freifunk Potsdam'
option 'homepage' 'http://potsdam.freifunk.net'
option 'ssid' 'freifunk-potsdam.de'
option 'ssid' 'Freifunk-Potsdam-XXX-YYY'
option 'mesh_network' '10.22.0.0/16'
option 'splash_network' '192.168.22.0/24'
option 'splash_prefix' '24'
@ -11,7 +11,7 @@ config 'community' 'profile'
config 'defaults' 'interface'
option 'netmask' '255.255.0.0'
option 'dns' '85.214.20.141 194.150.168.168'
option 'dns' '85.214.20.141 213.73.91.35 194.150.168.168'
option 'delegate' '0'
config 'defaults' 'wifi_device'

View File

@ -7,4 +7,4 @@ config 'community' 'profile'
option 'splash_prefix' '28'
config 'defaults' 'interface'
option 'dns' '216.87.84.211'
option 'dns' '213.73.91.35 216.87.84.211'

View File

@ -15,7 +15,6 @@ define Package/freifunk-common
CATEGORY:=LuCI
SUBMENU:=9. Freifunk
TITLE:=Freifunk common files
DEPENDS:=+libuci-lua
endef
define Package/freifunk-common/description

View File

@ -0,0 +1,48 @@
#
# Copyright (C) 2009 Andreas Seidler <tetzlav@subsignal.org>
# Copyright (C) 2012 Jo-Philipp Wich <jow@openwrt.org>
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=freifunk-p2pblock
PKG_RELEASE:=3
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
define Package/freifunk-p2pblock
SECTION:=luci
CATEGORY:=LuCI
SUBMENU:=9. Freifunk
TITLE:=Freifunk p2pblock Addon
DEPENDS:=+iptables-mod-filter +iptables-mod-ipp2p +l7-protocols +iptables-mod-conntrack-extra @BROKEN
endef
define Package/freifunk-p2pblock/description
Simple Addon for Freifunk which use iptables layer7-, ipp2p- and recent-modules
to block p2p/filesharing traffic
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/freifunk-p2pblock/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/freifunk-p2pblock.init $(1)/etc/init.d/freifunk-p2pblock
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DATA) ./files/freifunk-p2pblock.config $(1)/etc/config/freifunk_p2pblock
endef
$(eval $(call BuildPackage,freifunk-p2pblock))

View File

@ -0,0 +1,6 @@
config 'settings' 'p2pblock'
option 'portrange' '1024:65535'
option 'layer7' 'edonkey bittorrent fasttrack'
option 'ipp2p' 'edk dc kazaa gnu bit ares soul winmx apple'
option 'blocktime' '60'
option 'whitelist' ''

View File

@ -0,0 +1,95 @@
#!/bin/sh /etc/rc.common
START=82
ME="freifunk-p2pblock"
LOCK='/var/run/p2pblock.lock'
# helper-scripts
ipt_add() {
logger -t "$ME" "set 'iptables -I $1'"
iptables -I $1
echo "iptables -D $1" >> $LOCK
}
start() {
/etc/init.d/freifunk-p2pblock enabled || return
if [ ! -s "$LOCK" ]; then
logger -s -t "$ME" 'starting p2pblock...'
config_load network
config_get wan wan ifname
if [ -n "$wan" ]; then
config_load freifunk_p2pblock
config_get layer7 p2pblock layer7
config_get ipp2p p2pblock ipp2p
config_get portrange p2pblock portrange
config_get blocktime p2pblock blocktime
config_get whitelist p2pblock whitelist
# load modules
insmod ipt_ipp2p 2>&-
insmod ipt_layer7 2>&-
insmod ipt_recent ip_list_tot=400 ip_pkt_list_tot=3 2>&-
# create new p2p-chain
iptables -N p2pblock
# pipe all incoming FORWARD with source-/destination-port 1024-65535 throu p2p-chain
ipt_add "FORWARD -i $wan -p tcp --sport $portrange --dport $portrange -j p2pblock"
ipt_add "FORWARD -i $wan -p udp --sport $portrange --dport $portrange -j p2pblock"
# if p2p-traffic blocked 3 packages to a destination ip then block all traffic within the next 180 sec (port 1024-65535)
ipt_add "p2pblock -m recent --rdest --rcheck --name P2PBLOCK --seconds $blocktime --hitcount 3 -j DROP"
ipt_add "p2pblock -m recent --rdest --rcheck --name P2PBLOCK --seconds $blocktime --hitcount 3 -m limit --limit 1/minute -j LOG --log-prefix P2PBLOCK-DROP:"
# create layer7-rules
for proto in $layer7; do
ipt_add "p2pblock -m layer7 --l7proto $proto -m recent --rdest --set --name P2PBLOCK"
ipt_add "p2pblock -m layer7 --l7proto $proto -m limit --limit 1/minute -j LOG --log-prefix P2PBLOCK-seen-$proto:"
done
# create ipp2p-rules
for proto in $ipp2p; do
ipt_add "p2pblock -m ipp2p --$proto -m recent --rdest --set --name P2PBLOCK"
ipt_add "p2pblock -m ipp2p --$proto -m limit --limit 1/minute -j LOG --log-prefix P2PBLOCK-seen-$proto:"
done
# insert whitelisted ips
for ip in $whitelist; do
ipt_add "p2pblock -d $ip -j RETURN"
done
logger -s -t "$ME" 'Done.'; return 0
else
logger -s -t "$ME" 'No wan interface present.'; return 0
fi
else
logger -s -t "$ME" 'WARNING! already running - Aborting!'; return 2
fi
}
stop() {
if [ -s "$LOCK" ]; then
logger -s -t "$ME" 'stopping p2pblock...'
# unset all rules in $LOCK-file
cat $LOCK | sed -ne '1!G;h;$p' | while read line; do
logger -t "$ME" "unset $line"
while eval $line 2>&-; do :; done
done; : > "$LOCK"
# flush and delete the p2p-chain
iptables -F p2pblock
iptables -X p2pblock
logger -s -t "$ME" 'Done.'; return 0
else
logger -s -t "$ME" 'WARNING! not running - Aborting!'; return 2
fi
}
restart() {
stop; sleep 1; start
}

View File

@ -1,54 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=lucihttp
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL=https://github.com/jow-/lucihttp.git
PKG_SOURCE_DATE:=2018-05-18
PKG_SOURCE_VERSION:=cb119deddee5f0f8f1da883b20c60aea7611b175
PKG_MIRROR_HASH:=573a20817c73344b17c8fa1b8112f14af9dccc25fef017ae072ecd09140cf9e1
CMAKE_INSTALL:=1
PKG_LICENSE:=ISC
PKG_LICENSE_FILES:=LICENSE
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
PKG_CONFIG_DEPENDS:=CONFIG_PACKAGE_liblucihttp-lua
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
define Package/liblucihttp
SECTION:=libs
CATEGORY:=Libraries
ABI_VERSION:=$(PKG_VERSION)
TITLE:=LuCI HTTP utility library
endef
define Package/liblucihttp-lua
SECTION:=libs
CATEGORY:=Libraries
DEPENDS:=+liblucihttp +liblua
TITLE:=Lua binding for the LuCI HTTP utility library
endef
TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include
CMAKE_OPTIONS = \
-DLUAPATH=/usr/lib/lua \
-DBUILD_LUA=$(if $(CONFIG_PACKAGE_liblucihttp-lua),ON,OFF) \
-DBUILD_TESTS=OFF
define Package/liblucihttp/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/liblucihttp.so $(1)/usr/lib/
endef
define Package/liblucihttp-lua/install
$(INSTALL_DIR) $(1)/usr/lib/lua
$(CP) $(PKG_INSTALL_DIR)/usr/lib/lua/lucihttp.so $(1)/usr/lib/lua/
endef
$(eval $(call BuildPackage,liblucihttp))
$(eval $(call BuildPackage,liblucihttp-lua))

View File

@ -73,7 +73,7 @@ setup_nameservice() {
uci batch <<- EOF
set $cfg.olsrd_nameservice=LoadPlugin
set $cfg.olsrd_nameservice.library="olsrd_nameservice.so.0.4"
set $cfg.olsrd_nameservice.library="olsrd_nameservice.so.0.3"
set $cfg.olsrd_nameservice.latlon_file="$llfile"
set $cfg.olsrd_nameservice.hosts_file="$hosts"
set $cfg.olsrd_nameservice.sighup_pid_file="/var/run/dnsmasq.pid"
@ -118,7 +118,7 @@ setup_jsoninfo() {
proto="$1"
uci batch <<- EOF
set $cfg.olsrd_jsoninfo=LoadPlugin
set $cfg.olsrd_jsoninfo.library="olsrd_jsoninfo.so.1.1"
set $cfg.olsrd_jsoninfo.library="olsrd_jsoninfo.so.0.0"
EOF
if [ "$proto" = "6" ]; then
uci set $cfg.olsrd_jsoninfo.ipv6only='1'
@ -130,7 +130,7 @@ setup_txtinfo() {
proto="$1"
uci batch <<- EOF
set $cfg.olsrd_txtinfo=LoadPlugin
set $cfg.olsrd_txtinfo.library="olsrd_txtinfo.so.1.1"
set $cfg.olsrd_txtinfo.library="olsrd_txtinfo.so.0.1"
EOF
if [ "$proto" = "6" ]; then
uci set $cfg.olsrd_txtinfo.ipv6only='1'

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="modules/luci.http.date.html">luci.http.date</a>
<a href="modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="modules/luci.http.mime.html">luci.http.mime</a>
<a href="modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>
@ -210,17 +214,22 @@
</tr>
<tr>
<td class="name"><a href="modules/luci.http.conditionals.html">luci.http.conditionals</a></td>
<td class="name"><a href="modules/luci.http.protocol.html">luci.http.protocol</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name"><a href="modules/luci.http.date.html">luci.http.date</a></td>
<td class="name"><a href="modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name"><a href="modules/luci.http.mime.html">luci.http.mime</a></td>
<td class="name"><a href="modules/luci.http.protocol.date.html">luci.http.protocol.date</a></td>
<td class="summary"></td>
</tr>
<tr>
<td class="name"><a href="modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a></td>
<td class="summary"></td>
</tr>

View File

@ -41,15 +41,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>
@ -317,6 +321,7 @@ Create a CBI form model dispatching target.</td>
<td class="summary">
Fetch or create a dispatching node without setting the target module or
enabling the node.</td>
</tr>
@ -327,13 +332,6 @@ enabling the node.</td>
Dispatch an HTTP request.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#lookup">lookup</a>&nbsp;(...)</td>
<td class="summary">
Lookup node in dispatching tree.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#modifier">modifier</a>&nbsp;(func, order)</td>
<td class="summary">
@ -859,8 +857,8 @@ Create a CBI form model dispatching target.
Fetch or create a dispatching node without setting the target module or
enabling the node.
enabling the node.
<h3>Parameters</h3>
@ -911,38 +909,6 @@ Dispatch an HTTP request.
</dd>
<dt><a name="lookup"></a><strong>lookup</strong>&nbsp;(...)</dt>
<dd>
Lookup node in dispatching tree.
<h3>Parameters</h3>
<ul>
<li>
...: Virtual path
</li>
</ul>
<h3>Return value:</h3>
Node object, canonical url or nil if the path was not found.
</dd>

View File

@ -41,15 +41,19 @@
<li><strong>luci.http</strong></li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>
@ -252,6 +256,7 @@ Get the value of a certain HTTP-Cookie.</td>
<td class="summary">
Get the value of a certain HTTP environment variable
or the environment table itself.</td>
</tr>
@ -262,20 +267,6 @@ or the environment table itself.</td>
Send a HTTP-Header.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#mimedecode_message_body">mimedecode_message_body</a>&nbsp;(src, msg, filecb)</td>
<td class="summary">
Decode a mime encoded http message body with multipart/form-data Content-Type.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#parse_message_body">parse_message_body</a>&nbsp;(src, msg, filecb)</td>
<td class="summary">
Try to extract and decode a http message body from the given ltn12 source.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#prepare_content">prepare_content</a>&nbsp;(mime)</td>
<td class="summary">
@ -319,44 +310,6 @@ Splice data from a filedescriptor to the client.</td>
Set the HTTP status code and status message.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#urldecode">urldecode</a>&nbsp;(str, no_plus)</td>
<td class="summary">
Return the URL-decoded equivalent of a string.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#urldecode_message_body">urldecode_message_body</a>&nbsp;(src, msg)</td>
<td class="summary">
Decode an urlencoded http message body with application/x-www-urlencoded
Content-Type.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#urldecode_params">urldecode_params</a>&nbsp;(url, tbl)</td>
<td class="summary">
Extract and split urlencoded data pairs, separated bei either "&" or ";"
from given url or string.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#urlencode">urlencode</a>&nbsp;(str)</td>
<td class="summary">
Return the URL-encoded equivalent of a string.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#urlencode_params">urlencode_params</a>&nbsp;(tbl)</td>
<td class="summary">
Encode each key-value-pair in given table to x-www-urlencoded format,
separated by "&".</td>
</tr>
<tr>
<td class="name" nowrap><a href="#write">write</a>&nbsp;(content, src_err)</td>
<td class="summary">
@ -434,6 +387,7 @@ Close the HTTP-Connection.
</dd>
@ -573,8 +527,8 @@ String containing cookie data
Get the value of a certain HTTP environment variable
or the environment table itself.
or the environment table itself.
<h3>Parameters</h3>
@ -629,135 +583,6 @@ Send a HTTP-Header.
</dd>
<dt><a name="mimedecode_message_body"></a><strong>mimedecode_message_body</strong>&nbsp;(src, msg, filecb)</dt>
<dd>
Decode a mime encoded http message body with multipart/form-data Content-Type.
Stores all extracted data associated with its parameter name
in the params table within the given message object. Multiple parameter
values are stored as tables, ordinary ones as strings.
If an optional file callback function is given then it is feeded with the
file contents chunk by chunk and only the extracted file name is stored
within the params table. The callback function will be called subsequently
with three arguments:
o Table containing decoded (name, file) and raw (headers) mime header data
o String value containing a chunk of the file data
o Boolean which indicates wheather the current chunk is the last one (eof)
<h3>Parameters</h3>
<ul>
<li>
src: Ltn12 source function
</li>
<li>
msg: HTTP message object
</li>
<li>
filecb: File callback function (optional)
</li>
</ul>
<h3>Return values:</h3>
<ol>
<li>Value indicating successful operation (not nil means "ok")
<li>String containing the error if unsuccessful
</ol>
<h3>See also:</h3>
<ul>
<li><a href="">
parse_message_header
</a>
</ul>
</dd>
<dt><a name="parse_message_body"></a><strong>parse_message_body</strong>&nbsp;(src, msg, filecb)</dt>
<dd>
Try to extract and decode a http message body from the given ltn12 source.
This function will examine the Content-Type within the given message object
to select the appropriate content decoder.
Currently the application/x-www-urlencoded and application/form-data
mime types are supported. If the encountered content encoding can't be
handled then the whole message body will be stored unaltered as "content"
property within the given message object.
<h3>Parameters</h3>
<ul>
<li>
src: Ltn12 source function
</li>
<li>
msg: HTTP message object
</li>
<li>
filecb: File data callback (optional, see mimedecode_message_body())
</li>
</ul>
<h3>Return values:</h3>
<ol>
<li>Value indicating successful operation (not nil means "ok")
<li>String containing the error if unsuccessful
</ol>
<h3>See also:</h3>
<ul>
<li><a href="">
parse_message_header
</a>
</ul>
</dd>
@ -934,243 +759,6 @@ Set the HTTP status code and status message.
</dd>
<dt><a name="urldecode"></a><strong>urldecode</strong>&nbsp;(str, no_plus)</dt>
<dd>
Return the URL-decoded equivalent of a string.
<h3>Parameters</h3>
<ul>
<li>
str: URL-encoded string
</li>
<li>
no_plus: Don't decode + to " "
</li>
</ul>
<h3>Return value:</h3>
URL-decoded string
<h3>See also:</h3>
<ul>
<li><a href="#urlencode">
urlencode
</a>
</ul>
</dd>
<dt><a name="urldecode_message_body"></a><strong>urldecode_message_body</strong>&nbsp;(src, msg)</dt>
<dd>
Decode an urlencoded http message body with application/x-www-urlencoded
Content-Type.
Stores all extracted data associated with its parameter name in the params
table within the given message object. Multiple parameter values are stored
as tables, ordinary ones as strings.
<h3>Parameters</h3>
<ul>
<li>
src: Ltn12 source function
</li>
<li>
msg: HTTP message object
</li>
</ul>
<h3>Return values:</h3>
<ol>
<li>Value indicating successful operation (not nil means "ok")
<li>String containing the error if unsuccessful
</ol>
<h3>See also:</h3>
<ul>
<li><a href="">
parse_message_header
</a>
</ul>
</dd>
<dt><a name="urldecode_params"></a><strong>urldecode_params</strong>&nbsp;(url, tbl)</dt>
<dd>
Extract and split urlencoded data pairs, separated bei either "&" or ";"
from given url or string. Returns a table with urldecoded values.
Simple parameters are stored as string values associated with the parameter
name within the table. Parameters with multiple values are stored as array
containing the corresponding values.
<h3>Parameters</h3>
<ul>
<li>
url: The url or string which contains x-www-urlencoded form data
</li>
<li>
tbl: Use the given table for storing values (optional)
</li>
</ul>
<h3>Return value:</h3>
Table containing the urldecoded parameters
<h3>See also:</h3>
<ul>
<li><a href="#urlencode_params">
urlencode_params
</a>
</ul>
</dd>
<dt><a name="urlencode"></a><strong>urlencode</strong>&nbsp;(str)</dt>
<dd>
Return the URL-encoded equivalent of a string.
<h3>Parameters</h3>
<ul>
<li>
str: Source string
</li>
</ul>
<h3>Return value:</h3>
URL-encoded string
<h3>See also:</h3>
<ul>
<li><a href="#urldecode">
urldecode
</a>
</ul>
</dd>
<dt><a name="urlencode_params"></a><strong>urlencode_params</strong>&nbsp;(tbl)</dt>
<dd>
Encode each key-value-pair in given table to x-www-urlencoded format,
separated by "&".
Tables are encoded as parameters with multiple values by repeating the
parameter name with each value.
<h3>Parameters</h3>
<ul>
<li>
tbl: Table with the values
</li>
</ul>
<h3>Return value:</h3>
String containing encoded values
<h3>See also:</h3>
<ul>
<li><a href="#urldecode_params">
urldecode_params
</a>
</ul>
</dd>
@ -1186,7 +774,6 @@ This function is as a valid LTN12 sink.
If the content chunk is nil this function will automatically invoke close.
<h3>Parameters</h3>
<ul>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li><strong>luci.i18n</strong></li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>
@ -252,30 +256,6 @@ Checks whether the CIDR instance is an IPv6 link local address
<td class="summary">
Checks whether the CIDR instance is an IPv6 mapped IPv4 address
</td>
</tr>
<tr>
<td class="name" nowrap><a href="#cidr.ismac">cidr:ismac</a>&nbsp;()</td>
<td class="summary">
Checks whether the CIDR instance is an ethernet MAC address range
</td>
</tr>
<tr>
<td class="name" nowrap><a href="#cidr.ismaclocal">cidr:ismaclocal</a>&nbsp;()</td>
<td class="summary">
Checks whether the CIDR instance is a locally administered (LAA) MAC address
</td>
</tr>
<tr>
<td class="name" nowrap><a href="#cidr.ismacmcast">cidr:ismacmcast</a>&nbsp;()</td>
<td class="summary">
Checks whether the CIDR instance is a multicast MAC address
</td>
</tr>
@ -342,20 +322,6 @@ Derive broadcast address of CIDR instance.</td>
Derive mapped IPv4 address of CIDR instance.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#cidr.tomac">cidr:tomac</a>&nbsp;()</td>
<td class="summary">
Derive MAC address of IPv6 link local CIDR instance.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#cidr.tolinklocal">cidr:tolinklocal</a>&nbsp;()</td>
<td class="summary">
Derive IPv6 link local address from MAC address CIDR instance.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#cidr.contains">cidr:contains</a>&nbsp;(addr)</td>
<td class="summary">
@ -439,10 +405,6 @@ Checks whether the CIDR instance is an IPv4 address range
cidr:is6
</a>
<li><a href="#cidr.ismac">
cidr:ismac
</a>
</ul>
</dd>
@ -537,10 +499,6 @@ Checks whether the CIDR instance is an IPv6 address range
cidr:is4
</a>
<li><a href="#cidr.ismac">
cidr:ismac
</a>
</ul>
</dd>
@ -608,108 +566,13 @@ end</pre>
<dt><a name="cidr.ismac"></a><strong>cidr:ismac</strong>&nbsp;()</dt>
<dd>
Checks whether the CIDR instance is an ethernet MAC address range
<h3>Return value:</h3>
<code>true</code> if the CIDR is a MAC address range, else <code>false</code>
<h3>See also:</h3>
<ul>
<li><a href="#cidr.is4">
cidr:is4
</a>
<li><a href="#cidr.is6">
cidr:is6
</a>
</ul>
</dd>
<dt><a name="cidr.ismaclocal"></a><strong>cidr:ismaclocal</strong>&nbsp;()</dt>
<dd>
Checks whether the CIDR instance is a locally administered (LAA) MAC address
<h3>Usage:</h3>
<pre>local mac = luci.ip.new("02:C0:FF:EE:00:01")
if mac:ismaclocal() then
print("Is an LAA MAC address")
end</pre>
<h3>Return value:</h3>
<code>true</code> if the MAC address sets the locally administered bit.
</dd>
<dt><a name="cidr.ismacmcast"></a><strong>cidr:ismacmcast</strong>&nbsp;()</dt>
<dd>
Checks whether the CIDR instance is a multicast MAC address
<h3>Usage:</h3>
<pre>local mac = luci.ip.new("01:00:5E:7F:00:10")
if addr:ismacmcast() then
print("Is a multicast MAC address")
end</pre>
<h3>Return value:</h3>
<code>true</code> if the MAC address sets the multicast bit.
</dd>
<dt><a name="cidr.lower"></a><strong>cidr:lower</strong>&nbsp;(addr)</dt>
<dd>
Checks whether this CIDR instance is lower than the given argument.
The comparisation follows these rules:
<ul><li>An IPv4 address is always lower than an IPv6 address and IPv6 addresses
are considered lower than MAC addresses</li>
<ul><li>An IPv4 address is always lower than an IPv6 address</li>
<li>Prefix sizes are ignored</li></ul>
@ -732,8 +595,7 @@ are considered lower than MAC addresses</li>
print(addr:lower(addr)) -- false
print(addr:lower("10.10.10.10/24")) -- false
print(addr:lower(luci.ip.new("::1"))) -- true
print(addr:lower(luci.ip.new("192.168.200.1"))) -- true
print(addr:lower(luci.ip.new("00:14:22:01:23:45"))) -- true</pre>
print(addr:lower(luci.ip.new("192.168.200.1"))) -- true</pre>
@ -767,8 +629,7 @@ print(addr:lower(luci.ip.new("00:14:22:01:23:45"))) -- true</pre>
Checks whether this CIDR instance is higher than the given argument.
The comparisation follows these rules:
<ul><li>An IPv4 address is always lower than an IPv6 address and IPv6 addresses
are considered lower than MAC addresses</li>
<ul><li>An IPv4 address is always lower than an IPv6 address</li>
<li>Prefix sizes are ignored</li></ul>
@ -791,8 +652,7 @@ are considered lower than MAC addresses</li>
print(addr:higher(addr)) -- false
print(addr:higher("10.10.10.10/24")) -- true
print(addr:higher(luci.ip.new("::1"))) -- false
print(addr:higher(luci.ip.new("192.168.200.1"))) -- false
print(addr:higher(luci.ip.new("00:14:22:01:23:45"))) -- false</pre>
print(addr:higher(luci.ip.new("192.168.200.1"))) -- false</pre>
@ -849,11 +709,7 @@ print(addr:equal(luci.ip.new("::1"))) -- false
local addr6 = luci.ip.new("::1")
print(addr6:equal("0:0:0:0:0:0:0:1/64")) -- true
print(addr6:equal(luci.ip.new("fe80::221:63ff:fe75:aa17"))) -- false
local mac = luci.ip.new("00:14:22:01:23:45")
print(mac:equal("0:14:22:1:23:45")) -- true
print(mac:equal(luci.ip.new("01:23:45:67:89:AB")) -- false</pre>
print(addr6:equal(luci.ip.new("fe80::221:63ff:fe75:aa17"))) -- false</pre>
@ -896,8 +752,8 @@ else the current prefix size is returned.
<li>
mask: Either a number containing the number of bits (<code>0..32</code>
for IPv4, <code>0..128</code> for IPv6 or <code>0..48</code> for MAC addresses) or a string
containing a valid netmask (optional)
for IPv4, <code>0..128</code> for IPv6) or a string containing a valid
netmask (optional)
</li>
</ul>
@ -944,8 +800,8 @@ optional mask parameter.
<li>
mask: Either a number containing the number of bits (<code>0..32</code>
for IPv4, <code>0..128</code> for IPv6 or <code>0..48</code> for MAC addresses) or a string
containing a valid netmask (optional)
for IPv4, <code>0..128</code> for IPv6) or a string containing a valid
netmask (optional)
</li>
</ul>
@ -981,7 +837,7 @@ CIDR instance representing the network address
Derive host address of CIDR instance.
This function essentially constructs a copy of this CIDR with the prefix size
set to <code>32</code> for IPv4, <code>128</code> for IPv6 or <code>48</code> for MAC addresses.
set to <code>32</code> for IPv4 and <code>128</code> for IPv6.
@ -1021,8 +877,8 @@ prefix size can be overridden by the optional mask parameter.
<li>
mask: Either a number containing the number of bits (<code>0..32</code>
for IPv4, <code>0..128</code> for IPv6 or <code>0..48</code> for MAC addresses) or a string
containing a valid netmask (optional)
for IPv4, <code>0..128</code> for IPv6) or a string containing a valid
netmask (optional)
</li>
</ul>
@ -1057,8 +913,8 @@ Derive broadcast address of CIDR instance.
Constructs a CIDR instance representing the broadcast address of this instance.
The used prefix size can be overridden by the optional mask parameter.
This function has no effect on IPv6 or MAC address instances, it will return
nothing in this case.
This function has no effect on IPv6 instances, it will return nothing in this
case.
@ -1066,8 +922,9 @@ nothing in this case.
<ul>
<li>
mask: Either a number containing the number of bits (<code>0..32</code> for IPv4) or
a string containing a valid netmask (optional)
mask: Either a number containing the number of bits (<code>0..32</code>
for IPv4, <code>0..128</code> for IPv6) or a string containing a valid
netmask (optional)
</li>
</ul>
@ -1103,8 +960,8 @@ Derive mapped IPv4 address of CIDR instance.
Constructs a CIDR instance representing the IPv4 address of the IPv6 mapped
IPv4 address in this instance.
This function has no effect on IPv4 instances, MAC address instances or IPv6
instances which are not a mapped address, it will return nothing in this case.
This function has no effect on IPv4 instances or IPv6 instances which are not a
mapped address, it will return nothing in this case.
@ -1128,74 +985,6 @@ Return a new CIDR instance representing the IPv4 address if this
<dt><a name="cidr.tomac"></a><strong>cidr:tomac</strong>&nbsp;()</dt>
<dd>
Derive MAC address of IPv6 link local CIDR instance.
Constructs a CIDR instance representing the MAC address contained in the IPv6
link local address of this instance.
This function has no effect on IPv4 instances, MAC address instances or IPv6
instances which are not a link local address, it will return nothing in this
case.
<h3>Usage:</h3>
<pre>local addr = luci.ip.new("fe80::6666:b3ff:fe47:e1b9")
print(addr:tomac()) -- "64:66:B3:47:E1:B9"</pre>
<h3>Return value:</h3>
Return a new CIDR instance representing the MAC address if this
instance is an IPv6 link local address, else return nothing.
</dd>
<dt><a name="cidr.tolinklocal"></a><strong>cidr:tolinklocal</strong>&nbsp;()</dt>
<dd>
Derive IPv6 link local address from MAC address CIDR instance.
Constructs a CIDR instance representing the IPv6 link local address of the
MAC address represented by this instance.
This function has no effect on IPv4 instances or IPv6 instances, it will return
nothing in this case.
<h3>Usage:</h3>
<pre>local mac = luci.ip.new("64:66:B3:47:E1:B9")
print(mac:tolinklocal()) -- "fe80::6666:b3ff:fe47:e1b9"</pre>
<h3>Return value:</h3>
Return a new CIDR instance representing the IPv6 link local address.
</dd>
<dt><a name="cidr.contains"></a><strong>cidr:contains</strong>&nbsp;(addr)</dt>
<dd>
@ -1225,11 +1014,7 @@ print(range:contains("10.0.0.0/8")) -- false
local range6 = luci.ip.new("fe80::/10")
print(range6:contains("fe80::221:63f:fe75:aa17/64")) -- true
print(range6:contains("fd9b:6b3:c5:0:221:63f:fe75:aa17/64")) -- false
local intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00/24")
print(intel_macs:contains("C0:B6:F9:A3:C:11")) -- true
print(intel_macs:contains("64:66:B3:47:E1:B9")) -- false</pre>
print(range6:contains("fd9b:6b3:c5:0:221:63f:fe75:aa17/64")) -- false</pre>
@ -1274,40 +1059,30 @@ address space, the result is set to the highest possible address.
<h3>Usage:</h3>
<pre>local addr = luci.ip.new("192.168.1.1/24")
print(addr:add(250)) -- "192.168.1.251/24"
print(addr:add("0.0.99.0")) -- "192.168.100.1/24"
print(addr:add(250)) -- "192.168.1.251/24"
print(addr:add("0.0.99.0")) -- "192.168.100.1/24"
addr:add(256, true) -- true
print(addr) -- "192.168.2.1/24
addr:add(256, true) -- true
print(addr) -- "192.168.2.1/24
addr:add("255.0.0.0", true) -- false (overflow)
print(addr) -- "255.255.255.255/24
addr:add("255.0.0.0", true) -- false (overflow)
print(addr) -- "255.255.255.255/24
local addr6 = luci.ip.new("fe80::221:63f:fe75:aa17/64")
print(addr6:add(256)) -- "fe80::221:63f:fe75:ab17/64"
print(addr6:add("::ffff:0")) -- "fe80::221:640:fe74:aa17/64"
print(addr6:add(256)) -- "fe80::221:63f:fe75:ab17/64"
print(addr6:add("::ffff:0")) -- "fe80::221:640:fe74:aa17/64"
addr6:add(256, true) -- true
print(addr6) -- "fe80::221:63f:fe75:ab17/64
addr:add(256, true) -- true
print(addr) -- "fe80::221:63f:fe75:ab17/64
addr6:add("ffff::", true) -- false (overflow)
print(addr6) -- "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64"
local mac = luci.ip.new("00:14:22:01:23:45")
print(mac:add(256)) -- "00:14:22:01:24:45"
print(mac:add("0:0:0:0:FF:0") -- "00:14:22:02:22:45"
mac:add(256, true) -- true
print(mac) -- "00:14:22:01:24:45"
mac:add("FF:FF:0:0:0:0", true) -- false (overflow)
print(mac) -- "FF:FF:FF:FF:FF:FF"</pre>
addr:add("ffff::", true) -- false (overflow)
print(addr) -- "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64"</pre>
<h3>Return value:</h3>
<ul>
<li>When adding inplace: Return <code>true</code> if the addition succeded
<li>When adding inplace: Return <code>true</code> if the addition succeeded
or <code>false</code> when the addition overflowed.</li>
<li>When deriving new CIDR: Return new instance representing the value of
this instance plus the added amount or the highest possible address if
@ -1367,17 +1142,7 @@ addr:sub(256, true) -- true
print(addr) -- "fe80::221:63f:fe75:a917/64"
addr:sub("ffff::", true) -- false (underflow)
print(addr) -- "::/64"
local mac = luci.ip.new("00:14:22:01:23:45")
print(mac:sub(256)) -- "00:14:22:01:22:45"
print(mac:sub("0:0:0:0:FF:0") -- "00:14:22:00:24:45"
mac:sub(256, true) -- true
print(mac) -- "00:14:22:01:22:45"
mac:sub("FF:FF:0:0:0:0", true) -- false (overflow)
print(mac) -- "00:00:00:00:00:00"</pre>
print(addr) -- "::/64"</pre>
@ -1412,10 +1177,7 @@ Calculate the lowest possible host address within this CIDR instance.
print(addr:minhost()) -- "192.168.123.1"
local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
print(addr6:minhost()) -- "fd9b:62b3:9cc5::1"
local mac = luci.ip.new("00:14:22:01:22:45/32")
print(mac:minhost()) -- "00:14:22:01:00:01"</pre>
print(addr6:minhost()) -- "fd9b:62b3:9cc5::1"</pre>
@ -1446,10 +1208,7 @@ Calculate the highest possible host address within this CIDR instance.
print(addr:maxhost()) -- "192.168.123.254" (.255 is broadcast)
local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
print(addr6:maxhost()) -- "fd9b:62b3:9cc5:0:ffff:ffff:ffff:ffff"
local mac = luci.ip.new("00:14:22:01:22:45/32")
print(mac:maxhost()) -- "00:14:22:01:FF:FF"</pre>
print(addr6:maxhost()) -- "fd9b:62b3:9cc5:0:ffff:ffff:ffff:ffff"</pre>
@ -1470,9 +1229,8 @@ Returns a new CIDR instance representing the highest host address
Convert CIDR instance into string representation.
If the prefix size of instance is less than 32 for IPv4, 128 for IPv6 or 48 for
MACs, the address is returned in the form "address/prefix" otherwise just
"address".
If the prefix size of instance is less than 32 for IPv4 or 128 for IPv6, the
address is returned in the form "address/prefix" otherwise just "address".
It is usually not required to call this function directly as CIDR objects
define it as __tostring function in the associated metatable.

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>
@ -227,34 +231,6 @@ Construct a new IPv4 luci.ip.cidr instance.</td>
Construct a new IPv6 luci.ip.cidr instance.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#MAC">MAC</a>&nbsp;(address, netmask)</td>
<td class="summary">
Construct a new MAC luci.ip.cidr instance.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#checkip4">checkip4</a>&nbsp;(address)</td>
<td class="summary">
Verify an IPv4 address.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#checkip6">checkip6</a>&nbsp;(address)</td>
<td class="summary">
Verify an IPv6 address.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#checkmac">checkmac</a>&nbsp;(address)</td>
<td class="summary">
Verify an ethernet MAC address.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#route">route</a>&nbsp;(address)</td>
<td class="summary">
@ -358,10 +334,6 @@ address/mask range.
IPv6
</a>
<li><a href="#MAC">
MAC
</a>
</ul>
</dd>
@ -417,10 +389,6 @@ A <code>luci.ip.cidr</code> object representing the given IPv4 range.
IPv6
</a>
<li><a href="#MAC">
MAC
</a>
</ul>
</dd>
@ -476,252 +444,6 @@ A <code>luci.ip.cidr</code> object representing the given IPv6 range.
IPv4
</a>
<li><a href="#MAC">
MAC
</a>
</ul>
</dd>
<dt><a name="MAC"></a><strong>MAC</strong>&nbsp;(address, netmask)</dt>
<dd>
Construct a new MAC luci.ip.cidr instance.
Throws an error if the given string does not represent a valid ethernet MAC
address or if the given optional mask is of a different family.
<h3>Parameters</h3>
<ul>
<li>
address: String containing a valid ethernet MAC address, optionally with
prefix size (CIDR notation) or mask separated by slash.
</li>
<li>
netmask: String containing a valid MAC address mask or number
containing a prefix size between <code>0</code> and <code>48</code> bit.
Overrides mask embedded in the first argument if specified. (optional)
</li>
</ul>
<h3>Usage:</h3>
<pre>intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00/24")
intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00/FF:FF:FF:0:0:0")
intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00", "FF:FF:FF:0:0:0")
intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00/24", 48) -- override mask</pre>
<h3>Return value:</h3>
A <code>luci.ip.cidr</code> object representing the given MAC address range.
<h3>See also:</h3>
<ul>
<li><a href="#IPv4">
IPv4
</a>
<li><a href="#IPv6">
IPv6
</a>
</ul>
</dd>
<dt><a name="checkip4"></a><strong>checkip4</strong>&nbsp;(address)</dt>
<dd>
Verify an IPv4 address.
Checks whether given argument is a preexisting luci.ip.cidr IPv4 address
instance or a string literal convertible to an IPv4 address and returns a
plain Lua string containing the canonical representation of the address.
If the argument is not a valid address, returns nothing. This function is
intended to aid in safely verifying address literals without having to deal
with exceptions.
<h3>Parameters</h3>
<ul>
<li>
address: String containing a valid IPv4 address or existing
luci.ip.cidr IPv4 instance.
</li>
</ul>
<h3>Usage:</h3>
<pre>ipv4 = luci.ip.checkip4(luci.ip.new("127.0.0.1")) -- "127.0.0.1"
ipv4 = luci.ip.checkip4("127.0.0.1") -- "127.0.0.1"
ipv4 = luci.ip.checkip4("nonesense") -- nothing
ipv4 = luci.ip.checkip4(123) -- nothing
ipv4 = luci.ip.checkip4(nil) -- nothing
ipv4 = luci.ip.checkip4() -- nothing</pre>
<h3>Return value:</h3>
A string representing the given IPv4 address.
<h3>See also:</h3>
<ul>
<li><a href="#checkip6">
checkip6
</a>
<li><a href="#checkmac">
checkmac
</a>
</ul>
</dd>
<dt><a name="checkip6"></a><strong>checkip6</strong>&nbsp;(address)</dt>
<dd>
Verify an IPv6 address.
Checks whether given argument is a preexisting luci.ip.cidr IPv6 address
instance or a string literal convertible to an IPv6 address and returns a
plain Lua string containing the canonical representation of the address.
If the argument is not a valid address, returns nothing. This function is
intended to aid in safely verifying address literals without having to deal
with exceptions.
<h3>Parameters</h3>
<ul>
<li>
address: String containing a valid IPv6 address or existing
luci.ip.cidr IPv6 instance.
</li>
</ul>
<h3>Usage:</h3>
<pre>ipv6 = luci.ip.checkip6(luci.ip.new("0:0:0:0:0:0:0:1")) -- "::1"
ipv6 = luci.ip.checkip6("0:0:0:0:0:0:0:1") -- "::1"
ipv6 = luci.ip.checkip6("nonesense") -- nothing
ipv6 = luci.ip.checkip6(123) -- nothing
ipv6 = luci.ip.checkip6(nil) -- nothing
ipv6 = luci.ip.checkip6() -- nothing</pre>
<h3>Return value:</h3>
A string representing the given IPv6 address.
<h3>See also:</h3>
<ul>
<li><a href="#checkip4">
checkip4
</a>
<li><a href="#checkmac">
checkmac
</a>
</ul>
</dd>
<dt><a name="checkmac"></a><strong>checkmac</strong>&nbsp;(address)</dt>
<dd>
Verify an ethernet MAC address.
Checks whether given argument is a preexisting luci.ip.cidr MAC address
instance or a string literal convertible to an ethernet MAC and returns a
plain Lua string containing the canonical representation of the address.
If the argument is not a valid address, returns nothing. This function is
intended to aid in safely verifying address literals without having to deal
with exceptions.
<h3>Parameters</h3>
<ul>
<li>
address: String containing a valid MAC address or existing luci.ip.cidr
MAC address instance.
</li>
</ul>
<h3>Usage:</h3>
<pre>mac = luci.ip.checkmac(luci.ip.new("00-11-22-cc-dd-ee")) -- "00:11:22:CC:DD:EE"
mac = luci.ip.checkmac("00:11:22:cc:dd:ee") -- "00:11:22:CC:DD:EE"
mac = luci.ip.checkmac("nonesense") -- nothing
mac = luci.ip.checkmac(123) -- nothing
mac = luci.ip.checkmac(nil) -- nothing
mac = luci.ip.checkmac() -- nothing</pre>
<h3>Return value:</h3>
A string representing the given MAC address.
<h3>See also:</h3>
<ul>
<li><a href="#checkip4">
checkip4
</a>
<li><a href="#checkip6">
checkip6
</a>
</ul>
</dd>
@ -1065,7 +787,7 @@ A neighbour entry is a table containing the following fields:
</tr>
<tr>
<td><code>mac</code></td>
<td>MAC address <code>luci.ip.cidr</code> instance</td>
<td>String containing the associated MAC address</td>
</tr>
<tr>
<td><code>router</code></td>
@ -1183,8 +905,8 @@ described below is returned, else an empty table.
</tr>
<tr>
<td><code>mac</code></td>
<td>MAC address <code>luci.ip.cidr</code> instance representing the device ethernet
address</td>
<td>String containing the link local address of the device in
dotted hex notation</td>
</tr>
</table>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>
@ -305,13 +309,6 @@ Get an option or list and return values as table.</td>
Get the directory for uncomitted changes.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#Cursor.get_session_id">Cursor:get_session_id</a>&nbsp;()</td>
<td class="summary">
Get the effective session ID.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#Cursor.load">Cursor:load</a>&nbsp;(config)</td>
<td class="summary">
@ -368,13 +365,6 @@ Set given values as list.</td>
Set the directory for uncommited changes.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#Cursor.set_session_id">Cursor:set_session_id</a>&nbsp;(id)</td>
<td class="summary">
Set the effective session ID.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#Cursor.substate">Cursor:substate</a>&nbsp;()</td>
<td class="summary">
@ -641,8 +631,8 @@ Delete all sections of a given type that match certain criteria.
</li>
<li>
comparator: Function that will be called for each section and returns
a boolean whether to delete the current section (optional)
comparator: Function that will be called for each section and
returns a boolean whether to delete the current section (optional)
</li>
</ul>
@ -913,8 +903,8 @@ Get an option or list and return values as table.
<h3>Return value:</h3>
table. If the option was not found, you will simply get an empty
table.
table. If the option was not found, you will simply get
an empty table.
@ -946,29 +936,6 @@ Save directory
<dt><a name="Cursor.get_session_id"></a><strong>Cursor:get_session_id</strong>&nbsp;()</dt>
<dd>
Get the effective session ID.
<h3>Return value:</h3>
String containing the session ID
</dd>
<dt><a name="Cursor.load"></a><strong>Cursor:load</strong>&nbsp;(config)</dt>
<dd>
@ -1255,8 +1222,7 @@ has the same effect as deleting the option.
</li>
<li>
value: Value or table. Non-table values will be set as single
item UCI list.
value: value or table. Raw values will become a single item table.
</li>
</ul>
@ -1298,38 +1264,6 @@ Set the directory for uncommited changes.
<h3>Return value:</h3>
Boolean whether operation succeeded
</dd>
<dt><a name="Cursor.set_session_id"></a><strong>Cursor:set_session_id</strong>&nbsp;(id)</dt>
<dd>
Set the effective session ID.
<h3>Parameters</h3>
<ul>
<li>
id: String containing the session ID to set
</li>
</ul>
<h3>Return value:</h3>
Boolean whether operation succeeded
@ -1344,11 +1278,10 @@ Boolean whether operation succeeded
<dd>
Create a sub-state of this cursor.
The sub-state is tied to the parent curser, means it the parent unloads or
loads configs, the sub state will do so as well.
Create a sub-state of this cursor. The sub-state is tied to the parent
curser, means it the parent unloads or loads configs, the sub state will
do so as well.

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>
@ -270,6 +274,13 @@ This is a coroutine-safe drop-in replacement for Lua's "xpcall"-function
</td>
</tr>
<tr>
<td class="name" nowrap><a href="#dtable">dtable</a>&nbsp;()</td>
<td class="summary">
Create a dynamic table which automatically creates subtables.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#dumptable">dumptable</a>&nbsp;(t, maxdepth)</td>
<td class="summary">
@ -338,6 +349,7 @@ Returns the absolute path to LuCI base directory.</td>
<td class="summary">
Parse certain units from the given string and return the canonical integer
value or 0 if the unit is unknown.</td>
</tr>
@ -367,6 +379,7 @@ Restore data previously serialized with serialize_data().</td>
<td class="summary">
Recursively serialize given data to lua code, suitable for restoring
with loadstring().</td>
</tr>
@ -378,18 +391,12 @@ Convert data structure to JSON
</td>
</tr>
<tr>
<td class="name" nowrap><a href="#shellquote">shellquote</a>&nbsp;(value)</td>
<td class="summary">
Safely quote value for use in shell commands.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#spairs">spairs</a>&nbsp;(t, f)</td>
<td class="summary">
Return a key, value iterator which returns the values sorted according to
the provided callback function.</td>
</tr>
@ -398,6 +405,7 @@ the provided callback function.</td>
<td class="summary">
Splits given string on a defined separator sequence and return a table
containing the resulting substrings.</td>
</tr>
@ -420,6 +428,7 @@ Strip HTML tags from given string.</td>
<td class="summary">
Create a new or get an already existing thread local store associated with
the current active coroutine.</td>
</tr>
@ -444,20 +453,6 @@ Issue an ubus call.</td>
Update values in given table with the values from the second given table.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#urldecode">urldecode</a>&nbsp;(str, decode_plus)</td>
<td class="summary">
Decode an URL-encoded string - optionally decoding the "+" sign to space.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#urlencode">urlencode</a>&nbsp;(str)</td>
<td class="summary">
URL-encode given string.</td>
</tr>
<tr>
<td class="name" nowrap><a href="#vspairs">vspairs</a>&nbsp;(t)</td>
<td class="summary">
@ -557,7 +552,6 @@ The __init__ function must be used to set any object parameters that are not sha
with other objects of this class. Any return values will be ignored.
<h3>Parameters</h3>
<ul>
@ -734,8 +728,8 @@ Checks whether the given table contains the given value.
<h3>Return value:</h3>
Number indicating the first index at which the given value occurs
within table or false.
number indicating the first index at which the given value occurs
within table or false.
@ -772,7 +766,7 @@ This is a coroutine-safe drop-in replacement for Lua's "pcall"-function
<h3>Return value:</h3>
A boolean whether the function call succeeded and the returns
values of the function or the error object
values of the function or the error object
@ -813,7 +807,30 @@ This is a coroutine-safe drop-in replacement for Lua's "xpcall"-function
<h3>Return value:</h3>
A boolean whether the function call succeeded and the return
values of either the function or the error handler
values of either the function or the error handler
</dd>
<dt><a name="dtable"></a><strong>dtable</strong>&nbsp;()</dt>
<dd>
Create a dynamic table which automatically creates subtables.
<h3>Return value:</h3>
Dynamic Table
@ -927,8 +944,8 @@ Iterator
Return the current runtime bytecode of the given data. The byte code
will be stripped before it is returned.
will be stripped before it is returned.
<h3>Parameters</h3>
@ -959,12 +976,11 @@ String value containing the bytecode of the given data
<dd>
Return a matching iterator for the given value.
The iterator will return one token per invocation, the tokens are separated by
whitespace. If the input value is a table, it is transformed into a string first.
A nil value will result in a valid interator which aborts with the first invocation.
Return a matching iterator for the given value. The iterator will return
one token per invocation, the tokens are separated by whitespace. If the
input value is a table, it is transformed into a string first. A nil value
will result in a valid interator which aborts with the first invocation.
<h3>Parameters</h3>
@ -1081,7 +1097,6 @@ Return a key, value iterator for the given table.
The table pairs are sorted by key.
<h3>Parameters</h3>
<ul>
@ -1134,11 +1149,9 @@ String containing the directory path
Parse certain units from the given string and return the canonical integer
value or 0 if the unit is unknown.
Upper- or lower case is irrelevant.
value or 0 if the unit is unknown. Upper- or lower case is irrelevant.
Recognized units are:
o "y" - one year (60*60*24*366)
o "m" - one month (60*60*24*31)
o "w" - one week (60*60*24*7)
@ -1153,7 +1166,6 @@ Recognized units are:
o "gib" - one si gigabyte (1000*1000*1000)
<h3>Parameters</h3>
<ul>
@ -1292,8 +1304,8 @@ Value containing the restored data structure
Recursively serialize given data to lua code, suitable for restoring
with loadstring().
with loadstring().
<h3>Parameters</h3>
@ -1369,45 +1381,13 @@ String containing the JSON if called without write callback
<dt><a name="shellquote"></a><strong>shellquote</strong>&nbsp;(value)</dt>
<dd>
Safely quote value for use in shell commands.
<h3>Parameters</h3>
<ul>
<li>
value: String containing the value to quote
</li>
</ul>
<h3>Return value:</h3>
Single-quote enclosed string with embedded quotes escaped
</dd>
<dt><a name="spairs"></a><strong>spairs</strong>&nbsp;(t, f)</dt>
<dd>
Return a key, value iterator which returns the values sorted according to
the provided callback function.
the provided callback function.
<h3>Parameters</h3>
@ -1443,13 +1423,11 @@ Function value containing the corresponding iterator
Splits given string on a defined separator sequence and return a table
containing the resulting substrings.
The optional max parameter specifies the number of bytes to process,
regardless of the actual length of the given string. The optional last
parameter, regex, specifies whether the separator sequence is
nterpreted as regular expression.
containing the resulting substrings. The optional max parameter specifies
the number of bytes to process, regardless of the actual length of the given
string. The optional last parameter, regex, specifies whether the separator
sequence is interpreted as regular expression.
<h3>Parameters</h3>
@ -1493,11 +1471,10 @@ Table containing the resulting substrings
<dd>
Strips unnescessary lua bytecode from given string.
Information like line numbers and debugging numbers will be discarded.
Original version by Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html)
Strips unnescessary lua bytecode from given string. Information like line
numbers and debugging numbers will be discarded. Original version by
Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html)
<h3>Parameters</h3>
@ -1561,9 +1538,8 @@ String with HTML tags stripped of
Create a new or get an already existing thread local store associated with
the current active coroutine.
A thread local store is private a table object
the current active coroutine. A thread local store is private a table object
whose values can't be accessed from outside of the running coroutine.
@ -1572,7 +1548,6 @@ whose values can't be accessed from outside of the running coroutine.
<h3>Return value:</h3>
Table value representing the corresponding thread local store
@ -1664,7 +1639,6 @@ Update values in given table with the values from the second given table.
Both table are - in fact - merged together.
<h3>Parameters</h3>
<ul>
@ -1693,92 +1667,6 @@ Always nil
<dt><a name="urldecode"></a><strong>urldecode</strong>&nbsp;(str, decode_plus)</dt>
<dd>
Decode an URL-encoded string - optionally decoding the "+" sign to space.
<h3>Parameters</h3>
<ul>
<li>
str: Input string in x-www-urlencoded format
</li>
<li>
decode_plus: Decode "+" signs to spaces if true (optional)
</li>
</ul>
<h3>Return value:</h3>
The decoded string
<h3>See also:</h3>
<ul>
<li><a href="#urlencode">
urlencode
</a>
</ul>
</dd>
<dt><a name="urlencode"></a><strong>urlencode</strong>&nbsp;(str)</dt>
<dd>
URL-encode given string.
<h3>Parameters</h3>
<ul>
<li>
str: String to encode
</li>
</ul>
<h3>Return value:</h3>
String containing the encoded data
<h3>See also:</h3>
<ul>
<li><a href="#urldecode">
urldecode
</a>
</ul>
</dd>
<dt><a name="vspairs"></a><strong>vspairs</strong>&nbsp;(t)</dt>
<dd>
@ -1788,7 +1676,6 @@ Return a key, value iterator for the given table.
The table pairs are sorted by value.
<h3>Parameters</h3>
<ul>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>
@ -292,7 +296,7 @@
<li>If the name is significantly different from the POSIX-function, the
underlying function(s) are stated in the documentation.</li>
<li>Parameters should reflect those of the C-API, buffer length arguments and
by-reference parameters should be omitted for practical purposes.</li>
by-reference parameters should be omitted for pratical purposes.</li>
<li>If a C function accepts a bitfield as parameter, it should be translated
into lower case string flags representing the flags if the bitfield is the
last parameter and also omitting prefixes or suffixes. (e.g. waitpid

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>
@ -1270,7 +1274,7 @@ true
<h3>Usage:</h3>
It is normally not possible to rename files across filesystems.
It is normally not possible to rename files across fileystems.

View File

@ -43,15 +43,19 @@
</li>
<li>
<a href="../modules/luci.http.conditionals.html">luci.http.conditionals</a>
<a href="../modules/luci.http.protocol.html">luci.http.protocol</a>
</li>
<li>
<a href="../modules/luci.http.date.html">luci.http.date</a>
<a href="../modules/luci.http.protocol.conditionals.html">luci.http.protocol.conditionals</a>
</li>
<li>
<a href="../modules/luci.http.mime.html">luci.http.mime</a>
<a href="../modules/luci.http.protocol.date.html">luci.http.protocol.date</a>
</li>
<li>
<a href="../modules/luci.http.protocol.mime.html">luci.http.protocol.mime</a>
</li>
<li>

View File

@ -7,7 +7,7 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=HTTP(S) client library
LUCI_DEPENDS:=+luci-base +luci-lib-nixio +luci-lib-httpprotoutils
LUCI_DEPENDS:=+luci-base +luci-lib-nixio
include ../../luci.mk

View File

@ -7,8 +7,8 @@ local nixio = require "nixio"
local ltn12 = require "luci.ltn12"
local util = require "luci.util"
local table = require "table"
local http = require "luci.http"
local date = require "luci.http.date"
local http = require "luci.http.protocol"
local date = require "luci.http.protocol.date"
local type, pairs, ipairs, tonumber = type, pairs, ipairs, tonumber
local unpack = unpack

View File

@ -1,14 +0,0 @@
#
# Copyright (C) 2018 The LuCI Team <luci@lists.subsignal.org>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=HTTP protocol utility functions
LUCI_DEPENDS:=+luci-base
include ../../luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -1,5 +1,5 @@
/*
Copyright 2015-2018 Jo-Philipp Wich <jo@mein.io>
Copyright 2015 Jo-Philipp Wich <jow@openwrt.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -42,16 +42,6 @@ limitations under the License.
#define RTA_INT(x) (*(int *)RTA_DATA(x))
#define RTA_U32(x) (*(uint32_t *)RTA_DATA(x))
#define AF_BITS(f) \
((f) == AF_INET ? 32 : \
((f) == AF_INET6 ? 128 : \
((f) == AF_PACKET ? 48 : 0)))
#define AF_BYTES(f) \
((f) == AF_INET ? 4 : \
((f) == AF_INET6 ? 16 : \
((f) == AF_PACKET ? 6 : 0)))
static int hz = 0;
static struct nl_sock *sock = NULL;
@ -59,11 +49,11 @@ typedef struct {
union {
struct in_addr v4;
struct in6_addr v6;
struct ether_addr mac;
uint8_t u8[16];
} addr;
uint16_t family;
int16_t bits;
int len;
int bits;
int family;
bool exact;
} cidr_t;
struct dump_filter {
@ -80,8 +70,6 @@ struct dump_filter {
cidr_t src;
cidr_t dst;
struct ether_addr mac;
bool from_exact;
bool dst_exact;
};
struct dump_state {
@ -107,68 +95,29 @@ static cidr_t *L_checkcidr (lua_State *L, int index, cidr_t *p)
return NULL;
}
static bool parse_mac(const char *mac, struct ether_addr *ea)
{
unsigned long int n;
char *e, sep = 0;
int i;
for (i = 0; i < 6; i++)
{
if (i > 0)
{
if (sep == 0 && (mac[0] == ':' || mac[0] == '-'))
sep = mac[0];
if (sep == 0 || mac[0] != sep)
return false;
mac++;
}
n = strtoul(mac, &e, 16);
if (n > 0xFF)
return false;
mac += (e - mac);
ea->ether_addr_octet[i] = n;
}
if (mac[0] != 0)
return false;
return true;
}
static bool parse_mask(int family, const char *mask, int16_t *bits)
static bool parse_mask(int family, const char *mask, int *bits)
{
char *e;
union {
struct in_addr v4;
struct in6_addr v6;
struct ether_addr mac;
uint8_t u8[16];
} m;
struct in_addr m;
struct in6_addr m6;
if (family == AF_INET && inet_pton(AF_INET, mask, &m.v4))
if (family == AF_INET && inet_pton(AF_INET, mask, &m))
{
for (*bits = 0, m.v4.s_addr = ntohl(m.v4.s_addr);
*bits < AF_BITS(AF_INET) && (m.v4.s_addr << *bits) & 0x80000000;
for (*bits = 0, m.s_addr = ntohl(m.s_addr);
*bits < 32 && (m.s_addr << *bits) & 0x80000000;
++*bits);
}
else if ((family == AF_INET6 && inet_pton(AF_INET6, mask, &m.v6)) ||
(family == AF_PACKET && parse_mac(mask, &m.mac)))
else if (family == AF_INET6 && inet_pton(AF_INET6, mask, &m6))
{
for (*bits = 0;
*bits < AF_BITS(family) && (m.u8[*bits / 8] << (*bits % 8)) & 128;
*bits < 128 && (m6.s6_addr[*bits / 8] << (*bits % 8)) & 128;
++*bits);
}
else
{
*bits = strtoul(mask, &e, 10);
if (e == mask || *e != 0 || *bits > AF_BITS(family))
if (e == mask || *e != 0 || *bits > ((family == AF_INET) ? 32 : 128))
return false;
}
@ -178,6 +127,7 @@ static bool parse_mask(int family, const char *mask, int16_t *bits)
static bool parse_cidr(const char *dest, cidr_t *pp)
{
char *p, buf[INET6_ADDRSTRLEN * 2 + 2];
uint8_t bitlen = 0;
strncpy(buf, dest, sizeof(buf) - 1);
@ -187,11 +137,17 @@ static bool parse_cidr(const char *dest, cidr_t *pp)
*p++ = 0;
if (inet_pton(AF_INET, buf, &pp->addr.v4))
{
bitlen = 32;
pp->family = AF_INET;
pp->len = sizeof(struct in_addr);
}
else if (inet_pton(AF_INET6, buf, &pp->addr.v6))
{
bitlen = 128;
pp->family = AF_INET6;
else if (parse_mac(buf, &pp->addr.mac))
pp->family = AF_PACKET;
pp->len = sizeof(struct in6_addr);
}
else
return false;
@ -202,45 +158,12 @@ static bool parse_cidr(const char *dest, cidr_t *pp)
}
else
{
pp->bits = AF_BITS(pp->family);
pp->bits = bitlen;
}
return true;
}
static int format_cidr(lua_State *L, cidr_t *p)
{
char buf[INET6_ADDRSTRLEN];
if (p->family == AF_PACKET)
{
snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X",
p->addr.mac.ether_addr_octet[0],
p->addr.mac.ether_addr_octet[1],
p->addr.mac.ether_addr_octet[2],
p->addr.mac.ether_addr_octet[3],
p->addr.mac.ether_addr_octet[4],
p->addr.mac.ether_addr_octet[5]);
if (p->bits < AF_BITS(AF_PACKET))
lua_pushfstring(L, "%s/%d", buf, p->bits);
else
lua_pushstring(L, buf);
}
else
{
if (p->bits < AF_BITS(p->family))
lua_pushfstring(L, "%s/%d",
inet_ntop(p->family, &p->addr.v6, buf, sizeof(buf)),
p->bits);
else
lua_pushstring(L,
inet_ntop(p->family, &p->addr.v6, buf, sizeof(buf)));
}
return 1;
}
static int L_getint(lua_State *L, int index, const char *name)
{
int rv = 0;
@ -297,20 +220,16 @@ static void L_setaddr(struct lua_State *L, const char *name,
if (family == AF_INET)
{
p->family = AF_INET;
p->bits = (bits < 0) ? AF_BITS(AF_INET) : bits;
p->bits = (bits < 0) ? 32 : bits;
p->len = sizeof(p->addr.v4);
p->addr.v4 = *(struct in_addr *)addr;
}
else if (family == AF_INET6)
{
p->family = AF_INET6;
p->bits = (bits < 0) ? AF_BITS(AF_INET6) : bits;
p->addr.v6 = *(struct in6_addr *)addr;
}
else
{
p->family = AF_PACKET;
p->bits = (bits < 0) ? AF_BITS(AF_PACKET) : bits;
p->addr.mac = *(struct ether_addr *)addr;
p->family = AF_INET6;
p->bits = (bits < 0) ? 128 : bits;
p->len = sizeof(p->addr.v6);
p->addr.v6 = *(struct in6_addr *)addr;
}
luaL_getmetatable(L, LUCI_IP_CIDR);
@ -335,7 +254,6 @@ static void L_setdev(struct lua_State *L, const char *name,
static int L_checkbits(lua_State *L, int index, cidr_t *p)
{
int16_t s16;
int bits;
if (lua_gettop(L) < index || lua_isnil(L, index))
@ -346,15 +264,13 @@ static int L_checkbits(lua_State *L, int index, cidr_t *p)
{
bits = lua_tointeger(L, index);
if (bits < 0 || bits > AF_BITS(p->family))
if (bits < 0 || bits > ((p->family == AF_INET) ? 32 : 128))
return luaL_error(L, "Invalid prefix size");
}
else if (lua_type(L, index) == LUA_TSTRING)
{
if (!parse_mask(p->family, lua_tostring(L, index), &s16))
if (!parse_mask(p->family, lua_tostring(L, index), &bits))
return luaL_error(L, "Invalid netmask format");
bits = s16;
}
else
{
@ -377,26 +293,20 @@ static int _cidr_new(lua_State *L, int index, int family, bool mask)
if (family == AF_INET6)
{
cidr.family = AF_INET6;
cidr.bits = 128;
cidr.len = sizeof(cidr.addr.v6);
cidr.addr.v6.s6_addr[12] = n;
cidr.addr.v6.s6_addr[13] = (n >> 8);
cidr.addr.v6.s6_addr[14] = (n >> 16);
cidr.addr.v6.s6_addr[15] = (n >> 24);
}
else if (family == AF_INET)
{
cidr.family = AF_INET;
cidr.addr.v4.s_addr = n;
}
else
{
cidr.family = AF_PACKET;
cidr.addr.mac.ether_addr_octet[2] = n;
cidr.addr.mac.ether_addr_octet[3] = (n >> 8);
cidr.addr.mac.ether_addr_octet[4] = (n >> 16);
cidr.addr.mac.ether_addr_octet[5] = (n >> 24);
cidr.family = AF_INET;
cidr.bits = 32;
cidr.len = sizeof(cidr.addr.v4);
cidr.addr.v4.s_addr = n;
}
cidr.bits = AF_BITS(cidr.family);
}
else
{
@ -436,62 +346,6 @@ static int cidr_ipv6(lua_State *L)
return _cidr_new(L, 1, AF_INET6, true);
}
static int cidr_mac(lua_State *L)
{
return _cidr_new(L, 1, AF_PACKET, true);
}
static int cidr_check(lua_State *L, int family)
{
cidr_t cidr = { }, *cidrp;
const char *addr;
if (lua_type(L, 1) == LUA_TSTRING)
{
addr = lua_tostring(L, 1);
if (addr && parse_cidr(addr, &cidr) && cidr.family == family)
return format_cidr(L, &cidr);
}
else
{
cidrp = lua_touserdata(L, 1);
if (cidrp == NULL)
return 0;
if (!lua_getmetatable(L, 1))
return 0;
lua_getfield(L, LUA_REGISTRYINDEX, LUCI_IP_CIDR);
if (!lua_rawequal(L, -1, -2))
cidrp = NULL;
lua_pop(L, 2);
if (cidrp != NULL && cidrp->family == family)
return format_cidr(L, cidrp);
}
return 0;
}
static int cidr_checkip4(lua_State *L)
{
return cidr_check(L, AF_INET);
}
static int cidr_checkip6(lua_State *L)
{
return cidr_check(L, AF_INET6);
}
static int cidr_checkmac(lua_State *L)
{
return cidr_check(L, AF_PACKET);
}
static int cidr_is4(lua_State *L)
{
cidr_t *p = L_checkcidr(L, 1, NULL);
@ -570,34 +424,6 @@ static int cidr_is6linklocal(lua_State *L)
return 1;
}
static int cidr_ismac(lua_State *L)
{
cidr_t *p = L_checkcidr(L, 1, NULL);
lua_pushboolean(L, p->family == AF_PACKET);
return 1;
}
static int cidr_ismacmcast(lua_State *L)
{
cidr_t *p = L_checkcidr(L, 1, NULL);
lua_pushboolean(L, (p->family == AF_PACKET &&
(p->addr.mac.ether_addr_octet[0] & 0x1)));
return 1;
}
static int cidr_ismaclocal(lua_State *L)
{
cidr_t *p = L_checkcidr(L, 1, NULL);
lua_pushboolean(L, (p->family == AF_PACKET &&
(p->addr.mac.ether_addr_octet[0] & 0x2)));
return 1;
}
static int _cidr_cmp(lua_State *L)
{
cidr_t *a = L_checkcidr(L, 1, NULL);
@ -606,7 +432,7 @@ static int _cidr_cmp(lua_State *L)
if (a->family != b->family)
return (a->family - b->family);
return memcmp(&a->addr.v6, &b->addr.v6, AF_BYTES(a->family));
return memcmp(&a->addr.v6, &b->addr.v6, a->len);
}
static int cidr_lower(lua_State *L)
@ -649,24 +475,24 @@ static void _apply_mask(cidr_t *p, int bits, bool inv)
if (bits <= 0)
{
memset(&p->addr.u8, inv * 0xFF, AF_BYTES(p->family));
memset(&p->addr.v6, inv * 0xFF, p->len);
}
else if (p->family == AF_INET && bits <= AF_BITS(AF_INET))
else if (p->family == AF_INET && bits <= 32)
{
if (inv)
p->addr.v4.s_addr |= ntohl((1 << (AF_BITS(AF_INET) - bits)) - 1);
p->addr.v4.s_addr |= ntohl((1 << (32 - bits)) - 1);
else
p->addr.v4.s_addr &= ntohl(~((1 << (AF_BITS(AF_INET) - bits)) - 1));
p->addr.v4.s_addr &= ntohl(~((1 << (32 - bits)) - 1));
}
else if (bits <= AF_BITS(p->family))
else if (p->family == AF_INET6 && bits <= 128)
{
for (i = 0; i < AF_BYTES(p->family); i++)
for (i = 0; i < sizeof(p->addr.v6.s6_addr); i++)
{
b = (bits > 8) ? 8 : bits;
if (inv)
p->addr.u8[i] |= ~((uint8_t)(0xFF << (8 - b)));
p->addr.v6.s6_addr[i] |= ~((uint8_t)(0xFF << (8 - b)));
else
p->addr.u8[i] &= (uint8_t)(0xFF << (8 - b));
p->addr.v6.s6_addr[i] &= (uint8_t)(0xFF << (8 - b));
bits -= b;
}
}
@ -681,7 +507,7 @@ static int cidr_network(lua_State *L)
return 0;
*p2 = *p1;
p2->bits = AF_BITS(p1->family);
p2->bits = (p1->family == AF_INET) ? 32 : 128;
_apply_mask(p2, bits, false);
luaL_getmetatable(L, LUCI_IP_CIDR);
@ -698,7 +524,7 @@ static int cidr_host(lua_State *L)
return 0;
*p2 = *p1;
p2->bits = AF_BITS(p1->family);
p2->bits = (p1->family == AF_INET) ? 32 : 128;
luaL_getmetatable(L, LUCI_IP_CIDR);
lua_setmetatable(L, -2);
@ -713,7 +539,7 @@ static int cidr_mask(lua_State *L)
if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
return 0;
p2->bits = AF_BITS(p1->family);
p2->bits = (p1->family == AF_INET) ? 32 : 128;
p2->family = p1->family;
memset(&p2->addr.v6.s6_addr, 0xFF, sizeof(p2->addr.v6.s6_addr));
@ -730,14 +556,14 @@ static int cidr_broadcast(lua_State *L)
cidr_t *p2;
int bits = L_checkbits(L, 2, p1);
if (p1->family != AF_INET)
if (p1->family == AF_INET6)
return 0;
if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
return 0;
*p2 = *p1;
p2->bits = AF_BITS(AF_INET);
p2->bits = (p1->family == AF_INET) ? 32 : 128;
_apply_mask(p2, bits, true);
luaL_getmetatable(L, LUCI_IP_CIDR);
@ -757,7 +583,7 @@ static int cidr_mapped4(lua_State *L)
return 0;
p2->family = AF_INET;
p2->bits = (p1->bits > AF_BITS(AF_INET)) ? AF_BITS(AF_INET) : p1->bits;
p2->bits = (p1->bits > 32) ? 32 : p1->bits;
memcpy(&p2->addr.v4, p1->addr.v6.s6_addr + 12, sizeof(p2->addr.v4));
luaL_getmetatable(L, LUCI_IP_CIDR);
@ -765,72 +591,6 @@ static int cidr_mapped4(lua_State *L)
return 1;
}
static int cidr_tolinklocal(lua_State *L)
{
cidr_t *p1 = L_checkcidr(L, 1, NULL);
cidr_t *p2;
int i;
if (p1->family != AF_PACKET)
return 0;
if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
return 0;
p2->family = AF_INET6;
p2->bits = AF_BITS(AF_INET6);
p2->addr.u8[0] = 0xFE;
p2->addr.u8[1] = 0x80;
p2->addr.u8[8] = p1->addr.u8[0] ^ 0x02;
p2->addr.u8[9] = p1->addr.u8[1];
p2->addr.u8[10] = p1->addr.u8[2];
p2->addr.u8[11] = 0xFF;
p2->addr.u8[12] = 0xFE;
p2->addr.u8[13] = p1->addr.u8[3];
p2->addr.u8[14] = p1->addr.u8[4];
p2->addr.u8[15] = p1->addr.u8[5];
luaL_getmetatable(L, LUCI_IP_CIDR);
lua_setmetatable(L, -2);
return 1;
}
static int cidr_tomac(lua_State *L)
{
cidr_t *p1 = L_checkcidr(L, 1, NULL);
cidr_t *p2;
int i;
if (p1->family != AF_INET6 ||
p1->addr.u8[0] != 0xFE ||
p1->addr.u8[1] != 0x80 ||
p1->addr.u8[2] != 0x00 ||
p1->addr.u8[3] != 0x00 ||
p1->addr.u8[4] != 0x00 ||
p1->addr.u8[5] != 0x00 ||
p1->addr.u8[6] != 0x00 ||
p1->addr.u8[7] != 0x00 ||
p1->addr.u8[11] != 0xFF ||
p1->addr.u8[12] != 0xFE)
return 0;
if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
return 0;
p2->family = AF_PACKET;
p2->bits = AF_BITS(AF_PACKET);
p2->addr.u8[0] = p1->addr.u8[8] ^ 0x02;
p2->addr.u8[1] = p1->addr.u8[9];
p2->addr.u8[2] = p1->addr.u8[10];
p2->addr.u8[3] = p1->addr.u8[13];
p2->addr.u8[4] = p1->addr.u8[14];
p2->addr.u8[5] = p1->addr.u8[15];
luaL_getmetatable(L, LUCI_IP_CIDR);
lua_setmetatable(L, -2);
return 1;
}
static int cidr_contains(lua_State *L)
{
cidr_t *p1 = L_checkcidr(L, 1, NULL);
@ -843,15 +603,15 @@ static int cidr_contains(lua_State *L)
_apply_mask(&a, p1->bits, false);
_apply_mask(&b, p1->bits, false);
rv = !memcmp(&a.addr.v6, &b.addr.v6, AF_BYTES(a.family));
rv = !memcmp(&a.addr.v6, &b.addr.v6, a.len);
}
lua_pushboolean(L, rv);
return 1;
}
#define BYTE(a, i) \
(a)->addr.u8[AF_BYTES((a)->family) - (i) - 1]
#define S6_BYTE(a, i) \
(a)->addr.v6.s6_addr[sizeof((a)->addr.v6.s6_addr) - (i) - 1]
static int _cidr_add_sub(lua_State *L, bool add)
{
@ -865,7 +625,30 @@ static int _cidr_add_sub(lua_State *L, bool add)
if (p1->family == p2->family)
{
if (p1->family == AF_INET)
if (p1->family == AF_INET6)
{
for (i = 0, carry = 0; i < sizeof(r.addr.v6.s6_addr); i++)
{
if (add)
{
S6_BYTE(&r, i) = S6_BYTE(p1, i) + S6_BYTE(p2, i) + carry;
carry = (S6_BYTE(p1, i) + S6_BYTE(p2, i) + carry) / 256;
}
else
{
S6_BYTE(&r, i) = (S6_BYTE(p1, i) - S6_BYTE(p2, i) - carry);
carry = (S6_BYTE(p1, i) < (S6_BYTE(p2, i) + carry));
}
}
/* would over/underflow */
if (carry)
{
memset(&r.addr.v6, add * 0xFF, sizeof(r.addr.v6));
ok = false;
}
}
else
{
a = ntohl(p1->addr.v4.s_addr);
b = ntohl(p2->addr.v4.s_addr);
@ -881,29 +664,6 @@ static int _cidr_add_sub(lua_State *L, bool add)
r.addr.v4.s_addr = add ? htonl(a + b) : htonl(a - b);
}
}
else
{
for (i = 0, carry = 0; i < AF_BYTES(p1->family); i++)
{
if (add)
{
BYTE(&r, i) = BYTE(p1, i) + BYTE(p2, i) + carry;
carry = (BYTE(p1, i) + BYTE(p2, i) + carry) / 256;
}
else
{
BYTE(&r, i) = (BYTE(p1, i) - BYTE(p2, i) - carry);
carry = (BYTE(p1, i) < (BYTE(p2, i) + carry));
}
}
/* would over/underflow */
if (carry)
{
memset(&r.addr.u8, add * 0xFF, AF_BYTES(r.family));
ok = false;
}
}
}
else
{
@ -945,22 +705,22 @@ static int cidr_minhost(lua_State *L)
_apply_mask(&r, r.bits, false);
if (r.family == AF_INET && r.bits < AF_BITS(AF_INET))
if (r.family == AF_INET6 && r.bits < 128)
{
r.bits = AF_BITS(AF_INET);
r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) + 1);
}
else if (r.bits < AF_BITS(r.family))
{
r.bits = AF_BITS(r.family);
r.bits = 128;
for (i = 0, carry = 1; i < AF_BYTES(r.family); i++)
for (i = 0, carry = 1; i < sizeof(r.addr.v6.s6_addr); i++)
{
rest = (BYTE(&r, i) + carry) > 255;
BYTE(&r, i) += carry;
rest = (S6_BYTE(&r, i) + carry) > 255;
S6_BYTE(&r, i) += carry;
carry = rest;
}
}
else if (r.family == AF_INET && r.bits < 32)
{
r.bits = 32;
r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) + 1);
}
if (!(p = lua_newuserdata(L, sizeof(*p))))
return 0;
@ -979,14 +739,14 @@ static int cidr_maxhost(lua_State *L)
_apply_mask(&r, r.bits, true);
if (r.family == AF_INET && r.bits < AF_BITS(AF_INET))
if (r.family == AF_INET && r.bits < 32)
{
r.bits = AF_BITS(AF_INET);
r.bits = 32;
r.addr.v4.s_addr = htonl(ntohl(r.addr.v4.s_addr) - 1);
}
else
else if (r.family == AF_INET6)
{
r.bits = AF_BITS(r.family);
r.bits = 128;
}
if (!(p = lua_newuserdata(L, sizeof(*p))))
@ -1006,17 +766,31 @@ static int cidr_gc (lua_State *L)
static int cidr_tostring (lua_State *L)
{
char buf[INET6_ADDRSTRLEN];
cidr_t *p = L_checkcidr(L, 1, NULL);
return format_cidr(L, p);
if ((p->family == AF_INET && p->bits < 32) ||
(p->family == AF_INET6 && p->bits < 128))
{
lua_pushfstring(L, "%s/%d",
inet_ntop(p->family, &p->addr.v6, buf, sizeof(buf)),
p->bits);
}
else
{
lua_pushstring(L, inet_ntop(p->family, &p->addr.v6, buf, sizeof(buf)));
}
return 1;
}
/*
* route functions
*/
static bool diff_prefix(int family, void *addr, int bits, bool exact, cidr_t *p)
static bool diff_prefix(int family, void *addr, int bits, cidr_t *p)
{
uint8_t i, b, r, *a;
uint8_t i, b, r;
uint32_t m;
if (!p->family)
@ -1025,27 +799,28 @@ static bool diff_prefix(int family, void *addr, int bits, bool exact, cidr_t *p)
if (!addr || p->family != family || p->bits > bits)
return true;
if (family == AF_INET)
if (family == AF_INET6)
{
m = p->bits ? htonl(~((1 << (AF_BITS(AF_INET) - p->bits)) - 1)) : 0;
if ((((struct in_addr *)addr)->s_addr & m) != (p->addr.v4.s_addr & m))
return true;
}
else
{
for (i = 0, a = addr, r = p->bits; i < AF_BYTES(p->family); i++)
for (i = 0, r = p->bits; i < sizeof(struct in6_addr); i++)
{
b = r ? (0xFF << (8 - ((r > 8) ? 8 : r))) : 0;
if ((a[i] & b) != (p->addr.u8[i] & b))
if ((((struct in6_addr *)addr)->s6_addr[i] & b) !=
(p->addr.v6.s6_addr[i] & b))
return true;
r -= ((r > 8) ? 8 : r);
}
}
else
{
m = p->bits ? htonl(~((1 << (32 - p->bits)) - 1)) : 0;
return (exact && p->bits != bits);
if ((((struct in_addr *)addr)->s_addr & m) != (p->addr.v4.s_addr & m))
return true;
}
return (p->exact && p->bits != bits);
}
static int cb_dump_route(struct nl_msg *msg, void *arg)
@ -1073,7 +848,7 @@ static int cb_dump_route(struct nl_msg *msg, void *arg)
dst = tb[RTA_DST] ? RTA_DATA(tb[RTA_DST]) : &def;
gw = tb[RTA_GATEWAY] ? RTA_DATA(tb[RTA_GATEWAY]) : NULL;
bitlen = AF_BITS(rt->rtm_family);
bitlen = (rt->rtm_family == AF_INET6) ? 128 : 32;
if ((f->type && rt->rtm_type != f->type) ||
(f->family && rt->rtm_family != f->family) ||
@ -1082,14 +857,10 @@ static int cb_dump_route(struct nl_msg *msg, void *arg)
(f->iif && iif != f->iif) ||
(f->oif && oif != f->oif) ||
(f->table && table != f->table) ||
diff_prefix(rt->rtm_family, from, rt->rtm_src_len,
f->from_exact, &f->from) ||
diff_prefix(rt->rtm_family, dst, rt->rtm_dst_len,
f->dst_exact, &f->dst) ||
diff_prefix(rt->rtm_family, gw, bitlen,
false, &f->gw) ||
diff_prefix(rt->rtm_family, src, bitlen,
false, &f->src))
diff_prefix(rt->rtm_family, from, rt->rtm_src_len, &f->from) ||
diff_prefix(rt->rtm_family, dst, rt->rtm_dst_len, &f->dst) ||
diff_prefix(rt->rtm_family, gw, bitlen, &f->gw) ||
diff_prefix(rt->rtm_family, src, bitlen, &f->src))
goto out;
if (s->callback)
@ -1217,8 +988,7 @@ static int _route_dump(lua_State *L, struct dump_filter *filter)
nlmsg_append(msg, &rtm, sizeof(rtm), 0);
if (filter->get)
nla_put(msg, RTA_DST, AF_BYTES(filter->dst.family),
&filter->dst.addr.v6);
nla_put(msg, RTA_DST, filter->dst.len, &filter->dst.addr.v6);
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_route, &s);
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, cb_done, &s);
@ -1293,10 +1063,10 @@ static int route_dump(lua_State *L)
filter.dst = p;
if ((s = L_getstr(L, 1, "from_exact")) != NULL && parse_cidr(s, &p))
filter.from = p, filter.from_exact = true;
filter.from = p, filter.from.exact = true;
if ((s = L_getstr(L, 1, "dest_exact")) != NULL && parse_cidr(s, &p))
filter.dst = p, filter.dst_exact = true;
filter.dst = p, filter.dst.exact = true;
}
return _route_dump(L, &filter);
@ -1337,12 +1107,12 @@ static int cb_dump_neigh(struct nl_msg *msg, void *arg)
mac = tb[NDA_LLADDR] ? RTA_DATA(tb[NDA_LLADDR]) : NULL;
dst = tb[NDA_DST] ? RTA_DATA(tb[NDA_DST]) : NULL;
bitlen = AF_BITS(nd->ndm_family);
bitlen = (nd->ndm_family == AF_INET) ? 32 : 128;
if ((f->family && nd->ndm_family != f->family) ||
(f->iif && nd->ndm_ifindex != f->iif) ||
(f->type && !(f->type & nd->ndm_state)) ||
diff_prefix(nd->ndm_family, dst, bitlen, false, &f->dst) ||
diff_prefix(nd->ndm_family, dst, bitlen, &f->dst) ||
diff_macaddr(mac, &f->mac))
goto out;
@ -1370,7 +1140,15 @@ static int cb_dump_neigh(struct nl_msg *msg, void *arg)
L_setaddr(s->L, "dest", nd->ndm_family, dst, -1);
if (mac)
L_setaddr(s->L, "mac", AF_PACKET, mac, -1);
{
snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
mac->ether_addr_octet[0], mac->ether_addr_octet[1],
mac->ether_addr_octet[2], mac->ether_addr_octet[3],
mac->ether_addr_octet[4], mac->ether_addr_octet[5]);
lua_pushstring(s->L, buf);
lua_setfield(s->L, -2, "mac");
}
s->index++;
@ -1463,7 +1241,7 @@ out:
static int cb_dump_link(struct nl_msg *msg, void *arg)
{
char buf[48];
char *p, *addr, buf[48];
struct dump_state *s = arg;
struct nlmsghdr *hdr = nlmsg_hdr(msg);
struct ifinfomsg *ifm = NLMSG_DATA(hdr);
@ -1488,8 +1266,19 @@ static int cb_dump_link(struct nl_msg *msg, void *arg)
if (tb[IFLA_MASTER])
L_setdev(s->L, "master", tb[IFLA_MASTER]);
if (tb[IFLA_ADDRESS] && nla_len(tb[IFLA_ADDRESS]) == AF_BYTES(AF_PACKET))
L_setaddr(s->L, "mac", AF_PACKET, nla_get_string(tb[IFLA_ADDRESS]), -1);
if (tb[IFLA_ADDRESS])
{
len = nla_len(tb[IFLA_ADDRESS]);
addr = nla_get_string(tb[IFLA_ADDRESS]);
if ((len * 3) <= sizeof(buf))
{
for (p = buf, i = 0; i < len; i++)
p += sprintf(p, "%s%02x", (i ? ":" : ""), (uint8_t)*addr++);
L_setstr(s->L, "mac", buf);
}
}
s->pending = 0;
return NL_SKIP;
@ -1544,18 +1333,13 @@ static const luaL_reg ip_methods[] = {
{ "new", cidr_new },
{ "IPv4", cidr_ipv4 },
{ "IPv6", cidr_ipv6 },
{ "MAC", cidr_mac },
{ "checkip4", cidr_checkip4 },
{ "checkip6", cidr_checkip6 },
{ "checkmac", cidr_checkmac },
{ "route", route_get },
{ "routes", route_dump },
{ "neighbors", neighbor_dump },
{ "link", link_get },
{ "link", link_get },
{ }
};
@ -1567,9 +1351,6 @@ static const luaL_reg ip_cidr_methods[] = {
{ "is6", cidr_is6 },
{ "is6linklocal", cidr_is6linklocal },
{ "is6mapped4", cidr_is6mapped4 },
{ "ismac", cidr_ismac },
{ "ismaclocal", cidr_ismaclocal },
{ "ismacmcast", cidr_ismacmcast },
{ "lower", cidr_lower },
{ "higher", cidr_higher },
{ "equal", cidr_equal },
@ -1579,9 +1360,7 @@ static const luaL_reg ip_cidr_methods[] = {
{ "mask", cidr_mask },
{ "broadcast", cidr_broadcast },
{ "mapped4", cidr_mapped4 },
{ "tomac", cidr_tomac },
{ "tolinklocal", cidr_tolinklocal },
{ "contains", cidr_contains },
{ "contains", cidr_contains },
{ "add", cidr_add },
{ "sub", cidr_sub },
{ "minhost", cidr_minhost },

View File

@ -27,7 +27,6 @@ addr6 = luci.ip.new("fe80::221:63ff:fe75:aa17", "ffff:ffff:ffff:ffff::")
addr6 = luci.ip.new("fe80::221:63ff:fe75:aa17/64", 128) -- override netmask`
@see IPv4
@see IPv6
@see MAC
]]
---[[
@ -48,7 +47,6 @@ addr = luci.ip.IPv4("10.24.0.1/255.255.255.0")
addr = luci.ip.IPv4("10.24.0.1", "255.255.255.0") -- separate netmask
addr = luci.ip.IPv4("10.24.0.1/24", 16) -- override netmask`
@see IPv6
@see MAC
]]
---[[
@ -69,112 +67,12 @@ addr6 = luci.ip.IPv6("fe80::221:63ff:fe75:aa17/ffff:ffff:ffff:ffff::")
addr6 = luci.ip.IPv6("fe80::221:63ff:fe75:aa17", "ffff:ffff:ffff:ffff::")
addr6 = luci.ip.IPv6("fe80::221:63ff:fe75:aa17/64", 128) -- override netmask`
@see IPv4
@see MAC
]]
---[[
Construct a new MAC luci.ip.cidr instance.
Throws an error if the given string does not represent a valid ethernet MAC
address or if the given optional mask is of a different family.
@class function
@sort 4
@name MAC
@param address String containing a valid ethernet MAC address, optionally with
prefix size (CIDR notation) or mask separated by slash.
@param netmask String containing a valid MAC address mask or number
containing a prefix size between `0` and `48` bit.
Overrides mask embedded in the first argument if specified. (optional)
@return A `luci.ip.cidr` object representing the given MAC address range.
@usage `intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00/24")
intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00/FF:FF:FF:0:0:0")
intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00", "FF:FF:FF:0:0:0")
intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00/24", 48) -- override mask`
@see IPv4
@see IPv6
]]
---[[
Verify an IPv4 address.
Checks whether given argument is a preexisting luci.ip.cidr IPv4 address
instance or a string literal convertible to an IPv4 address and returns a
plain Lua string containing the canonical representation of the address.
If the argument is not a valid address, returns nothing. This function is
intended to aid in safely verifying address literals without having to deal
with exceptions.
@class function
@sort 5
@name checkip4
@param address String containing a valid IPv4 address or existing
luci.ip.cidr IPv4 instance.
@return A string representing the given IPv4 address.
@usage `ipv4 = luci.ip.checkip4(luci.ip.new("127.0.0.1")) -- "127.0.0.1"
ipv4 = luci.ip.checkip4("127.0.0.1") -- "127.0.0.1"
ipv4 = luci.ip.checkip4("nonesense") -- nothing
ipv4 = luci.ip.checkip4(123) -- nothing
ipv4 = luci.ip.checkip4(nil) -- nothing
ipv4 = luci.ip.checkip4() -- nothing`
@see checkip6
@see checkmac
]]
---[[
Verify an IPv6 address.
Checks whether given argument is a preexisting luci.ip.cidr IPv6 address
instance or a string literal convertible to an IPv6 address and returns a
plain Lua string containing the canonical representation of the address.
If the argument is not a valid address, returns nothing. This function is
intended to aid in safely verifying address literals without having to deal
with exceptions.
@class function
@sort 6
@name checkip6
@param address String containing a valid IPv6 address or existing
luci.ip.cidr IPv6 instance.
@return A string representing the given IPv6 address.
@usage `ipv6 = luci.ip.checkip6(luci.ip.new("0:0:0:0:0:0:0:1")) -- "::1"
ipv6 = luci.ip.checkip6("0:0:0:0:0:0:0:1") -- "::1"
ipv6 = luci.ip.checkip6("nonesense") -- nothing
ipv6 = luci.ip.checkip6(123) -- nothing
ipv6 = luci.ip.checkip6(nil) -- nothing
ipv6 = luci.ip.checkip6() -- nothing`
@see checkip4
@see checkmac
]]
---[[
Verify an ethernet MAC address.
Checks whether given argument is a preexisting luci.ip.cidr MAC address
instance or a string literal convertible to an ethernet MAC and returns a
plain Lua string containing the canonical representation of the address.
If the argument is not a valid address, returns nothing. This function is
intended to aid in safely verifying address literals without having to deal
with exceptions.
@class function
@sort 7
@name checkmac
@param address String containing a valid MAC address or existing luci.ip.cidr
MAC address instance.
@return A string representing the given MAC address.
@usage `mac = luci.ip.checkmac(luci.ip.new("00-11-22-cc-dd-ee")) -- "00:11:22:CC:DD:EE"
mac = luci.ip.checkmac("00:11:22:cc:dd:ee") -- "00:11:22:CC:DD:EE"
mac = luci.ip.checkmac("nonesense") -- nothing
mac = luci.ip.checkmac(123) -- nothing
mac = luci.ip.checkmac(nil) -- nothing
mac = luci.ip.checkmac() -- nothing`
@see checkip4
@see checkip6
]]
---[[
Determine the route leading to the given destination.
@class function
@sort 8
@sort 4
@name route
@param address A `luci.ip.cidr` instance or a string containing
a valid IPv4 or IPv6 range as specified by `luci.ip.new()`.
@ -280,7 +178,7 @@ end`</li>
---[[
Fetch all routes, optionally matching the given criteria.
@class function
@sort 9
@sort 5
@name routes
@param filter <p>Table containing one or more of the possible filter
critera described below (optional)</p><table>
@ -360,7 +258,7 @@ end`</li>
---[[
Fetches entries from the IPv4 ARP and IPv6 neighbour kernel table
@class function
@sort 10
@sort 6
@name neighbors
@param filter <p>Table containing one or more of the possible filter
critera described below (optional)</p><table>
@ -408,7 +306,7 @@ A neighbour entry is a table containing the following fields:
</tr>
<tr>
<td>`mac`</td>
<td>MAC address `luci.ip.cidr` instance</td>
<td>String containing the associated MAC address</td>
</tr>
<tr>
<td>`router`</td>
@ -469,7 +367,7 @@ end)`</li>
---[[
Fetch basic device information
@class function
@sort 11
@sort 7
@name link
@param device String containing the network device to query
@return If the given interface is found, a table containing the fields
@ -505,8 +403,8 @@ described below is returned, else an empty table.
</tr>
<tr>
<td>`mac`</td>
<td>MAC address `luci.ip.cidr` instance representing the device ethernet
address</td>
<td>String containing the link local address of the device in
dotted hex notation</td>
</tr>
</table>
@usage <ul>
@ -532,7 +430,6 @@ Checks whether the CIDR instance is an IPv4 address range
@sort 1
@name cidr.is4
@see cidr.is6
@see cidr.ismac
@return `true` if the CIDR is an IPv4 range, else `false`
]]
@ -573,7 +470,6 @@ Checks whether the CIDR instance is an IPv6 address range
@sort 4
@name cidr.is6
@see cidr.is4
@see cidr.ismac
@return `true` if the CIDR is an IPv6 range, else `false`
]]
@ -605,52 +501,14 @@ if addr:is6mapped4() then
end`
]]
---[[
Checks whether the CIDR instance is an ethernet MAC address range
@class function
@sort 7
@name cidr.ismac
@see cidr.is4
@see cidr.is6
@return `true` if the CIDR is a MAC address range, else `false`
]]
---[[
Checks whether the CIDR instance is a locally administered (LAA) MAC address
@class function
@sort 8
@name cidr.ismaclocal
@return `true` if the MAC address sets the locally administered bit.
@usage `local mac = luci.ip.new("02:C0:FF:EE:00:01")
if mac:ismaclocal() then
print("Is an LAA MAC address")
end`
]]
---[[
Checks whether the CIDR instance is a multicast MAC address
@class function
@sort 9
@name cidr.ismacmcast
@return `true` if the MAC address sets the multicast bit.
@usage `local mac = luci.ip.new("01:00:5E:7F:00:10")
if addr:ismacmcast() then
print("Is a multicast MAC address")
end`
]]
---[[
Checks whether this CIDR instance is lower than the given argument.
The comparisation follows these rules:
<ul><li>An IPv4 address is always lower than an IPv6 address and IPv6 addresses
are considered lower than MAC addresses</li>
<ul><li>An IPv4 address is always lower than an IPv6 address</li>
<li>Prefix sizes are ignored</li></ul>
@class function
@sort 10
@sort 7
@name cidr.lower
@param addr A `luci.ip.cidr` instance or a string convertable by
`luci.ip.new()` to compare against.
@ -660,8 +518,7 @@ are considered lower than MAC addresses</li>
print(addr:lower(addr)) -- false
print(addr:lower("10.10.10.10/24")) -- false
print(addr:lower(luci.ip.new("::1"))) -- true
print(addr:lower(luci.ip.new("192.168.200.1"))) -- true
print(addr:lower(luci.ip.new("00:14:22:01:23:45"))) -- true`
print(addr:lower(luci.ip.new("192.168.200.1"))) -- true`
@see cidr.higher
@see cidr.equal
]]
@ -669,12 +526,11 @@ print(addr:lower(luci.ip.new("00:14:22:01:23:45"))) -- true`
---[[
Checks whether this CIDR instance is higher than the given argument.
The comparisation follows these rules:
<ul><li>An IPv4 address is always lower than an IPv6 address and IPv6 addresses
are considered lower than MAC addresses</li>
<ul><li>An IPv4 address is always lower than an IPv6 address</li>
<li>Prefix sizes are ignored</li></ul>
@class function
@sort 11
@sort 8
@name cidr.higher
@param addr A `luci.ip.cidr` instance or a string convertable by
`luci.ip.new()` to compare against.
@ -684,8 +540,7 @@ are considered lower than MAC addresses</li>
print(addr:higher(addr)) -- false
print(addr:higher("10.10.10.10/24")) -- true
print(addr:higher(luci.ip.new("::1"))) -- false
print(addr:higher(luci.ip.new("192.168.200.1"))) -- false
print(addr:higher(luci.ip.new("00:14:22:01:23:45"))) -- false`
print(addr:higher(luci.ip.new("192.168.200.1"))) -- false`
@see cidr.lower
@see cidr.equal
]]
@ -694,7 +549,7 @@ print(addr:higher(luci.ip.new("00:14:22:01:23:45"))) -- false`
Checks whether this CIDR instance is equal to the given argument.
@class function
@sort 12
@sort 9
@name cidr.equal
@param addr A `luci.ip.cidr` instance or a string convertable by
`luci.ip.new()` to compare against.
@ -707,11 +562,7 @@ print(addr:equal(luci.ip.new("::1"))) -- false
local addr6 = luci.ip.new("::1")
print(addr6:equal("0:0:0:0:0:0:0:1/64")) -- true
print(addr6:equal(luci.ip.new("fe80::221:63ff:fe75:aa17"))) -- false
local mac = luci.ip.new("00:14:22:01:23:45")
print(mac:equal("0:14:22:1:23:45")) -- true
print(mac:equal(luci.ip.new("01:23:45:67:89:AB")) -- false`
print(addr6:equal(luci.ip.new("fe80::221:63ff:fe75:aa17"))) -- false`
@see cidr.lower
@see cidr.higher
]]
@ -722,11 +573,11 @@ If the optional mask parameter is given, the prefix size of this CIDR is altered
else the current prefix size is returned.
@class function
@sort 13
@sort 10
@name cidr.prefix
@param mask Either a number containing the number of bits (`0..32`
for IPv4, `0..128` for IPv6 or `0..48` for MAC addresses) or a string
containing a valid netmask (optional)
for IPv4, `0..128` for IPv6) or a string containing a valid
netmask (optional)
@return Bit count of the current prefix size
@usage `local range = luci.ip.new("192.168.1.1/255.255.255.0")
print(range:prefix()) -- 24
@ -746,11 +597,11 @@ with all host parts masked out. The used prefix size can be overridden by the
optional mask parameter.
@class function
@sort 14
@sort 11
@name cidr.network
@param mask Either a number containing the number of bits (`0..32`
for IPv4, `0..128` for IPv6 or `0..48` for MAC addresses) or a string
containing a valid netmask (optional)
for IPv4, `0..128` for IPv6) or a string containing a valid
netmask (optional)
@return CIDR instance representing the network address
@usage `local range = luci.ip.new("192.168.62.243/255.255.0.0")
print(range:network()) -- "192.168.0.0"
@ -765,10 +616,10 @@ print(range6:network()) -- "fd9b:62b3:9cc5::"`
Derive host address of CIDR instance.
This function essentially constructs a copy of this CIDR with the prefix size
set to `32` for IPv4, `128` for IPv6 or `48` for MAC addresses.
set to `32` for IPv4 and `128` for IPv6.
@class function
@sort 15
@sort 12
@name cidr.host
@return CIDR instance representing the host address
@usage `local range = luci.ip.new("172.19.37.45/16")
@ -783,11 +634,11 @@ Constructs a CIDR instance representing the netmask of this instance. The used
prefix size can be overridden by the optional mask parameter.
@class function
@sort 16
@sort 13
@name cidr.mask
@param mask Either a number containing the number of bits (`0..32`
for IPv4, `0..128` for IPv6 or `0..48` for MAC addresses) or a string
containing a valid netmask (optional)
for IPv4, `0..128` for IPv6) or a string containing a valid
netmask (optional)
@return CIDR instance representing the netmask
@usage `local range = luci.ip.new("172.19.37.45/16")
print(range:mask()) -- "255.255.0.0"
@ -801,14 +652,15 @@ Derive broadcast address of CIDR instance.
Constructs a CIDR instance representing the broadcast address of this instance.
The used prefix size can be overridden by the optional mask parameter.
This function has no effect on IPv6 or MAC address instances, it will return
nothing in this case.
This function has no effect on IPv6 instances, it will return nothing in this
case.
@class function
@sort 17
@sort 14
@name cidr.broadcast
@param mask Either a number containing the number of bits (`0..32` for IPv4) or
a string containing a valid netmask (optional)
@param mask Either a number containing the number of bits (`0..32`
for IPv4, `0..128` for IPv6) or a string containing a valid
netmask (optional)
@return Return a new CIDR instance representing the broadcast address if this
instance is an IPv4 range, else return nothing.
@usage `local range = luci.ip.new("172.19.37.45/16")
@ -823,11 +675,11 @@ Derive mapped IPv4 address of CIDR instance.
Constructs a CIDR instance representing the IPv4 address of the IPv6 mapped
IPv4 address in this instance.
This function has no effect on IPv4 instances, MAC address instances or IPv6
instances which are not a mapped address, it will return nothing in this case.
This function has no effect on IPv4 instances or IPv6 instances which are not a
mapped address, it will return nothing in this case.
@class function
@sort 18
@sort 15
@name cidr.mapped4
@return Return a new CIDR instance representing the IPv4 address if this
instance is an IPv6 mapped IPv4 address, else return nothing.
@ -835,47 +687,11 @@ instances which are not a mapped address, it will return nothing in this case.
print(addr:mapped4()) -- "172.16.19.1"`
]]
---[[
Derive MAC address of IPv6 link local CIDR instance.
Constructs a CIDR instance representing the MAC address contained in the IPv6
link local address of this instance.
This function has no effect on IPv4 instances, MAC address instances or IPv6
instances which are not a link local address, it will return nothing in this
case.
@class function
@sort 19
@name cidr.tomac
@return Return a new CIDR instance representing the MAC address if this
instance is an IPv6 link local address, else return nothing.
@usage `local addr = luci.ip.new("fe80::6666:b3ff:fe47:e1b9")
print(addr:tomac()) -- "64:66:B3:47:E1:B9"`
]]
---[[
Derive IPv6 link local address from MAC address CIDR instance.
Constructs a CIDR instance representing the IPv6 link local address of the
MAC address represented by this instance.
This function has no effect on IPv4 instances or IPv6 instances, it will return
nothing in this case.
@class function
@sort 20
@name cidr.tolinklocal
@return Return a new CIDR instance representing the IPv6 link local address.
@usage `local mac = luci.ip.new("64:66:B3:47:E1:B9")
print(mac:tolinklocal()) -- "fe80::6666:b3ff:fe47:e1b9"`
]]
---[[
Test whether CIDR contains given range.
@class function
@sort 21
@sort 16
@name cidr.contains
@param addr A `luci.ip.cidr` instance or a string convertable by
`luci.ip.new()` to test.
@ -888,11 +704,7 @@ print(range:contains("10.0.0.0/8")) -- false
local range6 = luci.ip.new("fe80::/10")
print(range6:contains("fe80::221:63f:fe75:aa17/64")) -- true
print(range6:contains("fd9b:6b3:c5:0:221:63f:fe75:aa17/64")) -- false
local intel_macs = luci.ip.MAC("C0:B6:F9:00:00:00/24")
print(intel_macs:contains("C0:B6:F9:A3:C:11")) -- true
print(intel_macs:contains("64:66:B3:47:E1:B9")) -- false`
print(range6:contains("fd9b:6b3:c5:0:221:63f:fe75:aa17/64")) -- false`
]]
---[[
@ -900,7 +712,7 @@ Add given amount to CIDR instance. If the result would overflow the maximum
address space, the result is set to the highest possible address.
@class function
@sort 22
@sort 17
@name cidr.add
@param amount A numeric value between 0 and 0xFFFFFFFF, a
`luci.ip.cidr` instance or a string convertable by
@ -914,42 +726,32 @@ address space, the result is set to the highest possible address.
this instance plus the added amount or the highest possible address if
the addition overflowed the available address space.</li></ul>
@usage `local addr = luci.ip.new("192.168.1.1/24")
print(addr:add(250)) -- "192.168.1.251/24"
print(addr:add("0.0.99.0")) -- "192.168.100.1/24"
print(addr:add(250)) -- "192.168.1.251/24"
print(addr:add("0.0.99.0")) -- "192.168.100.1/24"
addr:add(256, true) -- true
print(addr) -- "192.168.2.1/24
addr:add(256, true) -- true
print(addr) -- "192.168.2.1/24
addr:add("255.0.0.0", true) -- false (overflow)
print(addr) -- "255.255.255.255/24
addr:add("255.0.0.0", true) -- false (overflow)
print(addr) -- "255.255.255.255/24
local addr6 = luci.ip.new("fe80::221:63f:fe75:aa17/64")
print(addr6:add(256)) -- "fe80::221:63f:fe75:ab17/64"
print(addr6:add("::ffff:0")) -- "fe80::221:640:fe74:aa17/64"
print(addr6:add(256)) -- "fe80::221:63f:fe75:ab17/64"
print(addr6:add("::ffff:0")) -- "fe80::221:640:fe74:aa17/64"
addr6:add(256, true) -- true
print(addr6) -- "fe80::221:63f:fe75:ab17/64
addr:add(256, true) -- true
print(addr) -- "fe80::221:63f:fe75:ab17/64
addr6:add("ffff::", true) -- false (overflow)
print(addr6) -- "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64"
local mac = luci.ip.new("00:14:22:01:23:45")
print(mac:add(256)) -- "00:14:22:01:24:45"
print(mac:add("0:0:0:0:FF:0") -- "00:14:22:02:22:45"
mac:add(256, true) -- true
print(mac) -- "00:14:22:01:24:45"
mac:add("FF:FF:0:0:0:0", true) -- false (overflow)
print(mac) -- "FF:FF:FF:FF:FF:FF"`
addr:add("ffff::", true) -- false (overflow)
print(addr) -- "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64"`
]]
---[[
Subtract given amount from CIDR instance. If the result would under, the lowest
Substract given amount from CIDR instance. If the result would under, the lowest
possible address is returned.
@class function
@sort 23
@sort 18
@name cidr.sub
@param amount A numeric value between 0 and 0xFFFFFFFF, a
`luci.ip.cidr` instance or a string convertable by
@ -957,11 +759,11 @@ possible address is returned.
@param inplace If `true`, modify this instance instead of returning
a new derived CIDR instance.
@return <ul>
<li>When subtracting inplace: Return `true` if the subtraction
succeeded or `false` when the subtraction underflowed.</li>
<li>When substracting inplace: Return `true` if the substraction
succeded or `false` when the substraction underflowed.</li>
<li>When deriving new CIDR: Return new instance representing the value of
this instance minus the subtracted amount or the lowest address if
the subtraction underflowed.</li></ul>
this instance minus the substracted amount or the lowest address if
the substraction underflowed.</li></ul>
@usage `local addr = luci.ip.new("192.168.1.1/24")
print(addr:sub(256)) -- "192.168.0.1/24"
print(addr:sub("0.168.0.0")) -- "192.0.1.1/24"
@ -980,24 +782,14 @@ addr:sub(256, true) -- true
print(addr) -- "fe80::221:63f:fe75:a917/64"
addr:sub("ffff::", true) -- false (underflow)
print(addr) -- "::/64"
local mac = luci.ip.new("00:14:22:01:23:45")
print(mac:sub(256)) -- "00:14:22:01:22:45"
print(mac:sub("0:0:0:0:FF:0") -- "00:14:22:00:24:45"
mac:sub(256, true) -- true
print(mac) -- "00:14:22:01:22:45"
mac:sub("FF:FF:0:0:0:0", true) -- false (overflow)
print(mac) -- "00:00:00:00:00:00"`
print(addr) -- "::/64"`
]]
---[[
Calculate the lowest possible host address within this CIDR instance.
@class function
@sort 24
@sort 19
@name cidr.minhost
@return Returns a new CIDR instance representing the lowest host address
within this range.
@ -1005,17 +797,14 @@ Calculate the lowest possible host address within this CIDR instance.
print(addr:minhost()) -- "192.168.123.1"
local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
print(addr6:minhost()) -- "fd9b:62b3:9cc5::1"
local mac = luci.ip.new("00:14:22:01:22:45/32")
print(mac:minhost()) -- "00:14:22:01:00:01"`
print(addr6:minhost()) -- "fd9b:62b3:9cc5::1"`
]]
---[[
Calculate the highest possible host address within this CIDR instance.
@class function
@sort 25
@sort 20
@name cidr.maxhost
@return Returns a new CIDR instance representing the highest host address
within this range.
@ -1023,24 +812,20 @@ Calculate the highest possible host address within this CIDR instance.
print(addr:maxhost()) -- "192.168.123.254" (.255 is broadcast)
local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
print(addr6:maxhost()) -- "fd9b:62b3:9cc5:0:ffff:ffff:ffff:ffff"
local mac = luci.ip.new("00:14:22:01:22:45/32")
print(mac:maxhost()) -- "00:14:22:01:FF:FF"`
print(addr6:maxhost()) -- "fd9b:62b3:9cc5:0:ffff:ffff:ffff:ffff"`
]]
---[[
Convert CIDR instance into string representation.
If the prefix size of instance is less than 32 for IPv4, 128 for IPv6 or 48 for
MACs, the address is returned in the form "address/prefix" otherwise just
"address".
If the prefix size of instance is less than 32 for IPv4 or 128 for IPv6, the
address is returned in the form "address/prefix" otherwise just "address".
It is usually not required to call this function directly as CIDR objects
define it as __tostring function in the associated metatable.
@class function
@sort 26
@sort 21
@name cidr.string
@return Returns a string representing the range or address of this CIDR instance
]]

View File

@ -33,7 +33,7 @@ module "nixio.README"
-- <br />In general all functions are namend and behave like their POSIX API
-- counterparts - where applicable - applying the following rules:
-- <ul>
-- <li>Functions should be named like the underlying POSIX API function omitting
-- <li>Functions should be named like the underlying POSIX API function ommiting
-- prefixes or suffixes - especially when placed in an object-context (
-- lockf -> File:lock, fsync -> File:sync, dup2 -> dup, ...)</li>
-- <li>If you are unclear about the behaviour of a function you should consult
@ -41,10 +41,10 @@ module "nixio.README"
-- <li>If the name is significantly different from the POSIX-function, the
-- underlying function(s) are stated in the documentation.</li>
-- <li>Parameters should reflect those of the C-API, buffer length arguments and
-- by-reference parameters should be omitted for practical purposes.</li>
-- by-reference parameters should be ommitted for pratical purposes.</li>
-- <li>If a C function accepts a bitfield as parameter, it should be translated
-- into lower case string flags representing the flags if the bitfield is the
-- last parameter and also omitting prefixes or suffixes. (e.g. waitpid
-- last parameter and also ommiting prefixes or suffixes. (e.g. waitpid
-- (pid, &s, WNOHANG | WUNTRACED) -> waitpid(pid, "nohang", "untraced"),
-- getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) ->
-- Socket:getopt("socket", "reuseaddr"), etc.) </li>

View File

@ -71,7 +71,7 @@ module "nixio.Socket"
--- Send a message on the socket.
-- This function is identical to sendto except for the missing destination
-- parameters. See the sendto description for a detailed description.
-- paramters. See the sendto description for a detailed description.
-- @class function
-- @name Socket.send
-- @param buffer Buffer holding the data to be written.

View File

@ -24,15 +24,15 @@ module "nixio.UnifiedIO"
-- @class function
-- @name UnifiedIO.readall
-- @usage This function uses the low-level read function of the descriptor.
-- @usage If the length parameter is omitted, this function returns all data
-- @usage If the length parameter is ommited, this function returns all data
-- that can be read before an end-of-file, end-of-stream, connection shutdown
-- or similar happens.
-- @usage If the descriptor is non-blocking this function may fail with EAGAIN.
-- @param length Bytes to read (optional)
-- @return data that was successfully read if no error occurred
-- @return data that was successfully read if no error occured
-- @return - reserved for error code -
-- @return - reserved for error message -
-- @return data that was successfully read even if an error occurred
-- @return data that was successfully read even if an error occured
--- Write a block of data and wait until all data is written.
-- @class function
@ -40,10 +40,10 @@ module "nixio.UnifiedIO"
-- @usage This function uses the low-level write function of the descriptor.
-- @usage If the descriptor is non-blocking this function may fail with EAGAIN.
-- @param block Bytes to write
-- @return bytes that were successfully written if no error occurred
-- @return bytes that were successfully written if no error occured
-- @return - reserved for error code -
-- @return - reserved for error message -
-- @return bytes that were successfully written even if an error occurred
-- @return bytes that were successfully written even if an error occured
--- Create a line-based iterator.
-- Lines may end with either \n or \r\n, these control chars are not included
@ -56,7 +56,7 @@ module "nixio.UnifiedIO"
-- to stop reading line-based and want to use the read(all) functions instead
-- you can pass "true" to the iterator which will flush the buffer
-- and return the bufferd data.
-- @usage If the limit parameter is omitted, this function uses the nixio
-- @usage If the limit parameter is ommited, this function uses the nixio
-- buffersize (8192B by default).
-- @usage If the descriptor is non-blocking the iterator may fail with EAGAIN.
-- @usage The iterator can be used as an LTN12 source.
@ -69,7 +69,7 @@ module "nixio.UnifiedIO"
-- @usage This function uses the low-level read function of the descriptor.
-- @usage The blocksize given is only advisory and to be seen as an upper limit,
-- if an underlying read returns less bytes the chunk is nevertheless returned.
-- @usage If the limit parameter is omitted, the iterator returns data
-- @usage If the limit parameter is ommited, the iterator returns data
-- until an end-of-file, end-of-stream, connection shutdown or similar happens.
-- @usage The iterator will not buffer so it is safe to mix with calls to read.
-- @usage If the descriptor is non-blocking the iterator may fail with EAGAIN.
@ -94,15 +94,15 @@ module "nixio.UnifiedIO"
-- @name UnifiedIO.copy
-- @usage This function uses the blocksource function of the source descriptor
-- and the sink function of the target descriptor.
-- @usage If the limit parameter is omitted, data is copied
-- @usage If the limit parameter is ommited, data is copied
-- until an end-of-file, end-of-stream, connection shutdown or similar happens.
-- @usage If the descriptor is non-blocking the function may fail with EAGAIN.
-- @param fdout Target Descriptor
-- @param size Bytes to copy (optional)
-- @return bytes that were successfully written if no error occurred
-- @return bytes that were successfully written if no error occured
-- @return - reserved for error code -
-- @return - reserved for error message -
-- @return bytes that were successfully written even if an error occurred
-- @return bytes that were successfully written even if an error occured
--- Copy data from the current descriptor to another one using kernel-space
-- copying if possible.
@ -111,15 +111,15 @@ module "nixio.UnifiedIO"
-- @usage This function uses the sendfile() syscall to copy the data or the
-- blocksource function of the source descriptor and the sink function
-- of the target descriptor as a fallback mechanism.
-- @usage If the limit parameter is omitted, data is copied
-- @usage If the limit parameter is ommited, data is copied
-- until an end-of-file, end-of-stream, connection shutdown or similar happens.
-- @usage If the descriptor is non-blocking the function may fail with EAGAIN.
-- @param fdout Target Descriptor
-- @param size Bytes to copy (optional)
-- @return bytes that were successfully written if no error occurred
-- @return bytes that were successfully written if no error occured
-- @return - reserved for error code -
-- @return - reserved for error message -
-- @return bytes that were successfully written even if an error occurred
-- @return bytes that were successfully written even if an error occured
--- Close the descriptor.
-- @class function

View File

@ -47,7 +47,7 @@ module "nixio.fs"
-- @name nixio.fs.rename
-- @param src Source path
-- @param dest Destination path
-- @usage It is normally not possible to rename files across filesystems.
-- @usage It is normally not possible to rename files accross fileystems.
-- @return true
--- Remove an empty directory.

View File

@ -118,7 +118,7 @@ module "nixio"
-- @param flag1 First Flag ["append", "creat", "excl", "nonblock", "ndelay",
-- "sync", "trunc", "rdonly", "wronly", "rdwr"]
-- @param ... More Flags [-"-]
-- @return flag to be used as second parameter to open
-- @return flag to be used as second paramter to open
--- Duplicate a file descriptor.
-- @class function
@ -167,7 +167,7 @@ module "nixio"
--- Wait for some event on a file descriptor.
-- poll() sets the revents-field of the tables provided by fds to a bitfield
-- indicating the events that occurred.
-- indicating the events that occured.
-- @class function
-- @usage This function works in-place on the provided table and only
-- writes the revents field, you can use other fields on your demand.
@ -303,7 +303,7 @@ module "nixio"
--- Set or unset a environment variable.
-- @class function
-- @name nixio.setenv
-- @usage The environment variable will be unset if value is omitted.
-- @usage The environment variable will be unset if value is ommited.
-- @param variable Variable
-- @param value Value (optional)
-- @return true

23
luci.mk
View File

@ -7,7 +7,7 @@
LUCI_NAME?=$(notdir ${CURDIR})
LUCI_TYPE?=$(word 2,$(subst -, ,$(LUCI_NAME)))
LUCI_BASENAME?=$(patsubst luci-$(LUCI_TYPE)-%,%,$(LUCI_NAME))
LUCI_LANGUAGES:=$(sort $(filter-out templates,$(notdir $(wildcard ${CURDIR}/po/*))))
LUCI_LANGUAGES:=$(filter-out templates,$(notdir $(wildcard ${CURDIR}/po/*)))
LUCI_DEFAULTS:=$(notdir $(wildcard ${CURDIR}/root/etc/uci-defaults/*))
LUCI_PKGARCH?=$(if $(realpath src/Makefile),,all)
@ -36,8 +36,8 @@ LUCI_LANG.sv=Svenska (Swedish)
LUCI_LANG.tr=Türkçe (Turkish)
LUCI_LANG.uk=украї́нська (Ukrainian)
LUCI_LANG.vi=Tiếng Việt (Vietnamese)
LUCI_LANG.zh-cn=中文 (Chinese)
LUCI_LANG.zh-tw=臺灣華語 (Taiwanese)
LUCI_LANG.zh-cn=简体中文 (Simplified Chinese)
LUCI_LANG.zh-tw=繁体中文 (Traditional Chinese)
# Submenu titles
LUCI_MENU.col=1. Collections
@ -96,7 +96,6 @@ define Package/$(PKG_NAME)
SUBMENU:=$(if $(LUCI_MENU.$(LUCI_TYPE)),$(LUCI_MENU.$(LUCI_TYPE)),$(LUCI_MENU.app))
TITLE:=$(if $(LUCI_TITLE),$(LUCI_TITLE),LuCI $(LUCI_NAME) $(LUCI_TYPE))
DEPENDS:=$(LUCI_DEPENDS)
$(if $(LUCI_EXTRA_DEPENDS),EXTRA_DEPENDS:=$(LUCI_EXTRA_DEPENDS))
$(if $(LUCI_PKGARCH),PKGARCH:=$(LUCI_PKGARCH))
endef
@ -111,13 +110,13 @@ ifeq ($(PKG_NAME),luci-base)
define Package/luci-base/config
config LUCI_SRCDIET
bool "Minify Lua sources"
default n
default y
menu "Translations"$(foreach lang,$(LUCI_LANGUAGES),
config LUCI_LANG_$(lang)
tristate "$(shell echo '$(LUCI_LANG.$(lang))' | sed -e 's/^.* (\(.*\))$$/\1/') ($(lang))")
tristate "$(shell echo '$(LUCI_LANG.$(lang))' | sed -e 's/^.* (\(.*\))$$/\1/') ($(lang))"
default $(shell if [ '$(lang)' == 'zh-cn' ]; then echo y; else echo n; fi))
endmenu
endef
endif
@ -137,7 +136,7 @@ endef
ifneq ($(wildcard ${CURDIR}/src/Makefile),)
MAKE_PATH := src/
MAKE_VARS += FPIC="$(FPIC)" LUCI_VERSION="$(PKG_VERSION)" LUCI_GITBRANCH="$(PKG_GITBRANCH)"
MAKE_VARS += FPIC="$(FPIC)" LUA_TARGET=strip LUCI_VERSION="$(PKG_VERSION)" LUCI_GITBRANCH="$(PKG_GITBRANCH)"
define Build/Compile
$(call Build/Compile/Default,clean compile)
@ -158,6 +157,14 @@ define SrcDiet
done
endef
#Marked by lintel: debug.lua bad bytecode after luac
define SrcCompile
$(FIND) $(1) -type f -name '*.lua' | while read src; do \
if luac -s -o "$$$$src.o" "$$$$src"; \
then mv "$$$$src.o" "$$$$src"; fi; \
done
endef
define SubstituteVersion
$(FIND) $(1) -type f -name '*.htm' | while read src; do \
$(SED) 's/<%# *\([^ ]*\)PKG_VERSION *%>/\1$(PKG_VERSION)/g' \

View File

@ -12,11 +12,11 @@ LUCI_TYPE:=mod
LUCI_BASENAME:=base
LUCI_TITLE:=LuCI core libraries
LUCI_DEPENDS:=+lua +luci-lib-nixio +luci-lib-ip +rpcd +libubus-lua +luci-lib-jsonc +liblucihttp-lua
LUCI_DEPENDS:=+lua +libuci-lua +luci-lib-nixio +luci-lib-ip +rpcd +libubus-lua +luci-lib-jsonc
PKG_SOURCE:=LuaSrcDiet-0.12.1.tar.bz2
PKG_SOURCE_URL:=https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/luasrcdiet
PKG_HASH:=ed7680f2896269ae8633756e7edcf09050812f78c8f49e280e63c30d14f35aea
PKG_MD5SUM:=ed7680f2896269ae8633756e7edcf09050812f78c8f49e280e63c30d14f35aea
PKG_LICENSE:=Apache-2.0
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/LuaSrcDiet-0.12.1
@ -26,7 +26,6 @@ include $(INCLUDE_DIR)/host-build.mk
define Package/luci-base/conffiles
/etc/luci-uploads
/etc/config/luci
/etc/config/ucitrack
endef
include ../../luci.mk

View File

@ -23,62 +23,6 @@ function Dec(x) {
return (/^-?\d+(?:\.\d+)?$/.test(x) ? +x : NaN);
}
function IPv4(x) {
if (!x.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/))
return null;
if (RegExp.$1 > 255 || RegExp.$2 > 255 || RegExp.$3 > 255 || RegExp.$4 > 255)
return null;
return [ +RegExp.$1, +RegExp.$2, +RegExp.$3, +RegExp.$4 ];
}
function IPv6(x) {
if (x.match(/^([a-fA-F0-9:]+):(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/)) {
var v6 = RegExp.$1, v4 = IPv4(RegExp.$2);
if (!v4)
return null;
x = v6 + ':' + (v4[0] * 256 + v4[1]).toString(16)
+ ':' + (v4[2] * 256 + v4[3]).toString(16);
}
if (!x.match(/^[a-fA-F0-9:]+$/))
return null;
var prefix_suffix = x.split(/::/);
if (prefix_suffix.length > 2)
return null;
var prefix = (prefix_suffix[0] || '0').split(/:/);
var suffix = prefix_suffix.length > 1 ? (prefix_suffix[1] || '0').split(/:/) : [];
if (suffix.length ? (prefix.length + suffix.length > 7) : (prefix.length > 8))
return null;
var i, word;
var words = [];
for (i = 0, word = parseInt(prefix[0], 16); i < prefix.length; word = parseInt(prefix[++i], 16))
if (prefix[i].length <= 4 && !isNaN(word) && word <= 0xFFFF)
words.push(word);
else
return null;
for (i = 0; i < (8 - prefix.length - suffix.length); i++)
words.push(0);
for (i = 0, word = parseInt(suffix[0], 16); i < suffix.length; word = parseInt(suffix[++i], 16))
if (suffix[i].length <= 4 && !isNaN(word) && word <= 0xFFFF)
words.push(word);
else
return null;
return words;
}
var cbi_validators = {
'integer': function()
@ -109,63 +53,69 @@ var cbi_validators = {
'ip4addr': function()
{
var m = this.match(/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?:\/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|\/(\d{1,2}))?$/);
return !!(m && IPv4(m[1]) && (m[2] ? IPv4(m[2]) : (m[3] ? cbi_validators.ip4prefix.apply(m[3]) : true)));
if (this.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})(\/(\S+))?$/))
{
return (RegExp.$1 >= 0) && (RegExp.$1 <= 255) &&
(RegExp.$2 >= 0) && (RegExp.$2 <= 255) &&
(RegExp.$3 >= 0) && (RegExp.$3 <= 255) &&
(RegExp.$4 >= 0) && (RegExp.$4 <= 255) &&
((RegExp.$6.indexOf('.') < 0)
? ((RegExp.$6 >= 0) && (RegExp.$6 <= 32))
: (cbi_validators.ip4addr.apply(RegExp.$6)))
;
}
return false;
},
'ip6addr': function()
{
var m = this.match(/^([0-9a-fA-F:.]+)(?:\/(\d{1,3}))?$/);
return !!(m && IPv6(m[1]) && (m[2] ? cbi_validators.ip6prefix.apply(m[2]) : true));
},
if( this.match(/^([a-fA-F0-9:.]+)(\/(\d+))?$/) )
{
if( !RegExp.$2 || ((RegExp.$3 >= 0) && (RegExp.$3 <= 128)) )
{
var addr = RegExp.$1;
'ip4prefix': function()
{
return !isNaN(this) && this >= 0 && this <= 32;
},
if( addr == '::' )
{
return true;
}
'ip6prefix': function()
{
return !isNaN(this) && this >= 0 && this <= 128;
},
if( addr.indexOf('.') > 0 )
{
var off = addr.lastIndexOf(':');
'cidr': function()
{
return cbi_validators.cidr4.apply(this) ||
cbi_validators.cidr6.apply(this);
},
if( !(off && cbi_validators.ip4addr.apply(addr.substr(off+1))) )
return false;
'cidr4': function()
{
var m = this.match(/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\/(\d{1,2})$/);
return !!(m && IPv4(m[1]) && cbi_validators.ip4prefix.apply(m[2]));
},
addr = addr.substr(0, off) + ':0:0';
}
'cidr6': function()
{
var m = this.match(/^([0-9a-fA-F:.]+)\/(\d{1,3})$/);
return !!(m && IPv6(m[1]) && cbi_validators.ip6prefix.apply(m[2]));
},
if( addr.indexOf('::') >= 0 )
{
var colons = 0;
var fill = '0';
'ipnet4': function()
{
var m = this.match(/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/);
return !!(m && IPv4(m[1]) && IPv4(m[2]));
},
for( var i = 1; i < (addr.length-1); i++ )
if( addr.charAt(i) == ':' )
colons++;
'ipnet6': function()
{
var m = this.match(/^([0-9a-fA-F:.]+)\/([0-9a-fA-F:.]+)$/);
return !!(m && IPv6(m[1]) && IPv6(m[2]));
},
if( colons > 7 )
return false;
'ip6hostid': function()
{
if (this == "eui64" || this == "random")
return true;
for( var i = 0; i < (7 - colons); i++ )
fill += ':0';
var v6 = IPv6(this);
return !(!v6 || v6[0] || v6[1] || v6[2] || v6[3]);
if (addr.match(/^(.*?)::(.*?)$/))
addr = (RegExp.$1 ? RegExp.$1 + ':' : '') + fill +
(RegExp.$2 ? ':' + RegExp.$2 : '');
}
return (addr.match(/^(?:[a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}$/) != null);
}
}
return false;
},
'ipmask': function()
@ -176,16 +126,40 @@ var cbi_validators = {
'ipmask4': function()
{
return cbi_validators.cidr4.apply(this) ||
cbi_validators.ipnet4.apply(this) ||
cbi_validators.ip4addr.apply(this);
var ip = this, mask = 32;
if (ip.match(/^(\S+)\/(\S+)$/))
{
ip = RegExp.$1;
mask = RegExp.$2;
}
if (!isNaN(mask) && (mask < 0 || mask > 32))
return false;
if (isNaN(mask) && !cbi_validators.ip4addr.apply(mask))
return false;
return cbi_validators.ip4addr.apply(ip);
},
'ipmask6': function()
{
return cbi_validators.cidr6.apply(this) ||
cbi_validators.ipnet6.apply(this) ||
cbi_validators.ip6addr.apply(this);
var ip = this, mask = 128;
if (ip.match(/^(\S+)\/(\S+)$/))
{
ip = RegExp.$1;
mask = RegExp.$2;
}
if (!isNaN(mask) && (mask < 0 || mask > 128))
return false;
if (isNaN(mask) && !cbi_validators.ip6addr.apply(mask))
return false;
return cbi_validators.ip6addr.apply(ip);
},
'port': function()
@ -215,16 +189,15 @@ var cbi_validators = {
{
return cbi_validators.hostname.apply(this) ||
((ipv4only != 1) && cbi_validators.ipaddr.apply(this)) ||
((ipv4only == 1) && cbi_validators.ip4addr.apply(this));
((ipv4only == 1) && cb_validators.ip4addr.apply(this));
},
'hostname': function(strict)
'hostname': function()
{
if (this.length <= 253)
return (this.match(/^[a-zA-Z0-9_]+$/) != null ||
return (this.match(/^[a-zA-Z0-9]+$/) != null ||
(this.match(/^[a-zA-Z0-9_][a-zA-Z0-9_\-.]*[a-zA-Z0-9]$/) &&
this.match(/[^0-9.]/))) &&
(!strict || !this.match(/^_/));
this.match(/[^0-9.]/)));
return false;
},

View File

@ -39,7 +39,7 @@ XHR = function()
this._xmlHttp.abort();
}
this.get = function(url,data,callback,timeout)
this.get = function(url,data,callback)
{
this.reinit();
@ -56,9 +56,6 @@ XHR = function()
xhr.open('GET', url, true);
if (!isNaN(timeout))
xhr.timeout = timeout;
xhr.onreadystatechange = function()
{
if (xhr.readyState == 4) {
@ -79,7 +76,7 @@ XHR = function()
xhr.send(null);
}
this.post = function(url,data,callback,timeout)
this.post = function(url,data,callback)
{
this.reinit();
@ -93,10 +90,6 @@ XHR = function()
}
xhr.open('POST', url, true);
if (!isNaN(timeout))
xhr.timeout = timeout;
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send(code);
}
@ -175,7 +168,7 @@ XHR.get = function(url, data, callback)
(new XHR()).get(url, data, callback);
}
XHR.poll = function(interval, url, data, callback, post)
XHR.poll = function(interval, url, data, callback)
{
if (isNaN(interval) || interval < 1)
interval = 5;
@ -188,38 +181,22 @@ XHR.poll = function(interval, url, data, callback, post)
for (var i = 0, e = XHR._q[0]; i < XHR._q.length; e = XHR._q[++i])
{
if (!(XHR._t % e.interval) && !e.xhr.busy())
e.xhr[post ? 'post' : 'get'](e.url, e.data, e.callback, e.interval * 1000 - 5);
e.xhr.get(e.url, e.data, e.callback);
}
XHR._t++;
};
}
var e = {
XHR._q.push({
interval: interval,
callback: callback,
url: url,
data: data,
xhr: new XHR()
};
});
XHR._q.push(e);
XHR.run();
return e;
}
XHR.stop = function(e)
{
for (var i = 0; XHR._q && XHR._q[i]; i++) {
if (XHR._q[i] === e) {
e.xhr.cancel();
XHR._q.splice(i, 1);
return true;
}
}
return false;
}
XHR.halt = function()

View File

@ -132,50 +132,43 @@ function ip6prefix(val)
return ( val and val >= 0 and val <= 128 )
end
function cidr4(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$")
return ip4addr(ip) and ip4prefix(mask)
end
function cidr6(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$")
return ip6addr(ip) and ip6prefix(mask)
end
function ipnet4(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$")
return ip4addr(ip) and ip4addr(mask)
end
function ipnet6(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$")
return ip6addr(ip) and ip6addr(mask)
end
function ipmask(val)
return ipmask4(val) or ipmask6(val)
end
function ipmask4(val)
return cidr4(val) or ipnet4(val) or ip4addr(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$")
local bits = tonumber(mask)
if bits and (bits < 0 or bits > 32) then
return false
end
if not bits and mask and not ip4addr(mask) then
return false
end
return ip4addr(ip or val)
end
function ipmask6(val)
return cidr6(val) or ipnet6(val) or ip6addr(val)
local ip, mask = val:match("^([^/]+)/([^/]+)$")
local bits = tonumber(mask)
if bits and (bits < 0 or bits > 128) then
return false
end
if not bits and mask and not ip6addr(mask) then
return false
end
return ip6addr(ip or val)
end
function ip6hostid(val)
if val == "eui64" or val == "random" then
return true
else
local addr = ip.IPv6(val)
if addr and addr:prefix() == 128 and addr:lower("::1:0:0:0:0") then
return true
end
if val and val:match("^[a-fA-F0-9:]+$") and (#val > 2) then
return (ip6addr("2001:db8:0:0" .. val) or ip6addr("2001:db8:0:0:" .. val))
end
return false
@ -196,16 +189,32 @@ function portrange(val)
end
function macaddr(val)
return ip.checkmac(val) and true or false
if val and val:match(
"^[a-fA-F0-9]+:[a-fA-F0-9]+:[a-fA-F0-9]+:" ..
"[a-fA-F0-9]+:[a-fA-F0-9]+:[a-fA-F0-9]+$"
) then
local parts = util.split( val, ":" )
for i = 1,6 do
parts[i] = tonumber( parts[i], 16 )
if parts[i] < 0 or parts[i] > 255 then
return false
end
end
return true
end
return false
end
function hostname(val, strict)
function hostname(val)
if val and (#val < 254) and (
val:match("^[a-zA-Z_]+$") or
(val:match("^[a-zA-Z0-9_][a-zA-Z0-9_%-%.]*[a-zA-Z0-9]$") and
val:match("[^0-9%.]"))
) then
return (not strict or not val:match("^_"))
return true
end
return false
end

View File

@ -75,16 +75,11 @@ function error404(message)
http.status(404, "Not Found")
message = message or "Not Found"
local function render()
local template = require "luci.template"
template.render("error404")
end
if not util.copcall(render) then
require("luci.template")
if not util.copcall(luci.template.render, "error404") then
http.prepare_content("text/plain")
http.write(message)
end
return false
end
@ -118,8 +113,7 @@ function httpdispatch(request, prefix)
end
end
local node
for node in pathinfo:gmatch("[^/%z]+") do
for node in pathinfo:gmatch("[^/]+") do
r[#r+1] = node
end
@ -142,7 +136,8 @@ local function require_post_security(target)
if (type(required_val) == "string" and
request_val ~= required_val) or
(required_val == true and request_val == nil)
(required_val == true and
(request_val == nil or request_val == ""))
then
return false
end
@ -196,9 +191,6 @@ local function session_setup(user, pass, allowed_users)
timeout = tonumber(luci.config.sauth.sessiontime)
})
local rp = context.requestpath
and table.concat(context.requestpath, "/") or ""
if type(login) == "table" and
type(login.ubus_rpc_session) == "string"
then
@ -207,14 +199,8 @@ local function session_setup(user, pass, allowed_users)
values = { token = sys.uniqueid(16) }
})
io.stderr:write("luci: accepted login on /%s for %s from %s\n"
%{ rp, user, http.getenv("REMOTE_ADDR") or "?" })
return session_retrieve(login.ubus_rpc_session)
end
io.stderr:write("luci: failed login on /%s for %s from %s\n"
%{ rp, user, http.getenv("REMOTE_ADDR") or "?" })
end
return nil, nil
@ -233,19 +219,10 @@ function dispatch(request)
local lang = conf.main.lang or "auto"
if lang == "auto" then
local aclang = http.getenv("HTTP_ACCEPT_LANGUAGE") or ""
for aclang in aclang:gmatch("[%w_-]+") do
local country, culture = aclang:match("^([a-z][a-z])[_-]([a-zA-Z][a-zA-Z])$")
if country and culture then
local cc = "%s_%s" %{ country, culture:lower() }
if conf.languages[cc] then
lang = cc
break
elseif conf.languages[country] then
lang = country
break
end
elseif conf.languages[aclang] then
lang = aclang
for lpat in aclang:gmatch("[%w-]+") do
lpat = lpat and lpat:gsub("-", "_")
if conf.languages[lpat] then
lang = lpat
break
end
end
@ -351,23 +328,15 @@ function dispatch(request)
ifattr = function(...) return _ifattr(...) end;
attr = function(...) return _ifattr(true, ...) end;
url = build_url;
}, {__index=function(tbl, key)
}, {__index=function(table, key)
if key == "controller" then
return build_url()
elseif key == "REQUEST_URI" then
return build_url(unpack(ctx.requestpath))
elseif key == "FULL_REQUEST_URI" then
local url = { http.getenv("SCRIPT_NAME"), http.getenv("PATH_INFO") }
local query = http.getenv("QUERY_STRING")
if query and #query > 0 then
url[#url+1] = "?"
url[#url+1] = query
end
return table.concat(url, "")
elseif key == "token" then
return ctx.authtoken
else
return rawget(tbl, key) or _G[key]
return rawget(table, key) or _G[key]
end
end})
end
@ -380,7 +349,7 @@ function dispatch(request)
"https://github.com/openwrt/luci/issues"
)
if track.sysauth and not ctx.authsession then
if track.sysauth then
local authen = track.sysauth_authenticator
local _, sid, sdat, default_user, allowed_users
@ -428,9 +397,7 @@ function dispatch(request)
return
end
http.header("Set-Cookie", 'sysauth=%s; path=%s; HttpOnly%s' %{
sid, build_url(), http.getenv("HTTPS") == "on" and "; secure" or ""
})
http.header("Set-Cookie", 'sysauth=%s; path=%s' %{ sid, build_url() })
http.redirect(build_url(unpack(ctx.requestpath)))
end
@ -444,13 +411,6 @@ function dispatch(request)
ctx.authuser = sdat.username
end
if track.cors and http.getenv("REQUEST_METHOD") == "OPTIONS" then
luci.http.status(200, "OK")
luci.http.header("Access-Control-Allow-Origin", http.getenv("HTTP_ORIGIN") or "*")
luci.http.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
return
end
if c and require_post_security(c.target) then
if not test_post_security(c) then
return
@ -672,23 +632,6 @@ function node(...)
return c
end
function lookup(...)
local i, path = nil, {}
for i = 1, select('#', ...) do
local name, arg = nil, tostring(select(i, ...))
for name in arg:gmatch("[^/]+") do
path[#path+1] = name
end
end
for i = #path, 1, -1 do
local node = context.treecache[table.concat(path, ".", 1, i)]
if node and (i == #path or node.leaf) then
return node, build_url(unpack(path))
end
end
end
function _create_node(path)
if #path == 0 then
return context.tree
@ -830,16 +773,7 @@ local function _cbi(self, ...)
local state = nil
local i, res
for i, res in ipairs(maps) do
if util.instanceof(res, cbi.SimpleForm) then
io.stderr:write("Model %s returns SimpleForm but is dispatched via cbi(),\n"
% self.model)
io.stderr:write("please change %s to use the form() action instead.\n"
% table.concat(context.request, "/"))
end
res.flow = config
local cstate = res:parse()
if cstate and (not state or cstate < state) then
@ -932,7 +866,7 @@ end
function cbi(model, config)
return {
type = "cbi",
post = { ["cbi.submit"] = true },
post = { ["cbi.submit"] = "1" },
config = config,
model = model,
target = _cbi
@ -960,7 +894,6 @@ local function _form(self, ...)
local maps = luci.cbi.load(self.model, ...)
local state = nil
local i, res
for i, res in ipairs(maps) do
local cstate = res:parse()
if cstate and (not state or cstate < state) then
@ -979,7 +912,7 @@ end
function form(model)
return {
type = "cbi",
post = { ["cbi.submit"] = true },
post = { ["cbi.submit"] = "1" },
model = model,
target = _form
}

View File

@ -116,8 +116,8 @@ Create a new dispatching node and define common parameters.
---[[
Fetch or create a dispatching node without setting the target module or
enabling the node.
enabling the node.
@class function
@name get
@param ... Virtual path
@ -133,15 +133,6 @@ Fetch or create a new dispatching node.
@return Dispatching tree node
]]
---[[
Lookup node in dispatching tree.
@class function
@name lookup
@param ... Virtual path
@return Node object, canonical url or nil if the path was not found.
]]
---[[
Alias the first (lowest order) page automatically

View File

@ -1,21 +1,18 @@
-- Copyright 2008 Steven Barth <steven@midlink.org>
-- Copyright 2010-2018 Jo-Philipp Wich <jo@mein.io>
-- Licensed to the public under the Apache License 2.0.
local ltn12 = require "luci.ltn12"
local protocol = require "luci.http.protocol"
local util = require "luci.util"
local string = require "string"
local coroutine = require "coroutine"
local table = require "table"
local lhttp = require "lucihttp"
local nixio = require "nixio"
local ltn12 = require "luci.ltn12"
local table, ipairs, pairs, type, tostring, tonumber, error =
table, ipairs, pairs, type, tostring, tonumber, error
local ipairs, pairs, next, type, tostring, error =
ipairs, pairs, next, type, tostring, error
module "luci.http"
HTTP_MAX_CONTENT = 1024*100 -- 100 kB maximum content size
context = util.threadlocal()
Request = util.class()
@ -31,7 +28,7 @@ function Request.__init__(self, env, sourcein, sinkerr)
self.message = {
env = env,
headers = {},
params = urldecode_params(env.QUERY_STRING or ""),
params = protocol.urldecode_params(env.QUERY_STRING or ""),
}
self.parsed_input = false
@ -76,7 +73,10 @@ function Request.content(self)
end
function Request.getcookie(self, name)
return lhttp.header_attribute("cookie; " .. (self:getenv("HTTP_COOKIE") or ""), name)
local c = string.gsub(";" .. (self:getenv("HTTP_COOKIE") or "") .. ";", "%s*;%s*", ";")
local p = ";" .. name .. "=(.-);"
local i, j, value = c:find(p)
return value and urldecode(value)
end
function Request.getenv(self, name)
@ -90,34 +90,40 @@ end
function Request.setfilehandler(self, callback)
self.filehandler = callback
if not self.parsed_input then
return
end
-- If input has already been parsed then uploads are stored as unlinked
-- temporary files pointed to by open file handles in the parameter
-- value table. Loop all params, and invoke the file callback for any
-- param with an open file handle.
local name, value
for name, value in pairs(self.message.params) do
if type(value) == "table" then
while value.fd do
local data = value.fd:read(1024)
local eof = (not data or data == "")
callback(value, data, eof)
if eof then
value.fd:close()
value.fd = nil
-- If input has already been parsed then any files are either in temporary files
-- or are in self.message.params[key]
if self.parsed_input then
for param, value in pairs(self.message.params) do
repeat
-- We're only interested in files
if (not value["file"]) then break end
-- If we were able to write to temporary file
if (value["fd"]) then
fd = value["fd"]
local eof = false
repeat
filedata = fd:read(1024)
if (filedata:len() < 1024) then
eof = true
end
callback({ name=value["name"], file=value["file"] }, filedata, eof)
until (eof)
fd:close()
value["fd"] = nil
-- We had to read into memory
else
-- There should only be one numbered value in table - the data
for k, v in ipairs(value) do
callback({ name=value["name"], file=value["file"] }, v, true)
end
end
until true
end
end
end
function Request._parse_input(self)
parse_message_body(
protocol.parse_message_body(
self.input,
self.message,
self.filehandler
@ -216,17 +222,10 @@ function write(content, src_err)
end
if not context.headers["cache-control"] then
header("Cache-Control", "no-cache")
header("Pragma", "no-cache")
header("Expires", "0")
end
if not context.headers["x-frame-options"] then
header("X-Frame-Options", "SAMEORIGIN")
end
if not context.headers["x-xss-protection"] then
header("X-XSS-Protection", "1; mode=block")
end
if not context.headers["x-content-type-options"] then
header("X-Content-Type-Options", "nosniff")
end
context.eoh = true
coroutine.yield(3)
@ -248,307 +247,23 @@ function redirect(url)
end
function build_querystring(q)
local s, n, k, v = {}, 1, nil, nil
local s = { "?" }
for k, v in pairs(q) do
s[n+0] = (n == 1) and "?" or "&"
s[n+1] = util.urlencode(k)
s[n+2] = "="
s[n+3] = util.urlencode(v)
n = n + 4
if #s > 1 then s[#s+1] = "&" end
s[#s+1] = urldecode(k)
s[#s+1] = "="
s[#s+1] = urldecode(v)
end
return table.concat(s, "")
end
urldecode = util.urldecode
urldecode = protocol.urldecode
urlencode = util.urlencode
urlencode = protocol.urlencode
function write_json(x)
util.serialize_json(x, write)
end
-- from given url or string. Returns a table with urldecoded values.
-- Simple parameters are stored as string values associated with the parameter
-- name within the table. Parameters with multiple values are stored as array
-- containing the corresponding values.
function urldecode_params(url, tbl)
local parser, name
local params = tbl or { }
parser = lhttp.urlencoded_parser(function (what, buffer, length)
if what == parser.TUPLE then
name, value = nil, nil
elseif what == parser.NAME then
name = lhttp.urldecode(buffer)
elseif what == parser.VALUE and name then
params[name] = lhttp.urldecode(buffer) or ""
end
return true
end)
if parser then
parser:parse((url or ""):match("[^?]*$"))
parser:parse(nil)
end
return params
end
-- separated by "&". Tables are encoded as parameters with multiple values by
-- repeating the parameter name with each value.
function urlencode_params(tbl)
local k, v
local n, enc = 1, {}
for k, v in pairs(tbl) do
if type(v) == "table" then
local i, v2
for i, v2 in ipairs(v) do
if enc[1] then
enc[n] = "&"
n = n + 1
end
enc[n+0] = lhttp.urlencode(k)
enc[n+1] = "="
enc[n+2] = lhttp.urlencode(v2)
n = n + 3
end
else
if enc[1] then
enc[n] = "&"
n = n + 1
end
enc[n+0] = lhttp.urlencode(k)
enc[n+1] = "="
enc[n+2] = lhttp.urlencode(v)
n = n + 3
end
end
return table.concat(enc, "")
end
-- Content-Type. Stores all extracted data associated with its parameter name
-- in the params table within the given message object. Multiple parameter
-- values are stored as tables, ordinary ones as strings.
-- If an optional file callback function is given then it is feeded with the
-- file contents chunk by chunk and only the extracted file name is stored
-- within the params table. The callback function will be called subsequently
-- with three arguments:
-- o Table containing decoded (name, file) and raw (headers) mime header data
-- o String value containing a chunk of the file data
-- o Boolean which indicates wheather the current chunk is the last one (eof)
function mimedecode_message_body(src, msg, file_cb)
local parser, header, field
local len, maxlen = 0, tonumber(msg.env.CONTENT_LENGTH or nil)
parser, err = lhttp.multipart_parser(msg.env.CONTENT_TYPE, function (what, buffer, length)
if what == parser.PART_INIT then
field = { }
elseif what == parser.HEADER_NAME then
header = buffer:lower()
elseif what == parser.HEADER_VALUE and header then
if header:lower() == "content-disposition" and
lhttp.header_attribute(buffer, nil) == "form-data"
then
field.name = lhttp.header_attribute(buffer, "name")
field.file = lhttp.header_attribute(buffer, "filename")
field[1] = field.file
end
if field.headers then
field.headers[header] = buffer
else
field.headers = { [header] = buffer }
end
elseif what == parser.PART_BEGIN then
return not field.file
elseif what == parser.PART_DATA and field.name and length > 0 then
if field.file then
if file_cb then
file_cb(field, buffer, false)
msg.params[field.name] = msg.params[field.name] or field
else
if not field.fd then
field.fd = nixio.mkstemp(field.name)
end
if field.fd then
field.fd:write(buffer)
msg.params[field.name] = msg.params[field.name] or field
end
end
else
field.value = buffer
end
elseif what == parser.PART_END and field.name then
if field.file and msg.params[field.name] then
if file_cb then
file_cb(field, "", true)
elseif field.fd then
field.fd:seek(0, "set")
end
else
local val = msg.params[field.name]
if type(val) == "table" then
val[#val+1] = field.value or ""
elseif val ~= nil then
msg.params[field.name] = { val, field.value or "" }
else
msg.params[field.name] = field.value or ""
end
end
field = nil
elseif what == parser.ERROR then
err = buffer
end
return true
end, HTTP_MAX_CONTENT)
return ltn12.pump.all(src, function (chunk)
len = len + (chunk and #chunk or 0)
if maxlen and len > maxlen + 2 then
return nil, "Message body size exceeds Content-Length"
end
if not parser or not parser:parse(chunk) then
return nil, err
end
return true
end)
end
-- Content-Type. Stores all extracted data associated with its parameter name
-- in the params table within the given message object. Multiple parameter
-- values are stored as tables, ordinary ones as strings.
function urldecode_message_body(src, msg)
local err, name, value, parser
local len, maxlen = 0, tonumber(msg.env.CONTENT_LENGTH or nil)
parser = lhttp.urlencoded_parser(function (what, buffer, length)
if what == parser.TUPLE then
name, value = nil, nil
elseif what == parser.NAME then
name = lhttp.urldecode(buffer, lhttp.DECODE_PLUS)
elseif what == parser.VALUE and name then
local val = msg.params[name]
if type(val) == "table" then
val[#val+1] = lhttp.urldecode(buffer, lhttp.DECODE_PLUS) or ""
elseif val ~= nil then
msg.params[name] = { val, lhttp.urldecode(buffer, lhttp.DECODE_PLUS) or "" }
else
msg.params[name] = lhttp.urldecode(buffer, lhttp.DECODE_PLUS) or ""
end
elseif what == parser.ERROR then
err = buffer
end
return true
end, HTTP_MAX_CONTENT)
return ltn12.pump.all(src, function (chunk)
len = len + (chunk and #chunk or 0)
if maxlen and len > maxlen + 2 then
return nil, "Message body size exceeds Content-Length"
elseif len > HTTP_MAX_CONTENT then
return nil, "Message body size exceeds maximum allowed length"
end
if not parser or not parser:parse(chunk) then
return nil, err
end
return true
end)
end
-- This function will examine the Content-Type within the given message object
-- to select the appropriate content decoder.
-- Currently the application/x-www-urlencoded and application/form-data
-- mime types are supported. If the encountered content encoding can't be
-- handled then the whole message body will be stored unaltered as "content"
-- property within the given message object.
function parse_message_body(src, msg, filecb)
if msg.env.CONTENT_LENGTH or msg.env.REQUEST_METHOD == "POST" then
local ctype = lhttp.header_attribute(msg.env.CONTENT_TYPE, nil)
-- Is it multipart/mime ?
if ctype == "multipart/form-data" then
return mimedecode_message_body(src, msg, filecb)
-- Is it application/x-www-form-urlencoded ?
elseif ctype == "application/x-www-form-urlencoded" then
return urldecode_message_body(src, msg)
end
-- Unhandled encoding
-- If a file callback is given then feed it chunk by chunk, else
-- store whole buffer in message.content
local sink
-- If we have a file callback then feed it
if type(filecb) == "function" then
local meta = {
name = "raw",
encoding = msg.env.CONTENT_TYPE
}
sink = function( chunk )
if chunk then
return filecb(meta, chunk, false)
else
return filecb(meta, nil, true)
end
end
-- ... else append to .content
else
msg.content = ""
msg.content_length = 0
sink = function( chunk )
if chunk then
if ( msg.content_length + #chunk ) <= HTTP_MAX_CONTENT then
msg.content = msg.content .. chunk
msg.content_length = msg.content_length + #chunk
return true
else
return nil, "POST data exceeds maximum allowed length"
end
end
return true
end
end
-- Pump data...
while true do
local ok, err = ltn12.pump.step( src, sink )
if not ok and err then
return nil, err
elseif not ok then -- eof
return true
end
end
return true
end
return false
end

View File

@ -6,24 +6,25 @@ module "luci.http"
---[[
Close the HTTP-Connection.
@class function
@name close
@class function
@name close
]]
---[[
Return the request content if the request was of unknown type.
@class function
@name content
@return HTTP request body
@return HTTP request body length
@class function
@name content
@return HTTP request body
@return HTTP request body length
]]
---[[
Get a certain HTTP input value or a table of all input values.
@class function
@name formvalue
@class function
@name formvalue
@param name Name of the GET or POST variable to fetch
@param noparse Don't parse POST data before getting the value
@return HTTP input value or table of all input value
@ -32,8 +33,8 @@ Get a certain HTTP input value or a table of all input values.
---[[
Get a table of all HTTP input values with a certain prefix.
@class function
@name formvaluetable
@class function
@name formvaluetable
@param prefix Prefix
@return Table of all HTTP input values with given prefix
]]
@ -41,18 +42,18 @@ Get a table of all HTTP input values with a certain prefix.
---[[
Get the value of a certain HTTP-Cookie.
@class function
@name getcookie
@class function
@name getcookie
@param name Cookie Name
@return String containing cookie data
]]
---[[
Get the value of a certain HTTP environment variable
or the environment table itself.
@class function
@name getenv
or the environment table itself.
@class function
@name getenv
@param name Environment variable
@return HTTP environment value or environment table
]]
@ -60,41 +61,41 @@ or the environment table itself.
---[[
Set a handler function for incoming user file uploads.
@class function
@name setfilehandler
@class function
@name setfilehandler
@param callback Handler function
]]
---[[
Send a HTTP-Header.
@class function
@name header
@param key Header key
@param value Header value
@class function
@name header
@param key Header key
@param value Header value
]]
---[[
Set the mime type of following content data.
@class function
@name prepare_content
@param mime Mimetype of following content
@class function
@name prepare_content
@param mime Mimetype of following content
]]
---[[
Get the RAW HTTP input source
@class function
@name source
@return HTTP LTN12 source
@class function
@name source
@return HTTP LTN12 source
]]
---[[
Set the HTTP status code and status message.
@class function
@name status
@class function
@name status
@param code Status code
@param message Status message
]]
@ -104,9 +105,8 @@ Send a chunk of content data to the client.
This function is as a valid LTN12 sink.
If the content chunk is nil this function will automatically invoke close.
@class function
@name write
@class function
@name write
@param content Content chunk
@param src_err Error object from source (optional)
@see close
@ -115,146 +115,51 @@ If the content chunk is nil this function will automatically invoke close.
---[[
Splice data from a filedescriptor to the client.
@class function
@name splice
@param fp File descriptor
@param size Bytes to splice (optional)
@class function
@name splice
@param fp File descriptor
@param size Bytes to splice (optional)
]]
---[[
Redirects the client to a new URL and closes the connection.
@class function
@name redirect
@param url Target URL
@class function
@name redirect
@param url Target URL
]]
---[[
Create a querystring out of a table of key - value pairs.
@class function
@name build_querystring
@param table Query string source table
@class function
@name build_querystring
@param table Query string source table
@return Encoded HTTP query string
]]
---[[
Return the URL-decoded equivalent of a string.
@class function
@name urldecode
@param str URL-encoded string
@param no_plus Don't decode + to " "
@return URL-decoded string
@see urlencode
@see urlencode
]]
---[[
Return the URL-encoded equivalent of a string.
@class function
@name urlencode
@param str Source string
@return URL-encoded string
@see urldecode
@see urldecode
]]
---[[
Send the given data as JSON encoded string.
@class function
@name write_json
@class function
@name write_json
@param data Data to send
]]
---[[
Extract and split urlencoded data pairs, separated bei either "&" or ";"
from given url or string. Returns a table with urldecoded values.
Simple parameters are stored as string values associated with the parameter
name within the table. Parameters with multiple values are stored as array
containing the corresponding values.
@class function
@name urldecode_params
@param url The url or string which contains x-www-urlencoded form data
@param tbl Use the given table for storing values (optional)
@return Table containing the urldecoded parameters
@see urlencode_params
]]
---[[
Encode each key-value-pair in given table to x-www-urlencoded format,
separated by "&".
Tables are encoded as parameters with multiple values by repeating the
parameter name with each value.
@class function
@name urlencode_params
@param tbl Table with the values
@return String containing encoded values
@see urldecode_params
]]
---[[
Decode a mime encoded http message body with multipart/form-data Content-Type.
Stores all extracted data associated with its parameter name
in the params table within the given message object. Multiple parameter
values are stored as tables, ordinary ones as strings.
If an optional file callback function is given then it is feeded with the
file contents chunk by chunk and only the extracted file name is stored
within the params table. The callback function will be called subsequently
with three arguments:
o Table containing decoded (name, file) and raw (headers) mime header data
o String value containing a chunk of the file data
o Boolean which indicates wheather the current chunk is the last one (eof)
@class function
@name mimedecode_message_body
@param src Ltn12 source function
@param msg HTTP message object
@param filecb File callback function (optional)
@return Value indicating successful operation (not nil means "ok")
@return String containing the error if unsuccessful
@see parse_message_header
]]
---[[
Decode an urlencoded http message body with application/x-www-urlencoded
Content-Type.
Stores all extracted data associated with its parameter name in the params
table within the given message object. Multiple parameter values are stored
as tables, ordinary ones as strings.
@class function
@name urldecode_message_body
@param src Ltn12 source function
@param msg HTTP message object
@return Value indicating successful operation (not nil means "ok")
@return String containing the error if unsuccessful
@see parse_message_header
]]
---[[
Try to extract and decode a http message body from the given ltn12 source.
This function will examine the Content-Type within the given message object
to select the appropriate content decoder.
Currently the application/x-www-urlencoded and application/form-data
mime types are supported. If the encountered content encoding can't be
handled then the whole message body will be stored unaltered as "content"
property within the given message object.
@class function
@name parse_message_body
@param src Ltn12 source function
@param msg HTTP message object
@param filecb File data callback (optional, see mimedecode_message_body())
@return Value indicating successful operation (not nil means "ok")
@return String containing the error if unsuccessful
@see parse_message_header
]]

View File

@ -0,0 +1,649 @@
-- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <jow@openwrt.org>
-- Licensed to the public under the Apache License 2.0.
-- This class contains several functions useful for http message- and content
-- decoding and to retrive form data from raw http messages.
module("luci.http.protocol", package.seeall)
local ltn12 = require("luci.ltn12")
HTTP_MAX_CONTENT = 1024*8 -- 8 kB maximum content size
-- the "+" sign to " " - and return the decoded string.
function urldecode( str, no_plus )
local function __chrdec( hex )
return string.char( tonumber( hex, 16 ) )
end
if type(str) == "string" then
if not no_plus then
str = str:gsub( "+", " " )
end
str = str:gsub( "%%([a-fA-F0-9][a-fA-F0-9])", __chrdec )
end
return str
end
-- from given url or string. Returns a table with urldecoded values.
-- Simple parameters are stored as string values associated with the parameter
-- name within the table. Parameters with multiple values are stored as array
-- containing the corresponding values.
function urldecode_params( url, tbl )
local params = tbl or { }
if url:find("?") then
url = url:gsub( "^.+%?([^?]+)", "%1" )
end
for pair in url:gmatch( "[^&;]+" ) do
-- find key and value
local key = urldecode( pair:match("^([^=]+)") )
local val = urldecode( pair:match("^[^=]+=(.+)$") )
-- store
if type(key) == "string" and key:len() > 0 then
if type(val) ~= "string" then val = "" end
if not params[key] then
params[key] = val
elseif type(params[key]) ~= "table" then
params[key] = { params[key], val }
else
table.insert( params[key], val )
end
end
end
return params
end
function urlencode( str )
local function __chrenc( chr )
return string.format(
"%%%02x", string.byte( chr )
)
end
if type(str) == "string" then
str = str:gsub(
"([^a-zA-Z0-9$_%-%.%~])",
__chrenc
)
end
return str
end
-- separated by "&". Tables are encoded as parameters with multiple values by
-- repeating the parameter name with each value.
function urlencode_params( tbl )
local enc = ""
for k, v in pairs(tbl) do
if type(v) == "table" then
for i, v2 in ipairs(v) do
enc = enc .. ( #enc > 0 and "&" or "" ) ..
urlencode(k) .. "=" .. urlencode(v2)
end
else
enc = enc .. ( #enc > 0 and "&" or "" ) ..
urlencode(k) .. "=" .. urlencode(v)
end
end
return enc
end
-- (Internal function)
-- Initialize given parameter and coerce string into table when the parameter
-- already exists.
local function __initval( tbl, key )
if tbl[key] == nil then
tbl[key] = ""
elseif type(tbl[key]) == "string" then
tbl[key] = { tbl[key], "" }
else
table.insert( tbl[key], "" )
end
end
-- (Internal function)
-- Initialize given file parameter.
local function __initfileval( tbl, key, filename, fd )
if tbl[key] == nil then
tbl[key] = { file=filename, fd=fd, name=key, "" }
else
table.insert( tbl[key], "" )
end
end
-- (Internal function)
-- Append given data to given parameter, either by extending the string value
-- or by appending it to the last string in the parameter's value table.
local function __appendval( tbl, key, chunk )
if type(tbl[key]) == "table" then
tbl[key][#tbl[key]] = tbl[key][#tbl[key]] .. chunk
else
tbl[key] = tbl[key] .. chunk
end
end
-- (Internal function)
-- Finish the value of given parameter, either by transforming the string value
-- or - in the case of multi value parameters - the last element in the
-- associated values table.
local function __finishval( tbl, key, handler )
if handler then
if type(tbl[key]) == "table" then
tbl[key][#tbl[key]] = handler( tbl[key][#tbl[key]] )
else
tbl[key] = handler( tbl[key] )
end
end
end
-- Table of our process states
local process_states = { }
-- Extract "magic", the first line of a http message.
-- Extracts the message type ("get", "post" or "response"), the requested uri
-- or the status code if the line descripes a http response.
process_states['magic'] = function( msg, chunk, err )
if chunk ~= nil then
-- ignore empty lines before request
if #chunk == 0 then
return true, nil
end
-- Is it a request?
local method, uri, http_ver = chunk:match("^([A-Z]+) ([^ ]+) HTTP/([01]%.[019])$")
-- Yup, it is
if method then
msg.type = "request"
msg.request_method = method:lower()
msg.request_uri = uri
msg.http_version = tonumber( http_ver )
msg.headers = { }
-- We're done, next state is header parsing
return true, function( chunk )
return process_states['headers']( msg, chunk )
end
-- Is it a response?
else
local http_ver, code, message = chunk:match("^HTTP/([01]%.[019]) ([0-9]+) ([^\r\n]+)$")
-- Is a response
if code then
msg.type = "response"
msg.status_code = code
msg.status_message = message
msg.http_version = tonumber( http_ver )
msg.headers = { }
-- We're done, next state is header parsing
return true, function( chunk )
return process_states['headers']( msg, chunk )
end
end
end
end
-- Can't handle it
return nil, "Invalid HTTP message magic"
end
-- Extract headers from given string.
process_states['headers'] = function( msg, chunk )
if chunk ~= nil then
-- Look for a valid header format
local hdr, val = chunk:match( "^([A-Za-z][A-Za-z0-9%-_]+): +(.+)$" )
if type(hdr) == "string" and hdr:len() > 0 and
type(val) == "string" and val:len() > 0
then
msg.headers[hdr] = val
-- Valid header line, proceed
return true, nil
elseif #chunk == 0 then
-- Empty line, we won't accept data anymore
return false, nil
else
-- Junk data
return nil, "Invalid HTTP header received"
end
else
return nil, "Unexpected EOF"
end
end
-- data line by line with the trailing \r\n stripped of.
function header_source( sock )
return ltn12.source.simplify( function()
local chunk, err, part = sock:receive("*l")
-- Line too long
if chunk == nil then
if err ~= "timeout" then
return nil, part
and "Line exceeds maximum allowed length"
or "Unexpected EOF"
else
return nil, err
end
-- Line ok
elseif chunk ~= nil then
-- Strip trailing CR
chunk = chunk:gsub("\r$","")
return chunk, nil
end
end )
end
-- Content-Type. Stores all extracted data associated with its parameter name
-- in the params table withing the given message object. Multiple parameter
-- values are stored as tables, ordinary ones as strings.
-- If an optional file callback function is given then it is feeded with the
-- file contents chunk by chunk and only the extracted file name is stored
-- within the params table. The callback function will be called subsequently
-- with three arguments:
-- o Table containing decoded (name, file) and raw (headers) mime header data
-- o String value containing a chunk of the file data
-- o Boolean which indicates wheather the current chunk is the last one (eof)
function mimedecode_message_body( src, msg, filecb )
if msg and msg.env.CONTENT_TYPE then
msg.mime_boundary = msg.env.CONTENT_TYPE:match("^multipart/form%-data; boundary=(.+)$")
end
if not msg.mime_boundary then
return nil, "Invalid Content-Type found"
end
local tlen = 0
local inhdr = false
local field = nil
local store = nil
local lchunk = nil
local function parse_headers( chunk, field )
local stat
repeat
chunk, stat = chunk:gsub(
"^([A-Z][A-Za-z0-9%-_]+): +([^\r\n]+)\r\n",
function(k,v)
field.headers[k] = v
return ""
end
)
until stat == 0
chunk, stat = chunk:gsub("^\r\n","")
-- End of headers
if stat > 0 then
if field.headers["Content-Disposition"] then
if field.headers["Content-Disposition"]:match("^form%-data; ") then
field.name = field.headers["Content-Disposition"]:match('name="(.-)"')
field.file = field.headers["Content-Disposition"]:match('filename="(.+)"$')
end
end
if not field.headers["Content-Type"] then
field.headers["Content-Type"] = "text/plain"
end
if field.name and field.file and filecb then
__initval( msg.params, field.name )
__appendval( msg.params, field.name, field.file )
store = filecb
elseif field.name and field.file then
local nxf = require "nixio"
local fd = nxf.mkstemp(field.name)
__initfileval ( msg.params, field.name, field.file, fd )
if fd then
store = function(hdr, buf, eof)
fd:write(buf)
if (eof) then
fd:seek(0, "set")
end
end
else
store = function( hdr, buf, eof )
__appendval( msg.params, field.name, buf )
end
end
elseif field.name then
__initval( msg.params, field.name )
store = function( hdr, buf, eof )
__appendval( msg.params, field.name, buf )
end
else
store = nil
end
return chunk, true
end
return chunk, false
end
local function snk( chunk )
tlen = tlen + ( chunk and #chunk or 0 )
if msg.env.CONTENT_LENGTH and tlen > tonumber(msg.env.CONTENT_LENGTH) + 2 then
return nil, "Message body size exceeds Content-Length"
end
if chunk and not lchunk then
lchunk = "\r\n" .. chunk
elseif lchunk then
local data = lchunk .. ( chunk or "" )
local spos, epos, found
repeat
spos, epos = data:find( "\r\n--" .. msg.mime_boundary .. "\r\n", 1, true )
if not spos then
spos, epos = data:find( "\r\n--" .. msg.mime_boundary .. "--\r\n", 1, true )
end
if spos then
local predata = data:sub( 1, spos - 1 )
if inhdr then
predata, eof = parse_headers( predata, field )
if not eof then
return nil, "Invalid MIME section header"
elseif not field.name then
return nil, "Invalid Content-Disposition header"
end
end
if store then
store( field, predata, true )
end
field = { headers = { } }
found = found or true
data, eof = parse_headers( data:sub( epos + 1, #data ), field )
inhdr = not eof
end
until not spos
if found then
-- We found at least some boundary. Save
-- the unparsed remaining data for the
-- next chunk.
lchunk, data = data, nil
else
-- There was a complete chunk without a boundary. Parse it as headers or
-- append it as data, depending on our current state.
if inhdr then
lchunk, eof = parse_headers( data, field )
inhdr = not eof
else
-- We're inside data, so append the data. Note that we only append
-- lchunk, not all of data, since there is a chance that chunk
-- contains half a boundary. Assuming that each chunk is at least the
-- boundary in size, this should prevent problems
store( field, lchunk, false )
lchunk, chunk = chunk, nil
end
end
end
return true
end
return ltn12.pump.all( src, snk )
end
-- Content-Type. Stores all extracted data associated with its parameter name
-- in the params table withing the given message object. Multiple parameter
-- values are stored as tables, ordinary ones as strings.
function urldecode_message_body( src, msg )
local tlen = 0
local lchunk = nil
local function snk( chunk )
tlen = tlen + ( chunk and #chunk or 0 )
if msg.env.CONTENT_LENGTH and tlen > tonumber(msg.env.CONTENT_LENGTH) + 2 then
return nil, "Message body size exceeds Content-Length"
elseif tlen > HTTP_MAX_CONTENT then
return nil, "Message body size exceeds maximum allowed length"
end
if not lchunk and chunk then
lchunk = chunk
elseif lchunk then
local data = lchunk .. ( chunk or "&" )
local spos, epos
repeat
spos, epos = data:find("^.-[;&]")
if spos then
local pair = data:sub( spos, epos - 1 )
local key = pair:match("^(.-)=")
local val = pair:match("=([^%s]*)%s*$")
if key and #key > 0 then
__initval( msg.params, key )
__appendval( msg.params, key, val )
__finishval( msg.params, key, urldecode )
end
data = data:sub( epos + 1, #data )
end
until not spos
lchunk = data
end
return true
end
return ltn12.pump.all( src, snk )
end
-- version, message headers and resulting CGI environment variables from the
-- given ltn12 source.
function parse_message_header( src )
local ok = true
local msg = { }
local sink = ltn12.sink.simplify(
function( chunk )
return process_states['magic']( msg, chunk )
end
)
-- Pump input data...
while ok do
-- get data
ok, err = ltn12.pump.step( src, sink )
-- error
if not ok and err then
return nil, err
-- eof
elseif not ok then
-- Process get parameters
if ( msg.request_method == "get" or msg.request_method == "post" ) and
msg.request_uri:match("?")
then
msg.params = urldecode_params( msg.request_uri )
else
msg.params = { }
end
-- Populate common environment variables
msg.env = {
CONTENT_LENGTH = msg.headers['Content-Length'];
CONTENT_TYPE = msg.headers['Content-Type'] or msg.headers['Content-type'];
REQUEST_METHOD = msg.request_method:upper();
REQUEST_URI = msg.request_uri;
SCRIPT_NAME = msg.request_uri:gsub("?.+$","");
SCRIPT_FILENAME = ""; -- XXX implement me
SERVER_PROTOCOL = "HTTP/" .. string.format("%.1f", msg.http_version);
QUERY_STRING = msg.request_uri:match("?")
and msg.request_uri:gsub("^.+?","") or ""
}
-- Populate HTTP_* environment variables
for i, hdr in ipairs( {
'Accept',
'Accept-Charset',
'Accept-Encoding',
'Accept-Language',
'Connection',
'Cookie',
'Host',
'Referer',
'User-Agent',
} ) do
local var = 'HTTP_' .. hdr:upper():gsub("%-","_")
local val = msg.headers[hdr]
msg.env[var] = val
end
end
end
return msg
end
-- This function will examine the Content-Type within the given message object
-- to select the appropriate content decoder.
-- Currently the application/x-www-urlencoded and application/form-data
-- mime types are supported. If the encountered content encoding can't be
-- handled then the whole message body will be stored unaltered as "content"
-- property within the given message object.
function parse_message_body( src, msg, filecb )
-- Is it multipart/mime ?
if msg.env.REQUEST_METHOD == "POST" and msg.env.CONTENT_TYPE and
msg.env.CONTENT_TYPE:match("^multipart/form%-data")
then
return mimedecode_message_body( src, msg, filecb )
-- Is it application/x-www-form-urlencoded ?
elseif msg.env.REQUEST_METHOD == "POST" and msg.env.CONTENT_TYPE and
msg.env.CONTENT_TYPE:match("^application/x%-www%-form%-urlencoded")
then
return urldecode_message_body( src, msg, filecb )
-- Unhandled encoding
-- If a file callback is given then feed it chunk by chunk, else
-- store whole buffer in message.content
else
local sink
-- If we have a file callback then feed it
if type(filecb) == "function" then
local meta = {
name = "raw",
encoding = msg.env.CONTENT_TYPE
}
sink = function( chunk )
if chunk then
return filecb(meta, chunk, false)
else
return filecb(meta, nil, true)
end
end
-- ... else append to .content
else
msg.content = ""
msg.content_length = 0
sink = function( chunk )
if chunk then
if ( msg.content_length + #chunk ) <= HTTP_MAX_CONTENT then
msg.content = msg.content .. chunk
msg.content_length = msg.content_length + #chunk
return true
else
return nil, "POST data exceeds maximum allowed length"
end
end
return true
end
end
-- Pump data...
while true do
local ok, err = ltn12.pump.step( src, sink )
if not ok and err then
return nil, err
elseif not ok then -- eof
return true
end
end
return true
end
end
statusmsg = {
[200] = "OK",
[206] = "Partial Content",
[301] = "Moved Permanently",
[302] = "Found",
[304] = "Not Modified",
[400] = "Bad Request",
[403] = "Forbidden",
[404] = "Not Found",
[405] = "Method Not Allowed",
[408] = "Request Time-out",
[411] = "Length Required",
[412] = "Precondition Failed",
[416] = "Requested range not satisfiable",
[500] = "Internal Server Error",
[503] = "Server Unavailable",
}

View File

@ -0,0 +1,142 @@
---[[
LuCI http protocol class.
This class contains several functions useful for http message- and content
decoding and to retrive form data from raw http messages.
]]
module "luci.http.protocol"
---[[
Decode an urlencoded string - optionally without decoding
the "+" sign to " " - and return the decoded string.
@class function
@name urldecode
@param str Input string in x-www-urlencoded format
@param no_plus Don't decode "+" signs to spaces
@return The decoded string
@see urlencode
]]
---[[
Extract and split urlencoded data pairs, separated bei either "&" or ";"
from given url or string. Returns a table with urldecoded values.
Simple parameters are stored as string values associated with the parameter
name within the table. Parameters with multiple values are stored as array
containing the corresponding values.
@class function
@name urldecode_params
@param url The url or string which contains x-www-urlencoded form data
@param tbl Use the given table for storing values (optional)
@return Table containing the urldecoded parameters
@see urlencode_params
]]
---[[
Encode given string to x-www-urlencoded format.
@class function
@name urlencode
@param str String to encode
@return String containing the encoded data
@see urldecode
]]
---[[
Encode each key-value-pair in given table to x-www-urlencoded format,
separated by "&". Tables are encoded as parameters with multiple values by
repeating the parameter name with each value.
@class function
@name urlencode_params
@param tbl Table with the values
@return String containing encoded values
@see urldecode_params
]]
---[[
Creates a ltn12 source from the given socket. The source will return it's
data line by line with the trailing \r\n stripped of.
@class function
@name header_source
@param sock Readable network socket
@return Ltn12 source function
]]
---[[
Decode a mime encoded http message body with multipart/form-data
Content-Type. Stores all extracted data associated with its parameter name
in the params table withing the given message object. Multiple parameter
values are stored as tables, ordinary ones as strings.
If an optional file callback function is given then it is feeded with the
file contents chunk by chunk and only the extracted file name is stored
within the params table. The callback function will be called subsequently
with three arguments:
o Table containing decoded (name, file) and raw (headers) mime header data
o String value containing a chunk of the file data
o Boolean which indicates wheather the current chunk is the last one (eof)
@class function
@name mimedecode_message_body
@param src Ltn12 source function
@param msg HTTP message object
@param filecb File callback function (optional)
@return Value indicating successful operation (not nil means "ok")
@return String containing the error if unsuccessful
@see parse_message_header
]]
---[[
Decode an urlencoded http message body with application/x-www-urlencoded
Content-Type. Stores all extracted data associated with its parameter name
in the params table withing the given message object. Multiple parameter
values are stored as tables, ordinary ones as strings.
@class function
@name urldecode_message_body
@param src Ltn12 source function
@param msg HTTP message object
@return Value indicating successful operation (not nil means "ok")
@return String containing the error if unsuccessful
@see parse_message_header
]]
---[[
Try to extract an http message header including information like protocol
version, message headers and resulting CGI environment variables from the
given ltn12 source.
@class function
@name parse_message_header
@param src Ltn12 source function
@return HTTP message object
@see parse_message_body
]]
---[[
Try to extract and decode a http message body from the given ltn12 source.
This function will examine the Content-Type within the given message object
to select the appropriate content decoder.
Currently the application/x-www-urlencoded and application/form-data
mime types are supported. If the encountered content encoding can't be
handled then the whole message body will be stored unaltered as "content"
property within the given message object.
@class function
@name parse_message_body
@param src Ltn12 source function
@param msg HTTP message object
@param filecb File data callback (optional, see mimedecode_message_body())
@return Value indicating successful operation (not nil means "ok")
@return String containing the error if unsuccessful
@see parse_message_header
]]
---[[
Table containing human readable messages for several http status codes.
@class table
]]

View File

@ -3,9 +3,9 @@
-- This class provides basic ETag handling and implements most of the
-- conditional HTTP/1.1 headers specified in RFC2616 Sct. 14.24 - 14.28 .
module("luci.http.conditionals", package.seeall)
module("luci.http.protocol.conditionals", package.seeall)
local date = require("luci.http.date")
local date = require("luci.http.protocol.date")
function mk_etag( stat )

View File

@ -4,7 +4,7 @@ LuCI http protocol implementation - HTTP/1.1 bits.
This class provides basic ETag handling and implements most of the
conditional HTTP/1.1 headers specified in RFC2616 Sct. 14.24 - 14.28 .
]]
module "luci.http.conditionals"
module "luci.http.protocol.conditionals"
---[[
Implement 14.19 / ETag.

View File

@ -2,7 +2,7 @@
-- Licensed to the public under the Apache License 2.0.
-- This class contains functions to parse, compare and format http dates.
module("luci.http.date", package.seeall)
module("luci.http.protocol.date", package.seeall)
require("luci.sys.zoneinfo")

View File

@ -3,7 +3,7 @@ LuCI http protocol implementation - date helper class.
This class contains functions to parse, compare and format http dates.
]]
module "luci.http.date"
module "luci.http.protocol.date"
---[[
Return the time offset in seconds between the UTC and given time zone.

View File

@ -3,7 +3,7 @@
-- This class provides functions to guess mime types from file extensions and
-- vice versa.
module("luci.http.mime", package.seeall)
module("luci.http.protocol.mime", package.seeall)
require("luci.util")

View File

@ -4,7 +4,7 @@ LuCI http protocol implementation - mime helper class.
This class provides functions to guess mime types from file extensions and
vice versa.
]]
module "luci.http.mime"
module "luci.http.protocol.mime"
---[[
MIME mapping table containg extension - mimetype relations.

View File

@ -498,13 +498,11 @@ function forwarding.dest(self)
end
function forwarding.src_zone(self)
local z = zone(self:src())
return z.sid and z
return zone(self:src())
end
function forwarding.dest_zone(self)
local z = zone(self:dest())
return z.sid and z
return zone(self:dest())
end

View File

@ -20,14 +20,12 @@ module "luci.model.ipkg"
-- Internal action function
local function _action(cmd, ...)
local cmdline = { ipkg, cmd }
local k, v
local pkg = ""
for k, v in pairs({...}) do
cmdline[#cmdline+1] = util.shellquote(v)
pkg = pkg .. " '" .. v:gsub("'", "") .. "'"
end
local c = "%s >/tmp/opkg.stdout 2>/tmp/opkg.stderr" % table.concat(cmdline, " ")
local c = "%s %s %s >/tmp/opkg.stdout 2>/tmp/opkg.stderr" %{ ipkg, cmd, pkg }
local r = os.execute(c)
local e = fs.readfile("/tmp/opkg.stderr")
local o = fs.readfile("/tmp/opkg.stdout")
@ -76,17 +74,17 @@ local function _parselist(rawdata)
end
-- Internal lookup function
local function _lookup(cmd, pkg)
local cmdline = { ipkg, cmd }
local function _lookup(act, pkg)
local cmd = ipkg .. " " .. act
if pkg then
cmdline[#cmdline+1] = util.shellquote(pkg)
cmd = cmd .. " '" .. pkg:gsub("'", "") .. "'"
end
-- OPKG sometimes kills the whole machine because it sucks
-- Therefore we have to use a sucky approach too and use
-- tmpfiles instead of directly reading the output
local tmpfile = os.tmpname()
os.execute("%s >%s 2>/dev/null" %{ table.concat(cmdline, " "), tmpfile })
os.execute(cmd .. (" >%s 2>/dev/null" % tmpfile))
local data = _parselist(io.lines(tmpfile))
os.remove(tmpfile)
@ -125,12 +123,9 @@ end
-- List helper
local function _list(action, pat, cb)
local cmdline = { ipkg, action }
if pat then
cmdline[#cmdline+1] = util.shellquote(pat)
end
local fd = io.popen(ipkg .. " " .. action ..
(pat and (" '%s'" % pat:gsub("'", "")) or ""))
local fd = io.popen(table.concat(cmdline, " "))
if fd then
local name, version, sz, desc
while true do

View File

@ -6,12 +6,14 @@ local type, next, pairs, ipairs, loadfile, table, select
local tonumber, tostring, math = tonumber, tostring, math
local pcall, require, setmetatable = pcall, require, setmetatable
local require = require
local nxo = require "nixio"
local nfs = require "nixio.fs"
local ipc = require "luci.ip"
local sys = require "luci.sys"
local utl = require "luci.util"
local dsp = require "luci.dispatcher"
local uci = require "luci.model.uci"
local lng = require "luci.i18n"
local jsc = require "luci.jsonc"
@ -21,7 +23,7 @@ module "luci.model.network"
IFACE_PATTERNS_VIRTUAL = { }
IFACE_PATTERNS_IGNORE = { "^wmaster%d", "^wifi%d", "^hwsim%d", "^imq%d", "^ifb%d", "^mon%.wlan%d", "^sit%d", "^gre%d", "^gretap%d", "^ip6gre%d", "^ip6tnl%d", "^tunl%d", "^lo$" }
IFACE_PATTERNS_WIRELESS = { "^wlan%d", "^wl%d", "^ath%d", "^%w+%.network%d" }
IFACE_PATTERNS_WIRELESS = { "^wlan%d", "^wl%d", "^ath%d", "^rausb%d", "^rai%d", "^ra%d", "^wdsi%d", "^wds%d", "^apclii%d", "^apcli%d", "^apcliusb%d", "^%w+%.network%d" }
protocol = utl.class()
@ -106,58 +108,6 @@ function _set(c, s, o, v)
end
end
local function _wifi_state()
if not next(_ubuswificache) then
_ubuswificache = utl.ubus("network.wireless", "status", {}) or {}
end
return _ubuswificache
end
local function _wifi_state_by_sid(sid)
local t1, n1 = _uci:get("wireless", sid)
if t1 == "wifi-iface" and n1 ~= nil then
local radioname, radiostate
for radioname, radiostate in pairs(_wifi_state()) do
if type(radiostate) == "table" and
type(radiostate.interfaces) == "table"
then
local netidx, netstate
for netidx, netstate in ipairs(radiostate.interfaces) do
if type(netstate) == "table" and
type(netstate.section) == "string"
then
local t2, n2 = _uci:get("wireless", netstate.section)
if t1 == t2 and n1 == n2 then
return radioname, radiostate, netstate
end
end
end
end
end
end
end
local function _wifi_state_by_ifname(ifname)
if type(ifname) == "string" then
local radioname, radiostate
for radioname, radiostate in pairs(_wifi_state()) do
if type(radiostate) == "table" and
type(radiostate.interfaces) == "table"
then
local netidx, netstate
for netidx, netstate in ipairs(radiostate.interfaces) do
if type(netstate) == "table" and
type(netstate.ifname) == "string" and
netstate.ifname == ifname
then
return radioname, radiostate, netstate
end
end
end
end
end
end
function _wifi_iface(x)
local _, p
for _, p in ipairs(IFACE_PATTERNS_WIRELESS) do
@ -168,111 +118,59 @@ function _wifi_iface(x)
return false
end
local function _wifi_iwinfo_by_ifname(ifname, force_phy_only)
local stat, iwinfo = pcall(require, "iwinfo")
local iwtype = stat and type(ifname) == "string" and iwinfo.type(ifname)
local is_nonphy_op = {
bitrate = true,
quality = true,
quality_max = true,
mode = true,
ssid = true,
bssid = true,
assoclist = true,
encryption = true
}
function _wifi_state(key, val, field)
local radio, radiostate, ifc, ifcstate
if iwtype then
-- if we got a type but no real netdev, we're referring to a phy
local phy_only = force_phy_only or (ipc.link(ifname).type ~= 1)
if not next(_ubuswificache) then
_ubuswificache = utl.ubus("network.wireless", "status", {}) or {}
return setmetatable({}, {
__index = function(t, k)
if k == "ifname" then
return ifname
elseif phy_only and is_nonphy_op[k] then
return nil
elseif iwinfo[iwtype][k] then
return iwinfo[iwtype][k](ifname)
-- workaround extended section format
for radio, radiostate in pairs(_ubuswificache) do
for ifc, ifcstate in pairs(radiostate.interfaces) do
if ifcstate.section and ifcstate.section:sub(1, 1) == '@' then
local s = _uci:get_all('wireless.%s' % ifcstate.section)
if s then
ifcstate.section = s['.name']
end
end
end
})
end
end
end
local function _wifi_sid_by_netid(netid)
if type(netid) == "string" then
local radioname, netidx = netid:match("^(%w+)%.network(%d+)$")
if radioname and netidx then
local i, n = 0, nil
netidx = tonumber(netidx)
_uci:foreach("wireless", "wifi-iface",
function(s)
if s.device == radioname then
i = i + 1
if i == netidx then
n = s[".name"]
return false
end
end
end)
return n
for radio, radiostate in pairs(_ubuswificache) do
for ifc, ifcstate in pairs(radiostate.interfaces) do
if ifcstate[key] == val then
return ifcstate[field]
end
end
end
end
function _wifi_sid_by_ifname(ifn)
local sid = _wifi_sid_by_netid(ifn)
if sid then
function _wifi_lookup(ifn)
-- got a radio#.network# pseudo iface, locate the corresponding section
local radio, ifnidx = ifn:match("^(%w+)%.network(%d+)$")
if radio and ifnidx then
local sid = nil
local num = 0
ifnidx = tonumber(ifnidx)
_uci:foreach("wireless", "wifi-iface",
function(s)
if s.device == radio then
num = num + 1
if num == ifnidx then
sid = s['.name']
return false
end
end
end)
return sid
-- looks like wifi, try to locate the section via ubus state
elseif _wifi_iface(ifn) then
return _wifi_state("ifname", ifn, "section")
end
local _, _, netstate = _wifi_state_by_ifname(ifn)
if netstate and type(netstate.section) == "string" then
return netstate.section
end
end
local function _wifi_netid_by_sid(sid)
local t, n = _uci:get("wireless", sid)
if t == "wifi-iface" and n ~= nil then
local radioname = _uci:get("wireless", n, "device")
if type(radioname) == "string" then
local i, netid = 0, nil
_uci:foreach("wireless", "wifi-iface",
function(s)
if s.device == radioname then
i = i + 1
if s[".name"] == n then
netid = "%s.network%d" %{ radioname, i }
return false
end
end
end)
return netid, radioname
end
end
end
local function _wifi_netid_by_netname(name)
local netid = nil
_uci:foreach("wireless", "wifi-iface",
function(s)
local net
for net in utl.imatch(s.network) do
if net == name then
netid = _wifi_netid_by_sid(s[".name"])
return false
end
end
end)
return netid
end
function _iface_virtual(x)
@ -330,7 +228,7 @@ function init(cursor)
if i.family == "packet" then
_interfaces[name].flags = i.flags
_interfaces[name].stats = i.data
_interfaces[name].macaddr = ipc.checkmac(i.addr)
_interfaces[name].macaddr = i.addr
elseif i.family == "inet" then
_interfaces[name].ipaddrs[#_interfaces[name].ipaddrs+1] = ipc.IPv4(i.addr, i.netmask)
elseif i.family == "inet6" then
@ -543,9 +441,6 @@ end
function del_network(self, n)
local r = _uci:delete("network", n)
if r then
_uci:delete_all("luci", "ifstate",
function(s) return (s.interface == n) end)
_uci:delete_all("network", "alias",
function(s) return (s.interface == n) end)
@ -629,8 +524,20 @@ function get_interface(self, i)
if _interfaces[i] or _wifi_iface(i) then
return interface(i)
else
local netid = _wifi_netid_by_sid(i)
return netid and interface(netid)
local ifc
local num = { }
_uci:foreach("wireless", "wifi-iface",
function(s)
if s.device then
num[s.device] = num[s.device] and num[s.device] + 1 or 1
if s['.name'] == i then
ifc = interface(
"%s.network%d" %{s.device, num[s.device] })
return false
end
end
end)
return ifc
end
end
@ -737,7 +644,7 @@ function get_wifidevs(self)
end
function get_wifinet(self, net)
local wnet = _wifi_sid_by_ifname(net)
local wnet = _wifi_lookup(net)
if wnet then
return wifinet(wnet)
end
@ -753,7 +660,7 @@ function add_wifinet(self, net, options)
end
function del_wifinet(self, net)
local wnet = _wifi_sid_by_ifname(net)
local wnet = _wifi_lookup(net)
if wnet then
_uci:delete("wireless", wnet)
return true
@ -877,7 +784,22 @@ function protocol.ifname(self)
ifname = self:_ubus("device")
end
if not ifname then
ifname = _wifi_netid_by_netname(self.sid)
local num = { }
_uci:foreach("wireless", "wifi-iface",
function(s)
if s.device then
num[s.device] = num[s.device]
and num[s.device] + 1 or 1
local net
for net in utl.imatch(s.network) do
if net == self.sid then
ifname = "%s.network%d" %{ s.device, num[s.device] }
return false
end
end
end
end)
end
return ifname
end
@ -1001,15 +923,7 @@ function protocol.ip6addrs(self)
if type(addrs) == "table" then
for n, addr in ipairs(addrs) do
if type(addr["local-address"]) == "table" and
type(addr["local-address"].mask) == "number" and
type(addr["local-address"].address) == "string"
then
rv[#rv+1] = "%s/%d" %{
addr["local-address"].address,
addr["local-address"].mask
}
end
rv[#rv+1] = "%s1/%d" %{ addr.address, addr.mask }
end
end
@ -1067,17 +981,24 @@ function protocol.is_empty(self)
if self:is_floating() then
return false
else
local empty = true
local rv = true
if (self:_get("ifname") or ""):match("%S+") then
empty = false
rv = false
end
if empty and _wifi_netid_by_netname(self.sid) then
empty = false
end
_uci:foreach("wireless", "wifi-iface",
function(s)
local n
for n in utl.imatch(s.network) do
if n == self.sid then
rv = false
return false
end
end
end)
return empty
return rv
end
end
@ -1085,7 +1006,7 @@ function protocol.add_interface(self, ifname)
ifname = _M:ifnameof(ifname)
if ifname and not self:is_floating() then
-- if its a wifi interface, change its network option
local wif = _wifi_sid_by_ifname(ifname)
local wif = _wifi_lookup(ifname)
if wif then
_append("wireless", wif, "network", self.sid)
@ -1100,7 +1021,7 @@ function protocol.del_interface(self, ifname)
ifname = _M:ifnameof(ifname)
if ifname and not self:is_floating() then
-- if its a wireless interface, clear its network option
local wif = _wifi_sid_by_ifname(ifname)
local wif = _wifi_lookup(ifname)
if wif then _filter("wireless", wif, "network", self.sid) end
-- remove the interface
@ -1122,7 +1043,21 @@ function protocol.get_interface(self)
ifn = ifn:match("^[^:/]+")
return ifn and interface(ifn, self)
end
ifn = _wifi_netid_by_netname(self.sid)
ifn = nil
_uci:foreach("wireless", "wifi-iface",
function(s)
if s.device then
num[s.device] = num[s.device] and num[s.device] + 1 or 1
local net
for net in utl.imatch(s.network) do
if net == self.sid then
ifn = "%s.network%d" %{ s.device, num[s.device] }
return false
end
end
end
end)
return ifn and interface(ifn, self)
end
end
@ -1142,17 +1077,18 @@ function protocol.get_interfaces(self)
ifaces[#ifaces+1] = nfs[ifn]
end
local num = { }
local wfs = { }
_uci:foreach("wireless", "wifi-iface",
function(s)
if s.device then
num[s.device] = num[s.device] and num[s.device] + 1 or 1
local net
for net in utl.imatch(s.network) do
if net == self.sid then
ifn = _wifi_netid_by_sid(s[".name"])
if ifn then
wfs[ifn] = interface(ifn, self)
end
ifn = "%s.network%d" %{ s.device, num[s.device] }
wfs[ifn] = interface(ifn, self)
end
end
end
@ -1183,7 +1119,7 @@ function protocol.contains_interface(self, ifname)
end
end
local wif = _wifi_sid_by_ifname(ifname)
local wif = _wifi_lookup(ifname)
if wif then
local n
for n in utl.imatch(_uci:get("wireless", wif, "network")) do
@ -1198,18 +1134,17 @@ function protocol.contains_interface(self, ifname)
end
function protocol.adminlink(self)
local stat, dsp = pcall(require, "luci.dispatcher")
return stat and dsp.build_url("admin", "network", "network", self.sid)
return dsp.build_url("admin", "network", "network", self.sid)
end
interface = utl.class()
function interface.__init__(self, ifname, network)
local wif = _wifi_sid_by_ifname(ifname)
local wif = _wifi_lookup(ifname)
if wif then
self.wif = wifinet(wif)
self.ifname = self.wif:ifname()
self.ifname = _wifi_state("section", wif, "ifname")
end
self.ifname = self.ifname or ifname
@ -1233,7 +1168,8 @@ function interface.name(self)
end
function interface.mac(self)
return ipc.checkmac(self:_ubus("macaddr"))
local mac = self:_ubus("macaddr")
return mac and mac:upper()
end
function interface.ipaddrs(self)
@ -1396,14 +1332,9 @@ end
wifidev = utl.class()
function wifidev.__init__(self, name)
local t, n = _uci:get("wireless", name)
if t == "wifi-device" and n ~= nil then
self.sid = n
self.iwinfo = _wifi_iwinfo_by_ifname(self.sid, true)
end
self.sid = self.sid or name
self.iwinfo = self.iwinfo or { ifname = self.sid }
function wifidev.__init__(self, dev)
self.sid = dev
self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
end
function wifidev.get(self, opt)
@ -1428,9 +1359,11 @@ function wifidev.hwmodes(self)
end
function wifidev.get_i18n(self)
local t = self.iwinfo.hardware_name or "Generic"
local t = "Generic"
if self.iwinfo.type == "wl" then
t = "Broadcom"
elseif self.iwinfo.type == "ra" then
t = "Ralink/MediaTek"
end
local m = ""
@ -1456,7 +1389,7 @@ function wifidev.get_wifinet(self, net)
if _uci:get("wireless", net) == "wifi-iface" then
return wifinet(net)
else
local wnet = _wifi_sid_by_ifname(net)
local wnet = _wifi_lookup(net)
if wnet then
return wifinet(wnet)
end
@ -1490,7 +1423,7 @@ function wifidev.del_wifinet(self, net)
if utl.instanceof(net, wifinet) then
net = net.sid
elseif _uci:get("wireless", net) ~= "wifi-iface" then
net = _wifi_sid_by_ifname(net)
net = _wifi_lookup(net)
end
if net and _uci:get("wireless", net, "device") == self.sid then
@ -1504,50 +1437,49 @@ end
wifinet = utl.class()
function wifinet.__init__(self, name, data)
local sid, netid, radioname, radiostate, netstate
function wifinet.__init__(self, net, data)
self.sid = net
local n = 0
local num = { }
local netid, sid
_uci:foreach("wireless", "wifi-iface",
function(s)
n = n + 1
if s.device then
num[s.device] = num[s.device] and num[s.device] + 1 or 1
if s['.name'] == self.sid then
sid = "@wifi-iface[%d]" % n
netid = "%s.network%d" %{ s.device, num[s.device] }
return false
end
end
end)
-- lookup state by radio#.network# notation
sid = _wifi_sid_by_netid(name)
if sid then
netid = name
radioname, radiostate, netstate = _wifi_state_by_sid(sid)
else
-- lookup state by ifname (e.g. wlan0)
radioname, radiostate, netstate = _wifi_state_by_ifname(name)
if radioname and radiostate and netstate then
sid = netstate.section
netid = _wifi_netid_by_sid(sid)
else
-- lookup state by uci section id (e.g. cfg053579)
radioname, radiostate, netstate = _wifi_state_by_sid(name)
if radioname and radiostate and netstate then
sid = name
netid = _wifi_netid_by_sid(sid)
else
-- no state available, try to resolve from uci
netid, radioname = _wifi_netid_by_sid(name)
if netid and radioname then
sid = name
local _, k, r, i
for k, r in pairs(_ubuswificache) do
if type(r) == "table" and
type(r.interfaces) == "table"
then
for _, i in ipairs(r.interfaces) do
if type(i) == "table" and i.section == sid then
self._ubusdata = {
radio = k,
dev = r,
net = i
}
end
end
end
end
end
local iwinfo =
(netstate and _wifi_iwinfo_by_ifname(netstate.ifname)) or
(radioname and _wifi_iwinfo_by_ifname(radioname)) or
{ ifname = (netid or sid or name) }
local dev = _wifi_state("section", self.sid, "ifname") or netid
self.sid = sid or name
self.wdev = iwinfo.ifname
self.iwinfo = iwinfo
self.netid = netid
self._ubusdata = {
radio = radioname,
dev = radiostate,
net = netstate
}
self.netid = netid
self.wdev = dev
self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
end
function wifinet.ubus(self, ...)
@ -1600,7 +1532,7 @@ end
function wifinet.ifname(self)
local ifname = self:ubus("net", "ifname") or self.iwinfo.ifname
if not ifname or ifname:match("^wifi%d") or ifname:match("^radio%d") then
if not ifname or ifname:match("^wifi%d") or ifname:match("^radio%d") or ifname:match("^ra") or ifname:match("^rai") then
ifname = self.wdev
end
return ifname
@ -1734,8 +1666,7 @@ function wifinet.get_i18n(self)
end
function wifinet.adminlink(self)
local stat, dsp = pcall(require, "luci.dispatcher")
return dsp and dsp.build_url("admin", "network", "wireless", self.netid)
return dsp.build_url("admin", "network", "wireless", self.netid)
end
function wifinet.get_network(self)

View File

@ -2,12 +2,13 @@
-- Licensed to the public under the Apache License 2.0.
local os = require "os"
local uci = require "uci"
local util = require "luci.util"
local table = require "table"
local setmetatable, rawget, rawset = setmetatable, rawget, rawset
local require, getmetatable, assert = require, getmetatable, assert
local require, getmetatable = require, getmetatable
local error, pairs, ipairs = error, pairs, ipairs
local type, tostring, tonumber, unpack = type, tostring, tonumber, unpack
@ -19,436 +20,151 @@ local type, tostring, tonumber, unpack = type, tostring, tonumber, unpack
-- reloaded.
module "luci.model.uci"
local ERRSTR = {
"Invalid command",
"Invalid argument",
"Method not found",
"Entry not found",
"No data",
"Permission denied",
"Timeout",
"Not supported",
"Unknown error",
"Connection failed"
}
cursor = uci.cursor
local session_id = nil
local function call(cmd, args)
if type(args) == "table" and session_id then
args.ubus_rpc_session = session_id
end
return util.ubus("uci", cmd, args)
end
function cursor()
return _M
end
APIVERSION = uci.APIVERSION
function cursor_state()
return _M
end
function substate(self)
return self
return cursor(nil, "/var/state")
end
function get_confdir(self)
return "/etc/config"
end
inst = cursor()
inst_state = cursor_state()
function get_savedir(self)
return "/tmp/.uci"
end
local Cursor = getmetatable(inst)
function get_session_id(self)
return session_id
end
function set_confdir(self, directory)
return false
end
function set_savedir(self, directory)
return false
end
function set_session_id(self, id)
session_id = id
return true
end
function load(self, config)
return true
end
function save(self, config)
return true
end
function unload(self, config)
return true
end
function changes(self, config)
local rv = call("changes", { config = config })
local res = {}
if type(rv) == "table" and type(rv.changes) == "table" then
local package, changes
for package, changes in pairs(rv.changes) do
res[package] = {}
local _, change
for _, change in ipairs(changes) do
local operation, section, option, value = unpack(change)
if option and value and operation ~= "add" then
res[package][section] = res[package][section] or { }
if operation == "list-add" then
local v = res[package][section][option]
if type(v) == "table" then
v[#v+1] = value or ""
elseif v ~= nil then
res[package][section][option] = { v, value }
else
res[package][section][option] = { value }
end
else
res[package][section][option] = value or ""
end
else
res[package][section] = res[package][section] or {}
res[package][section][".type"] = option or ""
end
end
end
end
return res
end
function revert(self, config)
local _, err = call("revert", { config = config })
return (err == nil), ERRSTR[err]
end
function commit(self, config)
local _, err = call("commit", { config = config })
return (err == nil), ERRSTR[err]
end
--[[
function apply(self, configs, command)
local _, config
assert(not command, "Apply command not supported anymore")
if type(configs) == "table" then
for _, config in ipairs(configs) do
call("service", "event", {
type = "config.change",
data = { package = config }
})
end
end
end
]]
function foreach(self, config, stype, callback)
if type(callback) == "function" then
local rv, err = call("get", {
config = config,
type = stype
})
if type(rv) == "table" and type(rv.values) == "table" then
local sections = { }
local res = false
local index = 1
local _, section
for _, section in pairs(rv.values) do
section[".index"] = section[".index"] or index
sections[index] = section
index = index + 1
end
table.sort(sections, function(a, b)
return a[".index"] < b[".index"]
end)
for _, section in ipairs(sections) do
local continue = callback(section)
res = true
if continue == false then
break
end
end
return res
else
return false, ERRSTR[err] or "No data"
end
else
return false, "Invalid argument"
end
end
local function _get(self, operation, config, section, option)
if section == nil then
return nil
elseif type(option) == "string" and option:byte(1) ~= 46 then
local rv, err = call(operation, {
config = config,
section = section,
option = option
})
if type(rv) == "table" then
return rv.value or nil
elseif err then
return false, ERRSTR[err]
else
return nil
end
elseif option == nil then
local values = self:get_all(config, section)
if values then
return values[".type"], values[".name"]
else
return nil
end
else
return false, "Invalid argument"
end
end
function get(self, ...)
return _get(self, "get", ...)
end
function get_state(self, ...)
return _get(self, "state", ...)
end
function get_all(self, config, section)
local rv, err = call("get", {
config = config,
section = section
})
if type(rv) == "table" and type(rv.values) == "table" then
return rv.values
elseif err then
return false, ERRSTR[err]
else
return nil
end
end
function get_bool(self, ...)
local val = self:get(...)
return (val == "1" or val == "true" or val == "yes" or val == "on")
end
function get_first(self, config, stype, option, default)
local rv = default
self:foreach(config, stype, function(s)
local val = not option and s[".name"] or s[option]
if type(default) == "number" then
val = tonumber(val)
elseif type(default) == "boolean" then
val = (val == "1" or val == "true" or
val == "yes" or val == "on")
end
if val ~= nil then
rv = val
return false
end
end)
return rv
end
function get_list(self, config, section, option)
if config and section and option then
local val = self:get(config, section, option)
return (type(val) == "table" and val or { val })
end
return { }
end
function section(self, config, stype, name, values)
local rv, err = call("add", {
config = config,
type = stype,
name = name,
values = values
})
if type(rv) == "table" then
return rv.section
elseif err then
return false, ERRSTR[err]
else
return nil
end
end
function add(self, config, stype)
return self:section(config, stype)
end
function set(self, config, section, option, value)
if value == nil then
local sname, err = self:section(config, option, section)
return (not not sname), err
else
local _, err = call("set", {
config = config,
section = section,
values = { [option] = value }
})
return (err == nil), ERRSTR[err]
end
end
function set_list(self, config, section, option, value)
if section == nil or option == nil then
return false
elseif value == nil or (type(value) == "table" and #value == 0) then
return self:delete(config, section, option)
elseif type(value) == "table" then
return self:set(config, section, option, value)
else
return self:set(config, section, option, { value })
end
end
function tset(self, config, section, values)
local _, err = call("set", {
config = config,
section = section,
values = values
})
return (err == nil), ERRSTR[err]
end
function reorder(self, config, section, index)
local sections
if type(section) == "string" and type(index) == "number" then
local pos = 0
sections = { }
self:foreach(config, nil, function(s)
if pos == index then
pos = pos + 1
end
if s[".name"] ~= section then
pos = pos + 1
sections[pos] = s[".name"]
else
sections[index + 1] = section
end
end)
elseif type(section) == "table" then
sections = section
else
return false, "Invalid argument"
end
local _, err = call("order", {
config = config,
sections = sections
})
return (err == nil), ERRSTR[err]
end
function delete(self, config, section, option)
local _, err = call("delete", {
config = config,
section = section,
option = option
})
return (err == nil), ERRSTR[err]
end
function delete_all(self, config, stype, comparator)
local _, err
if type(comparator) == "table" then
_, err = call("delete", {
config = config,
type = stype,
match = comparator
})
elseif type(comparator) == "function" then
local rv = call("get", {
config = config,
type = stype
})
if type(rv) == "table" and type(rv.values) == "table" then
local sname, section
for sname, section in pairs(rv.values) do
if comparator(section) then
_, err = call("delete", {
config = config,
section = sname
})
end
end
end
elseif comparator == nil then
_, err = call("delete", {
config = config,
type = stype
})
else
return false, "Invalid argument"
end
return (err == nil), ERRSTR[err]
end
function apply(self, configlist, command)
function Cursor.apply(self, configlist, command)
configlist = self:_affected(configlist)
if command then
return { "/sbin/luci-reload", unpack(configlist) }
else
return os.execute("/sbin/luci-reload %s >/dev/null 2>&1"
% util.shellquote(table.concat(configlist, " ")))
% table.concat(configlist, " "))
end
end
-- returns a boolean whether to delete the current section (optional)
function Cursor.delete_all(self, config, stype, comparator)
local del = {}
if type(comparator) == "table" then
local tbl = comparator
comparator = function(section)
for k, v in pairs(tbl) do
if section[k] ~= v then
return false
end
end
return true
end
end
local function helper (section)
if not comparator or comparator(section) then
del[#del+1] = section[".name"]
end
end
self:foreach(config, stype, helper)
for i, j in ipairs(del) do
self:delete(config, j)
end
end
function Cursor.section(self, config, type, name, values)
local stat = true
if name then
stat = self:set(config, name, type)
else
name = self:add(config, type)
stat = name and true
end
if stat and values then
stat = self:tset(config, name, values)
end
return stat and name
end
function Cursor.tset(self, config, section, values)
local stat = true
for k, v in pairs(values) do
if k:sub(1, 1) ~= "." then
stat = stat and self:set(config, section, k, v)
end
end
return stat
end
function Cursor.get_bool(self, ...)
local val = self:get(...)
return ( val == "1" or val == "true" or val == "yes" or val == "on" )
end
function Cursor.get_list(self, config, section, option)
if config and section and option then
local val = self:get(config, section, option)
return ( type(val) == "table" and val or { val } )
end
return {}
end
function Cursor.get_first(self, conf, stype, opt, def)
local rv = def
self:foreach(conf, stype,
function(s)
local val = not opt and s['.name'] or s[opt]
if type(def) == "number" then
val = tonumber(val)
elseif type(def) == "boolean" then
val = (val == "1" or val == "true" or
val == "yes" or val == "on")
end
if val ~= nil then
rv = val
return false
end
end)
return rv
end
function Cursor.set_list(self, config, section, option, value)
if config and section and option then
if not value or #value == 0 then
return self:delete(config, section, option)
end
return self:set(
config, section, option,
( type(value) == "table" and value or { value } )
)
end
return false
end
-- Return a list of initscripts affected by configuration changes.
function _affected(self, configlist)
configlist = type(configlist) == "table" and configlist or { configlist }
function Cursor._affected(self, configlist)
configlist = type(configlist) == "table" and configlist or {configlist}
local c = cursor()
c:load("ucitrack")
-- Resolve dependencies
local reloadlist = { }
local reloadlist = {}
local function _resolve_deps(name)
local reload = { name }
local deps = { }
local reload = {name}
local deps = {}
self:foreach("ucitrack", name,
c:foreach("ucitrack", name,
function(section)
if section.affects then
for i, aff in ipairs(section.affects) do
@ -457,9 +173,7 @@ function _affected(self, configlist)
end
end)
local i, dep
for i, dep in ipairs(deps) do
local j, add
for j, add in ipairs(_resolve_deps(dep)) do
reload[#reload+1] = add
end
@ -469,9 +183,7 @@ function _affected(self, configlist)
end
-- Collect initscripts
local j, config
for j, config in ipairs(configlist) do
local i, e
for i, e in ipairs(_resolve_deps(config)) do
if not util.contains(reloadlist, e) then
reloadlist[#reloadlist+1] = e
@ -481,3 +193,44 @@ function _affected(self, configlist)
return reloadlist
end
-- curser, means it the parent unloads or loads configs, the sub state will
-- do so as well.
function Cursor.substate(self)
Cursor._substates = Cursor._substates or { }
Cursor._substates[self] = Cursor._substates[self] or cursor_state()
return Cursor._substates[self]
end
local _load = Cursor.load
function Cursor.load(self, ...)
if Cursor._substates and Cursor._substates[self] then
_load(Cursor._substates[self], ...)
end
return _load(self, ...)
end
local _unload = Cursor.unload
function Cursor.unload(self, ...)
if Cursor._substates and Cursor._substates[self] then
_unload(Cursor._substates[self], ...)
end
return _unload(self, ...)
end

View File

@ -14,226 +14,224 @@ module "luci.model.uci"
---[[
Create a new UCI-Cursor.
@class function
@name cursor
@return UCI-Cursor
@class function
@name cursor
@return UCI-Cursor
]]
---[[
Create a new Cursor initialized to the state directory.
@class function
@name cursor_state
@return UCI cursor
@class function
@name cursor_state
@return UCI cursor
]]
---[[
Applies UCI configuration changes
@class function
@name Cursor.apply
@param configlist List of UCI configurations
@param command Don't apply only return the command
@class function
@name Cursor.apply
@param configlist List of UCI configurations
@param command Don't apply only return the command
]]
---[[
Delete all sections of a given type that match certain criteria.
@class function
@name Cursor.delete_all
@class function
@name Cursor.delete_all
@param config UCI config
@param type UCI section type
@param comparator Function that will be called for each section and returns
a boolean whether to delete the current section (optional)
@param comparator Function that will be called for each section and
returns a boolean whether to delete the current section (optional)
]]
---[[
Create a new section and initialize it with data.
@class function
@name Cursor.section
@param config UCI config
@param type UCI section type
@param name UCI section name (optional)
@param values Table of key - value pairs to initialize the section with
@return Name of created section
@class function
@name Cursor.section
@param config UCI config
@param type UCI section type
@param name UCI section name (optional)
@param values Table of key - value pairs to initialize the section with
@return Name of created section
]]
---[[
Updated the data of a section using data from a table.
@class function
@name Cursor.tset
@param config UCI config
@param section UCI section name (optional)
@param values Table of key - value pairs to update the section with
@class function
@name Cursor.tset
@param config UCI config
@param section UCI section name (optional)
@param values Table of key - value pairs to update the section with
]]
---[[
Get a boolean option and return it's value as true or false.
@class function
@name Cursor.get_bool
@param config UCI config
@param section UCI section name
@param option UCI option
@return Boolean
@class function
@name Cursor.get_bool
@param config UCI config
@param section UCI section name
@param option UCI option
@return Boolean
]]
---[[
Get an option or list and return values as table.
@class function
@name Cursor.get_list
@param config UCI config
@param section UCI section name
@param option UCI option
@return table. If the option was not found, you will simply get an empty
table.
@class function
@name Cursor.get_list
@param config UCI config
@param section UCI section name
@param option UCI option
@return table. If the option was not found, you will simply get
-- an empty table.
]]
---[[
Get the given option from the first section with the given type.
@class function
@name Cursor.get_first
@param config UCI config
@param type UCI section type
@param option UCI option (optional)
@param default Default value (optional)
@return UCI value
@class function
@name Cursor.get_first
@param config UCI config
@param type UCI section type
@param option UCI option (optional)
@param default Default value (optional)
@return UCI value
]]
---[[
Set given values as list. Setting a list option to an empty list
has the same effect as deleting the option.
@class function
@name Cursor.set_list
@param config UCI config
@param section UCI section name
@param option UCI option
@param value Value or table. Non-table values will be set as single
item UCI list.
@return Boolean whether operation succeeded
@class function
@name Cursor.set_list
@param config UCI config
@param section UCI section name
@param option UCI option
@param value value or table. Raw values will become a single item table.
@return Boolean whether operation succeeded
]]
---[[
Create a sub-state of this cursor.
Create a sub-state of this cursor. The sub-state is tied to the parent
The sub-state is tied to the parent curser, means it the parent unloads or
loads configs, the sub state will do so as well.
@class function
@name Cursor.substate
@return UCI state cursor tied to the parent cursor
curser, means it the parent unloads or loads configs, the sub state will
do so as well.
@class function
@name Cursor.substate
@return UCI state cursor tied to the parent cursor
]]
---[[
Add an anonymous section.
@class function
@name Cursor.add
@param config UCI config
@param type UCI section type
@return Name of created section
@class function
@name Cursor.add
@param config UCI config
@param type UCI section type
@return Name of created section
]]
---[[
Get a table of saved but uncommitted changes.
@class function
@name Cursor.changes
@param config UCI config
@return Table of changes
@see Cursor.save
@class function
@name Cursor.changes
@param config UCI config
@return Table of changes
@see Cursor.save
]]
---[[
Commit saved changes.
@class function
@name Cursor.commit
@param config UCI config
@return Boolean whether operation succeeded
@see Cursor.revert
@see Cursor.save
@class function
@name Cursor.commit
@param config UCI config
@return Boolean whether operation succeeded
@see Cursor.revert
@see Cursor.save
]]
---[[
Deletes a section or an option.
@class function
@name Cursor.delete
@param config UCI config
@param section UCI section name
@param option UCI option (optional)
@return Boolean whether operation succeeded
@class function
@name Cursor.delete
@param config UCI config
@param section UCI section name
@param option UCI option (optional)
@return Boolean whether operation succeeded
]]
---[[
Call a function for every section of a certain type.
@class function
@name Cursor.foreach
@param config UCI config
@param type UCI section type
@param callback Function to be called
@return Boolean whether operation succeeded
@class function
@name Cursor.foreach
@param config UCI config
@param type UCI section type
@param callback Function to be called
@return Boolean whether operation succeeded
]]
---[[
Get a section type or an option
@class function
@name Cursor.get
@param config UCI config
@param section UCI section name
@param option UCI option (optional)
@return UCI value
@class function
@name Cursor.get
@param config UCI config
@param section UCI section name
@param option UCI option (optional)
@return UCI value
]]
---[[
Get all sections of a config or all values of a section.
@class function
@name Cursor.get_all
@param config UCI config
@param section UCI section name (optional)
@return Table of UCI sections or table of UCI values
@class function
@name Cursor.get_all
@param config UCI config
@param section UCI section name (optional)
@return Table of UCI sections or table of UCI values
]]
---[[
Manually load a config.
@class function
@name Cursor.load
@param config UCI config
@return Boolean whether operation succeeded
@see Cursor.save
@see Cursor.unload
@class function
@name Cursor.load
@param config UCI config
@return Boolean whether operation succeeded
@see Cursor.save
@see Cursor.unload
]]
---[[
Revert saved but uncommitted changes.
@class function
@name Cursor.revert
@param config UCI config
@return Boolean whether operation succeeded
@see Cursor.commit
@see Cursor.save
@class function
@name Cursor.revert
@param config UCI config
@return Boolean whether operation succeeded
@see Cursor.commit
@see Cursor.save
]]
---[[
Saves changes made to a config to make them committable.
@class function
@name Cursor.save
@param config UCI config
@return Boolean whether operation succeeded
@see Cursor.load
@see Cursor.unload
@class function
@name Cursor.save
@param config UCI config
@return Boolean whether operation succeeded
@see Cursor.load
@see Cursor.unload
]]
---[[
@ -245,74 +243,57 @@ then a named section of the given type is created.
When invoked with four arguments `config`, `sectionname`, `optionname` and
`optionvalue` then the value of the specified option is set to the given value.
@class function
@name Cursor.set
@param config UCI config
@param section UCI section name
@param option UCI option or UCI section type
@class function
@name Cursor.set
@param config UCI config
@param section UCI section name
@param option UCI option or UCI section type
@param value UCI value or nothing if you want to create a section
@return Boolean whether operation succeeded
@return Boolean whether operation succeeded
]]
---[[
Get the configuration directory.
@class function
@name Cursor.get_confdir
@return Configuration directory
@class function
@name Cursor.get_confdir
@return Configuration directory
]]
---[[
Get the directory for uncomitted changes.
@class function
@name Cursor.get_savedir
@return Save directory
]]
---[[
Get the effective session ID.
@class function
@name Cursor.get_session_id
@return String containing the session ID
@class function
@name Cursor.get_savedir
@return Save directory
]]
---[[
Set the configuration directory.
@class function
@name Cursor.set_confdir
@class function
@name Cursor.set_confdir
@param directory UCI configuration directory
@return Boolean whether operation succeeded
@return Boolean whether operation succeeded
]]
---[[
Set the directory for uncommited changes.
@class function
@name Cursor.set_savedir
@class function
@name Cursor.set_savedir
@param directory UCI changes directory
@return Boolean whether operation succeeded
]]
---[[
Set the effective session ID.
@class function
@name Cursor.set_session_id
@param id String containing the session ID to set
@return Boolean whether operation succeeded
@return Boolean whether operation succeeded
]]
---[[
Discard changes made to a config.
@class function
@name Cursor.unload
@param config UCI config
@return Boolean whether operation succeeded
@see Cursor.load
@see Cursor.save
@class function
@name Cursor.unload
@param config UCI config
@return Boolean whether operation succeeded
@see Cursor.load
@see Cursor.save
]]

View File

@ -7,7 +7,6 @@ local table = require "table"
local nixio = require "nixio"
local fs = require "nixio.fs"
local uci = require "luci.model.uci"
local ntm = require "luci.model.network"
local luci = {}
luci.util = require "luci.util"
@ -70,6 +69,24 @@ function mounts()
return data
end
function mtds()
local data = {}
if fs.access("/proc/mtd") then
for l in io.lines("/proc/mtd") do
local d, s, e, n = l:match('^([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+"([^%s]+)"')
if s and n then
local d = {}
d.size = tonumber(s, 16)
d.name = n
table.insert(data, d)
end
end
end
return data
end
-- containing the whole environment is returned otherwise this function returns
-- the corresponding string value for the given name or nil if no such variable
-- exists.
@ -87,10 +104,10 @@ end
function httpget(url, stream, target)
if not target then
local source = stream and io.popen or luci.util.exec
return source("wget -qO- %s" % luci.util.shellquote(url))
return source("wget -qO- '"..url:gsub("'", "").."'")
else
return os.execute("wget -qO %s %s" %
{luci.util.shellquote(target), luci.util.shellquote(url)})
return os.execute("wget -qO '%s' '%s'" %
{target:gsub("'", ""), url:gsub("'", "")})
end
end
@ -138,22 +155,17 @@ local function _nethints(what, callback)
luci.ip.neighbors(nil, function(neigh)
if neigh.mac and neigh.family == 4 then
_add(what, neigh.mac:string(), neigh.dest:string(), nil, nil)
_add(what, neigh.mac:upper(), neigh.dest:string(), nil, nil)
elseif neigh.mac and neigh.family == 6 then
_add(what, neigh.mac:string(), nil, neigh.dest:string(), nil)
_add(what, neigh.mac:upper(), nil, neigh.dest:string(), nil)
end
end)
if fs.access("/etc/ethers") then
for e in io.lines("/etc/ethers") do
mac, name = e:match("^([a-fA-F0-9:-]+)%s+(%S+)")
mac = luci.ip.checkmac(mac)
if mac and name then
if luci.ip.checkip4(name) then
_add(what, mac, name, nil, nil)
else
_add(what, mac, nil, nil, name)
end
mac, ip = e:match("^([a-f0-9]%S+) (%S+)")
if mac and ip then
_add(what, mac:upper(), ip, nil, nil)
end
end
end
@ -163,9 +175,8 @@ local function _nethints(what, callback)
if s.leasefile and fs.access(s.leasefile) then
for e in io.lines(s.leasefile) do
mac, ip, name = e:match("^%d+ (%S+) (%S+) (%S+)")
mac = luci.ip.checkmac(mac)
if mac and ip then
_add(what, mac, ip, nil, name ~= "*" and name)
_add(what, mac:upper(), ip, nil, name ~= "*" and name)
end
end
end
@ -175,10 +186,7 @@ local function _nethints(what, callback)
cur:foreach("dhcp", "host",
function(s)
for mac in luci.util.imatch(s.mac) do
mac = luci.ip.checkmac(mac)
if mac then
_add(what, mac, s.ip, nil, s.name)
end
_add(what, mac:upper(), s.ip, nil, s.name)
end
end)
@ -443,30 +451,55 @@ function user.checkpasswd(username, pass)
end
function user.setpasswd(username, password)
return os.execute("(echo %s; sleep 1; echo %s) | passwd %s >/dev/null 2>&1" %{
luci.util.shellquote(password),
luci.util.shellquote(password),
luci.util.shellquote(username)
})
if password then
password = password:gsub("'", [['"'"']])
end
if username then
username = username:gsub("'", [['"'"']])
end
return os.execute(
"(echo '" .. password .. "'; sleep 1; echo '" .. password .. "') | " ..
"passwd '" .. username .. "' >/dev/null 2>&1"
)
end
wifi = {}
function wifi.getiwinfo(ifname)
ntm.init()
local stat, iwinfo = pcall(require, "iwinfo")
local wnet = ntm:get_wifinet(ifname)
if wnet and wnet.iwinfo then
return wnet.iwinfo
if ifname then
local d, n = ifname:match("^(%w+)%.network(%d+)")
local wstate = luci.util.ubus("network.wireless", "status") or { }
d = d or ifname
n = n and tonumber(n) or 1
if type(wstate[d]) == "table" and
type(wstate[d].interfaces) == "table" and
type(wstate[d].interfaces[n]) == "table" and
type(wstate[d].interfaces[n].ifname) == "string"
then
ifname = wstate[d].interfaces[n].ifname
else
ifname = d
end
local t = stat and iwinfo.type(ifname)
local x = t and iwinfo[t] or { }
return setmetatable({}, {
__index = function(t, k)
if k == "ifname" then
return ifname
elseif x[k] then
return x[k](ifname)
end
end
})
end
local wdev = ntm:get_wifidev(ifname)
if wdev and wdev.iwinfo then
return wdev.iwinfo
end
return { ifname = ifname }
end

View File

@ -30,7 +30,7 @@ TZ = {
{ 'Africa/Johannesburg', 'SAST-2' },
{ 'Africa/Juba', 'EAT-3' },
{ 'Africa/Kampala', 'EAT-3' },
{ 'Africa/Khartoum', 'CAT-2' },
{ 'Africa/Khartoum', 'EAT-3' },
{ 'Africa/Kigali', 'CAT-2' },
{ 'Africa/Kinshasa', 'WAT-1' },
{ 'Africa/Lagos', 'WAT-1' },
@ -51,10 +51,10 @@ TZ = {
{ 'Africa/Nouakchott', 'GMT0' },
{ 'Africa/Ouagadougou', 'GMT0' },
{ 'Africa/Porto-Novo', 'WAT-1' },
{ 'Africa/Sao Tome', 'WAT-1' },
{ 'Africa/Sao Tome', 'GMT0' },
{ 'Africa/Tripoli', 'EET-2' },
{ 'Africa/Tunis', 'CET-1' },
{ 'Africa/Windhoek', 'CAT-2' },
{ 'Africa/Windhoek', 'WAT-1WAST,M9.1.0,M4.1.0' },
{ 'America/Adak', 'HST10HDT,M3.2.0,M11.1.0' },
{ 'America/Anchorage', 'AKST9AKDT,M3.2.0,M11.1.0' },
{ 'America/Anguilla', 'AST4' },
@ -85,7 +85,7 @@ TZ = {
{ 'America/Bogota', '<-05>5' },
{ 'America/Boise', 'MST7MDT,M3.2.0,M11.1.0' },
{ 'America/Cambridge Bay', 'MST7MDT,M3.2.0,M11.1.0' },
{ 'America/Campo Grande', '<-04>4<-03>,M11.1.0/0,M2.3.0/0' },
{ 'America/Campo Grande', '<-04>4<-03>,M10.3.0/0,M2.3.0/0' },
{ 'America/Cancun', 'EST5' },
{ 'America/Caracas', '<-04>4' },
{ 'America/Cayenne', '<-03>3' },
@ -94,7 +94,7 @@ TZ = {
{ 'America/Chihuahua', 'MST7MDT,M4.1.0,M10.5.0' },
{ 'America/Costa Rica', 'CST6' },
{ 'America/Creston', 'MST7' },
{ 'America/Cuiaba', '<-04>4<-03>,M11.1.0/0,M2.3.0/0' },
{ 'America/Cuiaba', '<-04>4<-03>,M10.3.0/0,M2.3.0/0' },
{ 'America/Curacao', 'AST4' },
{ 'America/Danmarkshavn', 'GMT0' },
{ 'America/Dawson', 'PST8PDT,M3.2.0,M11.1.0' },
@ -110,7 +110,7 @@ TZ = {
{ 'America/Glace Bay', 'AST4ADT,M3.2.0,M11.1.0' },
{ 'America/Godthab', '<-03>3<-02>,M3.5.0/-2,M10.5.0/-1' },
{ 'America/Goose Bay', 'AST4ADT,M3.2.0,M11.1.0' },
{ 'America/Grand Turk', 'EST5EDT,M3.2.0,M11.1.0' },
{ 'America/Grand Turk', 'AST4' },
{ 'America/Grenada', 'AST4' },
{ 'America/Guadeloupe', 'AST4' },
{ 'America/Guatemala', 'CST6' },
@ -181,7 +181,7 @@ TZ = {
{ 'America/Santarem', '<-03>3' },
{ 'America/Santiago', '<-04>4<-03>,M8.2.6/24,M5.2.6/24' },
{ 'America/Santo Domingo', 'AST4' },
{ 'America/Sao Paulo', '<-03>3<-02>,M11.1.0/0,M2.3.0/0' },
{ 'America/Sao Paulo', '<-03>3<-02>,M10.3.0/0,M2.3.0/0' },
{ 'America/Scoresbysund', '<-01>1<+00>,M3.5.0/0,M10.5.0/1' },
{ 'America/Sitka', 'AKST9AKDT,M3.2.0,M11.1.0' },
{ 'America/St Barthelemy', 'AST4' },
@ -202,7 +202,7 @@ TZ = {
{ 'America/Winnipeg', 'CST6CDT,M3.2.0,M11.1.0' },
{ 'America/Yakutat', 'AKST9AKDT,M3.2.0,M11.1.0' },
{ 'America/Yellowknife', 'MST7MDT,M3.2.0,M11.1.0' },
{ 'Antarctica/Casey', '<+08>-8' },
{ 'Antarctica/Casey', '<+11>-11' },
{ 'Antarctica/Davis', '<+07>-7' },
{ 'Antarctica/DumontDUrville', '<+10>-10' },
{ 'Antarctica/Macquarie', '<+11>-11' },
@ -238,9 +238,9 @@ TZ = {
{ 'Asia/Dili', '<+09>-9' },
{ 'Asia/Dubai', '<+04>-4' },
{ 'Asia/Dushanbe', '<+05>-5' },
{ 'Asia/Famagusta', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
{ 'Asia/Gaza', 'EET-2EEST,M3.4.6/1,M10.5.6/1' },
{ 'Asia/Hebron', 'EET-2EEST,M3.4.6/1,M10.5.6/1' },
{ 'Asia/Famagusta', '<+03>-3' },
{ 'Asia/Gaza', 'EET-2EEST,M3.5.6/1,M10.5.6/1' },
{ 'Asia/Hebron', 'EET-2EEST,M3.5.6/1,M10.5.6/1' },
{ 'Asia/Ho Chi Minh', '<+07>-7' },
{ 'Asia/Hong Kong', 'HKT-8' },
{ 'Asia/Hovd', '<+07>-7' },
@ -425,7 +425,7 @@ TZ = {
{ 'Pacific/Efate', '<+11>-11' },
{ 'Pacific/Enderbury', '<+13>-13' },
{ 'Pacific/Fakaofo', '<+13>-13' },
{ 'Pacific/Fiji', '<+12>-12<+13>,M11.1.0,M1.2.1/147' },
{ 'Pacific/Fiji', '<+12>-12<+13>,M11.1.0,M1.3.0/3' },
{ 'Pacific/Funafuti', '<+12>-12' },
{ 'Pacific/Galapagos', '<-06>6' },
{ 'Pacific/Gambier', '<-09>9' },
@ -451,7 +451,7 @@ TZ = {
{ 'Pacific/Saipan', 'ChST-10' },
{ 'Pacific/Tahiti', '<-10>10' },
{ 'Pacific/Tarawa', '<+12>-12' },
{ 'Pacific/Tongatapu', '<+13>-13' },
{ 'Pacific/Tongatapu', '<+13>-13<+14>,M11.1.0,M1.3.0/3' },
{ 'Pacific/Wake', '<+12>-12' },
{ 'Pacific/Wallis', '<+12>-12' },
}

View File

@ -4,7 +4,6 @@
module("luci.tools.status", package.seeall)
local uci = require "luci.model.uci".cursor()
local ipc = require "luci.ip"
local function dhcp_leases_common(family)
local rv = { }
@ -32,7 +31,7 @@ local function dhcp_leases_common(family)
if family == 4 and not ip:match(":") then
rv[#rv+1] = {
expires = (expire ~= 0) and os.difftime(expire, os.time()),
macaddr = ipc.checkmac(mac) or "00:00:00:00:00:00",
macaddr = mac,
ipaddr = ip,
hostname = (name ~= "*") and name
}
@ -75,9 +74,19 @@ local function dhcp_leases_common(family)
hostname = (name ~= "-") and name
}
elseif ip and iaid == "ipv4" and family == 4 then
local mac, mac1, mac2, mac3, mac4, mac5, mac6
if duid and type(duid) == "string" then
mac1, mac2, mac3, mac4, mac5, mac6 = duid:match("^(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)$")
end
if not (mac1 and mac2 and mac3 and mac4 and mac5 and mac6) then
mac = "FF:FF:FF:FF:FF:FF"
else
mac = mac1..":"..mac2..":"..mac3..":"..mac4..":"..mac5..":"..mac6
end
rv[#rv+1] = {
expires = (expire >= 0) and os.difftime(expire, os.time()),
macaddr = ipc.checkmac(duid:gsub("^(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)$", "%1:%2:%3:%4:%5:%6")) or "00:00:00:00:00:00",
macaddr = duid,
macaddr = mac:lower(),
ipaddr = ip,
hostname = (name ~= "-") and name
}
@ -187,9 +196,7 @@ function switch_status(devs)
local switches = { }
for dev in devs:gmatch("[^%s,]+") do
local ports = { }
local swc = io.popen("swconfig dev %s show"
% luci.util.shellquote(dev), "r")
local swc = io.popen("swconfig dev %q show" % dev, "r")
if swc then
local l
repeat

View File

@ -10,7 +10,6 @@ local string = require "string"
local coroutine = require "coroutine"
local tparser = require "luci.template.parser"
local json = require "luci.jsonc"
local lhttp = require "lucihttp"
local _ubus = require "ubus"
local _ubus_connection = nil
@ -161,25 +160,6 @@ function pcdata(value)
return value and tparser.pcdata(tostring(value))
end
function urlencode(value)
if value ~= nil then
local str = tostring(value)
return lhttp.urlencode(str, lhttp.ENCODE_IF_NEEDED + lhttp.ENCODE_FULL)
or str
end
return nil
end
function urldecode(value, decode_plus)
if value ~= nil then
local flag = decode_plus and lhttp.DECODE_PLUS or 0
local str = tostring(value)
return lhttp.urldecode(str, lhttp.DECODE_IF_NEEDED + flag)
or str
end
return nil
end
function striptags(value)
return value and tparser.striptags(tostring(value))
end
@ -407,6 +387,16 @@ function clone(object, deep)
end
function dtable()
return setmetatable({}, { __index =
function(tbl, key)
return rawget(tbl, key)
or rawget(rawset(tbl, key, dtable()), key)
end
})
end
-- Serialize the contents of a table value.
function _serialize_table(t, seen)
assert(not seen[t], "Recursion detected.")
@ -631,20 +621,6 @@ function execl(command)
return data
end
local ubus_codes = {
"INVALID_COMMAND",
"INVALID_ARGUMENT",
"METHOD_NOT_FOUND",
"NOT_FOUND",
"NO_DATA",
"PERMISSION_DENIED",
"TIMEOUT",
"NOT_SUPPORTED",
"UNKNOWN_ERROR",
"CONNECTION_FAILED"
}
function ubus(object, method, data)
if not _ubus_connection then
_ubus_connection = _ubus.connect()
@ -655,8 +631,7 @@ function ubus(object, method, data)
if type(data) ~= "table" then
data = { }
end
local rv, err = _ubus_connection:call(object, method, data)
return rv, err, ubus_codes[err]
return _ubus_connection:call(object, method, data)
elseif object then
return _ubus_connection:signatures(object)
else
@ -681,11 +656,10 @@ end
function checklib(fullpathexe, wantedlib)
local fs = require "nixio.fs"
local haveldd = fs.access('/usr/bin/ldd')
local haveexe = fs.access(fullpathexe)
if not haveldd or not haveexe then
if not haveldd then
return false
end
local libs = exec(string.format("/usr/bin/ldd %s", shellquote(fullpathexe)))
local libs = exec("/usr/bin/ldd " .. fullpathexe)
if not libs then
return false
end

View File

@ -15,164 +15,126 @@ Class can be instantiated by calling them. All parameters will be passed
to the __init__ function of this class - if such a function exists.
The __init__ function must be used to set any object parameters that are not shared
with other objects of this class. Any return values will be ignored.
@class function
@name class
@param base The base class to inherit from (optional)
@return A class object
@see instanceof
@see clone
@class function
@name class
@param base The base class to inherit from (optional)
@return A class object
@see instanceof
@see clone
]]
---[[
Test whether the given object is an instance of the given class.
@class function
@name instanceof
@param object Object instance
@class function
@name instanceof
@param object Object instance
@param class Class object to test against
@return Boolean indicating whether the object is an instance
@return Boolean indicating whether the object is an instance
@see class
@see clone
]]
---[[
Create a new or get an already existing thread local store associated with
the current active coroutine.
A thread local store is private a table object
the current active coroutine. A thread local store is private a table object
whose values can't be accessed from outside of the running coroutine.
@class function
@name threadlocal
@return Table value representing the corresponding thread local store
@class function
@name threadlocal
@return Table value representing the corresponding thread local store
]]
---[[
Write given object to stderr.
@class function
@name perror
@param obj Value to write to stderr
@return Boolean indicating whether the write operation was successful
@class function
@name perror
@param obj Value to write to stderr
@return Boolean indicating whether the write operation was successful
]]
---[[
Recursively dumps a table to stdout, useful for testing and debugging.
@class function
@name dumptable
@param t Table value to dump
@param maxdepth Maximum depth
@return Always nil
@class function
@name dumptable
@param t Table value to dump
@param maxdepth Maximum depth
@return Always nil
]]
---[[
Create valid XML PCDATA from given string.
@class function
@name pcdata
@param value String value containing the data to escape
@return String value containing the escaped data
]]
---[[
Decode an URL-encoded string - optionally decoding the "+" sign to space.
@class function
@name urldecode
@param str Input string in x-www-urlencoded format
@param decode_plus Decode "+" signs to spaces if true (optional)
@return The decoded string
@see urlencode
]]
---[[
URL-encode given string.
@class function
@name urlencode
@param str String to encode
@return String containing the encoded data
@see urldecode
@class function
@name pcdata
@param value String value containing the data to escape
@return String value containing the escaped data
]]
---[[
Strip HTML tags from given string.
@class function
@name striptags
@param value String containing the HTML text
@return String with HTML tags stripped of
]]
---[[
Safely quote value for use in shell commands.
@class function
@name shellquote
@param value String containing the value to quote
@return Single-quote enclosed string with embedded quotes escaped
@class function
@name striptags
@param value String containing the HTML text
@return String with HTML tags stripped of
]]
---[[
Splits given string on a defined separator sequence and return a table
containing the resulting substrings.
The optional max parameter specifies the number of bytes to process,
regardless of the actual length of the given string. The optional last
parameter, regex, specifies whether the separator sequence is
nterpreted as regular expression.
@class function
@name split
@param str String value containing the data to split up
@param pat String with separator pattern (optional, defaults to "\n")
@param max Maximum times to split (optional)
@param regex Boolean indicating whether to interpret the separator
containing the resulting substrings. The optional max parameter specifies
the number of bytes to process, regardless of the actual length of the given
string. The optional last parameter, regex, specifies whether the separator
sequence is interpreted as regular expression.
@class function
@name split
@param str String value containing the data to split up
@param pat String with separator pattern (optional, defaults to "\n")
@param max Maximum times to split (optional)
@param regex Boolean indicating whether to interpret the separator
-- pattern as regular expression (optional, default is false)
@return Table containing the resulting substrings
@return Table containing the resulting substrings
]]
---[[
Remove leading and trailing whitespace from given string value.
@class function
@name trim
@param str String value containing whitespace padded data
@return String value with leading and trailing space removed
@class function
@name trim
@param str String value containing whitespace padded data
@return String value with leading and trailing space removed
]]
---[[
Count the occurrences of given substring in given string.
Count the occurences of given substring in given string.
@class function
@name cmatch
@param str String to search in
@param pattern String containing pattern to find
@return Number of found occurrences
@class function
@name cmatch
@param str String to search in
@param pattern String containing pattern to find
@return Number of found occurences
]]
---[[
Return a matching iterator for the given value.
Return a matching iterator for the given value. The iterator will return
The iterator will return one token per invocation, the tokens are separated by
whitespace. If the input value is a table, it is transformed into a string first.
A nil value will result in a valid interator which aborts with the first invocation.
@class function
@name imatch
@param val The value to scan (table, string or nil)
@return Iterator which returns one token per call
one token per invocation, the tokens are separated by whitespace. If the
input value is a table, it is transformed into a string first. A nil value
will result in a valid interator which aborts with the first invocation.
@class function
@name imatch
@param val The value to scan (table, string or nil)
@return Iterator which returns one token per call
]]
---[[
Parse certain units from the given string and return the canonical integer
value or 0 if the unit is unknown.
Upper- or lower case is irrelevant.
value or 0 if the unit is unknown. Upper- or lower case is irrelevant.
Recognized units are:
-- o "y" - one year (60*60*24*366)
o "m" - one month (60*60*24*31)
o "w" - one week (60*60*24*7)
@ -185,229 +147,232 @@ Recognized units are:
o "kib" - one si kilobyte (1000)
o "mib" - one si megabyte (1000*1000)
o "gib" - one si gigabyte (1000*1000*1000)
@class function
@name parse_units
@param ustr String containing a numerical value with trailing unit
@return Number containing the canonical value
@class function
@name parse_units
@param ustr String containing a numerical value with trailing unit
@return Number containing the canonical value
]]
---[[
Appends numerically indexed tables or single objects to a given table.
@class function
@name append
@param src Target table
@param ... Objects to insert
@return Target table
@class function
@name append
@param src Target table
@param ... Objects to insert
@return Target table
]]
---[[
Combines two or more numerically indexed tables and single objects into one table.
@class function
@name combine
@param tbl1 Table value to combine
@param tbl2 Table value to combine
@param ... More tables to combine
@return Table value containing all values of given tables
@class function
@name combine
@param tbl1 Table value to combine
@param tbl2 Table value to combine
@param ... More tables to combine
@return Table value containing all values of given tables
]]
---[[
Checks whether the given table contains the given value.
@class function
@name contains
@param table Table value
@param value Value to search within the given table
@return Number indicating the first index at which the given value occurs
-- within table or false.
@class function
@name contains
@param table Table value
@param value Value to search within the given table
@return number indicating the first index at which the given value occurs
-- within table or false.
]]
---[[
Update values in given table with the values from the second given table.
Both table are - in fact - merged together.
@class function
@name update
@class function
@name update
@param t Table which should be updated
@param updates Table containing the values to update
@return Always nil
@param updates Table containing the values to update
@return Always nil
]]
---[[
Retrieve all keys of given associative table.
@class function
@name keys
@param t Table to extract keys from
@return Sorted table containing the keys
@class function
@name keys
@param t Table to extract keys from
@return Sorted table containing the keys
]]
---[[
Clones the given object and return it's copy.
@class function
@name clone
@param object Table value to clone
@param deep Boolean indicating whether to do recursive cloning
@return Cloned table value
@class function
@name clone
@param object Table value to clone
@param deep Boolean indicating whether to do recursive cloning
@return Cloned table value
]]
---[[
Create a dynamic table which automatically creates subtables.
@class function
@name dtable
@return Dynamic Table
]]
---[[
Recursively serialize given data to lua code, suitable for restoring
with loadstring().
@class function
@name serialize_data
@param val Value containing the data to serialize
@return String value containing the serialized code
@see restore_data
@see get_bytecode
with loadstring().
@class function
@name serialize_data
@param val Value containing the data to serialize
@return String value containing the serialized code
@see restore_data
@see get_bytecode
]]
---[[
Restore data previously serialized with serialize_data().
@class function
@name restore_data
@param str String containing the data to restore
@return Value containing the restored data structure
@see serialize_data
@see get_bytecode
@class function
@name restore_data
@param str String containing the data to restore
@return Value containing the restored data structure
@see serialize_data
@see get_bytecode
]]
---[[
Return the current runtime bytecode of the given data. The byte code
will be stripped before it is returned.
@class function
@name get_bytecode
@param val Value to return as bytecode
@return String value containing the bytecode of the given data
will be stripped before it is returned.
@class function
@name get_bytecode
@param val Value to return as bytecode
@return String value containing the bytecode of the given data
]]
---[[
Strips unnescessary lua bytecode from given string.
Strips unnescessary lua bytecode from given string. Information like line
Information like line numbers and debugging numbers will be discarded.
Original version by Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html)
@class function
@name strip_bytecode
@param code String value containing the original lua byte code
@return String value containing the stripped lua byte code
numbers and debugging numbers will be discarded. Original version by
Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html)
@class function
@name strip_bytecode
@param code String value containing the original lua byte code
@return String value containing the stripped lua byte code
]]
---[[
Return a key, value iterator which returns the values sorted according to
the provided callback function.
@class function
@name spairs
@param t The table to iterate
@param f A callback function to decide the order of elements
@return Function value containing the corresponding iterator
the provided callback function.
@class function
@name spairs
@param t The table to iterate
@param f A callback function to decide the order of elements
@return Function value containing the corresponding iterator
]]
---[[
Return a key, value iterator for the given table.
The table pairs are sorted by key.
@class function
@name kspairs
@param t The table to iterate
@return Function value containing the corresponding iterator
@class function
@name kspairs
@param t The table to iterate
@return Function value containing the corresponding iterator
]]
---[[
Return a key, value iterator for the given table.
The table pairs are sorted by value.
@class function
@name vspairs
@param t The table to iterate
@return Function value containing the corresponding iterator
@class function
@name vspairs
@param t The table to iterate
@return Function value containing the corresponding iterator
]]
---[[
Test whether the current system is operating in big endian mode.
@class function
@name bigendian
@return Boolean value indicating whether system is big endian
@class function
@name bigendian
@return Boolean value indicating whether system is big endian
]]
---[[
Execute given commandline and gather stdout.
@class function
@name exec
@param command String containing command to execute
@return String containing the command's stdout
@class function
@name exec
@param command String containing command to execute
@return String containing the command's stdout
]]
---[[
Return a line-buffered iterator over the output of given command.
@class function
@name execi
@param command String containing the command to execute
@return Iterator
@class function
@name execi
@param command String containing the command to execute
@return Iterator
]]
---[[
Issue an ubus call.
@class function
@name ubus
@class function
@name ubus
@param object String containing the ubus object to call
@param method String containing the ubus method to call
@param values Table containing the values to pass
@return Table containin the ubus result
@return Table containin the ubus result
]]
---[[
Convert data structure to JSON
@class function
@name serialize_json
@param data The data to serialize
@param writer A function to write a chunk of JSON data (optional)
@return String containing the JSON if called without write callback
@class function
@name serialize_json
@param data The data to serialize
@param writer A function to write a chunk of JSON data (optional)
@return String containing the JSON if called without write callback
]]
---[[
Returns the absolute path to LuCI base directory.
@class function
@name libpath
@return String containing the directory path
@class function
@name libpath
@return String containing the directory path
]]
---[[
This is a coroutine-safe drop-in replacement for Lua's "xpcall"-function
@class function
@name coxpcall
@param f Lua function to be called protected
@param err Custom error handler
@param ... Parameters passed to the function
@return A boolean whether the function call succeeded and the return
-- values of either the function or the error handler
@class function
@name coxpcall
@param f Lua function to be called protected
@param err Custom error handler
@param ... Parameters passed to the function
@return A boolean whether the function call succeeded and the return
-- values of either the function or the error handler
]]
---[[
This is a coroutine-safe drop-in replacement for Lua's "pcall"-function
@class function
@name copcall
@param f Lua function to be called protected
@param ... Parameters passed to the function
@return A boolean whether the function call succeeded and the returns
-- values of the function or the error object
@class function
@name copcall
@param f Lua function to be called protected
@param ... Parameters passed to the function
@return A boolean whether the function call succeeded and the returns
-- values of the function or the error object
]]

View File

@ -2,7 +2,6 @@
<%+cbi/valueheader%>
<input class="cbi-input-text" type="text"<%= attr("value", v) .. attr("name", cbid) .. attr("id", cbid) %> />
<script type="text/javascript">
cbi_init()
cbi_browser_init('<%=cbid%>', '<%=resource%>', '<%=url('admin/filebrowser')%>'<%=self.default_path and ", '"..self.default_path.."'"%>);
</script>
<%+cbi/valuefooter%>

View File

@ -22,9 +22,9 @@
<script type="text/javascript">
function callback(path) {
if( window.opener ) {
var input = window.opener.document.getElementById(decodeURIComponent('<%=luci.http.urlencode(luci.http.formvalue('field'))%>'));
var input = window.opener.document.getElementById('<%=luci.http.formvalue('field')%>');
if( input ) {
input.value = decodeURIComponent(path);
input.value = path;
window.close();
}
}
@ -48,44 +48,33 @@
end
end
local filestat = nixio.fs.stat(table.concat(path, '/'))
local baseurl = { 'admin', 'filebrowser' }
local filepath = table.concat( path, '/' )
local filestat = nixio.fs.stat( filepath )
local baseurl = luci.dispatcher.build_url('admin', 'filebrowser')
if filestat and filestat.type == "reg" then
path[#path] = ''
elseif not (filestat and filestat.type == "dir") then
path = { '', '' }
table.remove( path, #path )
filepath = table.concat( path, '/' ) .. '/'
elseif not ( filestat and filestat.type == "dir" ) then
path = { '' }
filepath = '/'
else
path[#path+1] = ''
filepath = filepath .. '/'
end
filepath = table.concat(path, '/')
local entries = {}
local _, e
for _, e in luci.util.vspairs(nixio.util.consume((nixio.fs.dir(filepath)))) do
local p = filepath .. e
local s = nixio.fs.stat(p)
if s then
entries[#entries+1] = {
name = e,
path = p,
type = s.type
}
end
end
local entries = nixio.util.consume((nixio.fs.dir(filepath)))
-%>
<div id="path">
<div id="path">
Location:
<% for i, dir in ipairs(path) do %>
<% if i == 1 then %>
<a href="<%=url(unpack(baseurl))%>?field=<%=luci.http.urlencode(field)%>">(root)</a>
<a href="<%=baseurl%>?field=<%=field%>">(root)</a>
<% elseif next(path, i) then %>
<% baseurl[#baseurl+1] = luci.http.urlencode(dir) %>
/ <a href="<%=url(unpack(baseurl))%>?field=<%=luci.http.urlencode(field)%>"><%=pcdata(dir)%></a>
<% baseurl = baseurl .. '/' .. dir %>
/ <a href="<%=baseurl%>?field=<%=field%>"><%=dir%></a>
<% else %>
<% baseurl[#baseurl+1] = luci.http.urlencode(dir) %>
/ <%=pcdata(dir)%>
<% baseurl = baseurl .. '/' .. dir %>
/ <%=dir%>
<% end %>
<% end %>
</div>
@ -94,17 +83,23 @@
<div id="listing">
<ul>
<% for _, e in ipairs(entries) do if e.type == 'dir' then -%>
<% for _, e in luci.util.vspairs(entries) do
local stat = nixio.fs.stat(filepath..e)
if stat and stat.type == 'dir' then
-%>
<li class="dir">
<img src="<%=resource%>/cbi/folder.gif" alt="<%:Directory%>" />
<a href="<%=url(unpack(baseurl))%>/<%=luci.http.urlencode(e.name)%>?field=<%=luci.http.urlencode(field)%>"><%=pcdata(e.name)%>/</a>
<a href="<%=baseurl%>/<%=e%>?field=<%=field%>"><%=e%>/</a>
</li>
<% end end -%>
<% for _, e in ipairs(entries) do if e.type ~= 'dir' then -%>
<% for _, e in luci.util.vspairs(entries) do
local stat = nixio.fs.stat(filepath..e)
if stat and stat.type ~= 'dir' then
-%>
<li class="file">
<img src="<%=resource%>/cbi/file.gif" alt="<%:File%>" />
<a href="#" onclick="callback('<%=luci.http.urlencode(e.path)%>')"><%=pcdata(e.name)%></a>
<a href="#" onclick="callback('<%=filepath..e%>')"><%=e%></a>
</li>
<% end end -%>
</ul>

View File

@ -43,12 +43,11 @@
&#160;&#8658;&#160;
<% for _, fwd in ipairs(zone:get_forwardings_by("src")) do
fz = fwd:dest_zone()
if fz then
empty = false %>
empty = false %>
<label class="zonebadge" style="background-color:<%=fz:get_color()%>">
<strong><%=fz:name()%></strong>
</label>&#160;
<% end end %>
<% end %>
<% if empty then %>
<label class="zonebadge zonebadge-empty">
<strong><%=zone:forward():upper()%></strong>

View File

@ -24,72 +24,70 @@
end
-%>
<span>
<ul style="margin:0; list-style-type:none; text-align:left">
<% if self.allowlocal then %>
<li style="padding:0.5em">
<input class="cbi-input-radio" data-update="click change"<%=attr("type", self.widget or "radio") .. attr("id", cbid .. "_empty") .. attr("name", cbid) .. attr("value", "") .. ifattr(checked[""], "checked", "checked")%> /> &#160;
<label<%=attr("for", cbid .. "_empty")%>></label>
<label<%=attr("for", cbid .. "_empty")%> style="background-color:<%=fwm.zone.get_color()%>" class="zonebadge">
<strong><%:Device%></strong>
<% if self.allowany and self.allowlocal then %>(<%:input%>)<% end %>
</label>
</li>
<% end %>
<% if self.allowany then %>
<li style="padding:0.5em">
<input class="cbi-input-radio" data-update="click change"<%=attr("type", self.widget or "radio") .. attr("id", cbid .. "_any") .. attr("name", cbid) .. attr("value", "*") .. ifattr(checked["*"], "checked", "checked")%> /> &#160;
<label<%=attr("for", cbid .. "_any")%>></label>
<label<%=attr("for", cbid .. "_any")%> style="background-color:<%=fwm.zone.get_color()%>" class="zonebadge">
<strong><%:Any zone%></strong>
<% if self.allowany and self.allowlocal then %>(<%:forward%>)<% end %>
</label>
</li>
<% end %>
<%
for _, zone in utl.spairs(zones, function(a,b) return (zones[a]:name() < zones[b]:name()) end) do
if zone:name() ~= self.exclude then
selected = selected or (value == zone:name())
%>
<li style="padding:0.5em">
<input class="cbi-input-radio" data-update="click change"<%=attr("type", self.widget or "radio") .. attr("id", cbid .. "." .. zone:name()) .. attr("name", cbid) .. attr("value", zone:name()) .. ifattr(checked[zone:name()], "checked", "checked")%> /> &#160;
<label<%=attr("for", cbid .. "." .. zone:name())%>></label>
<label<%=attr("for", cbid .. "." .. zone:name())%> style="background-color:<%=zone:get_color()%>" class="zonebadge">
<strong><%=zone:name()%>:</strong>
<ul style="margin:0; list-style-type:none; text-align:left">
<% if self.allowlocal then %>
<li style="padding:0.5em">
<input class="cbi-input-radio" data-update="click change"<%=attr("type", self.widget or "radio") .. attr("id", cbid .. "_empty") .. attr("name", cbid) .. attr("value", "") .. ifattr(checked[""], "checked", "checked")%> /> &#160;
<label<%=attr("for", cbid .. "_empty")%>></label>
<label<%=attr("for", cbid .. "_empty")%> style="background-color:<%=fwm.zone.get_color()%>" class="zonebadge">
<strong><%:Device%></strong>
<% if self.allowany and self.allowlocal then %>(<%:input%>)<% end %>
</label>
</li>
<% end %>
<% if self.allowany then %>
<li style="padding:0.5em">
<input class="cbi-input-radio" data-update="click change"<%=attr("type", self.widget or "radio") .. attr("id", cbid .. "_any") .. attr("name", cbid) .. attr("value", "*") .. ifattr(checked["*"], "checked", "checked")%> /> &#160;
<label<%=attr("for", cbid .. "_any")%>></label>
<label<%=attr("for", cbid .. "_any")%> style="background-color:<%=fwm.zone.get_color()%>" class="zonebadge">
<strong><%:Any zone%></strong>
<% if self.allowany and self.allowlocal then %>(<%:forward%>)<% end %>
</label>
</li>
<% end %>
<%
for _, zone in utl.spairs(zones, function(a,b) return (zones[a]:name() < zones[b]:name()) end) do
if zone:name() ~= self.exclude then
selected = selected or (value == zone:name())
%>
<li style="padding:0.5em">
<input class="cbi-input-radio" data-update="click change"<%=attr("type", self.widget or "radio") .. attr("id", cbid .. "." .. zone:name()) .. attr("name", cbid) .. attr("value", zone:name()) .. ifattr(checked[zone:name()], "checked", "checked")%> /> &#160;
<label<%=attr("for", cbid .. "." .. zone:name())%>></label>
<label<%=attr("for", cbid .. "." .. zone:name())%> style="background-color:<%=zone:get_color()%>" class="zonebadge">
<strong><%=zone:name()%>:</strong>
<%
local zempty = true
for _, net in ipairs(zone:get_networks()) do
net = nwm:get_network(net)
if net then
zempty = false
%>
<span class="ifacebadge<% if net:name() == self.network then %> ifacebadge-active<% end %>"><%=net:name()%>:
<%
local zempty = true
for _, net in ipairs(zone:get_networks()) do
net = nwm:get_network(net)
if net then
zempty = false
%>
<span class="ifacebadge<% if net:name() == self.network then %> ifacebadge-active<% end %>"><%=net:name()%>:
<%
local nempty = true
for _, iface in ipairs(net:is_bridge() and net:get_interfaces() or { net:get_interface() }) do
nempty = false
%>
<img<%=attr("title", iface:get_i18n())%> style="width:16px; height:16px; vertical-align:middle" src="<%=resource%>/icons/<%=iface:type()%><%=iface:is_up() and "" or "_disabled"%>.png" />
<% end %>
<% if nempty then %><em><%:(empty)%></em><% end %>
</span>
<% end end %>
<% if zempty then %><em><%:(empty)%></em><% end %>
</label>
</li>
<% end end %>
local nempty = true
for _, iface in ipairs(net:is_bridge() and net:get_interfaces() or { net:get_interface() }) do
nempty = false
%>
<img<%=attr("title", iface:get_i18n())%> style="width:16px; height:16px; vertical-align:middle" src="<%=resource%>/icons/<%=iface:type()%><%=iface:is_up() and "" or "_disabled"%>.png" />
<% end %>
<% if nempty then %><em><%:(empty)%></em><% end %>
</span>
<% end end %>
<% if zempty then %><em><%:(empty)%></em><% end %>
</label>
</li>
<% end end %>
<% if self.widget ~= "checkbox" and not self.nocreate then %>
<li style="padding:0.5em">
<input class="cbi-input-radio" data-update="click change" type="radio"<%=attr("id", cbid .. "_new") .. attr("name", cbid) .. attr("value", "-") .. ifattr(not selected, "checked", "checked")%> /> &#160;
<label<%=attr("for", cbid .. "_new")%>></label>
<div onclick="document.getElementById('<%=cbid%>_new').checked=true" class="zonebadge" style="background-color:<%=fwm.zone.get_color()%>">
<em><%:unspecified -or- create:%>&#160;</em>
<input type="text"<%=attr("name", cbid .. ".newzone") .. ifattr(not selected, "value", luci.http.formvalue(cbid .. ".newzone") or self.default)%> onfocus="document.getElementById('<%=cbid%>_new').checked=true" />
</div>
</li>
<% end %>
</ul>
</span>
<% if self.widget ~= "checkbox" and not self.nocreate then %>
<li style="padding:0.5em">
<input class="cbi-input-radio" data-update="click change" type="radio"<%=attr("id", cbid .. "_new") .. attr("name", cbid) .. attr("value", "-") .. ifattr(not selected, "checked", "checked")%> /> &#160;
<label<%=attr("for", cbid .. "_new")%>></label>
<div onclick="document.getElementById('<%=cbid%>_new').checked=true" class="zonebadge" style="background-color:<%=fwm.zone.get_color()%>">
<em><%:unspecified -or- create:%>&#160;</em>
<input type="text"<%=attr("name", cbid .. ".newzone") .. ifattr(not selected, "value", luci.http.formvalue(cbid .. ".newzone") or self.default)%> onfocus="document.getElementById('<%=cbid%>_new').checked=true" />
</div>
</li>
<% end %>
</ul>
<%+cbi/valuefooter%>

View File

@ -1,6 +1,6 @@
<%- if pageaction then -%>
<div class="cbi-page-actions">
<% if redirect and not flow.hidebackbtn then %>
<% if redirect then %>
<div style="float:left">
<input class="cbi-button cbi-button-link" type="button" value="<%:Back to Overview%>" onclick="location.href='<%=pcdata(redirect)%>'" />
</div>

View File

@ -52,8 +52,7 @@
<%- if not self.cancel then -%><%-:Cancel-%><%-else-%><%=self.cancel%><%end-%>
" />
<% end %>
<script type="text/javascript">cbi_d_update();</script>
</div>
</form>
<% end %>
<script type="text/javascript">cbi_init();</script>

View File

@ -35,7 +35,7 @@ end
<%- else -%>
<th>&#160;</th>
<%- end -%>
<%- count = count +1; end -%>
<%- end -%>
<%- for i, k in pairs(self.children) do if not k.optional then -%>
<th class="cbi-section-table-cell"<%=width(k)%>>
<%- if k.titleref then -%><a title="<%=self.titledesc or translate('Go to relevant configuration page')%>" class="cbi-title-ref" href="<%=k.titleref%>"><%- end -%>
@ -44,7 +44,7 @@ end
</th>
<%- count = count + 1; end; end; if self.sortable then -%>
<th class="cbi-section-table-cell"><%:Sort%></th>
<%- count = count + 1; end; if self.extedit or self.addremove then -%>
<%- end; if self.extedit or self.addremove then -%>
<th class="cbi-section-table-cell">&#160;</th>
<%- count = count + 1; end -%>
</tr>

View File

@ -7,5 +7,5 @@
<%+header%>
<h2 name="content">404 <%:Not Found%></h2>
<p><%:Sorry, the object you requested was not found.%></p>
<tt><%:Unable to dispatch%>: <%=url(unpack(luci.dispatcher.context.request))%></tt>
<tt><%:Unable to dispatch%>: <%=luci.http.request.env.PATH_INFO%></tt>
<%+footer%>

View File

@ -6,7 +6,7 @@
<%+header%>
<form method="post" action="<%=pcdata(FULL_REQUEST_URI)%>">
<form method="post" action="<%=pcdata(luci.http.getenv("REQUEST_URI"))%>">
<%- if fuser then %>
<div class="errorbox"><%:Invalid username and/or password! Please try again.%></div>
<% end -%>

View File

@ -13,9 +13,6 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Pootle 2.0.6\n"
msgid "%.1f dB"
msgstr ""
msgid "%s is untagged in multiple VLANs!"
msgstr ""
@ -127,7 +124,7 @@ msgid "<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Suffix (hex)"
msgstr ""
msgid "<abbr title=\"Light Emitting Diode\">LED</abbr> Configuration"
msgstr "Configuració dels <abbr title=\"Light Emitting Diode\">LED</abbr>s"
msgstr "Configuració <abbr title=\"Light Emitting Diode\">LED</abbr>"
msgid "<abbr title=\"Light Emitting Diode\">LED</abbr> Name"
msgstr "Nom <abbr title=\"Light Emitting Diode\">LED</abbr>"
@ -135,9 +132,6 @@ msgstr "Nom <abbr title=\"Light Emitting Diode\">LED</abbr>"
msgid "<abbr title=\"Media Access Control\">MAC</abbr>-Address"
msgstr "Adreça <abbr title=\"Media Access Control\">MAC</abbr>"
msgid "<abbr title=\"The DHCP Unique Identifier\">DUID</abbr>"
msgstr ""
msgid ""
"<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Dynamic Host Configuration "
"Protocol\">DHCP</abbr> leases"
@ -162,8 +156,6 @@ msgid ""
"<br/>Note: you need to manually restart the cron service if the crontab file "
"was empty before editing."
msgstr ""
"Avís: cal reiniciar manualment el servei cron si el fitxer crontab estava "
"buit abans d'editar-lo."
msgid "A43C + J43 + A43"
msgstr ""
@ -222,6 +214,9 @@ msgstr "Concentrador d'accés"
msgid "Access Point"
msgstr "Punt d'accés"
msgid "Action"
msgstr "Acció"
msgid "Actions"
msgstr "Accions"
@ -290,15 +285,11 @@ msgstr ""
msgid "Allow <abbr title=\"Secure Shell\">SSH</abbr> password authentication"
msgstr ""
"Permetre l'autenticació <abbr title=\"Secure Shell\">SSH</abbr> amb "
"contrasenya"
"Permet autenticació <abbr title=\"Secure Shell\">SSH</abbr> per contrasenya"
msgid "Allow all except listed"
msgstr "Permet-les totes menys les llistades"
msgid "Allow legacy 802.11b rates"
msgstr ""
msgid "Allow listed only"
msgstr "Permet només les llistades"
@ -307,14 +298,13 @@ msgstr "Permetre el localhost"
msgid "Allow remote hosts to connect to local SSH forwarded ports"
msgstr ""
"Permetre a màquines remotes de connectar-se als ports reenviats de l'SSH "
"local"
"Permetre a màquines remotes de connectar als ports reenviats de l'SSH local"
msgid "Allow root logins with password"
msgstr "Accés d'administrador amb contrasenya"
msgstr "Permetre l'accés del l'administrador amb paraula clau"
msgid "Allow the <em>root</em> user to login with password"
msgstr "Permetre l'accés de l'usurari <em>root</em> amb contrasenya"
msgstr "Permetre l'accés de l'usurari <em>root</em> amb paraula clau"
msgid ""
"Allow upstream responses in the 127.0.0.0/8 range, e.g. for RBL services"
@ -503,10 +493,10 @@ msgid "Back to scan results"
msgstr "Enrere als resultats de l'escaneig"
msgid "Backup / Flash Firmware"
msgstr "Còpia de seguretat i microprogramari"
msgstr "Còpia de seguretat / Recàrrega de programari"
msgid "Backup / Restore"
msgstr "Còpia de seguretat i restauració de la configuració"
msgstr "Còpia de seguretat / Restauració"
msgid "Backup file list"
msgstr "Llista de còpies de seguretat"
@ -569,8 +559,9 @@ msgid ""
"Build/distribution specific feed definitions. This file will NOT be "
"preserved in any sysupgrade."
msgstr ""
"Repositoris específics de la distribució/compilació. Aquest fitxer NO es "
"preservarà durant les actualitzacions del microprogramari del sistema."
msgid "Buttons"
msgstr "Botons"
msgid "CA certificate; if empty it will be saved after the first connection."
msgstr ""
@ -602,7 +593,7 @@ msgstr "Canal"
msgid "Check"
msgstr "Comprovació"
msgid "Check filesystems before mount"
msgid "Check fileystems before mount"
msgstr ""
msgid "Check this option to delete the existing networks from this radio."
@ -640,10 +631,6 @@ msgid ""
"configuration files. To reset the firmware to its initial state, click "
"\"Perform reset\" (only possible with squashfs images)."
msgstr ""
"Fes clic a \"Genera l'arxiu\" per obtenir un fitxer .tar.gz amb els fitxers "
"de configuració actuals. Per restablir el microprogramari al seu estat "
"inicial, fes clic a \"Restableix la configuració\" (només funciona amb "
"imatges squashfs)."
msgid "Client"
msgstr "Client"
@ -668,13 +655,6 @@ msgstr "Ordre"
msgid "Common Configuration"
msgstr "Configuració comuna"
msgid ""
"Complicates key reinstallation attacks on the client side by disabling "
"retransmission of EAPOL-Key frames that are used to install keys. This "
"workaround might cause interoperability issues and reduced robustness of key "
"negotiation especially in environments with heavy traffic load."
msgstr ""
msgid "Configuration"
msgstr "Configuració"
@ -743,17 +723,12 @@ msgstr ""
msgid "Custom feeds"
msgstr ""
msgid ""
"Custom files (certificates, scripts) may remain on the system. To prevent "
"this, perform a factory-reset first."
msgstr ""
msgid ""
"Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
"\">LED</abbr>s if possible."
msgstr ""
"Personalitza el comportament dels <abbr title=\"Light Emitting Diode\">LED</"
"abbr>s del dispositiu, si és possible."
"abbr>s del dispositiu si és possible."
msgid "DHCP Leases"
msgstr "Arrendaments DHCP"
@ -916,7 +891,7 @@ msgid "Distance to farthest network member in meters."
msgstr "Distància al membre de la xarxa més allunyat en metres."
msgid "Distribution feeds"
msgstr "Repositoris de la distribució"
msgstr ""
msgid "Diversity"
msgstr "Diversitat"
@ -961,10 +936,7 @@ msgid "Download and install package"
msgstr "Descarrega i instal·la el paquet"
msgid "Download backup"
msgstr "Descarrega còpia de seguretat"
msgid "Downstream SNR offset"
msgstr ""
msgstr "Descarrega còpia de seguritat"
msgid "Dropbear Instance"
msgstr "Instància de Dropbear"
@ -973,8 +945,8 @@ msgid ""
"Dropbear offers <abbr title=\"Secure Shell\">SSH</abbr> network shell access "
"and an integrated <abbr title=\"Secure Copy\">SCP</abbr> server"
msgstr ""
"El Dropbear ofereix accés a una consola <abbr title=\"Secure Shell\">SSH</"
"abbr> per xarxa i un servidor <abbr title=\"Secure Copy\">SCP</abbr> integrat"
"El Dropbear ofereix accés per la xarxa a consola <abbr title=\"Secure Shell"
"\">SSH</abbr>i un servidor <abbr title=\"Secure Copy\">SCP</abbr> integrat"
msgid "Dual-Stack Lite (RFC6333)"
msgstr ""
@ -1017,11 +989,6 @@ msgstr "Emergència"
msgid "Enable"
msgstr "Habilita"
msgid ""
"Enable <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> "
"snooping"
msgstr ""
msgid "Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
msgstr "Habilita l'<abbr title=\"Spanning Tree Protocol\">STP</abbr>"
@ -1052,9 +1019,6 @@ msgstr "Habilita la funcionalitat VLAN"
msgid "Enable WPS pushbutton, requires WPA(2)-PSK"
msgstr ""
msgid "Enable key reinstallation (KRACK) countermeasures"
msgstr ""
msgid "Enable learning and aging"
msgstr "Habilita l'aprenentatge i l'envelliment"
@ -1079,9 +1043,6 @@ msgstr "Activa/Desactiva"
msgid "Enabled"
msgstr "Habilitat"
msgid "Enables IGMP snooping on this bridge"
msgstr ""
msgid ""
"Enables fast roaming among access points that belong to the same Mobility "
"Domain"
@ -1140,26 +1101,17 @@ msgid "External R1 Key Holder List"
msgstr ""
msgid "External system log server"
msgstr "Servidor de registre del sistema extern"
msgstr ""
msgid "External system log server port"
msgstr "Port del servidor de registre del sistema extern"
msgstr ""
msgid "External system log server protocol"
msgstr "Protocol del servidor de registre del sistema extern"
msgstr ""
msgid "Extra SSH command options"
msgstr ""
msgid "FT over DS"
msgstr ""
msgid "FT over the Air"
msgstr ""
msgid "FT protocol"
msgstr ""
msgid "File"
msgstr "Fitxer"
@ -1214,19 +1166,19 @@ msgid "Fixed source port for outbound DNS queries"
msgstr ""
msgid "Flash Firmware"
msgstr "Escriptura del microprogramari a la memòria flaix"
msgstr "Reescriu el microprogramari"
msgid "Flash image..."
msgstr "Puja una imatge..."
msgstr "Escriu una imatge..."
msgid "Flash new firmware image"
msgstr "Escriu una imatge nova a la memòria flaix"
msgstr "Escriu una imatge nova"
msgid "Flash operations"
msgstr "Operacions a la memòria flaix"
msgstr "Operacions d'escriptura"
msgid "Flashing..."
msgstr "Escrivint a la memòria flaix..."
msgstr "Escrivent..."
msgid "Force"
msgstr "Força"
@ -1253,16 +1205,13 @@ msgid "Form token mismatch"
msgstr ""
msgid "Forward DHCP traffic"
msgstr "Reenvia el trànsit DHCP"
msgstr "Reenvia el tràfic DHCP"
msgid "Forward Error Correction Seconds (FECS)"
msgstr ""
msgid "Forward broadcast traffic"
msgstr "Reenvia el trànsit difós"
msgid "Forward mesh peer traffic"
msgstr ""
msgstr "Reenvia el tràfic difós"
msgid "Forwarding mode"
msgstr "Mode de reenviament"
@ -1274,7 +1223,7 @@ msgid "Frame Bursting"
msgstr ""
msgid "Free"
msgstr "Lliure"
msgstr "Lliures"
msgid "Free space"
msgstr "Espai lliure"
@ -1303,19 +1252,16 @@ msgid "General Setup"
msgstr ""
msgid "General options for opkg"
msgstr "Opcions generals d'opkg"
msgstr ""
msgid "Generate Config"
msgstr ""
msgid "Generate PMK locally"
msgid "Generate archive"
msgstr ""
msgid "Generate archive"
msgstr "Genera l'arxiu"
msgid "Generic 802.11%s Wireless Controller"
msgstr "Controlador sense fils 802.11%s genèric"
msgstr "Controlador sense fil 802.11%s genèric"
msgid "Given password confirmation did not match, password not changed!"
msgstr ""
@ -1349,6 +1295,9 @@ msgstr ""
msgid "HT mode (802.11n)"
msgstr ""
msgid "Handler"
msgstr ""
msgid "Hang Up"
msgstr "Penja"
@ -1369,8 +1318,6 @@ msgid ""
"Here you can paste public SSH-Keys (one per line) for SSH public-key "
"authentication."
msgstr ""
"Aquí pots afegir-hi les claus SSH públiques (una per línia) per entrar per "
"SSH amb autenticació per clau."
msgid "Hermes 802.11b Wireless Controller"
msgstr "Controlador sense fil Hermes 802.11b"
@ -1380,7 +1327,7 @@ msgstr ""
"No mostris l'<abbr title=\"Extended Service Set Identifier\">ESSID</abbr>"
msgid "Host"
msgstr "Nom de màquina"
msgstr ""
msgid "Host entries"
msgstr "Entrades de noms de màquina"
@ -1449,7 +1396,7 @@ msgid "IPv4 prefix length"
msgstr "Longitud de prefix IPv4"
msgid "IPv4-Address"
msgstr "Adreça IPv4"
msgstr "Adreça IPv6"
msgid "IPv4-in-IPv4 (RFC2003)"
msgstr ""
@ -1461,7 +1408,7 @@ msgid "IPv6 Firewall"
msgstr "Tallafocs IPv6"
msgid "IPv6 Neighbours"
msgstr "Veïns IPv6"
msgstr ""
msgid "IPv6 Settings"
msgstr ""
@ -1470,7 +1417,7 @@ msgid "IPv6 ULA-Prefix"
msgstr ""
msgid "IPv6 WAN Status"
msgstr "Estat WAN IPv6"
msgstr "Estado WAN IPv6"
msgid "IPv6 address"
msgstr "Adreça IPv6"
@ -1520,7 +1467,7 @@ msgstr "IPv6-sobre-IPv4 (6to4)"
msgid "Identity"
msgstr "Identitat"
msgid "If checked, 1DES is enabled"
msgid "If checked, 1DES is enaled"
msgstr ""
msgid "If checked, encryption is disabled"
@ -1565,10 +1512,10 @@ msgid "Ignore resolve file"
msgstr "Ignora el fitxer de resolució"
msgid "Image"
msgstr "Fitxer d'imatge"
msgstr "Imatge"
msgid "In"
msgstr "Entr."
msgstr "En"
msgid ""
"In order to prevent unauthorized access to the system, your request has been "
@ -1680,7 +1627,7 @@ msgid "Joining Network: %q"
msgstr ""
msgid "Keep settings"
msgstr "Mantenir la configuració"
msgstr ""
msgid "Kernel Log"
msgstr "Registre del nucli"
@ -1737,7 +1684,7 @@ msgid "Leasefile"
msgstr "Fitxer d'arrendament"
msgid "Leasetime remaining"
msgstr "Temps d'arrendament restant"
msgstr "Duració d'arrendament restant"
msgid "Leave empty to autodetect"
msgstr "Deixeu-ho en blanc per autodetectar"
@ -1770,7 +1717,7 @@ msgid "Line Uptime"
msgstr ""
msgid "Link On"
msgstr "Enllaç actiu"
msgstr "Enllaç activa"
msgid ""
"List of <abbr title=\"Domain Name System\">DNS</abbr> servers to forward "
@ -1810,17 +1757,15 @@ msgstr ""
msgid "Listen only on the given interface or, if unspecified, on all"
msgstr ""
"Habilita el servei en totes les interfícies o, si no se n'especifica cap, en "
"totes"
msgid "Listening port for inbound DNS queries"
msgstr ""
msgid "Load"
msgstr "Càrrega"
msgstr "Carrega"
msgid "Load Average"
msgstr "Càrrega mitjana"
msgstr "Carrega mitjana"
msgid "Loading"
msgstr "Carregant"
@ -1939,6 +1884,9 @@ msgstr ""
msgid "Maximum amount of seconds to wait for the modem to become ready"
msgstr ""
msgid "Maximum hold time"
msgstr ""
msgid ""
"Maximum length of the name is 15 characters including the automatic protocol/"
"bridge prefix (br-, 6in4-, pppoe- etc.)"
@ -1956,11 +1904,11 @@ msgstr "Memòria"
msgid "Memory usage (%)"
msgstr "Ús de Memòria (%)"
msgid "Mesh Id"
msgstr ""
msgid "Metric"
msgstr "Mètrica"
msgstr "Mètric"
msgid "Minimum hold time"
msgstr ""
msgid "Mirror monitor port"
msgstr ""
@ -2096,13 +2044,13 @@ msgid "No NAT-T"
msgstr ""
msgid "No chains in this table"
msgstr "No hi ha cadenes en aquesta taula"
msgstr "No hi ha cadenes a aquesta taula"
msgid "No files found"
msgstr "Cap fitxer trobat"
msgid "No information available"
msgstr "No hi ha informació disponible"
msgstr "Cap informació disponible"
msgid "No negative cache"
msgstr "Sense memòria cau negativa"
@ -2117,7 +2065,7 @@ msgid "No package lists available"
msgstr "No hi ha llistes de paquets disponibles"
msgid "No password set!"
msgstr "No hi ha cap contrasenya establerta!"
msgstr "Cap contrasenya establerta!"
msgid "No rules in this chain"
msgstr "No hi ha regles en aquesta cadena"
@ -2167,9 +2115,6 @@ msgstr "Avís"
msgid "Nslookup"
msgstr "Nslookup"
msgid "Number of cached DNS entries (max is 10000, 0 is no caching)"
msgstr ""
msgid "OK"
msgstr "D'acord"
@ -2285,7 +2230,7 @@ msgid "Other:"
msgstr "Altres:"
msgid "Out"
msgstr "Sort."
msgstr ""
msgid "Outbound:"
msgstr "Sortint:"
@ -2409,6 +2354,9 @@ msgstr ""
msgid "Path to Private Key"
msgstr "Ruta a la clau privada"
msgid "Path to executable which handles the button event"
msgstr ""
msgid "Path to inner CA-Certificate"
msgstr ""
@ -2499,7 +2447,7 @@ msgid "Private Key"
msgstr ""
msgid "Proceed"
msgstr "Procedeix"
msgstr "continua"
msgid "Processes"
msgstr "Processos"
@ -2523,7 +2471,7 @@ msgid "Protocol support is not installed"
msgstr ""
msgid "Provide NTP server"
msgstr "Habilita el servidor NTP"
msgstr ""
msgid "Provide new network"
msgstr ""
@ -2616,19 +2564,19 @@ msgid "Really switch protocol?"
msgstr ""
msgid "Realtime Connections"
msgstr "Connexions en temps real"
msgstr ""
msgid "Realtime Graphs"
msgstr "Gràfiques en temps real"
msgstr ""
msgid "Realtime Load"
msgstr "Càrrega en temps real"
msgstr ""
msgid "Realtime Traffic"
msgstr "Trànsit en temps real"
msgstr ""
msgid "Realtime Wireless"
msgstr "Dispositiu sense fils en temps real"
msgstr ""
msgid "Reassociation Deadline"
msgstr ""
@ -2646,7 +2594,7 @@ msgid "Reboots the operating system of your device"
msgstr "Arranca de nou el sistema operatiu del teu dispositiu"
msgid "Receive"
msgstr "Recepció"
msgstr "Rep"
msgid "Receiver Antenna"
msgstr "Antena receptora"
@ -2676,10 +2624,10 @@ msgid "Relay bridge"
msgstr "Pont de relé"
msgid "Remote IPv4 address"
msgstr "Adreça IPv4 remota"
msgstr "Adreça IPv6 remota"
msgid "Remote IPv4 address or FQDN"
msgstr "Adreça IPv4 remota o FQDN"
msgstr ""
msgid "Remove"
msgstr "Treu"
@ -2731,7 +2679,7 @@ msgid ""
msgstr ""
msgid "Reset"
msgstr "Restableix"
msgstr "Reinicia"
msgid "Reset Counters"
msgstr "Reinicia els comptadors"
@ -2749,7 +2697,7 @@ msgid "Restart"
msgstr "Reinicia"
msgid "Restart Firewall"
msgstr "Reinicia el tallafocs"
msgstr "Reinicia Tallafocs"
msgid "Restore backup"
msgstr "Restaura còpia de seguretat"
@ -2836,10 +2784,10 @@ msgid "Save"
msgstr "Desa"
msgid "Save & Apply"
msgstr "Desa i aplica"
msgstr "Desa y aplica"
msgid "Save &#38; Apply"
msgstr "Desa i aplica"
msgstr "Desa y aplica"
msgid "Scan"
msgstr "Escaneja"
@ -2894,7 +2842,7 @@ msgstr ""
#, fuzzy
msgid "Set up Time Synchronization"
msgstr "Configura la sincronització de l'hora"
msgstr "Sincronització de hora"
msgid "Setup DHCP Server"
msgstr ""
@ -2927,9 +2875,6 @@ msgid "Size"
msgstr "Mida"
msgid "Size (.ipk)"
msgstr "Mida (.ipk)"
msgid "Size of DNS query cache"
msgstr ""
msgid "Skip"
@ -2974,6 +2919,9 @@ msgstr "Origen"
msgid "Source routing"
msgstr ""
msgid "Specifies the button state to handle"
msgstr ""
msgid "Specifies the directory the device is attached to"
msgstr "Especifica el directori a que el dispositiu està adjuntat"
@ -3013,7 +2961,7 @@ msgid "Start priority"
msgstr "Prioritat d'inici"
msgid "Startup"
msgstr "Arrencada"
msgstr "Arranca"
msgid "Static IPv4 Routes"
msgstr "Rutes IPv4 estàtiques"
@ -3073,9 +3021,6 @@ msgid ""
"Switch %q has an unknown topology - the VLAN settings might not be accurate."
msgstr ""
msgid "Switch Port Mask"
msgstr ""
msgid "Switch VLAN"
msgstr ""
@ -3083,7 +3028,7 @@ msgid "Switch protocol"
msgstr "Protocol de commutador"
msgid "Sync with browser"
msgstr "Sincronitza amb el navegador"
msgstr "Sincronitza amb navegador"
msgid "Synchronizing..."
msgstr "Sincronitzant..."
@ -3092,13 +3037,13 @@ msgid "System"
msgstr "Sistema"
msgid "System Log"
msgstr "Registre del sistema"
msgstr "Registre de sistema"
msgid "System Properties"
msgstr "Propietats del sistema"
msgstr "Propietats de sistema"
msgid "System log buffer size"
msgstr "Mida de la memòria intermèdia per al registre del sistema"
msgstr "Mida de la memòria intermèdia del registre de sistema"
msgid "TCP:"
msgstr "TCP:"
@ -3186,10 +3131,6 @@ msgid ""
"compare them with the original file to ensure data integrity.<br /> Click "
"\"Proceed\" below to start the flash procedure."
msgstr ""
"S'ha pujat la imatge per a la memòria flaix. A sota hi ha llistades la suma "
"de verificació i la mida del fitxer per assegurar la integritat de les dades."
"<br />Fes clic a \"Procedeix\" a continuació per començar el procés "
"d'escriptura a la memòria flaix."
msgid "The following changes have been committed"
msgstr "S'han comès els següents canvis"
@ -3198,7 +3139,7 @@ msgid "The following changes have been reverted"
msgstr "S&#39;han desfet els següents canvis"
msgid "The following rules are currently active on this system."
msgstr "Les següents regles estan actualment actives en aquest sistema."
msgstr "Els següents regles estan actualment actives en aquest sistema."
msgid "The given network name is not unique"
msgstr "El nom de xarxa donat no és únic"
@ -3252,11 +3193,10 @@ msgid ""
"address of your computer to reach the device again, depending on your "
"settings."
msgstr ""
"S'està escrivint la imatge del microprogramari a la memòria flaix.<br />NO "
"APAGUIS EL DISPOSITIU!<br />Espera uns minuts abans d'intentar connectar-te "
"de nou. Pot ser necessari que renovis l'adreça DHCP del teu ordinador per "
"connectar-te de nou a l'encaminador, depenent de la configuració que hi "
"tinguis."
"El sistema s'està escrivent ara.<br />NO APAGUEU EL DISPOSITIU!<br />Espereu "
"uns minuts abans d'intentar connectar-vos de nou. Pot ser necessari que "
"renoveu l'adreça del vostre ordinador per a connectar al dispositiu de nou, "
"depenent dels vostres ajusts."
msgid ""
"The tunnel end-point is behind NAT, defaults to disabled and only applies to "
@ -3291,8 +3231,6 @@ msgid ""
"There is no password set on this router. Please configure a root password to "
"protect the web interface and enable SSH."
msgstr ""
"No s'ha establert cap contrasenya en aquest encaminador. Si us plau, "
"configura una contrasenya per protegir la interfície web i l'accés SSH."
msgid "This IPv4 address of the relay"
msgstr ""
@ -3318,13 +3256,10 @@ msgid ""
"This is the content of /etc/rc.local. Insert your own commands here (in "
"front of 'exit 0') to execute them at the end of the boot process."
msgstr ""
"Aquest és el contingut de /etc/rc.local. Afegeix-hi les teves comandes "
"(abans de la línia 'exit 0') per executar-les en finalitzar el procés "
"d'arrencada."
msgid ""
"This is the local endpoint address assigned by the tunnel broker, it usually "
"ends with <code>...:2/64</code>"
"ends with <code>:2</code>"
msgstr ""
msgid ""
@ -3357,16 +3292,19 @@ msgstr ""
"Aquesta llista mostra una vista general sobre els processos corrent al "
"sistema actualment i el seu estat."
msgid "This page allows the configuration of custom button actions"
msgstr ""
msgid "This page gives an overview over currently active network connections."
msgstr ""
"Aquesta pàgina ofereix una vista general de les connexions de xarxa actives "
"actualment."
msgid "This section contains no values yet"
msgstr "Aquesta secció encara no conté cap valor"
msgstr "Aquesta secció no conté cap valor encara"
msgid "Time Synchronization"
msgstr "Sincronització de l'hora"
msgstr "Sincronització de hora"
msgid "Time Synchronization is not configured yet."
msgstr "La sincronització de hora encara no s'ha configurat."
@ -3378,8 +3316,6 @@ msgid ""
"To restore configuration files, you can upload a previously generated backup "
"archive here."
msgstr ""
"Per restaurar els fitxers de configuració, pots pujar una còpia de seguretat "
"generada anteriorment aquí."
msgid "Tone"
msgstr ""
@ -3391,7 +3327,7 @@ msgid "Traceroute"
msgstr "Rastre de ruta"
msgid "Traffic"
msgstr "Trànsit"
msgstr "Tràfic"
msgid "Transfer"
msgstr "Transferència"
@ -3400,7 +3336,7 @@ msgid "Transmission Rate"
msgstr "Taxa de transmissió"
msgid "Transmit"
msgstr "Transmissió"
msgstr "Transmet"
msgid "Transmit Power"
msgstr "Potència de transmissió"
@ -3409,10 +3345,10 @@ msgid "Transmitter Antenna"
msgstr "Antena transmissora"
msgid "Trigger"
msgstr "Activador"
msgstr ""
msgid "Trigger Mode"
msgstr "Mode d'activació"
msgstr ""
msgid "Tunnel ID"
msgstr "ID del túnel"
@ -3488,9 +3424,6 @@ msgid ""
"Check \"Keep settings\" to retain the current configuration (requires a "
"compatible firmware image)."
msgstr ""
"Puja aquí una imatge compatible amb sysupgrade per reemplaçar el "
"microprogramari actual. Activa \"Mantenir la configuració\" per retenir la "
"configuració actual (requereix una imatge de microprogramari compatible)."
msgid "Upload archive..."
msgstr "Puja un arxiu..."
@ -3499,7 +3432,7 @@ msgid "Uploaded File"
msgstr "Fitxer pujat"
msgid "Uptime"
msgstr "Temps en marxa"
msgstr "Temps d'alta"
msgid "Use <code>/etc/ethers</code>"
msgstr "Fes servir <code>/etc/ethers</code>"
@ -3545,9 +3478,9 @@ msgstr ""
msgid ""
"Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</"
"em> identifies the host, the <em>IPv4-Address</em> specifies the fixed "
"address to use, and the <em>Hostname</em> is assigned as a symbolic name to "
"the requesting host. The optional <em>Lease time</em> can be used to set non-"
"em> indentifies the host, the <em>IPv4-Address</em> specifies to the fixed "
"address to use and the <em>Hostname</em> is assigned as symbolic name to the "
"requesting host. The optional <em>Lease time</em> can be used to set non-"
"standard host-specific lease time, e.g. 12h, 3d or infinite."
msgstr ""
@ -3655,7 +3588,7 @@ msgid "Waiting for command to complete..."
msgstr "Esperant que s'acabi l'ordre..."
msgid "Waiting for device..."
msgstr "Esperant el dispositiu..."
msgstr ""
msgid "Warning"
msgstr "Advertència"
@ -3663,11 +3596,6 @@ msgstr "Advertència"
msgid "Warning: There are unsaved changes that will get lost on reboot!"
msgstr ""
msgid ""
"When using a PSK, the PMK can be generated locally without inter AP "
"communications"
msgstr ""
msgid "Whether to create an IPv6 default route over the tunnel"
msgstr ""
@ -3696,10 +3624,10 @@ msgid "Wireless Security"
msgstr "Seguretat sense fils"
msgid "Wireless is disabled or not associated"
msgstr "El dispositiu sense fils està inhabilitat o sense associar"
msgstr "El sense fil està inhabilitat o sense associar"
msgid "Wireless is restarting..."
msgstr "El dispositiu sense fils està reiniciant..."
msgstr "Sense fils està reiniciant..."
msgid "Wireless network is disabled"
msgstr "La xarxa sense fil està inhabilitada"
@ -3714,10 +3642,10 @@ msgid "Wireless shut down"
msgstr "Sense fils aturat"
msgid "Write received DNS requests to syslog"
msgstr "Escriure les peticions DNS rebudes al registre del sistema"
msgstr "Escriure les peticions DNS rebudes al syslog"
msgid "Write system log to file"
msgstr "Escriure el registre del sistema al fitxer"
msgstr ""
msgid ""
"You can enable or disable installed init scripts here. Changes will applied "
@ -3847,9 +3775,6 @@ msgstr "obert"
msgid "overlay"
msgstr ""
msgid "random"
msgstr ""
msgid "relay mode"
msgstr ""
@ -3895,12 +3820,6 @@ msgstr "sí"
msgid "« Back"
msgstr "« Enrere"
#~ msgid "Action"
#~ msgstr "Acció"
#~ msgid "Buttons"
#~ msgstr "Botons"
#~ msgid "Leasetime"
#~ msgstr "Duració d'arrendament"

View File

@ -11,9 +11,6 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Pootle 2.0.6\n"
msgid "%.1f dB"
msgstr ""
msgid "%s is untagged in multiple VLANs!"
msgstr ""
@ -132,9 +129,6 @@ msgstr "<abbr title=\"Light Emitting Diode\">LED</abbr> Název"
msgid "<abbr title=\"Media Access Control\">MAC</abbr>-Address"
msgstr "<abbr title=\"Media Access Control\">MAC</abbr>-Adresa"
msgid "<abbr title=\"The DHCP Unique Identifier\">DUID</abbr>"
msgstr ""
msgid ""
"<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Dynamic Host Configuration "
"Protocol\">DHCP</abbr> leases"
@ -217,6 +211,9 @@ msgstr "Přístupový koncentrátor"
msgid "Access Point"
msgstr "Přístupový bod"
msgid "Action"
msgstr "Akce"
msgid "Actions"
msgstr "Akce"
@ -292,9 +289,6 @@ msgstr "Povolit <abbr title=\"Secure Shell\">SSH</abbr> autentizaci heslem"
msgid "Allow all except listed"
msgstr "Povolit vše mimo uvedené"
msgid "Allow legacy 802.11b rates"
msgstr ""
msgid "Allow listed only"
msgstr "Povolit pouze uvedené"
@ -565,6 +559,9 @@ msgid ""
"preserved in any sysupgrade."
msgstr ""
msgid "Buttons"
msgstr "Tlačítka"
msgid "CA certificate; if empty it will be saved after the first connection."
msgstr ""
@ -595,7 +592,7 @@ msgstr "Kanál"
msgid "Check"
msgstr "Kontrola"
msgid "Check filesystems before mount"
msgid "Check fileystems before mount"
msgstr ""
msgid "Check this option to delete the existing networks from this radio."
@ -662,13 +659,6 @@ msgstr "Příkaz"
msgid "Common Configuration"
msgstr "Společná nastavení"
msgid ""
"Complicates key reinstallation attacks on the client side by disabling "
"retransmission of EAPOL-Key frames that are used to install keys. This "
"workaround might cause interoperability issues and reduced robustness of key "
"negotiation especially in environments with heavy traffic load."
msgstr ""
msgid "Configuration"
msgstr "Nastavení"
@ -737,11 +727,6 @@ msgstr ""
msgid "Custom feeds"
msgstr ""
msgid ""
"Custom files (certificates, scripts) may remain on the system. To prevent "
"this, perform a factory-reset first."
msgstr ""
msgid ""
"Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
"\">LED</abbr>s if possible."
@ -961,9 +946,6 @@ msgstr "Stáhnout a nainstalovat balíček"
msgid "Download backup"
msgstr "Stáhnout zálohu"
msgid "Downstream SNR offset"
msgstr ""
msgid "Dropbear Instance"
msgstr "Instance Dropbear"
@ -1017,11 +999,6 @@ msgstr "Záchrana"
msgid "Enable"
msgstr "Povolit"
msgid ""
"Enable <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> "
"snooping"
msgstr ""
msgid "Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
msgstr "Povolit <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
@ -1052,9 +1029,6 @@ msgstr "Povolit funkcionalitu VLAN"
msgid "Enable WPS pushbutton, requires WPA(2)-PSK"
msgstr ""
msgid "Enable key reinstallation (KRACK) countermeasures"
msgstr ""
msgid "Enable learning and aging"
msgstr "Povolit ARP učení a stárnutí"
@ -1079,9 +1053,6 @@ msgstr "Povolit/Zakázat"
msgid "Enabled"
msgstr "Povoleno"
msgid "Enables IGMP snooping on this bridge"
msgstr ""
msgid ""
"Enables fast roaming among access points that belong to the same Mobility "
"Domain"
@ -1153,15 +1124,6 @@ msgstr ""
msgid "Extra SSH command options"
msgstr ""
msgid "FT over DS"
msgstr ""
msgid "FT over the Air"
msgstr ""
msgid "FT protocol"
msgstr ""
msgid "File"
msgstr "Soubor"
@ -1263,9 +1225,6 @@ msgstr ""
msgid "Forward broadcast traffic"
msgstr "Přeposílat broadcasty"
msgid "Forward mesh peer traffic"
msgstr ""
msgid "Forwarding mode"
msgstr "Režim přeposílání"
@ -1310,9 +1269,6 @@ msgstr ""
msgid "Generate Config"
msgstr ""
msgid "Generate PMK locally"
msgstr ""
msgid "Generate archive"
msgstr "Vytvorǐt archív"
@ -1349,6 +1305,9 @@ msgstr ""
msgid "HT mode (802.11n)"
msgstr ""
msgid "Handler"
msgstr "Handler"
msgid "Hang Up"
msgstr "Zavěsit"
@ -1519,7 +1478,7 @@ msgstr "IPv6-over-IPv4 (6to4)"
msgid "Identity"
msgstr "Identita"
msgid "If checked, 1DES is enabled"
msgid "If checked, 1DES is enaled"
msgstr ""
msgid "If checked, encryption is disabled"
@ -1947,6 +1906,9 @@ msgstr "Nejvyšší povolená velikost EDNS.0 UDP paketů"
msgid "Maximum amount of seconds to wait for the modem to become ready"
msgstr "Nejvyšší počet sekund čekání, než bude modem připraven"
msgid "Maximum hold time"
msgstr "Maximální doba držení"
msgid ""
"Maximum length of the name is 15 characters including the automatic protocol/"
"bridge prefix (br-, 6in4-, pppoe- etc.)"
@ -1964,12 +1926,12 @@ msgstr "Paměť"
msgid "Memory usage (%)"
msgstr "Využití paměti (%)"
msgid "Mesh Id"
msgstr ""
msgid "Metric"
msgstr "Metrika"
msgid "Minimum hold time"
msgstr "Minimální čas zápůjčky"
msgid "Mirror monitor port"
msgstr ""
@ -2175,9 +2137,6 @@ msgstr "Oznámení"
msgid "Nslookup"
msgstr "Nslookup"
msgid "Number of cached DNS entries (max is 10000, 0 is no caching)"
msgstr ""
msgid "OK"
msgstr "OK"
@ -2418,6 +2377,9 @@ msgstr "Cesta k certifikátu klienta"
msgid "Path to Private Key"
msgstr "Cesta k privátnímu klíči"
msgid "Path to executable which handles the button event"
msgstr "Cesta ke spustitelnému souboru, který obsluhuje událost tlačítka"
msgid "Path to inner CA-Certificate"
msgstr ""
@ -2955,9 +2917,6 @@ msgstr "Velikost"
msgid "Size (.ipk)"
msgstr ""
msgid "Size of DNS query cache"
msgstr ""
msgid "Skip"
msgstr "Přeskočit"
@ -3003,6 +2962,9 @@ msgstr "Zdroj"
msgid "Source routing"
msgstr ""
msgid "Specifies the button state to handle"
msgstr ""
msgid "Specifies the directory the device is attached to"
msgstr ""
@ -3107,9 +3069,6 @@ msgid ""
"Switch %q has an unknown topology - the VLAN settings might not be accurate."
msgstr ""
msgid "Switch Port Mask"
msgstr ""
msgid "Switch VLAN"
msgstr ""
@ -3366,7 +3325,7 @@ msgstr ""
msgid ""
"This is the local endpoint address assigned by the tunnel broker, it usually "
"ends with <code>...:2/64</code>"
"ends with <code>:2</code>"
msgstr ""
msgid ""
@ -3399,6 +3358,9 @@ msgstr ""
"V tomto seznamu vidíte přehled aktuálně běžících systémových procesů a "
"jejich stavy."
msgid "This page allows the configuration of custom button actions"
msgstr "Na této stránce si můžete nastavit vlastní události tlačítek"
msgid "This page gives an overview over currently active network connections."
msgstr "Tato stránka zobrazuje přehled aktivních síťových spojení."
@ -3585,9 +3547,9 @@ msgstr "Použít směrovací tabulku"
msgid ""
"Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</"
"em> identifies the host, the <em>IPv4-Address</em> specifies the fixed "
"address to use, and the <em>Hostname</em> is assigned as a symbolic name to "
"the requesting host. The optional <em>Lease time</em> can be used to set non-"
"em> indentifies the host, the <em>IPv4-Address</em> specifies to the fixed "
"address to use and the <em>Hostname</em> is assigned as symbolic name to the "
"requesting host. The optional <em>Lease time</em> can be used to set non-"
"standard host-specific lease time, e.g. 12h, 3d or infinite."
msgstr ""
"Použitím tlačítka <em>Přidat</em> přidáte novou zápůjčku (lease). <em>MAC "
@ -3706,11 +3668,6 @@ msgstr "Varování"
msgid "Warning: There are unsaved changes that will get lost on reboot!"
msgstr ""
msgid ""
"When using a PSK, the PMK can be generated locally without inter AP "
"communications"
msgstr ""
msgid "Whether to create an IPv6 default route over the tunnel"
msgstr ""
@ -3888,9 +3845,6 @@ msgstr ""
msgid "overlay"
msgstr ""
msgid "random"
msgstr ""
msgid "relay mode"
msgstr ""
@ -3936,27 +3890,6 @@ msgstr "ano"
msgid "« Back"
msgstr "« Zpět"
#~ msgid "Action"
#~ msgstr "Akce"
#~ msgid "Buttons"
#~ msgstr "Tlačítka"
#~ msgid "Handler"
#~ msgstr "Handler"
#~ msgid "Maximum hold time"
#~ msgstr "Maximální doba držení"
#~ msgid "Minimum hold time"
#~ msgstr "Minimální čas zápůjčky"
#~ msgid "Path to executable which handles the button event"
#~ msgstr "Cesta ke spustitelnému souboru, který obsluhuje událost tlačítka"
#~ msgid "This page allows the configuration of custom button actions"
#~ msgstr "Na této stránce si můžete nastavit vlastní události tlačítek"
#~ msgid "Leasetime"
#~ msgstr "Doba trvání zápůjčky"

View File

@ -1,23 +1,20 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-05-26 17:57+0200\n"
"PO-Revision-Date: 2018-01-09 08:01+0100\n"
"PO-Revision-Date: 2017-03-06 11:15+0200\n"
"Last-Translator: JoeSemler <josef.semler@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 1.8.11\n"
"Language-Team: \n"
msgid "%.1f dB"
msgstr ""
"X-Generator: Pootle 2.0.6\n"
msgid "%s is untagged in multiple VLANs!"
msgstr "%s darf nicht ohne VLAN-Tag in mehreren VLAN-Gruppen vorkommen!"
msgstr ""
msgid "(%d minute window, %d second interval)"
msgstr "(%d Minuten Abschnitt, %d Sekunden Intervall)"
@ -68,7 +65,7 @@ msgid "6-octet identifier as a hex string - no colons"
msgstr "sechstellige hexadezimale ID (ohne Doppelpunkte)"
msgid "802.11r Fast Transition"
msgstr "802.11r: Schnelle Client-Übergabe"
msgstr ""
msgid "802.11w Association SA Query maximum timeout"
msgstr "Maximales Timeout für Quelladressprüfungen (SA Query)"
@ -133,9 +130,6 @@ msgstr "<abbr title=\"Light Emitting Diode\">LED</abbr> Name"
msgid "<abbr title=\"Media Access Control\">MAC</abbr>-Address"
msgstr "MAC-Adresse"
msgid "<abbr title=\"The DHCP Unique Identifier\">DUID</abbr>"
msgstr ""
msgid ""
"<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Dynamic Host Configuration "
"Protocol\">DHCP</abbr> leases"
@ -160,8 +154,6 @@ msgid ""
"<br/>Note: you need to manually restart the cron service if the crontab file "
"was empty before editing."
msgstr ""
"<br/>Hinweis: Der Cron-Dienst muss manuell neu gestartet werden wenn die "
"Crontab-Datei vor der Bearbeitung leer war."
msgid "A43C + J43 + A43"
msgstr ""
@ -220,6 +212,9 @@ msgstr "Access Concentrator"
msgid "Access Point"
msgstr "Access Point"
msgid "Action"
msgstr "Aktion"
msgid "Actions"
msgstr "Aktionen"
@ -257,7 +252,7 @@ msgid "Additional Hosts files"
msgstr "Zusätzliche Hosts-Dateien"
msgid "Additional servers file"
msgstr "Zusätzliche Nameserver-Datei"
msgstr ""
msgid "Address"
msgstr "Adresse"
@ -272,7 +267,7 @@ msgid "Advanced Settings"
msgstr "Erweiterte Einstellungen"
msgid "Aggregate Transmit Power(ACTATP)"
msgstr "Vollständige Sendeleistung (ACTATP)"
msgstr ""
msgid "Alert"
msgstr "Alarm"
@ -293,9 +288,6 @@ msgstr "Erlaube Anmeldung per Passwort"
msgid "Allow all except listed"
msgstr "Alle außer gelistete erlauben"
msgid "Allow legacy 802.11b rates"
msgstr "Veraltete 802.11b Raten erlauben"
msgid "Allow listed only"
msgstr "Nur gelistete erlauben"
@ -326,8 +318,6 @@ msgid ""
"Also see <a href=\"https://www.sixxs.net/faq/connectivity/?faq=comparison"
"\">Tunneling Comparison</a> on SIXXS"
msgstr ""
"Siehe auch <a href=\"https://www.sixxs.net/faq/connectivity/?faq=comparison"
"\">Tunneling Comparison</a> bei SIXXS."
msgid "Always announce default router"
msgstr "Immer Defaultrouter ankündigen"
@ -581,6 +571,9 @@ msgstr ""
"Konfiguriert die distributionsspezifischen Paket-Repositories. Diese "
"Konfiguration wird bei Upgrades NICHT gesichert."
msgid "Buttons"
msgstr "Knöpfe"
msgid "CA certificate; if empty it will be saved after the first connection."
msgstr ""
"CA-Zertifikat (wird beim ersten Verbindungsaufbau automatisch gespeichert "
@ -613,7 +606,7 @@ msgstr "Kanal"
msgid "Check"
msgstr "Prüfen"
msgid "Check filesystems before mount"
msgid "Check fileystems before mount"
msgstr "Dateisysteme prüfen"
msgid "Check this option to delete the existing networks from this radio."
@ -682,17 +675,6 @@ msgstr "Befehl"
msgid "Common Configuration"
msgstr "Allgemeine Konfiguration"
msgid ""
"Complicates key reinstallation attacks on the client side by disabling "
"retransmission of EAPOL-Key frames that are used to install keys. This "
"workaround might cause interoperability issues and reduced robustness of key "
"negotiation especially in environments with heavy traffic load."
msgstr ""
"Deaktiviert bestimmte EAPOL-Key-Retransmissionen um Key-Reinstallation "
"(KRACK) Angriffe auf Client-Seite zu erschweren. Diese Abhilfemaßnahme kann "
"Kompatibilitätsprobleme verursachen und die Zuverlässigkeit von "
"Schlüsselerneuerungen in ausgelasteten Umgebungen verringern."
msgid "Configuration"
msgstr "Konfiguration"
@ -763,11 +745,6 @@ msgstr ""
msgid "Custom feeds"
msgstr "Eigene Repositories"
msgid ""
"Custom files (certificates, scripts) may remain on the system. To prevent "
"this, perform a factory-reset first."
msgstr ""
msgid ""
"Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
"\">LED</abbr>s if possible."
@ -795,10 +772,10 @@ msgid "DHCPv6 client"
msgstr "DHCPv6 Client"
msgid "DHCPv6-Mode"
msgstr "DHCPv6-Modus"
msgstr ""
msgid "DHCPv6-Service"
msgstr "DHCPv6-Dienst"
msgstr ""
msgid "DNS"
msgstr "DNS"
@ -915,7 +892,7 @@ msgid "Disable DNS setup"
msgstr "DNS-Verarbeitung deaktivieren"
msgid "Disable Encryption"
msgstr "Verschlüsselung deaktivieren"
msgstr ""
msgid "Disabled"
msgstr "Deaktiviert"
@ -986,9 +963,6 @@ msgstr "Paket herunterladen und installieren"
msgid "Download backup"
msgstr "Backup herunterladen"
msgid "Downstream SNR offset"
msgstr ""
msgid "Dropbear Instance"
msgstr "Dropbear Instanz"
@ -1043,11 +1017,6 @@ msgstr "Notfall"
msgid "Enable"
msgstr "Aktivieren"
msgid ""
"Enable <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> "
"snooping"
msgstr ""
msgid "Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
msgstr "<abbr title=\"Spanning Tree Protocol\">STP</abbr> aktivieren"
@ -1078,10 +1047,6 @@ msgstr "VLAN-Funktionalität aktivieren"
msgid "Enable WPS pushbutton, requires WPA(2)-PSK"
msgstr "WPS-via-Knopfdruck aktivieren, erfordert WPA(2)-PSK"
#, fuzzy
msgid "Enable key reinstallation (KRACK) countermeasures"
msgstr "Key Reinstallation (KRACK) Gegenmaßnahmen aktivieren "
msgid "Enable learning and aging"
msgstr "Learning und Aging aktivieren"
@ -1106,9 +1071,6 @@ msgstr "Aktivieren/Deaktivieren"
msgid "Enabled"
msgstr "Aktiviert"
msgid "Enables IGMP snooping on this bridge"
msgstr ""
msgid ""
"Enables fast roaming among access points that belong to the same Mobility "
"Domain"
@ -1183,15 +1145,6 @@ msgstr "Externes Protokollserver Protokoll"
msgid "Extra SSH command options"
msgstr "Zusätzliche SSH-Kommando-Optionen"
msgid "FT over DS"
msgstr ""
msgid "FT over the Air"
msgstr ""
msgid "FT protocol"
msgstr ""
msgid "File"
msgstr "Datei"
@ -1298,9 +1251,6 @@ msgstr "Fehlerkorrektursekunden (FECS)"
msgid "Forward broadcast traffic"
msgstr "Broadcasts weiterleiten"
msgid "Forward mesh peer traffic"
msgstr "Mesh-Nachbar-Traffic weiterleiten"
msgid "Forwarding mode"
msgstr "Weiterleitungstyp"
@ -1347,9 +1297,6 @@ msgstr "Allgemeine Optionen für Opkg."
msgid "Generate Config"
msgstr "Konfiguration generieren"
msgid "Generate PMK locally"
msgstr "PMK lokal generieren"
msgid "Generate archive"
msgstr "Sicherung erstellen"
@ -1388,6 +1335,9 @@ msgstr "HE.net Benutzername"
msgid "HT mode (802.11n)"
msgstr "HT-Modus (802.11n)"
msgid "Handler"
msgstr "Handler"
msgid "Hang Up"
msgstr "Auflegen"
@ -1557,7 +1507,7 @@ msgstr "IPv6-über-IPv4 (6to4)"
msgid "Identity"
msgstr "Identität"
msgid "If checked, 1DES is enabled"
msgid "If checked, 1DES is enaled"
msgstr "Aktiviert die Benutzung von 1DES, wenn ausgewählt"
msgid "If checked, encryption is disabled"
@ -1834,12 +1784,6 @@ msgid ""
"from the R0KH that the STA used during the Initial Mobility Domain "
"Association."
msgstr ""
"Liste von R0KH-Bezeichnern innerhalb der selben Mobilitätsdomäne. <br /"
">Format: MAC-Adresse,NAS-Identifier,128 Bit Schlüssel in Hex-Notation. <br /"
">Diese Liste wird verwendet um R0KH-Bezeichner (NAS Identifier) einer Ziel-"
"MAC-Adresse zuzuordnen damit ein PMK-R1-Schlüssel von der R0KH angefordert "
"werden kann, mit der sich der Client wärend der anfänglichen "
"Mobilitätsdomänen-Assoziation verbunden hat."
msgid ""
"List of R1KHs in the same Mobility Domain. <br />Format: MAC-address,R1KH-ID "
@ -1848,12 +1792,6 @@ msgid ""
"R0KH. This is also the list of authorized R1KHs in the MD that can request "
"PMK-R1 keys."
msgstr ""
"Liste von R1KH-Bezeichnern innerhalb der selben Mobilitätsdomäne. <br /"
">Format: MAC-Adresse,R1KH-ID im MAC-Adress-Format,128 Bit Schlüssel in Hex-"
"Notation. <br />Diese Liste wird benutzt um einer R1KH-ID eine Ziel-MAC-"
"Adresse zuzuordnen wenn ein PMK-R1-Schlüssel von einer R0KH-Station "
"versendet wird. Die Liste dient auch zur Authorisierung von R1KH-IDs, welche "
"innerhalb der Mobilitätsdomain PMK-R1-Schlüssel anfordern dürfen."
msgid "List of SSH key files for auth"
msgstr "Liste der SSH Schlüssel zur Authentifikation"
@ -2009,6 +1947,9 @@ msgstr "Maximal zulässige Größe von EDNS.0 UDP Paketen"
msgid "Maximum amount of seconds to wait for the modem to become ready"
msgstr "Maximale Zeit die gewartet wird bis das Modem bereit ist (in Sekunden)"
msgid "Maximum hold time"
msgstr "Maximalzeit zum Halten der Verbindung"
msgid ""
"Maximum length of the name is 15 characters including the automatic protocol/"
"bridge prefix (br-, 6in4-, pppoe- etc.)"
@ -2029,12 +1970,12 @@ msgstr "Hauptspeicher"
msgid "Memory usage (%)"
msgstr "Speichernutzung (%)"
msgid "Mesh Id"
msgstr "Mesh-ID"
msgid "Metric"
msgstr "Metrik"
msgid "Minimum hold time"
msgstr "Minimalzeit zum Halten der Verbindung"
msgid "Mirror monitor port"
msgstr "Spiegel-Monitor-Port"
@ -2085,7 +2026,7 @@ msgstr ""
"Laufwerke und Speicher zur Verwendung eingebunden werden."
msgid "Mount filesystems not specifically configured"
msgstr "Nicht explizit konfigurierte Dateisysteme einhängen"
msgstr ""
msgid "Mount options"
msgstr "Mount-Optionen"
@ -2241,9 +2182,6 @@ msgstr "Notiz"
msgid "Nslookup"
msgstr "DNS-Auflösung"
msgid "Number of cached DNS entries (max is 10000, 0 is no caching)"
msgstr ""
msgid "OK"
msgstr "OK"
@ -2501,6 +2439,9 @@ msgstr "Pfad zu Client-Zertifikat"
msgid "Path to Private Key"
msgstr "Pfad zum Privaten Schlüssel"
msgid "Path to executable which handles the button event"
msgstr "Ausführbare Datei welche das Schalter-Ereignis verarbeitet"
msgid "Path to inner CA-Certificate"
msgstr "Pfad zum inneren CA-Zertifikat"
@ -2640,10 +2581,10 @@ msgid "Quality"
msgstr "Qualität"
msgid "R0 Key Lifetime"
msgstr "R0-Schlüsselgültigkeit"
msgstr ""
msgid "R1 Key Holder"
msgstr "R1-Schlüsselinhaber"
msgstr ""
msgid "RFC3947 NAT-T mode"
msgstr ""
@ -3055,9 +2996,6 @@ msgstr "Größe"
msgid "Size (.ipk)"
msgstr "Größe (.ipk)"
msgid "Size of DNS query cache"
msgstr ""
msgid "Skip"
msgstr "Überspringen"
@ -3104,6 +3042,9 @@ msgstr "Quelle"
msgid "Source routing"
msgstr "Quell-Routing"
msgid "Specifies the button state to handle"
msgstr "Gibt den zu behandelnden Tastenstatus an"
msgid "Specifies the directory the device is attached to"
msgstr "Nennt das Verzeichnis, an welches das Gerät angebunden ist"
@ -3218,9 +3159,6 @@ msgstr ""
"Der Switch %q hat eine unbekannte Struktur, die VLAN Settings könnten "
"unpassend sein."
msgid "Switch Port Mask"
msgstr ""
msgid "Switch VLAN"
msgstr ""
@ -3268,7 +3206,7 @@ msgid "Target"
msgstr "Ziel"
msgid "Target network"
msgstr "Zielnetzwerk"
msgstr ""
msgid "Terminate"
msgstr "Beenden"
@ -3494,15 +3432,15 @@ msgid ""
"This is the content of /etc/rc.local. Insert your own commands here (in "
"front of 'exit 0') to execute them at the end of the boot process."
msgstr ""
"Dies ist der Inhalt von /etc/rc.local. Hier kann man eigene Befehle einfügen "
"Dies ist der Inhalt von /etc.rc.local. Hier kann man eigene Befehle einfügen "
"(vor 'exit 0'), die dann am Ende des Bootvorgangs ausgeführt werden."
msgid ""
"This is the local endpoint address assigned by the tunnel broker, it usually "
"ends with <code>...:2/64</code>"
"ends with <code>:2</code>"
msgstr ""
"Dies ist die lokale, vom Broker zugewiesene IPv6-Adresse, sie endet "
"üblicherweise mit <code>...:2/64</code>"
"üblicherweise mit <code>:2</code>"
msgid ""
"This is the only <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</"
@ -3535,6 +3473,10 @@ msgstr ""
"Diese Tabelle gibt eine Übersicht über aktuell laufende Systemprozesse und "
"deren Status."
msgid "This page allows the configuration of custom button actions"
msgstr ""
"Diese Seite ermöglicht die Konfiguration benutzerdefinierter Tastenaktionen"
msgid "This page gives an overview over currently active network connections."
msgstr "Diese Seite gibt eine Übersicht über aktive Netzwerkverbindungen."
@ -3722,9 +3664,9 @@ msgstr "Benutze Routing-Tabelle"
msgid ""
"Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</"
"em> identifies the host, the <em>IPv4-Address</em> specifies the fixed "
"address to use, and the <em>Hostname</em> is assigned as a symbolic name to "
"the requesting host. The optional <em>Lease time</em> can be used to set non-"
"em> indentifies the host, the <em>IPv4-Address</em> specifies to the fixed "
"address to use and the <em>Hostname</em> is assigned as symbolic name to the "
"requesting host. The optional <em>Lease time</em> can be used to set non-"
"standard host-specific lease time, e.g. 12h, 3d or infinite."
msgstr ""
"Die <em>Hinzufügen</em> Schaltfläche fügt einen neuen Lease-Eintrag hinzu. "
@ -3850,13 +3792,6 @@ msgstr ""
"Achtung: Es gibt ungespeicherte Änderungen die bei einem Neustart verloren "
"gehen!"
msgid ""
"When using a PSK, the PMK can be generated locally without inter AP "
"communications"
msgstr ""
"Wenn PSK in Verwendung ist, können PMK-Schlüssel lokal ohne Inter-Access-"
"Point-Kommunikation erzeugt werden."
msgid "Whether to create an IPv6 default route over the tunnel"
msgstr ""
"Gibt an, ob eine IPv6-Default-Route durch den Tunnel etabliert werden soll"
@ -4035,9 +3970,6 @@ msgstr "offen"
msgid "overlay"
msgstr "Overlay"
msgid "random"
msgstr ""
msgid "relay mode"
msgstr "Relay-Modus"
@ -4083,32 +4015,6 @@ msgstr "ja"
msgid "« Back"
msgstr "« Zurück"
#~ msgid "Action"
#~ msgstr "Aktion"
#~ msgid "Buttons"
#~ msgstr "Knöpfe"
#~ msgid "Handler"
#~ msgstr "Handler"
#~ msgid "Maximum hold time"
#~ msgstr "Maximalzeit zum Halten der Verbindung"
#~ msgid "Minimum hold time"
#~ msgstr "Minimalzeit zum Halten der Verbindung"
#~ msgid "Path to executable which handles the button event"
#~ msgstr "Ausführbare Datei welche das Schalter-Ereignis verarbeitet"
#~ msgid "Specifies the button state to handle"
#~ msgstr "Gibt den zu behandelnden Tastenstatus an"
#~ msgid "This page allows the configuration of custom button actions"
#~ msgstr ""
#~ "Diese Seite ermöglicht die Konfiguration benutzerdefinierter "
#~ "Tastenaktionen"
#~ msgid "Leasetime"
#~ msgstr "Laufzeit"

View File

@ -13,9 +13,6 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Pootle 2.0.4\n"
msgid "%.1f dB"
msgstr ""
msgid "%s is untagged in multiple VLANs!"
msgstr ""
@ -135,9 +132,6 @@ msgstr "Όνομα <abbr title=\"Light Emitting Diode\">LED</abbr>"
msgid "<abbr title=\"Media Access Control\">MAC</abbr>-Address"
msgstr "Διεύθυνση <abbr title=\"Media Access Control\">MAC</abbr>"
msgid "<abbr title=\"The DHCP Unique Identifier\">DUID</abbr>"
msgstr ""
msgid ""
"<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Dynamic Host Configuration "
"Protocol\">DHCP</abbr> leases"
@ -220,6 +214,9 @@ msgstr "Συγκεντρωτής Πρόσβασης "
msgid "Access Point"
msgstr "Σημείο Πρόσβασης"
msgid "Action"
msgstr "Ενέργεια"
msgid "Actions"
msgstr "Ενέργειες"
@ -296,9 +293,6 @@ msgstr ""
msgid "Allow all except listed"
msgstr "Να επιτρέπονται όλες, εκτός από αυτές στη λίστα"
msgid "Allow legacy 802.11b rates"
msgstr ""
msgid "Allow listed only"
msgstr "Να επιτρέπονται μόνο αυτές στην λίστα"
@ -574,6 +568,9 @@ msgid ""
"preserved in any sysupgrade."
msgstr ""
msgid "Buttons"
msgstr "Κουμπιά"
msgid "CA certificate; if empty it will be saved after the first connection."
msgstr ""
@ -604,7 +601,7 @@ msgstr "Κανάλι"
msgid "Check"
msgstr "Έλεγχος"
msgid "Check filesystems before mount"
msgid "Check fileystems before mount"
msgstr ""
msgid "Check this option to delete the existing networks from this radio."
@ -671,13 +668,6 @@ msgstr "Εντολή"
msgid "Common Configuration"
msgstr "Κοινή Παραμετροποίηση"
msgid ""
"Complicates key reinstallation attacks on the client side by disabling "
"retransmission of EAPOL-Key frames that are used to install keys. This "
"workaround might cause interoperability issues and reduced robustness of key "
"negotiation especially in environments with heavy traffic load."
msgstr ""
msgid "Configuration"
msgstr "Παραμετροποίηση"
@ -746,11 +736,6 @@ msgstr ""
msgid "Custom feeds"
msgstr ""
msgid ""
"Custom files (certificates, scripts) may remain on the system. To prevent "
"this, perform a factory-reset first."
msgstr ""
msgid ""
"Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
"\">LED</abbr>s if possible."
@ -972,9 +957,6 @@ msgstr "Κατέβασμα και εγκατάσταση πακέτου"
msgid "Download backup"
msgstr "Κατέβασμα αντιγράφου ασφαλείας"
msgid "Downstream SNR offset"
msgstr ""
msgid "Dropbear Instance"
msgstr ""
@ -1029,11 +1011,6 @@ msgstr "Έκτακτη ανάγκη"
msgid "Enable"
msgstr "Ενεργοποίηση"
msgid ""
"Enable <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> "
"snooping"
msgstr ""
msgid "Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
msgstr "Ενεργοποίηση <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
@ -1064,9 +1041,6 @@ msgstr "Ενεργοποίηση λειτουργίας VLAN"
msgid "Enable WPS pushbutton, requires WPA(2)-PSK"
msgstr ""
msgid "Enable key reinstallation (KRACK) countermeasures"
msgstr ""
msgid "Enable learning and aging"
msgstr "Ένεργοποίηση learning and aging"
@ -1091,9 +1065,6 @@ msgstr "Ενεργοποίηση/Απενεργοποίηση"
msgid "Enabled"
msgstr "Ενεργοποιημένο"
msgid "Enables IGMP snooping on this bridge"
msgstr ""
msgid ""
"Enables fast roaming among access points that belong to the same Mobility "
"Domain"
@ -1166,15 +1137,6 @@ msgstr ""
msgid "Extra SSH command options"
msgstr ""
msgid "FT over DS"
msgstr ""
msgid "FT over the Air"
msgstr ""
msgid "FT protocol"
msgstr ""
msgid "File"
msgstr "Αρχείο"
@ -1277,9 +1239,6 @@ msgstr ""
msgid "Forward broadcast traffic"
msgstr "Προώθηση κίνησης broadcast"
msgid "Forward mesh peer traffic"
msgstr ""
msgid "Forwarding mode"
msgstr "Μέθοδος προώθησης"
@ -1324,9 +1283,6 @@ msgstr ""
msgid "Generate Config"
msgstr ""
msgid "Generate PMK locally"
msgstr ""
msgid "Generate archive"
msgstr ""
@ -1363,6 +1319,9 @@ msgstr ""
msgid "HT mode (802.11n)"
msgstr ""
msgid "Handler"
msgstr ""
msgid "Hang Up"
msgstr "Κρέμασμα"
@ -1532,7 +1491,7 @@ msgstr ""
msgid "Identity"
msgstr "Ταυτότητα"
msgid "If checked, 1DES is enabled"
msgid "If checked, 1DES is enaled"
msgstr ""
msgid "If checked, encryption is disabled"
@ -1954,6 +1913,9 @@ msgid "Maximum amount of seconds to wait for the modem to become ready"
msgstr ""
"Μέγιστος αριθμός δευτερολέπτων αναμονής ώστε το modem να καταστεί έτοιμο"
msgid "Maximum hold time"
msgstr "Μέγιστος χρόνος κράτησης"
msgid ""
"Maximum length of the name is 15 characters including the automatic protocol/"
"bridge prefix (br-, 6in4-, pppoe- etc.)"
@ -1971,12 +1933,12 @@ msgstr "Μνήμη"
msgid "Memory usage (%)"
msgstr "Χρήση Μνήμης (%)"
msgid "Mesh Id"
msgstr ""
msgid "Metric"
msgstr "Μέτρο"
msgid "Minimum hold time"
msgstr "Ελάχιστος χρόνος κράτησης"
msgid "Mirror monitor port"
msgstr ""
@ -2183,9 +2145,6 @@ msgstr "Επισήμανση"
msgid "Nslookup"
msgstr ""
msgid "Number of cached DNS entries (max is 10000, 0 is no caching)"
msgstr ""
msgid "OK"
msgstr "Εντάξει"
@ -2425,6 +2384,9 @@ msgstr "Διαδρομή για Πιστοποιητικό-Πελάτη"
msgid "Path to Private Key"
msgstr "Διαδρομή για Ιδιωτικό Κλειδί"
msgid "Path to executable which handles the button event"
msgstr "Διαδρομή για το εκτελέσιμο που χειρίζεται το γεγονός του κουμπιού"
msgid "Path to inner CA-Certificate"
msgstr ""
@ -2947,9 +2909,6 @@ msgstr "Μέγεθος"
msgid "Size (.ipk)"
msgstr ""
msgid "Size of DNS query cache"
msgstr ""
msgid "Skip"
msgstr "Παράκαμψη"
@ -2992,6 +2951,9 @@ msgstr "Πηγή"
msgid "Source routing"
msgstr ""
msgid "Specifies the button state to handle"
msgstr ""
msgid "Specifies the directory the device is attached to"
msgstr ""
@ -3093,9 +3055,6 @@ msgid ""
"Switch %q has an unknown topology - the VLAN settings might not be accurate."
msgstr ""
msgid "Switch Port Mask"
msgstr ""
msgid "Switch VLAN"
msgstr ""
@ -3326,7 +3285,7 @@ msgstr ""
msgid ""
"This is the local endpoint address assigned by the tunnel broker, it usually "
"ends with <code>...:2/64</code>"
"ends with <code>:2</code>"
msgstr ""
msgid ""
@ -3359,6 +3318,9 @@ msgstr ""
"Αυτή η λίστα δίνει μία εικόνα των τρέχοντων εργασιών συστήματος και της "
"κατάστασής τους."
msgid "This page allows the configuration of custom button actions"
msgstr ""
msgid "This page gives an overview over currently active network connections."
msgstr ""
"Αυτή η σελίδα δίνει μία εικόνα για τις τρέχουσες ενεργές συνδέσεις δικτύου."
@ -3541,9 +3503,9 @@ msgstr ""
msgid ""
"Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</"
"em> identifies the host, the <em>IPv4-Address</em> specifies the fixed "
"address to use, and the <em>Hostname</em> is assigned as a symbolic name to "
"the requesting host. The optional <em>Lease time</em> can be used to set non-"
"em> indentifies the host, the <em>IPv4-Address</em> specifies to the fixed "
"address to use and the <em>Hostname</em> is assigned as symbolic name to the "
"requesting host. The optional <em>Lease time</em> can be used to set non-"
"standard host-specific lease time, e.g. 12h, 3d or infinite."
msgstr ""
@ -3657,11 +3619,6 @@ msgstr "Προειδοποίηση"
msgid "Warning: There are unsaved changes that will get lost on reboot!"
msgstr ""
msgid ""
"When using a PSK, the PMK can be generated locally without inter AP "
"communications"
msgstr ""
msgid "Whether to create an IPv6 default route over the tunnel"
msgstr ""
@ -3840,9 +3797,6 @@ msgstr ""
msgid "overlay"
msgstr ""
msgid "random"
msgstr ""
msgid "relay mode"
msgstr ""
@ -3888,21 +3842,6 @@ msgstr "ναι"
msgid "« Back"
msgstr "« Πίσω"
#~ msgid "Action"
#~ msgstr "Ενέργεια"
#~ msgid "Buttons"
#~ msgstr "Κουμπιά"
#~ msgid "Maximum hold time"
#~ msgstr "Μέγιστος χρόνος κράτησης"
#~ msgid "Minimum hold time"
#~ msgstr "Ελάχιστος χρόνος κράτησης"
#~ msgid "Path to executable which handles the button event"
#~ msgstr "Διαδρομή για το εκτελέσιμο που χειρίζεται το γεγονός του κουμπιού"
#~ msgid "Leasetime"
#~ msgstr "Χρόνος Lease"

View File

@ -13,9 +13,6 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Pootle 2.0.4\n"
msgid "%.1f dB"
msgstr ""
msgid "%s is untagged in multiple VLANs!"
msgstr ""
@ -135,9 +132,6 @@ msgstr "<abbr title=\"Light Emitting Diode\">LED</abbr> Name"
msgid "<abbr title=\"Media Access Control\">MAC</abbr>-Address"
msgstr "<abbr title=\"Media Access Control\">MAC</abbr>-Address"
msgid "<abbr title=\"The DHCP Unique Identifier\">DUID</abbr>"
msgstr ""
msgid ""
"<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Dynamic Host Configuration "
"Protocol\">DHCP</abbr> leases"
@ -220,6 +214,9 @@ msgstr "Access Concentrator"
msgid "Access Point"
msgstr "Access Point"
msgid "Action"
msgstr "Action"
msgid "Actions"
msgstr "Actions"
@ -291,9 +288,6 @@ msgstr "Allow <abbr title=\"Secure Shell\">SSH</abbr> password authentication"
msgid "Allow all except listed"
msgstr "Allow all except listed"
msgid "Allow legacy 802.11b rates"
msgstr ""
msgid "Allow listed only"
msgstr "Allow listed only"
@ -563,6 +557,9 @@ msgid ""
"preserved in any sysupgrade."
msgstr ""
msgid "Buttons"
msgstr "Buttons"
msgid "CA certificate; if empty it will be saved after the first connection."
msgstr ""
@ -593,7 +590,7 @@ msgstr "Channel"
msgid "Check"
msgstr "Check"
msgid "Check filesystems before mount"
msgid "Check fileystems before mount"
msgstr ""
msgid "Check this option to delete the existing networks from this radio."
@ -658,13 +655,6 @@ msgstr "Command"
msgid "Common Configuration"
msgstr "Common Configuration"
msgid ""
"Complicates key reinstallation attacks on the client side by disabling "
"retransmission of EAPOL-Key frames that are used to install keys. This "
"workaround might cause interoperability issues and reduced robustness of key "
"negotiation especially in environments with heavy traffic load."
msgstr ""
msgid "Configuration"
msgstr "Configuration"
@ -733,11 +723,6 @@ msgstr ""
msgid "Custom feeds"
msgstr ""
msgid ""
"Custom files (certificates, scripts) may remain on the system. To prevent "
"this, perform a factory-reset first."
msgstr ""
msgid ""
"Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
"\">LED</abbr>s if possible."
@ -954,9 +939,6 @@ msgstr "Download and install package"
msgid "Download backup"
msgstr ""
msgid "Downstream SNR offset"
msgstr ""
msgid "Dropbear Instance"
msgstr ""
@ -1008,11 +990,6 @@ msgstr ""
msgid "Enable"
msgstr ""
msgid ""
"Enable <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> "
"snooping"
msgstr ""
msgid "Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
msgstr "Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
@ -1043,9 +1020,6 @@ msgstr ""
msgid "Enable WPS pushbutton, requires WPA(2)-PSK"
msgstr ""
msgid "Enable key reinstallation (KRACK) countermeasures"
msgstr ""
msgid "Enable learning and aging"
msgstr ""
@ -1070,9 +1044,6 @@ msgstr "Enable/Disable"
msgid "Enabled"
msgstr "Enabled"
msgid "Enables IGMP snooping on this bridge"
msgstr ""
msgid ""
"Enables fast roaming among access points that belong to the same Mobility "
"Domain"
@ -1142,15 +1113,6 @@ msgstr ""
msgid "Extra SSH command options"
msgstr ""
msgid "FT over DS"
msgstr ""
msgid "FT over the Air"
msgstr ""
msgid "FT protocol"
msgstr ""
msgid "File"
msgstr ""
@ -1252,9 +1214,6 @@ msgstr ""
msgid "Forward broadcast traffic"
msgstr ""
msgid "Forward mesh peer traffic"
msgstr ""
msgid "Forwarding mode"
msgstr ""
@ -1299,9 +1258,6 @@ msgstr ""
msgid "Generate Config"
msgstr ""
msgid "Generate PMK locally"
msgstr ""
msgid "Generate archive"
msgstr ""
@ -1338,6 +1294,9 @@ msgstr ""
msgid "HT mode (802.11n)"
msgstr ""
msgid "Handler"
msgstr "Handler"
msgid "Hang Up"
msgstr "Hang Up"
@ -1506,7 +1465,7 @@ msgstr ""
msgid "Identity"
msgstr "Identity"
msgid "If checked, 1DES is enabled"
msgid "If checked, 1DES is enaled"
msgstr ""
msgid "If checked, encryption is disabled"
@ -1922,6 +1881,9 @@ msgstr ""
msgid "Maximum amount of seconds to wait for the modem to become ready"
msgstr ""
msgid "Maximum hold time"
msgstr "Maximum hold time"
msgid ""
"Maximum length of the name is 15 characters including the automatic protocol/"
"bridge prefix (br-, 6in4-, pppoe- etc.)"
@ -1939,12 +1901,12 @@ msgstr "Memory"
msgid "Memory usage (%)"
msgstr "Memory usage (%)"
msgid "Mesh Id"
msgstr ""
msgid "Metric"
msgstr "Metric"
msgid "Minimum hold time"
msgstr "Minimum hold time"
msgid "Mirror monitor port"
msgstr ""
@ -2150,9 +2112,6 @@ msgstr ""
msgid "Nslookup"
msgstr ""
msgid "Number of cached DNS entries (max is 10000, 0 is no caching)"
msgstr ""
msgid "OK"
msgstr "OK"
@ -2392,6 +2351,9 @@ msgstr ""
msgid "Path to Private Key"
msgstr "Path to Private Key"
msgid "Path to executable which handles the button event"
msgstr ""
msgid "Path to inner CA-Certificate"
msgstr ""
@ -2911,9 +2873,6 @@ msgstr "Size"
msgid "Size (.ipk)"
msgstr ""
msgid "Size of DNS query cache"
msgstr ""
msgid "Skip"
msgstr "Skip"
@ -2956,6 +2915,9 @@ msgstr "Source"
msgid "Source routing"
msgstr ""
msgid "Specifies the button state to handle"
msgstr "Specifies the button state to handle"
msgid "Specifies the directory the device is attached to"
msgstr ""
@ -3055,9 +3017,6 @@ msgid ""
"Switch %q has an unknown topology - the VLAN settings might not be accurate."
msgstr ""
msgid "Switch Port Mask"
msgstr ""
msgid "Switch VLAN"
msgstr ""
@ -3286,7 +3245,7 @@ msgstr ""
msgid ""
"This is the local endpoint address assigned by the tunnel broker, it usually "
"ends with <code>...:2/64</code>"
"ends with <code>:2</code>"
msgstr ""
msgid ""
@ -3317,6 +3276,9 @@ msgstr ""
"This list gives an overview over currently running system processes and "
"their status."
msgid "This page allows the configuration of custom button actions"
msgstr ""
msgid "This page gives an overview over currently active network connections."
msgstr "This page gives an overview over currently active network connections."
@ -3498,9 +3460,9 @@ msgstr ""
msgid ""
"Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</"
"em> identifies the host, the <em>IPv4-Address</em> specifies the fixed "
"address to use, and the <em>Hostname</em> is assigned as a symbolic name to "
"the requesting host. The optional <em>Lease time</em> can be used to set non-"
"em> indentifies the host, the <em>IPv4-Address</em> specifies to the fixed "
"address to use and the <em>Hostname</em> is assigned as symbolic name to the "
"requesting host. The optional <em>Lease time</em> can be used to set non-"
"standard host-specific lease time, e.g. 12h, 3d or infinite."
msgstr ""
@ -3616,11 +3578,6 @@ msgstr ""
msgid "Warning: There are unsaved changes that will get lost on reboot!"
msgstr ""
msgid ""
"When using a PSK, the PMK can be generated locally without inter AP "
"communications"
msgstr ""
msgid "Whether to create an IPv6 default route over the tunnel"
msgstr ""
@ -3797,9 +3754,6 @@ msgstr ""
msgid "overlay"
msgstr ""
msgid "random"
msgstr ""
msgid "relay mode"
msgstr ""
@ -3845,24 +3799,6 @@ msgstr ""
msgid "« Back"
msgstr "« Back"
#~ msgid "Action"
#~ msgstr "Action"
#~ msgid "Buttons"
#~ msgstr "Buttons"
#~ msgid "Handler"
#~ msgstr "Handler"
#~ msgid "Maximum hold time"
#~ msgstr "Maximum hold time"
#~ msgid "Minimum hold time"
#~ msgstr "Minimum hold time"
#~ msgid "Specifies the button state to handle"
#~ msgstr "Specifies the button state to handle"
#~ msgid "Leasetime"
#~ msgstr "Leasetime"

View File

@ -13,9 +13,6 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Pootle 2.0.6\n"
msgid "%.1f dB"
msgstr ""
msgid "%s is untagged in multiple VLANs!"
msgstr ""
@ -139,9 +136,6 @@ msgstr "Nombre del <abbr title=\"Light Emitting Diode\">LED</abbr>"
msgid "<abbr title=\"Media Access Control\">MAC</abbr>-Address"
msgstr "Dirección <abbr title=\"Media Access Control\">MAC</abbr>"
msgid "<abbr title=\"The DHCP Unique Identifier\">DUID</abbr>"
msgstr ""
msgid ""
"<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Dynamic Host Configuration "
"Protocol\">DHCP</abbr> leases"
@ -222,6 +216,9 @@ msgstr "Concentrador de acceso"
msgid "Access Point"
msgstr "Punto de Acceso"
msgid "Action"
msgstr "Acción"
msgid "Actions"
msgstr "Acciones"
@ -297,9 +294,6 @@ msgstr ""
msgid "Allow all except listed"
msgstr "Permitir a todos excepto a los de la lista"
msgid "Allow legacy 802.11b rates"
msgstr ""
msgid "Allow listed only"
msgstr "Permitir a los pertenecientes en la lista"
@ -570,6 +564,9 @@ msgid ""
"preserved in any sysupgrade."
msgstr ""
msgid "Buttons"
msgstr "Botones"
msgid "CA certificate; if empty it will be saved after the first connection."
msgstr ""
@ -600,7 +597,7 @@ msgstr "Canal"
msgid "Check"
msgstr "Comprobar"
msgid "Check filesystems before mount"
msgid "Check fileystems before mount"
msgstr ""
msgid "Check this option to delete the existing networks from this radio."
@ -667,13 +664,6 @@ msgstr "Comando"
msgid "Common Configuration"
msgstr "Configuración común"
msgid ""
"Complicates key reinstallation attacks on the client side by disabling "
"retransmission of EAPOL-Key frames that are used to install keys. This "
"workaround might cause interoperability issues and reduced robustness of key "
"negotiation especially in environments with heavy traffic load."
msgstr ""
msgid "Configuration"
msgstr "Configuración"
@ -742,11 +732,6 @@ msgstr ""
msgid "Custom feeds"
msgstr ""
msgid ""
"Custom files (certificates, scripts) may remain on the system. To prevent "
"this, perform a factory-reset first."
msgstr ""
msgid ""
"Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
"\">LED</abbr>s if possible."
@ -967,9 +952,6 @@ msgstr "Descargar e instalar paquete"
msgid "Download backup"
msgstr "Descargar copia de seguridad"
msgid "Downstream SNR offset"
msgstr ""
msgid "Dropbear Instance"
msgstr "Instancia Dropbear"
@ -1023,11 +1005,6 @@ msgstr "Emergencia"
msgid "Enable"
msgstr "Activar"
msgid ""
"Enable <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> "
"snooping"
msgstr ""
msgid "Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
msgstr "Activar <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
@ -1058,9 +1035,6 @@ msgstr "Activar funcionalidad VLAN"
msgid "Enable WPS pushbutton, requires WPA(2)-PSK"
msgstr ""
msgid "Enable key reinstallation (KRACK) countermeasures"
msgstr ""
msgid "Enable learning and aging"
msgstr "Activar aprendizaje y envejecimiento"
@ -1085,9 +1059,6 @@ msgstr "Activar/Desactivar"
msgid "Enabled"
msgstr "Activado"
msgid "Enables IGMP snooping on this bridge"
msgstr ""
msgid ""
"Enables fast roaming among access points that belong to the same Mobility "
"Domain"
@ -1160,15 +1131,6 @@ msgstr ""
msgid "Extra SSH command options"
msgstr ""
msgid "FT over DS"
msgstr ""
msgid "FT over the Air"
msgstr ""
msgid "FT protocol"
msgstr ""
msgid "File"
msgstr "Fichero"
@ -1270,9 +1232,6 @@ msgstr ""
msgid "Forward broadcast traffic"
msgstr "Retransmitir tráfico de propagación"
msgid "Forward mesh peer traffic"
msgstr ""
msgid "Forwarding mode"
msgstr "Modo de retransmisión"
@ -1318,9 +1277,6 @@ msgstr ""
msgid "Generate Config"
msgstr ""
msgid "Generate PMK locally"
msgstr ""
msgid "Generate archive"
msgstr "Generar archivo"
@ -1359,6 +1315,9 @@ msgstr ""
msgid "HT mode (802.11n)"
msgstr ""
msgid "Handler"
msgstr "Manejador"
msgid "Hang Up"
msgstr "Suspender"
@ -1528,7 +1487,7 @@ msgstr "IPv6-sobre-IPv4 (6to4)"
msgid "Identity"
msgstr "Identidad"
msgid "If checked, 1DES is enabled"
msgid "If checked, 1DES is enaled"
msgstr ""
msgid "If checked, encryption is disabled"
@ -1961,6 +1920,9 @@ msgstr "Tamaño máximo de paquetes EDNS.0 paquetes UDP"
msgid "Maximum amount of seconds to wait for the modem to become ready"
msgstr "Segundos máximos de espera a que el módem esté activo"
msgid "Maximum hold time"
msgstr "Pausa máxima de transmisión"
msgid ""
"Maximum length of the name is 15 characters including the automatic protocol/"
"bridge prefix (br-, 6in4-, pppoe- etc.)"
@ -1978,12 +1940,12 @@ msgstr "Memoria"
msgid "Memory usage (%)"
msgstr "Uso de memoria (%)"
msgid "Mesh Id"
msgstr ""
msgid "Metric"
msgstr "Métrica"
msgid "Minimum hold time"
msgstr "Pausa mínima de espera"
msgid "Mirror monitor port"
msgstr ""
@ -2189,9 +2151,6 @@ msgstr "Aviso"
msgid "Nslookup"
msgstr "NSLookup"
msgid "Number of cached DNS entries (max is 10000, 0 is no caching)"
msgstr ""
msgid "OK"
msgstr "Aceptar"
@ -2432,6 +2391,9 @@ msgstr "Camino al certificado de cliente"
msgid "Path to Private Key"
msgstr "Ruta a la Clave Privada"
msgid "Path to executable which handles the button event"
msgstr "Ruta al ejecutable que maneja el evento button"
msgid "Path to inner CA-Certificate"
msgstr ""
@ -2968,9 +2930,6 @@ msgstr "Tamaño"
msgid "Size (.ipk)"
msgstr ""
msgid "Size of DNS query cache"
msgstr ""
msgid "Skip"
msgstr "Saltar"
@ -3016,6 +2975,9 @@ msgstr "Origen"
msgid "Source routing"
msgstr ""
msgid "Specifies the button state to handle"
msgstr "Especifica el estado de botón a manejar"
msgid "Specifies the directory the device is attached to"
msgstr "Especifica el directorio al que está enlazado el dispositivo"
@ -3124,9 +3086,6 @@ msgid ""
"Switch %q has an unknown topology - the VLAN settings might not be accurate."
msgstr ""
msgid "Switch Port Mask"
msgstr ""
msgid "Switch VLAN"
msgstr ""
@ -3391,10 +3350,10 @@ msgstr ""
msgid ""
"This is the local endpoint address assigned by the tunnel broker, it usually "
"ends with <code>...:2/64</code>"
"ends with <code>:2</code>"
msgstr ""
"Esta es la dirección de punto final asignada por el broker del túnel, suele "
"terminar con <code>...:2/64</code>"
"terminar con <code>:2</code>"
msgid ""
"This is the only <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</"
@ -3424,6 +3383,9 @@ msgid ""
"their status."
msgstr "Procesos de sistema que se están ejecutando actualmente y su estado."
msgid "This page allows the configuration of custom button actions"
msgstr "Configuración de acciones personalizadas para los botones"
msgid "This page gives an overview over currently active network connections."
msgstr "Conexiones de red activas."
@ -3610,9 +3572,9 @@ msgstr "Usar tabla de rutas"
msgid ""
"Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</"
"em> identifies the host, the <em>IPv4-Address</em> specifies the fixed "
"address to use, and the <em>Hostname</em> is assigned as a symbolic name to "
"the requesting host. The optional <em>Lease time</em> can be used to set non-"
"em> indentifies the host, the <em>IPv4-Address</em> specifies to the fixed "
"address to use and the <em>Hostname</em> is assigned as symbolic name to the "
"requesting host. The optional <em>Lease time</em> can be used to set non-"
"standard host-specific lease time, e.g. 12h, 3d or infinite."
msgstr ""
"Pulse el botón <em>Añadir</em> para insertar una nueva cesión. <em>Dirección "
@ -3732,11 +3694,6 @@ msgstr "Aviso"
msgid "Warning: There are unsaved changes that will get lost on reboot!"
msgstr ""
msgid ""
"When using a PSK, the PMK can be generated locally without inter AP "
"communications"
msgstr ""
msgid "Whether to create an IPv6 default route over the tunnel"
msgstr ""
@ -3915,9 +3872,6 @@ msgstr "abierto"
msgid "overlay"
msgstr ""
msgid "random"
msgstr ""
msgid "relay mode"
msgstr ""
@ -3963,30 +3917,6 @@ msgstr "sí"
msgid "« Back"
msgstr "« Volver"
#~ msgid "Action"
#~ msgstr "Acción"
#~ msgid "Buttons"
#~ msgstr "Botones"
#~ msgid "Handler"
#~ msgstr "Manejador"
#~ msgid "Maximum hold time"
#~ msgstr "Pausa máxima de transmisión"
#~ msgid "Minimum hold time"
#~ msgstr "Pausa mínima de espera"
#~ msgid "Path to executable which handles the button event"
#~ msgstr "Ruta al ejecutable que maneja el evento button"
#~ msgid "Specifies the button state to handle"
#~ msgstr "Especifica el estado de botón a manejar"
#~ msgid "This page allows the configuration of custom button actions"
#~ msgstr "Configuración de acciones personalizadas para los botones"
#~ msgid "Leasetime"
#~ msgstr "Tiempo de cesión"

View File

@ -13,9 +13,6 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Pootle 2.0.6\n"
msgid "%.1f dB"
msgstr ""
msgid "%s is untagged in multiple VLANs!"
msgstr ""
@ -136,9 +133,6 @@ msgstr "Nom de la <abbr title=\"Diode Électro-Luminescente\">DEL</abbr>"
msgid "<abbr title=\"Media Access Control\">MAC</abbr>-Address"
msgstr "Adresse <abbr title=\"Media Access Control\">MAC</abbr>"
msgid "<abbr title=\"The DHCP Unique Identifier\">DUID</abbr>"
msgstr ""
msgid ""
"<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Dynamic Host Configuration "
"Protocol\">DHCP</abbr> leases"
@ -225,6 +219,9 @@ msgstr "Concentrateur d'accès"
msgid "Access Point"
msgstr "Point d'accès"
msgid "Action"
msgstr "Action"
msgid "Actions"
msgstr "Actions"
@ -299,9 +296,6 @@ msgstr ""
msgid "Allow all except listed"
msgstr "Autoriser tout sauf ce qui est listé"
msgid "Allow legacy 802.11b rates"
msgstr ""
msgid "Allow listed only"
msgstr "Autoriser seulement ce qui est listé"
@ -575,6 +569,9 @@ msgid ""
"preserved in any sysupgrade."
msgstr ""
msgid "Buttons"
msgstr "Boutons"
msgid "CA certificate; if empty it will be saved after the first connection."
msgstr ""
@ -605,7 +602,7 @@ msgstr "Canal"
msgid "Check"
msgstr "Vérification"
msgid "Check filesystems before mount"
msgid "Check fileystems before mount"
msgstr ""
msgid "Check this option to delete the existing networks from this radio."
@ -674,13 +671,6 @@ msgstr "Commande"
msgid "Common Configuration"
msgstr "Configuration commune"
msgid ""
"Complicates key reinstallation attacks on the client side by disabling "
"retransmission of EAPOL-Key frames that are used to install keys. This "
"workaround might cause interoperability issues and reduced robustness of key "
"negotiation especially in environments with heavy traffic load."
msgstr ""
msgid "Configuration"
msgstr "Configuration"
@ -749,11 +739,6 @@ msgstr ""
msgid "Custom feeds"
msgstr ""
msgid ""
"Custom files (certificates, scripts) may remain on the system. To prevent "
"this, perform a factory-reset first."
msgstr ""
msgid ""
"Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
"\">LED</abbr>s if possible."
@ -977,9 +962,6 @@ msgstr "Télécharge et installe le paquet"
msgid "Download backup"
msgstr "Télécharger la sauvegarde"
msgid "Downstream SNR offset"
msgstr ""
msgid "Dropbear Instance"
msgstr "Session Dropbear"
@ -1033,11 +1015,6 @@ msgstr "Urgence"
msgid "Enable"
msgstr "Activer"
msgid ""
"Enable <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> "
"snooping"
msgstr ""
msgid "Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
msgstr "Activer le protocole <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
@ -1068,9 +1045,6 @@ msgstr "Acviter la gestion des VLANs"
msgid "Enable WPS pushbutton, requires WPA(2)-PSK"
msgstr ""
msgid "Enable key reinstallation (KRACK) countermeasures"
msgstr ""
msgid "Enable learning and aging"
msgstr "Activer l'apprentissage et la péremption"
@ -1095,9 +1069,6 @@ msgstr "Activer/Désactiver"
msgid "Enabled"
msgstr "Activé"
msgid "Enables IGMP snooping on this bridge"
msgstr ""
msgid ""
"Enables fast roaming among access points that belong to the same Mobility "
"Domain"
@ -1172,15 +1143,6 @@ msgstr ""
msgid "Extra SSH command options"
msgstr ""
msgid "FT over DS"
msgstr ""
msgid "FT over the Air"
msgstr ""
msgid "FT protocol"
msgstr ""
msgid "File"
msgstr "Fichier"
@ -1282,9 +1244,6 @@ msgstr ""
msgid "Forward broadcast traffic"
msgstr "Transmettre le trafic de diffusion"
msgid "Forward mesh peer traffic"
msgstr ""
msgid "Forwarding mode"
msgstr "Mode de transmission"
@ -1329,9 +1288,6 @@ msgstr ""
msgid "Generate Config"
msgstr ""
msgid "Generate PMK locally"
msgstr ""
msgid "Generate archive"
msgstr "Construire l'archive"
@ -1370,6 +1326,9 @@ msgstr ""
msgid "HT mode (802.11n)"
msgstr ""
msgid "Handler"
msgstr "Gestionnaire"
msgid "Hang Up"
msgstr "Signal (HUP)"
@ -1540,7 +1499,7 @@ msgstr "IPv6 sur IPv4 (6 vers 4)"
msgid "Identity"
msgstr "Identité"
msgid "If checked, 1DES is enabled"
msgid "If checked, 1DES is enaled"
msgstr ""
msgid "If checked, encryption is disabled"
@ -1975,6 +1934,9 @@ msgstr "Taille maximum autorisée des paquets UDP EDNS.0"
msgid "Maximum amount of seconds to wait for the modem to become ready"
msgstr "Délai d'attente maximum que le modem soit prêt"
msgid "Maximum hold time"
msgstr "Temps de maintien maximum"
msgid ""
"Maximum length of the name is 15 characters including the automatic protocol/"
"bridge prefix (br-, 6in4-, pppoe- etc.)"
@ -1992,12 +1954,12 @@ msgstr "Mémoire"
msgid "Memory usage (%)"
msgstr "Utilisation Mémoire (%)"
msgid "Mesh Id"
msgstr ""
msgid "Metric"
msgstr "Metrique"
msgid "Minimum hold time"
msgstr "Temps de maintien mimimum"
msgid "Mirror monitor port"
msgstr ""
@ -2203,9 +2165,6 @@ msgstr "Note"
msgid "Nslookup"
msgstr "Nslookup"
msgid "Number of cached DNS entries (max is 10000, 0 is no caching)"
msgstr ""
msgid "OK"
msgstr "OK"
@ -2445,6 +2404,9 @@ msgstr "Chemin du certificat-client"
msgid "Path to Private Key"
msgstr "Chemin de la clé privée"
msgid "Path to executable which handles the button event"
msgstr "Chemin du programme exécutable gérant les évènements liés au bouton"
msgid "Path to inner CA-Certificate"
msgstr ""
@ -2982,9 +2944,6 @@ msgstr "Taille"
msgid "Size (.ipk)"
msgstr ""
msgid "Size of DNS query cache"
msgstr ""
msgid "Skip"
msgstr "Passer au suivant"
@ -3031,6 +2990,9 @@ msgstr "Source"
msgid "Source routing"
msgstr ""
msgid "Specifies the button state to handle"
msgstr "Indique l'état du bouton à gérer"
msgid "Specifies the directory the device is attached to"
msgstr "Indique le répertoire auquel le périphérique est rattaché"
@ -3136,9 +3098,6 @@ msgid ""
"Switch %q has an unknown topology - the VLAN settings might not be accurate."
msgstr ""
msgid "Switch Port Mask"
msgstr ""
msgid "Switch VLAN"
msgstr ""
@ -3406,10 +3365,10 @@ msgstr ""
msgid ""
"This is the local endpoint address assigned by the tunnel broker, it usually "
"ends with <code>...:2/64</code>"
"ends with <code>:2</code>"
msgstr ""
"Il s'agit de l'adresse de l'extrémité locale attribuée par le fournisseur de "
"tunnels, elle se termine habituellement avec <code>...:2/64</code>"
"tunnels, elle se termine habituellement avec <code>:2</code>"
msgid ""
"This is the only <abbr title=\"Dynamic Host Configuration Protocol\">DHCP</"
@ -3440,6 +3399,9 @@ msgstr ""
"Cette liste donne une vue d'ensemble des processus en exécution et leur "
"statut."
msgid "This page allows the configuration of custom button actions"
msgstr "Cette page permet la configuration d'actions spécifiques des boutons"
msgid "This page gives an overview over currently active network connections."
msgstr ""
"Cette page donne une vue d'ensemble des connexions réseaux actuellement "
@ -3629,9 +3591,9 @@ msgstr "Utiliser la table de routage"
msgid ""
"Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</"
"em> identifies the host, the <em>IPv4-Address</em> specifies the fixed "
"address to use, and the <em>Hostname</em> is assigned as a symbolic name to "
"the requesting host. The optional <em>Lease time</em> can be used to set non-"
"em> indentifies the host, the <em>IPv4-Address</em> specifies to the fixed "
"address to use and the <em>Hostname</em> is assigned as symbolic name to the "
"requesting host. The optional <em>Lease time</em> can be used to set non-"
"standard host-specific lease time, e.g. 12h, 3d or infinite."
msgstr ""
"Utiliser le bouton <em>Ajouter</em> pour créer un nouveau bail. "
@ -3751,11 +3713,6 @@ msgstr "Attention"
msgid "Warning: There are unsaved changes that will get lost on reboot!"
msgstr ""
msgid ""
"When using a PSK, the PMK can be generated locally without inter AP "
"communications"
msgstr ""
msgid "Whether to create an IPv6 default route over the tunnel"
msgstr ""
@ -3933,9 +3890,6 @@ msgstr "ouvrir"
msgid "overlay"
msgstr ""
msgid "random"
msgstr ""
msgid "relay mode"
msgstr ""
@ -3981,31 +3935,6 @@ msgstr "oui"
msgid "« Back"
msgstr "« Retour"
#~ msgid "Action"
#~ msgstr "Action"
#~ msgid "Buttons"
#~ msgstr "Boutons"
#~ msgid "Handler"
#~ msgstr "Gestionnaire"
#~ msgid "Maximum hold time"
#~ msgstr "Temps de maintien maximum"
#~ msgid "Minimum hold time"
#~ msgstr "Temps de maintien mimimum"
#~ msgid "Path to executable which handles the button event"
#~ msgstr "Chemin du programme exécutable gérant les évènements liés au bouton"
#~ msgid "Specifies the button state to handle"
#~ msgstr "Indique l'état du bouton à gérer"
#~ msgid "This page allows the configuration of custom button actions"
#~ msgstr ""
#~ "Cette page permet la configuration d'actions spécifiques des boutons"
#~ msgid "Leasetime"
#~ msgstr "Durée du bail"

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