• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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