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' config 'defaults' 'interface'
option 'netmask' '255.255.255.255' 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' config 'dhcp' 'dhcp'
option leasetime '5m' option leasetime '5m'

View File

@ -31,7 +31,7 @@ config 'defaults' 'ssidscheme'
config 'defaults' 'interface' config 'defaults' 'interface'
option 'netmask' '255.255.255.255' 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' config 'dhcp' 'dhcp'
option 'leasetime' '5m' 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' config 'community' 'profile'
option 'name' 'Freifunk Potsdam' option 'name' 'Freifunk Potsdam'
option 'homepage' 'http://potsdam.freifunk.net' 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 'mesh_network' '10.22.0.0/16'
option 'splash_network' '192.168.22.0/24' option 'splash_network' '192.168.22.0/24'
option 'splash_prefix' '24' option 'splash_prefix' '24'
@ -11,7 +11,7 @@ config 'community' 'profile'
config 'defaults' 'interface' config 'defaults' 'interface'
option 'netmask' '255.255.0.0' 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' option 'delegate' '0'
config 'defaults' 'wifi_device' config 'defaults' 'wifi_device'

View File

@ -7,4 +7,4 @@ config 'community' 'profile'
option 'splash_prefix' '28' option 'splash_prefix' '28'
config 'defaults' 'interface' 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 CATEGORY:=LuCI
SUBMENU:=9. Freifunk SUBMENU:=9. Freifunk
TITLE:=Freifunk common files TITLE:=Freifunk common files
DEPENDS:=+libuci-lua
endef endef
define Package/freifunk-common/description 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 uci batch <<- EOF
set $cfg.olsrd_nameservice=LoadPlugin 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.latlon_file="$llfile"
set $cfg.olsrd_nameservice.hosts_file="$hosts" set $cfg.olsrd_nameservice.hosts_file="$hosts"
set $cfg.olsrd_nameservice.sighup_pid_file="/var/run/dnsmasq.pid" set $cfg.olsrd_nameservice.sighup_pid_file="/var/run/dnsmasq.pid"
@ -118,7 +118,7 @@ setup_jsoninfo() {
proto="$1" proto="$1"
uci batch <<- EOF uci batch <<- EOF
set $cfg.olsrd_jsoninfo=LoadPlugin 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 EOF
if [ "$proto" = "6" ]; then if [ "$proto" = "6" ]; then
uci set $cfg.olsrd_jsoninfo.ipv6only='1' uci set $cfg.olsrd_jsoninfo.ipv6only='1'
@ -130,7 +130,7 @@ setup_txtinfo() {
proto="$1" proto="$1"
uci batch <<- EOF uci batch <<- EOF
set $cfg.olsrd_txtinfo=LoadPlugin 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 EOF
if [ "$proto" = "6" ]; then if [ "$proto" = "6" ]; then
uci set $cfg.olsrd_txtinfo.ipv6only='1' uci set $cfg.olsrd_txtinfo.ipv6only='1'

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>
@ -210,17 +214,22 @@
</tr> </tr>
<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> <td class="summary"></td>
</tr> </tr>
<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> <td class="summary"></td>
</tr> </tr>
<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> <td class="summary"></td>
</tr> </tr>

View File

@ -41,15 +41,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>
@ -317,6 +321,7 @@ Create a CBI form model dispatching target.</td>
<td class="summary"> <td class="summary">
Fetch or create a dispatching node without setting the target module or Fetch or create a dispatching node without setting the target module or
enabling the node.</td> enabling the node.</td>
</tr> </tr>
@ -327,13 +332,6 @@ enabling the node.</td>
Dispatch an HTTP request.</td> Dispatch an HTTP request.</td>
</tr> </tr>
<tr>
<td class="name" nowrap><a href="#lookup">lookup</a>&nbsp;(...)</td>
<td class="summary">
Lookup node in dispatching tree.</td>
</tr>
<tr> <tr>
<td class="name" nowrap><a href="#modifier">modifier</a>&nbsp;(func, order)</td> <td class="name" nowrap><a href="#modifier">modifier</a>&nbsp;(func, order)</td>
<td class="summary"> <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 Fetch or create a dispatching node without setting the target module or
enabling the node.
enabling the node.
<h3>Parameters</h3> <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> </dd>

View File

@ -41,15 +41,19 @@
<li><strong>luci.http</strong></li> <li><strong>luci.http</strong></li>
<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>
<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>
<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>
<li> <li>
@ -252,6 +256,7 @@ Get the value of a certain HTTP-Cookie.</td>
<td class="summary"> <td class="summary">
Get the value of a certain HTTP environment variable Get the value of a certain HTTP environment variable
or the environment table itself.</td> or the environment table itself.</td>
</tr> </tr>
@ -262,20 +267,6 @@ or the environment table itself.</td>
Send a HTTP-Header.</td> Send a HTTP-Header.</td>
</tr> </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> <tr>
<td class="name" nowrap><a href="#prepare_content">prepare_content</a>&nbsp;(mime)</td> <td class="name" nowrap><a href="#prepare_content">prepare_content</a>&nbsp;(mime)</td>
<td class="summary"> <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> Set the HTTP status code and status message.</td>
</tr> </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> <tr>
<td class="name" nowrap><a href="#write">write</a>&nbsp;(content, src_err)</td> <td class="name" nowrap><a href="#write">write</a>&nbsp;(content, src_err)</td>
<td class="summary"> <td class="summary">
@ -424,6 +377,7 @@ Encoded HTTP query string
Close the HTTP-Connection. Close the HTTP-Connection.
@ -573,8 +527,8 @@ String containing cookie data
Get the value of a certain HTTP environment variable Get the value of a certain HTTP environment variable
or the environment table itself.
or the environment table itself.
<h3>Parameters</h3> <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> </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> </dd>
@ -1183,8 +771,7 @@ String containing encoded values
Send a chunk of content data to the client. Send a chunk of content data to the client.
This function is as a valid LTN12 sink. This function is as a valid LTN12 sink.
If the content chunk is nil this function will automatically invoke close. If the content chunk is nil this function will automatically invoke close.
<h3>Parameters</h3> <h3>Parameters</h3>

View File

@ -341,7 +341,7 @@ Ltn12 source function
Decode a mime encoded http message body with multipart/form-data Decode a mime encoded http message body with multipart/form-data
Content-Type. Stores all extracted data associated with its parameter name Content-Type. Stores all extracted data associated with its parameter name
in the params table within the given message object. Multiple parameter in the params table within the given message object. Multiple parameter
values are stored as tables, ordinary ones as strings. values are stored as tables, ordinary ones as strings.
If an optional file callback function is given then it is feeded with the 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 file contents chunk by chunk and only the extracted file name is stored
@ -556,7 +556,7 @@ The decoded string
Decode an urlencoded http message body with application/x-www-urlencoded Decode an urlencoded http message body with application/x-www-urlencoded
Content-Type. Stores all extracted data associated with its parameter name Content-Type. Stores all extracted data associated with its parameter name
in the params table within the given message object. Multiple parameter in the params table within the given message object. Multiple parameter
values are stored as tables, ordinary ones as strings. values are stored as tables, ordinary ones as strings.

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li><strong>luci.i18n</strong></li> <li><strong>luci.i18n</strong></li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>
@ -252,30 +256,6 @@ Checks whether the CIDR instance is an IPv6 link local address
<td class="summary"> <td class="summary">
Checks whether the CIDR instance is an IPv6 mapped IPv4 address 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> </td>
</tr> </tr>
@ -342,20 +322,6 @@ Derive broadcast address of CIDR instance.</td>
Derive mapped IPv4 address of CIDR instance.</td> Derive mapped IPv4 address of CIDR instance.</td>
</tr> </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> <tr>
<td class="name" nowrap><a href="#cidr.contains">cidr:contains</a>&nbsp;(addr)</td> <td class="name" nowrap><a href="#cidr.contains">cidr:contains</a>&nbsp;(addr)</td>
<td class="summary"> <td class="summary">
@ -439,10 +405,6 @@ Checks whether the CIDR instance is an IPv4 address range
cidr:is6 cidr:is6
</a> </a>
<li><a href="#cidr.ismac">
cidr:ismac
</a>
</ul> </ul>
</dd> </dd>
@ -537,10 +499,6 @@ Checks whether the CIDR instance is an IPv6 address range
cidr:is4 cidr:is4
</a> </a>
<li><a href="#cidr.ismac">
cidr:ismac
</a>
</ul> </ul>
</dd> </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> <dt><a name="cidr.lower"></a><strong>cidr:lower</strong>&nbsp;(addr)</dt>
<dd> <dd>
Checks whether this CIDR instance is lower than the given argument. Checks whether this CIDR instance is lower than the given argument.
The comparisation follows these rules: The comparisation follows these rules:
<ul><li>An IPv4 address is always lower than an IPv6 address and IPv6 addresses <ul><li>An IPv4 address is always lower than an IPv6 address</li>
are considered lower than MAC addresses</li>
<li>Prefix sizes are ignored</li></ul> <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(addr)) -- false
print(addr:lower("10.10.10.10/24")) -- false print(addr:lower("10.10.10.10/24")) -- false
print(addr:lower(luci.ip.new("::1"))) -- true 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("192.168.200.1"))) -- true</pre>
print(addr:lower(luci.ip.new("00:14:22:01:23:45"))) -- 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. Checks whether this CIDR instance is higher than the given argument.
The comparisation follows these rules: The comparisation follows these rules:
<ul><li>An IPv4 address is always lower than an IPv6 address and IPv6 addresses <ul><li>An IPv4 address is always lower than an IPv6 address</li>
are considered lower than MAC addresses</li>
<li>Prefix sizes are ignored</li></ul> <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(addr)) -- false
print(addr:higher("10.10.10.10/24")) -- true print(addr:higher("10.10.10.10/24")) -- true
print(addr:higher(luci.ip.new("::1"))) -- false 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("192.168.200.1"))) -- false</pre>
print(addr:higher(luci.ip.new("00:14:22:01:23:45"))) -- false</pre>
@ -849,11 +709,7 @@ print(addr:equal(luci.ip.new("::1"))) -- false
local addr6 = luci.ip.new("::1") local addr6 = luci.ip.new("::1")
print(addr6:equal("0:0:0:0:0:0:0:1/64")) -- true 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 print(addr6:equal(luci.ip.new("fe80::221:63ff:fe75:aa17"))) -- false</pre>
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>
@ -896,8 +752,8 @@ else the current prefix size is returned.
<li> <li>
mask: Either a number containing the number of bits (<code>0..32</code> 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 for IPv4, <code>0..128</code> for IPv6) or a string containing a valid
containing a valid netmask (optional) netmask (optional)
</li> </li>
</ul> </ul>
@ -944,8 +800,8 @@ optional mask parameter.
<li> <li>
mask: Either a number containing the number of bits (<code>0..32</code> 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 for IPv4, <code>0..128</code> for IPv6) or a string containing a valid
containing a valid netmask (optional) netmask (optional)
</li> </li>
</ul> </ul>
@ -981,7 +837,7 @@ CIDR instance representing the network address
Derive host address of CIDR instance. Derive host address of CIDR instance.
This function essentially constructs a copy of this CIDR with the prefix size 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> <li>
mask: Either a number containing the number of bits (<code>0..32</code> 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 for IPv4, <code>0..128</code> for IPv6) or a string containing a valid
containing a valid netmask (optional) netmask (optional)
</li> </li>
</ul> </ul>
@ -1057,8 +913,8 @@ Derive broadcast address of CIDR instance.
Constructs a CIDR instance representing the broadcast address of this instance. Constructs a CIDR instance representing the broadcast address of this instance.
The used prefix size can be overridden by the optional mask parameter. 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 This function has no effect on IPv6 instances, it will return nothing in this
nothing in this case. case.
@ -1066,8 +922,9 @@ nothing in this case.
<ul> <ul>
<li> <li>
mask: Either a number containing the number of bits (<code>0..32</code> for IPv4) or mask: Either a number containing the number of bits (<code>0..32</code>
a string containing a valid netmask (optional) for IPv4, <code>0..128</code> for IPv6) or a string containing a valid
netmask (optional)
</li> </li>
</ul> </ul>
@ -1103,8 +960,8 @@ Derive mapped IPv4 address of CIDR instance.
Constructs a CIDR instance representing the IPv4 address of the IPv6 mapped Constructs a CIDR instance representing the IPv4 address of the IPv6 mapped
IPv4 address in this instance. IPv4 address in this instance.
This function has no effect on IPv4 instances, MAC address instances or IPv6 This function has no effect on IPv4 instances or IPv6 instances which are not a
instances which are not a mapped address, it will return nothing in this case. 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> <dt><a name="cidr.contains"></a><strong>cidr:contains</strong>&nbsp;(addr)</dt>
<dd> <dd>
@ -1225,11 +1014,7 @@ print(range:contains("10.0.0.0/8")) -- false
local range6 = luci.ip.new("fe80::/10") local range6 = luci.ip.new("fe80::/10")
print(range6:contains("fe80::221:63f:fe75:aa17/64")) -- true print(range6:contains("fe80::221:63f:fe75:aa17/64")) -- true
print(range6:contains("fd9b:6b3:c5:0:221:63f:fe75:aa17/64")) -- false print(range6:contains("fd9b:6b3:c5:0:221:63f:fe75:aa17/64")) -- false</pre>
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>
@ -1274,40 +1059,30 @@ address space, the result is set to the highest possible address.
<h3>Usage:</h3> <h3>Usage:</h3>
<pre>local addr = luci.ip.new("192.168.1.1/24") <pre>local addr = luci.ip.new("192.168.1.1/24")
print(addr:add(250)) -- "192.168.1.251/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("0.0.99.0")) -- "192.168.100.1/24"
addr:add(256, true) -- true addr:add(256, true) -- true
print(addr) -- "192.168.2.1/24 print(addr) -- "192.168.2.1/24
addr:add("255.0.0.0", true) -- false (overflow) addr:add("255.0.0.0", true) -- false (overflow)
print(addr) -- "255.255.255.255/24 print(addr) -- "255.255.255.255/24
local addr6 = luci.ip.new("fe80::221:63f:fe75:aa17/64") local addr6 = luci.ip.new("fe80::221:63f:fe75:aa17/64")
print(addr6:add(256)) -- "fe80::221:63f:fe75:ab17/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("::ffff:0")) -- "fe80::221:640:fe74:aa17/64"
addr6:add(256, true) -- true addr:add(256, true) -- true
print(addr6) -- "fe80::221:63f:fe75:ab17/64 print(addr) -- "fe80::221:63f:fe75:ab17/64
addr6:add("ffff::", true) -- false (overflow) addr:add("ffff::", true) -- false (overflow)
print(addr6) -- "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64" print(addr) -- "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64"</pre>
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>
<h3>Return value:</h3> <h3>Return value:</h3>
<ul> <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> or <code>false</code> when the addition overflowed.</li>
<li>When deriving new CIDR: Return new instance representing the value of <li>When deriving new CIDR: Return new instance representing the value of
this instance plus the added amount or the highest possible address if this instance plus the added amount or the highest possible address if
@ -1324,7 +1099,7 @@ print(mac) -- "FF:FF:FF:FF:FF:FF"</pre>
<dd> <dd>
Subtract given amount from CIDR instance. If the result would under, the lowest Subtract given amount from CIDR instance. If the result would under, the lowest
possible address is returned. possible address is returned.
@ -1367,26 +1142,16 @@ addr:sub(256, true) -- true
print(addr) -- "fe80::221:63f:fe75:a917/64" print(addr) -- "fe80::221:63f:fe75:a917/64"
addr:sub("ffff::", true) -- false (underflow) addr:sub("ffff::", true) -- false (underflow)
print(addr) -- "::/64" print(addr) -- "::/64"</pre>
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>
<h3>Return value:</h3> <h3>Return value:</h3>
<ul> <ul>
<li>When subtracting inplace: Return <code>true</code> if the subtraction <li>When subtracting inplace: Return <code>true</code> if the subtraction
succeeded or <code>false</code> when the subtraction underflowed.</li> succeeded or <code>false</code> when the subtraction underflowed.</li>
<li>When deriving new CIDR: Return new instance representing the value of <li>When deriving new CIDR: Return new instance representing the value of
this instance minus the subtracted amount or the lowest address if this instance minus the subtracted amount or the lowest address if
the subtraction underflowed.</li></ul> the subtraction underflowed.</li></ul>
@ -1412,10 +1177,7 @@ Calculate the lowest possible host address within this CIDR instance.
print(addr:minhost()) -- "192.168.123.1" print(addr:minhost()) -- "192.168.123.1"
local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64") local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
print(addr6:minhost()) -- "fd9b:62b3:9cc5::1" print(addr6:minhost()) -- "fd9b:62b3:9cc5::1"</pre>
local mac = luci.ip.new("00:14:22:01:22:45/32")
print(mac:minhost()) -- "00:14:22:01:00:01"</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) print(addr:maxhost()) -- "192.168.123.254" (.255 is broadcast)
local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64") 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" print(addr6:maxhost()) -- "fd9b:62b3:9cc5:0:ffff:ffff:ffff:ffff"</pre>
local mac = luci.ip.new("00:14:22:01:22:45/32")
print(mac:maxhost()) -- "00:14:22:01:FF:FF"</pre>
@ -1470,9 +1229,8 @@ Returns a new CIDR instance representing the highest host address
Convert CIDR instance into string representation. Convert CIDR instance into string representation.
If the prefix size of instance is less than 32 for IPv4, 128 for IPv6 or 48 for If the prefix size of instance is less than 32 for IPv4 or 128 for IPv6, the
MACs, the address is returned in the form "address/prefix" otherwise just address is returned in the form "address/prefix" otherwise just "address".
"address".
It is usually not required to call this function directly as CIDR objects It is usually not required to call this function directly as CIDR objects
define it as __tostring function in the associated metatable. define it as __tostring function in the associated metatable.

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>
@ -227,34 +231,6 @@ Construct a new IPv4 luci.ip.cidr instance.</td>
Construct a new IPv6 luci.ip.cidr instance.</td> Construct a new IPv6 luci.ip.cidr instance.</td>
</tr> </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> <tr>
<td class="name" nowrap><a href="#route">route</a>&nbsp;(address)</td> <td class="name" nowrap><a href="#route">route</a>&nbsp;(address)</td>
<td class="summary"> <td class="summary">
@ -358,10 +334,6 @@ address/mask range.
IPv6 IPv6
</a> </a>
<li><a href="#MAC">
MAC
</a>
</ul> </ul>
</dd> </dd>
@ -417,10 +389,6 @@ A <code>luci.ip.cidr</code> object representing the given IPv4 range.
IPv6 IPv6
</a> </a>
<li><a href="#MAC">
MAC
</a>
</ul> </ul>
</dd> </dd>
@ -476,252 +444,6 @@ A <code>luci.ip.cidr</code> object representing the given IPv6 range.
IPv4 IPv4
</a> </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> </ul>
</dd> </dd>
@ -1065,7 +787,7 @@ A neighbour entry is a table containing the following fields:
</tr> </tr>
<tr> <tr>
<td><code>mac</code></td> <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>
<tr> <tr>
<td><code>router</code></td> <td><code>router</code></td>
@ -1183,8 +905,8 @@ described below is returned, else an empty table.
</tr> </tr>
<tr> <tr>
<td><code>mac</code></td> <td><code>mac</code></td>
<td>MAC address <code>luci.ip.cidr</code> instance representing the device ethernet <td>String containing the link local address of the device in
address</td> dotted hex notation</td>
</tr> </tr>
</table> </table>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>
@ -305,13 +309,6 @@ Get an option or list and return values as table.</td>
Get the directory for uncomitted changes.</td> Get the directory for uncomitted changes.</td>
</tr> </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> <tr>
<td class="name" nowrap><a href="#Cursor.load">Cursor:load</a>&nbsp;(config)</td> <td class="name" nowrap><a href="#Cursor.load">Cursor:load</a>&nbsp;(config)</td>
<td class="summary"> <td class="summary">
@ -368,13 +365,6 @@ Set given values as list.</td>
Set the directory for uncommited changes.</td> Set the directory for uncommited changes.</td>
</tr> </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> <tr>
<td class="name" nowrap><a href="#Cursor.substate">Cursor:substate</a>&nbsp;()</td> <td class="name" nowrap><a href="#Cursor.substate">Cursor:substate</a>&nbsp;()</td>
<td class="summary"> <td class="summary">
@ -641,8 +631,8 @@ Delete all sections of a given type that match certain criteria.
</li> </li>
<li> <li>
comparator: Function that will be called for each section and returns comparator: Function that will be called for each section and
a boolean whether to delete the current section (optional) returns a boolean whether to delete the current section (optional)
</li> </li>
</ul> </ul>
@ -913,8 +903,8 @@ Get an option or list and return values as table.
<h3>Return value:</h3> <h3>Return value:</h3>
table. If the option was not found, you will simply get an empty table. If the option was not found, you will simply get
table. 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> <dt><a name="Cursor.load"></a><strong>Cursor:load</strong>&nbsp;(config)</dt>
<dd> <dd>
@ -1255,8 +1222,7 @@ has the same effect as deleting the option.
</li> </li>
<li> <li>
value: Value or table. Non-table values will be set as single value: value or table. Raw values will become a single item table.
item UCI list.
</li> </li>
</ul> </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> <h3>Return value:</h3>
Boolean whether operation succeeded Boolean whether operation succeeded
@ -1344,11 +1278,10 @@ Boolean whether operation succeeded
<dd> <dd>
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 curser, means it the parent unloads or loads configs, the sub state will
loads configs, the sub state will do so as well. do so as well.

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>
@ -270,6 +274,13 @@ This is a coroutine-safe drop-in replacement for Lua's "xpcall"-function
</td> </td>
</tr> </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> <tr>
<td class="name" nowrap><a href="#dumptable">dumptable</a>&nbsp;(t, maxdepth)</td> <td class="name" nowrap><a href="#dumptable">dumptable</a>&nbsp;(t, maxdepth)</td>
<td class="summary"> <td class="summary">
@ -338,6 +349,7 @@ Returns the absolute path to LuCI base directory.</td>
<td class="summary"> <td class="summary">
Parse certain units from the given string and return the canonical integer Parse certain units from the given string and return the canonical integer
value or 0 if the unit is unknown.</td> value or 0 if the unit is unknown.</td>
</tr> </tr>
@ -367,6 +379,7 @@ Restore data previously serialized with serialize_data().</td>
<td class="summary"> <td class="summary">
Recursively serialize given data to lua code, suitable for restoring Recursively serialize given data to lua code, suitable for restoring
with loadstring().</td> with loadstring().</td>
</tr> </tr>
@ -378,18 +391,12 @@ Convert data structure to JSON
</td> </td>
</tr> </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> <tr>
<td class="name" nowrap><a href="#spairs">spairs</a>&nbsp;(t, f)</td> <td class="name" nowrap><a href="#spairs">spairs</a>&nbsp;(t, f)</td>
<td class="summary"> <td class="summary">
Return a key, value iterator which returns the values sorted according to Return a key, value iterator which returns the values sorted according to
the provided callback function.</td> the provided callback function.</td>
</tr> </tr>
@ -398,6 +405,7 @@ the provided callback function.</td>
<td class="summary"> <td class="summary">
Splits given string on a defined separator sequence and return a table Splits given string on a defined separator sequence and return a table
containing the resulting substrings.</td> containing the resulting substrings.</td>
</tr> </tr>
@ -420,6 +428,7 @@ Strip HTML tags from given string.</td>
<td class="summary"> <td class="summary">
Create a new or get an already existing thread local store associated with Create a new or get an already existing thread local store associated with
the current active coroutine.</td> the current active coroutine.</td>
</tr> </tr>
@ -444,20 +453,6 @@ Issue an ubus call.</td>
Update values in given table with the values from the second given table.</td> Update values in given table with the values from the second given table.</td>
</tr> </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> <tr>
<td class="name" nowrap><a href="#vspairs">vspairs</a>&nbsp;(t)</td> <td class="name" nowrap><a href="#vspairs">vspairs</a>&nbsp;(t)</td>
<td class="summary"> <td class="summary">
@ -554,8 +549,7 @@ Classes can inherit member functions and values from a base class.
Class can be instantiated by calling them. All parameters will be passed Class can be instantiated by calling them. All parameters will be passed
to the __init__ function of this class - if such a function exists. 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 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. with other objects of this class. Any return values will be ignored.
<h3>Parameters</h3> <h3>Parameters</h3>
@ -635,7 +629,7 @@ Cloned table value
<dd> <dd>
Count the occurrences of given substring in given string. Count the occurrences of given substring in given string.
@ -734,8 +728,8 @@ Checks whether the given table contains the given value.
<h3>Return value:</h3> <h3>Return value:</h3>
Number indicating the first index at which the given value occurs number indicating the first index at which the given value occurs
within table or false. 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> <h3>Return value:</h3>
A boolean whether the function call succeeded and the returns 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> <h3>Return value:</h3>
A boolean whether the function call succeeded and the return 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 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> <h3>Parameters</h3>
@ -959,12 +976,11 @@ String value containing the bytecode of the given data
<dd> <dd>
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 one token per invocation, the tokens are separated by whitespace. If the
whitespace. If the input value is a table, it is transformed into a string first. input value is a table, it is transformed into a string first. A nil value
A nil value will result in a valid interator which aborts with the first invocation. will result in a valid interator which aborts with the first invocation.
<h3>Parameters</h3> <h3>Parameters</h3>
@ -1078,8 +1094,7 @@ Sorted table containing the keys
Return a key, value iterator for the given table. Return a key, value iterator for the given table.
The table pairs are sorted by key. The table pairs are sorted by key.
<h3>Parameters</h3> <h3>Parameters</h3>
@ -1134,11 +1149,9 @@ String containing the directory path
Parse certain units from the given string and return the canonical integer 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: Recognized units are:
o "y" - one year (60*60*24*366) o "y" - one year (60*60*24*366)
o "m" - one month (60*60*24*31) o "m" - one month (60*60*24*31)
o "w" - one week (60*60*24*7) o "w" - one week (60*60*24*7)
@ -1150,8 +1163,7 @@ Recognized units are:
o "gb" - one gigabyte (1024*1024*1024) o "gb" - one gigabyte (1024*1024*1024)
o "kib" - one si kilobyte (1000) o "kib" - one si kilobyte (1000)
o "mib" - one si megabyte (1000*1000) o "mib" - one si megabyte (1000*1000)
o "gib" - one si gigabyte (1000*1000*1000) o "gib" - one si gigabyte (1000*1000*1000)
<h3>Parameters</h3> <h3>Parameters</h3>
@ -1292,8 +1304,8 @@ Value containing the restored data structure
Recursively serialize given data to lua code, suitable for restoring Recursively serialize given data to lua code, suitable for restoring
with loadstring().
with loadstring().
<h3>Parameters</h3> <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> <dt><a name="spairs"></a><strong>spairs</strong>&nbsp;(t, f)</dt>
<dd> <dd>
Return a key, value iterator which returns the values sorted according to Return a key, value iterator which returns the values sorted according to
the provided callback function.
the provided callback function.
<h3>Parameters</h3> <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 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, containing the resulting substrings. The optional max parameter specifies
regardless of the actual length of the given string. The optional last the number of bytes to process, regardless of the actual length of the given
parameter, regex, specifies whether the separator sequence is string. The optional last parameter, regex, specifies whether the separator
nterpreted as regular expression. sequence is interpreted as regular expression.
<h3>Parameters</h3> <h3>Parameters</h3>
@ -1493,11 +1471,10 @@ Table containing the resulting substrings
<dd> <dd>
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. numbers and debugging numbers will be discarded. Original version by
Original version by Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html) Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html)
<h3>Parameters</h3> <h3>Parameters</h3>
@ -1561,11 +1538,9 @@ String with HTML tags stripped of
Create a new or get an already existing thread local store associated with 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. whose values can't be accessed from outside of the running coroutine.
@ -1661,8 +1636,7 @@ Table containin the ubus result
Update values in given table with the values from the second given table. Update values in given table with the values from the second given table.
Both table are - in fact - merged together. Both table are - in fact - merged together.
<h3>Parameters</h3> <h3>Parameters</h3>
@ -1693,100 +1667,13 @@ 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> <dt><a name="vspairs"></a><strong>vspairs</strong>&nbsp;(t)</dt>
<dd> <dd>
Return a key, value iterator for the given table. Return a key, value iterator for the given table.
The table pairs are sorted by value. The table pairs are sorted by value.
<h3>Parameters</h3> <h3>Parameters</h3>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>
@ -284,7 +288,7 @@
<br />In general all functions are namend and behave like their POSIX API <br />In general all functions are namend and behave like their POSIX API
counterparts - where applicable - applying the following rules: counterparts - where applicable - applying the following rules:
<ul> <ul>
<li>Functions should be named like the underlying POSIX API function omitting <li>Functions should be named like the underlying POSIX API function omitting
prefixes or suffixes - especially when placed in an object-context ( prefixes or suffixes - especially when placed in an object-context (
lockf -> File:lock, fsync -> File:sync, dup2 -> dup, ...)</li> lockf -> File:lock, fsync -> File:sync, dup2 -> dup, ...)</li>
<li>If you are unclear about the behaviour of a function you should consult <li>If you are unclear about the behaviour of a function you should consult
@ -292,10 +296,10 @@
<li>If the name is significantly different from the POSIX-function, the <li>If the name is significantly different from the POSIX-function, the
underlying function(s) are stated in the documentation.</li> underlying function(s) are stated in the documentation.</li>
<li>Parameters should reflect those of the C-API, buffer length arguments and <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 <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 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 omitting prefixes or suffixes. (e.g. waitpid
(pid, &s, WNOHANG | WUNTRACED) -> waitpid(pid, "nohang", "untraced"), (pid, &s, WNOHANG | WUNTRACED) -> waitpid(pid, "nohang", "untraced"),
getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) -> getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) ->
Socket:getopt("socket", "reuseaddr"), etc.) </li> Socket:getopt("socket", "reuseaddr"), etc.) </li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>
@ -322,7 +326,7 @@
<li>The blocksize given is only advisory and to be seen as an upper limit, <li>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. if an underlying read returns less bytes the chunk is nevertheless returned.
<li>If the limit parameter is omitted, the iterator returns data <li>If the limit parameter is omitted, the iterator returns data
until an end-of-file, end-of-stream, connection shutdown or similar happens. until an end-of-file, end-of-stream, connection shutdown or similar happens.
<li>The iterator will not buffer so it is safe to mix with calls to read. <li>The iterator will not buffer so it is safe to mix with calls to read.
@ -398,7 +402,7 @@ true
<li>This function uses the blocksource function of the source descriptor <li>This function uses the blocksource function of the source descriptor
and the sink function of the target descriptor. and the sink function of the target descriptor.
<li>If the limit parameter is omitted, data is copied <li>If the limit parameter is omitted, data is copied
until an end-of-file, end-of-stream, connection shutdown or similar happens. until an end-of-file, end-of-stream, connection shutdown or similar happens.
<li>If the descriptor is non-blocking the function may fail with EAGAIN. <li>If the descriptor is non-blocking the function may fail with EAGAIN.
@ -457,7 +461,7 @@ true
blocksource function of the source descriptor and the sink function blocksource function of the source descriptor and the sink function
of the target descriptor as a fallback mechanism. of the target descriptor as a fallback mechanism.
<li>If the limit parameter is omitted, data is copied <li>If the limit parameter is omitted, data is copied
until an end-of-file, end-of-stream, connection shutdown or similar happens. until an end-of-file, end-of-stream, connection shutdown or similar happens.
<li>If the descriptor is non-blocking the function may fail with EAGAIN. <li>If the descriptor is non-blocking the function may fail with EAGAIN.
@ -580,7 +584,7 @@ boolean
you can pass "true" to the iterator which will flush the buffer you can pass "true" to the iterator which will flush the buffer
and return the bufferd data. and return the bufferd data.
<li>If the limit parameter is omitted, this function uses the nixio <li>If the limit parameter is omitted, this function uses the nixio
buffersize (8192B by default). buffersize (8192B by default).
<li>If the descriptor is non-blocking the iterator may fail with EAGAIN. <li>If the descriptor is non-blocking the iterator may fail with EAGAIN.
@ -624,7 +628,7 @@ Line-based Iterator
<li>This function uses the low-level read function of the descriptor. <li>This function uses the low-level read function of the descriptor.
<li>If the length parameter is omitted, this function returns all data <li>If the length parameter is omitted, this function returns all data
that can be read before an end-of-file, end-of-stream, connection shutdown that can be read before an end-of-file, end-of-stream, connection shutdown
or similar happens. or similar happens.

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>

View File

@ -43,15 +43,19 @@
</li> </li>
<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>
<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>
<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>
<li> <li>
@ -1270,7 +1274,7 @@ true
<h3>Usage:</h3> <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>
<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>
<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>
<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>
<li> <li>

View File

@ -7,7 +7,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
LUCI_TITLE:=HTTP(S) client library 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 include ../../luci.mk

View File

@ -7,8 +7,8 @@ local nixio = require "nixio"
local ltn12 = require "luci.ltn12" local ltn12 = require "luci.ltn12"
local util = require "luci.util" local util = require "luci.util"
local table = require "table" local table = require "table"
local http = require "luci.http" local http = require "luci.http.protocol"
local date = require "luci.http.date" local date = require "luci.http.protocol.date"
local type, pairs, ipairs, tonumber = type, pairs, ipairs, tonumber local type, pairs, ipairs, tonumber = type, pairs, ipairs, tonumber
local unpack = unpack 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with 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_INT(x) (*(int *)RTA_DATA(x))
#define RTA_U32(x) (*(uint32_t *)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 int hz = 0;
static struct nl_sock *sock = NULL; static struct nl_sock *sock = NULL;
@ -59,11 +49,11 @@ typedef struct {
union { union {
struct in_addr v4; struct in_addr v4;
struct in6_addr v6; struct in6_addr v6;
struct ether_addr mac;
uint8_t u8[16];
} addr; } addr;
uint16_t family; int len;
int16_t bits; int bits;
int family;
bool exact;
} cidr_t; } cidr_t;
struct dump_filter { struct dump_filter {
@ -80,8 +70,6 @@ struct dump_filter {
cidr_t src; cidr_t src;
cidr_t dst; cidr_t dst;
struct ether_addr mac; struct ether_addr mac;
bool from_exact;
bool dst_exact;
}; };
struct dump_state { struct dump_state {
@ -107,68 +95,29 @@ static cidr_t *L_checkcidr (lua_State *L, int index, cidr_t *p)
return NULL; return NULL;
} }
static bool parse_mac(const char *mac, struct ether_addr *ea) static bool parse_mask(int family, const char *mask, int *bits)
{
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)
{ {
char *e; char *e;
union { struct in_addr m;
struct in_addr v4; struct in6_addr m6;
struct in6_addr v6;
struct ether_addr mac;
uint8_t u8[16];
} m;
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); for (*bits = 0, m.s_addr = ntohl(m.s_addr);
*bits < AF_BITS(AF_INET) && (m.v4.s_addr << *bits) & 0x80000000; *bits < 32 && (m.s_addr << *bits) & 0x80000000;
++*bits); ++*bits);
} }
else if ((family == AF_INET6 && inet_pton(AF_INET6, mask, &m.v6)) || else if (family == AF_INET6 && inet_pton(AF_INET6, mask, &m6))
(family == AF_PACKET && parse_mac(mask, &m.mac)))
{ {
for (*bits = 0; 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); ++*bits);
} }
else else
{ {
*bits = strtoul(mask, &e, 10); *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; 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) static bool parse_cidr(const char *dest, cidr_t *pp)
{ {
char *p, buf[INET6_ADDRSTRLEN * 2 + 2]; char *p, buf[INET6_ADDRSTRLEN * 2 + 2];
uint8_t bitlen = 0;
strncpy(buf, dest, sizeof(buf) - 1); strncpy(buf, dest, sizeof(buf) - 1);
@ -187,11 +137,17 @@ static bool parse_cidr(const char *dest, cidr_t *pp)
*p++ = 0; *p++ = 0;
if (inet_pton(AF_INET, buf, &pp->addr.v4)) if (inet_pton(AF_INET, buf, &pp->addr.v4))
{
bitlen = 32;
pp->family = AF_INET; pp->family = AF_INET;
pp->len = sizeof(struct in_addr);
}
else if (inet_pton(AF_INET6, buf, &pp->addr.v6)) else if (inet_pton(AF_INET6, buf, &pp->addr.v6))
{
bitlen = 128;
pp->family = AF_INET6; pp->family = AF_INET6;
else if (parse_mac(buf, &pp->addr.mac)) pp->len = sizeof(struct in6_addr);
pp->family = AF_PACKET; }
else else
return false; return false;
@ -202,45 +158,12 @@ static bool parse_cidr(const char *dest, cidr_t *pp)
} }
else else
{ {
pp->bits = AF_BITS(pp->family); pp->bits = bitlen;
} }
return true; 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) static int L_getint(lua_State *L, int index, const char *name)
{ {
int rv = 0; int rv = 0;
@ -297,20 +220,16 @@ static void L_setaddr(struct lua_State *L, const char *name,
if (family == AF_INET) if (family == AF_INET)
{ {
p->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; 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 else
{ {
p->family = AF_PACKET; p->family = AF_INET6;
p->bits = (bits < 0) ? AF_BITS(AF_PACKET) : bits; p->bits = (bits < 0) ? 128 : bits;
p->addr.mac = *(struct ether_addr *)addr; p->len = sizeof(p->addr.v6);
p->addr.v6 = *(struct in6_addr *)addr;
} }
luaL_getmetatable(L, LUCI_IP_CIDR); 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) static int L_checkbits(lua_State *L, int index, cidr_t *p)
{ {
int16_t s16;
int bits; int bits;
if (lua_gettop(L) < index || lua_isnil(L, index)) 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); 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"); return luaL_error(L, "Invalid prefix size");
} }
else if (lua_type(L, index) == LUA_TSTRING) 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"); return luaL_error(L, "Invalid netmask format");
bits = s16;
} }
else else
{ {
@ -377,26 +293,20 @@ static int _cidr_new(lua_State *L, int index, int family, bool mask)
if (family == AF_INET6) if (family == AF_INET6)
{ {
cidr.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[12] = n;
cidr.addr.v6.s6_addr[13] = (n >> 8); cidr.addr.v6.s6_addr[13] = (n >> 8);
cidr.addr.v6.s6_addr[14] = (n >> 16); cidr.addr.v6.s6_addr[14] = (n >> 16);
cidr.addr.v6.s6_addr[15] = (n >> 24); cidr.addr.v6.s6_addr[15] = (n >> 24);
} }
else if (family == AF_INET)
{
cidr.family = AF_INET;
cidr.addr.v4.s_addr = n;
}
else else
{ {
cidr.family = AF_PACKET; cidr.family = AF_INET;
cidr.addr.mac.ether_addr_octet[2] = n; cidr.bits = 32;
cidr.addr.mac.ether_addr_octet[3] = (n >> 8); cidr.len = sizeof(cidr.addr.v4);
cidr.addr.mac.ether_addr_octet[4] = (n >> 16); cidr.addr.v4.s_addr = n;
cidr.addr.mac.ether_addr_octet[5] = (n >> 24);
} }
cidr.bits = AF_BITS(cidr.family);
} }
else else
{ {
@ -436,62 +346,6 @@ static int cidr_ipv6(lua_State *L)
return _cidr_new(L, 1, AF_INET6, true); 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) static int cidr_is4(lua_State *L)
{ {
cidr_t *p = L_checkcidr(L, 1, NULL); cidr_t *p = L_checkcidr(L, 1, NULL);
@ -570,34 +424,6 @@ static int cidr_is6linklocal(lua_State *L)
return 1; 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) static int _cidr_cmp(lua_State *L)
{ {
cidr_t *a = L_checkcidr(L, 1, NULL); cidr_t *a = L_checkcidr(L, 1, NULL);
@ -606,7 +432,7 @@ static int _cidr_cmp(lua_State *L)
if (a->family != b->family) if (a->family != b->family)
return (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) 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) 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) 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 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; b = (bits > 8) ? 8 : bits;
if (inv) if (inv)
p->addr.u8[i] |= ~((uint8_t)(0xFF << (8 - b))); p->addr.v6.s6_addr[i] |= ~((uint8_t)(0xFF << (8 - b)));
else else
p->addr.u8[i] &= (uint8_t)(0xFF << (8 - b)); p->addr.v6.s6_addr[i] &= (uint8_t)(0xFF << (8 - b));
bits -= b; bits -= b;
} }
} }
@ -681,7 +507,7 @@ static int cidr_network(lua_State *L)
return 0; return 0;
*p2 = *p1; *p2 = *p1;
p2->bits = AF_BITS(p1->family); p2->bits = (p1->family == AF_INET) ? 32 : 128;
_apply_mask(p2, bits, false); _apply_mask(p2, bits, false);
luaL_getmetatable(L, LUCI_IP_CIDR); luaL_getmetatable(L, LUCI_IP_CIDR);
@ -698,7 +524,7 @@ static int cidr_host(lua_State *L)
return 0; return 0;
*p2 = *p1; *p2 = *p1;
p2->bits = AF_BITS(p1->family); p2->bits = (p1->family == AF_INET) ? 32 : 128;
luaL_getmetatable(L, LUCI_IP_CIDR); luaL_getmetatable(L, LUCI_IP_CIDR);
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
@ -713,7 +539,7 @@ static int cidr_mask(lua_State *L)
if (!(p2 = lua_newuserdata(L, sizeof(*p2)))) if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
return 0; return 0;
p2->bits = AF_BITS(p1->family); p2->bits = (p1->family == AF_INET) ? 32 : 128;
p2->family = p1->family; p2->family = p1->family;
memset(&p2->addr.v6.s6_addr, 0xFF, sizeof(p2->addr.v6.s6_addr)); 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; cidr_t *p2;
int bits = L_checkbits(L, 2, p1); int bits = L_checkbits(L, 2, p1);
if (p1->family != AF_INET) if (p1->family == AF_INET6)
return 0; return 0;
if (!(p2 = lua_newuserdata(L, sizeof(*p2)))) if (!(p2 = lua_newuserdata(L, sizeof(*p2))))
return 0; return 0;
*p2 = *p1; *p2 = *p1;
p2->bits = AF_BITS(AF_INET); p2->bits = (p1->family == AF_INET) ? 32 : 128;
_apply_mask(p2, bits, true); _apply_mask(p2, bits, true);
luaL_getmetatable(L, LUCI_IP_CIDR); luaL_getmetatable(L, LUCI_IP_CIDR);
@ -757,7 +583,7 @@ static int cidr_mapped4(lua_State *L)
return 0; return 0;
p2->family = AF_INET; 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)); memcpy(&p2->addr.v4, p1->addr.v6.s6_addr + 12, sizeof(p2->addr.v4));
luaL_getmetatable(L, LUCI_IP_CIDR); luaL_getmetatable(L, LUCI_IP_CIDR);
@ -765,72 +591,6 @@ static int cidr_mapped4(lua_State *L)
return 1; 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) static int cidr_contains(lua_State *L)
{ {
cidr_t *p1 = L_checkcidr(L, 1, NULL); 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(&a, p1->bits, false);
_apply_mask(&b, 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); lua_pushboolean(L, rv);
return 1; return 1;
} }
#define BYTE(a, i) \ #define S6_BYTE(a, i) \
(a)->addr.u8[AF_BYTES((a)->family) - (i) - 1] (a)->addr.v6.s6_addr[sizeof((a)->addr.v6.s6_addr) - (i) - 1]
static int _cidr_add_sub(lua_State *L, bool add) 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 == 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); a = ntohl(p1->addr.v4.s_addr);
b = ntohl(p2->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); 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 else
{ {
@ -945,22 +705,22 @@ static int cidr_minhost(lua_State *L)
_apply_mask(&r, r.bits, false); _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.bits = 128;
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);
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; rest = (S6_BYTE(&r, i) + carry) > 255;
BYTE(&r, i) += carry; S6_BYTE(&r, i) += carry;
carry = rest; 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)))) if (!(p = lua_newuserdata(L, sizeof(*p))))
return 0; return 0;
@ -979,14 +739,14 @@ static int cidr_maxhost(lua_State *L)
_apply_mask(&r, r.bits, true); _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); 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)))) 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) static int cidr_tostring (lua_State *L)
{ {
char buf[INET6_ADDRSTRLEN];
cidr_t *p = L_checkcidr(L, 1, NULL); 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 * 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; uint32_t m;
if (!p->family) 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) if (!addr || p->family != family || p->bits > bits)
return true; return true;
if (family == AF_INET) if (family == AF_INET6)
{ {
m = p->bits ? htonl(~((1 << (AF_BITS(AF_INET) - p->bits)) - 1)) : 0; for (i = 0, r = p->bits; i < sizeof(struct in6_addr); i++)
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++)
{ {
b = r ? (0xFF << (8 - ((r > 8) ? 8 : r))) : 0; 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; return true;
r -= ((r > 8) ? 8 : r); 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) 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; dst = tb[RTA_DST] ? RTA_DATA(tb[RTA_DST]) : &def;
gw = tb[RTA_GATEWAY] ? RTA_DATA(tb[RTA_GATEWAY]) : NULL; 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) || if ((f->type && rt->rtm_type != f->type) ||
(f->family && rt->rtm_family != f->family) || (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->iif && iif != f->iif) ||
(f->oif && oif != f->oif) || (f->oif && oif != f->oif) ||
(f->table && table != f->table) || (f->table && table != f->table) ||
diff_prefix(rt->rtm_family, from, rt->rtm_src_len, diff_prefix(rt->rtm_family, from, rt->rtm_src_len, &f->from) ||
f->from_exact, &f->from) || diff_prefix(rt->rtm_family, dst, rt->rtm_dst_len, &f->dst) ||
diff_prefix(rt->rtm_family, dst, rt->rtm_dst_len, diff_prefix(rt->rtm_family, gw, bitlen, &f->gw) ||
f->dst_exact, &f->dst) || diff_prefix(rt->rtm_family, src, bitlen, &f->src))
diff_prefix(rt->rtm_family, gw, bitlen,
false, &f->gw) ||
diff_prefix(rt->rtm_family, src, bitlen,
false, &f->src))
goto out; goto out;
if (s->callback) 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); nlmsg_append(msg, &rtm, sizeof(rtm), 0);
if (filter->get) if (filter->get)
nla_put(msg, RTA_DST, AF_BYTES(filter->dst.family), nla_put(msg, RTA_DST, filter->dst.len, &filter->dst.addr.v6);
&filter->dst.addr.v6);
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_dump_route, &s); 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); 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; filter.dst = p;
if ((s = L_getstr(L, 1, "from_exact")) != NULL && parse_cidr(s, &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)) 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); 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; mac = tb[NDA_LLADDR] ? RTA_DATA(tb[NDA_LLADDR]) : NULL;
dst = tb[NDA_DST] ? RTA_DATA(tb[NDA_DST]) : 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) || if ((f->family && nd->ndm_family != f->family) ||
(f->iif && nd->ndm_ifindex != f->iif) || (f->iif && nd->ndm_ifindex != f->iif) ||
(f->type && !(f->type & nd->ndm_state)) || (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)) diff_macaddr(mac, &f->mac))
goto out; 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); L_setaddr(s->L, "dest", nd->ndm_family, dst, -1);
if (mac) 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++; s->index++;
@ -1463,7 +1241,7 @@ out:
static int cb_dump_link(struct nl_msg *msg, void *arg) 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 dump_state *s = arg;
struct nlmsghdr *hdr = nlmsg_hdr(msg); struct nlmsghdr *hdr = nlmsg_hdr(msg);
struct ifinfomsg *ifm = NLMSG_DATA(hdr); 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]) if (tb[IFLA_MASTER])
L_setdev(s->L, "master", tb[IFLA_MASTER]); L_setdev(s->L, "master", tb[IFLA_MASTER]);
if (tb[IFLA_ADDRESS] && nla_len(tb[IFLA_ADDRESS]) == AF_BYTES(AF_PACKET)) if (tb[IFLA_ADDRESS])
L_setaddr(s->L, "mac", AF_PACKET, nla_get_string(tb[IFLA_ADDRESS]), -1); {
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; s->pending = 0;
return NL_SKIP; return NL_SKIP;
@ -1544,18 +1333,13 @@ static const luaL_reg ip_methods[] = {
{ "new", cidr_new }, { "new", cidr_new },
{ "IPv4", cidr_ipv4 }, { "IPv4", cidr_ipv4 },
{ "IPv6", cidr_ipv6 }, { "IPv6", cidr_ipv6 },
{ "MAC", cidr_mac },
{ "checkip4", cidr_checkip4 },
{ "checkip6", cidr_checkip6 },
{ "checkmac", cidr_checkmac },
{ "route", route_get }, { "route", route_get },
{ "routes", route_dump }, { "routes", route_dump },
{ "neighbors", neighbor_dump }, { "neighbors", neighbor_dump },
{ "link", link_get }, { "link", link_get },
{ } { }
}; };
@ -1567,9 +1351,6 @@ static const luaL_reg ip_cidr_methods[] = {
{ "is6", cidr_is6 }, { "is6", cidr_is6 },
{ "is6linklocal", cidr_is6linklocal }, { "is6linklocal", cidr_is6linklocal },
{ "is6mapped4", cidr_is6mapped4 }, { "is6mapped4", cidr_is6mapped4 },
{ "ismac", cidr_ismac },
{ "ismaclocal", cidr_ismaclocal },
{ "ismacmcast", cidr_ismacmcast },
{ "lower", cidr_lower }, { "lower", cidr_lower },
{ "higher", cidr_higher }, { "higher", cidr_higher },
{ "equal", cidr_equal }, { "equal", cidr_equal },
@ -1579,9 +1360,7 @@ static const luaL_reg ip_cidr_methods[] = {
{ "mask", cidr_mask }, { "mask", cidr_mask },
{ "broadcast", cidr_broadcast }, { "broadcast", cidr_broadcast },
{ "mapped4", cidr_mapped4 }, { "mapped4", cidr_mapped4 },
{ "tomac", cidr_tomac }, { "contains", cidr_contains },
{ "tolinklocal", cidr_tolinklocal },
{ "contains", cidr_contains },
{ "add", cidr_add }, { "add", cidr_add },
{ "sub", cidr_sub }, { "sub", cidr_sub },
{ "minhost", cidr_minhost }, { "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` addr6 = luci.ip.new("fe80::221:63ff:fe75:aa17/64", 128) -- override netmask`
@see IPv4 @see IPv4
@see IPv6 @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", "255.255.255.0") -- separate netmask
addr = luci.ip.IPv4("10.24.0.1/24", 16) -- override netmask` addr = luci.ip.IPv4("10.24.0.1/24", 16) -- override netmask`
@see IPv6 @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", "ffff:ffff:ffff:ffff::")
addr6 = luci.ip.IPv6("fe80::221:63ff:fe75:aa17/64", 128) -- override netmask` addr6 = luci.ip.IPv6("fe80::221:63ff:fe75:aa17/64", 128) -- override netmask`
@see IPv4 @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. Determine the route leading to the given destination.
@class function @class function
@sort 8 @sort 4
@name route @name route
@param address A `luci.ip.cidr` instance or a string containing @param address A `luci.ip.cidr` instance or a string containing
a valid IPv4 or IPv6 range as specified by `luci.ip.new()`. 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. Fetch all routes, optionally matching the given criteria.
@class function @class function
@sort 9 @sort 5
@name routes @name routes
@param filter <p>Table containing one or more of the possible filter @param filter <p>Table containing one or more of the possible filter
critera described below (optional)</p><table> critera described below (optional)</p><table>
@ -360,7 +258,7 @@ end`</li>
---[[ ---[[
Fetches entries from the IPv4 ARP and IPv6 neighbour kernel table Fetches entries from the IPv4 ARP and IPv6 neighbour kernel table
@class function @class function
@sort 10 @sort 6
@name neighbors @name neighbors
@param filter <p>Table containing one or more of the possible filter @param filter <p>Table containing one or more of the possible filter
critera described below (optional)</p><table> critera described below (optional)</p><table>
@ -408,7 +306,7 @@ A neighbour entry is a table containing the following fields:
</tr> </tr>
<tr> <tr>
<td>`mac`</td> <td>`mac`</td>
<td>MAC address `luci.ip.cidr` instance</td> <td>String containing the associated MAC address</td>
</tr> </tr>
<tr> <tr>
<td>`router`</td> <td>`router`</td>
@ -469,7 +367,7 @@ end)`</li>
---[[ ---[[
Fetch basic device information Fetch basic device information
@class function @class function
@sort 11 @sort 7
@name link @name link
@param device String containing the network device to query @param device String containing the network device to query
@return If the given interface is found, a table containing the fields @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>
<tr> <tr>
<td>`mac`</td> <td>`mac`</td>
<td>MAC address `luci.ip.cidr` instance representing the device ethernet <td>String containing the link local address of the device in
address</td> dotted hex notation</td>
</tr> </tr>
</table> </table>
@usage <ul> @usage <ul>
@ -532,7 +430,6 @@ Checks whether the CIDR instance is an IPv4 address range
@sort 1 @sort 1
@name cidr.is4 @name cidr.is4
@see cidr.is6 @see cidr.is6
@see cidr.ismac
@return `true` if the CIDR is an IPv4 range, else `false` @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 @sort 4
@name cidr.is6 @name cidr.is6
@see cidr.is4 @see cidr.is4
@see cidr.ismac
@return `true` if the CIDR is an IPv6 range, else `false` @return `true` if the CIDR is an IPv6 range, else `false`
]] ]]
@ -605,52 +501,14 @@ if addr:is6mapped4() then
end` 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. Checks whether this CIDR instance is lower than the given argument.
The comparisation follows these rules: The comparisation follows these rules:
<ul><li>An IPv4 address is always lower than an IPv6 address and IPv6 addresses <ul><li>An IPv4 address is always lower than an IPv6 address</li>
are considered lower than MAC addresses</li>
<li>Prefix sizes are ignored</li></ul> <li>Prefix sizes are ignored</li></ul>
@class function @class function
@sort 10 @sort 7
@name cidr.lower @name cidr.lower
@param addr A `luci.ip.cidr` instance or a string convertable by @param addr A `luci.ip.cidr` instance or a string convertable by
`luci.ip.new()` to compare against. `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(addr)) -- false
print(addr:lower("10.10.10.10/24")) -- false print(addr:lower("10.10.10.10/24")) -- false
print(addr:lower(luci.ip.new("::1"))) -- true 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("192.168.200.1"))) -- true`
print(addr:lower(luci.ip.new("00:14:22:01:23:45"))) -- true`
@see cidr.higher @see cidr.higher
@see cidr.equal @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. Checks whether this CIDR instance is higher than the given argument.
The comparisation follows these rules: The comparisation follows these rules:
<ul><li>An IPv4 address is always lower than an IPv6 address and IPv6 addresses <ul><li>An IPv4 address is always lower than an IPv6 address</li>
are considered lower than MAC addresses</li>
<li>Prefix sizes are ignored</li></ul> <li>Prefix sizes are ignored</li></ul>
@class function @class function
@sort 11 @sort 8
@name cidr.higher @name cidr.higher
@param addr A `luci.ip.cidr` instance or a string convertable by @param addr A `luci.ip.cidr` instance or a string convertable by
`luci.ip.new()` to compare against. `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(addr)) -- false
print(addr:higher("10.10.10.10/24")) -- true print(addr:higher("10.10.10.10/24")) -- true
print(addr:higher(luci.ip.new("::1"))) -- false 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("192.168.200.1"))) -- false`
print(addr:higher(luci.ip.new("00:14:22:01:23:45"))) -- false`
@see cidr.lower @see cidr.lower
@see cidr.equal @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. Checks whether this CIDR instance is equal to the given argument.
@class function @class function
@sort 12 @sort 9
@name cidr.equal @name cidr.equal
@param addr A `luci.ip.cidr` instance or a string convertable by @param addr A `luci.ip.cidr` instance or a string convertable by
`luci.ip.new()` to compare against. `luci.ip.new()` to compare against.
@ -707,11 +562,7 @@ print(addr:equal(luci.ip.new("::1"))) -- false
local addr6 = luci.ip.new("::1") local addr6 = luci.ip.new("::1")
print(addr6:equal("0:0:0:0:0:0:0:1/64")) -- true 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 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`
@see cidr.lower @see cidr.lower
@see cidr.higher @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. else the current prefix size is returned.
@class function @class function
@sort 13 @sort 10
@name cidr.prefix @name cidr.prefix
@param mask Either a number containing the number of bits (`0..32` @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 for IPv4, `0..128` for IPv6) or a string containing a valid
containing a valid netmask (optional) netmask (optional)
@return Bit count of the current prefix size @return Bit count of the current prefix size
@usage `local range = luci.ip.new("192.168.1.1/255.255.255.0") @usage `local range = luci.ip.new("192.168.1.1/255.255.255.0")
print(range:prefix()) -- 24 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. optional mask parameter.
@class function @class function
@sort 14 @sort 11
@name cidr.network @name cidr.network
@param mask Either a number containing the number of bits (`0..32` @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 for IPv4, `0..128` for IPv6) or a string containing a valid
containing a valid netmask (optional) netmask (optional)
@return CIDR instance representing the network address @return CIDR instance representing the network address
@usage `local range = luci.ip.new("192.168.62.243/255.255.0.0") @usage `local range = luci.ip.new("192.168.62.243/255.255.0.0")
print(range:network()) -- "192.168.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. Derive host address of CIDR instance.
This function essentially constructs a copy of this CIDR with the prefix size 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 @class function
@sort 15 @sort 12
@name cidr.host @name cidr.host
@return CIDR instance representing the host address @return CIDR instance representing the host address
@usage `local range = luci.ip.new("172.19.37.45/16") @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. prefix size can be overridden by the optional mask parameter.
@class function @class function
@sort 16 @sort 13
@name cidr.mask @name cidr.mask
@param mask Either a number containing the number of bits (`0..32` @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 for IPv4, `0..128` for IPv6) or a string containing a valid
containing a valid netmask (optional) netmask (optional)
@return CIDR instance representing the netmask @return CIDR instance representing the netmask
@usage `local range = luci.ip.new("172.19.37.45/16") @usage `local range = luci.ip.new("172.19.37.45/16")
print(range:mask()) -- "255.255.0.0" 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. Constructs a CIDR instance representing the broadcast address of this instance.
The used prefix size can be overridden by the optional mask parameter. 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 This function has no effect on IPv6 instances, it will return nothing in this
nothing in this case. case.
@class function @class function
@sort 17 @sort 14
@name cidr.broadcast @name cidr.broadcast
@param mask Either a number containing the number of bits (`0..32` for IPv4) or @param mask Either a number containing the number of bits (`0..32`
a string containing a valid netmask (optional) 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 @return Return a new CIDR instance representing the broadcast address if this
instance is an IPv4 range, else return nothing. instance is an IPv4 range, else return nothing.
@usage `local range = luci.ip.new("172.19.37.45/16") @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 Constructs a CIDR instance representing the IPv4 address of the IPv6 mapped
IPv4 address in this instance. IPv4 address in this instance.
This function has no effect on IPv4 instances, MAC address instances or IPv6 This function has no effect on IPv4 instances or IPv6 instances which are not a
instances which are not a mapped address, it will return nothing in this case. mapped address, it will return nothing in this case.
@class function @class function
@sort 18 @sort 15
@name cidr.mapped4 @name cidr.mapped4
@return Return a new CIDR instance representing the IPv4 address if this @return Return a new CIDR instance representing the IPv4 address if this
instance is an IPv6 mapped IPv4 address, else return nothing. 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"` 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. Test whether CIDR contains given range.
@class function @class function
@sort 21 @sort 16
@name cidr.contains @name cidr.contains
@param addr A `luci.ip.cidr` instance or a string convertable by @param addr A `luci.ip.cidr` instance or a string convertable by
`luci.ip.new()` to test. `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") local range6 = luci.ip.new("fe80::/10")
print(range6:contains("fe80::221:63f:fe75:aa17/64")) -- true print(range6:contains("fe80::221:63f:fe75:aa17/64")) -- true
print(range6:contains("fd9b:6b3:c5:0:221:63f:fe75:aa17/64")) -- false 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`
]] ]]
---[[ ---[[
@ -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. address space, the result is set to the highest possible address.
@class function @class function
@sort 22 @sort 17
@name cidr.add @name cidr.add
@param amount A numeric value between 0 and 0xFFFFFFFF, a @param amount A numeric value between 0 and 0xFFFFFFFF, a
`luci.ip.cidr` instance or a string convertable by `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 this instance plus the added amount or the highest possible address if
the addition overflowed the available address space.</li></ul> the addition overflowed the available address space.</li></ul>
@usage `local addr = luci.ip.new("192.168.1.1/24") @usage `local addr = luci.ip.new("192.168.1.1/24")
print(addr:add(250)) -- "192.168.1.251/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("0.0.99.0")) -- "192.168.100.1/24"
addr:add(256, true) -- true addr:add(256, true) -- true
print(addr) -- "192.168.2.1/24 print(addr) -- "192.168.2.1/24
addr:add("255.0.0.0", true) -- false (overflow) addr:add("255.0.0.0", true) -- false (overflow)
print(addr) -- "255.255.255.255/24 print(addr) -- "255.255.255.255/24
local addr6 = luci.ip.new("fe80::221:63f:fe75:aa17/64") local addr6 = luci.ip.new("fe80::221:63f:fe75:aa17/64")
print(addr6:add(256)) -- "fe80::221:63f:fe75:ab17/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("::ffff:0")) -- "fe80::221:640:fe74:aa17/64"
addr6:add(256, true) -- true addr:add(256, true) -- true
print(addr6) -- "fe80::221:63f:fe75:ab17/64 print(addr) -- "fe80::221:63f:fe75:ab17/64
addr6:add("ffff::", true) -- false (overflow) addr:add("ffff::", true) -- false (overflow)
print(addr6) -- "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64" print(addr) -- "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"`
]] ]]
---[[ ---[[
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. possible address is returned.
@class function @class function
@sort 23 @sort 18
@name cidr.sub @name cidr.sub
@param amount A numeric value between 0 and 0xFFFFFFFF, a @param amount A numeric value between 0 and 0xFFFFFFFF, a
`luci.ip.cidr` instance or a string convertable by `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 @param inplace If `true`, modify this instance instead of returning
a new derived CIDR instance. a new derived CIDR instance.
@return <ul> @return <ul>
<li>When subtracting inplace: Return `true` if the subtraction <li>When substracting inplace: Return `true` if the substraction
succeeded or `false` when the subtraction underflowed.</li> succeded or `false` when the substraction underflowed.</li>
<li>When deriving new CIDR: Return new instance representing the value of <li>When deriving new CIDR: Return new instance representing the value of
this instance minus the subtracted amount or the lowest address if this instance minus the substracted amount or the lowest address if
the subtraction underflowed.</li></ul> the substraction underflowed.</li></ul>
@usage `local addr = luci.ip.new("192.168.1.1/24") @usage `local addr = luci.ip.new("192.168.1.1/24")
print(addr:sub(256)) -- "192.168.0.1/24" print(addr:sub(256)) -- "192.168.0.1/24"
print(addr:sub("0.168.0.0")) -- "192.0.1.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" print(addr) -- "fe80::221:63f:fe75:a917/64"
addr:sub("ffff::", true) -- false (underflow) addr:sub("ffff::", true) -- false (underflow)
print(addr) -- "::/64" 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"`
]] ]]
---[[ ---[[
Calculate the lowest possible host address within this CIDR instance. Calculate the lowest possible host address within this CIDR instance.
@class function @class function
@sort 24 @sort 19
@name cidr.minhost @name cidr.minhost
@return Returns a new CIDR instance representing the lowest host address @return Returns a new CIDR instance representing the lowest host address
within this range. within this range.
@ -1005,17 +797,14 @@ Calculate the lowest possible host address within this CIDR instance.
print(addr:minhost()) -- "192.168.123.1" print(addr:minhost()) -- "192.168.123.1"
local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64") local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64")
print(addr6:minhost()) -- "fd9b:62b3:9cc5::1" 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"`
]] ]]
---[[ ---[[
Calculate the highest possible host address within this CIDR instance. Calculate the highest possible host address within this CIDR instance.
@class function @class function
@sort 25 @sort 20
@name cidr.maxhost @name cidr.maxhost
@return Returns a new CIDR instance representing the highest host address @return Returns a new CIDR instance representing the highest host address
within this range. 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) print(addr:maxhost()) -- "192.168.123.254" (.255 is broadcast)
local addr6 = luci.ip.new("fd9b:62b3:9cc5:0:221:63ff:fe75:aa17/64") 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" 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"`
]] ]]
---[[ ---[[
Convert CIDR instance into string representation. Convert CIDR instance into string representation.
If the prefix size of instance is less than 32 for IPv4, 128 for IPv6 or 48 for If the prefix size of instance is less than 32 for IPv4 or 128 for IPv6, the
MACs, the address is returned in the form "address/prefix" otherwise just address is returned in the form "address/prefix" otherwise just "address".
"address".
It is usually not required to call this function directly as CIDR objects It is usually not required to call this function directly as CIDR objects
define it as __tostring function in the associated metatable. define it as __tostring function in the associated metatable.
@class function @class function
@sort 26 @sort 21
@name cidr.string @name cidr.string
@return Returns a string representing the range or address of this CIDR instance @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 -- <br />In general all functions are namend and behave like their POSIX API
-- counterparts - where applicable - applying the following rules: -- counterparts - where applicable - applying the following rules:
-- <ul> -- <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 ( -- prefixes or suffixes - especially when placed in an object-context (
-- lockf -> File:lock, fsync -> File:sync, dup2 -> dup, ...)</li> -- lockf -> File:lock, fsync -> File:sync, dup2 -> dup, ...)</li>
-- <li>If you are unclear about the behaviour of a function you should consult -- <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 -- <li>If the name is significantly different from the POSIX-function, the
-- underlying function(s) are stated in the documentation.</li> -- underlying function(s) are stated in the documentation.</li>
-- <li>Parameters should reflect those of the C-API, buffer length arguments and -- <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 -- <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 -- 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"), -- (pid, &s, WNOHANG | WUNTRACED) -> waitpid(pid, "nohang", "untraced"),
-- getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) -> -- getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) ->
-- Socket:getopt("socket", "reuseaddr"), etc.) </li> -- Socket:getopt("socket", "reuseaddr"), etc.) </li>

View File

@ -71,7 +71,7 @@ module "nixio.Socket"
--- Send a message on the socket. --- Send a message on the socket.
-- This function is identical to sendto except for the missing destination -- 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 -- @class function
-- @name Socket.send -- @name Socket.send
-- @param buffer Buffer holding the data to be written. -- @param buffer Buffer holding the data to be written.
@ -167,4 +167,4 @@ module "nixio.Socket"
-- "mtu" (IP, IPv6), "hdrincl" (IP), "multicast_ttl" (IP), "multicast_loop" -- "mtu" (IP, IPv6), "hdrincl" (IP), "multicast_ttl" (IP), "multicast_loop"
-- (IP, IPv6), "multicast_if" (IP, IPv6), "v6only" (IPv6), "multicast_hops" -- (IP, IPv6), "multicast_if" (IP, IPv6), "v6only" (IPv6), "multicast_hops"
-- (IPv6), "add_membership" (IP, IPv6), "drop_membership" (IP, IPv6)] -- (IPv6), "add_membership" (IP, IPv6), "drop_membership" (IP, IPv6)]
-- @return Value -- @return Value

View File

@ -24,15 +24,15 @@ module "nixio.UnifiedIO"
-- @class function -- @class function
-- @name UnifiedIO.readall -- @name UnifiedIO.readall
-- @usage This function uses the low-level read function of the descriptor. -- @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 -- that can be read before an end-of-file, end-of-stream, connection shutdown
-- or similar happens. -- or similar happens.
-- @usage If the descriptor is non-blocking this function may fail with EAGAIN. -- @usage If the descriptor is non-blocking this function may fail with EAGAIN.
-- @param length Bytes to read (optional) -- @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 code -
-- @return - reserved for error message - -- @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. --- Write a block of data and wait until all data is written.
-- @class function -- @class function
@ -40,10 +40,10 @@ module "nixio.UnifiedIO"
-- @usage This function uses the low-level write function of the descriptor. -- @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. -- @usage If the descriptor is non-blocking this function may fail with EAGAIN.
-- @param block Bytes to write -- @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 code -
-- @return - reserved for error message - -- @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. --- Create a line-based iterator.
-- Lines may end with either \n or \r\n, these control chars are not included -- 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 -- 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 -- you can pass "true" to the iterator which will flush the buffer
-- and return the bufferd data. -- 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). -- buffersize (8192B by default).
-- @usage If the descriptor is non-blocking the iterator may fail with EAGAIN. -- @usage If the descriptor is non-blocking the iterator may fail with EAGAIN.
-- @usage The iterator can be used as an LTN12 source. -- @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 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, -- @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. -- 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. -- 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 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. -- @usage If the descriptor is non-blocking the iterator may fail with EAGAIN.
@ -94,15 +94,15 @@ module "nixio.UnifiedIO"
-- @name UnifiedIO.copy -- @name UnifiedIO.copy
-- @usage This function uses the blocksource function of the source descriptor -- @usage This function uses the blocksource function of the source descriptor
-- and the sink function of the target 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. -- 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. -- @usage If the descriptor is non-blocking the function may fail with EAGAIN.
-- @param fdout Target Descriptor -- @param fdout Target Descriptor
-- @param size Bytes to copy (optional) -- @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 code -
-- @return - reserved for error message - -- @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 --- Copy data from the current descriptor to another one using kernel-space
-- copying if possible. -- copying if possible.
@ -111,19 +111,19 @@ module "nixio.UnifiedIO"
-- @usage This function uses the sendfile() syscall to copy the data or the -- @usage This function uses the sendfile() syscall to copy the data or the
-- blocksource function of the source descriptor and the sink function -- blocksource function of the source descriptor and the sink function
-- of the target descriptor as a fallback mechanism. -- 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. -- 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. -- @usage If the descriptor is non-blocking the function may fail with EAGAIN.
-- @param fdout Target Descriptor -- @param fdout Target Descriptor
-- @param size Bytes to copy (optional) -- @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 code -
-- @return - reserved for error message - -- @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. --- Close the descriptor.
-- @class function -- @class function
-- @name UnifiedIO.close -- @name UnifiedIO.close
-- @usage If the descriptor is a TLS-socket the underlying descriptor is -- @usage If the descriptor is a TLS-socket the underlying descriptor is
-- closed without touching the TLS connection. -- closed without touching the TLS connection.
-- @return true -- @return true

View File

@ -47,7 +47,7 @@ module "nixio.fs"
-- @name nixio.fs.rename -- @name nixio.fs.rename
-- @param src Source path -- @param src Source path
-- @param dest Destination 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 -- @return true
--- Remove an empty directory. --- Remove an empty directory.
@ -262,4 +262,4 @@ module "nixio.fs"
-- omit the basename even if source and destination basename are equal. -- omit the basename even if source and destination basename are equal.
-- @param src Source path -- @param src Source path
-- @param dest Destination path -- @param dest Destination path
-- @return true -- @return true

View File

@ -118,7 +118,7 @@ module "nixio"
-- @param flag1 First Flag ["append", "creat", "excl", "nonblock", "ndelay", -- @param flag1 First Flag ["append", "creat", "excl", "nonblock", "ndelay",
-- "sync", "trunc", "rdonly", "wronly", "rdwr"] -- "sync", "trunc", "rdonly", "wronly", "rdwr"]
-- @param ... More Flags [-"-] -- @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. --- Duplicate a file descriptor.
-- @class function -- @class function
@ -167,7 +167,7 @@ module "nixio"
--- Wait for some event on a file descriptor. --- Wait for some event on a file descriptor.
-- poll() sets the revents-field of the tables provided by fds to a bitfield -- 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 -- @class function
-- @usage This function works in-place on the provided table and only -- @usage This function works in-place on the provided table and only
-- writes the revents field, you can use other fields on your demand. -- writes the revents field, you can use other fields on your demand.
@ -303,7 +303,7 @@ module "nixio"
--- Set or unset a environment variable. --- Set or unset a environment variable.
-- @class function -- @class function
-- @name nixio.setenv -- @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 variable Variable
-- @param value Value (optional) -- @param value Value (optional)
-- @return true -- @return true

23
luci.mk
View File

@ -7,7 +7,7 @@
LUCI_NAME?=$(notdir ${CURDIR}) LUCI_NAME?=$(notdir ${CURDIR})
LUCI_TYPE?=$(word 2,$(subst -, ,$(LUCI_NAME))) LUCI_TYPE?=$(word 2,$(subst -, ,$(LUCI_NAME)))
LUCI_BASENAME?=$(patsubst luci-$(LUCI_TYPE)-%,%,$(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_DEFAULTS:=$(notdir $(wildcard ${CURDIR}/root/etc/uci-defaults/*))
LUCI_PKGARCH?=$(if $(realpath src/Makefile),,all) 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.tr=Türkçe (Turkish)
LUCI_LANG.uk=украї́нська (Ukrainian) LUCI_LANG.uk=украї́нська (Ukrainian)
LUCI_LANG.vi=Tiếng Việt (Vietnamese) LUCI_LANG.vi=Tiếng Việt (Vietnamese)
LUCI_LANG.zh-cn=中文 (Chinese) LUCI_LANG.zh-cn=简体中文 (Simplified Chinese)
LUCI_LANG.zh-tw=臺灣華語 (Taiwanese) LUCI_LANG.zh-tw=繁体中文 (Traditional Chinese)
# Submenu titles # Submenu titles
LUCI_MENU.col=1. Collections 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)) SUBMENU:=$(if $(LUCI_MENU.$(LUCI_TYPE)),$(LUCI_MENU.$(LUCI_TYPE)),$(LUCI_MENU.app))
TITLE:=$(if $(LUCI_TITLE),$(LUCI_TITLE),LuCI $(LUCI_NAME) $(LUCI_TYPE)) TITLE:=$(if $(LUCI_TITLE),$(LUCI_TITLE),LuCI $(LUCI_NAME) $(LUCI_TYPE))
DEPENDS:=$(LUCI_DEPENDS) DEPENDS:=$(LUCI_DEPENDS)
$(if $(LUCI_EXTRA_DEPENDS),EXTRA_DEPENDS:=$(LUCI_EXTRA_DEPENDS))
$(if $(LUCI_PKGARCH),PKGARCH:=$(LUCI_PKGARCH)) $(if $(LUCI_PKGARCH),PKGARCH:=$(LUCI_PKGARCH))
endef endef
@ -111,13 +110,13 @@ ifeq ($(PKG_NAME),luci-base)
define Package/luci-base/config define Package/luci-base/config
config LUCI_SRCDIET config LUCI_SRCDIET
bool "Minify Lua sources" bool "Minify Lua sources"
default n default y
menu "Translations"$(foreach lang,$(LUCI_LANGUAGES), menu "Translations"$(foreach lang,$(LUCI_LANGUAGES),
config LUCI_LANG_$(lang) 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 endmenu
endef endef
endif endif
@ -137,7 +136,7 @@ endef
ifneq ($(wildcard ${CURDIR}/src/Makefile),) ifneq ($(wildcard ${CURDIR}/src/Makefile),)
MAKE_PATH := src/ 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 define Build/Compile
$(call Build/Compile/Default,clean compile) $(call Build/Compile/Default,clean compile)
@ -158,6 +157,14 @@ define SrcDiet
done done
endef 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 define SubstituteVersion
$(FIND) $(1) -type f -name '*.htm' | while read src; do \ $(FIND) $(1) -type f -name '*.htm' | while read src; do \
$(SED) 's/<%# *\([^ ]*\)PKG_VERSION *%>/\1$(PKG_VERSION)/g' \ $(SED) 's/<%# *\([^ ]*\)PKG_VERSION *%>/\1$(PKG_VERSION)/g' \

View File

@ -12,11 +12,11 @@ LUCI_TYPE:=mod
LUCI_BASENAME:=base LUCI_BASENAME:=base
LUCI_TITLE:=LuCI core libraries 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:=LuaSrcDiet-0.12.1.tar.bz2
PKG_SOURCE_URL:=https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/luasrcdiet 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 PKG_LICENSE:=Apache-2.0
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/LuaSrcDiet-0.12.1 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 define Package/luci-base/conffiles
/etc/luci-uploads /etc/luci-uploads
/etc/config/luci /etc/config/luci
/etc/config/ucitrack
endef endef
include ../../luci.mk include ../../luci.mk

View File

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

View File

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

View File

@ -132,50 +132,43 @@ function ip6prefix(val)
return ( val and val >= 0 and val <= 128 ) return ( val and val >= 0 and val <= 128 )
end 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) function ipmask(val)
return ipmask4(val) or ipmask6(val) return ipmask4(val) or ipmask6(val)
end end
function ipmask4(val) 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 end
function ipmask6(val) 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 end
function ip6hostid(val) function ip6hostid(val)
if val == "eui64" or val == "random" then if val and val:match("^[a-fA-F0-9:]+$") and (#val > 2) then
return true return (ip6addr("2001:db8:0:0" .. val) or ip6addr("2001:db8:0:0:" .. val))
else
local addr = ip.IPv6(val)
if addr and addr:prefix() == 128 and addr:lower("::1:0:0:0:0") then
return true
end
end end
return false return false
@ -196,16 +189,32 @@ function portrange(val)
end end
function macaddr(val) 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 end
function hostname(val, strict) function hostname(val)
if val and (#val < 254) and ( if val and (#val < 254) and (
val:match("^[a-zA-Z_]+$") or val:match("^[a-zA-Z_]+$") or
(val:match("^[a-zA-Z0-9_][a-zA-Z0-9_%-%.]*[a-zA-Z0-9]$") and (val:match("^[a-zA-Z0-9_][a-zA-Z0-9_%-%.]*[a-zA-Z0-9]$") and
val:match("[^0-9%.]")) val:match("[^0-9%.]"))
) then ) then
return (not strict or not val:match("^_")) return true
end end
return false return false
end end

View File

@ -75,16 +75,11 @@ function error404(message)
http.status(404, "Not Found") http.status(404, "Not Found")
message = message or "Not Found" message = message or "Not Found"
local function render() require("luci.template")
local template = require "luci.template" if not util.copcall(luci.template.render, "error404") then
template.render("error404")
end
if not util.copcall(render) then
http.prepare_content("text/plain") http.prepare_content("text/plain")
http.write(message) http.write(message)
end end
return false return false
end end
@ -118,8 +113,7 @@ function httpdispatch(request, prefix)
end end
end end
local node for node in pathinfo:gmatch("[^/]+") do
for node in pathinfo:gmatch("[^/%z]+") do
r[#r+1] = node r[#r+1] = node
end end
@ -142,7 +136,8 @@ local function require_post_security(target)
if (type(required_val) == "string" and if (type(required_val) == "string" and
request_val ~= required_val) or request_val ~= required_val) or
(required_val == true and request_val == nil) (required_val == true and
(request_val == nil or request_val == ""))
then then
return false return false
end end
@ -196,9 +191,6 @@ local function session_setup(user, pass, allowed_users)
timeout = tonumber(luci.config.sauth.sessiontime) timeout = tonumber(luci.config.sauth.sessiontime)
}) })
local rp = context.requestpath
and table.concat(context.requestpath, "/") or ""
if type(login) == "table" and if type(login) == "table" and
type(login.ubus_rpc_session) == "string" type(login.ubus_rpc_session) == "string"
then then
@ -207,14 +199,8 @@ local function session_setup(user, pass, allowed_users)
values = { token = sys.uniqueid(16) } 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) return session_retrieve(login.ubus_rpc_session)
end end
io.stderr:write("luci: failed login on /%s for %s from %s\n"
%{ rp, user, http.getenv("REMOTE_ADDR") or "?" })
end end
return nil, nil return nil, nil
@ -233,19 +219,10 @@ function dispatch(request)
local lang = conf.main.lang or "auto" local lang = conf.main.lang or "auto"
if lang == "auto" then if lang == "auto" then
local aclang = http.getenv("HTTP_ACCEPT_LANGUAGE") or "" local aclang = http.getenv("HTTP_ACCEPT_LANGUAGE") or ""
for aclang in aclang:gmatch("[%w_-]+") do for lpat in aclang:gmatch("[%w-]+") do
local country, culture = aclang:match("^([a-z][a-z])[_-]([a-zA-Z][a-zA-Z])$") lpat = lpat and lpat:gsub("-", "_")
if country and culture then if conf.languages[lpat] then
local cc = "%s_%s" %{ country, culture:lower() } lang = lpat
if conf.languages[cc] then
lang = cc
break
elseif conf.languages[country] then
lang = country
break
end
elseif conf.languages[aclang] then
lang = aclang
break break
end end
end end
@ -351,23 +328,15 @@ function dispatch(request)
ifattr = function(...) return _ifattr(...) end; ifattr = function(...) return _ifattr(...) end;
attr = function(...) return _ifattr(true, ...) end; attr = function(...) return _ifattr(true, ...) end;
url = build_url; url = build_url;
}, {__index=function(tbl, key) }, {__index=function(table, key)
if key == "controller" then if key == "controller" then
return build_url() return build_url()
elseif key == "REQUEST_URI" then elseif key == "REQUEST_URI" then
return build_url(unpack(ctx.requestpath)) 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 elseif key == "token" then
return ctx.authtoken return ctx.authtoken
else else
return rawget(tbl, key) or _G[key] return rawget(table, key) or _G[key]
end end
end}) end})
end end
@ -380,7 +349,7 @@ function dispatch(request)
"https://github.com/openwrt/luci/issues" "https://github.com/openwrt/luci/issues"
) )
if track.sysauth and not ctx.authsession then if track.sysauth then
local authen = track.sysauth_authenticator local authen = track.sysauth_authenticator
local _, sid, sdat, default_user, allowed_users local _, sid, sdat, default_user, allowed_users
@ -428,9 +397,7 @@ function dispatch(request)
return return
end end
http.header("Set-Cookie", 'sysauth=%s; path=%s; HttpOnly%s' %{ http.header("Set-Cookie", 'sysauth=%s; path=%s' %{ sid, build_url() })
sid, build_url(), http.getenv("HTTPS") == "on" and "; secure" or ""
})
http.redirect(build_url(unpack(ctx.requestpath))) http.redirect(build_url(unpack(ctx.requestpath)))
end end
@ -444,13 +411,6 @@ function dispatch(request)
ctx.authuser = sdat.username ctx.authuser = sdat.username
end 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 c and require_post_security(c.target) then
if not test_post_security(c) then if not test_post_security(c) then
return return
@ -672,23 +632,6 @@ function node(...)
return c return c
end 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) function _create_node(path)
if #path == 0 then if #path == 0 then
return context.tree return context.tree
@ -830,16 +773,7 @@ local function _cbi(self, ...)
local state = nil local state = nil
local i, res
for i, res in ipairs(maps) do 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 res.flow = config
local cstate = res:parse() local cstate = res:parse()
if cstate and (not state or cstate < state) then if cstate and (not state or cstate < state) then
@ -932,7 +866,7 @@ end
function cbi(model, config) function cbi(model, config)
return { return {
type = "cbi", type = "cbi",
post = { ["cbi.submit"] = true }, post = { ["cbi.submit"] = "1" },
config = config, config = config,
model = model, model = model,
target = _cbi target = _cbi
@ -960,7 +894,6 @@ local function _form(self, ...)
local maps = luci.cbi.load(self.model, ...) local maps = luci.cbi.load(self.model, ...)
local state = nil local state = nil
local i, res
for i, res in ipairs(maps) do for i, res in ipairs(maps) do
local cstate = res:parse() local cstate = res:parse()
if cstate and (not state or cstate < state) then if cstate and (not state or cstate < state) then
@ -979,7 +912,7 @@ end
function form(model) function form(model)
return { return {
type = "cbi", type = "cbi",
post = { ["cbi.submit"] = true }, post = { ["cbi.submit"] = "1" },
model = model, model = model,
target = _form 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 Fetch or create a dispatching node without setting the target module or
enabling the node.
enabling the node.
@class function @class function
@name get @name get
@param ... Virtual path @param ... Virtual path
@ -133,15 +133,6 @@ Fetch or create a new dispatching node.
@return Dispatching tree 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 Alias the first (lowest order) page automatically

View File

@ -1,21 +1,18 @@
-- Copyright 2008 Steven Barth <steven@midlink.org> -- 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. -- 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 util = require "luci.util"
local string = require "string"
local coroutine = require "coroutine" local coroutine = require "coroutine"
local table = require "table" 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 = local ipairs, pairs, next, type, tostring, error =
table, ipairs, pairs, type, tostring, tonumber, error ipairs, pairs, next, type, tostring, error
module "luci.http" module "luci.http"
HTTP_MAX_CONTENT = 1024*100 -- 100 kB maximum content size
context = util.threadlocal() context = util.threadlocal()
Request = util.class() Request = util.class()
@ -31,7 +28,7 @@ function Request.__init__(self, env, sourcein, sinkerr)
self.message = { self.message = {
env = env, env = env,
headers = {}, headers = {},
params = urldecode_params(env.QUERY_STRING or ""), params = protocol.urldecode_params(env.QUERY_STRING or ""),
} }
self.parsed_input = false self.parsed_input = false
@ -76,7 +73,10 @@ function Request.content(self)
end end
function Request.getcookie(self, name) 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 end
function Request.getenv(self, name) function Request.getenv(self, name)
@ -90,34 +90,40 @@ end
function Request.setfilehandler(self, callback) function Request.setfilehandler(self, callback)
self.filehandler = callback self.filehandler = callback
if not self.parsed_input then -- If input has already been parsed then any files are either in temporary files
return -- or are in self.message.params[key]
end if self.parsed_input then
for param, value in pairs(self.message.params) do
-- If input has already been parsed then uploads are stored as unlinked repeat
-- temporary files pointed to by open file handles in the parameter -- We're only interested in files
-- value table. Loop all params, and invoke the file callback for any if (not value["file"]) then break end
-- param with an open file handle. -- If we were able to write to temporary file
local name, value if (value["fd"]) then
for name, value in pairs(self.message.params) do fd = value["fd"]
if type(value) == "table" then local eof = false
while value.fd do repeat
local data = value.fd:read(1024) filedata = fd:read(1024)
local eof = (not data or data == "") if (filedata:len() < 1024) then
eof = true
callback(value, data, eof) end
callback({ name=value["name"], file=value["file"] }, filedata, eof)
if eof then until (eof)
value.fd:close() fd:close()
value.fd = nil 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
end end
until true
end end
end end
end end
function Request._parse_input(self) function Request._parse_input(self)
parse_message_body( protocol.parse_message_body(
self.input, self.input,
self.message, self.message,
self.filehandler self.filehandler
@ -216,17 +222,10 @@ function write(content, src_err)
end end
if not context.headers["cache-control"] then if not context.headers["cache-control"] then
header("Cache-Control", "no-cache") header("Cache-Control", "no-cache")
header("Pragma", "no-cache")
header("Expires", "0") header("Expires", "0")
end 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 context.eoh = true
coroutine.yield(3) coroutine.yield(3)
@ -248,307 +247,23 @@ function redirect(url)
end end
function build_querystring(q) function build_querystring(q)
local s, n, k, v = {}, 1, nil, nil local s = { "?" }
for k, v in pairs(q) do for k, v in pairs(q) do
s[n+0] = (n == 1) and "?" or "&" if #s > 1 then s[#s+1] = "&" end
s[n+1] = util.urlencode(k)
s[n+2] = "=" s[#s+1] = urldecode(k)
s[n+3] = util.urlencode(v) s[#s+1] = "="
n = n + 4 s[#s+1] = urldecode(v)
end end
return table.concat(s, "") return table.concat(s, "")
end end
urldecode = util.urldecode urldecode = protocol.urldecode
urlencode = util.urlencode urlencode = protocol.urlencode
function write_json(x) function write_json(x)
util.serialize_json(x, write) util.serialize_json(x, write)
end 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. Close the HTTP-Connection.
@class function
@name close @class function
@name close
]] ]]
---[[ ---[[
Return the request content if the request was of unknown type. Return the request content if the request was of unknown type.
@class function @class function
@name content @name content
@return HTTP request body @return HTTP request body
@return HTTP request body length @return HTTP request body length
]] ]]
---[[ ---[[
Get a certain HTTP input value or a table of all input values. Get a certain HTTP input value or a table of all input values.
@class function @class function
@name formvalue @name formvalue
@param name Name of the GET or POST variable to fetch @param name Name of the GET or POST variable to fetch
@param noparse Don't parse POST data before getting the value @param noparse Don't parse POST data before getting the value
@return HTTP input value or table of all input 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. Get a table of all HTTP input values with a certain prefix.
@class function @class function
@name formvaluetable @name formvaluetable
@param prefix Prefix @param prefix Prefix
@return Table of all HTTP input values with given 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. Get the value of a certain HTTP-Cookie.
@class function @class function
@name getcookie @name getcookie
@param name Cookie Name @param name Cookie Name
@return String containing cookie data @return String containing cookie data
]] ]]
---[[ ---[[
Get the value of a certain HTTP environment variable Get the value of a certain HTTP environment variable
or the environment table itself.
@class function or the environment table itself.
@name getenv @class function
@name getenv
@param name Environment variable @param name Environment variable
@return HTTP environment value or environment table @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. Set a handler function for incoming user file uploads.
@class function @class function
@name setfilehandler @name setfilehandler
@param callback Handler function @param callback Handler function
]] ]]
---[[ ---[[
Send a HTTP-Header. Send a HTTP-Header.
@class function @class function
@name header @name header
@param key Header key @param key Header key
@param value Header value @param value Header value
]] ]]
---[[ ---[[
Set the mime type of following content data. Set the mime type of following content data.
@class function @class function
@name prepare_content @name prepare_content
@param mime Mimetype of following content @param mime Mimetype of following content
]] ]]
---[[ ---[[
Get the RAW HTTP input source Get the RAW HTTP input source
@class function @class function
@name source @name source
@return HTTP LTN12 source @return HTTP LTN12 source
]] ]]
---[[ ---[[
Set the HTTP status code and status message. Set the HTTP status code and status message.
@class function @class function
@name status @name status
@param code Status code @param code Status code
@param message Status message @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. This function is as a valid LTN12 sink.
If the content chunk is nil this function will automatically invoke close. If the content chunk is nil this function will automatically invoke close.
@class function
@class function @name write
@name write
@param content Content chunk @param content Content chunk
@param src_err Error object from source (optional) @param src_err Error object from source (optional)
@see close @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. Splice data from a filedescriptor to the client.
@class function @class function
@name splice @name splice
@param fp File descriptor @param fp File descriptor
@param size Bytes to splice (optional) @param size Bytes to splice (optional)
]] ]]
---[[ ---[[
Redirects the client to a new URL and closes the connection. Redirects the client to a new URL and closes the connection.
@class function @class function
@name redirect @name redirect
@param url Target URL @param url Target URL
]] ]]
---[[ ---[[
Create a querystring out of a table of key - value pairs. Create a querystring out of a table of key - value pairs.
@class function @class function
@name build_querystring @name build_querystring
@param table Query string source table @param table Query string source table
@return Encoded HTTP query string @return Encoded HTTP query string
]] ]]
---[[ ---[[
Return the URL-decoded equivalent of a string. Return the URL-decoded equivalent of a string.
@class function
@name urldecode
@param str URL-encoded string @param str URL-encoded string
@param no_plus Don't decode + to " " @param no_plus Don't decode + to " "
@return URL-decoded string @return URL-decoded string
@see urlencode @see urlencode
]] ]]
---[[ ---[[
Return the URL-encoded equivalent of a string. Return the URL-encoded equivalent of a string.
@class function
@name urlencode
@param str Source string @param str Source string
@return URL-encoded string @return URL-encoded string
@see urldecode @see urldecode
]] ]]
---[[ ---[[
Send the given data as JSON encoded string. Send the given data as JSON encoded string.
@class function @class function
@name write_json @name write_json
@param data Data to send @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 -- This class provides basic ETag handling and implements most of the
-- conditional HTTP/1.1 headers specified in RFC2616 Sct. 14.24 - 14.28 . -- 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 ) 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 This class provides basic ETag handling and implements most of the
conditional HTTP/1.1 headers specified in RFC2616 Sct. 14.24 - 14.28 . 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. Implement 14.19 / ETag.

View File

@ -2,7 +2,7 @@
-- Licensed to the public under the Apache License 2.0. -- Licensed to the public under the Apache License 2.0.
-- This class contains functions to parse, compare and format http dates. -- 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") 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. 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. 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 -- This class provides functions to guess mime types from file extensions and
-- vice versa. -- vice versa.
module("luci.http.mime", package.seeall) module("luci.http.protocol.mime", package.seeall)
require("luci.util") 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 This class provides functions to guess mime types from file extensions and
vice versa. vice versa.
]] ]]
module "luci.http.mime" module "luci.http.protocol.mime"
---[[ ---[[
MIME mapping table containg extension - mimetype relations. MIME mapping table containg extension - mimetype relations.

View File

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

View File

@ -20,14 +20,12 @@ module "luci.model.ipkg"
-- Internal action function -- Internal action function
local function _action(cmd, ...) local function _action(cmd, ...)
local cmdline = { ipkg, cmd } local pkg = ""
local k, v
for k, v in pairs({...}) do for k, v in pairs({...}) do
cmdline[#cmdline+1] = util.shellquote(v) pkg = pkg .. " '" .. v:gsub("'", "") .. "'"
end 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 r = os.execute(c)
local e = fs.readfile("/tmp/opkg.stderr") local e = fs.readfile("/tmp/opkg.stderr")
local o = fs.readfile("/tmp/opkg.stdout") local o = fs.readfile("/tmp/opkg.stdout")
@ -76,17 +74,17 @@ local function _parselist(rawdata)
end end
-- Internal lookup function -- Internal lookup function
local function _lookup(cmd, pkg) local function _lookup(act, pkg)
local cmdline = { ipkg, cmd } local cmd = ipkg .. " " .. act
if pkg then if pkg then
cmdline[#cmdline+1] = util.shellquote(pkg) cmd = cmd .. " '" .. pkg:gsub("'", "") .. "'"
end end
-- OPKG sometimes kills the whole machine because it sucks -- OPKG sometimes kills the whole machine because it sucks
-- Therefore we have to use a sucky approach too and use -- Therefore we have to use a sucky approach too and use
-- tmpfiles instead of directly reading the output -- tmpfiles instead of directly reading the output
local tmpfile = os.tmpname() 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)) local data = _parselist(io.lines(tmpfile))
os.remove(tmpfile) os.remove(tmpfile)
@ -125,12 +123,9 @@ end
-- List helper -- List helper
local function _list(action, pat, cb) local function _list(action, pat, cb)
local cmdline = { ipkg, action } local fd = io.popen(ipkg .. " " .. action ..
if pat then (pat and (" '%s'" % pat:gsub("'", "")) or ""))
cmdline[#cmdline+1] = util.shellquote(pat)
end
local fd = io.popen(table.concat(cmdline, " "))
if fd then if fd then
local name, version, sz, desc local name, version, sz, desc
while true do 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 tonumber, tostring, math = tonumber, tostring, math
local pcall, require, setmetatable = pcall, require, setmetatable local require = require
local nxo = require "nixio" local nxo = require "nixio"
local nfs = require "nixio.fs" local nfs = require "nixio.fs"
local ipc = require "luci.ip" local ipc = require "luci.ip"
local sys = require "luci.sys"
local utl = require "luci.util" local utl = require "luci.util"
local dsp = require "luci.dispatcher"
local uci = require "luci.model.uci" local uci = require "luci.model.uci"
local lng = require "luci.i18n" local lng = require "luci.i18n"
local jsc = require "luci.jsonc" local jsc = require "luci.jsonc"
@ -21,7 +23,7 @@ module "luci.model.network"
IFACE_PATTERNS_VIRTUAL = { } 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_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() protocol = utl.class()
@ -106,58 +108,6 @@ function _set(c, s, o, v)
end end
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) function _wifi_iface(x)
local _, p local _, p
for _, p in ipairs(IFACE_PATTERNS_WIRELESS) do for _, p in ipairs(IFACE_PATTERNS_WIRELESS) do
@ -168,111 +118,59 @@ function _wifi_iface(x)
return false return false
end end
local function _wifi_iwinfo_by_ifname(ifname, force_phy_only) function _wifi_state(key, val, field)
local stat, iwinfo = pcall(require, "iwinfo") local radio, radiostate, ifc, ifcstate
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
}
if iwtype then if not next(_ubuswificache) then
-- if we got a type but no real netdev, we're referring to a phy _ubuswificache = utl.ubus("network.wireless", "status", {}) or {}
local phy_only = force_phy_only or (ipc.link(ifname).type ~= 1)
return setmetatable({}, { -- workaround extended section format
__index = function(t, k) for radio, radiostate in pairs(_ubuswificache) do
if k == "ifname" then for ifc, ifcstate in pairs(radiostate.interfaces) do
return ifname if ifcstate.section and ifcstate.section:sub(1, 1) == '@' then
elseif phy_only and is_nonphy_op[k] then local s = _uci:get_all('wireless.%s' % ifcstate.section)
return nil if s then
elseif iwinfo[iwtype][k] then ifcstate.section = s['.name']
return iwinfo[iwtype][k](ifname) end
end end
end end
}) end
end end
end
local function _wifi_sid_by_netid(netid) for radio, radiostate in pairs(_ubuswificache) do
if type(netid) == "string" then for ifc, ifcstate in pairs(radiostate.interfaces) do
local radioname, netidx = netid:match("^(%w+)%.network(%d+)$") if ifcstate[key] == val then
if radioname and netidx then return ifcstate[field]
local i, n = 0, nil end
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
end end
end end
end end
function _wifi_sid_by_ifname(ifn) function _wifi_lookup(ifn)
local sid = _wifi_sid_by_netid(ifn) -- got a radio#.network# pseudo iface, locate the corresponding section
if sid then 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 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 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 end
function _iface_virtual(x) function _iface_virtual(x)
@ -330,7 +228,7 @@ function init(cursor)
if i.family == "packet" then if i.family == "packet" then
_interfaces[name].flags = i.flags _interfaces[name].flags = i.flags
_interfaces[name].stats = i.data _interfaces[name].stats = i.data
_interfaces[name].macaddr = ipc.checkmac(i.addr) _interfaces[name].macaddr = i.addr
elseif i.family == "inet" then elseif i.family == "inet" then
_interfaces[name].ipaddrs[#_interfaces[name].ipaddrs+1] = ipc.IPv4(i.addr, i.netmask) _interfaces[name].ipaddrs[#_interfaces[name].ipaddrs+1] = ipc.IPv4(i.addr, i.netmask)
elseif i.family == "inet6" then elseif i.family == "inet6" then
@ -543,9 +441,6 @@ end
function del_network(self, n) function del_network(self, n)
local r = _uci:delete("network", n) local r = _uci:delete("network", n)
if r then if r then
_uci:delete_all("luci", "ifstate",
function(s) return (s.interface == n) end)
_uci:delete_all("network", "alias", _uci:delete_all("network", "alias",
function(s) return (s.interface == n) end) function(s) return (s.interface == n) end)
@ -629,8 +524,20 @@ function get_interface(self, i)
if _interfaces[i] or _wifi_iface(i) then if _interfaces[i] or _wifi_iface(i) then
return interface(i) return interface(i)
else else
local netid = _wifi_netid_by_sid(i) local ifc
return netid and interface(netid) 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
end end
@ -737,7 +644,7 @@ function get_wifidevs(self)
end end
function get_wifinet(self, net) function get_wifinet(self, net)
local wnet = _wifi_sid_by_ifname(net) local wnet = _wifi_lookup(net)
if wnet then if wnet then
return wifinet(wnet) return wifinet(wnet)
end end
@ -753,7 +660,7 @@ function add_wifinet(self, net, options)
end end
function del_wifinet(self, net) function del_wifinet(self, net)
local wnet = _wifi_sid_by_ifname(net) local wnet = _wifi_lookup(net)
if wnet then if wnet then
_uci:delete("wireless", wnet) _uci:delete("wireless", wnet)
return true return true
@ -877,7 +784,22 @@ function protocol.ifname(self)
ifname = self:_ubus("device") ifname = self:_ubus("device")
end end
if not ifname then 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 end
return ifname return ifname
end end
@ -1001,15 +923,7 @@ function protocol.ip6addrs(self)
if type(addrs) == "table" then if type(addrs) == "table" then
for n, addr in ipairs(addrs) do for n, addr in ipairs(addrs) do
if type(addr["local-address"]) == "table" and rv[#rv+1] = "%s1/%d" %{ addr.address, addr.mask }
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
end end
end end
@ -1067,17 +981,24 @@ function protocol.is_empty(self)
if self:is_floating() then if self:is_floating() then
return false return false
else else
local empty = true local rv = true
if (self:_get("ifname") or ""):match("%S+") then if (self:_get("ifname") or ""):match("%S+") then
empty = false rv = false
end end
if empty and _wifi_netid_by_netname(self.sid) then _uci:foreach("wireless", "wifi-iface",
empty = false function(s)
end 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
end end
@ -1085,7 +1006,7 @@ function protocol.add_interface(self, ifname)
ifname = _M:ifnameof(ifname) ifname = _M:ifnameof(ifname)
if ifname and not self:is_floating() then if ifname and not self:is_floating() then
-- if its a wifi interface, change its network option -- if its a wifi interface, change its network option
local wif = _wifi_sid_by_ifname(ifname) local wif = _wifi_lookup(ifname)
if wif then if wif then
_append("wireless", wif, "network", self.sid) _append("wireless", wif, "network", self.sid)
@ -1100,7 +1021,7 @@ function protocol.del_interface(self, ifname)
ifname = _M:ifnameof(ifname) ifname = _M:ifnameof(ifname)
if ifname and not self:is_floating() then if ifname and not self:is_floating() then
-- if its a wireless interface, clear its network option -- 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 if wif then _filter("wireless", wif, "network", self.sid) end
-- remove the interface -- remove the interface
@ -1122,7 +1043,21 @@ function protocol.get_interface(self)
ifn = ifn:match("^[^:/]+") ifn = ifn:match("^[^:/]+")
return ifn and interface(ifn, self) return ifn and interface(ifn, self)
end 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) return ifn and interface(ifn, self)
end end
end end
@ -1142,17 +1077,18 @@ function protocol.get_interfaces(self)
ifaces[#ifaces+1] = nfs[ifn] ifaces[#ifaces+1] = nfs[ifn]
end end
local num = { }
local wfs = { } local wfs = { }
_uci:foreach("wireless", "wifi-iface", _uci:foreach("wireless", "wifi-iface",
function(s) function(s)
if s.device then if s.device then
num[s.device] = num[s.device] and num[s.device] + 1 or 1
local net local net
for net in utl.imatch(s.network) do for net in utl.imatch(s.network) do
if net == self.sid then if net == self.sid then
ifn = _wifi_netid_by_sid(s[".name"]) ifn = "%s.network%d" %{ s.device, num[s.device] }
if ifn then wfs[ifn] = interface(ifn, self)
wfs[ifn] = interface(ifn, self)
end
end end
end end
end end
@ -1183,7 +1119,7 @@ function protocol.contains_interface(self, ifname)
end end
end end
local wif = _wifi_sid_by_ifname(ifname) local wif = _wifi_lookup(ifname)
if wif then if wif then
local n local n
for n in utl.imatch(_uci:get("wireless", wif, "network")) do for n in utl.imatch(_uci:get("wireless", wif, "network")) do
@ -1198,18 +1134,17 @@ function protocol.contains_interface(self, ifname)
end end
function protocol.adminlink(self) function protocol.adminlink(self)
local stat, dsp = pcall(require, "luci.dispatcher") return dsp.build_url("admin", "network", "network", self.sid)
return stat and dsp.build_url("admin", "network", "network", self.sid)
end end
interface = utl.class() interface = utl.class()
function interface.__init__(self, ifname, network) function interface.__init__(self, ifname, network)
local wif = _wifi_sid_by_ifname(ifname) local wif = _wifi_lookup(ifname)
if wif then if wif then
self.wif = wifinet(wif) self.wif = wifinet(wif)
self.ifname = self.wif:ifname() self.ifname = _wifi_state("section", wif, "ifname")
end end
self.ifname = self.ifname or ifname self.ifname = self.ifname or ifname
@ -1233,7 +1168,8 @@ function interface.name(self)
end end
function interface.mac(self) function interface.mac(self)
return ipc.checkmac(self:_ubus("macaddr")) local mac = self:_ubus("macaddr")
return mac and mac:upper()
end end
function interface.ipaddrs(self) function interface.ipaddrs(self)
@ -1396,14 +1332,9 @@ end
wifidev = utl.class() wifidev = utl.class()
function wifidev.__init__(self, name) function wifidev.__init__(self, dev)
local t, n = _uci:get("wireless", name) self.sid = dev
if t == "wifi-device" and n ~= nil then self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
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 }
end end
function wifidev.get(self, opt) function wifidev.get(self, opt)
@ -1428,9 +1359,11 @@ function wifidev.hwmodes(self)
end end
function wifidev.get_i18n(self) function wifidev.get_i18n(self)
local t = self.iwinfo.hardware_name or "Generic" local t = "Generic"
if self.iwinfo.type == "wl" then if self.iwinfo.type == "wl" then
t = "Broadcom" t = "Broadcom"
elseif self.iwinfo.type == "ra" then
t = "Ralink/MediaTek"
end end
local m = "" local m = ""
@ -1456,7 +1389,7 @@ function wifidev.get_wifinet(self, net)
if _uci:get("wireless", net) == "wifi-iface" then if _uci:get("wireless", net) == "wifi-iface" then
return wifinet(net) return wifinet(net)
else else
local wnet = _wifi_sid_by_ifname(net) local wnet = _wifi_lookup(net)
if wnet then if wnet then
return wifinet(wnet) return wifinet(wnet)
end end
@ -1490,7 +1423,7 @@ function wifidev.del_wifinet(self, net)
if utl.instanceof(net, wifinet) then if utl.instanceof(net, wifinet) then
net = net.sid net = net.sid
elseif _uci:get("wireless", net) ~= "wifi-iface" then elseif _uci:get("wireless", net) ~= "wifi-iface" then
net = _wifi_sid_by_ifname(net) net = _wifi_lookup(net)
end end
if net and _uci:get("wireless", net, "device") == self.sid then if net and _uci:get("wireless", net, "device") == self.sid then
@ -1504,50 +1437,49 @@ end
wifinet = utl.class() wifinet = utl.class()
function wifinet.__init__(self, name, data) function wifinet.__init__(self, net, data)
local sid, netid, radioname, radiostate, netstate 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 if sid then
netid = name local _, k, r, i
radioname, radiostate, netstate = _wifi_state_by_sid(sid) for k, r in pairs(_ubuswificache) do
else if type(r) == "table" and
-- lookup state by ifname (e.g. wlan0) type(r.interfaces) == "table"
radioname, radiostate, netstate = _wifi_state_by_ifname(name) then
if radioname and radiostate and netstate then for _, i in ipairs(r.interfaces) do
sid = netstate.section if type(i) == "table" and i.section == sid then
netid = _wifi_netid_by_sid(sid) self._ubusdata = {
else radio = k,
-- lookup state by uci section id (e.g. cfg053579) dev = r,
radioname, radiostate, netstate = _wifi_state_by_sid(name) net = i
if radioname and radiostate and netstate then }
sid = name end
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
end end
end end
end end
end end
local iwinfo = local dev = _wifi_state("section", self.sid, "ifname") or netid
(netstate and _wifi_iwinfo_by_ifname(netstate.ifname)) or
(radioname and _wifi_iwinfo_by_ifname(radioname)) or
{ ifname = (netid or sid or name) }
self.sid = sid or name self.netid = netid
self.wdev = iwinfo.ifname self.wdev = dev
self.iwinfo = iwinfo self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { }
self.netid = netid
self._ubusdata = {
radio = radioname,
dev = radiostate,
net = netstate
}
end end
function wifinet.ubus(self, ...) function wifinet.ubus(self, ...)
@ -1600,7 +1532,7 @@ end
function wifinet.ifname(self) function wifinet.ifname(self)
local ifname = self:ubus("net", "ifname") or self.iwinfo.ifname 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 ifname = self.wdev
end end
return ifname return ifname
@ -1734,8 +1666,7 @@ function wifinet.get_i18n(self)
end end
function wifinet.adminlink(self) function wifinet.adminlink(self)
local stat, dsp = pcall(require, "luci.dispatcher") return dsp.build_url("admin", "network", "wireless", self.netid)
return dsp and dsp.build_url("admin", "network", "wireless", self.netid)
end end
function wifinet.get_network(self) function wifinet.get_network(self)

View File

@ -2,12 +2,13 @@
-- Licensed to the public under the Apache License 2.0. -- Licensed to the public under the Apache License 2.0.
local os = require "os" local os = require "os"
local uci = require "uci"
local util = require "luci.util" local util = require "luci.util"
local table = require "table" local table = require "table"
local setmetatable, rawget, rawset = setmetatable, rawget, rawset 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 error, pairs, ipairs = error, pairs, ipairs
local type, tostring, tonumber, unpack = type, tostring, tonumber, unpack local type, tostring, tonumber, unpack = type, tostring, tonumber, unpack
@ -19,436 +20,151 @@ local type, tostring, tonumber, unpack = type, tostring, tonumber, unpack
-- reloaded. -- reloaded.
module "luci.model.uci" module "luci.model.uci"
local ERRSTR = { cursor = uci.cursor
"Invalid command",
"Invalid argument",
"Method not found",
"Entry not found",
"No data",
"Permission denied",
"Timeout",
"Not supported",
"Unknown error",
"Connection failed"
}
local session_id = nil APIVERSION = uci.APIVERSION
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
function cursor_state() function cursor_state()
return _M return cursor(nil, "/var/state")
end
function substate(self)
return self
end end
function get_confdir(self) inst = cursor()
return "/etc/config" inst_state = cursor_state()
end
function get_savedir(self) local Cursor = getmetatable(inst)
return "/tmp/.uci"
end
function get_session_id(self) function Cursor.apply(self, configlist, command)
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)
configlist = self:_affected(configlist) configlist = self:_affected(configlist)
if command then if command then
return { "/sbin/luci-reload", unpack(configlist) } return { "/sbin/luci-reload", unpack(configlist) }
else else
return os.execute("/sbin/luci-reload %s >/dev/null 2>&1" return os.execute("/sbin/luci-reload %s >/dev/null 2>&1"
% util.shellquote(table.concat(configlist, " "))) % table.concat(configlist, " "))
end end
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. -- Return a list of initscripts affected by configuration changes.
function _affected(self, configlist) function Cursor._affected(self, configlist)
configlist = type(configlist) == "table" and configlist or { configlist } configlist = type(configlist) == "table" and configlist or {configlist}
local c = cursor()
c:load("ucitrack")
-- Resolve dependencies -- Resolve dependencies
local reloadlist = { } local reloadlist = {}
local function _resolve_deps(name) local function _resolve_deps(name)
local reload = { name } local reload = {name}
local deps = { } local deps = {}
self:foreach("ucitrack", name, c:foreach("ucitrack", name,
function(section) function(section)
if section.affects then if section.affects then
for i, aff in ipairs(section.affects) do for i, aff in ipairs(section.affects) do
@ -457,9 +173,7 @@ function _affected(self, configlist)
end end
end) end)
local i, dep
for i, dep in ipairs(deps) do for i, dep in ipairs(deps) do
local j, add
for j, add in ipairs(_resolve_deps(dep)) do for j, add in ipairs(_resolve_deps(dep)) do
reload[#reload+1] = add reload[#reload+1] = add
end end
@ -469,9 +183,7 @@ function _affected(self, configlist)
end end
-- Collect initscripts -- Collect initscripts
local j, config
for j, config in ipairs(configlist) do for j, config in ipairs(configlist) do
local i, e
for i, e in ipairs(_resolve_deps(config)) do for i, e in ipairs(_resolve_deps(config)) do
if not util.contains(reloadlist, e) then if not util.contains(reloadlist, e) then
reloadlist[#reloadlist+1] = e reloadlist[#reloadlist+1] = e
@ -481,3 +193,44 @@ function _affected(self, configlist)
return reloadlist return reloadlist
end 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. Create a new UCI-Cursor.
@class function @class function
@name cursor @name cursor
@return UCI-Cursor @return UCI-Cursor
]] ]]
---[[ ---[[
Create a new Cursor initialized to the state directory. Create a new Cursor initialized to the state directory.
@class function @class function
@name cursor_state @name cursor_state
@return UCI cursor @return UCI cursor
]] ]]
---[[ ---[[
Applies UCI configuration changes Applies UCI configuration changes
@class function @class function
@name Cursor.apply @name Cursor.apply
@param configlist List of UCI configurations @param configlist List of UCI configurations
@param command Don't apply only return the command @param command Don't apply only return the command
]] ]]
---[[ ---[[
Delete all sections of a given type that match certain criteria. Delete all sections of a given type that match certain criteria.
@class function @class function
@name Cursor.delete_all @name Cursor.delete_all
@param config UCI config @param config UCI config
@param type UCI section type @param type UCI section type
@param comparator Function that will be called for each section and returns @param comparator Function that will be called for each section and
a boolean whether to delete the current section (optional) returns a boolean whether to delete the current section (optional)
]] ]]
---[[ ---[[
Create a new section and initialize it with data. Create a new section and initialize it with data.
@class function @class function
@name Cursor.section @name Cursor.section
@param config UCI config @param config UCI config
@param type UCI section type @param type UCI section type
@param name UCI section name (optional) @param name UCI section name (optional)
@param values Table of key - value pairs to initialize the section with @param values Table of key - value pairs to initialize the section with
@return Name of created section @return Name of created section
]] ]]
---[[ ---[[
Updated the data of a section using data from a table. Updated the data of a section using data from a table.
@class function @class function
@name Cursor.tset @name Cursor.tset
@param config UCI config @param config UCI config
@param section UCI section name (optional) @param section UCI section name (optional)
@param values Table of key - value pairs to update the section with @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. Get a boolean option and return it's value as true or false.
@class function @class function
@name Cursor.get_bool @name Cursor.get_bool
@param config UCI config @param config UCI config
@param section UCI section name @param section UCI section name
@param option UCI option @param option UCI option
@return Boolean @return Boolean
]] ]]
---[[ ---[[
Get an option or list and return values as table. Get an option or list and return values as table.
@class function @class function
@name Cursor.get_list @name Cursor.get_list
@param config UCI config @param config UCI config
@param section UCI section name @param section UCI section name
@param option UCI option @param option UCI option
@return table. If the option was not found, you will simply get an empty @return table. If the option was not found, you will simply get
table. -- an empty table.
]] ]]
---[[ ---[[
Get the given option from the first section with the given type. Get the given option from the first section with the given type.
@class function @class function
@name Cursor.get_first @name Cursor.get_first
@param config UCI config @param config UCI config
@param type UCI section type @param type UCI section type
@param option UCI option (optional) @param option UCI option (optional)
@param default Default value (optional) @param default Default value (optional)
@return UCI value @return UCI value
]] ]]
---[[ ---[[
Set given values as list. Setting a list option to an empty list Set given values as list. Setting a list option to an empty list
has the same effect as deleting the option. has the same effect as deleting the option.
@class function @class function
@name Cursor.set_list @name Cursor.set_list
@param config UCI config @param config UCI config
@param section UCI section name @param section UCI section name
@param option UCI option @param option UCI option
@param value Value or table. Non-table values will be set as single @param value value or table. Raw values will become a single item table.
item UCI list. @return Boolean whether operation succeeded
@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 curser, means it the parent unloads or loads configs, the sub state will
loads configs, the sub state will do so as well. do so as well.
@class function
@class function @name Cursor.substate
@name Cursor.substate @return UCI state cursor tied to the parent cursor
@return UCI state cursor tied to the parent cursor
]] ]]
---[[ ---[[
Add an anonymous section. Add an anonymous section.
@class function @class function
@name Cursor.add @name Cursor.add
@param config UCI config @param config UCI config
@param type UCI section type @param type UCI section type
@return Name of created section @return Name of created section
]] ]]
---[[ ---[[
Get a table of saved but uncommitted changes. Get a table of saved but uncommitted changes.
@class function @class function
@name Cursor.changes @name Cursor.changes
@param config UCI config @param config UCI config
@return Table of changes @return Table of changes
@see Cursor.save @see Cursor.save
]] ]]
---[[ ---[[
Commit saved changes. Commit saved changes.
@class function @class function
@name Cursor.commit @name Cursor.commit
@param config UCI config @param config UCI config
@return Boolean whether operation succeeded @return Boolean whether operation succeeded
@see Cursor.revert @see Cursor.revert
@see Cursor.save @see Cursor.save
]] ]]
---[[ ---[[
Deletes a section or an option. Deletes a section or an option.
@class function @class function
@name Cursor.delete @name Cursor.delete
@param config UCI config @param config UCI config
@param section UCI section name @param section UCI section name
@param option UCI option (optional) @param option UCI option (optional)
@return Boolean whether operation succeeded @return Boolean whether operation succeeded
]] ]]
---[[ ---[[
Call a function for every section of a certain type. Call a function for every section of a certain type.
@class function @class function
@name Cursor.foreach @name Cursor.foreach
@param config UCI config @param config UCI config
@param type UCI section type @param type UCI section type
@param callback Function to be called @param callback Function to be called
@return Boolean whether operation succeeded @return Boolean whether operation succeeded
]] ]]
---[[ ---[[
Get a section type or an option Get a section type or an option
@class function @class function
@name Cursor.get @name Cursor.get
@param config UCI config @param config UCI config
@param section UCI section name @param section UCI section name
@param option UCI option (optional) @param option UCI option (optional)
@return UCI value @return UCI value
]] ]]
---[[ ---[[
Get all sections of a config or all values of a section. Get all sections of a config or all values of a section.
@class function @class function
@name Cursor.get_all @name Cursor.get_all
@param config UCI config @param config UCI config
@param section UCI section name (optional) @param section UCI section name (optional)
@return Table of UCI sections or table of UCI values @return Table of UCI sections or table of UCI values
]] ]]
---[[ ---[[
Manually load a config. Manually load a config.
@class function @class function
@name Cursor.load @name Cursor.load
@param config UCI config @param config UCI config
@return Boolean whether operation succeeded @return Boolean whether operation succeeded
@see Cursor.save @see Cursor.save
@see Cursor.unload @see Cursor.unload
]] ]]
---[[ ---[[
Revert saved but uncommitted changes. Revert saved but uncommitted changes.
@class function @class function
@name Cursor.revert @name Cursor.revert
@param config UCI config @param config UCI config
@return Boolean whether operation succeeded @return Boolean whether operation succeeded
@see Cursor.commit @see Cursor.commit
@see Cursor.save @see Cursor.save
]] ]]
---[[ ---[[
Saves changes made to a config to make them committable. Saves changes made to a config to make them committable.
@class function @class function
@name Cursor.save @name Cursor.save
@param config UCI config @param config UCI config
@return Boolean whether operation succeeded @return Boolean whether operation succeeded
@see Cursor.load @see Cursor.load
@see Cursor.unload @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 When invoked with four arguments `config`, `sectionname`, `optionname` and
`optionvalue` then the value of the specified option is set to the given value. `optionvalue` then the value of the specified option is set to the given value.
@class function @class function
@name Cursor.set @name Cursor.set
@param config UCI config @param config UCI config
@param section UCI section name @param section UCI section name
@param option UCI option or UCI section type @param option UCI option or UCI section type
@param value UCI value or nothing if you want to create a section @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. Get the configuration directory.
@class function @class function
@name Cursor.get_confdir @name Cursor.get_confdir
@return Configuration directory @return Configuration directory
]] ]]
---[[ ---[[
Get the directory for uncomitted changes. Get the directory for uncomitted changes.
@class function @class function
@name Cursor.get_savedir @name Cursor.get_savedir
@return Save directory @return Save directory
]]
---[[
Get the effective session ID.
@class function
@name Cursor.get_session_id
@return String containing the session ID
]] ]]
---[[ ---[[
Set the configuration directory. Set the configuration directory.
@class function @class function
@name Cursor.set_confdir @name Cursor.set_confdir
@param directory UCI configuration directory @param directory UCI configuration directory
@return Boolean whether operation succeeded @return Boolean whether operation succeeded
]] ]]
---[[ ---[[
Set the directory for uncommited changes. Set the directory for uncommited changes.
@class function @class function
@name Cursor.set_savedir @name Cursor.set_savedir
@param directory UCI changes directory @param directory UCI changes directory
@return Boolean whether operation succeeded @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
]] ]]
---[[ ---[[
Discard changes made to a config. Discard changes made to a config.
@class function @class function
@name Cursor.unload @name Cursor.unload
@param config UCI config @param config UCI config
@return Boolean whether operation succeeded @return Boolean whether operation succeeded
@see Cursor.load @see Cursor.load
@see Cursor.save @see Cursor.save
]] ]]

View File

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

View File

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

View File

@ -4,7 +4,6 @@
module("luci.tools.status", package.seeall) module("luci.tools.status", package.seeall)
local uci = require "luci.model.uci".cursor() local uci = require "luci.model.uci".cursor()
local ipc = require "luci.ip"
local function dhcp_leases_common(family) local function dhcp_leases_common(family)
local rv = { } local rv = { }
@ -32,7 +31,7 @@ local function dhcp_leases_common(family)
if family == 4 and not ip:match(":") then if family == 4 and not ip:match(":") then
rv[#rv+1] = { rv[#rv+1] = {
expires = (expire ~= 0) and os.difftime(expire, os.time()), expires = (expire ~= 0) and os.difftime(expire, os.time()),
macaddr = ipc.checkmac(mac) or "00:00:00:00:00:00", macaddr = mac,
ipaddr = ip, ipaddr = ip,
hostname = (name ~= "*") and name hostname = (name ~= "*") and name
} }
@ -75,9 +74,19 @@ local function dhcp_leases_common(family)
hostname = (name ~= "-") and name hostname = (name ~= "-") and name
} }
elseif ip and iaid == "ipv4" and family == 4 then 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] = { rv[#rv+1] = {
expires = (expire >= 0) and os.difftime(expire, os.time()), 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, ipaddr = ip,
hostname = (name ~= "-") and name hostname = (name ~= "-") and name
} }
@ -187,9 +196,7 @@ function switch_status(devs)
local switches = { } local switches = { }
for dev in devs:gmatch("[^%s,]+") do for dev in devs:gmatch("[^%s,]+") do
local ports = { } local ports = { }
local swc = io.popen("swconfig dev %s show" local swc = io.popen("swconfig dev %q show" % dev, "r")
% luci.util.shellquote(dev), "r")
if swc then if swc then
local l local l
repeat repeat

View File

@ -10,7 +10,6 @@ local string = require "string"
local coroutine = require "coroutine" local coroutine = require "coroutine"
local tparser = require "luci.template.parser" local tparser = require "luci.template.parser"
local json = require "luci.jsonc" local json = require "luci.jsonc"
local lhttp = require "lucihttp"
local _ubus = require "ubus" local _ubus = require "ubus"
local _ubus_connection = nil local _ubus_connection = nil
@ -161,25 +160,6 @@ function pcdata(value)
return value and tparser.pcdata(tostring(value)) return value and tparser.pcdata(tostring(value))
end 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) function striptags(value)
return value and tparser.striptags(tostring(value)) return value and tparser.striptags(tostring(value))
end end
@ -407,6 +387,16 @@ function clone(object, deep)
end 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. -- Serialize the contents of a table value.
function _serialize_table(t, seen) function _serialize_table(t, seen)
assert(not seen[t], "Recursion detected.") assert(not seen[t], "Recursion detected.")
@ -631,20 +621,6 @@ function execl(command)
return data return data
end 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) function ubus(object, method, data)
if not _ubus_connection then if not _ubus_connection then
_ubus_connection = _ubus.connect() _ubus_connection = _ubus.connect()
@ -655,8 +631,7 @@ function ubus(object, method, data)
if type(data) ~= "table" then if type(data) ~= "table" then
data = { } data = { }
end end
local rv, err = _ubus_connection:call(object, method, data) return _ubus_connection:call(object, method, data)
return rv, err, ubus_codes[err]
elseif object then elseif object then
return _ubus_connection:signatures(object) return _ubus_connection:signatures(object)
else else
@ -681,11 +656,10 @@ end
function checklib(fullpathexe, wantedlib) function checklib(fullpathexe, wantedlib)
local fs = require "nixio.fs" local fs = require "nixio.fs"
local haveldd = fs.access('/usr/bin/ldd') local haveldd = fs.access('/usr/bin/ldd')
local haveexe = fs.access(fullpathexe) if not haveldd then
if not haveldd or not haveexe then
return false return false
end end
local libs = exec(string.format("/usr/bin/ldd %s", shellquote(fullpathexe))) local libs = exec("/usr/bin/ldd " .. fullpathexe)
if not libs then if not libs then
return false return false
end 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. 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 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. with other objects of this class. Any return values will be ignored.
@class function
@class function @name class
@name class @param base The base class to inherit from (optional)
@param base The base class to inherit from (optional) @return A class object
@return A class object @see instanceof
@see instanceof @see clone
@see clone
]] ]]
---[[ ---[[
Test whether the given object is an instance of the given class. Test whether the given object is an instance of the given class.
@class function @class function
@name instanceof @name instanceof
@param object Object instance @param object Object instance
@param class Class object to test against @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 class
@see clone @see clone
]] ]]
---[[ ---[[
Create a new or get an already existing thread local store associated with 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. whose values can't be accessed from outside of the running coroutine.
@class function
@class function @name threadlocal
@name threadlocal @return Table value representing the corresponding thread local store
@return Table value representing the corresponding thread local store
]] ]]
---[[ ---[[
Write given object to stderr. Write given object to stderr.
@class function @class function
@name perror @name perror
@param obj Value to write to stderr @param obj Value to write to stderr
@return Boolean indicating whether the write operation was successful @return Boolean indicating whether the write operation was successful
]] ]]
---[[ ---[[
Recursively dumps a table to stdout, useful for testing and debugging. Recursively dumps a table to stdout, useful for testing and debugging.
@class function @class function
@name dumptable @name dumptable
@param t Table value to dump @param t Table value to dump
@param maxdepth Maximum depth @param maxdepth Maximum depth
@return Always nil @return Always nil
]] ]]
---[[ ---[[
Create valid XML PCDATA from given string. Create valid XML PCDATA from given string.
@class function @class function
@name pcdata @name pcdata
@param value String value containing the data to escape @param value String value containing the data to escape
@return String value containing the escaped data @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
]] ]]
---[[ ---[[
Strip HTML tags from given string. Strip HTML tags from given string.
@class function @class function
@name striptags @name striptags
@param value String containing the HTML text @param value String containing the HTML text
@return String with HTML tags stripped of @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
]] ]]
---[[ ---[[
Splits given string on a defined separator sequence and return a table 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, containing the resulting substrings. The optional max parameter specifies
regardless of the actual length of the given string. The optional last the number of bytes to process, regardless of the actual length of the given
parameter, regex, specifies whether the separator sequence is string. The optional last parameter, regex, specifies whether the separator
nterpreted as regular expression. sequence is interpreted as regular expression.
@class function
@class function @name split
@name split @param str String value containing the data to split up
@param str String value containing the data to split up @param pat String with separator pattern (optional, defaults to "\n")
@param pat String with separator pattern (optional, defaults to "\n") @param max Maximum times to split (optional)
@param max Maximum times to split (optional) @param regex Boolean indicating whether to interpret the separator
@param regex Boolean indicating whether to interpret the separator
-- pattern as regular expression (optional, default is false) -- 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. Remove leading and trailing whitespace from given string value.
@class function @class function
@name trim @name trim
@param str String value containing whitespace padded data @param str String value containing whitespace padded data
@return String value with leading and trailing space removed @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 @class function
@name cmatch @name cmatch
@param str String to search in @param str String to search in
@param pattern String containing pattern to find @param pattern String containing pattern to find
@return Number of found occurrences @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 one token per invocation, the tokens are separated by whitespace. If the
whitespace. If the input value is a table, it is transformed into a string first. input value is a table, it is transformed into a string first. A nil value
A nil value will result in a valid interator which aborts with the first invocation. will result in a valid interator which aborts with the first invocation.
@class function
@class function @name imatch
@name imatch @param val The value to scan (table, string or nil)
@param val The value to scan (table, string or nil) @return Iterator which returns one token per call
@return Iterator which returns one token per call
]] ]]
---[[ ---[[
Parse certain units from the given string and return the canonical integer 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: Recognized units are:
-- o "y" - one year (60*60*24*366) -- o "y" - one year (60*60*24*366)
o "m" - one month (60*60*24*31) o "m" - one month (60*60*24*31)
o "w" - one week (60*60*24*7) o "w" - one week (60*60*24*7)
@ -185,229 +147,232 @@ Recognized units are:
o "kib" - one si kilobyte (1000) o "kib" - one si kilobyte (1000)
o "mib" - one si megabyte (1000*1000) o "mib" - one si megabyte (1000*1000)
o "gib" - one si gigabyte (1000*1000*1000) o "gib" - one si gigabyte (1000*1000*1000)
@class function
@class function @name parse_units
@name parse_units @param ustr String containing a numerical value with trailing unit
@param ustr String containing a numerical value with trailing unit @return Number containing the canonical value
@return Number containing the canonical value
]] ]]
---[[ ---[[
Appends numerically indexed tables or single objects to a given table. Appends numerically indexed tables or single objects to a given table.
@class function @class function
@name append @name append
@param src Target table @param src Target table
@param ... Objects to insert @param ... Objects to insert
@return Target table @return Target table
]] ]]
---[[ ---[[
Combines two or more numerically indexed tables and single objects into one table. Combines two or more numerically indexed tables and single objects into one table.
@class function @class function
@name combine @name combine
@param tbl1 Table value to combine @param tbl1 Table value to combine
@param tbl2 Table value to combine @param tbl2 Table value to combine
@param ... More tables to combine @param ... More tables to combine
@return Table value containing all values of given tables @return Table value containing all values of given tables
]] ]]
---[[ ---[[
Checks whether the given table contains the given value. Checks whether the given table contains the given value.
@class function @class function
@name contains @name contains
@param table Table value @param table Table value
@param value Value to search within the given table @param value Value to search within the given table
@return Number indicating the first index at which the given value occurs @return number indicating the first index at which the given value occurs
-- within table or false. -- within table or false.
]] ]]
---[[ ---[[
Update values in given table with the values from the second given table. Update values in given table with the values from the second given table.
Both table are - in fact - merged together. Both table are - in fact - merged together.
@class function
@class function @name update
@name update
@param t Table which should be updated @param t Table which should be updated
@param updates Table containing the values to update @param updates Table containing the values to update
@return Always nil @return Always nil
]] ]]
---[[ ---[[
Retrieve all keys of given associative table. Retrieve all keys of given associative table.
@class function @class function
@name keys @name keys
@param t Table to extract keys from @param t Table to extract keys from
@return Sorted table containing the keys @return Sorted table containing the keys
]] ]]
---[[ ---[[
Clones the given object and return it's copy. Clones the given object and return it's copy.
@class function @class function
@name clone @name clone
@param object Table value to clone @param object Table value to clone
@param deep Boolean indicating whether to do recursive cloning @param deep Boolean indicating whether to do recursive cloning
@return Cloned table value @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 Recursively serialize given data to lua code, suitable for restoring
with loadstring().
@class function with loadstring().
@name serialize_data @class function
@param val Value containing the data to serialize @name serialize_data
@return String value containing the serialized code @param val Value containing the data to serialize
@see restore_data @return String value containing the serialized code
@see get_bytecode @see restore_data
@see get_bytecode
]] ]]
---[[ ---[[
Restore data previously serialized with serialize_data(). Restore data previously serialized with serialize_data().
@class function @class function
@name restore_data @name restore_data
@param str String containing the data to restore @param str String containing the data to restore
@return Value containing the restored data structure @return Value containing the restored data structure
@see serialize_data @see serialize_data
@see get_bytecode @see get_bytecode
]] ]]
---[[ ---[[
Return the current runtime bytecode of the given data. The byte code Return the current runtime bytecode of the given data. The byte code
will be stripped before it is returned.
@class function will be stripped before it is returned.
@name get_bytecode @class function
@param val Value to return as bytecode @name get_bytecode
@return String value containing the bytecode of the given data @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. numbers and debugging numbers will be discarded. Original version by
Original version by Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html) Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html)
@class function
@class function @name strip_bytecode
@name strip_bytecode @param code String value containing the original lua byte code
@param code String value containing the original lua byte code @return String value containing the stripped lua byte code
@return String value containing the stripped lua byte code
]] ]]
---[[ ---[[
Return a key, value iterator which returns the values sorted according to Return a key, value iterator which returns the values sorted according to
the provided callback function.
@class function the provided callback function.
@name spairs @class function
@param t The table to iterate @name spairs
@param f A callback function to decide the order of elements @param t The table to iterate
@return Function value containing the corresponding iterator @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. Return a key, value iterator for the given table.
The table pairs are sorted by key. The table pairs are sorted by key.
@class function
@class function @name kspairs
@name kspairs @param t The table to iterate
@param t The table to iterate @return Function value containing the corresponding iterator
@return Function value containing the corresponding iterator
]] ]]
---[[ ---[[
Return a key, value iterator for the given table. Return a key, value iterator for the given table.
The table pairs are sorted by value. The table pairs are sorted by value.
@class function
@class function @name vspairs
@name vspairs @param t The table to iterate
@param t The table to iterate @return Function value containing the corresponding iterator
@return Function value containing the corresponding iterator
]] ]]
---[[ ---[[
Test whether the current system is operating in big endian mode. Test whether the current system is operating in big endian mode.
@class function @class function
@name bigendian @name bigendian
@return Boolean value indicating whether system is big endian @return Boolean value indicating whether system is big endian
]] ]]
---[[ ---[[
Execute given commandline and gather stdout. Execute given commandline and gather stdout.
@class function @class function
@name exec @name exec
@param command String containing command to execute @param command String containing command to execute
@return String containing the command's stdout @return String containing the command's stdout
]] ]]
---[[ ---[[
Return a line-buffered iterator over the output of given command. Return a line-buffered iterator over the output of given command.
@class function @class function
@name execi @name execi
@param command String containing the command to execute @param command String containing the command to execute
@return Iterator @return Iterator
]] ]]
---[[ ---[[
Issue an ubus call. Issue an ubus call.
@class function @class function
@name ubus @name ubus
@param object String containing the ubus object to call @param object String containing the ubus object to call
@param method String containing the ubus method to call @param method String containing the ubus method to call
@param values Table containing the values to pass @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 Convert data structure to JSON
@class function @class function
@name serialize_json @name serialize_json
@param data The data to serialize @param data The data to serialize
@param writer A function to write a chunk of JSON data (optional) @param writer A function to write a chunk of JSON data (optional)
@return String containing the JSON if called without write callback @return String containing the JSON if called without write callback
]] ]]
---[[ ---[[
Returns the absolute path to LuCI base directory. Returns the absolute path to LuCI base directory.
@class function @class function
@name libpath @name libpath
@return String containing the directory path @return String containing the directory path
]] ]]
---[[ ---[[
This is a coroutine-safe drop-in replacement for Lua's "xpcall"-function This is a coroutine-safe drop-in replacement for Lua's "xpcall"-function
@class function @class function
@name coxpcall @name coxpcall
@param f Lua function to be called protected @param f Lua function to be called protected
@param err Custom error handler @param err Custom error handler
@param ... Parameters passed to the function @param ... Parameters passed to the function
@return A boolean whether the function call succeeded and the return @return 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
]] ]]
---[[ ---[[
This is a coroutine-safe drop-in replacement for Lua's "pcall"-function This is a coroutine-safe drop-in replacement for Lua's "pcall"-function
@class function @class function
@name copcall @name copcall
@param f Lua function to be called protected @param f Lua function to be called protected
@param ... Parameters passed to the function @param ... Parameters passed to the function
@return A boolean whether the function call succeeded and the returns @return 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
]] ]]

View File

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

View File

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

View File

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

View File

@ -24,72 +24,70 @@
end end
-%> -%>
<span> <ul style="margin:0; list-style-type:none; text-align:left">
<ul style="margin:0; list-style-type:none; text-align:left"> <% if self.allowlocal then %>
<% if self.allowlocal then %> <li style="padding:0.5em">
<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;
<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")%>></label> <label<%=attr("for", cbid .. "_empty")%> style="background-color:<%=fwm.zone.get_color()%>" class="zonebadge">
<label<%=attr("for", cbid .. "_empty")%> style="background-color:<%=fwm.zone.get_color()%>" class="zonebadge"> <strong><%:Device%></strong>
<strong><%:Device%></strong> <% if self.allowany and self.allowlocal then %>(<%:input%>)<% end %>
<% if self.allowany and self.allowlocal then %>(<%:input%>)<% end %> </label>
</label> </li>
</li> <% end %>
<% end %> <% if self.allowany then %>
<% if self.allowany then %> <li style="padding:0.5em">
<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;
<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")%>></label> <label<%=attr("for", cbid .. "_any")%> style="background-color:<%=fwm.zone.get_color()%>" class="zonebadge">
<label<%=attr("for", cbid .. "_any")%> style="background-color:<%=fwm.zone.get_color()%>" class="zonebadge"> <strong><%:Any zone%></strong>
<strong><%:Any zone%></strong> <% if self.allowany and self.allowlocal then %>(<%:forward%>)<% end %>
<% if self.allowany and self.allowlocal then %>(<%:forward%>)<% end %> </label>
</label> </li>
</li> <% end %>
<% end %> <%
<% for _, zone in utl.spairs(zones, function(a,b) return (zones[a]:name() < zones[b]:name()) end) do
for _, zone in utl.spairs(zones, function(a,b) return (zones[a]:name() < zones[b]:name()) end) do if zone:name() ~= self.exclude then
if zone:name() ~= self.exclude then selected = selected or (value == zone:name())
selected = selected or (value == zone:name()) %>
%> <li style="padding:0.5em">
<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;
<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())%>></label> <label<%=attr("for", cbid .. "." .. zone:name())%> style="background-color:<%=zone:get_color()%>" class="zonebadge">
<label<%=attr("for", cbid .. "." .. zone:name())%> style="background-color:<%=zone:get_color()%>" class="zonebadge"> <strong><%=zone:name()%>:</strong>
<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 local nempty = true
for _, net in ipairs(zone:get_networks()) do for _, iface in ipairs(net:is_bridge() and net:get_interfaces() or { net:get_interface() }) do
net = nwm:get_network(net) nempty = false
if net then %>
zempty = 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 %>
<span class="ifacebadge<% if net:name() == self.network then %> ifacebadge-active<% end %>"><%=net:name()%>: <% if nempty then %><em><%:(empty)%></em><% end %>
<% </span>
local nempty = true <% end end %>
for _, iface in ipairs(net:is_bridge() and net:get_interfaces() or { net:get_interface() }) do <% if zempty then %><em><%:(empty)%></em><% end %>
nempty = false </label>
%> </li>
<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 end %>
<% 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 %> <% if self.widget ~= "checkbox" and not self.nocreate then %>
<li style="padding:0.5em"> <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; <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> <label<%=attr("for", cbid .. "_new")%>></label>
<div onclick="document.getElementById('<%=cbid%>_new').checked=true" class="zonebadge" style="background-color:<%=fwm.zone.get_color()%>"> <div onclick="document.getElementById('<%=cbid%>_new').checked=true" class="zonebadge" style="background-color:<%=fwm.zone.get_color()%>">
<em><%:unspecified -or- create:%>&#160;</em> <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" /> <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> </div>
</li> </li>
<% end %> <% end %>
</ul> </ul>
</span>
<%+cbi/valuefooter%> <%+cbi/valuefooter%>

View File

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

View File

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

View File

@ -35,7 +35,7 @@ end
<%- else -%> <%- else -%>
<th>&#160;</th> <th>&#160;</th>
<%- end -%> <%- end -%>
<%- count = count +1; end -%> <%- end -%>
<%- for i, k in pairs(self.children) do if not k.optional then -%> <%- for i, k in pairs(self.children) do if not k.optional then -%>
<th class="cbi-section-table-cell"<%=width(k)%>> <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 -%> <%- 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> </th>
<%- count = count + 1; end; end; if self.sortable then -%> <%- count = count + 1; end; end; if self.sortable then -%>
<th class="cbi-section-table-cell"><%:Sort%></th> <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> <th class="cbi-section-table-cell">&#160;</th>
<%- count = count + 1; end -%> <%- count = count + 1; end -%>
</tr> </tr>

View File

@ -7,5 +7,5 @@
<%+header%> <%+header%>
<h2 name="content">404 <%:Not Found%></h2> <h2 name="content">404 <%:Not Found%></h2>
<p><%:Sorry, the object you requested was not found.%></p> <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%> <%+footer%>

View File

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

View File

@ -13,9 +13,6 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Pootle 2.0.6\n" "X-Generator: Pootle 2.0.6\n"
msgid "%.1f dB"
msgstr ""
msgid "%s is untagged in multiple VLANs!" msgid "%s is untagged in multiple VLANs!"
msgstr "" msgstr ""
@ -127,7 +124,7 @@ msgid "<abbr title=\"Internet Protocol Version 6\">IPv6</abbr>-Suffix (hex)"
msgstr "" msgstr ""
msgid "<abbr title=\"Light Emitting Diode\">LED</abbr> Configuration" 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" msgid "<abbr title=\"Light Emitting Diode\">LED</abbr> Name"
msgstr "Nom <abbr title=\"Light Emitting Diode\">LED</abbr>" 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" msgid "<abbr title=\"Media Access Control\">MAC</abbr>-Address"
msgstr "Adreça <abbr title=\"Media Access Control\">MAC</abbr>" msgstr "Adreça <abbr title=\"Media Access Control\">MAC</abbr>"
msgid "<abbr title=\"The DHCP Unique Identifier\">DUID</abbr>"
msgstr ""
msgid "" msgid ""
"<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Dynamic Host Configuration " "<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Dynamic Host Configuration "
"Protocol\">DHCP</abbr> leases" "Protocol\">DHCP</abbr> leases"
@ -162,8 +156,6 @@ msgid ""
"<br/>Note: you need to manually restart the cron service if the crontab file " "<br/>Note: you need to manually restart the cron service if the crontab file "
"was empty before editing." "was empty before editing."
msgstr "" msgstr ""
"Avís: cal reiniciar manualment el servei cron si el fitxer crontab estava "
"buit abans d'editar-lo."
msgid "A43C + J43 + A43" msgid "A43C + J43 + A43"
msgstr "" msgstr ""
@ -222,6 +214,9 @@ msgstr "Concentrador d'accés"
msgid "Access Point" msgid "Access Point"
msgstr "Punt d'accés" msgstr "Punt d'accés"
msgid "Action"
msgstr "Acció"
msgid "Actions" msgid "Actions"
msgstr "Accions" msgstr "Accions"
@ -290,15 +285,11 @@ msgstr ""
msgid "Allow <abbr title=\"Secure Shell\">SSH</abbr> password authentication" msgid "Allow <abbr title=\"Secure Shell\">SSH</abbr> password authentication"
msgstr "" msgstr ""
"Permetre l'autenticació <abbr title=\"Secure Shell\">SSH</abbr> amb " "Permet autenticació <abbr title=\"Secure Shell\">SSH</abbr> per contrasenya"
"contrasenya"
msgid "Allow all except listed" msgid "Allow all except listed"
msgstr "Permet-les totes menys les llistades" msgstr "Permet-les totes menys les llistades"
msgid "Allow legacy 802.11b rates"
msgstr ""
msgid "Allow listed only" msgid "Allow listed only"
msgstr "Permet només les llistades" 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" msgid "Allow remote hosts to connect to local SSH forwarded ports"
msgstr "" msgstr ""
"Permetre a màquines remotes de connectar-se als ports reenviats de l'SSH " "Permetre a màquines remotes de connectar als ports reenviats de l'SSH local"
"local"
msgid "Allow root logins with password" 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" 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 "" msgid ""
"Allow upstream responses in the 127.0.0.0/8 range, e.g. for RBL services" "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" msgstr "Enrere als resultats de l'escaneig"
msgid "Backup / Flash Firmware" msgid "Backup / Flash Firmware"
msgstr "Còpia de seguretat i microprogramari" msgstr "Còpia de seguretat / Recàrrega de programari"
msgid "Backup / Restore" msgid "Backup / Restore"
msgstr "Còpia de seguretat i restauració de la configuració" msgstr "Còpia de seguretat / Restauració"
msgid "Backup file list" msgid "Backup file list"
msgstr "Llista de còpies de seguretat" msgstr "Llista de còpies de seguretat"
@ -569,8 +559,9 @@ msgid ""
"Build/distribution specific feed definitions. This file will NOT be " "Build/distribution specific feed definitions. This file will NOT be "
"preserved in any sysupgrade." "preserved in any sysupgrade."
msgstr "" 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." msgid "CA certificate; if empty it will be saved after the first connection."
msgstr "" msgstr ""
@ -602,7 +593,7 @@ msgstr "Canal"
msgid "Check" msgid "Check"
msgstr "Comprovació" msgstr "Comprovació"
msgid "Check filesystems before mount" msgid "Check fileystems before mount"
msgstr "" msgstr ""
msgid "Check this option to delete the existing networks from this radio." 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 " "configuration files. To reset the firmware to its initial state, click "
"\"Perform reset\" (only possible with squashfs images)." "\"Perform reset\" (only possible with squashfs images)."
msgstr "" 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" msgid "Client"
msgstr "Client" msgstr "Client"
@ -668,13 +655,6 @@ msgstr "Ordre"
msgid "Common Configuration" msgid "Common Configuration"
msgstr "Configuració comuna" 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" msgid "Configuration"
msgstr "Configuració" msgstr "Configuració"
@ -743,17 +723,12 @@ msgstr ""
msgid "Custom feeds" msgid "Custom feeds"
msgstr "" msgstr ""
msgid ""
"Custom files (certificates, scripts) may remain on the system. To prevent "
"this, perform a factory-reset first."
msgstr ""
msgid "" msgid ""
"Customizes the behaviour of the device <abbr title=\"Light Emitting Diode" "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
"\">LED</abbr>s if possible." "\">LED</abbr>s if possible."
msgstr "" msgstr ""
"Personalitza el comportament dels <abbr title=\"Light Emitting Diode\">LED</" "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" msgid "DHCP Leases"
msgstr "Arrendaments DHCP" 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." msgstr "Distància al membre de la xarxa més allunyat en metres."
msgid "Distribution feeds" msgid "Distribution feeds"
msgstr "Repositoris de la distribució" msgstr ""
msgid "Diversity" msgid "Diversity"
msgstr "Diversitat" msgstr "Diversitat"
@ -961,10 +936,7 @@ msgid "Download and install package"
msgstr "Descarrega i instal·la el paquet" msgstr "Descarrega i instal·la el paquet"
msgid "Download backup" msgid "Download backup"
msgstr "Descarrega còpia de seguretat" msgstr "Descarrega còpia de seguritat"
msgid "Downstream SNR offset"
msgstr ""
msgid "Dropbear Instance" msgid "Dropbear Instance"
msgstr "Instància de Dropbear" msgstr "Instància de Dropbear"
@ -973,8 +945,8 @@ msgid ""
"Dropbear offers <abbr title=\"Secure Shell\">SSH</abbr> network shell access " "Dropbear offers <abbr title=\"Secure Shell\">SSH</abbr> network shell access "
"and an integrated <abbr title=\"Secure Copy\">SCP</abbr> server" "and an integrated <abbr title=\"Secure Copy\">SCP</abbr> server"
msgstr "" msgstr ""
"El Dropbear ofereix accés a una consola <abbr title=\"Secure Shell\">SSH</" "El Dropbear ofereix accés per la xarxa a consola <abbr title=\"Secure Shell"
"abbr> per xarxa i un servidor <abbr title=\"Secure Copy\">SCP</abbr> integrat" "\">SSH</abbr>i un servidor <abbr title=\"Secure Copy\">SCP</abbr> integrat"
msgid "Dual-Stack Lite (RFC6333)" msgid "Dual-Stack Lite (RFC6333)"
msgstr "" msgstr ""
@ -1017,11 +989,6 @@ msgstr "Emergència"
msgid "Enable" msgid "Enable"
msgstr "Habilita" msgstr "Habilita"
msgid ""
"Enable <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> "
"snooping"
msgstr ""
msgid "Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>" msgid "Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
msgstr "Habilita l'<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" msgid "Enable WPS pushbutton, requires WPA(2)-PSK"
msgstr "" msgstr ""
msgid "Enable key reinstallation (KRACK) countermeasures"
msgstr ""
msgid "Enable learning and aging" msgid "Enable learning and aging"
msgstr "Habilita l'aprenentatge i l'envelliment" msgstr "Habilita l'aprenentatge i l'envelliment"
@ -1079,9 +1043,6 @@ msgstr "Activa/Desactiva"
msgid "Enabled" msgid "Enabled"
msgstr "Habilitat" msgstr "Habilitat"
msgid "Enables IGMP snooping on this bridge"
msgstr ""
msgid "" msgid ""
"Enables fast roaming among access points that belong to the same Mobility " "Enables fast roaming among access points that belong to the same Mobility "
"Domain" "Domain"
@ -1140,26 +1101,17 @@ msgid "External R1 Key Holder List"
msgstr "" msgstr ""
msgid "External system log server" msgid "External system log server"
msgstr "Servidor de registre del sistema extern" msgstr ""
msgid "External system log server port" msgid "External system log server port"
msgstr "Port del servidor de registre del sistema extern" msgstr ""
msgid "External system log server protocol" msgid "External system log server protocol"
msgstr "Protocol del servidor de registre del sistema extern" msgstr ""
msgid "Extra SSH command options" msgid "Extra SSH command options"
msgstr "" msgstr ""
msgid "FT over DS"
msgstr ""
msgid "FT over the Air"
msgstr ""
msgid "FT protocol"
msgstr ""
msgid "File" msgid "File"
msgstr "Fitxer" msgstr "Fitxer"
@ -1214,19 +1166,19 @@ msgid "Fixed source port for outbound DNS queries"
msgstr "" msgstr ""
msgid "Flash Firmware" msgid "Flash Firmware"
msgstr "Escriptura del microprogramari a la memòria flaix" msgstr "Reescriu el microprogramari"
msgid "Flash image..." msgid "Flash image..."
msgstr "Puja una imatge..." msgstr "Escriu una imatge..."
msgid "Flash new firmware image" msgid "Flash new firmware image"
msgstr "Escriu una imatge nova a la memòria flaix" msgstr "Escriu una imatge nova"
msgid "Flash operations" msgid "Flash operations"
msgstr "Operacions a la memòria flaix" msgstr "Operacions d'escriptura"
msgid "Flashing..." msgid "Flashing..."
msgstr "Escrivint a la memòria flaix..." msgstr "Escrivent..."
msgid "Force" msgid "Force"
msgstr "Força" msgstr "Força"
@ -1253,16 +1205,13 @@ msgid "Form token mismatch"
msgstr "" msgstr ""
msgid "Forward DHCP traffic" msgid "Forward DHCP traffic"
msgstr "Reenvia el trànsit DHCP" msgstr "Reenvia el tràfic DHCP"
msgid "Forward Error Correction Seconds (FECS)" msgid "Forward Error Correction Seconds (FECS)"
msgstr "" msgstr ""
msgid "Forward broadcast traffic" msgid "Forward broadcast traffic"
msgstr "Reenvia el trànsit difós" msgstr "Reenvia el tràfic difós"
msgid "Forward mesh peer traffic"
msgstr ""
msgid "Forwarding mode" msgid "Forwarding mode"
msgstr "Mode de reenviament" msgstr "Mode de reenviament"
@ -1274,7 +1223,7 @@ msgid "Frame Bursting"
msgstr "" msgstr ""
msgid "Free" msgid "Free"
msgstr "Lliure" msgstr "Lliures"
msgid "Free space" msgid "Free space"
msgstr "Espai lliure" msgstr "Espai lliure"
@ -1303,19 +1252,16 @@ msgid "General Setup"
msgstr "" msgstr ""
msgid "General options for opkg" msgid "General options for opkg"
msgstr "Opcions generals d'opkg" msgstr ""
msgid "Generate Config" msgid "Generate Config"
msgstr "" msgstr ""
msgid "Generate PMK locally" msgid "Generate archive"
msgstr "" msgstr ""
msgid "Generate archive"
msgstr "Genera l'arxiu"
msgid "Generic 802.11%s Wireless Controller" 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!" msgid "Given password confirmation did not match, password not changed!"
msgstr "" msgstr ""
@ -1349,6 +1295,9 @@ msgstr ""
msgid "HT mode (802.11n)" msgid "HT mode (802.11n)"
msgstr "" msgstr ""
msgid "Handler"
msgstr ""
msgid "Hang Up" msgid "Hang Up"
msgstr "Penja" msgstr "Penja"
@ -1369,8 +1318,6 @@ msgid ""
"Here you can paste public SSH-Keys (one per line) for SSH public-key " "Here you can paste public SSH-Keys (one per line) for SSH public-key "
"authentication." "authentication."
msgstr "" 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" msgid "Hermes 802.11b Wireless Controller"
msgstr "Controlador sense fil Hermes 802.11b" msgstr "Controlador sense fil Hermes 802.11b"
@ -1380,7 +1327,7 @@ msgstr ""
"No mostris l'<abbr title=\"Extended Service Set Identifier\">ESSID</abbr>" "No mostris l'<abbr title=\"Extended Service Set Identifier\">ESSID</abbr>"
msgid "Host" msgid "Host"
msgstr "Nom de màquina" msgstr ""
msgid "Host entries" msgid "Host entries"
msgstr "Entrades de noms de màquina" msgstr "Entrades de noms de màquina"
@ -1449,7 +1396,7 @@ msgid "IPv4 prefix length"
msgstr "Longitud de prefix IPv4" msgstr "Longitud de prefix IPv4"
msgid "IPv4-Address" msgid "IPv4-Address"
msgstr "Adreça IPv4" msgstr "Adreça IPv6"
msgid "IPv4-in-IPv4 (RFC2003)" msgid "IPv4-in-IPv4 (RFC2003)"
msgstr "" msgstr ""
@ -1461,7 +1408,7 @@ msgid "IPv6 Firewall"
msgstr "Tallafocs IPv6" msgstr "Tallafocs IPv6"
msgid "IPv6 Neighbours" msgid "IPv6 Neighbours"
msgstr "Veïns IPv6" msgstr ""
msgid "IPv6 Settings" msgid "IPv6 Settings"
msgstr "" msgstr ""
@ -1470,7 +1417,7 @@ msgid "IPv6 ULA-Prefix"
msgstr "" msgstr ""
msgid "IPv6 WAN Status" msgid "IPv6 WAN Status"
msgstr "Estat WAN IPv6" msgstr "Estado WAN IPv6"
msgid "IPv6 address" msgid "IPv6 address"
msgstr "Adreça IPv6" msgstr "Adreça IPv6"
@ -1520,7 +1467,7 @@ msgstr "IPv6-sobre-IPv4 (6to4)"
msgid "Identity" msgid "Identity"
msgstr "Identitat" msgstr "Identitat"
msgid "If checked, 1DES is enabled" msgid "If checked, 1DES is enaled"
msgstr "" msgstr ""
msgid "If checked, encryption is disabled" msgid "If checked, encryption is disabled"
@ -1565,10 +1512,10 @@ msgid "Ignore resolve file"
msgstr "Ignora el fitxer de resolució" msgstr "Ignora el fitxer de resolució"
msgid "Image" msgid "Image"
msgstr "Fitxer d'imatge" msgstr "Imatge"
msgid "In" msgid "In"
msgstr "Entr." msgstr "En"
msgid "" msgid ""
"In order to prevent unauthorized access to the system, your request has been " "In order to prevent unauthorized access to the system, your request has been "
@ -1680,7 +1627,7 @@ msgid "Joining Network: %q"
msgstr "" msgstr ""
msgid "Keep settings" msgid "Keep settings"
msgstr "Mantenir la configuració" msgstr ""
msgid "Kernel Log" msgid "Kernel Log"
msgstr "Registre del nucli" msgstr "Registre del nucli"
@ -1737,7 +1684,7 @@ msgid "Leasefile"
msgstr "Fitxer d'arrendament" msgstr "Fitxer d'arrendament"
msgid "Leasetime remaining" msgid "Leasetime remaining"
msgstr "Temps d'arrendament restant" msgstr "Duració d'arrendament restant"
msgid "Leave empty to autodetect" msgid "Leave empty to autodetect"
msgstr "Deixeu-ho en blanc per autodetectar" msgstr "Deixeu-ho en blanc per autodetectar"
@ -1770,7 +1717,7 @@ msgid "Line Uptime"
msgstr "" msgstr ""
msgid "Link On" msgid "Link On"
msgstr "Enllaç actiu" msgstr "Enllaç activa"
msgid "" msgid ""
"List of <abbr title=\"Domain Name System\">DNS</abbr> servers to forward " "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" msgid "Listen only on the given interface or, if unspecified, on all"
msgstr "" 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" msgid "Listening port for inbound DNS queries"
msgstr "" msgstr ""
msgid "Load" msgid "Load"
msgstr "Càrrega" msgstr "Carrega"
msgid "Load Average" msgid "Load Average"
msgstr "Càrrega mitjana" msgstr "Carrega mitjana"
msgid "Loading" msgid "Loading"
msgstr "Carregant" msgstr "Carregant"
@ -1939,6 +1884,9 @@ msgstr ""
msgid "Maximum amount of seconds to wait for the modem to become ready" msgid "Maximum amount of seconds to wait for the modem to become ready"
msgstr "" msgstr ""
msgid "Maximum hold time"
msgstr ""
msgid "" msgid ""
"Maximum length of the name is 15 characters including the automatic protocol/" "Maximum length of the name is 15 characters including the automatic protocol/"
"bridge prefix (br-, 6in4-, pppoe- etc.)" "bridge prefix (br-, 6in4-, pppoe- etc.)"
@ -1956,11 +1904,11 @@ msgstr "Memòria"
msgid "Memory usage (%)" msgid "Memory usage (%)"
msgstr "Ús de Memòria (%)" msgstr "Ús de Memòria (%)"
msgid "Mesh Id"
msgstr ""
msgid "Metric" msgid "Metric"
msgstr "Mètrica" msgstr "Mètric"
msgid "Minimum hold time"
msgstr ""
msgid "Mirror monitor port" msgid "Mirror monitor port"
msgstr "" msgstr ""
@ -2096,13 +2044,13 @@ msgid "No NAT-T"
msgstr "" msgstr ""
msgid "No chains in this table" 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" msgid "No files found"
msgstr "Cap fitxer trobat" msgstr "Cap fitxer trobat"
msgid "No information available" msgid "No information available"
msgstr "No hi ha informació disponible" msgstr "Cap informació disponible"
msgid "No negative cache" msgid "No negative cache"
msgstr "Sense memòria cau negativa" msgstr "Sense memòria cau negativa"
@ -2117,7 +2065,7 @@ msgid "No package lists available"
msgstr "No hi ha llistes de paquets disponibles" msgstr "No hi ha llistes de paquets disponibles"
msgid "No password set!" msgid "No password set!"
msgstr "No hi ha cap contrasenya establerta!" msgstr "Cap contrasenya establerta!"
msgid "No rules in this chain" msgid "No rules in this chain"
msgstr "No hi ha regles en aquesta cadena" msgstr "No hi ha regles en aquesta cadena"
@ -2167,9 +2115,6 @@ msgstr "Avís"
msgid "Nslookup" msgid "Nslookup"
msgstr "Nslookup" msgstr "Nslookup"
msgid "Number of cached DNS entries (max is 10000, 0 is no caching)"
msgstr ""
msgid "OK" msgid "OK"
msgstr "D'acord" msgstr "D'acord"
@ -2285,7 +2230,7 @@ msgid "Other:"
msgstr "Altres:" msgstr "Altres:"
msgid "Out" msgid "Out"
msgstr "Sort." msgstr ""
msgid "Outbound:" msgid "Outbound:"
msgstr "Sortint:" msgstr "Sortint:"
@ -2409,6 +2354,9 @@ msgstr ""
msgid "Path to Private Key" msgid "Path to Private Key"
msgstr "Ruta a la clau privada" msgstr "Ruta a la clau privada"
msgid "Path to executable which handles the button event"
msgstr ""
msgid "Path to inner CA-Certificate" msgid "Path to inner CA-Certificate"
msgstr "" msgstr ""
@ -2499,7 +2447,7 @@ msgid "Private Key"
msgstr "" msgstr ""
msgid "Proceed" msgid "Proceed"
msgstr "Procedeix" msgstr "continua"
msgid "Processes" msgid "Processes"
msgstr "Processos" msgstr "Processos"
@ -2523,7 +2471,7 @@ msgid "Protocol support is not installed"
msgstr "" msgstr ""
msgid "Provide NTP server" msgid "Provide NTP server"
msgstr "Habilita el servidor NTP" msgstr ""
msgid "Provide new network" msgid "Provide new network"
msgstr "" msgstr ""
@ -2616,19 +2564,19 @@ msgid "Really switch protocol?"
msgstr "" msgstr ""
msgid "Realtime Connections" msgid "Realtime Connections"
msgstr "Connexions en temps real" msgstr ""
msgid "Realtime Graphs" msgid "Realtime Graphs"
msgstr "Gràfiques en temps real" msgstr ""
msgid "Realtime Load" msgid "Realtime Load"
msgstr "Càrrega en temps real" msgstr ""
msgid "Realtime Traffic" msgid "Realtime Traffic"
msgstr "Trànsit en temps real" msgstr ""
msgid "Realtime Wireless" msgid "Realtime Wireless"
msgstr "Dispositiu sense fils en temps real" msgstr ""
msgid "Reassociation Deadline" msgid "Reassociation Deadline"
msgstr "" msgstr ""
@ -2646,7 +2594,7 @@ msgid "Reboots the operating system of your device"
msgstr "Arranca de nou el sistema operatiu del teu dispositiu" msgstr "Arranca de nou el sistema operatiu del teu dispositiu"
msgid "Receive" msgid "Receive"
msgstr "Recepció" msgstr "Rep"
msgid "Receiver Antenna" msgid "Receiver Antenna"
msgstr "Antena receptora" msgstr "Antena receptora"
@ -2676,10 +2624,10 @@ msgid "Relay bridge"
msgstr "Pont de relé" msgstr "Pont de relé"
msgid "Remote IPv4 address" msgid "Remote IPv4 address"
msgstr "Adreça IPv4 remota" msgstr "Adreça IPv6 remota"
msgid "Remote IPv4 address or FQDN" msgid "Remote IPv4 address or FQDN"
msgstr "Adreça IPv4 remota o FQDN" msgstr ""
msgid "Remove" msgid "Remove"
msgstr "Treu" msgstr "Treu"
@ -2731,7 +2679,7 @@ msgid ""
msgstr "" msgstr ""
msgid "Reset" msgid "Reset"
msgstr "Restableix" msgstr "Reinicia"
msgid "Reset Counters" msgid "Reset Counters"
msgstr "Reinicia els comptadors" msgstr "Reinicia els comptadors"
@ -2749,7 +2697,7 @@ msgid "Restart"
msgstr "Reinicia" msgstr "Reinicia"
msgid "Restart Firewall" msgid "Restart Firewall"
msgstr "Reinicia el tallafocs" msgstr "Reinicia Tallafocs"
msgid "Restore backup" msgid "Restore backup"
msgstr "Restaura còpia de seguretat" msgstr "Restaura còpia de seguretat"
@ -2836,10 +2784,10 @@ msgid "Save"
msgstr "Desa" msgstr "Desa"
msgid "Save & Apply" msgid "Save & Apply"
msgstr "Desa i aplica" msgstr "Desa y aplica"
msgid "Save &#38; Apply" msgid "Save &#38; Apply"
msgstr "Desa i aplica" msgstr "Desa y aplica"
msgid "Scan" msgid "Scan"
msgstr "Escaneja" msgstr "Escaneja"
@ -2894,7 +2842,7 @@ msgstr ""
#, fuzzy #, fuzzy
msgid "Set up Time Synchronization" msgid "Set up Time Synchronization"
msgstr "Configura la sincronització de l'hora" msgstr "Sincronització de hora"
msgid "Setup DHCP Server" msgid "Setup DHCP Server"
msgstr "" msgstr ""
@ -2927,9 +2875,6 @@ msgid "Size"
msgstr "Mida" msgstr "Mida"
msgid "Size (.ipk)" msgid "Size (.ipk)"
msgstr "Mida (.ipk)"
msgid "Size of DNS query cache"
msgstr "" msgstr ""
msgid "Skip" msgid "Skip"
@ -2974,6 +2919,9 @@ msgstr "Origen"
msgid "Source routing" msgid "Source routing"
msgstr "" msgstr ""
msgid "Specifies the button state to handle"
msgstr ""
msgid "Specifies the directory the device is attached to" msgid "Specifies the directory the device is attached to"
msgstr "Especifica el directori a que el dispositiu està adjuntat" msgstr "Especifica el directori a que el dispositiu està adjuntat"
@ -3013,7 +2961,7 @@ msgid "Start priority"
msgstr "Prioritat d'inici" msgstr "Prioritat d'inici"
msgid "Startup" msgid "Startup"
msgstr "Arrencada" msgstr "Arranca"
msgid "Static IPv4 Routes" msgid "Static IPv4 Routes"
msgstr "Rutes IPv4 estàtiques" msgstr "Rutes IPv4 estàtiques"
@ -3073,9 +3021,6 @@ msgid ""
"Switch %q has an unknown topology - the VLAN settings might not be accurate." "Switch %q has an unknown topology - the VLAN settings might not be accurate."
msgstr "" msgstr ""
msgid "Switch Port Mask"
msgstr ""
msgid "Switch VLAN" msgid "Switch VLAN"
msgstr "" msgstr ""
@ -3083,7 +3028,7 @@ msgid "Switch protocol"
msgstr "Protocol de commutador" msgstr "Protocol de commutador"
msgid "Sync with browser" msgid "Sync with browser"
msgstr "Sincronitza amb el navegador" msgstr "Sincronitza amb navegador"
msgid "Synchronizing..." msgid "Synchronizing..."
msgstr "Sincronitzant..." msgstr "Sincronitzant..."
@ -3092,13 +3037,13 @@ msgid "System"
msgstr "Sistema" msgstr "Sistema"
msgid "System Log" msgid "System Log"
msgstr "Registre del sistema" msgstr "Registre de sistema"
msgid "System Properties" msgid "System Properties"
msgstr "Propietats del sistema" msgstr "Propietats de sistema"
msgid "System log buffer size" 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:" msgid "TCP:"
msgstr "TCP:" msgstr "TCP:"
@ -3186,10 +3131,6 @@ msgid ""
"compare them with the original file to ensure data integrity.<br /> Click " "compare them with the original file to ensure data integrity.<br /> Click "
"\"Proceed\" below to start the flash procedure." "\"Proceed\" below to start the flash procedure."
msgstr "" 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" msgid "The following changes have been committed"
msgstr "S'han comès els següents canvis" 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" msgstr "S&#39;han desfet els següents canvis"
msgid "The following rules are currently active on this system." 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" msgid "The given network name is not unique"
msgstr "El nom de xarxa donat no és únic" 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 " "address of your computer to reach the device again, depending on your "
"settings." "settings."
msgstr "" msgstr ""
"S'està escrivint la imatge del microprogramari a la memòria flaix.<br />NO " "El sistema s'està escrivent ara.<br />NO APAGUEU EL DISPOSITIU!<br />Espereu "
"APAGUIS EL DISPOSITIU!<br />Espera uns minuts abans d'intentar connectar-te " "uns minuts abans d'intentar connectar-vos de nou. Pot ser necessari que "
"de nou. Pot ser necessari que renovis l'adreça DHCP del teu ordinador per " "renoveu l'adreça del vostre ordinador per a connectar al dispositiu de nou, "
"connectar-te de nou a l'encaminador, depenent de la configuració que hi " "depenent dels vostres ajusts."
"tinguis."
msgid "" msgid ""
"The tunnel end-point is behind NAT, defaults to disabled and only applies to " "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 " "There is no password set on this router. Please configure a root password to "
"protect the web interface and enable SSH." "protect the web interface and enable SSH."
msgstr "" 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" msgid "This IPv4 address of the relay"
msgstr "" msgstr ""
@ -3318,13 +3256,10 @@ msgid ""
"This is the content of /etc/rc.local. Insert your own commands here (in " "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." "front of 'exit 0') to execute them at the end of the boot process."
msgstr "" 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 "" msgid ""
"This is the local endpoint address assigned by the tunnel broker, it usually " "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 "" msgstr ""
msgid "" msgid ""
@ -3357,16 +3292,19 @@ msgstr ""
"Aquesta llista mostra una vista general sobre els processos corrent al " "Aquesta llista mostra una vista general sobre els processos corrent al "
"sistema actualment i el seu estat." "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." msgid "This page gives an overview over currently active network connections."
msgstr "" msgstr ""
"Aquesta pàgina ofereix una vista general de les connexions de xarxa actives " "Aquesta pàgina ofereix una vista general de les connexions de xarxa actives "
"actualment." "actualment."
msgid "This section contains no values yet" 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" msgid "Time Synchronization"
msgstr "Sincronització de l'hora" msgstr "Sincronització de hora"
msgid "Time Synchronization is not configured yet." msgid "Time Synchronization is not configured yet."
msgstr "La sincronització de hora encara no s'ha configurat." 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 " "To restore configuration files, you can upload a previously generated backup "
"archive here." "archive here."
msgstr "" msgstr ""
"Per restaurar els fitxers de configuració, pots pujar una còpia de seguretat "
"generada anteriorment aquí."
msgid "Tone" msgid "Tone"
msgstr "" msgstr ""
@ -3391,7 +3327,7 @@ msgid "Traceroute"
msgstr "Rastre de ruta" msgstr "Rastre de ruta"
msgid "Traffic" msgid "Traffic"
msgstr "Trànsit" msgstr "Tràfic"
msgid "Transfer" msgid "Transfer"
msgstr "Transferència" msgstr "Transferència"
@ -3400,7 +3336,7 @@ msgid "Transmission Rate"
msgstr "Taxa de transmissió" msgstr "Taxa de transmissió"
msgid "Transmit" msgid "Transmit"
msgstr "Transmissió" msgstr "Transmet"
msgid "Transmit Power" msgid "Transmit Power"
msgstr "Potència de transmissió" msgstr "Potència de transmissió"
@ -3409,10 +3345,10 @@ msgid "Transmitter Antenna"
msgstr "Antena transmissora" msgstr "Antena transmissora"
msgid "Trigger" msgid "Trigger"
msgstr "Activador" msgstr ""
msgid "Trigger Mode" msgid "Trigger Mode"
msgstr "Mode d'activació" msgstr ""
msgid "Tunnel ID" msgid "Tunnel ID"
msgstr "ID del túnel" msgstr "ID del túnel"
@ -3488,9 +3424,6 @@ msgid ""
"Check \"Keep settings\" to retain the current configuration (requires a " "Check \"Keep settings\" to retain the current configuration (requires a "
"compatible firmware image)." "compatible firmware image)."
msgstr "" 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..." msgid "Upload archive..."
msgstr "Puja un arxiu..." msgstr "Puja un arxiu..."
@ -3499,7 +3432,7 @@ msgid "Uploaded File"
msgstr "Fitxer pujat" msgstr "Fitxer pujat"
msgid "Uptime" msgid "Uptime"
msgstr "Temps en marxa" msgstr "Temps d'alta"
msgid "Use <code>/etc/ethers</code>" msgid "Use <code>/etc/ethers</code>"
msgstr "Fes servir <code>/etc/ethers</code>" msgstr "Fes servir <code>/etc/ethers</code>"
@ -3545,9 +3478,9 @@ msgstr ""
msgid "" msgid ""
"Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</" "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 " "em> indentifies the host, the <em>IPv4-Address</em> specifies to the fixed "
"address to use, and the <em>Hostname</em> is assigned as a symbolic name to " "address to use and the <em>Hostname</em> is assigned as symbolic name to the "
"the requesting host. The optional <em>Lease time</em> can be used to set non-" "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." "standard host-specific lease time, e.g. 12h, 3d or infinite."
msgstr "" msgstr ""
@ -3655,7 +3588,7 @@ msgid "Waiting for command to complete..."
msgstr "Esperant que s'acabi l'ordre..." msgstr "Esperant que s'acabi l'ordre..."
msgid "Waiting for device..." msgid "Waiting for device..."
msgstr "Esperant el dispositiu..." msgstr ""
msgid "Warning" msgid "Warning"
msgstr "Advertència" msgstr "Advertència"
@ -3663,11 +3596,6 @@ msgstr "Advertència"
msgid "Warning: There are unsaved changes that will get lost on reboot!" msgid "Warning: There are unsaved changes that will get lost on reboot!"
msgstr "" 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" msgid "Whether to create an IPv6 default route over the tunnel"
msgstr "" msgstr ""
@ -3696,10 +3624,10 @@ msgid "Wireless Security"
msgstr "Seguretat sense fils" msgstr "Seguretat sense fils"
msgid "Wireless is disabled or not associated" 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..." msgid "Wireless is restarting..."
msgstr "El dispositiu sense fils està reiniciant..." msgstr "Sense fils està reiniciant..."
msgid "Wireless network is disabled" msgid "Wireless network is disabled"
msgstr "La xarxa sense fil està inhabilitada" msgstr "La xarxa sense fil està inhabilitada"
@ -3714,10 +3642,10 @@ msgid "Wireless shut down"
msgstr "Sense fils aturat" msgstr "Sense fils aturat"
msgid "Write received DNS requests to syslog" 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" msgid "Write system log to file"
msgstr "Escriure el registre del sistema al fitxer" msgstr ""
msgid "" msgid ""
"You can enable or disable installed init scripts here. Changes will applied " "You can enable or disable installed init scripts here. Changes will applied "
@ -3847,9 +3775,6 @@ msgstr "obert"
msgid "overlay" msgid "overlay"
msgstr "" msgstr ""
msgid "random"
msgstr ""
msgid "relay mode" msgid "relay mode"
msgstr "" msgstr ""
@ -3895,12 +3820,6 @@ msgstr "sí"
msgid "« Back" msgid "« Back"
msgstr "« Enrere" msgstr "« Enrere"
#~ msgid "Action"
#~ msgstr "Acció"
#~ msgid "Buttons"
#~ msgstr "Botons"
#~ msgid "Leasetime" #~ msgid "Leasetime"
#~ msgstr "Duració d'arrendament" #~ 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" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Pootle 2.0.6\n" "X-Generator: Pootle 2.0.6\n"
msgid "%.1f dB"
msgstr ""
msgid "%s is untagged in multiple VLANs!" msgid "%s is untagged in multiple VLANs!"
msgstr "" msgstr ""
@ -132,9 +129,6 @@ msgstr "<abbr title=\"Light Emitting Diode\">LED</abbr> Název"
msgid "<abbr title=\"Media Access Control\">MAC</abbr>-Address" msgid "<abbr title=\"Media Access Control\">MAC</abbr>-Address"
msgstr "<abbr title=\"Media Access Control\">MAC</abbr>-Adresa" msgstr "<abbr title=\"Media Access Control\">MAC</abbr>-Adresa"
msgid "<abbr title=\"The DHCP Unique Identifier\">DUID</abbr>"
msgstr ""
msgid "" msgid ""
"<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Dynamic Host Configuration " "<abbr title=\"maximal\">Max.</abbr> <abbr title=\"Dynamic Host Configuration "
"Protocol\">DHCP</abbr> leases" "Protocol\">DHCP</abbr> leases"
@ -217,6 +211,9 @@ msgstr "Přístupový koncentrátor"
msgid "Access Point" msgid "Access Point"
msgstr "Přístupový bod" msgstr "Přístupový bod"
msgid "Action"
msgstr "Akce"
msgid "Actions" msgid "Actions"
msgstr "Akce" msgstr "Akce"
@ -292,9 +289,6 @@ msgstr "Povolit <abbr title=\"Secure Shell\">SSH</abbr> autentizaci heslem"
msgid "Allow all except listed" msgid "Allow all except listed"
msgstr "Povolit vše mimo uvedené" msgstr "Povolit vše mimo uvedené"
msgid "Allow legacy 802.11b rates"
msgstr ""
msgid "Allow listed only" msgid "Allow listed only"
msgstr "Povolit pouze uvedené" msgstr "Povolit pouze uvedené"
@ -565,6 +559,9 @@ msgid ""
"preserved in any sysupgrade." "preserved in any sysupgrade."
msgstr "" msgstr ""
msgid "Buttons"
msgstr "Tlačítka"
msgid "CA certificate; if empty it will be saved after the first connection." msgid "CA certificate; if empty it will be saved after the first connection."
msgstr "" msgstr ""
@ -595,7 +592,7 @@ msgstr "Kanál"
msgid "Check" msgid "Check"
msgstr "Kontrola" msgstr "Kontrola"
msgid "Check filesystems before mount" msgid "Check fileystems before mount"
msgstr "" msgstr ""
msgid "Check this option to delete the existing networks from this radio." msgid "Check this option to delete the existing networks from this radio."
@ -662,13 +659,6 @@ msgstr "Příkaz"
msgid "Common Configuration" msgid "Common Configuration"
msgstr "Společná nastavení" 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" msgid "Configuration"
msgstr "Nastavení" msgstr "Nastavení"
@ -737,11 +727,6 @@ msgstr ""
msgid "Custom feeds" msgid "Custom feeds"
msgstr "" msgstr ""
msgid ""
"Custom files (certificates, scripts) may remain on the system. To prevent "
"this, perform a factory-reset first."
msgstr ""
msgid "" msgid ""
"Customizes the behaviour of the device <abbr title=\"Light Emitting Diode" "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
"\">LED</abbr>s if possible." "\">LED</abbr>s if possible."
@ -961,9 +946,6 @@ msgstr "Stáhnout a nainstalovat balíček"
msgid "Download backup" msgid "Download backup"
msgstr "Stáhnout zálohu" msgstr "Stáhnout zálohu"
msgid "Downstream SNR offset"
msgstr ""
msgid "Dropbear Instance" msgid "Dropbear Instance"
msgstr "Instance Dropbear" msgstr "Instance Dropbear"
@ -1017,11 +999,6 @@ msgstr "Záchrana"
msgid "Enable" msgid "Enable"
msgstr "Povolit" msgstr "Povolit"
msgid ""
"Enable <abbr title=\"Internet Group Management Protocol\">IGMP</abbr> "
"snooping"
msgstr ""
msgid "Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>" msgid "Enable <abbr title=\"Spanning Tree Protocol\">STP</abbr>"
msgstr "Povolit <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" msgid "Enable WPS pushbutton, requires WPA(2)-PSK"
msgstr "" msgstr ""
msgid "Enable key reinstallation (KRACK) countermeasures"
msgstr ""
msgid "Enable learning and aging" msgid "Enable learning and aging"
msgstr "Povolit ARP učení a stárnutí" msgstr "Povolit ARP učení a stárnutí"
@ -1079,9 +1053,6 @@ msgstr "Povolit/Zakázat"
msgid "Enabled" msgid "Enabled"
msgstr "Povoleno" msgstr "Povoleno"
msgid "Enables IGMP snooping on this bridge"
msgstr ""
msgid "" msgid ""
"Enables fast roaming among access points that belong to the same Mobility " "Enables fast roaming among access points that belong to the same Mobility "
"Domain" "Domain"
@ -1153,15 +1124,6 @@ msgstr ""
msgid "Extra SSH command options" msgid "Extra SSH command options"
msgstr "" msgstr ""
msgid "FT over DS"
msgstr ""
msgid "FT over the Air"
msgstr ""
msgid "FT protocol"
msgstr ""
msgid "File" msgid "File"
msgstr "Soubor" msgstr "Soubor"
@ -1263,9 +1225,6 @@ msgstr ""
msgid "Forward broadcast traffic" msgid "Forward broadcast traffic"
msgstr "Přeposílat broadcasty" msgstr "Přeposílat broadcasty"
msgid "Forward mesh peer traffic"
msgstr ""
msgid "Forwarding mode" msgid "Forwarding mode"
msgstr "Režim přeposílání" msgstr "Režim přeposílání"
@ -1310,9 +1269,6 @@ msgstr ""
msgid "Generate Config" msgid "Generate Config"
msgstr "" msgstr ""
msgid "Generate PMK locally"
msgstr ""
msgid "Generate archive" msgid "Generate archive"
msgstr "Vytvorǐt archív" msgstr "Vytvorǐt archív"
@ -1349,6 +1305,9 @@ msgstr ""
msgid "HT mode (802.11n)" msgid "HT mode (802.11n)"
msgstr "" msgstr ""
msgid "Handler"
msgstr "Handler"
msgid "Hang Up" msgid "Hang Up"
msgstr "Zavěsit" msgstr "Zavěsit"
@ -1519,7 +1478,7 @@ msgstr "IPv6-over-IPv4 (6to4)"
msgid "Identity" msgid "Identity"
msgstr "Identita" msgstr "Identita"
msgid "If checked, 1DES is enabled" msgid "If checked, 1DES is enaled"
msgstr "" msgstr ""
msgid "If checked, encryption is disabled" 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" 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" msgstr "Nejvyšší počet sekund čekání, než bude modem připraven"
msgid "Maximum hold time"
msgstr "Maximální doba držení"
msgid "" msgid ""
"Maximum length of the name is 15 characters including the automatic protocol/" "Maximum length of the name is 15 characters including the automatic protocol/"
"bridge prefix (br-, 6in4-, pppoe- etc.)" "bridge prefix (br-, 6in4-, pppoe- etc.)"
@ -1964,12 +1926,12 @@ msgstr "Paměť"
msgid "Memory usage (%)" msgid "Memory usage (%)"
msgstr "Využití paměti (%)" msgstr "Využití paměti (%)"
msgid "Mesh Id"
msgstr ""
msgid "Metric" msgid "Metric"
msgstr "Metrika" msgstr "Metrika"
msgid "Minimum hold time"
msgstr "Minimální čas zápůjčky"
msgid "Mirror monitor port" msgid "Mirror monitor port"
msgstr "" msgstr ""
@ -2175,9 +2137,6 @@ msgstr "Oznámení"
msgid "Nslookup" msgid "Nslookup"
msgstr "Nslookup" msgstr "Nslookup"
msgid "Number of cached DNS entries (max is 10000, 0 is no caching)"
msgstr ""
msgid "OK" msgid "OK"
msgstr "OK" msgstr "OK"
@ -2418,6 +2377,9 @@ msgstr "Cesta k certifikátu klienta"
msgid "Path to Private Key" msgid "Path to Private Key"
msgstr "Cesta k privátnímu klíči" 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" msgid "Path to inner CA-Certificate"
msgstr "" msgstr ""
@ -2955,9 +2917,6 @@ msgstr "Velikost"
msgid "Size (.ipk)" msgid "Size (.ipk)"
msgstr "" msgstr ""
msgid "Size of DNS query cache"
msgstr ""
msgid "Skip" msgid "Skip"
msgstr "Přeskočit" msgstr "Přeskočit"
@ -3003,6 +2962,9 @@ msgstr "Zdroj"
msgid "Source routing" msgid "Source routing"
msgstr "" msgstr ""
msgid "Specifies the button state to handle"
msgstr ""
msgid "Specifies the directory the device is attached to" msgid "Specifies the directory the device is attached to"
msgstr "" msgstr ""
@ -3107,9 +3069,6 @@ msgid ""
"Switch %q has an unknown topology - the VLAN settings might not be accurate." "Switch %q has an unknown topology - the VLAN settings might not be accurate."
msgstr "" msgstr ""
msgid "Switch Port Mask"
msgstr ""
msgid "Switch VLAN" msgid "Switch VLAN"
msgstr "" msgstr ""
@ -3366,7 +3325,7 @@ msgstr ""
msgid "" msgid ""
"This is the local endpoint address assigned by the tunnel broker, it usually " "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 "" msgstr ""
msgid "" msgid ""
@ -3399,6 +3358,9 @@ msgstr ""
"V tomto seznamu vidíte přehled aktuálně běžících systémových procesů a " "V tomto seznamu vidíte přehled aktuálně běžících systémových procesů a "
"jejich stavy." "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." msgid "This page gives an overview over currently active network connections."
msgstr "Tato stránka zobrazuje přehled aktivních síťových spojení." msgstr "Tato stránka zobrazuje přehled aktivních síťových spojení."
@ -3585,9 +3547,9 @@ msgstr "Použít směrovací tabulku"
msgid "" msgid ""
"Use the <em>Add</em> Button to add a new lease entry. The <em>MAC-Address</" "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 " "em> indentifies the host, the <em>IPv4-Address</em> specifies to the fixed "
"address to use, and the <em>Hostname</em> is assigned as a symbolic name to " "address to use and the <em>Hostname</em> is assigned as symbolic name to the "
"the requesting host. The optional <em>Lease time</em> can be used to set non-" "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." "standard host-specific lease time, e.g. 12h, 3d or infinite."
msgstr "" msgstr ""
"Použitím tlačítka <em>Přidat</em> přidáte novou zápůjčku (lease). <em>MAC " "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!" msgid "Warning: There are unsaved changes that will get lost on reboot!"
msgstr "" 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" msgid "Whether to create an IPv6 default route over the tunnel"
msgstr "" msgstr ""
@ -3888,9 +3845,6 @@ msgstr ""
msgid "overlay" msgid "overlay"
msgstr "" msgstr ""
msgid "random"
msgstr ""
msgid "relay mode" msgid "relay mode"
msgstr "" msgstr ""
@ -3936,27 +3890,6 @@ msgstr "ano"
msgid "« Back" msgid "« Back"
msgstr "« Zpět" 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" #~ msgid "Leasetime"
#~ msgstr "Doba trvání zápůjčky" #~ msgstr "Doba trvání zápůjčky"

View File

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

View File

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

View File

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

View File

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

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