aboutsummaryrefslogtreecommitdiff
path: root/vendor/luasocket
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2025-03-04 02:19:37 -0300
committerHisham Muhammad <hisham@gobolinux.org>2025-03-10 10:51:04 -0300
commitcc887b9b25571e9ce0afa0cd5e4a4a2cbf130d3a (patch)
tree44b6e247a28934361ff979d32f677832a1d281a8 /vendor/luasocket
parent9e162d9e980f7e17c0ea41e0cd29173d01ada330 (diff)
downloadluarocks-cc887b9b25571e9ce0afa0cd5e4a4a2cbf130d3a.tar.gz
luarocks-cc887b9b25571e9ce0afa0cd5e4a4a2cbf130d3a.tar.bz2
luarocks-cc887b9b25571e9ce0afa0cd5e4a4a2cbf130d3a.zip
[wip] vendor in dependencies
Diffstat (limited to 'vendor/luasocket')
-rw-r--r--vendor/luasocket/.editorconfig23
-rw-r--r--vendor/luasocket/.gitignore15
-rw-r--r--vendor/luasocket/.luacheckrc31
-rw-r--r--vendor/luasocket/CHANGELOG.md65
-rw-r--r--vendor/luasocket/FIX28
-rw-r--r--vendor/luasocket/LICENSE19
-rw-r--r--vendor/luasocket/README.md12
-rw-r--r--vendor/luasocket/TODO81
-rw-r--r--vendor/luasocket/WISH22
-rw-r--r--vendor/luasocket/logo.ps210
-rw-r--r--vendor/luasocket/luasocket-scm-3.rockspec135
-rw-r--r--vendor/luasocket/luasocket.sln35
-rw-r--r--vendor/luasocket/src/auxiliar.c154
-rw-r--r--vendor/luasocket/src/auxiliar.h54
-rw-r--r--vendor/luasocket/src/buffer.c273
-rw-r--r--vendor/luasocket/src/buffer.h52
-rw-r--r--vendor/luasocket/src/compat.c39
-rw-r--r--vendor/luasocket/src/compat.h22
-rw-r--r--vendor/luasocket/src/except.c129
-rw-r--r--vendor/luasocket/src/except.h46
-rw-r--r--vendor/luasocket/src/ftp.lua329
-rw-r--r--vendor/luasocket/src/headers.lua104
-rw-r--r--vendor/luasocket/src/http.lua424
-rwxr-xr-xvendor/luasocket/src/inet.c537
-rw-r--r--vendor/luasocket/src/inet.h56
-rw-r--r--vendor/luasocket/src/io.c28
-rw-r--r--vendor/luasocket/src/io.h70
-rw-r--r--vendor/luasocket/src/ltn12.lua318
-rwxr-xr-xvendor/luasocket/src/luasocket.c104
-rw-r--r--vendor/luasocket/src/luasocket.h36
-rwxr-xr-xvendor/luasocket/src/makefile461
-rw-r--r--vendor/luasocket/src/mbox.lua93
-rwxr-xr-xvendor/luasocket/src/mime.c852
-rw-r--r--vendor/luasocket/src/mime.h22
-rw-r--r--vendor/luasocket/src/mime.lua81
-rw-r--r--vendor/luasocket/src/options.c480
-rw-r--r--vendor/luasocket/src/options.h113
-rw-r--r--vendor/luasocket/src/pierror.h28
-rw-r--r--vendor/luasocket/src/select.c214
-rw-r--r--vendor/luasocket/src/select.h23
-rw-r--r--vendor/luasocket/src/serial.c171
-rw-r--r--vendor/luasocket/src/smtp.lua256
-rwxr-xr-xvendor/luasocket/src/socket.h75
-rw-r--r--vendor/luasocket/src/socket.lua149
-rw-r--r--vendor/luasocket/src/tcp.c480
-rw-r--r--vendor/luasocket/src/tcp.h43
-rw-r--r--vendor/luasocket/src/timeout.c226
-rw-r--r--vendor/luasocket/src/timeout.h40
-rw-r--r--vendor/luasocket/src/tp.lua134
-rwxr-xr-xvendor/luasocket/src/udp.c488
-rw-r--r--vendor/luasocket/src/udp.h39
-rw-r--r--vendor/luasocket/src/unix.c69
-rw-r--r--vendor/luasocket/src/unix.h26
-rw-r--r--vendor/luasocket/src/unixdgram.c405
-rw-r--r--vendor/luasocket/src/unixdgram.h28
-rw-r--r--vendor/luasocket/src/unixstream.c355
-rw-r--r--vendor/luasocket/src/unixstream.h29
-rw-r--r--vendor/luasocket/src/url.lua331
-rw-r--r--vendor/luasocket/src/usocket.c454
-rw-r--r--vendor/luasocket/src/usocket.h59
-rwxr-xr-xvendor/luasocket/src/wsocket.c434
-rw-r--r--vendor/luasocket/src/wsocket.h33
62 files changed, 10142 insertions, 0 deletions
diff --git a/vendor/luasocket/.editorconfig b/vendor/luasocket/.editorconfig
new file mode 100644
index 00000000..56ad87df
--- /dev/null
+++ b/vendor/luasocket/.editorconfig
@@ -0,0 +1,23 @@
1root = true
2
3[*]
4end_of_line = lf
5insert_final_newline = true
6trim_trailing_whitespace = true
7charset = utf-8
8
9[{*.lua,*.rockspec,.luacheckrc}]
10indent_style = space
11indent_size = 4
12
13[Makefile]
14indent_style = tab
15indent_size = 4
16
17[*.html]
18indent_style = space
19indent_size = 4
20
21[*.{c,h}]
22indent_style = space
23indent_size = 4
diff --git a/vendor/luasocket/.gitignore b/vendor/luasocket/.gitignore
new file mode 100644
index 00000000..9ed661cf
--- /dev/null
+++ b/vendor/luasocket/.gitignore
@@ -0,0 +1,15 @@
1*.o
2*.so
3*.so.*
4*.obj
5*.lib
6*.dll*
7*.user
8*.sdf
9Debug
10Release
11*.manifest
12*.swp
13*.suo
14x64
15
diff --git a/vendor/luasocket/.luacheckrc b/vendor/luasocket/.luacheckrc
new file mode 100644
index 00000000..8b25dd7a
--- /dev/null
+++ b/vendor/luasocket/.luacheckrc
@@ -0,0 +1,31 @@
1unused_args = false
2redefined = false
3max_line_length = false
4
5not_globals = {
6 "string.len",
7 "table.getn",
8}
9
10include_files = {
11 "**/*.lua",
12 "**/*.rockspec",
13 ".busted",
14 ".luacheckrc",
15}
16
17exclude_files = {
18 "etc/*.lua",
19 "etc/**/*.lua",
20 "test/*.lua",
21 "test/**/*.lua",
22 "samples/*.lua",
23 "samples/**/*.lua",
24 "gem/*.lua",
25 "gem/**/*.lua",
26 -- GH Actions Lua Environment
27 ".lua",
28 ".luarocks",
29 ".install",
30}
31
diff --git a/vendor/luasocket/CHANGELOG.md b/vendor/luasocket/CHANGELOG.md
new file mode 100644
index 00000000..3a25186b
--- /dev/null
+++ b/vendor/luasocket/CHANGELOG.md
@@ -0,0 +1,65 @@
1# Changelog
2
3## [v3.1.0](https://github.com/lunarmodules/luasocket/releases/v3.1.0) — 2022-07-27
4
5* Add support for TCP Defer Accept – @Zash
6* Add support for TCP Fast Open – @Zash
7* Fix Windows (mingw32) builds – @goldenstein64
8* Avoid build warnings on 64-bit Windows – @rpatters1
9
10## [v3.0.0](https://github.com/lunarmodules/luasocket/releases/v3.0.0) — 2022-03-25
11
12The last time LuaSocket had a stable release tag was 14 years ago when 2.0.2 was tagged.
13A v3 release candidate was tagged 9 years ago.
14Since then it has been downloaded over 3 million times.
15Additionally the Git repository regularly gets several hundred clones a day.
16But 9 years is a long time and even the release candidate has grown a bit long in the tooth.
17Many Linux distros have packaged the current Git HEAD or some specific tested point as dated or otherwise labeled releases.
18256 commits later and having been migrated to the @lunarmodules org namespace on GitHub, please welcome v3.
19
20This release is a "safe-harbor" tag that represents a minimal amount of changes to get a release tagged.
21Beyond some CI tooling, very little code has changed since migration to @lunarmodules ([5b18e47..e47d98f](https://github.com/lunarmodules/luasocket/compare/5b18e47..e47d98f?w=1)):
22
23* Lua 5.4.3+ support – @pkulchenko, @Zash
24* Cleanup minor issues to get a code linter to pass – @Tieske, @jyoui, @alerque
25* Update Visual Studio build rules for Lua 5.1 – @ewestbrook
26* Set http transfer-encoding even without content-length – @tokenrove
27
28Prior to migration to @lunarmodules ([v3.0-rc1..5b18e47](https://github.com/lunarmodules/luasocket/compare/v3.0-rc1..5b18e47?w=1)) many things happened of which the author of this changelog is not fully apprised.
29Your best bet if it affects your project somehow is to read the commit log & diffs yourself.
30
31## [v3.0-rc1](https://github.com/lunarmodules/luasocket/releases/v3.0-rc1) — 2013-06-14
32
33Main changes for LuaSocket 3.0-rc1 are IPv6 support and Lua 5.2 compatibility.
34
35* Added: Compatible with Lua 5.2
36 - Note that unless you define LUA_COMPAT_MODULE, package tables will not be exported as globals!
37* Added: IPv6 support;
38 - Socket.connect and socket.bind support IPv6 addresses;
39 - Getpeername and getsockname support IPv6 addresses, and return the socket family as a third value;
40 - URL module updated to support IPv6 host names;
41 - New socket.tcp6 and socket.udp6 functions;
42 - New socket.dns.getaddrinfo and socket.dns.getnameinfo functions;
43* Added: getoption method;
44* Fixed: url.unescape was returning additional values;
45* Fixed: mime.qp, mime.unqp, mime.b64, and mime.unb64 could mistaking their own stack slots for functions arguments;
46* Fixed: Receiving zero-length datagram is now possible;
47* Improved: Hidden all internal library symbols;
48* Improved: Better error messages;
49* Improved: Better documentation of socket options.
50* Fixed: manual sample of HTTP authentication now uses correct "authorization" header (Alexandre Ittner);
51* Fixed: failure on bind() was destroying the socket (Sam Roberts);
52* Fixed: receive() returns immediatelly if prefix can satisfy bytes requested (M Joonas Pihlaja);
53* Fixed: multicast didn't work on Windows, or anywhere else for that matter (Herbert Leuwer, Adrian Sietsma);
54* Fixed: select() now reports an error when called with more sockets than FD_SETSIZE (Lorenzo Leonini);
55* Fixed: manual links to home.html changed to index.html (Robert Hahn);
56* Fixed: mime.unb64() would return an empty string on results that started with a null character (Robert Raschke);
57* Fixed: HTTP now automatically redirects on 303 and 307 (Jonathan Gray);
58* Fixed: calling sleep() with negative numbers could block forever, wasting CPU. Now it returns immediately (MPB);
59* Improved: FTP commands are now sent in upper case to help buggy servers (Anders Eurenius);
60* Improved: known headers now sent in canonic capitalization to help buggy servers (Joseph Stewart);
61* Improved: Clarified tcp:receive() in the manual (MPB);
62* Improved: Decent makefiles (LHF).
63* Fixed: RFC links in documentation now point to IETF (Cosmin Apreutesei).
64
65## [v2.0.2](https://github.com/lunarmodules/luasocket/releases/v2.0.2) — 2007-09-11
diff --git a/vendor/luasocket/FIX b/vendor/luasocket/FIX
new file mode 100644
index 00000000..40f30a15
--- /dev/null
+++ b/vendor/luasocket/FIX
@@ -0,0 +1,28 @@
1
2
3
4
5
6
7http was preserving old host header during redirects
8fix smtp.send hang on source error
9add create field to FTP and SMTP and fix HTTP ugliness
10clean timeout argument to open functions in SMTP, HTTP and FTP
11eliminate globals from namespaces created by module().
12url.absolute was not working when base_url was already parsed
13http.request was redirecting even when the location header was empty
14tcp{client}:shutdown() was checking for group instead of class.
15tcp{client}:send() now returns i+sent-1...
16get rid of a = socket.try() in the manual, except for protected cases. replace it with assert.
17get rid of "base." kludge in package.loaded
18check all "require("http")" etc in the manual.
19make sure sock_gethostname.* only return success if the hp is not null!
20change 'l' prefix in C libraries to 'c' to avoid clash with LHF libraries
21 don't forget the declarations in luasocket.h and mime.h!!!
22setpeername was using udp{unconnected}
23fixed a bug in http.lua that caused some requests to fail (Florian Berger)
24fixed a bug in select.c that prevented sockets with descriptor 0 from working (Renato Maia)
25fixed a "bug" that caused dns.toip to crash under uLinux
26fixed a "bug" that caused a crash in gethostbyname under VMS
27DEBUG and VERSION became _DEBUG and _VERSION
28send returns the right value if input is "". Alexander Marinov
diff --git a/vendor/luasocket/LICENSE b/vendor/luasocket/LICENSE
new file mode 100644
index 00000000..a8ed03ea
--- /dev/null
+++ b/vendor/luasocket/LICENSE
@@ -0,0 +1,19 @@
1Copyright (C) 2004-2022 Diego Nehab
2
3Permission is hereby granted, free of charge, to any person obtaining a
4copy of this software and associated documentation files (the "Software"),
5to deal in the Software without restriction, including without limitation
6the rights to use, copy, modify, merge, publish, distribute, sublicense,
7and/or sell copies of the Software, and to permit persons to whom the
8Software is furnished to do so, subject to the following conditions:
9
10The above copyright notice and this permission notice shall be included in
11all copies or substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19DEALINGS IN THE SOFTWARE.
diff --git a/vendor/luasocket/README.md b/vendor/luasocket/README.md
new file mode 100644
index 00000000..af722be6
--- /dev/null
+++ b/vendor/luasocket/README.md
@@ -0,0 +1,12 @@
1# LuaSocket
2
3
4[![Build](https://img.shields.io/github/workflow/status/lunarmodules/luasocket/Build?label=Build=Lua)](https://github.com/lunarmodules/luasocket/actions?workflow=Build)
5[![Luacheck](https://img.shields.io/github/workflow/status/lunarmodules/luasocket/Luacheck?label=Luacheck&logo=Lua)](https://github.com/lunarmodules/luasocket/actions?workflow=Luacheck)
6[![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/lunarmodules/luasocket?label=Tag&logo=GitHub)](https://github.com/lunarmodules/luasocket/releases)
7[![Luarocks](https://img.shields.io/luarocks/v/lunarmodules/luasocket?label=Luarocks&logo=Lua)](https://luarocks.org/modules/lunarmodules/luasocket)
8
9LuaSocket is a Lua extension library composed of two parts:
10
111. a set of C modules that provide support for the TCP and UDP transport layers, and
122. a set of Lua modules that provide functions commonly needed by applications that deal with the Internet.
diff --git a/vendor/luasocket/TODO b/vendor/luasocket/TODO
new file mode 100644
index 00000000..a838fc02
--- /dev/null
+++ b/vendor/luasocket/TODO
@@ -0,0 +1,81 @@
1- bizarre default values for getnameinfo should throw error instead!
2
3> It's just too bad it can't talk to gmail -
4> reason 1: they absolutely want TLS
5> reason 2: unlike all the other SMTP implementations, they
6> don't
7> tolerate missing < > around adresses
8
9- document the new bind and connect behavior.
10- shouldn't we instead make the code compatible to Lua 5.2
11 without any compat stuff, and use a compatibility layer to
12 make it work on 5.1?
13- add what's new to manual
14- should there be an equivalent to tohostname for IPv6?
15- should we add service name resolution as well to getaddrinfo?
16- Maybe the sockaddr to presentation conversion should be done with getnameinfo()?
17
18- add http POST sample to manual
19 people keep asking stupid questions
20- documentation of dirty/getfd/setfd is problematic because of portability
21 same for unix and serial.
22 what to do about this? add a stronger disclaimer?
23- fix makefile with decent defaults?
24
25Done:
26
27- added IPv6 support to getsockname
28- simplified getpeername implementation
29- added family to return of getsockname and getpeername
30 and added modification to the manual to describe
31
32- connect and bind try all adresses returned by getaddrinfo
33- document headers.lua?
34- update copyright date everywhere?
35- remove RCSID from files?
36- move version to 2.1 rather than 2.1.1?
37- fixed url package to support ipv6 hosts
38- changed domain to family
39- implement getfamily methods.
40
41- remove references to Lua 5.0 from documentation, add 5.2?
42- update lua and luasocket version in samples in documentation
43- document ipv5_v6only default option being set?
44- document tcp6 and udp6
45- document dns.getaddrinfo
46- documented zero-sized datagram change?
47 no.
48- document unix socket and serial socket? add raw support?
49 no.
50- document getoption
51- merge luaL_typeerror into auxiliar to avoid using luaL prefix?
52
53
54
55
56
57
58
59
60
61
62replace \r\n with \0xD\0xA in everything
63New mime support
64
65ftp send should return server replies?
66make sure there are no object files in the distribution tarball
67http handling of 100-continue, see DB patch
68DB ftp.lua bug.
69test unix.c to return just a function and works with require"unix"
70get rid of setmetatable(, nil) since packages don't need this anymore in 5.1
71compat-5.1 novo
72ajeitar pra lua-5.1
73
74adicionar exemplos de expansão: pipe, local, named pipe
75testar os options!
76
77
78- Thread-unsafe functions to protect
79 gethostbyname(), gethostbyaddr(), gethostent(),
80inet_ntoa(), strerror(),
81
diff --git a/vendor/luasocket/WISH b/vendor/luasocket/WISH
new file mode 100644
index 00000000..e7e9c076
--- /dev/null
+++ b/vendor/luasocket/WISH
@@ -0,0 +1,22 @@
1... as an l-value to get all results of a function call?
2at least ...[i] and #...
3extend to full tuples?
4
5__and __or __not metamethods
6
7lua_tostring, lua_tonumber, lua_touseradta etc push values in stack
8__tostring,__tonumber, __touserdata metamethods are checked
9and expected to push an object of correct type on stack
10
11lua_rawtostring, lua_rawtonumber, lua_rawtouserdata don't
12push anything on stack, return data of appropriate type,
13skip metamethods and throw error if object not of exact type
14
15package.findfile exported
16module not polluting the global namespace
17
18coxpcall with a coroutine pool for efficiency (reusing coroutines)
19
20exception mechanism formalized? just like the package system was.
21
22a nice bitlib in the core
diff --git a/vendor/luasocket/logo.ps b/vendor/luasocket/logo.ps
new file mode 100644
index 00000000..8b5809ab
--- /dev/null
+++ b/vendor/luasocket/logo.ps
@@ -0,0 +1,210 @@
1%!PS-Adobe-2.0 EPSF-2.0
2%%Title: Lua logo
3%%Creator: lua@tecgraf.puc-rio.br
4%%CreationDate: Wed Nov 29 19:04:04 EDT 2000
5%%BoundingBox: -45 0 1035 1080
6%%Pages: 1
7%%EndComments
8%%EndProlog
9
10%------------------------------------------------------------------------------
11%
12% Copyright (C) 1998-2000. All rights reserved.
13% Graphic design by Alexandre Nakonechny (nako@openlink.com.br).
14% PostScript programming by the Lua team (lua@tecgraf.puc-rio.br).
15%
16% Permission is hereby granted, without written agreement and without license
17% or royalty fees, to use, copy, and distribute this logo for any purpose,
18% including commercial applications, subject to the following conditions:
19%
20% * The origin of this logo must not be misrepresented; you must not
21% claim that you drew the original logo. We recommend that you give credit
22% to the graphics designer in all printed matter that includes the logo.
23%
24% * The only modification you can make is to adapt the orbiting text to
25% your product name.
26%
27% * The logo can be used in any scale as long as the relative proportions
28% of its elements are maintained.
29%
30%------------------------------------------------------------------------------
31
32/LABEL (tekcoS) def
33
34%-- DO NOT CHANGE ANYTHING BELOW THIS LINE ------------------------------------
35
36/PLANETCOLOR {0 0 0.5 setrgbcolor} bind def
37/HOLECOLOR {1.0 setgray} bind def
38/ORBITCOLOR {0.5 setgray} bind def
39/LOGOFONT {/Helvetica 0.90} def
40/LABELFONT {/Helvetica 0.36} def
41
42%------------------------------------------------------------------------------
43
44/MOONCOLOR {PLANETCOLOR} bind def
45/LOGOCOLOR {HOLECOLOR} bind def
46/LABELCOLOR {ORBITCOLOR} bind def
47
48/LABELANGLE 325 def
49/LOGO (Lua) def
50
51/DASHANGLE 10 def
52/HALFDASHANGLE DASHANGLE 2 div def
53
54% moon radius. planet radius is 1.
55/r 1 2 sqrt 2 div sub def
56
57/D {0 360 arc fill} bind def
58/F {exch findfont exch scalefont setfont} bind def
59
60% place it nicely on the paper
61/RESOLUTION 1024 def
62RESOLUTION 2 div dup translate
63RESOLUTION 2 div 2 sqrt div dup scale
64
65%-------------------------------------------------------------------- planet --
66PLANETCOLOR
670 0 1 D
68
69%---------------------------------------------------------------------- hole --
70HOLECOLOR
711 2 r mul sub dup r D
72
73%---------------------------------------------------------------------- moon --
74MOONCOLOR
751 1 r D
76
77%---------------------------------------------------------------------- logo --
78LOGOCOLOR
79LOGOFONT
80F
81LOGO stringwidth pop 2 div neg
82-0.5 moveto
83LOGO show
84
85%------------------------------------------------------------------------------
86% based on code from Blue Book Program 10, on pages 167--169
87% available at ftp://ftp.adobe.com/pub/adobe/displaypostscript/bluebook.shar
88
89% str ptsize centerangle radius outsidecircletext --
90/outsidecircletext {
91 circtextdict begin
92 /radius exch def
93 /centerangle exch def
94 /ptsize exch def
95 /str exch def
96
97 gsave
98 str radius ptsize findhalfangle
99 centerangle
100 add rotate
101 str
102 { /charcode exch def
103 ( ) dup 0 charcode put outsideplacechar
104 } forall
105
106 grestore
107 end
108} def
109
110% string radius ptsize findhalfangle halfangle
111/findhalfangle {
112 4 div add
113 exch
114 stringwidth pop 2 div
115 exch
116 2 mul 3.1415926535 mul div 360 mul
117} def
118
119/circtextdict 16 dict def
120circtextdict begin
121
122 /outsideplacechar {
123 /char exch def
124 /halfangle char radius ptsize findhalfangle def
125 gsave
126 halfangle neg rotate
127 1.4 0 translate
128 90 rotate
129 char stringwidth pop 2 div neg 0 moveto
130 char show
131 grestore
132 halfangle 2 mul neg rotate
133 } def
134
135end
136
137%--------------------------------------------------------------------- label --
138LABELFONT
139F
140
141/LABELSIZE LABELFONT exch pop def
142/LABELRADIUS LABELSIZE 3 div 1 r add sub neg 1.02 mul def
143
144
145/HALFANGLE
146 LABEL LABELRADIUS LABELSIZE findhalfangle
147 HALFDASHANGLE div ceiling HALFDASHANGLE mul
148def
149
150/LABELANGLE
151 60 LABELANGLE HALFANGLE sub
152 lt
153 {
154 HALFANGLE
155 HALFANGLE DASHANGLE div floor DASHANGLE mul
156 eq
157 {LABELANGLE DASHANGLE div ceiling DASHANGLE mul}
158 {LABELANGLE HALFDASHANGLE sub DASHANGLE div round DASHANGLE mul HALFDASHANGLE add}
159 ifelse
160 }
161 {HALFANGLE 60 add}
162 ifelse
163def
164
165LABELCOLOR
166LABEL
167LABELSIZE
168LABELANGLE
169LABELRADIUS
170outsidecircletext
171
172%--------------------------------------------------------------------- orbit --
173ORBITCOLOR
1740.03 setlinewidth
175[1 r add 3.1415926535 180 div HALFDASHANGLE mul mul] 0 setdash
176newpath
1770 0
1781 r add
1793 copy
18030
181LABELANGLE HALFANGLE add
182arcn
183stroke
18460
185LABELANGLE HALFANGLE sub
1862 copy
187lt {arc stroke} {4 {pop} repeat} ifelse
188
189%------------------------------------------------------------------ copyright --
190/COPYRIGHT
191(Graphic design by A. Nakonechny. Copyright (c) 1998, All rights reserved.)
192def
193
194LABELCOLOR
195LOGOFONT
19632 div
197F
1982 sqrt 0.99 mul
199dup
200neg
201moveto
202COPYRIGHT
20390 rotate
204%show
205
206%---------------------------------------------------------------------- done --
207showpage
208
209%%Trailer
210%%EOF
diff --git a/vendor/luasocket/luasocket-scm-3.rockspec b/vendor/luasocket/luasocket-scm-3.rockspec
new file mode 100644
index 00000000..10452510
--- /dev/null
+++ b/vendor/luasocket/luasocket-scm-3.rockspec
@@ -0,0 +1,135 @@
1package = "LuaSocket"
2version = "scm-3"
3source = {
4 url = "git+https://github.com/lunarmodules/luasocket.git",
5 branch = "master"
6}
7description = {
8 summary = "Network support for the Lua language",
9 detailed = [[
10 LuaSocket is a Lua extension library composed of two parts: a set of C
11 modules that provide support for the TCP and UDP transport layers, and a
12 set of Lua modules that provide functions commonly needed by applications
13 that deal with the Internet.
14 ]],
15 homepage = "https://github.com/lunarmodules/luasocket",
16 license = "MIT"
17}
18dependencies = {
19 "lua >= 5.1"
20}
21
22local function make_plat(plat)
23 local defines = {
24 unix = {
25 "LUASOCKET_DEBUG"
26 },
27 macosx = {
28 "LUASOCKET_DEBUG",
29 "UNIX_HAS_SUN_LEN"
30 },
31 win32 = {
32 "LUASOCKET_DEBUG",
33 "NDEBUG"
34 },
35 mingw32 = {
36 "LUASOCKET_DEBUG",
37 -- "LUASOCKET_INET_PTON",
38 "WINVER=0x0501"
39 }
40 }
41 local modules = {
42 ["socket.core"] = {
43 sources = {
44 "src/luasocket.c"
45 , "src/timeout.c"
46 , "src/buffer.c"
47 , "src/io.c"
48 , "src/auxiliar.c"
49 , "src/options.c"
50 , "src/inet.c"
51 , "src/except.c"
52 , "src/select.c"
53 , "src/tcp.c"
54 , "src/udp.c"
55 , "src/compat.c" },
56 defines = defines[plat],
57 incdir = "/src"
58 },
59 ["mime.core"] = {
60 sources = { "src/mime.c", "src/compat.c" },
61 defines = defines[plat],
62 incdir = "/src"
63 },
64 ["socket.http"] = "src/http.lua",
65 ["socket.url"] = "src/url.lua",
66 ["socket.tp"] = "src/tp.lua",
67 ["socket.ftp"] = "src/ftp.lua",
68 ["socket.headers"] = "src/headers.lua",
69 ["socket.smtp"] = "src/smtp.lua",
70 ltn12 = "src/ltn12.lua",
71 socket = "src/socket.lua",
72 mime = "src/mime.lua"
73 }
74 if plat == "unix"
75 or plat == "macosx"
76 or plat == "haiku"
77 then
78 modules["socket.core"].sources[#modules["socket.core"].sources+1] = "src/usocket.c"
79 if plat == "haiku" then
80 modules["socket.core"].libraries = {"network"}
81 end
82 modules["socket.unix"] = {
83 sources = {
84 "src/buffer.c"
85 , "src/compat.c"
86 , "src/auxiliar.c"
87 , "src/options.c"
88 , "src/timeout.c"
89 , "src/io.c"
90 , "src/usocket.c"
91 , "src/unix.c"
92 , "src/unixdgram.c"
93 , "src/unixstream.c" },
94 defines = defines[plat],
95 incdir = "/src"
96 }
97 modules["socket.serial"] = {
98 sources = {
99 "src/buffer.c"
100 , "src/compat.c"
101 , "src/auxiliar.c"
102 , "src/options.c"
103 , "src/timeout.c"
104 , "src/io.c"
105 , "src/usocket.c"
106 , "src/serial.c" },
107 defines = defines[plat],
108 incdir = "/src"
109 }
110 end
111 if plat == "win32"
112 or plat == "mingw32"
113 then
114 modules["socket.core"].sources[#modules["socket.core"].sources+1] = "src/wsocket.c"
115 modules["socket.core"].libraries = { "ws2_32" }
116 modules["socket.core"].libdirs = {}
117 end
118 return { modules = modules }
119end
120
121build = {
122 type = "builtin",
123 platforms = {
124 unix = make_plat("unix"),
125 macosx = make_plat("macosx"),
126 haiku = make_plat("haiku"),
127 win32 = make_plat("win32"),
128 mingw32 = make_plat("mingw32")
129 },
130 copy_directories = {
131 "docs"
132 , "samples"
133 , "etc"
134 , "test" }
135}
diff --git a/vendor/luasocket/luasocket.sln b/vendor/luasocket/luasocket.sln
new file mode 100644
index 00000000..0e5cdc73
--- /dev/null
+++ b/vendor/luasocket/luasocket.sln
@@ -0,0 +1,35 @@
1Microsoft Visual Studio Solution File, Format Version 12.00
2# Visual Studio 2012
3Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "socket", "socket.vcxproj", "{66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}"
4EndProject
5Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mime", "mime.vcxproj", "{128E8BD0-174A-48F0-8771-92B1E8D18713}"
6EndProject
7Global
8 GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 Debug|Win32 = Debug|Win32
10 Debug|x64 = Debug|x64
11 Release|Win32 = Release|Win32
12 Release|x64 = Release|x64
13 EndGlobalSection
14 GlobalSection(ProjectConfigurationPlatforms) = postSolution
15 {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Debug|Win32.ActiveCfg = Debug|Win32
16 {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Debug|Win32.Build.0 = Debug|Win32
17 {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Debug|x64.ActiveCfg = Debug|x64
18 {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Debug|x64.Build.0 = Debug|x64
19 {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Release|Win32.ActiveCfg = Release|Win32
20 {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Release|Win32.Build.0 = Release|Win32
21 {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Release|x64.ActiveCfg = Release|x64
22 {66E3CE14-884D-4AEA-9F20-15A0BEAF8C5A}.Release|x64.Build.0 = Release|x64
23 {128E8BD0-174A-48F0-8771-92B1E8D18713}.Debug|Win32.ActiveCfg = Debug|Win32
24 {128E8BD0-174A-48F0-8771-92B1E8D18713}.Debug|Win32.Build.0 = Debug|Win32
25 {128E8BD0-174A-48F0-8771-92B1E8D18713}.Debug|x64.ActiveCfg = Debug|x64
26 {128E8BD0-174A-48F0-8771-92B1E8D18713}.Debug|x64.Build.0 = Debug|x64
27 {128E8BD0-174A-48F0-8771-92B1E8D18713}.Release|Win32.ActiveCfg = Release|Win32
28 {128E8BD0-174A-48F0-8771-92B1E8D18713}.Release|Win32.Build.0 = Release|Win32
29 {128E8BD0-174A-48F0-8771-92B1E8D18713}.Release|x64.ActiveCfg = Release|x64
30 {128E8BD0-174A-48F0-8771-92B1E8D18713}.Release|x64.Build.0 = Release|x64
31 EndGlobalSection
32 GlobalSection(SolutionProperties) = preSolution
33 HideSolutionNode = FALSE
34 EndGlobalSection
35EndGlobal
diff --git a/vendor/luasocket/src/auxiliar.c b/vendor/luasocket/src/auxiliar.c
new file mode 100644
index 00000000..93a66a09
--- /dev/null
+++ b/vendor/luasocket/src/auxiliar.c
@@ -0,0 +1,154 @@
1/*=========================================================================*\
2* Auxiliar routines for class hierarchy manipulation
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6#include "auxiliar.h"
7#include <string.h>
8#include <stdio.h>
9
10/*-------------------------------------------------------------------------*\
11* Initializes the module
12\*-------------------------------------------------------------------------*/
13int auxiliar_open(lua_State *L) {
14 (void) L;
15 return 0;
16}
17
18/*-------------------------------------------------------------------------*\
19* Creates a new class with given methods
20* Methods whose names start with __ are passed directly to the metatable.
21\*-------------------------------------------------------------------------*/
22void auxiliar_newclass(lua_State *L, const char *classname, luaL_Reg *func) {
23 luaL_newmetatable(L, classname); /* mt */
24 /* create __index table to place methods */
25 lua_pushstring(L, "__index"); /* mt,"__index" */
26 lua_newtable(L); /* mt,"__index",it */
27 /* put class name into class metatable */
28 lua_pushstring(L, "class"); /* mt,"__index",it,"class" */
29 lua_pushstring(L, classname); /* mt,"__index",it,"class",classname */
30 lua_rawset(L, -3); /* mt,"__index",it */
31 /* pass all methods that start with _ to the metatable, and all others
32 * to the index table */
33 for (; func->name; func++) { /* mt,"__index",it */
34 lua_pushstring(L, func->name);
35 lua_pushcfunction(L, func->func);
36 lua_rawset(L, func->name[0] == '_' ? -5: -3);
37 }
38 lua_rawset(L, -3); /* mt */
39 lua_pop(L, 1);
40}
41
42/*-------------------------------------------------------------------------*\
43* Prints the value of a class in a nice way
44\*-------------------------------------------------------------------------*/
45int auxiliar_tostring(lua_State *L) {
46 char buf[32];
47 if (!lua_getmetatable(L, 1)) goto error;
48 lua_pushstring(L, "__index");
49 lua_gettable(L, -2);
50 if (!lua_istable(L, -1)) goto error;
51 lua_pushstring(L, "class");
52 lua_gettable(L, -2);
53 if (!lua_isstring(L, -1)) goto error;
54 sprintf(buf, "%p", lua_touserdata(L, 1));
55 lua_pushfstring(L, "%s: %s", lua_tostring(L, -1), buf);
56 return 1;
57error:
58 lua_pushstring(L, "invalid object passed to 'auxiliar.c:__tostring'");
59 lua_error(L);
60 return 1;
61}
62
63/*-------------------------------------------------------------------------*\
64* Insert class into group
65\*-------------------------------------------------------------------------*/
66void auxiliar_add2group(lua_State *L, const char *classname, const char *groupname) {
67 luaL_getmetatable(L, classname);
68 lua_pushstring(L, groupname);
69 lua_pushboolean(L, 1);
70 lua_rawset(L, -3);
71 lua_pop(L, 1);
72}
73
74/*-------------------------------------------------------------------------*\
75* Make sure argument is a boolean
76\*-------------------------------------------------------------------------*/
77int auxiliar_checkboolean(lua_State *L, int objidx) {
78 if (!lua_isboolean(L, objidx))
79 auxiliar_typeerror(L, objidx, lua_typename(L, LUA_TBOOLEAN));
80 return lua_toboolean(L, objidx);
81}
82
83/*-------------------------------------------------------------------------*\
84* Return userdata pointer if object belongs to a given class, abort with
85* error otherwise
86\*-------------------------------------------------------------------------*/
87void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx) {
88 void *data = auxiliar_getclassudata(L, classname, objidx);
89 if (!data) {
90 char msg[45];
91 sprintf(msg, "%.35s expected", classname);
92 luaL_argerror(L, objidx, msg);
93 }
94 return data;
95}
96
97/*-------------------------------------------------------------------------*\
98* Return userdata pointer if object belongs to a given group, abort with
99* error otherwise
100\*-------------------------------------------------------------------------*/
101void *auxiliar_checkgroup(lua_State *L, const char *groupname, int objidx) {
102 void *data = auxiliar_getgroupudata(L, groupname, objidx);
103 if (!data) {
104 char msg[45];
105 sprintf(msg, "%.35s expected", groupname);
106 luaL_argerror(L, objidx, msg);
107 }
108 return data;
109}
110
111/*-------------------------------------------------------------------------*\
112* Set object class
113\*-------------------------------------------------------------------------*/
114void auxiliar_setclass(lua_State *L, const char *classname, int objidx) {
115 luaL_getmetatable(L, classname);
116 if (objidx < 0) objidx--;
117 lua_setmetatable(L, objidx);
118}
119
120/*-------------------------------------------------------------------------*\
121* Get a userdata pointer if object belongs to a given group. Return NULL
122* otherwise
123\*-------------------------------------------------------------------------*/
124void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx) {
125 if (!lua_getmetatable(L, objidx))
126 return NULL;
127 lua_pushstring(L, groupname);
128 lua_rawget(L, -2);
129 if (lua_isnil(L, -1)) {
130 lua_pop(L, 2);
131 return NULL;
132 } else {
133 lua_pop(L, 2);
134 return lua_touserdata(L, objidx);
135 }
136}
137
138/*-------------------------------------------------------------------------*\
139* Get a userdata pointer if object belongs to a given class. Return NULL
140* otherwise
141\*-------------------------------------------------------------------------*/
142void *auxiliar_getclassudata(lua_State *L, const char *classname, int objidx) {
143 return luaL_testudata(L, objidx, classname);
144}
145
146/*-------------------------------------------------------------------------*\
147* Throws error when argument does not have correct type.
148* Used to be part of lauxlib in Lua 5.1, was dropped from 5.2.
149\*-------------------------------------------------------------------------*/
150int auxiliar_typeerror (lua_State *L, int narg, const char *tname) {
151 const char *msg = lua_pushfstring(L, "%s expected, got %s", tname,
152 luaL_typename(L, narg));
153 return luaL_argerror(L, narg, msg);
154}
diff --git a/vendor/luasocket/src/auxiliar.h b/vendor/luasocket/src/auxiliar.h
new file mode 100644
index 00000000..e8c3ead8
--- /dev/null
+++ b/vendor/luasocket/src/auxiliar.h
@@ -0,0 +1,54 @@
1#ifndef AUXILIAR_H
2#define AUXILIAR_H
3/*=========================================================================*\
4* Auxiliar routines for class hierarchy manipulation
5* LuaSocket toolkit (but completely independent of other LuaSocket modules)
6*
7* A LuaSocket class is a name associated with Lua metatables. A LuaSocket
8* group is a name associated with a class. A class can belong to any number
9* of groups. This module provides the functionality to:
10*
11* - create new classes
12* - add classes to groups
13* - set the class of objects
14* - check if an object belongs to a given class or group
15* - get the userdata associated to objects
16* - print objects in a pretty way
17*
18* LuaSocket class names follow the convention <module>{<class>}. Modules
19* can define any number of classes and groups. The module tcp.c, for
20* example, defines the classes tcp{master}, tcp{client} and tcp{server} and
21* the groups tcp{client,server} and tcp{any}. Module functions can then
22* perform type-checking on their arguments by either class or group.
23*
24* LuaSocket metatables define the __index metamethod as being a table. This
25* table has one field for each method supported by the class, and a field
26* "class" with the class name.
27*
28* The mapping from class name to the corresponding metatable and the
29* reverse mapping are done using lauxlib.
30\*=========================================================================*/
31
32#include "luasocket.h"
33
34#ifndef _WIN32
35#pragma GCC visibility push(hidden)
36#endif
37
38int auxiliar_open(lua_State *L);
39void auxiliar_newclass(lua_State *L, const char *classname, luaL_Reg *func);
40int auxiliar_tostring(lua_State *L);
41void auxiliar_add2group(lua_State *L, const char *classname, const char *group);
42int auxiliar_checkboolean(lua_State *L, int objidx);
43void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx);
44void *auxiliar_checkgroup(lua_State *L, const char *groupname, int objidx);
45void auxiliar_setclass(lua_State *L, const char *classname, int objidx);
46void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx);
47void *auxiliar_getclassudata(lua_State *L, const char *groupname, int objidx);
48int auxiliar_typeerror(lua_State *L, int narg, const char *tname);
49
50#ifndef _WIN32
51#pragma GCC visibility pop
52#endif
53
54#endif /* AUXILIAR_H */
diff --git a/vendor/luasocket/src/buffer.c b/vendor/luasocket/src/buffer.c
new file mode 100644
index 00000000..7148be34
--- /dev/null
+++ b/vendor/luasocket/src/buffer.c
@@ -0,0 +1,273 @@
1/*=========================================================================*\
2* Input/Output interface for Lua programs
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6#include "buffer.h"
7
8/*=========================================================================*\
9* Internal function prototypes
10\*=========================================================================*/
11static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b);
12static int recvline(p_buffer buf, luaL_Buffer *b);
13static int recvall(p_buffer buf, luaL_Buffer *b);
14static int buffer_get(p_buffer buf, const char **data, size_t *count);
15static void buffer_skip(p_buffer buf, size_t count);
16static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent);
17
18/* min and max macros */
19#ifndef MIN
20#define MIN(x, y) ((x) < (y) ? x : y)
21#endif
22#ifndef MAX
23#define MAX(x, y) ((x) > (y) ? x : y)
24#endif
25
26/*=========================================================================*\
27* Exported functions
28\*=========================================================================*/
29/*-------------------------------------------------------------------------*\
30* Initializes module
31\*-------------------------------------------------------------------------*/
32int buffer_open(lua_State *L) {
33 (void) L;
34 return 0;
35}
36
37/*-------------------------------------------------------------------------*\
38* Initializes C structure
39\*-------------------------------------------------------------------------*/
40void buffer_init(p_buffer buf, p_io io, p_timeout tm) {
41 buf->first = buf->last = 0;
42 buf->io = io;
43 buf->tm = tm;
44 buf->received = buf->sent = 0;
45 buf->birthday = timeout_gettime();
46}
47
48/*-------------------------------------------------------------------------*\
49* object:getstats() interface
50\*-------------------------------------------------------------------------*/
51int buffer_meth_getstats(lua_State *L, p_buffer buf) {
52 lua_pushnumber(L, (lua_Number) buf->received);
53 lua_pushnumber(L, (lua_Number) buf->sent);
54 lua_pushnumber(L, timeout_gettime() - buf->birthday);
55 return 3;
56}
57
58/*-------------------------------------------------------------------------*\
59* object:setstats() interface
60\*-------------------------------------------------------------------------*/
61int buffer_meth_setstats(lua_State *L, p_buffer buf) {
62 buf->received = (long) luaL_optnumber(L, 2, (lua_Number) buf->received);
63 buf->sent = (long) luaL_optnumber(L, 3, (lua_Number) buf->sent);
64 if (lua_isnumber(L, 4)) buf->birthday = timeout_gettime() - lua_tonumber(L, 4);
65 lua_pushnumber(L, 1);
66 return 1;
67}
68
69/*-------------------------------------------------------------------------*\
70* object:send() interface
71\*-------------------------------------------------------------------------*/
72int buffer_meth_send(lua_State *L, p_buffer buf) {
73 int top = lua_gettop(L);
74 int err = IO_DONE;
75 size_t size = 0, sent = 0;
76 const char *data = luaL_checklstring(L, 2, &size);
77 long start = (long) luaL_optnumber(L, 3, 1);
78 long end = (long) luaL_optnumber(L, 4, -1);
79 timeout_markstart(buf->tm);
80 if (start < 0) start = (long) (size+start+1);
81 if (end < 0) end = (long) (size+end+1);
82 if (start < 1) start = (long) 1;
83 if (end > (long) size) end = (long) size;
84 if (start <= end) err = sendraw(buf, data+start-1, end-start+1, &sent);
85 /* check if there was an error */
86 if (err != IO_DONE) {
87 lua_pushnil(L);
88 lua_pushstring(L, buf->io->error(buf->io->ctx, err));
89 lua_pushnumber(L, (lua_Number) (sent+start-1));
90 } else {
91 lua_pushnumber(L, (lua_Number) (sent+start-1));
92 lua_pushnil(L);
93 lua_pushnil(L);
94 }
95#ifdef LUASOCKET_DEBUG
96 /* push time elapsed during operation as the last return value */
97 lua_pushnumber(L, timeout_gettime() - timeout_getstart(buf->tm));
98#endif
99 return lua_gettop(L) - top;
100}
101
102/*-------------------------------------------------------------------------*\
103* object:receive() interface
104\*-------------------------------------------------------------------------*/
105int buffer_meth_receive(lua_State *L, p_buffer buf) {
106 int err = IO_DONE, top;
107 luaL_Buffer b;
108 size_t size;
109 const char *part = luaL_optlstring(L, 3, "", &size);
110 timeout_markstart(buf->tm);
111 /* make sure we don't confuse buffer stuff with arguments */
112 lua_settop(L, 3);
113 top = lua_gettop(L);
114 /* initialize buffer with optional extra prefix
115 * (useful for concatenating previous partial results) */
116 luaL_buffinit(L, &b);
117 luaL_addlstring(&b, part, size);
118 /* receive new patterns */
119 if (!lua_isnumber(L, 2)) {
120 const char *p= luaL_optstring(L, 2, "*l");
121 if (p[0] == '*' && p[1] == 'l') err = recvline(buf, &b);
122 else if (p[0] == '*' && p[1] == 'a') err = recvall(buf, &b);
123 else luaL_argcheck(L, 0, 2, "invalid receive pattern");
124 /* get a fixed number of bytes (minus what was already partially
125 * received) */
126 } else {
127 double n = lua_tonumber(L, 2);
128 size_t wanted = (size_t) n;
129 luaL_argcheck(L, n >= 0, 2, "invalid receive pattern");
130 if (size == 0 || wanted > size)
131 err = recvraw(buf, wanted-size, &b);
132 }
133 /* check if there was an error */
134 if (err != IO_DONE) {
135 /* we can't push anyting in the stack before pushing the
136 * contents of the buffer. this is the reason for the complication */
137 luaL_pushresult(&b);
138 lua_pushstring(L, buf->io->error(buf->io->ctx, err));
139 lua_pushvalue(L, -2);
140 lua_pushnil(L);
141 lua_replace(L, -4);
142 } else {
143 luaL_pushresult(&b);
144 lua_pushnil(L);
145 lua_pushnil(L);
146 }
147#ifdef LUASOCKET_DEBUG
148 /* push time elapsed during operation as the last return value */
149 lua_pushnumber(L, timeout_gettime() - timeout_getstart(buf->tm));
150#endif
151 return lua_gettop(L) - top;
152}
153
154/*-------------------------------------------------------------------------*\
155* Determines if there is any data in the read buffer
156\*-------------------------------------------------------------------------*/
157int buffer_isempty(p_buffer buf) {
158 return buf->first >= buf->last;
159}
160
161/*=========================================================================*\
162* Internal functions
163\*=========================================================================*/
164/*-------------------------------------------------------------------------*\
165* Sends a block of data (unbuffered)
166\*-------------------------------------------------------------------------*/
167#define STEPSIZE 8192
168static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent) {
169 p_io io = buf->io;
170 p_timeout tm = buf->tm;
171 size_t total = 0;
172 int err = IO_DONE;
173 while (total < count && err == IO_DONE) {
174 size_t done = 0;
175 size_t step = (count-total <= STEPSIZE)? count-total: STEPSIZE;
176 err = io->send(io->ctx, data+total, step, &done, tm);
177 total += done;
178 }
179 *sent = total;
180 buf->sent += total;
181 return err;
182}
183
184/*-------------------------------------------------------------------------*\
185* Reads a fixed number of bytes (buffered)
186\*-------------------------------------------------------------------------*/
187static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b) {
188 int err = IO_DONE;
189 size_t total = 0;
190 while (err == IO_DONE) {
191 size_t count; const char *data;
192 err = buffer_get(buf, &data, &count);
193 count = MIN(count, wanted - total);
194 luaL_addlstring(b, data, count);
195 buffer_skip(buf, count);
196 total += count;
197 if (total >= wanted) break;
198 }
199 return err;
200}
201
202/*-------------------------------------------------------------------------*\
203* Reads everything until the connection is closed (buffered)
204\*-------------------------------------------------------------------------*/
205static int recvall(p_buffer buf, luaL_Buffer *b) {
206 int err = IO_DONE;
207 size_t total = 0;
208 while (err == IO_DONE) {
209 const char *data; size_t count;
210 err = buffer_get(buf, &data, &count);
211 total += count;
212 luaL_addlstring(b, data, count);
213 buffer_skip(buf, count);
214 }
215 if (err == IO_CLOSED) {
216 if (total > 0) return IO_DONE;
217 else return IO_CLOSED;
218 } else return err;
219}
220
221/*-------------------------------------------------------------------------*\
222* Reads a line terminated by a CR LF pair or just by a LF. The CR and LF
223* are not returned by the function and are discarded from the buffer
224\*-------------------------------------------------------------------------*/
225static int recvline(p_buffer buf, luaL_Buffer *b) {
226 int err = IO_DONE;
227 while (err == IO_DONE) {
228 size_t count, pos; const char *data;
229 err = buffer_get(buf, &data, &count);
230 pos = 0;
231 while (pos < count && data[pos] != '\n') {
232 /* we ignore all \r's */
233 if (data[pos] != '\r') luaL_addchar(b, data[pos]);
234 pos++;
235 }
236 if (pos < count) { /* found '\n' */
237 buffer_skip(buf, pos+1); /* skip '\n' too */
238 break; /* we are done */
239 } else /* reached the end of the buffer */
240 buffer_skip(buf, pos);
241 }
242 return err;
243}
244
245/*-------------------------------------------------------------------------*\
246* Skips a given number of bytes from read buffer. No data is read from the
247* transport layer
248\*-------------------------------------------------------------------------*/
249static void buffer_skip(p_buffer buf, size_t count) {
250 buf->received += count;
251 buf->first += count;
252 if (buffer_isempty(buf))
253 buf->first = buf->last = 0;
254}
255
256/*-------------------------------------------------------------------------*\
257* Return any data available in buffer, or get more data from transport layer
258* if buffer is empty
259\*-------------------------------------------------------------------------*/
260static int buffer_get(p_buffer buf, const char **data, size_t *count) {
261 int err = IO_DONE;
262 p_io io = buf->io;
263 p_timeout tm = buf->tm;
264 if (buffer_isempty(buf)) {
265 size_t got;
266 err = io->recv(io->ctx, buf->data, BUF_SIZE, &got, tm);
267 buf->first = 0;
268 buf->last = got;
269 }
270 *count = buf->last - buf->first;
271 *data = buf->data + buf->first;
272 return err;
273}
diff --git a/vendor/luasocket/src/buffer.h b/vendor/luasocket/src/buffer.h
new file mode 100644
index 00000000..a0901fcc
--- /dev/null
+++ b/vendor/luasocket/src/buffer.h
@@ -0,0 +1,52 @@
1#ifndef BUF_H
2#define BUF_H
3/*=========================================================================*\
4* Input/Output interface for Lua programs
5* LuaSocket toolkit
6*
7* Line patterns require buffering. Reading one character at a time involves
8* too many system calls and is very slow. This module implements the
9* LuaSocket interface for input/output on connected objects, as seen by
10* Lua programs.
11*
12* Input is buffered. Output is *not* buffered because there was no simple
13* way of making sure the buffered output data would ever be sent.
14*
15* The module is built on top of the I/O abstraction defined in io.h and the
16* timeout management is done with the timeout.h interface.
17\*=========================================================================*/
18#include "luasocket.h"
19#include "io.h"
20#include "timeout.h"
21
22/* buffer size in bytes */
23#define BUF_SIZE 8192
24
25/* buffer control structure */
26typedef struct t_buffer_ {
27 double birthday; /* throttle support info: creation time, */
28 size_t sent, received; /* bytes sent, and bytes received */
29 p_io io; /* IO driver used for this buffer */
30 p_timeout tm; /* timeout management for this buffer */
31 size_t first, last; /* index of first and last bytes of stored data */
32 char data[BUF_SIZE]; /* storage space for buffer data */
33} t_buffer;
34typedef t_buffer *p_buffer;
35
36#ifndef _WIN32
37#pragma GCC visibility push(hidden)
38#endif
39
40int buffer_open(lua_State *L);
41void buffer_init(p_buffer buf, p_io io, p_timeout tm);
42int buffer_meth_getstats(lua_State *L, p_buffer buf);
43int buffer_meth_setstats(lua_State *L, p_buffer buf);
44int buffer_meth_send(lua_State *L, p_buffer buf);
45int buffer_meth_receive(lua_State *L, p_buffer buf);
46int buffer_isempty(p_buffer buf);
47
48#ifndef _WIN32
49#pragma GCC visibility pop
50#endif
51
52#endif /* BUF_H */
diff --git a/vendor/luasocket/src/compat.c b/vendor/luasocket/src/compat.c
new file mode 100644
index 00000000..34ffdaf7
--- /dev/null
+++ b/vendor/luasocket/src/compat.c
@@ -0,0 +1,39 @@
1#include "luasocket.h"
2#include "compat.h"
3
4#if LUA_VERSION_NUM==501
5
6/*
7** Adapted from Lua 5.2
8*/
9void luasocket_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
10 luaL_checkstack(L, nup+1, "too many upvalues");
11 for (; l->name != NULL; l++) { /* fill the table with given functions */
12 int i;
13 lua_pushstring(L, l->name);
14 for (i = 0; i < nup; i++) /* copy upvalues to the top */
15 lua_pushvalue(L, -(nup+1));
16 lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
17 lua_settable(L, -(nup + 3));
18 }
19 lua_pop(L, nup); /* remove upvalues */
20}
21
22/*
23** Duplicated from Lua 5.2
24*/
25void *luasocket_testudata (lua_State *L, int ud, const char *tname) {
26 void *p = lua_touserdata(L, ud);
27 if (p != NULL) { /* value is a userdata? */
28 if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
29 luaL_getmetatable(L, tname); /* get correct metatable */
30 if (!lua_rawequal(L, -1, -2)) /* not the same? */
31 p = NULL; /* value is a userdata with wrong metatable */
32 lua_pop(L, 2); /* remove both metatables */
33 return p;
34 }
35 }
36 return NULL; /* value is not a userdata with a metatable */
37}
38
39#endif
diff --git a/vendor/luasocket/src/compat.h b/vendor/luasocket/src/compat.h
new file mode 100644
index 00000000..fa2d7d7c
--- /dev/null
+++ b/vendor/luasocket/src/compat.h
@@ -0,0 +1,22 @@
1#ifndef COMPAT_H
2#define COMPAT_H
3
4#if LUA_VERSION_NUM==501
5
6#ifndef _WIN32
7#pragma GCC visibility push(hidden)
8#endif
9
10void luasocket_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
11void *luasocket_testudata ( lua_State *L, int arg, const char *tname);
12
13#ifndef _WIN32
14#pragma GCC visibility pop
15#endif
16
17#define luaL_setfuncs luasocket_setfuncs
18#define luaL_testudata luasocket_testudata
19
20#endif
21
22#endif
diff --git a/vendor/luasocket/src/except.c b/vendor/luasocket/src/except.c
new file mode 100644
index 00000000..9c3317f2
--- /dev/null
+++ b/vendor/luasocket/src/except.c
@@ -0,0 +1,129 @@
1/*=========================================================================*\
2* Simple exception support
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6#include "except.h"
7#include <stdio.h>
8
9#if LUA_VERSION_NUM < 502
10#define lua_pcallk(L, na, nr, err, ctx, cont) \
11 (((void)ctx),((void)cont),lua_pcall(L, na, nr, err))
12#endif
13
14#if LUA_VERSION_NUM < 503
15typedef int lua_KContext;
16#endif
17
18/*=========================================================================*\
19* Internal function prototypes.
20\*=========================================================================*/
21static int global_protect(lua_State *L);
22static int global_newtry(lua_State *L);
23static int protected_(lua_State *L);
24static int finalize(lua_State *L);
25static int do_nothing(lua_State *L);
26
27/* except functions */
28static luaL_Reg func[] = {
29 {"newtry", global_newtry},
30 {"protect", global_protect},
31 {NULL, NULL}
32};
33
34/*-------------------------------------------------------------------------*\
35* Try factory
36\*-------------------------------------------------------------------------*/
37static void wrap(lua_State *L) {
38 lua_createtable(L, 1, 0);
39 lua_pushvalue(L, -2);
40 lua_rawseti(L, -2, 1);
41 lua_pushvalue(L, lua_upvalueindex(1));
42 lua_setmetatable(L, -2);
43}
44
45static int finalize(lua_State *L) {
46 if (!lua_toboolean(L, 1)) {
47 lua_pushvalue(L, lua_upvalueindex(2));
48 lua_call(L, 0, 0);
49 lua_settop(L, 2);
50 wrap(L);
51 lua_error(L);
52 return 0;
53 } else return lua_gettop(L);
54}
55
56static int do_nothing(lua_State *L) {
57 (void) L;
58 return 0;
59}
60
61static int global_newtry(lua_State *L) {
62 lua_settop(L, 1);
63 if (lua_isnil(L, 1)) lua_pushcfunction(L, do_nothing);
64 lua_pushvalue(L, lua_upvalueindex(1));
65 lua_insert(L, -2);
66 lua_pushcclosure(L, finalize, 2);
67 return 1;
68}
69
70/*-------------------------------------------------------------------------*\
71* Protect factory
72\*-------------------------------------------------------------------------*/
73static int unwrap(lua_State *L) {
74 if (lua_istable(L, -1) && lua_getmetatable(L, -1)) {
75 int r = lua_rawequal(L, -1, lua_upvalueindex(1));
76 lua_pop(L, 1);
77 if (r) {
78 lua_pushnil(L);
79 lua_rawgeti(L, -2, 1);
80 return 1;
81 }
82 }
83 return 0;
84}
85
86static int protected_finish(lua_State *L, int status, lua_KContext ctx) {
87 (void)ctx;
88 if (status != 0 && status != LUA_YIELD) {
89 if (unwrap(L)) return 2;
90 else return lua_error(L);
91 } else return lua_gettop(L);
92}
93
94#if LUA_VERSION_NUM == 502
95static int protected_cont(lua_State *L) {
96 int ctx = 0;
97 int status = lua_getctx(L, &ctx);
98 return protected_finish(L, status, ctx);
99}
100#else
101#define protected_cont protected_finish
102#endif
103
104static int protected_(lua_State *L) {
105 int status;
106 lua_pushvalue(L, lua_upvalueindex(2));
107 lua_insert(L, 1);
108 status = lua_pcallk(L, lua_gettop(L) - 1, LUA_MULTRET, 0, 0, protected_cont);
109 return protected_finish(L, status, 0);
110}
111
112static int global_protect(lua_State *L) {
113 lua_settop(L, 1);
114 lua_pushvalue(L, lua_upvalueindex(1));
115 lua_insert(L, 1);
116 lua_pushcclosure(L, protected_, 2);
117 return 1;
118}
119
120/*-------------------------------------------------------------------------*\
121* Init module
122\*-------------------------------------------------------------------------*/
123int except_open(lua_State *L) {
124 lua_newtable(L); /* metatable for wrapped exceptions */
125 lua_pushboolean(L, 0);
126 lua_setfield(L, -2, "__metatable");
127 luaL_setfuncs(L, func, 1);
128 return 0;
129}
diff --git a/vendor/luasocket/src/except.h b/vendor/luasocket/src/except.h
new file mode 100644
index 00000000..71c31fd4
--- /dev/null
+++ b/vendor/luasocket/src/except.h
@@ -0,0 +1,46 @@
1#ifndef EXCEPT_H
2#define EXCEPT_H
3/*=========================================================================*\
4* Exception control
5* LuaSocket toolkit (but completely independent from other modules)
6*
7* This provides support for simple exceptions in Lua. During the
8* development of the HTTP/FTP/SMTP support, it became aparent that
9* error checking was taking a substantial amount of the coding. These
10* function greatly simplify the task of checking errors.
11*
12* The main idea is that functions should return nil as their first return
13* values when they find an error, and return an error message (or value)
14* following nil. In case of success, as long as the first value is not nil,
15* the other values don't matter.
16*
17* The idea is to nest function calls with the "try" function. This function
18* checks the first value, and, if it's falsy, wraps the second value in a
19* table with metatable and calls "error" on it. Otherwise, it returns all
20* values it received. Basically, it works like the Lua "assert" function,
21* but it creates errors targeted specifically at "protect".
22*
23* The "newtry" function is a factory for "try" functions that call a
24* finalizer in protected mode before calling "error".
25*
26* The "protect" function returns a new function that behaves exactly like
27* the function it receives, but the new function catches exceptions thrown
28* by "try" functions and returns nil followed by the error message instead.
29*
30* With these three functions, it's easy to write functions that throw
31* exceptions on error, but that don't interrupt the user script.
32\*=========================================================================*/
33
34#include "luasocket.h"
35
36#ifndef _WIN32
37#pragma GCC visibility push(hidden)
38#endif
39
40int except_open(lua_State *L);
41
42#ifndef _WIN32
43#pragma GCC visibility pop
44#endif
45
46#endif
diff --git a/vendor/luasocket/src/ftp.lua b/vendor/luasocket/src/ftp.lua
new file mode 100644
index 00000000..0ebc5086
--- /dev/null
+++ b/vendor/luasocket/src/ftp.lua
@@ -0,0 +1,329 @@
1-----------------------------------------------------------------------------
2-- FTP support for the Lua language
3-- LuaSocket toolkit.
4-- Author: Diego Nehab
5-----------------------------------------------------------------------------
6
7-----------------------------------------------------------------------------
8-- Declare module and import dependencies
9-----------------------------------------------------------------------------
10local base = _G
11local table = require("table")
12local string = require("string")
13local math = require("math")
14local socket = require("socket")
15local url = require("socket.url")
16local tp = require("socket.tp")
17local ltn12 = require("ltn12")
18socket.ftp = {}
19local _M = socket.ftp
20-----------------------------------------------------------------------------
21-- Program constants
22-----------------------------------------------------------------------------
23-- timeout in seconds before the program gives up on a connection
24_M.TIMEOUT = 60
25-- default port for ftp service
26local PORT = 21
27-- this is the default anonymous password. used when no password is
28-- provided in url. should be changed to your e-mail.
29_M.USER = "ftp"
30_M.PASSWORD = "anonymous@anonymous.org"
31
32-----------------------------------------------------------------------------
33-- Low level FTP API
34-----------------------------------------------------------------------------
35local metat = { __index = {} }
36
37function _M.open(server, port, create)
38 local tp = socket.try(tp.connect(server, port or PORT, _M.TIMEOUT, create))
39 local f = base.setmetatable({ tp = tp }, metat)
40 -- make sure everything gets closed in an exception
41 f.try = socket.newtry(function() f:close() end)
42 return f
43end
44
45function metat.__index:portconnect()
46 self.try(self.server:settimeout(_M.TIMEOUT))
47 self.data = self.try(self.server:accept())
48 self.try(self.data:settimeout(_M.TIMEOUT))
49end
50
51function metat.__index:pasvconnect()
52 self.data = self.try(socket.tcp())
53 self.try(self.data:settimeout(_M.TIMEOUT))
54 self.try(self.data:connect(self.pasvt.address, self.pasvt.port))
55end
56
57function metat.__index:login(user, password)
58 self.try(self.tp:command("user", user or _M.USER))
59 local code, _ = self.try(self.tp:check{"2..", 331})
60 if code == 331 then
61 self.try(self.tp:command("pass", password or _M.PASSWORD))
62 self.try(self.tp:check("2.."))
63 end
64 return 1
65end
66
67function metat.__index:pasv()
68 self.try(self.tp:command("pasv"))
69 local _, reply = self.try(self.tp:check("2.."))
70 local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
71 local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern))
72 self.try(a and b and c and d and p1 and p2, reply)
73 self.pasvt = {
74 address = string.format("%d.%d.%d.%d", a, b, c, d),
75 port = p1*256 + p2
76 }
77 if self.server then
78 self.server:close()
79 self.server = nil
80 end
81 return self.pasvt.address, self.pasvt.port
82end
83
84function metat.__index:epsv()
85 self.try(self.tp:command("epsv"))
86 local _, reply = self.try(self.tp:check("229"))
87 local pattern = "%((.)(.-)%1(.-)%1(.-)%1%)"
88 local _, _, _, port = string.match(reply, pattern)
89 self.try(port, "invalid epsv response")
90 self.pasvt = {
91 address = self.tp:getpeername(),
92 port = port
93 }
94 if self.server then
95 self.server:close()
96 self.server = nil
97 end
98 return self.pasvt.address, self.pasvt.port
99end
100
101
102function metat.__index:port(address, port)
103 self.pasvt = nil
104 if not address then
105 address = self.try(self.tp:getsockname())
106 self.server = self.try(socket.bind(address, 0))
107 address, port = self.try(self.server:getsockname())
108 self.try(self.server:settimeout(_M.TIMEOUT))
109 end
110 local pl = math.mod(port, 256)
111 local ph = (port - pl)/256
112 local arg = string.gsub(string.format("%s,%d,%d", address, ph, pl), "%.", ",")
113 self.try(self.tp:command("port", arg))
114 self.try(self.tp:check("2.."))
115 return 1
116end
117
118function metat.__index:eprt(family, address, port)
119 self.pasvt = nil
120 if not address then
121 address = self.try(self.tp:getsockname())
122 self.server = self.try(socket.bind(address, 0))
123 address, port = self.try(self.server:getsockname())
124 self.try(self.server:settimeout(_M.TIMEOUT))
125 end
126 local arg = string.format("|%s|%s|%d|", family, address, port)
127 self.try(self.tp:command("eprt", arg))
128 self.try(self.tp:check("2.."))
129 return 1
130end
131
132
133function metat.__index:send(sendt)
134 self.try(self.pasvt or self.server, "need port or pasv first")
135 -- if there is a pasvt table, we already sent a PASV command
136 -- we just get the data connection into self.data
137 if self.pasvt then self:pasvconnect() end
138 -- get the transfer argument and command
139 local argument = sendt.argument or
140 url.unescape(string.gsub(sendt.path or "", "^[/\\]", ""))
141 if argument == "" then argument = nil end
142 local command = sendt.command or "stor"
143 -- send the transfer command and check the reply
144 self.try(self.tp:command(command, argument))
145 local code, _ = self.try(self.tp:check{"2..", "1.."})
146 -- if there is not a pasvt table, then there is a server
147 -- and we already sent a PORT command
148 if not self.pasvt then self:portconnect() end
149 -- get the sink, source and step for the transfer
150 local step = sendt.step or ltn12.pump.step
151 local readt = { self.tp }
152 local checkstep = function(src, snk)
153 -- check status in control connection while downloading
154 local readyt = socket.select(readt, nil, 0)
155 if readyt[tp] then code = self.try(self.tp:check("2..")) end
156 return step(src, snk)
157 end
158 local sink = socket.sink("close-when-done", self.data)
159 -- transfer all data and check error
160 self.try(ltn12.pump.all(sendt.source, sink, checkstep))
161 if string.find(code, "1..") then self.try(self.tp:check("2..")) end
162 -- done with data connection
163 self.data:close()
164 -- find out how many bytes were sent
165 local sent = socket.skip(1, self.data:getstats())
166 self.data = nil
167 return sent
168end
169
170function metat.__index:receive(recvt)
171 self.try(self.pasvt or self.server, "need port or pasv first")
172 if self.pasvt then self:pasvconnect() end
173 local argument = recvt.argument or
174 url.unescape(string.gsub(recvt.path or "", "^[/\\]", ""))
175 if argument == "" then argument = nil end
176 local command = recvt.command or "retr"
177 self.try(self.tp:command(command, argument))
178 local code,reply = self.try(self.tp:check{"1..", "2.."})
179 if (code >= 200) and (code <= 299) then
180 recvt.sink(reply)
181 return 1
182 end
183 if not self.pasvt then self:portconnect() end
184 local source = socket.source("until-closed", self.data)
185 local step = recvt.step or ltn12.pump.step
186 self.try(ltn12.pump.all(source, recvt.sink, step))
187 if string.find(code, "1..") then self.try(self.tp:check("2..")) end
188 self.data:close()
189 self.data = nil
190 return 1
191end
192
193function metat.__index:cwd(dir)
194 self.try(self.tp:command("cwd", dir))
195 self.try(self.tp:check(250))
196 return 1
197end
198
199function metat.__index:type(type)
200 self.try(self.tp:command("type", type))
201 self.try(self.tp:check(200))
202 return 1
203end
204
205function metat.__index:greet()
206 local code = self.try(self.tp:check{"1..", "2.."})
207 if string.find(code, "1..") then self.try(self.tp:check("2..")) end
208 return 1
209end
210
211function metat.__index:quit()
212 self.try(self.tp:command("quit"))
213 self.try(self.tp:check("2.."))
214 return 1
215end
216
217function metat.__index:close()
218 if self.data then self.data:close() end
219 if self.server then self.server:close() end
220 return self.tp:close()
221end
222
223-----------------------------------------------------------------------------
224-- High level FTP API
225-----------------------------------------------------------------------------
226local function override(t)
227 if t.url then
228 local u = url.parse(t.url)
229 for i,v in base.pairs(t) do
230 u[i] = v
231 end
232 return u
233 else return t end
234end
235
236local function tput(putt)
237 putt = override(putt)
238 socket.try(putt.host, "missing hostname")
239 local f = _M.open(putt.host, putt.port, putt.create)
240 f:greet()
241 f:login(putt.user, putt.password)
242 if putt.type then f:type(putt.type) end
243 f:epsv()
244 local sent = f:send(putt)
245 f:quit()
246 f:close()
247 return sent
248end
249
250local default = {
251 path = "/",
252 scheme = "ftp"
253}
254
255local function genericform(u)
256 local t = socket.try(url.parse(u, default))
257 socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'")
258 socket.try(t.host, "missing hostname")
259 local pat = "^type=(.)$"
260 if t.params then
261 t.type = socket.skip(2, string.find(t.params, pat))
262 socket.try(t.type == "a" or t.type == "i",
263 "invalid type '" .. t.type .. "'")
264 end
265 return t
266end
267
268_M.genericform = genericform
269
270local function sput(u, body)
271 local putt = genericform(u)
272 putt.source = ltn12.source.string(body)
273 return tput(putt)
274end
275
276_M.put = socket.protect(function(putt, body)
277 if base.type(putt) == "string" then return sput(putt, body)
278 else return tput(putt) end
279end)
280
281local function tget(gett)
282 gett = override(gett)
283 socket.try(gett.host, "missing hostname")
284 local f = _M.open(gett.host, gett.port, gett.create)
285 f:greet()
286 f:login(gett.user, gett.password)
287 if gett.type then f:type(gett.type) end
288 f:epsv()
289 f:receive(gett)
290 f:quit()
291 return f:close()
292end
293
294local function sget(u)
295 local gett = genericform(u)
296 local t = {}
297 gett.sink = ltn12.sink.table(t)
298 tget(gett)
299 return table.concat(t)
300end
301
302_M.command = socket.protect(function(cmdt)
303 cmdt = override(cmdt)
304 socket.try(cmdt.host, "missing hostname")
305 socket.try(cmdt.command, "missing command")
306 local f = _M.open(cmdt.host, cmdt.port, cmdt.create)
307 f:greet()
308 f:login(cmdt.user, cmdt.password)
309 if type(cmdt.command) == "table" then
310 local argument = cmdt.argument or {}
311 local check = cmdt.check or {}
312 for i,cmd in ipairs(cmdt.command) do
313 f.try(f.tp:command(cmd, argument[i]))
314 if check[i] then f.try(f.tp:check(check[i])) end
315 end
316 else
317 f.try(f.tp:command(cmdt.command, cmdt.argument))
318 if cmdt.check then f.try(f.tp:check(cmdt.check)) end
319 end
320 f:quit()
321 return f:close()
322end)
323
324_M.get = socket.protect(function(gett)
325 if base.type(gett) == "string" then return sget(gett)
326 else return tget(gett) end
327end)
328
329return _M
diff --git a/vendor/luasocket/src/headers.lua b/vendor/luasocket/src/headers.lua
new file mode 100644
index 00000000..1eb8223b
--- /dev/null
+++ b/vendor/luasocket/src/headers.lua
@@ -0,0 +1,104 @@
1-----------------------------------------------------------------------------
2-- Canonic header field capitalization
3-- LuaSocket toolkit.
4-- Author: Diego Nehab
5-----------------------------------------------------------------------------
6local socket = require("socket")
7socket.headers = {}
8local _M = socket.headers
9
10_M.canonic = {
11 ["accept"] = "Accept",
12 ["accept-charset"] = "Accept-Charset",
13 ["accept-encoding"] = "Accept-Encoding",
14 ["accept-language"] = "Accept-Language",
15 ["accept-ranges"] = "Accept-Ranges",
16 ["action"] = "Action",
17 ["alternate-recipient"] = "Alternate-Recipient",
18 ["age"] = "Age",
19 ["allow"] = "Allow",
20 ["arrival-date"] = "Arrival-Date",
21 ["authorization"] = "Authorization",
22 ["bcc"] = "Bcc",
23 ["cache-control"] = "Cache-Control",
24 ["cc"] = "Cc",
25 ["comments"] = "Comments",
26 ["connection"] = "Connection",
27 ["content-description"] = "Content-Description",
28 ["content-disposition"] = "Content-Disposition",
29 ["content-encoding"] = "Content-Encoding",
30 ["content-id"] = "Content-ID",
31 ["content-language"] = "Content-Language",
32 ["content-length"] = "Content-Length",
33 ["content-location"] = "Content-Location",
34 ["content-md5"] = "Content-MD5",
35 ["content-range"] = "Content-Range",
36 ["content-transfer-encoding"] = "Content-Transfer-Encoding",
37 ["content-type"] = "Content-Type",
38 ["cookie"] = "Cookie",
39 ["date"] = "Date",
40 ["diagnostic-code"] = "Diagnostic-Code",
41 ["dsn-gateway"] = "DSN-Gateway",
42 ["etag"] = "ETag",
43 ["expect"] = "Expect",
44 ["expires"] = "Expires",
45 ["final-log-id"] = "Final-Log-ID",
46 ["final-recipient"] = "Final-Recipient",
47 ["from"] = "From",
48 ["host"] = "Host",
49 ["if-match"] = "If-Match",
50 ["if-modified-since"] = "If-Modified-Since",
51 ["if-none-match"] = "If-None-Match",
52 ["if-range"] = "If-Range",
53 ["if-unmodified-since"] = "If-Unmodified-Since",
54 ["in-reply-to"] = "In-Reply-To",
55 ["keywords"] = "Keywords",
56 ["last-attempt-date"] = "Last-Attempt-Date",
57 ["last-modified"] = "Last-Modified",
58 ["location"] = "Location",
59 ["max-forwards"] = "Max-Forwards",
60 ["message-id"] = "Message-ID",
61 ["mime-version"] = "MIME-Version",
62 ["original-envelope-id"] = "Original-Envelope-ID",
63 ["original-recipient"] = "Original-Recipient",
64 ["pragma"] = "Pragma",
65 ["proxy-authenticate"] = "Proxy-Authenticate",
66 ["proxy-authorization"] = "Proxy-Authorization",
67 ["range"] = "Range",
68 ["received"] = "Received",
69 ["received-from-mta"] = "Received-From-MTA",
70 ["references"] = "References",
71 ["referer"] = "Referer",
72 ["remote-mta"] = "Remote-MTA",
73 ["reply-to"] = "Reply-To",
74 ["reporting-mta"] = "Reporting-MTA",
75 ["resent-bcc"] = "Resent-Bcc",
76 ["resent-cc"] = "Resent-Cc",
77 ["resent-date"] = "Resent-Date",
78 ["resent-from"] = "Resent-From",
79 ["resent-message-id"] = "Resent-Message-ID",
80 ["resent-reply-to"] = "Resent-Reply-To",
81 ["resent-sender"] = "Resent-Sender",
82 ["resent-to"] = "Resent-To",
83 ["retry-after"] = "Retry-After",
84 ["return-path"] = "Return-Path",
85 ["sender"] = "Sender",
86 ["server"] = "Server",
87 ["smtp-remote-recipient"] = "SMTP-Remote-Recipient",
88 ["status"] = "Status",
89 ["subject"] = "Subject",
90 ["te"] = "TE",
91 ["to"] = "To",
92 ["trailer"] = "Trailer",
93 ["transfer-encoding"] = "Transfer-Encoding",
94 ["upgrade"] = "Upgrade",
95 ["user-agent"] = "User-Agent",
96 ["vary"] = "Vary",
97 ["via"] = "Via",
98 ["warning"] = "Warning",
99 ["will-retry-until"] = "Will-Retry-Until",
100 ["www-authenticate"] = "WWW-Authenticate",
101 ["x-mailer"] = "X-Mailer",
102}
103
104return _M \ No newline at end of file
diff --git a/vendor/luasocket/src/http.lua b/vendor/luasocket/src/http.lua
new file mode 100644
index 00000000..1330355f
--- /dev/null
+++ b/vendor/luasocket/src/http.lua
@@ -0,0 +1,424 @@
1-----------------------------------------------------------------------------
2-- HTTP/1.1 client support for the Lua language.
3-- LuaSocket toolkit.
4-- Author: Diego Nehab
5-----------------------------------------------------------------------------
6
7-----------------------------------------------------------------------------
8-- Declare module and import dependencies
9-------------------------------------------------------------------------------
10local socket = require("socket")
11local url = require("socket.url")
12local ltn12 = require("ltn12")
13local mime = require("mime")
14local string = require("string")
15local headers = require("socket.headers")
16local base = _G
17local table = require("table")
18socket.http = {}
19local _M = socket.http
20
21-----------------------------------------------------------------------------
22-- Program constants
23-----------------------------------------------------------------------------
24-- connection timeout in seconds
25_M.TIMEOUT = 60
26-- user agent field sent in request
27_M.USERAGENT = socket._VERSION
28
29-- supported schemes and their particulars
30local SCHEMES = {
31 http = {
32 port = 80
33 , create = function(t)
34 return socket.tcp end }
35 , https = {
36 port = 443
37 , create = function(t)
38 local https = assert(
39 require("ssl.https"), 'LuaSocket: LuaSec not found')
40 local tcp = assert(
41 https.tcp, 'LuaSocket: Function tcp() not available from LuaSec')
42 return tcp(t) end }}
43
44-----------------------------------------------------------------------------
45-- Reads MIME headers from a connection, unfolding where needed
46-----------------------------------------------------------------------------
47local function receiveheaders(sock, headers)
48 local line, name, value, err
49 headers = headers or {}
50 -- get first line
51 line, err = sock:receive()
52 if err then return nil, err end
53 -- headers go until a blank line is found
54 while line ~= "" do
55 -- get field-name and value
56 name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)"))
57 if not (name and value) then return nil, "malformed reponse headers" end
58 name = string.lower(name)
59 -- get next line (value might be folded)
60 line, err = sock:receive()
61 if err then return nil, err end
62 -- unfold any folded values
63 while string.find(line, "^%s") do
64 value = value .. line
65 line = sock:receive()
66 if err then return nil, err end
67 end
68 -- save pair in table
69 if headers[name] then headers[name] = headers[name] .. ", " .. value
70 else headers[name] = value end
71 end
72 return headers
73end
74
75-----------------------------------------------------------------------------
76-- Extra sources and sinks
77-----------------------------------------------------------------------------
78socket.sourcet["http-chunked"] = function(sock, headers)
79 return base.setmetatable({
80 getfd = function() return sock:getfd() end,
81 dirty = function() return sock:dirty() end
82 }, {
83 __call = function()
84 -- get chunk size, skip extention
85 local line, err = sock:receive()
86 if err then return nil, err end
87 local size = base.tonumber(string.gsub(line, ";.*", ""), 16)
88 if not size then return nil, "invalid chunk size" end
89 -- was it the last chunk?
90 if size > 0 then
91 -- if not, get chunk and skip terminating CRLF
92 local chunk, err, _ = sock:receive(size)
93 if chunk then sock:receive() end
94 return chunk, err
95 else
96 -- if it was, read trailers into headers table
97 headers, err = receiveheaders(sock, headers)
98 if not headers then return nil, err end
99 end
100 end
101 })
102end
103
104socket.sinkt["http-chunked"] = function(sock)
105 return base.setmetatable({
106 getfd = function() return sock:getfd() end,
107 dirty = function() return sock:dirty() end
108 }, {
109 __call = function(self, chunk, err)
110 if not chunk then return sock:send("0\r\n\r\n") end
111 local size = string.format("%X\r\n", string.len(chunk))
112 return sock:send(size .. chunk .. "\r\n")
113 end
114 })
115end
116
117-----------------------------------------------------------------------------
118-- Low level HTTP API
119-----------------------------------------------------------------------------
120local metat = { __index = {} }
121
122function _M.open(host, port, create)
123 -- create socket with user connect function, or with default
124 local c = socket.try(create())
125 local h = base.setmetatable({ c = c }, metat)
126 -- create finalized try
127 h.try = socket.newtry(function() h:close() end)
128 -- set timeout before connecting
129 h.try(c:settimeout(_M.TIMEOUT))
130 h.try(c:connect(host, port))
131 -- here everything worked
132 return h
133end
134
135function metat.__index:sendrequestline(method, uri)
136 local reqline = string.format("%s %s HTTP/1.1\r\n", method or "GET", uri)
137 return self.try(self.c:send(reqline))
138end
139
140function metat.__index:sendheaders(tosend)
141 local canonic = headers.canonic
142 local h = "\r\n"
143 for f, v in base.pairs(tosend) do
144 h = (canonic[f] or f) .. ": " .. v .. "\r\n" .. h
145 end
146 self.try(self.c:send(h))
147 return 1
148end
149
150function metat.__index:sendbody(headers, source, step)
151 source = source or ltn12.source.empty()
152 step = step or ltn12.pump.step
153 -- if we don't know the size in advance, send chunked and hope for the best
154 local mode = "http-chunked"
155 if headers["content-length"] then mode = "keep-open" end
156 return self.try(ltn12.pump.all(source, socket.sink(mode, self.c), step))
157end
158
159function metat.__index:receivestatusline()
160 local status,ec = self.try(self.c:receive(5))
161 -- identify HTTP/0.9 responses, which do not contain a status line
162 -- this is just a heuristic, but is what the RFC recommends
163 if status ~= "HTTP/" then
164 if ec == "timeout" then
165 return 408
166 end
167 return nil, status
168 end
169 -- otherwise proceed reading a status line
170 status = self.try(self.c:receive("*l", status))
171 local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)"))
172 return self.try(base.tonumber(code), status)
173end
174
175function metat.__index:receiveheaders()
176 return self.try(receiveheaders(self.c))
177end
178
179function metat.__index:receivebody(headers, sink, step)
180 sink = sink or ltn12.sink.null()
181 step = step or ltn12.pump.step
182 local length = base.tonumber(headers["content-length"])
183 local t = headers["transfer-encoding"] -- shortcut
184 local mode = "default" -- connection close
185 if t and t ~= "identity" then mode = "http-chunked"
186 elseif base.tonumber(headers["content-length"]) then mode = "by-length" end
187 return self.try(ltn12.pump.all(socket.source(mode, self.c, length),
188 sink, step))
189end
190
191function metat.__index:receive09body(status, sink, step)
192 local source = ltn12.source.rewind(socket.source("until-closed", self.c))
193 source(status)
194 return self.try(ltn12.pump.all(source, sink, step))
195end
196
197function metat.__index:close()
198 return self.c:close()
199end
200
201-----------------------------------------------------------------------------
202-- High level HTTP API
203-----------------------------------------------------------------------------
204local function adjusturi(reqt)
205 local u = reqt
206 -- if there is a proxy, we need the full url. otherwise, just a part.
207 if not reqt.proxy and not _M.PROXY then
208 u = {
209 path = socket.try(reqt.path, "invalid path 'nil'"),
210 params = reqt.params,
211 query = reqt.query,
212 fragment = reqt.fragment
213 }
214 end
215 return url.build(u)
216end
217
218local function adjustproxy(reqt)
219 local proxy = reqt.proxy or _M.PROXY
220 if proxy then
221 proxy = url.parse(proxy)
222 return proxy.host, proxy.port or 3128
223 else
224 return reqt.host, reqt.port
225 end
226end
227
228local function adjustheaders(reqt)
229 -- default headers
230 local host = reqt.host
231 local port = tostring(reqt.port)
232 if port ~= tostring(SCHEMES[reqt.scheme].port) then
233 host = host .. ':' .. port end
234 local lower = {
235 ["user-agent"] = _M.USERAGENT,
236 ["host"] = host,
237 ["connection"] = "close, TE",
238 ["te"] = "trailers"
239 }
240 -- if we have authentication information, pass it along
241 if reqt.user and reqt.password then
242 lower["authorization"] =
243 "Basic " .. (mime.b64(reqt.user .. ":" ..
244 url.unescape(reqt.password)))
245 end
246 -- if we have proxy authentication information, pass it along
247 local proxy = reqt.proxy or _M.PROXY
248 if proxy then
249 proxy = url.parse(proxy)
250 if proxy.user and proxy.password then
251 lower["proxy-authorization"] =
252 "Basic " .. (mime.b64(proxy.user .. ":" .. proxy.password))
253 end
254 end
255 -- override with user headers
256 for i,v in base.pairs(reqt.headers or lower) do
257 lower[string.lower(i)] = v
258 end
259 return lower
260end
261
262-- default url parts
263local default = {
264 path ="/"
265 , scheme = "http"
266}
267
268local function adjustrequest(reqt)
269 -- parse url if provided
270 local nreqt = reqt.url and url.parse(reqt.url, default) or {}
271 -- explicit components override url
272 for i,v in base.pairs(reqt) do nreqt[i] = v end
273 -- default to scheme particulars
274 local schemedefs, host, port, method
275 = SCHEMES[nreqt.scheme], nreqt.host, nreqt.port, nreqt.method
276 if not nreqt.create then nreqt.create = schemedefs.create(nreqt) end
277 if not (port and port ~= '') then nreqt.port = schemedefs.port end
278 if not (method and method ~= '') then nreqt.method = 'GET' end
279 if not (host and host ~= "") then
280 socket.try(nil, "invalid host '" .. base.tostring(nreqt.host) .. "'")
281 end
282 -- compute uri if user hasn't overriden
283 nreqt.uri = reqt.uri or adjusturi(nreqt)
284 -- adjust headers in request
285 nreqt.headers = adjustheaders(nreqt)
286 if nreqt.source
287 and not nreqt.headers["content-length"]
288 and not nreqt.headers["transfer-encoding"]
289 then
290 nreqt.headers["transfer-encoding"] = "chunked"
291 end
292
293 -- ajust host and port if there is a proxy
294 nreqt.host, nreqt.port = adjustproxy(nreqt)
295 return nreqt
296end
297
298local function shouldredirect(reqt, code, headers)
299 local location = headers.location
300 if not location then return false end
301 location = string.gsub(location, "%s", "")
302 if location == "" then return false end
303 local scheme = url.parse(location).scheme
304 if scheme and (not SCHEMES[scheme]) then return false end
305 -- avoid https downgrades
306 if ('https' == reqt.scheme) and ('https' ~= scheme) then return false end
307 return (reqt.redirect ~= false) and
308 (code == 301 or code == 302 or code == 303 or code == 307) and
309 (not reqt.method or reqt.method == "GET" or reqt.method == "HEAD")
310 and ((false == reqt.maxredirects)
311 or ((reqt.nredirects or 0)
312 < (reqt.maxredirects or 5)))
313end
314
315local function shouldreceivebody(reqt, code)
316 if reqt.method == "HEAD" then return nil end
317 if code == 204 or code == 304 then return nil end
318 if code >= 100 and code < 200 then return nil end
319 return 1
320end
321
322-- forward declarations
323local trequest, tredirect
324
325--[[local]] function tredirect(reqt, location)
326 -- the RFC says the redirect URL has to be absolute, but some
327 -- servers do not respect that
328 local newurl = url.absolute(reqt.url, location)
329 -- if switching schemes, reset port and create function
330 if url.parse(newurl).scheme ~= reqt.scheme then
331 reqt.port = nil
332 reqt.create = nil end
333 -- make new request
334 local result, code, headers, status = trequest {
335 url = newurl,
336 source = reqt.source,
337 sink = reqt.sink,
338 headers = reqt.headers,
339 proxy = reqt.proxy,
340 maxredirects = reqt.maxredirects,
341 nredirects = (reqt.nredirects or 0) + 1,
342 create = reqt.create
343 }
344 -- pass location header back as a hint we redirected
345 headers = headers or {}
346 headers.location = headers.location or location
347 return result, code, headers, status
348end
349
350--[[local]] function trequest(reqt)
351 -- we loop until we get what we want, or
352 -- until we are sure there is no way to get it
353 local nreqt = adjustrequest(reqt)
354 local h = _M.open(nreqt.host, nreqt.port, nreqt.create)
355 -- send request line and headers
356 h:sendrequestline(nreqt.method, nreqt.uri)
357 h:sendheaders(nreqt.headers)
358 -- if there is a body, send it
359 if nreqt.source then
360 h:sendbody(nreqt.headers, nreqt.source, nreqt.step)
361 end
362 local code, status = h:receivestatusline()
363 -- if it is an HTTP/0.9 server, simply get the body and we are done
364 if not code then
365 h:receive09body(status, nreqt.sink, nreqt.step)
366 return 1, 200
367 elseif code == 408 then
368 return 1, code
369 end
370 local headers
371 -- ignore any 100-continue messages
372 while code == 100 do
373 h:receiveheaders()
374 code, status = h:receivestatusline()
375 end
376 headers = h:receiveheaders()
377 -- at this point we should have a honest reply from the server
378 -- we can't redirect if we already used the source, so we report the error
379 if shouldredirect(nreqt, code, headers) and not nreqt.source then
380 h:close()
381 return tredirect(reqt, headers.location)
382 end
383 -- here we are finally done
384 if shouldreceivebody(nreqt, code) then
385 h:receivebody(headers, nreqt.sink, nreqt.step)
386 end
387 h:close()
388 return 1, code, headers, status
389end
390
391-- turns an url and a body into a generic request
392local function genericform(u, b)
393 local t = {}
394 local reqt = {
395 url = u,
396 sink = ltn12.sink.table(t),
397 target = t
398 }
399 if b then
400 reqt.source = ltn12.source.string(b)
401 reqt.headers = {
402 ["content-length"] = string.len(b),
403 ["content-type"] = "application/x-www-form-urlencoded"
404 }
405 reqt.method = "POST"
406 end
407 return reqt
408end
409
410_M.genericform = genericform
411
412local function srequest(u, b)
413 local reqt = genericform(u, b)
414 local _, code, headers, status = trequest(reqt)
415 return table.concat(reqt.target), code, headers, status
416end
417
418_M.request = socket.protect(function(reqt, body)
419 if base.type(reqt) == "string" then return srequest(reqt, body)
420 else return trequest(reqt) end
421end)
422
423_M.schemes = SCHEMES
424return _M
diff --git a/vendor/luasocket/src/inet.c b/vendor/luasocket/src/inet.c
new file mode 100755
index 00000000..138c9abe
--- /dev/null
+++ b/vendor/luasocket/src/inet.c
@@ -0,0 +1,537 @@
1/*=========================================================================*\
2* Internet domain functions
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6#include "inet.h"
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12/*=========================================================================*\
13* Internal function prototypes.
14\*=========================================================================*/
15static int inet_global_toip(lua_State *L);
16static int inet_global_getaddrinfo(lua_State *L);
17static int inet_global_tohostname(lua_State *L);
18static int inet_global_getnameinfo(lua_State *L);
19static void inet_pushresolved(lua_State *L, struct hostent *hp);
20static int inet_global_gethostname(lua_State *L);
21
22/* DNS functions */
23static luaL_Reg func[] = {
24 { "toip", inet_global_toip},
25 { "getaddrinfo", inet_global_getaddrinfo},
26 { "tohostname", inet_global_tohostname},
27 { "getnameinfo", inet_global_getnameinfo},
28 { "gethostname", inet_global_gethostname},
29 { NULL, NULL}
30};
31
32/*-------------------------------------------------------------------------*\
33* Initializes module
34\*-------------------------------------------------------------------------*/
35int inet_open(lua_State *L)
36{
37 lua_pushstring(L, "dns");
38 lua_newtable(L);
39 luaL_setfuncs(L, func, 0);
40 lua_settable(L, -3);
41 return 0;
42}
43
44/*=========================================================================*\
45* Global Lua functions
46\*=========================================================================*/
47/*-------------------------------------------------------------------------*\
48* Returns all information provided by the resolver given a host name
49* or ip address
50\*-------------------------------------------------------------------------*/
51static int inet_gethost(const char *address, struct hostent **hp) {
52 struct in_addr addr;
53 if (inet_aton(address, &addr))
54 return socket_gethostbyaddr((char *) &addr, sizeof(addr), hp);
55 else
56 return socket_gethostbyname(address, hp);
57}
58
59/*-------------------------------------------------------------------------*\
60* Returns all information provided by the resolver given a host name
61* or ip address
62\*-------------------------------------------------------------------------*/
63static int inet_global_tohostname(lua_State *L) {
64 const char *address = luaL_checkstring(L, 1);
65 struct hostent *hp = NULL;
66 int err = inet_gethost(address, &hp);
67 if (err != IO_DONE) {
68 lua_pushnil(L);
69 lua_pushstring(L, socket_hoststrerror(err));
70 return 2;
71 }
72 lua_pushstring(L, hp->h_name);
73 inet_pushresolved(L, hp);
74 return 2;
75}
76
77static int inet_global_getnameinfo(lua_State *L) {
78 char hbuf[NI_MAXHOST];
79 char sbuf[NI_MAXSERV];
80 int i, ret;
81 struct addrinfo hints;
82 struct addrinfo *resolved, *iter;
83 const char *host = luaL_optstring(L, 1, NULL);
84 const char *serv = luaL_optstring(L, 2, NULL);
85
86 if (!(host || serv))
87 luaL_error(L, "host and serv cannot be both nil");
88
89 memset(&hints, 0, sizeof(hints));
90 hints.ai_socktype = SOCK_STREAM;
91 hints.ai_family = AF_UNSPEC;
92
93 ret = getaddrinfo(host, serv, &hints, &resolved);
94 if (ret != 0) {
95 lua_pushnil(L);
96 lua_pushstring(L, socket_gaistrerror(ret));
97 return 2;
98 }
99
100 lua_newtable(L);
101 for (i = 1, iter = resolved; iter; i++, iter = iter->ai_next) {
102 getnameinfo(iter->ai_addr, (socklen_t) iter->ai_addrlen,
103 hbuf, host? (socklen_t) sizeof(hbuf): 0,
104 sbuf, serv? (socklen_t) sizeof(sbuf): 0, 0);
105 if (host) {
106 lua_pushnumber(L, i);
107 lua_pushstring(L, hbuf);
108 lua_settable(L, -3);
109 }
110 }
111 freeaddrinfo(resolved);
112
113 if (serv) {
114 lua_pushstring(L, sbuf);
115 return 2;
116 } else {
117 return 1;
118 }
119}
120
121/*-------------------------------------------------------------------------*\
122* Returns all information provided by the resolver given a host name
123* or ip address
124\*-------------------------------------------------------------------------*/
125static int inet_global_toip(lua_State *L)
126{
127 const char *address = luaL_checkstring(L, 1);
128 struct hostent *hp = NULL;
129 int err = inet_gethost(address, &hp);
130 if (err != IO_DONE) {
131 lua_pushnil(L);
132 lua_pushstring(L, socket_hoststrerror(err));
133 return 2;
134 }
135 lua_pushstring(L, inet_ntoa(*((struct in_addr *) hp->h_addr)));
136 inet_pushresolved(L, hp);
137 return 2;
138}
139
140int inet_optfamily(lua_State* L, int narg, const char* def)
141{
142 static const char* optname[] = { "unspec", "inet", "inet6", NULL };
143 static int optvalue[] = { AF_UNSPEC, AF_INET, AF_INET6, 0 };
144
145 return optvalue[luaL_checkoption(L, narg, def, optname)];
146}
147
148int inet_optsocktype(lua_State* L, int narg, const char* def)
149{
150 static const char* optname[] = { "stream", "dgram", NULL };
151 static int optvalue[] = { SOCK_STREAM, SOCK_DGRAM, 0 };
152
153 return optvalue[luaL_checkoption(L, narg, def, optname)];
154}
155
156static int inet_global_getaddrinfo(lua_State *L)
157{
158 const char *hostname = luaL_checkstring(L, 1);
159 struct addrinfo *iterator = NULL, *resolved = NULL;
160 struct addrinfo hints;
161 int i = 1, ret = 0;
162 memset(&hints, 0, sizeof(hints));
163 hints.ai_socktype = SOCK_STREAM;
164 hints.ai_family = AF_UNSPEC;
165 ret = getaddrinfo(hostname, NULL, &hints, &resolved);
166 if (ret != 0) {
167 lua_pushnil(L);
168 lua_pushstring(L, socket_gaistrerror(ret));
169 return 2;
170 }
171 lua_newtable(L);
172 for (iterator = resolved; iterator; iterator = iterator->ai_next) {
173 char hbuf[NI_MAXHOST];
174 ret = getnameinfo(iterator->ai_addr, (socklen_t) iterator->ai_addrlen,
175 hbuf, (socklen_t) sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
176 if (ret){
177 freeaddrinfo(resolved);
178 lua_pushnil(L);
179 lua_pushstring(L, socket_gaistrerror(ret));
180 return 2;
181 }
182 lua_pushnumber(L, i);
183 lua_newtable(L);
184 switch (iterator->ai_family) {
185 case AF_INET:
186 lua_pushliteral(L, "family");
187 lua_pushliteral(L, "inet");
188 lua_settable(L, -3);
189 break;
190 case AF_INET6:
191 lua_pushliteral(L, "family");
192 lua_pushliteral(L, "inet6");
193 lua_settable(L, -3);
194 break;
195 case AF_UNSPEC:
196 lua_pushliteral(L, "family");
197 lua_pushliteral(L, "unspec");
198 lua_settable(L, -3);
199 break;
200 default:
201 lua_pushliteral(L, "family");
202 lua_pushliteral(L, "unknown");
203 lua_settable(L, -3);
204 break;
205 }
206 lua_pushliteral(L, "addr");
207 lua_pushstring(L, hbuf);
208 lua_settable(L, -3);
209 lua_settable(L, -3);
210 i++;
211 }
212 freeaddrinfo(resolved);
213 return 1;
214}
215
216/*-------------------------------------------------------------------------*\
217* Gets the host name
218\*-------------------------------------------------------------------------*/
219static int inet_global_gethostname(lua_State *L)
220{
221 char name[257];
222 name[256] = '\0';
223 if (gethostname(name, 256) < 0) {
224 lua_pushnil(L);
225 lua_pushstring(L, socket_strerror(errno));
226 return 2;
227 } else {
228 lua_pushstring(L, name);
229 return 1;
230 }
231}
232
233/*=========================================================================*\
234* Lua methods
235\*=========================================================================*/
236/*-------------------------------------------------------------------------*\
237* Retrieves socket peer name
238\*-------------------------------------------------------------------------*/
239int inet_meth_getpeername(lua_State *L, p_socket ps, int family)
240{
241 int err;
242 struct sockaddr_storage peer;
243 socklen_t peer_len = sizeof(peer);
244 char name[INET6_ADDRSTRLEN];
245 char port[6]; /* 65535 = 5 bytes + 0 to terminate it */
246 if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) {
247 lua_pushnil(L);
248 lua_pushstring(L, socket_strerror(errno));
249 return 2;
250 }
251 err = getnameinfo((struct sockaddr *) &peer, peer_len,
252 name, INET6_ADDRSTRLEN,
253 port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
254 if (err) {
255 lua_pushnil(L);
256 lua_pushstring(L, LUA_GAI_STRERROR(err));
257 return 2;
258 }
259 lua_pushstring(L, name);
260 lua_pushinteger(L, (int) strtol(port, (char **) NULL, 10));
261 switch (family) {
262 case AF_INET: lua_pushliteral(L, "inet"); break;
263 case AF_INET6: lua_pushliteral(L, "inet6"); break;
264 case AF_UNSPEC: lua_pushliteral(L, "unspec"); break;
265 default: lua_pushliteral(L, "unknown"); break;
266 }
267 return 3;
268}
269
270/*-------------------------------------------------------------------------*\
271* Retrieves socket local name
272\*-------------------------------------------------------------------------*/
273int inet_meth_getsockname(lua_State *L, p_socket ps, int family)
274{
275 int err;
276 struct sockaddr_storage peer;
277 socklen_t peer_len = sizeof(peer);
278 char name[INET6_ADDRSTRLEN];
279 char port[6]; /* 65535 = 5 bytes + 0 to terminate it */
280 if (getsockname(*ps, (SA *) &peer, &peer_len) < 0) {
281 lua_pushnil(L);
282 lua_pushstring(L, socket_strerror(errno));
283 return 2;
284 }
285 err=getnameinfo((struct sockaddr *)&peer, peer_len,
286 name, INET6_ADDRSTRLEN, port, 6, NI_NUMERICHOST | NI_NUMERICSERV);
287 if (err) {
288 lua_pushnil(L);
289 lua_pushstring(L, LUA_GAI_STRERROR(err));
290 return 2;
291 }
292 lua_pushstring(L, name);
293 lua_pushstring(L, port);
294 switch (family) {
295 case AF_INET: lua_pushliteral(L, "inet"); break;
296 case AF_INET6: lua_pushliteral(L, "inet6"); break;
297 case AF_UNSPEC: lua_pushliteral(L, "unspec"); break;
298 default: lua_pushliteral(L, "unknown"); break;
299 }
300 return 3;
301}
302
303/*=========================================================================*\
304* Internal functions
305\*=========================================================================*/
306/*-------------------------------------------------------------------------*\
307* Passes all resolver information to Lua as a table
308\*-------------------------------------------------------------------------*/
309static void inet_pushresolved(lua_State *L, struct hostent *hp)
310{
311 char **alias;
312 struct in_addr **addr;
313 int i, resolved;
314 lua_newtable(L); resolved = lua_gettop(L);
315 lua_pushstring(L, "name");
316 lua_pushstring(L, hp->h_name);
317 lua_settable(L, resolved);
318 lua_pushstring(L, "ip");
319 lua_pushstring(L, "alias");
320 i = 1;
321 alias = hp->h_aliases;
322 lua_newtable(L);
323 if (alias) {
324 while (*alias) {
325 lua_pushnumber(L, i);
326 lua_pushstring(L, *alias);
327 lua_settable(L, -3);
328 i++; alias++;
329 }
330 }
331 lua_settable(L, resolved);
332 i = 1;
333 lua_newtable(L);
334 addr = (struct in_addr **) hp->h_addr_list;
335 if (addr) {
336 while (*addr) {
337 lua_pushnumber(L, i);
338 lua_pushstring(L, inet_ntoa(**addr));
339 lua_settable(L, -3);
340 i++; addr++;
341 }
342 }
343 lua_settable(L, resolved);
344}
345
346/*-------------------------------------------------------------------------*\
347* Tries to create a new inet socket
348\*-------------------------------------------------------------------------*/
349const char *inet_trycreate(p_socket ps, int family, int type, int protocol) {
350 const char *err = socket_strerror(socket_create(ps, family, type, protocol));
351 if (err == NULL && family == AF_INET6) {
352 int yes = 1;
353 setsockopt(*ps, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&yes, sizeof(yes));
354 }
355 return err;
356}
357
358/*-------------------------------------------------------------------------*\
359* "Disconnects" a DGRAM socket
360\*-------------------------------------------------------------------------*/
361const char *inet_trydisconnect(p_socket ps, int family, p_timeout tm)
362{
363 switch (family) {
364 case AF_INET: {
365 struct sockaddr_in sin;
366 memset((char *) &sin, 0, sizeof(sin));
367 sin.sin_family = AF_UNSPEC;
368 sin.sin_addr.s_addr = INADDR_ANY;
369 return socket_strerror(socket_connect(ps, (SA *) &sin,
370 sizeof(sin), tm));
371 }
372 case AF_INET6: {
373 struct sockaddr_in6 sin6;
374 struct in6_addr addrany = IN6ADDR_ANY_INIT;
375 memset((char *) &sin6, 0, sizeof(sin6));
376 sin6.sin6_family = AF_UNSPEC;
377 sin6.sin6_addr = addrany;
378 return socket_strerror(socket_connect(ps, (SA *) &sin6,
379 sizeof(sin6), tm));
380 }
381 }
382 return NULL;
383}
384
385/*-------------------------------------------------------------------------*\
386* Tries to connect to remote address (address, port)
387\*-------------------------------------------------------------------------*/
388const char *inet_tryconnect(p_socket ps, int *family, const char *address,
389 const char *serv, p_timeout tm, struct addrinfo *connecthints)
390{
391 struct addrinfo *iterator = NULL, *resolved = NULL;
392 const char *err = NULL;
393 int current_family = *family;
394 /* try resolving */
395 err = socket_gaistrerror(getaddrinfo(address, serv,
396 connecthints, &resolved));
397 if (err != NULL) {
398 if (resolved) freeaddrinfo(resolved);
399 return err;
400 }
401 for (iterator = resolved; iterator; iterator = iterator->ai_next) {
402 timeout_markstart(tm);
403 /* create new socket if necessary. if there was no
404 * bind, we need to create one for every new family
405 * that shows up while iterating. if there was a
406 * bind, all families will be the same and we will
407 * not enter this branch. */
408 if (current_family != iterator->ai_family || *ps == SOCKET_INVALID) {
409 socket_destroy(ps);
410 err = inet_trycreate(ps, iterator->ai_family,
411 iterator->ai_socktype, iterator->ai_protocol);
412 if (err) continue;
413 current_family = iterator->ai_family;
414 /* set non-blocking before connect */
415 socket_setnonblocking(ps);
416 }
417 /* try connecting to remote address */
418 err = socket_strerror(socket_connect(ps, (SA *) iterator->ai_addr,
419 (socklen_t) iterator->ai_addrlen, tm));
420 /* if success or timeout is zero, break out of loop */
421 if (err == NULL || timeout_iszero(tm)) {
422 *family = current_family;
423 break;
424 }
425 }
426 freeaddrinfo(resolved);
427 /* here, if err is set, we failed */
428 return err;
429}
430
431/*-------------------------------------------------------------------------*\
432* Tries to accept a socket
433\*-------------------------------------------------------------------------*/
434const char *inet_tryaccept(p_socket server, int family, p_socket client,
435 p_timeout tm) {
436 socklen_t len;
437 t_sockaddr_storage addr;
438 switch (family) {
439 case AF_INET6: len = sizeof(struct sockaddr_in6); break;
440 case AF_INET: len = sizeof(struct sockaddr_in); break;
441 default: len = sizeof(addr); break;
442 }
443 return socket_strerror(socket_accept(server, client, (SA *) &addr,
444 &len, tm));
445}
446
447/*-------------------------------------------------------------------------*\
448* Tries to bind socket to (address, port)
449\*-------------------------------------------------------------------------*/
450const char *inet_trybind(p_socket ps, int *family, const char *address,
451 const char *serv, struct addrinfo *bindhints) {
452 struct addrinfo *iterator = NULL, *resolved = NULL;
453 const char *err = NULL;
454 int current_family = *family;
455 /* translate luasocket special values to C */
456 if (strcmp(address, "*") == 0) address = NULL;
457 if (!serv) serv = "0";
458 /* try resolving */
459 err = socket_gaistrerror(getaddrinfo(address, serv, bindhints, &resolved));
460 if (err) {
461 if (resolved) freeaddrinfo(resolved);
462 return err;
463 }
464 /* iterate over resolved addresses until one is good */
465 for (iterator = resolved; iterator; iterator = iterator->ai_next) {
466 if (current_family != iterator->ai_family || *ps == SOCKET_INVALID) {
467 socket_destroy(ps);
468 err = inet_trycreate(ps, iterator->ai_family,
469 iterator->ai_socktype, iterator->ai_protocol);
470 if (err) continue;
471 current_family = iterator->ai_family;
472 }
473 /* try binding to local address */
474 err = socket_strerror(socket_bind(ps, (SA *) iterator->ai_addr,
475 (socklen_t) iterator->ai_addrlen));
476 /* keep trying unless bind succeeded */
477 if (err == NULL) {
478 *family = current_family;
479 /* set to non-blocking after bind */
480 socket_setnonblocking(ps);
481 break;
482 }
483 }
484 /* cleanup and return error */
485 freeaddrinfo(resolved);
486 /* here, if err is set, we failed */
487 return err;
488}
489
490/*-------------------------------------------------------------------------*\
491* Some systems do not provide these so that we provide our own.
492\*-------------------------------------------------------------------------*/
493#ifdef LUASOCKET_INET_ATON
494int inet_aton(const char *cp, struct in_addr *inp)
495{
496 unsigned int a = 0, b = 0, c = 0, d = 0;
497 int n = 0, r;
498 unsigned long int addr = 0;
499 r = sscanf(cp, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n);
500 if (r == 0 || n == 0) return 0;
501 cp += n;
502 if (*cp) return 0;
503 if (a > 255 || b > 255 || c > 255 || d > 255) return 0;
504 if (inp) {
505 addr += a; addr <<= 8;
506 addr += b; addr <<= 8;
507 addr += c; addr <<= 8;
508 addr += d;
509 inp->s_addr = htonl(addr);
510 }
511 return 1;
512}
513#endif
514
515#ifdef LUASOCKET_INET_PTON
516int inet_pton(int af, const char *src, void *dst)
517{
518 struct addrinfo hints, *res;
519 int ret = 1;
520 memset(&hints, 0, sizeof(struct addrinfo));
521 hints.ai_family = af;
522 hints.ai_flags = AI_NUMERICHOST;
523 if (getaddrinfo(src, NULL, &hints, &res) != 0) return -1;
524 if (af == AF_INET) {
525 struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr;
526 memcpy(dst, &in->sin_addr, sizeof(in->sin_addr));
527 } else if (af == AF_INET6) {
528 struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr;
529 memcpy(dst, &in->sin6_addr, sizeof(in->sin6_addr));
530 } else {
531 ret = -1;
532 }
533 freeaddrinfo(res);
534 return ret;
535}
536
537#endif
diff --git a/vendor/luasocket/src/inet.h b/vendor/luasocket/src/inet.h
new file mode 100644
index 00000000..5618b61b
--- /dev/null
+++ b/vendor/luasocket/src/inet.h
@@ -0,0 +1,56 @@
1#ifndef INET_H
2#define INET_H
3/*=========================================================================*\
4* Internet domain functions
5* LuaSocket toolkit
6*
7* This module implements the creation and connection of internet domain
8* sockets, on top of the socket.h interface, and the interface of with the
9* resolver.
10*
11* The function inet_aton is provided for the platforms where it is not
12* available. The module also implements the interface of the internet
13* getpeername and getsockname functions as seen by Lua programs.
14*
15* The Lua functions toip and tohostname are also implemented here.
16\*=========================================================================*/
17#include "luasocket.h"
18#include "socket.h"
19#include "timeout.h"
20
21#ifdef _WIN32
22#define LUASOCKET_INET_ATON
23#endif
24
25#ifndef _WIN32
26#pragma GCC visibility push(hidden)
27#endif
28
29int inet_open(lua_State *L);
30
31int inet_optfamily(lua_State* L, int narg, const char* def);
32int inet_optsocktype(lua_State* L, int narg, const char* def);
33
34int inet_meth_getpeername(lua_State *L, p_socket ps, int family);
35int inet_meth_getsockname(lua_State *L, p_socket ps, int family);
36
37const char *inet_trycreate(p_socket ps, int family, int type, int protocol);
38const char *inet_trydisconnect(p_socket ps, int family, p_timeout tm);
39const char *inet_tryconnect(p_socket ps, int *family, const char *address, const char *serv, p_timeout tm, struct addrinfo *connecthints);
40const char *inet_tryaccept(p_socket server, int family, p_socket client, p_timeout tm);
41const char *inet_trybind(p_socket ps, int *family, const char *address, const char *serv, struct addrinfo *bindhints);
42
43#ifdef LUASOCKET_INET_ATON
44int inet_aton(const char *cp, struct in_addr *inp);
45#endif
46
47#ifdef LUASOCKET_INET_PTON
48const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
49int inet_pton(int af, const char *src, void *dst);
50#endif
51
52#ifndef _WIN32
53#pragma GCC visibility pop
54#endif
55
56#endif /* INET_H */
diff --git a/vendor/luasocket/src/io.c b/vendor/luasocket/src/io.c
new file mode 100644
index 00000000..5ad4b3af
--- /dev/null
+++ b/vendor/luasocket/src/io.c
@@ -0,0 +1,28 @@
1/*=========================================================================*\
2* Input/Output abstraction
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6#include "io.h"
7
8/*-------------------------------------------------------------------------*\
9* Initializes C structure
10\*-------------------------------------------------------------------------*/
11void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx) {
12 io->send = send;
13 io->recv = recv;
14 io->error = error;
15 io->ctx = ctx;
16}
17
18/*-------------------------------------------------------------------------*\
19* I/O error strings
20\*-------------------------------------------------------------------------*/
21const char *io_strerror(int err) {
22 switch (err) {
23 case IO_DONE: return NULL;
24 case IO_CLOSED: return "closed";
25 case IO_TIMEOUT: return "timeout";
26 default: return "unknown error";
27 }
28}
diff --git a/vendor/luasocket/src/io.h b/vendor/luasocket/src/io.h
new file mode 100644
index 00000000..b8a54df6
--- /dev/null
+++ b/vendor/luasocket/src/io.h
@@ -0,0 +1,70 @@
1#ifndef IO_H
2#define IO_H
3/*=========================================================================*\
4* Input/Output abstraction
5* LuaSocket toolkit
6*
7* This module defines the interface that LuaSocket expects from the
8* transport layer for streamed input/output. The idea is that if any
9* transport implements this interface, then the buffer.c functions
10* automatically work on it.
11*
12* The module socket.h implements this interface, and thus the module tcp.h
13* is very simple.
14\*=========================================================================*/
15#include "luasocket.h"
16#include "timeout.h"
17
18/* IO error codes */
19enum {
20 IO_DONE = 0, /* operation completed successfully */
21 IO_TIMEOUT = -1, /* operation timed out */
22 IO_CLOSED = -2, /* the connection has been closed */
23 IO_UNKNOWN = -3
24};
25
26/* interface to error message function */
27typedef const char *(*p_error) (
28 void *ctx, /* context needed by send */
29 int err /* error code */
30);
31
32/* interface to send function */
33typedef int (*p_send) (
34 void *ctx, /* context needed by send */
35 const char *data, /* pointer to buffer with data to send */
36 size_t count, /* number of bytes to send from buffer */
37 size_t *sent, /* number of bytes sent uppon return */
38 p_timeout tm /* timeout control */
39);
40
41/* interface to recv function */
42typedef int (*p_recv) (
43 void *ctx, /* context needed by recv */
44 char *data, /* pointer to buffer where data will be writen */
45 size_t count, /* number of bytes to receive into buffer */
46 size_t *got, /* number of bytes received uppon return */
47 p_timeout tm /* timeout control */
48);
49
50/* IO driver definition */
51typedef struct t_io_ {
52 void *ctx; /* context needed by send/recv */
53 p_send send; /* send function pointer */
54 p_recv recv; /* receive function pointer */
55 p_error error; /* strerror function */
56} t_io;
57typedef t_io *p_io;
58
59#ifndef _WIN32
60#pragma GCC visibility push(hidden)
61#endif
62
63void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx);
64const char *io_strerror(int err);
65
66#ifndef _WIN32
67#pragma GCC visibility pop
68#endif
69
70#endif /* IO_H */
diff --git a/vendor/luasocket/src/ltn12.lua b/vendor/luasocket/src/ltn12.lua
new file mode 100644
index 00000000..4cb17f53
--- /dev/null
+++ b/vendor/luasocket/src/ltn12.lua
@@ -0,0 +1,318 @@
1-----------------------------------------------------------------------------
2-- LTN12 - Filters, sources, sinks and pumps.
3-- LuaSocket toolkit.
4-- Author: Diego Nehab
5-----------------------------------------------------------------------------
6
7-----------------------------------------------------------------------------
8-- Declare module
9-----------------------------------------------------------------------------
10local string = require("string")
11local table = require("table")
12local unpack = unpack or table.unpack
13local base = _G
14local select = select
15
16local _M = {}
17if module then -- heuristic for exporting a global package table
18 ltn12 = _M -- luacheck: ignore
19end
20local filter,source,sink,pump = {},{},{},{}
21
22_M.filter = filter
23_M.source = source
24_M.sink = sink
25_M.pump = pump
26
27-- 2048 seems to be better in windows...
28_M.BLOCKSIZE = 2048
29_M._VERSION = "LTN12 1.0.3"
30
31-----------------------------------------------------------------------------
32-- Filter stuff
33-----------------------------------------------------------------------------
34-- returns a high level filter that cycles a low-level filter
35function filter.cycle(low, ctx, extra)
36 base.assert(low)
37 return function(chunk)
38 local ret
39 ret, ctx = low(ctx, chunk, extra)
40 return ret
41 end
42end
43
44-- chains a bunch of filters together
45-- (thanks to Wim Couwenberg)
46function filter.chain(...)
47 local arg = {...}
48 local n = select('#',...)
49 local top, index = 1, 1
50 local retry = ""
51 return function(chunk)
52 retry = chunk and retry
53 while true do
54 if index == top then
55 chunk = arg[index](chunk)
56 if chunk == "" or top == n then return chunk
57 elseif chunk then index = index + 1
58 else
59 top = top+1
60 index = top
61 end
62 else
63 chunk = arg[index](chunk or "")
64 if chunk == "" then
65 index = index - 1
66 chunk = retry
67 elseif chunk then
68 if index == n then return chunk
69 else index = index + 1 end
70 else base.error("filter returned inappropriate nil") end
71 end
72 end
73 end
74end
75
76-----------------------------------------------------------------------------
77-- Source stuff
78-----------------------------------------------------------------------------
79-- create an empty source
80local function empty()
81 return nil
82end
83
84function source.empty()
85 return empty
86end
87
88-- returns a source that just outputs an error
89function source.error(err)
90 return function()
91 return nil, err
92 end
93end
94
95-- creates a file source
96function source.file(handle, io_err)
97 if handle then
98 return function()
99 local chunk = handle:read(_M.BLOCKSIZE)
100 if not chunk then handle:close() end
101 return chunk
102 end
103 else return source.error(io_err or "unable to open file") end
104end
105
106-- turns a fancy source into a simple source
107function source.simplify(src)
108 base.assert(src)
109 return function()
110 local chunk, err_or_new = src()
111 src = err_or_new or src
112 if not chunk then return nil, err_or_new
113 else return chunk end
114 end
115end
116
117-- creates string source
118function source.string(s)
119 if s then
120 local i = 1
121 return function()
122 local chunk = string.sub(s, i, i+_M.BLOCKSIZE-1)
123 i = i + _M.BLOCKSIZE
124 if chunk ~= "" then return chunk
125 else return nil end
126 end
127 else return source.empty() end
128end
129
130-- creates table source
131function source.table(t)
132 base.assert('table' == type(t))
133 local i = 0
134 return function()
135 i = i + 1
136 return t[i]
137 end
138end
139
140-- creates rewindable source
141function source.rewind(src)
142 base.assert(src)
143 local t = {}
144 return function(chunk)
145 if not chunk then
146 chunk = table.remove(t)
147 if not chunk then return src()
148 else return chunk end
149 else
150 table.insert(t, chunk)
151 end
152 end
153end
154
155-- chains a source with one or several filter(s)
156function source.chain(src, f, ...)
157 if ... then f=filter.chain(f, ...) end
158 base.assert(src and f)
159 local last_in, last_out = "", ""
160 local state = "feeding"
161 local err
162 return function()
163 if not last_out then
164 base.error('source is empty!', 2)
165 end
166 while true do
167 if state == "feeding" then
168 last_in, err = src()
169 if err then return nil, err end
170 last_out = f(last_in)
171 if not last_out then
172 if last_in then
173 base.error('filter returned inappropriate nil')
174 else
175 return nil
176 end
177 elseif last_out ~= "" then
178 state = "eating"
179 if last_in then last_in = "" end
180 return last_out
181 end
182 else
183 last_out = f(last_in)
184 if last_out == "" then
185 if last_in == "" then
186 state = "feeding"
187 else
188 base.error('filter returned ""')
189 end
190 elseif not last_out then
191 if last_in then
192 base.error('filter returned inappropriate nil')
193 else
194 return nil
195 end
196 else
197 return last_out
198 end
199 end
200 end
201 end
202end
203
204-- creates a source that produces contents of several sources, one after the
205-- other, as if they were concatenated
206-- (thanks to Wim Couwenberg)
207function source.cat(...)
208 local arg = {...}
209 local src = table.remove(arg, 1)
210 return function()
211 while src do
212 local chunk, err = src()
213 if chunk then return chunk end
214 if err then return nil, err end
215 src = table.remove(arg, 1)
216 end
217 end
218end
219
220-----------------------------------------------------------------------------
221-- Sink stuff
222-----------------------------------------------------------------------------
223-- creates a sink that stores into a table
224function sink.table(t)
225 t = t or {}
226 local f = function(chunk, err)
227 if chunk then table.insert(t, chunk) end
228 return 1
229 end
230 return f, t
231end
232
233-- turns a fancy sink into a simple sink
234function sink.simplify(snk)
235 base.assert(snk)
236 return function(chunk, err)
237 local ret, err_or_new = snk(chunk, err)
238 if not ret then return nil, err_or_new end
239 snk = err_or_new or snk
240 return 1
241 end
242end
243
244-- creates a file sink
245function sink.file(handle, io_err)
246 if handle then
247 return function(chunk, err)
248 if not chunk then
249 handle:close()
250 return 1
251 else return handle:write(chunk) end
252 end
253 else return sink.error(io_err or "unable to open file") end
254end
255
256-- creates a sink that discards data
257local function null()
258 return 1
259end
260
261function sink.null()
262 return null
263end
264
265-- creates a sink that just returns an error
266function sink.error(err)
267 return function()
268 return nil, err
269 end
270end
271
272-- chains a sink with one or several filter(s)
273function sink.chain(f, snk, ...)
274 if ... then
275 local args = { f, snk, ... }
276 snk = table.remove(args, #args)
277 f = filter.chain(unpack(args))
278 end
279 base.assert(f and snk)
280 return function(chunk, err)
281 if chunk ~= "" then
282 local filtered = f(chunk)
283 local done = chunk and ""
284 while true do
285 local ret, snkerr = snk(filtered, err)
286 if not ret then return nil, snkerr end
287 if filtered == done then return 1 end
288 filtered = f(done)
289 end
290 else return 1 end
291 end
292end
293
294-----------------------------------------------------------------------------
295-- Pump stuff
296-----------------------------------------------------------------------------
297-- pumps one chunk from the source to the sink
298function pump.step(src, snk)
299 local chunk, src_err = src()
300 local ret, snk_err = snk(chunk, src_err)
301 if chunk and ret then return 1
302 else return nil, src_err or snk_err end
303end
304
305-- pumps all data from a source to a sink, using a step function
306function pump.all(src, snk, step)
307 base.assert(src and snk)
308 step = step or pump.step
309 while true do
310 local ret, err = step(src, snk)
311 if not ret then
312 if err then return nil, err
313 else return 1 end
314 end
315 end
316end
317
318return _M
diff --git a/vendor/luasocket/src/luasocket.c b/vendor/luasocket/src/luasocket.c
new file mode 100755
index 00000000..0fd99f70
--- /dev/null
+++ b/vendor/luasocket/src/luasocket.c
@@ -0,0 +1,104 @@
1/*=========================================================================*\
2* LuaSocket toolkit
3* Networking support for the Lua language
4* Diego Nehab
5* 26/11/1999
6*
7* This library is part of an effort to progressively increase the network
8* connectivity of the Lua language. The Lua interface to networking
9* functions follows the Sockets API closely, trying to simplify all tasks
10* involved in setting up both client and server connections. The provided
11* IO routines, however, follow the Lua style, being very similar to the
12* standard Lua read and write functions.
13\*=========================================================================*/
14
15#include "luasocket.h"
16#include "auxiliar.h"
17#include "except.h"
18#include "timeout.h"
19#include "buffer.h"
20#include "inet.h"
21#include "tcp.h"
22#include "udp.h"
23#include "select.h"
24
25/*-------------------------------------------------------------------------*\
26* Internal function prototypes
27\*-------------------------------------------------------------------------*/
28static int global_skip(lua_State *L);
29static int global_unload(lua_State *L);
30static int base_open(lua_State *L);
31
32/*-------------------------------------------------------------------------*\
33* Modules and functions
34\*-------------------------------------------------------------------------*/
35static const luaL_Reg mod[] = {
36 {"auxiliar", auxiliar_open},
37 {"except", except_open},
38 {"timeout", timeout_open},
39 {"buffer", buffer_open},
40 {"inet", inet_open},
41 {"tcp", tcp_open},
42 {"udp", udp_open},
43 {"select", select_open},
44 {NULL, NULL}
45};
46
47static luaL_Reg func[] = {
48 {"skip", global_skip},
49 {"__unload", global_unload},
50 {NULL, NULL}
51};
52
53/*-------------------------------------------------------------------------*\
54* Skip a few arguments
55\*-------------------------------------------------------------------------*/
56static int global_skip(lua_State *L) {
57 int amount = (int) luaL_checkinteger(L, 1);
58 int ret = lua_gettop(L) - amount - 1;
59 return ret >= 0 ? ret : 0;
60}
61
62/*-------------------------------------------------------------------------*\
63* Unloads the library
64\*-------------------------------------------------------------------------*/
65static int global_unload(lua_State *L) {
66 (void) L;
67 socket_close();
68 return 0;
69}
70
71/*-------------------------------------------------------------------------*\
72* Setup basic stuff.
73\*-------------------------------------------------------------------------*/
74static int base_open(lua_State *L) {
75 if (socket_open()) {
76 /* export functions (and leave namespace table on top of stack) */
77 lua_newtable(L);
78 luaL_setfuncs(L, func, 0);
79#ifdef LUASOCKET_DEBUG
80 lua_pushstring(L, "_DEBUG");
81 lua_pushboolean(L, 1);
82 lua_rawset(L, -3);
83#endif
84 /* make version string available to scripts */
85 lua_pushstring(L, "_VERSION");
86 lua_pushstring(L, LUASOCKET_VERSION);
87 lua_rawset(L, -3);
88 return 1;
89 } else {
90 lua_pushstring(L, "unable to initialize library");
91 lua_error(L);
92 return 0;
93 }
94}
95
96/*-------------------------------------------------------------------------*\
97* Initializes all library modules.
98\*-------------------------------------------------------------------------*/
99LUASOCKET_API int luaopen_socket_core(lua_State *L) {
100 int i;
101 base_open(L);
102 for (i = 0; mod[i].name; i++) mod[i].func(L);
103 return 1;
104}
diff --git a/vendor/luasocket/src/luasocket.h b/vendor/luasocket/src/luasocket.h
new file mode 100644
index 00000000..1017fbaa
--- /dev/null
+++ b/vendor/luasocket/src/luasocket.h
@@ -0,0 +1,36 @@
1#ifndef LUASOCKET_H
2#define LUASOCKET_H
3/*=========================================================================*\
4* LuaSocket toolkit
5* Networking support for the Lua language
6* Diego Nehab
7* 9/11/1999
8\*=========================================================================*/
9
10/*-------------------------------------------------------------------------* \
11* Current socket library version
12\*-------------------------------------------------------------------------*/
13#define LUASOCKET_VERSION "LuaSocket 3.0.0"
14#define LUASOCKET_COPYRIGHT "Copyright (C) 1999-2013 Diego Nehab"
15
16/*-------------------------------------------------------------------------*\
17* This macro prefixes all exported API functions
18\*-------------------------------------------------------------------------*/
19#ifndef LUASOCKET_API
20#ifdef _WIN32
21#define LUASOCKET_API __declspec(dllexport)
22#else
23#define LUASOCKET_API __attribute__ ((visibility ("default")))
24#endif
25#endif
26
27#include "lua.h"
28#include "lauxlib.h"
29#include "compat.h"
30
31/*-------------------------------------------------------------------------*\
32* Initializes the library.
33\*-------------------------------------------------------------------------*/
34LUASOCKET_API int luaopen_socket_core(lua_State *L);
35
36#endif /* LUASOCKET_H */
diff --git a/vendor/luasocket/src/makefile b/vendor/luasocket/src/makefile
new file mode 100755
index 00000000..06f4d192
--- /dev/null
+++ b/vendor/luasocket/src/makefile
@@ -0,0 +1,461 @@
1# luasocket src/makefile
2#
3# Definitions in this section can be overriden on the command line or in the
4# environment.
5#
6# These are equivalent:
7#
8# export PLAT=linux DEBUG=DEBUG LUAV=5.2 prefix=/sw
9# make
10#
11# and
12#
13# make PLAT=linux DEBUG=DEBUG LUAV=5.2 prefix=/sw
14
15# PLAT: linux macosx win32 win64 mingw
16# platform to build for
17PLAT?=linux
18
19# LUAV: 5.1 5.2 5.3 5.4
20# lua version to build against
21LUAV?=5.1
22
23# MYCFLAGS: to be set by user if needed
24MYCFLAGS?=
25
26# MYLDFLAGS: to be set by user if needed
27MYLDFLAGS?=
28
29# DEBUG: NODEBUG DEBUG
30# debug mode causes luasocket to collect and returns timing information useful
31# for testing and debugging luasocket itself
32DEBUG?=NODEBUG
33
34# where lua headers are found for macosx builds
35# LUAINC_macosx:
36# /opt/local/include
37LUAINC_macosx_base?=/opt/local/include
38LUAINC_macosx?=$(LUAINC_macosx_base)/lua/$(LUAV) $(LUAINC_macosx_base)/lua$(LUAV) $(LUAINC_macosx_base)/lua-$(LUAV)
39
40# FIXME default should this default to fink or to macports?
41# What happens when more than one Lua version is installed?
42LUAPREFIX_macosx?=/opt/local
43CDIR_macosx?=lib/lua/$(LUAV)
44LDIR_macosx?=share/lua/$(LUAV)
45
46# LUAINC_linux:
47# /usr/include/lua$(LUAV)
48# /usr/local/include
49# /usr/local/include/lua$(LUAV)
50# where lua headers are found for linux builds
51LUAINC_linux_base?=/usr/include
52LUAINC_linux?=$(LUAINC_linux_base)/lua/$(LUAV) $(LUAINC_linux_base)/lua$(LUAV)
53LUAPREFIX_linux?=/usr/local
54CDIR_linux?=lib/lua/$(LUAV)
55LDIR_linux?=share/lua/$(LUAV)
56
57# LUAINC_freebsd:
58# /usr/local/include/lua$(LUAV)
59# where lua headers are found for freebsd builds
60LUAINC_freebsd_base?=/usr/local/include/
61LUAINC_freebsd?=$(LUAINC_freebsd_base)/lua/$(LUAV) $(LUAINC_freebsd_base)/lua$(LUAV)
62LUAPREFIX_freebsd?=/usr/local/
63CDIR_freebsd?=lib/lua/$(LUAV)
64LDIR_freebsd?=share/lua/$(LUAV)
65
66# where lua headers are found for mingw builds
67# LUAINC_mingw:
68# /opt/local/include
69LUAINC_mingw_base?=/usr/include
70LUAINC_mingw?=$(LUAINC_mingw_base)/lua/$(LUAV) $(LUAINC_mingw_base)/lua$(LUAV)
71LUALIB_mingw_base?=/usr/bin
72LUALIB_mingw?=$(LUALIB_mingw_base)/lua/$(LUAV)/lua$(subst .,,$(LUAV)).dll
73LUAPREFIX_mingw?=/usr
74CDIR_mingw?=lua/$(LUAV)
75LDIR_mingw?=lua/$(LUAV)/lua
76
77
78# LUAINC_win32:
79# LUALIB_win32:
80# where lua headers and libraries are found for win32 builds
81LUAPREFIX_win32?=
82LUAINC_win32?=$(LUAPREFIX_win32)/include/lua/$(LUAV) $(LUAPREFIX_win32)/include/lua$(LUAV)
83PLATFORM_win32?=Release
84CDIR_win32?=bin/lua/$(LUAV)/$(PLATFORM_win32)
85LDIR_win32?=bin/lua/$(LUAV)/$(PLATFORM_win32)/lua
86LUALIB_win32?=$(LUAPREFIX_win32)/lib/lua/$(LUAV)/$(PLATFORM_win32)
87LUALIBNAME_win32?=lua$(subst .,,$(LUAV)).lib
88
89# LUAINC_win64:
90# LUALIB_win64:
91# where lua headers and libraries are found for win64 builds
92LUAPREFIX_win64?=
93LUAINC_win64?=$(LUAPREFIX_win64)/include/lua/$(LUAV) $(LUAPREFIX_win64)/include/lua$(LUAV)
94PLATFORM_win64?=x64/Release
95CDIR_win64?=bin/lua/$(LUAV)/$(PLATFORM_win64)
96LDIR_win64?=bin/lua/$(LUAV)/$(PLATFORM_win64)/lua
97LUALIB_win64?=$(LUAPREFIX_win64)/lib/lua/$(LUAV)/$(PLATFORM_win64)
98LUALIBNAME_win64?=lua$(subst .,,$(LUAV)).lib
99
100
101# LUAINC_solaris:
102LUAINC_solaris_base?=/usr/include
103LUAINC_solaris?=$(LUAINC_solaris_base)/lua/$(LUAV) $(LUAINC_solaris_base)/lua$(LUAV)
104LUAPREFIX_solaris?=/usr/local
105CDIR_solaris?=lib/lua/$(LUAV)
106LDIR_solaris?=share/lua/$(LUAV)
107
108# prefix: /usr/local /usr /opt/local /sw
109# the top of the default install tree
110prefix?=$(LUAPREFIX_$(PLAT))
111
112CDIR?=$(CDIR_$(PLAT))
113LDIR?=$(LDIR_$(PLAT))
114
115# DESTDIR: (no default)
116# used by package managers to install into a temporary destination
117DESTDIR?=
118
119#------
120# Definitions below can be overridden on the make command line, but
121# shouldn't have to be.
122
123
124#------
125# Install directories
126#
127
128INSTALL_DIR=install -d
129INSTALL_DATA=install -m644
130INSTALL_EXEC=install
131INSTALL_TOP=$(DESTDIR)$(prefix)
132
133INSTALL_TOP_LDIR=$(INSTALL_TOP)/$(LDIR)
134INSTALL_TOP_CDIR=$(INSTALL_TOP)/$(CDIR)
135
136INSTALL_SOCKET_LDIR=$(INSTALL_TOP_LDIR)/socket
137INSTALL_SOCKET_CDIR=$(INSTALL_TOP_CDIR)/socket
138INSTALL_MIME_LDIR=$(INSTALL_TOP_LDIR)/mime
139INSTALL_MIME_CDIR=$(INSTALL_TOP_CDIR)/mime
140
141print:
142 @echo PLAT=$(PLAT)
143 @echo LUAV=$(LUAV)
144 @echo DEBUG=$(DEBUG)
145 @echo prefix=$(prefix)
146 @echo LUAINC_$(PLAT)=$(LUAINC_$(PLAT))
147 @echo LUALIB_$(PLAT)=$(LUALIB_$(PLAT))
148 @echo INSTALL_TOP_CDIR=$(INSTALL_TOP_CDIR)
149 @echo INSTALL_TOP_LDIR=$(INSTALL_TOP_LDIR)
150 @echo CFLAGS=$(CFLAGS)
151 @echo LDFLAGS=$(LDFLAGS)
152
153#------
154# Supported platforms
155#
156PLATS= macosx linux win32 win64 mingw solaris
157
158#------
159# Compiler and linker settings
160# for Mac OS X
161SO_macosx=so
162O_macosx=o
163CC_macosx=gcc
164DEF_macosx= -DLUASOCKET_$(DEBUG) -DUNIX_HAS_SUN_LEN
165CFLAGS_macosx=$(LUAINC:%=-I%) $(DEF) -Wall -O2 -fno-common
166LDFLAGS_macosx= -bundle -undefined dynamic_lookup -o
167LD_macosx=gcc
168SOCKET_macosx=usocket.o
169
170#------
171# Compiler and linker settings
172# for Linux
173SO_linux=so
174O_linux=o
175CC_linux=gcc
176DEF_linux=-DLUASOCKET_$(DEBUG)
177CFLAGS_linux=$(LUAINC:%=-I%) $(DEF) -Wall -Wshadow -Wextra \
178 -Wimplicit -O2 -ggdb3 -fpic
179LDFLAGS_linux=-O -shared -fpic -o
180LD_linux=gcc
181SOCKET_linux=usocket.o
182
183#------
184# Compiler and linker settings
185# for FreeBSD
186SO_freebsd=so
187O_freebsd=o
188CC_freebsd=gcc
189DEF_freebsd=-DLUASOCKET_$(DEBUG) -DUNIX_HAS_SUN_LEN
190CFLAGS_freebsd=$(LUAINC:%=-I%) $(DEF) -Wall -Wshadow -Wextra \
191 -Wimplicit -O2 -ggdb3 -fpic
192LDFLAGS_freebsd=-O -shared -fpic -o
193LD_freebsd=gcc
194SOCKET_freebsd=usocket.o
195
196#------
197# Compiler and linker settings
198# for Solaris
199SO_solaris=so
200O_solaris=o
201CC_solaris=gcc
202DEF_solaris=-DLUASOCKET_$(DEBUG)
203CFLAGS_solaris=$(LUAINC:%=-I%) $(DEF) -Wall -Wshadow -Wextra \
204 -Wimplicit -O2 -ggdb3 -fpic
205LDFLAGS_solaris=-lnsl -lsocket -lresolv -O -shared -fpic -o
206LD_solaris=gcc
207SOCKET_solaris=usocket.o
208
209#------
210# Compiler and linker settings
211# for MingW
212SO_mingw=dll
213O_mingw=o
214CC_mingw=gcc
215DEF_mingw= -DLUASOCKET_$(DEBUG) \
216 -DWINVER=0x0501
217CFLAGS_mingw=$(LUAINC:%=-I%) $(DEF) -Wall -O2 -fno-common
218LDFLAGS_mingw= $(LUALIB) -shared -Wl,-s -lws2_32 -o
219LD_mingw=gcc
220SOCKET_mingw=wsocket.o
221
222
223#------
224# Compiler and linker settings
225# for Win32
226SO_win32=dll
227O_win32=obj
228CC_win32=cl
229DEF_win32= //D "WIN32" //D "NDEBUG" //D "_WINDOWS" //D "_USRDLL" \
230 //D "_CRT_SECURE_NO_WARNINGS" \
231 //D "_WINDLL" \
232 //D "LUASOCKET_$(DEBUG)"
233CFLAGS_win32=$(LUAINC:%=//I "%") $(DEF) //O2 //Ot //MD //W3 //nologo
234LDFLAGS_win32= //nologo //link //NOLOGO //DLL //INCREMENTAL:NO \
235 //MANIFEST //MANIFESTFILE:"intermediate.manifest" \
236 /MANIFESTUAC:"level='asInvoker' uiAccess='false'" \
237 //SUBSYSTEM:WINDOWS //OPT:REF //OPT:ICF //DYNAMICBASE:NO \
238 //MACHINE:X86 /LIBPATH:"$(LUALIB)" \
239 $(LUALIBNAME_win32) ws2_32.lib //OUT:
240
241LD_win32=cl
242SOCKET_win32=wsocket.obj
243
244#------
245# Compiler and linker settings
246# for Win64
247SO_win64=dll
248O_win64=obj
249CC_win64=cl
250DEF_win64= //D "WIN32" //D "NDEBUG" //D "_WINDOWS" //D "_USRDLL" \
251 //D "_CRT_SECURE_NO_WARNINGS" \
252 //D "_WINDLL" \
253 //D "LUASOCKET_$(DEBUG)"
254CFLAGS_win64=$(LUAINC:%=//I "%") $(DEF) //O2 //Ot //MD //W3 //nologo
255LDFLAGS_win64= //nologo //link //NOLOGO //DLL //INCREMENTAL:NO \
256 //MANIFEST //MANIFESTFILE:"intermediate.manifest" \
257 /MANIFESTUAC:"level='asInvoker' uiAccess='false'" \
258 //SUBSYSTEM:WINDOWS //OPT:REF //OPT:ICF //DYNAMICBASE:NO \
259 /LIBPATH:"$(LUALIB)" \
260 $(LUALIBNAME_win64) ws2_32.lib //OUT:
261
262LD_win64=cl
263SOCKET_win64=wsocket.obj
264
265.SUFFIXES: .obj
266
267.c.obj:
268 $(CC) $(CFLAGS) //Fo"$@" //c $<
269
270#------
271# Output file names
272#
273SO=$(SO_$(PLAT))
274O=$(O_$(PLAT))
275SOCKET_V=3.0.0
276MIME_V=1.0.3
277SOCKET_SO=socket-$(SOCKET_V).$(SO)
278MIME_SO=mime-$(MIME_V).$(SO)
279UNIX_SO=unix.$(SO)
280SERIAL_SO=serial.$(SO)
281SOCKET=$(SOCKET_$(PLAT))
282
283#------
284# Settings selected for platform
285#
286CC=$(CC_$(PLAT))
287DEF=$(DEF_$(PLAT))
288CFLAGS=$(MYCFLAGS) $(CFLAGS_$(PLAT))
289LDFLAGS=$(MYLDFLAGS) $(LDFLAGS_$(PLAT))
290LD=$(LD_$(PLAT))
291LUAINC= $(LUAINC_$(PLAT))
292LUALIB= $(LUALIB_$(PLAT))
293
294#------
295# Modules belonging to socket-core
296#
297SOCKET_OBJS= \
298 luasocket.$(O) \
299 timeout.$(O) \
300 buffer.$(O) \
301 io.$(O) \
302 auxiliar.$(O) \
303 compat.$(O) \
304 options.$(O) \
305 inet.$(O) \
306 $(SOCKET) \
307 except.$(O) \
308 select.$(O) \
309 tcp.$(O) \
310 udp.$(O)
311
312#------
313# Modules belonging mime-core
314#
315MIME_OBJS= \
316 mime.$(O) \
317 compat.$(O)
318
319#------
320# Modules belonging unix (local domain sockets)
321#
322UNIX_OBJS=\
323 buffer.$(O) \
324 auxiliar.$(O) \
325 options.$(O) \
326 timeout.$(O) \
327 io.$(O) \
328 usocket.$(O) \
329 unixstream.$(O) \
330 unixdgram.$(O) \
331 compat.$(O) \
332 unix.$(O)
333
334#------
335# Modules belonging to serial (device streams)
336#
337SERIAL_OBJS=\
338 buffer.$(O) \
339 compat.$(O) \
340 auxiliar.$(O) \
341 options.$(O) \
342 timeout.$(O) \
343 io.$(O) \
344 usocket.$(O) \
345 serial.$(O)
346
347#------
348# Files to install
349#
350TO_SOCKET_LDIR= \
351 http.lua \
352 url.lua \
353 tp.lua \
354 ftp.lua \
355 headers.lua \
356 smtp.lua
357
358TO_TOP_LDIR= \
359 ltn12.lua \
360 socket.lua \
361 mime.lua
362
363#------
364# Targets
365#
366default: $(PLAT)
367
368
369freebsd:
370 $(MAKE) all-unix PLAT=freebsd
371
372macosx:
373 $(MAKE) all-unix PLAT=macosx
374
375win32:
376 $(MAKE) all PLAT=win32
377
378win64:
379 $(MAKE) all PLAT=win64
380
381linux:
382 $(MAKE) all-unix PLAT=linux
383
384mingw:
385 $(MAKE) all PLAT=mingw
386
387solaris:
388 $(MAKE) all-unix PLAT=solaris
389
390none:
391 @echo "Please run"
392 @echo " make PLATFORM"
393 @echo "where PLATFORM is one of these:"
394 @echo " $(PLATS)"
395
396all: $(SOCKET_SO) $(MIME_SO)
397
398$(SOCKET_SO): $(SOCKET_OBJS)
399 $(LD) $(SOCKET_OBJS) $(LDFLAGS)$@
400
401$(MIME_SO): $(MIME_OBJS)
402 $(LD) $(MIME_OBJS) $(LDFLAGS)$@
403
404all-unix: all $(UNIX_SO) $(SERIAL_SO)
405
406$(UNIX_SO): $(UNIX_OBJS)
407 $(LD) $(UNIX_OBJS) $(LDFLAGS)$@
408
409$(SERIAL_SO): $(SERIAL_OBJS)
410 $(LD) $(SERIAL_OBJS) $(LDFLAGS)$@
411
412install:
413 $(INSTALL_DIR) $(INSTALL_TOP_LDIR)
414 $(INSTALL_DATA) $(TO_TOP_LDIR) $(INSTALL_TOP_LDIR)
415 $(INSTALL_DIR) $(INSTALL_SOCKET_LDIR)
416 $(INSTALL_DATA) $(TO_SOCKET_LDIR) $(INSTALL_SOCKET_LDIR)
417 $(INSTALL_DIR) $(INSTALL_SOCKET_CDIR)
418 $(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET_CDIR)/core.$(SO)
419 $(INSTALL_DIR) $(INSTALL_MIME_CDIR)
420 $(INSTALL_EXEC) $(MIME_SO) $(INSTALL_MIME_CDIR)/core.$(SO)
421
422install-unix: install
423 $(INSTALL_EXEC) $(UNIX_SO) $(INSTALL_SOCKET_CDIR)/$(UNIX_SO)
424 $(INSTALL_EXEC) $(SERIAL_SO) $(INSTALL_SOCKET_CDIR)/$(SERIAL_SO)
425
426local:
427 $(MAKE) install INSTALL_TOP_CDIR=.. INSTALL_TOP_LDIR=..
428
429clean:
430 rm -f $(SOCKET_SO) $(SOCKET_OBJS) $(SERIAL_OBJS)
431 rm -f $(MIME_SO) $(UNIX_SO) $(SERIAL_SO) $(MIME_OBJS) $(UNIX_OBJS)
432
433.PHONY: all $(PLATS) default clean echo none
434
435#------
436# List of dependencies
437#
438compat.$(O): compat.c compat.h
439auxiliar.$(O): auxiliar.c auxiliar.h
440buffer.$(O): buffer.c buffer.h io.h timeout.h
441except.$(O): except.c except.h
442inet.$(O): inet.c inet.h socket.h io.h timeout.h usocket.h
443io.$(O): io.c io.h timeout.h
444luasocket.$(O): luasocket.c luasocket.h auxiliar.h except.h \
445 timeout.h buffer.h io.h inet.h socket.h usocket.h tcp.h \
446 udp.h select.h
447mime.$(O): mime.c mime.h
448options.$(O): options.c auxiliar.h options.h socket.h io.h \
449 timeout.h usocket.h inet.h
450select.$(O): select.c socket.h io.h timeout.h usocket.h select.h
451serial.$(O): serial.c auxiliar.h socket.h io.h timeout.h usocket.h \
452 options.h unix.h buffer.h
453tcp.$(O): tcp.c auxiliar.h socket.h io.h timeout.h usocket.h \
454 inet.h options.h tcp.h buffer.h
455timeout.$(O): timeout.c auxiliar.h timeout.h
456udp.$(O): udp.c auxiliar.h socket.h io.h timeout.h usocket.h \
457 inet.h options.h udp.h
458unix.$(O): unix.c auxiliar.h socket.h io.h timeout.h usocket.h \
459 options.h unix.h buffer.h
460usocket.$(O): usocket.c socket.h io.h timeout.h usocket.h
461wsocket.$(O): wsocket.c socket.h io.h timeout.h usocket.h
diff --git a/vendor/luasocket/src/mbox.lua b/vendor/luasocket/src/mbox.lua
new file mode 100644
index 00000000..12823b0a
--- /dev/null
+++ b/vendor/luasocket/src/mbox.lua
@@ -0,0 +1,93 @@
1local _M = {}
2
3if module then
4 mbox = _M -- luacheck: ignore
5end
6
7function _M.split_message(message_s)
8 local message = {}
9 message_s = string.gsub(message_s, "\r\n", "\n")
10 string.gsub(message_s, "^(.-\n)\n", function (h) message.headers = h end)
11 string.gsub(message_s, "^.-\n\n(.*)", function (b) message.body = b end)
12 if not message.body then
13 string.gsub(message_s, "^\n(.*)", function (b) message.body = b end)
14 end
15 if not message.headers and not message.body then
16 message.headers = message_s
17 end
18 return message.headers or "", message.body or ""
19end
20
21function _M.split_headers(headers_s)
22 local headers = {}
23 headers_s = string.gsub(headers_s, "\r\n", "\n")
24 headers_s = string.gsub(headers_s, "\n[ ]+", " ")
25 string.gsub("\n" .. headers_s, "\n([^\n]+)", function (h) table.insert(headers, h) end)
26 return headers
27end
28
29function _M.parse_header(header_s)
30 header_s = string.gsub(header_s, "\n[ ]+", " ")
31 header_s = string.gsub(header_s, "\n+", "")
32 local _, _, name, value = string.find(header_s, "([^%s:]-):%s*(.*)")
33 return name, value
34end
35
36function _M.parse_headers(headers_s)
37 local headers_t = _M.split_headers(headers_s)
38 local headers = {}
39 for i = 1, #headers_t do
40 local name, value = _M.parse_header(headers_t[i])
41 if name then
42 name = string.lower(name)
43 if headers[name] then
44 headers[name] = headers[name] .. ", " .. value
45 else headers[name] = value end
46 end
47 end
48 return headers
49end
50
51function _M.parse_from(from)
52 local _, _, name, address = string.find(from, "^%s*(.-)%s*%<(.-)%>")
53 if not address then
54 _, _, address = string.find(from, "%s*(.+)%s*")
55 end
56 name = name or ""
57 address = address or ""
58 if name == "" then name = address end
59 name = string.gsub(name, '"', "")
60 return name, address
61end
62
63function _M.split_mbox(mbox_s)
64 local mbox = {}
65 mbox_s = string.gsub(mbox_s, "\r\n", "\n") .."\n\nFrom \n"
66 local nj, i
67 local j = 1
68 while 1 do
69 i, nj = string.find(mbox_s, "\n\nFrom .-\n", j)
70 if not i then break end
71 local message = string.sub(mbox_s, j, i-1)
72 table.insert(mbox, message)
73 j = nj+1
74 end
75 return mbox
76end
77
78function _M.parse(mbox_s)
79 local mbox = _M.split_mbox(mbox_s)
80 for i = 1, #mbox do
81 mbox[i] = _M.parse_message(mbox[i])
82 end
83 return mbox
84end
85
86function _M.parse_message(message_s)
87 local message = {}
88 message.headers, message.body = _M.split_message(message_s)
89 message.headers = _M.parse_headers(message.headers)
90 return message
91end
92
93return _M
diff --git a/vendor/luasocket/src/mime.c b/vendor/luasocket/src/mime.c
new file mode 100755
index 00000000..05602f56
--- /dev/null
+++ b/vendor/luasocket/src/mime.c
@@ -0,0 +1,852 @@
1/*=========================================================================*\
2* MIME support functions
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6#include "mime.h"
7#include <string.h>
8#include <ctype.h>
9
10/*=========================================================================*\
11* Don't want to trust escape character constants
12\*=========================================================================*/
13typedef unsigned char UC;
14static const char CRLF[] = "\r\n";
15static const char EQCRLF[] = "=\r\n";
16
17/*=========================================================================*\
18* Internal function prototypes.
19\*=========================================================================*/
20static int mime_global_wrp(lua_State *L);
21static int mime_global_b64(lua_State *L);
22static int mime_global_unb64(lua_State *L);
23static int mime_global_qp(lua_State *L);
24static int mime_global_unqp(lua_State *L);
25static int mime_global_qpwrp(lua_State *L);
26static int mime_global_eol(lua_State *L);
27static int mime_global_dot(lua_State *L);
28
29static size_t dot(int c, size_t state, luaL_Buffer *buffer);
30/*static void b64setup(UC *base);*/
31static size_t b64encode(UC c, UC *input, size_t size, luaL_Buffer *buffer);
32static size_t b64pad(const UC *input, size_t size, luaL_Buffer *buffer);
33static size_t b64decode(UC c, UC *input, size_t size, luaL_Buffer *buffer);
34
35/*static void qpsetup(UC *class, UC *unbase);*/
36static void qpquote(UC c, luaL_Buffer *buffer);
37static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer);
38static size_t qpencode(UC c, UC *input, size_t size,
39 const char *marker, luaL_Buffer *buffer);
40static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer);
41
42/* code support functions */
43static luaL_Reg func[] = {
44 { "dot", mime_global_dot },
45 { "b64", mime_global_b64 },
46 { "eol", mime_global_eol },
47 { "qp", mime_global_qp },
48 { "qpwrp", mime_global_qpwrp },
49 { "unb64", mime_global_unb64 },
50 { "unqp", mime_global_unqp },
51 { "wrp", mime_global_wrp },
52 { NULL, NULL }
53};
54
55/*-------------------------------------------------------------------------*\
56* Quoted-printable globals
57\*-------------------------------------------------------------------------*/
58enum {QP_PLAIN, QP_QUOTED, QP_CR, QP_IF_LAST};
59
60static const UC qpclass[] = {
61 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
62 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_IF_LAST, QP_QUOTED, QP_QUOTED,
63 QP_QUOTED, QP_CR, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
64 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
65 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
66 QP_QUOTED, QP_QUOTED, QP_IF_LAST, QP_PLAIN, QP_PLAIN, QP_PLAIN,
67 QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
68 QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
69 QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
70 QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
71 QP_PLAIN, QP_QUOTED, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
72 QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
73 QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
74 QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
75 QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
76 QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
77 QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
78 QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
79 QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
80 QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
81 QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN, QP_PLAIN,
82 QP_PLAIN, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
83 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
84 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
85 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
86 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
87 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
88 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
89 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
90 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
91 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
92 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
93 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
94 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
95 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
96 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
97 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
98 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
99 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
100 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
101 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
102 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED,
103 QP_QUOTED, QP_QUOTED, QP_QUOTED, QP_QUOTED
104};
105
106static const UC qpbase[] = "0123456789ABCDEF";
107
108static const UC qpunbase[] = {
109 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
110 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
111 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
112 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
113 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255,
114 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15,
115 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
116 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
117 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 255, 255,
118 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
119 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
120 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
121 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
122 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
123 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
124 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
125 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
126 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
127 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
128 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
129 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
130 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
131 255, 255, 255, 255, 255, 255, 255, 255
132};
133
134/*-------------------------------------------------------------------------*\
135* Base64 globals
136\*-------------------------------------------------------------------------*/
137static const UC b64base[] =
138 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
139
140static const UC b64unbase[] = {
141 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
142 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
143 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
144 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
145 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 0,
146 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
147 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255,
148 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
149 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
150 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
151 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
152 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
153 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
154 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
155 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
156 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
157 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
158 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
159 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
160 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
161 255, 255
162};
163
164/*=========================================================================*\
165* Exported functions
166\*=========================================================================*/
167/*-------------------------------------------------------------------------*\
168* Initializes module
169\*-------------------------------------------------------------------------*/
170LUASOCKET_API int luaopen_mime_core(lua_State *L)
171{
172 lua_newtable(L);
173 luaL_setfuncs(L, func, 0);
174 /* make version string available to scripts */
175 lua_pushstring(L, "_VERSION");
176 lua_pushstring(L, MIME_VERSION);
177 lua_rawset(L, -3);
178 /* initialize lookup tables */
179 /*qpsetup(qpclass, qpunbase);*/
180 /*b64setup(b64unbase);*/
181 return 1;
182}
183
184/*=========================================================================*\
185* Global Lua functions
186\*=========================================================================*/
187/*-------------------------------------------------------------------------*\
188* Incrementaly breaks a string into lines. The string can have CRLF breaks.
189* A, n = wrp(l, B, length)
190* A is a copy of B, broken into lines of at most 'length' bytes.
191* 'l' is how many bytes are left for the first line of B.
192* 'n' is the number of bytes left in the last line of A.
193\*-------------------------------------------------------------------------*/
194static int mime_global_wrp(lua_State *L)
195{
196 size_t size = 0;
197 int left = (int) luaL_checknumber(L, 1);
198 const UC *input = (const UC *) luaL_optlstring(L, 2, NULL, &size);
199 const UC *last = input + size;
200 int length = (int) luaL_optnumber(L, 3, 76);
201 luaL_Buffer buffer;
202 /* end of input black-hole */
203 if (!input) {
204 /* if last line has not been terminated, add a line break */
205 if (left < length) lua_pushstring(L, CRLF);
206 /* otherwise, we are done */
207 else lua_pushnil(L);
208 lua_pushnumber(L, length);
209 return 2;
210 }
211 luaL_buffinit(L, &buffer);
212 while (input < last) {
213 switch (*input) {
214 case '\r':
215 break;
216 case '\n':
217 luaL_addstring(&buffer, CRLF);
218 left = length;
219 break;
220 default:
221 if (left <= 0) {
222 left = length;
223 luaL_addstring(&buffer, CRLF);
224 }
225 luaL_addchar(&buffer, *input);
226 left--;
227 break;
228 }
229 input++;
230 }
231 luaL_pushresult(&buffer);
232 lua_pushnumber(L, left);
233 return 2;
234}
235
236#if 0
237/*-------------------------------------------------------------------------*\
238* Fill base64 decode map.
239\*-------------------------------------------------------------------------*/
240static void b64setup(UC *unbase)
241{
242 int i;
243 for (i = 0; i <= 255; i++) unbase[i] = (UC) 255;
244 for (i = 0; i < 64; i++) unbase[b64base[i]] = (UC) i;
245 unbase['='] = 0;
246
247 printf("static const UC b64unbase[] = {\n");
248 for (int i = 0; i < 256; i++) {
249 printf("%d, ", unbase[i]);
250 }
251 printf("\n}\n;");
252}
253#endif
254
255/*-------------------------------------------------------------------------*\
256* Acumulates bytes in input buffer until 3 bytes are available.
257* Translate the 3 bytes into Base64 form and append to buffer.
258* Returns new number of bytes in buffer.
259\*-------------------------------------------------------------------------*/
260static size_t b64encode(UC c, UC *input, size_t size,
261 luaL_Buffer *buffer)
262{
263 input[size++] = c;
264 if (size == 3) {
265 UC code[4];
266 unsigned long value = 0;
267 value += input[0]; value <<= 8;
268 value += input[1]; value <<= 8;
269 value += input[2];
270 code[3] = b64base[value & 0x3f]; value >>= 6;
271 code[2] = b64base[value & 0x3f]; value >>= 6;
272 code[1] = b64base[value & 0x3f]; value >>= 6;
273 code[0] = b64base[value];
274 luaL_addlstring(buffer, (char *) code, 4);
275 size = 0;
276 }
277 return size;
278}
279
280/*-------------------------------------------------------------------------*\
281* Encodes the Base64 last 1 or 2 bytes and adds padding '='
282* Result, if any, is appended to buffer.
283* Returns 0.
284\*-------------------------------------------------------------------------*/
285static size_t b64pad(const UC *input, size_t size,
286 luaL_Buffer *buffer)
287{
288 unsigned long value = 0;
289 UC code[4] = {'=', '=', '=', '='};
290 switch (size) {
291 case 1:
292 value = input[0] << 4;
293 code[1] = b64base[value & 0x3f]; value >>= 6;
294 code[0] = b64base[value];
295 luaL_addlstring(buffer, (char *) code, 4);
296 break;
297 case 2:
298 value = input[0]; value <<= 8;
299 value |= input[1]; value <<= 2;
300 code[2] = b64base[value & 0x3f]; value >>= 6;
301 code[1] = b64base[value & 0x3f]; value >>= 6;
302 code[0] = b64base[value];
303 luaL_addlstring(buffer, (char *) code, 4);
304 break;
305 default:
306 break;
307 }
308 return 0;
309}
310
311/*-------------------------------------------------------------------------*\
312* Acumulates bytes in input buffer until 4 bytes are available.
313* Translate the 4 bytes from Base64 form and append to buffer.
314* Returns new number of bytes in buffer.
315\*-------------------------------------------------------------------------*/
316static size_t b64decode(UC c, UC *input, size_t size,
317 luaL_Buffer *buffer)
318{
319 /* ignore invalid characters */
320 if (b64unbase[c] > 64) return size;
321 input[size++] = c;
322 /* decode atom */
323 if (size == 4) {
324 UC decoded[3];
325 int valid, value = 0;
326 value = b64unbase[input[0]]; value <<= 6;
327 value |= b64unbase[input[1]]; value <<= 6;
328 value |= b64unbase[input[2]]; value <<= 6;
329 value |= b64unbase[input[3]];
330 decoded[2] = (UC) (value & 0xff); value >>= 8;
331 decoded[1] = (UC) (value & 0xff); value >>= 8;
332 decoded[0] = (UC) value;
333 /* take care of paddding */
334 valid = (input[2] == '=') ? 1 : (input[3] == '=') ? 2 : 3;
335 luaL_addlstring(buffer, (char *) decoded, valid);
336 return 0;
337 /* need more data */
338 } else return size;
339}
340
341/*-------------------------------------------------------------------------*\
342* Incrementally applies the Base64 transfer content encoding to a string
343* A, B = b64(C, D)
344* A is the encoded version of the largest prefix of C .. D that is
345* divisible by 3. B has the remaining bytes of C .. D, *without* encoding.
346* The easiest thing would be to concatenate the two strings and
347* encode the result, but we can't afford that or Lua would dupplicate
348* every chunk we received.
349\*-------------------------------------------------------------------------*/
350static int mime_global_b64(lua_State *L)
351{
352 UC atom[3];
353 size_t isize = 0, asize = 0;
354 const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize);
355 const UC *last = input + isize;
356 luaL_Buffer buffer;
357 /* end-of-input blackhole */
358 if (!input) {
359 lua_pushnil(L);
360 lua_pushnil(L);
361 return 2;
362 }
363 /* make sure we don't confuse buffer stuff with arguments */
364 lua_settop(L, 2);
365 /* process first part of the input */
366 luaL_buffinit(L, &buffer);
367 while (input < last)
368 asize = b64encode(*input++, atom, asize, &buffer);
369 input = (const UC *) luaL_optlstring(L, 2, NULL, &isize);
370 /* if second part is nil, we are done */
371 if (!input) {
372 size_t osize = 0;
373 asize = b64pad(atom, asize, &buffer);
374 luaL_pushresult(&buffer);
375 /* if the output is empty and the input is nil, return nil */
376 lua_tolstring(L, -1, &osize);
377 if (osize == 0) lua_pushnil(L);
378 lua_pushnil(L);
379 return 2;
380 }
381 /* otherwise process the second part */
382 last = input + isize;
383 while (input < last)
384 asize = b64encode(*input++, atom, asize, &buffer);
385 luaL_pushresult(&buffer);
386 lua_pushlstring(L, (char *) atom, asize);
387 return 2;
388}
389
390/*-------------------------------------------------------------------------*\
391* Incrementally removes the Base64 transfer content encoding from a string
392* A, B = b64(C, D)
393* A is the encoded version of the largest prefix of C .. D that is
394* divisible by 4. B has the remaining bytes of C .. D, *without* encoding.
395\*-------------------------------------------------------------------------*/
396static int mime_global_unb64(lua_State *L)
397{
398 UC atom[4];
399 size_t isize = 0, asize = 0;
400 const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize);
401 const UC *last = input + isize;
402 luaL_Buffer buffer;
403 /* end-of-input blackhole */
404 if (!input) {
405 lua_pushnil(L);
406 lua_pushnil(L);
407 return 2;
408 }
409 /* make sure we don't confuse buffer stuff with arguments */
410 lua_settop(L, 2);
411 /* process first part of the input */
412 luaL_buffinit(L, &buffer);
413 while (input < last)
414 asize = b64decode(*input++, atom, asize, &buffer);
415 input = (const UC *) luaL_optlstring(L, 2, NULL, &isize);
416 /* if second is nil, we are done */
417 if (!input) {
418 size_t osize = 0;
419 luaL_pushresult(&buffer);
420 /* if the output is empty and the input is nil, return nil */
421 lua_tolstring(L, -1, &osize);
422 if (osize == 0) lua_pushnil(L);
423 lua_pushnil(L);
424 return 2;
425 }
426 /* otherwise, process the rest of the input */
427 last = input + isize;
428 while (input < last)
429 asize = b64decode(*input++, atom, asize, &buffer);
430 luaL_pushresult(&buffer);
431 lua_pushlstring(L, (char *) atom, asize);
432 return 2;
433}
434
435/*-------------------------------------------------------------------------*\
436* Quoted-printable encoding scheme
437* all (except CRLF in text) can be =XX
438* CLRL in not text must be =XX=XX
439* 33 through 60 inclusive can be plain
440* 62 through 126 inclusive can be plain
441* 9 and 32 can be plain, unless in the end of a line, where must be =XX
442* encoded lines must be no longer than 76 not counting CRLF
443* soft line-break are =CRLF
444* To encode one byte, we need to see the next two.
445* Worst case is when we see a space, and wonder if a CRLF is comming
446\*-------------------------------------------------------------------------*/
447#if 0
448/*-------------------------------------------------------------------------*\
449* Split quoted-printable characters into classes
450* Precompute reverse map for encoding
451\*-------------------------------------------------------------------------*/
452static void qpsetup(UC *cl, UC *unbase)
453{
454
455 int i;
456 for (i = 0; i < 256; i++) cl[i] = QP_QUOTED;
457 for (i = 33; i <= 60; i++) cl[i] = QP_PLAIN;
458 for (i = 62; i <= 126; i++) cl[i] = QP_PLAIN;
459 cl['\t'] = QP_IF_LAST;
460 cl[' '] = QP_IF_LAST;
461 cl['\r'] = QP_CR;
462 for (i = 0; i < 256; i++) unbase[i] = 255;
463 unbase['0'] = 0; unbase['1'] = 1; unbase['2'] = 2;
464 unbase['3'] = 3; unbase['4'] = 4; unbase['5'] = 5;
465 unbase['6'] = 6; unbase['7'] = 7; unbase['8'] = 8;
466 unbase['9'] = 9; unbase['A'] = 10; unbase['a'] = 10;
467 unbase['B'] = 11; unbase['b'] = 11; unbase['C'] = 12;
468 unbase['c'] = 12; unbase['D'] = 13; unbase['d'] = 13;
469 unbase['E'] = 14; unbase['e'] = 14; unbase['F'] = 15;
470 unbase['f'] = 15;
471
472printf("static UC qpclass[] = {");
473 for (int i = 0; i < 256; i++) {
474 if (i % 6 == 0) {
475 printf("\n ");
476 }
477 switch(cl[i]) {
478 case QP_QUOTED:
479 printf("QP_QUOTED, ");
480 break;
481 case QP_PLAIN:
482 printf("QP_PLAIN, ");
483 break;
484 case QP_CR:
485 printf("QP_CR, ");
486 break;
487 case QP_IF_LAST:
488 printf("QP_IF_LAST, ");
489 break;
490 }
491 }
492printf("\n};\n");
493
494printf("static const UC qpunbase[] = {");
495 for (int i = 0; i < 256; i++) {
496 int c = qpunbase[i];
497 printf("%d, ", c);
498 }
499printf("\";\n");
500}
501#endif
502
503/*-------------------------------------------------------------------------*\
504* Output one character in form =XX
505\*-------------------------------------------------------------------------*/
506static void qpquote(UC c, luaL_Buffer *buffer)
507{
508 luaL_addchar(buffer, '=');
509 luaL_addchar(buffer, qpbase[c >> 4]);
510 luaL_addchar(buffer, qpbase[c & 0x0F]);
511}
512
513/*-------------------------------------------------------------------------*\
514* Accumulate characters until we are sure about how to deal with them.
515* Once we are sure, output to the buffer, in the correct form.
516\*-------------------------------------------------------------------------*/
517static size_t qpencode(UC c, UC *input, size_t size,
518 const char *marker, luaL_Buffer *buffer)
519{
520 input[size++] = c;
521 /* deal with all characters we can have */
522 while (size > 0) {
523 switch (qpclass[input[0]]) {
524 /* might be the CR of a CRLF sequence */
525 case QP_CR:
526 if (size < 2) return size;
527 if (input[1] == '\n') {
528 luaL_addstring(buffer, marker);
529 return 0;
530 } else qpquote(input[0], buffer);
531 break;
532 /* might be a space and that has to be quoted if last in line */
533 case QP_IF_LAST:
534 if (size < 3) return size;
535 /* if it is the last, quote it and we are done */
536 if (input[1] == '\r' && input[2] == '\n') {
537 qpquote(input[0], buffer);
538 luaL_addstring(buffer, marker);
539 return 0;
540 } else luaL_addchar(buffer, input[0]);
541 break;
542 /* might have to be quoted always */
543 case QP_QUOTED:
544 qpquote(input[0], buffer);
545 break;
546 /* might never have to be quoted */
547 default:
548 luaL_addchar(buffer, input[0]);
549 break;
550 }
551 input[0] = input[1]; input[1] = input[2];
552 size--;
553 }
554 return 0;
555}
556
557/*-------------------------------------------------------------------------*\
558* Deal with the final characters
559\*-------------------------------------------------------------------------*/
560static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer)
561{
562 size_t i;
563 for (i = 0; i < size; i++) {
564 if (qpclass[input[i]] == QP_PLAIN) luaL_addchar(buffer, input[i]);
565 else qpquote(input[i], buffer);
566 }
567 if (size > 0) luaL_addstring(buffer, EQCRLF);
568 return 0;
569}
570
571/*-------------------------------------------------------------------------*\
572* Incrementally converts a string to quoted-printable
573* A, B = qp(C, D, marker)
574* Marker is the text to be used to replace CRLF sequences found in A.
575* A is the encoded version of the largest prefix of C .. D that
576* can be encoded without doubts.
577* B has the remaining bytes of C .. D, *without* encoding.
578\*-------------------------------------------------------------------------*/
579static int mime_global_qp(lua_State *L)
580{
581 size_t asize = 0, isize = 0;
582 UC atom[3];
583 const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize);
584 const UC *last = input + isize;
585 const char *marker = luaL_optstring(L, 3, CRLF);
586 luaL_Buffer buffer;
587 /* end-of-input blackhole */
588 if (!input) {
589 lua_pushnil(L);
590 lua_pushnil(L);
591 return 2;
592 }
593 /* make sure we don't confuse buffer stuff with arguments */
594 lua_settop(L, 3);
595 /* process first part of input */
596 luaL_buffinit(L, &buffer);
597 while (input < last)
598 asize = qpencode(*input++, atom, asize, marker, &buffer);
599 input = (const UC *) luaL_optlstring(L, 2, NULL, &isize);
600 /* if second part is nil, we are done */
601 if (!input) {
602 asize = qppad(atom, asize, &buffer);
603 luaL_pushresult(&buffer);
604 if (!(*lua_tostring(L, -1))) lua_pushnil(L);
605 lua_pushnil(L);
606 return 2;
607 }
608 /* otherwise process rest of input */
609 last = input + isize;
610 while (input < last)
611 asize = qpencode(*input++, atom, asize, marker, &buffer);
612 luaL_pushresult(&buffer);
613 lua_pushlstring(L, (char *) atom, asize);
614 return 2;
615}
616
617/*-------------------------------------------------------------------------*\
618* Accumulate characters until we are sure about how to deal with them.
619* Once we are sure, output the to the buffer, in the correct form.
620\*-------------------------------------------------------------------------*/
621static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) {
622 int d;
623 input[size++] = c;
624 /* deal with all characters we can deal */
625 switch (input[0]) {
626 /* if we have an escape character */
627 case '=':
628 if (size < 3) return size;
629 /* eliminate soft line break */
630 if (input[1] == '\r' && input[2] == '\n') return 0;
631 /* decode quoted representation */
632 c = qpunbase[input[1]]; d = qpunbase[input[2]];
633 /* if it is an invalid, do not decode */
634 if (c > 15 || d > 15) luaL_addlstring(buffer, (char *)input, 3);
635 else luaL_addchar(buffer, (char) ((c << 4) + d));
636 return 0;
637 case '\r':
638 if (size < 2) return size;
639 if (input[1] == '\n') luaL_addlstring(buffer, (char *)input, 2);
640 return 0;
641 default:
642 if (input[0] == '\t' || (input[0] > 31 && input[0] < 127))
643 luaL_addchar(buffer, input[0]);
644 return 0;
645 }
646}
647
648/*-------------------------------------------------------------------------*\
649* Incrementally decodes a string in quoted-printable
650* A, B = qp(C, D)
651* A is the decoded version of the largest prefix of C .. D that
652* can be decoded without doubts.
653* B has the remaining bytes of C .. D, *without* decoding.
654\*-------------------------------------------------------------------------*/
655static int mime_global_unqp(lua_State *L)
656{
657 size_t asize = 0, isize = 0;
658 UC atom[3];
659 const UC *input = (const UC *) luaL_optlstring(L, 1, NULL, &isize);
660 const UC *last = input + isize;
661 luaL_Buffer buffer;
662 /* end-of-input blackhole */
663 if (!input) {
664 lua_pushnil(L);
665 lua_pushnil(L);
666 return 2;
667 }
668 /* make sure we don't confuse buffer stuff with arguments */
669 lua_settop(L, 2);
670 /* process first part of input */
671 luaL_buffinit(L, &buffer);
672 while (input < last)
673 asize = qpdecode(*input++, atom, asize, &buffer);
674 input = (const UC *) luaL_optlstring(L, 2, NULL, &isize);
675 /* if second part is nil, we are done */
676 if (!input) {
677 luaL_pushresult(&buffer);
678 if (!(*lua_tostring(L, -1))) lua_pushnil(L);
679 lua_pushnil(L);
680 return 2;
681 }
682 /* otherwise process rest of input */
683 last = input + isize;
684 while (input < last)
685 asize = qpdecode(*input++, atom, asize, &buffer);
686 luaL_pushresult(&buffer);
687 lua_pushlstring(L, (char *) atom, asize);
688 return 2;
689}
690
691/*-------------------------------------------------------------------------*\
692* Incrementally breaks a quoted-printed string into lines
693* A, n = qpwrp(l, B, length)
694* A is a copy of B, broken into lines of at most 'length' bytes.
695* 'l' is how many bytes are left for the first line of B.
696* 'n' is the number of bytes left in the last line of A.
697* There are two complications: lines can't be broken in the middle
698* of an encoded =XX, and there might be line breaks already
699\*-------------------------------------------------------------------------*/
700static int mime_global_qpwrp(lua_State *L)
701{
702 size_t size = 0;
703 int left = (int) luaL_checknumber(L, 1);
704 const UC *input = (const UC *) luaL_optlstring(L, 2, NULL, &size);
705 const UC *last = input + size;
706 int length = (int) luaL_optnumber(L, 3, 76);
707 luaL_Buffer buffer;
708 /* end-of-input blackhole */
709 if (!input) {
710 if (left < length) lua_pushstring(L, EQCRLF);
711 else lua_pushnil(L);
712 lua_pushnumber(L, length);
713 return 2;
714 }
715 /* process all input */
716 luaL_buffinit(L, &buffer);
717 while (input < last) {
718 switch (*input) {
719 case '\r':
720 break;
721 case '\n':
722 left = length;
723 luaL_addstring(&buffer, CRLF);
724 break;
725 case '=':
726 if (left <= 3) {
727 left = length;
728 luaL_addstring(&buffer, EQCRLF);
729 }
730 luaL_addchar(&buffer, *input);
731 left--;
732 break;
733 default:
734 if (left <= 1) {
735 left = length;
736 luaL_addstring(&buffer, EQCRLF);
737 }
738 luaL_addchar(&buffer, *input);
739 left--;
740 break;
741 }
742 input++;
743 }
744 luaL_pushresult(&buffer);
745 lua_pushnumber(L, left);
746 return 2;
747}
748
749/*-------------------------------------------------------------------------*\
750* Here is what we do: \n, and \r are considered candidates for line
751* break. We issue *one* new line marker if any of them is seen alone, or
752* followed by a different one. That is, \n\n and \r\r will issue two
753* end of line markers each, but \r\n, \n\r etc will only issue *one*
754* marker. This covers Mac OS, Mac OS X, VMS, Unix and DOS, as well as
755* probably other more obscure conventions.
756*
757* c is the current character being processed
758* last is the previous character
759\*-------------------------------------------------------------------------*/
760#define eolcandidate(c) (c == '\r' || c == '\n')
761static int eolprocess(int c, int last, const char *marker,
762 luaL_Buffer *buffer)
763{
764 if (eolcandidate(c)) {
765 if (eolcandidate(last)) {
766 if (c == last) luaL_addstring(buffer, marker);
767 return 0;
768 } else {
769 luaL_addstring(buffer, marker);
770 return c;
771 }
772 } else {
773 luaL_addchar(buffer, (char) c);
774 return 0;
775 }
776}
777
778/*-------------------------------------------------------------------------*\
779* Converts a string to uniform EOL convention.
780* A, n = eol(o, B, marker)
781* A is the converted version of the largest prefix of B that can be
782* converted unambiguously. 'o' is the context returned by the previous
783* call. 'n' is the new context.
784\*-------------------------------------------------------------------------*/
785static int mime_global_eol(lua_State *L)
786{
787 int ctx = (int) luaL_checkinteger(L, 1);
788 size_t isize = 0;
789 const char *input = luaL_optlstring(L, 2, NULL, &isize);
790 const char *last = input + isize;
791 const char *marker = luaL_optstring(L, 3, CRLF);
792 luaL_Buffer buffer;
793 luaL_buffinit(L, &buffer);
794 /* end of input blackhole */
795 if (!input) {
796 lua_pushnil(L);
797 lua_pushnumber(L, 0);
798 return 2;
799 }
800 /* process all input */
801 while (input < last)
802 ctx = eolprocess(*input++, ctx, marker, &buffer);
803 luaL_pushresult(&buffer);
804 lua_pushnumber(L, ctx);
805 return 2;
806}
807
808/*-------------------------------------------------------------------------*\
809* Takes one byte and stuff it if needed.
810\*-------------------------------------------------------------------------*/
811static size_t dot(int c, size_t state, luaL_Buffer *buffer)
812{
813 luaL_addchar(buffer, (char) c);
814 switch (c) {
815 case '\r':
816 return 1;
817 case '\n':
818 return (state == 1)? 2: 0;
819 case '.':
820 if (state == 2)
821 luaL_addchar(buffer, '.');
822 /* Falls through. */
823 default:
824 return 0;
825 }
826}
827
828/*-------------------------------------------------------------------------*\
829* Incrementally applies smtp stuffing to a string
830* A, n = dot(l, D)
831\*-------------------------------------------------------------------------*/
832static int mime_global_dot(lua_State *L)
833{
834 size_t isize = 0, state = (size_t) luaL_checknumber(L, 1);
835 const char *input = luaL_optlstring(L, 2, NULL, &isize);
836 const char *last = input + isize;
837 luaL_Buffer buffer;
838 /* end-of-input blackhole */
839 if (!input) {
840 lua_pushnil(L);
841 lua_pushnumber(L, 2);
842 return 2;
843 }
844 /* process all input */
845 luaL_buffinit(L, &buffer);
846 while (input < last)
847 state = dot(*input++, state, &buffer);
848 luaL_pushresult(&buffer);
849 lua_pushnumber(L, (lua_Number) state);
850 return 2;
851}
852
diff --git a/vendor/luasocket/src/mime.h b/vendor/luasocket/src/mime.h
new file mode 100644
index 00000000..4d938f46
--- /dev/null
+++ b/vendor/luasocket/src/mime.h
@@ -0,0 +1,22 @@
1#ifndef MIME_H
2#define MIME_H
3/*=========================================================================*\
4* Core MIME support
5* LuaSocket toolkit
6*
7* This module provides functions to implement transfer content encodings
8* and formatting conforming to RFC 2045. It is used by mime.lua, which
9* provide a higher level interface to this functionality.
10\*=========================================================================*/
11#include "luasocket.h"
12
13/*-------------------------------------------------------------------------*\
14* Current MIME library version
15\*-------------------------------------------------------------------------*/
16#define MIME_VERSION "MIME 1.0.3"
17#define MIME_COPYRIGHT "Copyright (C) 2004-2013 Diego Nehab"
18#define MIME_AUTHORS "Diego Nehab"
19
20LUASOCKET_API int luaopen_mime_core(lua_State *L);
21
22#endif /* MIME_H */
diff --git a/vendor/luasocket/src/mime.lua b/vendor/luasocket/src/mime.lua
new file mode 100644
index 00000000..93539de6
--- /dev/null
+++ b/vendor/luasocket/src/mime.lua
@@ -0,0 +1,81 @@
1-----------------------------------------------------------------------------
2-- MIME support for the Lua language.
3-- Author: Diego Nehab
4-- Conforming to RFCs 2045-2049
5-----------------------------------------------------------------------------
6
7-----------------------------------------------------------------------------
8-- Declare module and import dependencies
9-----------------------------------------------------------------------------
10local base = _G
11local ltn12 = require("ltn12")
12local mime = require("mime.core")
13local _M = mime
14
15-- encode, decode and wrap algorithm tables
16local encodet, decodet, wrapt = {},{},{}
17
18_M.encodet = encodet
19_M.decodet = decodet
20_M.wrapt = wrapt
21
22-- creates a function that chooses a filter by name from a given table
23local function choose(table)
24 return function(name, opt1, opt2)
25 if base.type(name) ~= "string" then
26 name, opt1, opt2 = "default", name, opt1
27 end
28 local f = table[name or "nil"]
29 if not f then
30 base.error("unknown key (" .. base.tostring(name) .. ")", 3)
31 else return f(opt1, opt2) end
32 end
33end
34
35-- define the encoding filters
36encodet['base64'] = function()
37 return ltn12.filter.cycle(_M.b64, "")
38end
39
40encodet['quoted-printable'] = function(mode)
41 return ltn12.filter.cycle(_M.qp, "",
42 (mode == "binary") and "=0D=0A" or "\r\n")
43end
44
45-- define the decoding filters
46decodet['base64'] = function()
47 return ltn12.filter.cycle(_M.unb64, "")
48end
49
50decodet['quoted-printable'] = function()
51 return ltn12.filter.cycle(_M.unqp, "")
52end
53
54-- define the line-wrap filters
55wrapt['text'] = function(length)
56 length = length or 76
57 return ltn12.filter.cycle(_M.wrp, length, length)
58end
59wrapt['base64'] = wrapt['text']
60wrapt['default'] = wrapt['text']
61
62wrapt['quoted-printable'] = function()
63 return ltn12.filter.cycle(_M.qpwrp, 76, 76)
64end
65
66-- function that choose the encoding, decoding or wrap algorithm
67_M.encode = choose(encodet)
68_M.decode = choose(decodet)
69_M.wrap = choose(wrapt)
70
71-- define the end-of-line normalization filter
72function _M.normalize(marker)
73 return ltn12.filter.cycle(_M.eol, 0, marker)
74end
75
76-- high level stuffing filter
77function _M.stuff()
78 return ltn12.filter.cycle(_M.dot, 2)
79end
80
81return _M
diff --git a/vendor/luasocket/src/options.c b/vendor/luasocket/src/options.c
new file mode 100644
index 00000000..3280c51d
--- /dev/null
+++ b/vendor/luasocket/src/options.c
@@ -0,0 +1,480 @@
1/*=========================================================================*\
2* Common option interface
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6#include "auxiliar.h"
7#include "options.h"
8#include "inet.h"
9#include <string.h>
10
11/*=========================================================================*\
12* Internal functions prototypes
13\*=========================================================================*/
14static int opt_setmembership(lua_State *L, p_socket ps, int level, int name);
15static int opt_ip6_setmembership(lua_State *L, p_socket ps, int level, int name);
16static int opt_setboolean(lua_State *L, p_socket ps, int level, int name);
17static int opt_getboolean(lua_State *L, p_socket ps, int level, int name);
18static int opt_setint(lua_State *L, p_socket ps, int level, int name);
19static int opt_getint(lua_State *L, p_socket ps, int level, int name);
20static int opt_set(lua_State *L, p_socket ps, int level, int name,
21 void *val, int len);
22static int opt_get(lua_State *L, p_socket ps, int level, int name,
23 void *val, int* len);
24
25/*=========================================================================*\
26* Exported functions
27\*=========================================================================*/
28/*-------------------------------------------------------------------------*\
29* Calls appropriate option handler
30\*-------------------------------------------------------------------------*/
31int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps)
32{
33 const char *name = luaL_checkstring(L, 2); /* obj, name, ... */
34 while (opt->name && strcmp(name, opt->name))
35 opt++;
36 if (!opt->func) {
37 char msg[57];
38 sprintf(msg, "unsupported option `%.35s'", name);
39 luaL_argerror(L, 2, msg);
40 }
41 return opt->func(L, ps);
42}
43
44int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps)
45{
46 const char *name = luaL_checkstring(L, 2); /* obj, name, ... */
47 while (opt->name && strcmp(name, opt->name))
48 opt++;
49 if (!opt->func) {
50 char msg[57];
51 sprintf(msg, "unsupported option `%.35s'", name);
52 luaL_argerror(L, 2, msg);
53 }
54 return opt->func(L, ps);
55}
56
57/*------------------------------------------------------*/
58/* enables reuse of local address */
59int opt_set_reuseaddr(lua_State *L, p_socket ps)
60{
61 return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEADDR);
62}
63
64int opt_get_reuseaddr(lua_State *L, p_socket ps)
65{
66 return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEADDR);
67}
68
69/*------------------------------------------------------*/
70/* enables reuse of local port */
71int opt_set_reuseport(lua_State *L, p_socket ps)
72{
73 return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEPORT);
74}
75
76int opt_get_reuseport(lua_State *L, p_socket ps)
77{
78 return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEPORT);
79}
80
81/*------------------------------------------------------*/
82/* disables the Nagle algorithm */
83int opt_set_tcp_nodelay(lua_State *L, p_socket ps)
84{
85 return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY);
86}
87
88int opt_get_tcp_nodelay(lua_State *L, p_socket ps)
89{
90 return opt_getboolean(L, ps, IPPROTO_TCP, TCP_NODELAY);
91}
92
93/*------------------------------------------------------*/
94#ifdef TCP_KEEPIDLE
95
96int opt_get_tcp_keepidle(lua_State *L, p_socket ps)
97{
98 return opt_getint(L, ps, IPPROTO_TCP, TCP_KEEPIDLE);
99}
100
101int opt_set_tcp_keepidle(lua_State *L, p_socket ps)
102{
103 return opt_setint(L, ps, IPPROTO_TCP, TCP_KEEPIDLE);
104}
105
106#endif
107
108/*------------------------------------------------------*/
109#ifdef TCP_KEEPCNT
110
111int opt_get_tcp_keepcnt(lua_State *L, p_socket ps)
112{
113 return opt_getint(L, ps, IPPROTO_TCP, TCP_KEEPCNT);
114}
115
116int opt_set_tcp_keepcnt(lua_State *L, p_socket ps)
117{
118 return opt_setint(L, ps, IPPROTO_TCP, TCP_KEEPCNT);
119}
120
121#endif
122
123/*------------------------------------------------------*/
124#ifdef TCP_KEEPINTVL
125
126int opt_get_tcp_keepintvl(lua_State *L, p_socket ps)
127{
128 return opt_getint(L, ps, IPPROTO_TCP, TCP_KEEPINTVL);
129}
130
131int opt_set_tcp_keepintvl(lua_State *L, p_socket ps)
132{
133 return opt_setint(L, ps, IPPROTO_TCP, TCP_KEEPINTVL);
134}
135
136#endif
137
138/*------------------------------------------------------*/
139int opt_set_keepalive(lua_State *L, p_socket ps)
140{
141 return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE);
142}
143
144int opt_get_keepalive(lua_State *L, p_socket ps)
145{
146 return opt_getboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE);
147}
148
149/*------------------------------------------------------*/
150int opt_set_dontroute(lua_State *L, p_socket ps)
151{
152 return opt_setboolean(L, ps, SOL_SOCKET, SO_DONTROUTE);
153}
154
155int opt_get_dontroute(lua_State *L, p_socket ps)
156{
157 return opt_getboolean(L, ps, SOL_SOCKET, SO_DONTROUTE);
158}
159
160/*------------------------------------------------------*/
161int opt_set_broadcast(lua_State *L, p_socket ps)
162{
163 return opt_setboolean(L, ps, SOL_SOCKET, SO_BROADCAST);
164}
165
166int opt_get_broadcast(lua_State *L, p_socket ps)
167{
168 return opt_getboolean(L, ps, SOL_SOCKET, SO_BROADCAST);
169}
170
171/*------------------------------------------------------*/
172int opt_set_recv_buf_size(lua_State *L, p_socket ps)
173{
174 return opt_setint(L, ps, SOL_SOCKET, SO_RCVBUF);
175}
176
177int opt_get_recv_buf_size(lua_State *L, p_socket ps)
178{
179 return opt_getint(L, ps, SOL_SOCKET, SO_RCVBUF);
180}
181
182/*------------------------------------------------------*/
183int opt_get_send_buf_size(lua_State *L, p_socket ps)
184{
185 return opt_getint(L, ps, SOL_SOCKET, SO_SNDBUF);
186}
187
188int opt_set_send_buf_size(lua_State *L, p_socket ps)
189{
190 return opt_setint(L, ps, SOL_SOCKET, SO_SNDBUF);
191}
192
193// /*------------------------------------------------------*/
194
195#ifdef TCP_FASTOPEN
196int opt_set_tcp_fastopen(lua_State *L, p_socket ps)
197{
198 return opt_setint(L, ps, IPPROTO_TCP, TCP_FASTOPEN);
199}
200#endif
201
202#ifdef TCP_FASTOPEN_CONNECT
203int opt_set_tcp_fastopen_connect(lua_State *L, p_socket ps)
204{
205 return opt_setint(L, ps, IPPROTO_TCP, TCP_FASTOPEN_CONNECT);
206}
207#endif
208
209/*------------------------------------------------------*/
210
211#ifdef TCP_DEFER_ACCEPT
212int opt_set_tcp_defer_accept(lua_State *L, p_socket ps)
213{
214 return opt_setint(L, ps, IPPROTO_TCP, TCP_DEFER_ACCEPT);
215}
216#endif
217
218/*------------------------------------------------------*/
219int opt_set_ip6_unicast_hops(lua_State *L, p_socket ps)
220{
221 return opt_setint(L, ps, IPPROTO_IPV6, IPV6_UNICAST_HOPS);
222}
223
224int opt_get_ip6_unicast_hops(lua_State *L, p_socket ps)
225{
226 return opt_getint(L, ps, IPPROTO_IPV6, IPV6_UNICAST_HOPS);
227}
228
229/*------------------------------------------------------*/
230int opt_set_ip6_multicast_hops(lua_State *L, p_socket ps)
231{
232 return opt_setint(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_HOPS);
233}
234
235int opt_get_ip6_multicast_hops(lua_State *L, p_socket ps)
236{
237 return opt_getint(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_HOPS);
238}
239
240/*------------------------------------------------------*/
241int opt_set_ip_multicast_loop(lua_State *L, p_socket ps)
242{
243 return opt_setboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP);
244}
245
246int opt_get_ip_multicast_loop(lua_State *L, p_socket ps)
247{
248 return opt_getboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP);
249}
250
251/*------------------------------------------------------*/
252int opt_set_ip6_multicast_loop(lua_State *L, p_socket ps)
253{
254 return opt_setboolean(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_LOOP);
255}
256
257int opt_get_ip6_multicast_loop(lua_State *L, p_socket ps)
258{
259 return opt_getboolean(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_LOOP);
260}
261
262/*------------------------------------------------------*/
263int opt_set_linger(lua_State *L, p_socket ps)
264{
265 struct linger li; /* obj, name, table */
266 if (!lua_istable(L, 3)) auxiliar_typeerror(L,3,lua_typename(L, LUA_TTABLE));
267 lua_pushstring(L, "on");
268 lua_gettable(L, 3);
269 if (!lua_isboolean(L, -1))
270 luaL_argerror(L, 3, "boolean 'on' field expected");
271 li.l_onoff = (u_short) lua_toboolean(L, -1);
272 lua_pushstring(L, "timeout");
273 lua_gettable(L, 3);
274 if (!lua_isnumber(L, -1))
275 luaL_argerror(L, 3, "number 'timeout' field expected");
276 li.l_linger = (u_short) lua_tonumber(L, -1);
277 return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof(li));
278}
279
280int opt_get_linger(lua_State *L, p_socket ps)
281{
282 struct linger li; /* obj, name */
283 int len = sizeof(li);
284 int err = opt_get(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, &len);
285 if (err)
286 return err;
287 lua_newtable(L);
288 lua_pushboolean(L, li.l_onoff);
289 lua_setfield(L, -2, "on");
290 lua_pushinteger(L, li.l_linger);
291 lua_setfield(L, -2, "timeout");
292 return 1;
293}
294
295/*------------------------------------------------------*/
296int opt_set_ip_multicast_ttl(lua_State *L, p_socket ps)
297{
298 return opt_setint(L, ps, IPPROTO_IP, IP_MULTICAST_TTL);
299}
300
301/*------------------------------------------------------*/
302int opt_set_ip_multicast_if(lua_State *L, p_socket ps)
303{
304 const char *address = luaL_checkstring(L, 3); /* obj, name, ip */
305 struct in_addr val;
306 val.s_addr = htonl(INADDR_ANY);
307 if (strcmp(address, "*") && !inet_aton(address, &val))
308 luaL_argerror(L, 3, "ip expected");
309 return opt_set(L, ps, IPPROTO_IP, IP_MULTICAST_IF,
310 (char *) &val, sizeof(val));
311}
312
313int opt_get_ip_multicast_if(lua_State *L, p_socket ps)
314{
315 struct in_addr val;
316 socklen_t len = sizeof(val);
317 if (getsockopt(*ps, IPPROTO_IP, IP_MULTICAST_IF, (char *) &val, &len) < 0) {
318 lua_pushnil(L);
319 lua_pushstring(L, "getsockopt failed");
320 return 2;
321 }
322 lua_pushstring(L, inet_ntoa(val));
323 return 1;
324}
325
326/*------------------------------------------------------*/
327int opt_set_ip_add_membership(lua_State *L, p_socket ps)
328{
329 return opt_setmembership(L, ps, IPPROTO_IP, IP_ADD_MEMBERSHIP);
330}
331
332int opt_set_ip_drop_membersip(lua_State *L, p_socket ps)
333{
334 return opt_setmembership(L, ps, IPPROTO_IP, IP_DROP_MEMBERSHIP);
335}
336
337/*------------------------------------------------------*/
338int opt_set_ip6_add_membership(lua_State *L, p_socket ps)
339{
340 return opt_ip6_setmembership(L, ps, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP);
341}
342
343int opt_set_ip6_drop_membersip(lua_State *L, p_socket ps)
344{
345 return opt_ip6_setmembership(L, ps, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP);
346}
347
348/*------------------------------------------------------*/
349int opt_get_ip6_v6only(lua_State *L, p_socket ps)
350{
351 return opt_getboolean(L, ps, IPPROTO_IPV6, IPV6_V6ONLY);
352}
353
354int opt_set_ip6_v6only(lua_State *L, p_socket ps)
355{
356 return opt_setboolean(L, ps, IPPROTO_IPV6, IPV6_V6ONLY);
357}
358
359/*------------------------------------------------------*/
360int opt_get_error(lua_State *L, p_socket ps)
361{
362 int val = 0;
363 socklen_t len = sizeof(val);
364 if (getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *) &val, &len) < 0) {
365 lua_pushnil(L);
366 lua_pushstring(L, "getsockopt failed");
367 return 2;
368 }
369 lua_pushstring(L, socket_strerror(val));
370 return 1;
371}
372
373/*=========================================================================*\
374* Auxiliar functions
375\*=========================================================================*/
376static int opt_setmembership(lua_State *L, p_socket ps, int level, int name)
377{
378 struct ip_mreq val; /* obj, name, table */
379 if (!lua_istable(L, 3)) auxiliar_typeerror(L,3,lua_typename(L, LUA_TTABLE));
380 lua_pushstring(L, "multiaddr");
381 lua_gettable(L, 3);
382 if (!lua_isstring(L, -1))
383 luaL_argerror(L, 3, "string 'multiaddr' field expected");
384 if (!inet_aton(lua_tostring(L, -1), &val.imr_multiaddr))
385 luaL_argerror(L, 3, "invalid 'multiaddr' ip address");
386 lua_pushstring(L, "interface");
387 lua_gettable(L, 3);
388 if (!lua_isstring(L, -1))
389 luaL_argerror(L, 3, "string 'interface' field expected");
390 val.imr_interface.s_addr = htonl(INADDR_ANY);
391 if (strcmp(lua_tostring(L, -1), "*") &&
392 !inet_aton(lua_tostring(L, -1), &val.imr_interface))
393 luaL_argerror(L, 3, "invalid 'interface' ip address");
394 return opt_set(L, ps, level, name, (char *) &val, sizeof(val));
395}
396
397static int opt_ip6_setmembership(lua_State *L, p_socket ps, int level, int name)
398{
399 struct ipv6_mreq val; /* obj, opt-name, table */
400 memset(&val, 0, sizeof(val));
401 if (!lua_istable(L, 3)) auxiliar_typeerror(L,3,lua_typename(L, LUA_TTABLE));
402 lua_pushstring(L, "multiaddr");
403 lua_gettable(L, 3);
404 if (!lua_isstring(L, -1))
405 luaL_argerror(L, 3, "string 'multiaddr' field expected");
406 if (!inet_pton(AF_INET6, lua_tostring(L, -1), &val.ipv6mr_multiaddr))
407 luaL_argerror(L, 3, "invalid 'multiaddr' ip address");
408 lua_pushstring(L, "interface");
409 lua_gettable(L, 3);
410 /* By default we listen to interface on default route
411 * (sigh). However, interface= can override it. We should
412 * support either number, or name for it. Waiting for
413 * windows port of if_nametoindex */
414 if (!lua_isnil(L, -1)) {
415 if (lua_isnumber(L, -1)) {
416 val.ipv6mr_interface = (unsigned int) lua_tonumber(L, -1);
417 } else
418 luaL_argerror(L, -1, "number 'interface' field expected");
419 }
420 return opt_set(L, ps, level, name, (char *) &val, sizeof(val));
421}
422
423static
424int opt_get(lua_State *L, p_socket ps, int level, int name, void *val, int* len)
425{
426 socklen_t socklen = *len;
427 if (getsockopt(*ps, level, name, (char *) val, &socklen) < 0) {
428 lua_pushnil(L);
429 lua_pushstring(L, "getsockopt failed");
430 return 2;
431 }
432 *len = socklen;
433 return 0;
434}
435
436static
437int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len)
438{
439 if (setsockopt(*ps, level, name, (char *) val, len) < 0) {
440 lua_pushnil(L);
441 lua_pushstring(L, "setsockopt failed");
442 return 2;
443 }
444 lua_pushnumber(L, 1);
445 return 1;
446}
447
448static int opt_getboolean(lua_State *L, p_socket ps, int level, int name)
449{
450 int val = 0;
451 int len = sizeof(val);
452 int err = opt_get(L, ps, level, name, (char *) &val, &len);
453 if (err)
454 return err;
455 lua_pushboolean(L, val);
456 return 1;
457}
458
459static int opt_setboolean(lua_State *L, p_socket ps, int level, int name)
460{
461 int val = auxiliar_checkboolean(L, 3); /* obj, name, bool */
462 return opt_set(L, ps, level, name, (char *) &val, sizeof(val));
463}
464
465static int opt_getint(lua_State *L, p_socket ps, int level, int name)
466{
467 int val = 0;
468 int len = sizeof(val);
469 int err = opt_get(L, ps, level, name, (char *) &val, &len);
470 if (err)
471 return err;
472 lua_pushnumber(L, val);
473 return 1;
474}
475
476static int opt_setint(lua_State *L, p_socket ps, int level, int name)
477{
478 int val = (int) lua_tonumber(L, 3); /* obj, name, int */
479 return opt_set(L, ps, level, name, (char *) &val, sizeof(val));
480}
diff --git a/vendor/luasocket/src/options.h b/vendor/luasocket/src/options.h
new file mode 100644
index 00000000..456eeb5f
--- /dev/null
+++ b/vendor/luasocket/src/options.h
@@ -0,0 +1,113 @@
1#ifndef OPTIONS_H
2#define OPTIONS_H
3/*=========================================================================*\
4* Common option interface
5* LuaSocket toolkit
6*
7* This module provides a common interface to socket options, used mainly by
8* modules UDP and TCP.
9\*=========================================================================*/
10
11#include "luasocket.h"
12#include "socket.h"
13
14/* option registry */
15typedef struct t_opt {
16 const char *name;
17 int (*func)(lua_State *L, p_socket ps);
18} t_opt;
19typedef t_opt *p_opt;
20
21#ifndef _WIN32
22#pragma GCC visibility push(hidden)
23#endif
24
25int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps);
26int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps);
27
28int opt_set_reuseaddr(lua_State *L, p_socket ps);
29int opt_get_reuseaddr(lua_State *L, p_socket ps);
30
31int opt_set_reuseport(lua_State *L, p_socket ps);
32int opt_get_reuseport(lua_State *L, p_socket ps);
33
34int opt_set_tcp_nodelay(lua_State *L, p_socket ps);
35int opt_get_tcp_nodelay(lua_State *L, p_socket ps);
36
37#ifdef TCP_KEEPIDLE
38int opt_set_tcp_keepidle(lua_State *L, p_socket ps);
39int opt_get_tcp_keepidle(lua_State *L, p_socket ps);
40#endif
41
42#ifdef TCP_KEEPCNT
43int opt_set_tcp_keepcnt(lua_State *L, p_socket ps);
44int opt_get_tcp_keepcnt(lua_State *L, p_socket ps);
45#endif
46
47#ifdef TCP_KEEPINTVL
48int opt_set_tcp_keepintvl(lua_State *L, p_socket ps);
49int opt_get_tcp_keepintvl(lua_State *L, p_socket ps);
50#endif
51
52#ifdef TCP_DEFER_ACCEPT
53int opt_set_tcp_defer_accept(lua_State *L, p_socket ps);
54#endif
55
56int opt_set_keepalive(lua_State *L, p_socket ps);
57int opt_get_keepalive(lua_State *L, p_socket ps);
58
59int opt_set_dontroute(lua_State *L, p_socket ps);
60int opt_get_dontroute(lua_State *L, p_socket ps);
61
62int opt_set_broadcast(lua_State *L, p_socket ps);
63int opt_get_broadcast(lua_State *L, p_socket ps);
64
65int opt_set_recv_buf_size(lua_State *L, p_socket ps);
66int opt_get_recv_buf_size(lua_State *L, p_socket ps);
67
68int opt_set_send_buf_size(lua_State *L, p_socket ps);
69int opt_get_send_buf_size(lua_State *L, p_socket ps);
70
71#ifdef TCP_FASTOPEN
72int opt_set_tcp_fastopen(lua_State *L, p_socket ps);
73#endif
74#ifdef TCP_FASTOPEN_CONNECT
75int opt_set_tcp_fastopen_connect(lua_State *L, p_socket ps);
76#endif
77
78int opt_set_ip6_unicast_hops(lua_State *L, p_socket ps);
79int opt_get_ip6_unicast_hops(lua_State *L, p_socket ps);
80
81int opt_set_ip6_multicast_hops(lua_State *L, p_socket ps);
82int opt_get_ip6_multicast_hops(lua_State *L, p_socket ps);
83
84int opt_set_ip_multicast_loop(lua_State *L, p_socket ps);
85int opt_get_ip_multicast_loop(lua_State *L, p_socket ps);
86
87int opt_set_ip6_multicast_loop(lua_State *L, p_socket ps);
88int opt_get_ip6_multicast_loop(lua_State *L, p_socket ps);
89
90int opt_set_linger(lua_State *L, p_socket ps);
91int opt_get_linger(lua_State *L, p_socket ps);
92
93int opt_set_ip_multicast_ttl(lua_State *L, p_socket ps);
94
95int opt_set_ip_multicast_if(lua_State *L, p_socket ps);
96int opt_get_ip_multicast_if(lua_State *L, p_socket ps);
97
98int opt_set_ip_add_membership(lua_State *L, p_socket ps);
99int opt_set_ip_drop_membersip(lua_State *L, p_socket ps);
100
101int opt_set_ip6_add_membership(lua_State *L, p_socket ps);
102int opt_set_ip6_drop_membersip(lua_State *L, p_socket ps);
103
104int opt_set_ip6_v6only(lua_State *L, p_socket ps);
105int opt_get_ip6_v6only(lua_State *L, p_socket ps);
106
107int opt_get_error(lua_State *L, p_socket ps);
108
109#ifndef _WIN32
110#pragma GCC visibility pop
111#endif
112
113#endif
diff --git a/vendor/luasocket/src/pierror.h b/vendor/luasocket/src/pierror.h
new file mode 100644
index 00000000..cb773ab7
--- /dev/null
+++ b/vendor/luasocket/src/pierror.h
@@ -0,0 +1,28 @@
1#ifndef PIERROR_H
2#define PIERROR_H
3/*=========================================================================*\
4* Error messages
5* Defines platform independent error messages
6\*=========================================================================*/
7
8#define PIE_HOST_NOT_FOUND "host not found"
9#define PIE_ADDRINUSE "address already in use"
10#define PIE_ISCONN "already connected"
11#define PIE_ACCESS "permission denied"
12#define PIE_CONNREFUSED "connection refused"
13#define PIE_CONNABORTED "closed"
14#define PIE_CONNRESET "closed"
15#define PIE_TIMEDOUT "timeout"
16#define PIE_AGAIN "temporary failure in name resolution"
17#define PIE_BADFLAGS "invalid value for ai_flags"
18#define PIE_BADHINTS "invalid value for hints"
19#define PIE_FAIL "non-recoverable failure in name resolution"
20#define PIE_FAMILY "ai_family not supported"
21#define PIE_MEMORY "memory allocation failure"
22#define PIE_NONAME "host or service not provided, or not known"
23#define PIE_OVERFLOW "argument buffer overflow"
24#define PIE_PROTOCOL "resolved protocol is unknown"
25#define PIE_SERVICE "service not supported for socket type"
26#define PIE_SOCKTYPE "ai_socktype not supported"
27
28#endif
diff --git a/vendor/luasocket/src/select.c b/vendor/luasocket/src/select.c
new file mode 100644
index 00000000..bb47c459
--- /dev/null
+++ b/vendor/luasocket/src/select.c
@@ -0,0 +1,214 @@
1/*=========================================================================*\
2* Select implementation
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6
7#include "socket.h"
8#include "timeout.h"
9#include "select.h"
10
11#include <string.h>
12
13/*=========================================================================*\
14* Internal function prototypes.
15\*=========================================================================*/
16static t_socket getfd(lua_State *L);
17static int dirty(lua_State *L);
18static void collect_fd(lua_State *L, int tab, int itab,
19 fd_set *set, t_socket *max_fd);
20static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set);
21static void return_fd(lua_State *L, fd_set *set, t_socket max_fd,
22 int itab, int tab, int start);
23static void make_assoc(lua_State *L, int tab);
24static int global_select(lua_State *L);
25
26/* functions in library namespace */
27static luaL_Reg func[] = {
28 {"select", global_select},
29 {NULL, NULL}
30};
31
32/*-------------------------------------------------------------------------*\
33* Initializes module
34\*-------------------------------------------------------------------------*/
35int select_open(lua_State *L) {
36 lua_pushstring(L, "_SETSIZE");
37 lua_pushinteger(L, FD_SETSIZE);
38 lua_rawset(L, -3);
39 lua_pushstring(L, "_SOCKETINVALID");
40 lua_pushinteger(L, SOCKET_INVALID);
41 lua_rawset(L, -3);
42 luaL_setfuncs(L, func, 0);
43 return 0;
44}
45
46/*=========================================================================*\
47* Global Lua functions
48\*=========================================================================*/
49/*-------------------------------------------------------------------------*\
50* Waits for a set of sockets until a condition is met or timeout.
51\*-------------------------------------------------------------------------*/
52static int global_select(lua_State *L) {
53 int rtab, wtab, itab, ret, ndirty;
54 t_socket max_fd = SOCKET_INVALID;
55 fd_set rset, wset;
56 t_timeout tm;
57 double t = luaL_optnumber(L, 3, -1);
58 FD_ZERO(&rset); FD_ZERO(&wset);
59 lua_settop(L, 3);
60 lua_newtable(L); itab = lua_gettop(L);
61 lua_newtable(L); rtab = lua_gettop(L);
62 lua_newtable(L); wtab = lua_gettop(L);
63 collect_fd(L, 1, itab, &rset, &max_fd);
64 collect_fd(L, 2, itab, &wset, &max_fd);
65 ndirty = check_dirty(L, 1, rtab, &rset);
66 t = ndirty > 0? 0.0: t;
67 timeout_init(&tm, t, -1);
68 timeout_markstart(&tm);
69 ret = socket_select(max_fd+1, &rset, &wset, NULL, &tm);
70 if (ret > 0 || ndirty > 0) {
71 return_fd(L, &rset, max_fd+1, itab, rtab, ndirty);
72 return_fd(L, &wset, max_fd+1, itab, wtab, 0);
73 make_assoc(L, rtab);
74 make_assoc(L, wtab);
75 return 2;
76 } else if (ret == 0) {
77 lua_pushstring(L, "timeout");
78 return 3;
79 } else {
80 luaL_error(L, "select failed");
81 return 3;
82 }
83}
84
85/*=========================================================================*\
86* Internal functions
87\*=========================================================================*/
88static t_socket getfd(lua_State *L) {
89 t_socket fd = SOCKET_INVALID;
90 lua_pushstring(L, "getfd");
91 lua_gettable(L, -2);
92 if (!lua_isnil(L, -1)) {
93 lua_pushvalue(L, -2);
94 lua_call(L, 1, 1);
95 if (lua_isnumber(L, -1)) {
96 double numfd = lua_tonumber(L, -1);
97 fd = (numfd >= 0.0)? (t_socket) numfd: SOCKET_INVALID;
98 }
99 }
100 lua_pop(L, 1);
101 return fd;
102}
103
104static int dirty(lua_State *L) {
105 int is = 0;
106 lua_pushstring(L, "dirty");
107 lua_gettable(L, -2);
108 if (!lua_isnil(L, -1)) {
109 lua_pushvalue(L, -2);
110 lua_call(L, 1, 1);
111 is = lua_toboolean(L, -1);
112 }
113 lua_pop(L, 1);
114 return is;
115}
116
117static void collect_fd(lua_State *L, int tab, int itab,
118 fd_set *set, t_socket *max_fd) {
119 int i = 1, n = 0;
120 /* nil is the same as an empty table */
121 if (lua_isnil(L, tab)) return;
122 /* otherwise we need it to be a table */
123 luaL_checktype(L, tab, LUA_TTABLE);
124 for ( ;; ) {
125 t_socket fd;
126 lua_pushnumber(L, i);
127 lua_gettable(L, tab);
128 if (lua_isnil(L, -1)) {
129 lua_pop(L, 1);
130 break;
131 }
132 /* getfd figures out if this is a socket */
133 fd = getfd(L);
134 if (fd != SOCKET_INVALID) {
135 /* make sure we don't overflow the fd_set */
136#ifdef _WIN32
137 if (n >= FD_SETSIZE)
138 luaL_argerror(L, tab, "too many sockets");
139#else
140 if (fd >= FD_SETSIZE)
141 luaL_argerror(L, tab, "descriptor too large for set size");
142#endif
143 FD_SET(fd, set);
144 n++;
145 /* keep track of the largest descriptor so far */
146 if (*max_fd == SOCKET_INVALID || *max_fd < fd)
147 *max_fd = fd;
148 /* make sure we can map back from descriptor to the object */
149 lua_pushnumber(L, (lua_Number) fd);
150 lua_pushvalue(L, -2);
151 lua_settable(L, itab);
152 }
153 lua_pop(L, 1);
154 i = i + 1;
155 }
156}
157
158static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) {
159 int ndirty = 0, i = 1;
160 if (lua_isnil(L, tab))
161 return 0;
162 for ( ;; ) {
163 t_socket fd;
164 lua_pushnumber(L, i);
165 lua_gettable(L, tab);
166 if (lua_isnil(L, -1)) {
167 lua_pop(L, 1);
168 break;
169 }
170 fd = getfd(L);
171 if (fd != SOCKET_INVALID && dirty(L)) {
172 lua_pushnumber(L, ++ndirty);
173 lua_pushvalue(L, -2);
174 lua_settable(L, dtab);
175 FD_CLR(fd, set);
176 }
177 lua_pop(L, 1);
178 i = i + 1;
179 }
180 return ndirty;
181}
182
183static void return_fd(lua_State *L, fd_set *set, t_socket max_fd,
184 int itab, int tab, int start) {
185 t_socket fd;
186 for (fd = 0; fd < max_fd; fd++) {
187 if (FD_ISSET(fd, set)) {
188 lua_pushnumber(L, ++start);
189 lua_pushnumber(L, (lua_Number) fd);
190 lua_gettable(L, itab);
191 lua_settable(L, tab);
192 }
193 }
194}
195
196static void make_assoc(lua_State *L, int tab) {
197 int i = 1, atab;
198 lua_newtable(L); atab = lua_gettop(L);
199 for ( ;; ) {
200 lua_pushnumber(L, i);
201 lua_gettable(L, tab);
202 if (!lua_isnil(L, -1)) {
203 lua_pushnumber(L, i);
204 lua_pushvalue(L, -2);
205 lua_settable(L, atab);
206 lua_pushnumber(L, i);
207 lua_settable(L, atab);
208 } else {
209 lua_pop(L, 1);
210 break;
211 }
212 i = i+1;
213 }
214}
diff --git a/vendor/luasocket/src/select.h b/vendor/luasocket/src/select.h
new file mode 100644
index 00000000..5d45fe75
--- /dev/null
+++ b/vendor/luasocket/src/select.h
@@ -0,0 +1,23 @@
1#ifndef SELECT_H
2#define SELECT_H
3/*=========================================================================*\
4* Select implementation
5* LuaSocket toolkit
6*
7* Each object that can be passed to the select function has to export
8* method getfd() which returns the descriptor to be passed to the
9* underlying select function. Another method, dirty(), should return
10* true if there is data ready for reading (required for buffered input).
11\*=========================================================================*/
12
13#ifndef _WIN32
14#pragma GCC visibility push(hidden)
15#endif
16
17int select_open(lua_State *L);
18
19#ifndef _WIN32
20#pragma GCC visibility pop
21#endif
22
23#endif /* SELECT_H */
diff --git a/vendor/luasocket/src/serial.c b/vendor/luasocket/src/serial.c
new file mode 100644
index 00000000..21485d3e
--- /dev/null
+++ b/vendor/luasocket/src/serial.c
@@ -0,0 +1,171 @@
1/*=========================================================================*\
2* Serial stream
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6
7#include "auxiliar.h"
8#include "socket.h"
9#include "options.h"
10#include "unix.h"
11
12#include <string.h>
13#include <sys/un.h>
14
15/*
16Reuses userdata definition from unix.h, since it is useful for all
17stream-like objects.
18
19If we stored the serial path for use in error messages or userdata
20printing, we might need our own userdata definition.
21
22Group usage is semi-inherited from unix.c, but unnecessary since we
23have only one object type.
24*/
25
26/*=========================================================================*\
27* Internal function prototypes
28\*=========================================================================*/
29static int global_create(lua_State *L);
30static int meth_send(lua_State *L);
31static int meth_receive(lua_State *L);
32static int meth_close(lua_State *L);
33static int meth_settimeout(lua_State *L);
34static int meth_getfd(lua_State *L);
35static int meth_setfd(lua_State *L);
36static int meth_dirty(lua_State *L);
37static int meth_getstats(lua_State *L);
38static int meth_setstats(lua_State *L);
39
40/* serial object methods */
41static luaL_Reg serial_methods[] = {
42 {"__gc", meth_close},
43 {"__tostring", auxiliar_tostring},
44 {"close", meth_close},
45 {"dirty", meth_dirty},
46 {"getfd", meth_getfd},
47 {"getstats", meth_getstats},
48 {"setstats", meth_setstats},
49 {"receive", meth_receive},
50 {"send", meth_send},
51 {"setfd", meth_setfd},
52 {"settimeout", meth_settimeout},
53 {NULL, NULL}
54};
55
56/*-------------------------------------------------------------------------*\
57* Initializes module
58\*-------------------------------------------------------------------------*/
59LUASOCKET_API int luaopen_socket_serial(lua_State *L) {
60 /* create classes */
61 auxiliar_newclass(L, "serial{client}", serial_methods);
62 /* create class groups */
63 auxiliar_add2group(L, "serial{client}", "serial{any}");
64 lua_pushcfunction(L, global_create);
65 return 1;
66}
67
68/*=========================================================================*\
69* Lua methods
70\*=========================================================================*/
71/*-------------------------------------------------------------------------*\
72* Just call buffered IO methods
73\*-------------------------------------------------------------------------*/
74static int meth_send(lua_State *L) {
75 p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
76 return buffer_meth_send(L, &un->buf);
77}
78
79static int meth_receive(lua_State *L) {
80 p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
81 return buffer_meth_receive(L, &un->buf);
82}
83
84static int meth_getstats(lua_State *L) {
85 p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
86 return buffer_meth_getstats(L, &un->buf);
87}
88
89static int meth_setstats(lua_State *L) {
90 p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1);
91 return buffer_meth_setstats(L, &un->buf);
92}
93
94/*-------------------------------------------------------------------------*\
95* Select support methods
96\*-------------------------------------------------------------------------*/
97static int meth_getfd(lua_State *L) {
98 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
99 lua_pushnumber(L, (int) un->sock);
100 return 1;
101}
102
103/* this is very dangerous, but can be handy for those that are brave enough */
104static int meth_setfd(lua_State *L) {
105 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
106 un->sock = (t_socket) luaL_checknumber(L, 2);
107 return 0;
108}
109
110static int meth_dirty(lua_State *L) {
111 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
112 lua_pushboolean(L, !buffer_isempty(&un->buf));
113 return 1;
114}
115
116/*-------------------------------------------------------------------------*\
117* Closes socket used by object
118\*-------------------------------------------------------------------------*/
119static int meth_close(lua_State *L)
120{
121 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
122 socket_destroy(&un->sock);
123 lua_pushnumber(L, 1);
124 return 1;
125}
126
127
128/*-------------------------------------------------------------------------*\
129* Just call tm methods
130\*-------------------------------------------------------------------------*/
131static int meth_settimeout(lua_State *L) {
132 p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1);
133 return timeout_meth_settimeout(L, &un->tm);
134}
135
136/*=========================================================================*\
137* Library functions
138\*=========================================================================*/
139
140
141/*-------------------------------------------------------------------------*\
142* Creates a serial object
143\*-------------------------------------------------------------------------*/
144static int global_create(lua_State *L) {
145 const char* path = luaL_checkstring(L, 1);
146
147 /* allocate unix object */
148 p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix));
149
150 /* open serial device */
151 t_socket sock = open(path, O_NOCTTY|O_RDWR);
152
153 /*printf("open %s on %d\n", path, sock);*/
154
155 if (sock < 0) {
156 lua_pushnil(L);
157 lua_pushstring(L, socket_strerror(errno));
158 lua_pushnumber(L, errno);
159 return 3;
160 }
161 /* set its type as client object */
162 auxiliar_setclass(L, "serial{client}", -1);
163 /* initialize remaining structure fields */
164 socket_setnonblocking(&sock);
165 un->sock = sock;
166 io_init(&un->io, (p_send) socket_write, (p_recv) socket_read,
167 (p_error) socket_ioerror, &un->sock);
168 timeout_init(&un->tm, -1, -1);
169 buffer_init(&un->buf, &un->io, &un->tm);
170 return 1;
171}
diff --git a/vendor/luasocket/src/smtp.lua b/vendor/luasocket/src/smtp.lua
new file mode 100644
index 00000000..b113d006
--- /dev/null
+++ b/vendor/luasocket/src/smtp.lua
@@ -0,0 +1,256 @@
1-----------------------------------------------------------------------------
2-- SMTP client support for the Lua language.
3-- LuaSocket toolkit.
4-- Author: Diego Nehab
5-----------------------------------------------------------------------------
6
7-----------------------------------------------------------------------------
8-- Declare module and import dependencies
9-----------------------------------------------------------------------------
10local base = _G
11local coroutine = require("coroutine")
12local string = require("string")
13local math = require("math")
14local os = require("os")
15local socket = require("socket")
16local tp = require("socket.tp")
17local ltn12 = require("ltn12")
18local headers = require("socket.headers")
19local mime = require("mime")
20
21socket.smtp = {}
22local _M = socket.smtp
23
24-----------------------------------------------------------------------------
25-- Program constants
26-----------------------------------------------------------------------------
27-- timeout for connection
28_M.TIMEOUT = 60
29-- default server used to send e-mails
30_M.SERVER = "localhost"
31-- default port
32_M.PORT = 25
33-- domain used in HELO command and default sendmail
34-- If we are under a CGI, try to get from environment
35_M.DOMAIN = os.getenv("SERVER_NAME") or "localhost"
36-- default time zone (means we don't know)
37_M.ZONE = "-0000"
38
39---------------------------------------------------------------------------
40-- Low level SMTP API
41-----------------------------------------------------------------------------
42local metat = { __index = {} }
43
44function metat.__index:greet(domain)
45 self.try(self.tp:check("2.."))
46 self.try(self.tp:command("EHLO", domain or _M.DOMAIN))
47 return socket.skip(1, self.try(self.tp:check("2..")))
48end
49
50function metat.__index:mail(from)
51 self.try(self.tp:command("MAIL", "FROM:" .. from))
52 return self.try(self.tp:check("2.."))
53end
54
55function metat.__index:rcpt(to)
56 self.try(self.tp:command("RCPT", "TO:" .. to))
57 return self.try(self.tp:check("2.."))
58end
59
60function metat.__index:data(src, step)
61 self.try(self.tp:command("DATA"))
62 self.try(self.tp:check("3.."))
63 self.try(self.tp:source(src, step))
64 self.try(self.tp:send("\r\n.\r\n"))
65 return self.try(self.tp:check("2.."))
66end
67
68function metat.__index:quit()
69 self.try(self.tp:command("QUIT"))
70 return self.try(self.tp:check("2.."))
71end
72
73function metat.__index:close()
74 return self.tp:close()
75end
76
77function metat.__index:login(user, password)
78 self.try(self.tp:command("AUTH", "LOGIN"))
79 self.try(self.tp:check("3.."))
80 self.try(self.tp:send(mime.b64(user) .. "\r\n"))
81 self.try(self.tp:check("3.."))
82 self.try(self.tp:send(mime.b64(password) .. "\r\n"))
83 return self.try(self.tp:check("2.."))
84end
85
86function metat.__index:plain(user, password)
87 local auth = "PLAIN " .. mime.b64("\0" .. user .. "\0" .. password)
88 self.try(self.tp:command("AUTH", auth))
89 return self.try(self.tp:check("2.."))
90end
91
92function metat.__index:auth(user, password, ext)
93 if not user or not password then return 1 end
94 if string.find(ext, "AUTH[^\n]+LOGIN") then
95 return self:login(user, password)
96 elseif string.find(ext, "AUTH[^\n]+PLAIN") then
97 return self:plain(user, password)
98 else
99 self.try(nil, "authentication not supported")
100 end
101end
102
103-- send message or throw an exception
104function metat.__index:send(mailt)
105 self:mail(mailt.from)
106 if base.type(mailt.rcpt) == "table" then
107 for i,v in base.ipairs(mailt.rcpt) do
108 self:rcpt(v)
109 end
110 else
111 self:rcpt(mailt.rcpt)
112 end
113 self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step)
114end
115
116function _M.open(server, port, create)
117 local tp = socket.try(tp.connect(server or _M.SERVER, port or _M.PORT,
118 _M.TIMEOUT, create))
119 local s = base.setmetatable({tp = tp}, metat)
120 -- make sure tp is closed if we get an exception
121 s.try = socket.newtry(function()
122 s:close()
123 end)
124 return s
125end
126
127-- convert headers to lowercase
128local function lower_headers(headers)
129 local lower = {}
130 for i,v in base.pairs(headers or lower) do
131 lower[string.lower(i)] = v
132 end
133 return lower
134end
135
136---------------------------------------------------------------------------
137-- Multipart message source
138-----------------------------------------------------------------------------
139-- returns a hopefully unique mime boundary
140local seqno = 0
141local function newboundary()
142 seqno = seqno + 1
143 return string.format('%s%05d==%05u', os.date('%d%m%Y%H%M%S'),
144 math.random(0, 99999), seqno)
145end
146
147-- send_message forward declaration
148local send_message
149
150-- yield the headers all at once, it's faster
151local function send_headers(tosend)
152 local canonic = headers.canonic
153 local h = "\r\n"
154 for f,v in base.pairs(tosend) do
155 h = (canonic[f] or f) .. ': ' .. v .. "\r\n" .. h
156 end
157 coroutine.yield(h)
158end
159
160-- yield multipart message body from a multipart message table
161local function send_multipart(mesgt)
162 -- make sure we have our boundary and send headers
163 local bd = newboundary()
164 local headers = lower_headers(mesgt.headers or {})
165 headers['content-type'] = headers['content-type'] or 'multipart/mixed'
166 headers['content-type'] = headers['content-type'] ..
167 '; boundary="' .. bd .. '"'
168 send_headers(headers)
169 -- send preamble
170 if mesgt.body.preamble then
171 coroutine.yield(mesgt.body.preamble)
172 coroutine.yield("\r\n")
173 end
174 -- send each part separated by a boundary
175 for i, m in base.ipairs(mesgt.body) do
176 coroutine.yield("\r\n--" .. bd .. "\r\n")
177 send_message(m)
178 end
179 -- send last boundary
180 coroutine.yield("\r\n--" .. bd .. "--\r\n\r\n")
181 -- send epilogue
182 if mesgt.body.epilogue then
183 coroutine.yield(mesgt.body.epilogue)
184 coroutine.yield("\r\n")
185 end
186end
187
188-- yield message body from a source
189local function send_source(mesgt)
190 -- make sure we have a content-type
191 local headers = lower_headers(mesgt.headers or {})
192 headers['content-type'] = headers['content-type'] or
193 'text/plain; charset="iso-8859-1"'
194 send_headers(headers)
195 -- send body from source
196 while true do
197 local chunk, err = mesgt.body()
198 if err then coroutine.yield(nil, err)
199 elseif chunk then coroutine.yield(chunk)
200 else break end
201 end
202end
203
204-- yield message body from a string
205local function send_string(mesgt)
206 -- make sure we have a content-type
207 local headers = lower_headers(mesgt.headers or {})
208 headers['content-type'] = headers['content-type'] or
209 'text/plain; charset="iso-8859-1"'
210 send_headers(headers)
211 -- send body from string
212 coroutine.yield(mesgt.body)
213end
214
215-- message source
216function send_message(mesgt)
217 if base.type(mesgt.body) == "table" then send_multipart(mesgt)
218 elseif base.type(mesgt.body) == "function" then send_source(mesgt)
219 else send_string(mesgt) end
220end
221
222-- set defaul headers
223local function adjust_headers(mesgt)
224 local lower = lower_headers(mesgt.headers)
225 lower["date"] = lower["date"] or
226 os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or _M.ZONE)
227 lower["x-mailer"] = lower["x-mailer"] or socket._VERSION
228 -- this can't be overriden
229 lower["mime-version"] = "1.0"
230 return lower
231end
232
233function _M.message(mesgt)
234 mesgt.headers = adjust_headers(mesgt)
235 -- create and return message source
236 local co = coroutine.create(function() send_message(mesgt) end)
237 return function()
238 local ret, a, b = coroutine.resume(co)
239 if ret then return a, b
240 else return nil, a end
241 end
242end
243
244---------------------------------------------------------------------------
245-- High level SMTP API
246-----------------------------------------------------------------------------
247_M.send = socket.protect(function(mailt)
248 local s = _M.open(mailt.server, mailt.port, mailt.create)
249 local ext = s:greet(mailt.domain)
250 s:auth(mailt.user, mailt.password, ext)
251 s:send(mailt)
252 s:quit()
253 return s:close()
254end)
255
256return _M \ No newline at end of file
diff --git a/vendor/luasocket/src/socket.h b/vendor/luasocket/src/socket.h
new file mode 100755
index 00000000..2555bab6
--- /dev/null
+++ b/vendor/luasocket/src/socket.h
@@ -0,0 +1,75 @@
1#ifndef SOCKET_H
2#define SOCKET_H
3/*=========================================================================*\
4* Socket compatibilization module
5* LuaSocket toolkit
6*
7* BSD Sockets and WinSock are similar, but there are a few irritating
8* differences. Also, not all *nix platforms behave the same. This module
9* (and the associated usocket.h and wsocket.h) factor these differences and
10* creates a interface compatible with the io.h module.
11\*=========================================================================*/
12#include "io.h"
13
14/*=========================================================================*\
15* Platform specific compatibilization
16\*=========================================================================*/
17#ifdef _WIN32
18#include "wsocket.h"
19#define LUA_GAI_STRERROR gai_strerrorA
20#else
21#include "usocket.h"
22#define LUA_GAI_STRERROR gai_strerror
23#endif
24
25/*=========================================================================*\
26* The connect and accept functions accept a timeout and their
27* implementations are somewhat complicated. We chose to move
28* the timeout control into this module for these functions in
29* order to simplify the modules that use them.
30\*=========================================================================*/
31#include "timeout.h"
32
33/* convenient shorthand */
34typedef struct sockaddr SA;
35
36/*=========================================================================*\
37* Functions bellow implement a comfortable platform independent
38* interface to sockets
39\*=========================================================================*/
40
41#ifndef _WIN32
42#pragma GCC visibility push(hidden)
43#endif
44
45int socket_waitfd(p_socket ps, int sw, p_timeout tm);
46int socket_open(void);
47int socket_close(void);
48void socket_destroy(p_socket ps);
49int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds, p_timeout tm);
50int socket_create(p_socket ps, int domain, int type, int protocol);
51int socket_bind(p_socket ps, SA *addr, socklen_t addr_len);
52int socket_listen(p_socket ps, int backlog);
53void socket_shutdown(p_socket ps, int how);
54int socket_connect(p_socket ps, SA *addr, socklen_t addr_len, p_timeout tm);
55int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *addr_len, p_timeout tm);
56int socket_send(p_socket ps, const char *data, size_t count, size_t *sent, p_timeout tm);
57int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, SA *addr, socklen_t addr_len, p_timeout tm);
58int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm);
59int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, SA *addr, socklen_t *addr_len, p_timeout tm);
60int socket_write(p_socket ps, const char *data, size_t count, size_t *sent, p_timeout tm);
61int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm);
62void socket_setblocking(p_socket ps);
63void socket_setnonblocking(p_socket ps);
64int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp);
65int socket_gethostbyname(const char *addr, struct hostent **hp);
66const char *socket_hoststrerror(int err);
67const char *socket_strerror(int err);
68const char *socket_ioerror(p_socket ps, int err);
69const char *socket_gaistrerror(int err);
70
71#ifndef _WIN32
72#pragma GCC visibility pop
73#endif
74
75#endif /* SOCKET_H */
diff --git a/vendor/luasocket/src/socket.lua b/vendor/luasocket/src/socket.lua
new file mode 100644
index 00000000..d1c0b164
--- /dev/null
+++ b/vendor/luasocket/src/socket.lua
@@ -0,0 +1,149 @@
1-----------------------------------------------------------------------------
2-- LuaSocket helper module
3-- Author: Diego Nehab
4-----------------------------------------------------------------------------
5
6-----------------------------------------------------------------------------
7-- Declare module and import dependencies
8-----------------------------------------------------------------------------
9local base = _G
10local string = require("string")
11local math = require("math")
12local socket = require("socket.core")
13
14local _M = socket
15
16-----------------------------------------------------------------------------
17-- Exported auxiliar functions
18-----------------------------------------------------------------------------
19function _M.connect4(address, port, laddress, lport)
20 return socket.connect(address, port, laddress, lport, "inet")
21end
22
23function _M.connect6(address, port, laddress, lport)
24 return socket.connect(address, port, laddress, lport, "inet6")
25end
26
27function _M.bind(host, port, backlog)
28 if host == "*" then host = "0.0.0.0" end
29 local addrinfo, err = socket.dns.getaddrinfo(host);
30 if not addrinfo then return nil, err end
31 local sock, res
32 err = "no info on address"
33 for i, alt in base.ipairs(addrinfo) do
34 if alt.family == "inet" then
35 sock, err = socket.tcp4()
36 else
37 sock, err = socket.tcp6()
38 end
39 if not sock then return nil, err end
40 sock:setoption("reuseaddr", true)
41 res, err = sock:bind(alt.addr, port)
42 if not res then
43 sock:close()
44 else
45 res, err = sock:listen(backlog)
46 if not res then
47 sock:close()
48 else
49 return sock
50 end
51 end
52 end
53 return nil, err
54end
55
56_M.try = _M.newtry()
57
58function _M.choose(table)
59 return function(name, opt1, opt2)
60 if base.type(name) ~= "string" then
61 name, opt1, opt2 = "default", name, opt1
62 end
63 local f = table[name or "nil"]
64 if not f then base.error("unknown key (".. base.tostring(name) ..")", 3)
65 else return f(opt1, opt2) end
66 end
67end
68
69-----------------------------------------------------------------------------
70-- Socket sources and sinks, conforming to LTN12
71-----------------------------------------------------------------------------
72-- create namespaces inside LuaSocket namespace
73local sourcet, sinkt = {}, {}
74_M.sourcet = sourcet
75_M.sinkt = sinkt
76
77_M.BLOCKSIZE = 2048
78
79sinkt["close-when-done"] = function(sock)
80 return base.setmetatable({
81 getfd = function() return sock:getfd() end,
82 dirty = function() return sock:dirty() end
83 }, {
84 __call = function(self, chunk, err)
85 if not chunk then
86 sock:close()
87 return 1
88 else return sock:send(chunk) end
89 end
90 })
91end
92
93sinkt["keep-open"] = function(sock)
94 return base.setmetatable({
95 getfd = function() return sock:getfd() end,
96 dirty = function() return sock:dirty() end
97 }, {
98 __call = function(self, chunk, err)
99 if chunk then return sock:send(chunk)
100 else return 1 end
101 end
102 })
103end
104
105sinkt["default"] = sinkt["keep-open"]
106
107_M.sink = _M.choose(sinkt)
108
109sourcet["by-length"] = function(sock, length)
110 return base.setmetatable({
111 getfd = function() return sock:getfd() end,
112 dirty = function() return sock:dirty() end
113 }, {
114 __call = function()
115 if length <= 0 then return nil end
116 local size = math.min(socket.BLOCKSIZE, length)
117 local chunk, err = sock:receive(size)
118 if err then return nil, err end
119 length = length - string.len(chunk)
120 return chunk
121 end
122 })
123end
124
125sourcet["until-closed"] = function(sock)
126 local done
127 return base.setmetatable({
128 getfd = function() return sock:getfd() end,
129 dirty = function() return sock:dirty() end
130 }, {
131 __call = function()
132 if done then return nil end
133 local chunk, err, partial = sock:receive(socket.BLOCKSIZE)
134 if not err then return chunk
135 elseif err == "closed" then
136 sock:close()
137 done = 1
138 return partial
139 else return nil, err end
140 end
141 })
142end
143
144
145sourcet["default"] = sourcet["until-closed"]
146
147_M.source = _M.choose(sourcet)
148
149return _M
diff --git a/vendor/luasocket/src/tcp.c b/vendor/luasocket/src/tcp.c
new file mode 100644
index 00000000..e84db845
--- /dev/null
+++ b/vendor/luasocket/src/tcp.c
@@ -0,0 +1,480 @@
1/*=========================================================================*\
2* TCP object
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6
7#include "auxiliar.h"
8#include "socket.h"
9#include "inet.h"
10#include "options.h"
11#include "tcp.h"
12
13#include <string.h>
14
15/*=========================================================================*\
16* Internal function prototypes
17\*=========================================================================*/
18static int global_create(lua_State *L);
19static int global_create4(lua_State *L);
20static int global_create6(lua_State *L);
21static int global_connect(lua_State *L);
22static int meth_connect(lua_State *L);
23static int meth_listen(lua_State *L);
24static int meth_getfamily(lua_State *L);
25static int meth_bind(lua_State *L);
26static int meth_send(lua_State *L);
27static int meth_getstats(lua_State *L);
28static int meth_setstats(lua_State *L);
29static int meth_getsockname(lua_State *L);
30static int meth_getpeername(lua_State *L);
31static int meth_shutdown(lua_State *L);
32static int meth_receive(lua_State *L);
33static int meth_accept(lua_State *L);
34static int meth_close(lua_State *L);
35static int meth_getoption(lua_State *L);
36static int meth_setoption(lua_State *L);
37static int meth_gettimeout(lua_State *L);
38static int meth_settimeout(lua_State *L);
39static int meth_getfd(lua_State *L);
40static int meth_setfd(lua_State *L);
41static int meth_dirty(lua_State *L);
42
43/* tcp object methods */
44static luaL_Reg tcp_methods[] = {
45 {"__gc", meth_close},
46 {"__tostring", auxiliar_tostring},
47 {"accept", meth_accept},
48 {"bind", meth_bind},
49 {"close", meth_close},
50 {"connect", meth_connect},
51 {"dirty", meth_dirty},
52 {"getfamily", meth_getfamily},
53 {"getfd", meth_getfd},
54 {"getoption", meth_getoption},
55 {"getpeername", meth_getpeername},
56 {"getsockname", meth_getsockname},
57 {"getstats", meth_getstats},
58 {"setstats", meth_setstats},
59 {"listen", meth_listen},
60 {"receive", meth_receive},
61 {"send", meth_send},
62 {"setfd", meth_setfd},
63 {"setoption", meth_setoption},
64 {"setpeername", meth_connect},
65 {"setsockname", meth_bind},
66 {"settimeout", meth_settimeout},
67 {"gettimeout", meth_gettimeout},
68 {"shutdown", meth_shutdown},
69 {NULL, NULL}
70};
71
72/* socket option handlers */
73static t_opt optget[] = {
74 {"keepalive", opt_get_keepalive},
75 {"reuseaddr", opt_get_reuseaddr},
76 {"reuseport", opt_get_reuseport},
77 {"tcp-nodelay", opt_get_tcp_nodelay},
78#ifdef TCP_KEEPIDLE
79 {"tcp-keepidle", opt_get_tcp_keepidle},
80#endif
81#ifdef TCP_KEEPCNT
82 {"tcp-keepcnt", opt_get_tcp_keepcnt},
83#endif
84#ifdef TCP_KEEPINTVL
85 {"tcp-keepintvl", opt_get_tcp_keepintvl},
86#endif
87 {"linger", opt_get_linger},
88 {"error", opt_get_error},
89 {"recv-buffer-size", opt_get_recv_buf_size},
90 {"send-buffer-size", opt_get_send_buf_size},
91 {NULL, NULL}
92};
93
94static t_opt optset[] = {
95 {"keepalive", opt_set_keepalive},
96 {"reuseaddr", opt_set_reuseaddr},
97 {"reuseport", opt_set_reuseport},
98 {"tcp-nodelay", opt_set_tcp_nodelay},
99#ifdef TCP_KEEPIDLE
100 {"tcp-keepidle", opt_set_tcp_keepidle},
101#endif
102#ifdef TCP_KEEPCNT
103 {"tcp-keepcnt", opt_set_tcp_keepcnt},
104#endif
105#ifdef TCP_KEEPINTVL
106 {"tcp-keepintvl", opt_set_tcp_keepintvl},
107#endif
108 {"ipv6-v6only", opt_set_ip6_v6only},
109 {"linger", opt_set_linger},
110 {"recv-buffer-size", opt_set_recv_buf_size},
111 {"send-buffer-size", opt_set_send_buf_size},
112#ifdef TCP_DEFER_ACCEPT
113 {"tcp-defer-accept", opt_set_tcp_defer_accept},
114#endif
115#ifdef TCP_FASTOPEN
116 {"tcp-fastopen", opt_set_tcp_fastopen},
117#endif
118#ifdef TCP_FASTOPEN_CONNECT
119 {"tcp-fastopen-connect", opt_set_tcp_fastopen_connect},
120#endif
121 {NULL, NULL}
122};
123
124/* functions in library namespace */
125static luaL_Reg func[] = {
126 {"tcp", global_create},
127 {"tcp4", global_create4},
128 {"tcp6", global_create6},
129 {"connect", global_connect},
130 {NULL, NULL}
131};
132
133/*-------------------------------------------------------------------------*\
134* Initializes module
135\*-------------------------------------------------------------------------*/
136int tcp_open(lua_State *L)
137{
138 /* create classes */
139 auxiliar_newclass(L, "tcp{master}", tcp_methods);
140 auxiliar_newclass(L, "tcp{client}", tcp_methods);
141 auxiliar_newclass(L, "tcp{server}", tcp_methods);
142 /* create class groups */
143 auxiliar_add2group(L, "tcp{master}", "tcp{any}");
144 auxiliar_add2group(L, "tcp{client}", "tcp{any}");
145 auxiliar_add2group(L, "tcp{server}", "tcp{any}");
146 /* define library functions */
147 luaL_setfuncs(L, func, 0);
148 return 0;
149}
150
151/*=========================================================================*\
152* Lua methods
153\*=========================================================================*/
154/*-------------------------------------------------------------------------*\
155* Just call buffered IO methods
156\*-------------------------------------------------------------------------*/
157static int meth_send(lua_State *L) {
158 p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
159 return buffer_meth_send(L, &tcp->buf);
160}
161
162static int meth_receive(lua_State *L) {
163 p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
164 return buffer_meth_receive(L, &tcp->buf);
165}
166
167static int meth_getstats(lua_State *L) {
168 p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
169 return buffer_meth_getstats(L, &tcp->buf);
170}
171
172static int meth_setstats(lua_State *L) {
173 p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
174 return buffer_meth_setstats(L, &tcp->buf);
175}
176
177/*-------------------------------------------------------------------------*\
178* Just call option handler
179\*-------------------------------------------------------------------------*/
180static int meth_getoption(lua_State *L)
181{
182 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
183 return opt_meth_getoption(L, optget, &tcp->sock);
184}
185
186static int meth_setoption(lua_State *L)
187{
188 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
189 return opt_meth_setoption(L, optset, &tcp->sock);
190}
191
192/*-------------------------------------------------------------------------*\
193* Select support methods
194\*-------------------------------------------------------------------------*/
195static int meth_getfd(lua_State *L)
196{
197 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
198 lua_pushnumber(L, (int) tcp->sock);
199 return 1;
200}
201
202/* this is very dangerous, but can be handy for those that are brave enough */
203static int meth_setfd(lua_State *L)
204{
205 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
206 tcp->sock = (t_socket) luaL_checknumber(L, 2);
207 return 0;
208}
209
210static int meth_dirty(lua_State *L)
211{
212 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
213 lua_pushboolean(L, !buffer_isempty(&tcp->buf));
214 return 1;
215}
216
217/*-------------------------------------------------------------------------*\
218* Waits for and returns a client object attempting connection to the
219* server object
220\*-------------------------------------------------------------------------*/
221static int meth_accept(lua_State *L)
222{
223 p_tcp server = (p_tcp) auxiliar_checkclass(L, "tcp{server}", 1);
224 p_timeout tm = timeout_markstart(&server->tm);
225 t_socket sock;
226 const char *err = inet_tryaccept(&server->sock, server->family, &sock, tm);
227 /* if successful, push client socket */
228 if (err == NULL) {
229 p_tcp clnt = (p_tcp) lua_newuserdata(L, sizeof(t_tcp));
230 auxiliar_setclass(L, "tcp{client}", -1);
231 /* initialize structure fields */
232 memset(clnt, 0, sizeof(t_tcp));
233 socket_setnonblocking(&sock);
234 clnt->sock = sock;
235 io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv,
236 (p_error) socket_ioerror, &clnt->sock);
237 timeout_init(&clnt->tm, -1, -1);
238 buffer_init(&clnt->buf, &clnt->io, &clnt->tm);
239 clnt->family = server->family;
240 return 1;
241 } else {
242 lua_pushnil(L);
243 lua_pushstring(L, err);
244 return 2;
245 }
246}
247
248/*-------------------------------------------------------------------------*\
249* Binds an object to an address
250\*-------------------------------------------------------------------------*/
251static int meth_bind(lua_State *L) {
252 p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1);
253 const char *address = luaL_checkstring(L, 2);
254 const char *port = luaL_checkstring(L, 3);
255 const char *err;
256 struct addrinfo bindhints;
257 memset(&bindhints, 0, sizeof(bindhints));
258 bindhints.ai_socktype = SOCK_STREAM;
259 bindhints.ai_family = tcp->family;
260 bindhints.ai_flags = AI_PASSIVE;
261 err = inet_trybind(&tcp->sock, &tcp->family, address, port, &bindhints);
262 if (err) {
263 lua_pushnil(L);
264 lua_pushstring(L, err);
265 return 2;
266 }
267 lua_pushnumber(L, 1);
268 return 1;
269}
270
271/*-------------------------------------------------------------------------*\
272* Turns a master tcp object into a client object.
273\*-------------------------------------------------------------------------*/
274static int meth_connect(lua_State *L) {
275 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
276 const char *address = luaL_checkstring(L, 2);
277 const char *port = luaL_checkstring(L, 3);
278 struct addrinfo connecthints;
279 const char *err;
280 memset(&connecthints, 0, sizeof(connecthints));
281 connecthints.ai_socktype = SOCK_STREAM;
282 /* make sure we try to connect only to the same family */
283 connecthints.ai_family = tcp->family;
284 timeout_markstart(&tcp->tm);
285 err = inet_tryconnect(&tcp->sock, &tcp->family, address, port,
286 &tcp->tm, &connecthints);
287 /* have to set the class even if it failed due to non-blocking connects */
288 auxiliar_setclass(L, "tcp{client}", 1);
289 if (err) {
290 lua_pushnil(L);
291 lua_pushstring(L, err);
292 return 2;
293 }
294 lua_pushnumber(L, 1);
295 return 1;
296}
297
298/*-------------------------------------------------------------------------*\
299* Closes socket used by object
300\*-------------------------------------------------------------------------*/
301static int meth_close(lua_State *L)
302{
303 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
304 socket_destroy(&tcp->sock);
305 lua_pushnumber(L, 1);
306 return 1;
307}
308
309/*-------------------------------------------------------------------------*\
310* Returns family as string
311\*-------------------------------------------------------------------------*/
312static int meth_getfamily(lua_State *L)
313{
314 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
315 if (tcp->family == AF_INET6) {
316 lua_pushliteral(L, "inet6");
317 return 1;
318 } else if (tcp->family == AF_INET) {
319 lua_pushliteral(L, "inet4");
320 return 1;
321 } else {
322 lua_pushliteral(L, "inet4");
323 return 1;
324 }
325}
326
327/*-------------------------------------------------------------------------*\
328* Puts the sockt in listen mode
329\*-------------------------------------------------------------------------*/
330static int meth_listen(lua_State *L)
331{
332 p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1);
333 int backlog = (int) luaL_optnumber(L, 2, 32);
334 int err = socket_listen(&tcp->sock, backlog);
335 if (err != IO_DONE) {
336 lua_pushnil(L);
337 lua_pushstring(L, socket_strerror(err));
338 return 2;
339 }
340 /* turn master object into a server object */
341 auxiliar_setclass(L, "tcp{server}", 1);
342 lua_pushnumber(L, 1);
343 return 1;
344}
345
346/*-------------------------------------------------------------------------*\
347* Shuts the connection down partially
348\*-------------------------------------------------------------------------*/
349static int meth_shutdown(lua_State *L)
350{
351 /* SHUT_RD, SHUT_WR, SHUT_RDWR have the value 0, 1, 2, so we can use method index directly */
352 static const char* methods[] = { "receive", "send", "both", NULL };
353 p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1);
354 int how = luaL_checkoption(L, 2, "both", methods);
355 socket_shutdown(&tcp->sock, how);
356 lua_pushnumber(L, 1);
357 return 1;
358}
359
360/*-------------------------------------------------------------------------*\
361* Just call inet methods
362\*-------------------------------------------------------------------------*/
363static int meth_getpeername(lua_State *L)
364{
365 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
366 return inet_meth_getpeername(L, &tcp->sock, tcp->family);
367}
368
369static int meth_getsockname(lua_State *L)
370{
371 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
372 return inet_meth_getsockname(L, &tcp->sock, tcp->family);
373}
374
375/*-------------------------------------------------------------------------*\
376* Just call tm methods
377\*-------------------------------------------------------------------------*/
378static int meth_settimeout(lua_State *L)
379{
380 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
381 return timeout_meth_settimeout(L, &tcp->tm);
382}
383
384static int meth_gettimeout(lua_State *L)
385{
386 p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1);
387 return timeout_meth_gettimeout(L, &tcp->tm);
388}
389
390/*=========================================================================*\
391* Library functions
392\*=========================================================================*/
393/*-------------------------------------------------------------------------*\
394* Creates a master tcp object
395\*-------------------------------------------------------------------------*/
396static int tcp_create(lua_State *L, int family) {
397 p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp));
398 memset(tcp, 0, sizeof(t_tcp));
399 /* set its type as master object */
400 auxiliar_setclass(L, "tcp{master}", -1);
401 /* if family is AF_UNSPEC, we leave the socket invalid and
402 * store AF_UNSPEC into family. This will allow it to later be
403 * replaced with an AF_INET6 or AF_INET socket upon first use. */
404 tcp->sock = SOCKET_INVALID;
405 tcp->family = family;
406 io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv,
407 (p_error) socket_ioerror, &tcp->sock);
408 timeout_init(&tcp->tm, -1, -1);
409 buffer_init(&tcp->buf, &tcp->io, &tcp->tm);
410 if (family != AF_UNSPEC) {
411 const char *err = inet_trycreate(&tcp->sock, family, SOCK_STREAM, 0);
412 if (err != NULL) {
413 lua_pushnil(L);
414 lua_pushstring(L, err);
415 return 2;
416 }
417 socket_setnonblocking(&tcp->sock);
418 }
419 return 1;
420}
421
422static int global_create(lua_State *L) {
423 return tcp_create(L, AF_UNSPEC);
424}
425
426static int global_create4(lua_State *L) {
427 return tcp_create(L, AF_INET);
428}
429
430static int global_create6(lua_State *L) {
431 return tcp_create(L, AF_INET6);
432}
433
434static int global_connect(lua_State *L) {
435 const char *remoteaddr = luaL_checkstring(L, 1);
436 const char *remoteserv = luaL_checkstring(L, 2);
437 const char *localaddr = luaL_optstring(L, 3, NULL);
438 const char *localserv = luaL_optstring(L, 4, "0");
439 int family = inet_optfamily(L, 5, "unspec");
440 p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp));
441 struct addrinfo bindhints, connecthints;
442 const char *err = NULL;
443 /* initialize tcp structure */
444 memset(tcp, 0, sizeof(t_tcp));
445 io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv,
446 (p_error) socket_ioerror, &tcp->sock);
447 timeout_init(&tcp->tm, -1, -1);
448 buffer_init(&tcp->buf, &tcp->io, &tcp->tm);
449 tcp->sock = SOCKET_INVALID;
450 tcp->family = AF_UNSPEC;
451 /* allow user to pick local address and port */
452 memset(&bindhints, 0, sizeof(bindhints));
453 bindhints.ai_socktype = SOCK_STREAM;
454 bindhints.ai_family = family;
455 bindhints.ai_flags = AI_PASSIVE;
456 if (localaddr) {
457 err = inet_trybind(&tcp->sock, &tcp->family, localaddr,
458 localserv, &bindhints);
459 if (err) {
460 lua_pushnil(L);
461 lua_pushstring(L, err);
462 return 2;
463 }
464 }
465 /* try to connect to remote address and port */
466 memset(&connecthints, 0, sizeof(connecthints));
467 connecthints.ai_socktype = SOCK_STREAM;
468 /* make sure we try to connect only to the same family */
469 connecthints.ai_family = tcp->family;
470 err = inet_tryconnect(&tcp->sock, &tcp->family, remoteaddr, remoteserv,
471 &tcp->tm, &connecthints);
472 if (err) {
473 socket_destroy(&tcp->sock);
474 lua_pushnil(L);
475 lua_pushstring(L, err);
476 return 2;
477 }
478 auxiliar_setclass(L, "tcp{client}", -1);
479 return 1;
480}
diff --git a/vendor/luasocket/src/tcp.h b/vendor/luasocket/src/tcp.h
new file mode 100644
index 00000000..9b282efe
--- /dev/null
+++ b/vendor/luasocket/src/tcp.h
@@ -0,0 +1,43 @@
1#ifndef TCP_H
2#define TCP_H
3/*=========================================================================*\
4* TCP object
5* LuaSocket toolkit
6*
7* The tcp.h module is basicly a glue that puts together modules buffer.h,
8* timeout.h socket.h and inet.h to provide the LuaSocket TCP (AF_INET,
9* SOCK_STREAM) support.
10*
11* Three classes are defined: master, client and server. The master class is
12* a newly created tcp object, that has not been bound or connected. Server
13* objects are tcp objects bound to some local address. Client objects are
14* tcp objects either connected to some address or returned by the accept
15* method of a server object.
16\*=========================================================================*/
17#include "luasocket.h"
18
19#include "buffer.h"
20#include "timeout.h"
21#include "socket.h"
22
23typedef struct t_tcp_ {
24 t_socket sock;
25 t_io io;
26 t_buffer buf;
27 t_timeout tm;
28 int family;
29} t_tcp;
30
31typedef t_tcp *p_tcp;
32
33#ifndef _WIN32
34#pragma GCC visibility push(hidden)
35#endif
36
37int tcp_open(lua_State *L);
38
39#ifndef _WIN32
40#pragma GCC visibility pop
41#endif
42
43#endif /* TCP_H */
diff --git a/vendor/luasocket/src/timeout.c b/vendor/luasocket/src/timeout.c
new file mode 100644
index 00000000..2bdc0698
--- /dev/null
+++ b/vendor/luasocket/src/timeout.c
@@ -0,0 +1,226 @@
1/*=========================================================================*\
2* Timeout management functions
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6
7#include "auxiliar.h"
8#include "timeout.h"
9
10#include <stdio.h>
11#include <limits.h>
12#include <float.h>
13
14#ifdef _WIN32
15#include <windows.h>
16#else
17#include <time.h>
18#include <sys/time.h>
19#endif
20
21/* min and max macros */
22#ifndef MIN
23#define MIN(x, y) ((x) < (y) ? x : y)
24#endif
25#ifndef MAX
26#define MAX(x, y) ((x) > (y) ? x : y)
27#endif
28
29/*=========================================================================*\
30* Internal function prototypes
31\*=========================================================================*/
32static int timeout_lua_gettime(lua_State *L);
33static int timeout_lua_sleep(lua_State *L);
34
35static luaL_Reg func[] = {
36 { "gettime", timeout_lua_gettime },
37 { "sleep", timeout_lua_sleep },
38 { NULL, NULL }
39};
40
41/*=========================================================================*\
42* Exported functions.
43\*=========================================================================*/
44/*-------------------------------------------------------------------------*\
45* Initialize structure
46\*-------------------------------------------------------------------------*/
47void timeout_init(p_timeout tm, double block, double total) {
48 tm->block = block;
49 tm->total = total;
50}
51
52/*-------------------------------------------------------------------------*\
53* Determines how much time we have left for the next system call,
54* if the previous call was successful
55* Input
56* tm: timeout control structure
57* Returns
58* the number of ms left or -1 if there is no time limit
59\*-------------------------------------------------------------------------*/
60double timeout_get(p_timeout tm) {
61 if (tm->block < 0.0 && tm->total < 0.0) {
62 return -1;
63 } else if (tm->block < 0.0) {
64 double t = tm->total - timeout_gettime() + tm->start;
65 return MAX(t, 0.0);
66 } else if (tm->total < 0.0) {
67 return tm->block;
68 } else {
69 double t = tm->total - timeout_gettime() + tm->start;
70 return MIN(tm->block, MAX(t, 0.0));
71 }
72}
73
74/*-------------------------------------------------------------------------*\
75* Returns time since start of operation
76* Input
77* tm: timeout control structure
78* Returns
79* start field of structure
80\*-------------------------------------------------------------------------*/
81double timeout_getstart(p_timeout tm) {
82 return tm->start;
83}
84
85/*-------------------------------------------------------------------------*\
86* Determines how much time we have left for the next system call,
87* if the previous call was a failure
88* Input
89* tm: timeout control structure
90* Returns
91* the number of ms left or -1 if there is no time limit
92\*-------------------------------------------------------------------------*/
93double timeout_getretry(p_timeout tm) {
94 if (tm->block < 0.0 && tm->total < 0.0) {
95 return -1;
96 } else if (tm->block < 0.0) {
97 double t = tm->total - timeout_gettime() + tm->start;
98 return MAX(t, 0.0);
99 } else if (tm->total < 0.0) {
100 double t = tm->block - timeout_gettime() + tm->start;
101 return MAX(t, 0.0);
102 } else {
103 double t = tm->total - timeout_gettime() + tm->start;
104 return MIN(tm->block, MAX(t, 0.0));
105 }
106}
107
108/*-------------------------------------------------------------------------*\
109* Marks the operation start time in structure
110* Input
111* tm: timeout control structure
112\*-------------------------------------------------------------------------*/
113p_timeout timeout_markstart(p_timeout tm) {
114 tm->start = timeout_gettime();
115 return tm;
116}
117
118/*-------------------------------------------------------------------------*\
119* Gets time in s, relative to January 1, 1970 (UTC)
120* Returns
121* time in s.
122\*-------------------------------------------------------------------------*/
123#ifdef _WIN32
124double timeout_gettime(void) {
125 FILETIME ft;
126 double t;
127 GetSystemTimeAsFileTime(&ft);
128 /* Windows file time (time since January 1, 1601 (UTC)) */
129 t = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7);
130 /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */
131 return (t - 11644473600.0);
132}
133#else
134double timeout_gettime(void) {
135 struct timeval v;
136 gettimeofday(&v, (struct timezone *) NULL);
137 /* Unix Epoch time (time since January 1, 1970 (UTC)) */
138 return v.tv_sec + v.tv_usec/1.0e6;
139}
140#endif
141
142/*-------------------------------------------------------------------------*\
143* Initializes module
144\*-------------------------------------------------------------------------*/
145int timeout_open(lua_State *L) {
146 luaL_setfuncs(L, func, 0);
147 return 0;
148}
149
150/*-------------------------------------------------------------------------*\
151* Sets timeout values for IO operations
152* Lua Input: base, time [, mode]
153* time: time out value in seconds
154* mode: "b" for block timeout, "t" for total timeout. (default: b)
155\*-------------------------------------------------------------------------*/
156int timeout_meth_settimeout(lua_State *L, p_timeout tm) {
157 double t = luaL_optnumber(L, 2, -1);
158 const char *mode = luaL_optstring(L, 3, "b");
159 switch (*mode) {
160 case 'b':
161 tm->block = t;
162 break;
163 case 'r': case 't':
164 tm->total = t;
165 break;
166 default:
167 luaL_argcheck(L, 0, 3, "invalid timeout mode");
168 break;
169 }
170 lua_pushnumber(L, 1);
171 return 1;
172}
173
174/*-------------------------------------------------------------------------*\
175* Gets timeout values for IO operations
176* Lua Output: block, total
177\*-------------------------------------------------------------------------*/
178int timeout_meth_gettimeout(lua_State *L, p_timeout tm) {
179 lua_pushnumber(L, tm->block);
180 lua_pushnumber(L, tm->total);
181 return 2;
182}
183
184/*=========================================================================*\
185* Test support functions
186\*=========================================================================*/
187/*-------------------------------------------------------------------------*\
188* Returns the time the system has been up, in secconds.
189\*-------------------------------------------------------------------------*/
190static int timeout_lua_gettime(lua_State *L)
191{
192 lua_pushnumber(L, timeout_gettime());
193 return 1;
194}
195
196/*-------------------------------------------------------------------------*\
197* Sleep for n seconds.
198\*-------------------------------------------------------------------------*/
199#ifdef _WIN32
200int timeout_lua_sleep(lua_State *L)
201{
202 double n = luaL_checknumber(L, 1);
203 if (n < 0.0) n = 0.0;
204 if (n < DBL_MAX/1000.0) n *= 1000.0;
205 if (n > INT_MAX) n = INT_MAX;
206 Sleep((int)n);
207 return 0;
208}
209#else
210int timeout_lua_sleep(lua_State *L)
211{
212 double n = luaL_checknumber(L, 1);
213 struct timespec t, r;
214 if (n < 0.0) n = 0.0;
215 if (n > INT_MAX) n = INT_MAX;
216 t.tv_sec = (int) n;
217 n -= t.tv_sec;
218 t.tv_nsec = (int) (n * 1000000000);
219 if (t.tv_nsec >= 1000000000) t.tv_nsec = 999999999;
220 while (nanosleep(&t, &r) != 0) {
221 t.tv_sec = r.tv_sec;
222 t.tv_nsec = r.tv_nsec;
223 }
224 return 0;
225}
226#endif
diff --git a/vendor/luasocket/src/timeout.h b/vendor/luasocket/src/timeout.h
new file mode 100644
index 00000000..9e5250d3
--- /dev/null
+++ b/vendor/luasocket/src/timeout.h
@@ -0,0 +1,40 @@
1#ifndef TIMEOUT_H
2#define TIMEOUT_H
3/*=========================================================================*\
4* Timeout management functions
5* LuaSocket toolkit
6\*=========================================================================*/
7#include "luasocket.h"
8
9/* timeout control structure */
10typedef struct t_timeout_ {
11 double block; /* maximum time for blocking calls */
12 double total; /* total number of miliseconds for operation */
13 double start; /* time of start of operation */
14} t_timeout;
15typedef t_timeout *p_timeout;
16
17#ifndef _WIN32
18#pragma GCC visibility push(hidden)
19#endif
20
21void timeout_init(p_timeout tm, double block, double total);
22double timeout_get(p_timeout tm);
23double timeout_getstart(p_timeout tm);
24double timeout_getretry(p_timeout tm);
25p_timeout timeout_markstart(p_timeout tm);
26
27double timeout_gettime(void);
28
29int timeout_open(lua_State *L);
30
31int timeout_meth_settimeout(lua_State *L, p_timeout tm);
32int timeout_meth_gettimeout(lua_State *L, p_timeout tm);
33
34#ifndef _WIN32
35#pragma GCC visibility pop
36#endif
37
38#define timeout_iszero(tm) ((tm)->block == 0.0)
39
40#endif /* TIMEOUT_H */
diff --git a/vendor/luasocket/src/tp.lua b/vendor/luasocket/src/tp.lua
new file mode 100644
index 00000000..b8ebc56d
--- /dev/null
+++ b/vendor/luasocket/src/tp.lua
@@ -0,0 +1,134 @@
1-----------------------------------------------------------------------------
2-- Unified SMTP/FTP subsystem
3-- LuaSocket toolkit.
4-- Author: Diego Nehab
5-----------------------------------------------------------------------------
6
7-----------------------------------------------------------------------------
8-- Declare module and import dependencies
9-----------------------------------------------------------------------------
10local base = _G
11local string = require("string")
12local socket = require("socket")
13local ltn12 = require("ltn12")
14
15socket.tp = {}
16local _M = socket.tp
17
18-----------------------------------------------------------------------------
19-- Program constants
20-----------------------------------------------------------------------------
21_M.TIMEOUT = 60
22
23-----------------------------------------------------------------------------
24-- Implementation
25-----------------------------------------------------------------------------
26-- gets server reply (works for SMTP and FTP)
27local function get_reply(c)
28 local code, current, sep
29 local line, err = c:receive()
30 local reply = line
31 if err then return nil, err end
32 code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
33 if not code then return nil, "invalid server reply" end
34 if sep == "-" then -- reply is multiline
35 repeat
36 line, err = c:receive()
37 if err then return nil, err end
38 current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
39 reply = reply .. "\n" .. line
40 -- reply ends with same code
41 until code == current and sep == " "
42 end
43 return code, reply
44end
45
46-- metatable for sock object
47local metat = { __index = {} }
48
49function metat.__index:getpeername()
50 return self.c:getpeername()
51end
52
53function metat.__index:getsockname()
54 return self.c:getpeername()
55end
56
57function metat.__index:check(ok)
58 local code, reply = get_reply(self.c)
59 if not code then return nil, reply end
60 if base.type(ok) ~= "function" then
61 if base.type(ok) == "table" then
62 for i, v in base.ipairs(ok) do
63 if string.find(code, v) then
64 return base.tonumber(code), reply
65 end
66 end
67 return nil, reply
68 else
69 if string.find(code, ok) then return base.tonumber(code), reply
70 else return nil, reply end
71 end
72 else return ok(base.tonumber(code), reply) end
73end
74
75function metat.__index:command(cmd, arg)
76 cmd = string.upper(cmd)
77 if arg then
78 return self.c:send(cmd .. " " .. arg.. "\r\n")
79 else
80 return self.c:send(cmd .. "\r\n")
81 end
82end
83
84function metat.__index:sink(snk, pat)
85 local chunk, err = self.c:receive(pat)
86 return snk(chunk, err)
87end
88
89function metat.__index:send(data)
90 return self.c:send(data)
91end
92
93function metat.__index:receive(pat)
94 return self.c:receive(pat)
95end
96
97function metat.__index:getfd()
98 return self.c:getfd()
99end
100
101function metat.__index:dirty()
102 return self.c:dirty()
103end
104
105function metat.__index:getcontrol()
106 return self.c
107end
108
109function metat.__index:source(source, step)
110 local sink = socket.sink("keep-open", self.c)
111 local ret, err = ltn12.pump.all(source, sink, step or ltn12.pump.step)
112 return ret, err
113end
114
115-- closes the underlying c
116function metat.__index:close()
117 self.c:close()
118 return 1
119end
120
121-- connect with server and return c object
122function _M.connect(host, port, timeout, create)
123 local c, e = (create or socket.tcp)()
124 if not c then return nil, e end
125 c:settimeout(timeout or _M.TIMEOUT)
126 local r, e = c:connect(host, port)
127 if not r then
128 c:close()
129 return nil, e
130 end
131 return base.setmetatable({c = c}, metat)
132end
133
134return _M
diff --git a/vendor/luasocket/src/udp.c b/vendor/luasocket/src/udp.c
new file mode 100755
index 00000000..712ad50f
--- /dev/null
+++ b/vendor/luasocket/src/udp.c
@@ -0,0 +1,488 @@
1/*=========================================================================*\
2* UDP object
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6
7#include "auxiliar.h"
8#include "socket.h"
9#include "inet.h"
10#include "options.h"
11#include "udp.h"
12
13#include <string.h>
14#include <stdlib.h>
15
16/* min and max macros */
17#ifndef MIN
18#define MIN(x, y) ((x) < (y) ? x : y)
19#endif
20#ifndef MAX
21#define MAX(x, y) ((x) > (y) ? x : y)
22#endif
23
24/*=========================================================================*\
25* Internal function prototypes
26\*=========================================================================*/
27static int global_create(lua_State *L);
28static int global_create4(lua_State *L);
29static int global_create6(lua_State *L);
30static int meth_send(lua_State *L);
31static int meth_sendto(lua_State *L);
32static int meth_receive(lua_State *L);
33static int meth_receivefrom(lua_State *L);
34static int meth_getfamily(lua_State *L);
35static int meth_getsockname(lua_State *L);
36static int meth_getpeername(lua_State *L);
37static int meth_gettimeout(lua_State *L);
38static int meth_setsockname(lua_State *L);
39static int meth_setpeername(lua_State *L);
40static int meth_close(lua_State *L);
41static int meth_setoption(lua_State *L);
42static int meth_getoption(lua_State *L);
43static int meth_settimeout(lua_State *L);
44static int meth_getfd(lua_State *L);
45static int meth_setfd(lua_State *L);
46static int meth_dirty(lua_State *L);
47
48/* udp object methods */
49static luaL_Reg udp_methods[] = {
50 {"__gc", meth_close},
51 {"__tostring", auxiliar_tostring},
52 {"close", meth_close},
53 {"dirty", meth_dirty},
54 {"getfamily", meth_getfamily},
55 {"getfd", meth_getfd},
56 {"getpeername", meth_getpeername},
57 {"getsockname", meth_getsockname},
58 {"receive", meth_receive},
59 {"receivefrom", meth_receivefrom},
60 {"send", meth_send},
61 {"sendto", meth_sendto},
62 {"setfd", meth_setfd},
63 {"setoption", meth_setoption},
64 {"getoption", meth_getoption},
65 {"setpeername", meth_setpeername},
66 {"setsockname", meth_setsockname},
67 {"settimeout", meth_settimeout},
68 {"gettimeout", meth_gettimeout},
69 {NULL, NULL}
70};
71
72/* socket options for setoption */
73static t_opt optset[] = {
74 {"dontroute", opt_set_dontroute},
75 {"broadcast", opt_set_broadcast},
76 {"reuseaddr", opt_set_reuseaddr},
77 {"reuseport", opt_set_reuseport},
78 {"ip-multicast-if", opt_set_ip_multicast_if},
79 {"ip-multicast-ttl", opt_set_ip_multicast_ttl},
80 {"ip-multicast-loop", opt_set_ip_multicast_loop},
81 {"ip-add-membership", opt_set_ip_add_membership},
82 {"ip-drop-membership", opt_set_ip_drop_membersip},
83 {"ipv6-unicast-hops", opt_set_ip6_unicast_hops},
84 {"ipv6-multicast-hops", opt_set_ip6_unicast_hops},
85 {"ipv6-multicast-loop", opt_set_ip6_multicast_loop},
86 {"ipv6-add-membership", opt_set_ip6_add_membership},
87 {"ipv6-drop-membership", opt_set_ip6_drop_membersip},
88 {"ipv6-v6only", opt_set_ip6_v6only},
89 {"recv-buffer-size", opt_set_recv_buf_size},
90 {"send-buffer-size", opt_set_send_buf_size},
91 {NULL, NULL}
92};
93
94/* socket options for getoption */
95static t_opt optget[] = {
96 {"dontroute", opt_get_dontroute},
97 {"broadcast", opt_get_broadcast},
98 {"reuseaddr", opt_get_reuseaddr},
99 {"reuseport", opt_get_reuseport},
100 {"ip-multicast-if", opt_get_ip_multicast_if},
101 {"ip-multicast-loop", opt_get_ip_multicast_loop},
102 {"error", opt_get_error},
103 {"ipv6-unicast-hops", opt_get_ip6_unicast_hops},
104 {"ipv6-multicast-hops", opt_get_ip6_unicast_hops},
105 {"ipv6-multicast-loop", opt_get_ip6_multicast_loop},
106 {"ipv6-v6only", opt_get_ip6_v6only},
107 {"recv-buffer-size", opt_get_recv_buf_size},
108 {"send-buffer-size", opt_get_send_buf_size},
109 {NULL, NULL}
110};
111
112/* functions in library namespace */
113static luaL_Reg func[] = {
114 {"udp", global_create},
115 {"udp4", global_create4},
116 {"udp6", global_create6},
117 {NULL, NULL}
118};
119
120/*-------------------------------------------------------------------------*\
121* Initializes module
122\*-------------------------------------------------------------------------*/
123int udp_open(lua_State *L) {
124 /* create classes */
125 auxiliar_newclass(L, "udp{connected}", udp_methods);
126 auxiliar_newclass(L, "udp{unconnected}", udp_methods);
127 /* create class groups */
128 auxiliar_add2group(L, "udp{connected}", "udp{any}");
129 auxiliar_add2group(L, "udp{unconnected}", "udp{any}");
130 auxiliar_add2group(L, "udp{connected}", "select{able}");
131 auxiliar_add2group(L, "udp{unconnected}", "select{able}");
132 /* define library functions */
133 luaL_setfuncs(L, func, 0);
134 /* export default UDP size */
135 lua_pushliteral(L, "_DATAGRAMSIZE");
136 lua_pushinteger(L, UDP_DATAGRAMSIZE);
137 lua_rawset(L, -3);
138 return 0;
139}
140
141/*=========================================================================*\
142* Lua methods
143\*=========================================================================*/
144static const char *udp_strerror(int err) {
145 /* a 'closed' error on an unconnected means the target address was not
146 * accepted by the transport layer */
147 if (err == IO_CLOSED) return "refused";
148 else return socket_strerror(err);
149}
150
151/*-------------------------------------------------------------------------*\
152* Send data through connected udp socket
153\*-------------------------------------------------------------------------*/
154static int meth_send(lua_State *L) {
155 p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{connected}", 1);
156 p_timeout tm = &udp->tm;
157 size_t count, sent = 0;
158 int err;
159 const char *data = luaL_checklstring(L, 2, &count);
160 timeout_markstart(tm);
161 err = socket_send(&udp->sock, data, count, &sent, tm);
162 if (err != IO_DONE) {
163 lua_pushnil(L);
164 lua_pushstring(L, udp_strerror(err));
165 return 2;
166 }
167 lua_pushnumber(L, (lua_Number) sent);
168 return 1;
169}
170
171/*-------------------------------------------------------------------------*\
172* Send data through unconnected udp socket
173\*-------------------------------------------------------------------------*/
174static int meth_sendto(lua_State *L) {
175 p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1);
176 size_t count, sent = 0;
177 const char *data = luaL_checklstring(L, 2, &count);
178 const char *ip = luaL_checkstring(L, 3);
179 const char *port = luaL_checkstring(L, 4);
180 p_timeout tm = &udp->tm;
181 int err;
182 struct addrinfo aihint;
183 struct addrinfo *ai;
184 memset(&aihint, 0, sizeof(aihint));
185 aihint.ai_family = udp->family;
186 aihint.ai_socktype = SOCK_DGRAM;
187 aihint.ai_flags = AI_NUMERICHOST;
188#ifdef AI_NUMERICSERV
189 aihint.ai_flags |= AI_NUMERICSERV;
190#endif
191 err = getaddrinfo(ip, port, &aihint, &ai);
192 if (err) {
193 lua_pushnil(L);
194 lua_pushstring(L, LUA_GAI_STRERROR(err));
195 return 2;
196 }
197
198 /* create socket if on first sendto if AF_UNSPEC was set */
199 if (udp->family == AF_UNSPEC && udp->sock == SOCKET_INVALID) {
200 struct addrinfo *ap;
201 const char *errstr = NULL;
202 for (ap = ai; ap != NULL; ap = ap->ai_next) {
203 errstr = inet_trycreate(&udp->sock, ap->ai_family, SOCK_DGRAM, 0);
204 if (errstr == NULL) {
205 socket_setnonblocking(&udp->sock);
206 udp->family = ap->ai_family;
207 break;
208 }
209 }
210 if (errstr != NULL) {
211 lua_pushnil(L);
212 lua_pushstring(L, errstr);
213 freeaddrinfo(ai);
214 return 2;
215 }
216 }
217
218 timeout_markstart(tm);
219 err = socket_sendto(&udp->sock, data, count, &sent, ai->ai_addr,
220 (socklen_t) ai->ai_addrlen, tm);
221 freeaddrinfo(ai);
222 if (err != IO_DONE) {
223 lua_pushnil(L);
224 lua_pushstring(L, udp_strerror(err));
225 return 2;
226 }
227 lua_pushnumber(L, (lua_Number) sent);
228 return 1;
229}
230
231/*-------------------------------------------------------------------------*\
232* Receives data from a UDP socket
233\*-------------------------------------------------------------------------*/
234static int meth_receive(lua_State *L) {
235 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
236 char buf[UDP_DATAGRAMSIZE];
237 size_t got, wanted = (size_t) luaL_optnumber(L, 2, sizeof(buf));
238 char *dgram = wanted > sizeof(buf)? (char *) malloc(wanted): buf;
239 int err;
240 p_timeout tm = &udp->tm;
241 timeout_markstart(tm);
242 if (!dgram) {
243 lua_pushnil(L);
244 lua_pushliteral(L, "out of memory");
245 return 2;
246 }
247 err = socket_recv(&udp->sock, dgram, wanted, &got, tm);
248 /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */
249 if (err != IO_DONE && err != IO_CLOSED) {
250 lua_pushnil(L);
251 lua_pushstring(L, udp_strerror(err));
252 if (wanted > sizeof(buf)) free(dgram);
253 return 2;
254 }
255 lua_pushlstring(L, dgram, got);
256 if (wanted > sizeof(buf)) free(dgram);
257 return 1;
258}
259
260/*-------------------------------------------------------------------------*\
261* Receives data and sender from a UDP socket
262\*-------------------------------------------------------------------------*/
263static int meth_receivefrom(lua_State *L) {
264 p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1);
265 char buf[UDP_DATAGRAMSIZE];
266 size_t got, wanted = (size_t) luaL_optnumber(L, 2, sizeof(buf));
267 char *dgram = wanted > sizeof(buf)? (char *) malloc(wanted): buf;
268 struct sockaddr_storage addr;
269 socklen_t addr_len = sizeof(addr);
270 char addrstr[INET6_ADDRSTRLEN];
271 char portstr[6];
272 int err;
273 p_timeout tm = &udp->tm;
274 timeout_markstart(tm);
275 if (!dgram) {
276 lua_pushnil(L);
277 lua_pushliteral(L, "out of memory");
278 return 2;
279 }
280 err = socket_recvfrom(&udp->sock, dgram, wanted, &got, (SA *) &addr,
281 &addr_len, tm);
282 /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */
283 if (err != IO_DONE && err != IO_CLOSED) {
284 lua_pushnil(L);
285 lua_pushstring(L, udp_strerror(err));
286 if (wanted > sizeof(buf)) free(dgram);
287 return 2;
288 }
289 err = getnameinfo((struct sockaddr *)&addr, addr_len, addrstr,
290 INET6_ADDRSTRLEN, portstr, 6, NI_NUMERICHOST | NI_NUMERICSERV);
291 if (err) {
292 lua_pushnil(L);
293 lua_pushstring(L, LUA_GAI_STRERROR(err));
294 if (wanted > sizeof(buf)) free(dgram);
295 return 2;
296 }
297 lua_pushlstring(L, dgram, got);
298 lua_pushstring(L, addrstr);
299 lua_pushinteger(L, (int) strtol(portstr, (char **) NULL, 10));
300 if (wanted > sizeof(buf)) free(dgram);
301 return 3;
302}
303
304/*-------------------------------------------------------------------------*\
305* Returns family as string
306\*-------------------------------------------------------------------------*/
307static int meth_getfamily(lua_State *L) {
308 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
309 if (udp->family == AF_INET6) {
310 lua_pushliteral(L, "inet6");
311 return 1;
312 } else {
313 lua_pushliteral(L, "inet4");
314 return 1;
315 }
316}
317
318/*-------------------------------------------------------------------------*\
319* Select support methods
320\*-------------------------------------------------------------------------*/
321static int meth_getfd(lua_State *L) {
322 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
323 lua_pushnumber(L, (int) udp->sock);
324 return 1;
325}
326
327/* this is very dangerous, but can be handy for those that are brave enough */
328static int meth_setfd(lua_State *L) {
329 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
330 udp->sock = (t_socket) luaL_checknumber(L, 2);
331 return 0;
332}
333
334static int meth_dirty(lua_State *L) {
335 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
336 (void) udp;
337 lua_pushboolean(L, 0);
338 return 1;
339}
340
341/*-------------------------------------------------------------------------*\
342* Just call inet methods
343\*-------------------------------------------------------------------------*/
344static int meth_getpeername(lua_State *L) {
345 p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{connected}", 1);
346 return inet_meth_getpeername(L, &udp->sock, udp->family);
347}
348
349static int meth_getsockname(lua_State *L) {
350 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
351 return inet_meth_getsockname(L, &udp->sock, udp->family);
352}
353
354/*-------------------------------------------------------------------------*\
355* Just call option handler
356\*-------------------------------------------------------------------------*/
357static int meth_setoption(lua_State *L) {
358 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
359 return opt_meth_setoption(L, optset, &udp->sock);
360}
361
362/*-------------------------------------------------------------------------*\
363* Just call option handler
364\*-------------------------------------------------------------------------*/
365static int meth_getoption(lua_State *L) {
366 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
367 return opt_meth_getoption(L, optget, &udp->sock);
368}
369
370/*-------------------------------------------------------------------------*\
371* Just call tm methods
372\*-------------------------------------------------------------------------*/
373static int meth_settimeout(lua_State *L) {
374 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
375 return timeout_meth_settimeout(L, &udp->tm);
376}
377
378static int meth_gettimeout(lua_State *L) {
379 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
380 return timeout_meth_gettimeout(L, &udp->tm);
381}
382
383/*-------------------------------------------------------------------------*\
384* Turns a master udp object into a client object.
385\*-------------------------------------------------------------------------*/
386static int meth_setpeername(lua_State *L) {
387 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
388 p_timeout tm = &udp->tm;
389 const char *address = luaL_checkstring(L, 2);
390 int connecting = strcmp(address, "*");
391 const char *port = connecting? luaL_checkstring(L, 3): "0";
392 struct addrinfo connecthints;
393 const char *err;
394 memset(&connecthints, 0, sizeof(connecthints));
395 connecthints.ai_socktype = SOCK_DGRAM;
396 /* make sure we try to connect only to the same family */
397 connecthints.ai_family = udp->family;
398 if (connecting) {
399 err = inet_tryconnect(&udp->sock, &udp->family, address,
400 port, tm, &connecthints);
401 if (err) {
402 lua_pushnil(L);
403 lua_pushstring(L, err);
404 return 2;
405 }
406 auxiliar_setclass(L, "udp{connected}", 1);
407 } else {
408 /* we ignore possible errors because Mac OS X always
409 * returns EAFNOSUPPORT */
410 inet_trydisconnect(&udp->sock, udp->family, tm);
411 auxiliar_setclass(L, "udp{unconnected}", 1);
412 }
413 lua_pushnumber(L, 1);
414 return 1;
415}
416
417/*-------------------------------------------------------------------------*\
418* Closes socket used by object
419\*-------------------------------------------------------------------------*/
420static int meth_close(lua_State *L) {
421 p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
422 socket_destroy(&udp->sock);
423 lua_pushnumber(L, 1);
424 return 1;
425}
426
427/*-------------------------------------------------------------------------*\
428* Turns a master object into a server object
429\*-------------------------------------------------------------------------*/
430static int meth_setsockname(lua_State *L) {
431 p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1);
432 const char *address = luaL_checkstring(L, 2);
433 const char *port = luaL_checkstring(L, 3);
434 const char *err;
435 struct addrinfo bindhints;
436 memset(&bindhints, 0, sizeof(bindhints));
437 bindhints.ai_socktype = SOCK_DGRAM;
438 bindhints.ai_family = udp->family;
439 bindhints.ai_flags = AI_PASSIVE;
440 err = inet_trybind(&udp->sock, &udp->family, address, port, &bindhints);
441 if (err) {
442 lua_pushnil(L);
443 lua_pushstring(L, err);
444 return 2;
445 }
446 lua_pushnumber(L, 1);
447 return 1;
448}
449
450/*=========================================================================*\
451* Library functions
452\*=========================================================================*/
453/*-------------------------------------------------------------------------*\
454* Creates a master udp object
455\*-------------------------------------------------------------------------*/
456static int udp_create(lua_State *L, int family) {
457 /* allocate udp object */
458 p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp));
459 auxiliar_setclass(L, "udp{unconnected}", -1);
460 /* if family is AF_UNSPEC, we leave the socket invalid and
461 * store AF_UNSPEC into family. This will allow it to later be
462 * replaced with an AF_INET6 or AF_INET socket upon first use. */
463 udp->sock = SOCKET_INVALID;
464 timeout_init(&udp->tm, -1, -1);
465 udp->family = family;
466 if (family != AF_UNSPEC) {
467 const char *err = inet_trycreate(&udp->sock, family, SOCK_DGRAM, 0);
468 if (err != NULL) {
469 lua_pushnil(L);
470 lua_pushstring(L, err);
471 return 2;
472 }
473 socket_setnonblocking(&udp->sock);
474 }
475 return 1;
476}
477
478static int global_create(lua_State *L) {
479 return udp_create(L, AF_UNSPEC);
480}
481
482static int global_create4(lua_State *L) {
483 return udp_create(L, AF_INET);
484}
485
486static int global_create6(lua_State *L) {
487 return udp_create(L, AF_INET6);
488}
diff --git a/vendor/luasocket/src/udp.h b/vendor/luasocket/src/udp.h
new file mode 100644
index 00000000..07d5247f
--- /dev/null
+++ b/vendor/luasocket/src/udp.h
@@ -0,0 +1,39 @@
1#ifndef UDP_H
2#define UDP_H
3/*=========================================================================*\
4* UDP object
5* LuaSocket toolkit
6*
7* The udp.h module provides LuaSocket with support for UDP protocol
8* (AF_INET, SOCK_DGRAM).
9*
10* Two classes are defined: connected and unconnected. UDP objects are
11* originally unconnected. They can be "connected" to a given address
12* with a call to the setpeername function. The same function can be used to
13* break the connection.
14\*=========================================================================*/
15#include "luasocket.h"
16
17#include "timeout.h"
18#include "socket.h"
19
20#define UDP_DATAGRAMSIZE 8192
21
22typedef struct t_udp_ {
23 t_socket sock;
24 t_timeout tm;
25 int family;
26} t_udp;
27typedef t_udp *p_udp;
28
29#ifndef _WIN32
30#pragma GCC visibility push(hidden)
31#endif
32
33int udp_open(lua_State *L);
34
35#ifndef _WIN32
36#pragma GCC visibility pop
37#endif
38
39#endif /* UDP_H */
diff --git a/vendor/luasocket/src/unix.c b/vendor/luasocket/src/unix.c
new file mode 100644
index 00000000..268d8b21
--- /dev/null
+++ b/vendor/luasocket/src/unix.c
@@ -0,0 +1,69 @@
1/*=========================================================================*\
2* Unix domain socket
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6
7#include "unixstream.h"
8#include "unixdgram.h"
9
10/*-------------------------------------------------------------------------*\
11* Modules and functions
12\*-------------------------------------------------------------------------*/
13static const luaL_Reg mod[] = {
14 {"stream", unixstream_open},
15 {"dgram", unixdgram_open},
16 {NULL, NULL}
17};
18
19static void add_alias(lua_State *L, int index, const char *name, const char *target)
20{
21 lua_getfield(L, index, target);
22 lua_setfield(L, index, name);
23}
24
25static int compat_socket_unix_call(lua_State *L)
26{
27 /* Look up socket.unix.stream in the socket.unix table (which is the first
28 * argument). */
29 lua_getfield(L, 1, "stream");
30
31 /* Replace the stack entry for the socket.unix table with the
32 * socket.unix.stream function. */
33 lua_replace(L, 1);
34
35 /* Call socket.unix.stream, passing along any arguments. */
36 int n = lua_gettop(L);
37 lua_call(L, n-1, LUA_MULTRET);
38
39 /* Pass along the return values from socket.unix.stream. */
40 n = lua_gettop(L);
41 return n;
42}
43
44/*-------------------------------------------------------------------------*\
45* Initializes module
46\*-------------------------------------------------------------------------*/
47LUASOCKET_API int luaopen_socket_unix(lua_State *L)
48{
49 int i;
50 lua_newtable(L);
51 int socket_unix_table = lua_gettop(L);
52
53 for (i = 0; mod[i].name; i++)
54 mod[i].func(L);
55
56 /* Add backwards compatibility aliases "tcp" and "udp" for the "stream" and
57 * "dgram" functions. */
58 add_alias(L, socket_unix_table, "tcp", "stream");
59 add_alias(L, socket_unix_table, "udp", "dgram");
60
61 /* Add a backwards compatibility function and a metatable setup to call it
62 * for the old socket.unix() interface. */
63 lua_pushcfunction(L, compat_socket_unix_call);
64 lua_setfield(L, socket_unix_table, "__call");
65 lua_pushvalue(L, socket_unix_table);
66 lua_setmetatable(L, socket_unix_table);
67
68 return 1;
69}
diff --git a/vendor/luasocket/src/unix.h b/vendor/luasocket/src/unix.h
new file mode 100644
index 00000000..c2035618
--- /dev/null
+++ b/vendor/luasocket/src/unix.h
@@ -0,0 +1,26 @@
1#ifndef UNIX_H
2#define UNIX_H
3/*=========================================================================*\
4* Unix domain object
5* LuaSocket toolkit
6*
7* This module is just an example of how to extend LuaSocket with a new
8* domain.
9\*=========================================================================*/
10#include "luasocket.h"
11
12#include "buffer.h"
13#include "timeout.h"
14#include "socket.h"
15
16typedef struct t_unix_ {
17 t_socket sock;
18 t_io io;
19 t_buffer buf;
20 t_timeout tm;
21} t_unix;
22typedef t_unix *p_unix;
23
24LUASOCKET_API int luaopen_socket_unix(lua_State *L);
25
26#endif /* UNIX_H */
diff --git a/vendor/luasocket/src/unixdgram.c b/vendor/luasocket/src/unixdgram.c
new file mode 100644
index 00000000..69093d73
--- /dev/null
+++ b/vendor/luasocket/src/unixdgram.c
@@ -0,0 +1,405 @@
1/*=========================================================================*\
2* Unix domain socket dgram submodule
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6
7#include "auxiliar.h"
8#include "socket.h"
9#include "options.h"
10#include "unix.h"
11
12#include <string.h>
13#include <stdlib.h>
14
15#include <sys/un.h>
16
17#define UNIXDGRAM_DATAGRAMSIZE 8192
18
19/* provide a SUN_LEN macro if sys/un.h doesn't (e.g. Android) */
20#ifndef SUN_LEN
21#define SUN_LEN(ptr) \
22 ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
23 + strlen ((ptr)->sun_path))
24#endif
25
26/*=========================================================================*\
27* Internal function prototypes
28\*=========================================================================*/
29static int global_create(lua_State *L);
30static int meth_connect(lua_State *L);
31static int meth_bind(lua_State *L);
32static int meth_send(lua_State *L);
33static int meth_receive(lua_State *L);
34static int meth_close(lua_State *L);
35static int meth_setoption(lua_State *L);
36static int meth_settimeout(lua_State *L);
37static int meth_gettimeout(lua_State *L);
38static int meth_getfd(lua_State *L);
39static int meth_setfd(lua_State *L);
40static int meth_dirty(lua_State *L);
41static int meth_receivefrom(lua_State *L);
42static int meth_sendto(lua_State *L);
43static int meth_getsockname(lua_State *L);
44
45static const char *unixdgram_tryconnect(p_unix un, const char *path);
46static const char *unixdgram_trybind(p_unix un, const char *path);
47
48/* unixdgram object methods */
49static luaL_Reg unixdgram_methods[] = {
50 {"__gc", meth_close},
51 {"__tostring", auxiliar_tostring},
52 {"bind", meth_bind},
53 {"close", meth_close},
54 {"connect", meth_connect},
55 {"dirty", meth_dirty},
56 {"getfd", meth_getfd},
57 {"send", meth_send},
58 {"sendto", meth_sendto},
59 {"receive", meth_receive},
60 {"receivefrom", meth_receivefrom},
61 {"setfd", meth_setfd},
62 {"setoption", meth_setoption},
63 {"setpeername", meth_connect},
64 {"setsockname", meth_bind},
65 {"getsockname", meth_getsockname},
66 {"settimeout", meth_settimeout},
67 {"gettimeout", meth_gettimeout},
68 {NULL, NULL}
69};
70
71/* socket option handlers */
72static t_opt optset[] = {
73 {"reuseaddr", opt_set_reuseaddr},
74 {NULL, NULL}
75};
76
77/* functions in library namespace */
78static luaL_Reg func[] = {
79 {"dgram", global_create},
80 {NULL, NULL}
81};
82
83/*-------------------------------------------------------------------------*\
84* Initializes module
85\*-------------------------------------------------------------------------*/
86int unixdgram_open(lua_State *L)
87{
88 /* create classes */
89 auxiliar_newclass(L, "unixdgram{connected}", unixdgram_methods);
90 auxiliar_newclass(L, "unixdgram{unconnected}", unixdgram_methods);
91 /* create class groups */
92 auxiliar_add2group(L, "unixdgram{connected}", "unixdgram{any}");
93 auxiliar_add2group(L, "unixdgram{unconnected}", "unixdgram{any}");
94 auxiliar_add2group(L, "unixdgram{connected}", "select{able}");
95 auxiliar_add2group(L, "unixdgram{unconnected}", "select{able}");
96
97 luaL_setfuncs(L, func, 0);
98 return 0;
99}
100
101/*=========================================================================*\
102* Lua methods
103\*=========================================================================*/
104static const char *unixdgram_strerror(int err)
105{
106 /* a 'closed' error on an unconnected means the target address was not
107 * accepted by the transport layer */
108 if (err == IO_CLOSED) return "refused";
109 else return socket_strerror(err);
110}
111
112static int meth_send(lua_State *L)
113{
114 p_unix un = (p_unix) auxiliar_checkclass(L, "unixdgram{connected}", 1);
115 p_timeout tm = &un->tm;
116 size_t count, sent = 0;
117 int err;
118 const char *data = luaL_checklstring(L, 2, &count);
119 timeout_markstart(tm);
120 err = socket_send(&un->sock, data, count, &sent, tm);
121 if (err != IO_DONE) {
122 lua_pushnil(L);
123 lua_pushstring(L, unixdgram_strerror(err));
124 return 2;
125 }
126 lua_pushnumber(L, (lua_Number) sent);
127 return 1;
128}
129
130/*-------------------------------------------------------------------------*\
131* Send data through unconnected unixdgram socket
132\*-------------------------------------------------------------------------*/
133static int meth_sendto(lua_State *L)
134{
135 p_unix un = (p_unix) auxiliar_checkclass(L, "unixdgram{unconnected}", 1);
136 size_t count, sent = 0;
137 const char *data = luaL_checklstring(L, 2, &count);
138 const char *path = luaL_checkstring(L, 3);
139 p_timeout tm = &un->tm;
140 int err;
141 struct sockaddr_un remote;
142 size_t len = strlen(path);
143
144 if (len >= sizeof(remote.sun_path)) {
145 lua_pushnil(L);
146 lua_pushstring(L, "path too long");
147 return 2;
148 }
149
150 memset(&remote, 0, sizeof(remote));
151 strcpy(remote.sun_path, path);
152 remote.sun_family = AF_UNIX;
153 timeout_markstart(tm);
154#ifdef UNIX_HAS_SUN_LEN
155 remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len)
156 + len + 1;
157 err = socket_sendto(&un->sock, data, count, &sent, (SA *) &remote, remote.sun_len, tm);
158#else
159 err = socket_sendto(&un->sock, data, count, &sent, (SA *) &remote,
160 sizeof(remote.sun_family) + len, tm);
161#endif
162 if (err != IO_DONE) {
163 lua_pushnil(L);
164 lua_pushstring(L, unixdgram_strerror(err));
165 return 2;
166 }
167 lua_pushnumber(L, (lua_Number) sent);
168 return 1;
169}
170
171static int meth_receive(lua_State *L) {
172 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixdgram{any}", 1);
173 char buf[UNIXDGRAM_DATAGRAMSIZE];
174 size_t got, wanted = (size_t) luaL_optnumber(L, 2, sizeof(buf));
175 char *dgram = wanted > sizeof(buf)? (char *) malloc(wanted): buf;
176 int err;
177 p_timeout tm = &un->tm;
178 timeout_markstart(tm);
179 if (!dgram) {
180 lua_pushnil(L);
181 lua_pushliteral(L, "out of memory");
182 return 2;
183 }
184 err = socket_recv(&un->sock, dgram, wanted, &got, tm);
185 /* Unlike STREAM, recv() of zero is not closed, but a zero-length packet. */
186 if (err != IO_DONE && err != IO_CLOSED) {
187 lua_pushnil(L);
188 lua_pushstring(L, unixdgram_strerror(err));
189 if (wanted > sizeof(buf)) free(dgram);
190 return 2;
191 }
192 lua_pushlstring(L, dgram, got);
193 if (wanted > sizeof(buf)) free(dgram);
194 return 1;
195}
196
197/*-------------------------------------------------------------------------*\
198* Receives data and sender from a DGRAM socket
199\*-------------------------------------------------------------------------*/
200static int meth_receivefrom(lua_State *L) {
201 p_unix un = (p_unix) auxiliar_checkclass(L, "unixdgram{unconnected}", 1);
202 char buf[UNIXDGRAM_DATAGRAMSIZE];
203 size_t got, wanted = (size_t) luaL_optnumber(L, 2, sizeof(buf));
204 char *dgram = wanted > sizeof(buf)? (char *) malloc(wanted): buf;
205 struct sockaddr_un addr;
206 socklen_t addr_len = sizeof(addr);
207 int err;
208 p_timeout tm = &un->tm;
209 timeout_markstart(tm);
210 if (!dgram) {
211 lua_pushnil(L);
212 lua_pushliteral(L, "out of memory");
213 return 2;
214 }
215 addr.sun_path[0] = '\0';
216 err = socket_recvfrom(&un->sock, dgram, wanted, &got, (SA *) &addr,
217 &addr_len, tm);
218 /* Unlike STREAM, recv() of zero is not closed, but a zero-length packet. */
219 if (err != IO_DONE && err != IO_CLOSED) {
220 lua_pushnil(L);
221 lua_pushstring(L, unixdgram_strerror(err));
222 if (wanted > sizeof(buf)) free(dgram);
223 return 2;
224 }
225
226 lua_pushlstring(L, dgram, got);
227 /* the path may be empty, when client send without bind */
228 lua_pushstring(L, addr.sun_path);
229 if (wanted > sizeof(buf)) free(dgram);
230 return 2;
231}
232
233/*-------------------------------------------------------------------------*\
234* Just call option handler
235\*-------------------------------------------------------------------------*/
236static int meth_setoption(lua_State *L) {
237 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixdgram{any}", 1);
238 return opt_meth_setoption(L, optset, &un->sock);
239}
240
241/*-------------------------------------------------------------------------*\
242* Select support methods
243\*-------------------------------------------------------------------------*/
244static int meth_getfd(lua_State *L) {
245 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixdgram{any}", 1);
246 lua_pushnumber(L, (int) un->sock);
247 return 1;
248}
249
250/* this is very dangerous, but can be handy for those that are brave enough */
251static int meth_setfd(lua_State *L) {
252 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixdgram{any}", 1);
253 un->sock = (t_socket) luaL_checknumber(L, 2);
254 return 0;
255}
256
257static int meth_dirty(lua_State *L) {
258 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixdgram{any}", 1);
259 (void) un;
260 lua_pushboolean(L, 0);
261 return 1;
262}
263
264/*-------------------------------------------------------------------------*\
265* Binds an object to an address
266\*-------------------------------------------------------------------------*/
267static const char *unixdgram_trybind(p_unix un, const char *path) {
268 struct sockaddr_un local;
269 size_t len = strlen(path);
270 if (len >= sizeof(local.sun_path)) return "path too long";
271 memset(&local, 0, sizeof(local));
272 strcpy(local.sun_path, path);
273 local.sun_family = AF_UNIX;
274 size_t addrlen = SUN_LEN(&local);
275#ifdef UNIX_HAS_SUN_LEN
276 local.sun_len = addrlen + 1;
277#endif
278 int err = socket_bind(&un->sock, (SA *) &local, addrlen);
279 if (err != IO_DONE) socket_destroy(&un->sock);
280 return socket_strerror(err);
281}
282
283static int meth_bind(lua_State *L)
284{
285 p_unix un = (p_unix) auxiliar_checkclass(L, "unixdgram{unconnected}", 1);
286 const char *path = luaL_checkstring(L, 2);
287 const char *err = unixdgram_trybind(un, path);
288 if (err) {
289 lua_pushnil(L);
290 lua_pushstring(L, err);
291 return 2;
292 }
293 lua_pushnumber(L, 1);
294 return 1;
295}
296
297static int meth_getsockname(lua_State *L)
298{
299 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixdgram{any}", 1);
300 struct sockaddr_un peer = {0};
301 socklen_t peer_len = sizeof(peer);
302
303 if (getsockname(un->sock, (SA *) &peer, &peer_len) < 0) {
304 lua_pushnil(L);
305 lua_pushstring(L, socket_strerror(errno));
306 return 2;
307 }
308
309 lua_pushstring(L, peer.sun_path);
310 return 1;
311}
312
313/*-------------------------------------------------------------------------*\
314* Turns a master unixdgram object into a client object.
315\*-------------------------------------------------------------------------*/
316static const char *unixdgram_tryconnect(p_unix un, const char *path)
317{
318 struct sockaddr_un remote;
319 size_t len = strlen(path);
320 if (len >= sizeof(remote.sun_path)) return "path too long";
321 memset(&remote, 0, sizeof(remote));
322 strcpy(remote.sun_path, path);
323 remote.sun_family = AF_UNIX;
324 timeout_markstart(&un->tm);
325 size_t addrlen = SUN_LEN(&remote);
326#ifdef UNIX_HAS_SUN_LEN
327 remote.sun_len = addrlen + 1;
328#endif
329 int err = socket_connect(&un->sock, (SA *) &remote, addrlen, &un->tm);
330 if (err != IO_DONE) socket_destroy(&un->sock);
331 return socket_strerror(err);
332}
333
334static int meth_connect(lua_State *L)
335{
336 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixdgram{any}", 1);
337 const char *path = luaL_checkstring(L, 2);
338 const char *err = unixdgram_tryconnect(un, path);
339 if (err) {
340 lua_pushnil(L);
341 lua_pushstring(L, err);
342 return 2;
343 }
344 /* turn unconnected object into a connected object */
345 auxiliar_setclass(L, "unixdgram{connected}", 1);
346 lua_pushnumber(L, 1);
347 return 1;
348}
349
350/*-------------------------------------------------------------------------*\
351* Closes socket used by object
352\*-------------------------------------------------------------------------*/
353static int meth_close(lua_State *L)
354{
355 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixdgram{any}", 1);
356 socket_destroy(&un->sock);
357 lua_pushnumber(L, 1);
358 return 1;
359}
360
361/*-------------------------------------------------------------------------*\
362* Just call tm methods
363\*-------------------------------------------------------------------------*/
364static int meth_settimeout(lua_State *L)
365{
366 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixdgram{any}", 1);
367 return timeout_meth_settimeout(L, &un->tm);
368}
369
370static int meth_gettimeout(lua_State *L)
371{
372 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixdgram{any}", 1);
373 return timeout_meth_gettimeout(L, &un->tm);
374}
375
376/*=========================================================================*\
377* Library functions
378\*=========================================================================*/
379/*-------------------------------------------------------------------------*\
380* Creates a master unixdgram object
381\*-------------------------------------------------------------------------*/
382static int global_create(lua_State *L)
383{
384 t_socket sock;
385 int err = socket_create(&sock, AF_UNIX, SOCK_DGRAM, 0);
386 /* try to allocate a system socket */
387 if (err == IO_DONE) {
388 /* allocate unixdgram object */
389 p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix));
390 /* set its type as master object */
391 auxiliar_setclass(L, "unixdgram{unconnected}", -1);
392 /* initialize remaining structure fields */
393 socket_setnonblocking(&sock);
394 un->sock = sock;
395 io_init(&un->io, (p_send) socket_send, (p_recv) socket_recv,
396 (p_error) socket_ioerror, &un->sock);
397 timeout_init(&un->tm, -1, -1);
398 buffer_init(&un->buf, &un->io, &un->tm);
399 return 1;
400 } else {
401 lua_pushnil(L);
402 lua_pushstring(L, socket_strerror(err));
403 return 2;
404 }
405}
diff --git a/vendor/luasocket/src/unixdgram.h b/vendor/luasocket/src/unixdgram.h
new file mode 100644
index 00000000..a1a0166b
--- /dev/null
+++ b/vendor/luasocket/src/unixdgram.h
@@ -0,0 +1,28 @@
1#ifndef UNIXDGRAM_H
2#define UNIXDGRAM_H
3/*=========================================================================*\
4* DGRAM object
5* LuaSocket toolkit
6*
7* The dgram.h module provides LuaSocket with support for DGRAM protocol
8* (AF_INET, SOCK_DGRAM).
9*
10* Two classes are defined: connected and unconnected. DGRAM objects are
11* originally unconnected. They can be "connected" to a given address
12* with a call to the setpeername function. The same function can be used to
13* break the connection.
14\*=========================================================================*/
15
16#include "unix.h"
17
18#ifndef _WIN32
19#pragma GCC visibility push(hidden)
20#endif
21
22int unixdgram_open(lua_State *L);
23
24#ifndef _WIN32
25#pragma GCC visibility pop
26#endif
27
28#endif /* UNIXDGRAM_H */
diff --git a/vendor/luasocket/src/unixstream.c b/vendor/luasocket/src/unixstream.c
new file mode 100644
index 00000000..02aced9c
--- /dev/null
+++ b/vendor/luasocket/src/unixstream.c
@@ -0,0 +1,355 @@
1/*=========================================================================*\
2* Unix domain socket stream sub module
3* LuaSocket toolkit
4\*=========================================================================*/
5#include "luasocket.h"
6
7#include "auxiliar.h"
8#include "socket.h"
9#include "options.h"
10#include "unixstream.h"
11
12#include <string.h>
13#include <sys/un.h>
14
15/*=========================================================================*\
16* Internal function prototypes
17\*=========================================================================*/
18static int global_create(lua_State *L);
19static int meth_connect(lua_State *L);
20static int meth_listen(lua_State *L);
21static int meth_bind(lua_State *L);
22static int meth_send(lua_State *L);
23static int meth_shutdown(lua_State *L);
24static int meth_receive(lua_State *L);
25static int meth_accept(lua_State *L);
26static int meth_close(lua_State *L);
27static int meth_setoption(lua_State *L);
28static int meth_settimeout(lua_State *L);
29static int meth_getfd(lua_State *L);
30static int meth_setfd(lua_State *L);
31static int meth_dirty(lua_State *L);
32static int meth_getstats(lua_State *L);
33static int meth_setstats(lua_State *L);
34static int meth_getsockname(lua_State *L);
35
36static const char *unixstream_tryconnect(p_unix un, const char *path);
37static const char *unixstream_trybind(p_unix un, const char *path);
38
39/* unixstream object methods */
40static luaL_Reg unixstream_methods[] = {
41 {"__gc", meth_close},
42 {"__tostring", auxiliar_tostring},
43 {"accept", meth_accept},
44 {"bind", meth_bind},
45 {"close", meth_close},
46 {"connect", meth_connect},
47 {"dirty", meth_dirty},
48 {"getfd", meth_getfd},
49 {"getstats", meth_getstats},
50 {"setstats", meth_setstats},
51 {"listen", meth_listen},
52 {"receive", meth_receive},
53 {"send", meth_send},
54 {"setfd", meth_setfd},
55 {"setoption", meth_setoption},
56 {"setpeername", meth_connect},
57 {"setsockname", meth_bind},
58 {"getsockname", meth_getsockname},
59 {"settimeout", meth_settimeout},
60 {"shutdown", meth_shutdown},
61 {NULL, NULL}
62};
63
64/* socket option handlers */
65static t_opt optset[] = {
66 {"keepalive", opt_set_keepalive},
67 {"reuseaddr", opt_set_reuseaddr},
68 {"linger", opt_set_linger},
69 {NULL, NULL}
70};
71
72/* functions in library namespace */
73static luaL_Reg func[] = {
74 {"stream", global_create},
75 {NULL, NULL}
76};
77
78/*-------------------------------------------------------------------------*\
79* Initializes module
80\*-------------------------------------------------------------------------*/
81int unixstream_open(lua_State *L)
82{
83 /* create classes */
84 auxiliar_newclass(L, "unixstream{master}", unixstream_methods);
85 auxiliar_newclass(L, "unixstream{client}", unixstream_methods);
86 auxiliar_newclass(L, "unixstream{server}", unixstream_methods);
87
88 /* create class groups */
89 auxiliar_add2group(L, "unixstream{master}", "unixstream{any}");
90 auxiliar_add2group(L, "unixstream{client}", "unixstream{any}");
91 auxiliar_add2group(L, "unixstream{server}", "unixstream{any}");
92
93 luaL_setfuncs(L, func, 0);
94 return 0;
95}
96
97/*=========================================================================*\
98* Lua methods
99\*=========================================================================*/
100/*-------------------------------------------------------------------------*\
101* Just call buffered IO methods
102\*-------------------------------------------------------------------------*/
103static int meth_send(lua_State *L) {
104 p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{client}", 1);
105 return buffer_meth_send(L, &un->buf);
106}
107
108static int meth_receive(lua_State *L) {
109 p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{client}", 1);
110 return buffer_meth_receive(L, &un->buf);
111}
112
113static int meth_getstats(lua_State *L) {
114 p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{client}", 1);
115 return buffer_meth_getstats(L, &un->buf);
116}
117
118static int meth_setstats(lua_State *L) {
119 p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{client}", 1);
120 return buffer_meth_setstats(L, &un->buf);
121}
122
123/*-------------------------------------------------------------------------*\
124* Just call option handler
125\*-------------------------------------------------------------------------*/
126static int meth_setoption(lua_State *L) {
127 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixstream{any}", 1);
128 return opt_meth_setoption(L, optset, &un->sock);
129}
130
131/*-------------------------------------------------------------------------*\
132* Select support methods
133\*-------------------------------------------------------------------------*/
134static int meth_getfd(lua_State *L) {
135 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixstream{any}", 1);
136 lua_pushnumber(L, (int) un->sock);
137 return 1;
138}
139
140/* this is very dangerous, but can be handy for those that are brave enough */
141static int meth_setfd(lua_State *L) {
142 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixstream{any}", 1);
143 un->sock = (t_socket) luaL_checknumber(L, 2);
144 return 0;
145}
146
147static int meth_dirty(lua_State *L) {
148 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixstream{any}", 1);
149 lua_pushboolean(L, !buffer_isempty(&un->buf));
150 return 1;
151}
152
153/*-------------------------------------------------------------------------*\
154* Waits for and returns a client object attempting connection to the
155* server object
156\*-------------------------------------------------------------------------*/
157static int meth_accept(lua_State *L) {
158 p_unix server = (p_unix) auxiliar_checkclass(L, "unixstream{server}", 1);
159 p_timeout tm = timeout_markstart(&server->tm);
160 t_socket sock;
161 int err = socket_accept(&server->sock, &sock, NULL, NULL, tm);
162 /* if successful, push client socket */
163 if (err == IO_DONE) {
164 p_unix clnt = (p_unix) lua_newuserdata(L, sizeof(t_unix));
165 auxiliar_setclass(L, "unixstream{client}", -1);
166 /* initialize structure fields */
167 socket_setnonblocking(&sock);
168 clnt->sock = sock;
169 io_init(&clnt->io, (p_send)socket_send, (p_recv)socket_recv,
170 (p_error) socket_ioerror, &clnt->sock);
171 timeout_init(&clnt->tm, -1, -1);
172 buffer_init(&clnt->buf, &clnt->io, &clnt->tm);
173 return 1;
174 } else {
175 lua_pushnil(L);
176 lua_pushstring(L, socket_strerror(err));
177 return 2;
178 }
179}
180
181/*-------------------------------------------------------------------------*\
182* Binds an object to an address
183\*-------------------------------------------------------------------------*/
184static const char *unixstream_trybind(p_unix un, const char *path) {
185 struct sockaddr_un local;
186 size_t len = strlen(path);
187 int err;
188 if (len >= sizeof(local.sun_path)) return "path too long";
189 memset(&local, 0, sizeof(local));
190 strcpy(local.sun_path, path);
191 local.sun_family = AF_UNIX;
192#ifdef UNIX_HAS_SUN_LEN
193 local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len)
194 + len + 1;
195 err = socket_bind(&un->sock, (SA *) &local, local.sun_len);
196
197#else
198 err = socket_bind(&un->sock, (SA *) &local,
199 sizeof(local.sun_family) + len);
200#endif
201 if (err != IO_DONE) socket_destroy(&un->sock);
202 return socket_strerror(err);
203}
204
205static int meth_bind(lua_State *L) {
206 p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{master}", 1);
207 const char *path = luaL_checkstring(L, 2);
208 const char *err = unixstream_trybind(un, path);
209 if (err) {
210 lua_pushnil(L);
211 lua_pushstring(L, err);
212 return 2;
213 }
214 lua_pushnumber(L, 1);
215 return 1;
216}
217
218static int meth_getsockname(lua_State *L)
219{
220 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixstream{any}", 1);
221 struct sockaddr_un peer = {0};
222 socklen_t peer_len = sizeof(peer);
223
224 if (getsockname(un->sock, (SA *) &peer, &peer_len) < 0) {
225 lua_pushnil(L);
226 lua_pushstring(L, socket_strerror(errno));
227 return 2;
228 }
229
230 lua_pushstring(L, peer.sun_path);
231 return 1;
232}
233
234/*-------------------------------------------------------------------------*\
235* Turns a master unixstream object into a client object.
236\*-------------------------------------------------------------------------*/
237static const char *unixstream_tryconnect(p_unix un, const char *path)
238{
239 struct sockaddr_un remote;
240 int err;
241 size_t len = strlen(path);
242 if (len >= sizeof(remote.sun_path)) return "path too long";
243 memset(&remote, 0, sizeof(remote));
244 strcpy(remote.sun_path, path);
245 remote.sun_family = AF_UNIX;
246 timeout_markstart(&un->tm);
247#ifdef UNIX_HAS_SUN_LEN
248 remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len)
249 + len + 1;
250 err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm);
251#else
252 err = socket_connect(&un->sock, (SA *) &remote,
253 sizeof(remote.sun_family) + len, &un->tm);
254#endif
255 if (err != IO_DONE) socket_destroy(&un->sock);
256 return socket_strerror(err);
257}
258
259static int meth_connect(lua_State *L)
260{
261 p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{master}", 1);
262 const char *path = luaL_checkstring(L, 2);
263 const char *err = unixstream_tryconnect(un, path);
264 if (err) {
265 lua_pushnil(L);
266 lua_pushstring(L, err);
267 return 2;
268 }
269 /* turn master object into a client object */
270 auxiliar_setclass(L, "unixstream{client}", 1);
271 lua_pushnumber(L, 1);
272 return 1;
273}
274
275/*-------------------------------------------------------------------------*\
276* Closes socket used by object
277\*-------------------------------------------------------------------------*/
278static int meth_close(lua_State *L)
279{
280 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixstream{any}", 1);
281 socket_destroy(&un->sock);
282 lua_pushnumber(L, 1);
283 return 1;
284}
285
286/*-------------------------------------------------------------------------*\
287* Puts the sockt in listen mode
288\*-------------------------------------------------------------------------*/
289static int meth_listen(lua_State *L)
290{
291 p_unix un = (p_unix) auxiliar_checkclass(L, "unixstream{master}", 1);
292 int backlog = (int) luaL_optnumber(L, 2, 32);
293 int err = socket_listen(&un->sock, backlog);
294 if (err != IO_DONE) {
295 lua_pushnil(L);
296 lua_pushstring(L, socket_strerror(err));
297 return 2;
298 }
299 /* turn master object into a server object */
300 auxiliar_setclass(L, "unixstream{server}", 1);
301 lua_pushnumber(L, 1);
302 return 1;
303}
304
305/*-------------------------------------------------------------------------*\
306* Shuts the connection down partially
307\*-------------------------------------------------------------------------*/
308static int meth_shutdown(lua_State *L)
309{
310 /* SHUT_RD, SHUT_WR, SHUT_RDWR have the value 0, 1, 2, so we can use method index directly */
311 static const char* methods[] = { "receive", "send", "both", NULL };
312 p_unix stream = (p_unix) auxiliar_checkclass(L, "unixstream{client}", 1);
313 int how = luaL_checkoption(L, 2, "both", methods);
314 socket_shutdown(&stream->sock, how);
315 lua_pushnumber(L, 1);
316 return 1;
317}
318
319/*-------------------------------------------------------------------------*\
320* Just call tm methods
321\*-------------------------------------------------------------------------*/
322static int meth_settimeout(lua_State *L) {
323 p_unix un = (p_unix) auxiliar_checkgroup(L, "unixstream{any}", 1);
324 return timeout_meth_settimeout(L, &un->tm);
325}
326
327/*=========================================================================*\
328* Library functions
329\*=========================================================================*/
330/*-------------------------------------------------------------------------*\
331* Creates a master unixstream object
332\*-------------------------------------------------------------------------*/
333static int global_create(lua_State *L) {
334 t_socket sock;
335 int err = socket_create(&sock, AF_UNIX, SOCK_STREAM, 0);
336 /* try to allocate a system socket */
337 if (err == IO_DONE) {
338 /* allocate unixstream object */
339 p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix));
340 /* set its type as master object */
341 auxiliar_setclass(L, "unixstream{master}", -1);
342 /* initialize remaining structure fields */
343 socket_setnonblocking(&sock);
344 un->sock = sock;
345 io_init(&un->io, (p_send) socket_send, (p_recv) socket_recv,
346 (p_error) socket_ioerror, &un->sock);
347 timeout_init(&un->tm, -1, -1);
348 buffer_init(&un->buf, &un->io, &un->tm);
349 return 1;
350 } else {
351 lua_pushnil(L);
352 lua_pushstring(L, socket_strerror(err));
353 return 2;
354 }
355}
diff --git a/vendor/luasocket/src/unixstream.h b/vendor/luasocket/src/unixstream.h
new file mode 100644
index 00000000..7916affa
--- /dev/null
+++ b/vendor/luasocket/src/unixstream.h
@@ -0,0 +1,29 @@
1#ifndef UNIXSTREAM_H
2#define UNIXSTREAM_H
3/*=========================================================================*\
4* UNIX STREAM object
5* LuaSocket toolkit
6*
7* The unixstream.h module is basicly a glue that puts together modules buffer.h,
8* timeout.h socket.h and inet.h to provide the LuaSocket UNIX STREAM (AF_UNIX,
9* SOCK_STREAM) support.
10*
11* Three classes are defined: master, client and server. The master class is
12* a newly created unixstream object, that has not been bound or connected. Server
13* objects are unixstream objects bound to some local address. Client objects are
14* unixstream objects either connected to some address or returned by the accept
15* method of a server object.
16\*=========================================================================*/
17#include "unix.h"
18
19#ifndef _WIN32
20#pragma GCC visibility push(hidden)
21#endif
22
23int unixstream_open(lua_State *L);
24
25#ifndef _WIN32
26#pragma GCC visibility pop
27#endif
28
29#endif /* UNIXSTREAM_H */
diff --git a/vendor/luasocket/src/url.lua b/vendor/luasocket/src/url.lua
new file mode 100644
index 00000000..8e0dc5ce
--- /dev/null
+++ b/vendor/luasocket/src/url.lua
@@ -0,0 +1,331 @@
1-----------------------------------------------------------------------------
2-- URI parsing, composition and relative URL resolution
3-- LuaSocket toolkit.
4-- Author: Diego Nehab
5-----------------------------------------------------------------------------
6
7-----------------------------------------------------------------------------
8-- Declare module
9-----------------------------------------------------------------------------
10local string = require("string")
11local base = _G
12local table = require("table")
13local socket = require("socket")
14
15socket.url = {}
16local _M = socket.url
17
18-----------------------------------------------------------------------------
19-- Module version
20-----------------------------------------------------------------------------
21_M._VERSION = "URL 1.0.3"
22
23-----------------------------------------------------------------------------
24-- Encodes a string into its escaped hexadecimal representation
25-- Input
26-- s: binary string to be encoded
27-- Returns
28-- escaped representation of string binary
29-----------------------------------------------------------------------------
30function _M.escape(s)
31 return (string.gsub(s, "([^A-Za-z0-9_])", function(c)
32 return string.format("%%%02x", string.byte(c))
33 end))
34end
35
36-----------------------------------------------------------------------------
37-- Protects a path segment, to prevent it from interfering with the
38-- url parsing.
39-- Input
40-- s: binary string to be encoded
41-- Returns
42-- escaped representation of string binary
43-----------------------------------------------------------------------------
44local function make_set(t)
45 local s = {}
46 for i,v in base.ipairs(t) do
47 s[t[i]] = 1
48 end
49 return s
50end
51
52-- these are allowed within a path segment, along with alphanum
53-- other characters must be escaped
54local segment_set = make_set {
55 "-", "_", ".", "!", "~", "*", "'", "(",
56 ")", ":", "@", "&", "=", "+", "$", ",",
57}
58
59local function protect_segment(s)
60 return string.gsub(s, "([^A-Za-z0-9_])", function (c)
61 if segment_set[c] then return c
62 else return string.format("%%%02X", string.byte(c)) end
63 end)
64end
65
66-----------------------------------------------------------------------------
67-- Unencodes a escaped hexadecimal string into its binary representation
68-- Input
69-- s: escaped hexadecimal string to be unencoded
70-- Returns
71-- unescaped binary representation of escaped hexadecimal binary
72-----------------------------------------------------------------------------
73function _M.unescape(s)
74 return (string.gsub(s, "%%(%x%x)", function(hex)
75 return string.char(base.tonumber(hex, 16))
76 end))
77end
78
79-----------------------------------------------------------------------------
80-- Removes '..' and '.' components appropriately from a path.
81-- Input
82-- path
83-- Returns
84-- dot-normalized path
85local function remove_dot_components(path)
86 local marker = string.char(1)
87 repeat
88 local was = path
89 path = path:gsub('//', '/'..marker..'/', 1)
90 until path == was
91 repeat
92 local was = path
93 path = path:gsub('/%./', '/', 1)
94 until path == was
95 repeat
96 local was = path
97 path = path:gsub('[^/]+/%.%./([^/]+)', '%1', 1)
98 until path == was
99 path = path:gsub('[^/]+/%.%./*$', '')
100 path = path:gsub('/%.%.$', '/')
101 path = path:gsub('/%.$', '/')
102 path = path:gsub('^/%.%./', '/')
103 path = path:gsub(marker, '')
104 return path
105end
106
107-----------------------------------------------------------------------------
108-- Builds a path from a base path and a relative path
109-- Input
110-- base_path
111-- relative_path
112-- Returns
113-- corresponding absolute path
114-----------------------------------------------------------------------------
115local function absolute_path(base_path, relative_path)
116 if string.sub(relative_path, 1, 1) == "/" then
117 return remove_dot_components(relative_path) end
118 base_path = base_path:gsub("[^/]*$", "")
119 if not base_path:find'/$' then base_path = base_path .. '/' end
120 local path = base_path .. relative_path
121 path = remove_dot_components(path)
122 return path
123end
124
125-----------------------------------------------------------------------------
126-- Parses a url and returns a table with all its parts according to RFC 2396
127-- The following grammar describes the names given to the URL parts
128-- <url> ::= <scheme>://<authority>/<path>;<params>?<query>#<fragment>
129-- <authority> ::= <userinfo>@<host>:<port>
130-- <userinfo> ::= <user>[:<password>]
131-- <path> :: = {<segment>/}<segment>
132-- Input
133-- url: uniform resource locator of request
134-- default: table with default values for each field
135-- Returns
136-- table with the following fields, where RFC naming conventions have
137-- been preserved:
138-- scheme, authority, userinfo, user, password, host, port,
139-- path, params, query, fragment
140-- Obs:
141-- the leading '/' in {/<path>} is considered part of <path>
142-----------------------------------------------------------------------------
143function _M.parse(url, default)
144 -- initialize default parameters
145 local parsed = {}
146 for i,v in base.pairs(default or parsed) do parsed[i] = v end
147 -- empty url is parsed to nil
148 if not url or url == "" then return nil, "invalid url" end
149 -- remove whitespace
150 -- url = string.gsub(url, "%s", "")
151 -- get scheme
152 url = string.gsub(url, "^([%w][%w%+%-%.]*)%:",
153 function(s) parsed.scheme = s; return "" end)
154 -- get authority
155 url = string.gsub(url, "^//([^/]*)", function(n)
156 parsed.authority = n
157 return ""
158 end)
159 -- get fragment
160 url = string.gsub(url, "#(.*)$", function(f)
161 parsed.fragment = f
162 return ""
163 end)
164 -- get query string
165 url = string.gsub(url, "%?(.*)", function(q)
166 parsed.query = q
167 return ""
168 end)
169 -- get params
170 url = string.gsub(url, "%;(.*)", function(p)
171 parsed.params = p
172 return ""
173 end)
174 -- path is whatever was left
175 if url ~= "" then parsed.path = url end
176 local authority = parsed.authority
177 if not authority then return parsed end
178 authority = string.gsub(authority,"^([^@]*)@",
179 function(u) parsed.userinfo = u; return "" end)
180 authority = string.gsub(authority, ":([^:%]]*)$",
181 function(p) parsed.port = p; return "" end)
182 if authority ~= "" then
183 -- IPv6?
184 parsed.host = string.match(authority, "^%[(.+)%]$") or authority
185 end
186 local userinfo = parsed.userinfo
187 if not userinfo then return parsed end
188 userinfo = string.gsub(userinfo, ":([^:]*)$",
189 function(p) parsed.password = p; return "" end)
190 parsed.user = userinfo
191 return parsed
192end
193
194-----------------------------------------------------------------------------
195-- Rebuilds a parsed URL from its components.
196-- Components are protected if any reserved or unallowed characters are found
197-- Input
198-- parsed: parsed URL, as returned by parse
199-- Returns
200-- a stringing with the corresponding URL
201-----------------------------------------------------------------------------
202function _M.build(parsed)
203 --local ppath = _M.parse_path(parsed.path or "")
204 --local url = _M.build_path(ppath)
205 local url = parsed.path or ""
206 if parsed.params then url = url .. ";" .. parsed.params end
207 if parsed.query then url = url .. "?" .. parsed.query end
208 local authority = parsed.authority
209 if parsed.host then
210 authority = parsed.host
211 if string.find(authority, ":") then -- IPv6?
212 authority = "[" .. authority .. "]"
213 end
214 if parsed.port then authority = authority .. ":" .. base.tostring(parsed.port) end
215 local userinfo = parsed.userinfo
216 if parsed.user then
217 userinfo = parsed.user
218 if parsed.password then
219 userinfo = userinfo .. ":" .. parsed.password
220 end
221 end
222 if userinfo then authority = userinfo .. "@" .. authority end
223 end
224 if authority then url = "//" .. authority .. url end
225 if parsed.scheme then url = parsed.scheme .. ":" .. url end
226 if parsed.fragment then url = url .. "#" .. parsed.fragment end
227 -- url = string.gsub(url, "%s", "")
228 return url
229end
230
231-----------------------------------------------------------------------------
232-- Builds a absolute URL from a base and a relative URL according to RFC 2396
233-- Input
234-- base_url
235-- relative_url
236-- Returns
237-- corresponding absolute url
238-----------------------------------------------------------------------------
239function _M.absolute(base_url, relative_url)
240 local base_parsed
241 if base.type(base_url) == "table" then
242 base_parsed = base_url
243 base_url = _M.build(base_parsed)
244 else
245 base_parsed = _M.parse(base_url)
246 end
247 local result
248 local relative_parsed = _M.parse(relative_url)
249 if not base_parsed then
250 result = relative_url
251 elseif not relative_parsed then
252 result = base_url
253 elseif relative_parsed.scheme then
254 result = relative_url
255 else
256 relative_parsed.scheme = base_parsed.scheme
257 if not relative_parsed.authority then
258 relative_parsed.authority = base_parsed.authority
259 if not relative_parsed.path then
260 relative_parsed.path = base_parsed.path
261 if not relative_parsed.params then
262 relative_parsed.params = base_parsed.params
263 if not relative_parsed.query then
264 relative_parsed.query = base_parsed.query
265 end
266 end
267 else
268 relative_parsed.path = absolute_path(base_parsed.path or "",
269 relative_parsed.path)
270 end
271 end
272 result = _M.build(relative_parsed)
273 end
274 return remove_dot_components(result)
275end
276
277-----------------------------------------------------------------------------
278-- Breaks a path into its segments, unescaping the segments
279-- Input
280-- path
281-- Returns
282-- segment: a table with one entry per segment
283-----------------------------------------------------------------------------
284function _M.parse_path(path)
285 local parsed = {}
286 path = path or ""
287 --path = string.gsub(path, "%s", "")
288 string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end)
289 for i = 1, #parsed do
290 parsed[i] = _M.unescape(parsed[i])
291 end
292 if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end
293 if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end
294 return parsed
295end
296
297-----------------------------------------------------------------------------
298-- Builds a path component from its segments, escaping protected characters.
299-- Input
300-- parsed: path segments
301-- unsafe: if true, segments are not protected before path is built
302-- Returns
303-- path: corresponding path stringing
304-----------------------------------------------------------------------------
305function _M.build_path(parsed, unsafe)
306 local path = ""
307 local n = #parsed
308 if unsafe then
309 for i = 1, n-1 do
310 path = path .. parsed[i]
311 path = path .. "/"
312 end
313 if n > 0 then
314 path = path .. parsed[n]
315 if parsed.is_directory then path = path .. "/" end
316 end
317 else
318 for i = 1, n-1 do
319 path = path .. protect_segment(parsed[i])
320 path = path .. "/"
321 end
322 if n > 0 then
323 path = path .. protect_segment(parsed[n])
324 if parsed.is_directory then path = path .. "/" end
325 end
326 end
327 if parsed.is_absolute then path = "/" .. path end
328 return path
329end
330
331return _M
diff --git a/vendor/luasocket/src/usocket.c b/vendor/luasocket/src/usocket.c
new file mode 100644
index 00000000..69635daa
--- /dev/null
+++ b/vendor/luasocket/src/usocket.c
@@ -0,0 +1,454 @@
1/*=========================================================================*\
2* Socket compatibilization module for Unix
3* LuaSocket toolkit
4*
5* The code is now interrupt-safe.
6* The penalty of calling select to avoid busy-wait is only paid when
7* the I/O call fail in the first place.
8\*=========================================================================*/
9#include "luasocket.h"
10
11#include "socket.h"
12#include "pierror.h"
13
14#include <string.h>
15#include <signal.h>
16
17/*-------------------------------------------------------------------------*\
18* Wait for readable/writable/connected socket with timeout
19\*-------------------------------------------------------------------------*/
20#ifndef SOCKET_SELECT
21#include <sys/poll.h>
22
23#define WAITFD_R POLLIN
24#define WAITFD_W POLLOUT
25#define WAITFD_C (POLLIN|POLLOUT)
26int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
27 int ret;
28 struct pollfd pfd;
29 pfd.fd = *ps;
30 pfd.events = sw;
31 pfd.revents = 0;
32 if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
33 do {
34 int t = (int)(timeout_getretry(tm)*1e3);
35 ret = poll(&pfd, 1, t >= 0? t: -1);
36 } while (ret == -1 && errno == EINTR);
37 if (ret == -1) return errno;
38 if (ret == 0) return IO_TIMEOUT;
39 if (sw == WAITFD_C && (pfd.revents & (POLLIN|POLLERR))) return IO_CLOSED;
40 return IO_DONE;
41}
42#else
43
44#define WAITFD_R 1
45#define WAITFD_W 2
46#define WAITFD_C (WAITFD_R|WAITFD_W)
47
48int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
49 int ret;
50 fd_set rfds, wfds, *rp, *wp;
51 struct timeval tv, *tp;
52 double t;
53 if (*ps >= FD_SETSIZE) return EINVAL;
54 if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
55 do {
56 /* must set bits within loop, because select may have modifed them */
57 rp = wp = NULL;
58 if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(*ps, &rfds); rp = &rfds; }
59 if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
60 t = timeout_getretry(tm);
61 tp = NULL;
62 if (t >= 0.0) {
63 tv.tv_sec = (int)t;
64 tv.tv_usec = (int)((t-tv.tv_sec)*1.0e6);
65 tp = &tv;
66 }
67 ret = select(*ps+1, rp, wp, NULL, tp);
68 } while (ret == -1 && errno == EINTR);
69 if (ret == -1) return errno;
70 if (ret == 0) return IO_TIMEOUT;
71 if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) return IO_CLOSED;
72 return IO_DONE;
73}
74#endif
75
76
77/*-------------------------------------------------------------------------*\
78* Initializes module
79\*-------------------------------------------------------------------------*/
80int socket_open(void) {
81 /* installs a handler to ignore sigpipe or it will crash us */
82 signal(SIGPIPE, SIG_IGN);
83 return 1;
84}
85
86/*-------------------------------------------------------------------------*\
87* Close module
88\*-------------------------------------------------------------------------*/
89int socket_close(void) {
90 return 1;
91}
92
93/*-------------------------------------------------------------------------*\
94* Close and inutilize socket
95\*-------------------------------------------------------------------------*/
96void socket_destroy(p_socket ps) {
97 if (*ps != SOCKET_INVALID) {
98 close(*ps);
99 *ps = SOCKET_INVALID;
100 }
101}
102
103/*-------------------------------------------------------------------------*\
104* Select with timeout control
105\*-------------------------------------------------------------------------*/
106int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
107 p_timeout tm) {
108 int ret;
109 do {
110 struct timeval tv;
111 double t = timeout_getretry(tm);
112 tv.tv_sec = (int) t;
113 tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
114 /* timeout = 0 means no wait */
115 ret = select(n, rfds, wfds, efds, t >= 0.0 ? &tv: NULL);
116 } while (ret < 0 && errno == EINTR);
117 return ret;
118}
119
120/*-------------------------------------------------------------------------*\
121* Creates and sets up a socket
122\*-------------------------------------------------------------------------*/
123int socket_create(p_socket ps, int domain, int type, int protocol) {
124 *ps = socket(domain, type, protocol);
125 if (*ps != SOCKET_INVALID) return IO_DONE;
126 else return errno;
127}
128
129/*-------------------------------------------------------------------------*\
130* Binds or returns error message
131\*-------------------------------------------------------------------------*/
132int socket_bind(p_socket ps, SA *addr, socklen_t len) {
133 int err = IO_DONE;
134 socket_setblocking(ps);
135 if (bind(*ps, addr, len) < 0) err = errno;
136 socket_setnonblocking(ps);
137 return err;
138}
139
140/*-------------------------------------------------------------------------*\
141*
142\*-------------------------------------------------------------------------*/
143int socket_listen(p_socket ps, int backlog) {
144 int err = IO_DONE;
145 if (listen(*ps, backlog)) err = errno;
146 return err;
147}
148
149/*-------------------------------------------------------------------------*\
150*
151\*-------------------------------------------------------------------------*/
152void socket_shutdown(p_socket ps, int how) {
153 shutdown(*ps, how);
154}
155
156/*-------------------------------------------------------------------------*\
157* Connects or returns error message
158\*-------------------------------------------------------------------------*/
159int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) {
160 int err;
161 /* avoid calling on closed sockets */
162 if (*ps == SOCKET_INVALID) return IO_CLOSED;
163 /* call connect until done or failed without being interrupted */
164 do if (connect(*ps, addr, len) == 0) return IO_DONE;
165 while ((err = errno) == EINTR);
166 /* if connection failed immediately, return error code */
167 if (err != EINPROGRESS && err != EAGAIN) return err;
168 /* zero timeout case optimization */
169 if (timeout_iszero(tm)) return IO_TIMEOUT;
170 /* wait until we have the result of the connection attempt or timeout */
171 err = socket_waitfd(ps, WAITFD_C, tm);
172 if (err == IO_CLOSED) {
173 if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE;
174 else return errno;
175 } else return err;
176}
177
178/*-------------------------------------------------------------------------*\
179* Accept with timeout
180\*-------------------------------------------------------------------------*/
181int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout tm) {
182 if (*ps == SOCKET_INVALID) return IO_CLOSED;
183 for ( ;; ) {
184 int err;
185 if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE;
186 err = errno;
187 if (err == EINTR) continue;
188 if (err != EAGAIN && err != ECONNABORTED) return err;
189 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
190 }
191 /* can't reach here */
192 return IO_UNKNOWN;
193}
194
195/*-------------------------------------------------------------------------*\
196* Send with timeout
197\*-------------------------------------------------------------------------*/
198int socket_send(p_socket ps, const char *data, size_t count,
199 size_t *sent, p_timeout tm)
200{
201 int err;
202 *sent = 0;
203 /* avoid making system calls on closed sockets */
204 if (*ps == SOCKET_INVALID) return IO_CLOSED;
205 /* loop until we send something or we give up on error */
206 for ( ;; ) {
207 long put = (long) send(*ps, data, count, 0);
208 /* if we sent anything, we are done */
209 if (put >= 0) {
210 *sent = put;
211 return IO_DONE;
212 }
213 err = errno;
214 /* EPIPE means the connection was closed */
215 if (err == EPIPE) return IO_CLOSED;
216 /* EPROTOTYPE means the connection is being closed (on Yosemite!)*/
217 if (err == EPROTOTYPE) continue;
218 /* we call was interrupted, just try again */
219 if (err == EINTR) continue;
220 /* if failed fatal reason, report error */
221 if (err != EAGAIN) return err;
222 /* wait until we can send something or we timeout */
223 if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
224 }
225 /* can't reach here */
226 return IO_UNKNOWN;
227}
228
229/*-------------------------------------------------------------------------*\
230* Sendto with timeout
231\*-------------------------------------------------------------------------*/
232int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
233 SA *addr, socklen_t len, p_timeout tm)
234{
235 int err;
236 *sent = 0;
237 if (*ps == SOCKET_INVALID) return IO_CLOSED;
238 for ( ;; ) {
239 long put = (long) sendto(*ps, data, count, 0, addr, len);
240 if (put >= 0) {
241 *sent = put;
242 return IO_DONE;
243 }
244 err = errno;
245 if (err == EPIPE) return IO_CLOSED;
246 if (err == EPROTOTYPE) continue;
247 if (err == EINTR) continue;
248 if (err != EAGAIN) return err;
249 if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
250 }
251 return IO_UNKNOWN;
252}
253
254/*-------------------------------------------------------------------------*\
255* Receive with timeout
256\*-------------------------------------------------------------------------*/
257int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) {
258 int err;
259 *got = 0;
260 if (*ps == SOCKET_INVALID) return IO_CLOSED;
261 for ( ;; ) {
262 long taken = (long) recv(*ps, data, count, 0);
263 if (taken > 0) {
264 *got = taken;
265 return IO_DONE;
266 }
267 err = errno;
268 if (taken == 0) return IO_CLOSED;
269 if (err == EINTR) continue;
270 if (err != EAGAIN) return err;
271 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
272 }
273 return IO_UNKNOWN;
274}
275
276/*-------------------------------------------------------------------------*\
277* Recvfrom with timeout
278\*-------------------------------------------------------------------------*/
279int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
280 SA *addr, socklen_t *len, p_timeout tm) {
281 int err;
282 *got = 0;
283 if (*ps == SOCKET_INVALID) return IO_CLOSED;
284 for ( ;; ) {
285 long taken = (long) recvfrom(*ps, data, count, 0, addr, len);
286 if (taken > 0) {
287 *got = taken;
288 return IO_DONE;
289 }
290 err = errno;
291 if (taken == 0) return IO_CLOSED;
292 if (err == EINTR) continue;
293 if (err != EAGAIN) return err;
294 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
295 }
296 return IO_UNKNOWN;
297}
298
299
300/*-------------------------------------------------------------------------*\
301* Write with timeout
302*
303* socket_read and socket_write are cut-n-paste of socket_send and socket_recv,
304* with send/recv replaced with write/read. We can't just use write/read
305* in the socket version, because behaviour when size is zero is different.
306\*-------------------------------------------------------------------------*/
307int socket_write(p_socket ps, const char *data, size_t count,
308 size_t *sent, p_timeout tm)
309{
310 int err;
311 *sent = 0;
312 /* avoid making system calls on closed sockets */
313 if (*ps == SOCKET_INVALID) return IO_CLOSED;
314 /* loop until we send something or we give up on error */
315 for ( ;; ) {
316 long put = (long) write(*ps, data, count);
317 /* if we sent anything, we are done */
318 if (put >= 0) {
319 *sent = put;
320 return IO_DONE;
321 }
322 err = errno;
323 /* EPIPE means the connection was closed */
324 if (err == EPIPE) return IO_CLOSED;
325 /* EPROTOTYPE means the connection is being closed (on Yosemite!)*/
326 if (err == EPROTOTYPE) continue;
327 /* we call was interrupted, just try again */
328 if (err == EINTR) continue;
329 /* if failed fatal reason, report error */
330 if (err != EAGAIN) return err;
331 /* wait until we can send something or we timeout */
332 if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
333 }
334 /* can't reach here */
335 return IO_UNKNOWN;
336}
337
338/*-------------------------------------------------------------------------*\
339* Read with timeout
340* See note for socket_write
341\*-------------------------------------------------------------------------*/
342int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) {
343 int err;
344 *got = 0;
345 if (*ps == SOCKET_INVALID) return IO_CLOSED;
346 for ( ;; ) {
347 long taken = (long) read(*ps, data, count);
348 if (taken > 0) {
349 *got = taken;
350 return IO_DONE;
351 }
352 err = errno;
353 if (taken == 0) return IO_CLOSED;
354 if (err == EINTR) continue;
355 if (err != EAGAIN) return err;
356 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
357 }
358 return IO_UNKNOWN;
359}
360
361/*-------------------------------------------------------------------------*\
362* Put socket into blocking mode
363\*-------------------------------------------------------------------------*/
364void socket_setblocking(p_socket ps) {
365 int flags = fcntl(*ps, F_GETFL, 0);
366 flags &= (~(O_NONBLOCK));
367 fcntl(*ps, F_SETFL, flags);
368}
369
370/*-------------------------------------------------------------------------*\
371* Put socket into non-blocking mode
372\*-------------------------------------------------------------------------*/
373void socket_setnonblocking(p_socket ps) {
374 int flags = fcntl(*ps, F_GETFL, 0);
375 flags |= O_NONBLOCK;
376 fcntl(*ps, F_SETFL, flags);
377}
378
379/*-------------------------------------------------------------------------*\
380* DNS helpers
381\*-------------------------------------------------------------------------*/
382int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) {
383 *hp = gethostbyaddr(addr, len, AF_INET);
384 if (*hp) return IO_DONE;
385 else if (h_errno) return h_errno;
386 else if (errno) return errno;
387 else return IO_UNKNOWN;
388}
389
390int socket_gethostbyname(const char *addr, struct hostent **hp) {
391 *hp = gethostbyname(addr);
392 if (*hp) return IO_DONE;
393 else if (h_errno) return h_errno;
394 else if (errno) return errno;
395 else return IO_UNKNOWN;
396}
397
398/*-------------------------------------------------------------------------*\
399* Error translation functions
400* Make sure important error messages are standard
401\*-------------------------------------------------------------------------*/
402const char *socket_hoststrerror(int err) {
403 if (err <= 0) return io_strerror(err);
404 switch (err) {
405 case HOST_NOT_FOUND: return PIE_HOST_NOT_FOUND;
406 default: return hstrerror(err);
407 }
408}
409
410const char *socket_strerror(int err) {
411 if (err <= 0) return io_strerror(err);
412 switch (err) {
413 case EADDRINUSE: return PIE_ADDRINUSE;
414 case EISCONN: return PIE_ISCONN;
415 case EACCES: return PIE_ACCESS;
416 case ECONNREFUSED: return PIE_CONNREFUSED;
417 case ECONNABORTED: return PIE_CONNABORTED;
418 case ECONNRESET: return PIE_CONNRESET;
419 case ETIMEDOUT: return PIE_TIMEDOUT;
420 default: {
421 return strerror(err);
422 }
423 }
424}
425
426const char *socket_ioerror(p_socket ps, int err) {
427 (void) ps;
428 return socket_strerror(err);
429}
430
431const char *socket_gaistrerror(int err) {
432 if (err == 0) return NULL;
433 switch (err) {
434 case EAI_AGAIN: return PIE_AGAIN;
435 case EAI_BADFLAGS: return PIE_BADFLAGS;
436#ifdef EAI_BADHINTS
437 case EAI_BADHINTS: return PIE_BADHINTS;
438#endif
439 case EAI_FAIL: return PIE_FAIL;
440 case EAI_FAMILY: return PIE_FAMILY;
441 case EAI_MEMORY: return PIE_MEMORY;
442 case EAI_NONAME: return PIE_NONAME;
443#ifdef EAI_OVERFLOW
444 case EAI_OVERFLOW: return PIE_OVERFLOW;
445#endif
446#ifdef EAI_PROTOCOL
447 case EAI_PROTOCOL: return PIE_PROTOCOL;
448#endif
449 case EAI_SERVICE: return PIE_SERVICE;
450 case EAI_SOCKTYPE: return PIE_SOCKTYPE;
451 case EAI_SYSTEM: return strerror(errno);
452 default: return LUA_GAI_STRERROR(err);
453 }
454}
diff --git a/vendor/luasocket/src/usocket.h b/vendor/luasocket/src/usocket.h
new file mode 100644
index 00000000..45f2f99f
--- /dev/null
+++ b/vendor/luasocket/src/usocket.h
@@ -0,0 +1,59 @@
1#ifndef USOCKET_H
2#define USOCKET_H
3/*=========================================================================*\
4* Socket compatibilization module for Unix
5* LuaSocket toolkit
6\*=========================================================================*/
7
8/*=========================================================================*\
9* BSD include files
10\*=========================================================================*/
11/* error codes */
12#include <errno.h>
13/* close function */
14#include <unistd.h>
15/* fnctnl function and associated constants */
16#include <fcntl.h>
17/* struct sockaddr */
18#include <sys/types.h>
19/* socket function */
20#include <sys/socket.h>
21/* struct timeval */
22#include <sys/time.h>
23/* gethostbyname and gethostbyaddr functions */
24#include <netdb.h>
25/* sigpipe handling */
26#include <signal.h>
27/* IP stuff*/
28#include <netinet/in.h>
29#include <arpa/inet.h>
30/* TCP options (nagle algorithm disable) */
31#include <netinet/tcp.h>
32#include <net/if.h>
33
34#ifndef SO_REUSEPORT
35#define SO_REUSEPORT SO_REUSEADDR
36#endif
37
38/* Some platforms use IPV6_JOIN_GROUP instead if
39 * IPV6_ADD_MEMBERSHIP. The semantics are same, though. */
40#ifndef IPV6_ADD_MEMBERSHIP
41#ifdef IPV6_JOIN_GROUP
42#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
43#endif /* IPV6_JOIN_GROUP */
44#endif /* !IPV6_ADD_MEMBERSHIP */
45
46/* Same with IPV6_DROP_MEMBERSHIP / IPV6_LEAVE_GROUP. */
47#ifndef IPV6_DROP_MEMBERSHIP
48#ifdef IPV6_LEAVE_GROUP
49#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
50#endif /* IPV6_LEAVE_GROUP */
51#endif /* !IPV6_DROP_MEMBERSHIP */
52
53typedef int t_socket;
54typedef t_socket *p_socket;
55typedef struct sockaddr_storage t_sockaddr_storage;
56
57#define SOCKET_INVALID (-1)
58
59#endif /* USOCKET_H */
diff --git a/vendor/luasocket/src/wsocket.c b/vendor/luasocket/src/wsocket.c
new file mode 100755
index 00000000..6cb1e415
--- /dev/null
+++ b/vendor/luasocket/src/wsocket.c
@@ -0,0 +1,434 @@
1/*=========================================================================*\
2* Socket compatibilization module for Win32
3* LuaSocket toolkit
4*
5* The penalty of calling select to avoid busy-wait is only paid when
6* the I/O call fail in the first place.
7\*=========================================================================*/
8#include "luasocket.h"
9
10#include <string.h>
11
12#include "socket.h"
13#include "pierror.h"
14
15/* WinSock doesn't have a strerror... */
16static const char *wstrerror(int err);
17
18/*-------------------------------------------------------------------------*\
19* Initializes module
20\*-------------------------------------------------------------------------*/
21int socket_open(void) {
22 WSADATA wsaData;
23 WORD wVersionRequested = MAKEWORD(2, 0);
24 int err = WSAStartup(wVersionRequested, &wsaData );
25 if (err != 0) return 0;
26 if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) &&
27 (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) {
28 WSACleanup();
29 return 0;
30 }
31 return 1;
32}
33
34/*-------------------------------------------------------------------------*\
35* Close module
36\*-------------------------------------------------------------------------*/
37int socket_close(void) {
38 WSACleanup();
39 return 1;
40}
41
42/*-------------------------------------------------------------------------*\
43* Wait for readable/writable/connected socket with timeout
44\*-------------------------------------------------------------------------*/
45#define WAITFD_R 1
46#define WAITFD_W 2
47#define WAITFD_E 4
48#define WAITFD_C (WAITFD_E|WAITFD_W)
49
50int socket_waitfd(p_socket ps, int sw, p_timeout tm) {
51 int ret;
52 fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL;
53 struct timeval tv, *tp = NULL;
54 double t;
55 if (timeout_iszero(tm)) return IO_TIMEOUT; /* optimize timeout == 0 case */
56 if (sw & WAITFD_R) {
57 FD_ZERO(&rfds);
58 FD_SET(*ps, &rfds);
59 rp = &rfds;
60 }
61 if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; }
62 if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; }
63 if ((t = timeout_get(tm)) >= 0.0) {
64 tv.tv_sec = (int) t;
65 tv.tv_usec = (int) ((t-tv.tv_sec)*1.0e6);
66 tp = &tv;
67 }
68 ret = select(0, rp, wp, ep, tp);
69 if (ret == -1) return WSAGetLastError();
70 if (ret == 0) return IO_TIMEOUT;
71 if (sw == WAITFD_C && FD_ISSET(*ps, &efds)) return IO_CLOSED;
72 return IO_DONE;
73}
74
75/*-------------------------------------------------------------------------*\
76* Select with int timeout in ms
77\*-------------------------------------------------------------------------*/
78int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,
79 p_timeout tm) {
80 struct timeval tv;
81 double t = timeout_get(tm);
82 tv.tv_sec = (int) t;
83 tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6);
84 if (n <= 0) {
85 Sleep((DWORD) (1000*t));
86 return 0;
87 } else return select(0, rfds, wfds, efds, t >= 0.0? &tv: NULL);
88}
89
90/*-------------------------------------------------------------------------*\
91* Close and inutilize socket
92\*-------------------------------------------------------------------------*/
93void socket_destroy(p_socket ps) {
94 if (*ps != SOCKET_INVALID) {
95 socket_setblocking(ps); /* close can take a long time on WIN32 */
96 closesocket(*ps);
97 *ps = SOCKET_INVALID;
98 }
99}
100
101/*-------------------------------------------------------------------------*\
102*
103\*-------------------------------------------------------------------------*/
104void socket_shutdown(p_socket ps, int how) {
105 socket_setblocking(ps);
106 shutdown(*ps, how);
107 socket_setnonblocking(ps);
108}
109
110/*-------------------------------------------------------------------------*\
111* Creates and sets up a socket
112\*-------------------------------------------------------------------------*/
113int socket_create(p_socket ps, int domain, int type, int protocol) {
114 *ps = socket(domain, type, protocol);
115 if (*ps != SOCKET_INVALID) return IO_DONE;
116 else return WSAGetLastError();
117}
118
119/*-------------------------------------------------------------------------*\
120* Connects or returns error message
121\*-------------------------------------------------------------------------*/
122int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) {
123 int err;
124 /* don't call on closed socket */
125 if (*ps == SOCKET_INVALID) return IO_CLOSED;
126 /* ask system to connect */
127 if (connect(*ps, addr, len) == 0) return IO_DONE;
128 /* make sure the system is trying to connect */
129 err = WSAGetLastError();
130 if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) return err;
131 /* zero timeout case optimization */
132 if (timeout_iszero(tm)) return IO_TIMEOUT;
133 /* we wait until something happens */
134 err = socket_waitfd(ps, WAITFD_C, tm);
135 if (err == IO_CLOSED) {
136 int elen = sizeof(err);
137 /* give windows time to set the error (yes, disgusting) */
138 Sleep(10);
139 /* find out why we failed */
140 getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &elen);
141 /* we KNOW there was an error. if 'why' is 0, we will return
142 * "unknown error", but it's not really our fault */
143 return err > 0? err: IO_UNKNOWN;
144 } else return err;
145
146}
147
148/*-------------------------------------------------------------------------*\
149* Binds or returns error message
150\*-------------------------------------------------------------------------*/
151int socket_bind(p_socket ps, SA *addr, socklen_t len) {
152 int err = IO_DONE;
153 socket_setblocking(ps);
154 if (bind(*ps, addr, len) < 0) err = WSAGetLastError();
155 socket_setnonblocking(ps);
156 return err;
157}
158
159/*-------------------------------------------------------------------------*\
160*
161\*-------------------------------------------------------------------------*/
162int socket_listen(p_socket ps, int backlog) {
163 int err = IO_DONE;
164 socket_setblocking(ps);
165 if (listen(*ps, backlog) < 0) err = WSAGetLastError();
166 socket_setnonblocking(ps);
167 return err;
168}
169
170/*-------------------------------------------------------------------------*\
171* Accept with timeout
172\*-------------------------------------------------------------------------*/
173int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len,
174 p_timeout tm) {
175 if (*ps == SOCKET_INVALID) return IO_CLOSED;
176 for ( ;; ) {
177 int err;
178 /* try to get client socket */
179 if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE;
180 /* find out why we failed */
181 err = WSAGetLastError();
182 /* if we failed because there was no connectoin, keep trying */
183 if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) return err;
184 /* call select to avoid busy wait */
185 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
186 }
187}
188
189/*-------------------------------------------------------------------------*\
190* Send with timeout
191* On windows, if you try to send 10MB, the OS will buffer EVERYTHING
192* this can take an awful lot of time and we will end up blocked.
193* Therefore, whoever calls this function should not pass a huge buffer.
194\*-------------------------------------------------------------------------*/
195int socket_send(p_socket ps, const char *data, size_t count,
196 size_t *sent, p_timeout tm)
197{
198 int err;
199 *sent = 0;
200 /* avoid making system calls on closed sockets */
201 if (*ps == SOCKET_INVALID) return IO_CLOSED;
202 /* loop until we send something or we give up on error */
203 for ( ;; ) {
204 /* try to send something */
205 int put = send(*ps, data, (int) count, 0);
206 /* if we sent something, we are done */
207 if (put > 0) {
208 *sent = put;
209 return IO_DONE;
210 }
211 /* deal with failure */
212 err = WSAGetLastError();
213 /* we can only proceed if there was no serious error */
214 if (err != WSAEWOULDBLOCK) return err;
215 /* avoid busy wait */
216 if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
217 }
218}
219
220/*-------------------------------------------------------------------------*\
221* Sendto with timeout
222\*-------------------------------------------------------------------------*/
223int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,
224 SA *addr, socklen_t len, p_timeout tm)
225{
226 int err;
227 *sent = 0;
228 if (*ps == SOCKET_INVALID) return IO_CLOSED;
229 for ( ;; ) {
230 int put = sendto(*ps, data, (int) count, 0, addr, len);
231 if (put > 0) {
232 *sent = put;
233 return IO_DONE;
234 }
235 err = WSAGetLastError();
236 if (err != WSAEWOULDBLOCK) return err;
237 if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err;
238 }
239}
240
241/*-------------------------------------------------------------------------*\
242* Receive with timeout
243\*-------------------------------------------------------------------------*/
244int socket_recv(p_socket ps, char *data, size_t count, size_t *got,
245 p_timeout tm)
246{
247 int err, prev = IO_DONE;
248 *got = 0;
249 if (*ps == SOCKET_INVALID) return IO_CLOSED;
250 for ( ;; ) {
251 int taken = recv(*ps, data, (int) count, 0);
252 if (taken > 0) {
253 *got = taken;
254 return IO_DONE;
255 }
256 if (taken == 0) return IO_CLOSED;
257 err = WSAGetLastError();
258 /* On UDP, a connreset simply means the previous send failed.
259 * So we try again.
260 * On TCP, it means our socket is now useless, so the error passes.
261 * (We will loop again, exiting because the same error will happen) */
262 if (err != WSAEWOULDBLOCK) {
263 if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
264 prev = err;
265 }
266 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
267 }
268}
269
270/*-------------------------------------------------------------------------*\
271* Recvfrom with timeout
272\*-------------------------------------------------------------------------*/
273int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got,
274 SA *addr, socklen_t *len, p_timeout tm)
275{
276 int err, prev = IO_DONE;
277 *got = 0;
278 if (*ps == SOCKET_INVALID) return IO_CLOSED;
279 for ( ;; ) {
280 int taken = recvfrom(*ps, data, (int) count, 0, addr, len);
281 if (taken > 0) {
282 *got = taken;
283 return IO_DONE;
284 }
285 if (taken == 0) return IO_CLOSED;
286 err = WSAGetLastError();
287 /* On UDP, a connreset simply means the previous send failed.
288 * So we try again.
289 * On TCP, it means our socket is now useless, so the error passes.
290 * (We will loop again, exiting because the same error will happen) */
291 if (err != WSAEWOULDBLOCK) {
292 if (err != WSAECONNRESET || prev == WSAECONNRESET) return err;
293 prev = err;
294 }
295 if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;
296 }
297}
298
299/*-------------------------------------------------------------------------*\
300* Put socket into blocking mode
301\*-------------------------------------------------------------------------*/
302void socket_setblocking(p_socket ps) {
303 u_long argp = 0;
304 ioctlsocket(*ps, FIONBIO, &argp);
305}
306
307/*-------------------------------------------------------------------------*\
308* Put socket into non-blocking mode
309\*-------------------------------------------------------------------------*/
310void socket_setnonblocking(p_socket ps) {
311 u_long argp = 1;
312 ioctlsocket(*ps, FIONBIO, &argp);
313}
314
315/*-------------------------------------------------------------------------*\
316* DNS helpers
317\*-------------------------------------------------------------------------*/
318int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) {
319 *hp = gethostbyaddr(addr, len, AF_INET);
320 if (*hp) return IO_DONE;
321 else return WSAGetLastError();
322}
323
324int socket_gethostbyname(const char *addr, struct hostent **hp) {
325 *hp = gethostbyname(addr);
326 if (*hp) return IO_DONE;
327 else return WSAGetLastError();
328}
329
330/*-------------------------------------------------------------------------*\
331* Error translation functions
332\*-------------------------------------------------------------------------*/
333const char *socket_hoststrerror(int err) {
334 if (err <= 0) return io_strerror(err);
335 switch (err) {
336 case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND;
337 default: return wstrerror(err);
338 }
339}
340
341const char *socket_strerror(int err) {
342 if (err <= 0) return io_strerror(err);
343 switch (err) {
344 case WSAEADDRINUSE: return PIE_ADDRINUSE;
345 case WSAECONNREFUSED : return PIE_CONNREFUSED;
346 case WSAEISCONN: return PIE_ISCONN;
347 case WSAEACCES: return PIE_ACCESS;
348 case WSAECONNABORTED: return PIE_CONNABORTED;
349 case WSAECONNRESET: return PIE_CONNRESET;
350 case WSAETIMEDOUT: return PIE_TIMEDOUT;
351 default: return wstrerror(err);
352 }
353}
354
355const char *socket_ioerror(p_socket ps, int err) {
356 (void) ps;
357 return socket_strerror(err);
358}
359
360static const char *wstrerror(int err) {
361 switch (err) {
362 case WSAEINTR: return "Interrupted function call";
363 case WSAEACCES: return PIE_ACCESS; /* "Permission denied"; */
364 case WSAEFAULT: return "Bad address";
365 case WSAEINVAL: return "Invalid argument";
366 case WSAEMFILE: return "Too many open files";
367 case WSAEWOULDBLOCK: return "Resource temporarily unavailable";
368 case WSAEINPROGRESS: return "Operation now in progress";
369 case WSAEALREADY: return "Operation already in progress";
370 case WSAENOTSOCK: return "Socket operation on nonsocket";
371 case WSAEDESTADDRREQ: return "Destination address required";
372 case WSAEMSGSIZE: return "Message too long";
373 case WSAEPROTOTYPE: return "Protocol wrong type for socket";
374 case WSAENOPROTOOPT: return "Bad protocol option";
375 case WSAEPROTONOSUPPORT: return "Protocol not supported";
376 case WSAESOCKTNOSUPPORT: return PIE_SOCKTYPE; /* "Socket type not supported"; */
377 case WSAEOPNOTSUPP: return "Operation not supported";
378 case WSAEPFNOSUPPORT: return "Protocol family not supported";
379 case WSAEAFNOSUPPORT: return PIE_FAMILY; /* "Address family not supported by protocol family"; */
380 case WSAEADDRINUSE: return PIE_ADDRINUSE; /* "Address already in use"; */
381 case WSAEADDRNOTAVAIL: return "Cannot assign requested address";
382 case WSAENETDOWN: return "Network is down";
383 case WSAENETUNREACH: return "Network is unreachable";
384 case WSAENETRESET: return "Network dropped connection on reset";
385 case WSAECONNABORTED: return "Software caused connection abort";
386 case WSAECONNRESET: return PIE_CONNRESET; /* "Connection reset by peer"; */
387 case WSAENOBUFS: return "No buffer space available";
388 case WSAEISCONN: return PIE_ISCONN; /* "Socket is already connected"; */
389 case WSAENOTCONN: return "Socket is not connected";
390 case WSAESHUTDOWN: return "Cannot send after socket shutdown";
391 case WSAETIMEDOUT: return PIE_TIMEDOUT; /* "Connection timed out"; */
392 case WSAECONNREFUSED: return PIE_CONNREFUSED; /* "Connection refused"; */
393 case WSAEHOSTDOWN: return "Host is down";
394 case WSAEHOSTUNREACH: return "No route to host";
395 case WSAEPROCLIM: return "Too many processes";
396 case WSASYSNOTREADY: return "Network subsystem is unavailable";
397 case WSAVERNOTSUPPORTED: return "Winsock.dll version out of range";
398 case WSANOTINITIALISED:
399 return "Successful WSAStartup not yet performed";
400 case WSAEDISCON: return "Graceful shutdown in progress";
401 case WSAHOST_NOT_FOUND: return PIE_HOST_NOT_FOUND; /* "Host not found"; */
402 case WSATRY_AGAIN: return "Nonauthoritative host not found";
403 case WSANO_RECOVERY: return PIE_FAIL; /* "Nonrecoverable name lookup error"; */
404 case WSANO_DATA: return "Valid name, no data record of requested type";
405 default: return "Unknown error";
406 }
407}
408
409const char *socket_gaistrerror(int err) {
410 if (err == 0) return NULL;
411 switch (err) {
412 case EAI_AGAIN: return PIE_AGAIN;
413 case EAI_BADFLAGS: return PIE_BADFLAGS;
414#ifdef EAI_BADHINTS
415 case EAI_BADHINTS: return PIE_BADHINTS;
416#endif
417 case EAI_FAIL: return PIE_FAIL;
418 case EAI_FAMILY: return PIE_FAMILY;
419 case EAI_MEMORY: return PIE_MEMORY;
420 case EAI_NONAME: return PIE_NONAME;
421#ifdef EAI_OVERFLOW
422 case EAI_OVERFLOW: return PIE_OVERFLOW;
423#endif
424#ifdef EAI_PROTOCOL
425 case EAI_PROTOCOL: return PIE_PROTOCOL;
426#endif
427 case EAI_SERVICE: return PIE_SERVICE;
428 case EAI_SOCKTYPE: return PIE_SOCKTYPE;
429#ifdef EAI_SYSTEM
430 case EAI_SYSTEM: return strerror(errno);
431#endif
432 default: return LUA_GAI_STRERROR(err);
433 }
434}
diff --git a/vendor/luasocket/src/wsocket.h b/vendor/luasocket/src/wsocket.h
new file mode 100644
index 00000000..39866402
--- /dev/null
+++ b/vendor/luasocket/src/wsocket.h
@@ -0,0 +1,33 @@
1#ifndef WSOCKET_H
2#define WSOCKET_H
3/*=========================================================================*\
4* Socket compatibilization module for Win32
5* LuaSocket toolkit
6\*=========================================================================*/
7
8/*=========================================================================*\
9* WinSock include files
10\*=========================================================================*/
11#include <winsock2.h>
12#include <ws2tcpip.h>
13
14typedef int socklen_t;
15typedef SOCKADDR_STORAGE t_sockaddr_storage;
16typedef SOCKET t_socket;
17typedef t_socket *p_socket;
18
19#ifndef IPV6_V6ONLY
20#define IPV6_V6ONLY 27
21#endif
22
23#define SOCKET_INVALID (INVALID_SOCKET)
24
25#ifndef SO_REUSEPORT
26#define SO_REUSEPORT SO_REUSEADDR
27#endif
28
29#ifndef AI_NUMERICSERV
30#define AI_NUMERICSERV (0)
31#endif
32
33#endif /* WSOCKET_H */