1
4
5# include "luametatex.h"
6# include "lmtoptional.h"
7
8typedef void* curl_instance ;
9typedef int curl_return_code ;
10typedef int curl_error_code ;
11
12typedef enum curl_option_type {
13 curl_ignore = 0,
14 curl_integer = 1,
15 curl_string = 2,
16 curl_function = 3,
17 curl_offset = 4,
18} curl_option_type;
19
20
21
22static const int curl_options[] = {
23 curl_ignore,
24 curl_string,
25 curl_string,
26 curl_integer,
27 curl_string,
28 curl_string,
29 curl_string,
30 curl_string,
31 curl_ignore,
32 curl_string,
33 curl_string,
34 curl_function,
35 curl_function,
36 curl_integer,
37 curl_integer,
38 curl_string,
39 curl_string,
40 curl_string,
41 curl_string,
42 curl_integer,
43 curl_integer,
44 curl_integer,
45 curl_string,
46 curl_string,
47 curl_string,
48 curl_string,
49 curl_string,
50 curl_integer,
51 curl_string,
52 curl_string,
53 curl_ignore,
54 curl_string,
55 curl_integer,
56 curl_integer,
57 curl_integer,
58 curl_ignore,
59 curl_string,
60 curl_string,
61 curl_ignore,
62 curl_string,
63 curl_string,
64 curl_integer,
65 curl_integer,
66 curl_integer,
67 curl_integer,
68 curl_integer,
69 curl_integer,
70 curl_integer,
71 curl_integer,
72 curl_ignore,
73 curl_integer,
74 curl_integer,
75 curl_integer,
76 curl_integer,
77 curl_integer,
78 curl_ignore,
79 curl_function,
80 curl_string,
81 curl_integer,
82 curl_integer,
83 curl_integer,
84 curl_integer,
85 curl_string,
86 curl_string,
87 curl_integer,
88 curl_string,
89 curl_ignore,
90 curl_ignore,
91 curl_integer,
92 curl_integer,
93 curl_string,
94 curl_integer,
95 curl_integer,
96 curl_ignore,
97 curl_integer,
98 curl_integer,
99 curl_string,
100 curl_string,
101 curl_integer,
102 curl_function,
103 curl_integer,
104 curl_integer,
105 curl_string,
106 curl_string,
107 curl_integer,
108 curl_integer,
109 curl_string,
110 curl_string,
111 curl_string,
112 curl_string,
113 curl_integer,
114 curl_integer,
115 curl_integer,
116 curl_string,
117 curl_function,
118 curl_string,
119 curl_integer,
120 curl_string,
121 curl_integer,
122 curl_integer,
123 curl_string,
124 curl_integer,
125 curl_string,
126 curl_string,
127 curl_string,
128 curl_integer,
129 curl_integer,
130 curl_integer,
131 curl_function,
132 curl_string,
133 curl_integer,
134 curl_integer,
135 curl_integer,
136 curl_integer,
137 curl_integer,
138 curl_offset,
139 curl_offset,
140 curl_offset,
141 curl_string,
142 curl_integer,
143 curl_offset,
144 curl_integer,
145 curl_ignore,
146 curl_ignore,
147 curl_ignore,
148 curl_ignore,
149 curl_ignore,
150 curl_ignore,
151 curl_ignore,
152 curl_integer,
153 curl_function,
154 curl_string,
155 curl_ignore,
156 curl_ignore,
157 curl_string,
158 curl_string,
159 curl_integer,
160 curl_integer,
161 curl_integer,
162 curl_integer,
163 curl_integer,
164 curl_integer,
165 curl_function,
166 curl_function,
167 curl_function,
168 curl_offset,
169 curl_offset,
170 curl_string,
171 curl_function,
172 curl_string,
173 curl_integer,
174 curl_integer,
175 curl_string,
176 curl_string,
177 curl_integer,
178 curl_integer,
179 curl_integer,
180 curl_integer,
181 curl_integer,
182 curl_integer,
183 curl_integer,
184 curl_integer,
185 curl_string,
186 curl_function,
187 curl_string,
188 curl_string,
189 curl_integer,
190 curl_function,
191 curl_string,
192 curl_string,
193 curl_string,
194 curl_integer,
195 curl_integer,
196 curl_string,
197 curl_string,
198 curl_string,
199 curl_string,
200 curl_string,
201 curl_integer,
202 curl_string,
203 curl_integer,
204 curl_integer,
205 curl_integer,
206 curl_string,
207 curl_function,
208 curl_string,
209 curl_string,
210 curl_string,
211 curl_integer,
212 curl_integer,
213 curl_string,
214 curl_string,
215 curl_string,
216 curl_integer,
217 curl_integer,
218 curl_string,
219 curl_function,
220 curl_integer,
221 curl_function,
222 curl_function,
223 curl_function,
224 curl_string,
225 curl_string,
226 curl_string,
227 curl_string,
228 curl_string,
229 curl_string,
230 curl_integer,
231 curl_function,
232 curl_string,
233 curl_integer,
234 curl_string,
235 curl_integer,
236 curl_integer,
237 curl_integer,
238 curl_integer,
239 curl_integer,
240 curl_string,
241 curl_integer,
242 curl_function,
243 curl_string,
244 curl_string,
245 curl_string,
246 curl_string,
247 curl_string,
248 curl_integer,
249 curl_integer,
250 curl_integer
251};
252
253# define curl_option_min 1
254# define curl_option_max 227
255# define curl_option_writedata 1
256# define curl_option_url 2
257# define curl_option_writefunction 11
258
259# define curl_integer_base 0
260# define curl_string_base 10000
261# define curl_object_base 10000
262# define curl_function_base 20000
263# define curl_offset_base 30000
264# define curl_offset_blob 40000
265
266typedef size_t (*curl_write_callback) (
267 char *buffer,
268 size_t size,
269 size_t nitems,
270 void *userdata
271);
272
273typedef struct curllib_state_info {
274
275 int initialized;
276 int padding;
277
278 char * (*curl_version) (
279 void
280 );
281
282 void (*curl_free) (
283 void* p
284 );
285
286 curl_instance (*curl_easy_init) (
287 void
288 );
289
290 void (*curl_easy_cleanup) (
291 curl_instance handle
292 );
293
294 curl_return_code (*curl_easy_perform) (
295 curl_instance handle
296 );
297
298 curl_return_code (*curl_easy_setopt) (
299 curl_instance handle,
300 int option,
301 ...
302 );
303
304 char* (*curl_easy_escape) (
305 curl_instance handle,
306 const char *url,
307 int length
308 );
309
310 char* (*curl_easy_unescape) (
311 curl_instance handle,
312 const char *url,
313 int length,
314 int *outlength
315 );
316
317 const char* (*curl_easy_strerror) (
318 curl_error_code errcode
319 );
320
321} curllib_state_info;
322
323static curllib_state_info curllib_state = {
324
325 .initialized = 0,
326 .padding = 0,
327
328 .curl_version = NULL,
329 .curl_free = NULL,
330 .curl_easy_init = NULL,
331 .curl_easy_cleanup = NULL,
332 .curl_easy_perform = NULL,
333 .curl_easy_setopt = NULL,
334 .curl_easy_escape = NULL,
335 .curl_easy_unescape = NULL,
336 .curl_easy_strerror = NULL,
337
338};
339
340static int curllib_initialize(lua_State * L)
341{
342 if (! curllib_state.initialized) {
343 const char *filename = lua_tostring(L, 1);
344 if (filename) {
345
346 lmt_library lib = lmt_library_load(filename);
347
348 curllib_state.curl_version = lmt_library_find(lib, "curl_version");
349 curllib_state.curl_free = lmt_library_find(lib, "curl_free");
350 curllib_state.curl_easy_init = lmt_library_find(lib, "curl_easy_init");
351 curllib_state.curl_easy_cleanup = lmt_library_find(lib, "curl_easy_cleanup");
352 curllib_state.curl_easy_perform = lmt_library_find(lib, "curl_easy_perform");
353 curllib_state.curl_easy_setopt = lmt_library_find(lib, "curl_easy_setopt");
354 curllib_state.curl_easy_escape = lmt_library_find(lib, "curl_easy_escape");
355 curllib_state.curl_easy_unescape = lmt_library_find(lib, "curl_easy_unescape");
356 curllib_state.curl_easy_strerror = lmt_library_find(lib, "curl_easy_strerror");
357
358 curllib_state.initialized = lmt_library_okay(lib);
359 }
360 }
361 lua_pushboolean(L, curllib_state.initialized);
362 return 1;
363}
364
365
366
367
368
369static size_t curllib_write_cb(char *data, size_t n, size_t l, void *b)
370{
371 luaL_addlstring((luaL_Buffer *) b, data, n * l);
372 return n * l;
373}
374
375
379
380static int curllib_fetch(lua_State * L)
381{
382 if (curllib_state.initialized) {
383 if (lua_type(L,1) == LUA_TTABLE) {
384 curl_instance *curl = curllib_state.curl_easy_init();
385 if (curl) {
386 int result;
387 luaL_Buffer buffer;
388 luaL_buffinit(L, &buffer);
389 curllib_state.curl_easy_setopt(curl, curl_object_base + curl_option_writedata, &buffer);
390 curllib_state.curl_easy_setopt(curl, curl_function_base + curl_option_writefunction, &curllib_write_cb);
391 lua_pushnil(L);
392 while (lua_next(L, 1) != 0) {
393 if (lua_type(L, -2) == LUA_TNUMBER) {
394 int o = lmt_tointeger(L, -2);
395 if (o >= curl_option_min && o <= curl_option_max) {
396 switch (curl_options[o]) {
397 case curl_string:
398 if (lua_type(L, -1) == LUA_TSTRING) {
399 curllib_state.curl_easy_setopt(curl, curl_string_base + o, lua_tostring(L, -1));
400 } else {
401
402 }
403 break;
404 case curl_integer:
405 switch (lua_type(L, -1)) {
406 case LUA_TNUMBER:
407 curllib_state.curl_easy_setopt(curl, curl_integer_base + o, lua_tointeger(L, -1));
408 break;
409 case LUA_TBOOLEAN:
410 curllib_state.curl_easy_setopt(curl, curl_integer_base + o, lua_toboolean(L, -1));
411 break;
412 default:
413
414 break;
415 }
416 break;
417 }
418 } else {
419
420 }
421 } else {
422
423 }
424 lua_pop(L, 1);
425 }
426 result = curllib_state.curl_easy_perform(curl);
427 if (result) {
428 lua_pushboolean(L, 0);
429 lua_pushstring(L, curllib_state.curl_easy_strerror(result));
430 result = 2;
431 } else {
432 luaL_pushresult(&buffer);
433 result = 1;
434 }
435 curllib_state.curl_easy_cleanup(curl);
436 return result;
437 }
438 }
439 }
440 return 0;
441}
442
443static int curllib_escape(lua_State * L)
444{
445 if (curllib_state.initialized) {
446 curl_instance *curl = curllib_state.curl_easy_init();
447 if (curl) {
448 size_t length = 0;
449 const char * url = lua_tolstring(L, 1, &length);
450 char *s = curllib_state.curl_easy_escape(curl, url, (int) length);
451 if (s) {
452 lua_pushstring(L,(const char *) s);
453 curllib_state.curl_free(s);
454 curllib_state.curl_easy_cleanup(curl);
455 return 1;
456 }
457 }
458 }
459 return 0;
460}
461
462static int curllib_unescape(lua_State * L)
463{
464 if (curllib_state.initialized) {
465 curl_instance *curl = curllib_state.curl_easy_init();
466 if (curl) {
467 size_t length = 0;
468 const char *url = lua_tolstring(L, 1, &length);
469 int l = 0;
470 char *s = curllib_state.curl_easy_unescape(curl, url, (int) length, &l);
471 if (s) {
472 lua_pushlstring(L, s, l);
473 curllib_state.curl_free(s);
474 curllib_state.curl_easy_cleanup(curl);
475 return 1;
476 }
477 }
478 }
479 return 0;
480}
481
482static int curllib_getversion(lua_State * L)
483{
484 if (curllib_state.initialized) {
485 char *version = curllib_state.curl_version();
486 if (version) {
487 lua_pushstring(L, version);
488 return 1;
489 }
490 }
491 return 0;
492}
493
494static struct luaL_Reg curllib_function_list[] = {
495 { "initialize", curllib_initialize },
496 { "fetch", curllib_fetch },
497 { "escape", curllib_escape },
498 { "unescape", curllib_unescape },
499 { "getversion", curllib_getversion },
500 { NULL, NULL },
501};
502
503int luaopen_curl(lua_State * L)
504{
505 lmt_library_register(L, "curl", curllib_function_list);
506 return 0;
507}
508 |