File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / sapi / nsapi / nsapi.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:04:02 2014 UTC (10 years ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

    1: /*
    2:    +----------------------------------------------------------------------+
    3:    | PHP Version 5                                                        |
    4:    +----------------------------------------------------------------------+
    5:    | Copyright (c) 1997-2014 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: Jayakumar Muthukumarasamy <jk@kasenna.com>                   |
   16:    |         Uwe Schindler <uwe@thetaphi.de>                              |
   17:    +----------------------------------------------------------------------+
   18: */
   19: 
   20: /* $Id: nsapi.c,v 1.1.1.4 2014/06/15 20:04:02 misho Exp $ */
   21: 
   22: /*
   23:  * PHP includes
   24:  */
   25: #define NSAPI 1
   26: 
   27: #ifdef HAVE_CONFIG_H
   28: #include "config.h"
   29: #endif
   30: 
   31: #include "php.h"
   32: #include "php_variables.h"
   33: #include "ext/standard/info.h"
   34: #include "php_ini.h"
   35: #include "php_globals.h"
   36: #include "SAPI.h"
   37: #include "php_main.h"
   38: #include "php_version.h"
   39: #include "TSRM.h"
   40: #include "ext/standard/php_standard.h"
   41: #include <sys/types.h>
   42: #include <sys/stat.h>
   43: 
   44: #ifndef RTLD_DEFAULT
   45: #define RTLD_DEFAULT NULL
   46: #endif
   47: 
   48: /*
   49:  * If neither XP_UNIX not XP_WIN32 is defined use PHP_WIN32
   50:  */
   51: #if !defined(XP_UNIX) && !defined(XP_WIN32)
   52: #ifdef PHP_WIN32
   53: #define XP_WIN32
   54: #else
   55: #define XP_UNIX
   56: #endif
   57: #endif
   58: 
   59: /*
   60:  * The manual define of HPUX is to fix bug #46020, nsapi.h needs this to detect HPUX
   61:  */
   62: #ifdef __hpux
   63: #define HPUX
   64: #endif
   65:  
   66: /*
   67:  * NSAPI includes
   68:  */
   69: #include "nsapi.h"
   70: 
   71: /* fix for gcc4 visibility issue */
   72: #ifndef PHP_WIN32
   73: # undef NSAPI_PUBLIC
   74: # define NSAPI_PUBLIC PHPAPI
   75: #endif
   76: 
   77: #define NSLS_D		struct nsapi_request_context *request_context
   78: #define NSLS_DC		, NSLS_D
   79: #define NSLS_C		request_context
   80: #define NSLS_CC		, NSLS_C
   81: #define NSG(v)		(request_context->v)
   82: 
   83: /*
   84:  * ZTS needs to be defined for NSAPI to work
   85:  */
   86: #if !defined(ZTS)
   87: #error "NSAPI module needs ZTS to be defined"
   88: #endif
   89: 
   90: /*
   91:  * Structure to encapsulate the NSAPI request in SAPI
   92:  */
   93: typedef struct nsapi_request_context {
   94: 	pblock	*pb;
   95: 	Session	*sn;
   96: 	Request	*rq;
   97: 	int	read_post_bytes;
   98: 	char *path_info;
   99: 	int fixed_script; /* 0 if script is from URI, 1 if script is from "script" parameter */
  100: 	short http_error; /* 0 in normal mode; for errors the HTTP error code */
  101: } nsapi_request_context;
  102: 
  103: /*
  104:  * Mappings between NSAPI names and environment variables. This
  105:  * mapping was obtained from the sample programs at the iplanet
  106:  * website.
  107:  */
  108: typedef struct nsapi_equiv {
  109: 	const char *env_var;
  110: 	const char *nsapi_eq;
  111: } nsapi_equiv;
  112: 
  113: static nsapi_equiv nsapi_reqpb[] = {
  114: 	{ "QUERY_STRING",		"query" },
  115: 	{ "REQUEST_LINE",		"clf-request" },
  116: 	{ "REQUEST_METHOD",		"method" },
  117: 	{ "PHP_SELF",			"uri" },
  118: 	{ "SERVER_PROTOCOL",	"protocol" }
  119: };
  120: static size_t nsapi_reqpb_size = sizeof(nsapi_reqpb)/sizeof(nsapi_reqpb[0]);
  121: 
  122: static nsapi_equiv nsapi_vars[] = {
  123: 	{ "AUTH_TYPE",			"auth-type" },
  124: 	{ "CLIENT_CERT",		"auth-cert" },
  125: 	{ "REMOTE_USER",		"auth-user" }
  126: };
  127: static size_t nsapi_vars_size = sizeof(nsapi_vars)/sizeof(nsapi_vars[0]);
  128: 
  129: static nsapi_equiv nsapi_client[] = {
  130: 	{ "HTTPS_KEYSIZE",		"keysize" },
  131: 	{ "HTTPS_SECRETSIZE",	"secret-keysize" },
  132: 	{ "REMOTE_ADDR",		"ip" },
  133: 	{ "REMOTE_HOST",		"ip" }
  134: };
  135: static size_t nsapi_client_size = sizeof(nsapi_client)/sizeof(nsapi_client[0]);
  136: 
  137: /* this parameters to "Service"/"Error" are NSAPI ones which should not be php.ini keys and are excluded */
  138: static char *nsapi_exclude_from_ini_entries[] = { "fn", "type", "method", "directive", "code", "reason", "script", "bucket", NULL };
  139: 
  140: static void nsapi_free(void *addr)
  141: {
  142: 	if (addr != NULL) {
  143: 		FREE(addr);
  144: 	}
  145: }
  146: 
  147: 
  148: /*******************/
  149: /* PHP module part */
  150: /*******************/
  151: 
  152: PHP_MINIT_FUNCTION(nsapi);
  153: PHP_MSHUTDOWN_FUNCTION(nsapi);
  154: PHP_RINIT_FUNCTION(nsapi);
  155: PHP_RSHUTDOWN_FUNCTION(nsapi);
  156: PHP_MINFO_FUNCTION(nsapi);
  157: 
  158: PHP_FUNCTION(nsapi_virtual);
  159: PHP_FUNCTION(nsapi_request_headers);
  160: PHP_FUNCTION(nsapi_response_headers);
  161: 
  162: ZEND_BEGIN_MODULE_GLOBALS(nsapi)
  163: 	long read_timeout;
  164: ZEND_END_MODULE_GLOBALS(nsapi)
  165: 
  166: ZEND_DECLARE_MODULE_GLOBALS(nsapi)
  167: 
  168: #define NSAPI_G(v) TSRMG(nsapi_globals_id, zend_nsapi_globals *, v)
  169: 
  170: 
  171: /* {{{ arginfo */
  172: ZEND_BEGIN_ARG_INFO_EX(arginfo_nsapi_virtual, 0, 0, 1)
  173: 	ZEND_ARG_INFO(0, uri)
  174: ZEND_END_ARG_INFO()
  175: 
  176: ZEND_BEGIN_ARG_INFO(arginfo_nsapi_request_headers, 0)
  177: ZEND_END_ARG_INFO()
  178: 
  179: ZEND_BEGIN_ARG_INFO(arginfo_nsapi_response_headers, 0)
  180: ZEND_END_ARG_INFO()
  181: /* }}} */
  182: 
  183: /* {{{ nsapi_functions[]
  184:  *
  185:  * Every user visible function must have an entry in nsapi_functions[].
  186:  */
  187: const zend_function_entry nsapi_functions[] = {
  188: 	PHP_FE(nsapi_virtual,	arginfo_nsapi_virtual)						/* Make subrequest */
  189: 	PHP_FALIAS(virtual, nsapi_virtual, arginfo_nsapi_virtual)			/* compatibility */
  190: 	PHP_FE(nsapi_request_headers, arginfo_nsapi_request_headers)		/* get request headers */
  191: 	PHP_FALIAS(getallheaders, nsapi_request_headers, arginfo_nsapi_request_headers)	/* compatibility */
  192: 	PHP_FALIAS(apache_request_headers, nsapi_request_headers, arginfo_nsapi_request_headers)	/* compatibility */
  193: 	PHP_FE(nsapi_response_headers, arginfo_nsapi_response_headers)		/* get response headers */
  194: 	PHP_FALIAS(apache_response_headers, nsapi_response_headers, arginfo_nsapi_response_headers)	/* compatibility */
  195: 	{NULL, NULL, NULL}
  196: };
  197: /* }}} */
  198: 
  199: /* {{{ nsapi_module_entry
  200:  */
  201: zend_module_entry nsapi_module_entry = {
  202: 	STANDARD_MODULE_HEADER,
  203: 	"nsapi",
  204: 	nsapi_functions,
  205: 	PHP_MINIT(nsapi),
  206: 	PHP_MSHUTDOWN(nsapi),
  207: 	NULL,
  208: 	NULL,
  209: 	PHP_MINFO(nsapi),
  210: 	NO_VERSION_YET,
  211: 	STANDARD_MODULE_PROPERTIES
  212: };
  213: /* }}} */
  214: 
  215: /* {{{ PHP_INI
  216:  */
  217: PHP_INI_BEGIN()
  218:     STD_PHP_INI_ENTRY("nsapi.read_timeout", "60", PHP_INI_ALL, OnUpdateLong, read_timeout, zend_nsapi_globals, nsapi_globals)
  219: PHP_INI_END()
  220: /* }}} */
  221: 
  222: /* newer servers hide this functions from the programmer so redefine the functions dynamically
  223:    thanks to Chris Elving from Sun for the function declarations */
  224: typedef int (*nsapi_servact_prototype)(Session *sn, Request *rq);
  225: nsapi_servact_prototype nsapi_servact_uri2path = NULL;
  226: nsapi_servact_prototype nsapi_servact_pathchecks = NULL;
  227: nsapi_servact_prototype nsapi_servact_fileinfo = NULL;
  228: nsapi_servact_prototype nsapi_servact_service = NULL;
  229: 
  230: #ifdef PHP_WIN32
  231: /* The following dll-names for nsapi are in use at this time. The undocumented
  232:  * servact_* functions are always in the newest one, older ones are supported by
  233:  * the server only by wrapping the function table nothing else. So choose
  234:  * the newest one found in process space for dynamic linking */
  235: static char *nsapi_dlls[] = { "ns-httpd40.dll", "ns-httpd36.dll", "ns-httpd35.dll", "ns-httpd30.dll", NULL };
  236: /* if user specifies an other dll name by server_lib parameter 
  237:  * it is placed in the following variable and only this DLL is
  238:  * checked for the servact_* functions */
  239: char *nsapi_dll = NULL;
  240: #endif
  241: 
  242: /* {{{ php_nsapi_init_dynamic_symbols
  243:  */
  244: static void php_nsapi_init_dynamic_symbols(void)
  245: {
  246: 	/* find address of internal NSAPI functions */
  247: #ifdef PHP_WIN32
  248: 	register int i;
  249: 	DL_HANDLE module = NULL;
  250: 	if (nsapi_dll) {
  251: 		/* try user specified server_lib */
  252: 		module = GetModuleHandle(nsapi_dll);
  253: 		if (!module) {
  254: 			log_error(LOG_WARN, "php5_init", NULL, NULL, "Cannot find DLL specified by server_lib parameter: %s", nsapi_dll);
  255: 		}
  256: 	} else {
  257: 		/* find a LOADED dll module from nsapi_dlls */
  258: 		for (i=0; nsapi_dlls[i]; i++) {
  259: 			if (module = GetModuleHandle(nsapi_dlls[i])) {
  260: 				break;
  261: 			}
  262: 		}
  263: 	}
  264: 	if (!module) return;
  265: #else
  266: 	DL_HANDLE module = RTLD_DEFAULT;
  267: #endif
  268: 	nsapi_servact_uri2path = (nsapi_servact_prototype)DL_FETCH_SYMBOL(module, "INTservact_uri2path");
  269: 	nsapi_servact_pathchecks = (nsapi_servact_prototype)DL_FETCH_SYMBOL(module, "INTservact_pathchecks");
  270: 	nsapi_servact_fileinfo = (nsapi_servact_prototype)DL_FETCH_SYMBOL(module, "INTservact_fileinfo");
  271: 	nsapi_servact_service = (nsapi_servact_prototype)DL_FETCH_SYMBOL(module, "INTservact_service");
  272: 	if (!(nsapi_servact_uri2path && nsapi_servact_pathchecks && nsapi_servact_fileinfo && nsapi_servact_service)) {
  273: 		/* not found - could be cause they are undocumented */
  274: 		nsapi_servact_uri2path = NULL;
  275: 		nsapi_servact_pathchecks = NULL;
  276: 		nsapi_servact_fileinfo = NULL;
  277: 		nsapi_servact_service = NULL;
  278: 	}
  279: }
  280: /* }}} */
  281: 
  282: /* {{{ php_nsapi_init_globals
  283:  */
  284: static void php_nsapi_init_globals(zend_nsapi_globals *nsapi_globals)
  285: {
  286: 	nsapi_globals->read_timeout = 60;
  287: }
  288: /* }}} */
  289: 
  290: /* {{{ PHP_MINIT_FUNCTION
  291:  */
  292: PHP_MINIT_FUNCTION(nsapi)
  293: {
  294: 	php_nsapi_init_dynamic_symbols();
  295: 	ZEND_INIT_MODULE_GLOBALS(nsapi, php_nsapi_init_globals, NULL);
  296: 	REGISTER_INI_ENTRIES();
  297: 	return SUCCESS;
  298: }
  299: /* }}} */
  300: 
  301: /* {{{ PHP_MSHUTDOWN_FUNCTION
  302:  */
  303: PHP_MSHUTDOWN_FUNCTION(nsapi)
  304: {
  305: 	UNREGISTER_INI_ENTRIES();
  306: 	return SUCCESS;
  307: }
  308: /* }}} */
  309: 
  310: /* {{{ PHP_MINFO_FUNCTION
  311:  */
  312: PHP_MINFO_FUNCTION(nsapi)
  313: {
  314: 	php_info_print_table_start();
  315: 	php_info_print_table_row(2, "NSAPI Module Revision", "$Id: nsapi.c,v 1.1.1.4 2014/06/15 20:04:02 misho Exp $");
  316: 	php_info_print_table_row(2, "Server Software", system_version());
  317: 	php_info_print_table_row(2, "Sub-requests with nsapi_virtual()",
  318: 	 (nsapi_servact_service)?((zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0))?"not supported with zlib.output_compression":"enabled"):"not supported on this platform" );
  319: 	php_info_print_table_end();
  320: 
  321: 	DISPLAY_INI_ENTRIES();
  322: }
  323: /* }}} */
  324: 
  325: /* {{{ proto bool nsapi_virtual(string uri)
  326:    Perform an NSAPI sub-request */
  327: /* This function is equivalent to <!--#include virtual...-->
  328:  * in SSI. It does an NSAPI sub-request. It is useful
  329:  * for including CGI scripts or .shtml files, or anything else
  330:  * that you'd parse through webserver.
  331:  */
  332: PHP_FUNCTION(nsapi_virtual)
  333: {
  334: 	int uri_len,rv;
  335: 	char *uri,*value;
  336: 	Request *rq;
  337: 	nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
  338: 
  339: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &uri, &uri_len) == FAILURE) {
  340: 		return;
  341: 	}
  342: 
  343: 	if (!nsapi_servact_service) {
  344: 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include uri '%s' - Sub-requests not supported on this platform", uri);
  345: 		RETURN_FALSE;
  346: 	} else if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0)) {
  347: 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include uri '%s' - Sub-requests do not work with zlib.output_compression", uri);
  348: 		RETURN_FALSE;
  349: 	} else {
  350: 		php_output_end_all(TSRMLS_C);
  351: 		php_header(TSRMLS_C);
  352: 
  353: 		/* do the sub-request */
  354: 		/* thanks to Chris Elving from Sun for this code sniplet */
  355: 		if ((rq = request_restart_internal(uri, NULL)) == NULL) {
  356: 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include uri '%s' - Internal request creation failed", uri);
  357: 			RETURN_FALSE;
  358: 		}
  359: 
  360: 		/* insert host of current request to get page from same vhost */
  361: 		param_free(pblock_remove("host", rq->headers));
  362: 		if (value = pblock_findval("host", rc->rq->headers)) {
  363: 			pblock_nvinsert("host", value, rq->headers);
  364: 		}
  365: 
  366: 		/* go through the normal request stages as given in obj.conf,
  367: 		   but leave out the logging/error section */
  368: 		do {
  369: 			rv = (*nsapi_servact_uri2path)(rc->sn, rq);
  370: 			if (rv != REQ_PROCEED) {
  371: 				continue;
  372: 			}
  373: 
  374: 			rv = (*nsapi_servact_pathchecks)(rc->sn, rq);
  375: 			if (rv != REQ_PROCEED) {
  376: 				continue;
  377: 			}
  378: 
  379: 			rv = (*nsapi_servact_fileinfo)(rc->sn, rq);
  380: 			if (rv != REQ_PROCEED) {
  381: 				continue;
  382: 			}
  383: 
  384: 			rv = (*nsapi_servact_service)(rc->sn, rq);
  385: 		} while (rv == REQ_RESTART);
  386: 
  387: 		if (rq->status_num != 200) {
  388: 			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include uri '%s' - HTTP status code %d during subrequest", uri, rq->status_num);
  389: 			request_free(rq);
  390: 			RETURN_FALSE;
  391: 		}
  392: 
  393: 		request_free(rq);
  394: 
  395: 		RETURN_TRUE;
  396: 	}
  397: }
  398: /* }}} */
  399: 
  400: /* {{{ proto array nsapi_request_headers(void)
  401:    Get all headers from the request */
  402: PHP_FUNCTION(nsapi_request_headers)
  403: {
  404: 	register int i;
  405: 	struct pb_entry *entry;
  406: 	nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
  407: 
  408: 	if (zend_parse_parameters_none() == FAILURE) {
  409: 		return;
  410: 	}
  411: 	
  412: 	array_init(return_value);
  413: 
  414: 	for (i=0; i < rc->rq->headers->hsize; i++) {
  415: 		entry=rc->rq->headers->ht[i];
  416: 		while (entry) {
  417: 			add_assoc_string(return_value, entry->param->name, entry->param->value, 1);
  418: 			entry=entry->next;
  419: 		}
  420:   	}
  421: }
  422: /* }}} */
  423: 
  424: /* {{{ proto array nsapi_response_headers(void)
  425:    Get all headers from the response */
  426: PHP_FUNCTION(nsapi_response_headers)
  427: {
  428: 	register int i;
  429: 	struct pb_entry *entry;
  430: 	nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
  431: 
  432: 	if (zend_parse_parameters_none() == FAILURE) {
  433: 		return;
  434: 	}
  435: 	
  436: 	array_init(return_value);
  437: 
  438: 	for (i=0; i < rc->rq->srvhdrs->hsize; i++) {
  439: 		entry=rc->rq->srvhdrs->ht[i];
  440: 		while (entry) {
  441: 			add_assoc_string(return_value, entry->param->name, entry->param->value, 1);
  442: 			entry=entry->next;
  443: 		}
  444:   	}
  445: }
  446: /* }}} */
  447: 
  448: 
  449: /*************/
  450: /* SAPI part */
  451: /*************/
  452: 
  453: static int sapi_nsapi_ub_write(const char *str, unsigned int str_length TSRMLS_DC)
  454: {
  455: 	int retval;
  456: 	nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
  457: 	
  458: 	if (!SG(headers_sent)) {
  459: 		sapi_send_headers(TSRMLS_C);
  460: 	}
  461: 
  462: 	retval = net_write(rc->sn->csd, (char *)str, str_length);
  463: 	if (retval == IO_ERROR /* -1 */ || retval == IO_EOF /* 0 */) {
  464: 		php_handle_aborted_connection();
  465: 	}
  466: 	return retval;
  467: }
  468: 
  469: /* modified version of apache2 */
  470: static void sapi_nsapi_flush(void *server_context)
  471: {
  472: 	nsapi_request_context *rc = (nsapi_request_context *)server_context;
  473: 	TSRMLS_FETCH();
  474: 	
  475: 	if (!rc) {
  476: 		/* we have no context, so no flushing needed. This fixes a SIGSEGV on shutdown */
  477: 		return;
  478: 	}
  479: 
  480: 	if (!SG(headers_sent)) {
  481: 		sapi_send_headers(TSRMLS_C);
  482: 	}
  483: 
  484: 	/* flushing is only supported in iPlanet servers from version 6.1 on, make it conditional */
  485: #if NSAPI_VERSION >= 302
  486: 	if (net_flush(rc->sn->csd) < 0) {
  487: 		php_handle_aborted_connection();
  488: 	}
  489: #endif
  490: }
  491: 
  492: /* callback for zend_llist_apply on SAPI_HEADER_DELETE_ALL operation */
  493: static int php_nsapi_remove_header(sapi_header_struct *sapi_header TSRMLS_DC)
  494: {
  495: 	char *header_name, *p;
  496: 	nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
  497: 	
  498: 	/* copy the header, because NSAPI needs reformatting and we do not want to change the parameter */
  499: 	header_name = pool_strdup(rc->sn->pool, sapi_header->header);
  500: 
  501: 	/* extract name, this works, if only the header without ':' is given, too */
  502: 	if (p = strchr(header_name, ':')) {
  503: 		*p = 0;
  504: 	}
  505: 	
  506: 	/* header_name to lower case because NSAPI reformats the headers and wants lowercase */
  507: 	for (p=header_name; *p; p++) {
  508: 		*p=tolower(*p);
  509: 	}
  510: 	
  511: 	/* remove the header */
  512: 	param_free(pblock_remove(header_name, rc->rq->srvhdrs));
  513: 	pool_free(rc->sn->pool, header_name);
  514: 	
  515: 	return ZEND_HASH_APPLY_KEEP;
  516: }
  517: 
  518: static int sapi_nsapi_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC)
  519: {
  520: 	char *header_name, *header_content, *p;
  521: 	nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
  522: 
  523: 	switch(op) {
  524: 		case SAPI_HEADER_DELETE_ALL:
  525: 			/* this only deletes headers set or overwritten by PHP, headers previously set by NSAPI are left intact */
  526: 			zend_llist_apply(&sapi_headers->headers, (llist_apply_func_t) php_nsapi_remove_header TSRMLS_CC);
  527: 			return 0;
  528: 
  529: 		case SAPI_HEADER_DELETE:
  530: 			/* reuse the zend_llist_apply callback function for this, too */
  531: 			php_nsapi_remove_header(sapi_header TSRMLS_CC);
  532: 			return 0;
  533: 
  534: 		case SAPI_HEADER_ADD:
  535: 		case SAPI_HEADER_REPLACE:
  536: 			/* copy the header, because NSAPI needs reformatting and we do not want to change the parameter */
  537: 			header_name = pool_strdup(rc->sn->pool, sapi_header->header);
  538: 
  539: 			/* split header and align pointer for content */
  540: 			header_content = strchr(header_name, ':');
  541: 			if (header_content) {
  542: 				*header_content = 0;
  543: 				do {
  544: 					header_content++;
  545: 				} while (*header_content==' ');
  546: 				
  547: 				/* header_name to lower case because NSAPI reformats the headers and wants lowercase */
  548: 				for (p=header_name; *p; p++) {
  549: 					*p=tolower(*p);
  550: 				}
  551: 
  552: 				/* if REPLACE, remove first.  "Content-type" is always removed, as SAPI has a bug according to this */
  553: 				if (op==SAPI_HEADER_REPLACE || strcmp(header_name, "content-type")==0) {
  554: 					param_free(pblock_remove(header_name, rc->rq->srvhdrs));
  555: 				}
  556: 				/* ADD header to nsapi table */
  557: 				pblock_nvinsert(header_name, header_content, rc->rq->srvhdrs);
  558: 			}
  559: 			
  560: 			pool_free(rc->sn->pool, header_name);
  561: 			return SAPI_HEADER_ADD;
  562: 			
  563: 		default:
  564: 			return 0;
  565: 	}
  566: }
  567: 
  568: static int sapi_nsapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
  569: {
  570: 	int retval;
  571: 	nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
  572: 
  573: 	if (SG(sapi_headers).send_default_content_type) {
  574: 		char *hd;
  575: 		param_free(pblock_remove("content-type", rc->rq->srvhdrs));
  576: 		hd = sapi_get_default_content_type(TSRMLS_C);
  577: 		pblock_nvinsert("content-type", hd, rc->rq->srvhdrs);
  578: 		efree(hd);
  579: 	}
  580: 
  581: 	protocol_status(rc->sn, rc->rq, SG(sapi_headers).http_response_code, NULL);
  582: 	retval = protocol_start_response(rc->sn, rc->rq);
  583: 
  584: 	if (retval == REQ_PROCEED || retval == REQ_NOACTION) {
  585: 		return SAPI_HEADER_SENT_SUCCESSFULLY;
  586: 	} else {
  587: 		return SAPI_HEADER_SEND_FAILED;
  588: 	}
  589: }
  590: 
  591: static int sapi_nsapi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
  592: {
  593: 	nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
  594: 	char *read_ptr = buffer, *content_length_str = NULL;
  595: 	uint bytes_read = 0;
  596: 	int length, content_length = 0;
  597: 	netbuf *nbuf = rc->sn->inbuf;
  598: 
  599: 	/*
  600: 	 *	Yesss!
  601: 	 */
  602: 	count_bytes = MIN(count_bytes, SG(request_info).content_length-rc->read_post_bytes);
  603: 	content_length = SG(request_info).content_length;
  604: 
  605: 	if (content_length <= 0) {
  606: 		return 0;
  607: 	}
  608: 
  609: 	/*
  610: 	 * Gobble any pending data in the netbuf.
  611: 	 */
  612: 	length = nbuf->cursize - nbuf->pos;
  613: 	length = MIN(count_bytes, length);
  614: 	if (length > 0) {
  615: 		memcpy(read_ptr, nbuf->inbuf + nbuf->pos, length);
  616: 		bytes_read += length;
  617: 		read_ptr += length;
  618: 		content_length -= length;
  619: 		nbuf->pos += length;
  620: 	}
  621: 
  622: 	/*
  623: 	 * Read the remaining from the socket.
  624: 	 */
  625: 	while (content_length > 0 && bytes_read < count_bytes) {
  626: 		int bytes_to_read = count_bytes - bytes_read;
  627: 
  628: 		if (content_length < bytes_to_read) {
  629: 			bytes_to_read = content_length;
  630: 		}
  631: 
  632: 		length = net_read(rc->sn->csd, read_ptr, bytes_to_read, NSAPI_G(read_timeout));
  633: 
  634: 		if (length == IO_ERROR || length == IO_EOF) {
  635: 			break;
  636: 		}
  637: 
  638: 		bytes_read += length;
  639: 		read_ptr += length;
  640: 		content_length -= length;
  641: 	}
  642: 
  643: 	if ( bytes_read > 0 ) {
  644: 		rc->read_post_bytes += bytes_read;
  645: 	}
  646: 	return bytes_read;
  647: }
  648: 
  649: static char *sapi_nsapi_read_cookies(TSRMLS_D)
  650: {
  651: 	char *cookie_string;
  652: 	nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
  653: 
  654: 	cookie_string = pblock_findval("cookie", rc->rq->headers);
  655: 	return cookie_string;
  656: }
  657: 
  658: static void sapi_nsapi_register_server_variables(zval *track_vars_array TSRMLS_DC)
  659: {
  660: 	nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
  661: 	register size_t i;
  662: 	int pos;
  663: 	char *value,*p;
  664: 	char buf[32];
  665: 	struct pb_entry *entry;
  666: 
  667: 	for (i = 0; i < nsapi_reqpb_size; i++) {
  668: 		value = pblock_findval(nsapi_reqpb[i].nsapi_eq, rc->rq->reqpb);
  669: 		if (value) {
  670: 			php_register_variable((char *)nsapi_reqpb[i].env_var, value, track_vars_array TSRMLS_CC);
  671: 		}
  672: 	}
  673: 
  674: 	for (i=0; i < rc->rq->headers->hsize; i++) {
  675: 		entry=rc->rq->headers->ht[i];
  676: 		while (entry) {
  677: 			if (strcasecmp(entry->param->name, "content-length")==0 || strcasecmp(entry->param->name, "content-type")==0) {
  678: 				value=estrdup(entry->param->name);
  679: 				pos = 0;
  680: 			} else {
  681: 				spprintf(&value, 0, "HTTP_%s", entry->param->name);
  682: 				pos = 5;
  683: 			}
  684: 			if (value) {
  685: 				for(p = value + pos; *p; p++) {
  686: 					*p = toupper(*p);
  687: 					if (!isalnum(*p)) {
  688: 						*p = '_';
  689: 					}
  690: 				}
  691: 				php_register_variable(value, entry->param->value, track_vars_array TSRMLS_CC);
  692: 				efree(value);
  693: 			}
  694: 			entry=entry->next;
  695: 		}
  696:   	}
  697: 
  698: 	for (i = 0; i < nsapi_vars_size; i++) {
  699: 		value = pblock_findval(nsapi_vars[i].nsapi_eq, rc->rq->vars);
  700: 		if (value) {
  701: 			php_register_variable((char *)nsapi_vars[i].env_var, value, track_vars_array TSRMLS_CC);
  702: 		}
  703: 	}
  704: 
  705: 	for (i = 0; i < nsapi_client_size; i++) {
  706: 		value = pblock_findval(nsapi_client[i].nsapi_eq, rc->sn->client);
  707: 		if (value) {
  708: 			php_register_variable((char *)nsapi_client[i].env_var, value, track_vars_array TSRMLS_CC);
  709: 		}
  710: 	}
  711: 
  712: 	if (value = session_dns(rc->sn)) {
  713: 		php_register_variable("REMOTE_HOST", value, track_vars_array TSRMLS_CC);
  714: 		nsapi_free(value);
  715: 	}
  716: 
  717: 	slprintf(buf, sizeof(buf), "%d", conf_getglobals()->Vport);
  718: 	php_register_variable("SERVER_PORT", buf, track_vars_array TSRMLS_CC);
  719: 	php_register_variable("SERVER_NAME", conf_getglobals()->Vserver_hostname, track_vars_array TSRMLS_CC);
  720: 
  721: 	value = http_uri2url_dynamic("", "", rc->sn, rc->rq);
  722: 	php_register_variable("SERVER_URL", value, track_vars_array TSRMLS_CC);
  723: 	nsapi_free(value);
  724: 
  725: 	php_register_variable("SERVER_SOFTWARE", system_version(), track_vars_array TSRMLS_CC);
  726: 	if (security_active) {
  727: 		php_register_variable("HTTPS", "ON", track_vars_array TSRMLS_CC);
  728: 	}
  729: 	php_register_variable("GATEWAY_INTERFACE", "CGI/1.1", track_vars_array TSRMLS_CC);
  730: 
  731: 	/* DOCUMENT_ROOT */
  732: 	if (value = request_translate_uri("/", rc->sn)) {
  733: 		pos = strlen(value);
  734: 		php_register_variable_safe("DOCUMENT_ROOT", value, pos-1, track_vars_array TSRMLS_CC);
  735: 		nsapi_free(value);
  736: 	}
  737: 
  738: 	/* PATH_INFO / PATH_TRANSLATED */
  739: 	if (rc->path_info) {
  740: 		if (value = request_translate_uri(rc->path_info, rc->sn)) {
  741: 			php_register_variable("PATH_TRANSLATED", value, track_vars_array TSRMLS_CC);
  742: 			nsapi_free(value);
  743: 		}
  744: 		php_register_variable("PATH_INFO", rc->path_info, track_vars_array TSRMLS_CC);
  745: 	}
  746: 
  747: 	/* Create full Request-URI & Script-Name */
  748: 	if (SG(request_info).request_uri) {
  749: 		pos = strlen(SG(request_info).request_uri);
  750: 		
  751: 		if (SG(request_info).query_string) {
  752: 			spprintf(&value, 0, "%s?%s", SG(request_info).request_uri, SG(request_info).query_string);
  753: 			if (value) {
  754: 				php_register_variable("REQUEST_URI", value, track_vars_array TSRMLS_CC);
  755: 				efree(value);
  756: 			}
  757: 		} else {
  758: 			php_register_variable_safe("REQUEST_URI", SG(request_info).request_uri, pos, track_vars_array TSRMLS_CC);
  759: 		}
  760: 
  761: 		if (rc->path_info) {
  762: 			pos -= strlen(rc->path_info);
  763: 			if (pos<0) {
  764: 				pos = 0;
  765: 			}
  766: 		}
  767: 		php_register_variable_safe("SCRIPT_NAME", SG(request_info).request_uri, pos, track_vars_array TSRMLS_CC);
  768: 	}
  769: 	php_register_variable("SCRIPT_FILENAME", SG(request_info).path_translated, track_vars_array TSRMLS_CC);
  770: 
  771: 	/* special variables in error mode */
  772: 	if (rc->http_error) {
  773: 		slprintf(buf, sizeof(buf), "%d", rc->http_error);
  774: 		php_register_variable("ERROR_TYPE", buf, track_vars_array TSRMLS_CC);
  775: 	}
  776: }
  777: 
  778: static void nsapi_log_message(char *message TSRMLS_DC)
  779: {
  780: 	nsapi_request_context *rc = (nsapi_request_context *)SG(server_context);
  781: 
  782: 	if (rc) {
  783: 		log_error(LOG_INFORM, pblock_findval("fn", rc->pb), rc->sn, rc->rq, "%s", message);
  784: 	} else {
  785: 		log_error(LOG_INFORM, "php5", NULL, NULL, "%s", message);
  786: 	}
  787: }
  788: 
  789: static double sapi_nsapi_get_request_time(TSRMLS_D)
  790: {
  791: 	return REQ_TIME( ((nsapi_request_context *)SG(server_context))->rq );
  792: }
  793: 
  794: static int php_nsapi_startup(sapi_module_struct *sapi_module)
  795: {
  796: 	if (php_module_startup(sapi_module, &nsapi_module_entry, 1)==FAILURE) {
  797: 		return FAILURE;
  798: 	}
  799: 	return SUCCESS;
  800: }
  801: 
  802: static struct stat* sapi_nsapi_get_stat(TSRMLS_D)
  803: {
  804: 	return request_stat_path(
  805: 		SG(request_info).path_translated,
  806: 		((nsapi_request_context *)SG(server_context))->rq
  807: 	);
  808: }
  809: 
  810: static sapi_module_struct nsapi_sapi_module = {
  811: 	"nsapi",                                /* name */
  812: 	"NSAPI",                                /* pretty name */
  813: 
  814: 	php_nsapi_startup,                      /* startup */
  815: 	php_module_shutdown_wrapper,            /* shutdown */
  816: 
  817: 	NULL,                                   /* activate */
  818: 	NULL,                                   /* deactivate */
  819: 
  820: 	sapi_nsapi_ub_write,                    /* unbuffered write */
  821: 	sapi_nsapi_flush,                       /* flush */
  822: 	sapi_nsapi_get_stat,                    /* get uid/stat */
  823: 	NULL,                                   /* getenv */
  824: 
  825: 	php_error,                              /* error handler */
  826: 
  827: 	sapi_nsapi_header_handler,              /* header handler */
  828: 	sapi_nsapi_send_headers,                /* send headers handler */
  829: 	NULL,                                   /* send header handler */
  830: 
  831: 	sapi_nsapi_read_post,                   /* read POST data */
  832: 	sapi_nsapi_read_cookies,                /* read Cookies */
  833: 
  834: 	sapi_nsapi_register_server_variables,   /* register server variables */
  835: 	nsapi_log_message,                      /* Log message */
  836: 	sapi_nsapi_get_request_time,			/* Get request time */
  837: 	NULL,									/* Child terminate */
  838: 
  839: 	NULL,                                   /* Block interruptions */
  840: 	NULL,                                   /* Unblock interruptions */
  841: 
  842: 	STANDARD_SAPI_MODULE_PROPERTIES
  843: };
  844: 
  845: static void nsapi_php_ini_entries(NSLS_D TSRMLS_DC)
  846: {
  847: 	struct pb_entry *entry;
  848: 	register int i,j,ok;
  849: 
  850: 	for (i=0; i < NSG(pb)->hsize; i++) {
  851: 		entry=NSG(pb)->ht[i];
  852: 		while (entry) {
  853: 			/* exclude standard entries given to "Service" which should not go into ini entries */
  854: 			ok=1;
  855: 			for (j=0; nsapi_exclude_from_ini_entries[j]; j++) {
  856: 				ok&=(strcasecmp(entry->param->name, nsapi_exclude_from_ini_entries[j])!=0);
  857: 			}
  858: 
  859: 			if (ok) {
  860: 				/* change the ini entry */
  861: 				if (zend_alter_ini_entry(entry->param->name, strlen(entry->param->name)+1,
  862: 				 entry->param->value, strlen(entry->param->value),
  863: 				 PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE)==FAILURE) {
  864: 					log_error(LOG_WARN, pblock_findval("fn", NSG(pb)), NSG(sn), NSG(rq), "Cannot change php.ini key \"%s\" to \"%s\"", entry->param->name, entry->param->value);
  865: 				}
  866: 			}
  867: 			entry=entry->next;
  868: 		}
  869:   	}
  870: }
  871: 
  872: void NSAPI_PUBLIC php5_close(void *vparam)
  873: {
  874: 	if (nsapi_sapi_module.shutdown) {
  875: 		nsapi_sapi_module.shutdown(&nsapi_sapi_module);
  876: 	}
  877: 
  878: 	if (nsapi_sapi_module.php_ini_path_override) {
  879: 		free(nsapi_sapi_module.php_ini_path_override);
  880: 	}
  881: 	
  882: #ifdef PHP_WIN32
  883: 	if (nsapi_dll) {
  884: 		free(nsapi_dll);
  885: 		nsapi_dll = NULL;
  886: 	}
  887: #endif	
  888: 
  889: 	sapi_shutdown();
  890: 	tsrm_shutdown();
  891: 
  892: 	log_error(LOG_INFORM, "php5_close", NULL, NULL, "Shutdown PHP Module");
  893: }
  894: 
  895: /*********************************************************
  896: / init SAF
  897: /
  898: / Init fn="php5_init" [php_ini="/path/to/php.ini"] [server_lib="ns-httpdXX.dll"]
  899: /   Initialize the NSAPI module in magnus.conf
  900: /
  901: / php_ini: gives path to php.ini file
  902: / server_lib: (only Win32) gives name of DLL (without path) to look for
  903: /  servact_* functions
  904: /
  905: /*********************************************************/
  906: int NSAPI_PUBLIC php5_init(pblock *pb, Session *sn, Request *rq)
  907: {
  908: 	php_core_globals *core_globals;
  909: 	char *strval;
  910: 	int threads=128; /* default for server */
  911: 
  912: 	/* fetch max threads from NSAPI and initialize TSRM with it */
  913: 	threads=conf_getglobals()->Vpool_maxthreads;
  914: 	if (threads<1) {
  915: 		threads=128; /* default for server */
  916: 	}
  917: 	tsrm_startup(threads, 1, 0, NULL);
  918: 
  919: 	core_globals = ts_resource(core_globals_id);
  920: 
  921: 	/* look if php_ini parameter is given to php5_init */
  922: 	if (strval = pblock_findval("php_ini", pb)) {
  923: 		nsapi_sapi_module.php_ini_path_override = strdup(strval);
  924: 	}
  925: 	
  926: #ifdef PHP_WIN32
  927: 	/* look if server_lib parameter is given to php5_init
  928: 	 * (this disables the automatic search for the newest ns-httpdXX.dll) */
  929: 	if (strval = pblock_findval("server_lib", pb)) {
  930: 		nsapi_dll = strdup(strval);
  931: 	}
  932: #endif	
  933: 
  934: 	/* start SAPI */
  935: 	sapi_startup(&nsapi_sapi_module);
  936: 	nsapi_sapi_module.startup(&nsapi_sapi_module);
  937: 
  938: 	daemon_atrestart(&php5_close, NULL);
  939: 
  940: 	log_error(LOG_INFORM, pblock_findval("fn", pb), sn, rq, "Initialized PHP Module (%d threads expected)", threads);
  941: 	return REQ_PROCEED;
  942: }
  943: 
  944: /*********************************************************
  945: / normal use in Service directive:
  946: /
  947: / Service fn="php5_execute" type=... method=... [inikey=inivalue inikey=inivalue...]
  948: /
  949: / use in Service for a directory to supply a php-made directory listing instead of server default:
  950: /
  951: / Service fn="php5_execute" type="magnus-internal/directory" script="/path/to/script.php" [inikey=inivalue inikey=inivalue...]
  952: /
  953: / use in Error SAF to display php script as error page:
  954: /
  955: / Error fn="php5_execute" code=XXX script="/path/to/script.php" [inikey=inivalue inikey=inivalue...]
  956: / Error fn="php5_execute" reason="Reason" script="/path/to/script.php" [inikey=inivalue inikey=inivalue...]
  957: /
  958: /*********************************************************/
  959: int NSAPI_PUBLIC php5_execute(pblock *pb, Session *sn, Request *rq)
  960: {
  961: 	int retval;
  962: 	nsapi_request_context *request_context;
  963: 	zend_file_handle file_handle = {0};
  964: 	struct stat *fst;
  965: 
  966: 	char *path_info;
  967: 	char *query_string    = pblock_findval("query", rq->reqpb);
  968: 	char *uri             = pblock_findval("uri", rq->reqpb);
  969: 	char *request_method  = pblock_findval("method", rq->reqpb);
  970: 	char *content_type    = pblock_findval("content-type", rq->headers);
  971: 	char *content_length  = pblock_findval("content-length", rq->headers);
  972: 	char *directive       = pblock_findval("Directive", pb);
  973: 	int error_directive   = (directive && !strcasecmp(directive, "error"));
  974: 	int fixed_script      = 1;
  975: 
  976: 	/* try to use script parameter -> Error or Service for directory listing */
  977: 	char *path_translated = pblock_findval("script", pb);
  978: 
  979: 	TSRMLS_FETCH();
  980: 
  981: 	/* if script parameter is missing: normal use as Service SAF  */
  982: 	if (!path_translated) {
  983: 		path_translated = pblock_findval("path", rq->vars);
  984: 		path_info       = pblock_findval("path-info", rq->vars);
  985: 		fixed_script = 0;
  986: 		if (error_directive) {
  987: 			/* go to next error directive if script parameter is missing */
  988: 			log_error(LOG_WARN, pblock_findval("fn", pb), sn, rq, "Missing 'script' parameter");
  989: 			return REQ_NOACTION;
  990: 		}
  991: 	} else {
  992: 		/* in error the path_info is the uri to the requested page */
  993: 		path_info = pblock_findval("uri", rq->reqpb);
  994: 	}
  995: 
  996: 	/* check if this uri was included in an other PHP script with nsapi_virtual()
  997: 	   by looking for a request context in the current thread */
  998: 	if (SG(server_context)) {
  999: 		/* send 500 internal server error */
 1000: 		log_error(LOG_WARN, pblock_findval("fn", pb), sn, rq, "Cannot make nesting PHP requests with nsapi_virtual()");
 1001: 		if (error_directive) {
 1002: 			return REQ_NOACTION;
 1003: 		} else {
 1004: 			protocol_status(sn, rq, 500, NULL);
 1005: 			return REQ_ABORTED;
 1006: 		}
 1007: 	}
 1008: 
 1009: 	request_context = (nsapi_request_context *)pool_malloc(sn->pool, sizeof(nsapi_request_context));
 1010: 	if (!request_context) {
 1011: 		log_error(LOG_CATASTROPHE, pblock_findval("fn", pb), sn, rq, "Insufficient memory to process PHP request!");
 1012: 		return REQ_ABORTED;
 1013: 	}
 1014: 	request_context->pb = pb;
 1015: 	request_context->sn = sn;
 1016: 	request_context->rq = rq;
 1017: 	request_context->read_post_bytes = 0;
 1018: 	request_context->fixed_script = fixed_script;
 1019: 	request_context->http_error = (error_directive) ? rq->status_num : 0;
 1020: 	request_context->path_info = path_info;
 1021: 
 1022: 	SG(server_context) = request_context;
 1023: 	SG(request_info).query_string = query_string;
 1024: 	SG(request_info).request_uri = uri;
 1025: 	SG(request_info).request_method = request_method;
 1026: 	SG(request_info).path_translated = path_translated;
 1027: 	SG(request_info).content_type = content_type;
 1028: 	SG(request_info).content_length = (content_length == NULL) ? 0 : strtoul(content_length, 0, 0);
 1029: 	SG(sapi_headers).http_response_code = (error_directive) ? rq->status_num : 200;
 1030: 	
 1031: 	nsapi_php_ini_entries(NSLS_C TSRMLS_CC);
 1032: 
 1033: 	php_handle_auth_data(pblock_findval("authorization", rq->headers) TSRMLS_CC);
 1034: 
 1035: 	file_handle.type = ZEND_HANDLE_FILENAME;
 1036: 	file_handle.filename = SG(request_info).path_translated;
 1037: 	file_handle.free_filename = 0;
 1038: 	file_handle.opened_path = NULL;
 1039: 
 1040: 	fst = request_stat_path(SG(request_info).path_translated, rq);
 1041: 	if (fst && S_ISREG(fst->st_mode)) {
 1042: 		if (php_request_startup(TSRMLS_C) == SUCCESS) {
 1043: 			php_execute_script(&file_handle TSRMLS_CC);
 1044: 			php_request_shutdown(NULL);
 1045: 			retval=REQ_PROCEED;
 1046: 		} else {
 1047: 			/* send 500 internal server error */
 1048: 			log_error(LOG_WARN, pblock_findval("fn", pb), sn, rq, "Cannot prepare PHP engine!");
 1049: 			if (error_directive) {
 1050: 				retval=REQ_NOACTION;
 1051: 			} else {
 1052: 				protocol_status(sn, rq, 500, NULL);
 1053: 				retval=REQ_ABORTED;
 1054: 			}
 1055: 		}
 1056: 	} else {
 1057: 		/* send 404 because file not found */
 1058: 		log_error(LOG_WARN, pblock_findval("fn", pb), sn, rq, "Cannot execute PHP script: %s (File not found)", SG(request_info).path_translated);
 1059: 		if (error_directive) {
 1060: 			retval=REQ_NOACTION;
 1061: 		} else {
 1062: 			protocol_status(sn, rq, 404, NULL);
 1063: 			retval=REQ_ABORTED;
 1064: 		}
 1065: 	}
 1066: 
 1067: 	pool_free(sn->pool, request_context);
 1068: 	SG(server_context) = NULL;
 1069: 
 1070: 	return retval;
 1071: }
 1072: 
 1073: /*********************************************************
 1074: / authentication
 1075: /
 1076: / we have to make a 'fake' authenticator for netscape so it
 1077: / will pass authentication through to php, and allow us to
 1078: / check authentication with our scripts.
 1079: /
 1080: / php5_auth_trans
 1081: /   main function called from netscape server to authenticate
 1082: /   a line in obj.conf:
 1083: /		funcs=php5_auth_trans shlib="path/to/this/phpnsapi.dll"
 1084: /	and:
 1085: /		<Object ppath="path/to/be/authenticated/by/php/*">
 1086: /		AuthTrans fn="php5_auth_trans"
 1087: /*********************************************************/
 1088: int NSAPI_PUBLIC php5_auth_trans(pblock * pb, Session * sn, Request * rq)
 1089: {
 1090: 	/* This is a DO NOTHING function that allows authentication
 1091: 	 * information
 1092: 	 * to be passed through to PHP scripts.
 1093: 	 */
 1094: 	return REQ_PROCEED;
 1095: }
 1096: 
 1097: /*
 1098:  * Local variables:
 1099:  * tab-width: 4
 1100:  * c-basic-offset: 4
 1101:  * End:
 1102:  * vim600: sw=4 ts=4 fdm=marker
 1103:  * vim<600: sw=4 ts=4
 1104:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>