root/src/modules/lua_noit.c

Revision db7752d7f39300e6bbc5db47364833d30558de11, 53.0 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 3 years ago)

fix type warnings

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007-2010, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  *       notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  *       copyright notice, this list of conditions and the following
13  *       disclaimer in the documentation and/or other materials provided
14  *       with the distribution.
15  *     * Neither the name OmniTI Computer Consulting, Inc. nor the names
16  *       of its contributors may be used to endorse or promote products
17  *       derived from this software without specific prior written
18  *       permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "noit_defines.h"
34
35 #include <assert.h>
36 #include <math.h>
37 #include <errno.h>
38 #include <unistd.h>
39 #include <netinet/in.h>
40 #include <arpa/inet.h>
41 #ifdef HAVE_SYS_FILIO_H
42 #include <sys/filio.h>
43 #endif
44 #include <zlib.h>
45 #include <libxml/parser.h>
46 #include <libxml/xpath.h>
47 #include <libxml/tree.h>
48 #include <openssl/md5.h>
49
50 #include "noit_conf.h"
51 #include "noit_module.h"
52 #include "noit_check.h"
53 #include "noit_check_tools.h"
54 #include "noit_xml.h"
55 #include "utils/noit_log.h"
56 #include "utils/noit_str.h"
57 #include "utils/noit_b32.h"
58 #include "utils/noit_b64.h"
59 #include "eventer/eventer.h"
60 #include "json-lib/json.h"
61 #include "lua_noit.h"
62
63 #define DEFLATE_CHUNK_SIZE 32768
64
65 #define LUA_DISPATCH(n, f) \
66      if(!strcmp(k, #n)) { \
67        lua_pushlightuserdata(L, udata); \
68        lua_pushcclosure(L, f, 1); \
69        return 1; \
70      }
71 #define LUA_RETSTRING(n, g) \
72      if(!strcmp(k, #n)) { \
73        lua_pushstring(L, g); \
74        return 1; \
75      }
76 #define LUA_RETINTEGER(n, g) \
77      if(!strcmp(k, #n)) { \
78        lua_pushinteger(L, g); \
79        return 1; \
80      }
81
82 typedef struct {
83   struct json_tokener *tok;
84   struct json_object *root;
85 } json_crutch;
86
87 static void
88 nl_extended_free(void *vcl) {
89   struct nl_slcl *cl = vcl;
90   if(cl->inbuff) free(cl->inbuff);
91   free(cl);
92 }
93 static int
94 lua_push_inet_ntop(lua_State *L, struct sockaddr *r) {
95   char remote_str[128];
96   int len;
97   switch(r->sa_family) {
98     case AF_INET:
99       len = sizeof(struct sockaddr_in);
100       inet_ntop(AF_INET, &((struct sockaddr_in *)r)->sin_addr,
101                 remote_str, len);
102       lua_pushstring(L, remote_str);
103       lua_pushinteger(L, ntohs(((struct sockaddr_in *)r)->sin_port));
104       break;
105     case AF_INET6:
106       len = sizeof(struct sockaddr_in6);
107       inet_ntop(AF_INET6, &((struct sockaddr_in6 *)r)->sin6_addr,
108                 remote_str, len);
109       lua_pushstring(L, remote_str);
110       lua_pushinteger(L, ntohs(((struct sockaddr_in6 *)r)->sin6_port));
111       break;
112     default:
113       lua_pushnil(L);
114       lua_pushnil(L);
115   }
116   return 2;
117 }
118 static void
119 inbuff_addlstring(struct nl_slcl *cl, const char *b, int l) {
120   int newsize = 0;
121   char *newbuf;
122   if(cl->inbuff_len + l > cl->inbuff_allocd)
123     newsize = cl->inbuff_len + l;
124   if(newsize) {
125     newbuf = cl->inbuff_allocd ? realloc(cl->inbuff, newsize) : malloc(newsize);
126     assert(newbuf);
127     cl->inbuff = newbuf;
128     cl->inbuff_allocd = newsize;
129   }
130   memcpy(cl->inbuff + cl->inbuff_len, b, l);
131   cl->inbuff_len += l;
132 }
133
134 static int
135 noit_lua_socket_connect_complete(eventer_t e, int mask, void *vcl,
136                                  struct timeval *now) {
137   noit_lua_check_info_t *ci;
138   struct nl_slcl *cl = vcl;
139   int args = 0, aerrno;
140   socklen_t aerrno_len = sizeof(aerrno);
141
142   ci = get_ci(cl->L);
143   assert(ci);
144   noit_lua_check_deregister_event(ci, e, 0);
145
146   *(cl->eptr) = eventer_alloc();
147   memcpy(*cl->eptr, e, sizeof(*e));
148   noit_lua_check_register_event(ci, *cl->eptr);
149
150   if(getsockopt(e->fd,SOL_SOCKET,SO_ERROR, &aerrno, &aerrno_len) == 0)
151     if(aerrno != 0) goto connerr;
152
153   if(!(mask & EVENTER_EXCEPTION) &&
154      mask & EVENTER_WRITE) {
155     /* Connect completed successfully */
156     lua_pushinteger(cl->L, 0);
157     args = 1;
158   }
159   else {
160     aerrno = errno;
161    connerr:
162     lua_pushinteger(cl->L, -1);
163     lua_pushstring(cl->L, strerror(aerrno));
164     args = 2;
165   }
166   noit_lua_resume(ci, args);
167   return 0;
168 }
169 static int
170 noit_lua_socket_recv_complete(eventer_t e, int mask, void *vcl,
171                               struct timeval *now) {
172   noit_lua_check_info_t *ci;
173   struct nl_slcl *cl = vcl;
174   int rv, args = 0;
175   void *inbuff = NULL;
176   socklen_t alen;
177
178   ci = get_ci(cl->L);
179   assert(ci);
180
181   if(mask & EVENTER_EXCEPTION) {
182     lua_pushinteger(cl->L, -1);
183     args = 1;
184     goto alldone;
185   }
186
187   inbuff = malloc(cl->read_goal);
188   if(!inbuff) {
189     lua_pushinteger(cl->L, -1);
190     args = 1;
191     goto alldone;
192   }
193
194   alen = sizeof(cl->address);
195   while((rv = recvfrom(e->fd, inbuff, cl->read_goal, 0,
196                        (struct sockaddr *)&cl->address, &alen)) == -1 &&
197         errno == EINTR);
198   if(rv < 0) {
199     if(errno == EAGAIN) {
200       free(inbuff);
201       return EVENTER_READ | EVENTER_EXCEPTION;
202     }
203     lua_pushinteger(cl->L, rv);
204     lua_pushstring(cl->L, strerror(errno));
205     args = 2;
206   }
207   else {
208     lua_pushinteger(cl->L, rv);
209     lua_pushlstring(cl->L, inbuff, rv);
210     args = 2;
211     args += lua_push_inet_ntop(cl->L, (struct sockaddr *)&cl->address);
212   }
213
214  alldone:
215   if(inbuff) free(inbuff);
216   eventer_remove_fd(e->fd);
217   noit_lua_check_deregister_event(ci, e, 0);
218   *(cl->eptr) = eventer_alloc();
219   memcpy(*cl->eptr, e, sizeof(*e));
220   noit_lua_check_register_event(ci, *cl->eptr);
221   noit_lua_resume(ci, args);
222   return 0;
223 }
224 static int
225 noit_lua_socket_recv(lua_State *L) {
226   int args, rv;
227   struct nl_slcl *cl;
228   noit_lua_check_info_t *ci;
229   eventer_t e, *eptr;
230   void *inbuff;
231   socklen_t alen;
232
233   ci = get_ci(L);
234   assert(ci);
235
236   eptr = lua_touserdata(L, lua_upvalueindex(1));
237   if(eptr != lua_touserdata(L, 1))
238     luaL_error(L, "must be called as method");
239   e = *eptr;
240   cl = e->closure;
241   cl->read_goal = lua_tointeger(L, 2);
242   inbuff = malloc(cl->read_goal);
243
244   alen = sizeof(cl->address);
245   while((rv = recvfrom(e->fd, inbuff, cl->read_goal, 0,
246                        (struct sockaddr *)&cl->address, &alen)) == -1 &&
247         errno == EINTR);
248   if(rv < 0) {
249     if(errno == EAGAIN) {
250       e->callback = noit_lua_socket_recv_complete;
251       e->mask = EVENTER_READ | EVENTER_EXCEPTION;
252       eventer_add(e);
253       free(inbuff);
254       return noit_lua_yield(ci, 0);
255     }
256     lua_pushinteger(cl->L, rv);
257     lua_pushstring(cl->L, strerror(errno));
258     args = 2;
259   }
260   else {
261     lua_pushinteger(cl->L, rv);
262     lua_pushlstring(cl->L, inbuff, rv);
263     args = 2;
264     args += lua_push_inet_ntop(cl->L, (struct sockaddr *)&cl->address);
265   }
266   free(inbuff);
267   return args;
268 }
269 static int
270 noit_lua_socket_send_complete(eventer_t e, int mask, void *vcl,
271                               struct timeval *now) {
272   noit_lua_check_info_t *ci;
273   struct nl_slcl *cl = vcl;
274   int sbytes;
275   int args = 0;
276
277   ci = get_ci(cl->L);
278   assert(ci);
279
280   if(mask & EVENTER_EXCEPTION) {
281     lua_pushinteger(cl->L, -1);
282     args = 1;
283     goto alldone;
284   }
285   if(cl->sendto) {
286     while((sbytes = sendto(e->fd, cl->outbuff, cl->write_goal, 0,
287                            (struct sockaddr *)&cl->address,
288                            cl->address.sin4.sin_family==AF_INET ?
289                                sizeof(cl->address.sin4) :
290                                sizeof(cl->address.sin6))) == -1 &&
291           errno == EINTR);
292   }
293   else {
294     while((sbytes = send(e->fd, cl->outbuff, cl->write_goal, 0)) == -1 &&
295           errno == EINTR);
296   }
297   if(sbytes > 0) {
298     lua_pushinteger(cl->L, sbytes);
299     args = 1;
300   }
301   else if(sbytes == -1 && errno == EAGAIN) {
302     return EVENTER_WRITE | EVENTER_EXCEPTION;
303   }
304   else {
305     lua_pushinteger(cl->L, sbytes);
306     args = 1;
307     if(sbytes == -1) {
308       lua_pushstring(cl->L, strerror(errno));
309       args++;
310     }
311   }
312
313  alldone:
314   eventer_remove_fd(e->fd);
315   noit_lua_check_deregister_event(ci, e, 0);
316   *(cl->eptr) = eventer_alloc();
317   memcpy(*cl->eptr, e, sizeof(*e));
318   noit_lua_check_register_event(ci, *cl->eptr);
319   noit_lua_resume(ci, args);
320   return 0;
321 }
322 static int
323 noit_lua_socket_send(lua_State *L) {
324   noit_lua_check_info_t *ci;
325   eventer_t e, *eptr;
326   const void *bytes;
327   size_t nbytes;
328   ssize_t sbytes;
329
330   ci = get_ci(L);
331   assert(ci);
332
333   eptr = lua_touserdata(L, lua_upvalueindex(1));
334   if(eptr != lua_touserdata(L, 1))
335     luaL_error(L, "must be called as method");
336   e = *eptr;
337   if(lua_gettop(L) != 2)
338     luaL_error(L, "noit.socket.send with bad arguments");
339   bytes = lua_tolstring(L, 2, &nbytes);
340
341   while((sbytes = send(e->fd, bytes, nbytes, 0)) == -1 && errno == EINTR);
342   if(sbytes < 0 && errno == EAGAIN) {
343     struct nl_slcl *cl;
344     /* continuation */
345     cl = e->closure;
346     cl->write_sofar = 0;
347     cl->outbuff = bytes;
348     cl->write_goal = nbytes;
349     cl->sendto = 0;
350     e->callback = noit_lua_socket_send_complete;
351     e->mask = EVENTER_WRITE | EVENTER_EXCEPTION;
352     eventer_add(e);
353     return noit_lua_yield(ci, 0);
354   }
355   lua_pushinteger(L, sbytes);
356   if(sbytes < 0) {
357     lua_pushstring(L, strerror(errno));
358     return 2;
359   }
360   return 1;
361 }
362
363 static int
364 noit_lua_socket_sendto(lua_State *L) {
365   noit_lua_check_info_t *ci;
366   eventer_t e, *eptr;
367   const char *target;
368   unsigned short port;
369   int8_t family;
370   int rv;
371   const void *bytes;
372   size_t nbytes;
373   ssize_t sbytes;
374   union {
375     struct sockaddr_in sin4;
376     struct sockaddr_in6 sin6;
377   } a;
378
379   ci = get_ci(L);
380   assert(ci);
381
382   eptr = lua_touserdata(L, lua_upvalueindex(1));
383   if(eptr != lua_touserdata(L, 1))
384     luaL_error(L, "must be called as method");
385   e = *eptr;
386   if(lua_gettop(L) != 4)
387     luaL_error(L, "noit.socket.sendto with bad arguments");
388   bytes = lua_tolstring(L, 2, &nbytes);
389   target = lua_tostring(L, 3);
390   if(!target) target = "";
391   port = lua_tointeger(L, 4);
392
393   family = AF_INET;
394   rv = inet_pton(family, target, &a.sin4.sin_addr);
395   if(rv != 1) {
396     family = AF_INET6;
397     rv = inet_pton(family, target, &a.sin6.sin6_addr);
398     if(rv != 1) {
399       memset(&a, 0, sizeof(a));
400       lua_pushinteger(L, -1);
401       lua_pushfstring(L, "Cannot translate '%s' to IP\n", target);
402       return 2;
403     }
404     else {
405       /* We've IPv6 */
406       a.sin6.sin6_family = AF_INET6;
407       a.sin6.sin6_port = htons(port);
408     }
409   }
410   else {
411     a.sin4.sin_family = family;
412     a.sin4.sin_port = htons(port);
413   }
414
415   while((sbytes = sendto(e->fd, bytes, nbytes, 0, (struct sockaddr *)&a,
416                          family==AF_INET ? sizeof(a.sin4)
417                                          : sizeof(a.sin6))) == -1 &&
418         errno == EINTR);
419   if(sbytes < 0 && errno == EAGAIN) {
420     struct nl_slcl *cl;
421     /* continuation */
422     cl = e->closure;
423     cl->write_sofar = 0;
424     cl->outbuff = bytes;
425     cl->write_goal = nbytes;
426     cl->sendto = 1;
427     e->callback = noit_lua_socket_send_complete;
428     e->mask = EVENTER_WRITE | EVENTER_EXCEPTION;
429     eventer_add(e);
430     return noit_lua_yield(ci, 0);
431   }
432   lua_pushinteger(L, sbytes);
433   if(sbytes < 0) {
434     lua_pushstring(L, strerror(errno));
435     return 2;
436   }
437   return 1;
438 }
439 static int
440 noit_lua_socket_connect(lua_State *L) {
441   noit_lua_check_info_t *ci;
442   eventer_t e, *eptr;
443   const char *target;
444   unsigned short port;
445   int8_t family;
446   int rv;
447   union {
448     struct sockaddr_in sin4;
449     struct sockaddr_in6 sin6;
450   } a;
451
452   ci = get_ci(L);
453   assert(ci);
454
455   eptr = lua_touserdata(L, lua_upvalueindex(1));
456   if(eptr != lua_touserdata(L, 1))
457     luaL_error(L, "must be called as method");
458   e = *eptr;
459   target = lua_tostring(L, 2);
460   if(!target) target = "";
461   port = lua_tointeger(L, 3);
462
463   family = AF_INET;
464   rv = inet_pton(family, target, &a.sin4.sin_addr);
465   if(rv != 1) {
466     family = AF_INET6;
467     rv = inet_pton(family, target, &a.sin6.sin6_addr);
468     if(rv != 1) {
469       memset(&a, 0, sizeof(a));
470       lua_pushinteger(L, -1);
471       lua_pushfstring(L, "Cannot translate '%s' to IP\n", target);
472       return 2;
473     }
474     else {
475       /* We've IPv6 */
476       a.sin6.sin6_family = AF_INET6;
477       a.sin6.sin6_port = htons(port);
478     }
479   }
480   else {
481     a.sin4.sin_family = family;
482     a.sin4.sin_port = htons(port);
483   }
484
485   rv = connect(e->fd, (struct sockaddr *)&a,
486                family==AF_INET ? sizeof(a.sin4) : sizeof(a.sin6));
487   if(rv == 0) {
488     lua_pushinteger(L, 0);
489     return 1;
490   }
491   if(rv == -1 && errno == EINPROGRESS) {
492     /* Need completion */
493     e->callback = noit_lua_socket_connect_complete;
494     e->mask = EVENTER_READ | EVENTER_WRITE | EVENTER_EXCEPTION;
495     eventer_add(e);
496     return noit_lua_yield(ci, 0);
497   }
498   lua_pushinteger(L, -1);
499   lua_pushstring(L, strerror(errno));
500   return 2;
501 }
502 static int
503 noit_lua_ssl_upgrade(eventer_t e, int mask, void *vcl,
504                      struct timeval *now) {
505   noit_lua_check_info_t *ci;
506   struct nl_slcl *cl = vcl;
507   int rv;
508
509   rv = eventer_SSL_connect(e, &mask);
510   if(rv <= 0 && errno == EAGAIN) return mask | EVENTER_EXCEPTION;
511
512   ci = get_ci(cl->L);
513   assert(ci);
514   noit_lua_check_deregister_event(ci, e, 0);
515
516   *(cl->eptr) = eventer_alloc();
517   memcpy(*cl->eptr, e, sizeof(*e));
518   noit_lua_check_register_event(ci, *cl->eptr);
519
520   /* Upgrade completed successfully */
521   lua_pushinteger(cl->L, (rv > 0) ? 0 : -1);
522   noit_lua_resume(ci, 1);
523   return 0;
524 }
525 static int
526 noit_lua_socket_connect_ssl(lua_State *L) {
527   const char *ca, *ciphers, *cert, *key;
528   eventer_ssl_ctx_t *sslctx;
529   noit_lua_check_info_t *ci;
530   eventer_t e, *eptr;
531   struct timeval now;
532   int tmpmask, rv;
533
534   ci = get_ci(L);
535   assert(ci);
536
537   eptr = lua_touserdata(L, lua_upvalueindex(1));
538   if(eptr != lua_touserdata(L, 1))
539     luaL_error(L, "must be called as method");
540   e = *eptr;
541   cert = lua_tostring(L, 2);
542   key = lua_tostring(L, 3);
543   ca = lua_tostring(L, 4);
544   ciphers = lua_tostring(L, 5);
545
546   sslctx = eventer_ssl_ctx_new(SSL_CLIENT, cert, key, ca, ciphers);
547   if(!sslctx) {
548     lua_pushinteger(L, -1);
549     return 1;
550   }
551
552   eventer_ssl_ctx_set_verify(sslctx, eventer_ssl_verify_cert, NULL);
553   EVENTER_ATTACH_SSL(e, sslctx);
554
555   /* We need do the ssl connect and register a completion if
556    * it comes back with an EAGAIN.
557    */
558   tmpmask = EVENTER_READ|EVENTER_WRITE;
559   rv = eventer_SSL_connect(e, &tmpmask);
560   if(rv <= 0 && errno == EAGAIN) {
561     /* Need completion */
562     e->mask = tmpmask | EVENTER_EXCEPTION;
563     e->callback = noit_lua_ssl_upgrade;
564     eventer_add(e);
565     return noit_lua_yield(ci, 0);
566   }
567   lua_pushinteger(L, (rv > 0) ? 0 : -1);
568   return 1;
569 }
570
571 static int
572 noit_lua_socket_do_read(eventer_t e, int *mask, struct nl_slcl *cl,
573                         int *read_complete) {
574   char buff[4096];
575   int len;
576   *read_complete = 0;
577   while((len = e->opset->read(e->fd, buff, sizeof(buff), mask, e)) > 0) {
578     if(cl->read_goal) {
579       int remaining = cl->read_goal - cl->read_sofar;
580       /* copy up to the goal into the inbuff */
581       inbuff_addlstring(cl, buff, MIN(len, remaining));
582       cl->read_sofar += len;
583       if(cl->read_sofar >= cl->read_goal) { /* We're done */
584         lua_pushlstring(cl->L, cl->inbuff, cl->read_goal);
585         *read_complete = 1;
586         cl->read_sofar -= cl->read_goal;
587         cl->inbuff_len = 0;
588         if(cl->read_sofar > 0) {  /* We have to buffer this for next read */
589           inbuff_addlstring(cl, buff + remaining, cl->read_sofar);
590         }
591         break;
592       }
593     }
594     else if(cl->read_terminator) {
595       const char *cp;
596       int remaining = len;
597       cp = strnstrn(cl->read_terminator, strlen(cl->read_terminator),
598                     buff, len);
599       if(cp) remaining = cp - buff + strlen(cl->read_terminator);
600       inbuff_addlstring(cl, buff, MIN(len, remaining));
601       cl->read_sofar += len;
602       if(cp) {
603         lua_pushlstring(cl->L, cl->inbuff, cl->inbuff_len);
604         *read_complete = 1;
605        
606         cl->read_sofar = len - remaining;
607         cl->inbuff_len = 0;
608         if(cl->read_sofar > 0) { /* We have to buffer this for next read */
609           inbuff_addlstring(cl, buff + remaining, cl->read_sofar);
610         }
611         break;
612       }
613     }
614   }
615   if(len == 0 && cl->inbuff_len) {
616     /* EOF */
617     *read_complete = 1;
618     lua_pushlstring(cl->L, cl->inbuff, cl->inbuff_len);
619     cl->inbuff_len = 0;
620   }
621   return len;
622 }
623 static int
624 noit_lua_socket_read_complete(eventer_t e, int mask, void *vcl,
625                               struct timeval *now) {
626   noit_lua_check_info_t *ci;
627   struct nl_slcl *cl = vcl;
628   int len;
629   int args = 0;
630
631   ci = get_ci(cl->L);
632   assert(ci);
633
634   len = noit_lua_socket_do_read(e, &mask, cl, &args);
635   if(len >= 0) {
636     /* We broke out, cause we read enough... */
637   }
638   else if(len == -1 && errno == EAGAIN) {
639     return mask | EVENTER_EXCEPTION;
640   }
641   else {
642     lua_pushnil(cl->L);
643     args = 1;
644   }
645   eventer_remove_fd(e->fd);
646   noit_lua_check_deregister_event(ci, e, 0);
647   *(cl->eptr) = eventer_alloc();
648   memcpy(*cl->eptr, e, sizeof(*e));
649   noit_lua_check_register_event(ci, *cl->eptr);
650   noit_lua_resume(ci, args);
651   return 0;
652 }
653
654 static int
655 noit_lua_socket_read(lua_State *L) {
656   int args, mask, len;
657   struct nl_slcl *cl;
658   noit_lua_check_info_t *ci;
659   eventer_t e, *eptr;
660
661   ci = get_ci(L);
662   assert(ci);
663
664   eptr = lua_touserdata(L, lua_upvalueindex(1));
665   if(eptr != lua_touserdata(L, 1))
666     luaL_error(L, "must be called as method");
667   e = *eptr;
668   cl = e->closure;
669   cl->read_goal = 0;
670   cl->read_terminator = NULL;
671
672   if(lua_isnumber(L, 2)) {
673     cl->read_goal = lua_tointeger(L, 2);
674     if(cl->read_goal <= cl->read_sofar) {
675      i_know_better:
676       /* We have enough, we can service this right here */
677       lua_pushlstring(L, cl->inbuff, cl->read_goal);
678       cl->read_sofar -= cl->read_goal;
679       if(cl->read_sofar) {
680         memmove(cl->inbuff, cl->inbuff + cl->read_goal, cl->read_sofar);
681       }
682       cl->inbuff_len = cl->read_sofar;
683       return 1;
684     }
685   }
686   else {
687     cl->read_terminator = lua_tostring(L, 2);
688     if(cl->read_sofar) {
689       const char *cp;
690       /* Ugh... inernalism */
691       cp = strnstrn(cl->read_terminator, strlen(cl->read_terminator),
692                     cl->inbuff, cl->read_sofar);
693       if(cp) {
694         /* Here we matched... and we _know_ that someone actually wants:
695          * strlen(cl->read_terminator) + cp - cl->inbuff.buffer bytes...
696          * give it to them.
697          */
698         cl->read_goal = strlen(cl->read_terminator) + cp - cl->inbuff;
699         cl->read_terminator = NULL;
700         assert(cl->read_goal <= cl->read_sofar);
701         goto i_know_better;
702       }
703     }
704   }
705
706   len = noit_lua_socket_do_read(e, &mask, cl, &args);
707   if(args == 1) return 1; /* completed read, return result */
708   if(len == -1 && errno == EAGAIN) {
709     /* we need to drop into eventer */
710   }
711   else {
712     lua_pushnil(cl->L);
713     args = 1;
714     return args;
715   }
716
717   eventer_remove_fd(e->fd);
718   e->callback = noit_lua_socket_read_complete;
719   e->mask = mask | EVENTER_EXCEPTION;
720   eventer_add(e);
721   return noit_lua_yield(ci, 0);
722 }
723 static int
724 noit_lua_socket_write_complete(eventer_t e, int mask, void *vcl,
725                                struct timeval *now) {
726   noit_lua_check_info_t *ci;
727   struct nl_slcl *cl = vcl;
728   int rv;
729   int args = 0;
730
731   ci = get_ci(cl->L);
732   assert(ci);
733
734   if(mask & EVENTER_EXCEPTION) {
735     lua_pushinteger(cl->L, -1);
736     args = 1;
737     goto alldone;
738   }
739   while((rv = e->opset->write(e->fd,
740                               cl->outbuff + cl->write_sofar,
741                               MIN(cl->send_size, cl->write_goal),
742                               &mask, e)) > 0) {
743     cl->write_sofar += rv;
744     assert(cl->write_sofar <= cl->write_goal);
745     if(cl->write_sofar == cl->write_goal) break;
746   }
747   if(rv > 0) {
748     lua_pushinteger(cl->L, cl->write_goal);
749     args = 1;
750   }
751   else if(rv == -1 && errno == EAGAIN) {
752     return mask | EVENTER_EXCEPTION;
753   }
754   else {
755     lua_pushinteger(cl->L, -1);
756     args = 1;
757     if(rv == -1) {
758       lua_pushstring(cl->L, strerror(errno));
759       args++;
760     }
761   }
762
763  alldone:
764   eventer_remove_fd(e->fd);
765   noit_lua_check_deregister_event(ci, e, 0);
766   *(cl->eptr) = eventer_alloc();
767   memcpy(*cl->eptr, e, sizeof(*e));
768   noit_lua_check_register_event(ci, *cl->eptr);
769   noit_lua_resume(ci, args);
770   return 0;
771 }
772 static int
773 noit_lua_socket_write(lua_State *L) {
774   int rv, mask;
775   struct nl_slcl *cl;
776   noit_lua_check_info_t *ci;
777   eventer_t e, *eptr;
778
779   ci = get_ci(L);
780   assert(ci);
781
782   eptr = lua_touserdata(L, lua_upvalueindex(1));
783   if(eptr != lua_touserdata(L, 1))
784     luaL_error(L, "must be called as method");
785   e = *eptr;
786   cl = e->closure;
787   cl->write_sofar = 0;
788   cl->outbuff = lua_tolstring(L, 2, &cl->write_goal);
789
790   while((rv = e->opset->write(e->fd,
791                               cl->outbuff + cl->write_sofar,
792                               MIN(cl->send_size, cl->write_goal),
793                               &mask, e)) > 0) {
794     cl->write_sofar += rv;
795     assert(cl->write_sofar <= cl->write_goal);
796     if(cl->write_sofar == cl->write_goal) break;
797   }
798   if(rv > 0) {
799     lua_pushinteger(L, cl->write_goal);
800     return 1;
801   }
802   if(rv == -1 && errno == EAGAIN) {
803     e->callback = noit_lua_socket_write_complete;
804     e->mask = mask | EVENTER_EXCEPTION;
805     eventer_add(e);
806     return noit_lua_yield(ci, 0);
807   }
808   lua_pushinteger(L, -1);
809   return 1;
810 }
811 static int
812 noit_lua_socket_ssl_ctx(lua_State *L) {
813   eventer_t *eptr, e;
814   eventer_ssl_ctx_t **ssl_ctx_holder, *ssl_ctx;
815
816   eptr = lua_touserdata(L, lua_upvalueindex(1));
817   if(eptr != lua_touserdata(L, 1))
818     luaL_error(L, "must be called as method");
819   e = *eptr;
820
821   ssl_ctx = eventer_get_eventer_ssl_ctx(e);
822   if(!ssl_ctx) {
823     lua_pushnil(L);
824     return 1;
825   }
826
827   ssl_ctx_holder = (eventer_ssl_ctx_t **)lua_newuserdata(L, sizeof(ssl_ctx));
828   *ssl_ctx_holder = ssl_ctx;
829   luaL_getmetatable(L, "noit.eventer.ssl_ctx");
830   lua_setmetatable(L, -2);
831   return 1;
832 }
833 static int
834 noit_eventer_index_func(lua_State *L) {
835   int n;
836   const char *k;
837   eventer_t *udata;
838   n = lua_gettop(L); /* number of arguments */
839   assert(n == 2);
840   if(!luaL_checkudata(L, 1, "noit.eventer")) {
841     luaL_error(L, "metatable error, arg1 not a noit.eventer!");
842   }
843   udata = lua_touserdata(L, 1);
844   if(!lua_isstring(L, 2)) {
845     luaL_error(L, "metatable error, arg2 not a string!");
846   }
847   k = lua_tostring(L, 2);
848   switch(*k) {
849     case 'c':
850      LUA_DISPATCH(connect, noit_lua_socket_connect);
851      break;
852     case 'r':
853      LUA_DISPATCH(read, noit_lua_socket_read);
854      LUA_DISPATCH(recv, noit_lua_socket_recv);
855      break;
856     case 's':
857      LUA_DISPATCH(send, noit_lua_socket_send);
858      LUA_DISPATCH(sendto, noit_lua_socket_sendto);
859      LUA_DISPATCH(ssl_upgrade_socket, noit_lua_socket_connect_ssl);
860      LUA_DISPATCH(ssl_ctx, noit_lua_socket_ssl_ctx);
861      break;
862     case 'w':
863      LUA_DISPATCH(write, noit_lua_socket_write);
864      break;
865     default:
866       break;
867   }
868   luaL_error(L, "noit.eventer no such element: %s", k);
869   return 0;
870 }
871
872 static eventer_t *
873 noit_lua_event(lua_State *L, eventer_t e) {
874   eventer_t *addr;
875   addr = (eventer_t *)lua_newuserdata(L, sizeof(e));
876   *addr = e;
877   luaL_getmetatable(L, "noit.eventer");
878   lua_setmetatable(L, -2);
879   return addr;
880 }
881
882 static int
883 noit_ssl_ctx_index_func(lua_State *L) {
884   int n;
885   const char *k;
886   eventer_ssl_ctx_t **udata, *ssl_ctx;
887   n = lua_gettop(L); /* number of arguments */
888   assert(n == 2);
889   if(!luaL_checkudata(L, 1, "noit.eventer.ssl_ctx")) {
890     luaL_error(L, "metatable error, arg1 not a noit.eventer.ssl_ctx!");
891   }
892   udata = lua_touserdata(L, 1);
893   ssl_ctx = *udata;
894   if(!lua_isstring(L, 2)) {
895     luaL_error(L, "metatable error, arg2 not a string!");
896   }
897   k = lua_tostring(L, 2);
898   switch(*k) {
899     case 'e':
900       LUA_RETSTRING(error, eventer_ssl_get_peer_error(ssl_ctx));
901       LUA_RETINTEGER(end_time, eventer_ssl_get_peer_end_time(ssl_ctx));
902       break;
903     case 'i':
904       LUA_RETSTRING(issuer, eventer_ssl_get_peer_issuer(ssl_ctx));
905       break;
906     case 's':
907       LUA_RETSTRING(subject, eventer_ssl_get_peer_subject(ssl_ctx));
908       LUA_RETINTEGER(start_time, eventer_ssl_get_peer_start_time(ssl_ctx));
909       break;
910     default:
911       break;
912   }
913   luaL_error(L, "noit.eventer.ssl_ctx no such element: %s", k);
914   return 0;
915 }
916
917 static int
918 nl_sleep_complete(eventer_t e, int mask, void *vcl, struct timeval *now) {
919   noit_lua_check_info_t *ci;
920   struct nl_slcl *cl = vcl;
921   struct timeval diff;
922   double p_int;
923
924   ci = get_ci(cl->L);
925   assert(ci);
926   noit_lua_check_deregister_event(ci, e, 0);
927
928   sub_timeval(*now, cl->start, &diff);
929   p_int = diff.tv_sec + diff.tv_usec / 1000000.0;
930   lua_pushnumber(cl->L, p_int);
931   free(cl);
932   noit_lua_resume(ci, 1);
933   return 0;
934 }
935
936 static int
937 nl_sleep(lua_State *L) {
938   noit_lua_check_info_t *ci;
939   struct nl_slcl *cl;
940   struct timeval diff;
941   eventer_t e;
942   double p_int;
943
944   ci = get_ci(L);
945   assert(ci);
946
947   p_int = lua_tonumber(L, 1);
948   cl = calloc(1, sizeof(*cl));
949   cl->free = nl_extended_free;
950   cl->L = L;
951   gettimeofday(&cl->start, NULL);
952
953   e = eventer_alloc();
954   e->mask = EVENTER_TIMER;
955   e->callback = nl_sleep_complete;
956   e->closure = cl;
957   memcpy(&e->whence, &cl->start, sizeof(cl->start));
958   diff.tv_sec = floor(p_int);
959   diff.tv_usec = (p_int - floor(p_int)) * 1000000;
960   add_timeval(e->whence, diff, &e->whence);
961   noit_lua_check_register_event(ci, e);
962   eventer_add(e);
963   return noit_lua_yield(ci, 0);
964 }
965
966 static int
967 nl_log(lua_State *L) {
968   int i, n;
969   const char *log_dest, *message;
970   noit_log_stream_t ls;
971
972   if(lua_gettop(L) < 2) luaL_error(L, "bad call to noit.log");
973
974   log_dest = lua_tostring(L, 1);
975   ls = noit_log_stream_find(log_dest);
976   if(!ls) {
977     noitL(noit_stderr, "Cannot find log stream: '%s'\n", log_dest);
978     return 0;
979   }
980
981   n = lua_gettop(L);
982   lua_pushstring(L, "string");
983   lua_gettable(L, LUA_GLOBALSINDEX);
984   lua_pushstring(L, "format");
985   lua_gettable(L, -1);
986   for(i=2;i<=n;i++)
987     lua_pushvalue(L, i);
988   lua_call(L, n-1, 1);
989   message = lua_tostring(L, -1);
990   noitL(ls, "%s", message);
991   lua_pop(L, 1); /* formatted string */
992   lua_pop(L, 1); /* "string" table */
993   return 0;
994 }
995 static int
996 nl_crc32(lua_State *L) {
997   size_t inlen;
998   const char *input;
999   uLong start = 0, inputidx = 1;
1000   if(lua_isnil(L,1)) start = crc32(0, NULL, 0);
1001   if(lua_gettop(L) == 2) {
1002     start = lua_tointeger(L, 2);
1003     inputidx = 2;
1004   }
1005   input = lua_tolstring(L, inputidx, &inlen);
1006   lua_pushnumber(L, (double)crc32(start, (Bytef *)input, inlen));
1007   return 1;
1008 }
1009 static int
1010 nl_base32_decode(lua_State *L) {
1011   size_t inlen, decoded_len;
1012   const char *message;
1013   unsigned char *decoded;
1014
1015   if(lua_gettop(L) != 1) luaL_error(L, "bad call to noit.decode");
1016
1017   message = lua_tolstring(L, 1, &inlen);
1018   decoded = malloc(MAX(1,inlen));
1019   if(!decoded) luaL_error(L, "out-of-memory");
1020   decoded_len = noit_b32_decode(message, inlen, decoded, MAX(1,inlen));
1021   lua_pushlstring(L, (char *)decoded, decoded_len);
1022   return 1;
1023 }
1024 static int
1025 nl_base32_encode(lua_State *L) {
1026   size_t inlen, encoded_len;
1027   const unsigned char *message;
1028   char *encoded;
1029
1030   if(lua_gettop(L) != 1) luaL_error(L, "bad call to noit.encode");
1031
1032   message = (const unsigned char *)lua_tolstring(L, 1, &inlen);
1033   encoded_len = (((inlen + 7) / 5) * 8) + 1;
1034   encoded = malloc(encoded_len);
1035   if(!encoded) luaL_error(L, "out-of-memory");
1036   encoded_len = noit_b32_encode(message, inlen, encoded, encoded_len);
1037   lua_pushlstring(L, (char *)encoded, encoded_len);
1038   return 1;
1039 }
1040 static int
1041 nl_base64_decode(lua_State *L) {
1042   size_t inlen, decoded_len;
1043   const char *message;
1044   unsigned char *decoded;
1045
1046   if(lua_gettop(L) != 1) luaL_error(L, "bad call to noit.decode");
1047
1048   message = lua_tolstring(L, 1, &inlen);
1049   decoded = malloc(MAX(1,inlen));
1050   if(!decoded) luaL_error(L, "out-of-memory");
1051   decoded_len = noit_b64_decode(message, inlen, decoded, MAX(1,inlen));
1052   lua_pushlstring(L, (char *)decoded, decoded_len);
1053   return 1;
1054 }
1055 static int
1056 nl_base64_encode(lua_State *L) {
1057   size_t inlen, encoded_len;
1058   const unsigned char *message;
1059   char *encoded;
1060
1061   if(lua_gettop(L) != 1) luaL_error(L, "bad call to noit.encode");
1062
1063   message = (const unsigned char *)lua_tolstring(L, 1, &inlen);
1064   encoded_len = (((inlen + 2) / 3) * 4) + 1;
1065   encoded = malloc(encoded_len);
1066   if(!encoded) luaL_error(L, "out-of-memory");
1067   encoded_len = noit_b64_encode(message, inlen, encoded, encoded_len);
1068   lua_pushlstring(L, (char *)encoded, encoded_len);
1069   return 1;
1070 }
1071 static const char _hexchars[16] =
1072   {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
1073 static int
1074 nl_md5_hex(lua_State *L) {
1075   int i;
1076   MD5_CTX ctx;
1077   size_t inlen;
1078   const char *in;
1079   unsigned char md5[MD5_DIGEST_LENGTH];
1080   char md5_hex[MD5_DIGEST_LENGTH * 2 + 1];
1081
1082   if(lua_gettop(L) != 1) luaL_error(L, "bad call to noit.md5_hex");
1083   MD5_Init(&ctx);
1084   in = lua_tolstring(L, 1, &inlen);
1085   MD5_Update(&ctx, (const void *)in, (unsigned long)inlen);
1086   MD5_Final(md5, &ctx);
1087   for(i=0;i<MD5_DIGEST_LENGTH;i++) {
1088     md5_hex[i*2] = _hexchars[(md5[i] >> 4) & 0xf];
1089     md5_hex[i*2+1] = _hexchars[md5[i] & 0xf];
1090   }
1091   md5_hex[i*2] = '\0';
1092   lua_pushstring(L, md5_hex);
1093   return 1;
1094 }
1095 static int
1096 nl_gettimeofday(lua_State *L) {
1097   struct timeval now;
1098   gettimeofday(&now, NULL);
1099   lua_pushinteger(L, now.tv_sec);
1100   lua_pushinteger(L, now.tv_usec);
1101   return 2;
1102 }
1103 static int
1104 nl_socket_internal(lua_State *L, int family, int proto) {
1105   struct nl_slcl *cl;
1106   noit_lua_check_info_t *ci;
1107   socklen_t optlen;
1108   int fd;
1109   eventer_t e;
1110
1111   fd = socket(family, proto, 0);
1112   if(fd < 0) {
1113     lua_pushnil(L);
1114     return 1;
1115   }
1116   if(eventer_set_fd_nonblocking(fd)) {
1117     close(fd);
1118     lua_pushnil(L);
1119     return 1;
1120   }
1121
1122   ci = get_ci(L);
1123   assert(ci);
1124
1125   cl = calloc(1, sizeof(*cl));
1126   cl->free = nl_extended_free;
1127   cl->L = L;
1128
1129   optlen = sizeof(cl->send_size);
1130   if(getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &cl->send_size, &optlen) != 0)
1131     cl->send_size = 4096;
1132
1133   e = eventer_alloc();
1134   e->fd = fd;
1135   e->mask = EVENTER_EXCEPTION;
1136   e->callback = NULL;
1137   e->closure = cl;
1138   cl->eptr = noit_lua_event(L, e);
1139
1140   noit_lua_check_register_event(ci, e);
1141   return 1;
1142 }
1143 static int
1144 nl_socket(lua_State *L) {
1145   int n = lua_gettop(L);
1146   uint8_t family = AF_INET;
1147   union {
1148     struct in_addr addr4;
1149     struct in6_addr addr6;
1150   } a;
1151
1152   if(n > 0 && lua_isstring(L,1)) {
1153     const char *fam = lua_tostring(L,1);
1154     if(!fam) fam = "";
1155     if(!strcmp(fam, "inet")) family = AF_INET;
1156     else if(!strcmp(fam, "inet6")) family = AF_INET6;
1157     else if(inet_pton(AF_INET, fam, &a) == 1) family = AF_INET;
1158     else if(inet_pton(AF_INET6, fam, &a) == 1) family = AF_INET6;
1159     else luaL_error(L, "noit.socket family for %s unknown", fam);
1160   }
1161
1162   if(n <= 1) return nl_socket_internal(L, family, SOCK_STREAM);
1163   if(n == 2 && lua_isstring(L,2)) {
1164     const char *type = lua_tostring(L,2);
1165     if(!strcmp(type, "tcp"))
1166       return nl_socket_internal(L, family, SOCK_STREAM);
1167     else if(!strcmp(type, "udp"))
1168       return nl_socket_internal(L, family, SOCK_DGRAM);
1169   }
1170   luaL_error(L, "noit.socket called with invalid arguments");
1171   return 0;
1172 }
1173
1174 struct gunzip_crutch {
1175   z_stream *stream;
1176   void *scratch_buffer;
1177 };
1178 static int
1179 nl_gunzip_deflate(lua_State *L) {
1180   struct gunzip_crutch *crutch;
1181   const char *input;
1182   size_t inlen;
1183   z_stream *stream;
1184   Bytef *data = NULL;
1185   uLong outlen = 0;
1186   int limit = 1024*1024;
1187   int err, n = lua_gettop(L);
1188
1189   if(n < 1 || n > 2) {
1190     lua_pushnil(L);
1191     return 1;
1192   }
1193
1194   crutch = lua_touserdata(L, lua_upvalueindex(1));
1195   stream = crutch->stream;
1196
1197   input = lua_tolstring(L, 1, &inlen);
1198   if(!input) {
1199     lua_pushnil(L);
1200     return 1;
1201   }
1202   if(n == 2)
1203     limit = lua_tointeger(L, 2);
1204
1205   stream->next_in = (Bytef *)input;
1206   stream->avail_in = inlen;
1207   while(1) {
1208     err = inflate(stream, Z_FULL_FLUSH);
1209     if(err == Z_OK || err == Z_STREAM_END) {
1210       /* got some data */
1211       int size_read = DEFLATE_CHUNK_SIZE - stream->avail_out;
1212       uLong newoutlen = outlen + size_read;
1213       if(newoutlen > limit) {
1214         err = Z_MEM_ERROR;
1215         break;
1216       }
1217       if(newoutlen > outlen) {
1218         Bytef *newdata;
1219         if(data) newdata = realloc(data, newoutlen);
1220         else newdata = malloc(newoutlen);
1221         if(!newdata) {
1222           err = Z_MEM_ERROR;
1223           break;
1224         }
1225         data = newdata;
1226         memcpy(data + outlen, stream->next_out - size_read, size_read);
1227         outlen += size_read;
1228         stream->next_out -= size_read;
1229         stream->avail_out += size_read;
1230       }
1231       if(err == Z_STREAM_END) {
1232         /* Good to go */
1233         break;
1234       }
1235     }
1236     else break;
1237     if(stream->avail_in == 0) break;
1238   }
1239   if(err == Z_OK || err == Z_STREAM_END) {
1240     if(outlen > 0) lua_pushlstring(L, (char *)data, outlen);
1241     else lua_pushstring(L, "");
1242     if(data) free(data);
1243     return 1;
1244   }
1245   if(data) free(data);
1246   switch(err) {
1247     case Z_NEED_DICT: luaL_error(L, "zlib: dictionary error"); break;
1248     case Z_STREAM_ERROR: luaL_error(L, "zlib: stream error"); break;
1249     case Z_DATA_ERROR: luaL_error(L, "zlib: data error"); break;
1250     case Z_MEM_ERROR: luaL_error(L, "zlib: out-of-memory"); break;
1251     case Z_BUF_ERROR: luaL_error(L, "zlib: buffer error"); break;
1252     case Z_VERSION_ERROR: luaL_error(L, "zlib: version mismatch"); break;
1253     case Z_ERRNO: luaL_error(L, strerror(errno)); break;
1254   }
1255   lua_pushnil(L);
1256   return 1;
1257 }
1258 static int
1259 nl_gunzip(lua_State *L) {
1260   struct gunzip_crutch *crutch;
1261   z_stream *stream;
1262  
1263   crutch = (struct gunzip_crutch *)lua_newuserdata(L, sizeof(*crutch));
1264   crutch->stream = malloc(sizeof(*stream));
1265   memset(crutch->stream, 0, sizeof(*crutch->stream));
1266   luaL_getmetatable(L, "noit.gunzip");
1267   lua_setmetatable(L, -2);
1268
1269   crutch->stream->next_in = NULL;
1270   crutch->stream->avail_in = 0;
1271   crutch->scratch_buffer =
1272     crutch->stream->next_out = malloc(DEFLATE_CHUNK_SIZE);
1273   crutch->stream->avail_out = crutch->stream->next_out ? DEFLATE_CHUNK_SIZE : 0;
1274   inflateInit2(crutch->stream, MAX_WBITS+32);
1275
1276   lua_pushcclosure(L, nl_gunzip_deflate, 1);
1277   return 1;
1278 }
1279 static int
1280 noit_lua_gunzip_gc(lua_State *L) {
1281   struct gunzip_crutch *crutch;
1282   crutch = (struct gunzip_crutch *)lua_touserdata(L,1);
1283   if(crutch->scratch_buffer) free(crutch->scratch_buffer);
1284   inflateEnd(crutch->stream);
1285   return 0;
1286 }
1287
1288 struct pcre_global_info {
1289   pcre *re;
1290   int offset;
1291 };
1292 static int
1293 noit_lua_pcre_match(lua_State *L) {
1294   const char *subject;
1295   struct pcre_global_info *pgi;
1296   int i, cnt, ovector[30];
1297   size_t inlen;
1298   struct pcre_extra e = { 0 };
1299
1300   pgi = (struct pcre_global_info *)lua_touserdata(L, lua_upvalueindex(1));
1301   subject = lua_tolstring(L,1,&inlen);
1302   if(!subject) {
1303     lua_pushboolean(L,0);
1304     return 1;
1305   }
1306   if(lua_gettop(L) > 1) {
1307     if(!lua_istable(L, 2)) {
1308       noitL(noit_error, "pcre match called with second argument that is not a table\n");
1309     }
1310     else {
1311       lua_pushstring(L, "limit");
1312       lua_gettable(L, -2);
1313       if(lua_isnumber(L, -1)) {
1314         e.flags |= PCRE_EXTRA_MATCH_LIMIT;
1315         e.match_limit = (int)lua_tonumber(L, -1);
1316       }
1317       lua_pop(L, 1);
1318       lua_pushstring(L, "limit_recurse");
1319       lua_gettable(L, -2);
1320       if(lua_isnumber(L, -1)) {
1321         e.flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
1322         e.match_limit_recursion = (int)lua_tonumber(L, -1);
1323       }
1324       lua_pop(L, 1);
1325     }
1326   }
1327   if (pgi->offset >= inlen) {
1328     lua_pushboolean(L,0);
1329     return 1;
1330   }
1331   cnt = pcre_exec(pgi->re, &e, subject + pgi->offset,
1332                   inlen - pgi->offset, 0, 0,
1333                   ovector, sizeof(ovector)/sizeof(*ovector));
1334   if(cnt <= 0) {
1335     lua_pushboolean(L,0);
1336     return 1;
1337   }
1338   lua_pushboolean(L,1);
1339   for(i = 0; i < cnt; i++) {
1340     int start = ovector[i*2];
1341     int end = ovector[i*2+1];
1342     lua_pushlstring(L, subject+pgi->offset+start, end-start);
1343   }
1344   pgi->offset += ovector[1]; /* endof the overall match */
1345   return cnt+1;
1346 }
1347 static int
1348 nl_pcre(lua_State *L) {
1349   pcre *re;
1350   struct pcre_global_info *pgi;
1351   const char *expr;
1352   const char *errstr;
1353   int erroff;
1354
1355   expr = lua_tostring(L,1);
1356   re = pcre_compile(expr, 0, &errstr, &erroff, NULL);
1357   if(!re) {
1358     lua_pushnil(L);
1359     lua_pushstring(L, errstr);
1360     lua_pushinteger(L, erroff);
1361     return 3;
1362   }
1363   pgi = (struct pcre_global_info *)lua_newuserdata(L, sizeof(*pgi));
1364   pgi->re = re;
1365   pgi->offset = 0;
1366   luaL_getmetatable(L, "noit.pcre");
1367   lua_setmetatable(L, -2);
1368   lua_pushcclosure(L, noit_lua_pcre_match, 1);
1369   return 1;
1370 }
1371 static int
1372 noit_lua_pcre_gc(lua_State *L) {
1373   struct pcre_global_info *pgi;
1374   pgi = (struct pcre_global_info *)lua_touserdata(L,1);
1375   pcre_free(pgi->re);
1376   return 0;
1377 }
1378
1379 static int
1380 nl_conf_get_string(lua_State *L) {
1381   char *val;
1382   const char *path = lua_tostring(L,1);
1383   if(path &&
1384      noit_conf_get_string(NULL, path, &val)) {
1385     lua_pushstring(L,val);
1386     free(val);
1387   }
1388   else lua_pushnil(L);
1389   return 1;
1390 }
1391 static int
1392 nl_conf_get_integer(lua_State *L) {
1393   int val;
1394   const char *path = lua_tostring(L,1);
1395   if(path &&
1396      noit_conf_get_int(NULL, path, &val)) {
1397     lua_pushinteger(L,val);
1398   }
1399   else lua_pushnil(L);
1400   return 1;
1401 }
1402 static int
1403 nl_conf_get_boolean(lua_State *L) {
1404   noit_boolean val;
1405   const char *path = lua_tostring(L,1);
1406   if(path &&
1407      noit_conf_get_boolean(NULL, path, &val)) {
1408     lua_pushboolean(L,val);
1409   }
1410   else lua_pushnil(L);
1411   return 1;
1412 }
1413 static int
1414 nl_conf_get_float(lua_State *L) {
1415   float val;
1416   const char *path = lua_tostring(L,1);
1417   if(path &&
1418      noit_conf_get_float(NULL, path, &val)) {
1419     lua_pushnumber(L,val);
1420   }
1421   else lua_pushnil(L);
1422   return 1;
1423 }
1424 struct xpath_iter {
1425   xmlXPathContextPtr ctxt;
1426   xmlXPathObjectPtr pobj;
1427   int cnt;
1428   int idx;
1429 };
1430 static int
1431 noit_lua_xpath_iter(lua_State *L) {
1432   struct xpath_iter *xpi;
1433   xpi = lua_touserdata(L, lua_upvalueindex(1));
1434   if(xpi->pobj) {
1435     if(xpi->idx < xpi->cnt) {
1436       xmlNodePtr node, *nodeptr;
1437       node = xmlXPathNodeSetItem(xpi->pobj->nodesetval, xpi->idx);
1438       xpi->idx++;
1439       nodeptr = (xmlNodePtr *)lua_newuserdata(L, sizeof(node));
1440       *nodeptr = node;
1441       luaL_getmetatable(L, "noit.xmlnode");
1442       lua_setmetatable(L, -2);
1443       return 1;
1444     }
1445   }
1446   return 0;
1447 }
1448 static int
1449 noit_lua_xpath(lua_State *L) {
1450   int n;
1451   const char *xpathexpr;
1452   xmlDocPtr *docptr, doc;
1453   xmlNodePtr *nodeptr = NULL;
1454   xmlXPathContextPtr ctxt;
1455   struct xpath_iter *xpi;
1456
1457   n = lua_gettop(L);
1458   /* the first arg is implicitly self (it's a method) */
1459   docptr = lua_touserdata(L, lua_upvalueindex(1));
1460   if(docptr != lua_touserdata(L, 1))
1461     luaL_error(L, "must be called as method");
1462   if(n < 2 || n > 3) luaL_error(L, "expects 1 or 2 arguments, got %d", n);
1463   doc = *docptr;
1464   xpathexpr = lua_tostring(L, 2);
1465   if(!xpathexpr) luaL_error(L, "no xpath expression provided");
1466   ctxt = xmlXPathNewContext(doc);
1467   if(n == 3) {
1468     nodeptr = lua_touserdata(L, 3);
1469     if(nodeptr) ctxt->node = *nodeptr;
1470   }
1471   if(!ctxt) luaL_error(L, "invalid xpath");
1472
1473   xpi = (struct xpath_iter *)lua_newuserdata(L, sizeof(*xpi));
1474   xpi->ctxt = ctxt;
1475   xpi->pobj = xmlXPathEval((xmlChar *)xpathexpr, xpi->ctxt);
1476   if(!xpi->pobj || xpi->pobj->type != XPATH_NODESET)
1477     xpi->cnt = 0;
1478   else
1479     xpi->cnt = xmlXPathNodeSetGetLength(xpi->pobj->nodesetval);
1480   xpi->idx = 0;
1481   luaL_getmetatable(L, "noit.xpathiter");
1482   lua_setmetatable(L, -2);
1483   lua_pushcclosure(L, noit_lua_xpath_iter, 1);
1484   return 1;
1485 }
1486 static int
1487 noit_lua_xmlnode_name(lua_State *L) {
1488   xmlNodePtr *nodeptr;
1489   /* the first arg is implicitly self (it's a method) */
1490   nodeptr = lua_touserdata(L, lua_upvalueindex(1));
1491   if(nodeptr != lua_touserdata(L, 1))
1492     luaL_error(L, "must be called as method");
1493   if(lua_gettop(L) == 1) {
1494     xmlChar *v;
1495     v = (xmlChar *)(*nodeptr)->name;
1496     if(v) {
1497       lua_pushstring(L, (const char *)v);
1498     }
1499     else lua_pushnil(L);
1500     return 1;
1501   }
1502   luaL_error(L,"must be called with no arguments");
1503   return 0;
1504 }
1505 static int
1506 noit_lua_xmlnode_attr(lua_State *L) {
1507   xmlNodePtr *nodeptr;
1508   /* the first arg is implicitly self (it's a method) */
1509   nodeptr = lua_touserdata(L, lua_upvalueindex(1));
1510   if(nodeptr != lua_touserdata(L, 1))
1511     luaL_error(L, "must be called as method");
1512   if(lua_gettop(L) == 3 && lua_isstring(L,2)) {
1513     const char *attr = lua_tostring(L,2);
1514     if(lua_isnil(L,3))
1515       xmlSetProp(*nodeptr, (xmlChar *)attr, NULL);
1516     else
1517       xmlSetProp(*nodeptr, (xmlChar *)attr, (xmlChar *)lua_tostring(L,3));
1518     return 0;
1519   }
1520   if(lua_gettop(L) == 2 && lua_isstring(L,2)) {
1521     xmlChar *v;
1522     const char *attr = lua_tostring(L,2);
1523     v = xmlGetProp(*nodeptr, (xmlChar *)attr);
1524     if(v) {
1525       lua_pushstring(L, (const char *)v);
1526       xmlFree(v);
1527     }
1528     else lua_pushnil(L);
1529     return 1;
1530   }
1531   luaL_error(L,"must be called with one argument");
1532   return 0;
1533 }
1534 static int
1535 noit_lua_xmlnode_contents(lua_State *L) {
1536   xmlNodePtr *nodeptr;
1537   /* the first arg is implicitly self (it's a method) */
1538   nodeptr = lua_touserdata(L, lua_upvalueindex(1));
1539   if(nodeptr != lua_touserdata(L, 1))
1540     luaL_error(L, "must be called as method");
1541   if(lua_gettop(L) == 2 && lua_isstring(L,2)) {
1542     const char *data = lua_tostring(L,2);
1543     xmlChar *enc = xmlEncodeEntitiesReentrant((*nodeptr)->doc, (xmlChar *)data);
1544     xmlNodeSetContent(*nodeptr, (xmlChar *)enc);
1545     return 0;
1546   }
1547   if(lua_gettop(L) == 1) {
1548     xmlChar *v;
1549     v = xmlNodeGetContent(*nodeptr);
1550     if(v) {
1551       lua_pushstring(L, (const char *)v);
1552       xmlFree(v);
1553     }
1554     else lua_pushnil(L);
1555     return 1;
1556   }
1557   luaL_error(L,"must be called with no arguments");
1558   return 0;
1559 }
1560 static int
1561 noit_lua_xmlnode_next(lua_State *L) {
1562   xmlNodePtr *nodeptr;
1563   nodeptr = lua_touserdata(L, lua_upvalueindex(1));
1564   if(*nodeptr) {
1565     xmlNodePtr *newnodeptr;
1566     newnodeptr = (xmlNodePtr *)lua_newuserdata(L, sizeof(*nodeptr));
1567     *newnodeptr = *nodeptr;
1568     luaL_getmetatable(L, "noit.xmlnode");
1569     lua_setmetatable(L, -2);
1570     *nodeptr = (*nodeptr)->next;
1571     return 1;
1572   }
1573   return 0;
1574 }
1575 static int
1576 noit_lua_xmlnode_addchild(lua_State *L) {
1577   xmlNodePtr *nodeptr;
1578   nodeptr = lua_touserdata(L, lua_upvalueindex(1));
1579   if(nodeptr != lua_touserdata(L, 1))
1580     luaL_error(L, "must be called as method");
1581   if(lua_gettop(L) == 2 && lua_isstring(L,2)) {
1582     xmlNodePtr *newnodeptr;
1583     newnodeptr = (xmlNodePtr *)lua_newuserdata(L, sizeof(*nodeptr));
1584     *newnodeptr = xmlNewChild(*nodeptr, NULL,
1585                               (xmlChar *)lua_tostring(L,2), NULL);
1586     luaL_getmetatable(L, "noit.xmlnode");
1587     lua_setmetatable(L, -2);
1588     return 1;
1589   }
1590   luaL_error(L,"must be called with one argument");
1591   return 0;
1592 }
1593 static int
1594 noit_lua_xmlnode_children(lua_State *L) {
1595   xmlNodePtr *nodeptr, node, cnode;
1596   /* the first arg is implicitly self (it's a method) */
1597   nodeptr = lua_touserdata(L, lua_upvalueindex(1));
1598   if(nodeptr != lua_touserdata(L, 1))
1599     luaL_error(L, "must be called as method");
1600   node = *nodeptr;
1601   cnode = node->children;
1602   nodeptr = lua_newuserdata(L, sizeof(cnode));
1603   *nodeptr = cnode;
1604   luaL_getmetatable(L, "noit.xmlnode");
1605   lua_setmetatable(L, -2);
1606   lua_pushcclosure(L, noit_lua_xmlnode_next, 1);
1607   return 1;
1608 }
1609 static int
1610 noit_lua_xml_tostring(lua_State *L) {
1611   int n;
1612   xmlDocPtr *docptr;
1613   char *xmlstring;
1614   n = lua_gettop(L);
1615   /* the first arg is implicitly self (it's a method) */
1616   docptr = lua_touserdata(L, lua_upvalueindex(1));
1617   if(docptr != lua_touserdata(L, 1))
1618     luaL_error(L, "must be called as method");
1619   if(n != 1) luaL_error(L, "expects no arguments, got %d", n - 1);
1620   xmlstring = noit_xmlSaveToBuffer(*docptr);
1621   lua_pushstring(L, xmlstring);
1622   free(xmlstring);
1623   return 1;
1624 }
1625 static int
1626 noit_lua_xml_docroot(lua_State *L) {
1627   int n;
1628   xmlDocPtr *docptr;
1629   xmlNodePtr *ptr;
1630   n = lua_gettop(L);
1631   /* the first arg is implicitly self (it's a method) */
1632   docptr = lua_touserdata(L, lua_upvalueindex(1));
1633   if(docptr != lua_touserdata(L, 1))
1634     luaL_error(L, "must be called as method");
1635   if(n != 1) luaL_error(L, "expects no arguments, got %d", n - 1);
1636   ptr = lua_newuserdata(L, sizeof(*ptr));
1637   *ptr = xmlDocGetRootElement(*docptr);
1638   luaL_getmetatable(L, "noit.xmlnode");
1639   lua_setmetatable(L, -2);
1640   return 1;
1641 }
1642 static int
1643 noit_lua_xpathiter_gc(lua_State *L) {
1644   struct xpath_iter *xpi;
1645   xpi = lua_touserdata(L, 1);
1646   xmlXPathFreeContext(xpi->ctxt);
1647   if(xpi->pobj) xmlXPathFreeObject(xpi->pobj);
1648   return 0;
1649 }
1650 static int
1651 noit_xmlnode_index_func(lua_State *L) {
1652   int n;
1653   const char *k;
1654   xmlNodePtr *udata;
1655   n = lua_gettop(L); /* number of arguments */
1656   assert(n == 2);
1657   if(!luaL_checkudata(L, 1, "noit.xmlnode")) {
1658     luaL_error(L, "metatable error, arg1 not a noit.xmlnode!");
1659   }
1660   udata = lua_touserdata(L, 1);
1661   if(!lua_isstring(L, 2)) {
1662     luaL_error(L, "metatable error, arg2 not a string!");
1663   }
1664   k = lua_tostring(L, 2);
1665   switch(*k) {
1666     case 'a':
1667       LUA_DISPATCH(attr, noit_lua_xmlnode_attr);
1668       LUA_DISPATCH(attribute, noit_lua_xmlnode_attr);
1669       LUA_DISPATCH(addchild, noit_lua_xmlnode_addchild);
1670       break;
1671     case 'c':
1672       LUA_DISPATCH(children, noit_lua_xmlnode_children);
1673       LUA_DISPATCH(contents, noit_lua_xmlnode_contents);
1674       break;
1675     case 'n':
1676       LUA_DISPATCH(name, noit_lua_xmlnode_name);
1677       break;
1678     default:
1679       break;
1680   }
1681   luaL_error(L, "noit.xmlnode no such element: %s", k);
1682   return 0;
1683 }
1684 static int
1685 nl_parsexml(lua_State *L) {
1686   xmlDocPtr *docptr, doc;
1687   const char *in;
1688   size_t inlen;
1689
1690   if(lua_gettop(L) != 1) luaL_error(L, "parsexml requires one argument");
1691
1692   in = lua_tolstring(L, 1, &inlen);
1693   doc = xmlParseMemory(in, inlen);
1694   if(!doc) {
1695     lua_pushnil(L);
1696     return 1;
1697   }
1698
1699   docptr = (xmlDocPtr *)lua_newuserdata(L, sizeof(doc));
1700   *docptr = doc;
1701   luaL_getmetatable(L, "noit.xmldoc");
1702   lua_setmetatable(L, -2);
1703   return 1;
1704 }
1705 static int
1706 noit_lua_xmldoc_gc(lua_State *L) {
1707   xmlDocPtr *holder;
1708   holder = (xmlDocPtr *)lua_touserdata(L,1);
1709   xmlFreeDoc(*holder);
1710   return 0;
1711 }
1712 static int
1713 noit_xmldoc_index_func(lua_State *L) {
1714   int n;
1715   const char *k;
1716   xmlDocPtr *udata;
1717   n = lua_gettop(L); /* number of arguments */
1718   assert(n == 2);
1719   if(!luaL_checkudata(L, 1, "noit.xmldoc")) {
1720     luaL_error(L, "metatable error, arg1 not a noit.xmldoc!");
1721   }
1722   udata = lua_touserdata(L, 1);
1723   if(!lua_isstring(L, 2)) {
1724     luaL_error(L, "metatable error, arg2 not a string!");
1725   }
1726   k = lua_tostring(L, 2);
1727   switch(*k) {
1728     case 'r':
1729      LUA_DISPATCH(root, noit_lua_xml_docroot);
1730      break;
1731     case 't':
1732      LUA_DISPATCH(tostring, noit_lua_xml_tostring);
1733      break;
1734     case 'x':
1735      LUA_DISPATCH(xpath, noit_lua_xpath);
1736      break;
1737     default:
1738      break;
1739   }
1740   luaL_error(L, "noit.xmldoc no such element: %s", k);
1741   return 0;
1742 }
1743
1744 static int
1745 noit_lua_json_tostring(lua_State *L) {
1746   int n;
1747   json_crutch **docptr;
1748   const char *jsonstring;
1749   n = lua_gettop(L);
1750   /* the first arg is implicitly self (it's a method) */
1751   docptr = lua_touserdata(L, lua_upvalueindex(1));
1752   if(docptr != lua_touserdata(L, 1))
1753     luaL_error(L, "must be called as method");
1754   if(n != 1) luaL_error(L, "expects no arguments, got %d", n - 1);
1755   jsonstring = json_object_to_json_string((*docptr)->root);
1756   lua_pushstring(L, jsonstring);
1757   /* jsonstring is freed with the root object later */
1758   return 1;
1759 }
1760 static int
1761 noit_json_object_to_luatype(lua_State *L, struct json_object *o) {
1762   if(!o) {
1763     lua_pushnil(L);
1764     return 1;
1765   }
1766   switch(json_object_get_type(o)) {
1767     case json_type_null: lua_pushnil(L); break;
1768     case json_type_object:
1769     {
1770       struct lh_table *lh;
1771       struct lh_entry *el;
1772       lh = json_object_get_object(o);
1773       lua_createtable(L, 0, lh->count);
1774       lh_foreach(lh, el) {
1775         noit_json_object_to_luatype(L, (struct json_object *)el->v);
1776         lua_setfield(L, -2, el->k);
1777       }
1778       break;
1779     }
1780     case json_type_string: lua_pushstring(L, json_object_get_string(o)); break;
1781     case json_type_boolean: lua_pushboolean(L, json_object_get_boolean(o)); break;
1782     case json_type_double: lua_pushnumber(L, json_object_get_double(o)); break;
1783     case json_type_int:
1784     {
1785       int64_t i64;
1786       uint64_t u64;
1787       char istr[64];
1788       switch(json_object_get_int_overflow(o)) {
1789         case json_overflow_int:
1790           lua_pushnumber(L, json_object_get_int(o)); break;
1791         case json_overflow_int64:
1792           i64 = json_object_get_int64(o);
1793           snprintf(istr, sizeof(istr), "%lld", (long long int)i64);
1794           lua_pushstring(L, istr);
1795           break;
1796         case json_overflow_uint64:
1797           u64 = json_object_get_uint64(o);
1798           snprintf(istr, sizeof(istr), "%llu", (long long unsigned int)u64);
1799           lua_pushstring(L, istr);
1800           break;
1801       }
1802       break;
1803     }
1804     case json_type_array:
1805     {
1806       int i, cnt;
1807       struct array_list *al;
1808       al = json_object_get_array(o);
1809       cnt = al ? array_list_length(al) : 0;
1810       lua_createtable(L, 0, cnt);
1811       for(i=0;i<cnt;i++) {
1812         noit_json_object_to_luatype(L, (struct json_object *)array_list_get_idx(al, i));
1813         lua_rawseti(L, -2, i);
1814       }
1815       break;
1816     }
1817   }
1818   return 1;
1819 }
1820 static int
1821 noit_lua_json_document(lua_State *L) {
1822   int n;
1823   json_crutch **docptr;
1824   n = lua_gettop(L);
1825   /* the first arg is implicitly self (it's a method) */
1826   docptr = lua_touserdata(L, lua_upvalueindex(1));
1827   if(docptr != lua_touserdata(L, 1))
1828     luaL_error(L, "must be called as method");
1829   if(n != 1) luaL_error(L, "expects no arguments, got %d", n - 1);
1830   return noit_json_object_to_luatype(L, (*docptr)->root);
1831 }
1832 static int
1833 nl_parsejson(lua_State *L) {
1834   json_crutch **docptr, *doc;
1835   const char *in;
1836   size_t inlen;
1837
1838   if(lua_gettop(L) != 1) luaL_error(L, "parsejson requires one argument");
1839
1840   in = lua_tolstring(L, 1, &inlen);
1841   doc = calloc(1, sizeof(*doc));
1842   doc->tok = json_tokener_new();
1843   doc->root = json_tokener_parse_ex(doc->tok, in, inlen);
1844   if(is_error(doc->root)) {
1845     json_tokener_free(doc->tok);
1846     if(doc->root) json_object_put(doc->root);
1847     free(doc);
1848     lua_pushnil(L);
1849     return 1;
1850   }
1851
1852   docptr = (json_crutch **)lua_newuserdata(L, sizeof(doc));
1853   *docptr = doc;
1854   luaL_getmetatable(L, "noit.json");
1855   lua_setmetatable(L, -2);
1856   return 1;
1857 }
1858 static int
1859 noit_lua_json_gc(lua_State *L) {
1860   json_crutch **json;
1861   json = (json_crutch **)lua_touserdata(L,1);
1862   if((*json)->tok) json_tokener_free((*json)->tok);
1863   if((*json)->root) json_object_put((*json)->root);
1864   free(*json);
1865   return 0;
1866 }
1867 static int
1868 noit_json_index_func(lua_State *L) {
1869   int n;
1870   const char *k;
1871   json_crutch **udata;
1872   n = lua_gettop(L); /* number of arguments */
1873   assert(n == 2);
1874   if(!luaL_checkudata(L, 1, "noit.json")) {
1875     luaL_error(L, "metatable error, arg1 not a noit.json!");
1876   }
1877   udata = lua_touserdata(L, 1);
1878   if(!lua_isstring(L, 2)) {
1879     luaL_error(L, "metatable error, arg2 not a string!");
1880   }
1881   k = lua_tostring(L, 2);
1882   switch(*k) {
1883     case 'd':
1884      LUA_DISPATCH(document, noit_lua_json_document);
1885      break;
1886     case 't':
1887      LUA_DISPATCH(tostring, noit_lua_json_tostring);
1888      break;
1889     default:
1890      break;
1891   }
1892   luaL_error(L, "noit.json no such element: %s", k);
1893   return 0;
1894 }
1895 static const luaL_Reg noitlib[] = {
1896   { "sleep", nl_sleep },
1897   { "gettimeofday", nl_gettimeofday },
1898   { "socket", nl_socket },
1899   { "dns", nl_dns_lookup },
1900   { "log", nl_log },
1901   { "crc32", nl_crc32 },
1902   { "base32_decode", nl_base32_decode },
1903   { "base32_encode", nl_base32_encode },
1904   { "base64_decode", nl_base64_decode },
1905   { "base64_encode", nl_base64_encode },
1906   { "md5_hex", nl_md5_hex },
1907   { "pcre", nl_pcre },
1908   { "gunzip", nl_gunzip },
1909   { "conf_get", nl_conf_get_string },
1910   { "conf_get_string", nl_conf_get_string },
1911   { "conf_get_integer", nl_conf_get_integer },
1912   { "conf_get_boolean", nl_conf_get_boolean },
1913   { "conf_get_number", nl_conf_get_float },
1914   { "parsexml", nl_parsexml },
1915   { "parsejson", nl_parsejson },
1916   { NULL, NULL }
1917 };
1918
1919 int luaopen_noit(lua_State *L) {
1920   luaL_newmetatable(L, "noit.eventer");
1921   lua_pushcclosure(L, noit_eventer_index_func, 0);
1922   lua_setfield(L, -2, "__index");
1923
1924   luaL_newmetatable(L, "noit.eventer.ssl_ctx");
1925   lua_pushcclosure(L, noit_ssl_ctx_index_func, 0);
1926   lua_setfield(L, -2, "__index");
1927
1928   luaL_newmetatable(L, "noit.dns");
1929   lua_pushcfunction(L, noit_lua_dns_gc);
1930   lua_setfield(L, -2, "__gc");
1931   luaL_newmetatable(L, "noit.dns");
1932   lua_pushcfunction(L, noit_lua_dns_index_func);
1933   lua_setfield(L, -2, "__index");
1934
1935   luaL_newmetatable(L, "noit.gunzip");
1936   lua_pushcfunction(L, noit_lua_gunzip_gc);
1937   lua_setfield(L, -2, "__gc");
1938
1939   luaL_newmetatable(L, "noit.pcre");
1940   lua_pushcfunction(L, noit_lua_pcre_gc);
1941   lua_setfield(L, -2, "__gc");
1942
1943   luaL_newmetatable(L, "noit.json");
1944   lua_pushcfunction(L, noit_lua_json_gc);
1945   lua_setfield(L, -2, "__gc");
1946   luaL_newmetatable(L, "noit.json");
1947   lua_pushcclosure(L, noit_json_index_func, 0);
1948   lua_setfield(L, -2, "__index");
1949
1950   luaL_newmetatable(L, "noit.xmldoc");
1951   lua_pushcfunction(L, noit_lua_xmldoc_gc);
1952   lua_setfield(L, -2, "__gc");
1953   luaL_newmetatable(L, "noit.xmldoc");
1954   lua_pushcclosure(L, noit_xmldoc_index_func, 0);
1955   lua_setfield(L, -2, "__index");
1956
1957   luaL_newmetatable(L, "noit.xmlnode");
1958   lua_pushcclosure(L, noit_xmlnode_index_func, 0);
1959   lua_setfield(L, -2, "__index");
1960
1961   luaL_newmetatable(L, "noit.xpathiter");
1962   lua_pushcfunction(L, noit_lua_xpathiter_gc);
1963   lua_setfield(L, -2, "__gc");
1964
1965   luaL_register(L, "noit", noitlib);
1966   return 0;
1967 }
1968
1969 void noit_lua_init() {
1970   eventer_name_callback("lua/sleep", nl_sleep_complete);
1971   eventer_name_callback("lua/socket_read",
1972                         noit_lua_socket_read_complete);
1973   eventer_name_callback("lua/socket_write",
1974                         noit_lua_socket_write_complete);
1975   eventer_name_callback("lua/socket_send",
1976                         noit_lua_socket_send_complete);
1977   eventer_name_callback("lua/socket_connect",
1978                         noit_lua_socket_connect_complete);
1979   eventer_name_callback("lua/ssl_upgrade", noit_lua_ssl_upgrade);
1980   noit_lua_init_dns();
1981 }
Note: See TracBrowser for help on using the browser.