root/src/modules/lua_noit.c

Revision 278be6a7d225b9ab718e0c0db325c1299f5b3835, 60.2 kB (checked in by Paul Querna <pquerna@apache.org>, 2 years ago)

If the first attempt at decompression fails with a data error, attempt to do it again, but ignore the deflate header

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