1 /*
2 * Copyright 2001-2004 Brandon Long
3 * All Rights Reserved.
4 *
5 * ClearSilver Templating System
6 *
7 * This code is made available under the terms of the ClearSilver License.
8 * http://www.clearsilver.net/license.hdf
9 *
10 */
11
12 #include <Python.h>
13 #include "ClearSilver.h"
14
15 #define NEO_CGI_MODULE
16 #include "p_neo_util.h"
17
18 static PyObject *CGIFinishedException;
19
20 #define CGIObjectCheck(a) (!(strcmp((a)->ob_type->tp_name, CGIObjectType.tp_name)))
21
22 typedef struct _CGIObject
23 {
24 PyObject_HEAD
25 CGI *cgi;
26 PyObject *hdf;
27 PyObject *upload_cb;
28 PyObject *upload_rock;
29 int upload_error;
30 } CGIObject;
31
32 static PyObject *p_cgi_value_get_attr (CGIObject *self, char *name);
33 static void p_cgi_dealloc (CGIObject *ho);
34
35 PyTypeObject CGIObjectType = {
36 PyObject_HEAD_INIT(NULL)
37 0, /*ob_size*/
38 "CGIObjectType", /*tp_name*/
39 sizeof(CGIObject), /*tp_size*/
40 0, /*tp_itemsize*/
41 /* methods */
42 (destructor)p_cgi_dealloc, /*tp_dealloc*/
43 0, /*tp_print*/
44 (getattrfunc)p_cgi_value_get_attr, /*tp_getattr*/
45 0, /*tp_setattr*/
46 0, /*tp_compare*/
47 (reprfunc)0, /*tp_repr*/
48 0, /* tp_as_number */
49 0, /* tp_as_sequence */
50 0, /* tp_as_mapping */
51 0, /* tp_as_hash */
52 };
53
p_cgi_dealloc(CGIObject * ho)54 static void p_cgi_dealloc (CGIObject *ho)
55 {
56 if (ho->cgi)
57 {
58 cgi_destroy (&(ho->cgi));
59 }
60 PyObject_DEL(ho);
61 }
62
p_cgi_to_object(CGI * data)63 PyObject * p_cgi_to_object (CGI *data)
64 {
65 PyObject *rv;
66
67 if (data == NULL)
68 {
69 rv = Py_None;
70 Py_INCREF (rv);
71 }
72 else
73 {
74 CGIObject *ho = PyObject_NEW (CGIObject, &CGIObjectType);
75 if (ho == NULL) return NULL;
76 ho->cgi = data;
77 ho->hdf = p_hdf_to_object (data->hdf, 0);
78 Py_INCREF(ho->hdf);
79 rv = (PyObject *) ho;
80 }
81 return rv;
82 }
83
p_cgi_init(PyObject * self,PyObject * args)84 static PyObject * p_cgi_init (PyObject *self, PyObject *args)
85 {
86 CGI *cgi = NULL;
87 NEOERR *err;
88
89 err = cgi_init (&cgi, NULL);
90 if (err) return p_neo_error (err);
91 return p_cgi_to_object (cgi);
92 }
93
p_cgi_parse(PyObject * self,PyObject * args)94 static PyObject * p_cgi_parse (PyObject *self, PyObject *args)
95 {
96 CGI *cgi = ((CGIObject *) self)->cgi;
97 CGIObject *p_cgi = (CGIObject *) self;
98 PyObject *rv;
99 NEOERR *err;
100
101 p_cgi->upload_error = 0;
102
103 err = cgi_parse (cgi);
104 if (err) return p_neo_error (err);
105
106 if (p_cgi->upload_error)
107 {
108 p_cgi->upload_error = 0;
109 return NULL;
110 }
111
112 rv = Py_None;
113 Py_INCREF(rv);
114 return rv;
115 }
116
python_upload_cb(CGI * cgi,int nread,int expected)117 static int python_upload_cb (CGI *cgi, int nread, int expected)
118 {
119 CGIObject *self = (CGIObject *)(cgi->data);
120 PyObject *cb, *rock;
121 PyObject *args, *result;
122 int r;
123
124 /* fprintf(stderr, "upload_cb: %d/%d\n", nread, expected); */
125 cb = self->upload_cb;
126 rock = self->upload_rock;
127
128 if (cb == NULL) return 0;
129 args = Py_BuildValue("(Oii)", rock, nread, expected);
130
131 if (args == NULL) {
132 self->upload_error = 1;
133 return 1;
134 }
135 result = PyEval_CallObject(cb, args);
136 Py_DECREF(args);
137 if (result != NULL && !PyInt_Check(result)) {
138 Py_DECREF(result);
139 result = NULL;
140 PyErr_SetString(PyExc_TypeError,
141 "upload_cb () returned non-integer");
142 self->upload_error = 1;
143 return 1;
144 }
145 r = PyInt_AsLong(result);
146 Py_DECREF(result);
147 result = NULL;
148 return r;
149 }
150
p_cgi_set_upload_cb(PyObject * self,PyObject * args)151 static PyObject * p_cgi_set_upload_cb (PyObject *self, PyObject *args)
152 {
153 CGI *cgi = ((CGIObject *) self)->cgi;
154 CGIObject *p_cgi = (CGIObject *) self;
155 PyObject *rock, *cb;
156
157 if (!PyArg_ParseTuple(args, "OO:setUploadCB(rock, func)", &rock, &cb))
158 return NULL;
159
160 cgi->data = self;
161 cgi->upload_cb = python_upload_cb;
162 p_cgi->upload_cb = cb;
163 p_cgi->upload_rock = rock;
164 p_cgi->upload_error = 0;
165 Py_INCREF(cb);
166 Py_INCREF(rock);
167
168 Py_INCREF(Py_None);
169 return Py_None;
170 }
171
p_cgi_error(PyObject * self,PyObject * args)172 static PyObject * p_cgi_error (PyObject *self, PyObject *args)
173 {
174 CGI *cgi = ((CGIObject *) self)->cgi;
175 char *s;
176 PyObject *rv;
177
178 if (!PyArg_ParseTuple(args, "s:error(str)", &s))
179 return NULL;
180
181 cgi_error (cgi, s);
182 rv = Py_None;
183 Py_INCREF(rv);
184 return rv;
185 }
186
p_cgi_display(PyObject * self,PyObject * args)187 static PyObject * p_cgi_display (PyObject *self, PyObject *args)
188 {
189 CGI *cgi = ((CGIObject *) self)->cgi;
190 char *file;
191 PyObject *rv;
192 NEOERR *err;
193
194 if (!PyArg_ParseTuple(args, "s:display(file)", &file))
195 return NULL;
196
197 err = cgi_display (cgi, file);
198 if (err) return p_neo_error (err);
199 rv = Py_None;
200 Py_INCREF(rv);
201 return rv;
202 }
203
p_cgi_redirect(PyObject * self,PyObject * args)204 static PyObject * p_cgi_redirect (PyObject *self, PyObject *args)
205 {
206 CGI *cgi = ((CGIObject *) self)->cgi;
207 char *s;
208 PyObject *rv;
209
210 if (!PyArg_ParseTuple(args, "s:redirect(str)", &s))
211 return NULL;
212
213 cgi_redirect (cgi, "%s", s);
214 rv = Py_None;
215 Py_INCREF(rv);
216 return rv;
217 }
218
p_cgi_redirect_uri(PyObject * self,PyObject * args)219 static PyObject * p_cgi_redirect_uri (PyObject *self, PyObject *args)
220 {
221 CGI *cgi = ((CGIObject *) self)->cgi;
222 char *s;
223 PyObject *rv;
224
225 if (!PyArg_ParseTuple(args, "s:redirectUri(str)", &s))
226 return NULL;
227
228 cgi_redirect_uri (cgi, "%s", s);
229 rv = Py_None;
230 Py_INCREF(rv);
231 return rv;
232 }
233
p_cgi_cookie_authority(PyObject * self,PyObject * args)234 static PyObject * p_cgi_cookie_authority (PyObject *self, PyObject *args)
235 {
236 CGI *cgi = ((CGIObject *) self)->cgi;
237 char *s, *host;
238 PyObject *rv;
239
240 if (!PyArg_ParseTuple(args, "s:cookieAuthority(host)", &host))
241 return NULL;
242
243 s = cgi_cookie_authority (cgi, host);
244 if (s == NULL)
245 {
246 rv = Py_None;
247 Py_INCREF(rv);
248 }
249 else
250 {
251 rv = Py_BuildValue ("s", s);
252 }
253 return rv;
254 }
255
p_cgi_cookie_set(PyObject * self,PyObject * args,PyObject * keywds)256 static PyObject * p_cgi_cookie_set (PyObject *self, PyObject *args,
257 PyObject *keywds)
258 {
259 CGI *cgi = ((CGIObject *) self)->cgi;
260 char *name, *value, *path = NULL, *domain = NULL, *time_str = NULL;
261 int persist = 0;
262 int secure = 0;
263 NEOERR *err;
264 static char *kwlist[] = {"name", "value", "path", "domain", "time_str", "persist", "secure", NULL};
265
266 if (!PyArg_ParseTupleAndKeywords(args, keywds, "ss|sssii:cookieSet()", kwlist, &name, &value, &path, &domain, &time_str, &persist, &secure))
267 return NULL;
268
269 err = cgi_cookie_set (cgi, name, value, path, domain, time_str, persist, secure);
270 if (err) return p_neo_error (err);
271 Py_INCREF(Py_None);
272 return Py_None;
273 }
274
p_cgi_cookie_clear(PyObject * self,PyObject * args)275 static PyObject * p_cgi_cookie_clear (PyObject *self, PyObject *args)
276 {
277 CGI *cgi = ((CGIObject *) self)->cgi;
278 char *name, *domain = NULL, *path = NULL;
279 NEOERR *err;
280
281 if (!PyArg_ParseTuple(args, "s|ss:cookieClear(name, domain, path)", &name, &domain, &path))
282 return NULL;
283
284 err = cgi_cookie_clear (cgi, name, domain, path);
285 if (err) return p_neo_error (err);
286 Py_INCREF(Py_None);
287 return Py_None;
288 }
289
p_cgi_filehandle(PyObject * self,PyObject * args)290 static PyObject * p_cgi_filehandle (PyObject *self, PyObject *args)
291 {
292 CGI *cgi = ((CGIObject *) self)->cgi;
293 char *name;
294 FILE *fp;
295
296 if (!PyArg_ParseTuple(args, "s:filehandle(form_name)", &name))
297 return NULL;
298
299 fp = cgi_filehandle (cgi, name);
300 if (fp == NULL)
301 {
302 Py_INCREF(Py_None);
303 return Py_None;
304 }
305 return PyFile_FromFile (fp, name, "w+", NULL);
306 }
307
p_cgi_cs_init(PyObject * self,PyObject * args)308 static PyObject * p_cgi_cs_init (PyObject *self, PyObject *args)
309 {
310 CGI *cgi = ((CGIObject *) self)->cgi;
311 NEOERR *err;
312 CSPARSE *cs;
313
314 if (!PyArg_ParseTuple(args, ":cs()"))
315 return NULL;
316
317 err = cgi_cs_init(cgi, &cs);
318 if (err) return p_neo_error (err);
319 return p_cs_to_object(cs);
320 }
321
322 static PyMethodDef CGIMethods[] =
323 {
324 #if 0
325 {"debugInit", p_cgi_debug_init, METH_VARARGS, NULL},
326 {"wrapInit", p_cgi_wrap_init, METH_VARARGS, NULL},
327 #endif
328 {"parse", p_cgi_parse, METH_VARARGS, NULL},
329 {"setUploadCB", p_cgi_set_upload_cb, METH_VARARGS, NULL},
330 {"error", p_cgi_error, METH_VARARGS, NULL},
331 {"display", p_cgi_display, METH_VARARGS, NULL},
332 {"redirect", p_cgi_redirect, METH_VARARGS, NULL},
333 {"redirectUri", p_cgi_redirect_uri, METH_VARARGS, NULL},
334 {"cookieAuthority", p_cgi_cookie_authority, METH_VARARGS, NULL},
335 {"cookieSet", (PyCFunction)p_cgi_cookie_set, METH_VARARGS|METH_KEYWORDS, NULL},
336 {"cookieClear", p_cgi_cookie_clear, METH_VARARGS, NULL},
337 {"filehandle", p_cgi_filehandle, METH_VARARGS, NULL},
338 {"cs", p_cgi_cs_init, METH_VARARGS, NULL},
339 {NULL, NULL}
340 };
341
p_cgi_url_escape(PyObject * self,PyObject * args)342 static PyObject * p_cgi_url_escape (PyObject *self, PyObject *args)
343 {
344 char *s, *esc, *o = NULL;
345 NEOERR *err;
346 PyObject *rv;
347
348 if (!PyArg_ParseTuple(args, "s|s:urlEscape(str, other=None)", &s, &o))
349 return NULL;
350
351 err = cgi_url_escape_more (s, &esc, o);
352 if (err) return p_neo_error (err);
353 rv = Py_BuildValue ("s", esc);
354 free (esc);
355 return rv;
356 }
357
p_cgi_url_unescape(PyObject * self,PyObject * args)358 static PyObject * p_cgi_url_unescape (PyObject *self, PyObject *args)
359 {
360 char *s;
361 PyObject *rv;
362 char *r;
363
364 if (!PyArg_ParseTuple(args, "s:urlUnescape(str)", &s))
365 return NULL;
366
367 r = strdup(s);
368 if (r == NULL) return PyErr_NoMemory();
369 cgi_url_unescape (r);
370 rv = Py_BuildValue ("s", r);
371 free (r);
372 return rv;
373 }
374
p_html_escape(PyObject * self,PyObject * args)375 static PyObject * p_html_escape (PyObject *self, PyObject *args)
376 {
377 char *s, *esc;
378 NEOERR *err;
379 PyObject *rv;
380 int len;
381
382 if (!PyArg_ParseTuple(args, "s#:htmlEscape(str)", &s, &len))
383 return NULL;
384
385 err = html_escape_alloc (s, len, &esc);
386 if (err) return p_neo_error (err);
387 rv = Py_BuildValue ("s", esc);
388 free (esc);
389 return rv;
390 }
391
p_html_strip(PyObject * self,PyObject * args)392 static PyObject * p_html_strip (PyObject *self, PyObject *args)
393 {
394 char *s, *esc;
395 NEOERR *err;
396 PyObject *rv;
397 int len;
398
399 if (!PyArg_ParseTuple(args, "s#:htmlStrip(str)", &s, &len))
400 return NULL;
401
402 err = html_strip_alloc (s, len, &esc);
403 if (err) return p_neo_error (err);
404 rv = Py_BuildValue ("s", esc);
405 free (esc);
406 return rv;
407 }
408
p_text_html(PyObject * self,PyObject * args,PyObject * keywds)409 static PyObject * p_text_html (PyObject *self, PyObject *args, PyObject *keywds)
410 {
411 char *s, *esc;
412 NEOERR *err;
413 PyObject *rv;
414 int len;
415 HTML_CONVERT_OPTS opts;
416 static char *kwlist[] = {"text", "bounce_url", "url_class", "url_target", "mailto_class", "long_lines", "space_convert", "newlines_convert", "longline_width", "check_ascii_art", "link_name", NULL};
417
418 /* These defaults all come from the old version */
419 opts.bounce_url = NULL;
420 opts.url_class = NULL;
421 opts.url_target = "_blank";
422 opts.mailto_class = NULL;
423 opts.long_lines = 0;
424 opts.space_convert = 0;
425 opts.newlines_convert = 1;
426 opts.longline_width = 75; /* This hasn't been used in a while, actually */
427 opts.check_ascii_art = 1;
428 opts.link_name = NULL;
429
430 if (!PyArg_ParseTupleAndKeywords(args, keywds, "s#|ssssiiiiis:text2html(text)",
431 kwlist,
432 &s, &len, &(opts.bounce_url), &(opts.url_class), &(opts.url_target),
433 &(opts.mailto_class), &(opts.long_lines), &(opts.space_convert),
434 &(opts.newlines_convert), &(opts.longline_width), &(opts.check_ascii_art), &(opts.link_name)))
435 return NULL;
436
437 err = convert_text_html_alloc_options (s, len, &esc, &opts);
438 if (err) return p_neo_error (err);
439 rv = Py_BuildValue ("s", esc);
440 free (esc);
441 return rv;
442 }
443
p_cgi_value_get_attr(CGIObject * ho,char * name)444 PyObject *p_cgi_value_get_attr (CGIObject *ho, char *name)
445 {
446 if (!strcmp(name, "hdf"))
447 {
448 Py_INCREF(ho->hdf);
449 return ho->hdf;
450 }
451 return Py_FindMethod(CGIMethods, (PyObject *)ho, name);
452 }
453
454 /* Enable wrapping of newlib stdin/stdout output to go through python */
455 typedef struct wrapper_data
456 {
457 PyObject *p_stdin;
458 PyObject *p_stdout;
459 PyObject *p_env;
460 } WRAPPER_DATA;
461
462 static WRAPPER_DATA Wrapper = {NULL, NULL, NULL};
463
464 static char cgiwrap_doc[] = "cgiwrap(stdin, stdout, env)\nMethod that will cause all cgiwrapped stdin/stdout functions to be redirected to the python stdin/stdout file objects specified. Also redirect getenv/putenv calls (env should be either a python dictionary or os.environ)";
cgiwrap(PyObject * self,PyObject * args)465 static PyObject * cgiwrap (PyObject *self, PyObject *args)
466 {
467 PyObject *p_stdin;
468 PyObject *p_stdout;
469 PyObject *p_env;
470
471 if (!PyArg_ParseTuple(args, "OOO:cgiwrap(stdin, stdout, env)", &p_stdin, &p_stdout, &p_env))
472 return NULL;
473
474 if (p_stdin != Py_None)
475 {
476 if (Wrapper.p_stdin != NULL)
477 {
478 Py_DECREF (Wrapper.p_stdin);
479 }
480 Wrapper.p_stdin = p_stdin;
481 Py_INCREF (Wrapper.p_stdin);
482 }
483 if (p_stdout != Py_None)
484 {
485 if (Wrapper.p_stdout != NULL)
486 {
487 Py_DECREF (Wrapper.p_stdout);
488 }
489 Wrapper.p_stdout = p_stdout;
490 Py_INCREF (Wrapper.p_stdout);
491 }
492 if (p_env != Py_None)
493 {
494 if (Wrapper.p_env != NULL)
495 {
496 Py_DECREF (Wrapper.p_env);
497 }
498 Wrapper.p_env = p_env;
499 Py_INCREF (Wrapper.p_env);
500 }
501
502 Py_INCREF(Py_None);
503 return Py_None;
504 }
505
p_writef(void * data,const char * fmt,va_list ap)506 static int p_writef (void *data, const char *fmt, va_list ap)
507 {
508 WRAPPER_DATA *wrap = (WRAPPER_DATA *)data;
509 PyObject *str;
510 char *buf;
511 int len;
512 int err;
513
514
515 buf = vsprintf_alloc(fmt, ap);
516 len = visprintf_alloc(&buf, fmt, ap);
517
518 if (buf == NULL)
519 return 0;
520
521 str = PyString_FromStringAndSize (buf, len);
522 free(buf);
523
524 err = PyFile_WriteObject(str, wrap->p_stdout, Py_PRINT_RAW);
525 Py_DECREF(str);
526
527 if (err == 0)
528 {
529 PyErr_Clear();
530 return len;
531 }
532 PyErr_Clear();
533 return err;
534 }
535
p_write(void * data,const char * buf,int len)536 static int p_write (void *data, const char *buf, int len)
537 {
538 WRAPPER_DATA *wrap = (WRAPPER_DATA *)data;
539 PyObject *s;
540 int err;
541
542 s = PyString_FromStringAndSize (buf, len);
543
544 err = PyFile_WriteObject(s, wrap->p_stdout, Py_PRINT_RAW);
545 Py_DECREF(s);
546
547 if (err == 0)
548 {
549 PyErr_Clear();
550 return len;
551 }
552 PyErr_Clear();
553 return err;
554 }
555
556 /* Similar to the PyFile_GetLine function, this one invokes read on the
557 * file object */
PyFile_Read(PyObject * f,int n)558 static PyObject *PyFile_Read (PyObject *f, int n)
559 {
560 if (f == NULL)
561 {
562 PyErr_BadInternalCall();
563 return NULL;
564 }
565 /* If this was in the python fileobject code, we could handle this
566 * directly for builtin file objects. Oh well. */
567 /* if (!PyFile_Check(f))*/
568 else
569 {
570 PyObject *reader;
571 PyObject *args;
572 PyObject *result;
573 reader = PyObject_GetAttrString(f, "read");
574 if (reader == NULL)
575 return NULL;
576 if (n <= 0)
577 args = Py_BuildValue("()");
578 else
579 args = Py_BuildValue("(i)", n);
580 if (args == NULL) {
581 Py_DECREF(reader);
582 return NULL;
583 }
584 result = PyEval_CallObject(reader, args);
585 Py_DECREF(reader);
586 Py_DECREF(args);
587 if (result != NULL && !PyString_Check(result)) {
588 Py_DECREF(result);
589 result = NULL;
590 PyErr_SetString(PyExc_TypeError,
591 "object.read() returned non-string");
592 }
593 return result;
594 }
595 }
596
p_read(void * data,char * ptr,int len)597 static int p_read (void *data, char *ptr, int len)
598 {
599 WRAPPER_DATA *wrap = (WRAPPER_DATA *)data;
600 PyObject *buf;
601 char *s;
602
603 buf = PyFile_Read (wrap->p_stdin, len);
604
605 if (buf == NULL)
606 {
607 PyErr_Clear();
608 return -1;
609 }
610
611 len = PyString_Size(buf);
612 s = PyString_AsString(buf);
613
614 memcpy (ptr, s, len);
615
616 Py_DECREF(buf);
617
618 PyErr_Clear();
619 return len;
620 }
621
622 /* We can't really have an error return from this (and the other
623 * cgiwrap) function, because the API doesn't have an error return,
624 * and if we get back to python, the error will occur at the next random
625 * place that python actually checks for errors independent of an error
626 * return. Not the best way to do things, but its what we've got. Some
627 * of these we can check for in cgiWrap() */
p_getenv(void * data,const char * s)628 static char *p_getenv (void *data, const char *s)
629 {
630 WRAPPER_DATA *wrap = (WRAPPER_DATA *)data;
631 PyObject *get;
632 PyObject *args = NULL;
633 PyObject *result;
634 char *ret = NULL;
635
636 get = PyObject_GetAttrString(wrap->p_env, "__getitem__");
637 if (get != NULL)
638 {
639 args = Py_BuildValue("(s)", s);
640 if (args == NULL) {
641 Py_DECREF(get);
642 PyErr_Clear();
643 return NULL;
644 }
645 }
646 else
647 {
648 /* Python 1.5.2 and earlier don't have __getitem__ on the standard
649 * dict object, so we'll just use get for them */
650
651 get = PyObject_GetAttrString(wrap->p_env, "get");
652 if (get != NULL)
653 {
654 args = Py_BuildValue("(s,O)", s, Py_None);
655 if (args == NULL)
656 {
657 Py_DECREF(get);
658 PyErr_Clear();
659 return NULL;
660 }
661 }
662 }
663 if (get == NULL)
664 {
665 ne_warn("Unable to get __getitem__ from env");
666 PyErr_Clear();
667 return NULL;
668 }
669 result = PyEval_CallObject(get, args);
670 Py_DECREF(get);
671 Py_DECREF(args);
672 if (result != NULL && !PyString_Check(result) && (result != Py_None))
673 {
674 Py_DECREF(result);
675 result = NULL;
676 PyErr_SetString(PyExc_TypeError,
677 "env.get() returned non-string");
678 }
679 if (result != NULL && result != Py_None)
680 {
681 ret = strdup (PyString_AsString(result));
682 Py_DECREF (result);
683 }
684
685 PyErr_Clear();
686 return ret;
687 }
688
p_iterenv(void * data,int x,char ** rk,char ** rv)689 static int p_iterenv (void *data, int x, char **rk, char **rv)
690 {
691 WRAPPER_DATA *wrap = (WRAPPER_DATA *)data;
692 PyObject *items;
693 PyObject *env_list;
694 PyObject *result;
695 PyObject *k, *v;
696
697 items = PyObject_GetAttrString(wrap->p_env, "items");
698 if (items == NULL)
699 {
700 ne_warn ("p_iterenv: Unable to get items method");
701 PyErr_Clear();
702 return -1;
703 }
704 env_list = PyEval_CallObject(items, NULL);
705 Py_DECREF(items);
706 if (env_list == NULL)
707 {
708 ne_warn ("p_iterenv: Unable to call items method");
709 PyErr_Clear();
710 return -1;
711 }
712 if (x >= PyList_Size(env_list))
713 {
714 *rk = NULL;
715 *rv = NULL;
716 Py_DECREF(env_list);
717 return 0;
718 }
719 result = PyList_GetItem (env_list, x);
720 if (result == NULL)
721 {
722 ne_warn ("p_iterenv: Unable to get env %d", x);
723 Py_DECREF(env_list);
724 PyErr_Clear();
725 return -1;
726 }
727 k = PyTuple_GetItem (result, 0);
728 v = PyTuple_GetItem (result, 1);
729 if (k == NULL || v == NULL)
730 {
731 ne_warn ("p_iterenv: Unable to get k,v %p,%p", k, v);
732 Py_DECREF(env_list);
733 PyErr_Clear();
734 return -1;
735 }
736 *rk = strdup(PyString_AsString(k));
737 *rv = strdup(PyString_AsString(v));
738 if (*rk == NULL || *rv == NULL)
739 {
740 if (*rk) free (*rk);
741 if (*rv) free (*rv);
742 Py_DECREF(env_list);
743 PyErr_Clear();
744 return -1;
745 }
746
747 Py_DECREF(env_list);
748 PyErr_Clear();
749 return 0;
750 }
751
p_putenv(void * data,const char * k,const char * v)752 static int p_putenv (void *data, const char *k, const char *v)
753 {
754 WRAPPER_DATA *wrap = (WRAPPER_DATA *)data;
755 PyObject *set;
756 PyObject *args;
757 PyObject *result;
758
759 if (k == NULL || v == NULL) return -1;
760
761 set = PyObject_GetAttrString(wrap->p_env, "__setitem__");
762 if (set == NULL)
763 {
764 PyErr_Clear();
765 return -1;
766 }
767 args = Py_BuildValue("(s,s)", k, v);
768
769 if (args == NULL) {
770 Py_DECREF(set);
771 PyErr_Clear();
772 return -1;
773 }
774 result = PyEval_CallObject(set, args);
775 Py_DECREF(set);
776 Py_DECREF(args);
777 if (result == NULL)
778 {
779 PyErr_Clear();
780 return -1;
781 }
782 Py_DECREF(result);
783 PyErr_Clear();
784 return 0;
785 }
786
p_cgiwrap_init(PyObject * m)787 static void p_cgiwrap_init(PyObject *m)
788 {
789 PyObject *sys, *os, *p_stdin, *p_stdout, *args, *p_env;
790 #if 0
791 PyObject *argv;
792 int x;
793 #endif
794
795 /* Set up the python wrapper
796 * This might not be enough to actually continue to point to
797 * sys.stdin/sys.stdout, we'd probably have to actually do the lookup
798 * every time... if we need that functionality
799 */
800 sys = PyImport_ImportModule("sys");
801 os = PyImport_ImportModule("os");
802 if (sys)
803 {
804 p_stdin = PyObject_GetAttrString(sys, "stdin");
805 p_stdout = PyObject_GetAttrString(sys, "stdout");
806 #if 0
807 argv = PyObject_GetAttrString(sys, "argv");
808 if (argv)
809 {
810 Argc = PyList_Size (argv);
811 if (Argc != -1)
812 {
813
814 Argv = (char **) malloc (sizeof (char *) * (Argc+1));
815 for (x = 0; x < Argc; x++)
816 {
817 PyObject *a;
818 char *b;
819
820 a = PyList_GetItem (argv, x);
821 if (a == NULL)
822 break;
823 b = PyString_AsString(a);
824 if (b == NULL)
825 break;
826 Argv[x] = b;
827 }
828 Argv[x] = NULL;
829 }
830 }
831 #endif
832 if (os)
833 {
834 p_env = PyObject_GetAttrString(os, "environ");
835 }
836 else
837 {
838 Py_INCREF(Py_None);
839 p_env = Py_None;
840 }
841 args = Py_BuildValue("(O,O,O)", p_stdin, p_stdout, p_env);
842 if (args)
843 {
844 cgiwrap_init_emu (&Wrapper, p_read, p_writef, p_write, p_getenv, p_putenv, p_iterenv);
845 cgiwrap (m, args);
846 Py_DECREF(args);
847 }
848 }
849 }
850
p_ignore(PyObject * self,PyObject * args)851 static PyObject * p_ignore (PyObject *self, PyObject *args)
852 {
853 int i = 0;
854
855 if (!PyArg_ParseTuple(args, "i:IgnoreEmptyFormVars(bool)", &i))
856 return NULL;
857
858 IgnoreEmptyFormVars = i;
859 Py_INCREF(Py_None);
860 return Py_None;
861 }
862
p_export_date(PyObject * self,PyObject * args)863 static PyObject * p_export_date (PyObject *self, PyObject *args)
864 {
865 NEOERR *err;
866 PyObject *ho;
867 int i = 0;
868 char *prefix;
869 char *timezone;
870 HDF *hdf;
871
872 if (!PyArg_ParseTuple(args, "Ossi:exportDate(hdf, prefix, timezone, time_t)", &ho, &prefix, &timezone, &i))
873 return NULL;
874
875 hdf = p_object_to_hdf (ho);
876 if (hdf == NULL)
877 {
878 PyErr_SetString(PyExc_TypeError, "First argument must be an HDF Object");
879 return NULL;
880 }
881
882 err = export_date_time_t (hdf, prefix, timezone, i);
883 if (err) return p_neo_error (err);
884
885 Py_INCREF(Py_None);
886 return Py_None;
887 }
888
p_update(PyObject * self,PyObject * args)889 static PyObject * p_update (PyObject *self, PyObject *args)
890 {
891 if (_PyImport_FindExtension("neo_util","neo_util") == NULL)
892 initneo_util();
893
894 if (_PyImport_FindExtension("neo_cs","neo_cs") == NULL)
895 initneo_cs();
896
897 Py_INCREF(Py_None);
898 return Py_None;
899 }
900
901 static PyMethodDef ModuleMethods[] =
902 {
903 {"CGI", p_cgi_init, METH_VARARGS, NULL},
904 {"urlEscape", p_cgi_url_escape, METH_VARARGS, NULL},
905 {"urlUnescape", p_cgi_url_unescape, METH_VARARGS, NULL},
906 {"htmlEscape", p_html_escape, METH_VARARGS, NULL},
907 {"htmlStrip", p_html_strip, METH_VARARGS, NULL},
908 {"text2html", (PyCFunction)p_text_html, METH_VARARGS|METH_KEYWORDS, NULL},
909 {"cgiWrap", cgiwrap, METH_VARARGS, cgiwrap_doc},
910 {"IgnoreEmptyFormVars", p_ignore, METH_VARARGS, NULL},
911 {"exportDate", p_export_date, METH_VARARGS, NULL},
912 {"update", p_update, METH_VARARGS, NULL},
913 {NULL, NULL}
914 };
915
initneo_cgi(void)916 DL_EXPORT(void) initneo_cgi(void)
917 {
918 PyObject *m, *d;
919 static void *NEO_PYTHON_API[P_NEO_CGI_POINTERS];
920 PyObject *c_api_object;
921
922 CGIObjectType.ob_type = &PyType_Type;
923
924
925
926 initneo_util();
927 _PyImport_FixupExtension("neo_util", "neo_util");
928
929 initneo_cs();
930 _PyImport_FixupExtension("neo_cs", "neo_cs");
931
932 m = Py_InitModule("neo_cgi", ModuleMethods);
933 p_cgiwrap_init (m);
934 d = PyModule_GetDict(m);
935 CGIFinishedException = PyErr_NewException("neo_cgi.CGIFinished", NULL, NULL);
936 PyDict_SetItemString(d, "CGIFinished", CGIFinishedException);
937
938 /* Initialize the C API Pointer array */
939 NEO_PYTHON_API[P_HDF_TO_OBJECT_NUM] = (void *)p_hdf_to_object;
940 NEO_PYTHON_API[P_OBJECT_TO_HDF_NUM] = (void *)p_object_to_hdf;
941 NEO_PYTHON_API[P_NEO_ERROR_NUM] = (void *)p_neo_error;
942
943 /* create a CObject containing the API pointer array's address */
944 c_api_object = PyCObject_FromVoidPtr((void *)NEO_PYTHON_API, NULL);
945 if (c_api_object != NULL) {
946 /* create a name for this object in the module's namespace */
947 PyDict_SetItemString(d, "_C_API", c_api_object);
948 Py_DECREF(c_api_object);
949 PyDict_SetItemString(d, "_C_API_NUM", PyInt_FromLong(P_NEO_CGI_POINTERS));
950 }
951 }
952