From 48789fc8a3a2660d250b0ceed06936cc2911cd25 Mon Sep 17 00:00:00 2001 From: Taco Hoekwater <taco@elvenkind.com> Date: Tue, 20 May 2008 15:26:23 +0000 Subject: [PATCH] incorporate luasocket (2.0.2) --- manual/luatexref-t.pdf | Bin 453235 -> 453507 bytes manual/luatexref-t.tex | 8 + src/libs/luasocket/LICENSE | 20 + src/libs/luasocket/NEW | 14 + src/libs/luasocket/README | 6 + src/libs/luasocket/config | 60 ++ src/libs/luasocket/doc/dns.html | 132 ++++ src/libs/luasocket/doc/ftp.html | 289 +++++++++ src/libs/luasocket/doc/http.html | 333 ++++++++++ src/libs/luasocket/doc/index.html | 208 ++++++ src/libs/luasocket/doc/installation.html | 163 +++++ src/libs/luasocket/doc/introduction.html | 333 ++++++++++ src/libs/luasocket/doc/ltn12.html | 430 +++++++++++++ src/libs/luasocket/doc/luasocket.png | Bin 0 -> 11732 bytes src/libs/luasocket/doc/mime.html | 476 ++++++++++++++ src/libs/luasocket/doc/reference.css | 54 ++ src/libs/luasocket/doc/reference.html | 239 +++++++ src/libs/luasocket/doc/smtp.html | 417 ++++++++++++ src/libs/luasocket/doc/socket.html | 404 ++++++++++++ src/libs/luasocket/doc/tcp.html | 533 +++++++++++++++ src/libs/luasocket/doc/udp.html | 416 ++++++++++++ src/libs/luasocket/doc/url.html | 329 ++++++++++ src/libs/luasocket/etc/README | 89 +++ src/libs/luasocket/etc/b64.lua | 20 + src/libs/luasocket/etc/check-links.lua | 112 ++++ src/libs/luasocket/etc/check-memory.lua | 17 + src/libs/luasocket/etc/dict.lua | 152 +++++ src/libs/luasocket/etc/dispatch.lua | 302 +++++++++ src/libs/luasocket/etc/eol.lua | 14 + src/libs/luasocket/etc/forward.lua | 65 ++ src/libs/luasocket/etc/get.lua | 142 ++++ src/libs/luasocket/etc/lp.lua | 324 ++++++++++ src/libs/luasocket/etc/qp.lua | 24 + src/libs/luasocket/etc/tftp.lua | 155 +++++ src/libs/luasocket/luasocket.sln | 37 ++ src/libs/luasocket/makefile | 51 ++ src/libs/luasocket/mime.vcproj | 141 ++++ src/libs/luasocket/samples/README | 50 ++ src/libs/luasocket/samples/cddb.lua | 46 ++ src/libs/luasocket/samples/daytimeclnt.lua | 23 + src/libs/luasocket/samples/echoclnt.lua | 24 + src/libs/luasocket/samples/echosrvr.lua | 29 + src/libs/luasocket/samples/listener.lua | 26 + src/libs/luasocket/samples/lpr.lua | 51 ++ src/libs/luasocket/samples/talker.lua | 21 + src/libs/luasocket/samples/tinyirc.lua | 90 +++ src/libs/luasocket/socket.vcproj | 182 ++++++ src/libs/luasocket/src/Makefile | 64 ++ src/libs/luasocket/src/auxiliar.c | 149 +++++ src/libs/luasocket/src/auxiliar.h | 48 ++ src/libs/luasocket/src/buffer.c | 268 ++++++++ src/libs/luasocket/src/buffer.h | 47 ++ src/libs/luasocket/src/except.c | 99 +++ src/libs/luasocket/src/except.h | 35 + src/libs/luasocket/src/ftp.lua | 281 ++++++++ src/libs/luasocket/src/ftp_lua.c | 470 ++++++++++++++ src/libs/luasocket/src/http.lua | 350 ++++++++++ src/libs/luasocket/src/http_lua.c | 623 ++++++++++++++++++ src/libs/luasocket/src/inet.c | 281 ++++++++ src/libs/luasocket/src/inet.h | 42 ++ src/libs/luasocket/src/io.c | 32 + src/libs/luasocket/src/io.h | 67 ++ src/libs/luasocket/src/ltn12.lua | 292 +++++++++ src/libs/luasocket/src/ltn12_lua.c | 422 ++++++++++++ src/libs/luasocket/src/lua_preload.c | 73 +++ src/libs/luasocket/src/luasocket.c | 118 ++++ src/libs/luasocket/src/luasocket.h | 32 + src/libs/luasocket/src/makefile.orig | 90 +++ src/libs/luasocket/src/mime.c | 711 ++++++++++++++++++++ src/libs/luasocket/src/mime.h | 31 + src/libs/luasocket/src/mime.lua | 87 +++ src/libs/luasocket/src/mime_lua.c | 135 ++++ src/libs/luasocket/src/options.c | 149 +++++ src/libs/luasocket/src/options.h | 39 ++ src/libs/luasocket/src/select.c | 200 ++++++ src/libs/luasocket/src/select.h | 17 + src/libs/luasocket/src/smtp.lua | 251 ++++++++ src/libs/luasocket/src/smtp_lua.c | 412 ++++++++++++ src/libs/luasocket/src/socket.c | 5 + src/libs/luasocket/src/socket.h | 76 +++ src/libs/luasocket/src/socket.lua | 133 ++++ src/libs/luasocket/src/socket_lua.c | 217 +++++++ src/libs/luasocket/src/tcp.c | 339 ++++++++++ src/libs/luasocket/src/tcp.h | 36 ++ src/libs/luasocket/src/timeout.c | 207 ++++++ src/libs/luasocket/src/timeout.h | 30 + src/libs/luasocket/src/tp.lua | 123 ++++ src/libs/luasocket/src/tp_lua.c | 194 ++++++ src/libs/luasocket/src/udp.c | 336 ++++++++++ src/libs/luasocket/src/udp.h | 33 + src/libs/luasocket/src/unix.c | 356 ++++++++++ src/libs/luasocket/src/unix.h | 28 + src/libs/luasocket/src/url.lua | 297 +++++++++ src/libs/luasocket/src/url_lua.c | 540 ++++++++++++++++ src/libs/luasocket/src/usocket.c | 370 +++++++++++ src/libs/luasocket/src/usocket.h | 40 ++ src/libs/luasocket/src/wsocket.c | 401 ++++++++++++ src/libs/luasocket/src/wsocket.h | 21 + src/libs/luasocket/test/README | 12 + src/libs/luasocket/test/testclnt.lua | 713 +++++++++++++++++++++ src/libs/luasocket/test/testsrvr.lua | 15 + src/libs/luasocket/test/testsupport.lua | 37 ++ src/texk/web2c/luatexdir/lua/luastuff.c | 26 + src/texk/web2c/luatexdir/luatexlib.mk | 17 +- 104 files changed, 17566 insertions(+), 2 deletions(-) create mode 100644 src/libs/luasocket/LICENSE create mode 100644 src/libs/luasocket/NEW create mode 100644 src/libs/luasocket/README create mode 100644 src/libs/luasocket/config create mode 100644 src/libs/luasocket/doc/dns.html create mode 100644 src/libs/luasocket/doc/ftp.html create mode 100644 src/libs/luasocket/doc/http.html create mode 100644 src/libs/luasocket/doc/index.html create mode 100644 src/libs/luasocket/doc/installation.html create mode 100644 src/libs/luasocket/doc/introduction.html create mode 100644 src/libs/luasocket/doc/ltn12.html create mode 100644 src/libs/luasocket/doc/luasocket.png create mode 100644 src/libs/luasocket/doc/mime.html create mode 100644 src/libs/luasocket/doc/reference.css create mode 100644 src/libs/luasocket/doc/reference.html create mode 100644 src/libs/luasocket/doc/smtp.html create mode 100644 src/libs/luasocket/doc/socket.html create mode 100644 src/libs/luasocket/doc/tcp.html create mode 100644 src/libs/luasocket/doc/udp.html create mode 100644 src/libs/luasocket/doc/url.html create mode 100644 src/libs/luasocket/etc/README create mode 100644 src/libs/luasocket/etc/b64.lua create mode 100644 src/libs/luasocket/etc/check-links.lua create mode 100644 src/libs/luasocket/etc/check-memory.lua create mode 100644 src/libs/luasocket/etc/dict.lua create mode 100644 src/libs/luasocket/etc/dispatch.lua create mode 100644 src/libs/luasocket/etc/eol.lua create mode 100644 src/libs/luasocket/etc/forward.lua create mode 100644 src/libs/luasocket/etc/get.lua create mode 100644 src/libs/luasocket/etc/lp.lua create mode 100644 src/libs/luasocket/etc/qp.lua create mode 100644 src/libs/luasocket/etc/tftp.lua create mode 100644 src/libs/luasocket/luasocket.sln create mode 100644 src/libs/luasocket/makefile create mode 100644 src/libs/luasocket/mime.vcproj create mode 100644 src/libs/luasocket/samples/README create mode 100644 src/libs/luasocket/samples/cddb.lua create mode 100644 src/libs/luasocket/samples/daytimeclnt.lua create mode 100644 src/libs/luasocket/samples/echoclnt.lua create mode 100644 src/libs/luasocket/samples/echosrvr.lua create mode 100644 src/libs/luasocket/samples/listener.lua create mode 100644 src/libs/luasocket/samples/lpr.lua create mode 100644 src/libs/luasocket/samples/talker.lua create mode 100644 src/libs/luasocket/samples/tinyirc.lua create mode 100644 src/libs/luasocket/socket.vcproj create mode 100644 src/libs/luasocket/src/Makefile create mode 100644 src/libs/luasocket/src/auxiliar.c create mode 100644 src/libs/luasocket/src/auxiliar.h create mode 100644 src/libs/luasocket/src/buffer.c create mode 100644 src/libs/luasocket/src/buffer.h create mode 100644 src/libs/luasocket/src/except.c create mode 100644 src/libs/luasocket/src/except.h create mode 100644 src/libs/luasocket/src/ftp.lua create mode 100644 src/libs/luasocket/src/ftp_lua.c create mode 100644 src/libs/luasocket/src/http.lua create mode 100644 src/libs/luasocket/src/http_lua.c create mode 100644 src/libs/luasocket/src/inet.c create mode 100644 src/libs/luasocket/src/inet.h create mode 100644 src/libs/luasocket/src/io.c create mode 100644 src/libs/luasocket/src/io.h create mode 100644 src/libs/luasocket/src/ltn12.lua create mode 100644 src/libs/luasocket/src/ltn12_lua.c create mode 100644 src/libs/luasocket/src/lua_preload.c create mode 100644 src/libs/luasocket/src/luasocket.c create mode 100644 src/libs/luasocket/src/luasocket.h create mode 100644 src/libs/luasocket/src/makefile.orig create mode 100644 src/libs/luasocket/src/mime.c create mode 100644 src/libs/luasocket/src/mime.h create mode 100644 src/libs/luasocket/src/mime.lua create mode 100644 src/libs/luasocket/src/mime_lua.c create mode 100644 src/libs/luasocket/src/options.c create mode 100644 src/libs/luasocket/src/options.h create mode 100644 src/libs/luasocket/src/select.c create mode 100644 src/libs/luasocket/src/select.h create mode 100644 src/libs/luasocket/src/smtp.lua create mode 100644 src/libs/luasocket/src/smtp_lua.c create mode 100644 src/libs/luasocket/src/socket.c create mode 100644 src/libs/luasocket/src/socket.h create mode 100644 src/libs/luasocket/src/socket.lua create mode 100644 src/libs/luasocket/src/socket_lua.c create mode 100644 src/libs/luasocket/src/tcp.c create mode 100644 src/libs/luasocket/src/tcp.h create mode 100644 src/libs/luasocket/src/timeout.c create mode 100644 src/libs/luasocket/src/timeout.h create mode 100644 src/libs/luasocket/src/tp.lua create mode 100644 src/libs/luasocket/src/tp_lua.c create mode 100644 src/libs/luasocket/src/udp.c create mode 100644 src/libs/luasocket/src/udp.h create mode 100644 src/libs/luasocket/src/unix.c create mode 100644 src/libs/luasocket/src/unix.h create mode 100644 src/libs/luasocket/src/url.lua create mode 100644 src/libs/luasocket/src/url_lua.c create mode 100644 src/libs/luasocket/src/usocket.c create mode 100644 src/libs/luasocket/src/usocket.h create mode 100644 src/libs/luasocket/src/wsocket.c create mode 100644 src/libs/luasocket/src/wsocket.h create mode 100644 src/libs/luasocket/test/README create mode 100644 src/libs/luasocket/test/testclnt.lua create mode 100644 src/libs/luasocket/test/testsrvr.lua create mode 100644 src/libs/luasocket/test/testsupport.lua diff --git a/manual/luatexref-t.pdf b/manual/luatexref-t.pdf index a2eaca3e1664f6cfb3ef73fce08f2b6bcc61713f..7c36b59856228161c9b45189e6cf1412c9774b02 100644 GIT binary patch delta 14951 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 delta 14682 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 diff --git a/manual/luatexref-t.tex b/manual/luatexref-t.tex index e969b0351..87e90c731 100644 --- a/manual/luatexref-t.tex +++ b/manual/luatexref-t.tex @@ -919,8 +919,16 @@ is two 'characters' (bytes), so \type{aä} totals three. \item \lua{lzlib}, by Tiago Dionizio, \hyphenatedurl{http://mega.ist.utl.pt/~tngd/lua/}. (version 0.2) \item \lua{md5}, by Roberto Ierusalimschy \hyphenatedurl{http://www.inf.puc-rio.br/~roberto/md5/md5-5/md5.html}. + +\item \lua{luasocket}, by Diego Nehab +\hyphenatedurl{http://www.tecgraf.puc-rio.br/~diego/professional/luasocket/} +(version 2.0.2). + +Note: the \type{.lua} support modules from \type{luasocket} are also +preloaded inside the executable, there are no external file dependancies. \stopitemize + \chapter[libraries]{\LUATEX\ \LUA\ Libraries} The interfacing between \TEX\ and \LUA\ is facilitated by a set of diff --git a/src/libs/luasocket/LICENSE b/src/libs/luasocket/LICENSE new file mode 100644 index 000000000..8c3cfe5bc --- /dev/null +++ b/src/libs/luasocket/LICENSE @@ -0,0 +1,20 @@ +LuaSocket 2.0.2 license +Copyright © 2004-2007 Diego Nehab + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/libs/luasocket/NEW b/src/libs/luasocket/NEW new file mode 100644 index 000000000..0191ccd50 --- /dev/null +++ b/src/libs/luasocket/NEW @@ -0,0 +1,14 @@ +What's New + +This is just a bug-fix/update release. + + * Improved: http.request() now supports deprecated HTTP/0.9 + servers (Florian Berger) + * Fixed: could return "timedout" instead of "timeout" (Leo Leo) + * Fixed: crash when reading '*a' on closed socket (Paul Ducklin); + * Fixed: return values are consistent when reading from closed sockets; + * Fixed: case sensitivity in headers of multipart messages in + smtp.message() (Graham Henstridge); + * Fixed a couple instances of error() being called instead of base.error(). These would cause an error when an error was reported. :) (Ketmar Dark); + * Fixed: test script now uses pairs() iterator instead of the old + Lua syntax (Robert Dodier). diff --git a/src/libs/luasocket/README b/src/libs/luasocket/README new file mode 100644 index 000000000..5d65f882f --- /dev/null +++ b/src/libs/luasocket/README @@ -0,0 +1,6 @@ +This is the LuaSocket 2.0.1. It has been tested on WinXP, Mac OS X, +and Linux. Please use the Lua mailing list to report any bugs +(or "features") you encounter. + +Have fun, +Diego Nehab. diff --git a/src/libs/luasocket/config b/src/libs/luasocket/config new file mode 100644 index 000000000..49958ebcb --- /dev/null +++ b/src/libs/luasocket/config @@ -0,0 +1,60 @@ +#------ +# LuaSocket makefile configuration +# + +#------ +# Output file names +# +EXT=so +SOCKET_V=2.0.2 +MIME_V=1.0.2 +SOCKET_SO=socket.$(EXT).$(SOCKET_V) +MIME_SO=mime.$(EXT).$(MIME_V) +UNIX_SO=unix.$(EXT) + +#------ +# Lua includes and libraries +# +#LUAINC=-I/usr/local/include/lua50 +#LUAINC=-I/usr/local/include/lua5.1 +#LUAINC=-Ilua-5.1.1/src + +#------ +# Compat-5.1 directory +# +#COMPAT=compat-5.1r5 + +#------ +# Top of your Lua installation +# Relative paths will be inside the src tree +# +#INSTALL_TOP_SHARE=/usr/local/share/lua/5.0 +#INSTALL_TOP_LIB=/usr/local/lib/lua/5.0 +INSTALL_TOP_SHARE=/usr/local/share/lua/5.1 +INSTALL_TOP_LIB=/usr/local/lib/lua/5.1 + +INSTALL_DATA=cp +INSTALL_EXEC=cp + +#------ +# Compiler and linker settings +# for Mac OS X +# +#CC=gcc +#DEF= -DLUASOCKET_DEBUG -DUNIX_HAS_SUN_LEN +#CFLAGS= $(LUAINC) -I$(COMPAT) $(DEF) -pedantic -Wall -O2 -fno-common +#LDFLAGS=-bundle -undefined dynamic_lookup +#LD=export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc + +#------ +# Compiler and linker settings +# for Linux +CC=gcc +DEF=-DLUASOCKET_DEBUG +CFLAGS= $(LUAINC) $(DEF) -pedantic -Wall -O2 -fpic +LDFLAGS=-O -shared -fpic +LD=gcc + +#------ +# End of makefile configuration +# diff --git a/src/libs/luasocket/doc/dns.html b/src/libs/luasocket/doc/dns.html new file mode 100644 index 000000000..f4c3b07d2 --- /dev/null +++ b/src/libs/luasocket/doc/dns.html @@ -0,0 +1,132 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + +<head> +<meta name="description" content="LuaSocket: DNS support"> +<meta name="keywords" content="Lua, LuaSocket, DNS, Network, Library, Support"> +<title>LuaSocket: DNS support</title> +<link rel="stylesheet" href="reference.css" type="text/css"> +</head> + +<body> + +<!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=header> +<hr> +<center> +<table summary="LuaSocket logo"> +<tr><td align=center><a href="http://www.lua.org"> +<img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png"> +</a></td></tr> +<tr><td align=center valign=top>Network support for the Lua language +</td></tr> +</table> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +</center> +<hr> +</div> + +<!-- dns ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=dns>DNS</h2> + +<p> +Name resolution functions return <em>all</em> information obtained from the +resolver in a table of the form: +</p> + +<blockquote><tt> +resolved = {<br> + name = <i>canonic-name</i>,<br> + alias = <i>alias-list</i>,<br> + ip = <i>ip-address-list</i><br> +} +</tt> </blockquote> + +<p> +Note that the <tt>alias</tt> list can be empty. +</p> + +<!-- gethostname ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=gethostname> +socket.dns.<b>gethostname()</b> +</p> + +<p class=description> +Returns the standard host name for the machine as a string. +</p> + +<!-- tohostname +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=tohostname> +socket.dns.<b>tohostname(</b>address<b>)</b> +</p> + +<p class=description> +Converts from IP address to host name. +</p> + +<p class=parameters> +<tt>Address</tt> can be an IP address or host name. +</p> + +<p class=return> +The function returns a string with the canonic host name of the given +<tt>address</tt>, followed by a table with all information returned by +the resolver. In case of error, the function returns <b><tt>nil</tt></b> +followed by an error message. +</p> + +<!-- toip +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=toip> +socket.dns.<b>toip(</b>address<b>)</b> +</p> + +<p class=description> +Converts from host name to IP address. +</p> + +<p class=parameters> +<tt>Address</tt> can be an IP address or host name. +</p> + +<p class=return> +Returns a string with the first IP address found for <tt>address</tt>, +followed by a table with all information returned by the resolver. +In case of error, the function returns <b><tt>nil</tt></b> followed by an error +message. +</p> + +<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=footer> +<hr> +<center> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#down">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +<p> +<small> +Last modified by Diego Nehab on <br> +Thu Apr 20 00:25:07 EDT 2006 +</small> +</p> +</center> +</div> + +</body> +</html> diff --git a/src/libs/luasocket/doc/ftp.html b/src/libs/luasocket/doc/ftp.html new file mode 100644 index 000000000..9884f3133 --- /dev/null +++ b/src/libs/luasocket/doc/ftp.html @@ -0,0 +1,289 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + +<head> +<meta name="description" content="LuaSocket: FTP support"> +<meta name="keywords" content="Lua, LuaSocket, FTP, Network, Library, Support"> +<title>LuaSocket: FTP support</title> +<link rel="stylesheet" href="reference.css" type="text/css"> +</head> + +<body> + +<!-- header ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=header> +<hr> +<center> +<table summary="LuaSocket logo"> +<tr><td align=center><a href="http://www.lua.org"> +<img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png"> +</a></td></tr> +<tr><td align=center valign=top>Network support for the Lua language +</td></tr> +</table> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +</center> +<hr> +</div> + +<!-- ftp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=ftp>FTP</h2> + +<p> +FTP (File Transfer Protocol) is a protocol used to transfer files +between hosts. The <tt>ftp</tt> namespace offers thorough support +to FTP, under a simple interface. The implementation conforms to +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc0959.txt">RFC 959</a>. +</p> + +<p> +High level functions are provided supporting the most common operations. +These high level functions are implemented on top of a lower level +interface. Using the low-level interface, users can easily create their +own functions to access <em>any</em> operation supported by the FTP +protocol. For that, check the implementation. +</p> + +<p> +To really benefit from this module, a good understanding of +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks"> +LTN012, Filters sources and sinks</a> is necessary. +</p> + +<p> +To obtain the <tt>ftp</tt> namespace, run: +</p> + +<pre class=example> +-- loads the FTP module and any libraries it requires +local ftp = require("socket.ftp") +</pre> + +<p> +URLs MUST conform to +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc1738.txt">RFC +1738</a>, that is, an URL is a string in the form: +</p> + +<blockquote> +<tt> +[ftp://][<user>[:<password>]@]<host>[:<port>][/<path>][<i>type</i>=a|i]</tt> +</blockquote> + +<p> +The following constants in the namespace can be set to control the default behavior of +the FTP module: +</p> + +<ul> +<li> <tt>PASSWORD</tt>: default anonymous password. +<li> <tt>PORT</tt>: default port used for the control connection; +<li> <tt>TIMEOUT</tt>: sets the timeout for all I/O operations; +<li> <tt>USER</tt>: default anonymous user; +</ul> + + +<!-- ftp.get ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=get> +ftp.<b>get(</b>url<b>)</b><br> +ftp.<b>get{</b><br> + host = <i>string</i>,<br> + sink = <i>LTN12 sink</i>,<br> + argument <i>or</i> path = <i>string</i>,<br> + [user = <i>string</i>,]<br> + [password = <i>string</i>]<br> + [command = <i>string</i>,]<br> + [port = <i>number</i>,]<br> + [type = <i>string</i>,]<br> + [step = <i>LTN12 pump step</i>,]<br> + [create = <i>function</i>]<br> +<b>}</b> +</p> + +<p class=description> +The <tt>get</tt> function has two forms. The simple form has fixed +functionality: it downloads the contents of a URL and returns it as a +string. The generic form allows a <em>lot</em> more control, as explained +below. +</p> + +<p class=parameters> +If the argument of the <tt>get</tt> function is a table, the function +expects at least the fields <tt>host</tt>, <tt>sink</tt>, and one of +<tt>argument</tt> or <tt>path</tt> (<tt>argument</tt> takes +precedence). <tt>Host</tt> is the server to connect to. <tt>Sink</tt> is +the <em>simple</em> +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> +sink that will receive the downloaded data. <tt>Argument</tt> or +<tt>path</tt> give the target path to the resource in the server. The +optional arguments are the following: +</p> +<ul> +<li><tt>user</tt>, <tt>password</tt>: User name and password used for +authentication. Defaults to "<tt>ftp:anonymous@anonymous.org</tt>"; +<li><tt>command</tt>: The FTP command used to obtain data. Defaults to +"<tt>retr</tt>", but see example below; +<li><tt>port</tt>: The port to used for the control connection. Defaults to 21; +<li><tt>type</tt>: The transfer mode. Can take values "<tt>i</tt>" or +"<tt>a</tt>". Defaults to whatever is the server default; +<li><tt>step</tt>: +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> +pump step function used to pass data from the +server to the sink. Defaults to the LTN12 <tt>pump.step</tt> function; +<li><tt>create</tt>: An optional function to be used instead of +<a href=tcp.html#socket.tcp><tt>socket.tcp</tt></a> when the communications socket is created. +</ul> + +<p class=return> +If successful, the simple version returns the URL contents as a +string, and the generic function returns 1. In case of error, both +functions return <b><tt>nil</tt></b> and an error message describing the +error. +</p> + +<pre class=example> +-- load the ftp support +local ftp = require("socket.ftp") + +-- Log as user "anonymous" on server "ftp.tecgraf.puc-rio.br", +-- and get file "lua.tar.gz" from directory "pub/lua" as binary. +f, e = ftp.get("ftp://ftp.tecgraf.puc-rio.br/pub/lua/lua.tar.gz;type=i") +</pre> + +<pre class=example> +-- load needed modules +local ftp = require("socket.ftp") +local ltn12 = require("ltn12") +local url = require("socket.url") + +-- a function that returns a directory listing +function nlst(u) + local t = {} + local p = url.parse(u) + p.command = "nlst" + p.sink = ltn12.sink.table(t) + local r, e = ftp.get(p) + return r and table.concat(t), e +end +</pre> + +<!-- put ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=put> +ftp.<b>put(</b>url, content<b>)</b><br> +ftp.<b>put{</b><br> + host = <i>string</i>,<br> + source = <i>LTN12 sink</i>,<br> + argument <i>or</i> path = <i>string</i>,<br> + [user = <i>string</i>,]<br> + [password = <i>string</i>]<br> + [command = <i>string</i>,]<br> + [port = <i>number</i>,]<br> + [type = <i>string</i>,]<br> + [step = <i>LTN12 pump step</i>,]<br> + [create = <i>function</i>]<br> +<b>}</b> +</p> + +<p class=description> +The <tt>put</tt> function has two forms. The simple form has fixed +functionality: it uploads a string of content into a URL. The generic form +allows a <em>lot</em> more control, as explained below. +</p> + +<p class=parameters> +If the argument of the <tt>put</tt> function is a table, the function +expects at least the fields <tt>host</tt>, <tt>source</tt>, and one of +<tt>argument</tt> or <tt>path</tt> (<tt>argument</tt> takes +precedence). <tt>Host</tt> is the server to connect to. <tt>Source</tt> is +the <em>simple</em> +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> +source that will provide the contents to be uploaded. +<tt>Argument</tt> or +<tt>path</tt> give the target path to the resource in the server. The +optional arguments are the following: +</p> +<ul> +<li><tt>user</tt>, <tt>password</tt>: User name and password used for +authentication. Defaults to "<tt>ftp:anonymous@anonymous.org</tt>"; +<li><tt>command</tt>: The FTP command used to send data. Defaults to +"<tt>stor</tt>", but see example below; +<li><tt>port</tt>: The port to used for the control connection. Defaults to 21; +<li><tt>type</tt>: The transfer mode. Can take values "<tt>i</tt>" or +"<tt>a</tt>". Defaults to whatever is the server default; +<li><tt>step</tt>: +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> +pump step function used to pass data from the +server to the sink. Defaults to the LTN12 <tt>pump.step</tt> function; +<li><tt>create</tt>: An optional function to be used instead of +<a href=tcp.html#socket.tcp><tt>socket.tcp</tt></a> when the communications socket is created. +</ul> + +<p class=return> +Both functions return 1 if successful, or <b><tt>nil</tt></b> and an error +message describing the reason for failure. +</p> + +<pre class=example> +-- load the ftp support +local ftp = require("socket.ftp") + +-- Log as user "fulano" on server "ftp.example.com", +-- using password "silva", and store a file "README" with contents +-- "wrong password, of course" +f, e = ftp.put("ftp://fulano:silva@ftp.example.com/README", + "wrong password, of course") +</pre> + +<pre class=example> +-- load the ftp support +local ftp = require("socket.ftp") +local ltn12 = require("ltn12") + +-- Log as user "fulano" on server "ftp.example.com", +-- using password "silva", and append to the remote file "LOG", sending the +-- contents of the local file "LOCAL-LOG" +f, e = ftp.put{ + host = "ftp.example.com", + user = "fulano", + password = "silva", + command = "appe", + argument = "LOG", + source = ltn12.source.file(io.open("LOCAL-LOG", "r")) +} +</pre> + + +<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=footer> +<hr> +<center> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +<p> +<small> +Last modified by Diego Nehab on <br> +Thu Apr 20 00:25:18 EDT 2006 +</small> +</p> +</center> +</div> + +</body> +</html> diff --git a/src/libs/luasocket/doc/http.html b/src/libs/luasocket/doc/http.html new file mode 100644 index 000000000..0acac13fe --- /dev/null +++ b/src/libs/luasocket/doc/http.html @@ -0,0 +1,333 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + +<head> +<meta name="description" content="LuaSocket: HTTP support"> +<meta name="keywords" content="Lua, HTTP, Library, WWW, Browser, Network, Support"> +<title>LuaSocket: HTTP support</title> +<link rel="stylesheet" href="reference.css" type="text/css"> +</head> + +<body> + +<!-- header ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=header> +<hr> +<center> +<table summary="LuaSocket logo"> +<tr><td align=center><a href="http://www.lua.org"> +<img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png"> +</a></td></tr> +<tr><td align=center valign=top>Network support for the Lua language +</td></tr> +</table> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="introduction.html">introduction</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +</center> +<hr> +</div> + +<!-- http +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=http>HTTP</h2> + +<p> +HTTP (Hyper Text Transfer Protocol) is the protocol used to exchange +information between web-browsers and servers. The <tt>http</tt> +namespace offers full support for the client side of the HTTP +protocol (i.e., +the facilities that would be used by a web-browser implementation). The +implementation conforms to the HTTP/1.1 standard, +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2616.txt">RFC +2616</a>. +</p> + +<p> +The module exports functions that provide HTTP functionality in different +levels of abstraction. From the simple +string oriented requests, through generic +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> based, down to even lower-level if you bother to look through the source code. +</p> + +<p> +To obtain the <tt>http</tt> namespace, run: +</p> + +<pre class=example> +-- loads the HTTP module and any libraries it requires +local http = require("socket.http") +</pre> + +<p> +URLs must conform to +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc1738.txt">RFC +1738</a>, +that is, an URL is a string in the form: +</p> + +<blockquote> +<pre> +[http://][<user>[:<password>]@]<host>[:<port>][/<path>] +</pre> +</blockquote> + +<p> +MIME headers are represented as a Lua table in the form: +</p> + +<blockquote> +<table summary="MIME headers in Lua table"> +<tr><td><tt> +headers = {<br> + field-1-name = <i>field-1-value</i>,<br> + field-2-name = <i>field-2-value</i>,<br> + field-3-name = <i>field-3-value</i>,<br> + ...<br> + field-n-name = <i>field-n-value</i><br> +} +</tt></td></tr> +</table> +</blockquote> + +<p> +Field names are case insensitive (as specified by the standard) and all +functions work with lowercase field names. +Field values are left unmodified. +</p> + +<p class=note> +Note: MIME headers are independent of order. Therefore, there is no problem +in representing them in a Lua table. +</p> + +<p> +The following constants can be set to control the default behavior of +the HTTP module: +</p> + +<ul> +<li> <tt>PORT</tt>: default port used for connections; +<li> <tt>PROXY</tt>: default proxy used for connections; +<li> <tt>TIMEOUT</tt>: sets the timeout for all I/O operations; +<li> <tt>USERAGENT</tt>: default user agent reported to server. +</ul> + +<!-- http.request ++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=request> +http.<b>request(</b>url [, body]<b>)</b><br> +http.<b>request{</b><br> + url = <i>string</i>,<br> + [sink = <i>LTN12 sink</i>,]<br> + [method = <i>string</i>,]<br> + [headers = <i>header-table</i>,]<br> + [source = <i>LTN12 source</i>],<br> + [step = <i>LTN12 pump step</i>,]<br> + [proxy = <i>string</i>,]<br> + [redirect = <i>boolean</i>,]<br> + [create = <i>function</i>]<br> +<b>}</b> +</p> + +<p class=description> +The request function has two forms. The simple form downloads +a URL using the <tt>GET</tt> or <tt>POST</tt> method and is based +on strings. The generic form performs any HTTP method and is +<a href=http://lua-users.org/wiki/FiltersSourcesAndSinks>LTN12</a> based. +</p> + +<p class=parameters> +If the first argument of the <tt>request</tt> function is a string, it +should be an <tt>url</tt>. In that case, if a <tt>body</tt> +is provided as a string, the function will perform a <tt>POST</tt> method +in the <tt>url</tt>. Otherwise, it performs a <tt>GET</tt> in the +<tt>url</tt> +</p> + +<p class=parameters> +If the first argument is instead a table, the most important fields are +the <tt>url</tt> and the <em>simple</em> +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> +<tt>sink</tt> that will receive the downloaded content. +Any part of the <tt>url</tt> can be overridden by including +the appropriate field in the request table. +If authentication information is provided, the function +uses the Basic Authentication Scheme (see <a href="#authentication">note</a>) +to retrieve the document. If <tt>sink</tt> is <tt><b>nil</b></tt>, the +function discards the downloaded data. The optional parameters are the +following: +</p> +<ul> +<li><tt>method</tt>: The HTTP request method. Defaults to "GET"; +<li><tt>headers</tt>: Any additional HTTP headers to send with the request; +<li><tt>source</tt>: <em>simple</em> +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> +source to provide the request body. If there +is a body, you need to provide an appropriate "<tt>content-length</tt>" +request header field, or the function will attempt to send the body as +"<tt>chunked</tt>" (something few servers support). Defaults to the empty source; +<li><tt>step</tt>: +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> +pump step function used to move data. +Defaults to the LTN12 <tt>pump.step</tt> function. +<li><tt>proxy</tt>: The URL of a proxy server to use. Defaults to no proxy; +<li><tt>redirect</tt>: Set to <tt><b>false</b></tt> to prevent the +function from automatically following 301 or 302 server redirect messages; +<li><tt>create</tt>: An optional function to be used instead of +<a href=tcp.html#socket.tcp><tt>socket.tcp</tt></a> when the communications socket is created. +</ul> + +<p class=return> +In case of failure, the function returns <tt><b>nil</b></tt> followed by an +error message. If successful, the simple form returns the response +body as a string, followed by the response status code, the response +headers and the response status line. The generic function returns the same +information, except the first return value is just the number 1 (the body +goes to the <tt>sink</tt>). +</p> + +<p class=return> +Even when the server fails to provide the contents of the requested URL (URL not found, for example), +it usually returns a message body (a web page informing the +URL was not found or some other useless page). To make sure the +operation was successful, check the returned status <tt>code</tt>. For +a list of the possible values and their meanings, refer to <a +href="http://www.cs.princeton.edu/~diego/rfc/rfc2616.txt">RFC +2616</a>. +</p> + +<p class=description> +Here are a few examples with the simple interface: +</p> + +<pre class=example> +-- load the http module +local io = require("io") +local http = require("socket.http") +local ltn12 = require("ltn12") + +-- connect to server "www.cs.princeton.edu" and retrieves this manual +-- file from "~diego/professional/luasocket/http.html" and print it to stdout +http.request{ + url = "http://www.cs.princeton.edu/~diego/professional/luasocket/http.html", + sink = ltn12.sink.file(io.stdout) +} + +-- connect to server "www.example.com" and tries to retrieve +-- "/private/index.html". Fails because authentication is needed. +b, c, h = http.request("http://www.example.com/private/index.html") +-- b returns some useless page telling about the denied access, +-- h returns authentication information +-- and c returns with value 401 (Authentication Required) + +-- tries to connect to server "wrong.host" to retrieve "/" +-- and fails because the host does not exist. +r, e = http.request("http://wrong.host/") +-- r is nil, and e returns with value "host not found" +</pre> + +<p class=description> +And here is an example using the generic interface: +</p> + +<pre class=example> +-- load the http module +http = require("socket.http") + +-- Requests information about a document, without downloading it. +-- Useful, for example, if you want to display a download gauge and need +-- to know the size of the document in advance +r, c, h = http.request { + method = "HEAD", + url = "http://www.tecgraf.puc-rio.br/~diego" +} +-- r is 1, c is 200, and h would return the following headers: +-- h = { +-- date = "Tue, 18 Sep 2001 20:42:21 GMT", +-- server = "Apache/1.3.12 (Unix) (Red Hat/Linux)", +-- ["last-modified"] = "Wed, 05 Sep 2001 06:11:20 GMT", +-- ["content-length"] = 15652, +-- ["connection"] = "close", +-- ["content-Type"] = "text/html" +-- } +</pre> + +<p class=note id=post> +Note: When sending a POST request, simple interface adds a +"<tt>Content-type: application/x-www-form-urlencoded</tt>" +header to the request. This is the type used by +HTML forms. If you need another type, use the generic +interface. +</p> + +<p class=note id=authentication> +Note: Some URLs are protected by their +servers from anonymous download. For those URLs, the server must receive +some sort of authentication along with the request or it will deny +download and return status "401 Authentication Required". +</p> + +<p class=note> +The HTTP/1.1 standard defines two authentication methods: the Basic +Authentication Scheme and the Digest Authentication Scheme, both +explained in detail in +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2068.txt">RFC 2068</a>. +</p> + +<p class=note>The Basic Authentication Scheme sends +<tt><user></tt> and +<tt><password></tt> unencrypted to the server and is therefore +considered unsafe. Unfortunately, by the time of this implementation, +the wide majority of servers and browsers support the Basic Scheme only. +Therefore, this is the method used by the toolkit whenever +authentication is required. +</p> + +<pre class=example> +-- load required modules +http = require("socket.http") +mime = require("mime") + +-- Connect to server "www.example.com" and tries to retrieve +-- "/private/index.html", using the provided name and password to +-- authenticate the request +b, c, h = http.request("http://fulano:silva@www.example.com/private/index.html") + +-- Alternatively, one could fill the appropriate header and authenticate +-- the request directly. +r, c = http.request { + url = "http://www.example.com/private/index.html", + headers = { authentication = "Basic " .. (mime.b64("fulano:silva")) } +} +</pre> + +<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=footer> +<hr> +<center> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +<p> +<small> +Last modified by Diego Nehab on <br> +Thu Apr 20 00:25:26 EDT 2006 +</small> +</p> +</center> +</div> + +</body> +</html> diff --git a/src/libs/luasocket/doc/index.html b/src/libs/luasocket/doc/index.html new file mode 100644 index 000000000..57a790714 --- /dev/null +++ b/src/libs/luasocket/doc/index.html @@ -0,0 +1,208 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + +<head> +<meta name="description" content="The LuaSocket Homepage"> +<meta name="keywords" content="Lua, LuaSocket, Network, Library, Support, Internet"> +<title>LuaSocket: Network support for the Lua language </title> +<link rel="stylesheet" href="reference.css" type="text/css"> +</head> + +<body> + +<!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=header> +<hr> +<center> +<table summary="LuaSocket logo"> +<tr><td align=center><a href="http://www.lua.org"> +<img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png"> +</a></td></tr> +<tr><td align=center valign=top>Network support for the Lua language +</td></tr> +</table> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +</center> +<hr> +</div> + +<!-- whatis +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=whatis>What is LuaSocket?</h2> + +<p> +LuaSocket is a <a href="http://www.lua.org">Lua</a> extension library +that is composed by two parts: a C core that provides support for the TCP +and UDP transport layers, and a set of Lua modules that add support for +functionality commonly needed by applications that deal with the Internet. +</p> + +<p> +The core support has been implemented so that it is both efficient and +simple to use. It is available to any Lua application once it has been +properly initialized by the interpreter in use. The code has been tested +and runs well on several Windows and Unix platforms. </p> + +<p> +Among the support modules, the most commonly used implement the +<a href=smtp.html>SMTP</a> +(sending e-mails), +<a href=http.html>HTTP</a> +(WWW access) and +<a href=ftp.html>FTP</a> +(uploading and downloading files) client +protocols. These provide a very natural and generic interface to the +functionality defined by each protocol. +In addition, you will find that the +<a href=mime.html>MIME</a> (common encodings), +<a href=url.html>URL</a> +(anything you could possible want to do with one) and +<a href=ltn12.html>LTN12</a> +(filters, sinks, sources and pumps) modules can be very handy. +</p> + +<p> +The library is available under the same +<a href="http://www.lua.org/copyright.html"> +terms and conditions</a> as the Lua language, the MIT license. The idea is +that if you can use Lua in a project, you should also be able to use +LuaSocket. +</p> + +<p> +Copyright © 2004-2007 Diego Nehab. All rights reserved. <br> +Author: <A href="http://www.cs.princeton.edu/~diego">Diego Nehab</a> +</p> + +<!-- download +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=download>Download</h2> + +<p> +LuaSocket version 2.0.2 is now available for download! It is +compatible with Lua 5.1, and has +been tested on Windows XP, Linux, and Mac OS X. Chances +are it works well on most UNIX distributions and Windows flavors. +</p> + +<p> +The library can be downloaded in source code from the +<a href=http://luaforge.net/projects/luasocket/>LuaSocket +project page</a> at LuaForge. +Besides the full C and Lua source code for the library, the distribution +contains several examples, this user's manual and basic test procedures. +</p> + +<p> +Danilo Tuler is maintaining Win32 binaries for LuaSocket, which are also +available from LuaForge. These are compatible with the +<a href=http://luaforge.net/projects/luabinaries>LuaBinaries</a>, +also available from LuaForge. +</p> + +<p> Take a look at the <a +href=installation.html>installation</a> section of the +manual to find out how to properly install the library. +</p> + +<!-- thanks +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=thanks>Special thanks</h2> + +<p> +Throughout LuaSocket's history, many people gave suggestions that helped +improve it. For that, I thank the Lua community. +Special thanks go to +David Burgess, who has helped push the library to a new level of quality and +from whom I have learned a lot of stuff that doesn't show up in RFCs. +Special thanks also to Carlos Cassino, who played a big part in the +extensible design seen in the C core of LuaSocket 2.0. Mike Pall +has been helping a lot too! Thanks to you all! +</p> + +<!-- whatsnew +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=new>What's New</h2> + +<p> +2.0.2 is just a bug-fix/update release. +</p> + +<ul> +<li> Improved: http.request() now supports deprecated +HTTP/0.9 servers (Florian Berger); +<li> Fixed: could return "timedout" instead of "timeout" (Leo Leo); +<li> Fixed: crash when reading '*a' on closed socket (Paul Ducklin); +<li> Fixed: return values are consistent when reading from closed sockets; +<li> Fixed: case sensitivity in headers of multipart +messages in smtp.message() (Graham Henstridge); +<li> Fixed a couple instances of error() being called instead of +base.error(). These would cause an error when an error was +reported :) (Ketmar Dark); +<li> Fixed: test script now uses pairs() iterator instead +of the old Lua syntax (Robert Dodier). +</ul> + +<p> +2.0.1 is just a bug-fix/update release. +</p> + +<ul> +<li> Updated: now using <tt>compat-5.1r5</tt>; +<li> Improved: <tt>http.request</tt> is more robust to +malformed URLs (Adrian Sietsma); +<li> Improved: the simple <tt>http.request</tt> interface sends a +"<tt>Content-type: application/x-www-form-urlencoded</tt>" +header (William Trenker); +<li> Improved: <tt>http.request</tt> is robust to evil +servers that send inappropriate 100-continue messages +(David Burgess); +<li> Fixed: <tt>http.request</tt> was using the old host header during +redirects (Florian Berger); +<li> Fixed: sample <tt>unix.c</tt> had fallen through the +cracks during development (Matthew Percival); +<li> Fixed: error code was not being propagated correctly in +ftp.lua (David Burgess). +</ul> + +<!-- old ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=old>Old Versions</h2> + +<p> +All previous versions of the LuaSocket library can be downloaded <a +href="http://www.cs.princeton.edu/~diego/professional/luasocket/old"> +here</a>. Although these versions are no longer supported, they are +still available for those that have compatibility issues. +</p> + +<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=footer> +<hr> +<center> +<p class=bar> +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +<p> +<small> +Last modified by Diego Nehab on <br> +Wed Oct 3 02:07:59 BRT 2007 +</small> +</p> +</center> +</div> + +</body> +</html> diff --git a/src/libs/luasocket/doc/installation.html b/src/libs/luasocket/doc/installation.html new file mode 100644 index 000000000..0288f4af3 --- /dev/null +++ b/src/libs/luasocket/doc/installation.html @@ -0,0 +1,163 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + +<head> +<meta name="description" content="LuaSocket: Introduction to the core"> +<meta name="keywords" content="Lua, LuaSocket, TCP, UDP, Network, Support, +Installation"> +<title>LuaSocket: Installation</title> +<link rel="stylesheet" href="reference.css" type="text/css"> +</head> + +<body> + +<!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=header> +<hr> +<center> +<table summary="LuaSocket logo"> +<tr><td align=center><a href="http://www.lua.org"> +<img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png"> +</a></td></tr> +<tr><td align=center valign=top>Network support for the Lua language +</td></tr> +</table> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +</center> +<hr> +</div> + +<!-- installation ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2>Installation</h2> + +<p> LuaSocket 2.0.2 uses the new package system for Lua 5.1. +All Lua library developers are encouraged to update their libraries so that +all libraries can coexist peacefully and users can benefit from the +standardization and flexibility of the standard. +</p> + +<p> +Those stuck with Lua 5.0 will need the +<a href=http://www.keplerproject.org/compat/>compat-5.1</a> +module. It is maintained by +<a href=http://www.keplerproject.org/>The Kepler +Project</a>'s team, and implements the Lua 5.1 package proposal +on top of Lua 5.0. </p> + +<p> Here we will only describe the standard distribution. +If the standard doesn't meet your needs, we refer you to the +Lua discussion list, where any question about the package +scheme will likely already have been answered. </p> + +<h3>Directory structure</h3> + +<p> On Unix systems, the standard distribution uses two base +directories, one for system dependent files, and another for system +independent files. Let's call these directories <tt><CDIR></tt> +and <tt><LDIR></tt>, respectively. +For instance, in my laptop, I use '<tt>/usr/local/lib/lua/5.0</tt>' for +<tt><CDIR></tt> and '<tt>/usr/local/share/lua/5.0</tt>' for +<tt><LDIR></tt>. On Windows, sometimes only one directory is used, say +'<tt>c:\program files\lua\5.0</tt>'. Here is the standard LuaSocket +distribution directory structure:</p> + +<pre class=example> +<LDIR>/compat-5.1.lua +<LDIR>/ltn12.lua +<LDIR>/socket.lua +<CDIR>/socket/core.dll +<LDIR>/socket/http.lua +<LDIR>/socket/tp.lua +<LDIR>/socket/ftp.lua +<LDIR>/socket/smtp.lua +<LDIR>/socket/url.lua +<LDIR>/mime.lua +<CDIR>/mime/core.dll +</pre> + +<p> Naturally, on Unix systems, <tt>core.dll</tt> +would be replaced by <tt>core.so</tt>. +</p> + +<p> In order for the interpreter to find all LuaSocket components, three +environment variables need to be set. The first environment variable tells +the interpreter to load the <tt>compat-5.1.lua</tt> module at startup: </p> + +<pre class=example> +LUA_INIT=@<LDIR>/compat-5.1.lua +</pre> + +<p> +This is only need for Lua 5.0! Lua 5.1 comes with +the package system built in, of course. +</p> + +<p> +The other two environment variables instruct the compatibility module to +look for dynamic libraries and extension modules in the appropriate +directories and with the appropriate filename extensions. +</p> + +<pre class=example> +LUA_PATH=<LDIR>/?.lua;?.lua +LUA_CPATH=<CDIR>/?.dll;?.dll +</pre> + +<p> Again, naturally, on Unix systems the shared library extension would be +<tt>.so</tt> instead of <tt>.dll</tt>.</p> + +<h3>Using LuaSocket</h3> + +<p> With the above setup, and an interpreter with shared library support, +it should be easy to use LuaSocket. Just fire the interpreter and use the +<tt>require</tt> function to gain access to whatever module you need:</p> + +<pre class=example> +Lua 5.1.2 Copyright (C) 1994-2007 Lua.org, PUC-Rio +> socket = require("socket") +> print(socket._VERSION) +--> LuaSocket 2.0.2 +</pre> + +<p> Each module loads their dependencies automatically, so you only need to +load the modules you directly depend upon: </p> + +<pre class=example> +Lua 5.1.2 Copyright (C) 1994-2007 Lua.org, PUC-Rio +> http = require("socket.http") +> print(http.request("http://www.cs.princeton.edu/~diego/professional/luasocket")) +--> homepage gets dumped to terminal +</pre> + +<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=footer> +<hr> +<center> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#down">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +<p> +<small> +Last modified by Diego Nehab on <br> +Thu Apr 20 00:25:30 EDT 2006 +</small> +</p> +</center> +</div> + +</body> +</html> diff --git a/src/libs/luasocket/doc/introduction.html b/src/libs/luasocket/doc/introduction.html new file mode 100644 index 000000000..eff636767 --- /dev/null +++ b/src/libs/luasocket/doc/introduction.html @@ -0,0 +1,333 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + +<head> +<meta name="description" content="LuaSocket: Introduction to the core"> +<meta name="keywords" content="Lua, LuaSocket, TCP, UDP, Network, +Library, Support"> +<title>LuaSocket: Introduction to the core</title> +<link rel="stylesheet" href="reference.css" type="text/css"> +</head> + +<body> + +<!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=header> +<hr> +<center> +<table summary="LuaSocket logo"> +<tr><td align=center><a href="http://www.lua.org"> +<img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png"> +</a></td></tr> +<tr><td align=center valign=top>Network support for the Lua language +</td></tr> +</table> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +</center> +<hr> +</div> + +<!-- introduction +++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2>Introduction</h2> + +<p> +LuaSocket is a <a href="http://www.lua.org">Lua</a> extension library +that is composed by two parts: a C core that provides support for the TCP +and UDP transport layers, and a set of Lua modules that add support for +the SMTP (sending e-mails), HTTP (WWW access) and FTP (uploading and +downloading files) protocols and other functionality commonly needed by +applications that deal with the Internet. This introduction is about the C +core. +</p> + +<p> +Communication in LuaSocket is performed via I/O objects. These can +represent different network domains. Currently, support is provided for TCP +and UDP, but nothing prevents other developers from implementing SSL, Local +Domain, Pipes, File Descriptors etc. I/O objects provide a standard +interface to I/O across different domains and operating systems. +</p> + +<p> +The API design had two goals in mind. First, users +experienced with the C API to sockets should feel comfortable using LuaSocket. +Second, the simplicity and the feel of the Lua language should be +preserved. To achieve these goals, the LuaSocket API keeps the function names and semantics the C API whenever possible, but their usage in Lua has been greatly simplified. +</p> + + +<p> +One of the simplifications is the receive pattern capability. +Applications can read data from stream domains (such as TCP) +line by line, block by block, or until the connection is closed. +All I/O reads are buffered and the performance differences between +different receive patterns are negligible. +</p> + +<p> +Another advantage is the flexible timeout control +mechanism. As in C, all I/O operations are blocking by default. For +example, the <a href=tcp.html#send><tt>send</tt></a>, +<a href=tcp.html#receive><tt>receive</tt></a> and +<a href=tcp.html#accept><tt>accept</tt></a> methods +of the TCP domain will block the caller application until +the operation is completed (if ever!). However, with a call to the +<a href=tcp.html#settimeout><tt>settimeout</tt></a> +method, an application can specify upper limits on +the time it can be blocked by LuaSocket (the "<tt>total</tt>" timeout), on +the time LuaSocket can internally be blocked by any OS call (the +"<tt>block</tt>" timeout) or a combination of the two. Each LuaSocket +call might perform several OS calls, so that the two timeout values are +<em>not</em> equivalent. +</p> + +<p> +Finally, the host name resolution is transparent, meaning that most +functions and methods accept both IP addresses and host names. In case a +host name is given, the library queries the system's resolver and +tries the main IP address returned. Note that direct use of IP addresses +is more efficient, of course. The +<a href=dns.html#toip><tt>toip</tt></a> +and <a href=dns.html#tohostname><tt>tohostname</tt></a> +functions from the DNS module are provided to convert between host names and IP addresses. +</p> + +<p> +Together, these changes make network programming in LuaSocket much simpler +than it is in C, as the following sections will show. +</p> + +<!-- tcp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h3 id=tcp>TCP</h3> + +<p> +TCP (Transfer Control Protocol) is reliable stream protocol. In other +words, applications communicating through TCP can send and receive data as +an error free stream of bytes. Data is split in one end and +reassembled transparently on the other end. There are no boundaries in +the data transfers. The library allows users to read data from the +sockets in several different granularities: patterns are available for +lines, arbitrary sized blocks or "read up to connection closed", all with +good performance. +</p> + +<p> +The library distinguishes three types of TCP sockets: <em>master</em>, +<em>client</em> and <em>server</em> sockets. +</p> + +<p> +Master sockets are newly created TCP sockets returned by the function +<a href=tcp.html#tcp><tt>socket.tcp</tt></a>. A master socket is +transformed into a server socket +after it is associated with a <em>local</em> address by a call to the +<a href=tcp.html#bind><tt>bind</tt></a> method followed by a call to the +<a href=tcp.html#listen><tt>listen</tt></a>. Conversely, a master socket +can be changed into a client socket with the method +<a href=tcp.html#connect><tt>connect</tt></a>, +which associates it with a <em>remote</em> address. +</p> + +<p> +On server sockets, applications can use the +<a href=tcp.html#accept><tt>accept</tt></a> method +to wait for a client connection. Once a connection is established, a +client socket object is returned representing this connection. The +other methods available for server socket objects are +<a href=tcp.html#getsockname><tt>getsockname</tt></a>, +<a href=tcp.html#setoption><tt>setoption</tt></a>, +<a href=tcp.html#settimeout><tt>settimeout</tt></a>, and +<a href=tcp.html#close><tt>close</tt></a>. +</p> + +<p> +Client sockets are used to exchange data between two applications over +the Internet. Applications can call the methods +<a href=tcp.html#send><tt>send</tt></a> and +<a href=tcp.html#receive><tt>receive</tt></a> +to send and receive data. The other methods +available for client socket objects are +<a href=tcp.html#getsockname><tt>getsockname</tt></a>, +<a href=tcp.html#getpeername><tt>getpeername</tt></a>, +<a href=tcp.html#setoption><tt>setoption</tt></a>, +<a href=tcp.html#settimeout><tt>settimeout</tt></a>, +<a href=tcp.html#shutdown><tt>shutdown</tt></a>, and +<a href=tcp.html#close><tt>close</tt></a>. +</p> + +<p> +Example: +</p> +<blockquote> +<p> +A simple echo server, using LuaSocket. The program binds to an ephemeral +port (one that is chosen by the operating system) on the local host and +awaits client connections on that port. When a connection is established, +the program reads a line from the remote end and sends it back, closing +the connection immediately. You can test it using the telnet +program. +</p> + +<pre class=example> +-- load namespace +local socket = require("socket") +-- create a TCP socket and bind it to the local host, at any port +local server = assert(socket.bind("*", 0)) +-- find out which port the OS chose for us +local ip, port = server:getsockname() +-- print a message informing what's up +print("Please telnet to localhost on port " .. port) +print("After connecting, you have 10s to enter a line to be echoed") +-- loop forever waiting for clients +while 1 do + -- wait for a connection from any client + local client = server:accept() + -- make sure we don't block waiting for this client's line + client:settimeout(10) + -- receive the line + local line, err = client:receive() + -- if there was no error, send it back to the client + if not err then client:send(line .. "\n") end + -- done with client, close the object + client:close() +end +</pre> +</blockquote> + +<!-- udp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h3 id=udp>UDP</h3> + +<p> +UDP (User Datagram Protocol) is a non-reliable datagram protocol. In +other words, applications communicating through UDP send and receive +data as independent blocks, which are not guaranteed to reach the other +end. Even when they do reach the other end, they are not guaranteed to be +error free. Data transfers are atomic, one datagram at a time. Reading +only part of a datagram discards the rest, so that the following read +operation will act on the next datagram. The advantages are in +simplicity (no connection setup) and performance (no error checking or +error correction). +</p> + +<p> +Note that although no guarantees are made, these days +networks are so good that, under normal circumstances, few errors +happen in practice. +</p> + +<p> +An UDP socket object is created by the +<a href=udp.html#udp><tt>socket.udp</tt></a> function. UDP +sockets do not need to be connected before use. The method +<a href=udp.html#sendto><tt>sendto</tt></a> +can be used immediately after creation to +send a datagram to IP address and port. Host names are not allowed +because performing name resolution for each packet would be forbiddingly +slow. Methods +<a href=udp.html#receive><tt>receive</tt></a> and +<a href=udp.html#receivefrom><tt>receivefrom</tt></a> +can be used to retrieve datagrams, the latter returning the IP and port of +the sender as extra return values (thus being slightly less +efficient). +</p> + +<p> +When communication is performed repeatedly with a single peer, an +application should call the +<a href=udp.html#setpeername><tt>setpeername</tt></a> method to specify a +permanent partner. Methods +<a href=udp.html#sendto><tt>sendto</tt></a> and +<a href=udp.html#receivefrom><tt>receivefrom</tt></a> +can no longer be used, but the method +<a href=udp.html#send><tt>send</tt></a> can be used to send data +directly to the peer, and the method +<a href=udp.html#receive><tt>receive</tt></a> +will only return datagrams originating +from that peer. There is about 30% performance gain due to this practice. +</p> + +<p> +To associate an UDP socket with a local address, an application calls the +<a href=udp.html#setsockname><tt>setsockname</tt></a> +method <em>before</em> sending any datagrams. Otherwise, the socket is +automatically bound to an ephemeral address before the first data +transmission and once bound the local address cannot be changed. +The other methods available for UDP sockets are +<a href=udp.html#getpeername><tt>getpeername</tt></a>, +<a href=udp.html#getsockname><tt>getsockname</tt></a>, +<a href=udp.html#settimeout><tt>settimeout</tt></a>, +<a href=udp.html#setoption><tt>setoption</tt></a> and +<a href=udp.html#close><tt>close</tt></a>. +</p> + +<p> +Example: +</p> +<blockquote> +<p> +A simple daytime client, using LuaSocket. The program connects to a remote +server and tries to retrieve the daytime, printing the answer it got or an +error message. +</p> + +<pre class=example> +-- change here to the host an port you want to contact +local host, port = "localhost", 13 +-- load namespace +local socket = require("socket") +-- convert host name to ip address +local ip = assert(socket.dns.toip(host)) +-- create a new UDP object +local udp = assert(socket.udp()) +-- contact daytime host +assert(udp:sendto("anything", ip, port)) +-- retrieve the answer and print results +io.write(assert(udp:receive())) +</pre> +</blockquote> + +<!-- More +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h3 id=more>Support modules</h3> + +<p> Although not covered in the introduction, LuaSocket offers +much more than TCP and UDP functionality. As the library +evolved, support for <a href=http.html>HTTP</a>, <a href=ftp.html>FTP</a>, +and <a href=smtp.html>SMTP</a> were built on top of these. These modules +and many others are covered by the <a href=reference.html>reference manual</a>. +</p> + +<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=footer> +<hr> +<center> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#down">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +<p> +<small> +Last modified by Diego Nehab on <br> +Thu Apr 20 00:25:36 EDT 2006 +</small> +</p> +</center> +</div> + +</body> +</html> diff --git a/src/libs/luasocket/doc/ltn12.html b/src/libs/luasocket/doc/ltn12.html new file mode 100644 index 000000000..001395030 --- /dev/null +++ b/src/libs/luasocket/doc/ltn12.html @@ -0,0 +1,430 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + +<head> +<meta name="description" content="LuaSocket: LTN12 support"> +<meta name="keywords" content="Lua, LuaSocket, Filters, Source, Sink, +Pump, Support, Library"> +<title>LuaSocket: LTN12 module</title> +<link rel="stylesheet" href="reference.css" type="text/css"> +</head> + +<body> + +<!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=header> +<hr> +<center> +<table summary="LuaSocket logo"> +<tr><td align=center><a href="http://www.lua.org"> +<img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png"> +</a></td></tr> +<tr><td align=center valign=top>Network support for the Lua language +</td></tr> +</table> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +</center> +<hr> +</div> + +<!-- ltn12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=ltn12>LTN12</h2> + +<p> The <tt>ltn12</tt> namespace implements the ideas described in +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks"> +LTN012, Filters sources and sinks</a>. This manual simply describes the +functions. Please refer to the LTN for a deeper explanation of the +functionality provided by this module. +</p> + +<p> +To obtain the <tt>ltn12</tt> namespace, run: +</p> + +<pre class=example> +-- loads the LTN21 module +local ltn12 = require("ltn12") +</pre> + +<!-- filters ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h3 id="filter">Filters</h3> + +<!-- chain ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="filter.chain"> +ltn12.filter.<b>chain(</b>filter<sub>1</sub>, filter<sub>2</sub> +[, ... filter<sub>N</sub>]<b>)</b> +</p> + +<p class=description> +Returns a filter that passes all data it receives through each of a +series of given filters. +</p> + +<p class=parameters> +<tt>Filter<sub>1</sub></tt> to <tt>filter<sub>N</sub></tt> are simple +filters. +</p> + +<p class=return> +The function returns the chained filter. +</p> + +<p class=note> +The nesting of filters can be arbitrary. For instance, the useless filter +below doesn't do anything but return the data that was passed to it, +unaltered. +</p> + +<pre class=example> +-- load required modules +local ltn12 = require("ltn12") +local mime = require("mime") + +-- create a silly identity filter +id = ltn12.filter.chain( + mime.encode("quoted-printable"), + mime.encode("base64"), + mime.decode("base64"), + mime.decode("quoted-printable") +) +</pre> + +<!-- cycle ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="filter.cycle"> +ltn12.filter.<b>cycle(</b>low [, ctx, extra]<b>)</b> +</p> + +<p class=description> +Returns a high-level filter that cycles though a low-level filter by +passing it each chunk and updating a context between calls. +</p> + +<p class=parameters> +<tt>Low</tt> is the low-level filter to be cycled, +<tt>ctx</tt> is the initial context and <tt>extra</tt> is any extra +argument the low-level filter might take. +</p> + +<p class=return> +The function returns the high-level filter. +</p> + +<pre class=example> +-- load the ltn12 module +local ltn12 = require("ltn12") + +-- the base64 mime filter factory +encodet['base64'] = function() + return ltn12.filter.cycle(b64, "") +end +</pre> + +<!-- pumps ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h3 id="pump">Pumps</h3> + +<!-- all ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="pump.all"> +ltn12.pump.<b>all(</b>source, sink<b>)</b> +</p> + +<p class=description> +Pumps <em>all</em> data from a <tt>source</tt> to a <tt>sink</tt>. +</p> + +<p class=return> +If successful, the function returns a value that evaluates to +<b><tt>true</tt></b>. In case +of error, the function returns a <b><tt>false</tt></b> value, followed by an error message. +</p> + +<!-- step +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="pump.step"> +ltn12.pump.<b>step(</b>source, sink<b>)</b> +</p> + +<p class=description> +Pumps <em>one</em> chunk of data from a <tt>source</tt> to a <tt>sink</tt>. +</p> + +<p class=return> +If successful, the function returns a value that evaluates to +<b><tt>true</tt></b>. In case +of error, the function returns a <b><tt>false</tt></b> value, followed by an error message. +</p> + +<!-- sinks ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h3 id="sink">Sinks</h3> + +<!-- chain ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="sink.chain"> +ltn12.sink.<b>chain(</b>filter, sink<b>)</b> +</p> + +<p class=description> +Creates and returns a new sink that passes data through a <tt>filter</tt> before sending it to a given <tt>sink</tt>. +</p> + +<!-- error ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="sink.error"> +ltn12.sink.<b>error(</b>message<b>)</b> +</p> + +<p class=description> +Creates and returns a sink that aborts transmission with the error +<tt>message</tt>. +</p> + +<!-- file +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="sink.file"> +ltn12.sink.<b>file(</b>handle, message<b>)</b> +</p> + +<p class=description> +Creates a sink that sends data to a file. +</p> + +<p class=parameters> +<tt>Handle</tt> is a file handle. If <tt>handle</tt> is <tt><b>nil</b></tt>, +<tt>message</tt> should give the reason for failure. +</p> + +<p class=return> +The function returns a sink that sends all data to the given <tt>handle</tt> +and closes the file when done, or a sink that aborts the transmission with +the error <tt>message</tt> +</p> + +<p class=note> +In the following example, notice how the prototype is designed to +fit nicely with the <tt>io.open</tt> function. +</p> + +<pre class=example> +-- load the ltn12 module +local ltn12 = require("ltn12") + +-- copy a file +ltn12.pump.all( + ltn12.source.file(io.open("original.png")), + ltn12.sink.file(io.open("copy.png")) +) +</pre> + +<!-- null +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="sink.null"> +ltn12.sink.<b>null()</b> +</p> + +<p class=description> +Returns a sink that ignores all data it receives. +</p> + +<!-- simplify +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="sink.simplify"> +ltn12.sink.<b>simplify(</b>sink<b>)</b> +</p> + +<p class=description> +Creates and returns a simple sink given a fancy <tt>sink</tt>. +</p> + +<!-- table ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="sink.table"> +ltn12.sink.<b>table(</b>[table]<b>)</b> +</p> + +<p class=description> +Creates a sink that stores all chunks in a table. The chunks can later be +efficiently concatenated into a single string. +</p> + +<p class=parameters> +<tt>Table</tt> is used to hold the chunks. If +<tt><b>nil</b></tt>, the function creates its own table. +</p> + +<p class=return> +The function returns the sink and the table used to store the chunks. +</p> + +<pre class=example> +-- load needed modules +local http = require("socket.http") +local ltn12 = require("ltn12") + +-- a simplified http.get function +function http.get(u) + local t = {} + local respt = request{ + url = u, + sink = ltn12.sink.table(t) + } + return table.concat(t), respt.headers, respt.code +end +</pre> + +<!-- sinks ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h3 id="source">Sources</h3> + +<!-- cat ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="source.cat"> +ltn12.source.<b>cat(</b>source<sub>1</sub> [, source<sub>2</sub>, ..., +source<sub>N</sub>]<b>)</b> +</p> + +<p class=description> +Creates a new source that produces the concatenation of the data produced +by a number of sources. +</p> + +<p class=parameters> +<tt>Source<sub>1</sub></tt> to <tt>source<sub>N</sub></tt> are the original +sources. +</p> + +<p class=return> +The function returns the new source. +</p> + +<!-- chain ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="source.chain"> +ltn12.source.<b>chain(</b>source, filter<b>)</b> +</p> + +<p class=description> +Creates a new <tt>source</tt> that passes data through a <tt>filter</tt> +before returning it. +</p> + +<p class=return> +The function returns the new source. +</p> + +<!-- empty ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="source.empty"> +ltn12.source.<b>empty()</b> +</p> + +<p class=description> +Creates and returns an empty source. +</p> + +<!-- error ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="source.error"> +ltn12.source.<b>error(</b>message<b>)</b> +</p> + +<p class=description> +Creates and returns a source that aborts transmission with the error +<tt>message</tt>. +</p> + +<!-- file +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="source.file"> +ltn12.source.<b>file(</b>handle, message<b>)</b> +</p> + +<p class=description> +Creates a source that produces the contents of a file. +</p> + +<p class=parameters> +<tt>Handle</tt> is a file handle. If <tt>handle</tt> is <tt><b>nil</b></tt>, +<tt>message</tt> should give the reason for failure. +</p> + +<p class=return> +The function returns a source that reads chunks of data from +given <tt>handle</tt> and returns it to the user, +closing the file when done, or a source that aborts the transmission with +the error <tt>message</tt> +</p> + +<p class=note> +In the following example, notice how the prototype is designed to +fit nicely with the <tt>io.open</tt> function. +</p> + +<pre class=example> +-- load the ltn12 module +local ltn12 = require("ltn12") + +-- copy a file +ltn12.pump.all( + ltn12.source.file(io.open("original.png")), + ltn12.sink.file(io.open("copy.png")) +) +</pre> + +<!-- simplify +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="source.simplify"> +ltn12.source.<b>simplify(</b>source<b>)</b> +</p> + +<p class=description> +Creates and returns a simple source given a fancy <tt>source</tt>. +</p> + +<!-- string +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="source.string"> +ltn12.source.<b>string(</b>string<b>)</b> +</p> + +<p class=description> +Creates and returns a source that produces the contents of a +<tt>string</tt>, chunk by chunk. +</p> + +<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=footer> +<hr> +<center> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#down">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +<p> +<small> +Last modified by Diego Nehab on <br> +Thu Apr 20 00:25:41 EDT 2006 +</small> +</p> +</center> +</div> + +</body> +</html> diff --git a/src/libs/luasocket/doc/luasocket.png b/src/libs/luasocket/doc/luasocket.png new file mode 100644 index 0000000000000000000000000000000000000000..d24a95495b55894b96aec1b01d0b7c02cc43f168 GIT binary patch literal 11732 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 XyRqY5hf@3l*8!B|RAozL%>4cb*_o<b literal 0 HcmV?d00001 diff --git a/src/libs/luasocket/doc/mime.html b/src/libs/luasocket/doc/mime.html new file mode 100644 index 000000000..d7faf52cb --- /dev/null +++ b/src/libs/luasocket/doc/mime.html @@ -0,0 +1,476 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + +<head> +<meta name="description" content="LuaSocket: MIME support"> +<meta name="keywords" content="Lua, LuaSocket, MIME, Library, Support"> +<title>LuaSocket: MIME module</title> +<link rel="stylesheet" href="reference.css" type="text/css"> +</head> + +<body> + +<!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=header> +<hr> +<center> +<table summary="LuaSocket logo"> +<tr><td align=center><a href="http://www.lua.org"> +<img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png"> +</a></td></tr> +<tr><td align=center valign=top>Network support for the Lua language +</td></tr> +</table> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +</center> +<hr> +</div> + +<!-- mime +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=mime>MIME</h2> + +<p> +The <tt>mime</tt> namespace offers filters that apply and remove common +content transfer encodings, such as Base64 and Quoted-Printable. +It also provides functions to break text into lines and change +the end-of-line convention. +MIME is described mainly in +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2045.txt">RFC 2045</a>, +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2046.txt">2046</a>, +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2047.txt">2047</a>, +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2047.txt">2048</a>, and +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2048.txt">2049</a>. +</p> + +<p> +All functionality provided by the MIME module +follows the ideas presented in +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks"> +LTN012, Filters sources and sinks</a>. +</p> + +<p> +To obtain the <tt>mime</tt> namespace, run: +</p> + +<pre class=example> +-- loads the MIME module and everything it requires +local mime = require("mime") +</pre> + + +<!-- High-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h3 id=high>High-level filters</h3> + +<!-- normalize ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="normalize"> +mime.<b>normalize(</b>[marker]<b>)</b> +</p> + +<p class=description> +Converts most common end-of-line markers to a specific given marker. +</p> + +<p class=parameters> +<tt>Marker</tt> is the new marker. It defaults to CRLF, the canonic +end-of-line marker defined by the MIME standard. +</p> + +<p class=return> +The function returns a filter that performs the conversion. +</p> + +<p class=note> +Note: There is no perfect solution to this problem. Different end-of-line +markers are an evil that will probably plague developers forever. +This function, however, will work perfectly for text created with any of +the most common end-of-line markers, i.e. the Mac OS (CR), the Unix (LF), +or the DOS (CRLF) conventions. Even if the data has mixed end-of-line +markers, the function will still work well, although it doesn't +guarantee that the number of empty lines will be correct. +</p> + +<!-- decode +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="decode"> +mime.<b>decode(</b>"base64"<b>)</b><br> +mime.<b>decode(</b>"quoted-printable"<b>)</b> +</p> + +<p class=description> +Returns a filter that decodes data from a given transfer content +encoding. +</p> + +<!-- encode +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="encode"> +mime.<b>encode(</b>"base64"<b>)</b><br> +mime.<b>encode(</b>"quoted-printable" [, mode]<b>)</b> +</p> + +<p class=description> +Returns a filter that encodes data according to a given transfer content +encoding. +</p> + +<p class=parameters> +In the Quoted-Printable case, the user can specify whether the data is +textual or binary, by passing the <tt>mode</tt> strings "<tt>text</tt>" or +"<tt>binary</tt>". <tt>Mode</tt> defaults to "<tt>text</tt>". +</p> + +<p class=note> +Although both transfer content encodings specify a limit for the line +length, the encoding filters do <em>not</em> break text into lines (for +added flexibility). +Below is a filter that converts binary data to the Base64 transfer content +encoding and breaks it into lines of the correct size. +</p> + +<pre class=example> +base64 = ltn12.filter.chain( + mime.encode("base64"), + mime.wrap("base64") +) +</pre> + +<p class=note> +Note: Text data <em>has</em> to be converted to canonic form +<em>before</em> being encoded. +</p> + +<pre class=example> +base64 = ltn12.filter.chain( + mime.normalize(), + mime.encode("base64"), + mime.wrap("base64") +) +</pre> + +<!-- stuff +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="stuff"> +mime.<b>stuff()</b><br> +</p> + +<p class=description> +Creates and returns a filter that performs stuffing of SMTP messages. +</p> + +<p class=note> +Note: The <a href=smtp.html#send><tt>smtp.send</tt></a> function +uses this filter automatically. You don't need to chain it with your +source, or apply it to your message body. +</p> + +<!-- wrap +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="wrap"> +mime.<b>wrap(</b>"text" [, length]<b>)</b><br> +mime.<b>wrap(</b>"base64"<b>)</b><br> +mime.<b>wrap(</b>"quoted-printable"<b>)</b> +</p> + +<p class=description> +Returns a filter that breaks data into lines. +</p> + +<p class=parameters> +The "<tt>text</tt>" line-wrap filter simply breaks text into lines by +inserting CRLF end-of-line markers at appropriate positions. +<tt>Length</tt> defaults 76. +The "<tt>base64</tt>" line-wrap filter works just like the default +"<tt>text</tt>" line-wrap filter with default length. +The function can also wrap "<tt>quoted-printable</tt>" lines, taking care +not to break lines in the middle of an escaped character. In that case, the +line length is fixed at 76. +</p> + +<p class=note> +For example, to create an encoding filter for the Quoted-Printable transfer content encoding of text data, do the following: +</p> + +<pre class=example> +qp = ltn12.filter.chain( + mime.normalize(), + mime.encode("quoted-printable"), + mime.wrap("quoted-printable") +) +</pre> + +<p class=note> +Note: To break into lines with a different end-of-line convention, apply +a normalization filter after the line break filter. +</p> + +<!-- Low-level ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h3 id=low>Low-level filters</h3> + +<!-- b64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="b64"> +A, B = mime.<b>b64(</b>C [, D]<b>)</b> +</p> + +<p class=description> +Low-level filter to perform Base64 encoding. +</p> + +<p class=description> +<tt>A</tt> is the encoded version of the largest prefix of +<tt>C..D</tt> +that can be encoded unambiguously. <tt>B</tt> has the remaining bytes of +<tt>C..D</tt>, <em>before</em> encoding. +If <tt>D</tt> is <tt><b>nil</b></tt>, <tt>A</tt> is padded with +the encoding of the remaining bytes of <tt>C</tt>. +</p> + +<p class=note> +Note: The simplest use of this function is to encode a string into it's +Base64 transfer content encoding. Notice the extra parenthesis around the +call to <tt>mime.b64</tt>, to discard the second return value. +</p> + +<pre class=example> +print((mime.b64("diego:password"))) +--> ZGllZ286cGFzc3dvcmQ= +</pre> + +<!-- dot +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> +<p class=name id="dot"> +A, n = mime.<b>dot(</b>m [, B]<b>)</b> +</p> + +<p class=description> +Low-level filter to perform SMTP stuffing and enable transmission of +messages containing the sequence "CRLF.CRLF". +</p> + +<p class=parameters> +<tt>A</tt> is the stuffed version of <tt>B</tt>. '<tt>n</tt>' gives the +number of characters from the sequence CRLF seen in the end of <tt>B</tt>. +'<tt>m</tt>' should tell the same, but for the previous chunk. +</p> + +<p class=note>Note: The message body is defined to begin with +an implicit CRLF. Therefore, to stuff a message correctly, the +first <tt>m</tt> should have the value 2. +</p> + +<pre class=example> +print((string.gsub(mime.dot(2, ".\r\nStuffing the message.\r\n.\r\n."), "\r\n", "\\n"))) +--> ..\nStuffing the message.\n..\n.. +</pre> + +<p class=note> +Note: The <a href=smtp.html#send><tt>smtp.send</tt></a> function +uses this filter automatically. You don't need to +apply it again. +</p> + +<!-- eol ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="eol"> +A, B = mime.<b>eol(</b>C [, D, marker]<b>)</b> +</p> + +<p class=description> +Low-level filter to perform end-of-line marker translation. +For each chunk, the function needs to know if the last character of the +previous chunk could be part of an end-of-line marker or not. This is the +context the function receives besides the chunk. An updated version of +the context is returned after each new chunk. +</p> + +<p class=parameters> +<tt>A</tt> is the translated version of <tt>D</tt>. <tt>C</tt> is the +ASCII value of the last character of the previous chunk, if it was a +candidate for line break, or 0 otherwise. +<tt>B</tt> is the same as <tt>C</tt>, but for the current +chunk. <tt>Marker</tt> gives the new end-of-line marker and defaults to CRLF. +</p> + +<pre class=example> +-- translates the end-of-line marker to UNIX +unix = mime.eol(0, dos, "\n") +</pre> + +<!-- qp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="qp"> +A, B = mime.<b>qp(</b>C [, D, marker]<b>)</b> +</p> + +<p class=description> +Low-level filter to perform Quoted-Printable encoding. +</p> + +<p class=parameters> +<tt>A</tt> is the encoded version of the largest prefix of +<tt>C..D</tt> +that can be encoded unambiguously. <tt>B</tt> has the remaining bytes of +<tt>C..D</tt>, <em>before</em> encoding. +If <tt>D</tt> is <tt><b>nil</b></tt>, <tt>A</tt> is padded with +the encoding of the remaining bytes of <tt>C</tt>. +Throughout encoding, occurrences of CRLF are replaced by the +<tt>marker</tt>, which itself defaults to CRLF. +</p> + +<p class=note> +Note: The simplest use of this function is to encode a string into it's +Quoted-Printable transfer content encoding. +Notice the extra parenthesis around the call to <tt>mime.qp</tt>, to discard the second return value. +</p> + +<pre class=example> +print((mime.qp("maçã"))) +--> ma=E7=E3= +</pre> + +<!-- qpwrp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="qpwrp"> +A, m = mime.<b>qpwrp(</b>n [, B, length]<b>)</b> +</p> + +<p class=description> +Low-level filter to break Quoted-Printable text into lines. +</p> + +<p class=parameters> +<tt>A</tt> is a copy of <tt>B</tt>, broken into lines of at most +<tt>length</tt> bytes (defaults to 76). +'<tt>n</tt>' should tell how many bytes are left for the first +line of <tt>B</tt> and '<tt>m</tt>' returns the number of bytes +left in the last line of <tt>A</tt>. +</p> + +<p class=note> +Note: Besides breaking text into lines, this function makes sure the line +breaks don't fall in the middle of an escaped character combination. Also, +this function only breaks lines that are bigger than <tt>length</tt> bytes. +</p> + +<!-- unb64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="unb64"> +A, B = mime.<b>unb64(</b>C [, D]<b>)</b> +</p> + +<p class=description> +Low-level filter to perform Base64 decoding. +</p> + +<p class=parameters> +<tt>A</tt> is the decoded version of the largest prefix of +<tt>C..D</tt> +that can be decoded unambiguously. <tt>B</tt> has the remaining bytes of +<tt>C..D</tt>, <em>before</em> decoding. +If <tt>D</tt> is <tt><b>nil</b></tt>, <tt>A</tt> is the empty string +and <tt>B</tt> returns whatever couldn't be decoded. +</p> + +<p class=note> +Note: The simplest use of this function is to decode a string from it's +Base64 transfer content encoding. +Notice the extra parenthesis around the call to <tt>mime.unqp</tt>, to discard the second return value. +</p> + +<pre class=example> +print((mime.unb64("ZGllZ286cGFzc3dvcmQ="))) +--> diego:password +</pre> + +<!-- unqp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="unqp"> +A, B = mime.<b>unqp(</b>C [, D]<b>)</b> +</p> + +<p class=description> +Low-level filter to remove the Quoted-Printable transfer content encoding +from data. +</p> + +<p class=parameters> +<tt>A</tt> is the decoded version of the largest prefix of +<tt>C..D</tt> +that can be decoded unambiguously. <tt>B</tt> has the remaining bytes of +<tt>C..D</tt>, <em>before</em> decoding. +If <tt>D</tt> is <tt><b>nil</b></tt>, <tt>A</tt> is augmented with +the encoding of the remaining bytes of <tt>C</tt>. +</p> + +<p class=note> +Note: The simplest use of this function is to decode a string from it's +Quoted-Printable transfer content encoding. +Notice the extra parenthesis around the call to <tt>mime.unqp</tt>, to discard the second return value. +</p> + +<pre class=example> +print((mime.qp("ma=E7=E3="))) +--> maçã +</pre> + +<!-- wrp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="wrp"> +A, m = mime.<b>wrp(</b>n [, B, length]<b>)</b> +</p> + +<p class=description> +Low-level filter to break text into lines with CRLF marker. +Text is assumed to be in the <a href=#normalize><tt>normalize</tt></a> form. +</p> + +<p class=parameters> +<tt>A</tt> is a copy of <tt>B</tt>, broken into lines of at most +<tt>length</tt> bytes (defaults to 76). +'<tt>n</tt>' should tell how many bytes are left for the first +line of <tt>B</tt> and '<tt>m</tt>' returns the number of bytes +left in the last line of <tt>A</tt>. +</p> + +<p class=note> +Note: This function only breaks lines that are bigger than +<tt>length</tt> bytes. The resulting line length does not include the CRLF +marker. +</p> + + +<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=footer> +<hr> +<center> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#down">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +<p> +<small> +Last modified by Diego Nehab on <br> +Thu Apr 20 00:25:44 EDT 2006 +</small> +</p> +</center> +</div> + +</body> +</html> diff --git a/src/libs/luasocket/doc/reference.css b/src/libs/luasocket/doc/reference.css new file mode 100644 index 000000000..b1dd25d70 --- /dev/null +++ b/src/libs/luasocket/doc/reference.css @@ -0,0 +1,54 @@ +body { + margin-left: 1em; + margin-right: 1em; + font-family: "Verdana", sans-serif; +} + +tt { + font-family: "Andale Mono", monospace; +} + +h1, h2, h3, h4 { margin-left: 0em; } + + +h3 { padding-top: 1em; } + +p { margin-left: 1em; } + +p.name { + font-family: "Andale Mono", monospace; + padding-top: 1em; + margin-left: 0em; +} + +a[href] { color: #00007f; } + +blockquote { margin-left: 3em; } + +pre.example { + background: #ccc; + padding: 1em; + margin-left: 1em; + font-family: "Andale Mono", monospace; + font-size: small; +} + +hr { + margin-left: 0em; + background: #00007f; + border: 0px; + height: 1px; +} + +ul { list-style-type: disc; } + +table.index { border: 1px #00007f; } +table.index td { text-align: left; vertical-align: top; } +table.index ul { padding-top: 0em; margin-top: 0em; } + +h1:first-letter, +h2:first-letter, +h2:first-letter, +h3:first-letter { color: #00007f; } + +div.header, div.footer { margin-left: 0em; } diff --git a/src/libs/luasocket/doc/reference.html b/src/libs/luasocket/doc/reference.html new file mode 100644 index 000000000..b329f57f5 --- /dev/null +++ b/src/libs/luasocket/doc/reference.html @@ -0,0 +1,239 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + +<head> +<meta name="description" content="LuaSocket: Index to reference manual"> +<meta name="keywords" content="Lua, LuaSocket, Index, Manual, Network, Library, +Support, Manual"> +<title>LuaSocket: Index to reference manual</title> +<link rel="stylesheet" href="reference.css" type="text/css"> +</head> + +<body> + +<!-- header ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=header> +<hr> +<center> +<table summary="LuaSocket logo"> +<tr><td align=center><a href="http://www.lua.org"> +<img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png"> +</a></td></tr> +<tr><td align=center valign=top>Network support for the Lua language +</td></tr> +</table> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +</center> +<hr> +</div> + +<!-- reference +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2>Reference</h2> + +<blockquote> +<a href="dns.html">DNS (in socket)</a> +<blockquote> +<a href="dns.html#toip">toip</a>, +<a href="dns.html#tohostname">tohostname</a>, +<a href="dns.html#gethostname">gethostname</a>. +</blockquote> +</blockquote> + +<!-- ftp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<blockquote> +<a href="ftp.html">FTP</a> +<blockquote> +<a href="ftp.html#get">get</a>, +<a href="ftp.html#put">put</a>. +</blockquote> +</blockquote> + +<!-- http +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<blockquote> +<a href="http.html">HTTP</a> +<blockquote> +<a href="http.html#request">request</a>. +</blockquote> +</blockquote> + +<!-- ltn12 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<blockquote> +<a href="ltn12.html">LTN12</a> +<blockquote> +<a href="ltn12.html#filter">filter</a>: +<a href="ltn12.html#filter.chain">chain</a>, +<a href="ltn12.html#filter.cycle">cycle</a>. +</blockquote> +<blockquote> +<a href="ltn12.html#pump">pump</a>: +<a href="ltn12.html#pump.all">all</a>, +<a href="ltn12.html#pump.step">step</a>. +</blockquote> +<blockquote> +<a href="ltn12.html#sink">sink</a>: +<a href="ltn12.html#sink.chain">chain</a>, +<a href="ltn12.html#sink.error">error</a>, +<a href="ltn12.html#sink.file">file</a>, +<a href="ltn12.html#sink.null">null</a>, +<a href="ltn12.html#sink.simplify">simplify</a>, +<a href="ltn12.html#sink.table">table</a>. +</blockquote> +<blockquote> +<a href="ltn12.html#source">source</a>: +<a href="ltn12.html#source.cat">cat</a>, +<a href="ltn12.html#source.chain">chain</a>, +<a href="ltn12.html#source.empty">empty</a>, +<a href="ltn12.html#source.error">error</a>, +<a href="ltn12.html#source.file">file</a>, +<a href="ltn12.html#source.simplify">simplify</a>, +<a href="ltn12.html#source.string">string</a>. +</blockquote> +</blockquote> + +<!-- mime +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<blockquote> +<a href="mime.html">MIME</a> +<blockquote> +<a href="mime.html#high">high-level</a>: +<a href="mime.html#normalize">normalize</a>, +<a href="mime.html#decode">decode</a>, +<a href="mime.html#encode">encode</a>, +<a href="mime.html#stuff">stuff</a>, +<a href="mime.html#wrap">wrap</a>. +</blockquote> +<blockquote> +<a href="mime.html#low">low-level</a>: +<a href="mime.html#b64">b64</a>, +<a href="mime.html#dot">dot</a>, +<a href="mime.html#eol">eol</a>, +<a href="mime.html#qp">qp</a>, +<a href="mime.html#wrp">wrp</a>, +<a href="mime.html#qpwrp">qpwrp</a>. +<a href="mime.html#unb64">unb64</a>, +<a href="mime.html#unqp">unqp</a>, +</blockquote> +</blockquote> + +<!-- smtp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<blockquote> +<a href="smtp.html">SMTP</a> +<blockquote> +<a href="smtp.html#message">message</a>, +<a href="smtp.html#send">send</a>. +</blockquote> +</blockquote> + +<!-- socket +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<blockquote> +<a href="socket.html">Socket</a> +<blockquote> +<a href="socket.html#debug">_DEBUG</a>, +<a href="dns.html#dns">dns</a>, +<a href="socket.html#gettime">gettime</a>, +<a href="socket.html#newtry">newtry</a>, +<a href="socket.html#protect">protect</a>, +<a href="socket.html#select">select</a>, +<a href="socket.html#sink">sink</a>, +<a href="socket.html#skip">skip</a>, +<a href="socket.html#sleep">sleep</a>, +<a href="socket.html#source">source</a>, +<a href="tcp.html#tcp">tcp</a>, +<a href="socket.html#try">try</a>, +<a href="udp.html#udp">udp</a>, +<a href="socket.html#version">_VERSION</a>. +</blockquote> +</blockquote> + +<!-- tcp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<blockquote> +<a href="tcp.html">TCP (in socket)</a> +<blockquote> +<a href="tcp.html#accept">accept</a>, +<a href="tcp.html#bind">bind</a>, +<a href="tcp.html#close">close</a>, +<a href="tcp.html#connect">connect</a>, +<a href="tcp.html#getpeername">getpeername</a>, +<a href="tcp.html#getsockname">getsockname</a>, +<a href="tcp.html#getstats">getstats</a>, +<a href="tcp.html#receive">receive</a>, +<a href="tcp.html#send">send</a>, +<a href="tcp.html#setoption">setoption</a>, +<a href="tcp.html#setstats">setstats</a>, +<a href="tcp.html#settimeout">settimeout</a>, +<a href="tcp.html#shutdown">shutdown</a>. +</blockquote> +</blockquote> + +<!-- udp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<blockquote> +<a href="udp.html">UDP (in socket)</a> +<blockquote> +<a href="udp.html#close">close</a>, +<a href="udp.html#getpeername">getpeername</a>, +<a href="udp.html#getsockname">getsockname</a>, +<a href="udp.html#receive">receive</a>, +<a href="udp.html#receivefrom">receivefrom</a>, +<a href="udp.html#send">send</a>, +<a href="udp.html#sendto">sendto</a>, +<a href="udp.html#setpeername">setpeername</a>, +<a href="udp.html#setsockname">setsockname</a>, +<a href="udp.html#setoption">setoption</a>, +<a href="udp.html#settimeout">settimeout</a>. +</blockquote> +</blockquote> + +<!-- url ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<blockquote> +<a href="url.html">URL</a> +<blockquote> +<a href="url.html#absolute">absolute</a>, +<a href="url.html#build">build</a>, +<a href="url.html#build_path">build_path</a>, +<a href="url.html#escape">escape</a>, +<a href="url.html#parse">parse</a>, +<a href="url.html#parse_path">parse_path</a>, +<a href="url.html#unescape">unescape</a>. +</blockquote> +</blockquote> + +<!-- footer ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=footer> +<hr> +<center> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#down">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +<p> +<small> +Last modified by Diego Nehab on <br> +Thu Apr 20 00:25:47 EDT 2006 +</small> +</p> +</center> +</div> + +</body> +</html> diff --git a/src/libs/luasocket/doc/smtp.html b/src/libs/luasocket/doc/smtp.html new file mode 100644 index 000000000..27dd4736b --- /dev/null +++ b/src/libs/luasocket/doc/smtp.html @@ -0,0 +1,417 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + +<head> +<meta name="description" content="LuaSocket: SMTP support"> +<meta name="keywords" content="Lua, LuaSocket, SMTP, E-Mail, MIME, Multipart, +Library, Support"> +<title>LuaSocket: SMTP support</title> +<link rel="stylesheet" href="reference.css" type="text/css"> +</head> + +<body> + +<!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=header> +<hr> +<center> +<table summary="LuaSocket logo"> +<tr><td align=center><a href="http://www.lua.org"> +<img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png"> +</a></td></tr> +<tr><td align=center valign=top>Network support for the Lua language +</td></tr> +</table> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +</center> +<hr> +</div> + +<!-- smtp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=smtp>SMTP</h2> + +<p> The <tt>smtp</tt> namespace provides functionality to send e-mail +messages. The high-level API consists of two functions: one to +define an e-mail message, and another to actually send the message. +Although almost all users will find that these functions provide more than +enough functionality, the underlying implementation allows for even more +control (if you bother to read the code). +</p> + +<p>The implementation conforms to the Simple Mail Transfer Protocol, +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2821.txt">RFC 2821</a>. +Another RFC of interest is <a +href="http://www.cs.princeton.edu/~diego/rfc/rfc2822.txt">RFC 2822</a>, +which governs the Internet Message Format. +Multipart messages (those that contain attachments) are part +of the MIME standard, but described mainly +in <a href="http://www.cs.princeton.edu/~diego/rfc/rfc2046.txt">RFC +2046</a> + +<p> In the description below, good understanding of <a +href="http://lua-users.org/wiki/FiltersSourcesAndSinks"> LTN012, Filters +sources and sinks</a> and the <a href=mime.html>MIME</a> module is +assumed. In fact, the SMTP module was the main reason for their +creation. </p> + +<p> +To obtain the <tt>smtp</tt> namespace, run: +</p> + +<pre class=example> +-- loads the SMTP module and everything it requires +local smtp = require("socket.smtp") +</pre> + +<p> +MIME headers are represented as a Lua table in the form: +</p> + +<blockquote> +<table summary="MIME headers in Lua table"> +<tr><td><tt> +headers = {<br> + field-1-name = <i>field-1-value</i>,<br> + field-2-name = <i>field-2-value</i>,<br> + field-3-name = <i>field-3-value</i>,<br> + ...<br> + field-n-name = <i>field-n-value</i><br> +} +</tt></td></tr> +</table> +</blockquote> + +<p> +Field names are case insensitive (as specified by the standard) and all +functions work with lowercase field names. +Field values are left unmodified. +</p> + +<p class=note> +Note: MIME headers are independent of order. Therefore, there is no problem +in representing them in a Lua table. +</p> + +<p> +The following constants can be set to control the default behavior of +the SMTP module: +</p> + +<ul> +<li> <tt>DOMAIN</tt>: domain used to greet the server; +<li> <tt>PORT</tt>: default port used for the connection; +<li> <tt>SERVER</tt>: default server used for the connection; +<li> <tt>TIMEOUT</tt>: default timeout for all I/O operations; +<li> <tt>ZONE</tt>: default time zone. +</ul> + +<!-- send +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=send> +smtp.<b>send{</b><br> + from = <i>string</i>,<br> + rcpt = <i>string</i> or <i>string-table</i>,<br> + source = <i>LTN12 source</i>,<br> + [user = <i>string</i>,]<br> + [password = <i>string</i>,]<br> + [server = <i>string</i>,]<br> + [port = <i>number</i>,]<br> + [domain = <i>string</i>,]<br> + [step = <i>LTN12 pump step</i>,]<br> + [create = <i>function</i>]<br> +<b>}</b> +</p> + +<p class=description> +Sends a message to a recipient list. Since sending messages is not as +simple as downloading an URL from a FTP or HTTP server, this function +doesn't have a simple interface. However, see the +<a href=#message><tt>message</tt></a> source factory for +a very powerful way to define the message contents. +</p> + + +<p class=parameters> +The sender is given by the e-mail address in the <tt>from</tt> field. +<tt>Rcpt</tt> is a Lua table with one entry for each recipient e-mail +address, or a string +in case there is just one recipient. +The contents of the message are given by a <em>simple</em> +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> +<tt>source</tt>. Several arguments are optional: +</p> +<ul> +<li> <tt>user</tt>, <tt>password</tt>: User and password for +authentication. The function will attempt LOGIN and PLAIN authentication +methods if supported by the server (both are unsafe); +<li> <tt>server</tt>: Server to connect to. Defaults to "localhost"; +<li> <tt>port</tt>: Port to connect to. Defaults to 25; +<li> <tt>domain</tt>: Domain name used to greet the server; Defaults to the +local machine host name; +<li> <tt>step</tt>: +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> +pump step function used to pass data from the +source to the server. Defaults to the LTN12 <tt>pump.step</tt> function; +<li><tt>create</tt>: An optional function to be used instead of +<a href=tcp.html#socket.tcp><tt>socket.tcp</tt></a> when the communications socket is created. +</ul> + +<p class=return> +If successful, the function returns 1. Otherwise, the function returns +<b><tt>nil</tt></b> followed by an error message. +</p> + +<p class=note> +Note: SMTP servers can be very picky with the format of e-mail +addresses. To be safe, use only addresses of the form +"<tt><fulano@example.com></tt>" in the <tt>from</tt> and +<tt>rcpt</tt> arguments to the <tt>send</tt> function. In headers, e-mail +addresses can take whatever form you like. </p> + +<p class=note> +Big note: There is a good deal of misconception with the use of the +destination address field headers, i.e., the '<tt>To</tt>', '<tt>Cc</tt>', +and, more importantly, the '<tt>Bcc</tt>' headers. Do <em>not</em> add a +'<tt>Bcc</tt>' header to your messages because it will probably do the +exact opposite of what you expect. +</p> + +<p class=note> +Only recipients specified in the <tt>rcpt</tt> list will receive a copy of the +message. Each recipient of an SMTP mail message receives a copy of the +message body along with the headers, and nothing more. The headers +<em>are</em> part of the message and should be produced by the +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> +<tt>source</tt> function. The <tt>rcpt</tt> list is <em>not</em> +part of the message and will not be sent to anyone. +</p> + +<p class=note> +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2822.txt">RFC 2822</a> +has two <em>important and short</em> sections, "3.6.3. Destination address +fields" and "5. Security considerations", explaining the proper +use of these headers. Here is a summary of what it says: +</p> + +<ul> +<li> <tt>To</tt>: contains the address(es) of the primary recipient(s) +of the message; +<li> <tt>Cc</tt>: (where the "Cc" means "Carbon Copy" in the sense of +making a copy on a typewriter using carbon paper) contains the +addresses of others who are to receive the message, though the +content of the message may not be directed at them; +<li> <tt>Bcc</tt>: (where the "Bcc" means "Blind Carbon +Copy") contains addresses of recipients of the message whose addresses are not to be revealed to other recipients of the message. +</ul> + +<p class=note> +The LuaSocket <tt>send</tt> function does not care or interpret the +headers you send, but it gives you full control over what is sent and +to whom it is sent: +</p> +<ul> +<li> If someone is to receive the message, the e-mail address <em>has</em> +to be in the recipient list. This is the only parameter that controls who +gets a copy of the message; +<li> If there are multiple recipients, none of them will automatically +know that someone else got that message. That is, the default behavior is +similar to the <tt>Bcc</tt> field of popular e-mail clients; +<li> It is up to you to add the <tt>To</tt> header with the list of primary +recipients so that other recipients can see it; +<li> It is also up to you to add the <tt>Cc</tt> header with the +list of additional recipients so that everyone else sees it; +<li> Adding a header <tt>Bcc</tt> is nonsense, unless it is +empty. Otherwise, everyone receiving the message will see it and that is +exactly what you <em>don't</em> want to happen! +</ul> + +<p class=note> +I hope this clarifies the issue. Otherwise, please refer to +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2821.txt">RFC 2821</a> +and +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2822.txt">RFC 2822</a>. +</p> + +<pre class=example> +-- load the smtp support +local smtp = require("socket.smtp") + +-- Connects to server "localhost" and sends a message to users +-- "fulano@example.com", "beltrano@example.com", +-- and "sicrano@example.com". +-- Note that "fulano" is the primary recipient, "beltrano" receives a +-- carbon copy and neither of them knows that "sicrano" received a blind +-- carbon copy of the message. +from = "<luasocket@example.com>" + +rcpt = { + "<fulano@example.com>", + "<beltrano@example.com>", + "<sicrano@example.com>" +} + +mesgt = { + headers = { + to = "Fulano da Silva <fulano@example.com>", + cc = '"Beltrano F. Nunes" <beltrano@example.com>', + subject = "My first message" + }, + body = "I hope this works. If it does, I can send you another 1000 copies." +} + +r, e = smtp.send{ + from = from, + rcpt = rcpt, + source = smtp.message(mesgt) +} +</pre> + +<!-- message ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=message> +smtp.<b>message(</b>mesgt<b>)</b> +</p> + +<p class=description> +Returns a <em>simple</em> +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> source that sends an SMTP message body, possibly multipart (arbitrarily deep). +</p> + +<p class=parameters> +The only parameter of the function is a table describing the message. +<tt>Mesgt</tt> has the following form (notice the recursive structure): +</p> + +<blockquote> +<table summary="Mesgt table structure"> +<tr><td><tt> +mesgt = {<br> + headers = <i>header-table</i>,<br> + body = <i>LTN12 source</i> or <i>string</i> or +<i>multipart-mesgt</i><br> +}<br> + <br> +multipart-mesgt = {<br> + [preamble = <i>string</i>,]<br> + [1] = <i>mesgt</i>,<br> + [2] = <i>mesgt</i>,<br> + ...<br> + [<i>n</i>] = <i>mesgt</i>,<br> + [epilogue = <i>string</i>,]<br> +}<br> +</tt></td></tr> +</table> +</blockquote> + +<p class=parameters> +For a simple message, all that is needed is a set of <tt>headers</tt> +and the <tt>body</tt>. The message <tt>body</tt> can be given as a string +or as a <em>simple</em> +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> +source. For multipart messages, the body is a table that +recursively defines each part as an independent message, plus an optional +<tt>preamble</tt> and <tt>epilogue</tt>. +</p> + +<p class=return> +The function returns a <em>simple</em> +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> +source that produces the +message contents as defined by <tt>mesgt</tt>, chunk by chunk. +Hopefully, the following +example will make things clear. When in doubt, refer to the appropriate RFC +as listed in the introduction. </p> + +<pre class=example> +-- load the smtp support and its friends +local smtp = require("socket.smtp") +local mime = require("mime") +local ltn12 = require("ltn12") + +-- creates a source to send a message with two parts. The first part is +-- plain text, the second part is a PNG image, encoded as base64. +source = smtp.message{ + headers = { + -- Remember that headers are *ignored* by smtp.send. + from = "Sicrano de Oliveira <sicrano@example.com>", + to = "Fulano da Silva <fulano@example.com>", + subject = "Here is a message with attachments" + }, + body = { + preamble = "If your client doesn't understand attachments, \r\n" .. + "it will still display the preamble and the epilogue.\r\n" .. + "Preamble will probably appear even in a MIME enabled client.", + -- first part: no headers means plain text, us-ascii. + -- The mime.eol low-level filter normalizes end-of-line markers. + [1] = { + body = mime.eol(0, [[ + Lines in a message body should always end with CRLF. + The smtp module will *NOT* perform translation. However, the + send function *DOES* perform SMTP stuffing, whereas the message + function does *NOT*. + ]]) + }, + -- second part: headers describe content to be a png image, + -- sent under the base64 transfer content encoding. + -- notice that nothing happens until the message is actually sent. + -- small chunks are loaded into memory right before transmission and + -- translation happens on the fly. + [2] = { + headers = { + ["content-type"] = 'image/png; name="image.png"', + ["content-disposition"] = 'attachment; filename="image.png"', + ["content-description"] = 'a beautiful image', + ["content-transfer-encoding"] = "BASE64" + }, + body = ltn12.source.chain( + ltn12.source.file(io.open("image.png", "rb")), + ltn12.filter.chain( + mime.encode("base64"), + mime.wrap() + ) + ) + }, + epilogue = "This might also show up, but after the attachments" + } +} + +-- finally send it +r, e = smtp.send{ + from = "<sicrano@example.com>", + rcpt = "<fulano@example.com>", + source = source, +} +</pre> + +<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=footer> +<hr> +<center> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#down">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +<p> +<small> +Last modified by Diego Nehab on <br> +Thu Apr 20 00:25:51 EDT 2006 +</small> +</p> +</center> +</div> + +</body> +</html> diff --git a/src/libs/luasocket/doc/socket.html b/src/libs/luasocket/doc/socket.html new file mode 100644 index 000000000..ba4b7303e --- /dev/null +++ b/src/libs/luasocket/doc/socket.html @@ -0,0 +1,404 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + +<head> +<meta name="description" content="LuaSocket: The core namespace"> +<meta name="keywords" content="Lua, LuaSocket, Socket, Network, Library, Support"> +<title>LuaSocket: The socket namespace</title> +<link rel="stylesheet" href="reference.css" type="text/css"> +</head> + +<body> + +<!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=header> +<hr> +<center> +<table summary="LuaSocket logo"> +<tr><td align=center><a href="http://www.lua.org"> +<img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png"> +</a></td></tr> +<tr><td align=center valign=top>Network support for the Lua language +</td></tr> +</table> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +</center> +<hr> +</div> + +<!-- socket +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=socket>The socket namespace</h2> + +<p> +The <tt>socket</tt> namespace contains the core functionality of LuaSocket. +</p> + +<p> +To obtain the <tt>socket</tt> namespace, run: +</p> + +<pre class=example> +-- loads the socket module +local socket = require("socket") +</pre> + +<!-- bind ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=bind> +socket.<b>bind(</b>address, port [, backlog]<b>)</b> +</p> + +<p class=description> +This function is a shortcut that creates and returns a TCP server object +bound to a local <tt>address</tt> and <tt>port</tt>, ready to +accept client connections. Optionally, +user can also specify the <tt>backlog</tt> argument to the +<a href=tcp.html#listen><tt>listen</tt></a> method (defaults to 32). +</p> + +<p class=note> +Note: The server object returned will have the option "<tt>reuseaddr</tt>" +set to <tt><b>true</b></tt>. +</p> + +<!-- connect ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=connect> +socket.<b>connect(</b>address, port [, locaddr, locport]<b>)</b> +</p> + +<p class=description> +This function is a shortcut that creates and returns a TCP client object +connected to a remote <tt>host</tt> at a given <tt>port</tt>. Optionally, +the user can also specify the local address and port to bind +(<tt>locaddr</tt> and <tt>locport</tt>). +</p> + +<!-- debug ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=debug> +socket.<b>_DEBUG</b> +</p> + +<p class=description> +This constant is set to <tt><b>true</b></tt> if the library was compiled +with debug support. +</p> + +<!-- newtry +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=newtry> +socket.<b>newtry(</b>finalizer<b>)</b> +</p> + +<p class=description> +Creates and returns a <em>clean</em> +<a href="#try"><tt>try</tt></a> +function that allows for cleanup before the exception +is raised. +</p> + +<p class=parameters> +<tt>Finalizer</tt> is a function that will be called before +<tt>try</tt> throws the exception. It will be called +in <em>protected</em> mode. +</p> + +<p class=return> +The function returns your customized <tt>try</tt> function. +</p> + +<p class=note> +Note: This idea saved a <em>lot</em> of work with the +implementation of protocols in LuaSocket: +</p> + +<pre class=example> +foo = socket.protect(function() + -- connect somewhere + local c = socket.try(socket.connect("somewhere", 42)) + -- create a try function that closes 'c' on error + local try = socket.newtry(function() c:close() end) + -- do everything reassured c will be closed + try(c:send("hello there?\r\n")) + local answer = try(c:receive()) + ... + try(c:send("good bye\r\n")) + c:close() +end) +</pre> + + +<!-- protect +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=protect> +socket.<b>protect(</b>func<b>)</b> +</p> + +<p class=description> +Converts a function that throws exceptions into a safe function. This +function only catches exceptions thrown by the <a href=#try><tt>try</tt></a> +and <a href=#newtry><tt>newtry</tt></a> functions. It does not catch normal +Lua errors. +</p> + +<p class=parameters> +<tt>Func</tt> is a function that calls +<a href=#try><tt>try</tt></a> (or <tt>assert</tt>, or <tt>error</tt>) +to throw exceptions. +</p> + +<p class=return> +Returns an equivalent function that instead of throwing exceptions, +returns <tt><b>nil</b></tt> followed by an error message. +</p> + +<p class=note> +Note: Beware that if your function performs some illegal operation that +raises an error, the protected function will catch the error and return it +as a string. This is because the <a href=#try><tt>try</tt></a> function +uses errors as the mechanism to throw exceptions. +</p> + +<!-- select +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=select> +socket.<b>select(</b>recvt, sendt [, timeout]<b>)</b> +</p> + +<p class=description> +Waits for a number of sockets to change status. +</p> + +<p class=parameters> +<tt>Recvt</tt> is an array with the sockets to test for characters +available for reading. Sockets in the <tt>sendt</tt> array are watched to +see if it is OK to immediately write on them. <tt>Timeout</tt> is the +maximum amount of time (in seconds) to wait for a change in status. A +<tt><b>nil</b></tt>, negative or omitted <tt>timeout</tt> value allows the +function to block indefinitely. <tt>Recvt</tt> and <tt>sendt</tt> can also +be empty tables or <tt><b>nil</b></tt>. Non-socket values (or values with +non-numeric indices) in the arrays will be silently ignored. +</p> + +<p class=return> The function returns a list with the sockets ready for +reading, a list with the sockets ready for writing and an error message. +The error message is "<tt>timeout</tt>" if a timeout condition was met and +<tt><b>nil</b></tt> otherwise. The returned tables are +doubly keyed both by integers and also by the sockets +themselves, to simplify the test if a specific socket has +changed status. +</p> + +<p class=note> +<b>Important note</b>: a known bug in WinSock causes <tt>select</tt> to fail +on non-blocking TCP sockets. The function may return a socket as +writable even though the socket is <em>not</em> ready for sending. +</p> + +<p class=note> +<b>Another important note</b>: calling select with a server socket in the receive parameter before a call to accept does <em>not</em> guarantee +<a href=tcp.html#accept><tt>accept</tt></a> will return immediately. +Use the <a href=tcp.html#settimeout><tt>settimeout</tt></a> +method or <tt>accept</tt> might block forever. +</p> + +<p class=note> +<b>Yet another note</b>: If you close a socket and pass +it to <tt>select</tt>, it will be ignored. +</p> + +<!-- sink ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=sink> +socket.<b>sink(</b>mode, socket<b>)</b> +</p> + +<p class=description> +Creates an +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> +sink from a stream socket object. +</p> + +<p class=parameters> +<tt>Mode</tt> defines the behavior of the sink. The following +options are available: +</p> +<ul> +<li> <tt>"http-chunked"</tt>: sends data through socket after applying the +<em>chunked transfer coding</em>, closing the socket when done; +<li> <tt>"close-when-done"</tt>: sends all received data through the +socket, closing the socket when done; +<li> <tt>"keep-open"</tt>: sends all received data through the +socket, leaving it open when done. +</ul> +<p> +<tt>Socket</tt> is the stream socket object used to send the data. +</p> + +<p class=return> +The function returns a sink with the appropriate behavior. +</p> + +<!-- skip ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=skip> +socket.<b>skip(</b>d [, ret<sub>1</sub>, ret<sub>2</sub> ... ret<sub>N</sub>]<b>)</b> +</p> + +<p class=description> +Drops a number of arguments and returns the remaining. +</p> + +<p class=parameters> +<tt>D</tt> is the number of arguments to drop. <tt>Ret<sub>1</sub></tt> to +<tt>ret<sub>N</sub></tt> are the arguments. +</p> + +<p class=return> +The function returns <tt>ret<sub>d+1</sub></tt> to <tt>ret<sub>N</sub></tt>. +</p> + +<p class=note> +Note: This function is useful to avoid creation of dummy variables: +</p> + +<pre class=example> +-- get the status code and separator from SMTP server reply +local code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)")) +</pre> + +<!-- sleep ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=sleep> +socket.<b>sleep(</b>time<b>)</b> +</p> + +<p class=description> +Freezes the program execution during a given amount of time. +</p> + +<p class=parameters> +<tt>Time</tt> is the number of seconds to sleep for. +</p> + +<!-- source +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=source> +socket.<b>source(</b>mode, socket [, length]<b>)</b> +</p> + +<p class=description> +Creates an +<a href="http://lua-users.org/wiki/FiltersSourcesAndSinks">LTN12</a> +source from a stream socket object. +</p> + +<p class=parameters> +<tt>Mode</tt> defines the behavior of the source. The following +options are available: +</p> +<ul> +<li> <tt>"http-chunked"</tt>: receives data from socket and removes the +<em>chunked transfer coding</em> before returning the data; +<li> <tt>"by-length"</tt>: receives a fixed number of bytes from the +socket. This mode requires the extra argument <tt>length</tt>; +<li> <tt>"until-closed"</tt>: receives data from a socket until the other +side closes the connection. +</ul> +<p> +<tt>Socket</tt> is the stream socket object used to receive the data. +</p> + +<p class=return> +The function returns a source with the appropriate behavior. +</p> + +<!-- time ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=gettime> +socket.<b>gettime()</b> +</p> + +<p class=description> +Returns the time in seconds, relative to the origin of the +universe. You should subtract the values returned by this function +to get meaningful values. +</p> + +<pre class=example> +t = socket.gettime() +-- do stuff +print(socket.gettime() - t .. " seconds elapsed") +</pre> + +<!-- try ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=try> +socket.<b>try(</b>ret<sub>1</sub> [, ret<sub>2</sub> ... ret<sub>N</sub>]<b>)</b> +</p> + +<p class=description> +Throws an exception in case of error. The exception can only be caught +by the <a href=#protect><tt>protect</tt></a> function. It does not explode +into an error message. +</p> + +<p class=parameters> +<tt>Ret<sub>1</sub></tt> to <tt>ret<sub>N</sub></tt> can be arbitrary +arguments, but are usually the return values of a function call +nested with <tt>try</tt>. +</p> + +<p class=return> +The function returns <tt>ret</tt><sub>1</sub> to <tt>ret</tt><sub>N</sub> if +<tt>ret</tt><sub>1</sub> is not <tt><b>nil</b></tt>. Otherwise, it calls <tt>error</tt> passing <tt>ret</tt><sub>2</sub>. +</p> + +<pre class=example> +-- connects or throws an exception with the appropriate error message +c = socket.try(socket.connect("localhost", 80)) +</pre> + +<!-- version ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=version> +socket.<b>_VERSION</b> +</p> + +<p class=description> +This constant has a string describing the current LuaSocket version. +</p> + +<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=footer> +<hr> +<center> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#down">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +<p> +<small> +Last modified by Diego Nehab on <br> +Thu Apr 20 00:25:54 EDT 2006 +</small> +</p> +</center> +</div> + +</body> +</html> diff --git a/src/libs/luasocket/doc/tcp.html b/src/libs/luasocket/doc/tcp.html new file mode 100644 index 000000000..a16a09ed5 --- /dev/null +++ b/src/libs/luasocket/doc/tcp.html @@ -0,0 +1,533 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + +<head> +<meta name="description" content="LuaSocket: The TCP/IP support"> +<meta name="keywords" content="Lua, LuaSocket, Socket, TCP, Library, Network, Support"> +<title>LuaSocket: TCP/IP support</title> +<link rel="stylesheet" href="reference.css" type="text/css"> +</head> + +<body> + +<!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=header> +<hr> +<center> +<table summary="LuaSocket logo"> +<tr><td align=center><a href="http://www.lua.org"> +<img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png"> +</a></td></tr> +<tr><td align=center valign=top>Network support for the Lua language +</td></tr> +</table> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +</center> +<hr> +</div> + +<!-- tcp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=tcp>TCP</h2> + +<!-- socket.tcp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=socket.tcp> +socket.<b>tcp()</b> +</p> + +<p class=description> +Creates and returns a TCP master object. A master object can +be transformed into a server object with the method +<a href=#listen><tt>listen</tt></a> (after a call to <a +href=#bind><tt>bind</tt></a>) or into a client object with +the method <a href=#connect><tt>connect</tt></a>. The only other +method supported by a master object is the +<a href=#close><tt>close</tt></a> method.</p> + +<p class=return> +In case of success, a new master object is returned. In case of error, +<b><tt>nil</tt></b> is returned, followed by an error message. +</p> + +<!-- accept +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=accept> +server:<b>accept()</b> +</p> + +<p class=description> +Waits for a remote connection on the server +object and returns a client object representing that connection. +</p> + +<p class=return> +If a connection is successfully initiated, a client object is returned. +If a timeout condition is met, the method returns <b><tt>nil</tt></b> +followed by the error string '<tt>timeout</tt>'. Other errors are +reported by <b><tt>nil</tt></b> followed by a message describing the error. +</p> + +<p class=note> +Note: calling <a href=socket.html#select><tt>socket.select</tt></a> +with a server object in +the <tt>recvt</tt> parameter before a call to <tt>accept</tt> does +<em>not</em> guarantee <tt>accept</tt> will return immediately. Use the <a +href=#settimeout><tt>settimeout</tt></a> method or <tt>accept</tt> +might block until <em>another</em> client shows up. +</p> + +<!-- bind +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=bind> +master:<b>bind(</b>address, port<b>)</b> +</p> + +<p class=description> +Binds a master object to <tt>address</tt> and <tt>port</tt> on the +local host. + +<p class=parameters> +<tt>Address</tt> can be an IP address or a host name. +<tt>Port</tt> must be an integer number in the range [0..64K). +If <tt>address</tt> +is '<tt>*</tt>', the system binds to all local interfaces +using the <tt>INADDR_ANY</tt> constant. If <tt>port</tt> is 0, the system automatically +chooses an ephemeral port. +</p> + +<p class=return> +In case of success, the method returns 1. In case of error, the +method returns <b><tt>nil</tt></b> followed by an error message. +</p> + +<p class=note> +Note: The function <a href=socket.html#bind><tt>socket.bind</tt></a> +is available and is a shortcut for the creation of server sockets. +</p> + +<!-- close ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=close> +master:<b>close()</b><br> +client:<b>close()</b><br> +server:<b>close()</b> +</p> + +<p class=description> +Closes a TCP object. The internal socket used by the object is closed +and the local address to which the object was +bound is made available to other applications. No further operations +(except for further calls to the <tt>close</tt> method) are allowed on +a closed socket. +</p> + +<p class=note> +Note: It is important to close all used sockets once they are not +needed, since, in many systems, each socket uses a file descriptor, +which are limited system resources. Garbage-collected objects are +automatically closed before destruction, though. +</p> + +<!-- connect ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=connect> +master:<b>connect(</b>address, port<b>)</b> +</p> + +<p class=description> +Attempts to connect a master object to a remote host, transforming it into a +client object. +Client objects support methods +<a href=#send><tt>send</tt></a>, +<a href=#receive><tt>receive</tt></a>, +<a href=#getsockname><tt>getsockname</tt></a>, +<a href=#getpeername><tt>getpeername</tt></a>, +<a href=#settimeout><tt>settimeout</tt></a>, +and <a href=#close><tt>close</tt></a>. +</p> + +<p class=parameters> +<tt>Address</tt> can be an IP address or a host name. +<tt>Port</tt> must be an integer number in the range [1..64K). +</p> + +<p class=return> +In case of error, the method returns <b><tt>nil</tt></b> followed by a string +describing the error. In case of success, the method returns 1. +</p> + +<p class=note> +Note: The function <a href=socket.html#connect><tt>socket.connect</tt></a> +is available and is a shortcut for the creation of client sockets. +</p> + +<p class=note> +Note: Starting with LuaSocket 2.0, +the <a href=#settimeout><tt>settimeout</tt></a> +method affects the behavior of <tt>connect</tt>, causing it to return +with an error in case of a timeout. If that happens, you can still call <a +href=socket.html#select><tt>socket.select</tt></a> with the socket in the +<tt>sendt</tt> table. The socket will be writable when the connection is +established. +</p> + +<!-- getpeername ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=getpeername> +client:<b>getpeername()</b> +</p> + +<p class=description> +Returns information about the remote side of a connected client object. +</p> + +<p class=return> +Returns a string with the IP address of the peer, followed by the +port number that peer is using for the connection. +In case of error, the method returns <b><tt>nil</tt></b>. +</p> + +<p class=note> +Note: It makes no sense to call this method on server objects. +</p> + +<!-- getsockname ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=getsockname> +master:<b>getsockname()</b><br> +client:<b>getsockname()</b><br> +server:<b>getsockname()</b> +</p> + +<p class=description> +Returns the local address information associated to the object. +</p> + +<p class=return> +The method returns a string with local IP address and a number with +the port. In case of error, the method returns <b><tt>nil</tt></b>. +</p> + +<!-- getstats +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=getstats> +master:<b>getstats()</b><br> +client:<b>getstats()</b><br> +server:<b>getstats()</b><br> +</p> + +<p class=description> +Returns accounting information on the socket, useful for throttling +of bandwidth. +</p> + +<p class=return> +The method returns the number of bytes received, the number of bytes sent, +and the age of the socket object in seconds. +</p> + +<!-- listen ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=listen> +master:<b>listen(</b>backlog<b>)</b> +</p> + +<p class=description> +Specifies the socket is willing to receive connections, transforming the +object into a server object. Server objects support the +<a href=#accept><tt>accept</tt></a>, +<a href=#getsockname><tt>getsockname</tt></a>, +<a href=#setoption><tt>setoption</tt></a>, +<a href=#settimeout><tt>settimeout</tt></a>, +and <a href=#close><tt>close</tt></a> methods. +</p> + +<p class=parameters> +The parameter <tt>backlog</tt> specifies the number of client +connections that can +be queued waiting for service. If the queue is full and another client +attempts connection, the connection is refused. +</p> + +<p class=return> +In case of success, the method returns 1. In case of error, the +method returns <b><tt>nil</tt></b> followed by an error message. +</p> + +<!-- receive ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=receive> +client:<b>receive(</b>[pattern [, prefix]]<b>)</b> +</p> + +<p class=description> +Reads data from a client object, according to the specified <em>read +pattern</em>. Patterns follow the Lua file I/O format, and the difference in performance between all patterns is negligible. +</p> + +<p class=parameters> +<tt>Pattern</tt> can be any of the following: +</p> + +<ul> +<li> '<tt>*a</tt>': reads from the socket until the connection is +closed. No end-of-line translation is performed; +<li> '<tt>*l</tt>': reads a line of text from the socket. The line is +terminated by a LF character (ASCII 10), optionally preceded by a +CR character (ASCII 13). The CR and LF characters are not included in +the returned line. In fact, <em>all</em> CR characters are +ignored by the pattern. This is the default pattern; +<li> <tt>number</tt>: causes the method to read a specified <tt>number</tt> +of bytes from the socket. +</ul> + +<p class=parameters> +<tt>Prefix</tt> is an optional string to be concatenated to the beginning +of any received data before return. +</p> + +<p class=return> +If successful, the method returns the received pattern. In case of error, +the method returns <tt><b>nil</b></tt> followed by an error message which +can be the string '<tt>closed</tt>' in case the connection was +closed before the transmission was completed or the string +'<tt>timeout</tt>' in case there was a timeout during the operation. +Also, after the error message, the function returns the partial result of +the transmission. +</p> + +<p class=note> +<b>Important note</b>: This function was changed <em>severely</em>. It used +to support multiple patterns (but I have never seen this feature used) and +now it doesn't anymore. Partial results used to be returned in the same +way as successful results. This last feature violated the idea that all +functions should return <tt><b>nil</b></tt> on error. Thus it was changed +too. +</p> + +<!-- send +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=send> +client:<b>send(</b>data [, i [, j]]<b>)</b> +</p> + +<p class=description> +Sends <tt>data</tt> through client object. +</p> + +<p class=parameters> +<tt>Data</tt> is the string to be sent. The optional arguments +<tt>i</tt> and <tt>j</tt> work exactly like the standard +<tt>string.sub</tt> Lua function to allow the selection of a +substring to be sent. +</p> + +<p class=return> +If successful, the method returns the index of the last byte +within <tt>[i, j]</tt> that has been sent. Notice that, if +<tt>i</tt> is 1 or absent, this is effectively the total +number of bytes sent. In case of error, the method returns +<b><tt>nil</tt></b>, followed by an error message, followed +by the index of the last byte within <tt>[i, j]</tt> that +has been sent. You might want to try again from the byte +following that. The error message can be '<tt>closed</tt>' +in case the connection was closed before the transmission +was completed or the string '<tt>timeout</tt>' in case +there was a timeout during the operation. +</p> + +<p class=note> +Note: Output is <em>not</em> buffered. For small strings, +it is always better to concatenate them in Lua +(with the '<tt>..</tt>' operator) and send the result in one call +instead of calling the method several times. +</p> + +<!-- setoption ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=setoption> +client:<b>setoption(</b>option [, value]<b>)</b><br> +server:<b>setoption(</b>option [, value]<b>)</b> +</p> + +<p class=description> +Sets options for the TCP object. Options are only needed by low-level or +time-critical applications. You should only modify an option if you +are sure you need it. +</p> + +<p class=parameters> +<tt>Option</tt> is a string with the option name, and <tt>value</tt> +depends on the option being set: + +<ul> + +<li> '<tt>keepalive</tt>': Setting this option to <tt>true</tt> enables +the periodic transmission of messages on a connected socket. Should the +connected party fail to respond to these messages, the connection is +considered broken and processes using the socket are notified; + +<li> '<tt>linger</tt>': Controls the action taken when unsent data are +queued on a socket and a close is performed. The value is a table with a +boolean entry '<tt>on</tt>' and a numeric entry for the time interval +'<tt>timeout</tt>' in seconds. If the '<tt>on</tt>' field is set to +<tt>true</tt>, the system will block the process on the close attempt until +it is able to transmit the data or until '<tt>timeout</tt>' has passed. If +'<tt>on</tt>' is <tt>false</tt> and a close is issued, the system will +process the close in a manner that allows the process to continue as +quickly as possible. I do not advise you to set this to anything other than +zero; + +<li> '<tt>reuseaddr</tt>': Setting this option indicates that the rules +used in validating addresses supplied in a call to +<a href=#bind><tt>bind</tt></a> should allow reuse of local addresses; + +<li> '<tt>tcp-nodelay</tt>': Setting this option to <tt>true</tt> +disables the Nagle's algorithm for the connection. + +</ul> + +<p class=return> +The method returns 1 in case of success, or <b><tt>nil</tt></b> otherwise. +</p> + +<p class=note> +Note: The descriptions above come from the man pages. +</p> + +<!-- setstats +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=setstats> +master:<b>setstats(</b>received, sent, age<b>)</b><br> +client:<b>setstats(</b>received, sent, age<b>)</b><br> +server:<b>setstats(</b>received, sent, age<b>)</b><br> +</p> + +<p class=description> +Resets accounting information on the socket, useful for throttling +of bandwidth. +</p> + +<p class=parameters> +<tt>Received</tt> is a number with the new number of bytes received. +<tt>Sent</tt> is a number with the new number of bytes sent. +<tt>Age</tt> is the new age in seconds. +</p> + +<p class=return> +The method returns 1 in case of success and <tt><b>nil</b></tt> otherwise. +</p> + +<!-- settimeout +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=settimeout> +master:<b>settimeout(</b>value [, mode]<b>)</b><br> +client:<b>settimeout(</b>value [, mode]<b>)</b><br> +server:<b>settimeout(</b>value [, mode]<b>)</b> +</p> + +<p class=description> +Changes the timeout values for the object. By default, +all I/O operations are blocking. That is, any call to the methods +<a href=#send><tt>send</tt></a>, +<a href=#receive><tt>receive</tt></a>, and +<a href=#accept><tt>accept</tt></a> +will block indefinitely, until the operation completes. The +<tt>settimeout</tt> method defines a limit on the amount of time the +I/O methods can block. When a timeout is set and the specified amount of +time has elapsed, the affected methods give up and fail with an error code. +</p> + +<p class=parameters> +The amount of time to wait is specified as the +<tt>value</tt> parameter, in seconds. There are two timeout modes and +both can be used together for fine tuning: +</p> + +<ul> +<li> '<tt>b</tt>': <em>block</em> timeout. Specifies the upper limit on +the amount of time LuaSocket can be blocked by the operating system +while waiting for completion of any single I/O operation. This is the +default mode;</li> + +<li> '<tt>t</tt>': <em>total</em> timeout. Specifies the upper limit on +the amount of time LuaSocket can block a Lua script before returning from +a call.</li> +</ul> + +<p class=parameters> +The <b><tt>nil</tt></b> timeout <tt>value</tt> allows operations to block +indefinitely. Negative timeout values have the same effect. +</p> + +<p class=note> +Note: although timeout values have millisecond precision in LuaSocket, +large blocks can cause I/O functions not to respect timeout values due +to the time the library takes to transfer blocks to and from the OS +and to and from the Lua interpreter. Also, function that accept host names +and perform automatic name resolution might be blocked by the resolver for +longer than the specified timeout value. +</p> + +<p class=note> +Note: The old <tt>timeout</tt> method is deprecated. The name has been +changed for sake of uniformity, since all other method names already +contained verbs making their imperative nature obvious. +</p> + +<!-- shutdown +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=shutdown> +client:<b>shutdown(</b>mode<b>)</b><br> +</p> + +<p class=description> +Shuts down part of a full-duplex connection. +</p> + +<p class=parameters> +Mode tells which way of the connection should be shut down and can +take the value: +<ul> +<li>"<tt>both</tt>": disallow further sends and receives on the object. +This is the default mode; +<li>"<tt>send</tt>": disallow further sends on the object; +<li>"<tt>receive</tt>": disallow further receives on the object. +</ul> + +<p class=return> +This function returns 1. +</p> + +<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=footer> +<hr> +<center> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#down">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +<p> +<small> +Last modified by Diego Nehab on <br> +Thu Apr 20 00:25:57 EDT 2006 +</small> +</p> +</center> +</div> + +</body> +</html> diff --git a/src/libs/luasocket/doc/udp.html b/src/libs/luasocket/doc/udp.html new file mode 100644 index 000000000..688649dec --- /dev/null +++ b/src/libs/luasocket/doc/udp.html @@ -0,0 +1,416 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + +<head> +<meta name="description" content="LuaSocket: The UDP support"> +<meta name="keywords" content="Lua, LuaSocket, Socket, UDP, Library, Network, Support"> +<title>LuaSocket: UDP support</title> +<link rel="stylesheet" href="reference.css" type="text/css"> +</head> + +<body> + +<!-- header ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=header> +<hr> +<center> +<table summary="LuaSocket logo"> +<tr><td align=center><a href="http://www.lua.org"> +<img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png"> +</a></td></tr> +<tr><td align=center valign=top>Network support for the Lua language +</td></tr> +</table> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +</center> +<hr> +</div> + + +<!-- udp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=udp>UDP</h2> + +<!-- socket.udp ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class="name" id="socket.udp"> +socket.<b>udp()</b> +</p> + +<p class="description"> +Creates and returns an unconnected UDP object. Unconnected objects support the +<a href="#sendto"><tt>sendto</tt></a>, +<a href="#receive"><tt>receive</tt></a>, +<a href="#receivefrom"><tt>receivefrom</tt></a>, +<a href="#getsockname"><tt>getsockname</tt></a>, +<a href="#setoption"><tt>setoption</tt></a>, +<a href="#settimeout"><tt>settimeout</tt></a>, +<a href="#setpeername"><tt>setpeername</tt></a>, +<a href="#setsockname"><tt>setsockname</tt></a>, and +<a href="#close"><tt>close</tt></a>. +The <a href="#setpeername"><tt>setpeername</tt></a> +is used to connect the object. +</p> + +<p class="return"> +In case of success, a new unconnected UDP object +returned. In case of error, <b><tt>nil</tt></b> is returned, followed by +an error message. +</p> + +<!-- close +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class="name" id="close"> +connected:<b>close()</b><br> +unconnected:<b>close()</b> +</p> + +<p class="description"> +Closes a UDP object. The internal socket +used by the object is closed and the local address to which the +object was bound is made available to other applications. No +further operations (except for further calls to the <tt>close</tt> +method) are allowed on a closed socket. +</p> + +<p class="note"> +Note: It is important to close all used sockets +once they are not needed, since, in many systems, each socket uses +a file descriptor, which are limited system resources. +Garbage-collected objects are automatically closed before +destruction, though. +</p> + +<!-- getpeername +++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class="name" id="getpeername"> +connected:<b>getpeername()</b> +</p> + +<p class="description"> +Retrieves information about the peer +associated with a connected UDP object. +</p> + +<p class="return"> +Returns the IP address and port number of the peer. +</p> + +<p class="note"> +Note: It makes no sense to call this method on unconnected objects. +</p> + +<!-- getsockname +++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class="name" id="getsockname"> +connected:<b>getsockname()</b><br> +unconnected:<b>getsockname()</b> +</p> + +<p class="description"> +Returns the local address information associated to the object. +</p> + +<p class="return"> +The method returns a string with local IP +address and a number with the port. In case of error, the method +returns <b><tt>nil</tt></b>. +</p> + +<p class="note"> +Note: UDP sockets are not bound to any address +until the <a href="#setsockname"><tt>setsockname</tt></a> or the +<a href="#sendto"><tt>sendto</tt></a> method is called for the +first time (in which case it is bound to an ephemeral port and the +wild-card address). +</p> + +<!-- receive +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class="name" id="receive"> +connected:<b>receive(</b>[size]<b>)</b><br> +unconnected:<b>receive(</b>[size]<b>)</b> +</p> + +<p class="description"> +Receives a datagram from the UDP object. If +the UDP object is connected, only datagrams coming from the peer +are accepted. Otherwise, the returned datagram can come from any +host. +</p> + +<p class="parameters"> +The optional <tt>size</tt> parameter +specifies the maximum size of the datagram to be retrieved. If +there are more than <tt>size</tt> bytes available in the datagram, +the excess bytes are discarded. If there are less then +<tt>size</tt> bytes available in the current datagram, the +available bytes are returned. If <tt>size</tt> is omitted, the +maximum datagram size is used (which is currently limited by the +implementation to 8192 bytes). +</p> + +<p class="return"> +In case of success, the method returns the +received datagram. In case of timeout, the method returns +<b><tt>nil</tt></b> followed by the string '<tt>timeout</tt>'. +</p> + +<!-- receivefrom +++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class="name" id="receivefrom"> +unconnected:<b>receivefrom(</b>[size]<b>)</b> +</p> + +<p class="description"> +Works exactly as the <a href="#receive"><tt>receive</tt></a> +method, except it returns the IP +address and port as extra return values (and is therefore slightly less +efficient). +</p> + +<!-- send ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class="name" id="send"> +connected:<b>send(</b>datagram<b>)</b> +</p> + +<p class="description"> +Sends a datagram to the UDP peer of a connected object. +</p> + +<p class="parameters"> +<tt>Datagram</tt> is a string with the datagram contents. +The maximum datagram size for UDP is 64K minus IP layer overhead. +However datagrams larger than the link layer packet size will be +fragmented, which may deteriorate performance and/or reliability. +</p> + +<p class="return"> +If successful, the method returns 1. In case of +error, the method returns <b><tt>nil</tt></b> followed by an error message. +</p> + +<p class="note"> +Note: In UDP, the <tt>send</tt> method never blocks +and the only way it can fail is if the underlying transport layer +refuses to send a message to the specified address (i.e. no +interface accepts the address). +</p> + +<!-- sendto ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class="name" id="sendto"> +unconnected:<b>sendto(</b>datagram, ip, port<b>)</b> +</p> + +<p class="description"> +Sends a datagram to the specified IP address and port number. +</p> + +<p class="parameters"> +<tt>Datagram</tt> is a string with the +datagram contents. +The maximum datagram size for UDP is 64K minus IP layer overhead. +However datagrams larger than the link layer packet size will be +fragmented, which may deteriorate performance and/or reliability. +<tt>Ip</tt> is the IP address of the recipient. +Host names are <em>not</em> allowed for performance reasons. + +<tt>Port</tt> is the port number at the recipient. +</p> + +<p class="return"> +If successful, the method returns 1. In case of +error, the method returns <b><tt>nil</tt></b> followed by an error message. +</p> + +<p class="note"> +Note: In UDP, the <tt>send</tt> method never blocks +and the only way it can fail is if the underlying transport layer +refuses to send a message to the specified address (i.e. no +interface accepts the address). +</p> + +<!-- setpeername +++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class="name" id="setpeername"> +connected:<b>setpeername(</b>'*'<b>)</b><br> +unconnected:<b>setpeername(</b>address, port<b>)</b> +</p> + +<p class="description"> +Changes the peer of a UDP object. This +method turns an unconnected UDP object into a connected UDP +object or vice versa. +</p> + +<p class="description"> +For connected objects, outgoing datagrams +will be sent to the specified peer, and datagrams received from +other peers will be discarded by the OS. Connected UDP objects must +use the <a href="#send"><tt>send</tt></a> and +<a href="#receive"><tt>receive</tt></a> methods instead of +<a href="#sendto"><tt>sendto</tt></a> and +<a href="#receivefrom"><tt>receivefrom</tt></a>. +</p> + +<p class="parameters"> +<tt>Address</tt> can be an IP address or a +host name. <tt>Port</tt> is the port number. If <tt>address</tt> is +'<tt>*</tt>' and the object is connected, the peer association is +removed and the object becomes an unconnected object again. In that +case, the <tt>port</tt> argument is ignored. +</p> + +<p class="return"> +In case of error the method returns +<b><tt>nil</tt></b> followed by an error message. In case of success, the +method returns 1. +</p> + +<p class="note"> +Note: Since the address of the peer does not have +to be passed to and from the OS, the use of connected UDP objects +is recommended when the same peer is used for several transmissions +and can result in up to 30% performance gains. +</p> + +<!-- setsockname +++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class="name" id="setsockname"> +unconnected:<b>setsockname(</b>address, port<b>)</b> +</p> + +<p class="description"> +Binds the UDP object to a local address. +</p> + +<p class="parameters"> +<tt>Address</tt> can be an IP address or a +host name. If <tt>address</tt> is '<tt>*</tt>' the system binds to +all local interfaces using the constant <tt>INADDR_ANY</tt>. If +<tt>port</tt> is 0, the system chooses an ephemeral port. +</p> + +<p class="return"> +If successful, the method returns 1. In case of +error, the method returns <b><tt>nil</tt></b> followed by an error +message. +</p> + +<p class="note"> +Note: This method can only be called before any +datagram is sent through the UDP object, and only once. Otherwise, +the system automatically binds the object to all local interfaces +and chooses an ephemeral port as soon as the first datagram is +sent. After the local address is set, either automatically by the +system or explicitly by <tt>setsockname</tt>, it cannot be +changed. +</p> + +<!-- setoption +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class="name" id="setoption"> +connected:<b>setoption(</b>option [, value]<b>)</b><br> +unconnected:<b>setoption(</b>option [, value]<b>)</b> +</p> + +<p class="description"> +Sets options for the UDP object. Options are +only needed by low-level or time-critical applications. You should +only modify an option if you are sure you need it.</p> +<p class="parameters"><tt>Option</tt> is a string with the option +name, and <tt>value</tt> depends on the option being set: +</p> + +<ul> +<li>'<tt>dontroute</tt>': Setting this option to <tt>true</tt> +indicates that outgoing messages should bypass the standard routing +facilities;</li> +<li>'<tt>broadcast</tt>': Setting this option to <tt>true</tt> +requests permission to send broadcast datagrams on the +socket.</li> +</ul> + +<p class="return"> +The method returns 1 in case of success, or +<b><tt>nil</tt></b> followed by an error message otherwise. +</p> + +<p class="note"> +Note: The descriptions above come from the man +pages. +</p> + +<!-- settimeout +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class="name" id="settimeout"> +connected:<b>settimeout(</b>value<b>)</b><br> +unconnected:<b>settimeout(</b>value<b>)</b> +</p> + +<p class="description"> +Changes the timeout values for the object. By default, the +<a href="#receive"><tt>receive</tt></a> and +<a href="#receivefrom"><tt>receivefrom</tt></a> +operations are blocking. That is, any call to the methods will block +indefinitely, until data arrives. The <tt>settimeout</tt> function defines +a limit on the amount of time the functions can block. When a timeout is +set and the specified amount of time has elapsed, the affected methods +give up and fail with an error code. +</p> + +<p class="parameters"> +The amount of time to wait is specified as +the <tt>value</tt> parameter, in seconds. The <b><tt>nil</tt></b> timeout +<tt>value</tt> allows operations to block indefinitely. Negative +timeout values have the same effect. +</p> + +<p class="note"> +Note: In UDP, the <a href="#send"><tt>send</tt></a> +and <a href="#sentdo"><tt>sendto</tt></a> methods never block (the +datagram is just passed to the OS and the call returns +immediately). Therefore, the <tt>settimeout</tt> method has no +effect on them. +</p> + +<p class="note"> +Note: The old <tt>timeout</tt> method is +deprecated. The name has been changed for sake of uniformity, since +all other method names already contained verbs making their +imperative nature obvious. +</p> + +<!-- footer ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=footer> +<hr> +<center> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +<p> +<small> +Last modified by Diego Nehab on <br> +Thu Apr 20 00:26:01 EDT 2006 +</small> +</p> +</center> +</div> + +</body> +</html> diff --git a/src/libs/luasocket/doc/url.html b/src/libs/luasocket/doc/url.html new file mode 100644 index 000000000..e87126fa3 --- /dev/null +++ b/src/libs/luasocket/doc/url.html @@ -0,0 +1,329 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/html4/strict.dtd"> +<html> + +<head> +<meta name="description" content="LuaSocket: URL manipulation"> +<meta name="keywords" content="Lua, LuaSocket, URL, Library, Link, Network, Support"> +<title>LuaSocket: URL support</title> +<link rel="stylesheet" href="reference.css" type="text/css"> +</head> + +<body> + +<!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=header> +<hr> +<center> +<table summary="LuaSocket logo"> +<tr><td align=center><a href="http://www.lua.org"> +<img width=128 height=128 border=0 alt="LuaSocket" src="luasocket.png"> +</a></td></tr> +<tr><td align=center valign=top>Network support for the Lua language +</td></tr> +</table> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#download">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +</center> +<hr> +</div> + +<!-- url ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<h2 id=url>URL</h2> + +<p> +The <tt>url</tt> namespace provides functions to parse, protect, +and build URLs, as well as functions to compose absolute URLs +from base and relative URLs, according to +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2396.txt">RFC +2396</a>. +</p> + +<p> +To obtain the <tt>url</tt> namespace, run: +</p> + +<pre class=example> +-- loads the URL module +local url = require("socket.url") +</pre> + +<p> +An URL is defined by the following grammar: +</p> + +<blockquote> +<tt> +<url> ::= [<scheme>:][//<authority>][/<path>][;<params>][?<query>][#<fragment>]<br> +<authority> ::= [<userinfo>@]<host>[:<port>]<br> +<userinfo> ::= <user>[:<password>]<br> +<path> ::= {<segment>/}<segment><br> +</tt> +</blockquote> + +<!-- absolute +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=absolute> +url.<b>absolute(</b>base, relative<b>)</b> +</p> + +<p class=description> +Builds an absolute URL from a base URL and a relative URL. +</p> + +<p class=parameters> +<tt>Base</tt> is a string with the base URL or +a parsed URL table. <tt>Relative</tt> is a +string with the relative URL. +</p> + +<p class=return> +The function returns a string with the absolute URL. +</p> + +<p class=note> +Note: The rules that +govern the composition are fairly complex, and are described in detail in +<a href="http://www.cs.princeton.edu/~diego/rfc/rfc2396.txt">RFC 2396</a>. +The example bellow should give an idea of what the rules are. +</p> + +<pre class=example> +http://a/b/c/d;p?q + ++ + +g:h = g:h +g = http://a/b/c/g +./g = http://a/b/c/g +g/ = http://a/b/c/g/ +/g = http://a/g +//g = http://g +?y = http://a/b/c/?y +g?y = http://a/b/c/g?y +#s = http://a/b/c/d;p?q#s +g#s = http://a/b/c/g#s +g?y#s = http://a/b/c/g?y#s +;x = http://a/b/c/;x +g;x = http://a/b/c/g;x +g;x?y#s = http://a/b/c/g;x?y#s +. = http://a/b/c/ +./ = http://a/b/c/ +.. = http://a/b/ +../ = http://a/b/ +../g = http://a/b/g +../.. = http://a/ +../../ = http://a/ +../../g = http://a/g +</pre> + +<!-- build ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=build> +url.<b>build(</b>parsed_url<b>)</b> +</p> + +<p class=description> +Rebuilds an URL from its parts. +</p> + +<p class=parameters> +<tt>Parsed_url</tt> is a table with same components returned by +<a href="#parse"><tt>parse</tt></a>. +Lower level components, if specified, +take precedence over high level components of the URL grammar. +</p> + +<p class=return> +The function returns a string with the built URL. +</p> + +<!-- build_path +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=build_path> +url.<b>build_path(</b>segments, unsafe<b>)</b> +</p> + +<p class=description> +Builds a <tt><path></tt> component from a list of +<tt><segment></tt> parts. +Before composition, any reserved characters found in a segment are escaped into +their protected form, so that the resulting path is a valid URL path +component. +</p> + +<p class=parameters> +<tt>Segments</tt> is a list of strings with the <tt><segment></tt> +parts. If <tt>unsafe</tt> is anything but <b><tt>nil</tt></b>, reserved +characters are left untouched. +</p> + +<p class=return> +The function returns a string with the +built <tt><path></tt> component. +</p> + +<!-- escape +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="escape"> +url.<b>escape(</b>content<b>)</b> +</p> + +<p class=description> +Applies the URL escaping content coding to a string +Each byte is encoded as a percent character followed +by the two byte hexadecimal representation of its integer +value. +</p> + +<p class=parameters> +<tt>Content</tt> is the string to be encoded. +</p> + +<p class=result> +The function returns the encoded string. +</p> + +<pre class=example> +-- load url module +url = require("socket.url") + +code = url.escape("/#?;") +-- code = "%2f%23%3f%3b" +</pre> + +<!-- parse ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=parse> +url.<b>parse(</b>url, default<b>)</b> +</p> + +<p class=description> +Parses an URL given as a string into a Lua table with its components. +</p> + +<p class=parameters> +<tt>Url</tt> is the URL to be parsed. If the <tt>default</tt> table is +present, it is used to store the parsed fields. Only fields present in the +URL are overwritten. Therefore, this table can be used to pass default +values for each field. +</p> + +<p class=return> +The function returns a table with all the URL components: +</p> + +<blockquote><tt> +parsed_url = {<br> + url = <i>string</i>,<br> + scheme = <i>string</i>,<br> + authority = <i>string</i>,<br> + path = <i>string</i>,<br> + params = <i>string</i>,<br> + query = <i>string</i>,<br> + fragment = <i>string</i>,<br> + userinfo = <i>string</i>,<br> + host = <i>string</i>,<br> + port = <i>string</i>,<br> + user = <i>string</i>,<br> + password = <i>string</i><br> +} +</tt></blockquote> + +<pre class=example> +-- load url module +url = require("socket.url") + +parsed_url = url.parse("http://www.example.com/cgilua/index.lua?a=2#there") +-- parsed_url = { +-- scheme = "http", +-- authority = "www.example.com", +-- path = "/cgilua/index.lua" +-- query = "a=2", +-- fragment = "there", +-- host = "www.puc-rio.br", +-- } + +parsed_url = url.parse("ftp://root:passwd@unsafe.org/pub/virus.exe;type=i") +-- parsed_url = { +-- scheme = "ftp", +-- authority = "root:passwd@unsafe.org", +-- path = "/pub/virus.exe", +-- params = "type=i", +-- userinfo = "root:passwd", +-- host = "unsafe.org", +-- user = "root", +-- password = "passwd", +-- } +</pre> + +<!-- parse_path +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id=parse_path> +url.<b>parse_path(</b>path<b>)</b> +</p> + +<p class=description> +Breaks a <tt><path></tt> URL component into all its +<tt><segment></tt> parts. +</p> + +<p class=description> +<tt>Path</tt> is a string with the path to be parsed. +</p> + +<p class=return> +Since some characters are reserved in URLs, they must be escaped +whenever present in a <tt><path></tt> component. Therefore, before +returning a list with all the parsed segments, the function removes +escaping from all of them. +</p> + +<!-- unescape +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<p class=name id="unescape"> +url.<b>unescape(</b>content<b>)</b> +</p> + +<p class=description> +Removes the URL escaping content coding from a string. +</p> + +<p class=parameters> +<tt>Content</tt> is the string to be decoded. +</p> + +<p class=return> +The function returns the decoded string. +</p> + +<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> + +<div class=footer> +<hr> +<center> +<p class=bar> +<a href="home.html">home</a> · +<a href="home.html#down">download</a> · +<a href="installation.html">installation</a> · +<a href="introduction.html">introduction</a> · +<a href="reference.html">reference</a> +</p> +<p> +<small> +Last modified by Diego Nehab on <br> +Thu Apr 20 00:26:05 EDT 2006 +</small> +</p> +</center> +</div> + +</body> +</html> diff --git a/src/libs/luasocket/etc/README b/src/libs/luasocket/etc/README new file mode 100644 index 000000000..cfd3e372f --- /dev/null +++ b/src/libs/luasocket/etc/README @@ -0,0 +1,89 @@ +This directory contains code that is more useful than the +samples. This code *is* supported. + + tftp.lua -- Trivial FTP client + +This module implements file retrieval by the TFTP protocol. +Its main use was to test the UDP code, but since someone +found it usefull, I turned it into a module that is almost +official (no uploads, yet). + + dict.lua -- Dict client + +The dict.lua module started with a cool simple client +for the DICT protocol, written by Luiz Henrique Figueiredo. +This new version has been converted into a library, similar +to the HTTP and FTP libraries, that can be used from within +any luasocket application. Take a look on the source code +and you will be able to figure out how to use it. + + lp.lua -- LPD client library + +The lp.lua module implements the client part of the Line +Printer Daemon protocol, used to print files on Unix +machines. It is courtesy of David Burgess! See the source +code and the lpr.lua in the examples directory. + + b64.lua + qp.lua + eol.lua + +These are tiny programs that perform Base64, +Quoted-Printable and end-of-line marker conversions. + + get.lua -- file retriever + +This little program is a client that uses the FTP and +HTTP code to implement a command line file graber. Just +run + + lua get.lua <remote-file> [<local-file>] + +to download a remote file (either ftp:// or http://) to +the specified local file. The program also prints the +download throughput, elapsed time, bytes already downloaded +etc during download. + + check-memory.lua -- checks memory consumption + +This is just to see how much memory each module uses. + + dispatch.lua -- coroutine based dispatcher + +This is a first try at a coroutine based non-blocking +dispatcher for LuaSocket. Take a look at 'check-links.lua' +and at 'forward.lua' to see how to use it. + + check-links.lua -- HTML link checker program + +This little program scans a HTML file and checks for broken +links. It is similar to check-links.pl by Jamie Zawinski, +but uses all facilities of the LuaSocket library and the Lua +language. It has not been thoroughly tested, but it should +work. Just run + + lua check-links.lua [-n] {<url>} > output + +and open the result to see a list of broken links. Make sure +you check the '-n' switch. It runs in non-blocking mode, +using coroutines, and is MUCH faster! + + forward.lua -- coroutine based forward server + +This is a forward server that can accept several connections +and transfers simultaneously using non-blocking I/O and the +coroutine-based dispatcher. You can run, for example + + lua forward.lua 8080:proxy.com:3128 + +to redirect all local conections to port 8080 to the host +'proxy.com' at port 3128. + + unix.c and unix.h + +This is an implementation of Unix local domain sockets and +demonstrates how to extend LuaSocket with a new type of +transport. It has been tested on Linux and on Mac OS X. + +Good luck, +Diego. diff --git a/src/libs/luasocket/etc/b64.lua b/src/libs/luasocket/etc/b64.lua new file mode 100644 index 000000000..f75c4232d --- /dev/null +++ b/src/libs/luasocket/etc/b64.lua @@ -0,0 +1,20 @@ +----------------------------------------------------------------------------- +-- Little program to convert to and from Base64 +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: b64.lua,v 1.8 2004/06/16 04:28:21 diego Exp $ +----------------------------------------------------------------------------- +local ltn12 = require("ltn12") +local mime = require("mime") +local source = ltn12.source.file(io.stdin) +local sink = ltn12.sink.file(io.stdout) +local convert +if arg and arg[1] == '-d' then + convert = mime.decode("base64") +else + local base64 = mime.encode("base64") + local wrap = mime.wrap() + convert = ltn12.filter.chain(base64, wrap) +end +sink = ltn12.sink.chain(convert, sink) +ltn12.pump.all(source, sink) diff --git a/src/libs/luasocket/etc/check-links.lua b/src/libs/luasocket/etc/check-links.lua new file mode 100644 index 000000000..a989f8c27 --- /dev/null +++ b/src/libs/luasocket/etc/check-links.lua @@ -0,0 +1,112 @@ +----------------------------------------------------------------------------- +-- Little program that checks links in HTML files, using coroutines and +-- non-blocking I/O via the dispatcher module. +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $$ +----------------------------------------------------------------------------- +local url = require("socket.url") +local dispatch = require("dispatch") +local http = require("socket.http") +dispatch.TIMEOUT = 10 + +-- make sure the user knows how to invoke us +arg = arg or {} +if table.getn(arg) < 1 then + print("Usage:\n luasocket check-links.lua [-n] {<url>}") + exit() +end + +-- '-n' means we are running in non-blocking mode +if arg[1] == "-n" then + -- if non-blocking I/O was requested, use real dispatcher interface + table.remove(arg, 1) + handler = dispatch.newhandler("coroutine") +else + -- if using blocking I/O, use fake dispatcher interface + handler = dispatch.newhandler("sequential") +end + +local nthreads = 0 + +-- get the status of a URL using the dispatcher +function getstatus(link) + local parsed = url.parse(link, {scheme = "file"}) + if parsed.scheme == "http" then + nthreads = nthreads + 1 + handler:start(function() + local r, c, h, s = http.request{ + method = "HEAD", + url = link, + create = handler.tcp + } + if r and c == 200 then io.write('\t', link, '\n') + else io.write('\t', link, ': ', tostring(c), '\n') end + nthreads = nthreads - 1 + end) + end +end + +function readfile(path) + path = url.unescape(path) + local file, error = io.open(path, "r") + if file then + local body = file:read("*a") + file:close() + return body + else return nil, error end +end + +function load(u) + local parsed = url.parse(u, { scheme = "file" }) + local body, headers, code, error + local base = u + if parsed.scheme == "http" then + body, code, headers = http.request(u) + if code == 200 then + -- if there was a redirect, update base to reflect it + base = headers.location or base + end + if not body then + error = code + end + elseif parsed.scheme == "file" then + body, error = readfile(parsed.path) + else error = string.format("unhandled scheme '%s'", parsed.scheme) end + return base, body, error +end + +function getlinks(body, base) + -- get rid of comments + body = string.gsub(body, "%<%!%-%-.-%-%-%>", "") + local links = {} + -- extract links + body = string.gsub(body, '[Hh][Rr][Ee][Ff]%s*=%s*"([^"]*)"', function(href) + table.insert(links, url.absolute(base, href)) + end) + body = string.gsub(body, "[Hh][Rr][Ee][Ff]%s*=%s*'([^']*)'", function(href) + table.insert(links, url.absolute(base, href)) + end) + string.gsub(body, "[Hh][Rr][Ee][Ff]%s*=%s*(.-)>", function(href) + table.insert(links, url.absolute(base, href)) + end) + return links +end + +function checklinks(address) + local base, body, error = load(address) + if not body then print(error) return end + print("Checking ", base) + local links = getlinks(body, base) + for _, link in ipairs(links) do + getstatus(link) + end +end + +for _, address in ipairs(arg) do + checklinks(url.absolute("file:", address)) +end + +while nthreads > 0 do + handler:step() +end diff --git a/src/libs/luasocket/etc/check-memory.lua b/src/libs/luasocket/etc/check-memory.lua new file mode 100644 index 000000000..7bd984d8e --- /dev/null +++ b/src/libs/luasocket/etc/check-memory.lua @@ -0,0 +1,17 @@ +function load(s) + collectgarbage() + local a = gcinfo() + _G[s] = require(s) + collectgarbage() + local b = gcinfo() + print(s .. ":\t " .. (b-a) .. "k") +end + +load("socket.url") +load("ltn12") +load("socket") +load("mime") +load("socket.tp") +load("socket.smtp") +load("socket.http") +load("socket.ftp") diff --git a/src/libs/luasocket/etc/dict.lua b/src/libs/luasocket/etc/dict.lua new file mode 100644 index 000000000..c082c24c0 --- /dev/null +++ b/src/libs/luasocket/etc/dict.lua @@ -0,0 +1,152 @@ +----------------------------------------------------------------------------- +-- Little program to download DICT word definitions +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: dict.lua,v 1.22 2005/11/22 08:33:29 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Load required modules +----------------------------------------------------------------------------- +local base = _G +local string = require("string") +local table = require("table") +local socket = require("socket") +local url = require("socket.url") +local tp = require("socket.tp") +module("socket.dict") + +----------------------------------------------------------------------------- +-- Globals +----------------------------------------------------------------------------- +HOST = "dict.org" +PORT = 2628 +TIMEOUT = 10 + +----------------------------------------------------------------------------- +-- Low-level dict API +----------------------------------------------------------------------------- +local metat = { __index = {} } + +function open(host, port) + local tp = socket.try(tp.connect(host or HOST, port or PORT, TIMEOUT)) + return base.setmetatable({tp = tp}, metat) +end + +function metat.__index:greet() + return socket.try(self.tp:check(220)) +end + +function metat.__index:check(ok) + local code, status = socket.try(self.tp:check(ok)) + return code, + base.tonumber(socket.skip(2, string.find(status, "^%d%d%d (%d*)"))) +end + +function metat.__index:getdef() + local line = socket.try(self.tp:receive()) + local def = {} + while line ~= "." do + table.insert(def, line) + line = socket.try(self.tp:receive()) + end + return table.concat(def, "\n") +end + +function metat.__index:define(database, word) + database = database or "!" + socket.try(self.tp:command("DEFINE", database .. " " .. word)) + local code, count = self:check(150) + local defs = {} + for i = 1, count do + self:check(151) + table.insert(defs, self:getdef()) + end + self:check(250) + return defs +end + +function metat.__index:match(database, strat, word) + database = database or "!" + strat = strat or "." + socket.try(self.tp:command("MATCH", database .." ".. strat .." ".. word)) + self:check(152) + local mat = {} + local line = socket.try(self.tp:receive()) + while line ~= '.' do + database, word = socket.skip(2, string.find(line, "(%S+) (.*)")) + if not mat[database] then mat[database] = {} end + table.insert(mat[database], word) + line = socket.try(self.tp:receive()) + end + self:check(250) + return mat +end + +function metat.__index:quit() + self.tp:command("QUIT") + return self:check(221) +end + +function metat.__index:close() + return self.tp:close() +end + +----------------------------------------------------------------------------- +-- High-level dict API +----------------------------------------------------------------------------- +local default = { + scheme = "dict", + host = "dict.org" +} + +local function there(f) + if f == "" then return nil + else return f end +end + +local function parse(u) + local t = socket.try(url.parse(u, default)) + socket.try(t.scheme == "dict", "invalid scheme '" .. t.scheme .. "'") + socket.try(t.path, "invalid path in url") + local cmd, arg = socket.skip(2, string.find(t.path, "^/(.)(.*)$")) + socket.try(cmd == "d" or cmd == "m", "<command> should be 'm' or 'd'") + socket.try(arg and arg ~= "", "need at least <word> in URL") + t.command, t.argument = cmd, arg + arg = string.gsub(arg, "^:([^:]+)", function(f) t.word = f end) + socket.try(t.word, "need at least <word> in URL") + arg = string.gsub(arg, "^:([^:]*)", function(f) t.database = there(f) end) + if cmd == "m" then + arg = string.gsub(arg, "^:([^:]*)", function(f) t.strat = there(f) end) + end + string.gsub(arg, ":([^:]*)$", function(f) t.n = base.tonumber(f) end) + return t +end + +local function tget(gett) + local con = open(gett.host, gett.port) + con:greet() + if gett.command == "d" then + local def = con:define(gett.database, gett.word) + con:quit() + con:close() + if gett.n then return def[gett.n] + else return def end + elseif gett.command == "m" then + local mat = con:match(gett.database, gett.strat, gett.word) + con:quit() + con:close() + return mat + else return nil, "invalid command" end +end + +local function sget(u) + local gett = parse(u) + return tget(gett) +end + +get = socket.protect(function(gett) + if base.type(gett) == "string" then return sget(gett) + else return tget(gett) end +end) + diff --git a/src/libs/luasocket/etc/dispatch.lua b/src/libs/luasocket/etc/dispatch.lua new file mode 100644 index 000000000..3ef1e72b6 --- /dev/null +++ b/src/libs/luasocket/etc/dispatch.lua @@ -0,0 +1,302 @@ +----------------------------------------------------------------------------- +-- A hacked dispatcher module +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $$ +----------------------------------------------------------------------------- +local base = _G +local table = require("table") +local socket = require("socket") +local coroutine = require("coroutine") +module("dispatch") + +-- if too much time goes by without any activity in one of our sockets, we +-- just kill it +TIMEOUT = 60 + +----------------------------------------------------------------------------- +-- We implement 3 types of dispatchers: +-- sequential +-- coroutine +-- threaded +-- The user can choose whatever one is needed +----------------------------------------------------------------------------- +local handlert = {} + +-- default handler is coroutine +function newhandler(mode) + mode = mode or "coroutine" + return handlert[mode]() +end + +local function seqstart(self, func) + return func() +end + +-- sequential handler simply calls the functions and doesn't wrap I/O +function handlert.sequential() + return { + tcp = socket.tcp, + start = seqstart + } +end + +----------------------------------------------------------------------------- +-- Mega hack. Don't try to do this at home. +----------------------------------------------------------------------------- +-- we can't yield across calls to protect, so we rewrite it with coxpcall +-- make sure you don't require any module that uses socket.protect before +-- loading our hack +function socket.protect(f) + return function(...) + local co = coroutine.create(f) + while true do + local results = {coroutine.resume(co, base.unpack(arg))} + local status = table.remove(results, 1) + if not status then + if type(results[1]) == 'table' then + return nil, results[1][1] + else base.error(results[1]) end + end + if coroutine.status(co) == "suspended" then + arg = {coroutine.yield(base.unpack(results))} + else + return base.unpack(results) + end + end + end +end + +----------------------------------------------------------------------------- +-- Simple set data structure. O(1) everything. +----------------------------------------------------------------------------- +local function newset() + local reverse = {} + local set = {} + return base.setmetatable(set, {__index = { + insert = function(set, value) + if not reverse[value] then + table.insert(set, value) + reverse[value] = table.getn(set) + end + end, + remove = function(set, value) + local index = reverse[value] + if index then + reverse[value] = nil + local top = table.remove(set) + if top ~= value then + reverse[top] = index + set[index] = top + end + end + end + }}) +end + +----------------------------------------------------------------------------- +-- socket.tcp() wrapper for the coroutine dispatcher +----------------------------------------------------------------------------- +local function cowrap(dispatcher, tcp, error) + if not tcp then return nil, error end + -- put it in non-blocking mode right away + tcp:settimeout(0) + -- metatable for wrap produces new methods on demand for those that we + -- don't override explicitly. + local metat = { __index = function(table, key) + table[key] = function(...) + arg[1] = tcp + return tcp[key](base.unpack(arg)) + end + return table[key] + end} + -- does our user want to do his own non-blocking I/O? + local zero = false + -- create a wrap object that will behave just like a real socket object + local wrap = { } + -- we ignore settimeout to preserve our 0 timeout, but record whether + -- the user wants to do his own non-blocking I/O + function wrap:settimeout(value, mode) + if value == 0 then zero = true + else zero = false end + return 1 + end + -- send in non-blocking mode and yield on timeout + function wrap:send(data, first, last) + first = (first or 1) - 1 + local result, error + while true do + -- return control to dispatcher and tell it we want to send + -- if upon return the dispatcher tells us we timed out, + -- return an error to whoever called us + if coroutine.yield(dispatcher.sending, tcp) == "timeout" then + return nil, "timeout" + end + -- try sending + result, error, first = tcp:send(data, first+1, last) + -- if we are done, or there was an unexpected error, + -- break away from loop + if error ~= "timeout" then return result, error, first end + end + end + -- receive in non-blocking mode and yield on timeout + -- or simply return partial read, if user requested timeout = 0 + function wrap:receive(pattern, partial) + local error = "timeout" + local value + while true do + -- return control to dispatcher and tell it we want to receive + -- if upon return the dispatcher tells us we timed out, + -- return an error to whoever called us + if coroutine.yield(dispatcher.receiving, tcp) == "timeout" then + return nil, "timeout" + end + -- try receiving + value, error, partial = tcp:receive(pattern, partial) + -- if we are done, or there was an unexpected error, + -- break away from loop. also, if the user requested + -- zero timeout, return all we got + if (error ~= "timeout") or zero then + return value, error, partial + end + end + end + -- connect in non-blocking mode and yield on timeout + function wrap:connect(host, port) + local result, error = tcp:connect(host, port) + if error == "timeout" then + -- return control to dispatcher. we will be writable when + -- connection succeeds. + -- if upon return the dispatcher tells us we have a + -- timeout, just abort + if coroutine.yield(dispatcher.sending, tcp) == "timeout" then + return nil, "timeout" + end + -- when we come back, check if connection was successful + result, error = tcp:connect(host, port) + if result or error == "already connected" then return 1 + else return nil, "non-blocking connect failed" end + else return result, error end + end + -- accept in non-blocking mode and yield on timeout + function wrap:accept() + while 1 do + -- return control to dispatcher. we will be readable when a + -- connection arrives. + -- if upon return the dispatcher tells us we have a + -- timeout, just abort + if coroutine.yield(dispatcher.receiving, tcp) == "timeout" then + return nil, "timeout" + end + local client, error = tcp:accept() + if error ~= "timeout" then + return cowrap(dispatcher, client, error) + end + end + end + -- remove cortn from context + function wrap:close() + dispatcher.stamp[tcp] = nil + dispatcher.sending.set:remove(tcp) + dispatcher.sending.cortn[tcp] = nil + dispatcher.receiving.set:remove(tcp) + dispatcher.receiving.cortn[tcp] = nil + return tcp:close() + end + return base.setmetatable(wrap, metat) +end + + +----------------------------------------------------------------------------- +-- Our coroutine dispatcher +----------------------------------------------------------------------------- +local cometat = { __index = {} } + +function schedule(cortn, status, operation, tcp) + if status then + if cortn and operation then + operation.set:insert(tcp) + operation.cortn[tcp] = cortn + operation.stamp[tcp] = socket.gettime() + end + else base.error(operation) end +end + +function kick(operation, tcp) + operation.cortn[tcp] = nil + operation.set:remove(tcp) +end + +function wakeup(operation, tcp) + local cortn = operation.cortn[tcp] + -- if cortn is still valid, wake it up + if cortn then + kick(operation, tcp) + return cortn, coroutine.resume(cortn) + -- othrewise, just get scheduler not to do anything + else + return nil, true + end +end + +function abort(operation, tcp) + local cortn = operation.cortn[tcp] + if cortn then + kick(operation, tcp) + coroutine.resume(cortn, "timeout") + end +end + +-- step through all active cortns +function cometat.__index:step() + -- check which sockets are interesting and act on them + local readable, writable = socket.select(self.receiving.set, + self.sending.set, 1) + -- for all readable connections, resume their cortns and reschedule + -- when they yield back to us + for _, tcp in base.ipairs(readable) do + schedule(wakeup(self.receiving, tcp)) + end + -- for all writable connections, do the same + for _, tcp in base.ipairs(writable) do + schedule(wakeup(self.sending, tcp)) + end + -- politely ask replacement I/O functions in idle cortns to + -- return reporting a timeout + local now = socket.gettime() + for tcp, stamp in base.pairs(self.stamp) do + if tcp.class == "tcp{client}" and now - stamp > TIMEOUT then + abort(self.sending, tcp) + abort(self.receiving, tcp) + end + end +end + +function cometat.__index:start(func) + local cortn = coroutine.create(func) + schedule(cortn, coroutine.resume(cortn)) +end + +function handlert.coroutine() + local stamp = {} + local dispatcher = { + stamp = stamp, + sending = { + name = "sending", + set = newset(), + cortn = {}, + stamp = stamp + }, + receiving = { + name = "receiving", + set = newset(), + cortn = {}, + stamp = stamp + }, + } + function dispatcher.tcp() + return cowrap(dispatcher, socket.tcp()) + end + return base.setmetatable(dispatcher, cometat) +end + diff --git a/src/libs/luasocket/etc/eol.lua b/src/libs/luasocket/etc/eol.lua new file mode 100644 index 000000000..b90be79d8 --- /dev/null +++ b/src/libs/luasocket/etc/eol.lua @@ -0,0 +1,14 @@ +----------------------------------------------------------------------------- +-- Little program to adjust end of line markers. +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: eol.lua,v 1.8 2005/11/22 08:33:29 diego Exp $ +----------------------------------------------------------------------------- +local mime = require("mime") +local ltn12 = require("ltn12") +local marker = '\n' +if arg and arg[1] == '-d' then marker = '\r\n' end +local filter = mime.normalize(marker) +local source = ltn12.source.chain(ltn12.source.file(io.stdin), filter) +local sink = ltn12.sink.file(io.stdout) +ltn12.pump.all(source, sink) diff --git a/src/libs/luasocket/etc/forward.lua b/src/libs/luasocket/etc/forward.lua new file mode 100644 index 000000000..9073ac4d0 --- /dev/null +++ b/src/libs/luasocket/etc/forward.lua @@ -0,0 +1,65 @@ +-- load our favourite library +local dispatch = require("dispatch") +local handler = dispatch.newhandler() + +-- make sure the user knows how to invoke us +if table.getn(arg) < 1 then + print("Usage") + print(" lua forward.lua <iport:ohost:oport> ...") + os.exit(1) +end + +-- function to move data from one socket to the other +local function move(foo, bar) + local live + while 1 do + local data, error, partial = foo:receive(2048) + live = data or error == "timeout" + data = data or partial + local result, error = bar:send(data) + if not live or not result then + foo:close() + bar:close() + break + end + end +end + +-- for each tunnel, start a new server +for i, v in ipairs(arg) do + -- capture forwarding parameters + local _, _, iport, ohost, oport = string.find(v, "([^:]+):([^:]+):([^:]+)") + assert(iport, "invalid arguments") + -- create our server socket + local server = assert(handler.tcp()) + assert(server:setoption("reuseaddr", true)) + assert(server:bind("*", iport)) + assert(server:listen(32)) + -- handler for the server object loops accepting new connections + handler:start(function() + while 1 do + local client = assert(server:accept()) + assert(client:settimeout(0)) + -- for each new connection, start a new client handler + handler:start(function() + -- handler tries to connect to peer + local peer = assert(handler.tcp()) + assert(peer:settimeout(0)) + assert(peer:connect(ohost, oport)) + -- if sucessful, starts a new handler to send data from + -- client to peer + handler:start(function() + move(client, peer) + end) + -- afte starting new handler, enter in loop sending data from + -- peer to client + move(peer, client) + end) + end + end) +end + +-- simply loop stepping the server +while 1 do + handler:step() +end diff --git a/src/libs/luasocket/etc/get.lua b/src/libs/luasocket/etc/get.lua new file mode 100644 index 000000000..3df6a4512 --- /dev/null +++ b/src/libs/luasocket/etc/get.lua @@ -0,0 +1,142 @@ +----------------------------------------------------------------------------- +-- Little program to download files from URLs +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: get.lua,v 1.25 2007/03/12 04:08:40 diego Exp $ +----------------------------------------------------------------------------- +local socket = require("socket") +local http = require("socket.http") +local ftp = require("socket.ftp") +local url = require("socket.url") +local ltn12 = require("ltn12") + +-- formats a number of seconds into human readable form +function nicetime(s) + local l = "s" + if s > 60 then + s = s / 60 + l = "m" + if s > 60 then + s = s / 60 + l = "h" + if s > 24 then + s = s / 24 + l = "d" -- hmmm + end + end + end + if l == "s" then return string.format("%5.0f%s", s, l) + else return string.format("%5.2f%s", s, l) end +end + +-- formats a number of bytes into human readable form +function nicesize(b) + local l = "B" + if b > 1024 then + b = b / 1024 + l = "KB" + if b > 1024 then + b = b / 1024 + l = "MB" + if b > 1024 then + b = b / 1024 + l = "GB" -- hmmm + end + end + end + return string.format("%7.2f%2s", b, l) +end + +-- returns a string with the current state of the download +local remaining_s = "%s received, %s/s throughput, %2.0f%% done, %s remaining" +local elapsed_s = "%s received, %s/s throughput, %s elapsed " +function gauge(got, delta, size) + local rate = got / delta + if size and size >= 1 then + return string.format(remaining_s, nicesize(got), nicesize(rate), + 100*got/size, nicetime((size-got)/rate)) + else + return string.format(elapsed_s, nicesize(got), + nicesize(rate), nicetime(delta)) + end +end + +-- creates a new instance of a receive_cb that saves to disk +-- kind of copied from luasocket's manual callback examples +function stats(size) + local start = socket.gettime() + local last = start + local got = 0 + return function(chunk) + -- elapsed time since start + local current = socket.gettime() + if chunk then + -- total bytes received + got = got + string.len(chunk) + -- not enough time for estimate + if current - last > 1 then + io.stderr:write("\r", gauge(got, current - start, size)) + io.stderr:flush() + last = current + end + else + -- close up + io.stderr:write("\r", gauge(got, current - start), "\n") + end + return chunk + end +end + +-- determines the size of a http file +function gethttpsize(u) + local r, c, h = http.request {method = "HEAD", url = u} + if c == 200 then + return tonumber(h["content-length"]) + end +end + +-- downloads a file using the http protocol +function getbyhttp(u, file) + local save = ltn12.sink.file(file or io.stdout) + -- only print feedback if output is not stdout + if file then save = ltn12.sink.chain(stats(gethttpsize(u)), save) end + local r, c, h, s = http.request {url = u, sink = save } + if c ~= 200 then io.stderr:write(s or c, "\n") end +end + +-- downloads a file using the ftp protocol +function getbyftp(u, file) + local save = ltn12.sink.file(file or io.stdout) + -- only print feedback if output is not stdout + -- and we don't know how big the file is + if file then save = ltn12.sink.chain(stats(), save) end + local gett = url.parse(u) + gett.sink = save + gett.type = "i" + local ret, err = ftp.get(gett) + if err then print(err) end +end + +-- determines the scheme +function getscheme(u) + -- this is an heuristic to solve a common invalid url poblem + if not string.find(u, "//") then u = "//" .. u end + local parsed = url.parse(u, {scheme = "http"}) + return parsed.scheme +end + +-- gets a file either by http or ftp, saving as <name> +function get(u, name) + local fout = name and io.open(name, "wb") + local scheme = getscheme(u) + if scheme == "ftp" then getbyftp(u, fout) + elseif scheme == "http" then getbyhttp(u, fout) + else print("unknown scheme" .. scheme) end +end + +-- main program +arg = arg or {} +if table.getn(arg) < 1 then + io.write("Usage:\n lua get.lua <remote-url> [<local-file>]\n") + os.exit(1) +else get(arg[1], arg[2]) end diff --git a/src/libs/luasocket/etc/lp.lua b/src/libs/luasocket/etc/lp.lua new file mode 100644 index 000000000..32699209c --- /dev/null +++ b/src/libs/luasocket/etc/lp.lua @@ -0,0 +1,324 @@ +----------------------------------------------------------------------------- +-- LPD support for the Lua language +-- LuaSocket toolkit. +-- Author: David Burgess +-- Modified by Diego Nehab, but David is in charge +-- RCS ID: $Id: lp.lua,v 1.14 2005/11/21 07:04:44 diego Exp $ +----------------------------------------------------------------------------- +--[[ + if you have any questions: RFC 1179 +]] +-- make sure LuaSocket is loaded +local io = require("io") +local base = _G +local os = require("os") +local math = require("math") +local string = require("string") +local socket = require("socket") +local ltn12 = require("ltn12") +module("socket.lp") + +-- default port +PORT = 515 +SERVER = os.getenv("SERVER_NAME") or os.getenv("COMPUTERNAME") or "localhost" +PRINTER = os.getenv("PRINTER") or "printer" + +local function connect(localhost, option) + local host = option.host or SERVER + local port = option.port or PORT + local skt + local try = socket.newtry(function() if skt then skt:close() end end) + if option.localbind then + -- bind to a local port (if we can) + local localport = 721 + local done, err + repeat + skt = socket.try(socket.tcp()) + try(skt:settimeout(30)) + done, err = skt:bind(localhost, localport) + if not done then + localport = localport + 1 + skt:close() + skt = nil + else break end + until localport > 731 + socket.try(skt, err) + else skt = socket.try(socket.tcp()) end + try(skt:connect(host, port)) + return { skt = skt, try = try } +end + +--[[ +RFC 1179 +5.3 03 - Send queue state (short) + + +----+-------+----+------+----+ + | 03 | Queue | SP | List | LF | + +----+-------+----+------+----+ + Command code - 3 + Operand 1 - Printer queue name + Other operands - User names or job numbers + + If the user names or job numbers or both are supplied then only those + jobs for those users or with those numbers will be sent. + + The response is an ASCII stream which describes the printer queue. + The stream continues until the connection closes. Ends of lines are + indicated with ASCII LF control characters. The lines may also + contain ASCII HT control characters. + +5.4 04 - Send queue state (long) + + +----+-------+----+------+----+ + | 04 | Queue | SP | List | LF | + +----+-------+----+------+----+ + Command code - 4 + Operand 1 - Printer queue name + Other operands - User names or job numbers + + If the user names or job numbers or both are supplied then only those + jobs for those users or with those numbers will be sent. + + The response is an ASCII stream which describes the printer queue. + The stream continues until the connection closes. Ends of lines are + indicated with ASCII LF control characters. The lines may also + contain ASCII HT control characters. +]] + +-- gets server acknowledement +local function recv_ack(con) + local ack = con.skt:receive(1) + con.try(string.char(0) == ack, "failed to receive server acknowledgement") +end + +-- sends client acknowledement +local function send_ack(con) + local sent = con.skt:send(string.char(0)) + con.try(sent == 1, "failed to send acknowledgement") +end + +-- sends queue request +-- 5.2 02 - Receive a printer job +-- +-- +----+-------+----+ +-- | 02 | Queue | LF | +-- +----+-------+----+ +-- Command code - 2 +-- Operand - Printer queue name +-- +-- Receiving a job is controlled by a second level of commands. The +-- daemon is given commands by sending them over the same connection. +-- The commands are described in the next section (6). +-- +-- After this command is sent, the client must read an acknowledgement +-- octet from the daemon. A positive acknowledgement is an octet of +-- zero bits. A negative acknowledgement is an octet of any other +-- pattern. +local function send_queue(con, queue) + queue = queue or PRINTER + local str = string.format("\2%s\10", queue) + local sent = con.skt:send(str) + con.try(sent == string.len(str), "failed to send print request") + recv_ack(con) +end + +-- sends control file +-- 6.2 02 - Receive control file +-- +-- +----+-------+----+------+----+ +-- | 02 | Count | SP | Name | LF | +-- +----+-------+----+------+----+ +-- Command code - 2 +-- Operand 1 - Number of bytes in control file +-- Operand 2 - Name of control file +-- +-- The control file must be an ASCII stream with the ends of lines +-- indicated by ASCII LF. The total number of bytes in the stream is +-- sent as the first operand. The name of the control file is sent as +-- the second. It should start with ASCII "cfA", followed by a three +-- digit job number, followed by the host name which has constructed the +-- control file. Acknowledgement processing must occur as usual after +-- the command is sent. +-- +-- The next "Operand 1" octets over the same TCP connection are the +-- intended contents of the control file. Once all of the contents have +-- been delivered, an octet of zero bits is sent as an indication that +-- the file being sent is complete. A second level of acknowledgement +-- processing must occur at this point. + +-- sends data file +-- 6.3 03 - Receive data file +-- +-- +----+-------+----+------+----+ +-- | 03 | Count | SP | Name | LF | +-- +----+-------+----+------+----+ +-- Command code - 3 +-- Operand 1 - Number of bytes in data file +-- Operand 2 - Name of data file +-- +-- The data file may contain any 8 bit values at all. The total number +-- of bytes in the stream may be sent as the first operand, otherwise +-- the field should be cleared to 0. The name of the data file should +-- start with ASCII "dfA". This should be followed by a three digit job +-- number. The job number should be followed by the host name which has +-- constructed the data file. Interpretation of the contents of the +-- data file is determined by the contents of the corresponding control +-- file. If a data file length has been specified, the next "Operand 1" +-- octets over the same TCP connection are the intended contents of the +-- data file. In this case, once all of the contents have been +-- delivered, an octet of zero bits is sent as an indication that the +-- file being sent is complete. A second level of acknowledgement +-- processing must occur at this point. + + +local function send_hdr(con, control) + local sent = con.skt:send(control) + con.try(sent and sent >= 1 , "failed to send header file") + recv_ack(con) +end + +local function send_control(con, control) + local sent = con.skt:send(control) + con.try(sent and sent >= 1, "failed to send control file") + send_ack(con) +end + +local function send_data(con,fh,size) + local buf + while size > 0 do + buf,message = fh:read(8192) + if buf then + st = con.try(con.skt:send(buf)) + size = size - st + else + con.try(size == 0, "file size mismatch") + end + end + recv_ack(con) -- note the double acknowledgement + send_ack(con) + recv_ack(con) + return size +end + + +--[[ +local control_dflt = { + "H"..string.sub(socket.hostname,1,31).."\10", -- host + "C"..string.sub(socket.hostname,1,31).."\10", -- class + "J"..string.sub(filename,1,99).."\10", -- jobname + "L"..string.sub(user,1,31).."\10", -- print banner page + "I"..tonumber(indent).."\10", -- indent column count ('f' only) + "M"..string.sub(mail,1,128).."\10", -- mail when printed user@host + "N"..string.sub(filename,1,131).."\10", -- name of source file + "P"..string.sub(user,1,31).."\10", -- user name + "T"..string.sub(title,1,79).."\10", -- title for banner ('p' only) + "W"..tonumber(width or 132).."\10", -- width of print f,l,p only + + "f"..file.."\10", -- formatted print (remove control chars) + "l"..file.."\10", -- print + "o"..file.."\10", -- postscript + "p"..file.."\10", -- pr format - requires T, L + "r"..file.."\10", -- fortran format + "U"..file.."\10", -- Unlink (data file only) +} +]] + +-- generate a varying job number +local seq = 0 +local function newjob(connection) + seq = seq + 1 + return math.floor(socket.gettime() * 1000 + seq)%1000 +end + + +local format_codes = { + binary = 'l', + text = 'f', + ps = 'o', + pr = 'p', + fortran = 'r', + l = 'l', + r = 'r', + o = 'o', + p = 'p', + f = 'f' +} + +-- lp.send{option} +-- requires option.file + +send = socket.protect(function(option) + socket.try(option and base.type(option) == "table", "invalid options") + local file = option.file + socket.try(file, "invalid file name") + local fh = socket.try(io.open(file,"rb")) + local datafile_size = fh:seek("end") -- get total size + fh:seek("set") -- go back to start of file + local localhost = socket.dns.gethostname() or os.getenv("COMPUTERNAME") + or "localhost" + local con = connect(localhost, option) +-- format the control file + local jobno = newjob() + local localip = socket.dns.toip(localhost) + localhost = string.sub(localhost,1,31) + local user = string.sub(option.user or os.getenv("LPRUSER") or + os.getenv("USERNAME") or os.getenv("USER") or "anonymous", 1,31) + local lpfile = string.format("dfA%3.3d%-s", jobno, localhost); + local fmt = format_codes[option.format] or 'l' + local class = string.sub(option.class or localip or localhost,1,31) + local _,_,ctlfn = string.find(file,".*[%/%\\](.*)") + ctlfn = string.sub(ctlfn or file,1,131) + local cfile = + string.format("H%-s\nC%-s\nJ%-s\nP%-s\n%.1s%-s\nU%-s\nN%-s\n", + localhost, + class, + option.job or "LuaSocket", + user, + fmt, lpfile, + lpfile, + ctlfn); -- mandatory part of ctl file + if (option.banner) then cfile = cfile .. 'L'..user..'\10' end + if (option.indent) then cfile = cfile .. 'I'..base.tonumber(option.indent)..'\10' end + if (option.mail) then cfile = cfile .. 'M'..string.sub((option.mail),1,128)..'\10' end + if (fmt == 'p' and option.title) then cfile = cfile .. 'T'..string.sub((option.title),1,79)..'\10' end + if ((fmt == 'p' or fmt == 'l' or fmt == 'f') and option.width) then + cfile = cfile .. 'W'..base.tonumber(option,width)..'\10' + end + + con.skt:settimeout(option.timeout or 65) +-- send the queue header + send_queue(con, option.queue) +-- send the control file header + local cfilecmd = string.format("\2%d cfA%3.3d%-s\n",string.len(cfile), jobno, localhost); + send_hdr(con,cfilecmd) + +-- send the control file + send_control(con,cfile) + +-- send the data file header + local dfilecmd = string.format("\3%d dfA%3.3d%-s\n",datafile_size, jobno, localhost); + send_hdr(con,dfilecmd) + +-- send the data file + send_data(con,fh,datafile_size) + fh:close() + con.skt:close(); + return jobno, datafile_size +end) + +-- +-- lp.query({host=,queue=printer|'*', format='l'|'s', list=}) +-- +query = socket.protect(function(p) + p = p or {} + local localhost = socket.dns.gethostname() or os.getenv("COMPUTERNAME") + or "localhost" + local con = connect(localhost,p) + local fmt + if string.sub(p.format or 's',1,1) == 's' then fmt = 3 else fmt = 4 end + con.try(con.skt:send(string.format("%c%s %s\n", fmt, p.queue or "*", + p.list or ""))) + local data = con.try(con.skt:receive("*a")) + con.skt:close() + return data +end) diff --git a/src/libs/luasocket/etc/qp.lua b/src/libs/luasocket/etc/qp.lua new file mode 100644 index 000000000..a4c0cad59 --- /dev/null +++ b/src/libs/luasocket/etc/qp.lua @@ -0,0 +1,24 @@ +----------------------------------------------------------------------------- +-- Little program to convert to and from Quoted-Printable +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: qp.lua,v 1.5 2004/06/17 21:46:22 diego Exp $ +----------------------------------------------------------------------------- +local ltn12 = require("ltn12") +local mime = require("mime") +local convert +arg = arg or {} +local mode = arg and arg[1] or "-et" +if mode == "-et" then + local normalize = mime.normalize() + local qp = mime.encode("quoted-printable") + local wrap = mime.wrap("quoted-printable") + convert = ltn12.filter.chain(normalize, qp, wrap) +elseif mode == "-eb" then + local qp = mime.encode("quoted-printable", "binary") + local wrap = mime.wrap("quoted-printable") + convert = ltn12.filter.chain(qp, wrap) +else convert = mime.decode("quoted-printable") end +local source = ltn12.source.chain(ltn12.source.file(io.stdin), convert) +local sink = ltn12.sink.file(io.stdout) +ltn12.pump.all(source, sink) diff --git a/src/libs/luasocket/etc/tftp.lua b/src/libs/luasocket/etc/tftp.lua new file mode 100644 index 000000000..94eaf3424 --- /dev/null +++ b/src/libs/luasocket/etc/tftp.lua @@ -0,0 +1,155 @@ +----------------------------------------------------------------------------- +-- TFTP support for the Lua language +-- LuaSocket toolkit. +-- Author: Diego Nehab +-- RCS ID: $Id: tftp.lua,v 1.16 2005/11/22 08:33:29 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Load required files +----------------------------------------------------------------------------- +local base = _G +local table = require("table") +local math = require("math") +local string = require("string") +local socket = require("socket") +local ltn12 = require("ltn12") +local url = require("socket.url") +module("socket.tftp") + +----------------------------------------------------------------------------- +-- Program constants +----------------------------------------------------------------------------- +local char = string.char +local byte = string.byte + +PORT = 69 +local OP_RRQ = 1 +local OP_WRQ = 2 +local OP_DATA = 3 +local OP_ACK = 4 +local OP_ERROR = 5 +local OP_INV = {"RRQ", "WRQ", "DATA", "ACK", "ERROR"} + +----------------------------------------------------------------------------- +-- Packet creation functions +----------------------------------------------------------------------------- +local function RRQ(source, mode) + return char(0, OP_RRQ) .. source .. char(0) .. mode .. char(0) +end + +local function WRQ(source, mode) + return char(0, OP_RRQ) .. source .. char(0) .. mode .. char(0) +end + +local function ACK(block) + local low, high + low = math.mod(block, 256) + high = (block - low)/256 + return char(0, OP_ACK, high, low) +end + +local function get_OP(dgram) + local op = byte(dgram, 1)*256 + byte(dgram, 2) + return op +end + +----------------------------------------------------------------------------- +-- Packet analysis functions +----------------------------------------------------------------------------- +local function split_DATA(dgram) + local block = byte(dgram, 3)*256 + byte(dgram, 4) + local data = string.sub(dgram, 5) + return block, data +end + +local function get_ERROR(dgram) + local code = byte(dgram, 3)*256 + byte(dgram, 4) + local msg + _,_, msg = string.find(dgram, "(.*)\000", 5) + return string.format("error code %d: %s", code, msg) +end + +----------------------------------------------------------------------------- +-- The real work +----------------------------------------------------------------------------- +local function tget(gett) + local retries, dgram, sent, datahost, dataport, code + local last = 0 + socket.try(gett.host, "missing host") + local con = socket.try(socket.udp()) + local try = socket.newtry(function() con:close() end) + -- convert from name to ip if needed + gett.host = try(socket.dns.toip(gett.host)) + con:settimeout(1) + -- first packet gives data host/port to be used for data transfers + local path = string.gsub(gett.path or "", "^/", "") + path = url.unescape(path) + retries = 0 + repeat + sent = try(con:sendto(RRQ(path, "octet"), gett.host, gett.port)) + dgram, datahost, dataport = con:receivefrom() + retries = retries + 1 + until dgram or datahost ~= "timeout" or retries > 5 + try(dgram, datahost) + -- associate socket with data host/port + try(con:setpeername(datahost, dataport)) + -- default sink + local sink = gett.sink or ltn12.sink.null() + -- process all data packets + while 1 do + -- decode packet + code = get_OP(dgram) + try(code ~= OP_ERROR, get_ERROR(dgram)) + try(code == OP_DATA, "unhandled opcode " .. code) + -- get data packet parts + local block, data = split_DATA(dgram) + -- if not repeated, write + if block == last+1 then + try(sink(data)) + last = block + end + -- last packet brings less than 512 bytes of data + if string.len(data) < 512 then + try(con:send(ACK(block))) + try(con:close()) + try(sink(nil)) + return 1 + end + -- get the next packet + retries = 0 + repeat + sent = try(con:send(ACK(last))) + dgram, err = con:receive() + retries = retries + 1 + until dgram or err ~= "timeout" or retries > 5 + try(dgram, err) + end +end + +local default = { + port = PORT, + path ="/", + scheme = "tftp" +} + +local function parse(u) + local t = socket.try(url.parse(u, default)) + socket.try(t.scheme == "tftp", "invalid scheme '" .. t.scheme .. "'") + socket.try(t.host, "invalid host") + return t +end + +local function sget(u) + local gett = parse(u) + local t = {} + gett.sink = ltn12.sink.table(t) + tget(gett) + return table.concat(t) +end + +get = socket.protect(function(gett) + if base.type(gett) == "string" then return sget(gett) + else return tget(gett) end +end) + diff --git a/src/libs/luasocket/luasocket.sln b/src/libs/luasocket/luasocket.sln new file mode 100644 index 000000000..a674c33ca --- /dev/null +++ b/src/libs/luasocket/luasocket.sln @@ -0,0 +1,37 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "socket", "socket.vcproj", "{66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mime", "mime.vcproj", "{128E8BD0-174A-48F0-8771-92B1E8D18713}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libluasocket", "libluasocket.vcproj", "{599EAD40-60EE-4043-9C14-AE090A8A092D}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Debug.ActiveCfg = Debug|Win32 + {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Debug.Build.0 = Debug|Win32 + {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Release.ActiveCfg = Release|Win32 + {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Release.Build.0 = Release|Win32 + {128E8BD0-174A-48F0-8771-92B1E8D18713}.Debug.ActiveCfg = Debug|Win32 + {128E8BD0-174A-48F0-8771-92B1E8D18713}.Debug.Build.0 = Debug|Win32 + {128E8BD0-174A-48F0-8771-92B1E8D18713}.Release.ActiveCfg = Release|Win32 + {128E8BD0-174A-48F0-8771-92B1E8D18713}.Release.Build.0 = Release|Win32 + {599EAD40-60EE-4043-9C14-AE090A8A092D}.Debug.ActiveCfg = Debug|Win32 + {599EAD40-60EE-4043-9C14-AE090A8A092D}.Debug.Build.0 = Debug|Win32 + {599EAD40-60EE-4043-9C14-AE090A8A092D}.Release.ActiveCfg = Release|Win32 + {599EAD40-60EE-4043-9C14-AE090A8A092D}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/libs/luasocket/makefile b/src/libs/luasocket/makefile new file mode 100644 index 000000000..6d700392a --- /dev/null +++ b/src/libs/luasocket/makefile @@ -0,0 +1,51 @@ +#------ +# Load configuration +# +include config + +#------ +# Hopefully no need to change anything below this line +# +INSTALL_SOCKET_SHARE=$(INSTALL_TOP_SHARE)/socket +INSTALL_SOCKET_LIB=$(INSTALL_TOP_LIB)/socket +INSTALL_MIME_SHARE=$(INSTALL_TOP_SHARE)/mime +INSTALL_MIME_LIB=$(INSTALL_TOP_LIB)/mime + +all clean: + cd src; $(MAKE) $@ + +#------ +# Files to install +# +TO_SOCKET_SHARE:= \ + http.lua \ + url.lua \ + tp.lua \ + ftp.lua \ + smtp.lua + +TO_TOP_SHARE:= \ + ltn12.lua \ + socket.lua \ + mime.lua + +TO_MIME_SHARE:= + +#------ +# Install LuaSocket according to recommendation +# +install: all + cd src; mkdir -p $(INSTALL_TOP_SHARE) + cd src; $(INSTALL_DATA) $(TO_TOP_SHARE) $(INSTALL_TOP_SHARE) + cd src; mkdir -p $(INSTALL_SOCKET_SHARE) + cd src; $(INSTALL_DATA) $(TO_SOCKET_SHARE) $(INSTALL_SOCKET_SHARE) + cd src; mkdir -p $(INSTALL_SOCKET_LIB) + cd src; $(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET_LIB)/core.$(EXT) + #cd src; mkdir -p $(INSTALL_MIME_SHARE) + #cd src; $(INSTALL_DATA) $(TO_MIME_SHARE) $(INSTALL_MIME_SHARE) + cd src; mkdir -p $(INSTALL_MIME_LIB) + cd src; $(INSTALL_EXEC) $(MIME_SO) $(INSTALL_MIME_LIB)/core.$(EXT) + +#------ +# End of makefile +# diff --git a/src/libs/luasocket/mime.vcproj b/src/libs/luasocket/mime.vcproj new file mode 100644 index 000000000..8ad790040 --- /dev/null +++ b/src/libs/luasocket/mime.vcproj @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="mime" + ProjectGUID="{128E8BD0-174A-48F0-8771-92B1E8D18713}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="src" + IntermediateDirectory="src" + ConfigurationType="2" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="h:\include\lua5.1" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MIME_EXPORTS;MIME_API=__declspec(dllexport)" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/mime.dll" + LinkIncremental="2" + AdditionalLibraryDirectories="h:\lib" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/mime.pdb" + SubSystem="2" + ImportLibrary="$(OutDir)/mime.lib" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="src" + IntermediateDirectory="src" + ConfigurationType="2" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="h:\include\lua5.1" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MIME_EXPORTS; MIME_API=__declspec(dllexport)" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="4" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/mime.dll" + LinkIncremental="1" + AdditionalLibraryDirectories="h:\lib" + GenerateDebugInformation="TRUE" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + ImportLibrary="$(OutDir)/mime.lib" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath="src\mime.c"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + <File + RelativePath="..\..\lib\lua5.1.dll.lib"> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/luasocket/samples/README b/src/libs/luasocket/samples/README new file mode 100644 index 000000000..e63a6f521 --- /dev/null +++ b/src/libs/luasocket/samples/README @@ -0,0 +1,50 @@ +This directory contains some sample programs using +LuaSocket. This code is not supported. + + listener.lua -- socket to stdout + talker.lua -- stdin to socket + +listener.lua and talker.lua are about the simplest +applications you can write using LuaSocket. Run + + 'lua listener.lua' and 'lua talker.lua' + +on different terminals. Whatever you type on talk.lua will +be printed by listen.lua. + + lpr.lua -- lpr client + +This is a cool program written by David Burgess to print +files using the Line Printer Daemon protocol, widely used in +Unix machines. It uses the lp.lua implementation, in the +etc directory. Just run 'lua lpr.lua <filename> +queue=<printername>' and the file will print! + + cddb.lua -- CDDB client + +This is the first try on a simple CDDB client. Not really +useful, but one day it might become a module. + + daytimeclnt.lua -- day time client + +Just run the program to retrieve the hour and date in +readable form from any server running an UDP daytime daemon. + + echoclnt.lua -- UDP echo client + echosrvr.lua -- UDP echo server + +These are a UDP echo client/server pair. They work with +other client and servers as well. + + tinyirc.lua -- irc like broadcast server + +This is a simple server that waits simultaneously on two +server sockets for telnet connections. Everything it +receives from the telnet clients is broadcasted to every +other connected client. It tests the select function and +shows how to create a simple server whith LuaSocket. Just +run tinyirc.lua and then open as many telnet connections +as you want to ports 8080 and 8081. + +Good luck, +Diego. diff --git a/src/libs/luasocket/samples/cddb.lua b/src/libs/luasocket/samples/cddb.lua new file mode 100644 index 000000000..883730c3a --- /dev/null +++ b/src/libs/luasocket/samples/cddb.lua @@ -0,0 +1,46 @@ +local socket = require("socket") +local http = require("socket.http") + +if not arg or not arg[1] or not arg[2] then + print("luasocket cddb.lua <category> <disc-id> [<server>]") + os.exit(1) +end + +local server = arg[3] or "http://freedb.freedb.org/~cddb/cddb.cgi" + +function parse(body) + local lines = string.gfind(body, "(.-)\r\n") + local status = lines() + local code, message = socket.skip(2, string.find(status, "(%d%d%d) (.*)")) + if tonumber(code) ~= 210 then + return nil, code, message + end + local data = {} + for l in lines do + local c = string.sub(l, 1, 1) + if c ~= '#' and c ~= '.' then + local key, value = socket.skip(2, string.find(l, "(.-)=(.*)")) + value = string.gsub(value, "\\n", "\n") + value = string.gsub(value, "\\\\", "\\") + value = string.gsub(value, "\\t", "\t") + data[key] = value + end + end + return data, code, message +end + +local host = socket.dns.gethostname() +local query = "%s?cmd=cddb+read+%s+%s&hello=LuaSocket+%s+LuaSocket+2.0&proto=6" +local url = string.format(query, server, arg[1], arg[2], host) +local body, headers, code = http.get(url) + +if code == 200 then + local data, code, error = parse(body) + if not data then + print(error or code) + else + for i,v in pairs(data) do + io.write(i, ': ', v, '\n') + end + end +else print(error) end diff --git a/src/libs/luasocket/samples/daytimeclnt.lua b/src/libs/luasocket/samples/daytimeclnt.lua new file mode 100644 index 000000000..90ab39e97 --- /dev/null +++ b/src/libs/luasocket/samples/daytimeclnt.lua @@ -0,0 +1,23 @@ +----------------------------------------------------------------------------- +-- UDP sample: daytime protocol client +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: daytimeclnt.lua,v 1.11 2004/06/21 06:07:57 diego Exp $ +----------------------------------------------------------------------------- +local socket = require"socket" +host = host or "127.0.0.1" +port = port or 13 +if arg then + host = arg[1] or host + port = arg[2] or port +end +host = socket.dns.toip(host) +udp = socket.udp() +print("Using host '" ..host.. "' and port " ..port.. "...") +udp:setpeername(host, port) +udp:settimeout(3) +sent, err = udp:send("anything") +if err then print(err) os.exit() end +dgram, err = udp:receive() +if not dgram then print(err) os.exit() end +io.write(dgram) diff --git a/src/libs/luasocket/samples/echoclnt.lua b/src/libs/luasocket/samples/echoclnt.lua new file mode 100644 index 000000000..038be4c23 --- /dev/null +++ b/src/libs/luasocket/samples/echoclnt.lua @@ -0,0 +1,24 @@ +----------------------------------------------------------------------------- +-- UDP sample: echo protocol client +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: echoclnt.lua,v 1.10 2005/01/02 22:44:00 diego Exp $ +----------------------------------------------------------------------------- +local socket = require("socket") +host = host or "localhost" +port = port or 7 +if arg then + host = arg[1] or host + port = arg[2] or port +end +host = socket.dns.toip(host) +udp = assert(socket.udp()) +assert(udp:setpeername(host, port)) +print("Using remote host '" ..host.. "' and port " .. port .. "...") +while 1 do + line = io.read() + if not line or line == "" then os.exit() end + assert(udp:send(line)) + dgram = assert(udp:receive()) + print(dgram) +end diff --git a/src/libs/luasocket/samples/echosrvr.lua b/src/libs/luasocket/samples/echosrvr.lua new file mode 100644 index 000000000..2697ca46d --- /dev/null +++ b/src/libs/luasocket/samples/echosrvr.lua @@ -0,0 +1,29 @@ +----------------------------------------------------------------------------- +-- UDP sample: echo protocol server +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: echosrvr.lua,v 1.12 2005/11/22 08:33:29 diego Exp $ +----------------------------------------------------------------------------- +local socket = require("socket") +host = host or "127.0.0.1" +port = port or 7 +if arg then + host = arg[1] or host + port = arg[2] or port +end +print("Binding to host '" ..host.. "' and port " ..port.. "...") +udp = assert(socket.udp()) +assert(udp:setsockname(host, port)) +assert(udp:settimeout(5)) +ip, port = udp:getsockname() +assert(ip, port) +print("Waiting packets on " .. ip .. ":" .. port .. "...") +while 1 do + dgram, ip, port = udp:receivefrom() + if dgram then + print("Echoing '" .. dgram .. "' to " .. ip .. ":" .. port) + udp:sendto(dgram, ip, port) + else + print(ip) + end +end diff --git a/src/libs/luasocket/samples/listener.lua b/src/libs/luasocket/samples/listener.lua new file mode 100644 index 000000000..9260fbb0f --- /dev/null +++ b/src/libs/luasocket/samples/listener.lua @@ -0,0 +1,26 @@ +----------------------------------------------------------------------------- +-- TCP sample: Little program to dump lines received at a given port +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: listener.lua,v 1.11 2005/01/02 22:44:00 diego Exp $ +----------------------------------------------------------------------------- +local socket = require("socket") +host = host or "*" +port = port or 8080 +if arg then + host = arg[1] or host + port = arg[2] or port +end +print("Binding to host '" ..host.. "' and port " ..port.. "...") +s = assert(socket.bind(host, port)) +i, p = s:getsockname() +assert(i, p) +print("Waiting connection from talker on " .. i .. ":" .. p .. "...") +c = assert(s:accept()) +print("Connected. Here is the stuff:") +l, e = c:receive() +while not e do + print(l) + l, e = c:receive() +end +print(e) diff --git a/src/libs/luasocket/samples/lpr.lua b/src/libs/luasocket/samples/lpr.lua new file mode 100644 index 000000000..2b059b158 --- /dev/null +++ b/src/libs/luasocket/samples/lpr.lua @@ -0,0 +1,51 @@ +local lp = require("socket.lp") + +local function usage() + print('\nUsage: lua lpr.lua [filename] [keyword=val...]\n') + print('Valid keywords are :') + print( + ' host=remote host or IP address (default "localhost")\n' .. + ' queue=remote queue or printer name (default "printer")\n' .. + ' port=remote port number (default 515)\n' .. + ' user=sending user name\n' .. + ' format=["binary" | "text" | "ps" | "pr" | "fortran"] (default "binary")\n' .. + ' banner=true|false\n' .. + ' indent=number of columns to indent\n' .. + ' mail=email of address to notify when print is complete\n' .. + ' title=title to use for "pr" format\n' .. + ' width=width for "text" or "pr" formats\n' .. + ' class=\n' .. + ' job=\n' .. + ' name=\n' .. + ' localbind=true|false\n' + ) + return nil +end + +if not arg or not arg[1] then + return usage() +end + +do + local opt = {} + local pat = "[%s%c%p]*([%w]*)=([\"]?[%w%s_!@#$%%^&*()<>:;]+[\"]\?\.?)" + for i = 2, table.getn(arg), 1 do + string.gsub(arg[i], pat, function(name, value) opt[name] = value end) + end + if not arg[2] then + return usage() + end + if arg[1] ~= "query" then + opt.file = arg[1] + r,e=lp.send(opt) + io.stdout:write(tostring(r or e),'\n') + else + r,e=lp.query(opt) + io.stdout:write(tostring(r or e), '\n') + end +end + +-- trivial tests +--lua lp.lua lp.lua queue=default host=localhost +--lua lp.lua lp.lua queue=default host=localhost format=binary localbind=1 +--lua lp.lua query queue=default host=localhost diff --git a/src/libs/luasocket/samples/talker.lua b/src/libs/luasocket/samples/talker.lua new file mode 100644 index 000000000..607ff3198 --- /dev/null +++ b/src/libs/luasocket/samples/talker.lua @@ -0,0 +1,21 @@ +----------------------------------------------------------------------------- +-- TCP sample: Little program to send text lines to a given host/port +-- LuaSocket sample files +-- Author: Diego Nehab +-- RCS ID: $Id: talker.lua,v 1.9 2005/01/02 22:44:00 diego Exp $ +----------------------------------------------------------------------------- +local socket = require("socket") +host = host or "localhost" +port = port or 8080 +if arg then + host = arg[1] or host + port = arg[2] or port +end +print("Attempting connection to host '" ..host.. "' and port " ..port.. "...") +c = assert(socket.connect(host, port)) +print("Connected! Please type stuff (empty line to stop):") +l = io.read() +while l and l ~= "" and not e do + assert(c:send(l .. "\n")) + l = io.read() +end diff --git a/src/libs/luasocket/samples/tinyirc.lua b/src/libs/luasocket/samples/tinyirc.lua new file mode 100644 index 000000000..f474302e0 --- /dev/null +++ b/src/libs/luasocket/samples/tinyirc.lua @@ -0,0 +1,90 @@ +----------------------------------------------------------------------------- +-- Select sample: simple text line server +-- LuaSocket sample files. +-- Author: Diego Nehab +-- RCS ID: $Id: tinyirc.lua,v 1.14 2005/11/22 08:33:29 diego Exp $ +----------------------------------------------------------------------------- +local socket = require("socket") +host = host or "*" +port1 = port1 or 8080 +port2 = port2 or 8181 +if arg then + host = arg[1] or host + port1 = arg[2] or port1 + port2 = arg[3] or port2 +end + +server1 = assert(socket.bind(host, port1)) +server2 = assert(socket.bind(host, port2)) +server1:settimeout(1) -- make sure we don't block in accept +server2:settimeout(1) + +io.write("Servers bound\n") + +-- simple set implementation +-- the select function doesn't care about what is passed to it as long as +-- it behaves like a table +-- creates a new set data structure +function newset() + local reverse = {} + local set = {} + return setmetatable(set, {__index = { + insert = function(set, value) + if not reverse[value] then + table.insert(set, value) + reverse[value] = table.getn(set) + end + end, + remove = function(set, value) + local index = reverse[value] + if index then + reverse[value] = nil + local top = table.remove(set) + if top ~= value then + reverse[top] = index + set[index] = top + end + end + end + }}) +end + +set = newset() + +io.write("Inserting servers in set\n") +set:insert(server1) +set:insert(server2) + +while 1 do + local readable, _, error = socket.select(set, nil) + for _, input in ipairs(readable) do + -- is it a server socket? + if input == server1 or input == server2 then + io.write("Waiting for clients\n") + local new = input:accept() + if new then + new:settimeout(1) + io.write("Inserting client in set\n") + set:insert(new) + end + -- it is a client socket + else + local line, error = input:receive() + if error then + input:close() + io.write("Removing client from set\n") + set:remove(input) + else + io.write("Broadcasting line '", line, "'\n") + writable, error = socket.skip(1, socket.select(nil, set, 1)) + if not error then + for __, output in ipairs(writable) do + if output ~= input then + output:send(line .. "\n") + end + end + else io.write("No client ready to receive!!!\n") end + end + end + end +end diff --git a/src/libs/luasocket/socket.vcproj b/src/libs/luasocket/socket.vcproj new file mode 100644 index 000000000..b7c4a0832 --- /dev/null +++ b/src/libs/luasocket/socket.vcproj @@ -0,0 +1,182 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="socket" + ProjectGUID="{66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="src" + IntermediateDirectory="src" + ConfigurationType="2" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="h:\include\lua5.1" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LUASOCKET_EXPORTS;LUASOCKET_API=__declspec(dllexport)" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="ws2_32.lib" + OutputFile="$(OutDir)/socket.dll" + LinkIncremental="2" + AdditionalLibraryDirectories="h:\lib" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/socket.pdb" + SubSystem="2" + ImportLibrary="$(OutDir)/socket.lib" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="./src" + IntermediateDirectory="./src" + ConfigurationType="2" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="h:\include\lua5.1" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LUASOCKET_EXPORTS;LUASOCKET_API=__declspec(dllexport); LUASOCKET_DEBUG" + RuntimeLibrary="2" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="ws2_32.lib" + OutputFile="$(OutDir)/socket.dll" + LinkIncremental="1" + AdditionalLibraryDirectories="h:\lib" + GenerateDebugInformation="TRUE" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + ImportLibrary="$(OutDir)/socket.lib" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath="src\auxiliar.c"> + </File> + <File + RelativePath="src\buffer.c"> + </File> + <File + RelativePath="src\except.c"> + </File> + <File + RelativePath="src\inet.c"> + </File> + <File + RelativePath="src\io.c"> + </File> + <File + RelativePath="src\luasocket.c"> + </File> + <File + RelativePath="src\options.c"> + </File> + <File + RelativePath="src\select.c"> + </File> + <File + RelativePath="src\tcp.c"> + </File> + <File + RelativePath="src\timeout.c"> + </File> + <File + RelativePath="src\udp.c"> + </File> + <File + RelativePath="src\wsocket.c"> + <FileConfiguration + Name="Release|Win32"> + <Tool + Name="VCCLCompilerTool" + GeneratePreprocessedFile="0"/> + </FileConfiguration> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + <File + RelativePath="..\..\lib\lua5.1.dll.lib"> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/libs/luasocket/src/Makefile b/src/libs/luasocket/src/Makefile new file mode 100644 index 000000000..988a66827 --- /dev/null +++ b/src/libs/luasocket/src/Makefile @@ -0,0 +1,64 @@ + +SOCKET_SO=socket.a + +INSTALL_TOP_SHARE=/usr/local/share/lua/5.1 +INSTALL_TOP_LIB=/usr/local/lib/lua/5.1 + +LUAINC = -I../../lua51 +CC = gcc + +DEF = -DLUASOCKET_DEBUG +CFLAGS = $(LUAINC) $(DEF) -pedantic -Wall -O2 +AR=ar +ARFLAGS=rc + +SOCKET_OBJS:= \ + luasocket.o \ + timeout.o \ + buffer.o \ + io.o \ + auxiliar.o \ + options.o \ + inet.o \ + tcp.o \ + udp.o \ + except.o \ + select.o \ + socket.o \ + mime.o \ + lua_preload.o + +all: $(SOCKET_SO) + +$(SOCKET_SO): $(SOCKET_OBJS) + $(AR) $(ARFLAGS) $@ $(SOCKET_OBJS) + +#------ +# List of dependencies +# +auxiliar.o: auxiliar.c auxiliar.h +buffer.o: buffer.c buffer.h io.h timeout.h +except.o: except.c except.h +inet.o: inet.c inet.h socket.h io.h timeout.h usocket.h +io.o: io.c io.h timeout.h +luasocket.o: luasocket.c luasocket.h auxiliar.h except.h timeout.h \ + buffer.h io.h inet.h socket.h usocket.h tcp.h udp.h select.h +mime.o: mime.c mime.h +options.o: options.c auxiliar.h options.h socket.h io.h timeout.h \ + usocket.h inet.h +select.o: select.c socket.h io.h timeout.h usocket.h select.h +tcp.o: tcp.c auxiliar.h socket.h io.h timeout.h usocket.h inet.h \ + options.h tcp.h buffer.h +timeout.o: timeout.c auxiliar.h timeout.h +udp.o: udp.c auxiliar.h socket.h io.h timeout.h usocket.h inet.h \ + options.h udp.h +unix.o: unix.c auxiliar.h socket.h io.h timeout.h usocket.h options.h \ + unix.h buffer.h +usocket.o: usocket.c socket.h io.h timeout.h usocket.h + +clean: + rm -f $(SOCKET_SO) $(SOCKET_OBJS) + +#------ +# End of makefile configuration +# diff --git a/src/libs/luasocket/src/auxiliar.c b/src/libs/luasocket/src/auxiliar.c new file mode 100644 index 000000000..951497011 --- /dev/null +++ b/src/libs/luasocket/src/auxiliar.c @@ -0,0 +1,149 @@ +/*=========================================================================*\ +* Auxiliar routines for class hierarchy manipulation +* LuaSocket toolkit +* +* RCS ID: $Id: auxiliar.c,v 1.14 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include <string.h> +#include <stdio.h> + +#include "auxiliar.h" + +/*=========================================================================*\ +* Exported functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Initializes the module +\*-------------------------------------------------------------------------*/ +int auxiliar_open(lua_State *L) { + (void) L; + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Creates a new class with given methods +* Methods whose names start with __ are passed directly to the metatable. +\*-------------------------------------------------------------------------*/ +void auxiliar_newclass(lua_State *L, const char *classname, luaL_reg *func) { + luaL_newmetatable(L, classname); /* mt */ + /* create __index table to place methods */ + lua_pushstring(L, "__index"); /* mt,"__index" */ + lua_newtable(L); /* mt,"__index",it */ + /* put class name into class metatable */ + lua_pushstring(L, "class"); /* mt,"__index",it,"class" */ + lua_pushstring(L, classname); /* mt,"__index",it,"class",classname */ + lua_rawset(L, -3); /* mt,"__index",it */ + /* pass all methods that start with _ to the metatable, and all others + * to the index table */ + for (; func->name; func++) { /* mt,"__index",it */ + lua_pushstring(L, func->name); + lua_pushcfunction(L, func->func); + lua_rawset(L, func->name[0] == '_' ? -5: -3); + } + lua_rawset(L, -3); /* mt */ + lua_pop(L, 1); +} + +/*-------------------------------------------------------------------------*\ +* Prints the value of a class in a nice way +\*-------------------------------------------------------------------------*/ +int auxiliar_tostring(lua_State *L) { + char buf[32]; + if (!lua_getmetatable(L, 1)) goto error; + lua_pushstring(L, "__index"); + lua_gettable(L, -2); + if (!lua_istable(L, -1)) goto error; + lua_pushstring(L, "class"); + lua_gettable(L, -2); + if (!lua_isstring(L, -1)) goto error; + sprintf(buf, "%p", lua_touserdata(L, 1)); + lua_pushfstring(L, "%s: %s", lua_tostring(L, -1), buf); + return 1; +error: + lua_pushstring(L, "invalid object passed to 'auxiliar.c:__tostring'"); + lua_error(L); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Insert class into group +\*-------------------------------------------------------------------------*/ +void auxiliar_add2group(lua_State *L, const char *classname, const char *groupname) { + luaL_getmetatable(L, classname); + lua_pushstring(L, groupname); + lua_pushboolean(L, 1); + lua_rawset(L, -3); + lua_pop(L, 1); +} + +/*-------------------------------------------------------------------------*\ +* Make sure argument is a boolean +\*-------------------------------------------------------------------------*/ +int auxiliar_checkboolean(lua_State *L, int objidx) { + if (!lua_isboolean(L, objidx)) + luaL_typerror(L, objidx, lua_typename(L, LUA_TBOOLEAN)); + return lua_toboolean(L, objidx); +} + +/*-------------------------------------------------------------------------*\ +* Return userdata pointer if object belongs to a given class, abort with +* error otherwise +\*-------------------------------------------------------------------------*/ +void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx) { + void *data = auxiliar_getclassudata(L, classname, objidx); + if (!data) { + char msg[45]; + sprintf(msg, "%.35s expected", classname); + luaL_argerror(L, objidx, msg); + } + return data; +} + +/*-------------------------------------------------------------------------*\ +* Return userdata pointer if object belongs to a given group, abort with +* error otherwise +\*-------------------------------------------------------------------------*/ +void *auxiliar_checkgroup(lua_State *L, const char *groupname, int objidx) { + void *data = auxiliar_getgroupudata(L, groupname, objidx); + if (!data) { + char msg[45]; + sprintf(msg, "%.35s expected", groupname); + luaL_argerror(L, objidx, msg); + } + return data; +} + +/*-------------------------------------------------------------------------*\ +* Set object class +\*-------------------------------------------------------------------------*/ +void auxiliar_setclass(lua_State *L, const char *classname, int objidx) { + luaL_getmetatable(L, classname); + if (objidx < 0) objidx--; + lua_setmetatable(L, objidx); +} + +/*-------------------------------------------------------------------------*\ +* Get a userdata pointer if object belongs to a given group. Return NULL +* otherwise +\*-------------------------------------------------------------------------*/ +void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx) { + if (!lua_getmetatable(L, objidx)) + return NULL; + lua_pushstring(L, groupname); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); + return NULL; + } else { + lua_pop(L, 2); + return lua_touserdata(L, objidx); + } +} + +/*-------------------------------------------------------------------------*\ +* Get a userdata pointer if object belongs to a given class. Return NULL +* otherwise +\*-------------------------------------------------------------------------*/ +void *auxiliar_getclassudata(lua_State *L, const char *classname, int objidx) { + return luaL_checkudata(L, objidx, classname); +} diff --git a/src/libs/luasocket/src/auxiliar.h b/src/libs/luasocket/src/auxiliar.h new file mode 100644 index 000000000..18b849554 --- /dev/null +++ b/src/libs/luasocket/src/auxiliar.h @@ -0,0 +1,48 @@ +#ifndef AUXILIAR_H +#define AUXILIAR_H +/*=========================================================================*\ +* Auxiliar routines for class hierarchy manipulation +* LuaSocket toolkit (but completely independent of other LuaSocket modules) +* +* A LuaSocket class is a name associated with Lua metatables. A LuaSocket +* group is a name associated with a class. A class can belong to any number +* of groups. This module provides the functionality to: +* +* - create new classes +* - add classes to groups +* - set the class of objects +* - check if an object belongs to a given class or group +* - get the userdata associated to objects +* - print objects in a pretty way +* +* LuaSocket class names follow the convention <module>{<class>}. Modules +* can define any number of classes and groups. The module tcp.c, for +* example, defines the classes tcp{master}, tcp{client} and tcp{server} and +* the groups tcp{client,server} and tcp{any}. Module functions can then +* perform type-checking on their arguments by either class or group. +* +* LuaSocket metatables define the __index metamethod as being a table. This +* table has one field for each method supported by the class, and a field +* "class" with the class name. +* +* The mapping from class name to the corresponding metatable and the +* reverse mapping are done using lauxlib. +* +* RCS ID: $Id: auxiliar.h,v 1.9 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ + +#include "lua.h" +#include "lauxlib.h" + +int auxiliar_open(lua_State *L); +void auxiliar_newclass(lua_State *L, const char *classname, luaL_reg *func); +void auxiliar_add2group(lua_State *L, const char *classname, const char *group); +void auxiliar_setclass(lua_State *L, const char *classname, int objidx); +void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx); +void *auxiliar_checkgroup(lua_State *L, const char *groupname, int objidx); +void *auxiliar_getclassudata(lua_State *L, const char *groupname, int objidx); +void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx); +int auxiliar_checkboolean(lua_State *L, int objidx); +int auxiliar_tostring(lua_State *L); + +#endif /* AUXILIAR_H */ diff --git a/src/libs/luasocket/src/buffer.c b/src/libs/luasocket/src/buffer.c new file mode 100644 index 000000000..73f4ffa85 --- /dev/null +++ b/src/libs/luasocket/src/buffer.c @@ -0,0 +1,268 @@ +/*=========================================================================*\ +* Input/Output interface for Lua programs +* LuaSocket toolkit +* +* RCS ID: $Id: buffer.c,v 1.28 2007/06/11 23:44:54 diego Exp $ +\*=========================================================================*/ +#include "lua.h" +#include "lauxlib.h" + +#include "buffer.h" + +/*=========================================================================*\ +* Internal function prototypes +\*=========================================================================*/ +static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b); +static int recvline(p_buffer buf, luaL_Buffer *b); +static int recvall(p_buffer buf, luaL_Buffer *b); +static int buffer_get(p_buffer buf, const char **data, size_t *count); +static void buffer_skip(p_buffer buf, size_t count); +static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent); + +/* min and max macros */ +#ifndef MIN +#define MIN(x, y) ((x) < (y) ? x : y) +#endif +#ifndef MAX +#define MAX(x, y) ((x) > (y) ? x : y) +#endif + +/*=========================================================================*\ +* Exported functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int buffer_open(lua_State *L) { + (void) L; + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Initializes C structure +\*-------------------------------------------------------------------------*/ +void buffer_init(p_buffer buf, p_io io, p_timeout tm) { + buf->first = buf->last = 0; + buf->io = io; + buf->tm = tm; + buf->received = buf->sent = 0; + buf->birthday = timeout_gettime(); +} + +/*-------------------------------------------------------------------------*\ +* object:getstats() interface +\*-------------------------------------------------------------------------*/ +int buffer_meth_getstats(lua_State *L, p_buffer buf) { + lua_pushnumber(L, buf->received); + lua_pushnumber(L, buf->sent); + lua_pushnumber(L, timeout_gettime() - buf->birthday); + return 3; +} + +/*-------------------------------------------------------------------------*\ +* object:setstats() interface +\*-------------------------------------------------------------------------*/ +int buffer_meth_setstats(lua_State *L, p_buffer buf) { + buf->received = (long) luaL_optnumber(L, 2, buf->received); + buf->sent = (long) luaL_optnumber(L, 3, buf->sent); + if (lua_isnumber(L, 4)) buf->birthday = timeout_gettime() - lua_tonumber(L, 4); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* object:send() interface +\*-------------------------------------------------------------------------*/ +int buffer_meth_send(lua_State *L, p_buffer buf) { + int top = lua_gettop(L); + int err = IO_DONE; + size_t size = 0, sent = 0; + const char *data = luaL_checklstring(L, 2, &size); + long start = (long) luaL_optnumber(L, 3, 1); + long end = (long) luaL_optnumber(L, 4, -1); + p_timeout tm = timeout_markstart(buf->tm); + if (start < 0) start = (long) (size+start+1); + if (end < 0) end = (long) (size+end+1); + if (start < 1) start = (long) 1; + if (end > (long) size) end = (long) size; + if (start <= end) err = sendraw(buf, data+start-1, end-start+1, &sent); + /* check if there was an error */ + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, buf->io->error(buf->io->ctx, err)); + lua_pushnumber(L, sent+start-1); + } else { + lua_pushnumber(L, sent+start-1); + lua_pushnil(L); + lua_pushnil(L); + } +#ifdef LUASOCKET_DEBUG + /* push time elapsed during operation as the last return value */ + lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm)); +#endif + return lua_gettop(L) - top; +} + +/*-------------------------------------------------------------------------*\ +* object:receive() interface +\*-------------------------------------------------------------------------*/ +int buffer_meth_receive(lua_State *L, p_buffer buf) { + int err = IO_DONE, top = lua_gettop(L); + luaL_Buffer b; + size_t size; + const char *part = luaL_optlstring(L, 3, "", &size); + p_timeout tm = timeout_markstart(buf->tm); + /* initialize buffer with optional extra prefix + * (useful for concatenating previous partial results) */ + luaL_buffinit(L, &b); + luaL_addlstring(&b, part, size); + /* receive new patterns */ + if (!lua_isnumber(L, 2)) { + const char *p= luaL_optstring(L, 2, "*l"); + if (p[0] == '*' && p[1] == 'l') err = recvline(buf, &b); + else if (p[0] == '*' && p[1] == 'a') err = recvall(buf, &b); + else luaL_argcheck(L, 0, 2, "invalid receive pattern"); + /* get a fixed number of bytes (minus what was already partially + * received) */ + } else err = recvraw(buf, (size_t) lua_tonumber(L, 2)-size, &b); + /* check if there was an error */ + if (err != IO_DONE) { + /* we can't push anyting in the stack before pushing the + * contents of the buffer. this is the reason for the complication */ + luaL_pushresult(&b); + lua_pushstring(L, buf->io->error(buf->io->ctx, err)); + lua_pushvalue(L, -2); + lua_pushnil(L); + lua_replace(L, -4); + } else { + luaL_pushresult(&b); + lua_pushnil(L); + lua_pushnil(L); + } +#ifdef LUASOCKET_DEBUG + /* push time elapsed during operation as the last return value */ + lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm)); +#endif + return lua_gettop(L) - top; +} + +/*-------------------------------------------------------------------------*\ +* Determines if there is any data in the read buffer +\*-------------------------------------------------------------------------*/ +int buffer_isempty(p_buffer buf) { + return buf->first >= buf->last; +} + +/*=========================================================================*\ +* Internal functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Sends a block of data (unbuffered) +\*-------------------------------------------------------------------------*/ +#define STEPSIZE 8192 +static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent) { + p_io io = buf->io; + p_timeout tm = buf->tm; + size_t total = 0; + int err = IO_DONE; + while (total < count && err == IO_DONE) { + size_t done; + size_t step = (count-total <= STEPSIZE)? count-total: STEPSIZE; + err = io->send(io->ctx, data+total, step, &done, tm); + total += done; + } + *sent = total; + buf->sent += total; + return err; +} + +/*-------------------------------------------------------------------------*\ +* Reads a fixed number of bytes (buffered) +\*-------------------------------------------------------------------------*/ +static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b) { + int err = IO_DONE; + size_t total = 0; + while (err == IO_DONE) { + size_t count; const char *data; + err = buffer_get(buf, &data, &count); + count = MIN(count, wanted - total); + luaL_addlstring(b, data, count); + buffer_skip(buf, count); + total += count; + if (total >= wanted) break; + } + return err; +} + +/*-------------------------------------------------------------------------*\ +* Reads everything until the connection is closed (buffered) +\*-------------------------------------------------------------------------*/ +static int recvall(p_buffer buf, luaL_Buffer *b) { + int err = IO_DONE; + size_t total = 0; + while (err == IO_DONE) { + const char *data; size_t count; + err = buffer_get(buf, &data, &count); + total += count; + luaL_addlstring(b, data, count); + buffer_skip(buf, count); + } + if (err == IO_CLOSED) { + if (total > 0) return IO_DONE; + else return IO_CLOSED; + } else return err; +} + +/*-------------------------------------------------------------------------*\ +* Reads a line terminated by a CR LF pair or just by a LF. The CR and LF +* are not returned by the function and are discarded from the buffer +\*-------------------------------------------------------------------------*/ +static int recvline(p_buffer buf, luaL_Buffer *b) { + int err = IO_DONE; + while (err == IO_DONE) { + size_t count, pos; const char *data; + err = buffer_get(buf, &data, &count); + pos = 0; + while (pos < count && data[pos] != '\n') { + /* we ignore all \r's */ + if (data[pos] != '\r') luaL_putchar(b, data[pos]); + pos++; + } + if (pos < count) { /* found '\n' */ + buffer_skip(buf, pos+1); /* skip '\n' too */ + break; /* we are done */ + } else /* reached the end of the buffer */ + buffer_skip(buf, pos); + } + return err; +} + +/*-------------------------------------------------------------------------*\ +* Skips a given number of bytes from read buffer. No data is read from the +* transport layer +\*-------------------------------------------------------------------------*/ +static void buffer_skip(p_buffer buf, size_t count) { + buf->received += count; + buf->first += count; + if (buffer_isempty(buf)) + buf->first = buf->last = 0; +} + +/*-------------------------------------------------------------------------*\ +* Return any data available in buffer, or get more data from transport layer +* if buffer is empty +\*-------------------------------------------------------------------------*/ +static int buffer_get(p_buffer buf, const char **data, size_t *count) { + int err = IO_DONE; + p_io io = buf->io; + p_timeout tm = buf->tm; + if (buffer_isempty(buf)) { + size_t got; + err = io->recv(io->ctx, buf->data, BUF_SIZE, &got, tm); + buf->first = 0; + buf->last = got; + } + *count = buf->last - buf->first; + *data = buf->data + buf->first; + return err; +} diff --git a/src/libs/luasocket/src/buffer.h b/src/libs/luasocket/src/buffer.h new file mode 100644 index 000000000..baf93caa0 --- /dev/null +++ b/src/libs/luasocket/src/buffer.h @@ -0,0 +1,47 @@ +#ifndef BUF_H +#define BUF_H +/*=========================================================================*\ +* Input/Output interface for Lua programs +* LuaSocket toolkit +* +* Line patterns require buffering. Reading one character at a time involves +* too many system calls and is very slow. This module implements the +* LuaSocket interface for input/output on connected objects, as seen by +* Lua programs. +* +* Input is buffered. Output is *not* buffered because there was no simple +* way of making sure the buffered output data would ever be sent. +* +* The module is built on top of the I/O abstraction defined in io.h and the +* timeout management is done with the timeout.h interface. +* +* RCS ID: $Id: buffer.h,v 1.12 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include "lua.h" + +#include "io.h" +#include "timeout.h" + +/* buffer size in bytes */ +#define BUF_SIZE 8192 + +/* buffer control structure */ +typedef struct t_buffer_ { + double birthday; /* throttle support info: creation time, */ + size_t sent, received; /* bytes sent, and bytes received */ + p_io io; /* IO driver used for this buffer */ + p_timeout tm; /* timeout management for this buffer */ + size_t first, last; /* index of first and last bytes of stored data */ + char data[BUF_SIZE]; /* storage space for buffer data */ +} t_buffer; +typedef t_buffer *p_buffer; + +int buffer_open(lua_State *L); +void buffer_init(p_buffer buf, p_io io, p_timeout tm); +int buffer_meth_send(lua_State *L, p_buffer buf); +int buffer_meth_receive(lua_State *L, p_buffer buf); +int buffer_meth_getstats(lua_State *L, p_buffer buf); +int buffer_meth_setstats(lua_State *L, p_buffer buf); +int buffer_isempty(p_buffer buf); + +#endif /* BUF_H */ diff --git a/src/libs/luasocket/src/except.c b/src/libs/luasocket/src/except.c new file mode 100644 index 000000000..5faa5be00 --- /dev/null +++ b/src/libs/luasocket/src/except.c @@ -0,0 +1,99 @@ +/*=========================================================================*\ +* Simple exception support +* LuaSocket toolkit +* +* RCS ID: $Id: except.c,v 1.8 2005/09/29 06:11:41 diego Exp $ +\*=========================================================================*/ +#include <stdio.h> + +#include "lua.h" +#include "lauxlib.h" + +#include "except.h" + +/*=========================================================================*\ +* Internal function prototypes. +\*=========================================================================*/ +static int global_protect(lua_State *L); +static int global_newtry(lua_State *L); +static int protected_(lua_State *L); +static int finalize(lua_State *L); +static int do_nothing(lua_State *L); + +/* except functions */ +static luaL_reg func[] = { + {"newtry", global_newtry}, + {"protect", global_protect}, + {NULL, NULL} +}; + +/*-------------------------------------------------------------------------*\ +* Try factory +\*-------------------------------------------------------------------------*/ +static void wrap(lua_State *L) { + lua_newtable(L); + lua_pushnumber(L, 1); + lua_pushvalue(L, -3); + lua_settable(L, -3); + lua_insert(L, -2); + lua_pop(L, 1); +} + +static int finalize(lua_State *L) { + if (!lua_toboolean(L, 1)) { + lua_pushvalue(L, lua_upvalueindex(1)); + lua_pcall(L, 0, 0, 0); + lua_settop(L, 2); + wrap(L); + lua_error(L); + return 0; + } else return lua_gettop(L); +} + +static int do_nothing(lua_State *L) { + (void) L; + return 0; +} + +static int global_newtry(lua_State *L) { + lua_settop(L, 1); + if (lua_isnil(L, 1)) lua_pushcfunction(L, do_nothing); + lua_pushcclosure(L, finalize, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Protect factory +\*-------------------------------------------------------------------------*/ +static int unwrap(lua_State *L) { + if (lua_istable(L, -1)) { + lua_pushnumber(L, 1); + lua_gettable(L, -2); + lua_pushnil(L); + lua_insert(L, -2); + return 1; + } else return 0; +} + +static int protected_(lua_State *L) { + lua_pushvalue(L, lua_upvalueindex(1)); + lua_insert(L, 1); + if (lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) != 0) { + if (unwrap(L)) return 2; + else lua_error(L); + return 0; + } else return lua_gettop(L); +} + +static int global_protect(lua_State *L) { + lua_pushcclosure(L, protected_, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Init module +\*-------------------------------------------------------------------------*/ +int except_open(lua_State *L) { + luaL_openlib(L, NULL, func, 0); + return 0; +} diff --git a/src/libs/luasocket/src/except.h b/src/libs/luasocket/src/except.h new file mode 100644 index 000000000..81efb29be --- /dev/null +++ b/src/libs/luasocket/src/except.h @@ -0,0 +1,35 @@ +#ifndef EXCEPT_H +#define EXCEPT_H +/*=========================================================================*\ +* Exception control +* LuaSocket toolkit (but completely independent from other modules) +* +* This provides support for simple exceptions in Lua. During the +* development of the HTTP/FTP/SMTP support, it became aparent that +* error checking was taking a substantial amount of the coding. These +* function greatly simplify the task of checking errors. +* +* The main idea is that functions should return nil as its first return +* value when it finds an error, and return an error message (or value) +* following nil. In case of success, as long as the first value is not nil, +* the other values don't matter. +* +* The idea is to nest function calls with the "try" function. This function +* checks the first value, and calls "error" on the second if the first is +* nil. Otherwise, it returns all values it received. +* +* The protect function returns a new function that behaves exactly like the +* function it receives, but the new function doesn't throw exceptions: it +* returns nil followed by the error message instead. +* +* With these two function, it's easy to write functions that throw +* exceptions on error, but that don't interrupt the user script. +* +* RCS ID: $Id: except.h,v 1.2 2005/09/29 06:11:41 diego Exp $ +\*=========================================================================*/ + +#include "lua.h" + +int except_open(lua_State *L); + +#endif diff --git a/src/libs/luasocket/src/ftp.lua b/src/libs/luasocket/src/ftp.lua new file mode 100644 index 000000000..598f65dca --- /dev/null +++ b/src/libs/luasocket/src/ftp.lua @@ -0,0 +1,281 @@ +----------------------------------------------------------------------------- +-- FTP support for the Lua language +-- LuaSocket toolkit. +-- Author: Diego Nehab +-- RCS ID: $Id: ftp.lua,v 1.45 2007/07/11 19:25:47 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local table = require("table") +local string = require("string") +local math = require("math") +local socket = require("socket") +local url = require("socket.url") +local tp = require("socket.tp") +local ltn12 = require("ltn12") +module("socket.ftp") + +----------------------------------------------------------------------------- +-- Program constants +----------------------------------------------------------------------------- +-- timeout in seconds before the program gives up on a connection +TIMEOUT = 60 +-- default port for ftp service +PORT = 21 +-- this is the default anonymous password. used when no password is +-- provided in url. should be changed to your e-mail. +USER = "ftp" +PASSWORD = "anonymous@anonymous.org" + +----------------------------------------------------------------------------- +-- Low level FTP API +----------------------------------------------------------------------------- +local metat = { __index = {} } + +function open(server, port, create) + local tp = socket.try(tp.connect(server, port or PORT, TIMEOUT, create)) + local f = base.setmetatable({ tp = tp }, metat) + -- make sure everything gets closed in an exception + f.try = socket.newtry(function() f:close() end) + return f +end + +function metat.__index:portconnect() + self.try(self.server:settimeout(TIMEOUT)) + self.data = self.try(self.server:accept()) + self.try(self.data:settimeout(TIMEOUT)) +end + +function metat.__index:pasvconnect() + self.data = self.try(socket.tcp()) + self.try(self.data:settimeout(TIMEOUT)) + self.try(self.data:connect(self.pasvt.ip, self.pasvt.port)) +end + +function metat.__index:login(user, password) + self.try(self.tp:command("user", user or USER)) + local code, reply = self.try(self.tp:check{"2..", 331}) + if code == 331 then + self.try(self.tp:command("pass", password or PASSWORD)) + self.try(self.tp:check("2..")) + end + return 1 +end + +function metat.__index:pasv() + self.try(self.tp:command("pasv")) + local code, reply = self.try(self.tp:check("2..")) + local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)" + local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern)) + self.try(a and b and c and d and p1 and p2, reply) + self.pasvt = { + ip = string.format("%d.%d.%d.%d", a, b, c, d), + port = p1*256 + p2 + } + if self.server then + self.server:close() + self.server = nil + end + return self.pasvt.ip, self.pasvt.port +end + +function metat.__index:port(ip, port) + self.pasvt = nil + if not ip then + ip, port = self.try(self.tp:getcontrol():getsockname()) + self.server = self.try(socket.bind(ip, 0)) + ip, port = self.try(self.server:getsockname()) + self.try(self.server:settimeout(TIMEOUT)) + end + local pl = math.mod(port, 256) + local ph = (port - pl)/256 + local arg = string.gsub(string.format("%s,%d,%d", ip, ph, pl), "%.", ",") + self.try(self.tp:command("port", arg)) + self.try(self.tp:check("2..")) + return 1 +end + +function metat.__index:send(sendt) + self.try(self.pasvt or self.server, "need port or pasv first") + -- if there is a pasvt table, we already sent a PASV command + -- we just get the data connection into self.data + if self.pasvt then self:pasvconnect() end + -- get the transfer argument and command + local argument = sendt.argument or + url.unescape(string.gsub(sendt.path or "", "^[/\\]", "")) + if argument == "" then argument = nil end + local command = sendt.command or "stor" + -- send the transfer command and check the reply + self.try(self.tp:command(command, argument)) + local code, reply = self.try(self.tp:check{"2..", "1.."}) + -- if there is not a a pasvt table, then there is a server + -- and we already sent a PORT command + if not self.pasvt then self:portconnect() end + -- get the sink, source and step for the transfer + local step = sendt.step or ltn12.pump.step + local readt = {self.tp.c} + local checkstep = function(src, snk) + -- check status in control connection while downloading + local readyt = socket.select(readt, nil, 0) + if readyt[tp] then code = self.try(self.tp:check("2..")) end + return step(src, snk) + end + local sink = socket.sink("close-when-done", self.data) + -- transfer all data and check error + self.try(ltn12.pump.all(sendt.source, sink, checkstep)) + if string.find(code, "1..") then self.try(self.tp:check("2..")) end + -- done with data connection + self.data:close() + -- find out how many bytes were sent + local sent = socket.skip(1, self.data:getstats()) + self.data = nil + return sent +end + +function metat.__index:receive(recvt) + self.try(self.pasvt or self.server, "need port or pasv first") + if self.pasvt then self:pasvconnect() end + local argument = recvt.argument or + url.unescape(string.gsub(recvt.path or "", "^[/\\]", "")) + if argument == "" then argument = nil end + local command = recvt.command or "retr" + self.try(self.tp:command(command, argument)) + local code = self.try(self.tp:check{"1..", "2.."}) + if not self.pasvt then self:portconnect() end + local source = socket.source("until-closed", self.data) + local step = recvt.step or ltn12.pump.step + self.try(ltn12.pump.all(source, recvt.sink, step)) + if string.find(code, "1..") then self.try(self.tp:check("2..")) end + self.data:close() + self.data = nil + return 1 +end + +function metat.__index:cwd(dir) + self.try(self.tp:command("cwd", dir)) + self.try(self.tp:check(250)) + return 1 +end + +function metat.__index:type(type) + self.try(self.tp:command("type", type)) + self.try(self.tp:check(200)) + return 1 +end + +function metat.__index:greet() + local code = self.try(self.tp:check{"1..", "2.."}) + if string.find(code, "1..") then self.try(self.tp:check("2..")) end + return 1 +end + +function metat.__index:quit() + self.try(self.tp:command("quit")) + self.try(self.tp:check("2..")) + return 1 +end + +function metat.__index:close() + if self.data then self.data:close() end + if self.server then self.server:close() end + return self.tp:close() +end + +----------------------------------------------------------------------------- +-- High level FTP API +----------------------------------------------------------------------------- +local function override(t) + if t.url then + local u = url.parse(t.url) + for i,v in base.pairs(t) do + u[i] = v + end + return u + else return t end +end + +local function tput(putt) + putt = override(putt) + socket.try(putt.host, "missing hostname") + local f = open(putt.host, putt.port, putt.create) + f:greet() + f:login(putt.user, putt.password) + if putt.type then f:type(putt.type) end + f:pasv() + local sent = f:send(putt) + f:quit() + f:close() + return sent +end + +local default = { + path = "/", + scheme = "ftp" +} + +local function parse(u) + local t = socket.try(url.parse(u, default)) + socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'") + socket.try(t.host, "missing hostname") + local pat = "^type=(.)$" + if t.params then + t.type = socket.skip(2, string.find(t.params, pat)) + socket.try(t.type == "a" or t.type == "i", + "invalid type '" .. t.type .. "'") + end + return t +end + +local function sput(u, body) + local putt = parse(u) + putt.source = ltn12.source.string(body) + return tput(putt) +end + +put = socket.protect(function(putt, body) + if base.type(putt) == "string" then return sput(putt, body) + else return tput(putt) end +end) + +local function tget(gett) + gett = override(gett) + socket.try(gett.host, "missing hostname") + local f = open(gett.host, gett.port, gett.create) + f:greet() + f:login(gett.user, gett.password) + if gett.type then f:type(gett.type) end + f:pasv() + f:receive(gett) + f:quit() + return f:close() +end + +local function sget(u) + local gett = parse(u) + local t = {} + gett.sink = ltn12.sink.table(t) + tget(gett) + return table.concat(t) +end + +command = socket.protect(function(cmdt) + cmdt = override(cmdt) + socket.try(cmdt.host, "missing hostname") + socket.try(cmdt.command, "missing command") + local f = open(cmdt.host, cmdt.port, cmdt.create) + f:greet() + f:login(cmdt.user, cmdt.password) + f.try(f.tp:command(cmdt.command, cmdt.argument)) + if cmdt.check then f.try(f.tp:check(cmdt.check)) end + f:quit() + return f:close() +end) + +get = socket.protect(function(gett) + if base.type(gett) == "string" then return sget(gett) + else return tget(gett) end +end) + diff --git a/src/libs/luasocket/src/ftp_lua.c b/src/libs/luasocket/src/ftp_lua.c new file mode 100644 index 000000000..b359db30b --- /dev/null +++ b/src/libs/luasocket/src/ftp_lua.c @@ -0,0 +1,470 @@ +/* + * This file is auto-generated by "./lua2c ftp.lua ftp_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_ftp_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 70, 84, 80, 32,115,117,112,112,111,114,116, 32,102,111,114, 32,116,104,101, + 32, 76,117, 97, 32,108, 97,110,103,117, 97,103,101, 10, 45, 45, 32, 76,117, 97, + 83,111, 99,107,101,116, 32,116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65, +117,116,104,111,114, 58, 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, + 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36, 73,100, 58, 32,102,116,112, 46,108, +117, 97, 44,118, 32, 49, 46, 52, 53, 32, 50, 48, 48, 55, 47, 48, 55, 47, 49, 49, + 32, 49, 57, 58, 50, 53, 58, 52, 55, 32,100,105,101,103,111, 32, 69,120,112, 32, + 36, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, + 45, 32, 68,101, 99,108, 97,114,101, 32,109,111,100,117,108,101, 32, 97,110,100, + 32,105,109,112,111,114,116, 32,100,101,112,101,110,100,101,110, 99,105,101,115, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108, +111, 99, 97,108, 32, 98, 97,115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, + 32,116, 97, 98,108,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,116, 97, + 98,108,101, 34, 41, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, + 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108, +111, 99, 97,108, 32,109, 97,116,104, 32, 61, 32,114,101,113,117,105,114,101, 40, + 34,109, 97,116,104, 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99,107,101,116, + 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 34, 41, + 10,108,111, 99, 97,108, 32,117,114,108, 32, 61, 32,114,101,113,117,105,114,101, + 40, 34,115,111, 99,107,101,116, 46,117,114,108, 34, 41, 10,108,111, 99, 97,108, + 32,116,112, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101, +116, 46,116,112, 34, 41, 10,108,111, 99, 97,108, 32,108,116,110, 49, 50, 32, 61, + 32,114,101,113,117,105,114,101, 40, 34,108,116,110, 49, 50, 34, 41, 10,109,111, +100,117,108,101, 40, 34,115,111, 99,107,101,116, 46,102,116,112, 34, 41, 10, 10, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, 97,110,116,115, 10, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, +116,105,109,101,111,117,116, 32,105,110, 32,115,101, 99,111,110,100,115, 32, 98, +101,102,111,114,101, 32,116,104,101, 32,112,114,111,103,114, 97,109, 32,103,105, +118,101,115, 32,117,112, 32,111,110, 32, 97, 32, 99,111,110,110,101, 99,116,105, +111,110, 10, 84, 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,100, +101,102, 97,117,108,116, 32,112,111,114,116, 32,102,111,114, 32,102,116,112, 32, +115,101,114,118,105, 99,101, 10, 80, 79, 82, 84, 32, 61, 32, 50, 49, 10, 45, 45, + 32,116,104,105,115, 32,105,115, 32,116,104,101, 32,100,101,102, 97,117,108,116, + 32, 97,110,111,110,121,109,111,117,115, 32,112, 97,115,115,119,111,114,100, 46, + 32,117,115,101,100, 32,119,104,101,110, 32,110,111, 32,112, 97,115,115,119,111, +114,100, 32,105,115, 10, 45, 45, 32,112,114,111,118,105,100,101,100, 32,105,110, + 32,117,114,108, 46, 32,115,104,111,117,108,100, 32, 98,101, 32, 99,104, 97,110, +103,101,100, 32,116,111, 32,121,111,117,114, 32,101, 45,109, 97,105,108, 46, 10, + 85, 83, 69, 82, 32, 61, 32, 34,102,116,112, 34, 10, 80, 65, 83, 83, 87, 79, 82, + 68, 32, 61, 32, 34, 97,110,111,110,121,109,111,117,115, 64, 97,110,111,110,121, +109,111,117,115, 46,111,114,103, 34, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 76,111,119, 32,108,101,118,101, +108, 32, 70, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,109,101,116, 97,116, 32, + 61, 32,123, 32, 95, 95,105,110,100,101,120, 32, 61, 32,123,125, 32,125, 10, 10, +102,117,110, 99,116,105,111,110, 32,111,112,101,110, 40,115,101,114,118,101,114, + 44, 32,112,111,114,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,116,112, 32, 61, 32,115,111, 99,107,101,116, 46,116,114, +121, 40,116,112, 46, 99,111,110,110,101, 99,116, 40,115,101,114,118,101,114, 44, + 32,112,111,114,116, 32,111,114, 32, 80, 79, 82, 84, 44, 32, 84, 73, 77, 69, 79, + 85, 84, 44, 32, 99,114,101, 97,116,101, 41, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,102, 32, 61, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, + 97, 98,108,101, 40,123, 32,116,112, 32, 61, 32,116,112, 32,125, 44, 32,109,101, +116, 97,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114, +101, 32,101,118,101,114,121,116,104,105,110,103, 32,103,101,116,115, 32, 99,108, +111,115,101,100, 32,105,110, 32, 97,110, 32,101,120, 99,101,112,116,105,111,110, + 10, 32, 32, 32, 32,102, 46,116,114,121, 32, 61, 32,115,111, 99,107,101,116, 46, +110,101,119,116,114,121, 40,102,117,110, 99,116,105,111,110, 40, 41, 32,102, 58, + 99,108,111,115,101, 40, 41, 32,101,110,100, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32,102, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, +109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,112,111,114,116, 99,111, +110,110,101, 99,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, + 40,115,101,108,102, 46,115,101,114,118,101,114, 58,115,101,116,116,105,109,101, +111,117,116, 40, 84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,115,101, +108,102, 46,100, 97,116, 97, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115, +101,108,102, 46,115,101,114,118,101,114, 58, 97, 99, 99,101,112,116, 40, 41, 41, + 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,100, + 97,116, 97, 58,115,101,116,116,105,109,101,111,117,116, 40, 84, 73, 77, 69, 79, + 85, 84, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109, +101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,112, 97,115,118, 99,111,110, +110,101, 99,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,100, 97,116, 97, + 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,111, 99,107,101,116, 46,116, + 99,112, 40, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115, +101,108,102, 46,100, 97,116, 97, 58,115,101,116,116,105,109,101,111,117,116, 40, + 84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116, +114,121, 40,115,101,108,102, 46,100, 97,116, 97, 58, 99,111,110,110,101, 99,116, + 40,115,101,108,102, 46,112, 97,115,118,116, 46,105,112, 44, 32,115,101,108,102, + 46,112, 97,115,118,116, 46,112,111,114,116, 41, 41, 10,101,110,100, 10, 10,102, +117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101, +120, 58,108,111,103,105,110, 40,117,115,101,114, 44, 32,112, 97,115,115,119,111, +114,100, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108, +102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,117,115,101,114, 34, 44, + 32,117,115,101,114, 32,111,114, 32, 85, 83, 69, 82, 41, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,114,101,112,108,121, 32, 61, 32, +115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, + 99,107,123, 34, 50, 46, 46, 34, 44, 32, 51, 51, 49,125, 41, 10, 32, 32, 32, 32, +105,102, 32, 99,111,100,101, 32, 61, 61, 32, 51, 51, 49, 32,116,104,101,110, 10, + 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108, +102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,112, 97,115,115, 34, 44, + 32,112, 97,115,115,119,111,114,100, 32,111,114, 32, 80, 65, 83, 83, 87, 79, 82, + 68, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, + 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, + 41, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, +116, 97,116, 46, 95, 95,105,110,100,101,120, 58,112, 97,115,118, 40, 41, 10, 32, + 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, + 99,111,109,109, 97,110,100, 40, 34,112, 97,115,118, 34, 41, 41, 10, 32, 32, 32, + 32,108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,114,101,112,108,121, 32, 61, + 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104, +101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97, +108, 32,112, 97,116,116,101,114,110, 32, 61, 32, 34, 40, 37,100, 43, 41, 37, 68, + 40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, 37, + 68, 40, 37,100, 43, 41, 37, 68, 40, 37,100, 43, 41, 34, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32, 97, 44, 32, 98, 44, 32, 99, 44, 32,100, 44, 32,112, 49, 44, + 32,112, 50, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, + 32,115,116,114,105,110,103, 46,102,105,110,100, 40,114,101,112,108,121, 44, 32, +112, 97,116,116,101,114,110, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116, +114,121, 40, 97, 32, 97,110,100, 32, 98, 32, 97,110,100, 32, 99, 32, 97,110,100, + 32,100, 32, 97,110,100, 32,112, 49, 32, 97,110,100, 32,112, 50, 44, 32,114,101, +112,108,121, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,112, 97,115,118,116, 32, + 61, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,112, 32, 61, 32,115,116,114, +105,110,103, 46,102,111,114,109, 97,116, 40, 34, 37,100, 46, 37,100, 46, 37,100, + 46, 37,100, 34, 44, 32, 97, 44, 32, 98, 44, 32, 99, 44, 32,100, 41, 44, 10, 32, + 32, 32, 32, 32, 32, 32, 32,112,111,114,116, 32, 61, 32,112, 49, 42, 50, 53, 54, + 32, 43, 32,112, 50, 10, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,105,102, 32,115, +101,108,102, 46,115,101,114,118,101,114, 32,116,104,101,110, 10, 32, 32, 32, 32, + 32, 32, 32, 32,115,101,108,102, 46,115,101,114,118,101,114, 58, 99,108,111,115, +101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,115,101,114, +118,101,114, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, + 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,112, 97,115,118,116, 46, +105,112, 44, 32,115,101,108,102, 46,112, 97,115,118,116, 46,112,111,114,116, 10, +101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, + 95, 95,105,110,100,101,120, 58,112,111,114,116, 40,105,112, 44, 32,112,111,114, +116, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,112, 97,115,118,116, 32, 61, 32, +110,105,108, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,105,112, 32,116,104, +101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,112, 44, 32,112,111,114,116, 32, + 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,103, +101,116, 99,111,110,116,114,111,108, 40, 41, 58,103,101,116,115,111, 99,107,110, + 97,109,101, 40, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46, +115,101,114,118,101,114, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,111, + 99,107,101,116, 46, 98,105,110,100, 40,105,112, 44, 32, 48, 41, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32,105,112, 44, 32,112,111,114,116, 32, 61, 32,115,101,108, +102, 46,116,114,121, 40,115,101,108,102, 46,115,101,114,118,101,114, 58,103,101, +116,115,111, 99,107,110, 97,109,101, 40, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,115,101,114,118,101, +114, 58,115,101,116,116,105,109,101,111,117,116, 40, 84, 73, 77, 69, 79, 85, 84, + 41, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32,112,108, 32, 61, 32,109, 97,116,104, 46,109,111,100, 40,112,111,114,116, 44, + 32, 50, 53, 54, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112,104, 32, 61, + 32, 40,112,111,114,116, 32, 45, 32,112,108, 41, 47, 50, 53, 54, 10, 32, 32, 32, + 32,108,111, 99, 97,108, 32, 97,114,103, 32, 61, 32,115,116,114,105,110,103, 46, +103,115,117, 98, 40,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 34, + 37,115, 44, 37,100, 44, 37,100, 34, 44, 32,105,112, 44, 32,112,104, 44, 32,112, +108, 41, 44, 32, 34, 37, 46, 34, 44, 32, 34, 44, 34, 41, 10, 32, 32, 32, 32,115, +101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, + 97,110,100, 40, 34,112,111,114,116, 34, 44, 32, 97,114,103, 41, 41, 10, 32, 32, + 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99, +104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, +109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,115,101,110,100, 40,115, +101,110,100,116, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115, +101,108,102, 46,112, 97,115,118,116, 32,111,114, 32,115,101,108,102, 46,115,101, +114,118,101,114, 44, 32, 34,110,101,101,100, 32,112,111,114,116, 32,111,114, 32, +112, 97,115,118, 32,102,105,114,115,116, 34, 41, 10, 32, 32, 32, 32, 45, 45, 32, +105,102, 32,116,104,101,114,101, 32,105,115, 32, 97, 32,112, 97,115,118,116, 32, +116, 97, 98,108,101, 44, 32,119,101, 32, 97,108,114,101, 97,100,121, 32,115,101, +110,116, 32, 97, 32, 80, 65, 83, 86, 32, 99,111,109,109, 97,110,100, 10, 32, 32, + 32, 32, 45, 45, 32,119,101, 32,106,117,115,116, 32,103,101,116, 32,116,104,101, + 32,100, 97,116, 97, 32, 99,111,110,110,101, 99,116,105,111,110, 32,105,110,116, +111, 32,115,101,108,102, 46,100, 97,116, 97, 10, 32, 32, 32, 32,105,102, 32,115, +101,108,102, 46,112, 97,115,118,116, 32,116,104,101,110, 32,115,101,108,102, 58, +112, 97,115,118, 99,111,110,110,101, 99,116, 40, 41, 32,101,110,100, 10, 32, 32, + 32, 32, 45, 45, 32,103,101,116, 32,116,104,101, 32,116,114, 97,110,115,102,101, +114, 32, 97,114,103,117,109,101,110,116, 32, 97,110,100, 32, 99,111,109,109, 97, +110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,114,103,117,109,101,110, +116, 32, 61, 32,115,101,110,100,116, 46, 97,114,103,117,109,101,110,116, 32,111, +114, 10, 32, 32, 32, 32, 32, 32, 32, 32,117,114,108, 46,117,110,101,115, 99, 97, +112,101, 40,115,116,114,105,110,103, 46,103,115,117, 98, 40,115,101,110,100,116, + 46,112, 97,116,104, 32,111,114, 32, 34, 34, 44, 32, 34, 94, 91, 47, 92, 92, 93, + 34, 44, 32, 34, 34, 41, 41, 10, 32, 32, 32, 32,105,102, 32, 97,114,103,117,109, +101,110,116, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32, 97,114,103,117,109, +101,110,116, 32, 61, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32, 99,111,109,109, 97,110,100, 32, 61, 32,115,101,110,100,116, 46, + 99,111,109,109, 97,110,100, 32,111,114, 32, 34,115,116,111,114, 34, 10, 32, 32, + 32, 32, 45, 45, 32,115,101,110,100, 32,116,104,101, 32,116,114, 97,110,115,102, +101,114, 32, 99,111,109,109, 97,110,100, 32, 97,110,100, 32, 99,104,101, 99,107, + 32,116,104,101, 32,114,101,112,108,121, 10, 32, 32, 32, 32,115,101,108,102, 46, +116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, + 99,111,109,109, 97,110,100, 44, 32, 97,114,103,117,109,101,110,116, 41, 41, 10, + 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,114,101,112,108, +121, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, + 58, 99,104,101, 99,107,123, 34, 50, 46, 46, 34, 44, 32, 34, 49, 46, 46, 34,125, + 41, 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,116,104,101,114,101, 32,105,115, + 32,110,111,116, 32, 97, 32, 97, 32,112, 97,115,118,116, 32,116, 97, 98,108,101, + 44, 32,116,104,101,110, 32,116,104,101,114,101, 32,105,115, 32, 97, 32,115,101, +114,118,101,114, 10, 32, 32, 32, 32, 45, 45, 32, 97,110,100, 32,119,101, 32, 97, +108,114,101, 97,100,121, 32,115,101,110,116, 32, 97, 32, 80, 79, 82, 84, 32, 99, +111,109,109, 97,110,100, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,101, +108,102, 46,112, 97,115,118,116, 32,116,104,101,110, 32,115,101,108,102, 58,112, +111,114,116, 99,111,110,110,101, 99,116, 40, 41, 32,101,110,100, 10, 32, 32, 32, + 32, 45, 45, 32,103,101,116, 32,116,104,101, 32,115,105,110,107, 44, 32,115,111, +117,114, 99,101, 32, 97,110,100, 32,115,116,101,112, 32,102,111,114, 32,116,104, +101, 32,116,114, 97,110,115,102,101,114, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32,115,116,101,112, 32, 61, 32,115,101,110,100,116, 46,115,116,101,112, 32,111, +114, 32,108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,114,101, 97,100,116, 32, 61, 32,123,115,101,108, +102, 46,116,112, 46, 99,125, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104, +101, 99,107,115,116,101,112, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115, +114, 99, 44, 32,115,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32, + 99,104,101, 99,107, 32,115,116, 97,116,117,115, 32,105,110, 32, 99,111,110,116, +114,111,108, 32, 99,111,110,110,101, 99,116,105,111,110, 32,119,104,105,108,101, + 32,100,111,119,110,108,111, 97,100,105,110,103, 10, 32, 32, 32, 32, 32, 32, 32, + 32,108,111, 99, 97,108, 32,114,101, 97,100,121,116, 32, 61, 32,115,111, 99,107, +101,116, 46,115,101,108,101, 99,116, 40,114,101, 97,100,116, 44, 32,110,105,108, + 44, 32, 48, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,114,101, 97,100, +121,116, 91,116,112, 93, 32,116,104,101,110, 32, 99,111,100,101, 32, 61, 32,115, +101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99, +107, 40, 34, 50, 46, 46, 34, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32,115,116,101,112, 40,115,114, 99, 44, 32,115, +110,107, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97, +108, 32,115,105,110,107, 32, 61, 32,115,111, 99,107,101,116, 46,115,105,110,107, + 40, 34, 99,108,111,115,101, 45,119,104,101,110, 45,100,111,110,101, 34, 44, 32, +115,101,108,102, 46,100, 97,116, 97, 41, 10, 32, 32, 32, 32, 45, 45, 32,116,114, + 97,110,115,102,101,114, 32, 97,108,108, 32,100, 97,116, 97, 32, 97,110,100, 32, + 99,104,101, 99,107, 32,101,114,114,111,114, 10, 32, 32, 32, 32,115,101,108,102, + 46,116,114,121, 40,108,116,110, 49, 50, 46,112,117,109,112, 46, 97,108,108, 40, +115,101,110,100,116, 46,115,111,117,114, 99,101, 44, 32,115,105,110,107, 44, 32, + 99,104,101, 99,107,115,116,101,112, 41, 41, 10, 32, 32, 32, 32,105,102, 32,115, +116,114,105,110,103, 46,102,105,110,100, 40, 99,111,100,101, 44, 32, 34, 49, 46, + 46, 34, 41, 32,116,104,101,110, 32,115,101,108,102, 46,116,114,121, 40,115,101, +108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 32, +101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,100,111,110,101, 32,119,105,116,104, + 32,100, 97,116, 97, 32, 99,111,110,110,101, 99,116,105,111,110, 10, 32, 32, 32, + 32,115,101,108,102, 46,100, 97,116, 97, 58, 99,108,111,115,101, 40, 41, 10, 32, + 32, 32, 32, 45, 45, 32,102,105,110,100, 32,111,117,116, 32,104,111,119, 32,109, + 97,110,121, 32, 98,121,116,101,115, 32,119,101,114,101, 32,115,101,110,116, 10, + 32, 32, 32, 32,108,111, 99, 97,108, 32,115,101,110,116, 32, 61, 32,115,111, 99, +107,101,116, 46,115,107,105,112, 40, 49, 44, 32,115,101,108,102, 46,100, 97,116, + 97, 58,103,101,116,115,116, 97,116,115, 40, 41, 41, 10, 32, 32, 32, 32,115,101, +108,102, 46,100, 97,116, 97, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,115,101,110,116, 10,101,110,100, 10, 10,102,117,110, 99,116, +105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, + 99,101,105,118,101, 40,114,101, 99,118,116, 41, 10, 32, 32, 32, 32,115,101,108, +102, 46,116,114,121, 40,115,101,108,102, 46,112, 97,115,118,116, 32,111,114, 32, +115,101,108,102, 46,115,101,114,118,101,114, 44, 32, 34,110,101,101,100, 32,112, +111,114,116, 32,111,114, 32,112, 97,115,118, 32,102,105,114,115,116, 34, 41, 10, + 32, 32, 32, 32,105,102, 32,115,101,108,102, 46,112, 97,115,118,116, 32,116,104, +101,110, 32,115,101,108,102, 58,112, 97,115,118, 99,111,110,110,101, 99,116, 40, + 41, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,114,103,117, +109,101,110,116, 32, 61, 32,114,101, 99,118,116, 46, 97,114,103,117,109,101,110, +116, 32,111,114, 10, 32, 32, 32, 32, 32, 32, 32, 32,117,114,108, 46,117,110,101, +115, 99, 97,112,101, 40,115,116,114,105,110,103, 46,103,115,117, 98, 40,114,101, + 99,118,116, 46,112, 97,116,104, 32,111,114, 32, 34, 34, 44, 32, 34, 94, 91, 47, + 92, 92, 93, 34, 44, 32, 34, 34, 41, 41, 10, 32, 32, 32, 32,105,102, 32, 97,114, +103,117,109,101,110,116, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32, 97,114, +103,117,109,101,110,116, 32, 61, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, + 32,108,111, 99, 97,108, 32, 99,111,109,109, 97,110,100, 32, 61, 32,114,101, 99, +118,116, 46, 99,111,109,109, 97,110,100, 32,111,114, 32, 34,114,101,116,114, 34, + 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116, +112, 58, 99,111,109,109, 97,110,100, 40, 99,111,109,109, 97,110,100, 44, 32, 97, +114,103,117,109,101,110,116, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, + 99,111,100,101, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, + 46,116,112, 58, 99,104,101, 99,107,123, 34, 49, 46, 46, 34, 44, 32, 34, 50, 46, + 46, 34,125, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,101,108,102, + 46,112, 97,115,118,116, 32,116,104,101,110, 32,115,101,108,102, 58,112,111,114, +116, 99,111,110,110,101, 99,116, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,115,111,117,114, 99,101, 32, 61, 32,115,111, 99,107,101,116, + 46,115,111,117,114, 99,101, 40, 34,117,110,116,105,108, 45, 99,108,111,115,101, +100, 34, 44, 32,115,101,108,102, 46,100, 97,116, 97, 41, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,115,116,101,112, 32, 61, 32,114,101, 99,118,116, 46,115,116, +101,112, 32,111,114, 32,108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101, +112, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,108,116,110, 49, 50, + 46,112,117,109,112, 46, 97,108,108, 40,115,111,117,114, 99,101, 44, 32,114,101, + 99,118,116, 46,115,105,110,107, 44, 32,115,116,101,112, 41, 41, 10, 32, 32, 32, + 32,105,102, 32,115,116,114,105,110,103, 46,102,105,110,100, 40, 99,111,100,101, + 44, 32, 34, 49, 46, 46, 34, 41, 32,116,104,101,110, 32,115,101,108,102, 46,116, +114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, + 46, 34, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32,115,101,108,102, 46,100, 97, +116, 97, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46, +100, 97,116, 97, 32, 61, 32,110,105,108, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, +116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,119,100, 40,100,105,114, 41, + 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116, +112, 58, 99,111,109,109, 97,110,100, 40, 34, 99,119,100, 34, 44, 32,100,105,114, + 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, + 46,116,112, 58, 99,104,101, 99,107, 40, 50, 53, 48, 41, 41, 10, 32, 32, 32, 32, +114,101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10,102,117,110, 99,116,105, +111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,116,121,112, +101, 40,116,121,112,101, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, + 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,116,121, +112,101, 34, 44, 32,116,121,112,101, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, + 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 50, + 48, 48, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110, +100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95, +105,110,100,101,120, 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32, 99,111,100,101, 32, 61, 32,115,101,108,102, 46,116,114,121, 40, +115,101,108,102, 46,116,112, 58, 99,104,101, 99,107,123, 34, 49, 46, 46, 34, 44, + 32, 34, 50, 46, 46, 34,125, 41, 10, 32, 32, 32, 32,105,102, 32,115,116,114,105, +110,103, 46,102,105,110,100, 40, 99,111,100,101, 44, 32, 34, 49, 46, 46, 34, 41, + 32,116,104,101,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, +116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 32,101,110,100, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10,102, +117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101, +120, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114, +121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34,113, +117,105,116, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40, +115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, + 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, 10, 10, +102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100, +101,120, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,105,102, 32,115,101, +108,102, 46,100, 97,116, 97, 32,116,104,101,110, 32,115,101,108,102, 46,100, 97, +116, 97, 58, 99,108,111,115,101, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,105, +102, 32,115,101,108,102, 46,115,101,114,118,101,114, 32,116,104,101,110, 32,115, +101,108,102, 46,115,101,114,118,101,114, 58, 99,108,111,115,101, 40, 41, 32,101, +110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116, +112, 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 72,105,103,104, + 32,108,101,118,101,108, 32, 70, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,102, +117,110, 99,116,105,111,110, 32,111,118,101,114,114,105,100,101, 40,116, 41, 10, + 32, 32, 32, 32,105,102, 32,116, 46,117,114,108, 32,116,104,101,110, 10, 32, 32, + 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,117, 32, 61, 32,117,114,108, 46, +112, 97,114,115,101, 40,116, 46,117,114,108, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115,101, 46,112, 97,105, +114,115, 40,116, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,117, 91,105, 93, 32, 61, 32,118, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110, +100, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,117, 10, 32, + 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,116, 32,101,110,100, + 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, + 32,116,112,117,116, 40,112,117,116,116, 41, 10, 32, 32, 32, 32,112,117,116,116, + 32, 61, 32,111,118,101,114,114,105,100,101, 40,112,117,116,116, 41, 10, 32, 32, + 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40,112,117,116,116, 46,104,111, +115,116, 44, 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97,109, +101, 34, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,111,112, +101,110, 40,112,117,116,116, 46,104,111,115,116, 44, 32,112,117,116,116, 46,112, +111,114,116, 44, 32,112,117,116,116, 46, 99,114,101, 97,116,101, 41, 10, 32, 32, + 32, 32,102, 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,102, 58,108,111, +103,105,110, 40,112,117,116,116, 46,117,115,101,114, 44, 32,112,117,116,116, 46, +112, 97,115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,105,102, 32,112,117,116, +116, 46,116,121,112,101, 32,116,104,101,110, 32,102, 58,116,121,112,101, 40,112, +117,116,116, 46,116,121,112,101, 41, 32,101,110,100, 10, 32, 32, 32, 32,102, 58, +112, 97,115,118, 40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,101,110, +116, 32, 61, 32,102, 58,115,101,110,100, 40,112,117,116,116, 41, 10, 32, 32, 32, + 32,102, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,102, 58, 99,108,111,115, +101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,110,116, 10, +101,110,100, 10, 10,108,111, 99, 97,108, 32,100,101,102, 97,117,108,116, 32, 61, + 32,123, 10, 9,112, 97,116,104, 32, 61, 32, 34, 47, 34, 44, 10, 9,115, 99,104, +101,109,101, 32, 61, 32, 34,102,116,112, 34, 10,125, 10, 10,108,111, 99, 97,108, + 32,102,117,110, 99,116,105,111,110, 32,112, 97,114,115,101, 40,117, 41, 10, 32, + 32, 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,115,111, 99,107,101,116, 46, +116,114,121, 40,117,114,108, 46,112, 97,114,115,101, 40,117, 44, 32,100,101,102, + 97,117,108,116, 41, 41, 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114, +121, 40,116, 46,115, 99,104,101,109,101, 32, 61, 61, 32, 34,102,116,112, 34, 44, + 32, 34,119,114,111,110,103, 32,115, 99,104,101,109,101, 32, 39, 34, 32, 46, 46, + 32,116, 46,115, 99,104,101,109,101, 32, 46, 46, 32, 34, 39, 34, 41, 10, 32, 32, + 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40,116, 46,104,111,115,116, 44, + 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97,109,101, 34, 41, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112, 97,116, 32, 61, 32, 34, 94,116, +121,112,101, 61, 40, 46, 41, 36, 34, 10, 32, 32, 32, 32,105,102, 32,116, 46,112, + 97,114, 97,109,115, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,116, + 46,116,121,112,101, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, + 50, 44, 32,115,116,114,105,110,103, 46,102,105,110,100, 40,116, 46,112, 97,114, + 97,109,115, 44, 32,112, 97,116, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115, +111, 99,107,101,116, 46,116,114,121, 40,116, 46,116,121,112,101, 32, 61, 61, 32, + 34, 97, 34, 32,111,114, 32,116, 46,116,121,112,101, 32, 61, 61, 32, 34,105, 34, + 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 34,105,110,118, 97,108, +105,100, 32,116,121,112,101, 32, 39, 34, 32, 46, 46, 32,116, 46,116,121,112,101, + 32, 46, 46, 32, 34, 39, 34, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, + 32,114,101,116,117,114,110, 32,116, 10,101,110,100, 10, 10,108,111, 99, 97,108, + 32,102,117,110, 99,116,105,111,110, 32,115,112,117,116, 40,117, 44, 32, 98,111, +100,121, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112,117,116,116, 32, 61, + 32,112, 97,114,115,101, 40,117, 41, 10, 32, 32, 32, 32,112,117,116,116, 46,115, +111,117,114, 99,101, 32, 61, 32,108,116,110, 49, 50, 46,115,111,117,114, 99,101, + 46,115,116,114,105,110,103, 40, 98,111,100,121, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,116,112,117,116, 40,112,117,116,116, 41, 10,101,110,100, 10, + 10,112,117,116, 32, 61, 32,115,111, 99,107,101,116, 46,112,114,111,116,101, 99, +116, 40,102,117,110, 99,116,105,111,110, 40,112,117,116,116, 44, 32, 98,111,100, +121, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40, +112,117,116,116, 41, 32, 61, 61, 32, 34,115,116,114,105,110,103, 34, 32,116,104, +101,110, 32,114,101,116,117,114,110, 32,115,112,117,116, 40,112,117,116,116, 44, + 32, 98,111,100,121, 41, 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117, +114,110, 32,116,112,117,116, 40,112,117,116,116, 41, 32,101,110,100, 10,101,110, +100, 41, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,116, +103,101,116, 40,103,101,116,116, 41, 10, 32, 32, 32, 32,103,101,116,116, 32, 61, + 32,111,118,101,114,114,105,100,101, 40,103,101,116,116, 41, 10, 32, 32, 32, 32, +115,111, 99,107,101,116, 46,116,114,121, 40,103,101,116,116, 46,104,111,115,116, + 44, 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97,109,101, 34, + 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,111,112,101,110, + 40,103,101,116,116, 46,104,111,115,116, 44, 32,103,101,116,116, 46,112,111,114, +116, 44, 32,103,101,116,116, 46, 99,114,101, 97,116,101, 41, 10, 32, 32, 32, 32, +102, 58,103,114,101,101,116, 40, 41, 10, 32, 32, 32, 32,102, 58,108,111,103,105, +110, 40,103,101,116,116, 46,117,115,101,114, 44, 32,103,101,116,116, 46,112, 97, +115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,105,102, 32,103,101,116,116, 46, +116,121,112,101, 32,116,104,101,110, 32,102, 58,116,121,112,101, 40,103,101,116, +116, 46,116,121,112,101, 41, 32,101,110,100, 10, 32, 32, 32, 32,102, 58,112, 97, +115,118, 40, 41, 10, 32, 32, 32, 32,102, 58,114,101, 99,101,105,118,101, 40,103, +101,116,116, 41, 10, 32, 32, 32, 32,102, 58,113,117,105,116, 40, 41, 10, 32, 32, + 32, 32,114,101,116,117,114,110, 32,102, 58, 99,108,111,115,101, 40, 41, 10,101, +110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115, +103,101,116, 40,117, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,103,101,116, +116, 32, 61, 32,112, 97,114,115,101, 40,117, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,116, 32, 61, 32,123,125, 10, 32, 32, 32, 32,103,101,116,116, 46,115, +105,110,107, 32, 61, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,116, 97, 98, +108,101, 40,116, 41, 10, 32, 32, 32, 32,116,103,101,116, 40,103,101,116,116, 41, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,116, 97, 98,108,101, 46, 99,111, +110, 99, 97,116, 40,116, 41, 10,101,110,100, 10, 10, 99,111,109,109, 97,110,100, + 32, 61, 32,115,111, 99,107,101,116, 46,112,114,111,116,101, 99,116, 40,102,117, +110, 99,116,105,111,110, 40, 99,109,100,116, 41, 10, 32, 32, 32, 32, 99,109,100, +116, 32, 61, 32,111,118,101,114,114,105,100,101, 40, 99,109,100,116, 41, 10, 32, + 32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40, 99,109,100,116, 46,104, +111,115,116, 44, 32, 34,109,105,115,115,105,110,103, 32,104,111,115,116,110, 97, +109,101, 34, 41, 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40, + 99,109,100,116, 46, 99,111,109,109, 97,110,100, 44, 32, 34,109,105,115,115,105, +110,103, 32, 99,111,109,109, 97,110,100, 34, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,102, 32, 61, 32,111,112,101,110, 40, 99,109,100,116, 46,104,111,115, +116, 44, 32, 99,109,100,116, 46,112,111,114,116, 44, 32, 99,109,100,116, 46, 99, +114,101, 97,116,101, 41, 10, 32, 32, 32, 32,102, 58,103,114,101,101,116, 40, 41, + 10, 32, 32, 32, 32,102, 58,108,111,103,105,110, 40, 99,109,100,116, 46,117,115, +101,114, 44, 32, 99,109,100,116, 46,112, 97,115,115,119,111,114,100, 41, 10, 32, + 32, 32, 32,102, 46,116,114,121, 40,102, 46,116,112, 58, 99,111,109,109, 97,110, +100, 40, 99,109,100,116, 46, 99,111,109,109, 97,110,100, 44, 32, 99,109,100,116, + 46, 97,114,103,117,109,101,110,116, 41, 41, 10, 32, 32, 32, 32,105,102, 32, 99, +109,100,116, 46, 99,104,101, 99,107, 32,116,104,101,110, 32,102, 46,116,114,121, + 40,102, 46,116,112, 58, 99,104,101, 99,107, 40, 99,109,100,116, 46, 99,104,101, + 99,107, 41, 41, 32,101,110,100, 10, 32, 32, 32, 32,102, 58,113,117,105,116, 40, + 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102, 58, 99,108,111,115,101, + 40, 41, 10,101,110,100, 41, 10, 10,103,101,116, 32, 61, 32,115,111, 99,107,101, +116, 46,112,114,111,116,101, 99,116, 40,102,117,110, 99,116,105,111,110, 40,103, +101,116,116, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112, +101, 40,103,101,116,116, 41, 32, 61, 61, 32, 34,115,116,114,105,110,103, 34, 32, +116,104,101,110, 32,114,101,116,117,114,110, 32,115,103,101,116, 40,103,101,116, +116, 41, 10, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,116, +103,101,116, 40,103,101,116,116, 41, 32,101,110,100, 10,101,110,100, 41, 10, 10, + + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/src/libs/luasocket/src/http.lua b/src/libs/luasocket/src/http.lua new file mode 100644 index 000000000..ad8db1ee0 --- /dev/null +++ b/src/libs/luasocket/src/http.lua @@ -0,0 +1,350 @@ +----------------------------------------------------------------------------- +-- HTTP/1.1 client support for the Lua language. +-- LuaSocket toolkit. +-- Author: Diego Nehab +-- RCS ID: $Id: http.lua,v 1.71 2007/10/13 23:55:20 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +------------------------------------------------------------------------------- +local socket = require("socket") +local url = require("socket.url") +local ltn12 = require("ltn12") +local mime = require("mime") +local string = require("string") +local base = _G +local table = require("table") +module("socket.http") + +----------------------------------------------------------------------------- +-- Program constants +----------------------------------------------------------------------------- +-- connection timeout in seconds +TIMEOUT = 60 +-- default port for document retrieval +PORT = 80 +-- user agent field sent in request +USERAGENT = socket._VERSION + +----------------------------------------------------------------------------- +-- Reads MIME headers from a connection, unfolding where needed +----------------------------------------------------------------------------- +local function receiveheaders(sock, headers) + local line, name, value, err + headers = headers or {} + -- get first line + line, err = sock:receive() + if err then return nil, err end + -- headers go until a blank line is found + while line ~= "" do + -- get field-name and value + name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)")) + if not (name and value) then return nil, "malformed reponse headers" end + name = string.lower(name) + -- get next line (value might be folded) + line, err = sock:receive() + if err then return nil, err end + -- unfold any folded values + while string.find(line, "^%s") do + value = value .. line + line = sock:receive() + if err then return nil, err end + end + -- save pair in table + if headers[name] then headers[name] = headers[name] .. ", " .. value + else headers[name] = value end + end + return headers +end + +----------------------------------------------------------------------------- +-- Extra sources and sinks +----------------------------------------------------------------------------- +socket.sourcet["http-chunked"] = function(sock, headers) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function() + -- get chunk size, skip extention + local line, err = sock:receive() + if err then return nil, err end + local size = base.tonumber(string.gsub(line, ";.*", ""), 16) + if not size then return nil, "invalid chunk size" end + -- was it the last chunk? + if size > 0 then + -- if not, get chunk and skip terminating CRLF + local chunk, err, part = sock:receive(size) + if chunk then sock:receive() end + return chunk, err + else + -- if it was, read trailers into headers table + headers, err = receiveheaders(sock, headers) + if not headers then return nil, err end + end + end + }) +end + +socket.sinkt["http-chunked"] = function(sock) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function(self, chunk, err) + if not chunk then return sock:send("0\r\n\r\n") end + local size = string.format("%X\r\n", string.len(chunk)) + return sock:send(size .. chunk .. "\r\n") + end + }) +end + +----------------------------------------------------------------------------- +-- Low level HTTP API +----------------------------------------------------------------------------- +local metat = { __index = {} } + +function open(host, port, create) + -- create socket with user connect function, or with default + local c = socket.try((create or socket.tcp)()) + local h = base.setmetatable({ c = c }, metat) + -- create finalized try + h.try = socket.newtry(function() h:close() end) + -- set timeout before connecting + h.try(c:settimeout(TIMEOUT)) + h.try(c:connect(host, port or PORT)) + -- here everything worked + return h +end + +function metat.__index:sendrequestline(method, uri) + local reqline = string.format("%s %s HTTP/1.1\r\n", method or "GET", uri) + return self.try(self.c:send(reqline)) +end + +function metat.__index:sendheaders(headers) + local h = "\r\n" + for i, v in base.pairs(headers) do + h = i .. ": " .. v .. "\r\n" .. h + end + self.try(self.c:send(h)) + return 1 +end + +function metat.__index:sendbody(headers, source, step) + source = source or ltn12.source.empty() + step = step or ltn12.pump.step + -- if we don't know the size in advance, send chunked and hope for the best + local mode = "http-chunked" + if headers["content-length"] then mode = "keep-open" end + return self.try(ltn12.pump.all(source, socket.sink(mode, self.c), step)) +end + +function metat.__index:receivestatusline() + local status = self.try(self.c:receive(5)) + -- identify HTTP/0.9 responses, which do not contain a status line + -- this is just a heuristic, but is what the RFC recommends + if status ~= "HTTP/" then return nil, status end + -- otherwise proceed reading a status line + status = self.try(self.c:receive("*l", status)) + local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)")) + return self.try(base.tonumber(code), status) +end + +function metat.__index:receiveheaders() + return self.try(receiveheaders(self.c)) +end + +function metat.__index:receivebody(headers, sink, step) + sink = sink or ltn12.sink.null() + step = step or ltn12.pump.step + local length = base.tonumber(headers["content-length"]) + local t = headers["transfer-encoding"] -- shortcut + local mode = "default" -- connection close + if t and t ~= "identity" then mode = "http-chunked" + elseif base.tonumber(headers["content-length"]) then mode = "by-length" end + return self.try(ltn12.pump.all(socket.source(mode, self.c, length), + sink, step)) +end + +function metat.__index:receive09body(status, sink, step) + local source = ltn12.source.rewind(socket.source("until-closed", self.c)) + source(status) + return self.try(ltn12.pump.all(source, sink, step)) +end + +function metat.__index:close() + return self.c:close() +end + +----------------------------------------------------------------------------- +-- High level HTTP API +----------------------------------------------------------------------------- +local function adjusturi(reqt) + local u = reqt + -- if there is a proxy, we need the full url. otherwise, just a part. + if not reqt.proxy and not PROXY then + u = { + path = socket.try(reqt.path, "invalid path 'nil'"), + params = reqt.params, + query = reqt.query, + fragment = reqt.fragment + } + end + return url.build(u) +end + +local function adjustproxy(reqt) + local proxy = reqt.proxy or PROXY + if proxy then + proxy = url.parse(proxy) + return proxy.host, proxy.port or 3128 + else + return reqt.host, reqt.port + end +end + +local function adjustheaders(reqt) + -- default headers + local lower = { + ["user-agent"] = USERAGENT, + ["host"] = reqt.host, + ["connection"] = "close, TE", + ["te"] = "trailers" + } + -- if we have authentication information, pass it along + if reqt.user and reqt.password then + lower["authorization"] = + "Basic " .. (mime.b64(reqt.user .. ":" .. reqt.password)) + end + -- override with user headers + for i,v in base.pairs(reqt.headers or lower) do + lower[string.lower(i)] = v + end + return lower +end + +-- default url parts +local default = { + host = "", + port = PORT, + path ="/", + scheme = "http" +} + +local function adjustrequest(reqt) + -- parse url if provided + local nreqt = reqt.url and url.parse(reqt.url, default) or {} + -- explicit components override url + for i,v in base.pairs(reqt) do nreqt[i] = v end + if nreqt.port == "" then nreqt.port = 80 end + socket.try(nreqt.host and nreqt.host ~= "", + "invalid host '" .. base.tostring(nreqt.host) .. "'") + -- compute uri if user hasn't overriden + nreqt.uri = reqt.uri or adjusturi(nreqt) + -- ajust host and port if there is a proxy + nreqt.host, nreqt.port = adjustproxy(nreqt) + -- adjust headers in request + nreqt.headers = adjustheaders(nreqt) + return nreqt +end + +local function shouldredirect(reqt, code, headers) + return headers.location and + string.gsub(headers.location, "%s", "") ~= "" and + (reqt.redirect ~= false) and + (code == 301 or code == 302) and + (not reqt.method or reqt.method == "GET" or reqt.method == "HEAD") + and (not reqt.nredirects or reqt.nredirects < 5) +end + +local function shouldreceivebody(reqt, code) + if reqt.method == "HEAD" then return nil end + if code == 204 or code == 304 then return nil end + if code >= 100 and code < 200 then return nil end + return 1 +end + +-- forward declarations +local trequest, tredirect + +function tredirect(reqt, location) + local result, code, headers, status = trequest { + -- the RFC says the redirect URL has to be absolute, but some + -- servers do not respect that + url = url.absolute(reqt.url, location), + source = reqt.source, + sink = reqt.sink, + headers = reqt.headers, + proxy = reqt.proxy, + nredirects = (reqt.nredirects or 0) + 1, + create = reqt.create + } + -- pass location header back as a hint we redirected + headers = headers or {} + headers.location = headers.location or location + return result, code, headers, status +end + +function trequest(reqt) + -- we loop until we get what we want, or + -- until we are sure there is no way to get it + local nreqt = adjustrequest(reqt) + local h = open(nreqt.host, nreqt.port, nreqt.create) + -- send request line and headers + h:sendrequestline(nreqt.method, nreqt.uri) + h:sendheaders(nreqt.headers) + -- if there is a body, send it + if nreqt.source then + h:sendbody(nreqt.headers, nreqt.source, nreqt.step) + end + local code, status = h:receivestatusline() + -- if it is an HTTP/0.9 server, simply get the body and we are done + if not code then + h:receive09body(status, nreqt.sink, nreqt.step) + return 1, 200 + end + local headers + -- ignore any 100-continue messages + while code == 100 do + headers = h:receiveheaders() + code, status = h:receivestatusline() + end + headers = h:receiveheaders() + -- at this point we should have a honest reply from the server + -- we can't redirect if we already used the source, so we report the error + if shouldredirect(nreqt, code, headers) and not nreqt.source then + h:close() + return tredirect(reqt, headers.location) + end + -- here we are finally done + if shouldreceivebody(nreqt, code) then + h:receivebody(headers, nreqt.sink, nreqt.step) + end + h:close() + return 1, code, headers, status +end + +local function srequest(u, b) + local t = {} + local reqt = { + url = u, + sink = ltn12.sink.table(t) + } + if b then + reqt.source = ltn12.source.string(b) + reqt.headers = { + ["content-length"] = string.len(b), + ["content-type"] = "application/x-www-form-urlencoded" + } + reqt.method = "POST" + end + local code, headers, status = socket.skip(1, trequest(reqt)) + return table.concat(t), code, headers, status +end + +request = socket.protect(function(reqt, body) + if base.type(reqt) == "string" then return srequest(reqt, body) + else return trequest(reqt) end +end) diff --git a/src/libs/luasocket/src/http_lua.c b/src/libs/luasocket/src/http_lua.c new file mode 100644 index 000000000..fa2875037 --- /dev/null +++ b/src/libs/luasocket/src/http_lua.c @@ -0,0 +1,623 @@ +/* + * This file is auto-generated by "./lua2c http.lua http_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_http_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 72, 84, 84, 80, 47, 49, 46, 49, 32, 99,108,105,101,110,116, 32,115,117,112, +112,111,114,116, 32,102,111,114, 32,116,104,101, 32, 76,117, 97, 32,108, 97,110, +103,117, 97,103,101, 46, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32, +116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, + 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, + 68, 58, 32, 36, 73,100, 58, 32,104,116,116,112, 46,108,117, 97, 44,118, 32, 49, + 46, 55, 49, 32, 50, 48, 48, 55, 47, 49, 48, 47, 49, 51, 32, 50, 51, 58, 53, 53, + 58, 50, 48, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, + 97,114,101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114, +116, 32,100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, + 32,115,111, 99,107,101,116, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115, +111, 99,107,101,116, 34, 41, 10,108,111, 99, 97,108, 32,117,114,108, 32, 61, 32, +114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 46,117,114,108, 34, + 41, 10,108,111, 99, 97,108, 32,108,116,110, 49, 50, 32, 61, 32,114,101,113,117, +105,114,101, 40, 34,108,116,110, 49, 50, 34, 41, 10,108,111, 99, 97,108, 32,109, +105,109,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,109,105,109,101, 34, + 41, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114,101,113, +117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108,111, 99, 97,108, + 32, 98, 97,115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,116, 97, 98, +108,101, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,116, 97, 98,108,101, 34, + 41, 10,109,111,100,117,108,101, 40, 34,115,111, 99,107,101,116, 46,104,116,116, +112, 34, 41, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 10, 45, 45, 32, 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, 97, +110,116,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 10, 45, 45, 32, 99,111,110,110,101, 99,116,105,111,110, 32,116,105,109,101, +111,117,116, 32,105,110, 32,115,101, 99,111,110,100,115, 10, 84, 73, 77, 69, 79, + 85, 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,100,101,102, 97,117,108,116, 32,112, +111,114,116, 32,102,111,114, 32,100,111, 99,117,109,101,110,116, 32,114,101,116, +114,105,101,118, 97,108, 10, 80, 79, 82, 84, 32, 61, 32, 56, 48, 10, 45, 45, 32, +117,115,101,114, 32, 97,103,101,110,116, 32,102,105,101,108,100, 32,115,101,110, +116, 32,105,110, 32,114,101,113,117,101,115,116, 10, 85, 83, 69, 82, 65, 71, 69, + 78, 84, 32, 61, 32,115,111, 99,107,101,116, 46, 95, 86, 69, 82, 83, 73, 79, 78, + 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, + 45, 45, 32, 82,101, 97,100,115, 32, 77, 73, 77, 69, 32,104,101, 97,100,101,114, +115, 32,102,114,111,109, 32, 97, 32, 99,111,110,110,101, 99,116,105,111,110, 44, + 32,117,110,102,111,108,100,105,110,103, 32,119,104,101,114,101, 32,110,101,101, +100,101,100, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,114,101, 99, +101,105,118,101,104,101, 97,100,101,114,115, 40,115,111, 99,107, 44, 32,104,101, + 97,100,101,114,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,105,110, +101, 44, 32,110, 97,109,101, 44, 32,118, 97,108,117,101, 44, 32,101,114,114, 10, + 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,104,101, 97,100,101,114, +115, 32,111,114, 32,123,125, 10, 32, 32, 32, 32, 45, 45, 32,103,101,116, 32,102, +105,114,115,116, 32,108,105,110,101, 10, 32, 32, 32, 32,108,105,110,101, 44, 32, +101,114,114, 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, + 10, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116, +117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, + 32, 45, 45, 32,104,101, 97,100,101,114,115, 32,103,111, 32,117,110,116,105,108, + 32, 97, 32, 98,108, 97,110,107, 32,108,105,110,101, 32,105,115, 32,102,111,117, +110,100, 10, 32, 32, 32, 32,119,104,105,108,101, 32,108,105,110,101, 32,126, 61, + 32, 34, 34, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,103,101, +116, 32,102,105,101,108,100, 45,110, 97,109,101, 32, 97,110,100, 32,118, 97,108, +117,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,110, 97,109,101, 44, 32,118, 97,108, +117,101, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32, +115,116,114,105,110,103, 46,102,105,110,100, 40,108,105,110,101, 44, 32, 34, 94, + 40, 46, 45, 41, 58, 37,115, 42, 40, 46, 42, 41, 34, 41, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,105,102, 32,110,111,116, 32, 40,110, 97,109,101, 32, 97,110,100, + 32,118, 97,108,117,101, 41, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, +110,105,108, 44, 32, 34,109, 97,108,102,111,114,109,101,100, 32,114,101,112,111, +110,115,101, 32,104,101, 97,100,101,114,115, 34, 32,101,110,100, 10, 32, 32, 32, + 32, 32, 32, 32, 32,110, 97,109,101, 32, 61, 32,115,116,114,105,110,103, 46,108, +111,119,101,114, 40,110, 97,109,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, + 45, 32,103,101,116, 32,110,101,120,116, 32,108,105,110,101, 32, 40,118, 97,108, +117,101, 32,109,105,103,104,116, 32, 98,101, 32,102,111,108,100,101,100, 41, 10, + 32, 32, 32, 32, 32, 32, 32, 32,108,105,110,101, 44, 32,101,114,114, 32, 32, 61, + 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116,117, +114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 45, 45, 32,117,110,102,111,108,100, 32, 97,110,121, 32,102,111, +108,100,101,100, 32,118, 97,108,117,101,115, 10, 32, 32, 32, 32, 32, 32, 32, 32, +119,104,105,108,101, 32,115,116,114,105,110,103, 46,102,105,110,100, 40,108,105, +110,101, 44, 32, 34, 94, 37,115, 34, 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,118, 97,108,117,101, 32, 61, 32,118, 97,108,117,101, 32, + 46, 46, 32,108,105,110,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +108,105,110,101, 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, + 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114, +114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 45, 45, 32,115, 97,118,101, 32,112, 97,105,114, 32,105, +110, 32,116, 97, 98,108,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,104, +101, 97,100,101,114,115, 91,110, 97,109,101, 93, 32,116,104,101,110, 32,104,101, + 97,100,101,114,115, 91,110, 97,109,101, 93, 32, 61, 32,104,101, 97,100,101,114, +115, 91,110, 97,109,101, 93, 32, 46, 46, 32, 34, 44, 32, 34, 32, 46, 46, 32,118, + 97,108,117,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,104,101, + 97,100,101,114,115, 91,110, 97,109,101, 93, 32, 61, 32,118, 97,108,117,101, 32, +101,110,100, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,104,101, 97,100,101,114,115, 10,101,110,100, 10, 10, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 69,120,116, +114, 97, 32,115,111,117,114, 99,101,115, 32, 97,110,100, 32,115,105,110,107,115, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,115, +111, 99,107,101,116, 46,115,111,117,114, 99,101,116, 91, 34,104,116,116,112, 45, + 99,104,117,110,107,101,100, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, + 40,115,111, 99,107, 44, 32,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, +114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, + 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102,100, + 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, + 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, 32, + 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99,116, +105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100,105, +114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, 99, +116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, + 45, 32,103,101,116, 32, 99,104,117,110,107, 32,115,105,122,101, 44, 32,115,107, +105,112, 32,101,120,116,101,110,116,105,111,110, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,105,110,101, 44, 32,101,114,114, + 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101, +110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110, +100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, +115,105,122,101, 32, 61, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, + 40,115,116,114,105,110,103, 46,103,115,117, 98, 40,108,105,110,101, 44, 32, 34, + 59, 46, 42, 34, 44, 32, 34, 34, 41, 44, 32, 49, 54, 41, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,105,122,101, 32,116, +104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, 34,105,110,118, + 97,108,105,100, 32, 99,104,117,110,107, 32,115,105,122,101, 34, 32,101,110,100, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,119, 97,115, 32, +105,116, 32,116,104,101, 32,108, 97,115,116, 32, 99,104,117,110,107, 63, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,115,105,122,101, 32, 62, + 32, 48, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 45, 45, 32,105,102, 32,110,111,116, 44, 32,103,101,116, 32, 99, +104,117,110,107, 32, 97,110,100, 32,115,107,105,112, 32,116,101,114,109,105,110, + 97,116,105,110,103, 32, 67, 82, 76, 70, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32, +101,114,114, 44, 32,112, 97,114,116, 32, 61, 32,115,111, 99,107, 58,114,101, 99, +101,105,118,101, 40,115,105,122,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107, 32,116,104,101,110, + 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40, 41, 32,101,110,100, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117, +114,110, 32, 99,104,117,110,107, 44, 32,101,114,114, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,105,102, 32,105,116, 32,119, 97,115, 44, + 32,114,101, 97,100, 32,116,114, 97,105,108,101,114,115, 32,105,110,116,111, 32, +104,101, 97,100,101,114,115, 32,116, 97, 98,108,101, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,104,101, 97,100,101,114,115, 44, 32,101, +114,114, 32, 61, 32,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40, +115,111, 99,107, 44, 32,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,104,101, + 97,100,101,114,115, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105, +108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, + 32, 32, 32,125, 41, 10,101,110,100, 10, 10,115,111, 99,107,101,116, 46,115,105, +110,107,116, 91, 34,104,116,116,112, 45, 99,104,117,110,107,101,100, 34, 93, 32, + 61, 32,102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 41, 10, 32, 32, 32, + 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97, +116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102, +100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114, +110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, + 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99, +116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100, +105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, + 99,116,105,111,110, 40,115,101,108,102, 44, 32, 99,104,117,110,107, 44, 32,101, +114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110, +111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 32,114,101,116,117,114,110, + 32,115,111, 99,107, 58,115,101,110,100, 40, 34, 48, 92,114, 92,110, 92,114, 92, +110, 34, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +108,111, 99, 97,108, 32,115,105,122,101, 32, 61, 32,115,116,114,105,110,103, 46, +102,111,114,109, 97,116, 40, 34, 37, 88, 92,114, 92,110, 34, 44, 32,115,116,114, +105,110,103, 46,108,101,110, 40, 99,104,117,110,107, 41, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58, +115,101,110,100, 40,115,105,122,101, 32, 46, 46, 32, 32, 99,104,117,110,107, 32, + 46, 46, 32, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101, +110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 76,111,119, 32, +108,101,118,101,108, 32, 72, 84, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,109, +101,116, 97,116, 32, 61, 32,123, 32, 95, 95,105,110,100,101,120, 32, 61, 32,123, +125, 32,125, 10, 10,102,117,110, 99,116,105,111,110, 32,111,112,101,110, 40,104, +111,115,116, 44, 32,112,111,114,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, + 32, 32, 32, 45, 45, 32, 99,114,101, 97,116,101, 32,115,111, 99,107,101,116, 32, +119,105,116,104, 32,117,115,101,114, 32, 99,111,110,110,101, 99,116, 32,102,117, +110, 99,116,105,111,110, 44, 32,111,114, 32,119,105,116,104, 32,100,101,102, 97, +117,108,116, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99, 32, 61, 32,115,111, + 99,107,101,116, 46,116,114,121, 40, 40, 99,114,101, 97,116,101, 32,111,114, 32, +115,111, 99,107,101,116, 46,116, 99,112, 41, 40, 41, 41, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,104, 32, 61, 32, 98, 97,115,101, 46,115,101,116,109,101,116, + 97,116, 97, 98,108,101, 40,123, 32, 99, 32, 61, 32, 99, 32,125, 44, 32,109,101, +116, 97,116, 41, 10, 32, 32, 32, 32, 45, 45, 32, 99,114,101, 97,116,101, 32,102, +105,110, 97,108,105,122,101,100, 32,116,114,121, 10, 32, 32, 32, 32,104, 46,116, +114,121, 32, 61, 32,115,111, 99,107,101,116, 46,110,101,119,116,114,121, 40,102, +117,110, 99,116,105,111,110, 40, 41, 32,104, 58, 99,108,111,115,101, 40, 41, 32, +101,110,100, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101,116, 32,116,105,109,101, +111,117,116, 32, 98,101,102,111,114,101, 32, 99,111,110,110,101, 99,116,105,110, +103, 10, 32, 32, 32, 32,104, 46,116,114,121, 40, 99, 58,115,101,116,116,105,109, +101,111,117,116, 40, 84, 73, 77, 69, 79, 85, 84, 41, 41, 10, 32, 32, 32, 32,104, + 46,116,114,121, 40, 99, 58, 99,111,110,110,101, 99,116, 40,104,111,115,116, 44, + 32,112,111,114,116, 32,111,114, 32, 80, 79, 82, 84, 41, 41, 10, 32, 32, 32, 32, + 45, 45, 32,104,101,114,101, 32,101,118,101,114,121,116,104,105,110,103, 32,119, +111,114,107,101,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,104, 10,101, +110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, + 95,105,110,100,101,120, 58,115,101,110,100,114,101,113,117,101,115,116,108,105, +110,101, 40,109,101,116,104,111,100, 44, 32,117,114,105, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,114,101,113,108,105,110,101, 32, 61, 32,115,116,114,105, +110,103, 46,102,111,114,109, 97,116, 40, 34, 37,115, 32, 37,115, 32, 72, 84, 84, + 80, 47, 49, 46, 49, 92,114, 92,110, 34, 44, 32,109,101,116,104,111,100, 32,111, +114, 32, 34, 71, 69, 84, 34, 44, 32,117,114,105, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, 99, + 58,115,101,110,100, 40,114,101,113,108,105,110,101, 41, 41, 10,101,110,100, 10, + 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110, +100,101,120, 58,115,101,110,100,104,101, 97,100,101,114,115, 40,104,101, 97,100, +101,114,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104, 32, 61, 32, 34, + 92,114, 92,110, 34, 10, 32, 32, 32, 32,102,111,114, 32,105, 44, 32,118, 32,105, +110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,104,101, 97,100,101,114,115, + 41, 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 32, 61, 32,105, 32, 46, + 46, 32, 34, 58, 32, 34, 32, 46, 46, 32,118, 32, 46, 46, 32, 34, 92,114, 92,110, + 34, 32, 46, 46, 32,104, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,115, +101,108,102, 46,116,114,121, 40,115,101,108,102, 46, 99, 58,115,101,110,100, 40, +104, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, + 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105, +110,100,101,120, 58,115,101,110,100, 98,111,100,121, 40,104,101, 97,100,101,114, +115, 44, 32,115,111,117,114, 99,101, 44, 32,115,116,101,112, 41, 10, 32, 32, 32, + 32,115,111,117,114, 99,101, 32, 61, 32,115,111,117,114, 99,101, 32,111,114, 32, +108,116,110, 49, 50, 46,115,111,117,114, 99,101, 46,101,109,112,116,121, 40, 41, + 10, 32, 32, 32, 32,115,116,101,112, 32, 61, 32,115,116,101,112, 32,111,114, 32, +108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, 10, 32, 32, 32, 32, + 45, 45, 32,105,102, 32,119,101, 32,100,111,110, 39,116, 32,107,110,111,119, 32, +116,104,101, 32,115,105,122,101, 32,105,110, 32, 97,100,118, 97,110, 99,101, 44, + 32,115,101,110,100, 32, 99,104,117,110,107,101,100, 32, 97,110,100, 32,104,111, +112,101, 32,102,111,114, 32,116,104,101, 32, 98,101,115,116, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,109,111,100,101, 32, 61, 32, 34,104,116,116,112, 45, 99, +104,117,110,107,101,100, 34, 10, 32, 32, 32, 32,105,102, 32,104,101, 97,100,101, +114,115, 91, 34, 99,111,110,116,101,110,116, 45,108,101,110,103,116,104, 34, 93, + 32,116,104,101,110, 32,109,111,100,101, 32, 61, 32, 34,107,101,101,112, 45,111, +112,101,110, 34, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, +115,101,108,102, 46,116,114,121, 40,108,116,110, 49, 50, 46,112,117,109,112, 46, + 97,108,108, 40,115,111,117,114, 99,101, 44, 32,115,111, 99,107,101,116, 46,115, +105,110,107, 40,109,111,100,101, 44, 32,115,101,108,102, 46, 99, 41, 44, 32,115, +116,101,112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, +109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101,105,118, +101,115,116, 97,116,117,115,108,105,110,101, 40, 41, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,115,116, 97,116,117,115, 32, 61, 32,115,101,108,102, 46,116,114, +121, 40,115,101,108,102, 46, 99, 58,114,101, 99,101,105,118,101, 40, 53, 41, 41, + 10, 32, 32, 32, 32, 45, 45, 32,105,100,101,110,116,105,102,121, 32, 72, 84, 84, + 80, 47, 48, 46, 57, 32,114,101,115,112,111,110,115,101,115, 44, 32,119,104,105, + 99,104, 32,100,111, 32,110,111,116, 32, 99,111,110,116, 97,105,110, 32, 97, 32, +115,116, 97,116,117,115, 32,108,105,110,101, 10, 32, 32, 32, 32, 45, 45, 32,116, +104,105,115, 32,105,115, 32,106,117,115,116, 32, 97, 32,104,101,117,114,105,115, +116,105, 99, 44, 32, 98,117,116, 32,105,115, 32,119,104, 97,116, 32,116,104,101, + 32, 82, 70, 67, 32,114,101, 99,111,109,109,101,110,100,115, 10, 32, 32, 32, 32, +105,102, 32,115,116, 97,116,117,115, 32,126, 61, 32, 34, 72, 84, 84, 80, 47, 34, + 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,115,116, + 97,116,117,115, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,111,116,104,101, +114,119,105,115,101, 32,112,114,111, 99,101,101,100, 32,114,101, 97,100,105,110, +103, 32, 97, 32,115,116, 97,116,117,115, 32,108,105,110,101, 10, 32, 32, 32, 32, +115,116, 97,116,117,115, 32, 61, 32,115,101,108,102, 46,116,114,121, 40,115,101, +108,102, 46, 99, 58,114,101, 99,101,105,118,101, 40, 34, 42,108, 34, 44, 32,115, +116, 97,116,117,115, 41, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111, +100,101, 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32, +115,116,114,105,110,103, 46,102,105,110,100, 40,115,116, 97,116,117,115, 44, 32, + 34, 72, 84, 84, 80, 47, 37,100, 42, 37, 46, 37,100, 42, 32, 40, 37,100, 37,100, + 37,100, 41, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101, +108,102, 46,116,114,121, 40, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, + 40, 99,111,100,101, 41, 44, 32,115,116, 97,116,117,115, 41, 10,101,110,100, 10, + 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110, +100,101,120, 58,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40, 41, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116,114,121, + 40,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40,115,101,108,102, + 46, 99, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109, +101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101,105,118,101, + 98,111,100,121, 40,104,101, 97,100,101,114,115, 44, 32,115,105,110,107, 44, 32, +115,116,101,112, 41, 10, 32, 32, 32, 32,115,105,110,107, 32, 61, 32,115,105,110, +107, 32,111,114, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,110,117,108,108, + 40, 41, 10, 32, 32, 32, 32,115,116,101,112, 32, 61, 32,115,116,101,112, 32,111, +114, 32,108,116,110, 49, 50, 46,112,117,109,112, 46,115,116,101,112, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,108,101,110,103,116,104, 32, 61, 32, 98, 97,115, +101, 46,116,111,110,117,109, 98,101,114, 40,104,101, 97,100,101,114,115, 91, 34, + 99,111,110,116,101,110,116, 45,108,101,110,103,116,104, 34, 93, 41, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,104,101, 97,100,101,114,115, 91, + 34,116,114, 97,110,115,102,101,114, 45,101,110, 99,111,100,105,110,103, 34, 93, + 32, 45, 45, 32,115,104,111,114,116, 99,117,116, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,109,111,100,101, 32, 61, 32, 34,100,101,102, 97,117,108,116, 34, 32, + 45, 45, 32, 99,111,110,110,101, 99,116,105,111,110, 32, 99,108,111,115,101, 10, + 32, 32, 32, 32,105,102, 32,116, 32, 97,110,100, 32,116, 32,126, 61, 32, 34,105, +100,101,110,116,105,116,121, 34, 32,116,104,101,110, 32,109,111,100,101, 32, 61, + 32, 34,104,116,116,112, 45, 99,104,117,110,107,101,100, 34, 10, 32, 32, 32, 32, +101,108,115,101,105,102, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, + 40,104,101, 97,100,101,114,115, 91, 34, 99,111,110,116,101,110,116, 45,108,101, +110,103,116,104, 34, 93, 41, 32,116,104,101,110, 32,109,111,100,101, 32, 61, 32, + 34, 98,121, 45,108,101,110,103,116,104, 34, 32,101,110,100, 10, 32, 32, 32, 32, +114,101,116,117,114,110, 32,115,101,108,102, 46,116,114,121, 40,108,116,110, 49, + 50, 46,112,117,109,112, 46, 97,108,108, 40,115,111, 99,107,101,116, 46,115,111, +117,114, 99,101, 40,109,111,100,101, 44, 32,115,101,108,102, 46, 99, 44, 32,108, +101,110,103,116,104, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,105,110,107, + 44, 32,115,116,101,112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105, +111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99, +101,105,118,101, 48, 57, 98,111,100,121, 40,115,116, 97,116,117,115, 44, 32,115, +105,110,107, 44, 32,115,116,101,112, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32,115,111,117,114, 99,101, 32, 61, 32,108,116,110, 49, 50, 46,115,111,117,114, + 99,101, 46,114,101,119,105,110,100, 40,115,111, 99,107,101,116, 46,115,111,117, +114, 99,101, 40, 34,117,110,116,105,108, 45, 99,108,111,115,101,100, 34, 44, 32, +115,101,108,102, 46, 99, 41, 41, 10, 32, 32, 32, 32,115,111,117,114, 99,101, 40, +115,116, 97,116,117,115, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115, +101,108,102, 46,116,114,121, 40,108,116,110, 49, 50, 46,112,117,109,112, 46, 97, +108,108, 40,115,111,117,114, 99,101, 44, 32,115,105,110,107, 44, 32,115,116,101, +112, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, +116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,108,111,115,101, 40, 41, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 58, 99,108, +111,115,101, 40, 41, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 72,105,103,104, 32,108,101,118, +101,108, 32, 72, 84, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,102,117,110, 99, +116,105,111,110, 32, 97,100,106,117,115,116,117,114,105, 40,114,101,113,116, 41, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,117, 32, 61, 32,114,101,113,116, 10, + 32, 32, 32, 32, 45, 45, 32,105,102, 32,116,104,101,114,101, 32,105,115, 32, 97, + 32,112,114,111,120,121, 44, 32,119,101, 32,110,101,101,100, 32,116,104,101, 32, +102,117,108,108, 32,117,114,108, 46, 32,111,116,104,101,114,119,105,115,101, 44, + 32,106,117,115,116, 32, 97, 32,112, 97,114,116, 46, 10, 32, 32, 32, 32,105,102, + 32,110,111,116, 32,114,101,113,116, 46,112,114,111,120,121, 32, 97,110,100, 32, +110,111,116, 32, 80, 82, 79, 88, 89, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, + 32, 32, 32,117, 32, 61, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +112, 97,116,104, 32, 61, 32,115,111, 99,107,101,116, 46,116,114,121, 40,114,101, +113,116, 46,112, 97,116,104, 44, 32, 34,105,110,118, 97,108,105,100, 32,112, 97, +116,104, 32, 39,110,105,108, 39, 34, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,112, 97,114, 97,109,115, 32, 61, 32,114,101,113,116, 46,112, 97,114, + 97,109,115, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,113,117,101,114, +121, 32, 61, 32,114,101,113,116, 46,113,117,101,114,121, 44, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,102,114, 97,103,109,101,110,116, 32, 61, 32,114,101, +113,116, 46,102,114, 97,103,109,101,110,116, 10, 32, 32, 32, 32, 32, 32, 32, 32, +125, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, + 32,117,114,108, 46, 98,117,105,108,100, 40,117, 41, 10,101,110,100, 10, 10,108, +111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, 97,100,106,117,115,116, +112,114,111,120,121, 40,114,101,113,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97, +108, 32,112,114,111,120,121, 32, 61, 32,114,101,113,116, 46,112,114,111,120,121, + 32,111,114, 32, 80, 82, 79, 88, 89, 10, 32, 32, 32, 32,105,102, 32,112,114,111, +120,121, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,112,114,111,120, +121, 32, 61, 32,117,114,108, 46,112, 97,114,115,101, 40,112,114,111,120,121, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,112,114,111,120, +121, 46,104,111,115,116, 44, 32,112,114,111,120,121, 46,112,111,114,116, 32,111, +114, 32, 51, 49, 50, 56, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, + 32, 32, 32, 32,114,101,116,117,114,110, 32,114,101,113,116, 46,104,111,115,116, + 44, 32,114,101,113,116, 46,112,111,114,116, 10, 32, 32, 32, 32,101,110,100, 10, +101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, + 97,100,106,117,115,116,104,101, 97,100,101,114,115, 40,114,101,113,116, 41, 10, + 32, 32, 32, 32, 45, 45, 32,100,101,102, 97,117,108,116, 32,104,101, 97,100,101, +114,115, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,111,119,101,114, 32, 61, + 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34,117,115,101,114, 45, 97,103, +101,110,116, 34, 93, 32, 61, 32, 85, 83, 69, 82, 65, 71, 69, 78, 84, 44, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 91, 34,104,111,115,116, 34, 93, 32, 61, 32,114,101, +113,116, 46,104,111,115,116, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34, 99, +111,110,110,101, 99,116,105,111,110, 34, 93, 32, 61, 32, 34, 99,108,111,115,101, + 44, 32, 84, 69, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34,116,101, 34, + 93, 32, 61, 32, 34,116,114, 97,105,108,101,114,115, 34, 10, 32, 32, 32, 32,125, + 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,119,101, 32,104, 97,118,101, 32, 97, +117,116,104,101,110,116,105, 99, 97,116,105,111,110, 32,105,110,102,111,114,109, + 97,116,105,111,110, 44, 32,112, 97,115,115, 32,105,116, 32, 97,108,111,110,103, + 10, 32, 32, 32, 32,105,102, 32,114,101,113,116, 46,117,115,101,114, 32, 97,110, +100, 32,114,101,113,116, 46,112, 97,115,115,119,111,114,100, 32,116,104,101,110, + 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111,119,101,114, 91, 34, 97,117,116,104, +111,114,105,122, 97,116,105,111,110, 34, 93, 32, 61, 32, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 34, 66, 97,115,105, 99, 32, 34, 32, 46, 46, 32, 32, + 40,109,105,109,101, 46, 98, 54, 52, 40,114,101,113,116, 46,117,115,101,114, 32, + 46, 46, 32, 34, 58, 34, 32, 46, 46, 32,114,101,113,116, 46,112, 97,115,115,119, +111,114,100, 41, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, + 32,111,118,101,114,114,105,100,101, 32,119,105,116,104, 32,117,115,101,114, 32, +104,101, 97,100,101,114,115, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32, +105,110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,114,101,113,116, 46,104, +101, 97,100,101,114,115, 32,111,114, 32,108,111,119,101,114, 41, 32,100,111, 10, + 32, 32, 32, 32, 32, 32, 32, 32,108,111,119,101,114, 91,115,116,114,105,110,103, + 46,108,111,119,101,114, 40,105, 41, 93, 32, 61, 32,118, 10, 32, 32, 32, 32,101, +110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,111,119,101,114, 10, +101,110,100, 10, 10, 45, 45, 32,100,101,102, 97,117,108,116, 32,117,114,108, 32, +112, 97,114,116,115, 10,108,111, 99, 97,108, 32,100,101,102, 97,117,108,116, 32, + 61, 32,123, 10, 32, 32, 32, 32,104,111,115,116, 32, 61, 32, 34, 34, 44, 10, 32, + 32, 32, 32,112,111,114,116, 32, 61, 32, 80, 79, 82, 84, 44, 10, 32, 32, 32, 32, +112, 97,116,104, 32, 61, 34, 47, 34, 44, 10, 32, 32, 32, 32,115, 99,104,101,109, +101, 32, 61, 32, 34,104,116,116,112, 34, 10,125, 10, 10,108,111, 99, 97,108, 32, +102,117,110, 99,116,105,111,110, 32, 97,100,106,117,115,116,114,101,113,117,101, +115,116, 40,114,101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,112, 97,114,115, +101, 32,117,114,108, 32,105,102, 32,112,114,111,118,105,100,101,100, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,110,114,101,113,116, 32, 61, 32,114,101,113,116, + 46,117,114,108, 32, 97,110,100, 32,117,114,108, 46,112, 97,114,115,101, 40,114, +101,113,116, 46,117,114,108, 44, 32,100,101,102, 97,117,108,116, 41, 32,111,114, + 32,123,125, 10, 32, 32, 32, 32, 45, 45, 32,101,120,112,108,105, 99,105,116, 32, + 99,111,109,112,111,110,101,110,116,115, 32,111,118,101,114,114,105,100,101, 32, +117,114,108, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, + 97,115,101, 46,112, 97,105,114,115, 40,114,101,113,116, 41, 32,100,111, 32,110, +114,101,113,116, 91,105, 93, 32, 61, 32,118, 32,101,110,100, 10, 32, 32, 32, 32, +105,102, 32,110,114,101,113,116, 46,112,111,114,116, 32, 61, 61, 32, 34, 34, 32, +116,104,101,110, 32,110,114,101,113,116, 46,112,111,114,116, 32, 61, 32, 56, 48, + 32,101,110,100, 10, 32, 32, 32, 32,115,111, 99,107,101,116, 46,116,114,121, 40, +110,114,101,113,116, 46,104,111,115,116, 32, 97,110,100, 32,110,114,101,113,116, + 46,104,111,115,116, 32,126, 61, 32, 34, 34, 44, 32, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 34,105,110,118, 97,108,105,100, 32,104,111,115,116, 32, 39, 34, 32, 46, + 46, 32, 98, 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110,114,101,113, +116, 46,104,111,115,116, 41, 32, 46, 46, 32, 34, 39, 34, 41, 10, 32, 32, 32, 32, + 45, 45, 32, 99,111,109,112,117,116,101, 32,117,114,105, 32,105,102, 32,117,115, +101,114, 32,104, 97,115,110, 39,116, 32,111,118,101,114,114,105,100,101,110, 10, + 32, 32, 32, 32,110,114,101,113,116, 46,117,114,105, 32, 61, 32,114,101,113,116, + 46,117,114,105, 32,111,114, 32, 97,100,106,117,115,116,117,114,105, 40,110,114, +101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, 32, 97,106,117,115,116, 32,104,111, +115,116, 32, 97,110,100, 32,112,111,114,116, 32,105,102, 32,116,104,101,114,101, + 32,105,115, 32, 97, 32,112,114,111,120,121, 10, 32, 32, 32, 32,110,114,101,113, +116, 46,104,111,115,116, 44, 32,110,114,101,113,116, 46,112,111,114,116, 32, 61, + 32, 97,100,106,117,115,116,112,114,111,120,121, 40,110,114,101,113,116, 41, 10, + 32, 32, 32, 32, 45, 45, 32, 97,100,106,117,115,116, 32,104,101, 97,100,101,114, +115, 32,105,110, 32,114,101,113,117,101,115,116, 10, 32, 32, 32, 32,110,114,101, +113,116, 46,104,101, 97,100,101,114,115, 32, 61, 32, 97,100,106,117,115,116,104, +101, 97,100,101,114,115, 40,110,114,101,113,116, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,110,114,101,113,116, 10,101,110,100, 10, 10,108,111, 99, 97, +108, 32,102,117,110, 99,116,105,111,110, 32,115,104,111,117,108,100,114,101,100, +105,114,101, 99,116, 40,114,101,113,116, 44, 32, 99,111,100,101, 44, 32,104,101, + 97,100,101,114,115, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,104,101, + 97,100,101,114,115, 46,108,111, 99, 97,116,105,111,110, 32, 97,110,100, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,116,114,105,110,103, 46,103,115,117, + 98, 40,104,101, 97,100,101,114,115, 46,108,111, 99, 97,116,105,111,110, 44, 32, + 34, 37,115, 34, 44, 32, 34, 34, 41, 32,126, 61, 32, 34, 34, 32, 97,110,100, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40,114,101,113,116, 46,114,101,100, +105,114,101, 99,116, 32,126, 61, 32,102, 97,108,115,101, 41, 32, 97,110,100, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 99,111,100,101, 32, 61, 61, 32, + 51, 48, 49, 32,111,114, 32, 99,111,100,101, 32, 61, 61, 32, 51, 48, 50, 41, 32, + 97,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40,110,111,116, 32, +114,101,113,116, 46,109,101,116,104,111,100, 32,111,114, 32,114,101,113,116, 46, +109,101,116,104,111,100, 32, 61, 61, 32, 34, 71, 69, 84, 34, 32,111,114, 32,114, +101,113,116, 46,109,101,116,104,111,100, 32, 61, 61, 32, 34, 72, 69, 65, 68, 34, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 97,110,100, 32, 40,110,111, +116, 32,114,101,113,116, 46,110,114,101,100,105,114,101, 99,116,115, 32,111,114, + 32,114,101,113,116, 46,110,114,101,100,105,114,101, 99,116,115, 32, 60, 32, 53, + 41, 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111, +110, 32,115,104,111,117,108,100,114,101, 99,101,105,118,101, 98,111,100,121, 40, +114,101,113,116, 44, 32, 99,111,100,101, 41, 10, 32, 32, 32, 32,105,102, 32,114, +101,113,116, 46,109,101,116,104,111,100, 32, 61, 61, 32, 34, 72, 69, 65, 68, 34, + 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 32,101,110,100, + 10, 32, 32, 32, 32,105,102, 32, 99,111,100,101, 32, 61, 61, 32, 50, 48, 52, 32, +111,114, 32, 99,111,100,101, 32, 61, 61, 32, 51, 48, 52, 32,116,104,101,110, 32, +114,101,116,117,114,110, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32,105, +102, 32, 99,111,100,101, 32, 62, 61, 32, 49, 48, 48, 32, 97,110,100, 32, 99,111, +100,101, 32, 60, 32, 50, 48, 48, 32,116,104,101,110, 32,114,101,116,117,114,110, + 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, + 49, 10,101,110,100, 10, 10, 45, 45, 32,102,111,114,119, 97,114,100, 32,100,101, + 99,108, 97,114, 97,116,105,111,110,115, 10,108,111, 99, 97,108, 32,116,114,101, +113,117,101,115,116, 44, 32,116,114,101,100,105,114,101, 99,116, 10, 10,102,117, +110, 99,116,105,111,110, 32,116,114,101,100,105,114,101, 99,116, 40,114,101,113, +116, 44, 32,108,111, 99, 97,116,105,111,110, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,114,101,115,117,108,116, 44, 32, 99,111,100,101, 44, 32,104,101, 97, +100,101,114,115, 44, 32,115,116, 97,116,117,115, 32, 61, 32,116,114,101,113,117, +101,115,116, 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 32,116,104,101, + 32, 82, 70, 67, 32,115, 97,121,115, 32,116,104,101, 32,114,101,100,105,114,101, + 99,116, 32, 85, 82, 76, 32,104, 97,115, 32,116,111, 32, 98,101, 32, 97, 98,115, +111,108,117,116,101, 44, 32, 98,117,116, 32,115,111,109,101, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 45, 45, 32,115,101,114,118,101,114,115, 32,100,111, 32,110,111, +116, 32,114,101,115,112,101, 99,116, 32,116,104, 97,116, 10, 32, 32, 32, 32, 32, + 32, 32, 32,117,114,108, 32, 61, 32,117,114,108, 46, 97, 98,115,111,108,117,116, +101, 40,114,101,113,116, 46,117,114,108, 44, 32,108,111, 99, 97,116,105,111,110, + 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,111,117,114, 99,101, 32, 61, 32, +114,101,113,116, 46,115,111,117,114, 99,101, 44, 10, 32, 32, 32, 32, 32, 32, 32, + 32,115,105,110,107, 32, 61, 32,114,101,113,116, 46,115,105,110,107, 44, 10, 32, + 32, 32, 32, 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,114,101,113, +116, 46,104,101, 97,100,101,114,115, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, +114,111,120,121, 32, 61, 32,114,101,113,116, 46,112,114,111,120,121, 44, 32, 10, + 32, 32, 32, 32, 32, 32, 32, 32,110,114,101,100,105,114,101, 99,116,115, 32, 61, + 32, 40,114,101,113,116, 46,110,114,101,100,105,114,101, 99,116,115, 32,111,114, + 32, 48, 41, 32, 43, 32, 49, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,114,101, + 97,116,101, 32, 61, 32,114,101,113,116, 46, 99,114,101, 97,116,101, 10, 32, 32, + 32, 32,125, 32, 32, 32, 10, 32, 32, 32, 32, 45, 45, 32,112, 97,115,115, 32,108, +111, 99, 97,116,105,111,110, 32,104,101, 97,100,101,114, 32, 98, 97, 99,107, 32, + 97,115, 32, 97, 32,104,105,110,116, 32,119,101, 32,114,101,100,105,114,101, 99, +116,101,100, 10, 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,104,101, + 97,100,101,114,115, 32,111,114, 32,123,125, 10, 32, 32, 32, 32,104,101, 97,100, +101,114,115, 46,108,111, 99, 97,116,105,111,110, 32, 61, 32,104,101, 97,100,101, +114,115, 46,108,111, 99, 97,116,105,111,110, 32,111,114, 32,108,111, 99, 97,116, +105,111,110, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,114,101,115,117,108, +116, 44, 32, 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 44, 32,115,116, + 97,116,117,115, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,116, +114,101,113,117,101,115,116, 40,114,101,113,116, 41, 10, 32, 32, 32, 32, 45, 45, + 32,119,101, 32,108,111,111,112, 32,117,110,116,105,108, 32,119,101, 32,103,101, +116, 32,119,104, 97,116, 32,119,101, 32,119, 97,110,116, 44, 32,111,114, 10, 32, + 32, 32, 32, 45, 45, 32,117,110,116,105,108, 32,119,101, 32, 97,114,101, 32,115, +117,114,101, 32,116,104,101,114,101, 32,105,115, 32,110,111, 32,119, 97,121, 32, +116,111, 32,103,101,116, 32,105,116, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, +110,114,101,113,116, 32, 61, 32, 97,100,106,117,115,116,114,101,113,117,101,115, +116, 40,114,101,113,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104, 32, + 61, 32,111,112,101,110, 40,110,114,101,113,116, 46,104,111,115,116, 44, 32,110, +114,101,113,116, 46,112,111,114,116, 44, 32,110,114,101,113,116, 46, 99,114,101, + 97,116,101, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32,114,101,113, +117,101,115,116, 32,108,105,110,101, 32, 97,110,100, 32,104,101, 97,100,101,114, +115, 10, 32, 32, 32, 32,104, 58,115,101,110,100,114,101,113,117,101,115,116,108, +105,110,101, 40,110,114,101,113,116, 46,109,101,116,104,111,100, 44, 32,110,114, +101,113,116, 46,117,114,105, 41, 10, 32, 32, 32, 32,104, 58,115,101,110,100,104, +101, 97,100,101,114,115, 40,110,114,101,113,116, 46,104,101, 97,100,101,114,115, + 41, 10, 32, 32, 32, 32, 45, 45, 32,105,102, 32,116,104,101,114,101, 32,105,115, + 32, 97, 32, 98,111,100,121, 44, 32,115,101,110,100, 32,105,116, 10, 32, 32, 32, + 32,105,102, 32,110,114,101,113,116, 46,115,111,117,114, 99,101, 32,116,104,101, +110, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 58,115,101,110,100, 98,111,100,121, + 40,110,114,101,113,116, 46,104,101, 97,100,101,114,115, 44, 32,110,114,101,113, +116, 46,115,111,117,114, 99,101, 44, 32,110,114,101,113,116, 46,115,116,101,112, + 41, 32, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32, 99,111,100,101, 44, 32,115,116, 97,116,117,115, 32, 61, 32,104, 58,114,101, + 99,101,105,118,101,115,116, 97,116,117,115,108,105,110,101, 40, 41, 10, 32, 32, + 32, 32, 45, 45, 32,105,102, 32,105,116, 32,105,115, 32, 97,110, 32, 72, 84, 84, + 80, 47, 48, 46, 57, 32,115,101,114,118,101,114, 44, 32,115,105,109,112,108,121, + 32,103,101,116, 32,116,104,101, 32, 98,111,100,121, 32, 97,110,100, 32,119,101, + 32, 97,114,101, 32,100,111,110,101, 10, 32, 32, 32, 32,105,102, 32,110,111,116, + 32, 99,111,100,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, + 58,114,101, 99,101,105,118,101, 48, 57, 98,111,100,121, 40,115,116, 97,116,117, +115, 44, 32,110,114,101,113,116, 46,115,105,110,107, 44, 32,110,114,101,113,116, + 46,115,116,101,112, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114, +110, 32, 49, 44, 32, 50, 48, 48, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, + 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115, 10, 32, 32, 32, 32, 45, + 45, 32,105,103,110,111,114,101, 32, 97,110,121, 32, 49, 48, 48, 45, 99,111,110, +116,105,110,117,101, 32,109,101,115,115, 97,103,101,115, 10, 32, 32, 32, 32,119, +104,105,108,101, 32, 99,111,100,101, 32, 61, 61, 32, 49, 48, 48, 32,100,111, 32, + 10, 32, 32, 32, 32, 32, 32, 32, 32,104,101, 97,100,101,114,115, 32, 61, 32,104, + 58,114,101, 99,101,105,118,101,104,101, 97,100,101,114,115, 40, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 99,111,100,101, 44, 32,115,116, 97,116,117,115, 32, 61, + 32,104, 58,114,101, 99,101,105,118,101,115,116, 97,116,117,115,108,105,110,101, + 40, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,104,101, 97,100,101, +114,115, 32, 61, 32,104, 58,114,101, 99,101,105,118,101,104,101, 97,100,101,114, +115, 40, 41, 10, 32, 32, 32, 32, 45, 45, 32, 97,116, 32,116,104,105,115, 32,112, +111,105,110,116, 32,119,101, 32,115,104,111,117,108,100, 32,104, 97,118,101, 32, + 97, 32,104,111,110,101,115,116, 32,114,101,112,108,121, 32,102,114,111,109, 32, +116,104,101, 32,115,101,114,118,101,114, 10, 32, 32, 32, 32, 45, 45, 32,119,101, + 32, 99, 97,110, 39,116, 32,114,101,100,105,114,101, 99,116, 32,105,102, 32,119, +101, 32, 97,108,114,101, 97,100,121, 32,117,115,101,100, 32,116,104,101, 32,115, +111,117,114, 99,101, 44, 32,115,111, 32,119,101, 32,114,101,112,111,114,116, 32, +116,104,101, 32,101,114,114,111,114, 32, 10, 32, 32, 32, 32,105,102, 32,115,104, +111,117,108,100,114,101,100,105,114,101, 99,116, 40,110,114,101,113,116, 44, 32, + 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 41, 32, 97,110,100, 32,110, +111,116, 32,110,114,101,113,116, 46,115,111,117,114, 99,101, 32,116,104,101,110, + 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 58, 99,108,111,115,101, 40, 41, 10, 32, + 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,116,114,101,100,105,114, +101, 99,116, 40,114,101,113,116, 44, 32,104,101, 97,100,101,114,115, 46,108,111, + 99, 97,116,105,111,110, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, + 45, 45, 32,104,101,114,101, 32,119,101, 32, 97,114,101, 32,102,105,110, 97,108, +108,121, 32,100,111,110,101, 10, 32, 32, 32, 32,105,102, 32,115,104,111,117,108, +100,114,101, 99,101,105,118,101, 98,111,100,121, 40,110,114,101,113,116, 44, 32, + 99,111,100,101, 41, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,104, + 58,114,101, 99,101,105,118,101, 98,111,100,121, 40,104,101, 97,100,101,114,115, + 44, 32,110,114,101,113,116, 46,115,105,110,107, 44, 32,110,114,101,113,116, 46, +115,116,101,112, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,104, 58, + 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, + 44, 32, 99,111,100,101, 44, 32,104,101, 97,100,101,114,115, 44, 32,115,116, 97, +116,117,115, 10,101,110,100, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116, +105,111,110, 32,115,114,101,113,117,101,115,116, 40,117, 44, 32, 98, 41, 10, 32, + 32, 32, 32,108,111, 99, 97,108, 32,116, 32, 61, 32,123,125, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,114,101,113,116, 32, 61, 32,123, 10, 32, 32, 32, 32, 32, + 32, 32, 32,117,114,108, 32, 61, 32,117, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, +115,105,110,107, 32, 61, 32,108,116,110, 49, 50, 46,115,105,110,107, 46,116, 97, + 98,108,101, 40,116, 41, 10, 32, 32, 32, 32,125, 10, 32, 32, 32, 32,105,102, 32, + 98, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,113,116, 46, +115,111,117,114, 99,101, 32, 61, 32,108,116,110, 49, 50, 46,115,111,117,114, 99, +101, 46,115,116,114,105,110,103, 40, 98, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,113,116, 46,104,101, 97,100,101,114,115, 32, 61, 32,123, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34, 99,111,110,116,101,110,116, 45,108, +101,110,103,116,104, 34, 93, 32, 61, 32,115,116,114,105,110,103, 46,108,101,110, + 40, 98, 41, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 91, 34, 99, +111,110,116,101,110,116, 45,116,121,112,101, 34, 93, 32, 61, 32, 34, 97,112,112, +108,105, 99, 97,116,105,111,110, 47,120, 45,119,119,119, 45,102,111,114,109, 45, +117,114,108,101,110, 99,111,100,101,100, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32, +125, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,113,116, 46,109,101,116,104,111, +100, 32, 61, 32, 34, 80, 79, 83, 84, 34, 10, 32, 32, 32, 32,101,110,100, 10, 32, + 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, 44, 32,104,101, 97,100,101, +114,115, 44, 32,115,116, 97,116,117,115, 32, 61, 32,115,111, 99,107,101,116, 46, +115,107,105,112, 40, 49, 44, 32,116,114,101,113,117,101,115,116, 40,114,101,113, +116, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,116, 97, 98,108,101, + 46, 99,111,110, 99, 97,116, 40,116, 41, 44, 32, 99,111,100,101, 44, 32,104,101, + 97,100,101,114,115, 44, 32,115,116, 97,116,117,115, 10,101,110,100, 10, 10,114, +101,113,117,101,115,116, 32, 61, 32,115,111, 99,107,101,116, 46,112,114,111,116, +101, 99,116, 40,102,117,110, 99,116,105,111,110, 40,114,101,113,116, 44, 32, 98, +111,100,121, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121,112, +101, 40,114,101,113,116, 41, 32, 61, 61, 32, 34,115,116,114,105,110,103, 34, 32, +116,104,101,110, 32,114,101,116,117,114,110, 32,115,114,101,113,117,101,115,116, + 40,114,101,113,116, 44, 32, 98,111,100,121, 41, 10, 32, 32, 32, 32,101,108,115, +101, 32,114,101,116,117,114,110, 32,116,114,101,113,117,101,115,116, 40,114,101, +113,116, 41, 32,101,110,100, 10,101,110,100, 41, 10, + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/src/libs/luasocket/src/inet.c b/src/libs/luasocket/src/inet.c new file mode 100644 index 000000000..f2cddeeab --- /dev/null +++ b/src/libs/luasocket/src/inet.c @@ -0,0 +1,281 @@ +/*=========================================================================*\ +* Internet domain functions +* LuaSocket toolkit +* +* RCS ID: $Id: inet.c,v 1.28 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include <stdio.h> +#include <string.h> + +#include "lua.h" +#include "lauxlib.h" + +#include "inet.h" + +/*=========================================================================*\ +* Internal function prototypes. +\*=========================================================================*/ +static int inet_global_toip(lua_State *L); +static int inet_global_tohostname(lua_State *L); +static void inet_pushresolved(lua_State *L, struct hostent *hp); +static int inet_global_gethostname(lua_State *L); + +/* DNS functions */ +static luaL_reg func[] = { + { "toip", inet_global_toip }, + { "tohostname", inet_global_tohostname }, + { "gethostname", inet_global_gethostname}, + { NULL, NULL} +}; + +/*=========================================================================*\ +* Exported functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int inet_open(lua_State *L) +{ + lua_pushstring(L, "dns"); + lua_newtable(L); + luaL_openlib(L, NULL, func, 0); + lua_settable(L, -3); + return 0; +} + +/*=========================================================================*\ +* Global Lua functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Returns all information provided by the resolver given a host name +* or ip address +\*-------------------------------------------------------------------------*/ +static int inet_gethost(const char *address, struct hostent **hp) { + struct in_addr addr; + if (inet_aton(address, &addr)) + return socket_gethostbyaddr((char *) &addr, sizeof(addr), hp); + else + return socket_gethostbyname(address, hp); +} + +/*-------------------------------------------------------------------------*\ +* Returns all information provided by the resolver given a host name +* or ip address +\*-------------------------------------------------------------------------*/ +static int inet_global_tohostname(lua_State *L) { + const char *address = luaL_checkstring(L, 1); + struct hostent *hp = NULL; + int err = inet_gethost(address, &hp); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, socket_hoststrerror(err)); + return 2; + } + lua_pushstring(L, hp->h_name); + inet_pushresolved(L, hp); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Returns all information provided by the resolver given a host name +* or ip address +\*-------------------------------------------------------------------------*/ +static int inet_global_toip(lua_State *L) +{ + const char *address = luaL_checkstring(L, 1); + struct hostent *hp = NULL; + int err = inet_gethost(address, &hp); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, socket_hoststrerror(err)); + return 2; + } + lua_pushstring(L, inet_ntoa(*((struct in_addr *) hp->h_addr))); + inet_pushresolved(L, hp); + return 2; +} + + +/*-------------------------------------------------------------------------*\ +* Gets the host name +\*-------------------------------------------------------------------------*/ +static int inet_global_gethostname(lua_State *L) +{ + char name[257]; + name[256] = '\0'; + if (gethostname(name, 256) < 0) { + lua_pushnil(L); + lua_pushstring(L, "gethostname failed"); + return 2; + } else { + lua_pushstring(L, name); + return 1; + } +} + + + +/*=========================================================================*\ +* Lua methods +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Retrieves socket peer name +\*-------------------------------------------------------------------------*/ +int inet_meth_getpeername(lua_State *L, p_socket ps) +{ + struct sockaddr_in peer; + socklen_t peer_len = sizeof(peer); + if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) { + lua_pushnil(L); + lua_pushstring(L, "getpeername failed"); + } else { + lua_pushstring(L, inet_ntoa(peer.sin_addr)); + lua_pushnumber(L, ntohs(peer.sin_port)); + } + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Retrieves socket local name +\*-------------------------------------------------------------------------*/ +int inet_meth_getsockname(lua_State *L, p_socket ps) +{ + struct sockaddr_in local; + socklen_t local_len = sizeof(local); + if (getsockname(*ps, (SA *) &local, &local_len) < 0) { + lua_pushnil(L); + lua_pushstring(L, "getsockname failed"); + } else { + lua_pushstring(L, inet_ntoa(local.sin_addr)); + lua_pushnumber(L, ntohs(local.sin_port)); + } + return 2; +} + +/*=========================================================================*\ +* Internal functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Passes all resolver information to Lua as a table +\*-------------------------------------------------------------------------*/ +static void inet_pushresolved(lua_State *L, struct hostent *hp) +{ + char **alias; + struct in_addr **addr; + int i, resolved; + lua_newtable(L); resolved = lua_gettop(L); + lua_pushstring(L, "name"); + lua_pushstring(L, hp->h_name); + lua_settable(L, resolved); + lua_pushstring(L, "ip"); + lua_pushstring(L, "alias"); + i = 1; + alias = hp->h_aliases; + lua_newtable(L); + if (alias) { + while (*alias) { + lua_pushnumber(L, i); + lua_pushstring(L, *alias); + lua_settable(L, -3); + i++; alias++; + } + } + lua_settable(L, resolved); + i = 1; + lua_newtable(L); + addr = (struct in_addr **) hp->h_addr_list; + if (addr) { + while (*addr) { + lua_pushnumber(L, i); + lua_pushstring(L, inet_ntoa(**addr)); + lua_settable(L, -3); + i++; addr++; + } + } + lua_settable(L, resolved); +} + +/*-------------------------------------------------------------------------*\ +* Tries to create a new inet socket +\*-------------------------------------------------------------------------*/ +const char *inet_trycreate(p_socket ps, int type) { + return socket_strerror(socket_create(ps, AF_INET, type, 0)); +} + +/*-------------------------------------------------------------------------*\ +* Tries to connect to remote address (address, port) +\*-------------------------------------------------------------------------*/ +const char *inet_tryconnect(p_socket ps, const char *address, + unsigned short port, p_timeout tm) +{ + struct sockaddr_in remote; + int err; + memset(&remote, 0, sizeof(remote)); + remote.sin_family = AF_INET; + remote.sin_port = htons(port); + if (strcmp(address, "*")) { + if (!inet_aton(address, &remote.sin_addr)) { + struct hostent *hp = NULL; + struct in_addr **addr; + err = socket_gethostbyname(address, &hp); + if (err != IO_DONE) return socket_hoststrerror(err); + addr = (struct in_addr **) hp->h_addr_list; + memcpy(&remote.sin_addr, *addr, sizeof(struct in_addr)); + } + } else remote.sin_family = AF_UNSPEC; + err = socket_connect(ps, (SA *) &remote, sizeof(remote), tm); + return socket_strerror(err); +} + +/*-------------------------------------------------------------------------*\ +* Tries to bind socket to (address, port) +\*-------------------------------------------------------------------------*/ +const char *inet_trybind(p_socket ps, const char *address, unsigned short port) +{ + struct sockaddr_in local; + int err; + memset(&local, 0, sizeof(local)); + /* address is either wildcard or a valid ip address */ + local.sin_addr.s_addr = htonl(INADDR_ANY); + local.sin_port = htons(port); + local.sin_family = AF_INET; + if (strcmp(address, "*") && !inet_aton(address, &local.sin_addr)) { + struct hostent *hp = NULL; + struct in_addr **addr; + err = socket_gethostbyname(address, &hp); + if (err != IO_DONE) return socket_hoststrerror(err); + addr = (struct in_addr **) hp->h_addr_list; + memcpy(&local.sin_addr, *addr, sizeof(struct in_addr)); + } + err = socket_bind(ps, (SA *) &local, sizeof(local)); + if (err != IO_DONE) socket_destroy(ps); + return socket_strerror(err); +} + +/*-------------------------------------------------------------------------*\ +* Some systems do not provide this so that we provide our own. It's not +* marvelously fast, but it works just fine. +\*-------------------------------------------------------------------------*/ +#ifdef INET_ATON +int inet_aton(const char *cp, struct in_addr *inp) +{ + unsigned int a = 0, b = 0, c = 0, d = 0; + int n = 0, r; + unsigned long int addr = 0; + r = sscanf(cp, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n); + if (r == 0 || n == 0) return 0; + cp += n; + if (*cp) return 0; + if (a > 255 || b > 255 || c > 255 || d > 255) return 0; + if (inp) { + addr += a; addr <<= 8; + addr += b; addr <<= 8; + addr += c; addr <<= 8; + addr += d; + inp->s_addr = htonl(addr); + } + return 1; +} +#endif + + diff --git a/src/libs/luasocket/src/inet.h b/src/libs/luasocket/src/inet.h new file mode 100644 index 000000000..766226611 --- /dev/null +++ b/src/libs/luasocket/src/inet.h @@ -0,0 +1,42 @@ +#ifndef INET_H +#define INET_H +/*=========================================================================*\ +* Internet domain functions +* LuaSocket toolkit +* +* This module implements the creation and connection of internet domain +* sockets, on top of the socket.h interface, and the interface of with the +* resolver. +* +* The function inet_aton is provided for the platforms where it is not +* available. The module also implements the interface of the internet +* getpeername and getsockname functions as seen by Lua programs. +* +* The Lua functions toip and tohostname are also implemented here. +* +* RCS ID: $Id: inet.h,v 1.16 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include "lua.h" +#include "socket.h" +#include "timeout.h" + +#ifdef _WIN32 +#define INET_ATON +#endif + +int inet_open(lua_State *L); + +const char *inet_trycreate(p_socket ps, int type); +const char *inet_tryconnect(p_socket ps, const char *address, + unsigned short port, p_timeout tm); +const char *inet_trybind(p_socket ps, const char *address, + unsigned short port); + +int inet_meth_getpeername(lua_State *L, p_socket ps); +int inet_meth_getsockname(lua_State *L, p_socket ps); + +#ifdef INET_ATON +int inet_aton(const char *cp, struct in_addr *inp); +#endif + +#endif /* INET_H */ diff --git a/src/libs/luasocket/src/io.c b/src/libs/luasocket/src/io.c new file mode 100644 index 000000000..06dc50eca --- /dev/null +++ b/src/libs/luasocket/src/io.c @@ -0,0 +1,32 @@ +/*=========================================================================*\ +* Input/Output abstraction +* LuaSocket toolkit +* +* RCS ID: $Id: io.c,v 1.6 2005/09/29 06:11:41 diego Exp $ +\*=========================================================================*/ +#include "io.h" + +/*=========================================================================*\ +* Exported functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Initializes C structure +\*-------------------------------------------------------------------------*/ +void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx) { + io->send = send; + io->recv = recv; + io->error = error; + io->ctx = ctx; +} + +/*-------------------------------------------------------------------------*\ +* I/O error strings +\*-------------------------------------------------------------------------*/ +const char *io_strerror(int err) { + switch (err) { + case IO_DONE: return NULL; + case IO_CLOSED: return "closed"; + case IO_TIMEOUT: return "timeout"; + default: return "unknown error"; + } +} diff --git a/src/libs/luasocket/src/io.h b/src/libs/luasocket/src/io.h new file mode 100644 index 000000000..cce3aaf55 --- /dev/null +++ b/src/libs/luasocket/src/io.h @@ -0,0 +1,67 @@ +#ifndef IO_H +#define IO_H +/*=========================================================================*\ +* Input/Output abstraction +* LuaSocket toolkit +* +* This module defines the interface that LuaSocket expects from the +* transport layer for streamed input/output. The idea is that if any +* transport implements this interface, then the buffer.c functions +* automatically work on it. +* +* The module socket.h implements this interface, and thus the module tcp.h +* is very simple. +* +* RCS ID: $Id: io.h,v 1.11 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include <stdio.h> +#include "lua.h" + +#include "timeout.h" + +/* IO error codes */ +enum { + IO_DONE = 0, /* operation completed successfully */ + IO_TIMEOUT = -1, /* operation timed out */ + IO_CLOSED = -2, /* the connection has been closed */ + IO_UNKNOWN = -3 +}; + +/* interface to error message function */ +typedef const char *(*p_error) ( + void *ctx, /* context needed by send */ + int err /* error code */ +); + +/* interface to send function */ +typedef int (*p_send) ( + void *ctx, /* context needed by send */ + const char *data, /* pointer to buffer with data to send */ + size_t count, /* number of bytes to send from buffer */ + size_t *sent, /* number of bytes sent uppon return */ + p_timeout tm /* timeout control */ +); + +/* interface to recv function */ +typedef int (*p_recv) ( + void *ctx, /* context needed by recv */ + char *data, /* pointer to buffer where data will be writen */ + size_t count, /* number of bytes to receive into buffer */ + size_t *got, /* number of bytes received uppon return */ + p_timeout tm /* timeout control */ +); + +/* IO driver definition */ +typedef struct t_io_ { + void *ctx; /* context needed by send/recv */ + p_send send; /* send function pointer */ + p_recv recv; /* receive function pointer */ + p_error error; /* strerror function */ +} t_io; +typedef t_io *p_io; + +void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx); +const char *io_strerror(int err); + +#endif /* IO_H */ + diff --git a/src/libs/luasocket/src/ltn12.lua b/src/libs/luasocket/src/ltn12.lua new file mode 100644 index 000000000..b42689a34 --- /dev/null +++ b/src/libs/luasocket/src/ltn12.lua @@ -0,0 +1,292 @@ +----------------------------------------------------------------------------- +-- LTN12 - Filters, sources, sinks and pumps. +-- LuaSocket toolkit. +-- Author: Diego Nehab +-- RCS ID: $Id: ltn12.lua,v 1.31 2006/04/03 04:45:42 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module +----------------------------------------------------------------------------- +local string = require("string") +local table = require("table") +local base = _G +module("ltn12") + +filter = {} +source = {} +sink = {} +pump = {} + +-- 2048 seems to be better in windows... +BLOCKSIZE = 2048 +_VERSION = "LTN12 1.0.1" + +----------------------------------------------------------------------------- +-- Filter stuff +----------------------------------------------------------------------------- +-- returns a high level filter that cycles a low-level filter +function filter.cycle(low, ctx, extra) + base.assert(low) + return function(chunk) + local ret + ret, ctx = low(ctx, chunk, extra) + return ret + end +end + +-- chains a bunch of filters together +-- (thanks to Wim Couwenberg) +function filter.chain(...) + local n = table.getn(arg) + local top, index = 1, 1 + local retry = "" + return function(chunk) + retry = chunk and retry + while true do + if index == top then + chunk = arg[index](chunk) + if chunk == "" or top == n then return chunk + elseif chunk then index = index + 1 + else + top = top+1 + index = top + end + else + chunk = arg[index](chunk or "") + if chunk == "" then + index = index - 1 + chunk = retry + elseif chunk then + if index == n then return chunk + else index = index + 1 end + else base.error("filter returned inappropriate nil") end + end + end + end +end + +----------------------------------------------------------------------------- +-- Source stuff +----------------------------------------------------------------------------- +-- create an empty source +local function empty() + return nil +end + +function source.empty() + return empty +end + +-- returns a source that just outputs an error +function source.error(err) + return function() + return nil, err + end +end + +-- creates a file source +function source.file(handle, io_err) + if handle then + return function() + local chunk = handle:read(BLOCKSIZE) + if not chunk then handle:close() end + return chunk + end + else return source.error(io_err or "unable to open file") end +end + +-- turns a fancy source into a simple source +function source.simplify(src) + base.assert(src) + return function() + local chunk, err_or_new = src() + src = err_or_new or src + if not chunk then return nil, err_or_new + else return chunk end + end +end + +-- creates string source +function source.string(s) + if s then + local i = 1 + return function() + local chunk = string.sub(s, i, i+BLOCKSIZE-1) + i = i + BLOCKSIZE + if chunk ~= "" then return chunk + else return nil end + end + else return source.empty() end +end + +-- creates rewindable source +function source.rewind(src) + base.assert(src) + local t = {} + return function(chunk) + if not chunk then + chunk = table.remove(t) + if not chunk then return src() + else return chunk end + else + table.insert(t, chunk) + end + end +end + +function source.chain(src, f) + base.assert(src and f) + local last_in, last_out = "", "" + local state = "feeding" + local err + return function() + if not last_out then + base.error('source is empty!', 2) + end + while true do + if state == "feeding" then + last_in, err = src() + if err then return nil, err end + last_out = f(last_in) + if not last_out then + if last_in then + base.error('filter returned inappropriate nil') + else + return nil + end + elseif last_out ~= "" then + state = "eating" + if last_in then last_in = "" end + return last_out + end + else + last_out = f(last_in) + if last_out == "" then + if last_in == "" then + state = "feeding" + else + base.error('filter returned ""') + end + elseif not last_out then + if last_in then + base.error('filter returned inappropriate nil') + else + return nil + end + else + return last_out + end + end + end + end +end + +-- creates a source that produces contents of several sources, one after the +-- other, as if they were concatenated +-- (thanks to Wim Couwenberg) +function source.cat(...) + local src = table.remove(arg, 1) + return function() + while src do + local chunk, err = src() + if chunk then return chunk end + if err then return nil, err end + src = table.remove(arg, 1) + end + end +end + +----------------------------------------------------------------------------- +-- Sink stuff +----------------------------------------------------------------------------- +-- creates a sink that stores into a table +function sink.table(t) + t = t or {} + local f = function(chunk, err) + if chunk then table.insert(t, chunk) end + return 1 + end + return f, t +end + +-- turns a fancy sink into a simple sink +function sink.simplify(snk) + base.assert(snk) + return function(chunk, err) + local ret, err_or_new = snk(chunk, err) + if not ret then return nil, err_or_new end + snk = err_or_new or snk + return 1 + end +end + +-- creates a file sink +function sink.file(handle, io_err) + if handle then + return function(chunk, err) + if not chunk then + handle:close() + return 1 + else return handle:write(chunk) end + end + else return sink.error(io_err or "unable to open file") end +end + +-- creates a sink that discards data +local function null() + return 1 +end + +function sink.null() + return null +end + +-- creates a sink that just returns an error +function sink.error(err) + return function() + return nil, err + end +end + +-- chains a sink with a filter +function sink.chain(f, snk) + base.assert(f and snk) + return function(chunk, err) + if chunk ~= "" then + local filtered = f(chunk) + local done = chunk and "" + while true do + local ret, snkerr = snk(filtered, err) + if not ret then return nil, snkerr end + if filtered == done then return 1 end + filtered = f(done) + end + else return 1 end + end +end + +----------------------------------------------------------------------------- +-- Pump stuff +----------------------------------------------------------------------------- +-- pumps one chunk from the source to the sink +function pump.step(src, snk) + local chunk, src_err = src() + local ret, snk_err = snk(chunk, src_err) + if chunk and ret then return 1 + else return nil, src_err or snk_err end +end + +-- pumps all data from a source to a sink, using a step function +function pump.all(src, snk, step) + base.assert(src and snk) + step = step or pump.step + while true do + local ret, err = step(src, snk) + if not ret then + if err then return nil, err + else return 1 end + end + end +end + diff --git a/src/libs/luasocket/src/ltn12_lua.c b/src/libs/luasocket/src/ltn12_lua.c new file mode 100644 index 000000000..308bc31f0 --- /dev/null +++ b/src/libs/luasocket/src/ltn12_lua.c @@ -0,0 +1,422 @@ +/* + * This file is auto-generated by "./lua2c ltn12.lua ltn12_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_ltn12_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 76, 84, 78, 49, 50, 32, 45, 32, 70,105,108,116,101,114,115, 44, 32,115,111, +117,114, 99,101,115, 44, 32,115,105,110,107,115, 32, 97,110,100, 32,112,117,109, +112,115, 46, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32,116,111,111, +108,107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, 68,105,101, +103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, + 36, 73,100, 58, 32,108,116,110, 49, 50, 46,108,117, 97, 44,118, 32, 49, 46, 51, + 49, 32, 50, 48, 48, 54, 47, 48, 52, 47, 48, 51, 32, 48, 52, 58, 52, 53, 58, 52, + 50, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114, +101, 32,109,111,100,117,108,101, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, + 61, 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10, +108,111, 99, 97,108, 32,116, 97, 98,108,101, 32, 61, 32,114,101,113,117,105,114, +101, 40, 34,116, 97, 98,108,101, 34, 41, 10,108,111, 99, 97,108, 32, 98, 97,115, +101, 32, 61, 32, 95, 71, 10,109,111,100,117,108,101, 40, 34,108,116,110, 49, 50, + 34, 41, 10, 10,102,105,108,116,101,114, 32, 61, 32,123,125, 10,115,111,117,114, + 99,101, 32, 61, 32,123,125, 10,115,105,110,107, 32, 61, 32,123,125, 10,112,117, +109,112, 32, 61, 32,123,125, 10, 10, 45, 45, 32, 50, 48, 52, 56, 32,115,101,101, +109,115, 32,116,111, 32, 98,101, 32, 98,101,116,116,101,114, 32,105,110, 32,119, +105,110,100,111,119,115, 46, 46, 46, 10, 66, 76, 79, 67, 75, 83, 73, 90, 69, 32, + 61, 32, 50, 48, 52, 56, 10, 95, 86, 69, 82, 83, 73, 79, 78, 32, 61, 32, 34, 76, + 84, 78, 49, 50, 32, 49, 46, 48, 46, 49, 34, 10, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 70,105,108,116,101,114, + 32,115,116,117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 10, 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,104,105, +103,104, 32,108,101,118,101,108, 32,102,105,108,116,101,114, 32,116,104, 97,116, + 32, 99,121, 99,108,101,115, 32, 97, 32,108,111,119, 45,108,101,118,101,108, 32, +102,105,108,116,101,114, 10,102,117,110, 99,116,105,111,110, 32,102,105,108,116, +101,114, 46, 99,121, 99,108,101, 40,108,111,119, 44, 32, 99,116,120, 44, 32,101, +120,116,114, 97, 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114, +116, 40,108,111,119, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117, +110, 99,116,105,111,110, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32,108,111, 99, 97,108, 32,114,101,116, 10, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,116, 44, 32, 99,116,120, 32, 61, 32,108,111,119, 40, 99,116,120, 44, 32, + 99,104,117,110,107, 44, 32,101,120,116,114, 97, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32,114,101,116, 10, 32, 32, 32, 32,101,110,100, + 10,101,110,100, 10, 10, 45, 45, 32, 99,104, 97,105,110,115, 32, 97, 32, 98,117, +110, 99,104, 32,111,102, 32,102,105,108,116,101,114,115, 32,116,111,103,101,116, +104,101,114, 10, 45, 45, 32, 40,116,104, 97,110,107,115, 32,116,111, 32, 87,105, +109, 32, 67,111,117,119,101,110, 98,101,114,103, 41, 10,102,117,110, 99,116,105, +111,110, 32,102,105,108,116,101,114, 46, 99,104, 97,105,110, 40, 46, 46, 46, 41, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,110, 32, 61, 32,116, 97, 98,108,101, + 46,103,101,116,110, 40, 97,114,103, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32,116,111,112, 44, 32,105,110,100,101,120, 32, 61, 32, 49, 44, 32, 49, 10, 32, + 32, 32, 32,108,111, 99, 97,108, 32,114,101,116,114,121, 32, 61, 32, 34, 34, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, + 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,114,121, + 32, 61, 32, 99,104,117,110,107, 32, 97,110,100, 32,114,101,116,114,121, 10, 32, + 32, 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,105,110,100,101, +120, 32, 61, 61, 32,116,111,112, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61, 32, 97,114, +103, 91,105,110,100,101,120, 93, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107, + 32, 61, 61, 32, 34, 34, 32,111,114, 32,116,111,112, 32, 61, 61, 32,110, 32,116, +104,101,110, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105,102, 32, + 99,104,117,110,107, 32,116,104,101,110, 32,105,110,100,101,120, 32, 61, 32,105, +110,100,101,120, 32, 43, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,116,111,112, 32, 61, 32,116,111,112, 43, + 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,105,110,100,101,120, 32, 61, 32,116,111,112, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61, 32, 97,114,103, 91,105, +110,100,101,120, 93, 40, 99,104,117,110,107, 32,111,114, 32, 34, 34, 41, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104, +117,110,107, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,110,100,101,120, + 32, 61, 32,105,110,100,101,120, 32, 45, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117,110,107, 32, 61, + 32,114,101,116,114,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,101,108,115,101,105,102, 32, 99,104,117,110,107, 32,116,104,101,110, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,105,102, 32,105,110,100,101,120, 32, 61, 61, 32,110, 32,116,104,101,110, 32, +114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,105,110, +100,101,120, 32, 61, 32,105,110,100,101,120, 32, 43, 32, 49, 32,101,110,100, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, + 32, 98, 97,115,101, 46,101,114,114,111,114, 40, 34,102,105,108,116,101,114, 32, +114,101,116,117,114,110,101,100, 32,105,110, 97,112,112,114,111,112,114,105, 97, +116,101, 32,110,105,108, 34, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, + 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 83,111,117,114, 99, +101, 32,115,116,117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 10, 45, 45, 32, 99,114,101, 97,116,101, 32, 97,110, 32,101, +109,112,116,121, 32,115,111,117,114, 99,101, 10,108,111, 99, 97,108, 32,102,117, +110, 99,116,105,111,110, 32,101,109,112,116,121, 40, 41, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,110,105,108, 10,101,110,100, 10, 10,102,117,110, 99,116, +105,111,110, 32,115,111,117,114, 99,101, 46,101,109,112,116,121, 40, 41, 10, 32, + 32, 32, 32,114,101,116,117,114,110, 32,101,109,112,116,121, 10,101,110,100, 10, + 10, 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,115,111,117,114, 99,101, + 32,116,104, 97,116, 32,106,117,115,116, 32,111,117,116,112,117,116,115, 32, 97, +110, 32,101,114,114,111,114, 10,102,117,110, 99,116,105,111,110, 32,115,111,117, +114, 99,101, 46,101,114,114,111,114, 40,101,114,114, 41, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, + 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, + 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, + 97,116,101,115, 32, 97, 32,102,105,108,101, 32,115,111,117,114, 99,101, 10,102, +117,110, 99,116,105,111,110, 32,115,111,117,114, 99,101, 46,102,105,108,101, 40, +104, 97,110,100,108,101, 44, 32,105,111, 95,101,114,114, 41, 10, 32, 32, 32, 32, +105,102, 32,104, 97,110,100,108,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, + 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99, +104,117,110,107, 32, 61, 32,104, 97,110,100,108,101, 58,114,101, 97,100, 40, 66, + 76, 79, 67, 75, 83, 73, 90, 69, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 32, +104, 97,110,100,108,101, 58, 99,108,111,115,101, 40, 41, 32,101,110,100, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 99,104, +117,110,107, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, +101,108,115,101, 32,114,101,116,117,114,110, 32,115,111,117,114, 99,101, 46,101, +114,114,111,114, 40,105,111, 95,101,114,114, 32,111,114, 32, 34,117,110, 97, 98, +108,101, 32,116,111, 32,111,112,101,110, 32,102,105,108,101, 34, 41, 32,101,110, +100, 10,101,110,100, 10, 10, 45, 45, 32,116,117,114,110,115, 32, 97, 32,102, 97, +110, 99,121, 32,115,111,117,114, 99,101, 32,105,110,116,111, 32, 97, 32,115,105, +109,112,108,101, 32,115,111,117,114, 99,101, 10,102,117,110, 99,116,105,111,110, + 32,115,111,117,114, 99,101, 46,115,105,109,112,108,105,102,121, 40,115,114, 99, + 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115,114, + 99, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105, +111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99, +104,117,110,107, 44, 32,101,114,114, 95,111,114, 95,110,101,119, 32, 61, 32,115, +114, 99, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,114, 99, 32, 61, 32,101, +114,114, 95,111,114, 95,110,101,119, 32,111,114, 32,115,114, 99, 10, 32, 32, 32, + 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104, +101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 95,111, +114, 95,110,101,119, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114, +101,116,117,114,110, 32, 99,104,117,110,107, 32,101,110,100, 10, 32, 32, 32, 32, +101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, +115,116,114,105,110,103, 32,115,111,117,114, 99,101, 10,102,117,110, 99,116,105, +111,110, 32,115,111,117,114, 99,101, 46,115,116,114,105,110,103, 40,115, 41, 10, + 32, 32, 32, 32,105,102, 32,115, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, + 32, 32,108,111, 99, 97,108, 32,105, 32, 61, 32, 49, 10, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104, +117,110,107, 32, 61, 32,115,116,114,105,110,103, 46,115,117, 98, 40,115, 44, 32, +105, 44, 32,105, 43, 66, 76, 79, 67, 75, 83, 73, 90, 69, 45, 49, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105, 32, 61, 32,105, 32, 43, 32, 66, 76, + 79, 67, 75, 83, 73, 90, 69, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +105,102, 32, 99,104,117,110,107, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 32, +114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,110,105,108, + 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, + 32,101,108,115,101, 32,114,101,116,117,114,110, 32,115,111,117,114, 99,101, 46, +101,109,112,116,121, 40, 41, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, + 99,114,101, 97,116,101,115, 32,114,101,119,105,110,100, 97, 98,108,101, 32,115, +111,117,114, 99,101, 10,102,117,110, 99,116,105,111,110, 32,115,111,117,114, 99, +101, 46,114,101,119,105,110,100, 40,115,114, 99, 41, 10, 32, 32, 32, 32, 98, 97, +115,101, 46, 97,115,115,101,114,116, 40,115,114, 99, 41, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,116, 32, 61, 32,123,125, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,102,117,110, 99,116,105,111,110, 40, 99,104,117,110,107, 41, 10, 32, + 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32, +116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 99,104,117, +110,107, 32, 61, 32,116, 97, 98,108,101, 46,114,101,109,111,118,101, 40,116, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, + 99,104,117,110,107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,115,114, + 99, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, + 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 32,101,110,100, 10, 32, 32, + 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,116, 97, 98,108,101, 46,105,110,115,101,114,116, 40,116, 44, 32, 99, +104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, + 32, 32,101,110,100, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32, +115,111,117,114, 99,101, 46, 99,104, 97,105,110, 40,115,114, 99, 44, 32,102, 41, + 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115,114, 99, + 32, 97,110,100, 32,102, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108, 97, +115,116, 95,105,110, 44, 32,108, 97,115,116, 95,111,117,116, 32, 61, 32, 34, 34, + 44, 32, 34, 34, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,116, 97,116,101, + 32, 61, 32, 34,102,101,101,100,105,110,103, 34, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,101,114,114, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117, +110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +110,111,116, 32,108, 97,115,116, 95,111,117,116, 32,116,104,101,110, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114, + 40, 39,115,111,117,114, 99,101, 32,105,115, 32,101,109,112,116,121, 33, 39, 44, + 32, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,115,116, 97,116,101, 32, 61, + 61, 32, 34,102,101,101,100,105,110,103, 34, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, 97,115,116, 95,105,110, + 44, 32,101,114,114, 32, 61, 32,115,114, 99, 40, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101, +110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110, +100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, 97, +115,116, 95,111,117,116, 32, 61, 32,102, 40,108, 97,115,116, 95,105,110, 41, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110, +111,116, 32,108, 97,115,116, 95,111,117,116, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +108, 97,115,116, 95,105,110, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115, +101, 46,101,114,114,111,114, 40, 39,102,105,108,116,101,114, 32,114,101,116,117, +114,110,101,100, 32,105,110, 97,112,112,114,111,112,114,105, 97,116,101, 32,110, +105,108, 39, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, + 32,110,105,108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,108,115,101,105,102, 32,108, 97,115,116, 95,111,117,116, + 32,126, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,116, 97,116,101, 32, 61, 32, + 34,101, 97,116,105,110,103, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,108, 97,115,116, 95,105,110, 32, +116,104,101,110, 32,108, 97,115,116, 95,105,110, 32, 61, 32, 34, 34, 32,101,110, +100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32,108, 97,115,116, 95,111,117,116, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108, 97,115,116, 95,111,117,116, 32, + 61, 32,102, 40,108, 97,115,116, 95,105,110, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,108, 97,115,116, 95,111,117,116, + 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,108, 97,115,116, 95, +105,110, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,116, + 97,116,101, 32, 61, 32, 34,102,101,101,100,105,110,103, 34, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114, 40, 39,102,105,108, +116,101,114, 32,114,101,116,117,114,110,101,100, 32, 34, 34, 39, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110, +100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108, +115,101,105,102, 32,110,111,116, 32,108, 97,115,116, 95,111,117,116, 32,116,104, +101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,105,102, 32,108, 97,115,116, 95,105,110, 32,116,104,101,110, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114, 40, 39,102,105,108,116,101, +114, 32,114,101,116,117,114,110,101,100, 32,105,110, 97,112,112,114,111,112,114, +105, 97,116,101, 32,110,105,108, 39, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,116,117,114,110, 32,110,105,108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117, +114,110, 32,108, 97,115,116, 95,111,117,116, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, + 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,114,101, 97, +116,101,115, 32, 97, 32,115,111,117,114, 99,101, 32,116,104, 97,116, 32,112,114, +111,100,117, 99,101,115, 32, 99,111,110,116,101,110,116,115, 32,111,102, 32,115, +101,118,101,114, 97,108, 32,115,111,117,114, 99,101,115, 44, 32,111,110,101, 32, + 97,102,116,101,114, 32,116,104,101, 10, 45, 45, 32,111,116,104,101,114, 44, 32, + 97,115, 32,105,102, 32,116,104,101,121, 32,119,101,114,101, 32, 99,111,110, 99, + 97,116,101,110, 97,116,101,100, 10, 45, 45, 32, 40,116,104, 97,110,107,115, 32, +116,111, 32, 87,105,109, 32, 67,111,117,119,101,110, 98,101,114,103, 41, 10,102, +117,110, 99,116,105,111,110, 32,115,111,117,114, 99,101, 46, 99, 97,116, 40, 46, + 46, 46, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,114, 99, 32, 61, 32, +116, 97, 98,108,101, 46,114,101,109,111,118,101, 40, 97,114,103, 44, 32, 49, 41, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, + 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,115,114, 99, + 32,100,111, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97, +108, 32, 99,104,117,110,107, 44, 32,101,114,114, 32, 61, 32,115,114, 99, 40, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110, +107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 32, +101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101, +114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, +101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +115,114, 99, 32, 61, 32,116, 97, 98,108,101, 46,114,101,109,111,118,101, 40, 97, +114,103, 44, 32, 49, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, + 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 83,105,110,107, 32,115,116, +117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, 97, 32,115,105,110,107, 32, +116,104, 97,116, 32,115,116,111,114,101,115, 32,105,110,116,111, 32, 97, 32,116, + 97, 98,108,101, 10,102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46,116, + 97, 98,108,101, 40,116, 41, 10, 32, 32, 32, 32,116, 32, 61, 32,116, 32,111,114, + 32,123,125, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,102,117, +110, 99,116,105,111,110, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10, 32, + 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104,117,110,107, 32,116,104,101,110, + 32,116, 97, 98,108,101, 46,105,110,115,101,114,116, 40,116, 44, 32, 99,104,117, +110,107, 41, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117, +114,110, 32, 49, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32,102, 44, 32,116, 10,101,110,100, 10, 10, 45, 45, 32,116,117,114, +110,115, 32, 97, 32,102, 97,110, 99,121, 32,115,105,110,107, 32,105,110,116,111, + 32, 97, 32,115,105,109,112,108,101, 32,115,105,110,107, 10,102,117,110, 99,116, +105,111,110, 32,115,105,110,107, 46,115,105,109,112,108,105,102,121, 40,115,110, +107, 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115, +110,107, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116, +105,111,110, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,116, 44, 32,101,114,114, 95,111, +114, 95,110,101,119, 32, 61, 32,115,110,107, 40, 99,104,117,110,107, 44, 32,101, +114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114, +101,116, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, +101,114,114, 95,111,114, 95,110,101,119, 32,101,110,100, 10, 32, 32, 32, 32, 32, + 32, 32, 32,115,110,107, 32, 61, 32,101,114,114, 95,111,114, 95,110,101,119, 32, +111,114, 32,115,110,107, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114, +110, 32, 49, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, + 99,114,101, 97,116,101,115, 32, 97, 32,102,105,108,101, 32,115,105,110,107, 10, +102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46,102,105,108,101, 40,104, + 97,110,100,108,101, 44, 32,105,111, 95,101,114,114, 41, 10, 32, 32, 32, 32,105, +102, 32,104, 97,110,100,108,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 99,104, +117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,104, 97,110,100, +108,101, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, +104, 97,110,100,108,101, 58,119,114,105,116,101, 40, 99,104,117,110,107, 41, 32, +101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, +101,108,115,101, 32,114,101,116,117,114,110, 32,115,105,110,107, 46,101,114,114, +111,114, 40,105,111, 95,101,114,114, 32,111,114, 32, 34,117,110, 97, 98,108,101, + 32,116,111, 32,111,112,101,110, 32,102,105,108,101, 34, 41, 32,101,110,100, 10, +101,110,100, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, 97, 32,115,105, +110,107, 32,116,104, 97,116, 32,100,105,115, 99, 97,114,100,115, 32,100, 97,116, + 97, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,110,117,108, +108, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 49, 10,101,110,100, + 10, 10,102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46,110,117,108,108, + 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,110,117,108,108, 10,101, +110,100, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, 97, 32,115,105,110, +107, 32,116,104, 97,116, 32,106,117,115,116, 32,114,101,116,117,114,110,115, 32, + 97,110, 32,101,114,114,111,114, 10,102,117,110, 99,116,105,111,110, 32,115,105, +110,107, 46,101,114,114,111,114, 40,101,114,114, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 10, + 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32, 99,104, 97,105, +110,115, 32, 97, 32,115,105,110,107, 32,119,105,116,104, 32, 97, 32,102,105,108, +116,101,114, 10,102,117,110, 99,116,105,111,110, 32,115,105,110,107, 46, 99,104, + 97,105,110, 40,102, 44, 32,115,110,107, 41, 10, 32, 32, 32, 32, 98, 97,115,101, + 46, 97,115,115,101,114,116, 40,102, 32, 97,110,100, 32,115,110,107, 41, 10, 32, + 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105,111,110, 40, 99, +104,117,110,107, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105, +102, 32, 99,104,117,110,107, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,102,105,108, +116,101,114,101,100, 32, 61, 32,102, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,100,111,110,101, 32, + 61, 32, 99,104,117,110,107, 32, 97,110,100, 32, 34, 34, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, + 97,108, 32,114,101,116, 44, 32,115,110,107,101,114,114, 32, 61, 32,115,110,107, + 40,102,105,108,116,101,114,101,100, 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114, +101,116, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, +115,110,107,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,105,102, 32,102,105,108,116,101,114,101,100, 32, 61, + 61, 32,100,111,110,101, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 49, + 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,102,105,108,116,101,114,101,100, 32, 61, 32,102, 40,100,111,110,101, 41, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, 49, 32,101,110, +100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 80,117,109,112, + 32,115,116,117,102,102, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 10, 45, 45, 32,112,117,109,112,115, 32,111,110,101, 32, 99,104, +117,110,107, 32,102,114,111,109, 32,116,104,101, 32,115,111,117,114, 99,101, 32, +116,111, 32,116,104,101, 32,115,105,110,107, 10,102,117,110, 99,116,105,111,110, + 32,112,117,109,112, 46,115,116,101,112, 40,115,114, 99, 44, 32,115,110,107, 41, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,115,114, + 99, 95,101,114,114, 32, 61, 32,115,114, 99, 40, 41, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,114,101,116, 44, 32,115,110,107, 95,101,114,114, 32, 61, 32,115, +110,107, 40, 99,104,117,110,107, 44, 32,115,114, 99, 95,101,114,114, 41, 10, 32, + 32, 32, 32,105,102, 32, 99,104,117,110,107, 32, 97,110,100, 32,114,101,116, 32, +116,104,101,110, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32,101,108, +115,101, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,115,114, 99, 95,101, +114,114, 32,111,114, 32,115,110,107, 95,101,114,114, 32,101,110,100, 10,101,110, +100, 10, 10, 45, 45, 32,112,117,109,112,115, 32, 97,108,108, 32,100, 97,116, 97, + 32,102,114,111,109, 32, 97, 32,115,111,117,114, 99,101, 32,116,111, 32, 97, 32, +115,105,110,107, 44, 32,117,115,105,110,103, 32, 97, 32,115,116,101,112, 32,102, +117,110, 99,116,105,111,110, 10,102,117,110, 99,116,105,111,110, 32,112,117,109, +112, 46, 97,108,108, 40,115,114, 99, 44, 32,115,110,107, 44, 32,115,116,101,112, + 41, 10, 32, 32, 32, 32, 98, 97,115,101, 46, 97,115,115,101,114,116, 40,115,114, + 99, 32, 97,110,100, 32,115,110,107, 41, 10, 32, 32, 32, 32,115,116,101,112, 32, + 61, 32,115,116,101,112, 32,111,114, 32,112,117,109,112, 46,115,116,101,112, 10, + 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, 10, 32, 32, + 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,116, 44, 32,101,114,114, + 32, 61, 32,115,116,101,112, 40,115,114, 99, 44, 32,115,110,107, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,116, 32,116,104,101, +110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, + 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114, +114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114, +101,116,117,114,110, 32, 49, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, +101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/src/libs/luasocket/src/lua_preload.c b/src/libs/luasocket/src/lua_preload.c new file mode 100644 index 000000000..8e27995a4 --- /dev/null +++ b/src/libs/luasocket/src/lua_preload.c @@ -0,0 +1,73 @@ + +#include <stdlib.h> +#include "lua.h" +#include "lauxlib.h" + +#include "socket_lua.c" +#include "ftp_lua.c" +#include "http_lua.c" +#include "smtp_lua.c" +#include "tp_lua.c" +#include "url_lua.c" +#include "ltn12_lua.c" +#include "mime_lua.c" + + +void luatex_socketlua_open (lua_State *L) { + lua_getglobal(L, "package"); + lua_getfield(L, -1, "loaded"); + if (!lua_istable(L,-1)) { + lua_newtable(L); + lua_setfield(L, -2, "loaded"); + lua_getfield(L, -1, "loaded"); + } + if(!luatex_socket_lua_open(L)) { + lua_setfield(L, -2, "socket"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + if(!luatex_ltn12_lua_open(L)) { + lua_setfield(L, -2, "ltn12"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + if(!luatex_mime_lua_open(L)) { + lua_setfield(L, -2, "mime"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + if(!luatex_url_lua_open(L)) { + lua_setfield(L, -2, "socket.url"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + if(!luatex_tp_lua_open(L)) { + lua_setfield(L, -2, "socket.tp"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + if(!luatex_smtp_lua_open(L)) { + lua_setfield(L, -2, "socket.smtp"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + if(!luatex_http_lua_open(L)) { + lua_setfield(L, -2, "socket.http"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + if(!luatex_ftp_lua_open(L)) { + lua_setfield(L, -2, "socket.ftp"); + } else { + fprintf(stderr,"FATAL error while preloading lua modules"); + exit(1); + } + lua_pop(L,2); +} diff --git a/src/libs/luasocket/src/luasocket.c b/src/libs/luasocket/src/luasocket.c new file mode 100644 index 000000000..11ffee94c --- /dev/null +++ b/src/libs/luasocket/src/luasocket.c @@ -0,0 +1,118 @@ +/*=========================================================================*\ +* LuaSocket toolkit +* Networking support for the Lua language +* Diego Nehab +* 26/11/1999 +* +* This library is part of an effort to progressively increase the network +* connectivity of the Lua language. The Lua interface to networking +* functions follows the Sockets API closely, trying to simplify all tasks +* involved in setting up both client and server connections. The provided +* IO routines, however, follow the Lua style, being very similar to the +* standard Lua read and write functions. +* +* RCS ID: $Id: luasocket.c,v 1.53 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ + +/*=========================================================================*\ +* Standard include files +\*=========================================================================*/ +#include "lua.h" +#include "lauxlib.h" + +#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) +#include "compat-5.1.h" +#endif + +/*=========================================================================*\ +* LuaSocket includes +\*=========================================================================*/ +#include "luasocket.h" +#include "auxiliar.h" +#include "except.h" +#include "timeout.h" +#include "buffer.h" +#include "inet.h" +#include "tcp.h" +#include "udp.h" +#include "select.h" + +/*-------------------------------------------------------------------------*\ +* Internal function prototypes +\*-------------------------------------------------------------------------*/ +static int global_skip(lua_State *L); +static int global_unload(lua_State *L); +static int base_open(lua_State *L); + +/*-------------------------------------------------------------------------*\ +* Modules and functions +\*-------------------------------------------------------------------------*/ +static const luaL_reg mod[] = { + {"auxiliar", auxiliar_open}, + {"except", except_open}, + {"timeout", timeout_open}, + {"buffer", buffer_open}, + {"inet", inet_open}, + {"tcp", tcp_open}, + {"udp", udp_open}, + {"select", select_open}, + {NULL, NULL} +}; + +static luaL_reg func[] = { + {"skip", global_skip}, + {"__unload", global_unload}, + {NULL, NULL} +}; + +/*-------------------------------------------------------------------------*\ +* Skip a few arguments +\*-------------------------------------------------------------------------*/ +static int global_skip(lua_State *L) { + int amount = luaL_checkint(L, 1); + int ret = lua_gettop(L) - amount - 1; + return ret >= 0 ? ret : 0; +} + +/*-------------------------------------------------------------------------*\ +* Unloads the library +\*-------------------------------------------------------------------------*/ +static int global_unload(lua_State *L) { + (void) L; + socket_close(); + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Setup basic stuff. +\*-------------------------------------------------------------------------*/ +static int base_open(lua_State *L) { + if (socket_open()) { + /* export functions (and leave namespace table on top of stack) */ + luaL_openlib(L, "socket", func, 0); +#ifdef LUASOCKET_DEBUG + lua_pushstring(L, "_DEBUG"); + lua_pushboolean(L, 1); + lua_rawset(L, -3); +#endif + /* make version string available to scripts */ + lua_pushstring(L, "_VERSION"); + lua_pushstring(L, LUASOCKET_VERSION); + lua_rawset(L, -3); + return 1; + } else { + lua_pushstring(L, "unable to initialize library"); + lua_error(L); + return 0; + } +} + +/*-------------------------------------------------------------------------*\ +* Initializes all library modules. +\*-------------------------------------------------------------------------*/ +LUASOCKET_API int luaopen_socket_core(lua_State *L) { + int i; + base_open(L); + for (i = 0; mod[i].name; i++) mod[i].func(L); + return 1; +} diff --git a/src/libs/luasocket/src/luasocket.h b/src/libs/luasocket/src/luasocket.h new file mode 100644 index 000000000..67270abb9 --- /dev/null +++ b/src/libs/luasocket/src/luasocket.h @@ -0,0 +1,32 @@ +#ifndef LUASOCKET_H +#define LUASOCKET_H +/*=========================================================================*\ +* LuaSocket toolkit +* Networking support for the Lua language +* Diego Nehab +* 9/11/1999 +* +* RCS ID: $Id: luasocket.h,v 1.25 2007/06/11 23:44:54 diego Exp $ +\*=========================================================================*/ +#include "lua.h" + +/*-------------------------------------------------------------------------*\ +* Current socket library version +\*-------------------------------------------------------------------------*/ +#define LUASOCKET_VERSION "LuaSocket 2.0.2" +#define LUASOCKET_COPYRIGHT "Copyright (C) 2004-2007 Diego Nehab" +#define LUASOCKET_AUTHORS "Diego Nehab" + +/*-------------------------------------------------------------------------*\ +* This macro prefixes all exported API functions +\*-------------------------------------------------------------------------*/ +#ifndef LUASOCKET_API +#define LUASOCKET_API extern +#endif + +/*-------------------------------------------------------------------------*\ +* Initializes the library. +\*-------------------------------------------------------------------------*/ +LUASOCKET_API int luaopen_socket_core(lua_State *L); + +#endif /* LUASOCKET_H */ diff --git a/src/libs/luasocket/src/makefile.orig b/src/libs/luasocket/src/makefile.orig new file mode 100644 index 000000000..b614f77bc --- /dev/null +++ b/src/libs/luasocket/src/makefile.orig @@ -0,0 +1,90 @@ +#------ +# Load configuration +# +include ../config + +#------ +# Hopefully no need to change anything below this line +# + +#------ +# Modules belonging to socket-core +# + +#$(COMPAT)/compat-5.1.o \ + +SOCKET_OBJS:= \ + luasocket.o \ + timeout.o \ + buffer.o \ + io.o \ + auxiliar.o \ + options.o \ + inet.o \ + tcp.o \ + udp.o \ + except.o \ + select.o \ + usocket.o + +#------ +# Modules belonging mime-core +# +#$(COMPAT)/compat-5.1.o \ + +MIME_OBJS:=\ + mime.o + +#------ +# Modules belonging unix (local domain sockets) +# +UNIX_OBJS:=\ + buffer.o \ + auxiliar.o \ + options.o \ + timeout.o \ + io.o \ + usocket.o \ + unix.o + +all: $(SOCKET_SO) $(MIME_SO) + +$(SOCKET_SO): $(SOCKET_OBJS) + $(LD) $(LDFLAGS) -o $@ $(SOCKET_OBJS) + +$(MIME_SO): $(MIME_OBJS) + $(LD) $(LDFLAGS) -o $@ $(MIME_OBJS) + +$(UNIX_SO): $(UNIX_OBJS) + $(LD) $(LDFLAGS) -o $@ $(UNIX_OBJS) + +#------ +# List of dependencies +# +auxiliar.o: auxiliar.c auxiliar.h +buffer.o: buffer.c buffer.h io.h timeout.h +except.o: except.c except.h +inet.o: inet.c inet.h socket.h io.h timeout.h usocket.h +io.o: io.c io.h timeout.h +luasocket.o: luasocket.c luasocket.h auxiliar.h except.h timeout.h \ + buffer.h io.h inet.h socket.h usocket.h tcp.h udp.h select.h +mime.o: mime.c mime.h +options.o: options.c auxiliar.h options.h socket.h io.h timeout.h \ + usocket.h inet.h +select.o: select.c socket.h io.h timeout.h usocket.h select.h +tcp.o: tcp.c auxiliar.h socket.h io.h timeout.h usocket.h inet.h \ + options.h tcp.h buffer.h +timeout.o: timeout.c auxiliar.h timeout.h +udp.o: udp.c auxiliar.h socket.h io.h timeout.h usocket.h inet.h \ + options.h udp.h +unix.o: unix.c auxiliar.h socket.h io.h timeout.h usocket.h options.h \ + unix.h buffer.h +usocket.o: usocket.c socket.h io.h timeout.h usocket.h + +clean: + rm -f $(SOCKET_SO) $(SOCKET_OBJS) + rm -f $(MIME_SO) $(UNIX_SO) $(MIME_OBJS) $(UNIX_OBJS) + +#------ +# End of makefile configuration +# diff --git a/src/libs/luasocket/src/mime.c b/src/libs/luasocket/src/mime.c new file mode 100644 index 000000000..700fa05e9 --- /dev/null +++ b/src/libs/luasocket/src/mime.c @@ -0,0 +1,711 @@ +/*=========================================================================*\ +* MIME support functions +* LuaSocket toolkit +* +* RCS ID: $Id: mime.c,v 1.28 2005/11/20 07:20:23 diego Exp $ +\*=========================================================================*/ +#include <string.h> + +#include "lua.h" +#include "lauxlib.h" + +#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) +#include "compat-5.1.h" +#endif + +#include "mime.h" + +/*=========================================================================*\ +* Don't want to trust escape character constants +\*=========================================================================*/ +typedef unsigned char UC; +static const char CRLF[] = "\r\n"; +static const char EQCRLF[] = "=\r\n"; + +/*=========================================================================*\ +* Internal function prototypes. +\*=========================================================================*/ +static int mime_global_wrp(lua_State *L); +static int mime_global_b64(lua_State *L); +static int mime_global_unb64(lua_State *L); +static int mime_global_qp(lua_State *L); +static int mime_global_unqp(lua_State *L); +static int mime_global_qpwrp(lua_State *L); +static int mime_global_eol(lua_State *L); +static int mime_global_dot(lua_State *L); + +static size_t dot(int c, size_t state, luaL_Buffer *buffer); +static void b64setup(UC *b64unbase); +static size_t b64encode(UC c, UC *input, size_t size, luaL_Buffer *buffer); +static size_t b64pad(const UC *input, size_t size, luaL_Buffer *buffer); +static size_t b64decode(UC c, UC *input, size_t size, luaL_Buffer *buffer); + +static void qpsetup(UC *qpclass, UC *qpunbase); +static void qpquote(UC c, luaL_Buffer *buffer); +static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer); +static size_t qpencode(UC c, UC *input, size_t size, + const char *marker, luaL_Buffer *buffer); +static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer); + +/* code support functions */ +static luaL_reg func[] = { + { "dot", mime_global_dot }, + { "b64", mime_global_b64 }, + { "eol", mime_global_eol }, + { "qp", mime_global_qp }, + { "qpwrp", mime_global_qpwrp }, + { "unb64", mime_global_unb64 }, + { "unqp", mime_global_unqp }, + { "wrp", mime_global_wrp }, + { NULL, NULL } +}; + +/*-------------------------------------------------------------------------*\ +* Quoted-printable globals +\*-------------------------------------------------------------------------*/ +static UC qpclass[256]; +static UC qpbase[] = "0123456789ABCDEF"; +static UC qpunbase[256]; +enum {QP_PLAIN, QP_QUOTED, QP_CR, QP_IF_LAST}; + +/*-------------------------------------------------------------------------*\ +* Base64 globals +\*-------------------------------------------------------------------------*/ +static const UC b64base[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static UC b64unbase[256]; + +/*=========================================================================*\ +* Exported functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +MIME_API int luaopen_mime_core(lua_State *L) +{ + luaL_openlib(L, "mime", func, 0); + /* make version string available to scripts */ + lua_pushstring(L, "_VERSION"); + lua_pushstring(L, MIME_VERSION); + lua_rawset(L, -3); + /* initialize lookup tables */ + qpsetup(qpclass, qpunbase); + b64setup(b64unbase); + return 1; +} + +/*=========================================================================*\ +* Global Lua functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Incrementaly breaks a string into lines. The string can have CRLF breaks. +* A, n = wrp(l, B, length) +* A is a copy of B, broken into lines of at most 'length' bytes. +* 'l' is how many bytes are left for the first line of B. +* 'n' is the number of bytes left in the last line of A. +\*-------------------------------------------------------------------------*/ +static int mime_global_wrp(lua_State *L) +{ + size_t size = 0; + int left = (int) luaL_checknumber(L, 1); + const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size); + const UC *last = input + size; + int length = (int) luaL_optnumber(L, 3, 76); + luaL_Buffer buffer; + /* end of input black-hole */ + if (!input) { + /* if last line has not been terminated, add a line break */ + if (left < length) lua_pushstring(L, CRLF); + /* otherwise, we are done */ + else lua_pushnil(L); + lua_pushnumber(L, length); + return 2; + } + luaL_buffinit(L, &buffer); + while (input < last) { + switch (*input) { + case '\r': + break; + case '\n': + luaL_addstring(&buffer, CRLF); + left = length; + break; + default: + if (left <= 0) { + left = length; + luaL_addstring(&buffer, CRLF); + } + luaL_putchar(&buffer, *input); + left--; + break; + } + input++; + } + luaL_pushresult(&buffer); + lua_pushnumber(L, left); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Fill base64 decode map. +\*-------------------------------------------------------------------------*/ +static void b64setup(UC *b64unbase) +{ + int i; + for (i = 0; i <= 255; i++) b64unbase[i] = (UC) 255; + for (i = 0; i < 64; i++) b64unbase[b64base[i]] = (UC) i; + b64unbase['='] = 0; +} + +/*-------------------------------------------------------------------------*\ +* Acumulates bytes in input buffer until 3 bytes are available. +* Translate the 3 bytes into Base64 form and append to buffer. +* Returns new number of bytes in buffer. +\*-------------------------------------------------------------------------*/ +static size_t b64encode(UC c, UC *input, size_t size, + luaL_Buffer *buffer) +{ + input[size++] = c; + if (size == 3) { + UC code[4]; + unsigned long value = 0; + value += input[0]; value <<= 8; + value += input[1]; value <<= 8; + value += input[2]; + code[3] = b64base[value & 0x3f]; value >>= 6; + code[2] = b64base[value & 0x3f]; value >>= 6; + code[1] = b64base[value & 0x3f]; value >>= 6; + code[0] = b64base[value]; + luaL_addlstring(buffer, (char *) code, 4); + size = 0; + } + return size; +} + +/*-------------------------------------------------------------------------*\ +* Encodes the Base64 last 1 or 2 bytes and adds padding '=' +* Result, if any, is appended to buffer. +* Returns 0. +\*-------------------------------------------------------------------------*/ +static size_t b64pad(const UC *input, size_t size, + luaL_Buffer *buffer) +{ + unsigned long value = 0; + UC code[4] = {'=', '=', '=', '='}; + switch (size) { + case 1: + value = input[0] << 4; + code[1] = b64base[value & 0x3f]; value >>= 6; + code[0] = b64base[value]; + luaL_addlstring(buffer, (char *) code, 4); + break; + case 2: + value = input[0]; value <<= 8; + value |= input[1]; value <<= 2; + code[2] = b64base[value & 0x3f]; value >>= 6; + code[1] = b64base[value & 0x3f]; value >>= 6; + code[0] = b64base[value]; + luaL_addlstring(buffer, (char *) code, 4); + break; + default: + break; + } + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Acumulates bytes in input buffer until 4 bytes are available. +* Translate the 4 bytes from Base64 form and append to buffer. +* Returns new number of bytes in buffer. +\*-------------------------------------------------------------------------*/ +static size_t b64decode(UC c, UC *input, size_t size, + luaL_Buffer *buffer) +{ + /* ignore invalid characters */ + if (b64unbase[c] > 64) return size; + input[size++] = c; + /* decode atom */ + if (size == 4) { + UC decoded[3]; + int valid, value = 0; + value = b64unbase[input[0]]; value <<= 6; + value |= b64unbase[input[1]]; value <<= 6; + value |= b64unbase[input[2]]; value <<= 6; + value |= b64unbase[input[3]]; + decoded[2] = (UC) (value & 0xff); value >>= 8; + decoded[1] = (UC) (value & 0xff); value >>= 8; + decoded[0] = (UC) value; + /* take care of paddding */ + valid = (input[2] == '=') ? 1 : (input[3] == '=') ? 2 : 3; + luaL_addlstring(buffer, (char *) decoded, valid); + return 0; + /* need more data */ + } else return size; +} + +/*-------------------------------------------------------------------------*\ +* Incrementally applies the Base64 transfer content encoding to a string +* A, B = b64(C, D) +* A is the encoded version of the largest prefix of C .. D that is +* divisible by 3. B has the remaining bytes of C .. D, *without* encoding. +* The easiest thing would be to concatenate the two strings and +* encode the result, but we can't afford that or Lua would dupplicate +* every chunk we received. +\*-------------------------------------------------------------------------*/ +static int mime_global_b64(lua_State *L) +{ + UC atom[3]; + size_t isize = 0, asize = 0; + const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *last = input + isize; + luaL_Buffer buffer; + /* end-of-input blackhole */ + if (!input) { + lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* process first part of the input */ + luaL_buffinit(L, &buffer); + while (input < last) + asize = b64encode(*input++, atom, asize, &buffer); + input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + /* if second part is nil, we are done */ + if (!input) { + asize = b64pad(atom, asize, &buffer); + luaL_pushresult(&buffer); + if (!(*lua_tostring(L, -1))) lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* otherwise process the second part */ + last = input + isize; + while (input < last) + asize = b64encode(*input++, atom, asize, &buffer); + luaL_pushresult(&buffer); + lua_pushlstring(L, (char *) atom, asize); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Incrementally removes the Base64 transfer content encoding from a string +* A, B = b64(C, D) +* A is the encoded version of the largest prefix of C .. D that is +* divisible by 4. B has the remaining bytes of C .. D, *without* encoding. +\*-------------------------------------------------------------------------*/ +static int mime_global_unb64(lua_State *L) +{ + UC atom[4]; + size_t isize = 0, asize = 0; + const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *last = input + isize; + luaL_Buffer buffer; + /* end-of-input blackhole */ + if (!input) { + lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* process first part of the input */ + luaL_buffinit(L, &buffer); + while (input < last) + asize = b64decode(*input++, atom, asize, &buffer); + input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + /* if second is nil, we are done */ + if (!input) { + luaL_pushresult(&buffer); + if (!(*lua_tostring(L, -1))) lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* otherwise, process the rest of the input */ + last = input + isize; + while (input < last) + asize = b64decode(*input++, atom, asize, &buffer); + luaL_pushresult(&buffer); + lua_pushlstring(L, (char *) atom, asize); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Quoted-printable encoding scheme +* all (except CRLF in text) can be =XX +* CLRL in not text must be =XX=XX +* 33 through 60 inclusive can be plain +* 62 through 126 inclusive can be plain +* 9 and 32 can be plain, unless in the end of a line, where must be =XX +* encoded lines must be no longer than 76 not counting CRLF +* soft line-break are =CRLF +* To encode one byte, we need to see the next two. +* Worst case is when we see a space, and wonder if a CRLF is comming +\*-------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------*\ +* Split quoted-printable characters into classes +* Precompute reverse map for encoding +\*-------------------------------------------------------------------------*/ +static void qpsetup(UC *qpclass, UC *qpunbase) +{ + int i; + for (i = 0; i < 256; i++) qpclass[i] = QP_QUOTED; + for (i = 33; i <= 60; i++) qpclass[i] = QP_PLAIN; + for (i = 62; i <= 126; i++) qpclass[i] = QP_PLAIN; + qpclass['\t'] = QP_IF_LAST; + qpclass[' '] = QP_IF_LAST; + qpclass['\r'] = QP_CR; + for (i = 0; i < 256; i++) qpunbase[i] = 255; + qpunbase['0'] = 0; qpunbase['1'] = 1; qpunbase['2'] = 2; + qpunbase['3'] = 3; qpunbase['4'] = 4; qpunbase['5'] = 5; + qpunbase['6'] = 6; qpunbase['7'] = 7; qpunbase['8'] = 8; + qpunbase['9'] = 9; qpunbase['A'] = 10; qpunbase['a'] = 10; + qpunbase['B'] = 11; qpunbase['b'] = 11; qpunbase['C'] = 12; + qpunbase['c'] = 12; qpunbase['D'] = 13; qpunbase['d'] = 13; + qpunbase['E'] = 14; qpunbase['e'] = 14; qpunbase['F'] = 15; + qpunbase['f'] = 15; +} + +/*-------------------------------------------------------------------------*\ +* Output one character in form =XX +\*-------------------------------------------------------------------------*/ +static void qpquote(UC c, luaL_Buffer *buffer) +{ + luaL_putchar(buffer, '='); + luaL_putchar(buffer, qpbase[c >> 4]); + luaL_putchar(buffer, qpbase[c & 0x0F]); +} + +/*-------------------------------------------------------------------------*\ +* Accumulate characters until we are sure about how to deal with them. +* Once we are sure, output to the buffer, in the correct form. +\*-------------------------------------------------------------------------*/ +static size_t qpencode(UC c, UC *input, size_t size, + const char *marker, luaL_Buffer *buffer) +{ + input[size++] = c; + /* deal with all characters we can have */ + while (size > 0) { + switch (qpclass[input[0]]) { + /* might be the CR of a CRLF sequence */ + case QP_CR: + if (size < 2) return size; + if (input[1] == '\n') { + luaL_addstring(buffer, marker); + return 0; + } else qpquote(input[0], buffer); + break; + /* might be a space and that has to be quoted if last in line */ + case QP_IF_LAST: + if (size < 3) return size; + /* if it is the last, quote it and we are done */ + if (input[1] == '\r' && input[2] == '\n') { + qpquote(input[0], buffer); + luaL_addstring(buffer, marker); + return 0; + } else luaL_putchar(buffer, input[0]); + break; + /* might have to be quoted always */ + case QP_QUOTED: + qpquote(input[0], buffer); + break; + /* might never have to be quoted */ + default: + luaL_putchar(buffer, input[0]); + break; + } + input[0] = input[1]; input[1] = input[2]; + size--; + } + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Deal with the final characters +\*-------------------------------------------------------------------------*/ +static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer) +{ + size_t i; + for (i = 0; i < size; i++) { + if (qpclass[input[i]] == QP_PLAIN) luaL_putchar(buffer, input[i]); + else qpquote(input[i], buffer); + } + if (size > 0) luaL_addstring(buffer, EQCRLF); + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Incrementally converts a string to quoted-printable +* A, B = qp(C, D, marker) +* Marker is the text to be used to replace CRLF sequences found in A. +* A is the encoded version of the largest prefix of C .. D that +* can be encoded without doubts. +* B has the remaining bytes of C .. D, *without* encoding. +\*-------------------------------------------------------------------------*/ +static int mime_global_qp(lua_State *L) +{ + + size_t asize = 0, isize = 0; + UC atom[3]; + const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *last = input + isize; + const char *marker = luaL_optstring(L, 3, CRLF); + luaL_Buffer buffer; + /* end-of-input blackhole */ + if (!input) { + lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* process first part of input */ + luaL_buffinit(L, &buffer); + while (input < last) + asize = qpencode(*input++, atom, asize, marker, &buffer); + input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + /* if second part is nil, we are done */ + if (!input) { + asize = qppad(atom, asize, &buffer); + luaL_pushresult(&buffer); + if (!(*lua_tostring(L, -1))) lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* otherwise process rest of input */ + last = input + isize; + while (input < last) + asize = qpencode(*input++, atom, asize, marker, &buffer); + luaL_pushresult(&buffer); + lua_pushlstring(L, (char *) atom, asize); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Accumulate characters until we are sure about how to deal with them. +* Once we are sure, output the to the buffer, in the correct form. +\*-------------------------------------------------------------------------*/ +static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) { + int d; + input[size++] = c; + /* deal with all characters we can deal */ + switch (input[0]) { + /* if we have an escape character */ + case '=': + if (size < 3) return size; + /* eliminate soft line break */ + if (input[1] == '\r' && input[2] == '\n') return 0; + /* decode quoted representation */ + c = qpunbase[input[1]]; d = qpunbase[input[2]]; + /* if it is an invalid, do not decode */ + if (c > 15 || d > 15) luaL_addlstring(buffer, (char *)input, 3); + else luaL_putchar(buffer, (c << 4) + d); + return 0; + case '\r': + if (size < 2) return size; + if (input[1] == '\n') luaL_addlstring(buffer, (char *)input, 2); + return 0; + default: + if (input[0] == '\t' || (input[0] > 31 && input[0] < 127)) + luaL_putchar(buffer, input[0]); + return 0; + } +} + +/*-------------------------------------------------------------------------*\ +* Incrementally decodes a string in quoted-printable +* A, B = qp(C, D) +* A is the decoded version of the largest prefix of C .. D that +* can be decoded without doubts. +* B has the remaining bytes of C .. D, *without* decoding. +\*-------------------------------------------------------------------------*/ +static int mime_global_unqp(lua_State *L) +{ + size_t asize = 0, isize = 0; + UC atom[3]; + const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); + const UC *last = input + isize; + luaL_Buffer buffer; + /* end-of-input blackhole */ + if (!input) { + lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* process first part of input */ + luaL_buffinit(L, &buffer); + while (input < last) + asize = qpdecode(*input++, atom, asize, &buffer); + input = (UC *) luaL_optlstring(L, 2, NULL, &isize); + /* if second part is nil, we are done */ + if (!input) { + luaL_pushresult(&buffer); + if (!(*lua_tostring(L, -1))) lua_pushnil(L); + lua_pushnil(L); + return 2; + } + /* otherwise process rest of input */ + last = input + isize; + while (input < last) + asize = qpdecode(*input++, atom, asize, &buffer); + luaL_pushresult(&buffer); + lua_pushlstring(L, (char *) atom, asize); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Incrementally breaks a quoted-printed string into lines +* A, n = qpwrp(l, B, length) +* A is a copy of B, broken into lines of at most 'length' bytes. +* 'l' is how many bytes are left for the first line of B. +* 'n' is the number of bytes left in the last line of A. +* There are two complications: lines can't be broken in the middle +* of an encoded =XX, and there might be line breaks already +\*-------------------------------------------------------------------------*/ +static int mime_global_qpwrp(lua_State *L) +{ + size_t size = 0; + int left = (int) luaL_checknumber(L, 1); + const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size); + const UC *last = input + size; + int length = (int) luaL_optnumber(L, 3, 76); + luaL_Buffer buffer; + /* end-of-input blackhole */ + if (!input) { + if (left < length) lua_pushstring(L, EQCRLF); + else lua_pushnil(L); + lua_pushnumber(L, length); + return 2; + } + /* process all input */ + luaL_buffinit(L, &buffer); + while (input < last) { + switch (*input) { + case '\r': + break; + case '\n': + left = length; + luaL_addstring(&buffer, CRLF); + break; + case '=': + if (left <= 3) { + left = length; + luaL_addstring(&buffer, EQCRLF); + } + luaL_putchar(&buffer, *input); + left--; + break; + default: + if (left <= 1) { + left = length; + luaL_addstring(&buffer, EQCRLF); + } + luaL_putchar(&buffer, *input); + left--; + break; + } + input++; + } + luaL_pushresult(&buffer); + lua_pushnumber(L, left); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Here is what we do: \n, and \r are considered candidates for line +* break. We issue *one* new line marker if any of them is seen alone, or +* followed by a different one. That is, \n\n and \r\r will issue two +* end of line markers each, but \r\n, \n\r etc will only issue *one* +* marker. This covers Mac OS, Mac OS X, VMS, Unix and DOS, as well as +* probably other more obscure conventions. +* +* c is the current character being processed +* last is the previous character +\*-------------------------------------------------------------------------*/ +#define eolcandidate(c) (c == '\r' || c == '\n') +static int eolprocess(int c, int last, const char *marker, + luaL_Buffer *buffer) +{ + if (eolcandidate(c)) { + if (eolcandidate(last)) { + if (c == last) luaL_addstring(buffer, marker); + return 0; + } else { + luaL_addstring(buffer, marker); + return c; + } + } else { + luaL_putchar(buffer, c); + return 0; + } +} + +/*-------------------------------------------------------------------------*\ +* Converts a string to uniform EOL convention. +* A, n = eol(o, B, marker) +* A is the converted version of the largest prefix of B that can be +* converted unambiguously. 'o' is the context returned by the previous +* call. 'n' is the new context. +\*-------------------------------------------------------------------------*/ +static int mime_global_eol(lua_State *L) +{ + int ctx = luaL_checkint(L, 1); + size_t isize = 0; + const char *input = luaL_optlstring(L, 2, NULL, &isize); + const char *last = input + isize; + const char *marker = luaL_optstring(L, 3, CRLF); + luaL_Buffer buffer; + luaL_buffinit(L, &buffer); + /* end of input blackhole */ + if (!input) { + lua_pushnil(L); + lua_pushnumber(L, 0); + return 2; + } + /* process all input */ + while (input < last) + ctx = eolprocess(*input++, ctx, marker, &buffer); + luaL_pushresult(&buffer); + lua_pushnumber(L, ctx); + return 2; +} + +/*-------------------------------------------------------------------------*\ +* Takes one byte and stuff it if needed. +\*-------------------------------------------------------------------------*/ +static size_t dot(int c, size_t state, luaL_Buffer *buffer) +{ + luaL_putchar(buffer, c); + switch (c) { + case '\r': + return 1; + case '\n': + return (state == 1)? 2: 0; + case '.': + if (state == 2) + luaL_putchar(buffer, '.'); + default: + return 0; + } +} + +/*-------------------------------------------------------------------------*\ +* Incrementally applies smtp stuffing to a string +* A, n = dot(l, D) +\*-------------------------------------------------------------------------*/ +static int mime_global_dot(lua_State *L) +{ + size_t isize = 0, state = (size_t) luaL_checknumber(L, 1); + const char *input = luaL_optlstring(L, 2, NULL, &isize); + const char *last = input + isize; + luaL_Buffer buffer; + /* end-of-input blackhole */ + if (!input) { + lua_pushnil(L); + lua_pushnumber(L, 2); + return 2; + } + /* process all input */ + luaL_buffinit(L, &buffer); + while (input < last) + state = dot(*input++, state, &buffer); + luaL_pushresult(&buffer); + lua_pushnumber(L, state); + return 2; +} + diff --git a/src/libs/luasocket/src/mime.h b/src/libs/luasocket/src/mime.h new file mode 100644 index 000000000..85ee2a398 --- /dev/null +++ b/src/libs/luasocket/src/mime.h @@ -0,0 +1,31 @@ +#ifndef MIME_H +#define MIME_H +/*=========================================================================*\ +* Core MIME support +* LuaSocket toolkit +* +* This module provides functions to implement transfer content encodings +* and formatting conforming to RFC 2045. It is used by mime.lua, which +* provide a higher level interface to this functionality. +* +* RCS ID: $Id: mime.h,v 1.15 2007/06/11 23:44:54 diego Exp $ +\*=========================================================================*/ +#include "lua.h" + +/*-------------------------------------------------------------------------*\ +* Current MIME library version +\*-------------------------------------------------------------------------*/ +#define MIME_VERSION "MIME 1.0.2" +#define MIME_COPYRIGHT "Copyright (C) 2004-2007 Diego Nehab" +#define MIME_AUTHORS "Diego Nehab" + +/*-------------------------------------------------------------------------*\ +* This macro prefixes all exported API functions +\*-------------------------------------------------------------------------*/ +#ifndef MIME_API +#define MIME_API extern +#endif + +MIME_API int luaopen_mime_core(lua_State *L); + +#endif /* MIME_H */ diff --git a/src/libs/luasocket/src/mime.lua b/src/libs/luasocket/src/mime.lua new file mode 100644 index 000000000..169eda29a --- /dev/null +++ b/src/libs/luasocket/src/mime.lua @@ -0,0 +1,87 @@ +----------------------------------------------------------------------------- +-- MIME support for the Lua language. +-- Author: Diego Nehab +-- Conforming to RFCs 2045-2049 +-- RCS ID: $Id: mime.lua,v 1.29 2007/06/11 23:44:54 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local ltn12 = require("ltn12") +local mime = require("mime.core") +local io = require("io") +local string = require("string") +module("mime") + +-- encode, decode and wrap algorithm tables +encodet = {} +decodet = {} +wrapt = {} + +-- creates a function that chooses a filter by name from a given table +local function choose(table) + return function(name, opt1, opt2) + if base.type(name) ~= "string" then + name, opt1, opt2 = "default", name, opt1 + end + local f = table[name or "nil"] + if not f then + base.error("unknown key (" .. base.tostring(name) .. ")", 3) + else return f(opt1, opt2) end + end +end + +-- define the encoding filters +encodet['base64'] = function() + return ltn12.filter.cycle(b64, "") +end + +encodet['quoted-printable'] = function(mode) + return ltn12.filter.cycle(qp, "", + (mode == "binary") and "=0D=0A" or "\r\n") +end + +-- define the decoding filters +decodet['base64'] = function() + return ltn12.filter.cycle(unb64, "") +end + +decodet['quoted-printable'] = function() + return ltn12.filter.cycle(unqp, "") +end + +local function format(chunk) + if chunk then + if chunk == "" then return "''" + else return string.len(chunk) end + else return "nil" end +end + +-- define the line-wrap filters +wrapt['text'] = function(length) + length = length or 76 + return ltn12.filter.cycle(wrp, length, length) +end +wrapt['base64'] = wrapt['text'] +wrapt['default'] = wrapt['text'] + +wrapt['quoted-printable'] = function() + return ltn12.filter.cycle(qpwrp, 76, 76) +end + +-- function that choose the encoding, decoding or wrap algorithm +encode = choose(encodet) +decode = choose(decodet) +wrap = choose(wrapt) + +-- define the end-of-line normalization filter +function normalize(marker) + return ltn12.filter.cycle(eol, 0, marker) +end + +-- high level stuffing filter +function stuff() + return ltn12.filter.cycle(dot, 2) +end diff --git a/src/libs/luasocket/src/mime_lua.c b/src/libs/luasocket/src/mime_lua.c new file mode 100644 index 000000000..e131536a8 --- /dev/null +++ b/src/libs/luasocket/src/mime_lua.c @@ -0,0 +1,135 @@ +/* + * This file is auto-generated by "./lua2c mime.lua mime_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_mime_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 77, 73, 77, 69, 32,115,117,112,112,111,114,116, 32,102,111,114, 32,116,104, +101, 32, 76,117, 97, 32,108, 97,110,103,117, 97,103,101, 46, 10, 45, 45, 32, 65, +117,116,104,111,114, 58, 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, + 45, 32, 67,111,110,102,111,114,109,105,110,103, 32,116,111, 32, 82, 70, 67,115, + 32, 50, 48, 52, 53, 45, 50, 48, 52, 57, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, + 58, 32, 36, 73,100, 58, 32,109,105,109,101, 46,108,117, 97, 44,118, 32, 49, 46, + 50, 57, 32, 50, 48, 48, 55, 47, 48, 54, 47, 49, 49, 32, 50, 51, 58, 52, 52, 58, + 53, 52, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97, +114,101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, + 32,100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97, +115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,108,116,110, 49, 50, 32, + 61, 32,114,101,113,117,105,114,101, 40, 34,108,116,110, 49, 50, 34, 41, 10,108, +111, 99, 97,108, 32,109,105,109,101, 32, 61, 32,114,101,113,117,105,114,101, 40, + 34,109,105,109,101, 46, 99,111,114,101, 34, 41, 10,108,111, 99, 97,108, 32,105, +111, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,105,111, 34, 41, 10,108,111, + 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114,101,113,117,105,114,101, + 40, 34,115,116,114,105,110,103, 34, 41, 10,109,111,100,117,108,101, 40, 34,109, +105,109,101, 34, 41, 10, 10, 45, 45, 32,101,110, 99,111,100,101, 44, 32,100,101, + 99,111,100,101, 32, 97,110,100, 32,119,114, 97,112, 32, 97,108,103,111,114,105, +116,104,109, 32,116, 97, 98,108,101,115, 10,101,110, 99,111,100,101,116, 32, 61, + 32,123,125, 10,100,101, 99,111,100,101,116, 32, 61, 32,123,125, 10,119,114, 97, +112,116, 32, 61, 32,123,125, 10, 10, 45, 45, 32, 99,114,101, 97,116,101,115, 32, + 97, 32,102,117,110, 99,116,105,111,110, 32,116,104, 97,116, 32, 99,104,111,111, +115,101,115, 32, 97, 32,102,105,108,116,101,114, 32, 98,121, 32,110, 97,109,101, + 32,102,114,111,109, 32, 97, 32,103,105,118,101,110, 32,116, 97, 98,108,101, 10, +108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, 99,104,111,111,115, +101, 40,116, 97, 98,108,101, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, +102,117,110, 99,116,105,111,110, 40,110, 97,109,101, 44, 32,111,112,116, 49, 44, + 32,111,112,116, 50, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 98, 97, +115,101, 46,116,121,112,101, 40,110, 97,109,101, 41, 32,126, 61, 32, 34,115,116, +114,105,110,103, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,110, 97,109,101, 44, 32,111,112,116, 49, 44, 32,111,112,116, 50, 32, + 61, 32, 34,100,101,102, 97,117,108,116, 34, 44, 32,110, 97,109,101, 44, 32,111, +112,116, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32,108,111, 99, 97,108, 32,102, 32, 61, 32,116, 97, 98,108,101, 91, +110, 97,109,101, 32,111,114, 32, 34,110,105,108, 34, 93, 10, 32, 32, 32, 32, 32, + 32, 32, 32,105,102, 32,110,111,116, 32,102, 32,116,104,101,110, 32, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 46,101,114,114,111,114, + 40, 34,117,110,107,110,111,119,110, 32,107,101,121, 32, 40, 34, 32, 46, 46, 32, + 98, 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110, 97,109,101, 41, 32, + 46, 46, 32, 34, 41, 34, 44, 32, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101, +108,115,101, 32,114,101,116,117,114,110, 32,102, 40,111,112,116, 49, 44, 32,111, +112,116, 50, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, + 10, 10, 45, 45, 32,100,101,102,105,110,101, 32,116,104,101, 32,101,110, 99,111, +100,105,110,103, 32,102,105,108,116,101,114,115, 10,101,110, 99,111,100,101,116, + 91, 39, 98, 97,115,101, 54, 52, 39, 93, 32, 61, 32,102,117,110, 99,116,105,111, +110, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,116,110, 49, 50, + 46,102,105,108,116,101,114, 46, 99,121, 99,108,101, 40, 98, 54, 52, 44, 32, 34, + 34, 41, 10,101,110,100, 10, 10,101,110, 99,111,100,101,116, 91, 39,113,117,111, +116,101,100, 45,112,114,105,110,116, 97, 98,108,101, 39, 93, 32, 61, 32,102,117, +110, 99,116,105,111,110, 40,109,111,100,101, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99, +108,101, 40,113,112, 44, 32, 34, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 40, +109,111,100,101, 32, 61, 61, 32, 34, 98,105,110, 97,114,121, 34, 41, 32, 97,110, +100, 32, 34, 61, 48, 68, 61, 48, 65, 34, 32,111,114, 32, 34, 92,114, 92,110, 34, + 41, 10,101,110,100, 10, 10, 45, 45, 32,100,101,102,105,110,101, 32,116,104,101, + 32,100,101, 99,111,100,105,110,103, 32,102,105,108,116,101,114,115, 10,100,101, + 99,111,100,101,116, 91, 39, 98, 97,115,101, 54, 52, 39, 93, 32, 61, 32,102,117, +110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, +108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108,101, 40,117, +110, 98, 54, 52, 44, 32, 34, 34, 41, 10,101,110,100, 10, 10,100,101, 99,111,100, +101,116, 91, 39,113,117,111,116,101,100, 45,112,114,105,110,116, 97, 98,108,101, + 39, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, +114,101,116,117,114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, + 99,121, 99,108,101, 40,117,110,113,112, 44, 32, 34, 34, 41, 10,101,110,100, 10, + 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,102,111,114,109, + 97,116, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32,105,102, 32, 99,104,117, +110,107, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99, +104,117,110,107, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32,114,101,116,117, +114,110, 32, 34, 39, 39, 34, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, + 32,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,108,101,110, 40, 99, +104,117,110,107, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,108,115,101, 32,114, +101,116,117,114,110, 32, 34,110,105,108, 34, 32,101,110,100, 10,101,110,100, 10, + 10, 45, 45, 32,100,101,102,105,110,101, 32,116,104,101, 32,108,105,110,101, 45, +119,114, 97,112, 32,102,105,108,116,101,114,115, 10,119,114, 97,112,116, 91, 39, +116,101,120,116, 39, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,108,101, +110,103,116,104, 41, 10, 32, 32, 32, 32,108,101,110,103,116,104, 32, 61, 32,108, +101,110,103,116,104, 32,111,114, 32, 55, 54, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108, +101, 40,119,114,112, 44, 32,108,101,110,103,116,104, 44, 32,108,101,110,103,116, +104, 41, 10,101,110,100, 10,119,114, 97,112,116, 91, 39, 98, 97,115,101, 54, 52, + 39, 93, 32, 61, 32,119,114, 97,112,116, 91, 39,116,101,120,116, 39, 93, 10,119, +114, 97,112,116, 91, 39,100,101,102, 97,117,108,116, 39, 93, 32, 61, 32,119,114, + 97,112,116, 91, 39,116,101,120,116, 39, 93, 10, 10,119,114, 97,112,116, 91, 39, +113,117,111,116,101,100, 45,112,114,105,110,116, 97, 98,108,101, 39, 93, 32, 61, + 32,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108, +101, 40,113,112,119,114,112, 44, 32, 55, 54, 44, 32, 55, 54, 41, 10,101,110,100, + 10, 10, 45, 45, 32,102,117,110, 99,116,105,111,110, 32,116,104, 97,116, 32, 99, +104,111,111,115,101, 32,116,104,101, 32,101,110, 99,111,100,105,110,103, 44, 32, +100,101, 99,111,100,105,110,103, 32,111,114, 32,119,114, 97,112, 32, 97,108,103, +111,114,105,116,104,109, 10,101,110, 99,111,100,101, 32, 61, 32, 99,104,111,111, +115,101, 40,101,110, 99,111,100,101,116, 41, 10,100,101, 99,111,100,101, 32, 61, + 32, 99,104,111,111,115,101, 40,100,101, 99,111,100,101,116, 41, 10,119,114, 97, +112, 32, 61, 32, 99,104,111,111,115,101, 40,119,114, 97,112,116, 41, 10, 10, 45, + 45, 32,100,101,102,105,110,101, 32,116,104,101, 32,101,110,100, 45,111,102, 45, +108,105,110,101, 32,110,111,114,109, 97,108,105,122, 97,116,105,111,110, 32,102, +105,108,116,101,114, 10,102,117,110, 99,116,105,111,110, 32,110,111,114,109, 97, +108,105,122,101, 40,109, 97,114,107,101,114, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99, +108,101, 40,101,111,108, 44, 32, 48, 44, 32,109, 97,114,107,101,114, 41, 10,101, +110,100, 10, 10, 45, 45, 32,104,105,103,104, 32,108,101,118,101,108, 32,115,116, +117,102,102,105,110,103, 32,102,105,108,116,101,114, 10,102,117,110, 99,116,105, +111,110, 32,115,116,117,102,102, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32,108,116,110, 49, 50, 46,102,105,108,116,101,114, 46, 99,121, 99,108,101, + 40,100,111,116, 44, 32, 50, 41, 10,101,110,100, 10, + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/src/libs/luasocket/src/options.c b/src/libs/luasocket/src/options.c new file mode 100644 index 000000000..5da3c518c --- /dev/null +++ b/src/libs/luasocket/src/options.c @@ -0,0 +1,149 @@ +/*=========================================================================*\ +* Common option interface +* LuaSocket toolkit +* +* RCS ID: $Id: options.c,v 1.6 2005/11/20 07:20:23 diego Exp $ +\*=========================================================================*/ +#include <string.h> + +#include "lauxlib.h" + +#include "auxiliar.h" +#include "options.h" +#include "inet.h" + + +/*=========================================================================*\ +* Internal functions prototypes +\*=========================================================================*/ +static int opt_setmembership(lua_State *L, p_socket ps, int level, int name); +static int opt_setboolean(lua_State *L, p_socket ps, int level, int name); +static int opt_set(lua_State *L, p_socket ps, int level, int name, + void *val, int len); + +/*=========================================================================*\ +* Exported functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Calls appropriate option handler +\*-------------------------------------------------------------------------*/ +int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps) +{ + const char *name = luaL_checkstring(L, 2); /* obj, name, ... */ + while (opt->name && strcmp(name, opt->name)) + opt++; + if (!opt->func) { + char msg[45]; + sprintf(msg, "unsupported option `%.35s'", name); + luaL_argerror(L, 2, msg); + } + return opt->func(L, ps); +} + +/* enables reuse of local address */ +int opt_reuseaddr(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEADDR); +} + +/* disables the Naggle algorithm */ +int opt_tcp_nodelay(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); +} + +int opt_keepalive(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); +} + +int opt_dontroute(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, SOL_SOCKET, SO_DONTROUTE); +} + +int opt_broadcast(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, SOL_SOCKET, SO_BROADCAST); +} + +int opt_ip_multicast_loop(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); +} + +int opt_linger(lua_State *L, p_socket ps) +{ + struct linger li; /* obj, name, table */ + if (!lua_istable(L, 3)) luaL_typerror(L, 3, lua_typename(L, LUA_TTABLE)); + lua_pushstring(L, "on"); + lua_gettable(L, 3); + if (!lua_isboolean(L, -1)) + luaL_argerror(L, 3, "boolean 'on' field expected"); + li.l_onoff = (u_short) lua_toboolean(L, -1); + lua_pushstring(L, "timeout"); + lua_gettable(L, 3); + if (!lua_isnumber(L, -1)) + luaL_argerror(L, 3, "number 'timeout' field expected"); + li.l_linger = (u_short) lua_tonumber(L, -1); + return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof(li)); +} + +int opt_ip_multicast_ttl(lua_State *L, p_socket ps) +{ + int val = (int) luaL_checknumber(L, 3); /* obj, name, int */ + return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &val, sizeof(val)); +} + +int opt_ip_add_membership(lua_State *L, p_socket ps) +{ + return opt_setmembership(L, ps, IPPROTO_IP, IP_ADD_MEMBERSHIP); +} + +int opt_ip_drop_membersip(lua_State *L, p_socket ps) +{ + return opt_setmembership(L, ps, IPPROTO_IP, IP_DROP_MEMBERSHIP); +} + +/*=========================================================================*\ +* Auxiliar functions +\*=========================================================================*/ +static int opt_setmembership(lua_State *L, p_socket ps, int level, int name) +{ + struct ip_mreq val; /* obj, name, table */ + if (!lua_istable(L, 3)) luaL_typerror(L, 3, lua_typename(L, LUA_TTABLE)); + lua_pushstring(L, "multiaddr"); + lua_gettable(L, 3); + if (!lua_isstring(L, -1)) + luaL_argerror(L, 3, "string 'multiaddr' field expected"); + if (!inet_aton(lua_tostring(L, -1), &val.imr_multiaddr)) + luaL_argerror(L, 3, "invalid 'multiaddr' ip address"); + lua_pushstring(L, "interface"); + lua_gettable(L, 3); + if (!lua_isstring(L, -1)) + luaL_argerror(L, 3, "string 'interface' field expected"); + val.imr_interface.s_addr = htonl(INADDR_ANY); + if (strcmp(lua_tostring(L, -1), "*") && + !inet_aton(lua_tostring(L, -1), &val.imr_interface)) + luaL_argerror(L, 3, "invalid 'interface' ip address"); + return opt_set(L, ps, level, name, (char *) &val, sizeof(val)); +} + +static +int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len) +{ + if (setsockopt(*ps, level, name, (char *) val, len) < 0) { + lua_pushnil(L); + lua_pushstring(L, "setsockopt failed"); + return 2; + } + lua_pushnumber(L, 1); + return 1; +} + +static int opt_setboolean(lua_State *L, p_socket ps, int level, int name) +{ + int val = auxiliar_checkboolean(L, 3); /* obj, name, bool */ + return opt_set(L, ps, level, name, (char *) &val, sizeof(val)); +} + diff --git a/src/libs/luasocket/src/options.h b/src/libs/luasocket/src/options.h new file mode 100644 index 000000000..4981cf2a0 --- /dev/null +++ b/src/libs/luasocket/src/options.h @@ -0,0 +1,39 @@ +#ifndef OPTIONS_H +#define OPTIONS_H +/*=========================================================================*\ +* Common option interface +* LuaSocket toolkit +* +* This module provides a common interface to socket options, used mainly by +* modules UDP and TCP. +* +* RCS ID: $Id: options.h,v 1.4 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ + +#include "lua.h" +#include "socket.h" + +/* option registry */ +typedef struct t_opt { + const char *name; + int (*func)(lua_State *L, p_socket ps); +} t_opt; +typedef t_opt *p_opt; + +/* supported options */ +int opt_dontroute(lua_State *L, p_socket ps); +int opt_broadcast(lua_State *L, p_socket ps); +int opt_reuseaddr(lua_State *L, p_socket ps); +int opt_tcp_nodelay(lua_State *L, p_socket ps); +int opt_keepalive(lua_State *L, p_socket ps); +int opt_linger(lua_State *L, p_socket ps); +int opt_reuseaddr(lua_State *L, p_socket ps); +int opt_ip_multicast_ttl(lua_State *L, p_socket ps); +int opt_ip_multicast_loop(lua_State *L, p_socket ps); +int opt_ip_add_membership(lua_State *L, p_socket ps); +int opt_ip_drop_membersip(lua_State *L, p_socket ps); + +/* invokes the appropriate option handler */ +int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps); + +#endif diff --git a/src/libs/luasocket/src/select.c b/src/libs/luasocket/src/select.c new file mode 100644 index 000000000..d70f66271 --- /dev/null +++ b/src/libs/luasocket/src/select.c @@ -0,0 +1,200 @@ +/*=========================================================================*\ +* Select implementation +* LuaSocket toolkit +* +* RCS ID: $Id: select.c,v 1.22 2005/11/20 07:20:23 diego Exp $ +\*=========================================================================*/ +#include <string.h> + +#include "lua.h" +#include "lauxlib.h" + +#include "socket.h" +#include "timeout.h" +#include "select.h" + +/*=========================================================================*\ +* Internal function prototypes. +\*=========================================================================*/ +static t_socket getfd(lua_State *L); +static int dirty(lua_State *L); +static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, + int itab, fd_set *set); +static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set); +static void return_fd(lua_State *L, fd_set *set, t_socket max_fd, + int itab, int tab, int start); +static void make_assoc(lua_State *L, int tab); +static int global_select(lua_State *L); + +/* functions in library namespace */ +static luaL_reg func[] = { + {"select", global_select}, + {NULL, NULL} +}; + +/*=========================================================================*\ +* Exported functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int select_open(lua_State *L) { + luaL_openlib(L, NULL, func, 0); + return 0; +} + +/*=========================================================================*\ +* Global Lua functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Waits for a set of sockets until a condition is met or timeout. +\*-------------------------------------------------------------------------*/ +static int global_select(lua_State *L) { + int rtab, wtab, itab, ret, ndirty; + t_socket max_fd; + fd_set rset, wset; + t_timeout tm; + double t = luaL_optnumber(L, 3, -1); + FD_ZERO(&rset); FD_ZERO(&wset); + lua_settop(L, 3); + lua_newtable(L); itab = lua_gettop(L); + lua_newtable(L); rtab = lua_gettop(L); + lua_newtable(L); wtab = lua_gettop(L); + max_fd = collect_fd(L, 1, SOCKET_INVALID, itab, &rset); + ndirty = check_dirty(L, 1, rtab, &rset); + t = ndirty > 0? 0.0: t; + timeout_init(&tm, t, -1); + timeout_markstart(&tm); + max_fd = collect_fd(L, 2, max_fd, itab, &wset); + ret = socket_select(max_fd+1, &rset, &wset, NULL, &tm); + if (ret > 0 || ndirty > 0) { + return_fd(L, &rset, max_fd+1, itab, rtab, ndirty); + return_fd(L, &wset, max_fd+1, itab, wtab, 0); + make_assoc(L, rtab); + make_assoc(L, wtab); + return 2; + } else if (ret == 0) { + lua_pushstring(L, "timeout"); + return 3; + } else { + lua_pushstring(L, "error"); + return 3; + } +} + +/*=========================================================================*\ +* Internal functions +\*=========================================================================*/ +static t_socket getfd(lua_State *L) { + t_socket fd = SOCKET_INVALID; + lua_pushstring(L, "getfd"); + lua_gettable(L, -2); + if (!lua_isnil(L, -1)) { + lua_pushvalue(L, -2); + lua_call(L, 1, 1); + if (lua_isnumber(L, -1)) + fd = (t_socket) lua_tonumber(L, -1); + } + lua_pop(L, 1); + return fd; +} + +static int dirty(lua_State *L) { + int is = 0; + lua_pushstring(L, "dirty"); + lua_gettable(L, -2); + if (!lua_isnil(L, -1)) { + lua_pushvalue(L, -2); + lua_call(L, 1, 1); + is = lua_toboolean(L, -1); + } + lua_pop(L, 1); + return is; +} + +static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, + int itab, fd_set *set) { + int i = 1; + if (lua_isnil(L, tab)) + return max_fd; + while (1) { + t_socket fd; + lua_pushnumber(L, i); + lua_gettable(L, tab); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); + break; + } + fd = getfd(L); + if (fd != SOCKET_INVALID) { + FD_SET(fd, set); + if (max_fd == SOCKET_INVALID || max_fd < fd) + max_fd = fd; + lua_pushnumber(L, fd); + lua_pushvalue(L, -2); + lua_settable(L, itab); + } + lua_pop(L, 1); + i = i + 1; + } + return max_fd; +} + +static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) { + int ndirty = 0, i = 1; + if (lua_isnil(L, tab)) + return 0; + while (1) { + t_socket fd; + lua_pushnumber(L, i); + lua_gettable(L, tab); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); + break; + } + fd = getfd(L); + if (fd != SOCKET_INVALID && dirty(L)) { + lua_pushnumber(L, ++ndirty); + lua_pushvalue(L, -2); + lua_settable(L, dtab); + FD_CLR(fd, set); + } + lua_pop(L, 1); + i = i + 1; + } + return ndirty; +} + +static void return_fd(lua_State *L, fd_set *set, t_socket max_fd, + int itab, int tab, int start) { + t_socket fd; + for (fd = 0; fd < max_fd; fd++) { + if (FD_ISSET(fd, set)) { + lua_pushnumber(L, ++start); + lua_pushnumber(L, fd); + lua_gettable(L, itab); + lua_settable(L, tab); + } + } +} + +static void make_assoc(lua_State *L, int tab) { + int i = 1, atab; + lua_newtable(L); atab = lua_gettop(L); + while (1) { + lua_pushnumber(L, i); + lua_gettable(L, tab); + if (!lua_isnil(L, -1)) { + lua_pushnumber(L, i); + lua_pushvalue(L, -2); + lua_settable(L, atab); + lua_pushnumber(L, i); + lua_settable(L, atab); + } else { + lua_pop(L, 1); + break; + } + i = i+1; + } +} + diff --git a/src/libs/luasocket/src/select.h b/src/libs/luasocket/src/select.h new file mode 100644 index 000000000..aa3db4adf --- /dev/null +++ b/src/libs/luasocket/src/select.h @@ -0,0 +1,17 @@ +#ifndef SELECT_H +#define SELECT_H +/*=========================================================================*\ +* Select implementation +* LuaSocket toolkit +* +* Each object that can be passed to the select function has to export +* method getfd() which returns the descriptor to be passed to the +* underlying select function. Another method, dirty(), should return +* true if there is data ready for reading (required for buffered input). +* +* RCS ID: $Id: select.h,v 1.7 2004/06/16 01:02:07 diego Exp $ +\*=========================================================================*/ + +int select_open(lua_State *L); + +#endif /* SELECT_H */ diff --git a/src/libs/luasocket/src/smtp.lua b/src/libs/luasocket/src/smtp.lua new file mode 100644 index 000000000..8f3cfcff6 --- /dev/null +++ b/src/libs/luasocket/src/smtp.lua @@ -0,0 +1,251 @@ +----------------------------------------------------------------------------- +-- SMTP client support for the Lua language. +-- LuaSocket toolkit. +-- Author: Diego Nehab +-- RCS ID: $Id: smtp.lua,v 1.46 2007/03/12 04:08:40 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local coroutine = require("coroutine") +local string = require("string") +local math = require("math") +local os = require("os") +local socket = require("socket") +local tp = require("socket.tp") +local ltn12 = require("ltn12") +local mime = require("mime") +module("socket.smtp") + +----------------------------------------------------------------------------- +-- Program constants +----------------------------------------------------------------------------- +-- timeout for connection +TIMEOUT = 60 +-- default server used to send e-mails +SERVER = "localhost" +-- default port +PORT = 25 +-- domain used in HELO command and default sendmail +-- If we are under a CGI, try to get from environment +DOMAIN = os.getenv("SERVER_NAME") or "localhost" +-- default time zone (means we don't know) +ZONE = "-0000" + +--------------------------------------------------------------------------- +-- Low level SMTP API +----------------------------------------------------------------------------- +local metat = { __index = {} } + +function metat.__index:greet(domain) + self.try(self.tp:check("2..")) + self.try(self.tp:command("EHLO", domain or DOMAIN)) + return socket.skip(1, self.try(self.tp:check("2.."))) +end + +function metat.__index:mail(from) + self.try(self.tp:command("MAIL", "FROM:" .. from)) + return self.try(self.tp:check("2..")) +end + +function metat.__index:rcpt(to) + self.try(self.tp:command("RCPT", "TO:" .. to)) + return self.try(self.tp:check("2..")) +end + +function metat.__index:data(src, step) + self.try(self.tp:command("DATA")) + self.try(self.tp:check("3..")) + self.try(self.tp:source(src, step)) + self.try(self.tp:send("\r\n.\r\n")) + return self.try(self.tp:check("2..")) +end + +function metat.__index:quit() + self.try(self.tp:command("QUIT")) + return self.try(self.tp:check("2..")) +end + +function metat.__index:close() + return self.tp:close() +end + +function metat.__index:login(user, password) + self.try(self.tp:command("AUTH", "LOGIN")) + self.try(self.tp:check("3..")) + self.try(self.tp:command(mime.b64(user))) + self.try(self.tp:check("3..")) + self.try(self.tp:command(mime.b64(password))) + return self.try(self.tp:check("2..")) +end + +function metat.__index:plain(user, password) + local auth = "PLAIN " .. mime.b64("\0" .. user .. "\0" .. password) + self.try(self.tp:command("AUTH", auth)) + return self.try(self.tp:check("2..")) +end + +function metat.__index:auth(user, password, ext) + if not user or not password then return 1 end + if string.find(ext, "AUTH[^\n]+LOGIN") then + return self:login(user, password) + elseif string.find(ext, "AUTH[^\n]+PLAIN") then + return self:plain(user, password) + else + self.try(nil, "authentication not supported") + end +end + +-- send message or throw an exception +function metat.__index:send(mailt) + self:mail(mailt.from) + if base.type(mailt.rcpt) == "table" then + for i,v in base.ipairs(mailt.rcpt) do + self:rcpt(v) + end + else + self:rcpt(mailt.rcpt) + end + self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step) +end + +function open(server, port, create) + local tp = socket.try(tp.connect(server or SERVER, port or PORT, + TIMEOUT, create)) + local s = base.setmetatable({tp = tp}, metat) + -- make sure tp is closed if we get an exception + s.try = socket.newtry(function() + s:close() + end) + return s +end + +-- convert headers to lowercase +local function lower_headers(headers) + local lower = {} + for i,v in base.pairs(headers or lower) do + lower[string.lower(i)] = v + end + return lower +end + +--------------------------------------------------------------------------- +-- Multipart message source +----------------------------------------------------------------------------- +-- returns a hopefully unique mime boundary +local seqno = 0 +local function newboundary() + seqno = seqno + 1 + return string.format('%s%05d==%05u', os.date('%d%m%Y%H%M%S'), + math.random(0, 99999), seqno) +end + +-- send_message forward declaration +local send_message + +-- yield the headers all at once, it's faster +local function send_headers(headers) + local h = "\r\n" + for i,v in base.pairs(headers) do + h = i .. ': ' .. v .. "\r\n" .. h + end + coroutine.yield(h) +end + +-- yield multipart message body from a multipart message table +local function send_multipart(mesgt) + -- make sure we have our boundary and send headers + local bd = newboundary() + local headers = lower_headers(mesgt.headers or {}) + headers['content-type'] = headers['content-type'] or 'multipart/mixed' + headers['content-type'] = headers['content-type'] .. + '; boundary="' .. bd .. '"' + send_headers(headers) + -- send preamble + if mesgt.body.preamble then + coroutine.yield(mesgt.body.preamble) + coroutine.yield("\r\n") + end + -- send each part separated by a boundary + for i, m in base.ipairs(mesgt.body) do + coroutine.yield("\r\n--" .. bd .. "\r\n") + send_message(m) + end + -- send last boundary + coroutine.yield("\r\n--" .. bd .. "--\r\n\r\n") + -- send epilogue + if mesgt.body.epilogue then + coroutine.yield(mesgt.body.epilogue) + coroutine.yield("\r\n") + end +end + +-- yield message body from a source +local function send_source(mesgt) + -- make sure we have a content-type + local headers = lower_headers(mesgt.headers or {}) + headers['content-type'] = headers['content-type'] or + 'text/plain; charset="iso-8859-1"' + send_headers(headers) + -- send body from source + while true do + local chunk, err = mesgt.body() + if err then coroutine.yield(nil, err) + elseif chunk then coroutine.yield(chunk) + else break end + end +end + +-- yield message body from a string +local function send_string(mesgt) + -- make sure we have a content-type + local headers = lower_headers(mesgt.headers or {}) + headers['content-type'] = headers['content-type'] or + 'text/plain; charset="iso-8859-1"' + send_headers(headers) + -- send body from string + coroutine.yield(mesgt.body) +end + +-- message source +function send_message(mesgt) + if base.type(mesgt.body) == "table" then send_multipart(mesgt) + elseif base.type(mesgt.body) == "function" then send_source(mesgt) + else send_string(mesgt) end +end + +-- set defaul headers +local function adjust_headers(mesgt) + local lower = lower_headers(mesgt.headers) + lower["date"] = lower["date"] or + os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or ZONE) + lower["x-mailer"] = lower["x-mailer"] or socket._VERSION + -- this can't be overriden + lower["mime-version"] = "1.0" + return lower +end + +function message(mesgt) + mesgt.headers = adjust_headers(mesgt) + -- create and return message source + local co = coroutine.create(function() send_message(mesgt) end) + return function() + local ret, a, b = coroutine.resume(co) + if ret then return a, b + else return nil, a end + end +end + +--------------------------------------------------------------------------- +-- High level SMTP API +----------------------------------------------------------------------------- +send = socket.protect(function(mailt) + local s = open(mailt.server, mailt.port, mailt.create) + local ext = s:greet(mailt.domain) + s:auth(mailt.user, mailt.password, ext) + s:send(mailt) + s:quit() + return s:close() +end) diff --git a/src/libs/luasocket/src/smtp_lua.c b/src/libs/luasocket/src/smtp_lua.c new file mode 100644 index 000000000..8743ff557 --- /dev/null +++ b/src/libs/luasocket/src/smtp_lua.c @@ -0,0 +1,412 @@ +/* + * This file is auto-generated by "./lua2c smtp.lua smtp_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_smtp_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 83, 77, 84, 80, 32, 99,108,105,101,110,116, 32,115,117,112,112,111,114,116, + 32,102,111,114, 32,116,104,101, 32, 76,117, 97, 32,108, 97,110,103,117, 97,103, +101, 46, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, 32,116,111,111,108, +107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, 68,105,101,103, +111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36, + 73,100, 58, 32,115,109,116,112, 46,108,117, 97, 44,118, 32, 49, 46, 52, 54, 32, + 50, 48, 48, 55, 47, 48, 51, 47, 49, 50, 32, 48, 52, 58, 48, 56, 58, 52, 48, 32, +100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114,101, 32, +109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, 32,100,101, +112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97,115,101, 32, + 61, 32, 95, 71, 10,108,111, 99, 97,108, 32, 99,111,114,111,117,116,105,110,101, + 32, 61, 32,114,101,113,117,105,114,101, 40, 34, 99,111,114,111,117,116,105,110, +101, 34, 41, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, 61, 32,114, +101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10,108,111, 99, + 97,108, 32,109, 97,116,104, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,109, + 97,116,104, 34, 41, 10,108,111, 99, 97,108, 32,111,115, 32, 61, 32,114,101,113, +117,105,114,101, 40, 34,111,115, 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99, +107,101,116, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101, +116, 34, 41, 10,108,111, 99, 97,108, 32,116,112, 32, 61, 32,114,101,113,117,105, +114,101, 40, 34,115,111, 99,107,101,116, 46,116,112, 34, 41, 10,108,111, 99, 97, +108, 32,108,116,110, 49, 50, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,108, +116,110, 49, 50, 34, 41, 10,108,111, 99, 97,108, 32,109,105,109,101, 32, 61, 32, +114,101,113,117,105,114,101, 40, 34,109,105,109,101, 34, 41, 10,109,111,100,117, +108,101, 40, 34,115,111, 99,107,101,116, 46,115,109,116,112, 34, 41, 10, 10, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, + 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, 97,110,116,115, 10, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,116, +105,109,101,111,117,116, 32,102,111,114, 32, 99,111,110,110,101, 99,116,105,111, +110, 10, 84, 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 45, 45, 32,100,101, +102, 97,117,108,116, 32,115,101,114,118,101,114, 32,117,115,101,100, 32,116,111, + 32,115,101,110,100, 32,101, 45,109, 97,105,108,115, 10, 83, 69, 82, 86, 69, 82, + 32, 61, 32, 34,108,111, 99, 97,108,104,111,115,116, 34, 10, 45, 45, 32,100,101, +102, 97,117,108,116, 32,112,111,114,116, 10, 80, 79, 82, 84, 32, 61, 32, 50, 53, + 10, 45, 45, 32,100,111,109, 97,105,110, 32,117,115,101,100, 32,105,110, 32, 72, + 69, 76, 79, 32, 99,111,109,109, 97,110,100, 32, 97,110,100, 32,100,101,102, 97, +117,108,116, 32,115,101,110,100,109, 97,105,108, 10, 45, 45, 32, 73,102, 32,119, +101, 32, 97,114,101, 32,117,110,100,101,114, 32, 97, 32, 67, 71, 73, 44, 32,116, +114,121, 32,116,111, 32,103,101,116, 32,102,114,111,109, 32,101,110,118,105,114, +111,110,109,101,110,116, 10, 68, 79, 77, 65, 73, 78, 32, 61, 32,111,115, 46,103, +101,116,101,110,118, 40, 34, 83, 69, 82, 86, 69, 82, 95, 78, 65, 77, 69, 34, 41, + 32,111,114, 32, 34,108,111, 99, 97,108,104,111,115,116, 34, 10, 45, 45, 32,100, +101,102, 97,117,108,116, 32,116,105,109,101, 32,122,111,110,101, 32, 40,109,101, + 97,110,115, 32,119,101, 32,100,111,110, 39,116, 32,107,110,111,119, 41, 10, 90, + 79, 78, 69, 32, 61, 32, 34, 45, 48, 48, 48, 48, 34, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 76,111,119, 32,108,101, +118,101,108, 32, 83, 77, 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32,109,101,116, + 97,116, 32, 61, 32,123, 32, 95, 95,105,110,100,101,120, 32, 61, 32,123,125, 32, +125, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95, +105,110,100,101,120, 58,103,114,101,101,116, 40,100,111,109, 97,105,110, 41, 10, + 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, + 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,115, +101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, + 97,110,100, 40, 34, 69, 72, 76, 79, 34, 44, 32,100,111,109, 97,105,110, 32,111, +114, 32, 68, 79, 77, 65, 73, 78, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 49, 44, 32,115,101,108, +102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, + 34, 50, 46, 46, 34, 41, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105, +111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,109, 97,105, +108, 40,102,114,111,109, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, + 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 77, 65, + 73, 76, 34, 44, 32, 34, 70, 82, 79, 77, 58, 34, 32, 46, 46, 32,102,114,111,109, + 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116, +114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, + 46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109, +101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,114, 99,112,116, 40,116,111, + 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, +116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 82, 67, 80, 84, 34, 44, 32, 34, + 84, 79, 58, 34, 32, 46, 46, 32,116,111, 41, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, + 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, 10, 10, +102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100, +101,120, 58,100, 97,116, 97, 40,115,114, 99, 44, 32,115,116,101,112, 41, 10, 32, + 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, + 99,111,109,109, 97,110,100, 40, 34, 68, 65, 84, 65, 34, 41, 41, 10, 32, 32, 32, + 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104, +101, 99,107, 40, 34, 51, 46, 46, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, + 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,115,111,117,114, 99,101, 40, +115,114, 99, 44, 32,115,116,101,112, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, + 46,116,114,121, 40,115,101,108,102, 46,116,112, 58,115,101,110,100, 40, 34, 92, +114, 92,110, 46, 92,114, 92,110, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, + 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, 10, 10,102, +117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101, +120, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114, +121, 40,115,101,108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 81, + 85, 73, 84, 34, 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101, +108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, + 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105, +111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,108,111, +115,101, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, + 46,116,112, 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 10, 10,102,117,110, + 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, +108,111,103,105,110, 40,117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100, + 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, +116,112, 58, 99,111,109,109, 97,110,100, 40, 34, 65, 85, 84, 72, 34, 44, 32, 34, + 76, 79, 71, 73, 78, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114, +121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 51, 46, 46, + 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108, +102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40,109,105,109,101, 46, 98, 54, + 52, 40,117,115,101,114, 41, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116, +114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 51, 46, + 46, 34, 41, 41, 10, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101, +108,102, 46,116,112, 58, 99,111,109,109, 97,110,100, 40,109,105,109,101, 46, 98, + 54, 52, 40,112, 97,115,115,119,111,114,100, 41, 41, 41, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46, +116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, 46, 34, 41, 41, 10,101,110,100, + 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105, +110,100,101,120, 58,112,108, 97,105,110, 40,117,115,101,114, 44, 32,112, 97,115, +115,119,111,114,100, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 97,117,116, +104, 32, 61, 32, 34, 80, 76, 65, 73, 78, 32, 34, 32, 46, 46, 32,109,105,109,101, + 46, 98, 54, 52, 40, 34, 92, 48, 34, 32, 46, 46, 32,117,115,101,114, 32, 46, 46, + 32, 34, 92, 48, 34, 32, 46, 46, 32,112, 97,115,115,119,111,114,100, 41, 10, 32, + 32, 32, 32,115,101,108,102, 46,116,114,121, 40,115,101,108,102, 46,116,112, 58, + 99,111,109,109, 97,110,100, 40, 34, 65, 85, 84, 72, 34, 44, 32, 97,117,116,104, + 41, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46,116, +114,121, 40,115,101,108,102, 46,116,112, 58, 99,104,101, 99,107, 40, 34, 50, 46, + 46, 34, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109, +101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 97,117,116,104, 40,117,115, +101,114, 44, 32,112, 97,115,115,119,111,114,100, 44, 32,101,120,116, 41, 10, 32, + 32, 32, 32,105,102, 32,110,111,116, 32,117,115,101,114, 32,111,114, 32,110,111, +116, 32,112, 97,115,115,119,111,114,100, 32,116,104,101,110, 32,114,101,116,117, +114,110, 32, 49, 32,101,110,100, 10, 32, 32, 32, 32,105,102, 32,115,116,114,105, +110,103, 46,102,105,110,100, 40,101,120,116, 44, 32, 34, 65, 85, 84, 72, 91, 94, + 92,110, 93, 43, 76, 79, 71, 73, 78, 34, 41, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 58,108,111,103, +105,110, 40,117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100, 41, 10, 32, + 32, 32, 32,101,108,115,101,105,102, 32,115,116,114,105,110,103, 46,102,105,110, +100, 40,101,120,116, 44, 32, 34, 65, 85, 84, 72, 91, 94, 92,110, 93, 43, 80, 76, + 65, 73, 78, 34, 41, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114, +101,116,117,114,110, 32,115,101,108,102, 58,112,108, 97,105,110, 40,117,115,101, +114, 44, 32,112, 97,115,115,119,111,114,100, 41, 10, 32, 32, 32, 32,101,108,115, +101, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 46,116,114,121, 40,110, +105,108, 44, 32, 34, 97,117,116,104,101,110,116,105, 99, 97,116,105,111,110, 32, +110,111,116, 32,115,117,112,112,111,114,116,101,100, 34, 41, 10, 32, 32, 32, 32, +101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,115,101,110,100, 32,109,101,115, +115, 97,103,101, 32,111,114, 32,116,104,114,111,119, 32, 97,110, 32,101,120, 99, +101,112,116,105,111,110, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97, +116, 46, 95, 95,105,110,100,101,120, 58,115,101,110,100, 40,109, 97,105,108,116, + 41, 10, 32, 32, 32, 32,115,101,108,102, 58,109, 97,105,108, 40,109, 97,105,108, +116, 46,102,114,111,109, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46, +116,121,112,101, 40,109, 97,105,108,116, 46,114, 99,112,116, 41, 32, 61, 61, 32, + 34,116, 97, 98,108,101, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, + 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115,101, 46,105,112, 97, +105,114,115, 40,109, 97,105,108,116, 46,114, 99,112,116, 41, 32,100,111, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 58,114, 99,112,116, + 40,118, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, +101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101,108,102, 58,114, 99, +112,116, 40,109, 97,105,108,116, 46,114, 99,112,116, 41, 10, 32, 32, 32, 32,101, +110,100, 10, 32, 32, 32, 32,115,101,108,102, 58,100, 97,116, 97, 40,108,116,110, + 49, 50, 46,115,111,117,114, 99,101, 46, 99,104, 97,105,110, 40,109, 97,105,108, +116, 46,115,111,117,114, 99,101, 44, 32,109,105,109,101, 46,115,116,117,102,102, + 40, 41, 41, 44, 32,109, 97,105,108,116, 46,115,116,101,112, 41, 10,101,110,100, + 10, 10,102,117,110, 99,116,105,111,110, 32,111,112,101,110, 40,115,101,114,118, +101,114, 44, 32,112,111,114,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32,116,112, 32, 61, 32,115,111, 99,107,101,116, 46, +116,114,121, 40,116,112, 46, 99,111,110,110,101, 99,116, 40,115,101,114,118,101, +114, 32,111,114, 32, 83, 69, 82, 86, 69, 82, 44, 32,112,111,114,116, 32,111,114, + 32, 80, 79, 82, 84, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 84, 73, 77, 69, 79, + 85, 84, 44, 32, 99,114,101, 97,116,101, 41, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,115, 32, 61, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, + 97, 98,108,101, 40,123,116,112, 32, 61, 32,116,112,125, 44, 32,109,101,116, 97, +116, 41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, 32, +116,112, 32,105,115, 32, 99,108,111,115,101,100, 32,105,102, 32,119,101, 32,103, +101,116, 32, 97,110, 32,101,120, 99,101,112,116,105,111,110, 10, 32, 32, 32, 32, +115, 46,116,114,121, 32, 61, 32,115,111, 99,107,101,116, 46,110,101,119,116,114, +121, 40,102,117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32,115, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,101,110,100, 41, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,115, 10,101,110,100, 10, 10, 45, 45, + 32, 99,111,110,118,101,114,116, 32,104,101, 97,100,101,114,115, 32,116,111, 32, +108,111,119,101,114, 99, 97,115,101, 10,108,111, 99, 97,108, 32,102,117,110, 99, +116,105,111,110, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,115, 40,104, +101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,108,111, +119,101,114, 32, 61, 32,123,125, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, + 32,105,110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,104,101, 97,100,101, +114,115, 32,111,114, 32,108,111,119,101,114, 41, 32,100,111, 10, 32, 32, 32, 32, + 32, 32, 32, 32,108,111,119,101,114, 91,115,116,114,105,110,103, 46,108,111,119, +101,114, 40,105, 41, 93, 32, 61, 32,118, 10, 32, 32, 32, 32,101,110,100, 10, 32, + 32, 32, 32,114,101,116,117,114,110, 32,108,111,119,101,114, 10,101,110,100, 10, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, + 77,117,108,116,105,112, 97,114,116, 32,109,101,115,115, 97,103,101, 32,115,111, +117,114, 99,101, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 10, 45, 45, 32,114,101,116,117,114,110,115, 32, 97, 32,104,111,112,101, +102,117,108,108,121, 32,117,110,105,113,117,101, 32,109,105,109,101, 32, 98,111, +117,110,100, 97,114,121, 10,108,111, 99, 97,108, 32,115,101,113,110,111, 32, 61, + 32, 48, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,110,101, +119, 98,111,117,110,100, 97,114,121, 40, 41, 10, 32, 32, 32, 32,115,101,113,110, +111, 32, 61, 32,115,101,113,110,111, 32, 43, 32, 49, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 39, + 37,115, 37, 48, 53,100, 61, 61, 37, 48, 53,117, 39, 44, 32,111,115, 46,100, 97, +116,101, 40, 39, 37,100, 37,109, 37, 89, 37, 72, 37, 77, 37, 83, 39, 41, 44, 10, + 32, 32, 32, 32, 32, 32, 32, 32,109, 97,116,104, 46,114, 97,110,100,111,109, 40, + 48, 44, 32, 57, 57, 57, 57, 57, 41, 44, 32,115,101,113,110,111, 41, 10,101,110, +100, 10, 10, 45, 45, 32,115,101,110,100, 95,109,101,115,115, 97,103,101, 32,102, +111,114,119, 97,114,100, 32,100,101, 99,108, 97,114, 97,116,105,111,110, 10,108, +111, 99, 97,108, 32,115,101,110,100, 95,109,101,115,115, 97,103,101, 10, 10, 45, + 45, 32,121,105,101,108,100, 32,116,104,101, 32,104,101, 97,100,101,114,115, 32, + 97,108,108, 32, 97,116, 32,111,110, 99,101, 44, 32,105,116, 39,115, 32,102, 97, +115,116,101,114, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32, +115,101,110,100, 95,104,101, 97,100,101,114,115, 40,104,101, 97,100,101,114,115, + 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104, 32, 61, 32, 34, 92,114, 92, +110, 34, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97, +115,101, 46,112, 97,105,114,115, 40,104,101, 97,100,101,114,115, 41, 32,100,111, + 10, 32, 32, 32, 32, 32, 32, 32, 32,104, 32, 61, 32,105, 32, 46, 46, 32, 39, 58, + 32, 39, 32, 46, 46, 32,118, 32, 46, 46, 32, 34, 92,114, 92,110, 34, 32, 46, 46, + 32,104, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 99,111,114,111,117, +116,105,110,101, 46,121,105,101,108,100, 40,104, 41, 10,101,110,100, 10, 10, 45, + 45, 32,121,105,101,108,100, 32,109,117,108,116,105,112, 97,114,116, 32,109,101, +115,115, 97,103,101, 32, 98,111,100,121, 32,102,114,111,109, 32, 97, 32,109,117, +108,116,105,112, 97,114,116, 32,109,101,115,115, 97,103,101, 32,116, 97, 98,108, +101, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115,101,110, +100, 95,109,117,108,116,105,112, 97,114,116, 40,109,101,115,103,116, 41, 10, 32, + 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, 32,119,101, 32,104, + 97,118,101, 32,111,117,114, 32, 98,111,117,110,100, 97,114,121, 32, 97,110,100, + 32,115,101,110,100, 32,104,101, 97,100,101,114,115, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32, 98,100, 32, 61, 32,110,101,119, 98,111,117,110,100, 97,114,121, + 40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115, + 32, 61, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,115, 40,109,101,115, +103,116, 46,104,101, 97,100,101,114,115, 32,111,114, 32,123,125, 41, 10, 32, 32, + 32, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116, +121,112,101, 39, 93, 32, 61, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110, +116,101,110,116, 45,116,121,112,101, 39, 93, 32,111,114, 32, 39,109,117,108,116, +105,112, 97,114,116, 47,109,105,120,101,100, 39, 10, 32, 32, 32, 32,104,101, 97, +100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116,121,112,101, 39, 93, + 32, 61, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45, +116,121,112,101, 39, 93, 32, 46, 46, 10, 32, 32, 32, 32, 32, 32, 32, 32, 39, 59, + 32, 98,111,117,110,100, 97,114,121, 61, 34, 39, 32, 46, 46, 32, 32, 98,100, 32, + 46, 46, 32, 39, 34, 39, 10, 32, 32, 32, 32,115,101,110,100, 95,104,101, 97,100, +101,114,115, 40,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, 45, 45, 32, +115,101,110,100, 32,112,114,101, 97,109, 98,108,101, 10, 32, 32, 32, 32,105,102, + 32,109,101,115,103,116, 46, 98,111,100,121, 46,112,114,101, 97,109, 98,108,101, + 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99,111,114,111,117,116, +105,110,101, 46,121,105,101,108,100, 40,109,101,115,103,116, 46, 98,111,100,121, + 46,112,114,101, 97,109, 98,108,101, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99, +111,114,111,117,116,105,110,101, 46,121,105,101,108,100, 40, 34, 92,114, 92,110, + 34, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,115,101, +110,100, 32,101, 97, 99,104, 32,112, 97,114,116, 32,115,101,112, 97,114, 97,116, +101,100, 32, 98,121, 32, 97, 32, 98,111,117,110,100, 97,114,121, 10, 32, 32, 32, + 32,102,111,114, 32,105, 44, 32,109, 32,105,110, 32, 98, 97,115,101, 46,105,112, + 97,105,114,115, 40,109,101,115,103,116, 46, 98,111,100,121, 41, 32,100,111, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 99,111,114,111,117,116,105,110,101, 46,121,105, +101,108,100, 40, 34, 92,114, 92,110, 45, 45, 34, 32, 46, 46, 32, 98,100, 32, 46, + 46, 32, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,115,101, +110,100, 95,109,101,115,115, 97,103,101, 40,109, 41, 10, 32, 32, 32, 32,101,110, +100, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32,108, 97,115,116, 32, 98, +111,117,110,100, 97,114,121, 10, 32, 32, 32, 32, 99,111,114,111,117,116,105,110, +101, 46,121,105,101,108,100, 40, 34, 92,114, 92,110, 45, 45, 34, 32, 46, 46, 32, + 98,100, 32, 46, 46, 32, 34, 45, 45, 92,114, 92,110, 92,114, 92,110, 34, 41, 10, + 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32,101,112,105,108,111,103,117,101, + 10, 32, 32, 32, 32,105,102, 32,109,101,115,103,116, 46, 98,111,100,121, 46,101, +112,105,108,111,103,117,101, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108,100, 40,109,101,115, +103,116, 46, 98,111,100,121, 46,101,112,105,108,111,103,117,101, 41, 10, 32, 32, + 32, 32, 32, 32, 32, 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108, +100, 40, 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32,101,110,100, 10,101,110, +100, 10, 10, 45, 45, 32,121,105,101,108,100, 32,109,101,115,115, 97,103,101, 32, + 98,111,100,121, 32,102,114,111,109, 32, 97, 32,115,111,117,114, 99,101, 10,108, +111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,115,101,110,100, 95,115, +111,117,114, 99,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32, 45, 45, 32, +109, 97,107,101, 32,115,117,114,101, 32,119,101, 32,104, 97,118,101, 32, 97, 32, + 99,111,110,116,101,110,116, 45,116,121,112,101, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,104,101, 97,100,101,114,115, 32, 61, 32,108,111,119,101,114, 95,104, +101, 97,100,101,114,115, 40,109,101,115,103,116, 46,104,101, 97,100,101,114,115, + 32,111,114, 32,123,125, 41, 10, 32, 32, 32, 32,104,101, 97,100,101,114,115, 91, + 39, 99,111,110,116,101,110,116, 45,116,121,112,101, 39, 93, 32, 61, 32,104,101, + 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116,121,112,101, 39, + 93, 32,111,114, 10, 32, 32, 32, 32, 32, 32, 32, 32, 39,116,101,120,116, 47,112, +108, 97,105,110, 59, 32, 99,104, 97,114,115,101,116, 61, 34,105,115,111, 45, 56, + 56, 53, 57, 45, 49, 34, 39, 10, 32, 32, 32, 32,115,101,110,100, 95,104,101, 97, +100,101,114,115, 40,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, 32, 45, 45, + 32,115,101,110,100, 32, 98,111,100,121, 32,102,114,111,109, 32,115,111,117,114, + 99,101, 10, 32, 32, 32, 32,119,104,105,108,101, 32,116,114,117,101, 32,100,111, + 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, + 44, 32,101,114,114, 32, 61, 32,109,101,115,103,116, 46, 98,111,100,121, 40, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, + 32, 99,111,114,111,117,116,105,110,101, 46,121,105,101,108,100, 40,110,105,108, + 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105, +102, 32, 99,104,117,110,107, 32,116,104,101,110, 32, 99,111,114,111,117,116,105, +110,101, 46,121,105,101,108,100, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,101,108,115,101, 32, 98,114,101, 97,107, 32,101,110,100, 10, 32, + 32, 32, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,121,105,101,108,100, + 32,109,101,115,115, 97,103,101, 32, 98,111,100,121, 32,102,114,111,109, 32, 97, + 32,115,116,114,105,110,103, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105, +111,110, 32,115,101,110,100, 95,115,116,114,105,110,103, 40,109,101,115,103,116, + 41, 10, 32, 32, 32, 32, 45, 45, 32,109, 97,107,101, 32,115,117,114,101, 32,119, +101, 32,104, 97,118,101, 32, 97, 32, 99,111,110,116,101,110,116, 45,116,121,112, +101, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,104,101, 97,100,101,114,115, 32, + 61, 32,108,111,119,101,114, 95,104,101, 97,100,101,114,115, 40,109,101,115,103, +116, 46,104,101, 97,100,101,114,115, 32,111,114, 32,123,125, 41, 10, 32, 32, 32, + 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116,101,110,116, 45,116,121, +112,101, 39, 93, 32, 61, 32,104,101, 97,100,101,114,115, 91, 39, 99,111,110,116, +101,110,116, 45,116,121,112,101, 39, 93, 32,111,114, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 39,116,101,120,116, 47,112,108, 97,105,110, 59, 32, 99,104, 97,114,115, +101,116, 61, 34,105,115,111, 45, 56, 56, 53, 57, 45, 49, 34, 39, 10, 32, 32, 32, + 32,115,101,110,100, 95,104,101, 97,100,101,114,115, 40,104,101, 97,100,101,114, +115, 41, 10, 32, 32, 32, 32, 45, 45, 32,115,101,110,100, 32, 98,111,100,121, 32, +102,114,111,109, 32,115,116,114,105,110,103, 10, 32, 32, 32, 32, 99,111,114,111, +117,116,105,110,101, 46,121,105,101,108,100, 40,109,101,115,103,116, 46, 98,111, +100,121, 41, 10,101,110,100, 10, 10, 45, 45, 32,109,101,115,115, 97,103,101, 32, +115,111,117,114, 99,101, 10,102,117,110, 99,116,105,111,110, 32,115,101,110,100, + 95,109,101,115,115, 97,103,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32, +105,102, 32, 98, 97,115,101, 46,116,121,112,101, 40,109,101,115,103,116, 46, 98, +111,100,121, 41, 32, 61, 61, 32, 34,116, 97, 98,108,101, 34, 32,116,104,101,110, + 32,115,101,110,100, 95,109,117,108,116,105,112, 97,114,116, 40,109,101,115,103, +116, 41, 10, 32, 32, 32, 32,101,108,115,101,105,102, 32, 98, 97,115,101, 46,116, +121,112,101, 40,109,101,115,103,116, 46, 98,111,100,121, 41, 32, 61, 61, 32, 34, +102,117,110, 99,116,105,111,110, 34, 32,116,104,101,110, 32,115,101,110,100, 95, +115,111,117,114, 99,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,101,108, +115,101, 32,115,101,110,100, 95,115,116,114,105,110,103, 40,109,101,115,103,116, + 41, 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 32,115,101,116, 32,100,101, +102, 97,117,108, 32,104,101, 97,100,101,114,115, 10,108,111, 99, 97,108, 32,102, +117,110, 99,116,105,111,110, 32, 97,100,106,117,115,116, 95,104,101, 97,100,101, +114,115, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, +108,111,119,101,114, 32, 61, 32,108,111,119,101,114, 95,104,101, 97,100,101,114, +115, 40,109,101,115,103,116, 46,104,101, 97,100,101,114,115, 41, 10, 32, 32, 32, + 32,108,111,119,101,114, 91, 34,100, 97,116,101, 34, 93, 32, 61, 32,108,111,119, +101,114, 91, 34,100, 97,116,101, 34, 93, 32,111,114, 10, 32, 32, 32, 32, 32, 32, + 32, 32,111,115, 46,100, 97,116,101, 40, 34, 33, 37, 97, 44, 32, 37,100, 32, 37, + 98, 32, 37, 89, 32, 37, 72, 58, 37, 77, 58, 37, 83, 32, 34, 41, 32, 46, 46, 32, + 40,109,101,115,103,116, 46,122,111,110,101, 32,111,114, 32, 90, 79, 78, 69, 41, + 10, 32, 32, 32, 32,108,111,119,101,114, 91, 34,120, 45,109, 97,105,108,101,114, + 34, 93, 32, 61, 32,108,111,119,101,114, 91, 34,120, 45,109, 97,105,108,101,114, + 34, 93, 32,111,114, 32,115,111, 99,107,101,116, 46, 95, 86, 69, 82, 83, 73, 79, + 78, 10, 32, 32, 32, 32, 45, 45, 32,116,104,105,115, 32, 99, 97,110, 39,116, 32, + 98,101, 32,111,118,101,114,114,105,100,101,110, 10, 32, 32, 32, 32,108,111,119, +101,114, 91, 34,109,105,109,101, 45,118,101,114,115,105,111,110, 34, 93, 32, 61, + 32, 34, 49, 46, 48, 34, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,108,111, +119,101,114, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101, +115,115, 97,103,101, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32,109,101,115, +103,116, 46,104,101, 97,100,101,114,115, 32, 61, 32, 97,100,106,117,115,116, 95, +104,101, 97,100,101,114,115, 40,109,101,115,103,116, 41, 10, 32, 32, 32, 32, 45, + 45, 32, 99,114,101, 97,116,101, 32, 97,110,100, 32,114,101,116,117,114,110, 32, +109,101,115,115, 97,103,101, 32,115,111,117,114, 99,101, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32, 99,111, 32, 61, 32, 99,111,114,111,117,116,105,110,101, 46, + 99,114,101, 97,116,101, 40,102,117,110, 99,116,105,111,110, 40, 41, 32,115,101, +110,100, 95,109,101,115,115, 97,103,101, 40,109,101,115,103,116, 41, 32,101,110, +100, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116,105, +111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,114, +101,116, 44, 32, 97, 44, 32, 98, 32, 61, 32, 99,111,114,111,117,116,105,110,101, + 46,114,101,115,117,109,101, 40, 99,111, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, +105,102, 32,114,101,116, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 97, + 44, 32, 98, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116, +117,114,110, 32,110,105,108, 44, 32, 97, 32,101,110,100, 10, 32, 32, 32, 32,101, +110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 10, 45, 45, 32, 72,105,103,104, 32,108,101,118,101,108, 32, 83, 77, + 84, 80, 32, 65, 80, 73, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 10,115,101,110,100, 32, 61, 32,115,111, 99,107,101,116, 46,112, +114,111,116,101, 99,116, 40,102,117,110, 99,116,105,111,110, 40,109, 97,105,108, +116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115, 32, 61, 32,111,112,101, +110, 40,109, 97,105,108,116, 46,115,101,114,118,101,114, 44, 32,109, 97,105,108, +116, 46,112,111,114,116, 44, 32,109, 97,105,108,116, 46, 99,114,101, 97,116,101, + 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,101,120,116, 32, 61, 32,115, 58, +103,114,101,101,116, 40,109, 97,105,108,116, 46,100,111,109, 97,105,110, 41, 10, + 32, 32, 32, 32,115, 58, 97,117,116,104, 40,109, 97,105,108,116, 46,117,115,101, +114, 44, 32,109, 97,105,108,116, 46,112, 97,115,115,119,111,114,100, 44, 32,101, +120,116, 41, 10, 32, 32, 32, 32,115, 58,115,101,110,100, 40,109, 97,105,108,116, + 41, 10, 32, 32, 32, 32,115, 58,113,117,105,116, 40, 41, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,115, 58, 99,108,111,115,101, 40, 41, 10,101,110,100, 41, + 10, + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/src/libs/luasocket/src/socket.c b/src/libs/luasocket/src/socket.c new file mode 100644 index 000000000..84165c70e --- /dev/null +++ b/src/libs/luasocket/src/socket.c @@ -0,0 +1,5 @@ +#ifdef _WIN32 +#include "wsocket.c" +#else +#include "usocket.c" +#endif diff --git a/src/libs/luasocket/src/socket.h b/src/libs/luasocket/src/socket.h new file mode 100644 index 000000000..656c7f5d5 --- /dev/null +++ b/src/libs/luasocket/src/socket.h @@ -0,0 +1,76 @@ +#ifndef SOCKET_H +#define SOCKET_H +/*=========================================================================*\ +* Socket compatibilization module +* LuaSocket toolkit +* +* BSD Sockets and WinSock are similar, but there are a few irritating +* differences. Also, not all *nix platforms behave the same. This module +* (and the associated usocket.h and wsocket.h) factor these differences and +* creates a interface compatible with the io.h module. +* +* RCS ID: $Id: socket.h,v 1.20 2005/11/20 07:20:23 diego Exp $ +\*=========================================================================*/ +#include "io.h" + +/*=========================================================================*\ +* Platform specific compatibilization +\*=========================================================================*/ +#ifdef _WIN32 +#include "wsocket.h" +#else +#include "usocket.h" +#endif + +/*=========================================================================*\ +* The connect and accept functions accept a timeout and their +* implementations are somewhat complicated. We chose to move +* the timeout control into this module for these functions in +* order to simplify the modules that use them. +\*=========================================================================*/ +#include "timeout.h" + +/* we are lazy... */ +typedef struct sockaddr SA; + +/*=========================================================================*\ +* Functions bellow implement a comfortable platform independent +* interface to sockets +\*=========================================================================*/ +int socket_open(void); +int socket_close(void); +void socket_destroy(p_socket ps); +void socket_shutdown(p_socket ps, int how); +int socket_sendto(p_socket ps, const char *data, size_t count, + size_t *sent, SA *addr, socklen_t addr_len, p_timeout tm); +int socket_recvfrom(p_socket ps, char *data, size_t count, + size_t *got, SA *addr, socklen_t *addr_len, p_timeout tm); + +void socket_setnonblocking(p_socket ps); +void socket_setblocking(p_socket ps); + +int socket_waitfd(p_socket ps, int sw, p_timeout tm); +int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, + p_timeout tm); + +int socket_connect(p_socket ps, SA *addr, socklen_t addr_len, p_timeout tm); +int socket_create(p_socket ps, int domain, int type, int protocol); +int socket_bind(p_socket ps, SA *addr, socklen_t addr_len); +int socket_listen(p_socket ps, int backlog); +int socket_accept(p_socket ps, p_socket pa, SA *addr, + socklen_t *addr_len, p_timeout tm); + +const char *socket_hoststrerror(int err); +const char *socket_strerror(int err); + +/* these are perfect to use with the io abstraction module + and the buffered input module */ +int socket_send(p_socket ps, const char *data, size_t count, + size_t *sent, p_timeout tm); +int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm); +const char *socket_ioerror(p_socket ps, int err); + +int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp); +int socket_gethostbyname(const char *addr, struct hostent **hp); + +#endif /* SOCKET_H */ diff --git a/src/libs/luasocket/src/socket.lua b/src/libs/luasocket/src/socket.lua new file mode 100644 index 000000000..211adcd1d --- /dev/null +++ b/src/libs/luasocket/src/socket.lua @@ -0,0 +1,133 @@ +----------------------------------------------------------------------------- +-- LuaSocket helper module +-- Author: Diego Nehab +-- RCS ID: $Id: socket.lua,v 1.22 2005/11/22 08:33:29 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local string = require("string") +local math = require("math") +local socket = require("socket.core") +module("socket") + +----------------------------------------------------------------------------- +-- Exported auxiliar functions +----------------------------------------------------------------------------- +function connect(address, port, laddress, lport) + local sock, err = socket.tcp() + if not sock then return nil, err end + if laddress then + local res, err = sock:bind(laddress, lport, -1) + if not res then return nil, err end + end + local res, err = sock:connect(address, port) + if not res then return nil, err end + return sock +end + +function bind(host, port, backlog) + local sock, err = socket.tcp() + if not sock then return nil, err end + sock:setoption("reuseaddr", true) + local res, err = sock:bind(host, port) + if not res then return nil, err end + res, err = sock:listen(backlog) + if not res then return nil, err end + return sock +end + +try = newtry() + +function choose(table) + return function(name, opt1, opt2) + if base.type(name) ~= "string" then + name, opt1, opt2 = "default", name, opt1 + end + local f = table[name or "nil"] + if not f then base.error("unknown key (".. base.tostring(name) ..")", 3) + else return f(opt1, opt2) end + end +end + +----------------------------------------------------------------------------- +-- Socket sources and sinks, conforming to LTN12 +----------------------------------------------------------------------------- +-- create namespaces inside LuaSocket namespace +sourcet = {} +sinkt = {} + +BLOCKSIZE = 2048 + +sinkt["close-when-done"] = function(sock) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function(self, chunk, err) + if not chunk then + sock:close() + return 1 + else return sock:send(chunk) end + end + }) +end + +sinkt["keep-open"] = function(sock) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function(self, chunk, err) + if chunk then return sock:send(chunk) + else return 1 end + end + }) +end + +sinkt["default"] = sinkt["keep-open"] + +sink = choose(sinkt) + +sourcet["by-length"] = function(sock, length) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function() + if length <= 0 then return nil end + local size = math.min(socket.BLOCKSIZE, length) + local chunk, err = sock:receive(size) + if err then return nil, err end + length = length - string.len(chunk) + return chunk + end + }) +end + +sourcet["until-closed"] = function(sock) + local done + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function() + if done then return nil end + local chunk, err, partial = sock:receive(socket.BLOCKSIZE) + if not err then return chunk + elseif err == "closed" then + sock:close() + done = 1 + return partial + else return nil, err end + end + }) +end + + +sourcet["default"] = sourcet["until-closed"] + +source = choose(sourcet) + diff --git a/src/libs/luasocket/src/socket_lua.c b/src/libs/luasocket/src/socket_lua.c new file mode 100644 index 000000000..4f3709e0d --- /dev/null +++ b/src/libs/luasocket/src/socket_lua.c @@ -0,0 +1,217 @@ +/* + * This file is auto-generated by "./lua2c socket.lua socket_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_socket_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 76,117, 97, 83,111, 99,107,101,116, 32,104,101,108,112,101,114, 32,109,111, +100,117,108,101, 10, 45, 45, 32, 65,117,116,104,111,114, 58, 32, 68,105,101,103, +111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36, + 73,100, 58, 32,115,111, 99,107,101,116, 46,108,117, 97, 44,118, 32, 49, 46, 50, + 50, 32, 50, 48, 48, 53, 47, 49, 49, 47, 50, 50, 32, 48, 56, 58, 51, 51, 58, 50, + 57, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97,114, +101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, 32, +100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97,115, +101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, 32, + 61, 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, 10, +108,111, 99, 97,108, 32,109, 97,116,104, 32, 61, 32,114,101,113,117,105,114,101, + 40, 34,109, 97,116,104, 34, 41, 10,108,111, 99, 97,108, 32,115,111, 99,107,101, +116, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,111, 99,107,101,116, 46, + 99,111,114,101, 34, 41, 10,109,111,100,117,108,101, 40, 34,115,111, 99,107,101, +116, 34, 41, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 10, 45, 45, 32, 69,120,112,111,114,116,101,100, 32, 97,117,120,105,108, +105, 97,114, 32,102,117,110, 99,116,105,111,110,115, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, + 32, 99,111,110,110,101, 99,116, 40, 97,100,100,114,101,115,115, 44, 32,112,111, +114,116, 44, 32,108, 97,100,100,114,101,115,115, 44, 32,108,112,111,114,116, 41, + 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,111, 99,107, 44, 32,101,114,114, + 32, 61, 32,115,111, 99,107,101,116, 46,116, 99,112, 40, 41, 10, 32, 32, 32, 32, +105,102, 32,110,111,116, 32,115,111, 99,107, 32,116,104,101,110, 32,114,101,116, +117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, + 32,105,102, 32,108, 97,100,100,114,101,115,115, 32,116,104,101,110, 10, 32, 32, + 32, 32, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,115, 44, 32,101,114,114, + 32, 61, 32,115,111, 99,107, 58, 98,105,110,100, 40,108, 97,100,100,114,101,115, +115, 44, 32,108,112,111,114,116, 44, 32, 45, 49, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,110,111,116, 32,114,101,115, 32,116,104,101,110, 32,114,101, +116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, + 32, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,115, 44, + 32,101,114,114, 32, 61, 32,115,111, 99,107, 58, 99,111,110,110,101, 99,116, 40, + 97,100,100,114,101,115,115, 44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,105, +102, 32,110,111,116, 32,114,101,115, 32,116,104,101,110, 32,114,101,116,117,114, +110, 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,115,111, 99,107, 10,101,110,100, 10, 10,102,117,110, 99, +116,105,111,110, 32, 98,105,110,100, 40,104,111,115,116, 44, 32,112,111,114,116, + 44, 32, 98, 97, 99,107,108,111,103, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, + 32,115,111, 99,107, 44, 32,101,114,114, 32, 61, 32,115,111, 99,107,101,116, 46, +116, 99,112, 40, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,115,111, 99, +107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101, +114,114, 32,101,110,100, 10, 32, 32, 32, 32,115,111, 99,107, 58,115,101,116,111, +112,116,105,111,110, 40, 34,114,101,117,115,101, 97,100,100,114, 34, 44, 32,116, +114,117,101, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101,115, 44, 32, +101,114,114, 32, 61, 32,115,111, 99,107, 58, 98,105,110,100, 40,104,111,115,116, + 44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114, +101,115, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32, +101,114,114, 32,101,110,100, 10, 32, 32, 32, 32,114,101,115, 44, 32,101,114,114, + 32, 61, 32,115,111, 99,107, 58,108,105,115,116,101,110, 40, 98, 97, 99,107,108, +111,103, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,115, 32,116, +104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32, +101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,111, 99,107, 10, +101,110,100, 10, 10,116,114,121, 32, 61, 32,110,101,119,116,114,121, 40, 41, 10, + 10,102,117,110, 99,116,105,111,110, 32, 99,104,111,111,115,101, 40,116, 97, 98, +108,101, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,102,117,110, 99,116, +105,111,110, 40,110, 97,109,101, 44, 32,111,112,116, 49, 44, 32,111,112,116, 50, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46,116,121, +112,101, 40,110, 97,109,101, 41, 32,126, 61, 32, 34,115,116,114,105,110,103, 34, + 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,110, 97, +109,101, 44, 32,111,112,116, 49, 44, 32,111,112,116, 50, 32, 61, 32, 34,100,101, +102, 97,117,108,116, 34, 44, 32,110, 97,109,101, 44, 32,111,112,116, 49, 10, 32, + 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,108, +111, 99, 97,108, 32,102, 32, 61, 32,116, 97, 98,108,101, 91,110, 97,109,101, 32, +111,114, 32, 34,110,105,108, 34, 93, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, + 32,110,111,116, 32,102, 32,116,104,101,110, 32, 98, 97,115,101, 46,101,114,114, +111,114, 40, 34,117,110,107,110,111,119,110, 32,107,101,121, 32, 40, 34, 46, 46, + 32, 98, 97,115,101, 46,116,111,115,116,114,105,110,103, 40,110, 97,109,101, 41, + 32, 46, 46, 34, 41, 34, 44, 32, 51, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,101, +108,115,101, 32,114,101,116,117,114,110, 32,102, 40,111,112,116, 49, 44, 32,111, +112,116, 50, 41, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 10,101,110,100, + 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, + 45, 45, 32, 83,111, 99,107,101,116, 32,115,111,117,114, 99,101,115, 32, 97,110, +100, 32,115,105,110,107,115, 44, 32, 99,111,110,102,111,114,109,105,110,103, 32, +116,111, 32, 76, 84, 78, 49, 50, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 99,114,101, 97,116,101, 32,110, 97,109, +101,115,112, 97, 99,101,115, 32,105,110,115,105,100,101, 32, 76,117, 97, 83,111, + 99,107,101,116, 32,110, 97,109,101,115,112, 97, 99,101, 10,115,111,117,114, 99, +101,116, 32, 61, 32,123,125, 10,115,105,110,107,116, 32, 61, 32,123,125, 10, 10, + 66, 76, 79, 67, 75, 83, 73, 90, 69, 32, 61, 32, 50, 48, 52, 56, 10, 10,115,105, +110,107,116, 91, 34, 99,108,111,115,101, 45,119,104,101,110, 45,100,111,110,101, + 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 41, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109, +101,116, 97,116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103, +101,116,102,100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101, +116,117,114,110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110, +100, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102, +117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99, +107, 58,100,105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, + 32,123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32, +102,117,110, 99,116,105,111,110, 40,115,101,108,102, 44, 32, 99,104,117,110,107, + 44, 32,101,114,114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105, +102, 32,110,111,116, 32, 99,104,117,110,107, 32,116,104,101,110, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,111, 99,107, 58, 99,108, +111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32, 49, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58, +115,101,110,100, 40, 99,104,117,110,107, 41, 32,101,110,100, 10, 32, 32, 32, 32, + 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110,100, 10, 10, +115,105,110,107,116, 91, 34,107,101,101,112, 45,111,112,101,110, 34, 93, 32, 61, + 32,102,117,110, 99,116,105,111,110, 40,115,111, 99,107, 41, 10, 32, 32, 32, 32, +114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, + 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102,100, + 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, + 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, 32, + 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99,116, +105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100,105, +114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, 32, + 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, 99, +116,105,111,110, 40,115,101,108,102, 44, 32, 99,104,117,110,107, 44, 32,101,114, +114, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, 99,104, +117,110,107, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,115,111, 99,107, + 58,115,101,110,100, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, 49, 32,101, +110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125, + 41, 10,101,110,100, 10, 10,115,105,110,107,116, 91, 34,100,101,102, 97,117,108, +116, 34, 93, 32, 61, 32,115,105,110,107,116, 91, 34,107,101,101,112, 45,111,112, +101,110, 34, 93, 10, 10,115,105,110,107, 32, 61, 32, 99,104,111,111,115,101, 40, +115,105,110,107,116, 41, 10, 10,115,111,117,114, 99,101,116, 91, 34, 98,121, 45, +108,101,110,103,116,104, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, +115,111, 99,107, 44, 32,108,101,110,103,116,104, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, 97,116, 97, 98, +108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101,116,102,100, 32, 61, + 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115, +111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, 44, 10, 32, 32, 32, + 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117,110, 99,116,105,111, +110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, 58,100,105,114,116, +121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32,123, 10, 32, 32, 32, + 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102,117,110, 99,116,105, +111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +108,101,110,103,116,104, 32, 60, 61, 32, 48, 32,116,104,101,110, 32,114,101,116, +117,114,110, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,108,111, 99, 97,108, 32,115,105,122,101, 32, 61, 32,109, 97,116, +104, 46,109,105,110, 40,115,111, 99,107,101,116, 46, 66, 76, 79, 67, 75, 83, 73, + 90, 69, 44, 32,108,101,110,103,116,104, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,101,114,114, + 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105,118,101, 40,115,105,122,101, + 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,101,114,114, + 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114, +114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,108,101, +110,103,116,104, 32, 61, 32,108,101,110,103,116,104, 32, 45, 32,115,116,114,105, +110,103, 46,108,101,110, 40, 99,104,117,110,107, 41, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 99,104,117,110,107, 10, 32, + 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,125, 41, 10,101,110, +100, 10, 10,115,111,117,114, 99,101,116, 91, 34,117,110,116,105,108, 45, 99,108, +111,115,101,100, 34, 93, 32, 61, 32,102,117,110, 99,116,105,111,110, 40,115,111, + 99,107, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,100,111,110,101, 10, 32, + 32, 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101, +116, 97,116, 97, 98,108,101, 40,123, 10, 32, 32, 32, 32, 32, 32, 32, 32,103,101, +116,102,100, 32, 61, 32,102,117,110, 99,116,105,111,110, 40, 41, 32,114,101,116, +117,114,110, 32,115,111, 99,107, 58,103,101,116,102,100, 40, 41, 32,101,110,100, + 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,100,105,114,116,121, 32, 61, 32,102,117, +110, 99,116,105,111,110, 40, 41, 32,114,101,116,117,114,110, 32,115,111, 99,107, + 58,100,105,114,116,121, 40, 41, 32,101,110,100, 10, 32, 32, 32, 32,125, 44, 32, +123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 95, 99, 97,108,108, 32, 61, 32,102, +117,110, 99,116,105,111,110, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,100,111,110,101, 32,116,104,101,110, 32,114,101,116,117,114, +110, 32,110,105,108, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,108,111, 99, 97,108, 32, 99,104,117,110,107, 44, 32,101,114,114, 44, 32, +112, 97,114,116,105, 97,108, 32, 61, 32,115,111, 99,107, 58,114,101, 99,101,105, +118,101, 40,115,111, 99,107,101,116, 46, 66, 76, 79, 67, 75, 83, 73, 90, 69, 41, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32, +101,114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 99,104,117,110, +107, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101,105,102, + 32,101,114,114, 32, 61, 61, 32, 34, 99,108,111,115,101,100, 34, 32,116,104,101, +110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,115,111, + 99,107, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,100,111,110,101, 32, 61, 32, 49, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,112, + 97,114,116,105, 97,108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101, +108,115,101, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101,114,114, 32, +101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, +125, 41, 10,101,110,100, 10, 10, 10,115,111,117,114, 99,101,116, 91, 34,100,101, +102, 97,117,108,116, 34, 93, 32, 61, 32,115,111,117,114, 99,101,116, 91, 34,117, +110,116,105,108, 45, 99,108,111,115,101,100, 34, 93, 10, 10,115,111,117,114, 99, +101, 32, 61, 32, 99,104,111,111,115,101, 40,115,111,117,114, 99,101,116, 41, 10, + 10, + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/src/libs/luasocket/src/tcp.c b/src/libs/luasocket/src/tcp.c new file mode 100644 index 000000000..6b8a79b4b --- /dev/null +++ b/src/libs/luasocket/src/tcp.c @@ -0,0 +1,339 @@ +/*=========================================================================*\ +* TCP object +* LuaSocket toolkit +* +* RCS ID: $Id: tcp.c,v 1.41 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include <string.h> + +#include "lua.h" +#include "lauxlib.h" + +#include "auxiliar.h" +#include "socket.h" +#include "inet.h" +#include "options.h" +#include "tcp.h" + +/*=========================================================================*\ +* Internal function prototypes +\*=========================================================================*/ +static int global_create(lua_State *L); +static int meth_connect(lua_State *L); +static int meth_listen(lua_State *L); +static int meth_bind(lua_State *L); +static int meth_send(lua_State *L); +static int meth_getstats(lua_State *L); +static int meth_setstats(lua_State *L); +static int meth_getsockname(lua_State *L); +static int meth_getpeername(lua_State *L); +static int meth_shutdown(lua_State *L); +static int meth_receive(lua_State *L); +static int meth_accept(lua_State *L); +static int meth_close(lua_State *L); +static int meth_setoption(lua_State *L); +static int meth_settimeout(lua_State *L); +static int meth_getfd(lua_State *L); +static int meth_setfd(lua_State *L); +static int meth_dirty(lua_State *L); + +/* tcp object methods */ +static luaL_reg tcp[] = { + {"__gc", meth_close}, + {"__tostring", auxiliar_tostring}, + {"accept", meth_accept}, + {"bind", meth_bind}, + {"close", meth_close}, + {"connect", meth_connect}, + {"dirty", meth_dirty}, + {"getfd", meth_getfd}, + {"getpeername", meth_getpeername}, + {"getsockname", meth_getsockname}, + {"getstats", meth_getstats}, + {"setstats", meth_setstats}, + {"listen", meth_listen}, + {"receive", meth_receive}, + {"send", meth_send}, + {"setfd", meth_setfd}, + {"setoption", meth_setoption}, + {"setpeername", meth_connect}, + {"setsockname", meth_bind}, + {"settimeout", meth_settimeout}, + {"shutdown", meth_shutdown}, + {NULL, NULL} +}; + +/* socket option handlers */ +static t_opt opt[] = { + {"keepalive", opt_keepalive}, + {"reuseaddr", opt_reuseaddr}, + {"tcp-nodelay", opt_tcp_nodelay}, + {"linger", opt_linger}, + {NULL, NULL} +}; + +/* functions in library namespace */ +static luaL_reg func[] = { + {"tcp", global_create}, + {NULL, NULL} +}; + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int tcp_open(lua_State *L) +{ + /* create classes */ + auxiliar_newclass(L, "tcp{master}", tcp); + auxiliar_newclass(L, "tcp{client}", tcp); + auxiliar_newclass(L, "tcp{server}", tcp); + /* create class groups */ + auxiliar_add2group(L, "tcp{master}", "tcp{any}"); + auxiliar_add2group(L, "tcp{client}", "tcp{any}"); + auxiliar_add2group(L, "tcp{server}", "tcp{any}"); + /* define library functions */ + luaL_openlib(L, NULL, func, 0); + return 0; +} + +/*=========================================================================*\ +* Lua methods +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Just call buffered IO methods +\*-------------------------------------------------------------------------*/ +static int meth_send(lua_State *L) { + p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); + return buffer_meth_send(L, &tcp->buf); +} + +static int meth_receive(lua_State *L) { + p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); + return buffer_meth_receive(L, &tcp->buf); +} + +static int meth_getstats(lua_State *L) { + p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); + return buffer_meth_getstats(L, &tcp->buf); +} + +static int meth_setstats(lua_State *L) { + p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); + return buffer_meth_setstats(L, &tcp->buf); +} + +/*-------------------------------------------------------------------------*\ +* Just call option handler +\*-------------------------------------------------------------------------*/ +static int meth_setoption(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + return opt_meth_setoption(L, opt, &tcp->sock); +} + +/*-------------------------------------------------------------------------*\ +* Select support methods +\*-------------------------------------------------------------------------*/ +static int meth_getfd(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + lua_pushnumber(L, (int) tcp->sock); + return 1; +} + +/* this is very dangerous, but can be handy for those that are brave enough */ +static int meth_setfd(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + tcp->sock = (t_socket) luaL_checknumber(L, 2); + return 0; +} + +static int meth_dirty(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + lua_pushboolean(L, !buffer_isempty(&tcp->buf)); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Waits for and returns a client object attempting connection to the +* server object +\*-------------------------------------------------------------------------*/ +static int meth_accept(lua_State *L) +{ + p_tcp server = (p_tcp) auxiliar_checkclass(L, "tcp{server}", 1); + p_timeout tm = timeout_markstart(&server->tm); + t_socket sock; + int err = socket_accept(&server->sock, &sock, NULL, NULL, tm); + /* if successful, push client socket */ + if (err == IO_DONE) { + p_tcp clnt = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); + auxiliar_setclass(L, "tcp{client}", -1); + /* initialize structure fields */ + socket_setnonblocking(&sock); + clnt->sock = sock; + io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv, + (p_error) socket_ioerror, &clnt->sock); + timeout_init(&clnt->tm, -1, -1); + buffer_init(&clnt->buf, &clnt->io, &clnt->tm); + return 1; + } else { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } +} + +/*-------------------------------------------------------------------------*\ +* Binds an object to an address +\*-------------------------------------------------------------------------*/ +static int meth_bind(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); + const char *address = luaL_checkstring(L, 2); + unsigned short port = (unsigned short) luaL_checknumber(L, 3); + const char *err = inet_trybind(&tcp->sock, address, port); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Turns a master tcp object into a client object. +\*-------------------------------------------------------------------------*/ +static int meth_connect(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + const char *address = luaL_checkstring(L, 2); + unsigned short port = (unsigned short) luaL_checknumber(L, 3); + p_timeout tm = timeout_markstart(&tcp->tm); + const char *err = inet_tryconnect(&tcp->sock, address, port, tm); + /* have to set the class even if it failed due to non-blocking connects */ + auxiliar_setclass(L, "tcp{client}", 1); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + /* turn master object into a client object */ + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Closes socket used by object +\*-------------------------------------------------------------------------*/ +static int meth_close(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + socket_destroy(&tcp->sock); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Puts the sockt in listen mode +\*-------------------------------------------------------------------------*/ +static int meth_listen(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); + int backlog = (int) luaL_optnumber(L, 2, 32); + int err = socket_listen(&tcp->sock, backlog); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } + /* turn master object into a server object */ + auxiliar_setclass(L, "tcp{server}", 1); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Shuts the connection down partially +\*-------------------------------------------------------------------------*/ +static int meth_shutdown(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); + const char *how = luaL_optstring(L, 2, "both"); + switch (how[0]) { + case 'b': + if (strcmp(how, "both")) goto error; + socket_shutdown(&tcp->sock, 2); + break; + case 's': + if (strcmp(how, "send")) goto error; + socket_shutdown(&tcp->sock, 1); + break; + case 'r': + if (strcmp(how, "receive")) goto error; + socket_shutdown(&tcp->sock, 0); + break; + } + lua_pushnumber(L, 1); + return 1; +error: + luaL_argerror(L, 2, "invalid shutdown method"); + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Just call inet methods +\*-------------------------------------------------------------------------*/ +static int meth_getpeername(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + return inet_meth_getpeername(L, &tcp->sock); +} + +static int meth_getsockname(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + return inet_meth_getsockname(L, &tcp->sock); +} + +/*-------------------------------------------------------------------------*\ +* Just call tm methods +\*-------------------------------------------------------------------------*/ +static int meth_settimeout(lua_State *L) +{ + p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); + return timeout_meth_settimeout(L, &tcp->tm); +} + +/*=========================================================================*\ +* Library functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Creates a master tcp object +\*-------------------------------------------------------------------------*/ +static int global_create(lua_State *L) +{ + t_socket sock; + const char *err = inet_trycreate(&sock, SOCK_STREAM); + /* try to allocate a system socket */ + if (!err) { + /* allocate tcp object */ + p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); + /* set its type as master object */ + auxiliar_setclass(L, "tcp{master}", -1); + /* initialize remaining structure fields */ + socket_setnonblocking(&sock); + tcp->sock = sock; + io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, + (p_error) socket_ioerror, &tcp->sock); + timeout_init(&tcp->tm, -1, -1); + buffer_init(&tcp->buf, &tcp->io, &tcp->tm); + return 1; + } else { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } +} diff --git a/src/libs/luasocket/src/tcp.h b/src/libs/luasocket/src/tcp.h new file mode 100644 index 000000000..511357f37 --- /dev/null +++ b/src/libs/luasocket/src/tcp.h @@ -0,0 +1,36 @@ +#ifndef TCP_H +#define TCP_H +/*=========================================================================*\ +* TCP object +* LuaSocket toolkit +* +* The tcp.h module is basicly a glue that puts together modules buffer.h, +* timeout.h socket.h and inet.h to provide the LuaSocket TCP (AF_INET, +* SOCK_STREAM) support. +* +* Three classes are defined: master, client and server. The master class is +* a newly created tcp object, that has not been bound or connected. Server +* objects are tcp objects bound to some local address. Client objects are +* tcp objects either connected to some address or returned by the accept +* method of a server object. +* +* RCS ID: $Id: tcp.h,v 1.7 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include "lua.h" + +#include "buffer.h" +#include "timeout.h" +#include "socket.h" + +typedef struct t_tcp_ { + t_socket sock; + t_io io; + t_buffer buf; + t_timeout tm; +} t_tcp; + +typedef t_tcp *p_tcp; + +int tcp_open(lua_State *L); + +#endif /* TCP_H */ diff --git a/src/libs/luasocket/src/timeout.c b/src/libs/luasocket/src/timeout.c new file mode 100644 index 000000000..c1df10218 --- /dev/null +++ b/src/libs/luasocket/src/timeout.c @@ -0,0 +1,207 @@ +/*=========================================================================*\ +* Timeout management functions +* LuaSocket toolkit +* +* RCS ID: $Id: timeout.c,v 1.30 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include <stdio.h> + +#include "lua.h" +#include "lauxlib.h" + +#include "auxiliar.h" +#include "timeout.h" + +#ifdef _WIN32 +#include <windows.h> +#else +#include <time.h> +#include <sys/time.h> +#endif + +/* min and max macros */ +#ifndef MIN +#define MIN(x, y) ((x) < (y) ? x : y) +#endif +#ifndef MAX +#define MAX(x, y) ((x) > (y) ? x : y) +#endif + +/*=========================================================================*\ +* Internal function prototypes +\*=========================================================================*/ +static int timeout_lua_gettime(lua_State *L); +static int timeout_lua_sleep(lua_State *L); + +static luaL_reg func[] = { + { "gettime", timeout_lua_gettime }, + { "sleep", timeout_lua_sleep }, + { NULL, NULL } +}; + +/*=========================================================================*\ +* Exported functions. +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Initialize structure +\*-------------------------------------------------------------------------*/ +void timeout_init(p_timeout tm, double block, double total) { + tm->block = block; + tm->total = total; +} + +/*-------------------------------------------------------------------------*\ +* Determines how much time we have left for the next system call, +* if the previous call was successful +* Input +* tm: timeout control structure +* Returns +* the number of ms left or -1 if there is no time limit +\*-------------------------------------------------------------------------*/ +double timeout_get(p_timeout tm) { + if (tm->block < 0.0 && tm->total < 0.0) { + return -1; + } else if (tm->block < 0.0) { + double t = tm->total - timeout_gettime() + tm->start; + return MAX(t, 0.0); + } else if (tm->total < 0.0) { + return tm->block; + } else { + double t = tm->total - timeout_gettime() + tm->start; + return MIN(tm->block, MAX(t, 0.0)); + } +} + +/*-------------------------------------------------------------------------*\ +* Returns time since start of operation +* Input +* tm: timeout control structure +* Returns +* start field of structure +\*-------------------------------------------------------------------------*/ +double timeout_getstart(p_timeout tm) { + return tm->start; +} + +/*-------------------------------------------------------------------------*\ +* Determines how much time we have left for the next system call, +* if the previous call was a failure +* Input +* tm: timeout control structure +* Returns +* the number of ms left or -1 if there is no time limit +\*-------------------------------------------------------------------------*/ +double timeout_getretry(p_timeout tm) { + if (tm->block < 0.0 && tm->total < 0.0) { + return -1; + } else if (tm->block < 0.0) { + double t = tm->total - timeout_gettime() + tm->start; + return MAX(t, 0.0); + } else if (tm->total < 0.0) { + double t = tm->block - timeout_gettime() + tm->start; + return MAX(t, 0.0); + } else { + double t = tm->total - timeout_gettime() + tm->start; + return MIN(tm->block, MAX(t, 0.0)); + } +} + +/*-------------------------------------------------------------------------*\ +* Marks the operation start time in structure +* Input +* tm: timeout control structure +\*-------------------------------------------------------------------------*/ +p_timeout timeout_markstart(p_timeout tm) { + tm->start = timeout_gettime(); + return tm; +} + +/*-------------------------------------------------------------------------*\ +* Gets time in s, relative to January 1, 1970 (UTC) +* Returns +* time in s. +\*-------------------------------------------------------------------------*/ +#ifdef _WIN32 +double timeout_gettime(void) { + FILETIME ft; + double t; + GetSystemTimeAsFileTime(&ft); + /* Windows file time (time since January 1, 1601 (UTC)) */ + t = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7); + /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */ + return (t - 11644473600.0); +} +#else +double timeout_gettime(void) { + struct timeval v; + gettimeofday(&v, (struct timezone *) NULL); + /* Unix Epoch time (time since January 1, 1970 (UTC)) */ + return v.tv_sec + v.tv_usec/1.0e6; +} +#endif + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int timeout_open(lua_State *L) { + luaL_openlib(L, NULL, func, 0); + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Sets timeout values for IO operations +* Lua Input: base, time [, mode] +* time: time out value in seconds +* mode: "b" for block timeout, "t" for total timeout. (default: b) +\*-------------------------------------------------------------------------*/ +int timeout_meth_settimeout(lua_State *L, p_timeout tm) { + double t = luaL_optnumber(L, 2, -1); + const char *mode = luaL_optstring(L, 3, "b"); + switch (*mode) { + case 'b': + tm->block = t; + break; + case 'r': case 't': + tm->total = t; + break; + default: + luaL_argcheck(L, 0, 3, "invalid timeout mode"); + break; + } + lua_pushnumber(L, 1); + return 1; +} + +/*=========================================================================*\ +* Test support functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Returns the time the system has been up, in secconds. +\*-------------------------------------------------------------------------*/ +static int timeout_lua_gettime(lua_State *L) +{ + lua_pushnumber(L, timeout_gettime()); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Sleep for n seconds. +\*-------------------------------------------------------------------------*/ +int timeout_lua_sleep(lua_State *L) +{ + double n = luaL_checknumber(L, 1); +#ifdef _WIN32 + Sleep((int)(n*1000)); +#else + struct timespec t, r; + t.tv_sec = (int) n; + n -= t.tv_sec; + t.tv_nsec = (int) (n * 1000000000); + if (t.tv_nsec >= 1000000000) t.tv_nsec = 999999999; + while (nanosleep(&t, &r) != 0) { + t.tv_sec = r.tv_sec; + t.tv_nsec = r.tv_nsec; + } +#endif + return 0; +} diff --git a/src/libs/luasocket/src/timeout.h b/src/libs/luasocket/src/timeout.h new file mode 100644 index 000000000..d2d896410 --- /dev/null +++ b/src/libs/luasocket/src/timeout.h @@ -0,0 +1,30 @@ +#ifndef TIMEOUT_H +#define TIMEOUT_H +/*=========================================================================*\ +* Timeout management functions +* LuaSocket toolkit +* +* RCS ID: $Id: timeout.h,v 1.14 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include "lua.h" + +/* timeout control structure */ +typedef struct t_timeout_ { + double block; /* maximum time for blocking calls */ + double total; /* total number of miliseconds for operation */ + double start; /* time of start of operation */ +} t_timeout; +typedef t_timeout *p_timeout; + +int timeout_open(lua_State *L); +void timeout_init(p_timeout tm, double block, double total); +double timeout_get(p_timeout tm); +double timeout_getretry(p_timeout tm); +p_timeout timeout_markstart(p_timeout tm); +double timeout_getstart(p_timeout tm); +double timeout_gettime(void); +int timeout_meth_settimeout(lua_State *L, p_timeout tm); + +#define timeout_iszero(tm) ((tm)->block == 0.0) + +#endif /* TIMEOUT_H */ diff --git a/src/libs/luasocket/src/tp.lua b/src/libs/luasocket/src/tp.lua new file mode 100644 index 000000000..068386949 --- /dev/null +++ b/src/libs/luasocket/src/tp.lua @@ -0,0 +1,123 @@ +----------------------------------------------------------------------------- +-- Unified SMTP/FTP subsystem +-- LuaSocket toolkit. +-- Author: Diego Nehab +-- RCS ID: $Id: tp.lua,v 1.22 2006/03/14 09:04:15 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local string = require("string") +local socket = require("socket") +local ltn12 = require("ltn12") +module("socket.tp") + +----------------------------------------------------------------------------- +-- Program constants +----------------------------------------------------------------------------- +TIMEOUT = 60 + +----------------------------------------------------------------------------- +-- Implementation +----------------------------------------------------------------------------- +-- gets server reply (works for SMTP and FTP) +local function get_reply(c) + local code, current, sep + local line, err = c:receive() + local reply = line + if err then return nil, err end + code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)")) + if not code then return nil, "invalid server reply" end + if sep == "-" then -- reply is multiline + repeat + line, err = c:receive() + if err then return nil, err end + current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)")) + reply = reply .. "\n" .. line + -- reply ends with same code + until code == current and sep == " " + end + return code, reply +end + +-- metatable for sock object +local metat = { __index = {} } + +function metat.__index:check(ok) + local code, reply = get_reply(self.c) + if not code then return nil, reply end + if base.type(ok) ~= "function" then + if base.type(ok) == "table" then + for i, v in base.ipairs(ok) do + if string.find(code, v) then + return base.tonumber(code), reply + end + end + return nil, reply + else + if string.find(code, ok) then return base.tonumber(code), reply + else return nil, reply end + end + else return ok(base.tonumber(code), reply) end +end + +function metat.__index:command(cmd, arg) + if arg then + return self.c:send(cmd .. " " .. arg.. "\r\n") + else + return self.c:send(cmd .. "\r\n") + end +end + +function metat.__index:sink(snk, pat) + local chunk, err = c:receive(pat) + return snk(chunk, err) +end + +function metat.__index:send(data) + return self.c:send(data) +end + +function metat.__index:receive(pat) + return self.c:receive(pat) +end + +function metat.__index:getfd() + return self.c:getfd() +end + +function metat.__index:dirty() + return self.c:dirty() +end + +function metat.__index:getcontrol() + return self.c +end + +function metat.__index:source(source, step) + local sink = socket.sink("keep-open", self.c) + local ret, err = ltn12.pump.all(source, sink, step or ltn12.pump.step) + return ret, err +end + +-- closes the underlying c +function metat.__index:close() + self.c:close() + return 1 +end + +-- connect with server and return c object +function connect(host, port, timeout, create) + local c, e = (create or socket.tcp)() + if not c then return nil, e end + c:settimeout(timeout or TIMEOUT) + local r, e = c:connect(host, port) + if not r then + c:close() + return nil, e + end + return base.setmetatable({c = c}, metat) +end + diff --git a/src/libs/luasocket/src/tp_lua.c b/src/libs/luasocket/src/tp_lua.c new file mode 100644 index 000000000..897579d53 --- /dev/null +++ b/src/libs/luasocket/src/tp_lua.c @@ -0,0 +1,194 @@ +/* + * This file is auto-generated by "./lua2c tp.lua tp_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_tp_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 85,110,105,102,105,101,100, 32, 83, 77, 84, 80, 47, 70, 84, 80, 32,115,117, + 98,115,121,115,116,101,109, 10, 45, 45, 32, 76,117, 97, 83,111, 99,107,101,116, + 32,116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65,117,116,104,111,114, 58, + 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, 45, 32, 82, 67, 83, 32, + 73, 68, 58, 32, 36, 73,100, 58, 32,116,112, 46,108,117, 97, 44,118, 32, 49, 46, + 50, 50, 32, 50, 48, 48, 54, 47, 48, 51, 47, 49, 52, 32, 48, 57, 58, 48, 52, 58, + 49, 53, 32,100,105,101,103,111, 32, 69,120,112, 32, 36, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 68,101, 99,108, 97, +114,101, 32,109,111,100,117,108,101, 32, 97,110,100, 32,105,109,112,111,114,116, + 32,100,101,112,101,110,100,101,110, 99,105,101,115, 10, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, 32, 98, 97, +115,101, 32, 61, 32, 95, 71, 10,108,111, 99, 97,108, 32,115,116,114,105,110,103, + 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115,116,114,105,110,103, 34, 41, + 10,108,111, 99, 97,108, 32,115,111, 99,107,101,116, 32, 61, 32,114,101,113,117, +105,114,101, 40, 34,115,111, 99,107,101,116, 34, 41, 10,108,111, 99, 97,108, 32, +108,116,110, 49, 50, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,108,116,110, + 49, 50, 34, 41, 10,109,111,100,117,108,101, 40, 34,115,111, 99,107,101,116, 46, +116,112, 34, 41, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 10, 45, 45, 32, 80,114,111,103,114, 97,109, 32, 99,111,110,115,116, + 97,110,116,115, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 10, 84, 73, 77, 69, 79, 85, 84, 32, 61, 32, 54, 48, 10, 10, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 73,109, +112,108,101,109,101,110,116, 97,116,105,111,110, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32,103,101,116,115, 32,115, +101,114,118,101,114, 32,114,101,112,108,121, 32, 40,119,111,114,107,115, 32,102, +111,114, 32, 83, 77, 84, 80, 32, 97,110,100, 32, 70, 84, 80, 41, 10,108,111, 99, + 97,108, 32,102,117,110, 99,116,105,111,110, 32,103,101,116, 95,114,101,112,108, +121, 40, 99, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, 44, + 32, 99,117,114,114,101,110,116, 44, 32,115,101,112, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,108,105,110,101, 44, 32,101,114,114, 32, 61, 32, 99, 58,114,101, + 99,101,105,118,101, 40, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,114,101, +112,108,121, 32, 61, 32,108,105,110,101, 10, 32, 32, 32, 32,105,102, 32,101,114, +114, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,101, +114,114, 32,101,110,100, 10, 32, 32, 32, 32, 99,111,100,101, 44, 32,115,101,112, + 32, 61, 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32,115,116, +114,105,110,103, 46,102,105,110,100, 40,108,105,110,101, 44, 32, 34, 94, 40, 37, +100, 37,100, 37,100, 41, 40, 46, 63, 41, 34, 41, 41, 10, 32, 32, 32, 32,105,102, + 32,110,111,116, 32, 99,111,100,101, 32,116,104,101,110, 32,114,101,116,117,114, +110, 32,110,105,108, 44, 32, 34,105,110,118, 97,108,105,100, 32,115,101,114,118, +101,114, 32,114,101,112,108,121, 34, 32,101,110,100, 10, 32, 32, 32, 32,105,102, + 32,115,101,112, 32, 61, 61, 32, 34, 45, 34, 32,116,104,101,110, 32, 45, 45, 32, +114,101,112,108,121, 32,105,115, 32,109,117,108,116,105,108,105,110,101, 10, 32, + 32, 32, 32, 32, 32, 32, 32,114,101,112,101, 97,116, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,108,105,110,101, 44, 32,101,114,114, 32, 61, 32, 99, 58, +114,101, 99,101,105,118,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,101,114,114, 32,116,104,101,110, 32,114,101,116,117,114,110, + 32,110,105,108, 44, 32,101,114,114, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 99,117,114,114,101,110,116, 44, 32,115,101,112, 32, 61, + 32,115,111, 99,107,101,116, 46,115,107,105,112, 40, 50, 44, 32,115,116,114,105, +110,103, 46,102,105,110,100, 40,108,105,110,101, 44, 32, 34, 94, 40, 37,100, 37, +100, 37,100, 41, 40, 46, 63, 41, 34, 41, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,114,101,112,108,121, 32, 61, 32,114,101,112,108,121, 32, 46, 46, + 32, 34, 92,110, 34, 32, 46, 46, 32,108,105,110,101, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 45, 45, 32,114,101,112,108,121, 32,101,110,100,115, 32,119,105,116,104, + 32,115, 97,109,101, 32, 99,111,100,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,117, +110,116,105,108, 32, 99,111,100,101, 32, 61, 61, 32, 99,117,114,114,101,110,116, + 32, 97,110,100, 32,115,101,112, 32, 61, 61, 32, 34, 32, 34, 10, 32, 32, 32, 32, +101,110,100, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32, 99,111,100,101, 44, + 32,114,101,112,108,121, 10,101,110,100, 10, 10, 45, 45, 32,109,101,116, 97,116, + 97, 98,108,101, 32,102,111,114, 32,115,111, 99,107, 32,111, 98,106,101, 99,116, + 10,108,111, 99, 97,108, 32,109,101,116, 97,116, 32, 61, 32,123, 32, 95, 95,105, +110,100,101,120, 32, 61, 32,123,125, 32,125, 10, 10,102,117,110, 99,116,105,111, +110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99,104,101, 99, +107, 40,111,107, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, 99,111,100,101, + 44, 32,114,101,112,108,121, 32, 61, 32,103,101,116, 95,114,101,112,108,121, 40, +115,101,108,102, 46, 99, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99, +111,100,101, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,110,105,108, 44, + 32,114,101,112,108,121, 32,101,110,100, 10, 32, 32, 32, 32,105,102, 32, 98, 97, +115,101, 46,116,121,112,101, 40,111,107, 41, 32,126, 61, 32, 34,102,117,110, 99, +116,105,111,110, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,105, +102, 32, 98, 97,115,101, 46,116,121,112,101, 40,111,107, 41, 32, 61, 61, 32, 34, +116, 97, 98,108,101, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32,102,111,114, 32,105, 44, 32,118, 32,105,110, 32, 98, 97,115,101, + 46,105,112, 97,105,114,115, 40,111,107, 41, 32,100,111, 10, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,115,116,114,105,110,103, + 46,102,105,110,100, 40, 99,111,100,101, 44, 32,118, 41, 32,116,104,101,110, 10, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,116,117,114,110, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, + 40, 99,111,100,101, 41, 44, 32,114,101,112,108,121, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,114,101,112,108,121, 10, + 32, 32, 32, 32, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,105,102, 32,115,116,114,105,110,103, 46,102,105,110,100, 40, + 99,111,100,101, 44, 32,111,107, 41, 32,116,104,101,110, 32,114,101,116,117,114, +110, 32, 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, 40, 99,111,100,101, + 41, 44, 32,114,101,112,108,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,101,108,115,101, 32,114,101,116,117,114,110, 32,110,105,108, 44, 32,114,101, +112,108,121, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, + 32, 32, 32, 32,101,108,115,101, 32,114,101,116,117,114,110, 32,111,107, 40, 98, + 97,115,101, 46,116,111,110,117,109, 98,101,114, 40, 99,111,100,101, 41, 44, 32, +114,101,112,108,121, 41, 32,101,110,100, 10,101,110,100, 10, 10,102,117,110, 99, +116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58, 99, +111,109,109, 97,110,100, 40, 99,109,100, 44, 32, 97,114,103, 41, 10, 32, 32, 32, + 32,105,102, 32, 97,114,103, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, + 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 58,115,101,110,100, 40, + 99,109,100, 32, 46, 46, 32, 34, 32, 34, 32, 46, 46, 32, 97,114,103, 46, 46, 32, + 34, 92,114, 92,110, 34, 41, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, + 32, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 58,115, +101,110,100, 40, 99,109,100, 32, 46, 46, 32, 34, 92,114, 92,110, 34, 41, 10, 32, + 32, 32, 32,101,110,100, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, + 32,109,101,116, 97,116, 46, 95, 95,105,110,100,101,120, 58,115,105,110,107, 40, +115,110,107, 44, 32,112, 97,116, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32, + 99,104,117,110,107, 44, 32,101,114,114, 32, 61, 32, 99, 58,114,101, 99,101,105, +118,101, 40,112, 97,116, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115, +110,107, 40, 99,104,117,110,107, 44, 32,101,114,114, 41, 10,101,110,100, 10, 10, +102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100, +101,120, 58,115,101,110,100, 40,100, 97,116, 97, 41, 10, 32, 32, 32, 32,114,101, +116,117,114,110, 32,115,101,108,102, 46, 99, 58,115,101,110,100, 40,100, 97,116, + 97, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, + 97,116, 46, 95, 95,105,110,100,101,120, 58,114,101, 99,101,105,118,101, 40,112, + 97,116, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, + 99, 58,114,101, 99,101,105,118,101, 40,112, 97,116, 41, 10,101,110,100, 10, 10, +102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105,110,100, +101,120, 58,103,101,116,102,100, 40, 41, 10, 32, 32, 32, 32,114,101,116,117,114, +110, 32,115,101,108,102, 46, 99, 58,103,101,116,102,100, 40, 41, 10,101,110,100, + 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95,105, +110,100,101,120, 58,100,105,114,116,121, 40, 41, 10, 32, 32, 32, 32,114,101,116, +117,114,110, 32,115,101,108,102, 46, 99, 58,100,105,114,116,121, 40, 41, 10,101, +110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, + 95,105,110,100,101,120, 58,103,101,116, 99,111,110,116,114,111,108, 40, 41, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,115,101,108,102, 46, 99, 10,101,110, +100, 10, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, 95, +105,110,100,101,120, 58,115,111,117,114, 99,101, 40,115,111,117,114, 99,101, 44, + 32,115,116,101,112, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,115,105,110, +107, 32, 61, 32,115,111, 99,107,101,116, 46,115,105,110,107, 40, 34,107,101,101, +112, 45,111,112,101,110, 34, 44, 32,115,101,108,102, 46, 99, 41, 10, 32, 32, 32, + 32,108,111, 99, 97,108, 32,114,101,116, 44, 32,101,114,114, 32, 61, 32,108,116, +110, 49, 50, 46,112,117,109,112, 46, 97,108,108, 40,115,111,117,114, 99,101, 44, + 32,115,105,110,107, 44, 32,115,116,101,112, 32,111,114, 32,108,116,110, 49, 50, + 46,112,117,109,112, 46,115,116,101,112, 41, 10, 32, 32, 32, 32,114,101,116,117, +114,110, 32,114,101,116, 44, 32,101,114,114, 10,101,110,100, 10, 10, 45, 45, 32, + 99,108,111,115,101,115, 32,116,104,101, 32,117,110,100,101,114,108,121,105,110, +103, 32, 99, 10,102,117,110, 99,116,105,111,110, 32,109,101,116, 97,116, 46, 95, + 95,105,110,100,101,120, 58, 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32,115, +101,108,102, 46, 99, 58, 99,108,111,115,101, 40, 41, 10, 9,114,101,116,117,114, +110, 32, 49, 10,101,110,100, 10, 10, 45, 45, 32, 99,111,110,110,101, 99,116, 32, +119,105,116,104, 32,115,101,114,118,101,114, 32, 97,110,100, 32,114,101,116,117, +114,110, 32, 99, 32,111, 98,106,101, 99,116, 10,102,117,110, 99,116,105,111,110, + 32, 99,111,110,110,101, 99,116, 40,104,111,115,116, 44, 32,112,111,114,116, 44, + 32,116,105,109,101,111,117,116, 44, 32, 99,114,101, 97,116,101, 41, 10, 32, 32, + 32, 32,108,111, 99, 97,108, 32, 99, 44, 32,101, 32, 61, 32, 40, 99,114,101, 97, +116,101, 32,111,114, 32,115,111, 99,107,101,116, 46,116, 99,112, 41, 40, 41, 10, + 32, 32, 32, 32,105,102, 32,110,111,116, 32, 99, 32,116,104,101,110, 32,114,101, +116,117,114,110, 32,110,105,108, 44, 32,101, 32,101,110,100, 10, 32, 32, 32, 32, + 99, 58,115,101,116,116,105,109,101,111,117,116, 40,116,105,109,101,111,117,116, + 32,111,114, 32, 84, 73, 77, 69, 79, 85, 84, 41, 10, 32, 32, 32, 32,108,111, 99, + 97,108, 32,114, 44, 32,101, 32, 61, 32, 99, 58, 99,111,110,110,101, 99,116, 40, +104,111,115,116, 44, 32,112,111,114,116, 41, 10, 32, 32, 32, 32,105,102, 32,110, +111,116, 32,114, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 99, 58, + 99,108,111,115,101, 40, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117, +114,110, 32,110,105,108, 44, 32,101, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, + 32, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 46,115,101,116,109,101,116, + 97,116, 97, 98,108,101, 40,123, 99, 32, 61, 32, 99,125, 44, 32,109,101,116, 97, +116, 41, 10,101,110,100, 10, 10, + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/src/libs/luasocket/src/udp.c b/src/libs/luasocket/src/udp.c new file mode 100644 index 000000000..fc25aa027 --- /dev/null +++ b/src/libs/luasocket/src/udp.c @@ -0,0 +1,336 @@ +/*=========================================================================*\ +* UDP object +* LuaSocket toolkit +* +* RCS ID: $Id: udp.c,v 1.29 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include <string.h> + +#include "lua.h" +#include "lauxlib.h" + +#include "auxiliar.h" +#include "socket.h" +#include "inet.h" +#include "options.h" +#include "udp.h" + +/* min and max macros */ +#ifndef MIN +#define MIN(x, y) ((x) < (y) ? x : y) +#endif +#ifndef MAX +#define MAX(x, y) ((x) > (y) ? x : y) +#endif + +/*=========================================================================*\ +* Internal function prototypes +\*=========================================================================*/ +static int global_create(lua_State *L); +static int meth_send(lua_State *L); +static int meth_sendto(lua_State *L); +static int meth_receive(lua_State *L); +static int meth_receivefrom(lua_State *L); +static int meth_getsockname(lua_State *L); +static int meth_getpeername(lua_State *L); +static int meth_setsockname(lua_State *L); +static int meth_setpeername(lua_State *L); +static int meth_close(lua_State *L); +static int meth_setoption(lua_State *L); +static int meth_settimeout(lua_State *L); +static int meth_getfd(lua_State *L); +static int meth_setfd(lua_State *L); +static int meth_dirty(lua_State *L); + +/* udp object methods */ +static luaL_reg udp[] = { + {"__gc", meth_close}, + {"__tostring", auxiliar_tostring}, + {"close", meth_close}, + {"dirty", meth_dirty}, + {"getfd", meth_getfd}, + {"getpeername", meth_getpeername}, + {"getsockname", meth_getsockname}, + {"receive", meth_receive}, + {"receivefrom", meth_receivefrom}, + {"send", meth_send}, + {"sendto", meth_sendto}, + {"setfd", meth_setfd}, + {"setoption", meth_setoption}, + {"setpeername", meth_setpeername}, + {"setsockname", meth_setsockname}, + {"settimeout", meth_settimeout}, + {NULL, NULL} +}; + +/* socket options */ +static t_opt opt[] = { + {"dontroute", opt_dontroute}, + {"broadcast", opt_broadcast}, + {"reuseaddr", opt_reuseaddr}, + {"ip-multicast-ttl", opt_ip_multicast_ttl}, + {"ip-multicast-loop", opt_ip_multicast_loop}, + {"ip-add-membership", opt_ip_add_membership}, + {"ip-drop-membership", opt_ip_drop_membersip}, + {NULL, NULL} +}; + +/* functions in library namespace */ +static luaL_reg func[] = { + {"udp", global_create}, + {NULL, NULL} +}; + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int udp_open(lua_State *L) +{ + /* create classes */ + auxiliar_newclass(L, "udp{connected}", udp); + auxiliar_newclass(L, "udp{unconnected}", udp); + /* create class groups */ + auxiliar_add2group(L, "udp{connected}", "udp{any}"); + auxiliar_add2group(L, "udp{unconnected}", "udp{any}"); + auxiliar_add2group(L, "udp{connected}", "select{able}"); + auxiliar_add2group(L, "udp{unconnected}", "select{able}"); + /* define library functions */ + luaL_openlib(L, NULL, func, 0); + return 0; +} + +/*=========================================================================*\ +* Lua methods +\*=========================================================================*/ +const char *udp_strerror(int err) { + /* a 'closed' error on an unconnected means the target address was not + * accepted by the transport layer */ + if (err == IO_CLOSED) return "refused"; + else return socket_strerror(err); +} + +/*-------------------------------------------------------------------------*\ +* Send data through connected udp socket +\*-------------------------------------------------------------------------*/ +static int meth_send(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{connected}", 1); + p_timeout tm = &udp->tm; + size_t count, sent = 0; + int err; + const char *data = luaL_checklstring(L, 2, &count); + timeout_markstart(tm); + err = socket_send(&udp->sock, data, count, &sent, tm); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, udp_strerror(err)); + return 2; + } + lua_pushnumber(L, sent); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Send data through unconnected udp socket +\*-------------------------------------------------------------------------*/ +static int meth_sendto(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); + size_t count, sent = 0; + const char *data = luaL_checklstring(L, 2, &count); + const char *ip = luaL_checkstring(L, 3); + unsigned short port = (unsigned short) luaL_checknumber(L, 4); + p_timeout tm = &udp->tm; + struct sockaddr_in addr; + int err; + memset(&addr, 0, sizeof(addr)); + if (!inet_aton(ip, &addr.sin_addr)) + luaL_argerror(L, 3, "invalid ip address"); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + timeout_markstart(tm); + err = socket_sendto(&udp->sock, data, count, &sent, + (SA *) &addr, sizeof(addr), tm); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, udp_strerror(err)); + return 2; + } + lua_pushnumber(L, sent); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Receives data from a UDP socket +\*-------------------------------------------------------------------------*/ +static int meth_receive(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + char buffer[UDP_DATAGRAMSIZE]; + size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); + int err; + p_timeout tm = &udp->tm; + count = MIN(count, sizeof(buffer)); + timeout_markstart(tm); + err = socket_recv(&udp->sock, buffer, count, &got, tm); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, udp_strerror(err)); + return 2; + } + lua_pushlstring(L, buffer, got); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Receives data and sender from a UDP socket +\*-------------------------------------------------------------------------*/ +static int meth_receivefrom(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); + struct sockaddr_in addr; + socklen_t addr_len = sizeof(addr); + char buffer[UDP_DATAGRAMSIZE]; + size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); + int err; + p_timeout tm = &udp->tm; + timeout_markstart(tm); + count = MIN(count, sizeof(buffer)); + err = socket_recvfrom(&udp->sock, buffer, count, &got, + (SA *) &addr, &addr_len, tm); + if (err == IO_DONE) { + lua_pushlstring(L, buffer, got); + lua_pushstring(L, inet_ntoa(addr.sin_addr)); + lua_pushnumber(L, ntohs(addr.sin_port)); + return 3; + } else { + lua_pushnil(L); + lua_pushstring(L, udp_strerror(err)); + return 2; + } +} + +/*-------------------------------------------------------------------------*\ +* Select support methods +\*-------------------------------------------------------------------------*/ +static int meth_getfd(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + lua_pushnumber(L, (int) udp->sock); + return 1; +} + +/* this is very dangerous, but can be handy for those that are brave enough */ +static int meth_setfd(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + udp->sock = (t_socket) luaL_checknumber(L, 2); + return 0; +} + +static int meth_dirty(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + (void) udp; + lua_pushboolean(L, 0); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Just call inet methods +\*-------------------------------------------------------------------------*/ +static int meth_getpeername(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{connected}", 1); + return inet_meth_getpeername(L, &udp->sock); +} + +static int meth_getsockname(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + return inet_meth_getsockname(L, &udp->sock); +} + +/*-------------------------------------------------------------------------*\ +* Just call option handler +\*-------------------------------------------------------------------------*/ +static int meth_setoption(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + return opt_meth_setoption(L, opt, &udp->sock); +} + +/*-------------------------------------------------------------------------*\ +* Just call tm methods +\*-------------------------------------------------------------------------*/ +static int meth_settimeout(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + return timeout_meth_settimeout(L, &udp->tm); +} + +/*-------------------------------------------------------------------------*\ +* Turns a master udp object into a client object. +\*-------------------------------------------------------------------------*/ +static int meth_setpeername(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + p_timeout tm = &udp->tm; + const char *address = luaL_checkstring(L, 2); + int connecting = strcmp(address, "*"); + unsigned short port = connecting ? + (unsigned short) luaL_checknumber(L, 3) : + (unsigned short) luaL_optnumber(L, 3, 0); + const char *err = inet_tryconnect(&udp->sock, address, port, tm); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + /* change class to connected or unconnected depending on address */ + if (connecting) auxiliar_setclass(L, "udp{connected}", 1); + else auxiliar_setclass(L, "udp{unconnected}", 1); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Closes socket used by object +\*-------------------------------------------------------------------------*/ +static int meth_close(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + socket_destroy(&udp->sock); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Turns a master object into a server object +\*-------------------------------------------------------------------------*/ +static int meth_setsockname(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); + const char *address = luaL_checkstring(L, 2); + unsigned short port = (unsigned short) luaL_checknumber(L, 3); + const char *err = inet_trybind(&udp->sock, address, port); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + lua_pushnumber(L, 1); + return 1; +} + +/*=========================================================================*\ +* Library functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Creates a master udp object +\*-------------------------------------------------------------------------*/ +static int global_create(lua_State *L) { + t_socket sock; + const char *err = inet_trycreate(&sock, SOCK_DGRAM); + /* try to allocate a system socket */ + if (!err) { + /* allocate tcp object */ + p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); + auxiliar_setclass(L, "udp{unconnected}", -1); + /* initialize remaining structure fields */ + socket_setnonblocking(&sock); + udp->sock = sock; + timeout_init(&udp->tm, -1, -1); + return 1; + } else { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } +} diff --git a/src/libs/luasocket/src/udp.h b/src/libs/luasocket/src/udp.h new file mode 100644 index 000000000..280171217 --- /dev/null +++ b/src/libs/luasocket/src/udp.h @@ -0,0 +1,33 @@ +#ifndef UDP_H +#define UDP_H +/*=========================================================================*\ +* UDP object +* LuaSocket toolkit +* +* The udp.h module provides LuaSocket with support for UDP protocol +* (AF_INET, SOCK_DGRAM). +* +* Two classes are defined: connected and unconnected. UDP objects are +* originally unconnected. They can be "connected" to a given address +* with a call to the setpeername function. The same function can be used to +* break the connection. +* +* RCS ID: $Id: udp.h,v 1.10 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ +#include "lua.h" + +#include "timeout.h" +#include "socket.h" + +/* can't be larger than wsocket.c MAXCHUNK!!! */ +#define UDP_DATAGRAMSIZE 8192 + +typedef struct t_udp_ { + t_socket sock; + t_timeout tm; +} t_udp; +typedef t_udp *p_udp; + +int udp_open(lua_State *L); + +#endif /* UDP_H */ diff --git a/src/libs/luasocket/src/unix.c b/src/libs/luasocket/src/unix.c new file mode 100644 index 000000000..158d319a5 --- /dev/null +++ b/src/libs/luasocket/src/unix.c @@ -0,0 +1,356 @@ +/*=========================================================================*\ +* Unix domain socket +* LuaSocket toolkit +* +* RCS ID: $Id: unix.c,v 1.13 2006/03/13 07:16:39 diego Exp $ +\*=========================================================================*/ +#include <string.h> + +#include "lua.h" +#include "lauxlib.h" + +#include "auxiliar.h" +#include "socket.h" +#include "options.h" +#include "unix.h" +#include <sys/un.h> + +/*=========================================================================*\ +* Internal function prototypes +\*=========================================================================*/ +static int global_create(lua_State *L); +static int meth_connect(lua_State *L); +static int meth_listen(lua_State *L); +static int meth_bind(lua_State *L); +static int meth_send(lua_State *L); +static int meth_shutdown(lua_State *L); +static int meth_receive(lua_State *L); +static int meth_accept(lua_State *L); +static int meth_close(lua_State *L); +static int meth_setoption(lua_State *L); +static int meth_settimeout(lua_State *L); +static int meth_getfd(lua_State *L); +static int meth_setfd(lua_State *L); +static int meth_dirty(lua_State *L); +static int meth_getstats(lua_State *L); +static int meth_setstats(lua_State *L); + +static const char *unix_tryconnect(p_unix un, const char *path); +static const char *unix_trybind(p_unix un, const char *path); + +/* unix object methods */ +static luaL_reg un[] = { + {"__gc", meth_close}, + {"__tostring", auxiliar_tostring}, + {"accept", meth_accept}, + {"bind", meth_bind}, + {"close", meth_close}, + {"connect", meth_connect}, + {"dirty", meth_dirty}, + {"getfd", meth_getfd}, + {"getstats", meth_getstats}, + {"setstats", meth_setstats}, + {"listen", meth_listen}, + {"receive", meth_receive}, + {"send", meth_send}, + {"setfd", meth_setfd}, + {"setoption", meth_setoption}, + {"setpeername", meth_connect}, + {"setsockname", meth_bind}, + {"settimeout", meth_settimeout}, + {"shutdown", meth_shutdown}, + {NULL, NULL} +}; + +/* socket option handlers */ +static t_opt opt[] = { + {"keepalive", opt_keepalive}, + {"reuseaddr", opt_reuseaddr}, + {"linger", opt_linger}, + {NULL, NULL} +}; + +/* our socket creation function */ +static luaL_reg func[] = { + {"unix", global_create}, + {NULL, NULL} +}; + + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int luaopen_socket_unix(lua_State *L) { + /* create classes */ + auxiliar_newclass(L, "unix{master}", un); + auxiliar_newclass(L, "unix{client}", un); + auxiliar_newclass(L, "unix{server}", un); + /* create class groups */ + auxiliar_add2group(L, "unix{master}", "unix{any}"); + auxiliar_add2group(L, "unix{client}", "unix{any}"); + auxiliar_add2group(L, "unix{server}", "unix{any}"); + /* make sure the function ends up in the package table */ + luaL_openlib(L, "socket", func, 0); + /* return the function instead of the 'socket' table */ + lua_pushstring(L, "unix"); + lua_gettable(L, -2); + return 1; +} + +/*=========================================================================*\ +* Lua methods +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Just call buffered IO methods +\*-------------------------------------------------------------------------*/ +static int meth_send(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); + return buffer_meth_send(L, &un->buf); +} + +static int meth_receive(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); + return buffer_meth_receive(L, &un->buf); +} + +static int meth_getstats(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); + return buffer_meth_getstats(L, &un->buf); +} + +static int meth_setstats(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); + return buffer_meth_setstats(L, &un->buf); +} + +/*-------------------------------------------------------------------------*\ +* Just call option handler +\*-------------------------------------------------------------------------*/ +static int meth_setoption(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); + return opt_meth_setoption(L, opt, &un->sock); +} + +/*-------------------------------------------------------------------------*\ +* Select support methods +\*-------------------------------------------------------------------------*/ +static int meth_getfd(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); + lua_pushnumber(L, (int) un->sock); + return 1; +} + +/* this is very dangerous, but can be handy for those that are brave enough */ +static int meth_setfd(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); + un->sock = (t_socket) luaL_checknumber(L, 2); + return 0; +} + +static int meth_dirty(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); + lua_pushboolean(L, !buffer_isempty(&un->buf)); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Waits for and returns a client object attempting connection to the +* server object +\*-------------------------------------------------------------------------*/ +static int meth_accept(lua_State *L) { + p_unix server = (p_unix) auxiliar_checkclass(L, "unix{server}", 1); + p_timeout tm = timeout_markstart(&server->tm); + t_socket sock; + int err = socket_accept(&server->sock, &sock, NULL, NULL, tm); + /* if successful, push client socket */ + if (err == IO_DONE) { + p_unix clnt = (p_unix) lua_newuserdata(L, sizeof(t_unix)); + auxiliar_setclass(L, "unix{client}", -1); + /* initialize structure fields */ + socket_setnonblocking(&sock); + clnt->sock = sock; + io_init(&clnt->io, (p_send)socket_send, (p_recv)socket_recv, + (p_error) socket_ioerror, &clnt->sock); + timeout_init(&clnt->tm, -1, -1); + buffer_init(&clnt->buf, &clnt->io, &clnt->tm); + return 1; + } else { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } +} + +/*-------------------------------------------------------------------------*\ +* Binds an object to an address +\*-------------------------------------------------------------------------*/ +static const char *unix_trybind(p_unix un, const char *path) { + struct sockaddr_un local; + size_t len = strlen(path); + int err; + if (len >= sizeof(local.sun_path)) return "path too long"; + memset(&local, 0, sizeof(local)); + strcpy(local.sun_path, path); + local.sun_family = AF_UNIX; +#ifdef UNIX_HAS_SUN_LEN + local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len) + + len + 1; + err = socket_bind(&un->sock, (SA *) &local, local.sun_len); + +#else + err = socket_bind(&un->sock, (SA *) &local, + sizeof(local.sun_family) + len); +#endif + if (err != IO_DONE) socket_destroy(&un->sock); + return socket_strerror(err); +} + +static int meth_bind(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1); + const char *path = luaL_checkstring(L, 2); + const char *err = unix_trybind(un, path); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Turns a master unix object into a client object. +\*-------------------------------------------------------------------------*/ +static const char *unix_tryconnect(p_unix un, const char *path) +{ + struct sockaddr_un remote; + int err; + size_t len = strlen(path); + if (len >= sizeof(remote.sun_path)) return "path too long"; + memset(&remote, 0, sizeof(remote)); + strcpy(remote.sun_path, path); + remote.sun_family = AF_UNIX; + timeout_markstart(&un->tm); +#ifdef UNIX_HAS_SUN_LEN + remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len) + + len + 1; + err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm); +#else + err = socket_connect(&un->sock, (SA *) &remote, + sizeof(remote.sun_family) + len, &un->tm); +#endif + if (err != IO_DONE) socket_destroy(&un->sock); + return socket_strerror(err); +} + +static int meth_connect(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1); + const char *path = luaL_checkstring(L, 2); + const char *err = unix_tryconnect(un, path); + if (err) { + lua_pushnil(L); + lua_pushstring(L, err); + return 2; + } + /* turn master object into a client object */ + auxiliar_setclass(L, "unix{client}", 1); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Closes socket used by object +\*-------------------------------------------------------------------------*/ +static int meth_close(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); + socket_destroy(&un->sock); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Puts the sockt in listen mode +\*-------------------------------------------------------------------------*/ +static int meth_listen(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1); + int backlog = (int) luaL_optnumber(L, 2, 32); + int err = socket_listen(&un->sock, backlog); + if (err != IO_DONE) { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } + /* turn master object into a server object */ + auxiliar_setclass(L, "unix{server}", 1); + lua_pushnumber(L, 1); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Shuts the connection down partially +\*-------------------------------------------------------------------------*/ +static int meth_shutdown(lua_State *L) +{ + p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); + const char *how = luaL_optstring(L, 2, "both"); + switch (how[0]) { + case 'b': + if (strcmp(how, "both")) goto error; + socket_shutdown(&un->sock, 2); + break; + case 's': + if (strcmp(how, "send")) goto error; + socket_shutdown(&un->sock, 1); + break; + case 'r': + if (strcmp(how, "receive")) goto error; + socket_shutdown(&un->sock, 0); + break; + } + lua_pushnumber(L, 1); + return 1; +error: + luaL_argerror(L, 2, "invalid shutdown method"); + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Just call tm methods +\*-------------------------------------------------------------------------*/ +static int meth_settimeout(lua_State *L) { + p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); + return timeout_meth_settimeout(L, &un->tm); +} + +/*=========================================================================*\ +* Library functions +\*=========================================================================*/ +/*-------------------------------------------------------------------------*\ +* Creates a master unix object +\*-------------------------------------------------------------------------*/ +static int global_create(lua_State *L) { + t_socket sock; + int err = socket_create(&sock, AF_UNIX, SOCK_STREAM, 0); + /* try to allocate a system socket */ + if (err == IO_DONE) { + /* allocate unix object */ + p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix)); + /* set its type as master object */ + auxiliar_setclass(L, "unix{master}", -1); + /* initialize remaining structure fields */ + socket_setnonblocking(&sock); + un->sock = sock; + io_init(&un->io, (p_send) socket_send, (p_recv) socket_recv, + (p_error) socket_ioerror, &un->sock); + timeout_init(&un->tm, -1, -1); + buffer_init(&un->buf, &un->io, &un->tm); + return 1; + } else { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(err)); + return 2; + } +} diff --git a/src/libs/luasocket/src/unix.h b/src/libs/luasocket/src/unix.h new file mode 100644 index 000000000..32b7380ff --- /dev/null +++ b/src/libs/luasocket/src/unix.h @@ -0,0 +1,28 @@ +#ifndef UNIX_H +#define UNIX_H +/*=========================================================================*\ +* Unix domain object +* LuaSocket toolkit +* +* This module is just an example of how to extend LuaSocket with a new +* domain. +* +* RCS ID: $Id: unix.h,v 1.9 2006/03/13 07:16:39 diego Exp $ +\*=========================================================================*/ +#include "lua.h" + +#include "buffer.h" +#include "timeout.h" +#include "socket.h" + +typedef struct t_unix_ { + t_socket sock; + t_io io; + t_buffer buf; + t_timeout tm; +} t_unix; +typedef t_unix *p_unix; + +int luaopen_socket_unix(lua_State *L); + +#endif /* UNIX_H */ diff --git a/src/libs/luasocket/src/url.lua b/src/libs/luasocket/src/url.lua new file mode 100644 index 000000000..0e31d8af2 --- /dev/null +++ b/src/libs/luasocket/src/url.lua @@ -0,0 +1,297 @@ +----------------------------------------------------------------------------- +-- URI parsing, composition and relative URL resolution +-- LuaSocket toolkit. +-- Author: Diego Nehab +-- RCS ID: $Id: url.lua,v 1.38 2006/04/03 04:45:42 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module +----------------------------------------------------------------------------- +local string = require("string") +local base = _G +local table = require("table") +module("socket.url") + +----------------------------------------------------------------------------- +-- Module version +----------------------------------------------------------------------------- +_VERSION = "URL 1.0.1" + +----------------------------------------------------------------------------- +-- Encodes a string into its escaped hexadecimal representation +-- Input +-- s: binary string to be encoded +-- Returns +-- escaped representation of string binary +----------------------------------------------------------------------------- +function escape(s) + return string.gsub(s, "([^A-Za-z0-9_])", function(c) + return string.format("%%%02x", string.byte(c)) + end) +end + +----------------------------------------------------------------------------- +-- Protects a path segment, to prevent it from interfering with the +-- url parsing. +-- Input +-- s: binary string to be encoded +-- Returns +-- escaped representation of string binary +----------------------------------------------------------------------------- +local function make_set(t) + local s = {} + for i,v in base.ipairs(t) do + s[t[i]] = 1 + end + return s +end + +-- these are allowed withing a path segment, along with alphanum +-- other characters must be escaped +local segment_set = make_set { + "-", "_", ".", "!", "~", "*", "'", "(", + ")", ":", "@", "&", "=", "+", "$", ",", +} + +local function protect_segment(s) + return string.gsub(s, "([^A-Za-z0-9_])", function (c) + if segment_set[c] then return c + else return string.format("%%%02x", string.byte(c)) end + end) +end + +----------------------------------------------------------------------------- +-- Encodes a string into its escaped hexadecimal representation +-- Input +-- s: binary string to be encoded +-- Returns +-- escaped representation of string binary +----------------------------------------------------------------------------- +function unescape(s) + return string.gsub(s, "%%(%x%x)", function(hex) + return string.char(base.tonumber(hex, 16)) + end) +end + +----------------------------------------------------------------------------- +-- Builds a path from a base path and a relative path +-- Input +-- base_path +-- relative_path +-- Returns +-- corresponding absolute path +----------------------------------------------------------------------------- +local function absolute_path(base_path, relative_path) + if string.sub(relative_path, 1, 1) == "/" then return relative_path end + local path = string.gsub(base_path, "[^/]*$", "") + path = path .. relative_path + path = string.gsub(path, "([^/]*%./)", function (s) + if s ~= "./" then return s else return "" end + end) + path = string.gsub(path, "/%.$", "/") + local reduced + while reduced ~= path do + reduced = path + path = string.gsub(reduced, "([^/]*/%.%./)", function (s) + if s ~= "../../" then return "" else return s end + end) + end + path = string.gsub(reduced, "([^/]*/%.%.)$", function (s) + if s ~= "../.." then return "" else return s end + end) + return path +end + +----------------------------------------------------------------------------- +-- Parses a url and returns a table with all its parts according to RFC 2396 +-- The following grammar describes the names given to the URL parts +-- <url> ::= <scheme>://<authority>/<path>;<params>?<query>#<fragment> +-- <authority> ::= <userinfo>@<host>:<port> +-- <userinfo> ::= <user>[:<password>] +-- <path> :: = {<segment>/}<segment> +-- Input +-- url: uniform resource locator of request +-- default: table with default values for each field +-- Returns +-- table with the following fields, where RFC naming conventions have +-- been preserved: +-- scheme, authority, userinfo, user, password, host, port, +-- path, params, query, fragment +-- Obs: +-- the leading '/' in {/<path>} is considered part of <path> +----------------------------------------------------------------------------- +function parse(url, default) + -- initialize default parameters + local parsed = {} + for i,v in base.pairs(default or parsed) do parsed[i] = v end + -- empty url is parsed to nil + if not url or url == "" then return nil, "invalid url" end + -- remove whitespace + -- url = string.gsub(url, "%s", "") + -- get fragment + url = string.gsub(url, "#(.*)$", function(f) + parsed.fragment = f + return "" + end) + -- get scheme + url = string.gsub(url, "^([%w][%w%+%-%.]*)%:", + function(s) parsed.scheme = s; return "" end) + -- get authority + url = string.gsub(url, "^//([^/]*)", function(n) + parsed.authority = n + return "" + end) + -- get query stringing + url = string.gsub(url, "%?(.*)", function(q) + parsed.query = q + return "" + end) + -- get params + url = string.gsub(url, "%;(.*)", function(p) + parsed.params = p + return "" + end) + -- path is whatever was left + if url ~= "" then parsed.path = url end + local authority = parsed.authority + if not authority then return parsed end + authority = string.gsub(authority,"^([^@]*)@", + function(u) parsed.userinfo = u; return "" end) + authority = string.gsub(authority, ":([^:]*)$", + function(p) parsed.port = p; return "" end) + if authority ~= "" then parsed.host = authority end + local userinfo = parsed.userinfo + if not userinfo then return parsed end + userinfo = string.gsub(userinfo, ":([^:]*)$", + function(p) parsed.password = p; return "" end) + parsed.user = userinfo + return parsed +end + +----------------------------------------------------------------------------- +-- Rebuilds a parsed URL from its components. +-- Components are protected if any reserved or unallowed characters are found +-- Input +-- parsed: parsed URL, as returned by parse +-- Returns +-- a stringing with the corresponding URL +----------------------------------------------------------------------------- +function build(parsed) + local ppath = parse_path(parsed.path or "") + local url = build_path(ppath) + if parsed.params then url = url .. ";" .. parsed.params end + if parsed.query then url = url .. "?" .. parsed.query end + local authority = parsed.authority + if parsed.host then + authority = parsed.host + if parsed.port then authority = authority .. ":" .. parsed.port end + local userinfo = parsed.userinfo + if parsed.user then + userinfo = parsed.user + if parsed.password then + userinfo = userinfo .. ":" .. parsed.password + end + end + if userinfo then authority = userinfo .. "@" .. authority end + end + if authority then url = "//" .. authority .. url end + if parsed.scheme then url = parsed.scheme .. ":" .. url end + if parsed.fragment then url = url .. "#" .. parsed.fragment end + -- url = string.gsub(url, "%s", "") + return url +end + +----------------------------------------------------------------------------- +-- Builds a absolute URL from a base and a relative URL according to RFC 2396 +-- Input +-- base_url +-- relative_url +-- Returns +-- corresponding absolute url +----------------------------------------------------------------------------- +function absolute(base_url, relative_url) + if base.type(base_url) == "table" then + base_parsed = base_url + base_url = build(base_parsed) + else + base_parsed = parse(base_url) + end + local relative_parsed = parse(relative_url) + if not base_parsed then return relative_url + elseif not relative_parsed then return base_url + elseif relative_parsed.scheme then return relative_url + else + relative_parsed.scheme = base_parsed.scheme + if not relative_parsed.authority then + relative_parsed.authority = base_parsed.authority + if not relative_parsed.path then + relative_parsed.path = base_parsed.path + if not relative_parsed.params then + relative_parsed.params = base_parsed.params + if not relative_parsed.query then + relative_parsed.query = base_parsed.query + end + end + else + relative_parsed.path = absolute_path(base_parsed.path or "", + relative_parsed.path) + end + end + return build(relative_parsed) + end +end + +----------------------------------------------------------------------------- +-- Breaks a path into its segments, unescaping the segments +-- Input +-- path +-- Returns +-- segment: a table with one entry per segment +----------------------------------------------------------------------------- +function parse_path(path) + local parsed = {} + path = path or "" + --path = string.gsub(path, "%s", "") + string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end) + for i = 1, table.getn(parsed) do + parsed[i] = unescape(parsed[i]) + end + if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end + if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end + return parsed +end + +----------------------------------------------------------------------------- +-- Builds a path component from its segments, escaping protected characters. +-- Input +-- parsed: path segments +-- unsafe: if true, segments are not protected before path is built +-- Returns +-- path: corresponding path stringing +----------------------------------------------------------------------------- +function build_path(parsed, unsafe) + local path = "" + local n = table.getn(parsed) + if unsafe then + for i = 1, n-1 do + path = path .. parsed[i] + path = path .. "/" + end + if n > 0 then + path = path .. parsed[n] + if parsed.is_directory then path = path .. "/" end + end + else + for i = 1, n-1 do + path = path .. protect_segment(parsed[i]) + path = path .. "/" + end + if n > 0 then + path = path .. protect_segment(parsed[n]) + if parsed.is_directory then path = path .. "/" end + end + end + if parsed.is_absolute then path = "/" .. path end + return path +end diff --git a/src/libs/luasocket/src/url_lua.c b/src/libs/luasocket/src/url_lua.c new file mode 100644 index 000000000..7b4a6e799 --- /dev/null +++ b/src/libs/luasocket/src/url_lua.c @@ -0,0 +1,540 @@ +/* + * This file is auto-generated by "./lua2c url.lua url_lua" + */ + +#include "lua.h" +#include "lauxlib.h" + +int luatex_url_lua_open (lua_State *L) { + static unsigned char B[] = { + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, + 32, 85, 82, 73, 32,112, 97,114,115,105,110,103, 44, 32, 99,111,109,112,111,115, +105,116,105,111,110, 32, 97,110,100, 32,114,101,108, 97,116,105,118,101, 32, 85, + 82, 76, 32,114,101,115,111,108,117,116,105,111,110, 10, 45, 45, 32, 76,117, 97, + 83,111, 99,107,101,116, 32,116,111,111,108,107,105,116, 46, 10, 45, 45, 32, 65, +117,116,104,111,114, 58, 32, 68,105,101,103,111, 32, 78,101,104, 97, 98, 10, 45, + 45, 32, 82, 67, 83, 32, 73, 68, 58, 32, 36, 73,100, 58, 32,117,114,108, 46,108, +117, 97, 44,118, 32, 49, 46, 51, 56, 32, 50, 48, 48, 54, 47, 48, 52, 47, 48, 51, + 32, 48, 52, 58, 52, 53, 58, 52, 50, 32,100,105,101,103,111, 32, 69,120,112, 32, + 36, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, + 45, 32, 68,101, 99,108, 97,114,101, 32,109,111,100,117,108,101, 10, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, + 32,115,116,114,105,110,103, 32, 61, 32,114,101,113,117,105,114,101, 40, 34,115, +116,114,105,110,103, 34, 41, 10,108,111, 99, 97,108, 32, 98, 97,115,101, 32, 61, + 32, 95, 71, 10,108,111, 99, 97,108, 32,116, 97, 98,108,101, 32, 61, 32,114,101, +113,117,105,114,101, 40, 34,116, 97, 98,108,101, 34, 41, 10,109,111,100,117,108, +101, 40, 34,115,111, 99,107,101,116, 46,117,114,108, 34, 41, 10, 10, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 77,111, +100,117,108,101, 32,118,101,114,115,105,111,110, 10, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 95, 86, 69, 82, 83, 73, 79, 78, 32, + 61, 32, 34, 85, 82, 76, 32, 49, 46, 48, 46, 49, 34, 10, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 69,110, 99,111, +100,101,115, 32, 97, 32,115,116,114,105,110,103, 32,105,110,116,111, 32,105,116, +115, 32,101,115, 99, 97,112,101,100, 32,104,101,120, 97,100,101, 99,105,109, 97, +108, 32,114,101,112,114,101,115,101,110,116, 97,116,105,111,110, 10, 45, 45, 32, + 73,110,112,117,116, 10, 45, 45, 32, 32, 32,115, 58, 32, 98,105,110, 97,114,121, + 32,115,116,114,105,110,103, 32,116,111, 32, 98,101, 32,101,110, 99,111,100,101, +100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, 32,101,115, + 99, 97,112,101,100, 32,114,101,112,114,101,115,101,110,116, 97,116,105,111,110, + 32,111,102, 32,115,116,114,105,110,103, 32, 98,105,110, 97,114,121, 10, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99, +116,105,111,110, 32,101,115, 99, 97,112,101, 40,115, 41, 10, 32, 32, 32, 32,114, +101,116,117,114,110, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,115, 44, + 32, 34, 40, 91, 94, 65, 45, 90, 97, 45,122, 48, 45, 57, 95, 93, 41, 34, 44, 32, +102,117,110, 99,116,105,111,110, 40, 99, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116, + 40, 34, 37, 37, 37, 48, 50,120, 34, 44, 32,115,116,114,105,110,103, 46, 98,121, +116,101, 40, 99, 41, 41, 10, 32, 32, 32, 32,101,110,100, 41, 10,101,110,100, 10, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, + 45, 32, 80,114,111,116,101, 99,116,115, 32, 97, 32,112, 97,116,104, 32,115,101, +103,109,101,110,116, 44, 32,116,111, 32,112,114,101,118,101,110,116, 32,105,116, + 32,102,114,111,109, 32,105,110,116,101,114,102,101,114,105,110,103, 32,119,105, +116,104, 32,116,104,101, 10, 45, 45, 32,117,114,108, 32,112, 97,114,115,105,110, +103, 46, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,115, 58, 32, + 98,105,110, 97,114,121, 32,115,116,114,105,110,103, 32,116,111, 32, 98,101, 32, +101,110, 99,111,100,101,100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, + 45, 32, 32, 32,101,115, 99, 97,112,101,100, 32,114,101,112,114,101,115,101,110, +116, 97,116,105,111,110, 32,111,102, 32,115,116,114,105,110,103, 32, 98,105,110, + 97,114,121, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111,110, 32,109, 97,107, +101, 95,115,101,116, 40,116, 41, 10, 9,108,111, 99, 97,108, 32,115, 32, 61, 32, +123,125, 10, 9,102,111,114, 32,105, 44,118, 32,105,110, 32, 98, 97,115,101, 46, +105,112, 97,105,114,115, 40,116, 41, 32,100,111, 10, 9, 9,115, 91,116, 91,105, + 93, 93, 32, 61, 32, 49, 10, 9,101,110,100, 10, 9,114,101,116,117,114,110, 32, +115, 10,101,110,100, 10, 10, 45, 45, 32,116,104,101,115,101, 32, 97,114,101, 32, + 97,108,108,111,119,101,100, 32,119,105,116,104,105,110,103, 32, 97, 32,112, 97, +116,104, 32,115,101,103,109,101,110,116, 44, 32, 97,108,111,110,103, 32,119,105, +116,104, 32, 97,108,112,104, 97,110,117,109, 10, 45, 45, 32,111,116,104,101,114, + 32, 99,104, 97,114, 97, 99,116,101,114,115, 32,109,117,115,116, 32, 98,101, 32, +101,115, 99, 97,112,101,100, 10,108,111, 99, 97,108, 32,115,101,103,109,101,110, +116, 95,115,101,116, 32, 61, 32,109, 97,107,101, 95,115,101,116, 32,123, 10, 32, + 32, 32, 32, 34, 45, 34, 44, 32, 34, 95, 34, 44, 32, 34, 46, 34, 44, 32, 34, 33, + 34, 44, 32, 34,126, 34, 44, 32, 34, 42, 34, 44, 32, 34, 39, 34, 44, 32, 34, 40, + 34, 44, 10, 9, 34, 41, 34, 44, 32, 34, 58, 34, 44, 32, 34, 64, 34, 44, 32, 34, + 38, 34, 44, 32, 34, 61, 34, 44, 32, 34, 43, 34, 44, 32, 34, 36, 34, 44, 32, 34, + 44, 34, 44, 10,125, 10, 10,108,111, 99, 97,108, 32,102,117,110, 99,116,105,111, +110, 32,112,114,111,116,101, 99,116, 95,115,101,103,109,101,110,116, 40,115, 41, + 10, 9,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,103,115,117, 98, + 40,115, 44, 32, 34, 40, 91, 94, 65, 45, 90, 97, 45,122, 48, 45, 57, 95, 93, 41, + 34, 44, 32,102,117,110, 99,116,105,111,110, 32, 40, 99, 41, 10, 9, 9,105,102, + 32,115,101,103,109,101,110,116, 95,115,101,116, 91, 99, 93, 32,116,104,101,110, + 32,114,101,116,117,114,110, 32, 99, 10, 9, 9,101,108,115,101, 32,114,101,116, +117,114,110, 32,115,116,114,105,110,103, 46,102,111,114,109, 97,116, 40, 34, 37, + 37, 37, 48, 50,120, 34, 44, 32,115,116,114,105,110,103, 46, 98,121,116,101, 40, + 99, 41, 41, 32,101,110,100, 10, 9,101,110,100, 41, 10,101,110,100, 10, 10, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, + 69,110, 99,111,100,101,115, 32, 97, 32,115,116,114,105,110,103, 32,105,110,116, +111, 32,105,116,115, 32,101,115, 99, 97,112,101,100, 32,104,101,120, 97,100,101, + 99,105,109, 97,108, 32,114,101,112,114,101,115,101,110,116, 97,116,105,111,110, + 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,115, 58, 32, 98,105, +110, 97,114,121, 32,115,116,114,105,110,103, 32,116,111, 32, 98,101, 32,101,110, + 99,111,100,101,100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, + 32, 32,101,115, 99, 97,112,101,100, 32,114,101,112,114,101,115,101,110,116, 97, +116,105,111,110, 32,111,102, 32,115,116,114,105,110,103, 32, 98,105,110, 97,114, +121, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, +102,117,110, 99,116,105,111,110, 32,117,110,101,115, 99, 97,112,101, 40,115, 41, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46,103, +115,117, 98, 40,115, 44, 32, 34, 37, 37, 40, 37,120, 37,120, 41, 34, 44, 32,102, +117,110, 99,116,105,111,110, 40,104,101,120, 41, 10, 32, 32, 32, 32, 32, 32, 32, + 32,114,101,116,117,114,110, 32,115,116,114,105,110,103, 46, 99,104, 97,114, 40, + 98, 97,115,101, 46,116,111,110,117,109, 98,101,114, 40,104,101,120, 44, 32, 49, + 54, 41, 41, 10, 32, 32, 32, 32,101,110,100, 41, 10,101,110,100, 10, 10, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 66, +117,105,108,100,115, 32, 97, 32,112, 97,116,104, 32,102,114,111,109, 32, 97, 32, + 98, 97,115,101, 32,112, 97,116,104, 32, 97,110,100, 32, 97, 32,114,101,108, 97, +116,105,118,101, 32,112, 97,116,104, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, + 45, 32, 32, 32, 98, 97,115,101, 95,112, 97,116,104, 10, 45, 45, 32, 32, 32,114, +101,108, 97,116,105,118,101, 95,112, 97,116,104, 10, 45, 45, 32, 82,101,116,117, +114,110,115, 10, 45, 45, 32, 32, 32, 99,111,114,114,101,115,112,111,110,100,105, +110,103, 32, 97, 98,115,111,108,117,116,101, 32,112, 97,116,104, 10, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,108,111, 99, 97,108, + 32,102,117,110, 99,116,105,111,110, 32, 97, 98,115,111,108,117,116,101, 95,112, + 97,116,104, 40, 98, 97,115,101, 95,112, 97,116,104, 44, 32,114,101,108, 97,116, +105,118,101, 95,112, 97,116,104, 41, 10, 32, 32, 32, 32,105,102, 32,115,116,114, +105,110,103, 46,115,117, 98, 40,114,101,108, 97,116,105,118,101, 95,112, 97,116, +104, 44, 32, 49, 44, 32, 49, 41, 32, 61, 61, 32, 34, 47, 34, 32,116,104,101,110, + 32,114,101,116,117,114,110, 32,114,101,108, 97,116,105,118,101, 95,112, 97,116, +104, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112, 97,116,104, + 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, 98, 97,115,101, 95, +112, 97,116,104, 44, 32, 34, 91, 94, 47, 93, 42, 36, 34, 44, 32, 34, 34, 41, 10, + 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, 46, 32,114, +101,108, 97,116,105,118,101, 95,112, 97,116,104, 10, 32, 32, 32, 32,112, 97,116, +104, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,112, 97,116,104, + 44, 32, 34, 40, 91, 94, 47, 93, 42, 37, 46, 47, 41, 34, 44, 32,102,117,110, 99, +116,105,111,110, 32, 40,115, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32, +115, 32,126, 61, 32, 34, 46, 47, 34, 32,116,104,101,110, 32,114,101,116,117,114, +110, 32,115, 32,101,108,115,101, 32,114,101,116,117,114,110, 32, 34, 34, 32,101, +110,100, 10, 32, 32, 32, 32,101,110,100, 41, 10, 32, 32, 32, 32,112, 97,116,104, + 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,112, 97,116,104, 44, + 32, 34, 47, 37, 46, 36, 34, 44, 32, 34, 47, 34, 41, 10, 32, 32, 32, 32,108,111, + 99, 97,108, 32,114,101,100,117, 99,101,100, 10, 32, 32, 32, 32,119,104,105,108, +101, 32,114,101,100,117, 99,101,100, 32,126, 61, 32,112, 97,116,104, 32,100,111, + 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,100,117, 99,101,100, 32, 61, 32,112, + 97,116,104, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,116,104, 32, 61, 32,115, +116,114,105,110,103, 46,103,115,117, 98, 40,114,101,100,117, 99,101,100, 44, 32, + 34, 40, 91, 94, 47, 93, 42, 47, 37, 46, 37, 46, 47, 41, 34, 44, 32,102,117,110, + 99,116,105,111,110, 32, 40,115, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32,105,102, 32,115, 32,126, 61, 32, 34, 46, 46, 47, 46, 46, 47, 34, 32,116, +104,101,110, 32,114,101,116,117,114,110, 32, 34, 34, 32,101,108,115,101, 32,114, +101,116,117,114,110, 32,115, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, +101,110,100, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,112, 97,116, +104, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,114,101,100,117, + 99,101,100, 44, 32, 34, 40, 91, 94, 47, 93, 42, 47, 37, 46, 37, 46, 41, 36, 34, + 44, 32,102,117,110, 99,116,105,111,110, 32, 40,115, 41, 10, 32, 32, 32, 32, 32, + 32, 32, 32,105,102, 32,115, 32,126, 61, 32, 34, 46, 46, 47, 46, 46, 34, 32,116, +104,101,110, 32,114,101,116,117,114,110, 32, 34, 34, 32,101,108,115,101, 32,114, +101,116,117,114,110, 32,115, 32,101,110,100, 10, 32, 32, 32, 32,101,110,100, 41, + 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,112, 97,116,104, 10,101,110,100, + 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10, + 45, 45, 32, 80, 97,114,115,101,115, 32, 97, 32,117,114,108, 32, 97,110,100, 32, +114,101,116,117,114,110,115, 32, 97, 32,116, 97, 98,108,101, 32,119,105,116,104, + 32, 97,108,108, 32,105,116,115, 32,112, 97,114,116,115, 32, 97, 99, 99,111,114, +100,105,110,103, 32,116,111, 32, 82, 70, 67, 32, 50, 51, 57, 54, 10, 45, 45, 32, + 84,104,101, 32,102,111,108,108,111,119,105,110,103, 32,103,114, 97,109,109, 97, +114, 32,100,101,115, 99,114,105, 98,101,115, 32,116,104,101, 32,110, 97,109,101, +115, 32,103,105,118,101,110, 32,116,111, 32,116,104,101, 32, 85, 82, 76, 32,112, + 97,114,116,115, 10, 45, 45, 32, 60,117,114,108, 62, 32, 58, 58, 61, 32, 60,115, + 99,104,101,109,101, 62, 58, 47, 47, 60, 97,117,116,104,111,114,105,116,121, 62, + 47, 60,112, 97,116,104, 62, 59, 60,112, 97,114, 97,109,115, 62, 63, 60,113,117, +101,114,121, 62, 35, 60,102,114, 97,103,109,101,110,116, 62, 10, 45, 45, 32, 60, + 97,117,116,104,111,114,105,116,121, 62, 32, 58, 58, 61, 32, 60,117,115,101,114, +105,110,102,111, 62, 64, 60,104,111,115,116, 62, 58, 60,112,111,114,116, 62, 10, + 45, 45, 32, 60,117,115,101,114,105,110,102,111, 62, 32, 58, 58, 61, 32, 60,117, +115,101,114, 62, 91, 58, 60,112, 97,115,115,119,111,114,100, 62, 93, 10, 45, 45, + 32, 60,112, 97,116,104, 62, 32, 58, 58, 32, 61, 32,123, 60,115,101,103,109,101, +110,116, 62, 47,125, 60,115,101,103,109,101,110,116, 62, 10, 45, 45, 32, 73,110, +112,117,116, 10, 45, 45, 32, 32, 32,117,114,108, 58, 32,117,110,105,102,111,114, +109, 32,114,101,115,111,117,114, 99,101, 32,108,111, 99, 97,116,111,114, 32,111, +102, 32,114,101,113,117,101,115,116, 10, 45, 45, 32, 32, 32,100,101,102, 97,117, +108,116, 58, 32,116, 97, 98,108,101, 32,119,105,116,104, 32,100,101,102, 97,117, +108,116, 32,118, 97,108,117,101,115, 32,102,111,114, 32,101, 97, 99,104, 32,102, +105,101,108,100, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, + 32,116, 97, 98,108,101, 32,119,105,116,104, 32,116,104,101, 32,102,111,108,108, +111,119,105,110,103, 32,102,105,101,108,100,115, 44, 32,119,104,101,114,101, 32, + 82, 70, 67, 32,110, 97,109,105,110,103, 32, 99,111,110,118,101,110,116,105,111, +110,115, 32,104, 97,118,101, 10, 45, 45, 32, 32, 32, 98,101,101,110, 32,112,114, +101,115,101,114,118,101,100, 58, 10, 45, 45, 32, 32, 32, 32, 32,115, 99,104,101, +109,101, 44, 32, 97,117,116,104,111,114,105,116,121, 44, 32,117,115,101,114,105, +110,102,111, 44, 32,117,115,101,114, 44, 32,112, 97,115,115,119,111,114,100, 44, + 32,104,111,115,116, 44, 32,112,111,114,116, 44, 10, 45, 45, 32, 32, 32, 32, 32, +112, 97,116,104, 44, 32,112, 97,114, 97,109,115, 44, 32,113,117,101,114,121, 44, + 32,102,114, 97,103,109,101,110,116, 10, 45, 45, 32, 79, 98,115, 58, 10, 45, 45, + 32, 32, 32,116,104,101, 32,108,101, 97,100,105,110,103, 32, 39, 47, 39, 32,105, +110, 32,123, 47, 60,112, 97,116,104, 62,125, 32,105,115, 32, 99,111,110,115,105, +100,101,114,101,100, 32,112, 97,114,116, 32,111,102, 32, 60,112, 97,116,104, 62, + 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102, +117,110, 99,116,105,111,110, 32,112, 97,114,115,101, 40,117,114,108, 44, 32,100, +101,102, 97,117,108,116, 41, 10, 32, 32, 32, 32, 45, 45, 32,105,110,105,116,105, + 97,108,105,122,101, 32,100,101,102, 97,117,108,116, 32,112, 97,114, 97,109,101, +116,101,114,115, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,112, 97,114,115,101, +100, 32, 61, 32,123,125, 10, 32, 32, 32, 32,102,111,114, 32,105, 44,118, 32,105, +110, 32, 98, 97,115,101, 46,112, 97,105,114,115, 40,100,101,102, 97,117,108,116, + 32,111,114, 32,112, 97,114,115,101,100, 41, 32,100,111, 32,112, 97,114,115,101, +100, 91,105, 93, 32, 61, 32,118, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32, +101,109,112,116,121, 32,117,114,108, 32,105,115, 32,112, 97,114,115,101,100, 32, +116,111, 32,110,105,108, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,117,114, +108, 32,111,114, 32,117,114,108, 32, 61, 61, 32, 34, 34, 32,116,104,101,110, 32, +114,101,116,117,114,110, 32,110,105,108, 44, 32, 34,105,110,118, 97,108,105,100, + 32,117,114,108, 34, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,114,101,109, +111,118,101, 32,119,104,105,116,101,115,112, 97, 99,101, 10, 32, 32, 32, 32, 45, + 45, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, +117,114,108, 44, 32, 34, 37,115, 34, 44, 32, 34, 34, 41, 10, 32, 32, 32, 32, 45, + 45, 32,103,101,116, 32,102,114, 97,103,109,101,110,116, 10, 32, 32, 32, 32,117, +114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,114,108, + 44, 32, 34, 35, 40, 46, 42, 41, 36, 34, 44, 32,102,117,110, 99,116,105,111,110, + 40,102, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115,101,100, 46,102, +114, 97,103,109,101,110,116, 32, 61, 32,102, 10, 32, 32, 32, 32, 32, 32, 32, 32, +114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10, 32, + 32, 32, 32, 45, 45, 32,103,101,116, 32,115, 99,104,101,109,101, 10, 32, 32, 32, + 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117, +114,108, 44, 32, 34, 94, 40, 91, 37,119, 93, 91, 37,119, 37, 43, 37, 45, 37, 46, + 93, 42, 41, 37, 58, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,102,117,110, 99, +116,105,111,110, 40,115, 41, 32,112, 97,114,115,101,100, 46,115, 99,104,101,109, +101, 32, 61, 32,115, 59, 32,114,101,116,117,114,110, 32, 34, 34, 32,101,110,100, + 41, 10, 32, 32, 32, 32, 45, 45, 32,103,101,116, 32, 97,117,116,104,111,114,105, +116,121, 10, 32, 32, 32, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46, +103,115,117, 98, 40,117,114,108, 44, 32, 34, 94, 47, 47, 40, 91, 94, 47, 93, 42, + 41, 34, 44, 32,102,117,110, 99,116,105,111,110, 40,110, 41, 10, 32, 32, 32, 32, + 32, 32, 32, 32,112, 97,114,115,101,100, 46, 97,117,116,104,111,114,105,116,121, + 32, 61, 32,110, 10, 32, 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, + 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10, 32, 32, 32, 32, 45, 45, 32,103, +101,116, 32,113,117,101,114,121, 32,115,116,114,105,110,103,105,110,103, 10, 32, + 32, 32, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, + 40,117,114,108, 44, 32, 34, 37, 63, 40, 46, 42, 41, 34, 44, 32,102,117,110, 99, +116,105,111,110, 40,113, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115, +101,100, 46,113,117,101,114,121, 32, 61, 32,113, 10, 32, 32, 32, 32, 32, 32, 32, + 32,114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10, + 32, 32, 32, 32, 45, 45, 32,103,101,116, 32,112, 97,114, 97,109,115, 10, 32, 32, + 32, 32,117,114,108, 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, +117,114,108, 44, 32, 34, 37, 59, 40, 46, 42, 41, 34, 44, 32,102,117,110, 99,116, +105,111,110, 40,112, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32,112, 97,114,115,101, +100, 46,112, 97,114, 97,109,115, 32, 61, 32,112, 10, 32, 32, 32, 32, 32, 32, 32, + 32,114,101,116,117,114,110, 32, 34, 34, 10, 32, 32, 32, 32,101,110,100, 41, 10, + 32, 32, 32, 32, 45, 45, 32,112, 97,116,104, 32,105,115, 32,119,104, 97,116,101, +118,101,114, 32,119, 97,115, 32,108,101,102,116, 10, 32, 32, 32, 32,105,102, 32, +117,114,108, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 32,112, 97,114,115,101, +100, 46,112, 97,116,104, 32, 61, 32,117,114,108, 32,101,110,100, 10, 32, 32, 32, + 32,108,111, 99, 97,108, 32, 97,117,116,104,111,114,105,116,121, 32, 61, 32,112, + 97,114,115,101,100, 46, 97,117,116,104,111,114,105,116,121, 10, 32, 32, 32, 32, +105,102, 32,110,111,116, 32, 97,117,116,104,111,114,105,116,121, 32,116,104,101, +110, 32,114,101,116,117,114,110, 32,112, 97,114,115,101,100, 32,101,110,100, 10, + 32, 32, 32, 32, 97,117,116,104,111,114,105,116,121, 32, 61, 32,115,116,114,105, +110,103, 46,103,115,117, 98, 40, 97,117,116,104,111,114,105,116,121, 44, 34, 94, + 40, 91, 94, 64, 93, 42, 41, 64, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32,102, +117,110, 99,116,105,111,110, 40,117, 41, 32,112, 97,114,115,101,100, 46,117,115, +101,114,105,110,102,111, 32, 61, 32,117, 59, 32,114,101,116,117,114,110, 32, 34, + 34, 32,101,110,100, 41, 10, 32, 32, 32, 32, 97,117,116,104,111,114,105,116,121, + 32, 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40, 97,117,116,104,111, +114,105,116,121, 44, 32, 34, 58, 40, 91, 94, 58, 93, 42, 41, 36, 34, 44, 10, 32, + 32, 32, 32, 32, 32, 32, 32,102,117,110, 99,116,105,111,110, 40,112, 41, 32,112, + 97,114,115,101,100, 46,112,111,114,116, 32, 61, 32,112, 59, 32,114,101,116,117, +114,110, 32, 34, 34, 32,101,110,100, 41, 10, 32, 32, 32, 32,105,102, 32, 97,117, +116,104,111,114,105,116,121, 32,126, 61, 32, 34, 34, 32,116,104,101,110, 32,112, + 97,114,115,101,100, 46,104,111,115,116, 32, 61, 32, 97,117,116,104,111,114,105, +116,121, 32,101,110,100, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,117,115,101, +114,105,110,102,111, 32, 61, 32,112, 97,114,115,101,100, 46,117,115,101,114,105, +110,102,111, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32,117,115,101,114,105, +110,102,111, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,112, 97,114,115, +101,100, 32,101,110,100, 10, 32, 32, 32, 32,117,115,101,114,105,110,102,111, 32, + 61, 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,115,101,114,105,110, +102,111, 44, 32, 34, 58, 40, 91, 94, 58, 93, 42, 41, 36, 34, 44, 10, 32, 32, 32, + 32, 32, 32, 32, 32,102,117,110, 99,116,105,111,110, 40,112, 41, 32,112, 97,114, +115,101,100, 46,112, 97,115,115,119,111,114,100, 32, 61, 32,112, 59, 32,114,101, +116,117,114,110, 32, 34, 34, 32,101,110,100, 41, 10, 32, 32, 32, 32,112, 97,114, +115,101,100, 46,117,115,101,114, 32, 61, 32,117,115,101,114,105,110,102,111, 10, + 32, 32, 32, 32,114,101,116,117,114,110, 32,112, 97,114,115,101,100, 10,101,110, +100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 10, 45, 45, 32, 82,101, 98,117,105,108,100,115, 32, 97, 32,112, 97,114,115,101, +100, 32, 85, 82, 76, 32,102,114,111,109, 32,105,116,115, 32, 99,111,109,112,111, +110,101,110,116,115, 46, 10, 45, 45, 32, 67,111,109,112,111,110,101,110,116,115, + 32, 97,114,101, 32,112,114,111,116,101, 99,116,101,100, 32,105,102, 32, 97,110, +121, 32,114,101,115,101,114,118,101,100, 32,111,114, 32,117,110, 97,108,108,111, +119,101,100, 32, 99,104, 97,114, 97, 99,116,101,114,115, 32, 97,114,101, 32,102, +111,117,110,100, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,112, + 97,114,115,101,100, 58, 32,112, 97,114,115,101,100, 32, 85, 82, 76, 44, 32, 97, +115, 32,114,101,116,117,114,110,101,100, 32, 98,121, 32,112, 97,114,115,101, 10, + 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, 32, 97, 32,115,116, +114,105,110,103,105,110,103, 32,119,105,116,104, 32,116,104,101, 32, 99,111,114, +114,101,115,112,111,110,100,105,110,103, 32, 85, 82, 76, 10, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111, +110, 32, 98,117,105,108,100, 40,112, 97,114,115,101,100, 41, 10, 32, 32, 32, 32, +108,111, 99, 97,108, 32,112,112, 97,116,104, 32, 61, 32,112, 97,114,115,101, 95, +112, 97,116,104, 40,112, 97,114,115,101,100, 46,112, 97,116,104, 32,111,114, 32, + 34, 34, 41, 10, 32, 32, 32, 32,108,111, 99, 97,108, 32,117,114,108, 32, 61, 32, + 98,117,105,108,100, 95,112, 97,116,104, 40,112,112, 97,116,104, 41, 10, 32, 32, + 32, 32,105,102, 32,112, 97,114,115,101,100, 46,112, 97,114, 97,109,115, 32,116, +104,101,110, 32,117,114,108, 32, 61, 32,117,114,108, 32, 46, 46, 32, 34, 59, 34, + 32, 46, 46, 32,112, 97,114,115,101,100, 46,112, 97,114, 97,109,115, 32,101,110, +100, 10, 32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, 46,113,117,101,114, +121, 32,116,104,101,110, 32,117,114,108, 32, 61, 32,117,114,108, 32, 46, 46, 32, + 34, 63, 34, 32, 46, 46, 32,112, 97,114,115,101,100, 46,113,117,101,114,121, 32, +101,110,100, 10, 9,108,111, 99, 97,108, 32, 97,117,116,104,111,114,105,116,121, + 32, 61, 32,112, 97,114,115,101,100, 46, 97,117,116,104,111,114,105,116,121, 10, + 9,105,102, 32,112, 97,114,115,101,100, 46,104,111,115,116, 32,116,104,101,110, + 10, 9, 9, 97,117,116,104,111,114,105,116,121, 32, 61, 32,112, 97,114,115,101, +100, 46,104,111,115,116, 10, 9, 9,105,102, 32,112, 97,114,115,101,100, 46,112, +111,114,116, 32,116,104,101,110, 32, 97,117,116,104,111,114,105,116,121, 32, 61, + 32, 97,117,116,104,111,114,105,116,121, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46, + 32,112, 97,114,115,101,100, 46,112,111,114,116, 32,101,110,100, 10, 9, 9,108, +111, 99, 97,108, 32,117,115,101,114,105,110,102,111, 32, 61, 32,112, 97,114,115, +101,100, 46,117,115,101,114,105,110,102,111, 10, 9, 9,105,102, 32,112, 97,114, +115,101,100, 46,117,115,101,114, 32,116,104,101,110, 10, 9, 9, 9,117,115,101, +114,105,110,102,111, 32, 61, 32,112, 97,114,115,101,100, 46,117,115,101,114, 10, + 9, 9, 9,105,102, 32,112, 97,114,115,101,100, 46,112, 97,115,115,119,111,114, +100, 32,116,104,101,110, 10, 9, 9, 9, 9,117,115,101,114,105,110,102,111, 32, + 61, 32,117,115,101,114,105,110,102,111, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46, + 32,112, 97,114,115,101,100, 46,112, 97,115,115,119,111,114,100, 10, 9, 9, 9, +101,110,100, 10, 9, 9,101,110,100, 10, 9, 9,105,102, 32,117,115,101,114,105, +110,102,111, 32,116,104,101,110, 32, 97,117,116,104,111,114,105,116,121, 32, 61, + 32,117,115,101,114,105,110,102,111, 32, 46, 46, 32, 34, 64, 34, 32, 46, 46, 32, + 97,117,116,104,111,114,105,116,121, 32,101,110,100, 10, 9,101,110,100, 10, 32, + 32, 32, 32,105,102, 32, 97,117,116,104,111,114,105,116,121, 32,116,104,101,110, + 32,117,114,108, 32, 61, 32, 34, 47, 47, 34, 32, 46, 46, 32, 97,117,116,104,111, +114,105,116,121, 32, 46, 46, 32,117,114,108, 32,101,110,100, 10, 32, 32, 32, 32, +105,102, 32,112, 97,114,115,101,100, 46,115, 99,104,101,109,101, 32,116,104,101, +110, 32,117,114,108, 32, 61, 32,112, 97,114,115,101,100, 46,115, 99,104,101,109, +101, 32, 46, 46, 32, 34, 58, 34, 32, 46, 46, 32,117,114,108, 32,101,110,100, 10, + 32, 32, 32, 32,105,102, 32,112, 97,114,115,101,100, 46,102,114, 97,103,109,101, +110,116, 32,116,104,101,110, 32,117,114,108, 32, 61, 32,117,114,108, 32, 46, 46, + 32, 34, 35, 34, 32, 46, 46, 32,112, 97,114,115,101,100, 46,102,114, 97,103,109, +101,110,116, 32,101,110,100, 10, 32, 32, 32, 32, 45, 45, 32,117,114,108, 32, 61, + 32,115,116,114,105,110,103, 46,103,115,117, 98, 40,117,114,108, 44, 32, 34, 37, +115, 34, 44, 32, 34, 34, 41, 10, 32, 32, 32, 32,114,101,116,117,114,110, 32,117, +114,108, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 10, 45, 45, 32, 66,117,105,108,100,115, 32, 97, 32, 97, 98, +115,111,108,117,116,101, 32, 85, 82, 76, 32,102,114,111,109, 32, 97, 32, 98, 97, +115,101, 32, 97,110,100, 32, 97, 32,114,101,108, 97,116,105,118,101, 32, 85, 82, + 76, 32, 97, 99, 99,111,114,100,105,110,103, 32,116,111, 32, 82, 70, 67, 32, 50, + 51, 57, 54, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32, 98, 97, +115,101, 95,117,114,108, 10, 45, 45, 32, 32, 32,114,101,108, 97,116,105,118,101, + 95,117,114,108, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, 32, 32, + 32, 99,111,114,114,101,115,112,111,110,100,105,110,103, 32, 97, 98,115,111,108, +117,116,101, 32,117,114,108, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, 32, 97, 98,115,111,108, +117,116,101, 40, 98, 97,115,101, 95,117,114,108, 44, 32,114,101,108, 97,116,105, +118,101, 95,117,114,108, 41, 10, 32, 32, 32, 32,105,102, 32, 98, 97,115,101, 46, +116,121,112,101, 40, 98, 97,115,101, 95,117,114,108, 41, 32, 61, 61, 32, 34,116, + 97, 98,108,101, 34, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, + 97,115,101, 95,112, 97,114,115,101,100, 32, 61, 32, 98, 97,115,101, 95,117,114, +108, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115,101, 95,117,114,108, 32, 61, + 32, 98,117,105,108,100, 40, 98, 97,115,101, 95,112, 97,114,115,101,100, 41, 10, + 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97,115, +101, 95,112, 97,114,115,101,100, 32, 61, 32,112, 97,114,115,101, 40, 98, 97,115, +101, 95,117,114,108, 41, 10, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32,108, +111, 99, 97,108, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, + 32, 61, 32,112, 97,114,115,101, 40,114,101,108, 97,116,105,118,101, 95,117,114, +108, 41, 10, 32, 32, 32, 32,105,102, 32,110,111,116, 32, 98, 97,115,101, 95,112, + 97,114,115,101,100, 32,116,104,101,110, 32,114,101,116,117,114,110, 32,114,101, +108, 97,116,105,118,101, 95,117,114,108, 10, 32, 32, 32, 32,101,108,115,101,105, +102, 32,110,111,116, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101, +100, 32,116,104,101,110, 32,114,101,116,117,114,110, 32, 98, 97,115,101, 95,117, +114,108, 10, 32, 32, 32, 32,101,108,115,101,105,102, 32,114,101,108, 97,116,105, +118,101, 95,112, 97,114,115,101,100, 46,115, 99,104,101,109,101, 32,116,104,101, +110, 32,114,101,116,117,114,110, 32,114,101,108, 97,116,105,118,101, 95,117,114, +108, 10, 32, 32, 32, 32,101,108,115,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,114, +101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46,115, 99,104,101,109, +101, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, 46,115, 99,104,101, +109,101, 10, 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101, +108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46, 97,117,116,104,111,114, +105,116,121, 32,116,104,101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46, 97,117,116, +104,111,114,105,116,121, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, + 46, 97,117,116,104,111,114,105,116,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,105,102, 32,110,111,116, 32,114,101,108, 97,116,105,118,101, 95,112, + 97,114,115,101,100, 46,112, 97,116,104, 32,116,104,101,110, 10, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, + 95,112, 97,114,115,101,100, 46,112, 97,116,104, 32, 61, 32, 98, 97,115,101, 95, +112, 97,114,115,101,100, 46,112, 97,116,104, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,108, 97,116, +105,118,101, 95,112, 97,114,115,101,100, 46,112, 97,114, 97,109,115, 32,116,104, +101,110, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 46,112, + 97,114, 97,109,115, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, 46, +112, 97,114, 97,109,115, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,105,102, 32,110,111,116, 32,114,101,108, 97,116,105, +118,101, 95,112, 97,114,115,101,100, 46,113,117,101,114,121, 32,116,104,101,110, + 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, + 46,113,117,101,114,121, 32, 61, 32, 98, 97,115,101, 95,112, 97,114,115,101,100, + 46,113,117,101,114,121, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,101,108,115,101, 32, 32, 32, 32, 10, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97,114, +115,101,100, 46,112, 97,116,104, 32, 61, 32, 97, 98,115,111,108,117,116,101, 95, +112, 97,116,104, 40, 98, 97,115,101, 95,112, 97,114,115,101,100, 46,112, 97,116, +104, 32,111,114, 32, 34, 34, 44, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32,114,101,108, 97,116,105,118,101, 95,112, 97, +114,115,101,100, 46,112, 97,116,104, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32,101,110,100, 10, 32, 32, 32, 32, 32, 32, 32, 32,101,110,100, 10, 32, + 32, 32, 32, 32, 32, 32, 32,114,101,116,117,114,110, 32, 98,117,105,108,100, 40, +114,101,108, 97,116,105,118,101, 95,112, 97,114,115,101,100, 41, 10, 32, 32, 32, + 32,101,110,100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 10, 45, 45, 32, 66,114,101, 97,107,115, 32, 97, 32, +112, 97,116,104, 32,105,110,116,111, 32,105,116,115, 32,115,101,103,109,101,110, +116,115, 44, 32,117,110,101,115, 99, 97,112,105,110,103, 32,116,104,101, 32,115, +101,103,109,101,110,116,115, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, + 32, 32,112, 97,116,104, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, 45, + 32, 32, 32,115,101,103,109,101,110,116, 58, 32, 97, 32,116, 97, 98,108,101, 32, +119,105,116,104, 32,111,110,101, 32,101,110,116,114,121, 32,112,101,114, 32,115, +101,103,109,101,110,116, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 10,102,117,110, 99,116,105,111,110, 32,112, 97,114,115,101, 95, +112, 97,116,104, 40,112, 97,116,104, 41, 10, 9,108,111, 99, 97,108, 32,112, 97, +114,115,101,100, 32, 61, 32,123,125, 10, 9,112, 97,116,104, 32, 61, 32,112, 97, +116,104, 32,111,114, 32, 34, 34, 10, 9, 45, 45,112, 97,116,104, 32, 61, 32,115, +116,114,105,110,103, 46,103,115,117, 98, 40,112, 97,116,104, 44, 32, 34, 37,115, + 34, 44, 32, 34, 34, 41, 10, 9,115,116,114,105,110,103, 46,103,115,117, 98, 40, +112, 97,116,104, 44, 32, 34, 40, 91, 94, 47, 93, 43, 41, 34, 44, 32,102,117,110, + 99,116,105,111,110, 32, 40,115, 41, 32,116, 97, 98,108,101, 46,105,110,115,101, +114,116, 40,112, 97,114,115,101,100, 44, 32,115, 41, 32,101,110,100, 41, 10, 9, +102,111,114, 32,105, 32, 61, 32, 49, 44, 32,116, 97, 98,108,101, 46,103,101,116, +110, 40,112, 97,114,115,101,100, 41, 32,100,111, 10, 9, 9,112, 97,114,115,101, +100, 91,105, 93, 32, 61, 32,117,110,101,115, 99, 97,112,101, 40,112, 97,114,115, +101,100, 91,105, 93, 41, 10, 9,101,110,100, 10, 9,105,102, 32,115,116,114,105, +110,103, 46,115,117, 98, 40,112, 97,116,104, 44, 32, 49, 44, 32, 49, 41, 32, 61, + 61, 32, 34, 47, 34, 32,116,104,101,110, 32,112, 97,114,115,101,100, 46,105,115, + 95, 97, 98,115,111,108,117,116,101, 32, 61, 32, 49, 32,101,110,100, 10, 9,105, +102, 32,115,116,114,105,110,103, 46,115,117, 98, 40,112, 97,116,104, 44, 32, 45, + 49, 44, 32, 45, 49, 41, 32, 61, 61, 32, 34, 47, 34, 32,116,104,101,110, 32,112, + 97,114,115,101,100, 46,105,115, 95,100,105,114,101, 99,116,111,114,121, 32, 61, + 32, 49, 32,101,110,100, 10, 9,114,101,116,117,114,110, 32,112, 97,114,115,101, +100, 10,101,110,100, 10, 10, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 10, 45, 45, 32, 66,117,105,108,100,115, 32, 97, 32,112, 97,116, +104, 32, 99,111,109,112,111,110,101,110,116, 32,102,114,111,109, 32,105,116,115, + 32,115,101,103,109,101,110,116,115, 44, 32,101,115, 99, 97,112,105,110,103, 32, +112,114,111,116,101, 99,116,101,100, 32, 99,104, 97,114, 97, 99,116,101,114,115, + 46, 10, 45, 45, 32, 73,110,112,117,116, 10, 45, 45, 32, 32, 32,112, 97,114,115, +101,100, 58, 32,112, 97,116,104, 32,115,101,103,109,101,110,116,115, 10, 45, 45, + 32, 32, 32,117,110,115, 97,102,101, 58, 32,105,102, 32,116,114,117,101, 44, 32, +115,101,103,109,101,110,116,115, 32, 97,114,101, 32,110,111,116, 32,112,114,111, +116,101, 99,116,101,100, 32, 98,101,102,111,114,101, 32,112, 97,116,104, 32,105, +115, 32, 98,117,105,108,116, 10, 45, 45, 32, 82,101,116,117,114,110,115, 10, 45, + 45, 32, 32, 32,112, 97,116,104, 58, 32, 99,111,114,114,101,115,112,111,110,100, +105,110,103, 32,112, 97,116,104, 32,115,116,114,105,110,103,105,110,103, 10, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 10,102,117,110, + 99,116,105,111,110, 32, 98,117,105,108,100, 95,112, 97,116,104, 40,112, 97,114, +115,101,100, 44, 32,117,110,115, 97,102,101, 41, 10, 9,108,111, 99, 97,108, 32, +112, 97,116,104, 32, 61, 32, 34, 34, 10, 9,108,111, 99, 97,108, 32,110, 32, 61, + 32,116, 97, 98,108,101, 46,103,101,116,110, 40,112, 97,114,115,101,100, 41, 10, + 9,105,102, 32,117,110,115, 97,102,101, 32,116,104,101,110, 10, 9, 9,102,111, +114, 32,105, 32, 61, 32, 49, 44, 32,110, 45, 49, 32,100,111, 10, 9, 9, 9,112, + 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, 46, 32,112, 97,114,115,101,100, + 91,105, 93, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, + 46, 32, 34, 47, 34, 10, 9, 9,101,110,100, 10, 9, 9,105,102, 32,110, 32, 62, + 32, 48, 32,116,104,101,110, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97, +116,104, 32, 46, 46, 32,112, 97,114,115,101,100, 91,110, 93, 10, 9, 9, 9,105, +102, 32,112, 97,114,115,101,100, 46,105,115, 95,100,105,114,101, 99,116,111,114, +121, 32,116,104,101,110, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, + 46, 32, 34, 47, 34, 32,101,110,100, 10, 9, 9,101,110,100, 10, 9,101,108,115, +101, 10, 9, 9,102,111,114, 32,105, 32, 61, 32, 49, 44, 32,110, 45, 49, 32,100, +111, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, 46, 32, +112,114,111,116,101, 99,116, 95,115,101,103,109,101,110,116, 40,112, 97,114,115, +101,100, 91,105, 93, 41, 10, 9, 9, 9,112, 97,116,104, 32, 61, 32,112, 97,116, +104, 32, 46, 46, 32, 34, 47, 34, 10, 9, 9,101,110,100, 10, 9, 9,105,102, 32, +110, 32, 62, 32, 48, 32,116,104,101,110, 10, 9, 9, 9,112, 97,116,104, 32, 61, + 32,112, 97,116,104, 32, 46, 46, 32,112,114,111,116,101, 99,116, 95,115,101,103, +109,101,110,116, 40,112, 97,114,115,101,100, 91,110, 93, 41, 10, 9, 9, 9,105, +102, 32,112, 97,114,115,101,100, 46,105,115, 95,100,105,114,101, 99,116,111,114, +121, 32,116,104,101,110, 32,112, 97,116,104, 32, 61, 32,112, 97,116,104, 32, 46, + 46, 32, 34, 47, 34, 32,101,110,100, 10, 9, 9,101,110,100, 10, 9,101,110,100, + 10, 9,105,102, 32,112, 97,114,115,101,100, 46,105,115, 95, 97, 98,115,111,108, +117,116,101, 32,116,104,101,110, 32,112, 97,116,104, 32, 61, 32, 34, 47, 34, 32, + 46, 46, 32,112, 97,116,104, 32,101,110,100, 10, 9,114,101,116,117,114,110, 32, +112, 97,116,104, 10,101,110,100, 10, + 0 }; + return luaL_dostring(L, (const char*)B); +} /* end of embedded lua code */ + diff --git a/src/libs/luasocket/src/usocket.c b/src/libs/luasocket/src/usocket.c new file mode 100644 index 000000000..70c6e1e39 --- /dev/null +++ b/src/libs/luasocket/src/usocket.c @@ -0,0 +1,370 @@ +/*=========================================================================*\ +* Socket compatibilization module for Unix +* LuaSocket toolkit +* +* The code is now interrupt-safe. +* The penalty of calling select to avoid busy-wait is only paid when +* the I/O call fail in the first place. +* +* RCS ID: $Id: usocket.c,v 1.38 2007/10/13 23:55:20 diego Exp $ +\*=========================================================================*/ +#include <string.h> +#include <signal.h> + +#include "socket.h" + +/*-------------------------------------------------------------------------*\ +* Wait for readable/writable/connected socket with timeout +\*-------------------------------------------------------------------------*/ +#ifdef SOCKET_POLL +#include <sys/poll.h> + +#define WAITFD_R POLLIN +#define WAITFD_W POLLOUT +#define WAITFD_C (POLLIN|POLLOUT) +int socket_waitfd(p_socket ps, int sw, p_timeout tm) { + int ret; + struct pollfd pfd; + pfd.fd = *ps; + pfd.events = sw; + pfd.revents = 0; + if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */ + do { + int t = (int)(timeout_getretry(tm)*1e3); + ret = poll(&pfd, 1, t >= 0? t: -1); + } while (ret == -1 && errno == EINTR); + if (ret == -1) return errno; + if (ret == 0) return IO_TIMEOUT; + if (sw == WAITFD_C && (pfd.revents & (POLLIN|POLLERR))) return IO_CLOSED; + return IO_DONE; +} +#else + +#define WAITFD_R 1 +#define WAITFD_W 2 +#define WAITFD_C (WAITFD_R|WAITFD_W) + +int socket_waitfd(p_socket ps, int sw, p_timeout tm) { + int ret; + fd_set rfds, wfds, *rp, *wp; + struct timeval tv, *tp; + double t; + if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */ + do { + /* must set bits within loop, because select may have modifed them */ + rp = wp = NULL; + if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(*ps, &rfds); rp = &rfds; } + if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; } + t = timeout_getretry(tm); + tp = NULL; + if (t >= 0.0) { + tv.tv_sec = (int)t; + tv.tv_usec = (int)((t-tv.tv_sec)*1.0e6); + tp = &tv; + } + ret = select(*ps+1, rp, wp, NULL, tp); + } while (ret == -1 && errno == EINTR); + if (ret == -1) return errno; + if (ret == 0) return IO_TIMEOUT; + if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) return IO_CLOSED; + return IO_DONE; +} +#endif + + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int socket_open(void) { + /* instals a handler to ignore sigpipe or it will crash us */ + signal(SIGPIPE, SIG_IGN); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Close module +\*-------------------------------------------------------------------------*/ +int socket_close(void) { + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Close and inutilize socket +\*-------------------------------------------------------------------------*/ +void socket_destroy(p_socket ps) { + if (*ps != SOCKET_INVALID) { + socket_setblocking(ps); + close(*ps); + *ps = SOCKET_INVALID; + } +} + +/*-------------------------------------------------------------------------*\ +* Select with timeout control +\*-------------------------------------------------------------------------*/ +int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, + p_timeout tm) { + int ret; + do { + struct timeval tv; + double t = timeout_getretry(tm); + tv.tv_sec = (int) t; + tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6); + /* timeout = 0 means no wait */ + ret = select(n, rfds, wfds, efds, t >= 0.0 ? &tv: NULL); + } while (ret < 0 && errno == EINTR); + return ret; +} + +/*-------------------------------------------------------------------------*\ +* Creates and sets up a socket +\*-------------------------------------------------------------------------*/ +int socket_create(p_socket ps, int domain, int type, int protocol) { + *ps = socket(domain, type, protocol); + if (*ps != SOCKET_INVALID) return IO_DONE; + else return errno; +} + +/*-------------------------------------------------------------------------*\ +* Binds or returns error message +\*-------------------------------------------------------------------------*/ +int socket_bind(p_socket ps, SA *addr, socklen_t len) { + int err = IO_DONE; + socket_setblocking(ps); + if (bind(*ps, addr, len) < 0) err = errno; + socket_setnonblocking(ps); + return err; +} + +/*-------------------------------------------------------------------------*\ +* +\*-------------------------------------------------------------------------*/ +int socket_listen(p_socket ps, int backlog) { + int err = IO_DONE; + socket_setblocking(ps); + if (listen(*ps, backlog)) err = errno; + socket_setnonblocking(ps); + return err; +} + +/*-------------------------------------------------------------------------*\ +* +\*-------------------------------------------------------------------------*/ +void socket_shutdown(p_socket ps, int how) { + socket_setblocking(ps); + shutdown(*ps, how); + socket_setnonblocking(ps); +} + +/*-------------------------------------------------------------------------*\ +* Connects or returns error message +\*-------------------------------------------------------------------------*/ +int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) { + int err; + /* avoid calling on closed sockets */ + if (*ps == SOCKET_INVALID) return IO_CLOSED; + /* call connect until done or failed without being interrupted */ + do if (connect(*ps, addr, len) == 0) return IO_DONE; + while ((err = errno) == EINTR); + /* if connection failed immediately, return error code */ + if (err != EINPROGRESS && err != EAGAIN) return err; + /* zero timeout case optimization */ + if (timeout_iszero(tm)) return IO_TIMEOUT; + /* wait until we have the result of the connection attempt or timeout */ + err = socket_waitfd(ps, WAITFD_C, tm); + if (err == IO_CLOSED) { + if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE; + else return errno; + } else return err; +} + +/*-------------------------------------------------------------------------*\ +* Accept with timeout +\*-------------------------------------------------------------------------*/ +int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout tm) { + SA daddr; + socklen_t dlen = sizeof(daddr); + if (*ps == SOCKET_INVALID) return IO_CLOSED; + if (!addr) addr = &daddr; + if (!len) len = &dlen; + for ( ;; ) { + int err; + if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE; + err = errno; + if (err == EINTR) continue; + if (err != EAGAIN && err != ECONNABORTED) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + } + /* can't reach here */ + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Send with timeout +\*-------------------------------------------------------------------------*/ +int socket_send(p_socket ps, const char *data, size_t count, + size_t *sent, p_timeout tm) +{ + int err; + *sent = 0; + /* avoid making system calls on closed sockets */ + if (*ps == SOCKET_INVALID) return IO_CLOSED; + /* loop until we send something or we give up on error */ + for ( ;; ) { + long put = (long) send(*ps, data, count, 0); + /* if we sent anything, we are done */ + if (put > 0) { + *sent = put; + return IO_DONE; + } + err = errno; + /* send can't really return 0, but EPIPE means the connection was + closed */ + if (put == 0 || err == EPIPE) return IO_CLOSED; + /* we call was interrupted, just try again */ + if (err == EINTR) continue; + /* if failed fatal reason, report error */ + if (err != EAGAIN) return err; + /* wait until we can send something or we timeout */ + if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; + } + /* can't reach here */ + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Sendto with timeout +\*-------------------------------------------------------------------------*/ +int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, + SA *addr, socklen_t len, p_timeout tm) +{ + int err; + *sent = 0; + if (*ps == SOCKET_INVALID) return IO_CLOSED; + for ( ;; ) { + long put = (long) sendto(*ps, data, count, 0, addr, len); + if (put > 0) { + *sent = put; + return IO_DONE; + } + err = errno; + if (put == 0 || err == EPIPE) return IO_CLOSED; + if (err == EINTR) continue; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; + } + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Receive with timeout +\*-------------------------------------------------------------------------*/ +int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { + int err; + *got = 0; + if (*ps == SOCKET_INVALID) return IO_CLOSED; + for ( ;; ) { + long taken = (long) recv(*ps, data, count, 0); + if (taken > 0) { + *got = taken; + return IO_DONE; + } + err = errno; + if (taken == 0) return IO_CLOSED; + if (err == EINTR) continue; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + } + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Recvfrom with timeout +\*-------------------------------------------------------------------------*/ +int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, + SA *addr, socklen_t *len, p_timeout tm) { + int err; + *got = 0; + if (*ps == SOCKET_INVALID) return IO_CLOSED; + for ( ;; ) { + long taken = (long) recvfrom(*ps, data, count, 0, addr, len); + if (taken > 0) { + *got = taken; + return IO_DONE; + } + err = errno; + if (taken == 0) return IO_CLOSED; + if (err == EINTR) continue; + if (err != EAGAIN) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + } + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Put socket into blocking mode +\*-------------------------------------------------------------------------*/ +void socket_setblocking(p_socket ps) { + int flags = fcntl(*ps, F_GETFL, 0); + flags &= (~(O_NONBLOCK)); + fcntl(*ps, F_SETFL, flags); +} + +/*-------------------------------------------------------------------------*\ +* Put socket into non-blocking mode +\*-------------------------------------------------------------------------*/ +void socket_setnonblocking(p_socket ps) { + int flags = fcntl(*ps, F_GETFL, 0); + flags |= O_NONBLOCK; + fcntl(*ps, F_SETFL, flags); +} + +/*-------------------------------------------------------------------------*\ +* DNS helpers +\*-------------------------------------------------------------------------*/ +int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { + *hp = gethostbyaddr(addr, len, AF_INET); + if (*hp) return IO_DONE; + else if (h_errno) return h_errno; + else if (errno) return errno; + else return IO_UNKNOWN; +} + +int socket_gethostbyname(const char *addr, struct hostent **hp) { + *hp = gethostbyname(addr); + if (*hp) return IO_DONE; + else if (h_errno) return h_errno; + else if (errno) return errno; + else return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Error translation functions +* Make sure important error messages are standard +\*-------------------------------------------------------------------------*/ +const char *socket_hoststrerror(int err) { + if (err <= 0) return io_strerror(err); + switch (err) { + case HOST_NOT_FOUND: return "host not found"; + default: return hstrerror(err); + } +} + +const char *socket_strerror(int err) { + if (err <= 0) return io_strerror(err); + switch (err) { + case EADDRINUSE: return "address already in use"; + case EISCONN: return "already connected"; + case EACCES: return "permission denied"; + case ECONNREFUSED: return "connection refused"; + case ECONNABORTED: return "closed"; + case ECONNRESET: return "closed"; + case ETIMEDOUT: return "timeout"; + default: return strerror(errno); + } +} + +const char *socket_ioerror(p_socket ps, int err) { + (void) ps; + return socket_strerror(err); +} diff --git a/src/libs/luasocket/src/usocket.h b/src/libs/luasocket/src/usocket.h new file mode 100644 index 000000000..f2a89aa0d --- /dev/null +++ b/src/libs/luasocket/src/usocket.h @@ -0,0 +1,40 @@ +#ifndef USOCKET_H +#define USOCKET_H +/*=========================================================================*\ +* Socket compatibilization module for Unix +* LuaSocket toolkit +* +* RCS ID: $Id: usocket.h,v 1.7 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ + +/*=========================================================================*\ +* BSD include files +\*=========================================================================*/ +/* error codes */ +#include <errno.h> +/* close function */ +#include <unistd.h> +/* fnctnl function and associated constants */ +#include <fcntl.h> +/* struct sockaddr */ +#include <sys/types.h> +/* socket function */ +#include <sys/socket.h> +/* struct timeval */ +#include <sys/time.h> +/* gethostbyname and gethostbyaddr functions */ +#include <netdb.h> +/* sigpipe handling */ +#include <signal.h> +/* IP stuff*/ +#include <netinet/in.h> +#include <arpa/inet.h> +/* TCP options (nagle algorithm disable) */ +#include <netinet/tcp.h> + +typedef int t_socket; +typedef t_socket *p_socket; + +#define SOCKET_INVALID (-1) + +#endif /* USOCKET_H */ diff --git a/src/libs/luasocket/src/wsocket.c b/src/libs/luasocket/src/wsocket.c new file mode 100644 index 000000000..602256518 --- /dev/null +++ b/src/libs/luasocket/src/wsocket.c @@ -0,0 +1,401 @@ +/*=========================================================================*\ +* Socket compatibilization module for Win32 +* LuaSocket toolkit +* +* The penalty of calling select to avoid busy-wait is only paid when +* the I/O call fail in the first place. +* +* RCS ID: $Id: wsocket.c,v 1.36 2007/06/11 23:44:54 diego Exp $ +\*=========================================================================*/ +#include <string.h> + +#include "socket.h" + +/* WinSock doesn't have a strerror... */ +static const char *wstrerror(int err); + +/*-------------------------------------------------------------------------*\ +* Initializes module +\*-------------------------------------------------------------------------*/ +int socket_open(void) { + WSADATA wsaData; + WORD wVersionRequested = MAKEWORD(2, 0); + int err = WSAStartup(wVersionRequested, &wsaData ); + if (err != 0) return 0; + if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) && + (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) { + WSACleanup(); + return 0; + } + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Close module +\*-------------------------------------------------------------------------*/ +int socket_close(void) { + WSACleanup(); + return 1; +} + +/*-------------------------------------------------------------------------*\ +* Wait for readable/writable/connected socket with timeout +\*-------------------------------------------------------------------------*/ +#define WAITFD_R 1 +#define WAITFD_W 2 +#define WAITFD_E 4 +#define WAITFD_C (WAITFD_E|WAITFD_W) + +int socket_waitfd(p_socket ps, int sw, p_timeout tm) { + int ret; + fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL; + struct timeval tv, *tp = NULL; + double t; + if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */ + if (sw & WAITFD_R) { + FD_ZERO(&rfds); + FD_SET(*ps, &rfds); + rp = &rfds; + } + if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; } + if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; } + if ((t = timeout_get(tm)) >= 0.0) { + tv.tv_sec = (int) t; + tv.tv_usec = (int) ((t-tv.tv_sec)*1.0e6); + tp = &tv; + } + ret = select(0, rp, wp, ep, tp); + if (ret == -1) return WSAGetLastError(); + if (ret == 0) return IO_TIMEOUT; + if (sw == WAITFD_C && FD_ISSET(*ps, &efds)) return IO_CLOSED; + return IO_DONE; +} + +/*-------------------------------------------------------------------------*\ +* Select with int timeout in ms +\*-------------------------------------------------------------------------*/ +int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, + p_timeout tm) { + struct timeval tv; + double t = timeout_get(tm); + tv.tv_sec = (int) t; + tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6); + if (n <= 0) { + Sleep((DWORD) (1000*t)); + return 0; + } else return select(0, rfds, wfds, efds, t >= 0.0? &tv: NULL); +} + +/*-------------------------------------------------------------------------*\ +* Close and inutilize socket +\*-------------------------------------------------------------------------*/ +void socket_destroy(p_socket ps) { + if (*ps != SOCKET_INVALID) { + socket_setblocking(ps); /* close can take a long time on WIN32 */ + closesocket(*ps); + *ps = SOCKET_INVALID; + } +} + +/*-------------------------------------------------------------------------*\ +* +\*-------------------------------------------------------------------------*/ +void socket_shutdown(p_socket ps, int how) { + socket_setblocking(ps); + shutdown(*ps, how); + socket_setnonblocking(ps); +} + +/*-------------------------------------------------------------------------*\ +* Creates and sets up a socket +\*-------------------------------------------------------------------------*/ +int socket_create(p_socket ps, int domain, int type, int protocol) { + *ps = socket(domain, type, protocol); + if (*ps != SOCKET_INVALID) return IO_DONE; + else return WSAGetLastError(); +} + +/*-------------------------------------------------------------------------*\ +* Connects or returns error message +\*-------------------------------------------------------------------------*/ +int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) { + int err; + /* don't call on closed socket */ + if (*ps == SOCKET_INVALID) return IO_CLOSED; + /* ask system to connect */ + if (connect(*ps, addr, len) == 0) return IO_DONE; + /* make sure the system is trying to connect */ + err = WSAGetLastError(); + if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) return err; + /* zero timeout case optimization */ + if (timeout_iszero(tm)) return IO_TIMEOUT; + /* we wait until something happens */ + err = socket_waitfd(ps, WAITFD_C, tm); + if (err == IO_CLOSED) { + int len = sizeof(err); + /* give windows time to set the error (yes, disgusting) */ + Sleep(10); + /* find out why we failed */ + getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len); + /* we KNOW there was an error. if 'why' is 0, we will return + * "unknown error", but it's not really our fault */ + return err > 0? err: IO_UNKNOWN; + } else return err; + +} + +/*-------------------------------------------------------------------------*\ +* Binds or returns error message +\*-------------------------------------------------------------------------*/ +int socket_bind(p_socket ps, SA *addr, socklen_t len) { + int err = IO_DONE; + socket_setblocking(ps); + if (bind(*ps, addr, len) < 0) err = WSAGetLastError(); + socket_setnonblocking(ps); + return err; +} + +/*-------------------------------------------------------------------------*\ +* +\*-------------------------------------------------------------------------*/ +int socket_listen(p_socket ps, int backlog) { + int err = IO_DONE; + socket_setblocking(ps); + if (listen(*ps, backlog) < 0) err = WSAGetLastError(); + socket_setnonblocking(ps); + return err; +} + +/*-------------------------------------------------------------------------*\ +* Accept with timeout +\*-------------------------------------------------------------------------*/ +int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, + p_timeout tm) { + SA daddr; + socklen_t dlen = sizeof(daddr); + if (*ps == SOCKET_INVALID) return IO_CLOSED; + if (!addr) addr = &daddr; + if (!len) len = &dlen; + for ( ;; ) { + int err; + /* try to get client socket */ + if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE; + /* find out why we failed */ + err = WSAGetLastError(); + /* if we failed because there was no connectoin, keep trying */ + if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) return err; + /* call select to avoid busy wait */ + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + } + /* can't reach here */ + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Send with timeout +* On windows, if you try to send 10MB, the OS will buffer EVERYTHING +* this can take an awful lot of time and we will end up blocked. +* Therefore, whoever calls this function should not pass a huge buffer. +\*-------------------------------------------------------------------------*/ +int socket_send(p_socket ps, const char *data, size_t count, + size_t *sent, p_timeout tm) +{ + int err; + *sent = 0; + /* avoid making system calls on closed sockets */ + if (*ps == SOCKET_INVALID) return IO_CLOSED; + /* loop until we send something or we give up on error */ + for ( ;; ) { + /* try to send something */ + int put = send(*ps, data, (int) count, 0); + /* if we sent something, we are done */ + if (put > 0) { + *sent = put; + return IO_DONE; + } + /* deal with failure */ + err = WSAGetLastError(); + /* we can only proceed if there was no serious error */ + if (err != WSAEWOULDBLOCK) return err; + /* avoid busy wait */ + if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; + } + /* can't reach here */ + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Sendto with timeout +\*-------------------------------------------------------------------------*/ +int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, + SA *addr, socklen_t len, p_timeout tm) +{ + int err; + *sent = 0; + if (*ps == SOCKET_INVALID) return IO_CLOSED; + for ( ;; ) { + int put = sendto(*ps, data, (int) count, 0, addr, len); + if (put > 0) { + *sent = put; + return IO_DONE; + } + err = WSAGetLastError(); + if (err != WSAEWOULDBLOCK) return err; + if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; + } + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Receive with timeout +\*-------------------------------------------------------------------------*/ +int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { + int err; + *got = 0; + if (*ps == SOCKET_INVALID) return IO_CLOSED; + for ( ;; ) { + int taken = recv(*ps, data, (int) count, 0); + if (taken > 0) { + *got = taken; + return IO_DONE; + } + if (taken == 0) return IO_CLOSED; + err = WSAGetLastError(); + if (err != WSAEWOULDBLOCK) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + } + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Recvfrom with timeout +\*-------------------------------------------------------------------------*/ +int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, + SA *addr, socklen_t *len, p_timeout tm) { + int err; + *got = 0; + if (*ps == SOCKET_INVALID) return IO_CLOSED; + for ( ;; ) { + int taken = recvfrom(*ps, data, (int) count, 0, addr, len); + if (taken > 0) { + *got = taken; + return IO_DONE; + } + if (taken == 0) return IO_CLOSED; + err = WSAGetLastError(); + if (err != WSAEWOULDBLOCK) return err; + if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; + } + return IO_UNKNOWN; +} + +/*-------------------------------------------------------------------------*\ +* Put socket into blocking mode +\*-------------------------------------------------------------------------*/ +void socket_setblocking(p_socket ps) { + u_long argp = 0; + ioctlsocket(*ps, FIONBIO, &argp); +} + +/*-------------------------------------------------------------------------*\ +* Put socket into non-blocking mode +\*-------------------------------------------------------------------------*/ +void socket_setnonblocking(p_socket ps) { + u_long argp = 1; + ioctlsocket(*ps, FIONBIO, &argp); +} + +/*-------------------------------------------------------------------------*\ +* DNS helpers +\*-------------------------------------------------------------------------*/ +int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { + *hp = gethostbyaddr(addr, len, AF_INET); + if (*hp) return IO_DONE; + else return WSAGetLastError(); +} + +int socket_gethostbyname(const char *addr, struct hostent **hp) { + *hp = gethostbyname(addr); + if (*hp) return IO_DONE; + else return WSAGetLastError(); +} + +/*-------------------------------------------------------------------------*\ +* Error translation functions +\*-------------------------------------------------------------------------*/ +const char *socket_hoststrerror(int err) { + if (err <= 0) return io_strerror(err); + switch (err) { + case WSAHOST_NOT_FOUND: return "host not found"; + default: return wstrerror(err); + } +} + +const char *socket_strerror(int err) { + if (err <= 0) return io_strerror(err); + switch (err) { + case WSAEADDRINUSE: return "address already in use"; + case WSAECONNREFUSED: return "connection refused"; + case WSAEISCONN: return "already connected"; + case WSAEACCES: return "permission denied"; + case WSAECONNABORTED: return "closed"; + case WSAECONNRESET: return "closed"; + case WSAETIMEDOUT: return "timeout"; + default: return wstrerror(err); + } +} + +const char *socket_ioerror(p_socket ps, int err) { + (void) ps; + return socket_strerror(err); +} + +static const char *wstrerror(int err) { + switch (err) { + case WSAEINTR: return "Interrupted function call"; + case WSAEACCES: return "Permission denied"; + case WSAEFAULT: return "Bad address"; + case WSAEINVAL: return "Invalid argument"; + case WSAEMFILE: return "Too many open files"; + case WSAEWOULDBLOCK: return "Resource temporarily unavailable"; + case WSAEINPROGRESS: return "Operation now in progress"; + case WSAEALREADY: return "Operation already in progress"; + case WSAENOTSOCK: return "Socket operation on nonsocket"; + case WSAEDESTADDRREQ: return "Destination address required"; + case WSAEMSGSIZE: return "Message too long"; + case WSAEPROTOTYPE: return "Protocol wrong type for socket"; + case WSAENOPROTOOPT: return "Bad protocol option"; + case WSAEPROTONOSUPPORT: return "Protocol not supported"; + case WSAESOCKTNOSUPPORT: return "Socket type not supported"; + case WSAEOPNOTSUPP: return "Operation not supported"; + case WSAEPFNOSUPPORT: return "Protocol family not supported"; + case WSAEAFNOSUPPORT: + return "Address family not supported by protocol family"; + case WSAEADDRINUSE: return "Address already in use"; + case WSAEADDRNOTAVAIL: return "Cannot assign requested address"; + case WSAENETDOWN: return "Network is down"; + case WSAENETUNREACH: return "Network is unreachable"; + case WSAENETRESET: return "Network dropped connection on reset"; + case WSAECONNABORTED: return "Software caused connection abort"; + case WSAECONNRESET: return "Connection reset by peer"; + case WSAENOBUFS: return "No buffer space available"; + case WSAEISCONN: return "Socket is already connected"; + case WSAENOTCONN: return "Socket is not connected"; + case WSAESHUTDOWN: return "Cannot send after socket shutdown"; + case WSAETIMEDOUT: return "Connection timed out"; + case WSAECONNREFUSED: return "Connection refused"; + case WSAEHOSTDOWN: return "Host is down"; + case WSAEHOSTUNREACH: return "No route to host"; + case WSAEPROCLIM: return "Too many processes"; + case WSASYSNOTREADY: return "Network subsystem is unavailable"; + case WSAVERNOTSUPPORTED: return "Winsock.dll version out of range"; + case WSANOTINITIALISED: + return "Successful WSAStartup not yet performed"; + case WSAEDISCON: return "Graceful shutdown in progress"; + case WSAHOST_NOT_FOUND: return "Host not found"; + case WSATRY_AGAIN: return "Nonauthoritative host not found"; + case WSANO_RECOVERY: return "Nonrecoverable name lookup error"; + case WSANO_DATA: return "Valid name, no data record of requested type"; + default: return "Unknown error"; + } +} diff --git a/src/libs/luasocket/src/wsocket.h b/src/libs/luasocket/src/wsocket.h new file mode 100644 index 000000000..b53668368 --- /dev/null +++ b/src/libs/luasocket/src/wsocket.h @@ -0,0 +1,21 @@ +#ifndef WSOCKET_H +#define WSOCKET_H +/*=========================================================================*\ +* Socket compatibilization module for Win32 +* LuaSocket toolkit +* +* RCS ID: $Id: wsocket.h,v 1.4 2005/10/07 04:40:59 diego Exp $ +\*=========================================================================*/ + +/*=========================================================================*\ +* WinSock include files +\*=========================================================================*/ +#include <winsock.h> + +typedef int socklen_t; +typedef SOCKET t_socket; +typedef t_socket *p_socket; + +#define SOCKET_INVALID (INVALID_SOCKET) + +#endif /* WSOCKET_H */ diff --git a/src/libs/luasocket/test/README b/src/libs/luasocket/test/README new file mode 100644 index 000000000..180fa277c --- /dev/null +++ b/src/libs/luasocket/test/README @@ -0,0 +1,12 @@ +This provides the automated test scripts used to make sure the library +is working properly. + +The files provided are: + + testsrvr.lua -- test server + testclnt.lua -- test client + +To run these tests, just run lua on the server and then on the client. + +Good luck, +Diego. diff --git a/src/libs/luasocket/test/testclnt.lua b/src/libs/luasocket/test/testclnt.lua new file mode 100644 index 000000000..a7ca1ba67 --- /dev/null +++ b/src/libs/luasocket/test/testclnt.lua @@ -0,0 +1,713 @@ +local socket = require"socket" + +host = host or "localhost" +port = port or "8383" + +function pass(...) + local s = string.format(unpack(arg)) + io.stderr:write(s, "\n") +end + +function fail(...) + local s = string.format(unpack(arg)) + io.stderr:write("ERROR: ", s, "!\n") +socket.sleep(3) + os.exit() +end + +function warn(...) + local s = string.format(unpack(arg)) + io.stderr:write("WARNING: ", s, "\n") +end + +function remote(...) + local s = string.format(unpack(arg)) + s = string.gsub(s, "\n", ";") + s = string.gsub(s, "%s+", " ") + s = string.gsub(s, "^%s*", "") + control:send(s .. "\n") + control:receive() +end + +function test(test) + io.stderr:write("----------------------------------------------\n", + "testing: ", test, "\n", + "----------------------------------------------\n") +end + +function check_timeout(tm, sl, elapsed, err, opp, mode, alldone) + if tm < sl then + if opp == "send" then + if not err then warn("must be buffered") + elseif err == "timeout" then pass("proper timeout") + else fail("unexpected error '%s'", err) end + else + if err ~= "timeout" then fail("should have timed out") + else pass("proper timeout") end + end + else + if mode == "total" then + if elapsed > tm then + if err ~= "timeout" then fail("should have timed out") + else pass("proper timeout") end + elseif elapsed < tm then + if err then fail(err) + else pass("ok") end + else + if alldone then + if err then fail("unexpected error '%s'", err) + else pass("ok") end + else + if err ~= "timeout" then fail(err) + else pass("proper timeoutk") end + end + end + else + if err then fail(err) + else pass("ok") end + end + end +end + +if not socket._DEBUG then + fail("Please define LUASOCKET_DEBUG and recompile LuaSocket") +end + +io.stderr:write("----------------------------------------------\n", +"LuaSocket Test Procedures\n", +"----------------------------------------------\n") + +start = socket.gettime() + +function reconnect() + io.stderr:write("attempting data connection... ") + if data then data:close() end + remote [[ + if data then data:close() data = nil end + data = server:accept() + data:setoption("tcp-nodelay", true) + ]] + data, err = socket.connect(host, port) + if not data then fail(err) + else pass("connected!") end + data:setoption("tcp-nodelay", true) +end + +pass("attempting control connection...") +control, err = socket.connect(host, port) +if err then fail(err) +else pass("connected!") end +control:setoption("tcp-nodelay", true) + +------------------------------------------------------------------------ +function test_methods(sock, methods) + for _, v in pairs(methods) do + if type(sock[v]) ~= "function" then + fail(sock.class .. " method '" .. v .. "' not registered") + end + end + pass(sock.class .. " methods are ok") +end + +------------------------------------------------------------------------ +function test_mixed(len) + reconnect() + local inter = math.ceil(len/4) + local p1 = "unix " .. string.rep("x", inter) .. "line\n" + local p2 = "dos " .. string.rep("y", inter) .. "line\r\n" + local p3 = "raw " .. string.rep("z", inter) .. "bytes" + local p4 = "end" .. string.rep("w", inter) .. "bytes" + local bp1, bp2, bp3, bp4 +remote (string.format("str = data:receive(%d)", + string.len(p1)+string.len(p2)+string.len(p3)+string.len(p4))) + sent, err = data:send(p1..p2..p3..p4) + if err then fail(err) end +remote "data:send(str); data:close()" + bp1, err = data:receive() + if err then fail(err) end + bp2, err = data:receive() + if err then fail(err) end + bp3, err = data:receive(string.len(p3)) + if err then fail(err) end + bp4, err = data:receive("*a") + if err then fail(err) end + if bp1.."\n" == p1 and bp2.."\r\n" == p2 and bp3 == p3 and bp4 == p4 then + pass("patterns match") + else fail("patterns don't match") end +end + +------------------------------------------------------------------------ +function test_asciiline(len) + reconnect() + local str, str10, back, err + str = string.rep("x", math.mod(len, 10)) + str10 = string.rep("aZb.c#dAe?", math.floor(len/10)) + str = str .. str10 +remote "str = data:receive()" + sent, err = data:send(str.."\n") + if err then fail(err) end +remote "data:send(str ..'\\n')" + back, err = data:receive() + if err then fail(err) end + if back == str then pass("lines match") + else fail("lines don't match") end +end + +------------------------------------------------------------------------ +function test_rawline(len) + reconnect() + local str, str10, back, err + str = string.rep(string.char(47), math.mod(len, 10)) + str10 = string.rep(string.char(120,21,77,4,5,0,7,36,44,100), + math.floor(len/10)) + str = str .. str10 +remote "str = data:receive()" + sent, err = data:send(str.."\n") + if err then fail(err) end +remote "data:send(str..'\\n')" + back, err = data:receive() + if err then fail(err) end + if back == str then pass("lines match") + else fail("lines don't match") end +end + +------------------------------------------------------------------------ +function test_raw(len) + reconnect() + local half = math.floor(len/2) + local s1, s2, back, err + s1 = string.rep("x", half) + s2 = string.rep("y", len-half) +remote (string.format("str = data:receive(%d)", len)) + sent, err = data:send(s1) + if err then fail(err) end + sent, err = data:send(s2) + if err then fail(err) end +remote "data:send(str)" + back, err = data:receive(len) + if err then fail(err) end + if back == s1..s2 then pass("blocks match") + else fail("blocks don't match") end +end + +------------------------------------------------------------------------ +function test_totaltimeoutreceive(len, tm, sl) + reconnect() + local str, err, partial + pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl) + remote (string.format ([[ + data:settimeout(%d) + str = string.rep('a', %d) + data:send(str) + print('server: sleeping for %ds') + socket.sleep(%d) + print('server: woke up') + data:send(str) + ]], 2*tm, len, sl, sl)) + data:settimeout(tm, "total") +local t = socket.gettime() + str, err, partial, elapsed = data:receive(2*len) + check_timeout(tm, sl, elapsed, err, "receive", "total", + string.len(str or partial) == 2*len) +end + +------------------------------------------------------------------------ +function test_totaltimeoutsend(len, tm, sl) + reconnect() + local str, err, total + pass("%d bytes, %ds total timeout, %ds pause", len, tm, sl) + remote (string.format ([[ + data:settimeout(%d) + str = data:receive(%d) + print('server: sleeping for %ds') + socket.sleep(%d) + print('server: woke up') + str = data:receive(%d) + ]], 2*tm, len, sl, sl, len)) + data:settimeout(tm, "total") + str = string.rep("a", 2*len) + total, err, partial, elapsed = data:send(str) + check_timeout(tm, sl, elapsed, err, "send", "total", + total == 2*len) +end + +------------------------------------------------------------------------ +function test_blockingtimeoutreceive(len, tm, sl) + reconnect() + local str, err, partial + pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl) + remote (string.format ([[ + data:settimeout(%d) + str = string.rep('a', %d) + data:send(str) + print('server: sleeping for %ds') + socket.sleep(%d) + print('server: woke up') + data:send(str) + ]], 2*tm, len, sl, sl)) + data:settimeout(tm) + str, err, partial, elapsed = data:receive(2*len) + check_timeout(tm, sl, elapsed, err, "receive", "blocking", + string.len(str or partial) == 2*len) +end + +------------------------------------------------------------------------ +function test_blockingtimeoutsend(len, tm, sl) + reconnect() + local str, err, total + pass("%d bytes, %ds blocking timeout, %ds pause", len, tm, sl) + remote (string.format ([[ + data:settimeout(%d) + str = data:receive(%d) + print('server: sleeping for %ds') + socket.sleep(%d) + print('server: woke up') + str = data:receive(%d) + ]], 2*tm, len, sl, sl, len)) + data:settimeout(tm) + str = string.rep("a", 2*len) + total, err, partial, elapsed = data:send(str) + check_timeout(tm, sl, elapsed, err, "send", "blocking", + total == 2*len) +end + +------------------------------------------------------------------------ +function empty_connect() + reconnect() + if data then data:close() data = nil end + remote [[ + if data then data:close() data = nil end + data = server:accept() + ]] + data, err = socket.connect("", port) + if not data then + pass("ok") + data = socket.connect(host, port) + else + pass("gethostbyname returns localhost on empty string...") + end +end + +------------------------------------------------------------------------ +function isclosed(c) + return c:getfd() == -1 or c:getfd() == (2^32-1) +end + +function active_close() + reconnect() + if isclosed(data) then fail("should not be closed") end + data:close() + if not isclosed(data) then fail("should be closed") end + data = nil + local udp = socket.udp() + if isclosed(udp) then fail("should not be closed") end + udp:close() + if not isclosed(udp) then fail("should be closed") end + pass("ok") +end + +------------------------------------------------------------------------ +function test_closed() + local back, partial, err + local str = 'little string' + reconnect() + pass("trying read detection") + remote (string.format ([[ + data:send('%s') + data:close() + data = nil + ]], str)) + -- try to get a line + back, err, partial = data:receive() + if not err then fail("should have gotten 'closed'.") + elseif err ~= "closed" then fail("got '"..err.."' instead of 'closed'.") + elseif str ~= partial then fail("didn't receive partial result.") + else pass("graceful 'closed' received") end + reconnect() + pass("trying write detection") + remote [[ + data:close() + data = nil + ]] + total, err, partial = data:send(string.rep("ugauga", 100000)) + if not err then + pass("failed: output buffer is at least %d bytes long!", total) + elseif err ~= "closed" then + fail("got '"..err.."' instead of 'closed'.") + else + pass("graceful 'closed' received after %d bytes were sent", partial) + end +end + +------------------------------------------------------------------------ +function test_selectbugs() + local r, s, e = socket.select(nil, nil, 0.1) + assert(type(r) == "table" and type(s) == "table" and + (e == "timeout" or e == "error")) + pass("both nil: ok") + local udp = socket.udp() + udp:close() + r, s, e = socket.select({ udp }, { udp }, 0.1) + assert(type(r) == "table" and type(s) == "table" and + (e == "timeout" or e == "error")) + pass("closed sockets: ok") + e = pcall(socket.select, "wrong", 1, 0.1) + assert(e == false) + e = pcall(socket.select, {}, 1, 0.1) + assert(e == false) + pass("invalid input: ok") +end + +------------------------------------------------------------------------ +function accept_timeout() + io.stderr:write("accept with timeout (if it hangs, it failed): ") + local s, e = socket.bind("*", 0, 0) + assert(s, e) + local t = socket.gettime() + s:settimeout(1) + local c, e = s:accept() + assert(not c, "should not accept") + assert(e == "timeout", string.format("wrong error message (%s)", e)) + t = socket.gettime() - t + assert(t < 2, string.format("took to long to give up (%gs)", t)) + s:close() + pass("good") +end + +------------------------------------------------------------------------ +function connect_timeout() + io.stderr:write("connect with timeout (if it hangs, it failed!): ") + local t = socket.gettime() + local c, e = socket.tcp() + assert(c, e) + c:settimeout(0.1) + local t = socket.gettime() + local r, e = c:connect("10.0.0.1", 81) +print(r, e) + assert(not r, "should not connect") + assert(socket.gettime() - t < 2, "took too long to give up.") + c:close() + print("ok") +end + +------------------------------------------------------------------------ +function accept_errors() + io.stderr:write("not listening: ") + local d, e = socket.bind("*", 0) + assert(d, e); + local c, e = socket.tcp(); + assert(c, e); + d:setfd(c:getfd()) + d:settimeout(2) + local r, e = d:accept() + assert(not r and e) + print("ok: ", e) + io.stderr:write("not supported: ") + local c, e = socket.udp() + assert(c, e); + d:setfd(c:getfd()) + local r, e = d:accept() + assert(not r and e) + print("ok: ", e) +end + +------------------------------------------------------------------------ +function connect_errors() + io.stderr:write("connection refused: ") + local c, e = socket.connect("localhost", 1); + assert(not c and e) + print("ok: ", e) + io.stderr:write("host not found: ") + local c, e = socket.connect("host.is.invalid", 1); + assert(not c and e, e) + print("ok: ", e) +end + +------------------------------------------------------------------------ +function rebind_test() + local c = socket.bind("localhost", 0) + local i, p = c:getsockname() + local s, e = socket.tcp() + assert(s, e) + s:setoption("reuseaddr", false) + r, e = s:bind("localhost", p) + assert(not r, "managed to rebind!") + assert(e) + print("ok: ", e) +end + +------------------------------------------------------------------------ +function getstats_test() + reconnect() + local t = 0 + for i = 1, 25 do + local c = math.random(1, 100) + remote (string.format ([[ + str = data:receive(%d) + data:send(str) + ]], c)) + data:send(string.rep("a", c)) + data:receive(c) + t = t + c + local r, s, a = data:getstats() + assert(r == t, "received count failed" .. tostring(r) + .. "/" .. tostring(t)) + assert(s == t, "sent count failed" .. tostring(s) + .. "/" .. tostring(t)) + end + print("ok") +end + + +------------------------------------------------------------------------ +function test_nonblocking(size) + reconnect() +print("Testing " .. 2*size .. " bytes") +remote(string.format([[ + data:send(string.rep("a", %d)) + socket.sleep(0.5) + data:send(string.rep("b", %d) .. "\n") +]], size, size)) + local err = "timeout" + local part = "" + local str + data:settimeout(0) + while 1 do + str, err, part = data:receive("*l", part) + if err ~= "timeout" then break end + end + assert(str == (string.rep("a", size) .. string.rep("b", size))) + reconnect() +remote(string.format([[ + str = data:receive(%d) + socket.sleep(0.5) + str = data:receive(2*%d, str) + data:send(str) +]], size, size)) + data:settimeout(0) + local start = 0 + while 1 do + ret, err, start = data:send(str, start+1) + if err ~= "timeout" then break end + end + data:send("\n") + data:settimeout(-1) + local back = data:receive(2*size) + assert(back == str, "'" .. back .. "' vs '" .. str .. "'") + print("ok") +end + +------------------------------------------------------------------------ +function test_readafterclose() + local back, partial, err + local str = 'little string' + reconnect() + pass("trying repeated '*a' pattern") + remote (string.format ([[ + data:send('%s') + data:close() + data = nil + ]], str)) + back, err, partial = data:receive("*a") + assert(back == str, "unexpected data read") + back, err, partial = data:receive("*a") + assert(back == nil and err == "closed", "should have returned 'closed'") + print("ok") + reconnect() + pass("trying active close before '*a'") + remote (string.format ([[ + data:close() + data = nil + ]])) + data:close() + back, err, partial = data:receive("*a") + assert(back == nil and err == "closed", "should have returned 'closed'") + print("ok") + reconnect() + pass("trying active close before '*l'") + remote (string.format ([[ + data:close() + data = nil + ]])) + data:close() + back, err, partial = data:receive() + assert(back == nil and err == "closed", "should have returned 'closed'") + print("ok") + reconnect() + pass("trying active close before raw 1") + remote (string.format ([[ + data:close() + data = nil + ]])) + data:close() + back, err, partial = data:receive(1) + assert(back == nil and err == "closed", "should have returned 'closed'") + print("ok") + reconnect() + pass("trying active close before raw 0") + remote (string.format ([[ + data:close() + data = nil + ]])) + data:close() + back, err, partial = data:receive(0) + assert(back == nil and err == "closed", "should have returned 'closed'") + print("ok") +end + +test("method registration") +test_methods(socket.tcp(), { + "accept", + "bind", + "close", + "connect", + "dirty", + "getfd", + "getpeername", + "getsockname", + "getstats", + "setstats", + "listen", + "receive", + "send", + "setfd", + "setoption", + "setpeername", + "setsockname", + "settimeout", + "shutdown", +}) + +test_methods(socket.udp(), { + "close", + "getpeername", + "dirty", + "getfd", + "getpeername", + "getsockname", + "receive", + "receivefrom", + "send", + "sendto", + "setfd", + "setoption", + "setpeername", + "setsockname", + "settimeout" +}) + +test("testing read after close") +test_readafterclose() + +test("select function") +test_selectbugs() + +test("connect function") +connect_timeout() +empty_connect() +connect_errors() + +test("rebinding: ") +rebind_test() + +test("active close: ") +active_close() + +test("closed connection detection: ") +test_closed() + +test("accept function: ") +accept_timeout() +accept_errors() + +test("getstats test") +getstats_test() + +test("character line") +test_asciiline(1) +test_asciiline(17) +test_asciiline(200) +test_asciiline(4091) +test_asciiline(80199) +test_asciiline(8000000) +test_asciiline(80199) +test_asciiline(4091) +test_asciiline(200) +test_asciiline(17) +test_asciiline(1) + +test("mixed patterns") +test_mixed(1) +test_mixed(17) +test_mixed(200) +test_mixed(4091) +test_mixed(801990) +test_mixed(4091) +test_mixed(200) +test_mixed(17) +test_mixed(1) + +test("binary line") +test_rawline(1) +test_rawline(17) +test_rawline(200) +test_rawline(4091) +test_rawline(80199) +test_rawline(8000000) +test_rawline(80199) +test_rawline(4091) +test_rawline(200) +test_rawline(17) +test_rawline(1) + +test("raw transfer") +test_raw(1) +test_raw(17) +test_raw(200) +test_raw(4091) +test_raw(80199) +test_raw(8000000) +test_raw(80199) +test_raw(4091) +test_raw(200) +test_raw(17) +test_raw(1) + +test("non-blocking transfer") +test_nonblocking(1) +test_nonblocking(17) +test_nonblocking(200) +test_nonblocking(4091) +test_nonblocking(80199) +test_nonblocking(800000) +test_nonblocking(80199) +test_nonblocking(4091) +test_nonblocking(200) +test_nonblocking(17) +test_nonblocking(1) + +test("total timeout on send") +test_totaltimeoutsend(800091, 1, 3) +test_totaltimeoutsend(800091, 2, 3) +test_totaltimeoutsend(800091, 5, 2) +test_totaltimeoutsend(800091, 3, 1) + +test("total timeout on receive") +test_totaltimeoutreceive(800091, 1, 3) +test_totaltimeoutreceive(800091, 2, 3) +test_totaltimeoutreceive(800091, 3, 2) +test_totaltimeoutreceive(800091, 3, 1) + +test("blocking timeout on send") +test_blockingtimeoutsend(800091, 1, 3) +test_blockingtimeoutsend(800091, 2, 3) +test_blockingtimeoutsend(800091, 3, 2) +test_blockingtimeoutsend(800091, 3, 1) + +test("blocking timeout on receive") +test_blockingtimeoutreceive(800091, 1, 3) +test_blockingtimeoutreceive(800091, 2, 3) +test_blockingtimeoutreceive(800091, 3, 2) +test_blockingtimeoutreceive(800091, 3, 1) + +test(string.format("done in %.2fs", socket.gettime() - start)) diff --git a/src/libs/luasocket/test/testsrvr.lua b/src/libs/luasocket/test/testsrvr.lua new file mode 100644 index 000000000..f1972c227 --- /dev/null +++ b/src/libs/luasocket/test/testsrvr.lua @@ -0,0 +1,15 @@ +socket = require("socket"); +host = host or "localhost"; +port = port or "8383"; +server = assert(socket.bind(host, port)); +ack = "\n"; +while 1 do + print("server: waiting for client connection..."); + control = assert(server:accept()); + while 1 do + command = assert(control:receive()); + assert(control:send(ack)); + print(command); + (loadstring(command))(); + end +end diff --git a/src/libs/luasocket/test/testsupport.lua b/src/libs/luasocket/test/testsupport.lua new file mode 100644 index 000000000..acad8f5bc --- /dev/null +++ b/src/libs/luasocket/test/testsupport.lua @@ -0,0 +1,37 @@ +function readfile(name) + local f = io.open(name, "rb") + if not f then return nil end + local s = f:read("*a") + f:close() + return s +end + +function similar(s1, s2) + return string.lower(string.gsub(s1 or "", "%s", "")) == + string.lower(string.gsub(s2 or "", "%s", "")) +end + +function fail(msg) + msg = msg or "failed" + error(msg, 2) +end + +function compare(input, output) + local original = readfile(input) + local recovered = readfile(output) + if original ~= recovered then fail("comparison failed") + else print("ok") end +end + +local G = _G +local set = rawset +local warn = print + +local setglobal = function(table, key, value) + warn("changed " .. key) + set(table, key, value) +end + +setmetatable(G, { + __newindex = setglobal +}) diff --git a/src/texk/web2c/luatexdir/lua/luastuff.c b/src/texk/web2c/luatexdir/lua/luastuff.c index 114c52dfe..30865f9e7 100644 --- a/src/texk/web2c/luatexdir/lua/luastuff.c +++ b/src/texk/web2c/luatexdir/lua/luastuff.c @@ -116,6 +116,32 @@ void luainterpreter(int n) lua_pushstring(L, "zip"); lua_call(L, 1, 0); + /* luasockets */ + /* socket and mime are a bit tricky to open because + * they use a load-time dependency that has to be + * worked around for luatex, where the C module is + * loaded way before the lua module. + */ + lua_getglobal(L, "package"); + lua_getfield(L, -1, "loaded"); + if (!lua_istable(L,-1)) { + lua_newtable(L); + lua_setfield(L, -2, "loaded"); + lua_getfield(L, -1, "loaded"); + } + luaopen_socket_core(L); + lua_setfield(L, -2, "socket.core"); + lua_pushnil(L); + lua_setfield(L, -2, "socket"); /* package.loaded.socket = nil */ + + luaopen_mime_core(L); + lua_setfield(L, -2, "mime.core"); + lua_pushnil(L); + lua_setfield(L, -2, "mime"); /* package.loaded.mime = nil */ + lua_pop(L, 2); /* pop the tables */ + + luatex_socketlua_open(L); /* preload the pure lua modules */ + /*luaopen_lpeg(L); */ lua_pushcfunction(L, luaopen_lpeg); lua_pushstring(L, "lpeg"); diff --git a/src/texk/web2c/luatexdir/luatexlib.mk b/src/texk/web2c/luatexdir/luatexlib.mk index 8d6a65af5..1df603a4b 100644 --- a/src/texk/web2c/luatexdir/luatexlib.mk +++ b/src/texk/web2c/luatexdir/luatexlib.mk @@ -102,6 +102,19 @@ $(LUAFSDEP): $(LUAFSDIR)/src/lfs.c $(LUAFSDIR)/src/lfs.h mkdir -p $(LUAFSDIR) && cd $(LUAFSDIR) && cp -R $(LUAFSSRCDIR)/* . && \ cd src && $(CC) $(CFLAGS) $(LUAFSINC) -g -o lfs.o -c lfs.c + +# luasocket + +LUASOCKETDIR=../../libs/luasocket +LUASOCKETSRCDIR=$(srcdir)/$(LUASOCKETDIR) +LUASOCKETDEP=$(LUASOCKETDIR)/src/socket.a +LUASOCKETINC=-I../../lua51 + +$(LUASOCKETDEP): $(LUASOCKETDIR)/src/luasocket.c $(LUASOCKETDIR)/src/luasocket.h + mkdir -p $(LUASOCKETDIR) && cd $(LUASOCKETDIR) && cp -R $(LUASOCKETSRCDIR)/* . && \ + cd src && make + + # luapeg LUAPEGDIR=../../libs/luapeg LUAPEGSRCDIR=$(srcdir)/$(LUAPEGDIR) @@ -142,11 +155,11 @@ $(LUAZLIBDEP): $(LUAZLIBDIR)/lgzip.c $(LUAZLIBDIR)/lzlib.c # Convenience variables. luatexlibs = $(luapdflib) $(LDLIBPNG) $(LDZLIB) $(LDLIBXPDF) $(LIBMD5DEP) $(LDLIBOBSD) \ - $(LIBLUADEP) $(SLNUNICODEDEP) $(LUAZIPDEP) $(ZZIPLIBDEP) $(LUAFSDEP) \ + $(LIBLUADEP) $(SLNUNICODEDEP) $(LUAZIPDEP) $(ZZIPLIBDEP) $(LUAFSDEP) $(LUASOCKETDEP) \ $(LUAPEGDEP) $(LUAMDVDEP) $(LUAZLIBDEP) $(LUAFFDEP) luatexlibsdep = $(luapdflib) $(LIBPNGDEP) $(ZLIBDEP) $(LIBXPDFDEP) $(LIBMD5DEP) $(LIBOBSDDEP) \ - $(LIBLUADEP) $(SLNUNICODEDEP) $(ZZIPLIBDEP) $(LUAZIPDEP) $(LUAFSDEP) \ + $(LIBLUADEP) $(SLNUNICODEDEP) $(ZZIPLIBDEP) $(LUAZIPDEP) $(LUAFSDEP) $(LUASOCKETDEP) \ $(LUAPEGDEP) $(LUAMDVDEP) $(LUAZLIBDEP) $(LUAFFDEP) $(makecpool) ## end of luatexlib.mk - Makefile fragment for libraries used by pdf[ex]tex. -- GitLab