root/sapi/roxen/roxen.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lookup_header
  2. lookup_string_header
  3. lookup_integer_header
  4. php_roxen_low_ub_write
  5. php_roxen_sapi_ub_write
  6. php_roxen_set_header
  7. php_roxen_sapi_header_handler
  8. php_roxen_low_send_headers
  9. php_roxen_sapi_send_headers
  10. php_roxen_low_read_post
  11. php_roxen_sapi_read_post
  12. php_roxen_sapi_read_cookies
  13. php_info_roxen
  14. php_roxen_startup
  15. php_roxen_hash_environment
  16. php_roxen_module_main
  17. f_php_roxen_request_handler
  18. clear_struct
  19. pike_module_init
  20. pike_module_exit

   1 /* 
   2    +----------------------------------------------------------------------+
   3    | PHP Version 5                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 The PHP Group                                |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 3.01 of the PHP license,      |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.php.net/license/3_01.txt                                  |
  11    | If you did not receive a copy of the PHP license and are unable to   |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@php.net so we can mail you a copy immediately.               |
  14    +----------------------------------------------------------------------+
  15    | Author: David Hedbor <neotron@php.net>                               |
  16    | Based on aolserver SAPI by Sascha Schumann <sascha@schumann.cx>      |
  17    +----------------------------------------------------------------------+
  18  */
  19 
  20 /* $Id$ */
  21 
  22 #include "php.h"
  23 #ifdef HAVE_ROXEN
  24 
  25 #include "php_ini.h"
  26 #include "php_globals.h"
  27 #include "SAPI.h"
  28 #include "php_main.h" 
  29 #include "ext/standard/info.h"
  30 
  31 #include "php_version.h"
  32 
  33 #ifndef ZTS
  34 /* Only valid if thread safety is enabled. */
  35 #undef ROXEN_USE_ZTS
  36 #endif
  37 
  38 
  39 /* Pike Include Files 
  40  *
  41  * conflicts with pike avoided by only using long names. Requires a new
  42  * Pike 0.7 since it was implemented for this interface only.
  43  *
  44  */
  45 #define NO_PIKE_SHORTHAND
  46 
  47 #include <fdlib.h>
  48 #include <program.h>
  49 #include <pike_types.h>
  50 #include <interpret.h>
  51 #include <module_support.h>
  52 #include <error.h>
  53 #include <array.h>
  54 #include <backend.h>
  55 #include <stralloc.h>
  56 #include <mapping.h>
  57 #include <object.h>
  58 #include <threads.h>
  59 #include <builtin_functions.h>
  60 #include <operators.h>
  61 
  62 #undef HIDE_GLOBAL_VARIABLES
  63 #undef REVEAL_GLOBAL_VARIABLES
  64 #define HIDE_GLOBAL_VARIABLES()
  65 #define REVEAL_GLOBAL_VARIABLES()
  66 
  67 /* php_roxen_request is per-request object storage */
  68 
  69 typedef struct
  70 {
  71   struct mapping *request_data;
  72   struct object *my_fd_obj;
  73   int my_fd;
  74   char *filename;
  75 } php_roxen_request;
  76 
  77 
  78 /* Defines to get to the data supplied when the script is started. */
  79 
  80 #ifdef ROXEN_USE_ZTS
  81 
  82 /* ZTS does work now, but it seems like it's faster using the "serialization"
  83  * method I previously used. Thus it's not used unless ROXEN_USE_ZTS is defined.
  84  */
  85 
  86 /* Per thread storage area id... */
  87 static int roxen_globals_id;
  88 
  89 # define GET_THIS() php_roxen_request *_request = ts_resource(roxen_globals_id)
  90 # define THIS _request
  91 #else
  92 static php_roxen_request *current_request = NULL;
  93 
  94 # define GET_THIS() current_request = ((php_roxen_request *)Pike_fp->current_storage)
  95 # define THIS current_request
  96 #endif
  97 
  98 /* File descriptor integer. Used to write directly to the FD without 
  99  * passing Pike
 100  */
 101 #define MY_FD    (THIS->my_fd)
 102 
 103 /* FD object. Really a PHPScript object from Pike which implements a couple
 104  * of functions to handle headers, writing and buffering.
 105  */
 106 #define MY_FD_OBJ        ((struct object *)(THIS->my_fd_obj))
 107 
 108 /* Mapping with data supplied from the calling Roxen module. Contains
 109  * a mapping with headers, an FD object etc.
 110  */
 111 #define REQUEST_DATA ((struct mapping *)(THIS->request_data))
 112 
 113 
 114 #if defined(_REENTRANT) && !defined(ROXEN_USE_ZTS)
 115 /* Lock used to serialize the PHP execution. If ROXEN_USE_ZTS is defined, we
 116  * are using the PHP thread safe mechanism instead.
 117  */
 118 static PIKE_MUTEX_T roxen_php_execution_lock;
 119 # define PHP_INIT_LOCK()        mt_init(&roxen_php_execution_lock)
 120 # define PHP_LOCK(X)    THREADS_ALLOW();mt_lock(&roxen_php_execution_lock);THREADS_DISALLOW()
 121 # define PHP_UNLOCK(X)  mt_unlock(&roxen_php_execution_lock);
 122 # define PHP_DESTROY()  mt_destroy(&roxen_php_execution_lock)
 123 #else /* !_REENTRANT */
 124 # define PHP_INIT_LOCK()        
 125 # define PHP_LOCK(X)
 126 # define PHP_UNLOCK(X)
 127 # define PHP_DESTROY()  
 128 #endif /* _REENTRANT */
 129 
 130 extern int fd_from_object(struct object *o);
 131 static unsigned char roxen_php_initialized;
 132 
 133 /* This allows calling of pike functions from the PHP callbacks,
 134  * which requires the Pike interpreter to be locked.
 135  */
 136 #define THREAD_SAFE_RUN(COMMAND, what)  do {\
 137   struct thread_state *state;\
 138  if((state = thread_state_for_id(th_self()))!=NULL) {\
 139     if(!state->swapped) {\
 140       COMMAND;\
 141     } else {\
 142       mt_lock(&interpreter_lock);\
 143       SWAP_IN_THREAD(state);\
 144       COMMAND;\
 145       SWAP_OUT_THREAD(state);\
 146       mt_unlock(&interpreter_lock);\
 147     }\
 148   }\
 149 } while(0)
 150 
 151 struct program *php_program;
 152 
 153 
 154 /* To avoid executing a PHP script from a PHP callback, which would
 155  * create a deadlock, a global thread id is used. If the thread calling the
 156  * php-script is the same as the current thread, it fails. 
 157  */
 158 static int current_thread = -1;
 159 
 160 
 161 /* Low level header lookup. Basically looks for the named header in the mapping
 162  * headers in the supplied options mapping.
 163  */
 164  
 165 static INLINE struct svalue *lookup_header(char *headername)
 166 {
 167   struct svalue *headers, *value;
 168   struct pike_string *sind;
 169 #ifdef ROXEN_USE_ZTS
 170   GET_THIS();
 171 #endif
 172   sind = make_shared_string("env");
 173   headers = low_mapping_string_lookup(REQUEST_DATA, sind);
 174   free_string(sind);
 175   if(!headers || headers->type != PIKE_T_MAPPING) return NULL;
 176   sind = make_shared_string(headername);
 177   value = low_mapping_string_lookup(headers->u.mapping, sind);
 178   free_string(sind);
 179   if(!value) return NULL;
 180   return value;
 181 }
 182 
 183 /* Lookup a header in the mapping and return the value as a string, or
 184  * return the default if it's missing
 185  */
 186 INLINE static char *lookup_string_header(char *headername, char *default_value)
 187 {
 188   struct svalue *head = NULL;
 189   THREAD_SAFE_RUN(head = lookup_header(headername), "header lookup");
 190   if(!head || head->type != PIKE_T_STRING)
 191     return default_value;
 192   return head->u.string->str;
 193 }
 194 
 195 /* Lookup a header in the mapping and return the value as if it's an integer
 196  * and otherwise return the default.
 197  */
 198 INLINE static int lookup_integer_header(char *headername, int default_value)
 199 {
 200   struct svalue *head = NULL;
 201   THREAD_SAFE_RUN(head = lookup_header(headername), "header lookup");
 202   if(!head || head->type != PIKE_T_INT)
 203     return default_value;
 204   return head->u.integer;
 205 }
 206 
 207 /*
 208  * php_roxen_low_ub_write() writes data to the client connection. Might be
 209  * rewritten to do more direct IO to save CPU and the need to lock the *
 210  * interpreter for better threading.
 211  */
 212 
 213 static int
 214 php_roxen_low_ub_write(const char *str, uint str_length TSRMLS_DC) {
 215   int sent_bytes = 0;
 216   struct pike_string *to_write = NULL;
 217 #ifdef ROXEN_USE_ZTS
 218   GET_THIS();
 219 #endif
 220 
 221   if(!MY_FD_OBJ->prog) {
 222     PG(connection_status) = PHP_CONNECTION_ABORTED;
 223     zend_bailout();
 224     return -1;
 225   }
 226   to_write = make_shared_binary_string(str, str_length);
 227   push_string(to_write);
 228   safe_apply(MY_FD_OBJ, "write", 1);
 229   if(Pike_sp[-1].type == PIKE_T_INT)
 230     sent_bytes = Pike_sp[-1].u.integer;
 231   pop_stack();
 232   if(sent_bytes != str_length) {
 233     /* This means the connection is closed. Dead. Gone. *sniff*  */
 234     php_handle_aborted_connection();
 235   }
 236   return sent_bytes;
 237 }
 238 
 239 /*
 240  * php_roxen_sapi_ub_write() calls php_roxen_low_ub_write in a Pike thread
 241  * safe manner.
 242  */
 243 
 244 static int
 245 php_roxen_sapi_ub_write(const char *str, uint str_length TSRMLS_DC)
 246 {
 247 #ifdef ROXEN_USE_ZTS
 248   GET_THIS();
 249 #endif
 250 
 251   int sent_bytes = 0, fd = MY_FD;
 252   if(fd)
 253   {
 254     for(sent_bytes=0;sent_bytes < str_length;)
 255     {
 256       int written;
 257       written = fd_write(fd, str + sent_bytes, str_length - sent_bytes);
 258       if(written < 0)
 259       {
 260         switch(errno)
 261         {
 262          default:
 263           /* This means the connection is closed. Dead. Gone. *sniff*  */
 264           PG(connection_status) = PHP_CONNECTION_ABORTED;
 265           zend_bailout();
 266           return sent_bytes;
 267          case EINTR: 
 268          case EWOULDBLOCK:
 269           continue;
 270         }
 271 
 272       } else {
 273         sent_bytes += written;
 274       }
 275     }
 276   } else {
 277     THREAD_SAFE_RUN(sent_bytes = php_roxen_low_ub_write(str, str_length TSRMLS_CC),
 278                     "write");
 279   }
 280   return sent_bytes;
 281 }
 282 
 283 /* php_roxen_set_header() sets a header in the header mapping. Called in a
 284  * thread safe manner from php_roxen_sapi_header_handler.
 285  */
 286 static void php_roxen_set_header(char *header_name, char *value, char *p)
 287 {
 288   struct svalue hsval;
 289   struct pike_string *hval, *ind, *hind;
 290   struct mapping *headermap;
 291   struct svalue *s_headermap;
 292 #ifdef ROXEN_USE_ZTS
 293   GET_THIS();
 294 #endif
 295   hval = make_shared_string(value);
 296   ind = make_shared_string(" _headers");
 297   hind = make_shared_binary_string(header_name,
 298                                    (int)(p - header_name));
 299 
 300   s_headermap = low_mapping_string_lookup(REQUEST_DATA, ind);
 301   if(!s_headermap)
 302   {
 303     struct svalue mappie;                                           
 304     mappie.type = PIKE_T_MAPPING;
 305     headermap = allocate_mapping(1);
 306     mappie.u.mapping = headermap;
 307     mapping_string_insert(REQUEST_DATA, ind, &mappie);
 308     free_mapping(headermap);
 309   } else
 310     headermap = s_headermap->u.mapping;
 311 
 312   hsval.type = PIKE_T_STRING;
 313   hsval.u.string = hval;
 314   mapping_string_insert(headermap, hind, &hsval);
 315 
 316   free_string(hval);
 317   free_string(ind);
 318   free_string(hind);
 319 }
 320 
 321 /*
 322  * php_roxen_sapi_header_handler() sets a HTTP reply header to be 
 323  * sent to the client.
 324  */
 325 static int
 326 php_roxen_sapi_header_handler(sapi_header_struct *sapi_header,
 327                               sapi_headers_struct *sapi_headers TSRMLS_DC)
 328 {
 329   char *header_name, *header_content, *p;
 330   header_name = sapi_header->header;
 331   header_content = p = strchr(header_name, ':');
 332   
 333   if(p) {
 334   do {
 335     header_content++;
 336   } while(*header_content == ' ');
 337     THREAD_SAFE_RUN(php_roxen_set_header(header_name, header_content, p), "header handler");
 338   }
 339   sapi_free_header(sapi_header);
 340   return 0;
 341 }
 342 
 343 /*
 344  * php_roxen_sapi_send_headers() flushes the headers to the client.
 345  * Called before real content is sent by PHP.
 346  */
 347 
 348 static int
 349 php_roxen_low_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
 350 {
 351   struct pike_string *ind;
 352   struct svalue *s_headermap;
 353 #ifdef ROXEN_USE_ZTS
 354   GET_THIS();
 355 #endif
 356 
 357   if(!MY_FD_OBJ->prog) {
 358     PG(connection_status) = PHP_CONNECTION_ABORTED;
 359     zend_bailout();
 360     return SAPI_HEADER_SEND_FAILED;
 361   }
 362   ind = make_shared_string(" _headers");  
 363   s_headermap = low_mapping_string_lookup(REQUEST_DATA, ind);
 364   free_string(ind);
 365   
 366   push_int(SG(sapi_headers).http_response_code);
 367   if(s_headermap && s_headermap->type == PIKE_T_MAPPING)
 368     ref_push_mapping(s_headermap->u.mapping);
 369   else
 370     push_int(0);
 371   safe_apply(MY_FD_OBJ, "send_headers", 2);
 372   pop_stack();
 373   
 374   return SAPI_HEADER_SENT_SUCCESSFULLY;
 375 }
 376 
 377 static int
 378 php_roxen_sapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
 379 {
 380   int res = 0;
 381   THREAD_SAFE_RUN(res = php_roxen_low_send_headers(sapi_headers TSRMLS_CC), "send headers");
 382   return res;
 383 }
 384 
 385 /*
 386  * php_roxen_sapi_read_post() reads a specified number of bytes from
 387  * the client. Used for POST/PUT requests.
 388  */
 389 
 390 INLINE static int php_roxen_low_read_post(char *buf, uint count_bytes)
 391 {
 392   uint total_read = 0;
 393 #ifdef ROXEN_USE_ZTS
 394   GET_THIS();
 395 #endif
 396   TSRMLS_FETCH();
 397   
 398   if(!MY_FD_OBJ->prog)
 399   {
 400     PG(connection_status) = PHP_CONNECTION_ABORTED;
 401     zend_bailout();
 402     return -1;
 403   }
 404   push_int(count_bytes);
 405   safe_apply(MY_FD_OBJ, "read_post", 1);
 406   if(Pike_sp[-1].type == PIKE_T_STRING) {
 407     MEMCPY(buf, Pike_sp[-1].u.string->str,
 408            (total_read = Pike_sp[-1].u.string->len));
 409     buf[total_read] = '\0';
 410   } else
 411     total_read = 0;
 412   pop_stack();
 413   return total_read;
 414 }
 415 
 416 static int
 417 php_roxen_sapi_read_post(char *buf, uint count_bytes TSRMLS_DC)
 418 {
 419   uint total_read = 0;
 420   THREAD_SAFE_RUN(total_read = php_roxen_low_read_post(buf, count_bytes), "read post");
 421   return total_read;
 422 }
 423 
 424 /* 
 425  * php_roxen_sapi_read_cookies() returns the Cookie header from
 426  * the HTTP request header
 427  */
 428         
 429 static char *
 430 php_roxen_sapi_read_cookies(TSRMLS_D)
 431 {
 432   char *cookies;
 433   cookies = lookup_string_header("HTTP_COOKIE", NULL);
 434   return cookies;
 435 }
 436 
 437 static void php_info_roxen(ZEND_MODULE_INFO_FUNC_ARGS)
 438 {
 439   /*  char buf[512]; */
 440   php_info_print_table_start();
 441   php_info_print_table_row(2, "SAPI module version", "$Id$");
 442   /*  php_info_print_table_row(2, "Build date", Ns_InfoBuildDate());
 443       php_info_print_table_row(2, "Config file path", Ns_InfoConfigFile());
 444       php_info_print_table_row(2, "Error Log path", Ns_InfoErrorLog());
 445       php_info_print_table_row(2, "Installation path", Ns_InfoHomePath());
 446       php_info_print_table_row(2, "Hostname of server", Ns_InfoHostname());
 447       php_info_print_table_row(2, "Source code label", Ns_InfoLabel());
 448       php_info_print_table_row(2, "Server platform", Ns_InfoPlatform());
 449       snprintf(buf, 511, "%s/%s", Ns_InfoServerName(), Ns_InfoServerVersion());
 450       php_info_print_table_row(2, "Server version", buf);
 451       snprintf(buf, 511, "%d day(s), %02d:%02d:%02d", 
 452       uptime / 86400,
 453       (uptime / 3600) % 24,
 454       (uptime / 60) % 60,
 455       uptime % 60);
 456       php_info_print_table_row(2, "Server uptime", buf);
 457   */
 458   php_info_print_table_end();
 459 }
 460 
 461 static zend_module_entry php_roxen_module = {
 462   STANDARD_MODULE_HEADER,
 463   "Roxen",
 464   NULL,
 465   NULL,
 466   NULL,
 467   NULL,
 468   NULL,
 469   php_info_roxen,
 470   NULL,
 471   STANDARD_MODULE_PROPERTIES
 472 };
 473 
 474 static int php_roxen_startup(sapi_module_struct *sapi_module)
 475 {
 476   if(php_module_startup(sapi_module, &php_roxen_module, 1) == FAILURE) {
 477     return FAILURE;
 478   } else {
 479     return SUCCESS;
 480   }
 481 }
 482 
 483 /* this structure is static (as in "it does not change") */
 484 
 485 static sapi_module_struct roxen_sapi_module = {
 486   "roxen",
 487   "Roxen",
 488   php_roxen_startup,                    /* startup */
 489   php_module_shutdown_wrapper,          /* shutdown */
 490   NULL,                                 /* activate */
 491   NULL,                                 /* deactivate */
 492   php_roxen_sapi_ub_write,              /* unbuffered write */
 493   NULL,                                 /* flush */
 494   NULL,                                 /* get uid */
 495   NULL,                                 /* getenv */
 496   php_error,                            /* error handler */
 497   php_roxen_sapi_header_handler,        /* header handler */
 498   php_roxen_sapi_send_headers,          /* send headers handler */
 499   NULL,                                 /* send header handler */
 500   php_roxen_sapi_read_post,             /* read POST data */
 501   php_roxen_sapi_read_cookies,          /* read Cookies */
 502   NULL,                                 /* register server variables */
 503   NULL,                                 /* Log message */
 504   NULL,                                 /* Get request time */
 505   NULL,                                 /* Child terminate */
 506 
 507   STANDARD_SAPI_MODULE_PROPERTIES
 508 };
 509 
 510 /*
 511  * php_roxen_hash_environment() populates the php script environment
 512  * with a number of variables. HTTP_* variables are created for
 513  * the HTTP header data, so that a script can access these.
 514  */
 515 #define ADD_STRING(name)                                                                                \
 516         MAKE_STD_ZVAL(zvalue);                                                                          \
 517         zvalue->type = IS_STRING;                                                                               \
 518         zvalue->value.str.len = strlen(buf);                                                    \
 519         zvalue->value.str.val = estrndup(buf, zvalue->value.str.len);   \
 520         zend_hash_update(&EG(symbol_table), name, sizeof(name),         \
 521                         &zvalue, sizeof(zval *), NULL)
 522 
 523 static void
 524 php_roxen_hash_environment(TSRMLS_D)
 525 {
 526   int i;
 527   char buf[512];
 528   zval *zvalue;
 529   struct svalue *headers;
 530   struct pike_string *sind;
 531   struct array *indices;
 532   struct svalue *ind, *val;
 533 #ifdef ROXEN_USE_ZTS
 534   GET_THIS();
 535 #endif
 536   sind = make_shared_string("env");
 537   headers = low_mapping_string_lookup(REQUEST_DATA, sind);
 538   free_string(sind);
 539   if(headers && headers->type == PIKE_T_MAPPING) {
 540     indices = mapping_indices(headers->u.mapping);
 541     for(i = 0; i < indices->size; i++) {
 542       ind = &indices->item[i];
 543       val = low_mapping_lookup(headers->u.mapping, ind);
 544       if(ind && ind->type == PIKE_T_STRING &&
 545          val && val->type == PIKE_T_STRING) {
 546         int buf_len;
 547         buf_len = MIN(511, ind->u.string->len);
 548         strncpy(buf, ind->u.string->str, buf_len);
 549         buf[buf_len] = '\0'; /* Terminate correctly */
 550         MAKE_STD_ZVAL(zvalue);
 551         zvalue->type = IS_STRING;
 552         zvalue->value.str.len = val->u.string->len;
 553         zvalue->value.str.val = estrndup(val->u.string->str, zvalue->value.str.len);
 554         
 555         zend_hash_update(&EG(symbol_table), buf, buf_len + 1, &zvalue, sizeof(zval *), NULL);
 556       }
 557     }
 558     free_array(indices);
 559   }
 560   
 561   /*
 562     MAKE_STD_ZVAL(zvalue);
 563     zvalue->type = IS_LONG;
 564     zvalue->value.lval = Ns_InfoBootTime();
 565     zend_hash_update(&EG(symbol_table), "SERVER_BOOTTIME", sizeof("SERVER_BOOTTIME"), &zvalue, sizeof(zval *), NULL);
 566   */
 567 }
 568 
 569 /*
 570  * php_roxen_module_main() is called by the per-request handler and
 571  * "executes" the script
 572  */
 573 
 574 static int php_roxen_module_main(TSRMLS_D)
 575 {
 576   int res, len;
 577   char *dir;
 578   zend_file_handle file_handle;
 579 #ifdef ROXEN_USE_ZTS
 580   GET_THIS();
 581 #endif
 582 
 583   file_handle.type = ZEND_HANDLE_FILENAME;
 584   file_handle.filename = THIS->filename;
 585   file_handle.free_filename = 0;
 586   file_handle.opened_path = NULL;
 587 
 588   THREADS_ALLOW();
 589   res = php_request_startup(TSRMLS_C);
 590   THREADS_DISALLOW();
 591   if(res == FAILURE) {
 592     return 0;
 593   }
 594   php_roxen_hash_environment(TSRMLS_C);
 595   THREADS_ALLOW();
 596   php_execute_script(&file_handle TSRMLS_CC);
 597   php_request_shutdown(NULL);
 598   THREADS_DISALLOW();
 599   return 1;
 600 }
 601 
 602 /*
 603  * The php_roxen_request_handler() is called per request and handles
 604  * everything for one request.
 605  */
 606 
 607 void f_php_roxen_request_handler(INT32 args)
 608 {
 609   struct object *my_fd_obj;
 610   struct mapping *request_data;
 611   struct svalue *done_callback, *raw_fd;
 612   struct pike_string *script, *ind;
 613   int status = 1;
 614 #ifdef ROXEN_USE_ZTS
 615   GET_THIS();
 616 #endif
 617   TSRMLS_FETCH();
 618 
 619   if(current_thread == th_self())
 620     php_error(E_WARNING, "PHP5.Interpreter->run: Tried to run a PHP-script from a PHP "
 621           "callback!");
 622   get_all_args("PHP5.Interpreter->run", args, "%S%m%O%*", &script,
 623                &request_data, &my_fd_obj, &done_callback);
 624   if(done_callback->type != PIKE_T_FUNCTION) 
 625     php_error(E_WARNING, "PHP5.Interpreter->run: Bad argument 4, expected function.\n");
 626   PHP_LOCK(THIS); /* Need to lock here or reusing the same object might cause
 627                        * problems in changing stuff in that object */
 628 #ifndef ROXEN_USE_ZTS
 629   GET_THIS();
 630 #endif
 631   THIS->request_data = request_data;
 632   THIS->my_fd_obj = my_fd_obj;
 633   THIS->filename = script->str;
 634   current_thread = th_self();
 635   SG(request_info).query_string = lookup_string_header("QUERY_STRING", 0);
 636   SG(server_context) = (void *)1; /* avoid server_context == NULL */
 637 
 638   /* path_translated is apparently the absolute path to the file, not
 639      the translated PATH_INFO
 640   */
 641   SG(request_info).path_translated =
 642     lookup_string_header("SCRIPT_FILENAME", NULL);
 643   SG(request_info).request_uri = lookup_string_header("DOCUMENT_URI", NULL);
 644   if(!SG(request_info).request_uri)
 645     SG(request_info).request_uri = lookup_string_header("SCRIPT_NAME", NULL);
 646   SG(request_info).request_method = lookup_string_header("REQUEST_METHOD", "GET");
 647   SG(request_info).content_length = lookup_integer_header("HTTP_CONTENT_LENGTH", 0);
 648   SG(request_info).content_type = lookup_string_header("HTTP_CONTENT_TYPE", NULL);
 649   SG(sapi_headers).http_response_code = 200;
 650 
 651   /* FIXME: Check for auth stuff needs to be fixed... */ 
 652   SG(request_info).auth_user = NULL; 
 653   SG(request_info).auth_password = NULL;
 654   
 655   ind = make_shared_binary_string("my_fd", 5);
 656   raw_fd = low_mapping_string_lookup(THIS->request_data, ind);
 657   if(raw_fd && raw_fd->type == PIKE_T_OBJECT)
 658   {
 659     int fd = fd_from_object(raw_fd->u.object);
 660     if(fd == -1)
 661       php_error(E_WARNING, "PHP5.Interpreter->run: my_fd object not open or not an FD.\n");
 662     THIS->my_fd = fd;
 663   } else
 664     THIS->my_fd = 0;
 665   
 666   status = php_roxen_module_main(TSRMLS_C);
 667   current_thread = -1;
 668   
 669   apply_svalue(done_callback, 0);
 670   pop_stack();
 671   pop_n_elems(args);
 672   push_int(status);
 673   PHP_UNLOCK(THIS);
 674 }
 675 
 676 
 677 /* Clear the object global struct */
 678 static void clear_struct(struct object *o)
 679 {
 680   MEMSET(Pike_fp->current_storage, 0, sizeof(php_roxen_request));
 681 }
 682 
 683 
 684 /*
 685  * pike_module_init() is called by Pike once at startup
 686  *
 687  * This functions allocates basic structures
 688  */
 689 
 690 void pike_module_init( void )
 691 {
 692   if (!roxen_php_initialized) {
 693 #ifdef ZTS
 694     tsrm_startup(1, 1, 0, NULL);
 695 #ifdef ROXEN_USE_ZTS
 696     ts_allocate_id(&roxen_globals_id, sizeof(php_roxen_request), NULL, NULL);
 697 #endif   
 698 #endif
 699     sapi_startup(&roxen_sapi_module);
 700     /*php_roxen_startup(&roxen_sapi_module); removed - should be called from SAPI activation*/
 701     roxen_php_initialized = 1;
 702     PHP_INIT_LOCK();
 703   }
 704   start_new_program(); /* Text */
 705   ADD_STORAGE(php_roxen_request);
 706   set_init_callback(clear_struct);
 707   pike_add_function("run", f_php_roxen_request_handler,
 708                     "function(string, mapping, object, function:int)", 0);
 709   add_program_constant("Interpreter", (php_program = end_program()), 0);
 710 }
 711 
 712 /*
 713  * pike_module_exit() performs the last steps before the
 714  * server exists. Shutdowns basic services and frees memory
 715  */
 716 
 717 void pike_module_exit(void)
 718 {
 719   roxen_php_initialized = 0;
 720   roxen_sapi_module.shutdown(&roxen_sapi_module);
 721   if(php_program)  free_program(php_program);
 722 #ifdef ZTS
 723   tsrm_shutdown();
 724 #endif
 725   PHP_DESTROY();
 726 }
 727 #endif

/* [<][>][^][v][top][bottom][index][help] */