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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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)"; 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 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 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 */ 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 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() */ 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 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 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 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 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 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 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 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