static int ngx_http_lua_parse_args(ngx_http_request_t *r, lua_State *L, u_char *buf, u_char *last) { u_char *p, *q; u_char *src, *dst; unsigned parsing_value; size_t len; p = buf; parsing_value = 0; q = p; while (p != last) { if (*p == '=' && ! parsing_value) { /* key data is between p and q */ src = q; dst = q; ngx_http_lua_unescape_uri(&dst, &src, p - q, NGX_UNESCAPE_URI_COMPONENT); dd("pushing key %.*s", (int) (dst - q), q); /* push the key */ lua_pushlstring(L, (char *) q, dst - q); /* skip the current '=' char */ p++; q = p; parsing_value = 1; } else if (*p == '&') { /* reached the end of a key or a value, just save it */ src = q; dst = q; ngx_http_lua_unescape_uri(&dst, &src, p - q, NGX_UNESCAPE_URI_COMPONENT); dd("pushing key or value %.*s", (int) (dst - q), q); /* push the value or key */ lua_pushlstring(L, (char *) q, dst - q); /* skip the current '&' char */ p++; q = p; if (parsing_value) { /* end of the current pair's value */ parsing_value = 0; } else { /* the current parsing pair takes no value, * just push the value "true" */ dd("pushing boolean true"); lua_pushboolean(L, 1); } (void) lua_tolstring(L, -2, &len); if (len == 0) { /* ignore empty string key pairs */ dd("popping key and value..."); lua_pop(L, 2); } else { dd("setting table..."); ngx_http_lua_set_multi_value_table(L, 1); } } else { p++; } } if (p != q || parsing_value) { src = q; dst = q; ngx_http_lua_unescape_uri(&dst, &src, p - q, NGX_UNESCAPE_URI_COMPONENT); dd("pushing key or value %.*s", (int) (dst - q), q); lua_pushlstring(L, (char *) q, dst - q); if (! parsing_value) { dd("pushing boolean true..."); lua_pushboolean(L, 1); } (void) lua_tolstring(L, -2, &len); if (len == 0) { /* ignore empty string key pairs */ dd("popping key and value..."); lua_pop(L, 2); } else { dd("setting table..."); ngx_http_lua_set_multi_value_table(L, 1); } } dd("gettop: %d", lua_gettop(L)); dd("type: %s", lua_typename(L, lua_type(L, 1))); if (lua_gettop(L) != 1) { return luaL_error(L, "internal error: stack in bad state"); } return 1; }
static int ngx_http_lua_ngx_req_raw_header(lua_State *L) { int n, line_break_len; u_char *data, *p, *last, *pos; unsigned no_req_line = 0, found; size_t size; ngx_buf_t *b, *first = NULL; ngx_int_t i, j; ngx_connection_t *c; ngx_http_request_t *r, *mr; ngx_http_connection_t *hc; n = lua_gettop(L); if (n > 0) { no_req_line = lua_toboolean(L, 1); } dd("no req line: %d", (int) no_req_line); r = ngx_http_lua_get_req(L); if (r == NULL) { return luaL_error(L, "no request object found"); } ngx_http_lua_check_fake_request(L, r); mr = r->main; hc = mr->http_connection; c = mr->connection; #if 1 dd("hc->nbusy: %d", (int) hc->nbusy); if (hc->nbusy) { dd("hc->busy: %p %p %p %p", hc->busy[0]->start, hc->busy[0]->pos, hc->busy[0]->last, hc->busy[0]->end); } dd("request line: %p %p", mr->request_line.data, mr->request_line.data + mr->request_line.len); dd("header in: %p %p %p %p", mr->header_in->start, mr->header_in->pos, mr->header_in->last, mr->header_in->end); dd("c->buffer: %p %p %p %p", c->buffer->start, c->buffer->pos, c->buffer->last, c->buffer->end); #endif size = 0; b = c->buffer; if (mr->request_line.data[mr->request_line.len] == CR) { line_break_len = 2; } else { line_break_len = 1; } if (mr->request_line.data >= b->start && mr->request_line.data + mr->request_line.len + line_break_len <= b->pos) { first = b; size += b->pos - mr->request_line.data; } dd("size: %d", (int) size); if (hc->nbusy) { b = NULL; for (i = 0; i < hc->nbusy; i++) { b = hc->busy[i]; dd("busy buf: %d: [%.*s]", (int) i, (int) (b->pos - b->start), b->start); if (first == NULL) { if (mr->request_line.data >= b->pos || mr->request_line.data + mr->request_line.len + line_break_len <= b->start) { continue; } dd("found first at %d", (int) i); first = b; } dd("adding size %d", (int) (b->pos - b->start)); size += b->pos - b->start; } } size++; /* plus the null terminator, as required by the later ngx_strstr() call */ dd("header size: %d", (int) size); data = lua_newuserdata(L, size); last = data; b = c->buffer; found = 0; if (first == b) { found = 1; pos = b->pos; if (no_req_line) { last = ngx_copy(data, mr->request_line.data + mr->request_line.len + line_break_len, pos - mr->request_line.data - mr->request_line.len - line_break_len); } else { last = ngx_copy(data, mr->request_line.data, pos - mr->request_line.data); } if (b != mr->header_in) { /* skip truncated header entries (if any) */ while (last > data && last[-1] != LF) { last--; } } i = 0; for (p = data; p != last; p++) { if (*p == '\0') { i++; if (p + 1 != last && *(p + 1) == LF) { *p = CR; } else if (i % 2 == 1) { *p = ':'; } else { *p = LF; } } } } if (hc->nbusy) { for (i = 0; i < hc->nbusy; i++) { b = hc->busy[i]; if (!found) { if (b != first) { continue; } dd("found first"); found = 1; } p = last; pos = b->pos; if (b == first) { dd("request line: %.*s", (int) mr->request_line.len, mr->request_line.data); if (no_req_line) { last = ngx_copy(last, mr->request_line.data + mr->request_line.len + line_break_len, pos - mr->request_line.data - mr->request_line.len - line_break_len); } else { last = ngx_copy(last, mr->request_line.data, pos - mr->request_line.data); } } else { last = ngx_copy(last, b->start, pos - b->start); } #if 1 /* skip truncated header entries (if any) */ while (last > p && last[-1] != LF) { last--; } #endif j = 0; for (; p != last; p++) { if (*p == '\0') { j++; if (p + 1 == last) { /* XXX this should not happen */ dd("found string end!!"); } else if (*(p + 1) == LF) { *p = CR; } else if (j % 2 == 1) { *p = ':'; } else { *p = LF; } } } if (b == mr->header_in) { break; } } } *last++ = '\0'; if (last - data > (ssize_t) size) { return luaL_error(L, "buffer error: %d", (int) (last - data - size)); } /* strip the leading part (if any) of the request body in our header. * the first part of the request body could slip in because nginx core's * ngx_http_request_body_length_filter and etc can move r->header_in->pos * in case that some of the body data has been preread into r->header_in. */ if ((p = (u_char *) ngx_strstr(data, CRLF CRLF)) != NULL) { last = p + sizeof(CRLF CRLF) - 1; } else if ((p = (u_char *) ngx_strstr(data, CRLF "\n")) != NULL) { last = p + sizeof(CRLF "\n") - 1; } else if ((p = (u_char *) ngx_strstr(data, "\n" CRLF)) != NULL) { last = p + sizeof("\n" CRLF) - 1; } else { for (p = last - 1; p - data >= 2; p--) { if (p[0] == LF && p[-1] == CR) { p[-1] = LF; last = p + 1; break; } if (p[0] == LF && p[-1] == LF) { last = p + 1; break; } } } lua_pushlstring(L, (char *) data, last - data); return 1; }
void LuaStack::pushString(const char* stringValue, int length) { lua_pushlstring(_state, stringValue, length); }
static int lua_request_attr_read_http_method(liRequest *req, lua_State *L) { lua_pushlstring(L, req->http_method_str->str, req->http_method_str->len); return 1; }
static int ngx_http_lua_ngx_req_get_headers(lua_State *L) { ngx_list_part_t *part; ngx_table_elt_t *header; ngx_http_request_t *r; ngx_uint_t i; int n; int max; int raw = 0; int count = 0; n = lua_gettop(L); if (n >= 1) { if (lua_isnil(L, 1)) { max = NGX_HTTP_LUA_MAX_HEADERS; } else { max = luaL_checkinteger(L, 1); } if (n >= 2) { raw = lua_toboolean(L, 2); } } else { max = NGX_HTTP_LUA_MAX_HEADERS; } r = ngx_http_lua_get_req(L); if (r == NULL) { return luaL_error(L, "no request object found"); } ngx_http_lua_check_fake_request(L, r); part = &r->headers_in.headers.part; count = part->nelts; while (part->next) { part = part->next; count += part->nelts; } if (max > 0 && count > max) { count = max; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua exceeding request header limit %d", max); } lua_createtable(L, 0, count); if (!raw) { lua_pushlightuserdata(L, &ngx_http_lua_headers_metatable_key); lua_rawget(L, LUA_REGISTRYINDEX); lua_setmetatable(L, -2); } part = &r->headers_in.headers.part; header = part->elts; for (i = 0; /* void */; i++) { dd("stack top: %d", lua_gettop(L)); if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; header = part->elts; i = 0; } if (raw) { lua_pushlstring(L, (char *) header[i].key.data, header[i].key.len); } else { lua_pushlstring(L, (char *) header[i].lowcase_key, header[i].key.len); } /* stack: table key */ lua_pushlstring(L, (char *) header[i].value.data, header[i].value.len); /* stack: table key value */ ngx_http_lua_set_multi_value_table(L, -3); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua request header: \"%V: %V\"", &header[i].key, &header[i].value); if (--count == 0) { return 1; } } return 1; }
static gint lua_util_tokenize_text (lua_State *L) { const gchar *in = NULL; gsize len, pos, ex_len, i; GList *exceptions = NULL, *cur; struct rspamd_lua_text *t; struct process_exception *ex; GArray *res; rspamd_fstring_t *w; gboolean compat = FALSE; if (lua_type (L, 1) == LUA_TSTRING) { in = luaL_checklstring (L, 1, &len); } else if (lua_type (L, 1) == LUA_TTABLE) { t = lua_check_text (L, 1); if (t) { in = t->start; len = t->len; } } if (in == NULL) { lua_pushnil (L); return 1; } if (lua_gettop (L) > 1 && lua_type (L, 2) == LUA_TTABLE) { lua_pushvalue (L, 2); lua_pushnil (L); while (lua_next (L, -2) != 0) { if (lua_type (L, -1) == LUA_TTABLE) { lua_rawgeti (L, -1, 1); pos = luaL_checknumber (L, -1); lua_pop (L, 1); lua_rawgeti (L, -1, 2); ex_len = luaL_checknumber (L, -1); lua_pop (L, 1); if (ex_len > 0) { ex = g_slice_alloc (sizeof (*ex)); ex->pos = pos; ex->len = ex_len; exceptions = g_list_prepend (exceptions, ex); } } lua_pop (L, 1); } lua_pop (L, 1); } if (lua_gettop (L) > 2 && lua_type (L, 3) == LUA_TBOOLEAN) { compat = lua_toboolean (L, 3); } if (exceptions) { exceptions = g_list_reverse (exceptions); } res = rspamd_tokenize_text ((gchar *)in, len, TRUE, 0, exceptions, compat); if (res == NULL) { lua_pushnil (L); } else { lua_newtable (L); for (i = 0; i < res->len; i ++) { w = &g_array_index (res, rspamd_fstring_t, i); lua_pushlstring (L, w->begin, w->len); lua_rawseti (L, -2, i + 1); } } cur = exceptions; while (cur) { ex = cur->data; g_slice_free1 (sizeof (*ex), ex); cur = g_list_next (cur); } g_list_free (exceptions); return 1; }
LUA_API void luanet_pushlstring (lua_State *L, const char *s, size_t len) { lua_pushlstring (L, s, len); }
static int ngx_http_lua_ngx_req_get_body_data(lua_State *L) { ngx_http_request_t *r; int n; size_t len; ngx_chain_t *cl; u_char *p; u_char *buf; n = lua_gettop(L); if (n != 0) { return luaL_error(L, "expecting 0 arguments but seen %d", n); } r = ngx_http_lua_get_req(L); if (r == NULL) { return luaL_error(L, "request object not found"); } ngx_http_lua_check_fake_request(L, r); if (r->request_body == NULL || r->request_body->temp_file || r->request_body->bufs == NULL) { lua_pushnil(L); return 1; } cl = r->request_body->bufs; if (cl->next == NULL) { len = cl->buf->last - cl->buf->pos; if (len == 0) { lua_pushnil(L); return 1; } lua_pushlstring(L, (char *) cl->buf->pos, len); return 1; } /* found multi-buffer body */ len = 0; for (; cl; cl = cl->next) { dd("body chunk len: %d", (int) ngx_buf_size(cl->buf)); len += cl->buf->last - cl->buf->pos; } if (len == 0) { lua_pushnil(L); return 1; } buf = (u_char *) lua_newuserdata(L, len); p = buf; for (cl = r->request_body->bufs; cl; cl = cl->next) { p = ngx_copy(p, cl->buf->pos, cl->buf->last - cl->buf->pos); } lua_pushlstring(L, (char *) buf, len); return 1; }
int process(lua_State *L, const char *name, const char* filter_name, int list_only) { struct archive *a = archive_read_new(); archive_read_support_filter_all(a); archive_read_support_format_all(a); if ( (archive_read_open_filename(a, name, 10240)) ) { lua_pushnil(L); lua_pushfstring(L, "Error: can't read archive %s: %s\n", name, archive_error_string(a)); return 2; } lua_newtable(L); int top = lua_gettop(L); struct archive_entry *entry; int r; int total = 0; for (;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) { lua_pushnil(L); lua_pushfstring(L, "%s\n", archive_error_string(a)); aclose(a); return 2; } if (r < ARCHIVE_WARN) { lua_pushnil(L); lua_pushfstring(L, "%s\n", "Warning from archive"); aclose(a); return 2; } // skip dirs if (!S_ISREG(archive_entry_mode(entry))) continue; const char *name = archive_entry_pathname(entry); if(list_only) { lua_pushstring(L, name); lua_rawseti(L, top, ++total); archive_read_data_skip(a); // automatically called anyway continue; } if ( filter_name && ! ( strlen(filter_name)==strlen(name) && strncmp(filter_name, name, strlen(name))==0 ) ) { archive_read_data_skip(a); // automatically called anyway continue; } size_t entry_size = archive_entry_size(entry); if (entry_size > 0) { char buff[entry_size]; ssize_t size = archive_read_data(a, buff, entry_size); if(size <= 0) { //TODO: send a warning or a black image //lua_pushfstring(L, "Corrupted data: %s\n", name); //lua_error(L); } lua_pushlstring(L, buff, entry_size); if(filter_name) lua_rawseti(L, top, 1); else lua_setfield(L, top, name); } if(filter_name)break; } aclose(a); return 1; }
static int ts_lua_transform_handler(TSCont contp, ts_lua_transform_ctx *transform_ctx) { TSVConn output_conn; TSVIO input_vio; TSIOBufferReader input_reader; TSIOBufferBlock blk; int64_t towrite, blk_len, upstream_done, avail, left; const char *start; const char *res; size_t res_len; int ret, eos; lua_State *L; L = transform_ctx->hctx->lua; output_conn = TSTransformOutputVConnGet(contp); input_vio = TSVConnWriteVIOGet(contp); input_reader = TSVIOReaderGet(input_vio); if (!transform_ctx->output_buffer) { transform_ctx->output_buffer = TSIOBufferCreate(); transform_ctx->output_reader = TSIOBufferReaderAlloc(transform_ctx->output_buffer); transform_ctx->output_vio = TSVConnWrite(output_conn, contp, transform_ctx->output_reader, INT64_MAX); } if (!TSVIOBufferGet(input_vio)) { TSVIONBytesSet(transform_ctx->output_vio, transform_ctx->total); TSVIOReenable(transform_ctx->output_vio); return 1; } if (transform_ctx->eos) { return 1; } left = towrite = TSVIONTodoGet(input_vio); upstream_done = TSVIONDoneGet(input_vio); avail = TSIOBufferReaderAvail(input_reader); eos = 0; if (left <= avail) eos = 1; if (towrite > avail) towrite = avail; blk = TSIOBufferReaderStart(input_reader); do { start = TSIOBufferBlockReadStart(blk, input_reader, &blk_len); lua_pushlightuserdata(L, transform_ctx); lua_rawget(L, LUA_GLOBALSINDEX); /* push function */ if (towrite > blk_len) { lua_pushlstring(L, start, (size_t)blk_len); towrite -= blk_len; } else { lua_pushlstring(L, start, (size_t)towrite); towrite = 0; } if (!towrite && eos) { lua_pushinteger(L, 1); /* second param, not finish */ } else { lua_pushinteger(L, 0); /* second param, not finish */ } if (lua_pcall(L, 2, 2, 0)) { fprintf(stderr, "lua_pcall failed: %s\n", lua_tostring(L, -1)); } ret = lua_tointeger(L, -1); /* 0 is not finished, 1 is finished */ res = lua_tolstring(L, -2, &res_len); if (res && res_len) { TSIOBufferWrite(transform_ctx->output_buffer, res, res_len); transform_ctx->total += res_len; } lua_pop(L, 2); if (ret || eos) { // EOS eos = 1; break; } blk = TSIOBufferBlockNext(blk); } while (blk && towrite > 0); TSIOBufferReaderConsume(input_reader, avail); TSVIONDoneSet(input_vio, upstream_done + avail); if (eos) { transform_ctx->eos = 1; TSVIONBytesSet(transform_ctx->output_vio, transform_ctx->total); TSVIOReenable(transform_ctx->output_vio); TSContCall(TSVIOContGet(input_vio), TS_EVENT_VCONN_WRITE_COMPLETE, input_vio); } else { TSVIOReenable(transform_ctx->output_vio); TSContCall(TSVIOContGet(input_vio), TS_EVENT_VCONN_WRITE_READY, input_vio); } return 1; }
LUALIB_API void luaL_pushresult (luaL_Buffer *B) { lua_State *L = B->L; lua_pushlstring(L, B->b, B->n); if (buffonstack(B)) lua_remove(L, -2); /* remove old buffer */ }
int heka_read_message(lua_State *lua, lsb_heka_message *m) { int n = lua_gettop(lua); if (n < 1 || n > 3) { return luaL_error(lua, "read_message() incorrect number of arguments"); } size_t field_len; const char *field = luaL_checklstring(lua, 1, &field_len); int fi = (int)luaL_optinteger(lua, 2, 0); luaL_argcheck(lua, fi >= 0, 2, "field index must be >= 0"); int ai = (int)luaL_optinteger(lua, 3, 0); luaL_argcheck(lua, ai >= 0, 3, "array index must be >= 0"); if (strcmp(field, LSB_UUID) == 0) { if (m->uuid.s) { lua_pushlstring(lua, m->uuid.s, m->uuid.len); } else { lua_pushnil(lua); } } else if (strcmp(field, LSB_TIMESTAMP) == 0) { lua_pushnumber(lua, (lua_Number)m->timestamp); } else if (strcmp(field, LSB_TYPE) == 0) { if (m->type.s) { lua_pushlstring(lua, m->type.s, m->type.len); } else { lua_pushnil(lua); } } else if (strcmp(field, LSB_LOGGER) == 0) { if (m->logger.s) { lua_pushlstring(lua, m->logger.s, m->logger.len); } else { lua_pushnil(lua); } } else if (strcmp(field, LSB_SEVERITY) == 0) { lua_pushinteger(lua, m->severity); } else if (strcmp(field, LSB_PAYLOAD) == 0) { if (m->payload.s) { lua_pushlstring(lua, m->payload.s, m->payload.len); } else { lua_pushnil(lua); } } else if (strcmp(field, LSB_ENV_VERSION) == 0) { if (m->env_version.s) { lua_pushlstring(lua, m->env_version.s, m->env_version.len); } else { lua_pushnil(lua); } } else if (strcmp(field, LSB_PID) == 0) { lua_pushinteger(lua, m->pid); } else if (strcmp(field, LSB_HOSTNAME) == 0) { if (m->hostname.s) { lua_pushlstring(lua, m->hostname.s, m->hostname.len); } else { lua_pushnil(lua); } } else if (strcmp(field, "raw") == 0) { lua_pushlstring(lua, m->raw.s, m->raw.len); } else if (strcmp(field, "framed") == 0) { { char header[14] = "\x1e\x00\x08"; // up to 10 varint bytes and a \x1f int hlen = lsb_pb_output_varint(header + 3, m->raw.len) + 1; header[1] = (char)hlen; header[hlen + 2] = '\x1f'; luaL_Buffer b; luaL_buffinit(lua, &b); luaL_addlstring(&b, header, hlen + 3); luaL_addlstring(&b, m->raw.s, m->raw.len); luaL_pushresult(&b); } } else if (strcmp(field, "size") == 0) { lua_pushnumber(lua, (lua_Number)m->raw.len); } else { if (field_len >= 8 && memcmp(field, LSB_FIELDS "[", 7) == 0 && field[field_len - 1] == ']') { lsb_read_value v; lsb_const_string f = { .s = field + 7, .len = field_len - 8 }; lsb_read_heka_field(m, &f, fi, ai, &v); switch (v.type) { case LSB_READ_STRING: lua_pushlstring(lua, v.u.s.s, v.u.s.len); break; case LSB_READ_NUMERIC: lua_pushnumber(lua, v.u.d); break; case LSB_READ_BOOL: lua_pushboolean(lua, v.u.d ? 1 : 0); break; default: lua_pushnil(lua); break; } } else { lua_pushnil(lua); } }
/** Initialize the Lua VM * \param xdg An xdg handle to use to get XDG basedir. */ void luaA_init(xdgHandle* xdg) { lua_State *L; static const struct luaL_Reg awesome_lib[] = { { "quit", luaA_quit }, { "exec", luaA_exec }, { "spawn", luaA_spawn }, { "restart", luaA_restart }, { "connect_signal", luaA_awesome_connect_signal }, { "disconnect_signal", luaA_awesome_disconnect_signal }, { "emit_signal", luaA_awesome_emit_signal }, { "systray", luaA_systray }, { "load_image", luaA_load_image }, { "set_preferred_icon_size", luaA_set_preferred_icon_size }, { "register_xproperty", luaA_register_xproperty }, { "set_xproperty", luaA_set_xproperty }, { "get_xproperty", luaA_get_xproperty }, { "__index", luaA_awesome_index }, { "__newindex", luaA_default_newindex }, { "xkb_set_layout_group", luaA_xkb_set_layout_group}, { "xkb_get_layout_group", luaA_xkb_get_layout_group}, { "xkb_get_group_names", luaA_xkb_get_group_names}, { "xrdb_get_value", luaA_xrdb_get_value}, { NULL, NULL } }; L = globalconf.L.real_L_dont_use_directly = luaL_newstate(); /* Set panic function */ lua_atpanic(L, luaA_panic); /* Set error handling function */ lualib_dofunction_on_error = luaA_dofunction_on_error; luaL_openlibs(L); luaA_fixups(L); luaA_object_setup(L); /* Export awesome lib */ luaA_openlib(L, "awesome", awesome_lib, awesome_lib); /* Export root lib */ luaA_registerlib(L, "root", awesome_root_lib); lua_pop(L, 1); /* luaA_registerlib() leaves the table on stack */ #ifdef WITH_DBUS /* Export D-Bus lib */ luaA_registerlib(L, "dbus", awesome_dbus_lib); lua_pop(L, 1); /* luaA_registerlib() leaves the table on stack */ #endif /* Export keygrabber lib */ luaA_registerlib(L, "keygrabber", awesome_keygrabber_lib); lua_pop(L, 1); /* luaA_registerlib() leaves the table on stack */ /* Export mousegrabber lib */ luaA_registerlib(L, "mousegrabber", awesome_mousegrabber_lib); lua_pop(L, 1); /* luaA_registerlib() leaves the table on stack */ /* Export mouse */ luaA_openlib(L, "mouse", awesome_mouse_methods, awesome_mouse_meta); /* Export screen */ screen_class_setup(L); /* Export button */ button_class_setup(L); /* Export tag */ tag_class_setup(L); /* Export window */ window_class_setup(L); /* Export drawable */ drawable_class_setup(L); /* Export drawin */ drawin_class_setup(L); /* Export client */ client_class_setup(L); /* Export keys */ key_class_setup(L); /* add Lua search paths */ lua_getglobal(L, "package"); if (LUA_TTABLE != lua_type(L, 1)) { warn("package is not a table"); return; } lua_getfield(L, 1, "path"); if (LUA_TSTRING != lua_type(L, 2)) { warn("package.path is not a string"); lua_pop(L, 1); return; } /* add XDG_CONFIG_DIR as include path */ const char * const *xdgconfigdirs = xdgSearchableConfigDirectories(xdg); for(; *xdgconfigdirs; xdgconfigdirs++) { size_t len = a_strlen(*xdgconfigdirs); lua_pushliteral(L, ";"); lua_pushlstring(L, *xdgconfigdirs, len); lua_pushliteral(L, "/awesome/?.lua"); lua_concat(L, 3); lua_pushliteral(L, ";"); lua_pushlstring(L, *xdgconfigdirs, len); lua_pushliteral(L, "/awesome/?/init.lua"); lua_concat(L, 3); lua_concat(L, 3); /* concatenate with package.path */ } /* add Lua lib path (/usr/share/awesome/lib by default) */ lua_pushliteral(L, ";" AWESOME_LUA_LIB_PATH "/?.lua"); lua_pushliteral(L, ";" AWESOME_LUA_LIB_PATH "/?/init.lua"); lua_concat(L, 3); /* concatenate with package.path */ lua_setfield(L, 1, "path"); /* package.path = "concatenated string" */ lua_getfield(L, 1, "loaded"); lua_pop(L, 2); /* pop "package" and "package.loaded" */ /** A call into the lua code aborted with an error * @signal debug::error */ signal_add(&global_signals, "debug::error"); /** A deprecated lua function was called * @signal debug::deprecation */ signal_add(&global_signals, "debug::deprecation"); /** An invalid key was read from an object (e.g. c.foo) * @signal debug::index::miss */ signal_add(&global_signals, "debug::index::miss"); /** An invalid key was written to an object (e.g. c.foo = "bar") * @signal debug::newindex::miss */ signal_add(&global_signals, "debug::newindex::miss"); /** * @signal systray::update */ signal_add(&global_signals, "systray::update"); /** * @signal wallpaper_changed */ signal_add(&global_signals, "wallpaper_changed"); /** * @signal xkb::map_changed */ signal_add(&global_signals, "xkb::map_changed"); /** * @signal xkb::group_changed */ signal_add(&global_signals, "xkb::group_changed"); /** * @signal refresh */ signal_add(&global_signals, "refresh"); /** * @signal startup */ signal_add(&global_signals, "startup"); /** * @signal exit */ signal_add(&global_signals, "exit"); /** * @signal screen::change */ signal_add(&global_signals, "screen::change"); }
static void ngx_http_lua_socket_resolve_handler(ngx_resolver_ctx_t *ctx) { ngx_http_request_t *r; ngx_http_upstream_resolved_t *ur; ngx_http_lua_ctx_t *lctx; lua_State *L; ngx_http_lua_socket_udp_upstream_t *u; u_char *p; size_t len; struct sockaddr_in *sin; ngx_uint_t i; unsigned waiting; u = ctx->data; r = u->request; ur = u->resolved; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket resolve handler"); lctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); L = lctx->cc; dd("setting socket_ready to 1"); waiting = u->waiting; if (ctx->state) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket resolver error: %s (waiting: %d)", ngx_resolver_strerror(ctx->state), (int) u->waiting); lua_pushnil(L); lua_pushlstring(L, (char *) ctx->name.data, ctx->name.len); lua_pushfstring(L, " could not be resolved (%d: %s)", (int) ctx->state, ngx_resolver_strerror(ctx->state)); lua_concat(L, 2); u->prepare_retvals = ngx_http_lua_socket_error_retval_handler; ngx_http_lua_socket_udp_handle_error(r, u, NGX_HTTP_LUA_SOCKET_FT_RESOLVER); return; } ur->naddrs = ctx->naddrs; ur->addrs = ctx->addrs; #if (NGX_DEBUG) { in_addr_t addr; ngx_uint_t i; for (i = 0; i < ctx->naddrs; i++) { dd("addr i: %d %p", (int) i, &ctx->addrs[i]); addr = ntohl(ctx->addrs[i]); ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "name was resolved to %ud.%ud.%ud.%ud", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff); } } #endif if (ur->naddrs == 0) { u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; lua_pushnil(L); lua_pushliteral(L, "name cannot be resolved to a address"); return; } if (ur->naddrs == 1) { i = 0; } else { i = ngx_random() % ur->naddrs; } dd("selected addr index: %d", (int) i); len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1; p = ngx_pnalloc(r->pool, len + sizeof(struct sockaddr_in)); if (p == NULL) { u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; lua_pushnil(L); lua_pushliteral(L, "out of memory"); return; } sin = (struct sockaddr_in *) &p[len]; ngx_memzero(sin, sizeof(struct sockaddr_in)); len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN); len = ngx_sprintf(&p[len], ":%d", ur->port) - p; sin->sin_family = AF_INET; sin->sin_port = htons(ur->port); sin->sin_addr.s_addr = ur->addrs[i]; ur->sockaddr = (struct sockaddr *) sin; ur->socklen = sizeof(struct sockaddr_in); ur->host.data = p; ur->host.len = len; ur->naddrs = 1; ur->ctx = NULL; ngx_resolve_name_done(ctx); u->waiting = 0; if (waiting) { lctx->udp_socket_busy = 0; lctx->udp_socket_ready = 1; r->write_event_handler(r); } else { (void) ngx_http_lua_socket_resolve_retval_handler(r, u, L); } }
void luaL_pushresult (luaL_Buffer_53 *B) { lua_pushlstring(B->L2, B->ptr, B->nelems); if (B->ptr != B->b.buffer) lua_replace(B->L2, -2); /* remove userdata buffer */ }
// 1 string data // 2 result document table // return boolean succ (false -> request id, error document) // number request_id // document first // string cursor_id // integer startfrom static int op_reply(lua_State *L) { size_t data_len = 0; const char * data = luaL_checklstring(L,1,&data_len); struct { // int32_t length; // total message size, including this int32_t request_id; // identifier for this message int32_t response_id; // requestID from the original request // (used in reponses from db) int32_t opcode; // request type int32_t flags; int32_t cursor_id[2]; int32_t starting; int32_t number; } const *reply = (const void *)data; if (data_len < sizeof(*reply)) { lua_pushboolean(L, 0); return 1; } int id = little_endian(reply->response_id); int flags = little_endian(reply->flags); if (flags & REPLY_QUERYFAILURE) { lua_pushboolean(L,0); lua_pushinteger(L, id); lua_pushlightuserdata(L, (void *)(reply+1)); return 3; } int starting_from = little_endian(reply->starting); int number = little_endian(reply->number); int sz = (int)data_len - sizeof(*reply); const uint8_t * doc = (const uint8_t *)(reply+1); if (lua_istable(L,2)) { int i = 1; while (sz > 4) { lua_pushlightuserdata(L, (void *)doc); lua_rawseti(L, 2, i); int32_t doc_len = get_length((document)doc); doc += doc_len; sz -= doc_len; ++i; } if (i != number + 1) { lua_pushboolean(L,0); lua_pushinteger(L, id); return 2; } int c = lua_rawlen(L, 2); for (;i<=c;i++) { lua_pushnil(L); lua_rawseti(L, 2, i); } } else { if (sz >= 4) { sz -= get_length((document)doc); } } if (sz != 0) { return luaL_error(L, "Invalid result bson document"); } lua_pushboolean(L,1); lua_pushinteger(L, id); if (number == 0) lua_pushnil(L); else lua_pushlightuserdata(L, (void *)(reply+1)); if (reply->cursor_id[0] == 0 && reply->cursor_id[1]==0) { // closed cursor lua_pushnil(L); } else { lua_pushlstring(L, (const char *)(reply->cursor_id), 8); } lua_pushinteger(L, starting_from); return 5; }
void ngx_http_lua_wev_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_http_lua_ctx_t *ctx; ngx_http_lua_main_conf_t *lmcf; lua_State *cc; ngx_chain_t *cl; size_t len; u_char *pos, *last; ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { goto error; } dd("request done: %d", (int) r->done); dd("cleanup done: %p", ctx->cleanup); #if 1 if (ctx->cleanup == NULL) { return; } #endif if (ctx->waiting && ! ctx->done) { if (r->main->posted_requests && r->main->posted_requests->request != r) { dd("postpone our wev handler"); #if defined(nginx_version) && nginx_version >= 8012 ngx_http_post_request(r, NULL); #else ngx_http_post_request(r); #endif return; } } ctx->done = 0; len = 0; for (cl = ctx->sr_body; cl; cl = cl->next) { /* ignore all non-memory buffers */ len += cl->buf->last - cl->buf->pos; } if (len == 0) { pos = NULL; } else { last = pos = ngx_palloc(r->pool, len); if (pos == NULL) { goto error; } for (cl = ctx->sr_body; cl; cl = cl->next) { /* ignore all non-memory buffers */ last = ngx_copy(last, cl->buf->pos, cl->buf->last - cl->buf->pos); } } cc = ctx->cc; /* {{{ construct ret value */ lua_newtable(cc); /* copy captured status */ lua_pushinteger(cc, ctx->sr_status); lua_setfield(cc, -2, "status"); /* copy captured body */ lua_pushlstring(cc, (const char*)pos, len); lua_setfield(cc, -2, "body"); /* }}} */ lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); dd("about to run thread..."); rc = ngx_http_lua_run_thread(lmcf->lua, r, ctx, 1); dd("already run thread..."); if (rc == NGX_AGAIN || rc == NGX_DONE) { ctx->waiting = 1; ctx->done = 0; } else { ctx->waiting = 0; ctx->done = 1; ngx_http_finalize_request(r, rc); } return; error: ngx_http_finalize_request(r, ctx->headers_sent ? NGX_ERROR: NGX_HTTP_INTERNAL_SERVER_ERROR); return; }
//----------------------------------------------------------------// void MOAILuaState::Push ( void* data, size_t size ) { lua_pushlstring ( this->mState, ( cc8* )data, size ); }
// char static void luapuz_pushchar(lua_State * L, const char ch) { lua_pushlstring(L, &ch, 1); }
static int from_arpa_to_ip6(lua_State *lua) { if (lua_type(lua, 1) != LUA_TSTRING) { lua_pushnil(lua); return 1; } data = (const unsigned char *) lua_tolstring(lua, 1, &dlen); if (dlen != 72) { fprintf(stderr, "(%s:%s:%i) string is not 72 characters in length: %lu'\n", __FILE__, __func__, __LINE__, dlen); lua_pushnil(lua); return 1; } ip6_string[0] = data[62]; ip6_string[1] = data[60]; ip6_string[2] = data[58]; ip6_string[3] = data[56]; ip6_string[5] = data[54]; ip6_string[6] = data[52]; ip6_string[7] = data[50]; ip6_string[8] = data[48]; ip6_string[10] = data[46]; ip6_string[11] = data[44]; ip6_string[12] = data[42]; ip6_string[13] = data[40]; ip6_string[15] = data[38]; ip6_string[16] = data[36]; ip6_string[17] = data[34]; ip6_string[18] = data[32]; ip6_string[20] = data[30]; ip6_string[21] = data[28]; ip6_string[22] = data[26]; ip6_string[23] = data[24]; ip6_string[25] = data[22]; ip6_string[26] = data[20]; ip6_string[27] = data[18]; ip6_string[28] = data[16]; ip6_string[30] = data[14]; ip6_string[31] = data[12]; ip6_string[32] = data[10]; ip6_string[33] = data[8]; ip6_string[35] = data[6]; ip6_string[36] = data[4]; ip6_string[37] = data[2]; ip6_string[38] = data[0]; // fDns_print_string_in_hex2(__FILE__, __func__, __LINE__, &ip6_string[0], 39); if (inet_pton(AF_INET6, (const char *)&ip6_string[0], &ia6) == 1) { bzero(&ip_string[0], INET6_ADDRSTRLEN + 1); if (inet_ntop(AF_INET6, &ia6.s6_addr[0], &ip_string[0], INET6_ADDRSTRLEN) != NULL) { // fprintf(stderr, "(%s:%s:%i) ip_string: '%s' \n", __FILE__, __func__, __LINE__, &ip_string[0]); lua_pushlstring(lua, (const char *)&ip_string[0], strlen(&ip_string[0])); } else { fprintf(stderr, "(%s:%s:%i) '%s' can not be converted to an ip6 address\n", __FILE__, __func__, __LINE__, &ip6_string[0]); lua_pushnil(lua); } } else { fprintf(stderr, "(%s:%s:%i) '%s' is not an ip6 address\n", __FILE__, __func__, __LINE__, &ip6_string[0]); lua_pushnil(lua); } return 1; }
LUA_API void luanet_pushlwstring(lua_State *L, const wchar_t *s, size_t len) { std::string utf8string(utf8_encode(s, len)); lua_pushlstring(L, utf8string.c_str(), len); }
/* ** Pushes the indexed value onto the lua stack */ static void push_column(lua_State *L, int i, cur_data *cur) { int varcharlen; struct tm timevar; char timestr[256]; ISC_STATUS blob_stat; isc_blob_handle blob_handle = 0; ISC_QUAD blob_id; luaL_Buffer b; char *buffer; unsigned short actual_seg_len; if( (cur->out_sqlda->sqlvar[i].sqlind != NULL) && (*(cur->out_sqlda->sqlvar[i].sqlind) != 0) ) { /* a null field? */ lua_pushnil(L); } else { switch(cur->out_sqlda->sqlvar[i].sqltype & ~1) { case SQL_VARYING: varcharlen = (int)isc_vax_integer(cur->out_sqlda->sqlvar[i].sqldata, 2); lua_pushlstring(L, cur->out_sqlda->sqlvar[i].sqldata+2, varcharlen); break; case SQL_TEXT: lua_pushlstring(L, cur->out_sqlda->sqlvar[i].sqldata, cur->out_sqlda->sqlvar[i].sqllen); break; case SQL_SHORT: luasql_pushinteger(L, *(short*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_LONG: luasql_pushinteger(L, *(long*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_INT64: luasql_pushinteger(L, *(ISC_INT64*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_FLOAT: lua_pushnumber(L, *(float*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_DOUBLE: lua_pushnumber(L, *(double*)(cur->out_sqlda->sqlvar[i].sqldata)); break; case SQL_TYPE_TIME: isc_decode_sql_time((ISC_TIME*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar); strftime(timestr, 255, "%X", &timevar); lua_pushstring(L, timestr); break; case SQL_TYPE_DATE: isc_decode_sql_date((ISC_DATE*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar); strftime(timestr, 255, "%x", &timevar); lua_pushstring(L, timestr); break; case SQL_TIMESTAMP: isc_decode_timestamp((ISC_TIMESTAMP*)(cur->out_sqlda->sqlvar[i].sqldata), &timevar); strftime(timestr, 255, "%x %X", &timevar); lua_pushstring(L, timestr); break; case SQL_BLOB: /* get the BLOB ID and open it */ memcpy(&blob_id, cur->out_sqlda->sqlvar[i].sqldata, sizeof(ISC_QUAD)); isc_open_blob2( cur->env->status_vector, &cur->conn->db, &cur->conn->transaction, &blob_handle, &blob_id, 0, NULL ); /* fetch the blob data */ luaL_buffinit(L, &b); buffer = luaL_prepbuffer(&b); blob_stat = isc_get_segment( cur->env->status_vector, &blob_handle, &actual_seg_len, LUAL_BUFFERSIZE, buffer ); while(blob_stat == 0 || cur->env->status_vector[1] == isc_segment) { luaL_addsize(&b, actual_seg_len); buffer = luaL_prepbuffer(&b); blob_stat = isc_get_segment( cur->env->status_vector, &blob_handle, &actual_seg_len, LUAL_BUFFERSIZE, buffer ); } /* finnished, close the BLOB */ isc_close_blob(cur->env->status_vector, &blob_handle); blob_handle = 0; luaL_pushresult(&b); break; default: lua_pushstring(L, "<unsupported data type>"); break; } } }
static int test_eof (lua_State *L, FILE *f) { int c = getc(f); ungetc(c, f); lua_pushlstring(L, NULL, 0); return (c != EOF); }
/* ** Returns a row of data from the query ** Lua Returns: ** list of results or table of results depending on call ** nil and error message otherwise. */ static int cur_fetch (lua_State *L) { ISC_STATUS fetch_stat; int i; cur_data *cur = getcursor(L,1); const char *opts = luaL_optstring (L, 3, "n"); int num = strchr(opts, 'n') != NULL; int alpha = strchr(opts, 'a') != NULL; if ((fetch_stat = isc_dsql_fetch(cur->env->status_vector, &cur->stmt, 1, cur->out_sqlda)) == 0) { if (lua_istable (L, 2)) { /* remove the option string */ lua_settop(L, 2); /* loop through the columns */ for (i = 0; i < cur->out_sqlda->sqld; i++) { push_column(L, i, cur); if( num ) { lua_pushnumber(L, i+1); lua_pushvalue(L, -2); lua_settable(L, 2); } if( alpha ) { lua_pushlstring(L, cur->out_sqlda->sqlvar[i].aliasname, cur->out_sqlda->sqlvar[i].aliasname_length); lua_pushvalue(L, -2); lua_settable(L, 2); } lua_pop(L, 1); } /* returning given table */ return 1; } else { for (i = 0; i < cur->out_sqlda->sqld; i++) push_column(L, i, cur); /* returning a list of values */ return cur->out_sqlda->sqld; } } /* isc_dsql_fetch returns 100 if no more rows remain to be retrieved so this can be ignored */ if (fetch_stat != 100L) return return_db_error(L, cur->env->status_vector); /* last row has been fetched, close cursor */ isc_dsql_free_statement(cur->env->status_vector, &cur->stmt, DSQL_drop); if ( CHECK_DB_ERROR(cur->env->status_vector) ) return return_db_error(L, cur->env->status_vector); /* free the cursor data */ free_cur(cur); cur->closed = 1; /* remove cursor from lock count */ --cur->conn->lock; /* return sucsess */ return 0; }
static int ngx_http_lua_ngx_resp_get_headers(lua_State *L) { ngx_list_part_t *part; ngx_table_elt_t *header; ngx_http_request_t *r; u_char *lowcase_key = NULL; size_t lowcase_key_sz = 0; ngx_uint_t i; int n; int max; int raw = 0; int count = 0; n = lua_gettop(L); if (n >= 1) { if (lua_isnil(L, 1)) { max = NGX_HTTP_LUA_MAX_HEADERS; } else { max = luaL_checkinteger(L, 1); } if (n >= 2) { raw = lua_toboolean(L, 2); } } else { max = NGX_HTTP_LUA_MAX_HEADERS; } r = ngx_http_lua_get_req(L); if (r == NULL) { return luaL_error(L, "no request object found"); } ngx_http_lua_check_fake_request(L, r); part = &r->headers_out.headers.part; count = part->nelts; while (part->next) { part = part->next; count += part->nelts; } if (max > 0 && count > max) { count = max; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua exceeding request header limit %d", max); } lua_createtable(L, 0, count); if (!raw) { lua_pushlightuserdata(L, &ngx_http_lua_headers_metatable_key); lua_rawget(L, LUA_REGISTRYINDEX); lua_setmetatable(L, -2); } #if 1 if (r->headers_out.content_type.len) { lua_pushliteral(L, "content-type"); lua_pushlstring(L, (char *) r->headers_out.content_type.data, r->headers_out.content_type.len); lua_rawset(L, -3); } if (r->headers_out.content_length == NULL && r->headers_out.content_length_n >= 0) { lua_pushliteral(L, "content-length"); lua_pushfstring(L, "%d", (int) r->headers_out.content_length_n); lua_rawset(L, -3); } lua_pushliteral(L, "connection"); if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) { lua_pushliteral(L, "upgrade"); } else if (r->keepalive) { lua_pushliteral(L, "keep-alive"); } else { lua_pushliteral(L, "close"); } lua_rawset(L, -3); if (r->chunked) { lua_pushliteral(L, "transfer-encoding"); lua_pushliteral(L, "chunked"); lua_rawset(L, -3); } #endif part = &r->headers_out.headers.part; header = part->elts; for (i = 0; /* void */; i++) { dd("stack top: %d", lua_gettop(L)); if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; header = part->elts; i = 0; } if (header[i].hash == 0) { continue; } if (raw) { lua_pushlstring(L, (char *) header[i].key.data, header[i].key.len); } else { /* nginx does not even bother initializing output header entry's * "lowcase_key" field. so we cannot count on that at all. */ if (header[i].key.len > lowcase_key_sz) { lowcase_key_sz = header[i].key.len * 2; /* we allocate via Lua's GC to prevent in-request * leaks in the nginx request memory pools */ lowcase_key = lua_newuserdata(L, lowcase_key_sz); lua_insert(L, 1); } ngx_strlow(lowcase_key, header[i].key.data, header[i].key.len); lua_pushlstring(L, (char *) lowcase_key, header[i].key.len); } /* stack: [udata] table key */ lua_pushlstring(L, (char *) header[i].value.data, header[i].value.len); /* stack: [udata] table key value */ ngx_http_lua_set_multi_value_table(L, -3); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua response header: \"%V: %V\"", &header[i].key, &header[i].value); if (--count == 0) { return 1; } } return 1; }
ngx_int_t ngx_http_lua_set_by_chunk(lua_State *L, ngx_http_request_t *r, ngx_str_t *val, ngx_http_variable_value_t *args, size_t nargs, ngx_str_t *script) { size_t i; ngx_int_t rc; u_char *err_msg; size_t len; u_char *data; #if (NGX_PCRE) ngx_pool_t *old_pool; #endif ngx_http_lua_ctx_t *ctx; ngx_http_cleanup_t *cln; dd("nargs: %d", (int) nargs); ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { ctx = ngx_http_lua_create_ctx(r); if (ctx == NULL) { return NGX_ERROR; } } else { ngx_http_lua_reset_ctx(r, L, ctx); } if (ctx->cleanup == NULL) { cln = ngx_http_cleanup_add(r, 0); if (cln == NULL) { return NGX_ERROR; } cln->handler = ngx_http_lua_request_cleanup; cln->data = r; ctx->cleanup = &cln->handler; } ctx->context = NGX_HTTP_LUA_CONTEXT_SET; dd("set Lua VM panic handler"); lua_atpanic(L, ngx_http_lua_atpanic); NGX_LUA_EXCEPTION_TRY { dd("initialize nginx context in Lua VM, code chunk at " "stack top sp = 1"); ngx_http_lua_set_by_lua_env(L, r, nargs, args); /* passing directive arguments to the user code */ for (i = 0; i < nargs; i++) { lua_pushlstring(L, (const char *) args[i].data, args[i].len); } #if (NGX_PCRE) /* XXX: work-around to nginx regex subsystem */ old_pool = ngx_http_lua_pcre_malloc_init(r->pool); #endif lua_pushcfunction(L, ngx_http_lua_traceback); lua_insert(L, 1); /* put it under chunk and args */ dd("protected call user code"); rc = lua_pcall(L, nargs, 1, 1); dd("after protected call user code"); lua_remove(L, 1); /* remove traceback function */ #if (NGX_PCRE) /* XXX: work-around to nginx regex subsystem */ ngx_http_lua_pcre_malloc_done(old_pool); #endif if (rc != 0) { /* error occured when running loaded code */ err_msg = (u_char *) lua_tolstring(L, -1, &len); if (err_msg == NULL) { err_msg = (u_char *) "unknown reason"; len = sizeof("unknown reason") - 1; } ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "failed to run set_by_lua*: %*s", len, err_msg); lua_settop(L, 0); /* clear remaining elems on stack */ return NGX_ERROR; } data = (u_char *) lua_tolstring(L, -1, &len); if (data) { val->data = ngx_palloc(r->pool, len); if (val->data == NULL) { return NGX_ERROR; } ngx_memcpy(val->data, data, len); val->len = len; } else { val->data = NULL; val->len = 0; } } NGX_LUA_EXCEPTION_CATCH { dd("nginx execution restored"); return NGX_ERROR; } /* clear Lua stack */ lua_settop(L, 0); return NGX_OK; }
LUA_API void lua_pushstring (lua_State *L, const char *s) { if (s == NULL) lua_pushnil(L); else lua_pushlstring(L, s, strlen(s)); }
int luapng_load(lua_State *L) { luaL_checktype(L, 1, LUA_TSTRING); const char *file_name = lua_tostring(L, 1); png_byte header[8]; FILE *fp = fopen(file_name, "rb"); if (fp == 0) { return luaL_error(L, "can't open %s", file_name); } // read the header fread(header, 1, 8, fp); if (png_sig_cmp(header, 0, 8)) { fclose(fp); return luaL_error(L, "%s is not a PNG", file_name); } png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fclose(fp); return luaL_error(L, "can't read %s", file_name); } // create png info struct png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); fclose(fp); return luaL_error(L, "can't read info from %s", file_name); } // create png info struct png_infop end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); fclose(fp); return luaL_error(L, "can't read info from %s", file_name); } // the code in this if statement gets called if libpng encounters an error if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); return luaL_error(L, "error from libpng while loading %s", file_name); } // init png reading png_init_io(png_ptr, fp); // let libpng know you already read the first 8 bytes png_set_sig_bytes(png_ptr, 8); // read all the info up to the image data png_read_info(png_ptr, info_ptr); // variables to pass to get info int bit_depth, color_type; png_uint_32 temp_width, temp_height; // get info about png png_get_IHDR(png_ptr, info_ptr, &temp_width, &temp_height, &bit_depth, &color_type, NULL, NULL, NULL); //printf("%s: %lux%lu %d\n", file_name, temp_width, temp_height, color_type); if (bit_depth != 8) { return luaL_error(L, "%s: unsupported bit depth %d, must be 8", file_name, bit_depth); } int has_alpha = 0; switch(color_type) { case PNG_COLOR_TYPE_RGB: has_alpha = 0; break; case PNG_COLOR_TYPE_RGB_ALPHA: has_alpha = 1; break; default: return luaL_error(L, "%s: unknown libpng color type %d", file_name, color_type); } // Update the png info struct. png_read_update_info(png_ptr, info_ptr); // Row size in bytes. int rowbytes = png_get_rowbytes(png_ptr, info_ptr); // glTexImage2d requires rows to be 4-byte aligned rowbytes += 3 - ((rowbytes-1) % 4); // Allocate the image_data as a big block, to be given to opengl size_t image_data_size = rowbytes * temp_height * sizeof(png_byte) + 15; png_byte * image_data = (png_byte *)malloc(image_data_size); if (image_data == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); return luaL_error(L, "%s: could not allocate memory for image data", file_name); } // row_pointers is for pointing to image_data for reading the png with libpng png_byte ** row_pointers = (png_byte **)malloc(temp_height * sizeof(png_byte *)); if (row_pointers == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); free(image_data); fclose(fp); return luaL_error(L, "%s: could not allocate memory for row pointers", file_name); } // set the individual row_pointers to point at the correct offsets of image_data for (unsigned int i = 0; i < temp_height; i++) { row_pointers[i] = image_data + i * rowbytes; } // read the png into image_data through row_pointers png_read_image(png_ptr, row_pointers); // Generate the OpenGL texture object lua_pushlstring(L, (char *)image_data, image_data_size); lua_pushnumber(L, temp_width); lua_pushnumber(L, temp_height); lua_pushboolean(L, has_alpha); // clean up png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); free(image_data); free(row_pointers); fclose(fp); return 4; }
static void mar_decode_value (lua_State *L, const char *buf, size_t len, const char **p, size_t *idx) { size_t l; char val_type = **p; mar_incr_ptr(MAR_CHR); switch (val_type) { case LUA_TBOOLEAN: lua_pushboolean(L, *(char*)*p); mar_incr_ptr(MAR_CHR); break; case LUA_TNUMBER: lua_pushnumber(L, *(lua_Number*)*p); mar_incr_ptr(MAR_I64); break; case MAR_TINT: lua_pushinteger(L, *(lua_Integer*)*p); mar_incr_ptr(MAR_I64); break; case LUA_TSTRING: mar_next_len(l, uint32_t); lua_pushlstring(L, *p, l); mar_incr_ptr(l); break; case LUA_TTABLE: { char tag = *(char*)*p; mar_incr_ptr(MAR_CHR); if (tag == MAR_TREF) { int ref; mar_next_len(ref, int); lua_rawgeti(L, SEEN_IDX, ref); } else if (tag == MAR_TVAL) { mar_next_len(l, uint32_t); lua_newtable(L); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_decode_table(L, *p, l, idx); mar_incr_ptr(l); } else if (tag == MAR_TUSR) { mar_next_len(l, uint32_t); lua_newtable(L); mar_decode_table(L, *p, l, idx); lua_rawgeti(L, -1, 1); lua_call(L, 0, 1); lua_remove(L, -2); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_incr_ptr(l); } else { luaL_error(L, "bad encoded data"); } break; } case LUA_TFUNCTION: { unsigned int nups; unsigned int i; mar_Buffer dec_buf; char tag = *(char*)*p; mar_incr_ptr(1); if (tag == MAR_TREF) { int ref; mar_next_len(ref, int); lua_rawgeti(L, SEEN_IDX, ref); } else { mar_next_len(l, uint32_t); dec_buf.data = (char*)*p; dec_buf.size = l; dec_buf.head = l; dec_buf.seek = 0; lua_load(L, (lua_Reader)buf_read, &dec_buf, "=marshal", NULL); mar_incr_ptr(l); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_next_len(l, uint32_t); lua_newtable(L); mar_decode_table(L, *p, l, idx); lua_pushstring(L, MAR_ENV_IDX_KEY); lua_rawget(L, -2); if (lua_isnumber(L, -1)) { lua_pushglobaltable(L); lua_rawset(L, -3); } else { lua_pop(L, 1); } lua_pushstring(L, MAR_NUPS_IDX_KEY); lua_rawget(L, -2); nups = luaL_checknumber(L, -1); lua_pop(L, 1); for (i = 1; i <= nups; i++) { lua_rawgeti(L, -1, i); lua_setupvalue(L, -3, i); } lua_pop(L, 1); mar_incr_ptr(l); } break; } case LUA_TUSERDATA: { char tag = *(char*)*p; mar_incr_ptr(MAR_CHR); if (tag == MAR_TREF) { int ref; mar_next_len(ref, int); lua_rawgeti(L, SEEN_IDX, ref); } else if (tag == MAR_TUSR) { mar_next_len(l, uint32_t); lua_newtable(L); mar_decode_table(L, *p, l, idx); lua_rawgeti(L, -1, 1); lua_call(L, 0, 1); lua_remove(L, -2); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_incr_ptr(l); } else { /* tag == MAR_TVAL */ lua_pushnil(L); } break; } case LUA_TNIL: case LUA_TTHREAD: lua_pushnil(L); break; default: luaL_error(L, "bad code"); } }
static void gmatch_pushsubject (lua_State *L, TArgExec *argE) { lua_pushlstring (L, argE->text, argE->textlen); }