Merge nixio 0.2
This commit is contained in:
parent
085a0a9ec0
commit
a2b916ab73
43 changed files with 5260 additions and 336 deletions
201
libs/nixio/LICENSE
Normal file
201
libs/nixio/LICENSE
Normal file
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -1,21 +1,27 @@
|
|||
ifneq (,$(wildcard ../../build/config.mk))
|
||||
include ../../build/config.mk
|
||||
include ../../build/module.mk
|
||||
include ../../build/gccconfig.mk
|
||||
else
|
||||
include standalone.mk
|
||||
endif
|
||||
|
||||
AXTLS_VERSION = 1.2.1
|
||||
AXTLS_DIR = axTLS
|
||||
AXTLS_FILE = $(AXTLS_DIR)-$(AXTLS_VERSION).tar.gz
|
||||
NIXIO_TLS ?= openssl
|
||||
NIXIO_LDFLAGS =
|
||||
NIXIO_LDFLAGS = -lcrypt
|
||||
NIXIO_SO = nixio.so
|
||||
|
||||
NIXIO_OBJ = src/nixio.o src/socket.o src/sockopt.o src/bind.o src/address.o \
|
||||
src/poll.o src/io.o src/file.o src/splice.o src/process.o src/syslog.o \
|
||||
src/tls-context.o src/tls-socket.o
|
||||
src/bit.o src/binary.o src/fs.o src/user.o \
|
||||
src/tls-crypto.o src/tls-context.o src/tls-socket.o
|
||||
|
||||
ifeq ($(NIXIO_TLS),axtls)
|
||||
TLS_CFLAGS = -IaxTLS/ssl -IaxTLS/crypto -IaxTLS/config -include src/openssl-compat.h
|
||||
TLS_DEPENDS = src/openssl-compat.o
|
||||
NIXIO_OBJ += src/openssl-compat.o src/libaxtls.a
|
||||
TLS_CFLAGS = -IaxTLS/ssl -IaxTLS/crypto -IaxTLS/config -include src/axtls-compat.h
|
||||
TLS_DEPENDS = src/axtls-compat.o
|
||||
NIXIO_OBJ += src/axtls-compat.o src/libaxtls.a
|
||||
endif
|
||||
|
||||
ifeq ($(NIXIO_TLS),openssl)
|
||||
|
@ -27,26 +33,43 @@ ifeq ($(OS),SunOS)
|
|||
NIXIO_LDFLAGS += -lsocket -lnsl -lsendfile
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring MINGW,$(OS))$(findstring mingw,$(OS))$(findstring Windows,$(OS)))
|
||||
NIXIO_CROSS_CC:=$(shell which i586-mingw32msvc-cc)
|
||||
ifneq (,$(NIXIO_CROSS_CC))
|
||||
CC:=$(NIXIO_CROSS_CC)
|
||||
endif
|
||||
NIXIO_OBJ += src/mingw-compat.o
|
||||
NIXIO_LDFLAGS_POST:=-llua -lssl -lcrypto -lws2_32 -lgdi32
|
||||
FPIC:=
|
||||
EXTRA_CFLAGS += -D_WIN32_WINNT=0x0501
|
||||
LUA_CFLAGS:=
|
||||
NIXIO_SO:=nixio.dll
|
||||
NIXIO_LDFLAGS:=
|
||||
endif
|
||||
|
||||
|
||||
%.o: %.c
|
||||
$(COMPILE) $(NIXIO_CFLAGS) $(LUA_CFLAGS) $(FPIC) -c -o $@ $<
|
||||
|
||||
src/tls-crypto.o: $(TLS_DEPENDS) src/tls-crypto.c
|
||||
$(COMPILE) $(NIXIO_CFLAGS) $(LUA_CFLAGS) $(FPIC) $(TLS_CFLAGS) -c -o $@ src/tls-crypto.c
|
||||
|
||||
src/tls-context.o: $(TLS_DEPENDS) src/tls-context.c
|
||||
$(COMPILE) $(NIXIO_CFLAGS) $(LUA_CFLAGS) $(FPIC) $(TLS_CFLAGS) -c -o $@ src/tls-context.c
|
||||
|
||||
src/tls-socket.o: $(TLS_DEPENDS) src/tls-socket.c
|
||||
$(COMPILE) $(NIXIO_CFLAGS) $(LUA_CFLAGS) $(FPIC) $(TLS_CFLAGS) -c -o $@ src/tls-socket.c
|
||||
|
||||
src/openssl-compat.o: src/libaxtls.a src/openssl-compat.c
|
||||
$(COMPILE) $(NIXIO_CFLAGS) $(LUA_CFLAGS) $(FPIC) $(TLS_CFLAGS) -c -o $@ src/openssl-compat.c
|
||||
src/axtls-compat.o: src/libaxtls.a src/axtls-compat.c
|
||||
$(COMPILE) $(NIXIO_CFLAGS) $(LUA_CFLAGS) $(FPIC) $(TLS_CFLAGS) -c -o $@ src/axtls-compat.c
|
||||
mkdir -p dist
|
||||
cp -pR axtls-root/* dist/
|
||||
|
||||
|
||||
compile: $(NIXIO_OBJ)
|
||||
$(LINK) $(SHLIB_FLAGS) $(NIXIO_LDFLAGS) -o src/nixio.so $(NIXIO_OBJ)
|
||||
$(LINK) $(SHLIB_FLAGS) $(NIXIO_LDFLAGS) -o src/$(NIXIO_SO) $(NIXIO_OBJ) $(NIXIO_LDFLAGS_POST)
|
||||
mkdir -p dist$(LUA_LIBRARYDIR)
|
||||
cp src/nixio.so dist$(LUA_LIBRARYDIR)/nixio.so
|
||||
cp src/$(NIXIO_SO) dist$(LUA_LIBRARYDIR)/$(NIXIO_SO)
|
||||
|
||||
$(AXTLS_DIR)/.prepared:
|
||||
#rm -rf $(AXTLS_DIR)
|
||||
|
@ -55,9 +78,13 @@ $(AXTLS_DIR)/.prepared:
|
|||
touch $@
|
||||
|
||||
src/libaxtls.a: $(AXTLS_DIR)/.prepared
|
||||
$(MAKE) -C $(AXTLS_DIR) CC=$(CC) CFLAGS="$(CFLAGS) $(EXTRA_CFLAGS) $(FPIC) '-Dalloca(size)=__builtin_alloca(size)' -Wall -pedantic -I../config -I../ssl -I../crypto" LDFLAGS="$(LDFLAGS)" OS="$(OS)" clean all
|
||||
$(MAKE) -C $(AXTLS_DIR) CC=$(CC) CFLAGS="$(CFLAGS) $(EXTRA_CFLAGS) $(FPIC) -Wall -pedantic -I../config -I../ssl -I../crypto" LDFLAGS="$(LDFLAGS)" OS="$(OS)" clean all
|
||||
cp -p $(AXTLS_DIR)/_stage/libaxtls.a src
|
||||
|
||||
clean: luaclean
|
||||
rm -f src/*.o src/*.so src/*.a
|
||||
rm -f src/*.o src/*.so src/*.a src/*.dll
|
||||
rm -f $(AXTLS_DIR)/.prepared
|
||||
|
||||
install: build
|
||||
cp -pR dist$(LUA_MODULEDIR)/* $(LUA_MODULEDIR)
|
||||
cp -pR dist$(LUA_LIBRARYDIR)/* $(LUA_LIBRARYDIR)
|
||||
|
|
10
libs/nixio/NOTICE
Normal file
10
libs/nixio/NOTICE
Normal file
|
@ -0,0 +1,10 @@
|
|||
nixio - Linux I/O library for lua
|
||||
Copyright 2009 Steven Barth <steven@midlink.org>
|
||||
Licensed under the Apache License, Version 2.0.
|
||||
|
||||
Contains code from:
|
||||
axTLS - Copyright 2008 Cameron Rich
|
||||
|
||||
Thanks for testing, feedback and code snippets:
|
||||
John Crispin <blogic@openwrt.org>
|
||||
Jo-Philipp Wich <xm@leipzig.freifunk.net>
|
|
@ -1,7 +1,13 @@
|
|||
Building:
|
||||
Use GNU Make.
|
||||
make or gmake depending on your system.
|
||||
|
||||
With axTLS (standard):
|
||||
make
|
||||
Special make flags:
|
||||
|
||||
With OpenSSL:
|
||||
make NIXIO_TLS=openssl
|
||||
OS Override Target OS [Linux|FreeBSD|SunOS|Windows]
|
||||
NIXIO_TLS TLS-Library [*openssl|axtls]
|
||||
NIXIO_CROSS_CC MinGW CC (Windows) `which i586-mingw32msvc-cc`
|
||||
LUA_CFLAGS Lua CFLAGS `pkg-config --cflags lua5.1`
|
||||
LUA_TARGET Lua compile target [*source|strip|compile]
|
||||
LUA_MODULEDIR Install LUA_PATH "/usr/share/lua/5.1"
|
||||
LUA_LIBRARYDIR Install LUA_CPATH "/usr/lib/lua/5.1"
|
||||
|
|
98
libs/nixio/docsrc/README.lua
Normal file
98
libs/nixio/docsrc/README.lua
Normal file
|
@ -0,0 +1,98 @@
|
|||
--- General Information.
|
||||
module "README"
|
||||
|
||||
--- General error handling information.
|
||||
-- <ul>
|
||||
-- <li> Most of the functions available in this library may fail. If any error
|
||||
-- occurs the function returns <strong>nil or false</strong>, an error code
|
||||
-- (usually errno) and an additional error message text (if avaialable).</li>
|
||||
-- <li>At the moment false is only returned when a non-blocking I/O function
|
||||
-- fails with EAGAIN, EWOULDBLOCK or WSAEWOULDBLOCK for any others nil is
|
||||
-- returned as first parameter. Therefore you can use false to write portable
|
||||
-- non-blocking I/O applications.</li>
|
||||
-- <li>Note that the function documentation does only mention the return values
|
||||
-- in case of a successful operation.</li>
|
||||
-- <li>You can find a table of common error numbers and other useful constants
|
||||
-- like signal numbers in <strong>nixio.const</strong> e.g. nixio.const.EINVAL,
|
||||
-- nixio.const.SIGTERM, etc. For portability there is a second error constant
|
||||
-- table <strong>nixio.const_sock</strong> for socket error codes. This might
|
||||
-- be important if you are dealing with Windows applications, on POSIX however
|
||||
-- const_sock is just an alias for const.</li>
|
||||
-- <li>With some exceptions - which are explicitely stated in the function
|
||||
-- documentation - all blocking functions are signal-protected and will not fail
|
||||
-- with EINTR.</li>
|
||||
-- <li>On POSIX the SIGPIPE signal will be set to ignore upon initialization.
|
||||
-- You should restore the default behaviour or set a custom signal handler
|
||||
-- in your program after loading nixio if you need this behaviour.</li>
|
||||
-- </ul>
|
||||
-- @class table
|
||||
-- @name Errorhandling
|
||||
-- @return !
|
||||
|
||||
--- Function conventions.
|
||||
-- <br />In general all functions are namend and behave like their POSIX API
|
||||
-- counterparts - where applicable - applying the following rules:
|
||||
-- <ul>
|
||||
-- <li>Functions should be named like the underlying POSIX API function ommiting
|
||||
-- prefixes or suffixes - especially when placed in an object-context (
|
||||
-- lockf -> File:lock, fsync -> File:sync, dup2 -> dup, ...)</li>
|
||||
-- <li>If you are unclear about the behaviour of a function you should consult
|
||||
-- your OS API documentation (e.g. the manpages).</li>
|
||||
-- <li>If the name is significantly different from the POSIX-function, the
|
||||
-- underlying function(s) are stated in the documentation.</li>
|
||||
-- <li>Parameters should reflect those of the C-API, buffer length arguments and
|
||||
-- by-reference parameters should be ommitted for pratical purposes.</li>
|
||||
-- <li>If a C function accepts a bitfield as parameter, it should be translated
|
||||
-- into lower case string flags representing the flags if the bitfield is the
|
||||
-- last parameter and also ommiting prefixes or suffixes. (e.g. waitpid
|
||||
-- (pid, &s, WNOHANG | WUNTRACED) -> waitpid(pid, "nohang", "untraced"),
|
||||
-- getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) ->
|
||||
-- Socket:getopt("socket", "reuseaddr"), etc.) </li>
|
||||
-- <li>If it is not applicable to provide a string representation of the
|
||||
-- bitfield a bitfield generator helper is provided. It is named FUNCTION_flags.
|
||||
-- (open("/tmp/test", O_RDONLY | O_NONBLOCK) -> open("/tmp/test", open_flags(
|
||||
-- "rdonly", "nonblock")))</li>
|
||||
-- </ul>
|
||||
-- @class table
|
||||
-- @name Functions
|
||||
-- @return !
|
||||
|
||||
--- Platform information.
|
||||
-- <ul>
|
||||
-- <li>The minimum platform requirements are a decent POSIX 2001 support.
|
||||
-- Builds are more or less tested on Linux, Solaris and FreeBSD. Builds for
|
||||
-- Windows XP SP1 and later can be compiled with MinGW either from Windows
|
||||
-- itself or using the MinGW cross-compiler. Earlier versions of Windows are not
|
||||
-- supported.</li>
|
||||
-- <li>In general all functions which don't have any remarks
|
||||
-- in their documentation are available on all platforms.</li>
|
||||
-- <li>Functions with a (POSIX), (Linux) or similar prefix are only available
|
||||
-- on these specific platforms. Same appplies to parameters of functions
|
||||
-- with a similar suffix.</li>
|
||||
-- <li>Some functions might have limitations on some platforms. This should
|
||||
-- be stated in the documentation. Please also consult your OS API
|
||||
-- documentation.</li>
|
||||
-- </ul>
|
||||
-- @usage Tes
|
||||
-- @class table
|
||||
-- @name Platforms
|
||||
-- @return !
|
||||
|
||||
--- Cryptography and TLS libraries.
|
||||
-- <ul>
|
||||
-- <li>Currently 2 underlying cryptography libraries are supported: openssl and
|
||||
-- axTLS. The name of the library in use is written to
|
||||
-- <strong>nixio.tls_provider</strong></li>
|
||||
-- <li>You should whenever possible use openssl as axTLS has only limited
|
||||
-- support. It does not provide support for non-blocking sockets and
|
||||
-- is probably less audited than openssl.</li>
|
||||
-- <li>However in embedded development if you don't need openssl anyway
|
||||
-- you may safe an essential amount of flash space (about 1 MB for the openssl
|
||||
-- library) by choosing axTLS over openssl.</li>
|
||||
-- <li>As the supported Windows versions are not suitable for embedded devices
|
||||
-- axTLS is at the moment not supported on Windows.</li>
|
||||
-- </ul>
|
||||
-- @usage Tes
|
||||
-- @class table
|
||||
-- @name TLS-Crypto
|
||||
-- @return !
|
17
libs/nixio/docsrc/nixio.CryptoHash.lua
Normal file
17
libs/nixio/docsrc/nixio.CryptoHash.lua
Normal file
|
@ -0,0 +1,17 @@
|
|||
--- Cryptographical Hash and HMAC object.
|
||||
-- @cstyle instance
|
||||
module "nixio.CryptoHash"
|
||||
|
||||
--- Add another chunk of data to be hashed.
|
||||
-- @class function
|
||||
-- @name CryptoHash.update
|
||||
-- @param chunk Chunk of data
|
||||
-- @return CryptoHash object (self)
|
||||
|
||||
--- Finalize the hash and return the digest.
|
||||
-- @class function
|
||||
-- @name CryptoHash.final
|
||||
-- @usage You cannot call update on a hash object that was already finalized
|
||||
-- you can however call final multiple times to get the digest.
|
||||
-- @return hexdigest
|
||||
-- @return buffer containing binary digest
|
109
libs/nixio/docsrc/nixio.File.lua
Normal file
109
libs/nixio/docsrc/nixio.File.lua
Normal file
|
@ -0,0 +1,109 @@
|
|||
--- Large File Object.
|
||||
-- Large file operations are supported up to 52 bits if the Lua number type is
|
||||
-- double (default).
|
||||
-- @cstyle instance
|
||||
module "nixio.File"
|
||||
|
||||
--- Write to the file descriptor.
|
||||
-- @class function
|
||||
-- @name File.write
|
||||
-- @usage <strong>Warning:</strong> It is not guaranteed that all data
|
||||
-- in the buffer is written at once especially when dealing with pipes.
|
||||
-- You have to check the return value - the number of bytes actually written -
|
||||
-- or use the safe IO functions in the high-level IO utility module.
|
||||
-- @usage Unlike standard Lua indexing the lowest offset and default is 0.
|
||||
-- @param buffer Buffer holding the data to be written.
|
||||
-- @param offset Offset to start reading the buffer from. (optional)
|
||||
-- @param length Length of chunk to read from the buffer. (optional)
|
||||
-- @return number of bytes written
|
||||
|
||||
--- Read from a file descriptor.
|
||||
-- @class function
|
||||
-- @name File.read
|
||||
-- @usage <strong>Warning:</strong> It is not guaranteed that all requested data
|
||||
-- is read at once especially when dealing with pipes.
|
||||
-- You have to check the return value - the length of the buffer actually read -
|
||||
-- or use the safe IO functions in the high-level IO utility module.
|
||||
-- @usage The length of the return buffer is limited by the (compile time)
|
||||
-- nixio buffersize which is <em>nixio.const.buffersize</em> (8192 by default).
|
||||
-- Any read request greater than that will be safely truncated to this value.
|
||||
-- @param length Amount of data to read (in Bytes).
|
||||
-- @return buffer containing data successfully read
|
||||
|
||||
--- Reposition read / write offset of the file descriptor.
|
||||
-- The seek will be done either from the beginning of the file or relative
|
||||
-- to the current position or relative to the end.
|
||||
-- @class function
|
||||
-- @name File.seek
|
||||
-- @usage This function calls lseek().
|
||||
-- @param offset File Offset
|
||||
-- @param whence Starting point [<strong>"set"</strong>, "cur", "end"]
|
||||
-- @return new (absolute) offset position
|
||||
|
||||
--- Return the current read / write offset of the file descriptor.
|
||||
-- @class function
|
||||
-- @name File.tell
|
||||
-- @usage This function calls lseek() with offset 0 from the current position.
|
||||
-- @return offset position
|
||||
|
||||
--- Synchronizes the file with the storage device.
|
||||
-- Returns when the file is successfully written to the disk.
|
||||
-- @class function
|
||||
-- @name File.sync
|
||||
-- @usage This function calls fsync() when data_only equals false
|
||||
-- otherwise fdatasync(), on Windows _commit() is used instead.
|
||||
-- @usage fdatasync() is only supported by Linux and Solaris. For other systems
|
||||
-- the <em>data_only</em> parameter is ignored and fsync() is always called.
|
||||
-- @param data_only Do not synchronize the metadata. (optional, boolean)
|
||||
-- @return true
|
||||
|
||||
--- Apply or test a lock on the file.
|
||||
-- @class function
|
||||
-- @name File.lock
|
||||
-- @usage This function calls lockf() on POSIX and _locking() on Windows.
|
||||
-- @usage The "lock" command is blocking, "tlock" is non-blocking,
|
||||
-- "ulock" unlocks and "test" only tests for the lock.
|
||||
-- @usage The "test" command is not available on Windows.
|
||||
-- @usage Locks are by default advisory on POSIX, but mandatory on Windows.
|
||||
-- @param command Locking Command ["lock", "tlock", "ulock", "test"]
|
||||
-- @param length Amount of Bytes to lock from current offset (optional)
|
||||
-- @return true
|
||||
|
||||
--- Get file status and attributes.
|
||||
-- @class function
|
||||
-- @name File.stat
|
||||
-- @param field Only return a specific field, not the whole table (optional)
|
||||
-- @usage This function calls fstat().
|
||||
-- @return Table containing: <ul>
|
||||
-- <li>atime = Last access timestamp</li>
|
||||
-- <li>blksize = Blocksize (POSIX only)</li>
|
||||
-- <li>blocks = Blocks used (POSIX only)</li>
|
||||
-- <li>ctime = Creation timestamp</li>
|
||||
-- <li>dev = Device ID</li>
|
||||
-- <li>gid = Group ID</li>
|
||||
-- <li>ino = Inode</li>
|
||||
-- <li>modedec = Mode converted into a decimal number</li>
|
||||
-- <li>modestr = Mode as string as returned by `ls -l`</li>
|
||||
-- <li>mtime = Last modification timestamp</li>
|
||||
-- <li>nlink = Number of links</li>
|
||||
-- <li>rdev = Device ID (if special file)</li>
|
||||
-- <li>size = Size in bytes</li>
|
||||
-- <li>type = ["reg", "dir", "chr", "blk", "fifo", "lnk", "sock"]</li>
|
||||
-- <li>uid = User ID</li>
|
||||
-- </ul>
|
||||
|
||||
--- Close the file descriptor.
|
||||
-- @class function
|
||||
-- @name File.close
|
||||
-- @return true
|
||||
|
||||
--- Get the number of the filedescriptor.
|
||||
-- @class function
|
||||
-- @name File.fileno
|
||||
-- @return file descriptor number
|
||||
|
||||
--- (POSIX) Set the blocking mode of the file descriptor.
|
||||
-- @class function
|
||||
-- @name File.setblocking
|
||||
-- @param blocking (boolean)
|
||||
-- @return true
|
170
libs/nixio/docsrc/nixio.Socket.lua
Normal file
170
libs/nixio/docsrc/nixio.Socket.lua
Normal file
|
@ -0,0 +1,170 @@
|
|||
--- Socket Object.
|
||||
-- Supports IPv4, IPv6 and UNIX (POSIX only) families.
|
||||
-- @cstyle instance
|
||||
module "nixio.Socket"
|
||||
|
||||
--- Get the local address of a socket.
|
||||
-- @class function
|
||||
-- @name Socket.getsockname
|
||||
-- @return IP-Address
|
||||
-- @return Port
|
||||
|
||||
--- Get the peer address of a socket.
|
||||
-- @class function
|
||||
-- @name Socket.getpeername
|
||||
-- @return IP-Address
|
||||
-- @return Port
|
||||
|
||||
--- Bind the socket to a network address.
|
||||
-- @class function
|
||||
-- @name Socket.bind
|
||||
-- @usage This function calls getaddrinfo() and bind() but NOT listen().
|
||||
-- @usage If <em>host</em> is a domain name it will be looked up and bind()
|
||||
-- tries the IP-Addresses in the order returned by the DNS resolver
|
||||
-- until the bind succeeds.
|
||||
-- @usage UNIX sockets ignore the <em>port</em>,
|
||||
-- and interpret <em>host</em> as a socket path.
|
||||
-- @param host Host (optional, default: all addresses)
|
||||
-- @param port Port or service description
|
||||
-- @return true
|
||||
|
||||
--- Connect the socket to a network address.
|
||||
-- @class function
|
||||
-- @name Socket.connect
|
||||
-- @usage This function calls getaddrinfo() and connect().
|
||||
-- @usage If <em>host</em> is a domain name it will be looked up and connect()
|
||||
-- tries the IP-Addresses in the order returned by the DNS resolver
|
||||
-- until the connect succeeds.
|
||||
-- @usage UNIX sockets ignore the <em>port</em>,
|
||||
-- and interpret <em>host</em> as a socket path.
|
||||
-- @param host Hostname or IP-Address (optional, default: localhost)
|
||||
-- @param port Port or service description
|
||||
-- @return true
|
||||
|
||||
--- Listen for connections on the socket.
|
||||
-- @class function
|
||||
-- @name Socket.listen
|
||||
-- @param backlog Length of queue for pending connections
|
||||
-- @return true
|
||||
|
||||
--- Accept a connection on the socket.
|
||||
-- @class function
|
||||
-- @name Socket.accept
|
||||
-- @return Socket Object
|
||||
-- @return Peer IP-Address
|
||||
-- @return Peer Port
|
||||
|
||||
--- Send a message on the socket specifying the destination.
|
||||
-- @class function
|
||||
-- @name Socket.sendto
|
||||
-- @usage <strong>Warning:</strong> It is not guaranteed that all data
|
||||
-- in the buffer is written at once.
|
||||
-- You have to check the return value - the number of bytes actually written -
|
||||
-- or use the safe IO functions in the high-level IO utility module.
|
||||
-- @usage Unlike standard Lua indexing the lowest offset and default is 0.
|
||||
-- @param buffer Buffer holding the data to be written.
|
||||
-- @param host Target IP-Address
|
||||
-- @param port Target Port
|
||||
-- @param offset Offset to start reading the buffer from. (optional)
|
||||
-- @param length Length of chunk to read from the buffer. (optional)
|
||||
-- @return number of bytes written
|
||||
|
||||
--- Send a message on the socket.
|
||||
-- This function is identical to sendto except for the missing destination
|
||||
-- paramters. See the sendto description for a detailed description.
|
||||
-- @class function
|
||||
-- @name Socket.send
|
||||
-- @param buffer Buffer holding the data to be written.
|
||||
-- @param offset Offset to start reading the buffer from. (optional)
|
||||
-- @param length Length of chunk to read from the buffer. (optional)
|
||||
-- @see Socket.sendto
|
||||
-- @return number of bytes written
|
||||
|
||||
--- Send a message on the socket (This is an alias for send).
|
||||
-- See the sendto description for a detailed description.
|
||||
-- @class function
|
||||
-- @name Socket.write
|
||||
-- @param buffer Buffer holding the data to be written.
|
||||
-- @param offset Offset to start reading the buffer from. (optional)
|
||||
-- @param length Length of chunk to read from the buffer. (optional)
|
||||
-- @see Socket.sendto
|
||||
-- @return number of bytes written
|
||||
|
||||
--- Receive a message on the socket including the senders source address.
|
||||
-- @class function
|
||||
-- @name Socket.recvfrom
|
||||
-- @usage <strong>Warning:</strong> It is not guaranteed that all requested data
|
||||
-- is read at once.
|
||||
-- You have to check the return value - the length of the buffer actually read -
|
||||
-- or use the safe IO functions in the high-level IO utility module.
|
||||
-- @usage The length of the return buffer is limited by the (compile time)
|
||||
-- nixio buffersize which is <em>nixio.const.buffersize</em> (8192 by default).
|
||||
-- Any read request greater than that will be safely truncated to this value.
|
||||
-- @param length Amount of data to read (in Bytes).
|
||||
-- @return buffer containing data successfully read
|
||||
-- @return host IP-Address of the sender
|
||||
-- @return port Port of the sender
|
||||
|
||||
--- Receive a message on the socket.
|
||||
-- This function is identical to recvfrom except that it does not return
|
||||
-- the sender's source address. See the recvfrom description for more details.
|
||||
-- @class function
|
||||
-- @name Socket.recv
|
||||
-- @param length Amount of data to read (in Bytes).
|
||||
-- @see Socket.recvfrom
|
||||
-- @return buffer containing data successfully read
|
||||
|
||||
--- Receive a message on the socket (This is an alias for recv).
|
||||
-- See the recvfrom description for more details.
|
||||
-- @class function
|
||||
-- @name Socket.read
|
||||
-- @param length Amount of data to read (in Bytes).
|
||||
-- @see Socket.recvfrom
|
||||
-- @return buffer containing data successfully read
|
||||
|
||||
--- Close the socket.
|
||||
-- @class function
|
||||
-- @name Socket.close
|
||||
-- @return true
|
||||
|
||||
--- Shut down part of a full-duplex connection.
|
||||
-- @class function
|
||||
-- @name Socket.shutdown
|
||||
-- @param how (optional, default: rdwr) ["rdwr", "rd", "wr"]
|
||||
-- @return true
|
||||
|
||||
--- Get the number of the filedescriptor.
|
||||
-- @class function
|
||||
-- @name Socket.fileno
|
||||
-- @return file descriptor number
|
||||
|
||||
--- Set the blocking mode of the socket.
|
||||
-- @class function
|
||||
-- @name Socket.setblocking
|
||||
-- @param blocking (boolean)
|
||||
-- @return true
|
||||
|
||||
--- Set a socket option.
|
||||
-- @class function
|
||||
-- @name Socket.setopt
|
||||
-- @param level Level ["socket", "tcp", "ip", "ipv6"]
|
||||
-- @param option Option ["keepalive", "reuseaddr", "sndbuf", "rcvbuf",
|
||||
-- "priority", "broadcast", "linger", "sndtimeo", "rcvtimeo", "dontroute",
|
||||
-- "bindtodevice", "error", "oobinline", "cork" (TCP), "nodelay" (TCP),
|
||||
-- "mtu" (IP, IPv6), "hdrincl" (IP), "multicast_ttl" (IP), "multicast_loop"
|
||||
-- (IP, IPv6), "multicast_if" (IP, IPv6), "v6only" (IPv6), "multicast_hops"
|
||||
-- (IPv6), "add_membership" (IP, IPv6), "drop_membership" (IP, IPv6)]
|
||||
-- @param value Value
|
||||
-- @return true
|
||||
|
||||
--- Get a socket option.
|
||||
-- @class function
|
||||
-- @name Socket.getopt
|
||||
-- @param level Level ["socket", "tcp", "ip", "ipv6"]
|
||||
-- @param option Option ["keepalive", "reuseaddr", "sndbuf", "rcvbuf",
|
||||
-- "priority", "broadcast", "linger", "sndtimeo", "rcvtimeo", "dontroute",
|
||||
-- "bindtodevice", "error", "oobinline", "cork" (TCP), "nodelay" (TCP),
|
||||
-- "mtu" (IP, IPv6), "hdrincl" (IP), "multicast_ttl" (IP), "multicast_loop"
|
||||
-- (IP, IPv6), "multicast_if" (IP, IPv6), "v6only" (IPv6), "multicast_hops"
|
||||
-- (IPv6), "add_membership" (IP, IPv6), "drop_membership" (IP, IPv6)]
|
||||
-- @return Value
|
46
libs/nixio/docsrc/nixio.TLSContext.lua
Normal file
46
libs/nixio/docsrc/nixio.TLSContext.lua
Normal file
|
@ -0,0 +1,46 @@
|
|||
--- Transport Layer Security Context Object.
|
||||
-- @cstyle instance
|
||||
module "nixio.TLSContext"
|
||||
|
||||
--- Create a TLS Socket from a socket descriptor.
|
||||
-- @class function
|
||||
-- @name TLSContext.create
|
||||
-- @param socket Socket Object
|
||||
-- @return TLSSocket Object
|
||||
|
||||
--- Assign a PEM certificate to this context.
|
||||
-- @class function
|
||||
-- @name TLSContext.set_cert
|
||||
-- @usage This function calls SSL_CTX_use_certificate_chain_file().
|
||||
-- @param path Certificate File path
|
||||
-- @return true
|
||||
|
||||
--- Assign a PEM private key to this context.
|
||||
-- @class function
|
||||
-- @name TLSContext.set_key
|
||||
-- @usage This function calls SSL_CTX_use_PrivateKey_file().
|
||||
-- @param path Private Key File path
|
||||
-- @return true
|
||||
|
||||
--- Set the available ciphers for this context.
|
||||
-- @class function
|
||||
-- @name TLSContext.set_ciphers
|
||||
-- @usage This function calls SSL_CTX_set_cipher_list().
|
||||
-- @param cipherlist String containing a list of ciphers
|
||||
-- @return true
|
||||
|
||||
--- Set the verification depth of this context.
|
||||
-- @class function
|
||||
-- @name TLSContext.set_verify_depth
|
||||
-- @usage This function calls SSL_CTX_set_verify_depth().
|
||||
-- @param depth Depth
|
||||
-- @return true
|
||||
|
||||
--- Set the verification flags of this context.
|
||||
-- @class function
|
||||
-- @name TLSContext.set_verify
|
||||
-- @usage This function calls SSL_CTX_set_verify().
|
||||
-- @param flag1 First Flag ["none", "peer", "verify_fail_if_no_peer_cert",
|
||||
-- "client_once"]
|
||||
-- @param ... More Flags [-"-]
|
||||
-- @return true
|
73
libs/nixio/docsrc/nixio.TLSSocket.lua
Normal file
73
libs/nixio/docsrc/nixio.TLSSocket.lua
Normal file
|
@ -0,0 +1,73 @@
|
|||
--- TLS Socket Object.
|
||||
-- TLS Sockets contain the underlying socket and context in the fields
|
||||
-- "socket" and "context".
|
||||
-- @cstyle instance
|
||||
module "nixio.TLSSocket"
|
||||
|
||||
--- Initiate the TLS handshake as client with the server.
|
||||
-- @class function
|
||||
-- @name TLSSocket.connect
|
||||
-- @usage This function calls SSL_connect().
|
||||
-- @usage You have to call either connect or accept before transmitting data.
|
||||
-- @see TLSSocket.accept
|
||||
-- @return true
|
||||
|
||||
--- Wait for a TLS handshake from a client.
|
||||
-- @class function
|
||||
-- @name TLSSocket.accept
|
||||
-- @usage This function calls SSL_accept().
|
||||
-- @usage You have to call either connect or accept before transmitting data.
|
||||
-- @see TLSSocket.connect
|
||||
-- @return true
|
||||
|
||||
--- Send a message to the socket.
|
||||
-- @class function
|
||||
-- @name TLSSocket.send
|
||||
-- @usage This function calls SSL_write().
|
||||
-- @usage <strong>Warning:</strong> It is not guaranteed that all data
|
||||
-- in the buffer is written at once.
|
||||
-- You have to check the return value - the number of bytes actually written -
|
||||
-- or use the safe IO functions in the high-level IO utility module.
|
||||
-- @usage Unlike standard Lua indexing the lowest offset and default is 0.
|
||||
-- @param buffer Buffer holding the data to be written.
|
||||
-- @param offset Offset to start reading the buffer from. (optional)
|
||||
-- @param length Length of chunk to read from the buffer. (optional)
|
||||
-- @return number of bytes written
|
||||
|
||||
--- Send a message on the socket (This is an alias for send).
|
||||
-- See the send description for a detailed description.
|
||||
-- @class function
|
||||
-- @name TLSSocket.write
|
||||
-- @param buffer Buffer holding the data to be written.
|
||||
-- @param offset Offset to start reading the buffer from. (optional)
|
||||
-- @param length Length of chunk to read from the buffer. (optional)
|
||||
-- @see TLSSocket.send
|
||||
-- @return number of bytes written
|
||||
|
||||
--- Receive a message on the socket.
|
||||
-- @class function
|
||||
-- @name TLSSocket.recv
|
||||
-- @usage This function calls SSL_read().
|
||||
-- @usage <strong>Warning:</strong> It is not guaranteed that all requested data
|
||||
-- is read at once.
|
||||
-- You have to check the return value - the length of the buffer actually read -
|
||||
-- or use the safe IO functions in the high-level IO utility module.
|
||||
-- @usage The length of the return buffer is limited by the (compile time)
|
||||
-- nixio buffersize which is <em>nixio.const.buffersize</em> (8192 by default).
|
||||
-- Any read request greater than that will be safely truncated to this value.
|
||||
-- @param length Amount of data to read (in Bytes).
|
||||
-- @return buffer containing data successfully read
|
||||
|
||||
--- Receive a message on the socket (This is an alias for recv).
|
||||
-- See the recv description for more details.
|
||||
-- @class function
|
||||
-- @name TLSSocket.read
|
||||
-- @param length Amount of data to read (in Bytes).
|
||||
-- @see TLSSocket.recv
|
||||
-- @return buffer containing data successfully read
|
||||
|
||||
--- Shut down the TLS connection.
|
||||
-- @class function
|
||||
-- @name TLSSocket.shutdown
|
||||
-- @usage This function calls SSL_shutdown().
|
||||
-- @return true
|
130
libs/nixio/docsrc/nixio.UnifiedIO.lua
Normal file
130
libs/nixio/docsrc/nixio.UnifiedIO.lua
Normal file
|
@ -0,0 +1,130 @@
|
|||
--- Unified high-level I/O utility API for Files, Sockets and TLS-Sockets.
|
||||
-- These functions are added to the object function tables by doing <strong>
|
||||
-- require "nixio.util"</strong>, can be used on all nixio IO Descriptors and
|
||||
-- are based on the shared low-level read() and write() functions.
|
||||
-- @cstyle instance
|
||||
module "nixio.UnifiedIO"
|
||||
|
||||
--- Test whether the I/O-Descriptor is a socket.
|
||||
-- @class function
|
||||
-- @name UnifiedIO.is_socket
|
||||
-- @return boolean
|
||||
|
||||
--- Test whether the I/O-Descriptor is a TLS socket.
|
||||
-- @class function
|
||||
-- @name UnifiedIO.is_tls_socket
|
||||
-- @return boolean
|
||||
|
||||
--- Test whether the I/O-Descriptor is a file.
|
||||
-- @class function
|
||||
-- @name UnifiedIO.is_file
|
||||
-- @return boolean
|
||||
|
||||
--- Read a block of data and wait until all data is available.
|
||||
-- @class function
|
||||
-- @name UnifiedIO.readall
|
||||
-- @usage This function uses the low-level read function of the descriptor.
|
||||
-- @usage If the length parameter is ommited, this function returns all data
|
||||
-- that can be read before an end-of-file, end-of-stream, connection shutdown
|
||||
-- or similar happens.
|
||||
-- @usage If the descriptor is non-blocking this function may fail with EAGAIN.
|
||||
-- @param length Bytes to read (optional)
|
||||
-- @return data that was successfully read if no error occured
|
||||
-- @return - reserved for error code -
|
||||
-- @return - reserved for error message -
|
||||
-- @return data that was successfully read even if an error occured
|
||||
|
||||
--- Write a block of data and wait until all data is written.
|
||||
-- @class function
|
||||
-- @name UnifiedIO.writeall
|
||||
-- @usage This function uses the low-level write function of the descriptor.
|
||||
-- @usage If the descriptor is non-blocking this function may fail with EAGAIN.
|
||||
-- @param block Bytes to write
|
||||
-- @return bytes that were successfully written if no error occured
|
||||
-- @return - reserved for error code -
|
||||
-- @return - reserved for error message -
|
||||
-- @return bytes that were successfully written even if an error occured
|
||||
|
||||
--- Create a line-based iterator.
|
||||
-- Lines may end with either \n or \r\n, these control chars are not included
|
||||
-- in the return value.
|
||||
-- @class function
|
||||
-- @name UnifiedIO.linesource
|
||||
-- @usage This function uses the low-level read function of the descriptor.
|
||||
-- @usage <strong>Note:</strong> This function uses an internal buffer to read
|
||||
-- ahead. Do NOT mix calls to read(all) and the returned iterator. If you want
|
||||
-- to stop reading line-based and want to use the read(all) functions instead
|
||||
-- you can pass "true" to the iterator which will flush the buffer
|
||||
-- and return the bufferd data.
|
||||
-- @usage If the limit parameter is ommited, this function uses the nixio
|
||||
-- buffersize (8192B by default).
|
||||
-- @usage If the descriptor is non-blocking the iterator may fail with EAGAIN.
|
||||
-- @usage The iterator can be used as an LTN12 source.
|
||||
-- @param limit Line limit
|
||||
-- @return Line-based Iterator
|
||||
|
||||
--- Create a block-based iterator.
|
||||
-- @class function
|
||||
-- @name UnifiedIO.blocksource
|
||||
-- @usage This function uses the low-level read function of the descriptor.
|
||||
-- @usage The blocksize given is only advisory and to be seen as an upper limit,
|
||||
-- if an underlying read returns less bytes the chunk is nevertheless returned.
|
||||
-- @usage If the limit parameter is ommited, the iterator returns data
|
||||
-- until an end-of-file, end-of-stream, connection shutdown or similar happens.
|
||||
-- @usage The iterator will not buffer so it is safe to mix with calls to read.
|
||||
-- @usage If the descriptor is non-blocking the iterator may fail with EAGAIN.
|
||||
-- @usage The iterator can be used as an LTN12 source.
|
||||
-- @param blocksize Advisory blocksize (optional)
|
||||
-- @param limit Amount of data to consume (optional)
|
||||
-- @return Block-based Iterator
|
||||
|
||||
--- Create a sink.
|
||||
-- This sink will simply write all data that it receives and optionally
|
||||
-- close the descriptor afterwards.
|
||||
-- @class function
|
||||
-- @name UnifiedIO.sink
|
||||
-- @usage This function uses the writeall function of the descriptor.
|
||||
-- @usage If the descriptor is non-blocking the sink may fail with EAGAIN.
|
||||
-- @usage The iterator can be used as an LTN12 sink.
|
||||
-- @param close_when_done (optional, boolean)
|
||||
-- @return Sink
|
||||
|
||||
--- Copy data from the current descriptor to another one.
|
||||
-- @class function
|
||||
-- @name UnifiedIO.copy
|
||||
-- @usage This function uses the blocksource function of the source descriptor
|
||||
-- and the sink function of the target descriptor.
|
||||
-- @usage If the limit parameter is ommited, data is copied
|
||||
-- until an end-of-file, end-of-stream, connection shutdown or similar happens.
|
||||
-- @usage If the descriptor is non-blocking the function may fail with EAGAIN.
|
||||
-- @param fdout Target Descriptor
|
||||
-- @param size Bytes to copy (optional)
|
||||
-- @return bytes that were successfully written if no error occured
|
||||
-- @return - reserved for error code -
|
||||
-- @return - reserved for error message -
|
||||
-- @return bytes that were successfully written even if an error occured
|
||||
|
||||
--- Copy data from the current descriptor to another one using kernel-space
|
||||
-- copying if possible.
|
||||
-- @class function
|
||||
-- @name UnifiedIO.copyz
|
||||
-- @usage This function uses the sendfile() syscall to copy the data or the
|
||||
-- blocksource function of the source descriptor and the sink function
|
||||
-- of the target descriptor as a fallback mechanism.
|
||||
-- @usage Support for splice() on Linux is not implemented yet.
|
||||
-- @usage If the limit parameter is ommited, data is copied
|
||||
-- until an end-of-file, end-of-stream, connection shutdown or similar happens.
|
||||
-- @usage If the descriptor is non-blocking the function may fail with EAGAIN.
|
||||
-- @param fdout Target Descriptor
|
||||
-- @param size Bytes to copy (optional)
|
||||
-- @return bytes that were successfully written if no error occured
|
||||
-- @return - reserved for error code -
|
||||
-- @return - reserved for error message -
|
||||
-- @return bytes that were successfully written even if an error occured
|
||||
|
||||
--- Close the descriptor.
|
||||
-- @class function
|
||||
-- @name UnifiedIO.close
|
||||
-- @usage If the descriptor is a TLS-socket the underlying descriptor is
|
||||
-- closed without touching the TLS connection.
|
||||
-- @return true
|
33
libs/nixio/docsrc/nixio.bin.lua
Normal file
33
libs/nixio/docsrc/nixio.bin.lua
Normal file
|
@ -0,0 +1,33 @@
|
|||
--- Binary operations and conversion.
|
||||
module "nixio.bin"
|
||||
|
||||
--- Return a hexadecimal ASCII represantation of the content of a buffer.
|
||||
-- @class function
|
||||
-- @name hexlify
|
||||
-- @param buffer Buffer
|
||||
-- @return representation using characters [0-9a-f]
|
||||
|
||||
--- Return a binary buffer from a hexadecimal ASCII representation.
|
||||
-- @class function
|
||||
-- @name unhexlify
|
||||
-- @param hexvalue representation using characters [0-9a-f]
|
||||
-- @return binary data
|
||||
|
||||
--- Calculate the CRC32 value of a buffer.
|
||||
-- @class function
|
||||
-- @name crc32
|
||||
-- @param buffer Buffer
|
||||
-- @param initial Initial CRC32 value (optional)
|
||||
-- @return crc32 value
|
||||
|
||||
--- Base64 encode a given buffer.
|
||||
-- @class function
|
||||
-- @name b64encode
|
||||
-- @param buffer Buffer
|
||||
-- @return base64 encoded buffer
|
||||
|
||||
--- Base64 decode a given buffer.
|
||||
-- @class function
|
||||
-- @name b64decode
|
||||
-- @param buffer Base 64 Encoded data
|
||||
-- @return binary data
|
86
libs/nixio/docsrc/nixio.bit.lua
Normal file
86
libs/nixio/docsrc/nixio.bit.lua
Normal file
|
@ -0,0 +1,86 @@
|
|||
--- Bitfield operators and mainpulation functions.
|
||||
-- Can be used as a drop-in replacement for bitlib.
|
||||
module "nixio.bit"
|
||||
|
||||
--- Bitwise OR several numbers.
|
||||
-- @class function
|
||||
-- @name bor
|
||||
-- @param oper1 First Operand
|
||||
-- @param oper2 Second Operand
|
||||
-- @param ... More Operands
|
||||
-- @return number
|
||||
|
||||
--- Bitwise AND several numbers.
|
||||
-- @class function
|
||||
-- @name band
|
||||
-- @param oper1 First Operand
|
||||
-- @param oper2 Second Operand
|
||||
-- @param ... More Operands
|
||||
-- @return number
|
||||
|
||||
--- Bitwise XOR several numbers.
|
||||
-- @class function
|
||||
-- @name bxor
|
||||
-- @param oper1 First Operand
|
||||
-- @param oper2 Second Operand
|
||||
-- @param ... More Operands
|
||||
-- @return number
|
||||
|
||||
--- Left shift a number.
|
||||
-- @class function
|
||||
-- @name shl
|
||||
-- @param oper number
|
||||
-- @param shift bits to shift
|
||||
-- @return number
|
||||
|
||||
--- Right shift a number.
|
||||
-- @class function
|
||||
-- @name shr
|
||||
-- @param oper number
|
||||
-- @param shift bits to shift
|
||||
-- @return number
|
||||
|
||||
--- Arithmetically right shift a number.
|
||||
-- @class function
|
||||
-- @name ashr
|
||||
-- @param oper number
|
||||
-- @param shift bits to shift
|
||||
-- @return number
|
||||
|
||||
--- Integer division of 2 or more numbers.
|
||||
-- @class function
|
||||
-- @name div
|
||||
-- @param oper1 Operand 1
|
||||
-- @param oper2 Operand 2
|
||||
-- @param ... More Operands
|
||||
-- @return number
|
||||
|
||||
--- Cast a number to the bit-operating range.
|
||||
-- @class function
|
||||
-- @name cast
|
||||
-- @param oper number
|
||||
-- @return number
|
||||
|
||||
--- Sets one or more flags of a bitfield.
|
||||
-- @class function
|
||||
-- @name set
|
||||
-- @param bitfield Bitfield
|
||||
-- @param flag1 First Flag
|
||||
-- @param ... More Flags
|
||||
-- @return altered bitfield
|
||||
|
||||
--- Unsets one or more flags of a bitfield.
|
||||
-- @class function
|
||||
-- @name unset
|
||||
-- @param bitfield Bitfield
|
||||
-- @param flag1 First Flag
|
||||
-- @param ... More Flags
|
||||
-- @return altered bitfield
|
||||
|
||||
--- Checks whether given flags are set in a bitfield.
|
||||
-- @class function
|
||||
-- @name check
|
||||
-- @param bitfield Bitfield
|
||||
-- @param flag1 First Flag
|
||||
-- @param ... More Flags
|
||||
-- @return true when all flags are set, otherwise false
|
15
libs/nixio/docsrc/nixio.crypto.lua
Normal file
15
libs/nixio/docsrc/nixio.crypto.lua
Normal file
|
@ -0,0 +1,15 @@
|
|||
--- Cryptographical library.
|
||||
module "nixio.crypto"
|
||||
|
||||
--- Create a hash object.
|
||||
-- @class function
|
||||
-- @name nixio.crypto.hash
|
||||
-- @param algo Algorithm ["sha1", "md5"]
|
||||
-- @return CryptoHash Object
|
||||
|
||||
--- Create a HMAC object.
|
||||
-- @class function
|
||||
-- @name nixio.crypto.hmac
|
||||
-- @param algo Algorithm ["sha1", "md5"]
|
||||
-- @param key HMAC-Key
|
||||
-- @return CryptoHash Object
|
265
libs/nixio/docsrc/nixio.fs.lua
Normal file
265
libs/nixio/docsrc/nixio.fs.lua
Normal file
|
@ -0,0 +1,265 @@
|
|||
--- Low-level and high-level filesystem manipulation library.
|
||||
module "nixio.fs"
|
||||
|
||||
|
||||
--- Check user's permission on a file.
|
||||
-- @class function
|
||||
-- @name nixio.fs.access
|
||||
-- @param path Path
|
||||
-- @param mode1 First Mode to check ["f", "r", "w", "x"]
|
||||
-- @param ... More Modes to check [-"-]
|
||||
-- @return true
|
||||
|
||||
--- Strip the directory part from a path.
|
||||
-- @class function
|
||||
-- @name nixio.fs.basename
|
||||
-- @usage This function cannot fail and will never return nil.
|
||||
-- @param path Path
|
||||
-- @return basename
|
||||
|
||||
--- Strip the base from a path.
|
||||
-- @class function
|
||||
-- @name nixio.fs.dirname
|
||||
-- @usage This function cannot fail and will never return nil.
|
||||
-- @param path Path
|
||||
-- @return dirname
|
||||
|
||||
--- Return the cannonicalized absolute pathname.
|
||||
-- @class function
|
||||
-- @name nixio.fs.realpath
|
||||
-- @param path Path
|
||||
-- @return absolute path
|
||||
|
||||
--- Remove a file or directory.
|
||||
-- @class function
|
||||
-- @name nixio.fs.remove
|
||||
-- @param path Path
|
||||
-- @return true
|
||||
|
||||
--- Delete a name and - if no links are left - the associated file.
|
||||
-- @class function
|
||||
-- @name nixio.fs.unlink
|
||||
-- @param path Path
|
||||
-- @return true
|
||||
|
||||
--- Renames a file or directory.
|
||||
-- @class function
|
||||
-- @name nixio.fs.rename
|
||||
-- @param src Source path
|
||||
-- @param dest Destination path
|
||||
-- @usage It is normally not possible to rename files accross fileystems.
|
||||
-- @return true
|
||||
|
||||
--- Remove an empty directory.
|
||||
-- @class function
|
||||
-- @name nixio.fs.rmdir
|
||||
-- @param path Path
|
||||
-- @return true
|
||||
|
||||
--- Create a new directory.
|
||||
-- @class function
|
||||
-- @name nixio.fs.mkdir
|
||||
-- @param path Path
|
||||
-- @param mode File mode (optional, see chmod and umask)
|
||||
-- @see nixio.fs.chmod
|
||||
-- @see nixio.umask
|
||||
-- @return true
|
||||
|
||||
--- Change the file mode.
|
||||
-- @class function
|
||||
-- @name nixio.fs.chmod
|
||||
-- @usage Windows only supports setting the write-protection through the
|
||||
-- "Writable to others" bit.
|
||||
-- @usage <strong>Notice:</strong> The mode-flag for the functions
|
||||
-- open, mkdir, mkfifo are affected by the umask.
|
||||
-- @param path Path
|
||||
-- @param mode File mode
|
||||
-- [decimal mode number, "[-r][-w][-xsS][-r][-w][-xsS][-r][-w][-xtT]"]
|
||||
-- @see nixio.umask
|
||||
-- @return true
|
||||
|
||||
--- Iterate over the entries of a directory.
|
||||
-- @class function
|
||||
-- @name nixio.fs.dir
|
||||
-- @usage The special entries "." and ".." are omitted.
|
||||
-- @param path Path
|
||||
-- @return directory iterator returning one entry per call
|
||||
|
||||
--- Create a hard link.
|
||||
-- @class function
|
||||
-- @name nixio.fs.link
|
||||
-- @usage This function calls link() on POSIX and CreateHardLink() on Windows.
|
||||
-- @param oldpath Path
|
||||
-- @param newpath Path
|
||||
-- @return true
|
||||
|
||||
--- Change file last access and last modification time.
|
||||
-- @class function
|
||||
-- @name nixio.fs.utimes
|
||||
-- @param path Path
|
||||
-- @param actime Last access timestamp (optional, default: current time)
|
||||
-- @param mtime Last modification timestamp (optional, default: actime)
|
||||
-- @return true
|
||||
|
||||
--- Get file status and attributes.
|
||||
-- @class function
|
||||
-- @name nixio.fs.stat
|
||||
-- @param path Path
|
||||
-- @param field Only return a specific field, not the whole table (optional)
|
||||
-- @return Table containing: <ul>
|
||||
-- <li>atime = Last access timestamp</li>
|
||||
-- <li>blksize = Blocksize (POSIX only)</li>
|
||||
-- <li>blocks = Blocks used (POSIX only)</li>
|
||||
-- <li>ctime = Creation timestamp</li>
|
||||
-- <li>dev = Device ID</li>
|
||||
-- <li>gid = Group ID</li>
|
||||
-- <li>ino = Inode</li>
|
||||
-- <li>modedec = Mode converted into a decimal number</li>
|
||||
-- <li>modestr = Mode as string as returned by `ls -l`</li>
|
||||
-- <li>mtime = Last modification timestamp</li>
|
||||
-- <li>nlink = Number of links</li>
|
||||
-- <li>rdev = Device ID (if special file)</li>
|
||||
-- <li>size = Size in bytes</li>
|
||||
-- <li>type = ["reg", "dir", "chr", "blk", "fifo", "lnk", "sock"]</li>
|
||||
-- <li>uid = User ID</li>
|
||||
-- </ul>
|
||||
|
||||
--- Get file status and attributes and do not resolve if target is a symlink.
|
||||
-- @class function
|
||||
-- @name nixio.fs.lstat
|
||||
-- @param path Path
|
||||
-- @param field Only return a specific field, not the whole table (optional)
|
||||
-- @see nixio.fs.stat
|
||||
-- @return Table containing attributes (see stat for a detailed description)
|
||||
|
||||
--- (POSIX) Change owner and group of a file.
|
||||
-- @class function
|
||||
-- @name nixio.fs.chown
|
||||
-- @param path Path
|
||||
-- @param user User ID or Username (optional)
|
||||
-- @param group Group ID or Groupname (optional)
|
||||
-- @return true
|
||||
|
||||
--- (POSIX) Change owner and group of a file and do not resolve
|
||||
-- if target is a symlink.
|
||||
-- @class function
|
||||
-- @name nixio.fs.lchown
|
||||
-- @param path Path
|
||||
-- @param user User ID or Username (optional)
|
||||
-- @param group Group ID or Groupname (optional)
|
||||
-- @return true
|
||||
|
||||
--- (POSIX) Create a FIFO (named pipe).
|
||||
-- @class function
|
||||
-- @name nixio.fs.mkfifo
|
||||
-- @param path Path
|
||||
-- @param mode File mode (optional, see chmod and umask)
|
||||
-- @see nixio.fs.chmod
|
||||
-- @see nixio.umask
|
||||
-- @return true
|
||||
|
||||
--- (POSIX) Create a symbolic link.
|
||||
-- @class function
|
||||
-- @name nixio.fs.symlink
|
||||
-- @param oldpath Path
|
||||
-- @param newpath Path
|
||||
-- @return true
|
||||
|
||||
--- (POSIX) Read the target of a symbolic link.
|
||||
-- @class function
|
||||
-- @name nixio.fs.readlink
|
||||
-- @param path Path
|
||||
-- @return target path
|
||||
|
||||
--- (POSIX) Find pathnames matching a pattern.
|
||||
-- @class function
|
||||
-- @name nixio.fs.glob
|
||||
-- @param pattern Pattern
|
||||
-- @return path iterator
|
||||
-- @return number of matches
|
||||
|
||||
--- (POSIX) Get filesystem statistics.
|
||||
-- @class function
|
||||
-- @name nixio.fs.statvfs
|
||||
-- @param path Path to any file within the filesystem.
|
||||
-- @return Table containing: <ul>
|
||||
-- <li>bavail = available blocks</li>
|
||||
-- <li>bfree = free blocks</li>
|
||||
-- <li>blocks = number of fragments</li>
|
||||
-- <li>frsize = fragment size</li>
|
||||
-- <li>favail = available inodes</li>
|
||||
-- <li>ffree = free inodes</li>
|
||||
-- <li>files = inodes</li>
|
||||
-- <li>flag = flags</li>
|
||||
-- <li>fsid = filesystem ID</li>
|
||||
-- <li>namemax = maximum filename length</li>
|
||||
-- </ul>
|
||||
|
||||
--- Read the contents of a file into a buffer.
|
||||
-- @class function
|
||||
-- @name nixio.fs.readfile
|
||||
-- @param path Path
|
||||
-- @param limit Maximum bytes to read (optional)
|
||||
-- @return file contents
|
||||
|
||||
--- Write a buffer into a file truncating the file first.
|
||||
-- @class function
|
||||
-- @name nixio.fs.writefile
|
||||
-- @param path Path
|
||||
-- @param data Data to write
|
||||
-- @return true
|
||||
|
||||
--- Copy data between files.
|
||||
-- @class function
|
||||
-- @name nixio.fs.datacopy
|
||||
-- @param src Source file path
|
||||
-- @param dest Destination file path
|
||||
-- @param limit Maximum bytes to copy (optional)
|
||||
-- @return true
|
||||
|
||||
--- Copy a file, directory or symlink non-recursively preserving file mode,
|
||||
-- timestamps, owner and group.
|
||||
-- @class function
|
||||
-- @name nixio.fs.copy
|
||||
-- @usage The destination must always be a full destination path e.g. do not
|
||||
-- omit the basename even if source and destination basename are equal.
|
||||
-- @param src Source path
|
||||
-- @param dest Destination path
|
||||
-- @return true
|
||||
|
||||
--- Rename a file, directory or symlink non-recursively across filesystems.
|
||||
-- @class function
|
||||
-- @name nixio.fs.move
|
||||
-- @usage The destination must always be a full destination path e.g. do not
|
||||
-- omit the basename even if source and destination basename are equal.
|
||||
-- @param src Source path
|
||||
-- @param dest Destination path
|
||||
-- @return true
|
||||
|
||||
--- Create a directory and all needed parent directories recursively.
|
||||
-- @class function
|
||||
-- @name nixio.fs.mkdirr
|
||||
-- @param dest Destination path
|
||||
-- @param mode File mode (optional, see chmod and umask)
|
||||
-- @see nixio.fs.chmod
|
||||
-- @see nixio.umask
|
||||
-- @return true
|
||||
|
||||
--- Rename a file, directory or symlink recursively across filesystems.
|
||||
-- @class function
|
||||
-- @name nixio.fs.mover
|
||||
-- @usage The destination must always be a full destination path e.g. do not
|
||||
-- omit the basename even if source and destination basename are equal.
|
||||
-- @param src Source path
|
||||
-- @param dest Destination path
|
||||
-- @return true
|
||||
|
||||
--- Copy a file, directory or symlink recursively preserving file mode,
|
||||
-- timestamps, owner and group.
|
||||
-- @class function
|
||||
-- @name nixio.fs.copyr
|
||||
-- @usage The destination must always be a full destination path e.g. do not
|
||||
-- omit the basename even if source and destination basename are equal.
|
||||
-- @param src Source path
|
||||
-- @param dest Destination path
|
||||
-- @return true
|
416
libs/nixio/docsrc/nixio.lua
Normal file
416
libs/nixio/docsrc/nixio.lua
Normal file
|
@ -0,0 +1,416 @@
|
|||
--- General POSIX IO library.
|
||||
module "nixio"
|
||||
|
||||
--- Look up a hostname and service via DNS.
|
||||
-- @class function
|
||||
-- @name nixio.getaddrinfo
|
||||
-- @param host hostname to lookup (optional)
|
||||
-- @param family address family [<strong>"any"</strong>, "inet", "inet6"]
|
||||
-- @param service service name or port (optional)
|
||||
-- @return Table containing one or more tables containing: <ul>
|
||||
-- <li>family = ["inet", "inet6"]</li>
|
||||
-- <li>socktype = ["stream", "dgram", "raw"]</li>
|
||||
-- <li>address = Resolved IP-Address</li>
|
||||
-- <li>port = Resolved Port (if service was given)</li>
|
||||
-- </ul>
|
||||
|
||||
--- Reverse look up an IP-Address via DNS.
|
||||
-- @class function
|
||||
-- @name nixio.getnameinfo
|
||||
-- @param ipaddr IPv4 or IPv6-Address
|
||||
-- @return FQDN
|
||||
|
||||
--- Create a new socket and bind it to a network address.
|
||||
-- This function is a shortcut for calling nixio.socket and then bind()
|
||||
-- on the socket object.
|
||||
-- @usage This functions calls getaddrinfo(), socket(),
|
||||
-- setsockopt() and bind() but NOT listen().
|
||||
-- @usage The <em>reuseaddr</em>-option is automatically set before binding.
|
||||
-- @class function
|
||||
-- @name nixio.bind
|
||||
-- @param host Hostname or IP-Address (optional, default: all addresses)
|
||||
-- @param port Port or service description
|
||||
-- @param family Address family [<strong>"any"</strong>, "inet", "inet6"]
|
||||
-- @param socktype Socket Type [<strong>"stream"</strong>, "dgram"]
|
||||
-- @return Socket Object
|
||||
|
||||
--- Create a new socket and connect to a network address.
|
||||
-- This function is a shortcut for calling nixio.socket and then connect()
|
||||
-- on the socket object.
|
||||
-- @usage This functions calls getaddrinfo(), socket() and connect().
|
||||
-- @class function
|
||||
-- @name nixio.connect
|
||||
-- @param host Hostname or IP-Address (optional, default: localhost)
|
||||
-- @param port Port or service description
|
||||
-- @param family Address family [<strong>"any"</strong>, "inet", "inet6"]
|
||||
-- @param socktype Socket Type [<strong>"stream"</strong>, "dgram"]
|
||||
-- @return Socket Object
|
||||
|
||||
--- Open a file.
|
||||
-- @class function
|
||||
-- @name nixio.open
|
||||
-- @usage Although this function also supports the traditional fopen()
|
||||
-- file flags it does not create a file stream but uses the open() syscall.
|
||||
-- @param path Filesystem path to open
|
||||
-- @param flags Flag string or number (see open_flags).
|
||||
-- [<strong>"r"</strong>, "r+", "w", "w+", "a", "a+"]
|
||||
-- @param mode File mode for newly created files (see chmod, umask).
|
||||
-- @see nixio.umask
|
||||
-- @see nixio.open_flags
|
||||
-- @return File Object
|
||||
|
||||
--- Generate flags for a call to open().
|
||||
-- @class function
|
||||
-- @name nixio.open_flags
|
||||
-- @usage This function cannot fail and will never return nil.
|
||||
-- @usage The "nonblock" and "ndelay" flags are aliases.
|
||||
-- @usage The "nonblock", "ndelay" and "sync" flags are no-ops on Windows.
|
||||
-- @param flag1 First Flag ["append", "creat", "excl", "nonblock", "ndelay",
|
||||
-- "sync", "trunc", "rdonly", "wronly", "rdwr"]
|
||||
-- @param ... More Flags [-"-]
|
||||
-- @return flag to be used as second paramter to open
|
||||
|
||||
--- Duplicate a file descriptor.
|
||||
-- @class function
|
||||
-- @name nixio.dup
|
||||
-- @usage This funcation calls dup2() if <em>newfd</em> is set, otherwise dup().
|
||||
-- @param oldfd Old descriptor [File Object, Socket Object (POSIX only)]
|
||||
-- @param newfd New descriptor to serve as copy (optional)
|
||||
-- @return File Object of new descriptor
|
||||
|
||||
--- Create a pipe.
|
||||
-- @class function
|
||||
-- @name nixio.pipe
|
||||
-- @return File Object of the read end
|
||||
-- @return File Object of the write end
|
||||
|
||||
--- Get the last system error code.
|
||||
-- @class function
|
||||
-- @name nixio.errno
|
||||
-- @return Error code
|
||||
|
||||
--- Get the error message for the corresponding error code.
|
||||
-- @class function
|
||||
-- @name nixio.strerror
|
||||
-- @param errno System error code
|
||||
-- @return Error message
|
||||
|
||||
--- Sleep for a specified amount of time.
|
||||
-- @class function
|
||||
-- @usage Not all systems support nanosecond precision but you can expect
|
||||
-- to have at least maillisecond precision.
|
||||
-- @usage This function is not signal-protected and may fail with EINTR.
|
||||
-- @param seconds Seconds to wait (optional)
|
||||
-- @param nanoseconds Nanoseconds to wait (optional)
|
||||
-- @name nixio.nanosleep
|
||||
-- @return true
|
||||
|
||||
--- Generate events-bitfield or parse revents-bitfield for poll.
|
||||
-- @class function
|
||||
-- @name nixio.poll_flags
|
||||
-- @param mode1 revents-Flag bitfield returned from poll to parse OR
|
||||
-- ["in", "out", "err", "pri" (POSIX), "hup" (POSIX), "nval" (POSIX)]
|
||||
-- @param ... More mode strings for generating the flag [-"-]
|
||||
-- @see nixio.poll
|
||||
-- @return table with boolean fields reflecting the mode parameter
|
||||
-- <strong>OR</strong> bitfield to use for the events-Flag field
|
||||
|
||||
--- Wait for some event on a file descriptor.
|
||||
-- poll() sets the revents-field of the tables provided by fds to a bitfield
|
||||
-- indicating the events that occured.
|
||||
-- @class function
|
||||
-- @usage This function works in-place on the provided table and only
|
||||
-- writes the revents field, you can use other fields on your demand.
|
||||
-- @usage All metamethods on the tables provided as fds are ignored.
|
||||
-- @usage The revents-fields are not reset when the call times out.
|
||||
-- You have to check the first return value to be 0 to handle this case.
|
||||
-- @usage If you want to wait on a TLS-Socket you have to use the underlying
|
||||
-- socket instead.
|
||||
-- @usage On Windows poll is emulated through select(), can only be used
|
||||
-- on socket descriptors and cannot take more than 64 descriptors per call.
|
||||
-- @usage This function is not signal-protected and may fail with EINTR.
|
||||
-- @param fds Table containing one or more tables containing <ul>
|
||||
-- <li> fd = I/O Descriptor [Socket Object, File Object (POSIX)]</li>
|
||||
-- <li> events = events to wait for (bitfield generated with poll_flags)</li>
|
||||
-- </ul>
|
||||
-- @param timeout Timeout in milliseconds
|
||||
-- @name nixio.poll
|
||||
-- @see nixio.poll_flags
|
||||
-- @return number of ready IO descriptors
|
||||
-- @return the fds-table with revents-fields set
|
||||
|
||||
--- (POSIX) Clone the current process.
|
||||
-- @class function
|
||||
-- @name nixio.fork
|
||||
-- @return the child process id for the parent process, 0 for the child process
|
||||
|
||||
--- (POSIX) Send a signal to one or more processes.
|
||||
-- @class function
|
||||
-- @name nixio.kill
|
||||
-- @param target Target process of process group.
|
||||
-- @param signal Signal to send
|
||||
-- @return true
|
||||
|
||||
--- (POSIX) Get the parent process id of the current process.
|
||||
-- @class function
|
||||
-- @name nixio.getppid
|
||||
-- @return parent process id
|
||||
|
||||
--- (POSIX) Get the user id of the current process.
|
||||
-- @class function
|
||||
-- @name nixio.getuid
|
||||
-- @return process user id
|
||||
|
||||
--- (POSIX) Get the group id of the current process.
|
||||
-- @class function
|
||||
-- @name nixio.getgid
|
||||
-- @return process group id
|
||||
|
||||
--- (POSIX) Set the group id of the current process.
|
||||
-- @class function
|
||||
-- @name nixio.setgid
|
||||
-- @param gid New Group ID
|
||||
-- @return true
|
||||
|
||||
--- (POSIX) Set the user id of the current process.
|
||||
-- @class function
|
||||
-- @name nixio.setuid
|
||||
-- @param gid New User ID
|
||||
-- @return true
|
||||
|
||||
--- (POSIX) Change priority of current process.
|
||||
-- @class function
|
||||
-- @name nixio.nice
|
||||
-- @param nice Nice Value
|
||||
-- @return true
|
||||
|
||||
--- (POSIX) Create a new session and set the process group ID.
|
||||
-- @class function
|
||||
-- @name nixio.setsid
|
||||
-- @return session id
|
||||
|
||||
--- (POSIX) Wait for a process to change state.
|
||||
-- @class function
|
||||
-- @name nixio.waitpid
|
||||
-- @usage If the "nohang" is given this function becomes non-blocking.
|
||||
-- @param pid Process ID (optional, default: any childprocess)
|
||||
-- @param flag1 Flag (optional) ["nohang", "untraced", "continued"]
|
||||
-- @param ... More Flags [-"-]
|
||||
-- @return process id of child or 0 if no child has changed state
|
||||
-- @return ["exited", "signaled", "stopped"]
|
||||
-- @return [exit code, terminate signal, stop signal]
|
||||
|
||||
--- (POSIX) Get process times.
|
||||
-- @class function
|
||||
-- @name nixio.times
|
||||
-- @return Table containing: <ul>
|
||||
-- <li>utime = user time</li>
|
||||
-- <li>utime = system time</li>
|
||||
-- <li>cutime = children user time</li>
|
||||
-- <li>cstime = children system time</li>
|
||||
-- </ul>
|
||||
|
||||
--- (POSIX) Get information about current system and kernel.
|
||||
-- @class function
|
||||
-- @name nixio.uname
|
||||
-- @return Table containing: <ul>
|
||||
-- <li>sysname = operating system</li>
|
||||
-- <li>nodename = network name (usually hostname)</li>
|
||||
-- <li>release = OS release</li>
|
||||
-- <li>version = OS version</li>
|
||||
-- <li>machine = hardware identifier</li>
|
||||
-- </ul>
|
||||
|
||||
--- Change the working directory.
|
||||
-- @class function
|
||||
-- @name nixio.chdir
|
||||
-- @param path New working directory
|
||||
-- @return true
|
||||
|
||||
--- Ignore or use set the default handler for a signal.
|
||||
-- @class function
|
||||
-- @name nixio.signal
|
||||
-- @param signal Signal
|
||||
-- @param handler ["ign", "dfl"]
|
||||
-- @return true
|
||||
|
||||
--- Get the ID of the current process.
|
||||
-- @class function
|
||||
-- @name nixio.getpid
|
||||
-- @return process id
|
||||
|
||||
--- Get the current working directory.
|
||||
-- @class function
|
||||
-- @name nixio.getcwd
|
||||
-- @return workign directory
|
||||
|
||||
--- Get the current environment table or a specific environment variable.
|
||||
-- @class function
|
||||
-- @name nixio.getenv
|
||||
-- @param variable Variable (optional)
|
||||
-- @return environment table or single environment variable
|
||||
|
||||
--- Set or unset a environment variable.
|
||||
-- @class function
|
||||
-- @name nixio.setenv
|
||||
-- @usage The environment variable will be unset if value is ommited.
|
||||
-- @param variable Variable
|
||||
-- @param value Value (optional)
|
||||
-- @return true
|
||||
|
||||
--- Execute a file to replace the current process.
|
||||
-- @class function
|
||||
-- @name nixio.exec
|
||||
-- @usage The name of the executable is automatically passed as argv[0]
|
||||
-- @usage This function does not return on success.
|
||||
-- @param executable Executable
|
||||
-- @param ... Parameters
|
||||
|
||||
--- Invoke the shell and execute a file to replace the current process.
|
||||
-- @class function
|
||||
-- @name nixio.execp
|
||||
-- @usage The name of the executable is automatically passed as argv[0]
|
||||
-- @usage This function does not return on success.
|
||||
-- @param executable Executable
|
||||
-- @param ... Parameters
|
||||
|
||||
--- Execute a file with a custom environment to replace the current process.
|
||||
-- @class function
|
||||
-- @name nixio.exece
|
||||
-- @usage The name of the executable is automatically passed as argv[0]
|
||||
-- @usage This function does not return on success.
|
||||
-- @param executable Executable
|
||||
-- @param arguments Argument Table
|
||||
-- @param environment Environment Table (optional)
|
||||
|
||||
--- Sets the file mode creation mask.
|
||||
-- @class function
|
||||
-- @name nixio.umask
|
||||
-- @param mask New creation mask (see chmod for format specifications)
|
||||
-- @return the old umask as decimal mode number
|
||||
-- @return the old umask as mode string
|
||||
|
||||
--- (Linux) Get overall system statistics.
|
||||
-- @class function
|
||||
-- @name nixio.sysinfo
|
||||
-- @return Table containing: <ul>
|
||||
-- <li>uptime = system uptime in seconds</li>
|
||||
-- <li>loads = {loadavg1, loadavg5, loadavg15}</li>
|
||||
-- <li>totalram = total RAM</li>
|
||||
-- <li>freeram = free RAM</li>
|
||||
-- <li>sharedram = shared RAM</li>
|
||||
-- <li>bufferram = buffered RAM</li>
|
||||
-- <li>totalswap = total SWAP</li>
|
||||
-- <li>freeswap = free SWAP</li>
|
||||
-- <li>procs = number of running processes</li>
|
||||
-- </ul>
|
||||
|
||||
--- Create a new socket.
|
||||
-- @class function
|
||||
-- @name nixio.socket
|
||||
-- @param domain Domain ["inet", "inet6", "unix"]
|
||||
-- @param type Type ["stream", "dgram", "raw"]
|
||||
-- @return Socket Object
|
||||
|
||||
--- (POSIX) Send data from a file to a socket in kernel-space.
|
||||
-- @class function
|
||||
-- @name nixio.sendfile
|
||||
-- @param socket Socket Object
|
||||
-- @param file File Object
|
||||
-- @param length Amount of data to send (in Bytes).
|
||||
-- @return bytes sent
|
||||
|
||||
--- (Linux) Send data from / to a pipe in kernel-space.
|
||||
-- @class function
|
||||
-- @name nixio.splice
|
||||
-- @param fdin Input I/O descriptor
|
||||
-- @param fdout Output I/O descriptor
|
||||
-- @param length Amount of data to send (in Bytes).
|
||||
-- @param flags (optional, bitfield generated by splice_flags)
|
||||
-- @see nixio.splice_flags
|
||||
-- @return bytes sent
|
||||
|
||||
--- (Linux) Generate a flag bitfield for a call to splice.
|
||||
-- @class function
|
||||
-- @name nixio.splice_flags
|
||||
-- @param flag1 First Flag ["move", "nonblock", "more"]
|
||||
-- @param ... More flags [-"-]
|
||||
-- @see nixio.splice
|
||||
-- @return Flag bitfield
|
||||
|
||||
--- (POSIX) Open a connection to the system logger.
|
||||
-- @class function
|
||||
-- @name nixio.openlog
|
||||
-- @param ident Identifier
|
||||
-- @param flag1 Flag 1 ["cons", "nowait", "pid", "perror", "ndelay", "odelay"]
|
||||
-- @param ... More flags [-"-]
|
||||
|
||||
--- (POSIX) Close the connection to the system logger.
|
||||
-- @class function
|
||||
-- @name nixio.closelog
|
||||
|
||||
--- (POSIX) Write a message to the system logger.
|
||||
-- @class function
|
||||
-- @name nixio.syslog
|
||||
-- @param priority Priority ["emerg", "alert", "crit", "err", "warning",
|
||||
-- "notice", "info", "debug"]
|
||||
-- @param message
|
||||
|
||||
--- (POSIX) Set the logmask of the system logger for current process.
|
||||
-- @class function
|
||||
-- @name nixio.setlogmask
|
||||
-- @param priority Priority ["emerg", "alert", "crit", "err", "warning",
|
||||
-- "notice", "info", "debug"]
|
||||
|
||||
--- (POSIX) Encrypt a user password.
|
||||
-- @class function
|
||||
-- @name nixio.crypt
|
||||
-- @param key Key
|
||||
-- @param salt Salt
|
||||
-- @return password hash
|
||||
|
||||
--- (POSIX) Get all or a specific user group.
|
||||
-- @class function
|
||||
-- @name nixio.getgr
|
||||
-- @param group Group ID or groupname (optional)
|
||||
-- @return Table containing: <ul>
|
||||
-- <li>name = Group Name</li>
|
||||
-- <li>gid = Group ID</li>
|
||||
-- <li>passwd = Password</li>
|
||||
-- <li>mem = {Member #1, Member #2, ...}</li>
|
||||
-- </ul>
|
||||
|
||||
--- (POSIX) Get all or a specific user account.
|
||||
-- @class function
|
||||
-- @name nixio.getpw
|
||||
-- @param user User ID or username (optional)
|
||||
-- @return Table containing: <ul>
|
||||
-- <li>name = Name</li>
|
||||
-- <li>uid = ID</li>
|
||||
-- <li>gid = Group ID</li>
|
||||
-- <li>passwd = Password</li>
|
||||
-- <li>dir = Home directory</li>
|
||||
-- <li>gecos = Information</li>
|
||||
-- <li>shell = Shell</li>
|
||||
-- </ul>
|
||||
|
||||
--- (Linux, Solaris) Get all or a specific shadow password entry.
|
||||
-- @class function
|
||||
-- @name nixio.getsp
|
||||
-- @param user username (optional)
|
||||
-- @return Table containing: <ul>
|
||||
-- <li>namp = Name</li>
|
||||
-- <li>expire = Expiration Date</li>
|
||||
-- <li>flag = Flags</li>
|
||||
-- <li>inact = Inactivity Date</li>
|
||||
-- <li>lstchg = Last change</li>
|
||||
-- <li>max = Maximum</li>
|
||||
-- <li>min = Minimum</li>
|
||||
-- <li>warn = Warning</li>
|
||||
-- <li>pwdp = Password Hash</li>
|
||||
-- </ul>
|
||||
|
||||
--- Create a new TLS context.
|
||||
-- @class function
|
||||
-- @name nixio.tls
|
||||
-- @return TLSContext Object
|
15
libs/nixio/lua/bit.lua
Normal file
15
libs/nixio/lua/bit.lua
Normal file
|
@ -0,0 +1,15 @@
|
|||
--[[
|
||||
nixio - Linux I/O library for lua
|
||||
|
||||
Copyright 2009 Steven Barth <steven@midlink.org>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
$Id$
|
||||
]]--
|
||||
|
||||
return require "nixio".bit
|
175
libs/nixio/lua/nixio/fs.lua
Normal file
175
libs/nixio/lua/nixio/fs.lua
Normal file
|
@ -0,0 +1,175 @@
|
|||
--[[
|
||||
nixio - Linux I/O library for lua
|
||||
|
||||
Copyright 2009 Steven Barth <steven@midlink.org>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
$Id$
|
||||
]]--
|
||||
|
||||
local table = require "table"
|
||||
local nixio = require "nixio"
|
||||
local type, ipairs, setmetatable = type, ipairs, setmetatable
|
||||
require "nixio.util"
|
||||
|
||||
|
||||
module ("nixio.fs", function(m) setmetatable(m, {__index = nixio.fs}) end)
|
||||
|
||||
|
||||
function readfile(path, limit)
|
||||
local fd, code, msg = nixio.open(path, "r")
|
||||
local data
|
||||
if not fd then
|
||||
return nil, code, msg
|
||||
end
|
||||
|
||||
data, code, msg = fd:readall(limit)
|
||||
|
||||
fd:close()
|
||||
return data, code, msg
|
||||
end
|
||||
|
||||
|
||||
function writefile(path, data)
|
||||
local fd, code, msg, stat = nixio.open(path, "w")
|
||||
if not fd then
|
||||
return nil, code, msg
|
||||
end
|
||||
|
||||
stat, code, msg = fd:writeall(data)
|
||||
|
||||
fd:close()
|
||||
return stat, code, msg
|
||||
end
|
||||
|
||||
function datacopy(src, dest, size)
|
||||
local fdin, code, msg = nixio.open(src, "r")
|
||||
if not fdin then
|
||||
return nil, code, msg
|
||||
end
|
||||
|
||||
local fdout, code, msg = nixio.open(dest, "w")
|
||||
if not fdout then
|
||||
return nil, code, msg
|
||||
end
|
||||
|
||||
local stat, code, msg, sent = fdin:copy(fdout, size)
|
||||
fdin:close()
|
||||
fdout:close()
|
||||
|
||||
return stat, code, msg, sent
|
||||
end
|
||||
|
||||
function copy(src, dest)
|
||||
local stat, code, msg, res = nixio.lstat(src)
|
||||
if not stat then
|
||||
return nil, code, msg
|
||||
end
|
||||
|
||||
if stat.type == "dir" then
|
||||
if nixio.stat(dest, type) ~= "dir" then
|
||||
res, code, msg = nixio.mkdir(dest)
|
||||
else
|
||||
stat = true
|
||||
end
|
||||
elseif stat.type == "lnk" then
|
||||
res, code, msg = nixio.symlink(nixio.readlink(src), dest)
|
||||
else
|
||||
res, code, msg = datacopy(src, dest)
|
||||
end
|
||||
|
||||
if not res then
|
||||
return nil, code, msg
|
||||
end
|
||||
|
||||
nixio.utimes(dest, stat.atime, stat.mtime)
|
||||
|
||||
if nixio.lchown then
|
||||
nixio.lchown(dest, stat.uid, stat.gid)
|
||||
end
|
||||
|
||||
if stat.type ~= "lnk" then
|
||||
nixio.chmod(dest, stat.modedec)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function move(src, dest)
|
||||
local stat, code, msg = nixio.rename(src, dest)
|
||||
if not stat and code == nixio.const.EXDEV then
|
||||
stat, code, msg = nixio.copy(src, dest)
|
||||
if stat then
|
||||
stat, code, msg = nixio.unlink(src)
|
||||
end
|
||||
end
|
||||
return stat, code, msg
|
||||
end
|
||||
|
||||
function mkdirr(dest, mode)
|
||||
if nixio.stat(dest, "type") == "dir" then
|
||||
return true
|
||||
else
|
||||
local stat, code, msg = nixio.mkdir(dest, mode)
|
||||
if not stat and code == nixio.const.ENOENT then
|
||||
stat, code, msg = mkdirr(nixio.dirname(dest), mode)
|
||||
if stat then
|
||||
stat, code, msg = nixio.mkdir(dest, mode)
|
||||
end
|
||||
end
|
||||
return stat, code, msg
|
||||
end
|
||||
end
|
||||
|
||||
local function _recurse(cb, src, dest)
|
||||
local type = nixio.lstat(src, "type")
|
||||
if type ~= "dir" then
|
||||
return cb(src, dest)
|
||||
else
|
||||
local stat, se, code, msg, s, c, m = true, nixio.const.sep
|
||||
if dest then
|
||||
s, c, m = cb(src, dest)
|
||||
stat, code, msg = stat and s, c or code, m or msg
|
||||
end
|
||||
|
||||
for e in nixio.dir(src) do
|
||||
if dest then
|
||||
s, c, m = _recurse(cb, src .. se .. e, dest .. se .. e)
|
||||
else
|
||||
s, c, m = _recurse(cb, src .. se .. e)
|
||||
end
|
||||
stat, code, msg = stat and s, c or code, m or msg
|
||||
end
|
||||
|
||||
if not dest then -- Postfix
|
||||
s, c, m = cb(src)
|
||||
stat, code, msg = stat and s, c or code, m or msg
|
||||
end
|
||||
|
||||
return stat, code, msg
|
||||
end
|
||||
end
|
||||
|
||||
function copyr(src, dest)
|
||||
return _recurse(copy, src, dest)
|
||||
end
|
||||
|
||||
function mover(src, dest)
|
||||
local stat, code, msg = nixio.rename(src, dest)
|
||||
if not stat and code == nixio.const.EXDEV then
|
||||
stat, code, msg = _recurse(copy, src, dest)
|
||||
if stat then
|
||||
stat, code, msg = _recurse(nixio.remove, src)
|
||||
end
|
||||
end
|
||||
return stat, code, msg
|
||||
end
|
||||
|
||||
function remover(src)
|
||||
return _recurse(nixio.remove, src)
|
||||
end
|
|
@ -18,11 +18,20 @@ local getmetatable, assert, pairs = getmetatable, assert, pairs
|
|||
|
||||
module "nixio.util"
|
||||
|
||||
local BUFFERSIZE = 8096
|
||||
local BUFFERSIZE = nixio.const.buffersize
|
||||
local ZIOBLKSIZE = 65536
|
||||
local socket = nixio.meta_socket
|
||||
local tls_socket = nixio.meta_tls_socket
|
||||
local file = nixio.meta_file
|
||||
|
||||
function consume(iter)
|
||||
local tbl = {}
|
||||
for obj in iter do
|
||||
tbl[#tbl+1] = obj
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
local meta = {}
|
||||
|
||||
function meta.is_socket(self)
|
||||
|
@ -38,50 +47,53 @@ function meta.is_file(self)
|
|||
end
|
||||
|
||||
function meta.readall(self, len)
|
||||
local block, code, msg = self:read(len)
|
||||
local block, code, msg = self:read(len or BUFFERSIZE)
|
||||
|
||||
if not block then
|
||||
return "", code, msg, len
|
||||
return nil, code, msg, ""
|
||||
elseif #block == 0 then
|
||||
return "", nil, nil, len
|
||||
return "", nil, nil, ""
|
||||
end
|
||||
|
||||
local data, total = {block}, #block
|
||||
|
||||
while len > total do
|
||||
block, code, msg = self:read(len - total)
|
||||
while not len or len > total do
|
||||
block, code, msg = self:read(len and (len - total) or BUFFERSIZE)
|
||||
|
||||
if not block then
|
||||
return data, code, msg, len - #data
|
||||
return nil, code, msg, table.concat(data)
|
||||
elseif #block == 0 then
|
||||
return data, nil, nil, len - #data
|
||||
break
|
||||
end
|
||||
|
||||
data[#data+1], total = block, total + #block
|
||||
end
|
||||
|
||||
return (#data > 1 and table.concat(data) or data[1]), nil, nil, 0
|
||||
local data = #data > 1 and table.concat(data) or data[1]
|
||||
return data, nil, nil, data
|
||||
end
|
||||
meta.recvall = meta.readall
|
||||
|
||||
function meta.writeall(self, data)
|
||||
local total, block = 0
|
||||
local sent, code, msg = self:write(data)
|
||||
|
||||
if not sent then
|
||||
return total, code, msg, data
|
||||
return nil, code, msg, 0
|
||||
end
|
||||
|
||||
while sent < #data do
|
||||
block, total = data:sub(sent + 1), total + sent
|
||||
sent, code, msg = self:write(block)
|
||||
local total = sent
|
||||
|
||||
while total < #data do
|
||||
sent, code, msg = self:write(data, total)
|
||||
|
||||
if not sent then
|
||||
return total, code, msg, block
|
||||
return nil, code, msg, total
|
||||
end
|
||||
|
||||
total = total + sent
|
||||
end
|
||||
|
||||
return total + sent, nil, nil, ""
|
||||
return total, nil, nil, total
|
||||
end
|
||||
meta.sendall = meta.writeall
|
||||
|
||||
|
@ -105,9 +117,9 @@ function meta.linesource(self, limit)
|
|||
bpos = endp
|
||||
return line
|
||||
elseif #buffer < limit + bpos then
|
||||
local newblock, code = self:read(limit + bpos - #buffer)
|
||||
local newblock, code, msg = self:read(limit + bpos - #buffer)
|
||||
if not newblock then
|
||||
return nil, code
|
||||
return nil, code, msg
|
||||
elseif #newblock == 0 then
|
||||
return nil
|
||||
end
|
||||
|
@ -135,7 +147,7 @@ function meta.blocksource(self, bs, limit)
|
|||
local block, code, msg = self:read(toread)
|
||||
|
||||
if not block then
|
||||
return nil, code
|
||||
return nil, code, msg
|
||||
elseif #block == 0 then
|
||||
return nil
|
||||
else
|
||||
|
@ -162,6 +174,40 @@ function meta.sink(self, close)
|
|||
end
|
||||
end
|
||||
|
||||
function meta.copy(self, fdout, size)
|
||||
local source = self:blocksource(nil, size)
|
||||
local sink = fdout:sink()
|
||||
local sent, chunk, code, msg = 0
|
||||
|
||||
repeat
|
||||
chunk, code, msg = source()
|
||||
sink(chunk, code, msg)
|
||||
sent = chunk and (sent + #chunk) or sent
|
||||
until not chunk
|
||||
return not code and sent or nil, code, msg, sent
|
||||
end
|
||||
|
||||
function meta.copyz(self, fd, size)
|
||||
local sent, lsent, code, msg = 0
|
||||
if self:is_file() then
|
||||
if nixio.sendfile and fd:is_socket() and self:stat("type") == "reg" then
|
||||
repeat
|
||||
lsent, code, msg = nixio.sendfile(fd, self, size or ZIOBLKSIZE)
|
||||
if lsent then
|
||||
sent = sent + lsent
|
||||
size = size and (size - lsent)
|
||||
end
|
||||
until (not lsent or lsent == 0 or (size and size == 0))
|
||||
if lsent or (not lsent and sent == 0 and
|
||||
code ~= nixio.const.ENOSYS and code ~= nixio.const.EINVAL) then
|
||||
return lsent and sent, code, msg, sent
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return self:copy(fd, size)
|
||||
end
|
||||
|
||||
function tls_socket.close(self)
|
||||
return self.socket:close()
|
||||
end
|
||||
|
|
|
@ -18,16 +18,79 @@
|
|||
|
||||
#include "nixio.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#ifndef NI_MAXHOST
|
||||
#define NI_MAXHOST 1025
|
||||
#endif
|
||||
|
||||
/**
|
||||
* address pushing helper
|
||||
*/
|
||||
int nixio__addr_parse(nixio_addr *addr, struct sockaddr *saddr) {
|
||||
void *baddr;
|
||||
|
||||
addr->family = saddr->sa_family;
|
||||
if (saddr->sa_family == AF_INET) {
|
||||
struct sockaddr_in *inetaddr = (struct sockaddr_in*)saddr;
|
||||
addr->port = ntohs(inetaddr->sin_port);
|
||||
baddr = &inetaddr->sin_addr;
|
||||
} else if (saddr->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *inet6addr = (struct sockaddr_in6*)saddr;
|
||||
addr->port = ntohs(inet6addr->sin6_port);
|
||||
baddr = &inet6addr->sin6_addr;
|
||||
} else {
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!inet_ntop(saddr->sa_family, baddr, addr->host, sizeof(addr->host))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* address pulling helper
|
||||
*/
|
||||
int nixio__addr_write(nixio_addr *addr, struct sockaddr *saddr) {
|
||||
if (addr->family == AF_UNSPEC) {
|
||||
if (strchr(addr->host, ':')) {
|
||||
addr->family = AF_INET6;
|
||||
} else {
|
||||
addr->family = AF_INET;
|
||||
}
|
||||
}
|
||||
if (addr->family == AF_INET) {
|
||||
struct sockaddr_in *inetaddr = (struct sockaddr_in *)saddr;
|
||||
memset(inetaddr, 0, sizeof(struct sockaddr_in));
|
||||
|
||||
if (inet_pton(AF_INET, addr->host, &inetaddr->sin_addr) < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
inetaddr->sin_family = AF_INET;
|
||||
inetaddr->sin_port = htons((uint16_t)addr->port);
|
||||
return 0;
|
||||
} else if (addr->family == AF_INET6) {
|
||||
struct sockaddr_in6 *inet6addr = (struct sockaddr_in6 *)saddr;
|
||||
memset(inet6addr, 0, sizeof(struct sockaddr_in6));
|
||||
|
||||
if (inet_pton(AF_INET6, addr->host, &inet6addr->sin6_addr) < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
inet6addr->sin6_family = AF_INET6;
|
||||
inet6addr->sin6_port = htons((uint16_t)addr->port);
|
||||
return 0;
|
||||
} else {
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* getaddrinfo(host, family, port)
|
||||
|
@ -70,9 +133,11 @@ static int nixio_getaddrinfo(lua_State *L) {
|
|||
|
||||
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||
/* avoid duplicate results */
|
||||
#ifndef __WINNT__
|
||||
if (!port && rp->ai_socktype != SOCK_STREAM) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rp->ai_family == AF_INET || rp->ai_family == AF_INET6) {
|
||||
lua_createtable(L, 0, port ? 4 : 2);
|
||||
|
@ -101,31 +166,18 @@ static int nixio_getaddrinfo(lua_State *L) {
|
|||
lua_setfield(L, -2, "socktype");
|
||||
}
|
||||
|
||||
char ip[INET6_ADDRSTRLEN];
|
||||
void *binaddr = NULL;
|
||||
uint16_t binport = 0;
|
||||
|
||||
if (rp->ai_family == AF_INET) {
|
||||
struct sockaddr_in *v4addr = (struct sockaddr_in*)rp->ai_addr;
|
||||
binport = v4addr->sin_port;
|
||||
binaddr = (void *)&v4addr->sin_addr;
|
||||
} else if (rp->ai_family == AF_INET6) {
|
||||
struct sockaddr_in6 *v6addr = (struct sockaddr_in6*)rp->ai_addr;
|
||||
binport = v6addr->sin6_port;
|
||||
binaddr = (void *)&v6addr->sin6_addr;
|
||||
}
|
||||
|
||||
if (!inet_ntop(rp->ai_family, binaddr, ip, sizeof(ip))) {
|
||||
nixio_addr addr;
|
||||
if (nixio__addr_parse(&addr, rp->ai_addr)) {
|
||||
freeaddrinfo(result);
|
||||
return nixio__perror(L);
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
|
||||
if (port) {
|
||||
lua_pushinteger(L, ntohs(binport));
|
||||
lua_pushinteger(L, addr.port);
|
||||
lua_setfield(L, -2, "port");
|
||||
}
|
||||
|
||||
lua_pushstring(L, ip);
|
||||
lua_pushstring(L, addr.host);
|
||||
lua_setfield(L, -2, "address");
|
||||
lua_rawseti(L, -2, i++);
|
||||
}
|
||||
|
@ -140,37 +192,29 @@ static int nixio_getaddrinfo(lua_State *L) {
|
|||
* getnameinfo(address, family)
|
||||
*/
|
||||
static int nixio_getnameinfo(lua_State *L) {
|
||||
const char *ip = luaL_checklstring(L, 1, NULL);
|
||||
const char *family = luaL_optlstring(L, 2, "inet", NULL);
|
||||
const char *ip = luaL_checkstring(L, 1);
|
||||
const char *family = luaL_optstring(L, 2, NULL);
|
||||
char host[NI_MAXHOST];
|
||||
|
||||
struct sockaddr *addr = NULL;
|
||||
socklen_t alen = 0;
|
||||
int res;
|
||||
struct sockaddr_storage saddr;
|
||||
nixio_addr addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
strncpy(addr.host, ip, sizeof(addr.host) - 1);
|
||||
|
||||
if (!strcmp(family, "inet")) {
|
||||
struct sockaddr_in inetaddr;
|
||||
memset(&inetaddr, 0, sizeof(inetaddr));
|
||||
inetaddr.sin_family = AF_INET;
|
||||
if (inet_pton(AF_INET, ip, &inetaddr.sin_addr) < 1) {
|
||||
return luaL_argerror(L, 1, "invalid address");
|
||||
}
|
||||
alen = sizeof(inetaddr);
|
||||
addr = (struct sockaddr *)&inetaddr;
|
||||
if (!family) {
|
||||
addr.family = AF_UNSPEC;
|
||||
} else if (!strcmp(family, "inet")) {
|
||||
addr.family = AF_INET;
|
||||
} else if (!strcmp(family, "inet6")) {
|
||||
struct sockaddr_in6 inet6addr;
|
||||
memset(&inet6addr, 0, sizeof(inet6addr));
|
||||
inet6addr.sin6_family = AF_INET6;
|
||||
if (inet_pton(AF_INET6, ip, &inet6addr.sin6_addr) < 1) {
|
||||
return luaL_argerror(L, 1, "invalid address");
|
||||
}
|
||||
alen = sizeof(inet6addr);
|
||||
addr = (struct sockaddr *)&inet6addr;
|
||||
addr.family = AF_INET6;
|
||||
} else {
|
||||
return luaL_argerror(L, 2, "supported values: inet, inet6");
|
||||
}
|
||||
|
||||
res = getnameinfo(addr, alen, host, sizeof(host), NULL, 0, NI_NAMEREQD);
|
||||
nixio__addr_write(&addr, (struct sockaddr *)&saddr);
|
||||
|
||||
int res = getnameinfo((struct sockaddr *)&saddr, sizeof(saddr),
|
||||
host, sizeof(host), NULL, 0, NI_NAMEREQD);
|
||||
if (res) {
|
||||
lua_pushnil(L);
|
||||
lua_pushinteger(L, res);
|
||||
|
@ -182,60 +226,42 @@ static int nixio_getnameinfo(lua_State *L) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* getsockname() / getpeername() helper
|
||||
*/
|
||||
static int nixio_sock__getname(lua_State *L, int sock) {
|
||||
int sockfd = nixio__checksockfd(L);
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen = sizeof(addr);
|
||||
char ipaddr[INET6_ADDRSTRLEN];
|
||||
void *binaddr;
|
||||
uint16_t port;
|
||||
|
||||
if (sock) {
|
||||
if (getsockname(sockfd, (struct sockaddr*)&addr, &addrlen)) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
} else {
|
||||
if (getpeername(sockfd, (struct sockaddr*)&addr, &addrlen)) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
}
|
||||
|
||||
if (addr.ss_family == AF_INET) {
|
||||
struct sockaddr_in *inetaddr = (struct sockaddr_in*)&addr;
|
||||
port = inetaddr->sin_port;
|
||||
binaddr = &inetaddr->sin_addr;
|
||||
} else if (addr.ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *inet6addr = (struct sockaddr_in6*)&addr;
|
||||
port = inet6addr->sin6_port;
|
||||
binaddr = &inet6addr->sin6_addr;
|
||||
} else {
|
||||
return luaL_error(L, "unknown address family");
|
||||
}
|
||||
|
||||
if (!inet_ntop(addr.ss_family, binaddr, ipaddr, sizeof(ipaddr))) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
lua_pushstring(L, ipaddr);
|
||||
lua_pushinteger(L, ntohs(port));
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* getsockname()
|
||||
*/
|
||||
static int nixio_sock_getsockname(lua_State *L) {
|
||||
return nixio_sock__getname(L, 1);
|
||||
int sockfd = nixio__checksockfd(L);
|
||||
struct sockaddr_storage saddr;
|
||||
socklen_t addrlen = sizeof(saddr);
|
||||
nixio_addr addr;
|
||||
|
||||
if (getsockname(sockfd, (struct sockaddr*)&saddr, &addrlen) ||
|
||||
nixio__addr_parse(&addr, (struct sockaddr*)&saddr)) {
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
|
||||
lua_pushstring(L, addr.host);
|
||||
lua_pushnumber(L, addr.port);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* getpeername()
|
||||
*/
|
||||
static int nixio_sock_getpeername(lua_State *L) {
|
||||
return nixio_sock__getname(L, 0);
|
||||
int sockfd = nixio__checksockfd(L);
|
||||
struct sockaddr_storage saddr;
|
||||
socklen_t addrlen = sizeof(saddr);
|
||||
nixio_addr addr;
|
||||
|
||||
if (getpeername(sockfd, (struct sockaddr*)&saddr, &addrlen) ||
|
||||
nixio__addr_parse(&addr, (struct sockaddr*)&saddr)) {
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
|
||||
lua_pushstring(L, addr.host);
|
||||
lua_pushnumber(L, addr.port);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
|
|
297
libs/nixio/src/axtls-compat.c
Normal file
297
libs/nixio/src/axtls-compat.c
Normal file
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
* Copyright (c) 2007, Cameron Rich
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Enable a subset of openssl compatible functions. We don't aim to be 100%
|
||||
* compatible - just to be able to do basic ports etc.
|
||||
*
|
||||
* Only really tested on mini_httpd, so I'm not too sure how extensive this
|
||||
* port is.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "ssl.h"
|
||||
|
||||
static char *key_password = NULL;
|
||||
|
||||
void *SSLv23_server_method(void) { return NULL; }
|
||||
void *SSLv3_server_method(void) { return NULL; }
|
||||
void *TLSv1_server_method(void) { return NULL; }
|
||||
void *SSLv23_client_method(void) { return NULL; }
|
||||
void *SSLv3_client_method(void) { return NULL; }
|
||||
void *TLSv1_client_method(void) { return NULL; }
|
||||
void *SSLv23_method(void) { return NULL; }
|
||||
void *TLSv1_method(void) { return NULL; }
|
||||
|
||||
SSL_CTX * SSL_CTX_new(void *meth)
|
||||
{
|
||||
SSL_CTX *ssl_ctx = ssl_ctx_new(SSL_SERVER_VERIFY_LATER, 5);
|
||||
return ssl_ctx;
|
||||
}
|
||||
|
||||
void SSL_CTX_free(SSL_CTX * ssl_ctx)
|
||||
{
|
||||
ssl_ctx_free(ssl_ctx);
|
||||
}
|
||||
|
||||
SSL * SSL_new(SSL_CTX *ssl_ctx)
|
||||
{
|
||||
SSL *ssl;
|
||||
|
||||
ssl = ssl_new(ssl_ctx, -1); /* fd is set later */
|
||||
|
||||
return ssl;
|
||||
}
|
||||
|
||||
int SSL_set_fd(SSL *s, int fd)
|
||||
{
|
||||
s->client_fd = fd;
|
||||
return 1; /* always succeeds */
|
||||
}
|
||||
|
||||
int SSL_accept(SSL *ssl)
|
||||
{
|
||||
ssl->next_state = HS_CLIENT_HELLO;
|
||||
while (ssl_read(ssl, NULL) == SSL_OK)
|
||||
{
|
||||
if (ssl->next_state == HS_CLIENT_HELLO)
|
||||
return 1; /* we're done */
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int SSL_connect(SSL *ssl)
|
||||
{
|
||||
SET_SSL_FLAG(SSL_IS_CLIENT);
|
||||
int stat = do_client_connect(ssl);
|
||||
ssl_display_error(stat);
|
||||
return (stat == SSL_OK) ? 1 : -1;
|
||||
}
|
||||
|
||||
void SSL_free(SSL *ssl)
|
||||
{
|
||||
ssl_free(ssl);
|
||||
}
|
||||
|
||||
int SSL_read(SSL *ssl, void *buf, int num)
|
||||
{
|
||||
uint8_t *read_buf;
|
||||
int ret;
|
||||
|
||||
while ((ret = ssl_read(ssl, &read_buf)) == SSL_OK);
|
||||
|
||||
if (ret > SSL_OK)
|
||||
{
|
||||
memcpy(buf, read_buf, ret > num ? num : ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SSL_write(SSL *ssl, const void *buf, int num)
|
||||
{
|
||||
return ssl_write(ssl, buf, num);
|
||||
}
|
||||
|
||||
int SSL_CTX_use_certificate_file(SSL_CTX *ssl_ctx, const char *file, int type)
|
||||
{
|
||||
return (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, file, NULL) == SSL_OK);
|
||||
}
|
||||
|
||||
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ssl_ctx, const char *file, int type)
|
||||
{
|
||||
return (ssl_obj_load(ssl_ctx, SSL_OBJ_RSA_KEY, file, key_password) == SSL_OK);
|
||||
}
|
||||
|
||||
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ssl_ctx, int len, const uint8_t *d)
|
||||
{
|
||||
return (ssl_obj_memory_load(ssl_ctx,
|
||||
SSL_OBJ_X509_CERT, d, len, NULL) == SSL_OK);
|
||||
}
|
||||
|
||||
int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
|
||||
unsigned int sid_ctx_len)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_CTX_use_certificate_chain_file(SSL_CTX *ssl_ctx, const char *file)
|
||||
{
|
||||
return (ssl_obj_load(ssl_ctx,
|
||||
SSL_OBJ_X509_CERT, file, NULL) == SSL_OK);
|
||||
}
|
||||
|
||||
int SSL_shutdown(SSL *ssl)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*** get/set session ***/
|
||||
SSL_SESSION *SSL_get1_session(SSL *ssl)
|
||||
{
|
||||
return (SSL_SESSION *)ssl_get_session_id(ssl); /* note: wrong cast */
|
||||
}
|
||||
|
||||
int SSL_set_session(SSL *ssl, SSL_SESSION *session)
|
||||
{
|
||||
memcpy(ssl->session_id, (uint8_t *)session, SSL_SESSION_ID_SIZE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void SSL_SESSION_free(SSL_SESSION *session) { }
|
||||
/*** end get/set session ***/
|
||||
|
||||
long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
|
||||
int (*verify_callback)(int, void *)) {
|
||||
if (mode & SSL_VERIFY_PEER) {
|
||||
ctx->options &= ~SSL_SERVER_VERIFY_LATER;
|
||||
ctx->options |= SSL_CLIENT_AUTHENTICATION;
|
||||
} else {
|
||||
ctx->options |= SSL_SERVER_VERIFY_LATER;
|
||||
ctx->options &= ~SSL_CLIENT_AUTHENTICATION;
|
||||
}
|
||||
}
|
||||
|
||||
void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth) { }
|
||||
|
||||
int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
|
||||
const char *CApath)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void *SSL_load_client_CA_file(const char *file)
|
||||
{
|
||||
return (void *)file;
|
||||
}
|
||||
|
||||
void SSL_CTX_set_client_CA_list(SSL_CTX *ssl_ctx, void *file)
|
||||
{
|
||||
|
||||
ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, (const char *)file, NULL);
|
||||
}
|
||||
|
||||
void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, void *cb) { }
|
||||
|
||||
void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u)
|
||||
{
|
||||
key_password = (char *)u;
|
||||
}
|
||||
|
||||
int SSL_peek(SSL *ssl, void *buf, int num)
|
||||
{
|
||||
memcpy(buf, ssl->bm_data, num);
|
||||
return num;
|
||||
}
|
||||
|
||||
void SSL_set_bio(SSL *ssl, void *rbio, void *wbio) { }
|
||||
|
||||
long SSL_get_verify_result(const SSL *ssl)
|
||||
{
|
||||
return ssl_handshake_status(ssl);
|
||||
}
|
||||
|
||||
int SSL_state(SSL *ssl)
|
||||
{
|
||||
return 0x03; // ok state
|
||||
}
|
||||
|
||||
/** end of could do better list */
|
||||
|
||||
void *SSL_get_peer_certificate(const SSL *ssl)
|
||||
{
|
||||
return &ssl->ssl_ctx->certs[0];
|
||||
}
|
||||
|
||||
int SSL_clear(SSL *ssl)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int SSL_CTX_check_private_key(const SSL_CTX *ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_CTX_set_cipher_list(SSL_CTX *s, const char *str)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SSL_get_error(const SSL *ssl, int ret)
|
||||
{
|
||||
ssl_display_error(ret);
|
||||
return ret; /* TODO: return proper return code */
|
||||
}
|
||||
|
||||
void SSL_CTX_set_options(SSL_CTX *ssl_ctx, int option) {}
|
||||
int SSL_library_init(void ) { return 1; }
|
||||
void SSL_load_error_strings(void ) {}
|
||||
void ERR_print_errors_fp(FILE *fp) {}
|
||||
|
||||
long SSL_CTX_get_timeout(const SSL_CTX *ssl_ctx) {
|
||||
return CONFIG_SSL_EXPIRY_TIME*3600; }
|
||||
long SSL_CTX_set_timeout(SSL_CTX *ssl_ctx, long t) {
|
||||
return SSL_CTX_get_timeout(ssl_ctx); }
|
||||
void BIO_printf(FILE *f, const char *format, ...)
|
||||
{
|
||||
va_list(ap);
|
||||
va_start(ap, format);
|
||||
vfprintf(f, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void* BIO_s_null(void) { return NULL; }
|
||||
FILE *BIO_new(bio_func_type_t func)
|
||||
{
|
||||
if (func == BIO_s_null)
|
||||
return fopen("/dev/null", "r");
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE *BIO_new_fp(FILE *stream, int close_flag) { return stream; }
|
||||
int BIO_free(FILE *a) { if (a != stdout && a != stderr) fclose(a); return 1; }
|
149
libs/nixio/src/axtls-compat.h
Normal file
149
libs/nixio/src/axtls-compat.h
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright (c) 2007, Cameron Rich
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of the axTLS project nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Enable a subset of openssl compatible functions. We don't aim to be 100%
|
||||
* compatible - just to be able to do basic ports etc.
|
||||
*
|
||||
* Only really tested on mini_httpd, so I'm not too sure how extensive this
|
||||
* port is.
|
||||
*/
|
||||
|
||||
#include "nixio.h"
|
||||
#include "config.h"
|
||||
|
||||
#define WITH_AXTLS 1
|
||||
#define WITHOUT_OPENSSL 1
|
||||
#define SSL_OP_NO_SSLv3 0x02000000L
|
||||
#define SSL_OP_NO_SSLv2 0x01000000L
|
||||
#define SSL_FILETYPE_PEM 1
|
||||
#define SSL_VERIFY_NONE 0x00
|
||||
#define SSL_VERIFY_PEER 0x01
|
||||
#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
|
||||
#define SSL_VERIFY_CLIENT_ONCE 0x03
|
||||
#define MD5_DIGEST_LENGTH 16
|
||||
#define SHA_DIGEST_LENGTH 20
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "ssl.h"
|
||||
|
||||
typedef SHA1_CTX SHA_CTX;
|
||||
|
||||
void *SSLv23_server_method(void);
|
||||
void *SSLv3_server_method(void);
|
||||
void *TLSv1_server_method(void);
|
||||
void *SSLv23_client_method(void);
|
||||
void *SSLv3_client_method(void);
|
||||
void *TLSv1_client_method(void);
|
||||
void *SSLv23_method(void);
|
||||
void *TLSv1_method(void);
|
||||
|
||||
|
||||
typedef void * (*ssl_func_type_t)(void);
|
||||
typedef void * (*bio_func_type_t)(void);
|
||||
|
||||
SSL_CTX * SSL_CTX_new(void *meth);
|
||||
void SSL_CTX_free(SSL_CTX * ssl_ctx);
|
||||
SSL * SSL_new(SSL_CTX *ssl_ctx);
|
||||
int SSL_set_fd(SSL *s, int fd);
|
||||
int SSL_accept(SSL *ssl);
|
||||
int SSL_connect(SSL *ssl);
|
||||
void SSL_free(SSL *ssl);
|
||||
int SSL_read(SSL *ssl, void *buf, int num);
|
||||
int SSL_write(SSL *ssl, const void *buf, int num);
|
||||
int SSL_CTX_use_certificate_file(SSL_CTX *ssl_ctx, const char *file, int type);
|
||||
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ssl_ctx, const char *file, int type);
|
||||
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ssl_ctx, int len, const uint8_t *d);
|
||||
int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
|
||||
unsigned int sid_ctx_len);
|
||||
int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
|
||||
int SSL_CTX_use_certificate_chain_file(SSL_CTX *ssl_ctx, const char *file);
|
||||
int SSL_shutdown(SSL *ssl);
|
||||
|
||||
/*** get/set session ***/
|
||||
SSL_SESSION *SSL_get1_session(SSL *ssl);
|
||||
int SSL_set_session(SSL *ssl, SSL_SESSION *session);
|
||||
void SSL_SESSION_free(SSL_SESSION *session);
|
||||
/*** end get/set session ***/
|
||||
|
||||
long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
|
||||
void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
|
||||
int (*verify_callback)(int, void *));
|
||||
|
||||
void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth);
|
||||
|
||||
int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
|
||||
const char *CApath);
|
||||
|
||||
void *SSL_load_client_CA_file(const char *file);
|
||||
|
||||
void SSL_CTX_set_client_CA_list(SSL_CTX *ssl_ctx, void *file);
|
||||
|
||||
void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, void *cb);
|
||||
|
||||
void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);
|
||||
|
||||
int SSL_peek(SSL *ssl, void *buf, int num);
|
||||
|
||||
void SSL_set_bio(SSL *ssl, void *rbio, void *wbio);
|
||||
|
||||
long SSL_get_verify_result(const SSL *ssl);
|
||||
|
||||
int SSL_state(SSL *ssl);
|
||||
|
||||
/** end of could do better list */
|
||||
|
||||
void *SSL_get_peer_certificate(const SSL *ssl);
|
||||
|
||||
int SSL_clear(SSL *ssl);
|
||||
|
||||
|
||||
int SSL_CTX_check_private_key(const SSL_CTX *ctx);
|
||||
|
||||
int SSL_CTX_set_cipher_list(SSL_CTX *s, const char *str);
|
||||
|
||||
int SSL_get_error(const SSL *ssl, int ret);
|
||||
|
||||
void SSL_CTX_set_options(SSL_CTX *ssl_ctx, int option);
|
||||
int SSL_library_init(void );
|
||||
void SSL_load_error_strings(void );
|
||||
void ERR_print_errors_fp(FILE *fp);
|
||||
|
||||
long SSL_CTX_get_timeout(const SSL_CTX *ssl_ctx);
|
||||
long SSL_CTX_set_timeout(SSL_CTX *ssl_ctx, long t);
|
||||
void BIO_printf(FILE *f, const char *format, ...);
|
||||
|
||||
void* BIO_s_null(void);
|
||||
FILE *BIO_new(bio_func_type_t func);
|
||||
|
||||
FILE *BIO_new_fp(FILE *stream, int close_flag);
|
||||
int BIO_free(FILE *a);
|
313
libs/nixio/src/binary.c
Normal file
313
libs/nixio/src/binary.c
Normal file
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
* nixio - Linux I/O library for lua
|
||||
*
|
||||
* Copyright (C) 2009 Steven Barth <steven@midlink.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "nixio.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
static char nixio__bin2hex[] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
|
||||
};
|
||||
|
||||
static unsigned char nixio__b64encode_tbl[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
static unsigned char nixio__b64decode_tbl[] = {
|
||||
0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36,
|
||||
0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff,
|
||||
0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01,
|
||||
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
|
||||
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
|
||||
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b,
|
||||
0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
|
||||
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
|
||||
0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33
|
||||
};
|
||||
|
||||
static const uint32_t nixio__crc32_tbl[] = {
|
||||
0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U,
|
||||
0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U,
|
||||
0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U,
|
||||
0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU,
|
||||
0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U,
|
||||
0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U,
|
||||
0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U,
|
||||
0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU,
|
||||
0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U,
|
||||
0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU,
|
||||
0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U,
|
||||
0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U,
|
||||
0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U,
|
||||
0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU,
|
||||
0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU,
|
||||
0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U,
|
||||
0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU,
|
||||
0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U,
|
||||
0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U,
|
||||
0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U,
|
||||
0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU,
|
||||
0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U,
|
||||
0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U,
|
||||
0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU,
|
||||
0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U,
|
||||
0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U,
|
||||
0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U,
|
||||
0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U,
|
||||
0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U,
|
||||
0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU,
|
||||
0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU,
|
||||
0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U,
|
||||
0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U,
|
||||
0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU,
|
||||
0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU,
|
||||
0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U,
|
||||
0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU,
|
||||
0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U,
|
||||
0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU,
|
||||
0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U,
|
||||
0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU,
|
||||
0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U,
|
||||
0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U,
|
||||
0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU,
|
||||
0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U,
|
||||
0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U,
|
||||
0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U,
|
||||
0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U,
|
||||
0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U,
|
||||
0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U,
|
||||
0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU,
|
||||
0x2d02ef8dU
|
||||
};
|
||||
|
||||
static int nixio_bin_crc32(lua_State *L) {
|
||||
size_t len;
|
||||
const char *buffer = luaL_checklstring(L, 1, &len);
|
||||
uint32_t value = luaL_optnumber(L, 2, 0);
|
||||
|
||||
value = ~value;
|
||||
for (size_t i=0; i<len; i++) {
|
||||
value = nixio__crc32_tbl[(value ^ buffer[i]) & 0xffU ] ^ (value >> 8);
|
||||
}
|
||||
|
||||
lua_pushinteger(L, (int)(value ^ 0xffffffffU));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_bin_hexlify(lua_State *L) {
|
||||
size_t len, lenout;
|
||||
luaL_checktype(L, 1, LUA_TSTRING);
|
||||
const unsigned char *data = (unsigned char*)lua_tolstring(L, 1, &len);
|
||||
|
||||
if (len == 0) {
|
||||
lua_pushvalue(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lenout = len * 2;
|
||||
luaL_argcheck(L, lenout > len, 1, "size overflow");
|
||||
|
||||
char *out = malloc(lenout);
|
||||
if (!out) {
|
||||
return luaL_error(L, NIXIO_OOM);
|
||||
}
|
||||
|
||||
for (size_t i=0; i < len; i++) {
|
||||
out[2*i] = nixio__bin2hex[(data[i] & 0xf0) >> 4];
|
||||
out[2*i+1] = nixio__bin2hex[(data[i] & 0x0f)];
|
||||
}
|
||||
|
||||
lua_pushlstring(L, out, lenout);
|
||||
free(out);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int nixio_bin_unhexlify(lua_State *L) {
|
||||
size_t len, lenout;
|
||||
const char *data = luaL_checklstring(L, 1, &len);
|
||||
|
||||
if (len == 0) {
|
||||
lua_pushvalue(L, 1);
|
||||
return 1;
|
||||
} else if (len % 2) {
|
||||
errno = EINVAL;
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
lenout = len / 2;
|
||||
char *out = malloc(lenout);
|
||||
if (!out) {
|
||||
return luaL_error(L, NIXIO_OOM);
|
||||
}
|
||||
|
||||
for (size_t i=0; i < lenout; i++) {
|
||||
char c = data[2*i];
|
||||
if (c >= '0' && c <= '9') {
|
||||
out[i] = (c - '0') << 4;
|
||||
} else if (c >= 'a' && c <= 'f') {
|
||||
out[i] = (c - 'a' + 10) << 4;
|
||||
} else if (data[2*i] >= 'A' && c <= 'F') {
|
||||
out[i] = (c - 'A' + 10) << 4;
|
||||
} else {
|
||||
free(out);
|
||||
errno = EINVAL;
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
c = data[2*i+1];
|
||||
if (c >= '0' && c <= '9') {
|
||||
out[i] += c - '0';
|
||||
} else if (c >= 'a' && c <= 'f') {
|
||||
out[i] += c - 'a' + 10;
|
||||
} else if (c >= 'A' && c <= 'F') {
|
||||
out[i] += c - 'A' + 10;
|
||||
} else {
|
||||
free(out);
|
||||
errno = EINVAL;
|
||||
return nixio__perror(L);
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushlstring(L, out, lenout);
|
||||
free(out);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_bin_b64encode(lua_State *L) {
|
||||
size_t len, lenout, pad, i;
|
||||
const char *data = luaL_checklstring(L, 1, &len);
|
||||
|
||||
lenout = len / 3;
|
||||
lenout *= 4;
|
||||
|
||||
pad = len % 3;
|
||||
|
||||
if (len == 0) {
|
||||
lua_pushvalue(L, 1);
|
||||
return 1;
|
||||
} else if (pad) {
|
||||
lenout += 4;
|
||||
}
|
||||
|
||||
luaL_argcheck(L, lenout > len, 1, "size overflow");
|
||||
|
||||
char *out = malloc(lenout);
|
||||
if (!out) {
|
||||
return luaL_error(L, NIXIO_OOM);
|
||||
}
|
||||
|
||||
char *o = out;
|
||||
for (i = 0; i < len; i += 3) {
|
||||
uint32_t cv = (data[i] << 16) | (data[i+1] << 8) | data[i+2];
|
||||
*(o+3) = nixio__b64encode_tbl[ cv & 0x3f];
|
||||
*(o+2) = nixio__b64encode_tbl[(cv >> 6) & 0x3f];
|
||||
*(o+1) = nixio__b64encode_tbl[(cv >> 12) & 0x3f];
|
||||
*o = nixio__b64encode_tbl[(cv >> 18) & 0x3f];
|
||||
o += 4;
|
||||
}
|
||||
|
||||
if (pad) {
|
||||
uint32_t cv = data[len-pad] << 16;
|
||||
*(o-1) = '=';
|
||||
*(o-2) = '=';
|
||||
if (pad == 2) {
|
||||
cv |= data[len-pad+1] << 8;
|
||||
*(o-2) = nixio__b64encode_tbl[(cv >> 6) & 0x3f];
|
||||
}
|
||||
*(o-3) = nixio__b64encode_tbl[(cv >> 12) & 0x3f];
|
||||
*(o-4) = nixio__b64encode_tbl[(cv >> 18) & 0x3f];
|
||||
}
|
||||
|
||||
lua_pushlstring(L, out, lenout);
|
||||
free(out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_bin_b64decode(lua_State *L) {
|
||||
size_t len, lenout, i;
|
||||
const char *dt = luaL_checklstring(L, 1, &len);
|
||||
|
||||
if (len == 0) {
|
||||
lua_pushvalue(L, 1);
|
||||
return 1;
|
||||
} else if (len % 4) {
|
||||
errno = EINVAL;
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
lenout = len / 4 * 3;
|
||||
|
||||
unsigned char *out = malloc(lenout);
|
||||
if (!out) {
|
||||
return luaL_error(L, NIXIO_OOM);
|
||||
}
|
||||
|
||||
unsigned char *o = out;
|
||||
for (i = 0; i < len; i += 4) {
|
||||
uint32_t cv = 0;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
unsigned char c = dt[i + j] - 43;
|
||||
if (c > 79 || (c = nixio__b64decode_tbl[c]) == 0xff) {
|
||||
free(out);
|
||||
errno = EINVAL;
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
cv |= c;
|
||||
if (j != 3) {
|
||||
cv <<= 6;
|
||||
}
|
||||
}
|
||||
|
||||
*(o+2) = (unsigned char)(cv & 0xff);
|
||||
*(o+1) = (unsigned char)((cv >> 8) & 0xff);
|
||||
*o = (unsigned char)((cv >> 16) & 0xff);
|
||||
o += 3;
|
||||
}
|
||||
|
||||
if (dt[len-1] == '=') {
|
||||
lenout--;
|
||||
}
|
||||
|
||||
if (dt[len-2] == '=') {
|
||||
lenout--;
|
||||
}
|
||||
|
||||
lua_pushlstring(L, (char*)out, lenout);
|
||||
free(out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* module table */
|
||||
static const luaL_reg R[] = {
|
||||
{"hexlify", nixio_bin_hexlify},
|
||||
{"unhexlify", nixio_bin_unhexlify},
|
||||
{"crc32", nixio_bin_crc32},
|
||||
{"b64encode", nixio_bin_b64encode},
|
||||
{"b64decode", nixio_bin_b64decode},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
void nixio_open_bin(lua_State *L) {
|
||||
lua_newtable(L);
|
||||
luaL_register(L, NULL, R);
|
||||
lua_setfield(L, -2, "bin");
|
||||
}
|
|
@ -18,15 +18,11 @@
|
|||
|
||||
#include "nixio.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/un.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/**
|
||||
* connect()/bind() shortcut
|
||||
*/
|
||||
|
@ -87,6 +83,9 @@ static int nixio__bind_connect(lua_State *L, int do_bind) {
|
|||
}
|
||||
|
||||
if (do_bind) {
|
||||
int one = 1;
|
||||
setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char*)&one, sizeof(one));
|
||||
status = bind(sock->fd, rp->ai_addr, rp->ai_addrlen);
|
||||
} else {
|
||||
do {
|
||||
|
@ -103,7 +102,11 @@ static int nixio__bind_connect(lua_State *L, int do_bind) {
|
|||
}
|
||||
|
||||
do {
|
||||
#ifndef __WINNT__
|
||||
clstat = close(sock->fd);
|
||||
#else
|
||||
clstat = closesocket(sock->fd);
|
||||
#endif
|
||||
} while (clstat == -1 && errno == EINTR);
|
||||
}
|
||||
|
||||
|
@ -111,7 +114,7 @@ static int nixio__bind_connect(lua_State *L, int do_bind) {
|
|||
|
||||
/* on failure */
|
||||
if (status) {
|
||||
return nixio__perror(L);
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
|
||||
luaL_getmetatable(L, NIXIO_META);
|
||||
|
@ -183,6 +186,7 @@ static int nixio_sock__bind_connect(lua_State *L, int do_bind) {
|
|||
}
|
||||
|
||||
freeaddrinfo(result);
|
||||
#ifndef __WINNT__
|
||||
} else if (sock->domain == AF_UNIX) {
|
||||
size_t pathlen;
|
||||
const char *path = luaL_checklstring(L, 2, &pathlen);
|
||||
|
@ -200,10 +204,11 @@ static int nixio_sock__bind_connect(lua_State *L, int do_bind) {
|
|||
sizeof(addr));
|
||||
} while (status == -1 && errno == EINTR);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
return luaL_error(L, "not supported");
|
||||
}
|
||||
return nixio__pstatus(L, !status);
|
||||
return nixio__pstatus_s(L, !status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -225,8 +230,8 @@ static int nixio_sock_connect(lua_State *L) {
|
|||
*/
|
||||
static int nixio_sock_listen(lua_State *L) {
|
||||
int sockfd = nixio__checksockfd(L);
|
||||
lua_Integer backlog = luaL_checkinteger(L, 2);
|
||||
return nixio__pstatus(L, !listen(sockfd, backlog));
|
||||
int backlog = luaL_checkinteger(L, 2);
|
||||
return nixio__pstatus_s(L, !listen(sockfd, backlog));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -234,18 +239,16 @@ static int nixio_sock_listen(lua_State *L) {
|
|||
*/
|
||||
static int nixio_sock_accept(lua_State *L) {
|
||||
nixio_sock *sock = nixio__checksock(L);
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen = sizeof(addr);
|
||||
char ipaddr[INET6_ADDRSTRLEN];
|
||||
void *binaddr;
|
||||
uint16_t port;
|
||||
struct sockaddr_storage saddr;
|
||||
nixio_addr addr;
|
||||
socklen_t saddrlen = sizeof(saddr);
|
||||
int newfd;
|
||||
|
||||
do {
|
||||
newfd = accept(sock->fd, (struct sockaddr *)&addr, &addrlen);
|
||||
newfd = accept(sock->fd, (struct sockaddr *)&saddr, &saddrlen);
|
||||
} while (newfd == -1 && errno == EINTR);
|
||||
if (newfd < 0) {
|
||||
return nixio__perror(L);
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
|
||||
/* create userdata */
|
||||
|
@ -256,25 +259,13 @@ static int nixio_sock_accept(lua_State *L) {
|
|||
memcpy(clsock, sock, sizeof(clsock));
|
||||
clsock->fd = newfd;
|
||||
|
||||
if (addr.ss_family == AF_INET) {
|
||||
struct sockaddr_in *inetaddr = (struct sockaddr_in*)&addr;
|
||||
port = inetaddr->sin_port;
|
||||
binaddr = &inetaddr->sin_addr;
|
||||
} else if (addr.ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *inet6addr = (struct sockaddr_in6*)&addr;
|
||||
port = inet6addr->sin6_port;
|
||||
binaddr = &inet6addr->sin6_addr;
|
||||
if (!nixio__addr_parse(&addr, (struct sockaddr *)&saddr)) {
|
||||
lua_pushstring(L, addr.host);
|
||||
lua_pushnumber(L, addr.port);
|
||||
return 3;
|
||||
} else {
|
||||
return luaL_error(L, "unknown address family");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!inet_ntop(addr.ss_family, binaddr, ipaddr, sizeof(ipaddr))) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
lua_pushstring(L, ipaddr);
|
||||
lua_pushinteger(L, ntohs(port));
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* module table */
|
||||
|
|
125
libs/nixio/src/bit.c
Normal file
125
libs/nixio/src/bit.c
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* nixio - Linux I/O library for lua
|
||||
*
|
||||
* Copyright (C) 2009 Steven Barth <steven@midlink.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "nixio.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* 52 bit maximum precision */
|
||||
#define NIXIO_BIT_BMAX 52
|
||||
#define NIXIO_BIT_NMAX 0xfffffffffffff
|
||||
|
||||
#define NIXIO_BIT_XOP(BIT_XOP) \
|
||||
uint64_t oper = luaL_checknumber(L, 1); \
|
||||
const int args = lua_gettop(L); \
|
||||
\
|
||||
for (int i = 2; i <= args; i++) { \
|
||||
uint64_t oper2 = luaL_checknumber(L, i); \
|
||||
oper BIT_XOP oper2; \
|
||||
} \
|
||||
\
|
||||
lua_pushnumber(L, oper); \
|
||||
return 1; \
|
||||
|
||||
|
||||
static int nixio_bit_or(lua_State *L) {
|
||||
NIXIO_BIT_XOP(|=);
|
||||
}
|
||||
|
||||
static int nixio_bit_and(lua_State *L) {
|
||||
NIXIO_BIT_XOP(&=);
|
||||
}
|
||||
|
||||
static int nixio_bit_xor(lua_State *L) {
|
||||
NIXIO_BIT_XOP(^=);
|
||||
}
|
||||
|
||||
static int nixio_bit_unset(lua_State *L) {
|
||||
NIXIO_BIT_XOP(&= ~);
|
||||
}
|
||||
|
||||
static int nixio_bit_not(lua_State *L) {
|
||||
lua_pushnumber(L, (~((uint64_t)luaL_checknumber(L, 1))) & NIXIO_BIT_NMAX);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_bit_shl(lua_State *L) {
|
||||
uint64_t oper = luaL_checknumber(L, 1);
|
||||
oper <<= luaL_checkinteger(L, 2);
|
||||
if (oper > NIXIO_BIT_NMAX) {
|
||||
return luaL_error(L, "arithmetic overflow");
|
||||
} else {
|
||||
lua_pushnumber(L, oper);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int nixio_bit_ashr(lua_State *L) {
|
||||
int64_t oper = luaL_checknumber(L, 1);
|
||||
lua_pushnumber(L, oper >> luaL_checkinteger(L, 2));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_bit_shr(lua_State *L) {
|
||||
uint64_t oper = luaL_checknumber(L, 1);
|
||||
lua_pushnumber(L, oper >> luaL_checkinteger(L, 2));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_bit_div(lua_State *L) {
|
||||
NIXIO_BIT_XOP(/=);
|
||||
}
|
||||
|
||||
static int nixio_bit_check(lua_State *L) {
|
||||
uint64_t oper = luaL_checknumber(L, 1);
|
||||
uint64_t oper2 = luaL_checknumber(L, 2);
|
||||
lua_pushboolean(L, (oper & oper2) == oper2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_bit_cast(lua_State *L) {
|
||||
lua_pushnumber(L, ((uint64_t)luaL_checknumber(L, 1)) & NIXIO_BIT_NMAX);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* module table */
|
||||
static const luaL_reg R[] = {
|
||||
{"bor", nixio_bit_or},
|
||||
{"set", nixio_bit_or},
|
||||
{"band", nixio_bit_and},
|
||||
{"bxor", nixio_bit_xor},
|
||||
{"unset", nixio_bit_unset},
|
||||
{"bnot", nixio_bit_not},
|
||||
{"rshift", nixio_bit_shr},
|
||||
{"arshift", nixio_bit_ashr},
|
||||
{"lshift", nixio_bit_shl},
|
||||
{"div", nixio_bit_div},
|
||||
{"check", nixio_bit_check},
|
||||
{"cast", nixio_bit_cast},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void nixio_open_bit(lua_State *L) {
|
||||
lua_newtable(L);
|
||||
luaL_register(L, NULL, R);
|
||||
lua_pushnumber(L, NIXIO_BIT_BMAX);
|
||||
lua_setfield(L, -2, "bits");
|
||||
lua_pushnumber(L, NIXIO_BIT_NMAX);
|
||||
lua_setfield(L, -2, "max");
|
||||
lua_setfield(L, -2, "bit");
|
||||
}
|
|
@ -30,12 +30,37 @@
|
|||
|
||||
static int nixio_open(lua_State *L) {
|
||||
const char *filename = luaL_checklstring(L, 1, NULL);
|
||||
int flags = luaL_optint(L, 2, O_RDONLY);
|
||||
int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
|
||||
int flags;
|
||||
|
||||
if (lua_isnoneornil(L, 2)) {
|
||||
flags = O_RDONLY;
|
||||
} else if (lua_isnumber(L, 2)) {
|
||||
flags = lua_tointeger(L, 2);
|
||||
} else if (lua_isstring(L, 2)) {
|
||||
const char *str = lua_tostring(L, 2);
|
||||
if (!strcmp(str, "r")) {
|
||||
flags = O_RDONLY;
|
||||
} else if (!strcmp(str, "r+")) {
|
||||
flags = O_RDWR;
|
||||
} else if (!strcmp(str, "w")) {
|
||||
flags = O_WRONLY | O_CREAT | O_TRUNC;
|
||||
} else if (!strcmp(str, "w+")) {
|
||||
flags = O_RDWR | O_CREAT | O_TRUNC;
|
||||
} else if (!strcmp(str, "a")) {
|
||||
flags = O_WRONLY | O_CREAT | O_APPEND;
|
||||
} else if (!strcmp(str, "a+")) {
|
||||
flags = O_RDWR | O_CREAT | O_APPEND;
|
||||
} else {
|
||||
return luaL_argerror(L, 2, "supported values: r, r+, w, w+, a, a+");
|
||||
}
|
||||
} else {
|
||||
return luaL_argerror(L, 2, "open flags or string expected");
|
||||
}
|
||||
|
||||
int fd;
|
||||
|
||||
do {
|
||||
fd = open(filename, flags, mode);
|
||||
fd = open(filename, flags, nixio__check_mode(L, 3, 0666));
|
||||
} while (fd == -1 && errno == EINTR);
|
||||
if (fd == -1) {
|
||||
return nixio__perror(L);
|
||||
|
@ -66,9 +91,13 @@ static int nixio_open_flags(lua_State *L) {
|
|||
} else if (!strcmp(flag, "excl")) {
|
||||
mode |= O_EXCL;
|
||||
} else if (!strcmp(flag, "nonblock") || !strcmp(flag, "ndelay")) {
|
||||
#ifndef __WINNT__
|
||||
mode |= O_NONBLOCK;
|
||||
#endif
|
||||
} else if (!strcmp(flag, "sync")) {
|
||||
#ifndef __WINNT__
|
||||
mode |= O_SYNC;
|
||||
#endif
|
||||
} else if (!strcmp(flag, "trunc")) {
|
||||
mode |= O_TRUNC;
|
||||
} else if (!strcmp(flag, "rdonly")) {
|
||||
|
@ -141,6 +170,23 @@ static int nixio_file_write(lua_State *L) {
|
|||
ssize_t sent;
|
||||
const char *data = luaL_checklstring(L, 2, &len);
|
||||
|
||||
if (lua_gettop(L) > 2) {
|
||||
int offset = luaL_optint(L, 3, 0);
|
||||
if (offset) {
|
||||
if (offset < len) {
|
||||
data += offset;
|
||||
len -= offset;
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int wlen = luaL_optint(L, 4, len);
|
||||
if (wlen < len) {
|
||||
len = wlen;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
sent = write(fd, data, len);
|
||||
} while(sent == -1 && errno == EINTR);
|
||||
|
@ -155,7 +201,7 @@ static int nixio_file_write(lua_State *L) {
|
|||
static int nixio_file_read(lua_State *L) {
|
||||
int fd = nixio__checkfd(L, 1);
|
||||
char buffer[NIXIO_BUFFERSIZE];
|
||||
int req = luaL_checkinteger(L, 2);
|
||||
uint req = luaL_checkinteger(L, 2);
|
||||
int readc;
|
||||
|
||||
/* We limit the readsize to NIXIO_BUFFERSIZE */
|
||||
|
@ -208,13 +254,33 @@ static int nixio_file_tell(lua_State *L) {
|
|||
}
|
||||
}
|
||||
|
||||
static int nixio_file_stat(lua_State *L) {
|
||||
nixio_stat_t buf;
|
||||
if (fstat(nixio__checkfd(L, 1), &buf)) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
nixio__push_stat(L, &buf);
|
||||
if (lua_isstring(L, 2)) {
|
||||
lua_getfield(L, -1, lua_tostring(L, 2));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int nixio_file_sync(lua_State *L) {
|
||||
int fd = nixio__checkfd(L, 1);
|
||||
#ifndef BSD
|
||||
int meta = lua_toboolean(L, 2);
|
||||
return nixio__pstatus(L, (meta) ? !fsync(fd) : !fdatasync(fd));
|
||||
int stat;
|
||||
#if (!defined BSD && !defined __WINNT__)
|
||||
int dataonly = lua_toboolean(L, 2);
|
||||
do {
|
||||
stat = (dataonly) ? fdatasync(fd) : fsync(fd);
|
||||
} while (stat == -1 && errno == EINTR);
|
||||
return nixio__pstatus(L, !stat);
|
||||
#else
|
||||
return nixio__pstatus(L, !fsync(fd));
|
||||
do {
|
||||
stat = fsync(fd);
|
||||
} while (stat == -1 && errno == EINTR);
|
||||
return nixio__pstatus(L, !stat);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -282,6 +348,7 @@ static const luaL_reg M[] = {
|
|||
{"read", nixio_file_read},
|
||||
{"tell", nixio_file_tell},
|
||||
{"seek", nixio_file_seek},
|
||||
{"stat", nixio_file_stat},
|
||||
{"sync", nixio_file_sync},
|
||||
{"lock", nixio_file_lock},
|
||||
{"close", nixio_file_close},
|
||||
|
@ -306,5 +373,26 @@ void nixio_open_file(lua_State *L) {
|
|||
luaL_register(L, NULL, M);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
int *uin = lua_newuserdata(L, sizeof(int));
|
||||
int *uout = lua_newuserdata(L, sizeof(int));
|
||||
int *uerr = lua_newuserdata(L, sizeof(int));
|
||||
|
||||
if (!uin || !uout || !uerr) {
|
||||
luaL_error(L, "out of memory");
|
||||
}
|
||||
|
||||
*uin = STDIN_FILENO;
|
||||
*uout = STDOUT_FILENO;
|
||||
*uerr = STDERR_FILENO;
|
||||
|
||||
for (int i = -4; i < -1; i++) {
|
||||
lua_pushvalue(L, -4);
|
||||
lua_setmetatable(L, i);
|
||||
}
|
||||
|
||||
lua_setfield(L, -5, "stderr");
|
||||
lua_setfield(L, -4, "stdout");
|
||||
lua_setfield(L, -3, "stdin");
|
||||
lua_setfield(L, -2, "meta_file");
|
||||
}
|
||||
|
|
566
libs/nixio/src/fs.c
Normal file
566
libs/nixio/src/fs.c
Normal file
|
@ -0,0 +1,566 @@
|
|||
/*
|
||||
* nixio - Linux I/O library for lua
|
||||
*
|
||||
* Copyright (C) 2009 Steven Barth <steven@midlink.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "nixio.h"
|
||||
#include <libgen.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <dirent.h>
|
||||
|
||||
/* Reads argument from given index and transforms it into a mode bitfield */
|
||||
int nixio__check_mode(lua_State *L, int idx, int def) {
|
||||
if (lua_isnoneornil(L, idx) && def > 0) {
|
||||
return def;
|
||||
} else if (lua_isstring(L, idx) && lua_objlen(L, idx) == 9) {
|
||||
int mode = 0;
|
||||
const char *modestr = lua_tostring(L, idx);
|
||||
int i;
|
||||
for (i=0; i<9; i++) {
|
||||
if (i % 3 == 0) { /* read flags */
|
||||
if (modestr[i] == 'r') {
|
||||
mode |= 1 << (8 - i);
|
||||
} else if (modestr[i] != '-') {
|
||||
break;
|
||||
}
|
||||
} else if (i % 3 == 1) { /* write flags */
|
||||
if (modestr[i] == 'w') {
|
||||
mode |= 1 << (8 - i);
|
||||
} else if (modestr[i] != '-') {
|
||||
break;
|
||||
}
|
||||
} else if (i == 2) {
|
||||
if (modestr[i] == 'x') {
|
||||
mode |= 00100;
|
||||
} else if (modestr[i] == 's') {
|
||||
mode |= 04100;
|
||||
} else if (modestr[i] == 'S') {
|
||||
mode |= 04000;
|
||||
} else if (modestr[i] != '-') {
|
||||
break;
|
||||
}
|
||||
} else if (i == 5) {
|
||||
if (modestr[i] == 'x') {
|
||||
mode |= 00010;
|
||||
} else if (modestr[i] == 's') {
|
||||
mode |= 02010;
|
||||
} else if (modestr[i] == 'S') {
|
||||
mode |= 02000;
|
||||
} else if (modestr[i] != '-') {
|
||||
break;
|
||||
}
|
||||
} else if (i == 8) {
|
||||
if (modestr[i] == 'x') {
|
||||
mode |= 00001;
|
||||
} else if (modestr[i] == 't') {
|
||||
mode |= 01001;
|
||||
} else if (modestr[i] == 'T') {
|
||||
mode |= 01000;
|
||||
} else if (modestr[i] != '-') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i == 9) { /* successfully parsed */
|
||||
return mode;
|
||||
}
|
||||
} else if (lua_isnumber(L, idx)) {
|
||||
int decmode = lua_tointeger(L, idx);
|
||||
int s = (decmode % 10000) / 1000;
|
||||
int u = (decmode % 1000) / 100;
|
||||
int g = (decmode % 100) / 10;
|
||||
int o = (decmode % 10);
|
||||
|
||||
if (s>=0 && s<=7 && u>=0 && u<=7 && g>=0 && g<=7 && o>=0 && o<=7) {
|
||||
return (s << 9) + (u << 6) + (g << 3) + o;
|
||||
}
|
||||
}
|
||||
|
||||
return luaL_argerror(L, idx, "supported values: [0-7]?[0-7][0-7][0-7], "
|
||||
"[-r][-w][-xsS][-r][-w][-xsS][-r][-w][-xtT]");
|
||||
}
|
||||
|
||||
/* Transforms a mode into the modestring */
|
||||
int nixio__mode_write(int mode, char *modestr) {
|
||||
if (modestr) {
|
||||
modestr[0] = (mode & 00400) ? 'r' : '-';
|
||||
modestr[1] = (mode & 00200) ? 'w' : '-';
|
||||
modestr[2] = ((mode & 04100) == 04100) ? 's' :
|
||||
(mode & 04000) ? 'S' : (mode & 00100) ? 'x' : '-';
|
||||
modestr[3] = (mode & 00040) ? 'r' : '-';
|
||||
modestr[4] = (mode & 00020) ? 'w' : '-';
|
||||
modestr[5] = ((mode & 02010) == 02010) ? 's' :
|
||||
(mode & 02000) ? 'S' : (mode & 00010) ? 'x' : '-';
|
||||
modestr[6] = (mode & 00004) ? 'r' : '-';
|
||||
modestr[7] = (mode & 00002) ? 'w' : '-';
|
||||
modestr[8] = ((mode & 01001) == 01001) ? 't' :
|
||||
(mode & 01000) ? 'T' : (mode & 00001) ? 'x' : '-';
|
||||
}
|
||||
|
||||
return (mode & 00007) + ((mode & 00070) >> 3) * 10 +
|
||||
((mode & 00700) >> 6) * 100 + ((mode & 07000) >> 9) * 1000;
|
||||
}
|
||||
|
||||
static int nixio_access(lua_State *L) {
|
||||
const char *path = luaL_checkstring(L, 1);
|
||||
int mode = F_OK;
|
||||
|
||||
for (const char *s = luaL_optstring(L, 2, "f"); *s; s++) {
|
||||
if (*s == 'r') {
|
||||
mode |= R_OK;
|
||||
} else if (*s == 'w') {
|
||||
mode |= W_OK;
|
||||
} else if (*s == 'x') {
|
||||
mode |= X_OK;
|
||||
} else if (*s != 'f') {
|
||||
return luaL_argerror(L, 2, "supported values: [frwx]");
|
||||
}
|
||||
}
|
||||
|
||||
return nixio__pstatus(L, !access(path, mode));
|
||||
}
|
||||
|
||||
static int nixio_basename(lua_State *L) {
|
||||
const char *path = luaL_checkstring(L, 1);
|
||||
char base[PATH_MAX];
|
||||
base[PATH_MAX-1] = 0;
|
||||
|
||||
strncpy(base, path, PATH_MAX-1);
|
||||
lua_pushstring(L, basename(base));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_dirname(lua_State *L) {
|
||||
const char *path = luaL_checkstring(L, 1);
|
||||
char base[PATH_MAX];
|
||||
base[PATH_MAX-1] = 0;
|
||||
|
||||
strncpy(base, path, PATH_MAX-1);
|
||||
lua_pushstring(L, dirname(base));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_realpath(lua_State *L) {
|
||||
const char *path = luaL_checkstring(L, 1);
|
||||
char real[PATH_MAX];
|
||||
|
||||
if (!realpath(path, real)) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
lua_pushstring(L, real);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int nixio_remove(lua_State *L) {
|
||||
return nixio__pstatus(L, !remove(luaL_checkstring(L, 1)));
|
||||
}
|
||||
|
||||
static int nixio_unlink(lua_State *L) {
|
||||
return nixio__pstatus(L, !unlink(luaL_checkstring(L, 1)));
|
||||
}
|
||||
|
||||
static int nixio_rename(lua_State *L) {
|
||||
return nixio__pstatus(L,
|
||||
!rename(luaL_checkstring(L, 1), luaL_checkstring(L, 2)));
|
||||
}
|
||||
|
||||
static int nixio_rmdir(lua_State *L) {
|
||||
return nixio__pstatus(L, !rmdir(luaL_checkstring(L, 1)));
|
||||
}
|
||||
|
||||
static int nixio_mkdir(lua_State *L) {
|
||||
return nixio__pstatus(L,
|
||||
!mkdir(luaL_checkstring(L, 1), nixio__check_mode(L, 2, 0777)));
|
||||
}
|
||||
|
||||
static int nixio_chmod(lua_State *L) {
|
||||
return nixio__pstatus(L,
|
||||
!chmod(luaL_checkstring(L, 1), nixio__check_mode(L, 2, -1)));
|
||||
}
|
||||
|
||||
static int nixio_dir__gc(lua_State *L) {
|
||||
DIR **dirp = lua_touserdata(L, 1);
|
||||
if (dirp && *dirp) {
|
||||
closedir(*dirp);
|
||||
*dirp = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nixio_dir__iter(lua_State *L) {
|
||||
DIR **dirp = lua_touserdata(L, lua_upvalueindex(1));
|
||||
struct dirent *entry;
|
||||
const char *n = NULL;
|
||||
|
||||
if (*dirp) {
|
||||
do {
|
||||
entry = readdir(*dirp);
|
||||
n = (entry) ? entry->d_name : NULL;
|
||||
} while(n && n[0] == '.' && (n[1] == 0 || (n[1] == '.' && n[2] == 0)));
|
||||
}
|
||||
|
||||
if (n) {
|
||||
lua_pushstring(L, n);
|
||||
} else {
|
||||
if (*dirp) {
|
||||
closedir(*dirp);
|
||||
*dirp = NULL;
|
||||
}
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_dir(lua_State *L) {
|
||||
const char *path = luaL_optstring(L, 1, ".");
|
||||
DIR **dirp = lua_newuserdata(L, sizeof(DIR *));
|
||||
|
||||
*dirp = opendir(path);
|
||||
if (!*dirp) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
luaL_getmetatable(L, NIXIO_DIR_META);
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pushcclosure(L, nixio_dir__iter, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int nixio_link(lua_State *L) {
|
||||
return nixio__pstatus(L,
|
||||
!link(luaL_checkstring(L, 1), luaL_checkstring(L, 2)));
|
||||
}
|
||||
|
||||
static int nixio_utimes(lua_State *L) {
|
||||
const char *path = luaL_checkstring(L, 1);
|
||||
if (lua_gettop(L) < 2) {
|
||||
return nixio__pstatus(L, !utimes(path, NULL));
|
||||
} else {
|
||||
double atime = luaL_checknumber(L, 2);
|
||||
double mtime = luaL_optnumber(L, 3, atime);
|
||||
struct timeval times[2];
|
||||
|
||||
times[0].tv_sec = atime;
|
||||
times[0].tv_usec = (long)((atime - (int64_t)atime) * 1000000);
|
||||
times[1].tv_sec = mtime;
|
||||
times[1].tv_usec = (long)((mtime - (int64_t)mtime) * 1000000);
|
||||
|
||||
return nixio__pstatus(L, !utimes(path, times));
|
||||
}
|
||||
}
|
||||
|
||||
int nixio__push_stat(lua_State *L, nixio_stat_t *buf) {
|
||||
lua_createtable(L, 0, 15);
|
||||
|
||||
lua_pushinteger(L, buf->st_dev);
|
||||
lua_setfield(L, -2, "dev");
|
||||
|
||||
lua_pushinteger(L, buf->st_ino);
|
||||
lua_setfield(L, -2, "ino");
|
||||
|
||||
if (S_ISREG(buf->st_mode)) {
|
||||
lua_pushliteral(L, "reg");
|
||||
} else if (S_ISDIR(buf->st_mode)) {
|
||||
lua_pushliteral(L, "dir");
|
||||
} else if (S_ISCHR(buf->st_mode)) {
|
||||
lua_pushliteral(L, "chr");
|
||||
} else if (S_ISBLK(buf->st_mode)) {
|
||||
lua_pushliteral(L, "blk");
|
||||
} else if (S_ISFIFO(buf->st_mode)) {
|
||||
lua_pushliteral(L, "fifo");
|
||||
} else if (S_ISLNK(buf->st_mode)) {
|
||||
lua_pushliteral(L, "lnk");
|
||||
} else if (S_ISSOCK(buf->st_mode)) {
|
||||
lua_pushliteral(L, "sock");
|
||||
} else {
|
||||
lua_pushliteral(L, "unknown");
|
||||
}
|
||||
lua_setfield(L, -2, "type");
|
||||
|
||||
char modestr[9];
|
||||
lua_pushinteger(L, nixio__mode_write(buf->st_mode, modestr));
|
||||
lua_setfield(L, -2, "modedec");
|
||||
|
||||
lua_pushlstring(L, modestr, 9);
|
||||
lua_setfield(L, -2, "modestr");
|
||||
|
||||
lua_pushinteger(L, buf->st_nlink);
|
||||
lua_setfield(L, -2, "nlink");
|
||||
|
||||
lua_pushinteger(L, buf->st_uid);
|
||||
lua_setfield(L, -2, "uid");
|
||||
|
||||
lua_pushinteger(L, buf->st_gid);
|
||||
lua_setfield(L, -2, "gid");
|
||||
|
||||
lua_pushinteger(L, buf->st_rdev);
|
||||
lua_setfield(L, -2, "rdev");
|
||||
|
||||
lua_pushnumber(L, buf->st_size);
|
||||
lua_setfield(L, -2, "size");
|
||||
|
||||
lua_pushinteger(L, buf->st_atime);
|
||||
lua_setfield(L, -2, "atime");
|
||||
|
||||
lua_pushinteger(L, buf->st_mtime);
|
||||
lua_setfield(L, -2, "mtime");
|
||||
|
||||
lua_pushinteger(L, buf->st_ctime);
|
||||
lua_setfield(L, -2, "ctime");
|
||||
|
||||
#ifndef __WINNT__
|
||||
lua_pushinteger(L, buf->st_blksize);
|
||||
lua_setfield(L, -2, "blksize");
|
||||
|
||||
lua_pushinteger(L, buf->st_blocks);
|
||||
lua_setfield(L, -2, "blocks");
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_stat(lua_State *L) {
|
||||
nixio_stat_t buf;
|
||||
if (stat(luaL_checkstring(L, 1), &buf)) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
nixio__push_stat(L, &buf);
|
||||
if (lua_isstring(L, 2)) {
|
||||
lua_getfield(L, -1, lua_tostring(L, 2));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int nixio_lstat(lua_State *L) {
|
||||
nixio_stat_t buf;
|
||||
if (stat(luaL_checkstring(L, 1), &buf)) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
nixio__push_stat(L, &buf);
|
||||
if (lua_isstring(L, 2)) {
|
||||
lua_getfield(L, -1, lua_tostring(L, 2));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __WINNT__
|
||||
|
||||
static int nixio_chown(lua_State *L) {
|
||||
return nixio__pstatus(L,
|
||||
!chown(
|
||||
luaL_checkstring(L, 1),
|
||||
lua_isnoneornil(L, 2) ? -1 : nixio__check_user(L, 2),
|
||||
lua_isnoneornil(L, 3) ? -1 : nixio__check_group(L, 3)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
static int nixio_lchown(lua_State *L) {
|
||||
return nixio__pstatus(L,
|
||||
!lchown(
|
||||
luaL_checkstring(L, 1),
|
||||
lua_isnoneornil(L, 2) ? -1 : nixio__check_user(L, 2),
|
||||
lua_isnoneornil(L, 3) ? -1 : nixio__check_group(L, 3)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
static int nixio_mkfifo(lua_State *L) {
|
||||
return nixio__pstatus(L,
|
||||
!mkfifo(luaL_checkstring(L, 1), nixio__check_mode(L, 2, -1)));
|
||||
}
|
||||
|
||||
static int nixio_symlink(lua_State *L) {
|
||||
return nixio__pstatus(L,
|
||||
!symlink(luaL_checkstring(L, 1), luaL_checkstring(L, 2)));
|
||||
}
|
||||
|
||||
static int nixio_readlink(lua_State *L) {
|
||||
char dest[PATH_MAX];
|
||||
ssize_t res = readlink(luaL_checkstring(L, 1), dest, sizeof(dest));
|
||||
if (res < 0) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
lua_pushlstring(L, dest, res);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#include <glob.h>
|
||||
|
||||
typedef struct {
|
||||
glob_t gl;
|
||||
size_t pos;
|
||||
int freed;
|
||||
} nixio_glob_t;
|
||||
|
||||
static int nixio_glob__iter(lua_State *L) {
|
||||
nixio_glob_t *globres = lua_touserdata(L, lua_upvalueindex(1));
|
||||
if (!globres->freed && globres->pos < globres->gl.gl_pathc) {
|
||||
lua_pushstring(L, globres->gl.gl_pathv[(globres->pos)++]);
|
||||
} else {
|
||||
if (!globres->freed) {
|
||||
globfree(&globres->gl);
|
||||
globres->freed = 1;
|
||||
}
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_glob__gc(lua_State *L) {
|
||||
nixio_glob_t *globres = lua_touserdata(L, 1);
|
||||
if (globres && !globres->freed) {
|
||||
globres->freed = 1;
|
||||
globfree(&globres->gl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nixio_glob(lua_State *L) {
|
||||
const char *pattern = luaL_optstring(L, 1, "*");
|
||||
nixio_glob_t *globres = lua_newuserdata(L, sizeof(nixio_glob_t));
|
||||
if (!globres) {
|
||||
return luaL_error(L, NIXIO_OOM);
|
||||
}
|
||||
globres->pos = 0;
|
||||
globres->freed = 0;
|
||||
|
||||
int globstat = glob(pattern, 0, NULL, &globres->gl);
|
||||
if (globstat == GLOB_NOMATCH) {
|
||||
lua_pushcfunction(L, nixio__nulliter);
|
||||
lua_pushinteger(L, 0);
|
||||
} else if (globstat) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
luaL_getmetatable(L, NIXIO_GLOB_META);
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pushcclosure(L, nixio_glob__iter, 1);
|
||||
lua_pushinteger(L, globres->gl.gl_pathc);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
static int nixio__push_statvfs(lua_State *L, struct statvfs *buf) {
|
||||
lua_createtable(L, 0, 12);
|
||||
|
||||
lua_pushnumber(L, buf->f_bavail);
|
||||
lua_setfield(L, -2, "bavail");
|
||||
|
||||
lua_pushnumber(L, buf->f_bfree);
|
||||
lua_setfield(L, -2, "bfree");
|
||||
|
||||
lua_pushnumber(L, buf->f_blocks);
|
||||
lua_setfield(L, -2, "blocks");
|
||||
|
||||
lua_pushnumber(L, buf->f_bsize);
|
||||
lua_setfield(L, -2, "bsize");
|
||||
|
||||
lua_pushnumber(L, buf->f_frsize);
|
||||
lua_setfield(L, -2, "frsize");
|
||||
|
||||
lua_pushnumber(L, buf->f_favail);
|
||||
lua_setfield(L, -2, "favail");
|
||||
|
||||
lua_pushnumber(L, buf->f_ffree);
|
||||
lua_setfield(L, -2, "ffree");
|
||||
|
||||
lua_pushnumber(L, buf->f_files);
|
||||
lua_setfield(L, -2, "files");
|
||||
|
||||
lua_pushnumber(L, buf->f_flag);
|
||||
lua_setfield(L, -2, "flag");
|
||||
|
||||
lua_pushnumber(L, buf->f_fsid);
|
||||
lua_setfield(L, -2, "fsid");
|
||||
|
||||
lua_pushnumber(L, buf->f_namemax);
|
||||
lua_setfield(L, -2, "namemax");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_statvfs(lua_State *L) {
|
||||
struct statvfs buf;
|
||||
if (statvfs(luaL_optstring(L, 1, "."), &buf)) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
return nixio__push_statvfs(L, &buf);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !__WINNT__ */
|
||||
|
||||
|
||||
|
||||
/* module table */
|
||||
static const luaL_reg R[] = {
|
||||
#ifndef __WINNT__
|
||||
{"glob", nixio_glob},
|
||||
{"mkfifo", nixio_mkfifo},
|
||||
{"symlink", nixio_symlink},
|
||||
{"readlink", nixio_readlink},
|
||||
{"chown", nixio_chown},
|
||||
{"lchown", nixio_lchown},
|
||||
{"statvfs", nixio_statvfs},
|
||||
#endif
|
||||
{"chmod", nixio_chmod},
|
||||
{"access", nixio_access},
|
||||
{"basename", nixio_basename},
|
||||
{"dir", nixio_dir},
|
||||
{"dirname", nixio_dirname},
|
||||
{"realpath", nixio_realpath},
|
||||
{"mkdir", nixio_mkdir},
|
||||
{"rmdir", nixio_rmdir},
|
||||
{"link", nixio_link},
|
||||
{"unlink", nixio_unlink},
|
||||
{"utimes", nixio_utimes},
|
||||
{"rename", nixio_rename},
|
||||
{"remove", nixio_remove},
|
||||
{"stat", nixio_stat},
|
||||
{"lstat", nixio_lstat},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void nixio_open_fs(lua_State *L) {
|
||||
lua_newtable(L);
|
||||
luaL_register(L, NULL, R);
|
||||
lua_setfield(L, -2, "fs");
|
||||
|
||||
luaL_newmetatable(L, NIXIO_DIR_META);
|
||||
lua_pushcfunction(L, nixio_dir__gc);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
lua_pop(L, 1);
|
||||
|
||||
#ifndef __WINNT__
|
||||
luaL_newmetatable(L, NIXIO_GLOB_META);
|
||||
lua_pushcfunction(L, nixio_glob__gc);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
lua_pop(L, 1);
|
||||
#endif
|
||||
}
|
|
@ -18,12 +18,10 @@
|
|||
|
||||
#include "nixio.h"
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
|
||||
/**
|
||||
|
@ -33,34 +31,46 @@ static int nixio_sock__sendto(lua_State *L, int to) {
|
|||
nixio_sock *sock = nixio__checksock(L);
|
||||
struct sockaddr *addr = NULL;
|
||||
socklen_t alen = 0;
|
||||
int argoff = 2;
|
||||
|
||||
if (to) {
|
||||
const char *address = luaL_checklstring(L, 3, NULL);
|
||||
uint16_t port = (uint16_t)luaL_checkinteger(L, 4);
|
||||
argoff += 2;
|
||||
const char *address = luaL_checkstring(L, 3);
|
||||
struct sockaddr_storage addrstor;
|
||||
addr = (struct sockaddr*)&addrstor;
|
||||
if (sock->domain == AF_INET) {
|
||||
struct sockaddr_in *inetaddr = (struct sockaddr_in *)addr;
|
||||
if (inet_pton(sock->domain, address, &inetaddr->sin_addr) < 0) {
|
||||
return luaL_argerror(L, 3, "invalid address");
|
||||
}
|
||||
inetaddr->sin_port = htons(port);
|
||||
alen = sizeof(*inetaddr);
|
||||
} else if (sock->domain == AF_INET6) {
|
||||
struct sockaddr_in6 *inet6addr = (struct sockaddr_in6 *)addr;
|
||||
if (inet_pton(sock->domain, address, &inet6addr->sin6_addr) < 0) {
|
||||
return luaL_argerror(L, 3, "invalid address");
|
||||
}
|
||||
inet6addr->sin6_port = htons(port);
|
||||
alen = sizeof(*inet6addr);
|
||||
} else {
|
||||
return luaL_argerror(L, 1, "supported families: inet, inet6");
|
||||
|
||||
nixio_addr naddr;
|
||||
memset(&naddr, 0, sizeof(naddr));
|
||||
strncpy(naddr.host, address, sizeof(naddr.host) - 1);
|
||||
naddr.port = (uint16_t)luaL_checkinteger(L, 4);
|
||||
naddr.family = sock->domain;
|
||||
|
||||
if (nixio__addr_write(&naddr, addr)) {
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
}
|
||||
|
||||
size_t len;
|
||||
ssize_t sent;
|
||||
const char *data = luaL_checklstring(L, 2, &len);
|
||||
|
||||
if (lua_gettop(L) > argoff) {
|
||||
int offset = luaL_optint(L, argoff + 1, 0);
|
||||
if (offset) {
|
||||
if (offset < len) {
|
||||
data += offset;
|
||||
len -= offset;
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int wlen = luaL_optint(L, argoff + 2, len);
|
||||
if (wlen < len) {
|
||||
len = wlen;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
sent = sendto(sock->fd, data, len, 0, addr, alen);
|
||||
} while(sent == -1 && errno == EINTR);
|
||||
|
@ -68,7 +78,7 @@ static int nixio_sock__sendto(lua_State *L, int to) {
|
|||
lua_pushinteger(L, sent);
|
||||
return 1;
|
||||
} else {
|
||||
return nixio__perror(L);
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,7 +104,7 @@ static int nixio_sock__recvfrom(lua_State *L, int from) {
|
|||
nixio_sock *sock = nixio__checksock(L);
|
||||
char buffer[NIXIO_BUFFERSIZE];
|
||||
struct sockaddr_storage addrobj;
|
||||
int req = luaL_checkinteger(L, 2);
|
||||
uint req = luaL_checkinteger(L, 2);
|
||||
int readc;
|
||||
|
||||
if (from && sock->domain != AF_INET && sock->domain != AF_INET6) {
|
||||
|
@ -111,38 +121,31 @@ static int nixio_sock__recvfrom(lua_State *L, int from) {
|
|||
readc = recvfrom(sock->fd, buffer, req, 0, addr, &alen);
|
||||
} while (readc == -1 && errno == EINTR);
|
||||
|
||||
#ifdef __WINNT__
|
||||
if (readc < 0) {
|
||||
return nixio__perror(L);
|
||||
int e = WSAGetLastError();
|
||||
if (e == WSAECONNRESET || e == WSAECONNABORTED || e == WSAESHUTDOWN) {
|
||||
readc = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (readc < 0) {
|
||||
return nixio__perror_s(L);
|
||||
} else {
|
||||
lua_pushlstring(L, buffer, readc);
|
||||
|
||||
if (!from) {
|
||||
return 1;
|
||||
} else {
|
||||
char ipaddr[INET6_ADDRSTRLEN];
|
||||
void *binaddr;
|
||||
uint16_t port;
|
||||
|
||||
if (addrobj.ss_family == AF_INET) {
|
||||
struct sockaddr_in *inetaddr = (struct sockaddr_in*)addr;
|
||||
port = inetaddr->sin_port;
|
||||
binaddr = &inetaddr->sin_addr;
|
||||
} else if (addrobj.ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *inet6addr = (struct sockaddr_in6*)addr;
|
||||
port = inet6addr->sin6_port;
|
||||
binaddr = &inet6addr->sin6_addr;
|
||||
nixio_addr naddr;
|
||||
if (!nixio__addr_parse(&naddr, (struct sockaddr *)&addrobj)) {
|
||||
lua_pushstring(L, naddr.host);
|
||||
lua_pushnumber(L, naddr.port);
|
||||
return 3;
|
||||
} else {
|
||||
return luaL_error(L, "unknown address family");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!inet_ntop(addrobj.ss_family, binaddr, ipaddr, sizeof(ipaddr))) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
lua_pushstring(L, ipaddr);
|
||||
lua_pushinteger(L, ntohs(port));
|
||||
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
220
libs/nixio/src/mingw-compat.c
Normal file
220
libs/nixio/src/mingw-compat.c
Normal file
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* nixio - Linux I/O library for lua
|
||||
*
|
||||
* Copyright (C) 2009 Steven Barth <steven@midlink.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "nixio.h"
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/locking.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/utime.h>
|
||||
|
||||
void nixio_open__mingw(lua_State *L) {
|
||||
_fmode = _O_BINARY;
|
||||
|
||||
WSADATA wsa;
|
||||
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsa)) {
|
||||
luaL_error(L, "Unable to initialize Winsock");
|
||||
}
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
NIXIO_WSA_CONSTANT(WSAEACCES);
|
||||
NIXIO_WSA_CONSTANT(WSAEINTR);
|
||||
NIXIO_WSA_CONSTANT(WSAEINVAL);
|
||||
NIXIO_WSA_CONSTANT(WSAEBADF);
|
||||
NIXIO_WSA_CONSTANT(WSAEFAULT);
|
||||
NIXIO_WSA_CONSTANT(WSAEMFILE);
|
||||
NIXIO_WSA_CONSTANT(WSAENAMETOOLONG);
|
||||
NIXIO_WSA_CONSTANT(WSAELOOP);
|
||||
NIXIO_WSA_CONSTANT(WSAEAFNOSUPPORT);
|
||||
NIXIO_WSA_CONSTANT(WSAENOBUFS);
|
||||
NIXIO_WSA_CONSTANT(WSAEPROTONOSUPPORT);
|
||||
NIXIO_WSA_CONSTANT(WSAENOPROTOOPT);
|
||||
NIXIO_WSA_CONSTANT(WSAEADDRINUSE);
|
||||
NIXIO_WSA_CONSTANT(WSAENETDOWN);
|
||||
NIXIO_WSA_CONSTANT(WSAENETUNREACH);
|
||||
NIXIO_WSA_CONSTANT(WSAECONNABORTED);
|
||||
NIXIO_WSA_CONSTANT(WSAECONNRESET);
|
||||
|
||||
lua_setfield(L, -2, "const_sock");
|
||||
}
|
||||
|
||||
const char* nixio__mgw_inet_ntop
|
||||
(int af, const void *src, char *dst, socklen_t size) {
|
||||
struct sockaddr_storage saddr;
|
||||
memset(&saddr, 0, sizeof(saddr));
|
||||
|
||||
DWORD hostlen = size, sl;
|
||||
if (af == AF_INET) {
|
||||
struct sockaddr_in *saddr4 = (struct sockaddr_in *)&saddr;
|
||||
memcpy(&saddr4->sin_addr, src, sizeof(saddr4->sin_addr));
|
||||
saddr4->sin_family = AF_INET;
|
||||
saddr4->sin_port = 0;
|
||||
sl = sizeof(struct sockaddr_in);
|
||||
} else if (af == AF_INET6) {
|
||||
struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)&saddr;
|
||||
memcpy(&saddr6->sin6_addr, src, sizeof(saddr6->sin6_addr));
|
||||
saddr6->sin6_family = AF_INET6;
|
||||
saddr6->sin6_port = 0;
|
||||
sl = sizeof(struct sockaddr_in6);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
if (WSAAddressToString((struct sockaddr*)&saddr, sl, NULL, dst, &hostlen)) {
|
||||
return NULL;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
int nixio__mgw_inet_pton (int af, const char *src, void *dst) {
|
||||
struct sockaddr_storage sa;
|
||||
int sl = sizeof(sa);
|
||||
|
||||
if (!WSAStringToAddress((char*)src, af, NULL, (struct sockaddr*)&sa, &sl)) {
|
||||
if (af == AF_INET) {
|
||||
struct in_addr ina = ((struct sockaddr_in *)&sa)->sin_addr;
|
||||
memcpy(dst, &ina, sizeof(ina));
|
||||
return 1;
|
||||
} else if (af == AF_INET6) {
|
||||
struct in_addr6 ina6 = ((struct sockaddr_in6 *)&sa)->sin6_addr;
|
||||
memcpy(dst, &ina6, sizeof(ina6));
|
||||
return 1;
|
||||
} else {
|
||||
WSASetLastError(WSAEAFNOSUPPORT);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int nixio__mgw_nanosleep(const struct timespec *req, struct timespec *rem) {
|
||||
if (rem) {
|
||||
rem->tv_sec = 0;
|
||||
rem->tv_nsec = 0;
|
||||
}
|
||||
Sleep(req->tv_sec * 1000 + req->tv_nsec * 1000000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nixio__mgw_poll(struct pollfd *fds, int nfds, int timeout) {
|
||||
if (!fds || !nfds) {
|
||||
Sleep(timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct timeval tv;
|
||||
int high = 0, rf = 0, wf = 0, ef = 0;
|
||||
fd_set rfds, wfds, efds;
|
||||
FD_ZERO(&rfds);
|
||||
FD_ZERO(&wfds);
|
||||
FD_ZERO(&efds);
|
||||
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
|
||||
for (int i = 0; i < nfds; i++) {
|
||||
if (fds->events & POLLIN) {
|
||||
FD_SET(fds->fd, &rfds);
|
||||
rf++;
|
||||
}
|
||||
if (fds->events & POLLOUT) {
|
||||
FD_SET(fds->fd, &wfds);
|
||||
wf++;
|
||||
}
|
||||
if (fds->events & POLLERR) {
|
||||
FD_SET(fds->fd, &efds);
|
||||
ef++;
|
||||
}
|
||||
if (fds->fd > high) {
|
||||
high = fds->fd;
|
||||
}
|
||||
}
|
||||
|
||||
int stat = select(high + 1, (rf) ? &rfds : NULL,
|
||||
(wf) ? &wfds : NULL, (ef) ? &efds : NULL, &tv);
|
||||
if (stat < 1) {
|
||||
errno = WSAGetLastError();
|
||||
return stat;
|
||||
}
|
||||
|
||||
high = 0;
|
||||
|
||||
for (int i = 0; i < nfds; i++) {
|
||||
fds->revents = 0;
|
||||
if ((fds->events & POLLIN) && FD_ISSET(fds->fd, &rfds)) {
|
||||
fds->revents |= POLLIN;
|
||||
}
|
||||
if ((fds->events & POLLOUT) && FD_ISSET(fds->fd, &wfds)) {
|
||||
fds->revents |= POLLOUT;
|
||||
}
|
||||
if ((fds->events & POLLERR) && FD_ISSET(fds->fd, &efds)) {
|
||||
fds->revents |= POLLERR;
|
||||
}
|
||||
if (fds->revents) {
|
||||
high++;
|
||||
}
|
||||
}
|
||||
|
||||
return high;
|
||||
}
|
||||
|
||||
int nixio__mgw_lockf(int fd, int cmd, off_t len) {
|
||||
int stat;
|
||||
if (cmd == F_LOCK) {
|
||||
do {
|
||||
stat = _locking(fd, _LK_LOCK, len);
|
||||
} while (stat == -1 && errno == EDEADLOCK);
|
||||
} else if (cmd == F_TLOCK) {
|
||||
stat = _locking(fd, _LK_NBLCK, len);
|
||||
} else if (cmd == F_ULOCK) {
|
||||
stat = _locking(fd, _LK_UNLCK, len);
|
||||
} else {
|
||||
stat = -1;
|
||||
errno = EINVAL;
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
char* nixio__mgw_realpath(const char *path, char *resolved) {
|
||||
if (GetFullPathName(path, PATH_MAX, resolved, NULL)) {
|
||||
return resolved;
|
||||
} else {
|
||||
errno = GetLastError();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int nixio__mgw_link(const char *oldpath, const char *newpath) {
|
||||
if (!CreateHardLink(newpath, oldpath, NULL)) {
|
||||
errno = GetLastError();
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int nixio__mgw_utimes(const char *filename, const struct timeval times[2]) {
|
||||
struct _utimbuf timebuffer;
|
||||
timebuffer.actime = times[0].tv_sec;
|
||||
timebuffer.modtime = times[1].tv_sec;
|
||||
|
||||
return _utime(filename, &timebuffer);
|
||||
}
|
112
libs/nixio/src/mingw-compat.h
Normal file
112
libs/nixio/src/mingw-compat.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
#ifndef NIXIO_MINGW_COMPAT_H_
|
||||
#define NIXIO_MINGW_COMPAT_H_
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <io.h>
|
||||
#include <process.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
|
||||
#define S_ISLNK(m) 0
|
||||
#define S_ISSOCK(m) 0
|
||||
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#define EAFNOSUPPORT WSAEAFNOSUPPORT
|
||||
#define ENOPROTOOPT WSAENOPROTOOPT
|
||||
|
||||
#define SHUT_RD SD_RECEIVE
|
||||
#define SHUT_WR SD_SEND
|
||||
#define SHUT_RDWR SD_BOTH
|
||||
|
||||
#define pipe(fds) _pipe(fds, 65536, 0)
|
||||
#define fsync _commit
|
||||
#define lseek lseek64
|
||||
#define stat _stati64
|
||||
#define lstat _stati64
|
||||
#define fstat _fstati64
|
||||
|
||||
|
||||
#define F_LOCK 1
|
||||
#define F_ULOCK 0
|
||||
#define F_TLOCK 2
|
||||
#define F_TEST 3
|
||||
int nixio__mgw_lockf(int fd, int cmd, off_t len);
|
||||
#define lockf nixio__mgw_lockf
|
||||
|
||||
const char* nixio__mgw_inet_ntop
|
||||
(int af, const void *src, char *dst, socklen_t size);
|
||||
#define inet_ntop nixio__mgw_inet_ntop
|
||||
|
||||
int nixio__mgw_inet_pton (int af, const char *src, void *dst);
|
||||
#define inet_pton nixio__mgw_inet_pton
|
||||
|
||||
|
||||
#ifndef POLLIN
|
||||
#define POLLIN 0x001
|
||||
#define POLLOUT 0x004
|
||||
#define POLLERR 0x008
|
||||
struct pollfd {
|
||||
int fd;
|
||||
short events;
|
||||
short revents;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef int nfds_t;
|
||||
int nixio__mgw_poll(struct pollfd *fds, nfds_t nfds, int timeout);
|
||||
#define poll nixio__mgw_poll
|
||||
|
||||
|
||||
struct timespec {
|
||||
time_t tv_sec;
|
||||
long tv_nsec;
|
||||
};
|
||||
|
||||
int nixio__mgw_nanosleep(const struct timespec *req, struct timespec *rem);
|
||||
#define nanosleep nixio__mgw_nanosleep
|
||||
|
||||
|
||||
char* nixio__mgw_realpath(const char *path, char *resolved);
|
||||
#define realpath nixio__mgw_realpath
|
||||
|
||||
|
||||
int nixio__mgw_link(const char *oldpath, const char *newpath);
|
||||
#define link nixio__mgw_link
|
||||
|
||||
|
||||
int nixio__mgw_utimes(const char *filename, const struct timeval times[2]);
|
||||
#define utimes nixio__mgw_utimes
|
||||
|
||||
|
||||
#define setenv(k, v, o) !SetEnvironmentVariable(k, v)
|
||||
#define unsetenv(k) !SetEnvironmentVariable(k, NULL)
|
||||
|
||||
#define execv(p, a) execv(p, (const char* const*)a)
|
||||
#define execvp(p, a) execvp(p, (const char* const*)a)
|
||||
#define execve(p, a, e) execve(p, (const char* const*)a, (const char* const*)e)
|
||||
|
||||
#define mkdir(p, m) mkdir(p)
|
||||
|
||||
|
||||
#define nixio__perror_s(L) \
|
||||
errno = WSAGetLastError(); \
|
||||
return nixio__perror(L);
|
||||
|
||||
#define nixio__pstatus_s(L, c) \
|
||||
errno = WSAGetLastError(); \
|
||||
return nixio__pstatus(L, c);
|
||||
|
||||
|
||||
|
||||
#define NIXIO_WSA_CONSTANT(x) \
|
||||
lua_pushinteger(L, x); \
|
||||
lua_setfield(L, -2, #x+3);
|
||||
|
||||
void nixio_open__mingw(lua_State *L);
|
||||
|
||||
#endif /* NIXIO_MINGW_COMPAT_H_ */
|
|
@ -2,9 +2,12 @@
|
|||
#define NIXIO_TLS_H_
|
||||
|
||||
#include "nixio.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef WITHOUT_OPENSSL
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
#endif
|
||||
|
||||
#define NIXIO_TLS_CTX_META "nixio.tls.ctx"
|
||||
|
@ -20,4 +23,31 @@ typedef struct nixio_tls_socket {
|
|||
#endif
|
||||
} nixio_tls_sock;
|
||||
|
||||
#define NIXIO_CRYPTO_HASH_META "nixio.crypto.hash"
|
||||
#define NIXIO_DIGEST_SIZE 64
|
||||
#define NIXIO_CRYPTO_BLOCK_SIZE 64
|
||||
|
||||
#define NIXIO_HASH_NONE 0
|
||||
#define NIXIO_HASH_MD5 0x01
|
||||
#define NIXIO_HASH_SHA1 0x02
|
||||
|
||||
#define NIXIO_HMAC_BIT 0x40
|
||||
|
||||
typedef int(*nixio_hash_initcb)(void *);
|
||||
typedef int(*nixio_hash_updatecb)(void *, const void *, unsigned long);
|
||||
typedef int(*nixio_hash_finalcb)(unsigned char *, void *);
|
||||
|
||||
typedef struct nixio_hash_obj {
|
||||
uint type;
|
||||
unsigned char digest[NIXIO_DIGEST_SIZE];
|
||||
size_t digest_size;
|
||||
unsigned char key[NIXIO_CRYPTO_BLOCK_SIZE];
|
||||
size_t key_size;
|
||||
size_t block_size;
|
||||
void *ctx;
|
||||
nixio_hash_initcb init;
|
||||
nixio_hash_updatecb update;
|
||||
nixio_hash_finalcb final;
|
||||
} nixio_hash;
|
||||
|
||||
#endif /* NIXIO_TLS_H_ */
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
/* pushes nil, error number and errstring on the stack */
|
||||
int nixio__perror(lua_State *L) {
|
||||
if (errno == EAGAIN) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
lua_pushboolean(L, 0);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
|
@ -85,6 +85,17 @@ int nixio__tofd(lua_State *L, int ud) {
|
|||
return fd;
|
||||
}
|
||||
|
||||
/* An empty iterator */
|
||||
int nixio__nulliter(lua_State *L) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_errno(lua_State *L) {
|
||||
lua_pushinteger(L, errno);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_strerror(lua_State *L) {
|
||||
lua_pushstring(L, strerror(luaL_checkinteger(L, 1)));
|
||||
return 1;
|
||||
|
@ -92,12 +103,13 @@ static int nixio_strerror(lua_State *L) {
|
|||
|
||||
/* object table */
|
||||
static const luaL_reg R[] = {
|
||||
{"errno", nixio_errno},
|
||||
{"strerror", nixio_strerror},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/* entry point */
|
||||
LUALIB_API int luaopen_nixio(lua_State *L) {
|
||||
NIXIO_API int luaopen_nixio(lua_State *L) {
|
||||
/* create metatable */
|
||||
luaL_newmetatable(L, NIXIO_META);
|
||||
|
||||
|
@ -113,6 +125,9 @@ LUALIB_API int luaopen_nixio(lua_State *L) {
|
|||
lua_setfield(L, -2, "meta_socket");
|
||||
|
||||
/* register methods */
|
||||
#ifdef __WINNT__
|
||||
nixio_open__mingw(L);
|
||||
#endif
|
||||
nixio_open_file(L);
|
||||
nixio_open_socket(L);
|
||||
nixio_open_sockopt(L);
|
||||
|
@ -123,6 +138,11 @@ LUALIB_API int luaopen_nixio(lua_State *L) {
|
|||
nixio_open_splice(L);
|
||||
nixio_open_process(L);
|
||||
nixio_open_syslog(L);
|
||||
nixio_open_bit(L);
|
||||
nixio_open_bin(L);
|
||||
nixio_open_fs(L);
|
||||
nixio_open_user(L);
|
||||
nixio_open_tls_crypto(L);
|
||||
nixio_open_tls_context(L);
|
||||
nixio_open_tls_socket(L);
|
||||
|
||||
|
@ -131,13 +151,21 @@ LUALIB_API int luaopen_nixio(lua_State *L) {
|
|||
lua_setfield(L, -2, "version");
|
||||
|
||||
/* some constants */
|
||||
lua_createtable(L, 0, 49);
|
||||
lua_newtable(L);
|
||||
|
||||
lua_pushliteral(L, NIXIO_SEP);
|
||||
lua_setfield(L, -2, "sep");
|
||||
|
||||
lua_pushliteral(L, NIXIO_PATHSEP);
|
||||
lua_setfield(L, -2, "pathsep");
|
||||
|
||||
lua_pushinteger(L, NIXIO_BUFFERSIZE);
|
||||
lua_setfield(L, -2, "buffersize");
|
||||
|
||||
NIXIO_PUSH_CONSTANT(EACCES);
|
||||
NIXIO_PUSH_CONSTANT(EINTR);
|
||||
NIXIO_PUSH_CONSTANT(ENOSYS);
|
||||
NIXIO_PUSH_CONSTANT(EINVAL);
|
||||
NIXIO_PUSH_CONSTANT(EWOULDBLOCK);
|
||||
NIXIO_PUSH_CONSTANT(EAGAIN);
|
||||
NIXIO_PUSH_CONSTANT(ENOMEM);
|
||||
NIXIO_PUSH_CONSTANT(ENOENT);
|
||||
|
@ -152,37 +180,51 @@ LUALIB_API int luaopen_nixio(lua_State *L) {
|
|||
NIXIO_PUSH_CONSTANT(EISDIR);
|
||||
NIXIO_PUSH_CONSTANT(EPERM);
|
||||
NIXIO_PUSH_CONSTANT(EEXIST);
|
||||
NIXIO_PUSH_CONSTANT(ELOOP);
|
||||
NIXIO_PUSH_CONSTANT(EMFILE);
|
||||
NIXIO_PUSH_CONSTANT(ENAMETOOLONG);
|
||||
NIXIO_PUSH_CONSTANT(ENFILE);
|
||||
NIXIO_PUSH_CONSTANT(ENODEV);
|
||||
NIXIO_PUSH_CONSTANT(EXDEV);
|
||||
NIXIO_PUSH_CONSTANT(ENOTDIR);
|
||||
NIXIO_PUSH_CONSTANT(ENXIO);
|
||||
NIXIO_PUSH_CONSTANT(EOVERFLOW);
|
||||
NIXIO_PUSH_CONSTANT(EROFS);
|
||||
NIXIO_PUSH_CONSTANT(EBUSY);
|
||||
NIXIO_PUSH_CONSTANT(ESRCH);
|
||||
NIXIO_PUSH_CONSTANT(SIGINT);
|
||||
NIXIO_PUSH_CONSTANT(SIGTERM);
|
||||
NIXIO_PUSH_CONSTANT(SIGSEGV);
|
||||
|
||||
#ifndef __WINNT__
|
||||
NIXIO_PUSH_CONSTANT(EWOULDBLOCK);
|
||||
NIXIO_PUSH_CONSTANT(ELOOP);
|
||||
NIXIO_PUSH_CONSTANT(EOVERFLOW);
|
||||
NIXIO_PUSH_CONSTANT(ETXTBSY);
|
||||
NIXIO_PUSH_CONSTANT(EAFNOSUPPORT);
|
||||
NIXIO_PUSH_CONSTANT(ENOBUFS);
|
||||
NIXIO_PUSH_CONSTANT(EPROTONOSUPPORT);
|
||||
NIXIO_PUSH_CONSTANT(ENOPROTOOPT);
|
||||
NIXIO_PUSH_CONSTANT(EBUSY);
|
||||
NIXIO_PUSH_CONSTANT(ESRCH);
|
||||
NIXIO_PUSH_CONSTANT(EADDRINUSE);
|
||||
NIXIO_PUSH_CONSTANT(ENETDOWN);
|
||||
NIXIO_PUSH_CONSTANT(ENETUNREACH);
|
||||
|
||||
NIXIO_PUSH_CONSTANT(SIGALRM);
|
||||
NIXIO_PUSH_CONSTANT(SIGINT);
|
||||
NIXIO_PUSH_CONSTANT(SIGTERM);
|
||||
NIXIO_PUSH_CONSTANT(SIGKILL);
|
||||
NIXIO_PUSH_CONSTANT(SIGHUP);
|
||||
NIXIO_PUSH_CONSTANT(SIGSTOP);
|
||||
NIXIO_PUSH_CONSTANT(SIGCONT);
|
||||
NIXIO_PUSH_CONSTANT(SIGSEGV);
|
||||
NIXIO_PUSH_CONSTANT(SIGCHLD);
|
||||
NIXIO_PUSH_CONSTANT(SIGQUIT);
|
||||
NIXIO_PUSH_CONSTANT(SIGUSR1);
|
||||
NIXIO_PUSH_CONSTANT(SIGUSR2);
|
||||
NIXIO_PUSH_CONSTANT(SIGIO);
|
||||
NIXIO_PUSH_CONSTANT(SIGURG);
|
||||
NIXIO_PUSH_CONSTANT(SIGPIPE);
|
||||
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -3, "const_sock");
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif /* !__WINNT__ */
|
||||
lua_setfield(L, -2, "const");
|
||||
|
||||
/* remove meta table */
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
#ifndef NIXIO_H_
|
||||
#define NIXIO_H_
|
||||
|
||||
#define NIXIO_OOM "out of memory"
|
||||
|
||||
#define NIXIO_META "nixio.socket"
|
||||
#define NIXIO_FILE_META "nixio.file"
|
||||
#define NIXIO_BUFFERSIZE 8096
|
||||
#define NIXIO_GLOB_META "nixio.glob"
|
||||
#define NIXIO_DIR_META "nixio.dir"
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#define NIXIO_PUSH_CONSTANT(x) \
|
||||
|
@ -17,6 +20,8 @@
|
|||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
#define NIXIO_BUFFERSIZE 8192
|
||||
|
||||
typedef struct nixio_socket {
|
||||
int fd;
|
||||
int domain;
|
||||
|
@ -24,12 +29,66 @@ typedef struct nixio_socket {
|
|||
int protocol;
|
||||
} nixio_sock;
|
||||
|
||||
typedef struct nixio_address {
|
||||
int family;
|
||||
char host[128];
|
||||
int port;
|
||||
} nixio_addr;
|
||||
|
||||
int nixio__perror(lua_State *L);
|
||||
int nixio__pstatus(lua_State *L, int condition);
|
||||
|
||||
#ifndef __WINNT__
|
||||
|
||||
#define NIXIO_API extern
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/un.h>
|
||||
#include <netdb.h>
|
||||
#include <poll.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define NIXIO_SEP "/"
|
||||
#define NIXIO_PATHSEP ":"
|
||||
|
||||
#define nixio__perror_s nixio__perror
|
||||
#define nixio__pstatus_s nixio__pstatus
|
||||
|
||||
int nixio__check_group(lua_State *L, int idx);
|
||||
int nixio__check_user(lua_State *L, int idx);
|
||||
|
||||
typedef struct stat nixio_stat_t;
|
||||
|
||||
#else /* __WINNT__ */
|
||||
|
||||
#define NIXIO_API extern __declspec(dllexport)
|
||||
#define NIXIO_SEP "\\"
|
||||
#define NIXIO_PATHSEP ";"
|
||||
#include "mingw-compat.h"
|
||||
|
||||
typedef struct _stati64 nixio_stat_t;
|
||||
|
||||
#endif
|
||||
|
||||
nixio_sock* nixio__checksock(lua_State *L);
|
||||
int nixio__checksockfd(lua_State *L);
|
||||
int nixio__checkfd(lua_State *L, int ud);
|
||||
int nixio__tofd(lua_State *L, int ud);
|
||||
int nixio__nulliter(lua_State *L);
|
||||
|
||||
int nixio__addr_parse(nixio_addr *addr, struct sockaddr *saddr);
|
||||
int nixio__addr_write(nixio_addr *addr, struct sockaddr *saddr);
|
||||
|
||||
int nixio__check_mode(lua_State *L, int idx, int def);
|
||||
int nixio__mode_write(int mode, char *modestr);
|
||||
|
||||
int nixio__push_stat(lua_State *L, nixio_stat_t *buf);
|
||||
|
||||
/* Module functions */
|
||||
void nixio_open_file(lua_State *L);
|
||||
|
@ -42,6 +101,11 @@ void nixio_open_io(lua_State *L);
|
|||
void nixio_open_splice(lua_State *L);
|
||||
void nixio_open_process(lua_State *L);
|
||||
void nixio_open_syslog(lua_State *L);
|
||||
void nixio_open_bit(lua_State *L);
|
||||
void nixio_open_bin(lua_State *L);
|
||||
void nixio_open_fs(lua_State *L);
|
||||
void nixio_open_user(lua_State *L);
|
||||
void nixio_open_tls_crypto(lua_State *L);
|
||||
void nixio_open_tls_context(lua_State *L);
|
||||
void nixio_open_tls_socket(lua_State *L);
|
||||
|
||||
|
|
|
@ -17,12 +17,10 @@
|
|||
*/
|
||||
|
||||
#include "nixio.h"
|
||||
#include <poll.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "nixio.h"
|
||||
|
||||
|
||||
/**
|
||||
|
@ -71,11 +69,13 @@ static int nixio_poll_flags(lua_State *L) {
|
|||
flags = luaL_checkinteger(L, 1);
|
||||
lua_newtable(L);
|
||||
nixio_poll_flags__r(L, &flags, POLLIN, "in");
|
||||
nixio_poll_flags__r(L, &flags, POLLPRI, "pri");
|
||||
nixio_poll_flags__r(L, &flags, POLLOUT, "out");
|
||||
nixio_poll_flags__r(L, &flags, POLLERR, "err");
|
||||
#ifndef __WINNT__
|
||||
nixio_poll_flags__r(L, &flags, POLLPRI, "pri");
|
||||
nixio_poll_flags__r(L, &flags, POLLHUP, "hup");
|
||||
nixio_poll_flags__r(L, &flags, POLLNVAL, "nval");
|
||||
#endif
|
||||
} else {
|
||||
flags = 0;
|
||||
const int j = lua_gettop(L);
|
||||
|
@ -83,16 +83,22 @@ static int nixio_poll_flags(lua_State *L) {
|
|||
const char *flag = luaL_checkstring(L, i);
|
||||
if (!strcmp(flag, "in")) {
|
||||
flags |= POLLIN;
|
||||
} else if (!strcmp(flag, "pri")) {
|
||||
flags |= POLLPRI;
|
||||
} else if (!strcmp(flag, "out")) {
|
||||
flags |= POLLOUT;
|
||||
} else if (!strcmp(flag, "err")) {
|
||||
flags |= POLLERR;
|
||||
} else if (!strcmp(flag, "pri")) {
|
||||
#ifndef __WINNT__
|
||||
flags |= POLLPRI;
|
||||
#endif
|
||||
} else if (!strcmp(flag, "hup")) {
|
||||
#ifndef __WINNT__
|
||||
flags |= POLLHUP;
|
||||
#endif
|
||||
} else if (!strcmp(flag, "nval")) {
|
||||
#ifndef __WINNT__
|
||||
flags |= POLLNVAL;
|
||||
#endif
|
||||
} else {
|
||||
return luaL_argerror(L, i,
|
||||
"supported values: in, pri, out, err, hup, nval");
|
||||
|
@ -114,11 +120,19 @@ static int nixio_poll(lua_State *L) {
|
|||
|
||||
/* we are being abused as sleep() replacement... */
|
||||
if (lua_isnoneornil(L, 1) || len < 1) {
|
||||
return nixio__pstatus(L, !poll(NULL, 0, timeout));
|
||||
if (!poll(NULL, 0, timeout)) {
|
||||
lua_pushinteger(L, 0);
|
||||
return 1;
|
||||
} else {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
}
|
||||
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
struct pollfd *fds = calloc(len, sizeof(struct pollfd));
|
||||
if (!fds) {
|
||||
return luaL_error(L, NIXIO_OOM);
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
lua_rawgeti(L, 1, i+1);
|
||||
|
@ -145,7 +159,11 @@ static int nixio_poll(lua_State *L) {
|
|||
|
||||
status = poll(fds, (nfds_t)len, timeout);
|
||||
|
||||
if (status < 1) {
|
||||
if (status == 0) {
|
||||
free(fds);
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
} else if (status < 0) {
|
||||
free(fds);
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
|
|
@ -17,15 +17,98 @@
|
|||
*/
|
||||
|
||||
#include "nixio.h"
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define NIXIO_EXECVE 0x01
|
||||
#define NIXIO_EXECV 0x02
|
||||
#define NIXIO_EXECVP 0x03
|
||||
|
||||
int nixio__exec(lua_State *L, int m) {
|
||||
const char *path = luaL_checkstring(L, 1);
|
||||
const char *arg;
|
||||
int argn, i;
|
||||
|
||||
if (m == NIXIO_EXECVE) {
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
argn = lua_objlen(L, 2) + 1;
|
||||
} else {
|
||||
argn = lua_gettop(L);
|
||||
}
|
||||
|
||||
char **args = lua_newuserdata(L, sizeof(char*) * (argn + 1));
|
||||
args[argn] = NULL;
|
||||
args[0] = (char *)path;
|
||||
|
||||
if (m == NIXIO_EXECVE) {
|
||||
for (i = 1; i < argn; i++) {
|
||||
lua_rawgeti(L, 2, i);
|
||||
arg = lua_tostring(L, -1);
|
||||
luaL_argcheck(L, arg, 2, "invalid argument");
|
||||
args[i] = (char *)arg;
|
||||
}
|
||||
|
||||
if (lua_isnoneornil(L, 3)) {
|
||||
execv(path, args);
|
||||
} else {
|
||||
luaL_checktype(L, 3, LUA_TTABLE);
|
||||
argn = 0;
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 3)) {
|
||||
if (!lua_checkstack(L, 1)) {
|
||||
lua_settop(L, 0);
|
||||
return luaL_error(L, "stack overflow");
|
||||
}
|
||||
|
||||
if (!lua_type(L, -2) != LUA_TSTRING || !lua_isstring(L, -1)) {
|
||||
return luaL_argerror(L, 3, "invalid environment");
|
||||
}
|
||||
|
||||
lua_pushfstring(L, "%s=%s",
|
||||
lua_tostring(L, -2), lua_tostring(L, -1));
|
||||
|
||||
lua_insert(L, 4);
|
||||
lua_pop(L, 1);
|
||||
argn++;
|
||||
}
|
||||
|
||||
char **env = lua_newuserdata(L, sizeof(char*) * (argn + 1));
|
||||
env[argn] = NULL;
|
||||
|
||||
for (i = 1; i < argn; i++) {
|
||||
env[i-1] = (char *)lua_tostring(L, -i);
|
||||
}
|
||||
|
||||
execve(path, args, env);
|
||||
}
|
||||
} else {
|
||||
for (i = 2; i <= argn; i++) {
|
||||
arg = luaL_checkstring(L, i);
|
||||
args[i-1] = (char *)arg;
|
||||
}
|
||||
|
||||
if (m == NIXIO_EXECV) {
|
||||
execv(path, args);
|
||||
} else {
|
||||
execvp(path, args);
|
||||
}
|
||||
}
|
||||
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
#ifndef __WINNT__
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/wait.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
static int nixio_fork(lua_State *L) {
|
||||
pid_t pid = fork();
|
||||
if (pid == -1) {
|
||||
|
@ -36,16 +119,55 @@ static int nixio_fork(lua_State *L) {
|
|||
}
|
||||
}
|
||||
|
||||
static int nixio_signal(lua_State *L) {
|
||||
int sig = luaL_checkinteger(L, 1);
|
||||
const char *val = luaL_checkstring(L, 2);
|
||||
static int nixio_kill(lua_State *L) {
|
||||
return nixio__pstatus(L, !kill(luaL_checkint(L, 1), luaL_checkint(L, 2)));
|
||||
}
|
||||
|
||||
if (!strcmp(val, "ign") || !strcmp(val, "ignore")) {
|
||||
return nixio__pstatus(L, signal(sig, SIG_IGN) != SIG_ERR);
|
||||
} else if (!strcmp(val, "dfl") || !strcmp(val, "default")) {
|
||||
return nixio__pstatus(L, signal(sig, SIG_DFL) != SIG_ERR);
|
||||
static int nixio_getppid(lua_State *L) {
|
||||
lua_pushinteger(L, getppid());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_getuid(lua_State *L) {
|
||||
lua_pushinteger(L, getuid());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_getgid(lua_State *L) {
|
||||
lua_pushinteger(L, getgid());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_setgid(lua_State *L) {
|
||||
return nixio__pstatus(L, !setgid(nixio__check_group(L, 1)));
|
||||
}
|
||||
|
||||
static int nixio_setuid(lua_State *L) {
|
||||
return nixio__pstatus(L, !setuid(nixio__check_user(L, 1)));
|
||||
}
|
||||
|
||||
static int nixio_nice(lua_State *L) {
|
||||
int nval = luaL_checkint(L, 1);
|
||||
|
||||
errno = 0;
|
||||
nval = nice(nval);
|
||||
|
||||
if (nval == -1 && errno) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
return luaL_argerror(L, 2, "supported values: ign, dfl");
|
||||
lua_pushinteger(L, nval);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int nixio_setsid(lua_State *L) {
|
||||
pid_t pid = setsid();
|
||||
|
||||
if (pid == -1) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
lua_pushinteger(L, pid);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,8 +219,71 @@ static int nixio_wait(lua_State *L) {
|
|||
return 3;
|
||||
}
|
||||
|
||||
static int nixio_kill(lua_State *L) {
|
||||
return nixio__pstatus(L, !kill(luaL_checkint(L, 1), luaL_checkint(L, 2)));
|
||||
static int nixio_times(lua_State *L) {
|
||||
struct tms buf;
|
||||
if (times(&buf) == -1) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
lua_createtable(L, 0, 4);
|
||||
lua_pushnumber(L, buf.tms_cstime);
|
||||
lua_setfield(L, -2, "cstime");
|
||||
|
||||
lua_pushnumber(L, buf.tms_cutime);
|
||||
lua_setfield(L, -2, "cutime");
|
||||
|
||||
lua_pushnumber(L, buf.tms_stime);
|
||||
lua_setfield(L, -2, "stime");
|
||||
|
||||
lua_pushnumber(L, buf.tms_utime);
|
||||
lua_setfield(L, -2, "utime");
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int nixio_uname(lua_State *L) {
|
||||
struct utsname buf;
|
||||
if (uname(&buf)) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
lua_createtable(L, 0, 5);
|
||||
|
||||
lua_pushstring(L, buf.machine);
|
||||
lua_setfield(L, -2, "machine");
|
||||
|
||||
lua_pushstring(L, buf.version);
|
||||
lua_setfield(L, -2, "version");
|
||||
|
||||
lua_pushstring(L, buf.release);
|
||||
lua_setfield(L, -2, "release");
|
||||
|
||||
lua_pushstring(L, buf.nodename);
|
||||
lua_setfield(L, -2, "nodename");
|
||||
|
||||
lua_pushstring(L, buf.sysname);
|
||||
lua_setfield(L, -2, "sysname");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* !__WINNT__ */
|
||||
|
||||
static int nixio_chdir(lua_State *L) {
|
||||
return nixio__pstatus(L, !chdir(luaL_checkstring(L, 1)));
|
||||
}
|
||||
|
||||
static int nixio_signal(lua_State *L) {
|
||||
int sig = luaL_checkinteger(L, 1);
|
||||
const char *val = luaL_checkstring(L, 2);
|
||||
|
||||
if (!strcmp(val, "ign") || !strcmp(val, "ignore")) {
|
||||
return nixio__pstatus(L, signal(sig, SIG_IGN) != SIG_ERR);
|
||||
} else if (!strcmp(val, "dfl") || !strcmp(val, "default")) {
|
||||
return nixio__pstatus(L, signal(sig, SIG_DFL) != SIG_ERR);
|
||||
} else {
|
||||
return luaL_argerror(L, 2, "supported values: ign, dfl");
|
||||
}
|
||||
}
|
||||
|
||||
static int nixio_getpid(lua_State *L) {
|
||||
|
@ -106,94 +291,157 @@ static int nixio_getpid(lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_getppid(lua_State *L) {
|
||||
lua_pushinteger(L, getppid());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_getuid(lua_State *L) {
|
||||
lua_pushinteger(L, getuid());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_getgid(lua_State *L) {
|
||||
lua_pushinteger(L, getgid());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_setgid(lua_State *L) {
|
||||
gid_t gid;
|
||||
if (lua_isstring(L, 1)) {
|
||||
struct group *g = getgrnam(lua_tostring(L, 1));
|
||||
gid = (!g) ? -1 : g->gr_gid;
|
||||
} else if (lua_isnumber(L, 1)) {
|
||||
gid = lua_tointeger(L, 1);
|
||||
static int nixio_getenv(lua_State *L) {
|
||||
const char *key = luaL_optstring(L, 1, NULL);
|
||||
if (key) {
|
||||
const char *val = getenv(key);
|
||||
if (val) {
|
||||
lua_pushstring(L, val);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
} else {
|
||||
return luaL_argerror(L, 1, "supported values: <groupname>, <gid>");
|
||||
lua_newtable(L);
|
||||
extern char **environ;
|
||||
for (char **c = environ; *c; c++) {
|
||||
const char *delim = strchr(*c, '=');
|
||||
if (!delim) {
|
||||
return luaL_error(L, "invalid environment");
|
||||
}
|
||||
lua_pushlstring(L, *c, delim-*c);
|
||||
lua_pushstring(L, delim + 1);
|
||||
lua_rawset(L, -3);
|
||||
}
|
||||
}
|
||||
|
||||
return nixio__pstatus(L, !setgid(gid));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_setuid(lua_State *L) {
|
||||
uid_t uid;
|
||||
if (lua_isstring(L, 1)) {
|
||||
struct passwd *p = getpwnam(lua_tostring(L, 1));
|
||||
uid = (!p) ? -1 : p->pw_uid;
|
||||
} else if (lua_isnumber(L, 1)) {
|
||||
uid = lua_tointeger(L, 1);
|
||||
} else {
|
||||
return luaL_argerror(L, 1, "supported values: <username>, <uid>");
|
||||
}
|
||||
|
||||
return nixio__pstatus(L, !setuid(uid));
|
||||
static int nixio_setenv(lua_State *L) {
|
||||
const char *key = luaL_checkstring(L, 1);
|
||||
const char *val = luaL_optstring(L, 2, NULL);
|
||||
return nixio__pstatus(L, (val) ? !setenv(key, val, 1) : !unsetenv(key));
|
||||
}
|
||||
|
||||
static int nixio_nice(lua_State *L) {
|
||||
int nval = luaL_checkint(L, 1);
|
||||
static int nixio_exec(lua_State *L) {
|
||||
return nixio__exec(L, NIXIO_EXECV);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
nval = nice(nval);
|
||||
static int nixio_execp(lua_State *L) {
|
||||
return nixio__exec(L, NIXIO_EXECVP);
|
||||
}
|
||||
|
||||
if (nval == -1 && errno) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
lua_pushinteger(L, nval);
|
||||
static int nixio_exece(lua_State *L) {
|
||||
return nixio__exec(L, NIXIO_EXECVE);
|
||||
}
|
||||
|
||||
static int nixio_getcwd(lua_State *L) {
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (getcwd(path, sizeof(path))) {
|
||||
lua_pushstring(L, path);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int nixio_setsid(lua_State *L) {
|
||||
pid_t pid = setsid();
|
||||
|
||||
if (pid == -1) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
lua_pushinteger(L, pid);
|
||||
return 1;
|
||||
return nixio__perror(L);
|
||||
}
|
||||
}
|
||||
|
||||
static int nixio_chdir(lua_State *L) {
|
||||
return nixio__pstatus(L, !chdir(luaL_checkstring(L, 1)));
|
||||
static int nixio_umask(lua_State *L) {
|
||||
char mask[9];
|
||||
lua_pushinteger(L,
|
||||
nixio__mode_write(umask(nixio__check_mode(L, 1, -1)), mask));
|
||||
lua_pushlstring(L, mask, 9);
|
||||
return 2;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
static int nixio_sysinfo(lua_State *L) {
|
||||
struct sysinfo info;
|
||||
if (sysinfo(&info)) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
lua_createtable(L, 0, 12);
|
||||
|
||||
lua_pushnumber(L, info.bufferram);
|
||||
lua_setfield(L, -2, "bufferram");
|
||||
|
||||
lua_pushnumber(L, info.freehigh);
|
||||
lua_setfield(L, -2, "freehigh");
|
||||
|
||||
lua_pushnumber(L, info.freeram);
|
||||
lua_setfield(L, -2, "freeram");
|
||||
|
||||
lua_pushnumber(L, info.freeswap);
|
||||
lua_setfield(L, -2, "freeswap");
|
||||
|
||||
lua_createtable(L, 0, 3);
|
||||
for (int i=0; i<3; i++) {
|
||||
lua_pushnumber(L, info.loads[i] / 65536.);
|
||||
lua_rawseti(L, -2, i+1);
|
||||
}
|
||||
lua_setfield(L, -2, "loads");
|
||||
|
||||
lua_pushnumber(L, info.mem_unit);
|
||||
lua_setfield(L, -2, "mem_unit");
|
||||
|
||||
lua_pushnumber(L, info.procs);
|
||||
lua_setfield(L, -2, "procs");
|
||||
|
||||
lua_pushnumber(L, info.sharedram);
|
||||
lua_setfield(L, -2, "sharedram");
|
||||
|
||||
lua_pushnumber(L, info.totalhigh);
|
||||
lua_setfield(L, -2, "totalhigh");
|
||||
|
||||
lua_pushnumber(L, info.totalram);
|
||||
lua_setfield(L, -2, "totalram");
|
||||
|
||||
lua_pushnumber(L, info.totalswap);
|
||||
lua_setfield(L, -2, "totalswap");
|
||||
|
||||
lua_pushnumber(L, info.uptime);
|
||||
lua_setfield(L, -2, "uptime");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* module table */
|
||||
static const luaL_reg R[] = {
|
||||
#ifdef __linux__
|
||||
{"sysinfo", nixio_sysinfo},
|
||||
#endif
|
||||
#ifndef __WINNT__
|
||||
{"fork", nixio_fork},
|
||||
{"wait", nixio_wait},
|
||||
{"kill", nixio_kill},
|
||||
{"nice", nixio_nice},
|
||||
{"chdir", nixio_chdir},
|
||||
{"getpid", nixio_getpid},
|
||||
{"getppid", nixio_getppid},
|
||||
{"getuid", nixio_getuid},
|
||||
{"getgid", nixio_getgid},
|
||||
{"setuid", nixio_setuid},
|
||||
{"setgid", nixio_setgid},
|
||||
{"setsid", nixio_setsid},
|
||||
{"wait", nixio_wait},
|
||||
{"waitpid", nixio_wait},
|
||||
{"times", nixio_times},
|
||||
{"uname", nixio_uname},
|
||||
#endif
|
||||
{"chdir", nixio_chdir},
|
||||
{"signal", nixio_signal},
|
||||
{"getpid", nixio_getpid},
|
||||
{"getenv", nixio_getenv},
|
||||
{"setenv", nixio_setenv},
|
||||
{"putenv", nixio_setenv},
|
||||
{"exec", nixio_exec},
|
||||
{"execp", nixio_execp},
|
||||
{"exece", nixio_exece},
|
||||
{"getcwd", nixio_getcwd},
|
||||
{"umask", nixio_umask},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -17,12 +17,9 @@
|
|||
*/
|
||||
|
||||
#include "nixio.h"
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "nixio.h"
|
||||
|
||||
|
||||
/**
|
||||
|
@ -79,7 +76,7 @@ static int nixio_socket(lua_State *L) {
|
|||
sock->fd = socket(sock->domain, sock->type, sock->protocol);
|
||||
|
||||
if (sock->fd < 0) {
|
||||
return nixio__perror(L);
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -95,10 +92,14 @@ static int nixio_sock_close(lua_State *L) {
|
|||
sock->fd = -1;
|
||||
|
||||
do {
|
||||
#ifndef __WINNT__
|
||||
res = close(sockfd);
|
||||
#else
|
||||
res = closesocket(sockfd);
|
||||
#endif
|
||||
} while (res == -1 && errno == EINTR);
|
||||
|
||||
return nixio__pstatus(L, !res);
|
||||
return nixio__pstatus_s(L, !res);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,7 +110,11 @@ static int nixio_sock__gc(lua_State *L) {
|
|||
int res;
|
||||
if (sock && sock->fd != -1) {
|
||||
do {
|
||||
#ifndef __WINNT__
|
||||
res = close(sock->fd);
|
||||
#else
|
||||
res = closesocket(sock->fd);
|
||||
#endif
|
||||
} while (res == -1 && errno == EINTR);
|
||||
}
|
||||
return 0;
|
||||
|
@ -141,7 +146,7 @@ static int nixio_sock_shutdown(lua_State *L) {
|
|||
return luaL_argerror(L, 2, "supported values: both, read, write");
|
||||
}
|
||||
|
||||
return nixio__pstatus(L, !shutdown(sockfd, how));
|
||||
return nixio__pstatus_s(L, !shutdown(sockfd, how));
|
||||
}
|
||||
|
||||
/* module table */
|
||||
|
|
|
@ -17,17 +17,25 @@
|
|||
*/
|
||||
|
||||
#include "nixio.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/time.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include "nixio.h"
|
||||
|
||||
#ifndef IPV6_ADD_MEMBERSHIP
|
||||
#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
|
||||
#endif
|
||||
|
||||
#ifndef IPV6_DROP_MEMBERSHIP
|
||||
#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
|
||||
#endif
|
||||
|
||||
static int nixio_sock_fileno(lua_State *L) {
|
||||
lua_pushinteger(L, nixio__checkfd(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* setblocking()
|
||||
|
@ -36,6 +44,9 @@ static int nixio_sock_setblocking(lua_State *L) {
|
|||
int fd = nixio__checkfd(L, 1);
|
||||
luaL_checkany(L, 2);
|
||||
int set = lua_toboolean(L, 2);
|
||||
|
||||
#ifndef __WINNT__
|
||||
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
|
||||
if (flags == -1) {
|
||||
|
@ -49,50 +60,64 @@ static int nixio_sock_setblocking(lua_State *L) {
|
|||
}
|
||||
|
||||
return nixio__pstatus(L, !fcntl(fd, F_SETFL, flags));
|
||||
|
||||
#else /* __WINNT__ */
|
||||
|
||||
lua_getmetatable(L, 1);
|
||||
luaL_getmetatable(L, NIXIO_META);
|
||||
if (lua_equal(L, -1, -2)) { /* Socket */
|
||||
unsigned long val = !set;
|
||||
return nixio__pstatus_s(L, !ioctlsocket(fd, FIONBIO, &val));
|
||||
} else { /* File */
|
||||
WSASetLastError(WSAENOTSOCK);
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
|
||||
#endif /* __WINNT__ */
|
||||
}
|
||||
|
||||
static int nixio__gso_int(lua_State *L, int fd, int level, int opt, int set) {
|
||||
int value;
|
||||
socklen_t optlen = sizeof(value);
|
||||
if (!set) {
|
||||
if (!getsockopt(fd, level, opt, &value, &optlen)) {
|
||||
if (!getsockopt(fd, level, opt, (char *)&value, &optlen)) {
|
||||
lua_pushinteger(L, value);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
value = luaL_checkinteger(L, set);
|
||||
if (!setsockopt(fd, level, opt, &value, optlen)) {
|
||||
if (!setsockopt(fd, level, opt, (char *)&value, optlen)) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return nixio__perror(L);
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
|
||||
static int nixio__gso_ling(lua_State *L, int fd, int level, int opt, int set) {
|
||||
struct linger value;
|
||||
socklen_t optlen = sizeof(value);
|
||||
if (!set) {
|
||||
if (!getsockopt(fd, level, opt, &value, &optlen)) {
|
||||
if (!getsockopt(fd, level, opt, (char *)&value, &optlen)) {
|
||||
lua_pushinteger(L, value.l_onoff ? value.l_linger : 0);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
value.l_linger = luaL_checkinteger(L, set);
|
||||
value.l_onoff = value.l_linger ? 1 : 0;
|
||||
if (!setsockopt(fd, level, opt, &value, optlen)) {
|
||||
if (!setsockopt(fd, level, opt, (char *)&value, optlen)) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return nixio__perror(L);
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
|
||||
static int nixio__gso_timev(lua_State *L, int fd, int level, int opt, int set) {
|
||||
struct timeval value;
|
||||
socklen_t optlen = sizeof(value);
|
||||
if (!set) {
|
||||
if (!getsockopt(fd, level, opt, &value, &optlen)) {
|
||||
if (!getsockopt(fd, level, opt, (char *)&value, &optlen)) {
|
||||
lua_pushinteger(L, value.tv_sec);
|
||||
lua_pushinteger(L, value.tv_usec);
|
||||
return 2;
|
||||
|
@ -100,12 +125,12 @@ static int nixio__gso_timev(lua_State *L, int fd, int level, int opt, int set) {
|
|||
} else {
|
||||
value.tv_sec = luaL_checkinteger(L, set);
|
||||
value.tv_usec = luaL_optinteger(L, set + 1, 0);
|
||||
if (!setsockopt(fd, level, opt, &value, optlen)) {
|
||||
if (!setsockopt(fd, level, opt, (char *)&value, optlen)) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return nixio__perror(L);
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
|
||||
#ifdef SO_BINDTODEVICE
|
||||
|
@ -114,7 +139,7 @@ static int nixio__gso_b(lua_State *L, int fd, int level, int opt, int set) {
|
|||
if (!set) {
|
||||
socklen_t optlen = IFNAMSIZ;
|
||||
char ifname[IFNAMSIZ];
|
||||
if (!getsockopt(fd, level, opt, ifname, &optlen)) {
|
||||
if (!getsockopt(fd, level, opt, (char *)ifname, &optlen)) {
|
||||
lua_pushlstring(L, ifname, optlen);
|
||||
return 1;
|
||||
}
|
||||
|
@ -122,16 +147,76 @@ static int nixio__gso_b(lua_State *L, int fd, int level, int opt, int set) {
|
|||
size_t valuelen;
|
||||
const char *value = luaL_checklstring(L, set, &valuelen);
|
||||
luaL_argcheck(L, valuelen <= IFNAMSIZ, set, "invalid interface name");
|
||||
if (!setsockopt(fd, level, opt, value, valuelen)) {
|
||||
if (!setsockopt(fd, level, opt, (char *)value, valuelen)) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return nixio__perror(L);
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
|
||||
#endif /* SO_BINDTODEVICE */
|
||||
|
||||
static int nixio__gso_mreq4(lua_State *L, int fd, int level, int opt, int set) {
|
||||
struct ip_mreq value;
|
||||
socklen_t optlen = sizeof(value);
|
||||
if (!set) {
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
if (!getsockopt(fd, level, opt, (char *)&value, &optlen)) {
|
||||
if (!inet_ntop(AF_INET, &value.imr_multiaddr, buf, sizeof(buf))) {
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
lua_pushstring(L, buf);
|
||||
if (!inet_ntop(AF_INET, &value.imr_interface, buf, sizeof(buf))) {
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
lua_pushstring(L, buf);
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
const char *maddr = luaL_checkstring(L, set);
|
||||
const char *iface = luaL_optstring(L, set + 1, "0.0.0.0");
|
||||
if (inet_pton(AF_INET, maddr, &value.imr_multiaddr) < 1) {
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
if (inet_pton(AF_INET, iface, &value.imr_interface) < 1) {
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
if (!setsockopt(fd, level, opt, (char *)&value, optlen)) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
|
||||
static int nixio__gso_mreq6(lua_State *L, int fd, int level, int opt, int set) {
|
||||
struct ipv6_mreq val;
|
||||
socklen_t optlen = sizeof(val);
|
||||
if (!set) {
|
||||
char buf[INET_ADDRSTRLEN];
|
||||
if (!getsockopt(fd, level, opt, (char *)&val, &optlen)) {
|
||||
if (!inet_ntop(AF_INET6, &val.ipv6mr_multiaddr, buf, sizeof(buf))) {
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
lua_pushstring(L, buf);
|
||||
lua_pushnumber(L, val.ipv6mr_interface);
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
const char *maddr = luaL_checkstring(L, set);
|
||||
if (inet_pton(AF_INET6, maddr, &val.ipv6mr_multiaddr) < 1) {
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
val.ipv6mr_interface = luaL_optlong(L, set + 1, 0);
|
||||
if (!setsockopt(fd, level, opt, (char *)&val, optlen)) {
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return nixio__perror_s(L);
|
||||
}
|
||||
|
||||
/**
|
||||
* get/setsockopt() helper
|
||||
*/
|
||||
|
@ -183,9 +268,6 @@ static int nixio__getsetsockopt(lua_State *L, int set) {
|
|||
);
|
||||
}
|
||||
} else if (!strcmp(level, "tcp")) {
|
||||
if (sock->type != SOCK_STREAM) {
|
||||
return luaL_error(L, "not a TCP socket");
|
||||
}
|
||||
if (!strcmp(option, "cork")) {
|
||||
#ifdef TCP_CORK
|
||||
return nixio__gso_int(L, sock->fd, IPPROTO_TCP, TCP_CORK, set);
|
||||
|
@ -197,8 +279,71 @@ static int nixio__getsetsockopt(lua_State *L, int set) {
|
|||
} else {
|
||||
return luaL_argerror(L, 3, "supported values: cork, nodelay");
|
||||
}
|
||||
} else if (!strcmp(level, "ip")) {
|
||||
if (!strcmp(option, "mtu")) {
|
||||
#ifdef IP_MTU
|
||||
return nixio__gso_int(L, sock->fd, IPPROTO_IP, IP_MTU, set);
|
||||
#else
|
||||
return nixio__pstatus(L, !(errno = ENOPROTOOPT));
|
||||
#endif
|
||||
} else if (!strcmp(option, "hdrincl")) {
|
||||
return nixio__gso_int(L, sock->fd, IPPROTO_IP, IP_HDRINCL,
|
||||
set);
|
||||
} else if (!strcmp(option, "multicast_loop")) {
|
||||
return nixio__gso_int(L, sock->fd, IPPROTO_IP, IP_MULTICAST_LOOP,
|
||||
set);
|
||||
} else if (!strcmp(option, "multicast_ttl")) {
|
||||
return nixio__gso_int(L, sock->fd, IPPROTO_IP, IP_MULTICAST_TTL,
|
||||
set);
|
||||
} else if (!strcmp(option, "multicast_if")) {
|
||||
return nixio__gso_mreq4(L, sock->fd, IPPROTO_IP, IP_MULTICAST_IF,
|
||||
set);
|
||||
} else if (!strcmp(option, "add_membership")) {
|
||||
return nixio__gso_mreq4(L, sock->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||
set);
|
||||
} else if (!strcmp(option, "drop_membership")) {
|
||||
return nixio__gso_mreq4(L, sock->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
|
||||
set);
|
||||
} else {
|
||||
return luaL_argerror(L, 3,
|
||||
"supported values: hdrincl, mtu, multicast_loop, "
|
||||
"multicast_ttl, multicast_if, add_membership, drop_membership");
|
||||
}
|
||||
} else if (!strcmp(level, "ipv6")) {
|
||||
if (!strcmp(option, "mtu")) {
|
||||
#ifdef IPV6_MTU
|
||||
return nixio__gso_int(L, sock->fd, IPPROTO_IPV6, IPV6_MTU, set);
|
||||
#else
|
||||
return nixio__pstatus(L, !(errno = ENOPROTOOPT));
|
||||
#endif
|
||||
} else if (!strcmp(option, "v6only")) {
|
||||
#ifdef IPV6_V6ONLY
|
||||
return nixio__gso_int(L, sock->fd, IPPROTO_IPV6, IPV6_V6ONLY, set);
|
||||
#else
|
||||
return nixio__pstatus(L, !(errno = ENOPROTOOPT));
|
||||
#endif
|
||||
} else if (!strcmp(option, "multicast_loop")) {
|
||||
return nixio__gso_int(L, sock->fd, IPPROTO_IPV6,
|
||||
IPV6_MULTICAST_LOOP, set);
|
||||
} else if (!strcmp(option, "multicast_hops")) {
|
||||
return nixio__gso_int(L, sock->fd, IPPROTO_IPV6,
|
||||
IPV6_MULTICAST_HOPS, set);
|
||||
} else if (!strcmp(option, "multicast_if")) {
|
||||
return nixio__gso_mreq6(L, sock->fd, IPPROTO_IPV6,
|
||||
IPV6_MULTICAST_IF, set);
|
||||
} else if (!strcmp(option, "add_membership")) {
|
||||
return nixio__gso_mreq6(L, sock->fd, IPPROTO_IPV6,
|
||||
IPV6_ADD_MEMBERSHIP, set);
|
||||
} else if (!strcmp(option, "drop_membership")) {
|
||||
return nixio__gso_mreq6(L, sock->fd, IPPROTO_IPV6,
|
||||
IPV6_DROP_MEMBERSHIP, set);
|
||||
} else {
|
||||
return luaL_argerror(L, 3,
|
||||
"supported values: v6only, mtu, multicast_loop, multicast_hops,"
|
||||
" multicast_if, add_membership, drop_membership");
|
||||
}
|
||||
} else {
|
||||
return luaL_argerror(L, 2, "supported values: socket, tcp");
|
||||
return luaL_argerror(L, 2, "supported values: socket, tcp, ip, ipv6");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,6 +366,9 @@ static const luaL_reg M[] = {
|
|||
{"setblocking", nixio_sock_setblocking},
|
||||
{"getsockopt", nixio_sock_getsockopt},
|
||||
{"setsockopt", nixio_sock_setsockopt},
|
||||
{"getopt", nixio_sock_getsockopt},
|
||||
{"setopt", nixio_sock_setsockopt},
|
||||
{"fileno", nixio_sock_fileno},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -232,5 +380,7 @@ void nixio_open_sockopt(lua_State *L) {
|
|||
luaL_getmetatable(L, NIXIO_FILE_META);
|
||||
lua_pushcfunction(L, nixio_sock_setblocking);
|
||||
lua_setfield(L, -2, "setblocking");
|
||||
lua_pushcfunction(L, nixio_sock_fileno);
|
||||
lua_setfield(L, -2, "fileno");
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
|
||||
#ifndef __WINNT__
|
||||
|
||||
#ifndef BSD
|
||||
#include <sys/sendfile.h>
|
||||
#else
|
||||
|
@ -150,6 +153,14 @@ static const luaL_reg R[] = {
|
|||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
void nixio_open_splice(lua_State *L) {
|
||||
luaL_register(L, NULL, R);
|
||||
}
|
||||
|
||||
#else /* __WINNT__ */
|
||||
|
||||
void nixio_open_splice(lua_State *L) {
|
||||
}
|
||||
|
||||
#endif /* !__WINNT__ */
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include "nixio.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef __WINNT__
|
||||
#include <syslog.h>
|
||||
|
||||
|
||||
|
@ -57,7 +59,7 @@ static int nixio_closelog(lua_State *L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int nixio__syslogmasg(lua_State *L, int dolog) {
|
||||
static int nixio__syslogmask(lua_State *L, int dolog) {
|
||||
int priority;
|
||||
|
||||
const char *flag = luaL_checkstring(L, 1);
|
||||
|
@ -92,11 +94,11 @@ static int nixio__syslogmasg(lua_State *L, int dolog) {
|
|||
}
|
||||
|
||||
static int nixio_setlogmask(lua_State *L) {
|
||||
return nixio__syslogmasg(L, 0);
|
||||
return nixio__syslogmask(L, 0);
|
||||
}
|
||||
|
||||
static int nixio_syslog(lua_State *L) {
|
||||
return nixio__syslogmasg(L, 1);
|
||||
return nixio__syslogmask(L, 1);
|
||||
}
|
||||
|
||||
/* module table */
|
||||
|
@ -111,3 +113,10 @@ static const luaL_reg R[] = {
|
|||
void nixio_open_syslog(lua_State *L) {
|
||||
luaL_register(L, NULL, R);
|
||||
}
|
||||
|
||||
#else /* __WINNT__ */
|
||||
|
||||
void nixio_open_syslog(lua_State *L) {
|
||||
}
|
||||
|
||||
#endif /* __WINNT__ */
|
||||
|
|
188
libs/nixio/src/tls-crypto.c
Normal file
188
libs/nixio/src/tls-crypto.c
Normal file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* nixio - Linux I/O library for lua
|
||||
*
|
||||
* Copyright (C) 2009 Steven Barth <steven@midlink.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "nixio-tls.h"
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static char nixio__bin2hex[] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
|
||||
};
|
||||
|
||||
static int nixio_crypto_hash__init(lua_State *L, int hmac) {
|
||||
const char *type = luaL_checkstring(L, 1);
|
||||
nixio_hash *hash = lua_newuserdata(L, sizeof(nixio_hash));
|
||||
|
||||
if (!strcmp(type, "md5")) {
|
||||
hash->type = NIXIO_HASH_MD5;
|
||||
hash->digest_size = MD5_DIGEST_LENGTH;
|
||||
hash->block_size = 64;
|
||||
hash->ctx = malloc(sizeof(MD5_CTX));
|
||||
if (!hash->ctx) {
|
||||
return luaL_error(L, NIXIO_OOM);
|
||||
}
|
||||
MD5_Init((MD5_CTX*)hash->ctx);
|
||||
hash->init = (nixio_hash_initcb)MD5_Init;
|
||||
hash->update = (nixio_hash_updatecb)MD5_Update;
|
||||
hash->final = (nixio_hash_finalcb)MD5_Final;
|
||||
} else if (!strcmp(type, "sha1")) {
|
||||
hash->type = NIXIO_HASH_SHA1;
|
||||
hash->digest_size = SHA_DIGEST_LENGTH;
|
||||
hash->block_size = 64;
|
||||
hash->ctx = malloc(sizeof(SHA_CTX));
|
||||
if (!hash->ctx) {
|
||||
return luaL_error(L, NIXIO_OOM);
|
||||
}
|
||||
SHA1_Init((SHA_CTX*)hash->ctx);
|
||||
hash->init = (nixio_hash_initcb)SHA1_Init;
|
||||
hash->update = (nixio_hash_updatecb)SHA1_Update;
|
||||
hash->final = (nixio_hash_finalcb)SHA1_Final;
|
||||
} else {
|
||||
luaL_argerror(L, 1, "supported values: md5, sha1");
|
||||
}
|
||||
|
||||
luaL_getmetatable(L, NIXIO_CRYPTO_HASH_META);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
if (hmac) {
|
||||
const char *key = luaL_checklstring(L, 2, &hash->key_size);
|
||||
if (hash->key_size > hash->block_size) {
|
||||
hash->update(hash->ctx, key, hash->key_size);
|
||||
hash->final(hash->digest, hash->ctx);
|
||||
hash->init(hash->ctx);
|
||||
hash->key_size = hash->digest_size;
|
||||
memcpy(hash->key, hash->digest, hash->key_size);
|
||||
} else {
|
||||
memcpy(hash->key, key, hash->key_size);
|
||||
}
|
||||
|
||||
unsigned char pad[NIXIO_CRYPTO_BLOCK_SIZE];
|
||||
for (uint i = 0; i < hash->block_size; i++) {
|
||||
pad[i] = (i < hash->key_size) ? (0x36 ^ hash->key[i]) : 0x36;
|
||||
}
|
||||
hash->update(hash->ctx, pad, hash->block_size);
|
||||
hash->type |= NIXIO_HMAC_BIT;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_crypto_hash(lua_State *L) {
|
||||
return nixio_crypto_hash__init(L, 0);
|
||||
}
|
||||
|
||||
static int nixio_crypto_hmac(lua_State *L) {
|
||||
return nixio_crypto_hash__init(L, 1);
|
||||
}
|
||||
|
||||
static int nixio_crypto_hash_update(lua_State *L) {
|
||||
nixio_hash *hash = luaL_checkudata(L, 1, NIXIO_CRYPTO_HASH_META);
|
||||
if (hash->type) {
|
||||
size_t len;
|
||||
const char *chunk = luaL_checklstring(L, 2, &len);
|
||||
hash->update(hash->ctx, chunk, len);
|
||||
lua_pushvalue(L, 1);
|
||||
return 1;
|
||||
} else {
|
||||
return luaL_error(L, "Tried to update finalized hash object.");
|
||||
}
|
||||
}
|
||||
|
||||
static int nixio_crypto_hash_final(lua_State *L) {
|
||||
nixio_hash *hash = luaL_checkudata(L, 1, NIXIO_CRYPTO_HASH_META);
|
||||
if (hash->type & NIXIO_HMAC_BIT) {
|
||||
hash->final(hash->digest, hash->ctx);
|
||||
hash->init(hash->ctx);
|
||||
|
||||
unsigned char pad[NIXIO_CRYPTO_BLOCK_SIZE];
|
||||
for (uint i = 0; i < hash->block_size; i++) {
|
||||
pad[i] = (i < hash->key_size) ? (0x5c ^ hash->key[i]) : 0x5c;
|
||||
}
|
||||
|
||||
hash->update(hash->ctx, pad, hash->block_size);
|
||||
hash->update(hash->ctx, hash->digest, hash->digest_size);
|
||||
}
|
||||
|
||||
if (hash->type) {
|
||||
hash->type = NIXIO_HASH_NONE;
|
||||
hash->final(hash->digest, hash->ctx);
|
||||
free(hash->ctx);
|
||||
}
|
||||
|
||||
char hashdigest[NIXIO_DIGEST_SIZE*2];
|
||||
for (uint i=0; i < hash->digest_size; i++) {
|
||||
hashdigest[2*i] = nixio__bin2hex[(hash->digest[i] & 0xf0) >> 4];
|
||||
hashdigest[2*i+1] = nixio__bin2hex[(hash->digest[i] & 0x0f)];
|
||||
}
|
||||
|
||||
lua_pushlstring(L, hashdigest, hash->digest_size * 2);
|
||||
memcpy(hashdigest, hash->digest, hash->digest_size);
|
||||
lua_pushlstring(L, hashdigest, hash->digest_size);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int nixio_crypto_hash__gc(lua_State *L) {
|
||||
nixio_hash *hash = luaL_checkudata(L, 1, NIXIO_CRYPTO_HASH_META);
|
||||
if (hash->type) {
|
||||
hash->final(hash->digest, hash->ctx);
|
||||
free(hash->ctx);
|
||||
hash->type = NIXIO_HASH_NONE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nixio_crypto_hash__tostring(lua_State *L) {
|
||||
nixio_hash *hash = luaL_checkudata(L, 1, NIXIO_CRYPTO_HASH_META);
|
||||
lua_pushfstring(L, "nixio hash object: %p", hash);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* module table */
|
||||
static const luaL_reg R[] = {
|
||||
{"hash", nixio_crypto_hash},
|
||||
{"hmac", nixio_crypto_hmac},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/* hash table */
|
||||
static const luaL_reg M[] = {
|
||||
{"update", nixio_crypto_hash_update},
|
||||
{"final", nixio_crypto_hash_final},
|
||||
{"__gc", nixio_crypto_hash__gc},
|
||||
{"__tostring", nixio_crypto_hash__tostring},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
|
||||
void nixio_open_tls_crypto(lua_State *L) {
|
||||
luaL_newmetatable(L, NIXIO_CRYPTO_HASH_META);
|
||||
luaL_register(L, NULL, M);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_newtable(L);
|
||||
luaL_register(L, NULL, R);
|
||||
|
||||
lua_setfield(L, -2, "crypto");
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* nixio - Linux I/O library for lua
|
||||
*
|
||||
* Copyright (C) 2009 Steven Barth <steven@midlink.org>
|
||||
|
@ -65,7 +65,7 @@ static SSL* nixio__checktlssock(lua_State *L) {
|
|||
static int nixio_tls_sock_recv(lua_State *L) {
|
||||
SSL *sock = nixio__checktlssock(L);
|
||||
nixio_tls__check_connected(L);
|
||||
int req = luaL_checkinteger(L, 2);
|
||||
uint req = luaL_checkinteger(L, 2);
|
||||
|
||||
luaL_argcheck(L, req >= 0, 2, "out of range");
|
||||
|
||||
|
@ -172,6 +172,24 @@ static int nixio_tls_sock_send(lua_State *L) {
|
|||
size_t len;
|
||||
ssize_t sent;
|
||||
const char *data = luaL_checklstring(L, 2, &len);
|
||||
|
||||
if (lua_gettop(L) > 2) {
|
||||
int offset = luaL_optint(L, 3, 0);
|
||||
if (offset) {
|
||||
if (offset < len) {
|
||||
data += offset;
|
||||
len -= offset;
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int wlen = luaL_optint(L, 4, len);
|
||||
if (wlen < len) {
|
||||
len = wlen;
|
||||
}
|
||||
}
|
||||
|
||||
sent = SSL_write(sock, data, len);
|
||||
if (sent > 0) {
|
||||
lua_pushinteger(L, sent);
|
||||
|
|
257
libs/nixio/src/user.c
Normal file
257
libs/nixio/src/user.c
Normal file
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
* nixio - Linux I/O library for lua
|
||||
*
|
||||
* Copyright (C) 2009 Steven Barth <steven@midlink.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "nixio.h"
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifndef __WINNT__
|
||||
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#ifndef BSD
|
||||
#include <shadow.h>
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
|
||||
int nixio__check_group(lua_State *L, int idx) {
|
||||
if (lua_isnumber(L, idx)) {
|
||||
return lua_tointeger(L, idx);
|
||||
} else if (lua_isstring(L, idx)) {
|
||||
struct group *g = getgrnam(lua_tostring(L, idx));
|
||||
return (!g) ? -1 : g->gr_gid;
|
||||
} else {
|
||||
return luaL_argerror(L, idx, "supported values: <groupname>, <gid>");
|
||||
}
|
||||
}
|
||||
|
||||
int nixio__check_user(lua_State *L, int idx) {
|
||||
if (lua_isnumber(L, idx)) {
|
||||
return lua_tointeger(L, idx);
|
||||
} else if (lua_isstring(L, idx)) {
|
||||
struct passwd *p = getpwnam(lua_tostring(L, idx));
|
||||
return (!p) ? -1 : p->pw_uid;
|
||||
} else {
|
||||
return luaL_argerror(L, idx, "supported values: <username>, <uid>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int nixio__push_group(lua_State *L, struct group *gr) {
|
||||
lua_createtable(L, 0, 4);
|
||||
lua_pushstring(L, gr->gr_name);
|
||||
lua_setfield(L, -2, "name");
|
||||
lua_pushstring(L, gr->gr_passwd);
|
||||
lua_setfield(L, -2, "passwd");
|
||||
lua_pushinteger(L, gr->gr_gid);
|
||||
lua_setfield(L, -2, "gid");
|
||||
lua_newtable(L);
|
||||
|
||||
for (int i=0; gr->gr_mem[i]; i++) {
|
||||
lua_pushstring(L, gr->gr_mem[i]);
|
||||
lua_rawseti(L, -2, i+1);
|
||||
}
|
||||
|
||||
lua_setfield(L, -2, "mem");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_getgr(lua_State *L) {
|
||||
struct group *gr;
|
||||
errno = 0;
|
||||
if (lua_isnumber(L, 1)) {
|
||||
gr = getgrgid(lua_tonumber(L, 1));
|
||||
} else if (lua_isstring(L, 1)) {
|
||||
gr = getgrnam(lua_tostring(L, 1));
|
||||
} else if (lua_isnoneornil(L, 1)) {
|
||||
lua_newtable(L);
|
||||
int i = 0;
|
||||
|
||||
setgrent();
|
||||
while ((gr = getgrent())) {
|
||||
nixio__push_group(L, gr);
|
||||
lua_rawseti(L, -2, ++i);
|
||||
}
|
||||
|
||||
if (errno) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
endgrent();
|
||||
return 1;
|
||||
} else {
|
||||
return luaL_argerror(L, 1, "supported values: <groupname>, <gid>");
|
||||
}
|
||||
|
||||
if (!gr) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
return nixio__push_group(L, gr);
|
||||
}
|
||||
}
|
||||
|
||||
static int nixio__push_passwd(lua_State *L, struct passwd *pw) {
|
||||
lua_createtable(L, 0, 7);
|
||||
lua_pushstring(L, pw->pw_name);
|
||||
lua_setfield(L, -2, "name");
|
||||
lua_pushstring(L, pw->pw_passwd);
|
||||
lua_setfield(L, -2, "passwd");
|
||||
lua_pushinteger(L, pw->pw_gid);
|
||||
lua_setfield(L, -2, "gid");
|
||||
lua_pushinteger(L, pw->pw_uid);
|
||||
lua_setfield(L, -2, "uid");
|
||||
lua_pushstring(L, pw->pw_dir);
|
||||
lua_setfield(L, -2, "dir");
|
||||
lua_pushstring(L, pw->pw_gecos);
|
||||
lua_setfield(L, -2, "gecos");
|
||||
lua_pushstring(L, pw->pw_shell);
|
||||
lua_setfield(L, -2, "shell");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_getpw(lua_State *L) {
|
||||
struct passwd *pw;
|
||||
errno = 0;
|
||||
if (lua_isnumber(L, 1)) {
|
||||
pw = getpwuid(lua_tonumber(L, 1));
|
||||
} else if (lua_isstring(L, 1)) {
|
||||
pw = getpwnam(lua_tostring(L, 1));
|
||||
} else if (lua_isnoneornil(L, 1)) {
|
||||
lua_newtable(L);
|
||||
int i = 0;
|
||||
|
||||
setpwent();
|
||||
while ((pw = getpwent())) {
|
||||
nixio__push_passwd(L, pw);
|
||||
lua_rawseti(L, -2, ++i);
|
||||
}
|
||||
|
||||
if (errno) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
endpwent();
|
||||
return 1;
|
||||
} else {
|
||||
return luaL_argerror(L, 1, "supported values: <username>, <uid>");
|
||||
}
|
||||
|
||||
if (!pw) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
return nixio__push_passwd(L, pw);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BSD
|
||||
static int nixio__push_spwd(lua_State *L, struct spwd *sp) {
|
||||
lua_createtable(L, 0, 9);
|
||||
lua_pushstring(L, sp->sp_namp);
|
||||
lua_setfield(L, -2, "namp");
|
||||
lua_pushinteger(L, sp->sp_expire);
|
||||
lua_setfield(L, -2, "expire");
|
||||
lua_pushinteger(L, sp->sp_flag);
|
||||
lua_setfield(L, -2, "flag");
|
||||
lua_pushinteger(L, sp->sp_inact);
|
||||
lua_setfield(L, -2, "inact");
|
||||
lua_pushinteger(L, sp->sp_lstchg);
|
||||
lua_setfield(L, -2, "lstchg");
|
||||
lua_pushinteger(L, sp->sp_max);
|
||||
lua_setfield(L, -2, "max");
|
||||
lua_pushinteger(L, sp->sp_min);
|
||||
lua_setfield(L, -2, "min");
|
||||
lua_pushinteger(L, sp->sp_warn);
|
||||
lua_setfield(L, -2, "warn");
|
||||
lua_pushstring(L, sp->sp_pwdp);
|
||||
lua_setfield(L, -2, "pwdp");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nixio_getsp(lua_State *L) {
|
||||
struct spwd *sp;
|
||||
errno = 0;
|
||||
if (lua_isstring(L, 1)) {
|
||||
sp = getspnam(lua_tostring(L, 1));
|
||||
} else if (lua_isnoneornil(L, 1)) {
|
||||
lua_newtable(L);
|
||||
int i = 0;
|
||||
|
||||
setspent();
|
||||
while ((sp = getspent())) {
|
||||
nixio__push_spwd(L, sp);
|
||||
lua_rawseti(L, -2, ++i);
|
||||
}
|
||||
|
||||
if (errno) {
|
||||
return nixio__perror(L);
|
||||
}
|
||||
|
||||
endspent();
|
||||
return 1;
|
||||
} else {
|
||||
return luaL_argerror(L, 1, "supported values: <username>");
|
||||
}
|
||||
|
||||
if (!sp) {
|
||||
return nixio__perror(L);
|
||||
} else {
|
||||
return nixio__push_spwd(L, sp);
|
||||
}
|
||||
}
|
||||
#endif /* !BSD */
|
||||
|
||||
static int nixio_crypt(lua_State *L) {
|
||||
const char *key = luaL_checkstring(L, 1);
|
||||
const char *salt = luaL_checkstring(L, 2);
|
||||
const char *hash = crypt(key, salt);
|
||||
|
||||
if (hash) {
|
||||
lua_pushstring(L, hash);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* module table */
|
||||
static const luaL_reg R[] = {
|
||||
{"crypt", nixio_crypt},
|
||||
{"getgr", nixio_getgr},
|
||||
{"getpw", nixio_getpw},
|
||||
#ifndef BSD
|
||||
{"getsp", nixio_getsp},
|
||||
#endif
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
#else /* __WINNT__ */
|
||||
|
||||
static const luaL_reg R[] = {
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
void nixio_open_user(lua_State *L) {
|
||||
luaL_register(L, NULL, R);
|
||||
}
|
56
libs/nixio/standalone.mk
Normal file
56
libs/nixio/standalone.mk
Normal file
|
@ -0,0 +1,56 @@
|
|||
LUAC = luac
|
||||
LUAC_OPTIONS = -s
|
||||
LUA_TARGET ?= source
|
||||
|
||||
LUA_MODULEDIR = /usr/local/share/lua/5.1
|
||||
LUA_LIBRARYDIR = /usr/local/lib/lua/5.1
|
||||
|
||||
OS ?= $(shell uname)
|
||||
|
||||
LUA_SHLIBS = $(shell pkg-config --silence-errors --libs lua5.1 || pkg-config --silence-errors --libs lua-5.1 || pkg-config --silence-errors --libs lua)
|
||||
LUA_LIBS = $(if $(LUA_SHLIBS),$(LUA_SHLIBS),$(firstword $(wildcard /usr/lib/liblua.a /usr/local/lib/liblua.a /opt/local/lib/liblua.a)))
|
||||
LUA_CFLAGS = $(shell pkg-config --silence-errors --cflags lua5.1 || pkg-config --silence-errors --cflags lua-5.1 || pkg-config --silence-errors --cflags lua)
|
||||
|
||||
CC = gcc
|
||||
AR = ar
|
||||
RANLIB = ranlib
|
||||
CFLAGS = -O2
|
||||
FPIC = -fPIC
|
||||
EXTRA_CFLAGS = --std=gnu99
|
||||
WFLAGS = -Wall -Werror -pedantic
|
||||
CPPFLAGS =
|
||||
COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) $(WFLAGS)
|
||||
ifeq ($(OS),Darwin)
|
||||
SHLIB_FLAGS = -bundle -undefined dynamic_lookup
|
||||
else
|
||||
SHLIB_FLAGS = -shared
|
||||
endif
|
||||
LINK = $(CC) $(LDFLAGS)
|
||||
|
||||
.PHONY: all build compile luacompile luasource clean luaclean
|
||||
|
||||
all: build
|
||||
|
||||
build: luabuild gccbuild
|
||||
|
||||
luabuild: lua$(LUA_TARGET)
|
||||
|
||||
gccbuild: compile
|
||||
compile:
|
||||
|
||||
clean: luaclean
|
||||
|
||||
luasource:
|
||||
mkdir -p dist$(LUA_MODULEDIR)
|
||||
cp -pR root/* dist 2>/dev/null || true
|
||||
cp -pR lua/* dist$(LUA_MODULEDIR) 2>/dev/null || true
|
||||
for i in $$(find dist -name .svn); do rm -rf $$i || true; done
|
||||
|
||||
luastrip: luasource
|
||||
for i in $$(find dist -type f -name '*.lua'); do perl -e 'undef $$/; open( F, "< $$ARGV[0]" ) || die $$!; $$src = <F>; close F; $$src =~ s/--\[\[.*?\]\](--)?//gs; $$src =~ s/^\s*--.*?\n//gm; open( F, "> $$ARGV[0]" ) || die $$!; print F $$src; close F' $$i; done
|
||||
|
||||
luacompile: luasource
|
||||
for i in $$(find dist -name *.lua -not -name debug.lua); do $(LUAC) $(LUAC_OPTIONS) -o $$i $$i; done
|
||||
|
||||
luaclean:
|
||||
rm -rf dist
|
Loading…
Reference in a new issue