Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
lua-apr/src/lua_apr.c
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
452 lines (386 sloc)
13.3 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* Miscellaneous functions module for the Lua/APR binding. | |
| * | |
| * Author: Peter Odding <peter@peterodding.com> | |
| * Last Change: November 20, 2011 | |
| * Homepage: http://peterodding.com/code/lua/apr/ | |
| * License: MIT | |
| */ | |
| #include "lua_apr.h" | |
| #include <apr_ldap.h> /* APR_HAS_LDAP */ | |
| #include <apr_portable.h> | |
| #include <ctype.h> | |
| #if LUA_APR_HAVE_APREQ | |
| #include <apreq_version.h> | |
| #endif | |
| /* Used to make sure that APR is only initialized once. */ | |
| static int apr_was_initialized = 0; | |
| /* List of all userdata types exposed to Lua by the binding. */ | |
| lua_apr_objtype *lua_apr_types[] = { | |
| &lua_apr_file_type, | |
| &lua_apr_dir_type, | |
| &lua_apr_socket_type, | |
| # if APR_HAS_THREADS | |
| &lua_apr_thread_type, | |
| &lua_apr_queue_type, | |
| # endif | |
| &lua_apr_pollset_type, | |
| &lua_apr_proc_type, | |
| &lua_apr_dbm_type, | |
| &lua_apr_dbd_type, | |
| &lua_apr_dbr_type, | |
| &lua_apr_dbp_type, | |
| # if APR_HAS_LDAP | |
| &lua_apr_ldap_type, | |
| # endif | |
| #if LUA_APR_HAVE_MEMCACHE | |
| &lua_apr_memcache_type, | |
| &lua_apr_memcache_server_type, | |
| #endif | |
| &lua_apr_md5_type, | |
| &lua_apr_sha1_type, | |
| &lua_apr_xml_type, | |
| NULL | |
| }; | |
| /* luaopen_apr_core() initializes the binding and library. {{{1 */ | |
| LUA_APR_EXPORT int luaopen_apr_core(lua_State *L) | |
| { | |
| apr_status_t status; | |
| /* Table of library functions. */ | |
| luaL_Reg functions[] = { | |
| /* lua_apr.c -- miscellaneous functions. */ | |
| { "platform_get", lua_apr_platform_get }, | |
| { "version_get", lua_apr_version_get }, | |
| { "os_default_encoding", lua_apr_os_default_encoding }, | |
| { "os_locale_encoding", lua_apr_os_locale_encoding }, | |
| { "type", lua_apr_type }, | |
| { "ref", lua_apr_ref }, | |
| { "deref", lua_apr_deref }, | |
| /* base64.c -- base64 encoding/decoding. */ | |
| { "base64_encode", lua_apr_base64_encode }, | |
| { "base64_decode", lua_apr_base64_decode }, | |
| /* crypt.c -- cryptographic functions. */ | |
| { "md5_init", lua_apr_md5_init }, | |
| { "md5_encode", lua_apr_md5_encode }, | |
| { "password_get", lua_apr_password_get }, | |
| { "password_validate", lua_apr_password_validate }, | |
| { "sha1_init", lua_apr_sha1_init }, | |
| /* date.c -- date parsing. */ | |
| { "date_parse_http", lua_apr_date_parse_http }, | |
| { "date_parse_rfc", lua_apr_date_parse_rfc }, | |
| /* dbd.c -- database module. */ | |
| { "dbd", lua_apr_dbd }, | |
| /* dbm.c -- dbm routines. */ | |
| { "dbm_open", lua_apr_dbm_open }, | |
| { "dbm_getnames", lua_apr_dbm_getnames }, | |
| /* env.c -- environment variable handling. */ | |
| { "env_get", lua_apr_env_get }, | |
| { "env_set", lua_apr_env_set }, | |
| { "env_delete", lua_apr_env_delete }, | |
| /* filepath.c -- filepath manipulation. */ | |
| { "filepath_root", lua_apr_filepath_root }, | |
| { "filepath_parent", lua_apr_filepath_parent }, | |
| { "filepath_name", lua_apr_filepath_name }, | |
| { "filepath_merge", lua_apr_filepath_merge }, | |
| { "filepath_list_split", lua_apr_filepath_list_split }, | |
| { "filepath_list_merge", lua_apr_filepath_list_merge }, | |
| { "filepath_get", lua_apr_filepath_get }, | |
| { "filepath_set", lua_apr_filepath_set }, | |
| /* fnmatch.c -- filename matching. */ | |
| { "fnmatch", lua_apr_fnmatch }, | |
| { "fnmatch_test", lua_apr_fnmatch_test }, | |
| /* getopt.c -- command argument parsing. */ | |
| { "getopt", lua_apr_getopt }, | |
| # if LUA_APR_HAVE_APREQ | |
| /* http.c -- HTTP request parsing. */ | |
| { "parse_headers", lua_apr_parse_headers }, | |
| { "parse_multipart", lua_apr_parse_multipart }, | |
| { "parse_cookie_header", lua_apr_parse_cookie_header }, | |
| { "parse_query_string", lua_apr_parse_query_string }, | |
| { "header_attribute", lua_apr_header_attribute }, | |
| { "uri_encode", lua_apr_uri_encode }, | |
| { "uri_decode", lua_apr_uri_decode }, | |
| # endif | |
| /* io_dir.c -- directory manipulation. */ | |
| { "temp_dir_get", lua_apr_temp_dir_get }, | |
| { "dir_make", lua_apr_dir_make }, | |
| { "dir_make_recursive", lua_apr_dir_make_recursive }, | |
| { "dir_remove", lua_apr_dir_remove }, | |
| { "dir_remove_recursive", lua_apr_dir_remove_recursive }, | |
| { "dir_open", lua_apr_dir_open }, | |
| /* io_file.c -- file i/o handling. */ | |
| # if APR_MAJOR_VERSION > 1 || (APR_MAJOR_VERSION == 1 && APR_MINOR_VERSION >= 4) | |
| { "file_link", lua_apr_file_link }, | |
| # endif | |
| { "file_copy", lua_apr_file_copy }, | |
| { "file_append", lua_apr_file_append }, | |
| { "file_rename", lua_apr_file_rename }, | |
| { "file_remove", lua_apr_file_remove }, | |
| { "file_mtime_set", lua_apr_file_mtime_set }, | |
| { "file_attrs_set", lua_apr_file_attrs_set }, | |
| { "file_perms_set", lua_apr_file_perms_set }, | |
| { "stat", lua_apr_stat }, | |
| { "file_open", lua_apr_file_open }, | |
| /* io_net.c -- network i/o handling. */ | |
| { "socket_create", lua_apr_socket_create }, | |
| { "hostname_get", lua_apr_hostname_get }, | |
| { "host_to_addr", lua_apr_host_to_addr }, | |
| { "addr_to_host", lua_apr_addr_to_host }, | |
| /* io_pipe.c -- pipe i/o handling. */ | |
| { "pipe_open_stdin", lua_apr_pipe_open_stdin }, | |
| { "pipe_open_stdout", lua_apr_pipe_open_stdout }, | |
| { "pipe_open_stderr", lua_apr_pipe_open_stderr }, | |
| { "namedpipe_create", lua_apr_namedpipe_create }, | |
| { "pipe_create", lua_apr_pipe_create }, | |
| # if APR_HAS_LDAP | |
| /* ldap.c -- LDAP connection handling. */ | |
| { "ldap", lua_apr_ldap }, | |
| { "ldap_info", lua_apr_ldap_info }, | |
| { "ldap_url_check", lua_apr_ldap_url_check }, | |
| { "ldap_url_parse", lua_apr_ldap_url_parse }, | |
| # endif | |
| /* pollset -- asynchronous network communication. */ | |
| { "pollset", lua_apr_pollset }, | |
| /* proc -- process handling. */ | |
| { "proc_create", lua_apr_proc_create }, | |
| { "proc_detach", lua_apr_proc_detach }, | |
| # if APR_HAS_FORK | |
| { "proc_fork", lua_apr_proc_fork }, | |
| # endif | |
| /* shm.c -- shared memory. */ | |
| { "shm_create", lua_apr_shm_create }, | |
| { "shm_attach", lua_apr_shm_attach }, | |
| { "shm_remove", lua_apr_shm_remove }, | |
| /* signal.c -- signal handling. */ | |
| { "signal", lua_apr_signal }, | |
| { "signal_raise", lua_apr_signal_raise }, | |
| { "signal_block", lua_apr_signal_block }, | |
| { "signal_unblock", lua_apr_signal_unblock }, | |
| { "signal_names", lua_apr_signal_names }, | |
| /* str.c -- string handling. */ | |
| { "strnatcmp", lua_apr_strnatcmp }, | |
| { "strnatcasecmp", lua_apr_strnatcasecmp }, | |
| { "strfsize", lua_apr_strfsize }, | |
| { "tokenize_to_argv", lua_apr_tokenize_to_argv }, | |
| # if APR_HAS_THREADS | |
| /* thread.c -- multi threading. */ | |
| { "thread", lua_apr_thread }, | |
| { "thread_yield", lua_apr_thread_yield }, | |
| /* thread_queue.c -- thread queues. */ | |
| { "thread_queue", lua_apr_thread_queue }, | |
| # endif | |
| /* time.c -- time management */ | |
| { "sleep", lua_apr_sleep }, | |
| { "time_now", lua_apr_time_now }, | |
| { "time_explode", lua_apr_time_explode }, | |
| { "time_implode", lua_apr_time_implode }, | |
| { "time_format", lua_apr_time_format }, | |
| /* uri.c -- URI parsing/unparsing. */ | |
| { "uri_parse", lua_apr_uri_parse }, | |
| { "uri_unparse", lua_apr_uri_unparse }, | |
| { "uri_port_of_scheme", lua_apr_uri_port_of_scheme }, | |
| /* user.c -- user/group identification. */ | |
| { "user_get", lua_apr_user_get }, | |
| { "user_homepath_get", lua_apr_user_homepath_get }, | |
| /* uuid.c -- UUID generation. */ | |
| { "uuid_get", lua_apr_uuid_get }, | |
| { "uuid_format", lua_apr_uuid_format }, | |
| { "uuid_parse", lua_apr_uuid_parse }, | |
| /* xlate.c -- character encoding translation. */ | |
| { "xlate", lua_apr_xlate }, | |
| /* xml.c -- XML parsing. */ | |
| { "xml", lua_apr_xml }, | |
| # if LUA_APR_HAVE_MEMCACHE | |
| /* memcache.c -- memcached client. */ | |
| { "memcache", lua_apr_memcache }, | |
| # endif | |
| { NULL, NULL } | |
| }; | |
| /* Initialize the library (only once per process). */ | |
| if (!apr_was_initialized) { | |
| if ((status = apr_initialize()) != APR_SUCCESS) | |
| raise_error_status(L, status); | |
| if (atexit(apr_terminate) != 0) | |
| raise_error_message(L, "Lua/APR: Failed to register apr_terminate()"); | |
| apr_was_initialized = 1; | |
| } | |
| /* Create the `scratch' memory pool for global APR functions (as opposed to | |
| * object methods) and install a __gc metamethod to detect when the Lua state | |
| * is exited. */ | |
| to_pool(L); | |
| /* Create the table of global functions. */ | |
| lua_createtable(L, 0, count(functions)); | |
| luaL_register(L, NULL, functions); | |
| /* Let callers of process:user_set() know whether it requires a password. */ | |
| lua_pushboolean(L, APR_PROCATTR_USER_SET_REQUIRES_PASSWORD); | |
| lua_setfield(L, -2, "user_set_requires_password"); | |
| /* Let callers of apr.socket_create() know whether it supports IPv6. */ | |
| lua_pushboolean(L, APR_HAVE_IPV6); | |
| lua_setfield(L, -2, "socket_supports_ipv6"); | |
| return 1; | |
| } | |
| /* apr.platform_get() -> name {{{1 | |
| * | |
| * Get the name of the platform for which the Lua/APR binding was compiled. | |
| * Returns one of the following strings: | |
| * | |
| * - `'UNIX'` | |
| * - `'WIN32'` | |
| * - `'NETWARE'` | |
| * - `'OS2'` | |
| * | |
| * Please note that the labels returned by `apr.platform_get()` don't imply | |
| * that these platforms are fully supported; the author of the Lua/APR binding | |
| * doesn't have NETWARE and OS2 environments available for testing. | |
| */ | |
| int lua_apr_platform_get(lua_State *L) | |
| { | |
| # if defined(WIN32) | |
| lua_pushstring(L, "WIN32"); | |
| # elif defined(NETWARE) | |
| lua_pushstring(L, "NETWARE"); | |
| # elif defined(OS2) | |
| lua_pushstring(L, "OS2"); | |
| # else | |
| lua_pushstring(L, "UNIX"); | |
| # endif | |
| return 1; | |
| } | |
| /* apr.version_get() -> versions_table {{{1 | |
| * | |
| * Get the versions of the libraries used by the Lua/APR binding. | |
| * Returns a table with one or more of the following fields: | |
| * | |
| * - **apr**: The version of the Apache Portable Runtime library. This field | |
| * is always available. | |
| * | |
| * - **aprutil**: The version of the APR utility library. This field is only | |
| * available when Lua/APR is compiled against APR and APR-util 1.x because | |
| * in version 2.x the utility library has been absorbed back into the APR | |
| * library; there is no longer a distinction between the APR core and APR | |
| * utility libraries. | |
| * | |
| * - **apreq**: The version of the HTTP request parsing library. This field is | |
| * only available when the libapreq2 library is installed. | |
| * | |
| * Each field is a string containing three numbers separated by dots. These | |
| * numbers have the following meaning: | |
| * | |
| * 1. Major [API] [api] changes that can cause compatibility problems between | |
| * the Lua/APR binding and APR library | |
| * | |
| * 2. Minor API changes that shouldn't impact existing functionality in the | |
| * Lua/APR binding | |
| * | |
| * 3. Used exclusively for bug fixes | |
| * | |
| * This function can be useful when you want to know whether a certain bug fix | |
| * has been applied to APR and/or APR-util or if you want to report a bug in | |
| * APR, APR-util or the Lua/APR binding. | |
| * | |
| * If you're looking for the version of the Lua/APR binding you can use the | |
| * `apr._VERSION` string, but note that Lua/APR currently does not adhere to | |
| * the above versioning rules. | |
| * | |
| * [api]: http://en.wikipedia.org/wiki/Application_programming_interface | |
| */ | |
| int lua_apr_version_get(lua_State *L) | |
| { | |
| lua_newtable(L); | |
| lua_pushstring(L, apr_version_string()); | |
| lua_setfield(L, -2, "apr"); | |
| # if APR_MAJOR_VERSION < 2 | |
| lua_pushstring(L, apu_version_string()); | |
| lua_setfield(L, -2, "aprutil"); | |
| # endif | |
| # if LUA_APR_HAVE_APREQ | |
| lua_pushstring(L, apreq_version_string()); | |
| lua_setfield(L, -2, "apreq"); | |
| # endif | |
| return 1; | |
| } | |
| /* apr.os_default_encoding() -> name {{{1 | |
| * | |
| * Get the name of the system default character set as a string. | |
| */ | |
| int lua_apr_os_default_encoding(lua_State *L) | |
| { | |
| lua_pushstring(L, apr_os_default_encoding(to_pool(L))); | |
| return 1; | |
| } | |
| /* apr.os_locale_encoding() -> name {{{1 | |
| * | |
| * Get the name of the current locale character set as a string. If the current | |
| * locale's data cannot be retrieved on this system, the name of the system | |
| * default character set is returned instead. | |
| */ | |
| int lua_apr_os_locale_encoding(lua_State *L) | |
| { | |
| lua_pushstring(L, apr_os_locale_encoding(to_pool(L))); | |
| return 1; | |
| } | |
| /* apr.type(object) -> name {{{1 | |
| * | |
| * Return the type of a userdata object created by the Lua/APR binding. If | |
| * @object is of a known type one of the following strings will be returned, | |
| * otherwise nothing is returned: | |
| * | |
| * - `'file'` | |
| * - `'directory'` | |
| * - `'socket'` | |
| * - `'thread'` | |
| * - `'process'` | |
| * - `'dbm'` | |
| * - `'database driver'` | |
| * - `'prepared statement'` | |
| * - `'result set'` | |
| * - `'memcache client'` | |
| * - `'memcache server'` | |
| * - `'md5 context'` | |
| * - `'sha1 context'` | |
| * - `'xml parser'` | |
| */ | |
| int lua_apr_type(lua_State *L) | |
| { | |
| int i; | |
| lua_settop(L, 1); | |
| luaL_checktype(L, 1, LUA_TUSERDATA); | |
| lua_getmetatable(L, 1); | |
| for (i = 0; lua_apr_types[i] != NULL; i++) { | |
| if (object_has_type(L, 1, lua_apr_types[i], 0)) { | |
| lua_pushstring(L, lua_apr_types[i]->friendlyname); | |
| return 1; | |
| } | |
| } | |
| return 0; | |
| } | |
| /* status_to_message() converts APR status codes to error messages. {{{1 */ | |
| int status_to_message(lua_State *L, apr_status_t status) | |
| { | |
| int length; | |
| char message[LUA_APR_MSGSIZE]; | |
| apr_strerror(status, message, count(message)); | |
| length = strlen(message); | |
| while (length > 0 && isspace(message[length - 1])) | |
| length--; | |
| lua_pushlstring(L, message, length); | |
| return 1; | |
| } | |
| /* push_status() returns true for APR_SUCCESS or the result of status_to_message(). {{{1 */ | |
| int push_status(lua_State *L, apr_status_t status) | |
| { | |
| if (status == APR_SUCCESS) { | |
| lua_pushboolean(L, 1); | |
| return 1; | |
| } else { | |
| return push_error_status(L, status); | |
| } | |
| } | |
| /* push_error_status() converts APR status codes to (nil, message, code). {{{1 */ | |
| int push_error_status(lua_State *L, apr_status_t status) | |
| { | |
| lua_pushnil(L); | |
| status_to_message(L, status); | |
| status_to_name(L, status); | |
| return 3; | |
| } | |
| /* vim: set ts=2 sw=2 et tw=79 fen fdm=marker : */ |